@mittwald/react-tunnel
Version:
It's like a Portal – but with React components
68 lines (67 loc) • 2.16 kB
JavaScript
"use client"
/* */
import { jsx as C } from "react/jsx-runtime";
import { useState as m, createContext as g, useContext as f, useId as E, useRef as b, useEffect as u } from "react";
import { observable as p, makeObservable as v, action as a } from "mobx";
import { observer as w } from "mobx-react-lite";
const d = "default";
class l {
children = p.map(
{},
{
deep: !1
}
);
preparedChildren = /* @__PURE__ */ new Map();
constructor() {
v(this, {
deleteChildren: a.bound,
setChildren: a.bound
});
}
static useNew() {
return m(() => new l())[0];
}
setChildren(e = d, r, n) {
const t = this.children.get(e) ?? p.map({}, { deep: !1 });
t.set(r, n), this.preparedChildren.get(e)?.delete(r), this.children.set(e, t);
}
prepareChildren(e = d, r, n) {
const t = this.preparedChildren.get(e) ?? /* @__PURE__ */ new Map();
t.set(r, n), this.preparedChildren.set(e, t);
}
deleteChildrenFromMap(e, r, n) {
const t = e.get(r);
t?.delete(n), t?.size === 0 && e.delete(r);
}
deleteChildren(e = d, r) {
this.deleteChildrenFromMap(this.children, e, r), this.deleteChildrenFromMap(this.preparedChildren, e, r);
}
getChildren(e = d) {
const r = this.children.get(e)?.entries() ?? this.preparedChildren.get(e)?.entries();
if (r)
return Array.from(r);
}
}
const h = g(new l()), N = (i) => {
const { children: e } = i;
return /* @__PURE__ */ C(h.Provider, { value: l.useNew(), children: e });
}, P = (i) => {
const { children: e, id: r, staticEntryId: n } = i, t = f(h), o = E(), s = n ?? o, c = b(!1);
return c.current || t.prepareChildren(r, s, e), u(() => {
c.current = !0, t.setChildren(r, s, e);
}, [e, r, s]), u(() => () => {
t.deleteChildren(r, s);
}, [r, s]), null;
}, x = (i) => {
const { children: e } = i;
return typeof e == "function" ? e() : e;
}, R = w((i) => {
const { children: e, id: r } = i, n = f(h).getChildren(r), t = n ? n.map(([o, s]) => /* @__PURE__ */ C(x, { children: s }, o)) : null;
return typeof e == "function" ? e(t) : t ?? e;
});
export {
P as TunnelEntry,
R as TunnelExit,
N as TunnelProvider
};