Skip to content

Commit

Permalink
feat(typography): split into Heading and Text components
Browse files Browse the repository at this point in the history
  • Loading branch information
anniehu4 committed Feb 8, 2021
1 parent d54938b commit 899c202
Show file tree
Hide file tree
Showing 15 changed files with 372 additions and 336 deletions.
6 changes: 6 additions & 0 deletions packages/components/src/Heading/Heading.spec.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import * as HeadingStoryFile from "./Heading.stories";
import { generateSnapshots } from "@chanzuckerberg/story-utils";

describe("<Heading />", () => {
generateSnapshots(HeadingStoryFile);
});
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
import * as React from "react";

import Typography, { TypographyProps } from "./typography";
import Heading from "./Heading";
import { Story } from "@storybook/react/types-6-0";

export default {
title: "Typography",
component: Typography,
title: "Heading",
component: Heading,
};

const Template: Story<TypographyProps> = (args) => <Typography {...args} />;
type Args = React.ComponentProps<typeof Heading>;

const Template: Story<Args> = (args) => <Heading {...args} />;

export const Heading1 = Template.bind(null);
Heading1.args = {
Expand Down Expand Up @@ -45,36 +47,6 @@ Heading5.args = {
children: "Heading 5 12/20",
};

export const Body = Template.bind(null);
Body.args = {
size: "body",
children: "Body paragraph 16/24",
};

export const BodySmall = Template.bind(null);
BodySmall.args = {
size: "sm",
children: "Body small 14/20",
};

export const BodyXSmall = Template.bind(null);
BodyXSmall.args = {
size: "xs",
children: "Body Xsmall 12/16",
};

export const Caption = Template.bind(null);
Caption.args = {
size: "caption",
children: "Caption 12/20",
};

export const Overline = Template.bind(null);
Overline.args = {
size: "overline",
children: "Overline 12/20",
};

export const Heading1AsHeading4 = Template.bind(null);
Heading1AsHeading4.args = {
as: "h1",
Expand Down
69 changes: 69 additions & 0 deletions packages/components/src/Heading/Heading.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import React, { ReactNode } from "react";
import {
TypographyColor,
TypographySize,
styleFromColor,
styleFromSize,
} from "../util/typography";
import tw, { styled } from "twin.macro";

type HeadingElement = "h1" | "h2" | "h3" | "h4" | "h5" | "h6";

type Props = {
/**
* This prop can be used to specify which size heading should
* actually be rendered, in the case that you want to render an element
* as one heading but style it as if it were another. If both an `as` prop
* and a `size` prop are passed, the `as` will be used to determine the element
* and the `size` will be used to determine the styling.
*/
as?: HeadingElement;
/**
* Specifies font weight as either bold or normal (defaults to bold).
* TODO: Currently we will allow toggling any size, but in the future
* we will add stricter enforcement -- e.g. enforcing a boldness
* for each size or checking for mutually exclusive props.
*/
bold?: boolean;
/**
* The text content to present.
*/
children: ReactNode;
/**
* The color of the heading element. If no color provided, defaults to a base color.
*/
color?: TypographyColor;
/**
* The size of the html element. If no `as` prop is provided, then
* the component uses this value to determine which html tag to render
* (e.g. 'h1', 'h2', etc.)
*/
size: TypographySize;
};

interface BaseHeadingProps {
bold: boolean;
color?: TypographyColor;
size: TypographySize;
}

const HeadingComponent = styled.span<BaseHeadingProps>(
({ bold, color, size }) => [
tw`font-arimo`,
bold ? tw`font-bold` : tw`font-normal`,
styleFromColor(color),
styleFromSize(size),
]
);

function Heading(props: Props) {
const { as, bold = true, children, color, size } = props;

return (
<HeadingComponent as={as || size} bold={bold} color={color} size={size}>
{children}
</HeadingComponent>
);
}

export default Heading;
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`<Heading /> Heading1 story renders snapshot 1`] = `
<h1>
Heading 1 24/32
</h1>
`;

exports[`<Heading /> Heading1AsHeading4 story renders snapshot 1`] = `
<h1>
Heading 1 styled as Heading 4
</h1>
`;

exports[`<Heading /> Heading2 story renders snapshot 1`] = `
<h2>
Heading 2 18/24
</h2>
`;

exports[`<Heading /> Heading3 story renders snapshot 1`] = `
<h3>
Heading 3 18/24
</h3>
`;

exports[`<Heading /> Heading4 story renders snapshot 1`] = `
<h4>
Heading 4 14/24
</h4>
`;

exports[`<Heading /> Heading4ColorNeutral story renders snapshot 1`] = `
<h4
color="neutral"
>
Neutral color Heading 4
</h4>
`;

exports[`<Heading /> Heading5 story renders snapshot 1`] = `
<h5>
Heading 5 12/20
</h5>
`;
6 changes: 6 additions & 0 deletions packages/components/src/Text/Text.spec.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import * as TextStoryFile from "./Text.stories";
import { generateSnapshots } from "@chanzuckerberg/story-utils";

describe("<Text />", () => {
generateSnapshots(TextStoryFile);
});
51 changes: 51 additions & 0 deletions packages/components/src/Text/Text.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import * as React from "react";

import { Story } from "@storybook/react/types-6-0";
import Text from "./Text";

export default {
title: "Text",
component: Text,
};

type Args = React.ComponentProps<typeof Text>;

const Template: Story<Args> = (args) => <Text {...args} />;

export const Body = Template.bind(null);
Body.args = {
size: "body",
children: "Body paragraph 16/24",
};

export const BodySmall = Template.bind(null);
BodySmall.args = {
size: "sm",
children: "Body small 14/20",
};

export const BodyXSmall = Template.bind(null);
BodyXSmall.args = {
size: "xs",
children: "Body Xsmall 12/16",
};

export const Caption = Template.bind(null);
Caption.args = {
size: "caption",
children: "Caption 12/20",
};

export const Overline = Template.bind(null);
Overline.args = {
size: "overline",
children: "Overline 12/20",
};

export const BodyColorInfoBold = Template.bind(null);
BodyColorInfoBold.args = {
bold: true,
children: "Info color body text, bold",
color: "info",
size: "body",
};
66 changes: 66 additions & 0 deletions packages/components/src/Text/Text.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import React, { ReactNode } from "react";
import {
TypographyColor,
TypographySize,
styleFromColor,
styleFromSize,
} from "../util/typography";
import tw, { styled } from "twin.macro";

interface BaseTextProps {
bold: boolean;
color?: TypographyColor;
size: TypographySize;
}

const TextComponent = styled.p<BaseTextProps>(({ bold, color, size }) => [
tw`font-arimo`,
bold ? tw`font-bold` : tw`font-normal`,
styleFromColor(color),
styleFromSize(size),
]);

type Props = {
/**
* Specifies font weight as either bold or normal (defaults to normal).
* TODO: We may add stricter enforcement of mutually exclusive props.
*/
bold?: boolean;
/**
* The text content to present.
*/
children: ReactNode;
/**
* The color of the text element. If no color provided, defaults to a base color.
*/
color?: TypographyColor;
/**
* The size of the html element. If used as a Heading and no `as` prop is provided,
* then the component uses this value to determine which html tag to render
* (e.g. 'h1', 'h2', etc.)
*/
size: TypographySize;
};

function Text(props: Props) {
const {
bold = false,
children,
size,
/**
* Components that wrap typography sometimes requires props such as event handlers
* to be passed down into the element. One example is the tooltip component. It
* attaches a onHover and onFocus event to the element to determine when to
* trigger the overlay.
*/
...rest
} = props;

return (
<TextComponent bold={bold} size={size} {...rest}>
{children}
</TextComponent>
);
}

export default Text;
39 changes: 39 additions & 0 deletions packages/components/src/Text/__snapshots__/Text.spec.tsx.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`<Text /> Body story renders snapshot 1`] = `
<p>
Body paragraph 16/24
</p>
`;

