/
index.tsx
129 lines (117 loc) · 3.89 KB
/
index.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
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
import * as React from 'react';
import classnames from 'classnames';
import { ConfigConsumer, ConfigConsumerProps } from '../config-provider';
import Icon from '../icon';
import Tag from '../tag';
import Breadcrumb, { BreadcrumbProps } from '../breadcrumb';
import Avatar, { AvatarProps } from '../avatar';
import TransButton from '../_util/transButton';
import LocaleReceiver from '../locale-provider/LocaleReceiver';
export interface PageHeaderProps {
backIcon?: React.ReactNode;
prefixCls?: string;
title: React.ReactNode;
subTitle?: React.ReactNode;
style?: React.CSSProperties;
breadcrumb?: BreadcrumbProps;
tags?: React.ReactElement<Tag> | React.ReactElement<Tag>[];
footer?: React.ReactNode;
extra?: React.ReactNode;
avatar?: AvatarProps;
onBack?: (e: React.MouseEvent<HTMLDivElement>) => void;
className?: string;
ghost?: boolean;
}
const renderBack = (
prefixCls: string,
backIcon?: React.ReactNode,
onBack?: (e: React.MouseEvent<HTMLElement>) => void,
) => {
if (!backIcon || !onBack) {
return null;
}
return (
<LocaleReceiver componentName="PageHeader">
{({ back }: { back: string }) => (
<div className={`${prefixCls}-back`}>
<TransButton
onClick={(e: React.MouseEvent<HTMLDivElement>) => {
if (onBack) {
onBack(e);
}
}}
className={`${prefixCls}-back-button`}
aria-label={back}
>
{backIcon}
</TransButton>
</div>
)}
</LocaleReceiver>
);
};
const renderBreadcrumb = (breadcrumb: BreadcrumbProps) => {
return <Breadcrumb {...breadcrumb} />;
};
const renderTitle = (prefixCls: string, props: PageHeaderProps) => {
const { title, avatar, subTitle, tags, extra, backIcon, onBack } = props;
const headingPrefixCls = `${prefixCls}-heading`;
if (title || subTitle || tags || extra) {
const backIconDom = renderBack(prefixCls, backIcon, onBack);
return (
<div className={headingPrefixCls}>
{backIconDom}
{avatar && <Avatar {...avatar} />}
{title && <span className={`${headingPrefixCls}-title`}>{title}</span>}
{subTitle && <span className={`${headingPrefixCls}-sub-title`}>{subTitle}</span>}
{tags && <span className={`${headingPrefixCls}-tags`}>{tags}</span>}
{extra && <span className={`${headingPrefixCls}-extra`}>{extra}</span>}
</div>
);
}
return null;
};
const renderFooter = (prefixCls: string, footer: React.ReactNode) => {
if (footer) {
return <div className={`${prefixCls}-footer`}>{footer}</div>;
}
return null;
};
const renderChildren = (prefixCls: string, children: React.ReactNode) => {
return <div className={`${prefixCls}-content`}>{children}</div>;
};
const PageHeader: React.SFC<PageHeaderProps> = props => (
<ConfigConsumer>
{({ getPrefixCls, pageHeader = { ghost: true } }: ConfigConsumerProps) => {
const {
prefixCls: customizePrefixCls,
style,
footer,
children,
ghost = true,
breadcrumb,
className: customizeClassName,
} = props;
const prefixCls = getPrefixCls('page-header', customizePrefixCls);
const breadcrumbDom = breadcrumb && breadcrumb.routes ? renderBreadcrumb(breadcrumb) : null;
const className = classnames(prefixCls, customizeClassName, {
'has-breadcrumb': breadcrumbDom,
'has-footer': footer,
// 防止设置为 null 报错
ghost: ghost || (pageHeader && ghost === undefined && pageHeader.ghost),
});
return (
<div className={className} style={style}>
{breadcrumbDom}
{renderTitle(prefixCls, props)}
{children && renderChildren(prefixCls, children)}
{renderFooter(prefixCls, footer)}
</div>
);
}}
</ConfigConsumer>
);
PageHeader.defaultProps = {
backIcon: <Icon type="arrow-left" />,
};
export default PageHeader;