import { SourceCode } from '@theme';
import { BasicStory, FallbackRendererStory, CustomStrategyStory } from 'components/form-materials/components/constant-inputs';

# ConstantInput

ConstantInput 是一个常量输入组件，它根据提供的 JSON Schema 自动选择合适的输入类型渲染器。

组件支持自定义渲染策略和兜底渲染器，能够处理各种数据类型的常量输入。

## 案例演示

### 基本使用

<BasicStory />

```tsx pure title="form-meta.tsx"
const formMeta = {
  render: () => (
    <>
      <FormHeader />
      <Field<string> name="constant_string" defaultValue="Hello World">
        {({ field }) => (
          <ConstantInput
            value={field.value}
            onChange={(value) => field.onChange(value)}
            schema={{ type: 'string' }}
          />
        )}
      </Field>
      <Field<string> name="constant_enum" defaultValue="上午">
        {({ field }) => (
          <ConstantInput
            value={field.value}
            onChange={(value) => field.onChange(value)}
            schema={{ type: 'string', enum: ['上午', '下午'] }}
          />
        )}
      </Field>
    </>
  ),
}
```

:::tip{title="注册新类型的常量输入器"}

参考 [类型管理](../common/json-schema-preset)，在类型注册的时候为类型配置常量输入器

:::

### 兜底渲染器

当组件无法找到合适的渲染器时，会使用兜底渲染器：

<FallbackRendererStory />

```tsx pure title="form-meta.tsx"
const formMeta = {
  render: () => (
    <>
      <FormHeader />
      <Field<any> name="constant_fallback" defaultValue={{ custom: 'data' }}>
        {({ field }) => (
          <ConstantInput
            value={field.value}
            onChange={(value) => field.onChange(value)}
            schema={{ type: 'custom-unsupported-type' }}
            fallbackRenderer={({ value, onChange, readonly }) => (
              <div style={{ padding: '8px', background: '#f0f0f0', border: '1px dashed #ccc' }}>
                <p>Fallback renderer for unsupported type</p>
              </div>
            )}
          />
        )}
      </Field>
    </>
  ),
}
```

### 自定义策略

使用自定义渲染策略来覆盖默认行为：

<CustomStrategyStory />

```tsx pure title="form-meta.tsx"
const formMeta = {
  render: () => (
    <>
      <FormHeader />
      <Field<string> name="constant_custom" defaultValue="自定义值">
        {({ field }) => (
          <ConstantInput
            value={field.value}
            onChange={(value) => field.onChange(value)}
            schema={{ type: 'object' }}
            strategies={[
              {
                hit: (schema) => schema.type === 'object',
                Renderer: ({ value, onChange, readonly }) => (
                  <p>Object is not supported now</p>
                ),
              },
            ]}
          />
        )}
      </Field>
    </>
  ),
}
```

## API 参考

### ConstantInput Props

| 属性名 | 类型 | 默认值 | 描述 |
|--------|------|--------|------|
| `value` | `any` | - | 输入值 |
| `onChange` | `(value: any) => void` | - | 值变化时的回调函数 |
| `schema` | `IJsonSchema` | - | 用于确定渲染器的 JSON Schema |
| `strategies` | `Strategy[]` | - | 自定义渲染策略数组 |
| `fallbackRenderer` | `React.FC<ConstantRendererProps>` | - | 当没有合适渲染器时使用的兜底渲染器 |
| `readonly` | `boolean` | `false` | 是否为只读模式 |

### Strategy 接口

```typescript
interface Strategy<Value = any> {
  hit: (schema: IJsonSchema) => boolean;
  Renderer: React.FC<ConstantRendererProps<Value>>;
}
```

## 源码导读

<SourceCode
  href="https://github.com/bytedance/flowgram.ai/tree/main/packages/materials/form-materials/src/components/constant-input"
/>

使用 CLI 命令可以复制源代码到本地：

```bash
npx @flowgram.ai/cli@latest materials components/constant-input
```

### 目录结构讲解

```
constant-input/
├── index.tsx    # 主组件实现，包含 ConstantInput 核心逻辑
└── types.ts     # 类型定义，包括 Strategy 接口和 PropsType
```

### 核心实现说明

#### 渲染器选择逻辑

组件通过以下步骤选择合适的渲染器：

1. **策略匹配**：首先检查 `strategies` 数组中是否有匹配当前 schema 的策略
2. **类型管理器**：如果没有匹配的策略，则使用类型管理器 (`useTypeManager`) 获取对应 schema 的渲染器
3. **兜底渲染**：如果以上都失败，使用提供的 `fallbackRenderer` 或默认的禁用输入框


#### 类型系统集成

ConstantInput 与 [**物料类型管理**](../common/json-schema-preset) 深度集成：

- 通过 `useTypeManager` Hook 获取类型管理器
- 使用 `typeManager.getTypeBySchema(schema)` 获取对应类型的渲染器
- 支持所有 JSON Schema 标准类型（string, number, boolean, object, array 等）

### 依赖梳理

#### flowgram API

[**@flowgram.ai/json-schema**](https://github.com/bytedance/flowgram.ai/tree/main/packages/variable/json-schema)
- [`IJsonSchema`](https://flowgram.ai/auto-docs/json-schema/interfaces/IJsonSchema): JSON Schema 类型定义
- [`useTypeManager`](https://flowgram.ai/auto-docs/json-schema/functions/useTypeManager): 类型管理器 Hook

#### 第三方库

[**Semi UI**](https://semi.design/zh-CN)
- 基础输入组件库，提供默认的输入控件
