diff --git a/packages/harmony/src/components/text/Text/Text.tsx b/packages/harmony/src/components/text/Text/Text.tsx index f6c13ce5bc2..c753dd6ff8e 100644 --- a/packages/harmony/src/components/text/Text/Text.tsx +++ b/packages/harmony/src/components/text/Text/Text.tsx @@ -5,52 +5,9 @@ import { Slot } from '@radix-ui/react-slot' import { typography } from 'foundations' +import { variantStylesMap, variantTagMap } from './constants' import type { TextProps } from './types' -const variantTagMap = { - display: { - xl: 'h1', - l: 'h1', - m: 'h1', - s: 'h1' - }, - heading: { - xl: 'h1', - l: 'h2', - m: 'h3', - s: 'h4' - } -} - -export const variantStylesMap = { - display: { - fontSize: { s: '6xl', m: '7xl', l: '8xl', xl: '9xl' }, - lineHeight: { s: '3xl', m: '4xl', l: '5xl', xl: '6xl' }, - fontWeight: { default: 'bold', strong: 'heavy' } - }, - heading: { - fontSize: { s: 'xl', m: '2xl', l: '3xl', xl: '5xl' }, - lineHeight: { s: 'l', m: 'xl', l: 'xl', xl: '2xl' }, - fontWeight: { default: 'bold', strong: 'heavy' } - }, - title: { - fontSize: { xs: 'xs', s: 's', m: 'm', l: 'l' }, - lineHeight: { xs: 's', s: 's', m: 'm', l: 'l' }, - fontWeight: { weak: 'demiBold', default: 'bold', strong: 'heavy' } - }, - label: { - fontSize: { xs: '2xs', s: 'xs', m: 's', l: 'm', xl: 'xl' }, - lineHeight: { xs: 'xs', s: 'xs', m: 's', l: 's', xl: 'l' }, - fontWeight: { default: 'bold', strong: 'heavy' }, - css: { textTransform: 'uppercase' as const, letterSpacing: 0.5 } - }, - body: { - fontSize: { xs: 'xs', s: 's', m: 'm', l: 'l' }, - lineHeight: { xs: 's', s: 'm', m: 'm', l: 'l' }, - fontWeight: { default: 'medium', strong: 'demiBold' } - } -} - export const Text = forwardRef( ( props: TextProps, diff --git a/packages/harmony/src/components/text/Text/constants.ts b/packages/harmony/src/components/text/Text/constants.ts new file mode 100644 index 00000000000..f5754ddc046 --- /dev/null +++ b/packages/harmony/src/components/text/Text/constants.ts @@ -0,0 +1,43 @@ +export const variantTagMap = { + display: { + xl: 'h1', + l: 'h1', + m: 'h1', + s: 'h1' + }, + heading: { + xl: 'h1', + l: 'h2', + m: 'h3', + s: 'h4' + } +} + +export const variantStylesMap = { + display: { + fontSize: { s: '6xl', m: '7xl', l: '8xl', xl: '9xl' }, + lineHeight: { s: '3xl', m: '4xl', l: '5xl', xl: '6xl' }, + fontWeight: { default: 'bold', strong: 'heavy' } + }, + heading: { + fontSize: { s: 'xl', m: '2xl', l: '3xl', xl: '5xl' }, + lineHeight: { s: 'l', m: 'xl', l: 'xl', xl: '2xl' }, + fontWeight: { default: 'bold', strong: 'heavy' } + }, + title: { + fontSize: { xs: 'xs', s: 's', m: 'm', l: 'l' }, + lineHeight: { xs: 's', s: 's', m: 'm', l: 'l' }, + fontWeight: { weak: 'demiBold', default: 'bold', strong: 'heavy' } + }, + label: { + fontSize: { xs: '2xs', s: 'xs', m: 's', l: 'm', xl: 'xl' }, + lineHeight: { xs: 'xs', s: 'xs', m: 's', l: 's', xl: 'l' }, + fontWeight: { default: 'bold', strong: 'heavy' }, + css: { textTransform: 'uppercase' as const, letterSpacing: 0.5 } + }, + body: { + fontSize: { xs: 'xs', s: 's', m: 'm', l: 'l' }, + lineHeight: { xs: 's', s: 'm', m: 'm', l: 'l' }, + fontWeight: { default: 'medium', strong: 'demiBold' } + } +} diff --git a/packages/harmony/src/components/text/Text/index.ts b/packages/harmony/src/components/text/Text/index.ts index 55656bfe30b..487e7c269df 100644 --- a/packages/harmony/src/components/text/Text/index.ts +++ b/packages/harmony/src/components/text/Text/index.ts @@ -1,2 +1,3 @@ export { Text } from './Text' export * from './types' +export * from './constants' diff --git a/packages/harmony/src/storybook/components/TypographyPanel.tsx b/packages/harmony/src/storybook/components/TypographyPanel.tsx index d1e15f104fb..3a8b5ddeb29 100644 --- a/packages/harmony/src/storybook/components/TypographyPanel.tsx +++ b/packages/harmony/src/storybook/components/TypographyPanel.tsx @@ -9,7 +9,7 @@ import { TextStrength, TextVariant } from 'components' -import { variantStylesMap } from 'components/text/Text/Text' +import { variantStylesMap } from 'components/text/Text' type TypographyCardProps = { variant: TextVariant diff --git a/packages/mobile/src/app/index.ts b/packages/mobile/src/app/index.ts index 99f67d0cedd..dde8945ca78 100644 --- a/packages/mobile/src/app/index.ts +++ b/packages/mobile/src/app/index.ts @@ -1,3 +1,3 @@ export * from './App' -// // Uncomment to run app in storybook mode +// Uncomment to run app in storybook mode // export { default as App } from '../../.storybook' diff --git a/packages/mobile/src/harmony-native/foundations/typography/Text.tsx b/packages/mobile/src/harmony-native/foundations/typography/Text.tsx index 911882d8750..256fece5267 100644 --- a/packages/mobile/src/harmony-native/foundations/typography/Text.tsx +++ b/packages/mobile/src/harmony-native/foundations/typography/Text.tsx @@ -1,112 +1,25 @@ +import { useMemo } from 'react' + +import type { + TextVariant, + TextSize, + TextColors, + TextStrength +} from '@audius/harmony' +import { variantStylesMap } from '@audius/harmony' +import { css } from '@emotion/native' import type { TextProps as TextPropsBase, TextStyle } from 'react-native' import { Text as TextBase } from 'react-native' -import { makeStyles, useTheme } from '../theme' -import type { HarmonyTheme } from '../theme/theme' +import { useTheme } from '../theme' export type TextProps = TextPropsBase & { variant?: TextVariant size?: TextSize strength?: TextStrength - color?: TextColor + color?: TextColors } -export type TextStrength = 'weak' | 'default' | 'strong' - -export type TextColor = - | 'heading' - | 'default' - | 'subdued' - | 'disabled' - | 'danger' - | 'warning' - -export type TextSize = 'xl' | 'l' | 'm' | 's' | 'xs' - -export type TextVariant = 'display' | 'heading' | 'title' | 'label' | 'body' - -type VariantConfig = { - variant: TextVariant - fontSize: Record - lineHeight: Record - fontWeight: Record - style?: TextStyle -} - -const generateVariantStyles = (config: VariantConfig, theme: HarmonyTheme) => { - const { variant, fontSize, lineHeight, fontWeight, style } = config - const { typography } = theme - const fontSizeKeys = Object.keys(fontSize) - const fontWeightKeys = Object.keys(fontWeight) - - const variants: Record = {} - for (const fontSizeKey of fontSizeKeys) { - for (const fontWeightKey of fontWeightKeys) { - const variantKey = `${variant}-${fontSizeKey}-${fontWeightKey}` - variants[variantKey] = { - fontSize: typography.size[fontSize[fontSizeKey]], - lineHeight: typography.lineHeight[lineHeight[fontSizeKey]], - fontWeight: typography.weight[fontWeight[fontWeightKey]], - fontFamily: typography.fontByWeight[fontWeight[fontWeightKey]], - ...style - } - } - } - return variants -} - -const useStyles = makeStyles((theme) => { - const displayConfig = { - variant: 'display' as const, - fontSize: { s: '6xl', m: '7xl', l: '8xl', xl: '9xl' }, - lineHeight: { s: '3xl', m: '4xl', l: '5xl', xl: '6xl' }, - fontWeight: { default: 'bold', strong: 'heavy' } - } - - const headingConfig = { - variant: 'heading' as const, - fontSize: { s: 'xl', m: '2xl', l: '3xl', xl: '3xl' }, - lineHeight: { s: 'l', m: 'xl', l: 'xl', xl: 'xl' }, - fontWeight: { default: 'bold', strong: 'heavy' } - } - - const titleConfig = { - variant: 'title' as const, - fontSize: { xs: 'xs', s: 's', m: 'm', l: 'l' }, - lineHeight: { xs: 's', s: 's', m: 'm', l: 'l' }, - fontWeight: { weak: 'demiBold', default: 'bold', strong: 'heavy' } - } - - const labelConfig = { - variant: 'label' as const, - fontSize: { xs: '2xs', s: 'xs', m: 's', l: 'm', xl: 'xl' }, - lineHeight: { xs: 'xs', s: 'xs', m: 's', l: 's', xl: 'l' }, - fontWeight: { default: 'bold', strong: 'heavy' }, - style: { textTransform: 'uppercase' as const, letterSpacing: 0.5 } - } - - const bodyConfig = { - variant: 'body' as const, - fontSize: { xs: 'xs', s: 's', m: 'm', l: 'l' }, - lineHeight: { xs: 's', s: 'm', m: 'm', l: 'l' }, - fontWeight: { default: 'medium', strong: 'demiBold' } - } - - return [ - displayConfig, - headingConfig, - titleConfig, - labelConfig, - bodyConfig - ].reduce( - (styles, config) => ({ - ...styles, - ...generateVariantStyles(config, theme) - }), - {} - ) -}) - export const Text = (props: TextProps) => { const { variant = 'body', @@ -116,7 +29,6 @@ export const Text = (props: TextProps) => { color: colorProp = 'default', ...other } = props - const styles = useStyles() const theme = useTheme() // TODO: make heading a proper gradient const color = @@ -124,13 +36,25 @@ export const Text = (props: TextProps) => { ? theme.color.secondary.secondary : theme.color.textIcon[colorProp] - const styleKey = `${variant}-${size}-${strength}` + const variantStyles = variantStylesMap[variant] + + const textStyles = useMemo((): TextStyle => { + const t = theme.typography + return css({ + fontSize: t.size[variantStyles.fontSize[size]], + lineHeight: t.lineHeight[variantStyles.lineHeight[size]], + fontWeight: t.weight[variantStyles.fontWeight[strength]], + fontFamily: t.fontByWeight[variantStyles.fontWeight[strength]], + ...('css' in variantStyles ? variantStyles.css : {}), + ...(color && { color }) + }) + }, [color, size, strength, theme.typography, variantStyles]) const isHeading = variant === 'display' || variant === 'heading' return (