✨(react) add closeOnEsc props to Modal
We want to be able to disable closing modals by pressing escape in some cases.
This commit is contained in:
@@ -149,6 +149,12 @@ You can change this behavior by passing the `closeOnClickOutside` prop.
|
||||
|
||||
<Canvas of={Stories.CloseOnClickOutside} story={{inline: false}}/>
|
||||
|
||||
## Close on escape
|
||||
|
||||
By default, the modal will be closed when you press the `esc` key. You can change this behavior by passing the `closeOnEsc` prop.
|
||||
|
||||
<Canvas of={Stories.DontCloseOnEsc} story={{inline: false}}/>
|
||||
|
||||
## Pre Built Modals
|
||||
|
||||
As we know that developers love to have handy shortcuts for common use cases, we provide some pre built modals that we
|
||||
|
||||
@@ -209,6 +209,54 @@ describe("<Modal/>", () => {
|
||||
await user.click(modal);
|
||||
expect(screen.queryByText("Modal Content")).toBeInTheDocument();
|
||||
});
|
||||
it("close on esc by default", async () => {
|
||||
const Wrapper = () => {
|
||||
const modal = useModal();
|
||||
return (
|
||||
<CunninghamProvider>
|
||||
<button onClick={modal.open}>Open Modal</button>
|
||||
<Modal size={ModalSize.SMALL} {...modal}>
|
||||
<div>Modal Content</div>
|
||||
</Modal>
|
||||
</CunninghamProvider>
|
||||
);
|
||||
};
|
||||
|
||||
render(<Wrapper />);
|
||||
const user = userEvent.setup();
|
||||
const button = screen.getByText("Open Modal");
|
||||
|
||||
expect(screen.queryByText("Modal Content")).not.toBeInTheDocument();
|
||||
await user.click(button);
|
||||
expect(screen.getByText("Modal Content")).toBeInTheDocument();
|
||||
|
||||
await user.keyboard("{Escape}");
|
||||
expect(screen.queryByText("Modal Content")).not.toBeInTheDocument();
|
||||
});
|
||||
it("does not close on esc when using closeOnEsc=false", async () => {
|
||||
const Wrapper = () => {
|
||||
const modal = useModal();
|
||||
return (
|
||||
<CunninghamProvider>
|
||||
<button onClick={modal.open}>Open Modal</button>
|
||||
<Modal size={ModalSize.SMALL} closeOnEsc={false} {...modal}>
|
||||
<div>Modal Content</div>
|
||||
</Modal>
|
||||
</CunninghamProvider>
|
||||
);
|
||||
};
|
||||
|
||||
render(<Wrapper />);
|
||||
const user = userEvent.setup();
|
||||
const button = screen.getByText("Open Modal");
|
||||
|
||||
expect(screen.queryByText("Modal Content")).not.toBeInTheDocument();
|
||||
await user.click(button);
|
||||
expect(screen.getByText("Modal Content")).toBeInTheDocument();
|
||||
|
||||
await user.keyboard("{Escape}");
|
||||
expect(screen.queryByText("Modal Content")).toBeInTheDocument();
|
||||
});
|
||||
|
||||
/**
|
||||
* It should also prevent the modal from closing when pressing the escape key, but it appears
|
||||
|
||||
@@ -80,6 +80,12 @@ export const CloseOnClickOutside: Story = {
|
||||
closeOnClickOutside: true,
|
||||
},
|
||||
};
|
||||
export const DontCloseOnEsc: Story = {
|
||||
args: {
|
||||
size: ModalSize.MEDIUM,
|
||||
closeOnEsc: false,
|
||||
},
|
||||
};
|
||||
export const PreventClose: Story = {
|
||||
args: {
|
||||
size: ModalSize.MEDIUM,
|
||||
|
||||
@@ -51,6 +51,7 @@ export type ModalProps = PropsWithChildren & {
|
||||
titleIcon?: React.ReactNode;
|
||||
hideCloseButton?: boolean;
|
||||
closeOnClickOutside?: boolean;
|
||||
closeOnEsc?: boolean;
|
||||
preventClose?: boolean;
|
||||
};
|
||||
|
||||
@@ -71,7 +72,7 @@ export const Modal = (props: ModalProps) => {
|
||||
return <ModalInner {...props} />;
|
||||
};
|
||||
|
||||
export const ModalInner = (props: ModalProps) => {
|
||||
export const ModalInner = ({ closeOnEsc = true, ...props }: ModalProps) => {
|
||||
const { modalParentSelector } = useModals();
|
||||
|
||||
if (!props.isOpen) {
|
||||
@@ -90,6 +91,7 @@ export const ModalInner = (props: ModalProps) => {
|
||||
overlayClassName="c__modal__backdrop"
|
||||
className={classNames(MODAL_CLASS, `${MODAL_CLASS}--${props.size}`)}
|
||||
shouldCloseOnOverlayClick={!!props.closeOnClickOutside}
|
||||
shouldCloseOnEsc={closeOnEsc}
|
||||
bodyOpenClassName={classNames("c__modals--opened", NOSCROLL_CLASS)}
|
||||
>
|
||||
{!props.hideCloseButton && !props.preventClose && (
|
||||
|
||||
Reference in New Issue
Block a user