Components / Feedback and display
Text
One piece of text in Cynosure's type scale: a label, a caption, a lead paragraph, a helper line or a value. For long-form content use Prose; for a title use Heading.
When to useLink to "When to use"
body(default): a short line of interface text. It takes the sizemdand the colour around it.lead: the intro sentence under a page or section title.caption: secondary detail under or beside something: a timestamp, a hint, a figure caption.eyebrow: the small uppercase label above a title or a group.code: a command, a file name or an identifier inside a line of text.numeric: values that sit in a column or change in place, so the digits do not jump.
Use something else when:
- the text is rendered Markdown or several paragraphs: Prose
- it is a title: Heading
- it is a status or category label with a background: Badge
- it is a block of code: CodeBlock
- it is a keyboard key: Kbd
- it labels a form control: the control's own
labelprop (TextField and the other fields)
UsageLink to "Usage"
import { Text } from "@arshad-shah/cynosure";
<Text>Last saved 2 minutes ago</Text>
<Text as="p" variant="lead">Everything that changed this month.</Text>
<Text variant="eyebrow">Release notes</Text>
<Text variant="caption" tone="danger">Could not save</Text>
<Text numeric weight="bold" size="xl">1,284.50</Text>
<Text as="p" truncate={2}>{description}</Text>
<Text as="time" dateTime="2026-03-12" variant="caption">12 March</Text>Sizes, weights and tonesLink to "Sizes, weights and tones"
size maps to the six font size tokens, weight to the three weight tokens. A variant only sets defaults: a size, weight or tone you give always wins.
tone="inherit" (the default for body and code) takes the surrounding colour. neutral is the ink and muted the secondary ink. The other tones use the readable text colour of that tone.
TruncationLink to "Truncation"
truncate keeps one line and ends it with an ellipsis. A number keeps that many lines. The text is cut to the width of its container, so the container needs a width.
WrappingLink to "Wrapping"
wrap="pre" keeps spaces and line breaks as written (a query, a log line) and still wraps at the container's edge. wrap="break" breaks a long unbroken string, such as an id, a hash or a URL, anywhere rather than letting it overflow. truncate wins over both.
Values and nestingLink to "Values and nesting"
numeric switches to tabular figures. A Text directly inside another Text keeps the outer size, weight and face, and changes only what it is given, so a value or a strong word inside a lead stays a lead.
PropsLink to "Props"
| Prop | What it does | Type | Default |
|---|---|---|---|
as | Element to render. strong is bold unless weight says otherwise; p, div and figcaption are blocks, the rest are inline. Default "span". | "time" | "div" | "label" | "strong" | "span" | "p" | "em" | "small" | "figcaption" | "span" |
variant | Preset: lead is larger muted intro text, caption is small and muted, eyebrow is the small uppercase tracked label, code uses the mono face. A preset only sets defaults: size, weight and tone still win. Default "body". | "body" | "lead" | "caption" | "eyebrow" | "code" | "body" |
size | Font size, from the --cy-font-size-* tokens. Default: from the variant ("md" for body). A Text placed directly inside another Text takes the outer size. | "sm" | "md" | "lg" | "xs" | "xl" | "2xl" | |
weight | Font weight. Default "regular" ("bold" for the eyebrow variant and for as="strong"). A Text placed directly inside another Text takes the outer weight. | "medium" | "bold" | "regular" | |
tone | Colour. inherit takes the surrounding colour, neutral is the ink, muted the secondary ink; the others are the readable text colour of that tone. Default "inherit" ("muted" for lead, caption and eyebrow). | Tone | "inherit" | "muted" | "inherit" ("muted" for lead |
align | Horizontal alignment; start and end follow the reading direction. Makes an inline element a block. | "start" | "end" | "center" | |
truncate | Cuts text that does not fit and ends it with an ellipsis: true keeps one line, a number keeps that many lines. An inline element becomes an inline block (one line) or a block (several lines). Default false. | number | boolean | false |
wrap | How lines wrap. pre keeps spaces and line breaks as written (a query, a log line) and still wraps at the edge; break breaks long unbroken strings such as ids, hashes and URLs anywhere rather than letting them overflow. truncate wins over it. Default: normal wrapping. | "pre" | "break" | normal wrapping |
numeric | Tabular figures, so digits in a column line up. Default false. | boolean | false |
htmlFor | Id of the control this text labels. Used with as="label". | string | |
dateTime | Machine-readable date or time. Used with as="time". | string | |
id | Id of the element, for aria-labelledby and aria-describedby. | string | |
className | Added to the root element, for layout. | string | |
style | Layout only. Restyle through --cy-text-* tokens. | CSSProperties | |
children | The text. | ReactNode |
Generated from the type definitions in @arshad-shah/cynosure 0.5.0.
Behaviour and accessibilityLink to "Behaviour and accessibility"
Text is not interactive, so it has no keyboard behaviour.
| Prop | Result |
|---|---|
as | Renders that element. span, label, strong, em, small and time are inline; p, div and figcaption are blocks. None has a margin |
as="label" with htmlFor | Pressing the text focuses the control with that id |
as="time" with dateTime | Carries the machine-readable date |
as="strong" | Bold unless weight is given |
align | start and end follow the reading direction. An inline element becomes a block |
wrap | pre keeps spaces and line breaks; break breaks long strings anywhere |
truncate | An inline element becomes an inline block (one line) or a block (several lines) |
- Meaning: Text adds no role. Pick the element for what the text is.
- Truncated text: the full text stays in the DOM and is read by screen readers. Sighted users cannot reach the hidden part, so do not truncate text people must read.
- Eyebrow: the uppercase is visual only. The text in the DOM keeps its case.
- Contrast: every tone and the muted variants keep 4.5:1 on the page background (tested).
- Host CSS: host rules for
spananddiv(weight, case, letter spacing, colour, size, line height) do not change Text (tested).
TouchLink to "Touch"
Text is not pressable, so it has no hit area. A label passes a tap on to its control, which has its own hit area.
ThemingLink to "Theming"
Tokens: --cy-text-line-height, --cy-text-lead-size, --cy-text-caption-size, --cy-text-eyebrow-size, --cy-text-eyebrow-tracking and --cy-text-muted. Sizes, weights, faces and tone colours come from the global tokens (--cy-font-size-*, --cy-font-weight-*, --cy-font-sans, --cy-font-mono, --cy-color-*-text).
createTheme({ components: { text: { leadSize: "18px", eyebrowTracking: ".12em" } } });className and style are for layout only (margin, placement, width). Change the look through tokens so every product stays consistent.
RelatedLink to "Related"
These examples run Cynosure 0.5.0 (commit 50ce30b), the version on npm.