|
|
import "antd/es/layout/style";
|
|
|
import _Layout from "antd/es/layout";
|
|
|
|
|
|
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(arr, i) { if (typeof Symbol === "undefined" || !(Symbol.iterator in Object(arr))) return; var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }
|
|
|
|
|
|
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; }
|
|
|
|
|
|
function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
|
|
|
|
|
|
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }
|
|
|
|
|
|
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
|
|
|
|
|
|
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
|
|
|
|
|
import './BasicLayout.less';
|
|
|
import React, { useContext, useEffect, useState } from 'react';
|
|
|
import classNames from 'classnames';
|
|
|
import warning from 'warning';
|
|
|
import useMergedState from 'rc-util/lib/hooks/useMergedState';
|
|
|
import { stringify } from 'use-json-comparison';
|
|
|
import useAntdMediaQuery from 'use-media-antd-query';
|
|
|
import { useDeepCompareEffect, useDocumentTitle, isBrowser } from '@ant-design/pro-utils';
|
|
|
import Omit from 'omit.js';
|
|
|
import Header from './Header';
|
|
|
import { getPageTitleInfo } from './getPageTitle';
|
|
|
import defaultSettings from './defaultSettings';
|
|
|
import getLocales from './locales';
|
|
|
import Footer from './Footer';
|
|
|
import RouteContext from './RouteContext';
|
|
|
import SiderMenu from './SiderMenu';
|
|
|
import { getBreadcrumbProps } from './utils/getBreadcrumbProps';
|
|
|
import getMenuData from './utils/getMenuData';
|
|
|
import PageLoading from './PageLoading';
|
|
|
import MenuCounter from './SiderMenu/Counter';
|
|
|
import WrapContent from './WrapContent';
|
|
|
import compatibleLayout from './utils/compatibleLayout';
|
|
|
|
|
|
var headerRender = function headerRender(props) {
|
|
|
if (props.headerRender === false || props.pure) {
|
|
|
return null;
|
|
|
}
|
|
|
|
|
|
return /*#__PURE__*/React.createElement(Header, props);
|
|
|
};
|
|
|
|
|
|
var footerRender = function footerRender(props) {
|
|
|
if (props.footerRender === false || props.pure) {
|
|
|
return null;
|
|
|
}
|
|
|
|
|
|
if (props.footerRender) {
|
|
|
return props.footerRender(_objectSpread({}, props), /*#__PURE__*/React.createElement(Footer, null));
|
|
|
}
|
|
|
|
|
|
return null;
|
|
|
};
|
|
|
|
|
|
var renderSiderMenu = function renderSiderMenu(props) {
|
|
|
var layout = props.layout,
|
|
|
isMobile = props.isMobile,
|
|
|
menuRender = props.menuRender;
|
|
|
|
|
|
if (props.menuRender === false || props.pure) {
|
|
|
return null;
|
|
|
}
|
|
|
|
|
|
if (layout === 'top' && !isMobile) {
|
|
|
return /*#__PURE__*/React.createElement(SiderMenu, _extends({}, props, {
|
|
|
hide: true
|
|
|
}));
|
|
|
}
|
|
|
|
|
|
if (menuRender) {
|
|
|
return menuRender(props, /*#__PURE__*/React.createElement(SiderMenu, props));
|
|
|
}
|
|
|
|
|
|
return /*#__PURE__*/React.createElement(SiderMenu, props);
|
|
|
};
|
|
|
|
|
|
var defaultPageTitleRender = function defaultPageTitleRender(pageProps, props) {
|
|
|
var pageTitleRender = props.pageTitleRender;
|
|
|
var pageTitleInfo = getPageTitleInfo(pageProps);
|
|
|
|
|
|
if (pageTitleRender === false) {
|
|
|
return {
|
|
|
title: props.title || '',
|
|
|
id: '',
|
|
|
pageName: ''
|
|
|
};
|
|
|
}
|
|
|
|
|
|
if (pageTitleRender) {
|
|
|
var title = pageTitleRender(pageProps, pageTitleInfo.title, pageTitleInfo);
|
|
|
|
|
|
if (typeof title === 'string') {
|
|
|
return _objectSpread(_objectSpread({}, pageTitleInfo), {}, {
|
|
|
title: title
|
|
|
});
|
|
|
}
|
|
|
|
|
|
warning(typeof title === 'string', 'pro-layout: renderPageTitle return value should be a string');
|
|
|
}
|
|
|
|
|
|
return pageTitleInfo;
|
|
|
};
|
|
|
|
|
|
var getPaddingLeft = function getPaddingLeft(hasLeftPadding, collapsed, siderWidth) {
|
|
|
if (hasLeftPadding) {
|
|
|
return collapsed ? 48 : siderWidth;
|
|
|
}
|
|
|
|
|
|
return 0;
|
|
|
};
|
|
|
/**
|
|
|
* 🌃 Powerful and easy to use beautiful layout
|
|
|
* 🏄 Support multiple topics and layout types
|
|
|
* @param props
|
|
|
*/
|
|
|
|
|
|
|
|
|
var BasicLayout = function BasicLayout(props) {
|
|
|
var _classNames, _classNames2;
|
|
|
|
|
|
var children = props.children,
|
|
|
propsOnCollapse = props.onCollapse,
|
|
|
_props$location = props.location,
|
|
|
location = _props$location === void 0 ? {
|
|
|
pathname: '/'
|
|
|
} : _props$location,
|
|
|
fixSiderbar = props.fixSiderbar,
|
|
|
navTheme = props.navTheme,
|
|
|
contentStyle = props.contentStyle,
|
|
|
_props$route = props.route,
|
|
|
route = _props$route === void 0 ? {
|
|
|
routes: []
|
|
|
} : _props$route,
|
|
|
defaultPropsLayout = props.layout,
|
|
|
style = props.style,
|
|
|
disableContentMargin = props.disableContentMargin,
|
|
|
_props$siderWidth = props.siderWidth,
|
|
|
siderWidth = _props$siderWidth === void 0 ? 208 : _props$siderWidth,
|
|
|
menu = props.menu,
|
|
|
propsIsChildrenLayout = props.isChildrenLayout,
|
|
|
menuDataRender = props.menuDataRender,
|
|
|
loading = props.loading,
|
|
|
rest = _objectWithoutProperties(props, ["children", "onCollapse", "location", "fixSiderbar", "navTheme", "contentStyle", "route", "layout", "style", "disableContentMargin", "siderWidth", "menu", "isChildrenLayout", "menuDataRender", "loading"]);
|
|
|
|
|
|
var propsLayout = compatibleLayout(defaultPropsLayout);
|
|
|
var prefixCls = rest.prefixCls;
|
|
|
|
|
|
var formatMessage = function formatMessage(_ref) {
|
|
|
var id = _ref.id,
|
|
|
defaultMessage = _ref.defaultMessage,
|
|
|
restParams = _objectWithoutProperties(_ref, ["id", "defaultMessage"]);
|
|
|
|
|
|
if (props.formatMessage) {
|
|
|
return props.formatMessage(_objectSpread({
|
|
|
id: id,
|
|
|
defaultMessage: defaultMessage
|
|
|
}, restParams));
|
|
|
}
|
|
|
|
|
|
var locales = getLocales();
|
|
|
|
|
|
if (locales[id]) {
|
|
|
return locales[id];
|
|
|
}
|
|
|
|
|
|
if (defaultMessage) {
|
|
|
return defaultMessage;
|
|
|
}
|
|
|
|
|
|
return id;
|
|
|
};
|
|
|
|
|
|
var colSize = useAntdMediaQuery();
|
|
|
var _route$routes = route.routes,
|
|
|
routes = _route$routes === void 0 ? [] : _route$routes;
|
|
|
|
|
|
var _useMergedState = useMergedState(function () {
|
|
|
return getMenuData(routes, menu, formatMessage, menuDataRender);
|
|
|
}),
|
|
|
_useMergedState2 = _slicedToArray(_useMergedState, 2),
|
|
|
menuInfoData = _useMergedState2[0],
|
|
|
setMenuInfoData = _useMergedState2[1];
|
|
|
|
|
|
var renderMenuInfoData = {}; // 如果menuDataRender 存在,就应该每次都render一下,不然无法保证数据的同步
|
|
|
|
|
|
if (menuDataRender) {
|
|
|
renderMenuInfoData = getMenuData(routes, menu, formatMessage, menuDataRender);
|
|
|
}
|
|
|
|
|
|
var isMobile = (colSize === 'sm' || colSize === 'xs') && !props.disableMobile;
|
|
|
|
|
|
var _ref2 = !menuDataRender ? menuInfoData : renderMenuInfoData,
|
|
|
_ref2$breadcrumb = _ref2.breadcrumb,
|
|
|
breadcrumb = _ref2$breadcrumb === void 0 ? {} : _ref2$breadcrumb,
|
|
|
breadcrumbMap = _ref2.breadcrumbMap,
|
|
|
_ref2$menuData = _ref2.menuData,
|
|
|
menuData = _ref2$menuData === void 0 ? [] : _ref2$menuData;
|
|
|
/**
|
|
|
* 如果 menuRender 不存在,可以做一下性能优化
|
|
|
* 只要 routers 没有更新就不需要重新计算
|
|
|
*/
|
|
|
|
|
|
|
|
|
useDeepCompareEffect(function () {
|
|
|
if (!menuDataRender) {
|
|
|
var infoData = getMenuData(routes, menu, formatMessage, menuDataRender); // 稍微慢一点 render,不然会造成性能问题,看起来像是菜单的卡顿
|
|
|
|
|
|
var animationFrameId = requestAnimationFrame(function () {
|
|
|
setMenuInfoData(infoData);
|
|
|
});
|
|
|
return function () {
|
|
|
return window.cancelAnimationFrame && window.cancelAnimationFrame(animationFrameId);
|
|
|
};
|
|
|
}
|
|
|
|
|
|
return function () {
|
|
|
return null;
|
|
|
};
|
|
|
}, [props.route, stringify(menu)]); // If it is a fix menu, calculate padding
|
|
|
// don't need padding in phone mode
|
|
|
|
|
|
var hasLeftPadding = propsLayout !== 'top' && !isMobile;
|
|
|
|
|
|
var _useMergedState3 = useMergedState(false, {
|
|
|
value: props.collapsed,
|
|
|
onChange: propsOnCollapse
|
|
|
}),
|
|
|
_useMergedState4 = _slicedToArray(_useMergedState3, 2),
|
|
|
collapsed = _useMergedState4[0],
|
|
|
onCollapse = _useMergedState4[1]; // Splicing parameters, adding menuData and formatMessage in props
|
|
|
|
|
|
|
|
|
var defaultProps = Omit(_objectSpread(_objectSpread({}, props), {}, {
|
|
|
formatMessage: formatMessage,
|
|
|
breadcrumb: breadcrumb,
|
|
|
layout: compatibleLayout(props.layout)
|
|
|
}), ['className', 'style']); // gen page title
|
|
|
|
|
|
var pageTitleInfo = defaultPageTitleRender(_objectSpread(_objectSpread({
|
|
|
pathname: location.pathname
|
|
|
}, defaultProps), {}, {
|
|
|
breadcrumbMap: breadcrumbMap
|
|
|
}), props); // gen breadcrumbProps, parameter for pageHeader
|
|
|
|
|
|
var breadcrumbProps = getBreadcrumbProps(_objectSpread(_objectSpread({}, defaultProps), {}, {
|
|
|
breadcrumbMap: breadcrumbMap
|
|
|
})); // render sider dom
|
|
|
|
|
|
var siderMenuDom = renderSiderMenu(_objectSpread(_objectSpread({}, defaultProps), {}, {
|
|
|
menuData: menuData,
|
|
|
onCollapse: onCollapse,
|
|
|
isMobile: isMobile,
|
|
|
theme: (navTheme || 'dark').toLocaleLowerCase().includes('dark') ? 'dark' : 'light',
|
|
|
collapsed: collapsed
|
|
|
})); // render header dom
|
|
|
|
|
|
var headerDom = headerRender(_objectSpread(_objectSpread({}, defaultProps), {}, {
|
|
|
hasSiderMenu: !!siderMenuDom,
|
|
|
menuData: menuData,
|
|
|
isMobile: isMobile,
|
|
|
collapsed: collapsed,
|
|
|
onCollapse: onCollapse,
|
|
|
theme: (navTheme || 'dark').toLocaleLowerCase().includes('dark') ? 'dark' : 'light'
|
|
|
})); // render footer dom
|
|
|
|
|
|
var footerDom = footerRender(_objectSpread({
|
|
|
isMobile: isMobile,
|
|
|
collapsed: collapsed
|
|
|
}, defaultProps));
|
|
|
|
|
|
var _useContext = useContext(RouteContext),
|
|
|
contextIsChildrenLayout = _useContext.isChildrenLayout; // 如果 props 中定义,以 props 为准
|
|
|
|
|
|
|
|
|
var isChildrenLayout = propsIsChildrenLayout !== undefined ? propsIsChildrenLayout : contextIsChildrenLayout;
|
|
|
var baseClassName = "".concat(prefixCls, "-basicLayout"); // gen className
|
|
|
|
|
|
var className = classNames(props.className, 'ant-design-pro', baseClassName, (_classNames = {}, _defineProperty(_classNames, "screen-".concat(colSize), colSize), _defineProperty(_classNames, "".concat(baseClassName, "-top-menu"), propsLayout === 'top'), _defineProperty(_classNames, "".concat(baseClassName, "-is-children"), isChildrenLayout), _defineProperty(_classNames, "".concat(baseClassName, "-fix-siderbar"), fixSiderbar), _defineProperty(_classNames, "".concat(baseClassName, "-mobile"), isMobile), _classNames));
|
|
|
/**
|
|
|
* 计算 slider 的宽度
|
|
|
*/
|
|
|
|
|
|
var leftSiderWidth = getPaddingLeft(!!hasLeftPadding, collapsed, siderWidth); // siderMenuDom 为空的时候,不需要 padding
|
|
|
|
|
|
var genLayoutStyle = {
|
|
|
position: 'relative'
|
|
|
}; // if is some layout children, don't need min height
|
|
|
|
|
|
if (isChildrenLayout || contentStyle && contentStyle.minHeight) {
|
|
|
genLayoutStyle.minHeight = 0;
|
|
|
}
|
|
|
|
|
|
var contentClassName = classNames("".concat(baseClassName, "-content"), (_classNames2 = {}, _defineProperty(_classNames2, "".concat(baseClassName, "-has-header"), headerDom), _defineProperty(_classNames2, "".concat(baseClassName, "-content-disable-margin"), disableContentMargin), _classNames2));
|
|
|
/**
|
|
|
* 页面切换的时候触发
|
|
|
*/
|
|
|
|
|
|
useEffect(function () {
|
|
|
var onPageChange = props.onPageChange;
|
|
|
|
|
|
if (onPageChange) {
|
|
|
onPageChange(props.location);
|
|
|
}
|
|
|
}, [stringify(props.location)]);
|
|
|
|
|
|
var _useState = useState(false),
|
|
|
_useState2 = _slicedToArray(_useState, 2),
|
|
|
hasFooterToolbar = _useState2[0],
|
|
|
setHasFooterToolbar = _useState2[1];
|
|
|
|
|
|
useDocumentTitle(pageTitleInfo, props.title || defaultSettings.title);
|
|
|
return /*#__PURE__*/React.createElement(MenuCounter.Provider, null, /*#__PURE__*/React.createElement(RouteContext.Provider, {
|
|
|
value: _objectSpread(_objectSpread({}, defaultProps), {}, {
|
|
|
breadcrumb: breadcrumbProps,
|
|
|
menuData: menuData,
|
|
|
isMobile: isMobile,
|
|
|
collapsed: collapsed,
|
|
|
isChildrenLayout: true,
|
|
|
title: pageTitleInfo.pageName,
|
|
|
hasSiderMenu: !!siderMenuDom,
|
|
|
hasHeader: !!headerDom,
|
|
|
siderWidth: leftSiderWidth,
|
|
|
hasFooter: !!footerDom,
|
|
|
hasFooterToolbar: hasFooterToolbar,
|
|
|
setHasFooterToolbar: setHasFooterToolbar,
|
|
|
pageTitleInfo: pageTitleInfo
|
|
|
})
|
|
|
}, /*#__PURE__*/React.createElement("div", {
|
|
|
className: className
|
|
|
}, /*#__PURE__*/React.createElement(_Layout, {
|
|
|
style: _objectSpread({
|
|
|
minHeight: '100%'
|
|
|
}, style),
|
|
|
hasSider: true
|
|
|
}, siderMenuDom, /*#__PURE__*/React.createElement(_Layout, {
|
|
|
style: genLayoutStyle
|
|
|
}, headerDom, /*#__PURE__*/React.createElement(WrapContent, _extends({
|
|
|
isChildrenLayout: isChildrenLayout
|
|
|
}, rest, {
|
|
|
className: contentClassName,
|
|
|
style: contentStyle
|
|
|
}), loading ? /*#__PURE__*/React.createElement(PageLoading, null) : children), footerDom)))));
|
|
|
};
|
|
|
|
|
|
BasicLayout.defaultProps = _objectSpread(_objectSpread({
|
|
|
logo: 'https://gw.alipayobjects.com/zos/antfincdn/PmY%24TNNDBI/logo.svg'
|
|
|
}, defaultSettings), {}, {
|
|
|
prefixCls: 'ant-pro',
|
|
|
siderWidth: 208,
|
|
|
location: isBrowser() ? window.location : undefined
|
|
|
});
|
|
|
export default BasicLayout; |