UNPKG

@zag-js/splitter

Version:

Core logic for the splitter widget implemented as a state machine

143 lines (141 loc) 5.22 kB
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 };