@react-navigation/elements 2.4.5 → 2.5.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.
- package/lib/module/SafeAreaProviderCompat.js +1 -0
- package/lib/module/SafeAreaProviderCompat.js.map +1 -1
- package/lib/module/useFrameSize.js +48 -50
- package/lib/module/useFrameSize.js.map +1 -1
- package/lib/typescript/src/SafeAreaProviderCompat.d.ts.map +1 -1
- package/lib/typescript/src/useFrameSize.d.ts +8 -4
- package/lib/typescript/src/useFrameSize.d.ts.map +1 -1
- package/package.json +7 -5
- package/src/SafeAreaProviderCompat.tsx +5 -1
- package/src/useFrameSize.tsx +84 -69
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["React","Dimensions","Platform","StyleSheet","View","initialWindowMetrics","SafeAreaInsetsContext","SafeAreaProvider","FrameSizeProvider","jsx","_jsx","width","height","get","initialMetrics","OS","frame","x","y","insets","top","left","right","bottom","SafeAreaProviderCompat","children","style","useContext","styles","container","create","flex"],"sourceRoot":"../../src","sources":["SafeAreaProviderCompat.tsx"],"mappings":";;AAAA,OAAO,KAAKA,KAAK,MAAM,OAAO;AAC9B,SACEC,UAAU,EACVC,QAAQ,EAERC,UAAU,EACVC,IAAI,QAEC,cAAc;AACrB,SACEC,oBAAoB,EACpBC,qBAAqB,EACrBC,gBAAgB,QACX,gCAAgC;AAEvC,SAASC,iBAAiB,QAAQ,mBAAgB;AAAC,SAAAC,GAAA,IAAAC,IAAA;AAOnD,MAAM;EAAEC,KAAK,GAAG,CAAC;EAAEC,MAAM,GAAG;AAAE,CAAC,GAAGX,UAAU,CAACY,GAAG,CAAC,QAAQ,CAAC;;AAE1D;AACA;AACA;AACA,MAAMC,cAAc,GAClBZ,QAAQ,CAACa,EAAE,KAAK,KAAK,IAAIV,oBAAoB,IAAI,IAAI,GACjD;EACEW,KAAK,EAAE;IAAEC,CAAC,EAAE,CAAC;IAAEC,CAAC,EAAE,CAAC;IAAEP,KAAK;IAAEC;EAAO,CAAC;EACpCO,MAAM,EAAE;IAAEC,GAAG,EAAE,CAAC;IAAEC,IAAI,EAAE,CAAC;IAAEC,KAAK,EAAE,CAAC;IAAEC,MAAM,EAAE;EAAE;AACjD,CAAC,GACDlB,oBAAoB;AAE1B,OAAO,SAASmB,sBAAsBA,CAAC;EAAEC,QAAQ;EAAEC;AAAa,CAAC,EAAE;EACjE,MAAMP,MAAM,GAAGnB,KAAK,CAAC2B,UAAU,CAACrB,qBAAqB,CAAC;EAEtDmB,QAAQ,
|
|
1
|
+
{"version":3,"names":["React","Dimensions","Platform","StyleSheet","View","initialWindowMetrics","SafeAreaInsetsContext","SafeAreaProvider","FrameSizeProvider","jsx","_jsx","width","height","get","initialMetrics","OS","frame","x","y","insets","top","left","right","bottom","SafeAreaProviderCompat","children","style","useContext","initialFrame","styles","container","create","flex"],"sourceRoot":"../../src","sources":["SafeAreaProviderCompat.tsx"],"mappings":";;AAAA,OAAO,KAAKA,KAAK,MAAM,OAAO;AAC9B,SACEC,UAAU,EACVC,QAAQ,EAERC,UAAU,EACVC,IAAI,QAEC,cAAc;AACrB,SACEC,oBAAoB,EACpBC,qBAAqB,EACrBC,gBAAgB,QACX,gCAAgC;AAEvC,SAASC,iBAAiB,QAAQ,mBAAgB;AAAC,SAAAC,GAAA,IAAAC,IAAA;AAOnD,MAAM;EAAEC,KAAK,GAAG,CAAC;EAAEC,MAAM,GAAG;AAAE,CAAC,GAAGX,UAAU,CAACY,GAAG,CAAC,QAAQ,CAAC;;AAE1D;AACA;AACA;AACA,MAAMC,cAAc,GAClBZ,QAAQ,CAACa,EAAE,KAAK,KAAK,IAAIV,oBAAoB,IAAI,IAAI,GACjD;EACEW,KAAK,EAAE;IAAEC,CAAC,EAAE,CAAC;IAAEC,CAAC,EAAE,CAAC;IAAEP,KAAK;IAAEC;EAAO,CAAC;EACpCO,MAAM,EAAE;IAAEC,GAAG,EAAE,CAAC;IAAEC,IAAI,EAAE,CAAC;IAAEC,KAAK,EAAE,CAAC;IAAEC,MAAM,EAAE;EAAE;AACjD,CAAC,GACDlB,oBAAoB;AAE1B,OAAO,SAASmB,sBAAsBA,CAAC;EAAEC,QAAQ;EAAEC;AAAa,CAAC,EAAE;EACjE,MAAMP,MAAM,GAAGnB,KAAK,CAAC2B,UAAU,CAACrB,qBAAqB,CAAC;EAEtDmB,QAAQ,gBACNf,IAAA,CAACF,iBAAiB;IAACoB,YAAY,EAAEd,cAAc,CAACE,KAAM;IAAAS,QAAA,EACnDA;EAAQ,CACQ,CACpB;EAED,IAAIN,MAAM,EAAE;IACV;IACA;IACA;IACA,oBAAOT,IAAA,CAACN,IAAI;MAACsB,KAAK,EAAE,CAACG,MAAM,CAACC,SAAS,EAAEJ,KAAK,CAAE;MAAAD,QAAA,EAAEA;IAAQ,CAAO,CAAC;EAClE;EAEA,oBACEf,IAAA,CAACH,gBAAgB;IAACO,cAAc,EAAEA,cAAe;IAACY,KAAK,EAAEA,KAAM;IAAAD,QAAA,EAC5DA;EAAQ,CACO,CAAC;AAEvB;AAEAD,sBAAsB,CAACV,cAAc,GAAGA,cAAc;AAEtD,MAAMe,MAAM,GAAG1B,UAAU,CAAC4B,MAAM,CAAC;EAC/BD,SAAS,EAAE;IACTE,IAAI,EAAE;EACR;AACF,CAAC,CAAC","ignoreList":[]}
|
|
@@ -1,21 +1,24 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
3
|
import * as React from 'react';
|
|
4
|
-
import {
|
|
4
|
+
import { Platform, StyleSheet } from 'react-native';
|
|
5
|
+
import { SafeAreaListener,
|
|
5
6
|
// eslint-disable-next-line no-restricted-imports
|
|
6
|
-
|
|
7
|
+
useSafeAreaFrame } from 'react-native-safe-area-context';
|
|
7
8
|
import useLatestCallback from 'use-latest-callback';
|
|
8
|
-
import {
|
|
9
|
+
import { useSyncExternalStoreWithSelector } from 'use-sync-external-store/with-selector';
|
|
10
|
+
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
9
11
|
const FrameContext = /*#__PURE__*/React.createContext(undefined);
|
|
10
12
|
export function useFrameSize(selector, debounce) {
|
|
11
13
|
const context = React.useContext(FrameContext);
|
|
12
14
|
if (context == null) {
|
|
13
15
|
throw new Error('useFrameSize must be used within a FrameSizeProvider');
|
|
14
16
|
}
|
|
15
|
-
const value =
|
|
17
|
+
const value = useSyncExternalStoreWithSelector(debounce ? context.subscribeDebounced : context.subscribe, context.getCurrent, context.getCurrent, selector);
|
|
16
18
|
return value;
|
|
17
19
|
}
|
|
18
20
|
export function FrameSizeProvider({
|
|
21
|
+
initialFrame,
|
|
19
22
|
children
|
|
20
23
|
}) {
|
|
21
24
|
const context = React.useContext(FrameContext);
|
|
@@ -24,20 +27,17 @@ export function FrameSizeProvider({
|
|
|
24
27
|
return children;
|
|
25
28
|
}
|
|
26
29
|
return /*#__PURE__*/_jsx(FrameSizeProviderInner, {
|
|
30
|
+
initialFrame: initialFrame,
|
|
27
31
|
children: children
|
|
28
32
|
});
|
|
29
33
|
}
|
|
30
34
|
function FrameSizeProviderInner({
|
|
35
|
+
initialFrame,
|
|
31
36
|
children
|
|
32
37
|
}) {
|
|
38
|
+
const frameRef = React.useRef(initialFrame);
|
|
33
39
|
const listeners = React.useRef(new Set());
|
|
34
|
-
const
|
|
35
|
-
element,
|
|
36
|
-
get
|
|
37
|
-
} = useResizeListener(size => {
|
|
38
|
-
listeners.current.forEach(listener => listener(size));
|
|
39
|
-
});
|
|
40
|
-
const getCurrent = useLatestCallback(get);
|
|
40
|
+
const getCurrent = useLatestCallback(() => frameRef.current);
|
|
41
41
|
const subscribe = useLatestCallback(listener => {
|
|
42
42
|
listeners.current.add(listener);
|
|
43
43
|
return () => {
|
|
@@ -46,65 +46,67 @@ function FrameSizeProviderInner({
|
|
|
46
46
|
});
|
|
47
47
|
const subscribeDebounced = useLatestCallback(listener => {
|
|
48
48
|
let timer;
|
|
49
|
-
const debouncedListener =
|
|
49
|
+
const debouncedListener = frame => {
|
|
50
50
|
clearTimeout(timer);
|
|
51
51
|
timer = setTimeout(() => {
|
|
52
|
-
listener(
|
|
52
|
+
listener(frame);
|
|
53
53
|
}, 100);
|
|
54
54
|
};
|
|
55
|
-
|
|
56
|
-
return () => {
|
|
57
|
-
clearTimeout(timer);
|
|
58
|
-
listeners.current.delete(debouncedListener);
|
|
59
|
-
};
|
|
55
|
+
return subscribe(debouncedListener);
|
|
60
56
|
});
|
|
61
57
|
const context = React.useMemo(() => ({
|
|
62
58
|
getCurrent,
|
|
63
59
|
subscribe,
|
|
64
60
|
subscribeDebounced
|
|
65
61
|
}), [subscribe, subscribeDebounced, getCurrent]);
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
62
|
+
const onChange = useLatestCallback(frame => {
|
|
63
|
+
if (frameRef.current.height === frame.height && frameRef.current.width === frame.width) {
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
listeners.current.forEach(listener => listener(frame));
|
|
67
|
+
frameRef.current = frame;
|
|
68
|
+
});
|
|
69
|
+
return /*#__PURE__*/_jsxs(_Fragment, {
|
|
70
|
+
children: [Platform.OS === 'web' ? /*#__PURE__*/_jsx(FrameSizeListenerWeb, {
|
|
71
|
+
onChange: onChange
|
|
72
|
+
}) : typeof SafeAreaListener === 'undefined' ? /*#__PURE__*/_jsx(FrameSizeListenerNativeFallback, {
|
|
73
|
+
onChange: onChange
|
|
74
|
+
}) : /*#__PURE__*/_jsx(SafeAreaListener, {
|
|
75
|
+
onChange: ({
|
|
76
|
+
frame
|
|
77
|
+
}) => onChange(frame),
|
|
78
|
+
style: StyleSheet.absoluteFill
|
|
79
|
+
}), /*#__PURE__*/_jsx(FrameContext.Provider, {
|
|
80
|
+
value: context,
|
|
81
|
+
children: children
|
|
82
|
+
})]
|
|
69
83
|
});
|
|
70
84
|
}
|
|
71
|
-
|
|
72
|
-
|
|
85
|
+
|
|
86
|
+
// SafeAreaListener is available only on newer versions
|
|
87
|
+
// Fallback to an effect-based shim for older versions
|
|
88
|
+
function FrameSizeListenerNativeFallback({
|
|
89
|
+
onChange
|
|
90
|
+
}) {
|
|
73
91
|
const frame = useSafeAreaFrame();
|
|
74
92
|
React.useLayoutEffect(() => {
|
|
75
93
|
onChange(frame);
|
|
76
94
|
}, [frame, onChange]);
|
|
77
|
-
return
|
|
78
|
-
element: null,
|
|
79
|
-
get: () => frame
|
|
80
|
-
};
|
|
95
|
+
return null;
|
|
81
96
|
}
|
|
82
|
-
const {
|
|
83
|
-
width = 0,
|
|
84
|
-
height = 0
|
|
85
|
-
} = Dimensions.get('window');
|
|
86
97
|
|
|
87
98
|
// FIXME: On the Web, the safe area frame value doesn't update on resize
|
|
88
99
|
// So we workaround this by measuring the frame on resize
|
|
89
|
-
function
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
height
|
|
93
|
-
});
|
|
100
|
+
function FrameSizeListenerWeb({
|
|
101
|
+
onChange
|
|
102
|
+
}) {
|
|
94
103
|
const elementRef = React.useRef(null);
|
|
95
104
|
React.useEffect(() => {
|
|
96
105
|
if (elementRef.current == null) {
|
|
97
106
|
return;
|
|
98
107
|
}
|
|
99
|
-
const update = size => {
|
|
100
|
-
if (frameRef.current.width === size.width && frameRef.current.height === size.height) {
|
|
101
|
-
return;
|
|
102
|
-
}
|
|
103
|
-
frameRef.current = size;
|
|
104
|
-
onChange(size);
|
|
105
|
-
};
|
|
106
108
|
const rect = elementRef.current.getBoundingClientRect();
|
|
107
|
-
|
|
109
|
+
onChange({
|
|
108
110
|
width: rect.width,
|
|
109
111
|
height: rect.height
|
|
110
112
|
});
|
|
@@ -115,7 +117,7 @@ function useResizeListenerWeb(onChange) {
|
|
|
115
117
|
width,
|
|
116
118
|
height
|
|
117
119
|
} = entry.contentRect;
|
|
118
|
-
|
|
120
|
+
onChange({
|
|
119
121
|
width,
|
|
120
122
|
height
|
|
121
123
|
});
|
|
@@ -126,7 +128,7 @@ function useResizeListenerWeb(onChange) {
|
|
|
126
128
|
observer.disconnect();
|
|
127
129
|
};
|
|
128
130
|
}, [onChange]);
|
|
129
|
-
|
|
131
|
+
return /*#__PURE__*/_jsx("div", {
|
|
130
132
|
ref: elementRef,
|
|
131
133
|
style: {
|
|
132
134
|
...StyleSheet.absoluteFillObject,
|
|
@@ -134,9 +136,5 @@ function useResizeListenerWeb(onChange) {
|
|
|
134
136
|
visibility: 'hidden'
|
|
135
137
|
}
|
|
136
138
|
});
|
|
137
|
-
return {
|
|
138
|
-
element,
|
|
139
|
-
get: () => frameRef.current
|
|
140
|
-
};
|
|
141
139
|
}
|
|
142
140
|
//# sourceMappingURL=useFrameSize.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["React","
|
|
1
|
+
{"version":3,"names":["React","Platform","StyleSheet","SafeAreaListener","useSafeAreaFrame","useLatestCallback","useSyncExternalStoreWithSelector","jsx","_jsx","Fragment","_Fragment","jsxs","_jsxs","FrameContext","createContext","undefined","useFrameSize","selector","debounce","context","useContext","Error","value","subscribeDebounced","subscribe","getCurrent","FrameSizeProvider","initialFrame","children","FrameSizeProviderInner","frameRef","useRef","listeners","Set","current","listener","add","delete","timer","debouncedListener","frame","clearTimeout","setTimeout","useMemo","onChange","height","width","forEach","OS","FrameSizeListenerWeb","FrameSizeListenerNativeFallback","style","absoluteFill","Provider","useLayoutEffect","elementRef","useEffect","rect","getBoundingClientRect","observer","ResizeObserver","entries","entry","contentRect","observe","disconnect","ref","absoluteFillObject","pointerEvents","visibility"],"sourceRoot":"../../src","sources":["useFrameSize.tsx"],"mappings":"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","ignoreList":[]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SafeAreaProviderCompat.d.ts","sourceRoot":"","sources":["../../../src/SafeAreaProviderCompat.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,EAGL,KAAK,SAAS,EAGd,KAAK,SAAS,EACf,MAAM,cAAc,CAAC;AAStB,KAAK,KAAK,GAAG;IACX,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,KAAK,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;CAC9B,CAAC;AAeF,wBAAgB,sBAAsB,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,EAAE,KAAK,
|
|
1
|
+
{"version":3,"file":"SafeAreaProviderCompat.d.ts","sourceRoot":"","sources":["../../../src/SafeAreaProviderCompat.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,EAGL,KAAK,SAAS,EAGd,KAAK,SAAS,EACf,MAAM,cAAc,CAAC;AAStB,KAAK,KAAK,GAAG;IACX,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,KAAK,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;CAC9B,CAAC;AAeF,wBAAgB,sBAAsB,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,EAAE,KAAK,2CAqBhE;yBArBe,sBAAsB"}
|
|
@@ -1,11 +1,15 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
|
-
type
|
|
2
|
+
import { type StyleProp, type ViewStyle } from 'react-native';
|
|
3
|
+
type Frame = {
|
|
3
4
|
width: number;
|
|
4
5
|
height: number;
|
|
5
6
|
};
|
|
6
|
-
export declare function useFrameSize<T>(selector: (
|
|
7
|
-
|
|
7
|
+
export declare function useFrameSize<T>(selector: (frame: Frame) => T, debounce?: boolean): T;
|
|
8
|
+
type FrameSizeProviderProps = {
|
|
9
|
+
initialFrame: Frame;
|
|
8
10
|
children: React.ReactNode;
|
|
9
|
-
|
|
11
|
+
style?: StyleProp<ViewStyle>;
|
|
12
|
+
};
|
|
13
|
+
export declare function FrameSizeProvider({ initialFrame, children, }: FrameSizeProviderProps): string | number | bigint | boolean | Iterable<React.ReactNode> | Promise<string | number | bigint | boolean | React.ReactPortal | React.ReactElement<unknown, string | React.JSXElementConstructor<any>> | Iterable<React.ReactNode> | null | undefined> | import("react/jsx-runtime").JSX.Element | null | undefined;
|
|
10
14
|
export {};
|
|
11
15
|
//# sourceMappingURL=useFrameSize.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useFrameSize.d.ts","sourceRoot":"","sources":["../../../src/useFrameSize.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"useFrameSize.d.ts","sourceRoot":"","sources":["../../../src/useFrameSize.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,EAEL,KAAK,SAAS,EAEd,KAAK,SAAS,EACf,MAAM,cAAc,CAAC;AAStB,KAAK,KAAK,GAAG;IACX,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAgBF,wBAAgB,YAAY,CAAC,CAAC,EAC5B,QAAQ,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,CAAC,EAC7B,QAAQ,CAAC,EAAE,OAAO,GACjB,CAAC,CAeH;AAED,KAAK,sBAAsB,GAAG;IAC5B,YAAY,EAAE,KAAK,CAAC;IACpB,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,KAAK,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;CAC9B,CAAC;AAEF,wBAAgB,iBAAiB,CAAC,EAChC,YAAY,EACZ,QAAQ,GACT,EAAE,sBAAsB,yTAaxB"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@react-navigation/elements",
|
|
3
3
|
"description": "UI Components for React Navigation",
|
|
4
|
-
"version": "2.
|
|
4
|
+
"version": "2.5.0",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"react-native",
|
|
7
7
|
"react-navigation",
|
|
@@ -43,14 +43,16 @@
|
|
|
43
43
|
},
|
|
44
44
|
"dependencies": {
|
|
45
45
|
"color": "^4.2.3",
|
|
46
|
-
"use-latest-callback": "^0.2.4"
|
|
46
|
+
"use-latest-callback": "^0.2.4",
|
|
47
|
+
"use-sync-external-store": "^1.5.0"
|
|
47
48
|
},
|
|
48
49
|
"devDependencies": {
|
|
49
50
|
"@jest/globals": "^30.0.0",
|
|
50
51
|
"@react-native-masked-view/masked-view": "0.3.2",
|
|
51
|
-
"@react-navigation/native": "^7.1.
|
|
52
|
+
"@react-navigation/native": "^7.1.14",
|
|
52
53
|
"@testing-library/react-native": "^13.2.0",
|
|
53
54
|
"@types/react": "~19.0.10",
|
|
55
|
+
"@types/use-sync-external-store": "^1.5.0",
|
|
54
56
|
"del-cli": "^6.0.0",
|
|
55
57
|
"react": "19.0.0",
|
|
56
58
|
"react-native": "0.79.3",
|
|
@@ -60,7 +62,7 @@
|
|
|
60
62
|
},
|
|
61
63
|
"peerDependencies": {
|
|
62
64
|
"@react-native-masked-view/masked-view": ">= 0.2.0",
|
|
63
|
-
"@react-navigation/native": "^7.1.
|
|
65
|
+
"@react-navigation/native": "^7.1.14",
|
|
64
66
|
"react": ">= 18.2.0",
|
|
65
67
|
"react-native": "*",
|
|
66
68
|
"react-native-safe-area-context": ">= 4.0.0"
|
|
@@ -88,5 +90,5 @@
|
|
|
88
90
|
]
|
|
89
91
|
]
|
|
90
92
|
},
|
|
91
|
-
"gitHead": "
|
|
93
|
+
"gitHead": "c059915c187967137f33b8931e6badcb0c604492"
|
|
92
94
|
}
|
|
@@ -36,7 +36,11 @@ const initialMetrics =
|
|
|
36
36
|
export function SafeAreaProviderCompat({ children, style }: Props) {
|
|
37
37
|
const insets = React.useContext(SafeAreaInsetsContext);
|
|
38
38
|
|
|
39
|
-
children =
|
|
39
|
+
children = (
|
|
40
|
+
<FrameSizeProvider initialFrame={initialMetrics.frame}>
|
|
41
|
+
{children}
|
|
42
|
+
</FrameSizeProvider>
|
|
43
|
+
);
|
|
40
44
|
|
|
41
45
|
if (insets) {
|
|
42
46
|
// If we already have insets, don't wrap the stack in another safe area provider
|
package/src/useFrameSize.tsx
CHANGED
|
@@ -1,21 +1,30 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
2
|
+
import {
|
|
3
|
+
Platform,
|
|
4
|
+
type StyleProp,
|
|
5
|
+
StyleSheet,
|
|
6
|
+
type ViewStyle,
|
|
7
|
+
} from 'react-native';
|
|
8
|
+
import {
|
|
9
|
+
SafeAreaListener,
|
|
10
|
+
// eslint-disable-next-line no-restricted-imports
|
|
11
|
+
useSafeAreaFrame,
|
|
12
|
+
} from 'react-native-safe-area-context';
|
|
5
13
|
import useLatestCallback from 'use-latest-callback';
|
|
14
|
+
import { useSyncExternalStoreWithSelector } from 'use-sync-external-store/with-selector';
|
|
6
15
|
|
|
7
|
-
type
|
|
16
|
+
type Frame = {
|
|
8
17
|
width: number;
|
|
9
18
|
height: number;
|
|
10
19
|
};
|
|
11
20
|
|
|
12
|
-
type Listener = (
|
|
21
|
+
type Listener = (frame: Frame) => void;
|
|
13
22
|
|
|
14
23
|
type RemoveListener = () => void;
|
|
15
24
|
|
|
16
25
|
type FrameContextType = {
|
|
17
|
-
getCurrent: () =>
|
|
18
|
-
subscribe: (listener: Listener
|
|
26
|
+
getCurrent: () => Frame;
|
|
27
|
+
subscribe: (listener: Listener) => RemoveListener;
|
|
19
28
|
subscribeDebounced: (listener: Listener) => RemoveListener;
|
|
20
29
|
};
|
|
21
30
|
|
|
@@ -24,7 +33,7 @@ const FrameContext = React.createContext<FrameContextType | undefined>(
|
|
|
24
33
|
);
|
|
25
34
|
|
|
26
35
|
export function useFrameSize<T>(
|
|
27
|
-
selector: (
|
|
36
|
+
selector: (frame: Frame) => T,
|
|
28
37
|
debounce?: boolean
|
|
29
38
|
): T {
|
|
30
39
|
const context = React.useContext(FrameContext);
|
|
@@ -33,16 +42,26 @@ export function useFrameSize<T>(
|
|
|
33
42
|
throw new Error('useFrameSize must be used within a FrameSizeProvider');
|
|
34
43
|
}
|
|
35
44
|
|
|
36
|
-
const value =
|
|
45
|
+
const value = useSyncExternalStoreWithSelector(
|
|
37
46
|
debounce ? context.subscribeDebounced : context.subscribe,
|
|
38
|
-
|
|
39
|
-
|
|
47
|
+
context.getCurrent,
|
|
48
|
+
context.getCurrent,
|
|
49
|
+
selector
|
|
40
50
|
);
|
|
41
51
|
|
|
42
52
|
return value;
|
|
43
53
|
}
|
|
44
54
|
|
|
45
|
-
|
|
55
|
+
type FrameSizeProviderProps = {
|
|
56
|
+
initialFrame: Frame;
|
|
57
|
+
children: React.ReactNode;
|
|
58
|
+
style?: StyleProp<ViewStyle>;
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
export function FrameSizeProvider({
|
|
62
|
+
initialFrame,
|
|
63
|
+
children,
|
|
64
|
+
}: FrameSizeProviderProps) {
|
|
46
65
|
const context = React.useContext(FrameContext);
|
|
47
66
|
|
|
48
67
|
if (context != null) {
|
|
@@ -50,21 +69,21 @@ export function FrameSizeProvider({ children }: { children: React.ReactNode }) {
|
|
|
50
69
|
return children;
|
|
51
70
|
}
|
|
52
71
|
|
|
53
|
-
return
|
|
72
|
+
return (
|
|
73
|
+
<FrameSizeProviderInner initialFrame={initialFrame}>
|
|
74
|
+
{children}
|
|
75
|
+
</FrameSizeProviderInner>
|
|
76
|
+
);
|
|
54
77
|
}
|
|
55
78
|
|
|
56
79
|
function FrameSizeProviderInner({
|
|
80
|
+
initialFrame,
|
|
57
81
|
children,
|
|
58
|
-
}: {
|
|
59
|
-
|
|
60
|
-
}): React.JSX.Element {
|
|
82
|
+
}: FrameSizeProviderProps) {
|
|
83
|
+
const frameRef = React.useRef<Frame>(initialFrame);
|
|
61
84
|
const listeners = React.useRef<Set<Listener>>(new Set());
|
|
62
85
|
|
|
63
|
-
const
|
|
64
|
-
listeners.current.forEach((listener) => listener(size));
|
|
65
|
-
});
|
|
66
|
-
|
|
67
|
-
const getCurrent = useLatestCallback(get);
|
|
86
|
+
const getCurrent = useLatestCallback(() => frameRef.current);
|
|
68
87
|
|
|
69
88
|
const subscribe = useLatestCallback((listener: Listener): RemoveListener => {
|
|
70
89
|
listeners.current.add(listener);
|
|
@@ -78,19 +97,14 @@ function FrameSizeProviderInner({
|
|
|
78
97
|
(listener: Listener): RemoveListener => {
|
|
79
98
|
let timer: ReturnType<typeof setTimeout>;
|
|
80
99
|
|
|
81
|
-
const debouncedListener = (
|
|
100
|
+
const debouncedListener = (frame: Frame) => {
|
|
82
101
|
clearTimeout(timer);
|
|
83
102
|
timer = setTimeout(() => {
|
|
84
|
-
listener(
|
|
103
|
+
listener(frame);
|
|
85
104
|
}, 100);
|
|
86
105
|
};
|
|
87
106
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
return () => {
|
|
91
|
-
clearTimeout(timer);
|
|
92
|
-
listeners.current.delete(debouncedListener);
|
|
93
|
-
};
|
|
107
|
+
return subscribe(debouncedListener);
|
|
94
108
|
}
|
|
95
109
|
);
|
|
96
110
|
|
|
@@ -103,40 +117,58 @@ function FrameSizeProviderInner({
|
|
|
103
117
|
[subscribe, subscribeDebounced, getCurrent]
|
|
104
118
|
);
|
|
105
119
|
|
|
120
|
+
const onChange = useLatestCallback((frame: Frame) => {
|
|
121
|
+
if (
|
|
122
|
+
frameRef.current.height === frame.height &&
|
|
123
|
+
frameRef.current.width === frame.width
|
|
124
|
+
) {
|
|
125
|
+
return;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
listeners.current.forEach((listener) => listener(frame));
|
|
129
|
+
frameRef.current = frame;
|
|
130
|
+
});
|
|
131
|
+
|
|
106
132
|
return (
|
|
107
|
-
|
|
108
|
-
{
|
|
109
|
-
|
|
110
|
-
|
|
133
|
+
<>
|
|
134
|
+
{Platform.OS === 'web' ? (
|
|
135
|
+
<FrameSizeListenerWeb onChange={onChange} />
|
|
136
|
+
) : typeof SafeAreaListener === 'undefined' ? (
|
|
137
|
+
<FrameSizeListenerNativeFallback onChange={onChange} />
|
|
138
|
+
) : (
|
|
139
|
+
<SafeAreaListener
|
|
140
|
+
onChange={({ frame }) => onChange(frame)}
|
|
141
|
+
style={StyleSheet.absoluteFill}
|
|
142
|
+
/>
|
|
143
|
+
)}
|
|
144
|
+
<FrameContext.Provider value={context}>{children}</FrameContext.Provider>
|
|
145
|
+
</>
|
|
111
146
|
);
|
|
112
147
|
}
|
|
113
148
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
149
|
+
// SafeAreaListener is available only on newer versions
|
|
150
|
+
// Fallback to an effect-based shim for older versions
|
|
151
|
+
function FrameSizeListenerNativeFallback({
|
|
152
|
+
onChange,
|
|
153
|
+
}: {
|
|
154
|
+
onChange: (frame: Frame) => void;
|
|
155
|
+
}) {
|
|
118
156
|
const frame = useSafeAreaFrame();
|
|
119
157
|
|
|
120
158
|
React.useLayoutEffect(() => {
|
|
121
159
|
onChange(frame);
|
|
122
160
|
}, [frame, onChange]);
|
|
123
161
|
|
|
124
|
-
return
|
|
125
|
-
element: null,
|
|
126
|
-
get: () => frame,
|
|
127
|
-
};
|
|
162
|
+
return null;
|
|
128
163
|
}
|
|
129
164
|
|
|
130
|
-
const { width = 0, height = 0 } = Dimensions.get('window');
|
|
131
|
-
|
|
132
165
|
// FIXME: On the Web, the safe area frame value doesn't update on resize
|
|
133
166
|
// So we workaround this by measuring the frame on resize
|
|
134
|
-
function
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
167
|
+
function FrameSizeListenerWeb({
|
|
168
|
+
onChange,
|
|
169
|
+
}: {
|
|
170
|
+
onChange: (frame: Frame) => void;
|
|
171
|
+
}) {
|
|
140
172
|
const elementRef = React.useRef<HTMLDivElement>(null);
|
|
141
173
|
|
|
142
174
|
React.useEffect(() => {
|
|
@@ -144,21 +176,9 @@ function useResizeListenerWeb(onChange: (size: Size) => void) {
|
|
|
144
176
|
return;
|
|
145
177
|
}
|
|
146
178
|
|
|
147
|
-
const update = (size: Size) => {
|
|
148
|
-
if (
|
|
149
|
-
frameRef.current.width === size.width &&
|
|
150
|
-
frameRef.current.height === size.height
|
|
151
|
-
) {
|
|
152
|
-
return;
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
frameRef.current = size;
|
|
156
|
-
onChange(size);
|
|
157
|
-
};
|
|
158
|
-
|
|
159
179
|
const rect = elementRef.current.getBoundingClientRect();
|
|
160
180
|
|
|
161
|
-
|
|
181
|
+
onChange({
|
|
162
182
|
width: rect.width,
|
|
163
183
|
height: rect.height,
|
|
164
184
|
});
|
|
@@ -169,7 +189,7 @@ function useResizeListenerWeb(onChange: (size: Size) => void) {
|
|
|
169
189
|
if (entry) {
|
|
170
190
|
const { width, height } = entry.contentRect;
|
|
171
191
|
|
|
172
|
-
|
|
192
|
+
onChange({ width, height });
|
|
173
193
|
}
|
|
174
194
|
});
|
|
175
195
|
|
|
@@ -180,7 +200,7 @@ function useResizeListenerWeb(onChange: (size: Size) => void) {
|
|
|
180
200
|
};
|
|
181
201
|
}, [onChange]);
|
|
182
202
|
|
|
183
|
-
|
|
203
|
+
return (
|
|
184
204
|
<div
|
|
185
205
|
ref={elementRef}
|
|
186
206
|
style={{
|
|
@@ -190,9 +210,4 @@ function useResizeListenerWeb(onChange: (size: Size) => void) {
|
|
|
190
210
|
}}
|
|
191
211
|
/>
|
|
192
212
|
);
|
|
193
|
-
|
|
194
|
-
return {
|
|
195
|
-
element,
|
|
196
|
-
get: () => frameRef.current,
|
|
197
|
-
};
|
|
198
213
|
}
|