# Option List

Option List [#option-list]

The **Option List** is an inline multi-choice selection list presented in a chat / agent turn for the user to pick from — distinct from quick-reply suggestion chips. It shows up to `pageSize` (5–7) options at a time and paginates longer lists. The chosen option is meant to feed back into your agent inquiry loop — for example a local human-in-the-loop disambiguation step (optionally [`useAgent`](https://localmode.dev/docs/react)).

It is presentational; the agent loop is owned by the consumer.

**When to use it:** when a local agent needs the user to disambiguate among several candidates ("Which file did you mean?") before continuing.

Preview [#preview]

```tsx
'use client';

import { useState } from 'react';
import { OptionList, type Option } from '@/components/option-list';

const OPTIONS: Option[] = [
  { id: 'report.pdf', label: 'report.pdf', description: 'Q4 financial report' },
  { id: 'report-draft.pdf', label: 'report-draft.pdf', description: 'Working draft' },
  { id: 'report-2023.pdf', label: 'report-2023.pdf', description: 'Last year' },
  { id: 'summary.md', label: 'summary.md', description: 'Executive summary' },
  { id: 'notes.txt', label: 'notes.txt', description: 'Meeting notes' },
  { id: 'budget.xlsx', label: 'budget.xlsx', description: 'Spreadsheet' },
  { id: 'roadmap.md', label: 'roadmap.md', description: 'Product roadmap' },
  { id: 'changelog.md', label: 'changelog.md', description: 'Release history' },
];

/**
 * Demo for OptionList, used by the docs live preview. Presents 8 disambiguation
 * choices (paginating past the 6-per-page limit); selecting one is what you
 * would feed back into a `useAgent` inquiry loop. Pure UI — no model download.
 */
export default function OptionListDemo() {
  const [chosen, setChosen] = useState<string | null>(null);

  return (
    <div className="flex w-full max-w-md flex-col gap-3">
      <OptionList
        prompt="Which file did you mean?"
        options={OPTIONS}
        selectedId={chosen ?? undefined}
        onSelect={(opt) => setChosen(opt.id)}
      />
      {chosen && (
        <p className="text-xs text-muted-foreground">
          Sent to agent: <span className="font-mono">{chosen}</span>
        </p>
      )}
    </div>
  );
}
```

Installation [#installation]

```bash
npx shadcn@latest add @localmode/ui/input-controls/option-list
```

Dependencies [#dependencies]

* **Data source:** renders the `options` you pass and emits the `onSelect` callback — works with any backend or agent loop. Recommended LocalMode producer: `useAgent` inquiry/human-in-the-loop (optional).
* `lucide-react` — the pagination icons
* `clsx` + `tailwind-merge` — via the shared `cn()` util (installed automatically)

Files installed [#files-installed]

* `option-list.tsx` — the component
* `lib/utils.ts` — the `cn()` helper (if not already present)

Props [#props]

**OptionList**

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `options` | `array` | — | **Required.** The choices to present. Lists longer than `pageSize` paginate. |
| `onSelect` | `function` | — | **Required.** Fired with the chosen option when the user selects one. |
| `pageSize` | `number` | `6` | Maximum options shown per page before paginating. |
| `prompt` | `string` | — | Optional prompt rendered above the choices. |
| `selectedId` | `string` | — | Currently selected option id (renders that option as active). |
| `disabled` | `boolean` | — | Disable interaction (e.g. while the agent is thinking). |

Examples [#examples]

Feed a `useAgent` inquiry [#feed-a-useagent-inquiry]

```tsx
import { OptionList } from '@/components/option-list';

export function Disambiguator({ candidates, onPick }) {
  return (
    <OptionList
      prompt="Which file did you mean?"
      options={candidates}
      onSelect={(opt) => onPick(opt.id)} // resume the agent loop with the choice
    />
  );
}
```

Custom page size [#custom-page-size]

```tsx
<OptionList options={options} onSelect={onSelect} pageSize={5} />
```

Customization [#customization]

Lists longer than `pageSize` paginate automatically with Prev / Next controls. Each option can carry a `description` for a secondary line. Pass `selectedId` to render the chosen option as active. Everything is theme-driven via shadcn/ui CSS variables — edit the copied file to change the row layout or add keyboard navigation.