()
| 64 | } |
| 65 | |
| 66 | function init() { |
| 67 | const [store, setStore] = createStore({ |
| 68 | stack: [] as { |
| 69 | element: JSX.Element |
| 70 | onClose?: () => void |
| 71 | }[], |
| 72 | size: "medium" as "medium" | "large" | "xlarge", |
| 73 | }) |
| 74 | |
| 75 | const renderer = useRenderer() |
| 76 | const modeStack = useOpencodeModeStack() |
| 77 | |
| 78 | createEffect(() => { |
| 79 | if (store.stack.length === 0) return |
| 80 | const popMode = modeStack.push("modal") |
| 81 | onCleanup(popMode) |
| 82 | }) |
| 83 | |
| 84 | let focus: Renderable | null |
| 85 | function refocus() { |
| 86 | setTimeout(() => { |
| 87 | if (!focus) return |
| 88 | if (focus.isDestroyed) return |
| 89 | function find(item: Renderable) { |
| 90 | for (const child of item.getChildren()) { |
| 91 | if (child === focus) return true |
| 92 | if (find(child)) return true |
| 93 | } |
| 94 | return false |
| 95 | } |
| 96 | const found = find(renderer.root) |
| 97 | if (!found) return |
| 98 | focus.focus() |
| 99 | }, 1) |
| 100 | } |
| 101 | |
| 102 | useBindings(() => ({ |
| 103 | enabled: store.stack.length > 0 && !renderer.getSelection()?.getSelectedText(), |
| 104 | bindings: [ |
| 105 | { |
| 106 | key: "escape", |
| 107 | desc: "Close dialog", |
| 108 | group: "Dialog", |
| 109 | cmd: () => { |
| 110 | if (renderer.getSelection()) { |
| 111 | renderer.clearSelection() |
| 112 | } |
| 113 | const current = store.stack.at(-1) |
| 114 | current?.onClose?.() |
| 115 | setStore("stack", store.stack.slice(0, -1)) |
| 116 | refocus() |
| 117 | }, |
| 118 | }, |
| 119 | { |
| 120 | key: "ctrl+c", |
| 121 | desc: "Close dialog", |
| 122 | group: "Dialog", |
| 123 | cmd: () => { |
no test coverage detected