// Generated, do not edit. sha256:26856efc0d14b9a73e26fd078294b6d0c3f7eebff4e23cc52adf3839ca9c9ebe
import { esc } from './escape.js';
const CLOSE = '';
const DEFAULT_LABELS = Object.freeze({
ok: 'OK', cancel: 'Cancel', close: 'Close', next: 'Next', back: 'Back', finish: 'Finish', skip: 'Skip',
});
let labels = { ...DEFAULT_LABELS };
let closeIcon = CLOSE;
let onDetail = null;
export function configureDialog({ labels: l = null, closeIcon: icon = null, onDetail: hook } = {}) {
labels = { ...DEFAULT_LABELS, ...(l || {}) };
closeIcon = icon || CLOSE;
onDetail = typeof hook === 'function' ? hook : null;
}
let overlayEl = null;
let activeResolve = null;
let overlayIsDetail = false;
export function isDialogOpen(el = null) {
if (topEl) return true;
if (!overlayEl) return false;
return !(el && overlayEl.contains(el));
}
let prevOverflow = null;
let prevPadding = null;
function lockPage() {
if (prevOverflow !== null) return;
const el = document.documentElement;
const gutter = window.innerWidth - el.clientWidth;
prevOverflow = el.style.overflow;
prevPadding = el.style.paddingRight;
el.style.overflow = 'hidden';
if (gutter > 0) el.style.paddingRight = `${gutter}px`;
}
function unlockPage() {
if (prevOverflow === null) return;
const el = document.documentElement;
el.style.overflow = prevOverflow;
el.style.paddingRight = prevPadding;
prevOverflow = null;
prevPadding = null;
}
function settle(result) {
if (topEl) settleTop(false);
document.removeEventListener('keydown', onKey, true);
if (overlayEl) { overlayEl.remove(); overlayEl = null; }
overlayIsDetail = false;
unlockPage();
const r = activeResolve; activeResolve = null;
if (r) r(result);
}
function onKey(e) {
if (!overlayEl || topEl) return;
if (overlayIsDetail && e.target && typeof e.target.matches === 'function' && overlayEl.contains(e.target)
&& e.target.matches('input, select, textarea')) return;
if (e.key === 'Escape') { e.preventDefault(); settle(false); }
}
let topEl = null;
let topResolve = null;
let topReturn = null;
function settleTop(result) {
document.removeEventListener('keydown', onKeyTop, true);
if (topEl) { topEl.remove(); topEl = null; }
const r = topResolve; topResolve = null;
if (topReturn && topReturn.isConnected) topReturn.focus();
topReturn = null;
if (r) r(result);
}
function onKeyTop(e) {
if (topEl && e.key === 'Escape') { e.preventDefault(); settleTop(false); }
}
export function confirmOver({ title, message, confirmLabel, cancelLabel, danger } = {}) {
if (!overlayEl) return confirm({ title, message, confirmLabel, cancelLabel, danger });
return openTop({ title, bodyHtml: `
${esc(message)}
`,
showCancel: true, confirmLabel, cancelLabel, danger });
}
function openTop({ title, bodyHtml, showCancel, confirmLabel, cancelLabel, danger, collect = null }) {
if (topEl) settleTop(false);
return new Promise(resolve => {
topResolve = resolve;
topReturn = document.activeElement;
topEl = document.createElement('div');
topEl.className = 'dialog-overlay dialog-overlay--stacked';
topEl.innerHTML = `
${title ? `
${esc(title)}
` : ''}
${bodyHtml}
${showCancel ? `` : ''}
`;
const outcome = ok => (collect ? (ok ? collect(topEl) : null) : ok);
topEl.addEventListener('click', e => {
const b = e.target.closest('[data-dlg]');
if (b) settleTop(outcome(b.dataset.dlg === 'ok'));
});
if (collect) {
topEl.addEventListener('keydown', e => {
if (e.key === 'Enter' && e.target.matches('input[data-dlg-field]')) { e.preventDefault(); settleTop(outcome(true)); }
});
}
document.body.appendChild(topEl);
document.addEventListener('keydown', onKeyTop, true);
(topEl.querySelector('[data-dlg-field]') || topEl.querySelector('[data-dlg="ok"]')).focus();
});
}
function open({ title, message, bodyHtml, wide, confirmLabel, cancelLabel, danger, showCancel, showOk = true,
closeCross = false, titleAside = false }) {
if (overlayEl) settle(false);
return new Promise(resolve => {
activeResolve = resolve;
const confirmCls = danger ? 'btn-danger' : 'btn-primary';
overlayEl = document.createElement('div');
overlayEl.className = 'dialog-overlay';
const actions = showCancel || showOk ? `
${showCancel ? `` : ''}
${showOk ? `` : ''}
` : '';
const body = bodyHtml != null
? `${bodyHtml}
`
: `${esc(message)}
`;
const head = title
? `
${esc(title)}
${titleAside ? '' : ''}
`
: '';
const cross = closeCross
? ``
: '';
overlayEl.innerHTML = `
${cross}${head}${body}${actions}
`;
const backdropCloses = !(showOk || showCancel || closeCross);
overlayEl.addEventListener('click', e => {
if (e.target === overlayEl) { if (backdropCloses) settle(false); return; }
const b = e.target.closest('[data-dlg]');
if (b) settle(b.dataset.dlg === 'ok');
});
document.body.appendChild(overlayEl);
lockPage();
document.addEventListener('keydown', onKey, true);
(overlayEl.querySelector('[data-dlg="ok"]') || overlayEl.querySelector('.dialog')).focus();
});
}
export function stepper({ title, steps, state = {}, skipLabel, finishLabel, hero = '' } = {}) {
if (overlayEl) settle(false);
return new Promise(resolve => {
activeResolve = resolve;
const visible = () => steps.filter(s => !(s.skip && s.skip(state)));
let i = 0;
overlayEl = document.createElement('div');
overlayEl.className = 'dialog-overlay dialog-overlay--focus';
overlayEl.innerHTML = `
${hero ? `
${hero}
` : ''}
${title ? `
${esc(title)}
` : ''}
`;
const body = overlayEl.querySelector('.dialog-body');
const actions = overlayEl.querySelector('.stepper-actions');
const draw = () => {
const list = visible();
i = Math.min(i, list.length - 1);
const step = list[i];
const last = i === list.length - 1;
const ready = !step.ready || step.ready(state);
body.innerHTML = `${step.title ? `${esc(step.title)}
` : ''}${step.html(state)}`;
actions.innerHTML = `
${i > 0 ? `` : ''}
`;
const focus = overlayEl.querySelector('[data-step="next"]:not([disabled])') || overlayEl.querySelector('.dialog');
focus.focus();
};
overlayEl.addEventListener('click', e => {
const set = e.target.closest('[data-step-set]');
if (set) { state[set.dataset.stepSet] = set.dataset.value; draw(); return; }
const toggle = e.target.closest('[data-step-toggle]');
if (toggle) {
const key = toggle.dataset.stepToggle;
const v = toggle.dataset.value;
const list = Array.isArray(state[key]) ? state[key] : [];
state[key] = list.includes(v) ? list.filter(x => x !== v) : [...list, v];
draw();
return;
}
const b = e.target.closest('[data-step]');
if (!b || b.disabled) return;
if (b.dataset.step === 'skip') settle(false);
else if (b.dataset.step === 'back') { i = Math.max(0, i - 1); draw(); }
else if (i === visible().length - 1) settle(state);
else { i += 1; draw(); }
});
document.body.appendChild(overlayEl);
lockPage();
document.addEventListener('keydown', onKey, true);
draw();
});
}
export function confirm({ title, message, confirmLabel, cancelLabel, danger } = {}) {
if (overlayEl && overlayIsDetail) return confirmOver({ title, message, confirmLabel, cancelLabel, danger });
return open({ title, message, confirmLabel, cancelLabel, danger, showCancel: true });
}
export function alert({ title, message, confirmLabel } = {}) {
if (overlayEl && overlayIsDetail) {
return openTop({ title, bodyHtml: `${esc(message)}
`, showCancel: false, confirmLabel });
}
return open({ title, message, confirmLabel, danger: false, showCancel: false });
}
export function notice({ title, message } = {}) {
return open({ title, message, showCancel: false, showOk: false });
}
export function detail({ title, html, size, titleHtml, asideHtml } = {}) {
const done = open({ title, bodyHtml: html ?? '', wide: true, showCancel: false, showOk: false,
closeCross: true, titleAside: true });
overlayIsDetail = true;
const d = overlayEl.querySelector('.dialog');
if (size === 'xl') d.classList.add('dialog--xl');
if (titleHtml) d.querySelector('.dialog-title-text').innerHTML = titleHtml;
if (asideHtml) d.querySelector('[data-dialog-aside]').innerHTML = asideHtml;
if (onDetail) onDetail(d, done);
return done;
}
function fieldsHtml(fields) {
return `
${fields.map(f => `
${f.type === 'textarea'
? ``
: f.type === 'select'
? ``
: ``}
`).join('')}
`;
}
const fieldValues = host => {
const out = {};
host.querySelectorAll('[data-dlg-field]').forEach(i => { out[i.dataset.dlgField] = i.value; });
return out;
};
export function form({ title, fields = [], confirmLabel, cancelLabel } = {}) {
if (overlayEl && overlayIsDetail) {
return openTop({ title, bodyHtml: fieldsHtml(fields), showCancel: true, confirmLabel, cancelLabel, collect: fieldValues });
}
if (overlayEl) settle(false);
return new Promise(resolve => {
activeResolve = resolve;
overlayEl = document.createElement('div');
overlayEl.className = 'dialog-overlay';
overlayEl.innerHTML = `
${title ? `
${esc(title)}
` : ''}
${fieldsHtml(fields)}
`;
const values = () => fieldValues(overlayEl);
overlayEl.addEventListener('click', e => {
if (e.target === overlayEl) return;
const b = e.target.closest('[data-dlg]');
if (b) settle(b.dataset.dlg === 'ok' ? values() : null);
});
overlayEl.addEventListener('keydown', e => {
if (e.key === 'Enter' && e.target.matches('input[data-dlg-field]')) { e.preventDefault(); settle(values()); }
});
document.body.appendChild(overlayEl);
lockPage();
document.addEventListener('keydown', onKey, true);
const first = overlayEl.querySelector('[data-dlg-field]');
if (first) first.focus();
});
}