@storybook/react-native-ui 10.4.4 → 10.5.0-canary-20260606223917

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.js CHANGED
@@ -37,8 +37,8 @@ let _gorhom_portal = require("@gorhom/portal");
37
37
  let react_native_gesture_handler = require("react-native-gesture-handler");
38
38
  let react_native_safe_area_context = require("react-native-safe-area-context");
39
39
  let storybook_internal_core_events = require("storybook/internal/core-events");
40
- let storybook_manager_api = require("storybook/manager-api");
41
40
  let storybook_internal_types = require("storybook/internal/types");
41
+ let storybook_manager_api = require("storybook/manager-api");
42
42
  let react_native_reanimated = require("react-native-reanimated");
43
43
  react_native_reanimated = __toESM(react_native_reanimated);
44
44
  //#region src/icon/ComponentIcon.tsx
@@ -1133,7 +1133,7 @@ const MenuIcon = ({ color = "currentColor", width = 14, height = 14, ...props })
1133
1133
  //#region src/MobileAddonsPanel.tsx
1134
1134
  const bottomSheetStyle = { paddingTop: 8 };
1135
1135
  const contentStyle = { flex: 1 };
1136
- const MobileAddonsPanel = (0, react.forwardRef)(({ storyId }, ref) => {
1136
+ const MobileAddonsPanel = (0, react.forwardRef)(({ storyId, parameters }, ref) => {
1137
1137
  const theme = (0, _storybook_react_native_theming.useTheme)();
1138
1138
  const reducedMotion = (0, react_native_reanimated.useReducedMotion)();
1139
1139
  const addonsPanelBottomSheetRef = (0, react.useRef)(null);
@@ -1188,7 +1188,8 @@ const MobileAddonsPanel = (0, react.forwardRef)(({ storyId }, ref) => {
1188
1188
  onClose: () => {
1189
1189
  addonsPanelBottomSheetRef.current?.dismiss();
1190
1190
  },
1191
- storyId
1191
+ storyId,
1192
+ parameters
1192
1193
  })
1193
1194
  })
1194
1195
  });
@@ -1219,14 +1220,18 @@ const hitSlop = {
1219
1220
  bottom: 10,
1220
1221
  left: 10
1221
1222
  };
1222
- const AddonsTabs = ({ onClose, storyId }) => {
1223
- const panels = storybook_manager_api.addons.getElements(storybook_internal_types.Addon_TypesEnum.PANEL);
1223
+ const AddonsTabs = ({ onClose, storyId, parameters }) => {
1224
+ const panels = (0, react.useMemo)(() => {
1225
+ const allPanels = storybook_manager_api.addons.getElements(storybook_internal_types.Addon_TypesEnum.PANEL);
1226
+ return Object.fromEntries(Object.entries(allPanels).filter(([, p]) => !p.paramKey || !parameters?.[p.paramKey]?.disable));
1227
+ }, [parameters]);
1224
1228
  const [addonSelected, setAddonSelected] = (0, react.useState)(Object.keys(panels)[0]);
1225
1229
  const insets = (0, react_native_safe_area_context.useSafeAreaInsets)();
1226
1230
  const scrollContentContainerStyle = (0, _storybook_react_native_ui_common.useStyle)(() => {
1227
1231
  return { paddingBottom: insets.bottom + 16 };
1228
1232
  });
1229
1233
  const panelEntries = (0, react.useMemo)(() => Object.entries(panels), [panels]);
1234
+ const activeAddonId = panels[addonSelected] ? addonSelected : panelEntries[0]?.[0];
1230
1235
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_native.View, {
1231
1236
  style: addonsTabsContainerStyle,
1232
1237
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_native.View, {
@@ -1238,7 +1243,7 @@ const AddonsTabs = ({ onClose, storyId }) => {
1238
1243
  children: Object.values(panels).map(({ id, title }) => {
1239
1244
  const resolvedTitle = typeof title === "function" ? title({}) : title;
1240
1245
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Tab, {
1241
- active: id === addonSelected,
1246
+ active: id === activeAddonId,
1242
1247
  onPress: () => setAddonSelected(id),
1243
1248
  text: String(resolvedTitle)
1244
1249
  }, id);
@@ -1259,7 +1264,7 @@ const AddonsTabs = ({ onClose, storyId }) => {
1259
1264
  style: centeredStyle,
1260
1265
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native.Text, { children: "No addons loaded." })
1261
1266
  }) : panelEntries.map(([id, p]) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native.View, {
1262
- style: id === addonSelected ? void 0 : hiddenStyle,
1267
+ style: id === activeAddonId ? void 0 : hiddenStyle,
1263
1268
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(PanelRenderer, { panel: p })
1264
1269
  }, id))
1265
1270
  })]
