# Dropdown

```tsx
import { Dropdown, useDropdown } from '@tangible/ui';
```

Interactive docs and examples: [Dropdown in Storybook](https://storybook-tangible-ui.pages.dev/?path=/docs/overlays-dropdown--docs).

## Dropdown props

| Prop | Type | Default | Description |
| - | - | - | - |
| `children` | `React.ReactNode` | | |
| `defaultOpen?` | `boolean` | `false` | Default open state for uncontrolled usage. |
| `onOpenChange?` | `(open: boolean) => void` | | Callback when open state changes. |
| `open?` | `boolean` | | Controlled open state. |

### Dropdown.Trigger

Also exported as `DropdownTrigger`.

| Prop | Type | Default | Description |
| - | - | - | - |
| `children` | `React.ReactNode` | | |
| `asChild?` | `boolean` | `false` | When true, merges props onto the child element instead of wrapping in a span. Child must be a single React element that accepts ref and event handlers. |

### Dropdown.Content

Also exported as `DropdownContent`.

| Prop | Type | Default | Description |
| - | - | - | - |
| `children` | `React.ReactNode` | | |
| `align?` | `"center" \| "end" \| "start"` | `'start'` | Alignment along the side. |
| `className?` | `string` | | Additional CSS class names. |
| `side?` | `"bottom" \| "left" \| "right" \| "top"` | `'bottom'` | Preferred side of the trigger to place the dropdown. |
| `sideOffset?` | `number` | `4` | Distance from the trigger in pixels. |
| `style?` | `React.CSSProperties` | | Inline styles (use sparingly, prefer className). |

### Dropdown.Item

Also exported as `DropdownItem`.

| Prop | Type | Default | Description |
| - | - | - | - |
| `children` | `React.ReactNode` | | |
| `className?` | `string` | | Additional CSS class names. |
| `disabled?` | `boolean` | `false` | Whether the item is disabled. |
| `href?` | `string` | | URL to navigate to. When provided, renders as an anchor. |
| `keepOpen?` | `boolean` | `false` | When true, keeps the dropdown open after selection. |
| `onSelect?` | `() => void` | | Click handler for the item. |
| `target?` | `string` | `'_self'` | Link target (only applies when href is provided). |

### Dropdown.Separator

Also exported as `DropdownSeparator`.

| Prop | Type | Default | Description |
| - | - | - | - |
| `className?` | `string` | | Additional CSS class names. |

### Dropdown.Header

Also exported as `DropdownHeader`.

| Prop | Type | Default | Description |
| - | - | - | - |
| `children` | `React.ReactNode` | | |
| `className?` | `string` | | Additional CSS class names. |

## Hooks

### useDropdown

```ts
useDropdown(): DropdownContextValue
```

Returns:

| Member | Type | Description |
| - | - | - |
| `open` | `boolean` | |
| `setOpen` | `(open: boolean) => void` | |
| `triggerRef` | `React.RefObject<HTMLElement \| null>` | |
| `contentId` | `string` | |
| `activeIndex` | `number \| null` | |
| `setActiveIndex` | `(index: number \| null) => void` | |
| `openedVia` | `React.MutableRefObject<string \| null>` | Tracks how the dropdown was opened (e.g. 'ArrowUp') for initial focus. |

## Examples

- [ArrowDown Opens First](https://storybook-tangible-ui.pages.dev/?path=/story/overlays-dropdown--arrow-down-interaction): ArrowDown on trigger opens the menu with the first enabled item focused.

- [ArrowUp Opens Last](https://storybook-tangible-ui.pages.dev/?path=/story/overlays-dropdown--arrow-up-interaction): ArrowUp on trigger opens the menu with the last enabled item focused.

- [Separator/Header Skipped](https://storybook-tangible-ui.pages.dev/?path=/story/overlays-dropdown--separator-header-skip-interaction): Keyboard navigation skips Separator and Header sub-components.

- [Disabled Items Skipped](https://storybook-tangible-ui.pages.dev/?path=/story/overlays-dropdown--disabled-skip-interaction): Keyboard navigation skips disabled items.

- [Escape Restores Focus](https://storybook-tangible-ui.pages.dev/?path=/story/overlays-dropdown--escape-restore-interaction): Pressing Escape closes the menu and restores focus to the trigger.

Other stories: Basic, With Icons, Disabled Items, With Links, Placement, Alignment, IconButton Trigger, Keep Open on Select, Controlled, Without asChild, Keyboard Navigation, Separators & Headers, User Menu Pattern, Danger Actions, Static (Inspect) ([interactive page](https://storybook-tangible-ui.pages.dev/?path=/docs/overlays-dropdown--docs)).

## Component API tokens

Read via fallback, never declared. Set one on an ancestor to restyle every instance under it.

- `--tui-dropdown-bg`
- `--tui-dropdown-fg`
- `--tui-dropdown-radius`
- `--tui-dropdown-shadow`
- `--tui-dropdown-border`
- `--tui-dropdown-z`
- `--tui-dropdown-min-width`
- `--tui-dropdown-item-bg-hover`
- `--tui-dropdown-item-bg-active`
- `--tui-dropdown-item-fg`
- `--tui-dropdown-item-fg-hover`
- `--tui-dropdown-item-fg-active`

---

Interactive version: https://storybook-tangible-ui.pages.dev/?path=/docs/overlays-dropdown--docs
