@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,241 @@
1
+ import * as React from "react"
2
+ import * as AlertDialogPrimitive from "@radix-ui/react-alert-dialog"
3
+ import { X, Loader2 } from "lucide-react"
4
+ import { cva } from "class-variance-authority"
5
+ import { Button } from "../Button/Button"
6
+ import { cn } from "../lib/utils"
7
+
8
+ type AlertDialogContentType = "desktop" | "mobile"
9
+ type AlertDialogHeaderType = "header" | "close-only" | "icon-button-close"
10
+ type AlertDialogFooterType = "buttons-right" | "full-width" | "single-full-width"
11
+ type AlertDialogCloseButtonVariant = "default" | "icon-button"
12
+
13
+ const AlertDialog = AlertDialogPrimitive.Root
14
+
15
+ const AlertDialogTrigger = AlertDialogPrimitive.Trigger
16
+
17
+ const AlertDialogPortal = AlertDialogPrimitive.Portal
18
+
19
+ const AlertDialogOverlay = React.forwardRef<
20
+ React.ElementRef<typeof AlertDialogPrimitive.Overlay>,
21
+ React.ComponentPropsWithoutRef<typeof AlertDialogPrimitive.Overlay>
22
+ >(({ className, ...props }, ref) => (
23
+ <AlertDialogPrimitive.Overlay
24
+ ref={ref}
25
+ className={cn(
26
+ "fixed inset-0 z-50 bg-black/50 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
27
+ className
28
+ )}
29
+ {...props}
30
+ />
31
+ ))
32
+ AlertDialogOverlay.displayName = AlertDialogPrimitive.Overlay.displayName
33
+
34
+ const alertDialogContentVariants = cva(
35
+ "fixed z-50 grid gap-4 bg-white border border-grey-200 shadow-lg duration-200 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",
36
+ {
37
+ variants: {
38
+ type: {
39
+ desktop: "left-[50%] top-[50%] translate-x-[-50%] translate-y-[-50%] w-full max-w-[640px] rounded-lg",
40
+ mobile: "left-[50%] top-[50%] translate-x-[-50%] translate-y-[-50%] w-full max-w-[320px] rounded-lg",
41
+ },
42
+ scrollable: {
43
+ true: "max-h-[80vh] overflow-y-auto",
44
+ false: "",
45
+ },
46
+ },
47
+ defaultVariants: {
48
+ type: "desktop",
49
+ scrollable: false,
50
+ },
51
+ }
52
+ )
53
+
54
+ export interface AlertDialogContentProps
55
+ extends React.ComponentPropsWithoutRef<typeof AlertDialogPrimitive.Content> {
56
+ type?: AlertDialogContentType
57
+ scrollable?: boolean
58
+ showCloseButton?: boolean
59
+ closeButtonVariant?: AlertDialogCloseButtonVariant
60
+ loading?: boolean
61
+ }
62
+
63
+ const AlertDialogContent = React.forwardRef<
64
+ React.ElementRef<typeof AlertDialogPrimitive.Content>,
65
+ AlertDialogContentProps
66
+ >(({ className, children, type, scrollable, showCloseButton = true, closeButtonVariant = "default", loading = false, ...props }, ref) => (
67
+ <AlertDialogPortal>
68
+ <AlertDialogOverlay />
69
+ <AlertDialogPrimitive.Content
70
+ ref={ref}
71
+ className={cn(alertDialogContentVariants({ type, scrollable, className }))}
72
+ {...props}
73
+ >
74
+ {loading && (
75
+ <div className="absolute inset-0 z-10 flex items-center justify-center bg-white/80 rounded-lg">
76
+ <Loader2 className="size-8 text-main-600 animate-spin" />
77
+ </div>
78
+ )}
79
+ {children}
80
+ {showCloseButton && closeButtonVariant === "default" && !loading && (
81
+ <AlertDialogPrimitive.Cancel className="absolute right-4 top-4 rounded-sm opacity-70 transition-opacity hover:opacity-100 focus:outline-none focus:shadow-[0_0_0_3px_#d4d4d4] disabled:pointer-events-none cursor-pointer">
82
+ <X className="size-4 text-grey-600" />
83
+ <span className="sr-only">Close</span>
84
+ </AlertDialogPrimitive.Cancel>
85
+ )}
86
+ {showCloseButton && closeButtonVariant === "icon-button" && !loading && (
87
+ <AlertDialogPrimitive.Cancel asChild>
88
+ <Button
89
+ variant="ghost"
90
+ size="small"
91
+ className="absolute right-2 top-2 size-9 p-0"
92
+ >
93
+ <X className="size-4" />
94
+ <span className="sr-only">Close</span>
95
+ </Button>
96
+ </AlertDialogPrimitive.Cancel>
97
+ )}
98
+ </AlertDialogPrimitive.Content>
99
+ </AlertDialogPortal>
100
+ ))
101
+ AlertDialogContent.displayName = AlertDialogPrimitive.Content.displayName
102
+
103
+ const alertDialogHeaderVariants = cva(
104
+ "flex p-4",
105
+ {
106
+ variants: {
107
+ type: {
108
+ header: "flex-row items-center justify-between",
109
+ "close-only": "flex-col items-end",
110
+ "icon-button-close": "flex-col items-end justify-center pr-0",
111
+ },
112
+ },
113
+ defaultVariants: {
114
+ type: "header",
115
+ },
116
+ }
117
+ )
118
+
119
+ export interface AlertDialogHeaderProps
120
+ extends React.HTMLAttributes<HTMLDivElement> {
121
+ type?: AlertDialogHeaderType
122
+ }
123
+
124
+ const AlertDialogHeader = React.forwardRef<HTMLDivElement, AlertDialogHeaderProps>(
125
+ ({ className, type, ...props }, ref) => (
126
+ <div
127
+ ref={ref}
128
+ className={cn(alertDialogHeaderVariants({ type, className }))}
129
+ {...props}
130
+ />
131
+ )
132
+ )
133
+ AlertDialogHeader.displayName = "AlertDialogHeader"
134
+
135
+ const alertDialogFooterVariants = cva(
136
+ "flex gap-2 p-4",
137
+ {
138
+ variants: {
139
+ type: {
140
+ "buttons-right": "flex-row items-center justify-end",
141
+ "full-width": "flex-row items-start",
142
+ "single-full-width": "flex-row items-start",
143
+ },
144
+ },
145
+ defaultVariants: {
146
+ type: "buttons-right",
147
+ },
148
+ }
149
+ )
150
+
151
+ export interface AlertDialogFooterProps
152
+ extends React.HTMLAttributes<HTMLDivElement> {
153
+ type?: AlertDialogFooterType
154
+ }
155
+
156
+ const AlertDialogFooter = React.forwardRef<HTMLDivElement, AlertDialogFooterProps>(
157
+ ({ className, type, children, ...props }, ref) => (
158
+ <div
159
+ ref={ref}
160
+ className={cn(alertDialogFooterVariants({ type, className }))}
161
+ {...props}
162
+ >
163
+ {type === "full-width" || type === "single-full-width" ? (
164
+ <div className="flex gap-2 w-full">
165
+ {React.Children.map(children, (child) =>
166
+ React.isValidElement(child)
167
+ ? React.cloneElement(child as React.ReactElement<{ className?: string }>, {
168
+ className: cn("flex-1", (child as React.ReactElement<{ className?: string }>).props.className),
169
+ })
170
+ : child
171
+ )}
172
+ </div>
173
+ ) : (
174
+ children
175
+ )}
176
+ </div>
177
+ )
178
+ )
179
+ AlertDialogFooter.displayName = "AlertDialogFooter"
180
+
181
+ const AlertDialogTitle = React.forwardRef<
182
+ React.ElementRef<typeof AlertDialogPrimitive.Title>,
183
+ React.ComponentPropsWithoutRef<typeof AlertDialogPrimitive.Title>
184
+ >(({ className, ...props }, ref) => (
185
+ <AlertDialogPrimitive.Title
186
+ ref={ref}
187
+ className={cn(
188
+ "text-2xl font-bold leading-[1.2] tracking-tight text-main-950 font-display",
189
+ className
190
+ )}
191
+ {...props}
192
+ />
193
+ ))
194
+ AlertDialogTitle.displayName = AlertDialogPrimitive.Title.displayName
195
+
196
+ const AlertDialogDescription = React.forwardRef<
197
+ React.ElementRef<typeof AlertDialogPrimitive.Description>,
198
+ React.ComponentPropsWithoutRef<typeof AlertDialogPrimitive.Description>
199
+ >(({ className, ...props }, ref) => (
200
+ <AlertDialogPrimitive.Description
201
+ ref={ref}
202
+ className={cn("text-sm text-grey-600", className)}
203
+ {...props}
204
+ />
205
+ ))
206
+ AlertDialogDescription.displayName = AlertDialogPrimitive.Description.displayName
207
+
208
+ const AlertDialogBody = React.forwardRef<
209
+ HTMLDivElement,
210
+ React.HTMLAttributes<HTMLDivElement>
211
+ >(({ className, ...props }, ref) => (
212
+ <div
213
+ ref={ref}
214
+ className={cn("flex-1 px-4 py-2", className)}
215
+ {...props}
216
+ />
217
+ ))
218
+ AlertDialogBody.displayName = "AlertDialogBody"
219
+
220
+ const AlertDialogAction = AlertDialogPrimitive.Action
221
+
222
+ const AlertDialogCancel = AlertDialogPrimitive.Cancel
223
+
224
+ export {
225
+ AlertDialog,
226
+ AlertDialogPortal,
227
+ AlertDialogOverlay,
228
+ AlertDialogTrigger,
229
+ AlertDialogContent,
230
+ AlertDialogHeader,
231
+ AlertDialogFooter,
232
+ AlertDialogTitle,
233
+ AlertDialogDescription,
234
+ AlertDialogBody,
235
+ AlertDialogAction,
236
+ AlertDialogCancel,
237
+ alertDialogContentVariants,
238
+ alertDialogHeaderVariants,
239
+ alertDialogFooterVariants,
240
+ }
241
+ export type { AlertDialogContentType, AlertDialogHeaderType, AlertDialogFooterType, AlertDialogCloseButtonVariant }
@@ -0,0 +1,128 @@
1
+ import type { Meta, StoryObj } from "@storybook/react"
2
+
3
+ import { Flex } from "../Flex/Flex"
4
+ import { Typography } from "../Typography/Typography"
5
+ import { Avatar, AvatarImage, AvatarFallback } from "./Avatar"
6
+
7
+ const meta: Meta<typeof Avatar> = {
8
+ title: "Components/Avatar",
9
+ component: Avatar,
10
+ parameters: {
11
+ layout: "centered",
12
+ },
13
+ argTypes: {
14
+ size: {
15
+ control: "select",
16
+ options: ["small", "regular", "large", "xlarge"],
17
+ description: "The size of the avatar",
18
+ },
19
+ },
20
+ tags: ["autodocs"],
21
+ }
22
+
23
+ export default meta
24
+ type Story = StoryObj<typeof meta>
25
+
26
+ export const Default: Story = {
27
+ render: () => (
28
+ <Avatar>
29
+ <AvatarImage src="https://github.com/shadcn.png" alt="@shadcn" />
30
+ <AvatarFallback>CN</AvatarFallback>
31
+ </Avatar>
32
+ ),
33
+ }
34
+
35
+ export const WithFallback: Story = {
36
+ render: () => (
37
+ <Avatar>
38
+ <AvatarImage src="https://invalid-url.com/avatar.png" alt="User" />
39
+ <AvatarFallback>JD</AvatarFallback>
40
+ </Avatar>
41
+ ),
42
+ }
43
+
44
+ export const Small: Story = {
45
+ render: () => (
46
+ <Avatar size="small">
47
+ <AvatarImage src="https://github.com/shadcn.png" alt="@shadcn" />
48
+ <AvatarFallback>CN</AvatarFallback>
49
+ </Avatar>
50
+ ),
51
+ }
52
+
53
+ export const Large: Story = {
54
+ render: () => (
55
+ <Avatar size="large">
56
+ <AvatarImage src="https://github.com/shadcn.png" alt="@shadcn" />
57
+ <AvatarFallback>CN</AvatarFallback>
58
+ </Avatar>
59
+ ),
60
+ }
61
+
62
+ export const XLarge: Story = {
63
+ render: () => (
64
+ <Avatar size="xlarge">
65
+ <AvatarImage src="https://github.com/shadcn.png" alt="@shadcn" />
66
+ <AvatarFallback>CN</AvatarFallback>
67
+ </Avatar>
68
+ ),
69
+ }
70
+
71
+ export const AllVariants: Story = {
72
+ render: () => (
73
+ <Flex direction="column" gap={6}>
74
+ <Typography variant="h4" className="text-white">Avatar Sizes</Typography>
75
+
76
+ <Flex gap={4} align="center">
77
+ <Flex direction="column" align="center" gap={2}>
78
+ <Avatar size="small">
79
+ <AvatarImage src="https://github.com/shadcn.png" alt="@shadcn" />
80
+ <AvatarFallback>CN</AvatarFallback>
81
+ </Avatar>
82
+ <Typography variant="caption" className="text-grey-400">Small</Typography>
83
+ </Flex>
84
+
85
+ <Flex direction="column" align="center" gap={2}>
86
+ <Avatar size="regular">
87
+ <AvatarImage src="https://github.com/shadcn.png" alt="@shadcn" />
88
+ <AvatarFallback>CN</AvatarFallback>
89
+ </Avatar>
90
+ <Typography variant="caption" className="text-grey-400">Regular</Typography>
91
+ </Flex>
92
+
93
+ <Flex direction="column" align="center" gap={2}>
94
+ <Avatar size="large">
95
+ <AvatarImage src="https://github.com/shadcn.png" alt="@shadcn" />
96
+ <AvatarFallback>CN</AvatarFallback>
97
+ </Avatar>
98
+ <Typography variant="caption" className="text-grey-400">Large</Typography>
99
+ </Flex>
100
+
101
+ <Flex direction="column" align="center" gap={2}>
102
+ <Avatar size="xlarge">
103
+ <AvatarImage src="https://github.com/shadcn.png" alt="@shadcn" />
104
+ <AvatarFallback>CN</AvatarFallback>
105
+ </Avatar>
106
+ <Typography variant="caption" className="text-grey-400">XLarge</Typography>
107
+ </Flex>
108
+ </Flex>
109
+
110
+ <Typography variant="h4" className="text-white mt-4">Fallback Examples</Typography>
111
+
112
+ <Flex gap={4} align="center">
113
+ <Avatar>
114
+ <AvatarFallback>JD</AvatarFallback>
115
+ </Avatar>
116
+ <Avatar>
117
+ <AvatarFallback>AB</AvatarFallback>
118
+ </Avatar>
119
+ <Avatar>
120
+ <AvatarFallback>MK</AvatarFallback>
121
+ </Avatar>
122
+ <Avatar>
123
+ <AvatarFallback>ZY</AvatarFallback>
124
+ </Avatar>
125
+ </Flex>
126
+ </Flex>
127
+ ),
128
+ }
@@ -0,0 +1,71 @@
1
+ import * as React from "react"
2
+ import * as AvatarPrimitive from "@radix-ui/react-avatar"
3
+ import { cva } from "class-variance-authority"
4
+
5
+ import { cn } from "../lib/utils"
6
+
7
+ type AvatarSize = "small" | "regular" | "large" | "xlarge"
8
+
9
+ const avatarVariants = cva(
10
+ "relative flex shrink-0 overflow-hidden rounded-full",
11
+ {
12
+ variants: {
13
+ size: {
14
+ small: "size-8",
15
+ regular: "size-10",
16
+ large: "size-12",
17
+ xlarge: "size-16",
18
+ },
19
+ },
20
+ defaultVariants: {
21
+ size: "regular",
22
+ },
23
+ }
24
+ )
25
+
26
+ export interface AvatarProps
27
+ extends React.ComponentPropsWithoutRef<typeof AvatarPrimitive.Root> {
28
+ size?: AvatarSize
29
+ }
30
+
31
+ const Avatar = React.forwardRef<
32
+ React.ElementRef<typeof AvatarPrimitive.Root>,
33
+ AvatarProps
34
+ >(({ className, size, ...props }, ref) => (
35
+ <AvatarPrimitive.Root
36
+ ref={ref}
37
+ className={cn(avatarVariants({ size }), className)}
38
+ {...props}
39
+ />
40
+ ))
41
+ Avatar.displayName = AvatarPrimitive.Root.displayName
42
+
43
+ const AvatarImage = React.forwardRef<
44
+ React.ElementRef<typeof AvatarPrimitive.Image>,
45
+ React.ComponentPropsWithoutRef<typeof AvatarPrimitive.Image>
46
+ >(({ className, ...props }, ref) => (
47
+ <AvatarPrimitive.Image
48
+ ref={ref}
49
+ className={cn("aspect-square h-full w-full", className)}
50
+ {...props}
51
+ />
52
+ ))
53
+ AvatarImage.displayName = AvatarPrimitive.Image.displayName
54
+
55
+ const AvatarFallback = React.forwardRef<
56
+ React.ElementRef<typeof AvatarPrimitive.Fallback>,
57
+ React.ComponentPropsWithoutRef<typeof AvatarPrimitive.Fallback>
58
+ >(({ className, ...props }, ref) => (
59
+ <AvatarPrimitive.Fallback
60
+ ref={ref}
61
+ className={cn(
62
+ "flex h-full w-full items-center justify-center rounded-full bg-grey-100 text-grey-600 font-medium",
63
+ className
64
+ )}
65
+ {...props}
66
+ />
67
+ ))
68
+ AvatarFallback.displayName = AvatarPrimitive.Fallback.displayName
69
+
70
+ export { Avatar, AvatarImage, AvatarFallback, avatarVariants }
71
+ export type { AvatarSize }
@@ -0,0 +1,76 @@
1
+ import type { Meta, StoryObj } from "@storybook/react"
2
+
3
+ import { Flex } from "../Flex/Flex"
4
+ import { Typography } from "../Typography/Typography"
5
+ import { Badge } from "./Badge"
6
+
7
+ const meta: Meta<typeof Badge> = {
8
+ title: "Components/Badge",
9
+ component: Badge,
10
+ parameters: {
11
+ layout: "centered",
12
+ },
13
+ argTypes: {
14
+ variant: {
15
+ control: "select",
16
+ options: ["default", "secondary", "outline", "destructive", "success", "warning"],
17
+ description: "The visual variant of the badge",
18
+ },
19
+ },
20
+ tags: ["autodocs"],
21
+ }
22
+
23
+ export default meta
24
+ type Story = StoryObj<typeof meta>
25
+
26
+ export const Default: Story = {
27
+ render: () => <Badge>Badge</Badge>,
28
+ }
29
+
30
+ export const Secondary: Story = {
31
+ render: () => <Badge variant="secondary">Secondary</Badge>,
32
+ }
33
+
34
+ export const Outline: Story = {
35
+ render: () => <Badge variant="outline">Outline</Badge>,
36
+ }
37
+
38
+ export const Destructive: Story = {
39
+ render: () => <Badge variant="destructive">Destructive</Badge>,
40
+ }
41
+
42
+ export const Success: Story = {
43
+ render: () => <Badge variant="success">Success</Badge>,
44
+ }
45
+
46
+ export const Warning: Story = {
47
+ render: () => <Badge variant="warning">Warning</Badge>,
48
+ }
49
+
50
+ export const AllVariants: Story = {
51
+ render: () => (
52
+ <Flex direction="column" gap={6}>
53
+ <Typography variant="h4" className="text-white">Badge Variants</Typography>
54
+
55
+ <Flex gap={3} align="center" wrap="wrap">
56
+ <Badge>Default</Badge>
57
+ <Badge variant="secondary">Secondary</Badge>
58
+ <Badge variant="outline">Outline</Badge>
59
+ <Badge variant="destructive">Destructive</Badge>
60
+ <Badge variant="success">Success</Badge>
61
+ <Badge variant="warning">Warning</Badge>
62
+ </Flex>
63
+
64
+ <Typography variant="h4" className="text-white mt-4">Use Cases</Typography>
65
+
66
+ <Flex gap={3} align="center" wrap="wrap">
67
+ <Badge>New</Badge>
68
+ <Badge variant="secondary">Featured</Badge>
69
+ <Badge variant="success">Active</Badge>
70
+ <Badge variant="warning">Pending</Badge>
71
+ <Badge variant="destructive">Expired</Badge>
72
+ <Badge variant="outline">Draft</Badge>
73
+ </Flex>
74
+ </Flex>
75
+ ),
76
+ }
@@ -0,0 +1,39 @@
1
+ import * as React from "react"
2
+ import { cva } from "class-variance-authority"
3
+
4
+ import { cn } from "../lib/utils"
5
+
6
+ type BadgeVariant = "default" | "secondary" | "outline" | "destructive" | "success" | "warning"
7
+
8
+ const badgeVariants = cva(
9
+ "inline-flex items-center rounded-full border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-main-950 focus:ring-offset-2",
10
+ {
11
+ variants: {
12
+ variant: {
13
+ default: "border-transparent bg-main-950 text-main-50",
14
+ secondary: "border-transparent bg-grey-100 text-main-950",
15
+ outline: "border-grey-300 text-main-950",
16
+ destructive: "border-transparent bg-error-600 text-white",
17
+ success: "border-transparent bg-success-600 text-white",
18
+ warning: "border-transparent bg-warning-500 text-white",
19
+ },
20
+ },
21
+ defaultVariants: {
22
+ variant: "default",
23
+ },
24
+ }
25
+ )
26
+
27
+ export interface BadgeProps
28
+ extends React.HTMLAttributes<HTMLDivElement> {
29
+ variant?: BadgeVariant
30
+ }
31
+
32
+ function Badge({ className, variant, ...props }: BadgeProps) {
33
+ return (
34
+ <div className={cn(badgeVariants({ variant }), className)} {...props} />
35
+ )
36
+ }
37
+
38
+ export { Badge, badgeVariants }
39
+ export type { BadgeVariant }