import type { Meta, StoryObj } from '@storybook/vue3-vite' import type { ProbeProperty, Token } from '@/stories/tokenUtils' import { copyableClass, copyableCopiedClass, getTokenPixels, readTokens, sortTokensBySize, splitRemPx, tokenTableClass, useCopier, } from '@/stories/tokenUtils' const meta: Meta = { title: 'Foundations/Typography', tags: ['!dev'], parameters: { layout: 'padded', controls: { disable: true }, docs: { source: { code: null } }, }, } export default meta type Story = StoryObj type PreviewKind = 'letter-spacing' | 'line-height' | 'text-size' const previewStyle = (kind: PreviewKind, tokenName: string): string => { const ref = `var(${tokenName})` switch (kind) { case 'text-size': return `font-size: ${ref}; line-height: 1.1; color: #36384d;` case 'line-height': return `font-size: 14px; line-height: ${ref}; color: #36384d; max-width: 280px; width:280px; display:block; white-space: initial;` case 'letter-spacing': return `font-size: 14px; letter-spacing: ${ref}; color: #36384d;` } } const sampleForKind = (kind: PreviewKind): string => { switch (kind) { case 'text-size': return 'The quick brown fox' case 'line-height': return 'Cras mattis consectetur purus sit amet fermentum. Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor.' case 'letter-spacing': return 'AVERAGE spacing sample' } } /** * Raw text sizes, sorted from the biggest to the smallest. Prefer the * semantic `--cp-text-*-size` tokens (Text scale) in application code. */ export const TextSize: Story = { render: () => ({ setup() { const tokens = sortTokensBySize(readTokens(['--cp-text-size-'])) const { copiedKey, copy } = useCopier() return { tokens, copiedKey, copy, tableClass: tokenTableClass, copyClass: copyableClass, copiedClass: copyableCopiedClass, preview: (tokenName: string) => previewStyle('text-size', tokenName), sample: sampleForKind('text-size'), split: (token: Token) => splitRemPx(token), } }, template: `
Token rem px Preview
{{ copiedKey === token.name ? 'Copied!' : token.name }} {{ split(token).rem }} {{ split(token).px }} {{ sample }}
No tokens
`, }), } type ValueSectionArgs = { kind: 'letter-spacing' | 'line-height'; loader: () => Token[] } const makeValueStory = ({ kind, loader }: ValueSectionArgs): Story => ({ render: () => ({ setup() { const { copiedKey, copy } = useCopier() const probeProperty: ProbeProperty = kind return { kind, tokens: loader(), copiedKey, copy, tableClass: tokenTableClass, copyClass: copyableClass, copiedClass: copyableCopiedClass, preview: (k: PreviewKind, tokenName: string) => previewStyle(k, tokenName), sample: (k: PreviewKind) => sampleForKind(k), px: (tokenName: string) => getTokenPixels(tokenName, probeProperty) ?? '—', } }, template: `
Token Value px Preview
{{ copiedKey === token.name ? 'Copied!' : token.name }} {{ token.value }} {{ px(token.name) }} {{ sample(kind) }}
No tokens
`, }), }) /** * Raw line-heights. The gradient line marks the baseline of each sample. */ export const LineHeight: Story = makeValueStory({ kind: 'line-height', loader: () => sortTokensBySize(readTokens(['--cp-line-height-'])), }) /** * Letter-spacing (tracking) scale. */ export const LetterSpacing: Story = makeValueStory({ kind: 'letter-spacing', loader: () => sortTokensBySize(readTokens(['--cp-letter-spacing-'])), })