Skip to content

Fix desktop focus management and accessibility action handling - #4314

Open
Jason Morse (JasonVMo) wants to merge 12 commits into
mainfrom
user/jasonvmo/fix-focus
Open

Jason Morse (JasonVMo) wants to merge 12 commits into
mainfrom
user/jasonvmo/fix-focus

Conversation

@JasonVMo

Copy link
Copy Markdown
Contributor

Platforms impacted

  • iOS
  • macOS
  • win32 (Office)
  • windows
  • Android

Description of changes

Fix desktop focus ownership, activation, and focus visuals across the agentic component library, using shipped V1 Win32 behavior as the Windows compatibility reference and preserving AppKit-specific behavior on macOS.

  • Add ThemedRoot, stable scene input-modality settings, focused-owner subscriptions, and shared-controller popup input boundaries. Apply the scene consistently to Storybook chrome and previews without remounting on theme changes.
  • Centralize native/custom focus-ring policy and styling: native rings by default on Windows/macOS, with the retained custom path on Win32.
  • Add ref-backed focus targets and cancellable requests; migrate interactive components and Input, and commit TabList eligibility/selection before requesting native focus.
  • Preserve exactly-once activation and press cleanup across repeats, overlapping keys, blur, disable, detach, and ref replacement. Coalesce same-instance inline-ref handoffs without render loops or invalidating a valid keyboard press.
  • Introduce the pure, typed resolveAccessibilityAction helper and an accessibility authoring directory in Framework Base. Checkbox, Switch, and Tab share declaration/name resolution, caller-preserving deduplication, and exact dispatch matching: lowercase toggle/select on Windows Fabric and the existing Toggle/Select names on Win32/macOS custom-action paths.
  • Keep the generic Framework Base entrypoint React-only import-safe, fixing the foundation-settings test failure.
  • Port shared focus cases to macOS with narrowly scoped Windows-only pointer assertions, native-readable status probes, platform-correct activation timing, and AppKit FocusZone geometry.
  • Fix macOS native-driver modifier flags and repeated-key tracking; enable and verify macOS Keyboard navigation in CI setup without changing the separate hosted-runner physical-input restrictions.
  • Update component contracts, authoring/testing guidance, changesets, and packages/agentic/components/WIN32-FOCUS-PLAN.md with executed evidence and remaining gates.

Related issues

This PR advances the following work items, but does not complete their full acceptance criteria:

No automatic issue-closing keywords are used because these are broader tracking issues rather than fully resolved individual defects.

Verification

Completed locally on macOS against the changes in this branch:

  • Framework Base: 22 suites, 175 tests, 6 snapshots passed.
  • Agentic Components: 57 suites, 440 tests, 8 snapshots passed.
  • Unified TypeScript build and yarn lage test --no-cache: 80 tasks passed.
  • Affected package format/lint/build checks, repository structural lint, publishing validation, and changeset validation passed.
  • Native macOS driver build, handshake, cache/reuse, and self-test contract passed, including repeated-modifier and left/right-key tracking coverage.
  • macOS production Storybook bundle passed.
  • Owned macOS Storybook smoke rendered 165 stories and ran 22 WDIO cases: 20 passed, 2 explicitly skipped. All 14 focus behavior cases executed, alongside six baseline cases.

The original 18-case suite also passed with real input and zero skips on both Windows Fabric and Win32 before the final follow-up repairs. Those earlier results are not presented as a rerun of the final 22-case catalog.

Before After
React-only Foundation Settings suites failed while importing React Native through Framework Base. Native/generic module separation preserves the React-only entrypoint.
An interrupted macOS keyboard press could stay visually pressed; inline ref handoffs could cause update loops. Regression coverage verifies release cleanup, stable handoffs, and genuine detach/replacement handling.
Windows Fabric action dispatch did not match the declared Toggle/Select casing. One shared resolver keeps declarations and event matching consistent with each endpoint.
macOS ran 6 baseline cases and skipped all 12 focus cases. macOS runs 20 cases, including all 14 current focus behavior cases; only two isolated native AX-state cases skip.
Rapid or repeated modifiers could leak incorrect flags into subsequent input. Native input derives flags from a deduplicated held-physical-key ledger; Shift-release/Tab regression passes.

Remaining validation and platform limits

  • The two macOS skips isolate RNmacOS 0.81.9 Fabric's missing accessibilityState.disabled/selected projection to AXEnabled/AXSelected. Focus exclusion, component-owned state, and activation guards are tested separately, not substituted for native AX state evidence.
  • Rerun the final 22-case catalog on interactive Windows Fabric and Win32 endpoints.
  • Actual UIA Toggle/SelectionItem.Select and macOS AX custom-action invocation, VoiceOver, and broader native/custom-ring and window/restoration qualification remain explicit follow-ups. Physical clicks and state reads do not establish assistive-action dispatch.
  • Run repository tests before native smoke, not concurrently: shared generated-state fixtures can otherwise cause an authenticated lease/nonce failure.

Pull request checklist

  • Automated tests
  • Documentation and examples
  • Keyboard accessibility
  • VoiceOver / native assistive-action qualification
  • Internationalization and right-to-left layout qualification

@github-actions

Copy link
Copy Markdown
Contributor

Bundle size report

Tree-shaken production Metro bundles. Component costs are relative to their platform shell; shell costs are absolute.

Platform Scenario Baseline cost Current cost Cost delta Change Gzip delta Module delta
macos shell 801.3 KiB 801.3 KiB 0.0 KiB 0.00% 0.0 KiB +0
macos components-button 50.1 KiB 57.4 KiB +7.3 KiB +14.58% +2.3 KiB +17
macos components-catalog 267.3 KiB 281.6 KiB +14.3 KiB +5.35% +5.1 KiB +24
macos design-theme-state 33.3 KiB 33.7 KiB +0.4 KiB +1.34% +0.2 KiB +6
macos design-themed-root New 36.1 KiB New New New New
macos design-color-lib 7.1 KiB 7.1 KiB 0.0 KiB 0.00% 0.0 KiB +0
macos design-theme-state-legacy-source 35.3 KiB 35.8 KiB +0.4 KiB +1.26% +0.1 KiB +6
macos design-legacy-theme-from-flex 100.2 KiB 100.7 KiB +0.4 KiB +0.45% +0.1 KiB +6
windows shell 810.2 KiB 810.2 KiB 0.0 KiB 0.00% 0.0 KiB +0
windows components-button 50.0 KiB 57.2 KiB +7.2 KiB +14.43% +2.4 KiB +17
windows components-catalog 267.0 KiB 281.2 KiB +14.2 KiB +5.31% +5.1 KiB +24
windows design-theme-state 33.2 KiB 33.7 KiB +0.5 KiB +1.36% +0.1 KiB +6
windows design-themed-root New 36.0 KiB New New New New
windows design-color-lib 7.1 KiB 7.1 KiB 0.0 KiB 0.00% 0.0 KiB +0
windows design-theme-state-legacy-source 35.3 KiB 35.7 KiB +0.4 KiB +1.27% +0.1 KiB +6
windows design-legacy-theme-from-flex 100.0 KiB 100.4 KiB +0.4 KiB +0.44% +0.1 KiB +6

The job is advisory: size changes are reported but do not fail the pull request. Bundle or analysis errors still fail.


View bundle-size workflow run

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