@applicaster/zapp-react-native-ui-components 14.0.40-alpha.3512631313 → 14.0.40-rc.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,33 @@
1
+ import React from "react";
2
+ import { PanGestureHandler } from "react-native-gesture-handler";
3
+ import { View } from "react-native";
4
+ import { useBottomSheet } from "@applicaster/zapp-react-native-utils/bottomSheet";
5
+
6
+ /**
7
+ * Turns its children into a drag zone for the enclosing DraggableBottomSheet:
8
+ * dragging here moves/dismisses the sheet (used for the modal header bar).
9
+ * Outside a sheet (no context) it renders children unchanged.
10
+ */
11
+ export const BottomSheetDragArea = ({
12
+ children,
13
+ }: {
14
+ children: React.ReactElement;
15
+ }) => {
16
+ const sheet = useBottomSheet();
17
+
18
+ // Outside a sheet (no context) render children unchanged.
19
+ if (!sheet) return children;
20
+
21
+ return (
22
+ <PanGestureHandler
23
+ simultaneousHandlers={[sheet.masterDrawerRef]}
24
+ shouldCancelWhenOutside={false}
25
+ onGestureEvent={sheet.onDragGestureEvent}
26
+ onHandlerStateChange={sheet.onDragStateChange}
27
+ >
28
+ {/* Old-API PanGestureHandler needs a host-component child; children may
29
+ be a function component (e.g. ModalHeader), so wrap in a View. */}
30
+ <View>{children}</View>
31
+ </PanGestureHandler>
32
+ );
33
+ };
@@ -6,11 +6,11 @@ import { ItemProps } from "./Button/Item";
6
6
  import { ItemLabelProps } from "./Button/ItemLabel";
7
7
  import { getItemIconProps, getItemLabelProps, getItemProps } from "./utils";
8
8
  import { useTheme } from "@applicaster/zapp-react-native-utils/theme";
9
-
10
9
  import type { PluginConfiguration } from "./";
11
10
 
12
11
  import { ModalHeader as DefaultModalHeader } from "./Header";
13
12
  import { useSafeAreaInsets } from "react-native-safe-area-context";
13
+ import { BottomSheetDragArea } from "./BottomSheetDragArea";
14
14
 
15
15
  type ModalComponentProps = {
16
16
  items: any[];
@@ -38,6 +38,10 @@ type ModalComponentProps = {
38
38
  theme: PluginConfiguration
39
39
  ) => ItemIconProps["asset"] | null;
40
40
  iconPlacement?: "left" | "right";
41
+ scrollViewContent?: {
42
+ renderItem: (item: any, index: number) => React.ReactNode;
43
+ items: any[];
44
+ } | null;
41
45
  };
42
46
 
