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

Svelte 5: Run outro transition on unmount #13728

Closed
typhonrt opened this issue Oct 21, 2024 · 6 comments
Closed

Svelte 5: Run outro transition on unmount #13728

typhonrt opened this issue Oct 21, 2024 · 6 comments

Comments

@typhonrt
Copy link
Contributor

typhonrt commented Oct 21, 2024

Describe the problem

With Svelte 3 & 4 using a crafty workaround with code example at the end of this issue it is possible to destroy components after outro transitions are run.

Svelte 3&4 related issue: #4056

Is there any comparable svelte/internal mechanisms accessible in Svelte 5 to achieve the same result? I have not found a corresponding capability yet in upgrading my framework to Svelte 5. This would be a rather debilitating situation without a solution for various use cases required by my framework.

It would be nice if unmount in Svelte could take an options object with { outro: boolean } and return a Promise. IE run outro transition, destroy / unmount component and then resolve the Promise.

This would make the declaration:

/**
 * Unmounts a component that was previously mounted using `mount` or `hydrate`. When `outro` is true outro transitions
 * are run before unmounting.
 */
export async function unmount(component: Record<string, any>, options?: { outro: boolean }): Promise<void>;

// Alternate suggestion given that `unmount` should stay synchronous:

/**
 * Unmounts a component that was previously mounted using `mount` or `hydrate` and run any outro transition.
 */
export async function unmountWithOutro(component: Record<string, any>): Promise<void>;

The Svelte 3 & 4 solution to the problem:

import { check_outros, group_outros, transition_out } from 'svelte/internal';

/**
 * Runs outro transition then destroys Svelte component.
 *
 * Workaround for https://github.com/sveltejs/svelte/issues/4056
 *
 * @param {SvelteComponent}  instance - A Svelte component.
 *
 * @returns {Promise<void>} Promise resolved after outro transition completes and component destroyed.
 */
export async function outroAndDestroy(instance)
{
   return new Promise((resolve) =>
   {
      if (instance.$$.fragment && instance.$$.fragment.o)
      {
         group_outros();
         transition_out(instance.$$.fragment, 0, 0, () =>
         {
            instance.$destroy();
            resolve();
         });
         check_outros();
      }
      else
      {
         instance.$destroy();
         resolve();
      }
   });
}

Describe the proposed solution

Modify unmount to take an options object indicating that the outro transition should run and complete before unmounting returning a Promise. Or provide an alternate unmountWithOutro function.

Importance

i cannot use svelte without it / blocking upgrade to Svelte 5.

@Serator
Copy link

Serator commented Nov 4, 2024

Is there a workaround to solve this issue? I'd like to use a portal based on mount and Svelte transitions, but unmount destroys the content ignoring outro transitions.

So far the only thing that comes to mind is to wrap the contents of the portaral in a condition and switch this condition first, and call unmount on the outroend event, but I would like a simpler solution. Thanks.

@Azarattum
Copy link
Contributor

I'm looking for a way to run transitions without component destruction (assuming I control DOM removal myself). This feature request would greatly help with that. Something like this could be perfect for my use-case:

export async function unmount(component: Record<string, any>, options?: { outro?: boolean, destroy?: boolean }): Promise<void>;

@typhonrt
Copy link
Contributor Author

Just saying this would be a fantastic "Svelte advent" feature to deliver and it will bring much rejoicing; this seems like low hanging fruit in terms of implementation. There isn't much possible in constructing a Svelte 5 workaround due to svelte/internal being gated now.

In my larger framework I have been able to remove all other usage of svelte/internal, but this remains to be the only blocker to Svelte 5 and is a necessary feature. It's great that it worked via a workaround in Svelte 3&4, but now needs some attention from the maintainers.

@Serator
Copy link

Serator commented Dec 14, 2024

https://github.com/sveltejs/svelte/releases/tag/svelte%405.13.0 - it looks like the outro option is already available.

@dummdidumm
Copy link
Member

Closed by #14540

@typhonrt
Copy link
Contributor Author

typhonrt commented Dec 15, 2024

Thanks so much for looking into this and getting it handled! Even the demo for the feature shows how useful / neat / handy it is...

Next up I'm sure I'll be chiming in on some of the new transition / WAAPI areas in terms of refinement, but after I get my larger framework to Svelte 5 so I can put things through the paces so to speak.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants