Changeset 0.23.1 (#154)
This commit is contained in:
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user