()
| 30 | const Context = createContext<ReturnType<typeof init>>() |
| 31 | |
| 32 | function init() { |
| 33 | const [stack, setStack] = createSignal<Active[]>([]) |
| 34 | const timer = { current: undefined as ReturnType<typeof setTimeout> | undefined } |
| 35 | const lock = { value: false } |
| 36 | |
| 37 | onCleanup(() => { |
| 38 | if (timer.current === undefined) return |
| 39 | clearTimeout(timer.current) |
| 40 | timer.current = undefined |
| 41 | }) |
| 42 | |
| 43 | const close = (id?: string) => { |
| 44 | const items = stack() |
| 45 | const current = id ? items.find((item) => item.id === id) : items.at(-1) |
| 46 | if (!current || lock.value) return |
| 47 | lock.value = true |
| 48 | current.onClose?.() |
| 49 | current.setClosing(true) |
| 50 | |
| 51 | const closed = current.id |
| 52 | if (timer.current !== undefined) { |
| 53 | clearTimeout(timer.current) |
| 54 | timer.current = undefined |
| 55 | } |
| 56 | |
| 57 | timer.current = setTimeout(() => { |
| 58 | timer.current = undefined |
| 59 | current.dispose() |
| 60 | setStack((items) => items.filter((item) => item.id !== closed)) |
| 61 | lock.value = false |
| 62 | }, 100) |
| 63 | } |
| 64 | |
| 65 | createEffect(() => { |
| 66 | if (stack().length === 0) return |
| 67 | |
| 68 | const onKeyDown = (event: KeyboardEvent) => { |
| 69 | if (event.key !== "Escape") return |
| 70 | close() |
| 71 | event.preventDefault() |
| 72 | event.stopPropagation() |
| 73 | } |
| 74 | |
| 75 | makeEventListener(window, "keydown", onKeyDown, { capture: true }) |
| 76 | }) |
| 77 | |
| 78 | const mount = (element: DialogElement, owner: Owner, onClose: (() => void) | undefined, layer: number) => { |
| 79 | const id = Math.random().toString(36).slice(2) |
| 80 | const zIndex = 50 + layer * 10 |
| 81 | let dispose: (() => void) | undefined |
| 82 | let setClosing: ((closing: boolean) => void) | undefined |
| 83 | |
| 84 | const node = runWithOwner(owner, () => |
| 85 | createRoot((d: () => void) => { |
| 86 | dispose = d |
| 87 | const [closing, setClosingSignal] = createSignal(false) |
| 88 | setClosing = setClosingSignal |
| 89 | return ( |
no test coverage detected