@a2v2ai/uikit 0.0.37 → 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.
Files changed (182) 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 +107 -0
  13. package/Calendar/Calendar.stories.tsx +291 -0
  14. package/Calendar/Calendar.tsx +246 -0
  15. package/Card/Card.stories.tsx +136 -0
  16. package/Card/Card.tsx +96 -0
  17. package/Carousel/Carousel.stories.tsx +256 -0
  18. package/Carousel/Carousel.tsx +301 -0
  19. package/ChatBubble/ChatBubble.stories.tsx +339 -0
  20. package/ChatBubble/ChatBubble.tsx +179 -0
  21. package/Checkbox/Checkbox.stories.tsx +137 -0
  22. package/Checkbox/Checkbox.tsx +53 -0
  23. package/DataTable/DataTable.stories.tsx +400 -0
  24. package/DataTable/DataTable.tsx +207 -0
  25. package/Drawer/Drawer.stories.tsx +721 -0
  26. package/Drawer/Drawer.tsx +201 -0
  27. package/DropdownMenu/DropdownMenu.stories.tsx +251 -0
  28. package/DropdownMenu/DropdownMenu.tsx +199 -0
  29. package/ErrorMessage/ErrorMessage.stories.tsx +159 -0
  30. package/ErrorMessage/ErrorMessage.tsx +55 -0
  31. package/Flex/Flex.stories.tsx +390 -0
  32. package/Flex/Flex.tsx +102 -0
  33. package/IconButton/IconButton.stories.tsx +566 -0
  34. package/IconButton/IconButton.tsx +95 -0
  35. package/Input/Input.stories.tsx +566 -0
  36. package/Input/Input.tsx +168 -0
  37. package/InputOTP/InputOTP.stories.tsx +246 -0
  38. package/InputOTP/InputOTP.tsx +127 -0
  39. package/Label/Label.stories.tsx +110 -0
  40. package/Label/Label.tsx +44 -0
  41. package/Loader/Loader.stories.tsx +170 -0
  42. package/Loader/Loader.tsx +62 -0
  43. package/Menubar/Menubar.stories.tsx +382 -0
  44. package/Menubar/Menubar.tsx +274 -0
  45. package/Menubar/index.ts +18 -0
  46. package/Pagination/Pagination.stories.tsx +196 -0
  47. package/Pagination/Pagination.tsx +122 -0
  48. package/Popover/Popover.stories.tsx +133 -0
  49. package/Popover/Popover.tsx +31 -0
  50. package/Progress/Progress.stories.tsx +146 -0
  51. package/Progress/Progress.tsx +67 -0
  52. package/RadioGroup/RadioGroup.stories.tsx +159 -0
  53. package/RadioGroup/RadioGroup.tsx +68 -0
  54. package/ScrollArea/ScrollArea.stories.tsx +136 -0
  55. package/ScrollArea/ScrollArea.tsx +46 -0
  56. package/Select/Select.stories.tsx +378 -0
  57. package/Select/Select.tsx +230 -0
  58. package/Separator/Separator.stories.tsx +110 -0
  59. package/Separator/Separator.tsx +29 -0
  60. package/Sidebar/Sidebar.stories.tsx +340 -0
  61. package/Sidebar/Sidebar.tsx +414 -0
  62. package/Sidebar/index.ts +28 -0
  63. package/Skeleton/Skeleton.stories.tsx +117 -0
  64. package/Skeleton/Skeleton.tsx +16 -0
  65. package/Slider/Slider.stories.tsx +216 -0
  66. package/Slider/Slider.tsx +29 -0
  67. package/Spinner/Spinner.stories.tsx +210 -0
  68. package/Spinner/Spinner.tsx +78 -0
  69. package/Switch/Switch.stories.tsx +146 -0
  70. package/Switch/Switch.tsx +59 -0
  71. package/Table/Table.stories.tsx +510 -0
  72. package/Table/Table.tsx +114 -0
  73. package/Tabs/Tabs.stories.tsx +197 -0
  74. package/Tabs/Tabs.tsx +74 -0
  75. package/Textarea/Textarea.stories.tsx +187 -0
  76. package/Textarea/Textarea.tsx +73 -0
  77. package/Toast/Toast.stories.tsx +285 -0
  78. package/Toast/Toast.tsx +59 -0
  79. package/Tooltip/Tooltip.stories.tsx +463 -0
  80. package/Tooltip/Tooltip.tsx +96 -0
  81. package/Typography/Typography.stories.tsx +425 -0
  82. package/Typography/Typography.tsx +106 -0
  83. package/helpers.ts +5 -0
  84. package/{icons.js → icons.ts} +1 -1
  85. package/index.ts +217 -0
  86. package/lib/typography-types.ts +223 -0
  87. package/lib/utils.ts +15 -0
  88. package/package.json +5 -2
  89. package/tsconfig.json +22 -0
  90. package/Alert/Alert.d.ts +0 -13
  91. package/Alert/Alert.js +0 -25
  92. package/AlertDialog/AlertDialog.d.ts +0 -43
  93. package/AlertDialog/AlertDialog.js +0 -71
  94. package/Avatar/Avatar.d.ts +0 -14
  95. package/Avatar/Avatar.js +0 -25
  96. package/Badge/Badge.d.ts +0 -11
  97. package/Badge/Badge.js +0 -23
  98. package/Breadcrumb/Breadcrumb.d.ts +0 -19
  99. package/Breadcrumb/Breadcrumb.js +0 -23
  100. package/Button/Button.d.ts +0 -23
  101. package/Button/Button.js +0 -52
  102. package/Calendar/Calendar.d.ts +0 -20
  103. package/Calendar/Calendar.js +0 -78
  104. package/Card/Card.d.ts +0 -16
  105. package/Card/Card.js +0 -28
  106. package/Carousel/Carousel.d.ts +0 -37
  107. package/Carousel/Carousel.js +0 -132
  108. package/ChatBubble/ChatBubble.d.ts +0 -33
  109. package/ChatBubble/ChatBubble.js +0 -107
  110. package/Checkbox/Checkbox.d.ts +0 -12
  111. package/Checkbox/Checkbox.js +0 -20
  112. package/DataTable/DataTable.d.ts +0 -35
  113. package/DataTable/DataTable.js +0 -51
  114. package/Drawer/Drawer.d.ts +0 -33
  115. package/Drawer/Drawer.js +0 -55
  116. package/DropdownMenu/DropdownMenu.d.ts +0 -27
  117. package/DropdownMenu/DropdownMenu.js +0 -35
  118. package/ErrorMessage/ErrorMessage.d.ts +0 -27
  119. package/ErrorMessage/ErrorMessage.js +0 -14
  120. package/Flex/Flex.d.ts +0 -31
  121. package/Flex/Flex.js +0 -64
  122. package/IconButton/IconButton.d.ts +0 -23
  123. package/IconButton/IconButton.js +0 -48
  124. package/Input/Input.d.ts +0 -27
  125. package/Input/Input.js +0 -42
  126. package/InputOTP/InputOTP.d.ts +0 -20
  127. package/InputOTP/InputOTP.js +0 -44
  128. package/Label/Label.d.ts +0 -13
  129. package/Label/Label.js +0 -19
  130. package/Loader/Loader.d.ts +0 -21
  131. package/Loader/Loader.js +0 -30
  132. package/Menubar/Menubar.d.ts +0 -26
  133. package/Menubar/Menubar.js +0 -54
  134. package/Menubar/index.d.ts +0 -1
  135. package/Menubar/index.js +0 -1
  136. package/Pagination/Pagination.d.ts +0 -35
  137. package/Pagination/Pagination.js +0 -37
  138. package/Popover/Popover.d.ts +0 -7
  139. package/Popover/Popover.js +0 -10
  140. package/Progress/Progress.d.ts +0 -17
  141. package/Progress/Progress.js +0 -33
  142. package/RadioGroup/RadioGroup.d.ts +0 -13
  143. package/RadioGroup/RadioGroup.js +0 -26
  144. package/ScrollArea/ScrollArea.d.ts +0 -5
  145. package/ScrollArea/ScrollArea.js +0 -11
  146. package/Select/Select.d.ts +0 -29
  147. package/Select/Select.js +0 -50
  148. package/Separator/Separator.d.ts +0 -4
  149. package/Separator/Separator.js +0 -7
  150. package/Sidebar/Sidebar.d.ts +0 -48
  151. package/Sidebar/Sidebar.js +0 -116
  152. package/Sidebar/index.d.ts +0 -2
  153. package/Sidebar/index.js +0 -1
  154. package/Skeleton/Skeleton.d.ts +0 -4
  155. package/Skeleton/Skeleton.js +0 -7
  156. package/Slider/Slider.d.ts +0 -6
  157. package/Slider/Slider.js +0 -7
  158. package/Spinner/Spinner.d.ts +0 -19
  159. package/Spinner/Spinner.js +0 -31
  160. package/Switch/Switch.d.ts +0 -12
  161. package/Switch/Switch.js +0 -30
  162. package/Table/Table.d.ts +0 -10
  163. package/Table/Table.js +0 -20
  164. package/Tabs/Tabs.d.ts +0 -15
  165. package/Tabs/Tabs.js +0 -24
  166. package/Textarea/Textarea.d.ts +0 -19
  167. package/Textarea/Textarea.js +0 -31
  168. package/Toast/Toast.d.ts +0 -12
  169. package/Toast/Toast.js +0 -25
  170. package/Tooltip/Tooltip.d.ts +0 -17
  171. package/Tooltip/Tooltip.js +0 -29
  172. package/Typography/Typography.d.ts +0 -20
  173. package/Typography/Typography.js +0 -43
  174. package/helpers.d.ts +0 -4
  175. package/helpers.js +0 -5
  176. package/icons.d.ts +0 -1
  177. package/index.d.ts +0 -42
  178. package/index.js +0 -45
  179. package/lib/typography-types.d.ts +0 -4
  180. package/lib/typography-types.js +0 -90
  181. package/lib/utils.d.ts +0 -3
  182. package/lib/utils.js +0 -14
@@ -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 gap={8}>
143
+ <Typography variant="h4" className="text-white">Tab Variants</Typography>
144
+
145
+ <Flex 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 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 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 cursor-pointer 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,187 @@
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
+ error: {
30
+ control: "text",
31
+ description: "Error message to display",
32
+ },
33
+ },
34
+ tags: ["autodocs"],
35
+ }
36
+
37
+ export default meta
38
+ type Story = StoryObj<typeof meta>
39
+
40
+ export const Default: Story = {
41
+ render: () => <Textarea placeholder="Type your message here." className="w-[300px]" />,
42
+ }
43
+
44
+ export const WithBuiltInLabel: Story = {
45
+ render: () => (
46
+ <Flex gap={4} className="w-[300px]">
47
+ <Textarea
48
+ id="message"
49
+ label="Your Message"
50
+ labelVariant="body2"
51
+ labelColor="main-800"
52
+ placeholder="Type your message here."
53
+ />
54
+ <Textarea
55
+ id="feedback"
56
+ label="Feedback"
57
+ labelVariant="body2"
58
+ labelColor="main-800"
59
+ placeholder="Share your feedback..."
60
+ />
61
+ </Flex>
62
+ ),
63
+ }
64
+
65
+ export const WithLabel: Story = {
66
+ render: () => (
67
+ <Flex gap={2} className="w-[300px]">
68
+ <Label htmlFor="message">Your message</Label>
69
+ <Textarea placeholder="Type your message here." id="message" />
70
+ </Flex>
71
+ ),
72
+ }
73
+
74
+ export const WithText: Story = {
75
+ render: () => (
76
+ <Flex gap={2} className="w-[300px]">
77
+ <Label htmlFor="bio">Bio</Label>
78
+ <Textarea placeholder="Tell us a little bit about yourself" id="bio" />
79
+ <Typography variant="caption" color="grey-500">
80
+ You can @mention other users and organizations.
81
+ </Typography>
82
+ </Flex>
83
+ ),
84
+ }
85
+
86
+ export const Disabled: Story = {
87
+ render: () => (
88
+ <Textarea placeholder="This textarea is disabled" disabled className="w-[300px]" />
89
+ ),
90
+ }
91
+
92
+ export const Error: Story = {
93
+ render: () => (
94
+ <Textarea
95
+ label="Message"
96
+ placeholder="Type your message here."
97
+ error="Message is required."
98
+ className="w-[300px]"
99
+ />
100
+ ),
101
+ }
102
+
103
+ export const WithButton: Story = {
104
+ render: () => (
105
+ <Flex gap={4} className="w-[300px]">
106
+ <Flex gap={2}>
107
+ <Label htmlFor="feedback">Send us your feedback</Label>
108
+ <Textarea
109
+ placeholder="What can we improve?"
110
+ id="feedback"
111
+ />
112
+ </Flex>
113
+ <Button>Submit</Button>
114
+ </Flex>
115
+ ),
116
+ }
117
+
118
+ export const AllVariants: Story = {
119
+ render: () => (
120
+ <Flex gap={6}>
121
+ <Typography variant="h4" className="text-white">Textarea Variants</Typography>
122
+
123
+ <Flex direction="row" gap={6}>
124
+ <Flex gap={2} className="w-[250px]">
125
+ <Label htmlFor="default">Default</Label>
126
+ <Textarea
127
+ id="default"
128
+ placeholder="Enter text..."
129
+ />
130
+ </Flex>
131
+
132
+ <Flex gap={2} className="w-[250px]">
133
+ <Textarea
134
+ id="error-state"
135
+ label="Error"
136
+ placeholder="Enter text..."
137
+ error="This field is required."
138
+ />
139
+ </Flex>
140
+ </Flex>
141
+
142
+ <Typography variant="h4" className="text-white mt-4">States</Typography>
143
+
144
+ <Flex direction="row" gap={6}>
145
+ <Flex gap={2} className="w-[250px]">
146
+ <Label>Enabled</Label>
147
+ <Textarea placeholder="Type here..." />
148
+ </Flex>
149
+
150
+ <Flex gap={2} className="w-[250px]">
151
+ <Label className="opacity-50">Disabled</Label>
152
+ <Textarea placeholder="Disabled textarea" disabled />
153
+ </Flex>
154
+ </Flex>
155
+
156
+ <Typography variant="h4" className="text-white mt-4">With Character Count</Typography>
157
+
158
+ <Flex gap={2} className="w-[300px]">
159
+ <Flex direction="row" justify="between">
160
+ <Label htmlFor="with-count">Description</Label>
161
+ <Typography variant="caption" color="grey-500">0/200</Typography>
162
+ </Flex>
163
+ <Textarea
164
+ id="with-count"
165
+ placeholder="Describe your project..."
166
+ rows={4}
167
+ />
168
+ </Flex>
169
+
170
+ <Typography variant="h4" className="text-white mt-4">Comment Form Example</Typography>
171
+
172
+ <div className="w-[350px] bg-white rounded-lg p-4 space-y-4">
173
+ <Flex gap={2}>
174
+ <Label htmlFor="comment">Leave a comment</Label>
175
+ <Textarea
176
+ id="comment"
177
+ placeholder="Write your comment here..."
178
+ rows={3}
179
+ />
180
+ </Flex>
181
+ <Flex direction="row" justify="end">
182
+ <Button size="small">Post Comment</Button>
183
+ </Flex>
184
+ </div>
185
+ </Flex>
186
+ ),
187
+ }
@@ -0,0 +1,73 @@
1
+ import * as React from "react"
2
+ import { cva } from "class-variance-authority"
3
+
4
+ import { cn } from "../lib/utils"
5
+ import { Label } from "../Label/Label"
6
+ import { Typography } from "../Typography/Typography"
7
+ import { type TextVariant, type TextColor } from "../lib/typography-types"
8
+
9
+ type TextareaVariant = "default" | "error"
10
+ type TextareaResize = "none" | "vertical" | "horizontal" | "both"
11
+
12
+ const textareaVariants = cva(
13
+ "flex min-h-[80px] w-full rounded-lg border bg-white px-3 py-2 text-sm font-normal font-sans transition-colors placeholder:text-grey-400 focus-visible:outline-none disabled:cursor-not-allowed disabled:opacity-50 disabled:bg-grey-50",
14
+ {
15
+ variants: {
16
+ variant: {
17
+ default: "border-grey-300 focus-visible:border-grey-300 focus-visible:ring-[3px] focus-visible:ring-grey-300/50",
18
+ error: "border-error-500 focus-visible:border-error-500 focus-visible:ring-[3px] focus-visible:ring-error-200",
19
+ },
20
+ resize: {
21
+ none: "resize-none",
22
+ vertical: "resize-y",
23
+ horizontal: "resize-x",
24
+ both: "resize",
25
+ },
26
+ },
27
+ defaultVariants: {
28
+ variant: "default",
29
+ resize: "vertical",
30
+ },
31
+ }
32
+ )
33
+
34
+ export interface TextareaProps
35
+ extends React.TextareaHTMLAttributes<HTMLTextAreaElement> {
36
+ variant?: TextareaVariant
37
+ resize?: TextareaResize
38
+ label?: string
39
+ labelVariant?: TextVariant
40
+ labelColor?: TextColor
41
+ error?: string
42
+ }
43
+
44
+ const Textarea = React.forwardRef<HTMLTextAreaElement, TextareaProps>(
45
+ ({ className, variant, resize, label, labelVariant="body2", labelColor="main-800", error, id, ...props }, ref) => {
46
+ const computedVariant = error ? "error" : variant
47
+
48
+ return (
49
+ <div className="flex flex-col gap-2 w-full">
50
+ {label && (
51
+ <Label htmlFor={id} variant={labelVariant} color={labelColor}>
52
+ {label}
53
+ </Label>
54
+ )}
55
+ <textarea
56
+ id={id}
57
+ className={cn(textareaVariants({ variant: computedVariant, resize }), className)}
58
+ ref={ref}
59
+ {...props}
60
+ />
61
+ {error && (
62
+ <Typography variant="caption" color="error-600" className="mt-1">
63
+ {error}
64
+ </Typography>
65
+ )}
66
+ </div>
67
+ )
68
+ }
69
+ )
70
+ Textarea.displayName = "Textarea"
71
+
72
+ export { Textarea, textareaVariants }
73
+ export type { TextareaVariant, TextareaResize }