diff --git a/packages/grafana-ui/src/components/Modal/Modal.tsx b/packages/grafana-ui/src/components/Modal/Modal.tsx index 777a764b105..e90a9202357 100644 --- a/packages/grafana-ui/src/components/Modal/Modal.tsx +++ b/packages/grafana-ui/src/components/Modal/Modal.tsx @@ -1,4 +1,4 @@ -import React, { FC, PropsWithChildren, useCallback } from 'react'; +import React, { FC, PropsWithChildren, useCallback, useEffect } from 'react'; import { Portal } from '../Portal/Portal'; import { cx } from 'emotion'; import { useTheme } from '../../themes'; @@ -14,6 +14,7 @@ export interface Props { title: string | JSX.Element; className?: string; contentClassName?: string; + closeOnEscape?: boolean; isOpen?: boolean; onDismiss?: () => void; @@ -27,6 +28,7 @@ export function Modal(props: PropsWithChildren): ReturnType> { title, children, isOpen = false, + closeOnEscape = true, className, contentClassName, onDismiss: propsOnDismiss, @@ -40,6 +42,23 @@ export function Modal(props: PropsWithChildren): ReturnType> { } }, [propsOnDismiss]); + const onEscKey = (ev: KeyboardEvent) => { + if (ev.key === 'Esc' || ev.key === 'Escape') { + onDismiss(); + } + }; + + useEffect(() => { + if (isOpen && closeOnEscape) { + document.addEventListener('keydown', onEscKey, false); + } else { + document.removeEventListener('keydown', onEscKey, false); + } + return () => { + document.removeEventListener('keydown', onEscKey, false); + }; + }, [closeOnEscape, isOpen]); + if (!isOpen) { return null; }