import React from "react"; import type { FontFamily, TextAlign, TextColor, TruncateLength, TypographyProps, } from "../Typography"; import { Typography } from "../Typography"; import { tokens } from "../utils/design"; type HeadingStyle = Pick< TypographyProps, "fontFamily" | "fontWeight" | "size" | "lineHeight" | "color" >; type HeadingColor = Extract; export type HeadingLevel = "title" | "subtitle" | "heading" | "subHeading"; interface HeadingProps extends Pick, "selectable"> { /** * Text to display. Supports nesting text elements. */ readonly children: React.ReactNode; /** * The type of heading, e.g., "Title" */ readonly level?: T; /** * The text color of heading */ readonly variation?: HeadingColor; /** * Uses the reverse variant of the text color for the heading */ readonly reverseTheme?: boolean; /** * Alignment of heading */ readonly align?: TextAlign; /** * The maximum amount of lines the text can occupy before being truncated with "...". * Uses predefined string values that correspond to a doubling scale for the amount of lines. */ readonly maxLines?: TruncateLength; /** * Allow text to be resized based on user's device display scale */ readonly allowFontScaling?: boolean; } export const HEADING_MAX_SCALED_FONT_SIZE: Record = { subHeading: tokens["typography--fontSize-base"] * 1.375, heading: tokens["typography--fontSize-base"] * 1.5, subtitle: tokens["typography--fontSize-base"] * 1.5, title: tokens["typography--fontSize-base"] * 2.125, }; export function Heading({ children, level, variation = "heading", reverseTheme = false, align, maxLines = "unlimited", allowFontScaling = true, selectable, }: HeadingProps) { const headingStyle = getHeadingStyle(level, variation); const accessibilityRole = "header"; return ( {children} ); } function getHeadingStyle( level: HeadingLevel = "heading", variation: HeadingColor, ): HeadingStyle { const headingLevelToStyle: Record = { title: { fontFamily: "display", fontWeight: "extraBold", size: "jumbo", lineHeight: "jumbo", color: variation, }, subtitle: { fontFamily: "base", fontWeight: "bold", size: "largest", lineHeight: "largest", color: variation, }, heading: { fontFamily: "base", fontWeight: "bold", size: "larger", lineHeight: "larger", color: variation, }, subHeading: { fontFamily: "base", fontWeight: "semiBold", size: "default", lineHeight: "base", color: variation, }, }; return headingLevelToStyle[level]; }