import { Dialog } from "@kobalte/core/dialog" import { Component, Show, createEffect, createSignal } from "solid-js" import { alertDialogState, dismissAlertDialog } from "../stores/alerts" import type { AlertVariant, AlertDialogState } from "../stores/alerts" import { useI18n } from "../lib/i18n" const variantAccent: Record = { info: { badgeBg: "var(--badge-neutral-bg)", badgeBorder: "var(--border-base)", badgeText: "var(--accent-primary)", symbol: "i", }, warning: { badgeBg: "rgba(255, 152, 0, 0.14)", badgeBorder: "var(--status-warning)", badgeText: "var(--status-warning)", symbol: "!", }, error: { badgeBg: "var(--danger-soft-bg)", badgeBorder: "var(--status-error)", badgeText: "var(--status-error)", symbol: "!", }, } function dismiss(confirmed: boolean, payload?: AlertDialogState | null, promptValue?: string) { const current = payload ?? alertDialogState() if (current?.type === "confirm") { if (confirmed) { current.onConfirm?.() } else { current.onCancel?.() } current.resolve?.(confirmed) dismissAlertDialog() return } if (current?.type === "prompt") { if (confirmed) { current.onConfirm?.() current.resolvePrompt?.(promptValue ?? "") } else { current.onCancel?.() current.resolvePrompt?.(null) } dismissAlertDialog() return } if (confirmed) { current?.onConfirm?.() } dismissAlertDialog() } const AlertDialog: Component = () => { const { t } = useI18n() let primaryButtonRef: HTMLButtonElement | undefined let promptInputRef: HTMLInputElement | undefined createEffect(() => { const state = alertDialogState() if (!state) return queueMicrotask(() => { if (state.type === "prompt") { promptInputRef?.focus() promptInputRef?.select() return } primaryButtonRef?.focus() }) }) return ( {(payload) => { const variant = payload.variant ?? "info" const accent = variantAccent[variant] const fallbackTitle = variant === "warning" ? t("alertDialog.fallbackTitle.warning") : variant === "error" ? t("alertDialog.fallbackTitle.error") : t("alertDialog.fallbackTitle.info") const title = payload.title || fallbackTitle const isConfirm = payload.type === "confirm" const isPrompt = payload.type === "prompt" const confirmLabel = payload.confirmLabel || (isConfirm ? t("alertDialog.actions.confirm") : isPrompt ? t("alertDialog.actions.run") : t("alertDialog.actions.ok")) const cancelLabel = payload.cancelLabel || t("alertDialog.actions.cancel") const [inputValue, setInputValue] = createSignal(payload.inputDefaultValue ?? "") return ( { if (!open) { dismiss(false, payload) } }} >
{accent.symbol}
{title} {payload.message} {payload.detail &&

{payload.detail}

}
{ promptInputRef = el }} class="form-input mt-2" value={inputValue()} placeholder={payload.inputPlaceholder || ""} autocapitalize="off" autocorrect="off" spellcheck={false} onInput={(e) => setInputValue(e.currentTarget.value)} onKeyDown={(e) => { if (e.key === "Enter") { e.preventDefault() dismiss(true, payload, inputValue()) } }} />
{(isConfirm || isPrompt) && ( )}
) }}
) } export default AlertDialog