@buildcanada/components 0.3.4 → 0.3.5

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 (69) hide show
  1. package/package.json +3 -2
  2. package/src/assets/fonts/financier-text-regular.woff2 +0 -0
  3. package/src/assets/fonts/founders-grotesk-mono-regular.woff2 +0 -0
  4. package/src/assets/fonts/soehne-kraftig.woff2 +0 -0
  5. package/src/content/Card/Card.scss +281 -0
  6. package/src/content/Card/Card.stories.tsx +389 -0
  7. package/src/content/Card/Card.tsx +170 -0
  8. package/src/content/Card/index.ts +22 -0
  9. package/src/content/Hero/Hero.scss +150 -0
  10. package/src/content/Hero/Hero.stories.tsx +299 -0
  11. package/src/content/Hero/Hero.tsx +63 -0
  12. package/src/content/Hero/index.ts +13 -0
  13. package/src/content/StatBlock/StatBlock.scss +83 -0
  14. package/src/content/StatBlock/StatBlock.stories.tsx +331 -0
  15. package/src/content/StatBlock/StatBlock.tsx +52 -0
  16. package/src/content/StatBlock/index.ts +2 -0
  17. package/src/feedback/Dialog/Dialog.scss +158 -0
  18. package/src/feedback/Dialog/Dialog.stories.tsx +286 -0
  19. package/src/feedback/Dialog/Dialog.tsx +120 -0
  20. package/src/feedback/Dialog/index.ts +1 -0
  21. package/src/feedback/PopupForm/PopupForm.scss +34 -0
  22. package/src/feedback/PopupForm/PopupForm.stories.tsx +341 -0
  23. package/src/feedback/PopupForm/PopupForm.tsx +90 -0
  24. package/src/feedback/PopupForm/index.ts +1 -0
  25. package/src/index.ts +61 -0
  26. package/src/layout/Container/Container.scss +40 -0
  27. package/src/layout/Container/Container.stories.tsx +153 -0
  28. package/src/layout/Container/Container.tsx +29 -0
  29. package/src/layout/Container/index.ts +2 -0
  30. package/src/layout/Divider/Divider.scss +117 -0
  31. package/src/layout/Divider/Divider.stories.tsx +204 -0
  32. package/src/layout/Divider/Divider.tsx +32 -0
  33. package/src/layout/Divider/index.ts +2 -0
  34. package/src/layout/Grid/Grid.scss +81 -0
  35. package/src/layout/Grid/Grid.stories.tsx +263 -0
  36. package/src/layout/Grid/Grid.tsx +75 -0
  37. package/src/layout/Grid/index.ts +2 -0
  38. package/src/layout/Section/Section.scss +74 -0
  39. package/src/layout/Section/Section.stories.tsx +173 -0
  40. package/src/layout/Section/Section.tsx +37 -0
  41. package/src/layout/Section/index.ts +2 -0
  42. package/src/layout/Stack/Stack.scss +61 -0
  43. package/src/layout/Stack/Stack.stories.tsx +342 -0
  44. package/src/layout/Stack/Stack.tsx +48 -0
  45. package/src/layout/Stack/index.ts +9 -0
  46. package/src/navigation/Footer/Footer.scss +233 -0
  47. package/src/navigation/Footer/Footer.stories.tsx +351 -0
  48. package/src/navigation/Footer/Footer.tsx +174 -0
  49. package/src/navigation/Footer/index.ts +2 -0
  50. package/src/navigation/Header/Header.scss +325 -0
  51. package/src/navigation/Header/Header.stories.tsx +346 -0
  52. package/src/navigation/Header/Header.tsx +185 -0
  53. package/src/navigation/Header/index.ts +2 -0
  54. package/src/primitives/Button/Button.scss +218 -0
  55. package/src/primitives/Button/Button.stories.tsx +300 -0
  56. package/src/primitives/Button/Button.tsx +120 -0
  57. package/src/primitives/Button/index.ts +2 -0
  58. package/src/primitives/Checkbox/Checkbox.scss +114 -0
  59. package/src/primitives/Checkbox/Checkbox.stories.tsx +204 -0
  60. package/src/primitives/Checkbox/Checkbox.tsx +75 -0
  61. package/src/primitives/Checkbox/index.ts +2 -0
  62. package/src/primitives/TextField/TextField.scss +93 -0
  63. package/src/primitives/TextField/TextField.stories.tsx +265 -0
  64. package/src/primitives/TextField/TextField.tsx +105 -0
  65. package/src/primitives/TextField/index.ts +2 -0
  66. package/src/styles/fonts.scss +27 -0
  67. package/src/styles/main.scss +36 -0
  68. package/src/styles/tokens.scss +301 -0
  69. package/src/styles/typography.scss +232 -0
