-
Notifications
You must be signed in to change notification settings - Fork 9
/
Heading.tsx
137 lines (133 loc) · 3.06 KB
/
Heading.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
import { type ReactElement, type ReactNode } from "react";
import Typography from "../Typography/Typography";
import { useTheme } from "../ThemeProvider/ThemeProvider";
function cambioWeight({
fontStyle,
size,
}: {
fontStyle: "serif" | "sans-serif";
size: 400 | 500 | 600 | 700 | 800 | 900 | 1000 | 1100;
}): "bold" | "medium" | "regular" {
if (fontStyle === "serif" && [400, 500, 600].includes(size)) {
return "bold";
} else if (fontStyle === "serif") {
return "medium";
} else {
return "regular";
}
}
/**
* [Heading](https://cambly-syntax.vercel.app/?path=/docs/components-heading--docs) enforces a consistent style & accessibility best practices for headings.
*/
const Heading = ({
align = "start",
as = "h1",
children,
color = "gray900",
"data-testid": dataTestId,
fontStyle = "sans-serif",
lineClamp,
size = 500,
}: {
/**
* Aligns the text to the left, right, or center of the container.
* * `start` and `end` will align the text to the left or right of the container depending on the locale.
* * `forceLeft` and `forceRight` will align the text to the left or right of the container regardless of the locale (should be used sparingly).
*
* @defaultValue "start"
*/
align?: "start" | "end" | "forceLeft" | "center" | "forceRight";
/**
* DOM element to render as.
*
* @defaultValue "h1"
*/
as?: "h1" | "h2" | "h3" | "h4" | "h5" | "h6";
/**
* The text to be rendered
*/
children?: ReactNode;
/**
* The color of the text.
*
* @defaultValue "gray900"
*/
color?:
| "gray900"
| "gray700"
| "primary"
| "destructive-primary"
| "success"
| "white"
| "inherit";
/**
* Test id for the text.
*/
"data-testid"?: string;
/**
* Style of the font
*
* Classic only supports `sans-serif`
*
* @defaultValue "sans-serif"
*/
fontStyle?: "serif" | "sans-serif";
/**
* The number of lines we should truncate the text at
*/
lineClamp?: number | undefined;
/**
* Size of the text.
*
* Classic:
* * `500`: 20px
* * `600`: 28px
* * `700`: 40px
* * `800`: 64px
*
* Cambio Mobile:
* * `400`: 20px
* * `500`: 23px
* * `600`: 26px
* * `700`: 29px
* * `800`: 33px
* * `900`: 37px
* * `1000`: 41px
* * `1100`: 46px
*
* Cambio Desktop (viewport width > 480px):
* * `400`: 25px
* * `500`: 31px
* * `600`: 39px
* * `700`: 49px
* * `800`: 61px
* * `900`: 76px
* * `1000`: 95px
* * `1100`: 119px
*
* @defaultValue 500
*/
size?: 400 | 500 | 600 | 700 | 800 | 900 | 1000 | 1100;
}): ReactElement => {
const { themeName } = useTheme();
const classicWeight = [700, 800].includes(size) ? "heavy" : "bold";
return (
<Typography
align={align}
as={as}
color={color}
fontStyle={fontStyle}
data-testid={dataTestId}
lineClamp={lineClamp}
size={size}
weight={
themeName === "classic"
? classicWeight
: cambioWeight({ fontStyle, size })
}
>
{children}
</Typography>
);
};
export default Heading;