exports[`<Text /> BodyColorInfoBold story renders snapshot 1`] = `
<p
color="info"
>
Info color body text, bold
</p>
`;

exports[`<Text /> BodySmall story renders snapshot 1`] = `
<p>
Body small 14/20
</p>
`;

exports[`<Text /> BodyXSmall story renders snapshot 1`] = `
<p>
Body Xsmall 12/16
</p>
`;

exports[`<Text /> Caption story renders snapshot 1`] = `
<p>
Caption 12/20
</p>
`;

exports[`<Text /> Overline story renders snapshot 1`] = `
<p>
Overline 12/20
</p>
`;
Original file line number Diff line number Diff line change
Expand Up @@ -4,40 +4,24 @@ exports[`<Button /> emoji story renders snapshot 1`] = `
<button
aria-label="so cool"
>
<p
color="white"
>
πŸ˜€ 😎 πŸ‘ πŸ’―
</p>
πŸ˜€ 😎 πŸ‘ πŸ’―
</button>
`;

exports[`<Button /> primary story renders snapshot 1`] = `
<button>
<p
color="white"
>
Primary Button
</p>
Primary Button
</button>
`;

exports[`<Button /> secondary story renders snapshot 1`] = `
<button>
<p
color="white"
>
Secondary Button
</p>
Secondary Button
</button>
`;

exports[`<Button /> text story renders snapshot 1`] = `
<button>
<p
color="white"
>
Hello Button
</p>
Hello Button
</button>
`;
Loading

0 comments on commit 899c202

Please sign in to comment.