UNPKG

react-workspaces

Version:

A component with a resizable and splittable workspace. A panel with draggable tabs.

172 lines (145 loc) 4.43 kB
'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.MSG = exports.MAX_DEPTH = undefined; var _lodash = require('lodash'); var _lodash2 = _interopRequireDefault(_lodash); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } const MAX_DEPTH = exports.MAX_DEPTH = 3; const MSG = exports.MSG = { IMPOSSIBLE_SPLIT: 'CANNOT SPLIT AT THIS PATH WITH AXIS', MAX_DEPTH: `CANNOT SPLIT BEYOND ${MAX_DEPTH} LAYERS`, INVALID_PATH: 'PANE VIA PATH NOT FOUND' }; let Manager = class Manager { constructor() {} /** * Checks if current pane can be split in that axis * @return {Boolean} Returns true or false */ static validateSplit(state, path, axis, multiplier) { const depth = ''.split('.').length; let errors = []; if (depth > MAX_DEPTH) { errors.push(new Error(MSG.MAX_DEPTH)); } let root = _lodash2.default.cloneDeep(state); let pane; if (path === '') { pane = root; } else { pane = _lodash2.default.get(root, path); } if (!pane) { errors.push(new Error(MSG.NO_SUCH_PATH)); return errors; } // if clean slate if (!pane.children) { return errors; } if (pane.axis !== axis) { errors.push(new Error(MSG.IMPOSSIBLE_SPLIT)); } return errors; } /** * Creates a new state with the manipulation * @param {Object} state [description] * @param {String} path e.g. 'x[0].y[1]' * @param {String} axis 'x' or 'y' * @param {Number} muliplier How many times you want to split by * @return {Object} Returns a new state */ static split(state = {}, path, axis, multiplier = 2) { // needs to check if the current path can accept a split in the axis const errors = this.validateSplit(state, path, axis, multiplier); if (errors.length) { throw new Error(_lodash2.default.map(errors, _lodash2.default.identity)); } let root = _lodash2.default.cloneDeep(state); let currentPane; if (path === '') { currentPane = root; } else { currentPane = _lodash2.default.get(root, path); } const edited = this.splitPane(currentPane, axis, multiplier); return this.setPane(root, path, edited); } static setPane(root, path, pane) { if (path === '') { return pane; } else { return _lodash2.default.set(root, path, pane); } } /** * Split the panes at current position with axis */ static splitPane(pane, axis, multiplier) { const divider = _lodash2.default.round(100 / multiplier, 2); pane.axis = axis; // if pane doesn't have an existing setup if (!pane.children) { pane.children = []; for (var i = 0; i < multiplier; i++) { pane.children.push({ size: divider }); } } else { _lodash2.default.times(multiplier, index => { if (pane.children[index]) { pane.children[index].size = divider; } else { pane.children.push({ size: divider }); } }); } return pane; } static moveTab(tabs, from, fromIndex, to, toIndex) { // const tabs = { // 'children[0].children[0]': ['green', 'red'], // 'children[0].children[1]': 'blue', // 'children[1]': ['yellow', 'red'] // } if (!toIndex) { toIndex = tabs[to].length; } let newTabs = _lodash2.default.cloneDeep(tabs); const name = newTabs[from][fromIndex]; newTabs[from].splice(fromIndex, 1); newTabs[to].splice(toIndex, 0, name); return newTabs; } static buildTree(root, components, tabs) { function walk(node, path = '') { if (tabs[path]) { if (_lodash2.default.isArray(tabs[path])) { node.component = _lodash2.default.map(tabs[path], componentName => components[componentName]); } else { node.component = components[tabs[path]]; } } if (node.children) { node.children = _lodash2.default.map(node.children, (child, index) => { let childPath; if (path === '') { childPath = `children[${index}]`; } else { childPath = `${path}.children[${index}]`; } return walk(child, childPath); }); } return node; } return walk(_lodash2.default.cloneDeep(root)); } }; exports.default = Manager;