@@ -1607,6 +1612,10 @@ const Layout = ({ storyHash, story, storyBackgroundColor, children }) => {
1607
1612
  const { isDesktop } = (0, _storybook_react_native_ui_common.useLayout)();
1608
1613
  const [desktopSidebarOpen, setDesktopSidebarOpen] = (0, _storybook_react_native_ui_common.useStoreBooleanState)("desktopSidebarState", true);
1609
1614
  const [desktopAddonsPanelOpen, setDesktopAddonsPanelOpen] = (0, _storybook_react_native_ui_common.useStoreBooleanState)("desktopPanelState", true);
1615
+ const hasEnabledPanels = (0, react.useMemo)(() => {
1616
+ const allPanels = storybook_manager_api.addons.getElements(storybook_internal_types.Addon_TypesEnum.PANEL);
1617
+ return Object.values(allPanels).some((p) => !p.paramKey || !story?.parameters?.[p.paramKey]?.disable);
1618
+ }, [story?.parameters]);
1610
1619
  const [uiHidden, setUiHidden] = (0, react.useState)(false);
1611
1620
  (0, react.useLayoutEffect)(() => {
1612
1621
  setUiHidden(story?.parameters?.storybookUIVisibility === "hidden");
@@ -1716,10 +1725,11 @@ const Layout = ({ storyHash, story, storyBackgroundColor, children }) => {
1716
1725
  onPress: () => setUiHidden((prev) => !prev),
1717
1726
  children: uiHidden ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(CloseFullscreenIcon, { color: theme.color.mediumdark }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(FullscreenIcon, { color: theme.color.mediumdark })
1718
1727
  }),
1719
- isDesktop ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native.View, {
1728
+ isDesktop && hasEnabledPanels ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native.View, {
1720
1729
  style: desktopAddonsPanelStyle,
1721
1730
  children: desktopAddonsPanelOpen ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(AddonsTabs, {
1722
1731
  storyId: story?.id,
1732
+ parameters: story?.parameters,
1723
1733
  onClose: () => setDesktopAddonsPanelOpen(false)
1724
1734
  }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_storybook_react_native_ui_common.IconButton, {
1725
1735
  style: iconFloatRightStyle,
@@ -1745,7 +1755,7 @@ const Layout = ({ storyHash, story, storyBackgroundColor, children }) => {
1745
1755
  story?.name
1746
1756
  ]
1747
1757
  })]
1748
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_storybook_react_native_ui_common.IconButton, {
1758
+ }), hasEnabledPanels && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_storybook_react_native_ui_common.IconButton, {
1749
1759
  testID: "mobile-addons-button",
1750
1760
  onPress: () => addonPanelRef.current.setAddonsPanelOpen(true),
1751
1761
  Icon: BottomBarToggleIcon
@@ -1767,9 +1777,10 @@ const Layout = ({ storyHash, story, storyBackgroundColor, children }) => {
1767
1777
  refId: DEFAULT_REF_ID
1768
1778
  })]
1769
1779
  }) }) : null,