@@ -0,0 +1,342 @@
1
+ import type { Meta, StoryObj } from "@storybook/react"
2
+
3
+ import { Stack } from "./Stack"
4
+
5
+ const meta: Meta<typeof Stack> = {
6
+ title: "Components/Layout/Stack",
7
+ component: Stack,
8
+ parameters: {
9
+ docs: {
10
+ description: {
11
+ component: `
12
+ A flexbox layout component for arranging items in a row or column with consistent spacing.
13
+
14
+ ## Usage
15
+
16
+ \`\`\`tsx
17
+ import { Stack } from "@buildcanada/components"
18
+
19
+ <Stack direction="vertical" spacing="md">
20
+ <div>Item 1</div>
21
+ <div>Item 2</div>
22
+ <div>Item 3</div>
23
+ </Stack>
24
+ \`\`\`
25
+
26
+ ## Horizontal Layout
27
+
28
+ \`\`\`tsx
29
+ <Stack direction="horizontal" spacing="lg" align="center">
30
+ <Button>Action 1</Button>
31
+ <Button>Action 2</Button>
32
+ </Stack>
33
+ \`\`\`
34
+
35
+ ## Spacing Options
36
+
37
+ - **none**: 0px
38
+ - **xs**: 4px
39
+ - **sm**: 8px
40
+ - **md**: 16px
41
+ - **lg**: 24px
42
+ - **xl**: 32px
43
+ `,
44
+ },
45
+ },
46
+ },
47
+ argTypes: {
48
+ direction: {
49
+ control: "radio",
50
+ options: ["vertical", "horizontal"],
51
+ description: "Stack direction (column or row)",
52
+ },
53
+ spacing: {
54
+ control: "select",
55
+ options: ["none", "xs", "sm", "md", "lg", "xl"],
56
+ description: "Gap between items",
57
+ },
58
+ align: {
59
+ control: "select",
60
+ options: ["start", "center", "end", "stretch"],
61
+ description: "Cross-axis alignment (align-items)",
62
+ },
63
+ justify: {
64
+ control: "select",
65
+ options: ["start", "center", "end", "between", "around"],
66
+ description: "Main-axis alignment (justify-content)",
67
+ },
68
+ wrap: {
69
+ description: "Whether items should wrap to next line",
70
+ },
71
+ },
72
+ }
73
+
74
+ export default meta
75
+ type Story = StoryObj<typeof Stack>
76
+
77
+ const StackItem = ({ children, height }: { children: React.ReactNode; height?: string }) => (
78
+ <div style={{
79
+ padding: "16px 24px",
80
+ backgroundColor: "#F6ECE3",
81
+ border: "1px solid #272727",
82
+ fontFamily: "sans-serif",
83
+ height: height || "auto",
84
+ }}>
85
+ {children}
86
+ </div>
87
+ )
88
+
89
+ export const Default: Story = {
90
+ args: {
91
+ direction: "vertical",
92
+ spacing: "md",
93
+ children: (
94
+ <>
95
+ <StackItem>Item 1</StackItem>
96
+ <StackItem>Item 2</StackItem>
97
+ <StackItem>Item 3</StackItem>
98
+ </>
99
+ ),
100
+ },
101
+ }
102
+
103
+ export const Vertical: Story = {
104
+ args: {
105
+ direction: "vertical",
106
+ spacing: "md",
107
+ children: (
108
+ <>
109
+ <StackItem>Item 1</StackItem>
110
+ <StackItem>Item 2</StackItem>
111
+ <StackItem>Item 3</StackItem>
112
+ </>
113
+ ),
114
+ },
115
+ }
116
+
117
+ export const Horizontal: Story = {
118
+ args: {
119
+ direction: "horizontal",
120
+ spacing: "md",
121
+ children: (
122
+ <>
123
+ <StackItem>Item 1</StackItem>
124
+ <StackItem>Item 2</StackItem>
125
+ <StackItem>Item 3</StackItem>
126
+ </>
127
+ ),
128
+ },
129
+ }
130
+
131
+ export const NoSpacing: Story = {
132
+ args: {
133
+ direction: "vertical",
134
+ spacing: "none",
135
+ children: (
136
+ <>
137
+ <StackItem>Item 1</StackItem>
138
+ <StackItem>Item 2</StackItem>
139
+ <StackItem>Item 3</StackItem>
140
+ </>
141
+ ),
142
+ },
143
+ }
144
+
145
+ export const ExtraSmallSpacing: Story = {
146
+ args: {
147
+ direction: "vertical",
148
+ spacing: "xs",
149
+ children: (
150
+ <>
151
+ <StackItem>Item 1</StackItem>
152
+ <StackItem>Item 2</StackItem>
153
+ <StackItem>Item 3</StackItem>
154
+ </>
155
+ ),
156
+ },
157
+ }
158
+
159
+ export const LargeSpacing: Story = {
160
+ args: {
161
+ direction: "vertical",
162
+ spacing: "lg",
163
+ children: (
164
+ <>
165
+ <StackItem>Item 1</StackItem>
166
+ <StackItem>Item 2</StackItem>
167
+ <StackItem>Item 3</StackItem>
168
+ </>
169
+ ),
170
+ },
171
+ }
172
+
173
+ export const AlignCenter: Story = {
174
+ args: {
175
+ direction: "horizontal",
176
+ spacing: "md",
177
+ align: "center",
178
+ children: (
179
+ <>
180
+ <StackItem height="60px">Tall</StackItem>
181
+ <StackItem height="40px">Medium</StackItem>
182
+ <StackItem height="80px">Taller</StackItem>
183
+ </>
184
+ ),
185
+ },
186
+ }
187
+
188
+ export const AlignStart: Story = {
189
+ args: {
190
+ direction: "horizontal",
191
+ spacing: "md",
192
+ align: "start",
193
+ children: (
194
+ <>
195
+ <StackItem height="60px">Tall</StackItem>
196
+ <StackItem height="40px">Medium</StackItem>
197
+ <StackItem height="80px">Taller</StackItem>
198
+ </>
199
+ ),
200
+ },
201
+ }
202
+
203
+ export const AlignEnd: Story = {
204
+ args: {
205
+ direction: "horizontal",
206
+ spacing: "md",
207
+ align: "end",
208
+ children: (
209
+ <>
210
+ <StackItem height="60px">Tall</StackItem>
211
+ <StackItem height="40px">Medium</StackItem>
212
+ <StackItem height="80px">Taller</StackItem>
213
+ </>
214
+ ),
215
+ },
216
+ }
217
+
218
+ export const JustifyBetween: Story = {
219
+ args: {
220
+ direction: "horizontal",
221
+ spacing: "md",
222
+ justify: "between",
223
+ children: (
224
+ <>
225
+ <StackItem>Left</StackItem>
226
+ <StackItem>Center</StackItem>
227
+ <StackItem>Right</StackItem>
228
+ </>
229
+ ),
230
+ },
231
+ decorators: [
232
+ (Story) => (
233
+ <div style={{ width: "100%" }}>
234
+ <Story />
235
+ </div>
236
+ ),
237
+ ],
238
+ }
239
+
240
+ export const JustifyCenter: Story = {
241
+ args: {
242
+ direction: "horizontal",
243
+ spacing: "md",
244
+ justify: "center",
245
+ children: (
246
+ <>
247
+ <StackItem>Item 1</StackItem>
248
+ <StackItem>Item 2</StackItem>
249
+ <StackItem>Item 3</StackItem>
250
+ </>
251
+ ),
252
+ },
253
+ decorators: [
254
+ (Story) => (
255
+ <div style={{ width: "100%" }}>
256
+ <Story />
257
+ </div>
258
+ ),
259
+ ],
260
+ }
261
+
262
+ export const WithWrap: Story = {
263
+ args: {
264
+ direction: "horizontal",
265
+ spacing: "md",
266
+ wrap: true,
267
+ children: (
268
+ <>
269
+ <StackItem>Item 1</StackItem>
270
+ <StackItem>Item 2</StackItem>
271
+ <StackItem>Item 3</StackItem>
272
+ <StackItem>Item 4</StackItem>
273
+ <StackItem>Item 5</StackItem>
274
+ <StackItem>Item 6</StackItem>
275
+ <StackItem>Item 7</StackItem>
276
+ <StackItem>Item 8</StackItem>
277
+ </>
278
+ ),
279
+ },
280
+ decorators: [
281
+ (Story) => (
282
+ <div style={{ maxWidth: "400px" }}>
283
+ <Story />
284
+ </div>
285
+ ),
286
+ ],
287
+ }
288
+
289
+ export const AllSpacings: Story = {
290
+ render: () => (
291
+ <Stack direction="vertical" spacing="lg">
292
+ <div>
293
+ <p style={{ fontFamily: "sans-serif", marginBottom: "8px" }}>None</p>
294
+ <Stack direction="horizontal" spacing="none">
295
+ <StackItem>1</StackItem>
296
+ <StackItem>2</StackItem>
297
+ <StackItem>3</StackItem>
298
+ </Stack>
299
+ </div>
300
+ <div>
301
+ <p style={{ fontFamily: "sans-serif", marginBottom: "8px" }}>Extra Small</p>
302
+ <Stack direction="horizontal" spacing="xs">
303
+ <StackItem>1</StackItem>
304
+ <StackItem>2</StackItem>
305
+ <StackItem>3</StackItem>
306
+ </Stack>
307
+ </div>
308
+ <div>
309
+ <p style={{ fontFamily: "sans-serif", marginBottom: "8px" }}>Small</p>
310
+ <Stack direction="horizontal" spacing="sm">
311
+ <StackItem>1</StackItem>
312
+ <StackItem>2</StackItem>
313
+ <StackItem>3</StackItem>
314
+ </Stack>
315
+ </div>
316
+ <div>
317
+ <p style={{ fontFamily: "sans-serif", marginBottom: "8px" }}>Medium</p>
318
+ <Stack direction="horizontal" spacing="md">
319
+ <StackItem>1</StackItem>
320
+ <StackItem>2</StackItem>
321
+ <StackItem>3</StackItem>
322
+ </Stack>
323
+ </div>
324
+ <div>
325
+ <p style={{ fontFamily: "sans-serif", marginBottom: "8px" }}>Large</p>
326
+ <Stack direction="horizontal" spacing="lg">
327
+ <StackItem>1</StackItem>
328
+ <StackItem>2</StackItem>
329
+ <StackItem>3</StackItem>
330
+ </Stack>
331
+ </div>
332
+ <div>
333
+ <p style={{ fontFamily: "sans-serif", marginBottom: "8px" }}>Extra Large</p>
334
+ <Stack direction="horizontal" spacing="xl">
335
+ <StackItem>1</StackItem>
336
+ <StackItem>2</StackItem>
337
+ <StackItem>3</StackItem>
338
+ </Stack>
339
+ </div>
340
+ </Stack>
341
+ ),
342
+ }
@@ -0,0 +1,48 @@
1
+ import cx from "classnames"
2
+
3
+ export type StackDirection = "vertical" | "horizontal"
4
+ export type StackSpacing = "none" | "xs" | "sm" | "md" | "lg" | "xl"
5
+ export type StackAlign = "start" | "center" | "end" | "stretch"
6
+ export type StackJustify = "start" | "center" | "end" | "between" | "around"
7
+
8
+ export interface StackProps {
9
+ children: React.ReactNode
10
+ className?: string
11
+ style?: React.CSSProperties
12
+ direction?: StackDirection
13
+ spacing?: StackSpacing
14
+ align?: StackAlign
15
+ justify?: StackJustify
16
+ wrap?: boolean
17
+ as?: "div" | "ul" | "ol" | "nav"
18
+ }
19
+
20
+ export function Stack({
21
+ children,
22
+ className,
23
+ style,
24
+ direction = "vertical",
25
+ spacing = "md",
26
+ align = "stretch",
27
+ justify = "start",
28
+ wrap = false,
29
+ as: Component = "div",
30
+ }: StackProps) {
31
+ const classes = cx(
32
+ "bc-stack",
33
+ `bc-stack--${direction}`,
34
+ `bc-stack--spacing-${spacing}`,
35
+ `bc-stack--align-${align}`,
36
+ `bc-stack--justify-${justify}`,
37
+ { "bc-stack--wrap": wrap },
38
+ className
39
+ )
40
+
41
+ return (
42
+ <Component className={classes} style={style}>
43
+ {children}
44
+ </Component>
45
+ )
46
+ }
47
+
48
+ export default Stack
@@ -0,0 +1,9 @@
1
+ export {
2
+ Stack,
3
+ type StackProps,
4
+ type StackDirection,
5
+ type StackSpacing,
6
+ type StackAlign,
7
+ type StackJustify,
8
+ } from "./Stack.js"
9
+ export { default } from "./Stack.js"
@@ -0,0 +1,233 @@
1
+ @use "../../styles/tokens" as *;
2
+ @use "../../styles/typography" as *;
3
+
4
+ /*******************************************************************************
5
+ * Footer Component
6
+ ******************************************************************************/
7
+
8
+ .bc-footer {
9
+ background-color: $charcoal;
10
+ color: $white;
11
+ padding: $space-8 0;
12
+
13
+ /***************************************************************************
14
+ * Inner Container
15
+ ***************************************************************************/
16
+
17
+ &__inner {
18
+ max-width: 1280px;
19
+ margin: 0 auto;
20
+ padding: 0 $space-3;
21
+
22
+ @include md-up {
23
+ padding: 0 $space-5;
24
+ }
25
+ }
26
+
27
+ /***************************************************************************
28
+ * Main Section
29
+ ***************************************************************************/
30
+
31
+ &__main {
32
+ display: grid;
33
+ gap: $space-6;
34
+
35
+ @include md-up {
36
+ grid-template-columns: auto 1fr auto;
37
+ align-items: start;
38
+ }
39
+ }
40
+
41
+ /***************************************************************************
42
+ * Logo
43
+ ***************************************************************************/
44
+
45
+ &__logo {
46
+ img {
47
+ height: 32px;
48
+ width: auto;
49
+ filter: brightness(0) invert(1);
50
+ }
51
+ }
52
+
53
+ /***************************************************************************
54
+ * Navigation
55
+ ***************************************************************************/
56
+
57
+ &__nav {
58
+ @include md-up {
59
+ justify-self: center;
60
+ }
61
+ }
62
+
63
+ &__nav-list {
64
+ display: flex;
65
+ flex-wrap: wrap;
66
+ gap: $space-1 $space-3;
67
+ list-style: none;
68
+ margin: 0;
69
+ padding: 0;
70
+ }
71
+
72
+ &__nav-link {
73
+ @include label;
74
+ color: rgba($white, 0.8);
75
+ text-decoration: none;
76
+ transition: color $transition-fast;
77
+
78
+ &:hover {
79
+ color: $white;
80
+ }
81
+ }
82
+
83
+ /***************************************************************************
84
+ * Newsletter
85
+ ***************************************************************************/
86
+
87
+ &__newsletter {
88
+ @include md-up {
89
+ text-align: right;
90
+ max-width: 320px;
91
+ }
92
+ }
93
+
94
+ &__newsletter-heading {
95
+ @include h4;
96
+ color: $white;
97
+ margin: 0 0 calc($space-1 / 2);
98
+ }
99
+
100
+ &__newsletter-description {
101
+ @include body-3;
102
+ color: rgba($white, 0.7);
103
+ margin: 0 0 $space-2;
104
+ }
105
+
106
+ &__newsletter-form {
107
+ display: flex;
108
+ gap: calc($space-1 / 2);
109
+ }
110
+
111
+ &__newsletter-input {
112
+ @include body-3;
113
+ flex: 1;
114
+ min-width: 0;
115
+ padding: $space-1 $space-2;
116
+ border: none;
117
+ border-radius: $radius-none;
118
+ background-color: rgba($white, 0.1);
119
+ color: $white;
120
+
121
+ &::placeholder {
122
+ color: rgba($white, 0.5);
123
+ }
124
+
125
+ &:focus {
126
+ outline: 2px solid $auburn;
127
+ outline-offset: -2px;
128
+ }
129
+ }
130
+
131
+ &__newsletter-button {
132
+ @include button-text-sm;
133
+ padding: $space-1 $space-2;
134
+ background-color: $auburn;
135
+ color: $white;
136
+ border: none;
137
+ border-radius: $radius-none;
138
+ cursor: pointer;
139
+ transition: background-color $transition-fast;
140
+
141
+ &:hover {
142
+ background-color: $auburn-600;
143
+ }
144
+ }
145
+
146
+ /***************************************************************************
147
+ * Bottom Section
148
+ ***************************************************************************/
149
+
150
+ &__bottom {
151
+ display: flex;
152
+ flex-wrap: wrap;
153
+ align-items: center;
154
+ justify-content: space-between;
155
+ gap: $space-2;
156
+ margin-top: $space-6;
157
+ padding-top: $space-4;
158
+ border-top: 1px solid rgba($white, 0.1);
159
+ }
160
+
161
+ /***************************************************************************
162
+ * Social Links
163
+ ***************************************************************************/
164
+
165
+ &__social {
166
+ display: flex;
167
+ gap: $space-2;
168
+ }
169
+
170
+ &__social-link {
171
+ display: flex;
172
+ align-items: center;
173
+ justify-content: center;
174
+ width: 36px;
175
+ height: 36px;
176
+ color: rgba($white, 0.7);
177
+ transition: color $transition-fast;
178
+
179
+ &:hover {
180
+ color: $white;
181
+ }
182
+
183
+ svg {
184
+ width: 20px;
185
+ height: 20px;
186
+ }
187
+ }
188
+
189
+ /***************************************************************************
190
+ * Copyright
191
+ ***************************************************************************/
192
+
193
+ &__copyright {
194
+ @include body-3;
195
+ color: rgba($white, 0.5);
196
+ margin: 0;
197
+ }
198
+
199
+ /***************************************************************************
200
+ * Quote
201
+ ***************************************************************************/
202
+
203
+ &__quote {
204
+ margin-top: $space-6;
205
+ padding-top: $space-4;
206
+ border-top: 1px solid rgba($white, 0.1);
207
+ text-align: center;
208
+ }
209
+
210
+ &__quote-text {
211
+ @include body-1;
212
+ font-style: italic;
213
+ color: rgba($white, 0.8);
214
+ margin: 0 0 $space-1;
215
+ max-width: 640px;
216
+ margin-left: auto;
217
+ margin-right: auto;
218
+
219
+ &::before {
220
+ content: '"';
221
+ }
222
+
223
+ &::after {
224
+ content: '"';
225
+ }
226
+ }
227
+
228
+ &__quote-attribution {
229
+ @include micro;
230
+ color: rgba($white, 0.5);
231
+ font-style: normal;
232
+ }
233
+ }