Conversation
The close affordance was a bare <div> wrapping a decorative SVG, so it had
no role and no accessible name — assistive technology announced nothing and
the glyph leaked into the accessibility tree. Add role="button" and an
aria-label qualified with the panel title ("Close <title>"), and mark the
SVG aria-hidden. Keyboard close stays on the tab strip's Delete binding.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…d nav The free WAI-ARIA tab keyboard handler supports Delete/Backspace to close the focused tab (retaining roving focus in the strip) and swaps to Up/Down arrows for vertical strips, but neither path was covered. Add tests for both; the behaviours already pass, so these lock them against regression. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…cking Keyboard docking could only dock a panel into another group; there was no keyboard equivalent of dragging a panel out into a floating group. Add Ctrl+Shift+F (rebindable via the keymap) as a terminal action from the target phase: it floats the moving panel, announces the result, and restores focus. Adds host.floatPanel + a moveFloated message to the catalog. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
fix(dockview-core): accessible name for the default tab close button
test(dockview-modules): cover Delete-close and vertical-strip keyboard nav
feat(dockview): keyboard 'float' terminal action for keyboard docking
…x on activation Two more free-baseline a11y gaps from the audit: the group region must drop its aria-label (not blank it) when the active panel loses its title, and the roving tabindex must follow panel activation — not only arrow-key navigation — so keyboard entry lands on the active tab. Both behaviours already pass; these lock them against regression. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
… preview Keyboard move mode reuses the same .dv-drop-target overlay a mouse drag shows. Nothing asserted it actually renders on entry and is torn down on cancel and on commit. Add those checks so the keyboard↔overlay wiring (and its cleanup) can't silently regress. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
test(dockview-modules): region label removal + roving-tabindex on activation
test(dockview-modules): keyboard docking shows/clears the drop preview
jsdom cannot model a second document (the unit-test window mock reuses the main one), so popout / cross-window focus, per-window listeners and per-window live regions are unverifiable in the unit suite. Add a Playwright harness that drives the built UMD bundles in headless Chromium over a zero-dependency static server, plus a smoke test proving a popped-out group renders in a real second window. This is the foundation the cross-window focus work will build on. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
test(e2e): Playwright cross-window harness for popout behaviour
A popout is a separate document, so the single main-window live region never reached a screen-reader user working in a popout. LiveRegionService now mounts a polite+assertive region in each popout document (synced via a new onDidChangePopouts seam + getPopoutWindows) and routes announce() to the region of the window that currently has focus, falling back to main. A popout that shares the main document (the jsdom test mock) is skipped, so the unit suite is unaffected; real cross-document behaviour is covered by new Playwright e2e tests. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…indows A popout window is a separate `document`, so the keyboard services' single main-document listeners never saw keystrokes made inside a popout, and their `rootElement.contains` gating rejected popout-document targets. Keyboard navigation, docking and Esc/Tab semantics therefore stopped at the window edge. - New core seam `IAccessibilityHost.ownsElement(node)` + `getPopoutWindows()` / `onDidChangePopouts` (the latter two already existed for the live region). `ownsElement` is the cross-document containment primitive: main-shell containment, or whole-document membership of a popout this component controls. - `bindDocumentListeners` (keyboardShared) mirrors a service's document listeners onto every popout document, synced as popouts open/close, skipping a same-document mock. - AccessibilityService + KeyboardDockingService use it, and replace every `rootElement.contains` gate with `ownsElement`. Focus-inside detection now reads the *focused* window's activeElement so close-focus-restore works when focus is in a popout. Test: - core unit `ownsElement.spec` (5) — containment, foreign-doc rejection, popout-doc ownership via stubbed getPopoutWindows, same-doc no-overclaim. - e2e `keyboard-docking.spec` (2) — Ctrl+M armed inside a popout narrates to the popout region and Esc cancels there; a keyboard split committed in the popout acts on the popout's own gridview. All 5 e2e + 107 modules + 1080 core green. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…e focus Two popout-window correctness niches surfaced while completing cross-window a11y. 1. Sash + scrollbar pointer drags were dead inside a popout. `splitview` and `scrollbar` attached their `pointermove`/`pointerup`/`pointercancel` (and the sash's `contextmenu`) listeners to the module-global `document` — the opener, not the popout — so a drag begun in a popped-out window was never heard. Bind the drag to the dragged element's own `ownerDocument` instead (also shields iframes in that document). Affects mouse users too, not just a11y. 2. Maximizing a *different* group than the focused one stranded focus on `<body>`: that group's DOM is hidden, blurring the focused element, and nothing pulled focus back. AccessibilityService already snapshots/restores focus across a `remove`; extend the same was-inside / not-inside guard to the `maximize` mutation. The guard means maximizing the focused group in place is still a no-op, so mouse users are never robbed of focus. Test: - module unit: maximize-into-another-group restores focus into the maximized group (jsdom can't blur a hidden element, so the hidden-element blur is emulated in the will phase; `setActive` doesn't move focus, so the focusContent spy isolates the restore). 108 modules green. - e2e `popout-pointer-drag.spec`: a sash dragged inside a popout resizes its split — only passes because the listeners now live on the popout document. - 1074 core green. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
feat(dockview-core): cross-window accessibility for popout windows
The tab and paneview focus rings were keyed on `:focus` / `:focus-within`, so they also showed on mouse click — visual noise that reads as a defect. Switch the indicator rules to `:focus-visible` (keyboard-only), keeping the descendant case via `:has(:focus-visible)` (e.g. a keyboard-focused close button still rings its tab). The inline tab-rename input keeps `:focus` (inputs should always ring) and the group content container keeps its `outline: none`. WCAG 2.4.7 / 1.4.11. Closes #1372. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
fix(dockview-core): use :focus-visible for keyboard focus indicators
…er-drag-and-maximize-focus # Conflicts: # e2e/fixtures/index.html # packages/dockview-modules/src/accessibilityService.ts
…mize-focus fix(dockview-core): popout-window pointer drags + cross-group maximize focus
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.



Description
Type of change
Affected packages
dockview-coredockview(vanilla JS)dockview-reactdockview-vuedockview-angulardocsHow to test
Checklist
yarn lint:fixpassesyarn formatpassesnpm run genhas been run and generated files are up to dateyarn testpasses