ProLayout - Advanced Layout

ProLayout provides a standard, yet flexible, middle and backend layout, with one-click layout switching and automatic menu generation. It can be used with PageContainer to automatically generate breadcrumbs, page headers, and provide a low-cost solution to access the footer toolbar.

When to use

ProLayout can be used to reduce layout costs when content needs to be carried on a page.

Use with umi plugins

ProLayout works best with umi. umi automatically injects the routes from config.ts into the configured layout for us, so we don't have to write the menus by hand.

ProLayout extends umi's router configuration, adding name, icon, locale, hideInMenu, hideChildrenInMenu and other configurations, so that it is easier to generate menus in one place. The data format is as follows.

export interface MenuDataItem {
/** @name submenu */
routes?: MenuDataItem[];
/** @name Hide child nodes in the menu */
hideChildrenInMenu?: boolean;
/** @name hideSelf and children in menu */
hideInMenu?: boolean;
/** @name Icon of the menu */
icon?: React.ReactNode;
/** @name Internationalization key for custom menus */
locale?: string | false;
/** @name The name of the menu */
name?: string;
/** @name is used to calibrate the selected value, default is path */
key?: string;
/** @name disable menu option */
disabled?: boolean;
/** @name path */
path?: string;
/**
* When this node is selected, the node of parentKeys is also selected
*
* @name custom parent node
*/
parentKeys?: string[];
/** @name hides itself and elevates child nodes to its level */
flatMenu?: boolean;
[key: string]: any;
}

ProLayout will automatically select the menu based on location.pathname and automatically generate the corresponding breadcrumbs. If you don't want to use it, you can configure selectedKeys and openKeys yourself for controlled configuration.

Code Demo

Basic usage

Load menu from server

ProLayout provides a powerful menu, but this necessarily encapsulates a lot of behavior, leading to dissatisfaction for users who need some special logic. So we provide a number of APIs that are expected to satisfy the vast majority of our clients in this way.

The main APIs used to load menu from the server are menuDataRender and menuRender, menuDataRender controls the current menu data and menuRender controls the menu's dom node.

Load the menu from the server and use the icon

Here is mainly a demo where we need to prepare an enumeration for icon rendering, which can significantly reduce the size of the package

Customize the content of the menu

With menuItemRender, subMenuItemRender, title, logo, menuHeaderRender you can customize the menu style very easily. If you are really not satisfied, you can use menuRender to fully customize it.

ProLayout does not provide footer by default, if you want to have the same style as Pro official website, you need to introduce a footer by yourself.

This is used to show various applications of ProLayout, if you think your usage can help others, feel free to PR.

Search menu

Multiple routes correspond to one menu item

Open all menus by default

Using IconFont

ghost mode

PageContainer configuration ghost can switch the page header to transparent mode.

Nested Layout

Customized collapsed

API

ProLayout

All methods suffixed with Render can be made not to render by passing false.

