Skip to content

fix(hub-ui): mark the selected dock with aria-current - #475

Merged
antfu merged 6 commits into
devframes:mainfrom
erkamyaman:fix/dock-aria-current
Nov 1, 2026
Merged

antfu merged 6 commits into
devframes:mainfrom
erkamyaman:fix/dock-aria-current

Conversation

@erkamyaman

@erkamyaman erkamyaman commented Nov 1, 2026 •

Copy link
Copy Markdown
Contributor

The dock bar and the group sidebar showed the selected dock only with a scale and a color. A screen reader announced every dock button the same way, so its user could not tell which dock was open (WCAG 4.1.2).

The button of the dock whose view is shown now gets aria-current="page", in the dock bar, the group sidebar, and the group and overflow popover. One helper, getCurrentDockId(), decides which dock that is: the selected dock, but not an action, and not while the panel of an embedded dock is closed. A group button is not marked, so a group and its member are never both current.

Checks

  • eslint on the changed files, and tsc --noEmit in packages/hub-ui
  • The standalone and embedded builds both have aria-current
  • In Chromium, standalone hub: exactly one button is aria-current="page", and it moves when another dock is selected

The dock bar and the group sidebar marked the selected dock only with a
scale and a color, so a screen reader announced every dock button the
same way and its user could not tell which dock was open (WCAG 4.1.2).

The button of the dock that is shown now gets `aria-current="page"`. A
new `isCurrent` prop carries this, because `isSelected` is also on
while a group popover is merely open. Group members in the sidebar get
the same attribute.
Copilot AI balanced review requested due to automatic review settings November 1, 2026 12:04
@vercel

vercel Bot commented Nov 1, 2026

Copy link
Copy Markdown

@erkamyaman is attempting to deploy a commit to the NuxtLabs Team on Vercel.

A member of the Team first needs to authorize it.

@github-actions

github-actions Bot commented Nov 1, 2026 •

Copy link
Copy Markdown

👁️‍🗨️ Review this pull request with grouped, summarized diffs at:
👉 https://pulls.review/gh/devframes/devframe/475?from=github-actions[bot]

raw result

💭 analyzed by vercel-ai-gateway/anthropic/claude-sonnet-5
🕰️ 2026-11-01 12:53 UTC
🔗 head 3a56edf
🤖 automated by pulls.review

{
  "headSha": "3a56edf266a8c641a8d16eed626946f163ca1446",
  "result": {
    "overallSummary": "Fixes an accessibility bug (WCAG 4.1.2) where screen readers couldn't tell which dock was selected, since it was only conveyed visually via scale/color. Adds a shared `getCurrentDockId`/`holdsCurrentDock` helper and applies `aria-current` across the dock bar, group sidebar, and the group/overflow popovers so exactly one button is marked current at a time.",
    "groups": [
      {
        "key": "core-logic",
        "label": "Current dock helper",
        "summary": "Adds `getCurrentDockId()` and `holdsCurrentDock()` to decide, from the docks context, which single dock is the one currently shown (excluding actions, and none while an embedded panel is closed), and whether a group button should stand in for a hidden current member.",
        "category": "core",
        "filePaths": [
          "packages/hub-ui/src/client/state/docks.ts"
        ],
        "critical": true
      },
      {
        "key": "ui-aria-current",
        "label": "Apply aria-current in UI",
        "summary": "Wires the new `getCurrentDockId`/`holdsCurrentDock` helpers into the dock bar, group sidebar, group popover and overflow popover so exactly one button gets `aria-current=\"page\"` (or `\"true\"` for a group/overflow button holding a hidden current dock), fixing the WCAG 4.1.2 issue where screen readers couldn't tell which dock was open.",
        "category": "ui",
        "filePaths": [
          "packages/hub-ui/src/client/components/dock/DockEntries.vue",
          "packages/hub-ui/src/client/components/dock/DockEntry.vue",
          "packages/hub-ui/src/client/components/dock/DockGroupButton.vue",
          "packages/hub-ui/src/client/components/dock/DockGroupPopover.vue",
          "packages/hub-ui/src/client/components/dock/DockGroupSidebar.vue",
          "packages/hub-ui/src/client/components/dock/DockOverflowButton.vue"
        ],
        "fileNotes": [
          {
            "path": "packages/hub-ui/src/client/components/dock/DockEntry.vue",
            "text": "New `current` prop distinguishes `page` (the dock actually shown) from `true` (a group/overflow button merely holding it), unlike `isSelected` which also lights up while a group popover is open."
          }
        ]
      },
      {
        "key": "tests",
        "label": "Tests for current-dock logic",
        "summary": "Unit tests covering the new helpers: selection vs. action vs. closed embedded panel, and the rule that a group is only marked current when its current member has no button of its own.",
        "category": "tests",
        "filePaths": [
          "packages/hub-ui/src/client/state/docks.test.ts"
        ]
      }
    ],
    "schemaVersion": 1,
    "source": "llm",
    "generatedAt": "2026-11-01T12:53:35.212Z",
    "model": "vercel-ai-gateway/anthropic/claude-sonnet-5",
    "locale": "en"
  }
}

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Outstanding accessibility issues can cause dock navigation to announce hidden or nonexistent pages as current, omit the current page, or mark multiple items as current.

