ZaidanHomeDocsComponentsBlocksChartsTypesetCreate

Command Palette

Search for a command to run...

GitHub
New
Sections
  • Introduction
  • Components
  • Blocks
  • Installation
  • Customization
  • Dark Mode
  • Typeset
  • Zaidan Skills
  • FAQ
  • Roadmap
  • Changelog
Installation
  • Astro
  • Manual
  • Solid Start
  • TanStack Router
  • TanStack Start
  • Vite
Blocks
  • Data Grid
  • Event Calendar
  • Filters
  • Gantt
  • Image Crop
  • Kanban
  • Message Scroller
  • Questionnaire
  • Sortable
Components
  • Accordion
  • Alert
  • Alert Dialog
  • Aspect Ratio
  • Attachment
  • Avatar
  • Badge
  • Breadcrumb
  • Bubble
  • Button
  • Button Group
  • Calendar
  • Card
  • Carousel
  • Chart
  • Checkbox
  • Collapsible
  • Combobox
  • Command
  • Context Menu
  • Dialog
  • Drawer
  • Dropdown Menu
  • Empty
  • Field
  • Hover Card
  • Input
  • Input Group
  • Input OTP
  • Item
  • Kbd
  • Label
  • Marker
  • Menubar
  • Message
  • Native Select
  • Navigation Menu
  • Pagination
  • Popover
  • Progress
  • Radio Group
  • Resizable
  • Scroll Area
  • Select
  • Separator
  • Sheet
  • Sidebar
  • Skeleton
  • Slider
  • Spinner
  • Switch
  • Table
  • Tabs
  • Textarea
  • Toast
  • Toggle
  • Toggle Group
  • Tooltip

Context Menu

Displays a menu of actions triggered by a right click.

Kobalte
Kobalte

The Context Menu component is built on top of Kobalte Context Menu, which provides accessible context-menu, keyboard, and focus behavior.

Right click hereLong press here
1
import {
2
ContextMenu,
3
ContextMenuCheckboxItem,
4
ContextMenuContent,
5
ContextMenuGroup,
6
ContextMenuItem,
7
ContextMenuLabel,
8
ContextMenuRadioGroup,
9
ContextMenuRadioItem,
10
ContextMenuSeparator,
11
ContextMenuShortcut,
12
ContextMenuSub,
13
ContextMenuSubContent,
14
ContextMenuSubTrigger,
15
ContextMenuTrigger,
16
} from "~/components/ui/context-menu";
17
18
export default function ContextMenuDemo() {
19
return (
20
<ContextMenu>
21
<ContextMenuTrigger class="flex aspect-video w-full max-w-xs items-center justify-center rounded-xl border border-dashed text-sm">
22
<span class="pointer-fine:inline-block hidden">Right click here</span>
23
<span class="pointer-coarse:inline-block hidden">Long press here</span>
24
</ContextMenuTrigger>
25
<ContextMenuContent class="w-48">
26
<ContextMenuGroup>
27
<ContextMenuItem>
28
Back<ContextMenuShortcut>⌘[</ContextMenuShortcut>
29
</ContextMenuItem>
30
<ContextMenuItem disabled>
31
Forward<ContextMenuShortcut>⌘]</ContextMenuShortcut>
32
</ContextMenuItem>
33
<ContextMenuItem>
34
Reload<ContextMenuShortcut>⌘R</ContextMenuShortcut>
35
</ContextMenuItem>
36
<ContextMenuSub>
37
<ContextMenuSubTrigger>More Tools</ContextMenuSubTrigger>
38
<ContextMenuSubContent class="w-44">
39
<ContextMenuGroup>
40
<ContextMenuItem>Save Page...</ContextMenuItem>
41
<ContextMenuItem>Create Shortcut...</ContextMenuItem>
42
<ContextMenuItem>Name Window...</ContextMenuItem>
43
</ContextMenuGroup>
44
<ContextMenuSeparator />
45
<ContextMenuItem>Developer Tools</ContextMenuItem>
46
<ContextMenuSeparator />
47
<ContextMenuItem variant="destructive">Delete</ContextMenuItem>
48
</ContextMenuSubContent>
49
</ContextMenuSub>
50
</ContextMenuGroup>
51
<ContextMenuSeparator />
52
<ContextMenuGroup>
53
<ContextMenuCheckboxItem checked>Show Bookmarks</ContextMenuCheckboxItem>
54
<ContextMenuCheckboxItem>Show Full URLs</ContextMenuCheckboxItem>
55
</ContextMenuGroup>
56
<ContextMenuSeparator />
57
<ContextMenuGroup>
58
<ContextMenuRadioGroup value="pedro">
59
<ContextMenuLabel>People</ContextMenuLabel>
60
<ContextMenuRadioItem value="pedro">Pedro Duarte</ContextMenuRadioItem>
61
<ContextMenuRadioItem value="colm">Colm Tuite</ContextMenuRadioItem>
62
</ContextMenuRadioGroup>
63
</ContextMenuGroup>
64
</ContextMenuContent>
65
</ContextMenu>
66
);
67
}

