CProgressCircular
Circular progress indicator. Shows determinate progress from 0 to 100 or an endless spinner in indeterminate mode. The default slot renders content in the center of the circle.
Basic usage
value sets the progress percentage and is clamped to the 0–100 range. The default slot receives the normalized value.
Show code
<script setup lang="ts">
import { ref } from 'vue'
const value = ref(65)
</script>
<template>
<c-progress-circular :value="value" size="96" width="8">
<template #default="{ value: shown }">{{ shown }}%</template>
</c-progress-circular>
<c-btn @click="value = Math.max(0, value - 10)">-10</c-btn>
<c-btn @click="value = Math.min(100, value + 10)">+10</c-btn>
</template>Colors
color accepts a palette token (teal, green-darken-1) or a raw color (#fa5a5a, rgb(...), var(...)) — there is no predefined set. The ring is drawn with currentColor, so the color lands on the root as a text-*/text-[...] class; the underlay stays on the theme tokens and can be recolored through a preset (the underlay zone).
Show code
<c-progress-circular value="70" size="48" width="5" color="indigo" />
<c-progress-circular value="70" size="48" width="5" color="teal" />
<c-progress-circular value="70" size="48" width="5" color="deep-purple-lighten-1" />
<c-progress-circular value="70" size="48" width="5" color="green-darken-1" />
<c-progress-circular value="70" size="48" width="5" color="#FFA726" />
<c-progress-circular value="70" size="48" width="5" color="#fa5a5a" />A raw color must be a literal
Arbitrary classes (text-[#fa5a5a]) are generated by utils-jit via a static source scan: color="#fa5a5a" works, :color="someVar" with a raw value does not. Palette tokens are unaffected. See Custom attrs for details.
Indeterminate
Endless spinner for operations with unknown duration. size and width control the diameter and the stroke thickness.
Show code
<c-progress-circular indeterminate size="24" width="3" />
<c-progress-circular indeterminate color="green-darken-1" size="40" width="4" />
<c-progress-circular indeterminate color="#fa5a5a" size="64" width="6" />Presets
CProgressCircular supports the preset system. Zones map 1:1 to the DOM and cover every colorable element: root (container), underlay (track ring), overlay (progress ring), and info (center content). The rings are SVG circles with stroke: currentColor, so text-* utilities recolor them. States: indeterminate and complete (value ≥ 100); indeterminate takes precedence.
In the demo below the ring and the counter are indigo/grey while uploading and turn green once value reaches 100 — no conditional classes in the template, the preset resolves the state on its own:
Show code
// main.ts — register the preset once
createVuelandUI({
presets: {
progress: {
upload: {
base: {
underlay: ['text-grey'],
overlay: ['text-indigo'],
info: ['text-grey'],
},
complete: {
overlay: ['text-green'],
info: ['text-green'],
},
},
},
},
})<template>
<c-progress-circular preset="progress.upload" :value="value" size="96" width="8">
<template #default="{ value: shown }">{{ shown }}%</template>
</c-progress-circular>
</template>Accessibility
The root element gets role="progressbar" with aria-valuemin="0", aria-valuemax="100", and aria-valuenow set to the current value. In indeterminate mode aria-valuenow is omitted, which matches the WAI-ARIA progressbar pattern.
API
Props
valuenumber | string0sizenumber | string32widthnumber | string4rotatenumber | string0indeterminatebooleanfalsecolorstringteal) or raw color (#fa5a5a, rgb(...), var(...)); defaults to the theme primarypresetstringSlots
default{ value: number }CSS variables
--c-progress-circular-colorvar(--c-sys-color-primary)--c-progress-circular-underlay-colorvar(--c-sys-color-primary-container)