4 open issues
What changed in this PR

This PR improves hub UI accessibility by marking the current dock for screen readers, separately from visual selection state.

Changes:

  • Adds an isCurrent prop that sets aria-current="page" on dock buttons.
  • Passes current-selection state to individual and grouped dock buttons.
  • Marks selected group members in the sidebar.
File Description
packages/​hub-ui/​src/​client/​components/​dock/​DockGroupSidebar.vue Marks the selected sidebar member as current.
packages/​hub-ui/​src/​client/​components/​dock/​DockGroupButton.vue Passes the group's active state as isCurrent.
packages/​hub-ui/​src/​client/​components/​dock/​DockEntry.vue Adds the isCurrent prop and ARIA attribute.
packages/​hub-ui/​src/​client/​components/​dock/​DockEntries.vue Passes selection-based current state to dock entries.

Review effort: Balanced

A group button now gets `aria-current="true"` and only the shown member
gets `page`, so the dock bar and the group sidebar no longer both claim
the current page. The group button finds the shown member among all
its members, also the hidden ones. The member list of the group and
overflow popover marks the shown member too, and an action dock is
never current.
Copilot AI balanced review requested due to automatic review settings November 1, 2026 12:17

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

`aria-current` now comes from one place, `getCurrentDockId()`: the
selected dock, but not an action, and not while the panel of an
embedded dock is closed. Only that dock's button gets
`aria-current="page"`, in the dock bar, the group sidebar or the group
and overflow popover. A group button is no longer marked, so a group
and its member are never both current, and `DockEntry` no longer reads
`dock.type`, which its prop type does not have.
Copilot AI balanced review requested due to automatic review settings November 1, 2026 12:26

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Current dock or member state can remain unannounced to screen readers for grouped and overflow entries, sidebar members, and views that remain visible after toggle actions.

4 open issues
4 resolved since last review

Review effort: Balanced

The shown dock keeps `aria-current="page"`. When it is out of sight, the
button that holds it gets `aria-current="true"`: the group button of its
group, the overflow button of the dock bar, or the show-more button of
the group sidebar. `DockEntry` takes the value through a `current` prop.
Copilot AI balanced review requested due to automatic review settings November 1, 2026 12:36

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Active issues remain with duplicate current announcements and missing current markers for visible docks in popup and float surfaces.

4 open issues
1 resolved since last review

Review effort: Balanced

:is-vertical="isVertical"
:is-selected="isActive || isPanelVisible || hasActiveTool"
:is-dimmed="dimInactive && selected ? !isActive && !hasActiveTool : false"
:current="holdsCurrent ? 'true' : undefined"
A group button was marked `aria-current="true"` even when its shown
member also had a pinned or recent button on the dock bar, so the bar
announced two current items. The group, and an overflow button through
it, now stands in for the member only when the member has no button of
its own. Tests cover `getCurrentDockId()` and `holdsCurrentDock()`.
Copilot AI balanced review requested due to automatic review settings November 1, 2026 12:52

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Current-state handling can mark both a group and its selected member as current, or omit the indication for visible docks in picture-in-picture and overflow layouts.

2 open issues
3 resolved since last review

Review effort: Balanced

Comment on lines +41 to +43
const recentIds = session.recentDockIds ?? (session.recentDockId ? [session.recentDockId] : [])
return recentIds.includes(id)
|| context.docks.groupedEntries.some(([, items]) => items.some(entry => entry.id === id))
@antfu
antfu merged commit be9fd6f into devframes:main Nov 1, 2026
11 of 13 checks passed
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.

3 participants