Skip to content

Commit

Permalink
feat: transition duration shorthand prop (#185)
Browse files Browse the repository at this point in the history
  • Loading branch information
BobbieGoede authored Apr 20, 2024
1 parent 7a77272 commit cd99fda
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 11 deletions.
12 changes: 9 additions & 3 deletions docs/content/2.features/1.directive-usage.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,16 @@ The `:variants` prop will be combined with all the other native variants propert

The rest of the variants properties can be found on the [Variants](/features/variants) page.

As a shorthand, you can use the `:delay` prop, that allows you to edit the delay from the element props.
### Shorthand props

If you specified `visible`, `visible-once` or `enter` variant, the delay will be applied to each of them.
For convenience we support the following shorthand props which allow you to quickly configure transition properties:

Otherwise, the delay will be applied on the `initial` [variant](/features/variants).
- **`delay`**
- **`duration`**

If you specified a `visible`, `visible-once` or `enter` variant, these shorthand properties will be applied to each of them.

Otherwise, they will be applied on the `initial` [variant](/features/variants) instead.

```vue
<template>
Expand All @@ -45,6 +50,7 @@ Otherwise, the delay will be applied on the `initial` [variant](/features/varian
:variants="{ custom: { scale: 2 } }"
:hovered="{ scale: 1.2 }"
:delay="200"
:duration="1200"
/>
</template>
```
Expand Down
14 changes: 10 additions & 4 deletions src/components/Motion.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,10 @@ export default defineComponent({
type: [Number, String] as PropType<number | string>,
required: false,
},
duration: {
type: [Number, String] as PropType<number | string>,
required: false,
},
},
setup(props) {
const slots = useSlots()
Expand Down Expand Up @@ -106,15 +110,17 @@ export default defineComponent({
...(props.variants || {}),
}

if (props.delay) {
const delayNumber = parseInt(props.delay as string)
for (const transitionKey of ['delay', 'duration'] as const) {
if (!props[transitionKey]) continue

const transitionValueParsed = parseInt(props[transitionKey] as string)

// Apply delay to existing variants where applicable
// Apply transition property to existing variants where applicable
for (const configKey of ['enter', 'visible', 'visibleOnce']) {
if (!config[configKey]) continue

config[configKey].transition ??= {}
config[configKey].transition.delay = delayNumber
config[configKey].transition[transitionKey] = transitionValueParsed
}
}

Expand Down
14 changes: 10 additions & 4 deletions src/utils/directive.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,12 @@ import { isObject } from '@vueuse/core'
import type { Ref, VNode } from 'vue'
import type { MotionVariants } from '../types'

const directivePropsKeys = ['initial', 'enter', 'leave', 'visible', 'visible-once', 'visibleOnce', 'hovered', 'tapped', 'focused', 'delay']
const transitionKeys = ['delay', 'duration'] as const
const directivePropsKeys = ['initial', 'enter', 'leave', 'visible', 'visible-once', 'visibleOnce', 'hovered', 'tapped', 'focused', ...transitionKeys] as const

function isTransitionKey(val: any): val is 'delay' | 'duration' {
return transitionKeys.includes(val)
}

export function resolveVariants<T extends string>(node: VNode<any, HTMLElement | SVGElement, Record<string, any>>, variantsRef: Ref<MotionVariants<T>>) {
// This is done to achieve compat with Vue 2 & 3
Expand All @@ -27,15 +32,16 @@ export function resolveVariants<T extends string>(node: VNode<any, HTMLElement |
for (let key of directivePropsKeys) {
if (!target || !target[key]) continue

if (key === 'delay' && typeof target[key] === 'number') {
// Apply delay to existing variants where applicable
if (isTransitionKey(key) && typeof target[key] === 'number') {
// Apply transition property to existing variants where applicable
for (const variantKey of ['enter', 'visible', 'visibleOnce'] as const) {
const variantConfig = variantsRef.value[variantKey]

if (variantConfig == null) continue

variantConfig.transition ??= {}
variantConfig.transition.delay = target[key]
// @ts-expect-error `duration` does not exist on `inertia` type transitions
variantConfig.transition[key] = target[key]
}

continue
Expand Down

0 comments on commit cd99fda

Please sign in to comment.