@a2v2ai/uikit 0.0.36 → 0.0.38

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 (185) hide show
  1. package/Alert/Alert.stories.tsx +121 -0
  2. package/Alert/Alert.tsx +71 -0
  3. package/AlertDialog/AlertDialog.stories.tsx +665 -0
  4. package/AlertDialog/AlertDialog.tsx +241 -0
  5. package/Avatar/Avatar.stories.tsx +128 -0
  6. package/Avatar/Avatar.tsx +71 -0
  7. package/Badge/Badge.stories.tsx +76 -0
  8. package/Badge/Badge.tsx +39 -0
  9. package/Breadcrumb/Breadcrumb.stories.tsx +231 -0
  10. package/Breadcrumb/Breadcrumb.tsx +114 -0
  11. package/Button/Button.stories.tsx +684 -0
  12. package/Button/Button.tsx +107 -0
  13. package/Calendar/Calendar.stories.tsx +291 -0
  14. package/Calendar/Calendar.tsx +246 -0
  15. package/Card/Card.stories.tsx +136 -0
  16. package/Card/Card.tsx +96 -0
  17. package/Carousel/Carousel.stories.tsx +256 -0
  18. package/Carousel/Carousel.tsx +301 -0
  19. package/ChatBubble/ChatBubble.stories.tsx +339 -0
  20. package/ChatBubble/ChatBubble.tsx +179 -0
  21. package/Checkbox/Checkbox.stories.tsx +137 -0
  22. package/Checkbox/Checkbox.tsx +53 -0
  23. package/DataTable/DataTable.stories.tsx +400 -0
  24. package/DataTable/DataTable.tsx +207 -0
  25. package/Drawer/Drawer.stories.tsx +721 -0
  26. package/Drawer/Drawer.tsx +201 -0
  27. package/DropdownMenu/DropdownMenu.stories.tsx +251 -0
  28. package/DropdownMenu/DropdownMenu.tsx +199 -0
  29. package/ErrorMessage/ErrorMessage.stories.tsx +159 -0
  30. package/ErrorMessage/ErrorMessage.tsx +55 -0
  31. package/Flex/Flex.stories.tsx +390 -0
  32. package/Flex/Flex.tsx +102 -0
  33. package/IconButton/IconButton.stories.tsx +566 -0
  34. package/IconButton/IconButton.tsx +95 -0
  35. package/Input/Input.stories.tsx +566 -0
  36. package/Input/Input.tsx +168 -0
  37. package/InputOTP/InputOTP.stories.tsx +246 -0
  38. package/InputOTP/InputOTP.tsx +127 -0
  39. package/Label/Label.stories.tsx +110 -0
  40. package/Label/Label.tsx +44 -0
  41. package/Loader/Loader.stories.tsx +170 -0
  42. package/Loader/Loader.tsx +62 -0
  43. package/Menubar/Menubar.stories.tsx +382 -0
  44. package/Menubar/Menubar.tsx +274 -0
  45. package/Menubar/index.ts +18 -0
  46. package/Pagination/Pagination.stories.tsx +196 -0
  47. package/Pagination/Pagination.tsx +122 -0
  48. package/Popover/Popover.stories.tsx +133 -0
  49. package/Popover/Popover.tsx +31 -0
  50. package/Progress/Progress.stories.tsx +146 -0
  51. package/Progress/Progress.tsx +67 -0
  52. package/RadioGroup/RadioGroup.stories.tsx +159 -0
  53. package/RadioGroup/RadioGroup.tsx +68 -0
  54. package/ScrollArea/ScrollArea.stories.tsx +136 -0
  55. package/ScrollArea/ScrollArea.tsx +46 -0
  56. package/Select/Select.stories.tsx +378 -0
  57. package/Select/Select.tsx +230 -0
  58. package/Separator/Separator.stories.tsx +110 -0
  59. package/Separator/Separator.tsx +29 -0
  60. package/Sidebar/Sidebar.stories.tsx +340 -0
  61. package/Sidebar/Sidebar.tsx +414 -0
  62. package/Sidebar/index.ts +28 -0
  63. package/Skeleton/Skeleton.stories.tsx +117 -0
  64. package/Skeleton/Skeleton.tsx +16 -0
  65. package/Slider/Slider.stories.tsx +216 -0
  66. package/Slider/Slider.tsx +29 -0
  67. package/Spinner/Spinner.stories.tsx +210 -0
  68. package/Spinner/Spinner.tsx +78 -0
  69. package/Switch/Switch.stories.tsx +146 -0
  70. package/Switch/Switch.tsx +59 -0
  71. package/Table/Table.stories.tsx +510 -0
  72. package/Table/Table.tsx +114 -0
  73. package/Tabs/Tabs.stories.tsx +197 -0
  74. package/Tabs/Tabs.tsx +74 -0
  75. package/Textarea/Textarea.stories.tsx +187 -0
  76. package/Textarea/Textarea.tsx +73 -0
  77. package/Toast/Toast.stories.tsx +285 -0
  78. package/Toast/Toast.tsx +59 -0
  79. package/Tooltip/Tooltip.stories.tsx +463 -0
  80. package/Tooltip/Tooltip.tsx +96 -0
  81. package/Typography/Typography.stories.tsx +425 -0
  82. package/Typography/Typography.tsx +106 -0
  83. package/helpers.ts +5 -0
  84. package/{icons.js → icons.ts} +1 -1
  85. package/index.ts +217 -0
  86. package/lib/typography-types.ts +223 -0
  87. package/lib/utils.ts +15 -0
  88. package/package.json +36 -33
  89. package/tsconfig.json +22 -0
  90. package/Alert/Alert.d.ts +0 -13
  91. package/Alert/Alert.js +0 -25
  92. package/AlertDialog/AlertDialog.d.ts +0 -43
  93. package/AlertDialog/AlertDialog.js +0 -71
  94. package/Avatar/Avatar.d.ts +0 -14
  95. package/Avatar/Avatar.js +0 -25
  96. package/Badge/Badge.d.ts +0 -11
  97. package/Badge/Badge.js +0 -23
  98. package/Breadcrumb/Breadcrumb.d.ts +0 -19
  99. package/Breadcrumb/Breadcrumb.js +0 -23
  100. package/Button/Button.d.ts +0 -23
  101. package/Button/Button.js +0 -52
  102. package/Calendar/Calendar.d.ts +0 -20
  103. package/Calendar/Calendar.js +0 -78
  104. package/Card/Card.d.ts +0 -16
  105. package/Card/Card.js +0 -28
  106. package/Carousel/Carousel.d.ts +0 -37
  107. package/Carousel/Carousel.js +0 -132
  108. package/ChatBubble/ChatBubble.d.ts +0 -33
  109. package/ChatBubble/ChatBubble.js +0 -107
  110. package/Checkbox/Checkbox.d.ts +0 -12
  111. package/Checkbox/Checkbox.js +0 -20
  112. package/DataTable/DataTable.d.ts +0 -35
  113. package/DataTable/DataTable.js +0 -51
  114. package/Dialog/Dialog.d.ts +0 -35
  115. package/Dialog/Dialog.js +0 -130
  116. package/Drawer/Drawer.d.ts +0 -33
  117. package/Drawer/Drawer.js +0 -55
  118. package/DropdownMenu/DropdownMenu.d.ts +0 -27
  119. package/DropdownMenu/DropdownMenu.js +0 -35
  120. package/ErrorMessage/ErrorMessage.d.ts +0 -27
  121. package/ErrorMessage/ErrorMessage.js +0 -14
  122. package/Flex/Flex.d.ts +0 -31
  123. package/Flex/Flex.js +0 -64
  124. package/IconButton/IconButton.d.ts +0 -23
  125. package/IconButton/IconButton.js +0 -48
  126. package/Input/Input.d.ts +0 -27
  127. package/Input/Input.js +0 -42
  128. package/InputOTP/InputOTP.d.ts +0 -20
  129. package/InputOTP/InputOTP.js +0 -44
  130. package/Label/Label.d.ts +0 -13
  131. package/Label/Label.js +0 -19
  132. package/Loader/Loader.d.ts +0 -21
  133. package/Loader/Loader.js +0 -30
  134. package/Menubar/Menubar.d.ts +0 -26
  135. package/Menubar/Menubar.js +0 -54
  136. package/Menubar/index.d.ts +0 -1
  137. package/Menubar/index.js +0 -1
  138. package/Pagination/Pagination.d.ts +0 -35
  139. package/Pagination/Pagination.js +0 -37
  140. package/Popover/Popover.d.ts +0 -7
  141. package/Popover/Popover.js +0 -10
  142. package/Progress/Progress.d.ts +0 -17
  143. package/Progress/Progress.js +0 -33
  144. package/RadioGroup/RadioGroup.d.ts +0 -13
  145. package/RadioGroup/RadioGroup.js +0 -26
  146. package/ScrollArea/ScrollArea.d.ts +0 -5
  147. package/ScrollArea/ScrollArea.js +0 -11
  148. package/Select/Select.d.ts +0 -29
  149. package/Select/Select.js +0 -50
  150. package/Separator/Separator.d.ts +0 -4
  151. package/Separator/Separator.js +0 -7
  152. package/Sidebar/Sidebar.d.ts +0 -48
  153. package/Sidebar/Sidebar.js +0 -116
  154. package/Sidebar/index.d.ts +0 -2
  155. package/Sidebar/index.js +0 -1
  156. package/Skeleton/Skeleton.d.ts +0 -4
  157. package/Skeleton/Skeleton.js +0 -7
  158. package/Slider/Slider.d.ts +0 -6
  159. package/Slider/Slider.js +0 -7
  160. package/Spinner/Spinner.d.ts +0 -19
  161. package/Spinner/Spinner.js +0 -31
  162. package/Switch/Switch.d.ts +0 -12
  163. package/Switch/Switch.js +0 -30
  164. package/Table/Table.d.ts +0 -10
  165. package/Table/Table.js +0 -20
  166. package/Tabs/Tabs.d.ts +0 -15
  167. package/Tabs/Tabs.js +0 -24
  168. package/Textarea/Textarea.d.ts +0 -19
  169. package/Textarea/Textarea.js +0 -31
  170. package/Toast/Toast.d.ts +0 -12
  171. package/Toast/Toast.js +0 -25
  172. package/Tooltip/Tooltip.d.ts +0 -17
  173. package/Tooltip/Tooltip.js +0 -29
  174. package/Typography/Typography.d.ts +0 -20
  175. package/Typography/Typography.js +0 -43
  176. package/helpers.d.ts +0 -4
  177. package/helpers.js +0 -5
  178. package/icons.d.ts +0 -1
  179. package/index.d.ts +0 -42
  180. package/index.js +0 -45
  181. package/lib/typography-types.d.ts +0 -4
  182. package/lib/typography-types.js +0 -90
  183. package/lib/utils.d.ts +0 -3
  184. package/lib/utils.js +0 -14
  185. package/tmpclaude-2407-cwd +0 -1
