FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

feat(Modal): Allow custom header and footer by jeff-phillips-18 · Pull Request #2120 · patternfly/patternfly-react · GitHub

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension .md  (1) .snap  (2) .ts  (1) .tsx  (6) All 4 file types selected
Viewed files
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Unified
Split
Hide whitespace
Diff view
Unified
Split
Hide whitespace
This file contains hidden or 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
Expand Up @@ -5,7 +5,8 @@ typescript: true
propComponents: ['Modal', 'ModalBox', 'ModalBoxBody', 'ModalBoxCloseButton', 'ModalBoxFooter', 'ModalBoxHeader', 'ModalContent']
---

import { Modal, Button } from '@patternfly/react-core';
import { Modal, Button, BaseSizes, TitleLevel } from '@patternfly/react-core';
import { WarningTriangleIcon } from '@patternfly/react-icons';

## Simple modal
```js
Expand Down Expand Up @@ -214,6 +215,75 @@ class WidthModal extends React.Component {
}
```

## Modal (custom header and footer)
```js
import React from 'react';
import { Modal, Button, BaseSizes, TitleLevel } from '@patternfly/react-core';

class CustomHeaderFooter extends React.Component {
constructor(props) {
super(props);
this.state = {
isModalOpen: false
};
this.handleModalToggle = () => {
this.setState(({ isModalOpen }) => ({
isModalOpen: !isModalOpen
}));
};
}

render() {
const { isModalOpen } = this.state;

const header = (
<React.Fragment>
<Title headingLevel={TitleLevel.h1} size={BaseSizes["2xl"]}>
Custom Modal Header/Footer
</Title>
<p className="pf-u-pt-sm">
Allows for custom content in the header and/or footer by passing components.
</p>
</React.Fragment>
);

const footer = (
<Title headingLevel={TitleLevel.h4} size={BaseSizes.sm}>
<WarningTriangleIcon />
<span className="pf-u-pl-sm">Custom modal footer.</span>
</Title>
);

return (
<React.Fragment>
<Button variant="primary" onClick={this.handleModalToggle}>
Show Custom Header/Footer Modal
</Button>
<Modal
isLarge
isOpen={isModalOpen}
header={header}
title="custom header example"
ariaDescribedById="custom-header-example"
onClose={this.handleModalToggle}
footer={footer}
>
<span id="custom-header-example">
When static text describing the modal is available, it can be wrapped with an ID referring to the modal's
aria-describedby value.
</span>
<br />
<br />
Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.
Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
</Modal>
</React.Fragment>
);
}
}
```

