@storybook/react-native 9.1.0 → 9.1.1-alpha.1
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.
- package/dist/index.d.ts +1 -1
- package/dist/index.js +15 -16
- package/dist/metro/withStorybook.js +8 -6
- package/dist/metro/withStorybookConfig.d.ts +116 -0
- package/dist/metro/withStorybookConfig.js +368 -0
- package/package.json +11 -10
package/dist/index.d.ts
CHANGED
|
@@ -123,4 +123,4 @@ interface StorybookConfig {
|
|
|
123
123
|
framework?: '@storybook/react-native';
|
|
124
124
|
}
|
|
125
125
|
|
|
126
|
-
export { InitialSelection, Params, Storage, StorybookConfig, ThemePartial, View, getProjectAnnotations, prepareStories, start, updateView };
|
|
126
|
+
export { type InitialSelection, type Params, type Storage, type StorybookConfig, type ThemePartial, View, getProjectAnnotations, prepareStories, start, updateView };
|
package/dist/index.js
CHANGED
|
@@ -27,8 +27,8 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
27
27
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
28
28
|
|
|
29
29
|
// src/index.ts
|
|
30
|
-
var
|
|
31
|
-
__export(
|
|
30
|
+
var index_exports = {};
|
|
31
|
+
__export(index_exports, {
|
|
32
32
|
darkTheme: () => import_react_native_theming3.darkTheme,
|
|
33
33
|
getProjectAnnotations: () => getProjectAnnotations,
|
|
34
34
|
prepareStories: () => prepareStories,
|
|
@@ -36,7 +36,7 @@ __export(src_exports, {
|
|
|
36
36
|
theme: () => import_react_native_theming3.theme,
|
|
37
37
|
updateView: () => updateView
|
|
38
38
|
});
|
|
39
|
-
module.exports = __toCommonJS(
|
|
39
|
+
module.exports = __toCommonJS(index_exports);
|
|
40
40
|
var import_react_native_theming3 = require("@storybook/react-native-theming");
|
|
41
41
|
|
|
42
42
|
// src/Start.tsx
|
|
@@ -915,8 +915,7 @@ var View3 = class {
|
|
|
915
915
|
this._asyncStorageStoryId = value;
|
|
916
916
|
}
|
|
917
917
|
const exists = value && this._storyIdExists(value);
|
|
918
|
-
if (!exists)
|
|
919
|
-
console.log("Storybook: could not find persisted story");
|
|
918
|
+
if (!exists) console.log("Storybook: could not find persisted story");
|
|
920
919
|
return { storySpecifier: exists ? value : "*", viewMode: "story" };
|
|
921
920
|
} catch (e) {
|
|
922
921
|
console.warn("storybook-log: error reading from async storage", e);
|
|
@@ -1200,22 +1199,23 @@ function prepareStories({
|
|
|
1200
1199
|
req.keys().forEach((filename) => {
|
|
1201
1200
|
try {
|
|
1202
1201
|
const fileExports = req(filename);
|
|
1203
|
-
if (!fileExports.default)
|
|
1204
|
-
return;
|
|
1202
|
+
if (!fileExports.default) return;
|
|
1205
1203
|
const meta = fileExports.default;
|
|
1206
1204
|
Object.keys(fileExports).forEach((key) => {
|
|
1207
|
-
if (key === "default")
|
|
1208
|
-
|
|
1209
|
-
if (!(0, import_csf2.isExportStory)(key, fileExports.default))
|
|
1210
|
-
return;
|
|
1205
|
+
if (key === "default") return;
|
|
1206
|
+
if (!(0, import_csf2.isExportStory)(key, fileExports.default)) return;
|
|
1211
1207
|
const exportValue = fileExports[key];
|
|
1212
|
-
if (!exportValue)
|
|
1213
|
-
return;
|
|
1208
|
+
if (!exportValue) return;
|
|
1214
1209
|
const title = makeTitle(filename, specifier, meta.title);
|
|
1215
1210
|
if (title) {
|
|
1216
1211
|
const nameFromExport = (0, import_csf2.storyNameFromExport)(key);
|
|
1217
1212
|
const id = (0, import_csf2.toId)(title, nameFromExport);
|
|
1218
|
-
|
|
1213
|
+
let name = nameFromExport;
|
|
1214
|
+
if (typeof exportValue === "function") {
|
|
1215
|
+
name = exportValue?.storyName || nameFromExport;
|
|
1216
|
+
} else {
|
|
1217
|
+
name = exportValue?.name || exportValue?.storyName || nameFromExport;
|
|
1218
|
+
}
|
|
1219
1219
|
index.entries[id] = {
|
|
1220
1220
|
type: "story",
|
|
1221
1221
|
id,
|
|
@@ -1228,8 +1228,7 @@ function prepareStories({
|
|
|
1228
1228
|
const importedStories = req(filename);
|
|
1229
1229
|
const stories = Object.entries(importedStories).reduce(
|
|
1230
1230
|
(carry, [storyKey, story]) => {
|
|
1231
|
-
if (!(0, import_csf2.isExportStory)(storyKey, fileExports.default))
|
|
1232
|
-
return carry;
|
|
1231
|
+
if (!(0, import_csf2.isExportStory)(storyKey, fileExports.default)) return carry;
|
|
1233
1232
|
if (story.play && !options?.playFn) {
|
|
1234
1233
|
carry[storyKey] = { ...story, play: void 0 };
|
|
1235
1234
|
} else {
|
|
@@ -69,8 +69,7 @@ var require_common = __commonJS({
|
|
|
69
69
|
return !!getFilePathExtension({ configPath }, "preview");
|
|
70
70
|
}
|
|
71
71
|
function resolveAddonFile(addon, file, extensions = ["js", "mjs", "ts"], configPath) {
|
|
72
|
-
if (!addon || typeof addon !== "string")
|
|
73
|
-
return null;
|
|
72
|
+
if (!addon || typeof addon !== "string") return null;
|
|
74
73
|
try {
|
|
75
74
|
const basePath = `${addon}/${file}`;
|
|
76
75
|
require.resolve(basePath);
|
|
@@ -97,10 +96,8 @@ var require_common = __commonJS({
|
|
|
97
96
|
return null;
|
|
98
97
|
}
|
|
99
98
|
function getAddonName(addon) {
|
|
100
|
-
if (typeof addon === "string")
|
|
101
|
-
|
|
102
|
-
if (typeof addon === "object" && addon.name && typeof addon.name === "string")
|
|
103
|
-
return addon.name;
|
|
99
|
+
if (typeof addon === "string") return addon;
|
|
100
|
+
if (typeof addon === "object" && addon.name && typeof addon.name === "string") return addon.name;
|
|
104
101
|
console.error("Invalid addon configuration", addon);
|
|
105
102
|
return null;
|
|
106
103
|
}
|
|
@@ -342,6 +339,11 @@ function withStorybook(config, options = {
|
|
|
342
339
|
type: "empty"
|
|
343
340
|
};
|
|
344
341
|
}
|
|
342
|
+
if (moduleName === "tty" || moduleName === "os") {
|
|
343
|
+
return {
|
|
344
|
+
type: "empty"
|
|
345
|
+
};
|
|
346
|
+
}
|
|
345
347
|
if (liteMode && resolveResult?.filePath?.includes?.("@storybook/react-native-ui") && !resolveResult?.filePath?.includes?.("@storybook/react-native-ui-lite") && !resolveResult?.filePath?.includes?.("@storybook/react-native-ui-common")) {
|
|
346
348
|
return {
|
|
347
349
|
type: "empty"
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import { MetroConfig } from 'metro-config';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Options for configuring WebSockets used for syncing storybook instances or sending events to storybook.
|
|
5
|
+
*/
|
|
6
|
+
interface WebsocketsOptions {
|
|
7
|
+
/**
|
|
8
|
+
* The port WebSocket server will listen on. Defaults to 7007.
|
|
9
|
+
*/
|
|
10
|
+
port?: number;
|
|
11
|
+
/**
|
|
12
|
+
* The host WebSocket server will bind to. Defaults to 'localhost'.
|
|
13
|
+
*/
|
|
14
|
+
host?: string;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Options for configuring Storybook with React Native.
|
|
18
|
+
*/
|
|
19
|
+
interface WithStorybookOptions {
|
|
20
|
+
/**
|
|
21
|
+
* The path to the Storybook config folder. Defaults to './.rnstorybook'.
|
|
22
|
+
*/
|
|
23
|
+
configPath?: string;
|
|
24
|
+
/**
|
|
25
|
+
* WebSocket configuration for syncing storybook instances or sending events to storybook.
|
|
26
|
+
*/
|
|
27
|
+
websockets?: WebsocketsOptions;
|
|
28
|
+
/**
|
|
29
|
+
* Whether to use JavaScript files for Storybook configuration instead of TypeScript. Defaults to false.
|
|
30
|
+
*/
|
|
31
|
+
useJs?: boolean;
|
|
32
|
+
/**
|
|
33
|
+
* if true, we will attempt to remove storybook from the js bundle.
|
|
34
|
+
*/
|
|
35
|
+
removeStorybook?: boolean;
|
|
36
|
+
/**
|
|
37
|
+
* Whether to include doc tools in the storybook.requires file. Defaults to true.
|
|
38
|
+
*/
|
|
39
|
+
docTools?: boolean;
|
|
40
|
+
/**
|
|
41
|
+
* Whether to use lite mode for the storybook. Defaults to false.
|
|
42
|
+
* This will mock out the default storybook ui so you don't need to install all its dependencies like reanimated etc.
|
|
43
|
+
*/
|
|
44
|
+
liteMode?: boolean;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Configures Metro bundler to work with Storybook in React Native.
|
|
48
|
+
* This function wraps a Metro configuration to enable Storybook usage.
|
|
49
|
+
* This is intended to replace the withStorybook function in the future.
|
|
50
|
+
*
|
|
51
|
+
* @param config - The Metro bundler configuration to be modified. This should be a valid Metro config object
|
|
52
|
+
* that includes resolver, transformer, and other Metro-specific options.
|
|
53
|
+
* @param options - Options to customize the Storybook configuration.
|
|
54
|
+
* @param options.configPath - The path to the Storybook config folder. Defaults to './.rnstorybook'.
|
|
55
|
+
* This is where your main.js/ts and preview.js/ts files are located.
|
|
56
|
+
* @param options.websockets - WebSocket configuration for syncing storybook instances or sending events.
|
|
57
|
+
* When provided, creates a WebSocket server for real-time communication.
|
|
58
|
+
* @param options.websockets.port - The port WebSocket server will listen on. Defaults to 7007.
|
|
59
|
+
* @param options.websockets.host - The host WebSocket server will bind to. Defaults to 'localhost'.
|
|
60
|
+
* @param options.useJs - Whether to use JavaScript files for Storybook configuration instead of TypeScript.
|
|
61
|
+
* When true, generates storybook.requires.js instead of storybook.requires.ts.
|
|
62
|
+
* Defaults to false.
|
|
63
|
+
* @param options.removeStorybook - If enabled is false and this is true, attempts to remove
|
|
64
|
+
* storybook modules from the JavaScript bundle to reduce bundle size.
|
|
65
|
+
* Defaults to false.
|
|
66
|
+
* @param options.docTools - Whether to include doc tools in the storybook.requires file.
|
|
67
|
+
* Doc tools provide additional documentation features. Defaults to true.
|
|
68
|
+
* @param options.liteMode - Whether to use lite mode for the storybook. In lite mode, the default
|
|
69
|
+
* storybook UI is mocked out so you don't need to install all its dependencies
|
|
70
|
+
* like reanimated etc. This is useful for reducing bundle size and dependencies.
|
|
71
|
+
* Defaults to false.
|
|
72
|
+
* @returns The modified Metro configuration with Storybook support enabled.
|
|
73
|
+
*
|
|
74
|
+
* @example
|
|
75
|
+
* ```javascript
|
|
76
|
+
* const { getDefaultConfig } = require('expo/metro-config');
|
|
77
|
+
* const withStorybook = require('@storybook/react-native/metro/withStorybook');
|
|
78
|
+
* const path = require('path');
|
|
79
|
+
*
|
|
80
|
+
* const projectRoot = __dirname;
|
|
81
|
+
* const config = getDefaultConfig(projectRoot);
|
|
82
|
+
*
|
|
83
|
+
* module.exports = withStorybook(config, {
|
|
84
|
+
* configPath: path.resolve(projectRoot, './.rnstorybook'),
|
|
85
|
+
* websockets: { port: 7007, host: 'localhost' },
|
|
86
|
+
* useJs: false,
|
|
87
|
+
* docTools: true,
|
|
88
|
+
* liteMode: false,
|
|
89
|
+
* });
|
|
90
|
+
* ```
|
|
91
|
+
*
|
|
92
|
+
* @example
|
|
93
|
+
* ```javascript
|
|
94
|
+
* // Minimal configuration
|
|
95
|
+
* const { getDefaultConfig } = require('expo/metro-config');
|
|
96
|
+
* const withStorybook = require('@storybook/react-native/metro/withStorybook');
|
|
97
|
+
*
|
|
98
|
+
* const config = getDefaultConfig(__dirname);
|
|
99
|
+
* module.exports = withStorybook(config);
|
|
100
|
+
* ```
|
|
101
|
+
*
|
|
102
|
+
* @example
|
|
103
|
+
* ```javascript
|
|
104
|
+
* // Disable Storybook in production
|
|
105
|
+
* const { getDefaultConfig } = require('expo/metro-config');
|
|
106
|
+
* const withStorybook = require('@storybook/react-native/metro/withStorybook');
|
|
107
|
+
*
|
|
108
|
+
* const config = getDefaultConfig(__dirname);
|
|
109
|
+
* module.exports = withStorybook(config, {
|
|
110
|
+
* removeStorybook: process.env.EXPO_PUBLIC_STORYBOOK_ENABLED !== "true",
|
|
111
|
+
* });
|
|
112
|
+
* ```
|
|
113
|
+
*/
|
|
114
|
+
declare function withStorybookConfig(config: MetroConfig, options?: WithStorybookOptions): MetroConfig;
|
|
115
|
+
|
|
116
|
+
export { withStorybookConfig as default, withStorybookConfig };
|
|
@@ -0,0 +1,368 @@
|
|
|
1
|
+
var __create = Object.create;
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
6
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
+
var __commonJS = (cb, mod) => function __require() {
|
|
8
|
+
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
|
|
9
|
+
};
|
|
10
|
+
var __export = (target, all) => {
|
|
11
|
+
for (var name in all)
|
|
12
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
13
|
+
};
|
|
14
|
+
var __copyProps = (to, from, except, desc) => {
|
|
15
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
16
|
+
for (let key of __getOwnPropNames(from))
|
|
17
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
18
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
19
|
+
}
|
|
20
|
+
return to;
|
|
21
|
+
};
|
|
22
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
23
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
24
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
25
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
26
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
27
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
28
|
+
mod
|
|
29
|
+
));
|
|
30
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
31
|
+
|
|
32
|
+
// scripts/common.js
|
|
33
|
+
var require_common = __commonJS({
|
|
34
|
+
"scripts/common.js"(exports2, module2) {
|
|
35
|
+
var { globToRegexp, serverRequire } = require("storybook/internal/common");
|
|
36
|
+
var path2 = require("path");
|
|
37
|
+
var fs = require("fs");
|
|
38
|
+
var cwd = process.cwd();
|
|
39
|
+
var toRequireContext = (specifier) => {
|
|
40
|
+
const { directory, files } = specifier;
|
|
41
|
+
const match = globToRegexp(`./${files}`);
|
|
42
|
+
return {
|
|
43
|
+
path: directory,
|
|
44
|
+
recursive: files.includes("**") || files.split("/").length > 1,
|
|
45
|
+
match
|
|
46
|
+
};
|
|
47
|
+
};
|
|
48
|
+
function requireUncached(module3) {
|
|
49
|
+
delete require.cache[require.resolve(module3)];
|
|
50
|
+
return serverRequire(module3);
|
|
51
|
+
}
|
|
52
|
+
var supportedExtensions = ["js", "jsx", "ts", "tsx", "cjs", "mjs"];
|
|
53
|
+
function getFilePathExtension({ configPath }, fileName) {
|
|
54
|
+
for (const ext of supportedExtensions) {
|
|
55
|
+
const filePath = path2.resolve(cwd, configPath, `${fileName}.${ext}`);
|
|
56
|
+
if (fs.existsSync(filePath)) {
|
|
57
|
+
return ext;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
return null;
|
|
61
|
+
}
|
|
62
|
+
function getMain({ configPath }) {
|
|
63
|
+
const fileExtension = getFilePathExtension({ configPath }, "main");
|
|
64
|
+
if (fileExtension === null) {
|
|
65
|
+
throw new Error("main config file not found");
|
|
66
|
+
}
|
|
67
|
+
const mainPath = path2.resolve(cwd, configPath, `main.${fileExtension}`);
|
|
68
|
+
return requireUncached(mainPath);
|
|
69
|
+
}
|
|
70
|
+
function ensureRelativePathHasDot(relativePath) {
|
|
71
|
+
return relativePath.startsWith(".") ? relativePath : `./${relativePath}`;
|
|
72
|
+
}
|
|
73
|
+
function getPreviewExists({ configPath }) {
|
|
74
|
+
return !!getFilePathExtension({ configPath }, "preview");
|
|
75
|
+
}
|
|
76
|
+
function resolveAddonFile(addon, file, extensions = ["js", "mjs", "ts"], configPath) {
|
|
77
|
+
if (!addon || typeof addon !== "string") return null;
|
|
78
|
+
try {
|
|
79
|
+
const basePath = `${addon}/${file}`;
|
|
80
|
+
require.resolve(basePath);
|
|
81
|
+
return basePath;
|
|
82
|
+
} catch (_error) {
|
|
83
|
+
}
|
|
84
|
+
for (const ext of extensions) {
|
|
85
|
+
try {
|
|
86
|
+
const filePath = `${addon}/${file}.${ext}`;
|
|
87
|
+
require.resolve(filePath);
|
|
88
|
+
return filePath;
|
|
89
|
+
} catch (_error) {
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
if (addon.startsWith("./") || addon.startsWith("../")) {
|
|
93
|
+
try {
|
|
94
|
+
const extension = getFilePathExtension({ configPath }, `${addon}/${file}`);
|
|
95
|
+
if (extension) {
|
|
96
|
+
return `${addon}/${file}`;
|
|
97
|
+
}
|
|
98
|
+
} catch (_error) {
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
return null;
|
|
102
|
+
}
|
|
103
|
+
function getAddonName(addon) {
|
|
104
|
+
if (typeof addon === "string") return addon;
|
|
105
|
+
if (typeof addon === "object" && addon.name && typeof addon.name === "string") return addon.name;
|
|
106
|
+
console.error("Invalid addon configuration", addon);
|
|
107
|
+
return null;
|
|
108
|
+
}
|
|
109
|
+
module2.exports = {
|
|
110
|
+
toRequireContext,
|
|
111
|
+
requireUncached,
|
|
112
|
+
getFilePathExtension,
|
|
113
|
+
getMain,
|
|
114
|
+
ensureRelativePathHasDot,
|
|
115
|
+
getPreviewExists,
|
|
116
|
+
resolveAddonFile,
|
|
117
|
+
getAddonName
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
// scripts/generate.js
|
|
123
|
+
var require_generate = __commonJS({
|
|
124
|
+
"scripts/generate.js"(exports2, module2) {
|
|
125
|
+
var {
|
|
126
|
+
toRequireContext,
|
|
127
|
+
ensureRelativePathHasDot,
|
|
128
|
+
getMain,
|
|
129
|
+
getPreviewExists,
|
|
130
|
+
resolveAddonFile,
|
|
131
|
+
getAddonName
|
|
132
|
+
} = require_common();
|
|
133
|
+
var { normalizeStories, globToRegexp } = require("storybook/internal/common");
|
|
134
|
+
var fs = require("fs");
|
|
135
|
+
var path2 = require("path");
|
|
136
|
+
var cwd = process.cwd();
|
|
137
|
+
function generate2({
|
|
138
|
+
configPath,
|
|
139
|
+
/* absolute = false, */
|
|
140
|
+
useJs = false,
|
|
141
|
+
docTools = true
|
|
142
|
+
}) {
|
|
143
|
+
const storybookRequiresLocation = path2.resolve(
|
|
144
|
+
cwd,
|
|
145
|
+
configPath,
|
|
146
|
+
`storybook.requires.${useJs ? "js" : "ts"}`
|
|
147
|
+
);
|
|
148
|
+
const mainImport = getMain({ configPath });
|
|
149
|
+
const main = mainImport.default ?? mainImport;
|
|
150
|
+
const storiesSpecifiers = normalizeStories(main.stories, {
|
|
151
|
+
configDir: configPath,
|
|
152
|
+
workingDir: cwd
|
|
153
|
+
});
|
|
154
|
+
const normalizedStories = storiesSpecifiers.map((specifier) => {
|
|
155
|
+
const reg = globToRegexp(`./${specifier.files}`);
|
|
156
|
+
const { path: p, recursive: r, match: m } = toRequireContext(specifier);
|
|
157
|
+
const pathToStory = ensureRelativePathHasDot(path2.posix.relative(configPath, p));
|
|
158
|
+
return `{
|
|
159
|
+
titlePrefix: "${specifier.titlePrefix}",
|
|
160
|
+
directory: "${specifier.directory}",
|
|
161
|
+
files: "${specifier.files}",
|
|
162
|
+
importPathMatcher: /${reg.source}/,
|
|
163
|
+
${useJs ? "" : "// @ts-ignore"}
|
|
164
|
+
req: require.context(
|
|
165
|
+
'${pathToStory}',
|
|
166
|
+
${r},
|
|
167
|
+
${m}
|
|
168
|
+
),
|
|
169
|
+
}`;
|
|
170
|
+
});
|
|
171
|
+
const registeredAddons = [];
|
|
172
|
+
for (const addon of main.addons) {
|
|
173
|
+
const registerPath = resolveAddonFile(
|
|
174
|
+
getAddonName(addon),
|
|
175
|
+
"register",
|
|
176
|
+
["js", "mjs", "jsx", "ts", "tsx"],
|
|
177
|
+
configPath
|
|
178
|
+
);
|
|
179
|
+
if (registerPath) {
|
|
180
|
+
registeredAddons.push(`import "${registerPath}";`);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
const docToolsAnnotation = 'require("@storybook/react-native/preview")';
|
|
184
|
+
const enhancers = [];
|
|
185
|
+
if (docTools) {
|
|
186
|
+
enhancers.push(docToolsAnnotation);
|
|
187
|
+
}
|
|
188
|
+
for (const addon of main.addons) {
|
|
189
|
+
const previewPath = resolveAddonFile(
|
|
190
|
+
getAddonName(addon),
|
|
191
|
+
"preview",
|
|
192
|
+
["js", "mjs", "jsx", "ts", "tsx"],
|
|
193
|
+
configPath
|
|
194
|
+
);
|
|
195
|
+
if (previewPath) {
|
|
196
|
+
enhancers.push(`require('${previewPath}')`);
|
|
197
|
+
continue;
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
let options = "";
|
|
201
|
+
let optionsVar = "";
|
|
202
|
+
const reactNativeOptions = main.reactNative;
|
|
203
|
+
if (reactNativeOptions && typeof reactNativeOptions === "object") {
|
|
204
|
+
optionsVar = `const options = ${JSON.stringify(reactNativeOptions, null, 2)}`;
|
|
205
|
+
options = "options";
|
|
206
|
+
}
|
|
207
|
+
const previewExists = getPreviewExists({ configPath });
|
|
208
|
+
if (previewExists) {
|
|
209
|
+
enhancers.unshift("require('./preview')");
|
|
210
|
+
}
|
|
211
|
+
const annotations = `[
|
|
212
|
+
${enhancers.join(",\n ")}
|
|
213
|
+
]`;
|
|
214
|
+
const globalTypes = `
|
|
215
|
+
declare global {
|
|
216
|
+
var view: View;
|
|
217
|
+
var STORIES: typeof normalizedStories;
|
|
218
|
+
}
|
|
219
|
+
`;
|
|
220
|
+
const fileContent = `/* do not change this file, it is auto generated by storybook. */
|
|
221
|
+
import { start, updateView${useJs ? "" : ", View"} } from '@storybook/react-native';
|
|
222
|
+
|
|
223
|
+
${registeredAddons.join("\n")}
|
|
224
|
+
|
|
225
|
+
const normalizedStories = [
|
|
226
|
+
${normalizedStories.join(",\n ")}
|
|
227
|
+
];
|
|
228
|
+
|
|
229
|
+
${useJs ? "" : globalTypes}
|
|
230
|
+
|
|
231
|
+
const annotations = ${annotations};
|
|
232
|
+
|
|
233
|
+
global.STORIES = normalizedStories;
|
|
234
|
+
|
|
235
|
+
${useJs ? "" : "// @ts-ignore"}
|
|
236
|
+
module?.hot?.accept?.();
|
|
237
|
+
|
|
238
|
+
${optionsVar}
|
|
239
|
+
|
|
240
|
+
if (!global.view) {
|
|
241
|
+
global.view = start({
|
|
242
|
+
annotations,
|
|
243
|
+
storyEntries: normalizedStories,
|
|
244
|
+
${options ? ` ${options},` : ""}
|
|
245
|
+
});
|
|
246
|
+
} else {
|
|
247
|
+
updateView(global.view, annotations, normalizedStories${options ? `, ${options}` : ""});
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
export const view${useJs ? "" : ": View"} = global.view;
|
|
251
|
+
`;
|
|
252
|
+
fs.writeFileSync(storybookRequiresLocation, fileContent, {
|
|
253
|
+
encoding: "utf8",
|
|
254
|
+
flag: "w"
|
|
255
|
+
});
|
|
256
|
+
}
|
|
257
|
+
module2.exports = {
|
|
258
|
+
generate: generate2
|
|
259
|
+
};
|
|
260
|
+
}
|
|
261
|
+
});
|
|
262
|
+
|
|
263
|
+
// src/metro/withStorybookConfig.ts
|
|
264
|
+
var withStorybookConfig_exports = {};
|
|
265
|
+
__export(withStorybookConfig_exports, {
|
|
266
|
+
default: () => withStorybookConfig_default,
|
|
267
|
+
withStorybookConfig: () => withStorybookConfig
|
|
268
|
+
});
|
|
269
|
+
module.exports = __toCommonJS(withStorybookConfig_exports);
|
|
270
|
+
var path = __toESM(require("path"));
|
|
271
|
+
var import_generate = __toESM(require_generate());
|
|
272
|
+
var import_ws = require("ws");
|
|
273
|
+
function withStorybookConfig(config, options = {
|
|
274
|
+
useJs: false,
|
|
275
|
+
removeStorybook: false,
|
|
276
|
+
docTools: true,
|
|
277
|
+
liteMode: false,
|
|
278
|
+
configPath: path.resolve(process.cwd(), "./.rnstorybook")
|
|
279
|
+
}) {
|
|
280
|
+
const {
|
|
281
|
+
configPath = path.resolve(process.cwd(), "./.rnstorybook"),
|
|
282
|
+
websockets,
|
|
283
|
+
useJs = false,
|
|
284
|
+
removeStorybook = false,
|
|
285
|
+
docTools = true,
|
|
286
|
+
liteMode = false
|
|
287
|
+
} = options;
|
|
288
|
+
if (removeStorybook) {
|
|
289
|
+
return {
|
|
290
|
+
...config,
|
|
291
|
+
resolver: {
|
|
292
|
+
...config.resolver,
|
|
293
|
+
resolveRequest: (context, moduleName, platform) => {
|
|
294
|
+
const resolveFunction = config?.resolver?.resolveRequest ? config.resolver.resolveRequest : context.resolveRequest;
|
|
295
|
+
if (moduleName.startsWith("storybook") || moduleName.startsWith("@storybook")) {
|
|
296
|
+
return {
|
|
297
|
+
type: "empty"
|
|
298
|
+
};
|
|
299
|
+
}
|
|
300
|
+
return resolveFunction(context, moduleName, platform);
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
};
|
|
304
|
+
}
|
|
305
|
+
if (websockets) {
|
|
306
|
+
const port = websockets.port ?? 7007;
|
|
307
|
+
const host = websockets.host ?? "localhost";
|
|
308
|
+
const wss = new import_ws.WebSocketServer({ port, host });
|
|
309
|
+
wss.on("connection", function connection(ws) {
|
|
310
|
+
console.log("WebSocket connection established");
|
|
311
|
+
ws.on("error", console.error);
|
|
312
|
+
ws.on("message", function message(data) {
|
|
313
|
+
try {
|
|
314
|
+
const json = JSON.parse(data.toString());
|
|
315
|
+
wss.clients.forEach((wsClient) => wsClient.send(JSON.stringify(json)));
|
|
316
|
+
} catch (error) {
|
|
317
|
+
console.error(error);
|
|
318
|
+
}
|
|
319
|
+
});
|
|
320
|
+
});
|
|
321
|
+
}
|
|
322
|
+
(0, import_generate.generate)({
|
|
323
|
+
configPath,
|
|
324
|
+
useJs,
|
|
325
|
+
docTools
|
|
326
|
+
});
|
|
327
|
+
return {
|
|
328
|
+
...config,
|
|
329
|
+
transformer: {
|
|
330
|
+
...config.transformer,
|
|
331
|
+
unstable_allowRequireContext: true
|
|
332
|
+
},
|
|
333
|
+
resolver: {
|
|
334
|
+
...config.resolver,
|
|
335
|
+
resolveRequest: (context, moduleName, platform) => {
|
|
336
|
+
const resolveFunction = config?.resolver?.resolveRequest ? config.resolver.resolveRequest : context.resolveRequest;
|
|
337
|
+
const shouldUseCustomResolveConfig = moduleName.startsWith("storybook") || moduleName.startsWith("@storybook") || moduleName.startsWith("uuid");
|
|
338
|
+
const theContext = shouldUseCustomResolveConfig ? {
|
|
339
|
+
...context,
|
|
340
|
+
unstable_enablePackageExports: true,
|
|
341
|
+
unstable_conditionNames: ["import"]
|
|
342
|
+
} : context;
|
|
343
|
+
const resolveResult = resolveFunction(theContext, moduleName, platform);
|
|
344
|
+
if (resolveResult?.filePath?.includes?.("@storybook/react/template/cli")) {
|
|
345
|
+
return {
|
|
346
|
+
type: "empty"
|
|
347
|
+
};
|
|
348
|
+
}
|
|
349
|
+
if (moduleName === "tty" || moduleName === "os") {
|
|
350
|
+
return {
|
|
351
|
+
type: "empty"
|
|
352
|
+
};
|
|
353
|
+
}
|
|
354
|
+
if (liteMode && resolveResult?.filePath?.includes?.("@storybook/react-native-ui") && !resolveResult?.filePath?.includes?.("@storybook/react-native-ui-lite") && !resolveResult?.filePath?.includes?.("@storybook/react-native-ui-common")) {
|
|
355
|
+
return {
|
|
356
|
+
type: "empty"
|
|
357
|
+
};
|
|
358
|
+
}
|
|
359
|
+
return resolveResult;
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
};
|
|
363
|
+
}
|
|
364
|
+
var withStorybookConfig_default = withStorybookConfig;
|
|
365
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
366
|
+
0 && (module.exports = {
|
|
367
|
+
withStorybookConfig
|
|
368
|
+
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@storybook/react-native",
|
|
3
|
-
"version": "9.1.
|
|
3
|
+
"version": "9.1.1-alpha.1",
|
|
4
4
|
"description": "A better way to develop React Native Components for your app",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"react",
|
|
@@ -24,6 +24,7 @@
|
|
|
24
24
|
"exports": {
|
|
25
25
|
".": "./dist/index.js",
|
|
26
26
|
"./metro/withStorybook": "./dist/metro/withStorybook.js",
|
|
27
|
+
"./metro/withStorybookConfig": "./dist/metro/withStorybookConfig.js",
|
|
27
28
|
"./preview": "./dist/preview.js",
|
|
28
29
|
"./scripts/generate": "./scripts/generate.js",
|
|
29
30
|
"./preset": "./preset.js"
|
|
@@ -47,10 +48,10 @@
|
|
|
47
48
|
},
|
|
48
49
|
"dependencies": {
|
|
49
50
|
"@storybook/global": "^5.0.0",
|
|
50
|
-
"@storybook/react": "^9.1.
|
|
51
|
-
"@storybook/react-native-theming": "^9.1.
|
|
52
|
-
"@storybook/react-native-ui": "^9.1.
|
|
53
|
-
"@storybook/react-native-ui-common": "^9.1.
|
|
51
|
+
"@storybook/react": "^9.1.2",
|
|
52
|
+
"@storybook/react-native-theming": "^9.1.1-alpha.1",
|
|
53
|
+
"@storybook/react-native-ui": "^9.1.1-alpha.1",
|
|
54
|
+
"@storybook/react-native-ui-common": "^9.1.1-alpha.1",
|
|
54
55
|
"commander": "^8.2.0",
|
|
55
56
|
"dedent": "^1.5.1",
|
|
56
57
|
"deepmerge": "^4.3.0",
|
|
@@ -66,13 +67,13 @@
|
|
|
66
67
|
"babel-jest": "^29.7.0",
|
|
67
68
|
"babel-preset-expo": "^12.0.9",
|
|
68
69
|
"jest": "^29.7.0",
|
|
69
|
-
"jest-expo": "~53.0.
|
|
70
|
+
"jest-expo": "~53.0.9",
|
|
70
71
|
"jotai": "^2.6.2",
|
|
71
72
|
"react": "19.0.0",
|
|
72
|
-
"react-native": "0.79.
|
|
73
|
+
"react-native": "0.79.5",
|
|
73
74
|
"react-test-renderer": "^19.1.0",
|
|
74
|
-
"storybook": "^9.1.
|
|
75
|
-
"tsup": "^
|
|
75
|
+
"storybook": "^9.1.2",
|
|
76
|
+
"tsup": "^8.5.0",
|
|
76
77
|
"typescript": "~5.8.3"
|
|
77
78
|
},
|
|
78
79
|
"peerDependencies": {
|
|
@@ -104,5 +105,5 @@
|
|
|
104
105
|
"publishConfig": {
|
|
105
106
|
"access": "public"
|
|
106
107
|
},
|
|
107
|
-
"gitHead": "
|
|
108
|
+
"gitHead": "cc38bfb53177171ffb92d228c0bcde0e4d01d767"
|
|
108
109
|
}
|