@majapisoftwares/ui 6.1.0 → 6.1.2

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 (73) hide show
  1. package/AGENTS.md +27 -27
  2. package/README.md +79 -79
  3. package/THIRD_PARTY_NOTICES.md +39 -39
  4. package/components.json +25 -25
  5. package/docs/MIGRATION-0.2.md +20 -20
  6. package/docs/MIGRATION-6.0.md +33 -33
  7. package/docs/NEXT-STARTER-VALIDATION.md +14 -14
  8. package/docs/STANDARDS.md +41 -41
  9. package/docs/VALIDATION.md +11 -11
  10. package/docs/VERSIONING.md +28 -28
  11. package/docs/validation/preference-titles.md +22 -0
  12. package/package.json +88 -84
  13. package/scripts/check-standards.mjs +41 -41
  14. package/src/components/ui/accordion.tsx +82 -82
  15. package/src/components/ui/alert-dialog.tsx +187 -187
  16. package/src/components/ui/alert.tsx +77 -77
  17. package/src/components/ui/avatar.tsx +108 -108
  18. package/src/components/ui/badge.tsx +55 -55
  19. package/src/components/ui/breadcrumb.tsx +125 -125
  20. package/src/components/ui/button-group.tsx +89 -89
  21. package/src/components/ui/button.tsx +59 -59
  22. package/src/components/ui/card.tsx +101 -101
  23. package/src/components/ui/checkbox.tsx +27 -27
  24. package/src/components/ui/collapsible.tsx +21 -21
  25. package/src/components/ui/context-menu.tsx +271 -271
  26. package/src/components/ui/dialog.tsx +161 -161
  27. package/src/components/ui/dropdown-menu.tsx +271 -271
  28. package/src/components/ui/empty.tsx +105 -105
  29. package/src/components/ui/field.tsx +238 -238
  30. package/src/components/ui/hover-card.tsx +50 -50
  31. package/src/components/ui/input-group.tsx +155 -155
  32. package/src/components/ui/input.tsx +21 -21
  33. package/src/components/ui/kbd.tsx +28 -28
  34. package/src/components/ui/label.tsx +19 -19
  35. package/src/components/ui/orb.css +1002 -1002
  36. package/src/components/ui/orb.tsx +752 -752
  37. package/src/components/ui/popover.tsx +89 -89
  38. package/src/components/ui/progress.tsx +82 -82
  39. package/src/components/ui/radio-group.tsx +37 -37
  40. package/src/components/ui/scroll-area.tsx +54 -54
  41. package/src/components/ui/select.tsx +204 -204
  42. package/src/components/ui/separator.tsx +24 -24
  43. package/src/components/ui/sheet.tsx +139 -139
  44. package/src/components/ui/sidebar.tsx +1039 -1035
  45. package/src/components/ui/skeleton.tsx +15 -15
  46. package/src/components/ui/slider.tsx +53 -53
  47. package/src/components/ui/sonner.tsx +44 -44
  48. package/src/components/ui/spinner.tsx +32 -32
  49. package/src/components/ui/switch.tsx +31 -31
  50. package/src/components/ui/table.tsx +121 -121
  51. package/src/components/ui/tabs.tsx +81 -81
  52. package/src/components/ui/textarea.tsx +19 -19
  53. package/src/components/ui/toggle-group.tsx +89 -89
  54. package/src/components/ui/toggle.tsx +44 -44
  55. package/src/components/ui/tooltip.tsx +65 -65
  56. package/src/hooks/use-mobile.ts +20 -20
  57. package/src/lib/i18n.tsx +109 -109
  58. package/src/lib/utils.ts +1 -1
  59. package/src/patterns/app-shell.tsx +177 -179
  60. package/src/patterns/data-table.tsx +2486 -2486
  61. package/src/patterns/details-sheet.tsx +54 -54
  62. package/src/patterns/filter-tabs.tsx +53 -53
  63. package/src/patterns/majapi-logo.tsx +32 -32
  64. package/src/patterns/page-header.tsx +62 -62
  65. package/src/patterns/preferences.tsx +15 -7
  66. package/src/patterns/status-badge.tsx +24 -24
  67. package/src/patterns/user-menu.tsx +218 -218
  68. package/src/patterns/workspace-switcher.tsx +176 -173
  69. package/src/styles.css +165 -165
  70. package/src/templates/admin-dashboard.tsx +44 -44
  71. package/src/templates/auth-layout.tsx +30 -30
  72. package/src/templates/login-form.tsx +129 -129
  73. package/src/templates/signup-form.tsx +177 -177
