diff options
Diffstat (limited to 'src/components/Typography.tsx')
-rw-r--r-- | src/components/Typography.tsx | 96 |
1 files changed, 83 insertions, 13 deletions
diff --git a/src/components/Typography.tsx b/src/components/Typography.tsx index 66cf0720d..64aa6d1a4 100644 --- a/src/components/Typography.tsx +++ b/src/components/Typography.tsx @@ -1,11 +1,50 @@ import React from 'react' -import {Text as RNText, TextProps} from 'react-native' +import {Text as RNText, TextStyle, TextProps} from 'react-native' import {useTheme, atoms, web, flatten} from '#/alf' +/** + * Util to calculate lineHeight from a text size atom and a leading atom + * + * Example: + * `leading(atoms.text_md, atoms.leading_normal)` // => 24 + */ +export function leading< + Size extends {fontSize?: number}, + Leading extends {lineHeight?: number}, +>(textSize: Size, leading: Leading) { + const size = textSize?.fontSize || atoms.text_md.fontSize + const lineHeight = leading?.lineHeight || atoms.leading_normal.lineHeight + return size * lineHeight +} + +/** + * Ensures that `lineHeight` defaults to a relative value of `1`, or applies + * other relative leading atoms. + * + * If the `lineHeight` value is > 2, we assume it's an absolute value and + * returns it as-is. + */ +function normalizeTextStyles(styles: TextStyle[]) { + const s = flatten(styles) + // should always be defined on these components + const fontSize = s.fontSize || atoms.text_md.fontSize + + if (s?.lineHeight) { + if (s.lineHeight <= 2) { + s.lineHeight = fontSize * s.lineHeight + } + } else { + s.lineHeight = fontSize + } + + return s +} + export function Text({style, ...rest}: TextProps) { const t = useTheme() - return <RNText style={[atoms.text_sm, t.atoms.text, style]} {...rest} /> + const s = normalizeTextStyles([atoms.text_sm, t.atoms.text, flatten(style)]) + return <RNText style={s} {...rest} /> } export function H1({style, ...rest}: TextProps) { @@ -19,7 +58,12 @@ export function H1({style, ...rest}: TextProps) { <RNText {...attr} {...rest} - style={[atoms.text_5xl, atoms.font_bold, t.atoms.text, flatten(style)]} + style={normalizeTextStyles([ + atoms.text_5xl, + atoms.font_bold, + t.atoms.text, + flatten(style), + ])} /> ) } @@ -35,7 +79,12 @@ export function H2({style, ...rest}: TextProps) { <RNText {...attr} {...rest} - style={[atoms.text_4xl, atoms.font_bold, t.atoms.text, flatten(style)]} + style={normalizeTextStyles([ + atoms.text_4xl, + atoms.font_bold, + t.atoms.text, + flatten(style), + ])} /> ) } @@ -51,7 +100,12 @@ export function H3({style, ...rest}: TextProps) { <RNText {...attr} {...rest} - style={[atoms.text_3xl, atoms.font_bold, t.atoms.text, flatten(style)]} + style={normalizeTextStyles([ + atoms.text_3xl, + atoms.font_bold, + t.atoms.text, + flatten(style), + ])} /> ) } @@ -67,7 +121,12 @@ export function H4({style, ...rest}: TextProps) { <RNText {...attr} {...rest} - style={[atoms.text_2xl, atoms.font_bold, t.atoms.text, flatten(style)]} + style={normalizeTextStyles([ + atoms.text_2xl, + atoms.font_bold, + t.atoms.text, + flatten(style), + ])} /> ) } @@ -83,7 +142,12 @@ export function H5({style, ...rest}: TextProps) { <RNText {...attr} {...rest} - style={[atoms.text_xl, atoms.font_bold, t.atoms.text, flatten(style)]} + style={normalizeTextStyles([ + atoms.text_xl, + atoms.font_bold, + t.atoms.text, + flatten(style), + ])} /> ) } @@ -99,7 +163,12 @@ export function H6({style, ...rest}: TextProps) { <RNText {...attr} {...rest} - style={[atoms.text_lg, atoms.font_bold, t.atoms.text, flatten(style)]} + style={normalizeTextStyles([ + atoms.text_lg, + atoms.font_bold, + t.atoms.text, + flatten(style), + ])} /> ) } @@ -110,15 +179,16 @@ export function P({style, ...rest}: TextProps) { web({ role: 'paragraph', }) || {} - const _style = flatten(style) - const lineHeight = - (_style?.lineHeight || atoms.text_md.lineHeight) * - atoms.leading_normal.lineHeight return ( <RNText {...attr} {...rest} - style={[atoms.text_md, t.atoms.text, _style, {lineHeight}]} + style={normalizeTextStyles([ + atoms.text_md, + atoms.leading_normal, + t.atoms.text, + flatten(style), + ])} /> ) } |