npm package: @mehdashti/forms
Description: Enterprise-grade form management with validation, error handling, autosave, and advanced components
Author: mehdashti
Latest version: 1.0.0

# @mehdashti/forms

> Comprehensive form validation and management for Smart Platform

Built on React Hook Form + Zod with smart defaults and seamless integration with @mehdashti/ui components.

## Features

- ✅ **React Hook Form + Zod** - Type-safe validation with automatic error handling
- ✅ **Real-time Validation** - Validate on change by default
- ✅ **Smart Defaults** - Sensible defaults based on APISmith patterns
- ✅ **Form Field Components** - Pre-built field components with error display
- ✅ **Layout Components** - Ready-to-use 1, 2, 3, 4 column layouts (NEW!)
- ✅ **Form Sections** - Organize forms with titles and descriptions (NEW!)
- ✅ **Advanced Grids** - Custom column spans with FormGrid (NEW!)
- ✅ **Field Arrays** - Dynamic form fields support
- ✅ **TypeScript First** - Full type safety with excellent IntelliSense
- ✅ **@mehdashti/ui Integration** - Works seamlessly with platform UI components
- ✅ **Lightweight** - Minimal bundle size with tree-shaking support

## Installation

```bash
pnpm add @mehdashti/forms react-hook-form zod @hookform/resolvers
```

**Peer Dependencies:**
```bash
pnpm add react react-dom @mehdashti/ui @mehdashti/contracts
```

## Quick Start

### Basic Form

```typescript
import { useSmartForm, FormField, z } from '@mehdashti/forms'

const loginSchema = z.object({
  email: z.string().email('Invalid email address'),
  password: z.string().min(8, 'Password must be at least 8 characters'),
})

function LoginForm() {
  const form = useSmartForm({
    schema: loginSchema,
    onSubmit: async (data) => {
      await loginUser(data)
    },
  })

  return (
    <form onSubmit={form.handleSubmit}>
      <FormField
        name="email"
        label="Email"
        type="email"
        required
        control={form.control}
        placeholder="Enter your email"
      />

      <FormField
        name="password"
        label="Password"
        type="password"
        required
        control={form.control}
      />

      <button type="submit" disabled={form.isSubmitting}>
        {form.isSubmitting ? 'Loading...' : 'Login'}
      </button>
    </form>
  )
}
```

### Form with Select

```typescript
import { useSmartForm, FormField, FormSelect, z } from '@mehdashti/forms'

const connectionSchema = z.object({
  name: z.string().min(1, 'Name is required'),
  type: z.enum(['oracle', 'mssql', 'postgresql']),
  host: z.string().min(1, 'Host is required'),
  port: z.number().min(1).max(65535),
})

function ConnectionForm() {
  const form = useSmartForm({
    schema: connectionSchema,
    defaultValues: {
      type: 'oracle',
      port: 1521,
    },
    onSubmit: async (data) => {
      await createConnection(data)
    },
  })

  return (
    <form onSubmit={form.handleSubmit}>
      <FormField
        name="name"
        label="Connection Name"
        required
        control={form.control}
      />

      <FormSelect
        name="type"
        label="Database Type"
        required
        control={form.control}
        options={[
          { value: 'oracle', label: 'Oracle' },
          { value: 'mssql', label: 'MS SQL Server' },
          { value: 'postgresql', label: 'PostgreSQL' },
        ]}
      />

      <FormField
        name="host"
        label="Host"
        required
        control={form.control}
        placeholder="192.168.1.100"
      />

      <FormField
        name="port"
        label="Port"
        type="number"
        required
        control={form.control}
      />

      <button type="submit">Save Connection</button>
    </form>
  )
}
```

### Dynamic Field Arrays

