@boxcustodia/library 2.0.0-alpha.13 → 2.0.0-alpha.14

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 (173) hide show
  1. package/dist/index.cjs.js +1 -138
  2. package/dist/index.d.ts +1083 -715
  3. package/dist/index.es.js +7077 -56175
  4. package/dist/theme.css +1 -1
  5. package/package.json +34 -26
  6. package/src/__doc__/Examples.tsx +1 -1
  7. package/src/__doc__/Intro.mdx +3 -3
  8. package/src/__doc__/Tabs.mdx +112 -0
  9. package/src/__doc__/V2.mdx +1246 -0
  10. package/src/components/accordion/accordion.stories.tsx +143 -0
  11. package/src/components/accordion/accordion.tsx +135 -0
  12. package/src/components/accordion/index.ts +1 -0
  13. package/src/components/alert/alert.stories.tsx +24 -4
  14. package/src/components/alert/alert.tsx +17 -9
  15. package/src/components/alert-dialog/alert-dialog.stories.tsx +24 -0
  16. package/src/components/alert-dialog/alert-dialog.test.tsx +1 -1
  17. package/src/components/alert-dialog/alert-dialog.tsx +58 -10
  18. package/src/components/auto-complete/auto-complete.stories.tsx +616 -200
  19. package/src/components/auto-complete/auto-complete.tsx +420 -68
  20. package/src/components/auto-complete/index.ts +0 -1
  21. package/src/components/avatar/avatar.stories.tsx +162 -21
  22. package/src/components/avatar/avatar.tsx +79 -20
  23. package/src/components/button/button.stories.tsx +219 -294
  24. package/src/components/button/button.test.tsx +10 -17
  25. package/src/components/button/button.tsx +78 -19
  26. package/src/components/button/components/base-button.tsx +30 -53
  27. package/src/components/button/index.ts +0 -1
  28. package/src/components/calendar/calendar.stories.tsx +1 -1
  29. package/src/components/calendar/calendar.tsx +4 -4
  30. package/src/components/card/card.stories.tsx +141 -69
  31. package/src/components/card/card.tsx +155 -54
  32. package/src/components/center/center.stories.tsx +22 -39
  33. package/src/components/checkbox/checkbox.stories.tsx +25 -5
  34. package/src/components/checkbox/checkbox.tsx +76 -15
  35. package/src/components/checkbox-group/checkbox-group.stories.tsx +116 -28
  36. package/src/components/checkbox-group/checkbox-group.tsx +84 -3
  37. package/src/components/combobox/combobox.stories.tsx +33 -23
  38. package/src/components/combobox/combobox.tsx +119 -103
  39. package/src/components/date-picker/date-input.stories.tsx +14 -6
  40. package/src/components/date-picker/date-input.tsx +2 -2
  41. package/src/components/date-picker/date-picker.model.ts +13 -4
  42. package/src/components/date-picker/date-picker.stories.tsx +38 -12
  43. package/src/components/date-picker/date-picker.tsx +28 -14
  44. package/src/components/dialog/dialog.stories.tsx +18 -0
  45. package/src/components/dialog/dialog.test.tsx +1 -1
  46. package/src/components/dialog/dialog.tsx +51 -20
  47. package/src/components/divider/divider.stories.tsx +6 -0
  48. package/src/components/dropzone/dropzone.stories.tsx +71 -90
  49. package/src/components/dropzone/dropzone.tsx +383 -105
  50. package/src/components/dropzone/index.ts +0 -1
  51. package/src/components/empty/empty.stories.tsx +165 -0
  52. package/src/components/empty/empty.tsx +156 -0
  53. package/src/components/empty/index.ts +1 -0
  54. package/src/components/field/field.stories.tsx +226 -3
  55. package/src/components/field/field.tsx +77 -42
  56. package/src/components/form/form.stories.tsx +320 -197
  57. package/src/components/form/form.tsx +3 -23
  58. package/src/components/index.ts +2 -6
  59. package/src/components/input/input.stories.tsx +5 -5
  60. package/src/components/input/input.tsx +4 -4
  61. package/src/components/kbd/kbd.stories.tsx +1 -0
  62. package/src/components/label/label.stories.tsx +16 -0
  63. package/src/components/label/label.tsx +13 -2
  64. package/src/components/loader/loader.stories.tsx +7 -5
  65. package/src/components/loader/loader.tsx +8 -3
  66. package/src/components/menu/menu-primitives.tsx +207 -196
  67. package/src/components/menu/menu.stories.tsx +276 -146
  68. package/src/components/menu/menu.tsx +146 -54
  69. package/src/components/number-input/number-input.stories.tsx +27 -4
  70. package/src/components/number-input/number-input.test.tsx +2 -2
  71. package/src/components/number-input/number-input.tsx +25 -29
  72. package/src/components/otp/index.ts +1 -0
  73. package/src/components/otp/otp.stories.tsx +209 -0
  74. package/src/components/otp/otp.tsx +100 -0
  75. package/src/components/pagination/index.ts +1 -0
  76. package/src/components/pagination/pagination.model.ts +2 -0
  77. package/src/components/pagination/pagination.stories.tsx +154 -59
  78. package/src/components/pagination/pagination.test.tsx +122 -57
  79. package/src/components/pagination/pagination.tsx +575 -77
  80. package/src/components/password/password.stories.tsx +18 -3
  81. package/src/components/password/password.tsx +26 -10
  82. package/src/components/popover/popover.stories.tsx +26 -5
  83. package/src/components/popover/popover.tsx +15 -23
  84. package/src/components/progress/progress.stories.tsx +1 -0
  85. package/src/components/radio-group/index.ts +1 -0
  86. package/src/components/radio-group/radio-group.stories.tsx +251 -0
  87. package/src/components/radio-group/radio-group.tsx +212 -0
  88. package/src/components/scroll-area/scroll-area.stories.tsx +1 -0
  89. package/src/components/select/select.stories.tsx +118 -19
  90. package/src/components/select/select.tsx +67 -62
  91. package/src/components/skeleton/skeleton.stories.tsx +1 -0
  92. package/src/components/stack/stack.stories.tsx +179 -89
  93. package/src/components/stack/stack.tsx +2 -2
  94. package/src/components/stepper/index.ts +1 -1
  95. package/src/components/stepper/stepper.stories.tsx +767 -83
  96. package/src/components/stepper/stepper.test.tsx +18 -18
  97. package/src/components/stepper/stepper.tsx +554 -0
  98. package/src/components/switch/switch.stories.tsx +15 -1
  99. package/src/components/switch/switch.tsx +17 -4
  100. package/src/components/table/index.ts +0 -2
  101. package/src/components/table/table.stories.tsx +131 -18
  102. package/src/components/table/table.test.tsx +1 -1
  103. package/src/components/table/table.tsx +183 -77
  104. package/src/components/tabs/tabs.stories.tsx +373 -155
  105. package/src/components/tabs/tabs.test.tsx +12 -12
  106. package/src/components/tabs/tabs.tsx +72 -149
  107. package/src/components/tag/index.ts +0 -1
  108. package/src/components/tag/tag.stories.tsx +155 -120
  109. package/src/components/tag/tag.tsx +47 -95
  110. package/src/components/textarea/textarea.stories.tsx +8 -22
  111. package/src/components/textarea/textarea.tsx +17 -79
  112. package/src/components/timeline/timeline.stories.tsx +323 -42
  113. package/src/components/timeline/timeline.tsx +359 -132
  114. package/src/components/toast/toast.stories.tsx +1 -0
  115. package/src/components/tooltip/tooltip.tsx +11 -9
  116. package/src/components/tree/index.ts +0 -1
  117. package/src/components/tree/tree.stories.tsx +365 -408
  118. package/src/components/tree/tree.test.tsx +163 -0
  119. package/src/components/tree/tree.tsx +212 -36
  120. package/src/hooks/useAsync/__doc__/useAsync.stories.tsx +5 -5
  121. package/src/hooks/useClipboard/__doc__/useClipboard.stories.tsx +1 -3
  122. package/src/hooks/useDebounceCallback/__doc__/useDebouncedCallback.stories.tsx +6 -6
  123. package/src/hooks/useDocumentTitle/__doc__/useDocumentTitle.stories.tsx +1 -1
  124. package/src/hooks/useEventListener/__test__/useEventListener.test.tsx +1 -1
  125. package/src/hooks/useLocalStorage/__doc__/useLocalStorage.stories.tsx +1 -1
  126. package/src/hooks/usePagination/usePagination.tsx +36 -24
  127. package/src/styles/theme.css +1 -1
  128. package/src/utils/form.tsx +67 -37
  129. package/src/utils/index.ts +1 -1
  130. package/src/__doc__/Migration.mdx +0 -451
  131. package/src/components/auto-complete/auto-complete-primitives.tsx +0 -155
  132. package/src/components/background-image/background-image.stories.tsx +0 -21
  133. package/src/components/background-image/background-image.test.tsx +0 -29
  134. package/src/components/background-image/background-image.tsx +0 -23
  135. package/src/components/background-image/index.ts +0 -1
  136. package/src/components/button/button.variants.ts +0 -44
  137. package/src/components/button/components/loader-overlay.tsx +0 -21
  138. package/src/components/button/components/loading-icon.tsx +0 -47
  139. package/src/components/dropzone/upload-primitives.tsx +0 -310
  140. package/src/components/dropzone/use-dropzone.ts +0 -122
  141. package/src/components/empty-state/empty-state.stories.tsx +0 -56
  142. package/src/components/empty-state/empty-state.tsx +0 -39
  143. package/src/components/empty-state/index.ts +0 -1
  144. package/src/components/heading/heading.stories.tsx +0 -74
  145. package/src/components/heading/heading.tsx +0 -28
  146. package/src/components/heading/heading.variants.ts +0 -27
  147. package/src/components/heading/index.ts +0 -1
  148. package/src/components/kbd/kbd.variants.ts +0 -26
  149. package/src/components/menu/util/render-menu-item.tsx +0 -54
  150. package/src/components/multi-select/hooks/use-multi-select.ts +0 -66
  151. package/src/components/multi-select/index.ts +0 -1
  152. package/src/components/multi-select/multi-select.stories.tsx +0 -294
  153. package/src/components/multi-select/multi-select.tsx +0 -300
  154. package/src/components/multi-select/multi-select.variants.ts +0 -22
  155. package/src/components/pagination/components/pagination-option.tsx +0 -27
  156. package/src/components/show/index.ts +0 -1
  157. package/src/components/show/show.stories.tsx +0 -197
  158. package/src/components/show/show.test.tsx +0 -41
  159. package/src/components/show/show.tsx +0 -16
  160. package/src/components/stepper/Stepper.tsx +0 -190
  161. package/src/components/stepper/context/stepper-context.tsx +0 -11
  162. package/src/components/table/table-primitives.tsx +0 -122
  163. package/src/components/table/table.model.ts +0 -20
  164. package/src/components/table-pagination/index.ts +0 -2
  165. package/src/components/table-pagination/table-pagination.model.ts +0 -2
  166. package/src/components/table-pagination/table-pagination.stories.tsx +0 -23
  167. package/src/components/table-pagination/table-pagination.test.tsx +0 -32
  168. package/src/components/table-pagination/table-pagination.tsx +0 -108
  169. package/src/components/tabs/context/tabs-context.tsx +0 -14
  170. package/src/components/tag/tag.variants.ts +0 -31
  171. package/src/components/timeline/timeline-status.ts +0 -5
  172. package/src/components/tree/hooks/use-controllable-tree-state.ts +0 -80
  173. package/src/components/tree/tree-primitives.tsx +0 -126
@@ -1,248 +1,259 @@
1
- import * as DropdownMenuPrimitive from "@radix-ui/react-dropdown-menu";
2
- import { Check, ChevronRight, Circle } from "lucide-react";
1
+ "use client";
2
+ import { Menu as MenuPrimitive } from "@base-ui/react/menu";
3
+ import { CheckIcon, ChevronRightIcon } from "lucide-react";
3
4
  import * as React from "react";
4
- import { useHotkey } from "../../hooks";
5
- import { HotkeyOptions, Keys } from "../../hooks/useHotkey/useHotkey";
6
5
  import { cn } from "../../lib";
7
6
 
8
- const MenuRoot = (
9
- props: React.ComponentProps<typeof DropdownMenuPrimitive.Root>,
10
- ) => {
11
- return <DropdownMenuPrimitive.Root data-slot="menu" {...props} />;
12
- };
7
+ function MenuRoot({ ...props }: MenuPrimitive.Root.Props) {
8
+ return <MenuPrimitive.Root data-slot="menu" {...props} />;
9
+ }
13
10
 
14
- const MenuTrigger = (
15
- props: React.ComponentProps<typeof DropdownMenuPrimitive.Trigger>,
16
- ) => {
17
- return <DropdownMenuPrimitive.Trigger data-slot="menu-trigger" {...props} />;
18
- };
11
+ function MenuPortal({ ...props }: MenuPrimitive.Portal.Props) {
12
+ return <MenuPrimitive.Portal data-slot="menu-portal" {...props} />;
13
+ }
19
14
 
