skeleton icon indicating copy to clipboard operation
skeleton copied to clipboard

popup on nested layout only works once page is refreshed once

Open TheEisbaer opened this issue 1 year ago • 6 comments

Current Behavior

having a

Expected Behavior

popup should open on first button click

Steps To Reproduce

in my repro:

  1. click on any login button on /login
  2. click on the avatar on the top right -> no popup
  3. reresh page
  4. click on the avatar on the top right -> popup appears

Link to Reproduction / Stackblitz

https://stackblitz.com/~/github.com/TheEisbaer/raise-temp

More Information

No response

TheEisbaer avatar Feb 05 '24 08:02 TheEisbaer

I am pretty sure that the problem is this line because the element annotated with data-popup does not exist yet during Clientside rendering.

Hugos already suggested a mutation observer which is probably the correct way to handle this.

Sarenor avatar Feb 05 '24 09:02 Sarenor

I've tried around for a bit and this seems to work:

	function setDomElements() {
		elemPopup =
			document.querySelector(`[data-popup="${args.target}"]`) ?? document.createElement('div');
		elemArrow = elemPopup.querySelector(`.arrow`) ?? document.createElement('div');
	}

	/**
	 *  MutationObserver callback
	 * @param {MutationRecord[]} mutationsList
	 * @param {MutationObserver} observer
	 */
	function handleMutation(mutationsList, observer) {
		for (const mutation of mutationsList) {
			// If the mutation target has the data-popup attribute and the correct value is set, update the elements and disconnect the observer
			if (
				mutation.target.attributes['data-popup'] &&
				mutation.target.attributes['data-popup'].value == args.target
			) {
				setDomElements(); // Update elements when there's a change in the DOM
				observer.disconnect();
				return;
			}
		}
	}

    //  Instantiate MutationObserver with the callback
	const observer = new MutationObserver(handleMutation);

	// Start observing the target element
	observer.observe(document.body, { childList: true, subtree: true });

TheEisbaer avatar Feb 05 '24 12:02 TheEisbaer

A quick fix for me was to delay loading the element that has the use:popup until onMount has run.

Example:

<script>
    import { onMount } from 'svelte';

    let ready = false;
    onMount(() => {
        ready = true;
    });
</script>

{#if ready}
    <div use:popup={{ event: 'hover', target: 'popup', placement: 'top' }}>
        Test
    </div>
{/if}

<div class="tooltip" data-popup="popup">
    <slot name="tooltip" />
</div>

iamsbro avatar Feb 22 '24 18:02 iamsbro

See my response here: https://github.com/skeletonlabs/skeleton/pull/2466#issuecomment-1964706852

endigo9740 avatar Feb 26 '24 17:02 endigo9740

@endigo9740 Hi Chris, I modified your example to get my issue "working", it seems like its connected to the button thats triggering the popup containing an avatar (or other elements possibly).

on /test when clicking the avatar on the top left I get the same behaviour. skeleton-popup-test.zip

TheEisbaer avatar Feb 27 '24 07:02 TheEisbaer

Thanks @TheEisbaer, I'll circle back and review. If I feel confident the change submitted will resolve the issue I'll reopen and merge.

endigo9740 avatar Feb 27 '24 16:02 endigo9740

Just FYI, we've outlined our plans for Skeleton v2 going forward in the post below. I'm am reaching out now as a heads up, as this ticket is slated to be closed when Skeleton v3 is released. Full details can be found here:

  • https://github.com/skeletonlabs/skeleton/discussions/3063

If you have any questions, please feel free to reach out in the comments below. Thanks!

endigo9740 avatar Dec 18 '24 20:12 endigo9740

Skeleton v3 is about to launch, as such all Skeleton v2 issues like this are now being closed. No further maintenance release will be provided outside of anything required to archive the branch.

endigo9740 avatar Mar 04 '25 22:03 endigo9740