Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Typography/Heading: add Cambio options & styles #323

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/strange-pillows-repair.md
@@ -0,0 +1,5 @@
---
"@cambly/syntax-core": minor
---

Typography/Heading: add Cambio styles & options
2 changes: 1 addition & 1 deletion packages/syntax-core/src/Checkbox/Checkbox.tsx
Expand Up @@ -125,7 +125,7 @@ const Checkbox = ({
/>
<Typography
size={typographySize[size]}
color={error ? "destructive-primary" : "gray800"}
color={error ? "destructive-primary" : "gray900"}
>
{label}
</Typography>
Expand Down
24 changes: 22 additions & 2 deletions packages/syntax-core/src/Heading/Heading.stories.tsx
Expand Up @@ -26,6 +26,7 @@ export default {
color: {
options: [
"destructive-primary",
"black",
"gray700",
"gray900",
"primary",
Expand All @@ -34,10 +35,17 @@ export default {
],
control: { type: "radio" },
},
size: {
options: [500, 600, 700, 800],
lineClamp: {
control: { type: "number", min: 0, max: 10, step: 1 },
},
fontStyle: {
options: ["serif", "sans-serif"],
control: { type: "radio" },
},
size: {
options: [400, 500, 600, 700, 800, 900, 1000, 1100],
control: { type: "select" },
},
},
tags: ["autodocs"],
} as Meta<typeof Heading>;
Expand All @@ -51,6 +59,9 @@ export const Default: StoryObj<typeof Heading> = {
export const Sizes: StoryObj<typeof Heading> = {
render: (args) => (
<>
<Heading {...args} size={400}>
Size 400 (Cambio only)
</Heading>
<Heading {...args} size={500}>
Size 500
</Heading>
Expand All @@ -63,6 +74,15 @@ export const Sizes: StoryObj<typeof Heading> = {
<Heading {...args} size={800}>
Size 800
</Heading>
<Heading {...args} size={900}>
Size 900 (Cambio only)
</Heading>
<Heading {...args} size={1000}>
Size 1000 (Cambio only)
</Heading>
<Heading {...args} size={1100}>
Size 1100 (Cambio only)
</Heading>
</>
),
};
Expand Down
51 changes: 46 additions & 5 deletions packages/syntax-core/src/Heading/Heading.tsx
@@ -1,6 +1,6 @@
import { type ReactElement, type ReactNode } from "react";
import { type Color } from "../constants";
import Typography from "../Typography/Typography";
import { useTheme } from "../ThemeProvider/ThemeProvider";

/**
* [Heading](https://cambly-syntax.vercel.app/?path=/docs/components-heading--docs) enforces a consistent style & accessibility best practices for headings.
Expand All @@ -11,6 +11,7 @@ const Heading = ({
children,
color = "gray900",
"data-testid": dataTestId,
fontStyle,
lineClamp,
size = 500,
}: {
Expand All @@ -37,37 +38,77 @@ const Heading = ({
*
* @defaultValue "gray900"
*/
color?: (typeof Color)[number];
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?: 500 | 600 | 700 | 800;
size?: 400 | 500 | 600 | 700 | 800 | 900 | 1000 | 1100;
}): ReactElement => {
const weight = [700, 800].includes(size) ? "heavy" : "bold";
const { themeName } = useTheme();
const classicWeight = [700, 800].includes(size) ? "heavy" : "bold";
const cambioWeight = fontStyle === "serif" ? "medium" : "regular";

return (
<Typography
align={align}
as={as}
color={color}
fontStyle={fontStyle}
data-testid={dataTestId}
lineClamp={lineClamp}
size={size}
weight={weight}
weight={themeName === "classic" ? classicWeight : cambioWeight}
>
{children}
</Typography>
Expand Down
2 changes: 1 addition & 1 deletion packages/syntax-core/src/RadioButton/RadioButton.tsx
Expand Up @@ -138,7 +138,7 @@ const RadioButton = ({
{label && (
<Typography
size={size === "md" ? 200 : 100}
color={error ? "destructive-primary" : "gray800"}
color={error ? "destructive-primary" : "gray900"}
>
{label}
</Typography>
Expand Down
6 changes: 6 additions & 0 deletions packages/syntax-core/src/ThemeProvider/ThemeProvider.test.tsx
Expand Up @@ -44,6 +44,9 @@ describe("themeProvider", () => {
expect(screen.getByTestId("themeprovider-style")).toContainHTML(
"--color-base-gray-10: rgba(203, 203, 203, 0.5);",
);
expect(screen.getByTestId("themeprovider-style")).toContainHTML(
"--elevation-400: 0px 16px 32px 0px #00000040;",
);
expect(screen.getByTestId("themeprovider-style")).not.toContainHTML(
"cambio",
);
Expand All @@ -68,6 +71,9 @@ describe("themeProvider", () => {
expect(screen.getByTestId("themeprovider-style")).toContainHTML(
"--color-base-primary-100: #faf4eb;",
);
expect(screen.getByTestId("themeprovider-style")).not.toContainHTML(
"elevation",
);
expect(screen.getByTestId("themeprovider-style")).toContainHTML("cambio");
});
});
7 changes: 6 additions & 1 deletion packages/syntax-core/src/ThemeProvider/ThemeProvider.tsx
Expand Up @@ -90,9 +90,14 @@ function stylesForTheme(themeName: ThemeName) {
],
];
}
// `elevation` is a classic only concept
if (themeName === "cambio" && key.includes("elevation")) {
return [null, null];
}
return [key, value];
})
.map(([key, value]) => `--${key}: ${value};`)
.map(([key, value]) => (key && value ? `--${key}: ${value};` : null))
.filter(Boolean)
.join("\n")}
}
`;
Expand Down
118 changes: 118 additions & 0 deletions packages/syntax-core/src/Typography/Typography.module.css
@@ -1,9 +1,32 @@
.typography {
margin: 0;
}

@font-face {
font-family: GT-Super-Text-Medium;
font-style: normal;
font-weight: 500;
src: local("GT-Super-Text-Medium"),
/* TODO fix CORS issues and change to url("https://static.cambly.com/fonts/GT-Super-Text-Medium.woff2") */
url("https://partners.rebelmouse.com/protocol/GT-Super-Text-Medium.woff2")
format("woff2");

/* TODO enable Most performant option - see https://web.dev/articles/font-best-practices */

/* font-display: optional; */
}

.sansSerif {
font-family: -apple-system, system-ui, BlinkMacSystemFont, "Segoe UI", Roboto,
Helvetica, Arial, sans-serif;
margin: 0;
}

.serif {
font-family: GT-Super-Text-Medium, -apple-system, system-ui,
BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, serif;
}

/* Sizes */
.size100 {
font-size: 12px;
Expand Down Expand Up @@ -33,6 +56,89 @@
font-size: 64px;
}

/* Sizes - Cambio sizes are responsive */
.size100Cambio {
font-size: 14px;
}

.size200Cambio {
font-size: 16px;
}

.size300Cambio {
font-size: 18px;
}

.size400Cambio {
font-size: 20px;
}

.size500Cambio {
font-size: 23px;
}

.size600Cambio {
font-size: 26px;
}

.size700Cambio {
font-size: 33px;
}

.size800Cambio {
font-size: 41px;
}

.size900Cambio {
font-size: 46px;
}

@media (min-width: 480px) {
.size100Cambio {
font-size: 13px;
}

.size200Cambio {
font-size: 16px;
}

.size300Cambio {
font-size: 20px;
}

.size400Cambio {
font-size: 25px;
}

.size500Cambio {
font-size: 31px;
}

.size600Cambio {
font-size: 39px;
}

.size700Cambio {
font-size: 49px;
}

.size800Cambio {
font-size: 61px;
}

.size900Cambio {
font-size: 76px;
}

.size1000Cambio {
font-size: 95px;
}

.size1100Cambio {
font-size: 119px;
}
}

/* Align */
.center {
text-align: center;
Expand Down Expand Up @@ -75,6 +181,18 @@
font-weight: 860;
}

.regularCambio {
font-weight: 400;
}

.mediumCambio {
font-weight: 510;
}

.semiBoldCambio {
font-weight: 590;
}

.underline {
text-decoration: underline;
}
Expand Down