UNPKG

react-resizable-panels

Version:

<img src="https://react-resizable-panels.vercel.app/og.svg" alt="react-resizable-panels logo" width="400" height="210" />

1,913 lines (1,912 loc) 47.4 kB
"use client"; import { jsx as q } from "react/jsx-runtime"; import { useState as Y, useCallback as K, useId as Je, useLayoutEffect as Ge, useEffect as Ie, useRef as k, createContext as Qe, useImperativeHandle as De, useMemo as Oe, useSyncExternalStore as et, useContext as tt } from "react"; function b(e, t = "Assertion error") { if (!e) throw Error(t); } function U({ group: e }) { const { orientation: t, panels: n } = e; return n.reduce((o, i) => (o += t === "horizontal" ? i.element.offsetWidth : i.element.offsetHeight, o), 0); } function ce(e, t) { return t.sort( e === "horizontal" ? nt : ot ); } function nt(e, t) { const n = e.element.offsetLeft - t.element.offsetLeft; return n !== 0 ? n : e.element.offsetWidth - t.element.offsetWidth; } function ot(e, t) { const n = e.element.offsetTop - t.element.offsetTop; return n !== 0 ? n : e.element.offsetHeight - t.element.offsetHeight; } function Te(e) { return e !== null && typeof e == "object" && "nodeType" in e && e.nodeType === Node.ELEMENT_NODE; } function _e(e, t) { return { x: e.x >= t.left && e.x <= t.right ? 0 : Math.min( Math.abs(e.x - t.left), Math.abs(e.x - t.right) ), y: e.y >= t.top && e.y <= t.bottom ? 0 : Math.min( Math.abs(e.y - t.top), Math.abs(e.y - t.bottom) ) }; } function it({ orientation: e, rects: t, targetRect: n }) { const o = { x: n.x + n.width / 2, y: n.y + n.height / 2 }; let i, s = Number.MAX_VALUE; for (const l of t) { const { x: r, y: a } = _e(o, l), u = e === "horizontal" ? r : a; u < s && (s = u, i = l); } return b(i, "No rect found"), i; } let oe; function rt() { return oe === void 0 && (typeof matchMedia == "function" ? oe = !!matchMedia("(pointer:coarse)").matches : oe = !1), oe; } function Ne(e) { const { element: t, orientation: n, panels: o, separators: i } = e, s = ce( n, Array.from(t.children).filter(Te).map((c) => ({ element: c })) ).map(({ element: c }) => c), l = []; let r = !1, a, u = []; for (const c of s) if (c.hasAttribute("data-panel")) { const m = o.find( (g) => g.element === c ); if (m) { if (a) { const g = a.element.getBoundingClientRect(), h = c.getBoundingClientRect(); let f; if (r) { const p = n === "horizontal" ? new DOMRect(g.right, g.top, 0, g.height) : new DOMRect( g.left, g.bottom, g.width, 0 ), d = n === "horizontal" ? new DOMRect(h.left, h.top, 0, h.height) : new DOMRect(h.left, h.top, h.width, 0); switch (u.length) { case 0: { f = [ p, d ]; break; } case 1: { const y = u[0], v = it({ orientation: n, rects: [g, h], targetRect: y.element.getBoundingClientRect() }); f = [ y, v === g ? d : p ]; break; } default: { f = u; break; } } } else u.length ? f = u : f = [ n === "horizontal" ? new DOMRect( g.right, h.top, h.left - g.right, h.height ) : new DOMRect( h.left, g.bottom, h.width, h.top - g.bottom ) ]; for (const p of f) { let d = "width" in p ? p : p.element.getBoundingClientRect(); const y = rt() ? 37 : 27; if (d.width < y) { const v = y - d.width; d = new DOMRect( d.x - v / 2, d.y, d.width + v, d.height ); } if (d.height < y) { const v = y - d.height; d = new DOMRect( d.x, d.y - v / 2, d.width, d.height + v ); } l.push({ group: e, groupSize: U({ group: e }), panels: [a, m], separator: "width" in p ? void 0 : p, rect: d }); } } r = !1, a = m, u = []; } } else if (c.hasAttribute("data-separator")) { const m = i.find( (g) => g.element === c ); m ? u.push(m) : (a = void 0, u = []); } else r = !0; return l; } function st(e, t) { const n = getComputedStyle(e), o = parseFloat(n.fontSize); return t * o; } function at(e, t) { const n = getComputedStyle(e.ownerDocument.body), o = parseFloat(n.fontSize); return t * o; } function lt(e) { return e / 100 * window.innerHeight; } function ut(e) { return e / 100 * window.innerWidth; } function ct(e) { switch (typeof e) { case "number": return [e, "px"]; case "string": { const t = parseFloat(e); return e.endsWith("%") ? [t, "%"] : e.endsWith("px") ? [t, "px"] : e.endsWith("rem") ? [t, "rem"] : e.endsWith("em") ? [t, "em"] : e.endsWith("vh") ? [t, "vh"] : e.endsWith("vw") ? [t, "vw"] : [t, "%"]; } } } function ie({ groupSize: e, panelElement: t, styleProp: n }) { let o; const [i, s] = ct(n); switch (s) { case "%": { o = i / 100 * e; break; } case "px": { o = i; break; } case "rem": { o = at(t, i); break; } case "em": { o = st(t, i); break; } case "vh": { o = lt(i); break; } case "vw": { o = ut(i); break; } } return o; } function O(e) { return parseFloat(e.toFixed(3)); } function ye(e) { const { panels: t } = e, n = U({ group: e }); return n === 0 ? t.map((o) => ({ collapsedSize: 0, collapsible: o.panelConstraints.collapsible === !0, defaultSize: void 0, minSize: 0, maxSize: 100, panelId: o.id })) : t.map((o) => { const { element: i, panelConstraints: s } = o; let l = 0; if (s.collapsedSize !== void 0) { const c = ie({ groupSize: n, panelElement: i, styleProp: s.collapsedSize }); l = O(c / n * 100); } let r; if (s.defaultSize !== void 0) { const c = ie({ groupSize: n, panelElement: i, styleProp: s.defaultSize }); r = O(c / n * 100); } let a = 0; if (s.minSize !== void 0) { const c = ie({ groupSize: n, panelElement: i, styleProp: s.minSize }); a = O(c / n * 100); } let u = 100; if (s.maxSize !== void 0) { const c = ie({ groupSize: n, panelElement: i, styleProp: s.maxSize }); u = O(c / n * 100); } return { collapsedSize: l, collapsible: s.collapsible === !0, defaultSize: r, minSize: a, maxSize: u, panelId: o.id }; }); } class ft { #e = {}; addListener(t, n) { const o = this.#e[t]; return o === void 0 ? this.#e[t] = [n] : o.includes(n) || o.push(n), () => { this.removeListener(t, n); }; } emit(t, n) { const o = this.#e[t]; if (o !== void 0) if (o.length === 1) o[0].call(null, n); else { let i = !1, s = null; const l = Array.from(o); for (let r = 0; r < l.length; r++) { const a = l[r]; try { a.call(null, n); } catch (u) { s === null && (i = !0, s = u); } } if (i) throw s; } } removeAllListeners() { this.#e = {}; } removeListener(t, n) { const o = this.#e[t]; if (o !== void 0) { const i = o.indexOf(n); i >= 0 && o.splice(i, 1); } } } function R(e, t, n = 0) { return Math.abs(O(e) - O(t)) <= n; } let D = { cursorFlags: 0, interactionState: { state: "inactive" }, mountedGroups: /* @__PURE__ */ new Map() }; const _ = new ft(); function G() { return D; } function E(e) { const t = typeof e == "function" ? e(D) : e; if (D === t) return D; const n = D; return D = { ...D, ...t }, t.cursorFlags !== void 0 && _.emit("cursorFlagsChange", D.cursorFlags), t.interactionState !== void 0 && _.emit("interactionStateChange", D.interactionState), t.mountedGroups !== void 0 && (D.mountedGroups.forEach((o, i) => { o.derivedPanelConstraints.forEach((s) => { if (s.collapsible) { const { layout: l } = n.mountedGroups.get(i) ?? {}; if (l) { const r = R( s.collapsedSize, o.layout[s.panelId] ), a = R( s.collapsedSize, l[s.panelId] ); r && !a && (i.inMemoryLastExpandedPanelSizes[s.panelId] = l[s.panelId]); } } }); }), _.emit("mountedGroupsChange", D.mountedGroups)), D; } function dt(e, t, n) { let o, i = { x: 1 / 0, y: 1 / 0 }; for (const s of t) { const l = _e(n, s.rect); switch (e) { case "horizontal": { l.x <= i.x && (o = s, i = l); break; } case "vertical": { l.y <= i.y && (o = s, i = l); break; } } } return o ? { distance: i, hitRegion: o } : void 0; } function pt(e) { return e !== null && typeof e == "object" && "nodeType" in e && e.nodeType === Node.DOCUMENT_FRAGMENT_NODE; } function ht(e, t) { if (e === t) throw new Error("Cannot compare node with itself"); const n = { a: xe(e), b: xe(t) }; let o; for (; n.a.at(-1) === n.b.at(-1); ) e = n.a.pop(), t = n.b.pop(), o = e; b( o, "Stacking order can only be calculated for elements with a common ancestor" ); const i = { a: ve(Se(n.a)), b: ve(Se(n.b)) }; if (i.a === i.b) { const s = o.childNodes, l = { a: n.a.at(-1), b: n.b.at(-1) }; let r = s.length; for (; r--; ) { const a = s[r]; if (a === l.a) return 1; if (a === l.b) return -1; } } return Math.sign(i.a - i.b); } const mt = /\b(?:position|zIndex|opacity|transform|webkitTransform|mixBlendMode|filter|webkitFilter|isolation)\b/; function gt(e) { const t = getComputedStyle(Ae(e) ?? e).display; return t === "flex" || t === "inline-flex"; } function yt(e) { const t = getComputedStyle(e); return !!(t.position === "fixed" || t.zIndex !== "auto" && (t.position !== "static" || gt(e)) || +t.opacity < 1 || "transform" in t && t.transform !== "none" || "webkitTransform" in t && t.webkitTransform !== "none" || "mixBlendMode" in t && t.mixBlendMode !== "normal" || "filter" in t && t.filter !== "none" || "webkitFilter" in t && t.webkitFilter !== "none" || "isolation" in t && t.isolation === "isolate" || mt.test(t.willChange) || t.webkitOverflowScrolling === "touch"); } function Se(e) { let t = e.length; for (; t--; ) { const n = e[t]; if (b(n, "Missing node"), yt(n)) return n; } return null; } function ve(e) { return e && Number(getComputedStyle(e).zIndex) || 0; } function xe(e) { const t = []; for (; e; ) t.push(e), e = Ae(e); return t; } function Ae(e) { const { parentNode: t } = e; return pt(t) ? t.host : t; } function St(e, t) { return e.x < t.x + t.width && e.x + e.width > t.x && e.y < t.y + t.height && e.y + e.height > t.y; } function vt({ groupElement: e, hitRegion: t, pointerEventTarget: n }) { if (!Te(n) || n.contains(e) || e.contains(n)) return !0; if (ht(n, e) > 0) { let o = n; for (; o; ) { if (o.contains(e)) return !0; if (St(o.getBoundingClientRect(), t)) return !1; o = o.parentElement; } } return !0; } function fe(e, t) { const n = []; return t.forEach((o, i) => { if (i.disabled) return; const s = Ne(i), l = dt(i.orientation, s, { x: e.clientX, y: e.clientY }); l && l.distance.x <= 0 && l.distance.y <= 0 && vt({ groupElement: i.element, hitRegion: l.hitRegion.rect, pointerEventTarget: e.target }) && n.push(l.hitRegion); }), n; } function xt(e, t) { if (e.length !== t.length) return !1; for (let n = 0; n < e.length; n++) if (e[n] != t[n]) return !1; return !0; } function Z(e, t) { return R(e, t) ? 0 : e > t ? 1 : -1; } function V({ panelConstraints: e, size: t }) { const { collapsedSize: n = 0, collapsible: o, maxSize: i = 100, minSize: s = 0 } = e; if (Z(t, s) < 0) if (o) { const l = (n + s) / 2; Z(t, l) < 0 ? t = n : t = s; } else t = s; return t = Math.min(i, t), t = O(t), t; } function J({ delta: e, initialLayout: t, panelConstraints: n, pivotIndices: o, prevLayout: i, trigger: s }) { if (R(e, 0)) return t; const l = Object.values(t), r = Object.values(i), a = [...l], [u, c] = o; b(u != null, "Invalid first pivot index"), b(c != null, "Invalid second pivot index"); let m = 0; if (s === "keyboard") { { const f = e < 0 ? c : u, p = n[f]; b( p, `Panel constraints not found for index ${f}` ); const { collapsedSize: d = 0, collapsible: y, minSize: v = 0 } = p; if (y) { const x = l[f]; if (b( x != null, `Previous layout not found for panel index ${f}` ), R(x, d)) { const S = v - x; Z(S, Math.abs(e)) > 0 && (e = e < 0 ? 0 - S : S); } } } { const f = e < 0 ? u : c, p = n[f]; b( p, `No panel constraints found for index ${f}` ); const { collapsedSize: d = 0, collapsible: y, minSize: v = 0 } = p; if (y) { const x = l[f]; if (b( x != null, `Previous layout not found for panel index ${f}` ), R(x, v)) { const S = x - d; Z(S, Math.abs(e)) > 0 && (e = e < 0 ? 0 - S : S); } } } } { const f = e < 0 ? 1 : -1; let p = e < 0 ? c : u, d = 0; for (; ; ) { const v = l[p]; b( v != null, `Previous layout not found for panel index ${p}` ); const S = V({ panelConstraints: n[p], size: 100 }) - v; if (d += S, p += f, p < 0 || p >= n.length) break; } const y = Math.min(Math.abs(e), Math.abs(d)); e = e < 0 ? 0 - y : y; } { let p = e < 0 ? u : c; for (; p >= 0 && p < n.length; ) { const d = Math.abs(e) - Math.abs(m), y = l[p]; b( y != null, `Previous layout not found for panel index ${p}` ); const v = y - d, x = V({ panelConstraints: n[p], size: v }); if (!R(y, x) && (m += y - x, a[p] = x, m.toFixed(3).localeCompare(Math.abs(e).toFixed(3), void 0, { numeric: !0 }) >= 0)) break; e < 0 ? p-- : p++; } } if (xt(r, a)) return i; { const f = e < 0 ? c : u, p = l[f]; b( p != null, `Previous layout not found for panel index ${f}` ); const d = p + m, y = V({ panelConstraints: n[f], size: d }); if (a[f] = y, !R(y, d)) { let v = d - y, S = e < 0 ? c : u; for (; S >= 0 && S < n.length; ) { const C = a[S]; b( C != null, `Previous layout not found for panel index ${S}` ); const L = C + v, P = V({ panelConstraints: n[S], size: L }); if (R(C, P) || (v -= P - C, a[S] = P), R(v, 0)) break; e > 0 ? S-- : S++; } } } const g = Object.values(a).reduce( (f, p) => p + f, 0 ); if (!R(g, 100, 0.1)) return i; const h = Object.keys(i); return a.reduce((f, p, d) => (f[h[d]] = p, f), {}); } function N(e, t) { if (Object.keys(e).length !== Object.keys(t).length) return !1; for (const n in e) if (t[n] === void 0 || Z(e[n], t[n]) !== 0) return !1; return !0; } function A({ layout: e, panelConstraints: t }) { const o = [...Object.values(e)], i = o.reduce( (r, a) => r + a, 0 ); if (o.length !== t.length) throw Error( `Invalid ${t.length} panel layout: ${o.map((r) => `${r}%`).join(", ")}` ); if (!R(i, 100) && o.length > 0) for (let r = 0; r < t.length; r++) { const a = o[r]; b(a != null, `No layout data found for index ${r}`); const u = 100 / i * a; o[r] = u; } let s = 0; for (let r = 0; r < t.length; r++) { const a = o[r]; b(a != null, `No layout data found for index ${r}`); const u = V({ panelConstraints: t[r], size: a }); a != u && (s += a - u, o[r] = u); } if (!R(s, 0)) for (let r = 0; r < t.length; r++) { const a = o[r]; b(a != null, `No layout data found for index ${r}`); const u = a + s, c = V({ panelConstraints: t[r], size: u }); if (a !== c && (s -= c - a, o[r] = c, R(s, 0))) break; } const l = Object.keys(e); return o.reduce((r, a, u) => (r[l[u]] = a, r), {}); } function Fe({ groupId: e, panelId: t }) { const n = () => { const { mountedGroups: r } = G(); for (const [ a, { defaultLayoutDeferred: u, derivedPanelConstraints: c, layout: m, separatorToPanels: g } ] of r) if (a.id === e) return { defaultLayoutDeferred: u, derivedPanelConstraints: c, group: a, layout: m, separatorToPanels: g }; throw Error(`Group ${e} not found`); }, o = () => { const r = n().derivedPanelConstraints.find( (a) => a.panelId === t ); if (r !== void 0) return r; throw Error(`Panel constraints not found for Panel ${t}`); }, i = () => { const r = n().group.panels.find((a) => a.id === t); if (r !== void 0) return r; throw Error(`Layout not found for Panel ${t}`); }, s = () => { const r = n().layout[t]; if (r !== void 0) return r; throw Error(`Layout not found for Panel ${t}`); }, l = (r) => { const a = s(); if (r === a) return; const { defaultLayoutDeferred: u, derivedPanelConstraints: c, group: m, layout: g, separatorToPanels: h } = n(), f = m.panels.findIndex((v) => v.id === t), p = f === m.panels.length - 1, d = J({ delta: p ? a - r : r - a, initialLayout: g, panelConstraints: c, pivotIndices: p ? [f - 1, f] : [f, f + 1], prevLayout: g, trigger: "imperative-api" }), y = A({ layout: d, panelConstraints: c }); N(g, y) || E((v) => ({ mountedGroups: new Map(v.mountedGroups).set(m, { defaultLayoutDeferred: u, derivedPanelConstraints: c, layout: y, separatorToPanels: h }) })); }; return { collapse: () => { const { collapsible: r, collapsedSize: a } = o(), { mutableValues: u } = i(), c = s(); r && c !== a && (u.expandToSize = c, l(a)); }, expand: () => { const { collapsible: r, collapsedSize: a, minSize: u } = o(), { mutableValues: c } = i(), m = s(); if (r && m === a) { let g = c.expandToSize ?? u; g === 0 && (g = 1), l(g); } }, getSize: () => { const { group: r } = n(), a = s(), { element: u } = i(), c = r.orientation === "horizontal" ? u.offsetWidth : u.offsetHeight; return { asPercentage: a, inPixels: c }; }, isCollapsed: () => { const { collapsible: r, collapsedSize: a } = o(), u = s(); return r && R(a, u); }, resize: (r) => { if (s() !== r) { let u; switch (typeof r) { case "number": { const { group: c } = n(), m = U({ group: c }); u = O(r / m * 100); break; } case "string": { u = parseFloat(r); break; } } l(u); } } }; } function ze(e) { if (e.defaultPrevented) return; const { mountedGroups: t } = G(), n = fe(e, t), o = /* @__PURE__ */ new Set(), i = /* @__PURE__ */ new Set(); n.forEach((s) => { if (o.add(s.group), s.panels.forEach((l) => { i.add(l); }), s.separator) { const l = s.panels.find( (r) => r.panelConstraints.defaultSize !== void 0 ); if (l) { const r = l.panelConstraints.defaultSize, a = Fe({ groupId: s.group.id, panelId: l.id }); a && r !== void 0 && (a.resize(r), e.preventDefault()); } } }); } function re(e) { const { mountedGroups: t } = G(); for (const [n] of t) if (n.separators.some( (o) => o.element === e )) return n; throw Error("Could not find parent Group for separator element"); } function $e({ groupId: e }) { const t = () => { const { mountedGroups: n } = G(); for (const [o, i] of n) if (o.id === e) return { group: o, ...i }; throw Error(`Could not find Group with id "${e}"`); }; return { getLayout() { const { defaultLayoutDeferred: n, layout: o } = t(); return n ? {} : o; }, setLayout(n) { const { defaultLayoutDeferred: o, derivedPanelConstraints: i, group: s, layout: l, separatorToPanels: r } = t(), a = A({ layout: n, panelConstraints: i }); return o ? l : (N(l, a) || E((u) => ({ mountedGroups: new Map(u.mountedGroups).set(s, { defaultLayoutDeferred: o, derivedPanelConstraints: i, layout: a, separatorToPanels: r }) })), a); } }; } function He(e) { const { mountedGroups: t } = G(), n = t.get(e); return b(n, `Mounted Group ${e.id} not found`), n; } function T(e, t) { const n = re(e), o = He(n), i = n.separators.find( (m) => m.element === e ); b(i, "Matching separator not found"); const s = o.separatorToPanels.get(i); b(s, "Matching panels not found"); const l = s.map((m) => n.panels.indexOf(m)), a = $e({ groupId: n.id }).getLayout(), u = J({ delta: t, initialLayout: a, panelConstraints: o.derivedPanelConstraints, pivotIndices: l, prevLayout: a, trigger: "keyboard" }), c = A({ layout: u, panelConstraints: o.derivedPanelConstraints }); N(a, c) || E((m) => ({ mountedGroups: new Map(m.mountedGroups).set(n, { defaultLayoutDeferred: o.defaultLayoutDeferred, derivedPanelConstraints: o.derivedPanelConstraints, layout: c, separatorToPanels: o.separatorToPanels }) })); } function be(e) { if (e.defaultPrevented) return; const t = e.currentTarget, n = re(t); if (!n.disabled) switch (e.key) { case "ArrowDown": { e.preventDefault(), n.orientation === "vertical" && T(t, 5); break; } case "ArrowLeft": { e.preventDefault(), n.orientation === "horizontal" && T(t, -5); break; } case "ArrowRight": { e.preventDefault(), n.orientation === "horizontal" && T(t, 5); break; } case "ArrowUp": { e.preventDefault(), n.orientation === "vertical" && T(t, -5); break; } case "End": { e.preventDefault(), T(t, 100); break; } case "Enter": { e.preventDefault(); const o = re(t), { derivedPanelConstraints: i, layout: s, separatorToPanels: l } = He(o), r = o.separators.find( (m) => m.element === t ); b(r, "Matching separator not found"); const a = l.get(r); b(a, "Matching panels not found"); const u = a[0], c = i.find( (m) => m.panelId === u.id ); if (b(c, "Panel metadata not found"), c.collapsible) { const m = s[u.id], g = c.collapsedSize === m ? o.inMemoryLastExpandedPanelSizes[u.id] ?? c.minSize : c.collapsedSize; T(t, g - m); } break; } case "F6": { e.preventDefault(); const i = re(t).separators.map( (a) => a.element ), s = Array.from(i).findIndex( (a) => a === e.currentTarget ); b(s !== null, "Index not found"); const l = e.shiftKey ? s > 0 ? s - 1 : i.length - 1 : s + 1 < i.length ? s + 1 : 0; i[l].focus(); break; } case "Home": { e.preventDefault(), T(t, -100); break; } } } function we(e) { if (e.defaultPrevented) return; if (e.pointerType === "mouse" && e.button > 0) return; const { mountedGroups: t } = G(), n = fe(e, t), o = /* @__PURE__ */ new Set(), i = /* @__PURE__ */ new Set(), s = /* @__PURE__ */ new Set(), l = /* @__PURE__ */ new Map(); let r = !1; n.forEach((a) => { o.add(a.group), a.panels.forEach((c) => { i.add(c); }), a.separator && (s.add(a.separator), r || (r = !0, a.separator.element.focus())); const u = t.get(a.group); u && l.set(a.group, u.layout); }), E({ interactionState: { hitRegions: n, initialLayoutMap: l, pointerDownAtPoint: { x: e.clientX, y: e.clientY }, state: "active" } }), n.length && e.preventDefault(); } const zt = (e) => e, le = () => { }, je = 1, Ve = 2, Ue = 4, We = 8, Le = 3, Ce = 12; function bt({ cursorFlags: e, groups: t, state: n }) { let o = 0, i = 0; switch (n) { case "active": case "hover": t.forEach((s) => { if (!s.disableCursor) switch (s.orientation) { case "horizontal": { o++; break; } case "vertical": { i++; break; } } }); } if (o === 0 && i === 0) return null; switch (n) { case "active": { const s = (e & je) !== 0, l = (e & Ve) !== 0, r = (e & Ue) !== 0, a = (e & We) !== 0; if (e) { if (s) return r ? "se-resize" : a ? "ne-resize" : "e-resize"; if (l) return r ? "sw-resize" : a ? "nw-resize" : "w-resize"; if (r) return "s-resize"; if (a) return "n-resize"; } break; } } return o > 0 && i > 0 ? "move" : o > 0 ? "ew-resize" : "ns-resize"; } const Pe = /* @__PURE__ */ new WeakMap(); function de(e) { if (e.defaultView === null || e.defaultView === void 0) return; let { prevStyle: t, styleSheet: n } = Pe.get(e) ?? {}; n === void 0 && (n = new e.defaultView.CSSStyleSheet(), e.adoptedStyleSheets.push(n)); const { cursorFlags: o, interactionState: i } = G(); switch (i.state) { case "active": case "hover": { const s = bt({ cursorFlags: o, groups: i.hitRegions.map((r) => r.group), state: i.state }), l = `*{cursor: ${s} !important; ${i.state === "active" ? "touch-action: none;" : ""} }`; if (t === l) return; t = l, s ? n.cssRules.length === 0 ? n.insertRule(l) : n.replaceSync(l) : n.cssRules.length === 1 && n.deleteRule(0); break; } case "inactive": { t = void 0, n.cssRules.length === 1 && n.deleteRule(0); break; } } Pe.set(e, { prevStyle: t, styleSheet: n }); } function Be({ document: e, event: t, hitRegions: n, initialLayoutMap: o, mountedGroups: i, pointerDownAtPoint: s, prevCursorFlags: l }) { let r = 0; const a = new Map(i); n.forEach((c) => { const { group: m, groupSize: g } = c, { disableCursor: h, orientation: f, panels: p } = m; let d = 0; s ? f === "horizontal" ? d = (t.clientX - s.x) / g * 100 : d = (t.clientY - s.y) / g * 100 : f === "horizontal" ? d = t.clientX < 0 ? -100 : 100 : d = t.clientY < 0 ? -100 : 100; const y = o.get(m), { defaultLayoutDeferred: v, derivedPanelConstraints: x, layout: S, separatorToPanels: C } = i.get(m) ?? { defaultLayoutDeferred: !1 }; if (x && y && S && C) { const L = J({ delta: d, initialLayout: y, panelConstraints: x, pivotIndices: c.panels.map((P) => p.indexOf(P)), prevLayout: S, trigger: "mouse-or-touch" }); if (N(L, S)) { if (d !== 0 && !h) switch (f) { case "horizontal": { r |= d < 0 ? je : Ve; break; } case "vertical": { r |= d < 0 ? Ue : We; break; } } } else { a.set(c.group, { defaultLayoutDeferred: v, derivedPanelConstraints: x, layout: L, separatorToPanels: C }); const P = c.group.panels.map(({ id: I }) => I).join(","); c.group.inMemoryLayouts[P] = L; } } }); let u = 0; t.movementX === 0 ? u |= l & Le : u |= r & Le, t.movementY === 0 ? u |= l & Ce : u |= r & Ce, E({ cursorFlags: u, mountedGroups: a }), de(e); } function Re(e) { const { cursorFlags: t, interactionState: n, mountedGroups: o } = G(); switch (n.state) { case "active": Be({ document: e.currentTarget, event: e, hitRegions: n.hitRegions, initialLayoutMap: n.initialLayoutMap, mountedGroups: o, prevCursorFlags: t }); } } function Me(e) { if (e.defaultPrevented) return; const { cursorFlags: t, interactionState: n, mountedGroups: o } = G(); switch (n.state) { case "active": { if ( // Skip this check for "pointerleave" events, else Firefox triggers a false positive (see #514) e.buttons === 0 ) { E( (i) => i.interactionState.state === "inactive" ? i : { cursorFlags: 0, interactionState: { state: "inactive" } } ), E((i) => ({ mountedGroups: new Map(i.mountedGroups) })); return; } Be({ document: e.currentTarget, event: e, hitRegions: n.hitRegions, initialLayoutMap: n.initialLayoutMap, mountedGroups: o, pointerDownAtPoint: n.pointerDownAtPoint, prevCursorFlags: t }); break; } default: { const i = fe(e, o); i.length === 0 ? n.state !== "inactive" && E({ interactionState: { state: "inactive" } }) : E({ interactionState: { hitRegions: i, state: "hover" } }), de(e.currentTarget); break; } } } function Ee(e) { if (e.defaultPrevented) return; if (e.pointerType === "mouse" && e.button > 0) return; const { interactionState: t } = G(); switch (t.state) { case "active": E({ cursorFlags: 0, interactionState: { state: "inactive" } }), t.hitRegions.length > 0 && (de(e.currentTarget), E((n) => ({ mountedGroups: new Map(n.mountedGroups) })), e.preventDefault()); } } function ke(e) { let t = 0, n = 0; const o = {}; for (const s of e) if (s.defaultSize !== void 0) { t++; const l = O(s.defaultSize); n += l, o[s.panelId] = l; } else o[s.panelId] = void 0; const i = e.length - t; if (i !== 0) { const s = O((100 - n) / i); for (const l of e) l.defaultSize === void 0 && (o[l.panelId] = s); } return o; } function wt(e, t, n) { if (!n[0]) return; const i = e.panels.find((u) => u.element === t); if (!i || !i.onResize) return; const s = U({ group: e }), l = e.orientation === "horizontal" ? i.element.offsetWidth : i.element.offsetHeight, r = i.mutableValues.prevSize, a = { asPercentage: O(l / s * 100), inPixels: l }; i.mutableValues.prevSize = a, i.onResize(a, i.id, r); } function Lt(e, t) { if (Object.keys(e).length !== Object.keys(t).length) return !1; for (const o in e) if (e[o] !== t[o]) return !1; return !0; } function Ct(e, t) { const n = e.map((i) => i.id), o = Object.keys(t); if (n.length !== o.length) return !1; for (const i of n) if (!o.includes(i)) return !1; return !0; } const j = /* @__PURE__ */ new Map(); function Pt(e) { let t = !0; b( e.element.ownerDocument.defaultView, "Cannot register an unmounted Group" ); const n = e.element.ownerDocument.defaultView.ResizeObserver, o = /* @__PURE__ */ new Set(), i = /* @__PURE__ */ new Set(), s = new n((f) => { for (const p of f) { const { borderBoxSize: d, target: y } = p; if (y === e.element) { if (t) { if (U({ group: e }) === 0) return; E((x) => { const S = x.mountedGroups.get(e); if (S) { const C = ye(e), L = S.defaultLayoutDeferred ? ke(C) : S.layout, P = A({ layout: L, panelConstraints: C }); return !S.defaultLayoutDeferred && N(L, P) && Lt( S.derivedPanelConstraints, C ) ? x : { mountedGroups: new Map(x.mountedGroups).set(e, { defaultLayoutDeferred: !1, derivedPanelConstraints: C, layout: P, separatorToPanels: S.separatorToPanels }) }; } return x; }); } } else wt(e, y, d); } }); s.observe(e.element), e.panels.forEach((f) => { b( !o.has(f.id), `Panel ids must be unique; id "${f.id}" was used more than once` ), o.add(f.id), f.onResize && s.observe(f.element); }); const l = U({ group: e }), r = ye(e), a = e.panels.map(({ id: f }) => f).join(","); let u = e.defaultLayout; u && (Ct(e.panels, u) || (u = void 0)); const c = e.inMemoryLayouts[a] ?? u ?? ke(r), m = A({ layout: c, panelConstraints: r }), g = Ne(e), h = e.element.ownerDocument; return E((f) => { const p = /* @__PURE__ */ new Map(); return j.set( h, (j.get(h) ?? 0) + 1 ), g.forEach((d) => { d.separator && p.set(d.separator, d.panels); }), { mountedGroups: new Map(f.mountedGroups).set(e, { defaultLayoutDeferred: l === 0, derivedPanelConstraints: r, layout: m, separatorToPanels: p }) }; }), e.separators.forEach((f) => { b( !i.has(f.id), `Separator ids must be unique; id "${f.id}" was used more than once` ), i.add(f.id), f.element.addEventListener("keydown", be); }), j.get(h) === 1 && (h.addEventListener("dblclick", ze, !0), h.addEventListener("pointerdown", we, !0), h.addEventListener("pointerleave", Re), h.addEventListener("pointermove", Me), h.addEventListener("pointerup", Ee, !0)), function() { t = !1, j.set( h, Math.max(0, (j.get(h) ?? 0) - 1) ), E((p) => { const d = new Map(p.mountedGroups); return d.delete(e), { mountedGroups: d }; }), e.separators.forEach((p) => { p.element.removeEventListener("keydown", be); }), j.get(h) || (h.removeEventListener( "dblclick", ze, !0 ), h.removeEventListener( "pointerdown", we, !0 ), h.removeEventListener("pointerleave", Re), h.removeEventListener("pointermove", Me), h.removeEventListener("pointerup", Ee, !0)), s.disconnect(); }; } function Ke() { const [e, t] = Y({}), n = K(() => t({}), []); return [e, n]; } function pe(e) { const t = Je(); return `${e ?? t}`; } const F = typeof window < "u" ? Ge : Ie; function X(e) { const t = k(e); return F(() => { t.current = e; }, [e]), K( (...n) => t.current?.(...n), [t] ); } function he(...e) { return X((t) => { e.forEach((n) => { if (n) switch (typeof n) { case "function": { n(t); break; } case "object": { n.current = t; break; } } }); }); } function Rt(e) { const t = k({ ...e }); return F(() => { for (const n in e) t.current[n] = e[n]; }, [e]), t.current; } const Xe = Qe(null); function Mt(e, t) { const n = k({ getLayout: () => ({}), setLayout: zt }); De(t, () => n.current, []), F(() => { Object.assign( n.current, $e({ groupId: e }) ); }); } function Et({ children: e, className: t, defaultLayout: n, disableCursor: o, disabled: i, elementRef: s, groupRef: l, id: r, onLayoutChange: a, onLayoutChanged: u, orientation: c = "horizontal", style: m, ...g }) { const h = k({ onLayoutChange: {}, onLayoutChanged: {} }), f = X((z) => { N(h.current.onLayoutChange, z) || (h.current.onLayoutChange = z, a?.(z)); }), p = X((z) => { N(h.current.onLayoutChanged, z) || (h.current.onLayoutChanged = z, u?.(z)); }), d = pe(r), y = k(null), [v, x] = Ke(), S = k({ lastExpandedPanelSizes: {}, layouts: {}, panels: [], separators: [] }), C = he(y, s); Mt(d, l); const L = X( (z, w) => { const { interactionState: M, mountedGroups: H } = G(); for (const Q of H.keys()) if (Q.id === z) { const W = H.get(Q); if (W) { let ee = !1; switch (M.state) { case "active": { ee = M.hitRegions.some( (se) => se.group === Q ); break; } } return { flexGrow: W.layout[w] ?? 1, pointerEvents: ee ? "none" : void 0 }; } } return { flexGrow: n?.[w] ?? 1 }; } ), P = Oe( () => ({ getPanelStyles: L, id: d, orientation: c, registerPanel: (z) => { const w = S.current; return w.panels = ce(c, [ ...w.panels, z ]), x(), () => { w.panels = w.panels.filter( (M) => M !== z ), x(); }; }, registerSeparator: (z) => { const w = S.current; return w.separators = ce(c, [ ...w.separators, z ]), x(), () => { w.separators = w.separators.filter( (M) => M !== z ), x(); }; } }), [L, d, x, c] ), I = Rt({ defaultLayout: n, disableCursor: o }), $ = k(null); return F(() => { const z = y.current; if (z === null) return; const w = S.current, M = { defaultLayout: I.defaultLayout, disableCursor: !!I.disableCursor, disabled: !!i, element: z, id: d, inMemoryLastExpandedPanelSizes: S.current.lastExpandedPanelSizes, inMemoryLayouts: S.current.layouts, orientation: c, panels: w.panels, separators: w.separators }; $.current = M; const H = Pt(M), W = G().mountedGroups.get(M); if (W) { const { defaultLayoutDeferred: B, derivedPanelConstraints: te, layout: ne } = W; !B && te.length > 0 && (f(ne), p(ne), w.panels.forEach((ae) => { ae.scheduleUpdate(); })); } const ee = _.addListener( "interactionStateChange", () => { w.panels.forEach((B) => { B.scheduleUpdate(); }); } ), se = _.addListener( "mountedGroupsChange", (B) => { const te = B.get(M); if (te) { const { defaultLayoutDeferred: ne, derivedPanelConstraints: ae, layout: ge } = te; if (ne || ae.length === 0) return; const { interactionState: qe } = G(), Ye = qe.state !== "active"; f(ge), Ye && p(ge), w.panels.forEach((Ze) => { Ze.scheduleUpdate(); }); } } ); return () => { $.current = null, H(), ee(), se(); }; }, [ i, d, p, f, c, v, I ]), Ie(() => { const z = $.current; z && (z.defaultLayout = n, z.disableCursor = !!o); }), /* @__PURE__ */ q(Xe.Provider, { value: P, children: /* @__PURE__ */ q( "div", { ...g, "aria-orientation": c, className: t, "data-group": !0, "data-testid": d, id: d, ref: C, style: { height: "100%", width: "100%", overflow: "hidden", ...m, display: "flex", flexDirection: c === "horizontal" ? "row" : "column", flexWrap: "nowrap" }, children: e } ) }); } Et.displayName = "Group"; function ue(e, t) { return `react-resizable-panels:${[e, ...t].join(":")}`; } function At({ debounceSaveMs: e = 100, panelIds: t, storage: n = localStorage, ...o }) { const i = t !== void 0, s = "id" in o ? o.id : o.groupId, l = ue(s, t ?? []), r = et( kt, () => n.getItem(l), () => n.getItem(l) ), a = Oe( () => r ? JSON.parse(r) : void 0, [r] ), u = k(null), c = K(() => { const h = u.current; h && (u.current = null, clearTimeout(h)); }, []); Ge(() => () => { c(); }, [c]); const m = K( (h) => { c(); let f; i ? f = ue(s, Object.keys(h)) : f = ue(s, []); try { n.setItem(f, JSON.stringify(h)); } catch (p) { console.error(p); } }, [c, i, s, n] ), g = K( (h) => { c(), e === 0 ? m(h) : u.current = setTimeout(() => { m(h); }, e); }, [c, e, m] ); return { /** * Pass this value to `Group` as the `defaultLayout` prop. */ defaultLayout: a, /** * Attach this callback on the `Group` as the `onLayoutChange` prop. * * @deprecated Use the {@link onLayoutChanged} prop instead. */ onLayoutChange: g, /** * Attach this callback on the `Group` as the `onLayoutChanged` prop. */ onLayoutChanged: m }; } function kt() { return function() { }; } function Ft() { return Y(null); } function $t() { return k(null); } function me() { const e = tt(Xe); return b( e, "Group Context not found; did you render a Panel or Separator outside of a Group?" ), e; } function Gt(e, t) { const { id: n } = me(), o = k({ collapse: le, expand: le, getSize: () => ({ asPercentage: 0, inPixels: 0 }), isCollapsed: () => !1, resize: le }); De(t, () => o.current, []), F(() => { Object.assign( o.current, Fe({ groupId: n, panelId: e }) ); }); } function It({ children: e, className: t, collapsedSize: n = "0%", collapsible: o = !1, defaultSize: i, elementRef: s, id: l, maxSize: r = "100%", minSize: a = "0%", onResize: u, panelRef: c, style: m, ...g }) { const h = !!l, f = pe(l), p = k(null), d = he(p, s), [, y] = Ke(), { getPanelStyles: v, id: x, registerPanel: S } = me(), C = u !== null, L = X( (I, $, z) => { u?.(I, l, z); } ); F(() => { const I = p.current; if (I !== null) return S({ element: I, id: f, idIsStable: h, mutableValues: { expandToSize: void 0, prevSize: void 0 }, onResize: C ? L : void 0, panelConstraints: { collapsedSize: n, collapsible: o, defaultSize: i, maxSize: r, minSize: a }, scheduleUpdate: y }); }, [ n, o, i, y, C, f, h, r, a, L, S ]), Gt(f, c); const P = v(x, f); return /* @__PURE__ */ q( "div", { ...g, "data-panel": !0, "data-testid": f, id: f, ref: d, style: { ...Dt, display: "flex", flexBasis: 0, flexShrink: 1, // Prevent Panel content from interfering with panel size overflow: "hidden", ...P }, children: /* @__PURE__ */ q( "div", { className: t, style: { flexGrow: 1, ...m }, children: e } ) } ); } It.displayName = "Panel"; const Dt = { minHeight: 0, maxHeight: "100%", height: "auto", minWidth: 0, maxWidth: "100%", width: "auto", border: "none", borderWidth: 0, padding: 0, margin: 0 }; function Ht() { return Y(null); } function jt() { return k(null); } function Ot({ layout: e, panelConstraints: t, panelId: n, panelIndex: o }) { let i, s; const l = e[n], r = t.find( (a) => a.panelId === n ); if (r) { const a = r.maxSize, u = s = r.collapsible ? r.collapsedSize : r.minSize, c = [o, o + 1]; s = A({ layout: J({ delta: u - l, initialLayout: e, panelConstraints: t, pivotIndices: c, prevLayout: e, trigger: "keyboard" }), panelConstraints: t })[n], i = A({ layout: J({ delta: a - l, initialLayout: e, panelConstraints: t, pivotIndices: c, prevLayout: e, trigger: "keyboard" }), panelConstraints: t })[n]; } return { valueControls: n, valueMax: i, valueMin: s, valueNow: l }; } function Tt({ children: e, className: t, elementRef: n, id: o, style: i, ...s }) { const l = pe(o), [r, a] = Y({}), [u, c] = Y("inactive"), m = k(null), g = he(m, n), { id: h, orientation: f, registerSeparator: p } = me(), d = f === "horizontal" ? "vertical" : "horizontal"; return F(() => { const y = m.current; if (y !== null) { const v = { element: y, id: l }, x = p(v), S = _.addListener( "interactionStateChange", (L) => { c( L.state !== "inactive" && L.hitRegions.some( (P) => P.separator === v ) ? L.state : "inactive" ); } ), C = _.addListener( "mountedGroupsChange", (L) => { L.forEach( ({ derivedPanelConstraints: P, layout: I, separatorToPanels: $ }, z) => { if (z.id === h) { const w = $.get(v); if (w) { const M = w[0], H = z.panels.indexOf(M); a( Ot({ layout: I, panelConstraints: P, panelId: M.id, panelIndex: H }) ); } } } ); } ); return () => { S(), C(), x(); }; } }, [h, l, p]), /* @__PURE__ */ q( "div", { ...s, "aria-controls": r.valueControls, "aria-orientation": d, "aria-valuemax": r.valueMax, "aria-valuemin": r.valueMin, "aria-valuenow": r.valueNow, children: e, className: t, "data-separator": u, "data-testid": l, id: l, ref: g, role: "separator", style: { flexBasis: "auto", ...i, flexGrow: 0, flexShrink: 0 }, tabIndex: 0 } ); } Tt.displayName = "Separator"; export { Et as Group, It as Panel, Tt as Separator, rt as isCoarsePointer, At as useDefaultLayout, Ft as useGroupCallbackRef, $t as useGroupRef, Ht as usePanelCallbackRef, jt as usePanelRef }; //# sourceMappingURL=react-resizable-panels.js.map