@nationaldesignstudio/react 0.0.17 → 0.0.19

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 (33) hide show
  1. package/dist/component-registry.md +181 -29
  2. package/dist/components/atoms/background/background.d.ts +135 -0
  3. package/dist/components/atoms/button/button.d.ts +64 -82
  4. package/dist/components/atoms/button/icon-button.d.ts +100 -66
  5. package/dist/components/organisms/card/card.d.ts +130 -4
  6. package/dist/components/organisms/us-gov-banner/us-gov-banner.d.ts +120 -2
  7. package/dist/components/sections/hero/hero.d.ts +166 -150
  8. package/dist/components/sections/quote-block/quote-block.d.ts +152 -0
  9. package/dist/index.d.ts +6 -2
  10. package/dist/index.js +3868 -5978
  11. package/dist/index.js.map +1 -1
  12. package/dist/lib/utils.d.ts +1 -2
  13. package/dist/tokens.css +207 -16
  14. package/package.json +2 -4
  15. package/src/components/atoms/background/background.tsx +377 -0
  16. package/src/components/atoms/background/index.ts +22 -0
  17. package/src/components/atoms/button/button.stories.tsx +81 -32
  18. package/src/components/atoms/button/button.tsx +91 -49
  19. package/src/components/atoms/button/icon-button.stories.tsx +179 -28
  20. package/src/components/atoms/button/icon-button.tsx +111 -49
  21. package/src/components/organisms/card/card.tsx +82 -24
  22. package/src/components/organisms/card/index.ts +7 -0
  23. package/src/components/organisms/us-gov-banner/index.ts +5 -1
  24. package/src/components/organisms/us-gov-banner/us-gov-banner.tsx +72 -16
  25. package/src/components/sections/hero/hero.stories.tsx +124 -1
  26. package/src/components/sections/hero/hero.test.tsx +21 -18
  27. package/src/components/sections/hero/hero.tsx +188 -301
  28. package/src/components/sections/hero/index.ts +13 -0
  29. package/src/components/sections/quote-block/index.ts +5 -0
  30. package/src/components/sections/quote-block/quote-block.tsx +216 -0
  31. package/src/index.ts +40 -0
  32. package/src/lib/utils.ts +1 -6
  33. package/src/stories/ThemeProvider.stories.tsx +5 -5
@@ -1,5 +1,5 @@
1
1
  import type { Meta, StoryObj } from "@storybook/react-vite";
2
- import { Hero, HeroBackground } from ".";
2
+ import { Hero, HeroBackground, HeroContent, HeroHeader } from ".";
3
3
 
4
4
  const meta: Meta<typeof Hero> = {
5
5
  title: "Sections/Hero",
@@ -30,6 +30,11 @@ const meta: Meta<typeof Hero> = {
30
30
  control: "color",
31
31
  description: "Color of the overlay",
32
32
  },
33
+ borderRadius: {
34
+ control: "text",
35
+ description:
36
+ "Border radius for the hero container (e.g., '0 0 20px 20px')",
37
+ },
33
38
  },
34
39
  } as Meta<typeof Hero>;
35
40
 
@@ -146,6 +151,124 @@ export const WithCloudflareStream: Story = {
146
151
  ),
147
152
  };
148
153
 
