import {createComponent} from '@workday/canvas-kit-react/common'; import {BoxProps, mergeStyles} from '@workday/canvas-kit-react/layout'; import {createStencil} from '@workday/canvas-kit-styling'; import {system} from '@workday/canvas-tokens-web'; type TypeSize = 'large' | 'medium' | 'small'; type TokenName = `${keyof typeof system.legacy.type}.${TypeSize}`; export interface TextProps extends BoxProps { /** * Type token as string with level and size separated by dot. * These values map to our [Canvas type levels](https://canvas.workday.com/tokens/type#type-styles). * * ```tsx * Small body text * ``` */ typeLevel?: TokenName; /** * Type variant token names: `error`, `hint` or `inverse`. * * ```tsx * Error text * ``` */ variant?: 'error' | 'hint' | 'inverse'; } export const textStencil = createStencil({ base: {}, modifiers: { typeLevel: { // Title level styles 'title.large': { fontFamily: system.fontFamily.default, fontWeight: system.fontWeight.bold, fontSize: system.legacy.fontSize.title.lg, lineHeight: system.legacy.lineHeight.title.lg, color: system.color.fg.strong, }, 'title.medium': { fontFamily: system.fontFamily.default, fontWeight: system.fontWeight.bold, fontSize: system.legacy.fontSize.title.md, lineHeight: system.legacy.lineHeight.title.md, color: system.color.fg.strong, }, 'title.small': { fontFamily: system.fontFamily.default, fontWeight: system.fontWeight.bold, lineHeight: system.legacy.lineHeight.title.sm, fontSize: system.legacy.fontSize.title.sm, color: system.color.fg.strong, }, // Heading level styles 'heading.large': { fontFamily: system.fontFamily.default, fontWeight: system.fontWeight.bold, fontSize: system.legacy.fontSize.heading.lg, lineHeight: system.legacy.lineHeight.heading.lg, color: system.color.fg.strong, }, 'heading.medium': { fontFamily: system.fontFamily.default, fontWeight: system.fontWeight.bold, fontSize: system.legacy.fontSize.heading.md, lineHeight: system.legacy.lineHeight.heading.md, color: system.color.fg.strong, }, 'heading.small': { fontFamily: system.fontFamily.default, fontWeight: system.fontWeight.bold, fontSize: system.legacy.fontSize.heading.sm, lineHeight: system.legacy.lineHeight.heading.sm, color: system.color.fg.strong, }, // Body level styles 'body.large': { fontFamily: system.fontFamily.default, fontWeight: system.fontWeight.normal, fontSize: system.legacy.fontSize.body.lg, lineHeight: system.legacy.lineHeight.body.lg, color: system.color.fg.default, }, 'body.medium': { fontFamily: system.fontFamily.default, fontWeight: system.fontWeight.normal, fontSize: system.legacy.fontSize.body.md, lineHeight: system.legacy.lineHeight.body.md, color: system.color.fg.default, }, 'body.small': { fontFamily: system.fontFamily.default, fontWeight: system.fontWeight.normal, fontSize: system.legacy.fontSize.body.sm, lineHeight: system.legacy.lineHeight.body.sm, letterSpacing: system.legacy.letterSpacing.body.sm, color: system.color.fg.default, }, // Subtext level styles 'subtext.large': { fontFamily: system.fontFamily.default, fontWeight: system.fontWeight.normal, fontSize: system.legacy.fontSize.subtext.lg, lineHeight: system.legacy.lineHeight.subtext.lg, letterSpacing: system.legacy.letterSpacing.subtext.lg, color: system.color.fg.default, }, 'subtext.medium': { fontFamily: system.fontFamily.default, fontWeight: system.fontWeight.normal, fontSize: system.legacy.fontSize.subtext.md, lineHeight: system.legacy.lineHeight.subtext.md, letterSpacing: system.legacy.letterSpacing.subtext.md, color: system.color.fg.default, }, 'subtext.small': { fontFamily: system.fontFamily.default, fontWeight: system.fontWeight.normal, fontSize: system.legacy.fontSize.subtext.sm, lineHeight: system.legacy.lineHeight.subtext.sm, letterSpacing: system.legacy.letterSpacing.subtext.sm, color: system.color.fg.default, }, }, variant: { error: { color: system.legacy.color.brand.fg.critical.default, }, hint: {color: system.color.fg.muted.default}, inverse: {color: system.color.fg.inverse}, }, }, }); /** * This is a generic base component intended to render any text. * It has `typeLevel` and `variant` style props that simplify navigating * our type hierarchy and using [Canvas type tokens](https://canvas.workday.com/tokens/type#type-styles). * By default, it renders a semantic `span` element, * but you can adjust this as needed with the `as` prop. * * The type hierarchy is organized into four levels, which correspond to our [Canvas type * levels](https://canvas.workday.com/tokens/type#type-styles). * * - `title`: Intended to be used for large page titles. * - `heading`: Intended to be used for headings and large text. * - `body`: Intended to be used for standard body text. * - `subtext`: Intended to be used for small subtext content or in tight spaces. * * Each level has three sizes: `large`, `medium`, and `small`. * * You can provide any level and size to the `typeLevel` prop, and it will apply the correct styles * accordingly. In the example below we're providing the `subtext` level and `small` size to the * component with the value `subtext.small`. * * ```tsx * import { Text } from '@workday/canvas-kit-react/text'; * * const CustomErrorText = () => ( * * Error Text * * ); * ``` */ export const Text = createComponent('span')({ displayName: 'Text', Component: ({children, typeLevel, variant, ...elemProps}: TextProps, ref, Element) => { return ( {children} ); }, });