UNPKG

@ant-design/pro-layout

Version:
401 lines (323 loc) 14.1 kB
"use strict"; var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard"); var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; require("antd/es/menu/style"); var _menu = _interopRequireDefault(require("antd/es/menu")); var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends")); require("antd/es/skeleton/style"); var _skeleton = _interopRequireDefault(require("antd/es/skeleton")); var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray")); var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray")); var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); var _objectSpread2 = _interopRequireDefault(require("@babel/runtime/helpers/objectSpread2")); var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass")); var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck")); require("./index.less"); var _icons = _interopRequireWildcard(require("@ant-design/icons")); var _react = _interopRequireWildcard(require("react")); var _classnames = _interopRequireDefault(require("classnames")); var _proUtils = require("@ant-design/pro-utils"); var _defaultSettings = _interopRequireDefault(require("../../defaultSettings")); var _utils = require("../../utils/utils"); var _Counter = _interopRequireDefault(require("./Counter")); var IconFont = (0, _icons.createFromIconfontCN)({ scriptUrl: _defaultSettings.default.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-'; if (typeof icon === 'string' && icon !== '') { if ((0, _proUtils.isUrl)(icon) || (0, _proUtils.isImg)(icon)) { return /*#__PURE__*/_react.default.createElement(_icons.default, { component: function component() { return /*#__PURE__*/_react.default.createElement("img", { src: icon, alt: "icon", className: "ant-pro-sider-menu-icon" }); } }); } if (icon.startsWith(iconPrefixes)) { return /*#__PURE__*/_react.default.createElement(IconFont, { type: icon }); } } return icon; }; var MenuUtil = /*#__PURE__*/(0, _createClass2.default)(function MenuUtil(props) { var _this = this; (0, _classCallCheck2.default)(this, MenuUtil); this.props = void 0; this.getNavMenuItems = function () { var menusData = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : []; var isChildren = arguments.length > 1 ? arguments[1] : undefined; return menusData.map(function (item) { return _this.getSubMenuOrItem(item, isChildren); }).filter(function (item) { return item; }); }; this.getSubMenuOrItem = function (item, isChildren) { var children = (item === null || item === void 0 ? void 0 : item.children) || (item === null || item === void 0 ? void 0 : item.routes); if (Array.isArray(children) && children.length > 0) { var name = _this.getIntlName(item); var _this$props = _this.props, subMenuItemRender = _this$props.subMenuItemRender, prefixCls = _this$props.prefixCls, menu = _this$props.menu, iconPrefixes = _this$props.iconPrefixes; // get defaultTitle by menuItemRender var defaultTitle = item.icon ? /*#__PURE__*/_react.default.createElement("span", { className: "".concat(prefixCls, "-menu-item"), title: name }, !isChildren && getIcon(item.icon, iconPrefixes), /*#__PURE__*/_react.default.createElement("span", { className: "".concat(prefixCls, "-menu-item-title") }, name)) : /*#__PURE__*/_react.default.createElement("span", { className: "".concat(prefixCls, "-menu-item"), title: name }, name); // subMenu only title render var title = subMenuItemRender ? subMenuItemRender((0, _objectSpread2.default)((0, _objectSpread2.default)({}, item), {}, { isUrl: false }), defaultTitle) : defaultTitle; return { type: (menu === null || menu === void 0 ? void 0 : menu.type) === 'group' ? 'group' : undefined, label: title, children: _this.getNavMenuItems(children, true), onTitleClick: item.onTitleClick, key: item.key || item.path }; } return { label: _this.getMenuItemPath(item, isChildren), title: _this.getIntlName(item), key: item.key || item.path, disabled: item.disabled, onClick: function onClick(e) { var _item$onTitleClick; if ((0, _proUtils.isUrl)(item === null || item === void 0 ? void 0 : item.path)) { window.open(item.path); } (_item$onTitleClick = item.onTitleClick) === null || _item$onTitleClick === void 0 ? void 0 : _item$onTitleClick.call(item, e); } }; }; this.getIntlName = function (item) { var name = item.name, locale = item.locale; var _this$props2 = _this.props, menu = _this$props2.menu, formatMessage = _this$props2.formatMessage; if (locale && (menu === null || menu === void 0 ? void 0 : menu.locale) !== false) { return formatMessage === null || formatMessage === void 0 ? void 0 : formatMessage({ id: locale, defaultMessage: name }); } return name; }; this.getMenuItemPath = function (item, isChildren) { var itemPath = _this.conversionPath(item.path || '/'); var _this$props3 = _this.props, _this$props3$location = _this$props3.location, location = _this$props3$location === void 0 ? { pathname: '/' } : _this$props3$location, isMobile = _this$props3.isMobile, onCollapse = _this$props3.onCollapse, menuItemRender = _this$props3.menuItemRender, iconPrefixes = _this$props3.iconPrefixes; // if local is true formatMessage all name。 var name = _this.getIntlName(item); var prefixCls = _this.props.prefixCls; var icon = isChildren ? null : getIcon(item.icon, iconPrefixes); var isHttpUrl = (0, _proUtils.isUrl)(itemPath); var defaultItem = /*#__PURE__*/_react.default.createElement("span", { className: (0, _classnames.default)("".concat(prefixCls, "-menu-item"), (0, _defineProperty2.default)({}, "".concat(prefixCls, "-menu-item-link"), isHttpUrl)) }, icon, /*#__PURE__*/_react.default.createElement("span", { className: "".concat(prefixCls, "-menu-item-title") }, name)); if (menuItemRender) { var renderItemProps = (0, _objectSpread2.default)((0, _objectSpread2.default)({}, item), {}, { isUrl: isHttpUrl, itemPath: itemPath, isMobile: isMobile, replace: itemPath === location.pathname, onClick: function onClick() { if (isHttpUrl) window.open(itemPath); if (onCollapse) onCollapse(true); }, children: undefined }); return menuItemRender(renderItemProps, defaultItem, _this.props); } return defaultItem; }; 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 = function BaseMenu(props) { var theme = props.theme, mode = props.mode, className = props.className, handleOpenChange = props.handleOpenChange, style = props.style, menuData = props.menuData, menu = props.menu, matchMenuKeys = props.matchMenuKeys, iconfontUrl = props.iconfontUrl, collapsed = props.collapsed, propsSelectedKeys = props.selectedKeys, onSelect = props.onSelect, propsOpenKeys = props.openKeys; // 用于减少 defaultOpenKeys 计算的组件 var defaultOpenKeysRef = (0, _react.useRef)([]); var _MenuCounter$useConta = _Counter.default.useContainer(), flatMenuKeys = _MenuCounter$useConta.flatMenuKeys; 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 ? 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 ? void 0 : menu.defaultOpenAll) || propsOpenKeys === false || flatMenuKeys.length) { 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 ? void 0 : menu.ignoreFlatMenu) && defaultOpenAll) { // 忽略用户手动折叠过的菜单状态,折叠按钮切换之后也可实现默认展开所有菜单 setOpenKeys((0, _utils.getOpenKeysFromMenuData)(menuData)); } else if (flatMenuKeys.length > 0) setDefaultOpenAll(false); // eslint-disable-next-line react-hooks/exhaustive-deps }, [matchMenuKeys.join('-'), collapsed]); 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 _useState = (0, _react.useState)(function () { return new MenuUtil(props); }), _useState2 = (0, _slicedToArray2.default)(_useState, 1), menuUtils = _useState2[0]; if (menu === null || menu === void 0 ? void 0 : menu.loading) { return /*#__PURE__*/_react.default.createElement("div", { style: (mode === null || mode === void 0 ? void 0 : mode.includes('inline')) ? { padding: 24 } : { marginTop: 16 } }, /*#__PURE__*/_react.default.createElement(_skeleton.default, { active: true, title: false, paragraph: { rows: (mode === null || mode === void 0 ? void 0 : mode.includes('inline')) ? 6 : 1 } })); } var cls = (0, _classnames.default)(className, { 'top-nav-menu': mode === 'horizontal' }); // sync props menuUtils.props = props; // 这次 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 /*#__PURE__*/_react.default.createElement(_menu.default, (0, _extends2.default)({}, openKeysProps, { key: "Menu", mode: mode, items: menuUtils.getNavMenuItems(finallyData, false), inlineIndent: 16, defaultOpenKeys: defaultOpenKeysRef.current, theme: theme, selectedKeys: selectedKeys, style: style, className: cls, onOpenChange: setOpenKeys }, props.menuProps)); }; BaseMenu.defaultProps = { postMenuData: function postMenuData(data) { return data || []; } }; var _default = BaseMenu; exports.default = _default;