UNPKG

@angeloreppucci/ant-design-pro-layout

Version:

ant-design-pro layout, easy to use pro scaffolding.

349 lines (283 loc) 12.7 kB
import "antd/es/layout/style"; import _Layout from "antd/es/layout"; 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; } function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _nonIterableRest(); } function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } function _iterableToArrayLimit(arr, i) { if (!(Symbol.iterator in Object(arr) || Object.prototype.toString.call(arr) === "[object Arguments]")) { 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; } var __rest = this && this.__rest || function (s, e) { var t = {}; for (var p in s) { if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p]; } if (s != null && typeof Object.getOwnPropertySymbols === "function") for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) t[p[i]] = s[p[i]]; } return t; }; import './BasicLayout.less'; import React, { useContext, useEffect } from 'react'; import { Helmet } from 'react-helmet'; import classNames from 'classnames'; import warning from 'warning'; import useMergeValue from 'use-merge-value'; import { stringify } from 'use-json-comparison'; import useAntdMediaQuery from 'use-media-antd-query'; 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 { isBrowser, useDeepCompareEffect } from './utils/utils'; import PageLoading from './PageLoading'; import MenuCounter from './SiderMenu/Counter'; import WrapContent from './WrapContent'; var headerRender = function headerRender(props) { if (props.headerRender === false) { return null; } return React.createElement(Header, Object.assign({}, props)); }; var footerRender = function footerRender(props) { if (props.footerRender === false) { return null; } if (props.footerRender) { return props.footerRender(Object.assign({}, props), 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) { return null; } if (layout === 'topmenu' && !isMobile) { return React.createElement(SiderMenu, Object.assign({}, props, { hide: true })); } if (menuRender) { return menuRender(props, React.createElement(SiderMenu, Object.assign({}, props))); } return React.createElement(SiderMenu, Object.assign({}, 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 Object.assign(Object.assign({}, 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 ? 80 : siderWidth; } return undefined; }; /** * 🌃 Powerful and easy to use beautiful layout * 🏄‍ Support multiple topics and layout types * @param props */ var BasicLayout = function BasicLayout(props) { var _classNames; 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, PropsLayout = props.layout, _props$route = props.route, route = _props$route === void 0 ? { routes: [] } : _props$route, style = props.style, disableContentMargin = props.disableContentMargin, _props$siderWidth = props.siderWidth, siderWidth = _props$siderWidth === void 0 ? 256 : _props$siderWidth, menu = props.menu, propsIsChildrenLayout = props.isChildrenLayout, menuDataRender = props.menuDataRender, loading = props.loading, rest = __rest(props, ["children", "onCollapse", "location", "fixSiderbar", "navTheme", "contentStyle", "layout", "route", "style", "disableContentMargin", "siderWidth", "menu", "isChildrenLayout", "menuDataRender", "loading"]); var formatMessage = function formatMessage(_a) { var id = _a.id, defaultMessage = _a.defaultMessage, restParams = __rest(_a, ["id", "defaultMessage"]); if (props.formatMessage) { return props.formatMessage(Object.assign({ 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 _useMergeValue = useMergeValue(function () { return getMenuData(routes, menu, formatMessage, menuDataRender); }), _useMergeValue2 = _slicedToArray(_useMergeValue, 2), menuInfoData = _useMergeValue2[0], setMenuInfoData = _useMergeValue2[1]; var renderMenuInfoData = {}; // 如果menuDataRender 存在,就应该每次都render一下,不然无法保证数据的同步 if (menuDataRender) { renderMenuInfoData = getMenuData(routes, menu, formatMessage, menuDataRender); } var isMobile = (colSize === 'sm' || colSize === 'xs') && !props.disableMobile; var _ref = !menuDataRender ? menuInfoData : renderMenuInfoData, _ref$breadcrumb = _ref.breadcrumb, breadcrumb = _ref$breadcrumb === void 0 ? {} : _ref$breadcrumb, breadcrumbMap = _ref.breadcrumbMap, _ref$menuData = _ref.menuData, menuData = _ref$menuData === void 0 ? [] : _ref$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 = fixSiderbar && PropsLayout !== 'topmenu' && !isMobile; var _useMergeValue3 = useMergeValue(false, { value: props.collapsed, onChange: propsOnCollapse }), _useMergeValue4 = _slicedToArray(_useMergeValue3, 2), collapsed = _useMergeValue4[0], onCollapse = _useMergeValue4[1]; // Splicing parameters, adding menuData and formatMessage in props var defaultProps = Omit(Object.assign(Object.assign({}, props), { formatMessage: formatMessage, breadcrumb: breadcrumb }), ['className', 'style']); // gen page title var pageTitleInfo = defaultPageTitleRender(Object.assign(Object.assign({ pathname: location.pathname }, defaultProps), { breadcrumbMap: breadcrumbMap }), props); // gen breadcrumbProps, parameter for pageHeader var breadcrumbProps = getBreadcrumbProps(Object.assign(Object.assign({}, defaultProps), { breadcrumbMap: breadcrumbMap })); // render sider dom var siderMenuDom = renderSiderMenu(Object.assign(Object.assign({}, defaultProps), { menuData: menuData, onCollapse: onCollapse, isMobile: isMobile, theme: (navTheme || 'dark').toLocaleLowerCase().includes('dark') ? 'dark' : 'light', collapsed: collapsed })); // render header dom var headerDom = headerRender(Object.assign(Object.assign({}, 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(Object.assign({ isMobile: isMobile, collapsed: collapsed }, defaultProps)); var _useContext = useContext(RouteContext), contextIsChildrenLayout = _useContext.isChildrenLayout; // 如果 props 中定义,以 props 为准 var isChildrenLayout = propsIsChildrenLayout !== undefined ? propsIsChildrenLayout : contextIsChildrenLayout; // gen className var className = classNames(props.className, 'ant-design-pro', 'ant-pro-basicLayout', (_classNames = {}, _defineProperty(_classNames, "screen-".concat(colSize), colSize), _defineProperty(_classNames, 'ant-pro-basicLayout-topmenu', PropsLayout === 'topmenu'), _defineProperty(_classNames, 'ant-pro-basicLayout-is-children', isChildrenLayout), _defineProperty(_classNames, 'ant-pro-basicLayout-fix-siderbar', fixSiderbar), _defineProperty(_classNames, 'ant-pro-basicLayout-mobile', isMobile), _classNames)); // siderMenuDom 为空的时候,不需要 padding var genLayoutStyle = { paddingLeft: siderMenuDom ? getPaddingLeft(!!hasLeftPadding, collapsed, siderWidth) : undefined, position: 'relative' }; // if is some layout children,don't need min height if (isChildrenLayout || contentStyle && contentStyle.minHeight) { genLayoutStyle.minHeight = 0; } var contentClassName = classNames('ant-pro-basicLayout-content', { 'ant-pro-basicLayout-has-header': headerDom, 'ant-pro-basicLayout-content-disable-margin': disableContentMargin }); // warning info useEffect(function () { warning(props.collapsed === undefined === (props.onCollapse === undefined), 'pro-layout: onCollapse and collapsed should exist simultaneously'); }, []); /** * 页面切换的时候触发 */ useEffect(function () { var onPageChange = props.onPageChange; if (onPageChange) { onPageChange(props.location); } }, [stringify(props.location)]); return React.createElement(React.Fragment, null, React.createElement(Helmet, null, React.createElement("title", null, pageTitleInfo.title)), React.createElement(MenuCounter.Provider, null, React.createElement(RouteContext.Provider, { value: Object.assign(Object.assign({}, defaultProps), { breadcrumb: breadcrumbProps, menuData: menuData, isMobile: isMobile, collapsed: collapsed, isChildrenLayout: true, title: pageTitleInfo.pageName }) }, React.createElement("div", { className: className }, React.createElement(_Layout, { style: Object.assign({ minHeight: '100%' }, style), hasSider: true }, siderMenuDom, React.createElement(_Layout, { style: genLayoutStyle }, headerDom, React.createElement(WrapContent, Object.assign({ className: contentClassName, isChildrenLayout: isChildrenLayout }, rest, { style: contentStyle }), loading ? React.createElement(PageLoading, null) : children), footerDom)))))); }; BasicLayout.defaultProps = Object.assign(Object.assign({ logo: 'https://gw.alipayobjects.com/zos/antfincdn/PmY%24TNNDBI/logo.svg' }, defaultSettings), { location: isBrowser() ? window.location : undefined }); export default BasicLayout;