@storybook/react-native 6.5.5 → 6.5.6-alpha.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.
Files changed (67) hide show
  1. package/dist/index.d.ts +125 -18
  2. package/dist/index.js +1591 -41
  3. package/package.json +7 -8
  4. package/dist/constants.d.ts +0 -5
  5. package/dist/constants.js +0 -8
  6. package/dist/hooks.d.ts +0 -67
  7. package/dist/hooks.js +0 -168
  8. package/dist/preview/View.d.ts +0 -50
  9. package/dist/preview/View.js +0 -183
  10. package/dist/preview/components/OnDeviceUI/OnDeviceUI.d.ts +0 -12
  11. package/dist/preview/components/OnDeviceUI/OnDeviceUI.js +0 -163
  12. package/dist/preview/components/OnDeviceUI/Panel.d.ts +0 -9
  13. package/dist/preview/components/OnDeviceUI/Panel.js +0 -28
  14. package/dist/preview/components/OnDeviceUI/absolute-positioned-keyboard-aware-view.d.ts +0 -12
  15. package/dist/preview/components/OnDeviceUI/absolute-positioned-keyboard-aware-view.js +0 -31
  16. package/dist/preview/components/OnDeviceUI/addons/Addons.d.ts +0 -6
  17. package/dist/preview/components/OnDeviceUI/addons/Addons.js +0 -34
  18. package/dist/preview/components/OnDeviceUI/addons/AddonsSkeleton.d.ts +0 -14
  19. package/dist/preview/components/OnDeviceUI/addons/AddonsSkeleton.js +0 -78
  20. package/dist/preview/components/OnDeviceUI/addons/List.d.ts +0 -9
  21. package/dist/preview/components/OnDeviceUI/addons/List.js +0 -18
  22. package/dist/preview/components/OnDeviceUI/addons/Wrapper.d.ts +0 -8
  23. package/dist/preview/components/OnDeviceUI/addons/Wrapper.js +0 -31
  24. package/dist/preview/components/OnDeviceUI/addons/index.d.ts +0 -1
  25. package/dist/preview/components/OnDeviceUI/addons/index.js +0 -8
  26. package/dist/preview/components/OnDeviceUI/animation.d.ts +0 -61
  27. package/dist/preview/components/OnDeviceUI/animation.js +0 -116
  28. package/dist/preview/components/OnDeviceUI/index.d.ts +0 -1
  29. package/dist/preview/components/OnDeviceUI/index.js +0 -8
  30. package/dist/preview/components/OnDeviceUI/navigation/Navigation.d.ts +0 -9
  31. package/dist/preview/components/OnDeviceUI/navigation/Navigation.js +0 -54
  32. package/dist/preview/components/OnDeviceUI/navigation/NavigationBar.d.ts +0 -8
  33. package/dist/preview/components/OnDeviceUI/navigation/NavigationBar.js +0 -24
  34. package/dist/preview/components/OnDeviceUI/navigation/NavigationButton.d.ts +0 -2
  35. package/dist/preview/components/OnDeviceUI/navigation/NavigationButton.js +0 -23
  36. package/dist/preview/components/OnDeviceUI/navigation/constants.d.ts +0 -3
  37. package/dist/preview/components/OnDeviceUI/navigation/constants.js +0 -6
  38. package/dist/preview/components/OnDeviceUI/navigation/index.d.ts +0 -1
  39. package/dist/preview/components/OnDeviceUI/navigation/index.js +0 -8
  40. package/dist/preview/components/Shared/icons.d.ts +0 -53
  41. package/dist/preview/components/Shared/icons.js +0 -72
  42. package/dist/preview/components/Shared/layout.d.ts +0 -26
  43. package/dist/preview/components/Shared/layout.js +0 -24
  44. package/dist/preview/components/Shared/tabs.d.ts +0 -20
  45. package/dist/preview/components/Shared/tabs.js +0 -48
  46. package/dist/preview/components/StoryListView/StoryListView.d.ts +0 -7
  47. package/dist/preview/components/StoryListView/StoryListView.js +0 -201
  48. package/dist/preview/components/StoryListView/getNestedStories.d.ts +0 -10
  49. package/dist/preview/components/StoryListView/getNestedStories.js +0 -95
  50. package/dist/preview/components/StoryListView/getNestedStories.test.d.ts +0 -1
  51. package/dist/preview/components/StoryListView/getNestedStories.test.js +0 -237
  52. package/dist/preview/components/StoryListView/index.d.ts +0 -1
  53. package/dist/preview/components/StoryListView/index.js +0 -8
  54. package/dist/preview/components/StoryView/StoryView.d.ts +0 -3
  55. package/dist/preview/components/StoryView/StoryView.js +0 -47
  56. package/dist/preview/components/StoryView/index.d.ts +0 -1
  57. package/dist/preview/components/StoryView/index.js +0 -8
  58. package/dist/preview/executeLoadable.d.ts +0 -27
  59. package/dist/preview/executeLoadable.js +0 -95
  60. package/dist/preview/rn-host-detect.d.ts +0 -1
  61. package/dist/preview/rn-host-detect.js +0 -63
  62. package/dist/preview/start.d.ts +0 -16
  63. package/dist/preview/start.js +0 -124
  64. package/dist/types/types-6.0.d.ts +0 -72
  65. package/dist/types/types-6.0.js +0 -2
  66. package/dist/types/types.d.ts +0 -14
  67. package/dist/types/types.js +0 -2
