@coinmeca/ui
Version:
This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app).
68 lines • 2.57 kB
JavaScript
"use client";
import { useEffect, useState } from "react";
import { createPortal } from "react-dom";
import { createRoot } from "react-dom/client";
export default function usePortal(initial, initialProps) {
const [root, setRoot] = useState(undefined);
const [active, setActive] = useState(false);
const [children, setChildren] = useState(null);
const [props, setProps] = useState((state) => {
return { ...(state || {}), ...(initial?.props || {}), ...(initialProps || {}) };
});
useEffect(() => {
const p = document.createElement("section");
const r = createRoot(p);
document.body.appendChild(p);
setRoot(r);
return () => {
setActive(false);
setChildren(null);
setRoot(undefined);
setTimeout(() => {
if (p.parentNode)
p.parentNode.removeChild(p);
if (r)
r.unmount();
}, 0);
};
}, []);
useEffect(() => {
const element = children || initial;
if (root) {
root.render(active ? createPortal(typeof element === "function" ? element(props) : element, document.body) : null);
}
}, [active, initial, children, props, root]);
return [
(...args) => {
if (args) {
const props = args?.length === 2 && typeof args[1] === "object" && !args[1]?.$$typeof
? args[1]
: args?.length === 1 && typeof args[0] === "object" && !args[0]?.$$typeof
? args[0]
: undefined;
props &&
setProps((state) => {
return { ...state, ...props, active: true };
});
const children = (args?.length === 2 && typeof args[1] === "function") ||
(typeof args[1] === "object" && args[1]?.$$typeof
? args[1]
: typeof args[0] === "function" || (typeof args[0] === "object" && args[0]?.$$typeof)
? args[0]
: undefined);
children && setChildren(children);
setActive(true);
}
},
() => {
setProps((state) => {
return { ...state, active: false };
});
setActive(false);
},
() => {
setProps(({ active }) => ({ active }));
},
];
}
//# sourceMappingURL=usePortal.js.map