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

GuidancePractices
DoPick a semantic type (body, label, supporting, large, code) instead of manually setting size and weight — the theme handles the details.
DoSet accessibilityLevel on XDSHeading when the visual level differs from the document outline so screen readers announce the correct hierarchy.
DoUse maxLines with a number to truncate long content — a tooltip appears automatically on hover so no text is lost.
DoEnable hasTabularNumbers for columns of numeric data so digits align vertically across rows.
Don'tOverride size and weight when a semantic type already matches — extra overrides fight the theme and break when themes change.
Don'tSkip heading levels in the document outline — go h1 then h2 then h3, never h1 then h3.
Don'tUse raw HTML tags like <p>, <h1>–<h6>, or <span> for text — XDSText and XDSHeading apply the correct theme tokens automatically.

Import

ts
import {XDSText} from '@xds/core/Text'

Props

PropTypeDescription
childrenrequired
ReactNodeText 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
stringHTML id attribute.
xstyle
StyleXStylesStyleX 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.
PropTypeDescription
levelrequired
1 | 2 | 3 | 4 | 5 | 6Visual heading level. Determines both the HTML element (h1–h6) and the styling from the theme.
childrenrequired
ReactNodeHeading content.
accessibilityLevel
1 | 2 | 3 | 4 | 5 | 6Accessibility 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
stringHTML id attribute.

XDSText

Semantic body text component that renders text with type-based styling from the theme, with optional truncation, decoration, and layout props.
PropTypeDescription
childrenrequired
ReactNodeText 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
stringHTML id attribute.
xstyle
StyleXStylesStyleX 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 (
<div
style={{
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>
<XDSText
type={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 (
<div
style={{
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 (
<div
style={{
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 the
edge.
</XDSText>
</div>
</div>
<div>
<XDSText type="label" display="block">
Nowrap
</XDSText>
<div
style={{
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 of
paragraphs.
</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>
);
}