20
- const MenuGroup = (
21
- props: React.ComponentProps<typeof DropdownMenuPrimitive.Group>,
22
- ) => {
23
- return <DropdownMenuPrimitive.Group data-slot="menu-group" {...props} />;
24
- };
15
+ function MenuTrigger({ ...props }: MenuPrimitive.Trigger.Props) {
16
+ return <MenuPrimitive.Trigger data-slot="menu-trigger" {...props} />;
17
+ }
25
18
 
26
- const MenuPortal = (
27
- props: React.ComponentProps<typeof DropdownMenuPrimitive.Portal>,
28
- ) => {
29
- return <DropdownMenuPrimitive.Portal data-slot="menu-portal" {...props} />;
30
- };
19
+ function MenuPopup({
20
+ align = "start",
21
+ alignOffset = 0,
22
+ side = "bottom",
23
+ sideOffset = 4,
24
+ className,
25
+ ...props
26
+ }: MenuPrimitive.Popup.Props &
27
+ Pick<
28
+ MenuPrimitive.Positioner.Props,
29
+ "align" | "alignOffset" | "side" | "sideOffset"
30
+ >) {
31
+ return (
32
+ <MenuPrimitive.Portal>
33
+ <MenuPrimitive.Positioner
34
+ className="isolate z-50 outline-none"
35
+ align={align}
36
+ alignOffset={alignOffset}
37
+ side={side}
38
+ sideOffset={sideOffset}
39
+ >
40
+ <MenuPrimitive.Popup
41
+ data-slot="menu-content"
42
+ className={cn(
43
+ "z-50 max-h-(--available-height) w-(--anchor-width) min-w-32 origin-(--transform-origin) overflow-x-hidden overflow-y-auto rounded-lg bg-popover p-1 text-popover-foreground shadow-md ring-1 ring-foreground/10 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 data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:overflow-hidden data-closed:fade-out-0 data-closed:zoom-out-95",
44
+ className,
45
+ )}
46
+ {...props}
47
+ />
48
+ </MenuPrimitive.Positioner>
49
+ </MenuPrimitive.Portal>
50
+ );
51
+ }
31
52
 
