@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.
Files changed (147) hide show
  1. package/Alert/Alert.stories.tsx +121 -0
  2. package/Alert/Alert.tsx +71 -0
  3. package/AlertDialog/AlertDialog.stories.tsx +665 -0
  4. package/AlertDialog/AlertDialog.tsx +241 -0
  5. package/Avatar/Avatar.stories.tsx +128 -0
  6. package/Avatar/Avatar.tsx +71 -0
  7. package/Badge/Badge.stories.tsx +76 -0
  8. package/Badge/Badge.tsx +39 -0
  9. package/Breadcrumb/Breadcrumb.stories.tsx +231 -0
  10. package/Breadcrumb/Breadcrumb.tsx +114 -0
  11. package/Button/Button.stories.tsx +684 -0
  12. package/Button/Button.tsx +90 -0
  13. package/Calendar/Calendar.stories.tsx +207 -0
  14. package/Calendar/Calendar.tsx +232 -0
  15. package/Card/Card.stories.tsx +136 -0
  16. package/Card/Card.tsx +96 -0
  17. package/ChatBubble/ChatBubble.stories.tsx +307 -0
  18. package/ChatBubble/ChatBubble.tsx +167 -0
  19. package/Checkbox/Checkbox.stories.tsx +137 -0
  20. package/Checkbox/Checkbox.tsx +53 -0
  21. package/Drawer/Drawer.stories.tsx +721 -0
  22. package/Drawer/Drawer.tsx +201 -0
  23. package/DropdownMenu/DropdownMenu.stories.tsx +251 -0
  24. package/DropdownMenu/DropdownMenu.tsx +199 -0
  25. package/ErrorMessage/ErrorMessage.stories.tsx +159 -0
  26. package/ErrorMessage/ErrorMessage.tsx +55 -0
  27. package/Flex/Flex.tsx +102 -0
  28. package/IconButton/IconButton.stories.tsx +566 -0
  29. package/IconButton/IconButton.tsx +95 -0
  30. package/Input/Input.stories.tsx +456 -0
  31. package/Input/Input.tsx +129 -0
  32. package/InputOTP/InputOTP.stories.tsx +246 -0
  33. package/InputOTP/InputOTP.tsx +127 -0
  34. package/Label/Label.stories.tsx +105 -0
  35. package/Label/Label.tsx +43 -0
  36. package/Loader/Loader.stories.tsx +170 -0
  37. package/Loader/Loader.tsx +62 -0
  38. package/Popover/Popover.stories.tsx +133 -0
  39. package/Popover/Popover.tsx +31 -0
  40. package/Progress/Progress.stories.tsx +146 -0
  41. package/Progress/Progress.tsx +67 -0
  42. package/RadioGroup/RadioGroup.stories.tsx +159 -0
  43. package/RadioGroup/RadioGroup.tsx +68 -0
  44. package/ScrollArea/ScrollArea.stories.tsx +136 -0
  45. package/ScrollArea/ScrollArea.tsx +46 -0
  46. package/Select/Select.stories.tsx +242 -0
  47. package/Select/Select.tsx +180 -0
  48. package/Separator/Separator.stories.tsx +110 -0
  49. package/Separator/Separator.tsx +29 -0
  50. package/Skeleton/Skeleton.stories.tsx +117 -0
  51. package/Skeleton/Skeleton.tsx +16 -0
  52. package/Spinner/Spinner.stories.tsx +210 -0
  53. package/Spinner/Spinner.tsx +78 -0
  54. package/Switch/Switch.stories.tsx +146 -0
  55. package/Switch/Switch.tsx +59 -0
  56. package/Tabs/Tabs.stories.tsx +197 -0
  57. package/Tabs/Tabs.tsx +74 -0
  58. package/Textarea/Textarea.stories.tsx +170 -0
  59. package/Textarea/Textarea.tsx +51 -0
  60. package/Toast/Toast.stories.tsx +285 -0
  61. package/Toast/Toast.tsx +59 -0
  62. package/Tooltip/Tooltip.stories.tsx +463 -0
  63. package/Tooltip/Tooltip.tsx +96 -0
  64. package/Typography/Typography.stories.tsx +235 -0
  65. package/Typography/Typography.tsx +171 -0
  66. package/helpers.ts +5 -0
  67. package/icons.ts +2 -0
  68. package/index.ts +136 -0
  69. package/lib/utils.ts +15 -0
  70. package/package.json +1 -1
  71. package/tsconfig.json +24 -0
  72. package/Alert/Alert.d.ts +0 -11
  73. package/Alert/Alert.js +0 -64
  74. package/AlertDialog/AlertDialog.d.ts +0 -35
  75. package/AlertDialog/AlertDialog.js +0 -121
  76. package/Avatar/Avatar.d.ts +0 -12
  77. package/Avatar/Avatar.js +0 -64
  78. package/Badge/Badge.d.ts +0 -9
  79. package/Badge/Badge.js +0 -26
  80. package/Breadcrumb/Breadcrumb.d.ts +0 -19
  81. package/Breadcrumb/Breadcrumb.js +0 -65
  82. package/Button/Button.d.ts +0 -14
  83. package/Button/Button.js +0 -75
  84. package/Calendar/Calendar.d.ts +0 -16
  85. package/Calendar/Calendar.js +0 -113
  86. package/Card/Card.d.ts +0 -14
  87. package/Card/Card.js +0 -70
  88. package/ChatBubble/ChatBubble.d.ts +0 -29
  89. package/ChatBubble/ChatBubble.js +0 -133
  90. package/Checkbox/Checkbox.d.ts +0 -10
  91. package/Checkbox/Checkbox.js +0 -57
  92. package/Dialog/Dialog.d.ts +0 -35
  93. package/Dialog/Dialog.js +0 -130
  94. package/Drawer/Drawer.d.ts +0 -31
  95. package/Drawer/Drawer.js +0 -69
  96. package/DropdownMenu/DropdownMenu.d.ts +0 -27
  97. package/DropdownMenu/DropdownMenu.js +0 -85
  98. package/ErrorMessage/ErrorMessage.d.ts +0 -27
  99. package/ErrorMessage/ErrorMessage.js +0 -15
  100. package/Flex/Flex.d.ts +0 -23
  101. package/Flex/Flex.js +0 -101
  102. package/IconButton/IconButton.d.ts +0 -17
  103. package/IconButton/IconButton.js +0 -85
  104. package/Input/Input.d.ts +0 -16
  105. package/Input/Input.js +0 -75
  106. package/InputOTP/InputOTP.d.ts +0 -18
  107. package/InputOTP/InputOTP.js +0 -85
  108. package/Label/Label.d.ts +0 -10
  109. package/Label/Label.js +0 -57
  110. package/Loader/Loader.d.ts +0 -18
  111. package/Loader/Loader.js +0 -67
  112. package/Popover/Popover.d.ts +0 -7
  113. package/Popover/Popover.js +0 -49
  114. package/Progress/Progress.d.ts +0 -13
  115. package/Progress/Progress.js +0 -71
  116. package/RadioGroup/RadioGroup.d.ts +0 -11
  117. package/RadioGroup/RadioGroup.js +0 -64
  118. package/ScrollArea/ScrollArea.d.ts +0 -5
  119. package/ScrollArea/ScrollArea.js +0 -48
  120. package/Select/Select.d.ts +0 -19
  121. package/Select/Select.js +0 -85
  122. package/Separator/Separator.d.ts +0 -4
  123. package/Separator/Separator.js +0 -43
  124. package/Skeleton/Skeleton.d.ts +0 -4
  125. package/Skeleton/Skeleton.js +0 -8
  126. package/Spinner/Spinner.d.ts +0 -15
  127. package/Spinner/Spinner.js +0 -68
  128. package/Switch/Switch.d.ts +0 -10
  129. package/Switch/Switch.js +0 -67
  130. package/Tabs/Tabs.d.ts +0 -13
  131. package/Tabs/Tabs.js +0 -64
  132. package/Textarea/Textarea.d.ts +0 -10
  133. package/Textarea/Textarea.js +0 -64
  134. package/Toast/Toast.d.ts +0 -10
  135. package/Toast/Toast.js +0 -29
  136. package/Tooltip/Tooltip.d.ts +0 -15
  137. package/Tooltip/Tooltip.js +0 -68
  138. package/Typography/Typography.d.ts +0 -15
  139. package/Typography/Typography.js +0 -125
  140. package/helpers.d.ts +0 -4
  141. package/helpers.js +0 -13
  142. package/icons.d.ts +0 -1
  143. package/icons.js +0 -18
  144. package/index.d.ts +0 -35
  145. package/index.js +0 -183
  146. package/lib/utils.d.ts +0 -3
  147. 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
+ }