Skip to content

fix(a11y): hide teleported popovers behind a maximized blade - #345

Merged
maksimzinchuk merged 1 commit into
mainfrom
fix/VCST-5815-popover-inert
Sep 1, 2026
Merged

fix(a11y): hide teleported popovers behind a maximized blade#345
maksimzinchuk merged 1 commit into
mainfrom
fix/VCST-5815-popover-inert

Conversation

@maksimzinchuk

Copy link
Copy Markdown
Collaborator

Problem

The app hub and the notification panel both teleport out of the <nav> that carries the covering state, so they land as siblings of it rather than descendants — and inert does not cross a Teleport. Maximizing a blade left both panels in the tab order and in the accessibility tree, reachable behind content that was supposed to be covering them.

VcSidebar and VcAiAgentPanel already got this treatment in #306; these two were missed because their teleport hides the relationship.

Fix

  • VcPopover gets an inert prop rendered on its teleported root. It has to be a prop: a fallthrough attribute never reaches the real root through the Teleport.
  • AppHubPopover forwards it to the VcPopover it wraps.
  • DesktopLayout passes the covering state to both panels explicitly.

MobileLayout renders neither panel, so it needs nothing.

Tests

  • vc-popover.test.ts — the panel carries inert when covered; the attribute is absent otherwise (inert="false" is still inert in HTML, so absence is the assertion).
  • DesktopLayout.test.ts — the layout tells both panels they are covered. This is the assertion that matches the defect: the panels were fine, the layout never told them.

Removing either binding fails exactly these tests.

Verification

vue-tsc clean · vitest run 4090 passed, exit 0 · lint:check clean · prettier, stylelint, madge, layer checks, docs:lint clean.

Closes VCST-5815

The app hub and notification panels teleport out of the <nav> that carries
the covering state, so they end up siblings of it rather than descendants —
and `inert` does not cross a Teleport. Maximizing a blade left both panels
in the tab order and in the accessibility tree, reachable behind content
that was supposed to be covering them.

Give VcPopover an `inert` prop rendered on its teleported root and pass the
state down from DesktopLayout, the same treatment the AI agent panel and the
mobile sidebar already had.
@github-actions

github-actions Bot commented Sep 1, 2026

Copy link
Copy Markdown

📦 Preview published for commit 356b508

Install the preview with dist-tag:

npm install @vc-shell/framework@pr-345

Or pin to the exact commit:

npm install @vc-shell/framework@2.5.0-pr345.356b508

Published packages (dist-tag pr-345, version 2.5.0-pr345.356b508):

  • @vc-shell/framework
  • @vc-shell/api-client-generator
  • @vc-shell/create-vc-app
  • @vc-shell/config-generator
  • @vc-shell/migrate
  • @vc-shell/ts-config
  • @vc-shell/mf-config
  • @vc-shell/mf-host
  • @vc-shell/mf-module
  • @vc-shell/vc-app-skill

@maksimzinchuk
maksimzinchuk merged commit 1196a81 into main Sep 1, 2026
12 checks passed
@maksimzinchuk
maksimzinchuk deleted the fix/VCST-5815-popover-inert branch September 1, 2026 14:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant