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

# Scoped Themes

> Apply a different theme to a subtree with `ScopedTheme`

<Badge>Available in Uniwind 1.4.0+</Badge>

## Overview

`ScopedTheme` lets you apply a theme to a specific subtree without changing the global app theme. This is useful for previews, isolated surfaces (cards, modals, panels), and mixed-theme layouts where multiple themes need to exist on screen at the same time.

The nearest `ScopedTheme` wins, so nested scopes work naturally.

<Info>
  `ScopedTheme` is a runtime theme boundary. Components, hooks, and `withUniwind` wrapped components inside the boundary resolve styles against the scoped theme.
</Info>

## Usage

### Basic Example

```tsx theme={null}
import { ScopedTheme } from 'uniwind'
import { Text, View } from 'react-native'

export function Example() {
  return (
    <View className="gap-4">
      <View className="p-4 rounded-xl bg-base">
        <Text className="text-default">Uses the current app theme</Text>
      </View>
      <ScopedTheme theme="dark">
        <View className="p-4 rounded-xl bg-base">
          <Text className="text-default">This subtree uses the dark theme</Text>
          <View className="mt-2 size-8 rounded bg-primary" />
        </View>
      </ScopedTheme>
    </View>
  )
}
```

## Common Patterns

### Side-by-Side Theme Previews

```tsx theme={null}
import { ScopedTheme } from 'uniwind'
import { Text, View } from 'react-native'

export function ThemePreviewRow() {
  return (
    <View className="flex-row gap-3">
      <ScopedTheme theme="light">
        <View className="flex-1 p-4 bg-base rounded-2xl gap-2">
          <Text className="text-default font-bold">Light</Text>
          <View className="size-8 rounded-lg bg-primary" />
          <Text className="text-default/60 text-xs">Scoped to light</Text>
        </View>
      </ScopedTheme>

      <ScopedTheme theme="dark">
        <View className="flex-1 p-4 bg-base rounded-2xl gap-2">
          <Text className="text-default font-bold">Dark</Text>
          <View className="size-8 rounded-lg bg-primary" />
          <Text className="text-default/60 text-xs">Scoped to dark</Text>
        </View>
      </ScopedTheme>

      <ScopedTheme theme="coffee">
        <View className="flex-1 p-4 bg-base rounded-2xl gap-2">
          <Text className="text-default font-bold">Coffee</Text>
          <View className="size-8 rounded-lg bg-primary" />
          <Text className="text-default/60 text-xs">Scoped to coffee (custom theme)</Text>
        </View>
      </ScopedTheme>
    </View>
  )
}
```

### Nested Scoped Themes

```tsx theme={null}
import { ScopedTheme } from 'uniwind'
import { Text, View } from 'react-native'

export function NestedScopes() {
  return (
    <ScopedTheme theme="coffee">
      <View className="w-full p-4 bg-base rounded-2xl gap-3">
        <Text className="text-default font-bold">Coffee (outer custom theme)</Text>

        <ScopedTheme theme="dark">
          <View className="w-full p-4 bg-base rounded-xl gap-3">
            <Text className="text-default font-bold">Dark (middle)</Text>

            <ScopedTheme theme="light">
              <View className="w-full p-3 bg-base rounded-lg gap-2">
                <Text className="text-default font-bold">Light (inner)</Text>
                <View className="size-6 rounded bg-primary" />
              </View>
            </ScopedTheme>
          </View>
        </ScopedTheme>
      </View>
    </ScopedTheme>
  )
}
```

<Tip>
  Nested scopes are great for documentation previews and component galleries where you want to compare variants without changing global theme state.
</Tip>

## Hooks and `withUniwind` in a Scoped Theme

Hooks and HOCs resolve against the closest `ScopedTheme` boundary.

* `useUniwind()` returns the scoped theme name
* `useResolveClassNames()` resolves class names using scoped theme variables
* `useCSSVariable()` reads CSS variables from the scoped theme
* `withUniwind()` mappings use values resolved from the scoped theme

### Example

