Skip to main content
You are viewing Pre-Alpha documentation.
Vuetify0 Logo
Theme
Mode
Palettes
Accessibility
Vuetify One
Sign in to Vuetify One

Access premium tools across the Vuetify ecosystem — Bin, Play, Studio, and more.

Not a subscriber? See what's included

Progress

A headless progress bar component for building determinate, indeterminate, and buffered loading indicators. Uses createProgress internally, which delegates segment tracking to createModel.


RenderlessIntermediateApr 6, 2026

Usage

The Progress supports single-value and multi-segment modes. Bind a number for a single bar, or an array for multiple segments.

0%
<script setup lang="ts">
  import { Progress, Slider } from '@vuetify/v0'
  import { shallowRef } from 'vue'

  const value = shallowRef(65)
</script>

<template>
  <div class="flex flex-col gap-4 w-full">
    <Progress.Root v-model="value">
      <Progress.Label class="text-sm font-medium">Loading...</Progress.Label>

      <Progress.Track class="relative h-2 w-full overflow-hidden rounded-full bg-surface-variant">
        <Progress.Fill class="h-full rounded-full bg-primary" />
      </Progress.Track>

      <Progress.Value class="text-sm text-neutral-500" />
    </Progress.Root>

    <Slider.Root v-model="value" class="relative flex items-center w-full h-5">
      <Slider.Track class="relative h-1 w-full rounded-full bg-surface-variant">
        <Slider.Range class="absolute h-full rounded-full bg-primary" />
      </Slider.Track>

      <Slider.Thumb class="absolute size-5 rounded-full bg-primary -translate-x-1/2 focus:outline-2 focus:outline-primary" />
    </Slider.Root>
  </div>
</template>

Anatomy

Anatomy
<script setup lang="ts">
  import { Progress } from '@vuetify/v0'
</script>

<template>
  <Progress.Root>
    <Progress.Label />

    <Progress.Track>
      <Progress.Fill />

      <Progress.Buffer />
    </Progress.Track>

    <Progress.Value />

    <Progress.HiddenInput />
  </Progress.Root>
</template>

Examples

Storage Usage

Multi-segment progress bar showing disk usage by category. Each Progress.Fill registers as a segment with its own value, and Root aggregates them into a total.

File breakdown:

FileRole
StorageBar.vueReusable component — renders a multi-segment bar with category colors and a total label
storage.vueDemo — wires category data with interactive sliders to adjust values

Key patterns:

  • Multiple Progress.Fill components register segments via the internal model registry — their values sum to the total

  • Progress.Value v-slot="{ total }" provides the aggregate for custom formatting

  • :max="128" on Root sets the upper bound so percentages compute against 128 GB instead of the default 100

0 of 128 GB
Photos
32 GB
Apps
24 GB
Documents
12 GB
System
8 GB

Media Player

A media player progress bar with buffer indicator. The buffer shows pre-loaded content while the fill tracks playback position.

File breakdown:

FileRole
MediaProgress.vueReusable component — thin bar with buffer and fill layers
media.vueDemo — simulates playback with play/pause/reset controls

Key patterns:

  • Progress.Buffer is independent of the segment registry — it reads value directly and computes its own percentage against Root’s min/max

  • Buffer and Fill are both absolute inset-y-0 left-0 so they layer correctly, with Fill rendering on top via DOM order

  • The timer increments both values at different rates to simulate realistic buffering ahead of playback

Midnight DriveSynthwave Collection
0:003:00

Recipes

Indeterminate State

When no value is provided (or all segment values are 0), the progress is indeterminate. Use data-state to apply CSS animations:

vue
<template>
  <Progress.Root>
    <Progress.Track class="relative h-2 w-full overflow-hidden rounded-full bg-neutral-200">
      <Progress.Fill class="h-full rounded-full bg-blue-500 data-[state=indeterminate]:animate-pulse data-[state=indeterminate]:w-full" />
    </Progress.Track>
  </Progress.Root>
</template>

Custom Value Format

Override the default ${percent}% display via the scoped slot:

vue
<template>
  <Progress.Value v-slot="{ total, percent }">
    {{ total }} of 100 ({{ Math.round(percent) }}%)
  </Progress.Value>
</template>

Form Integration

Set name on Root to auto-render a hidden input for form submission:

vue
<template>
  <Progress.Root v-model="value" name="upload-progress">
    <Progress.Track>
      <Progress.Fill />
    </Progress.Track>
  </Progress.Root>
</template>

Data Attributes

Style states without slot props:

vue
<template>
  <Progress.Fill class="data-[state=indeterminate]:animate-pulse transition-all" />
</template>
AttributeValuesComponents
data-statedeterminate, indeterminateRoot, Track, Fill, Buffer
data-completetrueRoot
data-buffertrueBuffer
data-indexnumberFill

Accessibility

The Root component manages ARIA attributes automatically.

ARIA Attributes

AttributeValueNotes
roleprogressbarApplied to Root
aria-valuenowCurrent totalOmitted when indeterminate
aria-valueminMin valueFrom Root’s min prop (default 0)
aria-valuemaxMax valueFrom Root’s max prop (default 100)
aria-valuetext${percent}%Omitted when indeterminate
aria-labelledbyLabel IDLinks to Progress.Label
aria-busytrueSet when indeterminate
data-statedeterminate / indeterminateReflects current mode
data-completetrueWhen total >= max

API Reference

The following API details are for all variations of the Progress component.

Progress.Root

Props

id

string | undefined

Default: useId()

modelValue

number | number[] | undefined

min

number | undefined

Default: 0

max

number | undefined

Default: 100

name

string | undefined

namespace

string | undefined

Default: "v0:progress:root"

Slots

default

ProgressRootSlotProps

Progress.Buffer

Props

value

number | undefined

Buffer value

Default: 0

namespace

string | undefined

Namespace for context injection from parent Progress.Root

Default: "v0:progress:root"

Slots

default

ProgressBufferSlotProps

Progress.Fill

Props

value

number | undefined

namespace

string | undefined

Default: "v0:progress:root"

Slots

default

ProgressFillSlotProps

Progress.HiddenInput

Props

namespace

string | undefined

Namespace for context injection from parent Progress.Root

Default: "v0:progress:root"

Progress.Label

Props

namespace

string | undefined

Default: "v0:progress:root"

Slots

default

ProgressLabelSlotProps

Progress.Track

Props

namespace

string | undefined

Namespace for context injection from parent Progress.Root

Default: "v0:progress:root"

Slots

default

ProgressTrackSlotProps

Progress.Value

Props

namespace

string | undefined

Namespace for context injection from parent Progress.Root

Default: "v0:progress:root"

Slots

default

ProgressValueSlotProps
Was this page helpful?

© 2016-1970 Vuetify, LLC
Ctrl+/