UNPKG

grommet

Version:

The most advanced UX framework for enterprise applications.

328 lines (269 loc) 10.7 kB
'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var _extends2 = require('babel-runtime/helpers/extends'); var _extends3 = _interopRequireDefault(_extends2); var _defineProperty2 = require('babel-runtime/helpers/defineProperty'); var _defineProperty3 = _interopRequireDefault(_defineProperty2); var _objectWithoutProperties2 = require('babel-runtime/helpers/objectWithoutProperties'); var _objectWithoutProperties3 = _interopRequireDefault(_objectWithoutProperties2); var _getPrototypeOf = require('babel-runtime/core-js/object/get-prototype-of'); var _getPrototypeOf2 = _interopRequireDefault(_getPrototypeOf); var _classCallCheck2 = require('babel-runtime/helpers/classCallCheck'); var _classCallCheck3 = _interopRequireDefault(_classCallCheck2); var _createClass2 = require('babel-runtime/helpers/createClass'); var _createClass3 = _interopRequireDefault(_createClass2); var _possibleConstructorReturn2 = require('babel-runtime/helpers/possibleConstructorReturn'); var _possibleConstructorReturn3 = _interopRequireDefault(_possibleConstructorReturn2); var _inherits2 = require('babel-runtime/helpers/inherits'); var _inherits3 = _interopRequireDefault(_inherits2); var _react = require('react'); var _react2 = _interopRequireDefault(_react); var _classnames2 = require('classnames'); var _classnames3 = _interopRequireDefault(_classnames2); var _CSSClassnames = require('../../utils/CSSClassnames'); var _CSSClassnames2 = _interopRequireDefault(_CSSClassnames); var _Drag = require('../icons/base/Drag'); var _Drag2 = _interopRequireDefault(_Drag); var _utils = require('./utils'); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var CLASS_ROOT = _CSSClassnames2.default.CHART_RANGE; // Allows selecting a region. // Click to select one. // Press and Drag to select multiple. // Drag edges to adjust. // (C) Copyright 2016 Hewlett Packard Enterprise Development LP var Range = function (_Component) { (0, _inherits3.default)(Range, _Component); function Range(props, context) { (0, _classCallCheck3.default)(this, Range); var _this = (0, _possibleConstructorReturn3.default)(this, (Range.__proto__ || (0, _getPrototypeOf2.default)(Range)).call(this, props, context)); _this._onMouseMove = _this._onMouseMove.bind(_this); _this._onMouseUp = _this._onMouseUp.bind(_this); _this.state = {}; return _this; } (0, _createClass3.default)(Range, [{ key: 'componentWillUnmount', value: function componentWillUnmount() { var mouseDown = this.state.mouseDown; if (mouseDown) { window.removeEventListener('mouseup', this._onMouseUp); } } }, { key: '_valueToIndex', value: function _valueToIndex(value) { var _props = this.props, count = _props.count, vertical = _props.vertical; var rect = this.rangeRef.getBoundingClientRect(); var total = vertical ? rect.height : rect.width; return Math.round(value / total * (count - 1)); } }, { key: '_percentForIndex', value: function _percentForIndex(index) { var count = this.props.count; return 100 / (count - 1) * Math.min(index, count - 1); } }, { key: '_mouseIndex', value: function _mouseIndex(event) { var _props2 = this.props, active = _props2.active, count = _props2.count, vertical = _props2.vertical; var _state = this.state, mouseDown = _state.mouseDown, mouseDownIndex = _state.mouseDownIndex; var rect = this.rangeRef.getBoundingClientRect(); var value = vertical ? event.clientY - rect.top : event.clientX - rect.left; var index = this._valueToIndex(value); // constrain index to keep it within range as needed if ('active' === mouseDown && mouseDownIndex >= 0) { if (index > mouseDownIndex) { // moving right/down index = Math.min(mouseDownIndex + count - 1 - active.end, index); } else if (index < mouseDownIndex) { // moving up/left index = Math.max(mouseDownIndex - active.start, index); } } else if ('start' === mouseDown) { index = Math.min(active.end, index); } else if ('end' === mouseDown) { index = Math.max(active.start, index); } return index; } }, { key: '_mouseDown', value: function _mouseDown(source) { var _this2 = this; return function (event) { event.stopPropagation(); // so start and end don't trigger range var index = _this2._mouseIndex(event); _this2.setState({ mouseDown: source, mouseDownIndex: index }); window.addEventListener('mouseup', _this2._onMouseUp); }; } }, { key: '_onMouseUp', value: function _onMouseUp(event) { window.removeEventListener('mouseup', this._onMouseUp); var _props3 = this.props, active = _props3.active, onActive = _props3.onActive, count = _props3.count; var _state2 = this.state, mouseDown = _state2.mouseDown, mouseDownIndex = _state2.mouseDownIndex, moved = _state2.moved; var mouseUpIndex = this._mouseIndex(event); if (mouseUpIndex < 0) { mouseUpIndex = 0; } else if (mouseUpIndex > count) { mouseUpIndex = count; } this.setState({ mouseDown: false, mouseDownIndex: undefined, mouseMoveIndex: undefined, moved: false }); if (onActive) { var nextActive = void 0; if ('range' === mouseDown) { if (moved) { nextActive = { start: Math.min(mouseDownIndex, mouseUpIndex), end: Math.max(mouseDownIndex, mouseUpIndex) }; } } else if ('active' === mouseDown) { var delta = mouseUpIndex - mouseDownIndex; nextActive = { start: active.start + delta, end: active.end + delta }; } else if ('start' === mouseDown) { nextActive = { start: mouseUpIndex, end: active.end }; } else if ('end' === mouseDown) { nextActive = { start: active.start, end: mouseUpIndex }; } onActive(nextActive); } } }, { key: '_onMouseMove', value: function _onMouseMove(event) { var mouseMoveIndex = this.state.mouseMoveIndex; var index = this._mouseIndex(event); if (index !== mouseMoveIndex) { this.setState({ mouseMoveIndex: index, moved: true }); } } }, { key: 'render', value: function render() { var _classnames, _this3 = this; var _props4 = this.props, active = _props4.active, className = _props4.className, count = _props4.count, onActive = _props4.onActive, vertical = _props4.vertical, props = (0, _objectWithoutProperties3.default)(_props4, ['active', 'className', 'count', 'onActive', 'vertical']); var _state3 = this.state, mouseDown = _state3.mouseDown, mouseDownIndex = _state3.mouseDownIndex, mouseMoveIndex = _state3.mouseMoveIndex; var classes = (0, _classnames3.default)(CLASS_ROOT, (_classnames = {}, (0, _defineProperty3.default)(_classnames, CLASS_ROOT + '--vertical', vertical), (0, _defineProperty3.default)(_classnames, CLASS_ROOT + '--dragging', mouseDown), _classnames), className); var layers = void 0; if (active || mouseDown) { var start = void 0, end = void 0; if ('range' === mouseDown) { start = Math.min(mouseDownIndex, mouseMoveIndex); end = Math.max(mouseDownIndex, mouseMoveIndex); } else if ('active' === mouseDown && mouseMoveIndex >= 0) { var delta = mouseMoveIndex - mouseDownIndex; start = active.start + delta; end = active.end + delta; } else if ('start' === mouseDown && mouseMoveIndex >= 0) { start = mouseMoveIndex; end = active.end; } else if ('end' === mouseDown && mouseMoveIndex >= 0) { start = active.start; end = mouseMoveIndex; } else { start = active.start; end = active.end; } // in case the user resizes the window start = Math.max(0, Math.min(count - 1, start)); end = Math.max(0, Math.min(count - 1, end)); layers = [_react2.default.createElement('div', { key: 'before', className: CLASS_ROOT + '__inactive', style: { flexBasis: this._percentForIndex(start) + '%' } }), _react2.default.createElement( 'div', (0, _extends3.default)({ key: 'active' }, props, { className: CLASS_ROOT + '__active', style: { flexBasis: this._percentForIndex(end - start) + '%' }, onMouseDown: this._mouseDown('active') }), _react2.default.createElement( 'div', { className: CLASS_ROOT + '__active-start', onMouseDown: onActive ? this._mouseDown('start') : undefined }, _react2.default.createElement(_Drag2.default, null) ), _react2.default.createElement( 'div', { className: CLASS_ROOT + '__active-end', onMouseDown: onActive ? this._mouseDown('end') : undefined }, _react2.default.createElement(_Drag2.default, null) ) ), _react2.default.createElement('div', { key: 'after', className: CLASS_ROOT + '__inactive', style: { flexBasis: this._percentForIndex(count - 1 - end) + '%' } })]; } var onMouseMove = void 0; if (onActive && mouseDown) { onMouseMove = this._onMouseMove; } return _react2.default.createElement( 'div', { ref: function ref(_ref) { return _this3.rangeRef = _ref; }, className: classes, style: { padding: _utils.padding }, onMouseMove: onMouseMove, onMouseDown: onActive ? this._mouseDown('range') : undefined }, layers ); } }]); return Range; }(_react.Component); Range.displayName = 'Range'; exports.default = Range; ; Range.propTypes = { active: _react.PropTypes.shape({ end: _react.PropTypes.number.isRequired, start: _react.PropTypes.number.isRequired }), count: _react.PropTypes.number.isRequired, onActive: _react.PropTypes.func, // (start, end) vertical: _react.PropTypes.bool }; module.exports = exports['default'];