@storybook/react-native 9.0.0-beta.1 → 9.0.0-beta.11

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 CHANGED
@@ -1,12 +1,13 @@
1
1
  import * as storybook_internal_types from 'storybook/internal/types';
2
- import { StoryIndex, PreparedStory, NormalizedStoriesSpecifier, Addon_StorySortParameterV7, StorybookConfig as StorybookConfig$1 } from 'storybook/internal/types';
2
+ import { API_IndexHash, StoryIndex, PreparedStory, NormalizedStoriesSpecifier, Addon_StorySortParameterV7, StorybookConfig as StorybookConfig$1 } from 'storybook/internal/types';
3
3
  import { ReactRenderer } from '@storybook/react';
4
4
  import * as react_jsx_runtime from 'react/jsx-runtime';
5
5
  import { Channel } from 'storybook/internal/channels';
6
6
  import { PreviewWithSelection } from 'storybook/internal/preview-api';
7
- import { StoryContext } from '@storybook/csf';
7
+ import { StoryContext, Args } from '@storybook/csf';
8
8
  import { Theme } from '@storybook/react-native-theming';
9
9
  export { Theme, darkTheme, theme } from '@storybook/react-native-theming';
10
+ import { ReactElement } from 'react';
10
11
 
11
12
  interface Storage {
12
13
  getItem: (key: string) => Promise<string | null>;
@@ -39,6 +40,14 @@ type Params = {
39
40
  shouldPersistSelection?: boolean;
40
41
  theme: ThemePartial;
41
42
  storage?: Storage;
43
+ CustomUIComponent?: (props: {
44
+ story: StoryContext<ReactRenderer, Args>;
45
+ storyHash: API_IndexHash;
46
+ setStory: (storyId: string) => void;
47
+ storage: Storage;
48
+ theme: Theme;
49
+ children: ReactElement;
50
+ }) => ReactElement;
42
51
  };
43
52
  declare class View {
44
53
  _storyIndex: StoryIndex;
@@ -70,9 +79,9 @@ interface ReactNativeOptions {
70
79
  playFn?: boolean;
71
80
  }
72
81
  declare function prepareStories({ storyEntries, options, storySort, }: {
73
- storyEntries: Array<NormalizedStoriesSpecifier & {
82
+ storyEntries: (NormalizedStoriesSpecifier & {
74
83
  req: any;
75
- }>;
84
+ })[];
76
85
  options?: ReactNativeOptions;
77
86
  storySort?: Addon_StorySortParameterV7;
78
87
  }): {
@@ -84,15 +93,15 @@ declare function prepareStories({ storyEntries, options, storySort, }: {
84
93
  };
85
94
  declare const getProjectAnnotations: (view: View, annotations: any[]) => () => Promise<storybook_internal_types.NormalizedProjectAnnotations<ReactRenderer>>;
86
95
  declare function start({ annotations, storyEntries, options, }: {
87
- storyEntries: Array<NormalizedStoriesSpecifier & {
96
+ storyEntries: (NormalizedStoriesSpecifier & {
88
97
  req: any;
89
- }>;
98
+ })[];
90
99
  annotations: any[];
91
100
  options?: ReactNativeOptions;
92
101
  }): View;
93
- declare function updateView(viewInstance: View, annotations: any[], normalizedStories: Array<NormalizedStoriesSpecifier & {
102
+ declare function updateView(viewInstance: View, annotations: any[], normalizedStories: (NormalizedStoriesSpecifier & {
94
103
  req: any;
95
- }>, options?: ReactNativeOptions): void;
104
+ })[], options?: ReactNativeOptions): void;
96
105
 
97
106
  interface StorybookConfig {
98
107
  stories: StorybookConfig$1['stories'];
package/dist/index.js CHANGED
@@ -49,7 +49,7 @@ var import_channels2 = require("storybook/internal/channels");
49
49
  // src/View.tsx
50
50
  var import_bottom_sheet = require("@gorhom/bottom-sheet");
51
51
  var import_channels = require("storybook/internal/channels");
52
- var import_core_events = __toESM(require("storybook/internal/core-events"));
52
+ var import_core_events = require("storybook/internal/core-events");
53
53
  var import_manager_api = require("storybook/internal/manager-api");
54
54
  var import_preview_api = require("storybook/internal/preview-api");
55
55
  var import_csf = require("@storybook/csf");
@@ -954,7 +954,8 @@ var View3 = class {
954
954
  shouldPersistSelection = true,
955
955
  onDeviceUI = true,
956
956
  enableWebsockets = false,
957
- storage
957
+ storage,
958
+ CustomUIComponent
958
959
  } = params;
959
960
  this._storage = storage;
960
961
  const initialStory = this._getInitialStory(params);
@@ -965,7 +966,7 @@ var View3 = class {
965
966
  this._channel = channel;
966
967
  this._preview.channel = channel;
967
968
  this._preview.setupListeners();
968
- channel.emit(import_core_events.default.CHANNEL_CREATED);
969
+ channel.emit(import_core_events.CHANNEL_CREATED);
969
970
  this._preview.ready().then(() => this._preview.onStoryIndexChanged());
970
971
  }
971
972
  import_manager_api.addons.loadAddons({
@@ -999,10 +1000,10 @@ var View3 = class {
999
1000
  const urlObj = new URL(url);
1000
1001
  const storyId = urlObj.searchParams.get("STORYBOOK_STORY_ID");
1001
1002
  const hasStoryId = storyId && typeof storyId === "string";
1002
- const storyExists = hasStoryId && this._storyIdExists(storyId);
1003
- if (storyExists && this._ready) {
1003
+ const storyExists = hasStoryId && self._storyIdExists(storyId);
1004
+ if (storyExists && self._ready) {
1004
1005
  console.log(`STORYBOOK: Linking event received, navigating to story: ${storyId}`);
1005
- this._channel.emit(import_core_events.default.SET_CURRENT_STORY, { storyId });
1006
+ self._channel.emit(import_core_events.SET_CURRENT_STORY, { storyId });
1006
1007
  }
1007
1008
  if (hasStoryId && !storyExists) {
1008
1009
  console.log(
@@ -1016,15 +1017,15 @@ var View3 = class {
1016
1017
  };
1017
1018
  }, []);
1018
1019
  (0, import_react4.useEffect)(() => {
1019
- this.createPreparedStoryMapping().then(() => {
1020
- this._ready = true;
1020
+ self.createPreparedStoryMapping().then(() => {
1021
+ self._ready = true;
1021
1022
  setReady(true);
1022
1023
  return import_react_native3.Linking.getInitialURL().then((url) => {
1023
1024
  if (url && typeof url === "string") {
1024
1025
  const urlObj = new URL(url);
1025
1026
  const storyId = urlObj.searchParams.get("STORYBOOK_STORY_ID");
1026
1027
  const hasStoryId = storyId && typeof storyId === "string";
1027
- const storyExists = hasStoryId && this._storyIdExists(storyId);
1028
+ const storyExists = hasStoryId && self._storyIdExists(storyId);
1028
1029
  if (hasStoryId && !storyExists) {
1029
1030
  console.log(
1030
1031
  `STORYBOOK: Initial Linking event received, but story does not exist: ${storyId}`
@@ -1064,8 +1065,8 @@ var View3 = class {
1064
1065
  });
1065
1066
  `);
1066
1067
  }
1067
- if (shouldPersistSelection && !!this._storage) {
1068
- this._storage.setItem(STORAGE_KEY, newStory.id).catch((e) => {
1068
+ if (shouldPersistSelection && !!self._storage) {
1069
+ self._storage.setItem(STORAGE_KEY, newStory.id).catch((e) => {
1069
1070
  console.warn("storybook-log: error writing to async storage", e);
1070
1071
  });
1071
1072
  }
@@ -1076,7 +1077,7 @@ var View3 = class {
1076
1077
  if (!ready) {
1077
1078
  return {};
1078
1079
  }
1079
- return (0, import_react_native_ui.transformStoryIndexToStoriesHash)(this._storyIndex, {
1080
+ return (0, import_react_native_ui.transformStoryIndexToStoriesHash)(self._storyIndex, {
1080
1081
  docsOptions: { docsMode: false, defaultName: "" },
1081
1082
  filters: {},
1082
1083
  status: {},
@@ -1101,6 +1102,18 @@ var View3 = class {
1101
1102
  }
1102
1103
  if (onDeviceUI) {
1103
1104
  return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native_theming2.ThemeProvider, { theme: appliedTheme, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native_safe_area_context.SafeAreaProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native_gesture_handler.GestureHandlerRootView, { style: { flex: 1 }, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_bottom_sheet.BottomSheetModalProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native_ui.StorageProvider, { storage, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native_ui.LayoutProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native_ui.Layout, { storyHash, story, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(StoryView_default, {}) }) }) }) }) }) }) });
1105
+ } else if (CustomUIComponent) {
1106
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1107
+ CustomUIComponent,
1108
+ {
1109
+ story,
1110
+ storyHash,
1111
+ setStory: (newStoryId) => self._channel.emit(import_core_events.SET_CURRENT_STORY, { storyId: newStoryId }),
1112
+ storage,
1113
+ theme: appliedTheme,
1114
+ children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(StoryView_default, {})
1115
+ }
1116
+ );
1104
1117
  } else {
1105
1118
  return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(StoryView_default, {});
1106
1119
  }
@@ -1218,10 +1231,13 @@ function prepareStories({
1218
1231
  storySort,
1219
1232
  Object.values(index.entries).map((entry) => entry.importPath)
1220
1233
  );
1221
- const sorted = sortableStories.reduce((acc, item) => {
1222
- acc[item.id] = item;
1223
- return acc;
1224
- }, {});
1234
+ const sorted = sortableStories.reduce(
1235
+ (acc, item) => {
1236
+ acc[item.id] = item;
1237
+ return acc;
1238
+ },
1239
+ {}
1240
+ );
1225
1241
  return { index: { v: 5, entries: sorted }, importMap };
1226
1242
  }
1227
1243
  var getProjectAnnotations = (view, annotations) => async () => (0, import_preview_api2.composeConfigs)([
@@ -75,14 +75,14 @@ var require_common = __commonJS({
75
75
  const basePath = `${addon}/${file}`;
76
76
  require.resolve(basePath);
77
77
  return basePath;
78
- } catch (error) {
78
+ } catch (_error) {
79
79
  }
80
80
  for (const ext of extensions) {
81
81
  try {
82
82
  const filePath = `${addon}/${file}.${ext}`;
83
83
  require.resolve(filePath);
84
84
  return filePath;
85
- } catch (error) {
85
+ } catch (_error) {
86
86
  }
87
87
  }
88
88
  if (addon.startsWith("./") || addon.startsWith("../")) {
@@ -91,7 +91,7 @@ var require_common = __commonJS({
91
91
  if (extension) {
92
92
  return `${addon}/${file}`;
93
93
  }
94
- } catch (error) {
94
+ } catch (_error) {
95
95
  }
96
96
  }
97
97
  return null;
@@ -130,7 +130,6 @@ var require_generate = __commonJS({
130
130
  } = require_common();
131
131
  var { normalizeStories, globToRegexp } = require("storybook/internal/common");
132
132
  var fs = require("fs");
133
- var prettier = require("prettier");
134
133
  var path2 = require("path");
135
134
  var cwd = process.cwd();
136
135
  function generate2({ configPath, absolute = false, useJs = false }) {
@@ -150,13 +149,13 @@ var require_generate = __commonJS({
150
149
  const { path: p, recursive: r, match: m } = toRequireContext(specifier);
151
150
  const pathToStory = ensureRelativePathHasDot(path2.posix.relative(configPath, p));
152
151
  return `{
153
- titlePrefix: "${specifier.titlePrefix}",
154
- directory: "${specifier.directory}",
155
- files: "${specifier.files}",
156
- importPathMatcher: /${reg.source}/,
157
- ${useJs ? "" : "// @ts-ignore"}
158
- req: require.context('${pathToStory}', ${r}, ${m})
159
- }`;
152
+ titlePrefix: "${specifier.titlePrefix}",
153
+ directory: "${specifier.directory}",
154
+ files: "${specifier.files}",
155
+ importPathMatcher: /${reg.source}/,
156
+ ${useJs ? "" : "// @ts-ignore"}
157
+ req: require.context('${pathToStory}', ${r}, ${m})
158
+ }`;
160
159
  });
161
160
  let registerAddons = "";
162
161
  for (const addon of main.addons) {
@@ -189,54 +188,55 @@ var require_generate = __commonJS({
189
188
  let optionsVar = "";
190
189
  const reactNativeOptions = main.reactNative;
191
190
  if (reactNativeOptions && typeof reactNativeOptions === "object") {
192
- optionsVar = `const options = ${JSON.stringify(reactNativeOptions)}`;
191
+ optionsVar = `const options = ${JSON.stringify(reactNativeOptions, null, 4)}`;
193
192
  options = "options";
194
193
  }
195
194
  const previewExists = getPreviewExists({ configPath });
196
195
  if (previewExists) {
197
196
  enhancers.unshift("require('./preview')");
198
197
  }
199
- const annotations = `[${enhancers.join(", ")}]`;
198
+ const annotations = `[
199
+ ${enhancers.join(",\n ")}
200
+ ]`;
200
201
  const globalTypes = `
201
- declare global {
202
- var view: View;
203
- var STORIES: typeof normalizedStories;
204
- }
202
+ declare global {
203
+ var view: View;
204
+ var STORIES: typeof normalizedStories;
205
+ }
205
206
  `;
206
- const fileContent = `
207
- /* do not change this file, it is auto generated by storybook. */
207
+ const fileContent = `/* do not change this file, it is auto generated by storybook. */
208
+ import { start, updateView${useJs ? "" : ", View"} } from '@storybook/react-native';
208
209
 
209
- import { start, updateView${useJs ? "" : ", View"} } from '@storybook/react-native';
210
+ ${registerAddons}
210
211
 
211
- ${registerAddons}
212
+ const normalizedStories = [
213
+ ${normalizedStories.join(",\n ")}
214
+ ];
212
215
 
213
- const normalizedStories = [${normalizedStories.join(",")}];
216
+ ${useJs ? "" : globalTypes}
214
217
 
215
- ${useJs ? "" : globalTypes}
218
+ const annotations = ${annotations};
216
219
 
217
- const annotations = ${annotations};
220
+ global.STORIES = normalizedStories;
218
221
 
219
- global.STORIES = normalizedStories;
220
-
221
- ${useJs ? "" : "// @ts-ignore"}
222
- module?.hot?.accept?.();
222
+ ${useJs ? "" : "// @ts-ignore"}
223
+ module?.hot?.accept?.();
223
224
 
224
- ${optionsVar}
225
+ ${optionsVar}
225
226
 
226
- if (!global.view) {
227
- global.view = start({
228
- annotations,
229
- storyEntries: normalizedStories,
230
- ${options}
231
- });
232
- } else {
233
- updateView(global.view, annotations, normalizedStories, ${options});
234
- }
227
+ if (!global.view) {
228
+ global.view = start({
229
+ annotations,
230
+ storyEntries: normalizedStories,
231
+ ${options}
232
+ });
233
+ } else {
234
+ updateView(global.view, annotations, normalizedStories, ${options});
235
+ }
235
236
 
236
- export const view${useJs ? "" : ": View"} = global.view;
237
+ export const view${useJs ? "" : ": View"} = global.view;
237
238
  `;
238
- const formattedFileContent = prettier.format(fileContent, { parser: "babel-ts" });
239
- fs.writeFileSync(storybookRequiresLocation, formattedFileContent, {
239
+ fs.writeFileSync(storybookRequiresLocation, fileContent, {
240
240
  encoding: "utf8",
241
241
  flag: "w"
242
242
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@storybook/react-native",
3
- "version": "9.0.0-beta.1",
3
+ "version": "9.0.0-beta.11",
4
4
  "description": "A better way to develop React Native Components for your app",
5
5
  "keywords": [
6
6
  "react",
@@ -48,13 +48,12 @@
48
48
  "dependencies": {
49
49
  "@storybook/csf": "^0.1.13",
50
50
  "@storybook/global": "^5.0.0",
51
- "@storybook/react": "9.0.0-beta.4",
52
- "@storybook/react-native-theming": "^9.0.0-beta.1",
53
- "@storybook/react-native-ui": "^9.0.0-beta.1",
51
+ "@storybook/react": "9.0.0-beta.10",
52
+ "@storybook/react-native-theming": "^9.0.0-beta.11",
53
+ "@storybook/react-native-ui": "^9.0.0-beta.11",
54
54
  "commander": "^8.2.0",
55
55
  "dedent": "^1.5.1",
56
56
  "deepmerge": "^4.3.0",
57
- "prettier": "^2.4.1",
58
57
  "react-native-url-polyfill": "^2.0.0",
59
58
  "setimmediate": "^1.0.5",
60
59
  "type-fest": "~2.19",
@@ -63,18 +62,18 @@
63
62
  },
64
63
  "devDependencies": {
65
64
  "@types/jest": "^29.4.3",
66
- "@types/react": "~18.3.12",
65
+ "@types/react": "~19.0.10",
67
66
  "babel-jest": "^29.7.0",
68
67
  "babel-preset-expo": "^12.0.9",
69
68
  "jest": "^29.7.0",
70
- "jest-expo": "~52.0.6",
69
+ "jest-expo": "~53.0.5",
71
70
  "jotai": "^2.6.2",
72
- "react": "18.3.1",
73
- "react-native": "0.76.9",
74
- "react-test-renderer": "^18.3.1",
75
- "storybook": "9.0.0-beta.4",
71
+ "react": "19.0.0",
72
+ "react-native": "0.79.2",
73
+ "react-test-renderer": "^19.1.0",
74
+ "storybook": "9.0.0-beta.10",
76
75
  "tsup": "^7.2.0",
77
- "typescript": "^5.3.3"
76
+ "typescript": "~5.8.3"
78
77
  },
79
78
  "peerDependencies": {
80
79
  "@gorhom/bottom-sheet": ">=4",
@@ -82,7 +81,7 @@
82
81
  "react-native": ">=0.72.0",
83
82
  "react-native-gesture-handler": ">=2",
84
83
  "react-native-safe-area-context": "*",
85
- "storybook": "9.0.0-beta.4"
84
+ "storybook": "9.0.0-beta.10"
86
85
  },
87
86
  "engines": {
88
87
  "node": ">=8.0.0"
@@ -90,5 +89,5 @@
90
89
  "publishConfig": {
91
90
  "access": "public"
92
91
  },
93
- "gitHead": "41dd93e39512d4df2258fd68055b54fc361962f3"
92
+ "gitHead": "531ed8a758adc98bb436d0ccb32efcb369572ffe"
94
93
  }
package/readme.md CHANGED
@@ -1,16 +1,14 @@
1
1
  # Storybook for React Native
2
2
 
3
- > [!IMPORTANT]
4
- > This readme is for v8, for v7 docs see the [v7.6 docs](https://github.com/storybookjs/react-native/tree/v7.6.20-stable).
3
+ > This readme is for v9 beta, for v8 docs see the [v8.6 docs](https://github.com/storybookjs/react-native/tree/v8.6.0-stable).
5
4
 
6
5
  With Storybook for React Native you can design and develop individual React Native components without running your app.
7
6
 
8
- If you are migrating from 7.6 to 8.3 you can find the migration guide [here](https://github.com/storybookjs/react-native/blob/next/MIGRATION.md#from-version-76x-to-83x)
7
+ If you are migrating from 8 to 9 you can find the migration guide [here](https://github.com/storybookjs/react-native/blob/next/MIGRATION.md#from-version-8-to-9)
9
8
 
10
9
  For more information about storybook visit: [storybook.js.org](https://storybook.js.org)
11
10
 
12
- > [!NOTE]
13
- > `@storybook/react-native` requires atleast 8.3.1, if you install other storybook core packages they should be `^8.3.1` or newer.
11
+ > Make sure you align your storybook dependencies to the same major version or you will see broken behaviour.
14
12
 
15
13
  ![picture of storybook](https://github.com/user-attachments/assets/cf98766d-8b90-44ab-b718-94ab16e63205)
16
14
 
@@ -139,6 +137,15 @@ module.exports = withStorybook(finalConfig, {
139
137
  });
140
138
  ```
141
139
 
140
+ #### Reanimated setup
141
+
142
+ Make sure you have `react-native-reanimated` in your project and the plugin setup in your babel config.
143
+
144
+ ```js
145
+ // babel.config.js
146
+ plugins: ['react-native-reanimated/plugin'],
147
+ ```
148
+
142
149
  ## Writing stories
143
150
 
144
151
  In storybook we use a syntax called CSF that looks like this:
@@ -376,8 +383,6 @@ You can pass these parameters to getStorybookUI call in your storybook entry poi
376
383
  storage?: Object (undefined)
377
384
  -- {getItem: (key: string) => Promise<string | null>;setItem: (key: string, value: string) => Promise<void>;}
378
385
  -- Custom storage to be used instead of AsyncStorage
379
- shouldPersistSelection: Boolean (true)
380
- -- Stores last selected story in your devices storage.
381
386
  onDeviceUI?: boolean;
382
387
  -- show the ondevice ui
383
388
  enableWebsockets?: boolean;
@@ -1,251 +1,270 @@
1
1
  // Jest Snapshot v1, https://goo.gl/fbAQLP
2
2
 
3
3
  exports[`loader writeRequires when there are different file extensions writes the story imports 1`] = `
4
- "
5
- /* do not change this file, it is auto generated by storybook. */
6
-
7
- import { start, updateView, View } from '@storybook/react-native';
4
+ "/* do not change this file, it is auto generated by storybook. */
5
+ import { start, updateView, View } from '@storybook/react-native';
8
6
 
9
- import "@storybook/addon-ondevice-notes/register";
7
+ import "@storybook/addon-ondevice-notes/register";
10
8
  import "@storybook/addon-ondevice-controls/register";
11
9
  import "@storybook/addon-ondevice-backgrounds/register";
12
10
  import "@storybook/addon-ondevice-actions/register";
13
11
 
14
12
 
15
- const normalizedStories = [{
16
- titlePrefix: "",
17
- directory: "./scripts/mocks/file-extensions",
18
- files: "FakeStory.stories.tsx",
19
- importPathMatcher: /^\\.[\\\\/](?:FakeStory\\.stories\\.tsx)$/,
20
- // @ts-ignore
21
- req: require.context('./', false, /^\\.[\\\\/](?:FakeStory\\.stories\\.tsx)$/)
22
- }];
13
+ const normalizedStories = [
14
+ {
15
+ titlePrefix: "",
16
+ directory: "./scripts/mocks/file-extensions",
17
+ files: "FakeStory.stories.tsx",
18
+ importPathMatcher: /^\\.[\\\\/](?:FakeStory\\.stories\\.tsx)$/,
19
+ // @ts-ignore
20
+ req: require.context('./', false, /^\\.[\\\\/](?:FakeStory\\.stories\\.tsx)$/)
21
+ }
22
+ ];
23
23
 
24
-
25
- declare global {
26
- var view: View;
27
- var STORIES: typeof normalizedStories;
28
- }
24
+
25
+ declare global {
26
+ var view: View;
27
+ var STORIES: typeof normalizedStories;
28
+ }
29
29
 
30
30
 
31
- const annotations = [require('./preview'), require("@storybook/react-native/preview"), require('@storybook/addon-ondevice-actions/preview')];
31
+ const annotations = [
32
+ require('./preview'),
33
+ require("@storybook/react-native/preview"),
34
+ require('@storybook/addon-ondevice-actions/preview')
35
+ ];
32
36
 
33
- global.STORIES = normalizedStories;
34
-
35
- // @ts-ignore
36
- module?.hot?.accept?.();
37
+ global.STORIES = normalizedStories;
37
38
 
38
-
39
+ // @ts-ignore
40
+ module?.hot?.accept?.();
39
41
 
40
- if (!global.view) {
41
- global.view = start({
42
- annotations,
43
- storyEntries: normalizedStories,
44
-
45
- });
46
- } else {
47
- updateView(global.view, annotations, normalizedStories, );
48
- }
49
42
 
50
- export const view: View = global.view;
43
+
44
+ if (!global.view) {
45
+ global.view = start({
46
+ annotations,
47
+ storyEntries: normalizedStories,
48
+
49
+ });
50
+ } else {
51
+ updateView(global.view, annotations, normalizedStories, );
52
+ }
53
+
54
+ export const view: View = global.view;
51
55
  "
52
56
  `;
53
57
 
54
58
  exports[`loader writeRequires when there is a configuration object writes the story imports 1`] = `
55
- "
56
- /* do not change this file, it is auto generated by storybook. */
57
-
58
- import { start, updateView, View } from '@storybook/react-native';
59
+ "/* do not change this file, it is auto generated by storybook. */
60
+ import { start, updateView, View } from '@storybook/react-native';
59
61
 
60
- import "@storybook/addon-ondevice-notes/register";
62
+ import "@storybook/addon-ondevice-notes/register";
61
63
  import "@storybook/addon-ondevice-controls/register";
62
64
  import "@storybook/addon-ondevice-backgrounds/register";
63
65
  import "@storybook/addon-ondevice-actions/register";
64
66
 
65
67
 
66
- const normalizedStories = [{
67
- titlePrefix: "ComponentsPrefix",
68
- directory: "./scripts/mocks/configuration-objects/components",
69
- files: "**/*.stories.tsx",
70
- importPathMatcher: /^\\.(?:(?:^|\\/|(?:(?:(?!(?:^|\\/)\\.).)*?)\\/)(?!\\.)(?=.)[^/]*?\\.stories\\.tsx)$/,
71
- // @ts-ignore
72
- req: require.context('./components', true, /^\\.(?:(?:^|\\/|(?:(?:(?!(?:^|\\/)\\.).)*?)\\/)(?!\\.)(?=.)[^/]*?\\.stories\\.tsx)$/)
73
- }];
68
+ const normalizedStories = [
69
+ {
70
+ titlePrefix: "ComponentsPrefix",
71
+ directory: "./scripts/mocks/configuration-objects/components",
72
+ files: "**/*.stories.tsx",
73
+ importPathMatcher: /^\\.(?:(?:^|\\/|(?:(?:(?!(?:^|\\/)\\.).)*?)\\/)(?!\\.)(?=.)[^/]*?\\.stories\\.tsx)$/,
74
+ // @ts-ignore
75
+ req: require.context('./components', true, /^\\.(?:(?:^|\\/|(?:(?:(?!(?:^|\\/)\\.).)*?)\\/)(?!\\.)(?=.)[^/]*?\\.stories\\.tsx)$/)
76
+ }
77
+ ];
78
+
74
79
 
75
-
76
- declare global {
77
- var view: View;
78
- var STORIES: typeof normalizedStories;
79
- }
80
+ declare global {
81
+ var view: View;
82
+ var STORIES: typeof normalizedStories;
83
+ }
80
84
 
81
85
 
82
- const annotations = [require('./preview'), require("@storybook/react-native/preview"), require('@storybook/addon-ondevice-actions/preview')];
86
+ const annotations = [
87
+ require('./preview'),
88
+ require("@storybook/react-native/preview"),
89
+ require('@storybook/addon-ondevice-actions/preview')
90
+ ];
83
91
 
84
- global.STORIES = normalizedStories;
85
-
86
- // @ts-ignore
87
- module?.hot?.accept?.();
92
+ global.STORIES = normalizedStories;
88
93
 
89
-
94
+ // @ts-ignore
95
+ module?.hot?.accept?.();
90
96
 
91
- if (!global.view) {
92
- global.view = start({
93
- annotations,
94
- storyEntries: normalizedStories,
95
-
96
- });
97
- } else {
98
- updateView(global.view, annotations, normalizedStories, );
99
- }
100
97
 
101
- export const view: View = global.view;
98
+
99
+ if (!global.view) {
100
+ global.view = start({
101
+ annotations,
102
+ storyEntries: normalizedStories,
103
+
104
+ });
105
+ } else {
106
+ updateView(global.view, annotations, normalizedStories, );
107
+ }
108
+
109
+ export const view: View = global.view;
102
110
  "
103
111
  `;
104
112
 
105
113
  exports[`loader writeRequires when there is a story glob writes the story imports 1`] = `
106
- "
107
- /* do not change this file, it is auto generated by storybook. */
108
-
109
- import { start, updateView, View } from '@storybook/react-native';
114
+ "/* do not change this file, it is auto generated by storybook. */
115
+ import { start, updateView, View } from '@storybook/react-native';
110
116
 
111
- import "@storybook/addon-ondevice-notes/register";
117
+ import "@storybook/addon-ondevice-notes/register";
112
118
  import "@storybook/addon-ondevice-controls/register";
113
119
  import "@storybook/addon-ondevice-backgrounds/register";
114
120
  import "@storybook/addon-ondevice-actions/register";
115
121
 
116
122
 
117
- const normalizedStories = [{
118
- titlePrefix: "",
119
- directory: "./scripts/mocks/all-config-files",
120
- files: "FakeStory.stories.tsx",
121
- importPathMatcher: /^\\.[\\\\/](?:FakeStory\\.stories\\.tsx)$/,
122
- // @ts-ignore
123
- req: require.context('./', false, /^\\.[\\\\/](?:FakeStory\\.stories\\.tsx)$/)
124
- }];
123
+ const normalizedStories = [
124
+ {
125
+ titlePrefix: "",
126
+ directory: "./scripts/mocks/all-config-files",
127
+ files: "FakeStory.stories.tsx",
128
+ importPathMatcher: /^\\.[\\\\/](?:FakeStory\\.stories\\.tsx)$/,
129
+ // @ts-ignore
130
+ req: require.context('./', false, /^\\.[\\\\/](?:FakeStory\\.stories\\.tsx)$/)
131
+ }
132
+ ];
133
+
125
134
 
126
-
127
- declare global {
128
- var view: View;
129
- var STORIES: typeof normalizedStories;
130
- }
135
+ declare global {
136
+ var view: View;
137
+ var STORIES: typeof normalizedStories;
138
+ }
131
139
 
132
140
 
133
- const annotations = [require('./preview'), require("@storybook/react-native/preview"), require('@storybook/addon-ondevice-actions/preview')];
141
+ const annotations = [
142
+ require('./preview'),
143
+ require("@storybook/react-native/preview"),
144
+ require('@storybook/addon-ondevice-actions/preview')
145
+ ];
134
146
 
135
- global.STORIES = normalizedStories;
136
-
137
- // @ts-ignore
138
- module?.hot?.accept?.();
147
+ global.STORIES = normalizedStories;
139
148
 
140
-
149
+ // @ts-ignore
150
+ module?.hot?.accept?.();
141
151
 
142
- if (!global.view) {
143
- global.view = start({
144
- annotations,
145
- storyEntries: normalizedStories,
146
-
147
- });
148
- } else {
149
- updateView(global.view, annotations, normalizedStories, );
150
- }
151
152
 
152
- export const view: View = global.view;
153
+
154
+ if (!global.view) {
155
+ global.view = start({
156
+ annotations,
157
+ storyEntries: normalizedStories,
158
+
159
+ });
160
+ } else {
161
+ updateView(global.view, annotations, normalizedStories, );
162
+ }
163
+
164
+ export const view: View = global.view;
153
165
  "
154
166
  `;
155
167
 
156
168
  exports[`loader writeRequires when there is no preview does not add preview related stuff 1`] = `
157
- "
158
- /* do not change this file, it is auto generated by storybook. */
159
-
160
- import { start, updateView, View } from '@storybook/react-native';
169
+ "/* do not change this file, it is auto generated by storybook. */
170
+ import { start, updateView, View } from '@storybook/react-native';
161
171
 
162
- import "@storybook/addon-ondevice-notes/register";
172
+ import "@storybook/addon-ondevice-notes/register";
163
173
  import "@storybook/addon-ondevice-controls/register";
164
174
  import "@storybook/addon-ondevice-backgrounds/register";
165
175
  import "@storybook/addon-ondevice-actions/register";
166
176
 
167
177
 
168
- const normalizedStories = [{
169
- titlePrefix: "",
170
- directory: "./scripts/mocks/no-preview",
171
- files: "FakeStory.stories.tsx",
172
- importPathMatcher: /^\\.[\\\\/](?:FakeStory\\.stories\\.tsx)$/,
173
- // @ts-ignore
174
- req: require.context('./', false, /^\\.[\\\\/](?:FakeStory\\.stories\\.tsx)$/)
175
- }];
178
+ const normalizedStories = [
179
+ {
180
+ titlePrefix: "",
181
+ directory: "./scripts/mocks/no-preview",
182
+ files: "FakeStory.stories.tsx",
183
+ importPathMatcher: /^\\.[\\\\/](?:FakeStory\\.stories\\.tsx)$/,
184
+ // @ts-ignore
185
+ req: require.context('./', false, /^\\.[\\\\/](?:FakeStory\\.stories\\.tsx)$/)
186
+ }
187
+ ];
176
188
 
177
-
178
- declare global {
179
- var view: View;
180
- var STORIES: typeof normalizedStories;
181
- }
189
+
190
+ declare global {
191
+ var view: View;
192
+ var STORIES: typeof normalizedStories;
193
+ }
182
194
 
183
195
 
184
- const annotations = [require("@storybook/react-native/preview"), require('@storybook/addon-ondevice-actions/preview')];
196
+ const annotations = [
197
+ require("@storybook/react-native/preview"),
198
+ require('@storybook/addon-ondevice-actions/preview')
199
+ ];
185
200
 
186
- global.STORIES = normalizedStories;
187
-
188
- // @ts-ignore
189
- module?.hot?.accept?.();
201
+ global.STORIES = normalizedStories;
202
+
203
+ // @ts-ignore
204
+ module?.hot?.accept?.();
190
205
 
191
-
192
206
 
193
- if (!global.view) {
194
- global.view = start({
195
- annotations,
196
- storyEntries: normalizedStories,
197
-
198
- });
199
- } else {
200
- updateView(global.view, annotations, normalizedStories, );
201
- }
202
207
 
203
- export const view: View = global.view;
208
+ if (!global.view) {
209
+ global.view = start({
210
+ annotations,
211
+ storyEntries: normalizedStories,
212
+
213
+ });
214
+ } else {
215
+ updateView(global.view, annotations, normalizedStories, );
216
+ }
217
+
218
+ export const view: View = global.view;
204
219
  "
205
220
  `;
206
221
 
207
222
  exports[`loader writeRequires when using js writes the story imports without types 1`] = `
208
- "
209
- /* do not change this file, it is auto generated by storybook. */
223
+ "/* do not change this file, it is auto generated by storybook. */
224
+ import { start, updateView } from '@storybook/react-native';
210
225
 
211
- import { start, updateView } from '@storybook/react-native';
212
-
213
- import "@storybook/addon-ondevice-notes/register";
226
+ import "@storybook/addon-ondevice-notes/register";
214
227
  import "@storybook/addon-ondevice-controls/register";
215
228
  import "@storybook/addon-ondevice-backgrounds/register";
216
229
  import "@storybook/addon-ondevice-actions/register";
217
230
 
218
231
 
219
- const normalizedStories = [{
220
- titlePrefix: "",
221
- directory: "./scripts/mocks/all-config-files",
222
- files: "FakeStory.stories.tsx",
223
- importPathMatcher: /^\\.[\\\\/](?:FakeStory\\.stories\\.tsx)$/,
224
-
225
- req: require.context('./', false, /^\\.[\\\\/](?:FakeStory\\.stories\\.tsx)$/)
226
- }];
232
+ const normalizedStories = [
233
+ {
234
+ titlePrefix: "",
235
+ directory: "./scripts/mocks/all-config-files",
236
+ files: "FakeStory.stories.tsx",
237
+ importPathMatcher: /^\\.[\\\\/](?:FakeStory\\.stories\\.tsx)$/,
238
+
239
+ req: require.context('./', false, /^\\.[\\\\/](?:FakeStory\\.stories\\.tsx)$/)
240
+ }
241
+ ];
227
242
 
228
-
229
243
 
230
- const annotations = [require('./preview'), require("@storybook/react-native/preview"), require('@storybook/addon-ondevice-actions/preview')];
231
244
 
232
- global.STORIES = normalizedStories;
233
-
234
-
235
- module?.hot?.accept?.();
245
+ const annotations = [
246
+ require('./preview'),
247
+ require("@storybook/react-native/preview"),
248
+ require('@storybook/addon-ondevice-actions/preview')
249
+ ];
236
250
 
237
-
251
+ global.STORIES = normalizedStories;
238
252
 
239
- if (!global.view) {
240
- global.view = start({
241
- annotations,
242
- storyEntries: normalizedStories,
243
-
244
- });
245
- } else {
246
- updateView(global.view, annotations, normalizedStories, );
247
- }
248
253
 
249
- export const view = global.view;
254
+ module?.hot?.accept?.();
255
+
256
+
257
+
258
+ if (!global.view) {
259
+ global.view = start({
260
+ annotations,
261
+ storyEntries: normalizedStories,
262
+
263
+ });
264
+ } else {
265
+ updateView(global.view, annotations, normalizedStories, );
266
+ }
267
+
268
+ export const view = global.view;
250
269
  "
251
270
  `;
package/scripts/common.js CHANGED
@@ -67,7 +67,7 @@ function resolveAddonFile(addon, file, extensions = ['js', 'mjs', 'ts'], configP
67
67
  require.resolve(basePath);
68
68
 
69
69
  return basePath;
70
- } catch (error) {}
70
+ } catch (_error) {}
71
71
 
72
72
  for (const ext of extensions) {
73
73
  try {
@@ -76,7 +76,7 @@ function resolveAddonFile(addon, file, extensions = ['js', 'mjs', 'ts'], configP
76
76
  require.resolve(filePath);
77
77
 
78
78
  return filePath;
79
- } catch (error) {}
79
+ } catch (_error) {}
80
80
  }
81
81
 
82
82
  // attempt to resolve as a relative path for local addons
@@ -87,7 +87,7 @@ function resolveAddonFile(addon, file, extensions = ['js', 'mjs', 'ts'], configP
87
87
  if (extension) {
88
88
  return `${addon}/${file}`;
89
89
  }
90
- } catch (error) {}
90
+ } catch (_error) {}
91
91
  }
92
92
 
93
93
  return null;
@@ -8,7 +8,7 @@ const {
8
8
  } = require('./common');
9
9
  const { normalizeStories, globToRegexp } = require('storybook/internal/common');
10
10
  const fs = require('fs');
11
- const prettier = require('prettier');
11
+
12
12
  const path = require('path');
13
13
 
14
14
  const cwd = process.cwd();
@@ -39,13 +39,13 @@ function generate({ configPath, absolute = false, useJs = false }) {
39
39
 
40
40
  const pathToStory = ensureRelativePathHasDot(path.posix.relative(configPath, p));
41
41
  return `{
42
- titlePrefix: "${specifier.titlePrefix}",
43
- directory: "${specifier.directory}",
44
- files: "${specifier.files}",
45
- importPathMatcher: /${reg.source}/,
46
- ${useJs ? '' : '// @ts-ignore'}
47
- req: require.context('${pathToStory}', ${r}, ${m})
48
- }`;
42
+ titlePrefix: "${specifier.titlePrefix}",
43
+ directory: "${specifier.directory}",
44
+ files: "${specifier.files}",
45
+ importPathMatcher: /${reg.source}/,
46
+ ${useJs ? '' : '// @ts-ignore'}
47
+ req: require.context('${pathToStory}', ${r}, ${m})
48
+ }`;
49
49
  });
50
50
 
51
51
  let registerAddons = '';
@@ -86,7 +86,7 @@ function generate({ configPath, absolute = false, useJs = false }) {
86
86
  const reactNativeOptions = main.reactNative;
87
87
 
88
88
  if (reactNativeOptions && typeof reactNativeOptions === 'object') {
89
- optionsVar = `const options = ${JSON.stringify(reactNativeOptions)}`;
89
+ optionsVar = `const options = ${JSON.stringify(reactNativeOptions, null, 4)}`;
90
90
  options = 'options';
91
91
  }
92
92
 
@@ -96,51 +96,51 @@ function generate({ configPath, absolute = false, useJs = false }) {
96
96
  enhancers.unshift("require('./preview')");
97
97
  }
98
98
 
99
- const annotations = `[${enhancers.join(', ')}]`;
99
+ const annotations = `[
100
+ ${enhancers.join(',\n ')}
101
+ ]`;
100
102
 
101
103
  const globalTypes = `
102
- declare global {
103
- var view: View;
104
- var STORIES: typeof normalizedStories;
105
- }
104
+ declare global {
105
+ var view: View;
106
+ var STORIES: typeof normalizedStories;
107
+ }
106
108
  `;
107
109
 
108
- const fileContent = `
109
- /* do not change this file, it is auto generated by storybook. */
110
+ const fileContent = `/* do not change this file, it is auto generated by storybook. */
111
+ import { start, updateView${useJs ? '' : ', View'} } from '@storybook/react-native';
110
112
 
111
- import { start, updateView${useJs ? '' : ', View'} } from '@storybook/react-native';
113
+ ${registerAddons}
112
114
 
113
- ${registerAddons}
115
+ const normalizedStories = [
116
+ ${normalizedStories.join(',\n ')}
117
+ ];
114
118
 
115
- const normalizedStories = [${normalizedStories.join(',')}];
119
+ ${useJs ? '' : globalTypes}
116
120
 
117
- ${useJs ? '' : globalTypes}
121
+ const annotations = ${annotations};
118
122
 
119
- const annotations = ${annotations};
123
+ global.STORIES = normalizedStories;
120
124
 
121
- global.STORIES = normalizedStories;
122
-
123
- ${useJs ? '' : '// @ts-ignore'}
124
- module?.hot?.accept?.();
125
+ ${useJs ? '' : '// @ts-ignore'}
126
+ module?.hot?.accept?.();
125
127
 
126
- ${optionsVar}
128
+ ${optionsVar}
127
129
 
128
- if (!global.view) {
129
- global.view = start({
130
- annotations,
131
- storyEntries: normalizedStories,
132
- ${options}
133
- });
134
- } else {
135
- updateView(global.view, annotations, normalizedStories, ${options});
136
- }
130
+ if (!global.view) {
131
+ global.view = start({
132
+ annotations,
133
+ storyEntries: normalizedStories,
134
+ ${options}
135
+ });
136
+ } else {
137
+ updateView(global.view, annotations, normalizedStories, ${options});
138
+ }
137
139
 
138
- export const view${useJs ? '' : ': View'} = global.view;
140
+ export const view${useJs ? '' : ': View'} = global.view;
139
141
  `;
140
142
 
141
- const formattedFileContent = prettier.format(fileContent, { parser: 'babel-ts' });
142
-
143
- fs.writeFileSync(storybookRequiresLocation, formattedFileContent, {
143
+ fs.writeFileSync(storybookRequiresLocation, fileContent, {
144
144
  encoding: 'utf8',
145
145
  flag: 'w',
146
146
  });
@@ -14,12 +14,6 @@ jest.mock('fs', () => ({
14
14
  },
15
15
  }));
16
16
 
17
- jest.mock('prettier', () => ({
18
- format(s, opts) {
19
- return s;
20
- },
21
- }));
22
-
23
17
  describe('loader', () => {
24
18
  describe('writeRequires', () => {
25
19
  describe('when there is a story glob', () => {
@@ -1,9 +1,9 @@
1
1
  export const decorators: any = [];
2
2
  export const parameters = {
3
- my_param: 'anything',
4
- backgrounds: [
5
- { name: 'plain', value: 'white', default: true },
6
- { name: 'warm', value: 'hotpink' },
7
- { name: 'cool', value: 'deepskyblue' },
8
- ],
3
+ my_param: 'anything',
4
+ backgrounds: [
5
+ { name: 'plain', value: 'white', default: true },
6
+ { name: 'warm', value: 'hotpink' },
7
+ { name: 'cool', value: 'deepskyblue' },
8
+ ],
9
9
  };