@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.
- package/dist/content/Card/Card.d.ts +62 -0
- package/dist/content/Card/Card.d.ts.map +1 -0
- package/dist/content/Card/Card.js +45 -0
- package/dist/content/Card/index.d.ts +3 -0
- package/dist/content/Card/index.d.ts.map +1 -0
- package/dist/content/Card/index.js +2 -0
- package/dist/content/Hero/Hero.d.ts +28 -0
- package/dist/content/Hero/Hero.d.ts.map +1 -0
- package/dist/content/Hero/Hero.js +16 -0
- package/dist/content/Hero/index.d.ts +3 -0
- package/dist/content/Hero/index.d.ts.map +1 -0
- package/dist/content/Hero/index.js +2 -0
- package/dist/content/StatBlock/StatBlock.d.ts +15 -0
- package/dist/content/StatBlock/StatBlock.d.ts.map +1 -0
- package/dist/content/StatBlock/StatBlock.js +10 -0
- package/dist/content/StatBlock/index.d.ts +3 -0
- package/dist/content/StatBlock/index.d.ts.map +1 -0
- package/dist/content/StatBlock/index.js +2 -0
- package/dist/feedback/Dialog/Dialog.d.ts +18 -0
- package/dist/feedback/Dialog/Dialog.d.ts.map +1 -0
- package/dist/feedback/Dialog/Dialog.js +33 -0
- package/{src/feedback/Dialog/index.ts → dist/feedback/Dialog/index.d.ts} +2 -1
- package/dist/feedback/Dialog/index.d.ts.map +1 -0
- package/dist/feedback/Dialog/index.js +1 -0
- package/dist/feedback/PopupForm/PopupForm.d.ts +24 -0
- package/dist/feedback/PopupForm/PopupForm.d.ts.map +1 -0
- package/dist/feedback/PopupForm/PopupForm.js +13 -0
- package/dist/feedback/PopupForm/index.d.ts +2 -0
- package/dist/feedback/PopupForm/index.d.ts.map +1 -0
- package/dist/feedback/PopupForm/index.js +1 -0
- package/{src/index.ts → dist/index.d.ts} +16 -56
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +25 -0
- package/dist/layout/Container/Container.d.ts +11 -0
- package/dist/layout/Container/Container.d.ts.map +1 -0
- package/dist/layout/Container/Container.js +7 -0
- package/dist/layout/Container/index.d.ts +3 -0
- package/dist/layout/Container/index.d.ts.map +1 -0
- package/dist/layout/Container/index.js +2 -0
- package/dist/layout/Divider/Divider.d.ts +12 -0
- package/dist/layout/Divider/Divider.d.ts.map +1 -0
- package/dist/layout/Divider/Divider.js +7 -0
- package/dist/layout/Divider/index.d.ts +3 -0
- package/dist/layout/Divider/index.d.ts.map +1 -0
- package/dist/layout/Divider/index.js +2 -0
- package/dist/layout/Grid/Grid.d.ts +24 -0
- package/dist/layout/Grid/Grid.d.ts.map +1 -0
- package/dist/layout/Grid/Grid.js +11 -0
- package/dist/layout/Grid/index.d.ts +3 -0
- package/dist/layout/Grid/index.d.ts.map +1 -0
- package/dist/layout/Grid/index.js +2 -0
- package/dist/layout/Section/Section.d.ts +13 -0
- package/dist/layout/Section/Section.d.ts.map +1 -0
- package/dist/layout/Section/Section.js +7 -0
- package/dist/layout/Section/index.d.ts +3 -0
- package/dist/layout/Section/index.d.ts.map +1 -0
- package/dist/layout/Section/index.js +2 -0
- package/dist/layout/Stack/Stack.d.ts +18 -0
- package/dist/layout/Stack/Stack.d.ts.map +1 -0
- package/dist/layout/Stack/Stack.js +7 -0
- package/dist/layout/Stack/index.d.ts +3 -0
- package/dist/layout/Stack/index.d.ts.map +1 -0
- package/dist/layout/Stack/index.js +2 -0
- package/dist/navigation/Footer/Footer.d.ts +31 -0
- package/dist/navigation/Footer/Footer.d.ts.map +1 -0
- package/dist/navigation/Footer/Footer.js +21 -0
- package/dist/navigation/Footer/index.d.ts +3 -0
- package/dist/navigation/Footer/index.d.ts.map +1 -0
- package/dist/navigation/Footer/index.js +2 -0
- package/dist/navigation/Header/Header.d.ts +23 -0
- package/dist/navigation/Header/Header.d.ts.map +1 -0
- package/dist/navigation/Header/Header.js +16 -0
- package/dist/navigation/Header/index.d.ts +3 -0
- package/dist/navigation/Header/index.d.ts.map +1 -0
- package/dist/navigation/Header/index.js +2 -0
- package/dist/primitives/Button/Button.d.ts +31 -0
- package/dist/primitives/Button/Button.d.ts.map +1 -0
- package/dist/primitives/Button/Button.js +36 -0
- package/dist/primitives/Button/index.d.ts +3 -0
- package/dist/primitives/Button/index.d.ts.map +1 -0
- package/dist/primitives/Button/index.js +2 -0
- package/dist/primitives/Checkbox/Checkbox.d.ts +13 -0
- package/dist/primitives/Checkbox/Checkbox.d.ts.map +1 -0
- package/dist/primitives/Checkbox/Checkbox.js +10 -0
- package/dist/primitives/Checkbox/index.d.ts +3 -0
- package/dist/primitives/Checkbox/index.d.ts.map +1 -0
- package/dist/primitives/Checkbox/index.js +2 -0
- package/dist/primitives/TextField/TextField.d.ts +22 -0
- package/dist/primitives/TextField/TextField.d.ts.map +1 -0
- package/dist/primitives/TextField/TextField.js +14 -0
- package/dist/primitives/TextField/index.d.ts +3 -0
- package/dist/primitives/TextField/index.d.ts.map +1 -0
- package/dist/primitives/TextField/index.js +2 -0
- package/package.json +11 -11
- package/src/assets/fonts/financier-text-regular.woff2 +0 -0
- package/src/assets/fonts/founders-grotesk-mono-regular.woff2 +0 -0
- package/src/assets/fonts/soehne-kraftig.woff2 +0 -0
- package/src/content/Card/Card.tsx +0 -170
- package/src/content/Card/index.ts +0 -22
- package/src/content/Hero/Hero.tsx +0 -63
- package/src/content/Hero/index.ts +0 -13
- package/src/content/StatBlock/StatBlock.tsx +0 -52
- package/src/content/StatBlock/index.ts +0 -2
- package/src/feedback/Dialog/Dialog.tsx +0 -120
- package/src/feedback/PopupForm/PopupForm.tsx +0 -90
- package/src/feedback/PopupForm/index.ts +0 -1
- package/src/layout/Container/Container.tsx +0 -29
- package/src/layout/Container/index.ts +0 -2
- package/src/layout/Divider/Divider.tsx +0 -32
- package/src/layout/Divider/index.ts +0 -2
- package/src/layout/Grid/Grid.tsx +0 -75
- package/src/layout/Grid/index.ts +0 -2
- package/src/layout/Section/Section.tsx +0 -37
- package/src/layout/Section/index.ts +0 -2
- package/src/layout/Stack/Stack.tsx +0 -48
- package/src/layout/Stack/index.ts +0 -9
- package/src/navigation/Footer/Footer.tsx +0 -174
- package/src/navigation/Footer/index.ts +0 -2
- package/src/navigation/Header/Header.tsx +0 -185
- package/src/navigation/Header/index.ts +0 -2
- package/src/primitives/Button/Button.tsx +0 -120
- package/src/primitives/Button/index.ts +0 -2
- package/src/primitives/Checkbox/Checkbox.tsx +0 -75
- package/src/primitives/Checkbox/index.ts +0 -2
- package/src/primitives/TextField/TextField.tsx +0 -105
- package/src/primitives/TextField/index.ts +0 -2
- /package/{src → dist}/content/Card/Card.scss +0 -0
- /package/{src → dist}/content/Hero/Hero.scss +0 -0
- /package/{src → dist}/content/StatBlock/StatBlock.scss +0 -0
- /package/{src → dist}/feedback/Dialog/Dialog.scss +0 -0
- /package/{src → dist}/feedback/PopupForm/PopupForm.scss +0 -0
- /package/{src → dist}/layout/Container/Container.scss +0 -0
- /package/{src → dist}/layout/Divider/Divider.scss +0 -0
- /package/{src → dist}/layout/Grid/Grid.scss +0 -0
- /package/{src → dist}/layout/Section/Section.scss +0 -0
- /package/{src → dist}/layout/Stack/Stack.scss +0 -0
- /package/{src → dist}/navigation/Footer/Footer.scss +0 -0
- /package/{src → dist}/navigation/Header/Header.scss +0 -0
- /package/{src → dist}/primitives/Button/Button.scss +0 -0
- /package/{src → dist}/primitives/Checkbox/Checkbox.scss +0 -0
- /package/{src → dist}/primitives/TextField/TextField.scss +0 -0
- /package/{src → dist}/styles/fonts.scss +0 -0
- /package/{src → dist}/styles/main.scss +0 -0
- /package/{src → dist}/styles/tokens.scss +0 -0
- /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,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,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,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,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,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
|