Installation

pnpm dlx shadcn@latest add @zaidan/context-menu
npx shadcn@latest add @zaidan/context-menu
yarn dlx shadcn@latest add @zaidan/context-menu
bunx --bun shadcn@latest add @zaidan/context-menu

Usage

1
import {
2
ContextMenu,
3
ContextMenuContent,
4
ContextMenuItem,
5
ContextMenuTrigger,
6
} from "~/components/ui/context-menu";
1
<ContextMenu>
2
<ContextMenuTrigger>Right click here</ContextMenuTrigger>
3
<ContextMenuContent>
4
<ContextMenuItem>Profile</ContextMenuItem>
5
<ContextMenuItem>Billing</ContextMenuItem>
6
<ContextMenuItem>Team</ContextMenuItem>
7
<ContextMenuItem>Subscription</ContextMenuItem>
8
</ContextMenuContent>
9
</ContextMenu>

See the Kobalte Context Menu documentation for primitive-level options, accessibility, and keyboard behavior.

Composition

Use the following composition to build a ContextMenu:

ContextMenu
├── ContextMenuTrigger
└── ContextMenuContent
├── ContextMenuGroup
│ ├── ContextMenuLabel
│ ├── ContextMenuItem
│ └── ContextMenuItem
├── ContextMenuSeparator
├── ContextMenuGroup
│ ├── ContextMenuLabel
│ ├── ContextMenuCheckboxItem
│ └── ContextMenuCheckboxItem
├── ContextMenuSeparator
├── ContextMenuGroup
│ ├── ContextMenuLabel
│ └── ContextMenuRadioGroup
│ ├── ContextMenuRadioItem
│ └── ContextMenuRadioItem
└── ContextMenuSub
├── ContextMenuSubTrigger
└── ContextMenuSubContent
└── ContextMenuGroup
├── ContextMenuItem
└── ContextMenuItem

Basic

A simple context menu with a few actions.

Right click hereLong press here
1
import {
2
ContextMenu,
3
ContextMenuContent,
4
ContextMenuGroup,
5
ContextMenuItem,
6
ContextMenuTrigger,
7
} from "~/components/ui/context-menu";
8
9
export default function ContextMenuBasic() {
10
return (
11
<ContextMenu>
12
<ContextMenuTrigger class="flex aspect-video w-full max-w-xs items-center justify-center rounded-xl border border-dashed text-sm">
13
<span class="pointer-fine:inline-block hidden">Right click here</span>
14
<span class="pointer-coarse:inline-block hidden">Long press here</span>
15
</ContextMenuTrigger>
16
<ContextMenuContent>
17
<ContextMenuGroup>
18
<ContextMenuItem>Back</ContextMenuItem>
19
<ContextMenuItem disabled>Forward</ContextMenuItem>
20
<ContextMenuItem>Reload</ContextMenuItem>
21
</ContextMenuGroup>
22
</ContextMenuContent>
23
</ContextMenu>
24
);
25
}

Submenu

Use ContextMenuSub to nest secondary actions.

Right click hereLong press here
1
import {
2
ContextMenu,
3
ContextMenuContent,
4
ContextMenuGroup,
5
ContextMenuItem,
6
ContextMenuSeparator,
7
ContextMenuShortcut,
8
ContextMenuSub,
9
ContextMenuSubContent,
10
ContextMenuSubTrigger,
11
ContextMenuTrigger,
12
} from "~/components/ui/context-menu";
13
14
export default function ContextMenuSubmenu() {
15
return (
16
<ContextMenu>
17
<ContextMenuTrigger class="flex aspect-video w-full max-w-xs items-center justify-center rounded-xl border border-dashed text-sm">
18
<span class="pointer-fine:inline-block hidden">Right click here</span>
19
<span class="pointer-coarse:inline-block hidden">Long press here</span>
20
</ContextMenuTrigger>
21
<ContextMenuContent>
22
<ContextMenuGroup>
23
<ContextMenuItem>
24
Copy<ContextMenuShortcut>⌘C</ContextMenuShortcut>
25
</ContextMenuItem>
26
<ContextMenuItem>
27
Cut<ContextMenuShortcut>⌘X</ContextMenuShortcut>
28
</ContextMenuItem>
29
</ContextMenuGroup>
30
<ContextMenuSub>
31
<ContextMenuSubTrigger>More Tools</ContextMenuSubTrigger>
32
<ContextMenuSubContent>
33
<ContextMenuGroup>
34
<ContextMenuItem>Save Page...</ContextMenuItem>
35
<ContextMenuItem>Create Shortcut...</ContextMenuItem>
36
<ContextMenuItem>Name Window...</ContextMenuItem>
37
</ContextMenuGroup>
38
<ContextMenuSeparator />
39
<ContextMenuItem>Developer Tools</ContextMenuItem>
40
<ContextMenuSeparator />
41
<ContextMenuItem variant="destructive">Delete</ContextMenuItem>
42
</ContextMenuSubContent>
43
</ContextMenuSub>
44
</ContextMenuContent>
45
</ContextMenu>
46
);
47
}

