replace custom modal with kobalte and prevent scroll jump

This commit is contained in:
vimtor
2026-05-14 16:59:27 +02:00
parent aeab589b5f
commit 7ae250dd4c
2 changed files with 49 additions and 11 deletions

View File

@@ -1,5 +1,5 @@
import { action, createAsync, json, query, useAction, useSubmission } from "@solidjs/router"
import { createMemo, createSignal, For, Show } from "solid-js"
import { action, json, query, useAction, useSubmission } from "@solidjs/router"
import { createEffect, createMemo, createSignal, For, onCleanup, Show } from "solid-js"
import { getRequestEvent } from "solid-js/web"
import { Referral } from "@opencode-ai/console-core/referral.js"
import { Database, and, eq, isNull } from "@opencode-ai/console-core/drizzle/index.js"
@@ -212,9 +212,27 @@ export function GoReferralSection(props: { workspaceID: string; summary: GoRefer
const apply = useAction(applyGoReferralReward)
const submission = useSubmission(applyGoReferralReward)
const [selected, setSelected] = createSignal<GoReferralReward>()
const preview = createAsync(() => queryGoReferralUsagePreview(props.workspaceID, selected()?.id))
const [preview, setPreview] = createSignal<GoReferralUsagePreview | null>()
const appliedCount = createMemo(() => props.summary.rewards.filter((reward) => reward.timeApplied).length)
createEffect(() => {
const reward = selected()
if (!reward) {
setPreview(undefined)
return
}
const request = { cancelled: false }
setPreview(undefined)
queryGoReferralUsagePreview(props.workspaceID, reward.id).then((result) => {
if (request.cancelled) return
setPreview(result)
})
onCleanup(() => {
request.cancelled = true
})
})
async function onApply() {
const reward = selected()
if (!reward) return

View File

@@ -1,3 +1,4 @@
import { Dialog as Kobalte } from "@kobalte/core/dialog"
import { JSX, Show } from "solid-js"
import "./modal.css"
@@ -11,14 +12,33 @@ interface ModalProps {
export function Modal(props: ModalProps) {
return (
<Show when={props.open}>
<div data-component="modal" data-slot="overlay" onClick={props.onClose}>
<div data-slot="content" onClick={(e) => e.stopPropagation()}>
<Show when={props.title}>
<h2 data-slot="title">{props.title}</h2>
</Show>
{props.children}
</div>
</div>
<Kobalte
modal
open={props.open}
preventScroll={false}
onOpenChange={(open) => {
if (!open) props.onClose()
}}
>
<Kobalte.Portal>
<Kobalte.Overlay data-component="modal" data-slot="overlay" onClick={props.onClose}>
<Kobalte.Content
data-slot="content"
onClick={(e) => e.stopPropagation()}
onOpenAutoFocus={(e) => {
e.preventDefault()
const target = e.currentTarget as HTMLElement | null
target?.focus({ preventScroll: true })
}}
>
<Show when={props.title}>
<Kobalte.Title data-slot="title">{props.title}</Kobalte.Title>
</Show>
{props.children}
</Kobalte.Content>
</Kobalte.Overlay>
</Kobalte.Portal>
</Kobalte>
</Show>
)
}