package/dist/index.js CHANGED
@@ -1,45 +1,1595 @@
1
- "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
- for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
- };
16
- var _a;
17
- Object.defineProperty(exports, "__esModule", { value: true });
18
- exports.darkTheme = exports.theme = exports.getStorybookUI = exports.storiesOf = exports.raw = exports.getStorybook = exports.clearDecorators = exports.addArgTypesEnhancer = exports.addArgsEnhancer = exports.addParameters = exports.addDecorator = exports.setAddon = exports.configure = void 0;
19
- var start_1 = require("./preview/start");
20
- var _b = (0, start_1.start)(), clientApi = _b.clientApi, configure = _b.configure, view = _b.view;
21
- exports.configure = configure;
22
- var rawStoriesOf = clientApi.storiesOf.bind(clientApi);
23
- exports.setAddon = clientApi.setAddon.bind(clientApi);
24
- exports.addDecorator = clientApi.addDecorator.bind(clientApi);
25
- exports.addParameters = clientApi.addParameters.bind(clientApi);
26
- exports.addArgsEnhancer = clientApi.addArgsEnhancer.bind(clientApi);
27
- exports.addArgTypesEnhancer = clientApi.addArgTypesEnhancer.bind(clientApi);
28
- exports.clearDecorators = clientApi.clearDecorators.bind(clientApi);
29
- exports.getStorybook = clientApi.getStorybook.bind(clientApi);
30
- exports.raw = clientApi.raw.bind(clientApi);
31
- var storiesOf = function (kind, _module) {
32
- return rawStoriesOf(kind, { hot: function () { } }).addParameters({
33
- framework: 'react-native',
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 __export = (target, all) => {
8
+ for (var name in all)
9
+ __defProp(target, name, { get: all[name], enumerable: true });
10
+ };
11
+ var __copyProps = (to, from, except, desc) => {
12
+ if (from && typeof from === "object" || typeof from === "function") {
13
+ for (let key of __getOwnPropNames(from))
14
+ if (!__hasOwnProp.call(to, key) && key !== except)
15
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
16
+ }
17
+ return to;
18
+ };
19
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
20
+ // If the importer is in node compatibility mode or this is not an ESM
21
+ // file that has been converted to a CommonJS file using a Babel-
22
+ // compatible transform (i.e. "__esModule" has not been set), then set
23
+ // "default" to the CommonJS "module.exports" for node compatibility.
24
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
25
+ mod
26
+ ));
27
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
28
+
29
+ // src/index.ts
30
+ var src_exports = {};
31
+ __export(src_exports, {
32
+ addArgTypesEnhancer: () => addArgTypesEnhancer,
33
+ addArgsEnhancer: () => addArgsEnhancer,
34
+ addDecorator: () => addDecorator,
35
+ addParameters: () => addParameters,
36
+ clearDecorators: () => clearDecorators,
37
+ configure: () => configure,
38
+ darkTheme: () => import_react_native_theming14.darkTheme,
39
+ getStorybook: () => getStorybook,
40
+ getStorybookUI: () => getStorybookUI,
41
+ raw: () => raw,
42
+ setAddon: () => setAddon,
43
+ storiesOf: () => storiesOf,
44
+ theme: () => import_react_native_theming14.theme
45
+ });
46
+ module.exports = __toCommonJS(src_exports);
47
+
48
+ // src/preview/start.tsx
49
+ var import_addons4 = require("@storybook/addons");
50
+ var import_channels = __toESM(require("@storybook/channels"));
51
+ var import_client_api = require("@storybook/client-api");
52
+ var import_core_events3 = __toESM(require("@storybook/core-events"));
53
+ var import_preview_web = require("@storybook/preview-web");
54
+
55
+ // src/preview/executeLoadable.ts
56
+ var import_client_logger = require("@storybook/client-logger");
57
+ function executeLoadable(loadable) {
58
+ let reqs = null;
59
+ if (Array.isArray(loadable)) {
60
+ reqs = loadable;
61
+ } else if (loadable.keys) {
62
+ reqs = [loadable];
63
+ }
64
+ let exportsMap = /* @__PURE__ */ new Map();
65
+ if (reqs) {
66
+ reqs.forEach((req) => {
67
+ req.keys().forEach((filename) => {
68
+ try {
69
+ const fileExports = req(filename);
70
+ exportsMap.set(
71
+ // NOTE context.resolve is not yet implemented for metro
72
+ // typeof req.resolve === 'function' ? req.resolve(filename) : filename,
73
+ filename,
74
+ fileExports
75
+ );
76
+ } catch (error) {
77
+ const errorString = error.message && error.stack ? `${error.message}
78
+ ${error.stack}` : error.toString();
79
+ import_client_logger.logger.error(`Unexpected error while loading ${filename}: ${errorString}`);
80
+ }
81
+ });
34
82
  });
83
+ } else {
84
+ const exported = loadable();
85
+ if (typeof exported === "object") {
86
+ const csfExports = Object.entries(exported).filter(
87
+ ([_key, value]) => value.default != null
88
+ );
89
+ exportsMap = new Map(csfExports.map(([filePath, fileExports]) => [filePath, fileExports]));
90
+ }
91
+ }
92
+ return exportsMap;
93
+ }
94
+ global.lastExportsMap = /* @__PURE__ */ new Map();
95
+ function executeLoadableForChanges(loadable, m) {
96
+ if (m?.hot?.accept) {
97
+ m.hot.accept();
98
+ }
99
+ const lastExportsMap = global.lastExportsMap;
100
+ const exportsMap = executeLoadable(loadable);
101
+ const added = /* @__PURE__ */ new Map();
102
+ Array.from(exportsMap.entries()).filter(([, fileExports]) => !!fileExports.default).filter(([fileName, fileExports]) => lastExportsMap.get(fileName) !== fileExports).forEach(([fileName, fileExports]) => added.set(fileName, fileExports));
103
+ const removed = /* @__PURE__ */ new Map();
104
+ Array.from(lastExportsMap.keys()).filter((fileName) => !exportsMap.has(fileName)).forEach((fileName) => removed.set(fileName, lastExportsMap.get(fileName)));
105
+ global.lastExportsMap = exportsMap;
106
+ return { added, removed };
107
+ }
108
+
109
+ // src/preview/View.tsx
110
+ var import_react14 = require("react");
111
+ var import_async_storage = __toESM(require("@react-native-async-storage/async-storage"));
112
+ var import_csf = require("@storybook/csf");
113
+ var import_addons3 = require("@storybook/addons");
114
+ var import_react_native_theming12 = require("@storybook/react-native-theming");
115
+ var import_react_native_safe_area_context3 = require("react-native-safe-area-context");
116
+
117
+ // src/hooks.tsx
118
+ var import_react = __toESM(require("react"));
119
+ var import_jotai = require("jotai");
120
+ var storyContextAtom = (0, import_jotai.atom)(null);
121
+ function useSetStoryContext() {
122
+ return (0, import_jotai.useSetAtom)(storyContextAtom);
123
+ }
124
+ function useStoryContext() {
125
+ return (0, import_jotai.useAtomValue)(storyContextAtom);
126
+ }
127
+ function useStoryContextParam(name, defaultValue) {
128
+ const paramAtom = (0, import_react.useMemo)(() => (0, import_jotai.atom)((get) => get(storyContextAtom)?.parameters?.[name]), [name]);
129
+ return (0, import_jotai.useAtomValue)(paramAtom) ?? defaultValue;
130
+ }
131
+ function useIsStorySelected(storyId) {
132
+ return (0, import_jotai.useAtomValue)(
133
+ (0, import_react.useMemo)(() => (0, import_jotai.atom)((get) => get(storyContextAtom)?.id === storyId), [storyId])
134
+ );
135
+ }
136
+ function useIsStorySectionSelected(title) {
137
+ return (0, import_jotai.useAtomValue)(
138
+ (0, import_react.useMemo)(
139
+ () => (0, import_jotai.atom)((get) => {
140
+ const contextTitle = get(storyContextAtom)?.title;
141
+ return contextTitle === title || contextTitle?.startsWith(`${title}/`);
142
+ }),
143
+ [title]
144
+ )
145
+ );
146
+ }
147
+ function useIsChildSelected(entries) {
148
+ return (0, import_jotai.useAtomValue)(
149
+ (0, import_react.useMemo)(
150
+ () => (0, import_jotai.atom)((get) => {
151
+ const contextId = get(storyContextAtom)?.id;
152
+ return !!entries.find(({ id }) => id === contextId);
153
+ }),
154
+ [entries]
155
+ )
156
+ );
157
+ }
158
+ function useUpdateOnStoryChanged() {
159
+ (0, import_jotai.useAtomValue)((0, import_react.useMemo)(() => (0, import_jotai.atom)((get) => get(storyContextAtom)?.id), []));
160
+ }
161
+ function atomWithToggle(initialValue) {
162
+ const anAtom = (0, import_jotai.atom)(initialValue, (get, set, nextValue) => {
163
+ const update = nextValue ?? !get(anAtom);
164
+ set(anAtom, update);
165
+ });
166
+ return anAtom;
167
+ }
168
+ var isUIVisibleAtom = atomWithToggle(true);
169
+ function useIsUIVisible() {
170
+ return (0, import_jotai.useAtom)(isUIVisibleAtom);
171
+ }
172
+ var isSplitPanelVisibleAtom = atomWithToggle(false);
173
+ function useIsSplitPanelVisible() {
174
+ return (0, import_jotai.useAtom)(isSplitPanelVisibleAtom);
175
+ }
176
+ function syncExternalUI({ isUIVisible, isSplitPanelVisible }) {
177
+ const jotaiStore = (0, import_jotai.getDefaultStore)();
178
+ if (isUIVisible !== void 0) {
179
+ jotaiStore.set(isUIVisibleAtom, isUIVisible);
180
+ }
181
+ if (isSplitPanelVisible !== void 0) {
182
+ jotaiStore.set(isSplitPanelVisibleAtom, isSplitPanelVisible);
183
+ }
184
+ }
185
+ var selectedAddonAtom = (0, import_jotai.atom)(void 0);
186
+ function useSelectedAddon(initialValue) {
187
+ const result = (0, import_jotai.useAtom)(selectedAddonAtom);
188
+ const set = result[1];
189
+ import_react.default.useEffect(() => {
190
+ const jotaiStore = (0, import_jotai.getDefaultStore)();
191
+ if (jotaiStore.get(selectedAddonAtom) === void 0) {
192
+ set(initialValue);
193
+ }
194
+ }, []);
195
+ return result;
196
+ }
197
+
198
+ // src/preview/components/OnDeviceUI/OnDeviceUI.tsx
199
+ var import_react_native_theming10 = require("@storybook/react-native-theming");
200
+ var import_react13 = __toESM(require("react"));
201
+ var import_react_native13 = require("react-native");
202
+
203
+ // src/constants.ts
204
+ var ANIMATION_DURATION_TRANSITION = 400;
205
+
206
+ // src/preview/components/StoryListView/StoryListView.tsx
207
+ var import_addons = require("@storybook/addons");
208
+ var import_core_events = __toESM(require("@storybook/core-events"));
209
+ var import_react_native_theming = require("@storybook/react-native-theming");
210
+ var import_react2 = __toESM(require("react"));
211
+ var import_react_native2 = require("react-native");
212
+
213
+ // src/preview/components/Shared/icons.tsx
214
+ var import_react_native = require("react-native");
215
+ var import_jsx_runtime = require("react/jsx-runtime");
216
+ var iconSources = {
217
+ grid: {
218
+ uri: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGQAAABkCAMAAABHPGVmAAAAAXNSR0IB2cksfwAAAAlwSFlzAAALEwAACxMBAJqcGAAAALdQTFRFAAAAIJ//Hqf9Hqf9Hqf9Hqf9Hqf9Hqf9Hqf9Hqf9Hqf9Hqf9Hqj9Hqf9Hqf9Hqf9Hqf9Hqf9Hqf9Hqf9Hqf9Hqf9Hqf9Hqf9Hqf9Hqf9Hqf9Hqf9Hqf9Hqf9Hqf9Hqf9Haf9Hqf9Hqf9Hqf9Hqf9Hqf9Hqf9Hqf9Hqf9Hqf9Hqf9Hqf9Hqf9Hqf9Hqf9Hqf9Hqf9Hqf9Hqb9Hqf9Hqf9Hqf9Hqf9Hqf9Hqf9Hqf9Hqf9Hqj9Hqf9Hmz01QAAAD10Uk5TAAAEGjNefYqLXDUFAjSY0e79/9KZAghmyMkBQbz6vUIBBnD1cQcOo6Sp76qBePTHVOoC+RQTX4mCDZsBMmX5zDcAAAHcSURBVHic7ZrrcoIwEIVX8W5VpAiUaq33GyJqrfby/s9VacsCDojUJNNx9vzCTLLfZJdkHM4ChJTJSrl8oVj6s4qFckWqZiBed7V6Q24qV6op36uVVgxC042rAQh60LUIhPnY7rBCuOo8dZ9PGb3+gCXC1WA4CjPGE9YIV9NxiNHmwVCUWYAy4rIPV1PMmNnnxVCUoVf9LvOa+xp0f89HqCDzhbWMle3NsuPnWIt5MF7757zogfOxcqLOEGrtzVufm6U5Kz9iR3eHNgYObNWXc4svhQDs1C0GNTbHgZp/l6hnt5ECApqKQZu1471b93O1S1h6OQR2fsbqGcg28JeTtDIFBBwM28iCJON7lZSsVBAN3zFZCpRkkbgwDQQWWJQcvOK2LLYQCwPnoYDPS7aQJQYuwJ4/ZA8l/pASQQhCEIIQhCAEIQhBghB7nSj839xMnmtHQriJIAS5IYiQw3g7dxdBCEIQghCEIAQhyH+ECPmMLsQQKOMzY2vjgIHLYkwaIXaTEOMM+FuAIMbMhJYIW1aIwczaKj9EWuVCTH++7Quml8Qev0aMnl+qtxkfxnu4cYXLXiYhhpg2H4AP1g1L7a55ygDGrVdGZOuVKwFNZN/KSp/XtsPVpOpJ0C+2naE/XA0rpwAAAABJRU5ErkJggg=="
219
+ },
220
+ "story-white": {
221
+ uri: "data:image/png;base64,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"
222
+ },
223
+ "story-blue": {
224
+ uri: "data:image/png;base64,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"
225
+ },
226
+ search: {
227
+ uri: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACQAAAAkCAYAAADhAJiYAAABgWlDQ1BzUkdCIElFQzYxOTY2LTIuMQAAKJF1kd8rg1EYxz/baGLy88KFsjSuTEyJG2USamnNlOFme+2H2ubtfbe03Cq3K0rc+HXBX8Ctcq0UkZJbrokb1ut5t9Uke07PeT7ne87zdM5zwBpMKim9ZgBS6YwWmPI6F0KLTvsLVlqw00VrWNHVcb/fR1X7vMdixlu3Wav6uX+tYSWqK2CpEx5TVC0jPC3sW8+oJu8ItyuJ8IrwmXCfJhcUvjP1SIlfTY6X+NtkLRiYAGuzsDP+iyO/WEloKWF5Oa5UMquU72O+xBFNz89J7BbvRCfAFF6czDDJBMMMMirzMG489MuKKvkDxfxZ1iRXkVklh8YqcRJk6BM1K9WjEmOiR2UkyZn9/9tXPTbkKVV3eKH22TDee8C+DYW8YXwdGUbhGGxPcJmu5K8dwsiH6PmK5jqApk04v6pokV242IKORzWshYuSTdwai8HbKTSGoO0G6pdKPSvvc/IAwQ35qmvY24deOd+0/AMfDGfFB6WkFAAAAAlwSFlzAAALEwAACxMBAJqcGAAAAqNJREFUWIXF2DmIFFEQBuBvVh3FC0EFdT3QaDORTUTFI9hQPAIRQxE0ETXwQBADD7zAaBEDTQxlIxExE4VFjTzYxQNFERUTr/VCvII3Q78Ze2Z6drvZH5ppmqq//q73XnXVlGRHFzZgJeZiDibjLd7gMa7gOr62wdsWStiEAfzNeH3HhYroXNGNu02CPsN9vMOfBjZHUc5DzBb8qAtwG7uxMMW+jB704kOd3w3MGImYg3WEQ9jehn8nrtVxPMeC4YjZ4v+3S8tIFmzD54jrnnAIMqNbWPcqwRFhU48EC/A04uzLyllSu4Fv5CCmimX4HXGvzeK0Se2eGe4yNcLpiH8QY1s5xHVmR85iYEJFSDXG5mbGXZHhnQLEVLEqinO5meGByHBPgYJKeF2J80XIWirimrGoQEFwLoq1PM2gQyhkhMr8vGBBg9H9nFaC3hYshtAVVNGZZtAhqZ5DhcupjTE+zaBDkplZhcthdnQ/kGbQIUnjTDm1Ck0QL9ODRoKeVO5LQjdYJFZXfj/hVSOjjZKj2FugmGn4WYlzq5nhJMlX/oMGxzEHHJa8+MlWxhcj46sFiFkiyc57TG/lME9tL7Q1RzFlYQNXuXdmdTweOX3C/JwEHYt4BzAuq2MZNyPnx1g6AiFlYer4FXH2tEsyEy8igl84of36tFgYkepHo2F1EwvxsI7oIVZk8J2KQ5INnHbta0bQqG+egktYV/f8lTAuDwoVfkj4HHRijVD44mw+ErLShbPR8/041UxYI7HrK6RZx+jq9RG71G7gvdrIVDOMFea1PuFPhEYiPqMfZ4S9mIaWotoddSYK81unUNHHC0f5AV5WgrTCXrXLNazlyxu5LV+eSBU1ZhQF9eObpFj2CIdh1BFn6s1oZqiKfqHtWYLz/wAUO/neFu9thgAAAABJRU5ErkJggg=="
228
+ },
229
+ "layout-bottom": {
230
+ uri: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAAACXBIWXMAABYlAAAWJQFJUiTwAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAEzSURBVHgB7ZjhDYIwEIWfTsAIjOAIHYGNZANwAnQi3KBu4AhYIiYNNHCF0ivxvuR+mHjNe70eyR0gCIKQOspEZUKb6CJFa6IxkWMD2SC8Y45q0OItvgXALd6uiJeJFG7eVQkSuSNZ49sL3qVcSQF3zylKcoOp+FjCbTJMTdSUxPHbL8CHwvQyFxmXjZMMC3pOjqSO8J+YzOo54+CIAW7EADdigBsxwI0Y4EYMcLPWwNXEG+HGxf4s8si4xNI8sOe8XK7Q450Q8uZdlfDS85c9cMN+PBAAypvrtwOhm7jcoGc2gWOlYuPdA6/R7wv4GK90niDQPw/bsUY6i62GkqgwLVt/UKwFVzZo0A4dOfWQGvt969cGaa1o38Kh1+s/EylUosbGHsxN3BG3InoQriAIgpA0H3BBw2jFymiHAAAAAElFTkSuQmCC"
231
+ },
232
+ "layout-bottom-inverse": {
233
+ uri: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAAACXBIWXMAABYlAAAWJQFJUiTwAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAFgSURBVHgB7ZjhcYMwDIXlTEA2YISOYDbIRmSD0AloJ+kIyQbuBskGqnz4R+OYw7jYchN9dzouwYIn2+LgAQiCIFQNImqKE4XBcpwpRooWUqHkxgnnxmpo5nSqOfF0+KJ4gzq4UHRKqZt/YjeT0EM94i1WSx81kma/DSyjwakXGigA3eeA4Z7TMcljQHwR4Z6OJlDEEJN49pIOwIRb9bvJ9MeoQBLeDSCACbfy19//+XqqLsCypGcH/xwpgBspgBspgBspgBspgBspgJukAugFsae44nbYa51gC/wrB87ndCqOa/Ws/h6ws0WHXJ+YN7rdHlboeckeeId8fMJfWdpzbsyA2zfxMUXPYg8Q+5AjVoqUHvj2frM5dPho6VxikgZv1QzWY2yNMYk6sEcNFjK4nHCNYWuxjb3IgPURtBWf0153AzvI+8yPxWrokp+EONntH/ho+ubE4LSNNQiCIFTND53ElQfvR3pDAAAAAElFTkSuQmCC"
234
+ },
235
+ "layout-split": {
236
+ uri: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAAACXBIWXMAABYlAAAWJQFJUiTwAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAADxSURBVHgB7ZjhCcIwFITP4gAdISM4QkZwI0doNqgb1Q3iJjU/Imga5YVK3yveB/ejkJa7vgTCAYQQYh2fNCTFpHkjTUljksMK+mx8VtaQvTSbnwBom3+dSFMIC3++NgkRDlA3+0m+NNtVAlxgl7NkkaW9XyqWZg+VADNs8+a5w85hAG0YQBsG0IYBtNl9gKNgzQG6fL3acAtpwwDaMIA2DKDNXwRorvW2pBbgXjyfoEfZA90gIGDZxWhMoceyER8lL3rUCyVRK/YD+uwhVnw46UcC7LVyAQ3svl5/hrAwiYCVZ9AlXbHtRGI27kEIIaZ5ALildIGPrcQbAAAAAElFTkSuQmCC"
237
+ },
238
+ "layout-split-inverse": {
239
+ uri: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAAACXBIWXMAABYlAAAWJQFJUiTwAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAEaSURBVHgB7ZntDYJADIaLcQBGYARHgAl0I0YQJ8BNdAPZ4BzBDWov8ENrkYuJtJA+SUO4D/K+1yaQAuA4jmMaRCwpjhQB5+NG0VIU8Cu0OR+EaxM15GM6szHxdLlQ7MAGHUWVZdmDT2xGNtRgR3wkaqmliY8MYF93AWwSs3B9HZAyUINdDnxAMmCpdDh7PiCVEIJhqITeNG9g4bgBbdyANm5AGzegzeINbKcW8Ff33Ex92ngJaeMGtHED2rgBbdZv4FtbzwKSgTu7V2uz0OHxPlCXsqlhzdWgkQXsm8uBaWlTNpZChzgIp/EXBuElyu38IvUhDdqjkbSus70+LKwoTqBP1CCKT4KyUVCcsf/tMxcB+zIuwXEcxzRPpfGo9y3IYogAAAAASUVORK5CYII="
240
+ },
241
+ folder: {
242
+ uri: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAuIwAALiMBeKU/dgAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAHTSURBVGiB7Zk7LwRRGIbf7wwRRIJGlDSEpdmI6Fw6lRWZXiJ0lkZUsn8A2dD5B0MhkS1UepGIXZu4hsKlJASxyZyjoJAx4uzutztjc57yXN58T+Z8M5kZoEKg2R4nSpL6IdCQ72YlhQLh3LLc/dUj+7YUBepC8ciWYshxidSy+1a/tHYx+s6QlzeCKcdSihZEzWtqfsCpZcrMCy6RTwgj8knsBCHDKwIEJsPVI36cKOCGK4ygnkHYbcpkNxJISO98lc+eR4Au9eJVG4DmXyY7CejUrvRPCFCIPUQifTjG1I9ZnyuynTyeiOlEx3udDkixB6CVo1RdXCHb19P21fexonokmbZPIeQQgPuiKssTS1K3d6zoZg9Choh+tATLXSuZtk8tSwyC1B1HXiH4NXtBrByNn8V7nWFIMcmVCVJzAGp0lrKJAF/HDFjkyotHtmagKcL/QAwIIxI2jEjYMCJhw4iEDSMSNoxI2DAiYcOIhI2KEfF71W2c7XGiZa/EDwVLd6mfyCApccBYTlmomKNlRAJFymvv0P8TIRzediHjHRYAMgBK9Y+EkxygUpBybHPTdr2TBADT0Z06K/ek9UUvKFpk9Usia+eCrsNgMBgMBkM5+ADkCHptw04GlAAAAABJRU5ErkJggg=="
243
+ }
244
+ };
245
+ function Icon({ name, ...props }) {
246
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
247
+ import_react_native.Image,
248
+ {
249
+ source: {
250
+ ...iconSources[name],
251
+ width: 16,
252
+ height: 16
253
+ },
254
+ ...props
255
+ }
256
+ );
257
+ }
258
+ function BackgroundIcon({ name, ...props }) {
259
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
260
+ import_react_native.ImageBackground,
261
+ {
262
+ source: {
263
+ ...iconSources[name],
264
+ width: 16,
265
+ height: 16
266
+ },
267
+ ...props
268
+ }
269
+ );
270
+ }
271
+
272
+ // src/preview/components/StoryListView/getNestedStories.ts
273
+ function getNestedStories(storyIndex) {
274
+ const stories = Object.values(storyIndex.stories);
275
+ const group = [];
276
+ stories.forEach((story) => {
277
+ const nameParts = story.title.split("/");
278
+ formGroup(nameParts, story, group);
279
+ });
280
+ return group;
281
+ }
282
+ function formGroup(nameParts, story, group) {
283
+ if (nameParts.length === 1) {
284
+ const current = group.find(({ name }) => name === nameParts[0]);
285
+ if (current) {
286
+ current.stories.push(story);
287
+ } else {
288
+ group.push({
289
+ title: story.title,
290
+ name: nameParts[0],
291
+ children: [],
292
+ stories: [story]
293
+ });
294
+ }
295
+ return;
296
+ }
297
+ const newParts = nameParts.slice(1);
298
+ const currentListPart = group.find(({ name }) => name === nameParts[0]);
299
+ if (!currentListPart) {
300
+ const toPush = {
301
+ name: nameParts[0],
302
+ title: story.title,
303
+ children: [],
304
+ stories: []
305
+ };
306
+ group.push(toPush);
307
+ return formGroup(newParts, story, toPush.children);
308
+ } else if (!currentListPart.children) {
309
+ currentListPart.children = [];
310
+ }
311
+ const newGroup = currentListPart.children;
312
+ return formGroup(newParts, story, newGroup);
313
+ }
314
+ var filterNestedStories = (stories, filter) => {
315
+ const filteredStories = [];
316
+ stories.forEach((story) => {
317
+ const filtered = filterStoryGroup(story, filter);
318
+ if (filtered) {
319
+ filteredStories.push(filtered);
320
+ }
321
+ });
322
+ return filteredStories;
323
+ };
324
+ var filterStoryGroup = (story, filter) => {
325
+ const filteredStories = story.stories.filter(
326
+ (item) => item.title.toLowerCase().includes(filter.toLowerCase()) || item.name.toLowerCase().includes(filter.toLowerCase())
327
+ );
328
+ const filteredChildren = filterNestedStories(story.children, filter);
329
+ if (filteredStories.length || filteredChildren.length) {
330
+ return {
331
+ ...story,
332
+ children: filteredChildren,
333
+ stories: filteredStories
334
+ };
335
+ }
336
+ };
337
+ var findFirstChildStory = (story) => {
338
+ if (story.stories.length) {
339
+ return story.stories[0];
340
+ }
341
+ if (story.children.length) {
342
+ return findFirstChildStory(story.children[0]);
343
+ }
344
+ };
345
+
346
+ // src/preview/components/StoryListView/StoryListView.tsx
347
+ var import_jsx_runtime2 = require("react/jsx-runtime");
348
+ var SectionHeaderText = import_react_native_theming.styled.Text(({ theme: theme3 }) => ({
349
+ fontSize: theme3.storyList.fontSize,
350
+ color: theme3.storyList.headerTextColor,
351
+ fontWeight: theme3.storyList.headerFontWeight,
352
+ flexShrink: 1
353
+ }));
354
+ var StoryNameText = import_react_native_theming.styled.Text(({ selected, theme: theme3 }) => ({
355
+ fontSize: theme3.storyList.fontSize,
356
+ fontWeight: selected ? theme3.storyList.storySelectedFontWeight : theme3.storyList.storyFontWeight,
357
+ color: selected ? theme3.storyList.storySelectedTextColor : theme3.storyList.storyTextColor
358
+ }));
359
+ var SEARCH_ICON_SIZE = 24;
360
+ var SearchInput = import_react_native_theming.styled.TextInput(
361
+ {
362
+ padding: 0,
363
+ ...import_react_native2.StyleSheet.absoluteFillObject
364
+ },
365
+ ({ theme: theme3 }) => ({
366
+ fontSize: theme3.storyList.search.fontSize,
367
+ paddingStart: theme3.storyList.search.paddingHorizontal + SEARCH_ICON_SIZE,
368
+ color: theme3.storyList.search.textColor
369
+ })
370
+ );
371
+ var SearchContainer = import_react_native_theming.styled.View(({ theme: theme3 }) => ({
372
+ flexDirection: "row",
373
+ alignItems: "center",
374
+ margin: theme3.panel.paddingHorizontal,
375
+ paddingVertical: theme3.storyList.search.paddingVertical,
376
+ paddingStart: theme3.storyList.search.paddingHorizontal,
377
+ borderColor: theme3.storyList.search.borderColor,
378
+ borderWidth: theme3.storyList.search.borderWidth,
379
+ borderRadius: theme3.storyList.search.borderRadius,
380
+ backgroundColor: theme3.storyList.search.backgroundColor
381
+ }));
382
+ var SearchBar = (props) => {
383
+ const theme3 = (0, import_react_native_theming.useTheme)();
384
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(SearchContainer, { children: [
385
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Icon, { name: "search", style: { opacity: 0.5 } }),
386
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
387
+ SearchInput,
388
+ {
389
+ ...props,
390
+ autoCapitalize: "none",
391
+ autoComplete: "off",
392
+ autoCorrect: false,
393
+ spellCheck: false,
394
+ clearButtonMode: "while-editing",
395
+ disableFullscreenUI: true,
396
+ placeholderTextColor: theme3.storyList.search.placeholderTextColor,
397
+ returnKeyType: "search"
398
+ }
399
+ )
400
+ ] });
401
+ };
402
+ var HeaderContainer = import_react_native_theming.styled.TouchableOpacity(
403
+ {
404
+ flexDirection: "row",
405
+ alignItems: "center"
406
+ },
407
+ ({ selected, theme: theme3, childSelected }) => ({
408
+ marginTop: theme3.storyList.sectionSpacing,
409
+ paddingHorizontal: theme3.storyList.headerPaddingHorizontal,
410
+ paddingVertical: theme3.storyList.headerPaddingVertical,
411
+ backgroundColor: selected ? theme3.storyList.sectionActiveBackgroundColor : void 0,
412
+ borderTopLeftRadius: theme3.storyList.sectionBorderRadius,
413
+ borderTopRightRadius: theme3.storyList.sectionBorderRadius,
414
+ borderBottomLeftRadius: selected && !childSelected ? theme3.storyList.sectionBorderRadius : void 0,
415
+ borderBottomRightRadius: selected && !childSelected ? theme3.storyList.sectionBorderRadius : void 0
416
+ })
417
+ );
418
+ var SectionHeader = import_react2.default.memo(
419
+ ({ name, onPress, isChildSelected, icon = "grid", expanded }) => {
420
+ const selected = useIsStorySectionSelected(name) || isChildSelected;
421
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
422
+ HeaderContainer,
423
+ {
424
+ selected,
425
+ childSelected: isChildSelected,
426
+ onPress,
427
+ activeOpacity: 0.8,
428
+ children: [
429
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
430
+ import_react_native2.View,
431
+ {
432
+ style: {
433
+ transform: [{ rotate: expanded ? "90deg" : "0deg" }],
434
+ marginRight: 6,
435
+ alignItems: "center",
436
+ justifyContent: "center"
437
+ },
438
+ children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native2.Text, { style: { fontSize: 8, color: "grey", lineHeight: 8 }, children: "\u27A4" })
439
+ }
440
+ ),
441
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Icon, { name: icon, width: 12, height: 12, style: { marginRight: 6 } }),
442
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(SectionHeaderText, { numberOfLines: 2, selected, children: name })
443
+ ]
444
+ },
445
+ name
446
+ );
447
+ }
448
+ );
449
+ var ItemTouchable = import_react_native_theming.styled.TouchableOpacity(
450
+ {
451
+ flexDirection: "row",
452
+ alignItems: "center"
453
+ },
454
+ ({ selected, sectionSelected, isLastItem, theme: theme3 }) => ({
455
+ padding: theme3.storyList.storyPaddingHorizontal,
456
+ paddingStart: theme3.storyList.storyIndent,
457
+ backgroundColor: selected ? theme3.storyList.storySelectedBackgroundColor : sectionSelected ? theme3.storyList.sectionActiveBackgroundColor : void 0,
458
+ borderBottomLeftRadius: isLastItem ? theme3.storyList.sectionBorderRadius : void 0,
459
+ borderBottomRightRadius: isLastItem ? theme3.storyList.sectionBorderRadius : void 0
460
+ })
461
+ );
462
+ var ListItem = ({
463
+ storyId,
464
+ kind,
465
+ title,
466
+ isLastItem,
467
+ onPress,
468
+ isSiblingSelected
469
+ }) => {
470
+ const selected = useIsStorySelected(storyId);
471
+ const sectionSelected = useIsStorySectionSelected(kind) || isSiblingSelected;
472
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
473
+ ItemTouchable,
474
+ {
475
+ onPress,
476
+ activeOpacity: 0.8,
477
+ testID: `Storybook.ListItem.${kind}.${title}`,
478
+ accessibilityLabel: `Storybook.ListItem.${title}`,
479
+ selected,
480
+ sectionSelected,
481
+ isLastItem,
482
+ children: [
483
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
484
+ Icon,
485
+ {
486
+ width: 14,
487
+ height: 14,
488
+ name: selected ? "story-white" : "story-blue",
489
+ style: { marginRight: 6 }
490
+ }
491
+ ),
492
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(StoryNameText, { selected, children: title })
493
+ ]
494
+ },
495
+ title
496
+ );
497
+ };
498
+ var styles = import_react_native2.StyleSheet.create({
499
+ sectionList: { flex: 1 },
500
+ sectionListContentContainer: { paddingBottom: 6 }
501
+ });
502
+ function keyExtractor(item, index) {
503
+ return item.name + index;
504
+ }
505
+ var RenderItem = ({
506
+ item,
507
+ changeStory
508
+ }) => {
509
+ const isChildSelected = useIsChildSelected(item.stories);
510
+ const firstChild = findFirstChildStory(item);
511
+ const firstChildSelected = useIsStorySelected(firstChild?.id);
512
+ const [showChildren, setShowChildren] = (0, import_react2.useState)(false);
513
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
514
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
515
+ SectionHeader,
516
+ {
517
+ name: item.name,
518
+ isChildSelected,
519
+ onPress: () => {
520
+ if (firstChildSelected && showChildren) {
521
+ setShowChildren(false);
522
+ } else if (!showChildren && firstChild) {
523
+ setShowChildren(true);
524
+ changeStory(firstChild.id);
525
+ } else if (showChildren && !firstChildSelected && firstChild) {
526
+ changeStory(firstChild.id);
527
+ }
528
+ },
529
+ icon: item.children.length ? "folder" : "grid",
530
+ expanded: showChildren
531
+ }
532
+ ),
533
+ showChildren && item.stories?.map((story, idx) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
534
+ ListItem,
535
+ {
536
+ storyId: story.id,
537
+ title: story.name,
538
+ kind: item.name,
539
+ isSiblingSelected: isChildSelected,
540
+ isLastItem: idx === item.stories.length - 1,
541
+ onPress: () => changeStory(story.id)
542
+ },
543
+ story.id
544
+ )),
545
+ showChildren && item.children?.map((child, idx) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native2.View, { style: { marginLeft: 16 }, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(RenderItem, { item: child, changeStory }) }, `${child.title}-${idx}`))
546
+ ] });
547
+ };
548
+ var StoryListView = ({ storyIndex }) => {
549
+ const originalData = (0, import_react2.useMemo)(() => getNestedStories(storyIndex), [storyIndex]);
550
+ const [data, setData] = (0, import_react2.useState)(originalData);
551
+ const theme3 = (0, import_react_native_theming.useTheme)();
552
+ const handleChangeSearchText = (text) => {
553
+ const query = text.trim();
554
+ if (!query) {
555
+ setData(originalData);
556
+ return;
557
+ }
558
+ setData(filterNestedStories(originalData, query));
559
+ };
560
+ const changeStory = (storyId) => {
561
+ const channel = import_addons.addons.getChannel();
562
+ channel.emit(import_core_events.default.SET_CURRENT_STORY, { storyId });
563
+ };
564
+ const renderItem = import_react2.default.useCallback(({ item }) => {
565
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(RenderItem, { item, changeStory });
566
+ }, []);
567
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react_native2.View, { style: { flex: 1 }, children: [
568
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
569
+ SearchBar,
570
+ {
571
+ testID: "Storybook.ListView.SearchBar",
572
+ onChangeText: handleChangeSearchText,
573
+ placeholder: "Find by name"
574
+ }
575
+ ),
576
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
577
+ import_react_native2.FlatList,
578
+ {
579
+ style: styles.sectionList,
580
+ contentContainerStyle: [
581
+ styles.sectionListContentContainer,
582
+ {
583
+ paddingVertical: theme3.panel.paddingVertical,
584
+ paddingHorizontal: theme3.panel.paddingHorizontal
585
+ }
586
+ ],
587
+ testID: "Storybook.ListView",
588
+ renderItem,
589
+ keyExtractor,
590
+ data
591
+ }
592
+ )
593
+ ] });
594
+ };
595
+ var StoryListView_default = import_react2.default.memo(StoryListView);
596
+
597
+ // src/preview/components/StoryView/StoryView.tsx
598
+ var import_react3 = __toESM(require("react"));
599
+ var import_react_native_theming2 = require("@storybook/react-native-theming");
600
+ var import_react_native3 = require("react-native");
601
+ var import_jsx_runtime3 = require("react/jsx-runtime");
602
+ function dismissOnStartResponder() {
603
+ import_react_native3.Keyboard.dismiss();
604
+ return false;
605
+ }
606
+ var StoryView = () => {
607
+ const context = useStoryContext();
608
+ const id = context?.id;
609
+ const { backgroundColor } = (0, import_react_native_theming2.useTheme)();
610
+ if (context && context.unboundStoryFn) {
611
+ const { unboundStoryFn: StoryComponent } = context;
612
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
613
+ import_react_native3.View,
614
+ {
615
+ style: { flex: 1, backgroundColor },
616
+ testID: id,
617
+ onStartShouldSetResponder: dismissOnStartResponder,
618
+ children: StoryComponent && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(StoryComponent, { ...context })
619
+ },
620
+ id
621
+ );
622
+ }
623
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native3.View, { style: { flex: 1, padding: 16, alignItems: "center", justifyContent: "center" }, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native3.Text, { children: "Please open the sidebar and select a story to preview." }) });
624
+ };
625
+ var StoryView_default = import_react3.default.memo(StoryView);
626
+
627
+ // src/preview/components/OnDeviceUI/absolute-positioned-keyboard-aware-view.tsx
628
+ var import_react4 = __toESM(require("react"));
629
+ var import_react_native4 = require("react-native");
630
+ var import_jsx_runtime4 = require("react/jsx-runtime");
631
+ var AbsolutePositionedKeyboardAwareView = ({
632
+ onLayout,
633
+ previewDimensions: { width, height },
634
+ children
635
+ }) => {
636
+ const onLayoutHandler = ({ nativeEvent }) => {
637
+ const { height: layoutHeight, width: layoutWidth } = nativeEvent.layout;
638
+ if (layoutHeight !== height || layoutWidth !== width) {
639
+ onLayout({
640
+ height: layoutHeight,
641
+ width: layoutWidth
642
+ });
643
+ }
644
+ };
645
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native4.View, { style: styles2.container, onLayout: onLayoutHandler, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
646
+ import_react_native4.View,
647
+ {
648
+ style: width === 0 ? styles2.container : [styles2.absolute, { position: "absolute", width, height }],
649
+ children
650
+ }
651
+ ) });
652
+ };
653
+ var styles2 = import_react_native4.StyleSheet.create({
654
+ absolute: { position: "absolute" },
655
+ container: { flex: 1 }
656
+ });
657
+ var absolute_positioned_keyboard_aware_view_default = import_react4.default.memo(AbsolutePositionedKeyboardAwareView);
658
+
659
+ // src/preview/components/OnDeviceUI/addons/Addons.tsx
660
+ var import_addons2 = require("@storybook/addons");
661
+ var import_react_native_theming6 = require("@storybook/react-native-theming");
662
+ var import_react8 = __toESM(require("react"));
663
+ var import_react_native7 = require("react-native");
664
+
665
+ // src/preview/components/OnDeviceUI/addons/List.tsx
666
+ var import_react6 = __toESM(require("react"));
667
+
668
+ // src/preview/components/Shared/tabs.tsx
669
+ var import_react5 = __toESM(require("react"));
670
+ var import_react_native5 = require("react-native");
671
+ var import_react_native_theming3 = require("@storybook/react-native-theming");
672
+ var import_react_native_theming4 = require("@storybook/react-native-theming");
673
+ var import_jsx_runtime5 = require("react/jsx-runtime");
674
+ var TabButtonText = import_react_native_theming3.styled.Text(({ theme: theme3, active }) => ({
675
+ color: active ? theme3.tabs.activeTextColor : theme3.tabs.inactiveTextColor,
676
+ paddingVertical: theme3.tabs.paddingVertical,
677
+ paddingHorizontal: theme3.tabs.paddingHorizontal,
678
+ fontSize: theme3.tabs.fontSize,
679
+ fontWeight: theme3.tabs.fontWeight
680
+ }));
681
+ var hitSlop = { top: 8, left: 0, right: 0, bottom: 20 };
682
+ var TabButtonTouchable = import_react_native_theming3.styled.TouchableOpacity(({ theme: theme3, active }) => ({
683
+ borderWidth: theme3.tabs.borderWidth,
684
+ borderColor: active ? theme3.tabs.activeBorderColor : theme3.tabs.inactiveBorderColor,
685
+ borderRadius: theme3.tabs.borderRadius,
686
+ backgroundColor: active ? theme3.tabs.activeBackgroundColor : theme3.tabs.inactiveBackgroundColor
687
+ }));
688
+ var TabButton = import_react5.default.memo(({ onPress, id, active, children, testID }) => {
689
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
690
+ TabButtonTouchable,
691
+ {
692
+ active,
693
+ testID,
694
+ onPress: () => onPress(id),
695
+ activeOpacity: 0.8,
696
+ hitSlop,
697
+ children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(TabButtonText, { active, children })
698
+ }
699
+ );
700
+ });
701
+ var TabBar = import_react5.default.memo(({ scrollable = false, style, children }) => {
702
+ const theme3 = (0, import_react_native_theming4.useTheme)();
703
+ if (scrollable) {
704
+ children = /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
705
+ import_react_native5.ScrollView,
706
+ {
707
+ showsHorizontalScrollIndicator: false,
708
+ horizontal: true,
709
+ contentContainerStyle: { paddingHorizontal: theme3.tokens.spacing2 },
710
+ children
711
+ }
712
+ );
713
+ }
714
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react_native5.View, { style, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(TabBarContainer, { children }) });
715
+ });
716
+ var TabBarContainer = import_react_native_theming3.styled.View(() => ({
717
+ flexDirection: "row",
718
+ paddingVertical: 6,
719
+ justifyItems: "center"
720
+ }));
721
+
722
+ // src/preview/components/OnDeviceUI/addons/List.tsx
723
+ var import_jsx_runtime6 = require("react/jsx-runtime");
724
+ var AddonList = ({ panels, addonSelected, onPressAddon }) => {
725
+ const addonKeys = Object.keys(panels);
726
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(TabBar, { scrollable: true, children: addonKeys.map((id) => {
727
+ const { title } = panels[id];
728
+ const resolvedTitle = typeof title === "function" ? title() : title;
729
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
730
+ TabButton,
731
+ {
732
+ active: id === addonSelected,
733
+ id,
734
+ onPress: () => onPressAddon(id),
735
+ children: resolvedTitle.toUpperCase()
736
+ },
737
+ id
738
+ );
739
+ }) });
740
+ };
741
+ var List_default = import_react6.default.memo(AddonList);
742
+
743
+ // src/preview/components/OnDeviceUI/addons/Wrapper.tsx
744
+ var import_react7 = __toESM(require("react"));
745
+ var import_react_native6 = require("react-native");
746
+ var import_react_native_theming5 = require("@storybook/react-native-theming");
747
+ var import_jsx_runtime7 = require("react/jsx-runtime");
748
+ var Container = import_react_native_theming5.styled.View(({ selected }) => ({
749
+ display: selected ? "flex" : "none",
750
+ flex: 1
751
+ }));
752
+ var Wrapper = ({ panels, addonSelected }) => {
753
+ useUpdateOnStoryChanged();
754
+ const theme3 = (0, import_react_native_theming5.useTheme)();
755
+ const addonKeys = Object.keys(panels);
756
+ const content = addonKeys.map((id) => {
757
+ const selected = addonSelected === id;
758
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Container, { selected, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_react_native6.ScrollView, { contentContainerStyle: { padding: theme3.panel.paddingHorizontal }, children: panels[id].render({ active: selected, key: id }) }) }, id);
759
+ });
760
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_jsx_runtime7.Fragment, { children: content });
761
+ };
762
+ var Wrapper_default = import_react7.default.memo(Wrapper);
763
+
764
+ // src/preview/components/OnDeviceUI/addons/Addons.tsx
765
+ var import_jsx_runtime8 = require("react/jsx-runtime");
766
+ var Text3 = import_react_native_theming6.styled.Text(({ theme: theme3 }) => ({
767
+ marginTop: theme3.tokens.spacing4
768
+ }));
769
+ var Addons = ({ active }) => {
770
+ const panels = import_addons2.addons.getElements("panel");
771
+ const [addonSelected, setAddonSelected] = useSelectedAddon(Object.keys(panels)[0]);
772
+ const context = useStoryContext();
773
+ const id = context?.id;
774
+ if (!id) {
775
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_react_native7.View, { style: { alignItems: "center", justifyContent: "center" }, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Text3, { children: "No Story Selected" }) });
776
+ }
777
+ if (Object.keys(panels).length === 0) {
778
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_react_native7.View, { style: { alignItems: "center", justifyContent: "center" }, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Text3, { children: "No addons loaded." }) });
779
+ }
780
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_react_native7.View, { style: { flex: 1 }, children: [
781
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
782
+ List_default,
783
+ {
784
+ onPressAddon: setAddonSelected,
785
+ panels,
786
+ addonSelected: active ? addonSelected : null
787
+ }
788
+ ),
789
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Wrapper_default, { addonSelected: active ? addonSelected : null, panels })
790
+ ] });
35
791
  };
