@storybook/react-native 10.0.0-rc.1 → 10.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -60,9 +60,8 @@ interface WithStorybookOptions {
|
|
|
60
60
|
* @param options.useJs - Whether to use JavaScript files for Storybook configuration instead of TypeScript.
|
|
61
61
|
* When true, generates storybook.requires.js instead of storybook.requires.ts.
|
|
62
62
|
* Defaults to false.
|
|
63
|
-
* @param options.
|
|
64
|
-
*
|
|
65
|
-
* Defaults to false.
|
|
63
|
+
* @param options.enabled - If false, attempts to remove storybook modules from the JavaScript
|
|
64
|
+
* bundle to reduce bundle size. Defaults to true.
|
|
66
65
|
* @param options.docTools - Whether to include doc tools in the storybook.requires file.
|
|
67
66
|
* Doc tools provide additional documentation features. Defaults to true.
|
|
68
67
|
* @param options.liteMode - Whether to use lite mode for the storybook. In lite mode, the default
|
|
@@ -107,7 +106,7 @@ interface WithStorybookOptions {
|
|
|
107
106
|
*
|
|
108
107
|
* const config = getDefaultConfig(__dirname);
|
|
109
108
|
* module.exports = withStorybook(config, {
|
|
110
|
-
*
|
|
109
|
+
* enabled: process.env.EXPO_PUBLIC_STORYBOOK_ENABLED === "true",
|
|
111
110
|
* });
|
|
112
111
|
* ```
|
|
113
112
|
*/
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@storybook/react-native",
|
|
3
|
-
"version": "10.0.0
|
|
3
|
+
"version": "10.0.0",
|
|
4
4
|
"description": "A better way to develop React Native Components for your app",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"react",
|
|
@@ -49,10 +49,10 @@
|
|
|
49
49
|
},
|
|
50
50
|
"dependencies": {
|
|
51
51
|
"@storybook/global": "^5.0.0",
|
|
52
|
-
"@storybook/react": "10.0.0
|
|
53
|
-
"@storybook/react-native-theming": "^10.0.0
|
|
54
|
-
"@storybook/react-native-ui": "^10.0.0
|
|
55
|
-
"@storybook/react-native-ui-common": "^10.0.0
|
|
52
|
+
"@storybook/react": "^10.0.0",
|
|
53
|
+
"@storybook/react-native-theming": "^10.0.0",
|
|
54
|
+
"@storybook/react-native-ui": "^10.0.0",
|
|
55
|
+
"@storybook/react-native-ui-common": "^10.0.0",
|
|
56
56
|
"commander": "^8.2.0",
|
|
57
57
|
"dedent": "^1.5.1",
|
|
58
58
|
"deepmerge": "^4.3.0",
|
|
@@ -74,7 +74,7 @@
|
|
|
74
74
|
"jotai": "^2.6.2",
|
|
75
75
|
"react": "19.1.0",
|
|
76
76
|
"react-native": "0.81.4",
|
|
77
|
-
"storybook": "10.0.0
|
|
77
|
+
"storybook": "^10.0.0",
|
|
78
78
|
"tsup": "^8.5.0",
|
|
79
79
|
"typescript": "~5.9.2",
|
|
80
80
|
"universal-test-renderer": "^0.6.0"
|
|
@@ -86,7 +86,7 @@
|
|
|
86
86
|
"react-native-gesture-handler": ">=2",
|
|
87
87
|
"react-native-reanimated": ">=2",
|
|
88
88
|
"react-native-safe-area-context": "*",
|
|
89
|
-
"storybook": ">=10 ||
|
|
89
|
+
"storybook": ">=10 || ^10"
|
|
90
90
|
},
|
|
91
91
|
"peerDependenciesMeta": {
|
|
92
92
|
"@gorhom/bottom-sheet": {
|
|
@@ -108,5 +108,5 @@
|
|
|
108
108
|
"publishConfig": {
|
|
109
109
|
"access": "public"
|
|
110
110
|
},
|
|
111
|
-
"gitHead": "
|
|
111
|
+
"gitHead": "f2af5e230aac4cd858f2d73909868ae4952eb1c1"
|
|
112
112
|
}
|
package/readme.md
CHANGED
|
@@ -1,13 +1,17 @@
|
|
|
1
1
|
# Storybook for React Native
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
A new docs site is being built for Storybook for React Native, you can find it at https://storybookjs.github.io/react-native/docs/intro/.
|
|
4
|
+
|
|
5
|
+
> [!IMPORTANT]
|
|
6
|
+
> This readme is for v10, for v9 docs see the [v9.1 docs](https://github.com/storybookjs/react-native/tree/v9.1.4).
|
|
4
7
|
|
|
5
8
|
With Storybook for React Native you can design and develop individual React Native components without running your app.
|
|
6
9
|
|
|
7
|
-
If you are migrating from
|
|
10
|
+
If you are migrating from 9 to 10 you can find the migration guide [here](https://github.com/storybookjs/react-native/blob/next/MIGRATION.md#from-version-9-to-10)
|
|
8
11
|
|
|
9
12
|
For more information about storybook visit: [storybook.js.org](https://storybook.js.org)
|
|
10
13
|
|
|
14
|
+
> [!NOTE]
|
|
11
15
|
> Make sure you align your storybook dependencies to the same major version or you will see broken behaviour.
|
|
12
16
|
|
|
13
17
|

|
|
@@ -79,23 +83,23 @@ Then wrap your config in the withStorybook function as seen below.
|
|
|
79
83
|
|
|
80
84
|
```js
|
|
81
85
|
// metro.config.js
|
|
82
|
-
const path = require('path');
|
|
83
86
|
const { getDefaultConfig } = require('expo/metro-config');
|
|
84
|
-
const withStorybook = require('@storybook/react-native/metro/withStorybook');
|
|
87
|
+
const { withStorybook } = require('@storybook/react-native/metro/withStorybook');
|
|
85
88
|
|
|
86
|
-
/** @type {import('expo/metro-config').MetroConfig} */
|
|
87
89
|
const config = getDefaultConfig(__dirname);
|
|
88
90
|
|
|
91
|
+
// For basic usage with all defaults, this is all you need
|
|
92
|
+
module.exports = withStorybook(config);
|
|
93
|
+
|
|
94
|
+
// Or customize the options
|
|
89
95
|
module.exports = withStorybook(config, {
|
|
90
|
-
//
|
|
91
|
-
|
|
92
|
-
enabled: true,
|
|
93
|
-
// Path to your storybook config
|
|
94
|
-
configPath: path.resolve(__dirname, './.rnstorybook'),
|
|
95
|
-
// note that this is the default so you can the config path blank if you use .rnstorybook
|
|
96
|
+
// When false, removes Storybook from bundle (useful for production)
|
|
97
|
+
enabled: process.env.EXPO_PUBLIC_STORYBOOK_ENABLED === 'true',
|
|
96
98
|
|
|
97
|
-
//
|
|
98
|
-
|
|
99
|
+
// Path to your storybook config (default: './.rnstorybook')
|
|
100
|
+
configPath: './.rnstorybook',
|
|
101
|
+
|
|
102
|
+
// Optional websockets configuration for syncing between devices
|
|
99
103
|
// websockets: {
|
|
100
104
|
// port: 7007,
|
|
101
105
|
// host: 'localhost',
|
|
@@ -107,8 +111,8 @@ module.exports = withStorybook(config, {
|
|
|
107
111
|
|
|
108
112
|
```js
|
|
109
113
|
const { getDefaultConfig, mergeConfig } = require('@react-native/metro-config');
|
|
110
|
-
const
|
|
111
|
-
|
|
114
|
+
const { withStorybook } = require('@storybook/react-native/metro/withStorybook');
|
|
115
|
+
|
|
112
116
|
const defaultConfig = getDefaultConfig(__dirname);
|
|
113
117
|
|
|
114
118
|
/**
|
|
@@ -122,15 +126,19 @@ const config = {};
|
|
|
122
126
|
|
|
123
127
|
const finalConfig = mergeConfig(defaultConfig, config);
|
|
124
128
|
|
|
129
|
+
// For basic usage with all defaults
|
|
130
|
+
module.exports = withStorybook(finalConfig);
|
|
131
|
+
|
|
132
|
+
// Or customize the options
|
|
125
133
|
module.exports = withStorybook(finalConfig, {
|
|
126
|
-
//
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
// Path to your storybook config
|
|
134
|
+
// When false, removes Storybook from bundle (useful for production)
|
|
135
|
+
enabled: process.env.STORYBOOK_ENABLED === 'true',
|
|
136
|
+
|
|
137
|
+
// Path to your storybook config (default: './.rnstorybook')
|
|
130
138
|
configPath: path.resolve(__dirname, './.rnstorybook'),
|
|
131
139
|
// note that this is the default so you can the config path blank if you use .rnstorybook
|
|
132
140
|
|
|
133
|
-
// Optional websockets configuration
|
|
141
|
+
// Optional websockets configuration for syncing between devices
|
|
134
142
|
// Starts a websocket server on the specified port and host on metro start
|
|
135
143
|
// websockets: {
|
|
136
144
|
// port: 7007,
|
|
@@ -148,12 +156,45 @@ Make sure you have `react-native-reanimated` in your project and the plugin setu
|
|
|
148
156
|
plugins: ['react-native-reanimated/plugin'],
|
|
149
157
|
```
|
|
150
158
|
|
|
159
|
+
## Expo router specific setup
|
|
160
|
+
|
|
161
|
+
```bash
|
|
162
|
+
npm create storybook@latest
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
choose recommended and then native
|
|
166
|
+
|
|
167
|
+
```bash
|
|
168
|
+
npx expo@latest customize metro.config.js
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
copy the metro config
|
|
172
|
+
|
|
173
|
+
```js
|
|
174
|
+
const withStorybook = require('@storybook/react-native/metro/withStorybook');
|
|
175
|
+
module.exports = withStorybook(config);
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
add storybook screen to app
|
|
179
|
+
|
|
180
|
+
create `app/storybook.tsx`
|
|
181
|
+
|
|
182
|
+
```tsx
|
|
183
|
+
export { default } from '../.rnstorybook';
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
Then add a way to navigate to your storybook route and I recommend disabling the header for the storybook route.
|
|
187
|
+
|
|
188
|
+
Heres a video showing the same setup:
|
|
189
|
+
|
|
190
|
+
https://www.youtube.com/watch?v=egBqrYg0AIg
|
|
191
|
+
|
|
151
192
|
## Writing stories
|
|
152
193
|
|
|
153
194
|
In storybook we use a syntax called CSF that looks like this:
|
|
154
195
|
|
|
155
196
|
```tsx
|
|
156
|
-
import type { Meta, StoryObj } from '@storybook/react';
|
|
197
|
+
import type { Meta, StoryObj } from '@storybook/react-native';
|
|
157
198
|
import { MyButton } from './Button';
|
|
158
199
|
|
|
159
200
|
const meta = {
|
|
@@ -222,7 +263,7 @@ For global decorators and parameters, you can add them to `preview.tsx` inside y
|
|
|
222
263
|
|
|
223
264
|
```tsx
|
|
224
265
|
// .rnstorybook/preview.tsx
|
|
225
|
-
import type {
|
|
266
|
+
import type {
|
|
226
267
|
import { withBackgrounds } from '@storybook/addon-ondevice-backgrounds';
|
|
227
268
|
|
|
228
269
|
const preview: Preview = {
|
|
@@ -291,13 +332,52 @@ For details of each ondevice addon you can see the readme:
|
|
|
291
332
|
|
|
292
333
|
## Hide/Show storybook
|
|
293
334
|
|
|
294
|
-
|
|
335
|
+
In v10, you have flexible options for integrating Storybook into your app:
|
|
295
336
|
|
|
296
|
-
|
|
297
|
-
Some have opted to toggle the storybook component by using a custom option in the react native developer menu.
|
|
337
|
+
### Option 1: Direct export (simplest)
|
|
298
338
|
|
|
299
|
-
|
|
300
|
-
|
|
339
|
+
Just export Storybook directly. Control inclusion via the metro config `enabled` flag:
|
|
340
|
+
|
|
341
|
+
```tsx
|
|
342
|
+
// App.tsx
|
|
343
|
+
export { default } from './.rnstorybook';
|
|
344
|
+
```
|
|
345
|
+
|
|
346
|
+
```js
|
|
347
|
+
// metro.config.js
|
|
348
|
+
module.exports = withStorybook(config, {
|
|
349
|
+
enabled: process.env.EXPO_PUBLIC_STORYBOOK_ENABLED === 'true',
|
|
350
|
+
});
|
|
351
|
+
```
|
|
352
|
+
|
|
353
|
+
When `enabled: false`, Metro automatically removes Storybook from your bundle.
|
|
354
|
+
|
|
355
|
+
### Option 2: Conditional rendering
|
|
356
|
+
|
|
357
|
+
If you want to switch between your app and Storybook at runtime:
|
|
358
|
+
|
|
359
|
+
```tsx
|
|
360
|
+
// App.tsx
|
|
361
|
+
import StorybookUI from './.rnstorybook';
|
|
362
|
+
import { MyApp } from './MyApp';
|
|
363
|
+
|
|
364
|
+
const isStorybook = process.env.EXPO_PUBLIC_STORYBOOK_ENABLED === 'true';
|
|
365
|
+
|
|
366
|
+
export default function App() {
|
|
367
|
+
return isStorybook ? <StorybookUI /> : <MyApp />;
|
|
368
|
+
}
|
|
369
|
+
```
|
|
370
|
+
|
|
371
|
+
### Option 3: Expo Router (recommended for Expo)
|
|
372
|
+
|
|
373
|
+
Create a dedicated route for Storybook:
|
|
374
|
+
|
|
375
|
+
```tsx
|
|
376
|
+
// app/storybook.tsx
|
|
377
|
+
export { default } from '../.rnstorybook';
|
|
378
|
+
```
|
|
379
|
+
|
|
380
|
+
Then navigate to `/storybook` in your app to view stories.
|
|
301
381
|
|
|
302
382
|
## withStorybook wrapper
|
|
303
383
|
|
|
@@ -322,7 +402,9 @@ module.exports = withStorybook(defaultConfig, {
|
|
|
322
402
|
|
|
323
403
|
Type: `boolean`, default: `true`
|
|
324
404
|
|
|
325
|
-
|
|
405
|
+
Controls whether Storybook is included in your app bundle. When `true`, enables Storybook metro configuration and generates the `storybook.requires` file. When `false`, removes all Storybook code from the bundle by replacing imports with empty modules.
|
|
406
|
+
|
|
407
|
+
This is useful for conditionally including Storybook in development but excluding it from production builds:
|
|
326
408
|
|
|
327
409
|
```js
|
|
328
410
|
// metro.config.js
|
|
@@ -332,18 +414,11 @@ const withStorybook = require('@storybook/react-native/metro/withStorybook');
|
|
|
332
414
|
const defaultConfig = getDefaultConfig(__dirname);
|
|
333
415
|
|
|
334
416
|
module.exports = withStorybook(defaultConfig, {
|
|
335
|
-
enabled: process.env.
|
|
417
|
+
enabled: process.env.STORYBOOK_ENABLED === 'true',
|
|
336
418
|
// ... other options
|
|
337
419
|
});
|
|
338
420
|
```
|
|
339
421
|
|
|
340
|
-
#### onDisabledRemoveStorybook
|
|
341
|
-
|
|
342
|
-
Type: `boolean`, default: `false`
|
|
343
|
-
|
|
344
|
-
If onDisabledRemoveStorybook `true` and `enabled` is `false`, the storybook package will be removed from the build.
|
|
345
|
-
This is useful if you want to remove storybook from your production build.
|
|
346
|
-
|
|
347
422
|
#### useJs
|
|
348
423
|
|
|
349
424
|
Type: `boolean`, default: `false`
|
|
@@ -356,6 +431,18 @@ Type: `string`, default: `path.resolve(process.cwd(), './.rnstorybook')`
|
|
|
356
431
|
|
|
357
432
|
The location of your Storybook configuration directory, which includes `main.ts` and other project-related files.
|
|
358
433
|
|
|
434
|
+
#### docTools
|
|
435
|
+
|
|
436
|
+
Type: `boolean`, default: `true`
|
|
437
|
+
|
|
438
|
+
Whether to include doc tools in the storybook.requires file. Doc tools provide additional documentation features and work with `babel-plugin-react-docgen-typescript`.
|
|
439
|
+
|
|
440
|
+
#### liteMode
|
|
441
|
+
|
|
442
|
+
Type: `boolean`, default: `false`
|
|
443
|
+
|
|
444
|
+
Whether to use lite mode for Storybook. In lite mode, the default Storybook UI is mocked out so you don't need to install all its dependencies like react-native-reanimated. This is useful for reducing bundle size and dependencies. Use this when using @storybook/react-native-ui-lite instead of @storybook/react-native-ui.
|
|
445
|
+
|
|
359
446
|
### websockets
|
|
360
447
|
|
|
361
448
|
Type: `{ host: string?, port: number? }`, default: `undefined`
|
package/template/cli/preview.tsx
CHANGED