@storybook/react-native-ui 8.3.0-alpha.1 → 8.3.0-alpha.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -175,8 +175,6 @@ declare const ButtonIcon: ({ Icon, active, variant, }: {
175
175
  declare const IconButton: React$1.ForwardRefExoticComponent<ButtonProps & React$1.RefAttributes<TouchableOpacity>>;
176
176
 
177
177
  type LayoutContextType = {
178
- openMobileMenu: () => void;
179
- closeMobileMenu: () => void;
180
178
  isDesktop: boolean;
181
179
  isMobile: boolean;
182
180
  };
package/dist/index.js CHANGED
@@ -3034,7 +3034,7 @@ var BranchNode = import_react_native_theming2.styled.TouchableOpacity(({ depth =
3034
3034
  alignItems: "flex-start",
3035
3035
  alignSelf: "flex-start",
3036
3036
  paddingLeft: (isExpandable ? 8 : 22) + depth * 18,
3037
- background: "transparent",
3037
+ backgroundColor: "transparent",
3038
3038
  minHeight: 28,
3039
3039
  borderRadius: 4,
3040
3040
  gap: 6,
@@ -3042,7 +3042,7 @@ var BranchNode = import_react_native_theming2.styled.TouchableOpacity(({ depth =
3042
3042
  paddingBottom: 4,
3043
3043
  // will this actually do anything?
3044
3044
  "&:hover, &:focus": {
3045
- background: (0, import_polished.transparentize)(0.93, theme.color.secondary),
3045
+ backgroundColor: (0, import_polished.transparentize)(0.93, theme.color.secondary),
3046
3046
  outline: "none"
3047
3047
  }
3048
3048
  }));
@@ -3291,64 +3291,31 @@ IconButton.displayName = "IconButton";
3291
3291
 
3292
3292
  // src/LayoutProvider.tsx
3293
3293
  var import_react4 = require("react");
3294
+ var import_react_native = require("react-native");
3294
3295
 
3295
3296
  // src/constants.ts
3296
- var BREAKPOINT = 600;
3297
+ var BREAKPOINT = 1e3;
3297
3298
  var MEDIA_DESKTOP_BREAKPOINT = `@media (min-width: ${BREAKPOINT}px)`;
3298
3299
  var DEFAULT_REF_ID = "storybook_internal";
3299
3300
 
3300
3301
  // src/LayoutProvider.tsx
3301
- var import_react_native = require("react-native");
3302
- var import_jsx_runtime8 = (
3303
- // <BottomSheetModalProvider>
3304
- require("react/jsx-runtime")
3305
- );
3302
+ var import_jsx_runtime8 = require("react/jsx-runtime");
3306
3303
  var LayoutContext = (0, import_react4.createContext)({
3307
- // isMobileMenuOpen: false,
3308
- openMobileMenu: () => {
3309
- },
3310
- closeMobileMenu: () => {
3311
- },
3312
- // isMobileAboutOpen: false,
3313
- // setMobileAboutOpen: () => {},
3314
- // isMobilePanelOpen: false,
3315
- // setMobilePanelOpen: () => {},
3316
3304
  isDesktop: false,
3317
- isMobile: false
3305
+ isMobile: true
3318
3306
  });
3319
3307
  var LayoutProvider = ({ children }) => {
3320
3308
  const { width } = (0, import_react_native.useWindowDimensions)();
3321
3309
  const isDesktop = width >= BREAKPOINT;
3322
3310
  const isMobile = !isDesktop;
3323
- const openMobileMenu = (0, import_react4.useCallback)(() => {
3324
- }, []);
3325
- const closeMobileMenu = (0, import_react4.useCallback)(() => {
3326
- }, []);
3327
3311
  const contextValue = (0, import_react4.useMemo)(
3328
3312
  () => ({
3329
- // isMobileMenuOpen,
3330
- openMobileMenu,
3331
- closeMobileMenu,
3332
- // isMobileAboutOpen,
3333
- // setMobileAboutOpen,
3334
- // isMobilePanelOpen,
3335
- // setMobilePanelOpen,
3336
3313
  isDesktop,
3337
3314
  isMobile
3338
3315
  }),
3339
- [
3340
- // isMobileMenuOpen,
3341
- openMobileMenu,
3342
- closeMobileMenu,
3343
- // // isMobileAboutOpen,
3344
- // setMobileAboutOpen,
3345
- // isMobilePanelOpen,
3346
- // setMobilePanelOpen,
3347
- isDesktop,
3348
- isMobile
3349
- ]
3316
+ [isDesktop, isMobile]
3350
3317
  );
3351
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_jsx_runtime8.Fragment, { children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(LayoutContext.Provider, { value: contextValue, children }) });
3318
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(LayoutContext.Provider, { value: contextValue, children });
3352
3319
  };
3353
3320
  var useLayout = () => (0, import_react4.useContext)(LayoutContext);
3354
3321
 
@@ -3550,7 +3517,7 @@ var Node = import_react6.default.memo(function Node2({
3550
3517
  setExpanded,
3551
3518
  onSelectStoryId
3552
3519
  }) {
3553
- const { isDesktop, isMobile, closeMobileMenu } = useLayout();
3520
+ const { isDesktop } = useLayout();
3554
3521
  if (!isDisplayed) {
3555
3522
  return null;
3556
3523
  }
@@ -3565,8 +3532,6 @@ var Node = import_react6.default.memo(function Node2({
3565
3532
  depth: isOrphan ? item.depth : item.depth - 1,
3566
3533
  onPress: () => {
3567
3534
  onSelectStoryId(item.id);
3568
- if (isMobile)
3569
- closeMobileMenu();
3570
3535
  },
3571
3536
  children: item.renderLabel?.(item) || item.name
3572
3537
  },
@@ -3638,7 +3603,7 @@ var LeafNodeStyleWrapper = import_react_native_theming7.styled.View(({ theme })
3638
3603
  alignItems: "center",
3639
3604
  paddingRight: 20,
3640
3605
  color: theme.color.defaultText,
3641
- background: "transparent",
3606
+ backgroundColor: "transparent",
3642
3607
  minHeight: 28,
3643
3608
  borderRadius: 4
3644
3609
  }));
@@ -3934,54 +3899,31 @@ var import_react14 = __toESM(require("react"));
3934
3899
  var import_react_native_theming11 = require("@storybook/react-native-theming");
3935
3900
 
3936
3901
  // src/Search.tsx
3902
+ var import_bottom_sheet = require("@gorhom/bottom-sheet");
3937
3903
  var import_react_native_theming9 = require("@storybook/react-native-theming");
3938
3904
  var import_fuse = __toESM(require("fuse.js"));
3939
3905
  var import_react10 = __toESM(require("react"));
3906
+ var import_react_native3 = require("react-native");
3940
3907
 
3941
- // src/types.ts
3942
- function isExpandType(x2) {
3943
- return !!(x2 && x2.showAll);
3944
- }
3945
-
3946
- // src/icon/SearchIcon.tsx
3908
+ // src/icon/CloseIcon.tsx
3947
3909
  var import_react_native_svg8 = require("react-native-svg");
3948
3910
  var import_jsx_runtime15 = require("react/jsx-runtime");
3949
- var SearchIcon = ({
3950
- color = "currentColor",
3951
- width = 14,
3952
- height = 14,
3953
- ...props
3954
- }) => {
3955
- return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_react_native_svg8.Svg, { width, height, viewBox: "0 0 14 14", fill: "none", ...props, children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
3956
- import_react_native_svg8.Path,
3957
- {
3958
- fillRule: "evenodd",
3959
- clipRule: "evenodd",
3960
- d: "M9.544 10.206a5.5 5.5 0 11.662-.662.5.5 0 01.148.102l3 3a.5.5 0 01-.708.708l-3-3a.5.5 0 01-.102-.148zM10.5 6a4.5 4.5 0 11-9 0 4.5 4.5 0 019 0z",
3961
- fill: color
3962
- }
3963
- ) });
3964
- };
3965
-
3966
- // src/icon/CloseIcon.tsx
3967
- var import_react_native_svg9 = require("react-native-svg");
3968
- var import_jsx_runtime16 = require("react/jsx-runtime");
3969
3911
  var CloseIcon = ({
3970
3912
  color = "currentColor",
3971
3913
  width = 14,
3972
3914
  height = 14,
3973
3915
  ...props
3974
3916
  }) => {
3975
- return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_react_native_svg9.Svg, { width, height, viewBox: "0 0 14 14", fill: "none", ...props, children: [
3976
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
3977
- import_react_native_svg9.Path,
3917
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_react_native_svg8.Svg, { width, height, viewBox: "0 0 14 14", fill: "none", ...props, children: [
3918
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
3919
+ import_react_native_svg8.Path,
3978
3920
  {
3979
3921
  d: "M9.854 4.146a.5.5 0 010 .708L7.707 7l2.147 2.146a.5.5 0 01-.708.708L7 7.707 4.854 9.854a.5.5 0 01-.708-.708L6.293 7 4.146 4.854a.5.5 0 11.708-.708L7 6.293l2.146-2.147a.5.5 0 01.708 0z",
3980
3922
  fill: color
3981
3923
  }
3982
3924
  ),
3983
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
3984
- import_react_native_svg9.Path,
3925
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
3926
+ import_react_native_svg8.Path,
3985
3927
  {
3986
3928
  fillRule: "evenodd",
3987
3929
  clipRule: "evenodd",
@@ -3992,9 +3934,32 @@ var CloseIcon = ({
3992
3934
  ] });
3993
3935
  };
3994
3936
 
3937
+ // src/icon/SearchIcon.tsx
3938
+ var import_react_native_svg9 = require("react-native-svg");
3939
+ var import_jsx_runtime16 = require("react/jsx-runtime");
3940
+ var SearchIcon = ({
3941
+ color = "currentColor",
3942
+ width = 14,
3943
+ height = 14,
3944
+ ...props
3945
+ }) => {
3946
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_react_native_svg9.Svg, { width, height, viewBox: "0 0 14 14", fill: "none", ...props, children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
3947
+ import_react_native_svg9.Path,
3948
+ {
3949
+ fillRule: "evenodd",
3950
+ clipRule: "evenodd",
3951
+ d: "M9.544 10.206a5.5 5.5 0 11.662-.662.5.5 0 01.148.102l3 3a.5.5 0 01-.708.708l-3-3a.5.5 0 01-.102-.148zM10.5 6a4.5 4.5 0 11-9 0 4.5 4.5 0 019 0z",
3952
+ fill: color
3953
+ }
3954
+ ) });
3955
+ };
3956
+
3957
+ // src/types.ts
3958
+ function isExpandType(x2) {
3959
+ return !!(x2 && x2.showAll);
3960
+ }
3961
+
3995
3962
  // src/Search.tsx
3996
- var import_react_native3 = require("react-native");
3997
- var import_bottom_sheet = require("@gorhom/bottom-sheet");
3998
3963
  var import_jsx_runtime17 = require("react/jsx-runtime");
3999
3964
  var DEFAULT_MAX_SEARCH_RESULTS = 50;
4000
3965
  var options = {
@@ -4030,7 +3995,19 @@ var SearchField = import_react_native_theming9.styled.View({
4030
3995
  flexDirection: "column",
4031
3996
  position: "relative"
4032
3997
  });
4033
- var Input = (0, import_react_native_theming9.styled)(import_bottom_sheet.BottomSheetTextInput)(({ theme }) => ({
3998
+ var BottomSheetInput = (0, import_react_native_theming9.styled)(import_bottom_sheet.BottomSheetTextInput)(({ theme }) => ({
3999
+ height: 32,
4000
+ paddingLeft: 28,
4001
+ paddingRight: 28,
4002
+ borderWidth: 1,
4003
+ borderColor: theme.appBorderColor,
4004
+ backgroundColor: "transparent",
4005
+ borderRadius: 4,
4006
+ fontSize: theme.typography.size.s1 + 1,
4007
+ color: theme.color.defaultText,
4008
+ width: "100%"
4009
+ }));
4010
+ var Input = (0, import_react_native_theming9.styled)(import_react_native3.TextInput)(({ theme }) => ({
4034
4011
  height: 32,
4035
4012
  paddingLeft: 28,
4036
4013
  paddingRight: 28,
@@ -4060,10 +4037,12 @@ var Search = import_react10.default.memo(function Search2({ children, dataset, s
4060
4037
  const [inputValue, setInputValue] = (0, import_react10.useState)(initialQuery);
4061
4038
  const [isOpen, setIsOpen] = (0, import_react10.useState)(false);
4062
4039
  const [allComponents, showAllComponents] = (0, import_react10.useState)(false);
4040
+ const { isMobile } = useLayout();
4063
4041
  const selectStory = (0, import_react10.useCallback)(
4064
4042
  (id, refId) => {
4065
4043
  setSelection({ storyId: id, refId });
4066
4044
  inputRef.current?.blur();
4045
+ setIsOpen(false);
4067
4046
  showAllComponents(false);
4068
4047
  },
4069
4048
  [setSelection]
@@ -4156,15 +4135,15 @@ var Search = import_react10.default.memo(function Search2({ children, dataset, s
4156
4135
  return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(import_react_native3.View, { style: { flex: 1 }, children: [
4157
4136
  /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(SearchField, { children: [
4158
4137
  /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(SearchIconWrapper, { children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(SearchIcon, {}) }),
4159
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
4160
- Input,
4138
+ isMobile ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
4139
+ BottomSheetInput,
4161
4140
  {
4162
4141
  ref: inputRef,
4163
4142
  onChangeText: setInputValue,
4164
4143
  onFocus: () => setIsOpen(true),
4165
4144
  onBlur: () => setIsOpen(false)
4166
4145
  }
4167
- ),
4146
+ ) : /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(Input, { ref: inputRef, onChangeText: setInputValue, onFocus: () => setIsOpen(true) }),
4168
4147
  isOpen && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
4169
4148
  ClearIcon,
4170
4149
  {
@@ -4347,7 +4326,7 @@ var SearchResults = import_react11.default.memo(function SearchResults2({
4347
4326
  };
4348
4327
  return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(ResultsList, { children: [
4349
4328
  results.length > 0 && !query && /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(RecentlyOpenedTitle, { children: [
4350
- "Recently opened",
4329
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(Text, { children: "Recently opened" }),
4351
4330
  /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(IconButton, { onPress: handleClearLastViewed })
4352
4331
  ] }),
4353
4332
  results.length === 0 && query && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_react_native4.View, { children: /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(NoResults, { children: [
@@ -4434,7 +4413,7 @@ var Container2 = import_react_native_theming11.styled.View(({ theme }) => ({
4434
4413
  height: "100%",
4435
4414
  display: "flex",
4436
4415
  flexDirection: "column",
4437
- background: theme.background.content
4416
+ backgroundColor: theme.background.content
4438
4417
  }));
4439
4418
  var Top = import_react_native_theming11.styled.View({
4440
4419
  paddingLeft: 4,
@@ -4565,98 +4544,26 @@ var MenuIcon = ({
4565
4544
  ) });
4566
4545
  };
4567
4546
 
4568
- // src/MobileMenuDrawer.tsx
4547
+ // src/MobileAddonsPanel.tsx
4569
4548
  var import_bottom_sheet2 = require("@gorhom/bottom-sheet");
4549
+ var import_manager_api = require("@storybook/core/manager-api");
4550
+ var import_react_native_theming12 = require("@storybook/react-native-theming");
4551
+ var import_types3 = require("@storybook/core/types");
4570
4552
  var import_react15 = require("react");
4571
4553
  var import_react_native6 = require("react-native");
4572
- var import_react_native_reanimated = require("react-native-reanimated");
4554
+ var import_react_native_gesture_handler = require("react-native-gesture-handler");
4555
+ var import_react_native_reanimated = __toESM(require("react-native-reanimated"));
4573
4556
  var import_react_native_safe_area_context = require("react-native-safe-area-context");
4574
- var import_react_native_theming12 = require("@storybook/react-native-theming");
4575
- var import_jsx_runtime22 = require("react/jsx-runtime");
4576
- var BottomSheetBackdropComponent = (backdropComponentProps) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
4577
- import_bottom_sheet2.BottomSheetBackdrop,
4578
- {
4579
- ...backdropComponentProps,
4580
- appearsOnIndex: 0,
4581
- disappearsOnIndex: -1,
4582
- pressBehavior: "close",
4583
- style: [backdropComponentProps.style, { backgroundColor: "rgba(0,0,0,0.5)" }]
4584
- }
4585
- );
4586
- var MobileMenuDrawer = (0, import_react15.forwardRef)(
4587
- ({ children, onStateChange }, ref) => {
4588
- const reducedMotion = (0, import_react_native_reanimated.useReducedMotion)();
4589
- const insets = (0, import_react_native_safe_area_context.useSafeAreaInsets)();
4590
- const theme = (0, import_react_native_theming12.useTheme)();
4591
- const menuBottomSheetRef = (0, import_react15.useRef)(null);
4592
- (0, import_react15.useImperativeHandle)(ref, () => ({
4593
- setMobileMenuOpen: (open) => {
4594
- if (open) {
4595
- onStateChange(true);
4596
- menuBottomSheetRef.current?.present();
4597
- } else {
4598
- import_react_native6.Keyboard.dismiss();
4599
- onStateChange(false);
4600
- menuBottomSheetRef.current?.dismiss();
4601
- }
4602
- }
4603
- }));
4604
- return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
4605
- import_bottom_sheet2.BottomSheetModal,
4606
- {
4607
- ref: menuBottomSheetRef,
4608
- index: 1,
4609
- animateOnMount: !reducedMotion,
4610
- onDismiss: () => {
4611
- onStateChange(false);
4612
- },
4613
- snapPoints: ["50%", "75%"],
4614
- enableDismissOnClose: true,
4615
- enableHandlePanningGesture: true,
4616
- enableContentPanningGesture: true,
4617
- keyboardBehavior: "extend",
4618
- keyboardBlurBehavior: "restore",
4619
- stackBehavior: "replace",
4620
- backdropComponent: BottomSheetBackdropComponent,
4621
- backgroundStyle: { backgroundColor: theme.background.content },
4622
- handleIndicatorStyle: { backgroundColor: theme.textMutedColor },
4623
- children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
4624
- import_bottom_sheet2.BottomSheetScrollView,
4625
- {
4626
- keyboardShouldPersistTaps: "handled",
4627
- contentContainerStyle: {
4628
- paddingBottom: insets.bottom
4629
- },
4630
- children
4631
- }
4632
- )
4633
- }
4634
- );
4635
- }
4636
- );
4637
-
4638
- // src/MobileAddonsPanel.tsx
4639
- var import_bottom_sheet3 = require("@gorhom/bottom-sheet");
4640
- var import_manager_api = require("@storybook/core/manager-api");
4641
4557
  var import_react_native_theming13 = require("@storybook/react-native-theming");
4642
- var import_types3 = require("@storybook/core/types");
4643
- var import_react16 = require("react");
4644
- var import_react_native7 = require("react-native");
4645
- var import_react_native_gesture_handler = require("react-native-gesture-handler");
4646
- var import_react_native_reanimated2 = __toESM(require("react-native-reanimated"));
4647
- var import_react_native_safe_area_context2 = require("react-native-safe-area-context");
4648
- var import_react_native_theming14 = require("@storybook/react-native-theming");
4649
- var import_jsx_runtime23 = require("react/jsx-runtime");
4650
- var MobileAddonsPanel = (0, import_react16.forwardRef)(({ storyId, onStateChange }, ref) => {
4651
- const theme = (0, import_react_native_theming14.useTheme)();
4652
- const reducedMotion = (0, import_react_native_reanimated2.useReducedMotion)();
4653
- const addonsPanelBottomSheetRef = (0, import_react16.useRef)(null);
4654
- const insets = (0, import_react_native_safe_area_context2.useSafeAreaInsets)();
4655
- const panels = import_manager_api.addons.getElements(import_types3.Addon_TypesEnum.PANEL);
4656
- const [addonSelected, setAddonSelected] = (0, import_react16.useState)(Object.keys(panels)[0]);
4657
- const animatedPosition = (0, import_react_native_reanimated2.useSharedValue)(0);
4658
- (0, import_react_native_reanimated2.useAnimatedKeyboard)();
4659
- (0, import_react16.useImperativeHandle)(ref, () => ({
4558
+ var import_jsx_runtime22 = require("react/jsx-runtime");
4559
+ var MobileAddonsPanel = (0, import_react15.forwardRef)(({ storyId, onStateChange }, ref) => {
4560
+ const theme = (0, import_react_native_theming13.useTheme)();
4561
+ const reducedMotion = (0, import_react_native_reanimated.useReducedMotion)();
4562
+ const addonsPanelBottomSheetRef = (0, import_react15.useRef)(null);
4563
+ const insets = (0, import_react_native_safe_area_context.useSafeAreaInsets)();
4564
+ const animatedPosition = (0, import_react_native_reanimated.useSharedValue)(0);
4565
+ (0, import_react_native_reanimated.useAnimatedKeyboard)();
4566
+ (0, import_react15.useImperativeHandle)(ref, () => ({
4660
4567
  setAddonsPanelOpen: (open) => {
4661
4568
  if (open) {
4662
4569
  onStateChange(true);
@@ -4667,14 +4574,14 @@ var MobileAddonsPanel = (0, import_react16.forwardRef)(({ storyId, onStateChange
4667
4574
  }
4668
4575
  }
4669
4576
  }));
4670
- const { height } = (0, import_react_native7.useWindowDimensions)();
4671
- const adjustedBottomSheetSize = (0, import_react_native_reanimated2.useAnimatedStyle)(() => {
4577
+ const { height } = (0, import_react_native6.useWindowDimensions)();
4578
+ const adjustedBottomSheetSize = (0, import_react_native_reanimated.useAnimatedStyle)(() => {
4672
4579
  return {
4673
4580
  maxHeight: height - animatedPosition.value - insets.bottom
4674
4581
  };
4675
4582
  }, [animatedPosition.value, height, insets.bottom]);
4676
- return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
4677
- import_bottom_sheet3.BottomSheetModal,
4583
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
4584
+ import_bottom_sheet2.BottomSheetModal,
4678
4585
  {
4679
4586
  ref: addonsPanelBottomSheetRef,
4680
4587
  index: 1,
@@ -4699,80 +4606,86 @@ var MobileAddonsPanel = (0, import_react16.forwardRef)(({ storyId, onStateChange
4699
4606
  enableDismissOnClose: true,
4700
4607
  enableHandlePanningGesture: true,
4701
4608
  stackBehavior: "replace",
4702
- children: /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(import_react_native_reanimated2.default.View, { style: [{ flex: 1 }, adjustedBottomSheetSize], children: [
4703
- /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
4704
- import_react_native7.View,
4705
- {
4706
- style: { flexDirection: "row", borderBottomWidth: 1, borderBottomColor: "lightgrey" },
4707
- children: [
4708
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
4709
- import_react_native_gesture_handler.ScrollView,
4710
- {
4711
- horizontal: true,
4712
- showsHorizontalScrollIndicator: false,
4713
- contentContainerStyle: {
4714
- justifyContent: "center"
4715
- },
4716
- children: Object.values(panels).map(({ id, title }) => {
4717
- const resolvedTitle = typeof title === "function" ? title({}) : title;
4718
- return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
4719
- Tab,
4720
- {
4721
- active: id === addonSelected,
4722
- onPress: () => setAddonSelected(id),
4723
- text: resolvedTitle
4724
- },
4725
- id
4726
- );
4727
- })
4728
- }
4729
- ),
4730
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
4731
- IconButton,
4732
- {
4733
- style: {
4734
- marginRight: 4,
4735
- marginBottom: 4,
4736
- alignItems: "center",
4737
- justifyContent: "center"
4738
- },
4739
- hitSlop: { top: 10, right: 10, bottom: 10, left: 10 },
4740
- Icon: CloseIcon,
4741
- onPress: () => {
4742
- onStateChange(false);
4743
- addonsPanelBottomSheetRef.current?.dismiss();
4744
- }
4745
- }
4746
- )
4747
- ]
4748
- }
4749
- ),
4750
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
4751
- import_react_native_gesture_handler.ScrollView,
4752
- {
4753
- style: { flex: 1 },
4754
- contentContainerStyle: {
4755
- paddingBottom: insets.bottom + 16
4756
- },
4757
- children: (() => {
4758
- if (!storyId) {
4759
- return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_react_native7.View, { style: { alignItems: "center", justifyContent: "center" }, children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_react_native7.Text, { children: "No Story Selected" }) });
4760
- }
4761
- if (Object.keys(panels).length === 0) {
4762
- return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_react_native7.View, { style: { alignItems: "center", justifyContent: "center" }, children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_react_native7.Text, { children: "No addons loaded." }) });
4763
- }
4764
- return panels[addonSelected].render({ active: true });
4765
- })()
4766
- }
4767
- )
4768
- ] })
4609
+ children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_react_native_reanimated.default.View, { style: [{ flex: 1 }, adjustedBottomSheetSize], children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
4610
+ AddonsTabs,
4611
+ {
4612
+ onClose: () => {
4613
+ onStateChange(false);
4614
+ addonsPanelBottomSheetRef.current?.dismiss();
4615
+ },
4616
+ storyId
4617
+ }
4618
+ ) })
4769
4619
  }
4770
4620
  );
4771
4621
  });
4622
+ var AddonsTabs = ({ onClose, storyId }) => {
4623
+ const panels = import_manager_api.addons.getElements(import_types3.Addon_TypesEnum.PANEL);
4624
+ const [addonSelected, setAddonSelected] = (0, import_react15.useState)(Object.keys(panels)[0]);
4625
+ const insets = (0, import_react_native_safe_area_context.useSafeAreaInsets)();
4626
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(import_react_native6.View, { style: { flex: 1 }, children: [
4627
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(import_react_native6.View, { style: { flexDirection: "row", borderBottomWidth: 1, borderBottomColor: "lightgrey" }, children: [
4628
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
4629
+ import_react_native_gesture_handler.ScrollView,
4630
+ {
4631
+ horizontal: true,
4632
+ showsHorizontalScrollIndicator: false,
4633
+ contentContainerStyle: {
4634
+ justifyContent: "center"
4635
+ },
4636
+ children: Object.values(panels).map(({ id, title }) => {
4637
+ const resolvedTitle = typeof title === "function" ? title({}) : title;
4638
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
4639
+ Tab,
4640
+ {
4641
+ active: id === addonSelected,
4642
+ onPress: () => setAddonSelected(id),
4643
+ text: resolvedTitle
4644
+ },
4645
+ id
4646
+ );
4647
+ })
4648
+ }
4649
+ ),
4650
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
4651
+ IconButton,
4652
+ {
4653
+ style: {
4654
+ marginRight: 4,
4655
+ marginBottom: 4,
4656
+ alignItems: "center",
4657
+ justifyContent: "center"
4658
+ },
4659
+ hitSlop: { top: 10, right: 10, bottom: 10, left: 10 },
4660
+ Icon: CloseIcon,
4661
+ onPress: () => onClose?.()
4662
+ }
4663
+ )
4664
+ ] }),
4665
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
4666
+ import_react_native_gesture_handler.ScrollView,
4667
+ {
4668
+ style: { flex: 1 },
4669
+ contentContainerStyle: {
4670
+ paddingBottom: insets.bottom + 16
4671
+ },
4672
+ children: (() => {
4673
+ if (!storyId) {
4674
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_react_native6.View, { style: { alignItems: "center", justifyContent: "center" }, children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_react_native6.Text, { children: "No Story Selected" }) });
4675
+ }
4676
+ if (Object.keys(panels).length === 0) {
4677
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_react_native6.View, { style: { alignItems: "center", justifyContent: "center" }, children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_react_native6.Text, { children: "No addons loaded." }) });
4678
+ }
4679
+ return panels[addonSelected].render({ active: true });
4680
+ })()
4681
+ }
4682
+ )
4683
+ ] });
4684
+ };
4772
4685
  var Tab = ({ active, onPress, text }) => {
4773
- return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(TabButton, { active, onPress, children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(TabText, { active, children: text }) });
4686
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(TabButton, { active, onPress, children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(TabText, { active, children: text }) });
4774
4687
  };
4775
- var TabButton = import_react_native_theming13.styled.TouchableOpacity(({ theme, active }) => ({
4688
+ var TabButton = import_react_native_theming12.styled.TouchableOpacity(({ theme, active }) => ({
4776
4689
  borderBottomWidth: active ? 2 : 0,
4777
4690
  borderBottomColor: active ? theme.barSelectedColor : void 0,
4778
4691
  overflow: "hidden",
@@ -4780,7 +4693,7 @@ var TabButton = import_react_native_theming13.styled.TouchableOpacity(({ theme,
4780
4693
  justifyContent: "center",
4781
4694
  alignItems: "center"
4782
4695
  }));
4783
- var TabText = import_react_native_theming13.styled.Text(({ theme, active }) => ({
4696
+ var TabText = import_react_native_theming12.styled.Text(({ theme, active }) => ({
4784
4697
  color: active ? theme.barSelectedColor : theme.color.mediumdark,
4785
4698
  textAlign: "center",
4786
4699
  fontWeight: "bold",
@@ -4788,6 +4701,76 @@ var TabText = import_react_native_theming13.styled.Text(({ theme, active }) => (
4788
4701
  lineHeight: 12
4789
4702
  }));
4790
4703
 
4704
+ // src/MobileMenuDrawer.tsx
4705
+ var import_bottom_sheet3 = require("@gorhom/bottom-sheet");
4706
+ var import_react16 = require("react");
4707
+ var import_react_native7 = require("react-native");
4708
+ var import_react_native_reanimated2 = require("react-native-reanimated");
4709
+ var import_react_native_safe_area_context2 = require("react-native-safe-area-context");
4710
+ var import_react_native_theming14 = require("@storybook/react-native-theming");
4711
+ var import_jsx_runtime23 = require("react/jsx-runtime");
4712
+ var BottomSheetBackdropComponent = (backdropComponentProps) => /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
4713
+ import_bottom_sheet3.BottomSheetBackdrop,
4714
+ {
4715
+ ...backdropComponentProps,
4716
+ appearsOnIndex: 0,
4717
+ disappearsOnIndex: -1,
4718
+ pressBehavior: "close",
4719
+ style: [backdropComponentProps.style, { backgroundColor: "rgba(0,0,0,0.5)" }]
4720
+ }
4721
+ );
4722
+ var MobileMenuDrawer = (0, import_react16.forwardRef)(
4723
+ ({ children, onStateChange }, ref) => {
4724
+ const reducedMotion = (0, import_react_native_reanimated2.useReducedMotion)();
4725
+ const insets = (0, import_react_native_safe_area_context2.useSafeAreaInsets)();
4726
+ const theme = (0, import_react_native_theming14.useTheme)();
4727
+ const menuBottomSheetRef = (0, import_react16.useRef)(null);
4728
+ (0, import_react16.useImperativeHandle)(ref, () => ({
4729
+ setMobileMenuOpen: (open) => {
4730
+ if (open) {
4731
+ onStateChange(true);
4732
+ menuBottomSheetRef.current?.present();
4733
+ } else {
4734
+ import_react_native7.Keyboard.dismiss();
4735
+ onStateChange(false);
4736
+ menuBottomSheetRef.current?.dismiss();
4737
+ }
4738
+ }
4739
+ }));
4740
+ return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
4741
+ import_bottom_sheet3.BottomSheetModal,
4742
+ {
4743
+ ref: menuBottomSheetRef,
4744
+ index: 1,
4745
+ animateOnMount: !reducedMotion,
4746
+ onDismiss: () => {
4747
+ onStateChange(false);
4748
+ },
4749
+ snapPoints: ["50%", "75%"],
4750
+ enableDismissOnClose: true,
4751
+ enableHandlePanningGesture: true,
4752
+ enableContentPanningGesture: true,
4753
+ keyboardBehavior: "extend",
4754
+ keyboardBlurBehavior: "restore",
4755
+ stackBehavior: "replace",
4756
+ backdropComponent: BottomSheetBackdropComponent,
4757
+ backgroundStyle: { backgroundColor: theme.background.content },
4758
+ handleIndicatorStyle: { backgroundColor: theme.textMutedColor },
4759
+ children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
4760
+ import_bottom_sheet3.BottomSheetScrollView,
4761
+ {
4762
+ keyboardShouldPersistTaps: "handled",
4763
+ contentContainerStyle: {
4764
+ paddingBottom: insets.bottom
4765
+ },
4766
+ children
4767
+ }
4768
+ )
4769
+ }
4770
+ );
4771
+ }
4772
+ );
4773
+
4791
4774
  // src/Layout.tsx
4792
4775
  var import_jsx_runtime24 = require("react/jsx-runtime");
4793
4776
  var Layout = ({
@@ -4801,6 +4784,73 @@ var Layout = ({
4801
4784
  const [drawerOpen, setDrawerOpen] = (0, import_react17.useState)(false);
4802
4785
  const addonPanelRef = (0, import_react17.useRef)(null);
4803
4786
  const insets = (0, import_react_native_safe_area_context3.useSafeAreaInsets)();
4787
+ const { isDesktop } = useLayout();
4788
+ if (isDesktop) {
4789
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(
4790
+ import_react_native8.View,
4791
+ {
4792
+ style: {
4793
+ flex: 1,
4794
+ paddingTop: insets.top,
4795
+ backgroundColor: theme.background.content,
4796
+ flexDirection: "row"
4797
+ },
4798
+ children: [
4799
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
4800
+ import_react_native8.View,
4801
+ {
4802
+ style: {
4803
+ width: 240,
4804
+ borderColor: theme.appBorderColor,
4805
+ borderRightWidth: 1
4806
+ },
4807
+ children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
4808
+ import_react_native8.ScrollView,
4809
+ {
4810
+ keyboardShouldPersistTaps: "handled",
4811
+ contentContainerStyle: {
4812
+ paddingBottom: insets.bottom
4813
+ },
4814
+ children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
4815
+ Sidebar,
4816
+ {
4817
+ extra: [],
4818
+ previewInitialized: true,
4819
+ indexError: void 0,
4820
+ refs: {},
4821
+ setSelection: ({ storyId: newStoryId }) => {
4822
+ const channel = import_manager_api2.addons.getChannel();
4823
+ channel.emit(import_core_events.SET_CURRENT_STORY, { storyId: newStoryId });
4824
+ },
4825
+ status: {},
4826
+ index: storyHash,
4827
+ storyId: story?.id,
4828
+ refId: DEFAULT_REF_ID
4829
+ }
4830
+ )
4831
+ }
4832
+ )
4833
+ }
4834
+ ),
4835
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(import_react_native8.View, { style: { flex: 1 }, children: [
4836
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_react_native8.View, { style: { flex: 1 }, children }),
4837
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
4838
+ import_react_native8.View,
4839
+ {
4840
+ style: {
4841
+ height: 300,
4842
+ borderTopWidth: 1,
4843
+ borderColor: theme.appBorderColor,
4844
+ paddingTop: 4
4845
+ },
4846
+ children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(AddonsTabs, { storyId: story?.id })
4847
+ }
4848
+ )
4849
+ ] })
4850
+ ]
4851
+ }
4852
+ );
4853
+ }
4804
4854
  return /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(import_react_native8.View, { style: { flex: 1, paddingTop: insets.top, backgroundColor: theme.background.content }, children: [
4805
4855
  /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_react_native8.View, { style: { flex: 1 }, children }),
4806
4856
  /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(MobileMenuDrawer, { ref: mobileMenuDrawerRef, onStateChange: setDrawerOpen, children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
@@ -4863,7 +4913,7 @@ var Container3 = import_react_native_theming15.styled.View(({ theme }) => ({
4863
4913
  alignSelf: "flex-end",
4864
4914
  width: "100%",
4865
4915
  zIndex: 10,
4866
- background: theme.barBg,
4916
+ backgroundColor: theme.barBg,
4867
4917
  borderTopColor: theme.appBorderColor,
4868
4918
  borderTopWidth: 1
4869
4919
  }));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@storybook/react-native-ui",
3
- "version": "8.3.0-alpha.1",
3
+ "version": "8.3.0-alpha.2",
4
4
  "description": "ui components for react native storybook",
5
5
  "keywords": [
6
6
  "react",
@@ -57,9 +57,9 @@
57
57
  "typescript": "~5.3.3"
58
58
  },
59
59
  "dependencies": {
60
- "@storybook/core": "^8.3.0",
61
- "@storybook/react": "^8.3.0",
62
- "@storybook/react-native-theming": "^8.3.0-alpha.1",
60
+ "@storybook/core": "^8.3.1",
61
+ "@storybook/react": "^8.3.1",
62
+ "@storybook/react-native-theming": "^8.3.0-alpha.2",
63
63
  "fuse.js": "^7.0.0",
64
64
  "memoizerific": "^1.11.3",
65
65
  "polished": "^4.3.1",
@@ -80,5 +80,5 @@
80
80
  "publishConfig": {
81
81
  "access": "public"
82
82
  },
83
- "gitHead": "44d795b125a02dc9f669187d37d6b5f348bb2ea8"
83
+ "gitHead": "afcce3fd6cfd6625afaddb06527c377449300d6d"
84
84
  }
package/src/Layout.tsx CHANGED
@@ -1,9 +1,9 @@
1
1
  import { SET_CURRENT_STORY } from '@storybook/core/core-events';
2
2
  import { addons } from '@storybook/core/manager-api';
3
- import { styled, useTheme } from '@storybook/react-native-theming';
4
3
  import { type API_IndexHash, type Args, type StoryContext } from '@storybook/core/types';
4
+ import { styled, useTheme } from '@storybook/react-native-theming';
5
5
  import { ReactNode, useRef, useState } from 'react';
6
- import { Platform, Text, View } from 'react-native';
6
+ import { Platform, ScrollView, Text, View } from 'react-native';
7
7
  import { useSafeAreaInsets } from 'react-native-safe-area-context';
8
8
  import { IconButton } from './IconButton';
9
9
  import { Sidebar } from './Sidebar';
@@ -12,8 +12,9 @@ import { BottomBarToggleIcon } from './icon/BottomBarToggleIcon';
12
12
  import { MenuIcon } from './icon/MenuIcon';
13
13
 
14
14
  import type { ReactRenderer } from '@storybook/react';
15
+ import { useLayout } from './LayoutProvider';
16
+ import { AddonsTabs, MobileAddonsPanel, MobileAddonsPanelRef } from './MobileAddonsPanel';
15
17
  import { MobileMenuDrawer, MobileMenuDrawerRef } from './MobileMenuDrawer';
16
- import { MobileAddonsPanel, MobileAddonsPanelRef } from './MobileAddonsPanel';
17
18
 
18
19
  export const Layout = ({
19
20
  storyHash,
@@ -30,10 +31,71 @@ export const Layout = ({
30
31
  const [drawerOpen, setDrawerOpen] = useState(false);
31
32
  const addonPanelRef = useRef<MobileAddonsPanelRef>(null);
32
33
  const insets = useSafeAreaInsets();
34
+ const { isDesktop } = useLayout();
35
+
36
+ if (isDesktop) {
37
+ return (
38
+ <View
39
+ style={{
40
+ flex: 1,
41
+ paddingTop: insets.top,
42
+ backgroundColor: theme.background.content,
43
+ flexDirection: 'row',
44
+ }}
45
+ >
46
+ <View
47
+ style={{
48
+ width: 240,
49
+ borderColor: theme.appBorderColor,
50
+ borderRightWidth: 1,
51
+ }}
52
+ >
53
+ <ScrollView
54
+ keyboardShouldPersistTaps="handled"
55
+ contentContainerStyle={{
56
+ paddingBottom: insets.bottom,
57
+ }}
58
+ >
59
+ <Sidebar
60
+ extra={[]}
61
+ previewInitialized
62
+ indexError={undefined}
63
+ refs={{}}
64
+ setSelection={({ storyId: newStoryId }) => {
65
+ const channel = addons.getChannel();
66
+
67
+ channel.emit(SET_CURRENT_STORY, { storyId: newStoryId });
68
+ }}
69
+ status={{}}
70
+ index={storyHash}
71
+ storyId={story?.id}
72
+ refId={DEFAULT_REF_ID}
73
+ />
74
+ </ScrollView>
75
+ </View>
76
+
77
+ <View style={{ flex: 1 }}>
78
+ <View style={{ flex: 1 }}>{children}</View>
79
+
80
+ <View
81
+ style={{
82
+ height: 300,
83
+ borderTopWidth: 1,
84
+ borderColor: theme.appBorderColor,
85
+ paddingTop: 4,
86
+ }}
87
+ >
88
+ <AddonsTabs storyId={story?.id} />
89
+ </View>
90
+ </View>
91
+ </View>
92
+ );
93
+ }
33
94
 
34
95
  return (
35
96
  <View style={{ flex: 1, paddingTop: insets.top, backgroundColor: theme.background.content }}>
36
97
  <View style={{ flex: 1 }}>{children}</View>
98
+
37
99
  <MobileMenuDrawer ref={mobileMenuDrawerRef} onStateChange={setDrawerOpen}>
38
100
  <Sidebar
39
101
  extra={[]}
@@ -51,6 +113,7 @@ export const Layout = ({
51
113
  refId={DEFAULT_REF_ID}
52
114
  />
53
115
  </MobileMenuDrawer>
116
+
54
117
  <MobileAddonsPanel ref={addonPanelRef} storyId={story?.id} onStateChange={setMenuOpen} />
55
118
  {(Platform.OS !== 'android' || (!menuOpen && !drawerOpen)) && (
56
119
  <Container style={{ marginBottom: insets.bottom }}>
@@ -93,7 +156,7 @@ const Container = styled.View(({ theme }) => ({
93
156
  alignSelf: 'flex-end',
94
157
  width: '100%',
95
158
  zIndex: 10,
96
- background: theme.barBg,
159
+ backgroundColor: theme.barBg,
97
160
  borderTopColor: theme.appBorderColor,
98
161
  borderTopWidth: 1,
99
162
  }));
@@ -1,90 +1,32 @@
1
1
  import type { FC, PropsWithChildren } from 'react';
2
- import React, { createContext, useCallback, useContext, useMemo, useRef } from 'react';
3
- import { BREAKPOINT } from './constants';
2
+ import { createContext, useContext, useMemo } from 'react';
4
3
  import { useWindowDimensions } from 'react-native';
5
- // import {
6
- // BottomSheetModal,
7
- // BottomSheetModalProvider,
8
- // BottomSheetScrollView,
9
- // } from '@gorhom/bottom-sheet';
4
+ import { BREAKPOINT } from './constants';
10
5
 
11
6
  type LayoutContextType = {
12
- // isMobileMenuOpen: boolean;
13
- openMobileMenu: () => void;
14
- closeMobileMenu: () => void;
15
- // isMobileAboutOpen: boolean;
16
- // setMobileAboutOpen: React.Dispatch<React.SetStateAction<boolean>>;
17
- // isMobilePanelOpen: boolean;
18
- // setMobilePanelOpen: React.Dispatch<React.SetStateAction<boolean>>;
19
7
  isDesktop: boolean;
20
8
  isMobile: boolean;
21
9
  };
22
10
 
23
11
  const LayoutContext = createContext<LayoutContextType>({
24
- // isMobileMenuOpen: false,
25
-
26
- openMobileMenu: () => {},
27
- closeMobileMenu: () => {},
28
- // isMobileAboutOpen: false,
29
- // setMobileAboutOpen: () => {},
30
- // isMobilePanelOpen: false,
31
- // setMobilePanelOpen: () => {},
32
-
33
12
  isDesktop: false,
34
- isMobile: false,
13
+ isMobile: true,
35
14
  });
36
15
 
37
16
  export const LayoutProvider: FC<PropsWithChildren> = ({ children }) => {
38
- // const [isMobileMenuOpen, setMobileMenuOpen] = useState(false);
39
- // const [isMobileAboutOpen, setMobileAboutOpen] = useState(false);
40
- // const [isMobilePanelOpen, setMobilePanelOpen] = useState(false);
41
17
  const { width } = useWindowDimensions();
42
18
  const isDesktop = width >= BREAKPOINT;
43
19
  const isMobile = !isDesktop;
44
- // const bottomSheetModalRef = useRef<BottomSheetModal>(null);
45
-
46
- const openMobileMenu = useCallback(() => {
47
- // bottomSheetModalRef.current?.present();
48
- }, []);
49
- const closeMobileMenu = useCallback(() => {
50
- // bottomSheetModalRef.current?.dismiss();
51
- }, []);
52
20
 
53
21
  const contextValue = useMemo(
54
22
  () => ({
55
- // isMobileMenuOpen,
56
- openMobileMenu,
57
- closeMobileMenu,
58
- // isMobileAboutOpen,
59
- // setMobileAboutOpen,
60
- // isMobilePanelOpen,
61
- // setMobilePanelOpen,
62
23
  isDesktop,
63
24
  isMobile,
64
25
  }),
65
- [
66
- // isMobileMenuOpen,
67
- openMobileMenu,
68
- closeMobileMenu,
69
- // // isMobileAboutOpen,
70
- // setMobileAboutOpen,
71
- // isMobilePanelOpen,
72
- // setMobilePanelOpen,
73
- isDesktop,
74
- isMobile,
75
- ]
26
+ [isDesktop, isMobile]
76
27
  );
77
28
 
78
- return (
79
- // <BottomSheetModalProvider>
80
- <>
81
- <LayoutContext.Provider value={contextValue}>{children}</LayoutContext.Provider>
82
- {/* <BottomSheetModal ref={bottomSheetModalRef} snapPoints={['70%', '50%']}>
83
- <BottomSheetScrollView>bla</BottomSheetScrollView>
84
- </BottomSheetModal> */}
85
- </>
86
- // </BottomSheetModalProvider>
87
- );
29
+ return <LayoutContext.Provider value={contextValue}>{children}</LayoutContext.Provider>;
88
30
  };
89
31
 
90
32
  export const useLayout = () => useContext(LayoutContext);
@@ -30,8 +30,6 @@ export const MobileAddonsPanel = forwardRef<
30
30
  const addonsPanelBottomSheetRef = useRef<BottomSheetModal>(null);
31
31
  const insets = useSafeAreaInsets();
32
32
 
33
- const panels = addons.getElements(Addon_TypesEnum.PANEL);
34
- const [addonSelected, setAddonSelected] = useState(Object.keys(panels)[0]);
35
33
  const animatedPosition = useSharedValue(0);
36
34
 
37
35
  // bringing in animated keyboard disables android resizing
@@ -87,76 +85,91 @@ export const MobileAddonsPanel = forwardRef<
87
85
  stackBehavior="replace"
88
86
  >
89
87
  <Animated.View style={[{ flex: 1 }, adjustedBottomSheetSize]}>
90
- <View
91
- style={{ flexDirection: 'row', borderBottomWidth: 1, borderBottomColor: 'lightgrey' }}
92
- >
93
- <ScrollView
94
- horizontal
95
- showsHorizontalScrollIndicator={false}
96
- contentContainerStyle={{
97
- justifyContent: 'center',
98
- }}
99
- >
100
- {Object.values(panels).map(({ id, title }) => {
101
- const resolvedTitle = typeof title === 'function' ? title({}) : title;
102
-
103
- return (
104
- <Tab
105
- key={id}
106
- active={id === addonSelected}
107
- onPress={() => setAddonSelected(id)}
108
- text={resolvedTitle}
109
- />
110
- );
111
- })}
112
- </ScrollView>
113
-
114
- <IconButton
115
- style={{
116
- marginRight: 4,
117
- marginBottom: 4,
118
- alignItems: 'center',
119
- justifyContent: 'center',
120
- }}
121
- hitSlop={{ top: 10, right: 10, bottom: 10, left: 10 }}
122
- Icon={CloseIcon}
123
- onPress={() => {
124
- onStateChange(false);
125
- addonsPanelBottomSheetRef.current?.dismiss();
126
- }}
127
- />
128
- </View>
88
+ <AddonsTabs
89
+ onClose={() => {
90
+ onStateChange(false);
91
+ addonsPanelBottomSheetRef.current?.dismiss();
92
+ }}
93
+ storyId={storyId}
94
+ />
95
+ </Animated.View>
96
+ </BottomSheetModal>
97
+ );
98
+ });
99
+
100
+ export const AddonsTabs = ({ onClose, storyId }: { onClose?: () => void; storyId?: string }) => {
101
+ const panels = addons.getElements(Addon_TypesEnum.PANEL);
102
+
103
+ const [addonSelected, setAddonSelected] = useState(Object.keys(panels)[0]);
104
+
105
+ const insets = useSafeAreaInsets();
106
+
107
+ return (
108
+ <View style={{ flex: 1 }}>
109
+ <View style={{ flexDirection: 'row', borderBottomWidth: 1, borderBottomColor: 'lightgrey' }}>
129
110
  <ScrollView
130
- style={{ flex: 1 }}
131
- // keyboardShouldPersistTaps="handled"
111
+ horizontal
112
+ showsHorizontalScrollIndicator={false}
132
113
  contentContainerStyle={{
133
- paddingBottom: insets.bottom + 16,
114
+ justifyContent: 'center',
134
115
  }}
135
116
  >
136
- {(() => {
137
- if (!storyId) {
138
- return (
139
- <View style={{ alignItems: 'center', justifyContent: 'center' }}>
140
- <Text>No Story Selected</Text>
141
- </View>
142
- );
143
- }
144
-
145
- if (Object.keys(panels).length === 0) {
146
- return (
147
- <View style={{ alignItems: 'center', justifyContent: 'center' }}>
148
- <Text>No addons loaded.</Text>
149
- </View>
150
- );
151
- }
152
-
153
- return panels[addonSelected].render({ active: true });
154
- })()}
117
+ {Object.values(panels).map(({ id, title }) => {
118
+ const resolvedTitle = typeof title === 'function' ? title({}) : title;
119
+
120
+ return (
121
+ <Tab
122
+ key={id}
123
+ active={id === addonSelected}
124
+ onPress={() => setAddonSelected(id)}
125
+ text={resolvedTitle}
126
+ />
127
+ );
128
+ })}
155
129
  </ScrollView>
156
- </Animated.View>
157
- </BottomSheetModal>
130
+
131
+ <IconButton
132
+ style={{
133
+ marginRight: 4,
134
+ marginBottom: 4,
135
+ alignItems: 'center',
136
+ justifyContent: 'center',
137
+ }}
138
+ hitSlop={{ top: 10, right: 10, bottom: 10, left: 10 }}
139
+ Icon={CloseIcon}
140
+ onPress={() => onClose?.()}
141
+ />
142
+ </View>
143
+ <ScrollView
144
+ style={{ flex: 1 }}
145
+ // keyboardShouldPersistTaps="handled"
146
+ contentContainerStyle={{
147
+ paddingBottom: insets.bottom + 16,
148
+ }}
149
+ >
150
+ {(() => {
151
+ if (!storyId) {
152
+ return (
153
+ <View style={{ alignItems: 'center', justifyContent: 'center' }}>
154
+ <Text>No Story Selected</Text>
155
+ </View>
156
+ );
157
+ }
158
+
159
+ if (Object.keys(panels).length === 0) {
160
+ return (
161
+ <View style={{ alignItems: 'center', justifyContent: 'center' }}>
162
+ <Text>No addons loaded.</Text>
163
+ </View>
164
+ );
165
+ }
166
+
167
+ return panels[addonSelected].render({ active: true });
168
+ })()}
169
+ </ScrollView>
170
+ </View>
158
171
  );
159
- });
172
+ };
160
173
 
161
174
  const Tab = ({ active, onPress, text }: { active: boolean; onPress: () => void; text: string }) => {
162
175
  return (
package/src/Search.tsx CHANGED
@@ -1,22 +1,23 @@
1
+ import { BottomSheetTextInput } from '@gorhom/bottom-sheet';
1
2
  import { styled } from '@storybook/react-native-theming';
2
3
  import type { IFuseOptions } from 'fuse.js';
3
4
  import Fuse from 'fuse.js';
4
- import React, { useRef, useState, useCallback } from 'react';
5
+ import React, { useCallback, useRef, useState } from 'react';
6
+ import { TextInput, View } from 'react-native';
7
+ import { CloseIcon } from './icon/CloseIcon';
8
+ import { SearchIcon } from './icon/SearchIcon';
9
+ import { useLayout } from './LayoutProvider';
5
10
  import {
6
11
  type CombinedDataset,
12
+ type GetSearchItemProps,
13
+ isExpandType,
14
+ type SearchChildrenFn,
7
15
  type SearchItem,
8
16
  type SearchResult,
9
- type SearchChildrenFn,
10
17
  type Selection,
11
- type GetSearchItemProps,
12
- isExpandType,
13
18
  } from './types';
14
- import { searchItem } from './util/tree';
15
19
  import { getGroupStatus, getHighestStatus } from './util/status';
16
- import { SearchIcon } from './icon/SearchIcon';
17
- import { CloseIcon } from './icon/CloseIcon';
18
- import { TextInput, View } from 'react-native';
19
- import { BottomSheetTextInput } from '@gorhom/bottom-sheet';
20
+ import { searchItem } from './util/tree';
20
21
 
21
22
  const DEFAULT_MAX_SEARCH_RESULTS = 50;
22
23
 
@@ -56,7 +57,20 @@ const SearchField = styled.View({
56
57
  position: 'relative',
57
58
  });
58
59
 
59
- const Input = styled(BottomSheetTextInput)(({ theme }) => ({
60
+ const BottomSheetInput = styled(BottomSheetTextInput)(({ theme }) => ({
61
+ height: 32,
62
+ paddingLeft: 28,
63
+ paddingRight: 28,
64
+ borderWidth: 1,
65
+ borderColor: theme.appBorderColor,
66
+ backgroundColor: 'transparent',
67
+ borderRadius: 4,
68
+ fontSize: theme.typography.size.s1 + 1,
69
+ color: theme.color.defaultText,
70
+ width: '100%',
71
+ }));
72
+
73
+ const Input = styled(TextInput)(({ theme }) => ({
60
74
  height: 32,
61
75
  paddingLeft: 28,
62
76
  paddingRight: 28,
@@ -94,12 +108,16 @@ export const Search = React.memo<{
94
108
  const [inputValue, setInputValue] = useState(initialQuery);
95
109
  const [isOpen, setIsOpen] = useState(false);
96
110
  const [allComponents, showAllComponents] = useState(false);
111
+ const { isMobile } = useLayout();
97
112
 
98
113
  const selectStory = useCallback(
99
114
  (id: string, refId: string) => {
100
115
  setSelection({ storyId: id, refId });
116
+
101
117
  inputRef.current?.blur();
102
118
 
119
+ setIsOpen(false);
120
+
103
121
  showAllComponents(false);
104
122
  },
105
123
  [setSelection]
@@ -212,12 +230,17 @@ export const Search = React.memo<{
212
230
  <SearchIcon />
213
231
  </SearchIconWrapper>
214
232
 
215
- <Input
216
- ref={inputRef as any} // TODO find solution for this
217
- onChangeText={setInputValue}
218
- onFocus={() => setIsOpen(true)}
219
- onBlur={() => setIsOpen(false)}
220
- />
233
+ {isMobile ? (
234
+ <BottomSheetInput
235
+ ref={inputRef as any} // TODO find solution for this
236
+ onChangeText={setInputValue}
237
+ onFocus={() => setIsOpen(true)}
238
+ onBlur={() => setIsOpen(false)}
239
+ />
240
+ ) : (
241
+ <Input ref={inputRef} onChangeText={setInputValue} onFocus={() => setIsOpen(true)} />
242
+ )}
243
+
221
244
  {isOpen && (
222
245
  <ClearIcon
223
246
  onPress={() => {
@@ -207,7 +207,7 @@ export const SearchResults: FC<{
207
207
  <ResultsList>
208
208
  {results.length > 0 && !query && (
209
209
  <RecentlyOpenedTitle>
210
- Recently opened
210
+ <Text>Recently opened</Text>
211
211
  <IconButton onPress={handleClearLastViewed} />
212
212
  </RecentlyOpenedTitle>
213
213
  )}
package/src/Sidebar.tsx CHANGED
@@ -19,7 +19,7 @@ const Container = styled.View(({ theme }) => ({
19
19
  height: '100%',
20
20
  display: 'flex',
21
21
  flexDirection: 'column',
22
- background: theme.background.content,
22
+ backgroundColor: theme.background.content,
23
23
  }));
24
24
 
25
25
  const Top = styled.View({
package/src/Tree.tsx CHANGED
@@ -53,7 +53,7 @@ export const Node = React.memo<NodeProps>(function Node({
53
53
  setExpanded,
54
54
  onSelectStoryId,
55
55
  }) {
56
- const { isDesktop, isMobile, closeMobileMenu } = useLayout();
56
+ const { isDesktop } = useLayout();
57
57
 
58
58
  if (!isDisplayed) {
59
59
  return null;
@@ -73,7 +73,6 @@ export const Node = React.memo<NodeProps>(function Node({
73
73
  depth={isOrphan ? item.depth : item.depth - 1}
74
74
  onPress={() => {
75
75
  onSelectStoryId(item.id);
76
- if (isMobile) closeMobileMenu();
77
76
  }}
78
77
  >
79
78
  {(item.renderLabel as (i: typeof item) => React.ReactNode)?.(item) || item.name}
@@ -147,7 +146,7 @@ export const LeafNodeStyleWrapper = styled.View(({ theme }) => ({
147
146
  alignItems: 'center',
148
147
  paddingRight: 20,
149
148
  color: theme.color.defaultText,
150
- background: 'transparent',
149
+ backgroundColor: 'transparent',
151
150
  minHeight: 28,
152
151
  borderRadius: 4,
153
152
  }));
package/src/TreeNode.tsx CHANGED
@@ -36,7 +36,7 @@ const BranchNode = styled.TouchableOpacity<{
36
36
  alignSelf: 'flex-start',
37
37
  paddingLeft: (isExpandable ? 8 : 22) + depth * 18,
38
38
 
39
- background: 'transparent',
39
+ backgroundColor: 'transparent',
40
40
  minHeight: 28,
41
41
  borderRadius: 4,
42
42
  gap: 6,
@@ -45,7 +45,7 @@ const BranchNode = styled.TouchableOpacity<{
45
45
 
46
46
  // will this actually do anything?
47
47
  '&:hover, &:focus': {
48
- background: transparentize(0.93, theme.color.secondary),
48
+ backgroundColor: transparentize(0.93, theme.color.secondary),
49
49
  outline: 'none',
50
50
  },
51
51
  }));
package/src/constants.ts CHANGED
@@ -1,4 +1,4 @@
1
- export const BREAKPOINT = 600;
1
+ export const BREAKPOINT = 1000;
2
2
  export const MEDIA_DESKTOP_BREAKPOINT = `@media (min-width: ${BREAKPOINT}px)`;
3
3
  export const MOBILE_TRANSITION_DURATION = 300;
4
4
  export const DEFAULT_REF_ID = 'storybook_internal';