@nationaldesignstudio/react 0.3.0 → 0.5.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/component-registry.md +1310 -127
- package/dist/components/atoms/button/button.d.ts +55 -47
- package/dist/components/atoms/button/button.figma.d.ts +1 -0
- package/dist/components/atoms/input/input.d.ts +24 -24
- package/dist/components/atoms/popover/popover.d.ts +195 -0
- package/dist/components/atoms/select/select.d.ts +24 -24
- package/dist/components/atoms/tooltip/tooltip.d.ts +161 -0
- package/dist/components/organisms/card/card.d.ts +1 -1
- package/dist/components/sections/hero/hero.d.ts +2 -2
- package/dist/components/sections/tout/tout.d.ts +3 -3
- package/dist/components/shared/floating-arrow.d.ts +34 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.js +11602 -8499
- package/dist/index.js.map +1 -1
- package/dist/lib/form-control.d.ts +25 -24
- package/dist/tokens.css +4797 -3940
- package/package.json +2 -1
- package/src/components/atoms/accordion/accordion.stories.tsx +1 -1
- package/src/components/atoms/accordion/accordion.tsx +2 -2
- package/src/components/atoms/button/button.figma.tsx +37 -0
- package/src/components/atoms/button/button.stories.tsx +236 -140
- package/src/components/atoms/button/button.test.tsx +289 -5
- package/src/components/atoms/button/button.tsx +37 -33
- package/src/components/atoms/button/button.visual.test.tsx +26 -76
- package/src/components/atoms/button/icon-button.stories.tsx +44 -101
- package/src/components/atoms/button/icon-button.test.tsx +26 -94
- package/src/components/atoms/button/icon-button.tsx +3 -3
- package/src/components/atoms/input/input-group.stories.tsx +4 -8
- package/src/components/atoms/input/input-group.test.tsx +14 -28
- package/src/components/atoms/input/input-group.tsx +57 -32
- package/src/components/atoms/input/input.stories.tsx +14 -18
- package/src/components/atoms/input/input.test.tsx +4 -20
- package/src/components/atoms/input/input.tsx +16 -9
- package/src/components/atoms/pager-control/pager-control.stories.tsx +6 -8
- package/src/components/atoms/pager-control/pager-control.tsx +12 -12
- package/src/components/atoms/popover/index.ts +30 -0
- package/src/components/atoms/popover/popover.stories.tsx +531 -0
- package/src/components/atoms/popover/popover.test.tsx +486 -0
- package/src/components/atoms/popover/popover.tsx +488 -0
- package/src/components/atoms/select/select.tsx +12 -8
- package/src/components/atoms/tooltip/index.ts +24 -0
- package/src/components/atoms/tooltip/tooltip.stories.tsx +348 -0
- package/src/components/atoms/tooltip/tooltip.test.tsx +363 -0
- package/src/components/atoms/tooltip/tooltip.tsx +347 -0
- package/src/components/dev-tools/dev-toolbar/dev-toolbar.stories.tsx +8 -13
- package/src/components/dev-tools/dev-toolbar/dev-toolbar.tsx +3 -3
- package/src/components/organisms/card/card.stories.tsx +19 -19
- package/src/components/organisms/card/card.tsx +1 -1
- package/src/components/organisms/card/card.visual.test.tsx +11 -11
- package/src/components/organisms/navbar/navbar.visual.test.tsx +2 -2
- package/src/components/organisms/us-gov-banner/us-gov-banner.tsx +2 -2
- package/src/components/sections/banner/banner.stories.tsx +1 -5
- package/src/components/sections/banner/banner.test.tsx +2 -2
- package/src/components/sections/banner/banner.tsx +6 -6
- package/src/components/sections/card-grid/card-grid.tsx +4 -4
- package/src/components/sections/hero/hero.stories.tsx +7 -7
- package/src/components/sections/hero/hero.tsx +10 -11
- package/src/components/sections/prose/prose.tsx +2 -2
- package/src/components/sections/river/river.test.tsx +3 -3
- package/src/components/sections/river/river.tsx +6 -12
- package/src/components/sections/tout/tout.stories.tsx +7 -31
- package/src/components/sections/tout/tout.tsx +9 -9
- package/src/components/sections/two-column-section/two-column-section.tsx +7 -9
- package/src/components/shared/floating-arrow.tsx +78 -0
- package/src/components/shared/index.ts +5 -0
- package/src/index.ts +57 -0
- package/src/lib/form-control.ts +8 -6
- package/src/stories/grid-system.stories.tsx +309 -0
- package/src/stories/{ThemeProvider.stories.tsx → theme-provider.stories.tsx} +7 -19
- package/src/stories/{TokenShowcase.stories.tsx → token-showcase.stories.tsx} +1 -1
- package/src/stories/{TokenShowcase.tsx → token-showcase.tsx} +34 -34
- package/src/styles.css +3 -3
- package/src/tests/token-resolution.test.tsx +6 -9
- package/src/theme/hooks.ts +1 -1
- package/src/theme/index.ts +1 -1
- package/src/theme/theme-provider.test.tsx +270 -0
- package/src/theme/{ThemeProvider.tsx → theme-provider.tsx} +18 -2
- package/src/stories/GridSystem.stories.tsx +0 -84
- /package/src/stories/{Introduction.mdx → introduction.mdx} +0 -0
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import type { Meta, StoryObj } from "@storybook/react-vite";
|
|
2
2
|
import { IconButton } from ".";
|
|
3
3
|
|
|
4
|
-
// Simple placeholder icons for stories
|
|
5
4
|
const SearchIcon = () => (
|
|
6
5
|
<svg
|
|
7
6
|
width="16"
|
|
@@ -66,7 +65,7 @@ Playground.argTypes = {
|
|
|
66
65
|
control: {
|
|
67
66
|
type: "radio",
|
|
68
67
|
},
|
|
69
|
-
options: ["sm", "
|
|
68
|
+
options: ["sm", "md", "lg"],
|
|
70
69
|
},
|
|
71
70
|
disabled: {
|
|
72
71
|
control: {
|
|
@@ -77,42 +76,38 @@ Playground.argTypes = {
|
|
|
77
76
|
control: {
|
|
78
77
|
type: "radio",
|
|
79
78
|
},
|
|
80
|
-
options: [
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
79
|
+
options: [
|
|
80
|
+
"primary",
|
|
81
|
+
"primary-outline",
|
|
82
|
+
"secondary",
|
|
83
|
+
"secondary-outline",
|
|
84
|
+
"ghost",
|
|
85
|
+
"ghost-inverse",
|
|
86
|
+
],
|
|
87
87
|
},
|
|
88
88
|
rounded: {
|
|
89
89
|
control: {
|
|
90
90
|
type: "radio",
|
|
91
91
|
},
|
|
92
|
-
options: ["default", "
|
|
92
|
+
options: ["default", "full"],
|
|
93
93
|
},
|
|
94
94
|
};
|
|
95
95
|
Playground.args = {
|
|
96
|
-
size: "
|
|
96
|
+
size: "md",
|
|
97
97
|
disabled: false,
|
|
98
|
-
variant: "
|
|
99
|
-
colorScheme: "dark",
|
|
98
|
+
variant: "primary",
|
|
100
99
|
rounded: "default",
|
|
101
100
|
"aria-label": "Search",
|
|
102
101
|
};
|
|
103
102
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
// =============================================================================
|
|
107
|
-
|
|
108
|
-
export const Solid = () => (
|
|
109
|
-
<IconButton variant="solid" aria-label="Search">
|
|
103
|
+
export const Primary = () => (
|
|
104
|
+
<IconButton variant="primary" aria-label="Search">
|
|
110
105
|
<SearchIcon />
|
|
111
106
|
</IconButton>
|
|
112
107
|
);
|
|
113
108
|
|
|
114
|
-
export const
|
|
115
|
-
<IconButton variant="outline" aria-label="Search">
|
|
109
|
+
export const PrimaryOutline = () => (
|
|
110
|
+
<IconButton variant="primary-outline" aria-label="Search">
|
|
116
111
|
<SearchIcon />
|
|
117
112
|
</IconButton>
|
|
118
113
|
);
|
|
@@ -123,92 +118,64 @@ export const Ghost = () => (
|
|
|
123
118
|
</IconButton>
|
|
124
119
|
);
|
|
125
120
|
|
|
126
|
-
export const Subtle = () => (
|
|
127
|
-
<IconButton variant="subtle" aria-label="Search">
|
|
128
|
-
<SearchIcon />
|
|
129
|
-
</IconButton>
|
|
130
|
-
);
|
|
131
|
-
|
|
132
|
-
// =============================================================================
|
|
133
|
-
// Variants (Light Color Scheme - for dark backgrounds)
|
|
134
|
-
// =============================================================================
|
|
135
|
-
|
|
136
121
|
const DarkBackground = ({ children }: { children: React.ReactNode }) => (
|
|
137
|
-
<div className="rounded-radius-12 bg-gray-1200 p-
|
|
138
|
-
);
|
|
139
|
-
|
|
140
|
-
export const SolidLight = () => (
|
|
141
|
-
<DarkBackground>
|
|
142
|
-
<IconButton variant="solid" colorScheme="light" aria-label="Navigate">
|
|
143
|
-
<ArrowRightIcon />
|
|
144
|
-
</IconButton>
|
|
145
|
-
</DarkBackground>
|
|
122
|
+
<div className="rounded-radius-12 bg-gray-1200 p-32">{children}</div>
|
|
146
123
|
);
|
|
147
124
|
|
|
148
|
-
export const
|
|
125
|
+
export const Secondary = () => (
|
|
149
126
|
<DarkBackground>
|
|
150
|
-
<IconButton variant="
|
|
127
|
+
<IconButton variant="secondary" aria-label="Navigate">
|
|
151
128
|
<ArrowRightIcon />
|
|
152
129
|
</IconButton>
|
|
153
130
|
</DarkBackground>
|
|
154
131
|
);
|
|
155
132
|
|
|
156
|
-
export const
|
|
133
|
+
export const SecondaryOutline = () => (
|
|
157
134
|
<DarkBackground>
|
|
158
|
-
<IconButton variant="
|
|
135
|
+
<IconButton variant="secondary-outline" aria-label="Navigate">
|
|
159
136
|
<ArrowRightIcon />
|
|
160
137
|
</IconButton>
|
|
161
138
|
</DarkBackground>
|
|
162
139
|
);
|
|
163
140
|
|
|
164
|
-
export const
|
|
141
|
+
export const GhostInverse = () => (
|
|
165
142
|
<DarkBackground>
|
|
166
|
-
<IconButton variant="
|
|
143
|
+
<IconButton variant="ghost-inverse" aria-label="Navigate">
|
|
167
144
|
<ArrowRightIcon />
|
|
168
145
|
</IconButton>
|
|
169
146
|
</DarkBackground>
|
|
170
147
|
);
|
|
171
148
|
|
|
172
|
-
// =============================================================================
|
|
173
|
-
// All Variants Comparison
|
|
174
|
-
// =============================================================================
|
|
175
|
-
|
|
176
149
|
export const AllVariants = () => (
|
|
177
|
-
<div className="flex flex-col gap-
|
|
150
|
+
<div className="flex flex-col gap-32">
|
|
178
151
|
<div>
|
|
179
|
-
<h3 className="mb-
|
|
180
|
-
|
|
152
|
+
<h3 className="mb-16 text-14 font-medium text-text-secondary">
|
|
153
|
+
For Light Backgrounds
|
|
181
154
|
</h3>
|
|
182
|
-
<div className="flex gap-
|
|
183
|
-
<IconButton variant="
|
|
155
|
+
<div className="flex gap-16">
|
|
156
|
+
<IconButton variant="primary" aria-label="Primary">
|
|
184
157
|
<SearchIcon />
|
|
185
158
|
</IconButton>
|
|
186
|
-
<IconButton variant="outline" aria-label="Outline">
|
|
159
|
+
<IconButton variant="primary-outline" aria-label="Primary Outline">
|
|
187
160
|
<SearchIcon />
|
|
188
161
|
</IconButton>
|
|
189
162
|
<IconButton variant="ghost" aria-label="Ghost">
|
|
190
163
|
<SearchIcon />
|
|
191
164
|
</IconButton>
|
|
192
|
-
<IconButton variant="subtle" aria-label="Subtle">
|
|
193
|
-
<SearchIcon />
|
|
194
|
-
</IconButton>
|
|
195
165
|
</div>
|
|
196
166
|
</div>
|
|
197
167
|
<DarkBackground>
|
|
198
|
-
<h3 className="mb-
|
|
199
|
-
|
|
168
|
+
<h3 className="mb-16 text-14 font-medium text-gray-400">
|
|
169
|
+
For Dark Backgrounds
|
|
200
170
|
</h3>
|
|
201
|
-
<div className="flex gap-
|
|
202
|
-
<IconButton variant="
|
|
203
|
-
<ArrowRightIcon />
|
|
204
|
-
</IconButton>
|
|
205
|
-
<IconButton variant="outline" colorScheme="light" aria-label="Outline">
|
|
171
|
+
<div className="flex gap-16">
|
|
172
|
+
<IconButton variant="secondary" aria-label="Secondary">
|
|
206
173
|
<ArrowRightIcon />
|
|
207
174
|
</IconButton>
|
|
208
|
-
<IconButton variant="
|
|
175
|
+
<IconButton variant="secondary-outline" aria-label="Secondary Outline">
|
|
209
176
|
<ArrowRightIcon />
|
|
210
177
|
</IconButton>
|
|
211
|
-
<IconButton variant="
|
|
178
|
+
<IconButton variant="ghost-inverse" aria-label="Ghost Inverse">
|
|
212
179
|
<ArrowRightIcon />
|
|
213
180
|
</IconButton>
|
|
214
181
|
</div>
|
|
@@ -216,22 +183,12 @@ export const AllVariants = () => (
|
|
|
216
183
|
</div>
|
|
217
184
|
);
|
|
218
185
|
|
|
219
|
-
// =============================================================================
|
|
220
|
-
// Rounded Variants
|
|
221
|
-
// =============================================================================
|
|
222
|
-
|
|
223
186
|
export const RoundedDefault = () => (
|
|
224
187
|
<IconButton rounded="default" aria-label="Search">
|
|
225
188
|
<SearchIcon />
|
|
226
189
|
</IconButton>
|
|
227
190
|
);
|
|
228
191
|
|
|
229
|
-
export const RoundedSm = () => (
|
|
230
|
-
<IconButton rounded="sm" aria-label="Search">
|
|
231
|
-
<SearchIcon />
|
|
232
|
-
</IconButton>
|
|
233
|
-
);
|
|
234
|
-
|
|
235
192
|
export const RoundedFull = () => (
|
|
236
193
|
<IconButton rounded="full" aria-label="Search">
|
|
237
194
|
<SearchIcon />
|
|
@@ -239,32 +196,22 @@ export const RoundedFull = () => (
|
|
|
239
196
|
);
|
|
240
197
|
|
|
241
198
|
export const AllRounded = () => (
|
|
242
|
-
<div className="flex gap-
|
|
199
|
+
<div className="flex gap-16">
|
|
243
200
|
<div className="text-center">
|
|
244
201
|
<IconButton rounded="default" aria-label="Default rounded">
|
|
245
202
|
<SearchIcon />
|
|
246
203
|
</IconButton>
|
|
247
|
-
<p className="mt-
|
|
248
|
-
</div>
|
|
249
|
-
<div className="text-center">
|
|
250
|
-
<IconButton rounded="sm" aria-label="Small rounded">
|
|
251
|
-
<SearchIcon />
|
|
252
|
-
</IconButton>
|
|
253
|
-
<p className="mt-spacing-8 text-12 text-text-muted">sm</p>
|
|
204
|
+
<p className="mt-8 text-12 text-text-muted">default</p>
|
|
254
205
|
</div>
|
|
255
206
|
<div className="text-center">
|
|
256
207
|
<IconButton rounded="full" aria-label="Full rounded">
|
|
257
208
|
<SearchIcon />
|
|
258
209
|
</IconButton>
|
|
259
|
-
<p className="mt-
|
|
210
|
+
<p className="mt-8 text-12 text-text-muted">full</p>
|
|
260
211
|
</div>
|
|
261
212
|
</div>
|
|
262
213
|
);
|
|
263
214
|
|
|
264
|
-
// =============================================================================
|
|
265
|
-
// Sizes
|
|
266
|
-
// =============================================================================
|
|
267
|
-
|
|
268
215
|
export const Small = () => (
|
|
269
216
|
<IconButton size="sm" aria-label="Search">
|
|
270
217
|
<ArrowRightIcon />
|
|
@@ -272,7 +219,7 @@ export const Small = () => (
|
|
|
272
219
|
);
|
|
273
220
|
|
|
274
221
|
export const Medium = () => (
|
|
275
|
-
<IconButton size="
|
|
222
|
+
<IconButton size="md" aria-label="Search">
|
|
276
223
|
<SearchIcon />
|
|
277
224
|
</IconButton>
|
|
278
225
|
);
|
|
@@ -284,32 +231,28 @@ export const Large = () => (
|
|
|
284
231
|
);
|
|
285
232
|
|
|
286
233
|
export const AllSizes = () => (
|
|
287
|
-
<div className="flex items-center gap-
|
|
234
|
+
<div className="flex items-center gap-16">
|
|
288
235
|
<div className="text-center">
|
|
289
236
|
<IconButton size="sm" aria-label="Small">
|
|
290
237
|
<ArrowRightIcon />
|
|
291
238
|
</IconButton>
|
|
292
|
-
<p className="mt-
|
|
239
|
+
<p className="mt-8 text-12 text-text-muted">sm (28px)</p>
|
|
293
240
|
</div>
|
|
294
241
|
<div className="text-center">
|
|
295
|
-
<IconButton size="
|
|
242
|
+
<IconButton size="md" aria-label="Default">
|
|
296
243
|
<SearchIcon />
|
|
297
244
|
</IconButton>
|
|
298
|
-
<p className="mt-
|
|
245
|
+
<p className="mt-8 text-12 text-text-muted">md (40px)</p>
|
|
299
246
|
</div>
|
|
300
247
|
<div className="text-center">
|
|
301
248
|
<IconButton size="lg" aria-label="Large">
|
|
302
249
|
<SearchIcon />
|
|
303
250
|
</IconButton>
|
|
304
|
-
<p className="mt-
|
|
251
|
+
<p className="mt-8 text-12 text-text-muted">lg (56px)</p>
|
|
305
252
|
</div>
|
|
306
253
|
</div>
|
|
307
254
|
);
|
|
308
255
|
|
|
309
|
-
// =============================================================================
|
|
310
|
-
// States
|
|
311
|
-
// =============================================================================
|
|
312
|
-
|
|
313
256
|
export const Disabled = () => (
|
|
314
257
|
<IconButton disabled aria-label="Search">
|
|
315
258
|
<SearchIcon />
|
|
@@ -3,7 +3,6 @@ import { page, userEvent } from "vitest/browser";
|
|
|
3
3
|
import { render } from "vitest-browser-react";
|
|
4
4
|
import { IconButton } from "./icon-button";
|
|
5
5
|
|
|
6
|
-
// Simple icon for testing
|
|
7
6
|
const TestIcon = () => (
|
|
8
7
|
// biome-ignore lint/a11y/noSvgWithoutTitle: Test component doesn't need accessibility title
|
|
9
8
|
<svg data-testid="test-icon" width="24" height="24" viewBox="0 0 24 24">
|
|
@@ -139,116 +138,49 @@ describe("IconButton", () => {
|
|
|
139
138
|
});
|
|
140
139
|
});
|
|
141
140
|
|
|
142
|
-
describe("Data attributes", () => {
|
|
143
|
-
test("includes data-variant attribute", async () => {
|
|
144
|
-
render(
|
|
145
|
-
<IconButton variant="ghost" aria-label="Ghost variant">
|
|
146
|
-
<TestIcon />
|
|
147
|
-
</IconButton>,
|
|
148
|
-
);
|
|
149
|
-
await expect
|
|
150
|
-
.element(page.getByRole("button", { name: "Ghost variant" }))
|
|
151
|
-
.toHaveAttribute("data-variant", "ghost");
|
|
152
|
-
});
|
|
153
|
-
|
|
154
|
-
test("includes data-size attribute", async () => {
|
|
155
|
-
render(
|
|
156
|
-
<IconButton size="lg" aria-label="Large size">
|
|
157
|
-
<TestIcon />
|
|
158
|
-
</IconButton>,
|
|
159
|
-
);
|
|
160
|
-
await expect
|
|
161
|
-
.element(page.getByRole("button", { name: "Large size" }))
|
|
162
|
-
.toHaveAttribute("data-size", "lg");
|
|
163
|
-
});
|
|
164
|
-
|
|
165
|
-
test("includes data-color-scheme attribute", async () => {
|
|
166
|
-
render(
|
|
167
|
-
<IconButton colorScheme="light" aria-label="Light scheme">
|
|
168
|
-
<TestIcon />
|
|
169
|
-
</IconButton>,
|
|
170
|
-
);
|
|
171
|
-
await expect
|
|
172
|
-
.element(page.getByRole("button", { name: "Light scheme" }))
|
|
173
|
-
.toHaveAttribute("data-color-scheme", "light");
|
|
174
|
-
});
|
|
175
|
-
|
|
176
|
-
test("includes data-rounded attribute", async () => {
|
|
177
|
-
render(
|
|
178
|
-
<IconButton rounded="full" aria-label="Full rounded">
|
|
179
|
-
<TestIcon />
|
|
180
|
-
</IconButton>,
|
|
181
|
-
);
|
|
182
|
-
await expect
|
|
183
|
-
.element(page.getByRole("button", { name: "Full rounded" }))
|
|
184
|
-
.toHaveAttribute("data-rounded", "full");
|
|
185
|
-
});
|
|
186
|
-
|
|
187
|
-
test("has default data attributes when not specified", async () => {
|
|
188
|
-
render(
|
|
189
|
-
<IconButton aria-label="Defaults">
|
|
190
|
-
<TestIcon />
|
|
191
|
-
</IconButton>,
|
|
192
|
-
);
|
|
193
|
-
const button = page.getByRole("button", { name: "Defaults" });
|
|
194
|
-
await expect.element(button).toHaveAttribute("data-variant", "solid");
|
|
195
|
-
await expect.element(button).toHaveAttribute("data-size", "default");
|
|
196
|
-
await expect.element(button).toHaveAttribute("data-color-scheme", "dark");
|
|
197
|
-
await expect.element(button).toHaveAttribute("data-rounded", "default");
|
|
198
|
-
});
|
|
199
|
-
});
|
|
200
|
-
|
|
201
141
|
describe("Variants", () => {
|
|
202
|
-
test("
|
|
142
|
+
test("primary variant has visible background color", async () => {
|
|
203
143
|
render(
|
|
204
144
|
<IconButton aria-label="Default">
|
|
205
145
|
<TestIcon />
|
|
206
146
|
</IconButton>,
|
|
207
147
|
);
|
|
208
148
|
const button = page.getByRole("button", { name: "Default" });
|
|
209
|
-
await expect.element(button).
|
|
210
|
-
});
|
|
149
|
+
await expect.element(button).toBeInTheDocument();
|
|
211
150
|
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
</IconButton>,
|
|
217
|
-
);
|
|
218
|
-
const button = page.getByRole("button", { name: "Ghost" });
|
|
219
|
-
await expect.element(button).toHaveClass(/text-gray-700/);
|
|
151
|
+
const element = button.element();
|
|
152
|
+
const bgColor = window.getComputedStyle(element).backgroundColor;
|
|
153
|
+
expect(bgColor).not.toBe("rgba(0, 0, 0, 0)");
|
|
154
|
+
expect(bgColor).not.toBe("transparent");
|
|
220
155
|
});
|
|
221
156
|
});
|
|
222
157
|
|
|
223
158
|
describe("Sizes", () => {
|
|
224
|
-
test("
|
|
159
|
+
test("different sizes have different dimensions", async () => {
|
|
225
160
|
render(
|
|
226
|
-
|
|
227
|
-
<
|
|
228
|
-
|
|
161
|
+
<>
|
|
162
|
+
<IconButton size="sm" aria-label="Small">
|
|
163
|
+
<TestIcon />
|
|
164
|
+
</IconButton>
|
|
165
|
+
<IconButton size="lg" aria-label="Large">
|
|
166
|
+
<TestIcon />
|
|
167
|
+
</IconButton>
|
|
168
|
+
</>,
|
|
229
169
|
);
|
|
230
|
-
const button = page.getByRole("button", { name: "Small" });
|
|
231
|
-
await expect.element(button).toHaveClass(/size-32/);
|
|
232
|
-
});
|
|
233
170
|
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
</IconButton>,
|
|
239
|
-
);
|
|
240
|
-
const button = page.getByRole("button", { name: "Default" });
|
|
241
|
-
await expect.element(button).toHaveClass(/size-40/);
|
|
242
|
-
});
|
|
171
|
+
const smallBtn = page.getByRole("button", { name: "Small" });
|
|
172
|
+
const largeBtn = page.getByRole("button", { name: "Large" });
|
|
173
|
+
await expect.element(smallBtn).toBeInTheDocument();
|
|
174
|
+
await expect.element(largeBtn).toBeInTheDocument();
|
|
243
175
|
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
176
|
+
const smallWidth = Number.parseFloat(
|
|
177
|
+
window.getComputedStyle(smallBtn.element()).width,
|
|
178
|
+
);
|
|
179
|
+
const largeWidth = Number.parseFloat(
|
|
180
|
+
window.getComputedStyle(largeBtn.element()).width,
|
|
249
181
|
);
|
|
250
|
-
|
|
251
|
-
|
|
182
|
+
|
|
183
|
+
expect(largeWidth).toBeGreaterThan(smallWidth);
|
|
252
184
|
});
|
|
253
185
|
});
|
|
254
186
|
});
|
|
@@ -61,9 +61,9 @@ const iconButtonVariants = tv({
|
|
|
61
61
|
"bg-button-ghost-inverse-bg text-button-ghost-inverse-text hover:bg-button-ghost-inverse-bg-hover hover:text-button-ghost-inverse-text-hover border-transparent focus-visible:ring-gray-50 focus-visible:ring-offset-gray-1000",
|
|
62
62
|
},
|
|
63
63
|
size: {
|
|
64
|
-
sm: "size-28 rounded-
|
|
65
|
-
md: "size-40 rounded-
|
|
66
|
-
lg: "size-56 rounded-
|
|
64
|
+
sm: "size-28 rounded-surface-button-small",
|
|
65
|
+
md: "size-40 rounded-surface-button-medium",
|
|
66
|
+
lg: "size-56 rounded-surface-button-large",
|
|
67
67
|
},
|
|
68
68
|
rounded: {
|
|
69
69
|
default: "",
|
|
@@ -279,7 +279,7 @@ export const ChatInput = () => (
|
|
|
279
279
|
<InputGroupText>52% used</InputGroupText>
|
|
280
280
|
<span className="ml-auto h-16 w-px bg-ui-color-border" />
|
|
281
281
|
<InputGroupButton
|
|
282
|
-
variant="
|
|
282
|
+
variant="primary"
|
|
283
283
|
className="rounded-full"
|
|
284
284
|
size="icon-sm"
|
|
285
285
|
aria-label="Send"
|
|
@@ -343,7 +343,7 @@ export const PillInput = () => (
|
|
|
343
343
|
<InputGroup className="max-w-sm rounded-full">
|
|
344
344
|
<InputGroupAddon>
|
|
345
345
|
<InputGroupButton
|
|
346
|
-
variant="outline"
|
|
346
|
+
variant="primary-outline"
|
|
347
347
|
size="icon-xs"
|
|
348
348
|
className="rounded-full"
|
|
349
349
|
>
|
|
@@ -474,7 +474,7 @@ export const TextareaWithActions = () => (
|
|
|
474
474
|
className="border-t border-ui-color-border pt-8"
|
|
475
475
|
>
|
|
476
476
|
<InputGroupText>Line 1, Column 1</InputGroupText>
|
|
477
|
-
<InputGroupButton className="ml-auto" size="sm" variant="
|
|
477
|
+
<InputGroupButton className="ml-auto" size="sm" variant="primary">
|
|
478
478
|
Run <SendIcon />
|
|
479
479
|
</InputGroupButton>
|
|
480
480
|
</InputGroupAddon>
|
|
@@ -552,11 +552,7 @@ export const WithLabel = () => (
|
|
|
552
552
|
</InputGroupAddon>
|
|
553
553
|
</InputGroup>
|
|
554
554
|
<InputGroup>
|
|
555
|
-
<InputGroupInput
|
|
556
|
-
id="email-2"
|
|
557
|
-
placeholder="shadcn@vercel.com"
|
|
558
|
-
className="!pl-12"
|
|
559
|
-
/>
|
|
555
|
+
<InputGroupInput id="email-2" placeholder="shadcn@vercel.com" />
|
|
560
556
|
<InputGroupAddon align="block-start">
|
|
561
557
|
<label
|
|
562
558
|
htmlFor="email-2"
|
|
@@ -151,34 +151,34 @@ describe("InputGroup", () => {
|
|
|
151
151
|
});
|
|
152
152
|
|
|
153
153
|
describe("Variants", () => {
|
|
154
|
-
test("
|
|
154
|
+
test("renders with default size", async () => {
|
|
155
155
|
render(
|
|
156
156
|
<InputGroup>
|
|
157
157
|
<InputGroupInput placeholder="Default" />
|
|
158
158
|
</InputGroup>,
|
|
159
159
|
);
|
|
160
160
|
const group = page.getByRole("group");
|
|
161
|
-
await expect.element(group).
|
|
161
|
+
await expect.element(group).toBeInTheDocument();
|
|
162
162
|
});
|
|
163
163
|
|
|
164
|
-
test("
|
|
164
|
+
test("renders with small size", async () => {
|
|
165
165
|
render(
|
|
166
166
|
<InputGroup size="sm">
|
|
167
167
|
<InputGroupInput placeholder="Small" />
|
|
168
168
|
</InputGroup>,
|
|
169
169
|
);
|
|
170
170
|
const group = page.getByRole("group");
|
|
171
|
-
await expect.element(group).
|
|
171
|
+
await expect.element(group).toBeInTheDocument();
|
|
172
172
|
});
|
|
173
173
|
|
|
174
|
-
test("
|
|
174
|
+
test("renders with large size", async () => {
|
|
175
175
|
render(
|
|
176
176
|
<InputGroup size="lg">
|
|
177
177
|
<InputGroupInput placeholder="Large" />
|
|
178
178
|
</InputGroup>,
|
|
179
179
|
);
|
|
180
180
|
const group = page.getByRole("group");
|
|
181
|
-
await expect.element(group).
|
|
181
|
+
await expect.element(group).toBeInTheDocument();
|
|
182
182
|
});
|
|
183
183
|
|
|
184
184
|
test("applies disabled data attribute", async () => {
|
|
@@ -191,29 +191,19 @@ describe("InputGroup", () => {
|
|
|
191
191
|
await expect.element(group).toHaveAttribute("data-disabled", "true");
|
|
192
192
|
});
|
|
193
193
|
|
|
194
|
-
test("
|
|
194
|
+
test("has expected data-slot attribute", async () => {
|
|
195
195
|
render(
|
|
196
196
|
<InputGroup>
|
|
197
197
|
<InputGroupInput placeholder="Default" />
|
|
198
198
|
</InputGroup>,
|
|
199
199
|
);
|
|
200
200
|
const group = page.getByRole("group").first();
|
|
201
|
-
await expect.element(group).
|
|
202
|
-
});
|
|
203
|
-
|
|
204
|
-
test("applies semantic token classes for border", async () => {
|
|
205
|
-
render(
|
|
206
|
-
<InputGroup>
|
|
207
|
-
<InputGroupInput placeholder="Default" />
|
|
208
|
-
</InputGroup>,
|
|
209
|
-
);
|
|
210
|
-
const group = page.getByRole("group").first();
|
|
211
|
-
await expect.element(group).toHaveClass(/border-ui-color-border/);
|
|
201
|
+
await expect.element(group).toHaveAttribute("data-slot", "input-group");
|
|
212
202
|
});
|
|
213
203
|
});
|
|
214
204
|
|
|
215
205
|
describe("Addon Positioning", () => {
|
|
216
|
-
test("inline-start addon
|
|
206
|
+
test("inline-start addon has correct data-align", async () => {
|
|
217
207
|
render(
|
|
218
208
|
<InputGroup>
|
|
219
209
|
<InputGroupAddon data-testid="start-addon">
|
|
@@ -224,10 +214,9 @@ describe("InputGroup", () => {
|
|
|
224
214
|
);
|
|
225
215
|
const addon = page.getByTestId("start-addon");
|
|
226
216
|
await expect.element(addon).toHaveAttribute("data-align", "inline-start");
|
|
227
|
-
await expect.element(addon).toHaveClass(/order-first/);
|
|
228
217
|
});
|
|
229
218
|
|
|
230
|
-
test("inline-end addon
|
|
219
|
+
test("inline-end addon has correct data-align", async () => {
|
|
231
220
|
render(
|
|
232
221
|
<InputGroup>
|
|
233
222
|
<InputGroupInput placeholder="Input" />
|
|
@@ -238,10 +227,9 @@ describe("InputGroup", () => {
|
|
|
238
227
|
);
|
|
239
228
|
const addon = page.getByTestId("end-addon");
|
|
240
229
|
await expect.element(addon).toHaveAttribute("data-align", "inline-end");
|
|
241
|
-
await expect.element(addon).toHaveClass(/order-last/);
|
|
242
230
|
});
|
|
243
231
|
|
|
244
|
-
test("block-start addon
|
|
232
|
+
test("block-start addon has correct data-align", async () => {
|
|
245
233
|
render(
|
|
246
234
|
<InputGroup>
|
|
247
235
|
<InputGroupAddon align="block-start" data-testid="block-start-addon">
|
|
@@ -252,10 +240,9 @@ describe("InputGroup", () => {
|
|
|
252
240
|
);
|
|
253
241
|
const addon = page.getByTestId("block-start-addon");
|
|
254
242
|
await expect.element(addon).toHaveAttribute("data-align", "block-start");
|
|
255
|
-
await expect.element(addon).toHaveClass(/w-full/);
|
|
256
243
|
});
|
|
257
244
|
|
|
258
|
-
test("block-end addon
|
|
245
|
+
test("block-end addon has correct data-align", async () => {
|
|
259
246
|
render(
|
|
260
247
|
<InputGroup>
|
|
261
248
|
<InputGroupInput placeholder="Input" />
|
|
@@ -266,7 +253,6 @@ describe("InputGroup", () => {
|
|
|
266
253
|
);
|
|
267
254
|
const addon = page.getByTestId("block-end-addon");
|
|
268
255
|
await expect.element(addon).toHaveAttribute("data-align", "block-end");
|
|
269
|
-
await expect.element(addon).toHaveClass(/w-full/);
|
|
270
256
|
});
|
|
271
257
|
});
|
|
272
258
|
|
|
@@ -327,7 +313,7 @@ describe("InputGroup", () => {
|
|
|
327
313
|
await expect.element(page.getByText("https://")).toBeInTheDocument();
|
|
328
314
|
});
|
|
329
315
|
|
|
330
|
-
test("
|
|
316
|
+
test("renders text element", async () => {
|
|
331
317
|
render(
|
|
332
318
|
<InputGroup>
|
|
333
319
|
<InputGroupAddon>
|
|
@@ -337,7 +323,7 @@ describe("InputGroup", () => {
|
|
|
337
323
|
</InputGroup>,
|
|
338
324
|
);
|
|
339
325
|
const text = page.getByTestId("text");
|
|
340
|
-
await expect.element(text).
|
|
326
|
+
await expect.element(text).toBeInTheDocument();
|
|
341
327
|
});
|
|
342
328
|
});
|
|
343
329
|
|