@nationaldesignstudio/react 0.5.2 → 0.5.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (160) hide show
  1. package/package.json +10 -2
  2. package/src/App.css +0 -0
  3. package/src/App.tsx +0 -7
  4. package/src/assets/fonts/PPNeueMontreal-Variable.woff2 +0 -0
  5. package/src/assets/react.svg +0 -1
  6. package/src/components/atoms/accordion/accordion.stories.tsx +0 -228
  7. package/src/components/atoms/accordion/accordion.test.tsx +0 -231
  8. package/src/components/atoms/accordion/index.ts +0 -6
  9. package/src/components/atoms/background/background.test.tsx +0 -213
  10. package/src/components/atoms/background/index.ts +0 -22
  11. package/src/components/atoms/button/__screenshots__/button.visual.test.tsx/button-charcoal-chromium-darwin.png +0 -0
  12. package/src/components/atoms/button/__screenshots__/button.visual.test.tsx/button-charcoal-chromium-linux.png +0 -0
  13. package/src/components/atoms/button/__screenshots__/button.visual.test.tsx/button-charcoal-outline-chromium-darwin.png +0 -0
  14. package/src/components/atoms/button/__screenshots__/button.visual.test.tsx/button-charcoal-outline-chromium-linux.png +0 -0
  15. package/src/components/atoms/button/__screenshots__/button.visual.test.tsx/button-charcoal-outline-quiet-chromium-darwin.png +0 -0
  16. package/src/components/atoms/button/__screenshots__/button.visual.test.tsx/button-charcoal-outline-quiet-chromium-linux.png +0 -0
  17. package/src/components/atoms/button/__screenshots__/button.visual.test.tsx/button-disabled-chromium-darwin.png +0 -0
  18. package/src/components/atoms/button/__screenshots__/button.visual.test.tsx/button-disabled-chromium-linux.png +0 -0
  19. package/src/components/atoms/button/__screenshots__/button.visual.test.tsx/button-ivory-chromium-darwin.png +0 -0
  20. package/src/components/atoms/button/__screenshots__/button.visual.test.tsx/button-ivory-chromium-linux.png +0 -0
  21. package/src/components/atoms/button/__screenshots__/button.visual.test.tsx/button-ivory-outline-chromium-darwin.png +0 -0
  22. package/src/components/atoms/button/__screenshots__/button.visual.test.tsx/button-ivory-outline-chromium-linux.png +0 -0
  23. package/src/components/atoms/button/__screenshots__/button.visual.test.tsx/button-ivory-outline-quiet-chromium-darwin.png +0 -0
  24. package/src/components/atoms/button/__screenshots__/button.visual.test.tsx/button-ivory-outline-quiet-chromium-linux.png +0 -0
  25. package/src/components/atoms/button/__screenshots__/button.visual.test.tsx/button-size-large-chromium-darwin.png +0 -0
  26. package/src/components/atoms/button/__screenshots__/button.visual.test.tsx/button-size-large-chromium-linux.png +0 -0
  27. package/src/components/atoms/button/__screenshots__/button.visual.test.tsx/button-size-medium-chromium-darwin.png +0 -0
  28. package/src/components/atoms/button/__screenshots__/button.visual.test.tsx/button-size-medium-chromium-linux.png +0 -0
  29. package/src/components/atoms/button/__screenshots__/button.visual.test.tsx/button-size-small-chromium-darwin.png +0 -0
  30. package/src/components/atoms/button/__screenshots__/button.visual.test.tsx/button-size-small-chromium-linux.png +0 -0
  31. package/src/components/atoms/button/button.stories.tsx +0 -289
  32. package/src/components/atoms/button/button.test.tsx +0 -419
  33. package/src/components/atoms/button/button.visual.test.tsx +0 -98
  34. package/src/components/atoms/button/icon-button.stories.tsx +0 -260
  35. package/src/components/atoms/button/icon-button.test.tsx +0 -186
  36. package/src/components/atoms/button/index.ts +0 -6
  37. package/src/components/atoms/input/index.ts +0 -17
  38. package/src/components/atoms/input/input-group.stories.tsx +0 -646
  39. package/src/components/atoms/input/input-group.test.tsx +0 -362
  40. package/src/components/atoms/input/input.stories.tsx +0 -228
  41. package/src/components/atoms/input/input.test.tsx +0 -167
  42. package/src/components/atoms/ndstudio-footer/index.ts +0 -1
  43. package/src/components/atoms/pager-control/index.ts +0 -5
  44. package/src/components/atoms/pager-control/pager-control.stories.tsx +0 -207
  45. package/src/components/atoms/pager-control/pager-control.test.tsx +0 -130
  46. package/src/components/atoms/popover/index.ts +0 -30
  47. package/src/components/atoms/popover/popover.stories.tsx +0 -531
  48. package/src/components/atoms/popover/popover.test.tsx +0 -486
  49. package/src/components/atoms/select/index.ts +0 -18
  50. package/src/components/atoms/select/select.stories.tsx +0 -455
  51. package/src/components/atoms/tooltip/index.ts +0 -24
  52. package/src/components/atoms/tooltip/tooltip.stories.tsx +0 -348
  53. package/src/components/atoms/tooltip/tooltip.test.tsx +0 -363
  54. package/src/components/dev-tools/dev-toolbar/dev-toolbar.stories.tsx +0 -73
  55. package/src/components/dev-tools/dev-toolbar/index.ts +0 -1
  56. package/src/components/dev-tools/grid-overlay/index.ts +0 -1
  57. package/src/components/dev-tools/index.ts +0 -2
  58. package/src/components/foundation/typography/typography.stories.tsx +0 -401
  59. package/src/components/organisms/card/__screenshots__/card.visual.test.tsx/card-default-vertical-chromium-darwin.png +0 -0
  60. package/src/components/organisms/card/__screenshots__/card.visual.test.tsx/card-default-vertical-chromium-linux.png +0 -0
  61. package/src/components/organisms/card/__screenshots__/card.visual.test.tsx/card-horizontal-chromium-darwin.png +0 -0
  62. package/src/components/organisms/card/__screenshots__/card.visual.test.tsx/card-horizontal-chromium-linux.png +0 -0
  63. package/src/components/organisms/card/__screenshots__/card.visual.test.tsx/card-minimal-chromium-darwin.png +0 -0
  64. package/src/components/organisms/card/__screenshots__/card.visual.test.tsx/card-minimal-chromium-linux.png +0 -0
  65. package/src/components/organisms/card/__screenshots__/card.visual.test.tsx/card-without-actions-chromium-darwin.png +0 -0
  66. package/src/components/organisms/card/__screenshots__/card.visual.test.tsx/card-without-actions-chromium-linux.png +0 -0
  67. package/src/components/organisms/card/__screenshots__/card.visual.test.tsx/card-without-eyebrow-chromium-darwin.png +0 -0
  68. package/src/components/organisms/card/__screenshots__/card.visual.test.tsx/card-without-eyebrow-chromium-linux.png +0 -0
  69. package/src/components/organisms/card/__screenshots__/card.visual.test.tsx/card-without-image-chromium-darwin.png +0 -0
  70. package/src/components/organisms/card/__screenshots__/card.visual.test.tsx/card-without-image-chromium-linux.png +0 -0
  71. package/src/components/organisms/card/card.stories.tsx +0 -293
  72. package/src/components/organisms/card/card.test.tsx +0 -247
  73. package/src/components/organisms/card/card.visual.test.tsx +0 -197
  74. package/src/components/organisms/card/index.ts +0 -26
  75. package/src/components/organisms/navbar/__screenshots__/navbar.visual.test.tsx/navbar-active-link-chromium-darwin.png +0 -0
  76. package/src/components/organisms/navbar/__screenshots__/navbar.visual.test.tsx/navbar-active-link-chromium-linux.png +0 -0
  77. package/src/components/organisms/navbar/__screenshots__/navbar.visual.test.tsx/navbar-brand-only-chromium-darwin.png +0 -0
  78. package/src/components/organisms/navbar/__screenshots__/navbar.visual.test.tsx/navbar-brand-only-chromium-linux.png +0 -0
  79. package/src/components/organisms/navbar/__screenshots__/navbar.visual.test.tsx/navbar-default-chromium-darwin.png +0 -0
  80. package/src/components/organisms/navbar/__screenshots__/navbar.visual.test.tsx/navbar-default-chromium-linux.png +0 -0
  81. package/src/components/organisms/navbar/index.ts +0 -18
  82. package/src/components/organisms/navbar/navbar.stories.tsx +0 -313
  83. package/src/components/organisms/navbar/navbar.test.tsx +0 -190
  84. package/src/components/organisms/navbar/navbar.visual.test.tsx +0 -85
  85. package/src/components/organisms/us-gov-banner/__screenshots__/us-gov-banner.visual.test.tsx/us-gov-banner-custom-icon-chromium-darwin.png +0 -0
  86. package/src/components/organisms/us-gov-banner/__screenshots__/us-gov-banner.visual.test.tsx/us-gov-banner-custom-icon-chromium-linux.png +0 -0
  87. package/src/components/organisms/us-gov-banner/__screenshots__/us-gov-banner.visual.test.tsx/us-gov-banner-custom-text-chromium-darwin.png +0 -0
  88. package/src/components/organisms/us-gov-banner/__screenshots__/us-gov-banner.visual.test.tsx/us-gov-banner-custom-text-chromium-linux.png +0 -0
  89. package/src/components/organisms/us-gov-banner/__screenshots__/us-gov-banner.visual.test.tsx/us-gov-banner-default-chromium-darwin.png +0 -0
  90. package/src/components/organisms/us-gov-banner/__screenshots__/us-gov-banner.visual.test.tsx/us-gov-banner-default-chromium-linux.png +0 -0
  91. package/src/components/organisms/us-gov-banner/index.ts +0 -5
  92. package/src/components/organisms/us-gov-banner/us-gov-banner.stories.tsx +0 -35
  93. package/src/components/organisms/us-gov-banner/us-gov-banner.test.tsx +0 -107
  94. package/src/components/organisms/us-gov-banner/us-gov-banner.visual.test.tsx +0 -46
  95. package/src/components/sections/banner/banner.stories.tsx +0 -150
  96. package/src/components/sections/banner/banner.test.tsx +0 -185
  97. package/src/components/sections/banner/index.ts +0 -2
  98. package/src/components/sections/card-grid/card-grid.stories.tsx +0 -351
  99. package/src/components/sections/card-grid/index.ts +0 -1
  100. package/src/components/sections/faq-section/faq-section.stories.tsx +0 -453
  101. package/src/components/sections/faq-section/index.ts +0 -2
  102. package/src/components/sections/hero/__screenshots__/hero.visual.test.tsx/hero-a1-desktop-chromium-darwin.png +0 -0
  103. package/src/components/sections/hero/__screenshots__/hero.visual.test.tsx/hero-a1-desktop-chromium-linux.png +0 -0
  104. package/src/components/sections/hero/__screenshots__/hero.visual.test.tsx/hero-a1-mobile-chromium-darwin.png +0 -0
  105. package/src/components/sections/hero/__screenshots__/hero.visual.test.tsx/hero-a1-mobile-chromium-linux.png +0 -0
  106. package/src/components/sections/hero/__screenshots__/hero.visual.test.tsx/hero-a1-tablet-chromium-darwin.png +0 -0
  107. package/src/components/sections/hero/__screenshots__/hero.visual.test.tsx/hero-a1-tablet-chromium-linux.png +0 -0
  108. package/src/components/sections/hero/__screenshots__/hero.visual.test.tsx/hero-a2-desktop-chromium-darwin.png +0 -0
  109. package/src/components/sections/hero/__screenshots__/hero.visual.test.tsx/hero-a2-desktop-chromium-linux.png +0 -0
  110. package/src/components/sections/hero/__screenshots__/hero.visual.test.tsx/hero-a2-mobile-chromium-darwin.png +0 -0
  111. package/src/components/sections/hero/__screenshots__/hero.visual.test.tsx/hero-a2-mobile-chromium-linux.png +0 -0
  112. package/src/components/sections/hero/__screenshots__/hero.visual.test.tsx/hero-a2-tablet-chromium-darwin.png +0 -0
  113. package/src/components/sections/hero/__screenshots__/hero.visual.test.tsx/hero-a2-tablet-chromium-linux.png +0 -0
  114. package/src/components/sections/hero/__screenshots__/hero.visual.test.tsx/hero-a3-desktop-chromium-darwin.png +0 -0
  115. package/src/components/sections/hero/__screenshots__/hero.visual.test.tsx/hero-a3-desktop-chromium-linux.png +0 -0
  116. package/src/components/sections/hero/__screenshots__/hero.visual.test.tsx/hero-a3-mobile-chromium-darwin.png +0 -0
  117. package/src/components/sections/hero/__screenshots__/hero.visual.test.tsx/hero-a3-mobile-chromium-linux.png +0 -0
  118. package/src/components/sections/hero/__screenshots__/hero.visual.test.tsx/hero-a3-tablet-chromium-darwin.png +0 -0
  119. package/src/components/sections/hero/__screenshots__/hero.visual.test.tsx/hero-a3-tablet-chromium-linux.png +0 -0
  120. package/src/components/sections/hero/__screenshots__/hero.visual.test.tsx/hero-custom-class-chromium-darwin.png +0 -0
  121. package/src/components/sections/hero/__screenshots__/hero.visual.test.tsx/hero-custom-class-chromium-linux.png +0 -0
  122. package/src/components/sections/hero/__screenshots__/hero.visual.test.tsx/hero-default-chromium-linux.png +0 -0
  123. package/src/components/sections/hero/__screenshots__/hero.visual.test.tsx/hero-long-title-chromium-darwin.png +0 -0
  124. package/src/components/sections/hero/__screenshots__/hero.visual.test.tsx/hero-long-title-chromium-linux.png +0 -0
  125. package/src/components/sections/hero/hero.stories.tsx +0 -397
  126. package/src/components/sections/hero/hero.test.tsx +0 -138
  127. package/src/components/sections/hero/hero.visual.test.tsx +0 -140
  128. package/src/components/sections/hero/index.ts +0 -23
  129. package/src/components/sections/prose/__screenshots__/prose.visual.test.tsx/prose-h3-heading-chromium-darwin.png +0 -0
  130. package/src/components/sections/prose/__screenshots__/prose.visual.test.tsx/prose-h3-heading-chromium-linux.png +0 -0
  131. package/src/components/sections/prose/__screenshots__/prose.visual.test.tsx/prose-multiple-paragraphs-chromium-darwin.png +0 -0
  132. package/src/components/sections/prose/__screenshots__/prose.visual.test.tsx/prose-multiple-paragraphs-chromium-linux.png +0 -0
  133. package/src/components/sections/prose/__screenshots__/prose.visual.test.tsx/prose-multiple-sections-chromium-darwin.png +0 -0
  134. package/src/components/sections/prose/__screenshots__/prose.visual.test.tsx/prose-multiple-sections-chromium-linux.png +0 -0
  135. package/src/components/sections/prose/__screenshots__/prose.visual.test.tsx/prose-single-section-chromium-darwin.png +0 -0
  136. package/src/components/sections/prose/__screenshots__/prose.visual.test.tsx/prose-single-section-chromium-linux.png +0 -0
  137. package/src/components/sections/prose/index.ts +0 -6
  138. package/src/components/sections/prose/prose.stories.tsx +0 -144
  139. package/src/components/sections/prose/prose.test.tsx +0 -178
  140. package/src/components/sections/prose/prose.visual.test.tsx +0 -105
  141. package/src/components/sections/quote-block/index.ts +0 -5
  142. package/src/components/sections/river/index.ts +0 -1
  143. package/src/components/sections/river/river.stories.tsx +0 -237
  144. package/src/components/sections/river/river.test.tsx +0 -268
  145. package/src/components/sections/tout/index.ts +0 -1
  146. package/src/components/sections/tout/tout.stories.tsx +0 -171
  147. package/src/components/sections/tout/tout.test.tsx +0 -242
  148. package/src/components/sections/two-column-section/index.ts +0 -5
  149. package/src/components/sections/two-column-section/two-column-section.stories.tsx +0 -285
  150. package/src/components/shared/index.ts +0 -5
  151. package/src/index.ts +0 -293
  152. package/src/main.tsx +0 -13
  153. package/src/stories/grid-system.stories.tsx +0 -309
  154. package/src/stories/introduction.mdx +0 -128
  155. package/src/stories/theme-provider.stories.tsx +0 -349
  156. package/src/stories/token-showcase.stories.tsx +0 -73
  157. package/src/stories/token-showcase.tsx +0 -777
  158. package/src/styles.css +0 -14
  159. package/src/tests/token-resolution.test.tsx +0 -298
  160. package/src/theme/theme-provider.test.tsx +0 -270
