# FormField 表单字段组件

一个灵活的表单字段包装组件，为表单控件提供一致的标签、验证显示和布局选项。

## 特性

- **灵活布局**: 支持垂直和水平标签排列
- **验证显示**: 内置错误消息显示，样式一致
- **必填字段指示器**: 必填字段的可视化星号指示器
- **可自定义样式**: 支持CSS变量和标签自定义样式
- **响应式设计**: 适配不同屏幕尺寸和表单布局
- **无障碍访问**: 为屏幕阅读器提供适当的语义结构

## 安装

```bash
npm install @ticatec/uniface-element
```

## 使用方法

### 基本用法

```svelte
<script>
  import FormField from '@ticatec/uniface-element/form-field';
  import TextEditor from '@ticatec/uniface-element/text-editor';
  
  let name = '';
</script>

<FormField label="姓名">
  <TextEditor bind:value={name} placeholder="请输入姓名" />
</FormField>
```

### 必填字段

```svelte
<FormField required label="邮箱">
  <TextEditor bind:value={email} placeholder="请输入邮箱地址" />
</FormField>
```

### 带错误消息的字段

```svelte
<script>
  let email = '';
  let emailError = '请输入有效的邮箱地址';
</script>

<FormField required label="邮箱" error={emailError}>
  <TextEditor bind:value={email} placeholder="请输入邮箱地址" />
</FormField>
```

### 水平布局

```svelte
<div class="field-layout-horizontal">
  <FormField label="出生日期">
    <DatePicker bind:value={dateOfBirth} />
  </FormField>
</div>
```

### 自定义标签样式

```svelte
<FormField 
  label="重要字段" 
  label$style="color: #2F54EB; font-weight: bold;"
>
  <TextEditor bind:value={value} />
</FormField>
```

### 多行控件的顶部对齐标签

```svelte
<FormField 
  label="描述" 
  label$alignment="top"
>
  <MemoEditor bind:value={description} resize="vertical" />
</FormField>
```

## API 参考

### 属性

| 属性 | 类型 | 默认值 | 描述 |
|------|------|---------|-------------|
| `label` | `string` | `"Label:"` | 表单字段的标签文本 |
| `style` | `string` | `''` | 表单字段容器的自定义CSS样式 |
| `label$style` | `string \| null` | `null` | 标签元素的自定义CSS样式 |
| `required` | `boolean` | `false` | 字段是否必填（显示星号指示器） |
| `error` | `string \| null` | `null` | 在字段下方显示的错误消息 |
| `labelSuffix` | `string` | `':'` | 附加到标签后的文本（如冒号） |
| `label$alignment` | `'center' \| 'top'` | `'center'` | 标签的垂直对齐方式 |
| `height` | `string` | `null` | 字段容器的自定义高度 |
| `class` | `string` | `''` | 表单字段的额外CSS类 |

### 插槽

| 插槽 | 描述 |
|------|-------------|
| default | 表单控件内容（输入框、选择器等） |

## 布局类

### 水平布局

在父容器中添加 `field-layout-horizontal` 类来水平排列表单字段：

```svelte
<div class="field-layout-horizontal">
  <FormField label="名">
    <TextEditor bind:value={firstName} />
  </FormField>
  <FormField label="姓">
    <TextEditor bind:value={lastName} />
  </FormField>
</div>
```

## 样式

### CSS 变量

FormField组件使用CSS变量进行一致的主题化：

```css
:root {
  --uniface-form-field-required-indicator-color: #ff3e00;
  --uniface-form-field-label-color: #374151;
  --uniface-form-field-invalid-message-color: #ff3e00;
  --uniface-form-field-label-width: 120px;
  --uniface-form-field-label-alignment: right;
  --uniface-form-field-padding: 6px 4px;
  --uniface-field-gap: 4px;
}
```

### 自定义样式

```css
.custom-form-field {
  --uniface-form-field-label-color: #2563eb;
  --uniface-form-field-label-width: 150px;
}
```

## 示例

### 完整表单示例