Shortcuts

Add ContextMenuShortcut to show keyboard hints.

Right click hereLong press here
1
import {
2
ContextMenu,
3
ContextMenuContent,
4
ContextMenuGroup,
5
ContextMenuItem,
6
ContextMenuSeparator,
7
ContextMenuShortcut,
8
ContextMenuTrigger,
9
} from "~/components/ui/context-menu";
10
11
export default function ContextMenuShortcuts() {
12
return (
13
<ContextMenu>
14
<ContextMenuTrigger class="flex aspect-video w-full max-w-xs items-center justify-center rounded-xl border border-dashed text-sm">
15
<span class="pointer-fine:inline-block hidden">Right click here</span>
16
<span class="pointer-coarse:inline-block hidden">Long press here</span>
17
</ContextMenuTrigger>
18
<ContextMenuContent>
19
<ContextMenuGroup>
20
<ContextMenuItem>
21
Back<ContextMenuShortcut>⌘[</ContextMenuShortcut>
22
</ContextMenuItem>
23
<ContextMenuItem disabled>
24
Forward<ContextMenuShortcut>⌘]</ContextMenuShortcut>
25
</ContextMenuItem>
26
<ContextMenuItem>
27
Reload<ContextMenuShortcut>⌘R</ContextMenuShortcut>
28
</ContextMenuItem>
29
</ContextMenuGroup>
30
<ContextMenuSeparator />
31
<ContextMenuGroup>
32
<ContextMenuItem>
33
Save<ContextMenuShortcut>⌘S</ContextMenuShortcut>
34
</ContextMenuItem>
35
<ContextMenuItem>
36
Save As...<ContextMenuShortcut>⇧⌘S</ContextMenuShortcut>
37
</ContextMenuItem>
38
</ContextMenuGroup>
39
</ContextMenuContent>
40
</ContextMenu>
41
);
42
}

Groups

Group related actions and separate them with dividers.

Right click hereLong press here
1
import {
2
ContextMenu,
3
ContextMenuContent,
4
ContextMenuGroup,
5
ContextMenuItem,
6
ContextMenuLabel,
7
ContextMenuSeparator,
8
ContextMenuShortcut,
9
ContextMenuTrigger,
10
} from "~/components/ui/context-menu";
11
12
export default function ContextMenuGroups() {
13
return (
14
<ContextMenu>
15
<ContextMenuTrigger class="flex aspect-video w-full max-w-xs items-center justify-center rounded-xl border border-dashed text-sm">
16
<span class="pointer-fine:inline-block hidden">Right click here</span>
17
<span class="pointer-coarse:inline-block hidden">Long press here</span>
18
</ContextMenuTrigger>
19
<ContextMenuContent>
20
<ContextMenuGroup>
21
<ContextMenuLabel>File</ContextMenuLabel>
22
<ContextMenuItem>
23
New File<ContextMenuShortcut>⌘N</ContextMenuShortcut>
24
</ContextMenuItem>
25
<ContextMenuItem>
26
Open File<ContextMenuShortcut>⌘O</ContextMenuShortcut>
27
</ContextMenuItem>
28
<ContextMenuItem>
29
Save<ContextMenuShortcut>⌘S</ContextMenuShortcut>
30
</ContextMenuItem>
31
</ContextMenuGroup>
32
<ContextMenuSeparator />
33
<ContextMenuGroup>
34
<ContextMenuLabel>Edit</ContextMenuLabel>
35
<ContextMenuItem>
36
Undo<ContextMenuShortcut>⌘Z</ContextMenuShortcut>
37
</ContextMenuItem>
38
<ContextMenuItem>
39
Redo<ContextMenuShortcut>⇧⌘Z</ContextMenuShortcut>
40
</ContextMenuItem>
41
</ContextMenuGroup>
42
<ContextMenuSeparator />
43
<ContextMenuGroup>
44
<ContextMenuItem>
45
Cut<ContextMenuShortcut>⌘X</ContextMenuShortcut>
46
</ContextMenuItem>
47
<ContextMenuItem>
48
Copy<ContextMenuShortcut>⌘C</ContextMenuShortcut>
49
</ContextMenuItem>
50
<ContextMenuItem>
51
Paste<ContextMenuShortcut>⌘V</ContextMenuShortcut>
52
</ContextMenuItem>
53
</ContextMenuGroup>
54
<ContextMenuSeparator />
55
<ContextMenuItem variant="destructive">
56
Delete<ContextMenuShortcut>⌫</ContextMenuShortcut>
57
</ContextMenuItem>
58
</ContextMenuContent>
59
</ContextMenu>
60
);
61
}

