|
| 1 | +import { Disposable, DisposableCollection } from "@gitpod/gitpod-protocol"; |
| 2 | +import { useEffect } from "react"; |
| 3 | + |
1 | 4 | export default function Modal(props: {
|
2 | 5 | children: React.ReactChild[] | React.ReactChild,
|
3 | 6 | visible: boolean,
|
4 | 7 | closeable?: boolean,
|
5 | 8 | className?: string,
|
6 |
| - onClose: () => void |
| 9 | + onClose: () => void, |
| 10 | + onEnter?: () => boolean |
7 | 11 | }) {
|
| 12 | + const disposable = new DisposableCollection(); |
| 13 | + const close = () => { |
| 14 | + disposable.dispose(); |
| 15 | + props.onClose(); |
| 16 | + } |
| 17 | + useEffect(() => { |
| 18 | + if (!props.visible) { |
| 19 | + return; |
| 20 | + } |
| 21 | + const keyHandler = (k: globalThis.KeyboardEvent) => { |
| 22 | + if (k.eventPhase === 1 /* CAPTURING */) { |
| 23 | + if (k.key === 'Escape') { |
| 24 | + close(); |
| 25 | + } |
| 26 | + if (k.key === 'Enter') { |
| 27 | + if (props.onEnter) { |
| 28 | + if (props.onEnter() === false) { |
| 29 | + return; |
| 30 | + } |
| 31 | + } |
| 32 | + close(); |
| 33 | + k.stopPropagation(); |
| 34 | + } |
| 35 | + } |
| 36 | + } |
| 37 | + window.addEventListener('keydown', keyHandler, { capture: true }); |
| 38 | + disposable.push(Disposable.create(()=> window.removeEventListener('keydown', keyHandler))); |
| 39 | + }); |
8 | 40 | if (!props.visible) {
|
9 | 41 | return null;
|
10 | 42 | }
|
11 |
| - setTimeout(() => window.addEventListener('click', props.onClose, { once: true }), 0); |
12 | 43 | return (
|
13 |
| - <div className="fixed top-0 left-0 bg-black bg-opacity-70 z-50 w-screen h-screen" > |
| 44 | + <div className="fixed top-0 left-0 bg-black bg-opacity-70 z-50 w-screen h-screen" onClick={close}> |
14 | 45 | <div className="w-screen h-screen align-middle" style={{display: 'table-cell'}}>
|
15 |
| - <div className={"relative bg-white border rounded-xl p-6 max-w-lg mx-auto text-gray-600" + props.className}> |
| 46 | + <div className={"relative bg-white border rounded-xl p-6 max-w-lg mx-auto text-gray-600" + props.className} onClick={e => e.stopPropagation()}> |
16 | 47 | {props.closeable !== false && (
|
17 |
| - <div className="absolute right-9 top-8 cursor-pointer" onClick={props.onClose}> |
| 48 | + <div className="absolute right-7 top-6 cursor-pointer hover:bg-gray-200 rounded-md p-2" onClick={close}> |
18 | 49 | <svg version="1.1" width="14px" height="14px"
|
19 | 50 | viewBox="0 0 100 100">
|
20 | 51 | <line x1="0" y1="0" x2="100" y2="100" stroke="currentColor" strokeWidth="10px" />
|
21 | 52 | <line x1="0" y1="100" x2="100" y2="0" stroke="currentColor" strokeWidth="10px" />
|
22 | 53 | </svg>
|
23 | 54 | </div>
|
24 |
| - |
25 | 55 | )}
|
26 | 56 | {props.children}
|
27 | 57 | </div>
|
|
0 commit comments