36
- exports.storiesOf = storiesOf;
37
- exports.getStorybookUI = view.getStorybookUI;
38
- __exportStar(require("./types/types-6.0"), exports);
39
- // @storybook/addon-storyshots v6 needs global.__STORYBOOK_STORY_STORE__.initializationPromise
792
+ var Addons_default = import_react8.default.memo(Addons);
793
+
794
+ // src/preview/components/OnDeviceUI/addons/AddonsSkeleton.tsx
795
+ var import_react9 = __toESM(require("react"));
796
+ var import_react_native_theming7 = require("@storybook/react-native-theming");
797
+ var import_react_native8 = require("react-native");
798
+ var import_jsx_runtime9 = require("react/jsx-runtime");
799
+ var AddonsSkeleton = import_react9.default.memo(function AddonsSkeleton2({ visible }) {
800
+ const progress = import_react9.default.useRef(new import_react_native8.Animated.Value(visible ? 1 : 0));
801
+ import_react9.default.useEffect(() => {
802
+ import_react_native8.Animated.timing(progress.current, {
803
+ toValue: visible ? 1 : 0,
804
+ duration: ANIMATION_DURATION_TRANSITION,
805
+ useNativeDriver: true,
806
+ easing: import_react_native8.Easing.inOut(import_react_native8.Easing.cubic)
807
+ }).start();
808
+ }, [visible]);
809
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(AddonsSkeletonContainer, { pointerEvents: "none", style: { opacity: progress.current }, children: [
810
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(TabsSkeleton, {}),
811
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(AddonsContentSkeleton, {})
812
+ ] });
813
+ });
814
+ var TabSkeleton = import_react_native_theming7.styled.View(({ theme: theme3, active }) => ({
815
+ opacity: active ? 1 : 0.5,
816
+ backgroundColor: active ? theme3.tabs.activeBackgroundColor : theme3.tokens.color.grey200,
817
+ borderRadius: theme3.tokens.borderRadius.round,
818
+ width: active ? 100 : 70,
819
+ height: 30,
820
+ marginRight: 12
821
+ }));
822
+ var BoxSkeleton = import_react_native_theming7.styled.View(
823
+ ({ theme: theme3, width, height, marginBottom }) => ({
824
+ backgroundColor: theme3.tokens.color.blue200,
825
+ borderRadius: theme3.tokens.borderRadius.large,
826
+ height,
827
+ marginBottom,
828
+ width
829
+ })
830
+ );
831
+ function AddonsFieldSkeleton({ long = false }) {
832
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_react_native8.View, { style: { marginBottom: 32 }, children: [
833
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(BoxSkeleton, { width: 75, height: 10, marginBottom: 12 }),
834
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(BoxSkeleton, { width: long ? 200 : 120, height: 15 })
835
+ ] });
836
+ }
837
+ function AddonsContentSkeleton() {
838
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_jsx_runtime9.Fragment, { children: [
839
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(AddonsFieldSkeleton, { long: true }),
840
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(AddonsFieldSkeleton, { long: true }),
841
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(AddonsFieldSkeleton, {}),
842
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(AddonsFieldSkeleton, {})
843
+ ] });
844
+ }
845
+ function TabsSkeleton() {
846
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_react_native8.View, { style: { flexDirection: "row", marginBottom: 16 }, children: [
847
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(TabSkeleton, {}),
848
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(TabSkeleton, { active: true }),
849
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(TabSkeleton, {})
850
+ ] });
851
+ }
852
+ var AddonsSkeletonContainer = (0, import_react_native_theming7.styled)(import_react_native8.Animated.View)(
853
+ ({ theme: theme3 }) => ({
854
+ ...import_react_native8.StyleSheet.absoluteFillObject,
855
+ flex: 1,
856
+ backgroundColor: theme3.panel.backgroundColor,
857
+ borderTopWidth: theme3.panel.borderWidth,
858
+ borderColor: theme3.panel.borderColor,
859
+ padding: theme3.panel.paddingHorizontal,
860
+ overflow: "hidden"
861
+ })
862
+ );
863
+
864
+ // src/preview/components/OnDeviceUI/animation.ts
865
+ var import_react_native9 = require("react-native");
866
+
867
+ // src/preview/components/OnDeviceUI/navigation/constants.ts
868
+ var SIDEBAR = -1;
869
+ var CANVAS = 0;
870
+ var ADDONS = 1;
871
+
872
+ // src/preview/components/OnDeviceUI/animation.ts
873
+ var RTL_SCALE = import_react_native9.I18nManager.isRTL ? -1 : 1;
874
+ var PREVIEW_SCALE = 0.3;
875
+ var PREVIEW_SCALE_WIDE = 0.7;
876
+ var PREVIEW_SCALE_SHRINK = 0.9;
877
+ var SCALE_OFFSET = 0.025;
878
+ var TRANSLATE_Y_OFFSET = 12;
879
+ var panelWidth = (width, wide) => {
880
+ const scale = wide ? PREVIEW_SCALE_WIDE : PREVIEW_SCALE;
881
+ return width * (1 - scale - SCALE_OFFSET);
882
+ };
883
+ var getSidebarPanelPosition = (animatedValue, previewWidth, wide) => {
884
+ return [
885
+ {
886
+ transform: [
887
+ {
888
+ translateX: animatedValue.interpolate({
889
+ inputRange: [SIDEBAR, CANVAS],
890
+ outputRange: [0, (-panelWidth(previewWidth, wide) - 1) * RTL_SCALE]
891
+ })
892
+ }
893
+ ],
894
+ width: panelWidth(previewWidth, wide)
895
+ }
896
+ ];
897
+ };
898
+ var getAddonPanelPosition = (animatedValue, previewWidth, wide) => {
899
+ return [
900
+ {
901
+ transform: [
902
+ {
903
+ translateX: animatedValue.interpolate({
904
+ inputRange: [CANVAS, ADDONS],
905
+ outputRange: [
906
+ previewWidth * RTL_SCALE,
907
+ (previewWidth - panelWidth(previewWidth, wide)) * RTL_SCALE
908
+ ]
909
+ })
910
+ }
911
+ ],
912
+ width: panelWidth(previewWidth, wide)
913
+ }
914
+ ];
915
+ };
916
+ var getPreviewStyle = ({
917
+ animatedValue,
918
+ previewDimensions: { width: previewWidth, height: previewHeight },
919
+ wide,
920
+ insets,
921
+ tabOpen,
922
+ lastTabOpen
923
+ }) => {
924
+ const scale = (wide ? PREVIEW_SCALE_WIDE : PREVIEW_SCALE) * PREVIEW_SCALE_SHRINK;
925
+ const scaledPreviewWidth = previewWidth * scale;
926
+ const scaledPreviewHeight = previewHeight * scale;
927
+ const nonPanelWidth = previewWidth - panelWidth(previewWidth, wide);
928
+ const translateXOffset = (nonPanelWidth - scaledPreviewWidth) / 2;
929
+ const translateX = (previewWidth / 2 - previewWidth * scale / 2 - translateXOffset) * RTL_SCALE;
930
+ const translateY = -(previewHeight / 2 - scaledPreviewHeight / 2) + insets.top + TRANSLATE_Y_OFFSET;
931
+ const skipPreview = lastTabOpen !== CANVAS && tabOpen !== CANVAS;
932
+ return {
933
+ transform: [
934
+ {
935
+ translateX: animatedValue.interpolate({
936
+ inputRange: [SIDEBAR, CANVAS, ADDONS],
937
+ outputRange: [translateX, 0, -translateX]
938
+ })
939
+ },
940
+ {
941
+ translateY: animatedValue.interpolate({
942
+ inputRange: [SIDEBAR, CANVAS, ADDONS],
943
+ outputRange: [translateY, skipPreview ? translateY : 0, translateY]
944
+ })
945
+ },
946
+ {
947
+ scale: animatedValue.interpolate({
948
+ inputRange: [SIDEBAR, CANVAS, ADDONS],
949
+ outputRange: [scale, skipPreview ? scale : 1, scale]
950
+ })
951
+ }
952
+ ]
953
+ };
954
+ };
955
+ var getPreviewShadowStyle = (animatedValue) => ({
956
+ elevation: 8,
957
+ shadowColor: "#000",
958
+ shadowOpacity: animatedValue.interpolate({
959
+ inputRange: [SIDEBAR, CANVAS, ADDONS],
960
+ outputRange: [0.25, 0, 0.25]
961
+ }),
962
+ shadowRadius: 8,
963
+ shadowOffset: { width: 0, height: 0 },
964
+ overflow: "visible"
965
+ });
966
+
967
+ // src/preview/components/OnDeviceUI/navigation/Navigation.tsx
968
+ var import_react11 = __toESM(require("react"));
969
+ var import_react_native11 = require("react-native");
970
+ var import_react_native_safe_area_context = require("react-native-safe-area-context");
971
+ var import_react_native_swipe_gestures = __toESM(require("react-native-swipe-gestures"));
972
+
973
+ // src/preview/components/OnDeviceUI/navigation/NavigationBar.tsx
974
+ var import_react10 = __toESM(require("react"));
975
+ var import_react_native_theming8 = require("@storybook/react-native-theming");
976
+ var import_jsx_runtime10 = require("react/jsx-runtime");
977
+ var NavigationTabBar = (0, import_react_native_theming8.styled)(TabBar)(({ theme: theme3 }) => ({
978
+ paddingHorizontal: theme3.tokens.spacing2,
979
+ backgroundColor: theme3.navigation.backgroundColor,
980
+ borderColor: theme3.navigation.borderColor,
981
+ borderTopWidth: theme3.navigation.borderWidth
982
+ }));
983
+ var NavigationBar = import_react10.default.memo(({ index, onPress, style }) => /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(NavigationTabBar, { style, children: [
984
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
985
+ TabButton,
986
+ {
987
+ onPress,
988
+ testID: "BottomMenu.Sidebar",
989
+ id: SIDEBAR,
990
+ active: index === SIDEBAR,
991
+ children: "SIDEBAR"
992
+ }
993
+ ),
994
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(TabButton, { onPress, testID: "BottomMenu.Canvas", id: CANVAS, active: index === CANVAS, children: "CANVAS" }),
995
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(TabButton, { onPress, testID: "BottomMenu.Addons", id: ADDONS, active: index === ADDONS, children: "ADDONS" })
996
+ ] }));
997
+
998
+ // src/preview/components/OnDeviceUI/navigation/NavigationButton.tsx
999
+ var import_react_native10 = require("react-native");
1000
+ var import_jsx_runtime11 = require("react/jsx-runtime");
1001
+ var hitSlop2 = { top: 5, left: 5, right: 5, bottom: 5 };
1002
+ function NavigationButton({ iconName, inverseIconName, active, toggle }) {
1003
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_react_native10.TouchableWithoutFeedback, { onPress: toggle, hitSlop: hitSlop2, children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_react_native10.View, { style: { marginHorizontal: 8 }, children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(BackgroundIcon, { style: { flex: 1, opacity: 0.8 }, name: inverseIconName, children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Icon, { name: iconName, style: { opacity: active ? 0.6 : 0.25 } }) }) }) });
1004
+ }
1005
+ function VisibilityButton() {
1006
+ const [active, toggle] = useIsUIVisible();
1007
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1008
+ NavigationButton,
1009
+ {
1010
+ iconName: "layout-bottom",
1011
+ inverseIconName: "layout-bottom-inverse",
1012
+ active,
1013
+ toggle: () => toggle()
1014
+ }
1015
+ );
1016
+ }
1017
+ function AddonsSplitButton() {
1018
+ const [active, toggle] = useIsSplitPanelVisible();
1019
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1020
+ NavigationButton,
1021
+ {
1022
+ iconName: "layout-split",
1023
+ inverseIconName: "layout-split-inverse",
1024
+ active,
1025
+ toggle: () => toggle()
1026
+ }
1027
+ );
1028
+ }
1029
+
1030
+ // src/preview/components/OnDeviceUI/navigation/Navigation.tsx
1031
+ var import_jsx_runtime12 = require("react/jsx-runtime");
1032
+ var SWIPE_CONFIG = {
1033
+ velocityThreshold: 0.2,
1034
+ directionalOffsetThreshold: 80
1035
+ };
1036
+ var navStyle = {
1037
+ position: "absolute",
1038
+ left: 0,
1039
+ right: 0,
1040
+ bottom: 0
1041
+ };
1042
+ var Navigation = ({ tabOpen, onChangeTab, onLayout }) => {
1043
+ const insets = (0, import_react_native_safe_area_context.useSafeAreaInsets)();
1044
+ const handleSwipeLeft = () => {
1045
+ if (tabOpen < 1) {
1046
+ onChangeTab(tabOpen + 1);
1047
+ }
1048
+ };
1049
+ const handleSwipeRight = () => {
1050
+ if (tabOpen > -1) {
1051
+ onChangeTab(tabOpen - 1);
1052
+ }
1053
+ };
1054
+ const [isUIVisible] = useIsUIVisible();
1055
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_react_native11.View, { style: navStyle, onLayout, children: [
1056
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_react_native11.View, { children: isUIVisible && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
1057
+ import_react_native_swipe_gestures.default,
1058
+ {
1059
+ onSwipeLeft: handleSwipeLeft,
1060
+ onSwipeRight: handleSwipeRight,
1061
+ config: SWIPE_CONFIG,
1062
+ children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
1063
+ NavigationBar,
1064
+ {
1065
+ index: tabOpen,
1066
+ onPress: onChangeTab,
1067
+ style: { paddingBottom: insets.bottom }
1068
+ }
1069
+ )
1070
+ }
1071
+ ) }),
1072
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(NavigationShortcuts, { children: [
1073
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(VisibilityButton, {}),
1074
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(AddonsSplitButton, {})
1075
+ ] })
1076
+ ] });
1077
+ };
1078
+ var Navigation_default = import_react11.default.memo(Navigation);
1079
+ function NavigationShortcuts({ children }) {
1080
+ const insets = (0, import_react_native_safe_area_context.useSafeAreaInsets)();
1081
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
1082
+ import_react_native11.View,
1083
+ {
1084
+ style: {
1085
+ zIndex: 100,
1086
+ alignSelf: "center",
1087
+ justifyContent: "center",
1088
+ alignItems: "center",
1089
+ flexDirection: "row-reverse",
1090
+ position: "absolute",
1091
+ bottom: insets.bottom + 14,
1092
+ right: 8
1093
+ },
1094
+ children
1095
+ }
1096
+ );
1097
+ }
1098
+
1099
+ // src/preview/components/OnDeviceUI/Panel.tsx
1100
+ var import_react12 = __toESM(require("react"));
1101
+ var import_react_native12 = require("react-native");
1102
+ var import_react_native_theming9 = require("@storybook/react-native-theming");
1103
+ var import_jsx_runtime13 = require("react/jsx-runtime");
1104
+ var Container2 = (0, import_react_native_theming9.styled)(import_react_native12.Animated.View)(({ theme: theme3, edge }) => ({
1105
+ backgroundColor: theme3.panel.backgroundColor,
1106
+ borderTopWidth: edge === "top" ? theme3.panel.borderWidth : void 0,
1107
+ borderStartWidth: edge === "left" ? theme3.panel.borderWidth : void 0,
1108
+ borderEndWidth: edge === "right" ? theme3.panel.borderWidth : void 0,
1109
+ borderColor: theme3.panel.borderColor
1110
+ }));
1111
+ var Panel = ({ edge, children, style }) => {
1112
+ const containerStyle = import_react_native12.StyleSheet.flatten([
1113
+ edge === "top" ? void 0 : import_react_native12.StyleSheet.absoluteFillObject,
1114
+ style
1115
+ ]);
1116
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Container2, { edge, style: containerStyle, children });
1117
+ };
1118
+ var Panel_default = import_react12.default.memo(Panel);
1119
+
1120
+ // src/preview/components/OnDeviceUI/OnDeviceUI.tsx
1121
+ var import_react_native14 = require("react-native");
1122
+ var import_react_native_safe_area_context2 = require("react-native-safe-area-context");
1123
+ var import_react_native_theming11 = require("@storybook/react-native-theming");
1124
+ var import_jsx_runtime14 = require("react/jsx-runtime");
1125
+ var IS_IOS = import_react_native13.Platform.OS === "ios";
1126
+ var getExpoRoot = () => global.Expo || global.__expo || global.__exponent;
1127
+ var IS_EXPO = getExpoRoot() !== void 0;
1128
+ var IS_ANDROID = import_react_native13.Platform.OS === "android";
1129
+ var BREAKPOINT = 1024;
1130
+ var flex = { flex: 1 };
1131
+ function Preview({ animatedValue, style, children }) {
1132
+ const theme3 = (0, import_react_native_theming11.useTheme)();
1133
+ const containerStyle = {
1134
+ backgroundColor: theme3.preview.backgroundColor,
1135
+ ...getPreviewShadowStyle(animatedValue)
1136
+ };
1137
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_react_native13.Animated.View, { style: [flex, containerStyle], children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_react_native13.View, { style: [flex, style], children }) });
1138
+ }
1139
+ var styles3 = import_react_native13.StyleSheet.create({
1140
+ expoAndroidContainer: { paddingTop: import_react_native13.StatusBar.currentHeight }
1141
+ });
1142
+ var Container3 = import_react_native_theming10.styled.View(({ theme: theme3 }) => ({
1143
+ flex: 1,
1144
+ backgroundColor: theme3.preview.containerBackgroundColor,
1145
+ ...IS_ANDROID && IS_EXPO ? styles3.expoAndroidContainer : void 0,
1146
+ ...import_react_native13.Platform.select({ web: { overflow: "hidden" } })
1147
+ }));
1148
+ var OnDeviceUI = ({
1149
+ storyIndex,
1150
+ shouldDisableKeyboardAvoidingView,
1151
+ keyboardAvoidingViewVerticalOffset,
1152
+ tabOpen: initialTabOpen
1153
+ }) => {
1154
+ const [tabOpen, setTabOpen] = (0, import_react13.useState)(initialTabOpen || CANVAS);
1155
+ const lastTabOpen = import_react13.default.useRef(tabOpen);
1156
+ const [previewDimensions, setPreviewDimensions] = (0, import_react13.useState)(() => ({
1157
+ width: import_react_native13.Dimensions.get("window").width,
1158
+ height: import_react_native13.Dimensions.get("window").height
1159
+ }));
1160
+ const animatedValue = (0, import_react13.useRef)(new import_react_native13.Animated.Value(tabOpen));
1161
+ const wide = (0, import_react_native14.useWindowDimensions)().width >= BREAKPOINT;
1162
+ const insets = (0, import_react_native_safe_area_context2.useSafeAreaInsets)();
1163
+ const handleToggleTab = import_react13.default.useCallback(
1164
+ (newTabOpen) => {
1165
+ if (newTabOpen === tabOpen) {
1166
+ return;
1167
+ }
1168
+ lastTabOpen.current = tabOpen;
1169
+ import_react_native13.Animated.timing(animatedValue.current, {
1170
+ toValue: newTabOpen,
1171
+ duration: ANIMATION_DURATION_TRANSITION,
1172
+ easing: import_react_native13.Easing.inOut(import_react_native13.Easing.cubic),
1173
+ useNativeDriver: true
1174
+ }).start();
1175
+ setTabOpen(newTabOpen);
1176
+ if (newTabOpen === CANVAS) {
1177
+ import_react_native13.Keyboard.dismiss();
1178
+ }
1179
+ },
1180
+ [tabOpen]
1181
+ );
1182
+ const noSafeArea = useStoryContextParam("noSafeArea", false);
1183
+ const previewWrapperStyles = [
1184
+ flex,
1185
+ getPreviewStyle({
1186
+ animatedValue: animatedValue.current,
1187
+ previewDimensions,
1188
+ wide,
1189
+ insets,
1190
+ tabOpen,
1191
+ lastTabOpen: lastTabOpen.current
1192
+ })
1193
+ ];
1194
+ const [isUIVisible] = useIsUIVisible();
1195
+ const [navBarHeight, setNavBarHeight] = import_react13.default.useState(insets.bottom + 40);
1196
+ const measureNavigation = import_react13.default.useCallback(
1197
+ ({ nativeEvent }) => {
1198
+ const inset = insets.bottom;
1199
+ setNavBarHeight(isUIVisible ? nativeEvent.layout.height - inset : 0);
1200
+ },
1201
+ [isUIVisible, insets]
1202
+ );
1203
+ const safeAreaMargins = {
1204
+ paddingBottom: isUIVisible ? insets.bottom + navBarHeight : noSafeArea ? 0 : insets.bottom,
1205
+ paddingTop: !noSafeArea ? insets.top : 0,
1206
+ overflow: "hidden"
1207
+ };
1208
+ const panelSafeAreaMargins = {
1209
+ paddingBottom: insets.bottom + navBarHeight,
1210
+ paddingTop: insets.top
1211
+ };
1212
+ const keyboardVerticalOffset = -panelSafeAreaMargins.paddingBottom + (keyboardAvoidingViewVerticalOffset ?? 0);
1213
+ const [isSplitPanelVisible] = useIsSplitPanelVisible();
1214
+ const isPreviewInactive = tabOpen !== CANVAS;
1215
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_jsx_runtime14.Fragment, { children: /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(Container3, { children: [
1216
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
1217
+ import_react_native13.KeyboardAvoidingView,
1218
+ {
1219
+ enabled: !shouldDisableKeyboardAvoidingView || isPreviewInactive,
1220
+ behavior: IS_IOS ? "padding" : null,
1221
+ keyboardVerticalOffset,
1222
+ style: flex,
1223
+ children: /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
1224
+ absolute_positioned_keyboard_aware_view_default,
1225
+ {
1226
+ onLayout: setPreviewDimensions,
1227
+ previewDimensions,
1228
+ children: [
1229
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_react_native13.Animated.View, { style: previewWrapperStyles, children: [
1230
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(Preview, { style: safeAreaMargins, animatedValue: animatedValue.current, children: [
1231
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(StoryView_default, {}),
1232
+ isSplitPanelVisible ? /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(Panel_default, { edge: "top", style: { flex: 1 }, children: [
1233
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(Addons_default, { active: true }),
1234
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(AddonsSkeleton, { visible: isPreviewInactive })
1235
+ ] }) : null
1236
+ ] }),
1237
+ isPreviewInactive ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
1238
+ import_react_native13.TouchableOpacity,
1239
+ {
1240
+ style: import_react_native13.StyleSheet.absoluteFillObject,
1241
+ onPress: () => handleToggleTab(CANVAS)
1242
+ }
1243
+ ) : null
1244
+ ] }),
1245
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
1246
+ Panel_default,
1247
+ {
1248
+ edge: "right",
1249
+ style: [
1250
+ getSidebarPanelPosition(animatedValue.current, previewDimensions.width, wide),
1251
+ panelSafeAreaMargins
1252
+ ],
1253
+ children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(StoryListView_default, { storyIndex })
1254
+ }
1255
+ ),
1256
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
1257
+ Panel_default,
1258
+ {
1259
+ edge: "left",
1260
+ style: [
1261
+ getAddonPanelPosition(animatedValue.current, previewDimensions.width, wide),
1262
+ panelSafeAreaMargins
1263
+ ],
1264
+ children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(Addons_default, { active: tabOpen === ADDONS })
1265
+ }
1266
+ )
1267
+ ]
1268
+ }
1269
+ )
1270
+ }
1271
+ ),
1272
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(Navigation_default, { onLayout: measureNavigation, tabOpen, onChangeTab: handleToggleTab })
1273
+ ] }) });
1274
+ };
1275
+ var OnDeviceUI_default = import_react13.default.memo(OnDeviceUI);
1276
+
1277
+ // src/preview/View.tsx
1278
+ var import_react_native_theming13 = require("@storybook/react-native-theming");
1279
+ var import_channel_websocket = __toESM(require("@storybook/channel-websocket"));
1280
+
1281
+ // src/preview/rn-host-detect.js
1282
+ function getByRemoteConfig(hostname) {
1283
+ var remoteModuleConfig = window?.__fbBatchedBridgeConfig?.remoteModuleConfig;
1284
+ if (!Array.isArray(remoteModuleConfig) || hostname !== "localhost" && hostname !== "127.0.0.1") {
1285
+ return { hostname, passed: false };
1286
+ }
1287
+ var constants = (remoteModuleConfig.find(getConstants) || [])[1];
1288
+ if (constants) {
1289
+ var serverHost = constants.ServerHost || hostname;
1290
+ return { hostname: serverHost.split(":")[0], passed: true };
1291
+ }
1292
+ return { hostname, passed: false };
1293
+ }
1294
+ function getConstants(config) {
1295
+ return config && (config[0] === "AndroidConstants" || config[0] === "PlatformConstants");
1296
+ }
1297
+ function getByRNRequirePolyfill(hostname) {
1298
+ var NativeModules;
1299
+ var PlatformConstants;
1300
+ var AndroidConstants;
1301
+ if (typeof window === "undefined" || !window.__DEV__ || typeof window.require !== "function" || // RN >= 0.56
1302
+ // TODO: Get NativeModules for RN >= 0.56
1303
+ window.require.name === "metroRequire") {
1304
+ return hostname;
1305
+ }
1306
+ NativeModules = window.require("NativeModules");
1307
+ if (!NativeModules || !NativeModules.PlatformConstants && !NativeModules.AndroidConstants) {
1308
+ return hostname;
1309
+ }
1310
+ PlatformConstants = NativeModules.PlatformConstants;
1311
+ AndroidConstants = NativeModules.AndroidConstants;
1312
+ var serverHost = (PlatformConstants ? PlatformConstants.ServerHost : AndroidConstants.ServerHost) || hostname;
1313
+ return serverHost.split(":")[0];
1314
+ }
1315
+ function getHost(hostname) {
1316
+ if (typeof __fbBatchedBridge !== "object" || hostname !== "localhost" && hostname !== "127.0.0.1") {
1317
+ return hostname;
1318
+ }
1319
+ var result = getByRemoteConfig(hostname);
1320
+ if (result.passed) {
1321
+ return result.hostname;
1322
+ }
1323
+ return getByRNRequirePolyfill(hostname);
1324
+ }
1325
+
1326
+ // src/preview/View.tsx
1327
+ var import_core_events2 = __toESM(require("@storybook/core-events"));
1328
+ var import_react_native15 = require("react-native");
1329
+ var import_deepmerge = __toESM(require("deepmerge"));
1330
+ var import_jsx_runtime15 = require("react/jsx-runtime");
1331
+ var STORAGE_KEY = "lastOpenedStory";
1332
+ var View10 = class {
1333
+ _storyIndex;
1334
+ _setStory = () => {
1335
+ };
1336
+ _forceRerender;
1337
+ _ready = false;
1338
+ _preview;
1339
+ _asyncStorageStoryId;
1340
+ _webUrl;
1341
+ constructor(preview) {
1342
+ this._preview = preview;
1343
+ }
1344
+ _getInitialStory = async ({
1345
+ initialSelection,
1346
+ shouldPersistSelection = true
1347
+ } = {}) => {
1348
+ if (initialSelection) {
1349
+ if (typeof initialSelection === "string") {
1350
+ return { storySpecifier: initialSelection, viewMode: "story" };
1351
+ } else {
1352
+ return {
1353
+ storySpecifier: (0, import_csf.toId)(initialSelection.kind, initialSelection.name),
1354
+ viewMode: "story"
1355
+ };
1356
+ }
1357
+ }
1358
+ if (shouldPersistSelection) {
1359
+ try {
1360
+ let value = this._asyncStorageStoryId;
1361
+ if (!value) {
1362
+ value = await import_async_storage.default.getItem(STORAGE_KEY);
1363
+ this._asyncStorageStoryId = value;
1364
+ }
1365
+ return { storySpecifier: value ?? "*", viewMode: "story" };
1366
+ } catch (e) {
1367
+ console.warn("storybook-log: error reading from async storage", e);
1368
+ }
1369
+ }
1370
+ return { storySpecifier: "*", viewMode: "story" };
1371
+ };
1372
+ _getServerChannel = (params = {}) => {
1373
+ const host = getHost(params.host || "localhost");
1374
+ const port = `:${params.port || 7007}`;
1375
+ const query = params.query || "";
1376
+ const websocketType = params.secured ? "wss" : "ws";
1377
+ const url = `${websocketType}://${host}${port}/${query}`;
1378
+ return (0, import_channel_websocket.default)({
1379
+ url,
1380
+ async: true,
1381
+ onError: async () => {
1382
+ }
1383
+ });
1384
+ };
1385
+ getStorybookUI = (params = {}) => {
1386
+ const { shouldPersistSelection = true, onDeviceUI = true, enableWebsockets = false } = params;
1387
+ const initialStory = this._getInitialStory(params);
1388
+ if (enableWebsockets) {
1389
+ const channel = this._getServerChannel(params);
1390
+ import_addons3.addons.setChannel(channel);
1391
+ this._preview.channel = channel;
1392
+ this._preview.setupListeners();
1393
+ channel.emit(import_core_events2.default.CHANNEL_CREATED);
1394
+ this._preview.initializeWithStoryIndex(this._storyIndex);
1395
+ }
1396
+ import_addons3.addons.loadAddons({
1397
+ store: () => ({
1398
+ fromId: (id) => this._preview.storyStore.getStoryContext(this._preview.storyStore.fromId(id)),
1399
+ getSelection: () => {
1400
+ return this._preview.currentSelection;
1401
+ },
1402
+ _channel: this._preview.channel
1403
+ })
1404
+ });
1405
+ const self = this;
1406
+ syncExternalUI({
1407
+ isUIVisible: params.isUIHidden !== void 0 ? !params.isUIHidden : void 0,
1408
+ isSplitPanelVisible: params.isSplitPanelVisible
1409
+ });
1410
+ return () => {
1411
+ const setContext = useSetStoryContext();
1412
+ const colorScheme = (0, import_react_native15.useColorScheme)();
1413
+ const [, forceUpdate] = (0, import_react14.useReducer)((x) => x + 1, 0);
1414
+ const appliedTheme = (0, import_react14.useMemo)(
1415
+ () => (0, import_deepmerge.default)(colorScheme === "dark" ? import_react_native_theming13.darkTheme : import_react_native_theming13.theme, params.theme ?? {}),
1416
+ [colorScheme]
1417
+ );
1418
+ (0, import_react14.useEffect)(() => {
1419
+ self._setStory = (newStory) => {
1420
+ setContext(newStory);
1421
+ if (shouldPersistSelection) {
1422
+ import_async_storage.default.setItem(STORAGE_KEY, newStory.id).catch((e) => {
1423
+ console.warn("storybook-log: error writing to async storage", e);
1424
+ });
1425
+ }
1426
+ };
1427
+ self._forceRerender = () => forceUpdate();
1428
+ initialStory.then((story) => {
1429
+ self._preview.urlStore.selectionSpecifier = story;
1430
+ self._preview.selectSpecifiedStory();
1431
+ });
1432
+ }, []);
1433
+ if (onDeviceUI) {
1434
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_react_native_safe_area_context3.SafeAreaProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_react_native_theming12.ThemeProvider, { theme: appliedTheme, children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
1435
+ OnDeviceUI_default,
1436
+ {
1437
+ storyIndex: self._storyIndex,
1438
+ tabOpen: params.tabOpen,
1439
+ shouldDisableKeyboardAvoidingView: params.shouldDisableKeyboardAvoidingView,
1440
+ keyboardAvoidingViewVerticalOffset: params.keyboardAvoidingViewVerticalOffset
1441
+ }
1442
+ ) }) });
1443
+ } else {
1444
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(StoryView_default, {});
1445
+ }
1446
+ };
1447
+ };
1448
+ };
1449
+
1450
+ // src/preview/start.tsx
1451
+ var import_jsx_runtime16 = require("react/jsx-runtime");
1452
+ var render = (args, context) => {
1453
+ const { id, component: Component } = context;
1454
+ if (!Component) {
1455
+ throw new Error(
1456
+ `Unable to render story ${id} as the component annotation is missing from the default export`
1457
+ );
1458
+ }
1459
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(Component, { ...args });
1460
+ };
1461
+ function start() {
1462
+ const channel = new import_channels.default({ async: true });
1463
+ import_addons4.addons.setChannel(channel);
1464
+ const clientApi2 = new import_client_api.ClientApi();
1465
+ const previewView = {
1466
+ prepareForStory: () => null,
1467
+ showNoPreview: () => {
1468
+ },
1469
+ showPreparingStory: () => {
1470
+ },
1471
+ applyLayout: () => {
1472
+ },
1473
+ showErrorDisplay: (e) => {
1474
+ console.log(e);
1475
+ },
1476
+ showStoryDuringRender: () => {
1477
+ },
1478
+ showMain: () => {
1479
+ },
1480
+ checkIfLayoutExists: () => {
1481
+ },
1482
+ showStory: () => {
1483
+ },
1484
+ docsRoot: null,
1485
+ prepareForDocs: () => null,
1486
+ showDocs: () => {
1487
+ },
1488
+ preparingTimeout: setTimeout(() => {
1489
+ }, 0),
1490
+ showMode: () => {
1491
+ },
1492
+ showPreparingDocs: () => {
1493
+ },
1494
+ storyRoot: null,
1495
+ testing: false
1496
+ };
1497
+ const urlStore = {
1498
+ selection: null,
1499
+ selectionSpecifier: null,
1500
+ setQueryParams: () => {
1501
+ },
1502
+ setSelection: (selection) => {
1503
+ preview.urlStore.selection = selection;
1504
+ }
1505
+ };
1506
+ const preview = new import_preview_web.PreviewWeb(urlStore, previewView);
1507
+ clientApi2.storyStore = preview.storyStore;
1508
+ (0, import_client_api.setGlobalRender)(render);
1509
+ let initialized = false;
1510
+ function onStoriesChanged() {
1511
+ const storyIndex = clientApi2.getStoryIndex();
1512
+ preview.onStoriesChanged({ storyIndex });
1513
+ view2._storyIndex = storyIndex;
1514
+ }
1515
+ const view2 = new View10(preview);
1516
+ return {
1517
+ view: view2,
1518
+ forceReRender: () => channel.emit(import_core_events3.default.FORCE_RE_RENDER),
1519
+ clientApi: clientApi2,
1520
+ preview,
1521
+ // This gets called each time the user calls configure (i.e. once per HMR)
1522
+ // The first time, it constructs thecurrentSelection preview, subsequently it updates it
1523
+ configure(loadable, m) {
1524
+ clientApi2.addParameters({ framework: "react-native" });
1525
+ const getProjectAnnotations = () => {
1526
+ const { added, removed } = executeLoadableForChanges(loadable, m);
1527
+ Array.from(added.entries()).forEach(
1528
+ ([fileName, fileExports]) => clientApi2.facade.addStoriesFromExports(fileName, fileExports)
1529
+ );
1530
+ Array.from(removed.entries()).forEach(
1531
+ ([fileName]) => clientApi2.facade.clearFilenameExports(fileName)
1532
+ );
1533
+ return {
1534
+ ...clientApi2.facade.projectAnnotations,
1535
+ renderToDOM: (context) => {
1536
+ view2._setStory(context.storyContext);
1537
+ }
1538
+ };
1539
+ };
1540
+ const importFn = (path) => clientApi2.importFn(path);
1541
+ if (!initialized) {
1542
+ preview.initialize({
1543
+ getStoryIndex: () => {
1544
+ const index = clientApi2.getStoryIndex();
1545
+ view2._storyIndex = index;
1546
+ return index;
1547
+ },
1548
+ importFn,
1549
+ getProjectAnnotations
1550
+ });
1551
+ initialized = true;
1552
+ } else {
1553
+ getProjectAnnotations();
1554
+ onStoriesChanged();
1555
+ }
1556
+ }
1557
+ };
1558
+ }
1559
+
1560
+ // src/index.ts
1561
+ var import_react_native_theming14 = require("@storybook/react-native-theming");
1562
+ var { clientApi, configure, view } = start();
1563
+ var rawStoriesOf = clientApi.storiesOf.bind(clientApi);
1564
+ var setAddon = clientApi.setAddon.bind(clientApi);
1565
+ var addDecorator = clientApi.addDecorator.bind(clientApi);
1566
+ var addParameters = clientApi.addParameters.bind(clientApi);
1567
+ var addArgsEnhancer = clientApi.addArgsEnhancer.bind(clientApi);
1568
+ var addArgTypesEnhancer = clientApi.addArgTypesEnhancer.bind(clientApi);
1569
+ var clearDecorators = clientApi.clearDecorators.bind(clientApi);
1570
+ var getStorybook = clientApi.getStorybook.bind(clientApi);
1571
+ var raw = clientApi.raw.bind(clientApi);
1572
+ var storiesOf = (kind, _module) => rawStoriesOf(kind, { hot: () => {
1573
+ } }).addParameters({
1574
+ framework: "react-native"
1575
+ });
1576
+ var getStorybookUI = view.getStorybookUI;
40
1577
  global.__STORYBOOK_STORY_STORE__ = {
41
- initializationPromise: (_a = clientApi.storyStore) === null || _a === void 0 ? void 0 : _a.initializationPromise,
1578
+ initializationPromise: clientApi.storyStore?.initializationPromise
42
1579
  };
43
- var react_native_theming_1 = require("@storybook/react-native-theming");
44
- Object.defineProperty(exports, "theme", { enumerable: true, get: function () { return react_native_theming_1.theme; } });
45
- Object.defineProperty(exports, "darkTheme", { enumerable: true, get: function () { return react_native_theming_1.darkTheme; } });
1580
+ // Annotate the CommonJS export names for ESM import in node:
1581
+ 0 && (module.exports = {
1582
+ addArgTypesEnhancer,
1583
+ addArgsEnhancer,
1584
+ addDecorator,
1585
+ addParameters,
1586
+ clearDecorators,
1587
+ configure,
1588
+ darkTheme,
1589
+ getStorybook,
1590
+ getStorybookUI,
1591
+ raw,
1592
+ setAddon,
1593
+ storiesOf,
1594
+ theme
1595
+ });