```tsx theme={null}
import { Feather } from '@expo/vector-icons'
import { Pressable, Text, View } from 'react-native'
import {
  ScopedTheme,
  useCSSVariable,
  useResolveClassNames,
  useUniwind,
  withUniwind,
} from 'uniwind'

const StyledFeather = withUniwind(Feather, {
  size: {
    fromClassName: 'className',
    styleProperty: 'width',
  },
  color: {
    fromClassName: 'className',
    styleProperty: 'color',
  },
})

function UseUniwindExample() {
  const { theme } = useUniwind()

  return (
    <View className="w-full p-4 bg-base rounded-2xl gap-1">
      <Text className="text-default font-bold">useUniwind</Text>
      <Text className="text-primary">Current theme: {theme}</Text>
    </View>
  )
}

function UseResolveClassNamesExample() {
  const styles = useResolveClassNames('text-primary')

  return (
    <View className="w-full p-4 bg-base rounded-2xl gap-1">
      <Text className="text-default font-bold">useResolveClassNames</Text>
      <Text style={styles}>Resolved from 'text-primary'</Text>
    </View>
  )
}

function UseCSSVariableExample() {
  const primaryColor = useCSSVariable('--color-primary')

  return (
    <View className="w-full p-4 bg-base rounded-2xl gap-1">
      <Text className="text-default font-bold">useCSSVariable</Text>
      <Text className="text-primary">--color-primary: {String(primaryColor)}</Text>
    </View>
  )
}

function WithUniwindExample() {
  return (
    <View className="w-full p-4 bg-base rounded-2xl gap-2">
      <Text className="text-default font-bold">withUniwind</Text>
      <View className="flex-row gap-3 items-center">
        <StyledFeather name="star" className="size-6 text-primary" />
        <StyledFeather name="heart" className="size-6 text-primary" />
        <StyledFeather name="zap" className="size-6 text-primary" />
        <Text className="text-primary">Icons via withUniwind</Text>
      </View>
    </View>
  )
}

function ThemedButton({ title }: { title: string }) {
  return (
    <Pressable className="px-6 py-3 bg-primary rounded-xl active:scale-[0.97] active:opacity-80">
      <Text className="text-white font-semibold text-center">{title}</Text>
    </Pressable>
  )
}

export function ScopedThemeHooksExample() {
  return (
    <View className="w-full gap-3">
      <ScopedTheme theme="coffee">
        <View className="w-full gap-3">
          <ThemedButton title="Coffee Button" />
          <UseUniwindExample />
          <UseResolveClassNamesExample />
          <UseCSSVariableExample />
          <WithUniwindExample />
        </View>
      </ScopedTheme>

      <View className="w-full gap-3">
        <ThemedButton title="Current Theme Button" />
        <UseUniwindExample />
        <UseResolveClassNamesExample />
        <UseCSSVariableExample />
        <WithUniwindExample />
      </View>
    </View>
  )
}
```

## API Reference

### Component Signature

```tsx theme={null}
import { ScopedTheme } from 'uniwind'

<ScopedTheme theme="dark">
  {/* themed subtree */}
</ScopedTheme>
```

### Props

<ParamField path="theme" type="string" required>
  Theme name to apply to this subtree. The theme must exist in your configured Uniwind theme definitions (for example, `light`, `dark`, or a custom theme like `coffee`).
</ParamField>

<ParamField path="children" type="React.ReactNode" required>
  React children rendered inside the scoped theme boundary.
</ParamField>

## Behavior Notes

* `ScopedTheme` affects only its descendants
* It does not change the global app theme
* Nested scopes override parent scopes for their own subtree
* Multiple scopes can render side by side on the same screen

## Related

<CardGroup cols={2}>
  <Card title="Theming Basics" icon="palette" href="/theming/basics">
    Learn how to set up themes in Uniwind
  </Card>

  <Card title="Custom Themes" icon="swatchbook" href="/theming/custom-themes">
    Define custom themes like `coffee`
  </Card>
</CardGroup>

<CardGroup cols={2}>
  <Card title="useUniwind" icon="code" href="/api/use-uniwind">
    Read the current theme and adaptive theme state
  </Card>

  <Card title="useCSSVariable" icon="code" href="/api/use-css-variable">
    Read theme variables directly in JavaScript
  </Card>
</CardGroup>

<CardGroup cols={2}>
  <Card title="useResolveClassNames" icon="code" href="/api/use-resolve-class-names">
    Resolve class names into style objects at runtime
  </Card>

  <Card title="withUniwind" icon="layer-group" href="/api/with-uniwind">
    Add className support to third-party components
  </Card>
</CardGroup>
