@a2v2ai/uikit 0.0.1 → 0.0.3

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 (148) 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 +90 -0
  13. package/Calendar/Calendar.stories.tsx +207 -0
  14. package/Calendar/Calendar.tsx +232 -0
  15. package/Card/Card.stories.tsx +136 -0
  16. package/Card/Card.tsx +96 -0
  17. package/ChatBubble/ChatBubble.stories.tsx +307 -0
  18. package/ChatBubble/ChatBubble.tsx +167 -0
  19. package/Checkbox/Checkbox.stories.tsx +137 -0
  20. package/Checkbox/Checkbox.tsx +53 -0
  21. package/Drawer/Drawer.stories.tsx +721 -0
  22. package/Drawer/Drawer.tsx +201 -0
  23. package/DropdownMenu/DropdownMenu.stories.tsx +251 -0
  24. package/DropdownMenu/DropdownMenu.tsx +199 -0
  25. package/ErrorMessage/ErrorMessage.stories.tsx +159 -0
  26. package/ErrorMessage/ErrorMessage.tsx +55 -0
  27. package/Flex/Flex.tsx +102 -0
  28. package/IconButton/IconButton.stories.tsx +566 -0
  29. package/IconButton/IconButton.tsx +95 -0
  30. package/Input/Input.stories.tsx +456 -0
  31. package/Input/Input.tsx +129 -0
  32. package/InputOTP/InputOTP.stories.tsx +246 -0
  33. package/InputOTP/InputOTP.tsx +127 -0
  34. package/Label/Label.stories.tsx +105 -0
  35. package/Label/Label.tsx +43 -0
  36. package/Loader/Loader.stories.tsx +170 -0
  37. package/Loader/Loader.tsx +62 -0
  38. package/Popover/Popover.stories.tsx +133 -0
  39. package/Popover/Popover.tsx +31 -0
  40. package/Progress/Progress.stories.tsx +146 -0
  41. package/Progress/Progress.tsx +67 -0
  42. package/README.md +12 -12
  43. package/RadioGroup/RadioGroup.stories.tsx +159 -0
  44. package/RadioGroup/RadioGroup.tsx +68 -0
  45. package/ScrollArea/ScrollArea.stories.tsx +136 -0
  46. package/ScrollArea/ScrollArea.tsx +46 -0
  47. package/Select/Select.stories.tsx +242 -0
  48. package/Select/Select.tsx +180 -0
  49. package/Separator/Separator.stories.tsx +110 -0
  50. package/Separator/Separator.tsx +29 -0
  51. package/Skeleton/Skeleton.stories.tsx +117 -0
  52. package/Skeleton/Skeleton.tsx +16 -0
  53. package/Spinner/Spinner.stories.tsx +210 -0
  54. package/Spinner/Spinner.tsx +78 -0
  55. package/Switch/Switch.stories.tsx +146 -0
  56. package/Switch/Switch.tsx +59 -0
  57. package/Tabs/Tabs.stories.tsx +197 -0
  58. package/Tabs/Tabs.tsx +74 -0
  59. package/Textarea/Textarea.stories.tsx +170 -0
  60. package/Textarea/Textarea.tsx +51 -0
  61. package/Toast/Toast.stories.tsx +285 -0
  62. package/Toast/Toast.tsx +59 -0
  63. package/Tooltip/Tooltip.stories.tsx +463 -0
  64. package/Tooltip/Tooltip.tsx +96 -0
  65. package/Typography/Typography.stories.tsx +235 -0
  66. package/Typography/Typography.tsx +171 -0
  67. package/helpers.ts +5 -0
  68. package/icons.ts +2 -0
  69. package/index.ts +136 -0
  70. package/lib/utils.ts +15 -0
  71. package/package.json +4 -1
  72. package/tsconfig.json +24 -0
  73. package/Alert/Alert.d.ts +0 -11
  74. package/Alert/Alert.js +0 -64
  75. package/AlertDialog/AlertDialog.d.ts +0 -35
  76. package/AlertDialog/AlertDialog.js +0 -121
  77. package/Avatar/Avatar.d.ts +0 -12
  78. package/Avatar/Avatar.js +0 -64
  79. package/Badge/Badge.d.ts +0 -9
  80. package/Badge/Badge.js +0 -26
  81. package/Breadcrumb/Breadcrumb.d.ts +0 -19
  82. package/Breadcrumb/Breadcrumb.js +0 -65
  83. package/Button/Button.d.ts +0 -14
  84. package/Button/Button.js +0 -75
  85. package/Calendar/Calendar.d.ts +0 -16
  86. package/Calendar/Calendar.js +0 -113
  87. package/Card/Card.d.ts +0 -14
  88. package/Card/Card.js +0 -70
  89. package/ChatBubble/ChatBubble.d.ts +0 -29
  90. package/ChatBubble/ChatBubble.js +0 -133
  91. package/Checkbox/Checkbox.d.ts +0 -10
  92. package/Checkbox/Checkbox.js +0 -57
  93. package/Dialog/Dialog.d.ts +0 -35
  94. package/Dialog/Dialog.js +0 -130
  95. package/Drawer/Drawer.d.ts +0 -31
  96. package/Drawer/Drawer.js +0 -69
  97. package/DropdownMenu/DropdownMenu.d.ts +0 -27
  98. package/DropdownMenu/DropdownMenu.js +0 -85
  99. package/ErrorMessage/ErrorMessage.d.ts +0 -27
  100. package/ErrorMessage/ErrorMessage.js +0 -15
  101. package/Flex/Flex.d.ts +0 -23
  102. package/Flex/Flex.js +0 -101
  103. package/IconButton/IconButton.d.ts +0 -17
  104. package/IconButton/IconButton.js +0 -85
  105. package/Input/Input.d.ts +0 -16
  106. package/Input/Input.js +0 -75
  107. package/InputOTP/InputOTP.d.ts +0 -18
  108. package/InputOTP/InputOTP.js +0 -85
  109. package/Label/Label.d.ts +0 -10
  110. package/Label/Label.js +0 -57
  111. package/Loader/Loader.d.ts +0 -18
  112. package/Loader/Loader.js +0 -67
  113. package/Popover/Popover.d.ts +0 -7
  114. package/Popover/Popover.js +0 -49
  115. package/Progress/Progress.d.ts +0 -13
  116. package/Progress/Progress.js +0 -71
  117. package/RadioGroup/RadioGroup.d.ts +0 -11
  118. package/RadioGroup/RadioGroup.js +0 -64
  119. package/ScrollArea/ScrollArea.d.ts +0 -5
  120. package/ScrollArea/ScrollArea.js +0 -48
  121. package/Select/Select.d.ts +0 -19
  122. package/Select/Select.js +0 -85
  123. package/Separator/Separator.d.ts +0 -4
  124. package/Separator/Separator.js +0 -43
  125. package/Skeleton/Skeleton.d.ts +0 -4
  126. package/Skeleton/Skeleton.js +0 -8
  127. package/Spinner/Spinner.d.ts +0 -15
  128. package/Spinner/Spinner.js +0 -68
  129. package/Switch/Switch.d.ts +0 -10
  130. package/Switch/Switch.js +0 -67
  131. package/Tabs/Tabs.d.ts +0 -13
  132. package/Tabs/Tabs.js +0 -64
  133. package/Textarea/Textarea.d.ts +0 -10
  134. package/Textarea/Textarea.js +0 -64
  135. package/Toast/Toast.d.ts +0 -10
  136. package/Toast/Toast.js +0 -29
  137. package/Tooltip/Tooltip.d.ts +0 -15
  138. package/Tooltip/Tooltip.js +0 -68
  139. package/Typography/Typography.d.ts +0 -15
  140. package/Typography/Typography.js +0 -125
  141. package/helpers.d.ts +0 -4
  142. package/helpers.js +0 -13
  143. package/icons.d.ts +0 -1
  144. package/icons.js +0 -18
  145. package/index.d.ts +0 -35
  146. package/index.js +0 -183
  147. package/lib/utils.d.ts +0 -3
  148. package/lib/utils.js +0 -18
