UNPKG

@alifd/next

Version:

A configurable component library for web built on React.

204 lines (203 loc) 9.89 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var react_1 = tslib_1.__importStar(require("react")); var react_dom_1 = require("react-dom"); var prop_types_1 = tslib_1.__importDefault(require("prop-types")); var classnames_1 = tslib_1.__importDefault(require("classnames")); var animate_1 = tslib_1.__importDefault(require("../../animate")); var icon_1 = tslib_1.__importDefault(require("../../icon")); var util_1 = require("../../util"); var item_1 = tslib_1.__importDefault(require("./item")); var selectable_item_1 = tslib_1.__importDefault(require("./selectable-item")); var popup_item_1 = tslib_1.__importDefault(require("./popup-item")); var util_2 = require("./util"); var Expand = animate_1.default.Expand; var bindCtx = util_1.func.bindCtx; var SubMenu = /** @class */ (function (_super) { tslib_1.__extends(SubMenu, _super); function SubMenu(props) { var _this = _super.call(this, props) || this; bindCtx(_this, [ 'handleMouseEnter', 'handleMouseLeave', 'handleClick', 'handleOpen', 'afterLeave', ]); return _this; } SubMenu.prototype.componentDidMount = function () { this.itemNode = (0, react_dom_1.findDOMNode)(this); }; SubMenu.prototype.afterLeave = function () { var _a = this.props, focused = _a.focused, root = _a.root; var focusable = root.props.focusable; if (focusable && focused) { this.itemNode.focus(); } }; SubMenu.prototype.getOpen = function () { var _a = this.props, _key = _a._key, root = _a.root; var openKeys = root.state.openKeys; return openKeys.indexOf(_key) > -1; }; SubMenu.prototype.handleMouseEnter = function (e) { this.handleOpen(true); this.props.onMouseEnter && this.props.onMouseEnter(e); }; SubMenu.prototype.handleMouseLeave = function (e) { this.handleOpen(false); this.props.onMouseLeave && this.props.onMouseLeave(e); }; SubMenu.prototype.handleClick = function (e) { var _a = this.props, root = _a.root, selectable = _a.selectable; var selectMode = root.props.selectMode; if (selectMode && selectable) { e.stopPropagation(); } var open = this.getOpen(); this.handleOpen(!open); }; SubMenu.prototype.handleOpen = function (open, triggerType, e) { var _a = this.props, _key = _a._key, root = _a.root; root.handleOpen(_key, open, triggerType, e); }; SubMenu.prototype.passParentToChildren = function (children) { var _this = this; var _a = this.props, mode = _a.mode, root = _a.root; return react_1.Children.map(children, function (child) { // to fix https://github.com/alibaba-fusion/next/issues/952 if (typeof child !== 'function' && typeof child !== 'object') { return child; } // @ts-expect-error FIXME: 上面的类型判断不正确,应该使用 React.isValidElement,这里先注释暴露问题 return (0, react_1.cloneElement)(child, { parent: _this, parentMode: mode || root.props.mode, }); }); }; SubMenu.prototype.renderInline = function () { var _a, _b, _c, _d; var _e = this.props, _key = _e._key, level = _e.level, inlineLevel = _e.inlineLevel, root = _e.root, className = _e.className, selectableFromProps = _e.selectable, label = _e.label, children = _e.children, noIcon = _e.noIcon, subMenuContentClassName = _e.subMenuContentClassName, propsTriggerType = _e.triggerType, parentMode = _e.parentMode; var _f = root.props, prefix = _f.prefix, selectMode = _f.selectMode, rootTriggerType = _f.triggerType, inlineArrowDirection = _f.inlineArrowDirection, expandAnimation = _f.expandAnimation, rtl = _f.rtl; var triggerType = propsTriggerType || rootTriggerType; var open = this.getOpen(); var _g = root.state, selectedKeys = _g.selectedKeys, _k2n = _g._k2n; var isChildSelected = (0, util_2.getChildSelected)({ _key: _key, _k2n: _k2n, selectMode: selectMode, selectedKeys: selectedKeys, }); var others = util_1.obj.pickOthers(SubMenu.propTypes, this.props); var liProps = { className: (0, classnames_1.default)((_a = {}, _a["".concat(prefix, "menu-sub-menu-wrapper")] = true, _a), className), }; var itemProps = { 'aria-expanded': open, _key: _key, level: level, role: 'listitem', inlineLevel: inlineLevel, root: root, type: 'submenu', component: 'div', parentMode: parentMode, className: (0, classnames_1.default)((_b = {}, _b["".concat(prefix, "opened")] = open, _b["".concat(prefix, "child-selected")] = isChildSelected, _b)), }; if (typeof label === 'string') { itemProps.title = label; } var arrorProps = { type: inlineArrowDirection === 'right' ? 'arrow-right' : 'arrow-down', className: (0, classnames_1.default)((_c = {}, _c["".concat(prefix, "menu-icon-arrow")] = true, _c["".concat(prefix, "menu-icon-arrow-down")] = inlineArrowDirection === 'down', _c["".concat(prefix, "menu-icon-arrow-right")] = inlineArrowDirection === 'right', _c["".concat(prefix, "open")] = open, _c)), }; var selectable = !!selectMode && selectableFromProps; var NewItem = (selectable ? selectable_item_1.default : item_1.default); if (triggerType === 'hover') { liProps.onMouseEnter = this.handleMouseEnter; liProps.onMouseLeave = this.handleMouseLeave; } else if (selectable) { arrorProps.onClick = this.handleClick; } else { itemProps.onClick = this.handleClick; } var newSubMenuContentClassName = (0, classnames_1.default)((_d = {}, _d["".concat(prefix, "menu-sub-menu")] = true, _d), subMenuContentClassName); var roleMenu = 'menu', roleItem = 'menuitem'; if ('selectMode' in root.props) { roleMenu = 'listbox'; roleItem = 'option'; } var subMenu = open ? (react_1.default.createElement("ul", { role: roleMenu, dir: rtl ? 'rtl' : undefined, className: newSubMenuContentClassName }, this.passParentToChildren(children))) : null; return ( // @ts-expect-error others.onSelect 签名不匹配 react_1.default.createElement("li", tslib_1.__assign({ role: roleItem }, others, liProps), react_1.default.createElement(NewItem, tslib_1.__assign({}, itemProps), react_1.default.createElement("span", { className: "".concat(prefix, "menu-item-text") }, label), noIcon ? null : react_1.default.createElement(icon_1.default, tslib_1.__assign({}, arrorProps))), expandAnimation ? (react_1.default.createElement(Expand, { animationAppear: false, afterLeave: this.afterLeave }, subMenu)) : (subMenu))); }; SubMenu.prototype.renderPopup = function () { var _a; var _b = this .props, children = _b.children, subMenuContentClassName = _b.subMenuContentClassName, noIcon = _b.noIcon, others = tslib_1.__rest(_b, ["children", "subMenuContentClassName", "noIcon"]); var root = this.props.root; var _c = root.props, prefix = _c.prefix, popupClassName = _c.popupClassName, popupStyle = _c.popupStyle, rtl = _c.rtl; var newClassName = (0, classnames_1.default)((_a = {}, _a["".concat(prefix, "menu")] = true, _a["".concat(prefix, "ver")] = true, _a), popupClassName, subMenuContentClassName); // @ts-expect-error FIXME: PopupItem 并没有使用 rtl 参数,这里可以移除 others.rtl = rtl; return (react_1.default.createElement(popup_item_1.default, tslib_1.__assign({}, others, { noIcon: noIcon, hasSubMenu: true }), react_1.default.createElement("ul", { role: "menu", dir: rtl ? 'rtl' : undefined, className: newClassName, style: popupStyle }, this.passParentToChildren(children)))); }; SubMenu.prototype.render = function () { var _a = this.props, mode = _a.mode, root = _a.root; var newMode = mode || root.props.mode; return newMode === 'popup' ? this.renderPopup() : this.renderInline(); }; SubMenu.menuChildType = 'submenu'; SubMenu.propTypes = { _key: prop_types_1.default.string, root: prop_types_1.default.object, level: prop_types_1.default.number, inlineLevel: prop_types_1.default.number, groupIndent: prop_types_1.default.number, label: prop_types_1.default.node, selectable: prop_types_1.default.bool, mode: prop_types_1.default.oneOf(['inline', 'popup']), noIcon: prop_types_1.default.bool, children: prop_types_1.default.node, onMouseEnter: prop_types_1.default.func, onMouseLeave: prop_types_1.default.func, subMenuContentClassName: prop_types_1.default.string, triggerType: prop_types_1.default.oneOf(['click', 'hover']), align: prop_types_1.default.oneOf(['outside', 'follow']), parentMode: prop_types_1.default.oneOf(['inline', 'popup']), parent: prop_types_1.default.any, }; SubMenu.defaultProps = { groupIndent: 0, noIcon: false, selectable: false, }; return SubMenu; }(react_1.Component)); exports.default = SubMenu;