web: focus modal, slice 8 of M3
Clicking a panel's network (cursor zoom-in, a real button for keyboard users) or its menu's Focus item opens the modal: the same SVG at the same global round rendered up to 90vw/85vh over the spec scrim, with a second PlayerBar docked in the footer sharing the store. Only the page PlayerBar owns the global keyboard map, so keys are never handled twice. role=dialog with aria-modal, labelled by the panel name, focus moves in and is trapped, Esc/X/scrim close, and focus returns to the opener. focusPanelId already lives in the URL, so shared links open pre-focused; on mobile the modal becomes a full-screen sheet.
This commit is contained in:
parent
eb1f7427c4
commit
8929eeddb0
4 changed files with 260 additions and 3 deletions
|
|
@ -3,6 +3,7 @@ import { onMounted } from 'vue'
|
|||
import AppBar from '@/components/AppBar.vue'
|
||||
import ControlsCard from '@/components/ControlsCard.vue'
|
||||
import ErrorBanner from '@/components/ErrorBanner.vue'
|
||||
import FocusModal from '@/components/FocusModal.vue'
|
||||
import FooterDisclaimer from '@/components/FooterDisclaimer.vue'
|
||||
import HeroHeadline from '@/components/HeroHeadline.vue'
|
||||
import LegendRow from '@/components/LegendRow.vue'
|
||||
|
|
@ -45,6 +46,7 @@ onMounted(async () => {
|
|||
/>
|
||||
</main>
|
||||
<FooterDisclaimer />
|
||||
<FocusModal v-if="store.state.focusPanelId" />
|
||||
<div class="visually-hidden" aria-live="polite">{{ store.state.announcement }}</div>
|
||||
</template>
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue