import "./text.css"; import type * as React from "react"; import { useRender } from "@base-ui/react/use-render"; import { type StyleProps } from "./style_props"; import { type TypeRungName } from "./type_ramp"; import { type TextColor } from "./text_ink"; export type HeadingLevel = 1 | 2 | 3 | 4 | 5 | 6; /** * The rungs of the ramp — the set is the ramp's own keys rather than a literal * union repeated here, so a rung cannot exist in one and not the other. */ export type TextSize = TypeRungName; type TextAlign = "left" | "right" | "center"; type TextDecoration = "underline" | "line-through" | "underline line-through"; type TextWeight = "regular" | "medium" | "semibold"; type TextTransform = "uppercase" | "lowercase" | "capitalize"; type TextUserSelect = "none" | "auto" | "text"; /** The elements a run of text may be. A heading comes from `level`. */ type TextElement = "span" | "p" | "div" | "label" | "strong" | "em"; export interface TextProps extends StyleProps { children?: React.ReactNode; testID?: string; size?: TextSize; color?: TextColor; /** `display` renders in the app's display face — a headline, a wordmark, a * figure the page exists to show. A ROLE, not a font name: the call site says * what the text IS, and the theme decides what that looks like. */ family?: "display"; /** * `tight` sets the rung's line box for a STACKED PAIR instead of for prose — * a subject over its supporting line, a value over its annotation. * * Set it on BOTH lines of the pair: the box belongs to each line, so tightening * one leaves the stack lopsided. Not for running text. */ leading?: "tight"; /** * `anywhere` breaks a run at ANY character rather than only between words — * for a value with no spaces in it: an id, a URL, a hash, a filename. * `break-word` cannot help there, because it only breaks a word that would * otherwise overflow ALONE. * * OPT-IN, because prose set this way breaks mid-word wherever the line ends. */ wrap?: "anywhere"; align?: TextAlign; weight?: TextWeight; /** * Clamp to this many lines, with an ellipsis on the last. * * `"container"` clamps to the count the SURROUNDING SHEET states in * `--lotics-text-lines` — how a component whose own `@container` query decides * the count says so, since a number here is an inline style no query can beat. */ lines?: number | "container"; userSelect?: TextUserSelect; transform?: TextTransform; decoration?: TextDecoration; /** A URL — renders the run as a real ``, so middle-click and * open-in-new-tab work. Anything that ACTS is a control: substitute the * element with `render={