32
- const MenuSub = (
33
- props: React.ComponentProps<typeof DropdownMenuPrimitive.Sub>,
34
- ) => {
35
- return <DropdownMenuPrimitive.Sub data-slot="menu-sub" {...props} />;
36
- };
53
+ function MenuGroup({ ...props }: MenuPrimitive.Group.Props) {
54
+ return <MenuPrimitive.Group data-slot="menu-group" {...props} />;
55
+ }
37
56
 
38
- const MenuRadioGroup = (
39
- props: React.ComponentProps<typeof DropdownMenuPrimitive.RadioGroup>,
40
- ) => {
57
+ function MenuLabel({
58
+ className,
59
+ inset,
60
+ ...props
61
+ }: MenuPrimitive.GroupLabel.Props & {
62
+ inset?: boolean;
63
+ }) {
41
64
  return (
42
- <DropdownMenuPrimitive.RadioGroup data-slot="menu-radio-group" {...props} />
65
+ <MenuPrimitive.GroupLabel
66
+ data-slot="menu-label"
67
+ data-inset={inset}
68
+ className={cn(
69
+ "px-1.5 py-1 text-xs font-medium text-muted-foreground data-inset:pl-7",
70
+ className,
71
+ )}
72
+ {...props}
73
+ />
43
74
  );
44
- };
75
+ }
45
76
 
