@buildcanada/components 0.1.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 (48) hide show
  1. package/package.json +67 -0
  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.tsx +170 -0
  7. package/src/content/Card/index.ts +22 -0
  8. package/src/content/Hero/Hero.scss +150 -0
  9. package/src/content/Hero/Hero.tsx +63 -0
  10. package/src/content/Hero/index.ts +13 -0
  11. package/src/content/StatBlock/StatBlock.scss +83 -0
  12. package/src/content/StatBlock/StatBlock.tsx +52 -0
  13. package/src/content/StatBlock/index.ts +2 -0
  14. package/src/index.ts +57 -0
  15. package/src/layout/Container/Container.scss +40 -0
  16. package/src/layout/Container/Container.tsx +29 -0
  17. package/src/layout/Container/index.ts +2 -0
  18. package/src/layout/Divider/Divider.scss +117 -0
  19. package/src/layout/Divider/Divider.tsx +32 -0
  20. package/src/layout/Divider/index.ts +2 -0
  21. package/src/layout/Grid/Grid.scss +81 -0
  22. package/src/layout/Grid/Grid.tsx +75 -0
  23. package/src/layout/Grid/index.ts +2 -0
  24. package/src/layout/Section/Section.scss +74 -0
  25. package/src/layout/Section/Section.tsx +37 -0
  26. package/src/layout/Section/index.ts +2 -0
  27. package/src/layout/Stack/Stack.scss +61 -0
  28. package/src/layout/Stack/Stack.tsx +48 -0
  29. package/src/layout/Stack/index.ts +9 -0
  30. package/src/navigation/Footer/Footer.scss +233 -0
  31. package/src/navigation/Footer/Footer.tsx +174 -0
  32. package/src/navigation/Footer/index.ts +2 -0
  33. package/src/navigation/Header/Header.scss +325 -0
  34. package/src/navigation/Header/Header.tsx +185 -0
  35. package/src/navigation/Header/index.ts +2 -0
  36. package/src/primitives/Button/Button.scss +218 -0
  37. package/src/primitives/Button/Button.tsx +120 -0
  38. package/src/primitives/Button/index.ts +2 -0
  39. package/src/primitives/Checkbox/Checkbox.scss +114 -0
  40. package/src/primitives/Checkbox/Checkbox.tsx +75 -0
  41. package/src/primitives/Checkbox/index.ts +2 -0
  42. package/src/primitives/TextField/TextField.scss +93 -0
  43. package/src/primitives/TextField/TextField.tsx +105 -0
  44. package/src/primitives/TextField/index.ts +2 -0
  45. package/src/styles/fonts.scss +27 -0
  46. package/src/styles/main.scss +34 -0
  47. package/src/styles/tokens.scss +301 -0
  48. package/src/styles/typography.scss +232 -0