package/src/styles.css DELETED
@@ -1,14 +0,0 @@
1
- /* Google Fonts - must be first to comply with CSS @import ordering rules */
2
- @import url("https://fonts.googleapis.com/css2?family=Inter:wght@100..900&family=Inter+Tight:wght@100..900&display=swap");
3
-
4
- @import "tailwindcss";
5
- @import "../../tailwind-token-generator/dist/tokens.css";
6
-
7
- @font-face {
8
- font-family: "PP Neue Montreal";
9
- src: url("./assets/fonts/PPNeueMontreal-Variable.woff2")
10
- format("woff2-variations");
11
- font-weight: 100 900;
12
- font-style: normal;
13
- font-display: swap;
14
- }
@@ -1,298 +0,0 @@
1
- /**
2
- * Token Resolution Tests
3
- *
4
- * These tests verify that CSS classes using design tokens resolve to the correct
5
- * computed styles. This ensures that:
6
- * 1. Semantic color tokens resolve to actual colors
7
- * 2. Typography tokens apply correct font properties
8
- * 3. Spacing tokens resolve to correct pixel values
9
- */
10
-
11
- import { describe, expect, test } from "vitest";
12
- import { page } from "vitest/browser";
13
- import { render } from "vitest-browser-react";
14
- import { Button } from "../components/atoms/button/button";
15
-
16
- /**
17
- * Helper to get computed style of an element
18
- */
19
- function getComputedStyleValue(element: Element, property: string): string {
20
- return window.getComputedStyle(element).getPropertyValue(property);
21
- }
22
-
23
- describe("Token Resolution", () => {
24
- describe("Semantic Color Tokens", () => {
25
- test("Button primary variant uses semantic bg token", async () => {
26
- render(<Button data-testid="btn">Primary Button</Button>);
27
- const button = page.getByTestId("btn");
28
- await expect.element(button).toBeInTheDocument();
29
-
30
- const element = button.element();
31
- const bgColor = getComputedStyleValue(element, "background-color");
32
-
33
- // The button should have a non-transparent background
34
- expect(bgColor).not.toBe("rgba(0, 0, 0, 0)");
35
- expect(bgColor).not.toBe("transparent");
36
- });
37
-
38
- test("Button text color resolves from semantic token", async () => {
39
- render(<Button data-testid="btn">Text Color</Button>);
40
- const button = page.getByTestId("btn");
41
- await expect.element(button).toBeInTheDocument();
42
-
43
- const element = button.element();
44
- const textColor = getComputedStyleValue(element, "color");
45
-
46
- // Should have a defined text color
47
- expect(textColor).toBeTruthy();
48
- expect(textColor).not.toBe("rgba(0, 0, 0, 0)");
49
- });
50
-
51
- test("Background page token resolves correctly", async () => {
52
- render(
53
- <div data-testid="bg-test" className="bg-bg-page p-16">
54
- Background Test
55
- </div>,
56
- );
57
- const element = page.getByTestId("bg-test").element();
58
- const bgColor = getComputedStyleValue(element, "background-color");
59
-
60
- // bg-page should resolve to a non-transparent color
61
- expect(bgColor).not.toBe("rgba(0, 0, 0, 0)");
62
- });
63
-
64
- test("Text primary token resolves correctly", async () => {
65
- render(
66
- <p data-testid="text-test" className="text-text-primary">
67
- Primary Text
68
- </p>,
69
- );
70
- const element = page.getByTestId("text-test").element();
71
- const textColor = getComputedStyleValue(element, "color");
72
-
73
- // text-primary should be a dark color
74
- expect(textColor).toBeTruthy();
75
- expect(textColor).not.toBe("rgba(0, 0, 0, 0)");
76
- });
77
- });
78
-
79
- describe("Primitive Color Tokens", () => {
80
- test("Gray scale colors resolve", async () => {
81
- render(
82
- <div>
83
- <div data-testid="gray-100" className="bg-gray-100">
84
- Gray 100
85
- </div>
86
- <div data-testid="gray-500" className="bg-gray-500">
87
- Gray 500
88
- </div>
89
- <div data-testid="gray-900" className="bg-gray-900">
90
- Gray 900
91
- </div>
92
- </div>,
93
- );
94
-
95
- const gray100 = page.getByTestId("gray-100").element();
96
- const gray500 = page.getByTestId("gray-500").element();
97
- const gray900 = page.getByTestId("gray-900").element();
98
-
99
- const bg100 = getComputedStyleValue(gray100, "background-color");
100
- const bg500 = getComputedStyleValue(gray500, "background-color");
101
- const bg900 = getComputedStyleValue(gray900, "background-color");
102
-
103
- // All should have resolved background colors
104
- expect(bg100).not.toBe("rgba(0, 0, 0, 0)");
105
- expect(bg500).not.toBe("rgba(0, 0, 0, 0)");
106
- expect(bg900).not.toBe("rgba(0, 0, 0, 0)");
107
-
108
- // Gray 100 should be lighter than Gray 900
109
- // (comparing luminance would be ideal, but we'll just verify they're different)
110
- expect(bg100).not.toBe(bg900);
111
- });
112
-
113
- test("Indigo accent colors resolve", async () => {
114
- render(
115
- <div data-testid="indigo" className="bg-indigo-600">
116
- Indigo 600
117
- </div>,
118
- );
119
-
120
- const element = page.getByTestId("indigo").element();
121
- const bgColor = getComputedStyleValue(element, "background-color");
122
-
123
- // Should resolve to a blue-ish color (indigo)
124
- expect(bgColor).not.toBe("rgba(0, 0, 0, 0)");
125
- });
126
- });
127
-
128
- describe("Typography Tokens", () => {
129
- test("Typography h1 class applies correct styles", async () => {
130
- render(
131
- <h1 data-testid="h1" className="typography-h1">
132
- Heading 1
133
- </h1>,
134
- );
135
-
136
- const element = page.getByTestId("h1").element();
137
- const fontSize = getComputedStyleValue(element, "font-size");
138
- const fontFamily = getComputedStyleValue(element, "font-family");
139
-
140
- const sizeNum = Number.parseFloat(fontSize);
141
- expect(sizeNum).toBeGreaterThan(0);
142
-
143
- expect(fontFamily).toBeTruthy();
144
- });
145
-
146
- test("Typography body-medium class applies correct styles", async () => {
147
- render(
148
- <p data-testid="body" className="typography-body-medium">
149
- Body text
150
- </p>,
151
- );
152
-
153
- const element = page.getByTestId("body").element();
154
- const fontSize = getComputedStyleValue(element, "font-size");
155
- const lineHeight = getComputedStyleValue(element, "line-height");
156
-
157
- // Body medium should be around 14-18px depending on breakpoint
158
- const sizeNum = Number.parseFloat(fontSize);
159
- expect(sizeNum).toBeGreaterThanOrEqual(14);
160
- expect(sizeNum).toBeLessThanOrEqual(18);
161
-
162
- // Should have a line height set
163
- expect(lineHeight).toBeTruthy();
164
- });
165
-
166
- test("Typography button class applies correct weight", async () => {
167
- render(
168
- <span data-testid="btn-text" className="typography-ui-button-medium">
169
- Button Text
170
- </span>,
171
- );
172
-
173
- const element = page.getByTestId("btn-text").element();
174
- const fontWeight = getComputedStyleValue(element, "font-weight");
175
-
176
- const weightNum = Number.parseInt(fontWeight, 10);
177
- expect(weightNum).toBeGreaterThan(0);
178
- });
179
- });
180
-
181
- describe("Spacing Tokens", () => {
182
- test("Padding tokens resolve to correct pixel values", async () => {
183
- render(
184
- <div data-testid="padded" className="p-16">
185
- Padded content
186
- </div>,
187
- );
188
-
189
- const element = page.getByTestId("padded").element();
190
- const padding = getComputedStyleValue(element, "padding");
191
-
192
- // p-16 should resolve to 16px on all sides
193
- expect(padding).toBe("16px");
194
- });
195
-
196
- test("Margin tokens resolve correctly", async () => {
197
- render(
198
- <div data-testid="margin" className="m-24">
199
- Margin content
200
- </div>,
201
- );
202
-
203
- const element = page.getByTestId("margin").element();
204
- const margin = getComputedStyleValue(element, "margin");
205
-
206
- // m-24 should resolve to 24px on all sides
207
- expect(margin).toBe("24px");
208
- });
209
-
210
- test("Gap tokens resolve correctly", async () => {
211
- render(
212
- <div data-testid="gap" className="flex gap-8">
213
- <span>Item 1</span>
214
- <span>Item 2</span>
215
- </div>,
216
- );
217
-
218
- const element = page.getByTestId("gap").element();
219
- const gap = getComputedStyleValue(element, "gap");
220
-
221
- // gap-8 should resolve to 8px
222
- expect(gap).toBe("8px");
223
- });
224
-
225
- test("Width spacing tokens resolve", async () => {
226
- render(
227
- <div data-testid="width" className="w-64 h-8 bg-gray-500">
228
- Width test
229
- </div>,
230
- );
231
-
232
- const element = page.getByTestId("width").element();
233
- const width = getComputedStyleValue(element, "width");
234
-
235
- // w-64 should be 64px
236
- expect(width).toBe("64px");
237
- });
238
- });
239
-
240
- describe("Border Radius Tokens", () => {
241
- test("Radius tokens resolve correctly", async () => {
242
- render(
243
- <div data-testid="rounded" className="rounded-8 bg-gray-200 p-16">
244
- Rounded corners
245
- </div>,
246
- );
247
-
248
- const element = page.getByTestId("rounded").element();
249
- const radius = getComputedStyleValue(element, "border-radius");
250
-
251
- // rounded-8 should be 8px
252
- expect(radius).toBe("8px");
253
- });
254
- });
255
-
256
- describe("Component Token Integration", () => {
257
- test("Button has defined height from spacing tokens", async () => {
258
- render(
259
- <Button data-testid="btn" size="md">
260
- Medium Button
261
- </Button>,
262
- );
263
- const button = page.getByTestId("btn");
264
- await expect.element(button).toBeInTheDocument();
265
-
266
- const element = button.element();
267
- const height = getComputedStyleValue(element, "height");
268
-
269
- // Button should have a defined height (not auto)
270
- const heightNum = Number.parseFloat(height);
271
- expect(heightNum).toBeGreaterThan(0);
272
- });
273
-
274
- test("Button sizes use different padding tokens", async () => {
275
- render(
276
- <div>
277
- <Button data-testid="btn-sm" size="sm">
278
- Small
279
- </Button>
280
- <Button data-testid="btn-lg" size="lg">
281
- Large
282
- </Button>
283
- </div>,
284
- );
285
-
286
- const smallBtn = page.getByTestId("btn-sm").element();
287
- const largeBtn = page.getByTestId("btn-lg").element();
288
-
289
- const smallPadding = getComputedStyleValue(smallBtn, "padding-left");
290
- const largePadding = getComputedStyleValue(largeBtn, "padding-left");
291
-
292
- // Large should have more padding than small
293
- const smallPaddingNum = Number.parseFloat(smallPadding);
294
- const largePaddingNum = Number.parseFloat(largePadding);
295
- expect(largePaddingNum).toBeGreaterThan(smallPaddingNum);
296
- });
297
- });
298
- });
@@ -1,270 +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 "../components/atoms/button/button";
5
- import { useCSSVars, useTheme } from "./hooks";
6
- import { ThemeProvider } from "./theme-provider";
7
-
8
- function getInlineStyleVar(element: Element, varName: string): string | null {
9
- const style = element.getAttribute("style") || "";
10
- const regex = new RegExp(`${varName}:\\s*([^;]+)`);
11
- const match = style.match(regex);
12
- return match ? match[1].trim() : null;
13
- }
14
-
15
- describe("ThemeProvider", () => {
16
- describe("CSS Variable Application", () => {
17
- test("renders a wrapper div with style attribute", async () => {
18
- render(
19
- <ThemeProvider>
20
- <div data-testid="content">Content</div>
21
- </ThemeProvider>,
22
- );
23
-
24
- const content = page.getByTestId("content");
25
- await expect.element(content).toBeInTheDocument();
26
-
27
- const wrapper = content.element().parentElement;
28
- expect(wrapper).toBeTruthy();
29
- expect(wrapper?.tagName).toBe("DIV");
30
- expect(wrapper?.hasAttribute("style")).toBe(true);
31
-
32
- const styleAttr = wrapper?.getAttribute("style") || "";
33
- expect(styleAttr).toContain("--color-bg-page");
34
- });
35
-
36
- test("applies className to wrapper div", async () => {
37
- render(
38
- <ThemeProvider className="custom-class">
39
- <div data-testid="content">Content</div>
40
- </ThemeProvider>,
41
- );
42
-
43
- const content = page.getByTestId("content");
44
- const wrapper = content.element().parentElement;
45
- expect(wrapper?.classList.contains("custom-class")).toBe(true);
46
- });
47
-
48
- test("applyStyles=false skips wrapper div", async () => {
49
- function TestContent() {
50
- const theme = useTheme();
51
- return <div data-testid="content">{theme.colorTheme}</div>;
52
- }
53
-
54
- render(
55
- <ThemeProvider applyStyles={false}>
56
- <TestContent />
57
- </ThemeProvider>,
58
- );
59
-
60
- const content = page.getByTestId("content");
61
- await expect.element(content).toBeInTheDocument();
62
- expect(content.element().textContent).toBe("base");
63
- });
64
- });
65
-
66
- describe("Color Theme Overrides", () => {
67
- test("base theme applies CSS variables for buttons", async () => {
68
- render(
69
- <ThemeProvider color="base">
70
- <Button data-testid="btn" variant="primary">
71
- Primary
72
- </Button>
73
- </ThemeProvider>,
74
- );
75
-
76
- const button = page.getByTestId("btn");
77
- await expect.element(button).toBeInTheDocument();
78
-
79
- const wrapper = button.element().parentElement;
80
- const styleAttr = wrapper?.getAttribute("style") || "";
81
- expect(styleAttr).toContain("--color-button-primary-bg");
82
- });
83
-
84
- test("civic theme overrides button primary color", async () => {
85
- render(
86
- <ThemeProvider color="civic">
87
- <Button data-testid="btn" variant="primary">
88
- Primary
89
- </Button>
90
- </ThemeProvider>,
91
- );
92
-
93
- const button = page.getByTestId("btn");
94
- await expect.element(button).toBeInTheDocument();
95
-
96
- const wrapper = button.element().parentElement;
97
- expect(wrapper).toBeTruthy();
98
-
99
- const styleAttr = wrapper?.getAttribute("style") || "";
100
- expect(styleAttr).toContain("--color-button-primary-bg");
101
- expect(styleAttr).toContain("red");
102
- });
103
-
104
- test("dark theme applies dark mode colors", async () => {
105
- render(
106
- <ThemeProvider color="dark">
107
- <div data-testid="bg" className="bg-bg-page p-16">
108
- Dark Theme
109
- </div>
110
- </ThemeProvider>,
111
- );
112
-
113
- const bgElement = page.getByTestId("bg");
114
- await expect.element(bgElement).toBeInTheDocument();
115
-
116
- const wrapper = bgElement.element().parentElement;
117
- const styleAttr = wrapper?.getAttribute("style") || "";
118
- expect(styleAttr).toContain("--color-bg-page");
119
- });
120
-
121
- test("institution theme uses green button colors", async () => {
122
- render(
123
- <ThemeProvider color="institution">
124
- <Button data-testid="btn" variant="primary">
125
- Institution
126
- </Button>
127
- </ThemeProvider>,
128
- );
129
-
130
- const button = page.getByTestId("btn");
131
- await expect.element(button).toBeInTheDocument();
132
-
133
- const wrapper = button.element().parentElement;
134
- const styleAttr = wrapper?.getAttribute("style") || "";
135
- expect(styleAttr).toContain("--color-button-primary-bg");
136
- expect(styleAttr).toContain("green");
137
- });
138
- });
139
-
140
- describe("Theme Context", () => {
141
- test("useTheme returns current theme names", async () => {
142
- function ThemeInfo() {
143
- const { colorTheme, surfaceTheme } = useTheme();
144
- return (
145
- <div data-testid="info">
146
- {colorTheme}-{surfaceTheme}
147
- </div>
148
- );
149
- }
150
-
151
- render(
152
- <ThemeProvider color="civic" surface="sharp">
153
- <ThemeInfo />
154
- </ThemeProvider>,
155
- );
156
-
157
- const info = page.getByTestId("info");
158
- await expect.element(info).toBeInTheDocument();
159
- expect(info.element().textContent).toBe("civic-sharp");
160
- });
161
-
162
- test("useCSSVars returns CSS variable map", async () => {
163
- function CSSVarsTest() {
164
- const cssVars = useCSSVars();
165
- const hasVars = Object.keys(cssVars).length > 0;
166
- return (
167
- <div data-testid="result">{hasVars ? "has-vars" : "no-vars"}</div>
168
- );
169
- }
170
-
171
- render(
172
- <ThemeProvider>
173
- <CSSVarsTest />
174
- </ThemeProvider>,
175
- );
176
-
177
- const result = page.getByTestId("result");
178
- await expect.element(result).toBeInTheDocument();
179
- expect(result.element().textContent).toBe("has-vars");
180
- });
181
- });
182
-
183
- describe("Nested ThemeProviders", () => {
184
- test("nested ThemeProvider overrides parent theme", async () => {
185
- function ThemeInfo() {
186
- const { colorTheme } = useTheme();
187
- return <span data-testid="theme">{colorTheme}</span>;
188
- }
189
-
190
- render(
191
- <ThemeProvider color="base">
192
- <div>
193
- <ThemeInfo />
194
- <ThemeProvider color="civic">
195
- <ThemeInfo />
196
- </ThemeProvider>
197
- </div>
198
- </ThemeProvider>,
199
- );
200
-
201
- const themes = page.getByTestId("theme");
202
- await expect.element(themes.first()).toBeInTheDocument();
203
-
204
- const themeElements = document.querySelectorAll('[data-testid="theme"]');
205
- expect(themeElements[0].textContent).toBe("base");
206
- expect(themeElements[1].textContent).toBe("civic");
207
- });
208
- });
209
-
210
- describe("Button Theming Integration", () => {
211
- test("button primary-outline inherits theme colors", async () => {
212
- render(
213
- <ThemeProvider color="civic">
214
- <Button data-testid="btn" variant="primary-outline">
215
- Outline
216
- </Button>
217
- </ThemeProvider>,
218
- );
219
-
220
- const button = page.getByTestId("btn");
221
- await expect.element(button).toBeInTheDocument();
222
-
223
- const wrapper = button.element().parentElement;
224
- const styleAttr = wrapper?.getAttribute("style") || "";
225
- expect(styleAttr).toContain("--color-button-primary-outline");
226
- });
227
-
228
- test("different themes produce different CSS variables", async () => {
229
- render(
230
- <div className="flex gap-16">
231
- <ThemeProvider color="base">
232
- <Button data-testid="base-btn" variant="primary">
233
- Base
234
- </Button>
235
- </ThemeProvider>
236
- <ThemeProvider color="civic">
237
- <Button data-testid="civic-btn" variant="primary">
238
- Civic
239
- </Button>
240
- </ThemeProvider>
241
- </div>,
242
- );
243
-
244
- const baseBtn = page.getByTestId("base-btn");
245
- const civicBtn = page.getByTestId("civic-btn");
246
-
247
- await expect.element(baseBtn).toBeInTheDocument();
248
- await expect.element(civicBtn).toBeInTheDocument();
249
-
250
- const baseWrapper = baseBtn.element().parentElement;
251
- const civicWrapper = civicBtn.element().parentElement;
252
-
253
- expect(baseWrapper).toBeTruthy();
254
- expect(civicWrapper).toBeTruthy();
255
-
256
- const baseBgVar = getInlineStyleVar(
257
- baseWrapper as Element,
258
- "--color-button-primary-bg",
259
- );
260
- const civicBgVar = getInlineStyleVar(
261
- civicWrapper as Element,
262
- "--color-button-primary-bg",
263
- );
264
-
265
- expect(baseBgVar).toBeTruthy();
266
- expect(civicBgVar).toBeTruthy();
267
- expect(baseBgVar).not.toBe(civicBgVar);
268
- });
269
- });
270
- });