154
+ // =============================================================================
155
+ // Composition - Top Slot & Border Radius
156
+ // =============================================================================
157
+
158
+ /**
159
+ * Mock banner component for story demonstration
160
+ */
161
+ const MockBanner = () => (
162
+ <div className="bg-gray-1200 px-spacing-16 py-spacing-8 text-center text-14 text-text-inverted">
163
+ An official website of the United States government
164
+ </div>
165
+ );
166
+
167
+ /**
168
+ * Mock navigation component for story demonstration
169
+ */
170
+ const MockNavigation = () => (
171
+ <nav className="flex items-center justify-between px-spacing-56 py-spacing-16">
172
+ <div className="flex items-center gap-spacing-24">
173
+ <div className="size-48 rounded-full bg-gray-50" />
174
+ <div className="flex gap-spacing-24 text-14 text-text-inverted">
175
+ <span className="cursor-pointer hover:opacity-80">Link 1</span>
176
+ <span className="cursor-pointer hover:opacity-80">Link 2</span>
177
+ </div>
178
+ </div>
179
+ <div className="text-14 text-text-inverted">Actions</div>
180
+ </nav>
181
+ );
182
+
183
+ /**
184
+ * Hero with top slot containing a banner
185
+ */
186
+ export const WithTopSlot: Story = {
187
+ render: () => (
188
+ <Hero
189
+ variant="A1"
190
+ title="Hero with Top Slot"
191
+ background="#1a1a1a"
192
+ top={<MockBanner />}
193
+ />
194
+ ),
195
+ };
196
+
197
+ /**
198
+ * Hero with rounded bottom corners
199
+ */
200
+ export const WithRoundedCorners: Story = {
201
+ render: () => (
202
+ <div className="bg-bg-page p-spacing-32">
203
+ <Hero
204
+ variant="A1"
205
+ title="Rounded Corners"
206
+ background="#1a1a1a"
207
+ borderRadius="0 0 20px 20px"
208
+ />
209
+ </div>
210
+ ),
211
+ };
212
+
213
+ /**
214
+ * Hero with both top slot and rounded corners
215
+ */
216
+ export const WithTopAndRoundedCorners: Story = {
217
+ render: () => (
218
+ <div className="bg-bg-page">
219
+ <Hero
220
+ variant="A1"
221
+ title="Full Composition"
222
+ background={
223
+ <HeroBackground.Image
224
+ src="https://images.unsplash.com/photo-1451187580459-43490279c0fa?w=1920&q=80"
225
+ position="center"
226
+ />
227
+ }
228
+ overlayOpacity={0.5}
229
+ borderRadius="0 0 20px 20px"
230
+ top={
231
+ <>
232
+ <MockBanner />
233
+ <MockNavigation />
234
+ </>
235
+ }
236
+ >
237
+ <p className="mt-spacing-16 max-w-[560px] text-20 text-text-inverted">
238
+ A subtitle or description can be added as children
239
+ </p>
240
+ </Hero>
241
+ </div>
242
+ ),
243
+ };
244
+
245
+ // =============================================================================
246
+ // Sub-components
247
+ // =============================================================================
248
+
249
+ /**
250
+ * Using Hero.Header and Hero.Content sub-components directly
251
+ * for more control over the layout
252
+ */
253
+ export const UsingSubComponents: Story = {
254
+ render: () => (
255
+ <section className="relative flex min-h-[80vh] flex-col bg-gray-1200">
256
+ <HeroHeader>
257
+ <MockBanner />
258
+ <MockNavigation />
259
+ </HeroHeader>
260
+ <HeroContent className="flex-1 justify-end">
261
+ <h1 className="text-64 font-medium text-text-inverted lg:text-128">
262
+ Custom Layout
263
+ </h1>
264
+ <p className="mt-spacing-16 text-20 text-text-inverted">
265
+ Using HeroHeader and HeroContent sub-components
266
+ </p>
267
+ </HeroContent>
268
+ </section>
269
+ ),
270
+ };
271
+
149
272
  // =============================================================================
150
273
  // Responsive Variants - A1 (Content at bottom)
151
274
  // =============================================================================
@@ -63,73 +63,76 @@ describe("Hero", () => {
63
63
  });
64
64
 
