react-native-web-headroom
Version:
React Native Web Headroom
422 lines (372 loc) • 15.4 kB
JavaScript
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
var _react = require('react');
var _react2 = _interopRequireDefault(_react);
var _propTypes = require('prop-types');
var _propTypes2 = _interopRequireDefault(_propTypes);
var _reactDom = require('react-dom');
var _reactDom2 = _interopRequireDefault(_reactDom);
var _inlineStylePrefixer = require('inline-style-prefixer');
var _inlineStylePrefixer2 = _interopRequireDefault(_inlineStylePrefixer);
var _reactStyleProptype = require('react-style-proptype');
var _reactStyleProptype2 = _interopRequireDefault(_reactStyleProptype);
var _Pane = require('./Pane');
var _Pane2 = _interopRequireDefault(_Pane);
var _Resizer = require('./Resizer');
var _Resizer2 = _interopRequireDefault(_Resizer);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
var DEFAULT_USER_AGENT = 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.2 (KHTML, like Gecko) Safari/537.2';
var USER_AGENT = typeof navigator !== 'undefined' ? navigator.userAgent : DEFAULT_USER_AGENT;
function unFocus(document, window) {
if (document.selection) {
document.selection.empty();
} else {
try {
window.getSelection().removeAllRanges();
// eslint-disable-next-line no-empty
} catch (e) {}
}
}
var SplitPane = function (_React$Component) {
_inherits(SplitPane, _React$Component);
function SplitPane() {
_classCallCheck(this, SplitPane);
var _this = _possibleConstructorReturn(this, (SplitPane.__proto__ || Object.getPrototypeOf(SplitPane)).call(this));
_this.onMouseDown = _this.onMouseDown.bind(_this);
_this.onTouchStart = _this.onTouchStart.bind(_this);
_this.onMouseMove = _this.onMouseMove.bind(_this);
_this.onTouchMove = _this.onTouchMove.bind(_this);
_this.onMouseUp = _this.onMouseUp.bind(_this);
_this.state = {
active: false,
resized: false
};
return _this;
}
_createClass(SplitPane, [{
key: 'componentDidMount',
value: function componentDidMount() {
this.setSize(this.props, this.state);
document.addEventListener('mouseup', this.onMouseUp);
document.addEventListener('mousemove', this.onMouseMove);
document.addEventListener('touchmove', this.onTouchMove);
}
}, {
key: 'componentWillReceiveProps',
value: function componentWillReceiveProps(props) {
this.setSize(props, this.state);
}
}, {
key: 'componentWillUnmount',
value: function componentWillUnmount() {
document.removeEventListener('mouseup', this.onMouseUp);
document.removeEventListener('mousemove', this.onMouseMove);
document.removeEventListener('touchmove', this.onTouchMove);
}
}, {
key: 'onMouseDown',
value: function onMouseDown(event) {
var eventWithTouches = _extends({}, event, {
touches: [{ clientX: event.clientX, clientY: event.clientY }]
});
this.onTouchStart(eventWithTouches);
}
}, {
key: 'onTouchStart',
value: function onTouchStart(event) {
var _props = this.props,
allowResize = _props.allowResize,
onDragStarted = _props.onDragStarted,
split = _props.split;
if (allowResize) {
unFocus(document, window);
var position = split === 'vertical' ? event.touches[0].clientX : event.touches[0].clientY;
if (typeof onDragStarted === 'function') {
onDragStarted();
}
this.setState({
active: true,
position: position
});
}
}
}, {
key: 'onMouseMove',
value: function onMouseMove(event) {
var eventWithTouches = _extends({}, event, {
touches: [{ clientX: event.clientX, clientY: event.clientY }]
});
this.onTouchMove(eventWithTouches);
}
}, {
key: 'onTouchMove',
value: function onTouchMove(event) {
var _props2 = this.props,
allowResize = _props2.allowResize,
maxSize = _props2.maxSize,
minSize = _props2.minSize,
onChange = _props2.onChange,
split = _props2.split,
step = _props2.step;
var _state = this.state,
active = _state.active,
position = _state.position;
if (allowResize && active) {
unFocus(document, window);
var isPrimaryFirst = this.props.primary === 'first';
var ref = isPrimaryFirst ? this.pane1 : this.pane2;
var ref2 = isPrimaryFirst ? this.pane2 : this.pane1;
if (ref) {
var node = _reactDom2.default.findDOMNode(ref);
var node2 = _reactDom2.default.findDOMNode(ref2);
if (node.getBoundingClientRect) {
var width = node.getBoundingClientRect().width;
var height = node.getBoundingClientRect().height;
var current = split === 'vertical' ? event.touches[0].clientX : event.touches[0].clientY;
var size = split === 'vertical' ? width : height;
var positionDelta = position - current;
if (step) {
if (Math.abs(positionDelta) < step) {
return;
}
// Integer division
// eslint-disable-next-line no-bitwise
positionDelta = ~~(positionDelta / step) * step;
}
var sizeDelta = isPrimaryFirst ? positionDelta : -positionDelta;
var pane1Order = parseInt(window.getComputedStyle(node).order);
var pane2Order = parseInt(window.getComputedStyle(node2).order);
if (pane1Order > pane2Order) {
sizeDelta = -sizeDelta;
}
var newMaxSize = maxSize;
if (maxSize !== undefined && maxSize <= 0) {
var splPane = this.splitPane;
if (split === 'vertical') {
newMaxSize = splPane.getBoundingClientRect().width + maxSize;
} else {
newMaxSize = splPane.getBoundingClientRect().height + maxSize;
}
}
var newSize = size - sizeDelta;
var newPosition = position - positionDelta;
if (newSize < minSize) {
newSize = minSize;
} else if (maxSize !== undefined && newSize > newMaxSize) {
newSize = newMaxSize;
} else {
this.setState({
position: newPosition,
resized: true
});
}
if (onChange) onChange(newSize);
this.setState({ draggedSize: newSize });
ref.setState({ size: newSize });
}
}
}
}
}, {
key: 'onMouseUp',
value: function onMouseUp() {
var _props3 = this.props,
allowResize = _props3.allowResize,
onDragFinished = _props3.onDragFinished;
var _state2 = this.state,
active = _state2.active,
draggedSize = _state2.draggedSize;
if (allowResize && active) {
if (typeof onDragFinished === 'function') {
onDragFinished(draggedSize);
}
this.setState({ active: false });
}
}
}, {
key: 'setSize',
value: function setSize(props, state) {
var isPrimaryFirst = props.primary === 'first';
var ref = isPrimaryFirst ? this.pane1 : this.pane2;
var ref2 = isPrimaryFirst ? this.pane2 : this.pane1;
var newSize = void 0;
if (ref) {
newSize = props.size || state && state.draggedSize || props.defaultSize || props.minSize;
ref.setState({
size: newSize
});
if (props.size !== state.draggedSize) {
this.setState({
draggedSize: newSize
});
}
}
if (ref2 && props.primary !== this.props.primary) {
ref2.setState({
size: undefined
});
}
}
}, {
key: 'render',
value: function render() {
var _this2 = this;
var _props4 = this.props,
allowResize = _props4.allowResize,
children = _props4.children,
className = _props4.className,
defaultSize = _props4.defaultSize,
minSize = _props4.minSize,
onResizerClick = _props4.onResizerClick,
onResizerDoubleClick = _props4.onResizerDoubleClick,
paneClassName = _props4.paneClassName,
pane1ClassName = _props4.pane1ClassName,
pane2ClassName = _props4.pane2ClassName,
paneStyle = _props4.paneStyle,
pane1StyleProps = _props4.pane1Style,
pane2StyleProps = _props4.pane2Style,
primary = _props4.primary,
prefixer = _props4.prefixer,
resizerClassName = _props4.resizerClassName,
resizerStyle = _props4.resizerStyle,
size = _props4.size,
split = _props4.split,
styleProps = _props4.style;
var disabledClass = allowResize ? '' : 'disabled';
var resizerClassNamesIncludingDefault = resizerClassName ? resizerClassName + ' ' + _Resizer.RESIZER_DEFAULT_CLASSNAME : resizerClassName;
var style = _extends({}, {
display: 'flex',
flex: 1,
height: '100%',
position: 'absolute',
outline: 'none',
overflow: 'hidden',
MozUserSelect: 'text',
WebkitUserSelect: 'text',
msUserSelect: 'text',
userSelect: 'text'
}, styleProps || {});
if (split === 'vertical') {
_extends(style, {
flexDirection: 'row',
left: 0,
right: 0
});
} else {
_extends(style, {
bottom: 0,
flexDirection: 'column',
minHeight: '100%',
top: 0,
width: '100%'
});
}
var classes = ['SplitPane', className, split, disabledClass];
var pane1Style = prefixer.prefix(_extends({}, paneStyle || {}, pane1StyleProps || {}));
var pane2Style = prefixer.prefix(_extends({}, paneStyle || {}, pane2StyleProps || {}));
var pane1Classes = ['Pane1', paneClassName, pane1ClassName].join(' ');
var pane2Classes = ['Pane2', paneClassName, pane2ClassName].join(' ');
return _react2.default.createElement(
'div',
{
className: classes.join(' '),
ref: function ref(node) {
_this2.splitPane = node;
},
style: prefixer.prefix(style)
},
_react2.default.createElement(
_Pane2.default,
{
className: pane1Classes,
key: 'pane1',
ref: function ref(node) {
_this2.pane1 = node;
},
size: primary === 'first' ? size || defaultSize || minSize : undefined,
split: split,
style: pane1Style
},
children[0]
),
_react2.default.createElement(_Resizer2.default, {
className: disabledClass,
onClick: onResizerClick,
onDoubleClick: onResizerDoubleClick,
onMouseDown: this.onMouseDown,
onTouchStart: this.onTouchStart,
onTouchEnd: this.onMouseUp,
key: 'resizer',
ref: function ref(node) {
_this2.resizer = node;
},
resizerClassName: resizerClassNamesIncludingDefault,
split: split,
style: resizerStyle || {}
}),
_react2.default.createElement(
_Pane2.default,
{
className: pane2Classes,
key: 'pane2',
ref: function ref(node) {
_this2.pane2 = node;
},
size: primary === 'second' ? size || defaultSize || minSize : undefined,
split: split,
style: pane2Style
},
children[1]
)
);
}
}]);
return SplitPane;
}(_react2.default.Component);
SplitPane.propTypes = {
allowResize: _propTypes2.default.bool,
children: _propTypes2.default.arrayOf(_propTypes2.default.node).isRequired,
className: _propTypes2.default.string,
primary: _propTypes2.default.oneOf(['first', 'second']),
minSize: _propTypes2.default.oneOfType([_propTypes2.default.string, _propTypes2.default.number]),
maxSize: _propTypes2.default.oneOfType([_propTypes2.default.string, _propTypes2.default.number]),
// eslint-disable-next-line react/no-unused-prop-types
defaultSize: _propTypes2.default.oneOfType([_propTypes2.default.string, _propTypes2.default.number]),
size: _propTypes2.default.oneOfType([_propTypes2.default.string, _propTypes2.default.number]),
split: _propTypes2.default.oneOf(['vertical', 'horizontal']),
onDragStarted: _propTypes2.default.func,
onDragFinished: _propTypes2.default.func,
onChange: _propTypes2.default.func,
onResizerClick: _propTypes2.default.func,
onResizerDoubleClick: _propTypes2.default.func,
prefixer: _propTypes2.default.instanceOf(_inlineStylePrefixer2.default).isRequired,
style: _reactStyleProptype2.default,
resizerStyle: _reactStyleProptype2.default,
paneClassName: _propTypes2.default.string,
pane1ClassName: _propTypes2.default.string,
pane2ClassName: _propTypes2.default.string,
paneStyle: _reactStyleProptype2.default,
pane1Style: _reactStyleProptype2.default,
pane2Style: _reactStyleProptype2.default,
resizerClassName: _propTypes2.default.string,
step: _propTypes2.default.number
};
SplitPane.defaultProps = {
allowResize: true,
minSize: 50,
prefixer: new _inlineStylePrefixer2.default({ userAgent: USER_AGENT }),
primary: 'first',
split: 'vertical',
paneClassName: '',
pane1ClassName: '',
pane2ClassName: ''
};
exports.default = SplitPane;
module.exports = exports['default'];