@react-navigation/elements 2.4.6 → 2.5.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/lib/module/SafeAreaProviderCompat.js +1 -0
- package/lib/module/SafeAreaProviderCompat.js.map +1 -1
- package/lib/module/useFrameSize.js +80 -53
- 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 +4 -4
- package/src/SafeAreaProviderCompat.tsx +5 -1
- package/src/useFrameSize.tsx +114 -70
|
@@ -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,22 +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
9
|
import { useSyncExternalStoreWithSelector } from 'use-sync-external-store/with-selector';
|
|
9
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
10
|
+
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
10
11
|
const FrameContext = /*#__PURE__*/React.createContext(undefined);
|
|
11
|
-
export function useFrameSize(selector,
|
|
12
|
+
export function useFrameSize(selector, throttle) {
|
|
12
13
|
const context = React.useContext(FrameContext);
|
|
13
14
|
if (context == null) {
|
|
14
15
|
throw new Error('useFrameSize must be used within a FrameSizeProvider');
|
|
15
16
|
}
|
|
16
|
-
const value = useSyncExternalStoreWithSelector(
|
|
17
|
+
const value = useSyncExternalStoreWithSelector(throttle ? context.subscribeThrottled : context.subscribe, context.getCurrent, context.getCurrent, selector);
|
|
17
18
|
return value;
|
|
18
19
|
}
|
|
19
20
|
export function FrameSizeProvider({
|
|
21
|
+
initialFrame,
|
|
20
22
|
children
|
|
21
23
|
}) {
|
|
22
24
|
const context = React.useContext(FrameContext);
|
|
@@ -25,87 +27,116 @@ export function FrameSizeProvider({
|
|
|
25
27
|
return children;
|
|
26
28
|
}
|
|
27
29
|
return /*#__PURE__*/_jsx(FrameSizeProviderInner, {
|
|
30
|
+
initialFrame: initialFrame,
|
|
28
31
|
children: children
|
|
29
32
|
});
|
|
30
33
|
}
|
|
31
34
|
function FrameSizeProviderInner({
|
|
35
|
+
initialFrame,
|
|
32
36
|
children
|
|
33
37
|
}) {
|
|
34
|
-
const
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
get
|
|
38
|
-
} = useResizeListener(size => {
|
|
39
|
-
listeners.current.forEach(listener => listener(size));
|
|
38
|
+
const frameRef = React.useRef({
|
|
39
|
+
width: initialFrame.width,
|
|
40
|
+
height: initialFrame.height
|
|
40
41
|
});
|
|
41
|
-
const
|
|
42
|
+
const listeners = React.useRef(new Set());
|
|
43
|
+
const getCurrent = useLatestCallback(() => frameRef.current);
|
|
42
44
|
const subscribe = useLatestCallback(listener => {
|
|
43
45
|
listeners.current.add(listener);
|
|
44
46
|
return () => {
|
|
45
47
|
listeners.current.delete(listener);
|
|
46
48
|
};
|
|
47
49
|
});
|
|
48
|
-
const
|
|
50
|
+
const subscribeThrottled = useLatestCallback(listener => {
|
|
51
|
+
const delay = 100; // Throttle delay in milliseconds
|
|
52
|
+
|
|
49
53
|
let timer;
|
|
50
|
-
|
|
54
|
+
let updated = false;
|
|
55
|
+
let waiting = false;
|
|
56
|
+
const throttledListener = () => {
|
|
51
57
|
clearTimeout(timer);
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
58
|
+
updated = true;
|
|
59
|
+
if (waiting) {
|
|
60
|
+
// Schedule a timer to call the listener at the end
|
|
61
|
+
timer = setTimeout(() => {
|
|
62
|
+
if (updated) {
|
|
63
|
+
updated = false;
|
|
64
|
+
listener();
|
|
65
|
+
}
|
|
66
|
+
}, delay);
|
|
67
|
+
} else {
|
|
68
|
+
waiting = true;
|
|
69
|
+
setTimeout(function () {
|
|
70
|
+
waiting = false;
|
|
71
|
+
}, delay);
|
|
72
|
+
|
|
73
|
+
// Call the listener immediately at start
|
|
74
|
+
updated = false;
|
|
75
|
+
listener();
|
|
76
|
+
}
|
|
55
77
|
};
|
|
56
|
-
|
|
78
|
+
const unsubscribe = subscribe(throttledListener);
|
|
57
79
|
return () => {
|
|
80
|
+
unsubscribe();
|
|
58
81
|
clearTimeout(timer);
|
|
59
|
-
listeners.current.delete(debouncedListener);
|
|
60
82
|
};
|
|
61
83
|
});
|
|
62
84
|
const context = React.useMemo(() => ({
|
|
63
85
|
getCurrent,
|
|
64
86
|
subscribe,
|
|
65
|
-
|
|
66
|
-
}), [subscribe,
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
87
|
+
subscribeThrottled
|
|
88
|
+
}), [subscribe, subscribeThrottled, getCurrent]);
|
|
89
|
+
const onChange = useLatestCallback(frame => {
|
|
90
|
+
if (frameRef.current.height === frame.height && frameRef.current.width === frame.width) {
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
frameRef.current = {
|
|
94
|
+
width: frame.width,
|
|
95
|
+
height: frame.height
|
|
96
|
+
};
|
|
97
|
+
listeners.current.forEach(listener => listener());
|
|
98
|
+
});
|
|
99
|
+
return /*#__PURE__*/_jsxs(_Fragment, {
|
|
100
|
+
children: [Platform.OS === 'web' ? /*#__PURE__*/_jsx(FrameSizeListenerWeb, {
|
|
101
|
+
onChange: onChange
|
|
102
|
+
}) : typeof SafeAreaListener === 'undefined' ? /*#__PURE__*/_jsx(FrameSizeListenerNativeFallback, {
|
|
103
|
+
onChange: onChange
|
|
104
|
+
}) : /*#__PURE__*/_jsx(SafeAreaListener, {
|
|
105
|
+
onChange: ({
|
|
106
|
+
frame
|
|
107
|
+
}) => onChange(frame),
|
|
108
|
+
style: StyleSheet.absoluteFill
|
|
109
|
+
}), /*#__PURE__*/_jsx(FrameContext.Provider, {
|
|
110
|
+
value: context,
|
|
111
|
+
children: children
|
|
112
|
+
})]
|
|
70
113
|
});
|
|
71
114
|
}
|
|
72
|
-
|
|
73
|
-
|
|
115
|
+
|
|
116
|
+
// SafeAreaListener is available only on newer versions
|
|
117
|
+
// Fallback to an effect-based shim for older versions
|
|
118
|
+
function FrameSizeListenerNativeFallback({
|
|
119
|
+
onChange
|
|
120
|
+
}) {
|
|
74
121
|
const frame = useSafeAreaFrame();
|
|
75
122
|
React.useLayoutEffect(() => {
|
|
76
123
|
onChange(frame);
|
|
77
124
|
}, [frame, onChange]);
|
|
78
|
-
return
|
|
79
|
-
element: null,
|
|
80
|
-
get: () => frame
|
|
81
|
-
};
|
|
125
|
+
return null;
|
|
82
126
|
}
|
|
83
|
-
const {
|
|
84
|
-
width = 0,
|
|
85
|
-
height = 0
|
|
86
|
-
} = Dimensions.get('window');
|
|
87
127
|
|
|
88
128
|
// FIXME: On the Web, the safe area frame value doesn't update on resize
|
|
89
129
|
// So we workaround this by measuring the frame on resize
|
|
90
|
-
function
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
height
|
|
94
|
-
});
|
|
130
|
+
function FrameSizeListenerWeb({
|
|
131
|
+
onChange
|
|
132
|
+
}) {
|
|
95
133
|
const elementRef = React.useRef(null);
|
|
96
134
|
React.useEffect(() => {
|
|
97
135
|
if (elementRef.current == null) {
|
|
98
136
|
return;
|
|
99
137
|
}
|
|
100
|
-
const update = size => {
|
|
101
|
-
if (frameRef.current.width === size.width && frameRef.current.height === size.height) {
|
|
102
|
-
return;
|
|
103
|
-
}
|
|
104
|
-
frameRef.current = size;
|
|
105
|
-
onChange(size);
|
|
106
|
-
};
|
|
107
138
|
const rect = elementRef.current.getBoundingClientRect();
|
|
108
|
-
|
|
139
|
+
onChange({
|
|
109
140
|
width: rect.width,
|
|
110
141
|
height: rect.height
|
|
111
142
|
});
|
|
@@ -116,7 +147,7 @@ function useResizeListenerWeb(onChange) {
|
|
|
116
147
|
width,
|
|
117
148
|
height
|
|
118
149
|
} = entry.contentRect;
|
|
119
|
-
|
|
150
|
+
onChange({
|
|
120
151
|
width,
|
|
121
152
|
height
|
|
122
153
|
});
|
|
@@ -127,7 +158,7 @@ function useResizeListenerWeb(onChange) {
|
|
|
127
158
|
observer.disconnect();
|
|
128
159
|
};
|
|
129
160
|
}, [onChange]);
|
|
130
|
-
|
|
161
|
+
return /*#__PURE__*/_jsx("div", {
|
|
131
162
|
ref: elementRef,
|
|
132
163
|
style: {
|
|
133
164
|
...StyleSheet.absoluteFillObject,
|
|
@@ -135,9 +166,5 @@ function useResizeListenerWeb(onChange) {
|
|
|
135
166
|
visibility: 'hidden'
|
|
136
167
|
}
|
|
137
168
|
});
|
|
138
|
-
return {
|
|
139
|
-
element,
|
|
140
|
-
get: () => frameRef.current
|
|
141
|
-
};
|
|
142
169
|
}
|
|
143
170
|
//# 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","throttle","context","useContext","Error","value","subscribeThrottled","subscribe","getCurrent","FrameSizeProvider","initialFrame","children","FrameSizeProviderInner","frameRef","useRef","width","height","listeners","Set","current","listener","add","delete","delay","timer","updated","waiting","throttledListener","clearTimeout","setTimeout","unsubscribe","useMemo","onChange","frame","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, throttle?: 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.1",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"react-native",
|
|
7
7
|
"react-navigation",
|
|
@@ -49,7 +49,7 @@
|
|
|
49
49
|
"devDependencies": {
|
|
50
50
|
"@jest/globals": "^30.0.0",
|
|
51
51
|
"@react-native-masked-view/masked-view": "0.3.2",
|
|
52
|
-
"@react-navigation/native": "^7.1.
|
|
52
|
+
"@react-navigation/native": "^7.1.14",
|
|
53
53
|
"@testing-library/react-native": "^13.2.0",
|
|
54
54
|
"@types/react": "~19.0.10",
|
|
55
55
|
"@types/use-sync-external-store": "^1.5.0",
|
|
@@ -62,7 +62,7 @@
|
|
|
62
62
|
},
|
|
63
63
|
"peerDependencies": {
|
|
64
64
|
"@react-native-masked-view/masked-view": ">= 0.2.0",
|
|
65
|
-
"@react-navigation/native": "^7.1.
|
|
65
|
+
"@react-navigation/native": "^7.1.14",
|
|
66
66
|
"react": ">= 18.2.0",
|
|
67
67
|
"react-native": "*",
|
|
68
68
|
"react-native-safe-area-context": ">= 4.0.0"
|
|
@@ -90,5 +90,5 @@
|
|
|
90
90
|
]
|
|
91
91
|
]
|
|
92
92
|
},
|
|
93
|
-
"gitHead": "
|
|
93
|
+
"gitHead": "0508fba46d6ea4823de28f35e981d5cc8f15e93a"
|
|
94
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,23 +1,31 @@
|
|
|
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';
|
|
6
14
|
import { useSyncExternalStoreWithSelector } from 'use-sync-external-store/with-selector';
|
|
7
15
|
|
|
8
|
-
type
|
|
16
|
+
type Frame = {
|
|
9
17
|
width: number;
|
|
10
18
|
height: number;
|
|
11
19
|
};
|
|
12
20
|
|
|
13
|
-
type Listener = (
|
|
21
|
+
type Listener = () => void;
|
|
14
22
|
|
|
15
23
|
type RemoveListener = () => void;
|
|
16
24
|
|
|
17
25
|
type FrameContextType = {
|
|
18
|
-
getCurrent: () =>
|
|
19
|
-
subscribe: (listener: Listener
|
|
20
|
-
|
|
26
|
+
getCurrent: () => Frame;
|
|
27
|
+
subscribe: (listener: Listener) => RemoveListener;
|
|
28
|
+
subscribeThrottled: (listener: Listener) => RemoveListener;
|
|
21
29
|
};
|
|
22
30
|
|
|
23
31
|
const FrameContext = React.createContext<FrameContextType | undefined>(
|
|
@@ -25,8 +33,8 @@ const FrameContext = React.createContext<FrameContextType | undefined>(
|
|
|
25
33
|
);
|
|
26
34
|
|
|
27
35
|
export function useFrameSize<T>(
|
|
28
|
-
selector: (
|
|
29
|
-
|
|
36
|
+
selector: (frame: Frame) => T,
|
|
37
|
+
throttle?: boolean
|
|
30
38
|
): T {
|
|
31
39
|
const context = React.useContext(FrameContext);
|
|
32
40
|
|
|
@@ -35,7 +43,7 @@ export function useFrameSize<T>(
|
|
|
35
43
|
}
|
|
36
44
|
|
|
37
45
|
const value = useSyncExternalStoreWithSelector(
|
|
38
|
-
|
|
46
|
+
throttle ? context.subscribeThrottled : context.subscribe,
|
|
39
47
|
context.getCurrent,
|
|
40
48
|
context.getCurrent,
|
|
41
49
|
selector
|
|
@@ -44,7 +52,16 @@ export function useFrameSize<T>(
|
|
|
44
52
|
return value;
|
|
45
53
|
}
|
|
46
54
|
|
|
47
|
-
|
|
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) {
|
|
48
65
|
const context = React.useContext(FrameContext);
|
|
49
66
|
|
|
50
67
|
if (context != null) {
|
|
@@ -52,21 +69,25 @@ export function FrameSizeProvider({ children }: { children: React.ReactNode }) {
|
|
|
52
69
|
return children;
|
|
53
70
|
}
|
|
54
71
|
|
|
55
|
-
return
|
|
72
|
+
return (
|
|
73
|
+
<FrameSizeProviderInner initialFrame={initialFrame}>
|
|
74
|
+
{children}
|
|
75
|
+
</FrameSizeProviderInner>
|
|
76
|
+
);
|
|
56
77
|
}
|
|
57
78
|
|
|
58
79
|
function FrameSizeProviderInner({
|
|
80
|
+
initialFrame,
|
|
59
81
|
children,
|
|
60
|
-
}: {
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
const { element, get } = useResizeListener((size) => {
|
|
66
|
-
listeners.current.forEach((listener) => listener(size));
|
|
82
|
+
}: FrameSizeProviderProps) {
|
|
83
|
+
const frameRef = React.useRef<Frame>({
|
|
84
|
+
width: initialFrame.width,
|
|
85
|
+
height: initialFrame.height,
|
|
67
86
|
});
|
|
68
87
|
|
|
69
|
-
const
|
|
88
|
+
const listeners = React.useRef<Set<Listener>>(new Set());
|
|
89
|
+
|
|
90
|
+
const getCurrent = useLatestCallback(() => frameRef.current);
|
|
70
91
|
|
|
71
92
|
const subscribe = useLatestCallback((listener: Listener): RemoveListener => {
|
|
72
93
|
listeners.current.add(listener);
|
|
@@ -76,22 +97,44 @@ function FrameSizeProviderInner({
|
|
|
76
97
|
};
|
|
77
98
|
});
|
|
78
99
|
|
|
79
|
-
const
|
|
100
|
+
const subscribeThrottled = useLatestCallback(
|
|
80
101
|
(listener: Listener): RemoveListener => {
|
|
102
|
+
const delay = 100; // Throttle delay in milliseconds
|
|
103
|
+
|
|
81
104
|
let timer: ReturnType<typeof setTimeout>;
|
|
105
|
+
let updated = false;
|
|
106
|
+
let waiting = false;
|
|
82
107
|
|
|
83
|
-
const
|
|
108
|
+
const throttledListener = () => {
|
|
84
109
|
clearTimeout(timer);
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
110
|
+
|
|
111
|
+
updated = true;
|
|
112
|
+
|
|
113
|
+
if (waiting) {
|
|
114
|
+
// Schedule a timer to call the listener at the end
|
|
115
|
+
timer = setTimeout(() => {
|
|
116
|
+
if (updated) {
|
|
117
|
+
updated = false;
|
|
118
|
+
listener();
|
|
119
|
+
}
|
|
120
|
+
}, delay);
|
|
121
|
+
} else {
|
|
122
|
+
waiting = true;
|
|
123
|
+
setTimeout(function () {
|
|
124
|
+
waiting = false;
|
|
125
|
+
}, delay);
|
|
126
|
+
|
|
127
|
+
// Call the listener immediately at start
|
|
128
|
+
updated = false;
|
|
129
|
+
listener();
|
|
130
|
+
}
|
|
88
131
|
};
|
|
89
132
|
|
|
90
|
-
|
|
133
|
+
const unsubscribe = subscribe(throttledListener);
|
|
91
134
|
|
|
92
135
|
return () => {
|
|
136
|
+
unsubscribe();
|
|
93
137
|
clearTimeout(timer);
|
|
94
|
-
listeners.current.delete(debouncedListener);
|
|
95
138
|
};
|
|
96
139
|
}
|
|
97
140
|
);
|
|
@@ -100,45 +143,63 @@ function FrameSizeProviderInner({
|
|
|
100
143
|
() => ({
|
|
101
144
|
getCurrent,
|
|
102
145
|
subscribe,
|
|
103
|
-
|
|
146
|
+
subscribeThrottled,
|
|
104
147
|
}),
|
|
105
|
-
[subscribe,
|
|
148
|
+
[subscribe, subscribeThrottled, getCurrent]
|
|
106
149
|
);
|
|
107
150
|
|
|
151
|
+
const onChange = useLatestCallback((frame: Frame) => {
|
|
152
|
+
if (
|
|
153
|
+
frameRef.current.height === frame.height &&
|
|
154
|
+
frameRef.current.width === frame.width
|
|
155
|
+
) {
|
|
156
|
+
return;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
frameRef.current = { width: frame.width, height: frame.height };
|
|
160
|
+
listeners.current.forEach((listener) => listener());
|
|
161
|
+
});
|
|
162
|
+
|
|
108
163
|
return (
|
|
109
|
-
|
|
110
|
-
{
|
|
111
|
-
|
|
112
|
-
|
|
164
|
+
<>
|
|
165
|
+
{Platform.OS === 'web' ? (
|
|
166
|
+
<FrameSizeListenerWeb onChange={onChange} />
|
|
167
|
+
) : typeof SafeAreaListener === 'undefined' ? (
|
|
168
|
+
<FrameSizeListenerNativeFallback onChange={onChange} />
|
|
169
|
+
) : (
|
|
170
|
+
<SafeAreaListener
|
|
171
|
+
onChange={({ frame }) => onChange(frame)}
|
|
172
|
+
style={StyleSheet.absoluteFill}
|
|
173
|
+
/>
|
|
174
|
+
)}
|
|
175
|
+
<FrameContext.Provider value={context}>{children}</FrameContext.Provider>
|
|
176
|
+
</>
|
|
113
177
|
);
|
|
114
178
|
}
|
|
115
179
|
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
180
|
+
// SafeAreaListener is available only on newer versions
|
|
181
|
+
// Fallback to an effect-based shim for older versions
|
|
182
|
+
function FrameSizeListenerNativeFallback({
|
|
183
|
+
onChange,
|
|
184
|
+
}: {
|
|
185
|
+
onChange: (frame: Frame) => void;
|
|
186
|
+
}) {
|
|
120
187
|
const frame = useSafeAreaFrame();
|
|
121
188
|
|
|
122
189
|
React.useLayoutEffect(() => {
|
|
123
190
|
onChange(frame);
|
|
124
191
|
}, [frame, onChange]);
|
|
125
192
|
|
|
126
|
-
return
|
|
127
|
-
element: null,
|
|
128
|
-
get: () => frame,
|
|
129
|
-
};
|
|
193
|
+
return null;
|
|
130
194
|
}
|
|
131
195
|
|
|
132
|
-
const { width = 0, height = 0 } = Dimensions.get('window');
|
|
133
|
-
|
|
134
196
|
// FIXME: On the Web, the safe area frame value doesn't update on resize
|
|
135
197
|
// So we workaround this by measuring the frame on resize
|
|
136
|
-
function
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
198
|
+
function FrameSizeListenerWeb({
|
|
199
|
+
onChange,
|
|
200
|
+
}: {
|
|
201
|
+
onChange: (frame: Frame) => void;
|
|
202
|
+
}) {
|
|
142
203
|
const elementRef = React.useRef<HTMLDivElement>(null);
|
|
143
204
|
|
|
144
205
|
React.useEffect(() => {
|
|
@@ -146,21 +207,9 @@ function useResizeListenerWeb(onChange: (size: Size) => void) {
|
|
|
146
207
|
return;
|
|
147
208
|
}
|
|
148
209
|
|
|
149
|
-
const update = (size: Size) => {
|
|
150
|
-
if (
|
|
151
|
-
frameRef.current.width === size.width &&
|
|
152
|
-
frameRef.current.height === size.height
|
|
153
|
-
) {
|
|
154
|
-
return;
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
frameRef.current = size;
|
|
158
|
-
onChange(size);
|
|
159
|
-
};
|
|
160
|
-
|
|
161
210
|
const rect = elementRef.current.getBoundingClientRect();
|
|
162
211
|
|
|
163
|
-
|
|
212
|
+
onChange({
|
|
164
213
|
width: rect.width,
|
|
165
214
|
height: rect.height,
|
|
166
215
|
});
|
|
@@ -171,7 +220,7 @@ function useResizeListenerWeb(onChange: (size: Size) => void) {
|
|
|
171
220
|
if (entry) {
|
|
172
221
|
const { width, height } = entry.contentRect;
|
|
173
222
|
|
|
174
|
-
|
|
223
|
+
onChange({ width, height });
|
|
175
224
|
}
|
|
176
225
|
});
|
|
177
226
|
|
|
@@ -182,7 +231,7 @@ function useResizeListenerWeb(onChange: (size: Size) => void) {
|
|
|
182
231
|
};
|
|
183
232
|
}, [onChange]);
|
|
184
233
|
|
|
185
|
-
|
|
234
|
+
return (
|
|
186
235
|
<div
|
|
187
236
|
ref={elementRef}
|
|
188
237
|
style={{
|
|
@@ -192,9 +241,4 @@ function useResizeListenerWeb(onChange: (size: Size) => void) {
|
|
|
192
241
|
}}
|
|
193
242
|
/>
|
|
194
243
|
);
|
|
195
|
-
|
|
196
|
-
return {
|
|
197
|
-
element,
|
|
198
|
-
get: () => frameRef.current,
|
|
199
|
-
};
|
|
200
244
|
}
|