Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Background page scrolls to top when clicking on select listbox in modal #963

Open
3 tasks done
idealerror opened this issue Jan 7, 2025 · 8 comments
Open
3 tasks done
Assignees

Comments

@idealerror
Copy link
Contributor

idealerror commented Jan 7, 2025

Flux version

1.1.2

Livewire version

3.5.12

What is the problem?

When clicking on a select with variant="listbox" in a modal, the page behind the modal scrolls to the top. This happens in both flyout and regular modals.

CleanShot.2025-01-06.at.22.22.07.mp4

Code snippets

<flux:modal.trigger name="edit-profile">
    <flux:button variant="primary">Edit profile</flux:button>
</flux:modal.trigger>

<flux:modal name="edit-profile" variant="flyout" class="md:w-96 space-y-6">
        <div>
            <flux:heading size="lg">Update profile</flux:heading>
            <flux:subheading>Make changes to your personal details.</flux:subheading>
        </div>

        <flux:field>
            <flux:label>Log Type</flux:label>
            <flux:select variant="listbox" wire:model="type_filter" searchable>
                <flux:option value="all">All Changes</flux:option>
                <flux:option value="active">Active Items</flux:option>
                <flux:option value="created">Added Items</flux:option>
                <flux:option value="deleted1">Deleted Items</flux:option>
                <flux:option value="deleted2">Deleted Items</flux:option>
            </flux:select>
        </flux:field>

        <flux:input label="Date of birth" type="date" />

        <flux:input label="Name" placeholder="Your name" />

        <div class="flex">
            <flux:spacer />

            <flux:button type="submit" variant="primary">Save changes</flux:button>
        </div>
    </flux:modal>

How do you expect it to work?

The background should not change when clicking select boxes within modals

Please confirm (incomplete submissions will not be addressed)

  • I have provided easy and step-by-step instructions to reproduce the bug.
  • I have provided code samples as text and NOT images.
  • I understand my bug report will be closed if I haven't met the criteria above.
@idealerror idealerror changed the title Background scrolls to top when clicking on select listbox in modal Background page scrolls to top when clicking on select listbox in modal Jan 7, 2025
@jeffchown
Copy link

@idealerror Converting your code to a Volt component (below), I cannot reproduce your issue. It may be something in the underlying page, shown in your video, that's causing the 'jump'.

If you can provide a copy/pasteable example (preferably in a Volt component) that consistently reproduces the issue, that will help.

Volt component:

<?php

use Livewire\Volt\Component;

new class extends Component {

}; ?>

<div>
    {{-- create some background text --}}
    @for ($i = 0; $i < 100; $i++)
        <div>Line {{ $i }}...</div><br>
    @endfor

    <flux:modal.trigger name="edit-profile">
        <flux:button variant="primary">Edit profile</flux:button>
    </flux:modal.trigger>


    <flux:modal name="edit-profile" variant="flyout" class="space-y-6 md:w-96">
        <div>
            <flux:heading size="lg">Update profile</flux:heading>
            <flux:subheading>Make changes to your personal details.</flux:subheading>
        </div>

        <flux:field>
            <flux:label>Log Type</flux:label>
            <flux:select variant="listbox" searchable>
                <flux:option value="all">All Changes</flux:option>
                <flux:option value="active">Active Items</flux:option>
                <flux:option value="created">Added Items</flux:option>
                <flux:option value="deleted1">Deleted Items</flux:option>
                <flux:option value="deleted2">Deleted Items</flux:option>
            </flux:select>
        </flux:field>

        <flux:input label="Date of birth" type="date" />

        <flux:input label="Name" placeholder="Your name" />

        <div class="flex">
            <flux:spacer />

            <flux:button type="submit" variant="primary">Save changes</flux:button>
        </div>
    </flux:modal>
</div>

@jeffchown
Copy link

@idealerror CORRECTION: I can now reproduce your issue. (Might have been caching on my end)

@jeffchown
Copy link

jeffchown commented Jan 7, 2025

@idealerror For me, the issue does not occur the first time I visit the page (e.g. when the flux:select is blank), but when I:

  • select a value from the flux:select
  • close the flyout
  • click on Edit profile again
  • click the select (which now has my previously selected value in it) to open it with the Search input focused
  • then the underlying page jumps to the top.

@joshhanley Any insights?

@joshhanley
Copy link
Member

@idealerror thanks for reporting and thanks @jeffchown for the component! Yeah this one looks deep, going to have to dig into it properly later.

I found a simpler way:

  • open the flyout
  • open the select
  • close the select
  • open the select again
  • then it jumps.

@jeffchown
Copy link

Interesting that the simpler way causes the same issue - I thought selecting an option from the select might be triggering it. Guess not.

Thanks, @joshhanley

@joshhanley
Copy link
Member

joshhanley commented Jan 8, 2025

Alright, I got to the bottom of it and have submitted a PR with a fix! As a consequence, the fix also fixes #764 😁

PR description below.

The scenario

If you have a modal/ slideover that contains a non-native select, then opening, closing, and then re-opening the select dropdown causes the page to scroll back to the top.

Image

<?php

use Livewire\Volt\Component;

new class extends Component {
    //
}; ?>

<div>
    <div class="h-screen">Scroll down...</div>
    <div class="h-screen">Scroll down...</div>

    <flux:modal.trigger name="edit-profile">
        <flux:button x-on:click="console.log('open')" variant="primary">Edit profile</flux:button>
    </flux:modal.trigger>

    <flux:modal name="edit-profile" variant="flyout">
        <flux:select variant="listbox" searchable class="mt-6">
            <flux:option value="all">All Changes</flux:option>
            <flux:option value="active">Active Items</flux:option>
            <flux:option value="created">Added Items</flux:option>
            <flux:option value="deleted1">Deleted Items</flux:option>
            <flux:option value="deleted2">Deleted Items</flux:option>
        </flux:select>
    </flux:modal>
</div>

The problem

It took a while to find exactly what the problem was, but ultimately the problem is that the dropdown anchorable is trying to reposition when the dropdown is reopened.

Digging through the code, I found that it was Floating UI that was causing the problem.

That led me to the documentation for the autoUpdate() function which has the below note. https://floating-ui.com/docs/autoUpdate

It’s important that this function is only called/set-up when the floating element is open on the screen, and cleaned up when it’s removed. Otherwise, it can cause severe performance degradation, especially with many floating elements being created.

When I reviewed the anchorable code for the select component, I found that the anchorable was never actually cleaned up when it was hidden.

popoverable.getState() && anchorable.reposition()

The solution

The solution was to ensure that if the popover state changes to closed, that we clean up the anchorable.

popoverable.getState() ? anchorable.reposition() : anchorable.cleanup()

I also remembered that there was another similar issue with select dropdowns at the bottom of the page repositioning wrong on a reopen. When I tested that, this fix also fixes that issue.

Fixes #764
Fixes #963

@jeffchown
Copy link

Nice! 2-for-1! Thanks, @joshhanley for the explanation and the fix 👍

@idealerror
Copy link
Contributor Author

Thanks for the quick fix and explanation!

@joshhanley joshhanley self-assigned this Jan 8, 2025
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

No branches or pull requests

3 participants