@applicaster/zapp-react-native-utils 14.0.17 → 14.0.18-alpha.5740764222
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/package.json +2 -2
- package/reactHooks/layout/__tests__/index.test.tsx +17 -0
- package/reactHooks/layout/types/index.ts +6 -0
- package/reactHooks/layout/useDimensions/__tests__/useDimensions.test.ts +38 -0
- package/reactHooks/layout/useDimensions/useDimensions.ts +62 -5
- package/reactHooks/resolvers/__tests__/useCellResolver.test.tsx +11 -13
- package/reactHooks/resolvers/useCellResolver.ts +1 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@applicaster/zapp-react-native-utils",
|
|
3
|
-
"version": "14.0.
|
|
3
|
+
"version": "14.0.18-alpha.5740764222",
|
|
4
4
|
"description": "Applicaster Zapp React Native utilities package",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"types": "index.d.ts",
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
},
|
|
28
28
|
"homepage": "https://github.com/applicaster/quickbrick#readme",
|
|
29
29
|
"dependencies": {
|
|
30
|
-
"@applicaster/applicaster-types": "14.0.
|
|
30
|
+
"@applicaster/applicaster-types": "14.0.18-alpha.5740764222",
|
|
31
31
|
"buffer": "^5.2.1",
|
|
32
32
|
"camelize": "^1.0.0",
|
|
33
33
|
"dayjs": "^1.11.10",
|
|
@@ -39,6 +39,7 @@ ReactNative.NativeModules.QuickBrickCommunicationModule =
|
|
|
39
39
|
|
|
40
40
|
jest.mock("react-native-safe-area-context", () => ({
|
|
41
41
|
useSafeAreaInsets: () => ({ top: 50 }),
|
|
42
|
+
useSafeAreaFrame: () => ({ x: 0, y: 0, width: 100, height: 100 }),
|
|
42
43
|
}));
|
|
43
44
|
|
|
44
45
|
jest.mock("../../../reactUtils", () => ({
|
|
@@ -49,6 +50,22 @@ jest.mock("../../../reactUtils", () => ({
|
|
|
49
50
|
|
|
50
51
|
jest.mock("../../navigation", () => ({
|
|
51
52
|
useIsScreenActive: () => true,
|
|
53
|
+
useRoute: () => ({
|
|
54
|
+
screenData: { general: { screen_orientation: "portrait" } },
|
|
55
|
+
}),
|
|
56
|
+
}));
|
|
57
|
+
|
|
58
|
+
jest.mock("../../screen", () => ({
|
|
59
|
+
useCurrentScreenData: () => null,
|
|
60
|
+
}));
|
|
61
|
+
|
|
62
|
+
jest.mock("../../device", () => ({
|
|
63
|
+
useIsTablet: () => false,
|
|
64
|
+
}));
|
|
65
|
+
|
|
66
|
+
jest.mock("../../../appUtils/orientationHelper", () => ({
|
|
67
|
+
getScreenOrientation: jest.fn(() => 1), // portrait
|
|
68
|
+
isOrientationCompatible: jest.fn(() => true),
|
|
52
69
|
}));
|
|
53
70
|
|
|
54
71
|
jest.mock("../../navigation/useNavigation");
|
|
@@ -22,6 +22,12 @@ export type Options = {
|
|
|
22
22
|
rounded?: boolean;
|
|
23
23
|
deviceInfo?: boolean;
|
|
24
24
|
updateForInactiveScreens?: boolean;
|
|
25
|
+
/**
|
|
26
|
+
* When true, dimensions will only update when they match the screen's target orientation.
|
|
27
|
+
* Returns the last valid dimensions during orientation transitions.
|
|
28
|
+
* Requires updateForInactiveScreens: false to work properly.
|
|
29
|
+
*/
|
|
30
|
+
waitForValidOrientation?: boolean;
|
|
25
31
|
};
|
|
26
32
|
|
|
27
33
|
export type Context = "window" | "screen";
|
|
@@ -19,6 +19,28 @@ jest.mock(
|
|
|
19
19
|
})
|
|
20
20
|
);
|
|
21
21
|
|
|
22
|
+
jest.mock("@applicaster/zapp-react-native-utils/reactHooks/screen", () => ({
|
|
23
|
+
useCurrentScreenData: jest.fn().mockReturnValue(null),
|
|
24
|
+
}));
|
|
25
|
+
|
|
26
|
+
jest.mock("@applicaster/zapp-react-native-utils/reactHooks/navigation", () => ({
|
|
27
|
+
useRoute: jest.fn().mockReturnValue({
|
|
28
|
+
screenData: { general: { screen_orientation: "portrait" } },
|
|
29
|
+
}),
|
|
30
|
+
}));
|
|
31
|
+
|
|
32
|
+
jest.mock("@applicaster/zapp-react-native-utils/reactHooks/device", () => ({
|
|
33
|
+
useIsTablet: jest.fn().mockReturnValue(false),
|
|
34
|
+
}));
|
|
35
|
+
|
|
36
|
+
jest.mock(
|
|
37
|
+
"@applicaster/zapp-react-native-utils/appUtils/orientationHelper",
|
|
38
|
+
() => ({
|
|
39
|
+
getScreenOrientation: jest.fn().mockReturnValue(1), // portrait
|
|
40
|
+
isOrientationCompatible: jest.fn().mockReturnValue(true),
|
|
41
|
+
})
|
|
42
|
+
);
|
|
43
|
+
|
|
22
44
|
jest.doMock("../helpers", () => ({
|
|
23
45
|
getInitialDimensions: jest
|
|
24
46
|
.fn()
|
|
@@ -129,4 +151,20 @@ describe("useDimensions", () => {
|
|
|
129
151
|
|
|
130
152
|
consoleWarnSpy.mockRestore();
|
|
131
153
|
});
|
|
154
|
+
|
|
155
|
+
it("accepts waitForValidOrientation option", () => {
|
|
156
|
+
// Smoke test to verify the option is accepted without errors
|
|
157
|
+
const { result } = renderHook(() =>
|
|
158
|
+
useDimensions("screen", {
|
|
159
|
+
updateForInactiveScreens: false,
|
|
160
|
+
waitForValidOrientation: true,
|
|
161
|
+
})
|
|
162
|
+
);
|
|
163
|
+
|
|
164
|
+
expect(result.current).toMatchObject({
|
|
165
|
+
width: expect.any(Number),
|
|
166
|
+
height: expect.any(Number),
|
|
167
|
+
statusBarHeight: expect.any(Number),
|
|
168
|
+
});
|
|
169
|
+
});
|
|
132
170
|
});
|
|
@@ -11,6 +11,13 @@ import { Options, UseDimensions } from "../types";
|
|
|
11
11
|
import { getDeviceInfo } from "../getDeviceInfo";
|
|
12
12
|
import { getInitialDimensions } from "./helpers";
|
|
13
13
|
import { useIsScreenActive } from "../../navigation/useIsScreenActive";
|
|
14
|
+
import {
|
|
15
|
+
getScreenOrientation,
|
|
16
|
+
isOrientationCompatible,
|
|
17
|
+
} from "../../../appUtils/orientationHelper";
|
|
18
|
+
import { useCurrentScreenData } from "../../screen";
|
|
19
|
+
import { useRoute } from "../../navigation";
|
|
20
|
+
import { useIsTablet } from "../../device";
|
|
14
21
|
|
|
15
22
|
function compensateForScaleIfNeeded(context) {
|
|
16
23
|
return function () {
|
|
@@ -59,9 +66,43 @@ export const useDimensions: UseDimensions = (
|
|
|
59
66
|
options.fullDimensions = false;
|
|
60
67
|
}
|
|
61
68
|
|
|
69
|
+
if (options.waitForValidOrientation === undefined) {
|
|
70
|
+
options.waitForValidOrientation = false;
|
|
71
|
+
}
|
|
72
|
+
|
|
62
73
|
const [dimensions, setDimensions] = useState(getInitialDimensions(context));
|
|
63
74
|
const deviceInfo = useRef(getDeviceInfo(dimensions, appData));
|
|
64
75
|
|
|
76
|
+
// Orientation validation setup (only when waitForValidOrientation is enabled)
|
|
77
|
+
const currentScreenData = useCurrentScreenData();
|
|
78
|
+
const { screenData } = useRoute();
|
|
79
|
+
const isTablet = useIsTablet();
|
|
80
|
+
const isTabletPortrait = appData?.isTabletPortrait;
|
|
81
|
+
|
|
82
|
+
const targetScreenData =
|
|
83
|
+
currentScreenData || (screenData as any)?.targetScreen || screenData;
|
|
84
|
+
|
|
85
|
+
const orientation = options.waitForValidOrientation
|
|
86
|
+
? getScreenOrientation({
|
|
87
|
+
screenData: targetScreenData,
|
|
88
|
+
layoutData: { isTablet, isTabletPortrait },
|
|
89
|
+
})
|
|
90
|
+
: null;
|
|
91
|
+
|
|
92
|
+
const isOrientationValid = options.waitForValidOrientation
|
|
93
|
+
? isOrientationCompatible({
|
|
94
|
+
orientation,
|
|
95
|
+
layoutData: {
|
|
96
|
+
isTablet,
|
|
97
|
+
isTabletPortrait,
|
|
98
|
+
width: dimensions.width,
|
|
99
|
+
height: dimensions.height,
|
|
100
|
+
},
|
|
101
|
+
})
|
|
102
|
+
: true;
|
|
103
|
+
|
|
104
|
+
const lastValidDimensions = useRef(dimensions);
|
|
105
|
+
|
|
65
106
|
const applyOptions = R.compose(
|
|
66
107
|
R.when(() => options.deviceInfo, R.assoc("deviceInfo", deviceInfo.current)),
|
|
67
108
|
R.when(
|
|
@@ -109,13 +150,29 @@ export const useDimensions: UseDimensions = (
|
|
|
109
150
|
};
|
|
110
151
|
}, [isActive]);
|
|
111
152
|
|
|
153
|
+
let dimensionsToUse;
|
|
154
|
+
|
|
155
|
+
// When waitForValidOrientation is enabled, freeze dimensions during invalid orientation
|
|
156
|
+
if (options.waitForValidOrientation) {
|
|
157
|
+
if (isOrientationValid) {
|
|
158
|
+
// Store last valid dimensions to return during orientation transitions
|
|
159
|
+
lastValidDimensions.current = dimensions;
|
|
160
|
+
dimensionsToUse = dimensions;
|
|
161
|
+
} else {
|
|
162
|
+
// Return last valid dimensions during orientation transitions
|
|
163
|
+
dimensionsToUse = lastValidDimensions.current;
|
|
164
|
+
}
|
|
165
|
+
} else {
|
|
166
|
+
dimensionsToUse = dimensions;
|
|
167
|
+
}
|
|
168
|
+
|
|
112
169
|
const memoizedDimensions = useMemo(() => {
|
|
113
|
-
return { ...applyOptions(
|
|
170
|
+
return { ...applyOptions(dimensionsToUse), statusBarHeight };
|
|
114
171
|
}, [
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
172
|
+
dimensionsToUse.width,
|
|
173
|
+
dimensionsToUse.height,
|
|
174
|
+
dimensionsToUse.fontScale,
|
|
175
|
+
dimensionsToUse.scale,
|
|
119
176
|
]);
|
|
120
177
|
|
|
121
178
|
return memoizedDimensions;
|
|
@@ -1,10 +1,7 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
2
|
import { View } from "react-native";
|
|
3
|
-
import { cleanup
|
|
4
|
-
import
|
|
5
|
-
import { Provider } from "react-redux";
|
|
6
|
-
|
|
7
|
-
const mockStore = configureStore([]);
|
|
3
|
+
import { cleanup } from "@testing-library/react-native";
|
|
4
|
+
import { renderWithProviders } from "../../../testUtils";
|
|
8
5
|
|
|
9
6
|
const mock_rtl_flag = false;
|
|
10
7
|
|
|
@@ -46,12 +43,7 @@ describe("cellResolver", () => {
|
|
|
46
43
|
},
|
|
47
44
|
};
|
|
48
45
|
|
|
49
|
-
const
|
|
50
|
-
|
|
51
|
-
// eslint-disable-next-line react/prop-types
|
|
52
|
-
const wrapper = ({ children }) => (
|
|
53
|
-
<Provider store={store}>{children}</Provider>
|
|
54
|
-
);
|
|
46
|
+
const storeState = { cellStyles, styles, plugins };
|
|
55
47
|
|
|
56
48
|
afterEach(() => {
|
|
57
49
|
cleanup();
|
|
@@ -61,8 +53,14 @@ describe("cellResolver", () => {
|
|
|
61
53
|
expect(useCellResolver).toBeDefined();
|
|
62
54
|
});
|
|
63
55
|
|
|
64
|
-
it("
|
|
65
|
-
|
|
56
|
+
it("resolves cell plugin", () => {
|
|
57
|
+
const TestComponent = () => {
|
|
58
|
+
const resolvedCell = useCellResolver({ component });
|
|
59
|
+
|
|
60
|
+
return <>{resolvedCell}</>;
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
renderWithProviders(<TestComponent />, storeState);
|
|
66
64
|
|
|
67
65
|
expect(testCellModule).toBeCalled();
|
|
68
66
|
});
|