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

Ability to specify either transition: or the in/out: pair for animation #14452

Open
webJose opened this issue Nov 26, 2024 · 2 comments
Open

Comments

@webJose
Copy link
Contributor

webJose commented Nov 26, 2024

Describe the problem

Right now, it is not possible to create components that can accept an animation specification (say, in the form of an object that satisfies the types shown below) because if an element has the transition: property, it cannot have the in/out: ones and vice versa.

At the very least, we would need to repeat the markup of the element that receives the animation, which is something snippets aimed towards eliminating, but this use case seems to escape them.

Describe the proposed solution

I have defined the following types in an NPM library, so components in the library can have their animation specified via props:

export type Animation<T extends (...args: any) => TransitionConfig> = T | {
    fn: T,
    options: Parameters<T>[1]
}

export type AsymmetricTransition<T extends (...args: any) => TransitionConfig> = {
    in: Animation<T>;
    out: Animation<T>;
}

These types allow the creation of variables (reactive or not) and prop declarations:

    // Variable somewhere:
    const x: Animation<typeof fly> = {
        fn: fly,
        options: {
            duration: 200
        }
    }; // <-- Intellisense provided the list of possible options for the fly function while I typed it.

    // SomeComponent.svelte with generics="TAnimation extends (...args: any) => TransitionConfig = typeof fly", for example.
    type Props = {
        animation?: false | Animation<TAnimation> | AsymmetricTransition<TAnimation>;
    }

The prop defined above is quite interesting:

<SomeComponent
    animation={blur}
    animation={{ fn: blur, options: { /* options for blur here */ }}
    animation={{ in: slide, out: fade }}
    animation={{ in: { fn: fly, options: { ... } }, out: { fn: scale, options: { ... } } }}
>

UPDATE: Added false as possible animation value to disable animation. Helpful in unit testing at the very least.

In the example, the first 2 refer to transition: because they only specify one function, while the second two are for an asymmetric transition with in/out:. I think this is nice and flexible and covers every possibility. The problem is that this is more flexible than Svelte. This forces us to repeat the root element's markup to cover symmetric and asymmetric transitions.

So the proposed solution is to get rid of in/out: altogether as a root prop of the element, stick only to transition: and let transition be as flexible as the animation prop of the example and let it decide in runtime if it is symmetric or asymmetric.

Importance

would make my life easier

@david-plugge
Copy link

As a workaround you can simply use in/out with the same fn

@webJose
Copy link
Contributor Author

webJose commented Nov 27, 2024

As a workaround you can simply use in/out with the same fn

Unfortunately it is not a suitable workaround because the symmetric transition is the only one that is reversible, AFAIK. I mean, Svelte assumes it cannot be reversed unless it is transition:.

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

2 participants