react-resizable-panels 3.0.6-alpha.0 → 4.0.0-alpha.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (34) hide show
  1. package/LICENSE.md +21 -0
  2. package/README.md +253 -250
  3. package/dist/react-resizable-panels.cjs +2 -0
  4. package/dist/react-resizable-panels.cjs.map +1 -0
  5. package/dist/react-resizable-panels.d.ts +316 -2
  6. package/dist/react-resizable-panels.js +1050 -2371
  7. package/dist/react-resizable-panels.js.map +1 -0
  8. package/package.json +94 -66
  9. package/dist/declarations/src/Panel.d.ts +0 -70
  10. package/dist/declarations/src/PanelGroup.d.ts +0 -38
  11. package/dist/declarations/src/PanelResizeHandle.d.ts +0 -23
  12. package/dist/declarations/src/PanelResizeHandleRegistry.d.ts +0 -19
  13. package/dist/declarations/src/constants.d.ts +0 -15
  14. package/dist/declarations/src/hooks/usePanelGroupContext.d.ts +0 -4
  15. package/dist/declarations/src/index.d.ts +0 -23
  16. package/dist/declarations/src/types.d.ts +0 -3
  17. package/dist/declarations/src/utils/assert.d.ts +0 -1
  18. package/dist/declarations/src/utils/csp.d.ts +0 -2
  19. package/dist/declarations/src/utils/cursor.d.ts +0 -18
  20. package/dist/declarations/src/utils/dom/getPanelElement.d.ts +0 -1
  21. package/dist/declarations/src/utils/dom/getPanelElementsForGroup.d.ts +0 -1
  22. package/dist/declarations/src/utils/dom/getPanelGroupElement.d.ts +0 -1
  23. package/dist/declarations/src/utils/dom/getResizeHandleElement.d.ts +0 -1
  24. package/dist/declarations/src/utils/dom/getResizeHandleElementIndex.d.ts +0 -1
  25. package/dist/declarations/src/utils/dom/getResizeHandleElementsForGroup.d.ts +0 -1
  26. package/dist/declarations/src/utils/dom/getResizeHandlePanelIds.d.ts +0 -2
  27. package/dist/declarations/src/utils/rects/getIntersectingRectangle.d.ts +0 -2
  28. package/dist/declarations/src/utils/rects/intersects.d.ts +0 -2
  29. package/dist/declarations/src/utils/rects/types.d.ts +0 -6
  30. package/dist/react-resizable-panels.browser.development.js +0 -2592
  31. package/dist/react-resizable-panels.browser.js +0 -2486
  32. package/dist/react-resizable-panels.development.edge-light.js +0 -2365
  33. package/dist/react-resizable-panels.development.js +0 -2599
  34. package/dist/react-resizable-panels.edge-light.js +0 -2264
