@olympusoss/canvas 2.6.19

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.
Files changed (128) hide show
  1. package/package.json +179 -0
  2. package/src/components/atoms/README.md +11 -0
  3. package/src/components/atoms/aspect-ratio.tsx +32 -0
  4. package/src/components/atoms/avatar.tsx +98 -0
  5. package/src/components/atoms/badge.tsx +44 -0
  6. package/src/components/atoms/brand-mark.tsx +74 -0
  7. package/src/components/atoms/button.tsx +104 -0
  8. package/src/components/atoms/checkbox.tsx +63 -0
  9. package/src/components/atoms/flex-box.tsx +105 -0
  10. package/src/components/atoms/icon.tsx +34 -0
  11. package/src/components/atoms/input.tsx +91 -0
  12. package/src/components/atoms/label.tsx +41 -0
  13. package/src/components/atoms/logo.tsx +89 -0
  14. package/src/components/atoms/progress.tsx +55 -0
  15. package/src/components/atoms/radio-group.tsx +122 -0
  16. package/src/components/atoms/scroll-area.tsx +106 -0
  17. package/src/components/atoms/section.tsx +48 -0
  18. package/src/components/atoms/separator.tsx +45 -0
  19. package/src/components/atoms/skeleton.tsx +17 -0
  20. package/src/components/atoms/slider.tsx +93 -0
  21. package/src/components/atoms/switch.tsx +60 -0
  22. package/src/components/atoms/textarea.tsx +78 -0
  23. package/src/components/atoms/toggle.tsx +80 -0
  24. package/src/components/charts/activity-heatmap.tsx +96 -0
  25. package/src/components/charts/axes.tsx +21 -0
  26. package/src/components/charts/chart-container.tsx +195 -0
  27. package/src/components/charts/chart-legend.tsx +67 -0
  28. package/src/components/charts/chart-tooltip.tsx +161 -0
  29. package/src/components/charts/chart-types.tsx +49 -0
  30. package/src/components/charts/containers.tsx +11 -0
  31. package/src/components/charts/data.tsx +16 -0
  32. package/src/components/charts/details.tsx +25 -0
  33. package/src/components/charts/gauge.tsx +106 -0
  34. package/src/components/charts/grids.tsx +8 -0
  35. package/src/components/charts/index.ts +62 -0
  36. package/src/components/charts/labeled-bar-list.tsx +85 -0
  37. package/src/components/charts/references.tsx +8 -0
  38. package/src/components/charts/service-health-list.tsx +73 -0
  39. package/src/components/charts/sparkline.tsx +52 -0
  40. package/src/components/charts/stacked-bar.tsx +104 -0
  41. package/src/components/charts/text.tsx +10 -0
  42. package/src/components/charts/world-heat-map-inner.tsx +317 -0
  43. package/src/components/charts/world-heat-map.tsx +184 -0
  44. package/src/components/molecules/README.md +12 -0
  45. package/src/components/molecules/action-bar.tsx +73 -0
  46. package/src/components/molecules/activity-item.tsx +74 -0
  47. package/src/components/molecules/alert.tsx +80 -0
  48. package/src/components/molecules/animated-background.tsx +92 -0
  49. package/src/components/molecules/brand-lockup.tsx +48 -0
  50. package/src/components/molecules/breadcrumb.tsx +161 -0
  51. package/src/components/molecules/button-group.tsx +104 -0
  52. package/src/components/molecules/calendar.tsx +216 -0
  53. package/src/components/molecules/card.tsx +101 -0
  54. package/src/components/molecules/code-block.tsx +48 -0
  55. package/src/components/molecules/empty-state.tsx +55 -0
  56. package/src/components/molecules/error-state.tsx +42 -0
  57. package/src/components/molecules/field-display.tsx +35 -0
  58. package/src/components/molecules/input-otp.tsx +74 -0
  59. package/src/components/molecules/loading-state.tsx +36 -0
  60. package/src/components/molecules/notification-item.tsx +67 -0
  61. package/src/components/molecules/notification-list.tsx +45 -0
  62. package/src/components/molecules/number-badge.tsx +53 -0
  63. package/src/components/molecules/page-header.tsx +88 -0
  64. package/src/components/molecules/page-tabs.tsx +94 -0
  65. package/src/components/molecules/pagination.tsx +150 -0
  66. package/src/components/molecules/phone-input.tsx +200 -0
  67. package/src/components/molecules/search-bar.tsx +64 -0
  68. package/src/components/molecules/secret-field.tsx +158 -0
  69. package/src/components/molecules/section-card.tsx +91 -0
  70. package/src/components/molecules/stat-card.tsx +96 -0
  71. package/src/components/molecules/status-badge.tsx +42 -0
  72. package/src/components/molecules/stepper.tsx +96 -0
  73. package/src/components/molecules/table.tsx +157 -0
  74. package/src/components/molecules/toggle-group.tsx +145 -0
  75. package/src/components/molecules/tooltip.tsx +150 -0
  76. package/src/components/molecules/user-avatar-chip.tsx +71 -0
  77. package/src/components/organisms/README.md +14 -0
  78. package/src/components/organisms/accordion.tsx +149 -0
  79. package/src/components/organisms/alert-dialog.tsx +269 -0
  80. package/src/components/organisms/carousel.tsx +244 -0
  81. package/src/components/organisms/collapsible.tsx +69 -0
  82. package/src/components/organisms/command.tsx +143 -0
  83. package/src/components/organisms/context-menu.tsx +333 -0
  84. package/src/components/organisms/dashboard-grid.tsx +360 -0
  85. package/src/components/organisms/data-table.tsx +330 -0
  86. package/src/components/organisms/dialog.tsx +304 -0
  87. package/src/components/organisms/drawer.tsx +100 -0
  88. package/src/components/organisms/dropdown-menu.tsx +434 -0
  89. package/src/components/organisms/editors/code-editor.tsx +144 -0
  90. package/src/components/organisms/editors/index.ts +4 -0
  91. package/src/components/organisms/editors/markdown-editor.tsx +153 -0
  92. package/src/components/organisms/editors/markdown-renderer.ts +27 -0
  93. package/src/components/organisms/editors/prose-canvas-classes.ts +45 -0
  94. package/src/components/organisms/editors/rich-text-editor.tsx +126 -0
  95. package/src/components/organisms/editors/toolbar/md-toolbar.tsx +129 -0
  96. package/src/components/organisms/editors/toolbar/rte-toolbar.tsx +211 -0
  97. package/src/components/organisms/editors/toolbar/toolbar-shell.tsx +45 -0
  98. package/src/components/organisms/editors/use-codemirror-theme.ts +61 -0
  99. package/src/components/organisms/error-boundary.tsx +61 -0
  100. package/src/components/organisms/form.tsx +174 -0
  101. package/src/components/organisms/hover-card.tsx +114 -0
  102. package/src/components/organisms/menubar.tsx +491 -0
  103. package/src/components/organisms/navbar.tsx +101 -0
  104. package/src/components/organisms/navigation-menu.tsx +234 -0
  105. package/src/components/organisms/popover.tsx +144 -0
  106. package/src/components/organisms/resizable.tsx +39 -0
  107. package/src/components/organisms/schema-form.tsx +232 -0
  108. package/src/components/organisms/select.tsx +303 -0
  109. package/src/components/organisms/sheet.tsx +256 -0
  110. package/src/components/organisms/sidebar.tsx +1037 -0
  111. package/src/components/organisms/sonner.tsx +96 -0
  112. package/src/components/organisms/tabs.tsx +132 -0
  113. package/src/components/organisms/theme-provider.tsx +101 -0
  114. package/src/hooks/use-mobile.tsx +19 -0
  115. package/src/index.ts +547 -0
  116. package/src/lib/portal-container.tsx +35 -0
  117. package/src/lib/utils.ts +6 -0
  118. package/src/native.ts +23 -0
  119. package/src/tokens/colors.ts +91 -0
  120. package/src/tokens/index.ts +3 -0
  121. package/src/tokens/spacing.ts +55 -0
  122. package/src/tokens/typography.ts +27 -0
  123. package/styles/canvas.css +55 -0
  124. package/styles/dashboard-grid.css +47 -0
  125. package/styles/leaflet.css +13 -0
  126. package/styles/tokens.css +234 -0
  127. package/tailwind.config.ts +70 -0
  128. package/tsconfig.json +23 -0