@@ -0,0 +1,566 @@
1
+ import type { Meta, StoryObj } from "@storybook/react"
2
+ import { Plus, Pencil, Filter, MoreVertical, MoreHorizontal, Trash2 } from "../icons"
3
+
4
+ import { Flex } from "../Flex/Flex"
5
+ import { Typography } from "../Typography/Typography"
6
+ import { IconButton } from "./IconButton"
7
+
8
+ const meta: Meta<typeof IconButton> = {
9
+ title: "Components/IconButton",
10
+ component: IconButton,
11
+ parameters: {
12
+ layout: "centered",
13
+ },
14
+ argTypes: {
15
+ variant: {
16
+ control: "select",
17
+ options: ["primary", "secondary", "outline", "ghost"],
18
+ description: "The visual variant of the button",
19
+ },
20
+ size: {
21
+ control: "select",
22
+ options: ["mini", "small", "regular", "large"],
23
+ description: "The size of the button",
24
+ },
25
+ roundness: {
26
+ control: "select",
27
+ options: ["default", "round"],
28
+ description: "The roundness of the button corners",
29
+ },
30
+ disabled: {
31
+ control: "boolean",
32
+ description: "Whether the button is disabled",
33
+ },
34
+ },
35
+ tags: ["autodocs"],
36
+ }
37
+
38
+ export default meta
39
+ type Story = StoryObj<typeof meta>
40
+
41
+ // Default story
42
+ export const Default: Story = {
43
+ args: {
44
+ icon: <Plus />,
45
+ "aria-label": "Add item",
46
+ },
47
+ parameters: {
48
+ docs: {
49
+ source: {
50
+ code: `<IconButton icon={<Plus />} aria-label="Add item" />`,
51
+ },
52
+ },
53
+ },
54
+ }
55
+
56
+ // Variants
57
+ export const Primary: Story = {
58
+ args: {
59
+ variant: "primary",
60
+ icon: <Plus />,
61
+ "aria-label": "Add item",
62
+ },
63
+ parameters: {
64
+ docs: {
65
+ source: {
66
+ code: `<IconButton variant="primary" icon={<Plus />} aria-label="Add item" />`,
67
+ },
68
+ },
69
+ },
70
+ }
71
+
72
+ export const Secondary: Story = {
73
+ args: {
74
+ variant: "secondary",
75
+ icon: <Pencil />,
76
+ "aria-label": "Edit",
77
+ },
78
+ parameters: {
79
+ docs: {
80
+ source: {
81
+ code: `<IconButton variant="secondary" icon={<Pencil />} aria-label="Edit" />`,
82
+ },
83
+ },
84
+ },
85
+ }
86
+
87
+ export const Outline: Story = {
88
+ args: {
89
+ variant: "outline",
90
+ icon: <Filter />,
91
+ "aria-label": "Filter",
92
+ },
93
+ parameters: {
94
+ docs: {
95
+ source: {
96
+ code: `<IconButton variant="outline" icon={<Filter />} aria-label="Filter" />`,
97
+ },
98
+ },
99
+ },
100
+ }
101
+
102
+ export const Ghost: Story = {
103
+ args: {
104
+ variant: "ghost",
105
+ icon: <MoreVertical />,
106
+ "aria-label": "More options",
107
+ },
108
+ parameters: {
109
+ docs: {
110
+ source: {
111
+ code: `<IconButton variant="ghost" icon={<MoreVertical />} aria-label="More options" />`,
112
+ },
113
+ },
114
+ },
115
+ }
116
+
117
+ // Sizes
118
+ export const SizeLarge: Story = {
119
+ args: {
120
+ size: "large",
121
+ icon: <Plus />,
122
+ "aria-label": "Add item",
123
+ },
124
+ parameters: {
125
+ docs: {
126
+ source: {
127
+ code: `<IconButton size="large" icon={<Plus />} aria-label="Add item" />`,
128
+ },
129
+ },
130
+ },
131
+ }
132
+
133
+ export const SizeRegular: Story = {
134
+ args: {
135
+ size: "regular",
136
+ icon: <Plus />,
137
+ "aria-label": "Add item",
138
+ },
139
+ parameters: {
140
+ docs: {
141
+ source: {
142
+ code: `<IconButton size="regular" icon={<Plus />} aria-label="Add item" />`,
143
+ },
144
+ },
145
+ },
146
+ }
147
+
148
+ export const SizeSmall: Story = {
149
+ args: {
150
+ size: "small",
151
+ icon: <Plus />,
152
+ "aria-label": "Add item",
153
+ },
154
+ parameters: {
155
+ docs: {
156
+ source: {
157
+ code: `<IconButton size="small" icon={<Plus />} aria-label="Add item" />`,
158
+ },
159
+ },
160
+ },
161
+ }
162
+
163
+ export const SizeMini: Story = {
164
+ args: {
165
+ size: "mini",
166
+ icon: <Plus />,
167
+ "aria-label": "Add item",
168
+ },
169
+ parameters: {
170
+ docs: {
171
+ source: {
172
+ code: `<IconButton size="mini" icon={<Plus />} aria-label="Add item" />`,
173
+ },
174
+ },
175
+ },
176
+ }
177
+
178
+ // Roundness
179
+ export const RoundDefault: Story = {
180
+ args: {
181
+ roundness: "default",
182
+ icon: <Plus />,
183
+ "aria-label": "Add item",
184
+ },
185
+ parameters: {
186
+ docs: {
187
+ source: {
188
+ code: `<IconButton roundness="default" icon={<Plus />} aria-label="Add item" />`,
189
+ },
190
+ },
191
+ },
192
+ }
193
+
194
+ export const RoundFull: Story = {
195
+ args: {
196
+ roundness: "round",
197
+ icon: <Plus />,
198
+ "aria-label": "Add item",
199
+ },
200
+ parameters: {
201
+ docs: {
202
+ source: {
203
+ code: `<IconButton roundness="round" icon={<Plus />} aria-label="Add item" />`,
204
+ },
205
+ },
206
+ },
207
+ }
208
+
209
+ // Disabled
210
+ export const Disabled: Story = {
211
+ args: {
212
+ disabled: true,
213
+ icon: <Plus />,
214
+ "aria-label": "Add item",
215
+ },
216
+ parameters: {
217
+ docs: {
218
+ source: {
219
+ code: `<IconButton disabled icon={<Plus />} aria-label="Add item" />`,
220
+ },
221
+ },
222
+ },
223
+ }
224
+
225
+ // All Variants showcase - matching Figma grid layout
226
+ export const AllVariants: Story = {
227
+ render: () => (
228
+ <Flex direction="column" gap={8}>
229
+ {/* Icon Button Grid - matching Figma layout */}
230
+ <Flex direction="column" gap={4}>
231
+ <Typography variant="h4" className="text-white">Icon Button</Typography>
232
+
233
+ {/* Header row with variant labels */}
234
+ <Flex gap={0}>
235
+ {/* Spacer for row labels */}
236
+ <div className="w-20" />
237
+
238
+ {/* Primary */}
239
+ <Flex direction="column" align="center" className="w-40">
240
+ <Typography variant="body2" className="text-neutral-400 mb-2">Primary</Typography>
241
+ <Flex gap={2}>
242
+ <Typography variant="caption" className="text-neutral-500 w-10 text-center">Default</Typography>
243
+ <Typography variant="caption" className="text-neutral-500 w-10 text-center">Disabled</Typography>
244
+ </Flex>
245
+ </Flex>
246
+
247
+ {/* Secondary */}
248
+ <Flex direction="column" align="center" className="w-40">
249
+ <Typography variant="body2" className="text-neutral-400 mb-2">Secondary</Typography>
250
+ <Flex gap={2}>
251
+ <Typography variant="caption" className="text-neutral-500 w-10 text-center">Default</Typography>
252
+ <Typography variant="caption" className="text-neutral-500 w-10 text-center">Disabled</Typography>
253
+ </Flex>
254
+ </Flex>
255
+
256
+ {/* Outline */}
257
+ <Flex direction="column" align="center" className="w-40">
258
+ <Typography variant="body2" className="text-neutral-400 mb-2">Outline</Typography>
259
+ <Flex gap={2}>
260
+ <Typography variant="caption" className="text-neutral-500 w-10 text-center">Default</Typography>
261
+ <Typography variant="caption" className="text-neutral-500 w-10 text-center">Disabled</Typography>
262
+ </Flex>
263
+ </Flex>
264
+
265
+ {/* Ghost */}
266
+ <Flex direction="column" align="center" className="w-40">
267
+ <Typography variant="body2" className="text-neutral-400 mb-2">Ghost</Typography>
268
+ <Flex gap={2}>
269
+ <Typography variant="caption" className="text-neutral-500 w-10 text-center">Default</Typography>
270
+ <Typography variant="caption" className="text-neutral-500 w-10 text-center">Disabled</Typography>
271
+ </Flex>
272
+ </Flex>
273
+ </Flex>
274
+
275
+ {/* Default Roundness Section */}
276
+ <Flex direction="column" gap={2}>
277
+ <Typography variant="body2" className="text-neutral-500 mb-1">Default</Typography>
278
+
279
+ {/* Regular Row */}
280
+ <Flex gap={0} align="center">
281
+ <Typography variant="caption" className="text-neutral-500 w-20">Regular</Typography>
282
+ <Flex gap={2} className="w-40" justify="center">
283
+ <IconButton variant="primary" size="regular" icon={<Plus />} aria-label="Primary Regular" />
284
+ <IconButton variant="primary" size="regular" icon={<Plus />} aria-label="Primary Regular Disabled" disabled />
285
+ </Flex>
286
+ <Flex gap={2} className="w-40" justify="center">
287
+ <IconButton variant="secondary" size="regular" icon={<Plus />} aria-label="Secondary Regular" />
288
+ <IconButton variant="secondary" size="regular" icon={<Plus />} aria-label="Secondary Regular Disabled" disabled />
289
+ </Flex>
290
+ <Flex gap={2} className="w-40" justify="center">
291
+ <IconButton variant="outline" size="regular" icon={<Plus />} aria-label="Outline Regular" />
292
+ <IconButton variant="outline" size="regular" icon={<Plus />} aria-label="Outline Regular Disabled" disabled />
293
+ </Flex>
294
+ <Flex gap={2} className="w-40" justify="center">
295
+ <IconButton variant="ghost" size="regular" icon={<Plus />} aria-label="Ghost Regular" />
296
+ <IconButton variant="ghost" size="regular" icon={<Plus />} aria-label="Ghost Regular Disabled" disabled />
297
+ </Flex>
298
+ </Flex>
299
+
300
+ {/* Large Row */}
301
+ <Flex gap={0} align="center">
302
+ <Typography variant="caption" className="text-neutral-500 w-20">Large</Typography>
303
+ <Flex gap={2} className="w-40" justify="center">
304
+ <IconButton variant="primary" size="large" icon={<Plus />} aria-label="Primary Large" />
305
+ <IconButton variant="primary" size="large" icon={<Plus />} aria-label="Primary Large Disabled" disabled />
306
+ </Flex>
307
+ <Flex gap={2} className="w-40" justify="center">
308
+ <IconButton variant="secondary" size="large" icon={<Plus />} aria-label="Secondary Large" />
309
+ <IconButton variant="secondary" size="large" icon={<Plus />} aria-label="Secondary Large Disabled" disabled />
310
+ </Flex>
311
+ <Flex gap={2} className="w-40" justify="center">
312
+ <IconButton variant="outline" size="large" icon={<Plus />} aria-label="Outline Large" />
313
+ <IconButton variant="outline" size="large" icon={<Plus />} aria-label="Outline Large Disabled" disabled />
314
+ </Flex>
315
+ <Flex gap={2} className="w-40" justify="center">
316
+ <IconButton variant="ghost" size="large" icon={<Plus />} aria-label="Ghost Large" />
317
+ <IconButton variant="ghost" size="large" icon={<Plus />} aria-label="Ghost Large Disabled" disabled />
318
+ </Flex>
319
+ </Flex>
320
+
321
+ {/* Small Row */}
322
+ <Flex gap={0} align="center">
323
+ <Typography variant="caption" className="text-neutral-500 w-20">Small</Typography>
324
+ <Flex gap={2} className="w-40" justify="center">
325
+ <IconButton variant="primary" size="small" icon={<Plus />} aria-label="Primary Small" />
326
+ <IconButton variant="primary" size="small" icon={<Plus />} aria-label="Primary Small Disabled" disabled />
327
+ </Flex>
328
+ <Flex gap={2} className="w-40" justify="center">
329
+ <IconButton variant="secondary" size="small" icon={<Plus />} aria-label="Secondary Small" />
330
+ <IconButton variant="secondary" size="small" icon={<Plus />} aria-label="Secondary Small Disabled" disabled />
331
+ </Flex>
332
+ <Flex gap={2} className="w-40" justify="center">
333
+ <IconButton variant="outline" size="small" icon={<Plus />} aria-label="Outline Small" />
334
+ <IconButton variant="outline" size="small" icon={<Plus />} aria-label="Outline Small Disabled" disabled />
335
+ </Flex>
336
+ <Flex gap={2} className="w-40" justify="center">
337
+ <IconButton variant="ghost" size="small" icon={<Plus />} aria-label="Ghost Small" />
338
+ <IconButton variant="ghost" size="small" icon={<Plus />} aria-label="Ghost Small Disabled" disabled />
339
+ </Flex>
340
+ </Flex>
341
+
342
+ {/* Mini Row */}
343
+ <Flex gap={0} align="center">
344
+ <Typography variant="caption" className="text-neutral-500 w-20">Mini</Typography>
345
+ <Flex gap={2} className="w-40" justify="center">
346
+ <IconButton variant="primary" size="mini" icon={<Plus />} aria-label="Primary Mini" />
347
+ <IconButton variant="primary" size="mini" icon={<Plus />} aria-label="Primary Mini Disabled" disabled />
348
+ </Flex>
349
+ <Flex gap={2} className="w-40" justify="center">
350
+ <IconButton variant="secondary" size="mini" icon={<Plus />} aria-label="Secondary Mini" />
351
+ <IconButton variant="secondary" size="mini" icon={<Plus />} aria-label="Secondary Mini Disabled" disabled />
352
+ </Flex>
353
+ <Flex gap={2} className="w-40" justify="center">
354
+ <IconButton variant="outline" size="mini" icon={<Plus />} aria-label="Outline Mini" />
355
+ <IconButton variant="outline" size="mini" icon={<Plus />} aria-label="Outline Mini Disabled" disabled />
356
+ </Flex>
357
+ <Flex gap={2} className="w-40" justify="center">
358
+ <IconButton variant="ghost" size="mini" icon={<Plus />} aria-label="Ghost Mini" />
359
+ <IconButton variant="ghost" size="mini" icon={<Plus />} aria-label="Ghost Mini Disabled" disabled />
360
+ </Flex>
361
+ </Flex>
362
+ </Flex>
363
+
364
+ {/* Round Section */}
365
+ <Flex direction="column" gap={2} className="mt-4">
366
+ <Typography variant="body2" className="text-neutral-500 mb-1">Round</Typography>
367
+
368
+ {/* Regular Row */}
369
+ <Flex gap={0} align="center">
370
+ <Typography variant="caption" className="text-neutral-500 w-20">Regular</Typography>
371
+ <Flex gap={2} className="w-40" justify="center">
372
+ <IconButton variant="primary" roundness="round" size="regular" icon={<Plus />} aria-label="Primary Regular Round" />
373
+ <IconButton variant="primary" roundness="round" size="regular" icon={<Plus />} aria-label="Primary Regular Round Disabled" disabled />
374
+ </Flex>
375
+ <Flex gap={2} className="w-40" justify="center">
376
+ <IconButton variant="secondary" roundness="round" size="regular" icon={<Plus />} aria-label="Secondary Regular Round" />
377
+ <IconButton variant="secondary" roundness="round" size="regular" icon={<Plus />} aria-label="Secondary Regular Round Disabled" disabled />
378
+ </Flex>
379
+ <Flex gap={2} className="w-40" justify="center">
380
+ <IconButton variant="outline" roundness="round" size="regular" icon={<Plus />} aria-label="Outline Regular Round" />
381
+ <IconButton variant="outline" roundness="round" size="regular" icon={<Plus />} aria-label="Outline Regular Round Disabled" disabled />
382
+ </Flex>
383
+ <Flex gap={2} className="w-40" justify="center">
384
+ <IconButton variant="ghost" roundness="round" size="regular" icon={<Plus />} aria-label="Ghost Regular Round" />
385
+ <IconButton variant="ghost" roundness="round" size="regular" icon={<Plus />} aria-label="Ghost Regular Round Disabled" disabled />
386
+ </Flex>
387
+ </Flex>
388
+
389
+ {/* Large Row */}
390
+ <Flex gap={0} align="center">
391
+ <Typography variant="caption" className="text-neutral-500 w-20">Large</Typography>
392
+ <Flex gap={2} className="w-40" justify="center">
393
+ <IconButton variant="primary" roundness="round" size="large" icon={<Plus />} aria-label="Primary Large Round" />
394
+ <IconButton variant="primary" roundness="round" size="large" icon={<Plus />} aria-label="Primary Large Round Disabled" disabled />
395
+ </Flex>
396
+ <Flex gap={2} className="w-40" justify="center">
397
+ <IconButton variant="secondary" roundness="round" size="large" icon={<Plus />} aria-label="Secondary Large Round" />
398
+ <IconButton variant="secondary" roundness="round" size="large" icon={<Plus />} aria-label="Secondary Large Round Disabled" disabled />
399
+ </Flex>
400
+ <Flex gap={2} className="w-40" justify="center">
401
+ <IconButton variant="outline" roundness="round" size="large" icon={<Plus />} aria-label="Outline Large Round" />
402
+ <IconButton variant="outline" roundness="round" size="large" icon={<Plus />} aria-label="Outline Large Round Disabled" disabled />
403
+ </Flex>
404
+ <Flex gap={2} className="w-40" justify="center">
405
+ <IconButton variant="ghost" roundness="round" size="large" icon={<Plus />} aria-label="Ghost Large Round" />
406
+ <IconButton variant="ghost" roundness="round" size="large" icon={<Plus />} aria-label="Ghost Large Round Disabled" disabled />
407
+ </Flex>
408
+ </Flex>
409
+
410
+ {/* Small Row */}
411
+ <Flex gap={0} align="center">
412
+ <Typography variant="caption" className="text-neutral-500 w-20">Small</Typography>
413
+ <Flex gap={2} className="w-40" justify="center">
414
+ <IconButton variant="primary" roundness="round" size="small" icon={<Plus />} aria-label="Primary Small Round" />
415
+ <IconButton variant="primary" roundness="round" size="small" icon={<Plus />} aria-label="Primary Small Round Disabled" disabled />
416
+ </Flex>
417
+ <Flex gap={2} className="w-40" justify="center">
418
+ <IconButton variant="secondary" roundness="round" size="small" icon={<Plus />} aria-label="Secondary Small Round" />
419
+ <IconButton variant="secondary" roundness="round" size="small" icon={<Plus />} aria-label="Secondary Small Round Disabled" disabled />
420
+ </Flex>
421
+ <Flex gap={2} className="w-40" justify="center">
422
+ <IconButton variant="outline" roundness="round" size="small" icon={<Plus />} aria-label="Outline Small Round" />
423
+ <IconButton variant="outline" roundness="round" size="small" icon={<Plus />} aria-label="Outline Small Round Disabled" disabled />
424
+ </Flex>
425
+ <Flex gap={2} className="w-40" justify="center">
426
+ <IconButton variant="ghost" roundness="round" size="small" icon={<Plus />} aria-label="Ghost Small Round" />
427
+ <IconButton variant="ghost" roundness="round" size="small" icon={<Plus />} aria-label="Ghost Small Round Disabled" disabled />
428
+ </Flex>
429
+ </Flex>
430
+
431
+ {/* Mini Row */}
432
+ <Flex gap={0} align="center">
433
+ <Typography variant="caption" className="text-neutral-500 w-20">Mini</Typography>
434
+ <Flex gap={2} className="w-40" justify="center">
435
+ <IconButton variant="primary" roundness="round" size="mini" icon={<Plus />} aria-label="Primary Mini Round" />
436
+ <IconButton variant="primary" roundness="round" size="mini" icon={<Plus />} aria-label="Primary Mini Round Disabled" disabled />
437
+ </Flex>
438
+ <Flex gap={2} className="w-40" justify="center">
439
+ <IconButton variant="secondary" roundness="round" size="mini" icon={<Plus />} aria-label="Secondary Mini Round" />
440
+ <IconButton variant="secondary" roundness="round" size="mini" icon={<Plus />} aria-label="Secondary Mini Round Disabled" disabled />
441
+ </Flex>
442
+ <Flex gap={2} className="w-40" justify="center">
443
+ <IconButton variant="outline" roundness="round" size="mini" icon={<Plus />} aria-label="Outline Mini Round" />
444
+ <IconButton variant="outline" roundness="round" size="mini" icon={<Plus />} aria-label="Outline Mini Round Disabled" disabled />
445
+ </Flex>
446
+ <Flex gap={2} className="w-40" justify="center">
447
+ <IconButton variant="ghost" roundness="round" size="mini" icon={<Plus />} aria-label="Ghost Mini Round" />
448
+ <IconButton variant="ghost" roundness="round" size="mini" icon={<Plus />} aria-label="Ghost Mini Round Disabled" disabled />
449
+ </Flex>
450
+ </Flex>
451
+ </Flex>
452
+ </Flex>
453
+
454
+ {/* Examples Section - matching Figma "Sizes" and "Round" */}
455
+ <Flex direction="column" gap={4}>
456
+ <Typography variant="h4" className="text-white">Examples</Typography>
457
+
458
+ <Flex gap={16}>
459
+ {/* Sizes Column */}
460
+ <Flex direction="column" gap={4}>
461
+ <Typography variant="body2" className="text-neutral-400">Sizes</Typography>
462
+ {/* Regular row */}
463
+ <Flex gap={3} align="center">
464
+ <IconButton variant="primary" size="regular" icon={<Plus />} aria-label="Add" />
465
+ <IconButton variant="secondary" size="regular" icon={<Pencil />} aria-label="Edit" />
466
+ <IconButton variant="outline" size="regular" icon={<Filter />} aria-label="Filter" />
467
+ <IconButton variant="ghost" size="regular" icon={<MoreVertical />} aria-label="More" />
468
+ <IconButton variant="ghost" size="regular" icon={<MoreHorizontal />} aria-label="More" />
469
+ <IconButton variant="outline" size="regular" icon={<Trash2 />} aria-label="Delete" className="text-red-500 border-red-500 hover:bg-red-50" />
470
+ </Flex>
471
+ {/* Large row */}
472
+ <Flex gap={3} align="center">
473
+ <IconButton variant="primary" size="large" icon={<Plus />} aria-label="Add" />
474
+ <IconButton variant="secondary" size="large" icon={<Pencil />} aria-label="Edit" />
475
+ <IconButton variant="outline" size="large" icon={<Filter />} aria-label="Filter" />
476
+ <IconButton variant="ghost" size="large" icon={<MoreVertical />} aria-label="More" />
477
+ <IconButton variant="ghost" size="large" icon={<MoreHorizontal />} aria-label="More" />
478
+ <IconButton variant="outline" size="large" icon={<Trash2 />} aria-label="Delete" className="text-red-500 border-red-500 hover:bg-red-50" />
479
+ </Flex>
480
+ {/* Small row */}
481
+ <Flex gap={3} align="center">
482
+ <IconButton variant="primary" size="small" icon={<Plus />} aria-label="Add" />
483
+ <IconButton variant="secondary" size="small" icon={<Pencil />} aria-label="Edit" />
484
+ <IconButton variant="outline" size="small" icon={<Filter />} aria-label="Filter" />
485
+ <IconButton variant="ghost" size="small" icon={<MoreVertical />} aria-label="More" />
486
+ <IconButton variant="ghost" size="small" icon={<MoreHorizontal />} aria-label="More" />
487
+ <IconButton variant="outline" size="small" icon={<Trash2 />} aria-label="Delete" className="text-red-500 border-red-500 hover:bg-red-50" />
488
+ </Flex>
489
+ {/* Mini row */}
490
+ <Flex gap={3} align="center">
491
+ <IconButton variant="primary" size="mini" icon={<Plus />} aria-label="Add" />
492
+ <IconButton variant="secondary" size="mini" icon={<Pencil />} aria-label="Edit" />
493
+ <IconButton variant="outline" size="mini" icon={<Filter />} aria-label="Filter" />
494
+ <IconButton variant="ghost" size="mini" icon={<MoreVertical />} aria-label="More" />
495
+ <IconButton variant="ghost" size="mini" icon={<MoreHorizontal />} aria-label="More" />
496
+ <IconButton variant="outline" size="mini" icon={<Trash2 />} aria-label="Delete" className="text-red-500 border-red-500 hover:bg-red-50" />
497
+ </Flex>
498
+ </Flex>
499
+
500
+ {/* Round Column */}
501
+ <Flex direction="column" gap={4}>
502
+ <Typography variant="body2" className="text-neutral-400">Round</Typography>
503
+ {/* Regular row */}
504
+ <Flex gap={3} align="center">
505
+ <IconButton variant="primary" roundness="round" size="regular" icon={<Plus />} aria-label="Add" />
506
+ <IconButton variant="secondary" roundness="round" size="regular" icon={<Pencil />} aria-label="Edit" />
507
+ <IconButton variant="outline" roundness="round" size="regular" icon={<Filter />} aria-label="Filter" />
508
+ <IconButton variant="ghost" roundness="round" size="regular" icon={<MoreVertical />} aria-label="More" />
509
+ <IconButton variant="ghost" roundness="round" size="regular" icon={<MoreHorizontal />} aria-label="More" />
510
+ <IconButton variant="outline" roundness="round" size="regular" icon={<Trash2 />} aria-label="Delete" className="text-red-500 border-red-500 hover:bg-red-50" />
511
+ </Flex>
512
+ {/* Large row */}
513
+ <Flex gap={3} align="center">
514
+ <IconButton variant="primary" roundness="round" size="large" icon={<Plus />} aria-label="Add" />
515
+ <IconButton variant="secondary" roundness="round" size="large" icon={<Pencil />} aria-label="Edit" />
516
+ <IconButton variant="outline" roundness="round" size="large" icon={<Filter />} aria-label="Filter" />
517
+ <IconButton variant="ghost" roundness="round" size="large" icon={<MoreVertical />} aria-label="More" />
518
+ <IconButton variant="ghost" roundness="round" size="large" icon={<MoreHorizontal />} aria-label="More" />
519
+ <IconButton variant="outline" roundness="round" size="large" icon={<Trash2 />} aria-label="Delete" className="text-red-500 border-red-500 hover:bg-red-50" />
520
+ </Flex>
521
+ {/* Small row */}
522
+ <Flex gap={3} align="center">
523
+ <IconButton variant="primary" roundness="round" size="small" icon={<Plus />} aria-label="Add" />
524
+ <IconButton variant="secondary" roundness="round" size="small" icon={<Pencil />} aria-label="Edit" />
525
+ <IconButton variant="outline" roundness="round" size="small" icon={<Filter />} aria-label="Filter" />
526
+ <IconButton variant="ghost" roundness="round" size="small" icon={<MoreVertical />} aria-label="More" />
527
+ <IconButton variant="ghost" roundness="round" size="small" icon={<MoreHorizontal />} aria-label="More" />
528
+ <IconButton variant="outline" roundness="round" size="small" icon={<Trash2 />} aria-label="Delete" className="text-red-500 border-red-500 hover:bg-red-50" />
529
+ </Flex>
530
+ {/* Mini row */}
531
+ <Flex gap={3} align="center">
532
+ <IconButton variant="primary" roundness="round" size="mini" icon={<Plus />} aria-label="Add" />
533
+ <IconButton variant="secondary" roundness="round" size="mini" icon={<Pencil />} aria-label="Edit" />
534
+ <IconButton variant="outline" roundness="round" size="mini" icon={<Filter />} aria-label="Filter" />
535
+ <IconButton variant="ghost" roundness="round" size="mini" icon={<MoreVertical />} aria-label="More" />
536
+ <IconButton variant="ghost" roundness="round" size="mini" icon={<MoreHorizontal />} aria-label="More" />
537
+ <IconButton variant="outline" roundness="round" size="mini" icon={<Trash2 />} aria-label="Delete" className="text-red-500 border-red-500 hover:bg-red-50" />
538
+ </Flex>
539
+ </Flex>
540
+ </Flex>
541
+ </Flex>
542
+ </Flex>
543
+ ),
544
+ parameters: {
545
+ docs: {
546
+ source: {
547
+ code: `// Primary variants
548
+ <IconButton variant="primary" icon={<Plus />} aria-label="Add" />
549
+ <IconButton variant="primary" size="large" icon={<Plus />} aria-label="Add" />
550
+ <IconButton variant="primary" roundness="round" icon={<Plus />} aria-label="Add" />
551
+
552
+ // Secondary variants
553
+ <IconButton variant="secondary" icon={<Pencil />} aria-label="Edit" />
554
+
555
+ // Outline variants
556
+ <IconButton variant="outline" icon={<Filter />} aria-label="Filter" />
557
+
558
+ // Ghost variants
559
+ <IconButton variant="ghost" icon={<MoreVertical />} aria-label="More" />
560
+
561
+ // Disabled
562
+ <IconButton disabled icon={<Plus />} aria-label="Add" />`,
563
+ },
564
+ },
565
+ },
566
+ }
@@ -0,0 +1,95 @@
1
+ import * as React from "react"
2
+ import { Slot } from "@radix-ui/react-slot"
3
+ import { cva } from "class-variance-authority"
4
+
5
+ import { cn } from "../lib/utils"
6
+
7
+ type IconButtonVariant = "primary" | "secondary" | "outline" | "ghost"
8
+ type IconButtonSize = "mini" | "small" | "regular" | "large"
9
+ type IconButtonRoundness = "default" | "round"
10
+
11
+ const iconButtonVariants = cva(
12
+ "inline-flex items-center justify-center shrink-0 cursor-pointer transition-colors focus-visible:outline-none focus-visible:shadow-[0_0_0_3px_#d4d4d4] disabled:pointer-events-none disabled:opacity-50 disabled:cursor-not-allowed [&_svg]:pointer-events-none [&_svg]:shrink-0",
13
+ {
14
+ variants: {
15
+ variant: {
16
+ primary: "bg-main-950 text-main-50 hover:bg-main-800",
17
+ secondary: "bg-main-100 text-main-950 hover:bg-main-200",
18
+ outline:
19
+ "border border-main-300 bg-transparent text-main-950 hover:bg-main-100",
20
+ ghost: "bg-transparent text-main-600 hover:bg-main-100 hover:text-main-950",
21
+ },
22
+ size: {
23
+ mini: "size-6 [&_svg]:size-3",
24
+ small: "size-8 [&_svg]:size-4",
25
+ regular: "size-9 [&_svg]:size-4",
26
+ large: "size-10 [&_svg]:size-5",
27
+ },
28
+ roundness: {
29
+ default: "rounded-lg",
30
+ round: "rounded-full",
31
+ },
32
+ },
33
+ compoundVariants: [
34
+ {
35
+ size: "mini",
36
+ roundness: "default",
37
+ className: "rounded-md",
38
+ },
39
+ {
40
+ size: "small",
41
+ roundness: "default",
42
+ className: "rounded-md",
43
+ },
44
+ ],
45
+ defaultVariants: {
46
+ variant: "primary",
47
+ size: "regular",
48
+ roundness: "default",
49
+ },
50
+ }
51
+ )
52
+
53
+ export interface IconButtonProps
54
+ extends React.ButtonHTMLAttributes<HTMLButtonElement> {
55
+ variant?: IconButtonVariant
56
+ size?: IconButtonSize
57
+ roundness?: IconButtonRoundness
58
+ /** Use the Slot component to render a different element */
59
+ asChild?: boolean
60
+ /** The icon to render inside the button */
61
+ icon?: React.ReactNode
62
+ /** Accessible label for screen readers */
63
+ "aria-label": string
64
+ }
65
+
66
+ const IconButton = React.forwardRef<HTMLButtonElement, IconButtonProps>(
67
+ (
68
+ {
69
+ className,
70
+ variant,
71
+ size,
72
+ roundness,
73
+ asChild = false,
74
+ icon,
75
+ children,
76
+ ...props
77
+ },
78
+ ref
79
+ ) => {
80
+ const Comp = asChild ? Slot : "button"
81
+ return (
82
+ <Comp
83
+ className={cn(iconButtonVariants({ variant, size, roundness, className }))}
84
+ ref={ref}
85
+ {...props}
86
+ >
87
+ {icon || children}
88
+ </Comp>
89
+ )
90
+ }
91
+ )
92
+ IconButton.displayName = "IconButton"
93
+
94
+ export { IconButton, iconButtonVariants }
95
+ export type { IconButtonVariant, IconButtonSize, IconButtonRoundness }