Skip to main content

Typography

Typography renders text with the type scale of the theme, semantic colors and automatic light and dark mode. Use it instead of a bare React Native Text so every piece of text follows the theme. Copy it as described in the introduction, together with core.

Basic​

Without props, the text uses the body1 variant and the primary text color.

import { StyleSheet, View } from 'react-native';
import { Typography } from 'tessera';

export function BasicExample() {
return (
<View style={styles.container}>
<Typography variant="h4">Heading</Typography>
<Typography>
Without a variant, Typography renders the body1 style of the theme.
</Typography>
</View>
);
}

const styles = StyleSheet.create({
container: {
gap: 8,
},
});

Heading

Without a variant, Typography renders the body1 style of the theme.

Heading

Without a variant, Typography renders the body1 style of the theme.

Variants​

variant picks a token from the type scale: h1 to h6, subtitle1, subtitle2, body1, body2, button, caption and overline.

import { StyleSheet, View } from 'react-native';
import { Typography } from 'tessera';
import type { TypographyVariant } from 'tessera';

const variants: TypographyVariant[] = [
'h1',
'h2',
'h3',
'h4',
'h5',
'h6',
'subtitle1',
'subtitle2',
'body1',
'body2',
'button',
'caption',
'overline',
];

export function VariantsExample() {
return (
<View style={styles.container}>
{variants.map(variant => (
<View key={variant} style={styles.row}>
<Typography variant="caption" color="secondary">
{variant}
</Typography>
<Typography variant={variant}>The quick brown fox</Typography>
</View>
))}
</View>
);
}

const styles = StyleSheet.create({
container: {
gap: 12,
},
row: {
gap: 4,
},
});
h1

The quick brown fox

h2

The quick brown fox

h3

The quick brown fox

h4

The quick brown fox

h5

The quick brown fox

h6

The quick brown fox

subtitle1
The quick brown fox
subtitle2
The quick brown fox
body1
The quick brown fox
body2
The quick brown fox
button
The quick brown fox
caption
The quick brown fox
overline
The quick brown fox
h1

The quick brown fox

h2

The quick brown fox

h3

The quick brown fox

h4

The quick brown fox

h5

The quick brown fox

h6

The quick brown fox

subtitle1
The quick brown fox
subtitle2
The quick brown fox
body1
The quick brown fox
body2
The quick brown fox
button
The quick brown fox
caption
The quick brown fox
overline
The quick brown fox

Tones​

color sets the text color from the palette. Each value resolves to the text variant of its color, the one that meets WCAG AA on the background.

import { StyleSheet, View } from 'react-native';
import { Typography } from 'tessera';
import type { TypographyColor } from 'tessera';

const tones: TypographyColor[] = [
'primary',
'secondary',
'success',
'info',
'warning',
'error',
'disabled',
];

export function TonesExample() {
return (
<View style={styles.container}>
{tones.map(tone => (
<Typography key={tone} color={tone}>
{tone}: sample text
</Typography>
))}
</View>
);
}

const styles = StyleSheet.create({
container: {
gap: 8,
},
});
primary: sample text
secondary: sample text
success: sample text
info: sample text
warning: sample text
error: sample text
disabled: sample text
primary: sample text
secondary: sample text
success: sample text
info: sample text
warning: sample text
error: sample text
disabled: sample text

Weight​

weight overrides the font weight of the variant. Size and line height do not change.

import { StyleSheet, View } from 'react-native';
import { Typography } from 'tessera';

export function WeightExample() {
return (
<View style={styles.container}>
<Typography variant="h4" weight="400">
Heading with regular weight
</Typography>
<Typography weight="700">Body text with bold weight</Typography>
<Typography variant="body2" weight="500">
Body 2 with medium weight
</Typography>
</View>
);
}

const styles = StyleSheet.create({
container: {
gap: 8,
},
});

Heading with regular weight

Body text with bold weight
Body 2 with medium weight

Heading with regular weight

Body text with bold weight
Body 2 with medium weight

Style override​

style is applied last, after the variant, weight, color and alignment. It accepts a React Native style or a function that receives the theme.

import { StyleSheet, View } from 'react-native';
import { Typography } from 'tessera';

export function StyleOverrideExample() {
return (
<View style={styles.container}>
<Typography style={styles.spaced}>
Object style adds letter spacing and a top margin.
</Typography>
<Typography
style={theme => ({
textDecorationLine: 'underline',
textDecorationColor: theme.palette.primary.textColor,
})}>
Function style reads the theme to underline with the primary color.
</Typography>
</View>
);
}

const styles = StyleSheet.create({
container: {
gap: 8,
},
spaced: {
letterSpacing: 2,
marginTop: 4,
},
});
Object style adds letter spacing and a top margin.
Function style reads the theme to underline with the primary color.
Object style adds letter spacing and a top margin.
Function style reads the theme to underline with the primary color.

Accessibility​

What the component sets:

  • h1 to h6 have accessibilityRole="header", so screen readers announce them as headings. Pass your own accessibilityRole to replace it.
  • maxFontSizeMultiplier defaults to 2, which limits how much the system font size scales the text.
  • The component is not interactive. It does not capture focus or announce anything by itself.

What you must provide:

  • Meaningful content. Avoid purely decorative text inside touchable rows.
  • A non-heading variant, such as body1, for text that repeats in lists.

Dependencies​

ImportReason
react-native (Text, types)Primitive that the component wraps
core (resolveTesseraStyle, useTheme, types)Theme tokens and the style escape hatch

Files​

Copy core/ once for the whole catalog, then this component's folder:

core/ # all files, copied once
components/typography/index.ts
components/typography/typography.tsx

Version and changes​

Changes to this component are listed in CHANGELOG.md. Each entry for this component starts with the typography scope.

Props​

PropTypeDefaultDescription
variantTypographyVariant'body1'Token from the type scale. h1 to h6 are announced as headings.
weightTypographyToken['fontWeight']—Overrides the font weight of the variant.
colorTypographyColortext.primaryprimary, secondary, success, info, warning, error, disabled. caption and overline use their own muted color when omitted.
alignTextStyle['textAlign']—left, center, right, justify.
styleTesseraStyleProp<TextStyle>—React Native style, or (theme) => style. Applied last.
maxFontSizeMultipliernumber2Upper limit for the system font scaling.

Any other Text prop, such as accessibilityLabel or numberOfLines, is passed to the underlying Text unchanged.