# Native Components

Resolve compiled styles for third-party components, class components, and code outside JSX.

## Overview

Inside function components and custom hooks, Metro resolves applied styles automatically. `View`, `Text`, `Image`, `Pressable`, and `TextInput` from `react-native` bind natively. Other components resolve `style` and every prop ending in `Style`, such as `contentContainerStyle`.

Rendering a core component with compiled styles outside a function component or hook fails compilation with a code frame. Class render methods, module-scope JSX, and code outside JSX resolve styles through `withStyles` or `useStyles`.

```tsx title="Notice.tsx"
import { Text, View } from 'react-native'
import { style } from 'zyzz'

// A function component, so Metro binds the styles automatically
export function Notice() {
  return (
    <View {...styles.notice()}>
      <Text {...styles.message()}>Changes saved</Text>
    </View>
  )
}

namespace styles {
  export const notice = style({ backgroundColor: '#ecfdf5', padding: '12px' })

  export const message = style({ color: '#065f46', fontSize: '14px' })
}
```

## Third-Party Components

Inside a function component, Metro resolves `style` and every prop whose name ends in `Style` on any component, such as `contentContainerStyle` on `ScrollView` or `columnWrapperStyle` on `FlatList`. Other props, such as `tintColor`, pass through unchanged.

```tsx title="Feed.tsx"
import { ScrollView, Text } from 'react-native'
import { style } from 'zyzz'

export function Feed() {
  return (
    // contentContainerStyle resolves like style, without a wrapper
    <ScrollView contentContainerStyle={styles.content().style}>
      <Text>First post</Text>
    </ScrollView>
  )
}

namespace styles {
  export const content = style({ gap: '12px', padding: '16px' })
}
```

## Class Components

`withStyles` wraps a component so its `style` and `contentContainerStyle` props resolve compiled styles in class render methods, module-scope JSX, and `React.createElement` calls. Define the wrapper at module scope. It forwards other props and refs, and accepts class components.

```tsx title="Feed.tsx"
import { Component } from 'react'
import { ScrollView, Text } from 'react-native'
import { style } from 'zyzz'
import { withStyles } from 'zyzz/react-native'

// Resolves style and contentContainerStyle for the nearest Provider
const Scroll = withStyles(ScrollView)

export class Feed extends Component {
  render() {
    return (
      <Scroll contentContainerStyle={styles.content().style}>
        <Text>First post</Text>
      </Scroll>
    )
  }
}

namespace styles {
  export const content = style({ gap: '12px', padding: '16px' })
}
```

## Custom Style Props

`styleProps` names other props that the wrapper resolves, such as a component's `headerStyle`. The names must belong to the component, and `key` and `ref` are rejected.

```tsx title="Sheet.tsx"
import { Component, type ReactNode } from 'react'
import { Text, View, type StyleProp, type ViewStyle } from 'react-native'
import { style } from 'zyzz'
import { withStyles } from 'zyzz/react-native'

function Panel(props: Panel.Props) {
  return (
    <View style={props.style}>
      <View style={props.headerStyle}>{props.header}</View>
      {props.children}
    </View>
  )
}

declare namespace Panel {
  type Props = {
    children: ReactNode
    header: ReactNode
    headerStyle?: StyleProp<ViewStyle>
    style?: StyleProp<ViewStyle>
  }
}

// headerStyle resolves alongside the default style props
const StyledPanel = withStyles(Panel, { styleProps: ['headerStyle'] })

export class Sheet extends Component {
  render() {
    return (
      <StyledPanel
        header={<Text>Settings</Text>}
        headerStyle={styles.header().style}
        style={styles.panel().style}
      >
        <Text>Notifications</Text>
      </StyledPanel>
    )
  }
}

namespace styles {
  export const header = style({ paddingBottom: '8px' })

  export const panel = style({ padding: '16px' })
}
```

## Explicit Resolution

`useStyles` resolves applied styles inside a function component, for `React.createElement` calls and code that inspects style values before rendering. `current.style(value)` returns only the native style value.

```tsx title="Label.tsx"
import { createElement } from 'react'
import { Text } from 'react-native'
import { style } from 'zyzz'
import { useStyles } from 'zyzz/react-native'

export function Label() {
  // Resolve the applied props before passing them to createElement
  const current = useStyles()

  return createElement(Text, current.props(styles.label()), 'Resolved style')
}

namespace styles {
  export const label = style({ color: '#111111', fontSize: '16px' })
}
```

## Manual Tables

A custom host without the React adapter can compile definitions to native tables and select one explicitly. Selection returns an existing table without compiling or cloning styles.

```ts title="native-styles.ts"
import { defineVars, Style } from 'zyzz'
import { StyleSheet } from 'zyzz/react-native'

const theme = defineVars({
  color: { ink: { dark: '#eeeeee', light: '#111111' } },
})
const definitions = Style.define({
  label: { color: theme.color.ink, fontSize: '16px' },
})

// 1. Compile every alternative ahead of time
const output = StyleSheet.compile({
  styles: definitions,
  vars: { base: theme },
})

// 2. Select the table for the host's current scheme
const selected = StyleSheet.select(output.styles, {
  colorScheme: 'dark',
  set: 'base',
})
```

Pass `selected.label` to a component's `style` prop. The host owns device preferences and updates, and manual compilation does not support media queries.

## More

[Styling](/docs/guides/native/styling)

Combine styles, branch by platform, and bind values that change at runtime.

[Animations](/docs/guides/native/animations)

Mix compiled styles with Reanimated styles on animated components.

[React Adapter](/docs/api/react-native#hooks)

Review `withStyles`, `useStyles`, and automatic selection boundaries.

[StyleSheet Reference](/docs/api/react-native/namespaces/StyleSheet)

Review manual compilation, selection, and host updates.
