# Dropdown Menu

Displays a menu to the user —such as a set of actions or functions— triggered by a button.

## Import

```ts
import { DropdownMenu } from "@kobalte/core/dropdown-menu";
// or
import { Root, Trigger, ... } from "@kobalte/core/dropdown-menu";
// or (deprecated)
import { DropdownMenu } from "@kobalte/core";
```

## Features

* Exposed to assistive technology as a button with a menu using the [WAI-ARIA Menu Button](https://www.w3.org/WAI/ARIA/apg/patterns/menu-button/) design pattern.
* Supports modal and non-modal modes.
* Supports submenus.
* Supports items, labels, groups of items.
* Supports checkable items (single or multiple) with optional indeterminate state.
* Support disabled items.
* Complex item labeling support for accessibility.
* Keyboard opening and navigation support.
* Automatic scrolling support during keyboard navigation.
* Typeahead to allow focusing items by typing text.
* Optionally render a pointing arrow.
* Focus is fully managed.
* Can be controlled or uncontrolled.

## Anatomy

The dropdown menu consists of:

* **DropdownMenu:** The root container for a dropdown menu.
* **DropdownMenu.Trigger:** The button that toggles the menu.
* **DropdownMenu.Icon:** A small icon often displayed next to the menu trigger as a visual affordance for the fact it can be open.
* **DropdownMenu.Portal:** Portals its children into the `body` when the menu is open.
* **DropdownMenu.Content:** Contains the content to be rendered when the menu is open.
* **DropdownMenu.Arrow:** An optional arrow element to render alongside the menu content.
* **DropdownMenu.Separator:** Used to visually separate items in the menu.
* **DropdownMenu.Group:** Used to group multiple items. Use in conjunction with `DropdownMenu.GroupLabel` to ensure good accessibility via automatic labelling.
* **DropdownMenu.GroupLabel:** Used to render the label of a group. It won't be focusable using arrow keys.
* **DropdownMenu.Sub:** Contains all the parts of a submenu.
* **DropdownMenu.SubTrigger:** An item that opens a submenu. Must be rendered inside `DropdownMenu.Sub`.
* **DropdownMenu.SubContent:** The component that pops out when a submenu is open. Must be rendered inside `DropdownMenu.Sub`.

The menu item consists of:

* **DropdownMenu.Item:** An item of the select.
* **DropdownMenu.ItemLabel:** An accessible label to be announced for the item.
* **DropdownMenu.ItemDescription:** An optional accessible description to be announced for the item.
* **DropdownMenu.ItemIndicator:** The visual indicator rendered when the item is checked.

The checkable menu item consists of:

* **DropdownMenu.RadioGroup:** Used to group multiple `DropdownMenu.RadioItem`s and manage the selection.
* **DropdownMenu.RadioItem:** An item that can be controlled and rendered like a radio.
* **DropdownMenu.CheckboxItem:** An item that can be controlled and rendered like a checkbox.

```tsx
<DropdownMenu>
	<DropdownMenu.Trigger>
		<DropdownMenu.Icon />
	</DropdownMenu.Trigger>

	<DropdownMenu.Portal>
		<DropdownMenu.Content>
			<DropdownMenu.Arrow />

			<DropdownMenu.Item>
				<DropdownMenu.ItemLabel />
				<DropdownMenu.ItemDescription />
			</DropdownMenu.Item>

			<DropdownMenu.Group>
				<DropdownMenu.GroupLabel />
				<DropdownMenu.Item />
			</DropdownMenu.Group>

			<DropdownMenu.CheckboxItem>
				<DropdownMenu.ItemIndicator />
			</DropdownMenu.CheckboxItem>

			<DropdownMenu.RadioGroup>
				<DropdownMenu.RadioItem>
					<DropdownMenu.ItemIndicator />
				</DropdownMenu.RadioItem>
			</DropdownMenu.RadioGroup>

			<DropdownMenu.Sub>
				<DropdownMenu.SubTrigger />
				<DropdownMenu.Portal>
					<DropdownMenu.SubContent />
				</DropdownMenu.Portal>
			</DropdownMenu.Sub>

			<DropdownMenu.Separator />
		</DropdownMenu.Content>
	</DropdownMenu.Portal>
</DropdownMenu>
```

## Example

:::preview
<BasicExample />

***

```tsx title="dropdown-menu.tsx" title="index.tsx" tab file="/opt/build/repo/apps/docs/src/examples/dropdown-menu.tsx#L11-L138"
import { DropdownMenu } from "@kobalte/core/dropdown-menu";

export function BasicExample() {
	const [showGitLog, setShowGitLog] = createSignal(true);
	const [showHistory, setShowHistory] = createSignal(false);
	const [branch, setBranch] = createSignal("main");

	return (
		<DropdownMenu>
			<DropdownMenu.Trigger class={style["dropdown-menu__trigger"]}>
				<span>Git Settings</span>
				<DropdownMenu.Icon class={style["dropdown-menu__trigger-icon"]}>
					<ChevronDownIcon />
				</DropdownMenu.Icon>
			</DropdownMenu.Trigger>
			<DropdownMenu.Portal>
				<DropdownMenu.Content class={style["dropdown-menu__content"]}>
					<DropdownMenu.Item class={style["dropdown-menu__item"]}>
						Commit{" "}
						<div class={style["dropdown-menu__item-right-slot"]}>⌘+K</div>
					</DropdownMenu.Item>
					<DropdownMenu.Item class={style["dropdown-menu__item"]}>
						Push{" "}
						<div class={style["dropdown-menu__item-right-slot"]}>⇧+⌘+K</div>
					</DropdownMenu.Item>
					<DropdownMenu.Item class={style["dropdown-menu__item"]} disabled>
						Update Project{" "}
						<div class={style["dropdown-menu__item-right-slot"]}>⌘+T</div>
					</DropdownMenu.Item>
					<DropdownMenu.Sub overlap gutter={4} shift={-8}>
						<DropdownMenu.SubTrigger
							class={style["dropdown-menu__sub-trigger"]}
						>
							GitHub
							<div class={style["dropdown-menu__item-right-slot"]}>
								<ChevronRightIcon width={20} height={20} />
							</div>
						</DropdownMenu.SubTrigger>
						<DropdownMenu.Portal>
							<DropdownMenu.SubContent
								class={style["dropdown-menu__sub-content"]}
							>
								<DropdownMenu.Item class={style["dropdown-menu__item"]}>
									Create Pull Request…
								</DropdownMenu.Item>
								<DropdownMenu.Item class={style["dropdown-menu__item"]}>
									View Pull Requests
								</DropdownMenu.Item>
								<DropdownMenu.Item class={style["dropdown-menu__item"]}>
									Sync Fork
								</DropdownMenu.Item>
								<DropdownMenu.Separator
									class={style["dropdown-menu__separator"]}
								/>
								<DropdownMenu.Item class={style["dropdown-menu__item"]}>
									Open on GitHub
								</DropdownMenu.Item>
							</DropdownMenu.SubContent>
						</DropdownMenu.Portal>
					</DropdownMenu.Sub>

					<DropdownMenu.Separator class={style["dropdown-menu__separator"]} />

					<DropdownMenu.CheckboxItem
						class={style["dropdown-menu__checkbox-item"]}
						checked={showGitLog()}
						onChange={setShowGitLog}
					>
						<DropdownMenu.ItemIndicator
							class={style["dropdown-menu__item-indicator"]}
						>
							<CheckIcon />
						</DropdownMenu.ItemIndicator>
						Show Git Log
					</DropdownMenu.CheckboxItem>
					<DropdownMenu.CheckboxItem
						class={style["dropdown-menu__checkbox-item"]}
						checked={showHistory()}
						onChange={setShowHistory}
					>
						<DropdownMenu.ItemIndicator
							class={style["dropdown-menu__item-indicator"]}
						>
							<CheckIcon />
						</DropdownMenu.ItemIndicator>
						Show History
					</DropdownMenu.CheckboxItem>

					<DropdownMenu.Separator class={style["dropdown-menu__separator"]} />

					<DropdownMenu.Group>
						<DropdownMenu.GroupLabel
							class={style["dropdown-menu__group-label"]}
						>
							Branches
						</DropdownMenu.GroupLabel>
						<DropdownMenu.RadioGroup value={branch()} onChange={setBranch}>
							<DropdownMenu.RadioItem
								class={style["dropdown-menu__radio-item"]}
								value="main"
							>
								<DropdownMenu.ItemIndicator
									class={style["dropdown-menu__item-indicator"]}
								>
									<DotFilledIcon />
								</DropdownMenu.ItemIndicator>
								main
							</DropdownMenu.RadioItem>
							<DropdownMenu.RadioItem
								class={style["dropdown-menu__radio-item"]}
								value="develop"
							>
								<DropdownMenu.ItemIndicator
									class={style["dropdown-menu__item-indicator"]}
								>
									<DotFilledIcon />
								</DropdownMenu.ItemIndicator>
								develop
							</DropdownMenu.RadioItem>
						</DropdownMenu.RadioGroup>
					</DropdownMenu.Group>

					<DropdownMenu.Arrow />
				</DropdownMenu.Content>
			</DropdownMenu.Portal>
		</DropdownMenu>
	);
}
```

```css title="dropdown-menu.module.css" title="style.css" tab file="/opt/build/repo/apps/docs/src/examples/dropdown-menu.module.css"
.dropdown-menu__trigger {
	appearance: none;
	border: none;
	display: inline-flex;
	justify-content: center;
	align-items: center;
	height: 40px;
	width: auto;
	outline: none;
	border-radius: 6px;
	padding: 0 16px;
	background-color: hsl(200 98% 39%);
	color: white;
	font-size: 16px;
	gap: 8px;
	line-height: 0;
	transition: 250ms background-color;
}

.dropdown-menu__trigger:hover {
	background-color: hsl(201 96% 32%);
}

.dropdown-menu__trigger:focus-visible {
	outline: 2px solid hsl(200 98% 39%);
	outline-offset: 2px;
}

.dropdown-menu__trigger:active {
	background-color: hsl(201 90% 27%);
}

.dropdown-menu__trigger-icon {
	height: 20px;
	width: 20px;
	flex: 0 0 20px;
	transition: transform 250ms;
}

.dropdown-menu__trigger-icon[data-expanded] {
	transform: rotate(180deg);
}

.dropdown-menu__content,
.dropdown-menu__sub-content {
	min-width: 220px;
	padding: 8px;
	background-color: white;
	border-radius: 6px;
	border: 1px solid hsl(240 6% 90%);
	box-shadow:
		0 4px 6px -1px rgb(0 0 0 / 0.1),
		0 2px 4px -2px rgb(0 0 0 / 0.1);
	outline: none;
	transform-origin: var(--kb-menu-content-transform-origin);
	animation: contentHide 250ms ease-in forwards;
}

.dropdown-menu__content[data-expanded],
.dropdown-menu__sub-content[data-expanded] {
	animation: contentShow 250ms ease-out;
}

.dropdown-menu__item,
.dropdown-menu__checkbox-item,
.dropdown-menu__radio-item,
.dropdown-menu__sub-trigger {
	font-size: 16px;
	line-height: 1;
	color: hsl(240 4% 16%);
	border-radius: 4px;
	display: flex;
	align-items: center;
	height: 32px;
	padding: 0 8px 0 24px;
	position: relative;
	user-select: none;
	outline: none;
}

.dropdown-menu__sub-trigger[data-expanded] {
	background-color: hsl(204 94% 94%);
	color: hsl(201 96% 32%);
}

.dropdown-menu__item[data-disabled],
.dropdown-menu__checkbox-item[data-disabled],
.dropdown-menu__radio-item[data-disabled],
.dropdown-menu__sub-trigger[data-disabled] {
	color: hsl(240 5% 65%);
	opacity: 0.5;
	pointer-events: none;
}

.dropdown-menu__item[data-highlighted],
.dropdown-menu__checkbox-item[data-highlighted],
.dropdown-menu__radio-item[data-highlighted],
.dropdown-menu__sub-trigger[data-highlighted] {
	outline: none;
	background-color: hsl(200 98% 39%);
	color: white;
}

.dropdown-menu__group-label {
	padding: 0 24px;
	font-size: 14px;
	line-height: 32px;
	color: hsl(240 4% 46%);
}

.dropdown-menu__separator {
	height: 1px;
	border-top: 1px solid hsl(240 6% 90%);
	margin: 6px;
}

.dropdown-menu__item-indicator {
	position: absolute;
	left: 0;
	height: 20px;
	width: 20px;
	display: inline-flex;
	align-items: center;
	justify-content: center;
}

.dropdown-menu__item-right-slot {
	margin-left: auto;
	padding-left: 20px;
	font-size: 14px;
	color: hsl(240 4% 46%);
}

[data-highlighted] > .dropdown-menu__item-right-slot {
	color: white;
}

[data-disabled] .dropdown-menu__item-right-slot {
	color: hsl(240 5% 65%);
	opacity: 0.5;
}

@keyframes contentShow {
	from {
		opacity: 0;
		transform: scale(0.96);
	}
	to {
		opacity: 1;
		transform: scale(1);
	}
}

@keyframes contentHide {
	from {
		opacity: 1;
		transform: scale(1);
	}
	to {
		opacity: 0;
		transform: scale(0.96);
	}
}

[data-theme*="dark"] .dropdown-menu__content,
[data-theme*="dark"] .dropdown-menu__sub-content {
	border: 1px solid hsl(240 5% 26%);
	background-color: hsl(240 4% 16%);
	box-shadow: none;
}

[data-theme*="dark"] .dropdown-menu__group-label {
	color: hsl(0 100% 100% / 0.7);
}

[data-theme*="dark"] .dropdown-menu__item,
[data-theme*="dark"] .dropdown-menu__checkbox-item,
[data-theme*="dark"] .dropdown-menu__radio-item,
[data-theme*="dark"] .dropdown-menu__sub-trigger {
	color: hsl(0 100% 100% / 0.9);
}

[data-theme*="dark"] .dropdown-menu__sub-trigger[data-expanded]:not([data-highlighted]) {
	background-color: hsl(202 80% 24% / 0.7);
	color: hsl(198 93% 60%);
}

[data-theme*="dark"] .dropdown-menu__separator {
	border-color: hsl(240 5% 34%);
}
```
:::

## Usage

### Default open

An initial, uncontrolled open value can be provided using the `defaultOpen` prop.

```tsx
<DropdownMenu defaultOpen>...</DropdownMenu>
```

### Controlled open

The `open` prop can be used to make the open state controlled. The `onOpenChange` event is fired when the user presses the trigger, an item or interact outside, and receives the new value.

:::preview
<ControlledExample />

***

```tsx {4,7}
import { createSignal } from "solid-js";

function ControlledExample() {
	const [open, setOpen] = createSignal(false);

	return (
		<DropdownMenu open={open()} onOpenChange={setOpen}>
			<DropdownMenu.Trigger>{open() ? "Close" : "Open"}</DropdownMenu.Trigger>
			<DropdownMenu.Portal>
				<DropdownMenu.Content>...</DropdownMenu.Content>
			</DropdownMenu.Portal>
		</DropdownMenu>
	);
}
```
:::

### Origin-aware animations

We expose a CSS custom property `--kb-menu-content-transform-origin` which can be used to animate the content from its computed origin.

```css {3}
/* style.css */
.dropdown-menu__content,
.dropdown-menu__sub-content {
	transform-origin: var(--kb-menu-content-transform-origin);
	animation: contentHide 250ms ease-in forwards;
}

.dropdown-menu__content[data-expanded],
.dropdown-menu__sub-content[data-expanded] {
	animation: contentShow 250ms ease-out;
}

@keyframes contentShow {
	from {
		opacity: 0;
		transform: scale(0.96);
	}
	to {
		opacity: 1;
		transform: scale(1);
	}
}

@keyframes contentHide {
	from {
		opacity: 1;
		transform: scale(1);
	}
	to {
		opacity: 0;
		transform: scale(0.96);
	}
}
```

## API Reference

### DropdownMenu

`DropdownMenu` is equivalent to the `Root` import from `@kobalte/core/dropdown-menu` (and deprecated `DropdownMenu.Root`).

| Prop          | Description                                                                                                                                                                                                                                                                                                                                         |
| :------------ | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| open          | `boolean` <br /> The controlled open state of the menu.                                                                                                                                                                                                                                                                                             |
| defaultOpen   | `boolean` <br /> The default open state when initially rendered. Useful when you do not need to control the open state.                                                                                                                                                                                                                             |
| onOpenChange  | `(open: boolean) => void` <br /> Event handler called when the open state of the menu changes.                                                                                                                                                                                                                                                      |
| id            | `string` <br /> A unique identifier for the component. The id is used to generate id attributes for nested components. If no id prop is provided, a generated id will be used.                                                                                                                                                                      |
| modal         | `boolean` <br /> Whether the menu should be the only visible content for screen readers, when set to `true`: <br /> - interaction with outside elements will be disabled. <br /> - scroll will be locked. <br /> - focus will be locked inside the menu content. <br /> - elements outside the menu content will not be visible for screen readers. |
| preventScroll | `boolean` <br /> Whether the scroll should be locked even if the menu is not modal.                                                                                                                                                                                                                                                                 |
| forceMount    | `boolean` <br /> Used to force mounting the menu (portal and content) when more control is needed. Useful when controlling animation with SolidJS animation libraries.                                                                                                                                                                              |

`DropdownMenu` also accepts the following props to customize the placement of the `DropdownMenu.Content`.

| Prop             | Description                                                                                                                                                                                                                                                                                                                                                              |
| :--------------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| getAnchorRect    | `(anchor?: HTMLElement) => AnchorRect  \| undefined` <br /> Function that returns the trigger element's DOMRect.                                                                                                                                                                                                                                                         |
| placement        | `Placement` <br /> The placement of the menu content.                                                                                                                                                                                                                                                                                                                    |
| gutter           | `number` <br /> The distance between the menu content and the trigger element. By default, it's 0 plus half of the arrow offset, if it exists.                                                                                                                                                                                                                           |
| shift            | `number` <br /> The skidding of the menu content along the trigger element.                                                                                                                                                                                                                                                                                              |
| flip             | `boolean \| string` <br /> Controls the behavior of the menu content when it overflows the viewport:<br /> - If a `boolean`, specifies whether the menu content should flip to the opposite side when it overflows.<br /> - If a `string`, indicates the preferred fallback placements when it overflows.<br />The placements must be spaced-delimited, e.g. "top left". |
| slide            | `boolean` <br /> Whether the menu content should slide when it overflows.                                                                                                                                                                                                                                                                                                |
| overlap          | `boolean` <br /> Whether the menu content can overlap the trigger element when it overflows.                                                                                                                                                                                                                                                                             |
| sameWidth        | `boolean` <br /> Whether the menu content should have the same width as the trigger element. This will be exposed to CSS as `--kb-popper-anchor-width`.                                                                                                                                                                                                                  |
| fitViewport      | `boolean` <br /> Whether the menu content should fit the viewport. If this is set to true, the menu content will have `maxWidth` and `maxHeight` set to the viewport size. This will be exposed to CSS as `--kb-popper-content-available-width` and `--kb-popper-content-available-height`.                                                                              |
| hideWhenDetached | `boolean` <br /> Whether to hide the menu content when the trigger element becomes occluded.                                                                                                                                                                                                                                                                             |
| detachedPadding  | `number` <br /> The minimum padding in order to consider the trigger element occluded.                                                                                                                                                                                                                                                                                   |
| arrowPadding     | `number` <br /> The minimum padding between the arrow and the menu content corner.                                                                                                                                                                                                                                                                                       |
| overflowPadding  | `number` <br /> The minimum padding between the menu content and the viewport edge. This will be exposed to CSS as `--kb-popper-overflow-padding`.                                                                                                                                                                                                                       |

### DropdownMenu.Trigger

`DropdownMenu.Trigger` consists of [Button](/docs/core/components/button).

| Data attribute | Description                     |
| :------------- | :------------------------------ |
| data-expanded  | Present when the menu is open.  |
| data-closed    | Present when the menu is close. |

`DropdownMenu.Icon`, `DropdownMenu.Content`, `DropdownMenu.SubTrigger` and `DropdownMenu.SubContent` share the same data-attributes.

### DropdownMenu.Content

The popper positioner will copy the same `z-index` as the `DropdownMenu.Content`.

| Prop                 | Description                                                                                                                                                                                                          |
| :------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| onOpenAutoFocus      | `(event: Event) => void` <br /> Event handler called when focus moves into the component after opening. It can be prevented by calling `event.preventDefault`.                                                       |
| onCloseAutoFocus     | `(event: Event) => void` <br /> Event handler called when focus moves to the trigger after closing. It can be prevented by calling `event.preventDefault`.                                                           |
| onEscapeKeyDown      | `(event: KeyboardEvent) => void` <br /> Event handler called when the escape key is down. It can be prevented by calling `event.preventDefault`.                                                                     |
| onPointerDownOutside | `(event: PointerDownOutsideEvent) => void` <br /> Event handler called when a pointer event occurs outside the bounds of the component. It can be prevented by calling `event.preventDefault`.                       |
| onFocusOutside       | `(event: FocusOutsideEvent) => void` <br /> Event handler called when the focus moves outside the bounds of the component. It can be prevented by calling `event.preventDefault`.                                    |
| onInteractOutside    | `(event: InteractOutsideEvent) => void` <br /> Event handler called when an interaction (pointer or focus event) happens outside the bounds of the component. It can be prevented by calling `event.preventDefault`. |

### DropdownMenu.Arrow

| Prop | Description                            |
| :--- | :------------------------------------- |
| size | `number` <br /> The size of the arrow. |

### DropdownMenu.Item

| Prop          | Description                                                                                                                                                                                                                                                                                                         |
| :------------ | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| textValue     | `string` <br /> Optional text used for typeahead purposes. By default, the typeahead behavior will use the .textContent of the `DropdownMenu.ItemLabel` part if provided, or fallback to the .textContent of the `DropdownMenu.Item`. Use this when the content is complex, or you have non-textual content inside. |
| disabled      | `boolean` <br /> Whether the item is disabled or not.                                                                                                                                                                                                                                                               |
| closeOnSelect | `boolean` <br /> Whether the menu should close when the item is activated.                                                                                                                                                                                                                                          |
| onSelect      | `() => void` <br /> Event handler called when the user selects an item (via mouse or keyboard).                                                                                                                                                                                                                     |

| Data attribute   | Description                           |
| :--------------- | :------------------------------------ |
| data-disabled    | Present when the item is disabled.    |
| data-highlighted | Present when the item is highlighted. |

`DropdownMenu.ItemLabel`, `DropdownMenu.ItemDescription` and `DropdownMenu.ItemIndicator` shares the same data-attributes.

### DropdownMenu.ItemIndicator

| Prop       | Description                                                                                                                              |
| :--------- | :--------------------------------------------------------------------------------------------------------------------------------------- |
| forceMount | `boolean` <br /> Used to force mounting when more control is needed. Useful when controlling animation with SolidJS animation libraries. |

### DropdownMenu.RadioGroup

| Prop         | Description                                                                                                                                                           |
| :----------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| value        | `string` <br /> The controlled value of the menu radio item to check.                                                                                                 |
| defaultValue | `string` <br /> The value of the menu radio item that should be checked when initially rendered. Useful when you do not need to control the state of the radio group. |
| onChange     | `(value: string) => void` <br /> Event handler called when the value changes.                                                                                         |
| disabled     | `boolean` <br /> Whether the radio group is disabled or not.                                                                                                          |

### DropdownMenu.RadioItem

| Prop          | Description                                                                                                                                                                                                                                                                                                         |
| :------------ | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| value         | `string` <br /> The value of the menu item radio.                                                                                                                                                                                                                                                                   |
| textValue     | `string` <br /> Optional text used for typeahead purposes. By default, the typeahead behavior will use the .textContent of the `DropdownMenu.ItemLabel` part if provided, or fallback to the .textContent of the `DropdownMenu.Item`. Use this when the content is complex, or you have non-textual content inside. |
| disabled      | `boolean` <br /> Whether the item is disabled or not.                                                                                                                                                                                                                                                               |
| closeOnSelect | `boolean` <br /> Whether the menu should close when the item is checked.                                                                                                                                                                                                                                            |
| onSelect      | `() => void` <br /> Event handler called when the user selects an item (via mouse or keyboard).                                                                                                                                                                                                                     |

| Data attribute   | Description                           |
| :--------------- | :------------------------------------ |
| data-disabled    | Present when the item is disabled.    |
| data-checked     | Present when the item is checked.     |
| data-highlighted | Present when the item is highlighted. |

### DropdownMenu.CheckboxItem

| Prop           | Description                                                                                                                                                                                                                                                                                                         |
| :------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| checked        | `boolean` <br /> The controlled checked state of the item.                                                                                                                                                                                                                                                          |
| defaultChecked | `boolean` <br /> The default checked state when initially rendered. Useful when you do not need to control the checked state.                                                                                                                                                                                       |
| onChange       | `(checked: boolean) => void` <br /> Event handler called when the checked state of the item changes.                                                                                                                                                                                                                |
| textValue      | `string` <br /> Optional text used for typeahead purposes. By default, the typeahead behavior will use the .textContent of the `DropdownMenu.ItemLabel` part if provided, or fallback to the .textContent of the `DropdownMenu.Item`. Use this when the content is complex, or you have non-textual content inside. |
| indeterminate  | `boolean` <br /> Whether the item is in an indeterminate state.                                                                                                                                                                                                                                                     |
| disabled       | `boolean` <br /> Whether the item is disabled or not.                                                                                                                                                                                                                                                               |
| closeOnSelect  | `boolean` <br /> Whether the menu should close when the item is checked/unchecked.                                                                                                                                                                                                                                  |
| onSelect       | `() => void` <br /> Event handler called when the user selects an item (via mouse or keyboard).                                                                                                                                                                                                                     |

| Data attribute     | Description                                         |
| :----------------- | :-------------------------------------------------- |
| data-disabled      | Present when the item is disabled.                  |
| data-indeterminate | Present when the item is in an indeterminate state. |
| data-checked       | Present when the item is checked.                   |
| data-highlighted   | Present when the item is highlighted.               |

### DropdownMenu.Sub

| Prop         | Description                                                                                                             |
| :----------- | :---------------------------------------------------------------------------------------------------------------------- |
| open         | `boolean` <br /> The controlled open state of the sub menu.                                                             |
| defaultOpen  | `boolean` <br /> The default open state when initially rendered. Useful when you do not need to control the open state. |
| onOpenChange | `(open: boolean) => void` <br /> Event handler called when the open state of the sub menu changes.                      |

`DropdownMenu.Sub` also accepts the following props to customize the placement of the `DropdownMenu.SubContent`.

| Prop             | Description                                                                                                                                                                                                                                                                                         |
| :--------------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| getAnchorRect    | `(anchor?: HTMLElement) => AnchorRect  \| undefined` <br /> Function that returns the trigger element's DOMRect.                                                                                                                                                                                    |
| gutter           | `number` <br /> The distance between the sub menu content and the trigger element. By default, it's 0 plus half of the arrow offset, if it exists.                                                                                                                                                  |
| shift            | `number` <br /> The skidding of the sub menu content along the trigger element.                                                                                                                                                                                                                     |
| slide            | `boolean` <br /> Whether the sub menu content should slide when it overflows.                                                                                                                                                                                                                       |
| overlap          | `boolean` <br /> Whether the sub menu content can overlap the trigger element when it overflows.                                                                                                                                                                                                    |
| fitViewport      | `boolean` <br /> Whether the sub menu content should fit the viewport. If this is set to true, the sub menu content will have `maxWidth` and `maxHeight` set to the viewport size. This will be exposed to CSS as `--kb-popper-content-available-width` and `--kb-popper-content-available-height`. |
| hideWhenDetached | `boolean` <br /> Whether to hide the sub menu content when the trigger element becomes occluded.                                                                                                                                                                                                    |
| detachedPadding  | `number` <br /> The minimum padding in order to consider the trigger element occluded.                                                                                                                                                                                                              |
| arrowPadding     | `number` <br /> The minimum padding between the arrow and the sub menu content corner.                                                                                                                                                                                                              |
| overflowPadding  | `number` <br /> The minimum padding between the sub menu content and the viewport edge. This will be exposed to CSS as `--kb-popper-overflow-padding`.                                                                                                                                              |

### DropdownMenu.SubTrigger

| Prop      | Description                                                                                                                                                                                                                             |
| :-------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| textValue | `string` <br /> Optional text used for typeahead purposes. By default, the typeahead behavior will use the .textContent of the `DropdownMenu.SubTrigger`. Use this when the content is complex, or you have non-textual content inside. |
| disabled  | `boolean` <br /> Whether the sub menu trigger is disabled or not.                                                                                                                                                                       |

| Data attribute   | Description                           |
| :--------------- | :------------------------------------ |
| data-disabled    | Present when the item is disabled.    |
| data-highlighted | Present when the item is highlighted. |

### DropdownMenu.SubContent

| Prop                 | Description                                                                                                                                                                                                          |
| :------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| onEscapeKeyDown      | `(event: KeyboardEvent) => void` <br /> Event handler called when the escape key is down. It can be prevented by calling `event.preventDefault`.                                                                     |
| onPointerDownOutside | `(event: PointerDownOutsideEvent) => void` <br /> Event handler called when a pointer event occurs outside the bounds of the component. It can be prevented by calling `event.preventDefault`.                       |
| onFocusOutside       | `(event: FocusOutsideEvent) => void` <br /> Event handler called when the focus moves outside the bounds of the component. It can be prevented by calling `event.preventDefault`.                                    |
| onInteractOutside    | `(event: InteractOutsideEvent) => void` <br /> Event handler called when an interaction (pointer or focus event) happens outside the bounds of the component. It can be prevented by calling `event.preventDefault`. |

## Rendered elements

| Component                      | Default rendered element |
| :----------------------------- | :----------------------- |
| `DropdownMenu`                 | none                     |
| `DropdownMenu.Trigger`         | `button`                 |
| `DropdownMenu.Icon`            | `span`                   |
| `DropdownMenu.Portal`          | `Portal`                 |
| `DropdownMenu.Content`         | `div`                    |
| `DropdownMenu.Arrow`           | `div`                    |
| `DropdownMenu.Separator`       | `hr`                     |
| `DropdownMenu.Group`           | `div`                    |
| `DropdownMenu.GroupLabel`      | `span`                   |
| `DropdownMenu.Sub`             | none                     |
| `DropdownMenu.SubTrigger`      | `div`                    |
| `DropdownMenu.SubContent`      | `div`                    |
| `DropdownMenu.Item`            | `div`                    |
| `DropdownMenu.ItemLabel`       | `div`                    |
| `DropdownMenu.ItemDescription` | `div`                    |
| `DropdownMenu.ItemIndicator`   | `div`                    |
| `DropdownMenu.RadioGroup`      | `div`                    |
| `DropdownMenu.RadioItem`       | `div`                    |
| `DropdownMenu.CheckboxItem`    | `div`                    |

## Accessibility

### Keyboard Interactions

| Key                                          | Description                                                                                                                                |
| :------------------------------------------- | :----------------------------------------------------------------------------------------------------------------------------------------- |
| <kbd>Space</kbd>                             | When focus is on the trigger, opens the menu and focuses the first item. <br /> When focus is on an item, activates the item.              |
| <kbd>Enter</kbd>                             | When focus is on the trigger, opens the menu and focuses the first item. <br /> When focus is on an item, activates the item.              |
| <kbd>ArrowDown</kbd>                         | When focus is on the trigger, opens the menu and focuses the first item. <br /> When focus is on an item, moves focus to the next item.    |
| <kbd>ArrowUp</kbd>                           | When focus is on the trigger, opens the menu and focuses the last item. <br /> When focus is on an item, moves focus to the previous item. |
| <kbd>ArrowRight</kbd> / <kbd>ArrowLeft</kbd> | When focus is on a sub menu trigger, opens or closes the submenu depending on reading direction.                                           |
| <kbd>Home</kbd>                              | When focus is on an item, moves focus to first item.                                                                                       |
| <kbd>End</kbd>                               | When focus is on an item, moves focus to last item.                                                                                        |
| <kbd>Esc</kbd>                               | Closes the menu and moves focus to the trigger.                                                                                            |