diff options
| author | Adam <[email protected]> | 2026-01-06 08:18:17 -0600 |
|---|---|---|
| committer | Adam <[email protected]> | 2026-01-06 08:19:17 -0600 |
| commit | b88bcd49fdea0955f2efc8f09a3614c188d22107 (patch) | |
| tree | 8ab04d7a9d2b892cd884eab5ab3bb5da9187191a /packages/ui/src/context | |
| parent | 3f463bc9168abd907be9ae582e161ff89c3a27c9 (diff) | |
| download | opencode-b88bcd49fdea0955f2efc8f09a3614c188d22107.tar.gz opencode-b88bcd49fdea0955f2efc8f09a3614c188d22107.zip | |
fix(app): code splitting for web load perf gains
Diffstat (limited to 'packages/ui/src/context')
| -rw-r--r-- | packages/ui/src/context/dialog.tsx | 109 |
1 files changed, 60 insertions, 49 deletions
diff --git a/packages/ui/src/context/dialog.tsx b/packages/ui/src/context/dialog.tsx index f85eb48df..8e770750a 100644 --- a/packages/ui/src/context/dialog.tsx +++ b/packages/ui/src/context/dialog.tsx @@ -1,11 +1,11 @@ import { createContext, + createRoot, createSignal, getOwner, - Owner, - ParentProps, + type Owner, + type ParentProps, runWithOwner, - Show, useContext, type JSX, } from "solid-js" @@ -13,58 +13,66 @@ import { Dialog as Kobalte } from "@kobalte/core/dialog" type DialogElement = () => JSX.Element +type Active = { + id: string + node: JSX.Element + dispose: () => void + owner: Owner + onClose?: () => void +} + const Context = createContext<ReturnType<typeof init>>() function init() { - const [active, setActive] = createSignal< - | { - id: string - element: DialogElement - onClose?: () => void - owner: Owner - } - | undefined - >() + const [active, setActive] = createSignal<Active | undefined>() + + const close = () => { + const current = active() + if (!current) return + current.onClose?.() + current.dispose() + setActive(undefined) + } + + const show = (element: DialogElement, owner: Owner, onClose?: () => void) => { + close() - const result = { + const id = Math.random().toString(36).slice(2) + let dispose: (() => void) | undefined + + const node = runWithOwner(owner, () => + createRoot((d) => { + dispose = d + return ( + <Kobalte + modal + open={true} + onOpenChange={(open) => { + if (open) return + close() + }} + > + <Kobalte.Portal> + <Kobalte.Overlay data-component="dialog-overlay" /> + {element()} + </Kobalte.Portal> + </Kobalte> + ) + }), + ) + + if (!dispose) return + + setActive({ id, node, dispose, owner, onClose }) + } + + return { 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) { - result.close() - } - }} - > - <Kobalte.Portal> - <Kobalte.Overlay data-component="dialog-overlay" /> - {element()} - </Kobalte.Portal> - </Kobalte> - </Show> - )), - onClose, - owner, - }) - }, + close, + show, } - - return result } export function DialogProvider(props: ParentProps) { @@ -72,7 +80,7 @@ export function DialogProvider(props: ParentProps) { return ( <Context.Provider value={ctx}> {props.children} - <div data-component="dialog-stack">{ctx.active?.element?.()}</div> + <div data-component="dialog-stack">{ctx.active?.node}</div> </Context.Provider> ) } @@ -80,18 +88,21 @@ export function DialogProvider(props: ParentProps) { 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) + const base = ctx.active?.owner ?? owner + ctx.show(element, base, onClose) }, close() { ctx.close() |
