@nationaldesignstudio/react 0.3.0 → 0.5.0

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 (79) hide show
  1. package/dist/component-registry.md +1310 -127
  2. package/dist/components/atoms/button/button.d.ts +55 -47
  3. package/dist/components/atoms/button/button.figma.d.ts +1 -0
  4. package/dist/components/atoms/input/input.d.ts +24 -24
  5. package/dist/components/atoms/popover/popover.d.ts +195 -0
  6. package/dist/components/atoms/select/select.d.ts +24 -24
  7. package/dist/components/atoms/tooltip/tooltip.d.ts +161 -0
  8. package/dist/components/organisms/card/card.d.ts +1 -1
  9. package/dist/components/sections/hero/hero.d.ts +2 -2
  10. package/dist/components/sections/tout/tout.d.ts +3 -3
  11. package/dist/components/shared/floating-arrow.d.ts +34 -0
  12. package/dist/index.d.ts +8 -0
  13. package/dist/index.js +11602 -8499
  14. package/dist/index.js.map +1 -1
  15. package/dist/lib/form-control.d.ts +25 -24
  16. package/dist/tokens.css +4797 -3940
  17. package/package.json +2 -1
  18. package/src/components/atoms/accordion/accordion.stories.tsx +1 -1
  19. package/src/components/atoms/accordion/accordion.tsx +2 -2
  20. package/src/components/atoms/button/button.figma.tsx +37 -0
  21. package/src/components/atoms/button/button.stories.tsx +236 -140
  22. package/src/components/atoms/button/button.test.tsx +289 -5
  23. package/src/components/atoms/button/button.tsx +37 -33
  24. package/src/components/atoms/button/button.visual.test.tsx +26 -76
  25. package/src/components/atoms/button/icon-button.stories.tsx +44 -101
  26. package/src/components/atoms/button/icon-button.test.tsx +26 -94
  27. package/src/components/atoms/button/icon-button.tsx +3 -3
  28. package/src/components/atoms/input/input-group.stories.tsx +4 -8
  29. package/src/components/atoms/input/input-group.test.tsx +14 -28
  30. package/src/components/atoms/input/input-group.tsx +57 -32
  31. package/src/components/atoms/input/input.stories.tsx +14 -18
  32. package/src/components/atoms/input/input.test.tsx +4 -20
  33. package/src/components/atoms/input/input.tsx +16 -9
  34. package/src/components/atoms/pager-control/pager-control.stories.tsx +6 -8
  35. package/src/components/atoms/pager-control/pager-control.tsx +12 -12
  36. package/src/components/atoms/popover/index.ts +30 -0
  37. package/src/components/atoms/popover/popover.stories.tsx +531 -0
  38. package/src/components/atoms/popover/popover.test.tsx +486 -0
  39. package/src/components/atoms/popover/popover.tsx +488 -0
  40. package/src/components/atoms/select/select.tsx +12 -8
  41. package/src/components/atoms/tooltip/index.ts +24 -0
  42. package/src/components/atoms/tooltip/tooltip.stories.tsx +348 -0
  43. package/src/components/atoms/tooltip/tooltip.test.tsx +363 -0
  44. package/src/components/atoms/tooltip/tooltip.tsx +347 -0
  45. package/src/components/dev-tools/dev-toolbar/dev-toolbar.stories.tsx +8 -13
  46. package/src/components/dev-tools/dev-toolbar/dev-toolbar.tsx +3 -3
  47. package/src/components/organisms/card/card.stories.tsx +19 -19
  48. package/src/components/organisms/card/card.tsx +1 -1
  49. package/src/components/organisms/card/card.visual.test.tsx +11 -11
  50. package/src/components/organisms/navbar/navbar.visual.test.tsx +2 -2
  51. package/src/components/organisms/us-gov-banner/us-gov-banner.tsx +2 -2
  52. package/src/components/sections/banner/banner.stories.tsx +1 -5
  53. package/src/components/sections/banner/banner.test.tsx +2 -2
  54. package/src/components/sections/banner/banner.tsx +6 -6
  55. package/src/components/sections/card-grid/card-grid.tsx +4 -4
  56. package/src/components/sections/hero/hero.stories.tsx +7 -7
  57. package/src/components/sections/hero/hero.tsx +10 -11
  58. package/src/components/sections/prose/prose.tsx +2 -2
  59. package/src/components/sections/river/river.test.tsx +3 -3
  60. package/src/components/sections/river/river.tsx +6 -12
  61. package/src/components/sections/tout/tout.stories.tsx +7 -31
  62. package/src/components/sections/tout/tout.tsx +9 -9
  63. package/src/components/sections/two-column-section/two-column-section.tsx +7 -9
  64. package/src/components/shared/floating-arrow.tsx +78 -0
  65. package/src/components/shared/index.ts +5 -0
  66. package/src/index.ts +57 -0
  67. package/src/lib/form-control.ts +8 -6
  68. package/src/stories/grid-system.stories.tsx +309 -0
  69. package/src/stories/{ThemeProvider.stories.tsx → theme-provider.stories.tsx} +7 -19
  70. package/src/stories/{TokenShowcase.stories.tsx → token-showcase.stories.tsx} +1 -1
  71. package/src/stories/{TokenShowcase.tsx → token-showcase.tsx} +34 -34
  72. package/src/styles.css +3 -3
  73. package/src/tests/token-resolution.test.tsx +6 -9
  74. package/src/theme/hooks.ts +1 -1
  75. package/src/theme/index.ts +1 -1
  76. package/src/theme/theme-provider.test.tsx +270 -0
  77. package/src/theme/{ThemeProvider.tsx → theme-provider.tsx} +18 -2
  78. package/src/stories/GridSystem.stories.tsx +0 -84
  79. /package/src/stories/{Introduction.mdx → introduction.mdx} +0 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nationaldesignstudio/react",
