@oxyhq/bloom 1.6.0 → 1.8.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/NOTICE +46 -0
- package/docs/media-flight.mdx +151 -3
- package/docs/teleport.mdx +72 -0
- package/lib/commonjs/media-flight/MediaFlightLayer.js +4 -5
- package/lib/commonjs/media-flight/MediaFlightLayer.js.map +1 -1
- package/lib/commonjs/media-flight/media-node.web.js +37 -1
- package/lib/commonjs/media-flight/media-node.web.js.map +1 -1
- package/lib/commonjs/teleport/Portal.js +109 -0
- package/lib/commonjs/teleport/Portal.js.map +1 -0
- package/lib/commonjs/teleport/PortalHost.js +75 -0
- package/lib/commonjs/teleport/PortalHost.js.map +1 -0
- package/lib/commonjs/teleport/PortalHostView.js +40 -0
- package/lib/commonjs/teleport/PortalHostView.js.map +1 -0
- package/lib/commonjs/teleport/PortalHostView.native.js +24 -0
- package/lib/commonjs/teleport/PortalHostView.native.js.map +1 -0
- package/lib/commonjs/teleport/PortalProvider.js +57 -0
- package/lib/commonjs/teleport/PortalProvider.js.map +1 -0
- package/lib/commonjs/teleport/PortalProviderView.js +59 -0
- package/lib/commonjs/teleport/PortalProviderView.js.map +1 -0
- package/lib/commonjs/teleport/PortalProviderView.native.js +19 -0
- package/lib/commonjs/teleport/PortalProviderView.native.js.map +1 -0
- package/lib/commonjs/teleport/PortalView.js +83 -0
- package/lib/commonjs/teleport/PortalView.js.map +1 -0
- package/lib/commonjs/teleport/PortalView.native.js +14 -0
- package/lib/commonjs/teleport/PortalView.native.js.map +1 -0
- package/lib/commonjs/teleport/index.js +35 -0
- package/lib/commonjs/teleport/index.js.map +1 -0
- package/lib/commonjs/teleport/portal-manager.js +40 -0
- package/lib/commonjs/teleport/portal-manager.js.map +1 -0
- package/lib/commonjs/teleport/portal-registry.js +24 -0
- package/lib/commonjs/teleport/portal-registry.js.map +1 -0
- package/lib/commonjs/teleport/reducer.js +86 -0
- package/lib/commonjs/teleport/reducer.js.map +1 -0
- package/lib/commonjs/teleport/scroll-view-context/context.js +17 -0
- package/lib/commonjs/teleport/scroll-view-context/context.js.map +1 -0
- package/lib/commonjs/teleport/scroll-view-context/context.native.js +22 -0
- package/lib/commonjs/teleport/scroll-view-context/context.native.js.map +1 -0
- package/lib/commonjs/teleport/scroll-view-context/types.js +2 -0
- package/lib/commonjs/teleport/scroll-view-context/types.js.map +1 -0
- package/lib/commonjs/teleport/specs/PortalHostViewNativeComponent.js +17 -0
- package/lib/commonjs/teleport/specs/PortalHostViewNativeComponent.js.map +1 -0
- package/lib/commonjs/teleport/specs/PortalViewNativeComponent.js +17 -0
- package/lib/commonjs/teleport/specs/PortalViewNativeComponent.js.map +1 -0
- package/lib/commonjs/teleport/teleport-global.d.js +2 -0
- package/lib/commonjs/teleport/teleport-global.d.js.map +1 -0
- package/lib/commonjs/teleport/types.js +6 -0
- package/lib/commonjs/teleport/types.js.map +1 -0
- package/lib/commonjs/teleport/use-id.js +24 -0
- package/lib/commonjs/teleport/use-id.js.map +1 -0
- package/lib/commonjs/teleport/use-portal.js +59 -0
- package/lib/commonjs/teleport/use-portal.js.map +1 -0
- package/lib/module/media-flight/MediaFlightLayer.js +4 -5
- package/lib/module/media-flight/MediaFlightLayer.js.map +1 -1
- package/lib/module/media-flight/media-node.web.js +37 -1
- package/lib/module/media-flight/media-node.web.js.map +1 -1
- package/lib/module/teleport/Portal.js +103 -0
- package/lib/module/teleport/Portal.js.map +1 -0
- package/lib/module/teleport/PortalHost.js +71 -0
- package/lib/module/teleport/PortalHost.js.map +1 -0
- package/lib/module/teleport/PortalHostView.js +35 -0
- package/lib/module/teleport/PortalHostView.js.map +1 -0
- package/lib/module/teleport/PortalHostView.native.js +18 -0
- package/lib/module/teleport/PortalHostView.native.js.map +1 -0
- package/lib/module/teleport/PortalProvider.js +51 -0
- package/lib/module/teleport/PortalProvider.js.map +1 -0
- package/lib/module/teleport/PortalProviderView.js +54 -0
- package/lib/module/teleport/PortalProviderView.js.map +1 -0
- package/lib/module/teleport/PortalProviderView.native.js +15 -0
- package/lib/module/teleport/PortalProviderView.native.js.map +1 -0
- package/lib/module/teleport/PortalView.js +79 -0
- package/lib/module/teleport/PortalView.js.map +1 -0
- package/lib/module/teleport/PortalView.native.js +10 -0
- package/lib/module/teleport/PortalView.native.js.map +1 -0
- package/lib/module/teleport/index.js +30 -0
- package/lib/module/teleport/index.js.map +1 -0
- package/lib/module/teleport/portal-manager.js +33 -0
- package/lib/module/teleport/portal-manager.js.map +1 -0
- package/lib/module/teleport/portal-registry.js +18 -0
- package/lib/module/teleport/portal-registry.js.map +1 -0
- package/lib/module/teleport/reducer.js +81 -0
- package/lib/module/teleport/reducer.js.map +1 -0
- package/lib/module/teleport/scroll-view-context/context.js +12 -0
- package/lib/module/teleport/scroll-view-context/context.js.map +1 -0
- package/lib/module/teleport/scroll-view-context/context.native.js +18 -0
- package/lib/module/teleport/scroll-view-context/context.native.js.map +1 -0
- package/lib/module/teleport/scroll-view-context/types.js +2 -0
- package/lib/module/teleport/scroll-view-context/types.js.map +1 -0
- package/lib/module/teleport/specs/PortalHostViewNativeComponent.js +13 -0
- package/lib/module/teleport/specs/PortalHostViewNativeComponent.js.map +1 -0
- package/lib/module/teleport/specs/PortalViewNativeComponent.js +13 -0
- package/lib/module/teleport/specs/PortalViewNativeComponent.js.map +1 -0
- package/lib/module/teleport/teleport-global.d.js +2 -0
- package/lib/module/teleport/teleport-global.d.js.map +1 -0
- package/lib/module/teleport/types.js +4 -0
- package/lib/module/teleport/types.js.map +1 -0
- package/lib/module/teleport/use-id.js +19 -0
- package/lib/module/teleport/use-id.js.map +1 -0
- package/lib/module/teleport/use-portal.js +55 -0
- package/lib/module/teleport/use-portal.js.map +1 -0
- package/lib/typescript/commonjs/media-flight/MediaFlightLayer.d.ts.map +1 -1
- package/lib/typescript/commonjs/media-flight/media-node.web.d.ts.map +1 -1
- package/lib/typescript/commonjs/teleport/Portal.d.ts +48 -0
- package/lib/typescript/commonjs/teleport/Portal.d.ts.map +1 -0
- package/lib/typescript/commonjs/teleport/PortalHost.d.ts +25 -0
- package/lib/typescript/commonjs/teleport/PortalHost.d.ts.map +1 -0
- package/lib/typescript/commonjs/teleport/PortalHostView.d.ts +5 -0
- package/lib/typescript/commonjs/teleport/PortalHostView.d.ts.map +1 -0
- package/lib/typescript/commonjs/teleport/PortalHostView.native.d.ts +4 -0
- package/lib/typescript/commonjs/teleport/PortalHostView.native.d.ts.map +1 -0
- package/lib/typescript/commonjs/teleport/PortalProvider.d.ts +23 -0
- package/lib/typescript/commonjs/teleport/PortalProvider.d.ts.map +1 -0
- package/lib/typescript/commonjs/teleport/PortalProviderView.d.ts +3 -0
- package/lib/typescript/commonjs/teleport/PortalProviderView.d.ts.map +1 -0
- package/lib/typescript/commonjs/teleport/PortalProviderView.native.d.ts +9 -0
- package/lib/typescript/commonjs/teleport/PortalProviderView.native.d.ts.map +1 -0
- package/lib/typescript/commonjs/teleport/PortalView.d.ts +9 -0
- package/lib/typescript/commonjs/teleport/PortalView.d.ts.map +1 -0
- package/lib/typescript/commonjs/teleport/PortalView.native.d.ts +8 -0
- package/lib/typescript/commonjs/teleport/PortalView.native.d.ts.map +1 -0
- package/lib/typescript/commonjs/teleport/index.d.ts +29 -0
- package/lib/typescript/commonjs/teleport/index.d.ts.map +1 -0
- package/lib/typescript/commonjs/teleport/portal-manager.d.ts +16 -0
- package/lib/typescript/commonjs/teleport/portal-manager.d.ts.map +1 -0
- package/lib/typescript/commonjs/teleport/portal-registry.d.ts +10 -0
- package/lib/typescript/commonjs/teleport/portal-registry.d.ts.map +1 -0
- package/lib/typescript/commonjs/teleport/reducer.d.ts +40 -0
- package/lib/typescript/commonjs/teleport/reducer.d.ts.map +1 -0
- package/lib/typescript/commonjs/teleport/scroll-view-context/context.d.ts +4 -0
- package/lib/typescript/commonjs/teleport/scroll-view-context/context.d.ts.map +1 -0
- package/lib/typescript/commonjs/teleport/scroll-view-context/context.native.d.ts +13 -0
- package/lib/typescript/commonjs/teleport/scroll-view-context/context.native.d.ts.map +1 -0
- package/lib/typescript/commonjs/teleport/scroll-view-context/types.d.ts +10 -0
- package/lib/typescript/commonjs/teleport/scroll-view-context/types.d.ts.map +1 -0
- package/lib/typescript/commonjs/teleport/specs/PortalHostViewNativeComponent.d.ts +13 -0
- package/lib/typescript/commonjs/teleport/specs/PortalHostViewNativeComponent.d.ts.map +1 -0
- package/lib/typescript/commonjs/teleport/specs/PortalViewNativeComponent.d.ts +14 -0
- package/lib/typescript/commonjs/teleport/specs/PortalViewNativeComponent.d.ts.map +1 -0
- package/lib/typescript/commonjs/teleport/types.d.ts +22 -0
- package/lib/typescript/commonjs/teleport/types.d.ts.map +1 -0
- package/lib/typescript/commonjs/teleport/use-id.d.ts +2 -0
- package/lib/typescript/commonjs/teleport/use-id.d.ts.map +1 -0
- package/lib/typescript/commonjs/teleport/use-portal.d.ts +35 -0
- package/lib/typescript/commonjs/teleport/use-portal.d.ts.map +1 -0
- package/lib/typescript/module/media-flight/MediaFlightLayer.d.ts.map +1 -1
- package/lib/typescript/module/media-flight/media-node.web.d.ts.map +1 -1
- package/lib/typescript/module/teleport/Portal.d.ts +48 -0
- package/lib/typescript/module/teleport/Portal.d.ts.map +1 -0
- package/lib/typescript/module/teleport/PortalHost.d.ts +25 -0
- package/lib/typescript/module/teleport/PortalHost.d.ts.map +1 -0
- package/lib/typescript/module/teleport/PortalHostView.d.ts +5 -0
- package/lib/typescript/module/teleport/PortalHostView.d.ts.map +1 -0
- package/lib/typescript/module/teleport/PortalHostView.native.d.ts +4 -0
- package/lib/typescript/module/teleport/PortalHostView.native.d.ts.map +1 -0
- package/lib/typescript/module/teleport/PortalProvider.d.ts +23 -0
- package/lib/typescript/module/teleport/PortalProvider.d.ts.map +1 -0
- package/lib/typescript/module/teleport/PortalProviderView.d.ts +3 -0
- package/lib/typescript/module/teleport/PortalProviderView.d.ts.map +1 -0
- package/lib/typescript/module/teleport/PortalProviderView.native.d.ts +9 -0
- package/lib/typescript/module/teleport/PortalProviderView.native.d.ts.map +1 -0
- package/lib/typescript/module/teleport/PortalView.d.ts +9 -0
- package/lib/typescript/module/teleport/PortalView.d.ts.map +1 -0
- package/lib/typescript/module/teleport/PortalView.native.d.ts +8 -0
- package/lib/typescript/module/teleport/PortalView.native.d.ts.map +1 -0
- package/lib/typescript/module/teleport/index.d.ts +29 -0
- package/lib/typescript/module/teleport/index.d.ts.map +1 -0
- package/lib/typescript/module/teleport/portal-manager.d.ts +16 -0
- package/lib/typescript/module/teleport/portal-manager.d.ts.map +1 -0
- package/lib/typescript/module/teleport/portal-registry.d.ts +10 -0
- package/lib/typescript/module/teleport/portal-registry.d.ts.map +1 -0
- package/lib/typescript/module/teleport/reducer.d.ts +40 -0
- package/lib/typescript/module/teleport/reducer.d.ts.map +1 -0
- package/lib/typescript/module/teleport/scroll-view-context/context.d.ts +4 -0
- package/lib/typescript/module/teleport/scroll-view-context/context.d.ts.map +1 -0
- package/lib/typescript/module/teleport/scroll-view-context/context.native.d.ts +13 -0
- package/lib/typescript/module/teleport/scroll-view-context/context.native.d.ts.map +1 -0
- package/lib/typescript/module/teleport/scroll-view-context/types.d.ts +10 -0
- package/lib/typescript/module/teleport/scroll-view-context/types.d.ts.map +1 -0
- package/lib/typescript/module/teleport/specs/PortalHostViewNativeComponent.d.ts +13 -0
- package/lib/typescript/module/teleport/specs/PortalHostViewNativeComponent.d.ts.map +1 -0
- package/lib/typescript/module/teleport/specs/PortalViewNativeComponent.d.ts +14 -0
- package/lib/typescript/module/teleport/specs/PortalViewNativeComponent.d.ts.map +1 -0
- package/lib/typescript/module/teleport/types.d.ts +22 -0
- package/lib/typescript/module/teleport/types.d.ts.map +1 -0
- package/lib/typescript/module/teleport/use-id.d.ts +2 -0
- package/lib/typescript/module/teleport/use-id.d.ts.map +1 -0
- package/lib/typescript/module/teleport/use-portal.d.ts +35 -0
- package/lib/typescript/module/teleport/use-portal.d.ts.map +1 -0
- package/package.json +16 -1
- package/src/media-flight/MediaFlightLayer.tsx +4 -5
- package/src/media-flight/media-node.web.ts +42 -1
- package/src/teleport/Portal.tsx +97 -0
- package/src/teleport/PortalHost.tsx +61 -0
- package/src/teleport/PortalHostView.native.tsx +14 -0
- package/src/teleport/PortalHostView.tsx +30 -0
- package/src/teleport/PortalProvider.tsx +51 -0
- package/src/teleport/PortalProviderView.native.tsx +11 -0
- package/src/teleport/PortalProviderView.tsx +67 -0
- package/src/teleport/PortalView.native.tsx +7 -0
- package/src/teleport/PortalView.tsx +94 -0
- package/src/teleport/index.ts +32 -0
- package/src/teleport/portal-manager.tsx +48 -0
- package/src/teleport/portal-registry.ts +27 -0
- package/src/teleport/reducer.ts +94 -0
- package/src/teleport/scroll-view-context/context.native.ts +19 -0
- package/src/teleport/scroll-view-context/context.ts +12 -0
- package/src/teleport/scroll-view-context/types.ts +7 -0
- package/src/teleport/specs/PortalHostViewNativeComponent.ts +15 -0
- package/src/teleport/specs/PortalViewNativeComponent.ts +16 -0
- package/src/teleport/teleport-global.d.ts +11 -0
- package/src/teleport/types.ts +22 -0
- package/src/teleport/use-id.ts +18 -0
- package/src/teleport/use-portal.ts +47 -0
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* COPIED FROM react-native-teleport 1.2.0 — `src/views/Portal/index.tsx`
|
|
3
|
+
* MIT, Copyright (c) 2025 Kiryl Ziusko. Full licence in `NOTICE` at the root.
|
|
4
|
+
*
|
|
5
|
+
* Changed: import paths only, for this flat directory.
|
|
6
|
+
*/
|
|
7
|
+
/// <reference lib="dom" />
|
|
8
|
+
|
|
9
|
+
import { useRef, useLayoutEffect, useCallback } from "react";
|
|
10
|
+
import { createPortal } from "react-dom";
|
|
11
|
+
import { usePortalRegistryContext } from "./portal-registry";
|
|
12
|
+
import type { PortalProps } from "./types";
|
|
13
|
+
|
|
14
|
+
const supportsMoveBefore =
|
|
15
|
+
typeof Element !== "undefined" && "moveBefore" in Element.prototype;
|
|
16
|
+
|
|
17
|
+
function moveElementTo(
|
|
18
|
+
parent: Element,
|
|
19
|
+
child: Element,
|
|
20
|
+
before: Element | null = null,
|
|
21
|
+
) {
|
|
22
|
+
if (supportsMoveBefore && child.parentNode) {
|
|
23
|
+
parent.moveBefore(child, before);
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
if (child.parentNode) {
|
|
28
|
+
child.parentNode.removeChild(child);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
parent.insertBefore(child, before);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export default function Portal({ hostName, children, style }: PortalProps) {
|
|
35
|
+
const { getHost, registerPendingPortal, unregisterPendingPortal } =
|
|
36
|
+
usePortalRegistryContext();
|
|
37
|
+
const elRef = useRef<HTMLDivElement | null>(null);
|
|
38
|
+
if (!elRef.current) {
|
|
39
|
+
elRef.current = document.createElement("div");
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const sentinelRef = useRef<HTMLDivElement>(null);
|
|
43
|
+
|
|
44
|
+
useLayoutEffect(() => {
|
|
45
|
+
if (elRef.current && style) {
|
|
46
|
+
Object.assign(elRef.current.style, style);
|
|
47
|
+
}
|
|
48
|
+
}, [style]);
|
|
49
|
+
|
|
50
|
+
const teleportToHost = useCallback(() => {
|
|
51
|
+
const el = elRef.current;
|
|
52
|
+
if (!el) return;
|
|
53
|
+
|
|
54
|
+
const hostNode = hostName ? getHost(hostName) : null;
|
|
55
|
+
if (hostNode) {
|
|
56
|
+
// teleport view to the host
|
|
57
|
+
moveElementTo(hostNode, el);
|
|
58
|
+
} else if (sentinelRef.current && sentinelRef.current.parentElement) {
|
|
59
|
+
// keep view locally
|
|
60
|
+
const parent = sentinelRef.current.parentElement;
|
|
61
|
+
moveElementTo(parent, el, sentinelRef.current);
|
|
62
|
+
}
|
|
63
|
+
}, [hostName, getHost]);
|
|
64
|
+
|
|
65
|
+
useLayoutEffect(() => {
|
|
66
|
+
teleportToHost();
|
|
67
|
+
|
|
68
|
+
if (!hostName) return;
|
|
69
|
+
|
|
70
|
+
registerPendingPortal(hostName, teleportToHost);
|
|
71
|
+
return () => {
|
|
72
|
+
unregisterPendingPortal(hostName, teleportToHost);
|
|
73
|
+
};
|
|
74
|
+
}, [
|
|
75
|
+
hostName,
|
|
76
|
+
registerPendingPortal,
|
|
77
|
+
unregisterPendingPortal,
|
|
78
|
+
teleportToHost,
|
|
79
|
+
]);
|
|
80
|
+
|
|
81
|
+
return (
|
|
82
|
+
<>
|
|
83
|
+
{createPortal(children, elRef.current)}
|
|
84
|
+
{/* Invisible sentinel for local position */}
|
|
85
|
+
<div ref={sentinelRef} style={styles.anchor} />
|
|
86
|
+
</>
|
|
87
|
+
);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
const styles = {
|
|
91
|
+
anchor: {
|
|
92
|
+
display: "contents",
|
|
93
|
+
},
|
|
94
|
+
};
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* react-native-teleport, vendored.
|
|
3
|
+
*
|
|
4
|
+
* COPIED FROM react-native-teleport 1.2.0 — `src/index.ts`. MIT, Copyright (c)
|
|
5
|
+
* 2025 Kiryl Ziusko; the full licence is in `NOTICE` at the repository root and
|
|
6
|
+
* every file in this directory names the file it came from.
|
|
7
|
+
*
|
|
8
|
+
* It is here rather than as a dependency because Bloom needs its NATIVE
|
|
9
|
+
* re-parenting — moving one platform view between hosts instead of mounting a
|
|
10
|
+
* second one — and that arrives as Fabric components, not as JavaScript.
|
|
11
|
+
*
|
|
12
|
+
* WHAT IS DIFFERENT FROM UPSTREAM, and it is not their code: **Bloom mounts
|
|
13
|
+
* these portals from its ROOT LAYER, never from the origin screen.** Their own
|
|
14
|
+
* recipe mounts the `<Portal>` inside the screen the media starts on, which is
|
|
15
|
+
* correct for a navigator that keeps that screen alive — and measured against
|
|
16
|
+
* expo-router on web, where the origin route unmounts on the URL change, it
|
|
17
|
+
* takes the media with it (`count 1 -> 0 -> 0`). The portal is not what fails
|
|
18
|
+
* there; the ownership is. Same piece, mounted where it does not die.
|
|
19
|
+
*
|
|
20
|
+
* Changed: import paths only, for this flat directory. Their file layout uses
|
|
21
|
+
* `index.tsx` per component, which Bloom's family-layout gate reserves for pure
|
|
22
|
+
* barrels, so each one is named after what it exports.
|
|
23
|
+
*/
|
|
24
|
+
export { default as PortalHost } from './PortalHost';
|
|
25
|
+
export { default as Portal } from './Portal';
|
|
26
|
+
export { default as PortalProvider } from './PortalProvider';
|
|
27
|
+
export { default as usePortal } from './use-portal';
|
|
28
|
+
export type {
|
|
29
|
+
PortalHostProps,
|
|
30
|
+
PortalProps,
|
|
31
|
+
PortalProviderProps,
|
|
32
|
+
} from './types';
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* COPIED FROM react-native-teleport 1.2.0 — `src/contexts/PortalManager.tsx`
|
|
3
|
+
* MIT, Copyright (c) 2025 Kiryl Ziusko. Full licence in `NOTICE` at the root.
|
|
4
|
+
*
|
|
5
|
+
* Changed: import paths only, for this flat directory.
|
|
6
|
+
*/
|
|
7
|
+
import {
|
|
8
|
+
createContext,
|
|
9
|
+
useContext,
|
|
10
|
+
useReducer,
|
|
11
|
+
useMemo,
|
|
12
|
+
type ReactNode,
|
|
13
|
+
} from "react";
|
|
14
|
+
import {
|
|
15
|
+
initialState,
|
|
16
|
+
reducer,
|
|
17
|
+
type Action,
|
|
18
|
+
type PortalState,
|
|
19
|
+
} from "./reducer";
|
|
20
|
+
|
|
21
|
+
const PortalManagerContext = createContext<
|
|
22
|
+
{ state: PortalState; dispatch: React.Dispatch<Action> } | undefined
|
|
23
|
+
>(undefined);
|
|
24
|
+
|
|
25
|
+
export const PortalManagerProvider = ({
|
|
26
|
+
children,
|
|
27
|
+
}: {
|
|
28
|
+
children: ReactNode;
|
|
29
|
+
}) => {
|
|
30
|
+
const [state, dispatch] = useReducer(reducer, initialState);
|
|
31
|
+
const context = useMemo(() => ({ state, dispatch }), [state, dispatch]);
|
|
32
|
+
|
|
33
|
+
return (
|
|
34
|
+
<PortalManagerContext.Provider value={context}>
|
|
35
|
+
{children}
|
|
36
|
+
</PortalManagerContext.Provider>
|
|
37
|
+
);
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
export const usePortalManagerContext = () => {
|
|
41
|
+
const context = useContext(PortalManagerContext);
|
|
42
|
+
|
|
43
|
+
if (!context) {
|
|
44
|
+
throw new Error("usePortalContext must be used within PortalProvider");
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
return context;
|
|
48
|
+
};
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* COPIED FROM react-native-teleport 1.2.0 — `src/contexts/PortalRegistry.ts`
|
|
3
|
+
* MIT, Copyright (c) 2025 Kiryl Ziusko. Full licence in `NOTICE` at the root.
|
|
4
|
+
*
|
|
5
|
+
* Changed: nothing — byte-for-byte, only its path.
|
|
6
|
+
*/
|
|
7
|
+
import { createContext, useContext } from "react";
|
|
8
|
+
|
|
9
|
+
type PortalRegistryContextType = {
|
|
10
|
+
registerHost: (name: string, node: HTMLElement | null) => void;
|
|
11
|
+
getHost: (name: string) => HTMLElement | null;
|
|
12
|
+
registerPendingPortal: (name: string, callback: () => void) => void;
|
|
13
|
+
unregisterPendingPortal: (name: string, callback: () => void) => void;
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
export const PortalRegistryContext =
|
|
17
|
+
createContext<PortalRegistryContextType | null>(null);
|
|
18
|
+
|
|
19
|
+
export function usePortalRegistryContext() {
|
|
20
|
+
const context = useContext(PortalRegistryContext);
|
|
21
|
+
if (!context) {
|
|
22
|
+
throw new Error(
|
|
23
|
+
"usePortalRegistryContext must be used within a PortalRegistryContext",
|
|
24
|
+
);
|
|
25
|
+
}
|
|
26
|
+
return context;
|
|
27
|
+
}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* COPIED FROM react-native-teleport 1.2.0 — `src/state/reducer.ts`
|
|
3
|
+
* MIT, Copyright (c) 2025 Kiryl Ziusko. Full licence in `NOTICE` at the root.
|
|
4
|
+
*
|
|
5
|
+
* Changed: nothing — byte-for-byte, only its path.
|
|
6
|
+
*/
|
|
7
|
+
import type { ScrollViewContextValue } from "./scroll-view-context/types";
|
|
8
|
+
|
|
9
|
+
export type PortalState = {
|
|
10
|
+
removed: Record<string, Record<string, Record<string, boolean>>>;
|
|
11
|
+
hosts: Record<string, number>;
|
|
12
|
+
hostScrollViewContexts: Record<string, ScrollViewContextValue | undefined>;
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
export type Action =
|
|
16
|
+
| { type: "REMOVE_PORTAL"; hostName: string; name: string }
|
|
17
|
+
| {
|
|
18
|
+
type: "CLEAR_REMOVED_ON_UNMOUNT";
|
|
19
|
+
hostName: string;
|
|
20
|
+
name: string;
|
|
21
|
+
instanceId: string;
|
|
22
|
+
}
|
|
23
|
+
| {
|
|
24
|
+
type: "REGISTER_PORTAL";
|
|
25
|
+
hostName: string;
|
|
26
|
+
name: string;
|
|
27
|
+
instanceId: string;
|
|
28
|
+
}
|
|
29
|
+
| { type: "REGISTER_HOST"; hostName: string }
|
|
30
|
+
| { type: "UNREGISTER_HOST"; hostName: string }
|
|
31
|
+
| {
|
|
32
|
+
type: "SET_HOST_SCROLL_VIEW_CONTEXT";
|
|
33
|
+
hostName: string;
|
|
34
|
+
value: ScrollViewContextValue;
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
export const initialState: PortalState = {
|
|
38
|
+
removed: {},
|
|
39
|
+
hosts: {},
|
|
40
|
+
hostScrollViewContexts: {},
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
export const reducer = (state: PortalState, action: Action): PortalState => {
|
|
44
|
+
const cloned = {
|
|
45
|
+
...state,
|
|
46
|
+
removed: { ...state.removed },
|
|
47
|
+
hostScrollViewContexts: { ...state.hostScrollViewContexts },
|
|
48
|
+
};
|
|
49
|
+
const hostRemoved =
|
|
50
|
+
"name" in action ? cloned.removed[action.hostName] || {} : {};
|
|
51
|
+
cloned.removed[action.hostName] = hostRemoved;
|
|
52
|
+
const nameRemoved = "name" in action ? hostRemoved[action.name] || {} : {};
|
|
53
|
+
if ("name" in action) {
|
|
54
|
+
hostRemoved[action.name] = nameRemoved;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
switch (action.type) {
|
|
58
|
+
case "REGISTER_HOST": {
|
|
59
|
+
const hosts = { ...cloned.hosts };
|
|
60
|
+
hosts[action.hostName] = (hosts[action.hostName] || 0) + 1;
|
|
61
|
+
return { ...cloned, hosts };
|
|
62
|
+
}
|
|
63
|
+
case "UNREGISTER_HOST": {
|
|
64
|
+
const hosts = { ...cloned.hosts };
|
|
65
|
+
const count = (hosts[action.hostName] || 0) - 1;
|
|
66
|
+
if (count <= 0) {
|
|
67
|
+
delete hosts[action.hostName];
|
|
68
|
+
delete cloned.hostScrollViewContexts[action.hostName];
|
|
69
|
+
} else {
|
|
70
|
+
hosts[action.hostName] = count;
|
|
71
|
+
}
|
|
72
|
+
return { ...cloned, hosts };
|
|
73
|
+
}
|
|
74
|
+
case "SET_HOST_SCROLL_VIEW_CONTEXT":
|
|
75
|
+
cloned.hostScrollViewContexts[action.hostName] = action.value;
|
|
76
|
+
return cloned;
|
|
77
|
+
case "REGISTER_PORTAL":
|
|
78
|
+
if (!nameRemoved[action.instanceId]) {
|
|
79
|
+
nameRemoved[action.instanceId] = false;
|
|
80
|
+
}
|
|
81
|
+
return cloned;
|
|
82
|
+
case "REMOVE_PORTAL":
|
|
83
|
+
Object.keys(nameRemoved).forEach((id) => (nameRemoved[id] = true));
|
|
84
|
+
return cloned;
|
|
85
|
+
case "CLEAR_REMOVED_ON_UNMOUNT":
|
|
86
|
+
delete nameRemoved[action.instanceId];
|
|
87
|
+
if (Object.keys(nameRemoved).length === 0) {
|
|
88
|
+
delete hostRemoved[action.name];
|
|
89
|
+
}
|
|
90
|
+
return cloned;
|
|
91
|
+
default:
|
|
92
|
+
return state;
|
|
93
|
+
}
|
|
94
|
+
};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* COPIED FROM react-native-teleport 1.2.0 — `src/contexts/ScrollViewContext/index.native.ts`
|
|
3
|
+
* MIT, Copyright (c) 2025 Kiryl Ziusko. Full licence in `NOTICE` at the root.
|
|
4
|
+
*
|
|
5
|
+
* Changed: import paths, and `ScrollView.Context` is reached through a cast
|
|
6
|
+
* because Bloom does not compile with their `react-native-strict-api` condition,
|
|
7
|
+
* which is the only place that property is declared.
|
|
8
|
+
*/
|
|
9
|
+
import type { Context } from "react";
|
|
10
|
+
import { ScrollView } from "react-native";
|
|
11
|
+
import type { ScrollViewContextValue } from "./types";
|
|
12
|
+
|
|
13
|
+
// Bloom does not compile with their `react-native-strict-api` condition, and
|
|
14
|
+
// `ScrollView.Context` is only declared there. Reached through the shape it has
|
|
15
|
+
// at runtime instead; the value and the behaviour are theirs, unchanged.
|
|
16
|
+
const ScrollViewContext = (ScrollView as unknown as { Context: Context<ScrollViewContextValue> })
|
|
17
|
+
.Context;
|
|
18
|
+
|
|
19
|
+
export default ScrollViewContext;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* COPIED FROM react-native-teleport 1.2.0 — `src/contexts/ScrollViewContext/index.ts`
|
|
3
|
+
* MIT, Copyright (c) 2025 Kiryl Ziusko. Full licence in `NOTICE` at the root.
|
|
4
|
+
*
|
|
5
|
+
* Changed: import paths only, for this flat directory.
|
|
6
|
+
*/
|
|
7
|
+
import { createContext } from "react";
|
|
8
|
+
import type { ScrollViewContextValue } from "./types";
|
|
9
|
+
|
|
10
|
+
const ScrollViewContext = createContext<ScrollViewContextValue>(null);
|
|
11
|
+
|
|
12
|
+
export default ScrollViewContext;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* COPIED FROM react-native-teleport 1.2.0 — `src/contexts/ScrollViewContext/types.ts`
|
|
3
|
+
* MIT, Copyright (c) 2025 Kiryl Ziusko. Full licence in `NOTICE` at the root.
|
|
4
|
+
*
|
|
5
|
+
* Changed: nothing — byte-for-byte, only its path.
|
|
6
|
+
*/
|
|
7
|
+
export type ScrollViewContextValue = { horizontal: boolean } | null;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* COPIED FROM react-native-teleport 1.2.0 — `src/specs/PortalHostViewNativeComponent.ts`
|
|
3
|
+
* MIT, Copyright (c) 2025 Kiryl Ziusko. Full licence in `NOTICE` at the root.
|
|
4
|
+
*
|
|
5
|
+
* Changed: nothing — byte-for-byte, only its path.
|
|
6
|
+
*/
|
|
7
|
+
import { codegenNativeComponent, type ViewProps } from "react-native";
|
|
8
|
+
|
|
9
|
+
interface NativeProps extends ViewProps {
|
|
10
|
+
name?: string;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export default codegenNativeComponent<NativeProps>("PortalHostView", {
|
|
14
|
+
interfaceOnly: true,
|
|
15
|
+
});
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* COPIED FROM react-native-teleport 1.2.0 — `src/specs/PortalViewNativeComponent.ts`
|
|
3
|
+
* MIT, Copyright (c) 2025 Kiryl Ziusko. Full licence in `NOTICE` at the root.
|
|
4
|
+
*
|
|
5
|
+
* Changed: nothing — byte-for-byte, only its path.
|
|
6
|
+
*/
|
|
7
|
+
import { codegenNativeComponent, type ViewProps } from "react-native";
|
|
8
|
+
|
|
9
|
+
interface NativeProps extends ViewProps {
|
|
10
|
+
name?: string;
|
|
11
|
+
hostName?: string;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export default codegenNativeComponent<NativeProps>("PortalView", {
|
|
15
|
+
interfaceOnly: true,
|
|
16
|
+
});
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* COPIED FROM react-native-teleport 1.2.0 — `src/global.d.ts`
|
|
3
|
+
* MIT, Copyright (c) 2025 Kiryl Ziusko. Full licence in `NOTICE` at the root.
|
|
4
|
+
*
|
|
5
|
+
* Changed: nothing — byte-for-byte, only its path. `moveBefore` is newer than
|
|
6
|
+
* TypeScript's DOM library, and this is how they declare it.
|
|
7
|
+
*/
|
|
8
|
+
// https://developer.mozilla.org/en-US/docs/Web/API/Element/moveBefore
|
|
9
|
+
interface Node {
|
|
10
|
+
moveBefore(node: Node, child: Node | null): void;
|
|
11
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* COPIED FROM react-native-teleport 1.2.0 — `src/types/index.ts`
|
|
3
|
+
* MIT, Copyright (c) 2025 Kiryl Ziusko. Full licence in `NOTICE` at the root.
|
|
4
|
+
*
|
|
5
|
+
* Changed: nothing — byte-for-byte, only its path.
|
|
6
|
+
*/
|
|
7
|
+
import type { StyleProp, ViewStyle } from "react-native";
|
|
8
|
+
|
|
9
|
+
export type PortalProviderProps = {
|
|
10
|
+
children: React.ReactNode;
|
|
11
|
+
};
|
|
12
|
+
export type PortalHostProps = {
|
|
13
|
+
name: string;
|
|
14
|
+
style?: StyleProp<ViewStyle>;
|
|
15
|
+
children?: React.ReactNode;
|
|
16
|
+
};
|
|
17
|
+
export type PortalProps = {
|
|
18
|
+
name?: string;
|
|
19
|
+
hostName?: string;
|
|
20
|
+
style?: StyleProp<ViewStyle>;
|
|
21
|
+
children?: React.ReactNode;
|
|
22
|
+
};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* COPIED FROM react-native-teleport 1.2.0 — `src/hooks/useId.ts`
|
|
3
|
+
* MIT, Copyright (c) 2025 Kiryl Ziusko. Full licence in `NOTICE` at the root.
|
|
4
|
+
*
|
|
5
|
+
* Changed: nothing — byte-for-byte, only its path.
|
|
6
|
+
*/
|
|
7
|
+
import { useRef } from "react";
|
|
8
|
+
|
|
9
|
+
let __idCounter = 0;
|
|
10
|
+
|
|
11
|
+
export default function useId(prefix = "uid"): string {
|
|
12
|
+
const idRef = useRef<string>("");
|
|
13
|
+
if (!idRef.current) {
|
|
14
|
+
const n = ++__idCounter;
|
|
15
|
+
idRef.current = `${prefix}-${n}`;
|
|
16
|
+
}
|
|
17
|
+
return idRef.current;
|
|
18
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* COPIED FROM react-native-teleport 1.2.0 — `src/hooks/usePortal.ts`
|
|
3
|
+
* MIT, Copyright (c) 2025 Kiryl Ziusko. Full licence in `NOTICE` at the root.
|
|
4
|
+
*
|
|
5
|
+
* Changed: import paths only, for this flat directory.
|
|
6
|
+
*/
|
|
7
|
+
import { usePortalManagerContext } from "./portal-manager";
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* The `usePortal` hook allows you to manage portals in imperative way.
|
|
11
|
+
*
|
|
12
|
+
* @category hooks
|
|
13
|
+
* @param `hostName` - `name` of the `<PortalHost />` component
|
|
14
|
+
* @returns an object that helps to manipulate portals
|
|
15
|
+
* @example
|
|
16
|
+
* ```tsx
|
|
17
|
+
* import { usePortal } from "react-native-teleport";
|
|
18
|
+
* export default function App() {
|
|
19
|
+
* const { removePortal, isHostAvailable } = usePortal("root");
|
|
20
|
+
* return (
|
|
21
|
+
* <View style={{ flex: 1 }}>
|
|
22
|
+
* <Text>{isHostAvailable ? "Host is available" : "Host is not available"}</Text>
|
|
23
|
+
* <Button title="Remove" onPress={() => removePortal("portal")} />
|
|
24
|
+
* </View>
|
|
25
|
+
* );
|
|
26
|
+
* }
|
|
27
|
+
* ```
|
|
28
|
+
*/
|
|
29
|
+
export default function usePortal(hostName: string = "root") {
|
|
30
|
+
const { state, dispatch } = usePortalManagerContext();
|
|
31
|
+
|
|
32
|
+
return {
|
|
33
|
+
/**
|
|
34
|
+
* Whether a `<PortalHost />` with the given `hostName` is currently mounted.
|
|
35
|
+
*/
|
|
36
|
+
isHostAvailable: (state.hosts[hostName] ?? 0) > 0,
|
|
37
|
+
/**
|
|
38
|
+
* Remove portal from host container. Subsequent re-renders will not restore portal,
|
|
39
|
+
* but if you mount a new portal with the same name it will be shown (i. e. hook doesn't
|
|
40
|
+
* prevent new portal from being added).
|
|
41
|
+
*
|
|
42
|
+
* @param name - `name` of `<Portal />` component.
|
|
43
|
+
*/
|
|
44
|
+
removePortal: (name: string) =>
|
|
45
|
+
dispatch({ type: "REMOVE_PORTAL", hostName, name }),
|
|
46
|
+
};
|
|
47
|
+
}
|