-
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 (#15459)
This PR implements the new helix product typography system. You can find it here: https://www.figma.com/design/1ot18My22DALIcjdLl5LJh/Helix-Design-System?node-id=3571-46578&t=B4pPbtL9mapki2Jg-4 The Product type system is distinct from at least the Web type system, which will have different styles for readability in a different context. It is currently only defined for places other than the ODD. This ended up being a big PR because our usage of the `StyledText` atom had to be changed somewhat. The change was necessary because the helix product styles do not and are not intended to align with the semantic styling presented by the `StyledText` component - there is no direct alignment that "when you're making a `<p>`, you use this style". Instead, the intent is that higher level components will use the style by the name it has in helix, without an explicit semantic link outside of the designs. That makes the way the old styled text works kind of nonsense. In addition, there are no helix product styles for the ODD, and there is no current map and possibly no intention to have a future map between the semantic styles of the ODD and Desktop. That means that having a `StyledText` component that maps from a single semantic element to a set of appropriate styles just doesn't really make sense. So, `StyledText` is renamed to `LegacyStyledText` including at all callsites. The new `StyledText` requires you to specify styles separately for ODD and Desktop, though it gives you a handy type system integrated hint towards which styles should be allowed. Well, not quite required, more like you have no way to specify both in one prop. You can view it commit by commit: - 07dae4b adds the actual data for the helix product typography styling, and stories for viewing them as design components (and for viewing the old typography styles). This is more or less the only commit there was during the initial review, though it didn't then have the stories for the old typography - a36f501 is a repo-wide find and replace to change `StyledText` to `LegacyStyledText` - acec934 implements the new `StyledText`. Stories here: https://s3-us-west-2.amazonaws.com/opentrons-components/EXEC-566-add-helix-product-typography/index.html?path=/docs/design-tokens-typography--docs Closes EXEC-566
- Loading branch information
Showing
462 changed files
with
3,850 additions
and
2,697 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
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
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
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
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
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
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', 'SemiBold'], | ||
['HeadingSmall', 'Regular'], | ||
['HeadingSmall', 'Bold'], | ||
['BodyLarge', 'SemiBold'], | ||
['BodyLarge', 'Regular'], | ||
['BodyDefault', 'SemiBold'], | ||
['BodyDefault', 'Regular'], | ||
['Caption', 'SemiBold'], | ||
['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}`] as string | ||
const fontSizeInPx = convertToPx(fontSize) | ||
return `font-size: ${fontSize}/${fontSizeInPx}` | ||
} | ||
const lineHeightForPairForHelix = (style: string, weight: string): string => { | ||
const lineHeight = PRODUCT.TYPOGRAPHY[`lineHeight${style}${weight}`] as string | ||
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
Oops, something went wrong.