72%
<script setup lang="ts">
import { RingProgress } from '@hina-ui/vue'
</script>
<template>
<RingProgress :value="72" show-value />
</template>
vue
Usage
import { RingProgress } from '@hina-ui/vue'
ts
value and max mean the same as in Progress; the arc is drawn clockwise from the top in proportion to the two. The centre is empty by default, and showValue shows the percentage there.
40%
<script setup lang="ts">
import { Inline, RingProgress } from '@hina-ui/vue'
</script>
<template>
<Inline gap="lg" align="center">
<RingProgress :value="40" />
<RingProgress :value="40" show-value />
</Inline>
</template>
vue
Examples
Centre content
The default slot replaces the centre content, for example an icon once done, or use format to rewrite the value text.
3/8
<script setup lang="ts">
import { Check } from '@lucide/vue'
import { Inline, RingProgress } from '@hina-ui/vue'
const format = (value: number, max: number) => `${value}/${max}`
</script>
<template>
<Inline gap="lg" align="center">
<RingProgress :value="100" tone="success">
<Check class="text-success size-6" />
</RingProgress>
<RingProgress :value="3" :max="8" show-value :format="format" />
</Inline>
</template>
vue
Label
label sits below the ring.
58%
91%
<script setup lang="ts">
import { Inline, RingProgress } from '@hina-ui/vue'
</script>
<template>
<Inline gap="xl" align="start">
<RingProgress :value="58" show-value label="Read" />
<RingProgress :value="91" show-value label="Bookmarked" tone="info" />
</Inline>
</template>
vue
Changing the value
When value changes the arc length transitions smoothly, whether it grows or shrinks.
30%
<script setup lang="ts">
import { ref } from 'vue'
import { Button, Inline, RingProgress, 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" align="center">
<RingProgress :value="value" show-value size="lg" />
<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
Sizes
Three diameters, md by default. The ring thickness and the centre text scale with the diameter.
60%
60%
60%
<script setup lang="ts">
import { Inline, RingProgress } from '@hina-ui/vue'
</script>
<template>
<Inline gap="lg" align="center">
<RingProgress :value="60" size="sm" show-value />
<RingProgress :value="60" show-value />
<RingProgress :value="60" size="lg" show-value />
</Inline>
</template>
vue
Tones
tone sets the arc colour, the accent colour by default.
<script setup lang="ts">
import { Inline, RingProgress } from '@hina-ui/vue'
</script>
<template>
<Inline gap="lg" align="center">
<RingProgress :value="70" />
<RingProgress :value="70" tone="neutral" />
<RingProgress :value="100" tone="success" />
<RingProgress :value="70" tone="warning" />
<RingProgress :value="70" tone="danger" />
<RingProgress :value="70" tone="info" />
</Inline>
</template>
vue
Indeterminate
Leaving out value means the total is unknown: a quarter-length arc spins around the ring.
Connecting
<script setup lang="ts">
import { RingProgress } from '@hina-ui/vue'
</script>
<template>
<RingProgress label="Connecting" />
</template>
vue
Behavior
- The arc is drawn clockwise from the top with round ends; nothing is drawn when
valueis 0. - When
valuechanges the arc length transitions smoothly, with duration and easing from the motion variables; an out-of-rangevalueis clamped. - The indeterminate spin runs at the same pace as Spinner. When reduced motion is on the spin stops and the arc stays visible.
Accessibility
- The ring carries
role="progressbar", witharia-valuenow,aria-valueminandaria-valuemaxfollowingvalueandmax; an indeterminate ring has noaria-valuenow. - The accessible name is
labelwhen given, otherwise the value text, and for an indeterminate ring the locale’s “Loading”. - With
formatthe result is also written toaria-valuetext. - The drawing itself is hidden from assistive technology; the centre content remains readable.
API
Props
| Prop | Type | Default | Description |
|---|---|---|---|
value | number | null | null | Current progress; leave out for indeterminate |
max | number | 100 | Total |
label | string | — | Label below the ring |
showValue | boolean | false | Whether to show the value text in the centre |
format | (value: number, max: number) => string | percentage | Format of the value text |
tone | 'accent' | 'neutral' | 'success' | 'warning' | 'danger' | 'info' | 'accent' | Arc colour |
size | 'sm' | 'md' | 'lg' | 'md' | Diameter |
class | string | — | Extra classes on the root element |
Other attributes fall through to the ring element carrying role="progressbar".
Slots
| Slot | Description |
|---|---|
| default | Centre content, the showValue text by default |