import { RawValueSignature, ResolvableModeLevelAlias, ResolvableTopLevelAlias, ResolvableValueLevelAlias, SpecifyFontValue, TokenState, UnresolvableModeLevelAlias, UnresolvableValueLevelAlias, } from '@specifyapp/specify-design-token-format'; import { fontWeightValueToCss } from './fontWeight.js'; import { makeCSSAlias } from '../utils/makeCSSAlias.js'; import { unwrapInnerValue } from '../../_utils/unwrapInnerValue.js'; import { DEFAULT_UNRESOLVABLE_STRATEGY } from '../aliasStrategies/throwOnUnresolvable.js'; import { CssResolvableAliasStrategy, CssUnresolvableAliasStrategy, } from '../aliasStrategies/CssAliasStrategy.js'; import { TemplateRenderer, dataOfToken, dataOfUnresolvedAlias, } from '../../../builtInParsers/utils/template.js'; /** * Converts a `TokenState<'font'>` to a css value. * **Warning**: this token is composite, so the output will be an object. * E.g: `{'font-family': 'family', 'font-weight': 900, 'font-style': 'italic' }` */ export function fontToCss( aliasStrategy: CssResolvableAliasStrategy, unresolvableAliasStrategy: CssUnresolvableAliasStrategy = DEFAULT_UNRESOLVABLE_STRATEGY, ) { return (tokenState: TokenState<'font'>) => tokenState .getStatefulValueResult() .mapResolvableTopLevelAlias(aliasStrategy) .mapUnresolvableTopLevelAlias(alias => unresolvableAliasStrategy(tokenState, alias)) .mapTopLevelValue(value => value .mapRawValue(rawValue => rawFontToCss(rawValue, aliasStrategy, unresolvableAliasStrategy)) .mapResolvableModeLevelAlias(aliasStrategy) .mapUnresolvableModeLevelAlias(alias => unresolvableAliasStrategy(tokenState, alias)) .unwrap(), ) .unwrap() as { [mode: string]: ReturnType }; } export function modeLevelAliasFontToVariables( alias: ResolvableModeLevelAlias | ResolvableTopLevelAlias | ResolvableValueLevelAlias, renderAlias: TemplateRenderer, withCssAlias = true, ) { const mode = alias instanceof ResolvableModeLevelAlias ? alias.targetMode : undefined; const baseAlias = renderAlias(dataOfToken(alias.tokenState, mode)); const fontStyle = `${baseAlias}-font-style`; const fontFamily = `${baseAlias}-font-family`; const fontWeight = `${baseAlias}-font-weight`; return { ['font-style']: withCssAlias ? makeCSSAlias(fontStyle) : fontStyle, ['font-family']: withCssAlias ? makeCSSAlias(fontFamily) : fontFamily, ['font-weight']: withCssAlias ? makeCSSAlias(fontWeight) : fontWeight, }; } export function modeLevelUnresolvableAliasFontToVariables( alias: UnresolvableModeLevelAlias | UnresolvableValueLevelAlias, renderAlias: TemplateRenderer, withCssAlias = true, ) { const baseAlias = renderAlias(dataOfUnresolvedAlias(alias)); const fontStyle = `${baseAlias}-font-style`; const fontFamily = `${baseAlias}-font-family`; const fontWeight = `${baseAlias}-font-weight`; return { ['font-style']: withCssAlias ? makeCSSAlias(fontStyle) : fontStyle, ['font-family']: withCssAlias ? makeCSSAlias(fontFamily) : fontFamily, ['font-weight']: withCssAlias ? makeCSSAlias(fontWeight) : fontWeight, }; } /** * Converts a `RawValueSignature<'font'>` to css. */ export function rawFontToCss( font: RawValueSignature<'font'>, aliasStrategy: CssResolvableAliasStrategy, unresolvableAliasStrategy: CssUnresolvableAliasStrategy = DEFAULT_UNRESOLVABLE_STRATEGY, ) { return { // @ts-ignore - Expression produces a union type that is too complex to represent ['font-style']: unwrapInnerValue( font.style, aliasStrategy, unresolvableAliasStrategy, ) as string, ['font-family']: unwrapInnerValue( font.postScriptName.mapPrimitiveValue(v => `'${v}'`), aliasStrategy, unresolvableAliasStrategy, ), ['font-weight']: unwrapInnerValue( font.weight.mapPrimitiveValue(fontWeightValueToCss), aliasStrategy, unresolvableAliasStrategy, ), }; } /** * Converts a font to css. */ export function fontValueToCss(font: SpecifyFontValue) { return { 'font-style': font.style, 'font-family': `'${font.postScriptName}'`, 'font-weight': fontWeightValueToCss(font.weight), }; }