UNPKG

@ant-design/pro-layout

Version:
473 lines (463 loc) 23.4 kB
"use strict"; var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard").default; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default; Object.defineProperty(exports, "__esModule", { value: true }); exports.BaseMenu = void 0; var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray")); var _objectSpread2 = _interopRequireDefault(require("@babel/runtime/helpers/objectSpread2")); var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass")); var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck")); var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray")); var _icons = require("@ant-design/icons"); var _proProvider = require("@ant-design/pro-provider"); var _proUtils = require("@ant-design/pro-utils"); var _antd = require("antd"); var _classnames = _interopRequireDefault(require("classnames")); var _react = _interopRequireWildcard(require("react")); var _defaultSettings = require("../../defaultSettings"); var _utils = require("../../utils/utils"); var _menu = require("./style/menu"); var _jsxRuntime = require("react/jsx-runtime"); // todo var MenuItemTooltip = function MenuItemTooltip(props) { var _useState = (0, _react.useState)(props.collapsed), _useState2 = (0, _slicedToArray2.default)(_useState, 2), collapsed = _useState2[0], setCollapsed = _useState2[1]; var _useState3 = (0, _react.useState)(false), _useState4 = (0, _slicedToArray2.default)(_useState3, 2), open = _useState4[0], setOpen = _useState4[1]; (0, _react.useEffect)(function () { setOpen(false); setTimeout(function () { setCollapsed(props.collapsed); }, 400); }, [props.collapsed]); if (props.disable) { return props.children; } return /*#__PURE__*/(0, _jsxRuntime.jsx)(_antd.Tooltip, { title: props.title, open: collapsed && props.collapsed ? open : false, placement: "right", onOpenChange: setOpen, children: props.children }); }; var IconFont = (0, _icons.createFromIconfontCN)({ scriptUrl: _defaultSettings.defaultSettings.iconfontUrl }); // Allow menu.js config icon as string or ReactNode // icon: 'setting', // icon: 'icon-geren' #For Iconfont , // icon: 'http://demo.com/icon.png', // icon: '/favicon.png', // icon: <Icon type="setting" />, var getIcon = function getIcon(icon) { var iconPrefixes = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'icon-'; var className = arguments.length > 2 ? arguments[2] : undefined; if (typeof icon === 'string' && icon !== '') { if ((0, _proUtils.isUrl)(icon) || (0, _proUtils.isImg)(icon)) { return /*#__PURE__*/(0, _jsxRuntime.jsx)("img", { width: 16, src: icon, alt: "icon", className: className }, icon); } if (icon.startsWith(iconPrefixes)) { return /*#__PURE__*/(0, _jsxRuntime.jsx)(IconFont, { type: icon }); } } return icon; }; var getMenuTitleSymbol = function getMenuTitleSymbol(title) { if (title && typeof title === 'string') { var symbol = title.substring(0, 1).toUpperCase(); return symbol; } return null; }; var MenuUtil = /*#__PURE__*/(0, _createClass2.default)(function MenuUtil(props) { var _this = this; (0, _classCallCheck2.default)(this, MenuUtil); (0, _defineProperty2.default)(this, "props", void 0); (0, _defineProperty2.default)(this, "getNavMenuItems", function () { var menusData = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : []; var level = arguments.length > 1 ? arguments[1] : undefined; var noGroupLevel = arguments.length > 2 ? arguments[2] : undefined; return menusData.map(function (item) { return _this.getSubMenuOrItem(item, level, noGroupLevel); }).filter(function (item) { return item; }).flat(1); }); /** Get SubMenu or Item */ (0, _defineProperty2.default)(this, "getSubMenuOrItem", function (item, level, noGroupLevel) { var _this$props = _this.props, subMenuItemRender = _this$props.subMenuItemRender, baseClassName = _this$props.baseClassName, prefixCls = _this$props.prefixCls, collapsed = _this$props.collapsed, menu = _this$props.menu, iconPrefixes = _this$props.iconPrefixes, layout = _this$props.layout; var isGroup = (menu === null || menu === void 0 ? void 0 : menu.type) === 'group' && layout !== 'top'; var designToken = _this.props.token; var name = _this.getIntlName(item); var children = (item === null || item === void 0 ? void 0 : item.children) || (item === null || item === void 0 ? void 0 : item.routes); var menuType = isGroup && level === 0 ? 'group' : undefined; if (Array.isArray(children) && children.length > 0) { var _this$props2, _this$props3, _this$props4, _this$props5, _designToken$layout; /** Menu 第一级可以有icon,或者 isGroup 时第二级别也要有 */ var shouldHasIcon = level === 0 || isGroup && level === 1; // get defaultTitle by menuItemRender var iconDom = getIcon(item.icon, iconPrefixes, "".concat(baseClassName, "-icon ").concat((_this$props2 = _this.props) === null || _this$props2 === void 0 ? void 0 : _this$props2.hashId)); /** * 如果没有icon在收起的时候用首字母代替 */ var defaultIcon = collapsed && shouldHasIcon ? getMenuTitleSymbol(name) : null; var defaultTitle = /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", { className: (0, _classnames.default)("".concat(baseClassName, "-item-title"), (_this$props3 = _this.props) === null || _this$props3 === void 0 ? void 0 : _this$props3.hashId, (0, _defineProperty2.default)((0, _defineProperty2.default)((0, _defineProperty2.default)((0, _defineProperty2.default)({}, "".concat(baseClassName, "-item-title-collapsed"), collapsed), "".concat(baseClassName, "-item-title-collapsed-level-").concat(noGroupLevel), collapsed), "".concat(baseClassName, "-group-item-title"), menuType === 'group'), "".concat(baseClassName, "-item-collapsed-show-title"), (menu === null || menu === void 0 ? void 0 : menu.collapsedShowTitle) && collapsed)), children: [menuType === 'group' && collapsed ? null : shouldHasIcon && iconDom ? /*#__PURE__*/(0, _jsxRuntime.jsx)("span", { className: "".concat(baseClassName, "-item-icon ").concat((_this$props4 = _this.props) === null || _this$props4 === void 0 ? void 0 : _this$props4.hashId).trim(), children: iconDom }) : defaultIcon, /*#__PURE__*/(0, _jsxRuntime.jsx)("span", { className: (0, _classnames.default)("".concat(baseClassName, "-item-text"), (_this$props5 = _this.props) === null || _this$props5 === void 0 ? void 0 : _this$props5.hashId, (0, _defineProperty2.default)({}, "".concat(baseClassName, "-item-text-has-icon"), menuType !== 'group' && shouldHasIcon && (iconDom || defaultIcon))), children: name })] }); // subMenu only title render var title = subMenuItemRender ? subMenuItemRender((0, _objectSpread2.default)((0, _objectSpread2.default)({}, item), {}, { isUrl: false }), defaultTitle, _this.props) : defaultTitle; // 如果收起来,没有子菜单了,就不需要展示 group,所以 level 不增加 if (isGroup && level === 0 && _this.props.collapsed && !menu.collapsedShowGroupTitle) { return _this.getNavMenuItems(children, level + 1, level); } var childrenList = _this.getNavMenuItems(children, level + 1, isGroup && level === 0 && _this.props.collapsed ? level : level + 1); return [{ type: menuType, key: item.key || item.path, label: title, onClick: isGroup ? undefined : item.onTitleClick, children: childrenList, className: (0, _classnames.default)((0, _defineProperty2.default)((0, _defineProperty2.default)((0, _defineProperty2.default)({}, "".concat(baseClassName, "-group"), menuType === 'group'), "".concat(baseClassName, "-submenu"), menuType !== 'group'), "".concat(baseClassName, "-submenu-has-icon"), menuType !== 'group' && shouldHasIcon && iconDom)) }, isGroup && level === 0 ? { type: 'divider', prefixCls: prefixCls, className: "".concat(baseClassName, "-divider"), key: (item.key || item.path) + '-group-divider', style: { padding: 0, borderBlockEnd: 0, margin: _this.props.collapsed ? '4px' : '6px 16px', marginBlockStart: _this.props.collapsed ? 4 : 8, borderColor: designToken === null || designToken === void 0 || (_designToken$layout = designToken.layout) === null || _designToken$layout === void 0 || (_designToken$layout = _designToken$layout.sider) === null || _designToken$layout === void 0 ? void 0 : _designToken$layout.colorMenuItemDivider } } : undefined].filter(Boolean); } return { className: "".concat(baseClassName, "-menu-item"), disabled: item.disabled, key: item.key || item.path, onClick: item.onTitleClick, // eslint-disable-next-line react/no-is-mounted label: _this.getMenuItemPath(item, level, noGroupLevel) }; }); (0, _defineProperty2.default)(this, "getIntlName", function (item) { var name = item.name, locale = item.locale; var _this$props6 = _this.props, menu = _this$props6.menu, formatMessage = _this$props6.formatMessage; var finalName = name; if (locale && (menu === null || menu === void 0 ? void 0 : menu.locale) !== false) { finalName = formatMessage === null || formatMessage === void 0 ? void 0 : formatMessage({ id: locale, defaultMessage: name }); } if (_this.props.menuTextRender) { return _this.props.menuTextRender(item, finalName, _this.props); } return finalName; }); /** * 判断是否是http链接.返回 Link 或 a Judge whether it is http link.return a or Link * * @memberof SiderMenu */ (0, _defineProperty2.default)(this, "getMenuItemPath", function (item, level, noGroupLevel) { var _this$props9, _this$props10, _this$props11, _this$props12; var itemPath = _this.conversionPath(item.path || '/'); var _this$props7 = _this.props, _this$props7$location = _this$props7.location, location = _this$props7$location === void 0 ? { pathname: '/' } : _this$props7$location, isMobile = _this$props7.isMobile, onCollapse = _this$props7.onCollapse, menuItemRender = _this$props7.menuItemRender, iconPrefixes = _this$props7.iconPrefixes; // if local is true formatMessage all name。 var menuItemTitle = _this.getIntlName(item); var _this$props8 = _this.props, baseClassName = _this$props8.baseClassName, menu = _this$props8.menu, collapsed = _this$props8.collapsed; var isGroup = (menu === null || menu === void 0 ? void 0 : menu.type) === 'group'; /** Menu 第一级可以有icon,或者 isGroup 时第二级别也要有 */ var hasIcon = level === 0 || isGroup && level === 1; var icon = !hasIcon ? null : getIcon(item.icon, iconPrefixes, "".concat(baseClassName, "-icon ").concat((_this$props9 = _this.props) === null || _this$props9 === void 0 ? void 0 : _this$props9.hashId)); // 如果没有 icon 在收起的时候用首字母代替 var defaultIcon = collapsed && hasIcon ? getMenuTitleSymbol(menuItemTitle) : null; var defaultItem = /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", { className: (0, _classnames.default)("".concat(baseClassName, "-item-title"), (_this$props10 = _this.props) === null || _this$props10 === void 0 ? void 0 : _this$props10.hashId, (0, _defineProperty2.default)((0, _defineProperty2.default)((0, _defineProperty2.default)({}, "".concat(baseClassName, "-item-title-collapsed"), collapsed), "".concat(baseClassName, "-item-title-collapsed-level-").concat(noGroupLevel), collapsed), "".concat(baseClassName, "-item-collapsed-show-title"), (menu === null || menu === void 0 ? void 0 : menu.collapsedShowTitle) && collapsed)), children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("span", { className: "".concat(baseClassName, "-item-icon ").concat((_this$props11 = _this.props) === null || _this$props11 === void 0 ? void 0 : _this$props11.hashId).trim(), style: { display: defaultIcon === null && !icon ? 'none' : '' }, children: icon || /*#__PURE__*/(0, _jsxRuntime.jsx)("span", { className: "anticon", children: defaultIcon }) }), /*#__PURE__*/(0, _jsxRuntime.jsx)("span", { className: (0, _classnames.default)("".concat(baseClassName, "-item-text"), (_this$props12 = _this.props) === null || _this$props12 === void 0 ? void 0 : _this$props12.hashId, (0, _defineProperty2.default)({}, "".concat(baseClassName, "-item-text-has-icon"), hasIcon && (icon || defaultIcon))), children: menuItemTitle })] }, itemPath); var isHttpUrl = (0, _proUtils.isUrl)(itemPath); // Is it a http link if (isHttpUrl) { var _this$props13, _this$props14, _this$props15; defaultItem = /*#__PURE__*/(0, _jsxRuntime.jsxs)("span", { onClick: function onClick() { var _window, _window$open; (_window = window) === null || _window === void 0 || (_window$open = _window.open) === null || _window$open === void 0 || _window$open.call(_window, itemPath, '_blank'); }, className: (0, _classnames.default)("".concat(baseClassName, "-item-title"), (_this$props13 = _this.props) === null || _this$props13 === void 0 ? void 0 : _this$props13.hashId, (0, _defineProperty2.default)((0, _defineProperty2.default)((0, _defineProperty2.default)((0, _defineProperty2.default)({}, "".concat(baseClassName, "-item-title-collapsed"), collapsed), "".concat(baseClassName, "-item-title-collapsed-level-").concat(noGroupLevel), collapsed), "".concat(baseClassName, "-item-link"), true), "".concat(baseClassName, "-item-collapsed-show-title"), (menu === null || menu === void 0 ? void 0 : menu.collapsedShowTitle) && collapsed)), children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("span", { className: "".concat(baseClassName, "-item-icon ").concat((_this$props14 = _this.props) === null || _this$props14 === void 0 ? void 0 : _this$props14.hashId).trim(), style: { display: defaultIcon === null && !icon ? 'none' : '' }, children: icon || /*#__PURE__*/(0, _jsxRuntime.jsx)("span", { className: "anticon", children: defaultIcon }) }), /*#__PURE__*/(0, _jsxRuntime.jsx)("span", { className: (0, _classnames.default)("".concat(baseClassName, "-item-text"), (_this$props15 = _this.props) === null || _this$props15 === void 0 ? void 0 : _this$props15.hashId, (0, _defineProperty2.default)({}, "".concat(baseClassName, "-item-text-has-icon"), hasIcon && (icon || defaultIcon))), children: menuItemTitle })] }, itemPath); } if (menuItemRender) { var renderItemProps = (0, _objectSpread2.default)((0, _objectSpread2.default)({}, item), {}, { isUrl: isHttpUrl, itemPath: itemPath, isMobile: isMobile, replace: itemPath === location.pathname, onClick: function onClick() { return onCollapse && onCollapse(true); }, children: undefined }); return level === 0 ? /*#__PURE__*/(0, _jsxRuntime.jsx)(MenuItemTooltip, { collapsed: collapsed, title: menuItemTitle, disable: item.disabledTooltip, children: menuItemRender(renderItemProps, defaultItem, _this.props) }) : menuItemRender(renderItemProps, defaultItem, _this.props); } return level === 0 ? /*#__PURE__*/(0, _jsxRuntime.jsx)(MenuItemTooltip, { collapsed: collapsed, title: menuItemTitle, disable: item.disabledTooltip, children: defaultItem }) : defaultItem; }); (0, _defineProperty2.default)(this, "conversionPath", function (path) { if (path && path.indexOf('http') === 0) { return path; } return "/".concat(path || '').replace(/\/+/g, '/'); }); this.props = props; }); /** * 生成openKeys 的对象,因为设置了openKeys 就会变成受控,所以需要一个空对象 * * @param BaseMenuProps */ var getOpenKeysProps = function getOpenKeysProps(openKeys, _ref) { var layout = _ref.layout, collapsed = _ref.collapsed; var openKeysProps = {}; if (openKeys && !collapsed && ['side', 'mix'].includes(layout || 'mix')) { openKeysProps = { openKeys: openKeys }; } return openKeysProps; }; var BaseMenu = exports.BaseMenu = function BaseMenu(props) { var mode = props.mode, className = props.className, handleOpenChange = props.handleOpenChange, style = props.style, menuData = props.menuData, prefixCls = props.prefixCls, menu = props.menu, matchMenuKeys = props.matchMenuKeys, iconfontUrl = props.iconfontUrl, propsSelectedKeys = props.selectedKeys, onSelect = props.onSelect, menuRenderType = props.menuRenderType, propsOpenKeys = props.openKeys; var _useContext = (0, _react.useContext)(_proProvider.ProProvider), dark = _useContext.dark, designToken = _useContext.token; var baseClassName = "".concat(prefixCls, "-base-menu-").concat(mode); // 用于减少 defaultOpenKeys 计算的组件 var defaultOpenKeysRef = (0, _react.useRef)([]); var _useMountMergeState = (0, _proUtils.useMountMergeState)(menu === null || menu === void 0 ? void 0 : menu.defaultOpenAll), _useMountMergeState2 = (0, _slicedToArray2.default)(_useMountMergeState, 2), defaultOpenAll = _useMountMergeState2[0], setDefaultOpenAll = _useMountMergeState2[1]; var _useMountMergeState3 = (0, _proUtils.useMountMergeState)(function () { if (menu !== null && menu !== void 0 && menu.defaultOpenAll) { return (0, _utils.getOpenKeysFromMenuData)(menuData) || []; } if (propsOpenKeys === false) { return false; } return []; }, { value: propsOpenKeys === false ? undefined : propsOpenKeys, onChange: handleOpenChange }), _useMountMergeState4 = (0, _slicedToArray2.default)(_useMountMergeState3, 2), openKeys = _useMountMergeState4[0], setOpenKeys = _useMountMergeState4[1]; var _useMountMergeState5 = (0, _proUtils.useMountMergeState)([], { value: propsSelectedKeys, onChange: onSelect ? function (keys) { if (onSelect && keys) { onSelect(keys); } } : undefined }), _useMountMergeState6 = (0, _slicedToArray2.default)(_useMountMergeState5, 2), selectedKeys = _useMountMergeState6[0], setSelectedKeys = _useMountMergeState6[1]; (0, _react.useEffect)(function () { if (menu !== null && menu !== void 0 && menu.defaultOpenAll || propsOpenKeys === false) { return; } if (matchMenuKeys) { setOpenKeys(matchMenuKeys); setSelectedKeys(matchMenuKeys); } // eslint-disable-next-line react-hooks/exhaustive-deps }, [matchMenuKeys.join('-')]); (0, _react.useEffect)(function () { // reset IconFont if (iconfontUrl) { IconFont = (0, _icons.createFromIconfontCN)({ scriptUrl: iconfontUrl }); } }, [iconfontUrl]); (0, _react.useEffect)(function () { // if pathname can't match, use the nearest parent's key if (matchMenuKeys.join('-') !== (selectedKeys || []).join('-')) { setSelectedKeys(matchMenuKeys); } if (!defaultOpenAll && propsOpenKeys !== false && matchMenuKeys.join('-') !== (openKeys || []).join('-')) { var newKeys = matchMenuKeys; // 如果不自动关闭,我需要把 openKeys 放进去 if ((menu === null || menu === void 0 ? void 0 : menu.autoClose) === false) { newKeys = Array.from(new Set([].concat((0, _toConsumableArray2.default)(matchMenuKeys), (0, _toConsumableArray2.default)(openKeys || [])))); } setOpenKeys(newKeys); } else if (menu !== null && menu !== void 0 && menu.ignoreFlatMenu && defaultOpenAll) { // 忽略用户手动折叠过的菜单状态,折叠按钮切换之后也可实现默认展开所有菜单 setOpenKeys((0, _utils.getOpenKeysFromMenuData)(menuData)); } else { setDefaultOpenAll(false); } }, // eslint-disable-next-line react-hooks/exhaustive-deps [matchMenuKeys.join('-')]); var openKeysProps = (0, _react.useMemo)(function () { return getOpenKeysProps(openKeys, props); }, // eslint-disable-next-line react-hooks/exhaustive-deps [openKeys && openKeys.join(','), props.layout, props.collapsed]); var _useStyle = (0, _menu.useStyle)(baseClassName, mode), wrapSSR = _useStyle.wrapSSR, hashId = _useStyle.hashId; var menuUtils = (0, _react.useMemo)(function () { return new MenuUtil((0, _objectSpread2.default)((0, _objectSpread2.default)({}, props), {}, { token: designToken, menuRenderType: menuRenderType, baseClassName: baseClassName, hashId: hashId })); }, [props, designToken, menuRenderType, baseClassName, hashId]); if (menu !== null && menu !== void 0 && menu.loading) { return /*#__PURE__*/(0, _jsxRuntime.jsx)("div", { style: mode !== null && mode !== void 0 && mode.includes('inline') ? { padding: 24 } : { marginBlockStart: 16 }, children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_antd.Skeleton, { active: true, title: false, paragraph: { rows: mode !== null && mode !== void 0 && mode.includes('inline') ? 6 : 1 } }) }); } // 这次 openKeys === false 的时候的情况,这种情况下帮用户选中一次 // 第二此不会使用,所以用了 defaultOpenKeys // 这里返回 null,是为了让 defaultOpenKeys 生效 if (props.openKeys === false && !props.handleOpenChange) { defaultOpenKeysRef.current = matchMenuKeys; } var finallyData = props.postMenuData ? props.postMenuData(menuData) : menuData; if (finallyData && (finallyData === null || finallyData === void 0 ? void 0 : finallyData.length) < 1) { return null; } return wrapSSR( /*#__PURE__*/(0, _react.createElement)(_antd.Menu, (0, _objectSpread2.default)((0, _objectSpread2.default)({}, openKeysProps), {}, { _internalDisableMenuItemTitleTooltip: true, key: "Menu", mode: mode, inlineIndent: 16, defaultOpenKeys: defaultOpenKeysRef.current, theme: dark ? 'dark' : 'light', selectedKeys: selectedKeys, style: (0, _objectSpread2.default)({ backgroundColor: 'transparent', border: 'none' }, style), className: (0, _classnames.default)(className, hashId, baseClassName, (0, _defineProperty2.default)((0, _defineProperty2.default)({}, "".concat(baseClassName, "-horizontal"), mode === 'horizontal'), "".concat(baseClassName, "-collapsed"), props.collapsed)), items: menuUtils.getNavMenuItems(finallyData, 0, 0), onOpenChange: function onOpenChange(_openKeys) { if (!props.collapsed) { setOpenKeys(_openKeys); } } }, props.menuProps))); };