UNPKG

@tldraw/tlschema

Version:

tldraw infinite canvas SDK (schema).

138 lines (129 loc) 3.9 kB
import { StyleProp } from './StyleProp' import { TLThemeFont, TLThemeFonts, TLThemes } from './TLTheme' /** * Default font style property used by tldraw shapes for text styling. * Controls which typeface is used for text content within shapes. * * Available values: * - `draw` - Hand-drawn, sketchy font style * - `sans` - Clean sans-serif font * - `serif` - Traditional serif font * - `mono` - Monospace font for code-like text * * @example * ```ts * import { DefaultFontStyle } from '@tldraw/tlschema' * * // Use in shape props definition * interface MyTextShapeProps { * font: typeof DefaultFontStyle * // other props... * } * * // Create a text shape with monospace font * const textShape = { * // ... other properties * props: { * font: 'mono' as const, * // ... other props * } * } * ``` * * @public */ export const DefaultFontStyle = StyleProp.defineEnum('tldraw:font', { defaultValue: 'draw', values: ['draw', 'sans', 'serif', 'mono'], }) /** * The names of all available font styles, derived from {@link TLThemeFonts}. * Extend {@link TLThemeFonts} to add custom font names. * * @example * ```ts * import { TLDefaultFontStyle } from '@tldraw/tlschema' * * // Valid font style values * const drawFont: TLDefaultFontStyle = 'draw' * const sansFont: TLDefaultFontStyle = 'sans' * const serifFont: TLDefaultFontStyle = 'serif' * const monoFont: TLDefaultFontStyle = 'mono' * * // Use in a function parameter * function setTextFont(font: TLDefaultFontStyle) { * // Apply font style to text * } * ``` * * @public */ export type TLDefaultFontStyle = keyof TLThemeFonts & string /** * Mapping of font style names to their corresponding CSS font-family declarations. * These are the actual CSS font families used when rendering text with each font style. * * @example * ```ts * import { DefaultFontFamilies, TLDefaultFontStyle } from '@tldraw/tlschema' * * // Get CSS font family for a font style * const fontStyle: TLDefaultFontStyle = 'mono' * const cssFamily = DefaultFontFamilies[fontStyle] // "'tldraw_mono', monospace" * * // Apply to DOM element * element.style.fontFamily = DefaultFontFamilies.sans * ``` * * @public */ export const DefaultFontFamilies = { draw: "'tldraw_draw', sans-serif", sans: "'tldraw_sans', sans-serif", serif: "'tldraw_serif', serif", mono: "'tldraw_mono', monospace", } /** @internal */ export function isFontEntry(value: unknown): value is TLThemeFont { return typeof value === 'object' && value !== null && 'fontFamily' in value } /** * Scan theme definitions and sync font registrations to match. * A font entry is any key in `TLThemeFonts` whose value is a {@link TLThemeFont} * object (i.e. has a `fontFamily` property). * * Fonts present in themes but not yet registered will be added. * Fonts currently registered but absent from all themes will be removed. * * @public */ export function registerFontsFromThemes(definitions: TLThemes): void { const fontNames = new Set<string>() for (const def of Object.values(definitions)) { if (!def.fonts) continue for (const [key, value] of Object.entries(def.fonts)) { if (isFontEntry(value)) { fontNames.add(key) } } } const toAdd = [...fontNames].filter((v) => !DefaultFontStyle.values.includes(v as any)) if (toAdd.length > 0) { DefaultFontStyle.addValues(...(toAdd as any)) } const toRemove = DefaultFontStyle.values.filter((v) => !fontNames.has(v as string)) if (toRemove.length > 0) { DefaultFontStyle.removeValues(...toRemove) } if (process.env.NODE_ENV !== 'production') { for (const def of Object.values(definitions)) { for (const font of fontNames) { if (!def.fonts || !(font in def.fonts)) { console.warn( `Theme '${def.id}' is missing font '${font}'. Shapes using this font won't render correctly in this theme.` ) } } } } }