Skip to content

Commit

Permalink
Build out Typography components
Browse files Browse the repository at this point in the history
  • Loading branch information
jessepinho committed Jul 11, 2024
1 parent f7261a3 commit 6c1d8f2
Show file tree
Hide file tree
Showing 2 changed files with 231 additions and 0 deletions.
84 changes: 84 additions & 0 deletions packages/ui/src/Typography/index.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
import type { Meta, StoryObj } from '@storybook/react';

import { Body, Detail, H1, H2, H3, H4, Large, P, Small, Strong, Technical } from '.';
import styled from 'styled-components';

const meta: Meta<typeof Body> = {
title: 'Typography',
tags: ['autodocs'],
};
export default meta;

const Wrapper = styled.div({ color: 'white' });

export const KitchenSink: StoryObj = {
render: function Render() {
return (
<Wrapper>
<H1>H1: This is a heading</H1>
<H2>H2: This is a heading</H2>
<H3>H3: This is a heading</H3>
<H4>H4: This is a heading</H4>
<Large as='p'>Large: This is large text used for section titles</Large>
<Body as='p'>Body: This is body text used throughout most of our UIs</Body>
<Strong as='p'>Strong: This is emphasized body text used in various components</Strong>
<Small as='p'>Small: This is small text used for secondary information</Small>
<Detail as='p'>
Detail: This is detail text used for small bits of tertiary information
</Detail>
<Technical as='p'>
Technical: This is monospaced text used for code, values, and other technical information
</Technical>
</Wrapper>
);
},
};

export const UsageExample: StoryObj<typeof Body> = {
render: function Render() {
return (
<Wrapper>
<H1>h1. Typography</H1>
<H2>h2. This is a section</H2>
<P>
<Strong>Here is some filler text:</Strong> Giggster kickstarter painting with light
academy award charlie kaufman shotdeck breakdown services indie white balance. Student
emmys sound design ots character arc low angle coming-of-age composition. Storyboard beat
sheet greenlight cowboy shot margarita shot blocking foley stage seed&spark.
</P>

<P>
Shot list low angle mit out sound telephoto rec.709 high angle eyeline assembly cut 8 1/2
dga. Post-viz circle of confusion location scout unpaid internship reality of doing genre
film. Jean-luc godard ilm symbolism alexa mini white balance margarita shot. Jordan peele
log line ryan coogler actors access.
</P>

<H2>h2. Section two</H2>
<P>
Silent film conflict sound design blocking script treatment. Teal and orange composition
fotokem third act blackmagic ingmar bergman jordan peele rembrandt lighting critical
darling silent film. Wes anderson arthouse diegetic sound after effects.
</P>

<Large>This is some large text.</Large>

<P>
White balance crafty debut film pan up 180-degree rule academy award exposure triangle
director&apos;s vision. Lavs led wall the actor prepares wrylies character arc stinger
sanford meisner. Given circumstances under-exposed jordan peele color grade nomadland team
deakins crafty dogme 95. French new wave pan up save the cat contrast ratio blue filter
cinema studies super 16 jump cut cannes unreal engine.
</P>

<P>
Establishing shot stella adler ludwig göransson first-time director shotdeck fotokem
over-exposed flashback reality of doing color grade. Fetch coffee student emmys indie key
light rembrandt lighting. Undercranking beat beat scriptnotes podcast. Sound design
academy award day-for-night christopher nolan undercranking. Unreal engine visionary match
cut grain vs. noise 35mm anti-hero production design.
</P>
</Wrapper>
);
},
};
147 changes: 147 additions & 0 deletions packages/ui/src/Typography/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
import styled, { DefaultTheme } from 'styled-components';

const base = {
margin: 0,
};

type Spec = typeof base & {
fontFamily: string;
fontSize: string;
fontWeight: number;
lineHeight: string;
};

