@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.
- package/package.json +67 -0
- 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.scss +281 -0
- package/src/content/Card/Card.tsx +170 -0
- package/src/content/Card/index.ts +22 -0
- package/src/content/Hero/Hero.scss +150 -0
- package/src/content/Hero/Hero.tsx +63 -0
- package/src/content/Hero/index.ts +13 -0
- package/src/content/StatBlock/StatBlock.scss +83 -0
- package/src/content/StatBlock/StatBlock.tsx +52 -0
- package/src/content/StatBlock/index.ts +2 -0
- package/src/index.ts +57 -0
- package/src/layout/Container/Container.scss +40 -0
- package/src/layout/Container/Container.tsx +29 -0
- package/src/layout/Container/index.ts +2 -0
- package/src/layout/Divider/Divider.scss +117 -0
- package/src/layout/Divider/Divider.tsx +32 -0
- package/src/layout/Divider/index.ts +2 -0
- package/src/layout/Grid/Grid.scss +81 -0
- package/src/layout/Grid/Grid.tsx +75 -0
- package/src/layout/Grid/index.ts +2 -0
- package/src/layout/Section/Section.scss +74 -0
- package/src/layout/Section/Section.tsx +37 -0
- package/src/layout/Section/index.ts +2 -0
- package/src/layout/Stack/Stack.scss +61 -0
- package/src/layout/Stack/Stack.tsx +48 -0
- package/src/layout/Stack/index.ts +9 -0
- package/src/navigation/Footer/Footer.scss +233 -0
- package/src/navigation/Footer/Footer.tsx +174 -0
- package/src/navigation/Footer/index.ts +2 -0
- package/src/navigation/Header/Header.scss +325 -0
- package/src/navigation/Header/Header.tsx +185 -0
- package/src/navigation/Header/index.ts +2 -0
- package/src/primitives/Button/Button.scss +218 -0
- package/src/primitives/Button/Button.tsx +120 -0
- package/src/primitives/Button/index.ts +2 -0
- package/src/primitives/Checkbox/Checkbox.scss +114 -0
- package/src/primitives/Checkbox/Checkbox.tsx +75 -0
- package/src/primitives/Checkbox/index.ts +2 -0
- package/src/primitives/TextField/TextField.scss +93 -0
- package/src/primitives/TextField/TextField.tsx +105 -0
- package/src/primitives/TextField/index.ts +2 -0
- package/src/styles/fonts.scss +27 -0
- package/src/styles/main.scss +34 -0
- package/src/styles/tokens.scss +301 -0
- 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,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
|
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,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,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
|