summaryrefslogtreecommitdiffhomepage
path: root/packages/ui/src/context
diff options
context:
space:
mode:
authorDavid Hill <[email protected]>2025-12-16 10:54:51 +0000
committerDavid Hill <[email protected]>2025-12-16 10:54:51 +0000
commit05e0759878cb0f24c981c69ae26f6be3ea5583c6 (patch)
tree39aaf6b86a6f2b8e653120e80d8f0facb528051b /packages/ui/src/context
parent2330ec6dc3000ae8b86810e9d59b414ad4f05f47 (diff)
parent75e5130cf8f58b32ee3f3ba2249d5917e7e3d6fc (diff)
downloadopencode-05e0759878cb0f24c981c69ae26f6be3ea5583c6.tar.gz
opencode-05e0759878cb0f24c981c69ae26f6be3ea5583c6.zip
Merge branch 'dev' of https://github.com/sst/opencode into dev
Diffstat (limited to 'packages/ui/src/context')
-rw-r--r--packages/ui/src/context/data.tsx2
-rw-r--r--packages/ui/src/context/dialog.tsx162
-rw-r--r--packages/ui/src/context/marked.tsx2
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({