1770
- !isDesktop ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(MobileAddonsPanel, {
1780
+ !isDesktop && hasEnabledPanels ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(MobileAddonsPanel, {
1771
1781
  ref: addonPanelRef,
1772
- storyId: story?.id
1782
+ storyId: story?.id,
1783
+ parameters: story?.parameters
1773
1784
  }) : null
1774
1785
  ]
1775
1786
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@storybook/react-native-ui",
3
- "version": "10.4.4",
3
+ "version": "10.5.0-canary-20260606223917",
4
4
  "description": "ui components for react native storybook",
5
5
  "keywords": [
6
6
  "react",
@@ -30,14 +30,14 @@
30
30
  "dependencies": {
31
31
  "@gorhom/portal": "^1.0.14",
32
32
  "@nozbe/microfuzz": "^1.0.0",
33
- "@storybook/react": "^10.4.0",
34
- "@storybook/react-native-theming": "^10.4.4",
35
- "@storybook/react-native-ui-common": "^10.4.4",
33
+ "@storybook/react": "^10.4.2",
34
+ "@storybook/react-native-theming": "10.5.0-canary-20260606223917",
35
+ "@storybook/react-native-ui-common": "10.5.0-canary-20260606223917",
36
36
  "polished": "^4.3.1"
37
37
  },
38
38
  "devDependencies": {
39
39
  "@types/react": "~19.2.14",
40
- "storybook": "^10.4.0",
40
+ "storybook": "^10.4.2",
41
41
  "tsdown": "^0.22.0",
42
42
  "typescript": "~6.0.3"
43
43
  },
package/src/Layout.tsx CHANGED
@@ -11,13 +11,18 @@ import {
11
11
  useStyle,
12
12
  type SBUI,
13
13
  } from '@storybook/react-native-ui-common';
14
- import { ReactNode, useCallback, useLayoutEffect, useRef, useState } from 'react';
14
+ import { ReactNode, useCallback, useLayoutEffect, useMemo, useRef, useState } from 'react';
15
15
  import { ScrollView, Text, TouchableOpacity, View, ViewStyle } from 'react-native';
16
16
  import { GestureHandlerRootView } from 'react-native-gesture-handler';
17
17
  import { SafeAreaProvider, useSafeAreaInsets } from 'react-native-safe-area-context';
18
18
  import { SET_CURRENT_STORY } from 'storybook/internal/core-events';
19
19
  import type { Args, StoryContext } from 'storybook/internal/csf';
20
- import type { API_IndexHash } from 'storybook/internal/types';
20
+ import {
21
+ Addon_TypesEnum,
22
+ type Addon_BaseType,
23
+ type Addon_Collection,
24
+ type API_IndexHash,
25
+ } from 'storybook/internal/types';
21
26
  import { addons } from 'storybook/manager-api';
22
27
  import { DEFAULT_REF_ID } from './constants';
23
28
  import { BottomBarToggleIcon } from './icon/BottomBarToggleIcon';
@@ -117,6 +122,14 @@ export const Layout = ({
117
122
  true
118
123
  );
119
124
 
125
+ const hasEnabledPanels = useMemo(() => {
126
+ const allPanels: Addon_Collection<Addon_BaseType> = addons.getElements(Addon_TypesEnum.PANEL);
127
+
128
+ return Object.values(allPanels).some(
129
+ (p) => !p.paramKey || !story?.parameters?.[p.paramKey]?.disable
130
+ );
131
+ }, [story?.parameters]);
132
+
120
133
  const [uiHidden, setUiHidden] = useState(false);
121
134
 
122
135
  useLayoutEffect(() => {
@@ -270,10 +283,14 @@ export const Layout = ({
270
283
  </TouchableOpacity>
271
284
  )}
272
285
 
273
- {isDesktop ? (
286
+ {isDesktop && hasEnabledPanels ? (
274
287
  <View style={desktopAddonsPanelStyle}>
275
288
  {desktopAddonsPanelOpen ? (
276
- <AddonsTabs storyId={story?.id} onClose={() => setDesktopAddonsPanelOpen(false)} />
289
+ <AddonsTabs
290
+ storyId={story?.id}
291
+ parameters={story?.parameters}
292
+ onClose={() => setDesktopAddonsPanelOpen(false)}
293
+ />
277
294
  ) : (
278
295
  <IconButton
279
296
  style={iconFloatRightStyle}
@@ -300,11 +317,13 @@ export const Layout = ({
300
317
  </Text>
301
318
  </Button>
302
319
 
303
- <IconButton
304
- testID="mobile-addons-button"
305
- onPress={() => addonPanelRef.current.setAddonsPanelOpen(true)}
306
- Icon={BottomBarToggleIcon}
307
- />
320
+ {hasEnabledPanels && (
321
+ <IconButton
322
+ testID="mobile-addons-button"
323
+ onPress={() => addonPanelRef.current.setAddonsPanelOpen(true)}
324
+ Icon={BottomBarToggleIcon}
325
+ />
326
+ )}
308
327
  </Nav>
309
328
  </Container>
310
329
  ) : null}
@@ -330,7 +349,9 @@ export const Layout = ({
330
349
  </SelectedNodeProvider>
331
350
  ) : null}
332
351
 
333
- {!isDesktop ? <MobileAddonsPanel ref={addonPanelRef} storyId={story?.id} /> : null}
352
+ {!isDesktop && hasEnabledPanels ? (
353
+ <MobileAddonsPanel ref={addonPanelRef} storyId={story?.id} parameters={story?.parameters} />
354
+ ) : null}
334
355
  </View>
335
356
  );
336
357
  };
@@ -1,6 +1,7 @@
1
1
  import { BottomSheetModal } from '@gorhom/bottom-sheet';
2
2
  import { addons } from 'storybook/manager-api';
3
3
  import { styled, useTheme } from '@storybook/react-native-theming';
4
+ import type { Parameters } from 'storybook/internal/csf';
4
5
  import {
5
6
  Addon_TypesEnum,
6
7
  type Addon_BaseType,
@@ -31,8 +32,10 @@ const contentStyle = {
31
32
  flex: 1,
32
33
  } satisfies StyleProp<ViewStyle>;
33
34
 
34
- export const MobileAddonsPanel = forwardRef<MobileAddonsPanelRef, { storyId?: string }>(
35
- ({ storyId }, ref) => {
35
+ type MobileAddonsPanelProps = { storyId?: string; parameters?: Parameters };
36
+
37
+ export const MobileAddonsPanel = forwardRef<MobileAddonsPanelRef, MobileAddonsPanelProps>(
38
+ ({ storyId, parameters }, ref) => {
36
39
  const theme = useTheme();
37
40
  const reducedMotion = useReducedMotion();
38
41
 
@@ -103,6 +106,7 @@ export const MobileAddonsPanel = forwardRef<MobileAddonsPanelRef, { storyId?: st
103
106
  addonsPanelBottomSheetRef.current?.dismiss();
104
107
  }}
105
108
  storyId={storyId}
109
+ parameters={parameters}
106
110
  />
107
111
  </Animated.View>
108
112
  </BottomSheetModal>
@@ -148,8 +152,22 @@ const hiddenStyle = {
148
152
 
149
153
  const hitSlop = { top: 10, right: 10, bottom: 10, left: 10 };
150
154
 
151
- export const AddonsTabs = ({ onClose, storyId }: { onClose?: () => void; storyId?: string }) => {
152
- const panels: Addon_Collection<Addon_BaseType> = addons.getElements(Addon_TypesEnum.PANEL);
155
+ export const AddonsTabs = ({
156
+ onClose,
157
+ storyId,
158
+ parameters,
159
+ }: {
160
+ onClose?: () => void;
161
+ storyId?: string;
162
+ parameters?: Parameters;
163
+ }) => {
164
+ const panels = useMemo<Addon_Collection<Addon_BaseType>>(() => {
165
+ const allPanels: Addon_Collection<Addon_BaseType> = addons.getElements(Addon_TypesEnum.PANEL);
166
+
167
+ return Object.fromEntries(
168
+ Object.entries(allPanels).filter(([, p]) => !p.paramKey || !parameters?.[p.paramKey]?.disable)
169
+ );
170
+ }, [parameters]);
153
171
 
154
172
  const [addonSelected, setAddonSelected] = useState(Object.keys(panels)[0]);
155
173
 
@@ -162,6 +180,7 @@ export const AddonsTabs = ({ onClose, storyId }: { onClose?: () => void; storyId
162
180
  });
163
181
 
164
182
  const panelEntries = useMemo(() => Object.entries(panels), [panels]);
183
+ const activeAddonId = panels[addonSelected] ? addonSelected : panelEntries[0]?.[0];
165
184
 
166
185
  return (
167
186
  <View style={addonsTabsContainerStyle}>
@@ -177,7 +196,7 @@ export const AddonsTabs = ({ onClose, storyId }: { onClose?: () => void; storyId
177
196
  return (
178
197
  <Tab
179
198
  key={id}
180
- active={id === addonSelected}
199
+ active={id === activeAddonId}
181
200
  onPress={() => setAddonSelected(id)}
182
201
  text={String(resolvedTitle)}
183
202
  />
@@ -207,7 +226,7 @@ export const AddonsTabs = ({ onClose, storyId }: { onClose?: () => void; storyId
207
226
  </View>
208
227
  ) : (
209
228
  panelEntries.map(([id, p]) => (
210
- <View key={id} style={id === addonSelected ? undefined : hiddenStyle}>
229
+ <View key={id} style={id === activeAddonId ? undefined : hiddenStyle}>
211
230
  <PanelRenderer panel={p} />
212
231
  </View>
213
232
  ))
@@ -13,7 +13,7 @@ import {
13
13
  useMemo,
14
14
  useRef,
15
15
  } from 'react';
16
- import { Keyboard, Platform } from 'react-native';
16
+ import { Keyboard, Platform, type ViewStyle } from 'react-native';
17
17
  import { useAnimatedStyle, useReducedMotion } from 'react-native-reanimated';
18
18
  import { useSafeAreaInsets } from 'react-native-safe-area-context';
19
19
  import { useSelectedNode } from './SelectedNodeProvider';
@@ -44,7 +44,7 @@ export const BottomSheetBackdropComponent = (backdropComponentProps: BottomSheet
44
44
  pressBehavior={'close'}
45
45
  style={[
46
46
  backdropComponentProps.style,
47
- androidTouchEventFix,
47
+ androidTouchEventFix as unknown as ViewStyle,
48
48
  {
49
49
  backgroundColor: 'rgba(0,0,0,0.5)',
50
50
  paddingTop: Platform.OS === 'android' ? 1 : undefined,