@buildcanada/components 0.3.2 → 0.3.4

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 (145) hide show
  1. package/dist/content/Card/Card.d.ts +62 -0
  2. package/dist/content/Card/Card.d.ts.map +1 -0
  3. package/dist/content/Card/Card.js +45 -0
  4. package/dist/content/Card/index.d.ts +3 -0
  5. package/dist/content/Card/index.d.ts.map +1 -0
  6. package/dist/content/Card/index.js +2 -0
  7. package/dist/content/Hero/Hero.d.ts +28 -0
  8. package/dist/content/Hero/Hero.d.ts.map +1 -0
  9. package/dist/content/Hero/Hero.js +16 -0
  10. package/dist/content/Hero/index.d.ts +3 -0
  11. package/dist/content/Hero/index.d.ts.map +1 -0
  12. package/dist/content/Hero/index.js +2 -0
  13. package/dist/content/StatBlock/StatBlock.d.ts +15 -0
  14. package/dist/content/StatBlock/StatBlock.d.ts.map +1 -0
  15. package/dist/content/StatBlock/StatBlock.js +10 -0
  16. package/dist/content/StatBlock/index.d.ts +3 -0
  17. package/dist/content/StatBlock/index.d.ts.map +1 -0
  18. package/dist/content/StatBlock/index.js +2 -0
  19. package/dist/feedback/Dialog/Dialog.d.ts +18 -0
  20. package/dist/feedback/Dialog/Dialog.d.ts.map +1 -0
  21. package/dist/feedback/Dialog/Dialog.js +33 -0
  22. package/{src/feedback/Dialog/index.ts → dist/feedback/Dialog/index.d.ts} +2 -1
  23. package/dist/feedback/Dialog/index.d.ts.map +1 -0
  24. package/dist/feedback/Dialog/index.js +1 -0
  25. package/dist/feedback/PopupForm/PopupForm.d.ts +24 -0
  26. package/dist/feedback/PopupForm/PopupForm.d.ts.map +1 -0
  27. package/dist/feedback/PopupForm/PopupForm.js +13 -0
  28. package/dist/feedback/PopupForm/index.d.ts +2 -0
  29. package/dist/feedback/PopupForm/index.d.ts.map +1 -0
  30. package/dist/feedback/PopupForm/index.js +1 -0
  31. package/{src/index.ts → dist/index.d.ts} +16 -56
  32. package/dist/index.d.ts.map +1 -0
  33. package/dist/index.js +25 -0
  34. package/dist/layout/Container/Container.d.ts +11 -0
  35. package/dist/layout/Container/Container.d.ts.map +1 -0
  36. package/dist/layout/Container/Container.js +7 -0
  37. package/dist/layout/Container/index.d.ts +3 -0
  38. package/dist/layout/Container/index.d.ts.map +1 -0
  39. package/dist/layout/Container/index.js +2 -0
  40. package/dist/layout/Divider/Divider.d.ts +12 -0
  41. package/dist/layout/Divider/Divider.d.ts.map +1 -0
  42. package/dist/layout/Divider/Divider.js +7 -0
  43. package/dist/layout/Divider/index.d.ts +3 -0
  44. package/dist/layout/Divider/index.d.ts.map +1 -0
  45. package/dist/layout/Divider/index.js +2 -0
  46. package/dist/layout/Grid/Grid.d.ts +24 -0
  47. package/dist/layout/Grid/Grid.d.ts.map +1 -0
  48. package/dist/layout/Grid/Grid.js +11 -0
  49. package/dist/layout/Grid/index.d.ts +3 -0
  50. package/dist/layout/Grid/index.d.ts.map +1 -0
  51. package/dist/layout/Grid/index.js +2 -0
  52. package/dist/layout/Section/Section.d.ts +13 -0
  53. package/dist/layout/Section/Section.d.ts.map +1 -0
  54. package/dist/layout/Section/Section.js +7 -0
  55. package/dist/layout/Section/index.d.ts +3 -0
  56. package/dist/layout/Section/index.d.ts.map +1 -0
  57. package/dist/layout/Section/index.js +2 -0
  58. package/dist/layout/Stack/Stack.d.ts +18 -0
  59. package/dist/layout/Stack/Stack.d.ts.map +1 -0
  60. package/dist/layout/Stack/Stack.js +7 -0
  61. package/dist/layout/Stack/index.d.ts +3 -0
  62. package/dist/layout/Stack/index.d.ts.map +1 -0
  63. package/dist/layout/Stack/index.js +2 -0
  64. package/dist/navigation/Footer/Footer.d.ts +31 -0
  65. package/dist/navigation/Footer/Footer.d.ts.map +1 -0
  66. package/dist/navigation/Footer/Footer.js +21 -0
  67. package/dist/navigation/Footer/index.d.ts +3 -0
  68. package/dist/navigation/Footer/index.d.ts.map +1 -0
  69. package/dist/navigation/Footer/index.js +2 -0
  70. package/dist/navigation/Header/Header.d.ts +23 -0
  71. package/dist/navigation/Header/Header.d.ts.map +1 -0
  72. package/dist/navigation/Header/Header.js +16 -0
  73. package/dist/navigation/Header/index.d.ts +3 -0
  74. package/dist/navigation/Header/index.d.ts.map +1 -0
  75. package/dist/navigation/Header/index.js +2 -0
  76. package/dist/primitives/Button/Button.d.ts +31 -0
  77. package/dist/primitives/Button/Button.d.ts.map +1 -0
  78. package/dist/primitives/Button/Button.js +36 -0
  79. package/dist/primitives/Button/index.d.ts +3 -0
  80. package/dist/primitives/Button/index.d.ts.map +1 -0
  81. package/dist/primitives/Button/index.js +2 -0
  82. package/dist/primitives/Checkbox/Checkbox.d.ts +13 -0
  83. package/dist/primitives/Checkbox/Checkbox.d.ts.map +1 -0
  84. package/dist/primitives/Checkbox/Checkbox.js +10 -0
  85. package/dist/primitives/Checkbox/index.d.ts +3 -0
  86. package/dist/primitives/Checkbox/index.d.ts.map +1 -0
  87. package/dist/primitives/Checkbox/index.js +2 -0
  88. package/dist/primitives/TextField/TextField.d.ts +22 -0
  89. package/dist/primitives/TextField/TextField.d.ts.map +1 -0
  90. package/dist/primitives/TextField/TextField.js +14 -0
  91. package/dist/primitives/TextField/index.d.ts +3 -0
  92. package/dist/primitives/TextField/index.d.ts.map +1 -0
  93. package/dist/primitives/TextField/index.js +2 -0
  94. package/package.json +11 -11
  95. package/src/assets/fonts/financier-text-regular.woff2 +0 -0
  96. package/src/assets/fonts/founders-grotesk-mono-regular.woff2 +0 -0
  97. package/src/assets/fonts/soehne-kraftig.woff2 +0 -0
  98. package/src/content/Card/Card.tsx +0 -170
  99. package/src/content/Card/index.ts +0 -22
  100. package/src/content/Hero/Hero.tsx +0 -63
  101. package/src/content/Hero/index.ts +0 -13
  102. package/src/content/StatBlock/StatBlock.tsx +0 -52
  103. package/src/content/StatBlock/index.ts +0 -2
  104. package/src/feedback/Dialog/Dialog.tsx +0 -120
  105. package/src/feedback/PopupForm/PopupForm.tsx +0 -90
  106. package/src/feedback/PopupForm/index.ts +0 -1
  107. package/src/layout/Container/Container.tsx +0 -29
  108. package/src/layout/Container/index.ts +0 -2
  109. package/src/layout/Divider/Divider.tsx +0 -32
  110. package/src/layout/Divider/index.ts +0 -2
  111. package/src/layout/Grid/Grid.tsx +0 -75
  112. package/src/layout/Grid/index.ts +0 -2
  113. package/src/layout/Section/Section.tsx +0 -37
  114. package/src/layout/Section/index.ts +0 -2
  115. package/src/layout/Stack/Stack.tsx +0 -48
  116. package/src/layout/Stack/index.ts +0 -9
  117. package/src/navigation/Footer/Footer.tsx +0 -174
  118. package/src/navigation/Footer/index.ts +0 -2
  119. package/src/navigation/Header/Header.tsx +0 -185
  120. package/src/navigation/Header/index.ts +0 -2
  121. package/src/primitives/Button/Button.tsx +0 -120
  122. package/src/primitives/Button/index.ts +0 -2
  123. package/src/primitives/Checkbox/Checkbox.tsx +0 -75
  124. package/src/primitives/Checkbox/index.ts +0 -2
  125. package/src/primitives/TextField/TextField.tsx +0 -105
  126. package/src/primitives/TextField/index.ts +0 -2
  127. /package/{src → dist}/content/Card/Card.scss +0 -0
  128. /package/{src → dist}/content/Hero/Hero.scss +0 -0
  129. /package/{src → dist}/content/StatBlock/StatBlock.scss +0 -0
  130. /package/{src → dist}/feedback/Dialog/Dialog.scss +0 -0
  131. /package/{src → dist}/feedback/PopupForm/PopupForm.scss +0 -0
  132. /package/{src → dist}/layout/Container/Container.scss +0 -0
  133. /package/{src → dist}/layout/Divider/Divider.scss +0 -0
  134. /package/{src → dist}/layout/Grid/Grid.scss +0 -0
  135. /package/{src → dist}/layout/Section/Section.scss +0 -0
  136. /package/{src → dist}/layout/Stack/Stack.scss +0 -0
  137. /package/{src → dist}/navigation/Footer/Footer.scss +0 -0
  138. /package/{src → dist}/navigation/Header/Header.scss +0 -0
  139. /package/{src → dist}/primitives/Button/Button.scss +0 -0
  140. /package/{src → dist}/primitives/Checkbox/Checkbox.scss +0 -0
  141. /package/{src → dist}/primitives/TextField/TextField.scss +0 -0
  142. /package/{src → dist}/styles/fonts.scss +0 -0
  143. /package/{src → dist}/styles/main.scss +0 -0
  144. /package/{src → dist}/styles/tokens.scss +0 -0
  145. /package/{src → dist}/styles/typography.scss +0 -0
