@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.
- package/Alert/Alert.stories.tsx +121 -0
- package/Alert/Alert.tsx +71 -0
- package/AlertDialog/AlertDialog.stories.tsx +665 -0
- package/AlertDialog/AlertDialog.tsx +241 -0
- package/Avatar/Avatar.stories.tsx +128 -0
- package/Avatar/Avatar.tsx +71 -0
- package/Badge/Badge.stories.tsx +76 -0
- package/Badge/Badge.tsx +39 -0
- package/Breadcrumb/Breadcrumb.stories.tsx +231 -0
- package/Breadcrumb/Breadcrumb.tsx +114 -0
- package/Button/Button.stories.tsx +684 -0
- package/Button/Button.tsx +90 -0
- package/Calendar/Calendar.stories.tsx +207 -0
- package/Calendar/Calendar.tsx +232 -0
- package/Card/Card.stories.tsx +136 -0
- package/Card/Card.tsx +96 -0
- package/ChatBubble/ChatBubble.stories.tsx +307 -0
- package/ChatBubble/ChatBubble.tsx +167 -0
- package/Checkbox/Checkbox.stories.tsx +137 -0
- package/Checkbox/Checkbox.tsx +53 -0
- package/Drawer/Drawer.stories.tsx +721 -0
- package/Drawer/Drawer.tsx +201 -0
- package/DropdownMenu/DropdownMenu.stories.tsx +251 -0
- package/DropdownMenu/DropdownMenu.tsx +199 -0
- package/ErrorMessage/ErrorMessage.stories.tsx +159 -0
- package/ErrorMessage/ErrorMessage.tsx +55 -0
- package/Flex/Flex.tsx +102 -0
- package/IconButton/IconButton.stories.tsx +566 -0
- package/IconButton/IconButton.tsx +95 -0
- package/Input/Input.stories.tsx +456 -0
- package/Input/Input.tsx +129 -0
- package/InputOTP/InputOTP.stories.tsx +246 -0
- package/InputOTP/InputOTP.tsx +127 -0
- package/Label/Label.stories.tsx +105 -0
- package/Label/Label.tsx +43 -0
- package/Loader/Loader.stories.tsx +170 -0
- package/Loader/Loader.tsx +62 -0
- package/Popover/Popover.stories.tsx +133 -0
- package/Popover/Popover.tsx +31 -0
- package/Progress/Progress.stories.tsx +146 -0
- package/Progress/Progress.tsx +67 -0
- package/README.md +12 -12
- package/RadioGroup/RadioGroup.stories.tsx +159 -0
- package/RadioGroup/RadioGroup.tsx +68 -0
- package/ScrollArea/ScrollArea.stories.tsx +136 -0
- package/ScrollArea/ScrollArea.tsx +46 -0
- package/Select/Select.stories.tsx +242 -0
- package/Select/Select.tsx +180 -0
- package/Separator/Separator.stories.tsx +110 -0
- package/Separator/Separator.tsx +29 -0
- package/Skeleton/Skeleton.stories.tsx +117 -0
- package/Skeleton/Skeleton.tsx +16 -0
- package/Spinner/Spinner.stories.tsx +210 -0
- package/Spinner/Spinner.tsx +78 -0
- package/Switch/Switch.stories.tsx +146 -0
- package/Switch/Switch.tsx +59 -0
- package/Tabs/Tabs.stories.tsx +197 -0
- package/Tabs/Tabs.tsx +74 -0
- package/Textarea/Textarea.stories.tsx +170 -0
- package/Textarea/Textarea.tsx +51 -0
- package/Toast/Toast.stories.tsx +285 -0
- package/Toast/Toast.tsx +59 -0
- package/Tooltip/Tooltip.stories.tsx +463 -0
- package/Tooltip/Tooltip.tsx +96 -0
- package/Typography/Typography.stories.tsx +235 -0
- package/Typography/Typography.tsx +171 -0
- package/helpers.ts +5 -0
- package/icons.ts +2 -0
- package/index.ts +136 -0
- package/lib/utils.ts +15 -0
- package/package.json +4 -1
- package/tsconfig.json +24 -0
- package/Alert/Alert.d.ts +0 -11
- package/Alert/Alert.js +0 -64
- package/AlertDialog/AlertDialog.d.ts +0 -35
- package/AlertDialog/AlertDialog.js +0 -121
- package/Avatar/Avatar.d.ts +0 -12
- package/Avatar/Avatar.js +0 -64
- package/Badge/Badge.d.ts +0 -9
- package/Badge/Badge.js +0 -26
- package/Breadcrumb/Breadcrumb.d.ts +0 -19
- package/Breadcrumb/Breadcrumb.js +0 -65
- package/Button/Button.d.ts +0 -14
- package/Button/Button.js +0 -75
- package/Calendar/Calendar.d.ts +0 -16
- package/Calendar/Calendar.js +0 -113
- package/Card/Card.d.ts +0 -14
- package/Card/Card.js +0 -70
- package/ChatBubble/ChatBubble.d.ts +0 -29
- package/ChatBubble/ChatBubble.js +0 -133
- package/Checkbox/Checkbox.d.ts +0 -10
- package/Checkbox/Checkbox.js +0 -57
- package/Dialog/Dialog.d.ts +0 -35
- package/Dialog/Dialog.js +0 -130
- package/Drawer/Drawer.d.ts +0 -31
- package/Drawer/Drawer.js +0 -69
- package/DropdownMenu/DropdownMenu.d.ts +0 -27
- package/DropdownMenu/DropdownMenu.js +0 -85
- package/ErrorMessage/ErrorMessage.d.ts +0 -27
- package/ErrorMessage/ErrorMessage.js +0 -15
- package/Flex/Flex.d.ts +0 -23
- package/Flex/Flex.js +0 -101
- package/IconButton/IconButton.d.ts +0 -17
- package/IconButton/IconButton.js +0 -85
- package/Input/Input.d.ts +0 -16
- package/Input/Input.js +0 -75
- package/InputOTP/InputOTP.d.ts +0 -18
- package/InputOTP/InputOTP.js +0 -85
- package/Label/Label.d.ts +0 -10
- package/Label/Label.js +0 -57
- package/Loader/Loader.d.ts +0 -18
- package/Loader/Loader.js +0 -67
- package/Popover/Popover.d.ts +0 -7
- package/Popover/Popover.js +0 -49
- package/Progress/Progress.d.ts +0 -13
- package/Progress/Progress.js +0 -71
- package/RadioGroup/RadioGroup.d.ts +0 -11
- package/RadioGroup/RadioGroup.js +0 -64
- package/ScrollArea/ScrollArea.d.ts +0 -5
- package/ScrollArea/ScrollArea.js +0 -48
- package/Select/Select.d.ts +0 -19
- package/Select/Select.js +0 -85
- package/Separator/Separator.d.ts +0 -4
- package/Separator/Separator.js +0 -43
- package/Skeleton/Skeleton.d.ts +0 -4
- package/Skeleton/Skeleton.js +0 -8
- package/Spinner/Spinner.d.ts +0 -15
- package/Spinner/Spinner.js +0 -68
- package/Switch/Switch.d.ts +0 -10
- package/Switch/Switch.js +0 -67
- package/Tabs/Tabs.d.ts +0 -13
- package/Tabs/Tabs.js +0 -64
- package/Textarea/Textarea.d.ts +0 -10
- package/Textarea/Textarea.js +0 -64
- package/Toast/Toast.d.ts +0 -10
- package/Toast/Toast.js +0 -29
- package/Tooltip/Tooltip.d.ts +0 -15
- package/Tooltip/Tooltip.js +0 -68
- package/Typography/Typography.d.ts +0 -15
- package/Typography/Typography.js +0 -125
- package/helpers.d.ts +0 -4
- package/helpers.js +0 -13
- package/icons.d.ts +0 -1
- package/icons.js +0 -18
- package/index.d.ts +0 -35
- package/index.js +0 -183
- package/lib/utils.d.ts +0 -3
- 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
|
+
}
|
package/Badge/Badge.tsx
ADDED
|
@@ -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 }
|