diff --git a/public/channels.js b/public/channels.js index 5dc9bdbe..6e6c8fbe 100644 --- a/public/channels.js +++ b/public/channels.js @@ -51,7 +51,29 @@ if (tip) tip.remove(); } + let _focusTrapCleanup = null; + let _nodePanelTrigger = null; + + function trapFocus(container) { + function handler(e) { + if (e.key === 'Escape') { closeNodeDetail(); return; } + if (e.key !== 'Tab') return; + const focusable = container.querySelectorAll('button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])'); + if (!focusable.length) return; + const first = focusable[0], last = focusable[focusable.length - 1]; + if (e.shiftKey) { + if (document.activeElement === first) { e.preventDefault(); last.focus(); } + } else { + if (document.activeElement === last) { e.preventDefault(); first.focus(); } + } + } + container.addEventListener('keydown', handler); + return function () { container.removeEventListener('keydown', handler); }; + } + async function showNodeDetail(name) { + _nodePanelTrigger = document.activeElement; + if (_focusTrapCleanup) { _focusTrapCleanup(); _focusTrapCleanup = null; } const node = await lookupNode(name); selectedNode = name; @@ -72,6 +94,8 @@