# FlexRowForm (FormContainer)

A structured row-based form layout system that provides explicit row and cell organization for precise form layouts with 12-column grid support.

## Features

- **Explicit Row Structure**: Manual row definition for precise layout control
- **12-Column Grid System**: Cell spanning from 1-12 columns with percentage-based widths
- **Layout Modes**: Supports vertical and horizontal field layouts
- **Structured Organization**: Clear separation between rows and cells
- **FormField Integration**: Works seamlessly with FormField components
- **Responsive Design**: Flexible grid system that adapts to different screen sizes

## Installation

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

## Usage

### Basic Usage

```svelte
<script>
  import FormContainer, { Row, Cell } from '@ticatec/uniface-element/flex-row-form';
  import FormField from '@ticatec/uniface-element/form-field';
  import TextEditor from '@ticatec/uniface-element/text-editor';
  
  let formData = {};
</script>

<FormContainer>
  <Row>
    <Cell span={6}>
      <FormField label="First Name" required>
        <TextEditor bind:value={formData.firstName} variant="filled" />
      </FormField>
    </Cell>
    
    <Cell span={6}>
      <FormField label="Last Name" required>
        <TextEditor bind:value={formData.lastName} variant="filled" />
      </FormField>
    </Cell>
  </Row>
  
  <Row>
    <Cell span={12}>
      <FormField label="Email Address">
        <TextEditor bind:value={formData.email} variant="filled" />
      </FormField>
    </Cell>
  </Row>
</FormContainer>
```

### Complete Form Example

```svelte
<script>
  import FormContainer, { Row, Cell } from '@ticatec/uniface-element/flex-row-form';
  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 OptionsSelect from '@ticatec/uniface-element/options-select';
  import MemoEditor from '@ticatec/uniface-element/memo-editor';
  
  let formData = {};
  let errors = {};
  
  const genderOptions = [
    { code: 'F', text: 'Female' },
    { code: 'M', text: 'Male' }
  ];
  
  const countries = [
    { code: 'AU', text: 'Australia' },
    { code: 'NZ', text: 'New Zealand' },
    { code: 'US', text: 'United States' }
  ];
</script>

<FormContainer style="max-width: 800px; margin: 0 auto; border: 1px solid #e1e1e1; padding: 20px;">
  <Row>
    <Cell span={4}>
      <FormField label="Full Name" required error={errors.name}>
        <TextEditor 
          bind:value={formData.name} 
          variant="filled"
          placeholder="Enter full name"
          input$maxLength={50}
        />
      </FormField>
    </Cell>
    
    <Cell span={4}>
      <FormField label="Date of Birth" required error={errors.dob}>
        <DatePicker 
          bind:value={formData.dob} 
          variant="filled"
          max={new Date()}
        />
      </FormField>
    </Cell>
    
    <Cell span={4}>
      <FormField label="Gender" required error={errors.gender}>
        <OptionsSelect 
          bind:value={formData.gender} 
          variant="filled"
          options={genderOptions}
        />
      </FormField>
    </Cell>
  </Row>
  
  <Row>
    <Cell span={6}>
      <FormField label="Nationality" error={errors.nationality}>
        <OptionsSelect 
          bind:value={formData.nationality} 
          variant="filled"
          options={countries}
        />
      </FormField>
    </Cell>
    
    <Cell span={6}>
      <FormField label="Phone Number" error={errors.phone}>
        <TextEditor 
          bind:value={formData.phone} 
          variant="filled"
          placeholder="Enter phone number"
        />
      </FormField>
    </Cell>
  </Row>
  
  <Row>
    <Cell span={12}>
      <FormField label="Additional Notes" error={errors.notes}>
        <MemoEditor 
          bind:value={formData.notes} 
          variant="filled"
          input$rows={4}
          input$maxLength={300}
          showIndicator
        />
      </FormField>
    </Cell>
  </Row>
</FormContainer>
```

### Horizontal Layout

```svelte
<FormContainer fieldLayout="horizontal">
  <Row>
    <Cell span={6}>
      <FormField label="Start Date">
        <DatePicker bind:value={startDate} variant="filled" />
      </FormField>
    </Cell>
    
    <Cell span={6}>
      <FormField label="End Date">
        <DatePicker bind:value={endDate} variant="filled" />
      </FormField>
    </Cell>
  </Row>
  
  <Row>
    <Cell span={12}>
      <FormField label="Description" label$alignment="top">
        <MemoEditor bind:value={description} variant="filled" />
      </FormField>
    </Cell>
  </Row>
</FormContainer>
```

