import '@ant-design/pro-layout/es/BasicLayout.less' ; import React , { useState } from 'react' ; import { BreadcrumbProps as AntdBreadcrumbProps } from 'antd/es/breadcrumb' ; import { ContainerQuery } from 'react-container-query' ; import DocumentTitle from 'react-document-title' ; import { Layout } from 'antd' ; import classNames from 'classnames' ; import useMedia from 'react-media-hook2' ; import warning from 'warning' ; import Header , { HeaderViewProps } from '@ant-design/pro-layout/es/Header' ; import { MenuDataItem , MessageDescriptor , Route , RouterTypes , WithFalse , } from '@ant-design/pro-layout/es/typings' ; import defaultGetPageTitle , { GetPageTitleProps } from '@ant-design/pro-layout/es/getPageTitle' ; import defaultSettings , { Settings } from '@ant-design/pro-layout/es/defaultSettings' ; import getLocales , { localeType } from '@ant-design/pro-layout/es/locales' ; import Footer from '@ant-design/pro-layout/es/Footer' ; import RouteContext from '@ant-design/pro-layout/es/RouteContext' ; import { getBreadcrumbProps } from '@ant-design/pro-layout/es/utils/getBreadcrumbProps' ; import { isBrowser } from '@ant-design/pro-layout/es/utils/utils' ; import { SiderMenuProps } from '@ant-design/pro-layout/es/SiderMenu/SiderMenu' ; import { BaseMenuProps } from '@ant-design/pro-layout/es/SiderMenu/BaseMenu' ; import SiderMenu from '@ant-design/pro-layout/es/SiderMenu' ; import getMenuData from '@ant-design/pro-layout/es/utils/getMenuData' ; const { Content } = Layout ; const query = { 'screen-xs' : { maxWidth : 575 , } , 'screen-sm' : { minWidth : 576 , maxWidth : 767 , } , 'screen-md' : { minWidth : 768 , maxWidth : 991 , } , 'screen-lg' : { minWidth : 992 , maxWidth : 1199 , } , 'screen-xl' : { minWidth : 1200 , maxWidth : 1599 , } , 'screen-xxl' : { minWidth : 1600 , } , } ; export interface BasicLayoutProps extends Partial < RouterTypes < Route > > , SiderMenuProps , HeaderViewProps , Partial < Settings > { logo ? : React . ReactNode | WithFalse < ( ) => React . ReactNode > ; locale ? : localeType ; onCollapse ? : ( collapsed : boolean ) => void ; headerRender ? : WithFalse < ( props : HeaderViewProps ) => React . ReactNode > ; footerRender ? : WithFalse < ( props : HeaderViewProps , defaultDom : React . ReactNode ) => React . ReactNode > ; menuRender ? : WithFalse < ( props : HeaderViewProps , defaultDom : React . ReactNode ) => React . ReactNode > ; menuItemRender ? : BaseMenuProps [ 'menuItemRender' ] ; pageTitleRender ? : WithFalse < typeof defaultGetPageTitle > ; formatMessage ? : ( message : MessageDescriptor ) => string ; menuDataRender ? : ( menuData : MenuDataItem [ ] ) => MenuDataItem [ ] ; breadcrumbRender ? : ( routers : AntdBreadcrumbProps [ 'routes' ] ) => AntdBreadcrumbProps [ 'routes' ] ; itemRender ? : AntdBreadcrumbProps [ 'itemRender' ] ; /**
     * 是否禁用移动端模式，有的管理系统不需要移动端模式，此属性设置为true即可
     */ disableMobile ? : boolean ; tabsView ? : boolean ; } const headerRender = ( props ) : React . ReactNode => { if ( props . headerRender === false ) { return null ; } return < Header { ... props } / > ; } ; const footerRender = ( props ) : React . ReactNode => { if ( props . footerRender === false ) { return null ; } if ( props . footerRender ) { return props . footerRender ( { ... props } , < Footer />); } return < Footer />; } ; const renderSiderMenu = ( props ) : React . ReactNode => { const { layout , isMobile , menuRender } = props ; if ( props . menuRender === false ) { return null ; } if ( layout === 'topmenu' && ! isMobile ) { return null ; } if ( menuRender ) { return menuRender ( props , < SiderMenu { ... props } / > ) ; } return < SiderMenu { ... props } { ... props . menuProps } />; } ; const defaultPageTitleRender = ( pageProps , props ) : string => { const { pageTitleRender } = props ; if ( pageTitleRender === false ) { return props . title || '' ; } if ( pageTitleRender ) { const title = pageTitleRender ( pageProps ) ; if ( typeof title === 'string' ) { return title ; } warning ( typeof title === 'string' , 'pro-layout: renderPageTitle return value should be a string' ) ; } return defaultGetPageTitle ( pageProps ) ; } ; export type BasicLayoutContext = { [ K in 'location' ] : BasicLayoutProps [ K ] ; } & { breadcrumb : { [ path ] : MenuDataItem ; } ; } ; function useCollapsed ( collapsed , onCollapse ) { warning ( ( collapsed === undefined ) === ( onCollapse === undefined ) , 'pro-layout: onCollapse and collapsed should exist simultaneously' ) ; const [ nativeCollapsed , setCollapsed ] = useState ( false ) ; if ( collapsed !== undefined && onCollapse ) { return [ collapsed , onCollapse ] ; } if ( collapsed !== undefined && ! onCollapse ) { return [ collapsed , undefined ] ; } if ( collapsed === undefined && onCollapse ) { return [ undefined , onCollapse ] ; } return [ nativeCollapsed , setCollapsed ] ; } const getPaddingLeft = ( hasLeftPadding , collapsed , siderWidth ) : number | undefined => { if ( hasLeftPadding ) { return collapsed ? 80 : siderWidth ; } return undefined ; } ; const BasicLayout = props => { const { children , onCollapse : propsOnCollapse , location = { pathname : '/' } , fixedHeader , fixSiderbar , navTheme , layout : PropsLayout , route = { routes : [ ] , } , siderWidth = 256 , menu , menuDataRender , tabsView , } = props ; const formatMessage = ( { id , defaultMessage , ... rest } ) : string => { if ( props . formatMessage ) { return props . formatMessage ( { id , defaultMessage , ... rest , } ) ; } const locales = getLocales ( ) ; if ( locales [ id ] ) { return locales [ id ] ; } if ( defaultMessage ) { return defaultMessage as string ; } return id ; } ; const { routes = [ ] } = route ; const { breadcrumb , menuData } = getMenuData ( routes , menu , formatMessage , menuDataRender ) ; /**
     * init variables
     */ const isMobile = useMedia ( { id : 'BasicLayout' , query : '(max-width: 599px)' , targetWindow : window || { matchMedia : ( ) => true , } , } ) [ 0 ] && ! props . disableMobile ; const hasLeftPadding = fixSiderbar && PropsLayout !== 'topmenu' && ! isMobile ; const [ collapsed , onCollapse ] = useCollapsed ( props . collapsed , propsOnCollapse ) ; const defaultProps = { ... props , formatMessage , breadcrumb , } ; const pageTitle = defaultPageTitleRender ( { pathname : location . pathname , ... defaultProps , } , props ) ; const breadcrumbProps = getBreadcrumbProps ( { ... props , breadcrumb , } ) ; return ( < DocumentTitle title = { pageTitle } > < ContainerQuery query = { query } > { params => ( < div className = { classNames ( params , 'ant-design-pro' , 'basicLayout' ) } > < Layout > { renderSiderMenu ( { ... defaultProps , menuData , onCollapse , isMobile , theme : navTheme , collapsed , } ) } < Layout style = { { paddingLeft : getPaddingLeft ( ! ! hasLeftPadding , collapsed , siderWidth ) , minHeight : '100vh' , } } > { headerRender ( { ... defaultProps , menuData , isMobile , collapsed , onCollapse , } ) } < Content className = { `ant-pro-basicLayout-content${ tabsView ? ' ant-pro-tabsLayout-content' : '' }` } style = { ! fixedHeader ? { paddingTop : 0 } : { } } > < RouteContext . Provider value = { { breadcrumb : breadcrumbProps , ... props , menuData , isMobile , collapsed , title : pageTitle . split ( '-' ) [ 0 ] . trim ( ) , } } > { children } < /RouteContext.Provider> < /Content> { footerRender ( { isMobile , collapsed , ... defaultProps , } ) } < /Layout> < /Layout> < /div>)} < /ContainerQuery> < /DocumentTitle>); } ; BasicLayout . defaultProps = { logo : 'https://gw.alipayobjects.com/zos/antfincdn/PmY%24TNNDBI/logo.svg' , ... defaultSettings , location : isBrowser ( ) ? window . location : undefined , } ; export default BasicLayout ;