Icons

Combine icons with labels for quick scanning.

Right click hereLong press here
1
import { ClipboardPasteIcon, CopyIcon, ScissorsIcon, TrashIcon } from "lucide-solid";
2
import {
3
ContextMenu,
4
ContextMenuContent,
5
ContextMenuGroup,
6
ContextMenuItem,
7
ContextMenuSeparator,
8
ContextMenuTrigger,
9
} from "~/components/ui/context-menu";
10
11
export default function ContextMenuIcons() {
12
return (
13
<ContextMenu>
14
<ContextMenuTrigger class="flex aspect-video w-full max-w-xs items-center justify-center rounded-xl border border-dashed text-sm">
15
<span class="pointer-fine:inline-block hidden">Right click here</span>
16
<span class="pointer-coarse:inline-block hidden">Long press here</span>
17
</ContextMenuTrigger>
18
<ContextMenuContent>
19
<ContextMenuGroup>
20
<ContextMenuItem>
21
<CopyIcon />
22
Copy
23
</ContextMenuItem>
24
<ContextMenuItem>
25
<ScissorsIcon />
26
Cut
27
</ContextMenuItem>
28
<ContextMenuItem>
29
<ClipboardPasteIcon />
30
Paste
31
</ContextMenuItem>
32
</ContextMenuGroup>
33
<ContextMenuSeparator />
34
<ContextMenuItem variant="destructive">
35
<TrashIcon />
36
Delete
37
</ContextMenuItem>
38
</ContextMenuContent>
39
</ContextMenu>
40
);
41
}

Checkboxes

Use ContextMenuCheckboxItem for toggles.

Right click hereLong press here
1
import {
2
ContextMenu,
3
ContextMenuCheckboxItem,
4
ContextMenuContent,
5
ContextMenuGroup,
6
ContextMenuTrigger,
7
} from "~/components/ui/context-menu";
8
9
export default function ContextMenuCheckboxes() {
10
return (
11
<ContextMenu>
12
<ContextMenuTrigger class="flex aspect-video w-full max-w-xs items-center justify-center rounded-xl border border-dashed text-sm">
13
<span class="pointer-fine:inline-block hidden">Right click here</span>
14
<span class="pointer-coarse:inline-block hidden">Long press here</span>
15
</ContextMenuTrigger>
16
<ContextMenuContent>
17
<ContextMenuGroup>
18
<ContextMenuCheckboxItem defaultChecked>Show Bookmarks Bar</ContextMenuCheckboxItem>
19
<ContextMenuCheckboxItem>Show Full URLs</ContextMenuCheckboxItem>
20
<ContextMenuCheckboxItem defaultChecked>Show Developer Tools</ContextMenuCheckboxItem>
21
</ContextMenuGroup>
22
</ContextMenuContent>
23
</ContextMenu>
24
);
25
}

Radio

Use ContextMenuRadioItem for exclusive choices.

