@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
package/Card/Card.tsx
ADDED
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import * as React from "react"
|
|
2
|
+
import { cva } from "class-variance-authority"
|
|
3
|
+
|
|
4
|
+
import { cn } from "../lib/utils"
|
|
5
|
+
|
|
6
|
+
type CardVariant = "default" | "outline"
|
|
7
|
+
|
|
8
|
+
const cardVariants = cva(
|
|
9
|
+
"rounded-xl border bg-white text-main-950 shadow-sm",
|
|
10
|
+
{
|
|
11
|
+
variants: {
|
|
12
|
+
variant: {
|
|
13
|
+
default: "border-grey-200",
|
|
14
|
+
outline: "border-grey-300 shadow-none",
|
|
15
|
+
},
|
|
16
|
+
},
|
|
17
|
+
defaultVariants: {
|
|
18
|
+
variant: "default",
|
|
19
|
+
},
|
|
20
|
+
}
|
|
21
|
+
)
|
|
22
|
+
|
|
23
|
+
export interface CardProps
|
|
24
|
+
extends React.HTMLAttributes<HTMLDivElement> {
|
|
25
|
+
variant?: CardVariant
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const Card = React.forwardRef<HTMLDivElement, CardProps>(
|
|
29
|
+
({ className, variant, ...props }, ref) => (
|
|
30
|
+
<div
|
|
31
|
+
ref={ref}
|
|
32
|
+
className={cn(cardVariants({ variant }), className)}
|
|
33
|
+
{...props}
|
|
34
|
+
/>
|
|
35
|
+
)
|
|
36
|
+
)
|
|
37
|
+
Card.displayName = "Card"
|
|
38
|
+
|
|
39
|
+
const CardHeader = React.forwardRef<
|
|
40
|
+
HTMLDivElement,
|
|
41
|
+
React.HTMLAttributes<HTMLDivElement>
|
|
42
|
+
>(({ className, ...props }, ref) => (
|
|
43
|
+
<div
|
|
44
|
+
ref={ref}
|
|
45
|
+
className={cn("flex flex-col space-y-1.5 p-6", className)}
|
|
46
|
+
{...props}
|
|
47
|
+
/>
|
|
48
|
+
))
|
|
49
|
+
CardHeader.displayName = "CardHeader"
|
|
50
|
+
|
|
51
|
+
const CardTitle = React.forwardRef<
|
|
52
|
+
HTMLDivElement,
|
|
53
|
+
React.HTMLAttributes<HTMLDivElement>
|
|
54
|
+
>(({ className, ...props }, ref) => (
|
|
55
|
+
<div
|
|
56
|
+
ref={ref}
|
|
57
|
+
className={cn("font-semibold leading-none tracking-tight", className)}
|
|
58
|
+
{...props}
|
|
59
|
+
/>
|
|
60
|
+
))
|
|
61
|
+
CardTitle.displayName = "CardTitle"
|
|
62
|
+
|
|
63
|
+
const CardDescription = React.forwardRef<
|
|
64
|
+
HTMLDivElement,
|
|
65
|
+
React.HTMLAttributes<HTMLDivElement>
|
|
66
|
+
>(({ className, ...props }, ref) => (
|
|
67
|
+
<div
|
|
68
|
+
ref={ref}
|
|
69
|
+
className={cn("text-sm text-grey-500", className)}
|
|
70
|
+
{...props}
|
|
71
|
+
/>
|
|
72
|
+
))
|
|
73
|
+
CardDescription.displayName = "CardDescription"
|
|
74
|
+
|
|
75
|
+
const CardContent = React.forwardRef<
|
|
76
|
+
HTMLDivElement,
|
|
77
|
+
React.HTMLAttributes<HTMLDivElement>
|
|
78
|
+
>(({ className, ...props }, ref) => (
|
|
79
|
+
<div ref={ref} className={cn("p-6 pt-0", className)} {...props} />
|
|
80
|
+
))
|
|
81
|
+
CardContent.displayName = "CardContent"
|
|
82
|
+
|
|
83
|
+
const CardFooter = React.forwardRef<
|
|
84
|
+
HTMLDivElement,
|
|
85
|
+
React.HTMLAttributes<HTMLDivElement>
|
|
86
|
+
>(({ className, ...props }, ref) => (
|
|
87
|
+
<div
|
|
88
|
+
ref={ref}
|
|
89
|
+
className={cn("flex items-center p-6 pt-0", className)}
|
|
90
|
+
{...props}
|
|
91
|
+
/>
|
|
92
|
+
))
|
|
93
|
+
CardFooter.displayName = "CardFooter"
|
|
94
|
+
|
|
95
|
+
export { Card, CardHeader, CardFooter, CardTitle, CardDescription, CardContent, cardVariants }
|
|
96
|
+
export type { CardVariant }
|
|
@@ -0,0 +1,307 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from "@storybook/react"
|
|
2
|
+
import { Flex } from "../Flex/Flex"
|
|
3
|
+
import { Typography } from "../Typography/Typography"
|
|
4
|
+
import { ChatBubble } from "./ChatBubble"
|
|
5
|
+
|
|
6
|
+
const meta: Meta<typeof ChatBubble> = {
|
|
7
|
+
title: "Components/ChatBubble",
|
|
8
|
+
component: ChatBubble,
|
|
9
|
+
parameters: {
|
|
10
|
+
layout: "centered",
|
|
11
|
+
backgrounds: {
|
|
12
|
+
default: "dark",
|
|
13
|
+
values: [
|
|
14
|
+
{ name: "dark", value: "#1a1a1a" },
|
|
15
|
+
{ name: "light", value: "#ffffff" },
|
|
16
|
+
],
|
|
17
|
+
},
|
|
18
|
+
},
|
|
19
|
+
tags: ["autodocs"],
|
|
20
|
+
argTypes: {
|
|
21
|
+
side: {
|
|
22
|
+
control: "select",
|
|
23
|
+
options: ["left", "right"],
|
|
24
|
+
description: "The side of the chat bubble",
|
|
25
|
+
},
|
|
26
|
+
color: {
|
|
27
|
+
control: "select",
|
|
28
|
+
options: ["blue", "grey", "green"],
|
|
29
|
+
description: "The color variant of the bubble",
|
|
30
|
+
},
|
|
31
|
+
theme: {
|
|
32
|
+
control: "select",
|
|
33
|
+
options: ["dark", "light"],
|
|
34
|
+
description: "The theme variant",
|
|
35
|
+
},
|
|
36
|
+
size: {
|
|
37
|
+
control: "select",
|
|
38
|
+
options: ["small", "medium", "large", "xlarge"],
|
|
39
|
+
description: "The text size of the bubble",
|
|
40
|
+
},
|
|
41
|
+
label: {
|
|
42
|
+
control: "text",
|
|
43
|
+
description: "Label shown above the bubble",
|
|
44
|
+
},
|
|
45
|
+
showLabel: {
|
|
46
|
+
control: "boolean",
|
|
47
|
+
description: "Whether to show the label",
|
|
48
|
+
},
|
|
49
|
+
},
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export default meta
|
|
53
|
+
type Story = StoryObj<typeof ChatBubble>
|
|
54
|
+
|
|
55
|
+
export const Default: Story = {
|
|
56
|
+
args: {
|
|
57
|
+
side: "left",
|
|
58
|
+
color: "blue",
|
|
59
|
+
theme: "dark",
|
|
60
|
+
label: "Your name",
|
|
61
|
+
children: "Your message goes here",
|
|
62
|
+
},
|
|
63
|
+
decorators: [
|
|
64
|
+
(Story) => (
|
|
65
|
+
<Flex className="w-[400px]">
|
|
66
|
+
<Story />
|
|
67
|
+
</Flex>
|
|
68
|
+
),
|
|
69
|
+
],
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export const RightSide: Story = {
|
|
73
|
+
args: {
|
|
74
|
+
side: "right",
|
|
75
|
+
color: "blue",
|
|
76
|
+
theme: "dark",
|
|
77
|
+
label: "Your name",
|
|
78
|
+
children: "Your message goes here",
|
|
79
|
+
},
|
|
80
|
+
decorators: [
|
|
81
|
+
(Story) => (
|
|
82
|
+
<Flex className="w-[400px]">
|
|
83
|
+
<Story />
|
|
84
|
+
</Flex>
|
|
85
|
+
),
|
|
86
|
+
],
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
export const Grey: Story = {
|
|
90
|
+
args: {
|
|
91
|
+
side: "left",
|
|
92
|
+
color: "grey",
|
|
93
|
+
theme: "dark",
|
|
94
|
+
label: "Your name",
|
|
95
|
+
children: "Your message goes here",
|
|
96
|
+
},
|
|
97
|
+
decorators: [
|
|
98
|
+
(Story) => (
|
|
99
|
+
<Flex className="w-[400px]">
|
|
100
|
+
<Story />
|
|
101
|
+
</Flex>
|
|
102
|
+
),
|
|
103
|
+
],
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
export const Green: Story = {
|
|
107
|
+
args: {
|
|
108
|
+
side: "left",
|
|
109
|
+
color: "green",
|
|
110
|
+
theme: "dark",
|
|
111
|
+
label: "Your name",
|
|
112
|
+
children: "Your message goes here",
|
|
113
|
+
},
|
|
114
|
+
decorators: [
|
|
115
|
+
(Story) => (
|
|
116
|
+
<Flex className="w-[400px]">
|
|
117
|
+
<Story />
|
|
118
|
+
</Flex>
|
|
119
|
+
),
|
|
120
|
+
],
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
export const LightTheme: Story = {
|
|
124
|
+
args: {
|
|
125
|
+
side: "left",
|
|
126
|
+
color: "blue",
|
|
127
|
+
theme: "light",
|
|
128
|
+
label: "Your name",
|
|
129
|
+
children: "Your message goes here",
|
|
130
|
+
},
|
|
131
|
+
parameters: {
|
|
132
|
+
backgrounds: { default: "light" },
|
|
133
|
+
},
|
|
134
|
+
decorators: [
|
|
135
|
+
(Story) => (
|
|
136
|
+
<Flex className="w-[400px]">
|
|
137
|
+
<Story />
|
|
138
|
+
</Flex>
|
|
139
|
+
),
|
|
140
|
+
],
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
export const GreyLight: Story = {
|
|
144
|
+
args: {
|
|
145
|
+
side: "left",
|
|
146
|
+
color: "grey",
|
|
147
|
+
theme: "light",
|
|
148
|
+
label: "Your name",
|
|
149
|
+
children: "Your message goes here",
|
|
150
|
+
},
|
|
151
|
+
parameters: {
|
|
152
|
+
backgrounds: { default: "light" },
|
|
153
|
+
},
|
|
154
|
+
decorators: [
|
|
155
|
+
(Story) => (
|
|
156
|
+
<Flex className="w-[400px]">
|
|
157
|
+
<Story />
|
|
158
|
+
</Flex>
|
|
159
|
+
),
|
|
160
|
+
],
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
export const NoLabel: Story = {
|
|
164
|
+
args: {
|
|
165
|
+
side: "left",
|
|
166
|
+
color: "blue",
|
|
167
|
+
theme: "dark",
|
|
168
|
+
showLabel: false,
|
|
169
|
+
children: "Message without a label",
|
|
170
|
+
},
|
|
171
|
+
decorators: [
|
|
172
|
+
(Story) => (
|
|
173
|
+
<Flex className="w-[400px]">
|
|
174
|
+
<Story />
|
|
175
|
+
</Flex>
|
|
176
|
+
),
|
|
177
|
+
],
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
export const LongMessage: Story = {
|
|
181
|
+
args: {
|
|
182
|
+
side: "left",
|
|
183
|
+
color: "blue",
|
|
184
|
+
theme: "dark",
|
|
185
|
+
label: "Your name",
|
|
186
|
+
children:
|
|
187
|
+
"This is a longer message that demonstrates how the chat bubble handles multiple lines of text. The bubble should expand to accommodate the content while maintaining proper padding and border radius.",
|
|
188
|
+
},
|
|
189
|
+
decorators: [
|
|
190
|
+
(Story) => (
|
|
191
|
+
<Flex className="w-[400px]">
|
|
192
|
+
<Story />
|
|
193
|
+
</Flex>
|
|
194
|
+
),
|
|
195
|
+
],
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
// Conversation example
|
|
199
|
+
export const Conversation: Story = {
|
|
200
|
+
render: () => (
|
|
201
|
+
<Flex direction="column" gap={4} className="w-[400px]">
|
|
202
|
+
<ChatBubble side="left" color="grey" theme="dark" label="Alice">
|
|
203
|
+
Hey! How are you doing?
|
|
204
|
+
</ChatBubble>
|
|
205
|
+
<ChatBubble side="right" color="blue" theme="dark" label="You">
|
|
206
|
+
I'm doing great, thanks for asking!
|
|
207
|
+
</ChatBubble>
|
|
208
|
+
<ChatBubble side="left" color="grey" theme="dark" label="Alice">
|
|
209
|
+
That's wonderful to hear. Want to grab lunch later?
|
|
210
|
+
</ChatBubble>
|
|
211
|
+
<ChatBubble side="right" color="green" theme="dark" label="You">
|
|
212
|
+
Sounds perfect! See you at noon.
|
|
213
|
+
</ChatBubble>
|
|
214
|
+
</Flex>
|
|
215
|
+
),
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
// All Variants
|
|
219
|
+
export const AllVariants: Story = {
|
|
220
|
+
render: () => (
|
|
221
|
+
<Flex direction="column" gap={8}>
|
|
222
|
+
{/* Dark Theme */}
|
|
223
|
+
<Flex direction="column" gap={4}>
|
|
224
|
+
<Typography variant="h4" className="text-white">Dark Theme</Typography>
|
|
225
|
+
<Flex gap={4}>
|
|
226
|
+
{/* Left side variants */}
|
|
227
|
+
<Flex direction="column" gap={4}>
|
|
228
|
+
<ChatBubble side="left" color="blue" theme="dark" label="Blue Left">
|
|
229
|
+
Your message goes here
|
|
230
|
+
</ChatBubble>
|
|
231
|
+
<ChatBubble side="left" color="grey" theme="dark" label="Grey Left">
|
|
232
|
+
Your message goes here
|
|
233
|
+
</ChatBubble>
|
|
234
|
+
<ChatBubble side="left" color="green" theme="dark" label="Green Left">
|
|
235
|
+
Your message goes here
|
|
236
|
+
</ChatBubble>
|
|
237
|
+
</Flex>
|
|
238
|
+
{/* Right side variants */}
|
|
239
|
+
<Flex direction="column" gap={4}>
|
|
240
|
+
<ChatBubble side="right" color="blue" theme="dark" label="Blue Right">
|
|
241
|
+
Your message goes here
|
|
242
|
+
</ChatBubble>
|
|
243
|
+
<ChatBubble side="right" color="grey" theme="dark" label="Grey Right">
|
|
244
|
+
Your message goes here
|
|
245
|
+
</ChatBubble>
|
|
246
|
+
<ChatBubble side="right" color="green" theme="dark" label="Green Right">
|
|
247
|
+
Your message goes here
|
|
248
|
+
</ChatBubble>
|
|
249
|
+
</Flex>
|
|
250
|
+
</Flex>
|
|
251
|
+
</Flex>
|
|
252
|
+
|
|
253
|
+
{/* Light Theme */}
|
|
254
|
+
<Flex direction="column" gap={4} className="bg-white p-6 rounded-lg">
|
|
255
|
+
<Typography variant="h4">Light Theme</Typography>
|
|
256
|
+
<Flex gap={4}>
|
|
257
|
+
{/* Left side variants */}
|
|
258
|
+
<Flex direction="column" gap={4}>
|
|
259
|
+
<ChatBubble side="left" color="blue" theme="light" label="Blue Left">
|
|
260
|
+
Your message goes here
|
|
261
|
+
</ChatBubble>
|
|
262
|
+
<ChatBubble side="left" color="grey" theme="light" label="Grey Left">
|
|
263
|
+
Your message goes here
|
|
264
|
+
</ChatBubble>
|
|
265
|
+
<ChatBubble side="left" color="green" theme="light" label="Green Left">
|
|
266
|
+
Your message goes here
|
|
267
|
+
</ChatBubble>
|
|
268
|
+
</Flex>
|
|
269
|
+
{/* Right side variants */}
|
|
270
|
+
<Flex direction="column" gap={4}>
|
|
271
|
+
<ChatBubble side="right" color="blue" theme="light" label="Blue Right">
|
|
272
|
+
Your message goes here
|
|
273
|
+
</ChatBubble>
|
|
274
|
+
<ChatBubble side="right" color="grey" theme="light" label="Grey Right">
|
|
275
|
+
Your message goes here
|
|
276
|
+
</ChatBubble>
|
|
277
|
+
<ChatBubble side="right" color="green" theme="light" label="Green Right">
|
|
278
|
+
Your message goes here
|
|
279
|
+
</ChatBubble>
|
|
280
|
+
</Flex>
|
|
281
|
+
</Flex>
|
|
282
|
+
</Flex>
|
|
283
|
+
|
|
284
|
+
{/* Sizes */}
|
|
285
|
+
<Flex direction="column" gap={4}>
|
|
286
|
+
<Typography variant="h4" className="text-white">Sizes</Typography>
|
|
287
|
+
<Flex direction="column" gap={2} className="w-[400px]">
|
|
288
|
+
<ChatBubble side="left" color="blue" theme="dark" size="small" label="Small">
|
|
289
|
+
Small text size
|
|
290
|
+
</ChatBubble>
|
|
291
|
+
<ChatBubble side="left" color="blue" theme="dark" size="medium" label="Medium">
|
|
292
|
+
Medium text size
|
|
293
|
+
</ChatBubble>
|
|
294
|
+
<ChatBubble side="left" color="blue" theme="dark" size="large" label="Large">
|
|
295
|
+
Large text size
|
|
296
|
+
</ChatBubble>
|
|
297
|
+
<ChatBubble side="left" color="blue" theme="dark" size="xlarge" label="XLarge">
|
|
298
|
+
Extra large text size
|
|
299
|
+
</ChatBubble>
|
|
300
|
+
</Flex>
|
|
301
|
+
</Flex>
|
|
302
|
+
</Flex>
|
|
303
|
+
),
|
|
304
|
+
parameters: {
|
|
305
|
+
layout: "padded",
|
|
306
|
+
},
|
|
307
|
+
}
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
import * as React from "react"
|
|
2
|
+
import { cva } from "class-variance-authority"
|
|
3
|
+
|
|
4
|
+
import { cn } from "../lib/utils"
|
|
5
|
+
|
|
6
|
+
type ChatBubbleSide = "left" | "right"
|
|
7
|
+
type ChatBubbleColor = "blue" | "grey" | "green"
|
|
8
|
+
type ChatBubbleTheme = "dark" | "light"
|
|
9
|
+
type ChatBubbleSize = "small" | "medium" | "large" | "xlarge"
|
|
10
|
+
|
|
11
|
+
const chatBubbleVariants = cva(
|
|
12
|
+
"flex flex-col gap-1.5 w-full",
|
|
13
|
+
{
|
|
14
|
+
variants: {
|
|
15
|
+
side: {
|
|
16
|
+
left: "items-start",
|
|
17
|
+
right: "items-end",
|
|
18
|
+
},
|
|
19
|
+
},
|
|
20
|
+
defaultVariants: {
|
|
21
|
+
side: "left",
|
|
22
|
+
},
|
|
23
|
+
}
|
|
24
|
+
)
|
|
25
|
+
|
|
26
|
+
const bubbleContentVariants = cva(
|
|
27
|
+
"px-4 py-3 font-medium leading-normal max-w-[85%]",
|
|
28
|
+
{
|
|
29
|
+
variants: {
|
|
30
|
+
color: {
|
|
31
|
+
blue: "bg-blue-500",
|
|
32
|
+
grey: "",
|
|
33
|
+
green: "bg-green-500",
|
|
34
|
+
},
|
|
35
|
+
theme: {
|
|
36
|
+
dark: "",
|
|
37
|
+
light: "",
|
|
38
|
+
},
|
|
39
|
+
side: {
|
|
40
|
+
left: "rounded-2xl rounded-bl-md",
|
|
41
|
+
right: "rounded-2xl rounded-br-md",
|
|
42
|
+
},
|
|
43
|
+
size: {
|
|
44
|
+
small: "text-sm px-3 py-2",
|
|
45
|
+
medium: "text-base px-4 py-3",
|
|
46
|
+
large: "text-lg px-4 py-3",
|
|
47
|
+
xlarge: "text-xl px-5 py-4",
|
|
48
|
+
},
|
|
49
|
+
},
|
|
50
|
+
compoundVariants: [
|
|
51
|
+
// Blue variants
|
|
52
|
+
{
|
|
53
|
+
color: "blue",
|
|
54
|
+
theme: "dark",
|
|
55
|
+
className: "bg-blue-500 text-white",
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
color: "blue",
|
|
59
|
+
theme: "light",
|
|
60
|
+
className: "bg-[#2e9dfb] text-white",
|
|
61
|
+
},
|
|
62
|
+
// Grey variants
|
|
63
|
+
{
|
|
64
|
+
color: "grey",
|
|
65
|
+
theme: "dark",
|
|
66
|
+
className: "bg-[#232323] text-white",
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
color: "grey",
|
|
70
|
+
theme: "light",
|
|
71
|
+
className: "bg-[#e7e7e7] text-neutral-900",
|
|
72
|
+
},
|
|
73
|
+
// Green variants
|
|
74
|
+
{
|
|
75
|
+
color: "green",
|
|
76
|
+
theme: "dark",
|
|
77
|
+
className: "bg-green-500 text-white",
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
color: "green",
|
|
81
|
+
theme: "light",
|
|
82
|
+
className: "bg-green-500 text-white",
|
|
83
|
+
},
|
|
84
|
+
],
|
|
85
|
+
defaultVariants: {
|
|
86
|
+
color: "blue",
|
|
87
|
+
theme: "dark",
|
|
88
|
+
side: "left",
|
|
89
|
+
size: "small",
|
|
90
|
+
},
|
|
91
|
+
}
|
|
92
|
+
)
|
|
93
|
+
|
|
94
|
+
const labelVariants = cva(
|
|
95
|
+
"text-sm text-neutral-400 mb-0.5",
|
|
96
|
+
{
|
|
97
|
+
variants: {
|
|
98
|
+
side: {
|
|
99
|
+
left: "ml-3",
|
|
100
|
+
right: "mr-3",
|
|
101
|
+
},
|
|
102
|
+
},
|
|
103
|
+
defaultVariants: {
|
|
104
|
+
side: "left",
|
|
105
|
+
},
|
|
106
|
+
}
|
|
107
|
+
)
|
|
108
|
+
|
|
109
|
+
export interface ChatBubbleProps
|
|
110
|
+
extends React.HTMLAttributes<HTMLDivElement> {
|
|
111
|
+
/** The side of the chat bubble (left for received, right for sent) */
|
|
112
|
+
side?: ChatBubbleSide
|
|
113
|
+
/** The color variant of the bubble */
|
|
114
|
+
color?: ChatBubbleColor
|
|
115
|
+
/** The theme variant */
|
|
116
|
+
theme?: ChatBubbleTheme
|
|
117
|
+
/** The text size of the bubble */
|
|
118
|
+
size?: ChatBubbleSize
|
|
119
|
+
/** The message content */
|
|
120
|
+
children: React.ReactNode
|
|
121
|
+
/** Optional label shown above the bubble (e.g., sender name) */
|
|
122
|
+
label?: string
|
|
123
|
+
/** Whether to show the label */
|
|
124
|
+
showLabel?: boolean
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
const ChatBubble = React.forwardRef<HTMLDivElement, ChatBubbleProps>(
|
|
128
|
+
(
|
|
129
|
+
{
|
|
130
|
+
className,
|
|
131
|
+
side = "left",
|
|
132
|
+
color = "blue",
|
|
133
|
+
theme = "dark",
|
|
134
|
+
size = "small",
|
|
135
|
+
children,
|
|
136
|
+
label,
|
|
137
|
+
showLabel = true,
|
|
138
|
+
...props
|
|
139
|
+
},
|
|
140
|
+
ref
|
|
141
|
+
) => {
|
|
142
|
+
return (
|
|
143
|
+
<div
|
|
144
|
+
ref={ref}
|
|
145
|
+
className={cn(chatBubbleVariants({ side, className }))}
|
|
146
|
+
{...props}
|
|
147
|
+
>
|
|
148
|
+
{showLabel && label && (
|
|
149
|
+
<span className={cn(labelVariants({ side }))}>
|
|
150
|
+
{label}
|
|
151
|
+
</span>
|
|
152
|
+
)}
|
|
153
|
+
<div
|
|
154
|
+
className={cn(
|
|
155
|
+
bubbleContentVariants({ color, theme, side, size })
|
|
156
|
+
)}
|
|
157
|
+
>
|
|
158
|
+
{children}
|
|
159
|
+
</div>
|
|
160
|
+
</div>
|
|
161
|
+
)
|
|
162
|
+
}
|
|
163
|
+
)
|
|
164
|
+
ChatBubble.displayName = "ChatBubble"
|
|
165
|
+
|
|
166
|
+
export { ChatBubble, chatBubbleVariants, bubbleContentVariants }
|
|
167
|
+
export type { ChatBubbleSide, ChatBubbleColor, ChatBubbleTheme, ChatBubbleSize }
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from "@storybook/react"
|
|
2
|
+
import { useState } from "react"
|
|
3
|
+
|
|
4
|
+
import { Label } from "../Label/Label"
|
|
5
|
+
import { Flex } from "../Flex/Flex"
|
|
6
|
+
import { Typography } from "../Typography/Typography"
|
|
7
|
+
import { Checkbox } from "./Checkbox"
|
|
8
|
+
|
|
9
|
+
function IndeterminateExample() {
|
|
10
|
+
const [checked, setChecked] = useState<boolean | "indeterminate">("indeterminate")
|
|
11
|
+
return (
|
|
12
|
+
<Flex align="center" gap={2}>
|
|
13
|
+
<Checkbox
|
|
14
|
+
id="indeterminate"
|
|
15
|
+
checked={checked}
|
|
16
|
+
onCheckedChange={(value) => setChecked(value)}
|
|
17
|
+
/>
|
|
18
|
+
<Label htmlFor="indeterminate">Indeterminate</Label>
|
|
19
|
+
</Flex>
|
|
20
|
+
)
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const meta: Meta<typeof Checkbox> = {
|
|
24
|
+
title: "Components/Checkbox",
|
|
25
|
+
component: Checkbox,
|
|
26
|
+
parameters: {
|
|
27
|
+
layout: "centered",
|
|
28
|
+
},
|
|
29
|
+
argTypes: {
|
|
30
|
+
size: {
|
|
31
|
+
control: "select",
|
|
32
|
+
options: ["small", "regular"],
|
|
33
|
+
description: "The size of the checkbox",
|
|
34
|
+
},
|
|
35
|
+
checked: {
|
|
36
|
+
control: "boolean",
|
|
37
|
+
description: "The checked state",
|
|
38
|
+
},
|
|
39
|
+
disabled: {
|
|
40
|
+
control: "boolean",
|
|
41
|
+
description: "Whether the checkbox is disabled",
|
|
42
|
+
},
|
|
43
|
+
},
|
|
44
|
+
tags: ["autodocs"],
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export default meta
|
|
48
|
+
type Story = StoryObj<typeof meta>
|
|
49
|
+
|
|
50
|
+
export const Default: Story = {
|
|
51
|
+
render: () => <Checkbox />,
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export const Checked: Story = {
|
|
55
|
+
render: () => <Checkbox defaultChecked />,
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export const WithLabel: Story = {
|
|
59
|
+
render: () => (
|
|
60
|
+
<Flex align="center" gap={2}>
|
|
61
|
+
<Checkbox id="terms" />
|
|
62
|
+
<Label htmlFor="terms">Accept terms and conditions</Label>
|
|
63
|
+
</Flex>
|
|
64
|
+
),
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
export const Disabled: Story = {
|
|
68
|
+
render: () => (
|
|
69
|
+
<Flex direction="column" gap={3}>
|
|
70
|
+
<Flex align="center" gap={2}>
|
|
71
|
+
<Checkbox id="disabled" disabled />
|
|
72
|
+
<Label htmlFor="disabled" className="opacity-50">Disabled</Label>
|
|
73
|
+
</Flex>
|
|
74
|
+
<Flex align="center" gap={2}>
|
|
75
|
+
<Checkbox id="disabled-checked" disabled defaultChecked />
|
|
76
|
+
<Label htmlFor="disabled-checked" className="opacity-50">Disabled checked</Label>
|
|
77
|
+
</Flex>
|
|
78
|
+
</Flex>
|
|
79
|
+
),
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
export const Indeterminate: Story = {
|
|
83
|
+
render: () => <IndeterminateExample />,
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
export const Small: Story = {
|
|
87
|
+
render: () => (
|
|
88
|
+
<Flex align="center" gap={2}>
|
|
89
|
+
<Checkbox id="small" size="small" />
|
|
90
|
+
<Label htmlFor="small" className="text-sm">Small checkbox</Label>
|
|
91
|
+
</Flex>
|
|
92
|
+
),
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
export const AllVariants: Story = {
|
|
96
|
+
render: () => (
|
|
97
|
+
<Flex direction="column" gap={6}>
|
|
98
|
+
<Typography variant="h4" className="text-white">Checkbox States</Typography>
|
|
99
|
+
|
|
100
|
+
<Flex direction="column" gap={4}>
|
|
101
|
+
<Flex align="center" gap={2}>
|
|
102
|
+
<Checkbox id="unchecked" />
|
|
103
|
+
<Label htmlFor="unchecked">Unchecked</Label>
|
|
104
|
+
</Flex>
|
|
105
|
+
|
|
106
|
+
<Flex align="center" gap={2}>
|
|
107
|
+
<Checkbox id="checked" defaultChecked />
|
|
108
|
+
<Label htmlFor="checked">Checked</Label>
|
|
109
|
+
</Flex>
|
|
110
|
+
|
|
111
|
+
<Flex align="center" gap={2}>
|
|
112
|
+
<Checkbox id="disabled-state" disabled />
|
|
113
|
+
<Label htmlFor="disabled-state" className="opacity-50">Disabled</Label>
|
|
114
|
+
</Flex>
|
|
115
|
+
|
|
116
|
+
<Flex align="center" gap={2}>
|
|
117
|
+
<Checkbox id="disabled-checked-state" disabled defaultChecked />
|
|
118
|
+
<Label htmlFor="disabled-checked-state" className="opacity-50">Disabled Checked</Label>
|
|
119
|
+
</Flex>
|
|
120
|
+
</Flex>
|
|
121
|
+
|
|
122
|
+
<Typography variant="h4" className="text-white mt-4">Sizes</Typography>
|
|
123
|
+
|
|
124
|
+
<Flex direction="column" gap={4}>
|
|
125
|
+
<Flex align="center" gap={2}>
|
|
126
|
+
<Checkbox id="small-size" size="small" defaultChecked />
|
|
127
|
+
<Label htmlFor="small-size" className="text-sm">Small</Label>
|
|
128
|
+
</Flex>
|
|
129
|
+
|
|
130
|
+
<Flex align="center" gap={2}>
|
|
131
|
+
<Checkbox id="regular-size" size="regular" defaultChecked />
|
|
132
|
+
<Label htmlFor="regular-size">Regular</Label>
|
|
133
|
+
</Flex>
|
|
134
|
+
</Flex>
|
|
135
|
+
</Flex>
|
|
136
|
+
),
|
|
137
|
+
}
|