Stabilize Soma overlay close targets

active-uix
dev 5 months ago
parent 5abeb298e9
commit 6578cefdaf

@ -195,7 +195,13 @@ export class DialogProvider {
*/
dismissWith(action: 'save' | 'cancel' | 'dismiss' | 'dismiss-outside' | 'fail'): Promise<void> {
const eventName = action === 'fail' ? 'close-after-fail' : `close-${action}`;
return this.runtime.trigger(eventName);
return this.triggerClose(eventName);
}
triggerClose(eventName: string, fallbackTarget?: HTMLElement): Promise<void> {
const target = this.contentRef.current ?? fallbackTarget ?? this.triggerNode.current;
if (!target) return this.runtime.trigger(eventName);
return this.runtime.trigger(eventName, { fallbackTarget: target });
}
setContentRef(el: HTMLElement | null) {
@ -235,6 +241,9 @@ export class DialogTriggerProvider {
id: opts.id,
ref: opts.ref,
owner: this,
onRefChange: (el) => {
this.provider.triggerNode.current = el;
},
syncAttrs: true
});
}
@ -331,12 +340,14 @@ export class DialogContentProvider {
enabled: readableActive(() => this.provider.opts.open.current),
onEscapeKeydown: readableActive(() => (e: KeyboardEvent) => {
opts.onEscapeKeydown.current(e);
if (!e.defaultPrevented) void this.provider.runtime.trigger('close-dismiss');
if (!e.defaultPrevented)
void this.provider.triggerClose('close-dismiss', opts.ref.current ?? undefined);
}),
escapeKeydownBehavior: resolvedEscapeBehavior,
onInteractOutside: readableActive(() => (e: PointerEvent) => {
opts.onInteractOutside.current(e);
if (!e.defaultPrevented) void this.provider.runtime.trigger('close-dismiss-outside');
if (!e.defaultPrevented)
void this.provider.triggerClose('close-dismiss-outside', opts.ref.current ?? undefined);
}),
interactOutsideBehavior: resolvedInteractBehavior,
onFocusOutside: opts.onFocusOutside,
@ -516,8 +527,8 @@ export class DialogCloseProvider {
});
}
readonly onclick = (_e: SomaMouseEvent<HTMLButtonElement>) => {
void this.provider.runtime.trigger('close-cancel');
readonly onclick = (e: SomaMouseEvent<HTMLButtonElement>) => {
void this.provider.triggerClose('close-cancel', e.currentTarget as HTMLElement);
};
readonly props = $derived.by(() => ({

@ -244,7 +244,13 @@ export class DrawerProvider {
*/
dismissWith(action: 'save' | 'cancel' | 'dismiss' | 'dismiss-outside' | 'fail'): Promise<void> {
const eventName = action === 'fail' ? 'close-after-fail' : `close-${action}`;
return this.runtime.trigger(eventName);
return this.triggerClose(eventName);
}
triggerClose(eventName: string, fallbackTarget?: HTMLElement): Promise<void> {
const target = this.contentRef.current ?? fallbackTarget ?? this.triggerNode.current;
if (!target) return this.runtime.trigger(eventName);
return this.runtime.trigger(eventName, { fallbackTarget: target });
}
readonly isNested = $derived.by(() => this.depth > 0);
@ -458,7 +464,8 @@ export class DrawerContentProvider {
),
onEscapeKeydown: readableActive(() => (e: KeyboardEvent) => {
opts.onEscapeKeydown.current(e);
if (!e.defaultPrevented) void this.provider.runtime.trigger('close-dismiss');
if (!e.defaultPrevented)
void this.provider.triggerClose('close-dismiss', opts.ref.current ?? undefined);
}),
escapeKeydownBehavior: readableActive(() => opts.escapeKeydownBehavior.current ?? 'close'),
onInteractOutside: readableActive(() => (_e: PointerEvent) => {}),
@ -829,7 +836,7 @@ export class DrawerContentProvider {
this.provider.opts.dismissible.current
) {
e.preventDefault();
void this.provider.runtime.trigger('close-dismiss');
void this.provider.triggerClose('close-dismiss', e.currentTarget as HTMLElement);
}
};
@ -973,9 +980,9 @@ export class DrawerOverlayProvider {
readonly isPresent = $derived.by(() => this.provider.overlayPresence.isPresent);
readonly onclick = () => {
readonly onclick = (e: SomaMouseEvent<HTMLElement>) => {
if (this.provider.opts.dismissible.current) {
void this.provider.runtime.trigger('close-dismiss-outside');
void this.provider.triggerClose('close-dismiss-outside', e.currentTarget as HTMLElement);
}
};
@ -1132,8 +1139,8 @@ export class DrawerCloseProvider {
});
}
readonly onclick = (_e: SomaMouseEvent<HTMLButtonElement>) => {
void this.provider.runtime.trigger('close-cancel');
readonly onclick = (e: SomaMouseEvent<HTMLButtonElement>) => {
void this.provider.triggerClose('close-cancel', e.currentTarget as HTMLElement);
};
readonly props = $derived.by(() => ({

Loading…
Cancel
Save

Powered by TurnKey Linux.