87 lines
3.4 KiB
JavaScript
87 lines
3.4 KiB
JavaScript
import { createScope, mountTheme, createButton } from './core.js';
|
|
|
|
let nextDialog = 0;
|
|
|
|
export function createDialog({ title, settings, fallbackFocus, onCancel }) {
|
|
const scope = createScope();
|
|
const element = document.createElement('dialog');
|
|
element.id = `ca-dialog-${++nextDialog}`;
|
|
element.className = 'ca-tools ca-dialog kikotools-dialog';
|
|
const header = document.createElement('header');
|
|
const heading = document.createElement('h2');
|
|
heading.id = `${element.id}-title`;
|
|
heading.textContent = title;
|
|
element.setAttribute('aria-labelledby', heading.id);
|
|
const brand = document.createElement('span');
|
|
brand.textContent = 'ComfyAssets';
|
|
header.append(heading, brand);
|
|
const body = document.createElement('div');
|
|
body.className = 'ca-dialog-body';
|
|
const actions = document.createElement('footer');
|
|
element.append(header, body, actions);
|
|
mountTheme(element, settings, scope);
|
|
let opener;
|
|
const nativeClose = element.close.bind(element);
|
|
const finish = reason => {
|
|
if (scope.signal.aborted) return;
|
|
scope.dispose();
|
|
if (opener?.isConnected && opener !== document.body) opener.focus();
|
|
else fallbackFocus?.focus();
|
|
if (reason === 'cancel') onCancel?.();
|
|
};
|
|
element.close = (reason = 'dismiss') => {
|
|
if (scope.signal.aborted) return;
|
|
nativeClose(reason);
|
|
finish(reason);
|
|
};
|
|
scope.cleanup(() => element.remove());
|
|
scope.listen(element, 'close', () => finish(element.returnValue));
|
|
scope.listen(element, 'cancel', event => {
|
|
event.preventDefault();
|
|
element.close('cancel');
|
|
});
|
|
scope.listen(element, 'keydown', event => event.stopPropagation());
|
|
scope.listen(element, 'keyup', event => event.stopPropagation());
|
|
for (const event of ['pointerdown', 'mousedown', 'click']) scope.listen(element, event, event => event.stopPropagation());
|
|
return {
|
|
element, scope, body, actions,
|
|
close: element.close,
|
|
open(initialFocus) {
|
|
opener = document.activeElement;
|
|
document.body.append(element);
|
|
element.showModal();
|
|
initialFocus?.focus();
|
|
},
|
|
};
|
|
}
|
|
|
|
export function createLegacyDialog(htmlContent, onOK, onCancel, settings, fallbackFocus) {
|
|
const dialog = createDialog({ title: 'KikoTools', settings, fallbackFocus, onCancel });
|
|
const form = document.createElement('form');
|
|
form.id = `${dialog.element.id}-form`;
|
|
form.innerHTML = htmlContent;
|
|
dialog.body.append(form);
|
|
const cancel = createButton('Cancel');
|
|
const ok = createButton('OK', 'ca-primary');
|
|
ok.type = 'submit';
|
|
ok.setAttribute('form', form.id);
|
|
dialog.actions.append(cancel, ok);
|
|
dialog.scope.listen(cancel, 'click', () => dialog.close('cancel'));
|
|
dialog.scope.listen(form, 'keydown', event => {
|
|
if (event.key === 'Enter' && !event.isComposing && event.target.matches('select')) {
|
|
event.preventDefault();
|
|
event.stopPropagation();
|
|
form.requestSubmit();
|
|
}
|
|
});
|
|
dialog.scope.listen(form, 'submit', event => {
|
|
event.preventDefault();
|
|
onOK?.(dialog.element, [...form.querySelectorAll('input, select')].map(input => input.value));
|
|
dialog.close('apply');
|
|
});
|
|
const firstInput = form.querySelector('input, select');
|
|
dialog.open(firstInput);
|
|
if (firstInput?.tagName === 'INPUT') firstInput.select();
|
|
return dialog.element;
|
|
}
|