@a2v2ai/uikit 0.0.2 → 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/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 +1 -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,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 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 direction="column" gap={3}>
|
|
55
|
+
<Flex align="center" gap={2}>
|
|
56
|
+
<Switch id="disabled" disabled />
|
|
57
|
+
<Label htmlFor="disabled" className="opacity-50">Disabled</Label>
|
|
58
|
+
</Flex>
|
|
59
|
+
<Flex 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 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 direction="column" gap={6}>
|
|
79
|
+
<Typography variant="h4" className="text-white">Switch States</Typography>
|
|
80
|
+
|
|
81
|
+
<Flex direction="column" gap={4}>
|
|
82
|
+
<Flex align="center" gap={2}>
|
|
83
|
+
<Switch id="off" />
|
|
84
|
+
<Label htmlFor="off">Off</Label>
|
|
85
|
+
</Flex>
|
|
86
|
+
|
|
87
|
+
<Flex align="center" gap={2}>
|
|
88
|
+
<Switch id="on" defaultChecked />
|
|
89
|
+
<Label htmlFor="on">On</Label>
|
|
90
|
+
</Flex>
|
|
91
|
+
|
|
92
|
+
<Flex 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 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 direction="column" gap={4}>
|
|
106
|
+
<Flex 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 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 justify="between" align="center">
|
|
121
|
+
<Flex direction="column" 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 justify="between" align="center">
|
|
129
|
+
<Flex direction="column" 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 justify="between" align="center">
|
|
137
|
+
<Flex direction="column" 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
|
+
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import * as React from "react"
|
|
2
|
+
import * as SwitchPrimitive from "@radix-ui/react-switch"
|
|
3
|
+
import { cva } from "class-variance-authority"
|
|
4
|
+
|
|
5
|
+
import { cn } from "../lib/utils"
|
|
6
|
+
|
|
7
|
+
type SwitchSize = "small" | "regular"
|
|
8
|
+
|
|
9
|
+
const switchVariants = cva(
|
|
10
|
+
"peer inline-flex shrink-0 cursor-pointer items-center rounded-full border-2 border-transparent shadow-sm transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-main-950 focus-visible:ring-offset-2 focus-visible:ring-offset-white disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-main-950 data-[state=unchecked]:bg-grey-200",
|
|
11
|
+
{
|
|
12
|
+
variants: {
|
|
13
|
+
size: {
|
|
14
|
+
small: "h-5 w-9",
|
|
15
|
+
regular: "h-6 w-11",
|
|
16
|
+
},
|
|
17
|
+
},
|
|
18
|
+
defaultVariants: {
|
|
19
|
+
size: "regular",
|
|
20
|
+
},
|
|
21
|
+
}
|
|
22
|
+
)
|
|
23
|
+
|
|
24
|
+
const switchThumbVariants = cva(
|
|
25
|
+
"pointer-events-none block rounded-full bg-white shadow-lg ring-0 transition-transform data-[state=unchecked]:translate-x-0",
|
|
26
|
+
{
|
|
27
|
+
variants: {
|
|
28
|
+
size: {
|
|
29
|
+
small: "size-4 data-[state=checked]:translate-x-4",
|
|
30
|
+
regular: "size-5 data-[state=checked]:translate-x-5",
|
|
31
|
+
},
|
|
32
|
+
},
|
|
33
|
+
defaultVariants: {
|
|
34
|
+
size: "regular",
|
|
35
|
+
},
|
|
36
|
+
}
|
|
37
|
+
)
|
|
38
|
+
|
|
39
|
+
export interface SwitchProps
|
|
40
|
+
extends React.ComponentPropsWithoutRef<typeof SwitchPrimitive.Root> {
|
|
41
|
+
size?: SwitchSize
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const Switch = React.forwardRef<
|
|
45
|
+
React.ElementRef<typeof SwitchPrimitive.Root>,
|
|
46
|
+
SwitchProps
|
|
47
|
+
>(({ className, size, ...props }, ref) => (
|
|
48
|
+
<SwitchPrimitive.Root
|
|
49
|
+
className={cn(switchVariants({ size }), className)}
|
|
50
|
+
{...props}
|
|
51
|
+
ref={ref}
|
|
52
|
+
>
|
|
53
|
+
<SwitchPrimitive.Thumb className={cn(switchThumbVariants({ size }))} />
|
|
54
|
+
</SwitchPrimitive.Root>
|
|
55
|
+
))
|
|
56
|
+
Switch.displayName = SwitchPrimitive.Root.displayName
|
|
57
|
+
|
|
58
|
+
export { Switch, switchVariants }
|
|
59
|
+
export type { SwitchSize }
|
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from "@storybook/react"
|
|
2
|
+
|
|
3
|
+
import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from "../Card/Card"
|
|
4
|
+
import { Button } from "../Button/Button"
|
|
5
|
+
import { Input } from "../Input/Input"
|
|
6
|
+
import { Label } from "../Label/Label"
|
|
7
|
+
import { Flex } from "../Flex/Flex"
|
|
8
|
+
import { Typography } from "../Typography/Typography"
|
|
9
|
+
import { Tabs, TabsList, TabsTrigger, TabsContent } from "./Tabs"
|
|
10
|
+
|
|
11
|
+
const meta: Meta<typeof Tabs> = {
|
|
12
|
+
title: "Components/Tabs",
|
|
13
|
+
component: Tabs,
|
|
14
|
+
parameters: {
|
|
15
|
+
layout: "centered",
|
|
16
|
+
},
|
|
17
|
+
tags: ["autodocs"],
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export default meta
|
|
21
|
+
type Story = StoryObj<typeof meta>
|
|
22
|
+
|
|
23
|
+
export const Default: Story = {
|
|
24
|
+
render: () => (
|
|
25
|
+
<Tabs defaultValue="account" className="w-[400px]">
|
|
26
|
+
<TabsList>
|
|
27
|
+
<TabsTrigger value="account">Account</TabsTrigger>
|
|
28
|
+
<TabsTrigger value="password">Password</TabsTrigger>
|
|
29
|
+
</TabsList>
|
|
30
|
+
<TabsContent value="account">
|
|
31
|
+
<Card>
|
|
32
|
+
<CardHeader>
|
|
33
|
+
<CardTitle>Account</CardTitle>
|
|
34
|
+
<CardDescription>
|
|
35
|
+
Make changes to your account here. Click save when you're done.
|
|
36
|
+
</CardDescription>
|
|
37
|
+
</CardHeader>
|
|
38
|
+
<CardContent className="space-y-2">
|
|
39
|
+
<div className="space-y-1">
|
|
40
|
+
<Label htmlFor="name">Name</Label>
|
|
41
|
+
<Input id="name" defaultValue="Pedro Duarte" />
|
|
42
|
+
</div>
|
|
43
|
+
<div className="space-y-1">
|
|
44
|
+
<Label htmlFor="username">Username</Label>
|
|
45
|
+
<Input id="username" defaultValue="@peduarte" />
|
|
46
|
+
</div>
|
|
47
|
+
</CardContent>
|
|
48
|
+
<CardFooter>
|
|
49
|
+
<Button>Save changes</Button>
|
|
50
|
+
</CardFooter>
|
|
51
|
+
</Card>
|
|
52
|
+
</TabsContent>
|
|
53
|
+
<TabsContent value="password">
|
|
54
|
+
<Card>
|
|
55
|
+
<CardHeader>
|
|
56
|
+
<CardTitle>Password</CardTitle>
|
|
57
|
+
<CardDescription>
|
|
58
|
+
Change your password here. After saving, you'll be logged out.
|
|
59
|
+
</CardDescription>
|
|
60
|
+
</CardHeader>
|
|
61
|
+
<CardContent className="space-y-2">
|
|
62
|
+
<div className="space-y-1">
|
|
63
|
+
<Label htmlFor="current">Current password</Label>
|
|
64
|
+
<Input id="current" type="password" />
|
|
65
|
+
</div>
|
|
66
|
+
<div className="space-y-1">
|
|
67
|
+
<Label htmlFor="new">New password</Label>
|
|
68
|
+
<Input id="new" type="password" />
|
|
69
|
+
</div>
|
|
70
|
+
</CardContent>
|
|
71
|
+
<CardFooter>
|
|
72
|
+
<Button>Save password</Button>
|
|
73
|
+
</CardFooter>
|
|
74
|
+
</Card>
|
|
75
|
+
</TabsContent>
|
|
76
|
+
</Tabs>
|
|
77
|
+
),
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
export const Simple: Story = {
|
|
81
|
+
render: () => (
|
|
82
|
+
<Tabs defaultValue="tab1" className="w-[400px]">
|
|
83
|
+
<TabsList>
|
|
84
|
+
<TabsTrigger value="tab1">Tab 1</TabsTrigger>
|
|
85
|
+
<TabsTrigger value="tab2">Tab 2</TabsTrigger>
|
|
86
|
+
<TabsTrigger value="tab3">Tab 3</TabsTrigger>
|
|
87
|
+
</TabsList>
|
|
88
|
+
<TabsContent value="tab1" className="p-4 bg-white rounded-lg mt-2">
|
|
89
|
+
<p>Content for Tab 1</p>
|
|
90
|
+
</TabsContent>
|
|
91
|
+
<TabsContent value="tab2" className="p-4 bg-white rounded-lg mt-2">
|
|
92
|
+
<p>Content for Tab 2</p>
|
|
93
|
+
</TabsContent>
|
|
94
|
+
<TabsContent value="tab3" className="p-4 bg-white rounded-lg mt-2">
|
|
95
|
+
<p>Content for Tab 3</p>
|
|
96
|
+
</TabsContent>
|
|
97
|
+
</Tabs>
|
|
98
|
+
),
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
export const Outline: Story = {
|
|
102
|
+
render: () => (
|
|
103
|
+
<Tabs defaultValue="overview" className="w-[400px]">
|
|
104
|
+
<TabsList variant="outline">
|
|
105
|
+
<TabsTrigger value="overview">Overview</TabsTrigger>
|
|
106
|
+
<TabsTrigger value="analytics">Analytics</TabsTrigger>
|
|
107
|
+
<TabsTrigger value="reports">Reports</TabsTrigger>
|
|
108
|
+
</TabsList>
|
|
109
|
+
<TabsContent value="overview" className="p-4 bg-white rounded-lg mt-2">
|
|
110
|
+
<p>Overview content</p>
|
|
111
|
+
</TabsContent>
|
|
112
|
+
<TabsContent value="analytics" className="p-4 bg-white rounded-lg mt-2">
|
|
113
|
+
<p>Analytics content</p>
|
|
114
|
+
</TabsContent>
|
|
115
|
+
<TabsContent value="reports" className="p-4 bg-white rounded-lg mt-2">
|
|
116
|
+
<p>Reports content</p>
|
|
117
|
+
</TabsContent>
|
|
118
|
+
</Tabs>
|
|
119
|
+
),
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
export const Disabled: Story = {
|
|
123
|
+
render: () => (
|
|
124
|
+
<Tabs defaultValue="active" className="w-[400px]">
|
|
125
|
+
<TabsList>
|
|
126
|
+
<TabsTrigger value="active">Active</TabsTrigger>
|
|
127
|
+
<TabsTrigger value="disabled" disabled>Disabled</TabsTrigger>
|
|
128
|
+
<TabsTrigger value="another">Another</TabsTrigger>
|
|
129
|
+
</TabsList>
|
|
130
|
+
<TabsContent value="active" className="p-4 bg-white rounded-lg mt-2">
|
|
131
|
+
<p>Active tab content</p>
|
|
132
|
+
</TabsContent>
|
|
133
|
+
<TabsContent value="another" className="p-4 bg-white rounded-lg mt-2">
|
|
134
|
+
<p>Another tab content</p>
|
|
135
|
+
</TabsContent>
|
|
136
|
+
</Tabs>
|
|
137
|
+
),
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
export const AllVariants: Story = {
|
|
141
|
+
render: () => (
|
|
142
|
+
<Flex direction="column" gap={8}>
|
|
143
|
+
<Typography variant="h4" className="text-white">Tab Variants</Typography>
|
|
144
|
+
|
|
145
|
+
<Flex direction="column" gap={4}>
|
|
146
|
+
<Typography variant="body2" className="text-grey-400">Default</Typography>
|
|
147
|
+
<Tabs defaultValue="tab1" className="w-[350px]">
|
|
148
|
+
<TabsList>
|
|
149
|
+
<TabsTrigger value="tab1">First</TabsTrigger>
|
|
150
|
+
<TabsTrigger value="tab2">Second</TabsTrigger>
|
|
151
|
+
<TabsTrigger value="tab3">Third</TabsTrigger>
|
|
152
|
+
</TabsList>
|
|
153
|
+
<TabsContent value="tab1" className="p-4 bg-white rounded-lg mt-2">
|
|
154
|
+
First tab content
|
|
155
|
+
</TabsContent>
|
|
156
|
+
<TabsContent value="tab2" className="p-4 bg-white rounded-lg mt-2">
|
|
157
|
+
Second tab content
|
|
158
|
+
</TabsContent>
|
|
159
|
+
<TabsContent value="tab3" className="p-4 bg-white rounded-lg mt-2">
|
|
160
|
+
Third tab content
|
|
161
|
+
</TabsContent>
|
|
162
|
+
</Tabs>
|
|
163
|
+
</Flex>
|
|
164
|
+
|
|
165
|
+
<Flex direction="column" gap={4}>
|
|
166
|
+
<Typography variant="body2" className="text-grey-400">Outline</Typography>
|
|
167
|
+
<Tabs defaultValue="tab1" className="w-[350px]">
|
|
168
|
+
<TabsList variant="outline">
|
|
169
|
+
<TabsTrigger value="tab1">First</TabsTrigger>
|
|
170
|
+
<TabsTrigger value="tab2">Second</TabsTrigger>
|
|
171
|
+
<TabsTrigger value="tab3">Third</TabsTrigger>
|
|
172
|
+
</TabsList>
|
|
173
|
+
<TabsContent value="tab1" className="p-4 bg-white rounded-lg mt-2">
|
|
174
|
+
First tab content
|
|
175
|
+
</TabsContent>
|
|
176
|
+
<TabsContent value="tab2" className="p-4 bg-white rounded-lg mt-2">
|
|
177
|
+
Second tab content
|
|
178
|
+
</TabsContent>
|
|
179
|
+
<TabsContent value="tab3" className="p-4 bg-white rounded-lg mt-2">
|
|
180
|
+
Third tab content
|
|
181
|
+
</TabsContent>
|
|
182
|
+
</Tabs>
|
|
183
|
+
</Flex>
|
|
184
|
+
|
|
185
|
+
<Flex direction="column" gap={4}>
|
|
186
|
+
<Typography variant="body2" className="text-grey-400">With Disabled Tab</Typography>
|
|
187
|
+
<Tabs defaultValue="enabled1" className="w-[350px]">
|
|
188
|
+
<TabsList>
|
|
189
|
+
<TabsTrigger value="enabled1">Enabled</TabsTrigger>
|
|
190
|
+
<TabsTrigger value="disabled1" disabled>Disabled</TabsTrigger>
|
|
191
|
+
<TabsTrigger value="enabled2">Enabled</TabsTrigger>
|
|
192
|
+
</TabsList>
|
|
193
|
+
</Tabs>
|
|
194
|
+
</Flex>
|
|
195
|
+
</Flex>
|
|
196
|
+
),
|
|
197
|
+
}
|
package/Tabs/Tabs.tsx
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import * as React from "react"
|
|
2
|
+
import * as TabsPrimitive from "@radix-ui/react-tabs"
|
|
3
|
+
import { cva } from "class-variance-authority"
|
|
4
|
+
|
|
5
|
+
import { cn } from "../lib/utils"
|
|
6
|
+
|
|
7
|
+
type TabsListVariant = "default" | "outline"
|
|
8
|
+
|
|
9
|
+
const Tabs = TabsPrimitive.Root
|
|
10
|
+
|
|
11
|
+
const tabsListVariants = cva(
|
|
12
|
+
"inline-flex items-center justify-center rounded-lg bg-grey-100 p-1 text-grey-500",
|
|
13
|
+
{
|
|
14
|
+
variants: {
|
|
15
|
+
variant: {
|
|
16
|
+
default: "bg-grey-100",
|
|
17
|
+
outline: "bg-transparent border border-grey-200",
|
|
18
|
+
},
|
|
19
|
+
},
|
|
20
|
+
defaultVariants: {
|
|
21
|
+
variant: "default",
|
|
22
|
+
},
|
|
23
|
+
}
|
|
24
|
+
)
|
|
25
|
+
|
|
26
|
+
export interface TabsListProps
|
|
27
|
+
extends React.ComponentPropsWithoutRef<typeof TabsPrimitive.List> {
|
|
28
|
+
variant?: TabsListVariant
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const TabsList = React.forwardRef<
|
|
32
|
+
React.ElementRef<typeof TabsPrimitive.List>,
|
|
33
|
+
TabsListProps
|
|
34
|
+
>(({ className, variant, ...props }, ref) => (
|
|
35
|
+
<TabsPrimitive.List
|
|
36
|
+
ref={ref}
|
|
37
|
+
className={cn(tabsListVariants({ variant }), className)}
|
|
38
|
+
{...props}
|
|
39
|
+
/>
|
|
40
|
+
))
|
|
41
|
+
TabsList.displayName = TabsPrimitive.List.displayName
|
|
42
|
+
|
|
43
|
+
const TabsTrigger = React.forwardRef<
|
|
44
|
+
React.ElementRef<typeof TabsPrimitive.Trigger>,
|
|
45
|
+
React.ComponentPropsWithoutRef<typeof TabsPrimitive.Trigger>
|
|
46
|
+
>(({ className, ...props }, ref) => (
|
|
47
|
+
<TabsPrimitive.Trigger
|
|
48
|
+
ref={ref}
|
|
49
|
+
className={cn(
|
|
50
|
+
"inline-flex items-center justify-center whitespace-nowrap rounded-md px-3 py-1 text-sm font-medium ring-offset-white transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-main-950 focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 data-[state=active]:bg-white data-[state=active]:text-main-950 data-[state=active]:shadow-sm",
|
|
51
|
+
className
|
|
52
|
+
)}
|
|
53
|
+
{...props}
|
|
54
|
+
/>
|
|
55
|
+
))
|
|
56
|
+
TabsTrigger.displayName = TabsPrimitive.Trigger.displayName
|
|
57
|
+
|
|
58
|
+
const TabsContent = React.forwardRef<
|
|
59
|
+
React.ElementRef<typeof TabsPrimitive.Content>,
|
|
60
|
+
React.ComponentPropsWithoutRef<typeof TabsPrimitive.Content>
|
|
61
|
+
>(({ className, ...props }, ref) => (
|
|
62
|
+
<TabsPrimitive.Content
|
|
63
|
+
ref={ref}
|
|
64
|
+
className={cn(
|
|
65
|
+
"mt-2 ring-offset-white focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-main-950 focus-visible:ring-offset-2",
|
|
66
|
+
className
|
|
67
|
+
)}
|
|
68
|
+
{...props}
|
|
69
|
+
/>
|
|
70
|
+
))
|
|
71
|
+
TabsContent.displayName = TabsPrimitive.Content.displayName
|
|
72
|
+
|
|
73
|
+
export { Tabs, TabsList, TabsTrigger, TabsContent, tabsListVariants }
|
|
74
|
+
export type { TabsListVariant }
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from "@storybook/react"
|
|
2
|
+
|
|
3
|
+
import { Label } from "../Label/Label"
|
|
4
|
+
import { Button } from "../Button/Button"
|
|
5
|
+
import { Flex } from "../Flex/Flex"
|
|
6
|
+
import { Typography } from "../Typography/Typography"
|
|
7
|
+
import { Textarea } from "./Textarea"
|
|
8
|
+
|
|
9
|
+
const meta: Meta<typeof Textarea> = {
|
|
10
|
+
title: "Components/Textarea",
|
|
11
|
+
component: Textarea,
|
|
12
|
+
parameters: {
|
|
13
|
+
layout: "centered",
|
|
14
|
+
},
|
|
15
|
+
argTypes: {
|
|
16
|
+
variant: {
|
|
17
|
+
control: "select",
|
|
18
|
+
options: ["default", "error"],
|
|
19
|
+
description: "The visual variant",
|
|
20
|
+
},
|
|
21
|
+
placeholder: {
|
|
22
|
+
control: "text",
|
|
23
|
+
description: "Placeholder text",
|
|
24
|
+
},
|
|
25
|
+
disabled: {
|
|
26
|
+
control: "boolean",
|
|
27
|
+
description: "Whether the textarea is disabled",
|
|
28
|
+
},
|
|
29
|
+
},
|
|
30
|
+
tags: ["autodocs"],
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export default meta
|
|
34
|
+
type Story = StoryObj<typeof meta>
|
|
35
|
+
|
|
36
|
+
export const Default: Story = {
|
|
37
|
+
render: () => <Textarea placeholder="Type your message here." className="w-[300px]" />,
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export const WithLabel: Story = {
|
|
41
|
+
render: () => (
|
|
42
|
+
<Flex direction="column" gap={2} className="w-[300px]">
|
|
43
|
+
<Label htmlFor="message">Your message</Label>
|
|
44
|
+
<Textarea placeholder="Type your message here." id="message" />
|
|
45
|
+
</Flex>
|
|
46
|
+
),
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export const WithText: Story = {
|
|
50
|
+
render: () => (
|
|
51
|
+
<Flex direction="column" gap={2} className="w-[300px]">
|
|
52
|
+
<Label htmlFor="bio">Bio</Label>
|
|
53
|
+
<Textarea placeholder="Tell us a little bit about yourself" id="bio" />
|
|
54
|
+
<Typography variant="caption" color="grey-500">
|
|
55
|
+
You can @mention other users and organizations.
|
|
56
|
+
</Typography>
|
|
57
|
+
</Flex>
|
|
58
|
+
),
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export const Disabled: Story = {
|
|
62
|
+
render: () => (
|
|
63
|
+
<Textarea placeholder="This textarea is disabled" disabled className="w-[300px]" />
|
|
64
|
+
),
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
export const Error: Story = {
|
|
68
|
+
render: () => (
|
|
69
|
+
<Flex direction="column" gap={2} className="w-[300px]">
|
|
70
|
+
<Label htmlFor="message-error" variant="error">Message</Label>
|
|
71
|
+
<Textarea
|
|
72
|
+
placeholder="Type your message here."
|
|
73
|
+
id="message-error"
|
|
74
|
+
variant="error"
|
|
75
|
+
/>
|
|
76
|
+
<Typography variant="caption" color="error-500">
|
|
77
|
+
Message is required.
|
|
78
|
+
</Typography>
|
|
79
|
+
</Flex>
|
|
80
|
+
),
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
export const WithButton: Story = {
|
|
84
|
+
render: () => (
|
|
85
|
+
<Flex direction="column" gap={4} className="w-[300px]">
|
|
86
|
+
<Flex direction="column" gap={2}>
|
|
87
|
+
<Label htmlFor="feedback">Send us your feedback</Label>
|
|
88
|
+
<Textarea
|
|
89
|
+
placeholder="What can we improve?"
|
|
90
|
+
id="feedback"
|
|
91
|
+
/>
|
|
92
|
+
</Flex>
|
|
93
|
+
<Button>Submit</Button>
|
|
94
|
+
</Flex>
|
|
95
|
+
),
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
export const AllVariants: Story = {
|
|
99
|
+
render: () => (
|
|
100
|
+
<Flex direction="column" gap={6}>
|
|
101
|
+
<Typography variant="h4" className="text-white">Textarea Variants</Typography>
|
|
102
|
+
|
|
103
|
+
<Flex gap={6}>
|
|
104
|
+
<Flex direction="column" gap={2} className="w-[250px]">
|
|
105
|
+
<Label htmlFor="default">Default</Label>
|
|
106
|
+
<Textarea
|
|
107
|
+
id="default"
|
|
108
|
+
placeholder="Enter text..."
|
|
109
|
+
/>
|
|
110
|
+
</Flex>
|
|
111
|
+
|
|
112
|
+
<Flex direction="column" gap={2} className="w-[250px]">
|
|
113
|
+
<Label htmlFor="error-state" variant="error">Error</Label>
|
|
114
|
+
<Textarea
|
|
115
|
+
id="error-state"
|
|
116
|
+
placeholder="Enter text..."
|
|
117
|
+
variant="error"
|
|
118
|
+
/>
|
|
119
|
+
<Typography variant="caption" color="error-500">
|
|
120
|
+
This field is required.
|
|
121
|
+
</Typography>
|
|
122
|
+
</Flex>
|
|
123
|
+
</Flex>
|
|
124
|
+
|
|
125
|
+
<Typography variant="h4" className="text-white mt-4">States</Typography>
|
|
126
|
+
|
|
127
|
+
<Flex gap={6}>
|
|
128
|
+
<Flex direction="column" gap={2} className="w-[250px]">
|
|
129
|
+
<Label>Enabled</Label>
|
|
130
|
+
<Textarea placeholder="Type here..." />
|
|
131
|
+
</Flex>
|
|
132
|
+
|
|
133
|
+
<Flex direction="column" gap={2} className="w-[250px]">
|
|
134
|
+
<Label className="opacity-50">Disabled</Label>
|
|
135
|
+
<Textarea placeholder="Disabled textarea" disabled />
|
|
136
|
+
</Flex>
|
|
137
|
+
</Flex>
|
|
138
|
+
|
|
139
|
+
<Typography variant="h4" className="text-white mt-4">With Character Count</Typography>
|
|
140
|
+
|
|
141
|
+
<Flex direction="column" gap={2} className="w-[300px]">
|
|
142
|
+
<Flex justify="between">
|
|
143
|
+
<Label htmlFor="with-count">Description</Label>
|
|
144
|
+
<Typography variant="caption" color="grey-500">0/200</Typography>
|
|
145
|
+
</Flex>
|
|
146
|
+
<Textarea
|
|
147
|
+
id="with-count"
|
|
148
|
+
placeholder="Describe your project..."
|
|
149
|
+
rows={4}
|
|
150
|
+
/>
|
|
151
|
+
</Flex>
|
|
152
|
+
|
|
153
|
+
<Typography variant="h4" className="text-white mt-4">Comment Form Example</Typography>
|
|
154
|
+
|
|
155
|
+
<div className="w-[350px] bg-white rounded-lg p-4 space-y-4">
|
|
156
|
+
<Flex direction="column" gap={2}>
|
|
157
|
+
<Label htmlFor="comment">Leave a comment</Label>
|
|
158
|
+
<Textarea
|
|
159
|
+
id="comment"
|
|
160
|
+
placeholder="Write your comment here..."
|
|
161
|
+
rows={3}
|
|
162
|
+
/>
|
|
163
|
+
</Flex>
|
|
164
|
+
<Flex justify="end">
|
|
165
|
+
<Button size="small">Post Comment</Button>
|
|
166
|
+
</Flex>
|
|
167
|
+
</div>
|
|
168
|
+
</Flex>
|
|
169
|
+
),
|
|
170
|
+
}
|