UNPKG

shineout

Version:

Shein 前端组件库

464 lines (387 loc) 16.6 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); exports.__esModule = true; exports.default = exports.DefaultProps = void 0; var _objectSpread2 = _interopRequireDefault(require("@babel/runtime/helpers/objectSpread")); var _inheritsLoose2 = _interopRequireDefault(require("@babel/runtime/helpers/inheritsLoose")); var _assertThisInitialized2 = _interopRequireDefault(require("@babel/runtime/helpers/assertThisInitialized")); var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); var _react = _interopRequireDefault(require("react")); var _classnames = _interopRequireDefault(require("classnames")); var _immer = _interopRequireDefault(require("immer")); var _uid = require("../utils/uid"); var _normalizeWheel = _interopRequireDefault(require("../utils/dom/normalizeWheel")); var _Bar = _interopRequireDefault(require("../Scroll/Bar")); var _styles = require("./styles"); var _List = _interopRequireDefault(require("./List")); var _context = require("./context"); var _is = require("../utils/is"); var _config = require("../config"); var _component = require("../component"); var DefaultProps = { data: [], level: 0, keygen: 'id', mode: 'inline', inlineIndent: 24, renderItem: 'title', defaultOpenKeys: [], onClick: function onClick() { return true; }, toggleDuration: 200, frontCaretType: 'solid', style: {}, disabled: function disabled(d) { return d.disabled; } }; exports.DefaultProps = DefaultProps; var modeDirection = { 'vertical-auto': 'y', vertical: 'y', horizontal: 'x' }; var getOption = function getOption(mode) { return mode.indexOf('vertical') === 0 ? { key: 'height', pos: 'Top', direction: 'Y' } : { key: 'width', pos: 'Left', direction: 'X' }; }; function keyToMap(keys, value) { if (keys === void 0) { keys = []; } if (value === void 0) { value = true; } var keyMap = new Map(); keys.forEach(function (v) { keyMap.set(v, value); }); return keyMap; } // function isSubMenu(el) { // if (el.matches(`.${menuClass('sub')}`)) return true // if (!el.parentElement) return false // return isSubMenu(el.parentElement) // } var Root = /*#__PURE__*/ function (_Component) { (0, _inheritsLoose2.default)(Root, _Component); function Root(props) { var _this; _this = _Component.call(this, props) || this; (0, _defineProperty2.default)((0, _assertThisInitialized2.default)((0, _assertThisInitialized2.default)(_this)), "handleScrollLeft", void 0); (0, _defineProperty2.default)((0, _assertThisInitialized2.default)((0, _assertThisInitialized2.default)(_this)), "handleScrollTop", void 0); (0, _defineProperty2.default)((0, _assertThisInitialized2.default)((0, _assertThisInitialized2.default)(_this)), "items", void 0); (0, _defineProperty2.default)((0, _assertThisInitialized2.default)((0, _assertThisInitialized2.default)(_this)), "itemsOpen", void 0); (0, _defineProperty2.default)((0, _assertThisInitialized2.default)((0, _assertThisInitialized2.default)(_this)), "itemsInPath", void 0); (0, _defineProperty2.default)((0, _assertThisInitialized2.default)((0, _assertThisInitialized2.default)(_this)), "providerValue", void 0); (0, _defineProperty2.default)((0, _assertThisInitialized2.default)((0, _assertThisInitialized2.default)(_this)), "container", void 0); (0, _defineProperty2.default)((0, _assertThisInitialized2.default)((0, _assertThisInitialized2.default)(_this)), "hasToggled", void 0); (0, _defineProperty2.default)((0, _assertThisInitialized2.default)((0, _assertThisInitialized2.default)(_this)), "wrapper", void 0); (0, _defineProperty2.default)((0, _assertThisInitialized2.default)((0, _assertThisInitialized2.default)(_this)), "rootElement", void 0); _this.state = { activeKey: null, scrollTop: 0, scrollLeft: 0, openKeys: keyToMap(props.defaultOpenKeys) }; _this.checkOpen = _this.checkOpen.bind((0, _assertThisInitialized2.default)((0, _assertThisInitialized2.default)(_this))); _this.checkActive = _this.checkActive.bind((0, _assertThisInitialized2.default)((0, _assertThisInitialized2.default)(_this))); _this.checkInPath = _this.checkInPath.bind((0, _assertThisInitialized2.default)((0, _assertThisInitialized2.default)(_this))); _this.handleClick = _this.handleClick.bind((0, _assertThisInitialized2.default)((0, _assertThisInitialized2.default)(_this))); _this.handleScrollLeft = _this.handleScrollX.bind((0, _assertThisInitialized2.default)((0, _assertThisInitialized2.default)(_this)), 'Left'); _this.handleScrollTop = _this.handleScrollX.bind((0, _assertThisInitialized2.default)((0, _assertThisInitialized2.default)(_this)), 'Top'); _this.handleScroll = _this.handleScroll.bind((0, _assertThisInitialized2.default)((0, _assertThisInitialized2.default)(_this))); _this.handleWheel = _this.handleWheel.bind((0, _assertThisInitialized2.default)((0, _assertThisInitialized2.default)(_this))); _this.renderItem = _this.renderItem.bind((0, _assertThisInitialized2.default)((0, _assertThisInitialized2.default)(_this))); _this.bindRootElement = _this.bindRootElement.bind((0, _assertThisInitialized2.default)((0, _assertThisInitialized2.default)(_this))); _this.toggleOpenKeys = _this.toggleOpenKeys.bind((0, _assertThisInitialized2.default)((0, _assertThisInitialized2.default)(_this))); _this.providerValue = { bindItem: _this.bindItem.bind((0, _assertThisInitialized2.default)((0, _assertThisInitialized2.default)(_this))), unbindItem: _this.unbindItem.bind((0, _assertThisInitialized2.default)((0, _assertThisInitialized2.default)(_this))) }; _this.items = {}; _this.itemsOpen = {}; _this.itemsInPath = {}; return _this; } var _proto = Root.prototype; _proto.componentDidMount = function componentDidMount() { _Component.prototype.componentDidMount.call(this); this.updateState(); }; _proto.componentDidUpdate = function componentDidUpdate() { this.updateState(); }; _proto.componentWillUnmount = function componentWillUnmount() { this.container.removeEventListener('wheel', this.handleWheel); _Component.prototype.componentWillUnmount.call(this); }; _proto.getOpenKeys = function getOpenKeys() { var _this$props = this.props, openKeys = _this$props.openKeys, defaultOpenKeys = _this$props.defaultOpenKeys; if (openKeys) return openKeys; return this.hasToggled ? Array.from(this.state.openKeys.keys()) : defaultOpenKeys; }; _proto.bindRootElement = function bindRootElement(el) { this.container = el; if (!el) return; this.wrapper = el.querySelector("." + (0, _styles.menuClass)('wrapper')); this.rootElement = el.querySelector("." + (0, _styles.menuClass)('root')); }; _proto.bindItem = function bindItem(id, updateActive, updateOpen, updateInPath) { this.items[id] = updateActive; this.itemsOpen[id] = updateOpen; this.itemsInPath[id] = updateInPath; return [this.checkActive, this.checkOpen, this.checkInPath]; }; _proto.unbindItem = function unbindItem(id) { delete this.items[id]; delete this.itemsOpen[id]; delete this.itemsInPath[id]; }; _proto.checkActive = function checkActive(id, data) { var active = this.props.active; var act = typeof active === 'function' ? active(data) : id === this.state.activeKey; // @ts-ignore 历史原因,待优化 if (act) this.state.activeKey = id; if (!act && this.state.activeKey === id) { // @ts-ignore 历史原因,待优化 this.state.activeKey = ''; } return act; }; _proto.checkOpen = function checkOpen(id) { var openKeys = this.getOpenKeys(); if ((0, _is.isArray)(openKeys)) { return openKeys.indexOf(id) > -1; } return false; }; _proto.checkInPath = function checkInPath(id) { var activeKey = this.state.activeKey; if (!activeKey || !id) return false; return activeKey.indexOf(id) >= 0; }; _proto.updateState = function updateState() { var mode = this.props.mode; this.updateActive(); this.updateOpen(); this.updateInPath(); if (!this.container) return; var bindMethod = mode !== 'inline' ? this.container.addEventListener : this.container.removeEventListener; bindMethod.call(this.container, 'wheel', this.handleWheel, { passive: false }); }; _proto.updateActive = function updateActive() { var _this2 = this; Object.keys(this.items).forEach(function (id) { var update = _this2.items[id]; update(_this2.checkActive, _this2.state.activeKey); }); }; _proto.updateOpen = function updateOpen() { var _this3 = this; var _this$props2 = this.props, data = _this$props2.data, keygen = _this$props2.keygen; Object.keys(this.itemsOpen).forEach(function (id) { var update = _this3.itemsOpen[id]; update(_this3.checkOpen); }); var hasOpen = this.getOpenKeys().filter(function (k) { return data.find(function (d, i) { return (0, _uid.getKey)(d, keygen, i) === k; }); }).length > 0; if (hasOpen !== this.state.hasOpen) { this.setState({ hasOpen: hasOpen }); } }; _proto.updateInPath = function updateInPath() { var _this4 = this; Object.keys(this.itemsInPath).forEach(function (id) { var update = _this4.itemsInPath[id]; update(_this4.checkInPath); }); }; _proto.toggleOpenKeys = function toggleOpenKeys(id, open) { var newOpenKeys = (0, _immer.default)(keyToMap(this.getOpenKeys()), function (draft) { if (open) { draft.set(id, true); } else draft.delete(id); }); this.hasToggled = true; var keys = Array.from(newOpenKeys.keys()); var _this$props3 = this.props, _this$props3$onOpenCh = _this$props3.onOpenChange, onOpenChange = _this$props3$onOpenCh === void 0 ? function () {} : _this$props3$onOpenCh, openKeys = _this$props3.openKeys; if (openKeys) { onOpenChange(keys); return; } this.setState({ openKeys: newOpenKeys, hasOpen: keys.length > 0 }); onOpenChange(keys); }; _proto.handleScrollX = function handleScrollX(pos, param) { var _this$setState; var sizeKey = pos === 'Top' ? 'height' : 'width'; var size = this.container.getBoundingClientRect()[sizeKey]; var scroll = this.rootElement.getBoundingClientRect()[sizeKey]; this.wrapper["scroll" + pos] = param * (scroll - size); this.setState((_this$setState = {}, _this$setState["scroll" + pos] = param, _this$setState)); }; _proto.handleScroll = function handleScroll(top) { var _this$container$getBo = this.container.getBoundingClientRect(), height = _this$container$getBo.height; var scrollHeight = this.rootElement.getBoundingClientRect().height; this.wrapper.scrollTop = top * (scrollHeight - height); this.setState({ scrollTop: top }); }; _proto.handleWheel = function handleWheel(e) { var _this$setState2; // if (isSubMenu(e.target)) return var mode = this.props.mode; var _getOption = getOption(mode), key = _getOption.key, pos = _getOption.pos, direction = _getOption.direction; var wheel = (0, _normalizeWheel.default)(e); var size = this.container.getBoundingClientRect()[key]; // const size = this.rootElement.getBoundingClientRect()[key] - this.container.getBoundingClientRect()[key] this.wrapper["scroll" + pos] += wheel["pixel" + direction]; var precent = this.wrapper["scroll" + pos] / size; this.setState((_this$setState2 = {}, _this$setState2["scroll" + pos] = precent > 1 ? 1 : precent, _this$setState2)); // this.setState({ [`scroll${pos}`]: size === 0 ? 0 : this.wrapper[`scroll${pos}`] / size }) e.preventDefault(); }; _proto.handleClick = function handleClick(id, data) { var onClick = this.props.onClick; this.setState({ activeKey: id }); if (onClick) onClick(data); }; _proto.renderItem = function renderItem(data, index) { var renderItem = this.props.renderItem; if (typeof renderItem === 'string') return data[renderItem]; if (typeof renderItem === 'function') return renderItem(data, index); return null; }; _proto.renderScrollBar = function renderScrollBar() { if (!this.rootElement || !this.container) return null; var mode = this.props.mode; var direction = modeDirection[mode]; if (!direction) return null; if (direction === 'x') { var _this$container$getBo2 = this.container.getBoundingClientRect(), width = _this$container$getBo2.width; var scrollWidth = this.rootElement.getBoundingClientRect().width; if (scrollWidth <= width) return null; return _react.default.createElement(_Bar.default, { className: (0, _styles.menuClass)('bar'), length: width, scrollLength: scrollWidth, offset: this.state.scrollLeft, onScroll: this.handleScrollLeft, direction: "x" }); } var length = this.container.getBoundingClientRect().height; var scrollHeight = this.rootElement.getBoundingClientRect().height; if (scrollHeight < length) return null; return _react.default.createElement(_Bar.default, { className: (0, _styles.menuClass)('bar'), forceHeight: length, length: length, scrollLength: scrollHeight, offset: this.state.scrollTop, onScroll: this.handleScrollTop }); }; _proto.render = function render() { var _this$props4 = this.props, _this$props4$data = _this$props4.data, data = _this$props4$data === void 0 ? DefaultProps.data : _this$props4$data, mode = _this$props4.mode, style = _this$props4.style, theme = _this$props4.theme, height = _this$props4.height, keygen = _this$props4.keygen, linkKey = _this$props4.linkKey, disabled = _this$props4.disabled, caretColor = _this$props4.caretColor, frontCaret = _this$props4.frontCaret, inlineIndent = _this$props4.inlineIndent, looseChildren = _this$props4.looseChildren, frontCaretType = _this$props4.frontCaretType, toggleDuration = _this$props4.toggleDuration, parentSelectable = _this$props4.parentSelectable; var isVertical = mode.indexOf('vertical') === 0; var showScroll = (style && style.height || height) && isVertical || mode === 'horizontal'; var rtl = (0, _config.isRTL)(); var className = (0, _classnames.default)((0, _styles.menuClass)('_', isVertical ? 'vertical' : mode, theme === 'dark' && 'dark', showScroll && 'scroll', this.state.hasOpen && 'has-open', rtl && 'rtl'), this.props.className); var rootStyle = {}; if (style && style.width && mode !== 'horizontal') rootStyle.width = style.width; var bottomLine = 0; var topLine = 0; if (this.container) { var rect = this.container.getBoundingClientRect(); bottomLine = rect.bottom; topLine = rect.top; } var outStyle = (0, _objectSpread2.default)({}, style); if (height !== undefined) outStyle.height = height; return _react.default.createElement("div", { className: className, ref: this.bindRootElement, style: outStyle }, _react.default.createElement("div", { className: (0, _styles.menuClass)('wrapper') }, _react.default.createElement(_context.Provider, { value: this.providerValue }, _react.default.createElement(_List.default, { path: "", level: 0, mode: mode, data: data, keygen: keygen, style: rootStyle, topLine: topLine, linkKey: linkKey, disabled: disabled, frontCaret: frontCaret, bottomLine: bottomLine, caretColor: caretColor, onClick: this.handleClick, inlineIndent: inlineIndent, renderItem: this.renderItem, className: (0, _styles.menuClass)('root'), looseChildren: looseChildren, frontCaretType: frontCaretType, toggleDuration: toggleDuration, parentSelectable: parentSelectable, toggleOpenKeys: this.toggleOpenKeys }))), showScroll && this.renderScrollBar()); }; return Root; }(_component.Component); (0, _defineProperty2.default)(Root, "defaultProps", DefaultProps); (0, _defineProperty2.default)(Root, "displayName", void 0); var _default = Root; exports.default = _default;