# Text (/components/typography/text)



`Text` applies Luke UI typography without adding heading semantics. It needs a Luke UI theme root.
See [Getting started](/docs/installation).

apps/docs/src/examples/text/basic.tsx

```tsx
import { Text } from '@luke-ui/react/text';

export default () => {
	return <Text>The quick brown fox jumps over the lazy dog.</Text>;
};
```

## Element type [#element-type]

`Text` renders React Aria's `Text` component, which uses a `span` by default. Set `elementType` to
choose a semantic element without changing the type treatment. `Text` trims Capsize space on known
block elements such as `p`, `div`, headings, and `blockquote`, and skips it for inline or unknown
element types.

```tsx
<Text elementType="p">A paragraph of supporting copy.</Text>

<Text elementType="label">Email address</Text>
```

## Typography [#typography]

Pass `typography` to choose a style. `body` is the default. See [Typography](/docs/typography) for
the full style reference.

apps/docs/src/examples/text/lead.tsx

```tsx
import { Text } from '@luke-ui/react/text';

export default () => {
	return <Text typography="lead">Lead text sits at a larger size than body text.</Text>;
};
```

Set `fontWeight` only when you need to override the style's weight. Themes expose `body`, `label`,
`heading`, and `emphasis` roles for that purpose.

## Alignment [#alignment]

Set `textAlign` when the layout needs a different inline alignment.

apps/docs/src/examples/text/alignment.tsx

```tsx
import { Box } from '@luke-ui/react/box';
import { Text } from '@luke-ui/react/text';
import { vars } from '@luke-ui/react/theme';

const rowStyle = {
	backgroundColor: vars.color.background.neutral.subtle.rest,
} as const;

export default () => {
	return (
		<Box display="flex" flexDirection="column" gap="sp8" inlineSize="100%">
			<Text elementType="p" style={rowStyle} textAlign="start">
				Start aligned
			</Text>
			<Text elementType="p" style={rowStyle} textAlign="center">
				Centre aligned
			</Text>
			<Text elementType="p" style={rowStyle} textAlign="end">
				End aligned
			</Text>
		</Box>
	);
};
```

## Numeric glyphs [#numeric-glyphs]

Use `fontVariantNumeric` to align numeric columns, format fractions and ordinals, or distinguish
zero with a slash.

apps/docs/src/examples/text/numeric-glyphs.tsx

```tsx
import { Box } from '@luke-ui/react/box';
import { Text } from '@luke-ui/react/text';

const variants = [
	{ label: 'Tabular', sample: '111,111 888,888', value: 'tabular-nums' },
	{ label: 'Fractions', sample: '1/2 3/4 5/6', value: 'diagonal-fractions' },
	{ label: 'Ordinals', sample: '1st 2nd 3rd 4th', value: 'ordinal' },
	{ label: 'Slashed zero', sample: '012 OQR', value: 'slashed-zero' },
] as const;

export default () => {
	return (
		<Box
			display="grid"
			gap="sp16"
			inlineSize="100%"
			maxInlineSize="48rem"
			style={{ gridTemplateColumns: 'repeat(auto-fit, minmax(8rem, 1fr))' }}
		>
			{variants.map((variant) => (
				<Box display="grid" gap="sp8" key={variant.value}>
					<Text color="secondary" typography="caption">
						{variant.label}
					</Text>
					<Text elementType="div" fontVariantNumeric={variant.value}>
						{variant.sample}
					</Text>
				</Box>
			))}
		</Box>
	);
};
```

## Trimming [#trimming]

Block text trims space above capitals and below the baseline by default. That makes vertical spacing
more predictable in cards and other bounded layouts. Inline text skips trim so its pseudo-elements
cannot interrupt the surrounding line. Set `shouldDisableTrim` explicitly when you need to override
the element-type inference.

apps/docs/src/examples/text/trim.tsx

```tsx
import { Box } from '@luke-ui/react/box';
import { Checkbox } from '@luke-ui/react/checkbox';
import { Text } from '@luke-ui/react/text';
import { vars } from '@luke-ui/react/theme';
import { useState } from 'react';

const lineBoxStyle = {
	backgroundColor: vars.color.surface.recessed,
	borderBlock: `1px dashed ${vars.color.border.decorative}`,
} as const;

export default () => {
	const [isTrimmed, setIsTrimmed] = useState(true);

	return (
		<Box display="flex" flexDirection="column" gap="sp16">
			<Checkbox isSelected={isTrimmed} onChange={setIsTrimmed}>
				Trim text
			</Checkbox>
			<Box paddingInline="sp12" style={lineBoxStyle}>
				<Text elementType="div" shouldDisableTrim={!isTrimmed} typography="display">
					Aa
				</Text>
			</Box>
		</Box>
	);
};
```

## Truncation [#truncation]

Use `lineClamp` to constrain text to one line or up to five lines. `Text` truncates overflow with an
ellipsis. It disables trimming automatically when you set `lineClamp`.

apps/docs/src/examples/text/truncation.tsx

```tsx
import { Box } from '@luke-ui/react/box';
import { Text } from '@luke-ui/react/text';

export default () => {
	return (
		<Box display="flex" flexDirection="column" gap="sp16" maxInlineSize="20rem">
			<Text elementType="div" lineClamp>
				Short lines are easier to scan than long ones, which is why well-set text rarely stretches
				edge to edge on a wide screen, no matter how much room is available.
			</Text>
			<Text elementType="div" lineClamp={2}>
				Short lines are easier to scan than long ones, which is why well-set text rarely stretches
				edge to edge on a wide screen, no matter how much room is available.
			</Text>
		</Box>
	);
};
```

## Transform and decoration [#transform-and-decoration]

Use `textTransform` and `textDecoration` when the content calls for them. These props affect the
rendered text only, so avoid using uppercase styling as a substitute for a clear label.

apps/docs/src/examples/text/transform.tsx

```tsx
import { Box } from '@luke-ui/react/box';
import { Text } from '@luke-ui/react/text';

export default () => {
	return (
		<Box display="flex" flexDirection="column" gap="sp12">
			<Text textTransform="uppercase">Uppercase text</Text>
			<Text textDecoration="underline">Underlined text</Text>
		</Box>
	);
};
```

## Related components [#related-components]

Use [Heading](/components/typography/heading) for a section heading. It manages heading levels for
you. Use `Text` with a larger style such as `display` or `heading1` for prominent content that is
not a heading. A large status value is one example.

Use [Numeral](/components/typography/numeral) to format locale-aware numbers and
[Emoji](/components/typography/emoji) for an emoji with a reliable accessible label.

## API [#api]

<ComponentPropsTable
  id="type-table-text.tsx-TextProps"
  type="{
  &#x22;id&#x22;: &#x22;text.tsx-TextProps&#x22;,
  &#x22;name&#x22;: &#x22;TextProps&#x22;,
  &#x22;description&#x22;: &#x22;Props for the `Text` component.&#x22;,
  &#x22;entries&#x22;: [
    {
      &#x22;name&#x22;: &#x22;render&#x22;,
      &#x22;description&#x22;: &#x22;Overrides the default DOM element with a custom render function.\nThis allows rendering existing components with built-in styles and behaviors\nsuch as router links, animation libraries, and pre-styled components.\n\nRequirements:\n\n- You must render the expected element type (e.g. if `<button>` is expected, you cannot render an\n  `<a>`).\n- Only a single root DOM element can be rendered (no fragments).\n- You must pass through props and ref to the underlying DOM element, merging with your own prop\n  as appropriate.&#x22;,
      &#x22;tags&#x22;: [],
      &#x22;type&#x22;: &#x22;DOMRenderFunction<any, any> | undefined&#x22;,
      &#x22;simplifiedType&#x22;: &#x22;DOMRenderFunction<any, any>&#x22;,
      &#x22;required&#x22;: false,
      &#x22;deprecated&#x22;: false
    },
    {
      &#x22;name&#x22;: &#x22;color&#x22;,
      &#x22;description&#x22;: &#x22;Sets text colour.&#x22;,
      &#x22;tags&#x22;: [
        {
          &#x22;name&#x22;: &#x22;default&#x22;,
          &#x22;text&#x22;: &#x22;'primary'&#x22;
        }
      ],
      &#x22;type&#x22;: &#x22;\&#x22;accent\&#x22; | \&#x22;info\&#x22; | \&#x22;success\&#x22; | \&#x22;warning\&#x22; | \&#x22;danger\&#x22; | \&#x22;primary\&#x22; | \&#x22;secondary\&#x22; | undefined&#x22;,
      &#x22;simplifiedType&#x22;: &#x22;union&#x22;,
      &#x22;required&#x22;: false,
      &#x22;deprecated&#x22;: false
    },
    {
      &#x22;name&#x22;: &#x22;fontStyle&#x22;,
      &#x22;description&#x22;: &#x22;Sets font style.&#x22;,
      &#x22;tags&#x22;: [
        {
          &#x22;name&#x22;: &#x22;default&#x22;,
          &#x22;text&#x22;: &#x22;'default'&#x22;
        }
      ],
      &#x22;type&#x22;: &#x22;\&#x22;inherit\&#x22; | \&#x22;normal\&#x22; | \&#x22;default\&#x22; | \&#x22;italic\&#x22; | undefined&#x22;,
      &#x22;simplifiedType&#x22;: &#x22;union&#x22;,
      &#x22;required&#x22;: false,
      &#x22;deprecated&#x22;: false
    },
    {
      &#x22;name&#x22;: &#x22;fontVariantNumeric&#x22;,
      &#x22;description&#x22;: &#x22;Sets numeric glyph style.&#x22;,
      &#x22;tags&#x22;: [
        {
          &#x22;name&#x22;: &#x22;default&#x22;,
          &#x22;text&#x22;: &#x22;'default'&#x22;
        }
      ],
      &#x22;type&#x22;: &#x22;\&#x22;normal\&#x22; | \&#x22;default\&#x22; | \&#x22;diagonal-fractions\&#x22; | \&#x22;ordinal\&#x22; | \&#x22;slashed-zero\&#x22; | \&#x22;tabular-nums\&#x22; | undefined&#x22;,
      &#x22;simplifiedType&#x22;: &#x22;union&#x22;,
      &#x22;required&#x22;: false,
      &#x22;deprecated&#x22;: false
    },
    {
      &#x22;name&#x22;: &#x22;fontWeight&#x22;,
      &#x22;description&#x22;: &#x22;Sets the semantic font-weight role. When omitted, the selected typography style supplies its\nweight.&#x22;,
      &#x22;tags&#x22;: [],
      &#x22;type&#x22;: &#x22;\&#x22;body\&#x22; | \&#x22;label\&#x22; | \&#x22;heading\&#x22; | \&#x22;emphasis\&#x22; | undefined&#x22;,
      &#x22;simplifiedType&#x22;: &#x22;union&#x22;,
      &#x22;required&#x22;: false,
      &#x22;deprecated&#x22;: false
    },
    {
      &#x22;name&#x22;: &#x22;isVisuallyHidden&#x22;,
      &#x22;description&#x22;: &#x22;Hides text visually while keeping it accessible.&#x22;,
      &#x22;tags&#x22;: [
        {
          &#x22;name&#x22;: &#x22;default&#x22;,
          &#x22;text&#x22;: &#x22;false&#x22;
        }
      ],
      &#x22;type&#x22;: &#x22;boolean | undefined&#x22;,
      &#x22;simplifiedType&#x22;: &#x22;union&#x22;,
      &#x22;required&#x22;: false,
      &#x22;deprecated&#x22;: false
    },
    {
      &#x22;name&#x22;: &#x22;lineClamp&#x22;,
      &#x22;description&#x22;: &#x22;Clamps text lines. `true` clamps to 1 line; numeric values clamp to 1–5.&#x22;,
      &#x22;tags&#x22;: [],
      &#x22;type&#x22;: &#x22;boolean | 2 | 1 | 3 | 4 | 5 | undefined&#x22;,
      &#x22;simplifiedType&#x22;: &#x22;union&#x22;,
      &#x22;required&#x22;: false,
      &#x22;deprecated&#x22;: false
    },
    {
      &#x22;name&#x22;: &#x22;shouldDisableTrim&#x22;,
      &#x22;description&#x22;: &#x22;Turns cap-height trim on or off. When omitted, trimming is disabled for inline or unknown\nelement types. Line clamp always disables trim.&#x22;,
      &#x22;tags&#x22;: [],
      &#x22;type&#x22;: &#x22;boolean | undefined&#x22;,
      &#x22;simplifiedType&#x22;: &#x22;union&#x22;,
      &#x22;required&#x22;: false,
      &#x22;deprecated&#x22;: false
    },
    {
      &#x22;name&#x22;: &#x22;shouldInheritFont&#x22;,
      &#x22;description&#x22;: &#x22;Makes text inherit its surrounding font and colour styles.&#x22;,
      &#x22;tags&#x22;: [
        {
          &#x22;name&#x22;: &#x22;default&#x22;,
          &#x22;text&#x22;: &#x22;false&#x22;
        }
      ],
      &#x22;type&#x22;: &#x22;boolean | undefined&#x22;,
      &#x22;simplifiedType&#x22;: &#x22;union&#x22;,
      &#x22;required&#x22;: false,
      &#x22;deprecated&#x22;: false
    },
    {
      &#x22;name&#x22;: &#x22;textAlign&#x22;,
      &#x22;description&#x22;: &#x22;Sets text alignment.&#x22;,
      &#x22;tags&#x22;: [
        {
          &#x22;name&#x22;: &#x22;default&#x22;,
          &#x22;text&#x22;: &#x22;'start'&#x22;
        }
      ],
      &#x22;type&#x22;: &#x22;\&#x22;center\&#x22; | \&#x22;end\&#x22; | \&#x22;start\&#x22; | undefined&#x22;,
      &#x22;simplifiedType&#x22;: &#x22;union&#x22;,
      &#x22;required&#x22;: false,
      &#x22;deprecated&#x22;: false
    },
    {
      &#x22;name&#x22;: &#x22;textDecoration&#x22;,
      &#x22;description&#x22;: &#x22;Sets text decoration.&#x22;,
      &#x22;tags&#x22;: [
        {
          &#x22;name&#x22;: &#x22;default&#x22;,
          &#x22;text&#x22;: &#x22;'none'&#x22;
        }
      ],
      &#x22;type&#x22;: &#x22;\&#x22;none\&#x22; | \&#x22;inherit\&#x22; | \&#x22;line-through\&#x22; | \&#x22;underline\&#x22; | undefined&#x22;,
      &#x22;simplifiedType&#x22;: &#x22;union&#x22;,
      &#x22;required&#x22;: false,
      &#x22;deprecated&#x22;: false
    },
    {
      &#x22;name&#x22;: &#x22;textTransform&#x22;,
      &#x22;description&#x22;: &#x22;Sets text transform.&#x22;,
      &#x22;tags&#x22;: [
        {
          &#x22;name&#x22;: &#x22;default&#x22;,
          &#x22;text&#x22;: &#x22;'none'&#x22;
        }
      ],
      &#x22;type&#x22;: &#x22;\&#x22;none\&#x22; | \&#x22;inherit\&#x22; | \&#x22;default\&#x22; | \&#x22;capitalize\&#x22; | \&#x22;lowercase\&#x22; | \&#x22;uppercase\&#x22; | undefined&#x22;,
      &#x22;simplifiedType&#x22;: &#x22;union&#x22;,
      &#x22;required&#x22;: false,
      &#x22;deprecated&#x22;: false
    },
    {
      &#x22;name&#x22;: &#x22;textWrap&#x22;,
      &#x22;description&#x22;: &#x22;Sets text wrapping behavior.&#x22;,
      &#x22;tags&#x22;: [
        {
          &#x22;name&#x22;: &#x22;default&#x22;,
          &#x22;text&#x22;: &#x22;'default'&#x22;
        }
      ],
      &#x22;type&#x22;: &#x22;\&#x22;balance\&#x22; | \&#x22;default\&#x22; | \&#x22;pretty\&#x22; | undefined&#x22;,
      &#x22;simplifiedType&#x22;: &#x22;union&#x22;,
      &#x22;required&#x22;: false,
      &#x22;deprecated&#x22;: false
    },
    {
      &#x22;name&#x22;: &#x22;typography&#x22;,
      &#x22;description&#x22;: &#x22;Applies a complete typography style: family, size, weight, line height, letter spacing, and\ntrim.&#x22;,
      &#x22;tags&#x22;: [
        {
          &#x22;name&#x22;: &#x22;default&#x22;,
          &#x22;text&#x22;: &#x22;'body'&#x22;
        }
      ],
      &#x22;type&#x22;: &#x22;\&#x22;body\&#x22; | \&#x22;caption\&#x22; | \&#x22;label\&#x22; | \&#x22;lead\&#x22; | \&#x22;heading4\&#x22; | \&#x22;heading3\&#x22; | \&#x22;heading2\&#x22; | \&#x22;heading1\&#x22; | \&#x22;display\&#x22; | undefined&#x22;,
      &#x22;simplifiedType&#x22;: &#x22;union&#x22;,
      &#x22;required&#x22;: false,
      &#x22;deprecated&#x22;: false
    },
    {
      &#x22;name&#x22;: &#x22;elementType&#x22;,
      &#x22;description&#x22;: &#x22;Renders a different element type in place of the default. Use it to choose a semantic element\nwithout changing the visual or accessibility treatment.&#x22;,
      &#x22;tags&#x22;: [],
      &#x22;type&#x22;: &#x22;string | undefined&#x22;,
      &#x22;simplifiedType&#x22;: &#x22;string&#x22;,
      &#x22;required&#x22;: false,
      &#x22;deprecated&#x22;: false
    },
    {
      &#x22;deprecated&#x22;: false,
      &#x22;description&#x22;: &#x22;`TextProps` also accepts compatible DOM and ARIA attributes and event handlers for its rendered element.&#x22;,
      &#x22;name&#x22;: &#x22;__nativePropsForwarding&#x22;,
      &#x22;required&#x22;: true,
      &#x22;simplifiedType&#x22;: &#x22;&#x22;,
      &#x22;tags&#x22;: [],
      &#x22;type&#x22;: &#x22;&#x22;
    }
  ]
}"
/>
