@a2v2ai/uikit 0.0.36 → 0.0.38
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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 +107 -0
- package/Calendar/Calendar.stories.tsx +291 -0
- package/Calendar/Calendar.tsx +246 -0
- package/Card/Card.stories.tsx +136 -0
- package/Card/Card.tsx +96 -0
- package/Carousel/Carousel.stories.tsx +256 -0
- package/Carousel/Carousel.tsx +301 -0
- package/ChatBubble/ChatBubble.stories.tsx +339 -0
- package/ChatBubble/ChatBubble.tsx +179 -0
- package/Checkbox/Checkbox.stories.tsx +137 -0
- package/Checkbox/Checkbox.tsx +53 -0
- package/DataTable/DataTable.stories.tsx +400 -0
- package/DataTable/DataTable.tsx +207 -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.stories.tsx +390 -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 +566 -0
- package/Input/Input.tsx +168 -0
- package/InputOTP/InputOTP.stories.tsx +246 -0
- package/InputOTP/InputOTP.tsx +127 -0
- package/Label/Label.stories.tsx +110 -0
- package/Label/Label.tsx +44 -0
- package/Loader/Loader.stories.tsx +170 -0
- package/Loader/Loader.tsx +62 -0
- package/Menubar/Menubar.stories.tsx +382 -0
- package/Menubar/Menubar.tsx +274 -0
- package/Menubar/index.ts +18 -0
- package/Pagination/Pagination.stories.tsx +196 -0
- package/Pagination/Pagination.tsx +122 -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/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 +378 -0
- package/Select/Select.tsx +230 -0
- package/Separator/Separator.stories.tsx +110 -0
- package/Separator/Separator.tsx +29 -0
- package/Sidebar/Sidebar.stories.tsx +340 -0
- package/Sidebar/Sidebar.tsx +414 -0
- package/Sidebar/index.ts +28 -0
- package/Skeleton/Skeleton.stories.tsx +117 -0
- package/Skeleton/Skeleton.tsx +16 -0
- package/Slider/Slider.stories.tsx +216 -0
- package/Slider/Slider.tsx +29 -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/Table/Table.stories.tsx +510 -0
- package/Table/Table.tsx +114 -0
- package/Tabs/Tabs.stories.tsx +197 -0
- package/Tabs/Tabs.tsx +74 -0
- package/Textarea/Textarea.stories.tsx +187 -0
- package/Textarea/Textarea.tsx +73 -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 +425 -0
- package/Typography/Typography.tsx +106 -0
- package/helpers.ts +5 -0
- package/{icons.js → icons.ts} +1 -1
- package/index.ts +217 -0
- package/lib/typography-types.ts +223 -0
- package/lib/utils.ts +15 -0
- package/package.json +36 -33
- package/tsconfig.json +22 -0
- package/Alert/Alert.d.ts +0 -13
- package/Alert/Alert.js +0 -25
- package/AlertDialog/AlertDialog.d.ts +0 -43
- package/AlertDialog/AlertDialog.js +0 -71
- package/Avatar/Avatar.d.ts +0 -14
- package/Avatar/Avatar.js +0 -25
- package/Badge/Badge.d.ts +0 -11
- package/Badge/Badge.js +0 -23
- package/Breadcrumb/Breadcrumb.d.ts +0 -19
- package/Breadcrumb/Breadcrumb.js +0 -23
- package/Button/Button.d.ts +0 -23
- package/Button/Button.js +0 -52
- package/Calendar/Calendar.d.ts +0 -20
- package/Calendar/Calendar.js +0 -78
- package/Card/Card.d.ts +0 -16
- package/Card/Card.js +0 -28
- package/Carousel/Carousel.d.ts +0 -37
- package/Carousel/Carousel.js +0 -132
- package/ChatBubble/ChatBubble.d.ts +0 -33
- package/ChatBubble/ChatBubble.js +0 -107
- package/Checkbox/Checkbox.d.ts +0 -12
- package/Checkbox/Checkbox.js +0 -20
- package/DataTable/DataTable.d.ts +0 -35
- package/DataTable/DataTable.js +0 -51
- package/Dialog/Dialog.d.ts +0 -35
- package/Dialog/Dialog.js +0 -130
- package/Drawer/Drawer.d.ts +0 -33
- package/Drawer/Drawer.js +0 -55
- package/DropdownMenu/DropdownMenu.d.ts +0 -27
- package/DropdownMenu/DropdownMenu.js +0 -35
- package/ErrorMessage/ErrorMessage.d.ts +0 -27
- package/ErrorMessage/ErrorMessage.js +0 -14
- package/Flex/Flex.d.ts +0 -31
- package/Flex/Flex.js +0 -64
- package/IconButton/IconButton.d.ts +0 -23
- package/IconButton/IconButton.js +0 -48
- package/Input/Input.d.ts +0 -27
- package/Input/Input.js +0 -42
- package/InputOTP/InputOTP.d.ts +0 -20
- package/InputOTP/InputOTP.js +0 -44
- package/Label/Label.d.ts +0 -13
- package/Label/Label.js +0 -19
- package/Loader/Loader.d.ts +0 -21
- package/Loader/Loader.js +0 -30
- package/Menubar/Menubar.d.ts +0 -26
- package/Menubar/Menubar.js +0 -54
- package/Menubar/index.d.ts +0 -1
- package/Menubar/index.js +0 -1
- package/Pagination/Pagination.d.ts +0 -35
- package/Pagination/Pagination.js +0 -37
- package/Popover/Popover.d.ts +0 -7
- package/Popover/Popover.js +0 -10
- package/Progress/Progress.d.ts +0 -17
- package/Progress/Progress.js +0 -33
- package/RadioGroup/RadioGroup.d.ts +0 -13
- package/RadioGroup/RadioGroup.js +0 -26
- package/ScrollArea/ScrollArea.d.ts +0 -5
- package/ScrollArea/ScrollArea.js +0 -11
- package/Select/Select.d.ts +0 -29
- package/Select/Select.js +0 -50
- package/Separator/Separator.d.ts +0 -4
- package/Separator/Separator.js +0 -7
- package/Sidebar/Sidebar.d.ts +0 -48
- package/Sidebar/Sidebar.js +0 -116
- package/Sidebar/index.d.ts +0 -2
- package/Sidebar/index.js +0 -1
- package/Skeleton/Skeleton.d.ts +0 -4
- package/Skeleton/Skeleton.js +0 -7
- package/Slider/Slider.d.ts +0 -6
- package/Slider/Slider.js +0 -7
- package/Spinner/Spinner.d.ts +0 -19
- package/Spinner/Spinner.js +0 -31
- package/Switch/Switch.d.ts +0 -12
- package/Switch/Switch.js +0 -30
- package/Table/Table.d.ts +0 -10
- package/Table/Table.js +0 -20
- package/Tabs/Tabs.d.ts +0 -15
- package/Tabs/Tabs.js +0 -24
- package/Textarea/Textarea.d.ts +0 -19
- package/Textarea/Textarea.js +0 -31
- package/Toast/Toast.d.ts +0 -12
- package/Toast/Toast.js +0 -25
- package/Tooltip/Tooltip.d.ts +0 -17
- package/Tooltip/Tooltip.js +0 -29
- package/Typography/Typography.d.ts +0 -20
- package/Typography/Typography.js +0 -43
- package/helpers.d.ts +0 -4
- package/helpers.js +0 -5
- package/icons.d.ts +0 -1
- package/index.d.ts +0 -42
- package/index.js +0 -45
- package/lib/typography-types.d.ts +0 -4
- package/lib/typography-types.js +0 -90
- package/lib/utils.d.ts +0 -3
- package/lib/utils.js +0 -14
- package/tmpclaude-2407-cwd +0 -1
|
@@ -0,0 +1,301 @@
|
|
|
1
|
+
import * as React from "react"
|
|
2
|
+
import useEmblaCarousel, {
|
|
3
|
+
type UseEmblaCarouselType,
|
|
4
|
+
} from "embla-carousel-react"
|
|
5
|
+
import { cva } from "class-variance-authority"
|
|
6
|
+
import { ArrowLeft, ArrowRight } from "lucide-react"
|
|
7
|
+
|
|
8
|
+
import { cn } from "../lib/utils"
|
|
9
|
+
import { Button } from "../Button/Button"
|
|
10
|
+
|
|
11
|
+
type CarouselApi = UseEmblaCarouselType[1]
|
|
12
|
+
type UseCarouselParameters = Parameters<typeof useEmblaCarousel>
|
|
13
|
+
type CarouselOptions = UseCarouselParameters[0]
|
|
14
|
+
type CarouselPlugin = UseCarouselParameters[1]
|
|
15
|
+
|
|
16
|
+
type CarouselOrientation = "horizontal" | "vertical"
|
|
17
|
+
|
|
18
|
+
type CarouselContextProps = {
|
|
19
|
+
carouselRef: ReturnType<typeof useEmblaCarousel>[0]
|
|
20
|
+
api: ReturnType<typeof useEmblaCarousel>[1]
|
|
21
|
+
scrollPrev: () => void
|
|
22
|
+
scrollNext: () => void
|
|
23
|
+
canScrollPrev: boolean
|
|
24
|
+
canScrollNext: boolean
|
|
25
|
+
} & CarouselProps
|
|
26
|
+
|
|
27
|
+
const CarouselContext = React.createContext<CarouselContextProps | null>(null)
|
|
28
|
+
|
|
29
|
+
function useCarousel() {
|
|
30
|
+
const context = React.useContext(CarouselContext)
|
|
31
|
+
|
|
32
|
+
if (!context) {
|
|
33
|
+
throw new Error("useCarousel must be used within a <Carousel />")
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
return context
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const carouselVariants = cva("relative", {
|
|
40
|
+
variants: {
|
|
41
|
+
orientation: {
|
|
42
|
+
horizontal: "",
|
|
43
|
+
vertical: "",
|
|
44
|
+
},
|
|
45
|
+
},
|
|
46
|
+
defaultVariants: {
|
|
47
|
+
orientation: "horizontal",
|
|
48
|
+
},
|
|
49
|
+
})
|
|
50
|
+
|
|
51
|
+
const carouselContentVariants = cva("flex", {
|
|
52
|
+
variants: {
|
|
53
|
+
orientation: {
|
|
54
|
+
horizontal: "-ml-4",
|
|
55
|
+
vertical: "-mt-4 flex-col",
|
|
56
|
+
},
|
|
57
|
+
},
|
|
58
|
+
defaultVariants: {
|
|
59
|
+
orientation: "horizontal",
|
|
60
|
+
},
|
|
61
|
+
})
|
|
62
|
+
|
|
63
|
+
const carouselItemVariants = cva("min-w-0 shrink-0 grow-0 basis-full", {
|
|
64
|
+
variants: {
|
|
65
|
+
orientation: {
|
|
66
|
+
horizontal: "pl-4",
|
|
67
|
+
vertical: "pt-4",
|
|
68
|
+
},
|
|
69
|
+
},
|
|
70
|
+
defaultVariants: {
|
|
71
|
+
orientation: "horizontal",
|
|
72
|
+
},
|
|
73
|
+
})
|
|
74
|
+
|
|
75
|
+
interface CarouselProps {
|
|
76
|
+
opts?: CarouselOptions
|
|
77
|
+
plugins?: CarouselPlugin
|
|
78
|
+
orientation?: CarouselOrientation
|
|
79
|
+
setApi?: (api: CarouselApi) => void
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
const Carousel = React.forwardRef<
|
|
83
|
+
HTMLDivElement,
|
|
84
|
+
React.HTMLAttributes<HTMLDivElement> & CarouselProps
|
|
85
|
+
>(
|
|
86
|
+
(
|
|
87
|
+
{
|
|
88
|
+
orientation = "horizontal",
|
|
89
|
+
opts,
|
|
90
|
+
setApi,
|
|
91
|
+
plugins,
|
|
92
|
+
className,
|
|
93
|
+
children,
|
|
94
|
+
...props
|
|
95
|
+
},
|
|
96
|
+
ref
|
|
97
|
+
) => {
|
|
98
|
+
const [carouselRef, api] = useEmblaCarousel(
|
|
99
|
+
{
|
|
100
|
+
...opts,
|
|
101
|
+
axis: orientation === "horizontal" ? "x" : "y",
|
|
102
|
+
},
|
|
103
|
+
plugins
|
|
104
|
+
)
|
|
105
|
+
const [canScrollPrev, setCanScrollPrev] = React.useState(false)
|
|
106
|
+
const [canScrollNext, setCanScrollNext] = React.useState(false)
|
|
107
|
+
|
|
108
|
+
const onSelect = React.useCallback((api: CarouselApi) => {
|
|
109
|
+
if (!api) {
|
|
110
|
+
return
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
setCanScrollPrev(api.canScrollPrev())
|
|
114
|
+
setCanScrollNext(api.canScrollNext())
|
|
115
|
+
}, [])
|
|
116
|
+
|
|
117
|
+
const scrollPrev = React.useCallback(() => {
|
|
118
|
+
api?.scrollPrev()
|
|
119
|
+
}, [api])
|
|
120
|
+
|
|
121
|
+
const scrollNext = React.useCallback(() => {
|
|
122
|
+
api?.scrollNext()
|
|
123
|
+
}, [api])
|
|
124
|
+
|
|
125
|
+
const handleKeyDown = React.useCallback(
|
|
126
|
+
(event: React.KeyboardEvent<HTMLDivElement>) => {
|
|
127
|
+
if (event.key === "ArrowLeft") {
|
|
128
|
+
event.preventDefault()
|
|
129
|
+
scrollPrev()
|
|
130
|
+
} else if (event.key === "ArrowRight") {
|
|
131
|
+
event.preventDefault()
|
|
132
|
+
scrollNext()
|
|
133
|
+
}
|
|
134
|
+
},
|
|
135
|
+
[scrollPrev, scrollNext]
|
|
136
|
+
)
|
|
137
|
+
|
|
138
|
+
React.useEffect(() => {
|
|
139
|
+
if (!api || !setApi) {
|
|
140
|
+
return
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
setApi(api)
|
|
144
|
+
}, [api, setApi])
|
|
145
|
+
|
|
146
|
+
React.useEffect(() => {
|
|
147
|
+
if (!api) {
|
|
148
|
+
return
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
onSelect(api)
|
|
152
|
+
api.on("reInit", onSelect)
|
|
153
|
+
api.on("select", onSelect)
|
|
154
|
+
|
|
155
|
+
return () => {
|
|
156
|
+
api?.off("select", onSelect)
|
|
157
|
+
}
|
|
158
|
+
}, [api, onSelect])
|
|
159
|
+
|
|
160
|
+
return (
|
|
161
|
+
<CarouselContext.Provider
|
|
162
|
+
value={{
|
|
163
|
+
carouselRef,
|
|
164
|
+
api: api,
|
|
165
|
+
opts,
|
|
166
|
+
orientation:
|
|
167
|
+
orientation || (opts?.axis === "y" ? "vertical" : "horizontal"),
|
|
168
|
+
scrollPrev,
|
|
169
|
+
scrollNext,
|
|
170
|
+
canScrollPrev,
|
|
171
|
+
canScrollNext,
|
|
172
|
+
}}
|
|
173
|
+
>
|
|
174
|
+
<div
|
|
175
|
+
ref={ref}
|
|
176
|
+
onKeyDownCapture={handleKeyDown}
|
|
177
|
+
className={cn(carouselVariants({ orientation }), className)}
|
|
178
|
+
role="region"
|
|
179
|
+
aria-roledescription="carousel"
|
|
180
|
+
{...props}
|
|
181
|
+
>
|
|
182
|
+
{children}
|
|
183
|
+
</div>
|
|
184
|
+
</CarouselContext.Provider>
|
|
185
|
+
)
|
|
186
|
+
}
|
|
187
|
+
)
|
|
188
|
+
Carousel.displayName = "Carousel"
|
|
189
|
+
|
|
190
|
+
const CarouselContent = React.forwardRef<
|
|
191
|
+
HTMLDivElement,
|
|
192
|
+
React.HTMLAttributes<HTMLDivElement>
|
|
193
|
+
>(({ className, ...props }, ref) => {
|
|
194
|
+
const { carouselRef, orientation } = useCarousel()
|
|
195
|
+
|
|
196
|
+
return (
|
|
197
|
+
<div ref={carouselRef} className="overflow-hidden">
|
|
198
|
+
<div
|
|
199
|
+
ref={ref}
|
|
200
|
+
className={cn(carouselContentVariants({ orientation }), className)}
|
|
201
|
+
{...props}
|
|
202
|
+
/>
|
|
203
|
+
</div>
|
|
204
|
+
)
|
|
205
|
+
})
|
|
206
|
+
CarouselContent.displayName = "CarouselContent"
|
|
207
|
+
|
|
208
|
+
const CarouselItem = React.forwardRef<
|
|
209
|
+
HTMLDivElement,
|
|
210
|
+
React.HTMLAttributes<HTMLDivElement>
|
|
211
|
+
>(({ className, ...props }, ref) => {
|
|
212
|
+
const { orientation } = useCarousel()
|
|
213
|
+
|
|
214
|
+
return (
|
|
215
|
+
<div
|
|
216
|
+
ref={ref}
|
|
217
|
+
role="group"
|
|
218
|
+
aria-roledescription="slide"
|
|
219
|
+
className={cn(carouselItemVariants({ orientation }), className)}
|
|
220
|
+
{...props}
|
|
221
|
+
/>
|
|
222
|
+
)
|
|
223
|
+
})
|
|
224
|
+
CarouselItem.displayName = "CarouselItem"
|
|
225
|
+
|
|
226
|
+
const CarouselPrevious = React.forwardRef<
|
|
227
|
+
HTMLButtonElement,
|
|
228
|
+
React.ComponentProps<typeof Button>
|
|
229
|
+
>(({ className, variant = "outline", size = "small", ...props }, ref) => {
|
|
230
|
+
const { orientation, scrollPrev, canScrollPrev } = useCarousel()
|
|
231
|
+
|
|
232
|
+
return (
|
|
233
|
+
<Button
|
|
234
|
+
ref={ref}
|
|
235
|
+
variant={variant}
|
|
236
|
+
size={size}
|
|
237
|
+
roundness="round"
|
|
238
|
+
className={cn(
|
|
239
|
+
"absolute h-8 w-8 p-0",
|
|
240
|
+
orientation === "horizontal"
|
|
241
|
+
? "-left-12 top-1/2 -translate-y-1/2"
|
|
242
|
+
: "-top-12 left-1/2 -translate-x-1/2 rotate-90",
|
|
243
|
+
className
|
|
244
|
+
)}
|
|
245
|
+
disabled={!canScrollPrev}
|
|
246
|
+
onClick={scrollPrev}
|
|
247
|
+
{...props}
|
|
248
|
+
>
|
|
249
|
+
<ArrowLeft className="h-4 w-4" />
|
|
250
|
+
<span className="sr-only">Previous slide</span>
|
|
251
|
+
</Button>
|
|
252
|
+
)
|
|
253
|
+
})
|
|
254
|
+
CarouselPrevious.displayName = "CarouselPrevious"
|
|
255
|
+
|
|
256
|
+
const CarouselNext = React.forwardRef<
|
|
257
|
+
HTMLButtonElement,
|
|
258
|
+
React.ComponentProps<typeof Button>
|
|
259
|
+
>(({ className, variant = "outline", size = "small", ...props }, ref) => {
|
|
260
|
+
const { orientation, scrollNext, canScrollNext } = useCarousel()
|
|
261
|
+
|
|
262
|
+
return (
|
|
263
|
+
<Button
|
|
264
|
+
ref={ref}
|
|
265
|
+
variant={variant}
|
|
266
|
+
size={size}
|
|
267
|
+
roundness="round"
|
|
268
|
+
className={cn(
|
|
269
|
+
"absolute h-8 w-8 p-0",
|
|
270
|
+
orientation === "horizontal"
|
|
271
|
+
? "-right-12 top-1/2 -translate-y-1/2"
|
|
272
|
+
: "-bottom-12 left-1/2 -translate-x-1/2 rotate-90",
|
|
273
|
+
className
|
|
274
|
+
)}
|
|
275
|
+
disabled={!canScrollNext}
|
|
276
|
+
onClick={scrollNext}
|
|
277
|
+
{...props}
|
|
278
|
+
>
|
|
279
|
+
<ArrowRight className="h-4 w-4" />
|
|
280
|
+
<span className="sr-only">Next slide</span>
|
|
281
|
+
</Button>
|
|
282
|
+
)
|
|
283
|
+
})
|
|
284
|
+
CarouselNext.displayName = "CarouselNext"
|
|
285
|
+
|
|
286
|
+
export {
|
|
287
|
+
Carousel,
|
|
288
|
+
CarouselContent,
|
|
289
|
+
CarouselItem,
|
|
290
|
+
CarouselPrevious,
|
|
291
|
+
CarouselNext,
|
|
292
|
+
carouselVariants,
|
|
293
|
+
carouselContentVariants,
|
|
294
|
+
carouselItemVariants,
|
|
295
|
+
useCarousel,
|
|
296
|
+
type CarouselApi,
|
|
297
|
+
type CarouselProps,
|
|
298
|
+
type CarouselOptions,
|
|
299
|
+
type CarouselPlugin,
|
|
300
|
+
type CarouselOrientation,
|
|
301
|
+
}
|
|
@@ -0,0 +1,339 @@
|
|
|
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", "lightGrey"],
|
|
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 LightGrey: Story = {
|
|
144
|
+
args: {
|
|
145
|
+
side: "left",
|
|
146
|
+
color: "lightGrey",
|
|
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 GreyLight: Story = {
|
|
164
|
+
args: {
|
|
165
|
+
side: "left",
|
|
166
|
+
color: "grey",
|
|
167
|
+
theme: "light",
|
|
168
|
+
label: "Your name",
|
|
169
|
+
children: "Your message goes here",
|
|
170
|
+
},
|
|
171
|
+
parameters: {
|
|
172
|
+
backgrounds: { default: "light" },
|
|
173
|
+
},
|
|
174
|
+
decorators: [
|
|
175
|
+
(Story) => (
|
|
176
|
+
<Flex className="w-[400px]">
|
|
177
|
+
<Story />
|
|
178
|
+
</Flex>
|
|
179
|
+
),
|
|
180
|
+
],
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
export const NoLabel: Story = {
|
|
184
|
+
args: {
|
|
185
|
+
side: "left",
|
|
186
|
+
color: "blue",
|
|
187
|
+
theme: "dark",
|
|
188
|
+
showLabel: false,
|
|
189
|
+
children: "Message without a label",
|
|
190
|
+
},
|
|
191
|
+
decorators: [
|
|
192
|
+
(Story) => (
|
|
193
|
+
<Flex className="w-[400px]">
|
|
194
|
+
<Story />
|
|
195
|
+
</Flex>
|
|
196
|
+
),
|
|
197
|
+
],
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
export const LongMessage: Story = {
|
|
201
|
+
args: {
|
|
202
|
+
side: "left",
|
|
203
|
+
color: "blue",
|
|
204
|
+
theme: "dark",
|
|
205
|
+
label: "Your name",
|
|
206
|
+
children:
|
|
207
|
+
"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.",
|
|
208
|
+
},
|
|
209
|
+
decorators: [
|
|
210
|
+
(Story) => (
|
|
211
|
+
<Flex className="w-[400px]">
|
|
212
|
+
<Story />
|
|
213
|
+
</Flex>
|
|
214
|
+
),
|
|
215
|
+
],
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
// Conversation example
|
|
219
|
+
export const Conversation: Story = {
|
|
220
|
+
render: () => (
|
|
221
|
+
<Flex gap={4} className="w-[400px]">
|
|
222
|
+
<ChatBubble side="left" color="grey" theme="dark" label="Alice">
|
|
223
|
+
Hey! How are you doing?
|
|
224
|
+
</ChatBubble>
|
|
225
|
+
<ChatBubble side="right" color="blue" theme="dark" label="You">
|
|
226
|
+
I'm doing great, thanks for asking!
|
|
227
|
+
</ChatBubble>
|
|
228
|
+
<ChatBubble side="left" color="grey" theme="dark" label="Alice">
|
|
229
|
+
That's wonderful to hear. Want to grab lunch later?
|
|
230
|
+
</ChatBubble>
|
|
231
|
+
<ChatBubble side="right" color="green" theme="dark" label="You">
|
|
232
|
+
Sounds perfect! See you at noon.
|
|
233
|
+
</ChatBubble>
|
|
234
|
+
</Flex>
|
|
235
|
+
),
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
// All Variants
|
|
239
|
+
export const AllVariants: Story = {
|
|
240
|
+
render: () => (
|
|
241
|
+
<Flex gap={8}>
|
|
242
|
+
{/* Dark Theme */}
|
|
243
|
+
<Flex gap={4}>
|
|
244
|
+
<Typography variant="h4" className="text-white">Dark Theme</Typography>
|
|
245
|
+
<Flex direction="row" gap={4}>
|
|
246
|
+
{/* Left side variants */}
|
|
247
|
+
<Flex gap={4}>
|
|
248
|
+
<ChatBubble side="left" color="blue" theme="dark" label="Blue Left">
|
|
249
|
+
Your message goes here
|
|
250
|
+
</ChatBubble>
|
|
251
|
+
<ChatBubble side="left" color="grey" theme="dark" label="Grey Left">
|
|
252
|
+
Your message goes here
|
|
253
|
+
</ChatBubble>
|
|
254
|
+
<ChatBubble side="left" color="green" theme="dark" label="Green Left">
|
|
255
|
+
Your message goes here
|
|
256
|
+
</ChatBubble>
|
|
257
|
+
<ChatBubble side="left" color="lightGrey" theme="dark" label="Light Grey Left">
|
|
258
|
+
Your message goes here
|
|
259
|
+
</ChatBubble>
|
|
260
|
+
</Flex>
|
|
261
|
+
{/* Right side variants */}
|
|
262
|
+
<Flex gap={4}>
|
|
263
|
+
<ChatBubble side="right" color="blue" theme="dark" label="Blue Right">
|
|
264
|
+
Your message goes here
|
|
265
|
+
</ChatBubble>
|
|
266
|
+
<ChatBubble side="right" color="grey" theme="dark" label="Grey Right">
|
|
267
|
+
Your message goes here
|
|
268
|
+
</ChatBubble>
|
|
269
|
+
<ChatBubble side="right" color="green" theme="dark" label="Green Right">
|
|
270
|
+
Your message goes here
|
|
271
|
+
</ChatBubble>
|
|
272
|
+
<ChatBubble side="right" color="lightGrey" theme="dark" label="Light Grey Right">
|
|
273
|
+
Your message goes here
|
|
274
|
+
</ChatBubble>
|
|
275
|
+
</Flex>
|
|
276
|
+
</Flex>
|
|
277
|
+
</Flex>
|
|
278
|
+
|
|
279
|
+
{/* Light Theme */}
|
|
280
|
+
<Flex gap={4} className="bg-white p-6 rounded-lg">
|
|
281
|
+
<Typography variant="h4">Light Theme</Typography>
|
|
282
|
+
<Flex direction="row" gap={4}>
|
|
283
|
+
{/* Left side variants */}
|
|
284
|
+
<Flex gap={4}>
|
|
285
|
+
<ChatBubble side="left" color="blue" theme="light" label="Blue Left">
|
|
286
|
+
Your message goes here
|
|
287
|
+
</ChatBubble>
|
|
288
|
+
<ChatBubble side="left" color="grey" theme="light" label="Grey Left">
|
|
289
|
+
Your message goes here
|
|
290
|
+
</ChatBubble>
|
|
291
|
+
<ChatBubble side="left" color="green" theme="light" label="Green Left">
|
|
292
|
+
Your message goes here
|
|
293
|
+
</ChatBubble>
|
|
294
|
+
<ChatBubble side="left" color="lightGrey" theme="light" label="Light Grey Left">
|
|
295
|
+
Your message goes here
|
|
296
|
+
</ChatBubble>
|
|
297
|
+
</Flex>
|
|
298
|
+
{/* Right side variants */}
|
|
299
|
+
<Flex gap={4}>
|
|
300
|
+
<ChatBubble side="right" color="blue" theme="light" label="Blue Right">
|
|
301
|
+
Your message goes here
|
|
302
|
+
</ChatBubble>
|
|
303
|
+
<ChatBubble side="right" color="grey" theme="light" label="Grey Right">
|
|
304
|
+
Your message goes here
|
|
305
|
+
</ChatBubble>
|
|
306
|
+
<ChatBubble side="right" color="green" theme="light" label="Green Right">
|
|
307
|
+
Your message goes here
|
|
308
|
+
</ChatBubble>
|
|
309
|
+
<ChatBubble side="right" color="lightGrey" theme="light" label="Light Grey Right">
|
|
310
|
+
Your message goes here
|
|
311
|
+
</ChatBubble>
|
|
312
|
+
</Flex>
|
|
313
|
+
</Flex>
|
|
314
|
+
</Flex>
|
|
315
|
+
|
|
316
|
+
{/* Sizes */}
|
|
317
|
+
<Flex gap={4}>
|
|
318
|
+
<Typography variant="h4" className="text-white">Sizes</Typography>
|
|
319
|
+
<Flex gap={2} className="w-[400px]">
|
|
320
|
+
<ChatBubble side="left" color="blue" theme="dark" size="small" label="Small">
|
|
321
|
+
Small text size
|
|
322
|
+
</ChatBubble>
|
|
323
|
+
<ChatBubble side="left" color="blue" theme="dark" size="medium" label="Medium">
|
|
324
|
+
Medium text size
|
|
325
|
+
</ChatBubble>
|
|
326
|
+
<ChatBubble side="left" color="blue" theme="dark" size="large" label="Large">
|
|
327
|
+
Large text size
|
|
328
|
+
</ChatBubble>
|
|
329
|
+
<ChatBubble side="left" color="blue" theme="dark" size="xlarge" label="XLarge">
|
|
330
|
+
Extra large text size
|
|
331
|
+
</ChatBubble>
|
|
332
|
+
</Flex>
|
|
333
|
+
</Flex>
|
|
334
|
+
</Flex>
|
|
335
|
+
),
|
|
336
|
+
parameters: {
|
|
337
|
+
layout: "padded",
|
|
338
|
+
},
|
|
339
|
+
}
|