> ## Documentation Index
> Fetch the complete documentation index at: https://docs.kansolabs.org/llms.txt
> Use this file to discover all available pages before exploring further.

# Theming

> ThemeScope, reading tokens with useTheme(), and the fonts a type role draws in.

`ThemeScope` themes everything inside it, and takes the same props as the web library's:

**theme** `KuiTheme`

A map of `--kui-*` properties to CSS values. A nested scope's map applies over its parent's.

**scheme** `'light' | 'dark'`

Pins the scope to light or dark and paints its surface. Left unset, the scheme follows the scope around it, or the device's appearance at the root.

```tsx theme={null}
import { type KuiTheme, ThemeScope } from '@kanso-labs/react-native-kanso-ui'

// The same object a web app hands kanso-ui's ThemeScope.
const brand: KuiTheme = {
  '--kui-color-primary': '#006a6a',
  '--kui-radius-md': '16px',
}

export default function App() {
  return (
    <ThemeScope style={{ flex: 1 }} theme={brand}>
      <Screen />
    </ThemeScope>
  )
}
```

To build a full theme from one colour, use the [Material Theme Builder](/kanso-ui/web/theming/material-theme-builder.md) recipe: its output is a `KuiTheme` both libraries take.

## Reading tokens

`useTheme()` reads the tokens in the values React Native styles take, under the keys of the web library's token modules:

| Web | React Native |
| - | - |
| `var(--kui-color-primary)` | `useTheme().colors.primary` |
| `12px` | `12` (dp) |
| `100ms` | `100` (ms) |
| `cubic-bezier(…)` | the four points `Easing.bezier()` takes |

```tsx theme={null}
import { useTheme } from '@kanso-labs/react-native-kanso-ui'
import { View } from 'react-native'

function Swatch() {
  const { colors } = useTheme()
  return <View style={{ backgroundColor: colors.primaryContainer, height: 48 }} />
}
```

> [!NOTE]
>
> A value React Native cannot evaluate, such as `calc()` or `color-mix()`, keeps its property at the library's default, and a development build names it in a warning.

What the library draws above the screen follows the scope it was opened in rather than the root's, so a sheet opened inside a branded scope keeps that brand.

## Fonts

Neither package ships a font. On iOS and Android a type role draws in the first family its token names when the app has registered that family with [expo-font](https://docs.expo.dev/versions/latest/sdk/font/) under that name, and in the system font otherwise.

```tsx theme={null}
import { useFonts } from 'expo-font'

const [loaded] = useFonts({
  'Roboto Flex': require('./assets/RobotoFlex.ttf'),
  'Roboto Serif': require('./assets/RobotoSerif.ttf'),
})
```

Under React Native Web the token's whole family list goes to CSS, as it does on the web.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.