# Core/SelectField - Usage

## Basic usage

```tsx
import { SelectField } from '@private/core';

const animals = [
  { id: '1', label: 'Dog' },
  { id: '2', label: 'Cat' },
  { id: '3', label: 'Bird' },
];

function Example() {
  return (
    <SelectField label="Animal" placeholder="Select" items={animals} />
  );
}
```

## Props

## Examples

### Single select

Pass `items` to render a list of options. Each item should have an `id` and a `label` property if using the default item renderer. You can also pass a custom item renderer to render each item as you need (see [Custom item renderer](#custom-item-renderer)).

```tsx
const animals = [
  { id: '1', label: 'Dog' },
  { id: '2', label: 'Cat' },
  { id: '3', label: 'Bird' },
];

<SelectField label="Animal" placeholder="Select" items={animals} />
```

### Multiple select

Set `selectionMode="multiple"` when more than one value can be selected. Selected options render as tags in the input.

```tsx
const states = [
  { id: '1', label: 'California' },
  { id: '2', label: 'New York' },
  { id: '3', label: 'Texas' },
];

<SelectField label="States" selectionMode="multiple" defaultValue={['CA', 'NY']} items={states} />
```

### Custom item renderer

When the default item renderer doesn't meet your needs, you can provide a custom item renderer. Each item **must** be a `SelectField.Item` or `SelectField.Section` component. `SelectField.Item` should be passed an `id` and `textValue` prop. `textValue` is used for typeahead and accessibility naming.

:::warning

For performance reasons, custom item renderers are cached on component mount. Custom item render functions should be pure functions that take only the passed item as an argument. Any reliance on external state or props will mostly likely cause unexpected and undesired behavior.

:::

```tsx
const users = [
  { id: '1', name: 'Malcolm Reynolds', email: 'malcolm.reynolds@example.com' },
  { id: '2', name: 'Inara Serra', email: 'inara.serra@example.com' },
  { id: '3', name: 'Kaylee Frye', email: 'kaylee.frye@example.com' },
];

<SelectField label="Users" selectionMode="multiple" defaultValue={['1', '2']} items={users}>
  {(user) => (
    <SelectField.Item id={user.id} textValue={user.name}>
      <div>{user.name}</div>
      <div>{user.email}</div>
    </SelectField.Item>
  )}
</SelectField>
```

### Searchable options

Enable `canSearch` for longer lists so users can filter options inside the popover.

```tsx
const categories = [
  { id: '1', name: 'Electronics' },
  { id: '2', name: 'Clothing' },
  { id: '3', name: 'Books' },
  // ...
  { id: '100', name: 'Other' },
];

<SelectField label="Category" items={categories} canSearch searchPlaceholder="Search categories">
  {(item) => (
    <SelectField.Item id={item.id} textValue={item.name}>
      {item.name}
    </SelectField.Item>
  )}
</SelectField>
```

When a search matches none of the options, the popover shows "No results" in place of the option list.

### Sections

Organize larger option lists into labeled groups by passing `items` with nested `children`, using the default item renderer. If a section has no visible `label`, provide `aria-label` on the section.

```tsx
const items = [
  {
    id: 'fruit',
    label: 'Fruit',
    children: [
      { id: 'apple', label: 'Apple' },
      { id: 'banana', label: 'Banana' },
    ],
  },
  {
    id: 'veg',
    label: 'Vegetable',
    children: [
      { id: 'broccoli', label: 'Broccoli' },
      { id: 'carrots', label: 'Carrots' },
    ],
  },
];

<SelectField label="Healthy Snack" placeholder="Select an item" items={items} />
```

Sections can also be built with `SelectField.Section` and `SelectField.Header` JSX children when using static options instead of `items`.

### Item icons

When an item has an `icon`, it renders before the label in the list. Selecting that item also shows the icon in the trigger for single select, or in the tag for multiple select.

```tsx
const items = [
  { id: '1', label: 'Favorites', icon: StarIcon },
  { id: '2', label: 'Settings', icon: CogIcon },
  { id: '3', label: 'Help', icon: HelpIcon },
];

<SelectField label="Menu" items={items} />
```