ParametersDescriptionTypeDefault
titleThe title of the top-left corner of the layoutReactNode'Ant Design Pro'
logourl to the top-left corner of layout's logoReactNode | ()=> ReactNode-
pureWhether to remove all self-contained interfacesboolean-
loadingThe loading state of the layoutboolean-
locationThe location information of the current application session. If your application creates a custom history, you will need to display the location attribute as described in issuehistory.locationisBrowser ? window.location : undefined
menuHeaderRenderrender logo and titleReactNode | (logo,title)=>ReactNode-
menuFooterRenderRender a block at the bottom of the layout(menuProps)=>ReactNode-
onMenuHeaderClickmenu menu menu's header click event(e: React.MouseEvent<HTMLDivElement>) => void-
menuExtraRenderRenders a region below the menu header(menuProps)=>ReactNode-
onTopMixMenuHeaderClickthe header click event of the top bar in mix mode(e: React.MouseEvent<HTMLDivElement>) => void-
contentStylelayout's content area styleCSSProperties-
layoutlayout's menu mode,side: right-hand navigation,top: top navigationside | topside
contentWidthcontent mode of layout,Fluid: adaptive,Fixed: fixed 1200pxFluid | FixedFluid
navThemeThe theme of the navigation, side and mix mode is the theme of the left menu, top mode is the top menulight | darkdark
headerThemeThe theme for the top navigation, with mix mode in effectlight | darkdark
fixedHeaderWhether to fix the header to the topbooleanfalse
fixSiderbarwhether to fix the navigationbooleanfalse
breakpointTrigger breakpoint for responsive layoutsEnum { 'xs', 'sm', 'md', 'lg', 'xl', 'xxl' }lg
menuFor the moment, only locale,locale can be turned off for the menu's own globalization{ locale: boolean, defaultOpenAll: boolean }{ locale: true }
iconfontUrlUse the icon configuration of IconFontURL-
iconPrefixesicon prefix of side menustringicon-
localeLanguage settings for the current layoutzh-CN | zh-TW | en-USnavigator.language
settingssettings for layoutSettings-
siderWidthwidth of the side menunumber208
defaultCollapsedThe default collapsed and expanded menusboolean-
collapsedControls the collapse and expansion of the menuboolean-
onCollapseThe collapsed event of the menu(collapsed: boolean) => void-
onPageChangeTriggered on page switch(location: Location) => void-
headerRenderCustom header render method(props: BasicLayoutProps) => ReactNode-
headerTitleRenderCustom header title method, works in mix mode(logo,title,props)=>ReactNode-
headerContentRenderCustom header content methods(props: BasicLayoutProps) => ReactNode-
rightContentRenderCustom render method for the right part of the header(props: HeaderViewProps) => ReactNode-
collapsedButtonRenderCustom method for collapsed button(collapsed: boolean) => ReactNode-
footerRenderCustom render method for footer(props: BasicLayoutProps) => JSX.Element | false-
pageTitleRenderThe render method for custom page titles(props: BasicLayoutProps) => ReactNode-
menuRenderThe render method for custom menus(props: HeaderViewProps) => ReactNode-
postMenuDataView the menu data before displaying it, changes will not trigger a re-render(menuData: MenuDataItem[]) => MenuDataItem[]-
menuItemRenderThe render method for custom menu items(itemProps: MenuDataItem, defaultDom: React.ReactNode, props: BaseMenuProps) => ReactNode-
subMenuItemRenderCustomize the render method with submenu items(itemProps: MenuDataItem) => ReactNode-
menuDataRenderThe render method of menuData, used to customize menuData(menuData: MenuDataItem[]) => MenuDataItem[]-
breadcrumbRendercustomize the data for breadcrumbs(route)=>route-
routeUsed to generate menus and breadcrumbs. umi's Layout will automatically haveroute-
disableMobiledisable automatic switching to mobile pagesbooleanfalse
linksShow shortcut actions in the lower right corner of the menuReactNode[]-
menuPropsThe props passed to the antd menu component, see (https://ant.design/components/menu/)MenuPropsundefined
waterMarkPropsConfigure watermark, watermark is a function of PageContainer, layout is only transparently transmitted to PageContainerWaterMarkProps-

SettingDrawer

SettingDrawer provides a graphical interface to set the layout's configuration. It is not recommended for use in a formal environment.

ParametersDescriptionTypeDefault
settingssettings for layoutSettings | Settings-
onSettingChangeSettings change event occurs(settings: [Settings](#Settings) ) => void-
hideHintAlertRemove the following alert messageboolean-

PageLoading

A simple loading page

parametersdescriptiontypedefault
(...)support all other antd Spin component parameters--

RouteContext

RouteContext can provide built-in data for Layout. For example, isMobile and collapsed, which you can consume to customize some of the behavior.

import { RouteContext, RouteContextType } from '@ant-design/pro-layout';
const Page = () => (
<RouteContext.
{(value: RouteContextType) => {
return value.title;
}}
</RouteContext.
);

GridContent

GridContent encapsulates the equal-width and [flow](https://preview.pro. ant.design/dashboard/analysis?layout=top) logic. You can see the preview effect in preview.

parametersdescriptiontypedefault
contentWidthContentModeFluid | Fixed-

getMenuData

Generate menuData and breadcrumb based on router information.

const { breadcrumb, menuData } = getMenuData(routes, menu, formatMessage, menuDataRender);
parametersdescriptiontypedefault
routesThe configuration information for the routeroute[]-
menuThe configuration entry for menu, default {locale: true}{ locale: boolean }-
menuDataRenderThe render method of menuData, used to customize menuData(menuData: MenuDataItem[]) => MenuDataItem[]-
formatMessageThe formatMessage method of react-intl(data: { id: any; defaultMessage?: string }) => string;-

getPageTitle

getPageTitle encapsulates the logic of the title generated on the menuData.

import { getPageTitle } from '@ant-design/pro-layout';
const title = getPageTitle({
pathname,
breadcrumb,
menu,
title,
formatMessage,
});
parametersdescriptiontypedefault
pathnamecurrent pathnamelocation.pathname-
breadcrumbthe collection of MenuDataItem{ [path: string]: MenuDataItem }-
menuThe configuration item for menu, default {locale: true}{ locale: boolean }-
titletype of titlestring'Ant Design Pro'
formatMessageformatMessage method of react-intl(data: { id: any; defaultMessage?: string }) => string;-

Settings

// You can get this type by importing { Settings } from '@ant-design/pro-layout/defaultSettings'
// to get this type
export interface Settings {
/** Theme for nav menu */
navTheme: 'light' | 'dark';
/** Primary color of ant design */
primaryColor: string;
/** Nav menu position: `side` or `top` */
layout: 'side' | 'top';
/** Layout of content: `Fluid` or `Fixed`, only works when layout is top */
contentWidth: 'Fluid' | 'Fixed';
/** Sticky header */
fixedHeader: boolean;
/** Sticky siderbar */
fixSiderbar: boolean;
menu: { locale: boolean };
title: string;
pwa: boolean;
// Your custom iconfont Symbol script Url
// eg: // at.alicdn.com/t/font_1039637_btcrd5co4w.js
// Usage: https://github.com/ant-design/ant-design-pro/pull/3517
iconfontUrl: string;
colorWeak: boolean;
}
// You can get this type by importing { MenuDataItem } from '@ant-design/pro-layout'
// to get this type
export interface MenuDataItem {
authority?: string[] | string;
routes?: MenuDataItem[];
hideChildrenInMenu?: boolean;
hideInMenu?: boolean;
icon?: string;
locale?: string;
name?: string;
path: string;
[key: string]: any;
}

Route

// You can get this type by importing { RouterTypes } from '@ant-design/pro-layout/lib/typings';
// to get this type
export interface Route {
path: string;
routes: Array<{
exact?: boolean;
icon: string;
name: string;
path: string;
// Optional secondary menu
routes?: Route['routes'];
}>;
}

The default ProLayout does not provide a footer, but does provide a footer component that supports the configuration of some hyperlinks and some copyright information.

<Footer
copyright="@2019 by Anthem Experience Technologies"
links={[
{
key: 'Ant Design Pro',
title: 'Ant Design Pro',
href: 'https://pro.ant.design',
blankTarget: true,
},
{
key: 'github',
title: <GithubOutlined />,
href: 'https://github.com/ant-design/ant-design-pro',
blankTarget: true,
},
{
key: 'Ant Design',
title: 'Ant Design',
href: 'https://ant.design',
blankTarget: true,
},
]}
/>

GridContent

GridContent is a simple syntactic sugar that encapsulates ProLayout's contentWidth configuration. contentWidth, if set to Fixed fixed-width mode, is only 1200px at its widest.

Usage.

<GridContent>{children}</GridContent>

RouteContext

RouteContext provides a way to perform operations based on the layout's data, PageContainer and FooterToolbar both rely on RouteContext's data for their functionality.

import { RouteContext, RouteContextType } from '@ant-design/pro-layout';
const Page = () => (
<RouteContext.
{(value: RouteContextType) => {
const { isMobile, hasHeader, hasSiderMenu, collapsed } = value;
// The title of the user
return value.title;
}}
</RouteContext.
);

FAQ

Customizing Layout

ProLayout provides some api to remove areas that are not needed by the user. Some configurations are also provided in SettingDrawer to set them.

setting-drawer-render

  • headerRender can customize the top bar
  • footerRender can customize the footer
  • menuRender can customize the menu area
  • menuHeaderRender Customizable menu header area
  • menuExtraRender can add an extra content to the menu, between the menu header and the menu

All xxxRender in layout can be passed in false to turn off rendering.

Collapse to expand

Sometimes we find that collapsed and onCollapse do not work by default. This is because ProLayout has a built-in breakpoint mechanism to trigger collapse, we can set breakpoint={false} to turn off this mechanism.

Customize the width of the menu

siderWidth can customize the width of the menu, you can set it shorter or longer FooterToolbar and other components will automatically support, but may need to do some style processing, otherwise the menu display may have some small problems.

The width of the menu is not customizable because it involves animation and huge amount of css changes, which is very difficult to customize.

Auto-cut menu

Auto-cut menu is an exclusive ability of mix mode to place the first level of the menu into the top bar. We can set splitMenus=true to turn it on, and for a good experience it's best to set a redirect for each level of the menu, which will prevent switching to a white screen page.

cutMenu

Customizing menus

ProLayout will automatically generate the menu and auto-select it according to pathname. Combined with PageContainer, this allows for automatic breadcrumb and page title projection. If used with the umi configuration, you only need to hand the Page props to ProLayout to automatically generate the configuration of the menu based on the configuration of routers in config.

In order to provide more functionality, we extended the routers configuration by adding several configurations for customization, with the following data structure definition:

// You can get this type by importing { MenuDataItem } from '@ant-design/pro-layout'
// to get this type
export interface MenuDataItem {
routes?: MenuDataItem[];
hideChildrenInMenu?: boolean;
hideInMenu?: boolean;
icon?: string;
locale?: string;
name?: string;
path: string;
[key: string]: any;
}
  • name is used to configure the name in the menu, and will be modified to the browser tab title
  • icon represents the body of the menu, only antd's icon, iconfont needs to be defined by yourself
  • locale can set the internationalization of the menu name
  • hideInMenu will be configured to hide this route in the menu, name will have the same effect if not filled
  • hideChildrenInMenu will hide the children of this route in the menu

ProLayout actually reads the route and location from the props, which are injected by default by umi.

Getting from the server

Sometimes we want the server to manage our routes, so we want the menus to be distributed by the server. We provide menuDataRender to modify the data, but note that menuDataRender will trigger re-rendering and will also support internationalization and permission configuration, so if you don't need internationalization, we recommend using postMenuData for a significant performance boost.

The server needs to return the same data as MenuDataItem, menuDataRender needs to return an array, if you want to have better performance you can try using the route property in props, here is a demo.