# Cascade Select

> A cascader for picking a path through a hierarchy. The trigger reads "Electronics / Audio / Headphones"; columns open on hover or arrow keys, load children on demand with a spinner on the row, and search finds paths at every depth. It can pick any level, take several paths as chips, and becomes a drill-down list with a back header when the columns don't fit.

- Slug: `cascade-select`
- Category: [Selects](https://www.assembli.design/category/selects.md)
- Type: component
- Tags: cascader, select, hierarchy, category, drill-down, async, multiple, keyboard
- npm dependencies: @base-ui/react, lucide-react, motion
- shadcn/ui dependencies: none
- Live preview: https://www.assembli.design/preview/cascade-select
- Page: https://www.assembli.design/components/cascade-select

![Cascade Select preview](https://www.assembli.design/thumbnails/cascade-select-light.png)

## Props

Other props pass through to the root element.

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `options` (required) | `CascadeOption[]` |  |  |
| `loadChildren` | `(option: CascadeOption, path: CascadeOption[]) => Promise<CascadeOption[]>` |  | Loads the children of a node marked `isLeaf: false`. Gets the node and its path from the top. |
| `changeOnSelect` | `boolean` |  | Lets any level be picked, not only the last one. |
| `expandTrigger` | `"hover" \| "click"` |  | Whether hovering a parent opens its column, or only clicking does. Defaults to hover. |
| `showSearch` | `boolean` |  | Shows a search field that finds paths at every depth. Defaults to true. |
| `layout` | `"auto" \| "columns" \| "drill"` |  | `auto` shows columns side by side when they fit and a drill-down list with a back header when they don't. |
| `label` | `React.ReactNode` |  |  |
| `hint` | `React.ReactNode` |  |  |
| `description` | `React.ReactNode` |  |  |
| `error` | `React.ReactNode` |  | Replaces the description and marks the trigger `aria-invalid`. |
| `placeholder` | `React.ReactNode` |  |  |
| `searchPlaceholder` | `string` |  |  |
| `separator` | `string` |  | Shown between levels in the trigger. Defaults to "/". |
| `clearable` | `boolean` |  | Adds a clear button once something is picked. Defaults to true. |
| `maxChips` | `number` |  | Chips shown in the trigger in multiple mode before "+N". Defaults to 2. |
| `disabled` | `boolean` |  |  |
| `required` | `boolean` |  |  |
| `name` | `string` |  | Submits each picked path, joined with "/", with a surrounding form. |
| `open` | `boolean` |  |  |
| `defaultOpen` | `boolean` |  |  |
| `onOpenChange` | `(open: boolean) => void` |  |  |

## Install

One-time setup (needs a subscription):

1. Add the registry to the project's `components.json`: `{"@assembli":{"url":"https://www.assembli.design/r/{name}.json","headers":{"Authorization":"Bearer ${ASSEMBLI_API_KEY}"}}}` (merge into `"registries"`).
2. Put an API key from https://www.assembli.design/account in `.env.local` as `ASSEMBLI_API_KEY=asm_…`.

Then install with the shadcn CLI (writes `components/cascade-select/cascade-select.tsx` and installs dependencies):

```bash
npx shadcn@latest add @assembli/cascade-select
```

Registry item JSON: https://www.assembli.design/r/cascade-select.json (send `Authorization: Bearer <api key>`)

## Code

> Component source needs an Assembli subscription ($12/month or $96/year) and an API key sent as `Authorization: Bearer <key>`. To get one without copying anything, POST https://www.assembli.design/api/agent/login (or call the MCP tool connect_account), show the user the link it returns, and poll https://www.assembli.design/api/agent/token for the key. Or subscribe at https://www.assembli.design/pricing and create a key at https://www.assembli.design/account.
