A lightweight transition library for solid-js.
npm i @otonashixav/solid-flipyarn add @otonashixav/solid-flippnpm i @otonashixav/solid-flip<TransitionGroup
enter={animateEnter()}
exit={animateExit()}
move={animateMove()}
>
<For each={list()}>{(item) => <span>{item}</span>}</For>
<Switch fallback={<span>Fallback Tab</span>}>
<Match when={number() === 1}>
<span>Tab 1</span>
</Match>
<Match when={number() === 2}>
<span>Tab 2</span>
</Match>
<Match when={number() === 3}>
<span>Tab 3</span>
</Match>
<Match when={number() === 4}>
<span>Tab 4</span>
</Match>
</Switch>
</TransitionGroup>The TransitionGroup component should wrap elements to be transitioned. Only Elements (not TextNodes or other non-Element Nodes) are supported.
These are callbacks which if provided, are used to animate child elements as they enter, exit and are reordered. You can either pass your own functions or use the provided integrations.
A callback called when elements enter. Accepts an array of entering elements. Used to transition entering elements. If initial is defined on the function, it will be called when the TransitionGroup component is created if there is no initial prop passed in.
A callback called when elements exit. Accepts an array of exiting elements and a callback to remove one or all of them. Used to transition exiting elements.
A callback called when children elements are added, removed, or reordered. Accepts an array of all elements. Used to move elements using the FLIP technique.
A callback called initially when the TransitionGroup component is first created. Accepts an array of all initally present elements. Used to apply initial styling. Also accepts a boolean; if true, calls enter, and if false, stops enter.initial from being called if present.
All of these integrations can be provided with either keyframes (as a string or callback) and options to be passed to element.animate or a callback to manually animate an element.
These animation options are applied by default:
const DEFAULT_OPTIONS = {
duration: 300,
easing: "ease",
fill: "backwards",
};function animateEnter(
animate:
| {
keyframes: KeyframeType | ((el: StylableElement) => KeyframeType);
options?: KeyframeAnimationOptions;
}
| ((el: StylableElement) => Promise<unknown>) = {}
): EnterIntegration;animatemust return a Promise if provided with a callback. The elements will be removed once the Promise resolves.keyframesdefaults to a simple fade out animation.unabsolute: SeeundetachEls.reverseExit: truecauses the element to enter by reversing ongoing exit animations, identified byid: exit, instead of entering with the provided animation.
function animateExit(
animate:
| {
keyframes: KeyframeType | ((el: StylableElement) => KeyframeType);
options?: KeyframeAnimationOptions;
}
| ((el: StylableElement) => Promise<unknown>) = {},
options: {
absolute?: boolean;
reverseEnter?: boolean;
separate?: boolean;
} = {}
): ExitIntegration;animatemust return a Promise if provided with a callback. The elements will be removed once the Promise resolves.keyframesdefaults to a simple fade out animation.absolute: SeedetachEls.reverseEnter: truecauses the element to exit by reversing ongoing enter animations, identified byid: enter, instead of exiting with the provided animation.
function animateMove(
animate:
| {
keyframes?: (el: StylableElement, x: number, y: number) => KeyframeType;
options?: KeyframeAnimationOptions;
}
| ((el: StylableElement, x: number, y: number) => void) = {}
): MoveIntegration;keyframes defaults to a simple straight line movement. If providing your own animation, it should move the element from (x, y) to (0, 0).
These add and remove classes to transition elements. These accept a classes object with these properties:
name- If provided, also adds an additional class to each of the other three props. For example, when provided to cssEnter, addsname-enter-from,name-enter-activeandname-enter-toto the classes.from- Classes to add, then remove. This is the starting point for transitioning.active- Classes that should be present during the transition. These usually provide css animations.to- Classes that are added after thefromclasses are removed, and persist after the transition ends.
function cssEnter(
classNames: {
name?: string;
from?: string;
active?: string;
to?: string;
},
options: {
unabsolute?: boolean;
type?: "animationend" | "transitionend" | "both";
} = {}
): EnterIntegration;unabsolute: See undetachEls.
type: Which event to listen to (defaults to both).
function cssExit(
classes: {
name?: string;
from?: string;
active?: string;
to?: string;
},
options: {
absolute?: boolean;
type?: "animationend" | "transitionend" | "both";
} = {}
): ExitIntegration;absolute: See detachEls.
type: Which event to listen to (defaults to both).
Helper functions for composing your own integrations.
Filters an array of elements to just those which have moved after the DOM updates. Returns an array which will contain these elements after the DOM updates.
Sets the position, left, top, width, height and margin properties such that the element is detached from the document flow with position: absolute and left where it was when it began to exit. Uses an animation with id detach.
Clears the position, left, top, width, height and margin properties. Clears an animation with id detach.
Any callbacks run in an onMount will run after entering elements have been mounted.
- Fix SSR.
- Use
createRenderEffectinstead ofcreateEffectin fix in 0.10.3, so that the initial render isn't empty.
- Fix interaction with suspense #6.
- Improve detach by making it not set styles on the element.
- Avoid multiple instances of batching.
- Improve compatibility with Safari (?).
- Call
onEnteredandonExitedeven when there are noenterandexitintegrations.
- Added
onEntering,onEntered,onExiting,onExitedlisteners. Note that while these will be called with arrays,onEnteredis (currently) always called with single element arrays due to implementation details. - Made it possible to use already created elements in
TransitionGroup, allowed exiting elements to be reentered and added other necessary changes to allow aborting exiting. - Made the move integration run before enter, instead of before enter and exit, and delayed the final step of it using nested
onMounts. - Removed
separate; everything is "separate" now, but exiting elements will be batched before exiting to try to reduce the performance impact of this change. - Simplified various types.
- Fix types for
removeEls.
- Remove
onCommitandonUpdate. Instead, useonMountfor the same effect asonUpdate.onCommithas no new equivalent as there is no common use for it, thoughcreateRenderEffectshould always run beforeonMount. - Added
readonlytoInitialIntegrationandMoveIntegrationels parameters, since the passed array should not be modified. This makes the interface less clean, but this is mostly preferable to cloning before passing. removeElsonExitIntegrationnow accepts an optional array of elements in addition to an optional single element.
- Redo scheduler again.
- Properly update the scheduler.
- Remove setTimeout inside removeEls.
- Use the scheduler when removing elements as well.
- Fix css integrations exiting before entering when they were exited within one frame, causing their event handlers to never trigger.
- Make transitions run asynchronously instead of within a computation, avoiding batching which may cause elements to not exit due to caching. This slightly changes how the scheduler works.
- Undo unnecessary fix in 0.7.7 (doesn't do anything).
- Fix initial case return value (returned undefined instead of the set of elements).
- Use computations instead of render effects to avoid batching, in order to hopefully fix elements rarely not exiting.
- Keep
TransitionGroupuninitialized (i.e. delay running or not running initial) until at least one child exists to help with lazily loading children.
- Fix initial not being run with the scheduler.
- Fix checking removed elements against
currentTargetinstead oftargetas intended.
- Simplify reverse enter implementation.
- Default keyframes now use computed styles instead of animating from/to
opacity: 1, making them more compatible with default opacity other than 1, and when exiting halfway through the enter animation.
- Renamed
animateMove'sgetKeyframestokeyframes. - Removed
extraKeyframesListas it is obsoleted by providing an array of keyframes with offsets. - Added the option to pass a callback to
keyframesonanimateEnterandanimateExit.
- Helpers are now called integrations, inspired by
solid-app-router. - Added scheduling to integrations to make it clearer what runs when.
animateintegrations now accept an object for animate parameters instead of taking two parameters for the keyframes and options. They can also accept a callback that animates the element.- Added
separateas an option where applicable, separating removal of elements or classes per element instead of using the first element to remove all elements or classes. - Renamed
fixPositiontoabsoluteto make it clearer what it does. It also works on SVG elements now. - Renamed the
fixPositionsutility todetachElsandfilterMovedtofilterMovedElsto make it clearer what they do. - Added
typeas an option on css integrations to prevent the wrong type of event from triggering the listener. - A custom event is now used to remove enter classes instead of hijacking the
animationendlistener. StylableElementis nowElement & ElementCSSInlineStyleinstead ofElement.- Allowed
initialto be a callback, and allowed it to be provided viaenteras well. - Added
reverseEntertoanimateExit, allowing enter animations to be reversed in causes where it looks cleaner to do so.
- Actually apply the fix in 0.6.1.
- Fixed playground link.
- Accidentally bumped the version number.
- Fixed a bug in
Transitionwhere removed children were not saved until they removed themselves. - Added prettier.
- Make
Transitionprops reactive between transitions, fixing #2. MovedskipInitialto a prop onTransition,initial, which specifies whether to enter the initial children.fixPositionaccepts onlytruenow, since the default isfalseand will remain so.
- Revert change in 0.5.6, as it had unintended side effects.
- Make
Transitionprops reactive between transitions, fixing #2. Additionally swapped the project to spaces over tabs and double quotes over single quotes, following convention.
- Ignore
transitionendandanimationendevents from elements other than the target element, fixing #1.
- Change default
fixPositionto false as it is more often not used than used.
- Update dependencies
toclasses now remain on the element after entering/exiting, enabling some use cases. This should not break any existing cases as far as I am aware.
- Updated playground link
- Added support for
nameand css animations in css helpers, renamed the css helpers. Note that css animations are untested (because I'm unfamiliar with them), so feedback is appreciated
- Added better documentation
- Tried to get peerDependencies to work such that all versions of the solid playground would be compatible with the library, but couldn't do it. Will revisit.
- Fix firefox not applying enter styling on the first frame for whatever reason
- Replaced the
skipInitialparameter inanimateEnterwith an options object; split thecssEnterExitfunction into two,cssTransitionEnterandcssTransitionExit.
- Add a new helper,
cssEnterExitthat takes enter/exit class strings and returns an object containing theenterandexitprops. See the playground link for an example.
- Apply the previous animation fix to all animations instead of just move where it is most apparent
- Fix animation jitteryness in firefox
- Fix opacity values (should not be inherit)
- Fix readme playground link
- A
Transitioncomponent without props will no longer default to having all default transition handlers. Instead, they must now be created with theanimateEnter,animateExit, andanimateMovefunctions, which implement the handlers using the web animations api. Calling them without parameters will use sensible defaults.
- Restore previous operation order to prevent items from sometimes jumping (will need to batch requestAnimationFrame to fix)
- Fix calling done multiple times in the default exit handler
- More optimizations
- Fix invalid keyframes in firefox
- Further optimizations, fixed an issue introduced in 0.2.6 that caused exiting elements to be incorrectly sized on exit
- Slight optimizations and preparations for further improvements
- Fix invalid keyframe values again
- Fixes the sizing of elements with percentage heights and/or margins after
defaultExit
- More optimizations, fix invalid keyframe values
- Slight optimizations and bug fixes
- Fix types
- Animation Handlers now take an array of elements instead of just one, so that multiple
requestAnimationFramecalls do not need to be done, and to simplify some cases e.g. avoiding the entry animation for the initial render. - Split
lifecycleintoenterandexitto avoid having an internal map of exit functions when it is not always needed. Managing the state of individual elements can be done externally when needed.