Skip to main content

Typography

Typography renders text using the Material Design 3 type scale.

Usage​

import { Typography } from '@rootnative/components'
import { mdiResolver } from '@rootnative/components/mdi'
import { ThemeProvider } from '@rootnative/core'
import { SafeAreaProvider } from 'react-native-safe-area-context'
import { View } from 'react-native'

export default function App() {
return (
<SafeAreaProvider>
<ThemeProvider iconResolver={mdiResolver}>
<View style={{ flex: 1, justifyContent: 'center', padding: 16, gap: 8 }}>
<Typography variant="headlineMedium">Hello World</Typography>
<Typography variant="bodyLarge">Body text content.</Typography>
</View>
</ThemeProvider>
</SafeAreaProvider>
)
}

Variants​

The full MD3 type scale:

CategoryVariants
DisplaydisplayLarge, displayMedium, displaySmall
HeadlineheadlineLarge, headlineMedium, headlineSmall
TitletitleLarge, titleMedium, titleSmall
BodybodyLarge, bodyMedium, bodySmall
LabellabelLarge, labelMedium, labelSmall

Each of the 15 roles also has an MD3 Expressive <name>Emphasized counterpart — same size and line height, weight one step heavier — so variant accepts 30 values in total:

CategoryEmphasized variants
DisplaydisplayLargeEmphasized, displayMediumEmphasized, displaySmallEmphasized
HeadlineheadlineLargeEmphasized, headlineMediumEmphasized, headlineSmallEmphasized
TitletitleLargeEmphasized, titleMediumEmphasized, titleSmallEmphasized
BodybodyLargeEmphasized, bodyMediumEmphasized, bodySmallEmphasized
LabellabelLargeEmphasized, labelMediumEmphasized, labelSmallEmphasized
<Typography variant="titleMediumEmphasized">Emphasized title</Typography>

Use an emphasized variant instead of a base variant plus a fontWeight override. The emphasized tokens also adjust tracking, which a weight override does not.

Accessibility​

Pass level (1 to 6) on a heading. It sets the header role and aria-level, so the web renders <h1> to <h6> and a crawler reads the outline. A display or headline variant with no level, plain or Emphasized, announces a header on native only: on the web a level-less header is always <h1>, so it renders a plain element there. An explicit accessibilityRole always wins.

<Typography variant="headlineSmall" level={1}>Dune</Typography>
<Typography variant="titleMedium" level={2}>Cast</Typography>
<Typography variant="displaySmall">Aa</Typography>

The AppBar title is a level={1} heading by default; pass titleLevel={2} to the bar when a heading above it is the page heading.

Custom Styles​

import { Typography } from '@rootnative/components'
import { mdiResolver } from '@rootnative/components/mdi'
import { ThemeProvider } from '@rootnative/core'
import { SafeAreaProvider } from 'react-native-safe-area-context'
import { View } from 'react-native'

export default function App() {
return (
<SafeAreaProvider>
<ThemeProvider iconResolver={mdiResolver}>
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Typography variant="bodyMedium" style={{ color: 'red' }}>
Custom colored text
</Typography>
</View>
</ThemeProvider>
</SafeAreaProvider>
)
}

Custom Text Component​

Use the as prop to render with a custom text component:

import { Typography } from '@rootnative/components'
import { mdiResolver } from '@rootnative/components/mdi'
import { ThemeProvider } from '@rootnative/core'
import { SafeAreaProvider } from 'react-native-safe-area-context'
import { Animated } from '@rootnative/inertia/reanimated'
import { View } from 'react-native'

export default function App() {
return (
<SafeAreaProvider>
<ThemeProvider iconResolver={mdiResolver}>
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Typography variant="titleLarge" as={Animated.Text}>
Animated text
</Typography>
</View>
</ThemeProvider>
</SafeAreaProvider>
)
}

Props​

This component has no custom props.