@@ -0,0 +1,63 @@
1
+ import cx from "classnames"
2
+
3
+ export type HeroVariant = "home" | "page" | "centered"
4
+ export type HeroBackground = "white" | "linen" | "charcoal"
5
+
6
+ export interface HeroProps {
7
+ children: React.ReactNode
8
+ className?: string
9
+ style?: React.CSSProperties
10
+ variant?: HeroVariant
11
+ background?: HeroBackground
12
+ }
13
+
14
+ export function Hero({
15
+ children,
16
+ className,
17
+ style,
18
+ variant = "page",
19
+ background = "linen",
20
+ }: HeroProps) {
21
+ const classes = cx(
22
+ "bc-hero",
23
+ `bc-hero--${variant}`,
24
+ `bc-hero--bg-${background}`,
25
+ className
26
+ )
27
+
28
+ return (
29
+ <div className={classes} style={style}>
30
+ <div className="bc-hero__inner">{children}</div>
31
+ </div>
32
+ )
33
+ }
34
+
35
+ export interface HeroTitleProps {
36
+ children: React.ReactNode
37
+ className?: string
38
+ as?: "h1" | "h2"
39
+ }
40
+
41
+ export function HeroTitle({ children, className, as: Component = "h1" }: HeroTitleProps) {
42
+ return <Component className={cx("bc-hero__title", className)}>{children}</Component>
43
+ }
44
+
45
+ export interface HeroSubtitleProps {
46
+ children: React.ReactNode
47
+ className?: string
48
+ }
49
+
50
+ export function HeroSubtitle({ children, className }: HeroSubtitleProps) {
51
+ return <p className={cx("bc-hero__subtitle", className)}>{children}</p>
52
+ }
53
+
54
+ export interface HeroActionsProps {
55
+ children: React.ReactNode
56
+ className?: string
57
+ }
58
+
59
+ export function HeroActions({ children, className }: HeroActionsProps) {
60
+ return <div className={cx("bc-hero__actions", className)}>{children}</div>
61
+ }
62
+
63
+ export default Hero
@@ -0,0 +1,13 @@
1
+ export {
2
+ Hero,
3
+ HeroTitle,
4
+ HeroSubtitle,
5
+ HeroActions,
6
+ type HeroProps,
7
+ type HeroVariant,
8
+ type HeroBackground,
9
+ type HeroTitleProps,
10
+ type HeroSubtitleProps,
11
+ type HeroActionsProps,
12
+ } from "./Hero"
13
+ export { default } from "./Hero"
@@ -0,0 +1,83 @@
1
+ @use "../../styles/tokens" as *;
2
+ @use "../../styles/typography" as *;
3
+
4
+ /*******************************************************************************
5
+ * StatBlock Component
6
+ *
7
+ * Large formatted number with label, used for data display (canadaspends.com)
8
+ ******************************************************************************/
9
+
10
+ .bc-stat-block {
11
+ display: flex;
12
+ flex-direction: column;
13
+ gap: calc($space-1 / 2);
14
+
15
+ /***************************************************************************
16
+ * Size Variants
17
+ ***************************************************************************/
18
+
19
+ &--sm {
20
+ .bc-stat-block__value {
21
+ @include h2;
22
+ }
23
+
24
+ .bc-stat-block__label {
25
+ @include label-sm;
26
+ }
27
+ }
28
+
29
+ &--md {
30
+ .bc-stat-block__value {
31
+ @include display-2;
32
+ }
33
+
34
+ .bc-stat-block__label {
35
+ @include label;
36
+ }
37
+ }
38
+
39
+ &--lg {
40
+ .bc-stat-block__value {
41
+ @include display-1;
42
+ }
43
+
44
+ .bc-stat-block__label {
45
+ @include h4;
46
+ }
47
+ }
48
+
49
+ /***************************************************************************
50
+ * Elements
51
+ ***************************************************************************/
52
+
53
+ &__value {
54
+ color: $charcoal;
55
+ font-variant-numeric: tabular-nums;
56
+ }
57
+
58
+ &__label {
59
+ color: $text-secondary;
60
+ text-transform: uppercase;
61
+ letter-spacing: 0.05em;
62
+ }
63
+
64
+ &__description {
65
+ @include body-3;
66
+ color: $text-muted;
67
+ margin-top: calc($space-1 / 2);
68
+ }
69
+
70
+ &__change {
71
+ @include mono-sm;
72
+ color: $text-secondary;
73
+ margin-top: calc($space-1 / 2);
74
+
75
+ &--up {
76
+ color: $emerald-600;
77
+ }
78
+
79
+ &--down {
80
+ color: $auburn;
81
+ }
82
+ }
83
+ }
@@ -0,0 +1,52 @@
1
+ import cx from "classnames"
2
+
3
+ export type StatBlockSize = "sm" | "md" | "lg"
4
+ export type StatBlockTrend = "up" | "down" | "neutral"
5
+
6
+ export interface StatBlockProps {
7
+ value: string | number
8
+ label: string
9
+ description?: string
10
+ change?: string
11
+ trend?: StatBlockTrend
12
+ size?: StatBlockSize
13
+ className?: string
14
+ style?: React.CSSProperties
15
+ }
16
+
17
+ export function StatBlock({
18
+ value,
19
+ label,
20
+ description,
21
+ change,
22
+ trend,
23
+ size = "md",
24
+ className,
25
+ style,
26
+ }: StatBlockProps) {
27
+ const classes = cx("bc-stat-block", `bc-stat-block--${size}`, className)
28
+
29
+ return (
30
+ <div className={classes} style={style}>
31
+ <span className="bc-stat-block__value">{value}</span>
32
+ <span className="bc-stat-block__label">{label}</span>
33
+ {description && (
34
+ <span className="bc-stat-block__description">{description}</span>
35
+ )}
36
+ {change && (
37
+ <span
38
+ className={cx("bc-stat-block__change", {
39
+ "bc-stat-block__change--up": trend === "up",
40
+ "bc-stat-block__change--down": trend === "down",
41
+ })}
42
+ >
43
+ {trend === "up" && "↑ "}
44
+ {trend === "down" && "↓ "}
45
+ {change}
46
+ </span>
47
+ )}
48
+ </div>
49
+ )
50
+ }
51
+
52
+ export default StatBlock
@@ -0,0 +1,2 @@
1
+ export { StatBlock, type StatBlockProps, type StatBlockSize, type StatBlockTrend } from "./StatBlock"
2
+ export { default } from "./StatBlock"
package/src/index.ts ADDED
@@ -0,0 +1,57 @@
1
+ /*******************************************************************************
2
+ * @buildcanada/components
3
+ *
4
+ * Build Canada Design System Components
5
+ ******************************************************************************/
6
+
7
+ // Primitives
8
+ export { Button, type ButtonProps, type ButtonVariant, type ButtonSize } from "./primitives/Button"
9
+ export { TextField, type TextFieldProps, type TextFieldType } from "./primitives/TextField"
10
+ export { Checkbox, type CheckboxProps } from "./primitives/Checkbox"
11
+
12
+ // Layout
13
+ export { Container, type ContainerProps, type ContainerSize } from "./layout/Container"
14
+ export { Section, type SectionProps, type SectionBackground, type SectionSpacing } from "./layout/Section"
15
+ export { Grid, GridItem, type GridProps, type GridItemProps, type GridColumns, type GridGap } from "./layout/Grid"
16
+ export { Stack, type StackProps, type StackDirection, type StackSpacing, type StackAlign, type StackJustify } from "./layout/Stack"
17
+ export { Divider, type DividerProps, type DividerOrientation, type DividerVariant } from "./layout/Divider"
18
+
19
+ // Content
20
+ export {
21
+ Card,
22
+ CardImage,
23
+ CardIcon,
24
+ CardContent,
25
+ CardTitle,
26
+ CardDescription,
27
+ CardMeta,
28
+ CardStat,
29
+ CardAuthor,
30
+ type CardProps,
31
+ type CardVariant,
32
+ type CardImageProps,
33
+ type CardIconProps,
34
+ type CardContentProps,
35
+ type CardTitleProps,
36
+ type CardDescriptionProps,
37
+ type CardMetaProps,
38
+ type CardStatProps,
39
+ type CardAuthorProps,
40
+ } from "./content/Card"
41
+ export {
42
+ Hero,
43
+ HeroTitle,
44
+ HeroSubtitle,
45
+ HeroActions,
46
+ type HeroProps,
47
+ type HeroVariant,
48
+ type HeroBackground,
49
+ type HeroTitleProps,
50
+ type HeroSubtitleProps,
51
+ type HeroActionsProps,
52
+ } from "./content/Hero"
53
+ export { StatBlock, type StatBlockProps, type StatBlockSize, type StatBlockTrend } from "./content/StatBlock"
54
+
55
+ // Navigation
56
+ export { Header, type HeaderProps, type NavItem } from "./navigation/Header"
57
+ export { Footer, type FooterProps, type FooterLink, type SocialLink } from "./navigation/Footer"
@@ -0,0 +1,40 @@
1
+ @use "../../styles/tokens" as *;
2
+
3
+ /*******************************************************************************
4
+ * Container Component
5
+ *
6
+ * Max-width container with responsive padding
7
+ ******************************************************************************/
8
+
9
+ .bc-container {
10
+ width: 100%;
11
+ margin-left: auto;
12
+ margin-right: auto;
13
+ padding-left: $space-3;
14
+ padding-right: $space-3;
15
+
16
+ @include md-up {
17
+ padding-left: $space-5;
18
+ padding-right: $space-5;
19
+ }
20
+
21
+ &--sm {
22
+ max-width: 640px;
23
+ }
24
+
25
+ &--md {
26
+ max-width: 768px;
27
+ }
28
+
29
+ &--lg {
30
+ max-width: 1024px;
31
+ }
32
+
33
+ &--xl {
34
+ max-width: 1280px;
35
+ }
36
+
37
+ &--full {
38
+ max-width: none;
39
+ }
40
+ }
@@ -0,0 +1,29 @@
1
+ import cx from "classnames"
2
+
3
+ export type ContainerSize = "sm" | "md" | "lg" | "xl" | "full"
4
+
5
+ export interface ContainerProps {
6
+ children: React.ReactNode
7
+ className?: string
8
+ style?: React.CSSProperties
9
+ size?: ContainerSize
10
+ as?: "div" | "main" | "article" | "section"
11
+ }
12
+
13
+ export function Container({
14
+ children,
15
+ className,
16
+ style,
17
+ size = "lg",
18
+ as: Component = "div",
19
+ }: ContainerProps) {
20
+ const classes = cx("bc-container", `bc-container--${size}`, className)
21
+
22
+ return (
23
+ <Component className={classes} style={style}>
24
+ {children}
25
+ </Component>
26
+ )
27
+ }
28
+
29
+ export default Container
@@ -0,0 +1,2 @@
1
+ export { Container, type ContainerProps, type ContainerSize } from "./Container"
2
+ export { default } from "./Container"
@@ -0,0 +1,117 @@
1
+ @use "../../styles/tokens" as *;
2
+
3
+ /*******************************************************************************
4
+ * Divider Component
5
+ *
6
+ * Construction line motif - blueprint/draft aesthetic
7
+ ******************************************************************************/
8
+
9
+ .bc-divider {
10
+ border: none;
11
+ background-color: $border-default;
12
+
13
+ /***************************************************************************
14
+ * Orientation Variants
15
+ ***************************************************************************/
16
+
17
+ &--horizontal {
18
+ width: 100%;
19
+ height: 1px;
20
+ }
21
+
22
+ &--vertical {
23
+ width: 1px;
24
+ height: 100%;
25
+ min-height: 24px;
26
+ }
27
+
28
+ /***************************************************************************
29
+ * Style Variants
30
+ ***************************************************************************/
31
+
32
+ &--solid {
33
+ background-color: $border-default;
34
+ }
35
+
36
+ &--dashed {
37
+ background-color: transparent;
38
+
39
+ &.bc-divider--horizontal {
40
+ background-image: linear-gradient(
41
+ to right,
42
+ $border-default 50%,
43
+ transparent 50%
44
+ );
45
+ background-size: 8px 1px;
46
+ background-repeat: repeat-x;
47
+ }
48
+
49
+ &.bc-divider--vertical {
50
+ background-image: linear-gradient(
51
+ to bottom,
52
+ $border-default 50%,
53
+ transparent 50%
54
+ );
55
+ background-size: 1px 8px;
56
+ background-repeat: repeat-y;
57
+ }
58
+ }
59
+
60
+ // Construction line motif - blueprint aesthetic
61
+ &--construction {
62
+ background-color: $charcoal;
63
+ opacity: 0.15;
64
+
65
+ &.bc-divider--horizontal {
66
+ height: 1px;
67
+ }
68
+
69
+ &.bc-divider--vertical {
70
+ width: 1px;
71
+ }
72
+ }
73
+
74
+ /***************************************************************************
75
+ * Spacing Variants
76
+ ***************************************************************************/
77
+
78
+ &--spacing-none {
79
+ margin: 0;
80
+ }
81
+
82
+ &--spacing-sm {
83
+ &.bc-divider--horizontal {
84
+ margin-top: $space-2;
85
+ margin-bottom: $space-2;
86
+ }
87
+
88
+ &.bc-divider--vertical {
89
+ margin-left: $space-2;
90
+ margin-right: $space-2;
91
+ }
92
+ }
93
+
94
+ &--spacing-md {
95
+ &.bc-divider--horizontal {
96
+ margin-top: $space-4;
97
+ margin-bottom: $space-4;
98
+ }
99
+
100
+ &.bc-divider--vertical {
101
+ margin-left: $space-4;
102
+ margin-right: $space-4;
103
+ }
104
+ }
105
+
106
+ &--spacing-lg {
107
+ &.bc-divider--horizontal {
108
+ margin-top: $space-6;
109
+ margin-bottom: $space-6;
110
+ }
111
+
112
+ &.bc-divider--vertical {
113
+ margin-left: $space-6;
114
+ margin-right: $space-6;
115
+ }
116
+ }
117
+ }
@@ -0,0 +1,32 @@
1
+ import cx from "classnames"
2
+
3
+ export type DividerOrientation = "horizontal" | "vertical"
4
+ export type DividerVariant = "solid" | "dashed" | "construction"
5
+
6
+ export interface DividerProps {
7
+ className?: string
8
+ style?: React.CSSProperties
9
+ orientation?: DividerOrientation
10
+ variant?: DividerVariant
11
+ spacing?: "none" | "sm" | "md" | "lg"
12
+ }
13
+
14
+ export function Divider({
15
+ className,
16
+ style,
17
+ orientation = "horizontal",
18
+ variant = "solid",
19
+ spacing = "md",
20
+ }: DividerProps) {
21
+ const classes = cx(
22
+ "bc-divider",
23
+ `bc-divider--${orientation}`,
24
+ `bc-divider--${variant}`,
25
+ `bc-divider--spacing-${spacing}`,
26
+ className
27
+ )
28
+
29
+ return <hr className={classes} style={style} />
30
+ }
31
+
32
+ export default Divider
@@ -0,0 +1,2 @@
1
+ export { Divider, type DividerProps, type DividerOrientation, type DividerVariant } from "./Divider"
2
+ export { default } from "./Divider"
@@ -0,0 +1,81 @@
1
+ @use "../../styles/tokens" as *;
2
+
3
+ /*******************************************************************************
4
+ * Grid Component
5
+ *
6
+ * Responsive CSS Grid system
7
+ ******************************************************************************/
8
+
9
+ .bc-grid {
10
+ display: grid;
11
+ width: 100%;
12
+
13
+ /***************************************************************************
14
+ * Column Variants
15
+ ***************************************************************************/
16
+
17
+ &--cols-1 { grid-template-columns: repeat(1, 1fr); }
18
+ &--cols-2 { grid-template-columns: repeat(2, 1fr); }
19
+ &--cols-3 { grid-template-columns: repeat(3, 1fr); }
20
+ &--cols-4 { grid-template-columns: repeat(4, 1fr); }
21
+ &--cols-6 { grid-template-columns: repeat(6, 1fr); }
22
+ &--cols-12 { grid-template-columns: repeat(12, 1fr); }
23
+
24
+ @include md-up {
25
+ &--cols-md-1 { grid-template-columns: repeat(1, 1fr); }
26
+ &--cols-md-2 { grid-template-columns: repeat(2, 1fr); }
27
+ &--cols-md-3 { grid-template-columns: repeat(3, 1fr); }
28
+ &--cols-md-4 { grid-template-columns: repeat(4, 1fr); }
29
+ &--cols-md-6 { grid-template-columns: repeat(6, 1fr); }
30
+ &--cols-md-12 { grid-template-columns: repeat(12, 1fr); }
31
+ }
32
+
33
+ @include lg-up {
34
+ &--cols-lg-1 { grid-template-columns: repeat(1, 1fr); }
35
+ &--cols-lg-2 { grid-template-columns: repeat(2, 1fr); }
36
+ &--cols-lg-3 { grid-template-columns: repeat(3, 1fr); }
37
+ &--cols-lg-4 { grid-template-columns: repeat(4, 1fr); }
38
+ &--cols-lg-6 { grid-template-columns: repeat(6, 1fr); }
39
+ &--cols-lg-12 { grid-template-columns: repeat(12, 1fr); }
40
+ }
41
+
42
+ /***************************************************************************
43
+ * Gap Variants
44
+ ***************************************************************************/
45
+
46
+ &--gap-none { gap: 0; }
47
+ &--gap-sm { gap: $space-2; }
48
+ &--gap-md { gap: $space-3; }
49
+ &--gap-lg { gap: $space-4; }
50
+
51
+ /***************************************************************************
52
+ * Grid Item
53
+ ***************************************************************************/
54
+
55
+ &__item {
56
+ &--span-1 { grid-column: span 1; }
57
+ &--span-2 { grid-column: span 2; }
58
+ &--span-3 { grid-column: span 3; }
59
+ &--span-4 { grid-column: span 4; }
60
+ &--span-6 { grid-column: span 6; }
61
+ &--span-12 { grid-column: span 12; }
62
+
63
+ @include md-up {
64
+ &--span-md-1 { grid-column: span 1; }
65
+ &--span-md-2 { grid-column: span 2; }
66
+ &--span-md-3 { grid-column: span 3; }
67
+ &--span-md-4 { grid-column: span 4; }
68
+ &--span-md-6 { grid-column: span 6; }
69
+ &--span-md-12 { grid-column: span 12; }
70
+ }
71
+
72
+ @include lg-up {
73
+ &--span-lg-1 { grid-column: span 1; }
74
+ &--span-lg-2 { grid-column: span 2; }
75
+ &--span-lg-3 { grid-column: span 3; }
76
+ &--span-lg-4 { grid-column: span 4; }
77
+ &--span-lg-6 { grid-column: span 6; }
78
+ &--span-lg-12 { grid-column: span 12; }
79
+ }
80
+ }
81
+ }
@@ -0,0 +1,75 @@
1
+ import cx from "classnames"
2
+
3
+ export type GridColumns = 1 | 2 | 3 | 4 | 6 | 12
4
+ export type GridGap = "none" | "sm" | "md" | "lg"
5
+
6
+ export interface GridProps {
7
+ children: React.ReactNode
8
+ className?: string
9
+ style?: React.CSSProperties
10
+ columns?: GridColumns
11
+ columnsMd?: GridColumns
12
+ columnsLg?: GridColumns
13
+ gap?: GridGap
14
+ as?: "div" | "ul" | "ol"
15
+ }
16
+
17
+ export function Grid({
18
+ children,
19
+ className,
20
+ style,
21
+ columns = 1,
22
+ columnsMd,
23
+ columnsLg,
24
+ gap = "md",
25
+ as: Component = "div",
26
+ }: GridProps) {
27
+ const classes = cx(
28
+ "bc-grid",
29
+ `bc-grid--cols-${columns}`,
30
+ `bc-grid--gap-${gap}`,
31
+ columnsMd && `bc-grid--cols-md-${columnsMd}`,
32
+ columnsLg && `bc-grid--cols-lg-${columnsLg}`,
33
+ className
34
+ )
35
+
36
+ return (
37
+ <Component className={classes} style={style}>
38
+ {children}
39
+ </Component>
40
+ )
41
+ }
42
+
43
+ export interface GridItemProps {
44
+ children: React.ReactNode
45
+ className?: string
46
+ style?: React.CSSProperties
47
+ span?: number
48
+ spanMd?: number
49
+ spanLg?: number
50
+ }
51
+
52
+ export function GridItem({
53
+ children,
54
+ className,
55
+ style,
56
+ span,
57
+ spanMd,
58
+ spanLg,
59
+ }: GridItemProps) {
60
+ const classes = cx(
61
+ "bc-grid__item",
62
+ span && `bc-grid__item--span-${span}`,
63
+ spanMd && `bc-grid__item--span-md-${spanMd}`,
64
+ spanLg && `bc-grid__item--span-lg-${spanLg}`,
65
+ className
66
+ )
67
+
68
+ return (
69
+ <div className={classes} style={style}>
70
+ {children}
71
+ </div>
72
+ )
73
+ }
74
+
75
+ export default Grid
@@ -0,0 +1,2 @@
1
+ export { Grid, GridItem, type GridProps, type GridItemProps, type GridColumns, type GridGap } from "./Grid"
2
+ export { default } from "./Grid"