@zag-js/splitter
Version:
Core logic for the splitter widget implemented as a state machine
143 lines (141 loc) • 5.22 kB
JavaScript
import "../chunk-QZ7TP4HQ.mjs";
// src/utils/resize-by-delta.ts
import { ensure } from "@zag-js/utils";
import { fuzzyCompareNumbers, fuzzySizeEqual, fuzzyNumbersEqual } from "./fuzzy.mjs";
import { resizePanel } from "./resize-panel.mjs";
function resizeByDelta(props) {
let { delta, initialSize, panels, pivotIndices, prevSize, trigger } = props;
if (fuzzyNumbersEqual(delta, 0)) {
return initialSize;
}
const nextSize = [...initialSize];
const [firstPivotIndex, secondPivotIndex] = pivotIndices;
ensure(firstPivotIndex, () => "Invalid first pivot index");
ensure(secondPivotIndex, () => "Invalid second pivot index");
let deltaApplied = 0;
{
if (trigger === "keyboard") {
{
const index = delta < 0 ? secondPivotIndex : firstPivotIndex;
const panel = panels[index];
ensure(panel, () => `Panel data not found for index ${index}`);
const { collapsedSize = 0, collapsible, minSize = 0 } = panel;
if (collapsible) {
const prevSize2 = initialSize[index];
ensure(prevSize2, () => `Previous size not found for panel index ${index}`);
if (fuzzyNumbersEqual(prevSize2, collapsedSize)) {
const localDelta = minSize - prevSize2;
if (fuzzyCompareNumbers(localDelta, Math.abs(delta)) > 0) {
delta = delta < 0 ? 0 - localDelta : localDelta;
}
}
}
}
{
const index = delta < 0 ? firstPivotIndex : secondPivotIndex;
const panel = panels[index];
ensure(panel, () => `No panel data found for index ${index}`);
const { collapsedSize = 0, collapsible, minSize = 0 } = panel;
if (collapsible) {
const prevSize2 = initialSize[index];
ensure(prevSize2, () => `Previous size not found for panel index ${index}`);
if (fuzzyNumbersEqual(prevSize2, minSize)) {
const localDelta = prevSize2 - collapsedSize;
if (fuzzyCompareNumbers(localDelta, Math.abs(delta)) > 0) {
delta = delta < 0 ? 0 - localDelta : localDelta;
}
}
}
}
}
}
{
const increment = delta < 0 ? 1 : -1;
let index = delta < 0 ? secondPivotIndex : firstPivotIndex;
let maxAvailableDelta = 0;
while (true) {
const prevSize2 = initialSize[index];
ensure(prevSize2, () => `Previous size not found for panel index ${index}`);
const maxSafeSize = resizePanel({
panels,
index,
size: 100
});
const delta2 = maxSafeSize - prevSize2;
maxAvailableDelta += delta2;
index += increment;
if (index < 0 || index >= panels.length) {
break;
}
}
const minAbsDelta = Math.min(Math.abs(delta), Math.abs(maxAvailableDelta));
delta = delta < 0 ? 0 - minAbsDelta : minAbsDelta;
}
{
const pivotIndex = delta < 0 ? firstPivotIndex : secondPivotIndex;
let index = pivotIndex;
while (index >= 0 && index < panels.length) {
const deltaRemaining = Math.abs(delta) - Math.abs(deltaApplied);
const prevSize2 = initialSize[index];
ensure(prevSize2, () => `Previous size not found for panel index ${index}`);
const unsafeSize = prevSize2 - deltaRemaining;
const safeSize = resizePanel({ panels, index, size: unsafeSize });
if (!fuzzyNumbersEqual(prevSize2, safeSize)) {
deltaApplied += prevSize2 - safeSize;
nextSize[index] = safeSize;
if (deltaApplied.toPrecision(3).localeCompare(Math.abs(delta).toPrecision(3), void 0, {
numeric: true
}) >= 0) {
break;
}
}
if (delta < 0) {
index--;
} else {
index++;
}
}
}
if (fuzzySizeEqual(prevSize, nextSize)) {
return prevSize;
}
{
const pivotIndex = delta < 0 ? secondPivotIndex : firstPivotIndex;
const prevSize2 = initialSize[pivotIndex];
ensure(prevSize2, () => `Previous size not found for panel index ${pivotIndex}`);
const unsafeSize = prevSize2 + deltaApplied;
const safeSize = resizePanel({ panels, index: pivotIndex, size: unsafeSize });
nextSize[pivotIndex] = safeSize;
if (!fuzzyNumbersEqual(safeSize, unsafeSize)) {
let deltaRemaining = unsafeSize - safeSize;
const pivotIndex2 = delta < 0 ? secondPivotIndex : firstPivotIndex;
let index = pivotIndex2;
while (index >= 0 && index < panels.length) {
const prevSize3 = nextSize[index];
ensure(prevSize3, () => `Previous size not found for panel index ${index}`);
const unsafeSize2 = prevSize3 + deltaRemaining;
const safeSize2 = resizePanel({ panels, index, size: unsafeSize2 });
if (!fuzzyNumbersEqual(prevSize3, safeSize2)) {
deltaRemaining -= safeSize2 - prevSize3;
nextSize[index] = safeSize2;
}
if (fuzzyNumbersEqual(deltaRemaining, 0)) {
break;
}
if (delta > 0) {
index--;
} else {
index++;
}
}
}
}
const totalSize = nextSize.reduce((total, size) => size + total, 0);
if (!fuzzyNumbersEqual(totalSize, 100)) {
return prevSize;
}
return nextSize;
}
export {
resizeByDelta
};