@corvu-next/resizable 0.1.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.
- package/LICENSE +21 -0
- package/dist/index.d.ts +304 -0
- package/dist/index.js +1587 -0
- package/dist/index.jsx +1706 -0
- package/package.json +49 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,1587 @@
|
|
|
1
|
+
import { createContext, merge, omit, createSignal, createEffect, createMemo, untrack, useContext, Show, createUniqueId } from 'solid-js';
|
|
2
|
+
import { useKeyedContext, createKeyedContext } from '@corvu-next/utils/create/keyedContext';
|
|
3
|
+
import { createComponent, mergeProps, effect, setStyleProperty, memo, template } from 'solid-js/web';
|
|
4
|
+
import { combineStyle, sortByDocumentPosition, callEventHandler } from '@corvu-next/utils/dom';
|
|
5
|
+
import { Dynamic } from '@corvu-next/utils/dynamic';
|
|
6
|
+
import { mergeRefs, some } from '@corvu-next/utils/reactivity';
|
|
7
|
+
import { dataIf, isFunction } from '@corvu-next/utils';
|
|
8
|
+
import createOnce from '@corvu-next/utils/create/once';
|
|
9
|
+
import createControllableSignal from '@corvu-next/utils/create/controllableSignal';
|
|
10
|
+
import createSize from '@corvu-next/utils/create/size';
|
|
11
|
+
|
|
12
|
+
// src/context.ts
|
|
13
|
+
var ResizableContext = createContext(null);
|
|
14
|
+
var createResizableContext = (contextId) => {
|
|
15
|
+
if (contextId === void 0) return ResizableContext;
|
|
16
|
+
const context = createKeyedContext(
|
|
17
|
+
`resizable-${contextId}`
|
|
18
|
+
);
|
|
19
|
+
return context;
|
|
20
|
+
};
|
|
21
|
+
var useResizableContext = (contextId) => {
|
|
22
|
+
if (contextId === void 0) {
|
|
23
|
+
const context2 = useContext(ResizableContext);
|
|
24
|
+
if (!context2) {
|
|
25
|
+
throw new Error(
|
|
26
|
+
"[corvu]: Resizable context not found. Make sure to wrap Resizable components in <Resizable.Root>"
|
|
27
|
+
);
|
|
28
|
+
}
|
|
29
|
+
return context2;
|
|
30
|
+
}
|
|
31
|
+
const context = useKeyedContext(
|
|
32
|
+
`resizable-${contextId}`
|
|
33
|
+
);
|
|
34
|
+
if (!context) {
|
|
35
|
+
throw new Error(
|
|
36
|
+
`[corvu]: Resizable context with id "${contextId}" not found. Make sure to wrap Resizable components in <Resizable.Root contextId="${contextId}">`
|
|
37
|
+
);
|
|
38
|
+
}
|
|
39
|
+
return context;
|
|
40
|
+
};
|
|
41
|
+
var InternalResizableContext = createContext(null);
|
|
42
|
+
var createInternalResizableContext = (contextId) => {
|
|
43
|
+
if (contextId === void 0) return InternalResizableContext;
|
|
44
|
+
const context = createKeyedContext(
|
|
45
|
+
`resizable-internal-${contextId}`
|
|
46
|
+
);
|
|
47
|
+
return context;
|
|
48
|
+
};
|
|
49
|
+
var useInternalResizableContext = (contextId) => {
|
|
50
|
+
if (contextId === void 0) {
|
|
51
|
+
const context2 = useContext(InternalResizableContext);
|
|
52
|
+
if (!context2) {
|
|
53
|
+
throw new Error(
|
|
54
|
+
"[corvu]: Resizable context not found. Make sure to wrap Resizable components in <Resizable.Root>"
|
|
55
|
+
);
|
|
56
|
+
}
|
|
57
|
+
return context2;
|
|
58
|
+
}
|
|
59
|
+
const context = useKeyedContext(
|
|
60
|
+
`resizable-internal-${contextId}`
|
|
61
|
+
);
|
|
62
|
+
if (!context) {
|
|
63
|
+
throw new Error(
|
|
64
|
+
`[corvu]: Resizable context with id "${contextId}" not found. Make sure to wrap Resizable components in <Resizable.Root contextId="${contextId}">`
|
|
65
|
+
);
|
|
66
|
+
}
|
|
67
|
+
return context;
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
// src/lib/utils.ts
|
|
71
|
+
var resolveSize = (size, rootSize) => {
|
|
72
|
+
if (typeof size === "number") {
|
|
73
|
+
return size;
|
|
74
|
+
}
|
|
75
|
+
if (!size.endsWith("px")) {
|
|
76
|
+
throw new Error(
|
|
77
|
+
`[corvu] Sizes must be a number or a string ending with 'px'. Got ${size}`
|
|
78
|
+
);
|
|
79
|
+
}
|
|
80
|
+
return fixToPrecision(parseFloat(size) / rootSize);
|
|
81
|
+
};
|
|
82
|
+
var splitPanels = (props) => {
|
|
83
|
+
const precedingPanels = props.panels.filter(
|
|
84
|
+
(panel) => !!(props.focusedElement.compareDocumentPosition(panel.data.element) & Node.DOCUMENT_POSITION_PRECEDING)
|
|
85
|
+
);
|
|
86
|
+
const followingPanels = props.panels.filter(
|
|
87
|
+
(panel) => !!(props.focusedElement.compareDocumentPosition(panel.data.element) & Node.DOCUMENT_POSITION_FOLLOWING)
|
|
88
|
+
);
|
|
89
|
+
return [precedingPanels, followingPanels];
|
|
90
|
+
};
|
|
91
|
+
var PRECISION = 6;
|
|
92
|
+
var fixToPrecision = (value) => parseFloat(value.toFixed(PRECISION));
|
|
93
|
+
|
|
94
|
+
// src/lib/cursor.ts
|
|
95
|
+
var globalCursorStyle = null;
|
|
96
|
+
var cursorStyleElement = null;
|
|
97
|
+
var globalResizeConstraints = 0;
|
|
98
|
+
var constraintToCursorMap = {
|
|
99
|
+
1: "e-resize",
|
|
100
|
+
2: "w-resize",
|
|
101
|
+
3: "ew-resize",
|
|
102
|
+
4: "s-resize",
|
|
103
|
+
8: "n-resize",
|
|
104
|
+
12: "ns-resize",
|
|
105
|
+
5: "se-resize",
|
|
106
|
+
9: "ne-resize",
|
|
107
|
+
6: "sw-resize",
|
|
108
|
+
10: "nw-resize"
|
|
109
|
+
};
|
|
110
|
+
var cachedCursorStyle = null;
|
|
111
|
+
var updateCursorStyle = () => {
|
|
112
|
+
if (!globalCursorStyle) {
|
|
113
|
+
if (cursorStyleElement) {
|
|
114
|
+
cachedCursorStyle = null;
|
|
115
|
+
cursorStyleElement.remove();
|
|
116
|
+
cursorStyleElement = null;
|
|
117
|
+
}
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
let cursorStyle = constraintToCursorMap[globalResizeConstraints] ?? null;
|
|
121
|
+
if (cursorStyle === null) {
|
|
122
|
+
switch (globalCursorStyle) {
|
|
123
|
+
case "horizontal":
|
|
124
|
+
cursorStyle = "col-resize";
|
|
125
|
+
break;
|
|
126
|
+
case "vertical":
|
|
127
|
+
cursorStyle = "row-resize";
|
|
128
|
+
break;
|
|
129
|
+
case "both":
|
|
130
|
+
cursorStyle = "move";
|
|
131
|
+
break;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
if (cursorStyle === cachedCursorStyle) return;
|
|
135
|
+
cachedCursorStyle = cursorStyle;
|
|
136
|
+
if (!cursorStyleElement) {
|
|
137
|
+
cursorStyleElement = document.createElement("style");
|
|
138
|
+
document.head.appendChild(cursorStyleElement);
|
|
139
|
+
}
|
|
140
|
+
cursorStyleElement.innerHTML = `*{cursor: ${cursorStyle}!important;}`;
|
|
141
|
+
};
|
|
142
|
+
var reportResizeConstraints = (orientation, constraints) => {
|
|
143
|
+
switch (orientation) {
|
|
144
|
+
case "horizontal":
|
|
145
|
+
if (constraints === 1) {
|
|
146
|
+
globalResizeConstraints |= 1;
|
|
147
|
+
globalResizeConstraints &= -3;
|
|
148
|
+
} else if (constraints === 2) {
|
|
149
|
+
globalResizeConstraints |= 2;
|
|
150
|
+
globalResizeConstraints &= -2;
|
|
151
|
+
} else if (constraints === 3) {
|
|
152
|
+
globalResizeConstraints |= 3;
|
|
153
|
+
} else {
|
|
154
|
+
globalResizeConstraints &= -4;
|
|
155
|
+
}
|
|
156
|
+
break;
|
|
157
|
+
case "vertical":
|
|
158
|
+
if (constraints === 1) {
|
|
159
|
+
globalResizeConstraints |= 4;
|
|
160
|
+
globalResizeConstraints &= -9;
|
|
161
|
+
} else if (constraints === 2) {
|
|
162
|
+
globalResizeConstraints |= 8;
|
|
163
|
+
globalResizeConstraints &= -5;
|
|
164
|
+
} else if (constraints === 3) {
|
|
165
|
+
globalResizeConstraints |= 12;
|
|
166
|
+
} else {
|
|
167
|
+
globalResizeConstraints &= -13;
|
|
168
|
+
}
|
|
169
|
+
break;
|
|
170
|
+
}
|
|
171
|
+
updateCursorStyle();
|
|
172
|
+
};
|
|
173
|
+
var resetResizeConstraints = () => {
|
|
174
|
+
globalResizeConstraints = 0;
|
|
175
|
+
updateCursorStyle();
|
|
176
|
+
};
|
|
177
|
+
var setGlobalCursorStyle = (cursorStyle) => {
|
|
178
|
+
globalCursorStyle = cursorStyle;
|
|
179
|
+
updateCursorStyle();
|
|
180
|
+
};
|
|
181
|
+
var handleResizeConstraints = (props) => {
|
|
182
|
+
if (fixToPrecision(props.distributablePercentage) !== fixToPrecision(props.desiredPercentage)) {
|
|
183
|
+
let constraints = null;
|
|
184
|
+
if (props.betweenCollapse === true) {
|
|
185
|
+
constraints = 3;
|
|
186
|
+
} else if (props.desiredPercentage < props.distributablePercentage && props.revertConstraints !== true || props.desiredPercentage > props.distributablePercentage && props.revertConstraints === true) {
|
|
187
|
+
constraints = 1;
|
|
188
|
+
} else {
|
|
189
|
+
constraints = 2;
|
|
190
|
+
}
|
|
191
|
+
reportResizeConstraints(props.orientation, constraints);
|
|
192
|
+
} else {
|
|
193
|
+
reportResizeConstraints(props.orientation, 0);
|
|
194
|
+
}
|
|
195
|
+
};
|
|
196
|
+
var handles = [];
|
|
197
|
+
var dragStartPos = null;
|
|
198
|
+
var globalHovered = null;
|
|
199
|
+
var INTERSECTION_TOLERANCE = 1;
|
|
200
|
+
var equalsWithTolerance = (a, b) => Math.abs(a - b) <= INTERSECTION_TOLERANCE;
|
|
201
|
+
var registerHandle = (handle) => {
|
|
202
|
+
handles.push(handle);
|
|
203
|
+
for (const handle2 of handles) {
|
|
204
|
+
for (const compareHandle of handles) {
|
|
205
|
+
if (handle2.orientation === compareHandle.orientation || handle2.element === compareHandle.element) {
|
|
206
|
+
continue;
|
|
207
|
+
}
|
|
208
|
+
const handleRect = handle2.element.getBoundingClientRect();
|
|
209
|
+
const compareHandleRect = compareHandle.element.getBoundingClientRect();
|
|
210
|
+
if (handle2.orientation === "horizontal") {
|
|
211
|
+
if (handleRect.left > compareHandleRect.right || handleRect.right < compareHandleRect.left) {
|
|
212
|
+
continue;
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
if (handle2.orientation === "vertical") {
|
|
216
|
+
if (handleRect.top > compareHandleRect.bottom || handleRect.bottom < compareHandleRect.top) {
|
|
217
|
+
continue;
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
const isStartIntersection = handle2.orientation === "horizontal" ? equalsWithTolerance(handleRect.top, compareHandleRect.bottom) : equalsWithTolerance(handleRect.left, compareHandleRect.right);
|
|
221
|
+
const isEndIntersection = handle2.orientation === "horizontal" ? equalsWithTolerance(handleRect.bottom, compareHandleRect.top) : equalsWithTolerance(handleRect.right, compareHandleRect.left);
|
|
222
|
+
if (isStartIntersection) {
|
|
223
|
+
handle2.startIntersection.setHandle(compareHandle);
|
|
224
|
+
}
|
|
225
|
+
if (isEndIntersection) {
|
|
226
|
+
handle2.endIntersection.setHandle(compareHandle);
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
return {
|
|
231
|
+
onDragStart: (event, target) => onDragStart(handle, event, target),
|
|
232
|
+
onHoveredChange: (state) => {
|
|
233
|
+
globalHovered = state;
|
|
234
|
+
const dragging = !!dragStartPos;
|
|
235
|
+
let cursorStyle = null;
|
|
236
|
+
switch (state) {
|
|
237
|
+
case "handle": {
|
|
238
|
+
const startHandle = handle.startIntersection.handle();
|
|
239
|
+
const endHandle = handle.endIntersection.handle();
|
|
240
|
+
if (!dragging) {
|
|
241
|
+
handle.setActive(true);
|
|
242
|
+
startHandle?.setActive(false);
|
|
243
|
+
endHandle?.setActive(false);
|
|
244
|
+
}
|
|
245
|
+
startHandle?.setHoveredAsIntersection(false);
|
|
246
|
+
endHandle?.setHoveredAsIntersection(false);
|
|
247
|
+
cursorStyle = handle.orientation;
|
|
248
|
+
break;
|
|
249
|
+
}
|
|
250
|
+
case "startIntersection": {
|
|
251
|
+
const startHandle = handle.startIntersection.handle();
|
|
252
|
+
if (!dragging) {
|
|
253
|
+
startHandle?.setActive(true);
|
|
254
|
+
}
|
|
255
|
+
startHandle?.setHoveredAsIntersection(true);
|
|
256
|
+
cursorStyle = "both";
|
|
257
|
+
break;
|
|
258
|
+
}
|
|
259
|
+
case "endIntersection": {
|
|
260
|
+
const endHandle = handle.endIntersection.handle();
|
|
261
|
+
if (!dragging) {
|
|
262
|
+
endHandle?.setActive(true);
|
|
263
|
+
}
|
|
264
|
+
endHandle?.setHoveredAsIntersection(true);
|
|
265
|
+
cursorStyle = "both";
|
|
266
|
+
break;
|
|
267
|
+
}
|
|
268
|
+
case null: {
|
|
269
|
+
const startHandle = handle.startIntersection.handle();
|
|
270
|
+
const endHandle = handle.endIntersection.handle();
|
|
271
|
+
if (!dragging && !handle.focused()) {
|
|
272
|
+
handle.setActive(false);
|
|
273
|
+
startHandle?.setActive(false);
|
|
274
|
+
endHandle?.setActive(false);
|
|
275
|
+
}
|
|
276
|
+
startHandle?.setHoveredAsIntersection(false);
|
|
277
|
+
endHandle?.setHoveredAsIntersection(false);
|
|
278
|
+
cursorStyle = null;
|
|
279
|
+
break;
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
if (!dragging && handle.handleCursorStyle()) {
|
|
283
|
+
setGlobalCursorStyle(cursorStyle);
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
};
|
|
287
|
+
};
|
|
288
|
+
var unregisterHandle = (handle) => {
|
|
289
|
+
handles.splice(handles.indexOf(handle), 1);
|
|
290
|
+
};
|
|
291
|
+
var onDragStart = (handle, event, target) => {
|
|
292
|
+
dragStartPos = { x: event.clientX, y: event.clientY };
|
|
293
|
+
handle.setDragging(true);
|
|
294
|
+
if (target === "startIntersection") {
|
|
295
|
+
handle.startIntersection.handle()?.setDragging(true);
|
|
296
|
+
}
|
|
297
|
+
if (target === "endIntersection") {
|
|
298
|
+
handle.endIntersection.handle()?.setDragging(true);
|
|
299
|
+
}
|
|
300
|
+
window.addEventListener("pointermove", onPointerMove);
|
|
301
|
+
window.addEventListener("touchmove", onTouchMove);
|
|
302
|
+
window.addEventListener("pointerup", onDragEnd);
|
|
303
|
+
window.addEventListener("touchend", onDragEnd);
|
|
304
|
+
window.addEventListener("contextmenu", onDragEnd);
|
|
305
|
+
};
|
|
306
|
+
var onPointerMove = (event) => onMove(event.clientX, event.clientY, event.altKey);
|
|
307
|
+
var onTouchMove = (event) => {
|
|
308
|
+
if (!event.touches[0]) return;
|
|
309
|
+
onMove(event.touches[0].clientX, event.touches[0].clientY, event.altKey);
|
|
310
|
+
};
|
|
311
|
+
var altKeyCache = false;
|
|
312
|
+
var onMove = (x, y, altKey) => {
|
|
313
|
+
if (!dragStartPos) return;
|
|
314
|
+
if (handles.some((handle) => handle.dragging() && handle.altKey === "only")) {
|
|
315
|
+
altKey = true;
|
|
316
|
+
}
|
|
317
|
+
if (handles.some((handle) => handle.dragging() && handle.altKey === false)) {
|
|
318
|
+
altKey = false;
|
|
319
|
+
}
|
|
320
|
+
if (altKeyCache !== altKey) {
|
|
321
|
+
dragStartPos = { x, y };
|
|
322
|
+
altKeyCache = altKey;
|
|
323
|
+
}
|
|
324
|
+
for (const handle of handles) {
|
|
325
|
+
if (!handle.dragging()) continue;
|
|
326
|
+
handle.onDrag(
|
|
327
|
+
handle.orientation === "horizontal" ? x - dragStartPos.x : y - dragStartPos.y,
|
|
328
|
+
altKey
|
|
329
|
+
);
|
|
330
|
+
}
|
|
331
|
+
};
|
|
332
|
+
var onDragEnd = (event) => {
|
|
333
|
+
for (const handle of handles) {
|
|
334
|
+
if (!handle.dragging()) {
|
|
335
|
+
if (some(handle.hovered, handle.focused, handle.hoveredAsIntersection)) {
|
|
336
|
+
handle.setActive(true);
|
|
337
|
+
if (handle.handleCursorStyle()) {
|
|
338
|
+
setGlobalCursorStyle(handle.orientation);
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
} else {
|
|
342
|
+
handle.setDragging(false);
|
|
343
|
+
handle.onDragEnd(event);
|
|
344
|
+
if (!handle.hovered() && !handle.hoveredAsIntersection()) {
|
|
345
|
+
handle.setActive(false);
|
|
346
|
+
}
|
|
347
|
+
if (!globalHovered && handle.handleCursorStyle()) {
|
|
348
|
+
setGlobalCursorStyle(null);
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
resetResizeConstraints();
|
|
353
|
+
dragStartPos = null;
|
|
354
|
+
window.removeEventListener("pointermove", onPointerMove);
|
|
355
|
+
window.removeEventListener("touchmove", onTouchMove);
|
|
356
|
+
window.removeEventListener("pointerup", onDragEnd);
|
|
357
|
+
window.removeEventListener("touchend", onDragEnd);
|
|
358
|
+
window.removeEventListener("contextmenu", onDragEnd);
|
|
359
|
+
};
|
|
360
|
+
var _tmpl$ = /* @__PURE__ */ template(`<div data-corvu-resizable-handle-start-intersection style="position:absolute;aspect-ratio:1 / 1;top:0;left:0;z-index:1">`);
|
|
361
|
+
var _tmpl$2 = /* @__PURE__ */ template(`<div data-corvu-resizable-handle-end-intersection style="position:absolute;aspect-ratio:1 / 1;bottom:0;right:0;z-index:1">`);
|
|
362
|
+
var ResizableHandle = (props) => {
|
|
363
|
+
const defaultedProps = merge({
|
|
364
|
+
startIntersection: true,
|
|
365
|
+
endIntersection: true,
|
|
366
|
+
altKey: true
|
|
367
|
+
}, props);
|
|
368
|
+
const localProps = defaultedProps;
|
|
369
|
+
const otherProps = omit(defaultedProps, "startIntersection", "endIntersection", "altKey", "onHandleDragStart", "onHandleDrag", "onHandleDragEnd", "contextId", "ref", "style", "disabled", "children", "onMouseEnter", "onMouseLeave", "onKeyDown", "onKeyUp", "onFocus", "onBlur", "onPointerDown");
|
|
370
|
+
const [ref, setRef] = createSignal(null);
|
|
371
|
+
const [hoveredAsIntersection, setHoveredAsIntersection] = createSignal(false);
|
|
372
|
+
const [hovered, setHovered] = createSignal(null);
|
|
373
|
+
const [focused, setFocused] = createSignal(false);
|
|
374
|
+
const [active, setActive] = createSignal(false);
|
|
375
|
+
const [dragging, setDragging] = createSignal(false);
|
|
376
|
+
const [startIntersectionHandle, setStartIntersectionHandle] = createSignal(null);
|
|
377
|
+
const [endIntersectionHandle, setEndIntersectionHandle] = createSignal(null);
|
|
378
|
+
const context = createMemo(() => useInternalResizableContext(localProps.contextId));
|
|
379
|
+
const ariaInformation = createMemo(() => {
|
|
380
|
+
const handle = ref();
|
|
381
|
+
if (!handle) {
|
|
382
|
+
return void 0;
|
|
383
|
+
}
|
|
384
|
+
const panels = context().panels();
|
|
385
|
+
const [precidingPanels, followingPanels] = splitPanels({
|
|
386
|
+
panels,
|
|
387
|
+
focusedElement: handle
|
|
388
|
+
});
|
|
389
|
+
const ariaControls = precidingPanels[precidingPanels.length - 1]?.data.id;
|
|
390
|
+
const ariaValueMax = followingPanels.reduce((acc, panel) => acc - resolveSize(panel.data.minSize, context().rootSize()), 1);
|
|
391
|
+
const ariaValueMin = precidingPanels.reduce((acc, panel) => acc + resolveSize(panel.data.minSize, context().rootSize()), 0);
|
|
392
|
+
const ariaValueNow = precidingPanels.reduce((acc, panel) => acc + resolveSize(panel.size(), context().rootSize()), 0);
|
|
393
|
+
return {
|
|
394
|
+
ariaControls,
|
|
395
|
+
ariaValueMax: fixToPrecision(ariaValueMax),
|
|
396
|
+
ariaValueMin: fixToPrecision(ariaValueMin),
|
|
397
|
+
ariaValueNow: fixToPrecision(ariaValueNow)
|
|
398
|
+
};
|
|
399
|
+
});
|
|
400
|
+
let globalHandleCallbacks = null;
|
|
401
|
+
createEffect((_prev) => {
|
|
402
|
+
if (localProps.disabled === true) return void 0;
|
|
403
|
+
const element = ref();
|
|
404
|
+
if (!element) return void 0;
|
|
405
|
+
const globalHandle = {
|
|
406
|
+
element,
|
|
407
|
+
orientation: context().orientation(),
|
|
408
|
+
handleCursorStyle: context().handleCursorStyle,
|
|
409
|
+
altKey: localProps.altKey,
|
|
410
|
+
startIntersection: {
|
|
411
|
+
handle: startIntersectionHandle,
|
|
412
|
+
setHandle: (handle) => {
|
|
413
|
+
if (localProps.startIntersection !== true) return;
|
|
414
|
+
setStartIntersectionHandle(handle);
|
|
415
|
+
}
|
|
416
|
+
},
|
|
417
|
+
endIntersection: {
|
|
418
|
+
handle: endIntersectionHandle,
|
|
419
|
+
setHandle: (handle) => {
|
|
420
|
+
if (localProps.endIntersection !== true) return;
|
|
421
|
+
setEndIntersectionHandle(handle);
|
|
422
|
+
}
|
|
423
|
+
},
|
|
424
|
+
hovered,
|
|
425
|
+
focused,
|
|
426
|
+
hoveredAsIntersection,
|
|
427
|
+
setHoveredAsIntersection,
|
|
428
|
+
active,
|
|
429
|
+
setActive,
|
|
430
|
+
dragging,
|
|
431
|
+
setDragging,
|
|
432
|
+
onDrag: (delta, altKey) => {
|
|
433
|
+
if (localProps.onHandleDrag !== void 0) {
|
|
434
|
+
const dragEvent = new CustomEvent("drag", {
|
|
435
|
+
cancelable: true
|
|
436
|
+
});
|
|
437
|
+
localProps.onHandleDrag(dragEvent);
|
|
438
|
+
if (dragEvent.defaultPrevented) return;
|
|
439
|
+
}
|
|
440
|
+
context().onDrag(element, delta, altKey);
|
|
441
|
+
},
|
|
442
|
+
onDragEnd: (event) => {
|
|
443
|
+
localProps.onHandleDragEnd?.(event);
|
|
444
|
+
context().onDragEnd();
|
|
445
|
+
}
|
|
446
|
+
};
|
|
447
|
+
globalHandleCallbacks = registerHandle(globalHandle);
|
|
448
|
+
return globalHandle;
|
|
449
|
+
}, (prevHandle) => {
|
|
450
|
+
if (prevHandle) {
|
|
451
|
+
unregisterHandle(prevHandle);
|
|
452
|
+
globalHandleCallbacks = null;
|
|
453
|
+
}
|
|
454
|
+
});
|
|
455
|
+
createEffect(() => {
|
|
456
|
+
const state = hovered();
|
|
457
|
+
return state;
|
|
458
|
+
}, (state) => {
|
|
459
|
+
globalHandleCallbacks?.onHoveredChange(state);
|
|
460
|
+
});
|
|
461
|
+
const onMouseEnter = (e) => {
|
|
462
|
+
if (callEventHandler(localProps.onMouseEnter, e) || localProps.disabled === true) return;
|
|
463
|
+
setHovered("handle");
|
|
464
|
+
};
|
|
465
|
+
const onMouseLeave = (e) => {
|
|
466
|
+
if (callEventHandler(localProps.onMouseLeave, e)) return;
|
|
467
|
+
setHovered(null);
|
|
468
|
+
};
|
|
469
|
+
const onKeyDown = (e) => {
|
|
470
|
+
if (callEventHandler(localProps.onKeyDown, e) || dragging()) return;
|
|
471
|
+
const element = ref();
|
|
472
|
+
if (!element) return;
|
|
473
|
+
const altKey = localProps.altKey === "only" || localProps.altKey !== false && e.altKey;
|
|
474
|
+
context().onKeyDown(element, e, altKey);
|
|
475
|
+
};
|
|
476
|
+
const onKeyUp = (e) => {
|
|
477
|
+
if (callEventHandler(localProps.onKeyUp, e) || e.key !== "Tab") return;
|
|
478
|
+
setFocused(true);
|
|
479
|
+
};
|
|
480
|
+
const onFocus = (e) => {
|
|
481
|
+
if (callEventHandler(localProps.onFocus, e) || hovered()) return;
|
|
482
|
+
setFocused(true);
|
|
483
|
+
setActive(true);
|
|
484
|
+
};
|
|
485
|
+
const onBlur = (e) => {
|
|
486
|
+
if (callEventHandler(localProps.onBlur, e)) return;
|
|
487
|
+
setFocused(false);
|
|
488
|
+
if (hovered()) return;
|
|
489
|
+
setActive(false);
|
|
490
|
+
};
|
|
491
|
+
const onPointerDown = (e) => {
|
|
492
|
+
if (callEventHandler(localProps.onPointerDown, e)) return;
|
|
493
|
+
if (callEventHandler(localProps.onHandleDragStart, e)) return;
|
|
494
|
+
const targetElement = e.target;
|
|
495
|
+
targetElement.setPointerCapture(e.pointerId);
|
|
496
|
+
let target = "handle";
|
|
497
|
+
if (targetElement.hasAttribute("data-corvu-resizable-handle-start-intersection")) {
|
|
498
|
+
target = "startIntersection";
|
|
499
|
+
}
|
|
500
|
+
if (targetElement.hasAttribute("data-corvu-resizable-handle-end-intersection")) {
|
|
501
|
+
target = "endIntersection";
|
|
502
|
+
}
|
|
503
|
+
globalHandleCallbacks?.onDragStart(e, target);
|
|
504
|
+
};
|
|
505
|
+
return createComponent(Dynamic, mergeProps({
|
|
506
|
+
as: "button",
|
|
507
|
+
ref(r$) {
|
|
508
|
+
var _ref$ = mergeRefs(setRef, localProps.ref);
|
|
509
|
+
typeof _ref$ === "function" && _ref$(r$);
|
|
510
|
+
},
|
|
511
|
+
get style() {
|
|
512
|
+
return combineStyle({
|
|
513
|
+
position: "relative",
|
|
514
|
+
cursor: context().handleCursorStyle() ? "inherit" : void 0,
|
|
515
|
+
"touch-action": "none",
|
|
516
|
+
"flex-shrink": 0
|
|
517
|
+
}, localProps.style);
|
|
518
|
+
},
|
|
519
|
+
get disabled() {
|
|
520
|
+
return localProps.disabled;
|
|
521
|
+
},
|
|
522
|
+
onBlur,
|
|
523
|
+
onFocus,
|
|
524
|
+
onKeyDown,
|
|
525
|
+
onKeyUp,
|
|
526
|
+
onMouseEnter,
|
|
527
|
+
onMouseLeave,
|
|
528
|
+
onPointerDown,
|
|
529
|
+
role: "separator",
|
|
530
|
+
get ["aria-controls"]() {
|
|
531
|
+
return ariaInformation()?.ariaControls;
|
|
532
|
+
},
|
|
533
|
+
get ["aria-orientation"]() {
|
|
534
|
+
return context().orientation();
|
|
535
|
+
},
|
|
536
|
+
get ["aria-valuemax"]() {
|
|
537
|
+
return ariaInformation()?.ariaValueMax;
|
|
538
|
+
},
|
|
539
|
+
get ["aria-valuemin"]() {
|
|
540
|
+
return ariaInformation()?.ariaValueMin;
|
|
541
|
+
},
|
|
542
|
+
get ["aria-valuenow"]() {
|
|
543
|
+
return ariaInformation()?.ariaValueNow;
|
|
544
|
+
},
|
|
545
|
+
get ["data-active"]() {
|
|
546
|
+
return dataIf(active());
|
|
547
|
+
},
|
|
548
|
+
get ["data-dragging"]() {
|
|
549
|
+
return dataIf(dragging());
|
|
550
|
+
},
|
|
551
|
+
get ["data-orientation"]() {
|
|
552
|
+
return context().orientation();
|
|
553
|
+
},
|
|
554
|
+
"data-corvu-resizable-handle": ""
|
|
555
|
+
}, otherProps, {
|
|
556
|
+
get children() {
|
|
557
|
+
return [createComponent(Show, {
|
|
558
|
+
get when() {
|
|
559
|
+
return startIntersectionHandle();
|
|
560
|
+
},
|
|
561
|
+
get children() {
|
|
562
|
+
var _el$ = _tmpl$();
|
|
563
|
+
_el$.addEventListener("mouseleave", (e) => {
|
|
564
|
+
if (ref()?.contains(e.relatedTarget) === true) {
|
|
565
|
+
setHovered("handle");
|
|
566
|
+
} else {
|
|
567
|
+
setHovered(null);
|
|
568
|
+
}
|
|
569
|
+
});
|
|
570
|
+
_el$.addEventListener("mouseenter", () => setHovered("startIntersection"));
|
|
571
|
+
effect((_p$) => {
|
|
572
|
+
var _v$ = context().orientation() === "horizontal" ? void 0 : "100%", _v$2 = context().orientation() === "horizontal" ? "100%" : void 0, _v$3 = context().orientation() === "horizontal" ? "translate3d(0, -100%, 0)" : "translate3d(-100%, 0, 0)";
|
|
573
|
+
_v$ !== _p$.e && setStyleProperty(_el$, "height", _p$.e = _v$);
|
|
574
|
+
_v$2 !== _p$.t && setStyleProperty(_el$, "width", _p$.t = _v$2);
|
|
575
|
+
_v$3 !== _p$.a && setStyleProperty(_el$, "transform", _p$.a = _v$3);
|
|
576
|
+
return _p$;
|
|
577
|
+
}, {
|
|
578
|
+
e: void 0,
|
|
579
|
+
t: void 0,
|
|
580
|
+
a: void 0
|
|
581
|
+
});
|
|
582
|
+
return _el$;
|
|
583
|
+
}
|
|
584
|
+
}), memo(() => localProps.children), createComponent(Show, {
|
|
585
|
+
get when() {
|
|
586
|
+
return endIntersectionHandle();
|
|
587
|
+
},
|
|
588
|
+
get children() {
|
|
589
|
+
var _el$2 = _tmpl$2();
|
|
590
|
+
_el$2.addEventListener("mouseleave", (e) => {
|
|
591
|
+
if (ref()?.contains(e.relatedTarget) === true) {
|
|
592
|
+
setHovered("handle");
|
|
593
|
+
} else {
|
|
594
|
+
setHovered(null);
|
|
595
|
+
}
|
|
596
|
+
});
|
|
597
|
+
_el$2.addEventListener("mouseenter", () => setHovered("endIntersection"));
|
|
598
|
+
effect((_p$) => {
|
|
599
|
+
var _v$4 = context().orientation() === "horizontal" ? void 0 : "100%", _v$5 = context().orientation() === "horizontal" ? "100%" : void 0, _v$6 = context().orientation() === "horizontal" ? "translate3d(0, 100%, 0)" : "translate3d(100%, 0, 0)";
|
|
600
|
+
_v$4 !== _p$.e && setStyleProperty(_el$2, "height", _p$.e = _v$4);
|
|
601
|
+
_v$5 !== _p$.t && setStyleProperty(_el$2, "width", _p$.t = _v$5);
|
|
602
|
+
_v$6 !== _p$.a && setStyleProperty(_el$2, "transform", _p$.a = _v$6);
|
|
603
|
+
return _p$;
|
|
604
|
+
}, {
|
|
605
|
+
e: void 0,
|
|
606
|
+
t: void 0,
|
|
607
|
+
a: void 0
|
|
608
|
+
});
|
|
609
|
+
return _el$2;
|
|
610
|
+
}
|
|
611
|
+
})];
|
|
612
|
+
}
|
|
613
|
+
}));
|
|
614
|
+
};
|
|
615
|
+
var Handle_default = ResizableHandle;
|
|
616
|
+
var ResizablePanelContext = createContext(null);
|
|
617
|
+
var createResizablePanelContext = (contextId) => {
|
|
618
|
+
if (contextId === void 0) return ResizablePanelContext;
|
|
619
|
+
const context = createKeyedContext(
|
|
620
|
+
`resizable-panel-${contextId}`
|
|
621
|
+
);
|
|
622
|
+
return context;
|
|
623
|
+
};
|
|
624
|
+
var useResizablePanelContext = (contextId) => {
|
|
625
|
+
if (contextId === void 0) {
|
|
626
|
+
const context2 = useContext(ResizablePanelContext);
|
|
627
|
+
if (!context2) {
|
|
628
|
+
throw new Error(
|
|
629
|
+
"[corvu]: Resizable panel context not found. Make sure to call usePanelContext under <Resizable.Panel>"
|
|
630
|
+
);
|
|
631
|
+
}
|
|
632
|
+
return context2;
|
|
633
|
+
}
|
|
634
|
+
const context = useKeyedContext(
|
|
635
|
+
`resizable-panel-${contextId}`
|
|
636
|
+
);
|
|
637
|
+
if (!context) {
|
|
638
|
+
throw new Error(
|
|
639
|
+
`[corvu]: Resizable context with id "${contextId}" not found. Make sure to call usePanelContext under <Resizable.Panel contextId="${contextId}">`
|
|
640
|
+
);
|
|
641
|
+
}
|
|
642
|
+
return context;
|
|
643
|
+
};
|
|
644
|
+
var ResizablePanel = (props) => {
|
|
645
|
+
const defaultedProps = merge({
|
|
646
|
+
initialSize: null,
|
|
647
|
+
minSize: 0,
|
|
648
|
+
maxSize: 1,
|
|
649
|
+
collapsible: false,
|
|
650
|
+
collapsedSize: 0,
|
|
651
|
+
collapseThreshold: 0.05,
|
|
652
|
+
panelId: createUniqueId()
|
|
653
|
+
}, props);
|
|
654
|
+
const localProps = defaultedProps;
|
|
655
|
+
const otherProps = omit(defaultedProps, "initialSize", "minSize", "maxSize", "collapsible", "collapsedSize", "collapseThreshold", "onResize", "onCollapse", "onExpand", "contextId", "panelId", "ref", "style", "children");
|
|
656
|
+
const [ref, setRef] = createSignal(null);
|
|
657
|
+
const context = createMemo(() => useInternalResizableContext(localProps.contextId));
|
|
658
|
+
const [panelInstance, setPanelInstance] = createSignal(null);
|
|
659
|
+
createEffect((prev) => {
|
|
660
|
+
const element = ref();
|
|
661
|
+
if (!element) return void 0;
|
|
662
|
+
const _context = context();
|
|
663
|
+
const instance = untrack(() => {
|
|
664
|
+
return _context.registerPanel({
|
|
665
|
+
id: localProps.panelId,
|
|
666
|
+
element,
|
|
667
|
+
initialSize: localProps.initialSize,
|
|
668
|
+
minSize: localProps.minSize,
|
|
669
|
+
maxSize: localProps.maxSize,
|
|
670
|
+
collapsible: localProps.collapsible,
|
|
671
|
+
collapsedSize: localProps.collapsedSize,
|
|
672
|
+
collapseThreshold: localProps.collapseThreshold,
|
|
673
|
+
onResize: localProps.onResize
|
|
674
|
+
});
|
|
675
|
+
});
|
|
676
|
+
setPanelInstance(instance);
|
|
677
|
+
return {
|
|
678
|
+
instance,
|
|
679
|
+
contextRef: context
|
|
680
|
+
};
|
|
681
|
+
}, (_prev) => {
|
|
682
|
+
if (_prev) {
|
|
683
|
+
_prev.contextRef().unregisterPanel(_prev.instance.data.id);
|
|
684
|
+
}
|
|
685
|
+
});
|
|
686
|
+
const panelSize = () => {
|
|
687
|
+
const instance = panelInstance();
|
|
688
|
+
if (!instance) {
|
|
689
|
+
if (typeof localProps.initialSize === "number") {
|
|
690
|
+
return localProps.initialSize;
|
|
691
|
+
}
|
|
692
|
+
return 1;
|
|
693
|
+
}
|
|
694
|
+
return instance.size();
|
|
695
|
+
};
|
|
696
|
+
const collapsed = createMemo((prev) => {
|
|
697
|
+
const instance = panelInstance();
|
|
698
|
+
if (localProps.collapsible !== true) {
|
|
699
|
+
return false;
|
|
700
|
+
}
|
|
701
|
+
const collapsed2 = instance ? instance.size() === resolveSize(localProps.collapsedSize, context().rootSize()) : false;
|
|
702
|
+
if (instance && prev !== collapsed2) {
|
|
703
|
+
if (collapsed2 && localProps.onCollapse !== void 0) {
|
|
704
|
+
localProps.onCollapse(instance.size());
|
|
705
|
+
} else if (!collapsed2 && localProps.onExpand !== void 0) {
|
|
706
|
+
localProps.onExpand(instance.size());
|
|
707
|
+
}
|
|
708
|
+
}
|
|
709
|
+
return collapsed2;
|
|
710
|
+
});
|
|
711
|
+
const resize2 = (size, strategy) => {
|
|
712
|
+
const instance = panelInstance();
|
|
713
|
+
if (!instance) {
|
|
714
|
+
return;
|
|
715
|
+
}
|
|
716
|
+
instance.resize(size, strategy ?? "both");
|
|
717
|
+
};
|
|
718
|
+
const collapse = (strategy) => {
|
|
719
|
+
const instance = panelInstance();
|
|
720
|
+
if (!instance) {
|
|
721
|
+
return;
|
|
722
|
+
}
|
|
723
|
+
instance.collapse(strategy ?? "both");
|
|
724
|
+
};
|
|
725
|
+
const expand = (strategy) => {
|
|
726
|
+
const instance = panelInstance();
|
|
727
|
+
if (!instance) {
|
|
728
|
+
return;
|
|
729
|
+
}
|
|
730
|
+
instance.expand(strategy ?? "both");
|
|
731
|
+
};
|
|
732
|
+
const childrenProps = {
|
|
733
|
+
get size() {
|
|
734
|
+
return panelSize();
|
|
735
|
+
},
|
|
736
|
+
get minSize() {
|
|
737
|
+
return localProps.minSize;
|
|
738
|
+
},
|
|
739
|
+
get maxSize() {
|
|
740
|
+
return localProps.maxSize;
|
|
741
|
+
},
|
|
742
|
+
get collapsible() {
|
|
743
|
+
return localProps.collapsible;
|
|
744
|
+
},
|
|
745
|
+
get collapsedSize() {
|
|
746
|
+
return localProps.collapsedSize;
|
|
747
|
+
},
|
|
748
|
+
get collapseThreshold() {
|
|
749
|
+
return localProps.collapseThreshold;
|
|
750
|
+
},
|
|
751
|
+
get collapsed() {
|
|
752
|
+
return collapsed();
|
|
753
|
+
},
|
|
754
|
+
resize: resize2,
|
|
755
|
+
collapse,
|
|
756
|
+
expand,
|
|
757
|
+
get panelId() {
|
|
758
|
+
return localProps.panelId;
|
|
759
|
+
}
|
|
760
|
+
};
|
|
761
|
+
const memoizedChildren = createOnce(() => localProps.children);
|
|
762
|
+
const resolveChildren = () => {
|
|
763
|
+
const children = memoizedChildren()();
|
|
764
|
+
if (isFunction(children)) {
|
|
765
|
+
return children(childrenProps);
|
|
766
|
+
}
|
|
767
|
+
return children;
|
|
768
|
+
};
|
|
769
|
+
const memoizedResizablePanel = createMemo(() => {
|
|
770
|
+
const ResizablePanelContext2 = createResizablePanelContext(localProps.contextId);
|
|
771
|
+
return createComponent(ResizablePanelContext2, {
|
|
772
|
+
value: {
|
|
773
|
+
size: panelSize,
|
|
774
|
+
minSize: () => localProps.minSize,
|
|
775
|
+
maxSize: () => localProps.maxSize,
|
|
776
|
+
collapsible: () => localProps.collapsible,
|
|
777
|
+
collapsedSize: () => localProps.collapsedSize,
|
|
778
|
+
collapseThreshold: () => localProps.collapseThreshold,
|
|
779
|
+
collapsed,
|
|
780
|
+
resize: resize2,
|
|
781
|
+
collapse,
|
|
782
|
+
expand,
|
|
783
|
+
panelId: () => localProps.panelId
|
|
784
|
+
},
|
|
785
|
+
get children() {
|
|
786
|
+
return createComponent(Dynamic, mergeProps({
|
|
787
|
+
as: "div",
|
|
788
|
+
ref(r$) {
|
|
789
|
+
var _ref$ = mergeRefs(setRef, localProps.ref);
|
|
790
|
+
typeof _ref$ === "function" && _ref$(r$);
|
|
791
|
+
},
|
|
792
|
+
get style() {
|
|
793
|
+
return combineStyle({
|
|
794
|
+
"flex-basis": panelSize() * 100 + "%"
|
|
795
|
+
}, localProps.style);
|
|
796
|
+
},
|
|
797
|
+
get id() {
|
|
798
|
+
return localProps.panelId;
|
|
799
|
+
},
|
|
800
|
+
get ["data-collapsed"]() {
|
|
801
|
+
return dataIf(collapsed());
|
|
802
|
+
},
|
|
803
|
+
get ["data-expanded"]() {
|
|
804
|
+
return dataIf(localProps.collapsible === true && !collapsed());
|
|
805
|
+
},
|
|
806
|
+
get ["data-orientation"]() {
|
|
807
|
+
return context().orientation();
|
|
808
|
+
},
|
|
809
|
+
"data-corvu-resizable-panel": ""
|
|
810
|
+
}, otherProps, {
|
|
811
|
+
get children() {
|
|
812
|
+
return untrack(() => resolveChildren());
|
|
813
|
+
}
|
|
814
|
+
}));
|
|
815
|
+
}
|
|
816
|
+
});
|
|
817
|
+
});
|
|
818
|
+
return memoizedResizablePanel;
|
|
819
|
+
};
|
|
820
|
+
var Panel_default = ResizablePanel;
|
|
821
|
+
var getDistributablePercentage = (props) => {
|
|
822
|
+
let distributablePercentage = props.desiredPercentage >= 0 ? Infinity : -Infinity;
|
|
823
|
+
let newSizes = props.initialSizes;
|
|
824
|
+
for (const resizeAction of props.resizeActions) {
|
|
825
|
+
const desiredPercentage = resizeAction.negate !== true ? props.desiredPercentage : -props.desiredPercentage;
|
|
826
|
+
let [
|
|
827
|
+
distributedPercentagePreceding,
|
|
828
|
+
// eslint-disable-next-line prefer-const
|
|
829
|
+
distributedSizesPreceding,
|
|
830
|
+
// eslint-disable-next-line prefer-const
|
|
831
|
+
collapsedPreceding
|
|
832
|
+
] = distributePercentage({
|
|
833
|
+
desiredPercentage,
|
|
834
|
+
side: "preceding",
|
|
835
|
+
panels: resizeAction.precedingPanels,
|
|
836
|
+
initialSizes: newSizes,
|
|
837
|
+
initialSizesStartIndex: 0,
|
|
838
|
+
collapsible: props.collapsible,
|
|
839
|
+
rootSize: props.resizableData.rootSize
|
|
840
|
+
});
|
|
841
|
+
let [
|
|
842
|
+
distributedPercentageFollowing,
|
|
843
|
+
// eslint-disable-next-line prefer-const
|
|
844
|
+
distributedSizesFollowing,
|
|
845
|
+
// eslint-disable-next-line prefer-const
|
|
846
|
+
collapsedFollowing
|
|
847
|
+
] = distributePercentage({
|
|
848
|
+
desiredPercentage,
|
|
849
|
+
side: "following",
|
|
850
|
+
panels: resizeAction.followingPanels,
|
|
851
|
+
initialSizes: newSizes,
|
|
852
|
+
initialSizesStartIndex: resizeAction.precedingPanels.length,
|
|
853
|
+
collapsible: props.collapsible,
|
|
854
|
+
rootSize: props.resizableData.rootSize
|
|
855
|
+
});
|
|
856
|
+
if (resizeAction.negate === true) {
|
|
857
|
+
distributedPercentagePreceding = -distributedPercentagePreceding;
|
|
858
|
+
distributedPercentageFollowing = -distributedPercentageFollowing;
|
|
859
|
+
}
|
|
860
|
+
if (collapsedPreceding) {
|
|
861
|
+
distributedPercentageFollowing = distributedPercentagePreceding;
|
|
862
|
+
}
|
|
863
|
+
if (collapsedFollowing) {
|
|
864
|
+
distributedPercentagePreceding = distributedPercentageFollowing;
|
|
865
|
+
}
|
|
866
|
+
if (props.desiredPercentage >= 0) {
|
|
867
|
+
distributablePercentage = Math.min(
|
|
868
|
+
distributablePercentage,
|
|
869
|
+
Math.min(
|
|
870
|
+
distributedPercentagePreceding,
|
|
871
|
+
distributedPercentageFollowing
|
|
872
|
+
)
|
|
873
|
+
);
|
|
874
|
+
} else {
|
|
875
|
+
distributablePercentage = Math.max(
|
|
876
|
+
distributablePercentage,
|
|
877
|
+
Math.max(
|
|
878
|
+
distributedPercentagePreceding,
|
|
879
|
+
distributedPercentageFollowing
|
|
880
|
+
)
|
|
881
|
+
);
|
|
882
|
+
}
|
|
883
|
+
newSizes = [...distributedSizesPreceding, ...distributedSizesFollowing];
|
|
884
|
+
}
|
|
885
|
+
return distributablePercentage;
|
|
886
|
+
};
|
|
887
|
+
var distributePercentage = (props) => {
|
|
888
|
+
props.desiredPercentage = fixToPrecision(props.desiredPercentage);
|
|
889
|
+
const resizeDirection = getResizeDirection({
|
|
890
|
+
side: props.side,
|
|
891
|
+
desiredPercentage: props.desiredPercentage
|
|
892
|
+
});
|
|
893
|
+
let distributedPercentage = 0;
|
|
894
|
+
const distributedSizes = props.initialSizes.slice(
|
|
895
|
+
props.initialSizesStartIndex,
|
|
896
|
+
props.initialSizesStartIndex + props.panels.length
|
|
897
|
+
);
|
|
898
|
+
for (let i = props.side === "preceding" ? props.panels.length - 1 : 0; props.side === "preceding" ? i >= 0 : i < props.panels.length; props.side === "preceding" ? i-- : i++) {
|
|
899
|
+
const panel2 = props.panels[i];
|
|
900
|
+
const panelSize2 = props.initialSizes[i + props.initialSizesStartIndex];
|
|
901
|
+
const collapsedSize2 = resolveSize(
|
|
902
|
+
panel2.data.collapsedSize ?? 0,
|
|
903
|
+
props.rootSize
|
|
904
|
+
);
|
|
905
|
+
if (panel2.data.collapsible && panelSize2 === collapsedSize2) continue;
|
|
906
|
+
const availablePercentage2 = fixToPrecision(
|
|
907
|
+
props.desiredPercentage - distributedPercentage
|
|
908
|
+
);
|
|
909
|
+
if (availablePercentage2 === 0) break;
|
|
910
|
+
switch (resizeDirection) {
|
|
911
|
+
case "precedingDecreasing": {
|
|
912
|
+
const minSize2 = resolveSize(panel2.data.minSize, props.rootSize);
|
|
913
|
+
distributedSizes[i] = Math.max(minSize2, panelSize2 + availablePercentage2);
|
|
914
|
+
distributedPercentage += distributedSizes[i] - panelSize2;
|
|
915
|
+
break;
|
|
916
|
+
}
|
|
917
|
+
case "followingDecreasing": {
|
|
918
|
+
const minSize2 = resolveSize(panel2.data.minSize, props.rootSize);
|
|
919
|
+
distributedSizes[i] = Math.max(minSize2, panelSize2 - availablePercentage2);
|
|
920
|
+
distributedPercentage -= distributedSizes[i] - panelSize2;
|
|
921
|
+
break;
|
|
922
|
+
}
|
|
923
|
+
case "precedingIncreasing": {
|
|
924
|
+
const maxSize = resolveSize(panel2.data.maxSize, props.rootSize);
|
|
925
|
+
distributedSizes[i] = Math.min(maxSize, panelSize2 + availablePercentage2);
|
|
926
|
+
distributedPercentage += distributedSizes[i] - panelSize2;
|
|
927
|
+
break;
|
|
928
|
+
}
|
|
929
|
+
case "followingIncreasing": {
|
|
930
|
+
const maxSize = resolveSize(panel2.data.maxSize, props.rootSize);
|
|
931
|
+
distributedSizes[i] = Math.min(maxSize, panelSize2 - availablePercentage2);
|
|
932
|
+
distributedPercentage -= distributedSizes[i] - panelSize2;
|
|
933
|
+
break;
|
|
934
|
+
}
|
|
935
|
+
}
|
|
936
|
+
}
|
|
937
|
+
distributedPercentage = fixToPrecision(distributedPercentage);
|
|
938
|
+
if (!props.collapsible || distributedPercentage === props.desiredPercentage) {
|
|
939
|
+
return [distributedPercentage, distributedSizes, false];
|
|
940
|
+
}
|
|
941
|
+
const panelIndex = props.side === "preceding" ? props.panels.length - 1 : 0;
|
|
942
|
+
const panel = props.panels[panelIndex];
|
|
943
|
+
if (!panel.data.collapsible) {
|
|
944
|
+
return [distributedPercentage, distributedSizes, false];
|
|
945
|
+
}
|
|
946
|
+
const availablePercentage = fixToPrecision(
|
|
947
|
+
props.desiredPercentage - distributedPercentage
|
|
948
|
+
);
|
|
949
|
+
let collapsed = false;
|
|
950
|
+
const panelSize = props.initialSizes[panelIndex + props.initialSizesStartIndex];
|
|
951
|
+
const minSize = resolveSize(panel.data.minSize, props.rootSize);
|
|
952
|
+
const collapsedSize = resolveSize(
|
|
953
|
+
panel.data.collapsedSize ?? 0,
|
|
954
|
+
props.rootSize
|
|
955
|
+
);
|
|
956
|
+
const collapseThreshold = Math.min(
|
|
957
|
+
resolveSize(panel.data.collapseThreshold ?? 0, props.rootSize),
|
|
958
|
+
minSize - collapsedSize
|
|
959
|
+
);
|
|
960
|
+
const isCollapsed = panelSize === collapsedSize;
|
|
961
|
+
if (resizeDirection === "precedingDecreasing" && !isCollapsed && Math.abs(availablePercentage) >= collapseThreshold) {
|
|
962
|
+
distributedPercentage -= distributedSizes[panelIndex] - panelSize;
|
|
963
|
+
distributedSizes[panelIndex] = collapsedSize;
|
|
964
|
+
distributedPercentage += distributedSizes[panelIndex] - panelSize;
|
|
965
|
+
collapsed = true;
|
|
966
|
+
} else if (resizeDirection === "precedingIncreasing" && isCollapsed && Math.abs(availablePercentage) >= collapseThreshold) {
|
|
967
|
+
const minSize2 = resolveSize(panel.data.minSize, props.rootSize);
|
|
968
|
+
distributedSizes[panelIndex] = minSize2;
|
|
969
|
+
if (Math.abs(availablePercentage) >= minSize2 - collapsedSize) {
|
|
970
|
+
const maxSize = resolveSize(panel.data.maxSize, props.rootSize);
|
|
971
|
+
distributedSizes[panelIndex] = Math.min(
|
|
972
|
+
maxSize,
|
|
973
|
+
panelSize + availablePercentage
|
|
974
|
+
);
|
|
975
|
+
} else {
|
|
976
|
+
collapsed = true;
|
|
977
|
+
}
|
|
978
|
+
distributedPercentage += distributedSizes[panelIndex] - panelSize;
|
|
979
|
+
} else if (resizeDirection === "followingDecreasing" && !isCollapsed && Math.abs(availablePercentage) >= collapseThreshold) {
|
|
980
|
+
distributedPercentage += distributedSizes[panelIndex] - panelSize;
|
|
981
|
+
distributedSizes[panelIndex] = collapsedSize;
|
|
982
|
+
distributedPercentage -= distributedSizes[panelIndex] - panelSize;
|
|
983
|
+
collapsed = true;
|
|
984
|
+
} else if (resizeDirection === "followingIncreasing" && isCollapsed && Math.abs(availablePercentage) >= collapseThreshold) {
|
|
985
|
+
const minSize2 = resolveSize(panel.data.minSize, props.rootSize);
|
|
986
|
+
distributedSizes[panelIndex] = minSize2;
|
|
987
|
+
if (Math.abs(availablePercentage) >= minSize2 - collapsedSize) {
|
|
988
|
+
const maxSize = resolveSize(panel.data.maxSize, props.rootSize);
|
|
989
|
+
distributedSizes[panelIndex] = Math.min(
|
|
990
|
+
maxSize,
|
|
991
|
+
panelSize - availablePercentage
|
|
992
|
+
);
|
|
993
|
+
} else {
|
|
994
|
+
collapsed = true;
|
|
995
|
+
}
|
|
996
|
+
distributedPercentage -= distributedSizes[panelIndex] - panelSize;
|
|
997
|
+
}
|
|
998
|
+
return [distributedPercentage, distributedSizes, collapsed];
|
|
999
|
+
};
|
|
1000
|
+
var getResizeDirection = (props) => {
|
|
1001
|
+
switch (props.side) {
|
|
1002
|
+
case "preceding":
|
|
1003
|
+
return props.desiredPercentage >= 0 ? "precedingIncreasing" : "precedingDecreasing";
|
|
1004
|
+
case "following":
|
|
1005
|
+
return props.desiredPercentage >= 0 ? "followingDecreasing" : "followingIncreasing";
|
|
1006
|
+
}
|
|
1007
|
+
};
|
|
1008
|
+
var resize = (props) => {
|
|
1009
|
+
let newSizes = props.initialSizes;
|
|
1010
|
+
for (const resizeAction of props.resizeActions) {
|
|
1011
|
+
const [, distributedSizesPreceding] = distributePercentage({
|
|
1012
|
+
desiredPercentage: resizeAction.deltaPercentage,
|
|
1013
|
+
side: "preceding",
|
|
1014
|
+
panels: resizeAction.precedingPanels,
|
|
1015
|
+
initialSizes: newSizes,
|
|
1016
|
+
initialSizesStartIndex: 0,
|
|
1017
|
+
collapsible: props.collapsible,
|
|
1018
|
+
rootSize: props.resizableData.rootSize
|
|
1019
|
+
});
|
|
1020
|
+
const [, distributedSizesFollowing] = distributePercentage({
|
|
1021
|
+
desiredPercentage: resizeAction.deltaPercentage,
|
|
1022
|
+
side: "following",
|
|
1023
|
+
panels: resizeAction.followingPanels,
|
|
1024
|
+
initialSizes: newSizes,
|
|
1025
|
+
initialSizesStartIndex: resizeAction.precedingPanels.length,
|
|
1026
|
+
collapsible: props.collapsible,
|
|
1027
|
+
rootSize: props.resizableData.rootSize
|
|
1028
|
+
});
|
|
1029
|
+
newSizes = [...distributedSizesPreceding, ...distributedSizesFollowing];
|
|
1030
|
+
}
|
|
1031
|
+
newSizes = newSizes.map(fixToPrecision);
|
|
1032
|
+
const totalSize = newSizes.reduce((totalSize2, size) => totalSize2 + size, 0);
|
|
1033
|
+
if (totalSize !== 1) {
|
|
1034
|
+
const offset = totalSize - 1;
|
|
1035
|
+
const offsetPerPanel = offset / newSizes.length;
|
|
1036
|
+
newSizes = newSizes.map((size) => size - offsetPerPanel);
|
|
1037
|
+
}
|
|
1038
|
+
props.resizableData.setSizes(newSizes.map(fixToPrecision));
|
|
1039
|
+
};
|
|
1040
|
+
var resizePanel = (props) => {
|
|
1041
|
+
let [precedingPanels, followingPanels] = splitPanels({
|
|
1042
|
+
panels: props.panels,
|
|
1043
|
+
focusedElement: props.panel.data.element
|
|
1044
|
+
});
|
|
1045
|
+
const panelIndex = props.panels.indexOf(props.panel);
|
|
1046
|
+
if (panelIndex === 0) {
|
|
1047
|
+
props.strategy = "following";
|
|
1048
|
+
} else if (panelIndex === props.panels.length - 1) {
|
|
1049
|
+
props.strategy = "preceding";
|
|
1050
|
+
}
|
|
1051
|
+
if (props.strategy === "both") {
|
|
1052
|
+
const precedingPanelsIncluding = [...precedingPanels, props.panel];
|
|
1053
|
+
const followingPanelsIncluding = [props.panel, ...followingPanels];
|
|
1054
|
+
const distributablePercentage = getDistributablePercentage({
|
|
1055
|
+
desiredPercentage: props.deltaPercentage / 2,
|
|
1056
|
+
initialSizes: props.initialSizes,
|
|
1057
|
+
collapsible: true,
|
|
1058
|
+
resizeActions: [
|
|
1059
|
+
{
|
|
1060
|
+
precedingPanels: precedingPanelsIncluding,
|
|
1061
|
+
followingPanels
|
|
1062
|
+
},
|
|
1063
|
+
{
|
|
1064
|
+
precedingPanels,
|
|
1065
|
+
followingPanels: followingPanelsIncluding,
|
|
1066
|
+
negate: true
|
|
1067
|
+
}
|
|
1068
|
+
],
|
|
1069
|
+
resizableData: {
|
|
1070
|
+
rootSize: props.resizableData.rootSize
|
|
1071
|
+
}
|
|
1072
|
+
});
|
|
1073
|
+
resize({
|
|
1074
|
+
initialSizes: props.initialSizes,
|
|
1075
|
+
collapsible: true,
|
|
1076
|
+
resizeActions: [
|
|
1077
|
+
{
|
|
1078
|
+
precedingPanels: precedingPanelsIncluding,
|
|
1079
|
+
followingPanels,
|
|
1080
|
+
deltaPercentage: distributablePercentage
|
|
1081
|
+
},
|
|
1082
|
+
{
|
|
1083
|
+
precedingPanels,
|
|
1084
|
+
followingPanels: followingPanelsIncluding,
|
|
1085
|
+
deltaPercentage: -distributablePercentage
|
|
1086
|
+
}
|
|
1087
|
+
],
|
|
1088
|
+
resizableData: props.resizableData
|
|
1089
|
+
});
|
|
1090
|
+
} else {
|
|
1091
|
+
precedingPanels = props.strategy === "preceding" ? precedingPanels : [...precedingPanels, props.panel];
|
|
1092
|
+
followingPanels = props.strategy === "following" ? followingPanels : [props.panel, ...followingPanels];
|
|
1093
|
+
if (props.strategy === "preceding") {
|
|
1094
|
+
props.deltaPercentage = -props.deltaPercentage;
|
|
1095
|
+
}
|
|
1096
|
+
const distributablePercentage = getDistributablePercentage({
|
|
1097
|
+
desiredPercentage: props.deltaPercentage,
|
|
1098
|
+
initialSizes: props.initialSizes,
|
|
1099
|
+
collapsible: props.collapsible,
|
|
1100
|
+
resizeActions: [
|
|
1101
|
+
{
|
|
1102
|
+
precedingPanels,
|
|
1103
|
+
followingPanels
|
|
1104
|
+
}
|
|
1105
|
+
],
|
|
1106
|
+
resizableData: {
|
|
1107
|
+
rootSize: props.resizableData.rootSize
|
|
1108
|
+
}
|
|
1109
|
+
});
|
|
1110
|
+
resize({
|
|
1111
|
+
initialSizes: props.initialSizes,
|
|
1112
|
+
collapsible: true,
|
|
1113
|
+
resizeActions: [
|
|
1114
|
+
{
|
|
1115
|
+
precedingPanels,
|
|
1116
|
+
followingPanels,
|
|
1117
|
+
deltaPercentage: distributablePercentage
|
|
1118
|
+
}
|
|
1119
|
+
],
|
|
1120
|
+
resizableData: props.resizableData
|
|
1121
|
+
});
|
|
1122
|
+
}
|
|
1123
|
+
};
|
|
1124
|
+
var deltaResize = (props) => {
|
|
1125
|
+
if (props.altKey && props.panels.length > 2) {
|
|
1126
|
+
let panelIndex = props.panels.filter(
|
|
1127
|
+
(panel2) => !!(props.handle.compareDocumentPosition(panel2.data.element) & Node.DOCUMENT_POSITION_PRECEDING)
|
|
1128
|
+
).length - 1;
|
|
1129
|
+
const isPrecedingHandle = panelIndex === 0;
|
|
1130
|
+
if (isPrecedingHandle) {
|
|
1131
|
+
panelIndex++;
|
|
1132
|
+
props.deltaPercentage = -props.deltaPercentage;
|
|
1133
|
+
}
|
|
1134
|
+
const panel = props.panels[panelIndex];
|
|
1135
|
+
const panelSize = props.initialSizes[panelIndex];
|
|
1136
|
+
const minDelta = resolveSize(panel.data.minSize, props.resizableData.rootSize) - panelSize;
|
|
1137
|
+
const maxDelta = resolveSize(panel.data.maxSize, props.resizableData.rootSize) - panelSize;
|
|
1138
|
+
const cappedDeltaPercentage = Math.max(minDelta, Math.min(props.deltaPercentage * 2, maxDelta)) / 2;
|
|
1139
|
+
const [precedingPanels, followingPanels] = splitPanels({
|
|
1140
|
+
panels: props.panels,
|
|
1141
|
+
focusedElement: panel.data.element
|
|
1142
|
+
});
|
|
1143
|
+
const precedingPanelsIncluding = [...precedingPanels, panel];
|
|
1144
|
+
const followingPanelsIncluding = [panel, ...followingPanels];
|
|
1145
|
+
const distributablePercentage = getDistributablePercentage({
|
|
1146
|
+
desiredPercentage: cappedDeltaPercentage,
|
|
1147
|
+
initialSizes: props.initialSizes,
|
|
1148
|
+
collapsible: false,
|
|
1149
|
+
resizeActions: [
|
|
1150
|
+
{
|
|
1151
|
+
precedingPanels: precedingPanelsIncluding,
|
|
1152
|
+
followingPanels
|
|
1153
|
+
},
|
|
1154
|
+
{
|
|
1155
|
+
precedingPanels,
|
|
1156
|
+
followingPanels: followingPanelsIncluding,
|
|
1157
|
+
negate: true
|
|
1158
|
+
}
|
|
1159
|
+
],
|
|
1160
|
+
resizableData: {
|
|
1161
|
+
rootSize: props.resizableData.rootSize
|
|
1162
|
+
}
|
|
1163
|
+
});
|
|
1164
|
+
if (props.resizableData.handleCursorStyle === true) {
|
|
1165
|
+
handleResizeConstraints({
|
|
1166
|
+
orientation: props.resizableData.orientation,
|
|
1167
|
+
desiredPercentage: props.deltaPercentage,
|
|
1168
|
+
distributablePercentage,
|
|
1169
|
+
revertConstraints: isPrecedingHandle
|
|
1170
|
+
});
|
|
1171
|
+
}
|
|
1172
|
+
resize({
|
|
1173
|
+
initialSizes: props.initialSizes,
|
|
1174
|
+
collapsible: false,
|
|
1175
|
+
resizeActions: [
|
|
1176
|
+
{
|
|
1177
|
+
precedingPanels: precedingPanelsIncluding,
|
|
1178
|
+
followingPanels,
|
|
1179
|
+
deltaPercentage: distributablePercentage
|
|
1180
|
+
},
|
|
1181
|
+
{
|
|
1182
|
+
precedingPanels,
|
|
1183
|
+
followingPanels: followingPanelsIncluding,
|
|
1184
|
+
deltaPercentage: -distributablePercentage
|
|
1185
|
+
}
|
|
1186
|
+
],
|
|
1187
|
+
resizableData: props.resizableData
|
|
1188
|
+
});
|
|
1189
|
+
} else {
|
|
1190
|
+
const [precedingPanels, followingPanels] = splitPanels({
|
|
1191
|
+
panels: props.panels,
|
|
1192
|
+
focusedElement: props.handle
|
|
1193
|
+
});
|
|
1194
|
+
const distributablePercentage = getDistributablePercentage({
|
|
1195
|
+
desiredPercentage: props.deltaPercentage,
|
|
1196
|
+
initialSizes: props.initialSizes,
|
|
1197
|
+
collapsible: true,
|
|
1198
|
+
resizeActions: [
|
|
1199
|
+
{
|
|
1200
|
+
precedingPanels,
|
|
1201
|
+
followingPanels
|
|
1202
|
+
}
|
|
1203
|
+
],
|
|
1204
|
+
resizableData: {
|
|
1205
|
+
rootSize: props.resizableData.rootSize
|
|
1206
|
+
}
|
|
1207
|
+
});
|
|
1208
|
+
resize({
|
|
1209
|
+
initialSizes: props.initialSizes,
|
|
1210
|
+
collapsible: true,
|
|
1211
|
+
resizeActions: [
|
|
1212
|
+
{
|
|
1213
|
+
precedingPanels,
|
|
1214
|
+
followingPanels,
|
|
1215
|
+
deltaPercentage: distributablePercentage
|
|
1216
|
+
}
|
|
1217
|
+
],
|
|
1218
|
+
resizableData: props.resizableData
|
|
1219
|
+
});
|
|
1220
|
+
if (props.resizableData.handleCursorStyle) {
|
|
1221
|
+
const fixedDesiredPercentage = fixToPrecision(props.deltaPercentage);
|
|
1222
|
+
const fixedDistributablePercentage = fixToPrecision(
|
|
1223
|
+
distributablePercentage
|
|
1224
|
+
);
|
|
1225
|
+
let betweenCollapse = false;
|
|
1226
|
+
const precedingPanel = precedingPanels[precedingPanels.length - 1];
|
|
1227
|
+
if (precedingPanel.data.collapsible) {
|
|
1228
|
+
const precedingCollapsedSize = resolveSize(
|
|
1229
|
+
precedingPanel.data.collapsedSize ?? 0,
|
|
1230
|
+
props.resizableData.rootSize
|
|
1231
|
+
);
|
|
1232
|
+
if (precedingPanel.size() === precedingCollapsedSize && fixedDesiredPercentage > fixedDistributablePercentage || precedingPanel.size() !== precedingCollapsedSize && fixedDesiredPercentage < fixedDistributablePercentage) {
|
|
1233
|
+
betweenCollapse = true;
|
|
1234
|
+
}
|
|
1235
|
+
}
|
|
1236
|
+
const followingPanel = followingPanels[0];
|
|
1237
|
+
if (followingPanel.data.collapsible) {
|
|
1238
|
+
const followingCollapsedSize = resolveSize(
|
|
1239
|
+
followingPanel.data.collapsedSize ?? 0,
|
|
1240
|
+
props.resizableData.rootSize
|
|
1241
|
+
);
|
|
1242
|
+
if (followingPanel.size() === followingCollapsedSize && fixedDesiredPercentage < fixedDistributablePercentage || followingPanel.size() !== followingCollapsedSize && fixedDesiredPercentage > fixedDistributablePercentage) {
|
|
1243
|
+
betweenCollapse = true;
|
|
1244
|
+
}
|
|
1245
|
+
}
|
|
1246
|
+
handleResizeConstraints({
|
|
1247
|
+
orientation: props.resizableData.orientation,
|
|
1248
|
+
desiredPercentage: props.deltaPercentage,
|
|
1249
|
+
distributablePercentage,
|
|
1250
|
+
betweenCollapse
|
|
1251
|
+
});
|
|
1252
|
+
}
|
|
1253
|
+
}
|
|
1254
|
+
};
|
|
1255
|
+
var ResizableRoot = (props) => {
|
|
1256
|
+
const defaultedProps = merge({
|
|
1257
|
+
orientation: "horizontal",
|
|
1258
|
+
initialSizes: [],
|
|
1259
|
+
keyboardDelta: 0.1,
|
|
1260
|
+
handleCursorStyle: true
|
|
1261
|
+
}, props);
|
|
1262
|
+
const localProps = defaultedProps;
|
|
1263
|
+
const otherProps = omit(defaultedProps, "orientation", "sizes", "onSizesChange", "initialSizes", "keyboardDelta", "handleCursorStyle", "contextId", "ref", "style", "children");
|
|
1264
|
+
const [sizes, setSizes] = createControllableSignal({
|
|
1265
|
+
value: () => localProps.sizes,
|
|
1266
|
+
initialValue: [],
|
|
1267
|
+
onChange: localProps.onSizesChange
|
|
1268
|
+
});
|
|
1269
|
+
const [ref, setRef] = createSignal(null);
|
|
1270
|
+
const rootSize = createSize({
|
|
1271
|
+
element: ref,
|
|
1272
|
+
dimension: () => localProps.orientation === "horizontal" ? "width" : "height"
|
|
1273
|
+
});
|
|
1274
|
+
const [panels, setPanels] = createSignal([]);
|
|
1275
|
+
const sizesToIds = [];
|
|
1276
|
+
const registerPanel = (panelData) => {
|
|
1277
|
+
const _panels = panels();
|
|
1278
|
+
const panelIndex = _panels.filter((panel2) => !!(panelData.element.compareDocumentPosition(panel2.data.element) & Node.DOCUMENT_POSITION_PRECEDING)).length;
|
|
1279
|
+
const idExists = sizesToIds[panelIndex] === void 0 || sizesToIds[panelIndex] === panelData.id;
|
|
1280
|
+
const sizeExists = sizes()[panelIndex] !== void 0;
|
|
1281
|
+
let panelSize = null;
|
|
1282
|
+
if (panelData.initialSize !== null) {
|
|
1283
|
+
panelSize = resolveSize(panelData.initialSize, rootSize());
|
|
1284
|
+
} else if (localProps.initialSizes[panelIndex] !== void 0 && idExists) {
|
|
1285
|
+
panelSize = resolveSize(localProps.initialSizes[panelIndex], rootSize());
|
|
1286
|
+
}
|
|
1287
|
+
panelSize = panelSize ?? 0.5;
|
|
1288
|
+
setSizes((sizes2) => {
|
|
1289
|
+
let newSizes = [...sizes2];
|
|
1290
|
+
const previousTotalSize = newSizes.reduce((totalSize, size) => totalSize + size, 0);
|
|
1291
|
+
if ((idExists && !sizeExists || !idExists) && previousTotalSize === 1) {
|
|
1292
|
+
const offsetPerPanel = panelSize / newSizes.length;
|
|
1293
|
+
newSizes = newSizes.map((size) => size - offsetPerPanel);
|
|
1294
|
+
}
|
|
1295
|
+
if (idExists) {
|
|
1296
|
+
if (!sizeExists) {
|
|
1297
|
+
newSizes[panelIndex] = panelSize;
|
|
1298
|
+
}
|
|
1299
|
+
sizesToIds[panelIndex] = panelData.id;
|
|
1300
|
+
} else {
|
|
1301
|
+
newSizes.splice(panelIndex, 0, panelSize);
|
|
1302
|
+
sizesToIds.splice(panelIndex, 0, panelData.id);
|
|
1303
|
+
}
|
|
1304
|
+
return newSizes;
|
|
1305
|
+
});
|
|
1306
|
+
const panelSizeMemo = createMemo(() => {
|
|
1307
|
+
const index = sizesToIds.indexOf(panelData.id);
|
|
1308
|
+
return sizes()[index];
|
|
1309
|
+
});
|
|
1310
|
+
createEffect(() => panelData.onResize?.(panelSizeMemo()));
|
|
1311
|
+
const panel = {
|
|
1312
|
+
data: panelData,
|
|
1313
|
+
size: panelSizeMemo,
|
|
1314
|
+
resize: (size, strategy) => resize2(sizesToIds.indexOf(panelData.id), size, strategy),
|
|
1315
|
+
collapse: (strategy) => collapse(sizesToIds.indexOf(panelData.id), strategy),
|
|
1316
|
+
expand: (strategy) => expand(sizesToIds.indexOf(panelData.id), strategy)
|
|
1317
|
+
};
|
|
1318
|
+
setPanels((panels2) => {
|
|
1319
|
+
const newPanels = [...panels2];
|
|
1320
|
+
newPanels.push(panel);
|
|
1321
|
+
newPanels.sort((a, b) => sortByDocumentPosition(a.data.element, b.data.element));
|
|
1322
|
+
return newPanels;
|
|
1323
|
+
});
|
|
1324
|
+
return panel;
|
|
1325
|
+
};
|
|
1326
|
+
const unregisterPanel = (id) => {
|
|
1327
|
+
setPanels((panels2) => panels2.filter((panel) => panel.data.id !== id));
|
|
1328
|
+
const panelSizeIndex = sizesToIds.indexOf(id);
|
|
1329
|
+
sizesToIds.splice(panelSizeIndex, 1);
|
|
1330
|
+
setSizes((sizes2) => {
|
|
1331
|
+
let newSizes = [...sizes2];
|
|
1332
|
+
newSizes.splice(panelSizeIndex, 1);
|
|
1333
|
+
const totalSize = newSizes.reduce((totalSize2, size) => totalSize2 + size, 0);
|
|
1334
|
+
const offset = totalSize - 1;
|
|
1335
|
+
const offsetPerPanel = offset / newSizes.length;
|
|
1336
|
+
newSizes = newSizes.map((size) => size + offsetPerPanel);
|
|
1337
|
+
return newSizes;
|
|
1338
|
+
});
|
|
1339
|
+
};
|
|
1340
|
+
createEffect(() => {
|
|
1341
|
+
if (localProps.onSizesChange !== void 0) {
|
|
1342
|
+
localProps.onSizesChange(sizes());
|
|
1343
|
+
}
|
|
1344
|
+
});
|
|
1345
|
+
const resize2 = (panelIndex, size, strategy) => {
|
|
1346
|
+
untrack(() => {
|
|
1347
|
+
const panel = panels()[panelIndex];
|
|
1348
|
+
if (!panel) return;
|
|
1349
|
+
const minSize = resolveSize(panel.data.minSize, rootSize());
|
|
1350
|
+
const maxSize = resolveSize(panel.data.maxSize, rootSize());
|
|
1351
|
+
const newSize = resolveSize(size, rootSize());
|
|
1352
|
+
const allowedSize = Math.max(minSize, Math.min(newSize, maxSize));
|
|
1353
|
+
const deltaPercentage = allowedSize - sizes()[panelIndex];
|
|
1354
|
+
resizePanel({
|
|
1355
|
+
deltaPercentage,
|
|
1356
|
+
strategy: strategy ?? "both",
|
|
1357
|
+
panel,
|
|
1358
|
+
panels: panels(),
|
|
1359
|
+
initialSizes: panels().map((panel2) => panel2.size()),
|
|
1360
|
+
collapsible: false,
|
|
1361
|
+
resizableData: {
|
|
1362
|
+
rootSize: rootSize(),
|
|
1363
|
+
orientation: localProps.orientation,
|
|
1364
|
+
setSizes
|
|
1365
|
+
}
|
|
1366
|
+
});
|
|
1367
|
+
});
|
|
1368
|
+
};
|
|
1369
|
+
const collapse = (panelIndex, strategy) => {
|
|
1370
|
+
untrack(() => {
|
|
1371
|
+
const panel = panels()[panelIndex];
|
|
1372
|
+
if (!panel) return;
|
|
1373
|
+
const panelSize = sizes()[panelIndex];
|
|
1374
|
+
const collapsedSize = resolveSize(panel.data.collapsedSize ?? 0, rootSize());
|
|
1375
|
+
if (!panel.data.collapsible || panelSize === collapsedSize) return;
|
|
1376
|
+
const deltaPercentage = collapsedSize - panelSize;
|
|
1377
|
+
resizePanel({
|
|
1378
|
+
deltaPercentage,
|
|
1379
|
+
strategy: strategy ?? "both",
|
|
1380
|
+
panel,
|
|
1381
|
+
panels: panels(),
|
|
1382
|
+
initialSizes: panels().map((panel2) => panel2.size()),
|
|
1383
|
+
collapsible: true,
|
|
1384
|
+
resizableData: {
|
|
1385
|
+
rootSize: rootSize(),
|
|
1386
|
+
orientation: localProps.orientation,
|
|
1387
|
+
setSizes
|
|
1388
|
+
}
|
|
1389
|
+
});
|
|
1390
|
+
});
|
|
1391
|
+
};
|
|
1392
|
+
const expand = (panelIndex, strategy) => {
|
|
1393
|
+
untrack(() => {
|
|
1394
|
+
const panel = panels()[panelIndex];
|
|
1395
|
+
if (!panel) return;
|
|
1396
|
+
const panelSize = sizes()[panelIndex];
|
|
1397
|
+
const collapsedSize = resolveSize(panel.data.collapsedSize ?? 0, rootSize());
|
|
1398
|
+
if (!panel.data.collapsible || panelSize !== collapsedSize) return;
|
|
1399
|
+
const minSize = resolveSize(panel.data.minSize, rootSize());
|
|
1400
|
+
const deltaPercentage = minSize - panelSize;
|
|
1401
|
+
resizePanel({
|
|
1402
|
+
deltaPercentage,
|
|
1403
|
+
strategy: strategy ?? "both",
|
|
1404
|
+
panel,
|
|
1405
|
+
panels: panels(),
|
|
1406
|
+
initialSizes: panels().map((panel2) => panel2.size()),
|
|
1407
|
+
collapsible: true,
|
|
1408
|
+
resizableData: {
|
|
1409
|
+
rootSize: rootSize(),
|
|
1410
|
+
orientation: localProps.orientation,
|
|
1411
|
+
setSizes
|
|
1412
|
+
}
|
|
1413
|
+
});
|
|
1414
|
+
});
|
|
1415
|
+
};
|
|
1416
|
+
let initialSizes = null;
|
|
1417
|
+
let altKeyCache2 = false;
|
|
1418
|
+
const onDrag = (handle, delta, altKey) => {
|
|
1419
|
+
if (initialSizes === null || altKeyCache2 !== altKey) {
|
|
1420
|
+
initialSizes = panels().map((panel) => panel.size());
|
|
1421
|
+
altKeyCache2 = altKey;
|
|
1422
|
+
}
|
|
1423
|
+
deltaResize({
|
|
1424
|
+
deltaPercentage: delta / rootSize(),
|
|
1425
|
+
altKey,
|
|
1426
|
+
handle,
|
|
1427
|
+
panels: panels(),
|
|
1428
|
+
initialSizes,
|
|
1429
|
+
resizableData: {
|
|
1430
|
+
rootSize: rootSize(),
|
|
1431
|
+
handleCursorStyle: localProps.handleCursorStyle,
|
|
1432
|
+
orientation: localProps.orientation,
|
|
1433
|
+
setSizes
|
|
1434
|
+
}
|
|
1435
|
+
});
|
|
1436
|
+
};
|
|
1437
|
+
const onKeyDown = (handle, event, altKey) => {
|
|
1438
|
+
if (event.key === "Enter") {
|
|
1439
|
+
const [precedingPanels, followingPanels] = splitPanels({
|
|
1440
|
+
panels: panels(),
|
|
1441
|
+
focusedElement: handle
|
|
1442
|
+
});
|
|
1443
|
+
let collapsiblePanel = precedingPanels[precedingPanels.length - 1];
|
|
1444
|
+
if (!collapsiblePanel || !collapsiblePanel.data.collapsible) {
|
|
1445
|
+
collapsiblePanel = followingPanels[0];
|
|
1446
|
+
if (!collapsiblePanel || !collapsiblePanel.data.collapsible) return;
|
|
1447
|
+
}
|
|
1448
|
+
const size = collapsiblePanel.size();
|
|
1449
|
+
const collapsedSize = resolveSize(collapsiblePanel.data.collapsedSize ?? 0, rootSize());
|
|
1450
|
+
if (size === collapsedSize) {
|
|
1451
|
+
collapsiblePanel.expand("following");
|
|
1452
|
+
} else {
|
|
1453
|
+
collapsiblePanel.collapse("following");
|
|
1454
|
+
}
|
|
1455
|
+
return;
|
|
1456
|
+
}
|
|
1457
|
+
let deltaPercentage = null;
|
|
1458
|
+
if (localProps.orientation === "horizontal" && event.key === "ArrowLeft" || localProps.orientation === "vertical" && event.key === "ArrowUp" || event.key === "Home") {
|
|
1459
|
+
if (event.shiftKey || event.key === "Home") {
|
|
1460
|
+
deltaPercentage = -1;
|
|
1461
|
+
} else {
|
|
1462
|
+
deltaPercentage = -resolveSize(localProps.keyboardDelta, rootSize());
|
|
1463
|
+
}
|
|
1464
|
+
} else if (localProps.orientation === "horizontal" && event.key === "ArrowRight" || localProps.orientation === "vertical" && event.key === "ArrowDown" || event.key === "End") {
|
|
1465
|
+
if (event.shiftKey || event.key === "End") {
|
|
1466
|
+
deltaPercentage = 1;
|
|
1467
|
+
} else {
|
|
1468
|
+
deltaPercentage = resolveSize(localProps.keyboardDelta, rootSize());
|
|
1469
|
+
}
|
|
1470
|
+
}
|
|
1471
|
+
if (deltaPercentage === null) return;
|
|
1472
|
+
event.preventDefault();
|
|
1473
|
+
const initialSizes2 = panels().map((panel) => panel.size());
|
|
1474
|
+
deltaResize({
|
|
1475
|
+
deltaPercentage,
|
|
1476
|
+
altKey,
|
|
1477
|
+
handle,
|
|
1478
|
+
panels: panels(),
|
|
1479
|
+
initialSizes: initialSizes2,
|
|
1480
|
+
resizableData: {
|
|
1481
|
+
rootSize: rootSize(),
|
|
1482
|
+
handleCursorStyle: false,
|
|
1483
|
+
orientation: localProps.orientation,
|
|
1484
|
+
setSizes
|
|
1485
|
+
}
|
|
1486
|
+
});
|
|
1487
|
+
};
|
|
1488
|
+
const childrenProps = {
|
|
1489
|
+
get sizes() {
|
|
1490
|
+
return sizes();
|
|
1491
|
+
},
|
|
1492
|
+
setSizes,
|
|
1493
|
+
get orientation() {
|
|
1494
|
+
return localProps.orientation;
|
|
1495
|
+
},
|
|
1496
|
+
get keyboardDelta() {
|
|
1497
|
+
return localProps.keyboardDelta;
|
|
1498
|
+
},
|
|
1499
|
+
get handleCursorStyle() {
|
|
1500
|
+
return localProps.handleCursorStyle;
|
|
1501
|
+
},
|
|
1502
|
+
resize: resize2,
|
|
1503
|
+
collapse,
|
|
1504
|
+
expand
|
|
1505
|
+
};
|
|
1506
|
+
const memoizedChildren = createOnce(() => localProps.children);
|
|
1507
|
+
const resolveChildren = () => {
|
|
1508
|
+
const children = memoizedChildren()();
|
|
1509
|
+
if (isFunction(children)) {
|
|
1510
|
+
return children(childrenProps);
|
|
1511
|
+
}
|
|
1512
|
+
return children;
|
|
1513
|
+
};
|
|
1514
|
+
const memoizedResizableRoot = createMemo(() => {
|
|
1515
|
+
const ResizableContext2 = createResizableContext(localProps.contextId);
|
|
1516
|
+
const InternalResizableContext2 = createInternalResizableContext(localProps.contextId);
|
|
1517
|
+
return createComponent(ResizableContext2, {
|
|
1518
|
+
value: {
|
|
1519
|
+
sizes,
|
|
1520
|
+
setSizes,
|
|
1521
|
+
orientation: () => localProps.orientation,
|
|
1522
|
+
keyboardDelta: () => localProps.keyboardDelta,
|
|
1523
|
+
handleCursorStyle: () => localProps.handleCursorStyle,
|
|
1524
|
+
resize: resize2,
|
|
1525
|
+
collapse,
|
|
1526
|
+
expand
|
|
1527
|
+
},
|
|
1528
|
+
get children() {
|
|
1529
|
+
return createComponent(InternalResizableContext2, {
|
|
1530
|
+
value: {
|
|
1531
|
+
sizes,
|
|
1532
|
+
setSizes,
|
|
1533
|
+
orientation: () => localProps.orientation,
|
|
1534
|
+
keyboardDelta: () => localProps.keyboardDelta,
|
|
1535
|
+
handleCursorStyle: () => localProps.handleCursorStyle,
|
|
1536
|
+
rootSize,
|
|
1537
|
+
panels,
|
|
1538
|
+
registerPanel,
|
|
1539
|
+
unregisterPanel,
|
|
1540
|
+
onDrag,
|
|
1541
|
+
onDragEnd: () => initialSizes = null,
|
|
1542
|
+
onKeyDown,
|
|
1543
|
+
resize: resize2,
|
|
1544
|
+
collapse,
|
|
1545
|
+
expand
|
|
1546
|
+
},
|
|
1547
|
+
get children() {
|
|
1548
|
+
return createComponent(Dynamic, mergeProps({
|
|
1549
|
+
as: "div",
|
|
1550
|
+
ref(r$) {
|
|
1551
|
+
var _ref$ = mergeRefs(setRef, localProps.ref);
|
|
1552
|
+
typeof _ref$ === "function" && _ref$(r$);
|
|
1553
|
+
},
|
|
1554
|
+
get style() {
|
|
1555
|
+
return combineStyle({
|
|
1556
|
+
display: "flex",
|
|
1557
|
+
"flex-direction": localProps.orientation === "horizontal" ? "row" : "column"
|
|
1558
|
+
}, localProps.style);
|
|
1559
|
+
},
|
|
1560
|
+
get ["data-orientation"]() {
|
|
1561
|
+
return localProps.orientation;
|
|
1562
|
+
},
|
|
1563
|
+
"data-corvu-resizable-root": ""
|
|
1564
|
+
}, otherProps, {
|
|
1565
|
+
get children() {
|
|
1566
|
+
return untrack(() => resolveChildren());
|
|
1567
|
+
}
|
|
1568
|
+
}));
|
|
1569
|
+
}
|
|
1570
|
+
});
|
|
1571
|
+
}
|
|
1572
|
+
});
|
|
1573
|
+
});
|
|
1574
|
+
return memoizedResizableRoot;
|
|
1575
|
+
};
|
|
1576
|
+
var Root_default = ResizableRoot;
|
|
1577
|
+
|
|
1578
|
+
// src/index.ts
|
|
1579
|
+
var Resizable = Object.assign(Root_default, {
|
|
1580
|
+
Panel: Panel_default,
|
|
1581
|
+
Handle: Handle_default,
|
|
1582
|
+
useContext: useResizableContext,
|
|
1583
|
+
usePanelContext: useResizablePanelContext
|
|
1584
|
+
});
|
|
1585
|
+
var index_default = Resizable;
|
|
1586
|
+
|
|
1587
|
+
export { Handle_default as Handle, Panel_default as Panel, Root_default as Root, index_default as default, useResizableContext as useContext, useResizablePanelContext as usePanelContext };
|