XDSText@xds/core · Text
Usage
Text renders styled body text and headings from the theme. Use XDSText with a semantic type for body copy, labels, and captions, and XDSHeading for section titles that output the correct h1–h6 element.Best practices
| Guidance | Practices |
|---|---|
| Do | Pick a semantic type (body, label, supporting, large, code) instead of manually setting size and weight — the theme handles the details. |
| Do | Set accessibilityLevel on XDSHeading when the visual level differs from the document outline so screen readers announce the correct hierarchy. |
| Do | Use maxLines with a number to truncate long content — a tooltip appears automatically on hover so no text is lost. |
| Do | Enable hasTabularNumbers for columns of numeric data so digits align vertically across rows. |
| Don't | Override size and weight when a semantic type already matches — extra overrides fight the theme and break when themes change. |
| Don't | Skip heading levels in the document outline — go h1 then h2 then h3, never h1 then h3. |
| Don't | Use raw HTML tags like <p>, <h1>–<h6>, or <span> for text — XDSText and XDSHeading apply the correct theme tokens automatically. |
Import
tsimport {XDSText} from '@xds/core/Text'
Props
| Prop | Type | Description |
|---|---|---|
childrenrequired | ReactNode | Text content. |
type | 'body' | 'large' | 'label' | 'supporting' | 'code' (default: 'body') | Semantic text type. Determines size, weight, and line-height from the theme. |
size | '4xs' | '3xs' | '2xs' | 'xsm' | 'sm' | 'base' | 'lg' | 'xl' | '2xl' | '3xl' | '4xl' | Explicit font size override. Overrides the size from `type` but preserves other type properties. Prefer using `type` alone. |
color | 'primary' | 'secondary' | 'disabled' | 'placeholder' | 'active' | 'inherit' | Text color. Defaults to 'secondary' for the 'supporting' type, 'primary' for all others. |
weight | 'normal' | 'medium' | 'semibold' | 'bold' | Font weight override. |
display | 'inline' | 'block' (default: 'inline') | Display type. Silently overridden to 'block' when maxLines > 0 or hasCapsize is true. |
as | 'span' | 'p' | 'div' | 'label' (default: 'span') | HTML element to render. |
maxLines | number (default: 0) | Maximum lines before truncation. 0 means no truncation. When set, shows a tooltip on hover if content is truncated. |
hasTruncateTooltip | boolean | LayerPlacement (default: true) | Controls tooltip behavior for truncated text. true shows the tooltip at the default position, false disables it, or a LayerPlacement string sets a specific position. |
wordBreak | 'break-word' | 'break-all' | Word break behavior when truncating. Defaults to 'break-all' for single-line truncation, 'break-word' otherwise. |
textWrap | 'wrap' | 'nowrap' | 'balance' | 'pretty' | Text wrapping behavior. |
hasCapsize | boolean (default: false) | Enable optical alignment using text-box-trim. Forces block display. |
hasStrikethrough | boolean (default: false) | Apply strikethrough text decoration. |
hasTabularNumbers | boolean (default: false) | Use tabular (monospace) numbers for aligned numeric data. |
id | string | HTML id attribute. |
xstyle | StyleXStyles | StyleX styles for layout customization (margins, positioning, sizing). Must be a stylex.create() value — not an inline style object like style={{}}. |
Sub-components
Text is a compound component with 2 sub-components.XDSHeading
Semantic heading component that renders h1–h6 elements with themed styling, themed sizing via type scale tokens, and line-clamp truncation.| Prop | Type | Description |
|---|---|---|
levelrequired | 1 | 2 | 3 | 4 | 5 | 6 | Visual heading level. Determines both the HTML element (h1–h6) and the styling from the theme. |
childrenrequired | ReactNode | Heading content. |
accessibilityLevel | 1 | 2 | 3 | 4 | 5 | 6 | Accessibility level override. When set and different from `level`, applies `aria-level` so the document outline differs from the visual style. |
color | 'primary' | 'secondary' | 'disabled' | 'placeholder' | 'active' | 'inherit' (default: 'primary') | Text color. |
display | 'inline' | 'block' (default: 'block') | Display type. Silently overridden to 'block' when maxLines > 0 or hasCapsize is true. |
maxLines | number (default: 0) | Maximum lines before truncation. 0 means no truncation. When set, shows a tooltip on hover if content is truncated. |
hasTruncateTooltip | boolean | LayerPlacement (default: true) | Controls tooltip behavior for truncated text. true shows the tooltip at the default position, false disables it, or a LayerPlacement string sets a specific position. |
wordBreak | 'break-word' | 'break-all' | Word break behavior when truncating. Defaults to 'break-all' for single-line truncation, 'break-word' otherwise. |
textWrap | 'wrap' | 'nowrap' | 'balance' | 'pretty' | Text wrapping behavior. |
hasCapsize | boolean (default: false) | Enable optical alignment using text-box-trim. Forces block display. |
hasStrikethrough | boolean (default: false) | Apply strikethrough text decoration. |
id | string | HTML id attribute. |
XDSText
Semantic body text component that renders text with type-based styling from the theme, with optional truncation, decoration, and layout props.| Prop | Type | Description |
|---|---|---|
childrenrequired | ReactNode | Text content. |
type | 'body' | 'large' | 'label' | 'supporting' | 'code' (default: 'body') | Semantic text type. Determines size, weight, and line-height from the theme. |
size | '4xs' | '3xs' | '2xs' | 'xsm' | 'sm' | 'base' | 'lg' | 'xl' | '2xl' | '3xl' | '4xl' | Explicit font size override. Overrides the size from `type` but preserves other type properties. Prefer using `type` alone. |
color | 'primary' | 'secondary' | 'disabled' | 'placeholder' | 'active' | 'inherit' | Text color. Defaults to 'secondary' for the 'supporting' type, 'primary' for all others. |
weight | 'normal' | 'medium' | 'semibold' | 'bold' | Font weight override. |
display | 'inline' | 'block' (default: 'inline') | Display type. Silently overridden to 'block' when maxLines > 0 or hasCapsize is true. |
as | 'span' | 'p' | 'div' | 'label' (default: 'span') | HTML element to render. |
maxLines | number (default: 0) | Maximum lines before truncation. 0 means no truncation. When set, shows a tooltip on hover if content is truncated. |
hasTruncateTooltip | boolean | LayerPlacement (default: true) | Controls tooltip behavior for truncated text. true shows the tooltip at the default position, false disables it, or a LayerPlacement string sets a specific position. |
wordBreak | 'break-word' | 'break-all' | Word break behavior when truncating. Defaults to 'break-all' for single-line truncation, 'break-word' otherwise. |
textWrap | 'wrap' | 'nowrap' | 'balance' | 'pretty' | Text wrapping behavior. |
hasCapsize | boolean (default: false) | Enable optical alignment using text-box-trim. Forces block display. |
hasStrikethrough | boolean (default: false) | Apply strikethrough text decoration. |
hasTabularNumbers | boolean (default: false) | Use tabular (monospace) numbers for aligned numeric data. |
id | string | HTML id attribute. |
xstyle | StyleXStyles | StyleX styles for layout customization (margins, positioning, sizing). Must be a stylex.create() value — not an inline style object like style={{}}. |
Examples
Common configurations, variations, and states.Text — ColorsAll text color options (primary, secondary, disabled, placeholder, active) applied to body text to show their intended use.
tsx'use client';import {XDSText} from '@xds/core/Text';import {XDSStack} from '@xds/core/Stack';const COLORS = [{color: 'primary' as const, description: 'Primary — Default for headings and body text'},{color: 'secondary' as const, description: 'Secondary — Supporting details and metadata'},{color: 'active' as const, description: 'Active — Links, success states, and emphasis'},{color: 'disabled' as const, description: 'Disabled — Unavailable or inactive content'},{color: 'placeholder' as const, description: 'Placeholder — Empty field hints'},];export default function TextColors() {return (<XDSStack direction="vertical" gap={3}>{COLORS.map(({color, description}) => (<XDSText key={color} type="body" color={color}>{description}</XDSText>))}</XDSStack>);}
Text — Heading LevelsAll 6 heading levels (h1 through h6) rendered with XDSHeading to show the full type scale.
tsx'use client';import {XDSHeading} from '@xds/core/Text';import {XDSStack} from '@xds/core/Stack';const LEVELS = [1, 2, 3, 4, 5, 6] as const;export default function TextHeadingLevels() {return (<XDSStack direction="vertical" gap={3}>{LEVELS.map((level) => (<XDSHeading key={level} level={level}>Heading {level}</XDSHeading>))}</XDSStack>);}
Text — InlineMixing body and code text inline within a single line using the default inline display mode.
tsx'use client';import {XDSText} from '@xds/core/Text';export default function TextInline() {return (<XDSText type="body" display="block">Design tokens are{' '}<XDSText type="code">themeable</XDSText>{' '}and shared across every surface.</XDSText>);}
Text — TruncationSingle-line and multi-line text truncation with ellipsis using maxLines in a width-constrained container.
tsx'use client';import {XDSText} from '@xds/core/Text';const LONG_TEXT ='The design system provides a consistent set of typography tokens, spacing scales, and color palettes that ensure every surface in the product feels cohesive regardless of which team built it.';const LINES = [{maxLines: 1, label: '1 line'},{maxLines: 2, label: '2 lines'},{maxLines: 3, label: '3 lines'},];export default function TextTruncation() {return (<divstyle={{display: 'flex',flexDirection: 'column',gap: 16,maxWidth: 300,}}>{LINES.map(({maxLines, label}) => (<div key={maxLines}><XDSText type="supporting" color="secondary" display="block">{label}</XDSText><div style={{border: '1px solid #ccc', padding: 8}}><XDSText type="body" maxLines={maxLines}>{LONG_TEXT}</XDSText></div></div>))}</div>);}
Text — TypesAll 5 semantic text types (body, large, label, supporting, code) with their default styling from the theme.
tsx'use client';import {XDSText} from '@xds/core/Text';import {XDSStack} from '@xds/core/Stack';const TYPES = [{type: 'body' as const, label: 'Body text', sample: 'Body text for paragraphs and general content'},{type: 'large' as const, label: 'Large text', sample: 'Large text for introductions and callouts'},{type: 'label' as const, label: 'Label text', sample: 'Label text for form fields and section titles'},{type: 'supporting' as const, label: 'Supporting text', sample: 'Supporting text for captions and metadata'},{type: 'code' as const, label: 'Code text', sample: 'const theme = defineTheme({})'},{type: 'body' as const, label: 'Strikethrough', sample: 'Body text with strikethrough decoration', hasStrikethrough: true},{type: 'body' as const, label: 'Tabular numbers', sample: '1,234.56 78.90 100,000.00', hasTabularNumbers: true},];export default function TextTypes() {return (<XDSStack direction="vertical" gap={3}>{TYPES.map(({type, label, sample, hasStrikethrough, hasTabularNumbers}) => (<XDSStack key={label} direction="vertical" gap={0}><XDSText type="supporting" color="secondary">{label}</XDSText><XDSTexttype={type}display="block"hasStrikethrough={hasStrikethrough}hasTabularNumbers={hasTabularNumbers}>{sample}</XDSText></XDSStack>))}</XDSStack>);}
Text — WeightThe 4 font weight variants (normal, medium, semibold, bold) applied to body text.
tsx'use client';import {XDSText} from '@xds/core/Text';import {XDSStack} from '@xds/core/Stack';const WEIGHTS = [{weight: 'normal' as const, label: 'Normal'},{weight: 'medium' as const, label: 'Medium'},{weight: 'semibold' as const, label: 'Semibold'},{weight: 'bold' as const, label: 'Bold'},];export default function TextWeight() {return (<XDSStack direction="vertical" gap={3}>{WEIGHTS.map(({weight, label}) => (<XDSText key={weight} type="body" weight={weight} display="block">{label}</XDSText>))}</XDSStack>);}
Text — Word BreakCompares break-word and break-all word break modes on a long unbreakable string.
tsx'use client';import {XDSText} from '@xds/core/Text';export default function TextWordBreak() {return (<divstyle={{display: 'flex',flexDirection: 'column',gap: 16,maxWidth: 400,}}><div><XDSText type="label" display="block">Break-word (default for multi-line)</XDSText><div style={{width: 200, border: '1px solid #ccc', padding: 8}}><XDSText type="body" maxLines={2} wordBreak="break-word">This is a verylongunbreakableword for a break-word example</XDSText></div></div><div><XDSText type="label" display="block">Break-all (default for single-line)</XDSText><div style={{width: 200, border: '1px solid #ccc', padding: 8}}><XDSText type="body" maxLines={2} wordBreak="break-all">Breaks anywhere: abcdefghijklmnopqrstuvwxyz0123456789</XDSText></div></div></div>);}
Text — WrapThe 4 text-wrap modes (wrap, nowrap, balance, pretty) shown in width-constrained containers.
tsx'use client';import {XDSText} from '@xds/core/Text';export default function TextWrap() {return (<divstyle={{display: 'flex',flexDirection: 'column',gap: 16,maxWidth: 400,}}><div><XDSText type="label" display="block">Wrap (default)</XDSText><div style={{border: '1px solid #ccc', padding: 8, width: 200}}><XDSText type="body" textWrap="wrap">This text wraps normally at word boundaries when it reaches theedge.</XDSText></div></div><div><XDSText type="label" display="block">Nowrap</XDSText><divstyle={{border: '1px solid #ccc',padding: 8,width: 200,overflow: 'hidden',}}><XDSText type="body" textWrap="nowrap">This text does not wrap and will overflow its container.</XDSText></div></div><div><XDSText type="label" display="block">Balance</XDSText><div style={{border: '1px solid #ccc', padding: 8, width: 200}}><XDSText type="body" textWrap="balance">This text is balanced for better visual appearance across lines.</XDSText></div></div><div><XDSText type="label" display="block">Pretty</XDSText><div style={{border: '1px solid #ccc', padding: 8, width: 200}}><XDSText type="body" textWrap="pretty">This text uses pretty wrap to avoid orphans at the end ofparagraphs.</XDSText></div></div></div>);}
Showcase source
tsx'use client';import {XDSText} from '@xds/core/Text';import {XDSStack} from '@xds/core/Stack';export default function TextShowcase() {return (<XDSStack direction="vertical" gap={2}><XDSText type="body">Body: The bulk of content</XDSText><XDSText type="large">Large: Emphasized content</XDSText><XDSText type="label">Label: Form and chart labels</XDSText><XDSText type="supporting">Supporting: Helper text</XDSText><XDSText type="code">Code: const x = 42;</XDSText></XDSStack>);}