@tamagui/portal 1.0.1-rc.8 → 1.0.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/dist/cjs/GorhomPortal.js +25 -15
- package/dist/cjs/GorhomPortal.js.map +3 -3
- package/dist/esm/GorhomPortal.js +19 -15
- package/dist/esm/GorhomPortal.js.map +2 -2
- package/dist/jsx/GorhomPortal.js +13 -23
- package/dist/jsx/GorhomPortal.js.map +3 -3
- package/dist/jsx/Portal.js +2 -2
- package/dist/jsx/Portal.js.map +2 -2
- package/dist/jsx/Portal.native.js +10 -14
- package/dist/jsx/Portal.native.js.map +2 -2
- package/dist/jsx/index.js.map +1 -1
- package/package.json +7 -7
- package/src/GorhomPortal.tsx +23 -16
package/dist/cjs/GorhomPortal.js
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
2
3
|
var __defProp = Object.defineProperty;
|
|
3
4
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
5
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
5
7
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
8
|
var __export = (target, all) => {
|
|
7
9
|
for (var name in all)
|
|
@@ -15,6 +17,10 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
15
17
|
}
|
|
16
18
|
return to;
|
|
17
19
|
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
22
|
+
mod
|
|
23
|
+
));
|
|
18
24
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
25
|
var GorhomPortal_exports = {};
|
|
20
26
|
__export(GorhomPortal_exports, {
|
|
@@ -28,7 +34,7 @@ __export(GorhomPortal_exports, {
|
|
|
28
34
|
module.exports = __toCommonJS(GorhomPortal_exports);
|
|
29
35
|
var import_jsx_runtime = require("react/jsx-runtime");
|
|
30
36
|
var import_core = require("@tamagui/core");
|
|
31
|
-
var import_react = require("react");
|
|
37
|
+
var import_react = __toESM(require("react"));
|
|
32
38
|
var ACTIONS = /* @__PURE__ */ ((ACTIONS2) => {
|
|
33
39
|
ACTIONS2[ACTIONS2["REGISTER_HOST"] = 0] = "REGISTER_HOST";
|
|
34
40
|
ACTIONS2[ACTIONS2["DEREGISTER_HOST"] = 1] = "DEREGISTER_HOST";
|
|
@@ -197,20 +203,24 @@ const PortalHostComponent = (props) => {
|
|
|
197
203
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_jsx_runtime.Fragment, {
|
|
198
204
|
children: state.map((item) => {
|
|
199
205
|
let next = item.node;
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
if (
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
206
|
+
if (forwardProps) {
|
|
207
|
+
const { space, separator, spaceDirection, ...rest } = forwardProps;
|
|
208
|
+
if (Array.isArray(next)) {
|
|
209
|
+
if (Object.keys(rest).length) {
|
|
210
|
+
next = next.map(
|
|
211
|
+
(item2) => (0, import_react.isValidElement)(item2) ? (0, import_react.cloneElement)(item2, rest) : item2
|
|
212
|
+
);
|
|
213
|
+
}
|
|
214
|
+
if (space || separator) {
|
|
215
|
+
next = (0, import_core.spacedChildren)({
|
|
216
|
+
separator: forwardProps.separator,
|
|
217
|
+
children: next,
|
|
218
|
+
space: forwardProps.space,
|
|
219
|
+
direction: forwardProps.spaceDirection
|
|
220
|
+
});
|
|
221
|
+
}
|
|
222
|
+
} else {
|
|
223
|
+
next = import_react.default.isValidElement(next) ? import_react.default.cloneElement(next, { key: next.key, ...forwardProps }) : next;
|
|
214
224
|
}
|
|
215
225
|
}
|
|
216
226
|
return next;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/GorhomPortal.tsx"],
|
|
4
|
-
"sourcesContent": ["// from https://github.com/gorhom/react-native-portal\n// MIT License Copyright (c) 2020 Mo Gorhom\n// fixing SSR issue\n\nimport {\n spacedChildren,\n useDidFinishSSR,\n useEvent,\n useIsomorphicLayoutEffect,\n} from '@tamagui/core'\nimport React, {\n ReactNode,\n cloneElement,\n createContext,\n isValidElement,\n memo,\n startTransition,\n useCallback,\n useContext,\n useEffect,\n useId,\n useMemo,\n useReducer,\n useRef,\n} from 'react'\n\ninterface PortalType {\n name: string\n node: ReactNode\n}\n\nenum ACTIONS {\n REGISTER_HOST,\n DEREGISTER_HOST,\n ADD_UPDATE_PORTAL,\n REMOVE_PORTAL,\n}\n\nconst INITIAL_STATE = {}\n\nexport { ACTIONS, INITIAL_STATE }\n\nexport interface AddUpdatePortalAction {\n type: ACTIONS\n hostName: string\n portalName: string\n node: ReactNode\n}\n\nexport interface RemovePortalAction {\n type: ACTIONS\n hostName: string\n portalName: string\n}\n\nexport interface RegisterHostAction {\n type: ACTIONS\n hostName: string\n}\n\nexport interface UnregisterHostAction {\n type: ACTIONS\n hostName: string\n}\n\nexport type ActionTypes =\n | AddUpdatePortalAction\n | RemovePortalAction\n | RegisterHostAction\n | UnregisterHostAction\n\nconst registerHost = (state: Record<string, Array<PortalType>>, hostName: string) => {\n if (!(hostName in state)) {\n state[hostName] = []\n }\n return state\n}\n\nconst deregisterHost = (state: Record<string, Array<PortalType>>, hostName: string) => {\n delete state[hostName]\n return state\n}\n\nconst addUpdatePortal = (\n state: Record<string, Array<PortalType>>,\n hostName: string,\n portalName: string,\n node: any\n) => {\n if (!(hostName in state)) {\n state = registerHost(state, hostName)\n }\n\n /**\n * updated portal, if it was already added.\n */\n const index = state[hostName].findIndex((item) => item.name === portalName)\n if (index !== -1) {\n state[hostName][index].node = node\n } else {\n state[hostName].push({\n name: portalName,\n node,\n })\n }\n return state\n}\n\nconst removePortal = (\n state: Record<string, Array<PortalType>>,\n hostName: string,\n portalName: string\n) => {\n if (!(hostName in state)) {\n // eslint-disable-next-line no-console\n console.log(\n `Failed to remove portal '${portalName}', '${hostName}' was not registered!`\n )\n return state\n }\n\n const index = state[hostName].findIndex((item) => item.name === portalName)\n if (index !== -1) state[hostName].splice(index, 1)\n return state\n}\n\nconst reducer = (state: Record<string, Array<PortalType>>, action: ActionTypes) => {\n const { type } = action\n switch (type) {\n case ACTIONS.REGISTER_HOST:\n return registerHost({ ...state }, action.hostName)\n case ACTIONS.DEREGISTER_HOST:\n return deregisterHost({ ...state }, action.hostName)\n case ACTIONS.ADD_UPDATE_PORTAL:\n return addUpdatePortal(\n { ...state },\n action.hostName,\n (action as AddUpdatePortalAction).portalName,\n (action as AddUpdatePortalAction).node\n )\n case ACTIONS.REMOVE_PORTAL:\n return removePortal(\n { ...state },\n action.hostName,\n (action as RemovePortalAction).portalName\n )\n default:\n return state\n }\n}\n\nconst PortalStateContext = createContext<Record<string, Array<PortalType>> | null>(null)\nconst PortalDispatchContext = createContext<React.Dispatch<ActionTypes> | null>(null)\n\nconst usePortalState = (hostName: string) => {\n const state = useContext(PortalStateContext)\n\n if (state === null) {\n throw new Error(\n \"'PortalStateContext' cannot be null, please add 'PortalProvider' to the root component.\"\n )\n }\n\n return state[hostName] || []\n}\n\nexport const usePortal = (hostName = 'root') => {\n const dispatch = useContext(PortalDispatchContext)\n\n if (dispatch === null) {\n throw new Error(\n \"'PortalDispatchContext' cannot be null, please add 'PortalProvider' to the root component.\"\n )\n }\n\n //#region methods\n const registerHost = useCallback(() => {\n dispatch({\n type: ACTIONS.REGISTER_HOST,\n hostName: hostName,\n })\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [])\n\n const deregisterHost = useCallback(() => {\n dispatch({\n type: ACTIONS.DEREGISTER_HOST,\n hostName: hostName,\n })\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [])\n\n const addUpdatePortal = useCallback((name: string, node: ReactNode) => {\n dispatch({\n type: ACTIONS.ADD_UPDATE_PORTAL,\n hostName,\n portalName: name,\n node,\n })\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [])\n\n const removePortal = useCallback((name: string) => {\n dispatch({\n type: ACTIONS.REMOVE_PORTAL,\n hostName,\n portalName: name,\n })\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [])\n //#endregion\n\n return {\n registerHost,\n deregisterHost,\n addPortal: addUpdatePortal,\n updatePortal: addUpdatePortal,\n removePortal,\n }\n}\n\nexport interface PortalProviderProps {\n /**\n * Defines whether to add a default root host or not.\n *\n * @default true\n * @type boolean\n */\n shouldAddRootHost?: boolean\n\n /**\n * Defines the root portal host name.\n *\n * @default \"root\"\n * @type string\n */\n rootHostName?: string\n\n children: ReactNode | ReactNode[]\n}\n\nconst PortalProviderComponent = ({\n rootHostName = 'root',\n shouldAddRootHost = true,\n children,\n}: PortalProviderProps) => {\n const [state, dispatch] = useReducer(reducer, INITIAL_STATE)\n const transitionDispatch = useMemo(() => {\n const next = (value: any) => {\n startTransition(() => {\n dispatch(value)\n })\n }\n return next as typeof dispatch\n }, [dispatch])\n\n return (\n <PortalDispatchContext.Provider value={transitionDispatch}>\n <PortalStateContext.Provider value={state}>\n {children}\n {shouldAddRootHost && <PortalHost name={rootHostName} />}\n </PortalStateContext.Provider>\n </PortalDispatchContext.Provider>\n )\n}\n\nexport const PortalProvider = memo(PortalProviderComponent)\nPortalProvider.displayName = 'PortalProvider'\n\nexport interface PortalHostProps {\n /**\n * Host's key or name to be used as an identifier.\n * @type string\n */\n name: string\n\n forwardProps?: Record<string, any>\n}\n\nconst PortalHostComponent = (props: PortalHostProps) => {\n const { name, forwardProps } = props\n const isServer = !useDidFinishSSR()\n const state = usePortalState(name)\n const { registerHost, deregisterHost } = usePortal(props.name)\n\n //#region effects\n useEffect(() => {\n if (isServer) return\n registerHost()\n return () => {\n deregisterHost()\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [isServer])\n //#endregion\n\n if (forwardProps) {\n return (\n <>\n {state.map((item) => {\n let next = item.node\n const { space, separator, spaceDirection, ...rest } = forwardProps\n\n if (Array.isArray(next)) {\n // add any extra props\n if (Object.keys(rest).length) {\n next = next.map((item) =>\n isValidElement(item) ? cloneElement(item, rest) : item\n )\n }\n if (space || separator) {\n next = spacedChildren({\n separator: forwardProps.separator,\n children: next as any,\n space: forwardProps.space,\n direction: forwardProps.spaceDirection,\n })\n }\n }\n return next\n })}\n </>\n )\n }\n\n //#region render\n return <>{state.map((item) => item.node)}</>\n //#endregion\n}\n\nexport const PortalHost = memo(PortalHostComponent)\nPortalHost.displayName = 'PortalHost'\n\nexport interface PortalItemProps {\n /**\n * Portal's key or name to be used as an identifier.\n * @type string\n * @default generated unique key.\n */\n name?: string\n /**\n * Host's name to teleport the portal content to.\n * @type string\n * @default 'root'\n */\n hostName?: string\n /**\n * Override internal mounting functionality, this is useful\n * if you want to trigger any action before mounting the portal content.\n * @type (mount?: () => void) => void\n * @default undefined\n */\n handleOnMount?: (mount: () => void) => void\n /**\n * Override internal un-mounting functionality, this is useful\n * if you want to trigger any action before un-mounting the portal content.\n * @type (unmount?: () => void) => void\n * @default undefined\n */\n handleOnUnmount?: (unmount: () => void) => void\n /**\n * Override internal updating functionality, this is useful\n * if you want to trigger any action before updating the portal content.\n * @type (update?: () => void) => void\n * @default undefined\n */\n handleOnUpdate?: (update: () => void) => void\n /**\n * Portal's content.\n * @type ReactNode\n * @default undefined\n */\n children?: ReactNode | ReactNode[]\n}\n\nconst PortalComponent = (props: PortalItemProps) => {\n const {\n name: _providedName,\n hostName,\n handleOnMount: _providedHandleOnMount,\n handleOnUnmount: _providedHandleOnUnmount,\n handleOnUpdate: _providedHandleOnUpdate,\n children,\n } = props\n const { addPortal: addUpdatePortal, removePortal } = usePortal(hostName)\n const id = useId()\n const name = _providedName || id\n\n const handleOnMount = useEvent(() => {\n if (_providedHandleOnMount) {\n _providedHandleOnMount(() => addUpdatePortal(name, children))\n } else {\n addUpdatePortal(name, children)\n }\n })\n\n const handleOnUnmount = useEvent(() => {\n if (_providedHandleOnUnmount) {\n _providedHandleOnUnmount(() => removePortal(name))\n } else {\n removePortal(name)\n }\n })\n\n const handleOnUpdate = useEvent(() => {\n if (_providedHandleOnUpdate) {\n _providedHandleOnUpdate(() => addUpdatePortal(name, children))\n } else {\n addUpdatePortal(name, children)\n }\n })\n\n useIsomorphicLayoutEffect(() => {\n handleOnMount()\n return () => {\n handleOnUnmount()\n }\n }, [])\n\n useEffect(() => {\n handleOnUpdate()\n }, [children])\n\n return null\n}\n\nexport const PortalItem = memo(PortalComponent)\nPortalItem.displayName = 'Portal'\n"],
|
|
5
|
-
"mappings": "
|
|
6
|
-
"names": ["ACTIONS", "registerHost", "deregisterHost", "addUpdatePortal", "removePortal", "item"]
|
|
4
|
+
"sourcesContent": ["// from https://github.com/gorhom/react-native-portal\n// MIT License Copyright (c) 2020 Mo Gorhom\n// fixing SSR issue\n\nimport {\n spacedChildren,\n useDidFinishSSR,\n useEvent,\n useIsomorphicLayoutEffect,\n} from '@tamagui/core'\nimport React, {\n ReactNode,\n cloneElement,\n createContext,\n isValidElement,\n memo,\n startTransition,\n useCallback,\n useContext,\n useEffect,\n useId,\n useMemo,\n useReducer,\n useRef,\n} from 'react'\n\ninterface PortalType {\n name: string\n node: ReactNode\n}\n\nenum ACTIONS {\n REGISTER_HOST,\n DEREGISTER_HOST,\n ADD_UPDATE_PORTAL,\n REMOVE_PORTAL,\n}\n\nconst INITIAL_STATE = {}\n\nexport { ACTIONS, INITIAL_STATE }\n\nexport interface AddUpdatePortalAction {\n type: ACTIONS\n hostName: string\n portalName: string\n node: ReactNode\n}\n\nexport interface RemovePortalAction {\n type: ACTIONS\n hostName: string\n portalName: string\n}\n\nexport interface RegisterHostAction {\n type: ACTIONS\n hostName: string\n}\n\nexport interface UnregisterHostAction {\n type: ACTIONS\n hostName: string\n}\n\nexport type ActionTypes =\n | AddUpdatePortalAction\n | RemovePortalAction\n | RegisterHostAction\n | UnregisterHostAction\n\nconst registerHost = (state: Record<string, Array<PortalType>>, hostName: string) => {\n if (!(hostName in state)) {\n state[hostName] = []\n }\n return state\n}\n\nconst deregisterHost = (state: Record<string, Array<PortalType>>, hostName: string) => {\n delete state[hostName]\n return state\n}\n\nconst addUpdatePortal = (\n state: Record<string, Array<PortalType>>,\n hostName: string,\n portalName: string,\n node: any\n) => {\n if (!(hostName in state)) {\n state = registerHost(state, hostName)\n }\n\n /**\n * updated portal, if it was already added.\n */\n const index = state[hostName].findIndex((item) => item.name === portalName)\n if (index !== -1) {\n state[hostName][index].node = node\n } else {\n state[hostName].push({\n name: portalName,\n node,\n })\n }\n return state\n}\n\nconst removePortal = (\n state: Record<string, Array<PortalType>>,\n hostName: string,\n portalName: string\n) => {\n if (!(hostName in state)) {\n // eslint-disable-next-line no-console\n console.log(\n `Failed to remove portal '${portalName}', '${hostName}' was not registered!`\n )\n return state\n }\n\n const index = state[hostName].findIndex((item) => item.name === portalName)\n if (index !== -1) state[hostName].splice(index, 1)\n return state\n}\n\nconst reducer = (state: Record<string, Array<PortalType>>, action: ActionTypes) => {\n const { type } = action\n switch (type) {\n case ACTIONS.REGISTER_HOST:\n return registerHost({ ...state }, action.hostName)\n case ACTIONS.DEREGISTER_HOST:\n return deregisterHost({ ...state }, action.hostName)\n case ACTIONS.ADD_UPDATE_PORTAL:\n return addUpdatePortal(\n { ...state },\n action.hostName,\n (action as AddUpdatePortalAction).portalName,\n (action as AddUpdatePortalAction).node\n )\n case ACTIONS.REMOVE_PORTAL:\n return removePortal(\n { ...state },\n action.hostName,\n (action as RemovePortalAction).portalName\n )\n default:\n return state\n }\n}\n\nconst PortalStateContext = createContext<Record<string, Array<PortalType>> | null>(null)\nconst PortalDispatchContext = createContext<React.Dispatch<ActionTypes> | null>(null)\n\nconst usePortalState = (hostName: string) => {\n const state = useContext(PortalStateContext)\n\n if (state === null) {\n throw new Error(\n \"'PortalStateContext' cannot be null, please add 'PortalProvider' to the root component.\"\n )\n }\n\n return state[hostName] || []\n}\n\nexport const usePortal = (hostName = 'root') => {\n const dispatch = useContext(PortalDispatchContext)\n\n if (dispatch === null) {\n throw new Error(\n \"'PortalDispatchContext' cannot be null, please add 'PortalProvider' to the root component.\"\n )\n }\n\n //#region methods\n const registerHost = useCallback(() => {\n dispatch({\n type: ACTIONS.REGISTER_HOST,\n hostName: hostName,\n })\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [])\n\n const deregisterHost = useCallback(() => {\n dispatch({\n type: ACTIONS.DEREGISTER_HOST,\n hostName: hostName,\n })\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [])\n\n const addUpdatePortal = useCallback((name: string, node: ReactNode) => {\n dispatch({\n type: ACTIONS.ADD_UPDATE_PORTAL,\n hostName,\n portalName: name,\n node,\n })\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [])\n\n const removePortal = useCallback((name: string) => {\n dispatch({\n type: ACTIONS.REMOVE_PORTAL,\n hostName,\n portalName: name,\n })\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [])\n //#endregion\n\n return {\n registerHost,\n deregisterHost,\n addPortal: addUpdatePortal,\n updatePortal: addUpdatePortal,\n removePortal,\n }\n}\n\nexport interface PortalProviderProps {\n /**\n * Defines whether to add a default root host or not.\n *\n * @default true\n * @type boolean\n */\n shouldAddRootHost?: boolean\n\n /**\n * Defines the root portal host name.\n *\n * @default \"root\"\n * @type string\n */\n rootHostName?: string\n\n children: ReactNode | ReactNode[]\n}\n\nconst PortalProviderComponent = ({\n rootHostName = 'root',\n shouldAddRootHost = true,\n children,\n}: PortalProviderProps) => {\n const [state, dispatch] = useReducer(reducer, INITIAL_STATE)\n const transitionDispatch = useMemo(() => {\n const next = (value: any) => {\n startTransition(() => {\n dispatch(value)\n })\n }\n return next as typeof dispatch\n }, [dispatch])\n\n return (\n <PortalDispatchContext.Provider value={transitionDispatch}>\n <PortalStateContext.Provider value={state}>\n {children}\n {shouldAddRootHost && <PortalHost name={rootHostName} />}\n </PortalStateContext.Provider>\n </PortalDispatchContext.Provider>\n )\n}\n\nexport const PortalProvider = memo(PortalProviderComponent)\nPortalProvider.displayName = 'PortalProvider'\n\nexport interface PortalHostProps {\n /**\n * Host's key or name to be used as an identifier.\n * @type string\n */\n name: string\n\n forwardProps?: Record<string, any>\n}\n\nconst PortalHostComponent = (props: PortalHostProps) => {\n const { name, forwardProps } = props\n const isServer = !useDidFinishSSR()\n const state = usePortalState(name)\n const { registerHost, deregisterHost } = usePortal(props.name)\n\n //#region effects\n useEffect(() => {\n if (isServer) return\n registerHost()\n return () => {\n deregisterHost()\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [isServer])\n //#endregion\n\n if (forwardProps) {\n return (\n <>\n {state.map((item) => {\n let next = item.node\n\n if (forwardProps) {\n const { space, separator, spaceDirection, ...rest } = forwardProps\n if (Array.isArray(next)) {\n // add any extra props\n if (Object.keys(rest).length) {\n next = next.map((item) =>\n isValidElement(item) ? cloneElement(item, rest) : item\n )\n }\n if (space || separator) {\n next = spacedChildren({\n separator: forwardProps.separator,\n children: next as any,\n space: forwardProps.space,\n direction: forwardProps.spaceDirection,\n })\n }\n } else {\n next = React.isValidElement(next)\n ? React.cloneElement(next, { key: next.key, ...forwardProps })\n : next\n }\n }\n\n return next\n })}\n </>\n )\n }\n\n //#region render\n return <>{state.map((item) => item.node)}</>\n //#endregion\n}\n\nexport const PortalHost = memo(PortalHostComponent)\nPortalHost.displayName = 'PortalHost'\n\nexport interface PortalItemProps {\n /**\n * Portal's key or name to be used as an identifier.\n * @type string\n * @default generated unique key.\n */\n name?: string\n /**\n * Host's name to teleport the portal content to.\n * @type string\n * @default 'root'\n */\n hostName?: string\n /**\n * Override internal mounting functionality, this is useful\n * if you want to trigger any action before mounting the portal content.\n * @type (mount?: () => void) => void\n * @default undefined\n */\n handleOnMount?: (mount: () => void) => void\n /**\n * Override internal un-mounting functionality, this is useful\n * if you want to trigger any action before un-mounting the portal content.\n * @type (unmount?: () => void) => void\n * @default undefined\n */\n handleOnUnmount?: (unmount: () => void) => void\n /**\n * Override internal updating functionality, this is useful\n * if you want to trigger any action before updating the portal content.\n * @type (update?: () => void) => void\n * @default undefined\n */\n handleOnUpdate?: (update: () => void) => void\n /**\n * Portal's content.\n * @type ReactNode\n * @default undefined\n */\n children?: ReactNode | ReactNode[]\n}\n\nconst PortalComponent = (props: PortalItemProps) => {\n const {\n name: _providedName,\n hostName,\n handleOnMount: _providedHandleOnMount,\n handleOnUnmount: _providedHandleOnUnmount,\n handleOnUpdate: _providedHandleOnUpdate,\n children,\n } = props\n const { addPortal: addUpdatePortal, removePortal } = usePortal(hostName)\n const id = useId()\n const name = _providedName || id\n\n const handleOnMount = useEvent(() => {\n if (_providedHandleOnMount) {\n _providedHandleOnMount(() => addUpdatePortal(name, children))\n } else {\n addUpdatePortal(name, children)\n }\n })\n\n const handleOnUnmount = useEvent(() => {\n if (_providedHandleOnUnmount) {\n _providedHandleOnUnmount(() => removePortal(name))\n } else {\n removePortal(name)\n }\n })\n\n const handleOnUpdate = useEvent(() => {\n if (_providedHandleOnUpdate) {\n _providedHandleOnUpdate(() => addUpdatePortal(name, children))\n } else {\n addUpdatePortal(name, children)\n }\n })\n\n useIsomorphicLayoutEffect(() => {\n handleOnMount()\n return () => {\n handleOnUnmount()\n }\n }, [])\n\n useEffect(() => {\n handleOnUpdate()\n }, [children])\n\n return null\n}\n\nexport const PortalItem = memo(PortalComponent)\nPortalItem.displayName = 'Portal'\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["ACTIONS", "registerHost", "deregisterHost", "addUpdatePortal", "removePortal", "item", "React"]
|
|
7
7
|
}
|
package/dist/esm/GorhomPortal.js
CHANGED
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
useEvent,
|
|
6
6
|
useIsomorphicLayoutEffect
|
|
7
7
|
} from "@tamagui/core";
|
|
8
|
-
import {
|
|
8
|
+
import React, {
|
|
9
9
|
cloneElement,
|
|
10
10
|
createContext,
|
|
11
11
|
isValidElement,
|
|
@@ -186,20 +186,24 @@ const PortalHostComponent = (props) => {
|
|
|
186
186
|
return /* @__PURE__ */ jsx(Fragment, {
|
|
187
187
|
children: state.map((item) => {
|
|
188
188
|
let next = item.node;
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
if (
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
189
|
+
if (forwardProps) {
|
|
190
|
+
const { space, separator, spaceDirection, ...rest } = forwardProps;
|
|
191
|
+
if (Array.isArray(next)) {
|
|
192
|
+
if (Object.keys(rest).length) {
|
|
193
|
+
next = next.map(
|
|
194
|
+
(item2) => isValidElement(item2) ? cloneElement(item2, rest) : item2
|
|
195
|
+
);
|
|
196
|
+
}
|
|
197
|
+
if (space || separator) {
|
|
198
|
+
next = spacedChildren({
|
|
199
|
+
separator: forwardProps.separator,
|
|
200
|
+
children: next,
|
|
201
|
+
space: forwardProps.space,
|
|
202
|
+
direction: forwardProps.spaceDirection
|
|
203
|
+
});
|
|
204
|
+
}
|
|
205
|
+
} else {
|
|
206
|
+
next = React.isValidElement(next) ? React.cloneElement(next, { key: next.key, ...forwardProps }) : next;
|
|
203
207
|
}
|
|
204
208
|
}
|
|
205
209
|
return next;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/GorhomPortal.tsx"],
|
|
4
|
-
"sourcesContent": ["// from https://github.com/gorhom/react-native-portal\n// MIT License Copyright (c) 2020 Mo Gorhom\n// fixing SSR issue\n\nimport {\n spacedChildren,\n useDidFinishSSR,\n useEvent,\n useIsomorphicLayoutEffect,\n} from '@tamagui/core'\nimport React, {\n ReactNode,\n cloneElement,\n createContext,\n isValidElement,\n memo,\n startTransition,\n useCallback,\n useContext,\n useEffect,\n useId,\n useMemo,\n useReducer,\n useRef,\n} from 'react'\n\ninterface PortalType {\n name: string\n node: ReactNode\n}\n\nenum ACTIONS {\n REGISTER_HOST,\n DEREGISTER_HOST,\n ADD_UPDATE_PORTAL,\n REMOVE_PORTAL,\n}\n\nconst INITIAL_STATE = {}\n\nexport { ACTIONS, INITIAL_STATE }\n\nexport interface AddUpdatePortalAction {\n type: ACTIONS\n hostName: string\n portalName: string\n node: ReactNode\n}\n\nexport interface RemovePortalAction {\n type: ACTIONS\n hostName: string\n portalName: string\n}\n\nexport interface RegisterHostAction {\n type: ACTIONS\n hostName: string\n}\n\nexport interface UnregisterHostAction {\n type: ACTIONS\n hostName: string\n}\n\nexport type ActionTypes =\n | AddUpdatePortalAction\n | RemovePortalAction\n | RegisterHostAction\n | UnregisterHostAction\n\nconst registerHost = (state: Record<string, Array<PortalType>>, hostName: string) => {\n if (!(hostName in state)) {\n state[hostName] = []\n }\n return state\n}\n\nconst deregisterHost = (state: Record<string, Array<PortalType>>, hostName: string) => {\n delete state[hostName]\n return state\n}\n\nconst addUpdatePortal = (\n state: Record<string, Array<PortalType>>,\n hostName: string,\n portalName: string,\n node: any\n) => {\n if (!(hostName in state)) {\n state = registerHost(state, hostName)\n }\n\n /**\n * updated portal, if it was already added.\n */\n const index = state[hostName].findIndex((item) => item.name === portalName)\n if (index !== -1) {\n state[hostName][index].node = node\n } else {\n state[hostName].push({\n name: portalName,\n node,\n })\n }\n return state\n}\n\nconst removePortal = (\n state: Record<string, Array<PortalType>>,\n hostName: string,\n portalName: string\n) => {\n if (!(hostName in state)) {\n // eslint-disable-next-line no-console\n console.log(\n `Failed to remove portal '${portalName}', '${hostName}' was not registered!`\n )\n return state\n }\n\n const index = state[hostName].findIndex((item) => item.name === portalName)\n if (index !== -1) state[hostName].splice(index, 1)\n return state\n}\n\nconst reducer = (state: Record<string, Array<PortalType>>, action: ActionTypes) => {\n const { type } = action\n switch (type) {\n case ACTIONS.REGISTER_HOST:\n return registerHost({ ...state }, action.hostName)\n case ACTIONS.DEREGISTER_HOST:\n return deregisterHost({ ...state }, action.hostName)\n case ACTIONS.ADD_UPDATE_PORTAL:\n return addUpdatePortal(\n { ...state },\n action.hostName,\n (action as AddUpdatePortalAction).portalName,\n (action as AddUpdatePortalAction).node\n )\n case ACTIONS.REMOVE_PORTAL:\n return removePortal(\n { ...state },\n action.hostName,\n (action as RemovePortalAction).portalName\n )\n default:\n return state\n }\n}\n\nconst PortalStateContext = createContext<Record<string, Array<PortalType>> | null>(null)\nconst PortalDispatchContext = createContext<React.Dispatch<ActionTypes> | null>(null)\n\nconst usePortalState = (hostName: string) => {\n const state = useContext(PortalStateContext)\n\n if (state === null) {\n throw new Error(\n \"'PortalStateContext' cannot be null, please add 'PortalProvider' to the root component.\"\n )\n }\n\n return state[hostName] || []\n}\n\nexport const usePortal = (hostName = 'root') => {\n const dispatch = useContext(PortalDispatchContext)\n\n if (dispatch === null) {\n throw new Error(\n \"'PortalDispatchContext' cannot be null, please add 'PortalProvider' to the root component.\"\n )\n }\n\n //#region methods\n const registerHost = useCallback(() => {\n dispatch({\n type: ACTIONS.REGISTER_HOST,\n hostName: hostName,\n })\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [])\n\n const deregisterHost = useCallback(() => {\n dispatch({\n type: ACTIONS.DEREGISTER_HOST,\n hostName: hostName,\n })\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [])\n\n const addUpdatePortal = useCallback((name: string, node: ReactNode) => {\n dispatch({\n type: ACTIONS.ADD_UPDATE_PORTAL,\n hostName,\n portalName: name,\n node,\n })\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [])\n\n const removePortal = useCallback((name: string) => {\n dispatch({\n type: ACTIONS.REMOVE_PORTAL,\n hostName,\n portalName: name,\n })\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [])\n //#endregion\n\n return {\n registerHost,\n deregisterHost,\n addPortal: addUpdatePortal,\n updatePortal: addUpdatePortal,\n removePortal,\n }\n}\n\nexport interface PortalProviderProps {\n /**\n * Defines whether to add a default root host or not.\n *\n * @default true\n * @type boolean\n */\n shouldAddRootHost?: boolean\n\n /**\n * Defines the root portal host name.\n *\n * @default \"root\"\n * @type string\n */\n rootHostName?: string\n\n children: ReactNode | ReactNode[]\n}\n\nconst PortalProviderComponent = ({\n rootHostName = 'root',\n shouldAddRootHost = true,\n children,\n}: PortalProviderProps) => {\n const [state, dispatch] = useReducer(reducer, INITIAL_STATE)\n const transitionDispatch = useMemo(() => {\n const next = (value: any) => {\n startTransition(() => {\n dispatch(value)\n })\n }\n return next as typeof dispatch\n }, [dispatch])\n\n return (\n <PortalDispatchContext.Provider value={transitionDispatch}>\n <PortalStateContext.Provider value={state}>\n {children}\n {shouldAddRootHost && <PortalHost name={rootHostName} />}\n </PortalStateContext.Provider>\n </PortalDispatchContext.Provider>\n )\n}\n\nexport const PortalProvider = memo(PortalProviderComponent)\nPortalProvider.displayName = 'PortalProvider'\n\nexport interface PortalHostProps {\n /**\n * Host's key or name to be used as an identifier.\n * @type string\n */\n name: string\n\n forwardProps?: Record<string, any>\n}\n\nconst PortalHostComponent = (props: PortalHostProps) => {\n const { name, forwardProps } = props\n const isServer = !useDidFinishSSR()\n const state = usePortalState(name)\n const { registerHost, deregisterHost } = usePortal(props.name)\n\n //#region effects\n useEffect(() => {\n if (isServer) return\n registerHost()\n return () => {\n deregisterHost()\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [isServer])\n //#endregion\n\n if (forwardProps) {\n return (\n <>\n {state.map((item) => {\n let next = item.node\n const { space, separator, spaceDirection, ...rest } = forwardProps\n\n if (Array.isArray(next)) {\n // add any extra props\n if (Object.keys(rest).length) {\n next = next.map((item) =>\n isValidElement(item) ? cloneElement(item, rest) : item\n )\n }\n if (space || separator) {\n next = spacedChildren({\n separator: forwardProps.separator,\n children: next as any,\n space: forwardProps.space,\n direction: forwardProps.spaceDirection,\n })\n }\n }\n return next\n })}\n </>\n )\n }\n\n //#region render\n return <>{state.map((item) => item.node)}</>\n //#endregion\n}\n\nexport const PortalHost = memo(PortalHostComponent)\nPortalHost.displayName = 'PortalHost'\n\nexport interface PortalItemProps {\n /**\n * Portal's key or name to be used as an identifier.\n * @type string\n * @default generated unique key.\n */\n name?: string\n /**\n * Host's name to teleport the portal content to.\n * @type string\n * @default 'root'\n */\n hostName?: string\n /**\n * Override internal mounting functionality, this is useful\n * if you want to trigger any action before mounting the portal content.\n * @type (mount?: () => void) => void\n * @default undefined\n */\n handleOnMount?: (mount: () => void) => void\n /**\n * Override internal un-mounting functionality, this is useful\n * if you want to trigger any action before un-mounting the portal content.\n * @type (unmount?: () => void) => void\n * @default undefined\n */\n handleOnUnmount?: (unmount: () => void) => void\n /**\n * Override internal updating functionality, this is useful\n * if you want to trigger any action before updating the portal content.\n * @type (update?: () => void) => void\n * @default undefined\n */\n handleOnUpdate?: (update: () => void) => void\n /**\n * Portal's content.\n * @type ReactNode\n * @default undefined\n */\n children?: ReactNode | ReactNode[]\n}\n\nconst PortalComponent = (props: PortalItemProps) => {\n const {\n name: _providedName,\n hostName,\n handleOnMount: _providedHandleOnMount,\n handleOnUnmount: _providedHandleOnUnmount,\n handleOnUpdate: _providedHandleOnUpdate,\n children,\n } = props\n const { addPortal: addUpdatePortal, removePortal } = usePortal(hostName)\n const id = useId()\n const name = _providedName || id\n\n const handleOnMount = useEvent(() => {\n if (_providedHandleOnMount) {\n _providedHandleOnMount(() => addUpdatePortal(name, children))\n } else {\n addUpdatePortal(name, children)\n }\n })\n\n const handleOnUnmount = useEvent(() => {\n if (_providedHandleOnUnmount) {\n _providedHandleOnUnmount(() => removePortal(name))\n } else {\n removePortal(name)\n }\n })\n\n const handleOnUpdate = useEvent(() => {\n if (_providedHandleOnUpdate) {\n _providedHandleOnUpdate(() => addUpdatePortal(name, children))\n } else {\n addUpdatePortal(name, children)\n }\n })\n\n useIsomorphicLayoutEffect(() => {\n handleOnMount()\n return () => {\n handleOnUnmount()\n }\n }, [])\n\n useEffect(() => {\n handleOnUpdate()\n }, [children])\n\n return null\n}\n\nexport const PortalItem = memo(PortalComponent)\nPortalItem.displayName = 'Portal'\n"],
|
|
5
|
-
"mappings": "AAkQM,SAwCA,UAtCwB,KAFxB;AA9PN;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP;AAAA,
|
|
4
|
+
"sourcesContent": ["// from https://github.com/gorhom/react-native-portal\n// MIT License Copyright (c) 2020 Mo Gorhom\n// fixing SSR issue\n\nimport {\n spacedChildren,\n useDidFinishSSR,\n useEvent,\n useIsomorphicLayoutEffect,\n} from '@tamagui/core'\nimport React, {\n ReactNode,\n cloneElement,\n createContext,\n isValidElement,\n memo,\n startTransition,\n useCallback,\n useContext,\n useEffect,\n useId,\n useMemo,\n useReducer,\n useRef,\n} from 'react'\n\ninterface PortalType {\n name: string\n node: ReactNode\n}\n\nenum ACTIONS {\n REGISTER_HOST,\n DEREGISTER_HOST,\n ADD_UPDATE_PORTAL,\n REMOVE_PORTAL,\n}\n\nconst INITIAL_STATE = {}\n\nexport { ACTIONS, INITIAL_STATE }\n\nexport interface AddUpdatePortalAction {\n type: ACTIONS\n hostName: string\n portalName: string\n node: ReactNode\n}\n\nexport interface RemovePortalAction {\n type: ACTIONS\n hostName: string\n portalName: string\n}\n\nexport interface RegisterHostAction {\n type: ACTIONS\n hostName: string\n}\n\nexport interface UnregisterHostAction {\n type: ACTIONS\n hostName: string\n}\n\nexport type ActionTypes =\n | AddUpdatePortalAction\n | RemovePortalAction\n | RegisterHostAction\n | UnregisterHostAction\n\nconst registerHost = (state: Record<string, Array<PortalType>>, hostName: string) => {\n if (!(hostName in state)) {\n state[hostName] = []\n }\n return state\n}\n\nconst deregisterHost = (state: Record<string, Array<PortalType>>, hostName: string) => {\n delete state[hostName]\n return state\n}\n\nconst addUpdatePortal = (\n state: Record<string, Array<PortalType>>,\n hostName: string,\n portalName: string,\n node: any\n) => {\n if (!(hostName in state)) {\n state = registerHost(state, hostName)\n }\n\n /**\n * updated portal, if it was already added.\n */\n const index = state[hostName].findIndex((item) => item.name === portalName)\n if (index !== -1) {\n state[hostName][index].node = node\n } else {\n state[hostName].push({\n name: portalName,\n node,\n })\n }\n return state\n}\n\nconst removePortal = (\n state: Record<string, Array<PortalType>>,\n hostName: string,\n portalName: string\n) => {\n if (!(hostName in state)) {\n // eslint-disable-next-line no-console\n console.log(\n `Failed to remove portal '${portalName}', '${hostName}' was not registered!`\n )\n return state\n }\n\n const index = state[hostName].findIndex((item) => item.name === portalName)\n if (index !== -1) state[hostName].splice(index, 1)\n return state\n}\n\nconst reducer = (state: Record<string, Array<PortalType>>, action: ActionTypes) => {\n const { type } = action\n switch (type) {\n case ACTIONS.REGISTER_HOST:\n return registerHost({ ...state }, action.hostName)\n case ACTIONS.DEREGISTER_HOST:\n return deregisterHost({ ...state }, action.hostName)\n case ACTIONS.ADD_UPDATE_PORTAL:\n return addUpdatePortal(\n { ...state },\n action.hostName,\n (action as AddUpdatePortalAction).portalName,\n (action as AddUpdatePortalAction).node\n )\n case ACTIONS.REMOVE_PORTAL:\n return removePortal(\n { ...state },\n action.hostName,\n (action as RemovePortalAction).portalName\n )\n default:\n return state\n }\n}\n\nconst PortalStateContext = createContext<Record<string, Array<PortalType>> | null>(null)\nconst PortalDispatchContext = createContext<React.Dispatch<ActionTypes> | null>(null)\n\nconst usePortalState = (hostName: string) => {\n const state = useContext(PortalStateContext)\n\n if (state === null) {\n throw new Error(\n \"'PortalStateContext' cannot be null, please add 'PortalProvider' to the root component.\"\n )\n }\n\n return state[hostName] || []\n}\n\nexport const usePortal = (hostName = 'root') => {\n const dispatch = useContext(PortalDispatchContext)\n\n if (dispatch === null) {\n throw new Error(\n \"'PortalDispatchContext' cannot be null, please add 'PortalProvider' to the root component.\"\n )\n }\n\n //#region methods\n const registerHost = useCallback(() => {\n dispatch({\n type: ACTIONS.REGISTER_HOST,\n hostName: hostName,\n })\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [])\n\n const deregisterHost = useCallback(() => {\n dispatch({\n type: ACTIONS.DEREGISTER_HOST,\n hostName: hostName,\n })\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [])\n\n const addUpdatePortal = useCallback((name: string, node: ReactNode) => {\n dispatch({\n type: ACTIONS.ADD_UPDATE_PORTAL,\n hostName,\n portalName: name,\n node,\n })\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [])\n\n const removePortal = useCallback((name: string) => {\n dispatch({\n type: ACTIONS.REMOVE_PORTAL,\n hostName,\n portalName: name,\n })\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [])\n //#endregion\n\n return {\n registerHost,\n deregisterHost,\n addPortal: addUpdatePortal,\n updatePortal: addUpdatePortal,\n removePortal,\n }\n}\n\nexport interface PortalProviderProps {\n /**\n * Defines whether to add a default root host or not.\n *\n * @default true\n * @type boolean\n */\n shouldAddRootHost?: boolean\n\n /**\n * Defines the root portal host name.\n *\n * @default \"root\"\n * @type string\n */\n rootHostName?: string\n\n children: ReactNode | ReactNode[]\n}\n\nconst PortalProviderComponent = ({\n rootHostName = 'root',\n shouldAddRootHost = true,\n children,\n}: PortalProviderProps) => {\n const [state, dispatch] = useReducer(reducer, INITIAL_STATE)\n const transitionDispatch = useMemo(() => {\n const next = (value: any) => {\n startTransition(() => {\n dispatch(value)\n })\n }\n return next as typeof dispatch\n }, [dispatch])\n\n return (\n <PortalDispatchContext.Provider value={transitionDispatch}>\n <PortalStateContext.Provider value={state}>\n {children}\n {shouldAddRootHost && <PortalHost name={rootHostName} />}\n </PortalStateContext.Provider>\n </PortalDispatchContext.Provider>\n )\n}\n\nexport const PortalProvider = memo(PortalProviderComponent)\nPortalProvider.displayName = 'PortalProvider'\n\nexport interface PortalHostProps {\n /**\n * Host's key or name to be used as an identifier.\n * @type string\n */\n name: string\n\n forwardProps?: Record<string, any>\n}\n\nconst PortalHostComponent = (props: PortalHostProps) => {\n const { name, forwardProps } = props\n const isServer = !useDidFinishSSR()\n const state = usePortalState(name)\n const { registerHost, deregisterHost } = usePortal(props.name)\n\n //#region effects\n useEffect(() => {\n if (isServer) return\n registerHost()\n return () => {\n deregisterHost()\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [isServer])\n //#endregion\n\n if (forwardProps) {\n return (\n <>\n {state.map((item) => {\n let next = item.node\n\n if (forwardProps) {\n const { space, separator, spaceDirection, ...rest } = forwardProps\n if (Array.isArray(next)) {\n // add any extra props\n if (Object.keys(rest).length) {\n next = next.map((item) =>\n isValidElement(item) ? cloneElement(item, rest) : item\n )\n }\n if (space || separator) {\n next = spacedChildren({\n separator: forwardProps.separator,\n children: next as any,\n space: forwardProps.space,\n direction: forwardProps.spaceDirection,\n })\n }\n } else {\n next = React.isValidElement(next)\n ? React.cloneElement(next, { key: next.key, ...forwardProps })\n : next\n }\n }\n\n return next\n })}\n </>\n )\n }\n\n //#region render\n return <>{state.map((item) => item.node)}</>\n //#endregion\n}\n\nexport const PortalHost = memo(PortalHostComponent)\nPortalHost.displayName = 'PortalHost'\n\nexport interface PortalItemProps {\n /**\n * Portal's key or name to be used as an identifier.\n * @type string\n * @default generated unique key.\n */\n name?: string\n /**\n * Host's name to teleport the portal content to.\n * @type string\n * @default 'root'\n */\n hostName?: string\n /**\n * Override internal mounting functionality, this is useful\n * if you want to trigger any action before mounting the portal content.\n * @type (mount?: () => void) => void\n * @default undefined\n */\n handleOnMount?: (mount: () => void) => void\n /**\n * Override internal un-mounting functionality, this is useful\n * if you want to trigger any action before un-mounting the portal content.\n * @type (unmount?: () => void) => void\n * @default undefined\n */\n handleOnUnmount?: (unmount: () => void) => void\n /**\n * Override internal updating functionality, this is useful\n * if you want to trigger any action before updating the portal content.\n * @type (update?: () => void) => void\n * @default undefined\n */\n handleOnUpdate?: (update: () => void) => void\n /**\n * Portal's content.\n * @type ReactNode\n * @default undefined\n */\n children?: ReactNode | ReactNode[]\n}\n\nconst PortalComponent = (props: PortalItemProps) => {\n const {\n name: _providedName,\n hostName,\n handleOnMount: _providedHandleOnMount,\n handleOnUnmount: _providedHandleOnUnmount,\n handleOnUpdate: _providedHandleOnUpdate,\n children,\n } = props\n const { addPortal: addUpdatePortal, removePortal } = usePortal(hostName)\n const id = useId()\n const name = _providedName || id\n\n const handleOnMount = useEvent(() => {\n if (_providedHandleOnMount) {\n _providedHandleOnMount(() => addUpdatePortal(name, children))\n } else {\n addUpdatePortal(name, children)\n }\n })\n\n const handleOnUnmount = useEvent(() => {\n if (_providedHandleOnUnmount) {\n _providedHandleOnUnmount(() => removePortal(name))\n } else {\n removePortal(name)\n }\n })\n\n const handleOnUpdate = useEvent(() => {\n if (_providedHandleOnUpdate) {\n _providedHandleOnUpdate(() => addUpdatePortal(name, children))\n } else {\n addUpdatePortal(name, children)\n }\n })\n\n useIsomorphicLayoutEffect(() => {\n handleOnMount()\n return () => {\n handleOnUnmount()\n }\n }, [])\n\n useEffect(() => {\n handleOnUpdate()\n }, [children])\n\n return null\n}\n\nexport const PortalItem = memo(PortalComponent)\nPortalItem.displayName = 'Portal'\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["ACTIONS", "registerHost", "deregisterHost", "addUpdatePortal", "removePortal", "item"]
|
|
7
7
|
}
|
package/dist/jsx/GorhomPortal.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { startTransition, useIsSSR } from "@tamagui/core";
|
|
2
|
+
import { nanoid } from "nanoid/non-secure";
|
|
3
|
+
import { useMemo, useRef } from "react";
|
|
3
4
|
import { createContext, memo, useCallback, useContext, useEffect, useReducer } from "react";
|
|
4
5
|
var ACTIONS = /* @__PURE__ */ ((ACTIONS2) => {
|
|
5
6
|
ACTIONS2[ACTIONS2["REGISTER_HOST"] = 0] = "REGISTER_HOST";
|
|
@@ -52,12 +53,7 @@ const reducer = (state, action) => {
|
|
|
52
53
|
case 1 /* DEREGISTER_HOST */:
|
|
53
54
|
return deregisterHost({ ...state }, action.hostName);
|
|
54
55
|
case 2 /* ADD_UPDATE_PORTAL */:
|
|
55
|
-
return addUpdatePortal(
|
|
56
|
-
{ ...state },
|
|
57
|
-
action.hostName,
|
|
58
|
-
action.portalName,
|
|
59
|
-
action.node
|
|
60
|
-
);
|
|
56
|
+
return addUpdatePortal({ ...state }, action.hostName, action.portalName, action.node);
|
|
61
57
|
case 3 /* REMOVE_PORTAL */:
|
|
62
58
|
return removePortal({ ...state }, action.hostName, action.portalName);
|
|
63
59
|
default:
|
|
@@ -69,18 +65,14 @@ const PortalDispatchContext = createContext(null);
|
|
|
69
65
|
const usePortalState = (hostName) => {
|
|
70
66
|
const state = useContext(PortalStateContext);
|
|
71
67
|
if (state === null) {
|
|
72
|
-
throw new Error(
|
|
73
|
-
"'PortalStateContext' cannot be null, please add 'PortalProvider' to the root component."
|
|
74
|
-
);
|
|
68
|
+
throw new Error("'PortalStateContext' cannot be null, please add 'PortalProvider' to the root component.");
|
|
75
69
|
}
|
|
76
70
|
return state[hostName] || [];
|
|
77
71
|
};
|
|
78
72
|
const usePortal = (hostName = "root") => {
|
|
79
73
|
const dispatch = useContext(PortalDispatchContext);
|
|
80
74
|
if (dispatch === null) {
|
|
81
|
-
throw new Error(
|
|
82
|
-
"'PortalDispatchContext' cannot be null, please add 'PortalProvider' to the root component."
|
|
83
|
-
);
|
|
75
|
+
throw new Error("'PortalDispatchContext' cannot be null, please add 'PortalProvider' to the root component.");
|
|
84
76
|
}
|
|
85
77
|
const registerHost2 = useCallback(() => {
|
|
86
78
|
dispatch({
|
|
@@ -139,7 +131,7 @@ const PortalProviderComponent = ({
|
|
|
139
131
|
const PortalProvider = memo(PortalProviderComponent);
|
|
140
132
|
PortalProvider.displayName = "PortalProvider";
|
|
141
133
|
const PortalHostComponent = ({ name }) => {
|
|
142
|
-
const isServer =
|
|
134
|
+
const isServer = useIsSSR();
|
|
143
135
|
const state = usePortalState(name);
|
|
144
136
|
const { registerHost: registerHost2, deregisterHost: deregisterHost2 } = usePortal(name);
|
|
145
137
|
useEffect(() => {
|
|
@@ -163,11 +155,6 @@ const PortalComponent = ({
|
|
|
163
155
|
children
|
|
164
156
|
}) => {
|
|
165
157
|
const { addPortal: addUpdatePortal2, removePortal: removePortal2 } = usePortal(hostName);
|
|
166
|
-
let id = 0;
|
|
167
|
-
const nanoid = () => {
|
|
168
|
-
id = (id + 1) % Number.MAX_SAFE_INTEGER;
|
|
169
|
-
return `${id}`;
|
|
170
|
-
};
|
|
171
158
|
const name = useMemo(() => _providedName || nanoid(), [_providedName]);
|
|
172
159
|
const handleOnMountRef = useRef();
|
|
173
160
|
const handleOnUnmountRef = useRef();
|
|
@@ -197,16 +184,19 @@ const PortalComponent = ({
|
|
|
197
184
|
}, [_providedHandleOnUpdate, addUpdatePortal2, children]);
|
|
198
185
|
handleOnUpdateRef.current = handleOnUpdate;
|
|
199
186
|
useEffect(() => {
|
|
200
|
-
|
|
187
|
+
var _a;
|
|
188
|
+
(_a = handleOnMountRef.current) == null ? void 0 : _a.call(handleOnMountRef);
|
|
201
189
|
return () => {
|
|
202
|
-
|
|
190
|
+
var _a2;
|
|
191
|
+
(_a2 = handleOnUnmountRef.current) == null ? void 0 : _a2.call(handleOnUnmountRef);
|
|
203
192
|
handleOnMountRef.current = void 0;
|
|
204
193
|
handleOnUnmountRef.current = void 0;
|
|
205
194
|
handleOnUpdateRef.current = void 0;
|
|
206
195
|
};
|
|
207
196
|
}, []);
|
|
208
197
|
useEffect(() => {
|
|
209
|
-
|
|
198
|
+
var _a;
|
|
199
|
+
(_a = handleOnUpdateRef.current) == null ? void 0 : _a.call(handleOnUpdateRef);
|
|
210
200
|
}, [children]);
|
|
211
201
|
return null;
|
|
212
202
|
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/GorhomPortal.tsx"],
|
|
4
|
-
"sourcesContent": ["// from https://github.com/gorhom/react-native-portal\n// MIT License Copyright (c) 2020 Mo Gorhom\n// fixing SSR issue\n\nimport { useDidFinishSSR, useThemeName } from '@tamagui/core'\nimport { ReactNode, startTransition, useMemo, useRef } from 'react'\nimport React, { createContext, memo, useCallback, useContext, useEffect, useReducer } from 'react'\n\ninterface PortalType {\n name: string\n node: ReactNode\n}\n\nenum ACTIONS {\n REGISTER_HOST,\n DEREGISTER_HOST,\n ADD_UPDATE_PORTAL,\n REMOVE_PORTAL,\n}\n\nconst INITIAL_STATE = {}\n\nexport { ACTIONS, INITIAL_STATE }\n\nexport interface AddUpdatePortalAction {\n type: ACTIONS\n hostName: string\n portalName: string\n node: ReactNode\n}\n\nexport interface RemovePortalAction {\n type: ACTIONS\n hostName: string\n portalName: string\n}\n\nexport interface RegisterHostAction {\n type: ACTIONS\n hostName: string\n}\n\nexport interface UnregisterHostAction {\n type: ACTIONS\n hostName: string\n}\n\nexport type ActionTypes =\n | AddUpdatePortalAction\n | RemovePortalAction\n | RegisterHostAction\n | UnregisterHostAction\n\nconst registerHost = (state: Record<string, Array<PortalType>>, hostName: string) => {\n if (!(hostName in state)) {\n state[hostName] = []\n }\n return state\n}\n\nconst deregisterHost = (state: Record<string, Array<PortalType>>, hostName: string) => {\n delete state[hostName]\n return state\n}\n\nconst addUpdatePortal = (\n state: Record<string, Array<PortalType>>,\n hostName: string,\n portalName: string,\n node: any\n) => {\n if (!(hostName in state)) {\n state = registerHost(state, hostName)\n }\n\n /**\n * updated portal, if it was already added.\n */\n const index = state[hostName].findIndex((item) => item.name === portalName)\n if (index !== -1) {\n state[hostName][index].node = node\n } else {\n state[hostName].push({\n name: portalName,\n node,\n })\n }\n return state\n}\n\nconst removePortal = (\n state: Record<string, Array<PortalType>>,\n hostName: string,\n portalName: string\n) => {\n if (!(hostName in state)) {\n // eslint-disable-next-line no-console\n console.log(`Failed to remove portal '${portalName}', '${hostName}' was not registered!`)\n return state\n }\n\n const index = state[hostName].findIndex((item) => item.name === portalName)\n if (index !== -1) state[hostName].splice(index, 1)\n return state\n}\n\nconst reducer = (state: Record<string, Array<PortalType>>, action: ActionTypes) => {\n const { type } = action\n switch (type) {\n case ACTIONS.REGISTER_HOST:\n return registerHost({ ...state }, action.hostName)\n case ACTIONS.DEREGISTER_HOST:\n return deregisterHost({ ...state }, action.hostName)\n case ACTIONS.ADD_UPDATE_PORTAL:\n return addUpdatePortal(\n { ...state },\n action.hostName,\n (action as AddUpdatePortalAction).portalName,\n (action as AddUpdatePortalAction).node\n )\n case ACTIONS.REMOVE_PORTAL:\n return removePortal({ ...state }, action.hostName, (action as RemovePortalAction).portalName)\n default:\n return state\n }\n}\n\nconst PortalStateContext = createContext<Record<string, Array<PortalType>> | null>(null)\nconst PortalDispatchContext = createContext<React.Dispatch<ActionTypes> | null>(null)\n\nconst usePortalState = (hostName: string) => {\n const state = useContext(PortalStateContext)\n\n if (state === null) {\n throw new Error(\n \"'PortalStateContext' cannot be null, please add 'PortalProvider' to the root component.\"\n )\n }\n\n return state[hostName] || []\n}\n\nexport const usePortal = (hostName = 'root') => {\n const dispatch = useContext(PortalDispatchContext)\n\n if (dispatch === null) {\n throw new Error(\n \"'PortalDispatchContext' cannot be null, please add 'PortalProvider' to the root component.\"\n )\n }\n\n //#region methods\n const registerHost = useCallback(() => {\n dispatch({\n type: ACTIONS.REGISTER_HOST,\n hostName: hostName,\n })\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [])\n\n const deregisterHost = useCallback(() => {\n dispatch({\n type: ACTIONS.DEREGISTER_HOST,\n hostName: hostName,\n })\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [])\n\n const addUpdatePortal = useCallback((name: string, node: ReactNode) => {\n dispatch({\n type: ACTIONS.ADD_UPDATE_PORTAL,\n hostName,\n portalName: name,\n node,\n })\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [])\n\n const removePortal = useCallback((name: string) => {\n dispatch({\n type: ACTIONS.REMOVE_PORTAL,\n hostName,\n portalName: name,\n })\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [])\n //#endregion\n\n return {\n registerHost,\n deregisterHost,\n addPortal: addUpdatePortal,\n updatePortal: addUpdatePortal,\n removePortal,\n }\n}\n\nexport interface PortalProviderProps {\n /**\n * Defines whether to add a default root host or not.\n *\n * @default true\n * @type boolean\n */\n shouldAddRootHost?: boolean\n\n /**\n * Defines the root portal host name.\n *\n * @default \"root\"\n * @type string\n */\n rootHostName?: string\n\n children: ReactNode | ReactNode[]\n}\n\nconst PortalProviderComponent = ({\n rootHostName = 'root',\n shouldAddRootHost = true,\n children,\n}: PortalProviderProps) => {\n const [state, dispatch] = useReducer(reducer, INITIAL_STATE)\n const transitionDispatch = useMemo(() => {\n const next = (value: any) => {\n startTransition(() => {\n dispatch(value)\n })\n }\n return next as typeof dispatch\n }, [dispatch])\n return (\n <PortalDispatchContext.Provider value={transitionDispatch}>\n <PortalStateContext.Provider value={state}>\n {children}\n {shouldAddRootHost && <PortalHost name={rootHostName} />}\n </PortalStateContext.Provider>\n </PortalDispatchContext.Provider>\n )\n}\n\nexport const PortalProvider = memo(PortalProviderComponent)\nPortalProvider.displayName = 'PortalProvider'\n\nexport interface PortalHostProps {\n /**\n * Host's key or name to be used as an identifier.\n * @type string\n */\n name: string\n}\n\nconst PortalHostComponent = ({ name }: PortalHostProps) => {\n //#region hooks\n const isServer = !useDidFinishSSR()\n const state = usePortalState(name)\n const { registerHost, deregisterHost } = usePortal(name)\n //#endregion\n\n //#region effects\n useEffect(() => {\n if (isServer) return\n registerHost()\n return () => {\n deregisterHost()\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [isServer])\n //#endregion\n\n //#region render\n return <>{state.map((item) => item.node)}</>\n //#endregion\n}\n\nexport const PortalHost = memo(PortalHostComponent)\nPortalHost.displayName = 'PortalHost'\n\nexport interface PortalItemProps {\n /**\n * Portal's key or name to be used as an identifier.\n * @type string\n * @default nanoid generated unique key.\n */\n name?: string\n /**\n * Host's name to teleport the portal content to.\n * @type string\n * @default 'root'\n */\n hostName?: string\n /**\n * Override internal mounting functionality, this is useful\n * if you want to trigger any action before mounting the portal content.\n * @type (mount?: () => void) => void\n * @default undefined\n */\n handleOnMount?: (mount: () => void) => void\n /**\n * Override internal un-mounting functionality, this is useful\n * if you want to trigger any action before un-mounting the portal content.\n * @type (unmount?: () => void) => void\n * @default undefined\n */\n handleOnUnmount?: (unmount: () => void) => void\n /**\n * Override internal updating functionality, this is useful\n * if you want to trigger any action before updating the portal content.\n * @type (update?: () => void) => void\n * @default undefined\n */\n handleOnUpdate?: (update: () => void) => void\n /**\n * Portal's content.\n * @type ReactNode\n * @default undefined\n */\n children?: ReactNode | ReactNode[]\n}\n\nconst PortalComponent = ({\n name: _providedName,\n hostName,\n handleOnMount: _providedHandleOnMount,\n handleOnUnmount: _providedHandleOnUnmount,\n handleOnUpdate: _providedHandleOnUpdate,\n children,\n}: PortalItemProps) => {\n //#region hooks\n const { addPortal: addUpdatePortal, removePortal } = usePortal(hostName)\n //#endregion\n\n let id = 0\n const nanoid = () => {\n id = (id + 1) % Number.MAX_SAFE_INTEGER\n return `${id}`\n }\n\n //#region variables\n const name = useMemo(() => _providedName || nanoid(), [_providedName])\n //#endregion\n\n //#region refs\n const handleOnMountRef = useRef<Function>()\n const handleOnUnmountRef = useRef<Function>()\n const handleOnUpdateRef = useRef<Function>()\n //#endregion\n\n //#region callbacks\n const handleOnMount = useCallback(() => {\n if (_providedHandleOnMount) {\n _providedHandleOnMount(() => addUpdatePortal(name, children))\n } else {\n addUpdatePortal(name, children)\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [_providedHandleOnMount, addUpdatePortal])\n handleOnMountRef.current = handleOnMount\n\n const handleOnUnmount = useCallback(() => {\n if (_providedHandleOnUnmount) {\n _providedHandleOnUnmount(() => removePortal(name))\n } else {\n removePortal(name)\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [_providedHandleOnUnmount, removePortal])\n handleOnUnmountRef.current = handleOnUnmount\n\n const handleOnUpdate = useCallback(() => {\n if (_providedHandleOnUpdate) {\n _providedHandleOnUpdate(() => addUpdatePortal(name, children))\n } else {\n addUpdatePortal(name, children)\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [_providedHandleOnUpdate, addUpdatePortal, children])\n handleOnUpdateRef.current = handleOnUpdate\n //#endregion\n\n //#region effects\n useEffect(() => {\n handleOnMountRef.current?.()\n return () => {\n handleOnUnmountRef.current?.()\n\n // remove callbacks refs\n handleOnMountRef.current = undefined\n handleOnUnmountRef.current = undefined\n handleOnUpdateRef.current = undefined\n }\n }, [])\n useEffect(() => {\n handleOnUpdateRef.current?.()\n }, [children])\n //#endregion\n\n return null\n}\n\nexport const PortalItem = memo(PortalComponent)\nPortalItem.displayName = 'Portal'\n"],
|
|
5
|
-
"mappings": "AAIA
|
|
6
|
-
"names": [
|
|
4
|
+
"sourcesContent": ["// from https://github.com/gorhom/react-native-portal\n// MIT License Copyright (c) 2020 Mo Gorhom\n// fixing SSR issue\n\nimport { startTransition, useIsSSR } from '@tamagui/core'\nimport { nanoid } from 'nanoid/non-secure'\nimport { ReactNode, useMemo, useRef } from 'react'\nimport React, { createContext, memo, useCallback, useContext, useEffect, useReducer } from 'react'\n\ninterface PortalType {\n name: string\n node: ReactNode\n}\n\nenum ACTIONS {\n REGISTER_HOST,\n DEREGISTER_HOST,\n ADD_UPDATE_PORTAL,\n REMOVE_PORTAL,\n}\n\nconst INITIAL_STATE = {}\n\nexport { ACTIONS, INITIAL_STATE }\n\nexport interface AddUpdatePortalAction {\n type: ACTIONS\n hostName: string\n portalName: string\n node: ReactNode\n}\n\nexport interface RemovePortalAction {\n type: ACTIONS\n hostName: string\n portalName: string\n}\n\nexport interface RegisterHostAction {\n type: ACTIONS\n hostName: string\n}\n\nexport interface UnregisterHostAction {\n type: ACTIONS\n hostName: string\n}\n\nexport type ActionTypes =\n | AddUpdatePortalAction\n | RemovePortalAction\n | RegisterHostAction\n | UnregisterHostAction\n\nconst registerHost = (state: Record<string, Array<PortalType>>, hostName: string) => {\n if (!(hostName in state)) {\n state[hostName] = []\n }\n return state\n}\n\nconst deregisterHost = (state: Record<string, Array<PortalType>>, hostName: string) => {\n delete state[hostName]\n return state\n}\n\nconst addUpdatePortal = (\n state: Record<string, Array<PortalType>>,\n hostName: string,\n portalName: string,\n node: any\n) => {\n if (!(hostName in state)) {\n state = registerHost(state, hostName)\n }\n\n /**\n * updated portal, if it was already added.\n */\n const index = state[hostName].findIndex((item) => item.name === portalName)\n if (index !== -1) {\n state[hostName][index].node = node\n } else {\n state[hostName].push({\n name: portalName,\n node,\n })\n }\n return state\n}\n\nconst removePortal = (\n state: Record<string, Array<PortalType>>,\n hostName: string,\n portalName: string\n) => {\n if (!(hostName in state)) {\n console.log(`Failed to remove portal '${portalName}', '${hostName}' was not registered!`)\n return state\n }\n\n const index = state[hostName].findIndex((item) => item.name === portalName)\n if (index !== -1) state[hostName].splice(index, 1)\n return state\n}\n\nconst reducer = (state: Record<string, Array<PortalType>>, action: ActionTypes) => {\n const { type } = action\n switch (type) {\n case ACTIONS.REGISTER_HOST:\n return registerHost({ ...state }, action.hostName)\n case ACTIONS.DEREGISTER_HOST:\n return deregisterHost({ ...state }, action.hostName)\n case ACTIONS.ADD_UPDATE_PORTAL:\n return addUpdatePortal(\n { ...state },\n action.hostName,\n (action as AddUpdatePortalAction).portalName,\n (action as AddUpdatePortalAction).node\n )\n case ACTIONS.REMOVE_PORTAL:\n return removePortal({ ...state }, action.hostName, (action as RemovePortalAction).portalName)\n default:\n return state\n }\n}\n\nconst PortalStateContext = createContext<Record<string, Array<PortalType>> | null>(null)\nconst PortalDispatchContext = createContext<React.Dispatch<ActionTypes> | null>(null)\n\nconst usePortalState = (hostName: string) => {\n const state = useContext(PortalStateContext)\n\n if (state === null) {\n throw new Error(\n \"'PortalStateContext' cannot be null, please add 'PortalProvider' to the root component.\"\n )\n }\n\n return state[hostName] || []\n}\n\nexport const usePortal = (hostName = 'root') => {\n const dispatch = useContext(PortalDispatchContext)\n\n if (dispatch === null) {\n throw new Error(\n \"'PortalDispatchContext' cannot be null, please add 'PortalProvider' to the root component.\"\n )\n }\n\n //#region methods\n const registerHost = useCallback(() => {\n dispatch({\n type: ACTIONS.REGISTER_HOST,\n hostName: hostName,\n })\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [])\n\n const deregisterHost = useCallback(() => {\n dispatch({\n type: ACTIONS.DEREGISTER_HOST,\n hostName: hostName,\n })\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [])\n\n const addUpdatePortal = useCallback((name: string, node: ReactNode) => {\n dispatch({\n type: ACTIONS.ADD_UPDATE_PORTAL,\n hostName,\n portalName: name,\n node,\n })\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [])\n\n const removePortal = useCallback((name: string) => {\n dispatch({\n type: ACTIONS.REMOVE_PORTAL,\n hostName,\n portalName: name,\n })\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [])\n //#endregion\n\n return {\n registerHost,\n deregisterHost,\n addPortal: addUpdatePortal,\n updatePortal: addUpdatePortal,\n removePortal,\n }\n}\n\nexport interface PortalProviderProps {\n /**\n * Defines whether to add a default root host or not.\n *\n * @default true\n * @type boolean\n */\n shouldAddRootHost?: boolean\n\n /**\n * Defines the root portal host name.\n *\n * @default \"root\"\n * @type string\n */\n rootHostName?: string\n\n children: ReactNode | ReactNode[]\n}\n\nconst PortalProviderComponent = ({\n rootHostName = 'root',\n shouldAddRootHost = true,\n children,\n}: PortalProviderProps) => {\n const [state, dispatch] = useReducer(reducer, INITIAL_STATE)\n const transitionDispatch = useMemo(() => {\n const next = (value: any) => {\n startTransition(() => {\n dispatch(value)\n })\n }\n return next as typeof dispatch\n }, [dispatch])\n return (\n <PortalDispatchContext.Provider value={transitionDispatch}>\n <PortalStateContext.Provider value={state}>\n {children}\n {shouldAddRootHost && <PortalHost name={rootHostName} />}\n </PortalStateContext.Provider>\n </PortalDispatchContext.Provider>\n )\n}\n\nexport const PortalProvider = memo(PortalProviderComponent)\nPortalProvider.displayName = 'PortalProvider'\n\nexport interface PortalHostProps {\n /**\n * Host's key or name to be used as an identifier.\n * @type string\n */\n name: string\n}\n\nconst PortalHostComponent = ({ name }: PortalHostProps) => {\n //#region hooks\n const isServer = useIsSSR()\n const state = usePortalState(name)\n const { registerHost, deregisterHost } = usePortal(name)\n //#endregion\n\n //#region effects\n useEffect(() => {\n if (isServer) return\n registerHost()\n return () => {\n deregisterHost()\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [isServer])\n //#endregion\n\n //#region render\n return <>{state.map((item) => item.node)}</>\n //#endregion\n}\n\nexport const PortalHost = memo(PortalHostComponent)\nPortalHost.displayName = 'PortalHost'\n\nexport interface PortalItemProps {\n /**\n * Portal's key or name to be used as an identifier.\n * @type string\n * @default nanoid generated unique key.\n */\n name?: string\n /**\n * Host's name to teleport the portal content to.\n * @type string\n * @default 'root'\n */\n hostName?: string\n /**\n * Override internal mounting functionality, this is useful\n * if you want to trigger any action before mounting the portal content.\n * @type (mount?: () => void) => void\n * @default undefined\n */\n handleOnMount?: (mount: () => void) => void\n /**\n * Override internal un-mounting functionality, this is useful\n * if you want to trigger any action before un-mounting the portal content.\n * @type (unmount?: () => void) => void\n * @default undefined\n */\n handleOnUnmount?: (unmount: () => void) => void\n /**\n * Override internal updating functionality, this is useful\n * if you want to trigger any action before updating the portal content.\n * @type (update?: () => void) => void\n * @default undefined\n */\n handleOnUpdate?: (update: () => void) => void\n /**\n * Portal's content.\n * @type ReactNode\n * @default undefined\n */\n children?: ReactNode | ReactNode[]\n}\n\nconst PortalComponent = ({\n name: _providedName,\n hostName,\n handleOnMount: _providedHandleOnMount,\n handleOnUnmount: _providedHandleOnUnmount,\n handleOnUpdate: _providedHandleOnUpdate,\n children,\n}: PortalItemProps) => {\n //#region hooks\n const { addPortal: addUpdatePortal, removePortal } = usePortal(hostName)\n //#endregion\n\n //#region variables\n const name = useMemo(() => _providedName || nanoid(), [_providedName])\n //#endregion\n\n //#region refs\n const handleOnMountRef = useRef<Function>()\n const handleOnUnmountRef = useRef<Function>()\n const handleOnUpdateRef = useRef<Function>()\n //#endregion\n\n //#region callbacks\n const handleOnMount = useCallback(() => {\n if (_providedHandleOnMount) {\n _providedHandleOnMount(() => addUpdatePortal(name, children))\n } else {\n addUpdatePortal(name, children)\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [_providedHandleOnMount, addUpdatePortal])\n handleOnMountRef.current = handleOnMount\n\n const handleOnUnmount = useCallback(() => {\n if (_providedHandleOnUnmount) {\n _providedHandleOnUnmount(() => removePortal(name))\n } else {\n removePortal(name)\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [_providedHandleOnUnmount, removePortal])\n handleOnUnmountRef.current = handleOnUnmount\n\n const handleOnUpdate = useCallback(() => {\n if (_providedHandleOnUpdate) {\n _providedHandleOnUpdate(() => addUpdatePortal(name, children))\n } else {\n addUpdatePortal(name, children)\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [_providedHandleOnUpdate, addUpdatePortal, children])\n handleOnUpdateRef.current = handleOnUpdate\n //#endregion\n\n //#region effects\n useEffect(() => {\n handleOnMountRef.current?.()\n return () => {\n handleOnUnmountRef.current?.()\n\n // remove callbacks refs\n handleOnMountRef.current = undefined\n handleOnUnmountRef.current = undefined\n handleOnUpdateRef.current = undefined\n }\n }, [])\n useEffect(() => {\n handleOnUpdateRef.current?.()\n }, [children])\n //#endregion\n\n return null\n}\n\nexport const PortalItem = memo(PortalComponent)\nPortalItem.displayName = 'Portal'\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
7
|
}
|
package/dist/jsx/Portal.js
CHANGED
|
@@ -3,8 +3,8 @@ import { isWeb, useIsomorphicLayoutEffect } from "@tamagui/core";
|
|
|
3
3
|
import { YStack } from "@tamagui/stacks";
|
|
4
4
|
import * as React from "react";
|
|
5
5
|
import { createPortal } from "react-dom";
|
|
6
|
-
const Portal = ({ host = globalThis.document
|
|
7
|
-
const contents = <YStack
|
|
6
|
+
const Portal = ({ host = ((_a) => (_a = globalThis.document) == null ? void 0 : _a.body)(), ...props }) => {
|
|
7
|
+
const contents = <YStack pointerEvents="box-none" fullscreen position={isWeb ? "fixed" : "absolute"} maxWidth={isWeb ? "100vw" : "100%"} maxHeight={isWeb ? "100vh" : "100%"} {...props} />;
|
|
8
8
|
const [hostElement, setHostElement] = React.useState(null);
|
|
9
9
|
useIsomorphicLayoutEffect(() => {
|
|
10
10
|
setHostElement(host);
|
package/dist/jsx/Portal.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/Portal.tsx"],
|
|
4
|
-
"sourcesContent": ["/* eslint-disable react-hooks/rules-of-hooks */\nimport '@tamagui/polyfill-dev'\n\nimport { isWeb, useIsomorphicLayoutEffect } from '@tamagui/core'\nimport { YStack } from '@tamagui/stacks'\nimport * as React from 'react'\nimport { createPortal } from 'react-dom'\n\
|
|
5
|
-
"mappings": "AACA
|
|
4
|
+
"sourcesContent": ["/* eslint-disable react-hooks/rules-of-hooks */\nimport '@tamagui/polyfill-dev'\n\nimport { isWeb, useIsomorphicLayoutEffect } from '@tamagui/core'\nimport { YStack, YStackProps } from '@tamagui/stacks'\nimport * as React from 'react'\nimport { createPortal } from 'react-dom'\n\nexport type PortalProps = YStackProps & {\n host?: any // element\n}\n\nexport const Portal = ({ host = globalThis.document?.body, ...props }: PortalProps) => {\n const contents = (\n <YStack\n pointerEvents=\"box-none\"\n fullscreen\n // @ts-expect-error ok on web\n position={isWeb ? 'fixed' : 'absolute'}\n maxWidth={isWeb ? '100vw' : '100%'}\n maxHeight={isWeb ? '100vh' : '100%'}\n {...props}\n />\n )\n\n const [hostElement, setHostElement] = React.useState<any>(null)\n\n useIsomorphicLayoutEffect(() => {\n setHostElement(host)\n }, [host])\n\n if (hostElement) {\n return createPortal(contents, hostElement)\n }\n\n // ssr return null\n return null\n}\n"],
|
|
5
|
+
"mappings": "AACA;AAEA;AACA;AACA;AACA;AAMO,MAAM,SAAS,CAAC,EAAE,OAAO,0BAAW,aAAX,mBAAqB,YAAS,YAAyB;AACrF,QAAM,WACJ,CAAC,OACC,cAAc,WACd,WAEA,UAAU,QAAQ,UAAU,YAC5B,UAAU,QAAQ,UAAU,QAC5B,WAAW,QAAQ,UAAU,YACzB,OACN;AAGF,QAAM,CAAC,aAAa,kBAAkB,MAAM,SAAc,IAAI;AAE9D,4BAA0B,MAAM;AAC9B,mBAAe,IAAI;AAAA,EACrB,GAAG,CAAC,IAAI,CAAC;AAET,MAAI,aAAa;AACf,WAAO,aAAa,UAAU,WAAW;AAAA,EAC3C;AAGA,SAAO;AACT;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -1,21 +1,17 @@
|
|
|
1
1
|
import { YStack } from "@tamagui/stacks";
|
|
2
|
-
import
|
|
3
|
-
import { Platform, RootTagContext } from "react-native";
|
|
2
|
+
import { AppRegistry } from "react-native";
|
|
4
3
|
import { createPortal } from "react-native/Libraries/Renderer/shims/ReactNative";
|
|
5
|
-
|
|
4
|
+
let root = 0;
|
|
5
|
+
const og = AppRegistry.runApplication.bind(AppRegistry);
|
|
6
|
+
AppRegistry.runApplication = function(...args) {
|
|
7
|
+
var _a;
|
|
8
|
+
root = (_a = args[1]) == null ? void 0 : _a.rootTag;
|
|
9
|
+
return og(...args);
|
|
10
|
+
};
|
|
6
11
|
const Portal = (props) => {
|
|
7
|
-
const rootTag = React.useContext(RootTagContext);
|
|
8
12
|
const contents = <YStack pointerEvents="box-none" fullscreen position="absolute" maxWidth="100%" zIndex={1e5} {...props} />;
|
|
9
|
-
if (
|
|
10
|
-
return
|
|
11
|
-
}
|
|
12
|
-
if (rootTag) {
|
|
13
|
-
return createPortal(contents, rootTag);
|
|
14
|
-
}
|
|
15
|
-
if (process.env.NODE_ENV === "development") {
|
|
16
|
-
console.warn(
|
|
17
|
-
`Missing rootTag, this is a bug - you may need a different React Native version, or to avoid using "modal" on native.`
|
|
18
|
-
);
|
|
13
|
+
if (root) {
|
|
14
|
+
return createPortal(contents, root);
|
|
19
15
|
}
|
|
20
16
|
return null;
|
|
21
17
|
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/Portal.native.tsx"],
|
|
4
|
-
"sourcesContent": ["import { YStack } from '@tamagui/stacks'\nimport * as React from 'react'\
|
|
5
|
-
"mappings": "AAAA,
|
|
4
|
+
"sourcesContent": ["import { YStack, YStackProps } from '@tamagui/stacks'\nimport * as React from 'react'\nimport { AppRegistry } from 'react-native'\nimport { createPortal } from 'react-native/Libraries/Renderer/shims/ReactNative'\n\nexport type PortalProps = YStackProps\n\nlet root = 0\nconst og = AppRegistry.runApplication.bind(AppRegistry)\nAppRegistry.runApplication = function (...args) {\n root = args[1]?.rootTag\n return og(...args)\n}\n\nexport const Portal = (props: PortalProps) => {\n const contents = (\n <YStack\n pointerEvents=\"box-none\"\n fullscreen\n position=\"absolute\"\n maxWidth=\"100%\"\n zIndex={100000}\n {...props}\n />\n )\n\n if (root) {\n return createPortal(contents, root)\n }\n\n return null\n}\n"],
|
|
5
|
+
"mappings": "AAAA;AAEA;AACA;AAIA,IAAI,OAAO;AACX,MAAM,KAAK,YAAY,eAAe,KAAK,WAAW;AACtD,YAAY,iBAAiB,YAAa,MAAM;AAThD;AAUE,SAAO,WAAK,OAAL,mBAAS;AAChB,SAAO,GAAG,GAAG,IAAI;AACnB;AAEO,MAAM,SAAS,CAAC,UAAuB;AAC5C,QAAM,WACJ,CAAC,OACC,cAAc,WACd,WACA,SAAS,WACT,SAAS,OACT,QAAQ,SACJ,OACN;AAGF,MAAI,MAAM;AACR,WAAO,aAAa,UAAU,IAAI;AAAA,EACpC;AAEA,SAAO;AACT;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/dist/jsx/index.js.map
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tamagui/portal",
|
|
3
|
-
"version": "1.0.1
|
|
3
|
+
"version": "1.0.1",
|
|
4
4
|
"source": "src/index.ts",
|
|
5
5
|
"types": "./types/index.d.ts",
|
|
6
6
|
"main": "dist/cjs",
|
|
@@ -19,17 +19,17 @@
|
|
|
19
19
|
"clean:build": "tamagui-build clean:build"
|
|
20
20
|
},
|
|
21
21
|
"dependencies": {
|
|
22
|
-
"@tamagui/core": "^1.0.1
|
|
23
|
-
"@tamagui/stacks": "^1.0.1
|
|
24
|
-
"@tamagui/use-event": "^1.0.1
|
|
22
|
+
"@tamagui/core": "^1.0.1",
|
|
23
|
+
"@tamagui/stacks": "^1.0.1",
|
|
24
|
+
"@tamagui/use-event": "^1.0.1"
|
|
25
25
|
},
|
|
26
26
|
"peerDependencies": {
|
|
27
|
-
"react": "
|
|
28
|
-
"react-dom": "
|
|
27
|
+
"react": "*",
|
|
28
|
+
"react-dom": "*",
|
|
29
29
|
"react-native": "*"
|
|
30
30
|
},
|
|
31
31
|
"devDependencies": {
|
|
32
|
-
"@tamagui/build": "^1.0.1
|
|
32
|
+
"@tamagui/build": "^1.0.1",
|
|
33
33
|
"react": "^18.2.0",
|
|
34
34
|
"react-dom": "^18.2.0",
|
|
35
35
|
"react-native": "*"
|
package/src/GorhomPortal.tsx
CHANGED
|
@@ -299,24 +299,31 @@ const PortalHostComponent = (props: PortalHostProps) => {
|
|
|
299
299
|
<>
|
|
300
300
|
{state.map((item) => {
|
|
301
301
|
let next = item.node
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
302
|
+
|
|
303
|
+
if (forwardProps) {
|
|
304
|
+
const { space, separator, spaceDirection, ...rest } = forwardProps
|
|
305
|
+
if (Array.isArray(next)) {
|
|
306
|
+
// add any extra props
|
|
307
|
+
if (Object.keys(rest).length) {
|
|
308
|
+
next = next.map((item) =>
|
|
309
|
+
isValidElement(item) ? cloneElement(item, rest) : item
|
|
310
|
+
)
|
|
311
|
+
}
|
|
312
|
+
if (space || separator) {
|
|
313
|
+
next = spacedChildren({
|
|
314
|
+
separator: forwardProps.separator,
|
|
315
|
+
children: next as any,
|
|
316
|
+
space: forwardProps.space,
|
|
317
|
+
direction: forwardProps.spaceDirection,
|
|
318
|
+
})
|
|
319
|
+
}
|
|
320
|
+
} else {
|
|
321
|
+
next = React.isValidElement(next)
|
|
322
|
+
? React.cloneElement(next, { key: next.key, ...forwardProps })
|
|
323
|
+
: next
|
|
318
324
|
}
|
|
319
325
|
}
|
|
326
|
+
|
|
320
327
|
return next
|
|
321
328
|
})}
|
|
322
329
|
</>
|