Skip to content

Commit

Permalink
Merge pull request #62 from fhlavac/warningModal
Browse files Browse the repository at this point in the history
feat(WarningModal): Add warning modal component
  • Loading branch information
Hyperkid123 authored Oct 24, 2023
2 parents dc22fb3 + 329ce6c commit d4984bd
Show file tree
Hide file tree
Showing 7 changed files with 305 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
---
# Sidenav top-level section
# should be the same for all markdown files
section: extensions
subsection: Component groups
# Sidenav secondary level section
# should be the same for all markdown files
id: Warning modal
# Tab (react | react-demos | html | html-demos | design-guidelines | accessibility)
source: react
# If you use typescript, the name of the interface to display props for
# These are found through the sourceProps function provided in patternfly-docs.source.js
propComponents: ['WarningModal']
---

import WarningModal from '@patternfly/react-component-groups/dist/dynamic/WarningModal';

A **warning modal** component displays a modal asking user to confirm his intention to perform a risky action.

## Examples

### Basic warning modal

A basic warning modal component provides users with a basic layout to which only specific texts need to be passed.
Action buttons callbacks can be customized using `onConfirm` and `onClose`.

```js file="./WarningModalExample.tsx"

```
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import React from 'react';
import WarningModal from '@patternfly/react-component-groups/dist/dynamic/WarningModal';
import { Button } from '@patternfly/react-core';

export const BasicExample: React.FunctionComponent = () => {
const [ isOpen, setIsOpen ] = React.useState(false);
return <>
<Button onClick={() => setIsOpen(true)}>Open modal</Button>
<WarningModal
isOpen={isOpen}
title='Unsaved changes'
onClose={() => setIsOpen(false)}
onConfirm={() => setIsOpen(false)}>
Your page contains unsaved changes. Do you want to leave?
</WarningModal>
</>
};
16 changes: 16 additions & 0 deletions packages/module/src/WarningModal/WarningModal.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import React from 'react';
import { render } from '@testing-library/react';
import WarningModal from './WarningModal';

describe('WarningModal component', () => {
const initialProps = {
title: 'Unsaved changes',
onClose: () => null,
onConfirm: () => null,
};

it('should render', () => {
const container = render(<WarningModal isOpen={true} {...initialProps}>Warning modal content</WarningModal>);
expect(container).toMatchSnapshot();
});
});
55 changes: 55 additions & 0 deletions packages/module/src/WarningModal/WarningModal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import React from 'react';
import { Button, ModalProps, Modal, ModalVariant, ButtonVariant } from '@patternfly/react-core';

export interface WarningModalProps extends Omit<ModalProps, 'ref'> {
/** Callback for the confirm action button. */
onConfirm?: () => void;
/** Custom label for the confirm action button */
confirmButtonLabel? : string;
/** Custom label for the cancel action button */
cancelButtonLabel? : string;
}

const WarningModal: React.FunctionComponent<WarningModalProps> = ({
isOpen,
onConfirm,
onClose,
children,
confirmButtonLabel = 'Confirm',
cancelButtonLabel = 'Cancel',
variant = ModalVariant.small,
titleIconVariant = 'warning',
...props
}: WarningModalProps) => (
<Modal
variant={variant}
isOpen={isOpen}
onClose={onClose}
onEscapePress={onClose}
titleIconVariant={titleIconVariant}
actions={[
<Button
ouiaId="primary-confirm-button"
key="confirm"
variant={ButtonVariant.primary}
onClick={onConfirm}
>
{confirmButtonLabel}
</Button>,
<Button
ouiaId="secondary-cancel-button"
key="cancel"
variant={ButtonVariant.link}
onClick={onClose}
>
{cancelButtonLabel}
</Button>,
]}
{...props}
>
{children}
</Modal>
);


