Skip to content

Commit d944ffb

Browse files
committed
feat(Compass): add Compass components
1 parent e78f9c4 commit d944ffb

13 files changed

Lines changed: 415 additions & 0 deletions

File tree

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
import { Drawer, DrawerContent, DrawerProps } from '../Drawer';
2+
import { css } from '@patternfly/react-styles';
3+
4+
export interface CompassProps extends React.HTMLProps<HTMLDivElement> {
5+
/** Additional classes added to the compass. */
6+
className?: string;
7+
/** Content placed at the top of the layout */
8+
header?: React.ReactNode;
9+
/** Flag indicating if the header is expanded */
10+
isHeaderExpanded?: boolean;
11+
/** Content placed at the start of the layout */
12+
panelStart?: React.ReactNode;
13+
/** Flag indicating if the start panel is expanded */
14+
isPanelStartExpanded?: boolean;
15+
/** Content placed at the center of the layout */
16+
main?: React.ReactNode;
17+
/** Content placed at the end of the layout */
18+
panelEnd?: React.ReactNode;
19+
/** Flag indicating if the end panel is expanded */
20+
isPanelEndExpanded?: boolean;
21+
/** Content placed at the bottom of the layout */
22+
footer?: React.ReactNode;
23+
/** Flag indicating if the footer is expanded */
24+
isFooterExpanded?: boolean;
25+
/** Content rendered in the drawer panel */
26+
drawerContent?: React.ReactNode;
27+
/** Props for the drawer */
28+
drawerProps?: DrawerProps;
29+
}
30+
31+
export const Compass: React.FunctionComponent<CompassProps> = ({
32+
className,
33+
header,
34+
isHeaderExpanded = true,
35+
panelStart,
36+
isPanelStartExpanded = true,
37+
main,
38+
panelEnd,
39+
isPanelEndExpanded = true,
40+
footer,
41+
isFooterExpanded = true,
42+
drawerContent,
43+
drawerProps,
44+
...props
45+
}) => {
46+
const hasDrawer = drawerContent !== undefined;
47+
48+
const compassContent = (
49+
<div className={css('pf-v6-c-compass', className)} {...props}>
50+
<div
51+
className={css('pf-v6-c-compass__header', isHeaderExpanded && 'pf-m-expanded')}
52+
{...(!isHeaderExpanded && { inert: true })}
53+
>
54+
{header}
55+
</div>
56+
<div
57+
className={css('pf-v6-c-compass__panel pf-m-start', isPanelStartExpanded && 'pf-m-expanded')}
58+
{...(!isPanelStartExpanded && { inert: true })}
59+
>
60+
{panelStart}
61+
</div>
62+
<div className={css('pf-v6-c-compass__main')}>{main}</div>
63+
<div
64+
className={css('pf-v6-c-compass__panel pf-m-end', isPanelEndExpanded && 'pf-m-expanded')}
65+
{...(!isPanelEndExpanded && { inert: true })}
66+
>
67+
{panelEnd}
68+
</div>
69+
<div
70+
className={css('pf-v6-c-compass__footer', isFooterExpanded && 'pf-m-expanded')}
71+
{...(!isFooterExpanded && { inert: true })}
72+
>
73+
{footer}
74+
</div>
75+
</div>
76+
);
77+
78+
if (hasDrawer) {
79+
return (
80+
<Drawer {...drawerProps}>
81+
<DrawerContent panelContent={drawerContent}>{compassContent}</DrawerContent>
82+
</Drawer>
83+
);
84+
}
85+
86+
return compassContent;
87+
};
88+
89+
Compass.displayName = 'Compass';
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import { Drawer, DrawerContent, DrawerProps } from '../Drawer';
2+
import { css } from '@patternfly/react-styles';
3+
4+
interface CompassContentProps extends React.HTMLProps<HTMLDivElement> {
5+
/** Content. Typically CompassSection components. */
6+
children: React.ReactNode;
7+
/** Additional classes added to the component */
8+
className?: string;
9+
/** Content of the drawer */
10+
drawerContent?: React.ReactNode;
11+
/** Additional props passed to the drawer */
12+
drawerProps?: DrawerProps;
13+
}
14+
15+
export const CompassContent: React.FunctionComponent<CompassContentProps> = ({
16+
children,
17+
className,
18+
drawerProps,
19+
drawerContent,
20+
...props
21+
}) => {
22+
const hasDrawer = drawerContent !== undefined;
23+
24+
const compassContent = (
25+
<div className={css('pf-v6-c-compass__content', className)} {...props}>
26+
{children}
27+
</div>
28+
);
29+
30+
if (hasDrawer) {
31+
return (
32+
<Drawer {...drawerProps}>
33+
<DrawerContent panelContent={drawerContent}>{compassContent}</DrawerContent>
34+
</Drawer>
35+
);
36+
}
37+
38+
return compassContent;
39+
};
40+
41+
CompassContent.displayName = 'CompassContent';
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import { css } from '@patternfly/react-styles';
2+
3+
interface CompassGlassProps {
4+
/** Content that should have a glass effect */
5+
children: React.ReactNode;
6+
/** Additional classes added to the container */
7+
className?: string;
8+
}
9+
10+
export const CompassGlass: React.FunctionComponent<CompassGlassProps> = ({ children, className }) => (
11+
<div className={css('pf-v6-c-compass__glass', className)}>{children}</div>
12+
);
13+
14+
CompassGlass.displayName = 'CompassGlass';
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import { css } from '@patternfly/react-styles';
2+
3+
interface CompassHeaderProps {
4+
/** Content for the logo area */
5+
logo?: React.ReactNode;
6+
/** Content for the navigation area */
7+
nav?: React.ReactNode;
8+
/** Content for the profile area */
9+
profile?: React.ReactNode;
10+
}
11+
12+
export const CompassHeader: React.FunctionComponent<CompassHeaderProps> = ({ logo, nav, profile }) => (
13+
<>
14+
<div className={css('pf-v6-c-compass__logo')}>{logo}</div>
15+
<div className={css('pf-v6-c-compass__nav')}>{nav}</div>
16+
<div className={css('pf-v6-c-compass__profile')}>{profile}</div>
17+
</>
18+
);
19+
20+
CompassHeader.displayName = 'CompassHeader';
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import { Flex, FlexItem } from '../../layouts/Flex';
2+
import { css } from '@patternfly/react-styles';
3+
4+
interface CompassHeroProps extends Omit<React.HTMLProps<HTMLDivElement>, 'content'> {
5+
/** Additional classes added to the hero. */
6+
className?: string;
7+
/** Styled hero content. If provided, the children prop will be ignored. */
8+
content?: React.ReactNode;
9+
/** Custom hero content. To opt into a default set of styling, use the content prop instead. */
10+
children?: React.ReactNode;
11+
}
12+
13+
export const CompassHero: React.FunctionComponent<CompassHeroProps> = ({ className, children, content, ...props }) => {
14+
if (content !== undefined) {
15+
return (
16+
<div className={css('pf-v6-c-compass__hero', className)} {...props}>
17+
<div className={css('pf-v6-c-compass__hero-body')}>
18+
<Flex>
19+
<FlexItem grow={{ default: 'grow' }}>{content}</FlexItem>
20+
</Flex>
21+
</div>
22+
</div>
23+
);
24+
}
25+
26+
return (
27+
<div className={css('pf-v6-c-compass__hero', className)} {...props}>
28+
<div className={css('pf-v6-c-compass__hero-body')}>{children}</div>
29+
</div>
30+
);
31+
};
32+
33+
CompassHero.displayName = 'CompassHero';
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import { Flex, FlexItem } from '../../layouts/Flex';
2+
import { css } from '@patternfly/react-styles';
3+
4+
interface CompassMainHeaderProps extends Omit<React.HTMLProps<HTMLDivElement>, 'title'> {
5+
/** Additional classes added to the main header. */
6+
className?: string;
7+
/** Styled title. If title or toolbar is provided, the children will be ignored. */
8+
title?: React.ReactNode;
9+
/** Styled toolbar. If title or toolbar is provided, the children will be ignored. */
10+
toolbar?: React.ReactNode;
11+
/** Custom main header content. To opt into a default set of styling, use the title and toolbar props instead. */
12+
children?: React.ReactNode;
13+
}
14+
15+
export const CompassMainHeader: React.FunctionComponent<CompassMainHeaderProps> = ({
16+
className,
17+
title,
18+
toolbar,
19+
children,
20+
...props
21+
}) => {
22+
if (title !== undefined || toolbar !== undefined) {
23+
return (
24+
<div className={css('pf-v6-c-compass__main-header', className)} {...props}>
25+
<Flex alignItems={{ default: 'alignItemsCenter' }}>
26+
<FlexItem grow={{ default: 'grow' }}>{title}</FlexItem>
27+
<FlexItem>{toolbar}</FlexItem>
28+
</Flex>
29+
</div>
30+
);
31+
}
32+
33+
return (
34+
<div className={css('pf-v6-c-compass__main-header', className)} {...props}>
35+
{children}
36+
</div>
37+
);
38+
};
39+
40+
CompassMainHeader.displayName = 'CompassMainHeader';
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import { css } from '@patternfly/react-styles';
2+
3+
interface CompassSectionProps extends React.HTMLProps<HTMLDivElement> {
4+
/** Additional classes added to the section. */
5+
className?: string;
6+
/** Content of the section. */
7+
children: React.ReactNode;
8+
}
9+
10+
export const CompassSection: React.FunctionComponent<CompassSectionProps> = ({ children, className, ...props }) => (
11+
<div className={css('pf-v6-c-compass__section', className)} {...props}>
12+
{children}
13+
</div>
14+
);
15+
16+
CompassSection.displayName = 'CompassSection';
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
---
2+
id: Compass
3+
cssPrefix: pf-v6-c-compass
4+
section: layouts
5+
propComponents: ['Compass', 'CompassHeader', 'CompassContent', 'CompassHero', 'CompassMainHeader', 'CompassSection']
6+
---
7+
8+
import './compass.css';
9+
import PlayIcon from '@patternfly/react-icons/dist/esm/icons/play-icon';
10+
import OutlinedPlusSquare from '@patternfly/react-icons/dist/esm/icons/outlined-plus-square-icon';
11+
import OutlinedCopy from '@patternfly/react-icons/dist/esm/icons/outlined-copy-icon';
12+
import OutlinedQuestionCircleIcon from '@patternfly/react-icons/dist/esm/icons/outlined-question-circle-icon';
13+
14+
## Examples
15+
16+
### Basic
17+
18+
```ts file="CompassBasic.tsx"
19+
20+
```
21+
22+
### Demo
23+
24+
```ts isFullscreen file="CompassDemo.tsx"
25+
26+
```
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import {
2+
Compass,
3+
CompassHeader,
4+
CompassHero,
5+
CompassContent,
6+
CompassMainHeader,
7+
CompassSection
8+
} from '@patternfly/react-core';
9+
10+
export const CompassBasic: React.FunctionComponent = () => {
11+
const headerContent = <CompassHeader logo={<div>Logo</div>} nav={<div>Nav</div>} profile={<div>Profile</div>} />;
12+
const panelStartContent = <div>Panel start</div>;
13+
const mainContent = (
14+
<>
15+
<CompassHero>
16+
<div>Hero</div>
17+
</CompassHero>
18+
<CompassContent>
19+
<CompassMainHeader title="Content title" />
20+
<CompassSection>Content</CompassSection>
21+
</CompassContent>
22+
</>
23+
);
24+
const panelEndContent = <div>Panel end</div>;
25+
const footerContent = <div>Footer</div>;
26+
27+
return (
28+
<Compass
29+
header={headerContent}
30+
panelStart={panelStartContent}
31+
main={mainContent}
32+
panelEnd={panelEndContent}
33+
footer={footerContent}
34+
/>
35+
);
36+
};

0 commit comments

Comments
 (0)