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:
| Category | Variants |
|---|---|
| Display | displayLarge, displayMedium, displaySmall |
| Headline | headlineLarge, headlineMedium, headlineSmall |
| Title | titleLarge, titleMedium, titleSmall |
| Body | bodyLarge, bodyMedium, bodySmall |
| Label | labelLarge, 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:
| Category | Emphasized variants |
|---|---|
| Display | displayLargeEmphasized, displayMediumEmphasized, displaySmallEmphasized |
| Headline | headlineLargeEmphasized, headlineMediumEmphasized, headlineSmallEmphasized |
| Title | titleLargeEmphasized, titleMediumEmphasized, titleSmallEmphasized |
| Body | bodyLargeEmphasized, bodyMediumEmphasized, bodySmallEmphasized |
| Label | labelLargeEmphasized, 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.