Repository navigation
Wizard page scrolls to the top after every Livewire update when the active step contains a dropdown (regression in v5.10.1) #20742
Description
Package
filament/schemas
Package Version
v5.10.2
Laravel Version
v13.35.0
Livewire Version
v4.4.7
PHP Version
PHP 8.5.10
Problem description
Since v5.10.1, any Livewire update on a page with a Wizard scrolls the page back to the top whenever the active step contains a dropdown (for example a Builder's add-block menu or an ActionGroup). With a ->live() field, this happens on every keystroke, so you can't edit fields further down a long step.
It's caused by two things that combine:
Wizard\Step::toHtml()renders a staticx-cloakon the step panel, and the step has nowire:ignore.self. Alpine removesx-cloakon load, so every Livewire morph adds it back and the whole active step isdisplay: noneuntil Alpine's next microtask removes it again.- Since fix: support keyboard navigation in dropdown menus #20669 ("support keyboard navigation in dropdown menus", first released in v5.10.1), the dropdown's
MutationObserverrunssyncAria()→getTrigger()→isElementVisible()(getComputedStyle()+getClientRects()) while the morph is still running. Reading layout while the step is hidden makes the document collapse, so the browser clampsscrollYto0.
Point 1 alone is harmless: no layout is read while the step is cloaked. Before #20669, nothing read layout during that window. In the reproduction:
| Version | x-cloak re-added to the step on update |
Page jumps to top |
|---|---|---|
| v5.10.0 | yes | no |
| v5.10.1 / v5.10.2 | yes | yes |
v5.10.2, step without the Builder (no dropdown in the step) |
yes | no |
v5.10.2, step with ->extraAttributes(['wire:ignore.self' => true]) |
no | no |
Stack trace of the layout read while the step had x-cloak (v5.10.1):
window.getComputedStyle
Proxy.isElementVisible (support.js)
Array.find
Proxy.getTrigger (support.js)
Proxy.syncAria (support.js)
MutationObserver.<anonymous> (support.js)
Expected behavior
The page keeps its scroll position after a Livewire update, as it did in v5.10.0.
Steps to reproduce
- Clone the reproduction repository, then run
composer setupandphp artisan serve. - Log in at
/admin(test@example.com/password) and open/admin/wizard-scroll-reproduction. - The wizard starts on its second step. That step contains a
Builder, 30 filler inputs and, at the bottom, a->live()text input. - Scroll to the bottom input and type a character.
- After the Livewire update, the page jumps to the top.
The whole reproduction is one page:
Wizard::make([
Step::make('First')
->schema([
TextInput::make('name'),
]),
Step::make('Second')
->schema([
Builder::make('blocks')
->blocks([
Block::make('heading')
->schema([
TextInput::make('text'),
]),
]),
...collect(range(1, 30))
->map(fn (int $number): TextInput => TextInput::make("filler_{$number}"))
->all(),
TextInput::make('type_here')
->live(),
]),
])
->startOnStep(2),Reproduction repository (issue will be closed if this is not valid)
https://github.com/yuges92/filament-wizard-scroll-repro
Workaround / possible fix
Adding wire:ignore.self to every step fixes it, the same way the Wizard and Tabs roots already use wire:ignore.self. A step's own attributes are static, and Alpine binds fi-active, so only its children need morphing:
Step::configureUsing(
fn (Step $step): Step => $step->extraAttributes(['wire:ignore.self' => true], merge: true),
);Possible fixes in Filament:
- add
wire:ignore.selfto the step panel inWizard\Step::toHtml(), or - defer the dropdown's
syncAria()visibility check until after the morph and Alpine'sx-cloakremoval, for example withqueueMicrotask()orrequestAnimationFrame().
A collapsible Section that renders x-cloak on its content wrapper (collapsed or persisted-collapsed) may hit the same problem, but I haven't confirmed it.
Activity
people-sea commentedon Oct 14, 2026
This seems related to alpinejs/alpine#4922. I can reproduce it with the bundled Alpine, and testing that PR’s change locally kept the scroll position stable in the Wizard, Section and visibleJs() cases I tried. The change doesn’t seem to be included in the latest Alpine release (3.17.4) or Livewire bundles (3.8.10 / 4.4.7) yet.