forked from patternfly/react-component-groups
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
RHCLOUD-30755 add ContentHeader component (patternfly#143)
- Loading branch information
Showing
13 changed files
with
493 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
import React from 'react'; | ||
import ContentHeader from '../../packages/module/dist/dynamic/ContentHeader'; | ||
|
||
describe('ContentHeader', () => { | ||
it('should render ContentHeader title and subtitle', () => { | ||
cy.mount(<ContentHeader title='My title' subtitle='This is a subtitle for your content header' />); | ||
cy.get('title').should('exist') | ||
cy.get('[data-ouia-component-id="ContentHeader-title"]').should('have.text', 'My title') | ||
cy.get('[data-ouia-component-id="ContentHeader-subtitle"]').should('have.text', 'This is a subtitle for your content header') | ||
}) | ||
}); |
1 change: 1 addition & 0 deletions
1
...y-docs/content/extensions/component-groups/assets/icons/content-header-icon.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
56 changes: 56 additions & 0 deletions
56
...ocs/content/extensions/component-groups/examples/ContentHeader/ContentHeader.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
--- | ||
section: extensions | ||
subsection: Component groups | ||
id: Content header | ||
source: react | ||
propComponents: ['ContentHeader'] | ||
sourceLink: https://github.com/patternfly/react-component-groups/blob/main/packages/module/patternfly-docs/content/extensions/component-groups/examples/ContentHeader/ContentHeader.md | ||
--- | ||
|
||
import ContentHeader from "@patternfly/react-component-groups/dist/dynamic/ContentHeader" | ||
import { EllipsisVIcon } from '@patternfly/react-icons'; | ||
import contentHeaderIcon from '../../assets/icons/content-header-icon.svg' | ||
|
||
The **content header** component displays a page header section with a title, subtitle and other optional content. | ||
|
||
## Examples | ||
|
||
### Basic content header | ||
|
||
In order to display a basic content header, pass the `title` and `subtitle`. | ||
|
||
```js file="./ContentHeaderExample.tsx" | ||
|
||
``` | ||
|
||
### Content header with breadcrumbs | ||
|
||
You can display breadcrumbs above the title using the `breadcrumbs` property. | ||
|
||
```js file="./ContentHeaderBreadCrumbExample.tsx" | ||
|
||
``` | ||
|
||
### Content header with icon | ||
|
||
Use the `icon` property to display your custom page icon separated with a [divider](/components/divider). | ||
|
||
```js file="./ContentHeaderIconExample.tsx" | ||
|
||
``` | ||
|
||
### Content header with label and link | ||
|
||
To add specific element captions for user clarity and convenience, you can use the `label` property together with [label](/components/label) or your custom component. The `linkProps` can be used to define a link displayed under the subtitle. | ||
|
||
```js file="./ContentHeaderLabelLinkExample.tsx" | ||
|
||
``` | ||
|
||
### Content header with actions menu | ||
|
||
In case you want to display actions in your header, you can use the `actionsMenu` property. | ||
|
||
```js file="./ContentHeaderActionsExample.tsx" | ||
|
||
``` |
63 changes: 63 additions & 0 deletions
63
...ontent/extensions/component-groups/examples/ContentHeader/ContentHeaderActionsExample.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
import React from 'react'; | ||
import ContentHeader from '@patternfly/react-component-groups/dist/dynamic/ContentHeader'; | ||
import { ActionList, ActionListItem, Dropdown, DropdownItem, DropdownList, MenuToggle, MenuToggleElement } from '@patternfly/react-core'; | ||
import { EllipsisVIcon } from '@patternfly/react-icons'; | ||
|
||
export const ActionsExample: React.FunctionComponent = () => { | ||
const [ isOpen, setIsOpen ] = React.useState(false); | ||
|
||
const onToggle = () => { | ||
setIsOpen(!isOpen); | ||
}; | ||
|
||
const onSelect = (event: React.MouseEvent<Element, MouseEvent> | undefined) => { | ||
event?.stopPropagation(); | ||
setIsOpen(!isOpen); | ||
}; | ||
|
||
const dropdownItems = ( | ||
<> | ||
<DropdownItem to="#" key="link"> | ||
Link | ||
</DropdownItem> | ||
<DropdownItem key="action">Action</DropdownItem> | ||
<DropdownItem to="#" key="disabled link" isDisabled> | ||
Disabled Link | ||
</DropdownItem> | ||
</> | ||
); | ||
|
||
return ( | ||
<React.Fragment> | ||
<ContentHeader | ||
title='My Title' | ||
subtitle='This is a subtitle for your content header' | ||
actionMenu={ | ||
<ActionList> | ||
<ActionListItem> | ||
<Dropdown | ||
popperProps={{ position: 'right' }} | ||
onSelect={onSelect} | ||
toggle={(toggleRef: React.Ref<MenuToggleElement>) => ( | ||
<MenuToggle | ||
ref={toggleRef} | ||
onClick={onToggle} | ||
variant="plain" | ||
isExpanded={isOpen} | ||
aria-label="Action list single group kebab" | ||
> | ||
<EllipsisVIcon /> | ||
</MenuToggle> | ||
)} | ||
isOpen={isOpen} | ||
onOpenChange={(isOpen: boolean) => setIsOpen(isOpen)} | ||
> | ||
<DropdownList>{dropdownItems}</DropdownList> | ||
</Dropdown> | ||
</ActionListItem> | ||
</ActionList> | ||
} | ||
/> | ||
</React.Fragment> | ||
) | ||
}; |
34 changes: 34 additions & 0 deletions
34
...ent/extensions/component-groups/examples/ContentHeader/ContentHeaderBreadCrumbExample.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
import React from 'react'; | ||
import ContentHeader from '@patternfly/react-component-groups/dist/dynamic/ContentHeader'; | ||
import { Breadcrumb, BreadcrumbItem } from '@patternfly/react-core'; | ||
|
||
export const BreadCrumbExample: React.FunctionComponent = () => ( | ||
<ContentHeader | ||
breadcrumbs={ | ||
<Breadcrumb> | ||
<BreadcrumbItem | ||
to="/resources" | ||
key="resources" | ||
> | ||
Section home | ||
</BreadcrumbItem> | ||
<BreadcrumbItem | ||
isActive | ||
to="/resources/example-resource" | ||
key="resources-example" | ||
> | ||
Section title | ||
</BreadcrumbItem> | ||
<BreadcrumbItem | ||
isActive | ||
to="/resources/example-resource/example" | ||
key="example" | ||
> | ||
Section title | ||
</BreadcrumbItem> | ||
</Breadcrumb> | ||
} | ||
title='My Title' | ||
subtitle='This is a subtitle for your content header' | ||
/> | ||
); |
9 changes: 9 additions & 0 deletions
9
...-docs/content/extensions/component-groups/examples/ContentHeader/ContentHeaderExample.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
import React from 'react'; | ||
import ContentHeader from '@patternfly/react-component-groups/dist/dynamic/ContentHeader'; | ||
|
||
export const BasicExample: React.FunctionComponent = () => ( | ||
<ContentHeader | ||
title='My Title' | ||
subtitle='This is a subtitle for your content header' | ||
/> | ||
); |
12 changes: 12 additions & 0 deletions
12
...s/content/extensions/component-groups/examples/ContentHeader/ContentHeaderIconExample.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
import React from 'react'; | ||
import ContentHeader from '@patternfly/react-component-groups/dist/dynamic/ContentHeader'; | ||
import contentHeaderIcon from '../../assets/icons/content-header-icon.svg'; | ||
|
||
|
||
export const IconExample: React.FunctionComponent = () => ( | ||
<ContentHeader | ||
title='My Title' | ||
subtitle='This is a subtitle for your content header' | ||
icon={<img src={contentHeaderIcon} alt="content-header-icon" />} | ||
/> | ||
); |
15 changes: 15 additions & 0 deletions
15
...tent/extensions/component-groups/examples/ContentHeader/ContentHeaderLabelLinkExample.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
import React from 'react'; | ||
import ContentHeader from '@patternfly/react-component-groups/dist/dynamic/ContentHeader'; | ||
import { Label } from '@patternfly/react-core'; | ||
|
||
export const BasicExample: React.FunctionComponent = () => ( | ||
<ContentHeader | ||
title='My Title' | ||
subtitle='This is a subtitle for your content header' | ||
label={<Label className="pf-v5-u-align-content-center">Org. Administrator</Label>} | ||
linkProps={{ | ||
label: 'Go to this link', | ||
isExternal: true, | ||
}} | ||
/> | ||
); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
import React from 'react'; | ||
import { render } from '@testing-library/react'; | ||
import ContentHeader from './ContentHeader'; | ||
|
||
describe('Contentheader component', () => { | ||
test('should render', () => { | ||
expect(render(<ContentHeader title='My title' subtitle='This is a subtitle for your content header' />)).toMatchSnapshot(); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,116 @@ | ||
import React from 'react'; | ||
import { | ||
Flex, | ||
FlexItem, | ||
Split, | ||
SplitItem, | ||
Text, | ||
PageSection, | ||
TextContent, | ||
Button, | ||
ButtonVariant, | ||
ButtonProps, | ||
Divider, | ||
} from '@patternfly/react-core'; | ||
import { ExternalLinkAltIcon } from '@patternfly/react-icons'; | ||
import { createUseStyles } from 'react-jss'; | ||
|
||
export interface PageHeaderLinkProps extends ButtonProps { | ||
/** Title for the link */ | ||
label: string; | ||
/** Indicates if the link points to an external page */ | ||
isExternal?: boolean; | ||
} | ||
|
||
export interface ContentHeaderProps { | ||
/** Title for content header */ | ||
title: string; | ||
/** Subtitle for content header */ | ||
subtitle: string; | ||
/** 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: React.FunctionComponent<React.PropsWithChildren<ContentHeaderProps>> = ({ | ||
title, | ||
subtitle, | ||
linkProps, | ||
icon, | ||
label, | ||
breadcrumbs = null, | ||
actionMenu, | ||
ouiaId = 'ContentHeader', | ||
}: ContentHeaderProps) => { | ||
const classes = useStyles(); | ||
|
||
return ( | ||
<PageSection variant="light"> | ||
{ breadcrumbs && ( | ||
<div className="pf-v5-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> | ||
<TextContent> | ||
<Text className="pf-v5-u-mb-sm" component="h1" ouiaId={`${ouiaId}-title`}> | ||
{title} | ||
</Text> | ||
</TextContent> | ||
</SplitItem> | ||
{label && ( | ||
<SplitItem> | ||
{label} | ||
</SplitItem> | ||
)} | ||
<SplitItem isFilled /> | ||
{actionMenu && ( | ||
<SplitItem> | ||
{actionMenu} | ||
</SplitItem> | ||
)} | ||
</Split> | ||
<TextContent> | ||
<Text component="p" ouiaId={`${ouiaId}-subtitle`}> | ||
{subtitle} | ||
</Text> | ||
{linkProps && ( | ||
<Button variant={ButtonVariant.link} ouiaId={`${ouiaId}-link-button`} isInline icon={linkProps.isExternal ? <ExternalLinkAltIcon /> : null} iconPosition="end" {...linkProps}> | ||
{linkProps.label} | ||
</Button> | ||
)} | ||
</TextContent> | ||
</FlexItem> | ||
</Flex> | ||
</PageSection> | ||
)}; | ||
|
||
export default ContentHeader; |
Oops, something went wrong.