diff options
| author | Dax Raad <[email protected]> | 2025-12-15 19:33:17 -0500 |
|---|---|---|
| committer | Dax Raad <[email protected]> | 2025-12-15 19:35:18 -0500 |
| commit | 112c58abf516e4523fb698b868a710c40b271559 (patch) | |
| tree | ba7f47f02cc5cda42e5ac0d5ae563be3e452ac68 /packages/ui/src/context | |
| parent | 0dce5173ccca05aa7bd9eaabab78fe1f5f4d4360 (diff) | |
| download | opencode-112c58abf516e4523fb698b868a710c40b271559.tar.gz opencode-112c58abf516e4523fb698b868a710c40b271559.zip | |
tui: refactor dialog system to use single active dialog instead of stack
Diffstat (limited to 'packages/ui/src/context')
| -rw-r--r-- | packages/ui/src/context/dialog.tsx | 122 |
1 files changed, 50 insertions, 72 deletions
diff --git a/packages/ui/src/context/dialog.tsx b/packages/ui/src/context/dialog.tsx index b15d96991..71fc63806 100644 --- a/packages/ui/src/context/dialog.tsx +++ b/packages/ui/src/context/dialog.tsx @@ -1,9 +1,7 @@ import { createContext, createEffect, - createMemo, createSignal, - For, getOwner, Owner, ParentProps, @@ -13,73 +11,58 @@ import { type JSX, } from "solid-js" import { Dialog as Kobalte } from "@kobalte/core/dialog" -import { iife } from "@opencode-ai/util/iife" type DialogElement = () => JSX.Element const Context = createContext<ReturnType<typeof init>>() function init() { - const [store, setStore] = createSignal< - { - id: string - element: DialogElement - onClose?: () => void - owner: Owner - }[] - >([]) + const [active, setActive] = createSignal< + | { + id: string + element: DialogElement + onClose?: () => void + owner: Owner + } + | undefined + >() const result = { - get stack() { - return store() - }, - pop() { - const current = store().at(-1) - if (!current) return - current?.onClose?.() - setStore((stack) => { - stack.pop() - return [...stack] - }) + get active() { + return active() }, - replace(element: DialogElement, owner: Owner, onClose?: () => void) { - for (const item of store()) { - item.onClose?.() - } - const id = Math.random().toString(36) - setStore([ - { - id, - element: () => - runWithOwner(owner, () => ( - <Show when={result.stack.at(-1)?.id === id}> - <Kobalte - modal - defaultOpen - onOpenChange={(open) => { - if (!open) { - onClose?.() - result.pop() - } - }} - > - <Kobalte.Portal> - <Kobalte.Overlay data-component="dialog-overlay" /> - {element()} - </Kobalte.Portal> - </Kobalte> - </Show> - )), - onClose, - owner, - }, - ]) + close() { + active()?.onClose?.() + setActive(undefined) }, - clear() { - for (const item of store()) { - item.onClose?.() - } - setStore([]) + show(element: DialogElement, owner: Owner, onClose?: () => void) { + active()?.onClose?.() + const id = Math.random().toString(36).slice(2) + setActive({ + id, + element: () => + runWithOwner(owner, () => ( + <Show when={active()?.id === id}> + <Kobalte + modal + open={true} + onOpenChange={(open) => { + if (!open) { + console.log("closing") + result.close() + } + }} + > + <Kobalte.Portal> + <Kobalte.Overlay data-component="dialog-overlay" /> + {element()} + </Kobalte.Portal> + </Kobalte> + </Show> + )), + onClose, + owner, + }) }, } @@ -89,14 +72,12 @@ function init() { export function DialogProvider(props: ParentProps) { const ctx = init() createEffect(() => { - console.log("store", ctx.stack.length) + console.log("active", ctx.active) }) return ( <Context.Provider value={ctx}> {props.children} - <div data-component="dialog-stack"> - <For each={ctx.stack}>{(item) => <>{item.element()}</>}</For> - </div> + <div data-component="dialog-stack">{ctx.active?.element?.()}</div> </Context.Provider> ) } @@ -111,17 +92,14 @@ export function useDialog() { throw new Error("useDialog must be used within a DialogProvider") } return { - get stack() { - return ctx.stack - }, - replace(element: DialogElement, onClose?: () => void) { - ctx.replace(element, owner, onClose) + get active() { + return ctx.active }, - pop() { - ctx.pop() + show(element: DialogElement, onClose?: () => void) { + ctx.show(element, owner, onClose) }, - clear() { - ctx.clear() + close() { + ctx.close() }, } } |