## API Reference

### FormContainer

Main container component for structured row-based form layout.

#### Props

| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `style` | `string` | `''` | Custom CSS styles for the form container |
| `fieldLayout` | `'vertical' \| 'horizontal'` | `'vertical'` | Layout mode for form fields |
| `class` | `string` | `''` | Additional CSS classes for the container |

#### Slots

| Slot | Description |
|------|-------------|
| default | Form content containing Row components |

### Row

Container component for organizing cells in horizontal rows.

#### Props

| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `style` | `string` | `''` | Custom CSS styles for the row |
| `class` | `string` | `''` | Additional CSS classes for the row |

#### Slots

| Slot | Description |
|------|-------------|
| default | Cell components and content for the row |

### Cell

Grid cell component that spans specified columns within a row.

#### Props

| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `span` | `number` | `1` | Number of columns to span (1-12) |
| `style` | `string` | `''` | Custom CSS styles for the cell |
| `class` | `string` | `''` | Additional CSS classes for the cell |

#### Slots

| Slot | Description |
|------|-------------|
| default | Content for the cell (typically FormField components) |

## Grid System

The FlexRowForm uses a 12-column grid system where each Cell can span 1-12 columns:

- **span={1}**: 8.33% width (1/12)
- **span={2}**: 16.67% width (2/12)  
- **span={3}**: 25% width (3/12)
- **span={4}**: 33.33% width (4/12)
- **span={6}**: 50% width (6/12)
- **span={8}**: 66.67% width (8/12)
- **span={12}**: 100% width (12/12)

## Layout Examples

### Multi-Row Complex Form

```svelte
<FormContainer>
  <!-- Header Row -->
  <Row>
    <Cell span={12}>
      <FormField label="Project Title" required>
        <TextEditor bind:value={project.title} variant="filled" />
      </FormField>
    </Cell>
  </Row>
  
  <!-- Details Row -->
  <Row>
    <Cell span={4}>
      <FormField label="Start Date" required>
        <DatePicker bind:value={project.startDate} variant="filled" />
      </FormField>
    </Cell>
    
    <Cell span={4}>
      <FormField label="End Date">
        <DatePicker bind:value={project.endDate} variant="filled" />
      </FormField>
    </Cell>
    
    <Cell span={4}>
      <FormField label="Priority">
        <OptionsSelect bind:value={project.priority} options={priorities} />
      </FormField>
    </Cell>
  </Row>
  
  <!-- Contact Row -->
  <Row>
    <Cell span={6}>
      <FormField label="Project Manager">
        <TextEditor bind:value={project.manager} variant="filled" />
      </FormField>
    </Cell>
    
    <Cell span={6}>
      <FormField label="Contact Email">
        <TextEditor bind:value={project.email} variant="filled" />
      </FormField>
    </Cell>
  </Row>
  
  <!-- Description Row -->
  <Row>
    <Cell span={12}>
      <FormField label="Project Description" label$alignment="top">
        <MemoEditor bind:value={project.description} variant="filled" />
      </FormField>
    </Cell>
  </Row>
</FormContainer>
```

### Asymmetric Layout

```svelte
<FormContainer>
  <Row>
    <Cell span={8}>
      <FormField label="Main Information">
        <TextEditor bind:value={mainInfo} variant="filled" />
      </FormField>
    </Cell>
    
    <Cell span={4}>
      <FormField label="Code">
        <TextEditor bind:value={code} variant="filled" />
      </FormField>
    </Cell>
  </Row>
  
  <Row>
    <Cell span={3}>
      <FormField label="Type">
        <OptionsSelect bind:value={type} options={typeOptions} />
      </FormField>
    </Cell>
    
    <Cell span={3}>
      <FormField label="Status">
        <OptionsSelect bind:value={status} options={statusOptions} />
      </FormField>
    </Cell>
    
    <Cell span={6}>
      <FormField label="Reference">
        <TextEditor bind:value={reference} variant="filled" />
      </FormField>
    </Cell>
  </Row>
</FormContainer>
```

### Form Sections

