dialog: add autofreeze to sync loading state

Enabled by default, autofreeze freezes the dialog whenever loading state
is enabled.
This commit is contained in:
Elijah Duffy
2026-03-15 15:58:44 -07:00
parent ebdca97527
commit 622481a1ca

View File

@@ -141,8 +141,10 @@
onopenchange?: ({ open, dialog }: { open: boolean; dialog: DialogAPI }) => void;
/** If default controls are used, controls loading state of submit button */
loading?: boolean;
/** If default controls are used, freezes all interactions */
/** If default controls are used, freezes all interactions preventing user input */
frozen?: boolean;
/** If enabled, automatically freezes dialog when loading (default: true) */
autoFreeze?: boolean;
/** If default controls are used, disables submit button */
disabled?: boolean;
}
@@ -162,6 +164,7 @@
onopenchange,
loading = $bindable(false),
frozen = $bindable(false),
autoFreeze = true,
disabled = $bindable(false)
}: Props = $props();
@@ -180,6 +183,8 @@
let stackIndex = $state(-1);
const zIndex = $derived(1000 + stackIndex * 100);
const reallyFrozen = $derived(autoFreeze ? frozen || loading : frozen);
/** handles open change */
const handleOpenChange = (localOpen: boolean) => {
if (localOpen) {
@@ -244,7 +249,7 @@
/** Returns the current state of the dialog */
export const getState = (): DialogState => {
return {
frozen,
frozen: reallyFrozen,
loading,
disabled,
api: dialogAPI
@@ -271,11 +276,11 @@
transition:fade={{ duration: 150 }}
onclick={(e) => {
const target = e.target as HTMLElement;
if (open && !frozen && !dialogContainer?.contains(target) && target !== dialogContainer)
if (open && !reallyFrozen && !dialogContainer?.contains(target) && target !== dialogContainer)
open = false;
}}
onkeydown={(e) => {
if (e.key === 'Escape' && !frozen) {
if (e.key === 'Escape' && !reallyFrozen) {
if (stackIndex === dialogStack.length - 1) {
// only close if this dialog is the topmost dialog
open = false;
@@ -374,7 +379,7 @@
state.api.close();
}
}}
disabled={state.frozen}
disabled={state.frozen || state.disabled}
>
{opts?.label || 'Cancel'}
</Button>