46
- type MenuSubTriggerProps = React.ComponentProps<
47
- typeof DropdownMenuPrimitive.SubTrigger
48
- > & {
77
+ function MenuItem({
78
+ className,
79
+ inset,
80
+ variant = "default",
81
+ ...props
82
+ }: MenuPrimitive.Item.Props & {
49
83
  inset?: boolean;
50
- };
84
+ variant?: "default" | "error";
85
+ }) {
86
+ return (
87
+ <MenuPrimitive.Item
88
+ data-slot="menu-item"
89
+ data-inset={inset}
90
+ data-variant={variant}
91
+ className={cn(
92
+ "group/menu-item relative flex cursor-default items-center gap-1.5 rounded-md px-1.5 py-1 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground not-data-[variant=error]:focus:**:text-accent-foreground data-inset:pl-7 data-[variant=error]:text-error data-[variant=error]:focus:bg-error/10 data-[variant=error]:focus:text-error dark:data-[variant=error]:focus:bg-error/20 data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 data-[variant=error]:*:[svg]:text-error",
93
+ className,
94
+ )}
95
+ {...props}
96
+ />
97
+ );
98
+ }
99
+
100
+ function MenuSub({ ...props }: MenuPrimitive.SubmenuRoot.Props) {
101
+ return <MenuPrimitive.SubmenuRoot data-slot="menu-sub" {...props} />;
102
+ }
51
103
 
52
- const MenuSubTrigger = ({
104
+ function MenuSubTrigger({
53
105
  className,
54
106
  inset,
55
107
  children,
56
108
  ...props
57
- }: MenuSubTriggerProps) => (
58
- <DropdownMenuPrimitive.SubTrigger
59
- data-slot="menu-sub-trigger"
60
- className={cn(
61
- "flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none focus:bg-accent data-[state='open']:bg-accent",
62
- inset && "pl-8",
63
- className,
64
- )}
65
- {...props}
66
- >
67
- {children}
68
- <ChevronRight className="ml-auto h-4 w-4" />
69
- </DropdownMenuPrimitive.SubTrigger>
70
- );
71
-
72
- type MenuSubContentProps = React.ComponentProps<
73
- typeof DropdownMenuPrimitive.SubContent
74
- >;
75
-
76
- const MenuSubContent = ({ className, ...props }: MenuSubContentProps) => (
77
- <DropdownMenuPrimitive.SubContent
78
- data-slot="menu-sub-content"
79
- className={cn(
80
- "z-float 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",
81
- className,
82
- )}
83
- {...props}
84
- />
85
- );
86
-
87
- type MenuContentProps = React.ComponentProps<
88
- typeof DropdownMenuPrimitive.Content
89
- >;
90
-
91
- const MenuContent = ({
109
+ }: MenuPrimitive.SubmenuTrigger.Props & {
110
+ inset?: boolean;
111
+ }) {
112
+ return (
113
+ <MenuPrimitive.SubmenuTrigger
114
+ data-slot="menu-sub-trigger"
115
+ data-inset={inset}
116
+ className={cn(
117
+ "flex cursor-default items-center gap-1.5 rounded-md px-1.5 py-1 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground not-data-[variant=error]:focus:**:text-accent-foreground data-inset:pl-7 data-popup-open:bg-accent data-popup-open:text-accent-foreground data-open:bg-accent data-open:text-accent-foreground [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
118
+ className,
119
+ )}
120
+ {...props}
121
+ >
122
+ {children}
123
+ <ChevronRightIcon className="cn-rtl-flip ml-auto" />
124
+ </MenuPrimitive.SubmenuTrigger>
125
+ );
126
+ }
127
+
128
+ function MenuSubContent({
129
+ align = "start",
130
+ alignOffset = -3,
131
+ side = "right",
132
+ sideOffset = 0,
92
133
  className,
93
- sideOffset = 4,
94
134
  ...props
95
- }: MenuContentProps) => (
96
- <DropdownMenuPrimitive.Portal data-slot="menu-portal">
97
- <DropdownMenuPrimitive.Content
98
- data-slot="menu-content"
99
- sideOffset={sideOffset}
135
+ }: React.ComponentProps<typeof MenuPopup>) {
136
+ return (
137
+ <MenuPopup
138
+ data-slot="menu-sub-content"
100
139
  className={cn(
101
- "z-float min-w-[8rem] overflow-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",
140
+ "w-auto min-w-[96px] rounded-lg bg-popover p-1 text-popover-foreground shadow-lg ring-1 ring-foreground/10 duration-100 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 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",
102
141
  className,
103
142
  )}
143
+ align={align}
144
+ alignOffset={alignOffset}
145
+ side={side}
146
+ sideOffset={sideOffset}
104
147
  {...props}
105
148
  />
106
- </DropdownMenuPrimitive.Portal>
107
- );
108
-
109
- type MenuItemProps = React.ComponentProps<typeof DropdownMenuPrimitive.Item> & {
110
- inset?: boolean;
111
- };
149
+ );
150
+ }
112
151
 