```typescript
import { useSmartForm, useSmartFieldArray, FormField, z } from '@mehdashti/forms'

const orderSchema = z.object({
  customerName: z.string().min(1),
  items: z.array(
    z.object({
      name: z.string().min(1, 'Item name is required'),
      quantity: z.number().min(1, 'Quantity must be at least 1'),
    })
  ),
})

function OrderForm() {
  const form = useSmartForm({
    schema: orderSchema,
    defaultValues: {
      items: [{ name: '', quantity: 1 }],
    },
    onSubmit: async (data) => {
      await createOrder(data)
    },
  })

  const { fields, append, remove } = useSmartFieldArray({
    name: 'items',
    control: form.control,
    defaultValue: { name: '', quantity: 1 },
  })

  return (
    <form onSubmit={form.handleSubmit}>
      <FormField
        name="customerName"
        label="Customer Name"
        required
        control={form.control}
      />

      <div>
        <h3>Order Items</h3>
        {fields.map((field, index) => (
          <div key={field.id} className="flex gap-2">
            <FormField
              name={`items.${index}.name`}
              label="Item Name"
              required
              control={form.control}
            />

            <FormField
              name={`items.${index}.quantity`}
              label="Quantity"
              type="number"
              required
              control={form.control}
            />

            <button type="button" onClick={() => remove(index)}>
              Remove
            </button>
          </div>
        ))}

        <button type="button" onClick={() => append()}>
          Add Item
        </button>
      </div>

      <button type="submit">Create Order</button>
    </form>
  )
}
```

### Custom Validation

```typescript
import { useSmartForm, FormField, z } from '@mehdashti/forms'

const registrationSchema = z
  .object({
    email: z.string().email(),
    password: z.string().min(8),
    confirmPassword: z.string(),
  })
  .refine((data) => data.password === data.confirmPassword, {
    message: "Passwords don't match",
    path: ['confirmPassword'],
  })

function RegistrationForm() {
  const form = useSmartForm({
    schema: registrationSchema,
    onSubmit: async (data) => {
      await registerUser(data)
    },
    onError: (errors) => {
      console.error('Validation errors:', errors)
    },
  })

  return (
    <form onSubmit={form.handleSubmit}>
      <FormField
        name="email"
        label="Email"
        type="email"
        required
        control={form.control}
      />

      <FormField
        name="password"
        label="Password"
        type="password"
        required
        control={form.control}
        helpText="Must be at least 8 characters"
      />

      <FormField
        name="confirmPassword"
        label="Confirm Password"
        type="password"
        required
        control={form.control}
      />

      <button type="submit">Register</button>
    </form>
  )
}
```

## Form Layouts

Pre-built layout components for quick form creation.

### 1-Column Layout

```typescript
import { useSmartForm, FormField, FormLayout, z } from '@mehdashti/forms'

const form = useSmartForm({ schema, onSubmit: async (data) => {} })

return (
  <form onSubmit={form.handleSubmit}>
    <FormLayout columns={1}>
      <FormField name="email" label="Email" required control={form.control} />
      <FormField name="password" label="Password" type="password" required control={form.control} />
    </FormLayout>
  </form>
)
```

### 2-Column Layout

```typescript
import { FormLayout } from '@mehdashti/forms'

<FormLayout columns={2}>
  <FormField name="firstName" label="First Name" required control={form.control} />
  <FormField name="lastName" label="Last Name" required control={form.control} />
  <FormField name="email" label="Email" required control={form.control} />
  <FormField name="phone" label="Phone" required control={form.control} />
</FormLayout>
```

### 3-Column Layout

```typescript
<FormLayout columns={3}>
  <FormField name="name" label="Connection Name" required control={form.control} />
  <FormSelect name="type" label="Type" required control={form.control} options={types} />
  <FormField name="host" label="Host" required control={form.control} />
  <FormField name="port" label="Port" type="number" required control={form.control} />
  <FormField name="database" label="Database" required control={form.control} />
  <FormField name="username" label="Username" required control={form.control} />
</FormLayout>
```

### Form Sections

Organize forms into sections with titles:

```typescript
import { FormSection } from '@mehdashti/forms'

<div className="space-y-8">
  <FormSection title="Personal Information" description="Enter your details" columns={2}>
    <FormField name="firstName" label="First Name" required control={form.control} />
    <FormField name="lastName" label="Last Name" required control={form.control} />
  </FormSection>

  <FormSection title="Company Information" columns={2}>
    <FormField name="company" label="Company" required control={form.control} />
    <FormField name="position" label="Position" required control={form.control} />
  </FormSection>
</div>
```

### Advanced Grid Layouts

Use `FormGrid` and `FormGridItem` for custom column spans:

```typescript
import { FormGrid, FormGridItem } from '@mehdashti/forms'

<FormGrid>
  {/* Full width */}
  <FormGridItem colSpan="full">
    <FormField name="title" label="Title" required control={form.control} />
  </FormGridItem>

  {/* 2 columns */}
  <FormGridItem colSpan={1}>
    <FormField name="firstName" label="First Name" required control={form.control} />
  </FormGridItem>
  <FormGridItem colSpan={1}>
    <FormField name="lastName" label="Last Name" required control={form.control} />
  </FormGridItem>

  {/* Full width */}
  <FormGridItem colSpan="full">
    <FormField name="bio" label="Bio" control={form.control} />
  </FormGridItem>
</FormGrid>
```

