# FormField

A flexible form field wrapper component that provides consistent labeling, validation display, and layout options for form controls.

## Features

- **Flexible Layout**: Supports both vertical and horizontal label arrangements
- **Validation Display**: Built-in error message display with consistent styling
- **Required Field Indicator**: Visual asterisk indicator for required fields
- **Customizable Styling**: CSS variables and custom style support for labels
- **Responsive Design**: Adapts to different screen sizes and form layouts
- **Accessibility**: Proper semantic structure for screen readers

## Installation

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

## Usage

### Basic Usage

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

<FormField label="Name">
  <TextEditor bind:value={name} placeholder="Enter your name" />
</FormField>
```

### Required Field

```svelte
<FormField required label="Email">
  <TextEditor bind:value={email} placeholder="Enter your email" />
</FormField>
```

### Field with Error Message

```svelte
<script>
  let email = '';
  let emailError = 'Please enter a valid email address';
</script>

<FormField required label="Email" error={emailError}>
  <TextEditor bind:value={email} placeholder="Enter your email" />
</FormField>
```

### Horizontal Layout

```svelte
<div class="field-layout-horizontal">
  <FormField label="Date of Birth">
    <DatePicker bind:value={dateOfBirth} />
  </FormField>
</div>
```

### Custom Label Styling

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

### Top-Aligned Label for Multi-line Controls

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

## API Reference

### Props

| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `label` | `string` | `"Label:"` | The label text for the form field |
| `style` | `string` | `''` | Custom CSS styles for the form field container |
| `label$style` | `string \| null` | `null` | Custom CSS styles for the label element |
| `required` | `boolean` | `false` | Whether the field is required (shows asterisk indicator) |
| `error` | `string \| null` | `null` | Error message to display below the field |
| `labelSuffix` | `string` | `':'` | Text to append to the label (e.g., colon) |
| `label$alignment` | `'center' \| 'top'` | `'center'` | Vertical alignment of the label |
| `height` | `string` | `null` | Custom height for the field container |
| `class` | `string` | `''` | Additional CSS classes for the form field |

### Slots

| Slot | Description |
|------|-------------|
| default | The form control content (input, select, etc.) |

## Layout Classes

### Horizontal Layout

Add the `field-layout-horizontal` class to a parent container to arrange form fields horizontally:

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

## Styling

### CSS Variables

The FormField component uses CSS variables for consistent theming:

```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;
}
```

### Custom Styling

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

## Examples

### Complete Form Example

```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 = 'Name is required';
    }
    
    if (!formData.email) {
      errors.email = 'Email is required';
    } else if (!/\S+@\S+\.\S+/.test(formData.email)) {
      errors.email = 'Please enter a valid email address';
    }
    
    return Object.keys(errors).length === 0;
  }
</script>

<form on:submit|preventDefault={validateForm}>
  <FormField required label="Full Name" error={errors.name}>
    <TextEditor 
      variant="filled" 
      bind:value={formData.name}
      placeholder="Enter your full name" 
    />
  </FormField>
  
  <FormField required label="Email Address" error={errors.email}>
    <TextEditor 
      variant="filled" 
      bind:value={formData.email}
      placeholder="Enter your email" 
    />
  </FormField>
  
  <div class="field-layout-horizontal">
    <FormField label="Date of Birth">
      <DatePicker variant="filled" bind:value={formData.dateOfBirth} />
    </FormField>
  </div>
  
  <FormField label="Additional Notes" label$alignment="top">
    <MemoEditor 
      variant="filled" 
      bind:value={formData.notes}
      resize="vertical"
      placeholder="Enter any additional notes..."
    />
  </FormField>
  
  <button type="submit">Submit</button>
</form>
```

### Responsive Form Layout

```svelte
<div class="responsive-form">
  <div class="field-row">
    <FormField label="First Name" error={errors.firstName}>
      <TextEditor bind:value={formData.firstName} />
    </FormField>
    
    <FormField label="Last Name" error={errors.lastName}>
      <TextEditor bind:value={formData.lastName} />
    </FormField>
  </div>
  
  <FormField label="Email Address" 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>
```

## Best Practices

### 1. Consistent Labeling

Use consistent label formatting across your forms:

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

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

### 2. Required Field Indicators

Always mark required fields with the `required` prop:

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

### 3. Error Handling

Provide clear, actionable error messages:

```svelte
<FormField 
  required 
  label="Password" 
  error={passwordError || (password && password.length < 8 ? 'Password must be at least 8 characters' : null)}
>
  <TextEditor type="password" bind:value={password} />
</FormField>
```

### 4. Accessibility

Ensure proper form accessibility:

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

### 5. Layout Considerations

Use horizontal layout for related fields:

```svelte
<div class="field-layout-horizontal">
  <FormField label="Start Date">
    <DatePicker bind:value={startDate} />
  </FormField>
  
  <FormField label="End Date">
    <DatePicker bind:value={endDate} />
  </FormField>
</div>
```

## Accessibility Features

- **Semantic HTML**: Uses proper form field structure
- **Required Indicators**: Visual asterisk for required fields
- **Error Association**: Error messages are properly associated with fields
- **Label Association**: Labels are semantically connected to form controls
- **Keyboard Navigation**: Supports standard form navigation patterns

## Browser Support

- **Modern Browsers**: Chrome, Firefox, Safari, Edge (latest versions)
- **Mobile Browsers**: iOS Safari, Chrome Mobile, Firefox Mobile
- **CSS Grid Support**: Required for layout functionality

## Related Components

- **TextEditor**: Single-line text input component
- **MemoEditor**: Multi-line text area component
- **DatePicker**: Date selection component
- **DateTimePicker**: Date and time selection component

## License

MIT License - see LICENSE file for details.