Skip to content

Commit 1da6fc2

Browse files
authored
feat(Compass): add CompassMainFooter (#12137)
* feat(Compass): add CompassMainFooter * add tests * add isExpanded to CompassMainFooter * add max height to examples
1 parent 754bcb0 commit 1da6fc2

File tree

8 files changed

+156
-3
lines changed

8 files changed

+156
-3
lines changed
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import styles from '@patternfly/react-styles/css/components/Compass/compass';
2+
import { css } from '@patternfly/react-styles';
3+
4+
interface CompassMainFooterProps extends Omit<React.HTMLProps<HTMLDivElement>, 'title'> {
5+
/** Additional classes added to the main footer */
6+
className?: string;
7+
/** Main footer content */
8+
children?: React.ReactNode;
9+
/** Indicates if the main footer is expanded */
10+
isExpanded?: boolean;
11+
}
12+
13+
export const CompassMainFooter: React.FunctionComponent<CompassMainFooterProps> = ({
14+
className,
15+
children,
16+
isExpanded = true,
17+
...props
18+
}) => (
19+
<div className={css(styles.compassMainFooter, isExpanded && 'pf-m-expanded', className)} {...props}>
20+
{children}
21+
</div>
22+
);
23+
24+
CompassMainFooter.displayName = 'CompassMainFooter';
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
import { render, screen } from '@testing-library/react';
2+
import { CompassMainFooter } from '../CompassMainFooter';
3+
import styles from '@patternfly/react-styles/css/components/Compass/compass';
4+
5+
test('Renders without children', () => {
6+
render(
7+
<div data-testid="test-main-footer">
8+
<CompassMainFooter />
9+
</div>
10+
);
11+
expect(screen.getByTestId('test-main-footer').firstChild).toBeVisible();
12+
});
13+
14+
test('Renders with children', () => {
15+
render(<CompassMainFooter>Custom content</CompassMainFooter>);
16+
expect(screen.getByText('Custom content')).toBeVisible();
17+
});
18+
19+
test('Renders with custom class name when className prop is provided', () => {
20+
render(<CompassMainFooter className="custom-class">Test</CompassMainFooter>);
21+
expect(screen.getByText('Test')).toHaveClass('custom-class');
22+
});
23+
24+
test(`Renders with default ${styles.compassMainFooter} class`, () => {
25+
render(<CompassMainFooter>Test</CompassMainFooter>);
26+
expect(screen.getByText('Test')).toHaveClass(styles.compassMainFooter);
27+
});
28+
29+
test(`Renders with pf-m-expanded class by default`, () => {
30+
render(<CompassMainFooter>Test</CompassMainFooter>);
31+
expect(screen.getByText('Test')).toHaveClass('pf-m-expanded');
32+
});
33+
34+
test(`Renders with pf-m-expanded class when isExpanded is true`, () => {
35+
render(<CompassMainFooter isExpanded>Test</CompassMainFooter>);
36+
expect(screen.getByText('Test')).toHaveClass('pf-m-expanded');
37+
});
38+
39+
test(`Renders without pf-m-expanded class when isExpanded is false`, () => {
40+
render(<CompassMainFooter isExpanded={false}>Test</CompassMainFooter>);
41+
expect(screen.getByText('Test')).not.toHaveClass('pf-m-expanded');
42+
});
43+
44+
test('Renders with additional props spread to the component', () => {
45+
render(<CompassMainFooter aria-label="Test label">Test</CompassMainFooter>);
46+
expect(screen.getByText('Test')).toHaveAccessibleName('Test label');
47+
});
48+
49+
test('Matches the snapshot', () => {
50+
const { asFragment } = render(<CompassMainFooter>Custom children content</CompassMainFooter>);
51+
expect(asFragment()).toMatchSnapshot();
52+
});
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// Jest Snapshot v1, https://goo.gl/fbAQLP
2+
3+
exports[`Matches the snapshot 1`] = `
4+
<DocumentFragment>
5+
<div
6+
class="pf-v6-c-compass__main-footer pf-m-expanded"
7+
>
8+
Custom children content
9+
</div>
10+
</DocumentFragment>
11+
`;

packages/react-core/src/components/Compass/examples/Compass.md

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,14 @@ propComponents:
1616
]
1717
---
1818

