@oceanbase/ui
Version:
The UI library based on OceanBase Design
376 lines (373 loc) • 20.2 kB
JavaScript
function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
var _excluded = ["children", "location", "banner", "iconUrl", "logoUrl", "simpleLogoUrl", "topHeader", "menus", "defaultCollapsed", "defaultSelectedKeys", "defaultOpenKeys", "sideHeader", "subSideMenuProps", "subSideMenus", "className", "prefixCls"];
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : String(i); }
function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); }
function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter); }
function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); }
function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }
function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }
import { CaretRightFilled, LeftOutlined, RightOutlined } from '@oceanbase/icons';
import { setAlpha } from '@ant-design/pro-components';
import { Typography, theme } from '@oceanbase/design';
import { isNullValue } from '@oceanbase/util';
import { ConfigProvider, Divider, Layout, Menu, Tooltip } from '@oceanbase/design';
import classNames from 'classnames';
import { some, uniq } from 'lodash';
import { pathToRegexp } from 'path-to-regexp';
import React, { useEffect, useState, useContext } from 'react';
import LocaleWrapper from "../locale/LocaleWrapper";
import { urlToList } from "../_util";
import useNavigate from "../_util/useNavigate";
import Header from "./Header";
import zhCN from "./locale/zh-CN";
import useStyle from "./style";
import { jsx as _jsx } from "react/jsx-runtime";
import { jsxs as _jsxs } from "react/jsx-runtime";
import { Fragment as _Fragment } from "react/jsx-runtime";
var Content = Layout.Content,
Sider = Layout.Sider;
var SubMenu = Menu.SubMenu,
Item = Menu.Item;
var BasicLayout = function BasicLayout(_ref) {
var children = _ref.children,
_ref$location = _ref.location,
_ref$location2 = _ref$location === void 0 ? {} : _ref$location,
pathname = _ref$location2.pathname,
banner = _ref.banner,
iconUrl = _ref.iconUrl,
logoUrl = _ref.logoUrl,
simpleLogoUrl = _ref.simpleLogoUrl,
topHeader = _ref.topHeader,
_ref$menus = _ref.menus,
menus = _ref$menus === void 0 ? [] : _ref$menus,
_ref$defaultCollapsed = _ref.defaultCollapsed,
defaultCollapsed = _ref$defaultCollapsed === void 0 ? false : _ref$defaultCollapsed,
_ref$defaultSelectedK = _ref.defaultSelectedKeys,
defaultSelectedKeys = _ref$defaultSelectedK === void 0 ? [] : _ref$defaultSelectedK,
_ref$defaultOpenKeys = _ref.defaultOpenKeys,
defaultOpenKeys = _ref$defaultOpenKeys === void 0 ? [] : _ref$defaultOpenKeys,
sideHeader = _ref.sideHeader,
subSideMenuProps = _ref.subSideMenuProps,
subSideMenus = _ref.subSideMenus,
className = _ref.className,
customizePrefixCls = _ref.prefixCls,
restProps = _objectWithoutProperties(_ref, _excluded);
var _theme$useToken = theme.useToken(),
token = _theme$useToken.token;
var _useContext = useContext(ConfigProvider.ConfigContext),
getPrefixCls = _useContext.getPrefixCls;
var prefixCls = getPrefixCls('pro-basic-layout', customizePrefixCls);
var _useStyle = useStyle(prefixCls),
wrapSSR = _useStyle.wrapSSR;
var navigate = useNavigate();
// 侧边栏导航是否收起
var _useState = useState(defaultCollapsed),
_useState2 = _slicedToArray(_useState, 2),
collapsed = _useState2[0],
setCollapsed = _useState2[1];
var _useState3 = useState(defaultSelectedKeys),
_useState4 = _slicedToArray(_useState3, 2),
selectedKeys = _useState4[0],
setSelectedKeys = _useState4[1];
var _useState5 = useState(defaultOpenKeys),
_useState6 = _slicedToArray(_useState5, 2),
openKeys = _useState6[0],
setOpenKeys = _useState6[1];
useEffect(function () {
// 获取当前选中的菜单
var selectedMenuKeys = urlToList(pathname).map(function (itemPath) {
return getMenuMatches(getFlatMenuKeys(menus), itemPath).pop();
}) || [];
var newSelectedKeys = selectedMenuKeys.filter(function (item) {
return item;
});
if (newSelectedKeys.length > 0) {
// use last selected key to avoid multiple selected menus
var selectedKey = newSelectedKeys[newSelectedKeys.length - 1];
setSelectedKeys([selectedKey]);
// get parent keys of current selectedKey
var selectedParentKeys = getParentKeys(menus, selectedKey);
// append parent keys as open keys
setOpenKeys(uniq([].concat(_toConsumableArray(openKeys), _toConsumableArray(selectedParentKeys))));
} else {
setSelectedKeys([]);
}
}, [pathname]);
var menuProps = {
selectedKeys: selectedKeys,
openKeys: openKeys,
onSelect: function onSelect(_ref2) {
var newSelectedKeys = _ref2.selectedKeys;
setSelectedKeys(newSelectedKeys);
},
onOpenChange: function onOpenChange(newOpenKeys) {
setOpenKeys(newOpenKeys);
}
};
var getMenuMatches = function getMenuMatches(flatMenuKeys, path) {
return flatMenuKeys.filter(function (item) {
return pathToRegexp(item).test(path);
});
};
var getParentKeys = function getParentKeys(menuList, selectedKey) {
var keys = [];
(menuList || []).forEach(function (item) {
var itemChildren = item.children || [];
var childrenKeys = itemChildren.map(function (child) {
return child.link;
});
if (childrenKeys.includes(selectedKey)) {
keys = [].concat(_toConsumableArray(keys), [item.link]);
} else {
keys = [].concat(_toConsumableArray(keys), [getParentKeys(itemChildren, selectedKey)]);
}
});
return keys;
};
var getFlatMenuKeys = function getFlatMenuKeys(menuList) {
var keys = [];
(menuList || []).forEach(function (item) {
if (item.children) {
keys = keys.concat(getFlatMenuKeys(item.children));
}
keys.push(item.link || '');
});
return keys;
};
// 渲染菜单中的图标
var renderIcon = function renderIcon(item) {
var isSubSider = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
var realSelectedKeys = isSubSider ? subSideMenuProps.selectedKeys || subSideMenuProps.defaultSelectedKeys : selectedKeys;
// 渲染 selectedIcon 的条件: 1. 菜单项被选中 2. 子菜单被选中
return realSelectedKeys.includes(item.link) || some(item.children || [], function (child) {
return realSelectedKeys.includes(child.link);
}) ? item.selectedIcon || item.icon : item.icon;
};
// 渲染菜单
var renderMenu = function renderMenu(data) {
return data.reduce(function (pre, item) {
var _item$children;
var _item$accessible = item.accessible,
accessible = _item$accessible === void 0 ? true : _item$accessible;
if (item.children && (isNullValue(item.accessible) ? // 如果子菜单本身没有设置 accessible,但只要其 children 之一可访问,则子菜单仍然展示
(_item$children = item.children) === null || _item$children === void 0 ? void 0 : _item$children.some(function (_ref3) {
var _ref3$accessible = _ref3.accessible,
childAccessible = _ref3$accessible === void 0 ? true : _ref3$accessible;
return childAccessible;
}) : item.accessible)) {
pre.push( /*#__PURE__*/_jsx(SubMenu, {
"data-testid": "menu.sub",
title: /*#__PURE__*/_jsxs("div", {
children: [renderIcon(item), /*#__PURE__*/_jsx(Typography.Text, {
ellipsis: {
tooltip: {
placement: 'right'
}
},
style: {
lineHeight: '40px',
maxWidth: 80
},
children: item.title
})]
}),
children: renderMenu(item.children)
}, item.link));
} else if (!item.children && accessible) {
pre.push( /*#__PURE__*/_jsx(Item, {
"data-testid": "menu.item",
onClick: function onClick() {
if (pathname !== item.link) {
navigate === null || navigate === void 0 || navigate(item.link);
}
},
children: /*#__PURE__*/_jsxs("div", {
children: [renderIcon(item), /*#__PURE__*/_jsx(Typography.Text, {
ellipsis: {
tooltip: {
placement: 'right'
}
},
style: {
lineHeight: '40px',
maxWidth: 116
},
children: item.title
})]
})
}, item.link));
}
if (item.divider && accessible) {
pre.push( /*#__PURE__*/_jsx(Divider, {
style: {
// 渐变的分隔线
borderImage: "linear-gradient(90deg, ".concat(token.colorTextQuaternary, " 0%, ").concat(setAlpha(token.colorTextQuaternary, 0), " 100%) 1")
}
}));
}
return pre;
}, []);
};
// 渲染收起菜单
var renderCollapsedMenu = function renderCollapsedMenu(data) {
var isSubSider = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
return data.reduce(function (pre, item) {
var _item$children2;
var _item$accessible2 = item.accessible,
accessible = _item$accessible2 === void 0 ? true : _item$accessible2;
if (item.children && (isNullValue(item.accessible) ? // 如果子菜单本身没有设置 accessible,但只要其 children 之一可访问,则子菜单仍然展示
(_item$children2 = item.children) === null || _item$children2 === void 0 ? void 0 : _item$children2.some(function (_ref4) {
var _ref4$accessible = _ref4.accessible,
childAccessible = _ref4$accessible === void 0 ? true : _ref4$accessible;
return childAccessible;
}) : item.accessible)) {
pre.push( /*#__PURE__*/_jsx(SubMenu, {
title: renderIcon(item, isSubSider),
children: renderMenu(item.children)
}, item.link));
} else if (!item.children && accessible) {
pre.push( /*#__PURE__*/_jsx(Item, {
"data-testid": "menu.item",
onClick: function onClick() {
if (pathname !== item.link) {
navigate === null || navigate === void 0 || navigate(item.link);
}
},
children: /*#__PURE__*/_jsx(Tooltip, {
placement: "right",
title: item.title,
getPopupContainer: function getPopupContainer() {
return document.body;
},
children: /*#__PURE__*/_jsx("div", {
children: renderIcon(item, isSubSider)
})
})
}, item.link));
}
if (item.divider && accessible) {
pre.push( /*#__PURE__*/_jsx(Divider, {}));
}
return pre;
}, []);
};
var siderWidth = 0;
// 根据菜单项的配置计算侧边栏的宽度
if (subSideMenus && menus) {
siderWidth = collapsed ? 52 * 2 : 208;
} else if (subSideMenus && !menus) {
siderWidth = 52;
} else if (!subSideMenus && menus) {
siderWidth = collapsed ? 52 : 192;
} else if (!subSideMenus && !menus) {
siderWidth = 0;
}
return wrapSSR( /*#__PURE__*/_jsxs(_Fragment, {
children: [banner && /*#__PURE__*/_jsx("div", {
className: "".concat(prefixCls, "-banner-wrapper"),
children: banner
}), /*#__PURE__*/_jsx(Layout, _objectSpread(_objectSpread({
className: classNames(prefixCls, _defineProperty(_defineProperty({}, "".concat(prefixCls, "-with-banner"), banner), "".concat(prefixCls, "-sider-").concat(siderWidth), true), className)
}, restProps), {}, {
children: /*#__PURE__*/_jsxs(React.Fragment, {
children: [/*#__PURE__*/_jsx(Header, _objectSpread({
prefixCls: prefixCls,
pathname: pathname,
iconUrl: iconUrl,
logoUrl: logoUrl,
simpleLogoUrl: simpleLogoUrl
}, topHeader)), /*#__PURE__*/_jsx("div", {
children: /*#__PURE__*/_jsxs(Layout, {
className: "".concat(prefixCls, "-content-layout"),
style: {
marginTop: 48
},
children: [(subSideMenus || menus) && /*#__PURE__*/_jsx(Sider, {
theme: "light",
width: siderWidth,
className: classNames("".concat(prefixCls, "-sider"), _defineProperty(_defineProperty({}, "".concat(prefixCls, "-sider-collapsed"), collapsed), "".concat(prefixCls, "-sider-has-sub-sider"), subSideMenus)),
children: /*#__PURE__*/_jsxs("div", {
className: "".concat(prefixCls, "-sider-wrapper"),
children: [subSideMenus && /*#__PURE__*/_jsx("div", {
className: "".concat(prefixCls, "-sub-sider"),
children: /*#__PURE__*/_jsx(Menu, _objectSpread(_objectSpread({}, subSideMenuProps), {}, {
mode: "vertical",
className: "".concat(prefixCls, "-menu-vertical"),
children: renderCollapsedMenu(subSideMenus, true)
}))
}), (sideHeader || menus) && /*#__PURE__*/_jsxs("div", {
style: {
display: 'flex',
width: '100%'
},
children: [/*#__PURE__*/_jsxs("div", {
className: "".concat(prefixCls, "-sider-content"),
children: [sideHeader && /*#__PURE__*/_jsx("div", {
className: "".concat(prefixCls, "-sider-header"),
children: sideHeader
}), /*#__PURE__*/_jsx("div", {
className: "".concat(prefixCls, "-menu-wrapper"),
children: collapsed ? /*#__PURE__*/_jsx("div", {
className: "".concat(prefixCls, "-menu-collapsed"),
children: /*#__PURE__*/_jsx(Menu, _objectSpread(_objectSpread({}, menuProps), {}, {
mode: "vertical",
className: "".concat(prefixCls, "-menu-vertical"),
children: renderCollapsedMenu(menus, false)
}))
}) : /*#__PURE__*/_jsx(Menu, _objectSpread(_objectSpread({}, menuProps), {}, {
mode: "inline",
expandIcon: function expandIcon(_ref5) {
var isOpen = _ref5.isOpen;
return /*#__PURE__*/_jsx(CaretRightFilled, {
rotate: isOpen ? 90 : 0,
style: {
fontSize: 12
}
});
},
className: "".concat(prefixCls, "-menu"),
children: renderMenu(menus)
}))
})]
}), /*#__PURE__*/_jsx("div", {
className: "".concat(prefixCls, "-sider-border"),
children: /*#__PURE__*/_jsx("div", {
className: "".concat(prefixCls, "-sider-collapse"),
onClick: function onClick() {
setCollapsed(!collapsed);
// 导航展开/收起时,重置 openKeys
setOpenKeys([]);
},
children: collapsed ? /*#__PURE__*/_jsx(RightOutlined, {}) : /*#__PURE__*/_jsx(LeftOutlined, {})
})
})]
})]
})
}), /*#__PURE__*/_jsx(Content, {
className: classNames("".concat(prefixCls, "-content"), "".concat(prefixCls, "-content-").concat(siderWidth)),
style: {
marginLeft: siderWidth
},
children: children
})]
})
})]
})
}))]
}));
};
export default LocaleWrapper({
componentName: 'BasicLayout',
defaultLocale: zhCN
})(BasicLayout);