Accessible modal and tabs project
Review request
The operations team needs a reusable details review dialog with Overview and History panels. The fixture supplies the title, review organization, and contact name. Build a named native modal, put initial focus on Review note, support Close and Escape, connect tabs and panels, add arrow/Home/End navigation, and return focus to the invoking control. Done means the same flow works from both invokers and with either fixture.
A modal changes where people can interact, so opening it is only the first requirement. It needs a name, useful initial focus, a close action, and a reliable way back to the control that opened it. Tabs inside the modal add a second state model: one selected panel and one tab stop in the tablist. Build those relationships in small steps. The native dialog supplies modality and focus containment, while your handlers coordinate the selected tab and keyboard movement. Each step keeps the previous files. The final preview must work from either invoker and support keyboard navigation without exposing a hidden panel as current content.
<button id="open">Open details</button><dialog><h2 id="dialog-title"></h2><button id="ack">Acknowledge</button></dialog>
body{font:16px/1.5 system-ui,sans-serif;color:#17243b;background:#fff;margin:20px}button,input,select{font:inherit}button,a,input,select{outline-offset:4px}button{cursor:pointer}main{max-width:100%}[hidden]{display:none!important}.cards{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:12px}.card{border:1px solid #94a3b8;padding:12px;min-width:0;overflow-wrap:anywhere}label{display:block}input,select{box-sizing:border-box;max-width:100%}ul{padding-left:24px}@media(max-width:600px){.cards{grid-template-columns:1fr}}
dialog{max-width:calc(100vw - 40px);box-sizing:border-box;border:1px solid #334155}dialog::backdrop{background:rgb(15 23 42 / .35)}[role="tablist"]{display:flex;gap:8px;margin-top:16px}[role="tab"][aria-selected="true"]{border-bottom:3px solid #2b4bff}
const dialog=document.querySelector('dialog');const opener=document.querySelector('#open');let returnTo=opener;document.querySelector('#dialog-title').textContent=fixture.title;
function open(event){returnTo=event.currentTarget;dialog.showModal();}
opener.addEventListener('click',open);
Read the markup and styles together, then trace the resulting control or layout.