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

Virtual List rendering issue in Popover #8630

Open
mukherjeesudebi opened this issue Feb 4, 2025 · 4 comments · May be fixed by #8642
Open

Virtual List rendering issue in Popover #8630

mukherjeesudebi opened this issue Feb 4, 2025 · 4 comments · May be fixed by #8642
Labels
bug Something isn't working vaadin-virtual-list

Comments

@mukherjeesudebi
Copy link

Description

When a Virtual List is added inside a Popover component and the list is scrolled to end, then on closing and re opening the Popover, the virtual list is blank and appears only when scrolled.

Expected outcome

The Virtual List should appear without the initial scrolling.

Minimal reproducible example

@Route("popover-virtual-list")
public class PopOverVirtualList extends Div {
	public PopOverVirtualList() {

		Button button = new Button(LumoIcon.BELL.create());
		button.addThemeVariants(ButtonVariant.LUMO_ICON);
		button.setAriaLabel("Notifications");

		Popover popover = new Popover();
		popover.setPosition(PopoverPosition.BOTTOM_END);
		popover.setOpenOnClick(true);
		popover.setCloseOnEsc(true);
		popover.setTarget(button);
		popover.setWidth("300px");
		popover.addThemeVariants(PopoverVariant.ARROW, PopoverVariant.LUMO_NO_PADDING);
		popover.setPosition(PopoverPosition.BOTTOM);
		popover.setAriaLabelledBy("notifications-heading");

		List<Person> people = Person.getPeople(500);
		
		VirtualList<Person> virtualList = new VirtualList<>();
		virtualList.setItems(people);
		virtualList.setRenderer(personCardRenderer);
		add(virtualList);
		popover.add(virtualList);

		add(button, popover);

	}

	private ComponentRenderer<Component, Person> personCardRenderer = new ComponentRenderer<>(person -> {
		HorizontalLayout cardLayout = new HorizontalLayout();
		cardLayout.setMargin(true);

		Avatar avatar = new Avatar(person.getFullName(), null);
		avatar.setHeight("64px");
		avatar.setWidth("64px");

		VerticalLayout infoLayout = new VerticalLayout();
		infoLayout.setSpacing(false);
		infoLayout.setPadding(false);
		infoLayout.getElement().appendChild(ElementFactory.createStrong(person.getFullName()));
		infoLayout.add(new Div(new Text("Dummy profession")));

		VerticalLayout contactLayout = new VerticalLayout();
		contactLayout.setSpacing(false);
		contactLayout.setPadding(false);
		contactLayout.add(new Div(new Text("Dummy email")));
		contactLayout.add(new Div(new Text("Dummy phone")));
		infoLayout.add(new Details("Contact information", contactLayout));

		cardLayout.add(avatar, infoLayout);
		return cardLayout;
	});

}

Steps to reproduce

  1. Add the above code to a vaadin 24.6.4 sample project
  2. Click on the bell icon to open the Popover
  3. Scroll to end
  4. Click outside to close the Popover
  5. Click on bell icon to re open the Popover

Environment

Vaadin version(s): 24.6.4

Browsers

No response

@subITCSS
Copy link

subITCSS commented Feb 4, 2025

RenderingIssue.mp4

@web-padawan
Copy link
Member

Could be related to #6431, see especially #6431 (comment)

@web-padawan web-padawan added vaadin-virtual-list bug Something isn't working labels Feb 4, 2025
@web-padawan
Copy link
Member

Reproduced with the web component using the following example:

<button>Open</button>

<vaadin-dialog></vaadin-dialog>

<script type="module">
  import '@vaadin/dialog';
  import '@vaadin/virtual-list';

  const dialog = document.querySelector('vaadin-dialog');
  dialog.renderer = (root) => {
    if (!root.firstChild) {
      const items = Array.from({ length: 100000 }).map((_, i) => {
        return { label: `Item ${i}` };
      });

      const renderer = (root, _, { item }) => {
        root.innerHTML = `<div>${item.label}</div>`;
      };

      const list = document.createElement('vaadin-virtual-list');
      list.style.height = '300px';
      list.items = items;
      list.renderer = renderer;
      root.appendChild(list);
    }
  }

  document.querySelector('button').addEventListener('click', () => {
    dialog.opened = true;
  });
</script>

Steps to reproduce:

  1. Open the dialog
  2. Scroll the list
  3. Re-open the dialog -> items disappear

@web-padawan
Copy link
Member

web-padawan commented Feb 5, 2025

UPD: this seems related to the vaadin-virtual-list being disconnected and moved to other parent, which happens with overlays. The issue occurs even if the visibility of the element doesn't change, see the reproduction below:

<button>Move to body</button>

<div>
  <vaadin-virtual-list style="height: 400px" data-overlay></vaadin-virtual-list>
</div>

<script type="module">
  import '@vaadin/virtual-list';

  const items = Array.from({ length: 100000 }).map((_, i) => {
    return { label: `Item ${i}` };
  });

  const renderer = (root, _, { item }) => {
    root.innerHTML = `<div>${item.label}</div>`;
  };

  const list = document.querySelector('vaadin-virtual-list');
  list.items = items;
  list.renderer = renderer;

  const div = document.querySelector('div');

  const button = document.querySelector('button');

  button.addEventListener('click', () => {
    if (list.hasAttribute('data-overlay')) {
      // Teleport to body
      list.removeAttribute('data-overlay');
      document.body.appendChild(list);
      button.textContent = 'Move to div';
    } else {
      // Teleport to div
      list.setAttribute('data-overlay', '');
      div.appendChild(list);
      button.textContent = 'Move to body';
    }
  });
</script>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working vaadin-virtual-list
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants