Progress

Displays an indicator showing the completion progress of a task, typically displayed as a progress bar.

<script setup lang="ts">
import { onBeforeUnmount, onMounted, ref } from 'vue'
import { Progress } from '@/components/ui/progress'

const progress = ref(13)

let timer: ReturnType<typeof setTimeout> | undefined

onMounted(() => {
  timer = setTimeout(() => {
    progress.value = 66
  }, 500)
})

onBeforeUnmount(() => clearTimeout(timer))
</script>

<template>
  <Progress :model-value="progress" class="w-[60%]" />
</template>

Installation

Install the packages

npm install @animate-ui/vue motion-v
pnpm add @animate-ui/vue motion-v
yarn add @animate-ui/vue motion-v
bun add @animate-ui/vue motion-v

Add the shadcn-vue component

npx shadcn-vue@latest add progress
pnpm dlx shadcn-vue@latest add progress
yarn dlx shadcn-vue@latest add progress
bun x shadcn-vue@latest add progress

Animate it

The CLI finds your shadcn-vue components through components.json, swaps their primitive imports for Animate UI's and removes the CSS animation classes Motion replaces.

npx @animate-ui/cli@latest animate progress
pnpm dlx @animate-ui/cli@latest animate progress
yarn dlx @animate-ui/cli@latest animate progress
bun x @animate-ui/cli@latest animate progress

Usage

<script setup lang="ts">
import { ref } from 'vue';
import {
  ProgressIndicator,
  ProgressRoot,
} from '@animate-ui/vue/primitives/reka-ui';

const value = ref(40);
</script>

<template>
  <ProgressRoot
    :model-value="value"
    class="h-2 w-full overflow-hidden rounded-full"
  >
    <ProgressIndicator
      class="h-full w-full bg-primary"
      :style="`transform: translateX(-${100 - value}%);`"
    />
  </ProgressRoot>
</template>

Animation

The motion of Animate UI's React progress:

  • Indicator springs to each new value (stiffness 300, damping 35: most of the way in ~230ms and settled by ~550ms, with no jump at the end; no overshoot, which would uncover the start of the track). reka-ui leaves the indicator's position to you: shadcn-vue moves it with transform: translateX(-…%) in its style, as a string or an object. Animate UI animates that translation instead of jumping to it, as an x that keeps its momentum when a new value arrives mid-way.
  • It starts at its value on mount, with no animation.
  • Under reduced motion, the indicator jumps to each value.
  • shadcn-vue's transition-all on the indicator would run on top of Motion: the CLI removes it.

API Reference

Every part takes exactly the props of reka-ui's Progress. Animate UI adds the animation props below.

ProgressRoot

reka-ui props only. It isn't animated.

ProgressIndicator

reka-ui props, plus:

PropTypeDefault
transition?
Transition{ type: 'spring', stiffness: 300, damping: 35, restDelta: 0.01, restSpeed: 0.1 }

AnimateUIProvider's tempo scales the spring with everything else.

Built by Skyleen. The source code is available on GitHub.

Last updated: 10/23/2026