43
47
  export function BottomSheetModalContent(props: ModalComponentProps) {
@@ -49,7 +53,9 @@ export function BottomSheetModalContent(props: ModalComponentProps) {
49
53
  dismiss,
50
54
  summary,
51
55
  title,
52
- headerComponent: ModalHeader = DefaultModalHeader,
56
+ headerComponent = DefaultModalHeader,
57
+ scrollViewContent = null,
58
+
53
59
  buttonComponent: ButtonComponent = Button,
54
60
  getSelectedItemIcon = ({
55
61
  modal_bottom_sheet_item_selected_icon,
@@ -63,6 +69,8 @@ export function BottomSheetModalContent(props: ModalComponentProps) {
63
69
  const paddingTop = Number(theme.modal_bottom_sheet_padding_top);
64
70
  const paddingBottom = Number(theme.modal_bottom_sheet_padding_bottom);
65
71
 
72
+ const Header = headerComponent;
73
+
66
74
  useEffect(() => {
67
75
  if (currentRoute !== route.current) {
68
76
  props.dismiss();
@@ -98,35 +106,48 @@ export function BottomSheetModalContent(props: ModalComponentProps) {
98
106
  paddingTop: paddingTop,
99
107
  }}
100
108
  >
101
- <ModalHeader
102
- dismiss={dismiss}
103
- configuration={theme}
104
- summary={summary}
105
- title={title}
106
- />
109
+ {Header ? (
110
+ <BottomSheetDragArea>
111
+ <Header
112
+ dismiss={dismiss}
113
+ configuration={theme}
114
+ summary={summary}
115
+ title={title}
116
+ />
117
+ </BottomSheetDragArea>
118
+ ) : null}
107
119
  <ScrollView
120
+ overScrollMode="never"
121
+ bounces={false}
122
+ showsVerticalScrollIndicator={false}
108
123
  contentContainerStyle={{
109
124
  paddingBottom: paddingBottom + bottomInset,
110
125
  }}
111
126
  >
112
- {items.map((item, index) =>
113
- item ? (
114
- <ButtonComponent
115
- key={index}
116
- configuration={theme}
117
- selectedItem={current_selection}
118
- item={item}
119
- onPress={handlePress}
120
- label={theme[item?.label] ?? item?.label}
121
- iconBaseProps={iconBaseProps}
122
- itemBaseProps={itemBaseProps}
123
- labelBaseProps={labelBaseProps}
124
- selectedItemIcon={getSelectedItemIcon(theme)}
125
- defaultItemIcon={getDefaultItemIcon(theme)}
126
- iconPlacement={iconPlacement}
127
- />
128
- ) : null
129
- )}
127
+ {scrollViewContent
128
+ ? scrollViewContent.items.map((item, index) =>
129
+ scrollViewContent.renderItem(item, index)
130
+ )
131
+ : null}
132
+ {!scrollViewContent &&
133
+ items.map((item, index) =>
134
+ item ? (
135
+ <ButtonComponent
136
+ key={index}
137
+ configuration={theme}
138
+ selectedItem={current_selection}
139
+ item={item}
140
+ onPress={handlePress}
141
+ label={theme[item?.label] ?? item?.label}
142
+ iconBaseProps={iconBaseProps}
143
+ itemBaseProps={itemBaseProps}
144
+ labelBaseProps={labelBaseProps}
145
+ selectedItemIcon={getSelectedItemIcon(theme)}
146
+ defaultItemIcon={getDefaultItemIcon(theme)}
147
+ iconPlacement={iconPlacement}
148
+ />
149
+ ) : null
150
+ )}
130
151
  </ScrollView>
131
152
  </View>
132
153
  );
@@ -0,0 +1,74 @@
1
+ import React from "react";
2
+ import { Text } from "react-native";
3
+ import { render, screen } from "@testing-library/react-native";
4
+ import { BottomSheetDragArea } from "../BottomSheetDragArea";
5
+ import { BottomSheetContext } from "@applicaster/zapp-react-native-utils/bottomSheet";
6
+
7
+ // Reveal PanGestureHandler and capture its props.
8
+ jest.mock("react-native-gesture-handler", () => {
9
+ const { View } = require("react-native");
10
+ const actual = jest.requireActual("react-native-gesture-handler");
11
+
12
+ return {
13
+ __esModule: true,
14
+ ...actual,
15
+ PanGestureHandler: ({
16
+ children,
17
+ onGestureEvent,
18
+ onHandlerStateChange,
19
+ simultaneousHandlers,
20
+ }: any) => (
21
+ <View
22
+ testID="drag-pan"
23
+ onGestureEvent={onGestureEvent}
24
+ onHandlerStateChange={onHandlerStateChange}
25
+ simultaneousHandlers={simultaneousHandlers}
26
+ >
27
+ {children}
28
+ </View>
29
+ ),
30
+ };
31
+ });
32
+
33
+ const makeValue = () => ({
34
+ scrollRef: React.createRef<any>(),
35
+ masterDrawerRef: React.createRef<any>(),
36
+ drawerRef: React.createRef<any>(),
37
+ onScroll: jest.fn(),
38
+ setBodyDragEnabled: jest.fn(),
39
+ onDragGestureEvent: jest.fn(),
40
+ onDragStateChange: jest.fn(),
41
+ });
42
+
43
+ describe("BottomSheetDragArea", () => {
44
+ it("wraps children in a sheet-wired PanGestureHandler when inside a sheet", () => {
45
+ const value = makeValue();
46
+
47
+ render(
48
+ <BottomSheetContext.Provider value={value}>
49
+ <BottomSheetDragArea>
50
+ <Text testID="child">hi</Text>
51
+ </BottomSheetDragArea>
52
+ </BottomSheetContext.Provider>
53
+ );
54
+
55
+ const pan = screen.getByTestId("drag-pan");
56
+ expect(pan.props.onGestureEvent).toBe(value.onDragGestureEvent);
57
+ expect(pan.props.onHandlerStateChange).toBe(value.onDragStateChange);
58
+
59
+ expect(pan.props.simultaneousHandlers).toEqual([value.masterDrawerRef]);
60
+
61
+ expect(screen.getByTestId("child")).toBeTruthy();
62
+ });
63
+
64
+ it("renders children bare when used outside a sheet", () => {
65
+ render(
66
+ <BottomSheetDragArea>
67
+ <Text testID="child">hi</Text>
68
+ </BottomSheetDragArea>
69
+ );
70
+
71
+ expect(screen.queryByTestId("drag-pan")).toBeNull();
72
+ expect(screen.getByTestId("child")).toBeTruthy();
73
+ });
74
+ });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@applicaster/zapp-react-native-ui-components",
3
- "version": "14.0.40-alpha.3512631313",
3
+ "version": "14.0.40-rc.0",
4
4
  "description": "Applicaster Zapp React Native ui components for the Quick Brick App",
5
5
  "main": "index.js",
6
6
  "types": "index.d.ts",
@@ -28,10 +28,10 @@
28
28
  },
29
29
  "homepage": "https://github.com/applicaster/quickbrick#readme",
30
30
  "dependencies": {
31
- "@applicaster/applicaster-types": "14.0.40-alpha.3512631313",
32
- "@applicaster/zapp-react-native-bridge": "14.0.40-alpha.3512631313",
33
- "@applicaster/zapp-react-native-redux": "14.0.40-alpha.3512631313",
34
- "@applicaster/zapp-react-native-utils": "14.0.40-alpha.3512631313",
31
+ "@applicaster/applicaster-types": "14.0.40-rc.0",
32
+ "@applicaster/zapp-react-native-bridge": "14.0.40-rc.0",
33
+ "@applicaster/zapp-react-native-redux": "14.0.40-rc.0",
34
+ "@applicaster/zapp-react-native-utils": "14.0.40-rc.0",
35
35
  "fast-json-stable-stringify": "^2.1.0",
36
36
  "promise": "^8.3.0",
37
37
  "url": "^0.11.0",