This repository has been archived by the owner on Dec 10, 2024. It is now read-only.
generated from productdevbookcom/vue-ts-bundle-template
-
-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add docs presence and presenceGroup api
- Loading branch information
1 parent
8390ad3
commit bae1bd9
Showing
2 changed files
with
186 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,168 @@ | ||
--- | ||
title: Presence | ||
description: Perform exit animations in Vue. | ||
icon: i-ph-brackets-curly-duotone | ||
--- | ||
|
||
|
||
```ts | ||
<Presence> | ||
<Motion | ||
v-show="show" | ||
:animate="{ opacity: 1 }" | ||
:exit="{ opacity: 0 }"> | ||
</Motion> | ||
</Presence> | ||
``` | ||
|
||
# Usage | ||
Import Motion from "motion/vue" and register it with your component. | ||
|
||
|
||
```ts | ||
<script setup lang="ts"> | ||
import { Motion, Presence } from "motion/vue" | ||
|
||
const show = ref(true) | ||
</script> | ||
|
||
<template> | ||
<div class="container"> | ||
<Presence> | ||
<Motion | ||
v-show="show" | ||
:initial="{ opacity: 0, scale: 0 }" | ||
:animate="{ opacity: 1, scale: 1 }" | ||
:exit="{ opacity: 0, scale: 0.6 }" | ||
class="box" | ||
/> | ||
</Presence> | ||
<button @click="show = !show"> | ||
Toggle | ||
</button> | ||
</div> | ||
</template> | ||
|
||
<style> | ||
:root { | ||
--splash: #fca311; | ||
} | ||
|
||
.container { | ||
width: 100px; | ||
height: 150px; | ||
display: flex; | ||
flex-direction: column; | ||
justify-content: flex-end; | ||
} | ||
|
||
.container button { | ||
cursor: pointer; | ||
} | ||
.box { | ||
width: 100px; | ||
height: 100px; | ||
border-radius: 10px; | ||
background-color: var(--splash); | ||
} | ||
</style> | ||
``` | ||
|
||
Now, when a child `Motion` component is hidden with `v-if` or `v-show`, it will animate to the target defined in `exit` prop. | ||
|
||
Note: Presence currently only supports a single rendered child. | ||
|
||
|
||
## Animate between elements | ||
|
||
By passing a different `key` to multiple children and rendering just one at a time, we can animate between them at a given time. | ||
|
||
|
||
```ts | ||
<script setup lang="ts"> | ||
import { Motion, Presence } from "motion/vue" | ||
|
||
const current = ref(0) | ||
</script> | ||
|
||
<template> | ||
<div class="container"> | ||
<Presence> | ||
<Motion | ||
:key="current" | ||
:initial="{ opacity: 0, x: 50 }" | ||
:animate="{ | ||
opacity: 1, | ||
x: 0, | ||
transition: { delay: 0.1 } | ||
}" | ||
:exit="{ opacity: 0, x: -50 }" | ||
class="slide" | ||
> | ||
{{ current }} | ||
</Motion> | ||
</Presence> | ||
<button @click="current++"> | ||
Next | ||
</button> | ||
</div> | ||
</template> | ||
|
||
<style> | ||
:root { | ||
--red: #e63946; | ||
--white: #f1faee; | ||
} | ||
|
||
.container { | ||
width: 100px; | ||
height: 150px; | ||
display: flex; | ||
flex-direction: column; | ||
justify-content: flex-end; | ||
position: relative; | ||
} | ||
|
||
.container button { | ||
cursor: pointer; | ||
} | ||
|
||
.slide { | ||
width: 100px; | ||
height: 100px; | ||
border-radius: 10px; | ||
background-color: var(--red); | ||
color: var(--white); | ||
display: flex; | ||
justify-content: center; | ||
align-items: center; | ||
font-size: 72px; | ||
line-height: 72px; | ||
font-family: Inter, sans-serif; | ||
font-weight: 700; | ||
position: absolute; | ||
top: 0; | ||
left: 0; | ||
} | ||
</style> | ||
``` | ||
|
||
In the above example, each element has the position: absolute CSS rule so when the incoming element is rendered it doesn't conflict with the element animating away. | ||
|
||
In situations where this isn't possible, `:exitBeforeEnter="true"` can be set on Presence to ensure the exiting element animates out before the entering element is rendered. | ||
|
||
|
||
## Props | ||
|
||
### initial | ||
|
||
default: `true` | ||
|
||
If `false`, will disable the first animation on all child `Motion` elements the first time `Presence` is rendered. | ||
|
||
|
||
### exitBeforeEnter | ||
|
||
default: `false` | ||
|
||
If `true`, Presence will wait for the exiting element to finish animating out before animating in the next one. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
--- | ||
title: PresenceGroup | ||
description: Perform exit animations in Vue. Group multiple Motion components together. | ||
icon: i-ph-brackets-curly-duotone | ||
--- | ||
|
||
|
||
```ts | ||
<PresenceGroup> | ||
<template v-for="item in items" :key="item.id"> | ||
<Motion | ||
v-show="show" | ||
:animate="{ opacity: 1 }" | ||
:exit="{ opacity: 0 }"> | ||
</Motion> | ||
</template> | ||
</PresenceGroup> | ||
``` |