# @rulecms/widget-react-native

React Native SDK for [RuleCMS](https://rulecms.com) — the React Native counterpart of [`@rulecms/widget-react`](https://www.npmjs.com/package/@rulecms/widget-react) and [`rulecms_widget`](../widget-flutter).

Fetches a widget by **token + key** and renders the `itemList` layout tree through registered component libraries (default: [`@rulecms/source-components-react-native`](../source-components-react-native)).

## Install

```bash
npm install @rulecms/widget-react-native @rulecms/source-components-react-native
```

## Usage

```tsx
import { RuleCMSWidget, RuleCMSWidgetProvider } from '@rulecms/widget-react-native';
import { rulecmsSourceComponentsLibrary } from '@rulecms/source-components-react-native';

export function MyPage({ token, publishedKey }: { token: string; publishedKey: string }) {
  return (
    <RuleCMSWidgetProvider
      token={token}
      libraries={{ default: rulecmsSourceComponentsLibrary }}
    >
      <RuleCMSWidget publishedKey={publishedKey} />
    </RuleCMSWidgetProvider>
  );
}
```

- Staging/Production: plain token + `environmentId---widget-…` published key → widget-cache
- Development: `dev.…` token + draft `widget-…` key → rulecms.com live drafts

Same routing rules as `@rulecms/widget-react`.

## Host `componentProps`

Pass extra props — a click handler, a callback — to one component instance by its column id. A key may be a bare id (every copy of a repeated collection) or a `/`-path of enclosing collection columns ending at the target (one embedding). Longest match wins.

```tsx
<RuleCMSWidget
  publishedKey={publishedKey}
  componentProps={{
    'b721c4e2-…': { onClick: handleCta },
    'holder-a/inner-col': { onClick: openBookingDrawer },
  }}
/>
```

`r-button` reads `onClick` from the bag. The renderer never inspects the contents. In development, a key that addresses no column in the widget is printed once so typos are visible while building.

## Host `mounts`

Register a React Native component from your app so a Custom (`r-mount`) slot in the composer can render it by name. The name is a map key, not a string that becomes code. A miss is a placeholder.

```tsx
<RuleCMSWidget
  publishedKey={publishedKey}
  mounts={{ 'booking-form': BookingForm }}
/>
```

Tell the marketer the exact name and the props the component reads. Event handlers still go through `componentProps` at that column's id — authored prop rows cannot become `onClick`. See `__docs__/CONTRACT_mounts.md` and [Mount Your Own Components](https://rulecms.com/docs/widget-mounts).

## Develop locally

```bash
cd widget-react-native
npm install
npm test
npm run lint
npm run typecheck
npm run build
```

## Publishing

Follow `__docs__/RUNBOOK_version-bump-and-release.md`.

### Increment version

```bash
# Patch version (0.1.0 -> 0.1.1)
npm run version:patch

# Minor version (0.1.0 -> 0.2.0)
npm run version:minor

# Major version (0.1.0 -> 1.0.0)
npm run version:major
```

### Publish to npm

Push the version tag. GitHub Actions publishes via trusted publishing
(`.github/workflows/publish.yml`). Do not run `npm run release` or
`npm publish` locally except for the first-ever version of a new package
(npm cannot attach a trusted publisher until the package exists).

```bash
git push && git push --tags
npm view @rulecms/widget-react-native version
```

## License

Proprietary — RuleCMS, LLC
