@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.
Files changed (160) hide show
  1. package/package.json +10 -2
  2. package/src/App.css +0 -0
  3. package/src/App.tsx +0 -7
  4. package/src/assets/fonts/PPNeueMontreal-Variable.woff2 +0 -0
  5. package/src/assets/react.svg +0 -1
  6. package/src/components/atoms/accordion/accordion.stories.tsx +0 -228
  7. package/src/components/atoms/accordion/accordion.test.tsx +0 -231
  8. package/src/components/atoms/accordion/index.ts +0 -6
  9. package/src/components/atoms/background/background.test.tsx +0 -213
  10. package/src/components/atoms/background/index.ts +0 -22
  11. package/src/components/atoms/button/__screenshots__/button.visual.test.tsx/button-charcoal-chromium-darwin.png +0 -0
  12. package/src/components/atoms/button/__screenshots__/button.visual.test.tsx/button-charcoal-chromium-linux.png +0 -0
  13. package/src/components/atoms/button/__screenshots__/button.visual.test.tsx/button-charcoal-outline-chromium-darwin.png +0 -0
  14. package/src/components/atoms/button/__screenshots__/button.visual.test.tsx/button-charcoal-outline-chromium-linux.png +0 -0
  15. package/src/components/atoms/button/__screenshots__/button.visual.test.tsx/button-charcoal-outline-quiet-chromium-darwin.png +0 -0
  16. package/src/components/atoms/button/__screenshots__/button.visual.test.tsx/button-charcoal-outline-quiet-chromium-linux.png +0 -0
  17. package/src/components/atoms/button/__screenshots__/button.visual.test.tsx/button-disabled-chromium-darwin.png +0 -0
  18. package/src/components/atoms/button/__screenshots__/button.visual.test.tsx/button-disabled-chromium-linux.png +0 -0
  19. package/src/components/atoms/button/__screenshots__/button.visual.test.tsx/button-ivory-chromium-darwin.png +0 -0
  20. package/src/components/atoms/button/__screenshots__/button.visual.test.tsx/button-ivory-chromium-linux.png +0 -0
  21. package/src/components/atoms/button/__screenshots__/button.visual.test.tsx/button-ivory-outline-chromium-darwin.png +0 -0
  22. package/src/components/atoms/button/__screenshots__/button.visual.test.tsx/button-ivory-outline-chromium-linux.png +0 -0
  23. package/src/components/atoms/button/__screenshots__/button.visual.test.tsx/button-ivory-outline-quiet-chromium-darwin.png +0 -0
  24. package/src/components/atoms/button/__screenshots__/button.visual.test.tsx/button-ivory-outline-quiet-chromium-linux.png +0 -0
  25. package/src/components/atoms/button/__screenshots__/button.visual.test.tsx/button-size-large-chromium-darwin.png +0 -0
  26. package/src/components/atoms/button/__screenshots__/button.visual.test.tsx/button-size-large-chromium-linux.png +0 -0
  27. package/src/components/atoms/button/__screenshots__/button.visual.test.tsx/button-size-medium-chromium-darwin.png +0 -0
  28. package/src/components/atoms/button/__screenshots__/button.visual.test.tsx/button-size-medium-chromium-linux.png +0 -0
  29. package/src/components/atoms/button/__screenshots__/button.visual.test.tsx/button-size-small-chromium-darwin.png +0 -0
  30. package/src/components/atoms/button/__screenshots__/button.visual.test.tsx/button-size-small-chromium-linux.png +0 -0
  31. package/src/components/atoms/button/button.stories.tsx +0 -289
  32. package/src/components/atoms/button/button.test.tsx +0 -419
  33. package/src/components/atoms/button/button.visual.test.tsx +0 -98
  34. package/src/components/atoms/button/icon-button.stories.tsx +0 -260
  35. package/src/components/atoms/button/icon-button.test.tsx +0 -186
  36. package/src/components/atoms/button/index.ts +0 -6
  37. package/src/components/atoms/input/index.ts +0 -17
  38. package/src/components/atoms/input/input-group.stories.tsx +0 -646
  39. package/src/components/atoms/input/input-group.test.tsx +0 -362
  40. package/src/components/atoms/input/input.stories.tsx +0 -228
  41. package/src/components/atoms/input/input.test.tsx +0 -167
  42. package/src/components/atoms/ndstudio-footer/index.ts +0 -1
  43. package/src/components/atoms/pager-control/index.ts +0 -5
  44. package/src/components/atoms/pager-control/pager-control.stories.tsx +0 -207
  45. package/src/components/atoms/pager-control/pager-control.test.tsx +0 -130
  46. package/src/components/atoms/popover/index.ts +0 -30
  47. package/src/components/atoms/popover/popover.stories.tsx +0 -531
  48. package/src/components/atoms/popover/popover.test.tsx +0 -486
  49. package/src/components/atoms/select/index.ts +0 -18
  50. package/src/components/atoms/select/select.stories.tsx +0 -455
  51. package/src/components/atoms/tooltip/index.ts +0 -24
  52. package/src/components/atoms/tooltip/tooltip.stories.tsx +0 -348
  53. package/src/components/atoms/tooltip/tooltip.test.tsx +0 -363
  54. package/src/components/dev-tools/dev-toolbar/dev-toolbar.stories.tsx +0 -73
  55. package/src/components/dev-tools/dev-toolbar/index.ts +0 -1
  56. package/src/components/dev-tools/grid-overlay/index.ts +0 -1
  57. package/src/components/dev-tools/index.ts +0 -2
  58. package/src/components/foundation/typography/typography.stories.tsx +0 -401
  59. package/src/components/organisms/card/__screenshots__/card.visual.test.tsx/card-default-vertical-chromium-darwin.png +0 -0
  60. package/src/components/organisms/card/__screenshots__/card.visual.test.tsx/card-default-vertical-chromium-linux.png +0 -0
  61. package/src/components/organisms/card/__screenshots__/card.visual.test.tsx/card-horizontal-chromium-darwin.png +0 -0
  62. package/src/components/organisms/card/__screenshots__/card.visual.test.tsx/card-horizontal-chromium-linux.png +0 -0
  63. package/src/components/organisms/card/__screenshots__/card.visual.test.tsx/card-minimal-chromium-darwin.png +0 -0
  64. package/src/components/organisms/card/__screenshots__/card.visual.test.tsx/card-minimal-chromium-linux.png +0 -0
  65. package/src/components/organisms/card/__screenshots__/card.visual.test.tsx/card-without-actions-chromium-darwin.png +0 -0
  66. package/src/components/organisms/card/__screenshots__/card.visual.test.tsx/card-without-actions-chromium-linux.png +0 -0
  67. package/src/components/organisms/card/__screenshots__/card.visual.test.tsx/card-without-eyebrow-chromium-darwin.png +0 -0
  68. package/src/components/organisms/card/__screenshots__/card.visual.test.tsx/card-without-eyebrow-chromium-linux.png +0 -0
  69. package/src/components/organisms/card/__screenshots__/card.visual.test.tsx/card-without-image-chromium-darwin.png +0 -0
  70. package/src/components/organisms/card/__screenshots__/card.visual.test.tsx/card-without-image-chromium-linux.png +0 -0
  71. package/src/components/organisms/card/card.stories.tsx +0 -293
  72. package/src/components/organisms/card/card.test.tsx +0 -247
  73. package/src/components/organisms/card/card.visual.test.tsx +0 -197
  74. package/src/components/organisms/card/index.ts +0 -26
  75. package/src/components/organisms/navbar/__screenshots__/navbar.visual.test.tsx/navbar-active-link-chromium-darwin.png +0 -0
  76. package/src/components/organisms/navbar/__screenshots__/navbar.visual.test.tsx/navbar-active-link-chromium-linux.png +0 -0
  77. package/src/components/organisms/navbar/__screenshots__/navbar.visual.test.tsx/navbar-brand-only-chromium-darwin.png +0 -0
  78. package/src/components/organisms/navbar/__screenshots__/navbar.visual.test.tsx/navbar-brand-only-chromium-linux.png +0 -0
  79. package/src/components/organisms/navbar/__screenshots__/navbar.visual.test.tsx/navbar-default-chromium-darwin.png +0 -0
  80. package/src/components/organisms/navbar/__screenshots__/navbar.visual.test.tsx/navbar-default-chromium-linux.png +0 -0
  81. package/src/components/organisms/navbar/index.ts +0 -18
  82. package/src/components/organisms/navbar/navbar.stories.tsx +0 -313
  83. package/src/components/organisms/navbar/navbar.test.tsx +0 -190
  84. package/src/components/organisms/navbar/navbar.visual.test.tsx +0 -85
  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
  86. package/src/components/organisms/us-gov-banner/__screenshots__/us-gov-banner.visual.test.tsx/us-gov-banner-custom-icon-chromium-linux.png +0 -0
  87. package/src/components/organisms/us-gov-banner/__screenshots__/us-gov-banner.visual.test.tsx/us-gov-banner-custom-text-chromium-darwin.png +0 -0
  88. package/src/components/organisms/us-gov-banner/__screenshots__/us-gov-banner.visual.test.tsx/us-gov-banner-custom-text-chromium-linux.png +0 -0
  89. package/src/components/organisms/us-gov-banner/__screenshots__/us-gov-banner.visual.test.tsx/us-gov-banner-default-chromium-darwin.png +0 -0
  90. package/src/components/organisms/us-gov-banner/__screenshots__/us-gov-banner.visual.test.tsx/us-gov-banner-default-chromium-linux.png +0 -0
  91. package/src/components/organisms/us-gov-banner/index.ts +0 -5
  92. package/src/components/organisms/us-gov-banner/us-gov-banner.stories.tsx +0 -35
  93. package/src/components/organisms/us-gov-banner/us-gov-banner.test.tsx +0 -107
  94. package/src/components/organisms/us-gov-banner/us-gov-banner.visual.test.tsx +0 -46
  95. package/src/components/sections/banner/banner.stories.tsx +0 -150
  96. package/src/components/sections/banner/banner.test.tsx +0 -185
  97. package/src/components/sections/banner/index.ts +0 -2
  98. package/src/components/sections/card-grid/card-grid.stories.tsx +0 -351
  99. package/src/components/sections/card-grid/index.ts +0 -1
  100. package/src/components/sections/faq-section/faq-section.stories.tsx +0 -453
  101. package/src/components/sections/faq-section/index.ts +0 -2
  102. package/src/components/sections/hero/__screenshots__/hero.visual.test.tsx/hero-a1-desktop-chromium-darwin.png +0 -0
  103. package/src/components/sections/hero/__screenshots__/hero.visual.test.tsx/hero-a1-desktop-chromium-linux.png +0 -0
  104. package/src/components/sections/hero/__screenshots__/hero.visual.test.tsx/hero-a1-mobile-chromium-darwin.png +0 -0
  105. package/src/components/sections/hero/__screenshots__/hero.visual.test.tsx/hero-a1-mobile-chromium-linux.png +0 -0
  106. package/src/components/sections/hero/__screenshots__/hero.visual.test.tsx/hero-a1-tablet-chromium-darwin.png +0 -0
  107. package/src/components/sections/hero/__screenshots__/hero.visual.test.tsx/hero-a1-tablet-chromium-linux.png +0 -0
  108. package/src/components/sections/hero/__screenshots__/hero.visual.test.tsx/hero-a2-desktop-chromium-darwin.png +0 -0
  109. package/src/components/sections/hero/__screenshots__/hero.visual.test.tsx/hero-a2-desktop-chromium-linux.png +0 -0
  110. package/src/components/sections/hero/__screenshots__/hero.visual.test.tsx/hero-a2-mobile-chromium-darwin.png +0 -0
  111. package/src/components/sections/hero/__screenshots__/hero.visual.test.tsx/hero-a2-mobile-chromium-linux.png +0 -0
  112. package/src/components/sections/hero/__screenshots__/hero.visual.test.tsx/hero-a2-tablet-chromium-darwin.png +0 -0
  113. package/src/components/sections/hero/__screenshots__/hero.visual.test.tsx/hero-a2-tablet-chromium-linux.png +0 -0
  114. package/src/components/sections/hero/__screenshots__/hero.visual.test.tsx/hero-a3-desktop-chromium-darwin.png +0 -0
  115. package/src/components/sections/hero/__screenshots__/hero.visual.test.tsx/hero-a3-desktop-chromium-linux.png +0 -0
  116. package/src/components/sections/hero/__screenshots__/hero.visual.test.tsx/hero-a3-mobile-chromium-darwin.png +0 -0
  117. package/src/components/sections/hero/__screenshots__/hero.visual.test.tsx/hero-a3-mobile-chromium-linux.png +0 -0
  118. package/src/components/sections/hero/__screenshots__/hero.visual.test.tsx/hero-a3-tablet-chromium-darwin.png +0 -0
  119. package/src/components/sections/hero/__screenshots__/hero.visual.test.tsx/hero-a3-tablet-chromium-linux.png +0 -0
  120. package/src/components/sections/hero/__screenshots__/hero.visual.test.tsx/hero-custom-class-chromium-darwin.png +0 -0
  121. package/src/components/sections/hero/__screenshots__/hero.visual.test.tsx/hero-custom-class-chromium-linux.png +0 -0
  122. package/src/components/sections/hero/__screenshots__/hero.visual.test.tsx/hero-default-chromium-linux.png +0 -0
  123. package/src/components/sections/hero/__screenshots__/hero.visual.test.tsx/hero-long-title-chromium-darwin.png +0 -0
  124. package/src/components/sections/hero/__screenshots__/hero.visual.test.tsx/hero-long-title-chromium-linux.png +0 -0
  125. package/src/components/sections/hero/hero.stories.tsx +0 -397
  126. package/src/components/sections/hero/hero.test.tsx +0 -138
  127. package/src/components/sections/hero/hero.visual.test.tsx +0 -140
  128. package/src/components/sections/hero/index.ts +0 -23
  129. package/src/components/sections/prose/__screenshots__/prose.visual.test.tsx/prose-h3-heading-chromium-darwin.png +0 -0
  130. package/src/components/sections/prose/__screenshots__/prose.visual.test.tsx/prose-h3-heading-chromium-linux.png +0 -0
  131. package/src/components/sections/prose/__screenshots__/prose.visual.test.tsx/prose-multiple-paragraphs-chromium-darwin.png +0 -0
  132. package/src/components/sections/prose/__screenshots__/prose.visual.test.tsx/prose-multiple-paragraphs-chromium-linux.png +0 -0
  133. package/src/components/sections/prose/__screenshots__/prose.visual.test.tsx/prose-multiple-sections-chromium-darwin.png +0 -0
  134. package/src/components/sections/prose/__screenshots__/prose.visual.test.tsx/prose-multiple-sections-chromium-linux.png +0 -0
  135. package/src/components/sections/prose/__screenshots__/prose.visual.test.tsx/prose-single-section-chromium-darwin.png +0 -0
  136. package/src/components/sections/prose/__screenshots__/prose.visual.test.tsx/prose-single-section-chromium-linux.png +0 -0
  137. package/src/components/sections/prose/index.ts +0 -6
  138. package/src/components/sections/prose/prose.stories.tsx +0 -144
  139. package/src/components/sections/prose/prose.test.tsx +0 -178
  140. package/src/components/sections/prose/prose.visual.test.tsx +0 -105
  141. package/src/components/sections/quote-block/index.ts +0 -5
  142. package/src/components/sections/river/index.ts +0 -1
  143. package/src/components/sections/river/river.stories.tsx +0 -237
  144. package/src/components/sections/river/river.test.tsx +0 -268
  145. package/src/components/sections/tout/index.ts +0 -1
  146. package/src/components/sections/tout/tout.stories.tsx +0 -171
  147. package/src/components/sections/tout/tout.test.tsx +0 -242
  148. package/src/components/sections/two-column-section/index.ts +0 -5
  149. package/src/components/sections/two-column-section/two-column-section.stories.tsx +0 -285
  150. package/src/components/shared/index.ts +0 -5
  151. package/src/index.ts +0 -293
  152. package/src/main.tsx +0 -13
  153. package/src/stories/grid-system.stories.tsx +0 -309
  154. package/src/stories/introduction.mdx +0 -128
  155. package/src/stories/theme-provider.stories.tsx +0 -349
  156. package/src/stories/token-showcase.stories.tsx +0 -73
  157. package/src/stories/token-showcase.tsx +0 -777
  158. package/src/styles.css +0 -14
  159. package/src/tests/token-resolution.test.tsx +0 -298
  160. 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
- });
@@ -1,5 +0,0 @@
1
- export {
2
- TwoColumnSection,
3
- type TwoColumnSectionProps,
4
- twoColumnSectionVariants,
5
- } from "./two-column-section";