@@ -0,0 +1,143 @@
1
+ "use client";
2
+
3
+ import type { DialogProps } from "@radix-ui/react-dialog";
4
+ import { Command as CommandPrimitive } from "cmdk";
5
+ import { Search } from "lucide-react";
6
+ import * as React from "react";
7
+
8
+ import { cn } from "../../lib/utils";
9
+ import { Dialog, DialogContent } from "./dialog";
10
+
11
+ const Command = React.forwardRef<
12
+ React.ElementRef<typeof CommandPrimitive>,
13
+ React.ComponentPropsWithoutRef<typeof CommandPrimitive>
14
+ >(({ className, ...props }, ref) => (
15
+ <CommandPrimitive
16
+ ref={ref}
17
+ className={cn(
18
+ "flex h-full w-full flex-col overflow-hidden rounded-md bg-popover text-popover-foreground",
19
+ className,
20
+ )}
21
+ {...props}
22
+ />
23
+ ));
24
+ Command.displayName = CommandPrimitive.displayName;
25
+
26
+ const CommandDialog = ({ children, ...props }: DialogProps) => {
27
+ return (
28
+ <Dialog {...props}>
29
+ <DialogContent className="overflow-hidden p-0">
30
+ <Command className="[&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group-heading]]:text-muted-foreground [&_[cmdk-group]:not([hidden])_~[cmdk-group]]:pt-0 [&_[cmdk-group]]:px-2 [&_[cmdk-input-wrapper]_svg]:h-5 [&_[cmdk-input-wrapper]_svg]:w-5 [&_[cmdk-input]]:h-12 [&_[cmdk-item]]:px-2 [&_[cmdk-item]]:py-3 [&_[cmdk-item]_svg]:h-5 [&_[cmdk-item]_svg]:w-5">
31
+ {children}
32
+ </Command>
33
+ </DialogContent>
34
+ </Dialog>
35
+ );
36
+ };
37
+
38
+ const CommandInput = React.forwardRef<
39
+ React.ElementRef<typeof CommandPrimitive.Input>,
40
+ React.ComponentPropsWithoutRef<typeof CommandPrimitive.Input>
41
+ >(({ className, ...props }, ref) => (
42
+ <div className="flex items-center border-b px-3" cmdk-input-wrapper="">
43
+ <Search className="mr-2 h-4 w-4 shrink-0 opacity-50" />
44
+ <CommandPrimitive.Input
45
+ ref={ref}
46
+ className={cn(
47
+ "flex h-10 w-full rounded-md bg-transparent py-3 text-sm outline-none placeholder:text-muted-foreground disabled:cursor-not-allowed disabled:opacity-50",
48
+ className,
49
+ )}
50
+ {...props}
51
+ />
52
+ </div>
53
+ ));
54
+
55
+ CommandInput.displayName = CommandPrimitive.Input.displayName;
56
+
57
+ const CommandList = React.forwardRef<
58
+ React.ElementRef<typeof CommandPrimitive.List>,
59
+ React.ComponentPropsWithoutRef<typeof CommandPrimitive.List>
60
+ >(({ className, ...props }, ref) => (
61
+ <CommandPrimitive.List
62
+ ref={ref}
63
+ className={cn("max-h-[300px] overflow-y-auto overflow-x-hidden", className)}
64
+ {...props}
65
+ />
66
+ ));
67
+
68
+ CommandList.displayName = CommandPrimitive.List.displayName;
69
+
70
+ const CommandEmpty = React.forwardRef<
71
+ React.ElementRef<typeof CommandPrimitive.Empty>,
72
+ React.ComponentPropsWithoutRef<typeof CommandPrimitive.Empty>
73
+ >((props, ref) => (
74
+ <CommandPrimitive.Empty ref={ref} className="py-6 text-center text-sm" {...props} />
75
+ ));
76
+
77
+ CommandEmpty.displayName = CommandPrimitive.Empty.displayName;
78
+
79
+ const CommandGroup = React.forwardRef<
80
+ React.ElementRef<typeof CommandPrimitive.Group>,
81
+ React.ComponentPropsWithoutRef<typeof CommandPrimitive.Group>
82
+ >(({ className, ...props }, ref) => (
83
+ <CommandPrimitive.Group
84
+ ref={ref}
85
+ className={cn(
86
+ "overflow-hidden p-1 text-foreground [&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:py-1.5 [&_[cmdk-group-heading]]:text-xs [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group-heading]]:text-muted-foreground",
87
+ className,
88
+ )}
89
+ {...props}
90
+ />
91
+ ));
92
+
93
+ CommandGroup.displayName = CommandPrimitive.Group.displayName;
94
+
95
+ const CommandSeparator = React.forwardRef<
96
+ React.ElementRef<typeof CommandPrimitive.Separator>,
97
+ React.ComponentPropsWithoutRef<typeof CommandPrimitive.Separator>
98
+ >(({ className, ...props }, ref) => (
99
+ <CommandPrimitive.Separator
100
+ ref={ref}
101
+ className={cn("-mx-1 h-px bg-border", className)}
102
+ {...props}
103
+ />
104
+ ));
105
+ CommandSeparator.displayName = CommandPrimitive.Separator.displayName;
106
+
107
+ const CommandItem = React.forwardRef<
108
+ React.ElementRef<typeof CommandPrimitive.Item>,
109
+ React.ComponentPropsWithoutRef<typeof CommandPrimitive.Item>
110
+ >(({ className, ...props }, ref) => (
111
+ <CommandPrimitive.Item
112
+ ref={ref}
113
+ className={cn(
114
+ "relative flex cursor-default gap-2 select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none data-[disabled=true]:pointer-events-none data-[selected=true]:bg-accent data-[selected=true]:text-accent-foreground data-[disabled=true]:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0",
115
+ className,
116
+ )}
117
+ {...props}
118
+ />
119
+ ));
120
+
121
+ CommandItem.displayName = CommandPrimitive.Item.displayName;
122
+
123
+ const CommandShortcut = ({ className, ...props }: React.HTMLAttributes<HTMLSpanElement>) => {
124
+ return (
125
+ <span
126
+ className={cn("ml-auto text-xs tracking-widest text-muted-foreground", className)}
127
+ {...props}
128
+ />
129
+ );
130
+ };
131
+ CommandShortcut.displayName = "CommandShortcut";
132
+
133
+ export {
134
+ Command,
135
+ CommandDialog,
136
+ CommandEmpty,
137
+ CommandGroup,
138
+ CommandInput,
139
+ CommandItem,
140
+ CommandList,
141
+ CommandSeparator,
142
+ CommandShortcut,
143
+ };
@@ -0,0 +1,333 @@
1
+ "use client";
2
+
3
+ import * as ContextMenuPrimitive from "@radix-ui/react-context-menu";
4
+ import { Check, ChevronRight, Circle } from "lucide-react";
5
+ import * as React from "react";
6
+
7
+ import { cn } from "../../lib/utils";
8
+
9
+ export interface ContextMenuProps extends React.ComponentProps<typeof ContextMenuPrimitive.Root> {
10
+ /** Reading direction. */
11
+ dir?: "ltr" | "rtl";
12
+ /** Fires when the user opens or closes the menu via right-click / long-press. */
13
+ onOpenChange?: (open: boolean) => void;
14
+ /**
15
+ * When true, blocks focus from leaving the menu.
16
+ * @default true
17
+ */
18
+ modal?: boolean;
19
+ /** Trigger + Content. */
20
+ children?: React.ReactNode;
21
+ }
22
+
23
+ const ContextMenu = ContextMenuPrimitive.Root as React.FC<ContextMenuProps>;
24
+
25
+ export interface ContextMenuTriggerProps
26
+ extends React.ComponentPropsWithoutRef<typeof ContextMenuPrimitive.Trigger> {
27
+ /**
28
+ * Disable the right-click trigger.
29
+ * @default false
30
+ */
31
+ disabled?: boolean;
32
+ asChild?: boolean;
33
+ /** The element that opens the context menu on right-click / long-press. */
34
+ children?: React.ReactNode;
35
+ className?: string;
36
+ }
37
+
38
+ const ContextMenuTrigger = ContextMenuPrimitive.Trigger as React.ForwardRefExoticComponent<
39
+ ContextMenuTriggerProps & React.RefAttributes<HTMLSpanElement>
40
+ >;
41
+
42
+ export interface ContextMenuGroupProps
43
+ extends React.ComponentPropsWithoutRef<typeof ContextMenuPrimitive.Group> {
44
+ children?: React.ReactNode;
45
+ }
46
+
47
+ const ContextMenuGroup = ContextMenuPrimitive.Group as React.ForwardRefExoticComponent<
48
+ ContextMenuGroupProps & React.RefAttributes<HTMLDivElement>
49
+ >;
50
+
51
+ export interface ContextMenuPortalProps
52
+ extends React.ComponentPropsWithoutRef<typeof ContextMenuPrimitive.Portal> {
53
+ container?: HTMLElement | null;
54
+ forceMount?: true;
55
+ children?: React.ReactNode;
56
+ }
57
+
58
+ const ContextMenuPortal = ContextMenuPrimitive.Portal as React.FC<ContextMenuPortalProps>;
59
+
60
+ export interface ContextMenuSubProps extends React.ComponentProps<typeof ContextMenuPrimitive.Sub> {
61
+ open?: boolean;
62
+ defaultOpen?: boolean;
63
+ onOpenChange?: (open: boolean) => void;
64
+ children?: React.ReactNode;
65
+ }
66
+
67
+ const ContextMenuSub = ContextMenuPrimitive.Sub as React.FC<ContextMenuSubProps>;
68
+
69
+ export interface ContextMenuRadioGroupProps
70
+ extends React.ComponentPropsWithoutRef<typeof ContextMenuPrimitive.RadioGroup> {
71
+ value?: string;
72
+ onValueChange?: (value: string) => void;
73
+ children?: React.ReactNode;
74
+ }
75
+
76
+ const ContextMenuRadioGroup = ContextMenuPrimitive.RadioGroup as React.ForwardRefExoticComponent<
77
+ ContextMenuRadioGroupProps & React.RefAttributes<HTMLDivElement>
78
+ >;
79
+
80
+ export interface ContextMenuSubTriggerProps
81
+ extends React.ComponentPropsWithoutRef<typeof ContextMenuPrimitive.SubTrigger> {
82
+ /**
83
+ * Add left padding to align with sibling checkbox/radio items.
84
+ * @default false
85
+ */
86
+ inset?: boolean;
87
+ disabled?: boolean;
88
+ asChild?: boolean;
89
+ children?: React.ReactNode;
90
+ className?: string;
91
+ }
92
+
93
+ const ContextMenuSubTrigger = React.forwardRef<
94
+ React.ElementRef<typeof ContextMenuPrimitive.SubTrigger>,
95
+ ContextMenuSubTriggerProps
96
+ >(({ className, inset, children, ...props }, ref) => (
97
+ <ContextMenuPrimitive.SubTrigger
98
+ ref={ref}
99
+ className={cn(
100
+ "flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[state=open]:bg-accent data-[state=open]:text-accent-foreground",
101
+ inset && "pl-8",
102
+ className,
103
+ )}
104
+ {...props}
105
+ >
106
+ {children}
107
+ <ChevronRight className="ml-auto h-4 w-4" />
108
+ </ContextMenuPrimitive.SubTrigger>
109
+ ));
110
+ ContextMenuSubTrigger.displayName = ContextMenuPrimitive.SubTrigger.displayName;
111
+
112
+ export interface ContextMenuSubContentProps
113
+ extends React.ComponentPropsWithoutRef<typeof ContextMenuPrimitive.SubContent> {
114
+ sideOffset?: number;
115
+ alignOffset?: number;
116
+ avoidCollisions?: boolean;
117
+ forceMount?: true;
118
+ asChild?: boolean;
119
+ children?: React.ReactNode;
120
+ className?: string;
121
+ }
122
+
123
+ const ContextMenuSubContent = React.forwardRef<
124
+ React.ElementRef<typeof ContextMenuPrimitive.SubContent>,
125
+ ContextMenuSubContentProps
126
+ >(({ className, ...props }, ref) => (
127
+ <ContextMenuPrimitive.SubContent
128
+ ref={ref}
129
+ className={cn(
130
+ "z-50 min-w-[8rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-lg 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 origin-[var(--radix-context-menu-content-transform-origin)]",
131
+ className,
132
+ )}
133
+ {...props}
134
+ />
135
+ ));
136
+ ContextMenuSubContent.displayName = ContextMenuPrimitive.SubContent.displayName;
137
+
138
+ export interface ContextMenuContentProps
139
+ extends React.ComponentPropsWithoutRef<typeof ContextMenuPrimitive.Content> {
140
+ /** Distance from the alignment edge (px). */
141
+ alignOffset?: number;
142
+ avoidCollisions?: boolean;
143
+ collisionPadding?: number | { top?: number; right?: number; bottom?: number; left?: number };
144
+ loop?: boolean;
145
+ forceMount?: true;
146
+ asChild?: boolean;
147
+ onEscapeKeyDown?: (event: KeyboardEvent) => void;
148
+ onPointerDownOutside?: (event: CustomEvent<{ originalEvent: PointerEvent }>) => void;
149
+ onInteractOutside?: (event: Event) => void;
150
+ children?: React.ReactNode;
151
+ className?: string;
152
+ }
153
+
154
+ const ContextMenuContent = React.forwardRef<
155
+ React.ElementRef<typeof ContextMenuPrimitive.Content>,
156
+ ContextMenuContentProps
157
+ >(({ className, ...props }, ref) => (
158
+ <ContextMenuPrimitive.Portal>
159
+ <ContextMenuPrimitive.Content
160
+ ref={ref}
161
+ className={cn(
162
+ "z-50 max-h-[var(--radix-context-menu-content-available-height)] min-w-[8rem] overflow-y-auto overflow-x-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-md 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 origin-[var(--radix-context-menu-content-transform-origin)]",
163
+ className,
164
+ )}
165
+ {...props}
166
+ />
167
+ </ContextMenuPrimitive.Portal>
168
+ ));
169
+ ContextMenuContent.displayName = ContextMenuPrimitive.Content.displayName;
170
+
171
+ export interface ContextMenuItemProps
172
+ extends React.ComponentPropsWithoutRef<typeof ContextMenuPrimitive.Item> {
173
+ /** Add left padding to align with checkbox/radio items. */
174
+ inset?: boolean;
175
+ disabled?: boolean;
176
+ onSelect?: (event: Event) => void;
177
+ asChild?: boolean;
178
+ children?: React.ReactNode;
179
+ className?: string;
180
+ }
181
+
182
+ const ContextMenuItem = React.forwardRef<
183
+ React.ElementRef<typeof ContextMenuPrimitive.Item>,
184
+ ContextMenuItemProps
185
+ >(({ className, inset, ...props }, ref) => (
186
+ <ContextMenuPrimitive.Item
187
+ ref={ref}
188
+ className={cn(
189
+ "relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
190
+ inset && "pl-8",
191
+ className,
192
+ )}
193
+ {...props}
194
+ />
195
+ ));
196
+ ContextMenuItem.displayName = ContextMenuPrimitive.Item.displayName;
197
+
198
+ export interface ContextMenuCheckboxItemProps
199
+ extends React.ComponentPropsWithoutRef<typeof ContextMenuPrimitive.CheckboxItem> {
200
+ checked?: boolean | "indeterminate";
201
+ onCheckedChange?: (checked: boolean) => void;
202
+ disabled?: boolean;
203
+ onSelect?: (event: Event) => void;
204
+ asChild?: boolean;
205
+ children?: React.ReactNode;
206
+ className?: string;
207
+ }
208
+
209
+ const ContextMenuCheckboxItem = React.forwardRef<
210
+ React.ElementRef<typeof ContextMenuPrimitive.CheckboxItem>,
211
+ ContextMenuCheckboxItemProps
212
+ >(({ className, children, checked, ...props }, ref) => (
213
+ <ContextMenuPrimitive.CheckboxItem
214
+ ref={ref}
215
+ className={cn(
216
+ "relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
217
+ className,
218
+ )}
219
+ checked={checked}
220
+ {...props}
221
+ >
222
+ <span className="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
223
+ <ContextMenuPrimitive.ItemIndicator>
224
+ <Check className="h-4 w-4" />
225
+ </ContextMenuPrimitive.ItemIndicator>
226
+ </span>
227
+ {children}
228
+ </ContextMenuPrimitive.CheckboxItem>
229
+ ));
230
+ ContextMenuCheckboxItem.displayName = ContextMenuPrimitive.CheckboxItem.displayName;
231
+
232
+ export interface ContextMenuRadioItemProps
233
+ extends React.ComponentPropsWithoutRef<typeof ContextMenuPrimitive.RadioItem> {
234
+ value: string;
235
+ disabled?: boolean;
236
+ onSelect?: (event: Event) => void;
237
+ asChild?: boolean;
238
+ children?: React.ReactNode;
239
+ className?: string;
240
+ }
241
+
242
+ const ContextMenuRadioItem = React.forwardRef<
243
+ React.ElementRef<typeof ContextMenuPrimitive.RadioItem>,
244
+ ContextMenuRadioItemProps
245
+ >(({ className, children, ...props }, ref) => (
246
+ <ContextMenuPrimitive.RadioItem
247
+ ref={ref}
248
+ className={cn(
249
+ "relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
250
+ className,
251
+ )}
252
+ {...props}
253
+ >
254
+ <span className="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
255
+ <ContextMenuPrimitive.ItemIndicator>
256
+ <Circle className="h-4 w-4 fill-current" />
257
+ </ContextMenuPrimitive.ItemIndicator>
258
+ </span>
259
+ {children}
260
+ </ContextMenuPrimitive.RadioItem>
261
+ ));
262
+ ContextMenuRadioItem.displayName = ContextMenuPrimitive.RadioItem.displayName;
263
+
264
+ export interface ContextMenuLabelProps
265
+ extends React.ComponentPropsWithoutRef<typeof ContextMenuPrimitive.Label> {
266
+ inset?: boolean;
267
+ asChild?: boolean;
268
+ children?: React.ReactNode;
269
+ className?: string;
270
+ }
271
+
272
+ const ContextMenuLabel = React.forwardRef<
273
+ React.ElementRef<typeof ContextMenuPrimitive.Label>,
274
+ ContextMenuLabelProps
275
+ >(({ className, inset, ...props }, ref) => (
276
+ <ContextMenuPrimitive.Label
277
+ ref={ref}
278
+ className={cn("px-2 py-1.5 text-sm font-semibold text-foreground", inset && "pl-8", className)}
279
+ {...props}
280
+ />
281
+ ));
282
+ ContextMenuLabel.displayName = ContextMenuPrimitive.Label.displayName;
283
+
284
+ export interface ContextMenuSeparatorProps
285
+ extends React.ComponentPropsWithoutRef<typeof ContextMenuPrimitive.Separator> {
286
+ asChild?: boolean;
287
+ className?: string;
288
+ }
289
+
290
+ const ContextMenuSeparator = React.forwardRef<
291
+ React.ElementRef<typeof ContextMenuPrimitive.Separator>,
292
+ ContextMenuSeparatorProps
293
+ >(({ className, ...props }, ref) => (
294
+ <ContextMenuPrimitive.Separator
295
+ ref={ref}
296
+ className={cn("-mx-1 my-1 h-px bg-border", className)}
297
+ {...props}
298
+ />
299
+ ));
300
+ ContextMenuSeparator.displayName = ContextMenuPrimitive.Separator.displayName;
301
+
302
+ export interface ContextMenuShortcutProps extends React.HTMLAttributes<HTMLSpanElement> {
303
+ children?: React.ReactNode;
304
+ className?: string;
305
+ }
306
+
307
+ const ContextMenuShortcut = ({ className, ...props }: ContextMenuShortcutProps) => {
308
+ return (
309
+ <span
310
+ className={cn("ml-auto text-xs tracking-widest text-muted-foreground", className)}
311
+ {...props}
312
+ />
313
+ );
314
+ };
315
+ ContextMenuShortcut.displayName = "ContextMenuShortcut";
316
+
317
+ export {
318
+ ContextMenu,
319
+ ContextMenuCheckboxItem,
320
+ ContextMenuContent,
321
+ ContextMenuGroup,
322
+ ContextMenuItem,
323
+ ContextMenuLabel,
324
+ ContextMenuPortal,
325
+ ContextMenuRadioGroup,
326
+ ContextMenuRadioItem,
327
+ ContextMenuSeparator,
328
+ ContextMenuShortcut,
329
+ ContextMenuSub,
330
+ ContextMenuSubContent,
331
+ ContextMenuSubTrigger,
332
+ ContextMenuTrigger,
333
+ };