@@ -1,37 +0,0 @@
1
- import cx from "classnames"
2
-
3
- export type SectionBackground = "white" | "linen" | "charcoal"
4
- export type SectionSpacing = "none" | "sm" | "md" | "lg" | "xl"
5
-
6
- export interface SectionProps {
7
- children: React.ReactNode
8
- className?: string
9
- style?: React.CSSProperties
10
- background?: SectionBackground
11
- spacing?: SectionSpacing
12
- id?: string
13
- }
14
-
15
- export function Section({
16
- children,
17
- className,
18
- style,
19
- background = "white",
20
- spacing = "lg",
21
- id,
22
- }: SectionProps) {
23
- const classes = cx(
24
- "bc-section",
25
- `bc-section--bg-${background}`,
26
- `bc-section--spacing-${spacing}`,
27
- className
28
- )
29
-
30
- return (
31
- <section className={classes} style={style} id={id}>
32
- {children}
33
- </section>
34
- )
35
- }
36
-
37
- export default Section
@@ -1,2 +0,0 @@
1
- export { Section, type SectionProps, type SectionBackground, type SectionSpacing } from "./Section"
2
- export { default } from "./Section"
@@ -1,48 +0,0 @@
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
@@ -1,9 +0,0 @@
1
- export {
2
- Stack,
3
- type StackProps,
4
- type StackDirection,
5
- type StackSpacing,
6
- type StackAlign,
7
- type StackJustify,
8
- } from "./Stack"
9
- export { default } from "./Stack"
@@ -1,174 +0,0 @@
1
- import cx from "classnames"
2
-
3
- export interface FooterLink {
4
- label: string
5
- href: string
6
- }
7
-
8
- export interface SocialLink {
9
- platform: "twitter" | "linkedin" | "instagram" | "github" | "email" | "bluesky"
10
- href: string
11
- label?: string
12
- }
13
-
14
- export interface FooterProps {
15
- logo?: React.ReactNode
16
- links?: FooterLink[]
17
- socialLinks?: SocialLink[]
18
- newsletter?: {
19
- heading: string
20
- description?: string
21
- placeholder?: string
22
- buttonText?: string
23
- onSubmit?: (email: string) => void
24
- }
25
- quote?: {
26
- text: string
27
- attribution: string
28
- }
29
- copyright?: string
30
- className?: string
31
- style?: React.CSSProperties
32
- }
33
-
34
- const socialIcons: Record<SocialLink["platform"], React.ReactNode> = {
35
- twitter: (
36
- <svg viewBox="0 0 24 24" fill="currentColor" aria-hidden="true">
37
- <path d="M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-5.214-6.817L4.99 21.75H1.68l7.73-8.835L1.254 2.25H8.08l4.713 6.231zm-1.161 17.52h1.833L7.084 4.126H5.117z" />
38
- </svg>
39
- ),
40
- linkedin: (
41
- <svg viewBox="0 0 24 24" fill="currentColor" aria-hidden="true">
42
- <path d="M20.447 20.452h-3.554v-5.569c0-1.328-.027-3.037-1.852-3.037-1.853 0-2.136 1.445-2.136 2.939v5.667H9.351V9h3.414v1.561h.046c.477-.9 1.637-1.85 3.37-1.85 3.601 0 4.267 2.37 4.267 5.455v6.286zM5.337 7.433c-1.144 0-2.063-.926-2.063-2.065 0-1.138.92-2.063 2.063-2.063 1.14 0 2.064.925 2.064 2.063 0 1.139-.925 2.065-2.064 2.065zm1.782 13.019H3.555V9h3.564v11.452zM22.225 0H1.771C.792 0 0 .774 0 1.729v20.542C0 23.227.792 24 1.771 24h20.451C23.2 24 24 23.227 24 22.271V1.729C24 .774 23.2 0 22.222 0h.003z" />
43
- </svg>
44
- ),
45
- instagram: (
46
- <svg viewBox="0 0 24 24" fill="currentColor" aria-hidden="true">
47
- <path d="M12.315 2c2.43 0 2.784.013 3.808.06 1.064.049 1.791.218 2.427.465a4.902 4.902 0 011.772 1.153 4.902 4.902 0 011.153 1.772c.247.636.416 1.363.465 2.427.048 1.067.06 1.407.06 4.123v.08c0 2.643-.012 2.987-.06 4.043-.049 1.064-.218 1.791-.465 2.427a4.902 4.902 0 01-1.153 1.772 4.902 4.902 0 01-1.772 1.153c-.636.247-1.363.416-2.427.465-1.067.048-1.407.06-4.123.06h-.08c-2.643 0-2.987-.012-4.043-.06-1.064-.049-1.791-.218-2.427-.465a4.902 4.902 0 01-1.772-1.153 4.902 4.902 0 01-1.153-1.772c-.247-.636-.416-1.363-.465-2.427-.047-1.024-.06-1.379-.06-3.808v-.63c0-2.43.013-2.784.06-3.808.049-1.064.218-1.791.465-2.427a4.902 4.902 0 011.153-1.772A4.902 4.902 0 015.45 2.525c.636-.247 1.363-.416 2.427-.465C8.901 2.013 9.256 2 11.685 2h.63zm-.081 1.802h-.468c-2.456 0-2.784.011-3.807.058-.975.045-1.504.207-1.857.344-.467.182-.8.398-1.15.748-.35.35-.566.683-.748 1.15-.137.353-.3.882-.344 1.857-.047 1.023-.058 1.351-.058 3.807v.468c0 2.456.011 2.784.058 3.807.045.975.207 1.504.344 1.857.182.466.399.8.748 1.15.35.35.683.566 1.15.748.353.137.882.3 1.857.344 1.054.048 1.37.058 4.041.058h.08c2.597 0 2.917-.01 3.96-.058.976-.045 1.505-.207 1.858-.344.466-.182.8-.398 1.15-.748.35-.35.566-.683.748-1.15.137-.353.3-.882.344-1.857.048-1.055.058-1.37.058-4.041v-.08c0-2.597-.01-2.917-.058-3.96-.045-.976-.207-1.505-.344-1.858a3.097 3.097 0 00-.748-1.15 3.098 3.098 0 00-1.15-.748c-.353-.137-.882-.3-1.857-.344-1.023-.047-1.351-.058-3.807-.058zM12 6.865a5.135 5.135 0 110 10.27 5.135 5.135 0 010-10.27zm0 1.802a3.333 3.333 0 100 6.666 3.333 3.333 0 000-6.666zm5.338-3.205a1.2 1.2 0 110 2.4 1.2 1.2 0 010-2.4z" />
48
- </svg>
49
- ),
50
- github: (
51
- <svg viewBox="0 0 24 24" fill="currentColor" aria-hidden="true">
52
- <path d="M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12" />
53
- </svg>
54
- ),
55
- email: (
56
- <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" aria-hidden="true">
57
- <path d="M3 8l7.89 5.26a2 2 0 002.22 0L21 8M5 19h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z" />
58
- </svg>
59
- ),
60
- bluesky: (
61
- <svg viewBox="0 0 24 24" fill="currentColor" aria-hidden="true">
62
- <path d="M12 10.8c-1.087-2.114-4.046-6.053-6.798-7.995C2.566.944 1.561 1.266.902 1.565.139 1.908 0 3.08 0 3.768c0 .69.378 5.65.624 6.479.815 2.736 3.713 3.66 6.383 3.364.136-.02.275-.039.415-.056-.138.022-.276.04-.415.056-3.912.58-7.387 2.005-2.83 7.078 5.013 5.19 6.87-1.113 7.823-4.308.953 3.195 2.05 9.271 7.733 4.308 4.267-4.308 1.172-6.498-2.74-7.078a8.741 8.741 0 01-.415-.056c.14.017.279.036.415.056 2.67.297 5.568-.628 6.383-3.364.246-.828.624-5.79.624-6.478 0-.69-.139-1.861-.902-2.206-.659-.298-1.664-.62-4.3 1.24C16.046 4.748 13.087 8.687 12 10.8z" />
63
- </svg>
64
- ),
65
- }
66
-
67
- export function Footer({
68
- logo,
69
- links = [],
70
- socialLinks = [],
71
- newsletter,
72
- quote,
73
- copyright,
74
- className,
75
- style,
76
- }: FooterProps) {
77
- const classes = cx("bc-footer", className)
78
-
79
- const handleNewsletterSubmit = (e: React.FormEvent<HTMLFormElement>) => {
80
- e.preventDefault()
81
- const formData = new FormData(e.currentTarget)
82
- const email = formData.get("email") as string
83
- newsletter?.onSubmit?.(email)
84
- }
85
-
86
- return (
87
- <footer className={classes} style={style}>
88
- <div className="bc-footer__inner">
89
- <div className="bc-footer__main">
90
- {logo && <div className="bc-footer__logo">{logo}</div>}
91
-
92
- {links.length > 0 && (
93
- <nav className="bc-footer__nav" aria-label="Footer navigation">
94
- <ul className="bc-footer__nav-list">
95
- {links.map((link) => (
96
- <li key={link.label}>
97
- <a href={link.href} className="bc-footer__nav-link">
98
- {link.label}
99
- </a>
100
- </li>
101
- ))}
102
- </ul>
103
- </nav>
104
- )}
105
-
106
- {newsletter && (
107
- <div className="bc-footer__newsletter">
108
- <h4 className="bc-footer__newsletter-heading">
109
- {newsletter.heading}
110
- </h4>
111
- {newsletter.description && (
112
- <p className="bc-footer__newsletter-description">
113
- {newsletter.description}
114
- </p>
115
- )}
116
- <form
117
- className="bc-footer__newsletter-form"
118
- onSubmit={handleNewsletterSubmit}
119
- >
120
- <input
121
- type="email"
122
- name="email"
123
- placeholder={newsletter.placeholder || "Enter your email"}
124
- className="bc-footer__newsletter-input"
125
- required
126
- />
127
- <button
128
- type="submit"
129
- className="bc-footer__newsletter-button"
130
- >
131
- {newsletter.buttonText || "Subscribe"}
132
- </button>
133
- </form>
134
- </div>
135
- )}
136
- </div>
137
-
138
- <div className="bc-footer__bottom">
139
- {socialLinks.length > 0 && (
140
- <div className="bc-footer__social">
141
- {socialLinks.map((link) => (
142
- <a
143
- key={link.platform}
144
- href={link.href}
145
- className="bc-footer__social-link"
146
- aria-label={link.label || link.platform}
147
- >
148
- {socialIcons[link.platform]}
149
- </a>
150
- ))}
151
- </div>
152
- )}
153
-
154
- {copyright && (
155
- <p className="bc-footer__copyright">{copyright}</p>
156
- )}
157
- </div>
158
-
159
- {quote && (
160
- <div className="bc-footer__quote">
161
- <blockquote className="bc-footer__quote-text">
162
- {quote.text}
163
- </blockquote>
164
- <cite className="bc-footer__quote-attribution">
165
- — {quote.attribution}
166
- </cite>
167
- </div>
168
- )}
169
- </div>
170
- </footer>
171
- )
172
- }
173
-
174
- export default Footer
@@ -1,2 +0,0 @@
1
- export { Footer, type FooterProps, type FooterLink, type SocialLink } from "./Footer"
2
- export { default } from "./Footer"
@@ -1,185 +0,0 @@
1
- import cx from "classnames"
2
- import { useState } from "react"
3
-
4
- export interface NavItem {
5
- label: string
6
- href: string
7
- dropdown?: NavItem[]
8
- }
9
-
10
- export interface HeaderProps {
11
- logo: React.ReactNode
12
- navItems?: NavItem[]
13
- cta?: {
14
- label: string
15
- href: string
16
- }
17
- announcement?: {
18
- text: string
19
- href?: string
20
- variant?: "default" | "auburn"
21
- }
22
- className?: string
23
- style?: React.CSSProperties
24
- }
25
-
26
- export function Header({
27
- logo,
28
- navItems = [],
29
- cta,
30
- announcement,
31
- className,
32
- style,
33
- }: HeaderProps) {
34
- const [mobileMenuOpen, setMobileMenuOpen] = useState(false)
35
- const [openDropdown, setOpenDropdown] = useState<string | null>(null)
36
-
37
- const classes = cx("bc-header", className)
38
-
39
- return (
40
- <header className={classes} style={style}>
41
- {announcement && (
42
- <div
43
- className={cx("bc-header__announcement", {
44
- "bc-header__announcement--auburn":
45
- announcement.variant === "auburn",
46
- })}
47
- >
48
- {announcement.href ? (
49
- <a href={announcement.href}>{announcement.text}</a>
50
- ) : (
51
- <span>{announcement.text}</span>
52
- )}
53
- </div>
54
- )}
55
- <div className="bc-header__main">
56
- <div className="bc-header__logo">{logo}</div>
57
-
58
- <nav className="bc-header__nav" aria-label="Main navigation">
59
- <ul className="bc-header__nav-list">
60
- {navItems.map((item) => (
61
- <li
62
- key={item.label}
63
- className={cx("bc-header__nav-item", {
64
- "bc-header__nav-item--has-dropdown": item.dropdown,
65
- })}
66
- onMouseEnter={() =>
67
- item.dropdown && setOpenDropdown(item.label)
68
- }
69
- onMouseLeave={() =>
70
- item.dropdown && setOpenDropdown(null)
71
- }
72
- >
73
- {item.dropdown ? (
74
- <>
75
- <button
76
- className="bc-header__nav-link bc-header__nav-link--dropdown"
77
- aria-expanded={openDropdown === item.label}
78
- aria-haspopup="true"
79
- >
80
- {item.label}
81
- <svg
82
- className="bc-header__dropdown-icon"
83
- viewBox="0 0 20 20"
84
- fill="currentColor"
85
- aria-hidden="true"
86
- >
87
- <path
88
- fillRule="evenodd"
89
- d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z"
90
- clipRule="evenodd"
91
- />
92
- </svg>
93
- </button>
94
- {openDropdown === item.label && (
95
- <ul className="bc-header__dropdown">
96
- {item.dropdown.map((subItem) => (
97
- <li key={subItem.label}>
98
- <a
99
- href={subItem.href}
100
- className="bc-header__dropdown-link"
101
- >
102
- {subItem.label}
103
- </a>
104
- </li>
105
- ))}
106
- </ul>
107
- )}
108
- </>
109
- ) : (
110
- <a href={item.href} className="bc-header__nav-link">
111
- {item.label}
112
- </a>
113
- )}
114
- </li>
115
- ))}
116
- </ul>
117
- </nav>
118
-
119
- {cta && (
120
- <a href={cta.href} className="bc-header__cta">
121
- {cta.label}
122
- </a>
123
- )}
124
-
125
- <button
126
- className="bc-header__mobile-toggle"
127
- onClick={() => setMobileMenuOpen(!mobileMenuOpen)}
128
- aria-expanded={mobileMenuOpen}
129
- aria-label="Toggle navigation menu"
130
- >
131
- <span className="bc-header__hamburger" />
132
- </button>
133
- </div>
134
-
135
- {/* Mobile Menu */}
136
- <div
137
- className={cx("bc-header__mobile-menu", {
138
- "bc-header__mobile-menu--open": mobileMenuOpen,
139
- })}
140
- >
141
- <nav aria-label="Mobile navigation">
142
- <ul className="bc-header__mobile-nav">
143
- {navItems.map((item) => (
144
- <li key={item.label}>
145
- <a
146
- href={item.href}
147
- className="bc-header__mobile-link"
148
- onClick={() => setMobileMenuOpen(false)}
149
- >
150
- {item.label}
151
- </a>
152
- {item.dropdown && (
153
- <ul className="bc-header__mobile-subnav">
154
- {item.dropdown.map((subItem) => (
155
- <li key={subItem.label}>
156
- <a
157
- href={subItem.href}
158
- className="bc-header__mobile-link bc-header__mobile-link--sub"
159
- onClick={() => setMobileMenuOpen(false)}
160
- >
161
- {subItem.label}
162
- </a>
163
- </li>
164
- ))}
165
- </ul>
166
- )}
167
- </li>
168
- ))}
169
- </ul>
170
- {cta && (
171
- <a
172
- href={cta.href}
173
- className="bc-header__mobile-cta"
174
- onClick={() => setMobileMenuOpen(false)}
175
- >
176
- {cta.label}
177
- </a>
178
- )}
179
- </nav>
180
- </div>
181
- </header>
182
- )
183
- }
184
-
185
- export default Header
@@ -1,2 +0,0 @@
1
- export { Header, type HeaderProps, type NavItem } from "./Header"
2
- export { default } from "./Header"
@@ -1,120 +0,0 @@
1
- import cx from "classnames"
2
- import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"
3
- import { IconDefinition, faArrowRight } from "@fortawesome/free-solid-svg-icons"
4
-
5
- export type ButtonVariant =
6
- | "solid-auburn"
7
- | "solid-charcoal"
8
- | "solid-linen"
9
- | "outline-auburn"
10
- | "outline-charcoal"
11
- | "outline-white"
12
-
13
- export type ButtonSize = "sm" | "md" | "lg"
14
-
15
- type ButtonCommonProps = {
16
- children?: React.ReactNode
17
- text?: string
18
- className?: string
19
- style?: React.CSSProperties
20
- variant?: ButtonVariant
21
- size?: ButtonSize
22
- icon?: IconDefinition | null
23
- iconPosition?: "left" | "right"
24
- fullWidth?: boolean
25
- disabled?: boolean
26
- ariaLabel?: string
27
- dataTrackNote?: string
28
- }
29
-
30
- type WithHrefProps = {
31
- href: string
32
- onClick?: never
33
- type?: never
34
- }
35
-
36
- type WithOnClickProps = {
37
- onClick?: () => void
38
- href?: never
39
- type?: "button" | "submit"
40
- }
41
-
42
- export type ButtonProps =
43
- | (ButtonCommonProps & WithHrefProps)
44
- | (ButtonCommonProps & WithOnClickProps)
45
-
46
- export function Button({
47
- variant = "solid-auburn",
48
- size = "md",
49
- className,
50
- style,
51
- href,
52
- onClick,
53
- text,
54
- children,
55
- ariaLabel,
56
- type = "button",
57
- icon = faArrowRight,
58
- iconPosition = "right",
59
- fullWidth = false,
60
- dataTrackNote,
61
- disabled,
62
- }: ButtonProps) {
63
- const classes = cx(
64
- "bc-btn",
65
- `bc-btn--${variant}`,
66
- `bc-btn--${size}`,
67
- className,
68
- {
69
- "bc-btn--icon-only": icon && !text && !children,
70
- "bc-btn--full-width": fullWidth,
71
- }
72
- )
73
-
74
- const content = (
75
- <>
76
- {iconPosition === "left" && icon && (
77
- <FontAwesomeIcon
78
- className={cx("bc-btn__icon", { "bc-btn__icon--left": text || children })}
79
- icon={icon}
80
- />
81
- )}
82
- {text && <span className="bc-btn__text">{text}</span>}
83
- {children}
84
- {iconPosition !== "left" && icon && (
85
- <FontAwesomeIcon
86
- className={cx("bc-btn__icon", { "bc-btn__icon--right": text || children })}
87
- icon={icon}
88
- />
89
- )}
90
- </>
91
- )
92
-
93
- if (href) {
94
- const aProps = {
95
- href: disabled ? undefined : href,
96
- className: classes,
97
- style,
98
- "data-track-note": dataTrackNote,
99
- onClick: disabled
100
- ? (e: React.MouseEvent) => e.preventDefault()
101
- : undefined,
102
- "aria-label": ariaLabel,
103
- "aria-disabled": disabled,
104
- }
105
- return <a {...aProps}>{content}</a>
106
- }
107
-
108
- const buttonProps = {
109
- type,
110
- className: classes,
111
- style,
112
- onClick,
113
- "aria-label": ariaLabel,
114
- "data-track-note": dataTrackNote,
115
- disabled,
116
- }
117
- return <button {...buttonProps}>{content}</button>
118
- }
119
-
120
- export default Button
@@ -1,2 +0,0 @@
1
- export { Button, type ButtonProps, type ButtonVariant, type ButtonSize } from "./Button"
2
- export { default } from "./Button"
@@ -1,75 +0,0 @@
1
- import cx from "classnames"
2
- import { forwardRef, useId } from "react"
3
-
4
- export interface CheckboxProps {
5
- label: string
6
- checked?: boolean
7
- defaultChecked?: boolean
8
- name?: string
9
- id?: string
10
- className?: string
11
- disabled?: boolean
12
- onChange?: (e: React.ChangeEvent<HTMLInputElement>) => void
13
- }
14
-
15
- export const Checkbox = forwardRef<HTMLInputElement, CheckboxProps>(
16
- function Checkbox(
17
- {
18
- label,
19
- checked,
20
- defaultChecked,
21
- name,
22
- id: providedId,
23
- className,
24
- disabled = false,
25
- onChange,
26
- },
27
- ref
28
- ) {
29
- const generatedId = useId()
30
- const id = providedId || generatedId
31
-
32
- const classes = cx(
33
- "bc-checkbox",
34
- { "bc-checkbox--disabled": disabled },
35
- className
36
- )
37
-
38
- return (
39
- <div className={classes}>
40
- <input
41
- ref={ref}
42
- type="checkbox"
43
- id={id}
44
- name={name}
45
- checked={checked}
46
- defaultChecked={defaultChecked}
47
- disabled={disabled}
48
- className="bc-checkbox__input"
49
- onChange={onChange}
50
- />
51
- <label htmlFor={id} className="bc-checkbox__label">
52
- <span className="bc-checkbox__box">
53
- <svg
54
- className="bc-checkbox__check"
55
- viewBox="0 0 14 14"
56
- fill="none"
57
- xmlns="http://www.w3.org/2000/svg"
58
- >
59
- <path
60
- d="M11.5 4L5.5 10L2.5 7"
61
- stroke="currentColor"
62
- strokeWidth="2"
63
- strokeLinecap="square"
64
- strokeLinejoin="round"
65
- />
66
- </svg>
67
- </span>
68
- <span className="bc-checkbox__text">{label}</span>
69
- </label>
70
- </div>
71
- )
72
- }
73
- )
74
-
75
- export default Checkbox
@@ -1,2 +0,0 @@
1
- export { Checkbox, type CheckboxProps } from "./Checkbox"
2
- export { default } from "./Checkbox"