UNPKG

rsuite

Version:

A suite of react components

545 lines (459 loc) 20.7 kB
"use strict"; var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard"); var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); exports.__esModule = true; exports.default = void 0; var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends")); var _objectWithoutPropertiesLoose2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutPropertiesLoose")); var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator")); var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass")); var _inheritsLoose2 = _interopRequireDefault(require("@babel/runtime/helpers/inheritsLoose")); var React = _interopRequireWildcard(require("react")); var _propTypes = _interopRequireDefault(require("prop-types")); var _recompose = require("recompose"); var _classnames = _interopRequireDefault(require("classnames")); var _domLib = require("dom-lib"); var _utils = require("./utils"); var _utils2 = require("../utils"); var _ListItem = _interopRequireDefault(require("./ListItem")); var _Manager = _interopRequireDefault(require("./Manager")); var _AutoScroller = _interopRequireDefault(require("./AutoScroller")); var _ListContext = _interopRequireDefault(require("./ListContext")); var NodeType = { Canvas: 'CANVAS', Anchor: 'A', Button: 'BUTTON', Input: 'INPUT', Option: 'OPTION', Textarea: 'TEXTAREA', Select: 'SELECT' }; var interactiveElements = [NodeType.Anchor, NodeType.Button, NodeType.Input, NodeType.Option, NodeType.Textarea, NodeType.Select]; var List = /*#__PURE__*/ function (_React$Component) { (0, _inheritsLoose2.default)(List, _React$Component); function List() { var _this; for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { args[_key] = arguments[_key]; } _this = _React$Component.call.apply(_React$Component, [this].concat(args)) || this; _this.state = { sorting: false, manager: new _Manager.default() }; _this.containerRef = React.createRef(); _this.containerBoundingRect = void 0; _this.touched = void 0; _this.scrollContainer = void 0; _this.scrollContainerInitialScroll = void 0; _this.autoScroller = void 0; _this.windowInitialScroll = void 0; _this.animatedNodeOffset = []; _this.activeNodeBoundingClientRect = void 0; _this.activeNodeGhost = void 0; _this.activeNodeFlowBody = void 0; _this.activeNodeFlowBodyTranslate = void 0; _this.activeNodeMarginOffset = void 0; _this.activeNodeOffsetEdge = void 0; _this.activeNodeOldIndex = void 0; _this.activeNodeNextIndex = void 0; _this.activeNodeTranslateMin = void 0; _this.activeNodeTranslateMax = void 0; _this.windowStartListener = void 0; _this.windowEndListener = void 0; _this.sortMouseMoveListener = void 0; _this.sortMouseEndListener = void 0; _this.cursorInitialOffset = void 0; _this.cursorCurrentPosition = void 0; _this.pressTimer = void 0; _this.handleStart = function (event) { var _this$props = _this.props, sortable = _this$props.sortable, pressDelay = _this$props.pressDelay; var _this$state = _this.state, sorting = _this$state.sorting, manager = _this$state.manager; var node = (0, _utils.closest)(event.target, function (el) { return !!manager.getNodeManagerRef(el); }); var curManager = manager.getNodeManagerRef(node); if (!((event === null || event === void 0 ? void 0 : event.target) && node instanceof HTMLElement && curManager)) { return; } var _curManager$info = curManager.info, disabled = _curManager$info.disabled, curNodeManager = _curManager$info.manager; if ( //is sortable sortable && //is list item !disabled && //is not secondary button pressed event.button !== 2 && //is this list curNodeManager === manager && //is not sorting !sorting && //excludes interactive elements !node.contains((0, _utils.closest)(event.target, function (el) { return interactiveElements.includes(el.tagName) || el.contentEditable === 'true'; }))) { event.preventDefault(); _this.touched = true; _this.cursorCurrentPosition = (0, _utils.getPosition)(event); manager.setActive(curManager); _this.pressTimer = setTimeout(function () { return _this.handlePress(event); }, pressDelay); } }; _this.handleEnd = function () { var _this$state2 = _this.state, sorting = _this$state2.sorting, manager = _this$state2.manager; _this.touched = false; if (!sorting) { clearTimeout(_this.pressTimer); manager.setActive(null); } }; _this.handlePress = function _callee(event) { var _this$props2, classPrefix, onSortStart, manager, _manager$getActive, activeNode, info, index, collection, addItemPrefix, style, activeNodeMargin; return _regenerator.default.async(function _callee$(_context) { while (1) { switch (_context.prev = _context.next) { case 0: _this$props2 = _this.props, classPrefix = _this$props2.classPrefix, onSortStart = _this$props2.onSortStart; manager = _this.state.manager; _manager$getActive = manager.getActive(), activeNode = _manager$getActive.node, info = _manager$getActive.info; // return if no active node if (!(!activeNode || !info)) { _context.next = 5; break; } return _context.abrupt("return"); case 5: index = info.index, collection = info.collection; addItemPrefix = (0, _utils2.prefix)(classPrefix + '-item'); style = window.getComputedStyle(activeNode); activeNodeMargin = { bottom: parseFloat(style.marginBottom), left: parseFloat(style.marginLeft), right: parseFloat(style.marginRight), top: parseFloat(style.marginTop) }; _this.activeNodeMarginOffset = { x: activeNodeMargin.left + activeNodeMargin.right, y: Math.max(activeNodeMargin.top, activeNodeMargin.bottom) }; _this.activeNodeBoundingClientRect = activeNode.getBoundingClientRect(); _this.containerBoundingRect = _this.scrollContainer.getBoundingClientRect(); _this.activeNodeOldIndex = index; _this.activeNodeNextIndex = index; _this.activeNodeOffsetEdge = (0, _utils.getEdgeOffset)(activeNode, _this.containerRef.current); _this.cursorInitialOffset = (0, _utils.getPosition)(event); _this.scrollContainerInitialScroll = { left: _this.scrollContainer.scrollLeft, top: _this.scrollContainer.scrollTop }; _this.windowInitialScroll = { left: window.pageXOffset, top: window.pageYOffset }; _this.activeNodeFlowBody = document.body.appendChild(activeNode.cloneNode(true)); _this.activeNodeFlowBody && _this.activeNodeFlowBody.classList.add(addItemPrefix('helper')); (0, _utils.setInlineStyles)(_this.activeNodeFlowBody, { position: 'fixed', width: _this.activeNodeBoundingClientRect.width + "px", height: _this.activeNodeBoundingClientRect.height + "px", left: _this.activeNodeBoundingClientRect.left - activeNodeMargin.left + "px", top: _this.activeNodeBoundingClientRect.top - activeNodeMargin.top + "px" }); _this.activeNodeGhost = activeNode; activeNode.classList.add(addItemPrefix('holder')); _this.activeNodeTranslateMin = { y: _this.containerBoundingRect.top - _this.activeNodeBoundingClientRect.top - _this.activeNodeBoundingClientRect.height / 2 }; _this.activeNodeTranslateMax = { y: _this.containerBoundingRect.top + _this.containerBoundingRect.height - _this.activeNodeBoundingClientRect.top - _this.activeNodeBoundingClientRect.height / 2 }; _this.sortMouseMoveListener = (0, _domLib.on)(window, 'mousemove', _this.handleSortMove, { passive: false }); _this.sortMouseEndListener = (0, _domLib.on)(window, 'mouseup', _this.handleSortEnd, { passive: false }); _this.setState({ sorting: true }); if (onSortStart) { onSortStart({ collection: collection, node: activeNode, oldIndex: _this.activeNodeOldIndex, newIndex: _this.activeNodeNextIndex }, event); } case 29: case "end": return _context.stop(); } } }); }; _this.handleSortMove = function (event) { var _this$props3 = _this.props, onSortMove = _this$props3.onSortMove, autoScroll = _this$props3.autoScroll; var manager = _this.state.manager; // Update helper position var offset = (0, _utils.getPosition)(event); var translate = { x: offset.x - _this.cursorInitialOffset.x, y: offset.y - _this.cursorInitialOffset.y }; // Adjust for window scroll translate.x -= window.pageXOffset - _this.windowInitialScroll.left; translate.y -= window.pageYOffset - _this.windowInitialScroll.top; _this.activeNodeFlowBodyTranslate = translate; (0, _utils.setTranslate3d)(_this.activeNodeFlowBody, translate); _this.animateNodes(); // auto scroll if (autoScroll) { _this.autoScroller.update({ width: _this.activeNodeBoundingClientRect.width, height: _this.activeNodeBoundingClientRect.height, translate: _this.activeNodeFlowBodyTranslate, maxTranslate: _this.activeNodeTranslateMax, minTranslate: _this.activeNodeTranslateMin }); } if (onSortMove) { onSortMove({ collection: manager.getActive().info.collection, node: manager.getActive().node, oldIndex: _this.activeNodeOldIndex, newIndex: _this.activeNodeNextIndex }, event); } }; _this.handleSortEnd = function (event) { var _this$props4 = _this.props, onSortEnd = _this$props4.onSortEnd, onSort = _this$props4.onSort, classPrefix = _this$props4.classPrefix, transitionDuration = _this$props4.transitionDuration; var manager = _this.state.manager; var activeManagerRef = manager.getActive(); var activeCollection = activeManagerRef ? activeManagerRef.info.collection : 0; var managerRefs = manager.getOrderedRefs(activeCollection); var addItemPrefix = (0, _utils2.prefix)(classPrefix + '-item'); // Remove the event listeners _this.sortMouseMoveListener.off(); _this.sortMouseEndListener.off(); (0, _utils.setTransitionDuration)(_this.activeNodeFlowBody, transitionDuration); (0, _utils.setTranslate3d)(_this.activeNodeFlowBody, { x: _this.holderTranslate.x - _this.containerScrollDelta.left, y: _this.holderTranslate.y - _this.containerScrollDelta.top }); // wait for animation setTimeout(function () { // Remove the helper from the DOM if (_this.activeNodeFlowBody) { _this.activeNodeFlowBody.parentNode && _this.activeNodeFlowBody.parentNode.removeChild(_this.activeNodeFlowBody); _this.activeNodeFlowBody = null; } if (_this.activeNodeGhost) { _this.activeNodeGhost.classList.remove(addItemPrefix('holder')); (0, _utils.setTranslate3d)(_this.activeNodeGhost, null); _this.animatedNodeOffset = []; } for (var i = 0, len = managerRefs.length; i < len; i++) { var managerRef = managerRefs[i]; var el = managerRef.node; // Clear the cached offsetTop / offsetLeft value managerRef.edgeOffset = null; // Remove the transforms / transitions (0, _utils.setTranslate3d)(el, null); (0, _utils.setTransitionDuration)(el, null); } // Stop autoScroll _this.autoScroller.clear(); // Update manager state manager.setActive(null); _this.setState({ sorting: false }); if (typeof onSortEnd === 'function') { onSortEnd({ collection: activeCollection, node: activeManagerRef.node, newIndex: _this.activeNodeNextIndex, oldIndex: _this.activeNodeOldIndex }, event); } if (typeof onSort === 'function') { onSort({ collection: activeCollection, node: activeManagerRef.node, newIndex: _this.activeNodeNextIndex, oldIndex: _this.activeNodeOldIndex }, event); } }, transitionDuration); }; return _this; } var _proto = List.prototype; _proto.componentDidMount = function componentDidMount() { var _this2 = this; if (this.containerRef.current instanceof HTMLElement) { this.scrollContainer = (0, _utils.getScrollingParent)(this.containerRef.current) || this.containerRef.current; this.autoScroller = new _AutoScroller.default(this.scrollContainer, function (offset) { _this2.activeNodeFlowBodyTranslate.x += offset.left; _this2.activeNodeFlowBodyTranslate.y += offset.top; }); this.windowStartListener = (0, _domLib.on)(this.containerRef.current, 'mousedown', this.handleStart, { passive: false }); this.windowEndListener = (0, _domLib.on)(this.containerRef.current, 'mouseup', this.handleEnd, { passive: false }); } }; _proto.componentWillUnmount = function componentWillUnmount() { var _this$windowStartList, _this$windowEndListen; (_this$windowStartList = this.windowStartListener) === null || _this$windowStartList === void 0 ? void 0 : _this$windowStartList.off(); (_this$windowEndListen = this.windowEndListener) === null || _this$windowEndListen === void 0 ? void 0 : _this$windowEndListen.off(); }; _proto.animateNodes = function animateNodes() { var transitionDuration = this.props.transitionDuration; var manager = this.state.manager; var listItemManagerRefs = manager.getOrderedRefs(); var sortingOffset = { left: this.activeNodeOffsetEdge.left + this.activeNodeFlowBodyTranslate.x + this.containerScrollDelta.left, top: this.activeNodeOffsetEdge.top + this.activeNodeFlowBodyTranslate.y + this.containerScrollDelta.top }; this.activeNodeNextIndex = -1; for (var i = 0, len = listItemManagerRefs.length; i < len; i++) { var _listItemManagerRefs$ = listItemManagerRefs[i], node = _listItemManagerRefs$.node, index = _listItemManagerRefs$.info.index, edgeOffset = _listItemManagerRefs$.edgeOffset; var width = node.offsetWidth; var height = node.offsetHeight; var offset = { height: this.activeNodeBoundingClientRect.height > height ? height / 2 : this.activeNodeBoundingClientRect.height / 2, width: this.activeNodeBoundingClientRect.width > width ? width / 2 : this.activeNodeBoundingClientRect.width / 2 }; var translate = { x: 0, y: 0 }; // If we haven't cached the node's offsetTop / offsetLeft value var curEdgeOffset = edgeOffset || (0, _utils.getEdgeOffset)(node, this.containerRef.current); listItemManagerRefs[i].edgeOffset = curEdgeOffset; // Get a reference to the next node var prvNode = i > 0 && listItemManagerRefs[i - 1]; var nextNode = i < len - 1 && listItemManagerRefs[i + 1]; // Also cache the node's edge offset if needed. if (prvNode && !prvNode.edgeOffset) { prvNode.edgeOffset = (0, _utils.getEdgeOffset)(prvNode.node, this.containerRef.current); } if (nextNode && !nextNode.edgeOffset) { nextNode.edgeOffset = (0, _utils.getEdgeOffset)(nextNode.node, this.containerRef.current); } // If the node is the one we're currently animating, skip it if (index === this.activeNodeOldIndex) { continue; } var distanceTop = sortingOffset.top + this.windowScrollDelta.top; if (prvNode && index > this.activeNodeOldIndex && distanceTop + offset.height >= curEdgeOffset.top) { translate.y = prvNode.edgeOffset.top - curEdgeOffset.top; this.activeNodeNextIndex = index; } else if (nextNode && index < this.activeNodeOldIndex && distanceTop <= curEdgeOffset.top + offset.height) { translate.y = nextNode.edgeOffset.top - curEdgeOffset.top; if (this.activeNodeNextIndex === -1) { this.activeNodeNextIndex = index; } } (0, _utils.setTransitionDuration)(node, transitionDuration); (0, _utils.setTranslate3d)(node, translate); // translate holder this.animatedNodeOffset[index] = translate; (0, _utils.setTranslate3d)(this.activeNodeGhost, this.holderTranslate); } if (this.activeNodeNextIndex === -1) { this.activeNodeNextIndex = this.activeNodeOldIndex; } }; _proto.render = function render() { var _classNames; var _this$props5 = this.props, className = _this$props5.className, classPrefix = _this$props5.classPrefix, bordered = _this$props5.bordered, hover = _this$props5.hover, size = _this$props5.size, sortable = _this$props5.sortable, children = _this$props5.children, rest = (0, _objectWithoutPropertiesLoose2.default)(_this$props5, ["className", "classPrefix", "bordered", "hover", "size", "sortable", "children"]); var _this$state3 = this.state, sorting = _this$state3.sorting, manager = _this$state3.manager; var addPrefix = (0, _utils2.prefix)(classPrefix); var unhandled = (0, _utils2.getUnhandledProps)(List, rest); var classes = (0, _classnames.default)(classPrefix, className, (_classNames = {}, _classNames[addPrefix('bordered')] = bordered, _classNames[addPrefix('sortable')] = sortable, _classNames[addPrefix('sorting')] = sorting, _classNames[addPrefix('hover')] = hover, _classNames)); var contextValue = { bordered: bordered, size: size, manager: manager }; return React.createElement(_ListContext.default.Provider, { value: contextValue }, React.createElement("div", (0, _extends2.default)({ ref: this.containerRef, className: classes }, unhandled), children)); }; (0, _createClass2.default)(List, [{ key: "containerScrollDelta", get: function get() { return { left: this.scrollContainer.scrollLeft - this.scrollContainerInitialScroll.left, top: this.scrollContainer.scrollTop - this.scrollContainerInitialScroll.top }; } }, { key: "windowScrollDelta", get: function get() { return { left: window.pageXOffset - this.windowInitialScroll.left, top: window.pageYOffset - this.windowInitialScroll.top }; } }, { key: "holderTranslate", get: function get() { return this.animatedNodeOffset.reduce(function (acc, item) { return { x: acc.x - item.x, y: acc.y - item.y }; }, { x: 0, y: 0 }); } }]); return List; }(React.Component); List.propTypes = { className: _propTypes.default.string, classPrefix: _propTypes.default.string, bordered: _propTypes.default.bool, hover: _propTypes.default.bool, sortable: _propTypes.default.bool, size: _propTypes.default.oneOf(['lg', 'md', 'sm']), autoScroll: _propTypes.default.bool, pressDelay: _propTypes.default.number, transitionDuration: _propTypes.default.number, onSortStart: _propTypes.default.func, onSortMove: _propTypes.default.func, onSortEnd: _propTypes.default.func, onSort: _propTypes.default.func }; List.defaultProps = { size: 'md', autoScroll: true, pressDelay: 0, transitionDuration: 300 }; var EnhancedList = (0, _utils2.defaultProps)({ classPrefix: 'list' })(List); (0, _recompose.setStatic)('Item', _ListItem.default)(EnhancedList); var _default = EnhancedList; exports.default = _default; module.exports = exports.default;