diff options
Diffstat (limited to 'packages/ui/src/context')
| -rw-r--r-- | packages/ui/src/context/data.tsx | 2 | ||||
| -rw-r--r-- | packages/ui/src/context/dialog.tsx | 162 | ||||
| -rw-r--r-- | packages/ui/src/context/marked.tsx | 2 |
3 files changed, 96 insertions, 70 deletions
diff --git a/packages/ui/src/context/data.tsx b/packages/ui/src/context/data.tsx index 265178e10..16efe7779 100644 --- a/packages/ui/src/context/data.tsx +++ b/packages/ui/src/context/data.tsx @@ -1,6 +1,6 @@ import type { Message, Session, Part, FileDiff, SessionStatus } from "@opencode-ai/sdk/v2" import { createSimpleContext } from "./helper" -import { PreloadMultiFileDiffResult } from "@pierre/precision-diffs/ssr" +import { PreloadMultiFileDiffResult } from "@pierre/diffs/ssr" type Data = { session: Session[] diff --git a/packages/ui/src/context/dialog.tsx b/packages/ui/src/context/dialog.tsx index af5da06f9..71fc63806 100644 --- a/packages/ui/src/context/dialog.tsx +++ b/packages/ui/src/context/dialog.tsx @@ -1,79 +1,105 @@ -import { For, Show, type JSX } from "solid-js" -import { createStore } from "solid-js/store" -import { createSimpleContext } from "@opencode-ai/ui/context" +import { + createContext, + createEffect, + createSignal, + getOwner, + Owner, + ParentProps, + runWithOwner, + Show, + useContext, + type JSX, +} from "solid-js" +import { Dialog as Kobalte } from "@kobalte/core/dialog" + +type DialogElement = () => JSX.Element -type DialogElement = JSX.Element | (() => JSX.Element) +const Context = createContext<ReturnType<typeof init>>() -export const { use: useDialog, provider: DialogProvider } = createSimpleContext({ - name: "Dialog", - init: () => { - const [store, setStore] = createStore({ - stack: [] as { +function init() { + const [active, setActive] = createSignal< + | { + id: string element: DialogElement onClose?: () => void - }[], - }) + owner: Owner + } + | undefined + >() - 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", []) - }, - } - }, -}) + const result = { + get active() { + return active() + }, + close() { + active()?.onClose?.() + setActive(undefined) + }, + 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, + }) + }, + } -import { Dialog as Kobalte } from "@kobalte/core/dialog" + return result +} -export function DialogRoot(props: { children?: JSX.Element }) { - const dialog = useDialog() +export function DialogProvider(props: ParentProps) { + const ctx = init() + createEffect(() => { + console.log("active", ctx.active) + }) return ( - <> + <Context.Provider value={ctx}> {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> - </> + <div data-component="dialog-stack">{ctx.active?.element?.()}</div> + </Context.Provider> ) } + +export function useDialog() { + const ctx = useContext(Context) + const owner = getOwner() + if (!owner) { + throw new Error("useDialog must be used within a DialogProvider") + } + if (!ctx) { + throw new Error("useDialog must be used within a DialogProvider") + } + return { + get active() { + return ctx.active + }, + show(element: DialogElement, onClose?: () => void) { + ctx.show(element, owner, onClose) + }, + close() { + ctx.close() + }, + } +} diff --git a/packages/ui/src/context/marked.tsx b/packages/ui/src/context/marked.tsx index 0d9c44758..f4d85519d 100644 --- a/packages/ui/src/context/marked.tsx +++ b/packages/ui/src/context/marked.tsx @@ -2,7 +2,7 @@ import { marked } from "marked" import markedShiki from "marked-shiki" import { bundledLanguages, type BundledLanguage } from "shiki" import { createSimpleContext } from "./helper" -import { getSharedHighlighter, registerCustomTheme, ThemeRegistrationResolved } from "@pierre/precision-diffs" +import { getSharedHighlighter, registerCustomTheme, ThemeRegistrationResolved } from "@pierre/diffs" registerCustomTheme("OpenCode", () => { return Promise.resolve({ |
