@nationaldesignstudio/react 0.0.9 → 0.0.11
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 +2405 -0
- package/dist/components/atoms/accordion/accordion.d.ts +44 -3
- package/dist/components/atoms/button/button.d.ts +155 -11
- package/dist/components/atoms/button/icon-button.d.ts +114 -5
- package/dist/components/atoms/ndstudio-footer/ndstudio-footer.d.ts +30 -0
- package/dist/components/atoms/pager-control/pager-control.d.ts +116 -9
- package/dist/components/dev-tools/dev-toolbar/dev-toolbar.d.ts +4 -0
- package/dist/components/dev-tools/grid-overlay/grid-overlay.d.ts +6 -0
- package/dist/components/organisms/card/card.d.ts +40 -4
- package/dist/components/sections/banner/banner.d.ts +39 -6
- package/dist/components/sections/card-grid/card-grid.d.ts +37 -4
- package/dist/components/sections/faq-section/faq-section.d.ts +2 -2
- package/dist/components/sections/hero/hero.d.ts +167 -16
- package/dist/components/sections/river/river.d.ts +37 -4
- package/dist/components/sections/tout/tout.d.ts +86 -6
- package/dist/components/sections/two-column-section/two-column-section.d.ts +80 -6
- package/dist/hooks/index.d.ts +1 -0
- package/dist/hooks/use-event-listener.d.ts +24 -0
- package/dist/index.d.ts +9 -2
- package/dist/index.js +12034 -5934
- package/dist/index.js.map +1 -1
- package/dist/lib/theme.d.ts +330 -0
- package/dist/tailwind.css +1 -15
- package/dist/tokens.css +13057 -6852
- package/package.json +12 -23
- 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.tsx +0 -137
- package/src/components/atoms/accordion/index.ts +0 -6
- 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 -84
- package/src/components/atoms/button/button.test.tsx +0 -141
- package/src/components/atoms/button/button.tsx +0 -95
- package/src/components/atoms/button/button.visual.test.tsx +0 -102
- package/src/components/atoms/button/icon-button.stories.tsx +0 -166
- package/src/components/atoms/button/icon-button.tsx +0 -125
- package/src/components/atoms/button/index.ts +0 -6
- package/src/components/atoms/pager-control/index.ts +0 -5
- package/src/components/atoms/pager-control/pager-control.stories.tsx +0 -209
- package/src/components/atoms/pager-control/pager-control.test.tsx +0 -149
- package/src/components/atoms/pager-control/pager-control.tsx +0 -328
- 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 -245
- package/src/components/organisms/card/card.tsx +0 -227
- package/src/components/organisms/card/card.visual.test.tsx +0 -197
- package/src/components/organisms/card/index.ts +0 -19
- 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.tsx +0 -317
- 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 -1
- 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.tsx +0 -73
- 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/banner.tsx +0 -130
- 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/card-grid.tsx +0 -118
- package/src/components/sections/card-grid/index.ts +0 -1
- package/src/components/sections/faq-section/faq-section.tsx +0 -77
- 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 -145
- package/src/components/sections/hero/hero.test.tsx +0 -135
- package/src/components/sections/hero/hero.tsx +0 -191
- package/src/components/sections/hero/hero.visual.test.tsx +0 -140
- package/src/components/sections/hero/index.ts +0 -1
- 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.tsx +0 -88
- package/src/components/sections/prose/prose.visual.test.tsx +0 -105
- 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/river/river.tsx +0 -175
- package/src/components/sections/tout/index.ts +0 -1
- package/src/components/sections/tout/tout.stories.tsx +0 -154
- package/src/components/sections/tout/tout.test.tsx +0 -242
- package/src/components/sections/tout/tout.tsx +0 -206
- 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/sections/two-column-section/two-column-section.tsx +0 -152
- package/src/index.ts +0 -98
- package/src/lib/utils.ts +0 -6
- package/src/main.tsx +0 -13
- package/src/stories/Introduction.mdx +0 -114
- package/src/stories/TokenShowcase.stories.tsx +0 -92
- package/src/stories/TokenShowcase.tsx +0 -1352
- package/src/styles.css +0 -11
|
@@ -1,150 +0,0 @@
|
|
|
1
|
-
import type { Meta, StoryObj } from "@storybook/react-vite";
|
|
2
|
-
import { Button } from "../../atoms/button";
|
|
3
|
-
import { Banner } from ".";
|
|
4
|
-
|
|
5
|
-
const meta: Meta<typeof Banner> = {
|
|
6
|
-
title: "Sections/Banner",
|
|
7
|
-
component: Banner,
|
|
8
|
-
parameters: {
|
|
9
|
-
layout: "fullscreen",
|
|
10
|
-
},
|
|
11
|
-
argTypes: {
|
|
12
|
-
heading: {
|
|
13
|
-
control: "text",
|
|
14
|
-
description: "The heading text displayed in the banner",
|
|
15
|
-
},
|
|
16
|
-
description: {
|
|
17
|
-
control: "text",
|
|
18
|
-
description: "The description text displayed below the heading",
|
|
19
|
-
},
|
|
20
|
-
},
|
|
21
|
-
} as Meta<typeof Banner>;
|
|
22
|
-
|
|
23
|
-
export default meta;
|
|
24
|
-
type Story = StoryObj<typeof Banner>;
|
|
25
|
-
|
|
26
|
-
export const Playground: Story = {
|
|
27
|
-
render: (args) => <Banner {...args} />,
|
|
28
|
-
};
|
|
29
|
-
Playground.args = {
|
|
30
|
-
heading: "Important Update",
|
|
31
|
-
description:
|
|
32
|
-
"Use banners to surface short, important updates or a single key action without disrupting the main page content.",
|
|
33
|
-
action: <Button>Learn More</Button>,
|
|
34
|
-
};
|
|
35
|
-
|
|
36
|
-
// =============================================================================
|
|
37
|
-
// Default
|
|
38
|
-
// =============================================================================
|
|
39
|
-
|
|
40
|
-
/**
|
|
41
|
-
* Default banner with heading, description, and action button.
|
|
42
|
-
* Responsive across all breakpoints.
|
|
43
|
-
*/
|
|
44
|
-
export const Default: Story = {
|
|
45
|
-
render: () => (
|
|
46
|
-
<Banner
|
|
47
|
-
heading="Important Update"
|
|
48
|
-
description="Use banners to surface short, important updates or a single key action without disrupting the main page content."
|
|
49
|
-
action={<Button>Learn More</Button>}
|
|
50
|
-
/>
|
|
51
|
-
),
|
|
52
|
-
};
|
|
53
|
-
|
|
54
|
-
/**
|
|
55
|
-
* Banner without an action button.
|
|
56
|
-
*/
|
|
57
|
-
export const WithoutAction: Story = {
|
|
58
|
-
render: () => (
|
|
59
|
-
<Banner
|
|
60
|
-
heading="Announcement"
|
|
61
|
-
description="Use banners to surface short, important updates or a single key action without disrupting the main page content."
|
|
62
|
-
/>
|
|
63
|
-
),
|
|
64
|
-
};
|
|
65
|
-
|
|
66
|
-
// =============================================================================
|
|
67
|
-
// Responsive Variants
|
|
68
|
-
// =============================================================================
|
|
69
|
-
|
|
70
|
-
/**
|
|
71
|
-
* Desktop viewport (lg breakpoint, 1440px)
|
|
72
|
-
* Horizontal layout with 72px padding
|
|
73
|
-
*/
|
|
74
|
-
export const Desktop: Story = {
|
|
75
|
-
render: () => (
|
|
76
|
-
<Banner
|
|
77
|
-
heading="Desktop Banner"
|
|
78
|
-
description="Use banners to surface short, important updates or a single key action without disrupting the main page content."
|
|
79
|
-
action={<Button>Learn More</Button>}
|
|
80
|
-
/>
|
|
81
|
-
),
|
|
82
|
-
globals: {
|
|
83
|
-
viewport: { value: "lg", isRotated: false },
|
|
84
|
-
},
|
|
85
|
-
};
|
|
86
|
-
|
|
87
|
-
/**
|
|
88
|
-
* Tablet viewport (md breakpoint, 768px)
|
|
89
|
-
* Horizontal layout with 56px padding
|
|
90
|
-
*/
|
|
91
|
-
export const Tablet: Story = {
|
|
92
|
-
render: () => (
|
|
93
|
-
<Banner
|
|
94
|
-
heading="Tablet Banner"
|
|
95
|
-
description="Use banners to surface short, important updates or a single key action without disrupting the main page content."
|
|
96
|
-
action={<Button>Learn More</Button>}
|
|
97
|
-
/>
|
|
98
|
-
),
|
|
99
|
-
globals: {
|
|
100
|
-
viewport: { value: "md", isRotated: false },
|
|
101
|
-
},
|
|
102
|
-
};
|
|
103
|
-
|
|
104
|
-
/**
|
|
105
|
-
* Mobile viewport (sm breakpoint, 320px)
|
|
106
|
-
* Stacked layout with 20x32px padding
|
|
107
|
-
*/
|
|
108
|
-
export const Mobile: Story = {
|
|
109
|
-
render: () => (
|
|
110
|
-
<Banner
|
|
111
|
-
heading="Mobile Banner"
|
|
112
|
-
description="Use banners to surface short, important updates or a single key action without disruption."
|
|
113
|
-
action={<Button size="sm">Learn More</Button>}
|
|
114
|
-
/>
|
|
115
|
-
),
|
|
116
|
-
globals: {
|
|
117
|
-
viewport: { value: "sm", isRotated: false },
|
|
118
|
-
},
|
|
119
|
-
};
|
|
120
|
-
|
|
121
|
-
// =============================================================================
|
|
122
|
-
// Examples
|
|
123
|
-
// =============================================================================
|
|
124
|
-
|
|
125
|
-
/**
|
|
126
|
-
* Banner with a longer description that wraps
|
|
127
|
-
*/
|
|
128
|
-
export const LongDescription: Story = {
|
|
129
|
-
render: () => (
|
|
130
|
-
<Banner
|
|
131
|
-
heading="New Features Available"
|
|
132
|
-
description="We've made significant improvements to our platform including enhanced security features, faster load times, improved accessibility across all components, and a redesigned dashboard experience. Check out the documentation for more details on how to take advantage of these updates."
|
|
133
|
-
action={<Button>View Documentation</Button>}
|
|
134
|
-
/>
|
|
135
|
-
),
|
|
136
|
-
};
|
|
137
|
-
|
|
138
|
-
/**
|
|
139
|
-
* Banner with custom styling
|
|
140
|
-
*/
|
|
141
|
-
export const CustomBackground: Story = {
|
|
142
|
-
render: () => (
|
|
143
|
-
<Banner
|
|
144
|
-
heading="Custom Styled Banner"
|
|
145
|
-
description="This banner has a custom background color applied via className."
|
|
146
|
-
action={<Button variant="ivory">Action</Button>}
|
|
147
|
-
className="bg-gray-1000 text-gray-50 [&_h2]:text-gray-50 [&_p]:text-gray-200"
|
|
148
|
-
/>
|
|
149
|
-
),
|
|
150
|
-
};
|
|
@@ -1,185 +0,0 @@
|
|
|
1
|
-
import { describe, expect, test } from "vitest";
|
|
2
|
-
import { page } from "vitest/browser";
|
|
3
|
-
import { render } from "vitest-browser-react";
|
|
4
|
-
import { Banner } from "./banner";
|
|
5
|
-
|
|
6
|
-
describe("Banner", () => {
|
|
7
|
-
describe("Accessibility", () => {
|
|
8
|
-
test("renders as section landmark", async () => {
|
|
9
|
-
render(
|
|
10
|
-
<Banner
|
|
11
|
-
heading="Test Banner"
|
|
12
|
-
description="Test description"
|
|
13
|
-
data-testid="banner"
|
|
14
|
-
/>,
|
|
15
|
-
);
|
|
16
|
-
|
|
17
|
-
const banner = page.getByTestId("banner");
|
|
18
|
-
await expect.element(banner).toBeInTheDocument();
|
|
19
|
-
});
|
|
20
|
-
|
|
21
|
-
test("heading renders as h2", async () => {
|
|
22
|
-
render(
|
|
23
|
-
<Banner heading="Banner Heading" description="Test description" />,
|
|
24
|
-
);
|
|
25
|
-
|
|
26
|
-
await expect
|
|
27
|
-
.element(
|
|
28
|
-
page.getByRole("heading", { level: 2, name: "Banner Heading" }),
|
|
29
|
-
)
|
|
30
|
-
.toBeInTheDocument();
|
|
31
|
-
});
|
|
32
|
-
|
|
33
|
-
test("description is accessible to screen readers", async () => {
|
|
34
|
-
render(
|
|
35
|
-
<Banner heading="Test" description="Accessible description text" />,
|
|
36
|
-
);
|
|
37
|
-
|
|
38
|
-
await expect
|
|
39
|
-
.element(page.getByText("Accessible description text"))
|
|
40
|
-
.toBeInTheDocument();
|
|
41
|
-
});
|
|
42
|
-
});
|
|
43
|
-
|
|
44
|
-
describe("Props", () => {
|
|
45
|
-
test("renders with required heading and description props", async () => {
|
|
46
|
-
render(
|
|
47
|
-
<Banner
|
|
48
|
-
heading="Required Heading"
|
|
49
|
-
description="Required description"
|
|
50
|
-
/>,
|
|
51
|
-
);
|
|
52
|
-
|
|
53
|
-
await expect
|
|
54
|
-
.element(page.getByText("Required Heading"))
|
|
55
|
-
.toBeInTheDocument();
|
|
56
|
-
await expect
|
|
57
|
-
.element(page.getByText("Required description"))
|
|
58
|
-
.toBeInTheDocument();
|
|
59
|
-
});
|
|
60
|
-
|
|
61
|
-
test("renders action when provided", async () => {
|
|
62
|
-
render(
|
|
63
|
-
<Banner
|
|
64
|
-
heading="With Action"
|
|
65
|
-
description="Description"
|
|
66
|
-
action={<button type="button">Click Me</button>}
|
|
67
|
-
/>,
|
|
68
|
-
);
|
|
69
|
-
|
|
70
|
-
await expect
|
|
71
|
-
.element(page.getByRole("button", { name: "Click Me" }))
|
|
72
|
-
.toBeInTheDocument();
|
|
73
|
-
});
|
|
74
|
-
|
|
75
|
-
test("does not render action slot when not provided", async () => {
|
|
76
|
-
render(
|
|
77
|
-
<Banner
|
|
78
|
-
heading="Without Action"
|
|
79
|
-
description="Description"
|
|
80
|
-
data-testid="banner"
|
|
81
|
-
/>,
|
|
82
|
-
);
|
|
83
|
-
|
|
84
|
-
const banner = page.getByTestId("banner");
|
|
85
|
-
await expect.element(banner).toBeInTheDocument();
|
|
86
|
-
// Only heading and description should be present
|
|
87
|
-
await expect.element(page.getByRole("button")).not.toBeInTheDocument();
|
|
88
|
-
});
|
|
89
|
-
|
|
90
|
-
test("supports custom className", async () => {
|
|
91
|
-
render(
|
|
92
|
-
<Banner
|
|
93
|
-
heading="Custom"
|
|
94
|
-
description="Description"
|
|
95
|
-
className="custom-class"
|
|
96
|
-
data-testid="banner"
|
|
97
|
-
/>,
|
|
98
|
-
);
|
|
99
|
-
|
|
100
|
-
const banner = page.getByTestId("banner");
|
|
101
|
-
await expect.element(banner).toHaveClass(/custom-class/);
|
|
102
|
-
});
|
|
103
|
-
|
|
104
|
-
test("spreads additional props to section element", async () => {
|
|
105
|
-
render(
|
|
106
|
-
<Banner
|
|
107
|
-
heading="Props Test"
|
|
108
|
-
description="Description"
|
|
109
|
-
data-testid="banner"
|
|
110
|
-
aria-label="Banner section"
|
|
111
|
-
/>,
|
|
112
|
-
);
|
|
113
|
-
|
|
114
|
-
const banner = page.getByTestId("banner");
|
|
115
|
-
await expect
|
|
116
|
-
.element(banner)
|
|
117
|
-
.toHaveAttribute("aria-label", "Banner section");
|
|
118
|
-
});
|
|
119
|
-
});
|
|
120
|
-
|
|
121
|
-
describe("Styling", () => {
|
|
122
|
-
test("applies default background color", async () => {
|
|
123
|
-
render(
|
|
124
|
-
<Banner
|
|
125
|
-
heading="Default"
|
|
126
|
-
description="Description"
|
|
127
|
-
data-testid="banner"
|
|
128
|
-
/>,
|
|
129
|
-
);
|
|
130
|
-
|
|
131
|
-
const banner = page.getByTestId("banner");
|
|
132
|
-
await expect.element(banner).toHaveClass(/bg-gray-50/);
|
|
133
|
-
});
|
|
134
|
-
|
|
135
|
-
test("applies col-full for grid alignment", async () => {
|
|
136
|
-
render(
|
|
137
|
-
<Banner
|
|
138
|
-
heading="Grid Test"
|
|
139
|
-
description="Description"
|
|
140
|
-
data-testid="banner"
|
|
141
|
-
/>,
|
|
142
|
-
);
|
|
143
|
-
|
|
144
|
-
const banner = page.getByTestId("banner");
|
|
145
|
-
await expect.element(banner).toHaveClass(/col-full/);
|
|
146
|
-
});
|
|
147
|
-
|
|
148
|
-
test("applies responsive padding classes", async () => {
|
|
149
|
-
render(
|
|
150
|
-
<Banner
|
|
151
|
-
heading="Responsive"
|
|
152
|
-
description="Description"
|
|
153
|
-
data-testid="banner"
|
|
154
|
-
/>,
|
|
155
|
-
);
|
|
156
|
-
|
|
157
|
-
const banner = page.getByTestId("banner");
|
|
158
|
-
// Mobile padding
|
|
159
|
-
await expect.element(banner).toHaveClass(/px-spacing-20/);
|
|
160
|
-
await expect.element(banner).toHaveClass(/py-spacing-32/);
|
|
161
|
-
});
|
|
162
|
-
});
|
|
163
|
-
|
|
164
|
-
describe("Content", () => {
|
|
165
|
-
test("heading has correct text color", async () => {
|
|
166
|
-
render(<Banner heading="Styled Heading" description="Description" />);
|
|
167
|
-
|
|
168
|
-
const heading = page.getByRole("heading", { level: 2 });
|
|
169
|
-
await expect.element(heading).toHaveClass(/text-gray-900/);
|
|
170
|
-
});
|
|
171
|
-
|
|
172
|
-
test("description has correct text color", async () => {
|
|
173
|
-
render(
|
|
174
|
-
<Banner
|
|
175
|
-
heading="Test"
|
|
176
|
-
description="Styled description"
|
|
177
|
-
data-testid="banner"
|
|
178
|
-
/>,
|
|
179
|
-
);
|
|
180
|
-
|
|
181
|
-
const description = page.getByText("Styled description");
|
|
182
|
-
await expect.element(description).toHaveClass(/text-gray-800/);
|
|
183
|
-
});
|
|
184
|
-
});
|
|
185
|
-
});
|
|
@@ -1,130 +0,0 @@
|
|
|
1
|
-
import { cva, type VariantProps } from "class-variance-authority";
|
|
2
|
-
import * as React from "react";
|
|
3
|
-
import { cn } from "@/lib/utils";
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Banner component based on Figma BaseKit / Banners
|
|
7
|
-
*
|
|
8
|
-
* Used to surface short, important updates or a single key action
|
|
9
|
-
* without disrupting the main page content.
|
|
10
|
-
*
|
|
11
|
-
* Responsive behavior using 24-column grid:
|
|
12
|
-
* - Mobile (sm): Stacked layout, 20px horizontal / 32px vertical padding
|
|
13
|
-
* - Tablet (md): Horizontal layout, 56px padding
|
|
14
|
-
* - Desktop (lg): Horizontal layout, 72px padding
|
|
15
|
-
*
|
|
16
|
-
* Must be placed inside a `grid-container`. Uses `col-full` to span all columns.
|
|
17
|
-
*/
|
|
18
|
-
const bannerVariants = cva(
|
|
19
|
-
[
|
|
20
|
-
// Grid alignment - full width
|
|
21
|
-
"col-full",
|
|
22
|
-
// Responsive padding: mobile -> tablet -> desktop
|
|
23
|
-
"px-spacing-20 py-spacing-32",
|
|
24
|
-
"md:p-spacing-56",
|
|
25
|
-
"lg:px-spacing-72 lg:pb-spacing-72 lg:pt-0",
|
|
26
|
-
],
|
|
27
|
-
{
|
|
28
|
-
variants: {
|
|
29
|
-
theme: {
|
|
30
|
-
light: "bg-gray-50",
|
|
31
|
-
dark: "bg-gray-1200",
|
|
32
|
-
},
|
|
33
|
-
},
|
|
34
|
-
defaultVariants: {
|
|
35
|
-
theme: "light",
|
|
36
|
-
},
|
|
37
|
-
},
|
|
38
|
-
);
|
|
39
|
-
|
|
40
|
-
export interface BannerProps
|
|
41
|
-
extends React.HTMLAttributes<HTMLElement>,
|
|
42
|
-
VariantProps<typeof bannerVariants> {
|
|
43
|
-
/**
|
|
44
|
-
* The heading text displayed in the banner
|
|
45
|
-
*/
|
|
46
|
-
heading: string;
|
|
47
|
-
/**
|
|
48
|
-
* The description text displayed below the heading
|
|
49
|
-
*/
|
|
50
|
-
description: string;
|
|
51
|
-
/**
|
|
52
|
-
* Optional action element (typically a Button component)
|
|
53
|
-
*/
|
|
54
|
-
action?: React.ReactNode;
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
/**
|
|
58
|
-
* Banner component for surfacing important updates or CTAs.
|
|
59
|
-
*
|
|
60
|
-
* Uses the 24-column grid system - must be placed inside a `grid-container`.
|
|
61
|
-
* Spans full width with `col-full`.
|
|
62
|
-
*
|
|
63
|
-
* Responsive across breakpoints:
|
|
64
|
-
* - Mobile: Stacked layout with smaller padding
|
|
65
|
-
* - Tablet: Horizontal layout with medium padding
|
|
66
|
-
* - Desktop: Horizontal layout with larger padding
|
|
67
|
-
*
|
|
68
|
-
* @example
|
|
69
|
-
* ```tsx
|
|
70
|
-
* <div className="grid-container">
|
|
71
|
-
* <Banner
|
|
72
|
-
* heading="Important Update"
|
|
73
|
-
* description="Check out our new features."
|
|
74
|
-
* action={<Button>Learn More</Button>}
|
|
75
|
-
* />
|
|
76
|
-
* </div>
|
|
77
|
-
*
|
|
78
|
-
* // Dark theme
|
|
79
|
-
* <Banner
|
|
80
|
-
* theme="dark"
|
|
81
|
-
* heading="Still Have Questions?"
|
|
82
|
-
* description="Contact us at support@example.com"
|
|
83
|
-
* action={<Button variant="secondary">Email Us</Button>}
|
|
84
|
-
* />
|
|
85
|
-
* ```
|
|
86
|
-
*/
|
|
87
|
-
const Banner = React.forwardRef<HTMLElement, BannerProps>(
|
|
88
|
-
({ className, theme, heading, description, action, ...props }, ref) => {
|
|
89
|
-
return (
|
|
90
|
-
<section
|
|
91
|
-
ref={ref}
|
|
92
|
-
className={cn(bannerVariants({ theme }), className)}
|
|
93
|
-
{...props}
|
|
94
|
-
>
|
|
95
|
-
{/* Inner container with border-top for dark theme */}
|
|
96
|
-
<div
|
|
97
|
-
className={cn(
|
|
98
|
-
"flex flex-col md:flex-row gap-spacing-20 items-start md:items-center md:justify-between",
|
|
99
|
-
theme === "dark" && "border-t border-gray-700 py-spacing-36",
|
|
100
|
-
)}
|
|
101
|
-
>
|
|
102
|
-
{/* Copy section */}
|
|
103
|
-
<div className="flex flex-col gap-spacing-6 items-start">
|
|
104
|
-
<h2
|
|
105
|
-
className={cn(
|
|
106
|
-
"typography-subheading-small",
|
|
107
|
-
theme === "dark" ? "text-gray-100" : "text-gray-900",
|
|
108
|
-
)}
|
|
109
|
-
>
|
|
110
|
-
{heading}
|
|
111
|
-
</h2>
|
|
112
|
-
<p
|
|
113
|
-
className={cn(
|
|
114
|
-
"typography-body-small",
|
|
115
|
-
theme === "dark" ? "text-gray-500" : "text-gray-800",
|
|
116
|
-
)}
|
|
117
|
-
>
|
|
118
|
-
{description}
|
|
119
|
-
</p>
|
|
120
|
-
</div>
|
|
121
|
-
{/* Action slot */}
|
|
122
|
-
{action}
|
|
123
|
-
</div>
|
|
124
|
-
</section>
|
|
125
|
-
);
|
|
126
|
-
},
|
|
127
|
-
);
|
|
128
|
-
Banner.displayName = "Banner";
|
|
129
|
-
|
|
130
|
-
export { Banner, bannerVariants };
|