Token system
native-mate uses a semantic token system. Instead of hardcoded colours, you reference tokens like theme.colors.primary — and the correct light/dark value is resolved automatically.
Token shape
Every resolved theme has this structure:
ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
interface ResolvedTheme {
colors: {
background: string // page/screen background
surface: string // card, input, overlay bg
border: string // dividers, outlines
foreground: string // primary text
mutedForeground: string // secondary text, placeholders
primary: string // brand/action colour
primaryForeground: string
destructive: string
destructiveForeground: string
success: string
successForeground: string
warning: string
warningForeground: string
overlay: string // modal scrim
input: string
ring: string // focus ring
// + more
}
spacing: { xs: 4, sm: 8, md: 12, lg: 16, xl: 24, '2xl': 32, '3xl': 48 }
radius: { sm: 6, md: 10, lg: 16, xl: 24, full: 9999 }
typography: {
size: { xs: 11, sm: 13, md: 15, lg: 17, xl: 20, '2xl': 24, '3xl': 30 }
weight: { regular: '400', medium: '500', semibold: '600', bold: '700' }
lineHeight: { tight: 18, normal: 22, relaxed: 28 } // absolute px
}
animation: {
speed: { fast: 150, normal: 250, slow: 400 } // ms
easing: { standard, decelerate, spring }
}
}useTheme()
Access the current resolved theme directly inside any component wrapped in ThemeProvider.
tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import { useTheme } from '@native-mate/core'
import { StyleSheet, View } from 'react-native'
function MyComponent() {
const theme = useTheme()
return (
<View
style={{
backgroundColor: theme.colors.surface,
borderRadius: theme.radius.md,
padding: theme.spacing.lg,
}}
/>
)
}makeStyles()
The preferred way to define styles. Call it at module level — it returns a hook that calls StyleSheet.create() once per theme change.
tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import { makeStyles } from '@native-mate/core'
// Called at module level — returns a hook
const useStyles = makeStyles((theme) => ({
container: {
backgroundColor: theme.colors.background,
padding: theme.spacing.lg,
},
title: {
fontSize: theme.typography.size.lg,
fontWeight: theme.typography.weight.bold,
color: theme.colors.foreground,
},
}))
function MyComponent() {
const styles = useStyles() // memoised per theme change
return <View style={styles.container} />
}Note on lineHeight: Values are absolute pixels (not CSS multipliers).
tight: 18, normal: 22, relaxed: 28. React Native requires absolute line heights.