export const STYLES_BY_VARIANT = (theme: DefaultTheme) =>
({
h1: {
...base,
fontFamily: theme.fonts.heading,
fontSize: theme.fontSizes.text6xl,
fontWeight: 500,
lineHeight: '3.75rem',
},
h2: {
...base,
fontFamily: theme.fonts.heading,
fontSize: theme.fontSizes.text5xl,
fontWeight: 500,
lineHeight: '3rem',
},
h3: {
...base,
fontFamily: theme.fonts.heading,
fontSize: theme.fontSizes.text4xl,
fontWeight: 500,
lineHeight: '2.5rem',
},
h4: {
...base,
fontFamily: theme.fonts.heading,
fontSize: theme.fontSizes.text3xl,
fontWeight: 500,
lineHeight: '2.25rem',
},
large: {
...base,
fontFamily: theme.fonts.default,
fontSize: theme.fontSizes.textLg,
fontWeight: 500,
lineHeight: '1.75rem',
},
body: {
...base,
fontFamily: theme.fonts.default,
fontSize: theme.fontSizes.textBase,
fontWeight: 400,
lineHeight: '1.5rem',
},
bodyEmphasized: {
...base,
fontFamily: theme.fonts.default,
fontSize: theme.fontSizes.textBase,
fontWeight: 500,
lineHeight: '1.5rem',
},
button: {
...base,
fontFamily: theme.fonts.default,
fontSize: theme.fontSizes.textBase,
fontWeight: 500,
lineHeight: '1.5rem',
},
detail: {
...base,
fontFamily: theme.fonts.default,
fontSize: theme.fontSizes.textXs,
fontWeight: 500,
lineHeight: '1rem',
},
small: {
...base,
fontFamily: theme.fonts.default,
fontSize: theme.fontSizes.textSm,
fontWeight: 400,
lineHeight: '1.25rem',
},
tab: {
...base,
fontFamily: theme.fonts.default,
fontSize: theme.fontSizes.textLg,
fontWeight: 400,
lineHeight: '1.75rem',
},
tableHeading: {
...base,
fontFamily: theme.fonts.default,
fontSize: theme.fontSizes.textBase,
fontWeight: 500,
lineHeight: '1.5rem',
},
tableItem: {
...base,
fontFamily: theme.fonts.default,
fontSize: theme.fontSizes.textBase,
fontWeight: 400,
lineHeight: '1.5rem',
},
technical: {
...base,
fontFamily: theme.fonts.mono,
fontSize: theme.fontSizes.textSm,
fontWeight: 500,
lineHeight: '1.25rem',
},
}) satisfies Record<string, Spec>;

export const H1 = styled.h1(props => STYLES_BY_VARIANT(props.theme).h1);
export const H2 = styled.h2(props => STYLES_BY_VARIANT(props.theme).h2);
export const H3 = styled.h3(props => STYLES_BY_VARIANT(props.theme).h3);
export const H4 = styled.h4(props => STYLES_BY_VARIANT(props.theme).h4);
export const Large = styled.span(props => STYLES_BY_VARIANT(props.theme).large);
export const Body = styled.span(props => STYLES_BY_VARIANT(props.theme).body);
export const Strong = styled.span(props => STYLES_BY_VARIANT(props.theme).bodyEmphasized);
export const Detail = styled.span(props => STYLES_BY_VARIANT(props.theme).detail);
export const Small = styled.span(props => STYLES_BY_VARIANT(props.theme).small);
export const Technical = styled.span(props => STYLES_BY_VARIANT(props.theme).technical);

/**
* Renders a styled `<p />` tag with a bottom-margin (unless it's the last
* child). Aside from the margin, `<P />` is identical to `<Body />`.
*
* Note that this is the only component in the entire Penumbra UI library that
* renders an external margin. It's a convenience for developers who don't want
* to wrap each `<P />` in a `<div />` with the appropriate margin, or a flex
* columnn with a gap.
*/
export const P = styled.p(props => {
const styles = STYLES_BY_VARIANT(props.theme).body;

return {
...styles,
marginBottom: styles.lineHeight,

'&:last-child': {
marginBottom: 0,
},
};
});

0 comments on commit 6c1d8f2

Please sign in to comment.