```svelte
<FormContainer>
  <!-- Personal Information Section -->
  <Row>
    <Cell span={12}>
      <h3>Personal Information</h3>
    </Cell>
  </Row>
  
  <Row>
    <Cell span={6}>
      <FormField label="First Name" required>
        <TextEditor bind:value={personal.firstName} variant="filled" />
      </FormField>
    </Cell>
    
    <Cell span={6}>
      <FormField label="Last Name" required>
        <TextEditor bind:value={personal.lastName} variant="filled" />
      </FormField>
    </Cell>
  </Row>
  
  <!-- Contact Information Section -->
  <Row>
    <Cell span={12}>
      <h3>Contact Information</h3>
    </Cell>
  </Row>
  
  <Row>
    <Cell span={8}>
      <FormField label="Email Address" required>
        <TextEditor bind:value={contact.email} variant="filled" />
      </FormField>
    </Cell>
    
    <Cell span={4}>
      <FormField label="Phone">
        <TextEditor bind:value={contact.phone} variant="filled" />
      </FormField>
    </Cell>
  </Row>
</FormContainer>
```

## Validation and Error Handling

```svelte
<script>
  let formData = {
    name: '',
    email: '',
    phone: '',
    notes: ''
  };
  
  let errors = {};
  
  function validateForm() {
    errors = {};
    
    if (!formData.name?.trim()) {
      errors.name = 'Name is required';
    }
    
    if (!formData.email?.trim()) {
      errors.email = 'Email is required';
    } else if (!/\S+@\S+\.\S+/.test(formData.email)) {
      errors.email = 'Please enter a valid email address';
    }
    
    if (formData.phone && !/^\+?[\d\s\-()]+$/.test(formData.phone)) {
      errors.phone = 'Please enter a valid phone number';
    }
    
    return Object.keys(errors).length === 0;
  }
  
  function handleSubmit() {
    if (validateForm()) {
      console.log('Form submitted:', formData);
    }
  }
</script>

<FormContainer>
  <Row>
    <Cell span={6}>
      <FormField label="Full Name" required error={errors.name}>
        <TextEditor 
          bind:value={formData.name}
          variant="filled"
          placeholder="Enter your full name"
        />
      </FormField>
    </Cell>
    
    <Cell span={6}>
      <FormField label="Phone Number" error={errors.phone}>
        <TextEditor 
          bind:value={formData.phone}
          variant="filled"
          placeholder="Enter phone number"
        />
      </FormField>
    </Cell>
  </Row>
  
  <Row>
    <Cell span={12}>
      <FormField label="Email Address" required error={errors.email}>
        <TextEditor 
          bind:value={formData.email}
          variant="filled"
          placeholder="Enter email address"
        />
      </FormField>
    </Cell>
  </Row>
  
  <Row>
    <Cell span={12}>
      <FormField label="Additional Notes">
        <MemoEditor 
          bind:value={formData.notes}
          variant="filled"
          placeholder="Enter any additional notes..."
        />
      </FormField>
    </Cell>
  </Row>
  
  <Row>
    <Cell span={12} style="text-align: right; margin-top: 20px;">
      <button type="button" on:click={handleSubmit}>
        Submit Form
      </button>
    </Cell>
  </Row>
</FormContainer>
```

## Styling

### Custom Form Styling

```svelte
<FormContainer 
  style="
    max-width: 900px;
    margin: 2rem auto;
    padding: 2rem;
    border: 1px solid #e2e8f0;
    border-radius: 8px;
    background: #ffffff;
    box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
  "
>
  <Row style="margin-bottom: 1.5rem;">
    <Cell span={12}>
      <h2 style="margin: 0; color: #2d3748;">Form Title</h2>
    </Cell>
  </Row>
  
  <!-- Form content here -->
</FormContainer>
```

### CSS Classes

```css
.custom-form-container {
  max-width: 800px;
  margin: 0 auto;
  padding: 2rem;
  background: white;
  border-radius: 8px;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}

.custom-form-container .form-row {
  margin-bottom: 1.5rem;
}

.custom-form-container .form-row:last-child {
  margin-bottom: 0;
}

.custom-form-container .form-cell {
  padding: 0 0.5rem;
}
```

## Responsive Design

```svelte
<FormContainer class="responsive-form">
  <Row>
    <Cell span={4}>
      <FormField label="Field 1">
        <TextEditor bind:value={field1} />
      </FormField>
    </Cell>
    
    <Cell span={4}>
      <FormField label="Field 2">
        <TextEditor bind:value={field2} />
      </FormField>
    </Cell>
    
    <Cell span={4}>
      <FormField label="Field 3">
        <TextEditor bind:value={field3} />
      </FormField>
    </Cell>
  </Row>
</FormContainer>

<style>
  @media (max-width: 768px) {
    :global(.responsive-form .form-cell) {
      width: 100% !important;
      margin-bottom: 1rem;
    }
  }
  
  @media (max-width: 480px) {
    :global(.responsive-form) {
      padding: 1rem;
    }
  }
</style>
```

## Best Practices

### 1. Logical Row Organization