65
65
  describe("Styling", () => {
66
- test("applies default background color", async () => {
66
+ test("applies default background color when no background provided", async () => {
67
67
  render(<Hero title="Default" data-testid="hero" />);
68
68
 
69
69
  const hero = page.getByTestId("hero");
70
- await expect.element(hero).toHaveClass(/bg-gray-1000/);
70
+ // Uses semantic token bg-bg-overlay for default background
71
+ await expect.element(hero).toHaveClass(/bg-bg-overlay/);
71
72
  });
72
73
 
73
- test("applies responsive height classes", async () => {
74
+ test("applies minimum height for viewport coverage", async () => {
74
75
  render(<Hero title="Responsive" data-testid="hero" />);
75
76
 
76
77
  const hero = page.getByTestId("hero");
77
- // Mobile height
78
- await expect.element(hero).toHaveClass(/h-\[500px\]/);
78
+ // Uses min-h-[80vh] for all variants
79
+ await expect.element(hero).toHaveClass(/min-h-\[80vh\]/);
79
80
  });
80
81
  });
81
82
 
82
83
  describe("Variants", () => {
83
- test("A1 variant applies items-end alignment (default)", async () => {
84
+ test("A1 variant applies flex column layout", async () => {
84
85
  render(<Hero title="A1 Hero" variant="A1" data-testid="hero" />);
85
86
 
86
87
  const hero = page.getByTestId("hero");
87
- await expect.element(hero).toHaveClass(/items-end/);
88
+ await expect.element(hero).toHaveClass(/flex-col/);
88
89
  });
89
90
 
90
91
  test("A1 variant is default when no variant specified", async () => {
91
92
  render(<Hero title="Default Hero" data-testid="hero" />);
92
93
 
93
94
  const hero = page.getByTestId("hero");
94
- await expect.element(hero).toHaveClass(/items-end/);
95
+ // Default variant still applies min-height and flex layout
96
+ await expect.element(hero).toHaveClass(/min-h-\[80vh\]/);
97
+ await expect.element(hero).toHaveClass(/flex-col/);
95
98
  });
96
99
 
97
- test("A2 variant applies items-start alignment", async () => {
100
+ test("A2 variant applies flex column layout", async () => {
98
101
  render(<Hero title="A2 Hero" variant="A2" data-testid="hero" />);
99
102
 
100
103
  const hero = page.getByTestId("hero");
101
- await expect.element(hero).toHaveClass(/items-start/);
104
+ await expect.element(hero).toHaveClass(/flex-col/);
102
105
  });
103
106
 
104
- test("A3 variant applies items-center alignment", async () => {
107
+ test("A3 variant applies flex column layout", async () => {
105
108
  render(<Hero title="A3 Hero" variant="A3" data-testid="hero" />);
106
109
 
107
110
  const hero = page.getByTestId("hero");
108
- await expect.element(hero).toHaveClass(/items-center/);
111
+ await expect.element(hero).toHaveClass(/flex-col/);
109
112
  });
110
113
 
111
114
  test("A1 variant maintains common styles", async () => {
112
115
  render(<Hero title="A1 Hero" variant="A1" data-testid="hero" />);
113
116
 
114
117
  const hero = page.getByTestId("hero");
115
- await expect.element(hero).toHaveClass(/bg-gray-1000/);
116
- await expect.element(hero).toHaveClass(/h-\[500px\]/);
118
+ await expect.element(hero).toHaveClass(/bg-bg-overlay/);
119
+ await expect.element(hero).toHaveClass(/min-h-\[80vh\]/);
117
120
  });
118
121
 
119
122
  test("A2 variant maintains common styles", async () => {
120
123
  render(<Hero title="A2 Hero" variant="A2" data-testid="hero" />);
121
124
 
122
125
  const hero = page.getByTestId("hero");
123
- await expect.element(hero).toHaveClass(/bg-gray-1000/);
124
- await expect.element(hero).toHaveClass(/h-\[500px\]/);
126
+ await expect.element(hero).toHaveClass(/bg-bg-overlay/);
127
+ await expect.element(hero).toHaveClass(/min-h-\[80vh\]/);
125
128
  });
126
129
 
127
130
  test("A3 variant maintains common styles", async () => {
128
131
  render(<Hero title="A3 Hero" variant="A3" data-testid="hero" />);
129
132
 
130
133
  const hero = page.getByTestId("hero");
131
- await expect.element(hero).toHaveClass(/bg-gray-1000/);
132
- await expect.element(hero).toHaveClass(/h-\[500px\]/);
134
+ await expect.element(hero).toHaveClass(/bg-bg-overlay/);
135
+ await expect.element(hero).toHaveClass(/min-h-\[80vh\]/);
133
136
  });
134
137
  });
135
138
  });