Overlays

DropdownMenu.

Actions that stay out of the way.

Live preview

Live preview
Choose an action
tsx
import { DropdownMenu, Button } from "luminescent";
import "luminescent/style.css";


export function Example() {
  return (
    <DropdownMenu
      trigger={<Button variant="secondary">Project actions</Button>}
      items={[
        { id: "duplicate", label: "Duplicate", onSelect: () => {} },
        { id: "archive", label: "Archive", disabled: true },
        { id: "delete", label: "Delete", destructive: true },
      ]}
    />
  );
}

Installation

bash
npm install luminescent

Import luminescent/style.css once at your application root. The example above uses the same package implementation as Storybook.

Variants and states

Use the preview controls to explore the supported variants, sizes, disabled/loading states and reduced motion. Controls appear only where the component exposes the corresponding prop. Theme and glow apply to every component.

Controlled and uncontrolled state

State contract: open / defaultOpen / onOpenChange. Omit the controlled prop to let the component own its initial state; supply a value and callback when your application owns it. Native uncontrolled fields and state-backed form controls participate in form reset. Controlled state must be reset by the application.

tsx
import { useState } from "react";
import { DropdownMenu, Button } from "luminescent";


export function ControlledExample() {
  const [value, setValue] = useState(false);
  return (
    <DropdownMenu
      open={value}
      onOpenChange={setValue}
      trigger={<Button>Actions</Button>}
      items={[{ id: "copy", label: "Copy", onSelect: () => {} }]}
    />
  );
}

API reference

Generated from the source TypeScript interfaces. Native attributes, className, style, aria-* and data-* also pass through to the documented element. Import DropdownMenuProps from the package for the full inherited contract.

PropTypeDetails
triggerrequiredReact.ReactElementOptional unless marked required.
itemsrequiredDropdownMenuItem[]Optional unless marked required.
labelstringOptional unless marked required.
openbooleanOptional unless marked required.
defaultOpenbooleanOptional unless marked required.
onOpenChange(open: boolean) => voidOptional unless marked required.
onAction(id: string) => voidOptional unless marked required.

Accessibility and keyboard

Radix menu: Enter/Space/ArrowDown opens, arrows and Home/End move, typing searches, Escape closes/restores focus. Disabled items are skipped. Use href for navigation and onSelect for actions. Does not expose nested/checkbox/radio menu items.

Keep labels meaningful and test application-level contrast, focus order and screen-reader output. See the accessibility guide for composition requirements.

Theme customization

tsx
import { LuminescentProvider, DropdownMenu, Button } from "luminescent";
import "luminescent/style.css";


export function Example() {
  return (
    <LuminescentProvider theme="light" accent="violet" glow="subtle">
      <DropdownMenu
        trigger={<Button variant="secondary">Project actions</Button>}
        items={[
          { id: "duplicate", label: "Duplicate", onSelect: () => {} },
          { id: "archive", label: "Archive", disabled: true },
          { id: "delete", label: "Delete", destructive: true },
        ]}
      />
    </LuminescentProvider>
  );
}

Switch between light and dark in the preview, or open the playground for a larger workspace. Custom CSS variables can override spacing, color, typography and effects.

Related components