Give a text-only dialog's scrolling body the first focus in every engine
With nothing focusable inside, showModal() focuses the <dialog> itself. Chrome's scroll containers are keyboard-focusable, so there the scrolling body became the focus delegate and modal.css drew its inset ring; Firefox and WebKit focused the dialog, where the arrow keys scroll nothing, and WebKit never lets Tab reach a scroll container, so a keyboard could not read a long text-only dialog there at all. <x-modal> now opens through materialShowModal() (resources/js/dialog.js): showModal(), and when the dialog took the focus itself and its body overflows, the body gets tabindex="0" and the focus, as in Chrome. The tabindex goes when the dialog closes. The body is wire:ignore.self, like the dialog: a Livewire render would otherwise morph the tabindex away and WebKit dropped the focus out of the dialog. ContainmentTest now also checks the focus stays on the body through a render. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
b4a82a4dbe
commit
921c8cef04
@@ -422,6 +422,13 @@ it('gives the scrolling body an inset focus ring when a text-only dialog opens f
|
||||
->assertScript("getComputedStyle({$body}).outlineStyle === 'solid'")
|
||||
->assertScript("getComputedStyle({$body}).outlineWidth === '3px'")
|
||||
->assertScript("getComputedStyle({$body}).outlineOffset === '-3px'");
|
||||
|
||||
// Outside Chrome the body holds the focus through a tabindex materialShowModal() gives it; a
|
||||
// Livewire render keeps it (the body is wire:ignore.self), so the focus stays in the dialog.
|
||||
$page->script('window.eval("Livewire.first().$refresh()")');
|
||||
|
||||
$page->assertScript("document.querySelector('dialog[open]') !== null")
|
||||
->assertScript("document.activeElement.matches('[data-md-modal-body]')");
|
||||
});
|
||||
|
||||
it('cycles a bottom sheet\'s preset heights from its handle, announcing each, and closes from the last', function () {
|
||||
|
||||
Reference in New Issue
Block a user