Changeset 0.23.1 (#154)

This commit is contained in:
2026-03-06 13:26:25 +00:00
parent 2fc620e1ac
commit 4c6555cb06
38 changed files with 1536 additions and 4031 deletions

View File

@@ -792,6 +792,74 @@ function showConfirm(message, opts = {}) {
});
}
// §8b PROMPT DIALOG
// ══════════════════════════════════════════════════════════════════════════════
/**
* Custom prompt dialog replacing native prompt().
* Returns a Promise<string|null> — null means cancelled or empty.
*
* @param {Object} opts
* @param {string} [opts.title='Enter value']
* @param {string} [opts.label] - Optional helper text below title
* @param {string} [opts.value=''] - Pre-filled value
* @param {string} [opts.placeholder='']
* @param {string} [opts.ok='OK']
* @param {string} [opts.cancel='Cancel']
* @param {string} [opts.inputType='text']
* @returns {Promise<string|null>}
*/
function showPrompt(opts = {}) {
return new Promise(resolve => {
const title = opts.title || 'Enter value';
const label = opts.label || '';
const defVal = opts.value || '';
const ph = opts.placeholder || '';
const okText = opts.ok || 'OK';
const caText = opts.cancel || 'Cancel';
const iType = opts.inputType || 'text';
const overlay = document.createElement('div');
overlay.className = 'confirm-overlay';
overlay.innerHTML = `
<div class="confirm-dialog">
<div class="confirm-header">${esc(title)}</div>
${label ? `<div class="confirm-body">${esc(label)}</div>` : ''}
<div class="prompt-input-wrap">
<input class="prompt-input" type="${esc(iType)}"
value="${esc(defVal)}" placeholder="${esc(ph)}" autocomplete="off">
</div>
<div class="confirm-footer">
<button class="btn-small" data-action="cancel">${esc(caText)}</button>
<button class="btn-small btn-primary" data-action="ok">${esc(okText)}</button>
</div>
</div>`;
const input = overlay.querySelector('.prompt-input');
function close(result) {
overlay.remove();
document.removeEventListener('keydown', onKey);
resolve(result);
}
function onKey(e) {
if (e.key === 'Escape') { close(null); }
if (e.key === 'Enter') { const v = input.value.trim(); close(v || null); }
}
overlay.querySelector('[data-action="ok"]').addEventListener('click', () => {
close(input.value.trim() || null);
});
overlay.querySelector('[data-action="cancel"]').addEventListener('click', () => close(null));
overlay.addEventListener('click', e => { if (e.target === overlay) close(null); });
document.addEventListener('keydown', onKey);
document.body.appendChild(overlay);
requestAnimationFrame(() => { input.focus(); if (defVal) input.select(); });
});
}
// ── Modal open/close ────────────────────────
// Generic modal show/hide used by settings, admin, debug, team-admin modals.
// Moved here from app.js so all surfaces (not just chat) can use modals.