@storybook/react-native-ui 8.3.10 → 8.4.0-alpha.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +7 -7
- package/dist/index.js +85 -97
- package/package.json +10 -9
- package/src/Button.tsx +4 -3
- package/src/IconButton.tsx +2 -3
- package/src/Layout.stories.tsx +46 -2
- package/src/Layout.tsx +28 -32
- package/src/MobileAddonsPanel.tsx +70 -77
- package/src/MobileMenuDrawer.tsx +2 -8
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as _storybook_react_native_theming from '@storybook/react-native-theming';
|
|
2
2
|
import * as react_native from 'react-native';
|
|
3
|
-
import { PressableProps, View, TouchableOpacityProps
|
|
3
|
+
import { PressableProps, View, TouchableOpacityProps } from 'react-native';
|
|
4
4
|
import * as React$1 from 'react';
|
|
5
5
|
import React__default, { FC, ComponentProps, ReactElement, PropsWithChildren, ReactNode } from 'react';
|
|
6
6
|
import { State, StoriesHash, API } from '@storybook/core/manager-api';
|
|
@@ -15,7 +15,7 @@ interface NodeProps$1 {
|
|
|
15
15
|
isExpandable?: boolean;
|
|
16
16
|
isExpanded?: boolean;
|
|
17
17
|
}
|
|
18
|
-
declare const BranchNode: _storybook_react_native_theming.StyledComponent<react_native.TouchableOpacityProps & {
|
|
18
|
+
declare const BranchNode: _storybook_react_native_theming.StyledComponent<react_native.TouchableOpacityProps & React__default.RefAttributes<react_native.View> & {
|
|
19
19
|
theme?: _storybook_react_native_theming.Theme;
|
|
20
20
|
as?: React__default.ElementType;
|
|
21
21
|
} & {
|
|
@@ -25,16 +25,16 @@ declare const BranchNode: _storybook_react_native_theming.StyledComponent<react_
|
|
|
25
25
|
isComponent?: boolean;
|
|
26
26
|
isSelected?: boolean;
|
|
27
27
|
}, {}, {
|
|
28
|
-
ref?: React__default.Ref<
|
|
28
|
+
ref?: React__default.Ref<any>;
|
|
29
29
|
}>;
|
|
30
|
-
declare const LeafNode: _storybook_react_native_theming.StyledComponent<react_native.TouchableOpacityProps & {
|
|
30
|
+
declare const LeafNode: _storybook_react_native_theming.StyledComponent<react_native.TouchableOpacityProps & React__default.RefAttributes<react_native.View> & {
|
|
31
31
|
theme?: _storybook_react_native_theming.Theme;
|
|
32
32
|
as?: React__default.ElementType;
|
|
33
33
|
} & {
|
|
34
34
|
depth?: number;
|
|
35
35
|
selected?: boolean;
|
|
36
36
|
}, {}, {
|
|
37
|
-
ref?: React__default.Ref<
|
|
37
|
+
ref?: React__default.Ref<any>;
|
|
38
38
|
}>;
|
|
39
39
|
declare const GroupNode: FC<ComponentProps<typeof BranchNode> & {
|
|
40
40
|
isExpanded?: boolean;
|
|
@@ -156,7 +156,7 @@ interface ButtonProps extends TouchableOpacityProps {
|
|
|
156
156
|
text?: string;
|
|
157
157
|
Icon?: (props: SvgProps) => ReactElement;
|
|
158
158
|
}
|
|
159
|
-
declare const Button: React$1.ForwardRefExoticComponent<ButtonProps & React$1.RefAttributes<
|
|
159
|
+
declare const Button: React$1.ForwardRefExoticComponent<ButtonProps & React$1.RefAttributes<any>>;
|
|
160
160
|
declare const ButtonText: _storybook_react_native_theming.StyledComponent<react_native.TextProps & {
|
|
161
161
|
theme?: _storybook_react_native_theming.Theme;
|
|
162
162
|
as?: React.ElementType;
|
|
@@ -172,7 +172,7 @@ declare const ButtonIcon: ({ Icon, active, variant, }: {
|
|
|
172
172
|
active: ButtonProps["active"];
|
|
173
173
|
}) => react_jsx_runtime.JSX.Element;
|
|
174
174
|
|
|
175
|
-
declare const IconButton: React$1.ForwardRefExoticComponent<ButtonProps & React$1.RefAttributes<
|
|
175
|
+
declare const IconButton: React$1.ForwardRefExoticComponent<ButtonProps & React$1.RefAttributes<unknown>>;
|
|
176
176
|
|
|
177
177
|
type LayoutContextType = {
|
|
178
178
|
isDesktop: boolean;
|
package/dist/index.js
CHANGED
|
@@ -4506,70 +4506,66 @@ var import_react_native_reanimated = __toESM(require("react-native-reanimated"))
|
|
|
4506
4506
|
var import_react_native_safe_area_context = require("react-native-safe-area-context");
|
|
4507
4507
|
var import_react_native_theming13 = require("@storybook/react-native-theming");
|
|
4508
4508
|
var import_jsx_runtime20 = require("react/jsx-runtime");
|
|
4509
|
-
var MobileAddonsPanel = (0, import_react15.forwardRef)(
|
|
4510
|
-
|
|
4511
|
-
|
|
4512
|
-
|
|
4513
|
-
|
|
4514
|
-
|
|
4515
|
-
|
|
4516
|
-
|
|
4517
|
-
|
|
4518
|
-
|
|
4519
|
-
|
|
4520
|
-
|
|
4521
|
-
|
|
4522
|
-
|
|
4523
|
-
addonsPanelBottomSheetRef.current?.dismiss();
|
|
4524
|
-
}
|
|
4525
|
-
}
|
|
4526
|
-
}));
|
|
4527
|
-
const { height } = (0, import_react_native6.useWindowDimensions)();
|
|
4528
|
-
const adjustedBottomSheetSize = (0, import_react_native_reanimated.useAnimatedStyle)(() => {
|
|
4529
|
-
return {
|
|
4530
|
-
maxHeight: height - animatedPosition.value - insets.bottom
|
|
4531
|
-
};
|
|
4532
|
-
}, [animatedPosition.value, height, insets.bottom]);
|
|
4533
|
-
return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
4534
|
-
import_bottom_sheet2.BottomSheetModal,
|
|
4535
|
-
{
|
|
4536
|
-
ref: addonsPanelBottomSheetRef,
|
|
4537
|
-
index: 1,
|
|
4538
|
-
animateOnMount: !reducedMotion,
|
|
4539
|
-
onDismiss: () => {
|
|
4540
|
-
onStateChange(false);
|
|
4541
|
-
},
|
|
4542
|
-
snapPoints: ["25%", "50%", "75%"],
|
|
4543
|
-
style: {
|
|
4544
|
-
paddingTop: 8
|
|
4545
|
-
},
|
|
4546
|
-
animatedPosition,
|
|
4547
|
-
containerStyle: {},
|
|
4548
|
-
backgroundStyle: {
|
|
4549
|
-
borderRadius: 0,
|
|
4550
|
-
borderTopColor: theme.appBorderColor,
|
|
4551
|
-
borderTopWidth: 1,
|
|
4552
|
-
backgroundColor: theme.background.content
|
|
4553
|
-
},
|
|
4554
|
-
handleIndicatorStyle: { backgroundColor: theme.textMutedColor },
|
|
4555
|
-
keyboardBehavior: "extend",
|
|
4556
|
-
enableDismissOnClose: true,
|
|
4557
|
-
enableHandlePanningGesture: true,
|
|
4558
|
-
stackBehavior: "replace",
|
|
4559
|
-
enableDynamicSizing: false,
|
|
4560
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_react_native_reanimated.default.View, { style: [{ flex: 1 }, adjustedBottomSheetSize], children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
4561
|
-
AddonsTabs,
|
|
4562
|
-
{
|
|
4563
|
-
onClose: () => {
|
|
4564
|
-
onStateChange(false);
|
|
4565
|
-
addonsPanelBottomSheetRef.current?.dismiss();
|
|
4566
|
-
},
|
|
4567
|
-
storyId
|
|
4509
|
+
var MobileAddonsPanel = (0, import_react15.forwardRef)(
|
|
4510
|
+
({ storyId }, ref) => {
|
|
4511
|
+
const theme = (0, import_react_native_theming13.useTheme)();
|
|
4512
|
+
const reducedMotion = (0, import_react_native_reanimated.useReducedMotion)();
|
|
4513
|
+
const addonsPanelBottomSheetRef = (0, import_react15.useRef)(null);
|
|
4514
|
+
const insets = (0, import_react_native_safe_area_context.useSafeAreaInsets)();
|
|
4515
|
+
const animatedPosition = (0, import_react_native_reanimated.useSharedValue)(0);
|
|
4516
|
+
(0, import_react_native_reanimated.useAnimatedKeyboard)();
|
|
4517
|
+
(0, import_react15.useImperativeHandle)(ref, () => ({
|
|
4518
|
+
setAddonsPanelOpen: (open) => {
|
|
4519
|
+
if (open) {
|
|
4520
|
+
addonsPanelBottomSheetRef.current?.present();
|
|
4521
|
+
} else {
|
|
4522
|
+
addonsPanelBottomSheetRef.current?.dismiss();
|
|
4568
4523
|
}
|
|
4569
|
-
|
|
4570
|
-
}
|
|
4571
|
-
|
|
4572
|
-
|
|
4524
|
+
}
|
|
4525
|
+
}));
|
|
4526
|
+
const { height } = (0, import_react_native6.useWindowDimensions)();
|
|
4527
|
+
const adjustedBottomSheetSize = (0, import_react_native_reanimated.useAnimatedStyle)(() => {
|
|
4528
|
+
return {
|
|
4529
|
+
maxHeight: height - animatedPosition.value - insets.bottom
|
|
4530
|
+
};
|
|
4531
|
+
}, [animatedPosition.value, height, insets.bottom]);
|
|
4532
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
4533
|
+
import_bottom_sheet2.BottomSheetModal,
|
|
4534
|
+
{
|
|
4535
|
+
ref: addonsPanelBottomSheetRef,
|
|
4536
|
+
index: 1,
|
|
4537
|
+
animateOnMount: !reducedMotion,
|
|
4538
|
+
snapPoints: ["25%", "50%", "75%"],
|
|
4539
|
+
style: {
|
|
4540
|
+
paddingTop: 8
|
|
4541
|
+
},
|
|
4542
|
+
animatedPosition,
|
|
4543
|
+
containerStyle: {},
|
|
4544
|
+
backgroundStyle: {
|
|
4545
|
+
borderRadius: 0,
|
|
4546
|
+
borderTopColor: theme.appBorderColor,
|
|
4547
|
+
borderTopWidth: 1,
|
|
4548
|
+
backgroundColor: theme.background.content
|
|
4549
|
+
},
|
|
4550
|
+
handleIndicatorStyle: { backgroundColor: theme.textMutedColor },
|
|
4551
|
+
keyboardBehavior: "extend",
|
|
4552
|
+
enableDismissOnClose: true,
|
|
4553
|
+
enableHandlePanningGesture: true,
|
|
4554
|
+
stackBehavior: "replace",
|
|
4555
|
+
enableDynamicSizing: false,
|
|
4556
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_react_native_reanimated.default.View, { style: [{ flex: 1 }, adjustedBottomSheetSize], children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
4557
|
+
AddonsTabs,
|
|
4558
|
+
{
|
|
4559
|
+
onClose: () => {
|
|
4560
|
+
addonsPanelBottomSheetRef.current?.dismiss();
|
|
4561
|
+
},
|
|
4562
|
+
storyId
|
|
4563
|
+
}
|
|
4564
|
+
) })
|
|
4565
|
+
}
|
|
4566
|
+
);
|
|
4567
|
+
}
|
|
4568
|
+
);
|
|
4573
4569
|
var AddonsTabs = ({ onClose, storyId }) => {
|
|
4574
4570
|
const panels = import_manager_api.addons.getElements(import_types3.Addon_TypesEnum.PANEL);
|
|
4575
4571
|
const [addonSelected, setAddonSelected] = (0, import_react15.useState)(Object.keys(panels)[0]);
|
|
@@ -4671,7 +4667,7 @@ var BottomSheetBackdropComponent = (backdropComponentProps) => /* @__PURE__ */ (
|
|
|
4671
4667
|
}
|
|
4672
4668
|
);
|
|
4673
4669
|
var MobileMenuDrawer = (0, import_react16.forwardRef)(
|
|
4674
|
-
({ children
|
|
4670
|
+
({ children }, ref) => {
|
|
4675
4671
|
const reducedMotion = (0, import_react_native_reanimated2.useReducedMotion)();
|
|
4676
4672
|
const insets = (0, import_react_native_safe_area_context2.useSafeAreaInsets)();
|
|
4677
4673
|
const theme = (0, import_react_native_theming14.useTheme)();
|
|
@@ -4679,11 +4675,9 @@ var MobileMenuDrawer = (0, import_react16.forwardRef)(
|
|
|
4679
4675
|
(0, import_react16.useImperativeHandle)(ref, () => ({
|
|
4680
4676
|
setMobileMenuOpen: (open) => {
|
|
4681
4677
|
if (open) {
|
|
4682
|
-
onStateChange(true);
|
|
4683
4678
|
menuBottomSheetRef.current?.present();
|
|
4684
4679
|
} else {
|
|
4685
4680
|
import_react_native7.Keyboard.dismiss();
|
|
4686
|
-
onStateChange(false);
|
|
4687
4681
|
menuBottomSheetRef.current?.dismiss();
|
|
4688
4682
|
}
|
|
4689
4683
|
}
|
|
@@ -4694,9 +4688,6 @@ var MobileMenuDrawer = (0, import_react16.forwardRef)(
|
|
|
4694
4688
|
ref: menuBottomSheetRef,
|
|
4695
4689
|
index: 1,
|
|
4696
4690
|
animateOnMount: !reducedMotion,
|
|
4697
|
-
onDismiss: () => {
|
|
4698
|
-
onStateChange(false);
|
|
4699
|
-
},
|
|
4700
4691
|
snapPoints: ["50%", "75%"],
|
|
4701
4692
|
enableDismissOnClose: true,
|
|
4702
4693
|
enableHandlePanningGesture: true,
|
|
@@ -4911,8 +4902,6 @@ var Layout = ({
|
|
|
4911
4902
|
}) => {
|
|
4912
4903
|
const theme = (0, import_react_native_theming15.useTheme)();
|
|
4913
4904
|
const mobileMenuDrawerRef = (0, import_react17.useRef)(null);
|
|
4914
|
-
const [menuOpen, setMenuOpen] = (0, import_react17.useState)(false);
|
|
4915
|
-
const [drawerOpen, setDrawerOpen] = (0, import_react17.useState)(false);
|
|
4916
4905
|
const addonPanelRef = (0, import_react17.useRef)(null);
|
|
4917
4906
|
const insets = (0, import_react_native_safe_area_context3.useSafeAreaInsets)();
|
|
4918
4907
|
const { isDesktop } = useLayout();
|
|
@@ -4987,7 +4976,7 @@ var Layout = ({
|
|
|
4987
4976
|
}
|
|
4988
4977
|
),
|
|
4989
4978
|
/* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(import_react_native8.View, { style: { flex: 1 }, children: [
|
|
4990
|
-
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_react_native8.View, { style: { flex: 1 }, children }),
|
|
4979
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_react_native8.View, { style: { flex: 1, overflow: "hidden" }, children }),
|
|
4991
4980
|
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
4992
4981
|
import_react_native8.View,
|
|
4993
4982
|
{
|
|
@@ -5014,29 +5003,8 @@ var Layout = ({
|
|
|
5014
5003
|
);
|
|
5015
5004
|
}
|
|
5016
5005
|
return /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(import_react_native8.View, { style: { flex: 1, paddingTop: insets.top, backgroundColor: theme.background.content }, children: [
|
|
5017
|
-
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_react_native8.View, { style: { flex: 1 }, children }),
|
|
5018
|
-
/* @__PURE__ */ (0, import_jsx_runtime26.
|
|
5019
|
-
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_react_native8.View, { style: { paddingLeft: 16, paddingTop: 4, paddingBottom: 4 }, children: theme.base === "light" ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(Logo, { height: 25, width: 125 }) : /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(DarkLogo, { height: 25, width: 125 }) }),
|
|
5020
|
-
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
5021
|
-
Sidebar,
|
|
5022
|
-
{
|
|
5023
|
-
extra: [],
|
|
5024
|
-
previewInitialized: true,
|
|
5025
|
-
indexError: void 0,
|
|
5026
|
-
refs: {},
|
|
5027
|
-
setSelection: ({ storyId: newStoryId }) => {
|
|
5028
|
-
const channel = import_manager_api2.addons.getChannel();
|
|
5029
|
-
channel.emit(import_core_events.SET_CURRENT_STORY, { storyId: newStoryId });
|
|
5030
|
-
},
|
|
5031
|
-
status: {},
|
|
5032
|
-
index: storyHash,
|
|
5033
|
-
storyId: story?.id,
|
|
5034
|
-
refId: DEFAULT_REF_ID
|
|
5035
|
-
}
|
|
5036
|
-
)
|
|
5037
|
-
] }),
|
|
5038
|
-
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(MobileAddonsPanel, { ref: addonPanelRef, storyId: story?.id, onStateChange: setMenuOpen }),
|
|
5039
|
-
(import_react_native8.Platform.OS !== "android" || !menuOpen && !drawerOpen) && /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(Container3, { style: { marginBottom: insets.bottom }, children: /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(Nav, { children: [
|
|
5006
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_react_native8.View, { style: { flex: 1, overflow: "hidden" }, children }),
|
|
5007
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(Container3, { style: { marginBottom: insets.bottom }, children: /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(Nav, { children: [
|
|
5040
5008
|
/* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(
|
|
5041
5009
|
Button2,
|
|
5042
5010
|
{
|
|
@@ -5062,7 +5030,28 @@ var Layout = ({
|
|
|
5062
5030
|
Icon: BottomBarToggleIcon
|
|
5063
5031
|
}
|
|
5064
5032
|
)
|
|
5065
|
-
] }) })
|
|
5033
|
+
] }) }),
|
|
5034
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(MobileMenuDrawer, { ref: mobileMenuDrawerRef, children: [
|
|
5035
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_react_native8.View, { style: { paddingLeft: 16, paddingTop: 4, paddingBottom: 4 }, children: theme.base === "light" ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(Logo, { height: 25, width: 125 }) : /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(DarkLogo, { height: 25, width: 125 }) }),
|
|
5036
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
5037
|
+
Sidebar,
|
|
5038
|
+
{
|
|
5039
|
+
extra: [],
|
|
5040
|
+
previewInitialized: true,
|
|
5041
|
+
indexError: void 0,
|
|
5042
|
+
refs: {},
|
|
5043
|
+
setSelection: ({ storyId: newStoryId }) => {
|
|
5044
|
+
const channel = import_manager_api2.addons.getChannel();
|
|
5045
|
+
channel.emit(import_core_events.SET_CURRENT_STORY, { storyId: newStoryId });
|
|
5046
|
+
},
|
|
5047
|
+
status: {},
|
|
5048
|
+
index: storyHash,
|
|
5049
|
+
storyId: story?.id,
|
|
5050
|
+
refId: DEFAULT_REF_ID
|
|
5051
|
+
}
|
|
5052
|
+
)
|
|
5053
|
+
] }),
|
|
5054
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(MobileAddonsPanel, { ref: addonPanelRef, storyId: story?.id })
|
|
5066
5055
|
] });
|
|
5067
5056
|
};
|
|
5068
5057
|
var Nav = import_react_native_theming15.styled.View({
|
|
@@ -5077,7 +5066,6 @@ var Nav = import_react_native_theming15.styled.View({
|
|
|
5077
5066
|
var Container3 = import_react_native_theming15.styled.View(({ theme }) => ({
|
|
5078
5067
|
alignSelf: "flex-end",
|
|
5079
5068
|
width: "100%",
|
|
5080
|
-
zIndex: 10,
|
|
5081
5069
|
backgroundColor: theme.barBg,
|
|
5082
5070
|
borderTopColor: theme.appBorderColor,
|
|
5083
5071
|
borderTopWidth: 1
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@storybook/react-native-ui",
|
|
3
|
-
"version": "8.
|
|
3
|
+
"version": "8.4.0-alpha.1",
|
|
4
4
|
"description": "ui components for react native storybook",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"react",
|
|
@@ -49,17 +49,18 @@
|
|
|
49
49
|
},
|
|
50
50
|
"devDependencies": {
|
|
51
51
|
"@types/jest": "^29.4.3",
|
|
52
|
-
"@types/react": "~18.
|
|
53
|
-
"babel-jest": "^29.
|
|
54
|
-
"jest": "29.7.0",
|
|
55
|
-
"react-test-renderer": "18.
|
|
52
|
+
"@types/react": "~18.3.12",
|
|
53
|
+
"babel-jest": "^29.7.0",
|
|
54
|
+
"jest": "^29.7.0",
|
|
55
|
+
"react-test-renderer": "^18.3.1",
|
|
56
|
+
"ts-dedent": "^2.2.0",
|
|
56
57
|
"tsup": "^7.2.0",
|
|
57
58
|
"typescript": "^5.3.3"
|
|
58
59
|
},
|
|
59
60
|
"dependencies": {
|
|
60
|
-
"@storybook/core": "^8.
|
|
61
|
-
"@storybook/react": "^8.
|
|
62
|
-
"@storybook/react-native-theming": "^8.
|
|
61
|
+
"@storybook/core": "^8.4.0",
|
|
62
|
+
"@storybook/react": "^8.4.0",
|
|
63
|
+
"@storybook/react-native-theming": "^8.4.0-alpha.1",
|
|
63
64
|
"fuse.js": "^7.0.0",
|
|
64
65
|
"memoizerific": "^1.11.3",
|
|
65
66
|
"polished": "^4.3.1",
|
|
@@ -80,5 +81,5 @@
|
|
|
80
81
|
"publishConfig": {
|
|
81
82
|
"access": "public"
|
|
82
83
|
},
|
|
83
|
-
"gitHead": "
|
|
84
|
+
"gitHead": "cda075d67d926d964def6d6eb9bb0fca09bb0d24"
|
|
84
85
|
}
|
package/src/Button.tsx
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { styled, useTheme } from '@storybook/react-native-theming';
|
|
2
2
|
import { ReactElement, forwardRef, useEffect, useMemo, useState } from 'react';
|
|
3
|
-
import {
|
|
3
|
+
import type { TouchableOpacityProps } from 'react-native';
|
|
4
4
|
import { SvgProps } from 'react-native-svg';
|
|
5
5
|
|
|
6
6
|
export interface ButtonProps extends TouchableOpacityProps {
|
|
@@ -15,7 +15,8 @@ export interface ButtonProps extends TouchableOpacityProps {
|
|
|
15
15
|
Icon?: (props: SvgProps) => ReactElement;
|
|
16
16
|
}
|
|
17
17
|
|
|
18
|
-
|
|
18
|
+
// TODO fix this type
|
|
19
|
+
export const Button = forwardRef<any, ButtonProps>(
|
|
19
20
|
(
|
|
20
21
|
{
|
|
21
22
|
Icon,
|
|
@@ -29,7 +30,7 @@ export const Button = forwardRef<TouchableOpacity, ButtonProps>(
|
|
|
29
30
|
children,
|
|
30
31
|
text,
|
|
31
32
|
...props
|
|
32
|
-
},
|
|
33
|
+
}: ButtonProps,
|
|
33
34
|
ref
|
|
34
35
|
) => {
|
|
35
36
|
// let Comp: 'button' | 'a' | typeof Slot = 'button';
|
package/src/IconButton.tsx
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
|
-
import { TouchableOpacity } from 'react-native';
|
|
2
1
|
import { Button, ButtonProps } from './Button';
|
|
3
2
|
import { forwardRef } from 'react';
|
|
4
3
|
|
|
5
|
-
export const IconButton = forwardRef
|
|
6
|
-
({ padding = 'small', variant = 'ghost', ...props }, ref) => {
|
|
4
|
+
export const IconButton = forwardRef(
|
|
5
|
+
({ padding = 'small', variant = 'ghost', ...props }: ButtonProps, ref) => {
|
|
7
6
|
return <Button padding={padding} variant={variant} ref={ref} {...props} />;
|
|
8
7
|
}
|
|
9
8
|
);
|
package/src/Layout.stories.tsx
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import type { Meta, StoryObj } from '@storybook/react';
|
|
2
2
|
import { Layout } from './Layout';
|
|
3
3
|
import { mockDataset } from './mockdata';
|
|
4
|
-
import { Text } from 'react-native';
|
|
4
|
+
import { Text, View } from 'react-native';
|
|
5
5
|
import { GestureHandlerRootView } from 'react-native-gesture-handler';
|
|
6
6
|
import { BottomSheetModalProvider } from '@gorhom/bottom-sheet';
|
|
7
|
+
import { LayoutProvider } from './LayoutProvider';
|
|
7
8
|
|
|
8
9
|
const meta = {
|
|
9
10
|
title: 'components/Layout',
|
|
@@ -12,7 +13,9 @@ const meta = {
|
|
|
12
13
|
(Story) => (
|
|
13
14
|
<GestureHandlerRootView style={{ flex: 1 }}>
|
|
14
15
|
<BottomSheetModalProvider>
|
|
15
|
-
<
|
|
16
|
+
<LayoutProvider>
|
|
17
|
+
<Story />
|
|
18
|
+
</LayoutProvider>
|
|
16
19
|
</BottomSheetModalProvider>
|
|
17
20
|
</GestureHandlerRootView>
|
|
18
21
|
),
|
|
@@ -31,3 +34,44 @@ export const Basic: Story = {
|
|
|
31
34
|
storyId: 'emails-buildnotification--with-changes',
|
|
32
35
|
},
|
|
33
36
|
};
|
|
37
|
+
|
|
38
|
+
export const OverflowSidebarExample: Story = {
|
|
39
|
+
args: {
|
|
40
|
+
children: (
|
|
41
|
+
<View
|
|
42
|
+
style={{
|
|
43
|
+
width: '100%',
|
|
44
|
+
backgroundColor: 'lightgreen',
|
|
45
|
+
alignItems: 'flex-end',
|
|
46
|
+
left: '-50%',
|
|
47
|
+
}}
|
|
48
|
+
>
|
|
49
|
+
<Text style={{ width: '50%', textAlign: 'right' }}>
|
|
50
|
+
This box should not overflow the side navigation in desktop mode
|
|
51
|
+
</Text>
|
|
52
|
+
</View>
|
|
53
|
+
),
|
|
54
|
+
//@ts-ignore
|
|
55
|
+
storyHash: mockDataset.withRoot,
|
|
56
|
+
storyId: 'emails-buildnotification--with-changes',
|
|
57
|
+
},
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
export const OverflowAddonsExample: Story = {
|
|
61
|
+
args: {
|
|
62
|
+
children: (
|
|
63
|
+
<View
|
|
64
|
+
style={{
|
|
65
|
+
height: '100%',
|
|
66
|
+
backgroundColor: 'lightgreen',
|
|
67
|
+
bottom: '-50%',
|
|
68
|
+
}}
|
|
69
|
+
>
|
|
70
|
+
<Text style={{ height: '50%' }}>This box should not overflow the addons panel</Text>
|
|
71
|
+
</View>
|
|
72
|
+
),
|
|
73
|
+
//@ts-ignore
|
|
74
|
+
storyHash: mockDataset.withRoot,
|
|
75
|
+
storyId: 'emails-buildnotification--with-changes',
|
|
76
|
+
},
|
|
77
|
+
};
|
package/src/Layout.tsx
CHANGED
|
@@ -4,7 +4,7 @@ import { type API_IndexHash, type Args, type StoryContext } from '@storybook/cor
|
|
|
4
4
|
import type { ReactRenderer } from '@storybook/react';
|
|
5
5
|
import { styled, useTheme } from '@storybook/react-native-theming';
|
|
6
6
|
import { ReactNode, useRef, useState } from 'react';
|
|
7
|
-
import {
|
|
7
|
+
import { ScrollView, Text, View } from 'react-native';
|
|
8
8
|
import { useSafeAreaInsets } from 'react-native-safe-area-context';
|
|
9
9
|
import { IconButton } from './IconButton';
|
|
10
10
|
import { useLayout } from './LayoutProvider';
|
|
@@ -28,8 +28,6 @@ export const Layout = ({
|
|
|
28
28
|
}) => {
|
|
29
29
|
const theme = useTheme();
|
|
30
30
|
const mobileMenuDrawerRef = useRef<MobileMenuDrawerRef>(null);
|
|
31
|
-
const [menuOpen, setMenuOpen] = useState(false);
|
|
32
|
-
const [drawerOpen, setDrawerOpen] = useState(false);
|
|
33
31
|
const addonPanelRef = useRef<MobileAddonsPanelRef>(null);
|
|
34
32
|
const insets = useSafeAreaInsets();
|
|
35
33
|
const { isDesktop } = useLayout();
|
|
@@ -105,7 +103,7 @@ export const Layout = ({
|
|
|
105
103
|
</View>
|
|
106
104
|
|
|
107
105
|
<View style={{ flex: 1 }}>
|
|
108
|
-
<View style={{ flex: 1 }}>{children}</View>
|
|
106
|
+
<View style={{ flex: 1, overflow: 'hidden' }}>{children}</View>
|
|
109
107
|
|
|
110
108
|
<View
|
|
111
109
|
style={{
|
|
@@ -133,9 +131,31 @@ export const Layout = ({
|
|
|
133
131
|
|
|
134
132
|
return (
|
|
135
133
|
<View style={{ flex: 1, paddingTop: insets.top, backgroundColor: theme.background.content }}>
|
|
136
|
-
<View style={{ flex: 1 }}>{children}</View>
|
|
137
|
-
|
|
138
|
-
<
|
|
134
|
+
<View style={{ flex: 1, overflow: 'hidden' }}>{children}</View>
|
|
135
|
+
|
|
136
|
+
<Container style={{ marginBottom: insets.bottom }}>
|
|
137
|
+
<Nav>
|
|
138
|
+
<Button
|
|
139
|
+
style={{ flexShrink: 1 }}
|
|
140
|
+
hitSlop={{ bottom: 10, left: 10, right: 10, top: 10 }}
|
|
141
|
+
onPress={() => {
|
|
142
|
+
mobileMenuDrawerRef.current.setMobileMenuOpen(true);
|
|
143
|
+
}}
|
|
144
|
+
>
|
|
145
|
+
<MenuIcon color={theme.color.mediumdark} />
|
|
146
|
+
<Text style={{ flexShrink: 1, color: theme.color.defaultText }} numberOfLines={1}>
|
|
147
|
+
{story?.title}/{story?.name}
|
|
148
|
+
</Text>
|
|
149
|
+
</Button>
|
|
150
|
+
|
|
151
|
+
<IconButton
|
|
152
|
+
onPress={() => addonPanelRef.current.setAddonsPanelOpen(true)}
|
|
153
|
+
Icon={BottomBarToggleIcon}
|
|
154
|
+
/>
|
|
155
|
+
</Nav>
|
|
156
|
+
</Container>
|
|
157
|
+
|
|
158
|
+
<MobileMenuDrawer ref={mobileMenuDrawerRef}>
|
|
139
159
|
<View style={{ paddingLeft: 16, paddingTop: 4, paddingBottom: 4 }}>
|
|
140
160
|
{theme.base === 'light' ? (
|
|
141
161
|
<Logo height={25} width={125} />
|
|
@@ -160,30 +180,7 @@ export const Layout = ({
|
|
|
160
180
|
/>
|
|
161
181
|
</MobileMenuDrawer>
|
|
162
182
|
|
|
163
|
-
<MobileAddonsPanel ref={addonPanelRef} storyId={story?.id}
|
|
164
|
-
{(Platform.OS !== 'android' || (!menuOpen && !drawerOpen)) && (
|
|
165
|
-
<Container style={{ marginBottom: insets.bottom }}>
|
|
166
|
-
<Nav>
|
|
167
|
-
<Button
|
|
168
|
-
style={{ flexShrink: 1 }}
|
|
169
|
-
hitSlop={{ bottom: 10, left: 10, right: 10, top: 10 }}
|
|
170
|
-
onPress={() => {
|
|
171
|
-
mobileMenuDrawerRef.current.setMobileMenuOpen(true);
|
|
172
|
-
}}
|
|
173
|
-
>
|
|
174
|
-
<MenuIcon color={theme.color.mediumdark} />
|
|
175
|
-
<Text style={{ flexShrink: 1, color: theme.color.defaultText }} numberOfLines={1}>
|
|
176
|
-
{story?.title}/{story?.name}
|
|
177
|
-
</Text>
|
|
178
|
-
</Button>
|
|
179
|
-
|
|
180
|
-
<IconButton
|
|
181
|
-
onPress={() => addonPanelRef.current.setAddonsPanelOpen(true)}
|
|
182
|
-
Icon={BottomBarToggleIcon}
|
|
183
|
-
/>
|
|
184
|
-
</Nav>
|
|
185
|
-
</Container>
|
|
186
|
-
)}
|
|
183
|
+
<MobileAddonsPanel ref={addonPanelRef} storyId={story?.id} />
|
|
187
184
|
</View>
|
|
188
185
|
);
|
|
189
186
|
};
|
|
@@ -201,7 +198,6 @@ const Nav = styled.View({
|
|
|
201
198
|
const Container = styled.View(({ theme }) => ({
|
|
202
199
|
alignSelf: 'flex-end',
|
|
203
200
|
width: '100%',
|
|
204
|
-
zIndex: 10,
|
|
205
201
|
backgroundColor: theme.barBg,
|
|
206
202
|
borderTopColor: theme.appBorderColor,
|
|
207
203
|
borderTopWidth: 1,
|
|
@@ -20,83 +20,76 @@ export interface MobileAddonsPanelRef {
|
|
|
20
20
|
setAddonsPanelOpen: (isOpen: boolean) => void;
|
|
21
21
|
}
|
|
22
22
|
|
|
23
|
-
export const MobileAddonsPanel = forwardRef<
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
}}
|
|
94
|
-
storyId={storyId}
|
|
95
|
-
/>
|
|
96
|
-
</Animated.View>
|
|
97
|
-
</BottomSheetModal>
|
|
98
|
-
);
|
|
99
|
-
});
|
|
23
|
+
export const MobileAddonsPanel = forwardRef<MobileAddonsPanelRef, { storyId?: string }>(
|
|
24
|
+
({ storyId }, ref) => {
|
|
25
|
+
const theme = useTheme();
|
|
26
|
+
const reducedMotion = useReducedMotion();
|
|
27
|
+
|
|
28
|
+
const addonsPanelBottomSheetRef = useRef<BottomSheetModal>(null);
|
|
29
|
+
const insets = useSafeAreaInsets();
|
|
30
|
+
|
|
31
|
+
const animatedPosition = useSharedValue(0);
|
|
32
|
+
|
|
33
|
+
// bringing in animated keyboard disables android resizing
|
|
34
|
+
// TODO replicate functionality without this
|
|
35
|
+
useAnimatedKeyboard();
|
|
36
|
+
|
|
37
|
+
useImperativeHandle(ref, () => ({
|
|
38
|
+
setAddonsPanelOpen: (open: boolean) => {
|
|
39
|
+
if (open) {
|
|
40
|
+
addonsPanelBottomSheetRef.current?.present();
|
|
41
|
+
} else {
|
|
42
|
+
addonsPanelBottomSheetRef.current?.dismiss();
|
|
43
|
+
}
|
|
44
|
+
},
|
|
45
|
+
}));
|
|
46
|
+
|
|
47
|
+
const { height } = useWindowDimensions();
|
|
48
|
+
|
|
49
|
+
const adjustedBottomSheetSize = useAnimatedStyle(() => {
|
|
50
|
+
return {
|
|
51
|
+
maxHeight: height - animatedPosition.value - insets.bottom,
|
|
52
|
+
};
|
|
53
|
+
}, [animatedPosition.value, height, insets.bottom]);
|
|
54
|
+
|
|
55
|
+
return (
|
|
56
|
+
<BottomSheetModal
|
|
57
|
+
ref={addonsPanelBottomSheetRef}
|
|
58
|
+
index={1}
|
|
59
|
+
animateOnMount={!reducedMotion}
|
|
60
|
+
snapPoints={['25%', '50%', '75%']}
|
|
61
|
+
style={{
|
|
62
|
+
paddingTop: 8,
|
|
63
|
+
}}
|
|
64
|
+
animatedPosition={animatedPosition}
|
|
65
|
+
containerStyle={{}}
|
|
66
|
+
backgroundStyle={{
|
|
67
|
+
borderRadius: 0,
|
|
68
|
+
borderTopColor: theme.appBorderColor,
|
|
69
|
+
borderTopWidth: 1,
|
|
70
|
+
backgroundColor: theme.background.content,
|
|
71
|
+
}}
|
|
72
|
+
handleIndicatorStyle={{ backgroundColor: theme.textMutedColor }}
|
|
73
|
+
keyboardBehavior="extend"
|
|
74
|
+
// keyboardBlurBehavior="restore"
|
|
75
|
+
enableDismissOnClose
|
|
76
|
+
enableHandlePanningGesture={true}
|
|
77
|
+
// enableContentPanningGesture={true}
|
|
78
|
+
stackBehavior="replace"
|
|
79
|
+
enableDynamicSizing={false}
|
|
80
|
+
>
|
|
81
|
+
<Animated.View style={[{ flex: 1 }, adjustedBottomSheetSize]}>
|
|
82
|
+
<AddonsTabs
|
|
83
|
+
onClose={() => {
|
|
84
|
+
addonsPanelBottomSheetRef.current?.dismiss();
|
|
85
|
+
}}
|
|
86
|
+
storyId={storyId}
|
|
87
|
+
/>
|
|
88
|
+
</Animated.View>
|
|
89
|
+
</BottomSheetModal>
|
|
90
|
+
);
|
|
91
|
+
}
|
|
92
|
+
);
|
|
100
93
|
|
|
101
94
|
export const AddonsTabs = ({ onClose, storyId }: { onClose?: () => void; storyId?: string }) => {
|
|
102
95
|
const panels = addons.getElements(Addon_TypesEnum.PANEL);
|
package/src/MobileMenuDrawer.tsx
CHANGED
|
@@ -12,7 +12,6 @@ import { useTheme } from '@storybook/react-native-theming';
|
|
|
12
12
|
|
|
13
13
|
interface MobileMenuDrawerProps {
|
|
14
14
|
children: ReactNode | ReactNode[];
|
|
15
|
-
onStateChange: (isOpen: boolean) => void;
|
|
16
15
|
}
|
|
17
16
|
|
|
18
17
|
export interface MobileMenuDrawerRef {
|
|
@@ -30,7 +29,7 @@ export const BottomSheetBackdropComponent = (backdropComponentProps: BottomSheet
|
|
|
30
29
|
);
|
|
31
30
|
|
|
32
31
|
export const MobileMenuDrawer = forwardRef<MobileMenuDrawerRef, MobileMenuDrawerProps>(
|
|
33
|
-
({ children
|
|
32
|
+
({ children }, ref) => {
|
|
34
33
|
const reducedMotion = useReducedMotion();
|
|
35
34
|
const insets = useSafeAreaInsets();
|
|
36
35
|
const theme = useTheme();
|
|
@@ -40,12 +39,10 @@ export const MobileMenuDrawer = forwardRef<MobileMenuDrawerRef, MobileMenuDrawer
|
|
|
40
39
|
useImperativeHandle(ref, () => ({
|
|
41
40
|
setMobileMenuOpen: (open: boolean) => {
|
|
42
41
|
if (open) {
|
|
43
|
-
onStateChange(true);
|
|
44
|
-
|
|
45
42
|
menuBottomSheetRef.current?.present();
|
|
46
43
|
} else {
|
|
47
44
|
Keyboard.dismiss();
|
|
48
|
-
|
|
45
|
+
|
|
49
46
|
menuBottomSheetRef.current?.dismiss();
|
|
50
47
|
}
|
|
51
48
|
},
|
|
@@ -56,9 +53,6 @@ export const MobileMenuDrawer = forwardRef<MobileMenuDrawerRef, MobileMenuDrawer
|
|
|
56
53
|
ref={menuBottomSheetRef}
|
|
57
54
|
index={1}
|
|
58
55
|
animateOnMount={!reducedMotion}
|
|
59
|
-
onDismiss={() => {
|
|
60
|
-
onStateChange(false);
|
|
61
|
-
}}
|
|
62
56
|
snapPoints={['50%', '75%']}
|
|
63
57
|
enableDismissOnClose
|
|
64
58
|
enableHandlePanningGesture
|