index.js 4.45 KB
Newer Older
偏右's avatar
偏右 committed
1
import React, { PureComponent, createElement } from 'react';
2 3 4 5 6
import PropTypes from 'prop-types';
import { Breadcrumb, Tabs } from 'antd';
import classNames from 'classnames';
import styles from './index.less';

afc163's avatar
afc163 committed
7
const { TabPane } = Tabs;
8 9 10 11 12

export default class PageHeader extends PureComponent {
  static contextTypes = {
    routes: PropTypes.array,
    params: PropTypes.object,
ddcat1115's avatar
ddcat1115 committed
13 14
    location: PropTypes.object,
    breadcrumbNameMap: PropTypes.object,
15 16 17 18 19 20 21 22 23 24
  };
  onChange = (key) => {
    if (this.props.onTabChange) {
      this.props.onTabChange(key);
    }
  };
  getBreadcrumbProps = () => {
    return {
      routes: this.props.routes || this.context.routes,
      params: this.props.params || this.context.params,
ddcat1115's avatar
ddcat1115 committed
25 26
      location: this.props.location || this.context.location,
      breadcrumbNameMap: this.props.breadcrumbNameMap || this.context.breadcrumbNameMap,
27 28
    };
  };
偏右's avatar
偏右 committed
29 30 31 32 33 34 35 36 37 38
  itemRender = (route, params, routes, paths) => {
    const { linkElement = 'a' } = this.props;
    const last = routes.indexOf(route) === routes.length - 1;
    return (last || !route.component)
      ? <span>{route.breadcrumbName}</span>
      : createElement(linkElement, {
        href: paths.join('/') || '/',
        to: paths.join('/') || '/',
      }, route.breadcrumbName);
  }
39
  render() {
ddcat1115's avatar
ddcat1115 committed
40
    const { routes, params, location, breadcrumbNameMap } = this.getBreadcrumbProps();
偏右's avatar
偏右 committed
41 42 43 44
    const {
      title, logo, action, content, extraContent,
      breadcrumbList, tabList, className, linkElement = 'a',
    } = this.props;
45 46 47 48 49 50 51 52
    const clsString = classNames(styles.pageHeader, className);
    let breadcrumb;
    if (routes && params) {
      breadcrumb = (
        <Breadcrumb
          className={styles.breadcrumb}
          routes={routes.filter(route => route.breadcrumbName)}
          params={params}
偏右's avatar
偏右 committed
53
          itemRender={this.itemRender}
54 55
        />
      );
ddcat1115's avatar
ddcat1115 committed
56 57 58 59 60 61
    } else if (location && location.pathname) {
      const pathSnippets = location.pathname.split('/').filter(i => i);
      const extraBreadcrumbItems = pathSnippets.map((_, index) => {
        const url = `/${pathSnippets.slice(0, index + 1).join('/')}`;
        return (
          <Breadcrumb.Item key={url}>
afc163's avatar
afc163 committed
62 63
            {createElement(index === pathSnippets.length - 1 ? 'span' : linkElement, {
              [linkElement === 'a' ? 'href' : 'to']: url,
偏右's avatar
偏右 committed
64
            }, breadcrumbNameMap[url] || breadcrumbNameMap[url.replace('/', '')] || url)}
ddcat1115's avatar
ddcat1115 committed
65 66 67 68 69
          </Breadcrumb.Item>
        );
      });
      const breadcrumbItems = [(
        <Breadcrumb.Item key="home">
偏右's avatar
偏右 committed
70
          {createElement(linkElement, {
afc163's avatar
afc163 committed
71
            [linkElement === 'a' ? 'href' : 'to']: '/',
偏右's avatar
偏右 committed
72
          }, 'ι¦–ι‘΅')}
ddcat1115's avatar
ddcat1115 committed
73 74 75 76 77 78 79
        </Breadcrumb.Item>
      )].concat(extraBreadcrumbItems);
      breadcrumb = (
        <Breadcrumb className={styles.breadcrumb}>
          {breadcrumbItems}
        </Breadcrumb>
      );
80 81 82 83 84
    } else if (breadcrumbList && breadcrumbList.length) {
      breadcrumb = (
        <Breadcrumb className={styles.breadcrumb}>
          {
            breadcrumbList.map(item => (
85
              <Breadcrumb.Item key={item.title}>
afc163's avatar
afc163 committed
86 87 88 89 90
                {item.href ? (
                  createElement(linkElement, {
                    [linkElement === 'a' ? 'href' : 'to']: item.href,
                  }, 'ι¦–ι‘΅')
                ) : item.title}
91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134
              </Breadcrumb.Item>)
            )
          }
        </Breadcrumb>
      );
    } else {
      breadcrumb = null;
    }

    const tabDefaultValue = tabList && tabList.filter(item => item.default)[0];

    return (
      <div className={clsString}>
        {breadcrumb}
        <div className={styles.detail}>
          {logo && <div className={styles.logo}>{logo}</div>}
          <div className={styles.main}>
            <div className={styles.row}>
              {title && <h1 className={styles.title}>{title}</h1>}
              {action && <div className={styles.action}>{action}</div>}
            </div>
            <div className={styles.row}>
              {content && <div className={styles.content}>{content}</div>}
              {extraContent && <div className={styles.extraContent}>{extraContent}</div>}
            </div>
          </div>
        </div>
        {
          tabList &&
          tabList.length &&
          <Tabs
            className={styles.tabs}
            defaultActiveKey={(tabDefaultValue && tabDefaultValue.key)}
            onChange={this.onChange}
          >
            {
              tabList.map(item => <TabPane tab={item.tab} key={item.key} />)
            }
          </Tabs>
        }
      </div>
    );
  }
}