Vitus Labs
Kinetic Presets

Factories & Utilities

Create custom presets with factory functions and modify existing presets with composition utilities.

Factories

Factory functions create custom presets with full control over timing, easing, and effect parameters. All factories return a Preset object compatible with <Transition> and kinetic().preset().

createFade

Create a fade preset with optional directional movement.

import { createFade } from '@vitus-labs/kinetic-presets'

// Pure opacity fade with custom duration
const slowFade = createFade({ duration: 500 })

// Fade with directional movement
const fadeUpCustom = createFade({ direction: 'up', distance: 24, duration: 400 })

// Fast enter, slow leave
const asymmetric = createFade({ duration: 150, leaveDuration: 400 })
OptionTypeDefaultDescription
direction'up' | 'down' | 'left' | 'right'Direction of movement (omit for pure opacity)
distancenumber16Translation distance in px
durationnumber300Enter duration in ms
leaveDurationnumber200Leave duration in ms
easingstring'ease-out'Enter easing
leaveEasingstring'ease-in'Leave easing

createSlide

Create a directional slide preset.

import { createSlide } from '@vitus-labs/kinetic-presets'

const slideFromLeft = createSlide({ direction: 'left', distance: 32, duration: 250 })
const slideDown = createSlide({ direction: 'down', distance: 48 })
OptionTypeDefaultDescription
direction'up' | 'down' | 'left' | 'right''up'Slide direction
distancenumber16Translation distance in px
durationnumber300Enter duration in ms
leaveDurationnumber200Leave duration in ms
easingstring'ease-out'Enter easing
leaveEasingstring'ease-in'Leave easing

createScale

Create a scale transform preset.

import { createScale } from '@vitus-labs/kinetic-presets'

const scaleFromSmall = createScale({ from: 0.8, duration: 400 })

// Spring bounce effect
const bounceScale = createScale({
  from: 0.5,
  easing: 'cubic-bezier(0.34, 1.56, 0.64, 1)',
})
OptionTypeDefaultDescription
fromnumber0.9Starting scale factor (0-1)
durationnumber300Enter duration in ms
leaveDurationnumber200Leave duration in ms
easingstring'ease-out'Enter easing
leaveEasingstring'ease-in'Leave easing

createRotate

Create a rotation preset.

import { createRotate } from '@vitus-labs/kinetic-presets'

const gentleRotate = createRotate({ degrees: 10, duration: 400 })

// Counter-clockwise
const reverseRotate = createRotate({ degrees: -90 })
OptionTypeDefaultDescription
degreesnumber15Rotation angle (negative for counter-clockwise)
durationnumber300Enter duration in ms
leaveDurationnumber200Leave duration in ms
easingstring'ease-out'Enter easing
leaveEasingstring'ease-in'Leave easing

createBlur

Create a blur effect preset with optional scale.

import { createBlur } from '@vitus-labs/kinetic-presets'

const heavyBlur = createBlur({ amount: 12, duration: 400 })

// Blur with scale for a "puff" effect
const puff = createBlur({ amount: 8, scale: 0.95 })
OptionTypeDefaultDescription
amountnumber8Blur amount in px
scalenumberOptional scale factor (omit for pure blur)
durationnumber300Enter duration in ms
leaveDurationnumber200Leave duration in ms
easingstring'ease-out'Enter easing
leaveEasingstring'ease-in'Leave easing

Composition Utilities

Utilities to modify, combine, and transform existing presets without mutating them.

compose

Merge multiple presets into one. Later presets override earlier ones for conflicting properties.

import { compose, fade, slideUp, scaleIn } from '@vitus-labs/kinetic-presets'

const fadeSlide = compose(fade, slideUp)
// Result: { opacity: 0, transform: 'translateY(16px)' } → { opacity: 1, transform: 'translateY(0)' }

const triple = compose(fade, slideUp, scaleIn)

Merge behavior:

  • Style objects are shallow-merged (later keys win)
  • Transition strings use the last preset's value
  • CSS class names are space-concatenated

Important: If two presets modify the same CSS transform property, the last one wins since CSS transform is a single string. Use factories for combined transform effects.


withDuration

Override the enter and leave durations of a preset.

import { withDuration, fadeUp } from '@vitus-labs/kinetic-presets'

// Same duration for enter and leave
const slow = withDuration(fadeUp, 500)

// Different durations
const fastIn = withDuration(fadeUp, 150, 400)
ParameterTypeDescription
presetPresetThe preset to modify
enterMsnumberEnter duration in ms
leaveMsnumberLeave duration in ms (defaults to enterMs)

withEasing

Override the easing function of a preset.

import { withEasing, fadeUp } from '@vitus-labs/kinetic-presets'

// Same easing for both
const spring = withEasing(fadeUp, 'cubic-bezier(0.34, 1.56, 0.64, 1)')

// Different easing for enter and leave
const custom = withEasing(fadeUp, 'ease-out', 'ease-in')
ParameterTypeDescription
presetPresetThe preset to modify
enterEasingstringEnter easing
leaveEasingstringLeave easing (defaults to enterEasing)

withDelay

Add a delay before transitions start.

import { withDelay, fadeUp } from '@vitus-labs/kinetic-presets'

// Same delay for both
const delayed = withDelay(fadeUp, 100)

// Delay only on enter
const enterDelayed = withDelay(fadeUp, 200, 0)
ParameterTypeDescription
presetPresetThe preset to modify
enterDelayMsnumberEnter delay in ms
leaveDelayMsnumberLeave delay in ms (defaults to enterDelayMs)

reverse

Swap enter and leave animations. The enter animation becomes the leave animation and vice versa.

import { reverse, slideUp } from '@vitus-labs/kinetic-presets'

// slideUp enters by sliding up, leaves by sliding down
// reversed: enters by sliding down, leaves by sliding up
const slideDownOnLeave = reverse(slideUp)
ParameterTypeDescription
presetPresetThe preset to reverse

Recipes

Staggered List with Custom Timing

import { kinetic } from '@vitus-labs/kinetic'
import { fadeUp, withDuration, withEasing } from '@vitus-labs/kinetic-presets'

const StaggerList = kinetic('ul')
  .preset(withEasing(
    withDuration(fadeUp, 400),
    'cubic-bezier(0.34, 1.56, 0.64, 1)',
  ))
  .stagger({ interval: 60, reverseLeave: true })
import { kinetic } from '@vitus-labs/kinetic'
import { fade, scaleIn, withDuration } from '@vitus-labs/kinetic-presets'

const Backdrop = kinetic('div').preset(withDuration(fade, 200))
const ModalPanel = kinetic('div').preset(scaleIn)

Notification Toast

import { kinetic } from '@vitus-labs/kinetic'
import { createSlide, withEasing } from '@vitus-labs/kinetic-presets'

const Toast = kinetic('div').preset(
  withEasing(
    createSlide({ direction: 'right', distance: 320, duration: 350 }),
    'cubic-bezier(0.16, 1, 0.3, 1)',
  ),
)

Accordion with Stagger

import { kinetic } from '@vitus-labs/kinetic'
import { fadeUp } from '@vitus-labs/kinetic-presets'

const AccordionBody = kinetic('div').collapse({ transition: 'height 300ms ease' })
const AccordionItems = kinetic('div').preset(fadeUp).stagger({ interval: 30 })

On this page