@ant-design/pro-layout
Version:
401 lines (323 loc) • 14.1 kB
JavaScript
"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;