**See [LAYOUT_EXAMPLES.md](./LAYOUT_EXAMPLES.md) for complete examples.**

## API Reference

### `useSmartForm(options)`

Main hook for form management.

**Options:**

| Option | Type | Default | Description |
|--------|------|---------|-------------|
| `schema` | `ZodSchema` | required | Zod validation schema |
| `onSubmit` | `function` | required | Submit handler |
| `onError` | `function` | optional | Error handler |
| `defaultValues` | `object` | optional | Initial form values |
| `realtimeValidation` | `boolean` | `true` | Enable validation on change |

**Returns:**

| Property | Type | Description |
|----------|------|-------------|
| `handleSubmit` | `function` | Form submit handler |
| `isSubmitting` | `boolean` | Whether form is submitting |
| `hasErrors` | `boolean` | Whether form has validation errors |
| `getError` | `function` | Get error message for a field |
| `control` | `Control` | React Hook Form control |
| `watch` | `function` | Watch field values |
| `setValue` | `function` | Set field value |
| `reset` | `function` | Reset form |
| `...` | | All React Hook Form methods |

### `<FormField>`

Smart form field component with automatic error handling.

**Props:**

| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `name` | `string` | required | Field name |
| `label` | `string` | required | Field label |
| `type` | `string` | `'text'` | Input type |
| `required` | `boolean` | `false` | Show required indicator |
| `placeholder` | `string` | optional | Placeholder text |
| `helpText` | `string` | optional | Help text below field |
| `disabled` | `boolean` | `false` | Disable field |
| `control` | `Control` | required | Form control |
| `render` | `function` | optional | Custom render function |

### `<FormSelect>`

Select field component.

**Props:**

Same as `FormField` plus:

| Prop | Type | Description |
|------|------|-------------|
| `options` | `SelectOption[]` | Select options |

### `<FormCheckbox>`

Checkbox field component.

**Props:**

| Prop | Type | Description |
|------|------|-------------|
| `name` | `string` | Field name |
| `label` | `string` | Checkbox label |
| `description` | `string` | Description text |
| `required` | `boolean` | Show required indicator |
| `control` | `Control` | Form control |

### `useSmartFieldArray(options)`

Hook for managing dynamic field arrays.

**Options:**

| Option | Type | Description |
|--------|------|-------------|
| `name` | `string` | Field array name |
| `control` | `Control` | Form control |
| `defaultValue` | `any` | Default value for new items |

**Returns:**

| Property | Type | Description |
|----------|------|-------------|
| `fields` | `array` | Current field array |
| `append` | `function` | Add new field |
| `remove` | `function` | Remove field by index |
| `insert` | `function` | Insert field at index |
| `move` | `function` | Move field |
| `swap` | `function` | Swap two fields |

## Integration with @mehdashti/ui

The form components are designed to work seamlessly with @mehdashti/ui. You can also use @mehdashti/ui components directly:

```typescript
import { useSmartForm, z } from '@mehdashti/forms'
import { Button, Input, Label } from '@mehdashti/ui'
import { Controller } from 'react-hook-form'

function CustomForm() {
  const form = useSmartForm({
    schema: z.object({
      name: z.string().min(1),
    }),
    onSubmit: async (data) => {
      console.log(data)
    },
  })

  return (
    <form onSubmit={form.handleSubmit}>
      <Controller
        name="name"
        control={form.control}
        render={({ field, fieldState: { error } }) => (
          <div>
            <Label>Name</Label>
            <Input {...field} />
            {error && <p className="text-destructive">{error.message}</p>}
          </div>
        )}
      />

      <Button type="submit">Submit</Button>
    </form>
  )
}
```

## Best Practices

1. **Export schemas** for reuse and testing
2. **Use TypeScript** for type safety
3. **Keep validation logic in schemas** not in components
4. **Use `watch`** sparingly for performance
5. **Debounce expensive validations** using Zod's `refine` with async
6. **Use `reset`** after successful submission
7. **Handle errors gracefully** with `onError` callback

## Examples

See the [examples directory](../../examples/forms) for complete working examples.

## License

MIT