@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,216 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from "@storybook/react"
|
|
2
|
+
import { useState } from "react"
|
|
3
|
+
|
|
4
|
+
import { Flex } from "../Flex/Flex"
|
|
5
|
+
import { Typography } from "../Typography/Typography"
|
|
6
|
+
import { Slider } from "./Slider"
|
|
7
|
+
|
|
8
|
+
const meta: Meta<typeof Slider> = {
|
|
9
|
+
title: "Components/Slider",
|
|
10
|
+
component: Slider,
|
|
11
|
+
parameters: {
|
|
12
|
+
layout: "centered",
|
|
13
|
+
},
|
|
14
|
+
argTypes: {
|
|
15
|
+
defaultValue: {
|
|
16
|
+
control: "object",
|
|
17
|
+
description: "The default value of the slider",
|
|
18
|
+
},
|
|
19
|
+
max: {
|
|
20
|
+
control: "number",
|
|
21
|
+
description: "The maximum value",
|
|
22
|
+
},
|
|
23
|
+
min: {
|
|
24
|
+
control: "number",
|
|
25
|
+
description: "The minimum value",
|
|
26
|
+
},
|
|
27
|
+
step: {
|
|
28
|
+
control: "number",
|
|
29
|
+
description: "The step increment",
|
|
30
|
+
},
|
|
31
|
+
disabled: {
|
|
32
|
+
control: "boolean",
|
|
33
|
+
description: "Whether the slider is disabled",
|
|
34
|
+
},
|
|
35
|
+
},
|
|
36
|
+
tags: ["autodocs"],
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export default meta
|
|
40
|
+
type Story = StoryObj<typeof meta>
|
|
41
|
+
|
|
42
|
+
export const Default: Story = {
|
|
43
|
+
render: () => (
|
|
44
|
+
<div className="w-[300px]">
|
|
45
|
+
<Slider defaultValue={[50]} max={100} step={1} />
|
|
46
|
+
</div>
|
|
47
|
+
),
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export const WithValue: Story = {
|
|
51
|
+
render: function Render() {
|
|
52
|
+
const [value, setValue] = useState([50])
|
|
53
|
+
|
|
54
|
+
return (
|
|
55
|
+
<div className="w-[300px]">
|
|
56
|
+
<Flex direction="row" justify="between" className="mb-2">
|
|
57
|
+
<Typography variant="body2">Volume</Typography>
|
|
58
|
+
<Typography variant="body2">{value[0]}%</Typography>
|
|
59
|
+
</Flex>
|
|
60
|
+
<Slider
|
|
61
|
+
value={value}
|
|
62
|
+
onValueChange={setValue}
|
|
63
|
+
max={100}
|
|
64
|
+
step={1}
|
|
65
|
+
/>
|
|
66
|
+
</div>
|
|
67
|
+
)
|
|
68
|
+
},
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export const Temperature: Story = {
|
|
72
|
+
render: function Render() {
|
|
73
|
+
const [value, setValue] = useState([0.5])
|
|
74
|
+
|
|
75
|
+
return (
|
|
76
|
+
<div className="w-[300px] bg-white p-4 rounded-lg">
|
|
77
|
+
<Flex direction="row" justify="between" className="mb-4">
|
|
78
|
+
<Typography variant="body1" color="main-900">Temperature</Typography>
|
|
79
|
+
<Typography variant="body1" color="main-900">{value[0].toFixed(1)}</Typography>
|
|
80
|
+
</Flex>
|
|
81
|
+
<Slider
|
|
82
|
+
value={value}
|
|
83
|
+
onValueChange={setValue}
|
|
84
|
+
max={1}
|
|
85
|
+
min={0}
|
|
86
|
+
step={0.1}
|
|
87
|
+
/>
|
|
88
|
+
<Flex direction="row" justify="between" className="mt-2">
|
|
89
|
+
<Typography variant="body2" color="grey-400">Reserved</Typography>
|
|
90
|
+
<Typography variant="body2" color="grey-400">Creative</Typography>
|
|
91
|
+
</Flex>
|
|
92
|
+
</div>
|
|
93
|
+
)
|
|
94
|
+
},
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
export const Range: Story = {
|
|
98
|
+
render: function Render() {
|
|
99
|
+
const [value, setValue] = useState([25, 75])
|
|
100
|
+
|
|
101
|
+
return (
|
|
102
|
+
<div className="w-[300px]">
|
|
103
|
+
<Flex direction="row" justify="between" className="mb-2">
|
|
104
|
+
<Typography variant="body2">Price Range</Typography>
|
|
105
|
+
<Typography variant="body2">${value[0]} - ${value[1]}</Typography>
|
|
106
|
+
</Flex>
|
|
107
|
+
<Slider
|
|
108
|
+
value={value}
|
|
109
|
+
onValueChange={setValue}
|
|
110
|
+
max={100}
|
|
111
|
+
step={1}
|
|
112
|
+
/>
|
|
113
|
+
</div>
|
|
114
|
+
)
|
|
115
|
+
},
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
export const Disabled: Story = {
|
|
119
|
+
render: () => (
|
|
120
|
+
<div className="w-[300px]">
|
|
121
|
+
<Slider defaultValue={[50]} max={100} step={1} disabled />
|
|
122
|
+
</div>
|
|
123
|
+
),
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
export const CustomStep: Story = {
|
|
127
|
+
render: function Render() {
|
|
128
|
+
const [value, setValue] = useState([5])
|
|
129
|
+
|
|
130
|
+
return (
|
|
131
|
+
<div className="w-[300px]">
|
|
132
|
+
<Flex direction="row" justify="between" className="mb-2">
|
|
133
|
+
<Typography variant="body2">Steps of 5</Typography>
|
|
134
|
+
<Typography variant="body2">{value[0]}</Typography>
|
|
135
|
+
</Flex>
|
|
136
|
+
<Slider
|
|
137
|
+
value={value}
|
|
138
|
+
onValueChange={setValue}
|
|
139
|
+
max={100}
|
|
140
|
+
min={0}
|
|
141
|
+
step={5}
|
|
142
|
+
/>
|
|
143
|
+
</div>
|
|
144
|
+
)
|
|
145
|
+
},
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
export const AllVariants: Story = {
|
|
149
|
+
render: function Render() {
|
|
150
|
+
const [volume, setVolume] = useState([50])
|
|
151
|
+
const [temperature, setTemperature] = useState([0.5])
|
|
152
|
+
const [priceRange, setPriceRange] = useState([25, 75])
|
|
153
|
+
|
|
154
|
+
return (
|
|
155
|
+
<Flex gap={6} className="w-[350px]">
|
|
156
|
+
<Typography variant="h4" className="text-white">Slider Examples</Typography>
|
|
157
|
+
|
|
158
|
+
<div className="bg-white p-4 rounded-lg space-y-6">
|
|
159
|
+
<Flex gap={2}>
|
|
160
|
+
<Flex direction="row" justify="between">
|
|
161
|
+
<Typography variant="body2" color="main-900">Volume</Typography>
|
|
162
|
+
<Typography variant="body2" color="main-900">{volume[0]}%</Typography>
|
|
163
|
+
</Flex>
|
|
164
|
+
<Slider
|
|
165
|
+
value={volume}
|
|
166
|
+
onValueChange={setVolume}
|
|
167
|
+
max={100}
|
|
168
|
+
step={1}
|
|
169
|
+
/>
|
|
170
|
+
</Flex>
|
|
171
|
+
|
|
172
|
+
<Flex gap={2}>
|
|
173
|
+
<Flex direction="row" justify="between">
|
|
174
|
+
<Typography variant="body2" color="main-900">Temperature</Typography>
|
|
175
|
+
<Typography variant="body2" color="main-900">{temperature[0].toFixed(1)}</Typography>
|
|
176
|
+
</Flex>
|
|
177
|
+
<Slider
|
|
178
|
+
value={temperature}
|
|
179
|
+
onValueChange={setTemperature}
|
|
180
|
+
max={1}
|
|
181
|
+
min={0}
|
|
182
|
+
step={0.1}
|
|
183
|
+
/>
|
|
184
|
+
<Flex direction="row" justify="between">
|
|
185
|
+
<Typography variant="caption" color="grey-400">Reserved</Typography>
|
|
186
|
+
<Typography variant="caption" color="grey-400">Creative</Typography>
|
|
187
|
+
</Flex>
|
|
188
|
+
</Flex>
|
|
189
|
+
|
|
190
|
+
<Flex gap={2}>
|
|
191
|
+
<Flex direction="row" justify="between">
|
|
192
|
+
<Typography variant="body2" color="main-900">Price Range</Typography>
|
|
193
|
+
<Typography variant="body2" color="main-900">${priceRange[0]} - ${priceRange[1]}</Typography>
|
|
194
|
+
</Flex>
|
|
195
|
+
<Slider
|
|
196
|
+
value={priceRange}
|
|
197
|
+
onValueChange={setPriceRange}
|
|
198
|
+
max={100}
|
|
199
|
+
step={1}
|
|
200
|
+
/>
|
|
201
|
+
</Flex>
|
|
202
|
+
|
|
203
|
+
<Flex gap={2}>
|
|
204
|
+
<Typography variant="body2" color="main-900">Disabled</Typography>
|
|
205
|
+
<Slider
|
|
206
|
+
defaultValue={[30]}
|
|
207
|
+
max={100}
|
|
208
|
+
step={1}
|
|
209
|
+
disabled
|
|
210
|
+
/>
|
|
211
|
+
</Flex>
|
|
212
|
+
</div>
|
|
213
|
+
</Flex>
|
|
214
|
+
)
|
|
215
|
+
},
|
|
216
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import * as React from "react"
|
|
2
|
+
import * as SliderPrimitive from "@radix-ui/react-slider"
|
|
3
|
+
|
|
4
|
+
import { cn } from "../lib/utils"
|
|
5
|
+
|
|
6
|
+
export interface SliderProps
|
|
7
|
+
extends React.ComponentPropsWithoutRef<typeof SliderPrimitive.Root> {}
|
|
8
|
+
|
|
9
|
+
const Slider = React.forwardRef<
|
|
10
|
+
React.ElementRef<typeof SliderPrimitive.Root>,
|
|
11
|
+
SliderProps
|
|
12
|
+
>(({ className, ...props }, ref) => (
|
|
13
|
+
<SliderPrimitive.Root
|
|
14
|
+
ref={ref}
|
|
15
|
+
className={cn(
|
|
16
|
+
"relative flex w-full touch-none select-none items-center",
|
|
17
|
+
className
|
|
18
|
+
)}
|
|
19
|
+
{...props}
|
|
20
|
+
>
|
|
21
|
+
<SliderPrimitive.Track className="relative h-1.5 w-full grow overflow-hidden rounded-full bg-grey-300">
|
|
22
|
+
<SliderPrimitive.Range className="absolute h-full bg-main-900" />
|
|
23
|
+
</SliderPrimitive.Track>
|
|
24
|
+
<SliderPrimitive.Thumb className="block size-3 rounded-full border border-main-900 bg-white shadow transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent-600 focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50" />
|
|
25
|
+
</SliderPrimitive.Root>
|
|
26
|
+
))
|
|
27
|
+
Slider.displayName = SliderPrimitive.Root.displayName
|
|
28
|
+
|
|
29
|
+
export { Slider }
|
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from "@storybook/react"
|
|
2
|
+
import { Spinner } from "./Spinner"
|
|
3
|
+
import { Typography } from "../Typography/Typography"
|
|
4
|
+
import { Flex } from "../Flex/Flex"
|
|
5
|
+
import { Button } from "../Button/Button"
|
|
6
|
+
|
|
7
|
+
const meta: Meta<typeof Spinner> = {
|
|
8
|
+
title: "Components/Spinner",
|
|
9
|
+
component: Spinner,
|
|
10
|
+
parameters: {
|
|
11
|
+
layout: "centered",
|
|
12
|
+
},
|
|
13
|
+
tags: ["autodocs"],
|
|
14
|
+
argTypes: {
|
|
15
|
+
size: {
|
|
16
|
+
control: "select",
|
|
17
|
+
options: ["sm", "default", "md", "lg", "xl"],
|
|
18
|
+
description: "The size of the spinner",
|
|
19
|
+
},
|
|
20
|
+
variant: {
|
|
21
|
+
control: "select",
|
|
22
|
+
options: ["default", "primary", "secondary", "muted", "white"],
|
|
23
|
+
description: "The color variant of the spinner",
|
|
24
|
+
},
|
|
25
|
+
label: {
|
|
26
|
+
control: "text",
|
|
27
|
+
description: "Screen reader label for accessibility",
|
|
28
|
+
},
|
|
29
|
+
},
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export default meta
|
|
33
|
+
type Story = StoryObj<typeof Spinner>
|
|
34
|
+
|
|
35
|
+
export const Default: Story = {
|
|
36
|
+
args: {
|
|
37
|
+
size: "default",
|
|
38
|
+
variant: "default",
|
|
39
|
+
},
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export const Sizes: Story = {
|
|
43
|
+
render: () => (
|
|
44
|
+
<Flex direction="row" gap={6} align="center">
|
|
45
|
+
<Flex align="center" gap={2}>
|
|
46
|
+
<Spinner size="sm" />
|
|
47
|
+
<Typography variant="caption" color="grey-500">sm</Typography>
|
|
48
|
+
</Flex>
|
|
49
|
+
<Flex align="center" gap={2}>
|
|
50
|
+
<Spinner size="default" />
|
|
51
|
+
<Typography variant="caption" color="grey-500">default</Typography>
|
|
52
|
+
</Flex>
|
|
53
|
+
<Flex align="center" gap={2}>
|
|
54
|
+
<Spinner size="md" />
|
|
55
|
+
<Typography variant="caption" color="grey-500">md</Typography>
|
|
56
|
+
</Flex>
|
|
57
|
+
<Flex align="center" gap={2}>
|
|
58
|
+
<Spinner size="lg" />
|
|
59
|
+
<Typography variant="caption" color="grey-500">lg</Typography>
|
|
60
|
+
</Flex>
|
|
61
|
+
<Flex align="center" gap={2}>
|
|
62
|
+
<Spinner size="xl" />
|
|
63
|
+
<Typography variant="caption" color="grey-500">xl</Typography>
|
|
64
|
+
</Flex>
|
|
65
|
+
</Flex>
|
|
66
|
+
),
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export const Variants: Story = {
|
|
70
|
+
render: () => (
|
|
71
|
+
<Flex direction="row" gap={6} align="center">
|
|
72
|
+
<Flex align="center" gap={2}>
|
|
73
|
+
<Spinner variant="primary" />
|
|
74
|
+
<Typography variant="caption" color="grey-500">primary</Typography>
|
|
75
|
+
</Flex>
|
|
76
|
+
<Flex align="center" gap={2}>
|
|
77
|
+
<Spinner variant="secondary" />
|
|
78
|
+
<Typography variant="caption" color="grey-500">secondary</Typography>
|
|
79
|
+
</Flex>
|
|
80
|
+
<Flex align="center" gap={2}>
|
|
81
|
+
<Spinner variant="muted" />
|
|
82
|
+
<Typography variant="caption" color="grey-500">muted</Typography>
|
|
83
|
+
</Flex>
|
|
84
|
+
<Flex align="center" gap={2} className="bg-main-900 p-4 rounded">
|
|
85
|
+
<Spinner variant="white" />
|
|
86
|
+
<Typography variant="caption" className="text-white">white</Typography>
|
|
87
|
+
</Flex>
|
|
88
|
+
</Flex>
|
|
89
|
+
),
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
export const WithText: Story = {
|
|
93
|
+
render: () => (
|
|
94
|
+
<Flex direction="row" gap={2} align="center">
|
|
95
|
+
<Spinner size="sm" />
|
|
96
|
+
<Typography variant="body2">Loading...</Typography>
|
|
97
|
+
</Flex>
|
|
98
|
+
),
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
export const InButton: Story = {
|
|
102
|
+
render: () => (
|
|
103
|
+
<Flex direction="row" gap={4}>
|
|
104
|
+
<Button disabled>
|
|
105
|
+
<Spinner size="sm" variant="muted" className="mr-2" />
|
|
106
|
+
Loading
|
|
107
|
+
</Button>
|
|
108
|
+
<Button variant="primary" disabled>
|
|
109
|
+
<Spinner size="sm" variant="white" className="mr-2" />
|
|
110
|
+
Submitting
|
|
111
|
+
</Button>
|
|
112
|
+
</Flex>
|
|
113
|
+
),
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
export const Centered: Story = {
|
|
117
|
+
render: () => (
|
|
118
|
+
<div className="w-64 h-32 border border-grey-200 rounded-lg flex items-center justify-center">
|
|
119
|
+
<Spinner size="lg" />
|
|
120
|
+
</div>
|
|
121
|
+
),
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
export const FullPage: Story = {
|
|
125
|
+
render: () => (
|
|
126
|
+
<div className="w-96 h-64 border border-grey-200 rounded-lg relative">
|
|
127
|
+
<div className="absolute inset-0 flex flex-col items-center justify-center bg-white/80">
|
|
128
|
+
<Spinner size="lg" />
|
|
129
|
+
<Typography variant="body2" color="grey-500" className="mt-4">
|
|
130
|
+
Loading content...
|
|
131
|
+
</Typography>
|
|
132
|
+
</div>
|
|
133
|
+
</div>
|
|
134
|
+
),
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
export const AllVariants: Story = {
|
|
138
|
+
render: () => (
|
|
139
|
+
<Flex gap={8}>
|
|
140
|
+
<div>
|
|
141
|
+
<Typography variant="h4" className="mb-4">Sizes</Typography>
|
|
142
|
+
<Flex direction="row" gap={6} align="end">
|
|
143
|
+
<Flex align="center" gap={2}>
|
|
144
|
+
<Spinner size="sm" />
|
|
145
|
+
<Typography variant="caption" color="grey-500">sm (16px)</Typography>
|
|
146
|
+
</Flex>
|
|
147
|
+
<Flex align="center" gap={2}>
|
|
148
|
+
<Spinner size="default" />
|
|
149
|
+
<Typography variant="caption" color="grey-500">default (24px)</Typography>
|
|
150
|
+
</Flex>
|
|
151
|
+
<Flex align="center" gap={2}>
|
|
152
|
+
<Spinner size="md" />
|
|
153
|
+
<Typography variant="caption" color="grey-500">md (32px)</Typography>
|
|
154
|
+
</Flex>
|
|
155
|
+
<Flex align="center" gap={2}>
|
|
156
|
+
<Spinner size="lg" />
|
|
157
|
+
<Typography variant="caption" color="grey-500">lg (48px)</Typography>
|
|
158
|
+
</Flex>
|
|
159
|
+
<Flex align="center" gap={2}>
|
|
160
|
+
<Spinner size="xl" />
|
|
161
|
+
<Typography variant="caption" color="grey-500">xl (64px)</Typography>
|
|
162
|
+
</Flex>
|
|
163
|
+
</Flex>
|
|
164
|
+
</div>
|
|
165
|
+
|
|
166
|
+
<div>
|
|
167
|
+
<Typography variant="h4" className="mb-4">Color Variants</Typography>
|
|
168
|
+
<Flex direction="row" gap={6} align="center">
|
|
169
|
+
<Flex align="center" gap={2}>
|
|
170
|
+
<Spinner variant="primary" size="md" />
|
|
171
|
+
<Typography variant="caption" color="grey-500">primary</Typography>
|
|
172
|
+
</Flex>
|
|
173
|
+
<Flex align="center" gap={2}>
|
|
174
|
+
<Spinner variant="secondary" size="md" />
|
|
175
|
+
<Typography variant="caption" color="grey-500">secondary</Typography>
|
|
176
|
+
</Flex>
|
|
177
|
+
<Flex align="center" gap={2}>
|
|
178
|
+
<Spinner variant="muted" size="md" />
|
|
179
|
+
<Typography variant="caption" color="grey-500">muted</Typography>
|
|
180
|
+
</Flex>
|
|
181
|
+
<Flex align="center" gap={2} className="bg-main-900 p-4 rounded-lg">
|
|
182
|
+
<Spinner variant="white" size="md" />
|
|
183
|
+
<Typography variant="caption" className="text-white">white</Typography>
|
|
184
|
+
</Flex>
|
|
185
|
+
</Flex>
|
|
186
|
+
</div>
|
|
187
|
+
|
|
188
|
+
<div>
|
|
189
|
+
<Typography variant="h4" className="mb-4">Use Cases</Typography>
|
|
190
|
+
<Flex direction="row" gap={6} align="center" wrap="wrap">
|
|
191
|
+
<Flex direction="row" gap={2} align="center" className="border border-grey-200 rounded-lg p-4">
|
|
192
|
+
<Spinner size="sm" />
|
|
193
|
+
<Typography variant="body2">Loading data...</Typography>
|
|
194
|
+
</Flex>
|
|
195
|
+
<Button disabled className="min-w-32">
|
|
196
|
+
<Spinner size="sm" variant="muted" className="mr-2" />
|
|
197
|
+
Loading
|
|
198
|
+
</Button>
|
|
199
|
+
<Button variant="primary" disabled className="min-w-32">
|
|
200
|
+
<Spinner size="sm" variant="white" className="mr-2" />
|
|
201
|
+
Saving
|
|
202
|
+
</Button>
|
|
203
|
+
</Flex>
|
|
204
|
+
</div>
|
|
205
|
+
</Flex>
|
|
206
|
+
),
|
|
207
|
+
parameters: {
|
|
208
|
+
layout: "padded",
|
|
209
|
+
},
|
|
210
|
+
}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import * as React from "react"
|
|
2
|
+
import { cva } from "class-variance-authority"
|
|
3
|
+
import { cn } from "../lib/utils"
|
|
4
|
+
|
|
5
|
+
type SpinnerSize = "sm" | "default" | "md" | "lg" | "xl"
|
|
6
|
+
type SpinnerVariant = "default" | "primary" | "secondary" | "muted" | "white"
|
|
7
|
+
|
|
8
|
+
const spinnerVariants = cva(
|
|
9
|
+
"animate-spin",
|
|
10
|
+
{
|
|
11
|
+
variants: {
|
|
12
|
+
size: {
|
|
13
|
+
sm: "size-4",
|
|
14
|
+
default: "size-6",
|
|
15
|
+
md: "size-8",
|
|
16
|
+
lg: "size-12",
|
|
17
|
+
xl: "size-16",
|
|
18
|
+
},
|
|
19
|
+
variant: {
|
|
20
|
+
default: "text-accent-500",
|
|
21
|
+
primary: "text-accent-500",
|
|
22
|
+
secondary: "text-grey-500",
|
|
23
|
+
muted: "text-grey-400",
|
|
24
|
+
white: "text-white",
|
|
25
|
+
},
|
|
26
|
+
},
|
|
27
|
+
defaultVariants: {
|
|
28
|
+
size: "default",
|
|
29
|
+
variant: "default",
|
|
30
|
+
},
|
|
31
|
+
}
|
|
32
|
+
)
|
|
33
|
+
|
|
34
|
+
export interface SpinnerProps
|
|
35
|
+
extends React.SVGAttributes<SVGSVGElement> {
|
|
36
|
+
size?: SpinnerSize
|
|
37
|
+
variant?: SpinnerVariant
|
|
38
|
+
/**
|
|
39
|
+
* Screen reader label for accessibility
|
|
40
|
+
* @default "Loading"
|
|
41
|
+
*/
|
|
42
|
+
label?: string
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
const Spinner = React.forwardRef<SVGSVGElement, SpinnerProps>(
|
|
46
|
+
({ className, size, variant, label = "Loading", ...props }, ref) => {
|
|
47
|
+
return (
|
|
48
|
+
<svg
|
|
49
|
+
ref={ref}
|
|
50
|
+
className={cn(spinnerVariants({ size, variant, className }))}
|
|
51
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
52
|
+
fill="none"
|
|
53
|
+
viewBox="0 0 24 24"
|
|
54
|
+
role="status"
|
|
55
|
+
aria-label={label}
|
|
56
|
+
{...props}
|
|
57
|
+
>
|
|
58
|
+
<circle
|
|
59
|
+
className="opacity-25"
|
|
60
|
+
cx="12"
|
|
61
|
+
cy="12"
|
|
62
|
+
r="10"
|
|
63
|
+
stroke="currentColor"
|
|
64
|
+
strokeWidth="4"
|
|
65
|
+
/>
|
|
66
|
+
<path
|
|
67
|
+
className="opacity-75"
|
|
68
|
+
fill="currentColor"
|
|
69
|
+
d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"
|
|
70
|
+
/>
|
|
71
|
+
</svg>
|
|
72
|
+
)
|
|
73
|
+
}
|
|
74
|
+
)
|
|
75
|
+
Spinner.displayName = "Spinner"
|
|
76
|
+
|
|
77
|
+
export { Spinner, spinnerVariants }
|
|
78
|
+
export type { SpinnerSize, SpinnerVariant }
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from "@storybook/react"
|
|
2
|
+
|
|
3
|
+
import { Label } from "../Label/Label"
|
|
4
|
+
import { Flex } from "../Flex/Flex"
|
|
5
|
+
import { Typography } from "../Typography/Typography"
|
|
6
|
+
import { Switch } from "./Switch"
|
|
7
|
+
|
|
8
|
+
const meta: Meta<typeof Switch> = {
|
|
9
|
+
title: "Components/Switch",
|
|
10
|
+
component: Switch,
|
|
11
|
+
parameters: {
|
|
12
|
+
layout: "centered",
|
|
13
|
+
},
|
|
14
|
+
argTypes: {
|
|
15
|
+
size: {
|
|
16
|
+
control: "select",
|
|
17
|
+
options: ["small", "regular"],
|
|
18
|
+
description: "The size of the switch",
|
|
19
|
+
},
|
|
20
|
+
checked: {
|
|
21
|
+
control: "boolean",
|
|
22
|
+
description: "The checked state",
|
|
23
|
+
},
|
|
24
|
+
disabled: {
|
|
25
|
+
control: "boolean",
|
|
26
|
+
description: "Whether the switch is disabled",
|
|
27
|
+
},
|
|
28
|
+
},
|
|
29
|
+
tags: ["autodocs"],
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export default meta
|
|
33
|
+
type Story = StoryObj<typeof meta>
|
|
34
|
+
|
|
35
|
+
export const Default: Story = {
|
|
36
|
+
render: () => <Switch />,
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export const Checked: Story = {
|
|
40
|
+
render: () => <Switch defaultChecked />,
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export const WithLabel: Story = {
|
|
44
|
+
render: () => (
|
|
45
|
+
<Flex direction="row" align="center" gap={2}>
|
|
46
|
+
<Switch id="airplane-mode" />
|
|
47
|
+
<Label htmlFor="airplane-mode">Airplane Mode</Label>
|
|
48
|
+
</Flex>
|
|
49
|
+
),
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export const Disabled: Story = {
|
|
53
|
+
render: () => (
|
|
54
|
+
<Flex gap={3}>
|
|
55
|
+
<Flex direction="row" align="center" gap={2}>
|
|
56
|
+
<Switch id="disabled" disabled />
|
|
57
|
+
<Label htmlFor="disabled" className="opacity-50">Disabled</Label>
|
|
58
|
+
</Flex>
|
|
59
|
+
<Flex direction="row" align="center" gap={2}>
|
|
60
|
+
<Switch id="disabled-checked" disabled defaultChecked />
|
|
61
|
+
<Label htmlFor="disabled-checked" className="opacity-50">Disabled checked</Label>
|
|
62
|
+
</Flex>
|
|
63
|
+
</Flex>
|
|
64
|
+
),
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
export const Small: Story = {
|
|
68
|
+
render: () => (
|
|
69
|
+
<Flex direction="row" align="center" gap={2}>
|
|
70
|
+
<Switch id="small" size="small" />
|
|
71
|
+
<Label htmlFor="small" className="text-sm">Small switch</Label>
|
|
72
|
+
</Flex>
|
|
73
|
+
),
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
export const AllVariants: Story = {
|
|
77
|
+
render: () => (
|
|
78
|
+
<Flex gap={6}>
|
|
79
|
+
<Typography variant="h4" className="text-white">Switch States</Typography>
|
|
80
|
+
|
|
81
|
+
<Flex gap={4}>
|
|
82
|
+
<Flex direction="row" align="center" gap={2}>
|
|
83
|
+
<Switch id="off" />
|
|
84
|
+
<Label htmlFor="off">Off</Label>
|
|
85
|
+
</Flex>
|
|
86
|
+
|
|
87
|
+
<Flex direction="row" align="center" gap={2}>
|
|
88
|
+
<Switch id="on" defaultChecked />
|
|
89
|
+
<Label htmlFor="on">On</Label>
|
|
90
|
+
</Flex>
|
|
91
|
+
|
|
92
|
+
<Flex direction="row" align="center" gap={2}>
|
|
93
|
+
<Switch id="disabled-off" disabled />
|
|
94
|
+
<Label htmlFor="disabled-off" className="opacity-50">Disabled Off</Label>
|
|
95
|
+
</Flex>
|
|
96
|
+
|
|
97
|
+
<Flex direction="row" align="center" gap={2}>
|
|
98
|
+
<Switch id="disabled-on" disabled defaultChecked />
|
|
99
|
+
<Label htmlFor="disabled-on" className="opacity-50">Disabled On</Label>
|
|
100
|
+
</Flex>
|
|
101
|
+
</Flex>
|
|
102
|
+
|
|
103
|
+
<Typography variant="h4" className="text-white mt-4">Sizes</Typography>
|
|
104
|
+
|
|
105
|
+
<Flex gap={4}>
|
|
106
|
+
<Flex direction="row" align="center" gap={2}>
|
|
107
|
+
<Switch id="small-size" size="small" defaultChecked />
|
|
108
|
+
<Label htmlFor="small-size" className="text-sm">Small</Label>
|
|
109
|
+
</Flex>
|
|
110
|
+
|
|
111
|
+
<Flex direction="row" align="center" gap={2}>
|
|
112
|
+
<Switch id="regular-size" size="regular" defaultChecked />
|
|
113
|
+
<Label htmlFor="regular-size">Regular</Label>
|
|
114
|
+
</Flex>
|
|
115
|
+
</Flex>
|
|
116
|
+
|
|
117
|
+
<Typography variant="h4" className="text-white mt-4">Settings Example</Typography>
|
|
118
|
+
|
|
119
|
+
<div className="w-[300px] bg-white rounded-lg p-4 space-y-4">
|
|
120
|
+
<Flex direction="row" justify="between" align="center">
|
|
121
|
+
<Flex gap={1}>
|
|
122
|
+
<Typography variant="body2">Dark Mode</Typography>
|
|
123
|
+
<Typography variant="caption" color="grey-500">Enable dark theme</Typography>
|
|
124
|
+
</Flex>
|
|
125
|
+
<Switch defaultChecked />
|
|
126
|
+
</Flex>
|
|
127
|
+
|
|
128
|
+
<Flex direction="row" justify="between" align="center">
|
|
129
|
+
<Flex gap={1}>
|
|
130
|
+
<Typography variant="body2">Notifications</Typography>
|
|
131
|
+
<Typography variant="caption" color="grey-500">Receive push notifications</Typography>
|
|
132
|
+
</Flex>
|
|
133
|
+
<Switch />
|
|
134
|
+
</Flex>
|
|
135
|
+
|
|
136
|
+
<Flex direction="row" justify="between" align="center">
|
|
137
|
+
<Flex gap={1}>
|
|
138
|
+
<Typography variant="body2">Auto-save</Typography>
|
|
139
|
+
<Typography variant="caption" color="grey-500">Save changes automatically</Typography>
|
|
140
|
+
</Flex>
|
|
141
|
+
<Switch defaultChecked />
|
|
142
|
+
</Flex>
|
|
143
|
+
</div>
|
|
144
|
+
</Flex>
|
|
145
|
+
),
|
|
146
|
+
}
|