summaryrefslogtreecommitdiffhomepage
path: root/packages/ui/src/context
diff options
context:
space:
mode:
authorAdam <[email protected]>2025-12-14 20:32:14 -0600
committerAdam <[email protected]>2025-12-14 21:38:59 -0600
commitdda579c8ad30f81ade458769971d85ff7afee64c (patch)
tree343c82906735fcfc82a5b2a178660aaab5bccb45 /packages/ui/src/context
parent4246cdb069502c96ab11e260eb36a07a0370b710 (diff)
downloadopencode-dda579c8ad30f81ade458769971d85ff7afee64c.tar.gz
opencode-dda579c8ad30f81ade458769971d85ff7afee64c.zip
wip(desktop): progress
Diffstat (limited to 'packages/ui/src/context')
-rw-r--r--packages/ui/src/context/dialog.tsx79
-rw-r--r--packages/ui/src/context/index.ts1
2 files changed, 80 insertions, 0 deletions
diff --git a/packages/ui/src/context/dialog.tsx b/packages/ui/src/context/dialog.tsx
new file mode 100644
index 000000000..af5da06f9
--- /dev/null
+++ b/packages/ui/src/context/dialog.tsx
@@ -0,0 +1,79 @@
+import { For, Show, type JSX } from "solid-js"
+import { createStore } from "solid-js/store"
+import { createSimpleContext } from "@opencode-ai/ui/context"
+
+type DialogElement = JSX.Element | (() => JSX.Element)
+
+export const { use: useDialog, provider: DialogProvider } = createSimpleContext({
+ name: "Dialog",
+ init: () => {
+ const [store, setStore] = createStore({
+ stack: [] as {
+ element: DialogElement
+ onClose?: () => void
+ }[],
+ })
+
+ return {
+ get stack() {
+ return store.stack
+ },
+ push(element: DialogElement, onClose?: () => void) {
+ setStore("stack", (s) => [...s, { element, onClose }])
+ },
+ pop() {
+ const current = store.stack.at(-1)
+ current?.onClose?.()
+ setStore("stack", store.stack.slice(0, -1))
+ },
+ replace(element: DialogElement, onClose?: () => void) {
+ for (const item of store.stack) {
+ item.onClose?.()
+ }
+ setStore("stack", [{ element, onClose }])
+ },
+ clear() {
+ for (const item of store.stack) {
+ item.onClose?.()
+ }
+ setStore("stack", [])
+ },
+ }
+ },
+})
+
+import { Dialog as Kobalte } from "@kobalte/core/dialog"
+
+export function DialogRoot(props: { children?: JSX.Element }) {
+ const dialog = useDialog()
+ return (
+ <>
+ {props.children}
+ <Show when={dialog.stack.length > 0}>
+ <div data-component="dialog-stack">
+ <For each={dialog.stack}>
+ {(item, index) => (
+ <Show when={index() === dialog.stack.length - 1}>
+ <Kobalte
+ modal
+ defaultOpen
+ onOpenChange={(open) => {
+ if (!open) {
+ item.onClose?.()
+ dialog.pop()
+ }
+ }}
+ >
+ <Kobalte.Portal>
+ <Kobalte.Overlay data-component="dialog-overlay" />
+ {typeof item.element === "function" ? item.element() : item.element}
+ </Kobalte.Portal>
+ </Kobalte>
+ </Show>
+ )}
+ </For>
+ </div>
+ </Show>
+ </>
+ )
+}
diff --git a/packages/ui/src/context/index.ts b/packages/ui/src/context/index.ts
index 3e0f5de74..499cb74d4 100644
--- a/packages/ui/src/context/index.ts
+++ b/packages/ui/src/context/index.ts
@@ -1,3 +1,4 @@
export * from "./helper"
export * from "./data"
export * from "./diff"
+export * from "./dialog"