- Notifications
You must be signed in to change notification settings - Fork5
Interface transitions library for Vue 2/3
License
MorevM/vue-transitions
Folders and files
| Name | Name | Last commit message | Last commit date | |
|---|---|---|---|---|
Repository files navigation
Reusable interface transitions forVue 2 andVue 3 with no CSS needed ❤️
✔️ Highly customizable via props;
✔️ Correctly works with grid/flex layouts ingroup mode;
✔️ Considers initial styles of animated elements such astransform oropacity;
✔️ Even more easy-to-use with universalNuxt 2 andNuxt 3 module.
- Node version:
>= 18.0.0 - Nuxt version (if used):
>= 2.17.0 || >= 3.5.0
The plugin will not work if you are using a Node or Nuxt version less than the specified ones.
yarn add @morev/vue-transitions
npm install @morev/vue-transitions
pnpm add @morev/vue-transitions
❗Important note forpnpm>=10.0.0 users
The package relies onpostinstall hook to determine the Vue version and provide proper components.
By default,pnpm@10.0.0 does not execute lifecycle hooks,so to make it work you need to add the package to thepnpm.onlyBuiltDependenciesfield in yourpackage.json before installing:
{"pnpm": {"onlyBuiltDependencies": ["@morev/vue-transitions"] }}If you install the package before adding the entry, you have to set Vue version you are using manually using the commandvue-transitions-version-switch:
# set Vue 3pnpm vue-transitions-version-switch 3# Set Vue 2pnpm vue-transitions-version-switch 2
Even with the command launched, it's important to add thepnpm.onlyBuiltDependencies field so that everything works well in future installations.
bun add @morev/vue-transitions
❗Important note forBun users
The package relies onpostinstall hook to determine the Vue version and provide proper components.
By default,Bun does not execute lifecycle hooks,so to make it work you need to manually add the package to thetrustedDependencies after installing and runbun install again.
{"trustedDependencies": ["@morev/vue-transitions"]}You may skip the following paragraphs if you are going to use the library with Nuxt.
Go to "Usage with Nuxt" section.
Package exports two versions of components:
- Version for
Vue2available with named export/vue2 - Version for
Vue3available with named export/vue3
However, there is also a default export mapped to local version of Vue being used.
Underhood, it utilized thepostinstall npm hook.
After installing the package, the script will start to check the installed Vue versionand redirect the exports to based on the local Vue version.
It feels pretty robust, but if you're worried about, prefer an explicit named import according to the version you're using.
By the way, you can change default export after installation: just run the command
vue-transitions-version-switch <version>
- Example using
yarn:yarn vue-transitions-version-switch 2- Example using
npx:npx vue-transitions-version-switch 3
import{createApp}from'vue';import{pluginasvueTransitionsPlugin}from'@morev/vue-transitions';import'@morev/vue-transitions/styles';constapp=createApp(App);app.use(vueTransitionsPlugin({// Plugin options (optional, described below)}));
importVuefrom'vue';import{pluginasvueTransitionsPlugin}from'@morev/vue-transitions';import'@morev/vue-transitions/styles';Vue.use(vueTransitionsPlugin,{// Plugin options (optional, described below)});
😥 I got an error "This dependency was not found"
For environments that can't resolveexports field (such asNuxt 2)just replace styles import with direct path to file:
- import '@morev/vue-transitions/styles';+ import '@morev/vue-transitions/dist/index.css';
It's recommended to use the named export
plugininstead of default export when setting custom options to get proper type information.
Custom options allows to change default property values.
To change the defaults, pass thedefaultProps key to the plugin settings, listing the key-value pairs of desired props.
You may also change default props per-component, to do so just pass thecomponentDefaultProps key to plugin settings.
Important: these props are not validated, so make sure you define them with right values.
import{createApp}from'vue';import{pluginasvueTransitionsPlugin}from'@morev/vue-transitions';import'@morev/vue-transitions/styles';constapp=createApp(App);app.use(vueTransitionsPlugin({// Default duration for all transitions now is `200`defaultProps:{duration:200,},// But for `<transition-expand>` default duration is `500`componentDefaultProps:{TransitionExpand:{duration:500,}}}));
<template> <transition-fade> <divv-if="isVisible"class="box"> Fade transition </div> </transition-fade></template><script>import {TransitionFade }from'@morev/vue-transitions';exportdefault { components: { TransitionFade }, };</script>
The library exports a ready-to-use universal module for Nuxt 2 and 3 via named export/nuxt.
Using Nuxt, it's recommended to use the module instead of manual installation because:
- Nuxt allows to auto-import components on demand instead of global registration, which is a more performant option.
- It's just faster to do :)
To use, add@morev/vue-transitions/nuxt to themodules section of yournuxt.config.ts /nuxt.config.js:
exportdefaultdefineNuxtConfig({modules:['@morev/vue-transitions/nuxt',],vueTransitions:{// The same options as in the plugin itself.// You will get an autocomplete using Nuxt 3.}});
Enjoy you transition components! 🎉
You may skip this section using Nuxt module - it does it for you.
This section only applies toVSCode setup and global registration of components.
Using Vue 2 withVeturextension installed all components should provide hints as it, no actions required:
Using Vue 3 withVolarextension installed all components should provide hints as it, no actions required:
Basic transition that changes elementopacity. Pretty simple.
Show code
<template> <transition-fade> <divv-if="isVisible">...</div> </transition-fade></template><script>import {TransitionFade }from'@morev/vue-transitions';exportdefault { components: { TransitionFade }, };</script>
Transition that manipulates with actual element size.
If you are old enough you may know this transition as jQueryslideUp/slideDown.
It also can work withX axis likeslideLeft andslideRight(although it's hard for me to come up with a scenario where it will really be needed).
Hasunique prop:axis
Transition that manipulates with element position viatransform: translate().
It requiresoffset prop to calculate desired element position and can work with percentage values.
Examples how to work withoffset prop
<template><!-- Element will fade in and fade out to top. Initial transform is `transform: translate(0, -16px)`--> <transition-slide:offset="[0, -16]"></transition-slide><!-- Element will fade in and fade out to bottom left side. Initial transform is `transform: translate(-16px, 16px)`--> <transition-slide:offset="[-16, 16]"></transition-slide><!-- Element will fade in and fade out to right, and the offset will be relative to the element width itself. Initial transform is `transform: translate(100%, 0)`--> <transition-slide:offset="['100%', 0]"></transition-slide><!-- Element will fade in from top and fade out to bottom, and the offset will be relative to the element height itself. Transform before element appears: `transform: translate(0, -100%)` Transform when element disappears: `transform: translate(0, 100%)`--> <transition-slide:offset="{ enter: [0, '-100%'], leave: [0, '100%'] }" ></transition-slide></template>
It respects the transform applied to element itself via CSS and merges it with defined offset.
It's very useful, for example, when you are trying to make centered dropdown.
👀 Show example of `transform` merging
<template> <divclass="block"><!-- In this case, given the CSS styles, initial transform will be calculated to `translate(-50%, -16px)`--> <transition-slide:offset="[0, -16]"> <divclass="block__dropdown"v-if="isVisible"> ... </div> </transition-slide> </div></template><style>.block {position:relative; }.block__dropdown {position:absolute;top:100%;left:50%;transform:translateX(-50%); }</style>
Hasunique prop:offset
Transition that manipulates with elementtransform: scale().
By default, it scales element fromscale(1) toscale(0), but this behavior can be customized via:scale prop.
It works with different axis viaaxis prop.
Hasunique props:scale,axis,origin
Show example of code
<template><!-- This element appears in `x` axis and disappears in `y`--> <transition-scale:axis="{ enter: 'x', leave: 'y' }"></transition-scale><!-- This element behaves like the `transition-expand`, but touches only `transform` property--> <transition-scaletransform-origin="50% 0%"></transition-scale><!-- This element scales just a little when fading in/out.--> <transition-scale:scale=".8"></transition-scale></template>
Those properties are related to each transition:
group
Whether the component should be atransition-group component.
exporttypeTransitionGroup=boolean;// Default: false
Example:
<template> <div><!-- To animate a list of items, use `group` prop. ⚠️ Don't forget you should pass the `:key` to each item in this case.--> <transition-fadegroup> <divv-for="item in items":key="item.id">...</div> </transition-fade> </div></template>
tag
Transition tag, in the case of using atransition-group component.
exporttypeTransitionTag=string;// Default: 'span'
Example:
<template> <div><!-- Passing the tag renders transition component with it. It's suitable, for example, for rendering semantic lists:--> <transition-fadegrouptag="ul"> <liv-for="item in items":key="item.id">...</li> </transition-fade><!-- ✨ Rendered HTML:--> <ul> <li>...</li> <li>...</li> </ul> </div></template>
appear
Whether to apply a transition on the initial render of a node.Acts literally the same as originalVue transition appear prop
exporttypeTransitionAppear=boolean;// Default: undefined
Example:
<template> <div><!-- This element appears when mounted if `isVisible` is `true` by default.--> <transition-fadeappear> <divv-if="isVisible">...</div> </transition-fade> </div></template>
mode
exporttypeTransitionMode='in-out'|'out-in'|undefined;// Default: undefined
Example:
<template> <div><!-- Current element transitions out first, then when complete, the new element transitions in.--> <transition-slidemode="out-in"> <component:is="currentComponent">...</component> </transition-slide> </div></template>
duration
Transition animation duration, ms.
If an object given thenenter andleave values will be used for enter and leave transition respectively.
// Default: 300exporttypeTransitionDuration=number|{enter:number,leave:number}
Example:
<template> <div><!-- If single value provided, the passed amount of milliseconds applied to enter and leave animations both. This element will appear and disappear within 500ms:--> <transition-fade:duration="500"> <divv-if="isVisible">...</div> </transition-fade><!-- If an object given, it SHOULD have `enter` and `leave` keys. This element appears in 200ms and disappears within 500ms:--> <transition-fade:duration="{ enter: 200, leave: 500 }"> <divv-if="isVisible">...</div> </transition-fade> </div></template>
move-duration
Duration of animation of elements positions changing, in the case of using atransition-group.
Although Vue does not have a native way to set the duration of the move animation via props, this task can be done usingCSS Custom Properties.
👀 Show explanation
```html<!-- This way it can be set dynamically --><div> <div></div> <div></div></div>``````css.scale-move { transition-duration: var(--move-duration, 300ms);}```// Default: 300exporttypeTransitionMoveDuration=number;
delay
Transition animation delay, ms.
If an object given thenenter andleave values will be used for enter and leave transition respectively.
// Default: 300exporttypeTransitionDelay=number|{enter:number,leave:number};
Example:
<template> <div><!-- If single value provided, then enter and leave animations will wait for given amount of milliseconds before run. This element will appear and disappear 100ms after `isVisible` property changes:--> <transition-fade:delay="100"> <divv-if="isVisible">...</div> </transition-fade><!-- If an object given, it SHOULD have `enter` and `leave` keys. This element appears immediately and disappears 200ms after `isVisible` property changes:--> <transition-fade:duration="{ enter: 0, leave: 300 }"> <divv-if="isVisible">...</div> </transition-fade> </div></template>
easing
Transition animation easing. Should be a valid CSS transition timing function.
If an object given thenenter andleave values will be used for enter and leave transition respectively.
exporttypeTransitionEasing=string;// Default: 'cubic-bezier(.25, .8, .5, 1)'
Example:
<template> <div><!-- If single value provided, then enter and leave animations will use it:--> <transition-fadeeasing="ease-out"> <divv-if="isVisible">...</div> </transition-fade><!-- If an object given, it SHOULD have `enter` and `leave` keys. This element uses custom animation known as `bounce-in` for entering and simple `ease-out` curve for leaving:--> <transition-fade:easing="{ enter: 'cubic-bezier(0.6, 0, 0.4, 2)', leave: 'ease-out' }" > <divv-if="isVisible">...</div> </transition-fade> </div></template>
no-opacity
Whether tonot animate the elementopacity.
By default, each transition manipulatesopacity in addition to the main property.
However, sometimes this is not required - for example, when implementing modal panels that appear from the edge of the screen.
The prop is obviously not applicable to
transition-fadecomponent.
exporttypeTransitionNoOpacity=boolean;// Default: false
Example:
<template> <div><!-- This panel appears from the right edge of the screen, while its transparency remains unchanged.--> <transition-slide:offset="['100%', 0]"no-opacity> <divclass="panel"v-if="isVisible">...</div> </transition-slide> </div></template><style>.panel {position:fixed;top:0;right:0;bottom:0;background:#ffffff;width:400px; }</style>
no-move
Whether tonot animate elements positions changing, in the case of using atransition-group.
By default, when usinggroup mode, when an element is removed, the remaining elements smoothly change their position.
They are given absolute positioning and dropped out of the flow, so the parent container collapses in height.
Usually this is not a problem, but sometimes - for example, when usingtransition-expand andsequentially placed elements under each other, it looks rough.
With this option, you can achieve a more pleasant behavior of the elements in this situation.
exporttypeTransitionNoMove=boolean;// Default: false
Example:
<template> <div><!-- In this case, the height of the parent element (`ul`) changes smoothly.--> <transition-expandgroupno-movetag="ul"> <liv-for="item in items":key="item.id">...</li> </transition-expand> </div></template>
axis
Axis by which the element should expand.
If an object given thenenter andleave values will be used for enter and leave transition respectively.
typeExpandAxisValue='x'|'y';// Default: 'y'exporttypeTransitionExpandAxis=ExpandAxisValue|{enter:ExpandAxisValue,leave:ExpandAxisValue}
offset
The element offset byx andy axis before/after the transition.
Should be an integer or a string representation of percentage value (e.g.'100%').
Number values treats aspx offset, string values ending with% sign treats aspercentage of the element width / height.
Examples and explanation
If an object given thenenter andleave values will be used for enter and leave transition respectively.
typeSlideOffsetValue=[number|string,number|string];// Default: [0, -16]exporttypeTransitionSlideOffset=SlideOffsetValue|{enter:SlideOffsetValue,leave:SlideOffsetValue}
axis
Scale axis to be animated.
* `both` (uses `transform: scale()`)* `x` (uses `transform: scaleX()`)* `y` (uses `transform: scaleY()`)If an object given thenenter andleave values will be used for enter and leave transition respectively.
typeScaleAxisValue='x'|'y'|'both';// Default: 'both'exporttypeTransitionScaleAxis=ScaleAxisValue|{enter:ScaleAxisValue,leave:ScaleAxisValue}
origin
transform-origin CSS property applied to element(s). \
If an object given thenenter andleave values will be used for enter and leave transition respectively.
If an object given thenenter andleave values will be used for enter and leave transition respectively.
// Default: '50% 50%'exporttypeTransitionScaleAxis=string|{enter:string,leave:string}
scale
The element scale value before/after the transition. Should be a number between0 and1.
If an object given thenenter andleave values will be used for enter and leave transition respectively.
If an object given thenenter andleave values will be used for enter and leave transition respectively.
// Default: 0exporttypeTransitionScaleScale=number|{enter:number,leave:number}
Components do not provide any special events,but triggerall standard transition events:
before-enterenterafter-enterenter-cancelledbefore-leaveleaveafter-leaveenter-leave
About
Interface transitions library for Vue 2/3
Topics
Resources
License
Contributing
Uh oh!
There was an error while loading.Please reload this page.
Stars
Watchers
Forks
Packages0
Contributors4
Uh oh!
There was an error while loading.Please reload this page.

