-
Notifications
You must be signed in to change notification settings - Fork 23
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Migrate typography components to KAIO (#4046)
* Migrate Heading & Paragraph components to KAIO * MDX lint fixes * Rename Paragraph component to Text
- Loading branch information
1 parent
f23ccdd
commit d1b1a1e
Showing
17 changed files
with
1,073 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
--- | ||
--- |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
@import "~@kaizen/design-tokens/sass/color"; | ||
@import "~@kaizen/design-tokens/sass/typography"; | ||
|
||
.heading { | ||
margin: 0; | ||
} | ||
|
||
.display-0 { | ||
font-family: $typography-display-0-font-family; | ||
font-weight: $typography-display-0-font-weight; | ||
font-size: $typography-display-0-font-size; | ||
line-height: $typography-display-0-line-height; | ||
letter-spacing: $typography-display-0-letter-spacing; | ||
} | ||
|
||
.heading-1 { | ||
font-family: $typography-heading-1-font-family; | ||
font-weight: $typography-heading-1-font-weight; | ||
font-size: $typography-heading-1-font-size; | ||
line-height: $typography-heading-1-line-height; | ||
letter-spacing: $typography-heading-1-letter-spacing; | ||
} | ||
|
||
.heading-2 { | ||
font-family: $typography-heading-2-font-family; | ||
font-weight: $typography-heading-2-font-weight; | ||
font-size: $typography-heading-2-font-size; | ||
line-height: $typography-heading-2-line-height; | ||
letter-spacing: $typography-heading-2-letter-spacing; | ||
} | ||
|
||
.heading-3 { | ||
font-family: $typography-heading-3-font-family; | ||
font-weight: $typography-heading-3-font-weight; | ||
font-size: $typography-heading-3-font-size; | ||
line-height: $typography-heading-3-line-height; | ||
letter-spacing: $typography-heading-3-letter-spacing; | ||
} | ||
|
||
.heading-4 { | ||
font-family: $typography-heading-4-font-family; | ||
font-weight: $typography-heading-4-font-weight; | ||
font-size: $typography-heading-4-font-size; | ||
line-height: $typography-heading-4-line-height; | ||
letter-spacing: $typography-heading-4-letter-spacing; | ||
} | ||
|
||
.heading-5 { | ||
font-family: $typography-heading-5-font-family; | ||
font-weight: $typography-heading-5-font-weight; | ||
font-size: $typography-heading-5-font-size; | ||
line-height: $typography-heading-5-line-height; | ||
letter-spacing: $typography-heading-5-letter-spacing; | ||
} | ||
|
||
.heading-6 { | ||
font-family: $typography-heading-6-font-family; | ||
font-weight: $typography-heading-6-font-weight; | ||
font-size: $typography-heading-6-font-size; | ||
line-height: $typography-heading-6-line-height; | ||
letter-spacing: $typography-heading-6-letter-spacing; | ||
} | ||
|
||
.dark { | ||
color: $color-purple-800; | ||
opacity: 100%; | ||
} | ||
|
||
.dark-reduced-opacity { | ||
color: $color-purple-800; | ||
opacity: 70%; | ||
} | ||
|
||
.white { | ||
color: $color-white; | ||
opacity: 100%; | ||
} | ||
|
||
.white-reduced-opacity { | ||
color: $color-white; | ||
opacity: 80%; | ||
} | ||
|
||
.positive { | ||
&.small { | ||
color: $color-green-600; | ||
} | ||
|
||
&.large { | ||
color: $color-green-500; | ||
} | ||
} | ||
|
||
.negative { | ||
&.small { | ||
color: $color-red-600; | ||
} | ||
|
||
&.large { | ||
color: $color-red-500; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
import * as React from "react" | ||
import { render } from "@testing-library/react" | ||
import { AllowedHeadingTags, Heading, HeadingVariants } from "./" | ||
|
||
describe("<Heading />", () => { | ||
it("renders the correct classes", () => { | ||
const headingMock = render(<Heading variant="display-0">Example</Heading>) | ||
const headingClasslist = headingMock.getByText("Example").classList | ||
expect(headingClasslist).toContain("heading") | ||
expect(headingClasslist).toContain("display-0") | ||
expect(headingClasslist).toContain("large") | ||
}) | ||
|
||
it("adds a .small class instead of .large if a Heading 3 is used", () => { | ||
const headingMock = render( | ||
<Heading variant="heading-3" tag="div"> | ||
Example | ||
</Heading> | ||
) | ||
expect(headingMock.getByText("Example").classList).toContain("small") | ||
expect(headingMock.getByText("Example").classList).not.toContain("large") | ||
}) | ||
|
||
it("adds a .dark-reduced-opacity class if the color prop is set to that", () => { | ||
const headingMock = render( | ||
<Heading variant="heading-3" color="dark-reduced-opacity"> | ||
Example | ||
</Heading> | ||
) | ||
expect(headingMock.getByText("Example").classList).toContain( | ||
"dark-reduced-opacity" | ||
) | ||
}) | ||
|
||
it("changes rendered HTML element when passed tag", () => { | ||
const headingMock = render( | ||
<Heading variant="display-0" tag="div"> | ||
Example | ||
</Heading> | ||
) | ||
expect(headingMock.getByText("Example").tagName).toBe("DIV") | ||
}) | ||
|
||
it("passes through data attributes", () => { | ||
const { container } = render( | ||
<Heading variant="display-0" data-automation-id="test-id"> | ||
Example | ||
</Heading> | ||
) | ||
expect( | ||
container.querySelector('[data-automation-id="test-id"]') | ||
).not.toBeNull() | ||
}) | ||
|
||
describe("defaults to the correct HTML element", () => { | ||
type TestObject = { variant: HeadingVariants; el: AllowedHeadingTags } | ||
const testCases: TestObject[] = [ | ||
{ variant: "display-0", el: "h1" }, | ||
{ variant: "heading-1", el: "h1" }, | ||
{ variant: "heading-2", el: "h2" }, | ||
{ variant: "heading-3", el: "h3" }, | ||
{ variant: "heading-4", el: "h4" }, | ||
{ variant: "heading-5", el: "h5" }, | ||
{ variant: "heading-6", el: "h6" }, | ||
] | ||
|
||
testCases.forEach(({ variant, el }) => { | ||
it(`renders the correct element for <Heading variant={${variant}} />`, () => { | ||
const headingMock = render(<Heading variant={variant}>Example</Heading>) | ||
expect(headingMock.getByText("Example").tagName.toLowerCase()).toBe(el) | ||
expect(headingMock.baseElement).toMatchSnapshot() | ||
}) | ||
}) | ||
}) | ||
|
||
it("allows consumers to provide a className", () => { | ||
const { getByText } = render( | ||
<Heading variant="heading-4" classNameOverride="example-classname"> | ||
Example | ||
</Heading> | ||
) | ||
expect(getByText("Example").classList).toContain("example-classname") | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
import { createElement, HTMLAttributes } from "react" | ||
import classnames from "classnames" | ||
import { OverrideClassName } from "~types/OverrideClassName" | ||
import styles from "./Heading.module.scss" | ||
|
||
const VARIANTS_24PX_OR_GREATER = ["display-0", "heading-1", "heading-2"] | ||
|
||
export type HeadingVariants = | ||
| "display-0" | ||
| "heading-1" | ||
| "heading-2" | ||
| "heading-3" | ||
| "heading-4" | ||
| "heading-5" | ||
| "heading-6" | ||
|
||
export type AllowedHeadingTags = | ||
| "pre" | ||
| "p" | ||
| "div" | ||
| "span" | ||
| "h1" | ||
| "h2" | ||
| "h3" | ||
| "h4" | ||
| "h5" | ||
| "h6" | ||
| "label" | ||
|
||
export type AllowedHeadingColors = | ||
| "dark" | ||
| "dark-reduced-opacity" | ||
| "white" | ||
| "white-reduced-opacity" | ||
| "positive" | ||
| "negative" | ||
|
||
export interface HeadingProps | ||
extends OverrideClassName<HTMLAttributes<HTMLElement>> { | ||
children: React.ReactNode | ||
/** | ||
* HTML elements that are allowed on Headings. When not supplied, the tag is inferred from | ||
* the variant. E.g. display-0 will infer h1 | ||
*/ | ||
tag?: AllowedHeadingTags | ||
/** | ||
* Allowed heading variants | ||
*/ | ||
variant: HeadingVariants | ||
color?: AllowedHeadingColors | ||
} | ||
|
||
/** | ||
* {@link https://cultureamp.atlassian.net/wiki/spaces/DesignSystem/pages/3074885298/Typography#Headings Guidance} | ||
* {@link https://cultureamp.design/?path=/docs/components-typography-heading--display-0 Storybook} | ||
*/ | ||
export const Heading = ({ | ||
children, | ||
tag, | ||
variant, | ||
color = "dark", | ||
classNameOverride, | ||
...restProps | ||
}: HeadingProps): JSX.Element => { | ||
const inferredTag = | ||
tag === undefined ? translateHeadingLevelToTag(variant) : tag | ||
|
||
const className = classnames( | ||
styles.heading, | ||
styles[variant], | ||
classNameOverride, | ||
styles[color], | ||
VARIANTS_24PX_OR_GREATER.includes(variant) ? styles.large : styles.small | ||
) | ||
|
||
return createElement(inferredTag, { ...restProps, className }, children) | ||
} | ||
|
||
Heading.displayName = "Heading" | ||
|
||
/** | ||
* A helper to infer the tag when not explicitly passed as a prop | ||
* @param headingLevel Level of the heading | ||
*/ | ||
const translateHeadingLevelToTag = (headingLevel: HeadingVariants): string => { | ||
switch (headingLevel) { | ||
case "display-0": | ||
case "heading-1": | ||
return "h1" | ||
case "heading-2": | ||
return "h2" | ||
case "heading-3": | ||
return "h3" | ||
case "heading-4": | ||
return "h4" | ||
case "heading-5": | ||
return "h5" | ||
case "heading-6": | ||
default: | ||
return "h6" | ||
} | ||
} |
85 changes: 85 additions & 0 deletions
85
packages/components/src/Heading/__snapshots__/Heading.spec.tsx.snap
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
// Jest Snapshot v1, https://goo.gl/fbAQLP | ||
|
||
exports[`<Heading /> defaults to the correct HTML element renders the correct element for <Heading variant={display-0} /> 1`] = ` | ||
<body> | ||
<div> | ||
<h1 | ||
class="heading display-0 dark large" | ||
> | ||
Example | ||
</h1> | ||
</div> | ||
</body> | ||
`; | ||
|
||
exports[`<Heading /> defaults to the correct HTML element renders the correct element for <Heading variant={heading-1} /> 1`] = ` | ||
<body> | ||
<div> | ||
<h1 | ||
class="heading heading-1 dark large" | ||
> | ||
Example | ||
</h1> | ||
</div> | ||
</body> | ||
`; | ||
|
||
exports[`<Heading /> defaults to the correct HTML element renders the correct element for <Heading variant={heading-2} /> 1`] = ` | ||
<body> | ||
<div> | ||
<h2 | ||
class="heading heading-2 dark large" | ||
> | ||
Example | ||
</h2> | ||
</div> | ||
</body> | ||
`; | ||
|
||
exports[`<Heading /> defaults to the correct HTML element renders the correct element for <Heading variant={heading-3} /> 1`] = ` | ||
<body> | ||
<div> | ||
<h3 | ||
class="heading heading-3 dark small" | ||
> | ||
Example | ||
</h3> | ||
</div> | ||
</body> | ||
`; | ||
|
||
exports[`<Heading /> defaults to the correct HTML element renders the correct element for <Heading variant={heading-4} /> 1`] = ` | ||
<body> | ||
<div> | ||
<h4 | ||
class="heading heading-4 dark small" | ||
> | ||
Example | ||
</h4> | ||
</div> | ||
</body> | ||
`; | ||
|
||
exports[`<Heading /> defaults to the correct HTML element renders the correct element for <Heading variant={heading-5} /> 1`] = ` | ||
<body> | ||
<div> | ||
<h5 | ||
class="heading heading-5 dark small" | ||
> | ||
Example | ||
</h5> | ||
</div> | ||
</body> | ||
`; | ||
|
||
exports[`<Heading /> defaults to the correct HTML element renders the correct element for <Heading variant={heading-6} /> 1`] = ` | ||
<body> | ||
<div> | ||
<h6 | ||
class="heading heading-6 dark small" | ||
> | ||
Example | ||
</h6> | ||
</div> | ||
</body> | ||
`; |
Oops, something went wrong.