@lyra/components
Version:
Basic UX components
172 lines (140 loc) • 5.51 kB
JavaScript
Object.defineProperty(exports, "__esModule", {
value: true
});
var _debounce2 = require('lodash/debounce');
var _debounce3 = _interopRequireDefault(_debounce2);
var _propTypes = require('prop-types');
var _propTypes2 = _interopRequireDefault(_propTypes);
var _react = require('react');
var _react2 = _interopRequireDefault(_react);
var _reactSplitPane = require('react-split-pane');
var _reactSplitPane2 = _interopRequireDefault(_reactSplitPane);
var _rxjs = require('rxjs');
var _SplitController = require('./styles/SplitController.css');
var _SplitController2 = _interopRequireDefault(_SplitController);
var _operators = require('rxjs/operators');
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/* eslint-disable complexity */
const COLLAPSED_WIDTH = 54;
const fromWindowEvent = eventName => new _rxjs.Observable(subscriber => {
const handler = event => subscriber.next(event);
window.addEventListener(eventName, handler);
return () => {
window.removeEventListener(eventName, handler);
};
});
const orientationChange$ = fromWindowEvent('orientationchange');
const resize$ = fromWindowEvent('resize');
const windowWidth$ = (0, _rxjs.merge)(orientationChange$, resize$).pipe((0, _operators.share)(), (0, _operators.debounceTime)(50), (0, _operators.map)(() => window.innerWidth));
class PanesSplitController extends _react2.default.Component {
constructor(...args) {
var _temp;
return _temp = super(...args), this.state = {
windowWidth: typeof window === 'undefined' ? 1000 : window.innerWidth
}, this.isResizing = false, this.handleSplitPaneChange = (0, _debounce3.default)((size, pane) => {
if (size <= pane.props.minWidth) {
this.props.onSholdCollapse(pane);
} else {
this.props.onSholdExpand(pane);
}
this.lastPaneSize = size;
}, 50), this.handleDragStarted = () => {
this.isResizing = true;
}, this.handleDragFinished = () => {
this.isResizing = false;
}, this.renderSplitPane = (pane1, pane2, restMinWidth, restDefaultWidth) => {
const isCollapsed = pane1.props.isCollapsed;
// Handle size override when collapsing
let size = isCollapsed ? COLLAPSED_WIDTH : undefined;
if (this.isResizing) {
size = undefined;
} else if (isCollapsed) {
size = COLLAPSED_WIDTH;
} else {
size = pane1.props.defaultWidth;
}
return _react2.default.createElement(
'div',
{
className: `
${_SplitController2.default.splitWrapper}
${pane2 ? _SplitController2.default.doubleWrapper : _SplitController2.default.singleWrapper}
${isCollapsed ? _SplitController2.default.isCollapsed : _SplitController2.default.notCollapsed}
`
},
_react2.default.createElement(
_reactSplitPane2.default,
{
minSize: isCollapsed ? COLLAPSED_WIDTH : pane1.props.minWidth,
defaultSize: isCollapsed ? COLLAPSED_WIDTH : pane1.props.defaultWidth,
size: size,
resizerClassName: isCollapsed ? _SplitController2.default.ResizerIsCollapsed : _SplitController2.default.Resizer,
allowResize: true,
className: _SplitController2.default.splitPane,
onDragStarted: this.handleDragStarted,
onDragFinished: this.handleDragFinished,
onChange: newSize => this.handleSplitPaneChange(newSize, pane1)
},
_react2.default.createElement(
'div',
{
className: isCollapsed ? _SplitController2.default.paneInSplittedCollapsed : _SplitController2.default.paneInSplitted
},
pane1
),
pane2 || ' '
)
);
}, this.renderRecursivePanes = panes => {
// only 1 pane left
if (panes.length === 1) {
return this.renderSplitPane(panes[0]);
}
// only 2 panes left
if (panes.length === 2) {
return this.renderSplitPane(panes[0], this.renderSplitPane(panes[1]));
}
// Recursive
const remainingPanes = panes.slice(1);
return this.renderSplitPane(panes[0], this.renderRecursivePanes(remainingPanes));
}, _temp;
}
componentDidMount() {
this.resizeSubscriber = windowWidth$.pipe((0, _operators.distinctUntilChanged)()).subscribe(windowWidth => {
this.setState({ windowWidth });
});
}
componentWillUnmount() {
this.resizeSubscriber.unsubscribe();
}
render() {
const children = this.props.children;
const panes = _react2.default.Children.toArray(children);
if (panes.length === 0) {
return _react2.default.createElement(
'div',
null,
'No panes'
);
}
// TODO We need a way to target mobile devices in JS
// --screen-medium-break: 32em; ~32 * 16 = 512
const isLessThanScreenMedium = this.state.windowWidth < 512;
return _react2.default.createElement(
'div',
{ className: _SplitController2.default.vertical },
isLessThanScreenMedium ? children : this.renderRecursivePanes(panes.filter(pane => pane.type !== 'div'))
);
}
}
exports.default = PanesSplitController;
PanesSplitController.propTypes = {
children: _propTypes2.default.node.isRequired,
onSholdCollapse: _propTypes2.default.func,
onSholdExpand: _propTypes2.default.func
};
PanesSplitController.defaultProps = {
onSholdCollapse() {},
onSholdExpand() {}
};
;