```svelte
<script>
  import FormField from '@ticatec/uniface-element/form-field';
  import TextEditor from '@ticatec/uniface-element/text-editor';
  import DatePicker from '@ticatec/uniface-element/date-picker';
  import MemoEditor from '@ticatec/uniface-element/memo-editor';
  
  let formData = {
    name: '',
    email: '',
    dateOfBirth: null,
    notes: ''
  };
  
  let errors = {};
  
  function validateForm() {
    errors = {};
    
    if (!formData.name) {
      errors.name = '姓名为必填项';
    }
    
    if (!formData.email) {
      errors.email = '邮箱为必填项';
    } else if (!/\S+@\S+\.\S+/.test(formData.email)) {
      errors.email = '请输入有效的邮箱地址';
    }
    
    return Object.keys(errors).length === 0;
  }
</script>

<form on:submit|preventDefault={validateForm}>
  <FormField required label="姓名" error={errors.name}>
    <TextEditor 
      variant="filled" 
      bind:value={formData.name}
      placeholder="请输入您的姓名" 
    />
  </FormField>
  
  <FormField required label="邮箱地址" error={errors.email}>
    <TextEditor 
      variant="filled" 
      bind:value={formData.email}
      placeholder="请输入邮箱地址" 
    />
  </FormField>
  
  <div class="field-layout-horizontal">
    <FormField label="出生日期">
      <DatePicker variant="filled" bind:value={formData.dateOfBirth} />
    </FormField>
  </div>
  
  <FormField label="备注" label$alignment="top">
    <MemoEditor 
      variant="filled" 
      bind:value={formData.notes}
      resize="vertical"
      placeholder="请输入备注信息..."
    />
  </FormField>
  
  <button type="submit">提交</button>
</form>
```

### 响应式表单布局

```svelte
<div class="responsive-form">
  <div class="field-row">
    <FormField label="名" error={errors.firstName}>
      <TextEditor bind:value={formData.firstName} />
    </FormField>
    
    <FormField label="姓" error={errors.lastName}>
      <TextEditor bind:value={formData.lastName} />
    </FormField>
  </div>
  
  <FormField label="邮箱地址" error={errors.email}>
    <TextEditor bind:value={formData.email} />
  </FormField>
</div>

<style>
  .responsive-form {
    max-width: 600px;
    margin: 0 auto;
  }
  
  .field-row {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 16px;
  }
  
  @media (max-width: 768px) {
    .field-row {
      grid-template-columns: 1fr;
    }
  }
</style>
```

## 最佳实践

### 1. 一致的标签格式

在表单中使用一致的标签格式：

```svelte
<FormField label="名" labelSuffix="">
  <TextEditor bind:value={firstName} />
</FormField>

<FormField label="姓" labelSuffix="">
  <TextEditor bind:value={lastName} />
</FormField>
```

### 2. 必填字段指示器

始终用 `required` 属性标记必填字段：

```svelte
<FormField required label="邮箱">
  <TextEditor bind:value={email} />
</FormField>
```

### 3. 错误处理

提供清晰、可操作的错误消息：

```svelte
<FormField 
  required 
  label="密码" 
  error={passwordError || (password && password.length < 8 ? '密码长度至少8位' : null)}
>
  <TextEditor type="password" bind:value={password} />
</FormField>
```

### 4. 无障碍访问

确保表单的无障碍访问：

```svelte
<FormField 
  required 
  label="用户名"
  error={usernameError}
>
  <TextEditor 
    bind:value={username}
    input$aria-describedby={usernameError ? 'username-error' : undefined}
  />
</FormField>
```

### 5. 布局考虑

对相关字段使用水平布局：

```svelte
<div class="field-layout-horizontal">
  <FormField label="开始日期">
    <DatePicker bind:value={startDate} />
  </FormField>
  
  <FormField label="结束日期">
    <DatePicker bind:value={endDate} />
  </FormField>
</div>
```

## 无障碍功能

- **语义化HTML**: 使用适当的表单字段结构
- **必填指示器**: 必填字段的可视化星号
- **错误关联**: 错误消息与字段正确关联
- **标签关联**: 标签与表单控件语义连接
- **键盘导航**: 支持标准表单导航模式

## 浏览器支持

- **现代浏览器**: Chrome、Firefox、Safari、Edge（最新版本）
- **移动浏览器**: iOS Safari、Chrome Mobile、Firefox Mobile
- **CSS Grid支持**: 布局功能必需

## 相关组件

- **TextEditor**: 单行文本输入组件
- **MemoEditor**: 多行文本区域组件
- **DatePicker**: 日期选择组件
- **DateTimePicker**: 日期时间选择组件

## 许可证

MIT许可证 - 详情请参阅LICENSE文件。