UNPKG

@douyinfe/semi-ui

Version:

A modern, comprehensive, flexible design system and UI library. Connect DesignOps & DevOps. Quickly build beautiful React apps. Maintained by Douyin-fe team.

274 lines (273 loc) 11.7 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _times2 = _interopRequireDefault(require("lodash/times")); var _noop2 = _interopRequireDefault(require("lodash/noop")); var _baseComponent = _interopRequireDefault(require("../_base/baseComponent")); var _react = _interopRequireDefault(require("react")); var _propTypes = _interopRequireDefault(require("prop-types")); var _classnames = _interopRequireDefault(require("classnames")); var _isNullOrUndefined = _interopRequireDefault(require("@douyinfe/semi-foundation/lib/cjs/utils/isNullOrUndefined")); var _utils = require("../_utils"); var _itemFoundation = _interopRequireDefault(require("@douyinfe/semi-foundation/lib/cjs/navigation/itemFoundation")); var _constants = require("@douyinfe/semi-foundation/lib/cjs/navigation/constants"); var _tooltip = _interopRequireDefault(require("../tooltip")); var _navContext = _interopRequireDefault(require("./nav-context")); var _dropdown = _interopRequireDefault(require("../dropdown")); function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; } const clsPrefix = `${_constants.cssClasses.PREFIX}-item`; class NavItem extends _baseComponent.default { constructor(props) { super(props); this.setItemRef = ref => { // console.log('Item - setItemRef()', ref); this.props.forwardRef && this.props.forwardRef(ref); }; this.wrapTooltip = node => { const { text, tooltipHideDelay, tooltipShowDelay } = this.props; const hideDelay = tooltipHideDelay !== null && tooltipHideDelay !== void 0 ? tooltipHideDelay : this.context.tooltipHideDelay; const showDelay = tooltipShowDelay !== null && tooltipShowDelay !== void 0 ? tooltipShowDelay : this.context.tooltipShowDelay; return /*#__PURE__*/_react.default.createElement(_tooltip.default, { content: text, wrapWhenSpecial: false, position: "right", trigger: 'hover', mouseEnterDelay: showDelay, mouseLeaveDelay: hideDelay }, node); }; this.handleClick = e => this.foundation.handleClick(e); this.handleKeyPress = e => this.foundation.handleKeyPress(e); this.state = { tooltipShow: false }; this.foundation = new _itemFoundation.default(this.adapter); } _invokeContextFunc(funcName) { if (funcName && this.context && typeof this.context[funcName] === 'function') { for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { args[_key - 1] = arguments[_key]; } return this.context[funcName](...args); } return null; } get adapter() { var _this = this; return Object.assign(Object.assign({}, super.adapter), { cloneDeep: _utils.cloneDeep, updateTooltipShow: tooltipShow => this.setState({ tooltipShow }), updateSelected: _selected => this._invokeContextFunc('updateSelectedKeys', [this.props.itemKey]), updateGlobalSelectedKeys: keys => this._invokeContextFunc('updateSelectedKeys', [...keys]), getSelectedKeys: () => this.context && this.context.selectedKeys, getSelectedKeysIsControlled: () => this.context && this.context.selectedKeysIsControlled, notifyGlobalOnSelect: function () { for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) { args[_key2] = arguments[_key2]; } return _this._invokeContextFunc('onSelect', ...args); }, notifyGlobalOnClick: function () { for (var _len3 = arguments.length, args = new Array(_len3), _key3 = 0; _key3 < _len3; _key3++) { args[_key3] = arguments[_key3]; } return _this._invokeContextFunc('onClick', ...args); }, notifyClick: function () { return _this.props.onClick(...arguments); }, notifyMouseEnter: function () { return _this.props.onMouseEnter(...arguments); }, notifyMouseLeave: function () { return _this.props.onMouseLeave(...arguments); }, getIsCollapsed: () => this.props.isCollapsed || Boolean(this.context && this.context.isCollapsed) || false, getSelected: () => Boolean(this.context && this.context.selectedKeys && this.context.selectedKeys.includes(this.props.itemKey)), getIsOpen: () => Boolean(this.context && this.context.openKeys && this.context.openKeys.includes(this.props.itemKey)) }); } renderIcon(icon, pos) { let isToggleIcon = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false; let key = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 0; if (this.props.isSubNav) { return null; } if (!icon && this.context.mode === _constants.strings.MODE_HORIZONTAL) { return null; } let iconSize = 'large'; if (pos === _constants.strings.ICON_POS_RIGHT) { iconSize = 'default'; } const className = (0, _classnames.default)(`${clsPrefix}-icon`, { [`${clsPrefix}-icon-toggle-${this.context.toggleIconPosition}`]: isToggleIcon, [`${clsPrefix}-icon-info`]: !isToggleIcon }); return /*#__PURE__*/_react.default.createElement("i", { className: className, key: key }, (0, _utils.isSemiIcon)(icon) ? /*#__PURE__*/_react.default.cloneElement(icon, { size: icon.props.size || iconSize }) : icon); } render() { var _a; const { text, icon, toggleIcon, className, isSubNav, style, indent, onMouseEnter, onMouseLeave, link, linkOptions, disabled, level = 0, tabIndex } = this.props; const { mode, isInSubNav, prefixCls, limitIndent } = this.context; const isCollapsed = this.adapter.getIsCollapsed(); const selected = this.adapter.getSelected(); let itemChildren = null; // Children is not a recommended usage and may cause some bug-like performance, but some users have already used it, so here we only delete the ts definition instead of deleting the actual code // children 并不是我们推荐的用法,可能会导致一些像 bug的表现,但是有些用户已经用了,所以此处仅作删除 ts 定义而非删除实际代码的操作 // refer https://github.com/DouyinFE/semi-design/issues/2710 // @ts-ignore const children = (_a = this.props) === null || _a === void 0 ? void 0 : _a.children; if (!(0, _isNullOrUndefined.default)(children)) { itemChildren = children; } else { let placeholderIcons = null; if (mode === _constants.strings.MODE_VERTICAL && !limitIndent && !isCollapsed) { const iconAmount = icon && !indent ? level : level - 1; placeholderIcons = (0, _times2.default)(iconAmount, index => this.renderIcon(null, _constants.strings.ICON_POS_RIGHT, false, index)); } itemChildren = /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, placeholderIcons, this.context.toggleIconPosition === _constants.strings.TOGGLE_ICON_LEFT && this.renderIcon(toggleIcon, _constants.strings.ICON_POS_RIGHT, true, 'key-toggle-pos-right'), icon || indent || isInSubNav ? this.renderIcon(icon, _constants.strings.ICON_POS_LEFT, false, 'key-position-left') : null, !(0, _isNullOrUndefined.default)(text) ? /*#__PURE__*/_react.default.createElement("span", { className: `${_constants.cssClasses.PREFIX}-item-text` }, text) : '', this.context.toggleIconPosition === _constants.strings.TOGGLE_ICON_RIGHT && this.renderIcon(toggleIcon, _constants.strings.ICON_POS_RIGHT, true, 'key-toggle-pos-right')); } if (typeof link === 'string') { itemChildren = /*#__PURE__*/_react.default.createElement("a", Object.assign({ className: `${prefixCls}-item-link`, href: link, tabIndex: -1 }, linkOptions), itemChildren); } let itemDom = ''; if (isInSubNav && (isCollapsed || mode === _constants.strings.MODE_HORIZONTAL)) { const popoverItemCls = (0, _classnames.default)({ [clsPrefix]: true, [`${clsPrefix}-sub`]: isSubNav, [`${clsPrefix}-selected`]: selected, [`${clsPrefix}-collapsed`]: isCollapsed, [`${clsPrefix}-disabled`]: disabled }); itemDom = /*#__PURE__*/_react.default.createElement(_dropdown.default.Item, { selected: selected, active: selected, forwardRef: this.setItemRef, className: popoverItemCls, onClick: this.handleClick, onMouseEnter: onMouseEnter, onMouseLeave: onMouseLeave, disabled: disabled, onKeyDown: this.handleKeyPress }, itemChildren); } else { // Items are divided into normal and sub-wrap const popoverItemCls = (0, _classnames.default)(`${className || `${clsPrefix}-normal`}`, { [clsPrefix]: true, [`${clsPrefix}-sub`]: isSubNav, [`${clsPrefix}-selected`]: selected && !isSubNav, [`${clsPrefix}-collapsed`]: isCollapsed, [`${clsPrefix}-disabled`]: disabled, [`${clsPrefix}-has-link`]: typeof link === 'string' }); const ariaProps = { 'aria-disabled': disabled }; if (isSubNav) { const isOpen = this.adapter.getIsOpen(); ariaProps['aria-expanded'] = isOpen; } itemDom = /*#__PURE__*/ // eslint-disable-next-line jsx-a11y/no-noninteractive-element-interactions _react.default.createElement("li", Object.assign({ // if role = menuitem, the narration will read all expanded li role: isSubNav ? null : "menuitem", tabIndex: isSubNav ? -1 : tabIndex }, ariaProps, { style: style, ref: this.setItemRef, className: popoverItemCls, onClick: this.handleClick, onMouseEnter: onMouseEnter, onMouseLeave: onMouseLeave, onKeyPress: this.handleKeyPress }, this.getDataAttr(this.props)), itemChildren); } // Display Tooltip when disabled and SubNav if (isCollapsed && !isInSubNav && !isSubNav || isCollapsed && isSubNav && disabled) { itemDom = this.wrapTooltip(itemDom); } if (typeof this.context.renderWrapper === 'function') { return this.context.renderWrapper({ itemElement: itemDom, isSubNav: isSubNav, isInSubNav: isInSubNav, props: this.props }); } return itemDom; } } exports.default = NavItem; NavItem.contextType = _navContext.default; NavItem.propTypes = { text: _propTypes.default.oneOfType([_propTypes.default.string, _propTypes.default.node]), itemKey: _propTypes.default.oneOfType([_propTypes.default.string, _propTypes.default.number]), onClick: _propTypes.default.func, onMouseEnter: _propTypes.default.func, onMouseLeave: _propTypes.default.func, icon: _propTypes.default.oneOfType([_propTypes.default.node]), className: _propTypes.default.string, toggleIcon: _propTypes.default.string, style: _propTypes.default.object, forwardRef: _propTypes.default.func, indent: _propTypes.default.oneOfType([_propTypes.default.bool, _propTypes.default.number]), isCollapsed: _propTypes.default.bool, isSubNav: _propTypes.default.bool, link: _propTypes.default.string, linkOptions: _propTypes.default.object, disabled: _propTypes.default.bool, tabIndex: _propTypes.default.number }; NavItem.defaultProps = { isSubNav: false, indent: false, forwardRef: _noop2.default, isCollapsed: false, onClick: _noop2.default, onMouseEnter: _noop2.default, onMouseLeave: _noop2.default, disabled: false, tabIndex: 0 };