# Combobox

## Overview

_[Design to fill]_

- **When to use**: _[Design to fill]_
- **When not to use**: _[Design to fill]_

## Anatomy

_[Design to fill]_

## Variants

| Prop         | Effect                                                    |
| ------------ | --------------------------------------------------------- |
| `isSmall`    | Renders the smaller trigger with `text-200` label sizing. |
| `hasError`   | Applies the error style to the trigger.                   |
| `hasWarning` | Applies the warning style to the trigger.                 |

## Props / API

### `Combobox<Value>`

| Prop           | Type                             | Default | Description                                                             |
| -------------- | -------------------------------- | ------- | ----------------------------------------------------------------------- |
| `options`      | `ComboboxOption<Value>[]`        | -       | The selectable items used to drive filtering and the value list.        |
| `value`        | `Value \| null`                  | -       | The controlled selected value.                                          |
| `defaultValue` | `Value \| null`                  | -       | The initial selected value for uncontrolled usage.                      |
| `onChange`     | `(value: Value \| null) => void` | -       | Called with the next value whenever selection changes.                  |
| `name`         | `string`                         | -       | Name for the underlying form field.                                     |
| `disabled`     | `boolean`                        | `false` | Disables the combobox.                                                  |
| `hasError`     | `boolean`                        | `false` | Applies the error style. Shared with the trigger via context.           |
| `hasWarning`   | `boolean`                        | `false` | Applies the warning style. Shared with the trigger via context.         |
| `isSmall`      | `boolean`                        | `false` | Renders the smaller size. Shared with the trigger via context.          |
| `children`     | `React.ReactNode`                | -       | The combobox content, typically `Combobox.Trigger` and `Combobox.Menu`. |

`ComboboxOption<Value>` is `{ value: Value; label: string; disabled?: boolean }`.

> `unsafe_open` forces the popup open. Do not use in production; it exists only for testing and documentation.

### `Combobox.Trigger<Value>`

| Prop          | Type                                | Default | Description                                            |
| ------------- | ----------------------------------- | ------- | ------------------------------------------------------ |
| `placeholder` | `string`                            | -       | Text shown when no value is selected.                  |
| `children`    | `(value: Value) => React.ReactNode` | -       | Renders the selected value inside the trigger.         |
| `aria-label`  | `string`                            | -       | Accessible label for the trigger.                      |
| `id`          | `string`                            | -       | Id for the trigger, for associating an external label. |

### `Combobox.Menu<Value>`

| Prop          | Type                                | Default     | Description                                               |
| ------------- | ----------------------------------- | ----------- | --------------------------------------------------------- |
| `placeholder` | `string`                            | `"Search…"` | Placeholder for the search input.                         |
| `searchLabel` | `string`                            | `"Search"`  | Accessible label for the search input. Override for l10n. |
| `children`    | `(value: Value) => React.ReactNode` | -           | Renders the list of `Combobox.Option`s.                   |

### `Combobox.Option<Value>`

| Prop       | Type              | Default | Description                       |
| ---------- | ----------------- | ------- | --------------------------------- |
| `value`    | `Value`           | -       | The value this option represents. |
| `disabled` | `boolean`         | `false` | Disables this option.             |
| `children` | `React.ReactNode` | -       | The option label.                 |

## States

- Default (idle)
- Hover
- Focus-visible
- Open
- Selected
- Error
- Warning
- Disabled

## Code examples

```tsx
import { useState } from "react";
import { Combobox } from "@mylighthouse/prism-react";

const options = [
  { value: "au", label: "Australia" },
  { value: "ca", label: "Canada" },
  { value: "us", label: "United States" },
];

export default function ComboboxExample(): React.JSX.Element {
  const [country, setCountry] = useState<string | null>(null);

  return (
    <Combobox options={options} value={country} onChange={setCountry}>
      <Combobox.Trigger placeholder="Select a country">
        {(value) => options.find((o) => o.value === value)?.label}
      </Combobox.Trigger>
      <Combobox.Menu>
        {(value) => (
          <Combobox.Option value={value}>
            {options.find((o) => o.value === value)?.label}
          </Combobox.Option>
        )}
      </Combobox.Menu>
    </Combobox>
  );
}
```

## A11y intent

_[Design to fill]_

- The trigger, search input, and list are built on the Base UI combobox primitives, so combobox roles, active-option tracking, and keyboard operation (type to filter, arrow keys, Enter, Escape) are handled correctly.
- The trigger must have an accessible name via `aria-label` or an external label associated through `id`.
- The search input has an accessible label (`searchLabel`, defaulting to "Search") so its purpose is announced.
- `hasError` / `hasWarning` are visual only, pair them with a programmatically associated message and don't rely on color alone to signal validity.
- The chevron icon is `aria-hidden`, as it is decorative.

## Cross-references

- **[Select](./select.md)**: a non-searchable dropdown for shorter option lists where filtering isn't needed.