Right click hereLong press here
1
import { createSignal } from "solid-js";
2
import {
3
ContextMenu,
4
ContextMenuContent,
5
ContextMenuGroup,
6
ContextMenuLabel,
7
ContextMenuRadioGroup,
8
ContextMenuRadioItem,
9
ContextMenuSeparator,
10
ContextMenuTrigger,
11
} from "~/components/ui/context-menu";
12
13
export default function ContextMenuRadio() {
14
const [user, setUser] = createSignal("pedro");
15
const [theme, setTheme] = createSignal("light");
16
17
return (
18
<ContextMenu>
19
<ContextMenuTrigger class="flex aspect-video w-full max-w-xs items-center justify-center rounded-xl border border-dashed text-sm">
20
<span class="pointer-fine:inline-block hidden">Right click here</span>
21
<span class="pointer-coarse:inline-block hidden">Long press here</span>
22
</ContextMenuTrigger>
23
<ContextMenuContent>
24
<ContextMenuGroup>
25
<ContextMenuLabel>People</ContextMenuLabel>
26
<ContextMenuRadioGroup value={user()} onChange={(value) => setUser(value)}>
27
<ContextMenuRadioItem value="pedro">Pedro Duarte</ContextMenuRadioItem>
28
<ContextMenuRadioItem value="colm">Colm Tuite</ContextMenuRadioItem>
29
</ContextMenuRadioGroup>
30
</ContextMenuGroup>
31
<ContextMenuSeparator />
32
<ContextMenuGroup>
33
<ContextMenuLabel>Theme</ContextMenuLabel>
34
<ContextMenuRadioGroup value={theme()} onChange={(value) => setTheme(value)}>
35
<ContextMenuRadioItem value="light">Light</ContextMenuRadioItem>
36
<ContextMenuRadioItem value="dark">Dark</ContextMenuRadioItem>
37
<ContextMenuRadioItem value="system">System</ContextMenuRadioItem>
38
</ContextMenuRadioGroup>
39
</ContextMenuGroup>
40
</ContextMenuContent>
41
</ContextMenu>
42
);
43
}

Destructive

Use variant="destructive" to style the menu item as destructive.

Right click hereLong press here
1
import { PencilIcon, ShareIcon, TrashIcon } from "lucide-solid";
2
import {
3
ContextMenu,
4
ContextMenuContent,
5
ContextMenuGroup,
6
ContextMenuItem,
7
ContextMenuSeparator,
8
ContextMenuTrigger,
9
} from "~/components/ui/context-menu";
10
11
export default function ContextMenuDestructive() {
12
return (
13
<ContextMenu>
14
<ContextMenuTrigger class="flex aspect-video w-full max-w-xs items-center justify-center rounded-xl border border-dashed text-sm">
15
<span class="pointer-fine:inline-block hidden">Right click here</span>
16
<span class="pointer-coarse:inline-block hidden">Long press here</span>
17
</ContextMenuTrigger>
18
<ContextMenuContent>
19
<ContextMenuGroup>
20
<ContextMenuItem>
21
<PencilIcon />
22
Edit
23
</ContextMenuItem>
24
<ContextMenuItem>
25
<ShareIcon />
26
Share
27
</ContextMenuItem>
28
</ContextMenuGroup>
29
<ContextMenuSeparator />
30
<ContextMenuItem variant="destructive">
31
<TrashIcon />
32
Delete
33
</ContextMenuItem>
34
</ContextMenuContent>
35
</ContextMenu>
36
);
37
}

Sides

Control menu placement by passing a placement prop to ContextMenu.

Right click (top)Long press (top)
Right click (right)Long press (right)
Right click (bottom)Long press (bottom)
Right click (left)Long press (left)
1
import { For } from "solid-js";
2
import {
3
ContextMenu,
4
ContextMenuContent,
5
ContextMenuGroup,
6
ContextMenuItem,
7
ContextMenuTrigger,
8
} from "~/components/ui/context-menu";
9
10
const sides = ["top", "right", "bottom", "left"] as const;
11
12
export default function ContextMenuSides() {
13
return (
14
<div class="grid w-full max-w-sm grid-cols-2 gap-4">
15
<For each={sides}>
16
{(side) => (
17
<ContextMenu placement={side}>
18
<ContextMenuTrigger class="flex aspect-video w-full max-w-xs items-center justify-center rounded-xl border border-dashed text-sm">
19
<span class="pointer-fine:inline-block hidden">Right click ({side})</span>
20
<span class="pointer-coarse:inline-block hidden">Long press ({side})</span>
21
</ContextMenuTrigger>
22
<ContextMenuContent>
23
<ContextMenuGroup>
24
<ContextMenuItem>Back</ContextMenuItem>
25
<ContextMenuItem>Forward</ContextMenuItem>
26
<ContextMenuItem>Reload</ContextMenuItem>
27
</ContextMenuGroup>
28
</ContextMenuContent>
29
</ContextMenu>
30
)}
31
</For>
32
</div>
33
);
34
}

API Reference

See the Kobalte Context Menu API reference for primitive props, keyboard behavior, and accessibility details.

On This Page

  • Installation
  • Usage
  • Composition
  • Basic
  • Submenu
  • Shortcuts
  • Groups
  • Icons
  • Checkboxes
  • Radio
  • Destructive
  • Sides
  • API Reference
Built by Kevin Abatan. The source code is available on GitHub.