react-native-reserved-regions 0.1.0-alpha.2 → 0.1.0-alpha.3
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/README.md +21 -3
- package/android/src/main/java/com/appandflow/reservedregions/ReservedRegionsView.kt +22 -8
- package/ios/ReservedRegionsView.mm +11 -0
- package/lib/module/index.js +7 -0
- package/lib/module/index.js.map +1 -1
- package/lib/typescript/src/index.d.ts +2 -0
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/package.json +2 -1
- package/src/index.tsx +5 -0
package/README.md
CHANGED
|
@@ -13,11 +13,10 @@ Its iOS target adopts `UISceneDelegate` because the RC template currently crashe
|
|
|
13
13
|
|
|
14
14
|
## Installation
|
|
15
15
|
|
|
16
|
-
`0.1.0-alpha.
|
|
17
|
-
once publication is verified; until then, run the repository example.
|
|
16
|
+
`0.1.0-alpha.3` is an alpha release; its API may still change.
|
|
18
17
|
|
|
19
18
|
```sh
|
|
20
|
-
npm install react-native-reserved-regions@0.1.0-alpha.
|
|
19
|
+
npm install react-native-reserved-regions@0.1.0-alpha.3
|
|
21
20
|
```
|
|
22
21
|
|
|
23
22
|
On iOS, install pods in your app's `ios` directory. Android links automatically through React Native autolinking.
|
|
@@ -69,6 +68,21 @@ type ReservedRegion =
|
|
|
69
68
|
|
|
70
69
|
A division splits the available display. `occludesContent` tells you whether content under that division is hidden. An occlusion is an area where content is hidden. On iOS, division regions currently report `occludesContent: false`. The TypeScript declarations in `src/index.tsx` document every field.
|
|
71
70
|
|
|
71
|
+
## Why a provider and a hook?
|
|
72
|
+
|
|
73
|
+
A reserved region needs a coordinate space: the same fold has different local
|
|
74
|
+
coordinates in a full-screen view and an inset panel. `ReservedRegionsProvider`
|
|
75
|
+
renders the native view that defines those bounds and shares its measurements
|
|
76
|
+
with descendants. `useReservedRegions()` reads the nearest provider, so several
|
|
77
|
+
consumers can use the same measurements without each adding a native view. Place
|
|
78
|
+
a provider around each area that needs its own coordinate space; it can replace
|
|
79
|
+
an existing container `View`.
|
|
80
|
+
|
|
81
|
+
[react-native-hinges](https://appandflow.github.io/react-native-hinges/docs/usage)
|
|
82
|
+
exposes a hook without a provider because posture and angle do not depend on a
|
|
83
|
+
child view's position or size. It observes the existing React root's hierarchy/window.
|
|
84
|
+
Use both libraries when layout and animation need those separate inputs.
|
|
85
|
+
|
|
72
86
|
## Native sources
|
|
73
87
|
|
|
74
88
|
- iOS queries UIKit's active `UIView` reserved division and occlusion regions on the provider view. Typed UIKit calls are guarded by the SDK version and runtime availability. Building with an SDK older than iOS 27.1 compiles out this feature. [Apple's reserved regions overview](https://developer.apple.com/videos/play/tech-talks/111463/)
|
|
@@ -96,6 +110,10 @@ Keeping the animated subtree mounted avoided this failure in the tested case;
|
|
|
96
110
|
apps that gate its mount need to apply the patch, rebuild the native app, and
|
|
97
111
|
validate it themselves.
|
|
98
112
|
|
|
113
|
+
The [performance guide](https://appandflow.github.io/react-native-reserved-regions/docs/performance)
|
|
114
|
+
explains provider placement and optional readiness gating. `ReservedRegionsGate`
|
|
115
|
+
is included starting with `0.1.0-alpha.3`.
|
|
116
|
+
|
|
99
117
|
## Development
|
|
100
118
|
|
|
101
119
|
```sh
|
|
@@ -34,6 +34,7 @@ class ReservedRegionsView(context: Context) : ReactViewGroup(context), ViewTreeO
|
|
|
34
34
|
private var foldingFeatures: List<FoldingFeature> = emptyList()
|
|
35
35
|
private var foldingFeaturesReady = false
|
|
36
36
|
private var lastRegions: List<ReservedRegion>? = null
|
|
37
|
+
private var awaitingFirstMount = true
|
|
37
38
|
private var onRegionsChange: RegionsChangeHandler? = null
|
|
38
39
|
|
|
39
40
|
override fun willDispatchViewUpdates(uiManager: UIManager) {}
|
|
@@ -45,13 +46,17 @@ class ReservedRegionsView(context: Context) : ReactViewGroup(context), ViewTreeO
|
|
|
45
46
|
override fun didDispatchMountItems(uiManager: UIManager) {}
|
|
46
47
|
|
|
47
48
|
override fun didMountItems(uiManager: UIManager) {
|
|
48
|
-
|
|
49
|
-
updateRegions()
|
|
49
|
+
if (awaitingFirstMount) updateRegions()
|
|
50
50
|
}
|
|
51
51
|
|
|
52
52
|
override fun onAttachedToWindow() {
|
|
53
53
|
super.onAttachedToWindow()
|
|
54
54
|
uiManager = UIManagerHelper.getUIManagerForReactTag(UIManagerHelper.getReactContext(this), id)
|
|
55
|
+
awaitingFirstMount = true
|
|
56
|
+
// React Native's FabricMountingManager.cpp applies layout before installing a view's event
|
|
57
|
+
// emitter inside one mount batch, so onLayout cannot dispatch a synchronous event on first
|
|
58
|
+
// mount; didMountItems is the earliest point after the emitter exists and before the event
|
|
59
|
+
// beat. It runs for every mount batch in the app, so it is removed after the first delivery.
|
|
55
60
|
uiManager?.addUIManagerEventListener(this)
|
|
56
61
|
viewTreeObserver.addOnPreDrawListener(this)
|
|
57
62
|
foldingFeatures = emptyList()
|
|
@@ -81,6 +86,11 @@ class ReservedRegionsView(context: Context) : ReactViewGroup(context), ViewTreeO
|
|
|
81
86
|
super.onDetachedFromWindow()
|
|
82
87
|
}
|
|
83
88
|
|
|
89
|
+
override fun onLayout(changed: Boolean, left: Int, top: Int, right: Int, bottom: Int) {
|
|
90
|
+
super.onLayout(changed, left, top, right, bottom)
|
|
91
|
+
if (!awaitingFirstMount) updateRegions()
|
|
92
|
+
}
|
|
93
|
+
|
|
84
94
|
override fun onPreDraw(): Boolean {
|
|
85
95
|
updateRegions()
|
|
86
96
|
return true
|
|
@@ -92,9 +102,9 @@ class ReservedRegionsView(context: Context) : ReactViewGroup(context), ViewTreeO
|
|
|
92
102
|
invalidate()
|
|
93
103
|
}
|
|
94
104
|
|
|
95
|
-
private fun updateRegions() {
|
|
96
|
-
val handler = onRegionsChange ?: return
|
|
97
|
-
if (!isAttachedToWindow || !foldingFeaturesReady || width == 0 || height == 0) return
|
|
105
|
+
private fun updateRegions(): Boolean {
|
|
106
|
+
val handler = onRegionsChange ?: return false
|
|
107
|
+
if (!isAttachedToWindow || !foldingFeaturesReady || width == 0 || height == 0) return false
|
|
98
108
|
|
|
99
109
|
val windowLocation = IntArray(2)
|
|
100
110
|
getLocationInWindow(windowLocation)
|
|
@@ -116,10 +126,14 @@ class ReservedRegionsView(context: Context) : ReactViewGroup(context), ViewTreeO
|
|
|
116
126
|
}
|
|
117
127
|
}
|
|
118
128
|
|
|
119
|
-
if (regions
|
|
120
|
-
|
|
121
|
-
|
|
129
|
+
if (regions == lastRegions) return false
|
|
130
|
+
lastRegions = regions
|
|
131
|
+
handler(this, regions)
|
|
132
|
+
if (awaitingFirstMount) {
|
|
133
|
+
awaitingFirstMount = false
|
|
134
|
+
uiManager?.removeUIManagerEventListener(this)
|
|
122
135
|
}
|
|
136
|
+
return true
|
|
123
137
|
}
|
|
124
138
|
|
|
125
139
|
private fun clippedFrame(bounds: Rect, originX: Int, originY: Int): Rect? {
|
|
@@ -22,6 +22,17 @@ using namespace facebook::react;
|
|
|
22
22
|
if (self = [super initWithFrame:frame]) {
|
|
23
23
|
static const auto defaultProps = std::make_shared<const ReservedRegionsViewProps>();
|
|
24
24
|
_props = defaultProps;
|
|
25
|
+
#if defined(__IPHONE_27_1) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_27_1
|
|
26
|
+
if (@available(iOS 27.1, *)) {
|
|
27
|
+
// UIKit posts no reserved-region change notification, so hinge updates schedule the re-query.
|
|
28
|
+
__weak __typeof(self) weakSelf = self;
|
|
29
|
+
UIHingeInteraction *hingeInteraction =
|
|
30
|
+
[[UIHingeInteraction alloc] initWithUpdateHandler:^(UIHingeInteraction *, UIHingeInteractionUpdate *) {
|
|
31
|
+
[weakSelf setNeedsLayout];
|
|
32
|
+
}];
|
|
33
|
+
[self addInteraction:hingeInteraction];
|
|
34
|
+
}
|
|
35
|
+
#endif
|
|
25
36
|
}
|
|
26
37
|
return self;
|
|
27
38
|
}
|
package/lib/module/index.js
CHANGED
|
@@ -70,4 +70,11 @@ export function useReservedRegionsReady() {
|
|
|
70
70
|
}
|
|
71
71
|
return snapshot.isReady;
|
|
72
72
|
}
|
|
73
|
+
|
|
74
|
+
/** Renders children after the nearest provider reports its first measurement. */
|
|
75
|
+
export function ReservedRegionsGate({
|
|
76
|
+
children
|
|
77
|
+
}) {
|
|
78
|
+
return useReservedRegionsReady() ? children : null;
|
|
79
|
+
}
|
|
73
80
|
//# sourceMappingURL=index.js.map
|
package/lib/module/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["React","ReservedRegionsView","jsx","_jsx","ReservedRegionsContext","createContext","ReservedRegionsProvider","children","props","snapshot","setSnapshot","useState","regions","isReady","onRegionsChange","useCallback","event","nativeEvent","flatMap","region","kind","frame","occludesContent","Provider","value","useReservedRegions","useContext","Error","useReservedRegionsReady"],"sourceRoot":"../../src","sources":["index.tsx"],"mappings":";;AAAA,OAAO,KAAKA,KAAK,MAAM,OAAO;AAE9B,SAASC,mBAAmB,QAAQ,uBAAuB;;AAG3D;;AAYA;AAAA,SAAAC,GAAA,IAAAC,IAAA;AAsBA,MAAMC,sBAAsB,gBAAGJ,KAAK,CAACK,aAAa,CAAiC,IAAI,CAAC;;AAExF;AACA,OAAO,SAASC,uBAAuBA,CAAC;EAAEC,QAAQ;EAAE,GAAGC;AAAiB,CAAC,EAAqB;EAC5F,MAAM,CAACC,QAAQ,EAAEC,WAAW,CAAC,GAAGV,KAAK,CAACW,QAAQ,CAA0B;IAAEC,OAAO,EAAE,EAAE;IAAEC,OAAO,EAAE;EAAM,CAAC,CAAC;EACxG,MAAMC,eAAe,GAAGd,KAAK,CAACe,WAAW,CAAEC,KAA0C,IAAK;IACxF,MAAMJ,OAAO,GAAGI,KAAK,CAACC,WAAW,CAACL,OAAO,CAACM,OAAO,CAAEC,MAAM,IAAuB;MAC9E,IAAIA,MAAM,CAACC,IAAI,KAAK,UAAU,EAAE;QAC9B,OAAO,CAAC;UAAEA,IAAI,EAAE,UAAU;UAAEC,KAAK,EAAEF,MAAM,CAACE,KAAK;UAAEC,eAAe,EAAEH,MAAM,CAACG;QAAgB,CAAC,CAAC;MAC7F;MACA,IAAIH,MAAM,CAACC,IAAI,KAAK,WAAW,EAAE;QAC/B,OAAO,CAAC;UAAEA,IAAI,EAAE,WAAW;UAAEC,KAAK,EAAEF,MAAM,CAACE;QAAM,CAAC,CAAC;MACrD;MACA,OAAO,EAAE;IACX,CAAC,CAAC;IACFX,WAAW,CAAC;MAAEE,OAAO;MAAEC,OAAO,EAAE;IAAK,CAAC,CAAC;EACzC,CAAC,EAAE,EAAE,CAAC;EAEN,oBACEV,IAAA,CAACC,sBAAsB,CAACmB,QAAQ;IAACC,KAAK,EAAEf,QAAS;IAAAF,QAAA,eAC/CJ,IAAA,CAACF,mBAAmB;MAAA,GAAKO,KAAK;MAAEM,eAAe,EAAEA,eAAgB;MAAAP,QAAA,EAC9DA;IAAQ,CACU;EAAC,CACS,CAAC;AAEtC;;AAEA;AACA,OAAO,SAASkB,kBAAkBA,CAAA,EAA8B;EAC9D,MAAMhB,QAAQ,GAAGT,KAAK,CAAC0B,UAAU,CAACtB,sBAAsB,CAAC;EACzD,IAAIK,QAAQ,KAAK,IAAI,EAAE;IACrB,MAAM,IAAIkB,KAAK,CAAC,gEAAgE,CAAC;EACnF;EACA,OAAOlB,QAAQ,CAACG,OAAO;AACzB;;AAEA;AACA;AACA;AACA;AACA,OAAO,SAASgB,uBAAuBA,CAAA,EAAY;EACjD,MAAMnB,QAAQ,GAAGT,KAAK,CAAC0B,UAAU,CAACtB,sBAAsB,CAAC;EACzD,IAAIK,QAAQ,KAAK,IAAI,EAAE;IACrB,MAAM,IAAIkB,KAAK,CAAC,qEAAqE,CAAC;EACxF;EACA,OAAOlB,QAAQ,CAACI,OAAO;AACzB","ignoreList":[]}
|
|
1
|
+
{"version":3,"names":["React","ReservedRegionsView","jsx","_jsx","ReservedRegionsContext","createContext","ReservedRegionsProvider","children","props","snapshot","setSnapshot","useState","regions","isReady","onRegionsChange","useCallback","event","nativeEvent","flatMap","region","kind","frame","occludesContent","Provider","value","useReservedRegions","useContext","Error","useReservedRegionsReady","ReservedRegionsGate"],"sourceRoot":"../../src","sources":["index.tsx"],"mappings":";;AAAA,OAAO,KAAKA,KAAK,MAAM,OAAO;AAE9B,SAASC,mBAAmB,QAAQ,uBAAuB;;AAG3D;;AAYA;AAAA,SAAAC,GAAA,IAAAC,IAAA;AAsBA,MAAMC,sBAAsB,gBAAGJ,KAAK,CAACK,aAAa,CAAiC,IAAI,CAAC;;AAExF;AACA,OAAO,SAASC,uBAAuBA,CAAC;EAAEC,QAAQ;EAAE,GAAGC;AAAiB,CAAC,EAAqB;EAC5F,MAAM,CAACC,QAAQ,EAAEC,WAAW,CAAC,GAAGV,KAAK,CAACW,QAAQ,CAA0B;IAAEC,OAAO,EAAE,EAAE;IAAEC,OAAO,EAAE;EAAM,CAAC,CAAC;EACxG,MAAMC,eAAe,GAAGd,KAAK,CAACe,WAAW,CAAEC,KAA0C,IAAK;IACxF,MAAMJ,OAAO,GAAGI,KAAK,CAACC,WAAW,CAACL,OAAO,CAACM,OAAO,CAAEC,MAAM,IAAuB;MAC9E,IAAIA,MAAM,CAACC,IAAI,KAAK,UAAU,EAAE;QAC9B,OAAO,CAAC;UAAEA,IAAI,EAAE,UAAU;UAAEC,KAAK,EAAEF,MAAM,CAACE,KAAK;UAAEC,eAAe,EAAEH,MAAM,CAACG;QAAgB,CAAC,CAAC;MAC7F;MACA,IAAIH,MAAM,CAACC,IAAI,KAAK,WAAW,EAAE;QAC/B,OAAO,CAAC;UAAEA,IAAI,EAAE,WAAW;UAAEC,KAAK,EAAEF,MAAM,CAACE;QAAM,CAAC,CAAC;MACrD;MACA,OAAO,EAAE;IACX,CAAC,CAAC;IACFX,WAAW,CAAC;MAAEE,OAAO;MAAEC,OAAO,EAAE;IAAK,CAAC,CAAC;EACzC,CAAC,EAAE,EAAE,CAAC;EAEN,oBACEV,IAAA,CAACC,sBAAsB,CAACmB,QAAQ;IAACC,KAAK,EAAEf,QAAS;IAAAF,QAAA,eAC/CJ,IAAA,CAACF,mBAAmB;MAAA,GAAKO,KAAK;MAAEM,eAAe,EAAEA,eAAgB;MAAAP,QAAA,EAC9DA;IAAQ,CACU;EAAC,CACS,CAAC;AAEtC;;AAEA;AACA,OAAO,SAASkB,kBAAkBA,CAAA,EAA8B;EAC9D,MAAMhB,QAAQ,GAAGT,KAAK,CAAC0B,UAAU,CAACtB,sBAAsB,CAAC;EACzD,IAAIK,QAAQ,KAAK,IAAI,EAAE;IACrB,MAAM,IAAIkB,KAAK,CAAC,gEAAgE,CAAC;EACnF;EACA,OAAOlB,QAAQ,CAACG,OAAO;AACzB;;AAEA;AACA;AACA;AACA;AACA,OAAO,SAASgB,uBAAuBA,CAAA,EAAY;EACjD,MAAMnB,QAAQ,GAAGT,KAAK,CAAC0B,UAAU,CAACtB,sBAAsB,CAAC;EACzD,IAAIK,QAAQ,KAAK,IAAI,EAAE;IACrB,MAAM,IAAIkB,KAAK,CAAC,qEAAqE,CAAC;EACxF;EACA,OAAOlB,QAAQ,CAACI,OAAO;AACzB;;AAEA;AACA,OAAO,SAASgB,mBAAmBA,CAAC;EAAEtB;AAAkC,CAAC,EAAmB;EAC1F,OAAOqB,uBAAuB,CAAC,CAAC,GAAGrB,QAAQ,GAAG,IAAI;AACpD","ignoreList":[]}
|
|
@@ -34,4 +34,6 @@ export declare function useReservedRegions(): readonly ReservedRegion[];
|
|
|
34
34
|
* result. Remains true for that provider's lifetime; does not imply platform support.
|
|
35
35
|
*/
|
|
36
36
|
export declare function useReservedRegionsReady(): boolean;
|
|
37
|
+
/** Renders children after the nearest provider reports its first measurement. */
|
|
38
|
+
export declare function ReservedRegionsGate({ children }: React.PropsWithChildren): React.ReactNode;
|
|
37
39
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAI9C,qFAAqF;AACrF,MAAM,MAAM,mBAAmB,GAAG,QAAQ,CAAC;IACzC,8CAA8C;IAC9C,CAAC,EAAE,MAAM,CAAC;IACV,6CAA6C;IAC7C,CAAC,EAAE,MAAM,CAAC;IACV,8CAA8C;IAC9C,KAAK,EAAE,MAAM,CAAC;IACd,4CAA4C;IAC5C,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC,CAAC;AAEH,2DAA2D;AAC3D,MAAM,MAAM,cAAc,GACtB,QAAQ,CAAC;IACP,sDAAsD;IACtD,IAAI,EAAE,UAAU,CAAC;IACjB,gEAAgE;IAChE,KAAK,EAAE,mBAAmB,CAAC;IAC3B,yDAAyD;IACzD,eAAe,EAAE,OAAO,CAAC;CAC1B,CAAC,GACF,QAAQ,CAAC;IACP,gEAAgE;IAChE,IAAI,EAAE,WAAW,CAAC;IAClB,iEAAiE;IACjE,KAAK,EAAE,mBAAmB,CAAC;CAC5B,CAAC,CAAC;AASP,sFAAsF;AACtF,wBAAgB,uBAAuB,CAAC,EAAE,QAAQ,EAAE,GAAG,KAAK,EAAE,EAAE,SAAS,GAAG,KAAK,CAAC,GAAG,CAAC,OAAO,CAsB5F;AAED,8EAA8E;AAC9E,wBAAgB,kBAAkB,IAAI,SAAS,cAAc,EAAE,CAM9D;AAED;;;GAGG;AACH,wBAAgB,uBAAuB,IAAI,OAAO,CAMjD"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAI9C,qFAAqF;AACrF,MAAM,MAAM,mBAAmB,GAAG,QAAQ,CAAC;IACzC,8CAA8C;IAC9C,CAAC,EAAE,MAAM,CAAC;IACV,6CAA6C;IAC7C,CAAC,EAAE,MAAM,CAAC;IACV,8CAA8C;IAC9C,KAAK,EAAE,MAAM,CAAC;IACd,4CAA4C;IAC5C,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC,CAAC;AAEH,2DAA2D;AAC3D,MAAM,MAAM,cAAc,GACtB,QAAQ,CAAC;IACP,sDAAsD;IACtD,IAAI,EAAE,UAAU,CAAC;IACjB,gEAAgE;IAChE,KAAK,EAAE,mBAAmB,CAAC;IAC3B,yDAAyD;IACzD,eAAe,EAAE,OAAO,CAAC;CAC1B,CAAC,GACF,QAAQ,CAAC;IACP,gEAAgE;IAChE,IAAI,EAAE,WAAW,CAAC;IAClB,iEAAiE;IACjE,KAAK,EAAE,mBAAmB,CAAC;CAC5B,CAAC,CAAC;AASP,sFAAsF;AACtF,wBAAgB,uBAAuB,CAAC,EAAE,QAAQ,EAAE,GAAG,KAAK,EAAE,EAAE,SAAS,GAAG,KAAK,CAAC,GAAG,CAAC,OAAO,CAsB5F;AAED,8EAA8E;AAC9E,wBAAgB,kBAAkB,IAAI,SAAS,cAAc,EAAE,CAM9D;AAED;;;GAGG;AACH,wBAAgB,uBAAuB,IAAI,OAAO,CAMjD;AAED,iFAAiF;AACjF,wBAAgB,mBAAmB,CAAC,EAAE,QAAQ,EAAE,EAAE,KAAK,CAAC,iBAAiB,GAAG,KAAK,CAAC,SAAS,CAE1F"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-native-reserved-regions",
|
|
3
|
-
"version": "0.1.0-alpha.
|
|
3
|
+
"version": "0.1.0-alpha.3",
|
|
4
4
|
"description": "Provider-scoped reserved display regions for React Native",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"android",
|
|
@@ -137,6 +137,7 @@
|
|
|
137
137
|
"lint:fix": "oxlint --fix .",
|
|
138
138
|
"format": "oxfmt .",
|
|
139
139
|
"format:check": "oxfmt --check .",
|
|
140
|
+
"e2e:android": "node e2e/android.mjs",
|
|
140
141
|
"docs:build": "pnpm --filter reserved-regions-docs build",
|
|
141
142
|
"docs:start": "pnpm --filter reserved-regions-docs start"
|
|
142
143
|
}
|
package/src/index.tsx
CHANGED
|
@@ -84,3 +84,8 @@ export function useReservedRegionsReady(): boolean {
|
|
|
84
84
|
}
|
|
85
85
|
return snapshot.isReady;
|
|
86
86
|
}
|
|
87
|
+
|
|
88
|
+
/** Renders children after the nearest provider reports its first measurement. */
|
|
89
|
+
export function ReservedRegionsGate({ children }: React.PropsWithChildren): React.ReactNode {
|
|
90
|
+
return useReservedRegionsReady() ? children : null;
|
|
91
|
+
}
|