Skip to content

@vibe-labs/design-vue-progress

Vue 3 progress indicators for the Vibe Design System. Linear bars, radial rings, auto-color thresholds, shimmer effects, and ETA estimation.

Installation

ts
import { VibeProgressBar, VibeProgressRing } from "@vibe-labs/design-vue-progress";

Requires the CSS layer from @vibe-labs/design-components-progress. The package also ships side-effect CSS (shimmer, inside labels, ring spin) imported automatically from progress-extras.css.

Components

VibeProgressBar

Linear progress bar with label positions, shimmer, stripes, and auto-color.

Usage

vue
<!-- Basic -->
<VibeProgressBar :value="65" />

<!-- With title and above label -->
<VibeProgressBar :value="65" title="Upload" label="above" />

<!-- Inside label -->
<VibeProgressBar :value="80" label="inside" size="lg" />

<!-- Right label -->
<VibeProgressBar :value="42" label="right" />

<!-- Custom label format -->
<VibeProgressBar :value="750" :max="1000" label="above" :format-label="(v, min, max) => `${v} / ${max} MB`" />

<!-- Sizes -->
<VibeProgressBar :value="50" size="xs" />
<VibeProgressBar :value="50" size="sm" />
<VibeProgressBar :value="50" size="md" />
<VibeProgressBar :value="50" size="lg" />

<!-- Color variants -->
<VibeProgressBar :value="80" variant="success" />
<VibeProgressBar :value="50" variant="warning" />
<VibeProgressBar :value="20" variant="danger" />

<!-- Auto-color (changes color based on value) -->
<VibeProgressBar :value="progress" variant="auto" />

<!-- Custom auto thresholds -->
<VibeProgressBar
  :value="progress"
  variant="auto"
  :auto-thresholds="[
    { max: 25, color: 'var(--progress-fill-danger)' },
    { max: 75, color: 'var(--progress-fill-warning)' },
    { max: 100, color: 'var(--progress-fill-success)' },
  ]"
/>

<!-- Custom color -->
<VibeProgressBar :value="65" color="#7c3aed" />

<!-- Indeterminate -->
<VibeProgressBar indeterminate />

<!-- Striped -->
<VibeProgressBar :value="70" striped />

<!-- Animated stripes -->
<VibeProgressBar :value="70" striped animated />

<!-- Shimmer effect -->
<VibeProgressBar :value="70" shimmer />

<!-- Custom min/max -->
<VibeProgressBar :value="3" :min="0" :max="10" label="above" />

<!-- Chromeless (for composing segmented bars) -->
<VibeProgressBar :value="40" chromeless />

Props

PropTypeDefaultDescription
valuenumber0Current value
minnumber0Minimum
maxnumber100Maximum
sizeProgressSize"md"xs · sm · md · lg
variantProgressVariant"accent"accent · success · warning · danger · auto
colorstringCustom CSS color (overrides variant)
autoThresholdsAutoColorThreshold[]danger→warning→successThresholds for variant="auto"
labelProgressLabelPosition"none"above · inside · right · none
labelTextstringCustom label text
formatLabel(value, min, max, percentage) => stringLabel format function
titlestringField title above the bar
indeterminatebooleanfalseLoading state
stripedbooleanfalseStriped pattern
animatedbooleanfalseAnimate stripes (requires striped)
shimmerbooleanfalseShimmer/liquid leading edge
chromelessbooleanfalseNo border-radius or background
ariaLabelstring"Progress"Accessible label

VibeProgressRing

Radial/circular progress indicator with centre label.

vue
<!-- Basic -->
<VibeProgressRing :value="72" />

<!-- Sizes -->
<VibeProgressRing :value="72" size="sm" />
<VibeProgressRing :value="72" size="lg" />
<VibeProgressRing :value="72" size="xl" />

<!-- Custom stroke width -->
<VibeProgressRing :value="72" :stroke-width="4" />

<!-- Auto-color -->
<VibeProgressRing :value="progress" variant="auto" />

<!-- Custom color -->
<VibeProgressRing :value="72" color="#7c3aed" />

<!-- Custom label -->
<VibeProgressRing :value="3" :max="10" :format-label="(v, min, max) => `${v}/${max}`" />

<!-- Label slot -->
<VibeProgressRing :value="72">
  <template #default="{ percentage, formatted }">
    <strong>{{ formatted }}</strong>
  </template>
</VibeProgressRing>

<!-- No label -->
<VibeProgressRing :value="72" :show-label="false" />

<!-- Indeterminate spinner -->
<VibeProgressRing indeterminate />

Props

PropTypeDefaultDescription
valuenumber0Current value
minnumber0Minimum
maxnumber100Maximum
sizeProgressRadialSize"md"sm · md · lg · xl
variantProgressVariant"accent"accent · success · warning · danger · auto
colorstringCustom CSS color
autoThresholdsAutoColorThreshold[]Thresholds for auto variant
strokeWidthnumberStroke width in px
showLabelbooleantrueShow centre label
labelTextstringCustom label text
formatLabel(value, min, max, percentage) => stringLabel format function
indeterminatebooleanfalseSpinner mode
ariaLabelstring"Progress"Accessible label

Scoped Slot

PropertyTypeDescription
valuenumberClamped value
percentagenumberPercentage 0–100
formattedstringFormatted label string

Composables

useProgress(options)

Shared computation for percentage, clamping, and auto-color resolution. Used internally by both components.

ts
import { useProgress } from "@vibe-labs/design-vue-progress";

const { percentage, clampedValue, resolvedColor } = useProgress({
  value: toRef(props, "value"),
  min: toRef(props, "min"),
  max: toRef(props, "max"),
  variant: toRef(props, "variant"),
  color: toRef(props, "color"),
  autoThresholds: toRef(props, "autoThresholds"),
});

useProgressTimer(options)

ETA estimation for long-running operations. Tracks progress samples over time, computes a smoothed rate, and estimates time remaining.

ts
import { useProgressTimer } from "@vibe-labs/design-vue-progress";

const { percentage } = useProgress({ value, min, max });
const { state, reset } = useProgressTimer({ percentage });

// state.value.etaFormatted → "~2m 30s"
// state.value.rate         → 0.65 (% per second)
// state.value.completionTime → Date
// state.value.reliable     → true (enough samples)

Options

OptionTypeDefaultDescription
percentageRef<number>requiredReactive percentage (0–100)
sampleSizenumber10Samples to keep for smoothing
minSamplesnumber3Minimum samples before showing estimate

State

PropertyTypeDescription
etanumber | nullEstimated seconds remaining
etaFormattedstring | nullFormatted ETA (e.g. "~2m 30s")
ratenumber | nullProgress rate (% per second)
reliablebooleanEnough samples collected
completionTimeDate | nullPredicted completion time

Auto-Color Thresholds

The variant="auto" mode changes the bar/ring color based on the current percentage. Default thresholds:

RangeColor
0–33%var(--progress-fill-danger) (red)
34–66%var(--progress-fill-warning) (yellow)
67–100%var(--progress-fill-success) (green)

Override with the autoThresholds prop for custom breakpoints.

Dependencies

PackagePurpose
@vibe-labs/design-components-progressCSS tokens + generated styles

Build

bash
npm run build

Built with Vite + vite-plugin-dts. Outputs ES module with TypeScript declarations. Note: sideEffects: ["*.css"] is set in package.json to ensure the extras CSS is not tree-shaken.