@nationaldesignstudio/react 0.2.0 → 0.3.0
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/dist/components/atoms/background/background.d.ts +13 -27
- package/dist/components/atoms/button/button.d.ts +55 -71
- package/dist/components/atoms/button/icon-button.d.ts +62 -110
- package/dist/components/atoms/input/input-group.d.ts +278 -0
- package/dist/components/atoms/input/input.d.ts +121 -0
- package/dist/components/atoms/select/select.d.ts +131 -0
- package/dist/components/organisms/card/card.d.ts +2 -2
- package/dist/components/sections/prose/prose.d.ts +3 -3
- package/dist/components/sections/river/river.d.ts +1 -1
- package/dist/components/sections/tout/tout.d.ts +1 -1
- package/dist/index.d.ts +4 -0
- package/dist/index.js +11034 -7824
- package/dist/index.js.map +1 -1
- package/dist/lib/form-control.d.ts +105 -0
- package/dist/tokens.css +2132 -17329
- package/package.json +1 -1
- package/src/components/atoms/background/background.tsx +71 -109
- package/src/components/atoms/button/button.stories.tsx +42 -0
- package/src/components/atoms/button/button.test.tsx +1 -1
- package/src/components/atoms/button/button.tsx +38 -103
- package/src/components/atoms/button/button.visual.test.tsx +70 -24
- package/src/components/atoms/button/icon-button.tsx +81 -224
- package/src/components/atoms/input/index.ts +17 -0
- package/src/components/atoms/input/input-group.stories.tsx +650 -0
- package/src/components/atoms/input/input-group.test.tsx +376 -0
- package/src/components/atoms/input/input-group.tsx +384 -0
- package/src/components/atoms/input/input.stories.tsx +232 -0
- package/src/components/atoms/input/input.test.tsx +183 -0
- package/src/components/atoms/input/input.tsx +97 -0
- package/src/components/atoms/select/index.ts +18 -0
- package/src/components/atoms/select/select.stories.tsx +455 -0
- package/src/components/atoms/select/select.tsx +320 -0
- package/src/components/dev-tools/dev-toolbar/dev-toolbar.stories.tsx +2 -6
- package/src/components/foundation/typography/typography.stories.tsx +401 -0
- package/src/components/organisms/card/card.stories.tsx +11 -11
- package/src/components/organisms/card/card.test.tsx +1 -1
- package/src/components/organisms/card/card.tsx +2 -2
- package/src/components/organisms/card/card.visual.test.tsx +6 -6
- package/src/components/organisms/navbar/navbar.tsx +2 -2
- package/src/components/organisms/navbar/navbar.visual.test.tsx +2 -2
- package/src/components/sections/card-grid/card-grid.tsx +1 -1
- package/src/components/sections/faq-section/faq-section.tsx +2 -2
- package/src/components/sections/hero/hero.test.tsx +5 -5
- package/src/components/sections/prose/prose.test.tsx +2 -2
- package/src/components/sections/prose/prose.tsx +4 -5
- package/src/components/sections/river/river.stories.tsx +8 -8
- package/src/components/sections/river/river.test.tsx +1 -1
- package/src/components/sections/river/river.tsx +2 -4
- package/src/components/sections/tout/tout.test.tsx +1 -1
- package/src/components/sections/tout/tout.tsx +2 -2
- package/src/index.ts +41 -0
- package/src/lib/form-control.ts +69 -0
- package/src/stories/Introduction.mdx +29 -15
- package/src/stories/ThemeProvider.stories.tsx +1 -3
- package/src/stories/TokenShowcase.stories.tsx +0 -19
- package/src/stories/TokenShowcase.tsx +714 -1366
- package/src/styles.css +3 -0
- package/src/tests/token-resolution.test.tsx +301 -0
|
@@ -0,0 +1,650 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from "@storybook/react-vite";
|
|
2
|
+
import {
|
|
3
|
+
InputGroup,
|
|
4
|
+
InputGroupAddon,
|
|
5
|
+
InputGroupButton,
|
|
6
|
+
InputGroupInput,
|
|
7
|
+
InputGroupText,
|
|
8
|
+
InputGroupTextarea,
|
|
9
|
+
} from "./input-group";
|
|
10
|
+
|
|
11
|
+
const SearchIcon = () => (
|
|
12
|
+
<svg
|
|
13
|
+
width="14"
|
|
14
|
+
height="14"
|
|
15
|
+
viewBox="0 0 16 16"
|
|
16
|
+
fill="none"
|
|
17
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
18
|
+
aria-hidden="true"
|
|
19
|
+
>
|
|
20
|
+
<path
|
|
21
|
+
d="M7.33333 12.6667C10.2789 12.6667 12.6667 10.2789 12.6667 7.33333C12.6667 4.38781 10.2789 2 7.33333 2C4.38781 2 2 4.38781 2 7.33333C2 10.2789 4.38781 12.6667 7.33333 12.6667Z"
|
|
22
|
+
stroke="currentColor"
|
|
23
|
+
strokeWidth="1.5"
|
|
24
|
+
strokeLinecap="round"
|
|
25
|
+
strokeLinejoin="round"
|
|
26
|
+
/>
|
|
27
|
+
<path
|
|
28
|
+
d="M14 14L11.1 11.1"
|
|
29
|
+
stroke="currentColor"
|
|
30
|
+
strokeWidth="1.5"
|
|
31
|
+
strokeLinecap="round"
|
|
32
|
+
strokeLinejoin="round"
|
|
33
|
+
/>
|
|
34
|
+
</svg>
|
|
35
|
+
);
|
|
36
|
+
|
|
37
|
+
const MailIcon = () => (
|
|
38
|
+
<svg
|
|
39
|
+
width="14"
|
|
40
|
+
height="14"
|
|
41
|
+
viewBox="0 0 16 16"
|
|
42
|
+
fill="none"
|
|
43
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
44
|
+
aria-hidden="true"
|
|
45
|
+
>
|
|
46
|
+
<path
|
|
47
|
+
d="M2.66667 2.66667H13.3333C14.0667 2.66667 14.6667 3.26667 14.6667 4V12C14.6667 12.7333 14.0667 13.3333 13.3333 13.3333H2.66667C1.93333 13.3333 1.33333 12.7333 1.33333 12V4C1.33333 3.26667 1.93333 2.66667 2.66667 2.66667Z"
|
|
48
|
+
stroke="currentColor"
|
|
49
|
+
strokeWidth="1.5"
|
|
50
|
+
strokeLinecap="round"
|
|
51
|
+
strokeLinejoin="round"
|
|
52
|
+
/>
|
|
53
|
+
<path
|
|
54
|
+
d="M14.6667 4L8 8.66667L1.33333 4"
|
|
55
|
+
stroke="currentColor"
|
|
56
|
+
strokeWidth="1.5"
|
|
57
|
+
strokeLinecap="round"
|
|
58
|
+
strokeLinejoin="round"
|
|
59
|
+
/>
|
|
60
|
+
</svg>
|
|
61
|
+
);
|
|
62
|
+
|
|
63
|
+
const CheckIcon = () => (
|
|
64
|
+
<svg
|
|
65
|
+
width="12"
|
|
66
|
+
height="12"
|
|
67
|
+
viewBox="0 0 16 16"
|
|
68
|
+
fill="none"
|
|
69
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
70
|
+
aria-hidden="true"
|
|
71
|
+
>
|
|
72
|
+
<path
|
|
73
|
+
d="M13.3333 4L6 11.3333L2.66667 8"
|
|
74
|
+
stroke="currentColor"
|
|
75
|
+
strokeWidth="2"
|
|
76
|
+
strokeLinecap="round"
|
|
77
|
+
strokeLinejoin="round"
|
|
78
|
+
/>
|
|
79
|
+
</svg>
|
|
80
|
+
);
|
|
81
|
+
|
|
82
|
+
const CopyIcon = () => (
|
|
83
|
+
<svg
|
|
84
|
+
width="14"
|
|
85
|
+
height="14"
|
|
86
|
+
viewBox="0 0 16 16"
|
|
87
|
+
fill="none"
|
|
88
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
89
|
+
aria-hidden="true"
|
|
90
|
+
>
|
|
91
|
+
<rect
|
|
92
|
+
x="5.33333"
|
|
93
|
+
y="5.33333"
|
|
94
|
+
width="8"
|
|
95
|
+
height="8"
|
|
96
|
+
rx="1"
|
|
97
|
+
stroke="currentColor"
|
|
98
|
+
strokeWidth="1.5"
|
|
99
|
+
/>
|
|
100
|
+
<path
|
|
101
|
+
d="M10.6667 5.33333V3.33333C10.6667 2.59695 10.0697 2 9.33333 2H3.33333C2.59695 2 2 2.59695 2 3.33333V9.33333C2 10.0697 2.59695 10.6667 3.33333 10.6667H5.33333"
|
|
102
|
+
stroke="currentColor"
|
|
103
|
+
strokeWidth="1.5"
|
|
104
|
+
/>
|
|
105
|
+
</svg>
|
|
106
|
+
);
|
|
107
|
+
|
|
108
|
+
const PlusIcon = () => (
|
|
109
|
+
<svg
|
|
110
|
+
width="14"
|
|
111
|
+
height="14"
|
|
112
|
+
viewBox="0 0 16 16"
|
|
113
|
+
fill="none"
|
|
114
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
115
|
+
aria-hidden="true"
|
|
116
|
+
>
|
|
117
|
+
<path
|
|
118
|
+
d="M8 3.33333V12.6667M3.33333 8H12.6667"
|
|
119
|
+
stroke="currentColor"
|
|
120
|
+
strokeWidth="1.5"
|
|
121
|
+
strokeLinecap="round"
|
|
122
|
+
/>
|
|
123
|
+
</svg>
|
|
124
|
+
);
|
|
125
|
+
|
|
126
|
+
const InfoIcon = () => (
|
|
127
|
+
<svg
|
|
128
|
+
width="14"
|
|
129
|
+
height="14"
|
|
130
|
+
viewBox="0 0 16 16"
|
|
131
|
+
fill="none"
|
|
132
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
133
|
+
aria-hidden="true"
|
|
134
|
+
>
|
|
135
|
+
<circle cx="8" cy="8" r="6" stroke="currentColor" strokeWidth="1.5" />
|
|
136
|
+
<path
|
|
137
|
+
d="M8 11V7M8 5V5.01"
|
|
138
|
+
stroke="currentColor"
|
|
139
|
+
strokeWidth="1.5"
|
|
140
|
+
strokeLinecap="round"
|
|
141
|
+
/>
|
|
142
|
+
</svg>
|
|
143
|
+
);
|
|
144
|
+
|
|
145
|
+
const SendIcon = () => (
|
|
146
|
+
<svg
|
|
147
|
+
width="14"
|
|
148
|
+
height="14"
|
|
149
|
+
viewBox="0 0 16 16"
|
|
150
|
+
fill="none"
|
|
151
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
152
|
+
aria-hidden="true"
|
|
153
|
+
>
|
|
154
|
+
<path
|
|
155
|
+
d="M8 3V13M8 3L4 7M8 3L12 7"
|
|
156
|
+
stroke="currentColor"
|
|
157
|
+
strokeWidth="1.5"
|
|
158
|
+
strokeLinecap="round"
|
|
159
|
+
strokeLinejoin="round"
|
|
160
|
+
/>
|
|
161
|
+
</svg>
|
|
162
|
+
);
|
|
163
|
+
|
|
164
|
+
const StarIcon = () => (
|
|
165
|
+
<svg
|
|
166
|
+
width="14"
|
|
167
|
+
height="14"
|
|
168
|
+
viewBox="0 0 16 16"
|
|
169
|
+
fill="none"
|
|
170
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
171
|
+
aria-hidden="true"
|
|
172
|
+
>
|
|
173
|
+
<path
|
|
174
|
+
d="M8 1.33333L10.06 5.50667L14.6667 6.18L11.3333 9.42667L12.12 14.0133L8 11.8467L3.88 14.0133L4.66667 9.42667L1.33333 6.18L5.94 5.50667L8 1.33333Z"
|
|
175
|
+
stroke="currentColor"
|
|
176
|
+
strokeWidth="1.5"
|
|
177
|
+
strokeLinecap="round"
|
|
178
|
+
strokeLinejoin="round"
|
|
179
|
+
/>
|
|
180
|
+
</svg>
|
|
181
|
+
);
|
|
182
|
+
|
|
183
|
+
const CreditCardIcon = () => (
|
|
184
|
+
<svg
|
|
185
|
+
width="14"
|
|
186
|
+
height="14"
|
|
187
|
+
viewBox="0 0 16 16"
|
|
188
|
+
fill="none"
|
|
189
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
190
|
+
aria-hidden="true"
|
|
191
|
+
>
|
|
192
|
+
<rect
|
|
193
|
+
x="1.33333"
|
|
194
|
+
y="3.33333"
|
|
195
|
+
width="13.3333"
|
|
196
|
+
height="9.33333"
|
|
197
|
+
rx="1.5"
|
|
198
|
+
stroke="currentColor"
|
|
199
|
+
strokeWidth="1.5"
|
|
200
|
+
/>
|
|
201
|
+
<path d="M1.33333 6H14.6667" stroke="currentColor" strokeWidth="1.5" />
|
|
202
|
+
</svg>
|
|
203
|
+
);
|
|
204
|
+
|
|
205
|
+
const meta: Meta<typeof InputGroup> = {
|
|
206
|
+
title: "Atoms/InputGroup",
|
|
207
|
+
component: InputGroup,
|
|
208
|
+
} as Meta<typeof InputGroup>;
|
|
209
|
+
|
|
210
|
+
export default meta;
|
|
211
|
+
type Story = StoryObj<typeof InputGroup>;
|
|
212
|
+
|
|
213
|
+
export const Playground: Story = {
|
|
214
|
+
render: (args) => (
|
|
215
|
+
<InputGroup {...args}>
|
|
216
|
+
<InputGroupInput placeholder="Search..." />
|
|
217
|
+
<InputGroupAddon>
|
|
218
|
+
<SearchIcon />
|
|
219
|
+
</InputGroupAddon>
|
|
220
|
+
</InputGroup>
|
|
221
|
+
),
|
|
222
|
+
};
|
|
223
|
+
Playground.argTypes = {
|
|
224
|
+
size: {
|
|
225
|
+
control: { type: "radio" },
|
|
226
|
+
options: ["sm", "default", "lg"],
|
|
227
|
+
},
|
|
228
|
+
disabled: {
|
|
229
|
+
control: { type: "boolean" },
|
|
230
|
+
},
|
|
231
|
+
};
|
|
232
|
+
Playground.args = {
|
|
233
|
+
size: "default",
|
|
234
|
+
disabled: false,
|
|
235
|
+
};
|
|
236
|
+
|
|
237
|
+
export const SearchWithResults = () => (
|
|
238
|
+
<InputGroup className="max-w-sm">
|
|
239
|
+
<InputGroupInput placeholder="Search..." />
|
|
240
|
+
<InputGroupAddon>
|
|
241
|
+
<SearchIcon />
|
|
242
|
+
</InputGroupAddon>
|
|
243
|
+
<InputGroupAddon align="inline-end">12 results</InputGroupAddon>
|
|
244
|
+
</InputGroup>
|
|
245
|
+
);
|
|
246
|
+
|
|
247
|
+
export const URLWithTooltip = () => (
|
|
248
|
+
<InputGroup className="max-w-sm">
|
|
249
|
+
<InputGroupInput placeholder="example.com" className="!pl-2" />
|
|
250
|
+
<InputGroupAddon>
|
|
251
|
+
<InputGroupText>https://</InputGroupText>
|
|
252
|
+
</InputGroupAddon>
|
|
253
|
+
<InputGroupAddon align="inline-end">
|
|
254
|
+
<InputGroupButton
|
|
255
|
+
className="rounded-full"
|
|
256
|
+
size="icon-xs"
|
|
257
|
+
aria-label="Info"
|
|
258
|
+
>
|
|
259
|
+
<InfoIcon />
|
|
260
|
+
</InputGroupButton>
|
|
261
|
+
</InputGroupAddon>
|
|
262
|
+
</InputGroup>
|
|
263
|
+
);
|
|
264
|
+
|
|
265
|
+
export const ChatInput = () => (
|
|
266
|
+
<InputGroup className="max-w-md">
|
|
267
|
+
<InputGroupTextarea
|
|
268
|
+
placeholder="Ask, Search or Chat..."
|
|
269
|
+
className="min-h-[80px]"
|
|
270
|
+
/>
|
|
271
|
+
<InputGroupAddon align="block-end">
|
|
272
|
+
<InputGroupButton
|
|
273
|
+
className="rounded-full"
|
|
274
|
+
size="icon-sm"
|
|
275
|
+
aria-label="Add attachment"
|
|
276
|
+
>
|
|
277
|
+
<PlusIcon />
|
|
278
|
+
</InputGroupButton>
|
|
279
|
+
<InputGroupText>52% used</InputGroupText>
|
|
280
|
+
<span className="ml-auto h-16 w-px bg-ui-color-border" />
|
|
281
|
+
<InputGroupButton
|
|
282
|
+
variant="solid"
|
|
283
|
+
className="rounded-full"
|
|
284
|
+
size="icon-sm"
|
|
285
|
+
aria-label="Send"
|
|
286
|
+
>
|
|
287
|
+
<SendIcon />
|
|
288
|
+
</InputGroupButton>
|
|
289
|
+
</InputGroupAddon>
|
|
290
|
+
</InputGroup>
|
|
291
|
+
);
|
|
292
|
+
|
|
293
|
+
export const VerifiedUsername = () => (
|
|
294
|
+
<InputGroup className="max-w-sm">
|
|
295
|
+
<InputGroupInput placeholder="@shadcn" defaultValue="@shadcn" />
|
|
296
|
+
<InputGroupAddon align="inline-end">
|
|
297
|
+
<div className="flex size-16 items-center justify-center rounded-full bg-green-500 text-white">
|
|
298
|
+
<CheckIcon />
|
|
299
|
+
</div>
|
|
300
|
+
</InputGroupAddon>
|
|
301
|
+
</InputGroup>
|
|
302
|
+
);
|
|
303
|
+
|
|
304
|
+
export const CopyableLink = () => (
|
|
305
|
+
<InputGroup className="max-w-sm">
|
|
306
|
+
<InputGroupInput
|
|
307
|
+
placeholder="https://x.com/shadcn"
|
|
308
|
+
defaultValue="https://x.com/shadcn"
|
|
309
|
+
readOnly
|
|
310
|
+
/>
|
|
311
|
+
<InputGroupAddon align="inline-end">
|
|
312
|
+
<InputGroupButton aria-label="Copy" size="icon-xs">
|
|
313
|
+
<CopyIcon />
|
|
314
|
+
</InputGroupButton>
|
|
315
|
+
</InputGroupAddon>
|
|
316
|
+
</InputGroup>
|
|
317
|
+
);
|
|
318
|
+
|
|
319
|
+
export const CurrencyInput = () => (
|
|
320
|
+
<InputGroup className="max-w-[200px]">
|
|
321
|
+
<InputGroupAddon>
|
|
322
|
+
<InputGroupText>$</InputGroupText>
|
|
323
|
+
</InputGroupAddon>
|
|
324
|
+
<InputGroupInput placeholder="0.00" type="number" />
|
|
325
|
+
<InputGroupAddon align="inline-end">
|
|
326
|
+
<InputGroupText>USD</InputGroupText>
|
|
327
|
+
</InputGroupAddon>
|
|
328
|
+
</InputGroup>
|
|
329
|
+
);
|
|
330
|
+
|
|
331
|
+
export const PasswordWithInfo = () => (
|
|
332
|
+
<InputGroup className="max-w-sm">
|
|
333
|
+
<InputGroupInput placeholder="Enter password" type="password" />
|
|
334
|
+
<InputGroupAddon align="inline-end">
|
|
335
|
+
<InputGroupButton aria-label="Password requirements" size="icon-xs">
|
|
336
|
+
<InfoIcon />
|
|
337
|
+
</InputGroupButton>
|
|
338
|
+
</InputGroupAddon>
|
|
339
|
+
</InputGroup>
|
|
340
|
+
);
|
|
341
|
+
|
|
342
|
+
export const PillInput = () => (
|
|
343
|
+
<InputGroup className="max-w-sm rounded-full">
|
|
344
|
+
<InputGroupAddon>
|
|
345
|
+
<InputGroupButton
|
|
346
|
+
variant="outline"
|
|
347
|
+
size="icon-xs"
|
|
348
|
+
className="rounded-full"
|
|
349
|
+
>
|
|
350
|
+
<InfoIcon />
|
|
351
|
+
</InputGroupButton>
|
|
352
|
+
</InputGroupAddon>
|
|
353
|
+
<InputGroupAddon className="pl-4 text-text-muted">https://</InputGroupAddon>
|
|
354
|
+
<InputGroupInput id="input-secure-19" placeholder="example.com" />
|
|
355
|
+
<InputGroupAddon align="inline-end">
|
|
356
|
+
<InputGroupButton size="icon-xs" aria-label="Favorite">
|
|
357
|
+
<StarIcon />
|
|
358
|
+
</InputGroupButton>
|
|
359
|
+
</InputGroupAddon>
|
|
360
|
+
</InputGroup>
|
|
361
|
+
);
|
|
362
|
+
|
|
363
|
+
export const WithIcons = () => (
|
|
364
|
+
<div className="grid w-full max-w-sm gap-24">
|
|
365
|
+
<InputGroup>
|
|
366
|
+
<InputGroupInput placeholder="Search..." />
|
|
367
|
+
<InputGroupAddon>
|
|
368
|
+
<SearchIcon />
|
|
369
|
+
</InputGroupAddon>
|
|
370
|
+
</InputGroup>
|
|
371
|
+
<InputGroup>
|
|
372
|
+
<InputGroupInput type="email" placeholder="Enter your email" />
|
|
373
|
+
<InputGroupAddon>
|
|
374
|
+
<MailIcon />
|
|
375
|
+
</InputGroupAddon>
|
|
376
|
+
</InputGroup>
|
|
377
|
+
<InputGroup>
|
|
378
|
+
<InputGroupInput placeholder="Card number" />
|
|
379
|
+
<InputGroupAddon>
|
|
380
|
+
<CreditCardIcon />
|
|
381
|
+
</InputGroupAddon>
|
|
382
|
+
<InputGroupAddon align="inline-end">
|
|
383
|
+
<CheckIcon />
|
|
384
|
+
</InputGroupAddon>
|
|
385
|
+
</InputGroup>
|
|
386
|
+
<InputGroup>
|
|
387
|
+
<InputGroupInput placeholder="Card number" />
|
|
388
|
+
<InputGroupAddon align="inline-end">
|
|
389
|
+
<StarIcon />
|
|
390
|
+
<InfoIcon />
|
|
391
|
+
</InputGroupAddon>
|
|
392
|
+
</InputGroup>
|
|
393
|
+
</div>
|
|
394
|
+
);
|
|
395
|
+
|
|
396
|
+
export const WithText = () => (
|
|
397
|
+
<div className="grid w-full max-w-sm gap-24">
|
|
398
|
+
<InputGroup>
|
|
399
|
+
<InputGroupAddon>
|
|
400
|
+
<InputGroupText>$</InputGroupText>
|
|
401
|
+
</InputGroupAddon>
|
|
402
|
+
<InputGroupInput placeholder="0.00" />
|
|
403
|
+
<InputGroupAddon align="inline-end">
|
|
404
|
+
<InputGroupText>USD</InputGroupText>
|
|
405
|
+
</InputGroupAddon>
|
|
406
|
+
</InputGroup>
|
|
407
|
+
<InputGroup>
|
|
408
|
+
<InputGroupAddon>
|
|
409
|
+
<InputGroupText>https://</InputGroupText>
|
|
410
|
+
</InputGroupAddon>
|
|
411
|
+
<InputGroupInput placeholder="example.com" className="!pl-2" />
|
|
412
|
+
<InputGroupAddon align="inline-end">
|
|
413
|
+
<InputGroupText>.com</InputGroupText>
|
|
414
|
+
</InputGroupAddon>
|
|
415
|
+
</InputGroup>
|
|
416
|
+
<InputGroup>
|
|
417
|
+
<InputGroupInput placeholder="Enter your username" />
|
|
418
|
+
<InputGroupAddon align="inline-end">
|
|
419
|
+
<InputGroupText>@company.com</InputGroupText>
|
|
420
|
+
</InputGroupAddon>
|
|
421
|
+
</InputGroup>
|
|
422
|
+
<InputGroup>
|
|
423
|
+
<InputGroupTextarea placeholder="Enter your message" />
|
|
424
|
+
<InputGroupAddon align="block-end">
|
|
425
|
+
<InputGroupText className="text-12 text-text-muted">
|
|
426
|
+
120 characters left
|
|
427
|
+
</InputGroupText>
|
|
428
|
+
</InputGroupAddon>
|
|
429
|
+
</InputGroup>
|
|
430
|
+
</div>
|
|
431
|
+
);
|
|
432
|
+
|
|
433
|
+
export const WithButtons = () => (
|
|
434
|
+
<div className="grid w-full max-w-sm gap-24">
|
|
435
|
+
<InputGroup>
|
|
436
|
+
<InputGroupInput placeholder="https://x.com/shadcn" readOnly />
|
|
437
|
+
<InputGroupAddon align="inline-end">
|
|
438
|
+
<InputGroupButton aria-label="Copy" size="icon-xs">
|
|
439
|
+
<CopyIcon />
|
|
440
|
+
</InputGroupButton>
|
|
441
|
+
</InputGroupAddon>
|
|
442
|
+
</InputGroup>
|
|
443
|
+
<InputGroup>
|
|
444
|
+
<InputGroupInput placeholder="Type to search..." />
|
|
445
|
+
<InputGroupAddon align="inline-end">
|
|
446
|
+
<InputGroupButton>Search</InputGroupButton>
|
|
447
|
+
</InputGroupAddon>
|
|
448
|
+
</InputGroup>
|
|
449
|
+
</div>
|
|
450
|
+
);
|
|
451
|
+
|
|
452
|
+
export const TextareaWithActions = () => (
|
|
453
|
+
<InputGroup className="max-w-md">
|
|
454
|
+
<InputGroupAddon
|
|
455
|
+
align="block-start"
|
|
456
|
+
className="border-b border-ui-color-border pb-8"
|
|
457
|
+
>
|
|
458
|
+
<InputGroupText className="font-medium">
|
|
459
|
+
<span className="font-mono">script.js</span>
|
|
460
|
+
</InputGroupText>
|
|
461
|
+
<InputGroupButton className="ml-auto" size="icon-xs" aria-label="Refresh">
|
|
462
|
+
<PlusIcon />
|
|
463
|
+
</InputGroupButton>
|
|
464
|
+
<InputGroupButton size="icon-xs" aria-label="Copy">
|
|
465
|
+
<CopyIcon />
|
|
466
|
+
</InputGroupButton>
|
|
467
|
+
</InputGroupAddon>
|
|
468
|
+
<InputGroupTextarea
|
|
469
|
+
placeholder="console.log('Hello, world!');"
|
|
470
|
+
className="min-h-[120px] font-mono"
|
|
471
|
+
/>
|
|
472
|
+
<InputGroupAddon
|
|
473
|
+
align="block-end"
|
|
474
|
+
className="border-t border-ui-color-border pt-8"
|
|
475
|
+
>
|
|
476
|
+
<InputGroupText>Line 1, Column 1</InputGroupText>
|
|
477
|
+
<InputGroupButton className="ml-auto" size="sm" variant="solid">
|
|
478
|
+
Run <SendIcon />
|
|
479
|
+
</InputGroupButton>
|
|
480
|
+
</InputGroupAddon>
|
|
481
|
+
</InputGroup>
|
|
482
|
+
);
|
|
483
|
+
|
|
484
|
+
export const SpinnerLoading = () => (
|
|
485
|
+
<div className="grid w-full max-w-sm gap-24">
|
|
486
|
+
<InputGroup data-disabled>
|
|
487
|
+
<InputGroupInput placeholder="Searching..." disabled />
|
|
488
|
+
<InputGroupAddon align="inline-end">
|
|
489
|
+
<svg
|
|
490
|
+
className="size-14 animate-spin"
|
|
491
|
+
viewBox="0 0 16 16"
|
|
492
|
+
fill="none"
|
|
493
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
494
|
+
aria-hidden="true"
|
|
495
|
+
>
|
|
496
|
+
<circle
|
|
497
|
+
cx="8"
|
|
498
|
+
cy="8"
|
|
499
|
+
r="6"
|
|
500
|
+
stroke="currentColor"
|
|
501
|
+
strokeWidth="2"
|
|
502
|
+
strokeOpacity="0.25"
|
|
503
|
+
/>
|
|
504
|
+
<path
|
|
505
|
+
d="M14 8A6 6 0 0 0 8 2"
|
|
506
|
+
stroke="currentColor"
|
|
507
|
+
strokeWidth="2"
|
|
508
|
+
strokeLinecap="round"
|
|
509
|
+
/>
|
|
510
|
+
</svg>
|
|
511
|
+
</InputGroupAddon>
|
|
512
|
+
</InputGroup>
|
|
513
|
+
<InputGroup data-disabled>
|
|
514
|
+
<InputGroupInput placeholder="Saving changes..." disabled />
|
|
515
|
+
<InputGroupAddon align="inline-end">
|
|
516
|
+
<InputGroupText>Saving...</InputGroupText>
|
|
517
|
+
<svg
|
|
518
|
+
className="size-14 animate-spin"
|
|
519
|
+
viewBox="0 0 16 16"
|
|
520
|
+
fill="none"
|
|
521
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
522
|
+
aria-hidden="true"
|
|
523
|
+
>
|
|
524
|
+
<circle
|
|
525
|
+
cx="8"
|
|
526
|
+
cy="8"
|
|
527
|
+
r="6"
|
|
528
|
+
stroke="currentColor"
|
|
529
|
+
strokeWidth="2"
|
|
530
|
+
strokeOpacity="0.25"
|
|
531
|
+
/>
|
|
532
|
+
<path
|
|
533
|
+
d="M14 8A6 6 0 0 0 8 2"
|
|
534
|
+
stroke="currentColor"
|
|
535
|
+
strokeWidth="2"
|
|
536
|
+
strokeLinecap="round"
|
|
537
|
+
/>
|
|
538
|
+
</svg>
|
|
539
|
+
</InputGroupAddon>
|
|
540
|
+
</InputGroup>
|
|
541
|
+
</div>
|
|
542
|
+
);
|
|
543
|
+
|
|
544
|
+
export const WithLabel = () => (
|
|
545
|
+
<div className="grid w-full max-w-sm gap-24">
|
|
546
|
+
<InputGroup>
|
|
547
|
+
<InputGroupInput id="email" placeholder="shadcn" />
|
|
548
|
+
<InputGroupAddon>
|
|
549
|
+
<label htmlFor="email" className="cursor-text">
|
|
550
|
+
@
|
|
551
|
+
</label>
|
|
552
|
+
</InputGroupAddon>
|
|
553
|
+
</InputGroup>
|
|
554
|
+
<InputGroup>
|
|
555
|
+
<InputGroupInput
|
|
556
|
+
id="email-2"
|
|
557
|
+
placeholder="shadcn@vercel.com"
|
|
558
|
+
className="!pl-12"
|
|
559
|
+
/>
|
|
560
|
+
<InputGroupAddon align="block-start">
|
|
561
|
+
<label
|
|
562
|
+
htmlFor="email-2"
|
|
563
|
+
className="text-14 font-semibold text-gray-900 cursor-text"
|
|
564
|
+
>
|
|
565
|
+
Email
|
|
566
|
+
</label>
|
|
567
|
+
<InputGroupButton
|
|
568
|
+
aria-label="Help"
|
|
569
|
+
className="ml-auto rounded-full"
|
|
570
|
+
size="icon-xs"
|
|
571
|
+
>
|
|
572
|
+
<InfoIcon />
|
|
573
|
+
</InputGroupButton>
|
|
574
|
+
</InputGroupAddon>
|
|
575
|
+
</InputGroup>
|
|
576
|
+
</div>
|
|
577
|
+
);
|
|
578
|
+
|
|
579
|
+
export const AllSizes = () => (
|
|
580
|
+
<div className="flex flex-col gap-24 max-w-sm">
|
|
581
|
+
<div>
|
|
582
|
+
<p className="mb-8 text-12 text-text-muted">Small (32px)</p>
|
|
583
|
+
<InputGroup size="sm">
|
|
584
|
+
<InputGroupInput placeholder="Small" />
|
|
585
|
+
<InputGroupAddon>
|
|
586
|
+
<SearchIcon />
|
|
587
|
+
</InputGroupAddon>
|
|
588
|
+
</InputGroup>
|
|
589
|
+
</div>
|
|
590
|
+
<div>
|
|
591
|
+
<p className="mb-8 text-12 text-text-muted">Default (36px)</p>
|
|
592
|
+
<InputGroup size="default">
|
|
593
|
+
<InputGroupInput placeholder="Default" />
|
|
594
|
+
<InputGroupAddon>
|
|
595
|
+
<SearchIcon />
|
|
596
|
+
</InputGroupAddon>
|
|
597
|
+
</InputGroup>
|
|
598
|
+
</div>
|
|
599
|
+
<div>
|
|
600
|
+
<p className="mb-8 text-12 text-text-muted">Large (48px)</p>
|
|
601
|
+
<InputGroup size="lg">
|
|
602
|
+
<InputGroupInput placeholder="Large" />
|
|
603
|
+
<InputGroupAddon>
|
|
604
|
+
<SearchIcon />
|
|
605
|
+
</InputGroupAddon>
|
|
606
|
+
</InputGroup>
|
|
607
|
+
</div>
|
|
608
|
+
</div>
|
|
609
|
+
);
|
|
610
|
+
|
|
611
|
+
export const AllStates = () => (
|
|
612
|
+
<div className="flex flex-col gap-24 max-w-sm">
|
|
613
|
+
<div>
|
|
614
|
+
<p className="mb-8 text-12 text-text-muted">Default</p>
|
|
615
|
+
<InputGroup>
|
|
616
|
+
<InputGroupInput placeholder="Search..." />
|
|
617
|
+
<InputGroupAddon>
|
|
618
|
+
<SearchIcon />
|
|
619
|
+
</InputGroupAddon>
|
|
620
|
+
</InputGroup>
|
|
621
|
+
</div>
|
|
622
|
+
<div>
|
|
623
|
+
<p className="mb-8 text-12 text-text-muted">Focus (click input)</p>
|
|
624
|
+
<InputGroup>
|
|
625
|
+
<InputGroupInput placeholder="Click to focus..." />
|
|
626
|
+
<InputGroupAddon>
|
|
627
|
+
<SearchIcon />
|
|
628
|
+
</InputGroupAddon>
|
|
629
|
+
</InputGroup>
|
|
630
|
+
</div>
|
|
631
|
+
<div>
|
|
632
|
+
<p className="mb-8 text-12 text-text-muted">Error</p>
|
|
633
|
+
<InputGroup>
|
|
634
|
+
<InputGroupInput aria-invalid="true" defaultValue="invalid" />
|
|
635
|
+
<InputGroupAddon>
|
|
636
|
+
<MailIcon />
|
|
637
|
+
</InputGroupAddon>
|
|
638
|
+
</InputGroup>
|
|
639
|
+
</div>
|
|
640
|
+
<div>
|
|
641
|
+
<p className="mb-8 text-12 text-text-muted">Disabled</p>
|
|
642
|
+
<InputGroup disabled>
|
|
643
|
+
<InputGroupInput disabled placeholder="Disabled" />
|
|
644
|
+
<InputGroupAddon>
|
|
645
|
+
<SearchIcon />
|
|
646
|
+
</InputGroupAddon>
|
|
647
|
+
</InputGroup>
|
|
648
|
+
</div>
|
|
649
|
+
</div>
|
|
650
|
+
);
|