# Form & Input Components

# Form & Input Components

<details>
<summary>Relevant source files</summary>

The following files were used as context for generating this wiki page:

- [components.json](components.json)
- [postcss.config.js](postcss.config.js)
- [src/lib/components/entity-list-table/search/SearchSyntaxHighlighter.svelte](src/lib/components/entity-list-table/search/SearchSyntaxHighlighter.svelte)
- [src/lib/components/entity-list-table/toolbar/SearchBar.svelte](src/lib/components/entity-list-table/toolbar/SearchBar.svelte)
- [src/lib/components/ui/checkbox/index.ts](src/lib/components/ui/checkbox/index.ts)
- [src/lib/components/ui/form/form-field-errors.svelte](src/lib/components/ui/form/form-field-errors.svelte)
- [src/lib/components/ui/form/index.ts](src/lib/components/ui/form/index.ts)
- [src/lib/components/ui/form/translated-field-errors.svelte](src/lib/components/ui/form/translated-field-errors.svelte)
- [src/lib/components/ui/input-group/highlighted-input.svelte](src/lib/components/ui/input-group/highlighted-input.svelte)
- [src/lib/components/ui/input-group/index.ts](src/lib/components/ui/input-group/index.ts)
- [src/lib/components/ui/input-group/input-group-addon.svelte](src/lib/components/ui/input-group/input-group-addon.svelte)
- [src/lib/components/ui/input-group/input-group-button.svelte](src/lib/components/ui/input-group/input-group-button.svelte)
- [src/lib/components/ui/input-group/input-group-input.svelte](src/lib/components/ui/input-group/input-group-input.svelte)
- [src/lib/components/ui/input-group/input-group-text.svelte](src/lib/components/ui/input-group/input-group-text.svelte)
- [src/lib/components/ui/input-group/input-group-textarea.svelte](src/lib/components/ui/input-group/input-group-textarea.svelte)
- [src/lib/components/ui/input-group/input-group.svelte](src/lib/components/ui/input-group/input-group.svelte)
- [src/lib/components/ui/input/async-validated-input.svelte](src/lib/components/ui/input/async-validated-input.svelte)
- [src/lib/components/ui/multi-select/multi-select.svelte](src/lib/components/ui/multi-select/multi-select.svelte)
- [src/lib/components/ui/select/select.svelte](src/lib/components/ui/select/select.svelte)
- [src/lib/components/ui/textarea/index.ts](src/lib/components/ui/textarea/index.ts)
- [src/lib/types/validation.ts](src/lib/types/validation.ts)
- [src/lib/utils/zod-error-translator.ts](src/lib/utils/zod-error-translator.ts)

</details>



The Primebrick frontend utilizes a two-tier component architecture for forms. The base layer consists of vendored **Shadcn-Svelte** primitives located in `src/lib/components/ui/*`, while the top layer provides specialized, domain-aware components for asynchronous validation, search syntax highlighting, and localized error handling.

## Input Primitives

The codebase provides standard and enhanced input components to handle diverse data entry requirements.

### Standard Input & Textarea
Standard inputs are built upon the Shadcn-Svelte `Input` and `Textarea` primitives. They support all standard HTML attributes and are styled to match the application's design system using Tailwind CSS classes defined in `components.json` [components.json:1-20]().

### AsyncValidatedInput
The `AsyncValidatedInput` component provides a debounced mechanism for server-side validation (e.g., checking if a username or email is already taken) without requiring a full form submission.

*   **Debounce Logic**: It uses a `DEBOUNCE_DELAY` of 300ms and a `MIN_CHARS` threshold of 3 before triggering the validation function [src/lib/components/ui/input/async-validated-input.svelte:67-68]().
*   **Validation States**: The component tracks internal `status` using the `ValidationStatus` type: `idle`, `loading`, `valid`, `not-valid`, or `api-error` [src/lib/types/validation.ts:7-7]().
*   **Visual Feedback**: It renders status-specific icons (Lucide) in the right-hand side of the input field:
    *   `loading`: Spinning `LoaderCircle` [src/lib/components/ui/input/async-validated-input.svelte:176-177]().
    *   `valid`: Green `CircleCheckBig` [src/lib/components/ui/input/async-validated-input.svelte:178-179]().
    *   `not-valid`: Destructive-colored `TicketX` [src/lib/components/ui/input/async-validated-input.svelte:180-181]().
    *   `api-error`: Yellow `AlertTriangle` [src/lib/components/ui/input/async-validated-input.svelte:182-183]().

### InputGroup
The `InputGroup` system allows for combining multiple elements (addons, buttons, text, and inputs) into a single visual unit.

| Component | Role |
| :--- | :--- |
| `InputGroup` | The root container that manages the flex layout and border styling [src/lib/components/ui/input-group/input-group.svelte:1-12](). |
| `InputGroupAddon` | Container for icons or labels at the start/end of the group [src/lib/components/ui/input-group/input-group-addon.svelte:1-10](). |
| `InputGroupInput` | A borderless input that fills the remaining space [src/lib/components/ui/input-group/input-group-input.svelte:14-21](). |
| `InputGroupButton` | Specifically styled buttons for use within the group [src/lib/components/ui/input-group/input-group-button.svelte:1-15](). |
| `HighlightedInput` | A specialized input that uses an underlay to provide syntax highlighting [src/lib/components/ui/input-group/highlighted-input.svelte:25-66](). |