export default WarningModal;
Original file line number Diff line number Diff line change
@@ -0,0 +1,183 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`WarningModal component should render 1`] = `
{
"asFragment": [Function],
"baseElement": <body
class="pf-v5-c-backdrop__open"
>
<div
aria-hidden="true"
/>
<div>
<div
class="pf-v5-c-backdrop"
>
<div
class="pf-v5-l-bullseye"
>
<div
aria-describedby="pf-modal-part-2"
aria-labelledby="pf-modal-part-1"
aria-modal="true"
class="pf-v5-c-modal-box pf-m-warning pf-m-sm"
data-ouia-component-id="OUIA-Generated-Modal-small-1"
data-ouia-component-type="PF5/ModalContent"
data-ouia-safe="true"
id="pf-modal-part-0"
role="dialog"
>
<div
class="pf-v5-c-modal-box__close"
>
<button
aria-disabled="false"
aria-label="Close"
class="pf-v5-c-button pf-m-plain"
data-ouia-component-id="OUIA-Generated-Modal-small-1-ModalBoxCloseButton"
data-ouia-component-type="PF5/Button"
data-ouia-safe="true"
type="button"
>
<svg
aria-hidden="true"
class="pf-v5-svg"
fill="currentColor"
height="1em"
role="img"
viewBox="0 0 352 512"
width="1em"
>
<path
d="M242.72 256l100.07-100.07c12.28-12.28 12.28-32.19 0-44.48l-22.24-22.24c-12.28-12.28-32.19-12.28-44.48 0L176 189.28 75.93 89.21c-12.28-12.28-32.19-12.28-44.48 0L9.21 111.45c-12.28 12.28-12.28 32.19 0 44.48L109.28 256 9.21 356.07c-12.28 12.28-12.28 32.19 0 44.48l22.24 22.24c12.28 12.28 32.2 12.28 44.48 0L176 322.72l100.07 100.07c12.28 12.28 32.2 12.28 44.48 0l22.24-22.24c12.28-12.28 12.28-32.19 0-44.48L242.72 256z"
/>
</svg>
</button>
</div>
<header
class="pf-v5-c-modal-box__header"
>
<h1
class="pf-v5-c-modal-box__title pf-m-icon"
id="pf-modal-part-1"
>
<span
class="pf-v5-c-modal-box__title-icon"
>
<svg
aria-hidden="true"
class="pf-v5-svg"
fill="currentColor"
height="1em"
role="img"
viewBox="0 0 576 512"
width="1em"
>
<path
d="M569.517 440.013C587.975 472.007 564.806 512 527.94 512H48.054c-36.937 0-59.999-40.055-41.577-71.987L246.423 23.985c18.467-32.009 64.72-31.951 83.154 0l239.94 416.028zM288 354c-25.405 0-46 20.595-46 46s20.595 46 46 46 46-20.595 46-46-20.595-46-46-46zm-43.673-165.346l7.418 136c.347 6.364 5.609 11.346 11.982 11.346h48.546c6.373 0 11.635-4.982 11.982-11.346l7.418-136c.375-6.874-5.098-12.654-11.982-12.654h-63.383c-6.884 0-12.356 5.78-11.981 12.654z"
/>
</svg>
</span>
<span
class="pf-v5-u-screen-reader"
>
Warning alert:
</span>
<span
class="pf-v5-c-modal-box__title-text"
>
Unsaved changes
</span>
</h1>
</header>
<div
class="pf-v5-c-modal-box__body"
id="pf-modal-part-2"
>
Warning modal content
</div>
<footer
class="pf-v5-c-modal-box__footer"
>
<button
aria-disabled="false"
class="pf-v5-c-button pf-m-primary"
data-ouia-component-id="primary-confirm-button"
data-ouia-component-type="PF5/Button"
data-ouia-safe="true"
type="button"
>
Confirm
</button>
<button
aria-disabled="false"
class="pf-v5-c-button pf-m-link"
data-ouia-component-id="secondary-cancel-button"
data-ouia-component-type="PF5/Button"
data-ouia-safe="true"
type="button"
>
Cancel
</button>
</footer>
</div>
</div>
</div>
</div>
</body>,
"container": <div
aria-hidden="true"
/>,
"debug": [Function],
"findAllByAltText": [Function],
"findAllByDisplayValue": [Function],
"findAllByLabelText": [Function],
"findAllByPlaceholderText": [Function],
"findAllByRole": [Function],
"findAllByTestId": [Function],
"findAllByText": [Function],
"findAllByTitle": [Function],
"findByAltText": [Function],
"findByDisplayValue": [Function],
"findByLabelText": [Function],
"findByPlaceholderText": [Function],
"findByRole": [Function],
"findByTestId": [Function],
"findByText": [Function],
"findByTitle": [Function],
"getAllByAltText": [Function],
"getAllByDisplayValue": [Function],
"getAllByLabelText": [Function],
"getAllByPlaceholderText": [Function],
"getAllByRole": [Function],
"getAllByTestId": [Function],
"getAllByText": [Function],
"getAllByTitle": [Function],
"getByAltText": [Function],
"getByDisplayValue": [Function],
"getByLabelText": [Function],
"getByPlaceholderText": [Function],
"getByRole": [Function],
"getByTestId": [Function],
"getByText": [Function],
"getByTitle": [Function],
"queryAllByAltText": [Function],
"queryAllByDisplayValue": [Function],
"queryAllByLabelText": [Function],
"queryAllByPlaceholderText": [Function],
"queryAllByRole": [Function],
"queryAllByTestId": [Function],
"queryAllByText": [Function],
"queryAllByTitle": [Function],
"queryByAltText": [Function],
"queryByDisplayValue": [Function],
"queryByLabelText": [Function],
"queryByPlaceholderText": [Function],
"queryByRole": [Function],
"queryByTestId": [Function],
"queryByText": [Function],
"queryByTitle": [Function],
"rerender": [Function],
"unmount": [Function],
}
`;
2 changes: 2 additions & 0 deletions packages/module/src/WarningModal/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export { default } from './WarningModal';
export * from './WarningModal';
3 changes: 3 additions & 0 deletions packages/module/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,6 @@ export * from './TagCount';

export { default as UnavailableContent } from './UnavailableContent';
export * from './UnavailableContent';

export { default as WarningModal } from './WarningModal';
export * from './WarningModal';

0 comments on commit d4984bd

Please sign in to comment.