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
- Date Picker
- Dialog
- Drawer
- Dropdown Menu
- Empty
- Field
- Hover Card
- Input
- Input OTP
- Input Group
- Item
- Kbd
- Label
- Marker
- Menubar
- Message
- Message Scroller
- Native Select
- Navigation Menu
- Pagination
- Popover
- Progress
- Radio Group
- Resizable
- Scroll Area
- Select
- Separator
- Sheet
- Sidebar
- Skeleton
- Slider
- Sonner
- Spinner
- Switch
- Table
- Tabs
- Textarea
- Toggle
- Toggle Group
- Tooltip
- New Component
Elements
Charts
Icons
Right-click here
import { ContextMenu, ContextMenuContent, ContextMenuItem, ContextMenuLabel, ContextMenuSeparator, ContextMenuShortcut, ContextMenuSub, ContextMenuSubContent, ContextMenuSubTrigger, ContextMenuTrigger } from "@/components/ui/context-menu";
export const ContextMenuDemo = () => (
<ContextMenu>
<ContextMenuTrigger className="flex h-32 w-64 items-center justify-center rounded-md border border-dashed text-sm text-muted-foreground">Right-click here</ContextMenuTrigger>
<ContextMenuContent className="w-48">
<ContextMenuItem>Back<ContextMenuShortcut>⌘[</ContextMenuShortcut></ContextMenuItem>
<ContextMenuItem disabled>Forward<ContextMenuShortcut>⌘]</ContextMenuShortcut></ContextMenuItem>
<ContextMenuItem>Reload<ContextMenuShortcut>⌘R</ContextMenuShortcut></ContextMenuItem>
<ContextMenuSub>
<ContextMenuSubTrigger>More Tools</ContextMenuSubTrigger>
<ContextMenuSubContent>
<ContextMenuItem>Save Page As…</ContextMenuItem>
<ContextMenuItem>Create Shortcut…</ContextMenuItem>
<ContextMenuSeparator />
<ContextMenuItem>Developer Tools</ContextMenuItem>
</ContextMenuSubContent>
</ContextMenuSub>
<ContextMenuSeparator />
<ContextMenuLabel>Appearance</ContextMenuLabel>
<ContextMenuItem inset>Zoom In</ContextMenuItem>
<ContextMenuItem inset>Zoom Out</ContextMenuItem>
<ContextMenuSeparator />
<ContextMenuItem variant="destructive">Delete</ContextMenuItem>
</ContextMenuContent>
</ContextMenu>
);With Checkboxes
Use ContextMenuCheckboxItem for toggleable items that show a check when active.
"use client";
import { useState } from "react";
import {
ContextMenu,
ContextMenuCheckboxItem,
ContextMenuContent,
ContextMenuLabel,
ContextMenuSeparator,
ContextMenuTrigger,
} from "@/components/ui/context-menu";
export function ContextMenuCheckboxDemo() {
const [showBookmarks, setShowBookmarks] = useState(true);
const [showURLs, setShowURLs] = useState(false);
return (
<ContextMenu>
<ContextMenuTrigger className="flex h-32 w-64 items-center justify-center rounded-md border border-dashed text-sm text-muted-foreground">
Right-click here
</ContextMenuTrigger>
<ContextMenuContent className="w-48">
<ContextMenuLabel>View</ContextMenuLabel>
<ContextMenuSeparator />
<ContextMenuCheckboxItem
checked={showBookmarks}
onCheckedChange={setShowBookmarks}
>
Show Bookmarks Bar
</ContextMenuCheckboxItem>
<ContextMenuCheckboxItem
checked={showURLs}
onCheckedChange={setShowURLs}
>
Show Full URLs
</ContextMenuCheckboxItem>
</ContextMenuContent>
</ContextMenu>
);
}With Radio Items
Use ContextMenuRadioGroup + ContextMenuRadioItem for mutually exclusive options.
"use client";
import { useState } from "react";
import {
ContextMenu,
ContextMenuContent,
ContextMenuLabel,
ContextMenuRadioGroup,
ContextMenuRadioItem,
ContextMenuSeparator,
ContextMenuTrigger,
} from "@/components/ui/context-menu";
export function ContextMenuRadioDemo() {
const [position, setPosition] = useState("top");
return (
<ContextMenu>
<ContextMenuTrigger className="flex h-32 w-64 items-center justify-center rounded-md border border-dashed text-sm text-muted-foreground">
Right-click here
</ContextMenuTrigger>
<ContextMenuContent className="w-48">
<ContextMenuLabel>Panel Position</ContextMenuLabel>
<ContextMenuSeparator />
<ContextMenuRadioGroup value={position} onValueChange={setPosition}>
<ContextMenuRadioItem value="top">Top</ContextMenuRadioItem>
<ContextMenuRadioItem value="right">Right</ContextMenuRadioItem>
<ContextMenuRadioItem value="bottom">Bottom</ContextMenuRadioItem>
</ContextMenuRadioGroup>
</ContextMenuContent>
</ContextMenu>
);
}Props
ContextMenuItem
| Prop | Type | Default | Description |
|---|---|---|---|
variant | "default" | "destructive" | "default" | Destructive styles for dangerous actions |
inset | boolean | false | Adds left padding to align with icon items |
disabled | boolean | false | Prevents selection |
onSelect | (event: Event) => void | — | Callback when item is selected |
className | string | — | Additional CSS classes |
ContextMenuSubTrigger
| Prop | Type | Default | Description |
|---|---|---|---|
inset | boolean | false | Adds left padding to align with icon items |
ContextMenuCheckboxItem
| Prop | Type | Default | Description |
|---|---|---|---|
checked | boolean | "indeterminate" | — | Controlled checked state |
onCheckedChange | (checked: boolean) => void | — | Callback when state changes |
ContextMenuRadioItem
| Prop | Type | Default | Description |
|---|---|---|---|
value | string | — | Value for the radio group |
ContextMenuLabel
| Prop | Type | Default | Description |
|---|---|---|---|
inset | boolean | false | Adds left padding |
Usage
import {
ContextMenu,
ContextMenuContent,
ContextMenuItem,
ContextMenuLabel,
ContextMenuSeparator,
ContextMenuShortcut,
ContextMenuSub,
ContextMenuSubContent,
ContextMenuSubTrigger,
ContextMenuTrigger,
} from "@/components/ui/context-menu";
<ContextMenu>
<ContextMenuTrigger>Right-click me</ContextMenuTrigger>
<ContextMenuContent className="w-48">
<ContextMenuItem>
Copy
<ContextMenuShortcut>⌘C</ContextMenuShortcut>
</ContextMenuItem>
<ContextMenuItem>
Paste
<ContextMenuShortcut>⌘V</ContextMenuShortcut>
</ContextMenuItem>
<ContextMenuSeparator />
<ContextMenuSub>
<ContextMenuSubTrigger>More</ContextMenuSubTrigger>
<ContextMenuSubContent>
<ContextMenuItem>Select All</ContextMenuItem>
</ContextMenuSubContent>
</ContextMenuSub>
<ContextMenuSeparator />
<ContextMenuItem variant="destructive">Delete</ContextMenuItem>
</ContextMenuContent>
</ContextMenu>Specs
# Mint — Context Menu Specs
## Component
- name: context-menu
- file: registry/mint/context-menu.tsx
- installs to: components/ui/context-menu.tsx
- dependencies: radix-ui, lucide-react
- registryDependencies: none
## What is it
A floating menu triggered by the browser's right-click (contextmenu) event on
a wrapped element. Use it for file/item actions, editor operations, or any
surface where right-click is a natural interaction pattern. Do not use it for
primary navigation — prefer DropdownMenu for pointer-initiated menus.
## Visual identity
Popover-surfaced panel with rounded-md corners and a 1px border. Compact item
rows (py-1.5, text-sm) with accent-coloured hover/focus states. Matches the
Mint palette's soft green wash — a light green tint appears only on focus or
the destructive variant.
## Design tokens
--popover: oklch(1 0 0) / oklch(0.269 0 0) — menu panel background
--popover-foreground: oklch(0.145 0 0) / oklch(0.985 0 0) — default item text
--accent: oklch(0.92 0.05 155) / oklch(0.26 0.05 155) — hover/focus item bg
--accent-foreground: oklch(0.32 0.1 155) / oklch(0.88 0.06 155) — hover/focus item text
--muted-foreground: oklch(0.52 0.06 155) / oklch(0.6 0.06 155) — shortcut + icon colour
--destructive: oklch(0.55 0.25 15) / oklch(0.704 0.191 22.216) — danger item text
--border: oklch(0.88 0.04 155 / 60%) / oklch(0.32 0.05 155 / 40%) — panel border + separator
--foreground: oklch(0.145 0 0) / oklch(0.985 0 0) — label text
## Sub-components
- ContextMenu → root provider, no visual output
- ContextMenuTrigger → wraps the right-clickable area
- ContextMenuPortal → renders content into a portal
- ContextMenuContent → floating menu panel (rendered via Portal automatically)
- ContextMenuGroup → semantic grouping wrapper, no visual output
- ContextMenuItem → action row; accepts variant and inset props
- ContextMenuCheckboxItem → toggleable item with CheckIcon indicator
- ContextMenuRadioGroup → wraps radio items, holds value + onValueChange
- ContextMenuRadioItem → mutually exclusive option with CircleIcon indicator
- ContextMenuLabel → non-interactive section heading (font-medium)
- ContextMenuSeparator → 1px horizontal rule between groups
- ContextMenuShortcut → right-aligned keyboard hint (ml-auto, display only)
- ContextMenuSub → sub-menu root
- ContextMenuSubTrigger → item that opens a sub-menu (ChevronRightIcon auto-appended)
- ContextMenuSubContent → floating panel for sub-menu items
## Variants
- default → standard item style; accent bg + text on focus
- destructive → text-destructive at rest; destructive/10 (light) or destructive/20 (dark) bg on focus
## States
- focus: bg-accent + text-accent-foreground on all interactive items
- data-[state=open]: SubTrigger shows accent bg + text while sub-menu is open
- data-[disabled]: pointer-events-none + opacity-50 on items and checkbox/radio items
- data-[checked]: ItemIndicator renders CheckIcon (checkbox) or CircleIcon (radio) when active
## Conventions
- Set a fixed width on ContextMenuContent: className="w-48" or "w-56"
- ContextMenuContent already renders inside a Portal — do not wrap it in ContextMenuPortal manually
- Use inset={true} on ContextMenuItem, ContextMenuLabel, or ContextMenuSubTrigger to add pl-8 and align text with icon-prefixed siblings
- ContextMenuShortcut is display-only — wire actual keyboard shortcuts separately (e.g. useEffect + keydown)
- ContextMenuTrigger wraps any element; no interactive element required
- Always nest ContextMenuSubContent inside a ContextMenuSub root
- Sub-components expose data-slot="[name]" attributes for CSS targetingInstallation
$ npx shadcn add \https://gin-design.vercel.app/context-menu