3
- "version": "0.3.0",
3
+ "version": "0.5.0",
4
4
  "type": "module",
5
5
  "sideEffects": [
6
6
  "*.css"
@@ -51,6 +51,7 @@
51
51
  },
52
52
  "devDependencies": {
53
53
  "@chromatic-com/storybook": "catalog:",
54
+ "@figma/code-connect": "^1.3.12",
54
55
  "@nds-design-system/tailwind-token-generator": "workspace:*",
55
56
  "@nds-design-system/tokens": "workspace:*",
56
57
  "@nds-design-system/tools": "workspace:*",
@@ -19,7 +19,7 @@ const meta: Meta<typeof Accordion> = {
19
19
  },
20
20
  decorators: [
21
21
  (Story) => (
22
- <div className="p-spacing-56 max-w-[746px]">
22
+ <div className="p-56 max-w-[746px]">
23
23
  <Story />
24
24
  </div>
25
25
  ),
@@ -38,7 +38,7 @@ const accordionItemVariants = tv({
38
38
  const accordionTriggerVariants = tv({
39
39
  base: [
40
40
  // Uses primitive spacing tokens
41
- "flex w-full items-center justify-between py-spacing-24 text-left",
41
+ "flex w-full items-center justify-between py-24 text-left",
42
42
  "typography-body-large transition-colors cursor-pointer",
43
43
  ],
44
44
  variants: {
@@ -54,7 +54,7 @@ const accordionTriggerVariants = tv({
54
54
 
55
55
  const accordionPanelVariants = tv({
56
56
  // Uses primitive spacing tokens
57
- base: "typography-body-large pb-spacing-24",
57
+ base: "typography-body-large pb-24",
58
58
  variants: {
59
59
  colorScheme: {
60
60
  dark: "text-gray-100",
@@ -0,0 +1,37 @@
1
+ import figma from "@figma/code-connect";
2
+ import { Button } from "./button";
3
+
4
+ figma.connect(
5
+ Button,
6
+ "https://www.figma.com/design/nvGqlGFXelQ5XdjEM5RCdK/Americas-Design-System?node-id=27103-21020",
7
+ {
8
+ props: {
9
+ variant: figma.enum("Variant", {
10
+ Primary: "primary",
11
+ Default: "default",
12
+ Secondary: "secondary",
13
+ Destructive: "destructive",
14
+ Outline: "outline",
15
+ Ghost: "ghost",
16
+ Link: "link",
17
+ }),
18
+ size: figma.enum("Size", {
19
+ sm: "sm",
20
+ default: "default",
21
+ lg: "lg",
22
+ }),
23
+ disabled: figma.enum("State", {
24
+ Disabled: true,
25
+ }),
26
+ },
27
+ example: (props) => (
28
+ <Button
29
+ variant={props.variant}
30
+ size={props.size}
31
+ disabled={props.disabled}
32
+ >
33
+ Button
34
+ </Button>
35
+ ),
36
+ },
37
+ );
@@ -3,191 +3,287 @@ import { Button } from ".";
3
3
 
4
4
  const meta: Meta<typeof Button> = {
5
5
  title: "Atoms/Button",
6
- } as Meta<typeof Button>;
6
+ component: Button,
7
+ argTypes: {
8
+ variant: {
9
+ control: { type: "select" },
10
+ options: [
11
+ "primary",
12
+ "default",
13
+ "secondary",
14
+ "destructive",
15
+ "outline",
16
+ "ghost",
17
+ "link",
18
+ ],
19
+ },
20
+ size: {
21
+ control: { type: "select" },
22
+ options: ["sm", "default", "lg"],
23
+ },
24
+ disabled: {
25
+ control: { type: "boolean" },
26
+ },
27
+ },
28
+ args: {
29
+ variant: "default",
30
+ size: "default",
31
+ disabled: false,
32
+ },
33
+ } satisfies Meta<typeof Button>;
7
34
 
8
35
  export default meta;
9
36
  type Story = StoryObj<typeof Button>;
10
37
 
38
+ // =============================================================================
39
+ // Playground
40
+ // =============================================================================
41
+
11
42
  export const Playground: Story = {
12
43
  render: (args) => <Button {...args}>Button</Button>,
13
44
  };
14
- Playground.argTypes = {
15
- size: {
16
- control: {
17
- type: "radio",
18
- },
19
- options: ["sm", "default", "lg"],
20
- },
21
- disabled: {
22
- control: {
23
- type: "boolean",
24
- },
25
- },
26
- variant: {
27
- control: {
28
- type: "radio",
29
- },
30
- options: ["solid", "outline", "ghost", "subtle"],
31
- },
32
- colorScheme: {
33
- control: {
34
- type: "radio",
35
- },
36
- options: ["dark", "light"],
37
- },
38
- };
39
- Playground.args = {
40
- size: "default",
41
- disabled: false,
42
- variant: "solid",
43
- colorScheme: "dark",
44
- };
45
45
 
46
46
  // =============================================================================
47
- // Variants (Dark Color Scheme - for light backgrounds)
48
- // Figma naming: Charcoal = solid+dark, Charcoal Outline = outline+dark
47
+ // All Variants
49
48
  // =============================================================================
50
49
 
51
50
  /**
52
- * Solid Dark (Figma: "Charcoal" / "Black")
53
- * Primary filled button with ui-button-primary-bg background and inverted text.
54
- * Use on light backgrounds for primary actions.
51
+ * All button variants in a single view.
52
+ * Matches Figma Button component variants.
55
53
  */
56
- export const Solid = () => <Button variant="solid">Solid</Button>;
54
+ export const AllVariants: Story = {
55
+ render: () => (
56
+ <div className="flex flex-col gap-24">
57
+ <div className="flex items-center gap-16">
58
+ <Button variant="primary">Primary</Button>
59
+ <Button variant="default">Default</Button>
60
+ <Button variant="secondary">Secondary</Button>
61
+ <Button variant="destructive">Destructive</Button>
62
+ <Button variant="outline">Outline</Button>
63
+ <Button variant="ghost">Ghost</Button>
64
+ <Button variant="link">Link</Button>
65
+ </div>
66
+ </div>
67
+ ),
68
+ };
69
+
70
+ // =============================================================================
71
+ // Individual Variants
72
+ // =============================================================================
57
73
 
58
74
  /**
59
- * Outline Dark (Figma: "Charcoal Outline")
60
- * Primary-colored border and text on transparent background.
61
- * Use on light backgrounds for secondary actions.
75
+ * Primary button - Blue filled for primary actions.
76
+ * Use for the main call-to-action.
62
77
  */
63
- export const Outline = () => <Button variant="outline">Outline</Button>;
78
+ export const Primary: Story = {
79
+ render: () => <Button variant="primary">Primary</Button>,
80
+ };
64
81
 
65
82
  /**
66
- * Ghost Dark
67
- * Primary-colored text with no border or background.
68
- * Use for tertiary actions on light backgrounds.
83
+ * Default button - Dark filled for secondary prominence.
84
+ * Use for important but not primary actions.
69
85
  */
70
- export const Ghost = () => <Button variant="ghost">Ghost</Button>;
86
+ export const Default: Story = {
87
+ render: () => <Button variant="default">Default</Button>,
88
+ };
71
89
 
72
90
  /**
73
- * Subtle Dark
74
- * Subtle border with primary-colored text.
75
- * Use for less prominent actions on light backgrounds.
91
+ * Secondary button - Light gray filled with subtle border.
92
+ * Use for less prominent actions.
76
93
  */
77
- export const Subtle = () => <Button variant="subtle">Subtle</Button>;
78
-
79
- // =============================================================================
80
- // Variants (Light Color Scheme - for dark backgrounds)
81
- // Figma naming: Ivory = solid+light, Ivory Outline = outline+light
82
- // =============================================================================
83
-
84
- const DarkBackground = ({ children }: { children: React.ReactNode }) => (
85
- <div className="rounded-radius-12 bg-gray-1200 p-spacing-32">{children}</div>
86
- );
94
+ export const Secondary: Story = {
95
+ render: () => <Button variant="secondary">Secondary</Button>,
96
+ };
87
97
 
88
98
  /**
89
- * Solid Light (Figma: "Ivory")
90
- * White filled button with primary-colored text.
91
- * Use on dark backgrounds for primary actions.
99
+ * Destructive button - Red filled for destructive actions.
100
+ * Use for delete, remove, or other destructive actions.
92
101
  */
93
- export const SolidLight = () => (
94
- <DarkBackground>
95
- <Button variant="solid" colorScheme="light">
96
- Solid Light
97
- </Button>
98
- </DarkBackground>
99
- );
102
+ export const Destructive: Story = {
103
+ render: () => <Button variant="destructive">Destructive</Button>,
104
+ };
100
105
 
101
106
  /**
102
- * Outline Light (Figma: "Ivory Outline")
103
- * White border and text on transparent background.
104
- * Use on dark backgrounds for secondary actions.
107
+ * Outline button - Bordered with transparent background.
108
+ * Use for secondary actions that need clear boundaries.
105
109
  */
106
- export const OutlineLight = () => (
107
- <DarkBackground>
108
- <Button variant="outline" colorScheme="light">
109
- Outline Light
110
- </Button>
111
- </DarkBackground>
112
- );
110
+ export const Outline: Story = {
111
+ render: () => <Button variant="outline">Outline</Button>,
112
+ };
113
113
 
114
114
  /**
115
- * Ghost Light
116
- * White text with no border or background.
117
- * Use for tertiary actions on dark backgrounds.
115
+ * Ghost button - Transparent with subtle hover.
116
+ * Use for tertiary actions or in toolbars.
118
117
  */
119
- export const GhostLight = () => (
120
- <DarkBackground>
121
- <Button variant="ghost" colorScheme="light">
122
- Ghost Light
123
- </Button>
124
- </DarkBackground>
125
- );
118
+ export const Ghost: Story = {
119
+ render: () => <Button variant="ghost">Ghost</Button>,
120
+ };
126
121
 
127
122
  /**
128
- * Subtle Light
129
- * Alpha-white border with white text.
130
- * Use for less prominent actions on dark backgrounds.
123
+ * Link button - Text only with underline on hover.
124
+ * Use for navigation or inline actions.
131
125
  */
132
- export const SubtleLight = () => (
133
- <DarkBackground>
134
- <Button variant="subtle" colorScheme="light">
135
- Subtle Light
136
- </Button>
137
- </DarkBackground>
138
- );
126
+ export const Link: Story = {
127
+ render: () => <Button variant="link">Link</Button>,
128
+ };
139
129
 
140
130
  // =============================================================================
141
- // All Variants Comparison
131
+ // Sizes
142
132
  // =============================================================================
143
133
 
144
- export const AllVariants = () => (
145
- <div className="flex flex-col gap-spacing-32">
146
- <div>
147
- <h3 className="mb-spacing-16 text-14 font-medium text-text-secondary">
148
- Dark Color Scheme (for light backgrounds)
149
- </h3>
150
- <div className="flex gap-spacing-16">
151
- <Button variant="solid">Solid</Button>
152
- <Button variant="outline">Outline</Button>
153
- <Button variant="ghost">Ghost</Button>
154
- <Button variant="subtle">Subtle</Button>
155
- </div>
134
+ /**
135
+ * All button sizes.
136
+ * Matches Figma Button component sizes: sm (32px), default (36px), lg (40px).
137
+ */
138
+ export const AllSizes: Story = {
139
+ render: () => (
140
+ <div className="flex items-center gap-16">
141
+ <Button size="sm">Small</Button>
142
+ <Button size="default">Default</Button>
143
+ <Button size="lg">Large</Button>
156
144
  </div>
157
- <DarkBackground>
158
- <h3 className="mb-spacing-16 text-14 font-medium text-gray-400">
159
- Light Color Scheme (for dark backgrounds)
160
- </h3>
161
- <div className="flex gap-spacing-16">
162
- <Button variant="solid" colorScheme="light">
163
- Solid
164
- </Button>
165
- <Button variant="outline" colorScheme="light">
166
- Outline
167
- </Button>
168
- <Button variant="ghost" colorScheme="light">
169
- Ghost
170
- </Button>
171
- <Button variant="subtle" colorScheme="light">
172
- Subtle
173
- </Button>
174
- </div>
175
- </DarkBackground>
176
- </div>
177
- );
145
+ ),
146
+ };
147
+
148
+ export const Small: Story = {
149
+ render: () => <Button size="sm">Small</Button>,
150
+ };
151
+
152
+ export const Medium: Story = {
153
+ render: () => <Button size="default">Default</Button>,
154
+ };
155
+
156
+ export const Large: Story = {
157
+ render: () => <Button size="lg">Large</Button>,
158
+ };
178
159
 
179
160
  // =============================================================================
180
- // Sizes
161
+ // States
181
162
  // =============================================================================
182
163
 
183
- export const Small = () => <Button size="sm">Small</Button>;
184
-
185
- export const Medium = () => <Button size="default">Medium</Button>;
164
+ /**
165
+ * Disabled state for all variants.
166
+ */
167
+ export const Disabled: Story = {
168
+ render: () => <Button disabled>Disabled</Button>,
169
+ };
186
170
 
187
- export const Large = () => <Button size="lg">Large</Button>;
171
+ export const DisabledVariants: Story = {
172
+ render: () => (
173
+ <div className="flex items-center gap-16">
174
+ <Button variant="primary" disabled>
175
+ Primary
176
+ </Button>
177
+ <Button variant="default" disabled>
178
+ Default
179
+ </Button>
180
+ <Button variant="secondary" disabled>
181
+ Secondary
182
+ </Button>
183
+ <Button variant="destructive" disabled>
184
+ Destructive
185
+ </Button>
186
+ <Button variant="outline" disabled>
187
+ Outline
188
+ </Button>
189
+ <Button variant="ghost" disabled>
190
+ Ghost
191
+ </Button>
192
+ <Button variant="link" disabled>
193
+ Link
194
+ </Button>
195
+ </div>
196
+ ),
197
+ };
188
198
 
189
199
  // =============================================================================
190
- // States
200
+ // Size Variants Matrix
191
201
  // =============================================================================
192
202
 
193
- export const Disabled = () => <Button disabled>Disabled</Button>;
203
+ /**
204
+ * Matrix showing all variants at all sizes.
205
+ */
206
+ export const VariantSizeMatrix: Story = {
207
+ render: () => (
208
+ <div className="flex flex-col gap-24">
209
+ <div>
210
+ <h3 className="mb-12 text-14 font-medium text-gray-600">Small</h3>
211
+ <div className="flex items-center gap-12">
212
+ <Button variant="primary" size="sm">
213
+ Primary
214
+ </Button>
215
+ <Button variant="default" size="sm">
216
+ Default
217
+ </Button>
218
+ <Button variant="secondary" size="sm">
219
+ Secondary
220
+ </Button>
221
+ <Button variant="destructive" size="sm">
222
+ Destructive
223
+ </Button>
224
+ <Button variant="outline" size="sm">
225
+ Outline
226
+ </Button>
227
+ <Button variant="ghost" size="sm">
228
+ Ghost
229
+ </Button>
230
+ <Button variant="link" size="sm">
231
+ Link
232
+ </Button>
233
+ </div>
234
+ </div>
235
+ <div>
236
+ <h3 className="mb-12 text-14 font-medium text-gray-600">Default</h3>
237
+ <div className="flex items-center gap-12">
238
+ <Button variant="primary" size="default">
239
+ Primary
240
+ </Button>
241
+ <Button variant="default" size="default">
242
+ Default
243
+ </Button>
244
+ <Button variant="secondary" size="default">
245
+ Secondary
246
+ </Button>
247
+ <Button variant="destructive" size="default">
248
+ Destructive
249
+ </Button>
250
+ <Button variant="outline" size="default">
251
+ Outline
252
+ </Button>
253
+ <Button variant="ghost" size="default">
254
+ Ghost
255
+ </Button>
256
+ <Button variant="link" size="default">
257
+ Link
258
+ </Button>
259
+ </div>
260
+ </div>
261
+ <div>
262
+ <h3 className="mb-12 text-14 font-medium text-gray-600">Large</h3>
263
+ <div className="flex items-center gap-12">
264
+ <Button variant="primary" size="lg">
265
+ Primary
266
+ </Button>
267
+ <Button variant="default" size="lg">
268
+ Default
269
+ </Button>
270
+ <Button variant="secondary" size="lg">
271
+ Secondary
272
+ </Button>
273
+ <Button variant="destructive" size="lg">
274
+ Destructive
275
+ </Button>
276
+ <Button variant="outline" size="lg">
277
+ Outline
278
+ </Button>
279
+ <Button variant="ghost" size="lg">
280
+ Ghost
281
+ </Button>
282
+ <Button variant="link" size="lg">
283
+ Link
284
+ </Button>
285
+ </div>
286
+ </div>
287
+ </div>
288
+ ),
289
+ };