Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 0 additions & 5 deletions .changeset/fresh-ways-deliver.md

This file was deleted.

118 changes: 118 additions & 0 deletions packages/controls-plugin/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
![rozenite-banner](https://www.rozenite.dev/rozenite-banner.jpg)

### A Rozenite plugin for exposing app-defined controls directly in React Native DevTools.

The Controls Plugin lets you create a custom control panel for your app inside Rozenite. You define sections and items on the device, then use DevTools to read runtime values, flip toggles, switch options, submit text input, and trigger actions without building extra debug screens.

![Controls Plugin](https://rozenite.dev/controls-plugin.png)

## Installation

```bash
npm install @rozenite/controls-plugin
```

## Usage

```ts
import { createSection, useRozeniteControlsPlugin } from '@rozenite/controls-plugin';
import { useMemo, useState } from 'react';

function App() {
const [verboseLogging, setVerboseLogging] = useState(false);
const [environment, setEnvironment] = useState('local');
const [releaseLabel, setReleaseLabel] = useState('build-001');

const sections = useMemo(
() => [
createSection({
id: 'runtime-status',
title: 'Runtime Status',
items: [
{
id: 'current-environment',
type: 'text',
title: 'Environment',
value: environment,
},
{
id: 'verbose-logging',
type: 'toggle',
title: 'Verbose Logging',
value: verboseLogging,
onUpdate: setVerboseLogging,
},
{
id: 'environment-selector',
type: 'select',
title: 'Environment',
value: environment,
options: [
{ label: 'Local', value: 'local' },
{ label: 'Staging', value: 'staging' },
{ label: 'Production', value: 'production' },
],
onUpdate: setEnvironment,
},
{
id: 'release-label',
type: 'input',
title: 'Release Label',
value: releaseLabel,
placeholder: 'build-001',
applyLabel: 'Apply',
onUpdate: setReleaseLabel,
},
{
id: 'reset-session',
type: 'button',
title: 'Reset Session',
actionLabel: 'Reset',
onPress: () => {
setVerboseLogging(false);
setEnvironment('local');
setReleaseLabel('build-001');
},
},
],
}),
],
[environment, releaseLabel, verboseLogging]
);

useRozeniteControlsPlugin({ sections });

return <YourApp />;
}
```

## Supported Controls

- `text`: Show read-only runtime values such as current environment, build label, or connection status.
- `toggle`: Enable or disable boolean flags from DevTools.
- `select`: Switch between predefined options such as backend targets or feature variants.
- `input`: Edit text values and apply them from DevTools.
- `button`: Trigger one-off actions such as reset, sync, refetch, or clear cache.

## Organizing the Panel

Group related controls into sections so the panel stays readable as your app grows:

- Use one section for read-only diagnostics and another for mutable settings.
- Keep labels short and descriptive so they scan well in DevTools.
- Add `description` when a control changes app behavior in a non-obvious way.
- Use stable `id` values so controls remain predictable across reloads.

## Validation and Disabled States

Controls can guide users toward safe actions:

- Use `validate` to block invalid values and show a clear error message in DevTools.
- Use `disabled` when a control should be visible but unavailable in the current state.
- For text input, `applyLabel` can make the action clearer than a generic submit button.

## Notes

- The panel appears in React Native DevTools as `Controls`.
- Updates flow both ways: local state changes are reflected in DevTools, and DevTools actions update the device.
- The hook is disabled in production builds.
4 changes: 2 additions & 2 deletions packages/controls-plugin/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@rozenite/controls-plugin",
"version": "0.0.0",
"description": "Device-owned controls for Rozenite.",
"version": "1.4.0",
"description": "A Rozenite plugin for exposing app-defined controls directly in React Native DevTools.",
"type": "module",
"main": "./dist/react-native.cjs",
"module": "./dist/react-native.js",
Expand Down
5 changes: 5 additions & 0 deletions website/src/docs/official-plugins/_meta.json
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,11 @@
"name": "storage",
"label": "Storage"
},
{
"type": "file",
"name": "controls",
"label": "Controls"
},
{
"type": "file",
"name": "require-profiler",
Expand Down
160 changes: 160 additions & 0 deletions website/src/docs/official-plugins/controls.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
import { PackageManagerTabs } from '@rspress/core/theme';

# Controls Plugin

![](/controls-plugin.png)

The Controls plugin lets you expose app-defined runtime controls inside React Native DevTools. Instead of adding temporary debug screens or hidden menus, you can give your team a dedicated panel for toggles, pickers, inputs, actions, and read-only status values.

## What is Controls Plugin?

The Controls plugin is a lightweight way to build a custom DevTools surface for your app. It provides:

- **Read-only Status Fields**: Show current runtime values such as environment, build label, counters, or sync state
- **Toggles**: Turn feature flags and boolean options on or off from DevTools
- **Select Menus**: Switch between predefined options such as local, staging, and production
- **Text Inputs**: Update text-based settings without changing in-app UI
- **Action Buttons**: Trigger one-off actions such as reset, sync, refetch, or checkpoint creation

## Installation

Make sure to go through the [Getting Started guide](/docs/getting-started) before installing the plugin.

Install the Controls plugin as a development dependency:

<PackageManagerTabs command="install -D @rozenite/controls-plugin" />

## Base Setup

```ts title="App.tsx"
import { createSection, useRozeniteControlsPlugin } from '@rozenite/controls-plugin';
import { useMemo, useState } from 'react';

function App() {
const [verboseLogging, setVerboseLogging] = useState(false);
const [environment, setEnvironment] = useState('local');
const [releaseLabel, setReleaseLabel] = useState('build-001');

const sections = useMemo(
() => [
createSection({
id: 'runtime-status',
title: 'Runtime Status',
items: [
{
id: 'environment-label',
type: 'text',
title: 'Environment',
value: environment,
},
{
id: 'verbose-logging',
type: 'toggle',
title: 'Verbose Logging',
value: verboseLogging,
onUpdate: setVerboseLogging,
},
{
id: 'environment-selector',
type: 'select',
title: 'Environment',
value: environment,
options: [
{ label: 'Local', value: 'local' },
{ label: 'Staging', value: 'staging' },
{ label: 'Production', value: 'production' },
],
onUpdate: setEnvironment,
},
{
id: 'release-label',
type: 'input',
title: 'Release Label',
value: releaseLabel,
placeholder: 'build-001',
applyLabel: 'Apply',
onUpdate: setReleaseLabel,
},
{
id: 'reset-session',
type: 'button',
title: 'Reset Session',
actionLabel: 'Reset',
onPress: () => {
setVerboseLogging(false);
setEnvironment('local');
setReleaseLabel('build-001');
},
},
],
}),
],
[environment, releaseLabel, verboseLogging]
);

useRozeniteControlsPlugin({ sections });

return <YourApp />;
}
```

## Usage

Once configured, the Controls plugin appears in your React Native DevTools sidebar as `Controls`.

Use it when you want to:

- flip feature flags without building dedicated debug UI
- change runtime targets such as environment or API variant
- submit text values like labels, tokens, or test identifiers
- trigger app actions directly from DevTools
- keep read-only status values visible while testing flows

## Control Types

### Text

Use `text` items for values you want to observe but not edit, such as status, counters, or last action timestamps.

### Toggle

Use `toggle` items for boolean settings such as feature flags, logging switches, and debug modes.

### Select

Use `select` items when the user must choose from a fixed list of options.

### Input

Use `input` items for text-based values. This is useful for release labels, test IDs, user identifiers, or other string settings you want to edit from DevTools.

### Button

Use `button` items for single actions. Good examples are reset, sync, refresh, retry, and seed actions.

## Organizing Sections

Sections help keep the panel understandable:

- Put diagnostics and editable controls in separate sections.
- Prefer short titles so the panel stays easy to scan.
- Add descriptions when a control has side effects or temporary constraints.
- Keep section and item IDs stable across reloads.

## Validation and Availability

You can shape the user experience without exposing implementation details in the panel:

- Use `validate` to reject invalid values with a clear message.
- Use `disabled` when a control should stay visible but unavailable.
- Use `applyLabel` on text inputs when a custom action label reads better than the default.

## Common Uses

- feature flag management during manual testing
- switching between local, staging, and production services
- resetting temporary app state
- triggering checkpoints for demos or QA flows
- exposing internal diagnostics without adding a screen to the app

**Next**: Explore other [Official Plugins](./overview.md) or learn how to build your own in the [Plugin Development guide](../plugin-development/plugin-development.md).
13 changes: 12 additions & 1 deletion website/src/docs/official-plugins/overview.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,15 @@ Inspect multiple storage backends from one panel using adapters for MMKV, AsyncS
- **Per-Storage Blacklist**: Hide sensitive or noisy keys per storage instance
- **Async + Sync Coverage**: Works with both sync (MMKV) and async (AsyncStorage/SecureStore) APIs

### [Controls](./controls.md)

Expose app-defined controls directly in React Native DevTools so your team can inspect state, change flags, update text values, choose predefined options, and trigger actions from one panel. This plugin provides:

- **Custom Runtime Panels**: Organize controls into sections that match your app workflows
- **Read + Write Controls**: Combine status fields, toggles, selects, inputs, and buttons
- **Validation Feedback**: Prevent invalid changes and show clear errors in DevTools
- **No Extra Debug Screens**: Keep temporary controls out of your in-app UI

## Installing Plugins

Plugins should be installed as development dependencies since they are only needed during development:
Expand All @@ -96,6 +105,8 @@ Plugins should be installed as development dependencies since they are only need

<PackageManagerTabs command="install -D @rozenite/storage-plugin" />

<PackageManagerTabs command="install -D @rozenite/controls-plugin" />

See the individual plugin documentation for complete installation instructions including hook setup.

## Configuration
Expand All @@ -112,4 +123,4 @@ Want to contribute to plugins or suggest new ones? Check out our [Plugin Develop

---

**Next**: Learn about the [Expo Atlas plugin](./expo-atlas.md), [TanStack Query plugin](./tanstack-query.md), [Network Activity Inspector](./network-activity.md), [Redux DevTools plugin](./redux-devtools.md), [Performance Monitor plugin](./performance-monitor.md), [MMKV plugin](./mmkv.md), or [Storage plugin](./storage.md).
**Next**: Learn about the [Expo Atlas plugin](./expo-atlas.md), [TanStack Query plugin](./tanstack-query.md), [Network Activity Inspector](./network-activity.md), [Redux DevTools plugin](./redux-devtools.md), [Performance Monitor plugin](./performance-monitor.md), [MMKV plugin](./mmkv.md), [Storage plugin](./storage.md), or [Controls plugin](./controls.md).
Binary file added website/src/public/controls-plugin.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading