Progress

A bar whose fill shows how much of a task is done.

Uploading62%
<script setup lang="ts">
  import { Progress } from '@hina-ui/vue'
</script>

<template>
  <Progress :value="62" label="Uploading" show-value class="w-80" />
</template>
vue

Usage

import { Progress } from '@hina-ui/vue'
ts

value is the current progress and max the total, 100 by default. The bar fills in proportion to the two, and the fill length transitions smoothly when value changes.

<script setup lang="ts">
  import { Progress } from '@hina-ui/vue'
</script>

<template>
  <Progress :value="40" class="w-80" />
</template>
vue

Examples

Label and value

label sits above the bar; showValue shows the percentage at the end of the same line.

Syncing bookmarks
Syncing bookmarks25%
25%
<script setup lang="ts">
  import { Progress, Stack } from '@hina-ui/vue'
</script>

<template>
  <Stack gap="lg" class="w-80">
    <Progress :value="25" label="Syncing bookmarks" />
    <Progress :value="25" label="Syncing bookmarks" show-value />
    <Progress :value="25" show-value />
  </Stack>
</template>
vue

Changing the value

When value changes the fill length transitions smoothly, whether it grows or shrinks, and the value text updates with it.

Downloading30%
<script setup lang="ts">
  import { ref } from 'vue'
  import { Button, Inline, Progress, Stack } from '@hina-ui/vue'

  const value = ref(30)
  const step = (delta: number) => {
    value.value = Math.min(100, Math.max(0, value.value + delta))
  }
</script>

<template>
  <Stack gap="md" class="w-80">
    <Progress :value="value" label="Downloading" show-value />
    <Inline gap="sm">
      <Button size="sm" variant="soft" tone="neutral" :disabled="value === 0" @click="step(-10)">
        −10
      </Button>
      <Button size="sm" variant="soft" tone="neutral" :disabled="value === 100" @click="step(10)">
        +10
      </Button>
    </Inline>
  </Stack>
</template>
vue

Value format

format receives the current value and the total and returns the text to show. The same text is what assistive technology reads as the value.

Processed3 of 8 files
<script setup lang="ts">
  import { Progress } from '@hina-ui/vue'

  const format = (value: number, max: number) => `${value} of ${max} files`
</script>

<template>
  <Progress :value="3" :max="8" label="Processed" show-value :format="format" class="w-80" />
</template>
vue

Sizes

Three heights, md by default: sm for compact places such as list rows, lg for a progress that stands on its own.

<script setup lang="ts">
  import { Progress, Stack } from '@hina-ui/vue'
</script>

<template>
  <Stack gap="lg" class="w-80">
    <Progress :value="60" size="sm" />
    <Progress :value="60" />
    <Progress :value="60" size="lg" />
  </Stack>
</template>
vue

Tones

tone sets the fill colour, the accent colour by default. Done, warning and failed states can switch to the matching semantic colour.

<script setup lang="ts">
  import { Progress, Stack } from '@hina-ui/vue'
</script>

<template>
  <Stack gap="lg" class="w-80">
    <Progress :value="70" />
    <Progress :value="70" tone="neutral" />
    <Progress :value="100" tone="success" />
    <Progress :value="70" tone="warning" />
    <Progress :value="70" tone="danger" />
    <Progress :value="70" tone="info" />
  </Stack>
</template>
vue

Indeterminate

Leaving out value means the total is unknown: a segment of fill sweeps along the track repeatedly.

Connecting
<script setup lang="ts">
  import { Progress } from '@hina-ui/vue'
</script>

<template>
  <Progress label="Connecting" class="w-80" />
</template>
vue

Behavior

  • When value changes the fill length transitions smoothly, with duration and easing from the motion variables.
  • An out-of-range value is clamped: below 0 counts as 0, above max counts as max.
  • The indeterminate sweep takes its duration from the motion variables. When reduced motion is on the sweep stops and the segment rests in the middle of the track.

Accessibility

  • The track carries role="progressbar", with aria-valuenow, aria-valuemin and aria-valuemax following value and max; an indeterminate bar has no aria-valuenow.
  • The accessible name is label when given, otherwise the value text, and for an indeterminate bar the locale’s “Loading”.
  • With format the result is also written to aria-valuetext, so assistive technology reads the formatted text rather than the raw number.

API

Props

Prop
Type
Default
Description
value
number | null
null
Current progress; leave out for indeterminate
max
number
100
Total
label
string
—
Label above the bar
showValue
boolean
false
Whether to show the value text
format
(value: number, max: number) => string
percentage
Format of the value text
tone
'accent' | 'neutral' | 'success' | 'warning' | 'danger' | 'info'
'accent'
Fill colour
size
'sm' | 'md' | 'lg'
'md'
Height
class
string
—
Extra classes on the root element

Other attributes fall through to the track element carrying role="progressbar".