@@ -1,271 +1,271 @@
1
- "use client";
2
-
3
- import * as React from "react";
4
- import { ContextMenu as ContextMenuPrimitive } from "@base-ui/react/context-menu";
5
- import { cn } from "cn";
6
- import { ChevronRightIcon, CheckIcon } from "lucide-react";
7
-
8
- function ContextMenu({ ...props }: ContextMenuPrimitive.Root.Props) {
9
- return <ContextMenuPrimitive.Root data-slot="context-menu" {...props} />;
10
- }
11
-
12
- function ContextMenuPortal({ ...props }: ContextMenuPrimitive.Portal.Props) {
13
- return (
14
- <ContextMenuPrimitive.Portal data-slot="context-menu-portal" {...props} />
15
- );
16
- }
17
-
18
- function ContextMenuTrigger({
19
- className,
20
- ...props
21
- }: ContextMenuPrimitive.Trigger.Props) {
22
- return (
23
- <ContextMenuPrimitive.Trigger
24
- data-slot="context-menu-trigger"
25
- className={cn("select-none", className)}
26
- {...props}
27
- />
28
- );
29
- }
30
-
31
- function ContextMenuContent({
32
- className,
33
- align = "start",
34
- alignOffset = 4,
35
- side = "right",
36
- sideOffset = 0,
37
- ...props
38
- }: ContextMenuPrimitive.Popup.Props &
39
- Pick<
40
- ContextMenuPrimitive.Positioner.Props,
41
- "align" | "alignOffset" | "side" | "sideOffset"
42
- >) {
43
- return (
44
- <ContextMenuPrimitive.Portal>
45
- <ContextMenuPrimitive.Positioner
46
- className="isolate z-50 outline-none"
47
- align={align}
48
- alignOffset={alignOffset}
49
- side={side}
50
- sideOffset={sideOffset}
51
- >
52
- <ContextMenuPrimitive.Popup
53
- data-slot="context-menu-content"
54
- className={cn(
55
- "z-50 max-h-(--available-height) min-w-48 origin-(--transform-origin) overflow-x-hidden overflow-y-auto rounded-3xl bg-popover p-1.5 text-popover-foreground shadow-lg ring-1 ring-foreground/5 duration-100 outline-none data-[side=bottom]:slide-in-from-top-2 data-[side=inline-end]:slide-in-from-left-2 data-[side=inline-start]:slide-in-from-right-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 dark:ring-foreground/10 data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95",
56
- className,
57
- )}
58
- {...props}
59
- />
60
- </ContextMenuPrimitive.Positioner>
61
- </ContextMenuPrimitive.Portal>
62
- );
63
- }
64
-
65
- function ContextMenuGroup({ ...props }: ContextMenuPrimitive.Group.Props) {
66
- return (
67
- <ContextMenuPrimitive.Group data-slot="context-menu-group" {...props} />
68
- );
69
- }
70
-
71
- function ContextMenuLabel({
72
- className,
73
- inset,
74
- ...props
75
- }: ContextMenuPrimitive.GroupLabel.Props & {
76
- inset?: boolean;
77
- }) {
78
- return (
79
- <ContextMenuPrimitive.GroupLabel
80
- data-slot="context-menu-label"
81
- data-inset={inset}
82
- className={cn(
83
- "px-3 py-2.5 text-xs text-muted-foreground data-inset:pl-9.5",
84
- className,
85
- )}
86
- {...props}
87
- />
88
- );
89
- }
90
-
91
- function ContextMenuItem({
92
- className,
93
- inset,
94
- variant = "default",
95
- ...props
96
- }: ContextMenuPrimitive.Item.Props & {
97
- inset?: boolean;
98
- variant?: "default" | "destructive";
99
- }) {
100
- return (
101
- <ContextMenuPrimitive.Item
102
- data-slot="context-menu-item"
103
- data-inset={inset}
104
- data-variant={variant}
105
- className={cn(
106
- "group/context-menu-item relative flex cursor-default items-center gap-2.5 rounded-2xl px-3 py-2 text-sm font-medium outline-hidden select-none focus:bg-accent focus:text-accent-foreground data-inset:pl-9.5 data-[variant=destructive]:text-destructive data-[variant=destructive]:focus:bg-destructive/10 data-[variant=destructive]:focus:text-destructive dark:data-[variant=destructive]:focus:bg-destructive/20 data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 focus:*:[svg]:text-accent-foreground data-[variant=destructive]:*:[svg]:text-destructive",
107
- className,
108
- )}
109
- {...props}
110
- />
111
- );
112
- }
113
-
114
- function ContextMenuSub({ ...props }: ContextMenuPrimitive.SubmenuRoot.Props) {
115
- return (
116
- <ContextMenuPrimitive.SubmenuRoot data-slot="context-menu-sub" {...props} />
117
- );
118
- }
119
-
120
- function ContextMenuSubTrigger({
121
- className,
122
- inset,
123
- children,
124
- ...props
125
- }: ContextMenuPrimitive.SubmenuTrigger.Props & {
126
- inset?: boolean;
127
- }) {
128
- return (
129
- <ContextMenuPrimitive.SubmenuTrigger
130
- data-slot="context-menu-sub-trigger"
131
- data-inset={inset}
132
- className={cn(
133
- "flex cursor-default items-center rounded-2xl px-3 py-2 text-sm font-medium outline-hidden select-none focus:bg-accent focus:text-accent-foreground data-inset:pl-9.5 data-open:bg-accent data-open:text-accent-foreground [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
134
- className,
135
- )}
136
- {...props}
137
- >
138
- {children}
139
- <ChevronRightIcon className="ml-auto" />
140
- </ContextMenuPrimitive.SubmenuTrigger>
141
- );
142
- }
143
-
144
- function ContextMenuSubContent({
145
- ...props
146
- }: React.ComponentProps<typeof ContextMenuContent>) {
147
- return (
148
- <ContextMenuContent
149
- data-slot="context-menu-sub-content"
150
- className="shadow-lg"
151
- side="right"
152
- {...props}
153
- />
154
- );
155
- }
156
-
157
- function ContextMenuCheckboxItem({
158
- className,
159
- children,
160
- checked,
161
- inset,
162
- ...props
163
- }: ContextMenuPrimitive.CheckboxItem.Props & {
164
- inset?: boolean;
165
- }) {
166
- return (
167
- <ContextMenuPrimitive.CheckboxItem
168
- data-slot="context-menu-checkbox-item"
169
- data-inset={inset}
170
- className={cn(
171
- "relative flex cursor-default items-center gap-2.5 rounded-2xl py-2 pr-8 pl-3 text-sm font-medium outline-hidden select-none focus:bg-accent focus:text-accent-foreground data-inset:pl-9.5 data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
172
- className,
173
- )}
174
- checked={checked}
175
- {...props}
176
- >
177
- <span className="pointer-events-none absolute right-2">
178
- <ContextMenuPrimitive.CheckboxItemIndicator>
179
- <CheckIcon />
180
- </ContextMenuPrimitive.CheckboxItemIndicator>
181
- </span>
182
- {children}
183
- </ContextMenuPrimitive.CheckboxItem>
184
- );
185
- }
186
-
187
- function ContextMenuRadioGroup({
188
- ...props
189
- }: ContextMenuPrimitive.RadioGroup.Props) {
190
- return (
191
- <ContextMenuPrimitive.RadioGroup
192
- data-slot="context-menu-radio-group"
193
- {...props}
194
- />
195
- );
196
- }
197
-
198
- function ContextMenuRadioItem({
199
- className,
200
- children,
201
- inset,
202
- ...props
203
- }: ContextMenuPrimitive.RadioItem.Props & {
204
- inset?: boolean;
205
- }) {
206
- return (
207
- <ContextMenuPrimitive.RadioItem
208
- data-slot="context-menu-radio-item"
209
- data-inset={inset}
210
- className={cn(
211
- "relative flex cursor-default items-center gap-2.5 rounded-2xl py-2 pr-8 pl-3 text-sm font-medium outline-hidden select-none focus:bg-accent focus:text-accent-foreground data-inset:pl-9.5 data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
212
- className,
213
- )}
214
- {...props}
215
- >
216
- <span className="pointer-events-none absolute right-2">
217
- <ContextMenuPrimitive.RadioItemIndicator>
218
- <CheckIcon />
219
- </ContextMenuPrimitive.RadioItemIndicator>
220
- </span>
221
- {children}
222
- </ContextMenuPrimitive.RadioItem>
223
- );
224
- }
225
-
226
- function ContextMenuSeparator({
227
- className,
228
- ...props
229
- }: ContextMenuPrimitive.Separator.Props) {
230
- return (
231
- <ContextMenuPrimitive.Separator
232
- data-slot="context-menu-separator"
233
- className={cn("-mx-1.5 my-1.5 h-px bg-border/50", className)}
234
- {...props}
235
- />
236
- );
237
- }
238
-
239
- function ContextMenuShortcut({
240
- className,
241
- ...props
242
- }: React.ComponentProps<"span">) {
243
- return (
244
- <span
245
- data-slot="context-menu-shortcut"
246
- className={cn(
247
- "ml-auto text-xs tracking-widest text-muted-foreground group-focus/context-menu-item:text-accent-foreground",
248
- className,
249
- )}
250
- {...props}
251
- />
252
- );
253
- }
254
-
255
- export {
256
- ContextMenu,
257
- ContextMenuTrigger,
258
- ContextMenuContent,
259
- ContextMenuItem,
260
- ContextMenuCheckboxItem,
261
- ContextMenuRadioItem,
262
- ContextMenuLabel,
263
- ContextMenuSeparator,
264
- ContextMenuShortcut,
265
- ContextMenuGroup,
266
- ContextMenuPortal,
267
- ContextMenuSub,
268
- ContextMenuSubContent,
269
- ContextMenuSubTrigger,
270
- ContextMenuRadioGroup,
271
- };
1
+ "use client";
2
+
3
+ import * as React from "react";
4
+ import { ContextMenu as ContextMenuPrimitive } from "@base-ui/react/context-menu";
5
+ import { cn } from "cn";
6
+ import { ChevronRightIcon, CheckIcon } from "lucide-react";
7
+
8
+ function ContextMenu({ ...props }: ContextMenuPrimitive.Root.Props) {
9
+ return <ContextMenuPrimitive.Root data-slot="context-menu" {...props} />;
10
+ }
11
+
12
+ function ContextMenuPortal({ ...props }: ContextMenuPrimitive.Portal.Props) {
13
+ return (
14
+ <ContextMenuPrimitive.Portal data-slot="context-menu-portal" {...props} />
15
+ );
16
+ }
17
+
18
+ function ContextMenuTrigger({
19
+ className,
20
+ ...props
21
+ }: ContextMenuPrimitive.Trigger.Props) {
22
+ return (
23
+ <ContextMenuPrimitive.Trigger
24
+ data-slot="context-menu-trigger"
25
+ className={cn("select-none", className)}
26
+ {...props}
27
+ />
28
+ );
29
+ }
30
+
31
+ function ContextMenuContent({
32
+ className,
33
+ align = "start",
34
+ alignOffset = 4,
35
+ side = "right",
36
+ sideOffset = 0,
37
+ ...props
38
+ }: ContextMenuPrimitive.Popup.Props &
39
+ Pick<
40
+ ContextMenuPrimitive.Positioner.Props,
41
+ "align" | "alignOffset" | "side" | "sideOffset"
42
+ >) {
43
+ return (
44
+ <ContextMenuPrimitive.Portal>
45
+ <ContextMenuPrimitive.Positioner
46
+ className="isolate z-50 outline-none"
47
+ align={align}
48
+ alignOffset={alignOffset}
49
+ side={side}
50
+ sideOffset={sideOffset}
51
+ >
52
+ <ContextMenuPrimitive.Popup
53
+ data-slot="context-menu-content"
54
+ className={cn(
55
+ "z-50 max-h-(--available-height) min-w-48 origin-(--transform-origin) overflow-x-hidden overflow-y-auto rounded-3xl bg-popover p-1.5 text-popover-foreground shadow-lg ring-1 ring-foreground/5 duration-100 outline-none data-[side=bottom]:slide-in-from-top-2 data-[side=inline-end]:slide-in-from-left-2 data-[side=inline-start]:slide-in-from-right-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 dark:ring-foreground/10 data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95",
56
+ className,
57
+ )}
58
+ {...props}
59
+ />
60
+ </ContextMenuPrimitive.Positioner>
61
+ </ContextMenuPrimitive.Portal>
62
+ );
63
+ }
64
+
65
+ function ContextMenuGroup({ ...props }: ContextMenuPrimitive.Group.Props) {
66
+ return (
67
+ <ContextMenuPrimitive.Group data-slot="context-menu-group" {...props} />
68
+ );
69
+ }
70
+
71
+ function ContextMenuLabel({
72
+ className,
73
+ inset,
74
+ ...props
75
+ }: ContextMenuPrimitive.GroupLabel.Props & {
76
+ inset?: boolean;
77
+ }) {
78
+ return (
79
+ <ContextMenuPrimitive.GroupLabel
80
+ data-slot="context-menu-label"
81
+ data-inset={inset}
82
+ className={cn(
83
+ "px-3 py-2.5 text-xs text-muted-foreground data-inset:pl-9.5",
84
+ className,
85
+ )}
86
+ {...props}
87
+ />
88
+ );
89
+ }
90
+
91
+ function ContextMenuItem({
92
+ className,
93
+ inset,
94
+ variant = "default",
95
+ ...props
96
+ }: ContextMenuPrimitive.Item.Props & {
97
+ inset?: boolean;
98
+ variant?: "default" | "destructive";
99
+ }) {
100
+ return (
101
+ <ContextMenuPrimitive.Item
102
+ data-slot="context-menu-item"
103
+ data-inset={inset}
104
+ data-variant={variant}
105
+ className={cn(
106
+ "group/context-menu-item relative flex cursor-default items-center gap-2.5 rounded-2xl px-3 py-2 text-sm font-medium outline-hidden select-none focus:bg-accent focus:text-accent-foreground data-inset:pl-9.5 data-[variant=destructive]:text-destructive data-[variant=destructive]:focus:bg-destructive/10 data-[variant=destructive]:focus:text-destructive dark:data-[variant=destructive]:focus:bg-destructive/20 data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 focus:*:[svg]:text-accent-foreground data-[variant=destructive]:*:[svg]:text-destructive",
107
+ className,
108
+ )}
109
+ {...props}
110
+ />
111
+ );
112
+ }
113
+
114
+ function ContextMenuSub({ ...props }: ContextMenuPrimitive.SubmenuRoot.Props) {
115
+ return (
116
+ <ContextMenuPrimitive.SubmenuRoot data-slot="context-menu-sub" {...props} />
117
+ );
118
+ }
119
+
120
+ function ContextMenuSubTrigger({
121
+ className,
122
+ inset,
123
+ children,
124
+ ...props
125
+ }: ContextMenuPrimitive.SubmenuTrigger.Props & {
126
+ inset?: boolean;
127
+ }) {
128
+ return (
129
+ <ContextMenuPrimitive.SubmenuTrigger
130
+ data-slot="context-menu-sub-trigger"
131
+ data-inset={inset}
132
+ className={cn(
133
+ "flex cursor-default items-center rounded-2xl px-3 py-2 text-sm font-medium outline-hidden select-none focus:bg-accent focus:text-accent-foreground data-inset:pl-9.5 data-open:bg-accent data-open:text-accent-foreground [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
134
+ className,
135
+ )}
136
+ {...props}
137
+ >
138
+ {children}
139
+ <ChevronRightIcon className="ml-auto" />
140
+ </ContextMenuPrimitive.SubmenuTrigger>
141
+ );
142
+ }
143
+
144
+ function ContextMenuSubContent({
145
+ ...props
146
+ }: React.ComponentProps<typeof ContextMenuContent>) {
147
+ return (
148
+ <ContextMenuContent
149
+ data-slot="context-menu-sub-content"
150
+ className="shadow-lg"
151
+ side="right"
152
+ {...props}
153
+ />
154
+ );
155
+ }
156
+
157
+ function ContextMenuCheckboxItem({
158
+ className,
159
+ children,
160
+ checked,
161
+ inset,
162
+ ...props
163
+ }: ContextMenuPrimitive.CheckboxItem.Props & {
164
+ inset?: boolean;
165
+ }) {
166
+ return (
167
+ <ContextMenuPrimitive.CheckboxItem
168
+ data-slot="context-menu-checkbox-item"
169
+ data-inset={inset}
170
+ className={cn(
171
+ "relative flex cursor-default items-center gap-2.5 rounded-2xl py-2 pr-8 pl-3 text-sm font-medium outline-hidden select-none focus:bg-accent focus:text-accent-foreground data-inset:pl-9.5 data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
172
+ className,
173
+ )}
174
+ checked={checked}
175
+ {...props}
176
+ >
177
+ <span className="pointer-events-none absolute right-2">
178
+ <ContextMenuPrimitive.CheckboxItemIndicator>
179
+ <CheckIcon />
180
+ </ContextMenuPrimitive.CheckboxItemIndicator>
181
+ </span>
182
+ {children}
183
+ </ContextMenuPrimitive.CheckboxItem>
184
+ );
185
+ }
186
+
187
+ function ContextMenuRadioGroup({
188
+ ...props
189
+ }: ContextMenuPrimitive.RadioGroup.Props) {
190
+ return (
191
+ <ContextMenuPrimitive.RadioGroup
192
+ data-slot="context-menu-radio-group"
193
+ {...props}
194
+ />
195
+ );
196
+ }
197
+
198
+ function ContextMenuRadioItem({
199
+ className,
200
+ children,
201
+ inset,
202
+ ...props
203
+ }: ContextMenuPrimitive.RadioItem.Props & {
204
+ inset?: boolean;
205
+ }) {
206
+ return (
207
+ <ContextMenuPrimitive.RadioItem
208
+ data-slot="context-menu-radio-item"
209
+ data-inset={inset}
210
+ className={cn(
211
+ "relative flex cursor-default items-center gap-2.5 rounded-2xl py-2 pr-8 pl-3 text-sm font-medium outline-hidden select-none focus:bg-accent focus:text-accent-foreground data-inset:pl-9.5 data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
212
+ className,
213
+ )}
214
+ {...props}
215
+ >
216
+ <span className="pointer-events-none absolute right-2">
217
+ <ContextMenuPrimitive.RadioItemIndicator>
218
+ <CheckIcon />
219
+ </ContextMenuPrimitive.RadioItemIndicator>
220
+ </span>
221
+ {children}
222
+ </ContextMenuPrimitive.RadioItem>
223
+ );
224
+ }
225
+
226
+ function ContextMenuSeparator({
227
+ className,
228
+ ...props
229
+ }: ContextMenuPrimitive.Separator.Props) {
230
+ return (
231
+ <ContextMenuPrimitive.Separator
232
+ data-slot="context-menu-separator"
233
+ className={cn("-mx-1.5 my-1.5 h-px bg-border/50", className)}
234
+ {...props}
235
+ />
236
+ );
237
+ }
238
+
239
+ function ContextMenuShortcut({
240
+ className,
241
+ ...props
242
+ }: React.ComponentProps<"span">) {
243
+ return (
244
+ <span
245
+ data-slot="context-menu-shortcut"
246
+ className={cn(
247
+ "ml-auto text-xs tracking-widest text-muted-foreground group-focus/context-menu-item:text-accent-foreground",
248
+ className,
249
+ )}
250
+ {...props}
251
+ />
252
+ );
253
+ }
254
+
255
+ export {
256
+ ContextMenu,
257
+ ContextMenuTrigger,
258
+ ContextMenuContent,
259
+ ContextMenuItem,
260
+ ContextMenuCheckboxItem,
261
+ ContextMenuRadioItem,
262
+ ContextMenuLabel,
263
+ ContextMenuSeparator,
264
+ ContextMenuShortcut,
265
+ ContextMenuGroup,
266
+ ContextMenuPortal,
267
+ ContextMenuSub,
268
+ ContextMenuSubContent,
269
+ ContextMenuSubTrigger,
270
+ ContextMenuRadioGroup,
271
+ };