Group related fields in the same row:

```svelte
<FormContainer>
  <!-- Personal details in one row -->
  <Row>
    <Cell span={4}>
      <FormField label="First Name" required>
        <TextEditor bind:value={firstName} />
      </FormField>
    </Cell>
    
    <Cell span={4}>
      <FormField label="Last Name" required>
        <TextEditor bind:value={lastName} />
      </FormField>
    </Cell>
    
    <Cell span={4}>
      <FormField label="Date of Birth">
        <DatePicker bind:value={dateOfBirth} />
      </FormField>
    </Cell>
  </Row>
  
  <!-- Contact details in another row -->
  <Row>
    <Cell span={8}>
      <FormField label="Email Address" required>
        <TextEditor bind:value={email} />
      </FormField>
    </Cell>
    
    <Cell span={4}>
      <FormField label="Phone">
        <TextEditor bind:value={phone} />
      </FormField>
    </Cell>
  </Row>
</FormContainer>
```

### 2. Consistent Spacing

Use consistent cell spans for similar field types:

```svelte
<FormContainer>
  <Row>
    <!-- Standard text fields: 6 columns each -->
    <Cell span={6}>
      <FormField label="Username" required>
        <TextEditor bind:value={username} />
      </FormField>
    </Cell>
    
    <Cell span={6}>
      <FormField label="Department">
        <TextEditor bind:value={department} />
      </FormField>
    </Cell>
  </Row>
  
  <Row>
    <!-- Important fields: full width -->
    <Cell span={12}>
      <FormField label="Description">
        <MemoEditor bind:value={description} />
      </FormField>
    </Cell>
  </Row>
</FormContainer>
```

### 3. Form Sections

Use rows to create clear form sections:

```svelte
<FormContainer>
  <!-- Section Header -->
  <Row>
    <Cell span={12}>
      <h3 style="border-bottom: 1px solid #e2e8f0; padding-bottom: 0.5rem;">
        Account Information
      </h3>
    </Cell>
  </Row>
  
  <!-- Section Fields -->
  <Row>
    <Cell span={6}>
      <FormField label="Username" required>
        <TextEditor bind:value={username} />
      </FormField>
    </Cell>
    
    <Cell span={6}>
      <FormField label="Email" required>
        <TextEditor bind:value={email} />
      </FormField>
    </Cell>
  </Row>
</FormContainer>
```

## Comparison with FlexForm

| Feature | FlexRowForm | FlexForm |
|---------|-------------|----------|
| Structure | Explicit rows and cells | Automatic wrapping |
| Layout Control | High precision | Automatic flow |
| Row Management | Manual row breaks | Automatic wrapping |
| Use Case | Complex structured forms | Simple flowing forms |
| Complexity | Higher | Lower |

## Integration with Other Components

### With Dynamic Content

```svelte
<script>
  let items = [
    { id: 1, name: '', value: '' },
    { id: 2, name: '', value: '' }
  ];
  
  function addItem() {
    items = [...items, { id: Date.now(), name: '', value: '' }];
  }
  
  function removeItem(id) {
    items = items.filter(item => item.id !== id);
  }
</script>

<FormContainer>
  {#each items as item, index}
    <Row>
      <Cell span={5}>
        <FormField label="Name">
          <TextEditor bind:value={item.name} variant="filled" />
        </FormField>
      </Cell>
      
      <Cell span={5}>
        <FormField label="Value">
          <TextEditor bind:value={item.value} variant="filled" />
        </FormField>
      </Cell>
      
      <Cell span={2} style="display: flex; align-items: end;">
        <button type="button" on:click={() => removeItem(item.id)}>
          Remove
        </button>
      </Cell>
    </Row>
  {/each}
  
  <Row>
    <Cell span={12} style="text-align: center; margin-top: 1rem;">
      <button type="button" on:click={addItem}>
        Add Item
      </button>
    </Cell>
  </Row>
</FormContainer>
```

## Accessibility Features

- **Semantic Structure**: Proper form organization with logical tab order
- **Keyboard Navigation**: Standard form navigation patterns
- **Screen Reader Support**: Clear row and cell structure
- **Error Association**: Proper error message association with fields
- **Focus Management**: Logical focus flow through rows and cells

## Browser Support

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

## Related Components

- **FormField**: Form field wrapper with labels and validation
- **FlexForm**: Alternative automatic-wrapping form layout
- **TextEditor**: Single-line text input component
- **DatePicker**: Date selection component
- **OptionsSelect**: Dropdown selection component

## License

MIT License - see LICENSE file for details.