@nationaldesignstudio/react 0.5.2 → 0.5.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.
- package/package.json +10 -2
- package/src/App.css +0 -0
- package/src/App.tsx +0 -7
- package/src/assets/fonts/PPNeueMontreal-Variable.woff2 +0 -0
- package/src/assets/react.svg +0 -1
- package/src/components/atoms/accordion/accordion.stories.tsx +0 -228
- package/src/components/atoms/accordion/accordion.test.tsx +0 -231
- package/src/components/atoms/accordion/index.ts +0 -6
- package/src/components/atoms/background/background.test.tsx +0 -213
- package/src/components/atoms/background/index.ts +0 -22
- package/src/components/atoms/button/__screenshots__/button.visual.test.tsx/button-charcoal-chromium-darwin.png +0 -0
- package/src/components/atoms/button/__screenshots__/button.visual.test.tsx/button-charcoal-chromium-linux.png +0 -0
- package/src/components/atoms/button/__screenshots__/button.visual.test.tsx/button-charcoal-outline-chromium-darwin.png +0 -0
- package/src/components/atoms/button/__screenshots__/button.visual.test.tsx/button-charcoal-outline-chromium-linux.png +0 -0
- package/src/components/atoms/button/__screenshots__/button.visual.test.tsx/button-charcoal-outline-quiet-chromium-darwin.png +0 -0
- package/src/components/atoms/button/__screenshots__/button.visual.test.tsx/button-charcoal-outline-quiet-chromium-linux.png +0 -0
- package/src/components/atoms/button/__screenshots__/button.visual.test.tsx/button-disabled-chromium-darwin.png +0 -0
- package/src/components/atoms/button/__screenshots__/button.visual.test.tsx/button-disabled-chromium-linux.png +0 -0
- package/src/components/atoms/button/__screenshots__/button.visual.test.tsx/button-ivory-chromium-darwin.png +0 -0
- package/src/components/atoms/button/__screenshots__/button.visual.test.tsx/button-ivory-chromium-linux.png +0 -0
- package/src/components/atoms/button/__screenshots__/button.visual.test.tsx/button-ivory-outline-chromium-darwin.png +0 -0
- package/src/components/atoms/button/__screenshots__/button.visual.test.tsx/button-ivory-outline-chromium-linux.png +0 -0
- package/src/components/atoms/button/__screenshots__/button.visual.test.tsx/button-ivory-outline-quiet-chromium-darwin.png +0 -0
- package/src/components/atoms/button/__screenshots__/button.visual.test.tsx/button-ivory-outline-quiet-chromium-linux.png +0 -0
- package/src/components/atoms/button/__screenshots__/button.visual.test.tsx/button-size-large-chromium-darwin.png +0 -0
- package/src/components/atoms/button/__screenshots__/button.visual.test.tsx/button-size-large-chromium-linux.png +0 -0
- package/src/components/atoms/button/__screenshots__/button.visual.test.tsx/button-size-medium-chromium-darwin.png +0 -0
- package/src/components/atoms/button/__screenshots__/button.visual.test.tsx/button-size-medium-chromium-linux.png +0 -0
- package/src/components/atoms/button/__screenshots__/button.visual.test.tsx/button-size-small-chromium-darwin.png +0 -0
- package/src/components/atoms/button/__screenshots__/button.visual.test.tsx/button-size-small-chromium-linux.png +0 -0
- package/src/components/atoms/button/button.stories.tsx +0 -289
- package/src/components/atoms/button/button.test.tsx +0 -419
- package/src/components/atoms/button/button.visual.test.tsx +0 -98
- package/src/components/atoms/button/icon-button.stories.tsx +0 -260
- package/src/components/atoms/button/icon-button.test.tsx +0 -186
- package/src/components/atoms/button/index.ts +0 -6
- package/src/components/atoms/input/index.ts +0 -17
- package/src/components/atoms/input/input-group.stories.tsx +0 -646
- package/src/components/atoms/input/input-group.test.tsx +0 -362
- package/src/components/atoms/input/input.stories.tsx +0 -228
- package/src/components/atoms/input/input.test.tsx +0 -167
- package/src/components/atoms/ndstudio-footer/index.ts +0 -1
- package/src/components/atoms/pager-control/index.ts +0 -5
- package/src/components/atoms/pager-control/pager-control.stories.tsx +0 -207
- package/src/components/atoms/pager-control/pager-control.test.tsx +0 -130
- package/src/components/atoms/popover/index.ts +0 -30
- package/src/components/atoms/popover/popover.stories.tsx +0 -531
- package/src/components/atoms/popover/popover.test.tsx +0 -486
- package/src/components/atoms/select/index.ts +0 -18
- package/src/components/atoms/select/select.stories.tsx +0 -455
- package/src/components/atoms/tooltip/index.ts +0 -24
- package/src/components/atoms/tooltip/tooltip.stories.tsx +0 -348
- package/src/components/atoms/tooltip/tooltip.test.tsx +0 -363
- package/src/components/dev-tools/dev-toolbar/dev-toolbar.stories.tsx +0 -73
- package/src/components/dev-tools/dev-toolbar/index.ts +0 -1
- package/src/components/dev-tools/grid-overlay/index.ts +0 -1
- package/src/components/dev-tools/index.ts +0 -2
- package/src/components/foundation/typography/typography.stories.tsx +0 -401
- package/src/components/organisms/card/__screenshots__/card.visual.test.tsx/card-default-vertical-chromium-darwin.png +0 -0
- package/src/components/organisms/card/__screenshots__/card.visual.test.tsx/card-default-vertical-chromium-linux.png +0 -0
- package/src/components/organisms/card/__screenshots__/card.visual.test.tsx/card-horizontal-chromium-darwin.png +0 -0
- package/src/components/organisms/card/__screenshots__/card.visual.test.tsx/card-horizontal-chromium-linux.png +0 -0
- package/src/components/organisms/card/__screenshots__/card.visual.test.tsx/card-minimal-chromium-darwin.png +0 -0
- package/src/components/organisms/card/__screenshots__/card.visual.test.tsx/card-minimal-chromium-linux.png +0 -0
- package/src/components/organisms/card/__screenshots__/card.visual.test.tsx/card-without-actions-chromium-darwin.png +0 -0
- package/src/components/organisms/card/__screenshots__/card.visual.test.tsx/card-without-actions-chromium-linux.png +0 -0
- package/src/components/organisms/card/__screenshots__/card.visual.test.tsx/card-without-eyebrow-chromium-darwin.png +0 -0
- package/src/components/organisms/card/__screenshots__/card.visual.test.tsx/card-without-eyebrow-chromium-linux.png +0 -0
- package/src/components/organisms/card/__screenshots__/card.visual.test.tsx/card-without-image-chromium-darwin.png +0 -0
- package/src/components/organisms/card/__screenshots__/card.visual.test.tsx/card-without-image-chromium-linux.png +0 -0
- package/src/components/organisms/card/card.stories.tsx +0 -293
- package/src/components/organisms/card/card.test.tsx +0 -247
- package/src/components/organisms/card/card.visual.test.tsx +0 -197
- package/src/components/organisms/card/index.ts +0 -26
- package/src/components/organisms/navbar/__screenshots__/navbar.visual.test.tsx/navbar-active-link-chromium-darwin.png +0 -0
- package/src/components/organisms/navbar/__screenshots__/navbar.visual.test.tsx/navbar-active-link-chromium-linux.png +0 -0
- package/src/components/organisms/navbar/__screenshots__/navbar.visual.test.tsx/navbar-brand-only-chromium-darwin.png +0 -0
- package/src/components/organisms/navbar/__screenshots__/navbar.visual.test.tsx/navbar-brand-only-chromium-linux.png +0 -0
- package/src/components/organisms/navbar/__screenshots__/navbar.visual.test.tsx/navbar-default-chromium-darwin.png +0 -0
- package/src/components/organisms/navbar/__screenshots__/navbar.visual.test.tsx/navbar-default-chromium-linux.png +0 -0
- package/src/components/organisms/navbar/index.ts +0 -18
- package/src/components/organisms/navbar/navbar.stories.tsx +0 -313
- package/src/components/organisms/navbar/navbar.test.tsx +0 -190
- package/src/components/organisms/navbar/navbar.visual.test.tsx +0 -85
- package/src/components/organisms/us-gov-banner/__screenshots__/us-gov-banner.visual.test.tsx/us-gov-banner-custom-icon-chromium-darwin.png +0 -0
- package/src/components/organisms/us-gov-banner/__screenshots__/us-gov-banner.visual.test.tsx/us-gov-banner-custom-icon-chromium-linux.png +0 -0
- package/src/components/organisms/us-gov-banner/__screenshots__/us-gov-banner.visual.test.tsx/us-gov-banner-custom-text-chromium-darwin.png +0 -0
- package/src/components/organisms/us-gov-banner/__screenshots__/us-gov-banner.visual.test.tsx/us-gov-banner-custom-text-chromium-linux.png +0 -0
- package/src/components/organisms/us-gov-banner/__screenshots__/us-gov-banner.visual.test.tsx/us-gov-banner-default-chromium-darwin.png +0 -0
- package/src/components/organisms/us-gov-banner/__screenshots__/us-gov-banner.visual.test.tsx/us-gov-banner-default-chromium-linux.png +0 -0
- package/src/components/organisms/us-gov-banner/index.ts +0 -5
- package/src/components/organisms/us-gov-banner/us-gov-banner.stories.tsx +0 -35
- package/src/components/organisms/us-gov-banner/us-gov-banner.test.tsx +0 -107
- package/src/components/organisms/us-gov-banner/us-gov-banner.visual.test.tsx +0 -46
- package/src/components/sections/banner/banner.stories.tsx +0 -150
- package/src/components/sections/banner/banner.test.tsx +0 -185
- package/src/components/sections/banner/index.ts +0 -2
- package/src/components/sections/card-grid/card-grid.stories.tsx +0 -351
- package/src/components/sections/card-grid/index.ts +0 -1
- package/src/components/sections/faq-section/faq-section.stories.tsx +0 -453
- package/src/components/sections/faq-section/index.ts +0 -2
- package/src/components/sections/hero/__screenshots__/hero.visual.test.tsx/hero-a1-desktop-chromium-darwin.png +0 -0
- package/src/components/sections/hero/__screenshots__/hero.visual.test.tsx/hero-a1-desktop-chromium-linux.png +0 -0
- package/src/components/sections/hero/__screenshots__/hero.visual.test.tsx/hero-a1-mobile-chromium-darwin.png +0 -0
- package/src/components/sections/hero/__screenshots__/hero.visual.test.tsx/hero-a1-mobile-chromium-linux.png +0 -0
- package/src/components/sections/hero/__screenshots__/hero.visual.test.tsx/hero-a1-tablet-chromium-darwin.png +0 -0
- package/src/components/sections/hero/__screenshots__/hero.visual.test.tsx/hero-a1-tablet-chromium-linux.png +0 -0
- package/src/components/sections/hero/__screenshots__/hero.visual.test.tsx/hero-a2-desktop-chromium-darwin.png +0 -0
- package/src/components/sections/hero/__screenshots__/hero.visual.test.tsx/hero-a2-desktop-chromium-linux.png +0 -0
- package/src/components/sections/hero/__screenshots__/hero.visual.test.tsx/hero-a2-mobile-chromium-darwin.png +0 -0
- package/src/components/sections/hero/__screenshots__/hero.visual.test.tsx/hero-a2-mobile-chromium-linux.png +0 -0
- package/src/components/sections/hero/__screenshots__/hero.visual.test.tsx/hero-a2-tablet-chromium-darwin.png +0 -0
- package/src/components/sections/hero/__screenshots__/hero.visual.test.tsx/hero-a2-tablet-chromium-linux.png +0 -0
- package/src/components/sections/hero/__screenshots__/hero.visual.test.tsx/hero-a3-desktop-chromium-darwin.png +0 -0
- package/src/components/sections/hero/__screenshots__/hero.visual.test.tsx/hero-a3-desktop-chromium-linux.png +0 -0
- package/src/components/sections/hero/__screenshots__/hero.visual.test.tsx/hero-a3-mobile-chromium-darwin.png +0 -0
- package/src/components/sections/hero/__screenshots__/hero.visual.test.tsx/hero-a3-mobile-chromium-linux.png +0 -0
- package/src/components/sections/hero/__screenshots__/hero.visual.test.tsx/hero-a3-tablet-chromium-darwin.png +0 -0
- package/src/components/sections/hero/__screenshots__/hero.visual.test.tsx/hero-a3-tablet-chromium-linux.png +0 -0
- package/src/components/sections/hero/__screenshots__/hero.visual.test.tsx/hero-custom-class-chromium-darwin.png +0 -0
- package/src/components/sections/hero/__screenshots__/hero.visual.test.tsx/hero-custom-class-chromium-linux.png +0 -0
- package/src/components/sections/hero/__screenshots__/hero.visual.test.tsx/hero-default-chromium-linux.png +0 -0
- package/src/components/sections/hero/__screenshots__/hero.visual.test.tsx/hero-long-title-chromium-darwin.png +0 -0
- package/src/components/sections/hero/__screenshots__/hero.visual.test.tsx/hero-long-title-chromium-linux.png +0 -0
- package/src/components/sections/hero/hero.stories.tsx +0 -397
- package/src/components/sections/hero/hero.test.tsx +0 -138
- package/src/components/sections/hero/hero.visual.test.tsx +0 -140
- package/src/components/sections/hero/index.ts +0 -23
- package/src/components/sections/prose/__screenshots__/prose.visual.test.tsx/prose-h3-heading-chromium-darwin.png +0 -0
- package/src/components/sections/prose/__screenshots__/prose.visual.test.tsx/prose-h3-heading-chromium-linux.png +0 -0
- package/src/components/sections/prose/__screenshots__/prose.visual.test.tsx/prose-multiple-paragraphs-chromium-darwin.png +0 -0
- package/src/components/sections/prose/__screenshots__/prose.visual.test.tsx/prose-multiple-paragraphs-chromium-linux.png +0 -0
- package/src/components/sections/prose/__screenshots__/prose.visual.test.tsx/prose-multiple-sections-chromium-darwin.png +0 -0
- package/src/components/sections/prose/__screenshots__/prose.visual.test.tsx/prose-multiple-sections-chromium-linux.png +0 -0
- package/src/components/sections/prose/__screenshots__/prose.visual.test.tsx/prose-single-section-chromium-darwin.png +0 -0
- package/src/components/sections/prose/__screenshots__/prose.visual.test.tsx/prose-single-section-chromium-linux.png +0 -0
- package/src/components/sections/prose/index.ts +0 -6
- package/src/components/sections/prose/prose.stories.tsx +0 -144
- package/src/components/sections/prose/prose.test.tsx +0 -178
- package/src/components/sections/prose/prose.visual.test.tsx +0 -105
- package/src/components/sections/quote-block/index.ts +0 -5
- package/src/components/sections/river/index.ts +0 -1
- package/src/components/sections/river/river.stories.tsx +0 -237
- package/src/components/sections/river/river.test.tsx +0 -268
- package/src/components/sections/tout/index.ts +0 -1
- package/src/components/sections/tout/tout.stories.tsx +0 -171
- package/src/components/sections/tout/tout.test.tsx +0 -242
- package/src/components/sections/two-column-section/index.ts +0 -5
- package/src/components/sections/two-column-section/two-column-section.stories.tsx +0 -285
- package/src/components/shared/index.ts +0 -5
- package/src/index.ts +0 -293
- package/src/main.tsx +0 -13
- package/src/stories/grid-system.stories.tsx +0 -309
- package/src/stories/introduction.mdx +0 -128
- package/src/stories/theme-provider.stories.tsx +0 -349
- package/src/stories/token-showcase.stories.tsx +0 -73
- package/src/stories/token-showcase.tsx +0 -777
- package/src/styles.css +0 -14
- package/src/tests/token-resolution.test.tsx +0 -298
- package/src/theme/theme-provider.test.tsx +0 -270
|
@@ -1,268 +0,0 @@
|
|
|
1
|
-
import { describe, expect, test } from "vitest";
|
|
2
|
-
import { page } from "vitest/browser";
|
|
3
|
-
import { render } from "vitest-browser-react";
|
|
4
|
-
import { River } from "./river";
|
|
5
|
-
|
|
6
|
-
const PlaceholderMedia = () => <div data-testid="media">Media</div>;
|
|
7
|
-
|
|
8
|
-
describe("River", () => {
|
|
9
|
-
describe("Accessibility", () => {
|
|
10
|
-
test("renders as section landmark", async () => {
|
|
11
|
-
render(
|
|
12
|
-
<River
|
|
13
|
-
headline="Test Headline"
|
|
14
|
-
body="Test body"
|
|
15
|
-
primaryAction={<button type="button">Action</button>}
|
|
16
|
-
media={<PlaceholderMedia />}
|
|
17
|
-
data-testid="river"
|
|
18
|
-
/>,
|
|
19
|
-
);
|
|
20
|
-
|
|
21
|
-
const river = page.getByTestId("river");
|
|
22
|
-
await expect.element(river).toBeInTheDocument();
|
|
23
|
-
});
|
|
24
|
-
|
|
25
|
-
test("headline renders as h2", async () => {
|
|
26
|
-
render(
|
|
27
|
-
<River
|
|
28
|
-
headline="River Headline"
|
|
29
|
-
body="Test body"
|
|
30
|
-
primaryAction={<button type="button">Action</button>}
|
|
31
|
-
media={<PlaceholderMedia />}
|
|
32
|
-
/>,
|
|
33
|
-
);
|
|
34
|
-
|
|
35
|
-
await expect
|
|
36
|
-
.element(
|
|
37
|
-
page.getByRole("heading", { level: 2, name: "River Headline" }),
|
|
38
|
-
)
|
|
39
|
-
.toBeInTheDocument();
|
|
40
|
-
});
|
|
41
|
-
|
|
42
|
-
test("body text is accessible", async () => {
|
|
43
|
-
render(
|
|
44
|
-
<River
|
|
45
|
-
headline="Test"
|
|
46
|
-
body="Accessible body text"
|
|
47
|
-
primaryAction={<button type="button">Action</button>}
|
|
48
|
-
media={<PlaceholderMedia />}
|
|
49
|
-
/>,
|
|
50
|
-
);
|
|
51
|
-
|
|
52
|
-
await expect
|
|
53
|
-
.element(page.getByText("Accessible body text"))
|
|
54
|
-
.toBeInTheDocument();
|
|
55
|
-
});
|
|
56
|
-
});
|
|
57
|
-
|
|
58
|
-
describe("Props", () => {
|
|
59
|
-
test("renders with required props", async () => {
|
|
60
|
-
render(
|
|
61
|
-
<River
|
|
62
|
-
headline="Required Headline"
|
|
63
|
-
body="Required body"
|
|
64
|
-
primaryAction={<button type="button">Primary</button>}
|
|
65
|
-
media={<PlaceholderMedia />}
|
|
66
|
-
/>,
|
|
67
|
-
);
|
|
68
|
-
|
|
69
|
-
await expect
|
|
70
|
-
.element(page.getByText("Required Headline"))
|
|
71
|
-
.toBeInTheDocument();
|
|
72
|
-
await expect.element(page.getByText("Required body")).toBeInTheDocument();
|
|
73
|
-
await expect
|
|
74
|
-
.element(page.getByRole("button", { name: "Primary" }))
|
|
75
|
-
.toBeInTheDocument();
|
|
76
|
-
await expect.element(page.getByTestId("media")).toBeInTheDocument();
|
|
77
|
-
});
|
|
78
|
-
|
|
79
|
-
test("renders secondary action when provided", async () => {
|
|
80
|
-
render(
|
|
81
|
-
<River
|
|
82
|
-
headline="Test"
|
|
83
|
-
body="Test"
|
|
84
|
-
primaryAction={<button type="button">Primary</button>}
|
|
85
|
-
secondaryAction={<button type="button">Secondary</button>}
|
|
86
|
-
media={<PlaceholderMedia />}
|
|
87
|
-
/>,
|
|
88
|
-
);
|
|
89
|
-
|
|
90
|
-
await expect
|
|
91
|
-
.element(page.getByRole("button", { name: "Primary" }))
|
|
92
|
-
.toBeInTheDocument();
|
|
93
|
-
await expect
|
|
94
|
-
.element(page.getByRole("button", { name: "Secondary" }))
|
|
95
|
-
.toBeInTheDocument();
|
|
96
|
-
});
|
|
97
|
-
|
|
98
|
-
test("does not render secondary action when not provided", async () => {
|
|
99
|
-
render(
|
|
100
|
-
<River
|
|
101
|
-
headline="Test"
|
|
102
|
-
body="Test"
|
|
103
|
-
primaryAction={<button type="button">Primary</button>}
|
|
104
|
-
media={<PlaceholderMedia />}
|
|
105
|
-
/>,
|
|
106
|
-
);
|
|
107
|
-
|
|
108
|
-
await expect
|
|
109
|
-
.element(page.getByRole("button", { name: "Primary" }))
|
|
110
|
-
.toBeInTheDocument();
|
|
111
|
-
// Should only have one button
|
|
112
|
-
const buttons = page.getByRole("button");
|
|
113
|
-
await expect.element(buttons).toBeInTheDocument();
|
|
114
|
-
});
|
|
115
|
-
|
|
116
|
-
test("supports custom className", async () => {
|
|
117
|
-
render(
|
|
118
|
-
<River
|
|
119
|
-
headline="Test"
|
|
120
|
-
body="Test"
|
|
121
|
-
primaryAction={<button type="button">Action</button>}
|
|
122
|
-
media={<PlaceholderMedia />}
|
|
123
|
-
className="custom-class"
|
|
124
|
-
data-testid="river"
|
|
125
|
-
/>,
|
|
126
|
-
);
|
|
127
|
-
|
|
128
|
-
const river = page.getByTestId("river");
|
|
129
|
-
await expect.element(river).toHaveClass(/custom-class/);
|
|
130
|
-
});
|
|
131
|
-
|
|
132
|
-
test("spreads additional props to section element", async () => {
|
|
133
|
-
render(
|
|
134
|
-
<River
|
|
135
|
-
headline="Test"
|
|
136
|
-
body="Test"
|
|
137
|
-
primaryAction={<button type="button">Action</button>}
|
|
138
|
-
media={<PlaceholderMedia />}
|
|
139
|
-
data-testid="river"
|
|
140
|
-
aria-label="River section"
|
|
141
|
-
/>,
|
|
142
|
-
);
|
|
143
|
-
|
|
144
|
-
const river = page.getByTestId("river");
|
|
145
|
-
await expect
|
|
146
|
-
.element(river)
|
|
147
|
-
.toHaveAttribute("aria-label", "River section");
|
|
148
|
-
});
|
|
149
|
-
});
|
|
150
|
-
|
|
151
|
-
describe("Styling", () => {
|
|
152
|
-
test("applies col-full for grid alignment", async () => {
|
|
153
|
-
render(
|
|
154
|
-
<River
|
|
155
|
-
headline="Test"
|
|
156
|
-
body="Test"
|
|
157
|
-
primaryAction={<button type="button">Action</button>}
|
|
158
|
-
media={<PlaceholderMedia />}
|
|
159
|
-
data-testid="river"
|
|
160
|
-
/>,
|
|
161
|
-
);
|
|
162
|
-
|
|
163
|
-
const river = page.getByTestId("river");
|
|
164
|
-
await expect.element(river).toHaveClass(/col-full/);
|
|
165
|
-
});
|
|
166
|
-
|
|
167
|
-
test("applies responsive padding classes", async () => {
|
|
168
|
-
render(
|
|
169
|
-
<River
|
|
170
|
-
headline="Test"
|
|
171
|
-
body="Test"
|
|
172
|
-
primaryAction={<button type="button">Action</button>}
|
|
173
|
-
media={<PlaceholderMedia />}
|
|
174
|
-
data-testid="river"
|
|
175
|
-
/>,
|
|
176
|
-
);
|
|
177
|
-
|
|
178
|
-
const river = page.getByTestId("river");
|
|
179
|
-
// Mobile padding
|
|
180
|
-
await expect.element(river).toHaveClass(/px-20/);
|
|
181
|
-
await expect.element(river).toHaveClass(/pt-72/);
|
|
182
|
-
await expect.element(river).toHaveClass(/pb-20/);
|
|
183
|
-
});
|
|
184
|
-
});
|
|
185
|
-
|
|
186
|
-
describe("Variants", () => {
|
|
187
|
-
test("variant A is default", async () => {
|
|
188
|
-
render(
|
|
189
|
-
<River
|
|
190
|
-
headline="Test"
|
|
191
|
-
body="Test"
|
|
192
|
-
primaryAction={<button type="button">Action</button>}
|
|
193
|
-
media={<PlaceholderMedia />}
|
|
194
|
-
data-testid="river"
|
|
195
|
-
/>,
|
|
196
|
-
);
|
|
197
|
-
|
|
198
|
-
const river = page.getByTestId("river");
|
|
199
|
-
await expect.element(river).toBeInTheDocument();
|
|
200
|
-
});
|
|
201
|
-
|
|
202
|
-
test("variant A renders content before media", async () => {
|
|
203
|
-
render(
|
|
204
|
-
<River
|
|
205
|
-
variant="A"
|
|
206
|
-
headline="Test Headline"
|
|
207
|
-
body="Test"
|
|
208
|
-
primaryAction={<button type="button">Action</button>}
|
|
209
|
-
media={<PlaceholderMedia />}
|
|
210
|
-
data-testid="river"
|
|
211
|
-
/>,
|
|
212
|
-
);
|
|
213
|
-
|
|
214
|
-
// Both should be present
|
|
215
|
-
await expect.element(page.getByText("Test Headline")).toBeInTheDocument();
|
|
216
|
-
await expect.element(page.getByTestId("media")).toBeInTheDocument();
|
|
217
|
-
});
|
|
218
|
-
|
|
219
|
-
test("variant B renders media before content", async () => {
|
|
220
|
-
render(
|
|
221
|
-
<River
|
|
222
|
-
variant="B"
|
|
223
|
-
headline="Test Headline"
|
|
224
|
-
body="Test"
|
|
225
|
-
primaryAction={<button type="button">Action</button>}
|
|
226
|
-
media={<PlaceholderMedia />}
|
|
227
|
-
data-testid="river"
|
|
228
|
-
/>,
|
|
229
|
-
);
|
|
230
|
-
|
|
231
|
-
// Both should be present
|
|
232
|
-
await expect.element(page.getByText("Test Headline")).toBeInTheDocument();
|
|
233
|
-
await expect.element(page.getByTestId("media")).toBeInTheDocument();
|
|
234
|
-
});
|
|
235
|
-
});
|
|
236
|
-
|
|
237
|
-
describe("Content", () => {
|
|
238
|
-
test("headline has correct styling", async () => {
|
|
239
|
-
render(
|
|
240
|
-
<River
|
|
241
|
-
headline="Styled Headline"
|
|
242
|
-
body="Test"
|
|
243
|
-
primaryAction={<button type="button">Action</button>}
|
|
244
|
-
media={<PlaceholderMedia />}
|
|
245
|
-
/>,
|
|
246
|
-
);
|
|
247
|
-
|
|
248
|
-
const headline = page.getByRole("heading", { level: 2 });
|
|
249
|
-
await expect.element(headline).toHaveClass(/typography-h4/);
|
|
250
|
-
await expect.element(headline).toHaveClass(/text-gray-900/);
|
|
251
|
-
});
|
|
252
|
-
|
|
253
|
-
test("body has correct styling", async () => {
|
|
254
|
-
render(
|
|
255
|
-
<River
|
|
256
|
-
headline="Test"
|
|
257
|
-
body="Styled body text"
|
|
258
|
-
primaryAction={<button type="button">Action</button>}
|
|
259
|
-
media={<PlaceholderMedia />}
|
|
260
|
-
/>,
|
|
261
|
-
);
|
|
262
|
-
|
|
263
|
-
const body = page.getByText("Styled body text");
|
|
264
|
-
await expect.element(body).toHaveClass(/typography-body-small/);
|
|
265
|
-
await expect.element(body).toHaveClass(/text-gray-800/);
|
|
266
|
-
});
|
|
267
|
-
});
|
|
268
|
-
});
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { Tout, type ToutProps } from "./tout";
|
|
@@ -1,171 +0,0 @@
|
|
|
1
|
-
import type { Meta, StoryObj } from "@storybook/react-vite";
|
|
2
|
-
import { Button } from "../../atoms/button";
|
|
3
|
-
import { NdstudioFooter } from "../../atoms/ndstudio-footer";
|
|
4
|
-
import { Tout } from ".";
|
|
5
|
-
|
|
6
|
-
const meta: Meta<typeof Tout> = {
|
|
7
|
-
title: "Sections/Tout",
|
|
8
|
-
component: Tout,
|
|
9
|
-
parameters: {
|
|
10
|
-
layout: "fullscreen",
|
|
11
|
-
},
|
|
12
|
-
argTypes: {
|
|
13
|
-
headline: {
|
|
14
|
-
control: "text",
|
|
15
|
-
description: "The headline text",
|
|
16
|
-
},
|
|
17
|
-
body: {
|
|
18
|
-
control: "text",
|
|
19
|
-
description: "The body text",
|
|
20
|
-
},
|
|
21
|
-
},
|
|
22
|
-
} as Meta<typeof Tout>;
|
|
23
|
-
|
|
24
|
-
export default meta;
|
|
25
|
-
type Story = StoryObj<typeof Tout>;
|
|
26
|
-
|
|
27
|
-
const PlaceholderBackground = () => (
|
|
28
|
-
<div className="absolute inset-0 bg-gradient-to-br from-gray-300 to-gray-400" />
|
|
29
|
-
);
|
|
30
|
-
|
|
31
|
-
const ImageBackground = () => (
|
|
32
|
-
<img
|
|
33
|
-
src="https://images.unsplash.com/photo-1557804506-669a67965ba0?w=1600&h=900&fit=crop"
|
|
34
|
-
alt=""
|
|
35
|
-
className="absolute inset-0 w-full h-full object-cover"
|
|
36
|
-
/>
|
|
37
|
-
);
|
|
38
|
-
|
|
39
|
-
export const Playground: Story = {
|
|
40
|
-
render: (args) => <Tout {...args} />,
|
|
41
|
-
};
|
|
42
|
-
Playground.args = {
|
|
43
|
-
headline: "Brand-Large/Headline/Small",
|
|
44
|
-
body: "A river pattern stacks content in a simple vertical flow: one clear heading, a short block of copy, then the next step. It's ideal for guiding citizens through a process or story, keeping focus moving straight down the page with minimal choices and well-timed calls to action.",
|
|
45
|
-
primaryAction: <Button>Primary</Button>,
|
|
46
|
-
secondaryAction: <Button variant="secondary-outline">Secondary</Button>,
|
|
47
|
-
backgroundMedia: <PlaceholderBackground />,
|
|
48
|
-
};
|
|
49
|
-
|
|
50
|
-
// =============================================================================
|
|
51
|
-
// Responsive Variants
|
|
52
|
-
// =============================================================================
|
|
53
|
-
|
|
54
|
-
export const Desktop: Story = {
|
|
55
|
-
render: () => (
|
|
56
|
-
<Tout
|
|
57
|
-
headline="Brand-Large/Headline/Small"
|
|
58
|
-
body="A river pattern stacks content in a simple vertical flow: one clear heading, a short block of copy, then the next step. It's ideal for guiding citizens through a process or story, keeping focus moving straight down the page with minimal choices and well-timed calls to action."
|
|
59
|
-
primaryAction={<Button>Primary</Button>}
|
|
60
|
-
secondaryAction={<Button variant="secondary-outline">Secondary</Button>}
|
|
61
|
-
backgroundMedia={<PlaceholderBackground />}
|
|
62
|
-
/>
|
|
63
|
-
),
|
|
64
|
-
globals: {
|
|
65
|
-
viewport: { value: "lg", isRotated: false },
|
|
66
|
-
},
|
|
67
|
-
};
|
|
68
|
-
|
|
69
|
-
export const Tablet: Story = {
|
|
70
|
-
render: () => (
|
|
71
|
-
<Tout
|
|
72
|
-
headline="Brand-Large/Headline/Small"
|
|
73
|
-
body="A river pattern stacks content in a simple vertical flow: one clear heading, a short block of copy, then the next step. It's ideal for guiding citizens through a process or story, keeping focus moving straight down the page with minimal choices and well-timed calls to action."
|
|
74
|
-
primaryAction={<Button>Primary</Button>}
|
|
75
|
-
secondaryAction={<Button variant="secondary-outline">Secondary</Button>}
|
|
76
|
-
backgroundMedia={<PlaceholderBackground />}
|
|
77
|
-
/>
|
|
78
|
-
),
|
|
79
|
-
globals: {
|
|
80
|
-
viewport: { value: "md", isRotated: false },
|
|
81
|
-
},
|
|
82
|
-
};
|
|
83
|
-
|
|
84
|
-
export const Mobile: Story = {
|
|
85
|
-
render: () => (
|
|
86
|
-
<Tout
|
|
87
|
-
headline="Brand-Large/Headline/Small"
|
|
88
|
-
body="A river pattern stacks content in a simple vertical flow: one clear heading, a short block of copy, then the next step. It's ideal for guiding citizens through a process or story, keeping focus moving straight down the page with minimal choices and well-timed calls to action."
|
|
89
|
-
primaryAction={<Button size="sm">Primary</Button>}
|
|
90
|
-
secondaryAction={
|
|
91
|
-
<Button size="sm" variant="secondary-outline">
|
|
92
|
-
Secondary
|
|
93
|
-
</Button>
|
|
94
|
-
}
|
|
95
|
-
backgroundMedia={<PlaceholderBackground />}
|
|
96
|
-
/>
|
|
97
|
-
),
|
|
98
|
-
globals: {
|
|
99
|
-
viewport: { value: "sm", isRotated: false },
|
|
100
|
-
},
|
|
101
|
-
};
|
|
102
|
-
|
|
103
|
-
// =============================================================================
|
|
104
|
-
// Examples
|
|
105
|
-
// =============================================================================
|
|
106
|
-
|
|
107
|
-
/**
|
|
108
|
-
* With actual background image
|
|
109
|
-
*/
|
|
110
|
-
export const WithImage: Story = {
|
|
111
|
-
render: () => (
|
|
112
|
-
<Tout
|
|
113
|
-
headline="Work with Purpose"
|
|
114
|
-
body="Join a team that's building the future of government services. We're looking for passionate individuals who want to make a difference."
|
|
115
|
-
primaryAction={<Button>View Careers</Button>}
|
|
116
|
-
secondaryAction={<Button variant="secondary-outline">Learn More</Button>}
|
|
117
|
-
backgroundMedia={<ImageBackground />}
|
|
118
|
-
/>
|
|
119
|
-
),
|
|
120
|
-
};
|
|
121
|
-
|
|
122
|
-
/**
|
|
123
|
-
* Without secondary action
|
|
124
|
-
*/
|
|
125
|
-
export const SingleAction: Story = {
|
|
126
|
-
render: () => (
|
|
127
|
-
<Tout
|
|
128
|
-
headline="Get Started Today"
|
|
129
|
-
body="Begin your journey with our comprehensive onboarding process designed to help you succeed from day one."
|
|
130
|
-
primaryAction={<Button>Start Now</Button>}
|
|
131
|
-
backgroundMedia={<PlaceholderBackground />}
|
|
132
|
-
/>
|
|
133
|
-
),
|
|
134
|
-
};
|
|
135
|
-
|
|
136
|
-
/**
|
|
137
|
-
* With video background (placeholder)
|
|
138
|
-
*/
|
|
139
|
-
export const WithVideoPlaceholder: Story = {
|
|
140
|
-
render: () => (
|
|
141
|
-
<Tout
|
|
142
|
-
headline="Experience Innovation"
|
|
143
|
-
body="See how modern technology is transforming the way government serves its citizens."
|
|
144
|
-
primaryAction={<Button>Watch Video</Button>}
|
|
145
|
-
secondaryAction={<Button variant="secondary-outline">Learn More</Button>}
|
|
146
|
-
backgroundMedia={
|
|
147
|
-
<div className="absolute inset-0 bg-gray-800 flex items-center justify-center">
|
|
148
|
-
<span className="text-gray-400 typography-body-small">
|
|
149
|
-
Video Background
|
|
150
|
-
</span>
|
|
151
|
-
</div>
|
|
152
|
-
}
|
|
153
|
-
/>
|
|
154
|
-
),
|
|
155
|
-
};
|
|
156
|
-
|
|
157
|
-
/**
|
|
158
|
-
* With NdstudioFooter - shows the National Design Studio branding at the bottom
|
|
159
|
-
*/
|
|
160
|
-
export const WithNdstudioFooter: Story = {
|
|
161
|
-
render: () => (
|
|
162
|
-
<Tout
|
|
163
|
-
headline="Work with Purpose"
|
|
164
|
-
body="Join a team that's building the future of government services. We're looking for passionate individuals who want to make a difference."
|
|
165
|
-
primaryAction={<Button>View Careers</Button>}
|
|
166
|
-
secondaryAction={<Button variant="secondary-outline">Learn More</Button>}
|
|
167
|
-
backgroundMedia={<ImageBackground />}
|
|
168
|
-
footer={<NdstudioFooter />}
|
|
169
|
-
/>
|
|
170
|
-
),
|
|
171
|
-
};
|
|
@@ -1,242 +0,0 @@
|
|
|
1
|
-
import { describe, expect, test } from "vitest";
|
|
2
|
-
import { page } from "vitest/browser";
|
|
3
|
-
import { render } from "vitest-browser-react";
|
|
4
|
-
import { Tout } from "./tout";
|
|
5
|
-
|
|
6
|
-
const PlaceholderBackground = () => (
|
|
7
|
-
<div data-testid="background" className="absolute inset-0 bg-gray-300" />
|
|
8
|
-
);
|
|
9
|
-
|
|
10
|
-
describe("Tout", () => {
|
|
11
|
-
describe("Accessibility", () => {
|
|
12
|
-
test("renders as section landmark", async () => {
|
|
13
|
-
render(
|
|
14
|
-
<Tout
|
|
15
|
-
headline="Test Headline"
|
|
16
|
-
body="Test body"
|
|
17
|
-
primaryAction={<button type="button">Action</button>}
|
|
18
|
-
backgroundMedia={<PlaceholderBackground />}
|
|
19
|
-
data-testid="tout"
|
|
20
|
-
/>,
|
|
21
|
-
);
|
|
22
|
-
|
|
23
|
-
const tout = page.getByTestId("tout");
|
|
24
|
-
await expect.element(tout).toBeInTheDocument();
|
|
25
|
-
});
|
|
26
|
-
|
|
27
|
-
test("headline renders as h2", async () => {
|
|
28
|
-
render(
|
|
29
|
-
<Tout
|
|
30
|
-
headline="Tout Headline"
|
|
31
|
-
body="Test body"
|
|
32
|
-
primaryAction={<button type="button">Action</button>}
|
|
33
|
-
backgroundMedia={<PlaceholderBackground />}
|
|
34
|
-
/>,
|
|
35
|
-
);
|
|
36
|
-
|
|
37
|
-
await expect
|
|
38
|
-
.element(page.getByRole("heading", { level: 2, name: "Tout Headline" }))
|
|
39
|
-
.toBeInTheDocument();
|
|
40
|
-
});
|
|
41
|
-
|
|
42
|
-
test("body text is accessible", async () => {
|
|
43
|
-
render(
|
|
44
|
-
<Tout
|
|
45
|
-
headline="Test"
|
|
46
|
-
body="Accessible body text"
|
|
47
|
-
primaryAction={<button type="button">Action</button>}
|
|
48
|
-
backgroundMedia={<PlaceholderBackground />}
|
|
49
|
-
/>,
|
|
50
|
-
);
|
|
51
|
-
|
|
52
|
-
await expect
|
|
53
|
-
.element(page.getByText("Accessible body text"))
|
|
54
|
-
.toBeInTheDocument();
|
|
55
|
-
});
|
|
56
|
-
|
|
57
|
-
test("background is hidden from screen readers", async () => {
|
|
58
|
-
render(
|
|
59
|
-
<Tout
|
|
60
|
-
headline="Test"
|
|
61
|
-
body="Test"
|
|
62
|
-
primaryAction={<button type="button">Action</button>}
|
|
63
|
-
backgroundMedia={<PlaceholderBackground />}
|
|
64
|
-
data-testid="tout"
|
|
65
|
-
/>,
|
|
66
|
-
);
|
|
67
|
-
|
|
68
|
-
const tout = page.getByTestId("tout");
|
|
69
|
-
await expect.element(tout).toBeInTheDocument();
|
|
70
|
-
});
|
|
71
|
-
});
|
|
72
|
-
|
|
73
|
-
describe("Props", () => {
|
|
74
|
-
test("renders with required props", async () => {
|
|
75
|
-
render(
|
|
76
|
-
<Tout
|
|
77
|
-
headline="Required Headline"
|
|
78
|
-
body="Required body"
|
|
79
|
-
primaryAction={<button type="button">Primary</button>}
|
|
80
|
-
backgroundMedia={<PlaceholderBackground />}
|
|
81
|
-
/>,
|
|
82
|
-
);
|
|
83
|
-
|
|
84
|
-
await expect
|
|
85
|
-
.element(page.getByText("Required Headline"))
|
|
86
|
-
.toBeInTheDocument();
|
|
87
|
-
await expect.element(page.getByText("Required body")).toBeInTheDocument();
|
|
88
|
-
await expect
|
|
89
|
-
.element(page.getByRole("button", { name: "Primary" }))
|
|
90
|
-
.toBeInTheDocument();
|
|
91
|
-
await expect.element(page.getByTestId("background")).toBeInTheDocument();
|
|
92
|
-
});
|
|
93
|
-
|
|
94
|
-
test("renders secondary action when provided", async () => {
|
|
95
|
-
render(
|
|
96
|
-
<Tout
|
|
97
|
-
headline="Test"
|
|
98
|
-
body="Test"
|
|
99
|
-
primaryAction={<button type="button">Primary</button>}
|
|
100
|
-
secondaryAction={<button type="button">Secondary</button>}
|
|
101
|
-
backgroundMedia={<PlaceholderBackground />}
|
|
102
|
-
/>,
|
|
103
|
-
);
|
|
104
|
-
|
|
105
|
-
await expect
|
|
106
|
-
.element(page.getByRole("button", { name: "Primary" }))
|
|
107
|
-
.toBeInTheDocument();
|
|
108
|
-
await expect
|
|
109
|
-
.element(page.getByRole("button", { name: "Secondary" }))
|
|
110
|
-
.toBeInTheDocument();
|
|
111
|
-
});
|
|
112
|
-
|
|
113
|
-
test("does not render secondary action when not provided", async () => {
|
|
114
|
-
render(
|
|
115
|
-
<Tout
|
|
116
|
-
headline="Test"
|
|
117
|
-
body="Test"
|
|
118
|
-
primaryAction={<button type="button">Primary</button>}
|
|
119
|
-
backgroundMedia={<PlaceholderBackground />}
|
|
120
|
-
/>,
|
|
121
|
-
);
|
|
122
|
-
|
|
123
|
-
await expect
|
|
124
|
-
.element(page.getByRole("button", { name: "Primary" }))
|
|
125
|
-
.toBeInTheDocument();
|
|
126
|
-
// Should only have one button
|
|
127
|
-
const buttons = page.getByRole("button");
|
|
128
|
-
await expect.element(buttons).toBeInTheDocument();
|
|
129
|
-
});
|
|
130
|
-
|
|
131
|
-
test("supports custom className", async () => {
|
|
132
|
-
render(
|
|
133
|
-
<Tout
|
|
134
|
-
headline="Test"
|
|
135
|
-
body="Test"
|
|
136
|
-
primaryAction={<button type="button">Action</button>}
|
|
137
|
-
backgroundMedia={<PlaceholderBackground />}
|
|
138
|
-
className="custom-class"
|
|
139
|
-
data-testid="tout"
|
|
140
|
-
/>,
|
|
141
|
-
);
|
|
142
|
-
|
|
143
|
-
const tout = page.getByTestId("tout");
|
|
144
|
-
await expect.element(tout).toHaveClass(/custom-class/);
|
|
145
|
-
});
|
|
146
|
-
|
|
147
|
-
test("spreads additional props to section element", async () => {
|
|
148
|
-
render(
|
|
149
|
-
<Tout
|
|
150
|
-
headline="Test"
|
|
151
|
-
body="Test"
|
|
152
|
-
primaryAction={<button type="button">Action</button>}
|
|
153
|
-
backgroundMedia={<PlaceholderBackground />}
|
|
154
|
-
data-testid="tout"
|
|
155
|
-
aria-label="Tout section"
|
|
156
|
-
/>,
|
|
157
|
-
);
|
|
158
|
-
|
|
159
|
-
const tout = page.getByTestId("tout");
|
|
160
|
-
await expect.element(tout).toHaveAttribute("aria-label", "Tout section");
|
|
161
|
-
});
|
|
162
|
-
});
|
|
163
|
-
|
|
164
|
-
describe("Styling", () => {
|
|
165
|
-
test("applies full width class", async () => {
|
|
166
|
-
render(
|
|
167
|
-
<Tout
|
|
168
|
-
headline="Test"
|
|
169
|
-
body="Test"
|
|
170
|
-
primaryAction={<button type="button">Action</button>}
|
|
171
|
-
backgroundMedia={<PlaceholderBackground />}
|
|
172
|
-
data-testid="tout"
|
|
173
|
-
/>,
|
|
174
|
-
);
|
|
175
|
-
|
|
176
|
-
const tout = page.getByTestId("tout");
|
|
177
|
-
await expect.element(tout).toHaveClass(/w-full/);
|
|
178
|
-
});
|
|
179
|
-
|
|
180
|
-
test("applies responsive height classes", async () => {
|
|
181
|
-
render(
|
|
182
|
-
<Tout
|
|
183
|
-
headline="Test"
|
|
184
|
-
body="Test"
|
|
185
|
-
primaryAction={<button type="button">Action</button>}
|
|
186
|
-
backgroundMedia={<PlaceholderBackground />}
|
|
187
|
-
data-testid="tout"
|
|
188
|
-
/>,
|
|
189
|
-
);
|
|
190
|
-
|
|
191
|
-
const tout = page.getByTestId("tout");
|
|
192
|
-
await expect.element(tout).toHaveClass(/h-\[600px\]/);
|
|
193
|
-
});
|
|
194
|
-
|
|
195
|
-
test("applies relative positioning for z-index context", async () => {
|
|
196
|
-
render(
|
|
197
|
-
<Tout
|
|
198
|
-
headline="Test"
|
|
199
|
-
body="Test"
|
|
200
|
-
primaryAction={<button type="button">Action</button>}
|
|
201
|
-
backgroundMedia={<PlaceholderBackground />}
|
|
202
|
-
data-testid="tout"
|
|
203
|
-
/>,
|
|
204
|
-
);
|
|
205
|
-
|
|
206
|
-
const tout = page.getByTestId("tout");
|
|
207
|
-
await expect.element(tout).toHaveClass(/relative/);
|
|
208
|
-
});
|
|
209
|
-
});
|
|
210
|
-
|
|
211
|
-
describe("Content", () => {
|
|
212
|
-
test("headline has correct styling", async () => {
|
|
213
|
-
render(
|
|
214
|
-
<Tout
|
|
215
|
-
headline="Styled Headline"
|
|
216
|
-
body="Test"
|
|
217
|
-
primaryAction={<button type="button">Action</button>}
|
|
218
|
-
backgroundMedia={<PlaceholderBackground />}
|
|
219
|
-
/>,
|
|
220
|
-
);
|
|
221
|
-
|
|
222
|
-
const headline = page.getByRole("heading", { level: 2 });
|
|
223
|
-
await expect.element(headline).toHaveClass(/typography-h4/);
|
|
224
|
-
await expect.element(headline).toHaveClass(/text-gray-900/);
|
|
225
|
-
});
|
|
226
|
-
|
|
227
|
-
test("body has correct styling", async () => {
|
|
228
|
-
render(
|
|
229
|
-
<Tout
|
|
230
|
-
headline="Test"
|
|
231
|
-
body="Styled body text"
|
|
232
|
-
primaryAction={<button type="button">Action</button>}
|
|
233
|
-
backgroundMedia={<PlaceholderBackground />}
|
|
234
|
-
/>,
|
|
235
|
-
);
|
|
236
|
-
|
|
237
|
-
const body = page.getByText("Styled body text");
|
|
238
|
-
await expect.element(body).toHaveClass(/typography-body-small/);
|
|
239
|
-
await expect.element(body).toHaveClass(/text-gray-800/);
|
|
240
|
-
});
|
|
241
|
-
});
|
|
242
|
-
});
|