-
-
Notifications
You must be signed in to change notification settings - Fork 4.3k
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
Keep updating the state during out transition #6479
Comments
Could you provide some use cases where this behavior is desired? |
@dummdidumm Sure. Although the use cases that I personally encountered are a bit niche; I'll try my best to describe them:
Rec.0014.mp4
{#if !hasEverPlayed && !hasEverSeeked}
<!-- NOTE: If the poster is being removed but not as a result of the video being played but as a result of user's seeking, then we don't want to have a fade out transition since we want the relevant frame of the video to be shown instantly, which is to say no transition for the poster. -->
<Poster
{posterUrl}
shouldHaveTransition={hasEverPlayed && !hasEverSeeked}
/>
{/if} This wouldn't work, as Svelte doesn't update the state within the {#if} block, namely the value of the <script lang="ts">
// Imports:
import { fade } from "svelte/transition";
// Props:
export let posterUrl: string;
export let shouldHaveTransition: boolean;
</script>
<img
src={posterUrl}
alt="foo"
class="video-player__poster"
out:fade|local={{ duration: shouldHaveTransition ? 80 : 0 }}
/> Again, the examples I'm providing are perhaps a bit too niche, and that's because I'm currently building a full-fledged video player in Svelte and so these were some of the cases where this limitation was annoying. |
@dummdidumm Hey, I just stumbled into this again and I actually think this wouldn't make sense logically, so unless I'm missing something, we can close this issue. Imagine you have something like this: {#if someObject != null}
<div transition:fade>
{someObject.someProperty}
</div>
{/if} If Svelte continues to keep the state inside the The larger point being that any time you have an Let me know what you think. Am I right here? |
Just encountered the same issue, since I wanted to update a class on an element via the <script>
import {fade} from "svelte/transition";
export let isOpen = false;
let isAnimatingOut = false;
</script>
{#if isOpen}
<aside
in:fade
out:fade
on:introstart={() => isAnimatingOut = false}
on:outrostart={() => isAnimatingOut = true}
class:animate-out={isAnimatingOut}
>
Content
</aside>
{/if} In this case, the class |
Hi there. Also stumbled into this problem today and thankfully found this GH issue. I'm trying to create a custom dropdown, but as you can see, the selected option isn't marked when clicked because the transition starts right after. Thought adding the slightest delay (i.e.: 1ms) would do the trick, but was wrong. Here's the associated code: {#if isDropdownOpen}
<ul class="listbox" transition:scale={{ duration: 250, opacity: 0, start: 0.96, easing: quadOut }}>
{#each options as option}
<li>
<button class="option" role="option" on:click={() => handleOptionClick(option)} >
{#if selectedOption === option}
<Check size="16" />
{:else}
<div class="icon-spacer"></div>
{/if}
{option}
</button>
</li>
{/each}
</ul>
{/if} See how it compares to https://ui.shadcn.com/docs/components/combobox, where the checkmark is seen before the options fade away. Edit: forgot to mention that in my case adding a |
The strategy I've used for dealing with this problem, is to use store reactivity, instead of DSL reactivity, so that outroing child components continue to receive updates. Specifically, just put the relevant state into a store, and then pass the store to each child component so that they can subscribe to it, and then they will update in response to changes to that store even while outroing. A simple example of doing this for the type of combobox situation that @keoshi mentioned is: https://svelte.dev/repl/aa236dfb8f68416c86f4ae431265b595?version=4.2.12 Note that the newly selected item is highlighted while outroing. (I created a generic |
The strategies I outlined in my previous comment don't work with Svelte 5. Despite Svelte 5 having nice granular updates, no DOM updates are carried out at all for components/elements that are outroing. The workaround I came up with (and which feels a bit hacky), is to have the child components use I think it would be good to decide and state in the docs whether or not outroing elements should receive DOM updates. That way it will be clear if this is a bug to fix, a behaviour to work-around, or a limitation to live with. |
I just came across this - my use case was an image gallery with a popup preview that showed a larger version of the hovered item. If the popup has a transition applied, the change to the image src frequently stops working so the view gets out of sync, showing the wrong popup for the hovered image. My quick-fix was to add a use:action to set the src instead, so instead of <img {src} ...> you have <img use:setsrc={src} ... > action: function setsrc(node: HTMLImageElement, src: string) {
function update(src: string) {
node.src = src
}
update(src)
return {
update,
}
} |
I just updated the Svelte 5 workaround I posted previously, to work with the more recent Svelte 5 changes (on:click becoming onclick, and disallowing snippets from being treated as components). It is ergonomically nice enough, but the implementation is hacky (I don't know if calling mount() like this could cause weird things to happen, or performance issues). Update here. |
Describe the problem
Check out this REPL.
When you click the "Close" button at the top, the div at the center starts its out transition, and as soon as the transition begins, the state inside of the div stops getting updated.
This might seem trivial or unimportant; but I have encountered numerous situations where I would've preferred Svelte to keep updating the contents as the out transition is happening. (If it's not clear to you when anyone would want that, I could provide examples.)
Describe the proposed solution
I'd propose that the state keeps being updated until the element is present in the DOM, either by default, or at least we should have a modifier (similar to
local
) that leaves the decision up to the developer:Alternatives considered
Currently, you either have to come to terms with this limitation, or use CSS transitions with CSS classes and then toggle those classes on your element.
Importance
would make my life easier
The text was updated successfully, but these errors were encountered: