@a2v2ai/uikit 0.0.1 → 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 (148) 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/README.md +12 -12
  43. package/RadioGroup/RadioGroup.stories.tsx +159 -0
  44. package/RadioGroup/RadioGroup.tsx +68 -0
  45. package/ScrollArea/ScrollArea.stories.tsx +136 -0
  46. package/ScrollArea/ScrollArea.tsx +46 -0
  47. package/Select/Select.stories.tsx +242 -0
  48. package/Select/Select.tsx +180 -0
  49. package/Separator/Separator.stories.tsx +110 -0
  50. package/Separator/Separator.tsx +29 -0
  51. package/Skeleton/Skeleton.stories.tsx +117 -0
  52. package/Skeleton/Skeleton.tsx +16 -0
  53. package/Spinner/Spinner.stories.tsx +210 -0
  54. package/Spinner/Spinner.tsx +78 -0
  55. package/Switch/Switch.stories.tsx +146 -0
  56. package/Switch/Switch.tsx +59 -0
  57. package/Tabs/Tabs.stories.tsx +197 -0
  58. package/Tabs/Tabs.tsx +74 -0
  59. package/Textarea/Textarea.stories.tsx +170 -0
  60. package/Textarea/Textarea.tsx +51 -0
  61. package/Toast/Toast.stories.tsx +285 -0
  62. package/Toast/Toast.tsx +59 -0
  63. package/Tooltip/Tooltip.stories.tsx +463 -0
  64. package/Tooltip/Tooltip.tsx +96 -0
  65. package/Typography/Typography.stories.tsx +235 -0
  66. package/Typography/Typography.tsx +171 -0
  67. package/helpers.ts +5 -0
  68. package/icons.ts +2 -0
  69. package/index.ts +136 -0
  70. package/lib/utils.ts +15 -0
  71. package/package.json +4 -1
  72. package/tsconfig.json +24 -0
  73. package/Alert/Alert.d.ts +0 -11
  74. package/Alert/Alert.js +0 -64
  75. package/AlertDialog/AlertDialog.d.ts +0 -35
  76. package/AlertDialog/AlertDialog.js +0 -121
  77. package/Avatar/Avatar.d.ts +0 -12
  78. package/Avatar/Avatar.js +0 -64
  79. package/Badge/Badge.d.ts +0 -9
  80. package/Badge/Badge.js +0 -26
  81. package/Breadcrumb/Breadcrumb.d.ts +0 -19
  82. package/Breadcrumb/Breadcrumb.js +0 -65
  83. package/Button/Button.d.ts +0 -14
  84. package/Button/Button.js +0 -75
  85. package/Calendar/Calendar.d.ts +0 -16
  86. package/Calendar/Calendar.js +0 -113
  87. package/Card/Card.d.ts +0 -14
  88. package/Card/Card.js +0 -70
  89. package/ChatBubble/ChatBubble.d.ts +0 -29
  90. package/ChatBubble/ChatBubble.js +0 -133
  91. package/Checkbox/Checkbox.d.ts +0 -10
  92. package/Checkbox/Checkbox.js +0 -57
  93. package/Dialog/Dialog.d.ts +0 -35
  94. package/Dialog/Dialog.js +0 -130
  95. package/Drawer/Drawer.d.ts +0 -31
  96. package/Drawer/Drawer.js +0 -69
  97. package/DropdownMenu/DropdownMenu.d.ts +0 -27
  98. package/DropdownMenu/DropdownMenu.js +0 -85
  99. package/ErrorMessage/ErrorMessage.d.ts +0 -27
  100. package/ErrorMessage/ErrorMessage.js +0 -15
  101. package/Flex/Flex.d.ts +0 -23
  102. package/Flex/Flex.js +0 -101
  103. package/IconButton/IconButton.d.ts +0 -17
  104. package/IconButton/IconButton.js +0 -85
  105. package/Input/Input.d.ts +0 -16
  106. package/Input/Input.js +0 -75
  107. package/InputOTP/InputOTP.d.ts +0 -18
  108. package/InputOTP/InputOTP.js +0 -85
  109. package/Label/Label.d.ts +0 -10
  110. package/Label/Label.js +0 -57
  111. package/Loader/Loader.d.ts +0 -18
  112. package/Loader/Loader.js +0 -67
  113. package/Popover/Popover.d.ts +0 -7
  114. package/Popover/Popover.js +0 -49
  115. package/Progress/Progress.d.ts +0 -13
  116. package/Progress/Progress.js +0 -71
  117. package/RadioGroup/RadioGroup.d.ts +0 -11
  118. package/RadioGroup/RadioGroup.js +0 -64
  119. package/ScrollArea/ScrollArea.d.ts +0 -5
  120. package/ScrollArea/ScrollArea.js +0 -48
  121. package/Select/Select.d.ts +0 -19
  122. package/Select/Select.js +0 -85
  123. package/Separator/Separator.d.ts +0 -4
  124. package/Separator/Separator.js +0 -43
  125. package/Skeleton/Skeleton.d.ts +0 -4
  126. package/Skeleton/Skeleton.js +0 -8
  127. package/Spinner/Spinner.d.ts +0 -15
  128. package/Spinner/Spinner.js +0 -68
  129. package/Switch/Switch.d.ts +0 -10
  130. package/Switch/Switch.js +0 -67
  131. package/Tabs/Tabs.d.ts +0 -13
  132. package/Tabs/Tabs.js +0 -64
  133. package/Textarea/Textarea.d.ts +0 -10
  134. package/Textarea/Textarea.js +0 -64
  135. package/Toast/Toast.d.ts +0 -10
  136. package/Toast/Toast.js +0 -29
  137. package/Tooltip/Tooltip.d.ts +0 -15
  138. package/Tooltip/Tooltip.js +0 -68
  139. package/Typography/Typography.d.ts +0 -15
  140. package/Typography/Typography.js +0 -125
  141. package/helpers.d.ts +0 -4
  142. package/helpers.js +0 -13
  143. package/icons.d.ts +0 -1
  144. package/icons.js +0 -18
  145. package/index.d.ts +0 -35
  146. package/index.js +0 -183
  147. package/lib/utils.d.ts +0 -3
  148. package/lib/utils.js +0 -18
@@ -0,0 +1,456 @@
1
+ import type { Meta, StoryObj } from "@storybook/react"
2
+ import { useState } from "react"
3
+ import { Search, Mail, Eye, EyeOff, Info, User, Lock } from "../icons"
4
+ import { Typography } from "../Typography/Typography"
5
+ import { Flex } from "../Flex/Flex"
6
+ import { Button } from "../Button/Button"
7
+ import { Input } from "./Input"
8
+
9
+ const meta: Meta<typeof Input> = {
10
+ title: "Components/Input",
11
+ component: Input,
12
+ parameters: {
13
+ layout: "centered",
14
+ },
15
+ tags: ["autodocs"],
16
+ argTypes: {
17
+ size: {
18
+ control: "select",
19
+ options: ["mini", "small", "regular", "large"],
20
+ },
21
+ roundness: {
22
+ control: "select",
23
+ options: ["default", "round"],
24
+ },
25
+ variant: {
26
+ control: "select",
27
+ options: ["default", "error"],
28
+ },
29
+ disabled: {
30
+ control: "boolean",
31
+ },
32
+ },
33
+ }
34
+
35
+ export default meta
36
+ type Story = StoryObj<typeof Input>
37
+
38
+ export const Default: Story = {
39
+ args: {
40
+ placeholder: "Enter text...",
41
+ },
42
+ }
43
+
44
+ export const WithValue: Story = {
45
+ args: {
46
+ defaultValue: "Hello World",
47
+ },
48
+ }
49
+
50
+ export const Placeholder: Story = {
51
+ args: {
52
+ placeholder: "Type something...",
53
+ },
54
+ }
55
+
56
+ export const Disabled: Story = {
57
+ args: {
58
+ placeholder: "Disabled input",
59
+ disabled: true,
60
+ },
61
+ }
62
+
63
+ export const DisabledWithValue: Story = {
64
+ args: {
65
+ defaultValue: "Cannot edit this",
66
+ disabled: true,
67
+ },
68
+ }
69
+
70
+ export const Error: Story = {
71
+ args: {
72
+ defaultValue: "Invalid value",
73
+ variant: "error",
74
+ },
75
+ }
76
+
77
+ export const WithLeftIcon: Story = {
78
+ args: {
79
+ placeholder: "Search...",
80
+ leftIcon: <Search size={16} />,
81
+ },
82
+ }
83
+
84
+ export const WithRightIcon: Story = {
85
+ args: {
86
+ placeholder: "Enter email",
87
+ rightIcon: <Info size={16} />,
88
+ },
89
+ }
90
+
91
+ export const WithBothIcons: Story = {
92
+ args: {
93
+ placeholder: "Search users...",
94
+ leftIcon: <Search size={16} />,
95
+ rightIcon: <User size={16} />,
96
+ },
97
+ }
98
+
99
+ export const WithAddons: Story = {
100
+ render: () => (
101
+ <Flex direction="column" gap={4} style={{ width: "320px" }}>
102
+ <Flex direction="column" gap={2}>
103
+ <Typography variant="body3" color="main-500">URL Input</Typography>
104
+ <Input leftAddon="https://" placeholder="example.com" />
105
+ </Flex>
106
+ <Flex direction="column" gap={2}>
107
+ <Typography variant="body3" color="main-500">Currency Input</Typography>
108
+ <Input leftAddon="$" rightAddon="USD" placeholder="0.00" />
109
+ </Flex>
110
+ <Flex direction="column" gap={2}>
111
+ <Typography variant="body3" color="main-500">Email Input</Typography>
112
+ <Input leftIcon={<Mail size={16} />} placeholder="you@example.com" />
113
+ </Flex>
114
+ </Flex>
115
+ ),
116
+ }
117
+
118
+ export const PasswordInput: Story = {
119
+ render: function PasswordInputStory() {
120
+ const [showPassword, setShowPassword] = useState(false)
121
+ return (
122
+ <Flex style={{ width: "320px" }}>
123
+ <Input
124
+ type={showPassword ? "text" : "password"}
125
+ placeholder="Enter password"
126
+ leftIcon={<Lock size={16} />}
127
+ rightIcon={
128
+ <button
129
+ type="button"
130
+ onClick={() => setShowPassword(!showPassword)}
131
+ style={{ background: "none", border: "none", cursor: "pointer", padding: 0 }}
132
+ >
133
+ {showPassword ? <EyeOff size={16} /> : <Eye size={16} />}
134
+ </button>
135
+ }
136
+ />
137
+ </Flex>
138
+ )
139
+ },
140
+ }
141
+
142
+ export const SearchWithButton: Story = {
143
+ render: () => (
144
+ <Flex style={{ width: "320px" }}>
145
+ <Input
146
+ placeholder="Type to search..."
147
+ rightElement={
148
+ <Button size="small" variant="secondary">
149
+ Search
150
+ </Button>
151
+ }
152
+ />
153
+ </Flex>
154
+ ),
155
+ }
156
+
157
+ export const AllVariantsAndSizes: Story = {
158
+ parameters: {
159
+ layout: "fullscreen",
160
+ },
161
+ render: () => (
162
+ <Flex direction="column" style={{ padding: "32px", backgroundColor: "#ffffff", minHeight: "100vh" }}>
163
+ {/* Header */}
164
+ <Flex style={{ borderBottom: "1px solid #e5e7eb", paddingBottom: "24px", marginBottom: "32px" }}>
165
+ <Typography variant="h3" color="main-950">Input</Typography>
166
+ </Flex>
167
+
168
+ {/* Main Content */}
169
+ <Flex direction="column" gap={12}>
170
+ {/* Default Roundness Section */}
171
+ <Flex direction="column" gap={6}>
172
+ <Typography variant="subtitle1" color="main-700">Default Roundness</Typography>
173
+
174
+ {/* Size Headers */}
175
+ <Flex>
176
+ <Flex style={{ width: "120px" }} />
177
+ <Flex gap={4}>
178
+ <Flex justify="center" style={{ width: "200px" }}>
179
+ <Typography variant="body3" color="accent-600">Regular</Typography>
180
+ </Flex>
181
+ <Flex justify="center" style={{ width: "200px" }}>
182
+ <Typography variant="body3" color="accent-600">Large</Typography>
183
+ </Flex>
184
+ <Flex justify="center" style={{ width: "200px" }}>
185
+ <Typography variant="body3" color="accent-600">Small</Typography>
186
+ </Flex>
187
+ <Flex justify="center" style={{ width: "200px" }}>
188
+ <Typography variant="body3" color="accent-600">Mini</Typography>
189
+ </Flex>
190
+ </Flex>
191
+ </Flex>
192
+
193
+ {/* Empty Row */}
194
+ <Flex align="center">
195
+ <Flex style={{ width: "120px" }}>
196
+ <Typography variant="body3" color="main-500">Empty</Typography>
197
+ </Flex>
198
+ <Flex gap={4}>
199
+ <Flex style={{ width: "200px" }}><Input size="regular" /></Flex>
200
+ <Flex style={{ width: "200px" }}><Input size="large" /></Flex>
201
+ <Flex style={{ width: "200px" }}><Input size="small" /></Flex>
202
+ <Flex style={{ width: "200px" }}><Input size="mini" /></Flex>
203
+ </Flex>
204
+ </Flex>
205
+
206
+ {/* Placeholder Row */}
207
+ <Flex align="center">
208
+ <Flex style={{ width: "120px" }}>
209
+ <Typography variant="body3" color="main-500">Placeholder</Typography>
210
+ </Flex>
211
+ <Flex gap={4}>
212
+ <Flex style={{ width: "200px" }}><Input size="regular" placeholder="Value" /></Flex>
213
+ <Flex style={{ width: "200px" }}><Input size="large" placeholder="Value" /></Flex>
214
+ <Flex style={{ width: "200px" }}><Input size="small" placeholder="Value" /></Flex>
215
+ <Flex style={{ width: "200px" }}><Input size="mini" placeholder="Value" /></Flex>
216
+ </Flex>
217
+ </Flex>
218
+
219
+ {/* Value Row */}
220
+ <Flex align="center">
221
+ <Flex style={{ width: "120px" }}>
222
+ <Typography variant="body3" color="main-500">Value</Typography>
223
+ </Flex>
224
+ <Flex gap={4}>
225
+ <Flex style={{ width: "200px" }}><Input size="regular" defaultValue="Value" /></Flex>
226
+ <Flex style={{ width: "200px" }}><Input size="large" defaultValue="Value" /></Flex>
227
+ <Flex style={{ width: "200px" }}><Input size="small" defaultValue="Value" /></Flex>
228
+ <Flex style={{ width: "200px" }}><Input size="mini" defaultValue="Value" /></Flex>
229
+ </Flex>
230
+ </Flex>
231
+
232
+ {/* Focus Row - simulated with ring */}
233
+ <Flex align="center">
234
+ <Flex style={{ width: "120px" }}>
235
+ <Typography variant="body3" color="main-500">Focus</Typography>
236
+ </Flex>
237
+ <Flex gap={4}>
238
+ <Flex style={{ width: "200px" }}><Input size="regular" defaultValue="Value" className="ring-[3px] ring-grey-300/50" /></Flex>
239
+ <Flex style={{ width: "200px" }}><Input size="large" defaultValue="Value" className="ring-[3px] ring-grey-300/50" /></Flex>
240
+ <Flex style={{ width: "200px" }}><Input size="small" defaultValue="Value" className="ring-[3px] ring-grey-300/50" /></Flex>
241
+ <Flex style={{ width: "200px" }}><Input size="mini" defaultValue="Value" className="ring-[3px] ring-grey-300/50" /></Flex>
242
+ </Flex>
243
+ </Flex>
244
+
245
+ {/* Error Row */}
246
+ <Flex align="center">
247
+ <Flex style={{ width: "120px" }}>
248
+ <Typography variant="body3" color="error-500">Error</Typography>
249
+ </Flex>
250
+ <Flex gap={4}>
251
+ <Flex style={{ width: "200px" }}><Input size="regular" defaultValue="Value" variant="error" /></Flex>
252
+ <Flex style={{ width: "200px" }}><Input size="large" defaultValue="Value" variant="error" /></Flex>
253
+ <Flex style={{ width: "200px" }}><Input size="small" defaultValue="Value" variant="error" /></Flex>
254
+ <Flex style={{ width: "200px" }}><Input size="mini" defaultValue="Value" variant="error" /></Flex>
255
+ </Flex>
256
+ </Flex>
257
+
258
+ {/* Error Focus Row */}
259
+ <Flex align="center">
260
+ <Flex style={{ width: "120px" }}>
261
+ <Typography variant="body3" color="error-500">Error Focus</Typography>
262
+ </Flex>
263
+ <Flex gap={4}>
264
+ <Flex style={{ width: "200px" }}><Input size="regular" defaultValue="Value" variant="error" className="ring-[3px] ring-error-200" /></Flex>
265
+ <Flex style={{ width: "200px" }}><Input size="large" defaultValue="Value" variant="error" className="ring-[3px] ring-error-200" /></Flex>
266
+ <Flex style={{ width: "200px" }}><Input size="small" defaultValue="Value" variant="error" className="ring-[3px] ring-error-200" /></Flex>
267
+ <Flex style={{ width: "200px" }}><Input size="mini" defaultValue="Value" variant="error" className="ring-[3px] ring-error-200" /></Flex>
268
+ </Flex>
269
+ </Flex>
270
+
271
+ {/* Disabled Row */}
272
+ <Flex align="center">
273
+ <Flex style={{ width: "120px" }}>
274
+ <Typography variant="body3" color="main-400">Disabled</Typography>
275
+ </Flex>
276
+ <Flex gap={4}>
277
+ <Flex style={{ width: "200px" }}><Input size="regular" defaultValue="Value" disabled /></Flex>
278
+ <Flex style={{ width: "200px" }}><Input size="large" defaultValue="Value" disabled /></Flex>
279
+ <Flex style={{ width: "200px" }}><Input size="small" defaultValue="Value" disabled /></Flex>
280
+ <Flex style={{ width: "200px" }}><Input size="mini" defaultValue="Value" disabled /></Flex>
281
+ </Flex>
282
+ </Flex>
283
+ </Flex>
284
+
285
+ {/* Round Section */}
286
+ <Flex direction="column" gap={6}>
287
+ <Typography variant="subtitle1" color="main-700">Round</Typography>
288
+
289
+ {/* Size Headers */}
290
+ <Flex>
291
+ <Flex style={{ width: "120px" }} />
292
+ <Flex gap={4}>
293
+ <Flex justify="center" style={{ width: "200px" }}>
294
+ <Typography variant="body3" color="accent-600">Regular</Typography>
295
+ </Flex>
296
+ <Flex justify="center" style={{ width: "200px" }}>
297
+ <Typography variant="body3" color="accent-600">Large</Typography>
298
+ </Flex>
299
+ <Flex justify="center" style={{ width: "200px" }}>
300
+ <Typography variant="body3" color="accent-600">Small</Typography>
301
+ </Flex>
302
+ <Flex justify="center" style={{ width: "200px" }}>
303
+ <Typography variant="body3" color="accent-600">Mini</Typography>
304
+ </Flex>
305
+ </Flex>
306
+ </Flex>
307
+
308
+ {/* Empty Row */}
309
+ <Flex align="center">
310
+ <Flex style={{ width: "120px" }}>
311
+ <Typography variant="body3" color="main-500">Empty</Typography>
312
+ </Flex>
313
+ <Flex gap={4}>
314
+ <Flex style={{ width: "200px" }}><Input size="regular" roundness="round" /></Flex>
315
+ <Flex style={{ width: "200px" }}><Input size="large" roundness="round" /></Flex>
316
+ <Flex style={{ width: "200px" }}><Input size="small" roundness="round" /></Flex>
317
+ <Flex style={{ width: "200px" }}><Input size="mini" roundness="round" /></Flex>
318
+ </Flex>
319
+ </Flex>
320
+
321
+ {/* Placeholder Row */}
322
+ <Flex align="center">
323
+ <Flex style={{ width: "120px" }}>
324
+ <Typography variant="body3" color="main-500">Placeholder</Typography>
325
+ </Flex>
326
+ <Flex gap={4}>
327
+ <Flex style={{ width: "200px" }}><Input size="regular" roundness="round" placeholder="Value" /></Flex>
328
+ <Flex style={{ width: "200px" }}><Input size="large" roundness="round" placeholder="Value" /></Flex>
329
+ <Flex style={{ width: "200px" }}><Input size="small" roundness="round" placeholder="Value" /></Flex>
330
+ <Flex style={{ width: "200px" }}><Input size="mini" roundness="round" placeholder="Value" /></Flex>
331
+ </Flex>
332
+ </Flex>
333
+
334
+ {/* Value Row */}
335
+ <Flex align="center">
336
+ <Flex style={{ width: "120px" }}>
337
+ <Typography variant="body3" color="main-500">Value</Typography>
338
+ </Flex>
339
+ <Flex gap={4}>
340
+ <Flex style={{ width: "200px" }}><Input size="regular" roundness="round" defaultValue="Value" /></Flex>
341
+ <Flex style={{ width: "200px" }}><Input size="large" roundness="round" defaultValue="Value" /></Flex>
342
+ <Flex style={{ width: "200px" }}><Input size="small" roundness="round" defaultValue="Value" /></Flex>
343
+ <Flex style={{ width: "200px" }}><Input size="mini" roundness="round" defaultValue="Value" /></Flex>
344
+ </Flex>
345
+ </Flex>
346
+
347
+ {/* Focus Row */}
348
+ <Flex align="center">
349
+ <Flex style={{ width: "120px" }}>
350
+ <Typography variant="body3" color="main-500">Focus</Typography>
351
+ </Flex>
352
+ <Flex gap={4}>
353
+ <Flex style={{ width: "200px" }}><Input size="regular" roundness="round" defaultValue="Value" className="ring-[3px] ring-grey-300/50" /></Flex>
354
+ <Flex style={{ width: "200px" }}><Input size="large" roundness="round" defaultValue="Value" className="ring-[3px] ring-grey-300/50" /></Flex>
355
+ <Flex style={{ width: "200px" }}><Input size="small" roundness="round" defaultValue="Value" className="ring-[3px] ring-grey-300/50" /></Flex>
356
+ <Flex style={{ width: "200px" }}><Input size="mini" roundness="round" defaultValue="Value" className="ring-[3px] ring-grey-300/50" /></Flex>
357
+ </Flex>
358
+ </Flex>
359
+
360
+ {/* Error Row */}
361
+ <Flex align="center">
362
+ <Flex style={{ width: "120px" }}>
363
+ <Typography variant="body3" color="error-500">Error</Typography>
364
+ </Flex>
365
+ <Flex gap={4}>
366
+ <Flex style={{ width: "200px" }}><Input size="regular" roundness="round" defaultValue="Value" variant="error" /></Flex>
367
+ <Flex style={{ width: "200px" }}><Input size="large" roundness="round" defaultValue="Value" variant="error" /></Flex>
368
+ <Flex style={{ width: "200px" }}><Input size="small" roundness="round" defaultValue="Value" variant="error" /></Flex>
369
+ <Flex style={{ width: "200px" }}><Input size="mini" roundness="round" defaultValue="Value" variant="error" /></Flex>
370
+ </Flex>
371
+ </Flex>
372
+
373
+ {/* Error Focus Row */}
374
+ <Flex align="center">
375
+ <Flex style={{ width: "120px" }}>
376
+ <Typography variant="body3" color="error-500">Error Focus</Typography>
377
+ </Flex>
378
+ <Flex gap={4}>
379
+ <Flex style={{ width: "200px" }}><Input size="regular" roundness="round" defaultValue="Value" variant="error" className="ring-[3px] ring-error-200" /></Flex>
380
+ <Flex style={{ width: "200px" }}><Input size="large" roundness="round" defaultValue="Value" variant="error" className="ring-[3px] ring-error-200" /></Flex>
381
+ <Flex style={{ width: "200px" }}><Input size="small" roundness="round" defaultValue="Value" variant="error" className="ring-[3px] ring-error-200" /></Flex>
382
+ <Flex style={{ width: "200px" }}><Input size="mini" roundness="round" defaultValue="Value" variant="error" className="ring-[3px] ring-error-200" /></Flex>
383
+ </Flex>
384
+ </Flex>
385
+
386
+ {/* Disabled Row */}
387
+ <Flex align="center">
388
+ <Flex style={{ width: "120px" }}>
389
+ <Typography variant="body3" color="main-400">Disabled</Typography>
390
+ </Flex>
391
+ <Flex gap={4}>
392
+ <Flex style={{ width: "200px" }}><Input size="regular" roundness="round" defaultValue="Value" disabled /></Flex>
393
+ <Flex style={{ width: "200px" }}><Input size="large" roundness="round" defaultValue="Value" disabled /></Flex>
394
+ <Flex style={{ width: "200px" }}><Input size="small" roundness="round" defaultValue="Value" disabled /></Flex>
395
+ <Flex style={{ width: "200px" }}><Input size="mini" roundness="round" defaultValue="Value" disabled /></Flex>
396
+ </Flex>
397
+ </Flex>
398
+ </Flex>
399
+
400
+ {/* Examples Section */}
401
+ <Flex direction="column" gap={6} style={{ marginTop: "24px", paddingTop: "24px", borderTop: "1px solid #e5e7eb" }}>
402
+ <Typography variant="subtitle1" color="main-700">Examples</Typography>
403
+
404
+ <Flex gap={6} wrap="wrap">
405
+ {/* Search with results */}
406
+ <Flex direction="column" gap={2}>
407
+ <Typography variant="body3" color="main-500">Search Input</Typography>
408
+ <Input
409
+ leftIcon={<Search size={16} />}
410
+ defaultValue="Value"
411
+ rightAddon="12 results"
412
+ style={{ width: "280px" }}
413
+ />
414
+ </Flex>
415
+
416
+ {/* URL Input */}
417
+ <Flex direction="column" gap={2}>
418
+ <Typography variant="body3" color="main-500">URL Input</Typography>
419
+ <Input
420
+ leftAddon="https://"
421
+ defaultValue="example.com"
422
+ rightIcon={<Info size={16} />}
423
+ style={{ width: "280px" }}
424
+ />
425
+ </Flex>
426
+
427
+ {/* Search with Button */}
428
+ <Flex direction="column" gap={2}>
429
+ <Typography variant="body3" color="main-500">Search with Button</Typography>
430
+ <Input
431
+ placeholder="Type to search..."
432
+ rightElement={
433
+ <Button size="small" variant="secondary">
434
+ Search
435
+ </Button>
436
+ }
437
+ style={{ width: "280px" }}
438
+ />
439
+ </Flex>
440
+
441
+ {/* Currency Input */}
442
+ <Flex direction="column" gap={2}>
443
+ <Typography variant="body3" color="main-500">Currency Input</Typography>
444
+ <Input
445
+ leftAddon="$"
446
+ defaultValue="0.00"
447
+ rightAddon="USD"
448
+ style={{ width: "280px" }}
449
+ />
450
+ </Flex>
451
+ </Flex>
452
+ </Flex>
453
+ </Flex>
454
+ </Flex>
455
+ ),
456
+ }
@@ -0,0 +1,129 @@
1
+ import * as React from "react"
2
+ import { cva } from "class-variance-authority"
3
+
4
+ import { cn } from "../lib/utils"
5
+
6
+ type InputSize = "mini" | "small" | "regular" | "large"
7
+ type InputRoundness = "default" | "round"
8
+ type InputVariant = "default" | "error"
9
+
10
+ const inputVariants = cva(
11
+ "flex w-full bg-white border font-normal font-sans transition-colors file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-grey-400 focus-visible:outline-none disabled:cursor-not-allowed disabled:opacity-50 disabled:bg-grey-50",
12
+ {
13
+ variants: {
14
+ size: {
15
+ mini: "h-6 px-3 text-xs rounded-md",
16
+ small: "h-8 px-3 text-sm rounded-md",
17
+ regular: "h-9 px-3 text-sm rounded-lg",
18
+ large: "h-10 px-3 text-base rounded-lg",
19
+ },
20
+ roundness: {
21
+ default: "",
22
+ round: "!rounded-full",
23
+ },
24
+ variant: {
25
+ default: "border-grey-300 focus-visible:border-grey-300 focus-visible:ring-[3px] focus-visible:ring-grey-300/50",
26
+ error: "border-error-500 focus-visible:border-error-500 focus-visible:ring-[3px] focus-visible:ring-error-200",
27
+ },
28
+ },
29
+ defaultVariants: {
30
+ size: "regular",
31
+ roundness: "default",
32
+ variant: "default",
33
+ },
34
+ }
35
+ )
36
+
37
+ export interface InputProps
38
+ extends Omit<React.InputHTMLAttributes<HTMLInputElement>, "size"> {
39
+ size?: InputSize
40
+ roundness?: InputRoundness
41
+ variant?: InputVariant
42
+ leftIcon?: React.ReactNode
43
+ rightIcon?: React.ReactNode
44
+ leftAddon?: React.ReactNode
45
+ rightAddon?: React.ReactNode
46
+ rightElement?: React.ReactNode
47
+ }
48
+
49
+ const Input = React.forwardRef<HTMLInputElement, InputProps>(
50
+ (
51
+ {
52
+ className,
53
+ type = "text",
54
+ size,
55
+ roundness,
56
+ variant,
57
+ leftIcon,
58
+ rightIcon,
59
+ leftAddon,
60
+ rightAddon,
61
+ rightElement,
62
+ ...props
63
+ },
64
+ ref
65
+ ) => {
66
+ const hasAddons = leftIcon || rightIcon || leftAddon || rightAddon || rightElement
67
+
68
+ if (hasAddons) {
69
+ return (
70
+ <div
71
+ className={cn(
72
+ "flex items-center gap-2 bg-white border font-sans transition-colors",
73
+ "focus-within:ring-[3px]",
74
+ variant === "error"
75
+ ? "border-error-500 focus-within:border-error-500 focus-within:ring-error-200"
76
+ : "border-grey-300 focus-within:border-grey-300 focus-within:ring-grey-300/50",
77
+ size === "mini" && "h-6 pl-3 pr-0.5 text-xs rounded-md",
78
+ size === "small" && "h-8 pl-3 pr-0.5 text-sm rounded-md",
79
+ size === "regular" && "h-9 pl-3 pr-0.5 text-sm rounded-lg",
80
+ size === "large" && "h-10 pl-3 pr-0.5 text-base rounded-lg",
81
+ !size && "h-9 pl-3 pr-0.5 text-sm rounded-lg",
82
+ !rightElement && "pr-3",
83
+ roundness === "round" && "!rounded-full",
84
+ props.disabled && "opacity-50 cursor-not-allowed bg-grey-50",
85
+ className
86
+ )}
87
+ >
88
+ {leftIcon && (
89
+ <span className="shrink-0 text-grey-500 [&_svg]:size-4">{leftIcon}</span>
90
+ )}
91
+ {leftAddon && (
92
+ <span className="shrink-0 text-grey-500">{leftAddon}</span>
93
+ )}
94
+ <input
95
+ type={type}
96
+ className={cn(
97
+ "flex-1 min-w-0 bg-transparent border-0 outline-none placeholder:text-grey-400",
98
+ "disabled:cursor-not-allowed"
99
+ )}
100
+ ref={ref}
101
+ {...props}
102
+ />
103
+ {rightAddon && (
104
+ <span className="shrink-0 text-grey-500">{rightAddon}</span>
105
+ )}
106
+ {rightIcon && (
107
+ <span className="shrink-0 text-grey-500 [&_svg]:size-4">{rightIcon}</span>
108
+ )}
109
+ {rightElement && (
110
+ <span className="shrink-0">{rightElement}</span>
111
+ )}
112
+ </div>
113
+ )
114
+ }
115
+
116
+ return (
117
+ <input
118
+ type={type}
119
+ className={cn(inputVariants({ size, roundness, variant, className }))}
120
+ ref={ref}
121
+ {...props}
122
+ />
123
+ )
124
+ }
125
+ )
126
+ Input.displayName = "Input"
127
+
128
+ export { Input, inputVariants }
129
+ export type { InputSize, InputRoundness, InputVariant }