vael-ui v0.3.10

Bring your own animation

Every component that animates ships a plain CSS transition, but exposes a real escape hatch to drive it with GSAP, motion-v, or nothing at all. Check a component's own Props/Slots/Exposed tables for which of these it has, not every component has all three.

motionCss

false disables the built-in CSS transition, the component still changes state instantly, leaving the DOM ready for you to animate.

forceMount

Keeps content mounted while closed instead of removing it on v-if. Pair with <AnimatePresence> and the default slot's isClosing flag to own exit timing yourself.

beforeClose(done)

For imperative libraries: pass a function that receives done. The component stays mounted and isClosing until you call it.

Example: motion-v, Popover

forceMount plus the default slot's isClosing flag, wrapped in <AnimatePresence>:

<script setup lang="ts">
import { AnimatePresence, motion } from "motion-v"
import { Popover } from "vael-ui"
</script>

<template>
  <Popover force-mount v-model:open="open">
    <template #trigger="{ setTriggerEl }">
      <button :ref="setTriggerEl">Open</button>
    </template>
    <template #default="{ isClosing }">
      <AnimatePresence>
        <motion.div
          v-if="!isClosing"
          :initial="{ opacity: 0, scale: 0.95 }"
          :animate="{ opacity: 1, scale: 1 }"
          :exit="{ opacity: 0, scale: 0.95 }"
        >
          Popover content
        </motion.div>
      </AnimatePresence>
    </template>
  </Popover>
</template>

Example: GSAP, Dialog

beforeClose(done) plus the exposed panelEl ref, so the tween runs on the real panel element before it's removed:

<script setup lang="ts">
import { ref } from "vue"
import gsap from "gsap"
import { Dialog } from "vael-ui"

const dialogRef = ref<InstanceType<typeof Dialog>>()
const open = ref(false)

function beforeClose(done: () => void) {
  gsap.to(dialogRef.value?.panelEl, {
    opacity: 0,
    y: 8,
    duration: 0.2,
    onComplete: done,
  })
}
</script>

<template>
  <Dialog ref="dialogRef" v-model:open="open" :before-close="beforeClose">
    Dialog content
  </Dialog>
</template>