**Sources:** [src/lib/components/ui/input/async-validated-input.svelte:1-187](), [src/lib/types/validation.ts:1-8](), [src/lib/components/ui/input-group/index.ts:1-25]().

## Specialized Selection Components

### Select & MultiSelect
The `Select` and `MultiSelect` components are built using `Popover` and `Command` primitives to provide searchable dropdown interfaces.

*   **Select**: Used for single-value selection. It synchronizes internal state with external props using `$effect` and supports a `loading` state with a spinner [src/lib/components/ui/select/select.svelte:39-95]().
*   **MultiSelect**: Allows selecting multiple tags. It renders selected items as `Badge` components with a removal button [src/lib/components/ui/multi-select/multi-select.svelte:88-102](). It uses a checkbox-style visual in the dropdown to indicate selection [src/lib/components/ui/multi-select/multi-select.svelte:130-139]().

### Checkbox & Switch
The `Checkbox` implementation provides three semantic styling classes:
1.  `checkboxBaseClass`: The standard styling [src/lib/components/ui/checkbox/index.ts:7-8]().
2.  `checkboxVisualOnlyClass`: Used for items where the parent handles the click (e.g., in side sheets), disabling `pointer-events` [src/lib/components/ui/checkbox/index.ts:14-15]().
3.  `checkboxInteractiveClass`: Standard interactive checkbox for table row selection [src/lib/components/ui/checkbox/index.ts:21-22]().

**Sources:** [src/lib/components/ui/select/select.svelte:1-130](), [src/lib/components/ui/multi-select/multi-select.svelte:1-150](), [src/lib/components/ui/checkbox/index.ts:1-25]().

## Search & Syntax Highlighting

The `SearchBar` used in entity lists utilizes a "Double-Layer" approach for syntax highlighting within a text input.

### The HighlightedInput Mechanism
To achieve syntax highlighting while maintaining native input behavior (text selection, cursor movement), the `HighlightedInput` component renders two layers:
1.  **Underlay (Visual)**: A `div` containing `SearchSyntaxHighlighter` which renders the text with colored spans for wildcards [src/lib/components/ui/input-group/highlighted-input.svelte:27-48]().
2.  **Overlay (Interactive)**: A native `<input>` with `text-transparent` and `caret-foreground`, allowing the user to type while seeing the highlights from the layer below [src/lib/components/ui/input-group/highlighted-input.svelte:51-65]().

**Diagram: Search Input Data Flow**
```mermaid
graph TD
    subgraph "Natural Language Space"
        User["User Types 'cust*?'"]
    end

    subgraph "Code Entity Space"
        Input["input-group-input.svelte"]
        Highlighter["SearchSyntaxHighlighter.svelte"]
        SegFunction["searchSyntaxSegments()"]
        Store["search $state"]
    end

    User -->|oninput| Input
    Input -->|updates| Store
    Store -->|reactive| Highlighter
    Highlighter -->|calls| SegFunction
    SegFunction -->|returns| Segments["SearchSyntaxSeg[]"]
    Segments -->|render| UI["Colored Spans (\* and \?)"]
```

**Sources:** [src/lib/components/ui/input-group/highlighted-input.svelte:1-67](), [src/lib/components/entity-list-table/search/SearchSyntaxHighlighter.svelte:1-66](), [src/lib/components/entity-list-table/toolbar/SearchBar.svelte:40-97]().

## Form Validation & Error Handling

Primebrick uses **Formsnap** and **Zod** for form validation, with a custom translation layer for localized error messages.

### TranslatedFieldErrors
The `TranslatedFieldErrors` component wraps the Formsnap `FieldErrors` primitive to automatically translate Zod validation keys.

*   **Key Detection**: If an error string starts with `validation.`, it is passed to the `$t` translation function [src/lib/components/ui/form/translated-field-errors.svelte:18-29]().
*   **Parameter Mapping**: It extracts parameters from Zod error objects (like `minimum` or `maximum`) and passes them to the translation engine as `min` and `max` [src/lib/components/ui/form/translated-field-errors.svelte:22-26]().

**Diagram: Error Translation Pipeline**
```mermaid
graph LR
    subgraph "Validation Logic"
        Zod["Zod Schema"]
        Result["ZodError: { code: 'too_small', minimum: 5 }"]
    end

    subgraph "Translation Component"
        TFE["TranslatedFieldErrors.svelte"]
        Map["translateError()"]
        I18n["$t('validation.too_small', { min: 5 })"]
    end

    Zod --> Result
    Result --> TFE
    TFE --> Map
    Map --> I18n
    I18n --> UI["'Must be at least 5 characters'"]
```

**Sources:** [src/lib/components/ui/form/translated-field-errors.svelte:1-50](), [src/lib/i18n/index.ts]().

---
