@nationaldesignstudio/react 0.0.10 → 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/tokens.css +13650 -6129
- package/package.json +11 -21
- 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
|
Binary file
|
|
Binary file
|
|
@@ -1,293 +0,0 @@
|
|
|
1
|
-
import type { Meta, StoryObj } from "@storybook/react-vite";
|
|
2
|
-
import { Button } from "../../atoms/button";
|
|
3
|
-
import {
|
|
4
|
-
Card,
|
|
5
|
-
CardActions,
|
|
6
|
-
CardBody,
|
|
7
|
-
CardContent,
|
|
8
|
-
CardDescription,
|
|
9
|
-
CardEyebrow,
|
|
10
|
-
CardImage,
|
|
11
|
-
CardTitle,
|
|
12
|
-
} from ".";
|
|
13
|
-
|
|
14
|
-
const meta: Meta<typeof Card> = {
|
|
15
|
-
title: "Organisms/Card",
|
|
16
|
-
component: Card,
|
|
17
|
-
parameters: {
|
|
18
|
-
layout: "centered",
|
|
19
|
-
},
|
|
20
|
-
} as Meta<typeof Card>;
|
|
21
|
-
|
|
22
|
-
export default meta;
|
|
23
|
-
type Story = StoryObj<typeof Card>;
|
|
24
|
-
|
|
25
|
-
// =============================================================================
|
|
26
|
-
// Default
|
|
27
|
-
// =============================================================================
|
|
28
|
-
|
|
29
|
-
export const Default: Story = {
|
|
30
|
-
render: () => (
|
|
31
|
-
<div className="w-[418px]">
|
|
32
|
-
<Card>
|
|
33
|
-
<CardImage />
|
|
34
|
-
<CardContent>
|
|
35
|
-
<CardBody>
|
|
36
|
-
<CardEyebrow>Optional Eyebrow</CardEyebrow>
|
|
37
|
-
<div className="flex flex-col gap-[6px]">
|
|
38
|
-
<CardTitle>Card Title</CardTitle>
|
|
39
|
-
<CardDescription>
|
|
40
|
-
Use cards when citizens need to scan items at a glance, either
|
|
41
|
-
to jump to a more detailed page or absorb short information.
|
|
42
|
-
</CardDescription>
|
|
43
|
-
</div>
|
|
44
|
-
</CardBody>
|
|
45
|
-
<CardActions>
|
|
46
|
-
<Button size="default" variant="charcoal">
|
|
47
|
-
Primary
|
|
48
|
-
</Button>
|
|
49
|
-
<Button size="default" variant="charcoalOutline">
|
|
50
|
-
Secondary
|
|
51
|
-
</Button>
|
|
52
|
-
</CardActions>
|
|
53
|
-
</CardContent>
|
|
54
|
-
</Card>
|
|
55
|
-
</div>
|
|
56
|
-
),
|
|
57
|
-
};
|
|
58
|
-
|
|
59
|
-
// =============================================================================
|
|
60
|
-
// Layouts
|
|
61
|
-
// =============================================================================
|
|
62
|
-
|
|
63
|
-
export const Vertical: Story = {
|
|
64
|
-
render: () => (
|
|
65
|
-
<div className="w-[418px]">
|
|
66
|
-
<Card layout="vertical">
|
|
67
|
-
<CardImage />
|
|
68
|
-
<CardContent>
|
|
69
|
-
<CardBody>
|
|
70
|
-
<CardEyebrow>Optional Eyebrow</CardEyebrow>
|
|
71
|
-
<div className="flex flex-col gap-[6px]">
|
|
72
|
-
<CardTitle>Card Title</CardTitle>
|
|
73
|
-
<CardDescription>
|
|
74
|
-
Use cards when citizens need to scan items at a glance, either
|
|
75
|
-
to jump to a more detailed page or absorb short information.
|
|
76
|
-
</CardDescription>
|
|
77
|
-
</div>
|
|
78
|
-
</CardBody>
|
|
79
|
-
<CardActions>
|
|
80
|
-
<Button size="default" variant="charcoal">
|
|
81
|
-
Primary
|
|
82
|
-
</Button>
|
|
83
|
-
<Button size="default" variant="charcoalOutline">
|
|
84
|
-
Secondary
|
|
85
|
-
</Button>
|
|
86
|
-
</CardActions>
|
|
87
|
-
</CardContent>
|
|
88
|
-
</Card>
|
|
89
|
-
</div>
|
|
90
|
-
),
|
|
91
|
-
};
|
|
92
|
-
|
|
93
|
-
export const Horizontal: Story = {
|
|
94
|
-
render: () => (
|
|
95
|
-
<div className="w-[700px]">
|
|
96
|
-
<Card layout="horizontal">
|
|
97
|
-
<CardImage />
|
|
98
|
-
<CardContent>
|
|
99
|
-
<CardBody>
|
|
100
|
-
<CardEyebrow>Eyebrow</CardEyebrow>
|
|
101
|
-
<div className="flex flex-col gap-[9px]">
|
|
102
|
-
<CardTitle>
|
|
103
|
-
Cards can support multi line headings easily.
|
|
104
|
-
</CardTitle>
|
|
105
|
-
<CardDescription>
|
|
106
|
-
Use cards when citizens need to scan items at a glance, either
|
|
107
|
-
to jump to a more detailed page or absorb short information.
|
|
108
|
-
</CardDescription>
|
|
109
|
-
</div>
|
|
110
|
-
</CardBody>
|
|
111
|
-
<CardActions>
|
|
112
|
-
<Button size="sm" variant="charcoal">
|
|
113
|
-
Primary
|
|
114
|
-
</Button>
|
|
115
|
-
<Button size="sm" variant="charcoalOutline">
|
|
116
|
-
Secondary
|
|
117
|
-
</Button>
|
|
118
|
-
</CardActions>
|
|
119
|
-
</CardContent>
|
|
120
|
-
</Card>
|
|
121
|
-
</div>
|
|
122
|
-
),
|
|
123
|
-
};
|
|
124
|
-
|
|
125
|
-
// =============================================================================
|
|
126
|
-
// Variations
|
|
127
|
-
// =============================================================================
|
|
128
|
-
|
|
129
|
-
export const WithoutImage: Story = {
|
|
130
|
-
render: () => (
|
|
131
|
-
<div className="w-[418px]">
|
|
132
|
-
<Card>
|
|
133
|
-
<CardContent>
|
|
134
|
-
<CardBody>
|
|
135
|
-
<CardEyebrow>Category</CardEyebrow>
|
|
136
|
-
<div className="flex flex-col gap-[6px]">
|
|
137
|
-
<CardTitle>Card Without Image</CardTitle>
|
|
138
|
-
<CardDescription>
|
|
139
|
-
Cards can be used without images for text-focused content.
|
|
140
|
-
</CardDescription>
|
|
141
|
-
</div>
|
|
142
|
-
</CardBody>
|
|
143
|
-
<CardActions>
|
|
144
|
-
<Button size="default" variant="charcoal">
|
|
145
|
-
Learn More
|
|
146
|
-
</Button>
|
|
147
|
-
</CardActions>
|
|
148
|
-
</CardContent>
|
|
149
|
-
</Card>
|
|
150
|
-
</div>
|
|
151
|
-
),
|
|
152
|
-
};
|
|
153
|
-
|
|
154
|
-
export const WithoutEyebrow: Story = {
|
|
155
|
-
render: () => (
|
|
156
|
-
<div className="w-[418px]">
|
|
157
|
-
<Card>
|
|
158
|
-
<CardImage />
|
|
159
|
-
<CardContent>
|
|
160
|
-
<CardBody>
|
|
161
|
-
<div className="flex flex-col gap-[6px]">
|
|
162
|
-
<CardTitle>Card Title</CardTitle>
|
|
163
|
-
<CardDescription>
|
|
164
|
-
The eyebrow is optional and can be omitted when not needed.
|
|
165
|
-
</CardDescription>
|
|
166
|
-
</div>
|
|
167
|
-
</CardBody>
|
|
168
|
-
<CardActions>
|
|
169
|
-
<Button size="default" variant="charcoal">
|
|
170
|
-
Primary
|
|
171
|
-
</Button>
|
|
172
|
-
</CardActions>
|
|
173
|
-
</CardContent>
|
|
174
|
-
</Card>
|
|
175
|
-
</div>
|
|
176
|
-
),
|
|
177
|
-
};
|
|
178
|
-
|
|
179
|
-
export const WithoutActions: Story = {
|
|
180
|
-
render: () => (
|
|
181
|
-
<div className="w-[418px]">
|
|
182
|
-
<Card>
|
|
183
|
-
<CardImage />
|
|
184
|
-
<CardContent>
|
|
185
|
-
<CardBody>
|
|
186
|
-
<CardEyebrow>Information</CardEyebrow>
|
|
187
|
-
<div className="flex flex-col gap-[6px]">
|
|
188
|
-
<CardTitle>Informational Card</CardTitle>
|
|
189
|
-
<CardDescription>
|
|
190
|
-
Cards without actions can be used for purely informational
|
|
191
|
-
content that doesn't require user interaction.
|
|
192
|
-
</CardDescription>
|
|
193
|
-
</div>
|
|
194
|
-
</CardBody>
|
|
195
|
-
</CardContent>
|
|
196
|
-
</Card>
|
|
197
|
-
</div>
|
|
198
|
-
),
|
|
199
|
-
};
|
|
200
|
-
|
|
201
|
-
export const Minimal: Story = {
|
|
202
|
-
render: () => (
|
|
203
|
-
<div className="w-[418px]">
|
|
204
|
-
<Card>
|
|
205
|
-
<CardContent>
|
|
206
|
-
<CardBody>
|
|
207
|
-
<CardTitle>Minimal Card</CardTitle>
|
|
208
|
-
<CardDescription>
|
|
209
|
-
A minimal card with just title and description.
|
|
210
|
-
</CardDescription>
|
|
211
|
-
</CardBody>
|
|
212
|
-
</CardContent>
|
|
213
|
-
</Card>
|
|
214
|
-
</div>
|
|
215
|
-
),
|
|
216
|
-
};
|
|
217
|
-
|
|
218
|
-
// =============================================================================
|
|
219
|
-
// Grid Example
|
|
220
|
-
// =============================================================================
|
|
221
|
-
|
|
222
|
-
export const CardGrid: Story = {
|
|
223
|
-
render: () => (
|
|
224
|
-
<div className="grid max-w-[900px] grid-cols-1 gap-6 md:grid-cols-2 lg:grid-cols-3">
|
|
225
|
-
{[1, 2, 3].map((i) => (
|
|
226
|
-
<Card key={i}>
|
|
227
|
-
<CardImage />
|
|
228
|
-
<CardContent>
|
|
229
|
-
<CardBody>
|
|
230
|
-
<CardEyebrow>Category {i}</CardEyebrow>
|
|
231
|
-
<div className="flex flex-col gap-[6px]">
|
|
232
|
-
<CardTitle>Card Title {i}</CardTitle>
|
|
233
|
-
<CardDescription>
|
|
234
|
-
Brief description of the card content goes here.
|
|
235
|
-
</CardDescription>
|
|
236
|
-
</div>
|
|
237
|
-
</CardBody>
|
|
238
|
-
<CardActions>
|
|
239
|
-
<Button size="sm" variant="charcoal">
|
|
240
|
-
Action
|
|
241
|
-
</Button>
|
|
242
|
-
</CardActions>
|
|
243
|
-
</CardContent>
|
|
244
|
-
</Card>
|
|
245
|
-
))}
|
|
246
|
-
</div>
|
|
247
|
-
),
|
|
248
|
-
parameters: {
|
|
249
|
-
layout: "padded",
|
|
250
|
-
},
|
|
251
|
-
};
|
|
252
|
-
|
|
253
|
-
// =============================================================================
|
|
254
|
-
// Playground
|
|
255
|
-
// =============================================================================
|
|
256
|
-
|
|
257
|
-
export const Playground: Story = {
|
|
258
|
-
render: (args) => (
|
|
259
|
-
<div className="w-[418px]">
|
|
260
|
-
<Card {...args}>
|
|
261
|
-
<CardImage />
|
|
262
|
-
<CardContent>
|
|
263
|
-
<CardBody>
|
|
264
|
-
<CardEyebrow>Eyebrow</CardEyebrow>
|
|
265
|
-
<div className="flex flex-col gap-[6px]">
|
|
266
|
-
<CardTitle>Card Title</CardTitle>
|
|
267
|
-
<CardDescription>
|
|
268
|
-
Use cards when citizens need to scan items at a glance.
|
|
269
|
-
</CardDescription>
|
|
270
|
-
</div>
|
|
271
|
-
</CardBody>
|
|
272
|
-
<CardActions>
|
|
273
|
-
<Button size="default" variant="charcoal">
|
|
274
|
-
Primary
|
|
275
|
-
</Button>
|
|
276
|
-
<Button size="default" variant="charcoalOutline">
|
|
277
|
-
Secondary
|
|
278
|
-
</Button>
|
|
279
|
-
</CardActions>
|
|
280
|
-
</CardContent>
|
|
281
|
-
</Card>
|
|
282
|
-
</div>
|
|
283
|
-
),
|
|
284
|
-
};
|
|
285
|
-
Playground.argTypes = {
|
|
286
|
-
layout: {
|
|
287
|
-
control: { type: "radio" },
|
|
288
|
-
options: ["vertical", "horizontal"],
|
|
289
|
-
},
|
|
290
|
-
};
|
|
291
|
-
Playground.args = {
|
|
292
|
-
layout: "vertical",
|
|
293
|
-
};
|
|
@@ -1,245 +0,0 @@
|
|
|
1
|
-
import { describe, expect, test } from "vitest";
|
|
2
|
-
import { page } from "vitest/browser";
|
|
3
|
-
import { render } from "vitest-browser-react";
|
|
4
|
-
import { Button } from "../../atoms/button";
|
|
5
|
-
import {
|
|
6
|
-
Card,
|
|
7
|
-
CardActions,
|
|
8
|
-
CardBody,
|
|
9
|
-
CardContent,
|
|
10
|
-
CardDescription,
|
|
11
|
-
CardEyebrow,
|
|
12
|
-
CardImage,
|
|
13
|
-
CardTitle,
|
|
14
|
-
} from "./card";
|
|
15
|
-
|
|
16
|
-
describe("Card", () => {
|
|
17
|
-
describe("Accessibility", () => {
|
|
18
|
-
test("CardTitle renders as h3 heading by default", async () => {
|
|
19
|
-
render(
|
|
20
|
-
<Card>
|
|
21
|
-
<CardContent>
|
|
22
|
-
<CardBody>
|
|
23
|
-
<CardTitle>Test Title</CardTitle>
|
|
24
|
-
</CardBody>
|
|
25
|
-
</CardContent>
|
|
26
|
-
</Card>,
|
|
27
|
-
);
|
|
28
|
-
|
|
29
|
-
await expect
|
|
30
|
-
.element(page.getByRole("heading", { level: 3, name: "Test Title" }))
|
|
31
|
-
.toBeInTheDocument();
|
|
32
|
-
});
|
|
33
|
-
|
|
34
|
-
test("CardTitle supports as prop to change heading level", async () => {
|
|
35
|
-
render(
|
|
36
|
-
<Card>
|
|
37
|
-
<CardContent>
|
|
38
|
-
<CardBody>
|
|
39
|
-
<CardTitle as="h2">H2 Title</CardTitle>
|
|
40
|
-
</CardBody>
|
|
41
|
-
</CardContent>
|
|
42
|
-
</Card>,
|
|
43
|
-
);
|
|
44
|
-
|
|
45
|
-
await expect
|
|
46
|
-
.element(page.getByRole("heading", { level: 2, name: "H2 Title" }))
|
|
47
|
-
.toBeInTheDocument();
|
|
48
|
-
});
|
|
49
|
-
|
|
50
|
-
test("CardImage renders img with alt text when src provided", async () => {
|
|
51
|
-
render(
|
|
52
|
-
<Card>
|
|
53
|
-
<CardImage
|
|
54
|
-
src="https://example.com/image.jpg"
|
|
55
|
-
alt="Test image description"
|
|
56
|
-
/>
|
|
57
|
-
<CardContent>
|
|
58
|
-
<CardBody>
|
|
59
|
-
<CardTitle>Card with Image</CardTitle>
|
|
60
|
-
</CardBody>
|
|
61
|
-
</CardContent>
|
|
62
|
-
</Card>,
|
|
63
|
-
);
|
|
64
|
-
|
|
65
|
-
await expect
|
|
66
|
-
.element(page.getByRole("img", { name: "Test image description" }))
|
|
67
|
-
.toBeInTheDocument();
|
|
68
|
-
});
|
|
69
|
-
|
|
70
|
-
test("CardImage does not render img when no src provided", async () => {
|
|
71
|
-
render(
|
|
72
|
-
<Card>
|
|
73
|
-
<CardImage />
|
|
74
|
-
<CardContent>
|
|
75
|
-
<CardBody>
|
|
76
|
-
<CardTitle>Card without Image Source</CardTitle>
|
|
77
|
-
</CardBody>
|
|
78
|
-
</CardContent>
|
|
79
|
-
</Card>,
|
|
80
|
-
);
|
|
81
|
-
|
|
82
|
-
// Should not have an img element
|
|
83
|
-
const images = page.getByRole("img");
|
|
84
|
-
await expect.element(images).not.toBeInTheDocument();
|
|
85
|
-
});
|
|
86
|
-
|
|
87
|
-
test("buttons in CardActions are accessible", async () => {
|
|
88
|
-
render(
|
|
89
|
-
<Card>
|
|
90
|
-
<CardContent>
|
|
91
|
-
<CardBody>
|
|
92
|
-
<CardTitle>Card with Actions</CardTitle>
|
|
93
|
-
</CardBody>
|
|
94
|
-
<CardActions>
|
|
95
|
-
<Button>Primary Action</Button>
|
|
96
|
-
<Button variant="charcoalOutline">Secondary Action</Button>
|
|
97
|
-
</CardActions>
|
|
98
|
-
</CardContent>
|
|
99
|
-
</Card>,
|
|
100
|
-
);
|
|
101
|
-
|
|
102
|
-
await expect
|
|
103
|
-
.element(page.getByRole("button", { name: "Primary Action" }))
|
|
104
|
-
.toBeInTheDocument();
|
|
105
|
-
await expect
|
|
106
|
-
.element(page.getByRole("button", { name: "Secondary Action" }))
|
|
107
|
-
.toBeInTheDocument();
|
|
108
|
-
});
|
|
109
|
-
|
|
110
|
-
test("Card structure is semantically correct", async () => {
|
|
111
|
-
render(
|
|
112
|
-
<Card data-testid="card">
|
|
113
|
-
<CardContent>
|
|
114
|
-
<CardBody>
|
|
115
|
-
<CardEyebrow>Eyebrow Text</CardEyebrow>
|
|
116
|
-
<CardTitle>Card Title</CardTitle>
|
|
117
|
-
<CardDescription>Card description text</CardDescription>
|
|
118
|
-
</CardBody>
|
|
119
|
-
</CardContent>
|
|
120
|
-
</Card>,
|
|
121
|
-
);
|
|
122
|
-
|
|
123
|
-
// Verify all text content is present and readable
|
|
124
|
-
await expect.element(page.getByText("Eyebrow Text")).toBeInTheDocument();
|
|
125
|
-
await expect.element(page.getByText("Card Title")).toBeInTheDocument();
|
|
126
|
-
await expect
|
|
127
|
-
.element(page.getByText("Card description text"))
|
|
128
|
-
.toBeInTheDocument();
|
|
129
|
-
});
|
|
130
|
-
});
|
|
131
|
-
|
|
132
|
-
describe("Layout Variants", () => {
|
|
133
|
-
test("vertical layout applies correct classes", async () => {
|
|
134
|
-
render(
|
|
135
|
-
<Card layout="vertical" data-testid="card">
|
|
136
|
-
<CardContent>
|
|
137
|
-
<CardBody>
|
|
138
|
-
<CardTitle>Vertical Card</CardTitle>
|
|
139
|
-
</CardBody>
|
|
140
|
-
</CardContent>
|
|
141
|
-
</Card>,
|
|
142
|
-
);
|
|
143
|
-
|
|
144
|
-
const card = page.getByTestId("card");
|
|
145
|
-
await expect.element(card).toHaveClass(/flex-col/);
|
|
146
|
-
});
|
|
147
|
-
|
|
148
|
-
test("horizontal layout applies correct classes", async () => {
|
|
149
|
-
render(
|
|
150
|
-
<Card layout="horizontal" data-testid="card">
|
|
151
|
-
<CardContent>
|
|
152
|
-
<CardBody>
|
|
153
|
-
<CardTitle>Horizontal Card</CardTitle>
|
|
154
|
-
</CardBody>
|
|
155
|
-
</CardContent>
|
|
156
|
-
</Card>,
|
|
157
|
-
);
|
|
158
|
-
|
|
159
|
-
const card = page.getByTestId("card");
|
|
160
|
-
await expect.element(card).toHaveClass(/flex-row/);
|
|
161
|
-
});
|
|
162
|
-
|
|
163
|
-
test("default layout is vertical", async () => {
|
|
164
|
-
render(
|
|
165
|
-
<Card data-testid="card">
|
|
166
|
-
<CardContent>
|
|
167
|
-
<CardBody>
|
|
168
|
-
<CardTitle>Default Card</CardTitle>
|
|
169
|
-
</CardBody>
|
|
170
|
-
</CardContent>
|
|
171
|
-
</Card>,
|
|
172
|
-
);
|
|
173
|
-
|
|
174
|
-
const card = page.getByTestId("card");
|
|
175
|
-
await expect.element(card).toHaveClass(/flex-col/);
|
|
176
|
-
});
|
|
177
|
-
});
|
|
178
|
-
|
|
179
|
-
describe("Component Composition", () => {
|
|
180
|
-
test("renders complete card with all sub-components", async () => {
|
|
181
|
-
render(
|
|
182
|
-
<Card>
|
|
183
|
-
<CardImage src="https://example.com/test.jpg" alt="Test" />
|
|
184
|
-
<CardContent>
|
|
185
|
-
<CardBody>
|
|
186
|
-
<CardEyebrow>Category</CardEyebrow>
|
|
187
|
-
<CardTitle>Full Card Example</CardTitle>
|
|
188
|
-
<CardDescription>
|
|
189
|
-
This is a complete card with all components.
|
|
190
|
-
</CardDescription>
|
|
191
|
-
</CardBody>
|
|
192
|
-
<CardActions>
|
|
193
|
-
<Button>Action</Button>
|
|
194
|
-
</CardActions>
|
|
195
|
-
</CardContent>
|
|
196
|
-
</Card>,
|
|
197
|
-
);
|
|
198
|
-
|
|
199
|
-
await expect
|
|
200
|
-
.element(page.getByRole("img", { name: "Test" }))
|
|
201
|
-
.toBeInTheDocument();
|
|
202
|
-
await expect.element(page.getByText("Category")).toBeInTheDocument();
|
|
203
|
-
await expect
|
|
204
|
-
.element(page.getByRole("heading", { name: "Full Card Example" }))
|
|
205
|
-
.toBeInTheDocument();
|
|
206
|
-
await expect
|
|
207
|
-
.element(page.getByText("This is a complete card with all components."))
|
|
208
|
-
.toBeInTheDocument();
|
|
209
|
-
await expect
|
|
210
|
-
.element(page.getByRole("button", { name: "Action" }))
|
|
211
|
-
.toBeInTheDocument();
|
|
212
|
-
});
|
|
213
|
-
|
|
214
|
-
test("renders minimal card with only required components", async () => {
|
|
215
|
-
render(
|
|
216
|
-
<Card>
|
|
217
|
-
<CardContent>
|
|
218
|
-
<CardBody>
|
|
219
|
-
<CardTitle>Minimal</CardTitle>
|
|
220
|
-
</CardBody>
|
|
221
|
-
</CardContent>
|
|
222
|
-
</Card>,
|
|
223
|
-
);
|
|
224
|
-
|
|
225
|
-
await expect
|
|
226
|
-
.element(page.getByRole("heading", { name: "Minimal" }))
|
|
227
|
-
.toBeInTheDocument();
|
|
228
|
-
});
|
|
229
|
-
|
|
230
|
-
test("supports custom className on Card", async () => {
|
|
231
|
-
render(
|
|
232
|
-
<Card className="custom-class" data-testid="card">
|
|
233
|
-
<CardContent>
|
|
234
|
-
<CardBody>
|
|
235
|
-
<CardTitle>Custom Card</CardTitle>
|
|
236
|
-
</CardBody>
|
|
237
|
-
</CardContent>
|
|
238
|
-
</Card>,
|
|
239
|
-
);
|
|
240
|
-
|
|
241
|
-
const card = page.getByTestId("card");
|
|
242
|
-
await expect.element(card).toHaveClass(/custom-class/);
|
|
243
|
-
});
|
|
244
|
-
});
|
|
245
|
-
});
|