import {ExampleCodeBlock, SymbolDoc, Specifications} from '@workday/canvas-kit-docs';
import Autocomplete from './examples/Autocomplete';

# Combobox

Combobox is an _abstract_ compound component - it should not be used on its own, but used as a base
to create combobox components. The Combobox system provides components, models, loaders, and
elemProps hooks.

The term "Combobox" is based on the
[Combobox Pattern](https://www.w3.org/WAI/ARIA/apg/patterns/combobox/) as defined in the ARIA
Authoring Practices Guide (APG):

> A [combobox](https://w3c.github.io/aria/#combobox) is an input widget with an associated popup
> that enables users to select a value for the combobox from a collection of possible values.

Examples of a "combobox" would be date pickers, autocomplete, and select components.

## Combobox value restriction

A Combobox can either be either "constrained" or "arbitrary".

### Constrained

A constrained combobox can only have a value from a set of values presented as options. The user can
pick from these values, but cannot input a value outside the options provided. Constrained
comboboxes use the [useComboboxInputConstrained](#usecomboboxinputconstrained) hook and often have
two separate `input` elements.

- user input - This is the visible input and it should contain user-friendly values. Calls to
  `.focus()` or `.blur()` are redirected to this input. Any prop passed to the `*.Input` component
  that is not directly related to forms will be passed here (i.e. `data-testid`, `aria-*`, etc).

- form input - This input is only visible to forms and the `value` will usually be server IDs. If
  the combobox options don't have an ID and only use user values, the value of this input will be
  the same as the user input. Any prop related to the function of forms will be passed here. For
  example, the `name` attribute will be passed here. The `ref` will be pointed to this element.

`Select` and `MultiSelect` are examples of constrained comboboxes.

### Arbitrary

An arbitrary combobox allows the user to enter any value. The list of options are presented as
suggestions and selecting an option will prefill the combobox with the value of the option. The user
is still allowed to modify the combobox even after an option is entered. With arbitrary comboboxes,
there is only one `input` element. Arbitrary combobox inputs should use the
[useComboboxInputArbitrary](#usecomboboxinputarbirary) hook. Typeahead or `Autocomplete` are
examples are arbitrary value comboboxes.

## Installation

```sh
yarn add @workday/canvas-kit-react
```

## Usage

### Autocomplete

This example shows an Autocomplete example using `FormField`, `InputGroup`, and the `Combobox`
components to make an autocomplete form field. It uses [useComboboxLoader](#usecomboboxloader) to
make mock API calls using `setTimeout`. Your application may use
[fetch](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API),
[WebSockets](https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API), or other means of
communicating with a server.

An Autocomplete is an example of an arbitrary combobox.

<ExampleCodeBlock code={Autocomplete} />

### Custom Styles

Combobox and its subcomponents support custom styling via the `cs` prop. For more information, check
our
["How To Customize Styles"](https://workday.github.io/canvas-kit/?path=/docs/styling-guides-customizing-styles--docs).

## Component API

<SymbolDoc name="Combobox" fileName="/react/" hideDescription />

## Hooks

<SymbolDoc name="useComboboxLoader" fileName="/react/" />

<SymbolDoc name="useComboboxInputConstrained" fileName="/react/" />

<SymbolDoc name="useComboboxInputArbitrary" fileName="/react/" />