113
- const MenuItem = ({ className, inset, ...props }: MenuItemProps) => (
114
- <DropdownMenuPrimitive.Item
115
- data-slot="menu-item"
116
- className={cn(
117
- "relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
118
- inset && "pl-8",
119
- className,
120
- )}
121
- {...props}
122
- />
123
- );
124
-
125
- type MenuCheckboxItemProps = React.ComponentProps<
126
- typeof DropdownMenuPrimitive.CheckboxItem
127
- >;
128
-
129
- const MenuCheckboxItem = ({
152
+ function MenuCheckboxItem({
130
153
  className,
131
154
  children,
132
155
  checked,
156
+ inset,
133
157
  ...props
134
- }: MenuCheckboxItemProps) => (
135
- <DropdownMenuPrimitive.CheckboxItem
136
- data-slot="menu-checkbox-item"
137
- className={cn(
138
- "relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
139
- className,
140
- )}
141
- checked={checked}
142
- {...props}
143
- >
144
- <span className="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
145
- <DropdownMenuPrimitive.ItemIndicator>
146
- <Check className="h-4 w-4" />
147
- </DropdownMenuPrimitive.ItemIndicator>
148
- </span>
149
- {children}
150
- </DropdownMenuPrimitive.CheckboxItem>
151
- );
152
-
153
- type MenuRadioItemProps = React.ComponentProps<
154
- typeof DropdownMenuPrimitive.RadioItem
155
- >;
156
-
157
- const MenuRadioItem = ({
158
+ }: MenuPrimitive.CheckboxItem.Props & {
159
+ inset?: boolean;
160
+ }) {
161
+ return (
162
+ <MenuPrimitive.CheckboxItem
163
+ data-slot="menu-checkbox-item"
164
+ data-inset={inset}
165
+ className={cn(
166
+ "relative flex cursor-default items-center gap-1.5 rounded-md py-1 pr-8 pl-1.5 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground focus:**:text-accent-foreground data-inset:pl-7 data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
167
+ className,
168
+ )}
169
+ checked={checked}
170
+ {...props}
171
+ >
172
+ <span
173
+ className="pointer-events-none absolute right-2 flex items-center justify-center"
174
+ data-slot="menu-checkbox-item-indicator"
175
+ >
176
+ <MenuPrimitive.CheckboxItemIndicator>
177
+ <CheckIcon />
178
+ </MenuPrimitive.CheckboxItemIndicator>
179
+ </span>
180
+ {children}
181
+ </MenuPrimitive.CheckboxItem>
182
+ );
183
+ }
184
+
185
+ function MenuRadioGroup({ ...props }: MenuPrimitive.RadioGroup.Props) {
186
+ return <MenuPrimitive.RadioGroup data-slot="menu-radio-group" {...props} />;
187
+ }
188
+
189
+ function MenuRadioItem({
158
190
  className,
159
191
  children,
192
+ inset,
160
193
  ...props
161
- }: MenuRadioItemProps) => (
162
- <DropdownMenuPrimitive.RadioItem
163
- data-slot="menu-radio-item"
164
- className={cn(
165
- "relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
166
- className,
167
- )}
168
- {...props}
169
- >
170
- <span className="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
171
- <DropdownMenuPrimitive.ItemIndicator>
172
- <Circle className="h-2 w-2 fill-current" />
173
- </DropdownMenuPrimitive.ItemIndicator>
174
- </span>
175
- {children}
176
- </DropdownMenuPrimitive.RadioItem>
177
- );
178
-
179
- type MenuLabelProps = React.ComponentProps<
180
- typeof DropdownMenuPrimitive.Label
181
- > & {
194
+ }: MenuPrimitive.RadioItem.Props & {
182
195
  inset?: boolean;
183
- };
196
+ }) {
197
+ return (
198
+ <MenuPrimitive.RadioItem
199
+ data-slot="menu-radio-item"
200
+ data-inset={inset}
201
+ className={cn(
202
+ "relative flex cursor-default items-center gap-1.5 rounded-md py-1 pr-8 pl-1.5 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground focus:**:text-accent-foreground data-inset:pl-7 data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
203
+ className,
204
+ )}
205
+ {...props}
206
+ >
207
+ <span
208
+ className="pointer-events-none absolute right-2 flex items-center justify-center"
209
+ data-slot="menu-radio-item-indicator"
210
+ >
211
+ <MenuPrimitive.RadioItemIndicator>
212
+ <CheckIcon />
213
+ </MenuPrimitive.RadioItemIndicator>
214
+ </span>
215
+ {children}
216
+ </MenuPrimitive.RadioItem>
217
+ );
218
+ }
184
219
 
