Innate UIv0.1.0
Overlays

Menu

A keyboard-navigable collection of actions, radio items, and checkable items.

Example

The preview is interactive. The code below it is the docs demo source; demo-only layout classes can be omitted in application code.

Right-click or press Shift+F10
tsx
import { Cell } from "retend";

import { Button, Menu } from "innate-ui";
import classes from "../docs.module.css";

export function MenuDemo() {
  const showDetails = Cell.source(true);
  const sort = Cell.source<"recent" | "name">("recent");

  return (
    <div class={classes.stack}>
      <Menu>
        <Menu.Trigger>
          <Button>Actions</Button>
        </Menu.Trigger>
        <Menu.Content>
          <Menu.Item textValue="Duplicate">Duplicate</Menu.Item>
          <Menu.Item textValue="Archive" disabled>
            Archive
          </Menu.Item>
          <Menu.CheckboxItem
            value={showDetails}
            onChange={(value) => showDetails.set(value)}
            textValue="Show details"
          >
            Show details
          </Menu.CheckboxItem>
          <Menu.Separator />
          <Menu.RadioGroup value={sort} onChange={(value) => sort.set(value)}>
            <Menu.RadioItem value="recent" textValue="Recent first">
              Recent first
            </Menu.RadioItem>
            <Menu.RadioItem value="name" textValue="Name">
              Name
            </Menu.RadioItem>
          </Menu.RadioGroup>
          <Menu.Separator />
          <Menu.Sub>
            <Menu.SubTrigger textValue="Export">Export</Menu.SubTrigger>
            <Menu.Content>
              <Menu.Item textValue="Export PDF">PDF</Menu.Item>
              <Menu.Item textValue="Export CSV">CSV</Menu.Item>
            </Menu.Content>
          </Menu.Sub>
          <Menu.Separator />
          <Menu.Item tone="danger" textValue="Delete">
            Delete
          </Menu.Item>
        </Menu.Content>
      </Menu>

      <Menu sideOffset={2}>
        <Menu.ContextTrigger>
          <div class={classes.contextMenuTarget}>Right-click or press Shift+F10</div>
        </Menu.ContextTrigger>
        <Menu.Content>
          <Menu.Item textValue="Open">Open</Menu.Item>
          <Menu.Item textValue="Rename">Rename</Menu.Item>
          <Menu.Sub>
            <Menu.SubTrigger textValue="Open with">Open with</Menu.SubTrigger>
            <Menu.Content>
              <Menu.Item textValue="Open in browser">Browser</Menu.Item>
              <Menu.Item textValue="Open in editor">Editor</Menu.Item>
            </Menu.Content>
          </Menu.Sub>
          <Menu.Separator />
          <Menu.Item tone="danger" textValue="Remove">
            Remove
          </Menu.Item>
        </Menu.Content>
      </Menu>
    </div>
  );
}

API reference

This table is generated from Innate UI's exported TypeScript declarations and JSDoc. Native element attributes inherited by a prop type are not repeated here.

MenuProps

PropTypeDefault
childrenrequired

Menu trigger, content, items, and optional nested submenu parts.

JSX.Children
open

Whether the popover is open.

JSX.ValueOrCell<boolean>false
side

Preferred side of the anchor.

JSX.ValueOrCell<PopoverSide>"bottom"
align

Preferred alignment along the anchor edge.

JSX.ValueOrCell<PopoverAlign>"center"
onOpenChange

Called when the popover requests an open-state change.

(open: boolean, reason?: PopoverCloseReason) => void
sideOffset

Gap in pixels between the anchor and content.

JSX.ValueOrCell<number>8
collisionPadding

Viewport padding used when resolving collisions.

JSX.ValueOrCell<number>8
triggerRef

Optional externally owned trigger element reference.

SourceCell<HTMLElement | null>
Inspect the typed source →