@devbookhq/splitter
Advanced tools
Comparing version 1.0.1 to 1.0.2
import React from 'react'; | ||
import './index.css'; | ||
export declare enum SplitDirection { | ||
@@ -3,0 +4,0 @@ Horizontal = "Horizontal", |
468
lib/index.js
@@ -1,468 +0,2 @@ | ||
Object.defineProperty(exports, '__esModule', { value: true }); | ||
var jsxRuntime = require('react/jsx-runtime'); | ||
var React = require('react'); | ||
var styled = require('styled-components'); | ||
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; } | ||
var React__default = /*#__PURE__*/_interopDefaultLegacy(React); | ||
var styled__default = /*#__PURE__*/_interopDefaultLegacy(styled); | ||
/*! ***************************************************************************** | ||
Copyright (c) Microsoft Corporation. | ||
Permission to use, copy, modify, and/or distribute this software for any | ||
purpose with or without fee is hereby granted. | ||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH | ||
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY | ||
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, | ||
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM | ||
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR | ||
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR | ||
PERFORMANCE OF THIS SOFTWARE. | ||
***************************************************************************** */ | ||
var __assign = function() { | ||
__assign = Object.assign || function __assign(t) { | ||
for (var s, i = 1, n = arguments.length; i < n; i++) { | ||
s = arguments[i]; | ||
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; | ||
} | ||
return t; | ||
}; | ||
return __assign.apply(this, arguments); | ||
}; | ||
/** @deprecated */ | ||
function __spreadArrays() { | ||
for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length; | ||
for (var r = Array(s), k = 0, i = 0; i < il; i++) | ||
for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++) | ||
r[k] = a[j]; | ||
return r; | ||
} | ||
function __makeTemplateObject(cooked, raw) { | ||
if (Object.defineProperty) { Object.defineProperty(cooked, "raw", { value: raw }); } else { cooked.raw = raw; } | ||
return cooked; | ||
} | ||
function getInnerSize(direction, element) { | ||
// Returns undefined if parent element has no layout yet. | ||
// Or if the parent has no size. | ||
var computedStyle = getComputedStyle(element); | ||
if (!computedStyle) | ||
return; | ||
var size = direction === exports.SplitDirection.Horizontal ? element.clientWidth : element.clientHeight; | ||
if (size === 0) | ||
return; | ||
if (direction === exports.SplitDirection.Horizontal) { | ||
size -= parseFloat(computedStyle.paddingLeft) + parseFloat(computedStyle.paddingRight); | ||
} | ||
else { | ||
size -= parseFloat(computedStyle.paddingTop) + parseFloat(computedStyle.paddingBottom); | ||
} | ||
return size; | ||
} | ||
function useEventListener(event, handler, deps) { | ||
if (deps === void 0) { deps = []; } | ||
React.useEffect(function () { | ||
window.addEventListener(event, handler); | ||
return function () { return window.removeEventListener(event, handler); }; | ||
// eslint-disable-next-line react-hooks/exhaustive-deps | ||
}, __spreadArrays([event, handler], deps)); | ||
} | ||
var Container = styled__default['default'].div(templateObject_1 || (templateObject_1 = __makeTemplateObject(["\n padding: ", ";\n ", ";\n\n display: flex;\n align-items: center;\n justify-content: center;\n flex-direction: ", ";\n\n background: #020203;\n\n :hover {\n cursor: ", ";\n\n // Set the Dragger background.\n & > * {\n background: #9995A3;\n }\n }\n"], ["\n padding: ", ";\n ", ";\n\n display: flex;\n align-items: center;\n justify-content: center;\n flex-direction: ", ";\n\n background: #020203;\n\n :hover {\n cursor: ", ";\n\n // Set the Dragger background.\n & > * {\n background: #9995A3;\n }\n }\n"])), function (props) { return props.dir === exports.SplitDirection.Horizontal ? '0 2px' : '2px 0'; }, function (props) { return props.dir === exports.SplitDirection.Horizontal ? 'height: 100%' : 'width: 100%'; }, function (props) { return props.dir === exports.SplitDirection.Horizontal ? 'column' : 'row'; }, function (props) { return props.dir === exports.SplitDirection.Horizontal ? 'col-resize' : 'row-resize'; }); | ||
var Dragger = styled__default['default'].div(templateObject_2 || (templateObject_2 = __makeTemplateObject(["\n width: ", "px;\n height: ", "px;\n background: #434252;\n border-radius: 2px;\n"], ["\n width: ", "px;\n height: ", "px;\n background: #434252;\n border-radius: 2px;\n"])), function (props) { return props.dir === exports.SplitDirection.Horizontal ? '4' : '24'; }, function (props) { return props.dir === exports.SplitDirection.Horizontal ? '24' : '4'; }); | ||
var Gutter = React__default['default'].forwardRef(function (_a, ref) { | ||
var className = _a.className, draggerClassName = _a.draggerClassName, direction = _a.direction, onMouseDown = _a.onMouseDown; | ||
return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [className && | ||
jsxRuntime.jsxs("div", __assign({ className: className, ref: ref, dir: direction, onMouseDown: onMouseDown }, { children: [draggerClassName && | ||
jsxRuntime.jsx("div", { className: draggerClassName, dir: direction }, void 0), | ||
!draggerClassName && | ||
jsxRuntime.jsx(Dragger, { dir: direction }, void 0)] }), void 0), | ||
!className && | ||
jsxRuntime.jsxs(Container, __assign({ ref: ref, className: className, dir: direction, onMouseDown: onMouseDown }, { children: [draggerClassName && | ||
jsxRuntime.jsx("div", { className: draggerClassName, dir: direction }, void 0), | ||
!draggerClassName && | ||
jsxRuntime.jsx(Dragger, { dir: direction }, void 0)] }), void 0)] }, void 0)); | ||
}); | ||
var templateObject_1, templateObject_2; | ||
var ActionType; | ||
(function (ActionType) { | ||
ActionType[ActionType["CreatePairs"] = 0] = "CreatePairs"; | ||
ActionType[ActionType["CalculateSizes"] = 1] = "CalculateSizes"; | ||
ActionType[ActionType["StartDragging"] = 2] = "StartDragging"; | ||
ActionType[ActionType["StopDragging"] = 3] = "StopDragging"; | ||
})(ActionType || (ActionType = {})); | ||
function getGutterSizes(gutterSize, isFirst, isLast) { | ||
var aGutterSize; | ||
var bGutterSize; | ||
if (isFirst) { | ||
aGutterSize = gutterSize / 2; | ||
bGutterSize = gutterSize; | ||
} | ||
else if (isLast) { | ||
aGutterSize = gutterSize; | ||
bGutterSize = gutterSize / 2; | ||
} | ||
else { | ||
aGutterSize = gutterSize; | ||
bGutterSize = gutterSize; | ||
} | ||
return { aGutterSize: aGutterSize, bGutterSize: bGutterSize }; | ||
} | ||
function reducer(state, action) { | ||
switch (action.type) { | ||
// ----------------------------------------------------------------------- | ||
// | i=0 | i=1 | i=2 | i=3 | | ||
// | | | | | | ||
// | pair 0 pair 1 pair 2 | | ||
// | | | | | | ||
// ----------------------------------------------------------------------- | ||
case ActionType.CreatePairs: { | ||
var _a = action.payload, direction_1 = _a.direction, children_1 = _a.children, gutters_1 = _a.gutters; | ||
// All children must have common parent. | ||
var parent_1 = children_1[0].parentNode; | ||
if (!parent_1) | ||
throw new Error("Cannot create pairs - parent is undefined."); | ||
var parentSize = getInnerSize(direction_1, parent_1); | ||
if (parentSize === undefined) | ||
throw new Error("Cannot create pairs - parent has undefined or zero size: " + parentSize + "."); | ||
var pairs_1 = []; | ||
children_1.forEach(function (_, idx) { | ||
if (idx > 0) { | ||
var a = children_1[idx - 1]; | ||
var b = children_1[idx]; | ||
var gutter = gutters_1[idx - 1]; | ||
var start = direction_1 === exports.SplitDirection.Horizontal | ||
? a.getBoundingClientRect().left | ||
: a.getBoundingClientRect().top; | ||
var end = direction_1 === exports.SplitDirection.Horizontal | ||
? b.getBoundingClientRect().right | ||
: b.getBoundingClientRect().bottom; | ||
var size = direction_1 === exports.SplitDirection.Horizontal | ||
? a.getBoundingClientRect().width + gutter.getBoundingClientRect().width + b.getBoundingClientRect().width | ||
: a.getBoundingClientRect().height + gutter.getBoundingClientRect().height + b.getBoundingClientRect().height; | ||
var gutterSize = direction_1 === exports.SplitDirection.Horizontal | ||
? gutter.getBoundingClientRect().width | ||
: gutter.getBoundingClientRect().height; | ||
var pair = { | ||
idx: idx - 1, | ||
// TODO: Do we need to have a reference to the whole elements? Aren't indexes enough? | ||
a: a, | ||
b: b, | ||
gutter: gutter, | ||
parent: parent_1, | ||
start: start, | ||
end: end, | ||
size: size, | ||
gutterSize: gutterSize, | ||
// At the start, all elements has the same width. | ||
aSizePct: 100 / children_1.length, | ||
bSizePct: 100 / children_1.length, | ||
}; | ||
pairs_1.push(pair); | ||
} | ||
}); | ||
return __assign(__assign({}, state), { pairs: pairs_1 }); | ||
} | ||
case ActionType.StartDragging: { | ||
var gutterIdx = action.payload.gutterIdx; | ||
return __assign(__assign({}, state), { isDragging: true, draggingIdx: gutterIdx }); | ||
} | ||
case ActionType.StopDragging: { | ||
return __assign(__assign({}, state), { isDragging: false }); | ||
} | ||
case ActionType.CalculateSizes: { | ||
// We need to calculate sizes only for the pair | ||
// that has the moved gutter. | ||
var _b = action.payload, direction = _b.direction, gutterIdx = _b.gutterIdx; | ||
var pair = state.pairs[gutterIdx]; | ||
var parentSize = getInnerSize(direction, pair.parent); | ||
if (!parentSize) | ||
throw new Error("Cannot calculate sizes - 'pair.parent' has undefined or zero size."); | ||
var gutterSize = pair.gutter[direction === exports.SplitDirection.Horizontal ? 'clientWidth' : 'clientHeight']; | ||
var isFirst = gutterIdx === 0; | ||
var isLast = gutterIdx === state.pairs.length - 1; | ||
var _c = getGutterSizes(gutterSize, isFirst, isLast), aGutterSize = _c.aGutterSize, bGutterSize = _c.bGutterSize; | ||
var start = void 0; | ||
var end = void 0; | ||
var size = void 0; | ||
var aSizePct = void 0; | ||
var bSizePct = void 0; | ||
if (direction === exports.SplitDirection.Horizontal) { | ||
start = pair.a.getBoundingClientRect().left; | ||
end = pair.b.getBoundingClientRect().right; | ||
aSizePct = ((pair.a.getBoundingClientRect().width + aGutterSize) / parentSize) * 100; | ||
bSizePct = ((pair.b.getBoundingClientRect().width + bGutterSize) / parentSize) * 100; | ||
size = | ||
pair.a.getBoundingClientRect().width + | ||
aGutterSize + | ||
bGutterSize + | ||
pair.b.getBoundingClientRect().width; | ||
} | ||
else { | ||
start = pair.a.getBoundingClientRect().top; | ||
end = pair.b.getBoundingClientRect().bottom; | ||
aSizePct = ((pair.a.getBoundingClientRect().height + aGutterSize) / parentSize) * 100; | ||
bSizePct = ((pair.b.getBoundingClientRect().height + bGutterSize) / parentSize) * 100; | ||
size = | ||
pair.a.getBoundingClientRect().height + | ||
aGutterSize + | ||
bGutterSize + | ||
pair.b.getBoundingClientRect().height; | ||
} | ||
state.pairs[gutterIdx] = __assign(__assign({}, pair), { start: start, | ||
end: end, | ||
size: size, | ||
aSizePct: aSizePct, | ||
bSizePct: bSizePct, | ||
gutterSize: gutterSize }); | ||
return __assign({}, state); | ||
} | ||
default: | ||
return state; | ||
} | ||
} | ||
exports.SplitDirection = void 0; | ||
(function (SplitDirection) { | ||
SplitDirection["Horizontal"] = "Horizontal"; | ||
SplitDirection["Vertical"] = "Vertical"; | ||
})(exports.SplitDirection || (exports.SplitDirection = {})); | ||
var DefaultMinSize = 16; | ||
var Container$1 = styled__default['default'].div(templateObject_1$1 || (templateObject_1$1 = __makeTemplateObject(["\n height: 100%;\n width: 100%;\n\n display: flex;\n flex-direction: ", ";\n overflow: hidden;\n"], ["\n height: 100%;\n width: 100%;\n\n display: flex;\n flex-direction: ", ";\n overflow: hidden;\n"])), function (props) { return props.dir === exports.SplitDirection.Horizontal ? 'row' : 'column'; }); | ||
var ChildWrapper = styled__default['default'].div(templateObject_2$1 || (templateObject_2$1 = __makeTemplateObject(["\n height: 100%;\n width: 100%;\n"], ["\n height: 100%;\n width: 100%;\n"]))); | ||
function getMousePosition(dir, e) { | ||
if (dir === exports.SplitDirection.Horizontal) | ||
return e.clientX; | ||
return e.clientY; | ||
} | ||
function getCursorIcon(dir) { | ||
if (dir === exports.SplitDirection.Horizontal) | ||
return 'col-resize'; | ||
return 'row-resize'; | ||
} | ||
/* | ||
const stateInit: State = (direction: SplitDirection = SplitDirection.Horizontal) => ({ | ||
direction, | ||
isDragging: false, | ||
pairs: [], | ||
}); | ||
*/ | ||
var initialState = { | ||
isDragging: false, | ||
pairs: [], | ||
}; | ||
function Split(_a) { | ||
var direction = _a.direction, minWidth = _a.minWidth, minHeight = _a.minHeight, initialSizes = _a.initialSizes, gutterClassName = _a.gutterClassName, draggerClassName = _a.draggerClassName, children = _a.children; | ||
var _b = React.useReducer(reducer, initialState), state = _b[0], dispatch = _b[1]; | ||
var childRefs = React.useRef([]); | ||
var gutterRefs = React.useRef([]); | ||
// We want to reset refs on each re-render so they don't contain old references. | ||
childRefs.current = []; | ||
gutterRefs.current = []; | ||
// Helper dispatch functions. | ||
var startDragging = React__default['default'].useCallback(function (direction, gutterIdx) { | ||
dispatch({ | ||
type: ActionType.StartDragging, | ||
payload: { gutterIdx: gutterIdx }, | ||
}); | ||
var pair = state.pairs[gutterIdx]; | ||
// Disable selection. | ||
pair.a.style.userSelect = 'none'; | ||
pair.b.style.userSelect = 'none'; | ||
// Set the mouse cursor. | ||
// Must be done at multiple levels, nut just for a gutter. | ||
// The mouse cursor might move outside of the gutter element. | ||
pair.gutter.style.cursor = getCursorIcon(direction); | ||
pair.parent.style.cursor = getCursorIcon(direction); | ||
document.body.style.cursor = getCursorIcon(direction); | ||
}, [state.pairs]); | ||
var stopDragging = React__default['default'].useCallback(function () { | ||
dispatch({ | ||
type: ActionType.StopDragging, | ||
}); | ||
if (state.draggingIdx === undefined) | ||
throw new Error("Could not reset cursor and user-select because 'state.draggingIdx' is undefined."); | ||
var pair = state.pairs[state.draggingIdx]; | ||
// Disable selection. | ||
pair.a.style.userSelect = ''; | ||
pair.b.style.userSelect = ''; | ||
// Set the mouse cursor. | ||
// Must be done at multiple levels, not just for a gutter. | ||
// The mouse cursor might move outside of the gutter element. | ||
pair.gutter.style.cursor = ''; | ||
pair.parent.style.cursor = ''; | ||
document.body.style.cursor = ''; | ||
}, [state.draggingIdx, state.pairs]); | ||
var calculateSizes = React__default['default'].useCallback(function (direction, gutterIdx) { | ||
dispatch({ | ||
type: ActionType.CalculateSizes, | ||
payload: { direction: direction, gutterIdx: gutterIdx }, | ||
}); | ||
}, []); | ||
var createPairs = React__default['default'].useCallback(function (direction, children, gutters) { | ||
dispatch({ | ||
type: ActionType.CreatePairs, | ||
payload: { direction: direction, children: children, gutters: gutters }, | ||
}); | ||
}, []); | ||
///////// | ||
// This method is called on the initial render. | ||
// It iterates through the all children and make them equal wide. | ||
var setInitialSizes = React__default['default'].useCallback(function (direction, children, gutters, initialSizes) { | ||
// All children must have common parent. | ||
var parent = children[0].parentNode; | ||
if (!parent) | ||
throw new Error("Cannot set initial sizes - parent is undefined."); | ||
var parentSize = getInnerSize(direction, parent); | ||
if (parentSize === undefined) | ||
throw new Error("Cannot set initial sizes - parent has undefined or zero size: " + parentSize + "."); | ||
children.forEach(function (c, idx) { | ||
var isFirst = idx === 0; | ||
var isLast = idx === children.length - 1; | ||
var gutter = gutters[isLast ? idx - 1 : idx]; | ||
var gutterSize = gutter.getBoundingClientRect()[direction === exports.SplitDirection.Horizontal ? 'width' : 'height']; | ||
gutterSize = isFirst || isLast ? gutterSize / 2 : gutterSize; | ||
var calc; | ||
if (initialSizes && idx < initialSizes.length) { | ||
calc = "calc(" + initialSizes[idx] + "% - " + gutterSize + "px)"; | ||
} | ||
else { | ||
// '100 / children.length' makes all the children same wide. | ||
calc = "calc(" + 100 / children.length + "% - " + gutterSize + "px)"; | ||
} | ||
if (direction === exports.SplitDirection.Horizontal) { | ||
c.style.width = calc; | ||
// Reset the child wrapper's height because the direction could have changed. | ||
c.style.height = '100%'; | ||
} | ||
else { | ||
c.style.height = calc; | ||
// Reset the child wrapper's width because the direction could have changed. | ||
c.style.width = '100%'; | ||
} | ||
}); | ||
}, []); | ||
// Here we actually change the width of children. | ||
// We convert the element's sizes into percentage | ||
// and let the CSS 'calc' function do the heavy lifting. | ||
// Size of 'a' is same as 'offset'. | ||
// | ||
// For just 2 children total, the percentage adds up always to 100. | ||
// For >2 children total, the percentage adds to less than 100. | ||
// That's because a single gutter changes sizes of only the given pair of children. | ||
// Each gutter changes size only of the two adjacent elements. | ||
// ----------------------------------------------------------------------- | ||
// | ||| ||| | | ||
// | 33.3% ||| 33.3% ||| 33.3% | | ||
// | ||| ||| | | ||
// | ||| ||| | | ||
// ----------------------------------------------------------------------- | ||
var adjustSize = React__default['default'].useCallback(function (direction, offset) { | ||
if (state.draggingIdx === undefined) | ||
throw new Error("Cannot adjust size - 'draggingIdx' is undefined."); | ||
var pair = state.pairs[state.draggingIdx]; | ||
if (pair.size === undefined) | ||
throw new Error("Cannot adjust size - 'pair.size' is undefined."); | ||
if (pair.gutterSize === undefined) | ||
throw new Error("Cannot adjust size - 'pair.gutterSize' is undefined."); | ||
var percentage = pair.aSizePct + pair.bSizePct; | ||
var aSizePct = (offset / pair.size) * percentage; | ||
var bSizePct = percentage - (offset / pair.size) * percentage; | ||
var isFirst = state.draggingIdx === 0; | ||
var isLast = state.draggingIdx === state.pairs.length - 1; | ||
var _a = getGutterSizes(pair.gutterSize, isFirst, isLast), aGutterSize = _a.aGutterSize, bGutterSize = _a.bGutterSize; | ||
var aCalc = "calc(" + aSizePct + "% - " + aGutterSize + "px)"; | ||
var bCalc = "calc(" + bSizePct + "% - " + bGutterSize + "px)"; | ||
if (direction === exports.SplitDirection.Horizontal) { | ||
pair.a.style.width = aCalc; | ||
pair.b.style.width = bCalc; | ||
} | ||
else { | ||
pair.a.style.height = aCalc; | ||
pair.b.style.height = bCalc; | ||
} | ||
}, [state.draggingIdx, state.pairs, direction]); | ||
var drag = React__default['default'].useCallback(function (e, direction, minSize) { | ||
if (!state.isDragging) | ||
return; | ||
if (state.draggingIdx === undefined) | ||
throw new Error("Cannot drag - 'draggingIdx' is undefined."); | ||
var pair = state.pairs[state.draggingIdx]; | ||
if (pair.start === undefined) | ||
throw new Error("Cannot drag - 'pair.start' is undefined."); | ||
if (pair.size === undefined) | ||
throw new Error("Cannot drag - 'pair.size' is undefined."); | ||
if (pair.gutterSize === undefined) | ||
throw new Error("Cannot drag - 'pair.gutterSize' is undefined."); | ||
// 'offset' is the width of the 'a' element in a pair. | ||
var offset = getMousePosition(direction, e) - pair.start; | ||
// Limit the maximum and minimum size of resized children. | ||
var visibleSize = minSize === undefined ? DefaultMinSize : minSize; | ||
if (offset < pair.gutterSize + visibleSize) { | ||
offset = pair.gutterSize + visibleSize; | ||
} | ||
if (offset >= pair.size - (pair.gutterSize + visibleSize)) { | ||
offset = pair.size - (pair.gutterSize + visibleSize); | ||
} | ||
adjustSize(direction, offset); | ||
}, [state.isDragging, state.draggingIdx, state.pairs, adjustSize]); | ||
function handleGutterMouseDown(gutterIdx, e) { | ||
e.preventDefault(); | ||
calculateSizes(direction, gutterIdx); | ||
startDragging(direction, gutterIdx); | ||
} | ||
useEventListener('mouseup', function () { | ||
if (!state.isDragging) | ||
return; | ||
stopDragging(); | ||
}, [state.isDragging, stopDragging]); | ||
useEventListener('mousemove', function (e) { | ||
if (!state.isDragging) | ||
return; | ||
drag(e, direction, direction === exports.SplitDirection.Horizontal ? minWidth : minHeight); | ||
}, [direction, state.isDragging, drag, minWidth, minHeight]); | ||
// Initial setup, runs every time the child views changes. | ||
React.useEffect(function () { | ||
if (children === undefined) | ||
throw new Error("Cannot initialize split - 'children' are undefined"); | ||
if (!Array.isArray(children)) | ||
throw new Error("Cannot initialize split - 'children' isn't an array."); | ||
if (children.length <= 1) | ||
throw new Error("Cannot initialize split - the 'children' array has 1 or less elements. Provide at least 2 child views for the split."); | ||
// By the time first useEffect runs refs should be already set, unless something really bad happened. | ||
if (!childRefs.current || !gutterRefs.current) | ||
throw new Error("Cannot create pairs - 'childRefs' or 'gutterRefs' is undefined."); | ||
setInitialSizes(direction, childRefs.current, gutterRefs.current, initialSizes); | ||
createPairs(direction, childRefs.current, gutterRefs.current); | ||
// The reason 'children' is in the dependency array is that we have to recalculate | ||
// the state every time a child view is deleted or added - this is every time the child | ||
// views change -> hence the deps array. | ||
// The same goes for 'direction'. We need to recalculate the state if the split's direction | ||
// changes. | ||
}, [children, direction, setInitialSizes, createPairs, initialSizes]); | ||
function addRef(refs, el) { | ||
if (!refs.current) | ||
throw new Error("Can't add element to ref object - ref isn't initialized"); | ||
if (el && !refs.current.includes(el)) { | ||
refs.current.push(el); | ||
} | ||
} | ||
return (jsxRuntime.jsx(Container$1, __assign({ dir: direction }, { children: children && Array.isArray(children) && children.map(function (c, idx) { return (jsxRuntime.jsxs(React__default['default'].Fragment, { children: [jsxRuntime.jsx(ChildWrapper, __assign({ ref: function (el) { return addRef(childRefs, el); } }, { children: c }), void 0), | ||
idx < children.length - 1 && | ||
jsxRuntime.jsx(Gutter, { ref: function (el) { return addRef(gutterRefs, el); }, className: gutterClassName, draggerClassName: draggerClassName, direction: direction, onMouseDown: function (e) { return handleGutterMouseDown(idx, e); } }, void 0)] }, idx)); }) }), void 0)); | ||
} | ||
var templateObject_1$1, templateObject_2$1; | ||
exports.default = Split; | ||
Object.defineProperty(exports,"__esModule",{value:!0});var e=require("react/jsx-runtime"),t=require("react"),i=require("styled-components");function n(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var r=n(t),o=n(i),a=function(){return(a=Object.assign||function(e){for(var t,i=1,n=arguments.length;i<n;i++)for(var r in t=arguments[i])Object.prototype.hasOwnProperty.call(t,r)&&(e[r]=t[r]);return e}).apply(this,arguments)};function d(e,t){return Object.defineProperty?Object.defineProperty(e,"raw",{value:t}):e.raw=t,e}function s(e,t){var i=getComputedStyle(t);if(i){var n=e===exports.SplitDirection.Horizontal?t.clientWidth:t.clientHeight;if(0!==n)return e===exports.SplitDirection.Horizontal?n-=parseFloat(i.paddingLeft)+parseFloat(i.paddingRight):n-=parseFloat(i.paddingTop)+parseFloat(i.paddingBottom),n}}function l(e,i,n){void 0===n&&(n=[]),t.useEffect((function(){return window.addEventListener(e,i),function(){return window.removeEventListener(e,i)}}),function(){for(var e=0,t=0,i=arguments.length;t<i;t++)e+=arguments[t].length;var n=Array(e),r=0;for(t=0;t<i;t++)for(var o=arguments[t],a=0,d=o.length;a<d;a++,r++)n[r]=o[a];return n}([e,i],n))}var g,u,c,p,f=o.default.div(g||(g=d(["\n padding: ",";\n ",";\n\n display: flex;\n align-items: center;\n justify-content: center;\n flex-direction: ",";\n\n background: #020203;\n\n :hover {\n cursor: ",";\n\n // Set the Dragger background.\n & > * {\n background: #9995A3;\n }\n }\n"],["\n padding: ",";\n ",";\n\n display: flex;\n align-items: center;\n justify-content: center;\n flex-direction: ",";\n\n background: #020203;\n\n :hover {\n cursor: ",";\n\n // Set the Dragger background.\n & > * {\n background: #9995A3;\n }\n }\n"])),(function(e){return e.dir===exports.SplitDirection.Horizontal?"0 2px":"2px 0"}),(function(e){return e.dir===exports.SplitDirection.Horizontal?"height: 100%":"width: 100%"}),(function(e){return e.dir===exports.SplitDirection.Horizontal?"column":"row"}),(function(e){return e.dir===exports.SplitDirection.Horizontal?"col-resize":"row-resize"})),h=o.default.div(u||(u=d(["\n width: ","px;\n height: ","px;\n background: #434252;\n border-radius: 2px;\n"],["\n width: ","px;\n height: ","px;\n background: #434252;\n border-radius: 2px;\n"])),(function(e){return e.dir===exports.SplitDirection.Horizontal?"4":"24"}),(function(e){return e.dir===exports.SplitDirection.Horizontal?"24":"4"})),v=r.default.forwardRef((function(t,i){var n=t.className,r=t.draggerClassName,o=t.direction,d=t.onMouseDown;return e.jsxs(e.Fragment,{children:[n&&e.jsxs("div",a({className:n,ref:i,dir:o,onMouseDown:d},{children:[r&&e.jsx("div",{className:r,dir:o},void 0),!r&&e.jsx(h,{dir:o},void 0)]}),void 0),!n&&e.jsxs(f,a({ref:i,className:n,dir:o,onMouseDown:d},{children:[r&&e.jsx("div",{className:r,dir:o},void 0),!r&&e.jsx(h,{dir:o},void 0)]}),void 0)]},void 0)}));function z(e,t,i){var n,r;return t?(n=e/2,r=e):i?(n=e,r=e/2):(n=e,r=e),{aGutterSize:n,bGutterSize:r}}function x(e,t){switch(t.type){case c.CreatePairs:var i=t.payload,n=i.direction,r=i.children,o=i.gutters,d=r[0].parentNode;if(!d)throw new Error("Cannot create pairs - parent is undefined.");if(void 0===(u=s(n,d)))throw new Error("Cannot create pairs - parent has undefined or zero size: "+u+".");var l=[];return r.forEach((function(e,t){if(t>0){var i=r[t-1],a=r[t],s=o[t-1],g=n===exports.SplitDirection.Horizontal?i.getBoundingClientRect().left:i.getBoundingClientRect().top,u=n===exports.SplitDirection.Horizontal?a.getBoundingClientRect().right:a.getBoundingClientRect().bottom,c=n===exports.SplitDirection.Horizontal?i.getBoundingClientRect().width+s.getBoundingClientRect().width+a.getBoundingClientRect().width:i.getBoundingClientRect().height+s.getBoundingClientRect().height+a.getBoundingClientRect().height,p=n===exports.SplitDirection.Horizontal?s.getBoundingClientRect().width:s.getBoundingClientRect().height,f={idx:t-1,a:i,b:a,gutter:s,parent:d,start:g,end:u,size:c,gutterSize:p,aSizePct:100/r.length,bSizePct:100/r.length};l.push(f)}})),a(a({},e),{pairs:l});case c.StartDragging:var g=t.payload.gutterIdx;return a(a({},e),{isDragging:!0,draggingIdx:g});case c.StopDragging:return a(a({},e),{isDragging:!1});case c.CalculateSizes:var u,p=t.payload,f=p.direction,h=(g=p.gutterIdx,e.pairs[g]);if(!(u=s(f,h.parent)))throw new Error("Cannot calculate sizes - 'pair.parent' has undefined or zero size.");var v=h.gutter[f===exports.SplitDirection.Horizontal?"clientWidth":"clientHeight"],x=z(v,0===g,g===e.pairs.length-1),w=x.aGutterSize,S=x.bGutterSize,C=void 0,y=void 0,D=void 0,b=void 0,m=void 0;return f===exports.SplitDirection.Horizontal?(C=h.a.getBoundingClientRect().left,y=h.b.getBoundingClientRect().right,b=(h.a.getBoundingClientRect().width+w)/u*100,m=(h.b.getBoundingClientRect().width+S)/u*100,D=h.a.getBoundingClientRect().width+w+S+h.b.getBoundingClientRect().width):(C=h.a.getBoundingClientRect().top,y=h.b.getBoundingClientRect().bottom,b=(h.a.getBoundingClientRect().height+w)/u*100,m=(h.b.getBoundingClientRect().height+S)/u*100,D=h.a.getBoundingClientRect().height+w+S+h.b.getBoundingClientRect().height),e.pairs[g]=a(a({},h),{start:C,end:y,size:D,aSizePct:b,bSizePct:m,gutterSize:v}),a({},e);default:return e}}!function(e){e[e.CreatePairs=0]="CreatePairs",e[e.CalculateSizes=1]="CalculateSizes",e[e.StartDragging=2]="StartDragging",e[e.StopDragging=3]="StopDragging"}(c||(c={})),exports.SplitDirection=void 0,(p=exports.SplitDirection||(exports.SplitDirection={})).Horizontal="Horizontal",p.Vertical="Vertical";var w=o.default.div(y||(y=d(["\n height: 100%;\n width: 100%;\n\n display: flex;\n flex-direction: ",";\n overflow: hidden;\n"],["\n height: 100%;\n width: 100%;\n\n display: flex;\n flex-direction: ",";\n overflow: hidden;\n"])),(function(e){return e.dir===exports.SplitDirection.Horizontal?"row":"column"})),S=o.default.div(D||(D=d(["\n height: 100%;\n width: 100%;\n"],["\n height: 100%;\n width: 100%;\n"])));function C(e){return e===exports.SplitDirection.Horizontal?"col-resize":"row-resize"}var y,D,b={isDragging:!1,pairs:[]};exports.default=function(i){var n=i.direction,o=i.minWidth,d=i.minHeight,g=i.initialSizes,u=i.gutterClassName,p=i.draggerClassName,f=i.children,h=t.useReducer(x,b),y=h[0],D=h[1],m=t.useRef([]),R=t.useRef([]);m.current=[],R.current=[];var B=r.default.useCallback((function(e,t){D({type:c.StartDragging,payload:{gutterIdx:t}});var i=y.pairs[t];i.a.style.userSelect="none",i.b.style.userSelect="none",i.gutter.style.cursor=C(e),i.parent.style.cursor=C(e),document.body.style.cursor=C(e)}),[y.pairs]),H=r.default.useCallback((function(){if(D({type:c.StopDragging}),void 0===y.draggingIdx)throw new Error("Could not reset cursor and user-select because 'state.draggingIdx' is undefined.");var e=y.pairs[y.draggingIdx];e.a.style.userSelect="",e.b.style.userSelect="",e.gutter.style.cursor="",e.parent.style.cursor="",document.body.style.cursor=""}),[y.draggingIdx,y.pairs]),j=r.default.useCallback((function(e,t){D({type:c.CalculateSizes,payload:{direction:e,gutterIdx:t}})}),[]),E=r.default.useCallback((function(e,t,i){D({type:c.CreatePairs,payload:{direction:e,children:t,gutters:i}})}),[]),I=r.default.useCallback((function(e,t,i,n){var r=t[0].parentNode;if(!r)throw new Error("Cannot set initial sizes - parent is undefined.");var o=s(e,r);if(void 0===o)throw new Error("Cannot set initial sizes - parent has undefined or zero size: "+o+".");t.forEach((function(r,o){var a,d=0===o,s=o===t.length-1,l=i[s?o-1:o].getBoundingClientRect()[e===exports.SplitDirection.Horizontal?"width":"height"];l=d||s?l/2:l,a=n&&o<n.length?"calc("+n[o]+"% - "+l+"px)":"calc("+100/t.length+"% - "+l+"px)",e===exports.SplitDirection.Horizontal?(r.style.width=a,r.style.height="100%"):(r.style.height=a,r.style.width="100%")}))}),[]),k=r.default.useCallback((function(e,t){if(void 0===y.draggingIdx)throw new Error("Cannot adjust size - 'draggingIdx' is undefined.");var i=y.pairs[y.draggingIdx];if(void 0===i.size)throw new Error("Cannot adjust size - 'pair.size' is undefined.");if(void 0===i.gutterSize)throw new Error("Cannot adjust size - 'pair.gutterSize' is undefined.");var n=i.aSizePct+i.bSizePct,r=t/i.size*n,o=n-t/i.size*n,a=0===y.draggingIdx,d=y.draggingIdx===y.pairs.length-1,s=z(i.gutterSize,a,d),l="calc("+r+"% - "+s.aGutterSize+"px)",g="calc("+o+"% - "+s.bGutterSize+"px)";e===exports.SplitDirection.Horizontal?(i.a.style.width=l,i.b.style.width=g):(i.a.style.height=l,i.b.style.height=g)}),[y.draggingIdx,y.pairs,n]),P=r.default.useCallback((function(e,t,i){if(y.isDragging){if(void 0===y.draggingIdx)throw new Error("Cannot drag - 'draggingIdx' is undefined.");var n=y.pairs[y.draggingIdx];if(void 0===n.start)throw new Error("Cannot drag - 'pair.start' is undefined.");if(void 0===n.size)throw new Error("Cannot drag - 'pair.size' is undefined.");if(void 0===n.gutterSize)throw new Error("Cannot drag - 'pair.gutterSize' is undefined.");var r=function(e,t){return e===exports.SplitDirection.Horizontal?t.clientX:t.clientY}(t,e)-n.start,o=void 0===i?16:i;r<n.gutterSize+o&&(r=n.gutterSize+o),r>=n.size-(n.gutterSize+o)&&(r=n.size-(n.gutterSize+o)),k(t,r)}}),[y.isDragging,y.draggingIdx,y.pairs,k]);function N(e,t){if(!e.current)throw new Error("Can't add element to ref object - ref isn't initialized");t&&!e.current.includes(t)&&e.current.push(t)}return l("mouseup",(function(){y.isDragging&&H()}),[y.isDragging,H]),l("mousemove",(function(e){y.isDragging&&P(e,n,n===exports.SplitDirection.Horizontal?o:d)}),[n,y.isDragging,P,o,d]),t.useEffect((function(){if(void 0===f)throw new Error("Cannot initialize split - 'children' are undefined");if(!Array.isArray(f))throw new Error("Cannot initialize split - 'children' isn't an array.");if(f.length<=1)throw new Error("Cannot initialize split - the 'children' array has 1 or less elements. Provide at least 2 child views for the split.");if(!m.current||!R.current)throw new Error("Cannot create pairs - 'childRefs' or 'gutterRefs' is undefined.");I(n,m.current,R.current,g),E(n,m.current,R.current)}),[f,n,I,E,g]),e.jsx(e.Fragment,{children:e.jsx(w,a({dir:n},{children:f&&Array.isArray(f)&&f.map((function(t,i){return e.jsxs(r.default.Fragment,{children:[e.jsx(S,a({ref:function(e){return N(m,e)}},{children:t}),void 0),i<f.length-1&&e.jsx(v,{ref:function(e){return N(R,e)},className:u,draggerClassName:p,direction:n,onMouseDown:function(e){return function(e,t){t.preventDefault(),j(n,e),B(n,e)}(i,e)}},void 0)]},i)}))}),void 0)},void 0)}; | ||
//# sourceMappingURL=index.js.map |
{ | ||
"name": "@devbookhq/splitter", | ||
"version": "1.0.1", | ||
"version": "1.0.2", | ||
"description": "Create resizable split views - like in VS Code", | ||
@@ -29,2 +29,3 @@ "license": "MIT", | ||
"devDependencies": { | ||
"@babel/core": "^7.13.8", | ||
"@types/node": "^12.20.4", | ||
@@ -34,4 +35,9 @@ "@types/react": "^17.0.2", | ||
"@types/styled-components": "^5.1.7", | ||
"autoprefixer": "^10.2.5", | ||
"babel-core": "^6.26.3", | ||
"babel-runtime": "^6.26.0", | ||
"postcss": "^8.2.7", | ||
"rollup-plugin-babel": "^4.4.0", | ||
"rollup-plugin-postcss": "^4.0.0", | ||
"rollup-plugin-terser": "^7.0.2", | ||
"rollup-plugin-typescript2": "^0.30.0", | ||
@@ -38,0 +44,0 @@ "styled-components": "^5.2.1", |
# Splitter | ||
Splitter is a React component thath allows you to split views into resizable panels. Similar to tabs in Visual Studio Code, for example. It's used in [Devbook](https://usedevbook.com) - A Search Engine for Developers. | ||
Splitter is a React component that allows you to split views into resizable panels. Similar to tabs in Visual Studio Code, for example. It's used in [Devbook](https://usedevbook.com) - A Search Engine for Developers. | ||
Here's a gif of what you can build with Splitter: | ||
@@ -10,5 +9,7 @@ ![](example.gif) | ||
- Fully responsive | ||
- No dependencies beside React | ||
- No dependencies beside React and styled-components | ||
- Minimal assumptions about your styling and views | ||
[CodeSandbox project](https://codesandbox.io/s/devbookhqspliiter-example-l23s4) | ||
## Installing | ||
@@ -75,3 +76,3 @@ ``` | ||
## Examples | ||
Check the [`example`](./example/src/App.tsx) folder or the [CodeSandbox project](). | ||
Check the [`example`](./example/src/App.tsx) folder or the [CodeSandbox project](https://codesandbox.io/s/devbookhqspliiter-example-l23s4). | ||
- [Horizontal](./example/src/HorizontalSplit/index.tsx) | ||
@@ -78,0 +79,0 @@ - [Vertical](./example/src/VerticalSplit/index.tsx) |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Minified code
QualityThis package contains minified code. This may be harmless in some cases where minified code is included in packaged libraries, however packages on npm should not minify code.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
232741
16
5449
84
15
1
1