## Modal (no header)
```js
import React from 'react';
Expand Down Expand Up @@ -244,6 +314,8 @@ class NoHeader extends React.Component {
isLarge
isOpen={isModalOpen}
hideTitle={true}
title="no header example"
showClose={false}
ariaDescribedById="no-header-example"
onClose={this.handleModalToggle}
actions={[
Expand All @@ -255,7 +327,9 @@ class NoHeader extends React.Component {
<span id="no-header-example">
When static text describing the modal is available, it can be wrapped with an ID referring to the modal's
aria-describedby value.
</span>{' '}
</span>
<br />
<br />
Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.
Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
Expand Down
This file contains hidden or 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
@@ -1,5 +1,5 @@
import * as React from 'react';
import { shallow } from 'enzyme';
import { shallow, mount } from 'enzyme';
import { KEY_CODES } from '../../helpers/constants';
import { css } from '../../../../react-styles/dist/js';
import styles from '@patternfly/react-styles/css/components/Backdrop/backdrop';
Expand Down Expand Up @@ -55,3 +55,12 @@ test('modal removes body backdropOpen class when removed', () => {
view.update();
expect(document.body.className).not.toContain(css(styles.backdropOpen));
});

test('modal shows/hides the close button based on showClose (default true)', () => {
const view = mount(<Modal {...props} isOpen />);
view.update();
expect(view.exists('.pf-c-modal-box .pf-c-button')).toBeTruthy();
view.setProps({ showClose: false });
view.update();
expect(view.exists('.pf-c-modal-box .pf-c-button')).toBeFalsy();
});
This file contains hidden or 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
Expand Up @@ -15,13 +15,19 @@ export interface ModalProps extends React.HTMLProps<HTMLDivElement> {
className?: string;
/** Flag to show the modal */
isOpen?: boolean;
/** Content of the Modal Header */
/** Complex header (more than just text), supersedes title for header content */
header?: React.ReactNode,
/** Simple text content of the Modal Header, also used for aria-label on the body */
title: string;
/** Flag to hide the title */
hideTitle?: boolean;
/** Flag to show the close button in the header area of the modal */
showClose?: boolean;
/** Id to use for Modal Box description */
ariaDescribedById?: string;
/** Action buttons to put in the Modal Footer */
/** Custom footer */
footer?: React.ReactNode,
/** Action buttons to add to the standard Modal Footer, ignored if `footer` is given */
actions?: any,
/** A callback for when the close button is clicked */
onClose?: () => void;
Expand All @@ -45,6 +51,7 @@ export class Modal extends React.Component<ModalProps, ModalState> {
className: '',
isOpen: false,
hideTitle: false,
showClose: true,
ariaDescribedById: '',
actions: [] as any[],
onClose: () => undefined as any,
Expand Down
This file contains hidden or 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
Expand Up @@ -14,9 +14,7 @@ export const ModalBoxCloseButton: React.FunctionComponent<ModalBoxCloseButtonPro
onClose = () => undefined as any,
...props
}: ModalBoxCloseButtonProps) => (
<React.Fragment>
<Button className={className} variant="plain" onClick={onClose} aria-label="Close" {...props}>
<TimesIcon />
</Button>
</React.Fragment>
<Button className={className} variant="plain" onClick={onClose} aria-label="Close" {...props}>
<TimesIcon />
</Button>
);
This file contains hidden or 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
Expand Up @@ -54,3 +54,40 @@ test('Modal Content Test with onclose', () => {
);
expect(view).toMatchSnapshot();
});

test('Modal Test with custom header', () => {
const header = <span id="test-custom-header">TEST</span>;

const view = shallow(
<ModalContent
header={header}
title="test-custom-header-modal"
actions={['Testing footer']}
isLarge
onClose={() => undefined}
id="id"
isOpen
>
This is a ModalBox header
</ModalContent>
);
expect(view).toMatchSnapshot();
});

test('Modal Test with custom footer', () => {
const footer = <span id="test-custom-footer">TEST</span>;

const view = shallow(
<ModalContent
footer={footer}
title="Test Modal Custom Footer"
isLarge
onClose={() => undefined}
id="id"
isOpen
>
This is a ModalBox header
</ModalContent>
);
expect(view).toMatchSnapshot();
});
This file contains hidden or 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
Expand Up @@ -6,6 +6,7 @@ import * as React from 'react';
const FocusTrap: any = require('focus-trap-react');

import styles from '@patternfly/react-styles/css/layouts/Bullseye/bullseye';
import titleStyles from '@patternfly/react-styles/css/components/Title/title';
import { css } from '@patternfly/react-styles';

import { Backdrop } from '../Backdrop/Backdrop';
Expand All @@ -26,13 +27,19 @@ export interface ModalContentProps {
isSmall?: boolean;
/** Flag to show the modal */
isOpen?: boolean;
/** Content of the Modal Header */
/** Complex header (more than just text), supersedes title for header content */
header?: React.ReactNode,
/** Simple text content of the Modal Header, also used for aria-label on the body */
title: string;
/** Flag to show the title */
/** Flag to show the title (ignored for custom headers) */
hideTitle?: boolean;
/** Flag to show the close button in the header area of the modal */
showClose?: boolean;
/** Default width of the content. */
width?: number | string;
/** Content of the Modal Footer */
/** Custom footer */
footer?: React.ReactNode,
/** Action buttons to add to the standard Modal Footer, ignored if `footer` is given */
actions?: any,
/** A callback for when the close button is clicked */
onClose?: () => void;
Expand All @@ -46,8 +53,11 @@ export const ModalContent: React.FunctionComponent<ModalContentProps> = ({
children,
className = '',
isOpen = false,
header = null,
title,
hideTitle = false,
showClose = true,
footer = null,
actions = [],
onClose = () => undefined as any,
isLarge = false,
Expand All @@ -57,12 +67,17 @@ export const ModalContent: React.FunctionComponent<ModalContentProps> = ({
id = '',
...props
}) => {
const modalBoxHeader = <ModalBoxHeader hideTitle={hideTitle}> {title} </ModalBoxHeader>;
const modalBoxFooter = actions.length > 0 && <ModalBoxFooter> {actions} </ModalBoxFooter>;
if (!isOpen) {
return null;
}

const modalBoxHeader = header ?
<div className={css(titleStyles.title)}>{header}</div> :
<ModalBoxHeader hideTitle={hideTitle}> {title} </ModalBoxHeader>;

const modalBoxFooter = footer ?
<ModalBoxFooter>{footer}</ModalBoxFooter> :
actions.length > 0 && <ModalBoxFooter>{actions}</ModalBoxFooter>;
const boxStyle = width === -1 ? {} : { width };

return (
Expand All @@ -76,7 +91,7 @@ export const ModalContent: React.FunctionComponent<ModalContentProps> = ({
title={title}
id={ariaDescribedById || id}
>
<ModalBoxCloseButton onClose={onClose} />
{showClose && <ModalBoxCloseButton onClose={onClose} />}
{modalBoxHeader}
<ModalBoxBody {...props} id={id}>
{children}
Expand Down
This file contains hidden or 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
@@ -1,19 +1,17 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`ModalBoxCloseButton Test 1`] = `
<Fragment>
<Component
aria-label="Close"
className="test-box-close-button-class"
onClick={[MockFunction]}
variant="plain"
>
<TimesIcon
color="currentColor"
noVerticalAlign={false}
size="sm"
title={null}
/>
</Component>
</Fragment>
<Component
aria-label="Close"
className="test-box-close-button-class"
onClick={[MockFunction]}
variant="plain"
>
<TimesIcon
color="currentColor"
noVerticalAlign={false}
size="sm"
title={null}
/>
</Component>
`;
Loading

Back | FazBrowse Home | New Git URL