Menu
Context menu for right-click actions.
Right click here
import { Menu } from "ui-lab-components";
export function Example() {
return (
<Menu>
<Menu.Trigger>Right click here</Menu.Trigger>
<Menu.Content>
<Menu.Item>Copy</Menu.Item>
<Menu.Item>Paste</Menu.Item>
<Menu.Item disabled>Cut</Menu.Item>
</Menu.Content>
</Menu>
);
}Basic Menu
A simple context menu triggered by right-click. Use this to provide quick access to common actions and context-specific commands.
Right click here
import { Menu } from 'ui-lab-components';
export const metadata = {
title: 'Basic Menu',
description: 'A simple context menu triggered by right-click. Use this to provide quick access to common actions and context-specific commands.'
};
export default function Example() {
return (
<Menu>
<Menu.Trigger className="flex items-center justify-center rounded-md border-2 border-dashed border-background-600 p-12 w-full cursor-context-menu select-none text-foreground-300 hover:border-background-500 transition-colors">
Right click here
</Menu.Trigger>
<Menu.Content>
<Menu.Item>Copy</Menu.Item>
<Menu.Item>Paste</Menu.Item>
<Menu.Item disabled>Cut</Menu.Item>
</Menu.Content>
</Menu>
);
}
Nested Menu
Context menu with submenus for organizing related actions. Hover over items with arrows to reveal nested options.
Right click here
import { Menu } from 'ui-lab-components';
export const metadata = {
title: 'Nested Menu',
description: 'Context menu with submenus for organizing related actions. Hover over items with arrows to reveal nested options.'
};
export default function Example() {
return (
<Menu>
<Menu.Trigger className="flex items-center justify-center rounded-md border-2 border-dashed border-background-600 p-12 w-full cursor-context-menu select-none text-foreground-300 hover:border-background-500 transition-colors">
Right click here
</Menu.Trigger>
<Menu.Content>
<Menu.Item>New File</Menu.Item>
<Menu.Item>New Folder</Menu.Item>
<Menu.Separator />
<Menu.Sub>
<Menu.SubTrigger>Open with...</Menu.SubTrigger>
<Menu.SubContent>
<Menu.Item>VS Code</Menu.Item>
<Menu.Item>Sublime Text</Menu.Item>
<Menu.Item>Vim</Menu.Item>
<Menu.Separator />
<Menu.Item>Other Application...</Menu.Item>
</Menu.SubContent>
</Menu.Sub>
<Menu.Sub>
<Menu.SubTrigger>Share</Menu.SubTrigger>
<Menu.SubContent>
<Menu.Item>Copy Link</Menu.Item>
<Menu.Item>Email</Menu.Item>
<Menu.Sub>
<Menu.SubTrigger>Social Media</Menu.SubTrigger>
<Menu.SubContent>
<Menu.Item>Twitter</Menu.Item>
<Menu.Item>LinkedIn</Menu.Item>
<Menu.Item>Facebook</Menu.Item>
</Menu.SubContent>
</Menu.Sub>
</Menu.SubContent>
</Menu.Sub>
<Menu.Separator />
<Menu.Item>Rename</Menu.Item>
<Menu.Item disabled>Delete</Menu.Item>
</Menu.Content>
</Menu>
);
}
Toolbar Dropdown
Dropdown menu of actions with keyboard shortcuts and a disabled item.
import { Menu, Button } from "ui-lab-components";
import { FaChevronDown } from "react-icons/fa6";
export const metadata = {
title: "Toolbar Dropdown",
description: "Dropdown menu of actions with keyboard shortcuts and a disabled item.",
};
export default function Example() {
return (
<Menu type="pop-over">
<Menu.Trigger>
<Button variant="ghost">
File <FaChevronDown className="w-3 h-3 ml-1" />
</Button>
</Menu.Trigger>
<Menu.Content align="start">
<Menu.Item onSelect={() => {}}>
New file
<Menu.Shortcut>⌘N</Menu.Shortcut>
</Menu.Item>
<Menu.Item onSelect={() => {}}>
Open…
<Menu.Shortcut>⌘O</Menu.Shortcut>
</Menu.Item>
<Menu.Item onSelect={() => {}}>
Save
<Menu.Shortcut>⌘S</Menu.Shortcut>
</Menu.Item>
<Menu.Separator />
<Menu.Item disabled>Recent files</Menu.Item>
</Menu.Content>
</Menu>
);
}
Table Row Actions
Per-row overflow menu in a table, with a destructive action separated from neutral ones.
| Document | Updated | |
|---|---|---|
| Q3 roadmap | 2h ago | |
| Pricing review | yesterday | |
| Hiring plan | 3 days ago |
import { Menu, Button } from "ui-lab-components";
import { FaEllipsis } from "react-icons/fa6";
export const metadata = {
title: "Table Row Actions",
description: "Per-row overflow menu in a table, with a destructive action separated from neutral ones.",
};
const rows = [
{ id: "doc_1", name: "Q3 roadmap", updated: "2h ago" },
{ id: "doc_2", name: "Pricing review", updated: "yesterday" },
{ id: "doc_3", name: "Hiring plan", updated: "3 days ago" },
];
export default function Example() {
return (
<table className="w-full text-sm border-collapse">
<thead>
<tr className="border-b border-background-700">
<th className="text-left py-2 px-3 font-medium text-foreground-200">Document</th>
<th className="text-left py-2 px-3 font-medium text-foreground-200">Updated</th>
<th className="py-2 px-3" />
</tr>
</thead>
<tbody>
{rows.map((row) => (
<tr key={row.id} className="border-b border-background-700 last:border-0">
<td className="py-2 px-3">{row.name}</td>
<td className="py-2 px-3 text-foreground-400">{row.updated}</td>
<td className="py-2 px-3 text-right">
<Menu type="pop-over">
<Menu.Trigger>
<Button
icon={<FaEllipsis />}
size="icon"
variant="ghost"
styles="p-2"
aria-label={`Actions for ${row.name}`}
/>
</Menu.Trigger>
<Menu.Content align="end">
<Menu.Item onSelect={() => {}}>Open</Menu.Item>
<Menu.Item onSelect={() => {}}>Rename</Menu.Item>
<Menu.Item onSelect={() => {}}>Duplicate</Menu.Item>
<Menu.Separator />
<Menu.Item
onSelect={() => {}}
styles={{ root: "text-destructive" }}
>
Delete
</Menu.Item>
</Menu.Content>
</Menu>
</td>
</tr>
))}
</tbody>
</table>
);
}
Context Menu
Right-click anywhere in the surface to open the menu at the cursor position.
Right-click anywhere in this area
import { Menu } from "ui-lab-components";
export const metadata = {
title: "Context Menu",
description: "Right-click anywhere in the surface to open the menu at the cursor position.",
};
export default function Example() {
return (
<Menu type="context-menu">
<Menu.Trigger>
<div className="flex items-center justify-center w-80 h-32 border border-dashed border-background-700 rounded-sm text-sm text-foreground-400 select-none">
Right-click anywhere in this area
</div>
</Menu.Trigger>
<Menu.Content>
<Menu.Item onSelect={() => {}}>
Cut
<Menu.Shortcut>⌘X</Menu.Shortcut>
</Menu.Item>
<Menu.Item onSelect={() => {}}>
Copy
<Menu.Shortcut>⌘C</Menu.Shortcut>
</Menu.Item>
<Menu.Item onSelect={() => {}}>
Paste
<Menu.Shortcut>⌘V</Menu.Shortcut>
</Menu.Item>
<Menu.Separator />
<Menu.Item onSelect={() => {}} styles={{ root: "text-destructive" }}>
Delete
</Menu.Item>
</Menu.Content>
</Menu>
);
}
View Options
Mixed checkbox and radio items for toggling display state and selecting a single density.
"use client";
import { useState } from "react";
import { Menu, Button } from "ui-lab-components";
export const metadata = {
title: "View Options",
description: "Mixed checkbox and radio items for toggling display state and selecting a single density.",
};
export default function Example() {
const [showGrid, setShowGrid] = useState(true);
const [showRulers, setShowRulers] = useState(false);
const [density, setDensity] = useState("comfortable");
return (
<Menu type="pop-over">
<Menu.Trigger>
<Button>View</Button>
</Menu.Trigger>
<Menu.Content align="start">
<Menu.Label>Display</Menu.Label>
<Menu.CheckboxItem checked={showGrid} onCheckedChange={setShowGrid}>
Show grid
</Menu.CheckboxItem>
<Menu.CheckboxItem checked={showRulers} onCheckedChange={setShowRulers}>
Show rulers
</Menu.CheckboxItem>
<Menu.Separator />
<Menu.Label>Density</Menu.Label>
<Menu.RadioGroup value={density} onValueChange={setDensity}>
<Menu.RadioItem value="compact">Compact</Menu.RadioItem>
<Menu.RadioItem value="comfortable">Comfortable</Menu.RadioItem>
<Menu.RadioItem value="spacious">Spacious</Menu.RadioItem>
</Menu.RadioGroup>
</Menu.Content>
</Menu>
);
}