Offline edits that send when back online, books saved on the device, and keyboard access for dialogs and Bible verses; roadmap
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
275ef2009f
commit
95ade02bf2
11 files changed
+96
-18
No files matched your search
+9
-2
@@ -10,11 +10,18 @@ function openSheet(title, sub, bodyHtml) {
|
||||
el.querySelector('.scrim').onclick = dismissSheet; el.querySelector('.sheetx').onclick = dismissSheet;
|
||||
swipeToDismiss(el.querySelector('.sheet'), () => closeSheet(), { handle: '.grip, h3, .sheetx', scrim: el.querySelector('.scrim') });
|
||||
requestAnimationFrame(() => el.classList.add('on'));
|
||||
// keyboard: focus moves into the dialog (not into a field, so a phone's keyboard does not pop up), Tab stays inside it, and closing gives focus back to what opened it
|
||||
el._from = document.activeElement; const box = el.querySelector('.sheet'); box.tabIndex = -1; try { box.focus({ preventScroll: true }); } catch { /* old browser */ }
|
||||
el.addEventListener('keydown', e => {
|
||||
if (e.key !== 'Tab') return; const f = [...box.querySelectorAll('a[href],button:not([disabled]),input:not([disabled]):not([type=hidden]),select:not([disabled]),textarea:not([disabled]),[tabindex]:not([tabindex="-1"])')].filter(x => x.offsetParent !== null || x === document.activeElement); if (!f.length) return;
|
||||
const first = f[0], last = f[f.length - 1]; if (e.shiftKey && (document.activeElement === first || document.activeElement === box)) { e.preventDefault(); last.focus(); } else if (!e.shiftKey && document.activeElement === last) { e.preventDefault(); first.focus(); }
|
||||
});
|
||||
return el;
|
||||
}
|
||||
function closeSheet() { document.getElementById('sheet')?.remove(); }
|
||||
const sheetGone = s => { const from = s && s._from; if (from && from.isConnected && from !== document.body && !document.getElementById('sheet')) { try { from.focus({ preventScroll: true }); } catch { /* it cannot take focus */ } } };
|
||||
function closeSheet() { const s = document.getElementById('sheet'); if (s) { s.remove(); sheetGone(s); } }
|
||||
/** Close with the slide-down (the close button, a tap outside); closeSheet() is the instant one other code calls before opening something else. */
|
||||
function dismissSheet() { const s = document.getElementById('sheet'); if (!s || s._closing) return; s._closing = true; s.classList.remove('on'); setTimeout(() => { if (s.isConnected) s.remove(); }, 230); }
|
||||
function dismissSheet() { const s = document.getElementById('sheet'); if (!s || s._closing) return; s._closing = true; s.classList.remove('on'); setTimeout(() => { if (s.isConnected) { s.remove(); sheetGone(s); } }, 230); }
|
||||
/** Swipe down to dismiss: `el` follows the finger and `close` runs when it is let go far enough or fast enough. Touches starting in `handle` always count; elsewhere only when nothing under the finger is scrolled down, and never on sliders or text fields. On a phone-sized screen only, unless `always` (full-screen views). */
|
||||
function swipeToDismiss(el, close, { handle = '', scrim = null, always = false } = {}) {
|
||||
let y0 = 0, x0 = 0, t0 = 0, on = false, dead = true;
|
||||
|
||||
Reference in new issue
Block a user