diff --git a/components/src/atoms/StyledText/StyledText.stories.tsx b/components/src/atoms/StyledText/StyledText.stories.tsx index c6e7eaf2699d..11b198698c51 100644 --- a/components/src/atoms/StyledText/StyledText.stories.tsx +++ b/components/src/atoms/StyledText/StyledText.stories.tsx @@ -1,13 +1,27 @@ /* eslint-disable storybook/prefer-pascal-case */ import * as React from 'react' -import { SPACING, TYPOGRAPHY } from '../../ui-style-constants' +import { SPACING } from '../../ui-style-constants' import { Flex } from '../../primitives' -import { LegacyStyledText } from './index' +import { StyledText, ODD_STYLES, HELIX_STYLES } from './index' import type { Meta, StoryObj } from '@storybook/react' -const meta: Meta = { +const meta: Meta = { title: 'Library/Atoms/StyledText', - component: LegacyStyledText, + component: StyledText, + argTypes: { + oddStyle: { + control: { + type: 'select', + }, + options: ODD_STYLES, + }, + desktopStyle: { + control: { + type: 'select', + }, + options: HELIX_STYLES, + }, + }, decorators: [ Story => ( @@ -19,89 +33,15 @@ const meta: Meta = { export default meta -type Story = StoryObj +type Story = StoryObj const dummyText = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Purus sapien nunc dolor, aliquet nibh placerat et nisl, arcu. Pellentesque blandit sollicitudin vitae morbi morbi vulputate cursus tellus. Amet proin donec proin id aliquet in nullam.' -export const h1: Story = { - args: { - as: 'h1', - children: dummyText, - }, -} - -export const h2: Story = { - args: { - as: 'h2', - children: dummyText, - }, -} - -export const h3: Story = { - args: { - as: 'h3', - children: dummyText, - }, -} - -export const h6: Story = { - args: { - as: 'h6', - children: dummyText, - }, -} - -export const p: Story = { - args: { - as: 'p', - children: dummyText, - }, -} - -export const label: Story = { - args: { - as: 'label', - children: dummyText, - }, -} - -export const h2SemiBold: Story = { - args: { - as: 'h2', - fontWeight: TYPOGRAPHY.fontWeightSemiBold, - children: dummyText, - }, -} - -export const h3SemiBold: Story = { - args: { - as: 'h3', - fontWeight: TYPOGRAPHY.fontWeightSemiBold, - children: dummyText, - }, -} - -export const h6SemiBold: Story = { - args: { - as: 'h6', - fontWeight: TYPOGRAPHY.fontWeightSemiBold, - children: dummyText, - }, -} - -export const pSemiBold: Story = { - args: { - as: 'p', - fontWeight: TYPOGRAPHY.fontWeightSemiBold, - children: dummyText, - }, -} - -export const labelSemiBold: Story = { +export const Example: Story = { args: { - as: 'label', - fontWeight: TYPOGRAPHY.fontWeightSemiBold, + oddStyle: 'level1Header', + desktopStyle: 'displayBold', children: dummyText, }, } diff --git a/components/src/atoms/StyledText/StyledText.tsx b/components/src/atoms/StyledText/StyledText.tsx index 1659e8e120d4..af23658df8d4 100644 --- a/components/src/atoms/StyledText/StyledText.tsx +++ b/components/src/atoms/StyledText/StyledText.tsx @@ -1,95 +1,276 @@ import styled, { css } from 'styled-components' import { Text } from '../../primitives' import { TYPOGRAPHY, RESPONSIVENESS } from '../../ui-style-constants' +import { TYPOGRAPHY as HELIX_TYPOGRAPHY } from '../../helix-design-system/product' import type * as React from 'react' import type { FlattenSimpleInterpolation } from 'styled-components' +const helixProductStyleMap = { + displayBold: { + as: 'h1', + style: css` + @media not (${RESPONSIVENESS.touchscreenMediaQuerySpecs}) { + font: ${HELIX_TYPOGRAPHY.fontStyleDisplayBold}; + } + `, + }, + headingLargeRegular: { + as: 'h2', + style: css` + @media not (${RESPONSIVENESS.touchscreenMediaQuerySpecs}) { + font: ${HELIX_TYPOGRAPHY.fontStyleHeadingLargeRegular}; + } + `, + }, + headingLargeBold: { + as: 'h2', + style: css` + @media not (${RESPONSIVENESS.touchscreenMediaQuerySpecs}) { + font: ${HELIX_TYPOGRAPHY.fontStyleHeadingLargeBold}; + } + `, + }, + headingMediumMedium: { + as: 'h3', + style: css` + @media not (${RESPONSIVENESS.touchscreenMediaQuerySpecs}) { + font: ${HELIX_TYPOGRAPHY.fontStyleHeadingMediumMedium}; + } + `, + }, + headingSmallRegular: { + as: 'h4', + style: css` + @media not (${RESPONSIVENESS.touchscreenMediaQuerySpecs}) { + font: ${HELIX_TYPOGRAPHY.fontStyleHeadingSmallRegular}; + } + `, + }, + headingSmallBold: { + as: 'h4', + style: css` + @media not (${RESPONSIVENESS.touchscreenMediaQuerySpecs}) { + font: ${HELIX_TYPOGRAPHY.fontStyleHeadingSmallBold}; + } + `, + }, + bodyLargeMedium: { + as: 'p', + style: css` + @media not (${RESPONSIVENESS.touchscreenMediaQuerySpecs}) { + font: ${HELIX_TYPOGRAPHY.fontStyleBodyLargeMedium}; + } + `, + }, + bodyLargeRegular: { + as: 'p', + style: css` + @media not (${RESPONSIVENESS.touchscreenMediaQuerySpecs}) { + font: ${HELIX_TYPOGRAPHY.fontStyleBodyLargeRegular}; + } + `, + }, + bodyDefaultMedium: { + as: 'p', + style: css` + @media not (${RESPONSIVENESS.touchscreenMediaQuerySpecs}) { + font: ${HELIX_TYPOGRAPHY.fontStyleBodyDefaultMedium}; + } + `, + }, + bodyDefaultRegular: { + as: 'p', + style: css` + @media not (${RESPONSIVENESS.touchscreenMediaQuerySpecs}) { + font: ${HELIX_TYPOGRAPHY.fontStyleBodyDefaultRegular}; + } + `, + }, + captionMedium: { + as: 'label', + style: css` + @media not (${RESPONSIVENESS.touchscreenMediaQuerySpecs}) { + font: ${HELIX_TYPOGRAPHY.fontStyleCaptionMedium}; + } + `, + }, + captionRegular: { + as: 'label', + style: css` + @media not (${RESPONSIVENESS.touchscreenMediaQuerySpecs}) { + font: ${HELIX_TYPOGRAPHY.fontStyleCaptionRegular}; + } + `, + }, + codeRegular: { + as: 'p', + style: css` + @media not (${RESPONSIVENESS.touchscreenMediaQuerySpecs}) { + font: ${HELIX_TYPOGRAPHY.fontStyleCodeRegular}; + } + `, + }, +} as const + +const ODDStyleMap = { + level1Header: { + as: 'h1', + style: css` + @media ${RESPONSIVENESS.touchscreenMediaQuerySpecs} { + ${TYPOGRAPHY.level1Header}; + } + `, + }, + level2HeaderRegular: { + as: 'h2', + style: css` + @media ${RESPONSIVENESS.touchscreenMediaQuerySpecs} { + ${TYPOGRAPHY.level2HeaderRegular}; + } + `, + }, + level2HeaderSemiBold: { + as: 'h2', + style: css` + @media ${RESPONSIVENESS.touchscreenMediaQuerySpecs} { + ${TYPOGRAPHY.level2HeaderSemiBold} + } + `, + }, + level2HeaderBold: { + as: 'h2', + style: css` + @media ${RESPONSIVENESS.touchscreenMediaQuerySpecs} { + ${TYPOGRAPHY.level2HeaderBold} + } + `, + }, + + level3HeaderRegular: { + as: 'h3', + style: css` + @media ${RESPONSIVENESS.touchscreenMediaQuerySpecs} { + ${TYPOGRAPHY.level3HeaderRegular}; + } + `, + }, + level3HeaderSemiBold: { + as: 'h3', + style: css` + @media ${RESPONSIVENESS.touchscreenMediaQuerySpecs} { + ${TYPOGRAPHY.level3HeaderSemiBold} + } + `, + }, + + level3HeaderBold: { + as: 'h3', + style: css` + @media ${RESPONSIVENESS.touchscreenMediaQuerySpecs} { + ${TYPOGRAPHY.level3HeaderBold} + } + `, + }, + + level4HeaderRegular: { + as: 'h4', + style: css` + @media ${RESPONSIVENESS.touchscreenMediaQuerySpecs} { + ${TYPOGRAPHY.level4HeaderRegular}; + } + `, + }, + level4HeaderBold: { + as: 'h4', + style: css` + @media ${RESPONSIVENESS.touchscreenMediaQuerySpecs} { + ${TYPOGRAPHY.level4HeaderBold} + } + `, + }, + + bodyTextRegular: { + as: 'p', + style: css` + @media ${RESPONSIVENESS.touchscreenMediaQuerySpecs} { + ${TYPOGRAPHY.bodyTextRegular} + } + `, + }, + bodyTextSemiBold: { + as: 'p', + style: css` + @media ${RESPONSIVENESS.touchscreenMediaQuerySpecs} { + ${TYPOGRAPHY.bodyTextSemiBold} + } + `, + }, + bodyTextBold: { + as: 'p', + style: css` + @media ${RESPONSIVENESS.touchscreenMediaQuerySpecs} { + ${TYPOGRAPHY.bodyTextBold} + } + `, + }, + smallBodyTextRegular: { + as: 'label', + style: css` + @media ${RESPONSIVENESS.touchscreenMediaQuerySpecs} { + ${TYPOGRAPHY.smallBodyTextRegular} + } + `, + }, + + smallBodyTextSemiBold: { + as: 'label', + style: css` + @media ${RESPONSIVENESS.touchscreenMediaQuerySpecs} { + font-size: ${TYPOGRAPHY.fontSize20}; + line-height: ${TYPOGRAPHY.lineHeight24}; + } + `, + }, + + smallBodyTextBold: { + as: 'label', + style: css` + @media ${RESPONSIVENESS.touchscreenMediaQuerySpecs} { + ${TYPOGRAPHY.smallBodyTextBold} + } + `, + }, +} as const + export interface Props extends React.ComponentProps { - asDesktop?: string - asODD?: string + oddStyle?: ODDStyles + desktopStyle?: HelixStyles children?: React.ReactNode } +export const ODD_STYLES = Object.keys(ODDStyleMap) +export const HELIX_STYLES = Object.keys(helixProductStyleMap) +export type HelixStyles = typeof HELIX_STYLES +export type ODDStyles = typeof ODD_STYLES + +function styleForDesktopName( + name?: keyof typeof helixProductStyleMap +): FlattenSimpleInterpolation { + return name ? helixProductStyleMap[name].style : css`` +} -const styleMap: { [tag: string]: FlattenSimpleInterpolation } = { - h1: css` - ${TYPOGRAPHY.h1Default}; - @media ${RESPONSIVENESS.touchscreenMediaQuerySpecs} { - ${TYPOGRAPHY.level1Header}; - } - `, - h2: css` - ${TYPOGRAPHY.h2Regular} - @media ${RESPONSIVENESS.touchscreenMediaQuerySpecs} { - ${TYPOGRAPHY.level2HeaderRegular}; - } - `, - h3: css` - ${TYPOGRAPHY.h3Regular} - @media ${RESPONSIVENESS.touchscreenMediaQuerySpecs} { - ${TYPOGRAPHY.level3HeaderRegular}; - } - `, - h4: css` - @media ${RESPONSIVENESS.touchscreenMediaQuerySpecs} { - ${TYPOGRAPHY.level4HeaderRegular}; - } - `, - h6: TYPOGRAPHY.h6Default, - p: css` - ${TYPOGRAPHY.pRegular} - @media ${RESPONSIVENESS.touchscreenMediaQuerySpecs} { - ${TYPOGRAPHY.bodyTextRegular} - } - `, - label: css` - ${TYPOGRAPHY.labelRegular} - @media ${RESPONSIVENESS.touchscreenMediaQuerySpecs} { - ${TYPOGRAPHY.smallBodyTextRegular} - } - `, - h2SemiBold: css` - ${TYPOGRAPHY.h2SemiBold} - @media ${RESPONSIVENESS.touchscreenMediaQuerySpecs} { - ${TYPOGRAPHY.level2HeaderSemiBold} - } - `, - h3SemiBold: css` - ${TYPOGRAPHY.h3SemiBold} - @media ${RESPONSIVENESS.touchscreenMediaQuerySpecs} { - ${TYPOGRAPHY.level3HeaderSemiBold} - } - `, - h4SemiBold: TYPOGRAPHY.level4HeaderSemiBold, - h6SemiBold: TYPOGRAPHY.h6SemiBold, - pSemiBold: css` - ${TYPOGRAPHY.pSemiBold} - @media ${RESPONSIVENESS.touchscreenMediaQuerySpecs} { - ${TYPOGRAPHY.bodyTextSemiBold} - } - `, - labelSemiBold: css` - ${TYPOGRAPHY.labelSemiBold} - @media ${RESPONSIVENESS.touchscreenMediaQuerySpecs} { - font-size: ${TYPOGRAPHY.fontSize20}; - line-height: ${TYPOGRAPHY.lineHeight24}; - } - `, - h2Bold: TYPOGRAPHY.level2HeaderBold, - h3Bold: TYPOGRAPHY.level3HeaderBold, - h4Bold: TYPOGRAPHY.level4HeaderBold, - pBold: TYPOGRAPHY.bodyTextBold, - labelBold: TYPOGRAPHY.smallBodyTextBold, +function styleForODDName( + name?: keyof typeof ODDStyleMap +): FlattenSimpleInterpolation { + return name ? ODDStyleMap[name].style : css`` } -export const StyledText: (props: Props) => JSX.Element = styled(Text)` - ${props => { - let fontWeight = '' - if (props.fontWeight === TYPOGRAPHY.fontWeightSemiBold) { - fontWeight = 'SemiBold' - } else if (props.fontWeight === TYPOGRAPHY.fontWeightBold) { - fontWeight = 'Bold' - } - return styleMap[`${props.as}${fontWeight}`] - }} +const DesktopStyledText: (props: Props) => JSX.Element = styled(Text)` + ${props => styleForDesktopName(props.desktopStyle)} +` + +export const StyledText: (props: Props) => JSX.Element = styled( + DesktopStyledText +)` + ${props => styleForODDName(props.oddStyle)} `