UNPKG

react-mosaic-component2

Version:
115 lines (114 loc) 3.3 kB
// src/util/mosaicUpdates.ts import update from "immutability-helper"; import { drop, dropRight, isEqual, last, set, take } from "lodash-es"; import { MosaicDropTargetPosition } from "../internalTypes.mjs"; import { getAndAssertNodeAtPathExists, getOtherBranch } from "./mosaicUtilities.mjs"; function buildSpecFromUpdate(mosaicUpdate) { if (mosaicUpdate.path.length > 0) { return set({}, mosaicUpdate.path, mosaicUpdate.spec); } else { return mosaicUpdate.spec; } } function updateTree(root, updates) { let currentNode = root; updates.forEach((mUpdate) => { currentNode = update(currentNode, buildSpecFromUpdate(mUpdate)); }); return currentNode; } function createRemoveUpdate(root, path) { const parentPath = dropRight(path); const nodeToRemove = last(path); const siblingPath = parentPath.concat(getOtherBranch(nodeToRemove)); const sibling = getAndAssertNodeAtPathExists(root, siblingPath); return { path: parentPath, spec: { $set: sibling } }; } function isPathPrefixEqual(a, b, length) { return isEqual(take(a, length), take(b, length)); } function createDragToUpdates(root, sourcePath, destinationPath, position) { let destinationNode = getAndAssertNodeAtPathExists(root, destinationPath); const updates = []; const destinationIsParentOfSource = isPathPrefixEqual(sourcePath, destinationPath, destinationPath.length); if (destinationIsParentOfSource) { destinationNode = updateTree(destinationNode, [ createRemoveUpdate(destinationNode, drop(sourcePath, destinationPath.length)) ]); } else { updates.push(createRemoveUpdate(root, sourcePath)); const removedNodeParentIsInPath = isPathPrefixEqual(sourcePath, destinationPath, sourcePath.length - 1); if (removedNodeParentIsInPath) { destinationPath.splice(sourcePath.length - 1, 1); } } const sourceNode = getAndAssertNodeAtPathExists(root, sourcePath); let first; let second; if (position === MosaicDropTargetPosition.LEFT || position === MosaicDropTargetPosition.TOP) { first = sourceNode; second = destinationNode; } else { first = destinationNode; second = sourceNode; } let direction = "column"; if (position === MosaicDropTargetPosition.LEFT || position === MosaicDropTargetPosition.RIGHT) { direction = "row"; } updates.push({ path: destinationPath, spec: { $set: { first, second, direction } } }); return updates; } function createHideUpdate(path) { const targetPath = dropRight(path); const thisBranch = last(path); let splitPercentage; if (thisBranch === "first") { splitPercentage = 0; } else { splitPercentage = 100; } return { path: targetPath, spec: { splitPercentage: { $set: splitPercentage } } }; } function createExpandUpdate(path, percentage) { let spec = {}; for (let i = path.length - 1; i >= 0; i--) { const branch = path[i]; const splitPercentage = branch === "first" ? percentage : 100 - percentage; spec = { splitPercentage: { $set: splitPercentage }, [branch]: spec }; } return { spec, path: [] }; } export { buildSpecFromUpdate, createDragToUpdates, createExpandUpdate, createHideUpdate, createRemoveUpdate, updateTree };