185
- const MenuLabel = ({ className, inset, ...props }: MenuLabelProps) => (
186
- <DropdownMenuPrimitive.Label
187
- data-slot="menu-label"
188
- className={cn(
189
- "px-2 py-1.5 text-sm font-semibold",
190
- inset && "pl-8",
191
- className,
192
- )}
193
- {...props}
194
- />
195
- );
196
-
197
- type MenuSeparatorProps = React.ComponentProps<
198
- typeof DropdownMenuPrimitive.Separator
199
- >;
200
-
201
- const MenuSeparator = ({ className, ...props }: MenuSeparatorProps) => (
202
- <DropdownMenuPrimitive.Separator
203
- data-slot="menu-separator"
204
- className={cn("-mx-1 my-1 h-px bg-muted", className)}
205
- {...props}
206
- />
207
- );
208
-
209
- type MenuShortcutProps = React.ComponentPropsWithoutRef<"span"> & {
210
- keys: Keys;
211
- handler: (event: KeyboardEvent) => any;
212
- options?: HotkeyOptions;
213
- };
220
+ function MenuSeparator({ className, ...props }: MenuPrimitive.Separator.Props) {
221
+ return (
222
+ <MenuPrimitive.Separator
223
+ data-slot="menu-separator"
224
+ className={cn("-mx-1 my-px h-px bg-input/50", className)}
225
+ {...props}
226
+ />
227
+ );
228
+ }
214
229
 
215
- const MenuShortcut = ({
216
- className,
217
- keys,
218
- handler,
219
- options = {},
220
- ...props
221
- }: MenuShortcutProps) => {
222
- useHotkey(keys, handler, options);
230
+ function MenuShortcut({ className, ...props }: React.ComponentProps<"span">) {
223
231
  return (
224
232
  <span
225
233
  data-slot="menu-shortcut"
226
- className={cn("ml-auto text-xs tracking-widest opacity-60", className)}
234
+ className={cn(
235
+ "ml-auto text-xs tracking-widest text-muted-foreground group-focus/menu-item:text-accent-foreground",
236
+ className,
237
+ )}
227
238
  {...props}
228
239
  />
229
240
  );
230
- };
241
+ }
231
242
 
232
243
  export {
233
- MenuCheckboxItem,
234
- MenuContent,
244
+ MenuRoot,
245
+ MenuPortal,
246
+ MenuTrigger,
247
+ MenuPopup,
235
248
  MenuGroup,
236
- MenuItem,
237
249
  MenuLabel,
238
- MenuPortal,
250
+ MenuItem,
251
+ MenuCheckboxItem,
239
252
  MenuRadioGroup,
240
253
  MenuRadioItem,
241
- MenuRoot,
242
254
  MenuSeparator,
243
255
  MenuShortcut,
244
256
  MenuSub,
245
- MenuSubContent,
246
257
  MenuSubTrigger,
247
- MenuTrigger,
258
+ MenuSubContent,
248
259
  };