-
Notifications
You must be signed in to change notification settings - Fork 178
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(components): add helix product typography
- Adds the new sizes for type in the helix product system - Adds a dummy component under "Design Tokens" in storybook so you can view all the text Closes EXEC-566 Make the storybook display all the stories
- Loading branch information
Showing
4 changed files
with
373 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,230 @@ | ||
import * as React from 'react' | ||
import { css } from 'styled-components' | ||
import type { FlattenSimpleInterpolation } from 'styled-components' | ||
import { | ||
ALIGN_CENTER, | ||
Box, | ||
DIRECTION_COLUMN, | ||
Flex, | ||
SPACING, | ||
Text, | ||
PRODUCT, | ||
TYPOGRAPHY, | ||
} from '@opentrons/components' | ||
|
||
import type { Story, Meta } from '@storybook/react' | ||
|
||
const fontStyles = { | ||
'Helix Product (Desktop)': [ | ||
['Display', 'Bold'], | ||
['HeadingLarge', 'Regular'], | ||
['HeadingLarge', 'Bold'], | ||
['HeadingMedium', 'Medium'], | ||
['HeadingSmall', 'Regular'], | ||
['HeadingSmall', 'Bold'], | ||
['BodyLarge', 'Medium'], | ||
['BodyLarge', 'Regular'], | ||
['BodyDefault', 'Medium'], | ||
['BodyDefault', 'Regular'], | ||
['Caption', 'Medium'], | ||
['Caption', 'Regular'], | ||
['Code', 'Regular'], | ||
], | ||
ODD: [ | ||
['level1Header', ''], | ||
['level2Header', 'Bold'], | ||
['level2Header', 'SemiBold'], | ||
['level2Header', 'Regular'], | ||
['level3Header', 'Bold'], | ||
['level3Header', 'SemiBold'], | ||
['level3Header', 'Regular'], | ||
['level4Header', 'Bold'], | ||
['level4Header', 'SemiBold'], | ||
['level4Header', 'Regular'], | ||
['bodyText', 'Bold'], | ||
['bodyText', 'SemiBold'], | ||
['bodyText', 'Regular'], | ||
['smallBodyText', 'Bold'], | ||
['smallBodyText', 'SemiBold'], | ||
['smallBodyText', 'Regular'], | ||
], | ||
'Legacy Desktop': [ | ||
['h1', 'Default'], | ||
['h2', 'Regular'], | ||
['h2', 'SemiBold'], | ||
['h3', 'Regular'], | ||
['h3', 'SemiBold'], | ||
['h6', 'Default'], | ||
['h6', 'SemiBold'], | ||
['p', 'Regular'], | ||
['p', 'SemiBold'], | ||
['label', 'Regular'], | ||
['label', 'SemiBold'], | ||
['linkP', 'SemiBold'], | ||
], | ||
} | ||
|
||
type TypographyStandard = keyof typeof fontStyles | ||
|
||
export default { | ||
title: 'Design Tokens/Typography', | ||
argTypes: { | ||
text: { | ||
type: 'text', | ||
}, | ||
styles: { | ||
control: { | ||
type: 'select', | ||
}, | ||
options: Object.keys(fontStyles), | ||
}, | ||
}, | ||
} as Meta | ||
|
||
interface TypographyStorybookProps { | ||
text: string | ||
styles: TypographyStandard | ||
} | ||
|
||
const convertToPx = (remFormat: string): string => { | ||
const pxVal = Number(remFormat.replace('rem', '')) * 16 | ||
return `${pxVal}px` | ||
} | ||
const styleForPairForHelix = (style: string, weight: string): string => { | ||
const fontPayload = PRODUCT.TYPOGRAPHY[`fontStyle${style}${weight}`] | ||
return css` | ||
font: ${fontPayload}; | ||
` | ||
} | ||
const fontSizeForPairForHelix = (style: string, weight: string): string => { | ||
const fontSize = PRODUCT.TYPOGRAPHY[`fontSize${style}${weight}`] | ||
const fontSizeInPx = convertToPx(fontSize) | ||
return `font-size: ${fontSize}/${fontSizeInPx}` | ||
} | ||
const lineHeightForPairForHelix = (style: string, weight: string): string => { | ||
const lineHeight = PRODUCT.TYPOGRAPHY[`lineHeight${style}${weight}`] | ||
const lineHeightInPx = convertToPx(lineHeight) | ||
return `line-height: ${lineHeight}/${lineHeightInPx}` | ||
} | ||
const fontWeightForPairForHelix = (style: string, weight: string): string => { | ||
const fontWeight = PRODUCT.TYPOGRAPHY[`fontWeight${style}${weight}`] | ||
return `font-weight: ${fontWeight}` | ||
} | ||
|
||
const styleForPairForLegacy = (style: string, weight: string): string => { | ||
return TYPOGRAPHY[`${style}${weight}`] | ||
} | ||
|
||
const fontSizeForPairForLegacy = (style: string, weight: string): string => { | ||
const stylePayload = styleForPairForLegacy(style, weight) | ||
const sizeStr = valueFromFlattenedInterp(stylePayload, 'font-size:') | ||
const sizeInPx = convertToPx(sizeStr) | ||
|
||
return `font-size: ${sizeStr}/${sizeInPx}` | ||
} | ||
|
||
const lineHeightForPairForLegacy = (style: string, weight: string): string => { | ||
const stylePayload = styleForPairForLegacy(style, weight) | ||
const sizeStr = valueFromFlattenedInterp(stylePayload, 'line-height:') | ||
const sizeInPx = convertToPx(sizeStr) | ||
return `line-height: ${sizeStr}/${sizeInPx}` | ||
} | ||
|
||
const fontWeightForPairForLegacy = (style: string, weight: string): string => { | ||
const stylePayload = styleForPairForLegacy(style, weight) | ||
const fontWeight = valueFromFlattenedInterp(stylePayload, 'font-weight:') | ||
return `font-weight: ${fontWeight}` | ||
} | ||
|
||
const valueFromFlattenedInterp = ( | ||
style: FlattenSimpleInterpolation, | ||
valueName: str | ||
): string => { | ||
return style.reduce( | ||
([sawKey, value]: [boolean, null | string], el) => { | ||
const thisEl = el.trim() | ||
if (sawKey && value == null) { | ||
return [sawKey, el] | ||
} | ||
if (sawKey && value != null) { | ||
return [sawKey, value] | ||
} | ||
if (thisEl.includes(valueName)) { | ||
return [true, null] | ||
} | ||
return [false, null] | ||
}, | ||
[false, null] | ||
)[1] | ||
} | ||
|
||
const styleForPair = ( | ||
style: string, | ||
weight: string, | ||
which: TypographyStandard | ||
): string => | ||
which === 'Helix Product (Desktop)' | ||
? styleForPairForHelix(style, weight) | ||
: styleForPairForLegacy(style, weight) | ||
|
||
const fontSizeForPair = ( | ||
style: string, | ||
weight: string, | ||
which: TypographyStandard | ||
): string => | ||
which === 'Helix Product (Desktop)' | ||
? fontSizeForPairForHelix(style, weight) | ||
: fontSizeForPairForLegacy(style, weight) | ||
|
||
const lineHeightForPair = ( | ||
style: string, | ||
weight: string, | ||
which: TypographyStandard | ||
): string => | ||
which === 'Helix Product (Desktop)' | ||
? lineHeightForPairForHelix(style, weight) | ||
: lineHeightForPairForLegacy(style, weight) | ||
|
||
const fontWeightForPair = ( | ||
style: string, | ||
weight: string, | ||
which: TypographyStandard | ||
): string => | ||
which === 'Helix Product (Desktop)' | ||
? fontWeightForPairForHelix(style, weight) | ||
: fontWeightForPairForLegacy(style, weight) | ||
|
||
const Template: Story<TypographyStorybookProps> = args => { | ||
const fonts = fontStyles[args.styles] | ||
return ( | ||
<Flex | ||
flexDirection={DIRECTION_COLUMN} | ||
gridGap={SPACING.spacing8} | ||
padding={SPACING.spacing24} | ||
> | ||
{fonts.map(([style, weight]) => ( | ||
<Box key={`${style}_${weight}`} alignItems={ALIGN_CENTER}> | ||
<Text css={styleForPair(style, weight, args.styles)}> | ||
{`${style} ${weight} (${fontWeightForPair( | ||
style, | ||
weight, | ||
args.styles | ||
)}, ${fontSizeForPair( | ||
style, | ||
weight, | ||
args.styles | ||
)}, ${lineHeightForPair(style, weight, args.styles)}): ${ | ||
args.text | ||
}`} | ||
</Text> | ||
</Box> | ||
))} | ||
</Flex> | ||
) | ||
} | ||
|
||
export const AllTypographyStyles = Template.bind({}) | ||
AllTypographyStyles.args = { | ||
text: 'The quick brown fox jumped over the lazy dog.', | ||
styles: 'Helix Product (Desktop)', | ||
} |
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 |
---|---|---|
@@ -1,2 +1,3 @@ | ||
export * as COLORS from './colors' | ||
export * as BORDERS from './borders' | ||
export * as PRODUCT from './product' |
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 @@ | ||
export * as TYPOGRAPHY from './typography' |
141 changes: 141 additions & 0 deletions
141
components/src/helix-design-system/product/typography.ts
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,141 @@ | ||
/** | ||
* Note: these values are only currently correct for desktop and should not be used on ODD. | ||
*/ | ||
|
||
// Valid for most typography styles | ||
export const fontFamily = 'Public Sans' | ||
|
||
export const fontWeightRegular = '400' | ||
export const fontWeightSemiBold = '600' | ||
export const fontWeightBold = '700' | ||
|
||
// Display styles | ||
const fontFamilyDisplay = fontFamily | ||
const fontSizeDisplay = '2.4375rem' // 39px | ||
const lineHeightDisplay = '3rem' // 48px | ||
|
||
// Display-Bold | ||
export const fontSizeDisplayBold = fontSizeDisplay | ||
export const lineHeightDisplayBold = lineHeightDisplay | ||
export const fontFamilyDisplayBold = fontFamilyDisplay | ||
export const fontWeightDisplayBold = fontWeightBold | ||
export const fontStyleDisplayBold = `${fontWeightDisplayBold} ${fontSizeDisplayBold}/${lineHeightDisplayBold} ${fontFamilyDisplayBold}` | ||
|
||
// Heading-Large | ||
const fontSizeHeadingLarge = '1.625rem' // 26px | ||
const lineHeightHeadingLarge = '2rem' // 32px | ||
const fontFamilyHeadingLarge = fontFamily | ||
|
||
// Heading-Large-Regular | ||
export const fontFamilyHeadingLargeRegular = fontFamilyHeadingLarge | ||
export const fontSizeHeadingLargeRegular = fontSizeHeadingLarge | ||
export const lineHeightHeadingLargeRegular = lineHeightHeadingLarge | ||
export const fontWeightHeadingLargeRegular = fontWeightRegular | ||
export const fontStyleHeadingLargeRegular = `${fontWeightHeadingLargeRegular} ${fontSizeHeadingLargeRegular}/${lineHeightHeadingLargeRegular} ${fontFamilyHeadingLargeRegular}` | ||
|
||
// Heading-Large-Bold | ||
export const fontFamilyHeadingLargeBold = fontFamilyHeadingLarge | ||
export const fontSizeHeadingLargeBold = fontSizeHeadingLarge | ||
export const lineHeightHeadingLargeBold = lineHeightHeadingLarge | ||
export const fontWeightHeadingLargeBold = fontWeightBold | ||
export const fontStyleHeadingLargeBold = `${fontWeightHeadingLargeBold} ${fontSizeHeadingLargeBold}/${lineHeightHeadingLargeBold} ${fontFamilyHeadingLargeBold}` | ||
|
||
// Heading-Medium | ||
const fontSizeHeadingMedium = '1.4375rem' // 23px | ||
const lineHeightHeadingMedium = '1.75rem' // 28px | ||
const fontFamilyHeadingMedium = fontFamily | ||
|
||
// Heading-Medium-Regular | ||
export const fontSizeHeadingMediumMedium = fontSizeHeadingMedium | ||
export const lineHeightHeadingMediumMedium = lineHeightHeadingMedium | ||
export const fontFamilyHeadingMediumMedium = fontFamilyHeadingMedium | ||
export const fontWeightHeadingMediumMedium = fontWeightSemiBold | ||
export const fontStyleHeadingMediumMedium = `${fontWeightHeadingMediumMedium} ${fontSizeHeadingMediumMedium}/${lineHeightHeadingMediumMedium} ${fontFamilyHeadingMediumMedium}` | ||
|
||
// Heading-Small | ||
const fontSizeHeadingSmall = '1.125rem' // 18px | ||
const lineHeightHeadingSmall = '1.5rem' // 24px | ||
const fontFamilyHeadingSmall = fontFamily | ||
|
||
// Heading-Small-Regular | ||
export const fontSizeHeadingSmallRegular = fontSizeHeadingSmall | ||
export const lineHeightHeadingSmallRegular = lineHeightHeadingSmall | ||
export const fontFamilyHeadingSmallRegular = fontFamilyHeadingSmall | ||
export const fontWeightHeadingSmallRegular = '600' | ||
export const fontStyleHeadingSmallRegular = `${fontWeightHeadingSmallRegular} ${fontSizeHeadingSmallRegular}/${lineHeightHeadingSmallRegular} ${fontFamilyHeadingSmallRegular}` | ||
|
||
// Heading-Small-Bold | ||
export const fontSizeHeadingSmallBold = fontSizeHeadingSmall | ||
export const lineHeightHeadingSmallBold = lineHeightHeadingSmall | ||
export const fontFamilyHeadingSmallBold = fontFamilyHeadingSmall | ||
export const fontWeightHeadingSmallBold = fontWeightBold | ||
export const fontStyleHeadingSmallBold = `${fontWeightHeadingSmallBold} ${fontSizeHeadingSmallBold}/${lineHeightHeadingSmallBold} ${fontFamilyHeadingSmallBold}` | ||
|
||
// Body-Large | ||
const fontSizeBodyLarge = '1rem' // 16px | ||
const lineHeightBodyLarge = '1.5rem' // 24px | ||
const fontFamilyBodyLarge = fontFamily | ||
|
||
// Body-Large-Medium | ||
export const fontSizeBodyLargeMedium = fontSizeBodyLarge | ||
export const lineHeightBodyLargeMedium = lineHeightBodyLarge | ||
export const fontFamilyBodyLargeMedium = fontFamilyBodyLarge | ||
export const fontWeightBodyLargeMedium = fontWeightSemiBold | ||
export const fontStyleBodyLargeMedium = `${fontWeightBodyLargeMedium} ${fontSizeBodyLargeMedium}/${lineHeightBodyLargeMedium} ${fontFamilyBodyLargeMedium}` | ||
|
||
// Body-Large-Regular | ||
export const fontSizeBodyLargeRegular = fontSizeBodyLarge | ||
export const lineHeightBodyLargeRegular = lineHeightBodyLarge | ||
export const fontFamilyBodyLargeRegular = fontFamilyBodyLarge | ||
export const fontWeightBodyLargeRegular = fontWeightRegular | ||
export const fontStyleBodyLargeRegular = `${fontWeightBodyLargeRegular} ${fontSizeBodyLargeRegular}/${lineHeightBodyLargeRegular} ${fontFamilyBodyLargeRegular}` | ||
|
||
// Body-Default | ||
const fontSizeBodyDefault = '0.875rem' // 14px | ||
const lineHeightBodyDefault = '1.25rem' // 20px | ||
const fontFamilyBodyDefault = fontFamily | ||
|
||
// Body-Default-Medium | ||
export const fontSizeBodyDefaultMedium = fontSizeBodyDefault | ||
export const lineHeightBodyDefaultMedium = lineHeightBodyDefault | ||
export const fontFamilyBodyDefaultMedium = fontFamilyBodyDefault | ||
export const fontWeightBodyDefaultMedium = fontWeightSemiBold | ||
export const fontStyleBodyDefaultMedium = `${fontWeightBodyDefaultMedium} ${fontSizeBodyDefaultMedium}/${lineHeightBodyDefaultMedium} ${fontFamilyBodyDefaultMedium}` | ||
|
||
// Body-Default-Regular | ||
export const fontSizeBodyDefaultRegular = fontSizeBodyDefault | ||
export const lineHeightBodyDefaultRegular = lineHeightBodyDefault | ||
export const fontFamilyBodyDefaultRegular = fontFamilyBodyDefault | ||
export const fontWeightBodyDefaultRegular = fontWeightRegular | ||
export const fontStyleBodyDefaultRegular = `${fontWeightBodyDefaultRegular} ${fontSizeBodyDefaultRegular}/${lineHeightBodyDefaultRegular} ${fontFamilyBodyDefaultRegular}` | ||
|
||
// Caption | ||
const fontSizeCaption = '0.8125rem' // 13px | ||
const lineHeightCaption = '1rem' // 16px | ||
const fontFamilyCaption = 'Public Sans' | ||
|
||
// Caption-Medium | ||
export const fontSizeCaptionMedium = fontSizeCaption | ||
export const lineHeightCaptionMedium = lineHeightCaption | ||
export const fontFamilyCaptionMedium = fontFamilyCaption | ||
export const fontWeightCaptionMedium = '500' | ||
export const fontStyleCaptionMedium = `${fontWeightCaptionMedium} ${fontSizeCaptionMedium}/${lineHeightCaptionMedium} ${fontFamilyCaptionMedium}` | ||
|
||
// Caption-Regular | ||
export const fontSizeCaptionRegular = fontSizeCaption | ||
export const lineHeightCaptionRegular = lineHeightCaption | ||
export const fontFamilyCaptionRegular = fontFamilyCaption | ||
export const fontWeightCaptionRegular = '400' | ||
export const fontStyleCaptionRegular = `${fontWeightCaptionRegular} ${fontSizeCaptionRegular}/${lineHeightCaptionRegular} ${fontFamilyCaptionRegular}` | ||
|
||
// Code | ||
const fontSizeCode = '0.75rem' // 12px | ||
const lineHeightCode = '1.25rem' // 20px | ||
const fontFamilyCode = 'Reddit Mono' | ||
|
||
// Code-Regular | ||
export const fontSizeCodeRegular = fontSizeCode | ||
export const lineHeightCodeRegular = lineHeightCode | ||
export const fontFamilyCodeRegular = fontFamilyCode | ||
export const fontWeightCodeRegular = fontWeightRegular | ||
export const fontStyleCodeRegular = `${fontWeightCodeRegular} ${fontSizeCodeRegular}/${lineHeightCodeRegular} ${fontFamilyCodeRegular}` |