A button component that renders a labeled trigger with a trailing chevron, opening an `ActionsMenuDropdown` on click. The chevron rotates 180° when the menu is open, and the entire button surface lightens on hover/open state. ## Key Components ### `DropdownButton` The primary export. A composite trigger + dropdown built on top of `ActionsMenuDropdown`. Key behaviors: - Manages open/closed state internally via `React.useState` - Prevents interaction when `disabled` (blocks `onPointerDown` and ignores open-change calls) - Chevron animates via `rotate-180` when `open === true` - Renders an optional leading `icon` before the label text - Supports positioning via `align` (`start | center | end`) and `side` (`top | right | bottom | left`) ### `DropdownButtonProps` TypeScript interface defining the public API: | Prop | Type | Default | Description | |---|---|---|---| | `label` | `string` | — | Button text and fallback aria-label | | `icon` | `ReactNode` | — | Optional leading icon | | `items` | `ActionsMenuItem[]` | — | Dropdown menu items | | `disabled` | `boolean` | — | Disables interaction and dims the button | | `align` | `'start' \| 'center' \| 'end'` | `'end'` | Dropdown horizontal alignment | | `side` | `'top' \| 'right' \| 'bottom' \| 'left'` | `'bottom'` | Dropdown preferred side | | `ariaLabel` | `string` | `label` | Overrides the accessible label | | `className` | `string` | — | Additional classes on the button root | ## Usage Example ```typescript import { DropdownButton } from './dropdown-button' import { PlusIcon } from '../icons-v2-generated' const actions = [ { label: 'Export CSV', onSelect: () => handleExport('csv') }, { label: 'Export PDF', onSelect: () => handleExport('pdf') }, { label: 'Delete', onSelect: handleDelete, destructive: true }, ] export function ToolbarActions() { return ( } items={actions} align="end" side="bottom" /> ) } ``` > **Source:** [`dropdown-button.tsx`](https://github.com/flamingo-stack/openframe-oss-lib/blob/main/dropdown-button.tsx)