From 7679507bffb9505bd2747edb09b8d8920cc2007d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E5=B8=85?= Date: Wed, 3 Apr 2019 09:48:24 +0800 Subject: [PATCH] use antd page-header (#3881) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * use antd page-header * remove page-header * up ant version * up antd version * up antd verison * use umi-request (#3883) * use umi-request * use data repalce to body * 401 不需要提示请求错误。 * use netlify functions (#3882) * use netlify functions * rm .gitignore key * fix build error * use new folder * change config * add redirects * add redirects * add router * remobe "/" * remove code * add tag * remove babel loader * rm firebase config * remove babel * bugfix: fix#3891 ,dll config error * add function build * fix error script * feat: win add test script (#3845) * feat: win add test script * bugfix: fix test error * use new config * style: change title size * style: change title size --- src/components/PageHeader/breadcrumb.d.ts | 6 - src/components/PageHeader/breadcrumb.js | 178 ------------------ src/components/PageHeader/demo/image.md | 75 -------- src/components/PageHeader/demo/simple.md | 32 ---- src/components/PageHeader/demo/standard.md | 102 ---------- src/components/PageHeader/demo/structure.md | 68 ------- src/components/PageHeader/index.d.ts | 31 --- src/components/PageHeader/index.js | 82 -------- src/components/PageHeader/index.less | 161 ---------------- src/components/PageHeader/index.md | 35 ---- src/components/PageHeader/index.test.js | 43 ----- .../PageHeaderWrapper/breadcrumb.js | 116 ++++++++++++ src/components/PageHeaderWrapper/index.js | 117 +++++++++--- src/components/PageHeaderWrapper/index.less | 105 ++++++++++- src/layouts/Header.js | 5 +- 15 files changed, 312 insertions(+), 844 deletions(-) delete mode 100644 src/components/PageHeader/breadcrumb.d.ts delete mode 100644 src/components/PageHeader/breadcrumb.js delete mode 100644 src/components/PageHeader/demo/image.md delete mode 100644 src/components/PageHeader/demo/simple.md delete mode 100644 src/components/PageHeader/demo/standard.md delete mode 100644 src/components/PageHeader/demo/structure.md delete mode 100644 src/components/PageHeader/index.d.ts delete mode 100644 src/components/PageHeader/index.js delete mode 100644 src/components/PageHeader/index.less delete mode 100644 src/components/PageHeader/index.md delete mode 100644 src/components/PageHeader/index.test.js create mode 100644 src/components/PageHeaderWrapper/breadcrumb.js diff --git a/src/components/PageHeader/breadcrumb.d.ts b/src/components/PageHeader/breadcrumb.d.ts deleted file mode 100644 index 69a95dc1..00000000 --- a/src/components/PageHeader/breadcrumb.d.ts +++ /dev/null @@ -1,6 +0,0 @@ -import React from 'react'; -import { PageHeaderProps } from './index'; - -export default class BreadcrumbView extends React.Component {} - -export function getBreadcrumb(breadcrumbNameMap: object, url: string): object; diff --git a/src/components/PageHeader/breadcrumb.js b/src/components/PageHeader/breadcrumb.js deleted file mode 100644 index e6afcb54..00000000 --- a/src/components/PageHeader/breadcrumb.js +++ /dev/null @@ -1,178 +0,0 @@ -import React, { PureComponent, createElement } from 'react'; -import pathToRegexp from 'path-to-regexp'; -import { Breadcrumb } from 'antd'; -import styles from './index.less'; -import { urlToList } from '../_utils/pathTools'; - -export const getBreadcrumb = (breadcrumbNameMap, url) => { - let breadcrumb = breadcrumbNameMap[url]; - if (!breadcrumb) { - Object.keys(breadcrumbNameMap).forEach(item => { - if (pathToRegexp(item).test(url)) { - breadcrumb = breadcrumbNameMap[item]; - } - }); - } - return breadcrumb || {}; -}; - -export default class BreadcrumbView extends PureComponent { - state = { - breadcrumb: null, - }; - - componentDidMount() { - this.getBreadcrumbDom(); - } - - componentDidUpdate(preProps) { - const { location } = this.props; - if (!location || !preProps.location) { - return; - } - const prePathname = preProps.location.pathname; - if (prePathname !== location.pathname) { - this.getBreadcrumbDom(); - } - } - - getBreadcrumbDom = () => { - const breadcrumb = this.conversionBreadcrumbList(); - this.setState({ - breadcrumb, - }); - }; - - getBreadcrumbProps = () => { - const { routes, params, location, breadcrumbNameMap } = this.props; - return { - routes, - params, - routerLocation: location, - breadcrumbNameMap, - }; - }; - - // Generated according to props - conversionFromProps = () => { - const { breadcrumbList, breadcrumbSeparator, itemRender, linkElement = 'a' } = this.props; - return ( - - {breadcrumbList.map(item => { - const title = itemRender ? itemRender(item) : item.title; - return ( - - {item.href - ? createElement( - linkElement, - { - [linkElement === 'a' ? 'href' : 'to']: item.href, - }, - title - ) - : title} - - ); - })} - - ); - }; - - conversionFromLocation = (routerLocation, breadcrumbNameMap) => { - const { breadcrumbSeparator, home, itemRender, linkElement = 'a' } = this.props; - // Convert the url to an array - const pathSnippets = urlToList(routerLocation.pathname); - // Loop data mosaic routing - const extraBreadcrumbItems = pathSnippets.map((url, index) => { - const currentBreadcrumb = getBreadcrumb(breadcrumbNameMap, url); - if (currentBreadcrumb.inherited) { - return null; - } - const isLinkable = index !== pathSnippets.length - 1 && currentBreadcrumb.component; - const name = itemRender ? itemRender(currentBreadcrumb) : currentBreadcrumb.name; - return currentBreadcrumb.name && !currentBreadcrumb.hideInBreadcrumb ? ( - - {createElement( - isLinkable ? linkElement : 'span', - { [linkElement === 'a' ? 'href' : 'to']: url }, - name - )} - - ) : null; - }); - // Add home breadcrumbs to your head if defined - if (home) { - extraBreadcrumbItems.unshift( - - {createElement( - linkElement, - { - [linkElement === 'a' ? 'href' : 'to']: '/', - }, - home - )} - - ); - } - return ( - - {extraBreadcrumbItems} - - ); - }; - - /** - * 将参数转化为面包屑 - * Convert parameters into breadcrumbs - */ - conversionBreadcrumbList = () => { - const { breadcrumbList, breadcrumbSeparator } = this.props; - const { routes, params, routerLocation, breadcrumbNameMap } = this.getBreadcrumbProps(); - if (breadcrumbList && breadcrumbList.length) { - return this.conversionFromProps(); - } - // 如果传入 routes 和 params 属性 - // If pass routes and params attributes - if (routes && params) { - return ( - route.breadcrumbName)} - params={params} - itemRender={this.itemRender} - separator={breadcrumbSeparator} - /> - ); - } - // 根据 location 生成 面包屑 - // Generate breadcrumbs based on location - if (routerLocation && routerLocation.pathname) { - return this.conversionFromLocation(routerLocation, breadcrumbNameMap); - } - return null; - }; - - // 渲染Breadcrumb 子节点 - // Render the Breadcrumb child node - itemRender = (route, params, routes, paths) => { - const { linkElement = 'a' } = this.props; - const last = routes.indexOf(route) === routes.length - 1; - return last || !route.component ? ( - {route.breadcrumbName} - ) : ( - createElement( - linkElement, - { - href: paths.join('/') || '/', - to: paths.join('/') || '/', - }, - route.breadcrumbName - ) - ); - }; - - render() { - const { breadcrumb } = this.state; - return breadcrumb; - } -} diff --git a/src/components/PageHeader/demo/image.md b/src/components/PageHeader/demo/image.md deleted file mode 100644 index 511bac5d..00000000 --- a/src/components/PageHeader/demo/image.md +++ /dev/null @@ -1,75 +0,0 @@ ---- -order: 2 -title: With Image ---- - -带图片的页头。 - -````jsx -import PageHeader from 'ant-design-pro/lib/PageHeader'; - -const content = ( -
-

段落示意:蚂蚁金服务设计平台 ant.design,用最小的工作量,无缝接入蚂蚁金服生态,提供跨越设计与开发的体验解决方案。

-
- - 快速开始 - - - 产品简介 - - - 产品文档 - -
-
-); - -const extra = ( -
- -
-); - -const breadcrumbList = [{ - title: '一级菜单', - href: '/', -}, { - title: '二级菜单', - href: '/', -}, { - title: '三级菜单', -}]; - -ReactDOM.render( -
- -
-, mountNode); -```` - - diff --git a/src/components/PageHeader/demo/simple.md b/src/components/PageHeader/demo/simple.md deleted file mode 100644 index d0ad1f7d..00000000 --- a/src/components/PageHeader/demo/simple.md +++ /dev/null @@ -1,32 +0,0 @@ ---- -order: 3 -title: Simple ---- - -简单的页头。 - -````jsx -import PageHeader from 'ant-design-pro/lib/PageHeader'; - -const breadcrumbList = [{ - title: '一级菜单', - href: '/', -}, { - title: '二级菜单', - href: '/', -}, { - title: '三级菜单', -}]; - -ReactDOM.render( -
- -
-, mountNode); -```` - - diff --git a/src/components/PageHeader/demo/standard.md b/src/components/PageHeader/demo/standard.md deleted file mode 100644 index 5c59c933..00000000 --- a/src/components/PageHeader/demo/standard.md +++ /dev/null @@ -1,102 +0,0 @@ ---- -order: 1 -title: Standard ---- - -标准页头。 - -````jsx -import PageHeader from 'ant-design-pro/lib/PageHeader'; -import DescriptionList from 'ant-design-pro/lib/DescriptionList'; -import { Button, Menu, Dropdown, Icon, Row, Col } from 'antd'; - -const { Description } = DescriptionList; -const ButtonGroup = Button.Group; - -const description = ( - - 曲丽丽 - XX 服务 - 2017-07-07 - 12421 - -); - -const menu = ( - - 选项一 - 选项二 - 选项三 - -); - -const action = ( -
- - - - - - - - -
-); - -const extra = ( - - -
状态
-
待审批
- - -
订单金额
-
¥ 568.08
- -
-); - -const breadcrumbList = [{ - title: '一级菜单', - href: '/', -}, { - title: '二级菜单', - href: '/', -}, { - title: '三级菜单', -}]; - -const tabList = [{ - key: 'detail', - tab: '详情', -}, { - key: 'rule', - tab: '规则', -}]; - -function onTabChange(key) { - console.log(key); -} - -ReactDOM.render( -
- } - action={action} - content={description} - extraContent={extra} - breadcrumbList={breadcrumbList} - tabList={tabList} - tabActiveKey="detail" - onTabChange={onTabChange} - /> -
-, mountNode); -```` - - diff --git a/src/components/PageHeader/demo/structure.md b/src/components/PageHeader/demo/structure.md deleted file mode 100644 index 429eed63..00000000 --- a/src/components/PageHeader/demo/structure.md +++ /dev/null @@ -1,68 +0,0 @@ ---- -order: 0 -title: Structure ---- - -基本结构,具备响应式布局功能,主要断点为 768px 和 576px,拖动窗口改变大小试试看。 - -````jsx -import PageHeader from 'ant-design-pro/lib/PageHeader'; - -const breadcrumbList = [{ - title: '面包屑', -}]; - -const tabList = [{ - key: '1', - tab: '页签一', -}, { - key: '2', - tab: '页签二', -}, { - key: '3', - tab: '页签三', -}]; - -ReactDOM.render( -
- Title
} - logo={
logo
} - action={
action
} - content={
content
} - extraContent={
extraContent
} - breadcrumbList={breadcrumbList} - tabList={tabList} - tabActiveKey="1" - /> - -, mountNode); -```` - - diff --git a/src/components/PageHeader/index.d.ts b/src/components/PageHeader/index.d.ts deleted file mode 100644 index fb927e74..00000000 --- a/src/components/PageHeader/index.d.ts +++ /dev/null @@ -1,31 +0,0 @@ -import React from 'react'; -import { Location } from 'history'; - -export interface PageHeaderProps { - title?: React.ReactNode | string | number; - logo?: React.ReactNode | string; - action?: React.ReactNode | string; - content?: React.ReactNode; - extraContent?: React.ReactNode; - routes?: any[]; - params?: any; - breadcrumbList?: Array<{ title: string | number; href?: string }>; - tabList?: Array<{ key: string; tab: React.ReactNode }>; - tabActiveKey?: string; - tabDefaultActiveKey?: string; - onTabChange?: (key: string) => void; - tabBarExtraContent?: React.ReactNode; - linkElement?: React.ReactNode | string; - style?: React.CSSProperties; - home?: React.ReactNode; - wide?: boolean; - hiddenBreadcrumb?: boolean; - className?: string; - loading?: boolean; - breadcrumbSeparator?: React.ReactNode; - location?: Location; - itemRender: (menuItem: any) => React.ReactNode; - breadcrumbNameMap?: any; -} - -export default class PageHeader extends React.Component {} diff --git a/src/components/PageHeader/index.js b/src/components/PageHeader/index.js deleted file mode 100644 index 17c1a7e2..00000000 --- a/src/components/PageHeader/index.js +++ /dev/null @@ -1,82 +0,0 @@ -import React, { PureComponent } from 'react'; -import { Tabs, Skeleton } from 'antd'; -import classNames from 'classnames'; -import styles from './index.less'; -import BreadcrumbView from './breadcrumb'; - -const { TabPane } = Tabs; -export default class PageHeader extends PureComponent { - onChange = key => { - const { onTabChange } = this.props; - if (onTabChange) { - onTabChange(key); - } - }; - - render() { - const { - title = '', - logo, - action, - content, - extraContent, - tabList, - className, - tabActiveKey, - tabDefaultActiveKey, - tabBarExtraContent, - loading = false, - wide = false, - hiddenBreadcrumb = false, - } = this.props; - - const clsString = classNames(styles.pageHeader, className); - const activeKeyProps = {}; - if (tabDefaultActiveKey !== undefined) { - activeKeyProps.defaultActiveKey = tabDefaultActiveKey; - } - if (tabActiveKey !== undefined) { - activeKeyProps.activeKey = tabActiveKey; - } - return ( -
-
- - {hiddenBreadcrumb ? null : } -
- {logo &&
{logo}
} -
-
-

{title}

- {action &&
{action}
} -
-
- {content &&
{content}
} - {extraContent &&
{extraContent}
} -
-
-
- {tabList && tabList.length ? ( - - {tabList.map(item => ( - - ))} - - ) : null} -
-
-
- ); - } -} diff --git a/src/components/PageHeader/index.less b/src/components/PageHeader/index.less deleted file mode 100644 index 81125bbd..00000000 --- a/src/components/PageHeader/index.less +++ /dev/null @@ -1,161 +0,0 @@ -@import '~antd/lib/style/themes/default.less'; - -.pageHeader { - padding: 16px 32px 0 32px; - background: @component-background; - border-bottom: @border-width-base @border-style-base @border-color-split; - .wide { - max-width: 1200px; - margin: auto; - } - .detail { - display: flex; - } - - .row { - display: flex; - width: 100%; - } - - .breadcrumb { - margin-bottom: 16px; - } - - .tabs { - margin: 0 0 0 -8px; - - :global { - // 1px 可以让选中效果显示完成 - .ant-tabs-bar { - margin-bottom: 1px; - border-bottom: none; - } - } - } - - .logo { - flex: 0 1 auto; - margin-right: 16px; - padding-top: 1px; - > img { - display: block; - width: 28px; - height: 28px; - border-radius: @border-radius-base; - } - } - - .title { - color: @heading-color; - font-weight: 500; - font-size: 20px; - } - - .action { - min-width: 266px; - margin-left: 56px; - - :global { - .ant-btn-group:not(:last-child), - .ant-btn:not(:last-child) { - margin-right: 8px; - } - - .ant-btn-group > .ant-btn { - margin-right: 0; - } - } - } - - .title, - .content { - flex: auto; - } - - .action, - .extraContent, - .main { - flex: 0 1 auto; - } - - .main { - width: 100%; - } - - .title, - .action { - margin-bottom: 16px; - } - - .logo, - .content, - .extraContent { - margin-bottom: 16px; - } - - .action, - .extraContent { - text-align: right; - } - - .extraContent { - min-width: 242px; - margin-left: 88px; - } -} - -@media screen and (max-width: @screen-xl) { - .pageHeader { - .extraContent { - margin-left: 44px; - } - } -} - -@media screen and (max-width: @screen-lg) { - .pageHeader { - .extraContent { - margin-left: 20px; - } - } -} - -@media screen and (max-width: @screen-md) { - .pageHeader { - .row { - display: block; - } - - .action, - .extraContent { - margin-left: 0; - text-align: left; - } - } -} - -@media screen and (max-width: @screen-sm) { - .pageHeader { - .detail { - display: block; - } - } -} - -@media screen and (max-width: @screen-xs) { - .pageHeader { - .action { - :global { - .ant-btn-group, - .ant-btn { - display: block; - margin-bottom: 8px; - } - .ant-btn-group > .ant-btn { - display: inline-block; - margin-bottom: 0; - } - } - } - } -} diff --git a/src/components/PageHeader/index.md b/src/components/PageHeader/index.md deleted file mode 100644 index 32a93426..00000000 --- a/src/components/PageHeader/index.md +++ /dev/null @@ -1,35 +0,0 @@ ---- -title: PageHeader -subtitle: 页头 -cols: 1 -order: 11 ---- - -页头用来声明页面的主题,包含了用户所关注的最重要的信息,使用户可以快速理解当前页面是什么以及它的功能。 - -## API - -| 参数 | 说明 | 类型 | 默认值 | -|----------|------------------------------------------|-------------|-------| -| title | title 区域 | ReactNode | - | -| loading | 骨架屏loading状态 | boolean | false | -| logo | logo区域 | ReactNode | - | -| action | 操作区,位于 title 行的行尾 | ReactNode | - | -| home | 默认的主页说明文字 | ReactNode | - | -| content | 内容区 | ReactNode | - | -| extraContent | 额外内容区,位于content的右侧 | ReactNode | - | -| breadcrumbList | 面包屑数据,配置了此属性时 `routes` `params` `location` `breadcrumbNameMap` 无效 | array<{title: ReactNode, href?: string}> | - | -| hiddenBreadcrumb |隐藏面包屑 | boolean | false | -| routes | 面包屑相关属性,router 的路由栈信息 | object[] | - | -| params | 面包屑相关属性,路由的参数 | object | - | -| location | 面包屑相关属性,当前的路由信息 | object | - | -| breadcrumbNameMap | 面包屑相关属性,路由的地址-名称映射表 | object | - | -| tabList | tab 标题列表 | array<{key: string, tab: ReactNode}> | - | -| tabActiveKey | 当前高亮的 tab 项 | string | - | -| tabDefaultActiveKey | 默认高亮的 tab 项 | string | 第一项 | -| wide | 是否定宽 | boolean | false | -| onTabChange | 切换面板的回调 | (key) => void | - | -| itemRender | 自定义节点方法 | (menuItem) => ReactNode | - | -| linkElement | 定义链接的元素,默认为 `a`,可传入 react-router 的 Link | string\|ReactElement | - | - -> 面包屑的配置方式有三种,一是直接配置 `breadcrumbList`,二是结合 `react-router@2` `react-router@3`,配置 `routes` 及 `params` 实现,类似 [面包屑 Demo](https://ant.design/components/breadcrumb-cn/#components-breadcrumb-demo-router),三是结合 `react-router@4`,配置 `location` `breadcrumbNameMap`,优先级依次递减,脚手架中使用最后一种。 对于后两种用法,你也可以将 `routes` `params` 及 `location` `breadcrumbNameMap` 放到 context 中,组件会自动获取。 diff --git a/src/components/PageHeader/index.test.js b/src/components/PageHeader/index.test.js deleted file mode 100644 index d22706e9..00000000 --- a/src/components/PageHeader/index.test.js +++ /dev/null @@ -1,43 +0,0 @@ -import { getBreadcrumb } from './breadcrumb'; -import { urlToList } from '../_utils/pathTools'; - -const routerData = { - '/dashboard/analysis': { - name: '分析页', - }, - '/userinfo': { - name: '用户列表', - }, - '/userinfo/:id': { - name: '用户信息', - }, - '/userinfo/:id/addr': { - name: '收货订单', - }, -}; -describe('test getBreadcrumb', () => { - it('Simple url', () => { - expect(getBreadcrumb(routerData, '/dashboard/analysis').name).toEqual('分析页'); - }); - it('Parameters url', () => { - expect(getBreadcrumb(routerData, '/userinfo/2144').name).toEqual('用户信息'); - }); - it('The middle parameter url', () => { - expect(getBreadcrumb(routerData, '/userinfo/2144/addr').name).toEqual('收货订单'); - }); - it('Loop through the parameters', () => { - const urlNameList = urlToList('/userinfo/2144/addr').map( - url => getBreadcrumb(routerData, url).name - ); - expect(urlNameList).toEqual(['用户列表', '用户信息', '收货订单']); - }); - - it('a path', () => { - const urlNameList = urlToList('/userinfo').map(url => getBreadcrumb(routerData, url).name); - expect(urlNameList).toEqual(['用户列表']); - }); - it('Secondary path', () => { - const urlNameList = urlToList('/userinfo/2144').map(url => getBreadcrumb(routerData, url).name); - expect(urlNameList).toEqual(['用户列表', '用户信息']); - }); -}); diff --git a/src/components/PageHeaderWrapper/breadcrumb.js b/src/components/PageHeaderWrapper/breadcrumb.js new file mode 100644 index 00000000..02fe66fd --- /dev/null +++ b/src/components/PageHeaderWrapper/breadcrumb.js @@ -0,0 +1,116 @@ +import React from 'react'; +import pathToRegexp from 'path-to-regexp'; +import Link from 'umi/link'; +import { FormattedMessage } from 'umi-plugin-react/locale'; +import { urlToList } from '../_utils/pathTools'; + +// 渲染Breadcrumb 子节点 +// Render the Breadcrumb child node +const itemRender = (route, params, routes, paths) => { + const last = routes.indexOf(route) === routes.length - 1; + return last || !route.component ? ( + {route.breadcrumbName} + ) : ( + {route.breadcrumbName} + ); +}; + +const renderItemLocal = item => { + if (item.locale) { + return ; + } + return item.name; +}; + +export const getBreadcrumb = (breadcrumbNameMap, url) => { + let breadcrumb = breadcrumbNameMap[url]; + if (!breadcrumb) { + Object.keys(breadcrumbNameMap).forEach(item => { + if (pathToRegexp(item).test(url)) { + breadcrumb = breadcrumbNameMap[item]; + } + }); + } + return breadcrumb || {}; +}; + +export const getBreadcrumbProps = props => { + const { routes, params, location, breadcrumbNameMap } = props; + return { + routes, + params, + routerLocation: location, + breadcrumbNameMap, + }; +}; + +// Generated according to props +const conversionFromProps = props => { + const { breadcrumbList } = props; + return breadcrumbList.map(item => { + const { title, href } = item; + return { + path: href, + breadcrumbName: title, + }; + }); +}; + +const conversionFromLocation = (routerLocation, breadcrumbNameMap, props) => { + const { home } = props; + // Convert the url to an array + const pathSnippets = urlToList(routerLocation.pathname); + // Loop data mosaic routing + const extraBreadcrumbItems = pathSnippets.map(url => { + const currentBreadcrumb = getBreadcrumb(breadcrumbNameMap, url); + if (currentBreadcrumb.inherited) { + return null; + } + const name = renderItemLocal(currentBreadcrumb); + const { hideInBreadcrumb } = currentBreadcrumb; + return name && !hideInBreadcrumb + ? { + path: url, + breadcrumbName: name, + } + : null; + }); + // Add home breadcrumbs to your head if defined + if (home) { + extraBreadcrumbItems.unshift({ + path: '/', + breadcrumbName: home, + }); + } + return extraBreadcrumbItems; +}; + +/** + * 将参数转化为面包屑 + * Convert parameters into breadcrumbs + */ +export const conversionBreadcrumbList = props => { + const { breadcrumbList } = props; + const { routes, params, routerLocation, breadcrumbNameMap } = getBreadcrumbProps(props); + if (breadcrumbList && breadcrumbList.length) { + return conversionFromProps(); + } + // 如果传入 routes 和 params 属性 + // If pass routes and params attributes + if (routes && params) { + return { + routes: routes.filter(route => route.breadcrumbName), + params, + itemRender, + }; + } + // 根据 location 生成 面包屑 + // Generate breadcrumbs based on location + if (routerLocation && routerLocation.pathname) { + return { + routes: conversionFromLocation(routerLocation, breadcrumbNameMap, props), + itemRender, + }; + } + return {}; +}; diff --git a/src/components/PageHeaderWrapper/index.js b/src/components/PageHeaderWrapper/index.js index a305e1a0..7a766834 100644 --- a/src/components/PageHeaderWrapper/index.js +++ b/src/components/PageHeaderWrapper/index.js @@ -1,40 +1,103 @@ import React from 'react'; import { FormattedMessage } from 'umi-plugin-react/locale'; import Link from 'umi/link'; -import PageHeader from '@/components/PageHeader'; +import { PageHeader, Tabs, Typography } from 'antd'; import { connect } from 'dva'; +import classNames from 'classnames'; import GridContent from './GridContent'; import styles from './index.less'; import MenuContext from '@/layouts/MenuContext'; +import { conversionBreadcrumbList } from './breadcrumb'; -const PageHeaderWrapper = ({ children, contentWidth, wrapperClassName, top, ...restProps }) => ( -
- {top} - - {value => ( - } - {...value} - key="pageheader" - {...restProps} - linkElement={Link} - itemRender={item => { - if (item.locale) { - return ; - } - return item.title; +const { Title } = Typography; + +/** + * render Footer tabList + * In order to be compatible with the old version of the PageHeader + * basically all the functions are implemented. + */ +const renderFooter = ({ tabList, activeKeyProps, onTabChange, tabBarExtraContent }) => { + return tabList && tabList.length ? ( + { + if (onTabChange) { + onTabChange(key); + } + }} + tabBarExtraContent={tabBarExtraContent} + > + {tabList.map(item => ( + + ))} + + ) : null; +}; + +const PageHeaderWrapper = ({ + children, + contentWidth, + wrapperClassName, + top, + title, + content, + logo, + extraContent, + ...restProps +}) => { + return ( +
+ {top} + {title && content && ( + + {value => { + return ( + + {title} + + } + key="pageheader" + {...restProps} + breadcrumb={conversionBreadcrumbList({ + ...value, + ...restProps, + home: , + })} + className={styles.pageHeader} + linkElement={Link} + footer={renderFooter(restProps)} + > +
+ {logo &&
{logo}
} +
+
+ {content &&
{content}
} + {extraContent &&
{extraContent}
} +
+
+
+
+ ); }} - /> +
)} - - {children ? ( -
- {children} -
- ) : null} -
-); + {children ? ( +
+ {children} +
+ ) : null} +
+ ); +}; export default connect(({ setting }) => ({ contentWidth: setting.contentWidth, diff --git a/src/components/PageHeaderWrapper/index.less b/src/components/PageHeaderWrapper/index.less index 39a44965..119585bb 100644 --- a/src/components/PageHeaderWrapper/index.less +++ b/src/components/PageHeaderWrapper/index.less @@ -1,11 +1,110 @@ @import '~antd/lib/style/themes/default.less'; -.content { +.children-content { margin: 24px 24px 0; } -@media screen and (max-width: @screen-sm) { +.main { + :global { + .ant-page-header { + padding: 16px 32px 0; + background: #fff; + border-bottom: 1px solid #e8e8e8; + } + } + + .wide { + max-width: 1200px; + margin: auto; + } + .detail { + display: flex; + } + + .row { + display: flex; + width: 100%; + } + + .logo { + flex: 0 1 auto; + margin-right: 16px; + padding-top: 1px; + > img { + display: block; + width: 28px; + height: 28px; + border-radius: @border-radius-base; + } + } + + .title-content { + margin-bottom: 16px; + } + + @media screen and (max-width: @screen-sm) { + .content { + margin: 24px 0 0; + } + } + + .title, .content { - margin: 24px 0 0; + flex: auto; + } + + .extraContent, + .main { + flex: 0 1 auto; + } + + .main { + width: 100%; + } + + .title { + margin-bottom: 16px; + } + + .logo, + .content, + .extraContent { + margin-bottom: 16px; + } + + .extraContent { + min-width: 242px; + margin-left: 88px; + text-align: right; + } +} + +@media screen and (max-width: @screen-xl) { + .extraContent { + margin-left: 44px; + } +} + +@media screen and (max-width: @screen-lg) { + .extraContent { + margin-left: 20px; + } +} + +@media screen and (max-width: @screen-md) { + .row { + display: block; + } + + .action, + .extraContent { + margin-left: 0; + text-align: left; + } +} + +@media screen and (max-width: @screen-sm) { + .detail { + display: block; } } diff --git a/src/layouts/Header.js b/src/layouts/Header.js index d6931fbb..e58d37c5 100644 --- a/src/layouts/Header.js +++ b/src/layouts/Header.js @@ -120,7 +120,10 @@ class HeaderView extends Component { const isTop = layout === 'topmenu'; const width = this.getHeadWidth(); const HeaderDom = visible ? ( -
+
{isTop && !isMobile ? (