forked from patternfly/react-component-groups
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathContentHeader.tsx
More file actions
118 lines (112 loc) · 3.33 KB
/
ContentHeader.tsx
File metadata and controls
118 lines (112 loc) · 3.33 KB
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
import type { PropsWithChildren, FunctionComponent, ReactNode } from 'react';
import {
Flex,
FlexItem,
Split,
SplitItem,
Content,
PageSection,
Button,
ButtonVariant,
ButtonProps,
Divider,
} from '@patternfly/react-core';
import { ExternalLinkAltIcon } from '@patternfly/react-icons';
import { createUseStyles } from 'react-jss';
/** extends ButtonProps */
export interface PageHeaderLinkProps extends ButtonProps {
/** Title for the link */
label: ReactNode;
/** Indicates if the link points to an external page */
isExternal?: boolean;
}
export interface ContentHeaderProps {
/** Title for content header */
title: React.ReactNode;
/** Optional subtitle for content header */
subtitle?: React.ReactNode;
/** Optional link below subtitle */
linkProps?: PageHeaderLinkProps;
/** Optional icon for content header (appears to the left of the content header's title with a divider) */
icon?: React.ReactNode;
/** Optional label for content header (appears to the right of the content header's title) */
label?: React.ReactNode;
/** Breadcrumbs component */
breadcrumbs?: React.ReactNode;
/** Menu that appears to the far right of the title */
actionMenu?: React.ReactNode;
/** Custom OUIA ID */
ouiaId?: string | number;
}
const useStyles = createUseStyles({
iconMinWidth: {
minWidth: '48px',
}
});
export const ContentHeader: FunctionComponent<PropsWithChildren<ContentHeaderProps>> = ({
title,
subtitle = null,
linkProps,
icon,
label,
breadcrumbs = null,
actionMenu,
ouiaId = 'ContentHeader',
}: ContentHeaderProps) => {
const classes = useStyles();
const { isExternal = false, ...linkRestProps } = linkProps ?? {};
return (
<PageSection hasBodyWrapper={false}>
{ breadcrumbs && (
<div className="pf-v6-u-mb-md">
{breadcrumbs}
</div>
)}
<Flex>
{icon && (
<>
<FlexItem alignSelf={{ default: 'alignSelfCenter' }} className={`${classes.iconMinWidth}`}>
{icon}
</FlexItem>
<Divider orientation={{
default: 'vertical',
}} />
</>
)}
<FlexItem flex={{ default: 'flex_1' }}>
<Split hasGutter>
<SplitItem>
{typeof title === 'string' ? (
<Content className="pf-v6-u-mb-sm" component="h1" ouiaId={`${ouiaId}-title`}>
{title}
</Content>
) : title}
</SplitItem>
{label && (
<SplitItem>
{label}
</SplitItem>
)}
<SplitItem isFilled />
{actionMenu && (
<SplitItem>
{actionMenu}
</SplitItem>
)}
</Split>
{typeof subtitle === 'string' ? (
<Content component="p" ouiaId={`${ouiaId}-subtitle`}>
{subtitle}
</Content>
) : subtitle}
{linkProps && (
<Button variant={ButtonVariant.link} component="a" ouiaId={`${ouiaId}-link-button`} isInline icon={isExternal ? <ExternalLinkAltIcon className='pf-v6-u-ml-sm' /> : null} iconPosition="end" {...linkRestProps}>
{linkProps.label}
</Button>
)}
</FlexItem>
</Flex>
</PageSection>
);
};
export default ContentHeader;