@@ -1,2488 +1,1167 @@
1
- import * as React from 'react';
2
- import { createContext, useLayoutEffect, useRef, forwardRef, createElement, useContext, useImperativeHandle, useState, useCallback, useEffect, useMemo } from 'react';
3
-
4
- const isBrowser = typeof window !== "undefined";
5
-
6
- // The "contextmenu" event is not supported as a PointerEvent in all browsers yet, so MouseEvent still need to be handled
7
-
8
- const PanelGroupContext = createContext(null);
9
- PanelGroupContext.displayName = "PanelGroupContext";
10
-
11
- const DATA_ATTRIBUTES = {
12
- group: "data-panel-group",
13
- groupDirection: "data-panel-group-direction",
14
- groupId: "data-panel-group-id",
15
- panel: "data-panel",
16
- panelCollapsible: "data-panel-collapsible",
17
- panelId: "data-panel-id",
18
- panelSize: "data-panel-size",
19
- resizeHandle: "data-resize-handle",
20
- resizeHandleActive: "data-resize-handle-active",
21
- resizeHandleEnabled: "data-panel-resize-handle-enabled",
22
- resizeHandleId: "data-panel-resize-handle-id",
23
- resizeHandleState: "data-resize-handle-state"
24
- };
25
- const PRECISION = 10;
26
-
27
- const useIsomorphicLayoutEffect = isBrowser ? useLayoutEffect : () => {};
28
-
29
- const useId = React["useId".toString()];
30
- const wrappedUseId = typeof useId === "function" ? useId : () => null;
31
- let counter = 0;
32
- function useUniqueId(idFromParams = null) {
33
- const idFromUseId = wrappedUseId();
34
- const idRef = useRef(idFromParams || idFromUseId || null);
35
- if (idRef.current === null) {
36
- idRef.current = "" + counter++;
1
+ "use client";
2
+ import { jsx as F } from "react/jsx-runtime";
3
+ import { useId as Re, useLayoutEffect as Pe, useEffect as Ce, useRef as I, useCallback as ce, createContext as Ee, useImperativeHandle as ue, useState as M, useMemo as Me, useContext as Ge } from "react";
4
+ function Ie(e, t) {
5
+ const n = getComputedStyle(e), o = parseFloat(n.fontSize);
6
+ return t * o;
7
+ }
8
+ function Oe(e, t) {
9
+ const n = getComputedStyle(e.ownerDocument.body), o = parseFloat(n.fontSize);
10
+ return t * o;
11
+ }
12
+ function ke(e) {
13
+ return e / 100 * window.innerHeight;
14
+ }
15
+ function Ae(e) {
16
+ return e / 100 * window.innerWidth;
17
+ }
18
+ function Ne(e) {
19
+ switch (typeof e) {
20
+ case "number":
21
+ return [e, "px"];
22
+ case "string": {
23
+ const t = parseFloat(e);
24
+ 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, "%"];
25
+ }
37
26
  }
38
- return idFromParams !== null && idFromParams !== void 0 ? idFromParams : idRef.current;
39
27
  }
40
-
41
- function PanelWithForwardedRef({
42
- children,
43
- className: classNameFromProps = "",
44
- collapsedSize,
45
- collapsible,
46
- defaultSize,
47
- forwardedRef,
48
- id: idFromProps,
49
- maxSize,
50
- minSize,
51
- onCollapse,
52
- onExpand,
53
- onResize,
54
- order,
55
- style: styleFromProps,
56
- tagName: Type = "div",
57
- ...rest
28
+ function H({
29
+ groupSize: e,
30
+ panelElement: t,
31
+ styleProp: n
58
32
  }) {
59
- const context = useContext(PanelGroupContext);
60
- if (context === null) {
61
- throw Error(`Panel components must be rendered within a PanelGroup container`);
62
- }
63
- const {
64
- collapsePanel,
65
- expandPanel,
66
- getPanelSize,
67
- getPanelStyle,
68
- groupId,
69
- isPanelCollapsed,
70
- reevaluatePanelConstraints,
71
- registerPanel,
72
- resizePanel,
73
- unregisterPanel
74
- } = context;
75
- const panelId = useUniqueId(idFromProps);
76
- const panelDataRef = useRef({
77
- callbacks: {
78
- onCollapse,
79
- onExpand,
80
- onResize
81
- },
82
- constraints: {
83
- collapsedSize,
84
- collapsible,
85
- defaultSize,
86
- maxSize,
87
- minSize
88
- },
89
- id: panelId,
90
- idIsFromProps: idFromProps !== undefined,
91
- order
92
- });
93
- useRef({
94
- didLogMissingDefaultSizeWarning: false
95
- });
96
- useIsomorphicLayoutEffect(() => {
97
- const {
98
- callbacks,
99
- constraints
100
- } = panelDataRef.current;
101
- const prevConstraints = {
102
- ...constraints
103
- };
104
- panelDataRef.current.id = panelId;
105
- panelDataRef.current.idIsFromProps = idFromProps !== undefined;
106
- panelDataRef.current.order = order;
107
- callbacks.onCollapse = onCollapse;
108
- callbacks.onExpand = onExpand;
109
- callbacks.onResize = onResize;
110
- constraints.collapsedSize = collapsedSize;
111
- constraints.collapsible = collapsible;
112
- constraints.defaultSize = defaultSize;
113
- constraints.maxSize = maxSize;
114
- constraints.minSize = minSize;
115
-
116
- // If constraints have changed, we should revisit panel sizes.
117
- // This is uncommon but may happen if people are trying to implement pixel based constraints.
118
- if (prevConstraints.collapsedSize !== constraints.collapsedSize || prevConstraints.collapsible !== constraints.collapsible || prevConstraints.maxSize !== constraints.maxSize || prevConstraints.minSize !== constraints.minSize) {
119
- reevaluatePanelConstraints(panelDataRef.current, prevConstraints);
33
+ let o;
34
+ const [s, i] = Ne(n);
35
+ switch (i) {
36
+ case "%": {
37
+ o = s / 100 * e;
38
+ break;
120
39
  }
121
- });
122
- useIsomorphicLayoutEffect(() => {
123
- const panelData = panelDataRef.current;
124
- registerPanel(panelData);
125
- return () => {
126
- unregisterPanel(panelData);
127
- };
128
- }, [order, panelId, registerPanel, unregisterPanel]);
129
- useImperativeHandle(forwardedRef, () => ({
130
- collapse: () => {
131
- collapsePanel(panelDataRef.current);
132
- },
133
- expand: minSize => {
134
- expandPanel(panelDataRef.current, minSize);
135
- },
136
- getId() {
137
- return panelId;
138
- },
139
- getSize() {
140
- return getPanelSize(panelDataRef.current);
141
- },
142
- isCollapsed() {
143
- return isPanelCollapsed(panelDataRef.current);
144
- },
145
- isExpanded() {
146
- return !isPanelCollapsed(panelDataRef.current);
147
- },
148
- resize: size => {
149
- resizePanel(panelDataRef.current, size);
40
+ case "px": {
41
+ o = s;
42
+ break;
150
43
  }
151
- }), [collapsePanel, expandPanel, getPanelSize, isPanelCollapsed, panelId, resizePanel]);
152
- const style = getPanelStyle(panelDataRef.current, defaultSize);
153
- return createElement(Type, {
154
- ...rest,
155
- children,
156
- className: classNameFromProps,
157
- id: panelId,
158
- style: {
159
- ...style,
160
- ...styleFromProps
161
- },
162
- // CSS selectors
163
- [DATA_ATTRIBUTES.groupId]: groupId,
164
- [DATA_ATTRIBUTES.panel]: "",
165
- [DATA_ATTRIBUTES.panelCollapsible]: collapsible || undefined,
166
- [DATA_ATTRIBUTES.panelId]: panelId,
167
- [DATA_ATTRIBUTES.panelSize]: parseFloat("" + style.flexGrow).toFixed(1)
168
- });
169
- }
170
- const Panel = forwardRef((props, ref) => createElement(PanelWithForwardedRef, {
171
- ...props,
172
- forwardedRef: ref
173
- }));
174
- PanelWithForwardedRef.displayName = "Panel";
175
- Panel.displayName = "forwardRef(Panel)";
176
-
177
- let nonce;
178
- function getNonce() {
179
- return nonce;
180
- }
181
- function setNonce(value) {
182
- nonce = value;
183
- }
184
-
185
- let currentCursorStyle = null;
186
- let enabled = true;
187
- let getCustomCursorStyleFunction = null;
188
- let prevRuleIndex = -1;
189
- let styleElement = null;
190
- function customizeGlobalCursorStyles(callback) {
191
- getCustomCursorStyleFunction = callback;
192
- }
193
- function disableGlobalCursorStyles() {
194
- enabled = false;
195
- }
196
- function enableGlobalCursorStyles() {
197
- enabled = true;
198
- }
199
- function getCursorStyle(state, constraintFlags, isPointerDown) {
200
- const horizontalMin = (constraintFlags & EXCEEDED_HORIZONTAL_MIN) !== 0;
201
- const horizontalMax = (constraintFlags & EXCEEDED_HORIZONTAL_MAX) !== 0;
202
- const verticalMin = (constraintFlags & EXCEEDED_VERTICAL_MIN) !== 0;
203
- const verticalMax = (constraintFlags & EXCEEDED_VERTICAL_MAX) !== 0;
204
- if (getCustomCursorStyleFunction) {
205
- return getCustomCursorStyleFunction({
206
- exceedsHorizontalMaximum: horizontalMax,
207
- exceedsHorizontalMinimum: horizontalMin,
208
- exceedsVerticalMaximum: verticalMax,
209
- exceedsVerticalMinimum: verticalMin,
210
- intersectsHorizontalDragHandle: state === "horizontal" || state === "intersection",
211
- intersectsVerticalDragHandle: state === "vertical" || state === "intersection",
212
- isPointerDown
213
- });
214
- }
215
- if (constraintFlags) {
216
- if (horizontalMin) {
217
- if (verticalMin) {
218
- return "se-resize";
219
- } else if (verticalMax) {
220
- return "ne-resize";
221
- } else {
222
- return "e-resize";
223
- }
224
- } else if (horizontalMax) {
225
- if (verticalMin) {
226
- return "sw-resize";
227
- } else if (verticalMax) {
228
- return "nw-resize";
229
- } else {
230
- return "w-resize";
231
- }
232
- } else if (verticalMin) {
233
- return "s-resize";
234
- } else if (verticalMax) {
235
- return "n-resize";
44
+ case "rem": {
45
+ o = Oe(t, s);
46
+ break;
236
47
  }
237
- }
238
- switch (state) {
239
- case "horizontal":
240
- return "ew-resize";
241
- case "intersection":
242
- return "move";
243
- case "vertical":
244
- return "ns-resize";
245
- }
246
- }
247
- function resetGlobalCursorStyle() {
248
- if (styleElement !== null) {
249
- document.head.removeChild(styleElement);
250
- currentCursorStyle = null;
251
- styleElement = null;
252
- prevRuleIndex = -1;
253
- }
254
- }
255
- function setGlobalCursorStyle(state, constraintFlags, isPointerDown) {
256
- var _styleElement$sheet$i, _styleElement$sheet2;
257
- if (!enabled) {
258
- return;
259
- }
260
- const style = getCursorStyle(state, constraintFlags, isPointerDown);
261
- if (currentCursorStyle === style) {
262
- return;
263
- }
264
- currentCursorStyle = style;
265
- if (styleElement === null) {
266
- styleElement = document.createElement("style");
267
- const nonce = getNonce();
268
- if (nonce) {
269
- styleElement.setAttribute("nonce", nonce);
48
+ case "em": {
49
+ o = Ie(t, s);
50
+ break;
51
+ }
52
+ case "vh": {
53
+ o = ke(s);
54
+ break;
55
+ }
56
+ case "vw": {
57
+ o = Ae(s);
58
+ break;
270
59
  }
271
- document.head.appendChild(styleElement);
272
- }
273
- if (prevRuleIndex >= 0) {
274
- var _styleElement$sheet;
275
- (_styleElement$sheet = styleElement.sheet) === null || _styleElement$sheet === void 0 ? void 0 : _styleElement$sheet.removeRule(prevRuleIndex);
276
60
  }
277
- prevRuleIndex = (_styleElement$sheet$i = (_styleElement$sheet2 = styleElement.sheet) === null || _styleElement$sheet2 === void 0 ? void 0 : _styleElement$sheet2.insertRule(`*{cursor: ${style} !important;}`)) !== null && _styleElement$sheet$i !== void 0 ? _styleElement$sheet$i : -1;
61
+ return o;
278
62
  }
279
-
280
- function isKeyDown(event) {
281
- return event.type === "keydown";
63
+ function L(e) {
64
+ return parseFloat(e.toFixed(3));
282
65
  }
283
- function isPointerEvent(event) {
284
- return event.type.startsWith("pointer");
285
- }
286
- function isMouseEvent(event) {
287
- return event.type.startsWith("mouse");
288
- }
289
-
290
- function getResizeEventCoordinates(event) {
291
- if (isPointerEvent(event)) {
292
- if (event.isPrimary) {
293
- return {
294
- x: event.clientX,
295
- y: event.clientY
296
- };
66
+ function Z({
67
+ group: e
68
+ }) {
69
+ const { direction: t, panels: n } = e;
70
+ return n.reduce((o, s) => (o += t === "horizontal" ? s.element.offsetWidth : s.element.offsetHeight, o), 0);
71
+ }
72
+ function ie(e) {
73
+ const { panels: t } = e, n = Z({ group: e });
74
+ return t.map((o) => {
75
+ const { element: s, panelConstraints: i } = o;
76
+ let a = 0;
77
+ if (i.collapsedSize) {
78
+ const u = H({
79
+ groupSize: n,
80
+ panelElement: s,
81
+ styleProp: i.collapsedSize
82
+ });
83
+ a = L(u / n * 100);
84
+ }
85
+ let r;
86
+ if (i.defaultSize) {
87
+ const u = H({
88
+ groupSize: n,
89
+ panelElement: s,
90
+ styleProp: i.defaultSize
91
+ });
92
+ r = L(u / n * 100);
93
+ }
94
+ let l = 0;
95
+ if (i.minSize) {
96
+ const u = H({
97
+ groupSize: n,
98
+ panelElement: s,
99
+ styleProp: i.minSize
100
+ });
101
+ l = L(u / n * 100);
102
+ }
103
+ let c = 100;
104
+ if (i.maxSize) {
105
+ const u = H({
106
+ groupSize: n,
107
+ panelElement: s,
108
+ styleProp: i.maxSize
109
+ });
110
+ c = L(u / n * 100);
297
111
  }
298
- } else if (isMouseEvent(event)) {
299
112
  return {
300
- x: event.clientX,
301
- y: event.clientY
113
+ collapsedSize: a,
114
+ collapsible: i.collapsible === !0,
115
+ defaultSize: r,
116
+ minSize: l,
117
+ maxSize: c,
118
+ panelId: o.id
302
119
  };
303
- }
304
- return {
305
- x: Infinity,
306
- y: Infinity
307
- };
120
+ });
308
121
  }
309
-
310
- function getInputType() {
311
- if (typeof matchMedia === "function") {
312
- return matchMedia("(pointer:coarse)").matches ? "coarse" : "fine";
122
+ class $e {
123
+ #e = {};
124
+ addListener(t, n) {
125
+ const o = this.#e[t];
126
+ return o === void 0 ? this.#e[t] = [n] : o.includes(n) || o.push(n), () => {
127
+ this.removeListener(t, n);
128
+ };
313
129
  }
314
- }
315
-
316
- function intersects(rectOne, rectTwo, strict) {
317
- if (strict) {
318
- return rectOne.x < rectTwo.x + rectTwo.width && rectOne.x + rectOne.width > rectTwo.x && rectOne.y < rectTwo.y + rectTwo.height && rectOne.y + rectOne.height > rectTwo.y;
319
- } else {
320
- return rectOne.x <= rectTwo.x + rectTwo.width && rectOne.x + rectOne.width >= rectTwo.x && rectOne.y <= rectTwo.y + rectTwo.height && rectOne.y + rectOne.height >= rectTwo.y;
130
+ emit(t, n) {
131
+ const o = this.#e[t];
132
+ if (o !== void 0)
133
+ if (o.length === 1)
134
+ o[0].call(null, n);
135
+ else {
136
+ let s = !1, i = null;
137
+ const a = Array.from(o);
138
+ for (let r = 0; r < a.length; r++) {
139
+ const l = a[r];
140
+ try {
141
+ l.call(null, n);
142
+ } catch (c) {
143
+ i === null && (s = !0, i = c);
144
+ }
145
+ }
146
+ if (s)
147
+ throw i;
148
+ }
321
149
  }
322
- }
323
-
324
- // Forked from NPM stacking-order@2.0.0
325
-
326
- /**
327
- * Determine which of two nodes appears in front of the other —
328
- * if `a` is in front, returns 1, otherwise returns -1
329
- * @param {HTMLElement | SVGElement} a
330
- * @param {HTMLElement | SVGElement} b
331
- */
332
- function compare(a, b) {
333
- if (a === b) throw new Error("Cannot compare node with itself");
334
- const ancestors = {
335
- a: get_ancestors(a),
336
- b: get_ancestors(b)
337
- };
338
- let common_ancestor;
339
-
340
- // remove shared ancestors
341
- while (ancestors.a.at(-1) === ancestors.b.at(-1)) {
342
- a = ancestors.a.pop();
343
- b = ancestors.b.pop();
344
- common_ancestor = a;
150
+ removeAllListeners() {
151
+ this.#e = {};
345
152
  }
346
- assert(common_ancestor, "Stacking order can only be calculated for elements with a common ancestor");
347
- const z_indexes = {
348
- a: get_z_index(find_stacking_context(ancestors.a)),
349
- b: get_z_index(find_stacking_context(ancestors.b))
350
- };
351
- if (z_indexes.a === z_indexes.b) {
352
- const children = common_ancestor.childNodes;
353
- const furthest_ancestors = {
354
- a: ancestors.a.at(-1),
355
- b: ancestors.b.at(-1)
356
- };
357
- let i = children.length;
358
- while (i--) {
359
- const child = children[i];
360
- if (child === furthest_ancestors.a) return 1;
361
- if (child === furthest_ancestors.b) return -1;
153
+ removeListener(t, n) {
154
+ const o = this.#e[t];
155
+ if (o !== void 0) {
156
+ const s = o.indexOf(n);
157
+ s >= 0 && o.splice(s, 1);
362
158
  }
363
159
  }
364
- return Math.sign(z_indexes.a - z_indexes.b);
365
- }
366
- const props = /\b(?:position|zIndex|opacity|transform|webkitTransform|mixBlendMode|filter|webkitFilter|isolation)\b/;
367
-
368
- /** @param {HTMLElement | SVGElement} node */
369
- function is_flex_item(node) {
370
- var _get_parent;
371
- // @ts-ignore
372
- const display = getComputedStyle((_get_parent = get_parent(node)) !== null && _get_parent !== void 0 ? _get_parent : node).display;
373
- return display === "flex" || display === "inline-flex";
374
- }
375
-
376
- /** @param {HTMLElement | SVGElement} node */
377
- function creates_stacking_context(node) {
378
- const style = getComputedStyle(node);
379
-
380
- // https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Positioning/Understanding_z_index/The_stacking_context
381
- if (style.position === "fixed") return true;
382
- // Forked to fix upstream bug https://github.com/Rich-Harris/stacking-order/issues/3
383
- // if (
384
- // (style.zIndex !== "auto" && style.position !== "static") ||
385
- // is_flex_item(node)
386
- // )
387
- if (style.zIndex !== "auto" && (style.position !== "static" || is_flex_item(node))) return true;
388
- if (+style.opacity < 1) return true;
389
- if ("transform" in style && style.transform !== "none") return true;
390
- if ("webkitTransform" in style && style.webkitTransform !== "none") return true;
391
- if ("mixBlendMode" in style && style.mixBlendMode !== "normal") return true;
392
- if ("filter" in style && style.filter !== "none") return true;
393
- if ("webkitFilter" in style && style.webkitFilter !== "none") return true;
394
- if ("isolation" in style && style.isolation === "isolate") return true;
395
- if (props.test(style.willChange)) return true;
396
- // @ts-expect-error
397
- if (style.webkitOverflowScrolling === "touch") return true;
398
- return false;
399
- }
400
-
401
- /** @param {(HTMLElement| SVGElement)[]} nodes */
402
- function find_stacking_context(nodes) {
403
- let i = nodes.length;
404
- while (i--) {
405
- const node = nodes[i];
406
- assert(node, "Missing node");
407
- if (creates_stacking_context(node)) return node;
408
- }
409
- return null;
410
- }
411
-
412
- /** @param {HTMLElement | SVGElement} node */
413
- function get_z_index(node) {
414
- return node && Number(getComputedStyle(node).zIndex) || 0;
415
160
  }
416
-
417
- /** @param {HTMLElement} node */
418
- function get_ancestors(node) {
419
- const ancestors = [];
420
- while (node) {
421
- ancestors.push(node);
422
- // @ts-ignore
423
- node = get_parent(node);
161
+ let C = {
162
+ cursorFlags: 0,
163
+ interactionState: {
164
+ state: "inactive"
165
+ },
166
+ mountedGroups: /* @__PURE__ */ new Map()
167
+ };
168
+ const _ = new $e();
169
+ function O() {
170
+ return C;
171
+ }
172
+ function G(e) {
173
+ const t = typeof e == "function" ? e(C) : e;
174
+ return C === t || (C = {
175
+ ...C,
176
+ ...t
177
+ }, t.cursorFlags !== void 0 && _.emit("cursorFlagsChange", C.cursorFlags), t.interactionState !== void 0 && _.emit("interactionStateChange", C.interactionState), t.mountedGroups !== void 0 && _.emit("mountedGroupsChange", C.mountedGroups)), C;
178
+ }
179
+ const Te = (e) => e, K = () => {
180
+ }, fe = 1, de = 2, pe = 4, he = 8, re = {
181
+ coarse: 10,
182
+ precise: 5
183
+ };
184
+ function _e(e) {
185
+ const { direction: t, element: n, panels: o, separators: s } = e, i = Array.from(n.children).filter((c) => c instanceof HTMLElement).sort((c, u) => {
186
+ const f = c.getBoundingClientRect(), p = u.getBoundingClientRect();
187
+ return t === "horizontal" ? f.left - p.left : f.top - p.top;
188
+ }), a = [];
189
+ let r, l;
190
+ for (const c of i) {
191
+ const u = o.find(
192
+ (f) => f.element === c
193
+ );
194
+ if (u) {
195
+ if (r) {
196
+ const f = r.element.getBoundingClientRect(), p = c.getBoundingClientRect();
197
+ a.push({
198
+ group: e,
199
+ panels: [r, u],
200
+ separator: l,
201
+ rect: t === "horizontal" ? new DOMRect(
202
+ f.right,
203
+ p.top,
204
+ p.left - f.right,
205
+ p.height
206
+ ) : new DOMRect(
207
+ p.left,
208
+ f.bottom,
209
+ p.width,
210
+ p.top - f.bottom
211
+ )
212
+ });
213
+ }
214
+ r = u;
215
+ } else {
216
+ const f = s.find(
217
+ (p) => p.element === c
218
+ );
219
+ f ? l = f : (r = void 0, l = void 0);
220
+ }
424
221
  }
425
- return ancestors; // [ node, ... <body>, <html>, document ]
222
+ return a;
426
223
  }
427
-
428
- /** @param {HTMLElement} node */
429
- function get_parent(node) {
430
- const {
431
- parentNode
432
- } = node;
433
- if (parentNode && parentNode instanceof ShadowRoot) {
434
- return parentNode.host;
435
- }
436
- return parentNode;
224
+ function De(e, t) {
225
+ return {
226
+ x: e.x >= t.left && e.x <= t.right ? 0 : Math.min(
227
+ Math.abs(e.x - t.left),
228
+ Math.abs(e.x - t.right)
229
+ ),
230
+ y: e.y >= t.top && e.y <= t.bottom ? 0 : Math.min(
231
+ Math.abs(e.y - t.top),
232
+ Math.abs(e.y - t.bottom)
233
+ )
234
+ };
437
235
  }
438
-
439
- const EXCEEDED_HORIZONTAL_MIN = 0b0001;
440
- const EXCEEDED_HORIZONTAL_MAX = 0b0010;
441
- const EXCEEDED_VERTICAL_MIN = 0b0100;
442
- const EXCEEDED_VERTICAL_MAX = 0b1000;
443
- const isCoarsePointer = getInputType() === "coarse";
444
- let intersectingHandles = [];
445
- let isPointerDown = false;
446
- let ownerDocumentCounts = new Map();
447
- let panelConstraintFlags = new Map();
448
- const registeredResizeHandlers = new Set();
449
- function registerResizeHandle(resizeHandleId, element, direction, hitAreaMargins, setResizeHandlerState) {
450
- var _ownerDocumentCounts$;
451
- const {
452
- ownerDocument
453
- } = element;
454
- const data = {
455
- direction,
456
- element,
457
- hitAreaMargins,
458
- setResizeHandlerState
236
+ function Fe(e, t, n) {
237
+ let o, s = {
238
+ x: 1 / 0,
239
+ y: 1 / 0
459
240
  };
460
- const count = (_ownerDocumentCounts$ = ownerDocumentCounts.get(ownerDocument)) !== null && _ownerDocumentCounts$ !== void 0 ? _ownerDocumentCounts$ : 0;
461
- ownerDocumentCounts.set(ownerDocument, count + 1);
462
- registeredResizeHandlers.add(data);
463
- updateListeners();
464
- return function unregisterResizeHandle() {
465
- var _ownerDocumentCounts$2;
466
- panelConstraintFlags.delete(resizeHandleId);
467
- registeredResizeHandlers.delete(data);
468
- const count = (_ownerDocumentCounts$2 = ownerDocumentCounts.get(ownerDocument)) !== null && _ownerDocumentCounts$2 !== void 0 ? _ownerDocumentCounts$2 : 1;
469
- ownerDocumentCounts.set(ownerDocument, count - 1);
470
- updateListeners();
471
- if (count === 1) {
472
- ownerDocumentCounts.delete(ownerDocument);
473
- }
474
-
475
- // If the resize handle that is currently unmounting is intersecting with the pointer,
476
- // update the global pointer to account for the change
477
- if (intersectingHandles.includes(data)) {
478
- const index = intersectingHandles.indexOf(data);
479
- if (index >= 0) {
480
- intersectingHandles.splice(index, 1);
241
+ for (const i of t) {
242
+ const a = De(n, i.rect);
243
+ switch (e) {
244
+ case "horizontal": {
245
+ a.x <= s.x && (o = i, s = a);
246
+ break;
247
+ }
248
+ case "vertical": {
249
+ a.y <= s.y && (o = i, s = a);
250
+ break;
481
251
  }
482
- updateCursor();
483
-
484
- // Also instruct the handle to stop dragging; this prevents the parent group from being left in an inconsistent state
485
- // See github.com/bvaughn/react-resizable-panels/issues/402
486
- setResizeHandlerState("up", true, null);
487
- }
488
- };
489
- }
490
- function handlePointerDown(event) {
491
- const {
492
- target
493
- } = event;
494
- const {
495
- x,
496
- y
497
- } = getResizeEventCoordinates(event);
498
- isPointerDown = true;
499
- recalculateIntersectingHandles({
500
- target,
501
- x,
502
- y
503
- });
504
- updateListeners();
505
- if (intersectingHandles.length > 0) {
506
- updateResizeHandlerStates("down", event);
507
-
508
- // Update cursor based on return value(s) from active handles
509
- updateCursor();
510
- event.preventDefault();
511
- if (!isWithinResizeHandle(target)) {
512
- event.stopImmediatePropagation();
513
252
  }
514
253
  }
515
- }
516
- function handlePointerMove(event) {
517
- const {
518
- x,
519
- y
520
- } = getResizeEventCoordinates(event);
521
-
522
- // Edge case (see #340)
523
- // Detect when the pointer has been released outside an iframe on a different domain
524
- if (isPointerDown &&
525
- // Skip this check for "pointerleave" events, else Firefox triggers a false positive (see #514)
526
- event.type !== "pointerleave" && event.buttons === 0) {
527
- isPointerDown = false;
528
- updateResizeHandlerStates("up", event);
529
- }
530
- if (!isPointerDown) {
531
- const {
532
- target
533
- } = event;
534
-
535
- // Recalculate intersecting handles whenever the pointer moves, except if it has already been pressed
536
- // at that point, the handles may not move with the pointer (depending on constraints)
537
- // but the same set of active handles should be locked until the pointer is released
538
- recalculateIntersectingHandles({
539
- target,
540
- x,
541
- y
254
+ return o ? {
255
+ distance: s,
256
+ hitRegion: o
257
+ } : void 0;
258
+ }
259
+ let B;
260
+ function je() {
261
+ return B === void 0 && (typeof matchMedia == "function" ? B = !!matchMedia("(pointer:coarse)").matches : B = !1), B;
262
+ }
263
+ function me(e, t) {
264
+ const n = [];
265
+ return t.forEach((o, s) => {
266
+ if (s.disabled)
267
+ return;
268
+ const i = je() ? re.coarse : re.precise, a = _e(s), r = Fe(s.direction, a, {
269
+ x: e.clientX,
270
+ y: e.clientY
542
271
  });
543
- }
544
- updateResizeHandlerStates("move", event);
545
-
546
- // Update cursor based on return value(s) from active handles
547
- updateCursor();
548
- if (intersectingHandles.length > 0) {
549
- event.preventDefault();
550
- }
272
+ r && r.distance.x <= i && r.distance.y <= i && n.push(r.hitRegion);
273
+ }), n;
551
274
  }
552
- function handlePointerUp(event) {
553
- const {
554
- target
555
- } = event;
556
- const {
557
- x,
558
- y
559
- } = getResizeEventCoordinates(event);
560
- panelConstraintFlags.clear();
561
- isPointerDown = false;
562
- if (intersectingHandles.length > 0) {
563
- event.preventDefault();
564
- if (!isWithinResizeHandle(target)) {
565
- event.stopImmediatePropagation();
566
- }
567
- }
568
- updateResizeHandlerStates("up", event);
569
- recalculateIntersectingHandles({
570
- target,
571
- x,
572
- y
573
- });
574
- updateCursor();
575
- updateListeners();
576
- }
577
- function isWithinResizeHandle(element) {
578
- let currentElement = element;
579
- while (currentElement) {
580
- if (currentElement.hasAttribute(DATA_ATTRIBUTES.resizeHandle)) {
581
- return true;
275
+ function se(e) {
276
+ if (e.defaultPrevented)
277
+ return;
278
+ const { mountedGroups: t } = O(), n = me(e, t), o = /* @__PURE__ */ new Set(), s = /* @__PURE__ */ new Set(), i = /* @__PURE__ */ new Set(), a = /* @__PURE__ */ new Map();
279
+ n.forEach((r) => {
280
+ o.add(r.group), r.panels.forEach((c) => {
281
+ s.add(c);
282
+ }), r.separator && i.add(r.separator);
283
+ const l = t.get(r.group);
284
+ l && a.set(r.group, l.layout);
285
+ }), G({
286
+ interactionState: {
287
+ hitRegions: n,
288
+ initialLayoutMap: a,
289
+ pointerDownAtPoint: { x: e.clientX, y: e.clientY },
290
+ state: "active"
582
291
  }
583
- currentElement = currentElement.parentElement;
584
- }
585
- return false;
292
+ }), n.length && e.preventDefault();
586
293
  }
587
- function recalculateIntersectingHandles({
588
- target,
589
- x,
590
- y
294
+ function He({
295
+ cursorFlags: e,
296
+ groups: t,
297
+ state: n
591
298
  }) {
592
- intersectingHandles.splice(0);
593
- let targetElement = null;
594
- if (target instanceof HTMLElement || target instanceof SVGElement) {
595
- targetElement = target;
596
- }
597
- registeredResizeHandlers.forEach(data => {
598
- const {
599
- element: dragHandleElement,
600
- hitAreaMargins
601
- } = data;
602
- const dragHandleRect = dragHandleElement.getBoundingClientRect();
603
- const {
604
- bottom,
605
- left,
606
- right,
607
- top
608
- } = dragHandleRect;
609
- const margin = isCoarsePointer ? hitAreaMargins.coarse : hitAreaMargins.fine;
610
- const eventIntersects = x >= left - margin && x <= right + margin && y >= top - margin && y <= bottom + margin;
611
- if (eventIntersects) {
612
- // TRICKY
613
- // We listen for pointers events at the root in order to support hit area margins
614
- // (determining when the pointer is close enough to an element to be considered a "hit")
615
- // Clicking on an element "above" a handle (e.g. a modal) should prevent a hit though
616
- // so at this point we need to compare stacking order of a potentially intersecting drag handle,
617
- // and the element that was actually clicked/touched
618
- if (targetElement !== null && document.contains(targetElement) && dragHandleElement !== targetElement && !dragHandleElement.contains(targetElement) && !targetElement.contains(dragHandleElement) &&
619
- // Calculating stacking order has a cost, so we should avoid it if possible
620
- // That is why we only check potentially intersecting handles,
621
- // and why we skip if the event target is within the handle's DOM
622
- compare(targetElement, dragHandleElement) > 0) {
623
- // If the target is above the drag handle, then we also need to confirm they overlap
624
- // If they are beside each other (e.g. a panel and its drag handle) then the handle is still interactive
625
- //
626
- // It's not enough to compare only the target
627
- // The target might be a small element inside of a larger container
628
- // (For example, a SPAN or a DIV inside of a larger modal dialog)
629
- let currentElement = targetElement;
630
- let didIntersect = false;
631
- while (currentElement) {
632
- if (currentElement.contains(dragHandleElement)) {
633
- break;
634
- } else if (intersects(currentElement.getBoundingClientRect(), dragHandleRect, true)) {
635
- didIntersect = true;
636
- break;
299
+ let o = 0, s = 0;
300
+ switch (n) {
301
+ case "active":
302
+ case "hover":
303
+ t.forEach((i) => {
304
+ if (!i.disableCursor)
305
+ switch (i.direction) {
306
+ case "horizontal": {
307
+ o++;
308
+ break;
309
+ }
310
+ case "vertical": {
311
+ s++;
312
+ break;
313
+ }
637
314
  }
638
- currentElement = currentElement.parentElement;
639
- }
640
- if (didIntersect) {
641
- return;
642
- }
315
+ });
316
+ }
317
+ if (o === 0 && s === 0)
318
+ return null;
319
+ switch (n) {
320
+ case "active": {
321
+ const i = (e & fe) !== 0, a = (e & de) !== 0, r = (e & pe) !== 0, l = (e & he) !== 0;
322
+ if (e) {
323
+ if (i)
324
+ return r ? "se-resize" : l ? "ne-resize" : "e-resize";
325
+ if (a)
326
+ return r ? "sw-resize" : l ? "nw-resize" : "w-resize";
327
+ if (r)
328
+ return "s-resize";
329
+ if (l)
330
+ return "n-resize";
643
331
  }
644
- intersectingHandles.push(data);
332
+ break;
645
333
  }
646
- });
647
- }
648
- function reportConstraintsViolation(resizeHandleId, flag) {
649
- panelConstraintFlags.set(resizeHandleId, flag);
650
- }
651
- function updateCursor() {
652
- let intersectsHorizontal = false;
653
- let intersectsVertical = false;
654
- intersectingHandles.forEach(data => {
655
- const {
656
- direction
657
- } = data;
658
- if (direction === "horizontal") {
659
- intersectsHorizontal = true;
660
- } else {
661
- intersectsVertical = true;
662
- }
663
- });
664
- let constraintFlags = 0;
665
- panelConstraintFlags.forEach(flag => {
666
- constraintFlags |= flag;
667
- });
668
- if (intersectsHorizontal && intersectsVertical) {
669
- setGlobalCursorStyle("intersection", constraintFlags, isPointerDown);
670
- } else if (intersectsHorizontal) {
671
- setGlobalCursorStyle("horizontal", constraintFlags, isPointerDown);
672
- } else if (intersectsVertical) {
673
- setGlobalCursorStyle("vertical", constraintFlags, isPointerDown);
674
- } else {
675
- resetGlobalCursorStyle();
676
334
  }
677
- }
678
- let listenersAbortController;
679
- function updateListeners() {
680
- var _listenersAbortContro;
681
- (_listenersAbortContro = listenersAbortController) === null || _listenersAbortContro === void 0 ? void 0 : _listenersAbortContro.abort();
682
- listenersAbortController = new AbortController();
683
- const options = {
684
- capture: true,
685
- signal: listenersAbortController.signal
686
- };
687
- if (!registeredResizeHandlers.size) {
688
- return;
689
- }
690
- if (isPointerDown) {
691
- if (intersectingHandles.length > 0) {
692
- ownerDocumentCounts.forEach((count, ownerDocument) => {
693
- const {
694
- body
695
- } = ownerDocument;
696
- if (count > 0) {
697
- body.addEventListener("contextmenu", handlePointerUp, options);
698
- body.addEventListener("pointerleave", handlePointerMove, options);
699
- body.addEventListener("pointermove", handlePointerMove, options);
700
- }
335
+ return o > 0 && s > 0 ? "move" : o > 0 ? "ew-resize" : "ns-resize";
336
+ }
337
+ let V = null, P;
338
+ function X() {
339
+ P === void 0 && (P = new CSSStyleSheet(), document.adoptedStyleSheets = [P]);
340
+ const { cursorFlags: e, interactionState: t } = O();
341
+ switch (t.state) {
342
+ case "active":
343
+ case "hover": {
344
+ const n = He({
345
+ cursorFlags: e,
346
+ groups: t.hitRegions.map((o) => o.group),
347
+ state: t.state
701
348
  });
349
+ if (V === n)
350
+ return;
351
+ V = n, n ? P.cssRules.length === 0 ? P.insertRule(`*{cursor: ${n} !important;}`) : P.replaceSync(`*{cursor: ${n} !important;}`) : P.cssRules.length === 1 && P.deleteRule(0);
352
+ break;
353
+ }
354
+ case "inactive": {
355
+ V = null, P.cssRules.length === 1 && P.deleteRule(0);
356
+ break;
702
357
  }
703
- ownerDocumentCounts.forEach((_, ownerDocument) => {
704
- const {
705
- body
706
- } = ownerDocument;
707
- body.addEventListener("pointerup", handlePointerUp, options);
708
- body.addEventListener("pointercancel", handlePointerUp, options);
709
- });
710
- } else {
711
- ownerDocumentCounts.forEach((count, ownerDocument) => {
712
- const {
713
- body
714
- } = ownerDocument;
715
- if (count > 0) {
716
- body.addEventListener("pointerdown", handlePointerDown, options);
717
- body.addEventListener("pointermove", handlePointerMove, options);
718
- }
719
- });
720
- }
721
- }
722
- function updateResizeHandlerStates(action, event) {
723
- registeredResizeHandlers.forEach(data => {
724
- const {
725
- setResizeHandlerState
726
- } = data;
727
- const isActive = intersectingHandles.includes(data);
728
- setResizeHandlerState(action, isActive, event);
729
- });
730
- }
731
-
732
- function useForceUpdate() {
733
- const [_, setCount] = useState(0);
734
- return useCallback(() => setCount(prevCount => prevCount + 1), []);
735
- }
736
-
737
- function assert(expectedCondition, message) {
738
- if (!expectedCondition) {
739
- console.error(message);
740
- throw Error(message);
741
358
  }
742
359
  }
743
-
744
- function fuzzyCompareNumbers(actual, expected, fractionDigits = PRECISION) {
745
- if (actual.toFixed(fractionDigits) === expected.toFixed(fractionDigits)) {
746
- return 0;
747
- } else {
748
- return actual > expected ? 1 : -1;
749
- }
360
+ function E(e, t = "Assertion error") {
361
+ if (!e)
362
+ throw console.error(t), Error(t);
750
363
  }
751
- function fuzzyNumbersEqual$1(actual, expected, fractionDigits = PRECISION) {
752
- return fuzzyCompareNumbers(actual, expected, fractionDigits) === 0;
364
+ function Be(e, t) {
365
+ if (e.length !== t.length)
366
+ return !1;
367
+ for (let n = 0; n < e.length; n++)
368
+ if (e[n] != t[n])
369
+ return !1;
370
+ return !0;
753
371
  }
754
-
755
- function fuzzyNumbersEqual(actual, expected, fractionDigits) {
756
- return fuzzyCompareNumbers(actual, expected, fractionDigits) === 0;
372
+ function b(e, t, n = 0) {
373
+ return Math.abs(L(e) - L(t)) <= n;
757
374
  }
758
-
759
- function fuzzyLayoutsEqual(actual, expected, fractionDigits) {
760
- if (actual.length !== expected.length) {
761
- return false;
762
- }
763
- for (let index = 0; index < actual.length; index++) {
764
- const actualSize = actual[index];
765
- const expectedSize = expected[index];
766
- if (!fuzzyNumbersEqual(actualSize, expectedSize, fractionDigits)) {
767
- return false;
768
- }
769
- }
770
- return true;
375
+ function Y(e, t) {
376
+ return b(e, t) ? 0 : e > t ? 1 : -1;
771
377
  }
772
-
773
- // Panel size must be in percentages; pixel values should be pre-converted
774
- function resizePanel({
775
- panelConstraints: panelConstraintsArray,
776
- panelIndex,
777
- size
378
+ function T({
379
+ panelConstraints: e,
380
+ size: t
778
381
  }) {
779
- const panelConstraints = panelConstraintsArray[panelIndex];
780
- assert(panelConstraints != null, `Panel constraints not found for index ${panelIndex}`);
781
- let {
782
- collapsedSize = 0,
783
- collapsible,
784
- maxSize = 100,
785
- minSize = 0
786
- } = panelConstraints;
787
- if (fuzzyCompareNumbers(size, minSize) < 0) {
788
- if (collapsible) {
789
- // Collapsible panels should snap closed or open only once they cross the halfway point between collapsed and min size.
790
- const halfwayPoint = (collapsedSize + minSize) / 2;
791
- if (fuzzyCompareNumbers(size, halfwayPoint) < 0) {
792
- size = collapsedSize;
793
- } else {
794
- size = minSize;
795
- }
796
- } else {
797
- size = minSize;
798
- }
799
- }
800
- size = Math.min(maxSize, size);
801
- size = parseFloat(size.toFixed(PRECISION));
802
- return size;
803
- }
804
-
805
- // All units must be in percentages; pixel values should be pre-converted
806
- function adjustLayoutByDelta({
807
- delta,
808
- initialLayout,
809
- panelConstraints: panelConstraintsArray,
810
- pivotIndices,
811
- prevLayout,
812
- trigger
382
+ const {
383
+ collapsedSize: n = 0,
384
+ collapsible: o,
385
+ maxSize: s = 100,
386
+ minSize: i = 0
387
+ } = e;
388
+ if (Y(t, i) < 0)
389
+ if (o) {
390
+ const a = (n + i) / 2;
391
+ Y(t, a) < 0 ? t = n : t = i;
392
+ } else
393
+ t = i;
394
+ return t = Math.min(s, t), t = L(t), t;
395
+ }
396
+ function We({
397
+ delta: e,
398
+ initialLayout: t,
399
+ panelConstraints: n,
400
+ pivotIndices: o,
401
+ prevLayout: s,
402
+ trigger: i
813
403
  }) {
814
- if (fuzzyNumbersEqual(delta, 0)) {
815
- return initialLayout;
816
- }
817
- const nextLayout = [...initialLayout];
818
- const [firstPivotIndex, secondPivotIndex] = pivotIndices;
819
- assert(firstPivotIndex != null, "Invalid first pivot index");
820
- assert(secondPivotIndex != null, "Invalid second pivot index");
821
- let deltaApplied = 0;
822
-
823
- // const DEBUG = [];
824
- // DEBUG.push(`adjustLayoutByDelta()`);
825
- // DEBUG.push(` initialLayout: ${initialLayout.join(", ")}`);
826
- // DEBUG.push(` prevLayout: ${prevLayout.join(", ")}`);
827
- // DEBUG.push(` delta: ${delta}`);
828
- // DEBUG.push(` pivotIndices: ${pivotIndices.join(", ")}`);
829
- // DEBUG.push(` trigger: ${trigger}`);
830
- // DEBUG.push("");
831
-
832
- // A resizing panel affects the panels before or after it.
833
- //
834
- // A negative delta means the panel(s) immediately after the resize handle should grow/expand by decreasing its offset.
835
- // Other panels may also need to shrink/contract (and shift) to make room, depending on the min weights.
836
- //
837
- // A positive delta means the panel(s) immediately before the resize handle should "expand".
838
- // This is accomplished by shrinking/contracting (and shifting) one or more of the panels after the resize handle.
839
-
840
- {
841
- // If this is a resize triggered by a keyboard event, our logic for expanding/collapsing is different.
842
- // We no longer check the halfway threshold because this may prevent the panel from expanding at all.
843
- if (trigger === "keyboard") {
844
- {
845
- // Check if we should expand a collapsed panel
846
- const index = delta < 0 ? secondPivotIndex : firstPivotIndex;
847
- const panelConstraints = panelConstraintsArray[index];
848
- assert(panelConstraints, `Panel constraints not found for index ${index}`);
849
- const {
850
- collapsedSize = 0,
851
- collapsible,
852
- minSize = 0
853
- } = panelConstraints;
854
-
855
- // DEBUG.push(`edge case check 1: ${index}`);
856
- // DEBUG.push(` -> collapsible? ${collapsible}`);
857
- if (collapsible) {
858
- const prevSize = initialLayout[index];
859
- assert(prevSize != null, `Previous layout not found for panel index ${index}`);
860
- if (fuzzyNumbersEqual(prevSize, collapsedSize)) {
861
- const localDelta = minSize - prevSize;
862
- // DEBUG.push(` -> expand delta: ${localDelta}`);
863
-
864
- if (fuzzyCompareNumbers(localDelta, Math.abs(delta)) > 0) {
865
- delta = delta < 0 ? 0 - localDelta : localDelta;
866
- // DEBUG.push(` -> delta: ${delta}`);
867
- }
868
- }
869
- }
870
- }
871
-
872
- {
873
- // Check if we should collapse a panel at its minimum size
874
- const index = delta < 0 ? firstPivotIndex : secondPivotIndex;
875
- const panelConstraints = panelConstraintsArray[index];
876
- assert(panelConstraints, `No panel constraints found for index ${index}`);
877
- const {
878
- collapsedSize = 0,
879
- collapsible,
880
- minSize = 0
881
- } = panelConstraints;
882
-
883
- // DEBUG.push(`edge case check 2: ${index}`);
884
- // DEBUG.push(` -> collapsible? ${collapsible}`);
885
- if (collapsible) {
886
- const prevSize = initialLayout[index];
887
- assert(prevSize != null, `Previous layout not found for panel index ${index}`);
888
- if (fuzzyNumbersEqual(prevSize, minSize)) {
889
- const localDelta = prevSize - collapsedSize;
890
- // DEBUG.push(` -> expand delta: ${localDelta}`);
891
-
892
- if (fuzzyCompareNumbers(localDelta, Math.abs(delta)) > 0) {
893
- delta = delta < 0 ? 0 - localDelta : localDelta;
894
- // DEBUG.push(` -> delta: ${delta}`);
895
- }
896
- }
897
- }
898
- }
899
- }
900
- // DEBUG.push("");
901
- }
902
-
404
+ if (b(e, 0))
405
+ return t;
406
+ const a = Object.values(t), r = Object.values(s), l = [...a], [c, u] = o;
407
+ E(c != null, "Invalid first pivot index"), E(u != null, "Invalid second pivot index");
408
+ let f = 0;
903
409
  {
904
- // Pre-calculate max available delta in the opposite direction of our pivot.
905
- // This will be the maximum amount we're allowed to expand/contract the panels in the primary direction.
906
- // If this amount is less than the requested delta, adjust the requested delta.
907
- // If this amount is greater than the requested delta, that's useful information too–
908
- // as an expanding panel might change from collapsed to min size.
909
-
910
- const increment = delta < 0 ? 1 : -1;
911
- let index = delta < 0 ? secondPivotIndex : firstPivotIndex;
912
- let maxAvailableDelta = 0;
913
-
914
- // DEBUG.push("pre calc...");
915
- while (true) {
916
- const prevSize = initialLayout[index];
917
- assert(prevSize != null, `Previous layout not found for panel index ${index}`);
918
- const maxSafeSize = resizePanel({
919
- panelConstraints: panelConstraintsArray,
920
- panelIndex: index,
410
+ const m = e < 0 ? 1 : -1;
411
+ let d = e < 0 ? u : c, v = 0;
412
+ for (; ; ) {
413
+ const x = a[d];
414
+ E(
415
+ x != null,
416
+ `Previous layout not found for panel index ${d}`
417
+ );
418
+ const y = T({
419
+ panelConstraints: n[d],
921
420
  size: 100
922
- });
923
- const delta = maxSafeSize - prevSize;
924
- // DEBUG.push(` ${index}: ${prevSize} -> ${maxSafeSize}`);
925
-
926
- maxAvailableDelta += delta;
927
- index += increment;
928
- if (index < 0 || index >= panelConstraintsArray.length) {
421
+ }) - x;
422
+ if (v += y, d += m, d < 0 || d >= n.length)
929
423
  break;
930
- }
931
424
  }
932
-
933
- // DEBUG.push(` -> max available delta: ${maxAvailableDelta}`);
934
- const minAbsDelta = Math.min(Math.abs(delta), Math.abs(maxAvailableDelta));
935
- delta = delta < 0 ? 0 - minAbsDelta : minAbsDelta;
936
- // DEBUG.push(` -> adjusted delta: ${delta}`);
937
- // DEBUG.push("");
425
+ const S = Math.min(Math.abs(e), Math.abs(v));
426
+ e = e < 0 ? 0 - S : S;
938
427
  }
939
-
940
428
  {
941
- // Delta added to a panel needs to be subtracted from other panels (within the constraints that those panels allow).
942
-
943
- const pivotIndex = delta < 0 ? firstPivotIndex : secondPivotIndex;
944
- let index = pivotIndex;
945
- while (index >= 0 && index < panelConstraintsArray.length) {
946
- const deltaRemaining = Math.abs(delta) - Math.abs(deltaApplied);
947
- const prevSize = initialLayout[index];
948
- assert(prevSize != null, `Previous layout not found for panel index ${index}`);
949
- const unsafeSize = prevSize - deltaRemaining;
950
- const safeSize = resizePanel({
951
- panelConstraints: panelConstraintsArray,
952
- panelIndex: index,
953
- size: unsafeSize
429
+ let d = e < 0 ? c : u;
430
+ for (; d >= 0 && d < n.length; ) {
431
+ const v = Math.abs(e) - Math.abs(f), S = a[d];
432
+ E(
433
+ S != null,
434
+ `Previous layout not found for panel index ${d}`
435
+ );
436
+ const x = S - v, z = T({
437
+ panelConstraints: n[d],
438
+ size: x
954
439
  });
955
- if (!fuzzyNumbersEqual(prevSize, safeSize)) {
956
- deltaApplied += prevSize - safeSize;
957
- nextLayout[index] = safeSize;
958
- if (deltaApplied.toFixed(3).localeCompare(Math.abs(delta).toFixed(3), undefined, {
959
- numeric: true
960
- }) >= 0) {
961
- break;
962
- }
963
- }
964
- if (delta < 0) {
965
- index--;
966
- } else {
967
- index++;
968
- }
440
+ if (!b(S, z) && (f += S - z, l[d] = z, f.toFixed(3).localeCompare(Math.abs(e).toFixed(3), void 0, {
441
+ numeric: !0
442
+ }) >= 0))
443
+ break;
444
+ e < 0 ? d-- : d++;
969
445
  }
970
446
  }
971
- // DEBUG.push(`after 1: ${nextLayout.join(", ")}`);
972
- // DEBUG.push(` deltaApplied: ${deltaApplied}`);
973
- // DEBUG.push("");
974
-
975
- // If we were unable to resize any of the panels panels, return the previous state.
976
- // This will essentially bailout and ignore e.g. drags past a panel's boundaries
977
- if (fuzzyLayoutsEqual(prevLayout, nextLayout)) {
978
- // DEBUG.push(`bailout to previous layout: ${prevLayout.join(", ")}`);
979
- // console.log(DEBUG.join("\n"));
980
-
981
- return prevLayout;
982
- }
447
+ if (Be(r, l))
448
+ return s;
983
449
  {
984
- // Now distribute the applied delta to the panels in the other direction
985
- const pivotIndex = delta < 0 ? secondPivotIndex : firstPivotIndex;
986
- const prevSize = initialLayout[pivotIndex];
987
- assert(prevSize != null, `Previous layout not found for panel index ${pivotIndex}`);
988
- const unsafeSize = prevSize + deltaApplied;
989
- const safeSize = resizePanel({
990
- panelConstraints: panelConstraintsArray,
991
- panelIndex: pivotIndex,
992
- size: unsafeSize
450
+ const m = e < 0 ? u : c, d = a[m];
451
+ E(
452
+ d != null,
453
+ `Previous layout not found for panel index ${m}`
454
+ );
455
+ const v = d + f, S = T({
456
+ panelConstraints: n[m],
457
+ size: v
993
458
  });
994
-
995
- // Adjust the pivot panel before, but only by the amount that surrounding panels were able to shrink/contract.
996
- nextLayout[pivotIndex] = safeSize;
997
-
998
- // Edge case where expanding or contracting one panel caused another one to change collapsed state
999
- if (!fuzzyNumbersEqual(safeSize, unsafeSize)) {
1000
- let deltaRemaining = unsafeSize - safeSize;
1001
- const pivotIndex = delta < 0 ? secondPivotIndex : firstPivotIndex;
1002
- let index = pivotIndex;
1003
- while (index >= 0 && index < panelConstraintsArray.length) {
1004
- const prevSize = nextLayout[index];
1005
- assert(prevSize != null, `Previous layout not found for panel index ${index}`);
1006
- const unsafeSize = prevSize + deltaRemaining;
1007
- const safeSize = resizePanel({
1008
- panelConstraints: panelConstraintsArray,
1009
- panelIndex: index,
1010
- size: unsafeSize
459
+ if (l[m] = S, !b(S, v)) {
460
+ let x = v - S, y = e < 0 ? u : c;
461
+ for (; y >= 0 && y < n.length; ) {
462
+ const R = l[y];
463
+ E(
464
+ R != null,
465
+ `Previous layout not found for panel index ${y}`
466
+ );
467
+ const k = R + x, A = T({
468
+ panelConstraints: n[y],
469
+ size: k
1011
470
  });
1012
- if (!fuzzyNumbersEqual(prevSize, safeSize)) {
1013
- deltaRemaining -= safeSize - prevSize;
1014
- nextLayout[index] = safeSize;
1015
- }
1016
- if (fuzzyNumbersEqual(deltaRemaining, 0)) {
471
+ if (b(R, A) || (x -= A - R, l[y] = A), b(x, 0))
1017
472
  break;
1018
- }
1019
- if (delta > 0) {
1020
- index--;
1021
- } else {
1022
- index++;
1023
- }
473
+ e > 0 ? y-- : y++;
1024
474
  }
1025
475
  }
1026
476
  }
1027
- // DEBUG.push(`after 2: ${nextLayout.join(", ")}`);
1028
- // DEBUG.push(` deltaApplied: ${deltaApplied}`);
1029
- // DEBUG.push("");
1030
-
1031
- const totalSize = nextLayout.reduce((total, size) => size + total, 0);
1032
- // DEBUG.push(`total size: ${totalSize}`);
1033
-
1034
- // If our new layout doesn't add up to 100%, that means the requested delta can't be applied
1035
- // In that case, fall back to our most recent valid layout
1036
- if (!fuzzyNumbersEqual(totalSize, 100)) {
1037
- // DEBUG.push(`bailout to previous layout: ${prevLayout.join(", ")}`);
1038
- // console.log(DEBUG.join("\n"));
1039
-
1040
- return prevLayout;
1041
- }
1042
-
1043
- // console.log(DEBUG.join("\n"));
1044
- return nextLayout;
1045
- }
1046
-
1047
- function calculateAriaValues({
1048
- layout,
1049
- panelsArray,
1050
- pivotIndices
1051
- }) {
1052
- let currentMinSize = 0;
1053
- let currentMaxSize = 100;
1054
- let totalMinSize = 0;
1055
- let totalMaxSize = 0;
1056
- const firstIndex = pivotIndices[0];
1057
- assert(firstIndex != null, "No pivot index found");
1058
-
1059
- // A panel's effective min/max sizes also need to account for other panel's sizes.
1060
- panelsArray.forEach((panelData, index) => {
1061
- const {
1062
- constraints
1063
- } = panelData;
1064
- const {
1065
- maxSize = 100,
1066
- minSize = 0
1067
- } = constraints;
1068
- if (index === firstIndex) {
1069
- currentMinSize = minSize;
1070
- currentMaxSize = maxSize;
1071
- } else {
1072
- totalMinSize += minSize;
1073
- totalMaxSize += maxSize;
477
+ const p = Object.values(l).reduce(
478
+ (m, d) => d + m,
479
+ 0
480
+ );
481
+ if (!b(p, 100, 0.1))
482
+ return s;
483
+ const h = Object.keys(s);
484
+ return l.reduce((m, d, v) => (m[h[v]] = d, m), {});
485
+ }
486
+ function q(e, t) {
487
+ if (Object.keys(e).length !== Object.keys(t).length)
488
+ return !1;
489
+ for (const n in e)
490
+ if (Y(e[n], t[n]) !== 0)
491
+ return !1;
492
+ return !0;
493
+ }
494
+ function W(e) {
495
+ if (e.defaultPrevented)
496
+ return;
497
+ const { interactionState: t, mountedGroups: n } = O();
498
+ switch (t.state) {
499
+ case "active": {
500
+ if (
501
+ // Skip this check for "pointerleave" events, else Firefox triggers a false positive (see #514)
502
+ e.type !== "pointerleave" && e.buttons === 0
503
+ ) {
504
+ G(
505
+ (i) => i.interactionState.state === "inactive" ? i : {
506
+ cursorFlags: 0,
507
+ interactionState: {
508
+ state: "inactive"
509
+ }
510
+ }
511
+ );
512
+ return;
513
+ }
514
+ let o = 0;
515
+ const s = new Map(n);
516
+ t.hitRegions.forEach((i) => {
517
+ const { direction: a, disableCursor: r, element: l, panels: c } = i.group;
518
+ let u = 0;
519
+ t.state === "active" && (a === "horizontal" ? u = (e.clientX - t.pointerDownAtPoint.x) / l.offsetWidth * 100 : u = (e.clientY - t.pointerDownAtPoint.y) / l.offsetHeight * 100);
520
+ const f = t.initialLayoutMap.get(
521
+ i.group
522
+ ), { derivedPanelConstraints: p, layout: h } = n.get(i.group) ?? {};
523
+ if (p && f && h) {
524
+ const m = We({
525
+ delta: u,
526
+ initialLayout: f,
527
+ panelConstraints: p,
528
+ pivotIndices: i.panels.map((d) => c.indexOf(d)),
529
+ prevLayout: h,
530
+ trigger: "mouse-or-touch"
531
+ });
532
+ if (q(m, h)) {
533
+ if (u !== 0 && !r)
534
+ switch (a) {
535
+ case "horizontal": {
536
+ o |= u < 0 ? fe : de;
537
+ break;
538
+ }
539
+ case "vertical": {
540
+ o |= u < 0 ? pe : he;
541
+ break;
542
+ }
543
+ }
544
+ } else {
545
+ s.set(i.group, {
546
+ derivedPanelConstraints: p,
547
+ layout: m
548
+ });
549
+ const d = i.group.panels.map(({ id: v }) => v).join(",");
550
+ i.group.inMemoryLayouts[d] = m;
551
+ }
552
+ }
553
+ }), G({
554
+ cursorFlags: o,
555
+ mountedGroups: s
556
+ }), X();
557
+ break;
558
+ }
559
+ default: {
560
+ const o = me(e, n);
561
+ o.length === 0 ? t.state !== "inactive" && G({
562
+ interactionState: { state: "inactive" }
563
+ }) : G({
564
+ interactionState: {
565
+ hitRegions: o,
566
+ state: "hover"
567
+ }
568
+ }), X();
569
+ break;
1074
570
  }
1075
- });
1076
- const valueMax = Math.min(currentMaxSize, 100 - totalMinSize);
1077
- const valueMin = Math.max(currentMinSize, 100 - totalMaxSize);
1078
- const valueNow = layout[firstIndex];
1079
- return {
1080
- valueMax,
1081
- valueMin,
1082
- valueNow
1083
- };
1084
- }
1085
-
1086
- function getResizeHandleElementsForGroup(groupId, scope = document) {
1087
- return Array.from(scope.querySelectorAll(`[${DATA_ATTRIBUTES.resizeHandleId}][data-panel-group-id="${groupId}"]`));
1088
- }
1089
-
1090
- function getResizeHandleElementIndex(groupId, id, scope = document) {
1091
- const handles = getResizeHandleElementsForGroup(groupId, scope);
1092
- const index = handles.findIndex(handle => handle.getAttribute(DATA_ATTRIBUTES.resizeHandleId) === id);
1093
- return index !== null && index !== void 0 ? index : null;
1094
- }
1095
-
1096
- function determinePivotIndices(groupId, dragHandleId, panelGroupElement) {
1097
- const index = getResizeHandleElementIndex(groupId, dragHandleId, panelGroupElement);
1098
- return index != null ? [index, index + 1] : [-1, -1];
1099
- }
1100
-
1101
- function isHTMLElement(target) {
1102
- if (target instanceof HTMLElement) {
1103
- return true;
1104
571
  }
1105
-
1106
- // Fallback to duck typing to handle edge case of portals within a popup window
1107
- return typeof target === "object" && target !== null && "tagName" in target && "getAttribute" in target;
1108
572
  }
1109
-
1110
- function getPanelGroupElement(id, rootElement = document) {
1111
- // If the root element is the PanelGroup
1112
- if (isHTMLElement(rootElement) && rootElement.dataset.panelGroupId == id) {
1113
- return rootElement;
1114
- }
1115
-
1116
- // Else query children
1117
- const element = rootElement.querySelector(`[data-panel-group][data-panel-group-id="${id}"]`);
1118
- if (element) {
1119
- return element;
573
+ function ae(e) {
574
+ if (e.defaultPrevented)
575
+ return;
576
+ e.preventDefault();
577
+ const { interactionState: t } = O();
578
+ switch (t.state) {
579
+ case "active":
580
+ G({
581
+ cursorFlags: 0,
582
+ interactionState: {
583
+ state: "inactive"
584
+ }
585
+ }), X();
1120
586
  }
1121
- return null;
1122
587
  }
1123
-
1124
- function getResizeHandleElement(id, scope = document) {
1125
- const element = scope.querySelector(`[${DATA_ATTRIBUTES.resizeHandleId}="${id}"]`);
1126
- if (element) {
1127
- return element;
588
+ function Ue(e) {
589
+ let t = 0, n = 0;
590
+ const o = {};
591
+ for (const i of e)
592
+ if (i.defaultSize !== void 0) {
593
+ t++;
594
+ const a = L(i.defaultSize);
595
+ n += a, o[i.panelId] = a;
596
+ } else
597
+ o[i.panelId] = void 0;
598
+ const s = e.length - t;
599
+ if (s !== 0) {
600
+ const i = L((100 - n) / s);
601
+ for (const a of e)
602
+ a.defaultSize === void 0 && (o[a.panelId] = i);
1128
603
  }
1129
- return null;
604
+ return o;
1130
605
  }
1131
-
1132
- function getResizeHandlePanelIds(groupId, handleId, panelsArray, scope = document) {
1133
- var _panelsArray$index$id, _panelsArray$index, _panelsArray$id, _panelsArray;
1134
- const handle = getResizeHandleElement(handleId, scope);
1135
- const handles = getResizeHandleElementsForGroup(groupId, scope);
1136
- const index = handle ? handles.indexOf(handle) : -1;
1137
- const idBefore = (_panelsArray$index$id = (_panelsArray$index = panelsArray[index]) === null || _panelsArray$index === void 0 ? void 0 : _panelsArray$index.id) !== null && _panelsArray$index$id !== void 0 ? _panelsArray$index$id : null;
1138
- const idAfter = (_panelsArray$id = (_panelsArray = panelsArray[index + 1]) === null || _panelsArray === void 0 ? void 0 : _panelsArray.id) !== null && _panelsArray$id !== void 0 ? _panelsArray$id : null;
1139
- return [idBefore, idAfter];
606
+ function Ke(e, t, n) {
607
+ const o = n[0];
608
+ if (!o)
609
+ return;
610
+ const s = e.panels.find((a) => a.element === t);
611
+ if (!s || !s.onResize)
612
+ return;
613
+ const i = Z({ group: e });
614
+ s.onResize({
615
+ asPercentage: L(
616
+ o.inlineSize / i * 100
617
+ ),
618
+ inPixels: o.inlineSize
619
+ });
1140
620
  }
1141
-
1142
- // https://www.w3.org/WAI/ARIA/apg/patterns/windowsplitter/
1143
-
1144
- function useWindowSplitterPanelGroupBehavior({
1145
- committedValuesRef,
1146
- eagerValuesRef,
1147
- groupId,
1148
- layout,
1149
- panelDataArray,
1150
- panelGroupElement,
1151
- setLayout
621
+ function ve({
622
+ layout: e,
623
+ panelConstraints: t
1152
624
  }) {
1153
- useRef({
1154
- didWarnAboutMissingResizeHandle: false
1155
- });
1156
- useIsomorphicLayoutEffect(() => {
1157
- if (!panelGroupElement) {
1158
- return;
1159
- }
1160
- const resizeHandleElements = getResizeHandleElementsForGroup(groupId, panelGroupElement);
1161
- for (let index = 0; index < panelDataArray.length - 1; index++) {
1162
- const {
1163
- valueMax,
1164
- valueMin,
1165
- valueNow
1166
- } = calculateAriaValues({
1167
- layout,
1168
- panelsArray: panelDataArray,
1169
- pivotIndices: [index, index + 1]
1170
- });
1171
- const resizeHandleElement = resizeHandleElements[index];
1172
- if (resizeHandleElement == null) ; else {
1173
- const panelData = panelDataArray[index];
1174
- assert(panelData, `No panel data found for index "${index}"`);
1175
- resizeHandleElement.setAttribute("aria-controls", panelData.id);
1176
- resizeHandleElement.setAttribute("aria-valuemax", "" + Math.round(valueMax));
1177
- resizeHandleElement.setAttribute("aria-valuemin", "" + Math.round(valueMin));
1178
- resizeHandleElement.setAttribute("aria-valuenow", valueNow != null ? "" + Math.round(valueNow) : "");
1179
- }
625
+ const o = [...Object.values(e)], s = o.reduce(
626
+ (r, l) => r + l,
627
+ 0
628
+ );
629
+ if (o.length !== t.length)
630
+ throw Error(
631
+ `Invalid ${t.length} panel layout: ${o.map((r) => `${r}%`).join(", ")}`
632
+ );
633
+ if (!b(s, 100) && o.length > 0)
634
+ for (let r = 0; r < t.length; r++) {
635
+ const l = o[r];
636
+ E(l != null, `No layout data found for index ${r}`);
637
+ const c = 100 / s * l;
638
+ o[r] = c;
1180
639
  }
1181
- return () => {
1182
- resizeHandleElements.forEach((resizeHandleElement, index) => {
1183
- resizeHandleElement.removeAttribute("aria-controls");
1184
- resizeHandleElement.removeAttribute("aria-valuemax");
1185
- resizeHandleElement.removeAttribute("aria-valuemin");
1186
- resizeHandleElement.removeAttribute("aria-valuenow");
1187
- });
1188
- };
1189
- }, [groupId, layout, panelDataArray, panelGroupElement]);
1190
- useEffect(() => {
1191
- if (!panelGroupElement) {
1192
- return;
1193
- }
1194
- const eagerValues = eagerValuesRef.current;
1195
- assert(eagerValues, `Eager values not found`);
1196
- const {
1197
- panelDataArray
1198
- } = eagerValues;
1199
- const groupElement = getPanelGroupElement(groupId, panelGroupElement);
1200
- assert(groupElement != null, `No group found for id "${groupId}"`);
1201
- const handles = getResizeHandleElementsForGroup(groupId, panelGroupElement);
1202
- assert(handles, `No resize handles found for group id "${groupId}"`);
1203
- const cleanupFunctions = handles.map(handle => {
1204
- const handleId = handle.getAttribute(DATA_ATTRIBUTES.resizeHandleId);
1205
- assert(handleId, `Resize handle element has no handle id attribute`);
1206
- const [idBefore, idAfter] = getResizeHandlePanelIds(groupId, handleId, panelDataArray, panelGroupElement);
1207
- if (idBefore == null || idAfter == null) {
1208
- return () => {};
1209
- }
1210
- const onKeyDown = event => {
1211
- if (event.defaultPrevented) {
1212
- return;
1213
- }
1214
- switch (event.key) {
1215
- case "Enter":
1216
- {
1217
- event.preventDefault();
1218
- const index = panelDataArray.findIndex(panelData => panelData.id === idBefore);
1219
- if (index >= 0) {
1220
- const panelData = panelDataArray[index];
1221
- assert(panelData, `No panel data found for index ${index}`);
1222
- const size = layout[index];
1223
- const {
1224
- collapsedSize = 0,
1225
- collapsible,
1226
- minSize = 0
1227
- } = panelData.constraints;
1228
- if (size != null && collapsible) {
1229
- const nextLayout = adjustLayoutByDelta({
1230
- delta: fuzzyNumbersEqual(size, collapsedSize) ? minSize - collapsedSize : collapsedSize - size,
1231
- initialLayout: layout,
1232
- panelConstraints: panelDataArray.map(panelData => panelData.constraints),
1233
- pivotIndices: determinePivotIndices(groupId, handleId, panelGroupElement),
1234
- prevLayout: layout,
1235
- trigger: "keyboard"
1236
- });
1237
- if (layout !== nextLayout) {
1238
- setLayout(nextLayout);
1239
- }
1240
- }
1241
- }
1242
- break;
1243
- }
1244
- }
1245
- };
1246
- handle.addEventListener("keydown", onKeyDown);
1247
- return () => {
1248
- handle.removeEventListener("keydown", onKeyDown);
1249
- };
640
+ let i = 0;
641
+ for (let r = 0; r < t.length; r++) {
642
+ const l = o[r];
643
+ E(l != null, `No layout data found for index ${r}`);
644
+ const c = T({
645
+ panelConstraints: t[r],
646
+ size: l
1250
647
  });
1251
- return () => {
1252
- cleanupFunctions.forEach(cleanupFunction => cleanupFunction());
1253
- };
1254
- }, [panelGroupElement, committedValuesRef, eagerValuesRef, groupId, layout, panelDataArray, setLayout]);
1255
- }
1256
-
1257
- function areEqual(arrayA, arrayB) {
1258
- if (arrayA.length !== arrayB.length) {
1259
- return false;
648
+ l != c && (i += l - c, o[r] = c);
1260
649
  }
1261
- for (let index = 0; index < arrayA.length; index++) {
1262
- if (arrayA[index] !== arrayB[index]) {
1263
- return false;
1264
- }
1265
- }
1266
- return true;
1267
- }
1268
-
1269
- function getResizeEventCursorPosition(direction, event) {
1270
- const isHorizontal = direction === "horizontal";
1271
- const {
1272
- x,
1273
- y
1274
- } = getResizeEventCoordinates(event);
1275
- return isHorizontal ? x : y;
1276
- }
1277
-
1278
- function calculateDragOffsetPercentage(event, dragHandleId, direction, initialDragState, panelGroupElement) {
1279
- const isHorizontal = direction === "horizontal";
1280
- const handleElement = getResizeHandleElement(dragHandleId, panelGroupElement);
1281
- assert(handleElement, `No resize handle element found for id "${dragHandleId}"`);
1282
- const groupId = handleElement.getAttribute(DATA_ATTRIBUTES.groupId);
1283
- assert(groupId, `Resize handle element has no group id attribute`);
1284
- let {
1285
- initialCursorPosition
1286
- } = initialDragState;
1287
- const cursorPosition = getResizeEventCursorPosition(direction, event);
1288
- const groupElement = getPanelGroupElement(groupId, panelGroupElement);
1289
- assert(groupElement, `No group element found for id "${groupId}"`);
1290
- const groupRect = groupElement.getBoundingClientRect();
1291
- const groupSizeInPixels = isHorizontal ? groupRect.width : groupRect.height;
1292
- const offsetPixels = cursorPosition - initialCursorPosition;
1293
- const offsetPercentage = offsetPixels / groupSizeInPixels * 100;
1294
- return offsetPercentage;
1295
- }
1296
-
1297
- // https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/movementX
1298
- function calculateDeltaPercentage(event, dragHandleId, direction, initialDragState, keyboardResizeBy, panelGroupElement) {
1299
- if (isKeyDown(event)) {
1300
- const isHorizontal = direction === "horizontal";
1301
- let delta = 0;
1302
- if (event.shiftKey) {
1303
- delta = 100;
1304
- } else if (keyboardResizeBy != null) {
1305
- delta = keyboardResizeBy;
1306
- } else {
1307
- delta = 10;
1308
- }
1309
- let movement = 0;
1310
- switch (event.key) {
1311
- case "ArrowDown":
1312
- movement = isHorizontal ? 0 : delta;
1313
- break;
1314
- case "ArrowLeft":
1315
- movement = isHorizontal ? -delta : 0;
1316
- break;
1317
- case "ArrowRight":
1318
- movement = isHorizontal ? delta : 0;
1319
- break;
1320
- case "ArrowUp":
1321
- movement = isHorizontal ? 0 : -delta;
1322
- break;
1323
- case "End":
1324
- movement = 100;
1325
- break;
1326
- case "Home":
1327
- movement = -100;
650
+ if (!b(i, 0))
651
+ for (let r = 0; r < t.length; r++) {
652
+ const l = o[r];
653
+ E(l != null, `No layout data found for index ${r}`);
654
+ const c = l + i, u = T({
655
+ panelConstraints: t[r],
656
+ size: c
657
+ });
658
+ if (l !== u && (i -= u - l, o[r] = u, b(i, 0)))
1328
659
  break;
1329
660
  }
1330
- return movement;
1331
- } else {
1332
- if (initialDragState == null) {
1333
- return 0;
1334
- }
1335
- return calculateDragOffsetPercentage(event, dragHandleId, direction, initialDragState, panelGroupElement);
1336
- }
1337
- }
1338
-
1339
- function calculateUnsafeDefaultLayout({
1340
- panelDataArray
1341
- }) {
1342
- const layout = Array(panelDataArray.length);
1343
- const panelConstraintsArray = panelDataArray.map(panelData => panelData.constraints);
1344
- let numPanelsWithSizes = 0;
1345
- let remainingSize = 100;
1346
-
1347
- // Distribute default sizes first
1348
- for (let index = 0; index < panelDataArray.length; index++) {
1349
- const panelConstraints = panelConstraintsArray[index];
1350
- assert(panelConstraints, `Panel constraints not found for index ${index}`);
1351
- const {
1352
- defaultSize
1353
- } = panelConstraints;
1354
- if (defaultSize != null) {
1355
- numPanelsWithSizes++;
1356
- layout[index] = defaultSize;
1357
- remainingSize -= defaultSize;
1358
- }
1359
- }
1360
-
1361
- // Remaining size should be distributed evenly between panels without default sizes
1362
- for (let index = 0; index < panelDataArray.length; index++) {
1363
- const panelConstraints = panelConstraintsArray[index];
1364
- assert(panelConstraints, `Panel constraints not found for index ${index}`);
1365
- const {
1366
- defaultSize
1367
- } = panelConstraints;
1368
- if (defaultSize != null) {
1369
- continue;
661
+ const a = Object.keys(e);
662
+ return o.reduce((r, l, c) => (r[a[c]] = l, r), {});
663
+ }
664
+ function Ve(e) {
665
+ let t = !1;
666
+ const n = new ResizeObserver((l) => {
667
+ for (const c of l) {
668
+ const { borderBoxSize: u, target: f } = c;
669
+ f === e.element ? t && G((p) => {
670
+ const h = p.mountedGroups.get(e);
671
+ return h ? {
672
+ mountedGroups: new Map(p.mountedGroups).set(e, {
673
+ derivedPanelConstraints: ie(e),
674
+ layout: h.layout
675
+ })
676
+ } : p;
677
+ }) : Ke(e, f, u);
1370
678
  }
1371
- const numRemainingPanels = panelDataArray.length - numPanelsWithSizes;
1372
- const size = remainingSize / numRemainingPanels;
1373
- numPanelsWithSizes++;
1374
- layout[index] = size;
1375
- remainingSize -= size;
1376
- }
1377
- return layout;
679
+ });
680
+ n.observe(e.element), e.panels.forEach((l) => {
681
+ l.onResize && n.observe(l.element);
682
+ });
683
+ const o = ie(e), s = e.panels.map(({ id: l }) => l).join(","), i = e.inMemoryLayouts[s] ?? e.defaultLayout ?? Ue(o), a = ve({
684
+ layout: i,
685
+ panelConstraints: o
686
+ }), r = G((l) => ({
687
+ mountedGroups: new Map(l.mountedGroups).set(e, {
688
+ derivedPanelConstraints: o,
689
+ layout: a
690
+ })
691
+ }));
692
+ return t = !0, r.mountedGroups.size === 1 && (window.addEventListener("pointerdown", se), window.addEventListener("pointerleave", W), window.addEventListener("pointermove", W), window.addEventListener("pointerup", ae)), function() {
693
+ const c = G((u) => {
694
+ const f = new Map(u.mountedGroups);
695
+ return f.delete(e), { mountedGroups: f };
696
+ });
697
+ t = !1, c.mountedGroups.size === 0 && (window.removeEventListener("pointerdown", se), window.removeEventListener("pointerleave", W), window.removeEventListener("pointermove", W), window.removeEventListener("pointerup", ae)), n.disconnect();
698
+ };
1378
699
  }
1379
-
1380
- // Layout should be pre-converted into percentages
1381
- function callPanelCallbacks(panelsArray, layout, panelIdToLastNotifiedSizeMap) {
1382
- layout.forEach((size, index) => {
1383
- const panelData = panelsArray[index];
1384
- assert(panelData, `Panel data not found for index ${index}`);
1385
- const {
1386
- callbacks,
1387
- constraints,
1388
- id: panelId
1389
- } = panelData;
1390
- const {
1391
- collapsedSize = 0,
1392
- collapsible
1393
- } = constraints;
1394
- const lastNotifiedSize = panelIdToLastNotifiedSizeMap[panelId];
1395
- if (lastNotifiedSize == null || size !== lastNotifiedSize) {
1396
- panelIdToLastNotifiedSizeMap[panelId] = size;
1397
- const {
1398
- onCollapse,
1399
- onExpand,
1400
- onResize
1401
- } = callbacks;
1402
- if (onResize) {
1403
- onResize(size, lastNotifiedSize);
1404
- }
1405
- if (collapsible && (onCollapse || onExpand)) {
1406
- if (onExpand && (lastNotifiedSize == null || fuzzyNumbersEqual$1(lastNotifiedSize, collapsedSize)) && !fuzzyNumbersEqual$1(size, collapsedSize)) {
1407
- onExpand();
1408
- }
1409
- if (onCollapse && (lastNotifiedSize == null || !fuzzyNumbersEqual$1(lastNotifiedSize, collapsedSize)) && fuzzyNumbersEqual$1(size, collapsedSize)) {
1410
- onCollapse();
700
+ function J(e) {
701
+ const t = Re();
702
+ return `${e ?? t}`;
703
+ }
704
+ const D = typeof window < "u" ? Pe : Ce;
705
+ function Q(e) {
706
+ const t = I(e);
707
+ return D(() => {
708
+ t.current = e;
709
+ }, [e]), ce((n) => t.current?.(n), [t]);
710
+ }
711
+ function ee(...e) {
712
+ return Q((t) => {
713
+ e.forEach((n) => {
714
+ if (n)
715
+ switch (typeof n) {
716
+ case "function": {
717
+ n(t);
718
+ break;
719
+ }
720
+ case "object": {
721
+ n.current = t;
722
+ break;
723
+ }
1411
724
  }
1412
- }
1413
- }
725
+ });
1414
726
  });
1415
727
  }
1416
-
1417
- function compareLayouts(a, b) {
1418
- if (a.length !== b.length) {
1419
- return false;
1420
- } else {
1421
- for (let index = 0; index < a.length; index++) {
1422
- if (a[index] != b[index]) {
1423
- return false;
1424
- }
1425
- }
1426
- }
1427
- return true;
728
+ const ge = "--react-resizable-panels--panel--pointer-events";
729
+ function ye(e, t) {
730
+ const n = e.replace(/[^a-zA-Z0-9\-_]/g, ""), o = t.replace(/[^a-zA-Z0-9\-_]/g, "");
731
+ return `--react-resizable-panels--${n}--${o}`;
732
+ }
733
+ const Se = Ee(null);
734
+ function le(e, t) {
735
+ return t.sort(
736
+ e === "horizontal" ? (n, o) => n.element.offsetLeft - o.element.offsetLeft : (n, o) => n.element.offsetTop - o.element.offsetTop
737
+ );
1428
738
  }
1429
-
1430
- // This method returns a number between 1 and 100 representing
1431
-
1432
- // the % of the group's overall space this panel should occupy.
1433
- function computePanelFlexBoxStyle({
1434
- defaultSize,
1435
- dragState,
1436
- layout,
1437
- panelData,
1438
- panelIndex,
1439
- precision = 3
739
+ function Xe({
740
+ groupId: e
1440
741
  }) {
1441
- const size = layout[panelIndex];
1442
- let flexGrow;
1443
- if (size == null) {
1444
- // Initial render (before panels have registered themselves)
1445
- // In order to support server rendering, fall back to default size if provided
1446
- flexGrow = defaultSize != undefined ? defaultSize.toFixed(precision) : "1";
1447
- } else if (panelData.length === 1) {
1448
- // Special case: Single panel group should always fill full width/height
1449
- flexGrow = "1";
1450
- } else {
1451
- flexGrow = size.toFixed(precision);
1452
- }
1453
- return {
1454
- flexBasis: 0,
1455
- flexGrow,
1456
- flexShrink: 1,
1457
- // Without this, Panel sizes may be unintentionally overridden by their content
1458
- overflow: "hidden",
1459
- // Disable pointer events inside of a panel during resize
1460
- // This avoid edge cases like nested iframes
1461
- pointerEvents: dragState !== null ? "none" : undefined
742
+ const t = () => {
743
+ const { mountedGroups: n } = O();
744
+ for (const [o, { derivedPanelConstraints: s, layout: i }] of n)
745
+ if (o.id === e)
746
+ return { derivedPanelConstraints: s, group: o, layout: i };
747
+ throw Error(`Group ${e} not found`);
1462
748
  };
1463
- }
1464
-
1465
- function debounce(callback, durationMs = 10) {
1466
- let timeoutId = null;
1467
- let callable = (...args) => {
1468
- if (timeoutId !== null) {
1469
- clearTimeout(timeoutId);
749
+ return {
750
+ getLayout() {
751
+ const { layout: n } = t();
752
+ return n;
753
+ },
754
+ setLayout(n) {
755
+ const { derivedPanelConstraints: o, group: s, layout: i } = t(), a = ve({
756
+ layout: n,
757
+ panelConstraints: o
758
+ });
759
+ return q(i, a) || G((r) => ({
760
+ mountedGroups: new Map(r.mountedGroups).set(s, {
761
+ derivedPanelConstraints: o,
762
+ layout: a
763
+ })
764
+ })), a;
1470
765
  }
1471
- timeoutId = setTimeout(() => {
1472
- callback(...args);
1473
- }, durationMs);
1474
766
  };
1475
- return callable;
1476
767
  }
1477
-
1478
- // PanelGroup might be rendering in a server-side environment where localStorage is not available
1479
- // or on a browser with cookies/storage disabled.
1480
- // In either case, this function avoids accessing localStorage until needed,
1481
- // and avoids throwing user-visible errors.
1482
- function initializeDefaultStorage(storageObject) {
1483
- try {
1484
- if (typeof localStorage !== "undefined") {
1485
- // Bypass this check for future calls
1486
- storageObject.getItem = name => {
1487
- return localStorage.getItem(name);
1488
- };
1489
- storageObject.setItem = (name, value) => {
1490
- localStorage.setItem(name, value);
768
+ function Ye(e, t) {
769
+ const n = I({
770
+ getLayout: () => ({}),
771
+ setLayout: Te
772
+ });
773
+ ue(t, () => n.current, []), D(() => {
774
+ Object.assign(
775
+ n.current,
776
+ Xe({ groupId: e })
777
+ );
778
+ });
779
+ }
780
+ function nt({
781
+ children: e,
782
+ className: t,
783
+ defaultLayout: n,
784
+ direction: o = "horizontal",
785
+ disableCursor: s,
786
+ disabled: i,
787
+ elementRef: a,
788
+ groupRef: r,
789
+ id: l,
790
+ onLayoutChange: c,
791
+ style: u
792
+ }) {
793
+ const f = I({}), p = Q((g) => {
794
+ q(f.current, g) || (f.current = g, c?.(g));
795
+ }), h = J(l), [m, d] = M(!1), [v, S] = M(null), x = I({}), [z, y] = M(n ?? {}), [R, k] = M([]), [A, ne] = M([]), ze = ee(S, a);
796
+ Ye(h, r);
797
+ const we = Me(
798
+ () => ({
799
+ direction: o,
800
+ id: h,
801
+ registerPanel: (g) => (k((w) => le(o, [...w, g])), () => {
802
+ k((w) => w.filter((N) => N !== g));
803
+ }),
804
+ registerSeparator: (g) => (ne(
805
+ (w) => le(o, [...w, g])
806
+ ), () => {
807
+ ne(
808
+ (w) => w.filter((N) => N !== g)
809
+ );
810
+ })
811
+ }),
812
+ [o, h]
813
+ );
814
+ D(() => {
815
+ if (v !== null && R.length > 0) {
816
+ const g = {
817
+ defaultLayout: n,
818
+ direction: o,
819
+ disableCursor: !!s,
820
+ disabled: !!i,
821
+ element: v,
822
+ id: h,
823
+ inMemoryLayouts: x.current,
824
+ panels: R,
825
+ separators: A
826
+ }, w = Ve(g), U = O().mountedGroups.get(g);
827
+ U && (y(U.layout), p?.(U.layout));
828
+ const be = _.addListener(
829
+ "interactionStateChange",
830
+ (j) => {
831
+ switch (j.state) {
832
+ case "active":
833
+ case "hover": {
834
+ d(
835
+ j.hitRegions.some(
836
+ ($) => $.group === g
837
+ )
838
+ );
839
+ break;
840
+ }
841
+ }
842
+ }
843
+ ), Le = _.addListener(
844
+ "mountedGroupsChange",
845
+ (j) => {
846
+ const $ = j.get(g);
847
+ $ && $.derivedPanelConstraints.length > 0 && (y($.layout), p?.($.layout));
848
+ }
849
+ );
850
+ return () => {
851
+ w(), be(), Le();
1491
852
  };
1492
- } else {
1493
- throw new Error("localStorage not supported in this environment");
1494
853
  }
1495
- } catch (error) {
1496
- console.error(error);
1497
- storageObject.getItem = () => null;
1498
- storageObject.setItem = () => {};
854
+ }, [
855
+ n,
856
+ o,
857
+ s,
858
+ i,
859
+ v,
860
+ h,
861
+ p,
862
+ R,
863
+ A
864
+ ]);
865
+ const oe = {
866
+ [ge]: m ? "none" : void 0
867
+ };
868
+ for (const g in z) {
869
+ const w = ye(h, g), N = z[g];
870
+ oe[w] = N;
1499
871
  }
1500
- }
1501
-
1502
- function getPanelGroupKey(autoSaveId) {
1503
- return `react-resizable-panels:${autoSaveId}`;
1504
- }
1505
-
1506
- // Note that Panel ids might be user-provided (stable) or useId generated (non-deterministic)
1507
- // so they should not be used as part of the serialization key.
1508
- // Using the min/max size attributes should work well enough as a backup.
1509
- // Pre-sorting by minSize allows remembering layouts even if panels are re-ordered/dragged.
1510
- function getPanelKey(panels) {
1511
- return panels.map(panel => {
1512
- const {
1513
- constraints,
1514
- id,
1515
- idIsFromProps,
1516
- order
1517
- } = panel;
1518
- if (idIsFromProps) {
1519
- return id;
1520
- } else {
1521
- return order ? `${order}:${JSON.stringify(constraints)}` : JSON.stringify(constraints);
872
+ return /* @__PURE__ */ F(Se.Provider, { value: we, children: /* @__PURE__ */ F(
873
+ "div",
874
+ {
875
+ className: t,
876
+ "data-group": !0,
877
+ "data-group-id": h,
878
+ "data-group-direction": o,
879
+ ref: ze,
880
+ style: {
881
+ ...u,
882
+ ...oe,
883
+ display: "flex",
884
+ flexDirection: o === "horizontal" ? "row" : "column",
885
+ flexWrap: "nowrap",
886
+ overflow: "hidden"
887
+ },
888
+ children: e
1522
889
  }
1523
- }).sort((a, b) => a.localeCompare(b)).join(",");
890
+ ) });
1524
891
  }
1525
- function loadSerializedPanelGroupState(autoSaveId, storage) {
1526
- try {
1527
- const panelGroupKey = getPanelGroupKey(autoSaveId);
1528
- const serialized = storage.getItem(panelGroupKey);
1529
- if (serialized) {
1530
- const parsed = JSON.parse(serialized);
1531
- if (typeof parsed === "object" && parsed != null) {
1532
- return parsed;
1533
- }
1534
- }
1535
- } catch (error) {}
1536
- return null;
1537
- }
1538
- function loadPanelGroupState(autoSaveId, panels, storage) {
1539
- var _loadSerializedPanelG, _state$panelKey;
1540
- const state = (_loadSerializedPanelG = loadSerializedPanelGroupState(autoSaveId, storage)) !== null && _loadSerializedPanelG !== void 0 ? _loadSerializedPanelG : {};
1541
- const panelKey = getPanelKey(panels);
1542
- return (_state$panelKey = state[panelKey]) !== null && _state$panelKey !== void 0 ? _state$panelKey : null;
892
+ function xe(e) {
893
+ return `react-resizable-panels:${e}`;
1543
894
  }
1544
- function savePanelGroupState(autoSaveId, panels, panelSizesBeforeCollapse, sizes, storage) {
1545
- var _loadSerializedPanelG2;
1546
- const panelGroupKey = getPanelGroupKey(autoSaveId);
1547
- const panelKey = getPanelKey(panels);
1548
- const state = (_loadSerializedPanelG2 = loadSerializedPanelGroupState(autoSaveId, storage)) !== null && _loadSerializedPanelG2 !== void 0 ? _loadSerializedPanelG2 : {};
1549
- state[panelKey] = {
1550
- expandToSizes: Object.fromEntries(panelSizesBeforeCollapse.entries()),
1551
- layout: sizes
1552
- };
895
+ function Ze({
896
+ id: e,
897
+ storage: t
898
+ }) {
1553
899
  try {
1554
- storage.setItem(panelGroupKey, JSON.stringify(state));
1555
- } catch (error) {
1556
- console.error(error);
900
+ const n = xe(e), o = t.getItem(n);
901
+ if (o)
902
+ return JSON.parse(o);
903
+ } catch (n) {
904
+ console.error(n);
1557
905
  }
1558
906
  }
1559
-
1560
- // All units must be in percentages; pixel values should be pre-converted
1561
- function validatePanelGroupLayout({
1562
- layout: prevLayout,
1563
- panelConstraints
907
+ function qe({
908
+ id: e,
909
+ layout: t,
910
+ storage: n
1564
911
  }) {
1565
- const nextLayout = [...prevLayout];
1566
- const nextLayoutTotalSize = nextLayout.reduce((accumulated, current) => accumulated + current, 0);
1567
-
1568
- // Validate layout expectations
1569
- if (nextLayout.length !== panelConstraints.length) {
1570
- throw Error(`Invalid ${panelConstraints.length} panel layout: ${nextLayout.map(size => `${size}%`).join(", ")}`);
1571
- } else if (!fuzzyNumbersEqual(nextLayoutTotalSize, 100) && nextLayout.length > 0) {
1572
- for (let index = 0; index < panelConstraints.length; index++) {
1573
- const unsafeSize = nextLayout[index];
1574
- assert(unsafeSize != null, `No layout data found for index ${index}`);
1575
- const safeSize = 100 / nextLayoutTotalSize * unsafeSize;
1576
- nextLayout[index] = safeSize;
1577
- }
1578
- }
1579
- let remainingSize = 0;
1580
-
1581
- // First pass: Validate the proposed layout given each panel's constraints
1582
- for (let index = 0; index < panelConstraints.length; index++) {
1583
- const unsafeSize = nextLayout[index];
1584
- assert(unsafeSize != null, `No layout data found for index ${index}`);
1585
- const safeSize = resizePanel({
1586
- panelConstraints,
1587
- panelIndex: index,
1588
- size: unsafeSize
1589
- });
1590
- if (unsafeSize != safeSize) {
1591
- remainingSize += unsafeSize - safeSize;
1592
- nextLayout[index] = safeSize;
1593
- }
1594
- }
1595
-
1596
- // If there is additional, left over space, assign it to any panel(s) that permits it
1597
- // (It's not worth taking multiple additional passes to evenly distribute)
1598
- if (!fuzzyNumbersEqual(remainingSize, 0)) {
1599
- for (let index = 0; index < panelConstraints.length; index++) {
1600
- const prevSize = nextLayout[index];
1601
- assert(prevSize != null, `No layout data found for index ${index}`);
1602
- const unsafeSize = prevSize + remainingSize;
1603
- const safeSize = resizePanel({
1604
- panelConstraints,
1605
- panelIndex: index,
1606
- size: unsafeSize
1607
- });
1608
- if (prevSize !== safeSize) {
1609
- remainingSize -= safeSize - prevSize;
1610
- nextLayout[index] = safeSize;
1611
-
1612
- // Once we've used up the remainder, bail
1613
- if (fuzzyNumbersEqual(remainingSize, 0)) {
1614
- break;
1615
- }
1616
- }
1617
- }
912
+ try {
913
+ const o = xe(e);
914
+ n.setItem(o, JSON.stringify(t));
915
+ } catch (o) {
916
+ console.error(o);
1618
917
  }
1619
- return nextLayout;
1620
918
  }
1621
-
1622
- const LOCAL_STORAGE_DEBOUNCE_INTERVAL = 100;
1623
- const defaultStorage = {
1624
- getItem: name => {
1625
- initializeDefaultStorage(defaultStorage);
1626
- return defaultStorage.getItem(name);
1627
- },
1628
- setItem: (name, value) => {
1629
- initializeDefaultStorage(defaultStorage);
1630
- defaultStorage.setItem(name, value);
1631
- }
1632
- };
1633
- const debounceMap = {};
1634
- function PanelGroupWithForwardedRef({
1635
- autoSaveId = null,
1636
- children,
1637
- className: classNameFromProps = "",
1638
- direction,
1639
- forwardedRef,
1640
- id: idFromProps = null,
1641
- onLayout = null,
1642
- keyboardResizeBy = null,
1643
- storage = defaultStorage,
1644
- style: styleFromProps,
1645
- tagName: Type = "div",
1646
- ...rest
919
+ function ot({
920
+ groupId: e,
921
+ storage: t = localStorage
1647
922
  }) {
1648
- const groupId = useUniqueId(idFromProps);
1649
- const panelGroupElementRef = useRef(null);
1650
- const [dragState, setDragState] = useState(null);
1651
- const [layout, setLayout] = useState([]);
1652
- const forceUpdate = useForceUpdate();
1653
- const panelIdToLastNotifiedSizeMapRef = useRef({});
1654
- const panelSizeBeforeCollapseRef = useRef(new Map());
1655
- const prevDeltaRef = useRef(0);
1656
- const committedValuesRef = useRef({
1657
- autoSaveId,
1658
- direction,
1659
- dragState,
1660
- id: groupId,
1661
- keyboardResizeBy,
1662
- onLayout,
1663
- storage
1664
- });
1665
- const eagerValuesRef = useRef({
1666
- layout,
1667
- panelDataArray: [],
1668
- panelDataArrayChanged: false
1669
- });
1670
- useRef({
1671
- didLogIdAndOrderWarning: false,
1672
- didLogPanelConstraintsWarning: false,
1673
- prevPanelIds: []
1674
- });
1675
- useImperativeHandle(forwardedRef, () => ({
1676
- getId: () => committedValuesRef.current.id,
1677
- getLayout: () => {
1678
- const {
1679
- layout
1680
- } = eagerValuesRef.current;
1681
- return layout;
923
+ const n = I(null);
924
+ n.current === null && (n.current = Ze({
925
+ id: e,
926
+ storage: t
927
+ }));
928
+ const o = ce(
929
+ (s) => qe({
930
+ id: e,
931
+ layout: s,
932
+ storage: t
933
+ }),
934
+ [e, t]
935
+ );
936
+ return {
937
+ defaultLayout: n.current,
938
+ onLayoutChange: o
939
+ };
940
+ }
941
+ function it() {
942
+ return M(null);
943
+ }
944
+ function rt() {
945
+ return I(null);
946
+ }
947
+ function te() {
948
+ const e = Ge(Se);
949
+ return E(e, "Unexpected"), e;
950
+ }
951
+ function Je({
952
+ groupId: e,
953
+ panelId: t
954
+ }) {
955
+ const n = () => {
956
+ const { mountedGroups: a } = O();
957
+ for (const [r, { derivedPanelConstraints: l, layout: c }] of a)
958
+ if (r.id === e)
959
+ return { derivedPanelConstraints: l, group: r, layout: c };
960
+ throw Error(`Group ${e} not found`);
961
+ }, o = () => {
962
+ const a = n().derivedPanelConstraints.find(
963
+ (r) => r.panelId === t
964
+ );
965
+ if (a !== void 0)
966
+ return a;
967
+ throw Error(`Panel constraints not found for Panel ${t}`);
968
+ }, s = () => {
969
+ const a = n().group.panels.find((r) => r.id === t);
970
+ if (a !== void 0)
971
+ return a;
972
+ throw Error(`Layout not found for Panel ${t}`);
973
+ }, i = () => {
974
+ const a = n().layout[t];
975
+ if (a !== void 0)
976
+ return a;
977
+ throw Error(`Layout not found for Panel ${t}`);
978
+ };
979
+ return {
980
+ collapse: () => {
981
+ const { collapsible: a, collapsedSize: r } = o();
982
+ i();
1682
983
  },
1683
- setLayout: unsafeLayout => {
1684
- const {
1685
- onLayout
1686
- } = committedValuesRef.current;
1687
- const {
1688
- layout: prevLayout,
1689
- panelDataArray
1690
- } = eagerValuesRef.current;
1691
- const safeLayout = validatePanelGroupLayout({
1692
- layout: unsafeLayout,
1693
- panelConstraints: panelDataArray.map(panelData => panelData.constraints)
1694
- });
1695
- if (!areEqual(prevLayout, safeLayout)) {
1696
- setLayout(safeLayout);
1697
- eagerValuesRef.current.layout = safeLayout;
1698
- if (onLayout) {
1699
- onLayout(safeLayout);
984
+ expand: () => {
985
+ const { collapsible: a, collapsedSize: r, minSize: l } = o();
986
+ i();
987
+ },
988
+ getSize: () => {
989
+ const { group: a } = n(), r = i(), { element: l } = s(), c = a.direction === "horizontal" ? l.offsetWidth : l.offsetHeight;
990
+ return {
991
+ asPercentage: r,
992
+ inPixels: c
993
+ };
994
+ },
995
+ isCollapsed: () => {
996
+ const { collapsible: a, collapsedSize: r } = o(), l = i();
997
+ return a && b(r, l);
998
+ },
999
+ resize: (a) => {
1000
+ if (i() !== a)
1001
+ switch (typeof a) {
1002
+ case "number": {
1003
+ const { group: l } = n(), c = Z({ group: l });
1004
+ L(a / c * 100);
1005
+ break;
1006
+ }
1700
1007
  }
1701
- callPanelCallbacks(panelDataArray, safeLayout, panelIdToLastNotifiedSizeMapRef.current);
1702
- }
1703
1008
  }
1704
- }), []);
1705
- useIsomorphicLayoutEffect(() => {
1706
- committedValuesRef.current.autoSaveId = autoSaveId;
1707
- committedValuesRef.current.direction = direction;
1708
- committedValuesRef.current.dragState = dragState;
1709
- committedValuesRef.current.id = groupId;
1710
- committedValuesRef.current.onLayout = onLayout;
1711
- committedValuesRef.current.storage = storage;
1009
+ };
1010
+ }
1011
+ function Qe(e, t) {
1012
+ const { id: n } = te(), o = I({
1013
+ collapse: K,
1014
+ expand: K,
1015
+ getSize: () => ({
1016
+ asPercentage: 0,
1017
+ inPixels: 0
1018
+ }),
1019
+ isCollapsed: () => !1,
1020
+ resize: K
1712
1021
  });
1713
- useWindowSplitterPanelGroupBehavior({
1714
- committedValuesRef,
1715
- eagerValuesRef,
1716
- groupId,
1717
- layout,
1718
- panelDataArray: eagerValuesRef.current.panelDataArray,
1719
- setLayout,
1720
- panelGroupElement: panelGroupElementRef.current
1022
+ ue(t, () => o.current, []), D(() => {
1023
+ Object.assign(
1024
+ o.current,
1025
+ Je({ groupId: n, panelId: e })
1026
+ );
1721
1027
  });
1722
- useEffect(() => {
1723
- const {
1724
- panelDataArray
1725
- } = eagerValuesRef.current;
1726
-
1727
- // If this panel has been configured to persist sizing information, save sizes to local storage.
1728
- if (autoSaveId) {
1729
- if (layout.length === 0 || layout.length !== panelDataArray.length) {
1730
- return;
1731
- }
1732
- let debouncedSave = debounceMap[autoSaveId];
1733
-
1734
- // Limit the frequency of localStorage updates.
1735
- if (debouncedSave == null) {
1736
- debouncedSave = debounce(savePanelGroupState, LOCAL_STORAGE_DEBOUNCE_INTERVAL);
1737
- debounceMap[autoSaveId] = debouncedSave;
1738
- }
1739
-
1740
- // Clone mutable data before passing to the debounced function,
1741
- // else we run the risk of saving an incorrect combination of mutable and immutable values to state.
1742
- const clonedPanelDataArray = [...panelDataArray];
1743
- const clonedPanelSizesBeforeCollapse = new Map(panelSizeBeforeCollapseRef.current);
1744
- debouncedSave(autoSaveId, clonedPanelDataArray, clonedPanelSizesBeforeCollapse, layout, storage);
1745
- }
1746
- }, [autoSaveId, layout, storage]);
1747
-
1748
- // DEV warnings
1749
- useEffect(() => {
1028
+ }
1029
+ function st({
1030
+ children: e,
1031
+ className: t,
1032
+ collapsedSize: n = 0,
1033
+ collapsible: o = !1,
1034
+ defaultSize: s,
1035
+ elementRef: i,
1036
+ id: a,
1037
+ maxSize: r = "100",
1038
+ minSize: l = "0",
1039
+ onResize: c,
1040
+ panelRef: u,
1041
+ style: f
1042
+ }) {
1043
+ const p = !!a, h = J(a), [m, d] = M(null), v = ee(d, i), { id: S, registerPanel: x } = te(), z = c !== null, y = Q((k) => {
1044
+ c?.(k);
1750
1045
  });
1751
-
1752
- // External APIs are safe to memoize via committed values ref
1753
- const collapsePanel = useCallback(panelData => {
1754
- const {
1755
- onLayout
1756
- } = committedValuesRef.current;
1757
- const {
1758
- layout: prevLayout,
1759
- panelDataArray
1760
- } = eagerValuesRef.current;
1761
- if (panelData.constraints.collapsible) {
1762
- const panelConstraintsArray = panelDataArray.map(panelData => panelData.constraints);
1763
- const {
1764
- collapsedSize = 0,
1765
- panelSize,
1766
- pivotIndices
1767
- } = panelDataHelper(panelDataArray, panelData, prevLayout);
1768
- assert(panelSize != null, `Panel size not found for panel "${panelData.id}"`);
1769
- if (!fuzzyNumbersEqual$1(panelSize, collapsedSize)) {
1770
- // Store size before collapse;
1771
- // This is the size that gets restored if the expand() API is used.
1772
- panelSizeBeforeCollapseRef.current.set(panelData.id, panelSize);
1773
- const isLastPanel = findPanelDataIndex(panelDataArray, panelData) === panelDataArray.length - 1;
1774
- const delta = isLastPanel ? panelSize - collapsedSize : collapsedSize - panelSize;
1775
- const nextLayout = adjustLayoutByDelta({
1776
- delta,
1777
- initialLayout: prevLayout,
1778
- panelConstraints: panelConstraintsArray,
1779
- pivotIndices,
1780
- prevLayout,
1781
- trigger: "imperative-api"
1782
- });
1783
- if (!compareLayouts(prevLayout, nextLayout)) {
1784
- setLayout(nextLayout);
1785
- eagerValuesRef.current.layout = nextLayout;
1786
- if (onLayout) {
1787
- onLayout(nextLayout);
1788
- }
1789
- callPanelCallbacks(panelDataArray, nextLayout, panelIdToLastNotifiedSizeMapRef.current);
1790
- }
1791
- }
1792
- }
1793
- }, []);
1794
-
1795
- // External APIs are safe to memoize via committed values ref
1796
- const expandPanel = useCallback((panelData, minSizeOverride) => {
1797
- const {
1798
- onLayout
1799
- } = committedValuesRef.current;
1800
- const {
1801
- layout: prevLayout,
1802
- panelDataArray
1803
- } = eagerValuesRef.current;
1804
- if (panelData.constraints.collapsible) {
1805
- const panelConstraintsArray = panelDataArray.map(panelData => panelData.constraints);
1806
- const {
1807
- collapsedSize = 0,
1808
- panelSize = 0,
1809
- minSize: minSizeFromProps = 0,
1810
- pivotIndices
1811
- } = panelDataHelper(panelDataArray, panelData, prevLayout);
1812
- const minSize = minSizeOverride !== null && minSizeOverride !== void 0 ? minSizeOverride : minSizeFromProps;
1813
- if (fuzzyNumbersEqual$1(panelSize, collapsedSize)) {
1814
- // Restore this panel to the size it was before it was collapsed, if possible.
1815
- const prevPanelSize = panelSizeBeforeCollapseRef.current.get(panelData.id);
1816
- const baseSize = prevPanelSize != null && prevPanelSize >= minSize ? prevPanelSize : minSize;
1817
- const isLastPanel = findPanelDataIndex(panelDataArray, panelData) === panelDataArray.length - 1;
1818
- const delta = isLastPanel ? panelSize - baseSize : baseSize - panelSize;
1819
- const nextLayout = adjustLayoutByDelta({
1820
- delta,
1821
- initialLayout: prevLayout,
1822
- panelConstraints: panelConstraintsArray,
1823
- pivotIndices,
1824
- prevLayout,
1825
- trigger: "imperative-api"
1826
- });
1827
- if (!compareLayouts(prevLayout, nextLayout)) {
1828
- setLayout(nextLayout);
1829
- eagerValuesRef.current.layout = nextLayout;
1830
- if (onLayout) {
1831
- onLayout(nextLayout);
1832
- }
1833
- callPanelCallbacks(panelDataArray, nextLayout, panelIdToLastNotifiedSizeMapRef.current);
1834
- }
1835
- }
1836
- }
1837
- }, []);
1838
-
1839
- // External APIs are safe to memoize via committed values ref
1840
- const getPanelSize = useCallback(panelData => {
1841
- const {
1842
- layout,
1843
- panelDataArray
1844
- } = eagerValuesRef.current;
1845
- const {
1846
- panelSize
1847
- } = panelDataHelper(panelDataArray, panelData, layout);
1848
- assert(panelSize != null, `Panel size not found for panel "${panelData.id}"`);
1849
- return panelSize;
1850
- }, []);
1851
-
1852
- // This API should never read from committedValuesRef
1853
- const getPanelStyle = useCallback((panelData, defaultSize) => {
1854
- const {
1855
- panelDataArray
1856
- } = eagerValuesRef.current;
1857
- const panelIndex = findPanelDataIndex(panelDataArray, panelData);
1858
- return computePanelFlexBoxStyle({
1859
- defaultSize,
1860
- dragState,
1861
- layout,
1862
- panelData: panelDataArray,
1863
- panelIndex
1864
- });
1865
- }, [dragState, layout]);
1866
-
1867
- // External APIs are safe to memoize via committed values ref
1868
- const isPanelCollapsed = useCallback(panelData => {
1869
- const {
1870
- layout,
1871
- panelDataArray
1872
- } = eagerValuesRef.current;
1873
- const {
1874
- collapsedSize = 0,
1875
- collapsible,
1876
- panelSize
1877
- } = panelDataHelper(panelDataArray, panelData, layout);
1878
- assert(panelSize != null, `Panel size not found for panel "${panelData.id}"`);
1879
- return collapsible === true && fuzzyNumbersEqual$1(panelSize, collapsedSize);
1880
- }, []);
1881
-
1882
- // External APIs are safe to memoize via committed values ref
1883
- const isPanelExpanded = useCallback(panelData => {
1884
- const {
1885
- layout,
1886
- panelDataArray
1887
- } = eagerValuesRef.current;
1888
- const {
1889
- collapsedSize = 0,
1890
- collapsible,
1891
- panelSize
1892
- } = panelDataHelper(panelDataArray, panelData, layout);
1893
- assert(panelSize != null, `Panel size not found for panel "${panelData.id}"`);
1894
- return !collapsible || fuzzyCompareNumbers(panelSize, collapsedSize) > 0;
1895
- }, []);
1896
- const registerPanel = useCallback(panelData => {
1897
- const {
1898
- panelDataArray
1899
- } = eagerValuesRef.current;
1900
- panelDataArray.push(panelData);
1901
- panelDataArray.sort((panelA, panelB) => {
1902
- const orderA = panelA.order;
1903
- const orderB = panelB.order;
1904
- if (orderA == null && orderB == null) {
1905
- return 0;
1906
- } else if (orderA == null) {
1907
- return -1;
1908
- } else if (orderB == null) {
1909
- return 1;
1910
- } else {
1911
- return orderA - orderB;
1912
- }
1913
- });
1914
- eagerValuesRef.current.panelDataArrayChanged = true;
1915
- forceUpdate();
1916
- }, [forceUpdate]);
1917
-
1918
- // (Re)calculate group layout whenever panels are registered or unregistered.
1919
- // eslint-disable-next-line react-hooks/exhaustive-deps
1920
- useIsomorphicLayoutEffect(() => {
1921
- if (eagerValuesRef.current.panelDataArrayChanged) {
1922
- eagerValuesRef.current.panelDataArrayChanged = false;
1923
- const {
1924
- autoSaveId,
1925
- onLayout,
1926
- storage
1927
- } = committedValuesRef.current;
1928
- const {
1929
- layout: prevLayout,
1930
- panelDataArray
1931
- } = eagerValuesRef.current;
1932
-
1933
- // If this panel has been configured to persist sizing information,
1934
- // default size should be restored from local storage if possible.
1935
- let unsafeLayout = null;
1936
- if (autoSaveId) {
1937
- const state = loadPanelGroupState(autoSaveId, panelDataArray, storage);
1938
- if (state) {
1939
- panelSizeBeforeCollapseRef.current = new Map(Object.entries(state.expandToSizes));
1940
- unsafeLayout = state.layout;
1046
+ D(() => {
1047
+ if (m !== null)
1048
+ return x({
1049
+ element: m,
1050
+ id: h,
1051
+ idIsStable: p,
1052
+ onResize: z ? y : void 0,
1053
+ panelConstraints: {
1054
+ collapsedSize: n,
1055
+ collapsible: o,
1056
+ defaultSize: s,
1057
+ maxSize: r,
1058
+ minSize: l
1941
1059
  }
1942
- }
1943
- if (unsafeLayout == null) {
1944
- unsafeLayout = calculateUnsafeDefaultLayout({
1945
- panelDataArray
1946
- });
1947
- }
1948
-
1949
- // Validate even saved layouts in case something has changed since last render
1950
- // e.g. for pixel groups, this could be the size of the window
1951
- const nextLayout = validatePanelGroupLayout({
1952
- layout: unsafeLayout,
1953
- panelConstraints: panelDataArray.map(panelData => panelData.constraints)
1954
1060
  });
1955
- if (!areEqual(prevLayout, nextLayout)) {
1956
- setLayout(nextLayout);
1957
- eagerValuesRef.current.layout = nextLayout;
1958
- if (onLayout) {
1959
- onLayout(nextLayout);
1061
+ }, [
1062
+ n,
1063
+ o,
1064
+ s,
1065
+ m,
1066
+ z,
1067
+ h,
1068
+ p,
1069
+ r,
1070
+ l,
1071
+ y,
1072
+ x
1073
+ ]), Qe(h, u);
1074
+ const R = ye(S, h);
1075
+ return /* @__PURE__ */ F(
1076
+ "div",
1077
+ {
1078
+ "data-panel": !0,
1079
+ "data-panel-id": h,
1080
+ ref: v,
1081
+ style: {
1082
+ flexBasis: 0,
1083
+ flexGrow: `var(${R}, 1)`,
1084
+ flexShrink: 1,
1085
+ // Prevent Panel content from interfering with panel size
1086
+ overflow: "hidden",
1087
+ // Disable pointer events inside of a panel during resize
1088
+ // This avoid edge cases like nested iframes
1089
+ pointerEvents: `var(${ge})`
1090
+ },
1091
+ children: /* @__PURE__ */ F(
1092
+ "div",
1093
+ {
1094
+ className: t,
1095
+ style: {
1096
+ width: "100%",
1097
+ height: "100%",
1098
+ ...f
1099
+ },
1100
+ children: e
1960
1101
  }
1961
- callPanelCallbacks(panelDataArray, nextLayout, panelIdToLastNotifiedSizeMapRef.current);
1962
- }
1102
+ )
1963
1103
  }
1964
- });
1965
-
1966
- // Reset the cached layout if hidden by the Activity/Offscreen API
1967
- useIsomorphicLayoutEffect(() => {
1968
- const eagerValues = eagerValuesRef.current;
1969
- return () => {
1970
- eagerValues.layout = [];
1971
- };
1972
- }, []);
1973
- const registerResizeHandle = useCallback(dragHandleId => {
1974
- let isRTL = false;
1975
- const panelGroupElement = panelGroupElementRef.current;
1976
- if (panelGroupElement) {
1977
- const style = window.getComputedStyle(panelGroupElement, null);
1978
- if (style.getPropertyValue("direction") === "rtl") {
1979
- isRTL = true;
1980
- }
1981
- }
1982
- return function resizeHandler(event) {
1983
- event.preventDefault();
1984
- const panelGroupElement = panelGroupElementRef.current;
1985
- if (!panelGroupElement) {
1986
- return () => null;
1987
- }
1988
- const {
1989
- direction,
1990
- dragState,
1991
- id: groupId,
1992
- keyboardResizeBy,
1993
- onLayout
1994
- } = committedValuesRef.current;
1995
- const {
1996
- layout: prevLayout,
1997
- panelDataArray
1998
- } = eagerValuesRef.current;
1999
- const {
2000
- initialLayout
2001
- } = dragState !== null && dragState !== void 0 ? dragState : {};
2002
- const pivotIndices = determinePivotIndices(groupId, dragHandleId, panelGroupElement);
2003
- let delta = calculateDeltaPercentage(event, dragHandleId, direction, dragState, keyboardResizeBy, panelGroupElement);
2004
- const isHorizontal = direction === "horizontal";
2005
- if (isHorizontal && isRTL) {
2006
- delta = -delta;
2007
- }
2008
- const panelConstraints = panelDataArray.map(panelData => panelData.constraints);
2009
- const nextLayout = adjustLayoutByDelta({
2010
- delta,
2011
- initialLayout: initialLayout !== null && initialLayout !== void 0 ? initialLayout : prevLayout,
2012
- panelConstraints,
2013
- pivotIndices,
2014
- prevLayout,
2015
- trigger: isKeyDown(event) ? "keyboard" : "mouse-or-touch"
2016
- });
2017
- const layoutChanged = !compareLayouts(prevLayout, nextLayout);
2018
-
2019
- // Only update the cursor for layout changes triggered by touch/mouse events (not keyboard)
2020
- // Update the cursor even if the layout hasn't changed (we may need to show an invalid cursor state)
2021
- if (isPointerEvent(event) || isMouseEvent(event)) {
2022
- // Watch for multiple subsequent deltas; this might occur for tiny cursor movements.
2023
- // In this case, Panel sizes might not change–
2024
- // but updating cursor in this scenario would cause a flicker.
2025
- if (prevDeltaRef.current != delta) {
2026
- prevDeltaRef.current = delta;
2027
- if (!layoutChanged && delta !== 0) {
2028
- // If the pointer has moved too far to resize the panel any further, note this so we can update the cursor.
2029
- // This mimics VS Code behavior.
2030
- if (isHorizontal) {
2031
- reportConstraintsViolation(dragHandleId, delta < 0 ? EXCEEDED_HORIZONTAL_MIN : EXCEEDED_HORIZONTAL_MAX);
2032
- } else {
2033
- reportConstraintsViolation(dragHandleId, delta < 0 ? EXCEEDED_VERTICAL_MIN : EXCEEDED_VERTICAL_MAX);
2034
- }
2035
- } else {
2036
- reportConstraintsViolation(dragHandleId, 0);
2037
- }
2038
- }
2039
- }
2040
- if (layoutChanged) {
2041
- setLayout(nextLayout);
2042
- eagerValuesRef.current.layout = nextLayout;
2043
- if (onLayout) {
2044
- onLayout(nextLayout);
2045
- }
2046
- callPanelCallbacks(panelDataArray, nextLayout, panelIdToLastNotifiedSizeMapRef.current);
2047
- }
2048
- };
2049
- }, []);
2050
-
2051
- // External APIs are safe to memoize via committed values ref
2052
- const resizePanel = useCallback((panelData, unsafePanelSize) => {
2053
- const {
2054
- onLayout
2055
- } = committedValuesRef.current;
2056
- const {
2057
- layout: prevLayout,
2058
- panelDataArray
2059
- } = eagerValuesRef.current;
2060
- const panelConstraintsArray = panelDataArray.map(panelData => panelData.constraints);
2061
- const {
2062
- panelSize,
2063
- pivotIndices
2064
- } = panelDataHelper(panelDataArray, panelData, prevLayout);
2065
- assert(panelSize != null, `Panel size not found for panel "${panelData.id}"`);
2066
- const isLastPanel = findPanelDataIndex(panelDataArray, panelData) === panelDataArray.length - 1;
2067
- const delta = isLastPanel ? panelSize - unsafePanelSize : unsafePanelSize - panelSize;
2068
- const nextLayout = adjustLayoutByDelta({
2069
- delta,
2070
- initialLayout: prevLayout,
2071
- panelConstraints: panelConstraintsArray,
2072
- pivotIndices,
2073
- prevLayout,
2074
- trigger: "imperative-api"
2075
- });
2076
- if (!compareLayouts(prevLayout, nextLayout)) {
2077
- setLayout(nextLayout);
2078
- eagerValuesRef.current.layout = nextLayout;
2079
- if (onLayout) {
2080
- onLayout(nextLayout);
2081
- }
2082
- callPanelCallbacks(panelDataArray, nextLayout, panelIdToLastNotifiedSizeMapRef.current);
2083
- }
2084
- }, []);
2085
- const reevaluatePanelConstraints = useCallback((panelData, prevConstraints) => {
2086
- const {
2087
- layout,
2088
- panelDataArray
2089
- } = eagerValuesRef.current;
2090
- const {
2091
- collapsedSize: prevCollapsedSize = 0,
2092
- collapsible: prevCollapsible
2093
- } = prevConstraints;
2094
- const {
2095
- collapsedSize: nextCollapsedSize = 0,
2096
- collapsible: nextCollapsible,
2097
- maxSize: nextMaxSize = 100,
2098
- minSize: nextMinSize = 0
2099
- } = panelData.constraints;
2100
- const {
2101
- panelSize: prevPanelSize
2102
- } = panelDataHelper(panelDataArray, panelData, layout);
2103
- if (prevPanelSize == null) {
2104
- // It's possible that the panels in this group have changed since the last render
2105
- return;
2106
- }
2107
- if (prevCollapsible && nextCollapsible && fuzzyNumbersEqual$1(prevPanelSize, prevCollapsedSize)) {
2108
- if (!fuzzyNumbersEqual$1(prevCollapsedSize, nextCollapsedSize)) {
2109
- resizePanel(panelData, nextCollapsedSize);
2110
- }
2111
- } else if (prevPanelSize < nextMinSize) {
2112
- resizePanel(panelData, nextMinSize);
2113
- } else if (prevPanelSize > nextMaxSize) {
2114
- resizePanel(panelData, nextMaxSize);
2115
- }
2116
- }, [resizePanel]);
2117
-
2118
- // TODO Multiple drag handles can be active at the same time so this API is a bit awkward now
2119
- const startDragging = useCallback((dragHandleId, event) => {
2120
- const {
2121
- direction
2122
- } = committedValuesRef.current;
2123
- const {
2124
- layout
2125
- } = eagerValuesRef.current;
2126
- if (!panelGroupElementRef.current) {
2127
- return;
2128
- }
2129
- const handleElement = getResizeHandleElement(dragHandleId, panelGroupElementRef.current);
2130
- assert(handleElement, `Drag handle element not found for id "${dragHandleId}"`);
2131
- const initialCursorPosition = getResizeEventCursorPosition(direction, event);
2132
- setDragState({
2133
- dragHandleId,
2134
- dragHandleRect: handleElement.getBoundingClientRect(),
2135
- initialCursorPosition,
2136
- initialLayout: layout
2137
- });
2138
- }, []);
2139
- const stopDragging = useCallback(() => {
2140
- setDragState(null);
2141
- }, []);
2142
- const unregisterPanel = useCallback(panelData => {
2143
- const {
2144
- panelDataArray
2145
- } = eagerValuesRef.current;
2146
- const index = findPanelDataIndex(panelDataArray, panelData);
2147
- if (index >= 0) {
2148
- panelDataArray.splice(index, 1);
2149
-
2150
- // TRICKY
2151
- // When a panel is removed from the group, we should delete the most recent prev-size entry for it.
2152
- // If we don't do this, then a conditionally rendered panel might not call onResize when it's re-mounted.
2153
- // Strict effects mode makes this tricky though because all panels will be registered, unregistered, then re-registered on mount.
2154
- delete panelIdToLastNotifiedSizeMapRef.current[panelData.id];
2155
- eagerValuesRef.current.panelDataArrayChanged = true;
2156
- forceUpdate();
2157
- }
2158
- }, [forceUpdate]);
2159
- const context = useMemo(() => ({
2160
- collapsePanel,
2161
- direction,
2162
- dragState,
2163
- expandPanel,
2164
- getPanelSize,
2165
- getPanelStyle,
2166
- groupId,
2167
- isPanelCollapsed,
2168
- isPanelExpanded,
2169
- reevaluatePanelConstraints,
2170
- registerPanel,
2171
- registerResizeHandle,
2172
- resizePanel,
2173
- startDragging,
2174
- stopDragging,
2175
- unregisterPanel,
2176
- panelGroupElement: panelGroupElementRef.current
2177
- }), [collapsePanel, dragState, direction, expandPanel, getPanelSize, getPanelStyle, groupId, isPanelCollapsed, isPanelExpanded, reevaluatePanelConstraints, registerPanel, registerResizeHandle, resizePanel, startDragging, stopDragging, unregisterPanel]);
2178
- const style = {
2179
- display: "flex",
2180
- flexDirection: direction === "horizontal" ? "row" : "column",
2181
- height: "100%",
2182
- overflow: "hidden",
2183
- width: "100%"
2184
- };
2185
- return createElement(PanelGroupContext.Provider, {
2186
- value: context
2187
- }, createElement(Type, {
2188
- ...rest,
2189
- children,
2190
- className: classNameFromProps,
2191
- id: idFromProps,
2192
- ref: panelGroupElementRef,
2193
- style: {
2194
- ...style,
2195
- ...styleFromProps
2196
- },
2197
- // CSS selectors
2198
- [DATA_ATTRIBUTES.group]: "",
2199
- [DATA_ATTRIBUTES.groupDirection]: direction,
2200
- [DATA_ATTRIBUTES.groupId]: groupId
2201
- }));
1104
+ );
2202
1105
  }
2203
- const PanelGroup = forwardRef((props, ref) => createElement(PanelGroupWithForwardedRef, {
2204
- ...props,
2205
- forwardedRef: ref
2206
- }));
2207
- PanelGroupWithForwardedRef.displayName = "PanelGroup";
2208
- PanelGroup.displayName = "forwardRef(PanelGroup)";
2209
- function findPanelDataIndex(panelDataArray, panelData) {
2210
- return panelDataArray.findIndex(prevPanelData => prevPanelData === panelData || prevPanelData.id === panelData.id);
1106
+ function at() {
1107
+ return M(null);
2211
1108
  }
2212
- function panelDataHelper(panelDataArray, panelData, layout) {
2213
- const panelIndex = findPanelDataIndex(panelDataArray, panelData);
2214
- const isLastPanel = panelIndex === panelDataArray.length - 1;
2215
- const pivotIndices = isLastPanel ? [panelIndex - 1, panelIndex] : [panelIndex, panelIndex + 1];
2216
- const panelSize = layout[panelIndex];
2217
- return {
2218
- ...panelData.constraints,
2219
- panelSize,
2220
- pivotIndices
2221
- };
1109
+ function lt() {
1110
+ return I(null);
2222
1111
  }
2223
-
2224
- // https://www.w3.org/WAI/ARIA/apg/patterns/windowsplitter/
2225
-
2226
- function useWindowSplitterResizeHandlerBehavior({
2227
- disabled,
2228
- handleId,
2229
- resizeHandler,
2230
- panelGroupElement
1112
+ function ct({
1113
+ children: e,
1114
+ className: t,
1115
+ elementRef: n,
1116
+ id: o,
1117
+ style: s
2231
1118
  }) {
2232
- useEffect(() => {
2233
- if (disabled || resizeHandler == null || panelGroupElement == null) {
2234
- return;
2235
- }
2236
- const handleElement = getResizeHandleElement(handleId, panelGroupElement);
2237
- if (handleElement == null) {
2238
- return;
1119
+ const i = J(o), [a, r] = M(null), [l, c] = M("inactive"), u = ee(r, n), { registerSeparator: f } = te();
1120
+ return D(() => {
1121
+ if (a !== null) {
1122
+ const p = {
1123
+ element: a,
1124
+ id: i
1125
+ }, h = f(p), m = _.addListener(
1126
+ "interactionStateChange",
1127
+ (d) => {
1128
+ c(
1129
+ d.state !== "inactive" && d.hitRegions.some(
1130
+ (v) => v.separator === p
1131
+ ) ? d.state : "inactive"
1132
+ );
1133
+ }
1134
+ );
1135
+ return () => {
1136
+ h(), m();
1137
+ };
2239
1138
  }
2240
- const onKeyDown = event => {
2241
- if (event.defaultPrevented) {
2242
- return;
2243
- }
2244
- switch (event.key) {
2245
- case "ArrowDown":
2246
- case "ArrowLeft":
2247
- case "ArrowRight":
2248
- case "ArrowUp":
2249
- case "End":
2250
- case "Home":
2251
- {
2252
- event.preventDefault();
2253
- resizeHandler(event);
2254
- break;
2255
- }
2256
- case "F6":
2257
- {
2258
- event.preventDefault();
2259
- const groupId = handleElement.getAttribute(DATA_ATTRIBUTES.groupId);
2260
- assert(groupId, `No group element found for id "${groupId}"`);
2261
- const handles = getResizeHandleElementsForGroup(groupId, panelGroupElement);
2262
- const index = getResizeHandleElementIndex(groupId, handleId, panelGroupElement);
2263
- assert(index !== null, `No resize element found for id "${handleId}"`);
2264
- const nextIndex = event.shiftKey ? index > 0 ? index - 1 : handles.length - 1 : index + 1 < handles.length ? index + 1 : 0;
2265
- const nextHandle = handles[nextIndex];
2266
- nextHandle.focus();
2267
- break;
2268
- }
1139
+ }, [a, i, f]), /* @__PURE__ */ F(
1140
+ "div",
1141
+ {
1142
+ children: e,
1143
+ className: t,
1144
+ "data-separator": !0,
1145
+ "data-separator-id": i,
1146
+ "data-separator-state": l,
1147
+ ref: u,
1148
+ style: {
1149
+ flexBasis: "auto",
1150
+ ...s,
1151
+ flexGrow: 0,
1152
+ flexShrink: 0
2269
1153
  }
2270
- };
2271
- handleElement.addEventListener("keydown", onKeyDown);
2272
- return () => {
2273
- handleElement.removeEventListener("keydown", onKeyDown);
2274
- };
2275
- }, [panelGroupElement, disabled, handleId, resizeHandler]);
2276
- }
2277
-
2278
- function PanelResizeHandle({
2279
- children = null,
2280
- className: classNameFromProps = "",
2281
- disabled = false,
2282
- hitAreaMargins,
2283
- id: idFromProps,
2284
- onBlur,
2285
- onClick,
2286
- onDragging,
2287
- onFocus,
2288
- onPointerDown,
2289
- onPointerUp,
2290
- style: styleFromProps = {},
2291
- tabIndex = 0,
2292
- tagName: Type = "div",
2293
- ...rest
2294
- }) {
2295
- var _hitAreaMargins$coars, _hitAreaMargins$fine;
2296
- const elementRef = useRef(null);
2297
-
2298
- // Use a ref to guard against users passing inline props
2299
- const callbacksRef = useRef({
2300
- onClick,
2301
- onDragging,
2302
- onPointerDown,
2303
- onPointerUp
2304
- });
2305
- useEffect(() => {
2306
- callbacksRef.current.onClick = onClick;
2307
- callbacksRef.current.onDragging = onDragging;
2308
- callbacksRef.current.onPointerDown = onPointerDown;
2309
- callbacksRef.current.onPointerUp = onPointerUp;
2310
- });
2311
- const panelGroupContext = useContext(PanelGroupContext);
2312
- if (panelGroupContext === null) {
2313
- throw Error(`PanelResizeHandle components must be rendered within a PanelGroup container`);
2314
- }
2315
- const {
2316
- direction,
2317
- groupId,
2318
- registerResizeHandle: registerResizeHandleWithParentGroup,
2319
- startDragging,
2320
- stopDragging,
2321
- panelGroupElement
2322
- } = panelGroupContext;
2323
- const resizeHandleId = useUniqueId(idFromProps);
2324
- const [state, setState] = useState("inactive");
2325
- const [isFocused, setIsFocused] = useState(false);
2326
- const [resizeHandler, setResizeHandler] = useState(null);
2327
- const committedValuesRef = useRef({
2328
- state
2329
- });
2330
- useIsomorphicLayoutEffect(() => {
2331
- committedValuesRef.current.state = state;
2332
- });
2333
- useEffect(() => {
2334
- if (disabled) {
2335
- setResizeHandler(null);
2336
- } else {
2337
- const resizeHandler = registerResizeHandleWithParentGroup(resizeHandleId);
2338
- setResizeHandler(() => resizeHandler);
2339
1154
  }
2340
- }, [disabled, resizeHandleId, registerResizeHandleWithParentGroup]);
2341
-
2342
- // Extract hit area margins before passing them to the effect's dependency array
2343
- // so that inline object values won't trigger re-renders
2344
- const coarseHitAreaMargins = (_hitAreaMargins$coars = hitAreaMargins === null || hitAreaMargins === void 0 ? void 0 : hitAreaMargins.coarse) !== null && _hitAreaMargins$coars !== void 0 ? _hitAreaMargins$coars : 15;
2345
- const fineHitAreaMargins = (_hitAreaMargins$fine = hitAreaMargins === null || hitAreaMargins === void 0 ? void 0 : hitAreaMargins.fine) !== null && _hitAreaMargins$fine !== void 0 ? _hitAreaMargins$fine : 5;
2346
- useEffect(() => {
2347
- if (disabled || resizeHandler == null) {
2348
- return;
2349
- }
2350
- const element = elementRef.current;
2351
- assert(element, "Element ref not attached");
2352
- let didMove = false;
2353
- const setResizeHandlerState = (action, isActive, event) => {
2354
- if (!isActive) {
2355
- setState("inactive");
2356
- return;
2357
- }
2358
- switch (action) {
2359
- case "down":
2360
- {
2361
- setState("drag");
2362
- didMove = false;
2363
- assert(event, 'Expected event to be defined for "down" action');
2364
- startDragging(resizeHandleId, event);
2365
- const {
2366
- onDragging,
2367
- onPointerDown
2368
- } = callbacksRef.current;
2369
- onDragging === null || onDragging === void 0 ? void 0 : onDragging(true);
2370
- onPointerDown === null || onPointerDown === void 0 ? void 0 : onPointerDown();
2371
- break;
2372
- }
2373
- case "move":
2374
- {
2375
- const {
2376
- state
2377
- } = committedValuesRef.current;
2378
- didMove = true;
2379
- if (state !== "drag") {
2380
- setState("hover");
2381
- }
2382
- assert(event, 'Expected event to be defined for "move" action');
2383
- resizeHandler(event);
2384
- break;
2385
- }
2386
- case "up":
2387
- {
2388
- setState("hover");
2389
- stopDragging();
2390
- const {
2391
- onClick,
2392
- onDragging,
2393
- onPointerUp
2394
- } = callbacksRef.current;
2395
- onDragging === null || onDragging === void 0 ? void 0 : onDragging(false);
2396
- onPointerUp === null || onPointerUp === void 0 ? void 0 : onPointerUp();
2397
- if (!didMove) {
2398
- onClick === null || onClick === void 0 ? void 0 : onClick();
2399
- }
2400
- break;
2401
- }
2402
- }
2403
- };
2404
- return registerResizeHandle(resizeHandleId, element, direction, {
2405
- coarse: coarseHitAreaMargins,
2406
- fine: fineHitAreaMargins
2407
- }, setResizeHandlerState);
2408
- }, [coarseHitAreaMargins, direction, disabled, fineHitAreaMargins, registerResizeHandleWithParentGroup, resizeHandleId, resizeHandler, startDragging, stopDragging]);
2409
- useWindowSplitterResizeHandlerBehavior({
2410
- disabled,
2411
- handleId: resizeHandleId,
2412
- resizeHandler,
2413
- panelGroupElement
2414
- });
2415
- const style = {
2416
- touchAction: "none",
2417
- userSelect: "none"
2418
- };
2419
- return createElement(Type, {
2420
- ...rest,
2421
- children,
2422
- className: classNameFromProps,
2423
- id: idFromProps,
2424
- onBlur: () => {
2425
- setIsFocused(false);
2426
- onBlur === null || onBlur === void 0 ? void 0 : onBlur();
2427
- },
2428
- onFocus: () => {
2429
- setIsFocused(true);
2430
- onFocus === null || onFocus === void 0 ? void 0 : onFocus();
2431
- },
2432
- ref: elementRef,
2433
- role: "separator",
2434
- style: {
2435
- ...style,
2436
- ...styleFromProps
2437
- },
2438
- tabIndex,
2439
- // CSS selectors
2440
- [DATA_ATTRIBUTES.groupDirection]: direction,
2441
- [DATA_ATTRIBUTES.groupId]: groupId,
2442
- [DATA_ATTRIBUTES.resizeHandle]: "",
2443
- [DATA_ATTRIBUTES.resizeHandleActive]: state === "drag" ? "pointer" : isFocused ? "keyboard" : undefined,
2444
- [DATA_ATTRIBUTES.resizeHandleEnabled]: !disabled,
2445
- [DATA_ATTRIBUTES.resizeHandleId]: resizeHandleId,
2446
- [DATA_ATTRIBUTES.resizeHandleState]: state
2447
- });
2448
- }
2449
- PanelResizeHandle.displayName = "PanelResizeHandle";
2450
-
2451
- function usePanelGroupContext() {
2452
- const context = useContext(PanelGroupContext);
2453
- return {
2454
- direction: context === null || context === void 0 ? void 0 : context.direction,
2455
- groupId: context === null || context === void 0 ? void 0 : context.groupId
2456
- };
2457
- }
2458
-
2459
- function getPanelElement(id, scope = document) {
2460
- const element = scope.querySelector(`[data-panel-id="${id}"]`);
2461
- if (element) {
2462
- return element;
2463
- }
2464
- return null;
2465
- }
2466
-
2467
- function getPanelElementsForGroup(groupId, scope = document) {
2468
- return Array.from(scope.querySelectorAll(`[data-panel][data-panel-group-id="${groupId}"]`));
2469
- }
2470
-
2471
- function getIntersectingRectangle(rectOne, rectTwo, strict) {
2472
- if (!intersects(rectOne, rectTwo, strict)) {
2473
- return {
2474
- x: 0,
2475
- y: 0,
2476
- width: 0,
2477
- height: 0
2478
- };
2479
- }
2480
- return {
2481
- x: Math.max(rectOne.x, rectTwo.x),
2482
- y: Math.max(rectOne.y, rectTwo.y),
2483
- width: Math.min(rectOne.x + rectOne.width, rectTwo.x + rectTwo.width) - Math.max(rectOne.x, rectTwo.x),
2484
- height: Math.min(rectOne.y + rectOne.height, rectTwo.y + rectTwo.height) - Math.max(rectOne.y, rectTwo.y)
2485
- };
2486
- }
2487
-
2488
- export { DATA_ATTRIBUTES, Panel, PanelGroup, PanelResizeHandle, assert, customizeGlobalCursorStyles, disableGlobalCursorStyles, enableGlobalCursorStyles, getIntersectingRectangle, getPanelElement, getPanelElementsForGroup, getPanelGroupElement, getResizeHandleElement, getResizeHandleElementIndex, getResizeHandleElementsForGroup, getResizeHandlePanelIds, intersects, setNonce, usePanelGroupContext };
1155
+ );
1156
+ }
1157
+ export {
1158
+ nt as Group,
1159
+ st as Panel,
1160
+ ct as Separator,
1161
+ ot as useDefaultLayout,
1162
+ it as useGroupCallbackRef,
1163
+ rt as useGroupRef,
1164
+ at as usePanelCallbackRef,
1165
+ lt as usePanelRef
1166
+ };
1167
+ //# sourceMappingURL=react-resizable-panels.js.map