@@ -0,0 +1,201 @@
1
+ import * as React from "react"
2
+ import { Drawer as DrawerPrimitive } from "vaul"
3
+ import { cva } from "class-variance-authority"
4
+
5
+ import { Loader } from "../Loader/Loader"
6
+ import { cn } from "../lib/utils"
7
+
8
+ type DrawerDirection = "bottom" | "top" | "left" | "right"
9
+
10
+ const drawerContentVariants = cva(
11
+ "group/drawer-content fixed z-50 flex h-auto flex-col bg-white",
12
+ {
13
+ variants: {
14
+ direction: {
15
+ bottom: "inset-x-0 bottom-0 mt-24 max-h-[80vh] rounded-t-[10px]",
16
+ top: "inset-x-0 top-0 mb-24 max-h-[80vh] rounded-b-[10px]",
17
+ left: "inset-y-0 left-0 w-3/4 sm:max-w-sm rounded-r-[10px]",
18
+ right: "inset-y-0 right-0 w-3/4 sm:max-w-sm rounded-l-[10px]",
19
+ },
20
+ },
21
+ defaultVariants: {
22
+ direction: "bottom",
23
+ },
24
+ }
25
+ )
26
+
27
+ const drawerOverlayVariants = cva(
28
+ "fixed inset-0 z-50 bg-black/60 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0"
29
+ )
30
+
31
+ export type DrawerProps = React.ComponentProps<typeof DrawerPrimitive.Root> & {
32
+ /** Direction the drawer slides in from */
33
+ direction?: DrawerDirection
34
+ /** Whether clicking outside or dragging down dismisses the drawer */
35
+ dismissible?: boolean
36
+ }
37
+
38
+ export type DrawerContentProps = Omit<
39
+ React.ComponentProps<typeof DrawerPrimitive.Content>,
40
+ "direction"
41
+ > & {
42
+ direction?: DrawerDirection
43
+ /** Whether to show the drag handle */
44
+ showHandle?: boolean
45
+ /** Whether the drawer content is in a loading state */
46
+ loading?: boolean
47
+ }
48
+
49
+ function Drawer({
50
+ direction = "bottom",
51
+ dismissible = true,
52
+ ...props
53
+ }: DrawerProps) {
54
+ return (
55
+ <DrawerPrimitive.Root
56
+ direction={direction}
57
+ dismissible={dismissible}
58
+ {...props}
59
+ />
60
+ )
61
+ }
62
+
63
+ function DrawerTrigger({
64
+ ...props
65
+ }: React.ComponentProps<typeof DrawerPrimitive.Trigger>) {
66
+ return <DrawerPrimitive.Trigger {...props} />
67
+ }
68
+
69
+ function DrawerPortal({
70
+ ...props
71
+ }: React.ComponentProps<typeof DrawerPrimitive.Portal>) {
72
+ return <DrawerPrimitive.Portal {...props} />
73
+ }
74
+
75
+ function DrawerClose({
76
+ ...props
77
+ }: React.ComponentProps<typeof DrawerPrimitive.Close>) {
78
+ return <DrawerPrimitive.Close {...props} />
79
+ }
80
+
81
+ function DrawerOverlay({
82
+ className,
83
+ ...props
84
+ }: React.ComponentProps<typeof DrawerPrimitive.Overlay>) {
85
+ return (
86
+ <DrawerPrimitive.Overlay
87
+ className={cn(drawerOverlayVariants(), className)}
88
+ {...props}
89
+ />
90
+ )
91
+ }
92
+
93
+ function DrawerContent({
94
+ className,
95
+ children,
96
+ direction = "bottom",
97
+ showHandle = true,
98
+ loading = false,
99
+ ...props
100
+ }: DrawerContentProps) {
101
+ const isVertical = direction === "bottom" || direction === "top"
102
+
103
+ return (
104
+ <DrawerPortal>
105
+ <DrawerOverlay />
106
+ <DrawerPrimitive.Content
107
+ className={cn(
108
+ drawerContentVariants({ direction }),
109
+ "shadow-lg",
110
+ className
111
+ )}
112
+ {...props}
113
+ >
114
+ {showHandle && isVertical && (
115
+ <div
116
+ className={cn(
117
+ "mx-auto shrink-0 rounded-full bg-neutral-200",
118
+ direction === "bottom" ? "mt-2 mb-4" : "mb-2 mt-4",
119
+ "h-[3px] w-[50px]"
120
+ )}
121
+ />
122
+ )}
123
+ {loading ? (
124
+ <div className="flex flex-1 items-center justify-center p-8">
125
+ <Loader size="large" color="grey" />
126
+ </div>
127
+ ) : (
128
+ children
129
+ )}
130
+ </DrawerPrimitive.Content>
131
+ </DrawerPortal>
132
+ )
133
+ }
134
+
135
+ function DrawerHeader({ className, ...props }: React.ComponentProps<"div">) {
136
+ return (
137
+ <div
138
+ className={cn("flex flex-col gap-1.5 p-4 text-center sm:text-left", className)}
139
+ {...props}
140
+ />
141
+ )
142
+ }
143
+
144
+ function DrawerFooter({ className, ...props }: React.ComponentProps<"div">) {
145
+ return (
146
+ <div
147
+ className={cn("mt-auto flex flex-col gap-2 p-4", className)}
148
+ {...props}
149
+ />
150
+ )
151
+ }
152
+
153
+ function DrawerBody({ className, ...props }: React.ComponentProps<"div">) {
154
+ return (
155
+ <div
156
+ className={cn("flex-1 overflow-auto p-4", className)}
157
+ {...props}
158
+ />
159
+ )
160
+ }
161
+
162
+ function DrawerTitle({
163
+ className,
164
+ ...props
165
+ }: React.ComponentProps<typeof DrawerPrimitive.Title>) {
166
+ return (
167
+ <DrawerPrimitive.Title
168
+ className={cn("text-lg font-semibold text-neutral-900", className)}
169
+ {...props}
170
+ />
171
+ )
172
+ }
173
+
174
+ function DrawerDescription({
175
+ className,
176
+ ...props
177
+ }: React.ComponentProps<typeof DrawerPrimitive.Description>) {
178
+ return (
179
+ <DrawerPrimitive.Description
180
+ className={cn("text-sm text-neutral-500", className)}
181
+ {...props}
182
+ />
183
+ )
184
+ }
185
+
186
+ export {
187
+ Drawer,
188
+ DrawerPortal,
189
+ DrawerOverlay,
190
+ DrawerTrigger,
191
+ DrawerClose,
192
+ DrawerContent,
193
+ DrawerHeader,
194
+ DrawerFooter,
195
+ DrawerBody,
196
+ DrawerTitle,
197
+ DrawerDescription,
198
+ drawerContentVariants,
199
+ drawerOverlayVariants,
200
+ }
201
+ export type { DrawerDirection }
@@ -0,0 +1,251 @@
1
+ import type { Meta, StoryObj } from "@storybook/react"
2
+ import { Cloud, CreditCard, Github, Keyboard, LifeBuoy, LogOut, Mail, MessageSquare, Plus, PlusCircle, Settings, User, UserPlus, Users } from "../icons"
3
+
4
+ import { Button } from "../Button/Button"
5
+ import { Flex } from "../Flex/Flex"
6
+ import { Typography } from "../Typography/Typography"
7
+ import {
8
+ DropdownMenu,
9
+ DropdownMenuTrigger,
10
+ DropdownMenuContent,
11
+ DropdownMenuItem,
12
+ DropdownMenuCheckboxItem,
13
+ DropdownMenuRadioItem,
14
+ DropdownMenuLabel,
15
+ DropdownMenuSeparator,
16
+ DropdownMenuShortcut,
17
+ DropdownMenuGroup,
18
+ DropdownMenuSub,
19
+ DropdownMenuSubContent,
20
+ DropdownMenuSubTrigger,
21
+ DropdownMenuRadioGroup,
22
+ } from "./DropdownMenu"
23
+
24
+ const meta: Meta<typeof DropdownMenu> = {
25
+ title: "Components/DropdownMenu",
26
+ component: DropdownMenu,
27
+ parameters: {
28
+ layout: "centered",
29
+ },
30
+ tags: ["autodocs"],
31
+ }
32
+
33
+ export default meta
34
+ type Story = StoryObj<typeof meta>
35
+
36
+ export const Default: Story = {
37
+ render: () => (
38
+ <DropdownMenu>
39
+ <DropdownMenuTrigger asChild>
40
+ <Button variant="outline">Open Menu</Button>
41
+ </DropdownMenuTrigger>
42
+ <DropdownMenuContent className="w-56">
43
+ <DropdownMenuLabel>My Account</DropdownMenuLabel>
44
+ <DropdownMenuSeparator />
45
+ <DropdownMenuGroup>
46
+ <DropdownMenuItem>
47
+ <User />
48
+ <span>Profile</span>
49
+ <DropdownMenuShortcut>⇧⌘P</DropdownMenuShortcut>
50
+ </DropdownMenuItem>
51
+ <DropdownMenuItem>
52
+ <CreditCard />
53
+ <span>Billing</span>
54
+ <DropdownMenuShortcut>⌘B</DropdownMenuShortcut>
55
+ </DropdownMenuItem>
56
+ <DropdownMenuItem>
57
+ <Settings />
58
+ <span>Settings</span>
59
+ <DropdownMenuShortcut>⌘S</DropdownMenuShortcut>
60
+ </DropdownMenuItem>
61
+ <DropdownMenuItem>
62
+ <Keyboard />
63
+ <span>Keyboard shortcuts</span>
64
+ <DropdownMenuShortcut>⌘K</DropdownMenuShortcut>
65
+ </DropdownMenuItem>
66
+ </DropdownMenuGroup>
67
+ <DropdownMenuSeparator />
68
+ <DropdownMenuGroup>
69
+ <DropdownMenuItem>
70
+ <Users />
71
+ <span>Team</span>
72
+ </DropdownMenuItem>
73
+ <DropdownMenuSub>
74
+ <DropdownMenuSubTrigger>
75
+ <UserPlus />
76
+ <span>Invite users</span>
77
+ </DropdownMenuSubTrigger>
78
+ <DropdownMenuSubContent>
79
+ <DropdownMenuItem>
80
+ <Mail />
81
+ <span>Email</span>
82
+ </DropdownMenuItem>
83
+ <DropdownMenuItem>
84
+ <MessageSquare />
85
+ <span>Message</span>
86
+ </DropdownMenuItem>
87
+ <DropdownMenuSeparator />
88
+ <DropdownMenuItem>
89
+ <PlusCircle />
90
+ <span>More...</span>
91
+ </DropdownMenuItem>
92
+ </DropdownMenuSubContent>
93
+ </DropdownMenuSub>
94
+ <DropdownMenuItem>
95
+ <Plus />
96
+ <span>New Team</span>
97
+ <DropdownMenuShortcut>⌘+T</DropdownMenuShortcut>
98
+ </DropdownMenuItem>
99
+ </DropdownMenuGroup>
100
+ <DropdownMenuSeparator />
101
+ <DropdownMenuItem>
102
+ <Github />
103
+ <span>GitHub</span>
104
+ </DropdownMenuItem>
105
+ <DropdownMenuItem>
106
+ <LifeBuoy />
107
+ <span>Support</span>
108
+ </DropdownMenuItem>
109
+ <DropdownMenuItem disabled>
110
+ <Cloud />
111
+ <span>API</span>
112
+ </DropdownMenuItem>
113
+ <DropdownMenuSeparator />
114
+ <DropdownMenuItem>
115
+ <LogOut />
116
+ <span>Log out</span>
117
+ <DropdownMenuShortcut>⇧⌘Q</DropdownMenuShortcut>
118
+ </DropdownMenuItem>
119
+ </DropdownMenuContent>
120
+ </DropdownMenu>
121
+ ),
122
+ }
123
+
124
+ export const WithCheckboxItems: Story = {
125
+ render: () => (
126
+ <DropdownMenu>
127
+ <DropdownMenuTrigger asChild>
128
+ <Button variant="outline">Open</Button>
129
+ </DropdownMenuTrigger>
130
+ <DropdownMenuContent className="w-56">
131
+ <DropdownMenuLabel>Appearance</DropdownMenuLabel>
132
+ <DropdownMenuSeparator />
133
+ <DropdownMenuCheckboxItem checked>
134
+ Status Bar
135
+ </DropdownMenuCheckboxItem>
136
+ <DropdownMenuCheckboxItem checked disabled>
137
+ Activity Bar
138
+ </DropdownMenuCheckboxItem>
139
+ <DropdownMenuCheckboxItem>Panel</DropdownMenuCheckboxItem>
140
+ </DropdownMenuContent>
141
+ </DropdownMenu>
142
+ ),
143
+ }
144
+
145
+ export const WithRadioItems: Story = {
146
+ render: () => (
147
+ <DropdownMenu>
148
+ <DropdownMenuTrigger asChild>
149
+ <Button variant="outline">Open</Button>
150
+ </DropdownMenuTrigger>
151
+ <DropdownMenuContent className="w-56">
152
+ <DropdownMenuLabel>Panel Position</DropdownMenuLabel>
153
+ <DropdownMenuSeparator />
154
+ <DropdownMenuRadioGroup value="bottom">
155
+ <DropdownMenuRadioItem value="top">Top</DropdownMenuRadioItem>
156
+ <DropdownMenuRadioItem value="bottom">Bottom</DropdownMenuRadioItem>
157
+ <DropdownMenuRadioItem value="right">Right</DropdownMenuRadioItem>
158
+ </DropdownMenuRadioGroup>
159
+ </DropdownMenuContent>
160
+ </DropdownMenu>
161
+ ),
162
+ }
163
+
164
+ export const Simple: Story = {
165
+ render: () => (
166
+ <DropdownMenu>
167
+ <DropdownMenuTrigger asChild>
168
+ <Button variant="outline">Actions</Button>
169
+ </DropdownMenuTrigger>
170
+ <DropdownMenuContent>
171
+ <DropdownMenuItem>Edit</DropdownMenuItem>
172
+ <DropdownMenuItem>Duplicate</DropdownMenuItem>
173
+ <DropdownMenuSeparator />
174
+ <DropdownMenuItem className="text-error-600">Delete</DropdownMenuItem>
175
+ </DropdownMenuContent>
176
+ </DropdownMenu>
177
+ ),
178
+ }
179
+
180
+ export const AllVariants: Story = {
181
+ render: () => (
182
+ <Flex gap={6}>
183
+ <Typography variant="h4" className="text-white">Dropdown Menu Examples</Typography>
184
+
185
+ <Flex direction="row" gap={4}>
186
+ <DropdownMenu>
187
+ <DropdownMenuTrigger asChild>
188
+ <Button variant="outline">Simple Menu</Button>
189
+ </DropdownMenuTrigger>
190
+ <DropdownMenuContent>
191
+ <DropdownMenuItem>New File</DropdownMenuItem>
192
+ <DropdownMenuItem>Open</DropdownMenuItem>
193
+ <DropdownMenuItem>Save</DropdownMenuItem>
194
+ <DropdownMenuSeparator />
195
+ <DropdownMenuItem>Exit</DropdownMenuItem>
196
+ </DropdownMenuContent>
197
+ </DropdownMenu>
198
+
199
+ <DropdownMenu>
200
+ <DropdownMenuTrigger asChild>
201
+ <Button variant="outline">With Icons</Button>
202
+ </DropdownMenuTrigger>
203
+ <DropdownMenuContent className="w-48">
204
+ <DropdownMenuItem>
205
+ <User />
206
+ <span>Profile</span>
207
+ </DropdownMenuItem>
208
+ <DropdownMenuItem>
209
+ <Settings />
210
+ <span>Settings</span>
211
+ </DropdownMenuItem>
212
+ <DropdownMenuSeparator />
213
+ <DropdownMenuItem>
214
+ <LogOut />
215
+ <span>Log out</span>
216
+ </DropdownMenuItem>
217
+ </DropdownMenuContent>
218
+ </DropdownMenu>
219
+
220
+ <DropdownMenu>
221
+ <DropdownMenuTrigger asChild>
222
+ <Button variant="outline">With Shortcuts</Button>
223
+ </DropdownMenuTrigger>
224
+ <DropdownMenuContent className="w-48">
225
+ <DropdownMenuItem>
226
+ <span>Undo</span>
227
+ <DropdownMenuShortcut>⌘Z</DropdownMenuShortcut>
228
+ </DropdownMenuItem>
229
+ <DropdownMenuItem>
230
+ <span>Redo</span>
231
+ <DropdownMenuShortcut>⇧⌘Z</DropdownMenuShortcut>
232
+ </DropdownMenuItem>
233
+ <DropdownMenuSeparator />
234
+ <DropdownMenuItem>
235
+ <span>Cut</span>
236
+ <DropdownMenuShortcut>⌘X</DropdownMenuShortcut>
237
+ </DropdownMenuItem>
238
+ <DropdownMenuItem>
239
+ <span>Copy</span>
240
+ <DropdownMenuShortcut>⌘C</DropdownMenuShortcut>
241
+ </DropdownMenuItem>
242
+ <DropdownMenuItem>
243
+ <span>Paste</span>
244
+ <DropdownMenuShortcut>⌘V</DropdownMenuShortcut>
245
+ </DropdownMenuItem>
246
+ </DropdownMenuContent>
247
+ </DropdownMenu>
248
+ </Flex>
249
+ </Flex>
250
+ ),
251
+ }
@@ -0,0 +1,199 @@
1
+ import * as React from "react"
2
+ import * as DropdownMenuPrimitive from "@radix-ui/react-dropdown-menu"
3
+ import { Check, ChevronRight, Circle } from "lucide-react"
4
+
5
+ import { cn } from "../lib/utils"
6
+
7
+ const DropdownMenu = DropdownMenuPrimitive.Root
8
+
9
+ const DropdownMenuTrigger = DropdownMenuPrimitive.Trigger
10
+
11
+ const DropdownMenuGroup = DropdownMenuPrimitive.Group
12
+
13
+ const DropdownMenuPortal = DropdownMenuPrimitive.Portal
14
+
15
+ const DropdownMenuSub = DropdownMenuPrimitive.Sub
16
+
17
+ const DropdownMenuRadioGroup = DropdownMenuPrimitive.RadioGroup
18
+
19
+ const DropdownMenuSubTrigger = React.forwardRef<
20
+ React.ElementRef<typeof DropdownMenuPrimitive.SubTrigger>,
21
+ React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.SubTrigger> & {
22
+ inset?: boolean
23
+ }
24
+ >(({ className, inset, children, ...props }, ref) => (
25
+ <DropdownMenuPrimitive.SubTrigger
26
+ ref={ref}
27
+ className={cn(
28
+ "flex cursor-pointer select-none items-center gap-2 rounded-md px-2 py-1.5 text-sm outline-none focus:bg-grey-100 data-[state=open]:bg-grey-100 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0",
29
+ inset && "pl-8",
30
+ className
31
+ )}
32
+ {...props}
33
+ >
34
+ {children}
35
+ <ChevronRight className="ml-auto" />
36
+ </DropdownMenuPrimitive.SubTrigger>
37
+ ))
38
+ DropdownMenuSubTrigger.displayName =
39
+ DropdownMenuPrimitive.SubTrigger.displayName
40
+
41
+ const DropdownMenuSubContent = React.forwardRef<
42
+ React.ElementRef<typeof DropdownMenuPrimitive.SubContent>,
43
+ React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.SubContent>
44
+ >(({ className, ...props }, ref) => (
45
+ <DropdownMenuPrimitive.SubContent
46
+ ref={ref}
47
+ className={cn(
48
+ "z-50 min-w-[8rem] overflow-hidden rounded-lg border border-grey-200 bg-white p-1 text-main-950 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",
49
+ className
50
+ )}
51
+ {...props}
52
+ />
53
+ ))
54
+ DropdownMenuSubContent.displayName =
55
+ DropdownMenuPrimitive.SubContent.displayName
56
+
57
+ const DropdownMenuContent = React.forwardRef<
58
+ React.ElementRef<typeof DropdownMenuPrimitive.Content>,
59
+ React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Content>
60
+ >(({ className, sideOffset = 4, ...props }, ref) => (
61
+ <DropdownMenuPrimitive.Portal>
62
+ <DropdownMenuPrimitive.Content
63
+ ref={ref}
64
+ sideOffset={sideOffset}
65
+ className={cn(
66
+ "z-50 min-w-[8rem] overflow-hidden rounded-lg border border-grey-200 bg-white p-1 text-main-950 shadow-md",
67
+ "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",
68
+ className
69
+ )}
70
+ {...props}
71
+ />
72
+ </DropdownMenuPrimitive.Portal>
73
+ ))
74
+ DropdownMenuContent.displayName = DropdownMenuPrimitive.Content.displayName
75
+
76
+ const DropdownMenuItem = React.forwardRef<
77
+ React.ElementRef<typeof DropdownMenuPrimitive.Item>,
78
+ React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Item> & {
79
+ inset?: boolean
80
+ }
81
+ >(({ className, inset, ...props }, ref) => (
82
+ <DropdownMenuPrimitive.Item
83
+ ref={ref}
84
+ className={cn(
85
+ "relative flex cursor-pointer select-none items-center gap-2 rounded-md px-2 py-1.5 text-sm outline-none transition-colors focus:bg-grey-100 focus:text-main-950 data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&>svg]:size-4 [&>svg]:shrink-0",
86
+ inset && "pl-8",
87
+ className
88
+ )}
89
+ {...props}
90
+ />
91
+ ))
92
+ DropdownMenuItem.displayName = DropdownMenuPrimitive.Item.displayName
93
+
94
+ const DropdownMenuCheckboxItem = React.forwardRef<
95
+ React.ElementRef<typeof DropdownMenuPrimitive.CheckboxItem>,
96
+ React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.CheckboxItem>
97
+ >(({ className, children, checked, ...props }, ref) => (
98
+ <DropdownMenuPrimitive.CheckboxItem
99
+ ref={ref}
100
+ className={cn(
101
+ "relative flex cursor-default select-none items-center rounded-md py-1.5 pl-8 pr-2 text-sm outline-none transition-colors focus:bg-grey-100 focus:text-main-950 data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
102
+ className
103
+ )}
104
+ checked={checked}
105
+ {...props}
106
+ >
107
+ <span className="absolute left-2 flex size-3.5 items-center justify-center">
108
+ <DropdownMenuPrimitive.ItemIndicator>
109
+ <Check className="size-4" />
110
+ </DropdownMenuPrimitive.ItemIndicator>
111
+ </span>
112
+ {children}
113
+ </DropdownMenuPrimitive.CheckboxItem>
114
+ ))
115
+ DropdownMenuCheckboxItem.displayName =
116
+ DropdownMenuPrimitive.CheckboxItem.displayName
117
+
118
+ const DropdownMenuRadioItem = React.forwardRef<
119
+ React.ElementRef<typeof DropdownMenuPrimitive.RadioItem>,
120
+ React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.RadioItem>
121
+ >(({ className, children, ...props }, ref) => (
122
+ <DropdownMenuPrimitive.RadioItem
123
+ ref={ref}
124
+ className={cn(
125
+ "relative flex cursor-default select-none items-center rounded-md py-1.5 pl-8 pr-2 text-sm outline-none transition-colors focus:bg-grey-100 focus:text-main-950 data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
126
+ className
127
+ )}
128
+ {...props}
129
+ >
130
+ <span className="absolute left-2 flex size-3.5 items-center justify-center">
131
+ <DropdownMenuPrimitive.ItemIndicator>
132
+ <Circle className="size-2 fill-current" />
133
+ </DropdownMenuPrimitive.ItemIndicator>
134
+ </span>
135
+ {children}
136
+ </DropdownMenuPrimitive.RadioItem>
137
+ ))
138
+ DropdownMenuRadioItem.displayName = DropdownMenuPrimitive.RadioItem.displayName
139
+
140
+ const DropdownMenuLabel = React.forwardRef<
141
+ React.ElementRef<typeof DropdownMenuPrimitive.Label>,
142
+ React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Label> & {
143
+ inset?: boolean
144
+ }
145
+ >(({ className, inset, ...props }, ref) => (
146
+ <DropdownMenuPrimitive.Label
147
+ ref={ref}
148
+ className={cn(
149
+ "px-2 py-1.5 text-sm font-semibold text-main-950",
150
+ inset && "pl-8",
151
+ className
152
+ )}
153
+ {...props}
154
+ />
155
+ ))
156
+ DropdownMenuLabel.displayName = DropdownMenuPrimitive.Label.displayName
157
+
158
+ const DropdownMenuSeparator = React.forwardRef<
159
+ React.ElementRef<typeof DropdownMenuPrimitive.Separator>,
160
+ React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Separator>
161
+ >(({ className, ...props }, ref) => (
162
+ <DropdownMenuPrimitive.Separator
163
+ ref={ref}
164
+ className={cn("-mx-1 my-1 h-px bg-grey-100", className)}
165
+ {...props}
166
+ />
167
+ ))
168
+ DropdownMenuSeparator.displayName = DropdownMenuPrimitive.Separator.displayName
169
+
170
+ const DropdownMenuShortcut = ({
171
+ className,
172
+ ...props
173
+ }: React.HTMLAttributes<HTMLSpanElement>) => {
174
+ return (
175
+ <span
176
+ className={cn("ml-auto text-xs tracking-widest text-grey-400", className)}
177
+ {...props}
178
+ />
179
+ )
180
+ }
181
+ DropdownMenuShortcut.displayName = "DropdownMenuShortcut"
182
+
183
+ export {
184
+ DropdownMenu,
185
+ DropdownMenuTrigger,
186
+ DropdownMenuContent,
187
+ DropdownMenuItem,
188
+ DropdownMenuCheckboxItem,
189
+ DropdownMenuRadioItem,
190
+ DropdownMenuLabel,
191
+ DropdownMenuSeparator,
192
+ DropdownMenuShortcut,
193
+ DropdownMenuGroup,
194
+ DropdownMenuPortal,
195
+ DropdownMenuSub,
196
+ DropdownMenuSubContent,
197
+ DropdownMenuSubTrigger,
198
+ DropdownMenuRadioGroup,
199
+ }