Skip to content

Actions

IDropdownMenu

A menu opened from a button. Entries are data, and their shape decides what they render as — the same rule ISelect and INavigationMenu follow.

Nothing chosen yet.

Four shapes, one array, decided in this order:

The entryRenders as
The string '-'A separator
Has its own itemsA submenu
Has an onSelectA menu item
Has neitherA group label

Group labels are the intended use:

Danger items

danger colours a destructive entry. It does not confirm anything — pair it with useConfirm() when the action cannot be undone.

ts
const items = [
  { label: 'Archive', onSelect: () => archive() },
  '-',
  {
    label: 'Delete invoice',
    danger: true,
    onSelect: async () => {
      if (await confirm({ title: 'Delete this invoice?' }))
        remove()
    },
  },
]

Placement

side and align position the menu against its trigger, and sideOffset sets the distance. Like the tooltip, side is a preference — the menu flips when there is not enough room.

Icons

An entry's icon takes a Hugeicons icon or any component that renders an SVG.

ts
import { Delete02Icon, PencilEdit02Icon } from '@hugeicons/core-free-icons'

const items = [
  { label: 'Edit', icon: PencilEdit02Icon, onSelect: () => edit() },
  { label: 'Delete', icon: Delete02Icon, danger: true, onSelect: () => remove() },
]

Props

PropTypeDefaultDescription
itemsDropdownMenuEntry[][]The menu contents
align'start' | 'center' | 'end''start'Alignment against the trigger
side'top' | 'right' | 'bottom' | 'left''bottom'Preferred side; flips when it will not fit
sideOffsetnumber4Distance from the trigger, in px
unstyledbooleanDrop built-in classes
classstringMerged with the built-in classes
ui{ content?, item?, label?, separator?, subTrigger?, subContent? }Per-slot class overrides
ts
interface DropdownMenuItemOption {
  label: string
  icon?: IconLike
  disabled?: boolean
  danger?: boolean
  onSelect?: () => void
  /** Makes this entry a submenu. */
  items?: DropdownMenuEntry[]
}

type DropdownMenuEntry = DropdownMenuItemOption | '-'

Slots

SlotWhen to use it
triggerThe button that opens the menu. Required

A dropdown menu is for actions. For choosing a value, use ISelect — it has a model, the right ARIA roles, and typeahead.