@neynar/ui 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +195 -0
- package/dist/components/ui/accordion.d.ts +229 -0
- package/dist/components/ui/accordion.d.ts.map +1 -0
- package/dist/components/ui/alert-dialog.d.ts +247 -0
- package/dist/components/ui/alert-dialog.d.ts.map +1 -0
- package/dist/components/ui/alert.d.ts +187 -0
- package/dist/components/ui/alert.d.ts.map +1 -0
- package/dist/components/ui/aspect-ratio.d.ts +94 -0
- package/dist/components/ui/aspect-ratio.d.ts.map +1 -0
- package/dist/components/ui/avatar.d.ts +244 -0
- package/dist/components/ui/avatar.d.ts.map +1 -0
- package/dist/components/ui/badge.d.ts +163 -0
- package/dist/components/ui/badge.d.ts.map +1 -0
- package/dist/components/ui/breadcrumb.d.ts +281 -0
- package/dist/components/ui/breadcrumb.d.ts.map +1 -0
- package/dist/components/ui/button.d.ts +129 -0
- package/dist/components/ui/button.d.ts.map +1 -0
- package/dist/components/ui/calendar.d.ts +169 -0
- package/dist/components/ui/calendar.d.ts.map +1 -0
- package/dist/components/ui/card.d.ts +365 -0
- package/dist/components/ui/card.d.ts.map +1 -0
- package/dist/components/ui/carousel.d.ts +369 -0
- package/dist/components/ui/carousel.d.ts.map +1 -0
- package/dist/components/ui/chart.d.ts +442 -0
- package/dist/components/ui/chart.d.ts.map +1 -0
- package/dist/components/ui/checkbox.d.ts +88 -0
- package/dist/components/ui/checkbox.d.ts.map +1 -0
- package/dist/components/ui/collapsible.d.ts +182 -0
- package/dist/components/ui/collapsible.d.ts.map +1 -0
- package/dist/components/ui/combobox.d.ts +270 -0
- package/dist/components/ui/combobox.d.ts.map +1 -0
- package/dist/components/ui/command.d.ts +355 -0
- package/dist/components/ui/command.d.ts.map +1 -0
- package/dist/components/ui/container.d.ts +102 -0
- package/dist/components/ui/container.d.ts.map +1 -0
- package/dist/components/ui/context-menu.d.ts +339 -0
- package/dist/components/ui/context-menu.d.ts.map +1 -0
- package/dist/components/ui/date-picker.d.ts +145 -0
- package/dist/components/ui/date-picker.d.ts.map +1 -0
- package/dist/components/ui/dialog.d.ts +322 -0
- package/dist/components/ui/dialog.d.ts.map +1 -0
- package/dist/components/ui/drawer.d.ts +154 -0
- package/dist/components/ui/drawer.d.ts.map +1 -0
- package/dist/components/ui/dropdown-menu.d.ts +349 -0
- package/dist/components/ui/dropdown-menu.d.ts.map +1 -0
- package/dist/components/ui/empty-state.d.ts +133 -0
- package/dist/components/ui/empty-state.d.ts.map +1 -0
- package/dist/components/ui/hover-card.d.ts +109 -0
- package/dist/components/ui/hover-card.d.ts.map +1 -0
- package/dist/components/ui/input.d.ts +89 -0
- package/dist/components/ui/input.d.ts.map +1 -0
- package/dist/components/ui/label.d.ts +93 -0
- package/dist/components/ui/label.d.ts.map +1 -0
- package/dist/components/ui/menubar.d.ts +306 -0
- package/dist/components/ui/menubar.d.ts.map +1 -0
- package/dist/components/ui/navigation-menu.d.ts +318 -0
- package/dist/components/ui/navigation-menu.d.ts.map +1 -0
- package/dist/components/ui/pagination.d.ts +343 -0
- package/dist/components/ui/pagination.d.ts.map +1 -0
- package/dist/components/ui/popover.d.ts +178 -0
- package/dist/components/ui/popover.d.ts.map +1 -0
- package/dist/components/ui/progress.d.ts +64 -0
- package/dist/components/ui/progress.d.ts.map +1 -0
- package/dist/components/ui/radio-group.d.ts +144 -0
- package/dist/components/ui/radio-group.d.ts.map +1 -0
- package/dist/components/ui/resizable.d.ts +164 -0
- package/dist/components/ui/resizable.d.ts.map +1 -0
- package/dist/components/ui/scroll-area.d.ts +82 -0
- package/dist/components/ui/scroll-area.d.ts.map +1 -0
- package/dist/components/ui/select.d.ts +316 -0
- package/dist/components/ui/select.d.ts.map +1 -0
- package/dist/components/ui/separator.d.ts +80 -0
- package/dist/components/ui/separator.d.ts.map +1 -0
- package/dist/components/ui/sheet.d.ts +346 -0
- package/dist/components/ui/sheet.d.ts.map +1 -0
- package/dist/components/ui/sidebar.d.ts +1561 -0
- package/dist/components/ui/sidebar.d.ts.map +1 -0
- package/dist/components/ui/skeleton.d.ts +66 -0
- package/dist/components/ui/skeleton.d.ts.map +1 -0
- package/dist/components/ui/slider.d.ts +95 -0
- package/dist/components/ui/slider.d.ts.map +1 -0
- package/dist/components/ui/sonner.d.ts +101 -0
- package/dist/components/ui/sonner.d.ts.map +1 -0
- package/dist/components/ui/stack.d.ts +192 -0
- package/dist/components/ui/stack.d.ts.map +1 -0
- package/dist/components/ui/stories/accordion.stories.d.ts +71 -0
- package/dist/components/ui/stories/accordion.stories.d.ts.map +1 -0
- package/dist/components/ui/stories/alert-dialog.stories.d.ts +39 -0
- package/dist/components/ui/stories/alert-dialog.stories.d.ts.map +1 -0
- package/dist/components/ui/stories/alert.stories.d.ts +48 -0
- package/dist/components/ui/stories/alert.stories.d.ts.map +1 -0
- package/dist/components/ui/stories/aspect-ratio.stories.d.ts +53 -0
- package/dist/components/ui/stories/aspect-ratio.stories.d.ts.map +1 -0
- package/dist/components/ui/stories/avatar.stories.d.ts +49 -0
- package/dist/components/ui/stories/avatar.stories.d.ts.map +1 -0
- package/dist/components/ui/stories/badge.stories.d.ts +64 -0
- package/dist/components/ui/stories/badge.stories.d.ts.map +1 -0
- package/dist/components/ui/stories/breadcrumb.stories.d.ts +27 -0
- package/dist/components/ui/stories/breadcrumb.stories.d.ts.map +1 -0
- package/dist/components/ui/stories/button.stories.d.ts +92 -0
- package/dist/components/ui/stories/button.stories.d.ts.map +1 -0
- package/dist/components/ui/stories/calendar.stories.d.ts +94 -0
- package/dist/components/ui/stories/calendar.stories.d.ts.map +1 -0
- package/dist/components/ui/stories/card.stories.d.ts +29 -0
- package/dist/components/ui/stories/card.stories.d.ts.map +1 -0
- package/dist/components/ui/stories/carousel.stories.d.ts +42 -0
- package/dist/components/ui/stories/carousel.stories.d.ts.map +1 -0
- package/dist/components/ui/stories/chart.stories.d.ts +51 -0
- package/dist/components/ui/stories/chart.stories.d.ts.map +1 -0
- package/dist/components/ui/stories/checkbox.stories.d.ts +72 -0
- package/dist/components/ui/stories/checkbox.stories.d.ts.map +1 -0
- package/dist/components/ui/stories/cn.stories.d.ts +19 -0
- package/dist/components/ui/stories/cn.stories.d.ts.map +1 -0
- package/dist/components/ui/stories/collapsible.stories.d.ts +51 -0
- package/dist/components/ui/stories/collapsible.stories.d.ts.map +1 -0
- package/dist/components/ui/stories/colors.stories.d.ts +31 -0
- package/dist/components/ui/stories/colors.stories.d.ts.map +1 -0
- package/dist/components/ui/stories/combobox.stories.d.ts +89 -0
- package/dist/components/ui/stories/combobox.stories.d.ts.map +1 -0
- package/dist/components/ui/stories/command.stories.d.ts +69 -0
- package/dist/components/ui/stories/command.stories.d.ts.map +1 -0
- package/dist/components/ui/stories/container.stories.d.ts +42 -0
- package/dist/components/ui/stories/container.stories.d.ts.map +1 -0
- package/dist/components/ui/stories/context-menu.stories.d.ts +32 -0
- package/dist/components/ui/stories/context-menu.stories.d.ts.map +1 -0
- package/dist/components/ui/stories/date-picker.stories.d.ts +67 -0
- package/dist/components/ui/stories/date-picker.stories.d.ts.map +1 -0
- package/dist/components/ui/stories/dialog.stories.d.ts +48 -0
- package/dist/components/ui/stories/dialog.stories.d.ts.map +1 -0
- package/dist/components/ui/stories/drawer.stories.d.ts +33 -0
- package/dist/components/ui/stories/drawer.stories.d.ts.map +1 -0
- package/dist/components/ui/stories/dropdown-menu.stories.d.ts +31 -0
- package/dist/components/ui/stories/dropdown-menu.stories.d.ts.map +1 -0
- package/dist/components/ui/stories/empty-state.stories.d.ts +74 -0
- package/dist/components/ui/stories/empty-state.stories.d.ts.map +1 -0
- package/dist/components/ui/stories/hover-card.stories.d.ts +35 -0
- package/dist/components/ui/stories/hover-card.stories.d.ts.map +1 -0
- package/dist/components/ui/stories/input.stories.d.ts +69 -0
- package/dist/components/ui/stories/input.stories.d.ts.map +1 -0
- package/dist/components/ui/stories/label.stories.d.ts +47 -0
- package/dist/components/ui/stories/label.stories.d.ts.map +1 -0
- package/dist/components/ui/stories/menubar.stories.d.ts +39 -0
- package/dist/components/ui/stories/menubar.stories.d.ts.map +1 -0
- package/dist/components/ui/stories/navigation-menu.stories.d.ts +44 -0
- package/dist/components/ui/stories/navigation-menu.stories.d.ts.map +1 -0
- package/dist/components/ui/stories/pagination.stories.d.ts +33 -0
- package/dist/components/ui/stories/pagination.stories.d.ts.map +1 -0
- package/dist/components/ui/stories/popover.stories.d.ts +36 -0
- package/dist/components/ui/stories/popover.stories.d.ts.map +1 -0
- package/dist/components/ui/stories/progress.stories.d.ts +38 -0
- package/dist/components/ui/stories/progress.stories.d.ts.map +1 -0
- package/dist/components/ui/stories/radio-group.stories.d.ts +76 -0
- package/dist/components/ui/stories/radio-group.stories.d.ts.map +1 -0
- package/dist/components/ui/stories/resizable.stories.d.ts +49 -0
- package/dist/components/ui/stories/resizable.stories.d.ts.map +1 -0
- package/dist/components/ui/stories/scroll-area.stories.d.ts +35 -0
- package/dist/components/ui/stories/scroll-area.stories.d.ts.map +1 -0
- package/dist/components/ui/stories/select.stories.d.ts +51 -0
- package/dist/components/ui/stories/select.stories.d.ts.map +1 -0
- package/dist/components/ui/stories/separator.stories.d.ts +58 -0
- package/dist/components/ui/stories/separator.stories.d.ts.map +1 -0
- package/dist/components/ui/stories/sheet.stories.d.ts +43 -0
- package/dist/components/ui/stories/sheet.stories.d.ts.map +1 -0
- package/dist/components/ui/stories/sidebar.stories.d.ts +60 -0
- package/dist/components/ui/stories/sidebar.stories.d.ts.map +1 -0
- package/dist/components/ui/stories/skeleton.stories.d.ts +42 -0
- package/dist/components/ui/stories/skeleton.stories.d.ts.map +1 -0
- package/dist/components/ui/stories/slider.stories.d.ts +99 -0
- package/dist/components/ui/stories/slider.stories.d.ts.map +1 -0
- package/dist/components/ui/stories/sonner.stories.d.ts +9 -0
- package/dist/components/ui/stories/sonner.stories.d.ts.map +1 -0
- package/dist/components/ui/stories/stack.stories.d.ts +39 -0
- package/dist/components/ui/stories/stack.stories.d.ts.map +1 -0
- package/dist/components/ui/stories/switch.stories.d.ts +71 -0
- package/dist/components/ui/stories/switch.stories.d.ts.map +1 -0
- package/dist/components/ui/stories/table.stories.d.ts +40 -0
- package/dist/components/ui/stories/table.stories.d.ts.map +1 -0
- package/dist/components/ui/stories/tabs.stories.d.ts +62 -0
- package/dist/components/ui/stories/tabs.stories.d.ts.map +1 -0
- package/dist/components/ui/stories/text-field.stories.d.ts +78 -0
- package/dist/components/ui/stories/text-field.stories.d.ts.map +1 -0
- package/dist/components/ui/stories/textarea.stories.d.ts +57 -0
- package/dist/components/ui/stories/textarea.stories.d.ts.map +1 -0
- package/dist/components/ui/stories/theme-toggle.stories.d.ts +71 -0
- package/dist/components/ui/stories/theme-toggle.stories.d.ts.map +1 -0
- package/dist/components/ui/stories/theme.stories.d.ts +51 -0
- package/dist/components/ui/stories/theme.stories.d.ts.map +1 -0
- package/dist/components/ui/stories/toggle-group.stories.d.ts +71 -0
- package/dist/components/ui/stories/toggle-group.stories.d.ts.map +1 -0
- package/dist/components/ui/stories/toggle.stories.d.ts +78 -0
- package/dist/components/ui/stories/toggle.stories.d.ts.map +1 -0
- package/dist/components/ui/stories/tooltip.stories.d.ts +37 -0
- package/dist/components/ui/stories/tooltip.stories.d.ts.map +1 -0
- package/dist/components/ui/stories/typography.stories.d.ts +137 -0
- package/dist/components/ui/stories/typography.stories.d.ts.map +1 -0
- package/dist/components/ui/stories/use-mobile.stories.d.ts +20 -0
- package/dist/components/ui/stories/use-mobile.stories.d.ts.map +1 -0
- package/dist/components/ui/stories/use-theme.stories.d.ts +23 -0
- package/dist/components/ui/stories/use-theme.stories.d.ts.map +1 -0
- package/dist/components/ui/switch.d.ts +84 -0
- package/dist/components/ui/switch.d.ts.map +1 -0
- package/dist/components/ui/table.d.ts +321 -0
- package/dist/components/ui/table.d.ts.map +1 -0
- package/dist/components/ui/tabs.d.ts +260 -0
- package/dist/components/ui/tabs.d.ts.map +1 -0
- package/dist/components/ui/text-field.d.ts +157 -0
- package/dist/components/ui/text-field.d.ts.map +1 -0
- package/dist/components/ui/textarea.d.ts +84 -0
- package/dist/components/ui/textarea.d.ts.map +1 -0
- package/dist/components/ui/theme-toggle.d.ts +105 -0
- package/dist/components/ui/theme-toggle.d.ts.map +1 -0
- package/dist/components/ui/theme.d.ts +110 -0
- package/dist/components/ui/theme.d.ts.map +1 -0
- package/dist/components/ui/toggle-group.d.ts +133 -0
- package/dist/components/ui/toggle-group.d.ts.map +1 -0
- package/dist/components/ui/toggle.d.ts +84 -0
- package/dist/components/ui/toggle.d.ts.map +1 -0
- package/dist/components/ui/tooltip.d.ts +202 -0
- package/dist/components/ui/tooltip.d.ts.map +1 -0
- package/dist/components/ui/typography.d.ts +287 -0
- package/dist/components/ui/typography.d.ts.map +1 -0
- package/dist/hooks/use-mobile.d.ts +74 -0
- package/dist/hooks/use-mobile.d.ts.map +1 -0
- package/dist/hooks/use-theme.d.ts +142 -0
- package/dist/hooks/use-theme.d.ts.map +1 -0
- package/dist/index.d.ts +57 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +27498 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/utils.d.ts +43 -0
- package/dist/lib/utils.d.ts.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/docs/llm/colors.md +273 -0
- package/docs/llm/components/buttons.md +68 -0
- package/docs/llm/components/cards.md +53 -0
- package/docs/llm/components/display.md +134 -0
- package/docs/llm/components/feedback.md +96 -0
- package/docs/llm/components/forms.md +90 -0
- package/docs/llm/components/layout.md +59 -0
- package/docs/llm/components/menus.md +70 -0
- package/docs/llm/components/navigation.md +80 -0
- package/docs/llm/components/overlays.md +83 -0
- package/docs/llm/components/tables.md +73 -0
- package/docs/llm/components/typography.md +199 -0
- package/docs/llm/components/utilities.md +114 -0
- package/docs/llm/guide.md +165 -0
- package/llms.txt +122 -0
- package/package.json +104 -0
- package/src/components/ui/accordion.tsx +285 -0
- package/src/components/ui/alert-dialog.tsx +387 -0
- package/src/components/ui/alert.tsx +243 -0
- package/src/components/ui/aspect-ratio.tsx +99 -0
- package/src/components/ui/avatar.tsx +288 -0
- package/src/components/ui/badge.tsx +205 -0
- package/src/components/ui/breadcrumb.tsx +378 -0
- package/src/components/ui/button.tsx +195 -0
- package/src/components/ui/calendar.tsx +371 -0
- package/src/components/ui/card.tsx +447 -0
- package/src/components/ui/carousel.tsx +624 -0
- package/src/components/ui/chart.tsx +802 -0
- package/src/components/ui/checkbox.tsx +113 -0
- package/src/components/ui/collapsible.tsx +207 -0
- package/src/components/ui/combobox.tsx +373 -0
- package/src/components/ui/command.tsx +518 -0
- package/src/components/ui/container.tsx +114 -0
- package/src/components/ui/context-menu.tsx +563 -0
- package/src/components/ui/date-picker.tsx +213 -0
- package/src/components/ui/dialog.tsx +447 -0
- package/src/components/ui/drawer.tsx +273 -0
- package/src/components/ui/dropdown-menu.tsx +578 -0
- package/src/components/ui/empty-state.tsx +145 -0
- package/src/components/ui/hover-card.tsx +144 -0
- package/src/components/ui/input.tsx +106 -0
- package/src/components/ui/label.tsx +110 -0
- package/src/components/ui/menubar.tsx +553 -0
- package/src/components/ui/navigation-menu.tsx +471 -0
- package/src/components/ui/pagination.tsx +456 -0
- package/src/components/ui/popover.tsx +216 -0
- package/src/components/ui/progress.tsx +88 -0
- package/src/components/ui/radio-group.tsx +183 -0
- package/src/components/ui/resizable.tsx +209 -0
- package/src/components/ui/scroll-area.tsx +132 -0
- package/src/components/ui/select.tsx +485 -0
- package/src/components/ui/separator.tsx +101 -0
- package/src/components/ui/sheet.tsx +495 -0
- package/src/components/ui/sidebar.tsx +2211 -0
- package/src/components/ui/skeleton.tsx +76 -0
- package/src/components/ui/slider.tsx +147 -0
- package/src/components/ui/sonner.tsx +120 -0
- package/src/components/ui/stack.tsx +180 -0
- package/src/components/ui/stories/accordion.stories.tsx +429 -0
- package/src/components/ui/stories/alert-dialog.stories.tsx +519 -0
- package/src/components/ui/stories/alert.stories.tsx +228 -0
- package/src/components/ui/stories/aspect-ratio.stories.tsx +200 -0
- package/src/components/ui/stories/avatar.stories.tsx +317 -0
- package/src/components/ui/stories/badge.stories.tsx +260 -0
- package/src/components/ui/stories/breadcrumb.stories.tsx +482 -0
- package/src/components/ui/stories/button.stories.tsx +266 -0
- package/src/components/ui/stories/calendar.stories.tsx +375 -0
- package/src/components/ui/stories/card.stories.tsx +308 -0
- package/src/components/ui/stories/carousel.stories.tsx +328 -0
- package/src/components/ui/stories/chart.stories.tsx +430 -0
- package/src/components/ui/stories/checkbox.stories.tsx +297 -0
- package/src/components/ui/stories/cn.stories.tsx +433 -0
- package/src/components/ui/stories/collapsible.stories.tsx +256 -0
- package/src/components/ui/stories/colors.stories.tsx +502 -0
- package/src/components/ui/stories/combobox.stories.tsx +301 -0
- package/src/components/ui/stories/command.stories.tsx +632 -0
- package/src/components/ui/stories/container.stories.tsx +250 -0
- package/src/components/ui/stories/context-menu.stories.tsx +446 -0
- package/src/components/ui/stories/date-picker.stories.tsx +378 -0
- package/src/components/ui/stories/dialog.stories.tsx +535 -0
- package/src/components/ui/stories/drawer.stories.tsx +364 -0
- package/src/components/ui/stories/dropdown-menu.stories.tsx +374 -0
- package/src/components/ui/stories/empty-state.stories.tsx +244 -0
- package/src/components/ui/stories/hover-card.stories.tsx +355 -0
- package/src/components/ui/stories/input.stories.tsx +289 -0
- package/src/components/ui/stories/label.stories.tsx +294 -0
- package/src/components/ui/stories/menubar.stories.tsx +764 -0
- package/src/components/ui/stories/navigation-menu.stories.tsx +539 -0
- package/src/components/ui/stories/pagination.stories.tsx +604 -0
- package/src/components/ui/stories/popover.stories.tsx +392 -0
- package/src/components/ui/stories/progress.stories.tsx +218 -0
- package/src/components/ui/stories/radio-group.stories.tsx +400 -0
- package/src/components/ui/stories/resizable.stories.tsx +417 -0
- package/src/components/ui/stories/scroll-area.stories.tsx +180 -0
- package/src/components/ui/stories/select.stories.tsx +389 -0
- package/src/components/ui/stories/separator.stories.tsx +192 -0
- package/src/components/ui/stories/sheet.stories.tsx +468 -0
- package/src/components/ui/stories/sidebar.stories.tsx +731 -0
- package/src/components/ui/stories/skeleton.stories.tsx +216 -0
- package/src/components/ui/stories/slider.stories.tsx +321 -0
- package/src/components/ui/stories/sonner.stories.tsx +373 -0
- package/src/components/ui/stories/stack.stories.tsx +222 -0
- package/src/components/ui/stories/switch.stories.tsx +202 -0
- package/src/components/ui/stories/table.stories.tsx +541 -0
- package/src/components/ui/stories/tabs.stories.tsx +544 -0
- package/src/components/ui/stories/text-field.stories.tsx +280 -0
- package/src/components/ui/stories/textarea.stories.tsx +245 -0
- package/src/components/ui/stories/theme-toggle.stories.tsx +275 -0
- package/src/components/ui/stories/theme.stories.tsx +412 -0
- package/src/components/ui/stories/toggle-group.stories.tsx +337 -0
- package/src/components/ui/stories/toggle.stories.tsx +325 -0
- package/src/components/ui/stories/tooltip.stories.tsx +444 -0
- package/src/components/ui/stories/typography.stories.tsx +1586 -0
- package/src/components/ui/stories/use-mobile.stories.tsx +420 -0
- package/src/components/ui/stories/use-theme.stories.tsx +531 -0
- package/src/components/ui/switch.tsx +106 -0
- package/src/components/ui/table.tsx +424 -0
- package/src/components/ui/tabs.tsx +316 -0
- package/src/components/ui/text-field.tsx +206 -0
- package/src/components/ui/textarea.tsx +98 -0
- package/src/components/ui/theme-toggle.tsx +185 -0
- package/src/components/ui/theme.tsx +148 -0
- package/src/components/ui/toggle-group.tsx +196 -0
- package/src/components/ui/toggle.tsx +115 -0
- package/src/components/ui/tooltip.tsx +253 -0
- package/src/components/ui/typography.tsx +468 -0
- package/src/hooks/use-mobile.ts +91 -0
- package/src/hooks/use-theme.ts +319 -0
- package/src/index.ts +77 -0
- package/src/lib/utils.ts +57 -0
- package/src/styles/globals.css +160 -0
|
@@ -0,0 +1,563 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import * as ContextMenuPrimitive from "@radix-ui/react-context-menu";
|
|
3
|
+
import { CheckIcon, ChevronRightIcon, CircleIcon } from "lucide-react";
|
|
4
|
+
|
|
5
|
+
import { cn } from "@/lib/utils";
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* ContextMenu - A contextual menu that appears on right-click or long-press
|
|
9
|
+
*
|
|
10
|
+
* Context menus provide contextual actions for specific elements or areas.
|
|
11
|
+
* Built on Radix UI primitives, they appear when users right-click (or long-press
|
|
12
|
+
* on touch devices) and offer actions relevant to the clicked item or region.
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```tsx
|
|
16
|
+
* // Basic context menu with items
|
|
17
|
+
* <ContextMenu>
|
|
18
|
+
* <ContextMenuTrigger>
|
|
19
|
+
* <div className="border rounded p-4">
|
|
20
|
+
* Right-click here
|
|
21
|
+
* </div>
|
|
22
|
+
* </ContextMenuTrigger>
|
|
23
|
+
* <ContextMenuContent>
|
|
24
|
+
* <ContextMenuItem>Copy</ContextMenuItem>
|
|
25
|
+
* <ContextMenuItem>Paste</ContextMenuItem>
|
|
26
|
+
* <ContextMenuSeparator />
|
|
27
|
+
* <ContextMenuItem variant="destructive">Delete</ContextMenuItem>
|
|
28
|
+
* </ContextMenuContent>
|
|
29
|
+
* </ContextMenu>
|
|
30
|
+
* ```
|
|
31
|
+
*
|
|
32
|
+
* @example
|
|
33
|
+
* ```tsx
|
|
34
|
+
* // With sub-menus and shortcuts
|
|
35
|
+
* <ContextMenu>
|
|
36
|
+
* <ContextMenuTrigger>Right-click me</ContextMenuTrigger>
|
|
37
|
+
* <ContextMenuContent>
|
|
38
|
+
* <ContextMenuItem>
|
|
39
|
+
* Edit <ContextMenuShortcut>⌘E</ContextMenuShortcut>
|
|
40
|
+
* </ContextMenuItem>
|
|
41
|
+
* <ContextMenuSub>
|
|
42
|
+
* <ContextMenuSubTrigger>Share</ContextMenuSubTrigger>
|
|
43
|
+
* <ContextMenuSubContent>
|
|
44
|
+
* <ContextMenuItem>Email</ContextMenuItem>
|
|
45
|
+
* <ContextMenuItem>Copy Link</ContextMenuItem>
|
|
46
|
+
* </ContextMenuSubContent>
|
|
47
|
+
* </ContextMenuSub>
|
|
48
|
+
* </ContextMenuContent>
|
|
49
|
+
* </ContextMenu>
|
|
50
|
+
* ```
|
|
51
|
+
*
|
|
52
|
+
* @accessibility
|
|
53
|
+
* - Triggered by right-click, long-press, or Shift+F10
|
|
54
|
+
* - Full keyboard navigation with arrow keys
|
|
55
|
+
* - Escape key closes the menu and sub-menus
|
|
56
|
+
* - Enter/Space activates menu items
|
|
57
|
+
* - Tab moves focus outside the menu
|
|
58
|
+
* - Proper ARIA roles and focus management
|
|
59
|
+
* - Screen reader announcements for menu state changes
|
|
60
|
+
*
|
|
61
|
+
* @see {@link https://ui.shadcn.com/docs/components/context-menu} shadcn/ui docs
|
|
62
|
+
* @since 1.0.0
|
|
63
|
+
* @see {@link https://www.radix-ui.com/primitives/docs/components/context-menu} Radix UI docs
|
|
64
|
+
*/
|
|
65
|
+
function ContextMenu({
|
|
66
|
+
...props
|
|
67
|
+
}: React.ComponentProps<typeof ContextMenuPrimitive.Root>) {
|
|
68
|
+
return <ContextMenuPrimitive.Root data-slot="context-menu" {...props} />;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* ContextMenuTrigger - The element that triggers the context menu
|
|
73
|
+
*
|
|
74
|
+
* Wraps any element to make it respond to right-click or long-press events.
|
|
75
|
+
* The trigger element should provide visual feedback about its interactive nature.
|
|
76
|
+
*
|
|
77
|
+
* @example
|
|
78
|
+
* ```tsx
|
|
79
|
+
* <ContextMenuTrigger>
|
|
80
|
+
* <Button variant="outline">Right-click me</Button>
|
|
81
|
+
* </ContextMenuTrigger>
|
|
82
|
+
* ```
|
|
83
|
+
*
|
|
84
|
+
* @param children - Any React element that should trigger the context menu
|
|
85
|
+
*/
|
|
86
|
+
function ContextMenuTrigger({
|
|
87
|
+
...props
|
|
88
|
+
}: React.ComponentProps<typeof ContextMenuPrimitive.Trigger>) {
|
|
89
|
+
return (
|
|
90
|
+
<ContextMenuPrimitive.Trigger data-slot="context-menu-trigger" {...props} />
|
|
91
|
+
);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* ContextMenuGroup - Logical grouping for menu items
|
|
96
|
+
*
|
|
97
|
+
* Groups related menu items together for better organization and accessibility.
|
|
98
|
+
* Provides semantic structure without visual changes.
|
|
99
|
+
*
|
|
100
|
+
* @example
|
|
101
|
+
* ```tsx
|
|
102
|
+
* <ContextMenuGroup>
|
|
103
|
+
* <ContextMenuItem>Copy</ContextMenuItem>
|
|
104
|
+
* <ContextMenuItem>Cut</ContextMenuItem>
|
|
105
|
+
* <ContextMenuItem>Paste</ContextMenuItem>
|
|
106
|
+
* </ContextMenuGroup>
|
|
107
|
+
* ```
|
|
108
|
+
*/
|
|
109
|
+
function ContextMenuGroup({
|
|
110
|
+
...props
|
|
111
|
+
}: React.ComponentProps<typeof ContextMenuPrimitive.Group>) {
|
|
112
|
+
return (
|
|
113
|
+
<ContextMenuPrimitive.Group data-slot="context-menu-group" {...props} />
|
|
114
|
+
);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* ContextMenuPortal - Portal container for menu content
|
|
119
|
+
*
|
|
120
|
+
* Renders menu content in a portal to ensure proper layering and positioning.
|
|
121
|
+
* Typically used with sub-menus to control rendering context.
|
|
122
|
+
*
|
|
123
|
+
* @example
|
|
124
|
+
* ```tsx
|
|
125
|
+
* <ContextMenuPortal>
|
|
126
|
+
* <ContextMenuSubContent>
|
|
127
|
+
* <ContextMenuItem>Portal Item</ContextMenuItem>
|
|
128
|
+
* </ContextMenuSubContent>
|
|
129
|
+
* </ContextMenuPortal>
|
|
130
|
+
* ```
|
|
131
|
+
*
|
|
132
|
+
* @param container - Custom container element for the portal
|
|
133
|
+
*/
|
|
134
|
+
function ContextMenuPortal({
|
|
135
|
+
...props
|
|
136
|
+
}: React.ComponentProps<typeof ContextMenuPrimitive.Portal>) {
|
|
137
|
+
return (
|
|
138
|
+
<ContextMenuPrimitive.Portal data-slot="context-menu-portal" {...props} />
|
|
139
|
+
);
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* ContextMenuSub - Container for sub-menu functionality
|
|
144
|
+
*
|
|
145
|
+
* Wraps a sub-menu trigger and its content to create nested menu structures.
|
|
146
|
+
* Enables hierarchical organization of menu items.
|
|
147
|
+
*
|
|
148
|
+
* @example
|
|
149
|
+
* ```tsx
|
|
150
|
+
* <ContextMenuSub>
|
|
151
|
+
* <ContextMenuSubTrigger>Share</ContextMenuSubTrigger>
|
|
152
|
+
* <ContextMenuSubContent>
|
|
153
|
+
* <ContextMenuItem>Email</ContextMenuItem>
|
|
154
|
+
* <ContextMenuItem>Copy Link</ContextMenuItem>
|
|
155
|
+
* </ContextMenuSubContent>
|
|
156
|
+
* </ContextMenuSub>
|
|
157
|
+
* ```
|
|
158
|
+
*/
|
|
159
|
+
function ContextMenuSub({
|
|
160
|
+
...props
|
|
161
|
+
}: React.ComponentProps<typeof ContextMenuPrimitive.Sub>) {
|
|
162
|
+
return <ContextMenuPrimitive.Sub data-slot="context-menu-sub" {...props} />;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
/**
|
|
166
|
+
* ContextMenuRadioGroup - Container for radio button items
|
|
167
|
+
*
|
|
168
|
+
* Groups radio items together to allow single selection from multiple options.
|
|
169
|
+
* Manages the selected state and ensures only one item can be selected.
|
|
170
|
+
*
|
|
171
|
+
* @example
|
|
172
|
+
* ```tsx
|
|
173
|
+
* <ContextMenuRadioGroup value={theme} onValueChange={setTheme}>
|
|
174
|
+
* <ContextMenuRadioItem value="light">Light</ContextMenuRadioItem>
|
|
175
|
+
* <ContextMenuRadioItem value="dark">Dark</ContextMenuRadioItem>
|
|
176
|
+
* <ContextMenuRadioItem value="system">System</ContextMenuRadioItem>
|
|
177
|
+
* </ContextMenuRadioGroup>
|
|
178
|
+
* ```
|
|
179
|
+
*
|
|
180
|
+
* @param value - The currently selected value
|
|
181
|
+
* @param onValueChange - Callback fired when selection changes
|
|
182
|
+
*/
|
|
183
|
+
function ContextMenuRadioGroup({
|
|
184
|
+
...props
|
|
185
|
+
}: React.ComponentProps<typeof ContextMenuPrimitive.RadioGroup>) {
|
|
186
|
+
return (
|
|
187
|
+
<ContextMenuPrimitive.RadioGroup
|
|
188
|
+
data-slot="context-menu-radio-group"
|
|
189
|
+
{...props}
|
|
190
|
+
/>
|
|
191
|
+
);
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
/**
|
|
195
|
+
* ContextMenuSubTrigger - Trigger element for opening sub-menus
|
|
196
|
+
*
|
|
197
|
+
* Menu item that opens a sub-menu on hover or focus. Automatically includes
|
|
198
|
+
* a chevron icon to indicate the presence of a sub-menu.
|
|
199
|
+
*
|
|
200
|
+
* @example
|
|
201
|
+
* ```tsx
|
|
202
|
+
* <ContextMenuSubTrigger>
|
|
203
|
+
* <Share className="mr-2 h-4 w-4" />
|
|
204
|
+
* Share Options
|
|
205
|
+
* </ContextMenuSubTrigger>
|
|
206
|
+
* ```
|
|
207
|
+
*
|
|
208
|
+
* @param inset - Whether to indent the trigger for proper alignment
|
|
209
|
+
* @param children - Content of the trigger (text, icons, etc.)
|
|
210
|
+
*/
|
|
211
|
+
function ContextMenuSubTrigger({
|
|
212
|
+
className,
|
|
213
|
+
inset,
|
|
214
|
+
children,
|
|
215
|
+
...props
|
|
216
|
+
}: React.ComponentProps<typeof ContextMenuPrimitive.SubTrigger> & {
|
|
217
|
+
/** Whether to indent the trigger for proper alignment */
|
|
218
|
+
inset?: boolean;
|
|
219
|
+
}) {
|
|
220
|
+
return (
|
|
221
|
+
<ContextMenuPrimitive.SubTrigger
|
|
222
|
+
data-slot="context-menu-sub-trigger"
|
|
223
|
+
data-inset={inset}
|
|
224
|
+
className={cn(
|
|
225
|
+
"focus:bg-accent focus:text-accent-foreground data-[state=open]:bg-accent data-[state=open]:text-accent-foreground flex cursor-default items-center rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-[inset]:pl-8 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
|
|
226
|
+
className,
|
|
227
|
+
)}
|
|
228
|
+
{...props}
|
|
229
|
+
>
|
|
230
|
+
{children}
|
|
231
|
+
<ChevronRightIcon className="ml-auto" />
|
|
232
|
+
</ContextMenuPrimitive.SubTrigger>
|
|
233
|
+
);
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
/**
|
|
237
|
+
* ContextMenuSubContent - Container for sub-menu items
|
|
238
|
+
*
|
|
239
|
+
* Contains the items within a sub-menu. Automatically positioned relative
|
|
240
|
+
* to its trigger with collision detection and smooth animations.
|
|
241
|
+
*
|
|
242
|
+
* @example
|
|
243
|
+
* ```tsx
|
|
244
|
+
* <ContextMenuSubContent>
|
|
245
|
+
* <ContextMenuItem>Option 1</ContextMenuItem>
|
|
246
|
+
* <ContextMenuItem>Option 2</ContextMenuItem>
|
|
247
|
+
* <ContextMenuSeparator />
|
|
248
|
+
* <ContextMenuItem>Option 3</ContextMenuItem>
|
|
249
|
+
* </ContextMenuSubContent>
|
|
250
|
+
* ```
|
|
251
|
+
*
|
|
252
|
+
* @param className - Additional CSS classes for styling
|
|
253
|
+
* @param children - Sub-menu items, separators, and labels
|
|
254
|
+
*/
|
|
255
|
+
function ContextMenuSubContent({
|
|
256
|
+
className,
|
|
257
|
+
...props
|
|
258
|
+
}: React.ComponentProps<typeof ContextMenuPrimitive.SubContent>) {
|
|
259
|
+
return (
|
|
260
|
+
<ContextMenuPrimitive.SubContent
|
|
261
|
+
data-slot="context-menu-sub-content"
|
|
262
|
+
className={cn(
|
|
263
|
+
"bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 min-w-[8rem] origin-(--radix-context-menu-content-transform-origin) overflow-hidden rounded-md border p-1 shadow-lg",
|
|
264
|
+
className,
|
|
265
|
+
)}
|
|
266
|
+
{...props}
|
|
267
|
+
/>
|
|
268
|
+
);
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
/**
|
|
272
|
+
* ContextMenuContent - The container for context menu items
|
|
273
|
+
*
|
|
274
|
+
* Contains all menu items, separators, labels, and sub-menus. Automatically
|
|
275
|
+
* positioned relative to the trigger point with collision detection.
|
|
276
|
+
*
|
|
277
|
+
* @example
|
|
278
|
+
* ```tsx
|
|
279
|
+
* <ContextMenuContent className="w-56">
|
|
280
|
+
* <ContextMenuLabel>Actions</ContextMenuLabel>
|
|
281
|
+
* <ContextMenuSeparator />
|
|
282
|
+
* <ContextMenuItem>Copy</ContextMenuItem>
|
|
283
|
+
* <ContextMenuItem>Paste</ContextMenuItem>
|
|
284
|
+
* </ContextMenuContent>
|
|
285
|
+
* ```
|
|
286
|
+
*
|
|
287
|
+
* @param className - Additional CSS classes for styling
|
|
288
|
+
* @param children - Menu items, separators, labels, and sub-menus
|
|
289
|
+
*/
|
|
290
|
+
function ContextMenuContent({
|
|
291
|
+
className,
|
|
292
|
+
...props
|
|
293
|
+
}: React.ComponentProps<typeof ContextMenuPrimitive.Content>) {
|
|
294
|
+
return (
|
|
295
|
+
<ContextMenuPrimitive.Portal>
|
|
296
|
+
<ContextMenuPrimitive.Content
|
|
297
|
+
data-slot="context-menu-content"
|
|
298
|
+
className={cn(
|
|
299
|
+
"bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 max-h-(--radix-context-menu-content-available-height) min-w-[8rem] origin-(--radix-context-menu-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-md border p-1 shadow-md",
|
|
300
|
+
className,
|
|
301
|
+
)}
|
|
302
|
+
{...props}
|
|
303
|
+
/>
|
|
304
|
+
</ContextMenuPrimitive.Portal>
|
|
305
|
+
);
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
/**
|
|
309
|
+
* ContextMenuItem - An actionable item within the context menu
|
|
310
|
+
*
|
|
311
|
+
* Individual menu items that users can interact with. Supports different
|
|
312
|
+
* variants for visual hierarchy and includes automatic icon styling.
|
|
313
|
+
*
|
|
314
|
+
* @example
|
|
315
|
+
* ```tsx
|
|
316
|
+
* <ContextMenuItem>
|
|
317
|
+
* <Edit className="mr-2 h-4 w-4" />
|
|
318
|
+
* Edit
|
|
319
|
+
* <ContextMenuShortcut>⌘E</ContextMenuShortcut>
|
|
320
|
+
* </ContextMenuItem>
|
|
321
|
+
* ```
|
|
322
|
+
*
|
|
323
|
+
* @example
|
|
324
|
+
* ```tsx
|
|
325
|
+
* <ContextMenuItem variant="destructive">
|
|
326
|
+
* <Trash2 className="mr-2 h-4 w-4" />
|
|
327
|
+
* Delete
|
|
328
|
+
* </ContextMenuItem>
|
|
329
|
+
* ```
|
|
330
|
+
*
|
|
331
|
+
* @param inset - Whether to indent the item (useful when mixing items with/without icons)
|
|
332
|
+
* @param variant - Visual variant: "default" for normal actions, "destructive" for dangerous actions
|
|
333
|
+
* @param disabled - Whether the item is disabled and non-interactive
|
|
334
|
+
* @param onSelect - Callback fired when the item is selected
|
|
335
|
+
*/
|
|
336
|
+
function ContextMenuItem({
|
|
337
|
+
className,
|
|
338
|
+
inset,
|
|
339
|
+
variant = "default",
|
|
340
|
+
...props
|
|
341
|
+
}: React.ComponentProps<typeof ContextMenuPrimitive.Item> & {
|
|
342
|
+
/** Whether to indent the item for proper alignment */
|
|
343
|
+
inset?: boolean;
|
|
344
|
+
/** Visual variant for the menu item */
|
|
345
|
+
variant?: "default" | "destructive";
|
|
346
|
+
}) {
|
|
347
|
+
return (
|
|
348
|
+
<ContextMenuPrimitive.Item
|
|
349
|
+
data-slot="context-menu-item"
|
|
350
|
+
data-inset={inset}
|
|
351
|
+
data-variant={variant}
|
|
352
|
+
className={cn(
|
|
353
|
+
"focus:bg-accent focus:text-accent-foreground data-[variant=destructive]:text-destructive data-[variant=destructive]:focus:bg-destructive/10 dark:data-[variant=destructive]:focus:bg-destructive/20 data-[variant=destructive]:focus:text-destructive data-[variant=destructive]:*:[svg]:!text-destructive [&_svg:not([class*='text-'])]:text-muted-foreground relative flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 data-[inset]:pl-8 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
|
|
354
|
+
className,
|
|
355
|
+
)}
|
|
356
|
+
{...props}
|
|
357
|
+
/>
|
|
358
|
+
);
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
/**
|
|
362
|
+
* ContextMenuCheckboxItem - A menu item with checkbox functionality
|
|
363
|
+
*
|
|
364
|
+
* Menu items that can be toggled on/off, useful for binary settings or options.
|
|
365
|
+
* Displays a check mark when selected and supports controlled state management.
|
|
366
|
+
*
|
|
367
|
+
* @example
|
|
368
|
+
* ```tsx
|
|
369
|
+
* const [showGrid, setShowGrid] = useState(true)
|
|
370
|
+
*
|
|
371
|
+
* <ContextMenuCheckboxItem
|
|
372
|
+
* checked={showGrid}
|
|
373
|
+
* onCheckedChange={setShowGrid}
|
|
374
|
+
* >
|
|
375
|
+
* Show Grid
|
|
376
|
+
* </ContextMenuCheckboxItem>
|
|
377
|
+
* ```
|
|
378
|
+
*
|
|
379
|
+
* @param checked - Whether the checkbox is checked
|
|
380
|
+
* @param onCheckedChange - Callback fired when the checked state changes
|
|
381
|
+
* @param disabled - Whether the item is disabled
|
|
382
|
+
*/
|
|
383
|
+
function ContextMenuCheckboxItem({
|
|
384
|
+
className,
|
|
385
|
+
children,
|
|
386
|
+
checked,
|
|
387
|
+
...props
|
|
388
|
+
}: React.ComponentProps<typeof ContextMenuPrimitive.CheckboxItem>) {
|
|
389
|
+
return (
|
|
390
|
+
<ContextMenuPrimitive.CheckboxItem
|
|
391
|
+
data-slot="context-menu-checkbox-item"
|
|
392
|
+
className={cn(
|
|
393
|
+
"focus:bg-accent focus:text-accent-foreground relative flex cursor-default items-center gap-2 rounded-sm py-1.5 pr-2 pl-8 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
|
|
394
|
+
className,
|
|
395
|
+
)}
|
|
396
|
+
checked={checked}
|
|
397
|
+
{...props}
|
|
398
|
+
>
|
|
399
|
+
<span className="pointer-events-none absolute left-2 flex size-3.5 items-center justify-center">
|
|
400
|
+
<ContextMenuPrimitive.ItemIndicator>
|
|
401
|
+
<CheckIcon className="size-4" />
|
|
402
|
+
</ContextMenuPrimitive.ItemIndicator>
|
|
403
|
+
</span>
|
|
404
|
+
{children}
|
|
405
|
+
</ContextMenuPrimitive.CheckboxItem>
|
|
406
|
+
);
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
/**
|
|
410
|
+
* ContextMenuRadioItem - A radio button item within a radio group
|
|
411
|
+
*
|
|
412
|
+
* Menu items that allow single selection from a group of options.
|
|
413
|
+
* Must be used within a ContextMenuRadioGroup for proper functionality.
|
|
414
|
+
*
|
|
415
|
+
* @example
|
|
416
|
+
* ```tsx
|
|
417
|
+
* <ContextMenuRadioGroup value={theme} onValueChange={setTheme}>
|
|
418
|
+
* <ContextMenuRadioItem value="light">Light</ContextMenuRadioItem>
|
|
419
|
+
* <ContextMenuRadioItem value="dark">Dark</ContextMenuRadioItem>
|
|
420
|
+
* <ContextMenuRadioItem value="system">System</ContextMenuRadioItem>
|
|
421
|
+
* </ContextMenuRadioGroup>
|
|
422
|
+
* ```
|
|
423
|
+
*
|
|
424
|
+
* @param value - The value of this radio item
|
|
425
|
+
* @param disabled - Whether the item is disabled
|
|
426
|
+
*/
|
|
427
|
+
function ContextMenuRadioItem({
|
|
428
|
+
className,
|
|
429
|
+
children,
|
|
430
|
+
...props
|
|
431
|
+
}: React.ComponentProps<typeof ContextMenuPrimitive.RadioItem>) {
|
|
432
|
+
return (
|
|
433
|
+
<ContextMenuPrimitive.RadioItem
|
|
434
|
+
data-slot="context-menu-radio-item"
|
|
435
|
+
className={cn(
|
|
436
|
+
"focus:bg-accent focus:text-accent-foreground relative flex cursor-default items-center gap-2 rounded-sm py-1.5 pr-2 pl-8 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
|
|
437
|
+
className,
|
|
438
|
+
)}
|
|
439
|
+
{...props}
|
|
440
|
+
>
|
|
441
|
+
<span className="pointer-events-none absolute left-2 flex size-3.5 items-center justify-center">
|
|
442
|
+
<ContextMenuPrimitive.ItemIndicator>
|
|
443
|
+
<CircleIcon className="size-2 fill-current" />
|
|
444
|
+
</ContextMenuPrimitive.ItemIndicator>
|
|
445
|
+
</span>
|
|
446
|
+
{children}
|
|
447
|
+
</ContextMenuPrimitive.RadioItem>
|
|
448
|
+
);
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
/**
|
|
452
|
+
* ContextMenuLabel - A non-interactive label for menu sections
|
|
453
|
+
*
|
|
454
|
+
* Used to group related menu items and provide context. Labels are not
|
|
455
|
+
* focusable and serve as visual section headers within the menu.
|
|
456
|
+
*
|
|
457
|
+
* @example
|
|
458
|
+
* ```tsx
|
|
459
|
+
* <ContextMenuLabel>File Actions</ContextMenuLabel>
|
|
460
|
+
* <ContextMenuSeparator />
|
|
461
|
+
* <ContextMenuItem>Open</ContextMenuItem>
|
|
462
|
+
* <ContextMenuItem>Save</ContextMenuItem>
|
|
463
|
+
* ```
|
|
464
|
+
*
|
|
465
|
+
* @param inset - Whether to indent the label to align with inset items
|
|
466
|
+
*/
|
|
467
|
+
function ContextMenuLabel({
|
|
468
|
+
className,
|
|
469
|
+
inset,
|
|
470
|
+
...props
|
|
471
|
+
}: React.ComponentProps<typeof ContextMenuPrimitive.Label> & {
|
|
472
|
+
/** Whether to indent the label for proper alignment */
|
|
473
|
+
inset?: boolean;
|
|
474
|
+
}) {
|
|
475
|
+
return (
|
|
476
|
+
<ContextMenuPrimitive.Label
|
|
477
|
+
data-slot="context-menu-label"
|
|
478
|
+
data-inset={inset}
|
|
479
|
+
className={cn(
|
|
480
|
+
"text-foreground px-2 py-1.5 text-sm font-medium data-[inset]:pl-8",
|
|
481
|
+
className,
|
|
482
|
+
)}
|
|
483
|
+
{...props}
|
|
484
|
+
/>
|
|
485
|
+
);
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
/**
|
|
489
|
+
* ContextMenuSeparator - A visual divider between menu items
|
|
490
|
+
*
|
|
491
|
+
* Creates visual separation between groups of related menu items.
|
|
492
|
+
* Typically used after labels or to separate different types of actions.
|
|
493
|
+
*
|
|
494
|
+
* @example
|
|
495
|
+
* ```tsx
|
|
496
|
+
* <ContextMenuItem>Copy</ContextMenuItem>
|
|
497
|
+
* <ContextMenuItem>Paste</ContextMenuItem>
|
|
498
|
+
* <ContextMenuSeparator />
|
|
499
|
+
* <ContextMenuItem variant="destructive">Delete</ContextMenuItem>
|
|
500
|
+
* ```
|
|
501
|
+
*/
|
|
502
|
+
function ContextMenuSeparator({
|
|
503
|
+
className,
|
|
504
|
+
...props
|
|
505
|
+
}: React.ComponentProps<typeof ContextMenuPrimitive.Separator>) {
|
|
506
|
+
return (
|
|
507
|
+
<ContextMenuPrimitive.Separator
|
|
508
|
+
data-slot="context-menu-separator"
|
|
509
|
+
className={cn("bg-border -mx-1 my-1 h-px", className)}
|
|
510
|
+
{...props}
|
|
511
|
+
/>
|
|
512
|
+
);
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
/**
|
|
516
|
+
* ContextMenuShortcut - Displays keyboard shortcuts within menu items
|
|
517
|
+
*
|
|
518
|
+
* Shows keyboard shortcuts aligned to the right side of menu items.
|
|
519
|
+
* Provides visual indication of available keyboard shortcuts for actions.
|
|
520
|
+
*
|
|
521
|
+
* @example
|
|
522
|
+
* ```tsx
|
|
523
|
+
* <ContextMenuItem>
|
|
524
|
+
* Copy
|
|
525
|
+
* <ContextMenuShortcut>⌘C</ContextMenuShortcut>
|
|
526
|
+
* </ContextMenuItem>
|
|
527
|
+
* ```
|
|
528
|
+
*
|
|
529
|
+
* @param children - The shortcut text (e.g., "⌘C", "Ctrl+V")
|
|
530
|
+
*/
|
|
531
|
+
function ContextMenuShortcut({
|
|
532
|
+
className,
|
|
533
|
+
...props
|
|
534
|
+
}: React.ComponentProps<"span">) {
|
|
535
|
+
return (
|
|
536
|
+
<span
|
|
537
|
+
data-slot="context-menu-shortcut"
|
|
538
|
+
className={cn(
|
|
539
|
+
"text-muted-foreground ml-auto text-xs tracking-widest",
|
|
540
|
+
className,
|
|
541
|
+
)}
|
|
542
|
+
{...props}
|
|
543
|
+
/>
|
|
544
|
+
);
|
|
545
|
+
}
|
|
546
|
+
|
|
547
|
+
export {
|
|
548
|
+
ContextMenu,
|
|
549
|
+
ContextMenuTrigger,
|
|
550
|
+
ContextMenuContent,
|
|
551
|
+
ContextMenuItem,
|
|
552
|
+
ContextMenuCheckboxItem,
|
|
553
|
+
ContextMenuRadioItem,
|
|
554
|
+
ContextMenuLabel,
|
|
555
|
+
ContextMenuSeparator,
|
|
556
|
+
ContextMenuShortcut,
|
|
557
|
+
ContextMenuGroup,
|
|
558
|
+
ContextMenuPortal,
|
|
559
|
+
ContextMenuSub,
|
|
560
|
+
ContextMenuSubContent,
|
|
561
|
+
ContextMenuSubTrigger,
|
|
562
|
+
ContextMenuRadioGroup,
|
|
563
|
+
};
|