Skip to content

feat(ui5-toolbar): implement WAI-ARIA toolbar keyboard navigation#13622

Open
plamenivanov91 wants to merge 12 commits into
mainfrom
tb-arrow-nav-1-june
Open

feat(ui5-toolbar): implement WAI-ARIA toolbar keyboard navigation#13622
plamenivanov91 wants to merge 12 commits into
mainfrom
tb-arrow-nav-1-june

Conversation

@plamenivanov91

@plamenivanov91 plamenivanov91 commented Jun 2, 2026

Copy link
Copy Markdown
Contributor

Replace Tab-through-every-item with a proper roving tabIndex +
arrow-key pattern per the WAI-ARIA toolbar pattern.

Keyboard handling

  • [Left]/[Right] navigate between toolbar items (RTL-aware)
  • [Home]/[End] jump to first/last item
  • [Tab]/[Shift+Tab] exit the toolbar — browser native behaviour
    handles this naturally because only one item has tabIndex=0
  • Overflow popover is fully isolated: arrow keys and focusin
    handling are suppressed when the popover is open, leaving the
    popover's natural Tab order intact

Roving tabIndex

  • Only the current toolbar item has tabIndex=0; all others get -1
  • _lastFocusedItem is restored on re-render so focus memory survives
    overflow layout changes
  • When the overflow button disappears (items move back to toolbar),
    focus moves to the last navigable item via focusForToolbarNavigation
  • Overflowed items are reset to tabIndex=0 so Tab works inside the
    overflow popover
  • On popover open, first interactive overflow item receives focus

ToolbarItemBase — hook API for complex items
New overridable methods (all no-ops in base):

  • getToolbarMovementInfo(): reports {currentIndex, itemCount} so the
    toolbar knows when a Left/Right press is at an internal boundary
  • moveWithinToolbarItem(isForward): advances focus within the item
  • focusForToolbarNavigation(isForward): direction-aware focus entry
  • setToolbarForcedTabIndex(tabIndex): distributes roving tabIndex

ToolbarItem — three navigation paths

  • _itemNavigation introspection: components that use ItemNavigation
    internally (e.g. SegmentedButton) are detected via duck-typing and
    their currentIndex/itemCount is read directly
  • getToolbarMovementInfo interface: explicit opt-in for components
    that want to expose caret/selection position as boundary info
  • Multi-child fallback: ToolbarItems with more than one slotted child
    (radio button groups, checkbox groups) are treated as a navigable
    group using _getCurrentNavigationState — no API needed on children

Input / TextArea — caret-aware boundary
Both implement getToolbarMovementInfo() using selectionStart and
value.length so Left/Right only exits to the next toolbar item once
the caret reaches the start or end of the text.

Templates
ToolbarButtonTemplate and ToolbarSelectTemplate: removed tabIndex JSX
prop — setting it on the UI5 host broke F6Navigation's focus traversal.

Docs

  • Updated keyboard handling JSDoc on ui5-toolbar
  • Added WCAG 2.1 notes to accessibleName / accessibleNameRef
  • Restored @csspart root JSDoc entry on ui5-radio-button

Tests (Toolbar.cy.tsx)

  • Arrow Left/Right navigation between items
  • Home/End jump to first/last
  • First overflow item focused on popover open
  • Checkbox group: arrow traversal within group + boundary exit
  • Overflow button: ArrowRight wraps to first item
  • Updated "overflow button disappears" test to check focused
    ToolbarButton directly instead of shadow .ui5-tb-item wrapper

JIRA: BGSOFUIPIRIN-7018
Fixes: #12945

…2 (prevent page scroll on unhandled up/down)
Refactor toolbar keyboard handling around a single toolbar-owned flow.

- centralize arrow and tab navigation in Toolbar
- add movement-info and roving-tabindex hooks to ToolbarItemBase
- adapt grouped ToolbarItem content through shared internal target logic
- restore caret-aware movement for Input and TextArea
- apply forced tabindex to toolbar button/select templates
- remove redundant select-owned keyboard handling
- add Toolbar regressions for checkbox groups and overflow-button exit
@ui5-webcomponents-bot

ui5-webcomponents-bot commented Jun 2, 2026

Copy link
Copy Markdown
Collaborator

@ui5-webcomponents-bot ui5-webcomponents-bot temporarily deployed to preview June 2, 2026 08:48 Inactive
@ui5-webcomponents-bot ui5-webcomponents-bot temporarily deployed to preview June 2, 2026 09:45 Inactive
- Skip focusin/keydown handling when focus is inside the open overflow
  popover, preventing arrow-nav logic from firing inside the popover
- Skip forcedTabIndex on overflowed ToolbarButton/ToolbarSelect so
  overflow items keep their natural tab order
- Fix Tab-exit containment check to use shadow-DOM-aware walk
  (_isNodeInsideElement) instead of contains/shadowRoot.contains
- Remove own-fallback movement info path from ToolbarItem; items without
  _itemNavigation or getToolbarMovementInfo are now treated as single
  tab stops
- Drop dead WeakMap tab-index restoration machinery (no longer needed
  now that overflow items manage their own tab order)
@ui5-webcomponents-bot ui5-webcomponents-bot temporarily deployed to preview June 3, 2026 10:24 Inactive
@plamenivanov91 plamenivanov91 changed the title fix(ui5-toolbar): simplify toolbar item keyboard navigation feat(ui5-toolbar): implement WAI-ARIA toolbar keyboard navigation Jun 3, 2026
Comment thread packages/main/src/Toolbar.ts Outdated
Comment thread packages/main/src/ToolbarItem.ts Outdated
Comment thread packages/main/src/Toolbar.ts Outdated
Comment thread packages/main/src/RadioButton.ts
Comment thread packages/main/src/Toolbar.ts Outdated
@plamenivanov91 plamenivanov91 marked this pull request as ready for review June 10, 2026 12:02
@github-actions

Copy link
Copy Markdown

👋 Heads-up: dev close is in effect

Thanks for the contribution! This repository is currently in dev close ahead of release next (scheduled 2026-07-09, UTC). See the release schedule for the full timeline.

This PR appears to introduce public-API changes (detected by diffing the Custom Elements Manifest against the latest published version on npm):

@ui5/webcomponents

  • ➕ added interface: IInputSuggestionItem
  • ➕ added interface: IToolbarItemContent
  • 🔄 changed attribute value-state (type)
  • 🔄 changed attribute value-state (type)

Could you please hold off on merging into main until the release ships? Public-API changes are best landed in the next dev cycle so they don't slip into the release at the last minute. Once the release is out, this PR is good to go.

If this change must ship in the current release, please request a review from one or two members of @UI5/ui5-team-webc so the team can sign off explicitly.

💬 False positive? If you believe this PR doesn't actually change the public API (e.g. only internal refactoring, or an entry the detector mis-attributed), please reply on this thread — your feedback helps us improve the detection during this trial run.

Posted automatically by the Dev Close Notice workflow.

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.

[ui5-toolbar][A11y]: toolbar keyboard interaction does not align with WCAG requirement

3 participants