19-
import './compass.css';
2019
import { useRef, useState } from 'react';
2120
import PlayIcon from '@patternfly/react-icons/dist/esm/icons/play-icon';
2221
import OutlinedPlusSquare from '@patternfly/react-icons/dist/esm/icons/outlined-plus-square-icon';
2322
import OutlinedCopy from '@patternfly/react-icons/dist/esm/icons/outlined-copy-icon';
2423
import OutlinedQuestionCircleIcon from '@patternfly/react-icons/dist/esm/icons/outlined-question-circle-icon';
2524

25+
import './compass.css';
26+
2627
## Examples
2728

2829
### Basic
@@ -41,6 +42,14 @@ The background image of the `Compass` and `CompassHero` may be customized by usi
4142

4243
```
4344

45+
### With alternate footer
46+
47+
When `footer` is used, its content will take up the width of the screen. However, if content inside of the footer grows, then the two sidebars' heights and placement will adjust to allow for the change. If this is not the desired behavior, then using a `CompassMainFooter` inside of the of the `main` section provides an alterate way to render footer content without interfering with the sidebars, by rendering content at the bottom of the page between the two sidebars opposed to the whole bottom of the page.
48+
49+
```ts file="CompassMainFooterDemo.tsx"
50+
51+
```
52+
4453
### Demo
4554

4655
```ts isFullscreen file="CompassDemo.tsx"

packages/react-core/src/components/Compass/examples/CompassBasic.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ export const CompassBasic: React.FunctionComponent = () => {
4040
main={mainContent}
4141
sidebarEnd={sidebarEndContent}
4242
footer={footerContent}
43+
style={{ height: '600px' }}
4344
/>
4445
);
4546
};
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import {
2+
Compass,
3+
CompassHeader,
4+
CompassHero,
5+
CompassContent,
6+
CompassMainHeader,
7+
CompassMainFooter
8+
} from '@patternfly/react-core';
9+
import './compass.css';
10+
11+
export const CompassMainFooterDemo: React.FunctionComponent = () => {
12+
const headerContent = <CompassHeader logo={<div>Logo</div>} nav={<div>Nav</div>} profile={<div>Profile</div>} />;
13+
const sidebarStartContent = <div>Sidebar start</div>;
14+
// TODO: simplify mainContent to only a div string
15+
const mainContent = (
16+
<>
17+
<CompassHero>
18+
<div>Hero</div>
19+
</CompassHero>
20+
<CompassContent>
21+
<CompassMainHeader>
22+
<div>Content title</div>
23+
</CompassMainHeader>
24+
<div>Content</div>
25+
</CompassContent>
26+
<CompassMainFooter>
27+
<div>Footer</div>
28+
</CompassMainFooter>
29+
</>
30+
);
31+
const sidebarEndContent = <div>Sidebar end</div>;
32+
33+
return (
34+
<Compass
35+
header={headerContent}
36+
sidebarStart={sidebarStartContent}
37+
main={mainContent}
38+
sidebarEnd={sidebarEndContent}
39+
isFooterExpanded={false}
40+
style={{ height: '600px' }}
41+
/>
42+
);
43+
};

packages/react-core/src/components/Compass/examples/compass.css

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,20 @@
1-
#ws-react-c-compass-basic [class*="pf-v6-c-compass"] {
1+
#ws-react-p-compass-basic [class*="pf-v6-c-compass"] {
22
position: relative;
33
}
44

5-
#ws-react-c-compass-basic [class*="pf-v6-c-compass"]::after {
5+
#ws-react-p-compass-basic [class*="pf-v6-c-compass"]::after {
6+
content: "";
7+
position: absolute;
8+
inset: 0;
9+
border: var(--pf-t--global--border--width--regular) dashed var(--pf-t--global--border--color--default);
10+
pointer-events: none;
11+
}
12+
13+
#ws-react-p-compass-with-alternate-footer [class*="pf-v6-c-compass"] {
14+
position: relative;
15+
}
16+
17+
#ws-react-p-compass-with-alternate-footer [class*="pf-v6-c-compass"]:not([class*="footer"])::after {
618
content: "";
719
position: absolute;
820
inset: 0;

packages/react-core/src/components/Compass/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ export * from './CompassMainHeader';
66
export * from './CompassMainHeaderContent';
77
export * from './CompassMainHeaderTitle';
88
export * from './CompassMainHeaderToolbar';
9+
export * from './CompassMainFooter';
910
export * from './CompassMessageBar';
1011
export * from './CompassNavContent';
1112
export * from './CompassNavHome';

0 commit comments

Comments
 (0)