# annex

Define supplementary document slots

Canonical URL: https://docs.paradoc.dev/sdk/artifacts/form/annex/

Define annex slots for supplementary documents that can be attached to a form. Annexes are predefined placeholders for supporting documents like IDs, contracts, or receipts.

## Examples

### Creating annexes

```ts
// Required document
const photoId = annex()
  .title('Photo ID')
  .description('Upload a government-issued photo ID')
  .required()
  .order(1)
  .build()

// Optional document
const proofOfAddress = annex()
  .title('Proof of Address')
  .description('Utility bill or bank statement')
  .build()

// Conditionally required (using logic expression)
const parentConsent = annex()
  .title('Parental Consent Form')
  .required('!isAdult')
  .visible('!isAdult')
  .build()
```

### Adding annexes to forms

```ts
// Object pattern
const form = p.form({
  name: 'application',
  annexes: {
    photoId: { title: 'Photo ID', required: true },
    proofOfAddress: { title: 'Proof of Address' }
  },
  allowAdditionalAnnexes: true  // Allow additional ad-hoc attachments
})

// Builder pattern
const form = p.form()
  .name('application')
  .annex('photoId', annex().title('Photo ID').required().build())
  .annex('proofOfAddress', annex().title('Proof of Address').build())
  .allowAdditionalAnnexes(true)
  .build()
```

## API

### Object Pattern

Create annex definitions directly as objects:

```ts
const annexDef: FormAnnex = {
  title: 'Photo ID',
  description: 'Government-issued photo identification',
  required: true,
  visible: true,
  order: 1
}
```

#### Properties

| Name | Type | Description |
| --- | --- | --- |
| `title?` | `string` | Display title for the annex slot |
| `description?` | `string` | Description of what document to attach |
| `required?` | `boolean \| string` | Whether annex must be filled. Can be an expression. |
| `visible?` | `boolean \| string` | Whether annex is visible. Can be an expression. |
| `order?` | `number` | Display order for rendering |

### Builder Pattern

Chain methods to build an annex incrementally:

Start with `annex()`. Each method returns `FormAnnexBuilder` and can be chained.

| Method | Description |
| --- | --- |
| `title(value: string)` | Set display title |
| `description(value: string)` | Set description text |
| `required(value?: boolean \| string)` | Mark as required (default: true). Accepts expression. |
| `visible(value?: boolean \| string)` | Set visibility (default: true). Accepts expression. |
| `order(value: number)` | Set display order for rendering |
| `from(value: FormAnnex)` | Initialize from existing annex |

Terminal methods return `FormAnnex`.

| Method | Description |
| --- | --- |
| `build()` | Build and validate |

### Static Methods

| Method | Returns | Description |
| --- | --- | --- |
| `parse(input: unknown)` | `FormAnnex` | Parse unknown input (throws on error) |
| `safeParse(input: unknown)` | `Result<FormAnnex>` | Parse unknown input (returns result object) |

## Conditional Annexes

Use defs for conditional requirements:

```ts
const form = p.form()
  .name('loan-application')
  .field('amount', field.number().label('Loan amount').build())
  .field('age', field.number().label('Applicant age').build())
  .def('isLargeAmount', 'fields.amount > 50000')
  .def('isMinor', 'fields.age < 18')
  .annex('financialStatements', annex()
    .title('Financial Statements')
    .description('Required for loans over $50,000')
    .required('isLargeAmount')
    .visible('isLargeAmount')
    .build())
  .annex('parentConsent', annex()
    .title('Parental Consent')
    .required('isMinor')
    .visible('isMinor')
    .build())
  .build()
```

## Ad-hoc Annexes

Set `allowAdditionalAnnexes: true` on the form to permit additional attachments beyond predefined slots:

```ts
const form = p.form({
  name: 'application',
  annexes: {
    requiredDoc: { title: 'Required Document', required: true }
  },
  allowAdditionalAnnexes: true  // Users can attach additional documents
})
```

An additional annex value must still be an [Attachment](/schemas/primitives/attachment). Without `allowAdditionalAnnexes: true`, a payload with an undeclared annex key fails validation. The inferred payload type (`InferFormPayload`) follows the same rule for the object pattern and the builder.

## Related

* [form](/sdk/artifacts/form) - Parent form artifact
* [Annex Schema](/schemas/artifacts/form/annex)
