# CircularProgress

*Category:* Components
*Section:* Progress
*Source:* https://uikit.developers.rio.cloud/#/components/circularProgress
*Captured:* 2026-04-27T14:57:46.545Z

## CircularProgress

### Example: Default circular progress

Default circular progress
30

Circular progress customizations
85 km/h

Speed

40%

Custom label

100

With max value

Different sizes with custom value label

xs

sm

md

lg

xl

Strong customization
40%

3200 Points

#### React (tsx)

```tsx
import CircularProgress from '@rio-cloud/rio-uikit/CircularProgress';
import Divider from '@rio-cloud/rio-uikit/Divider';
import FormLabel from '@rio-cloud/rio-uikit/FormLabel';

export default () => (
    <>
        <FormLabel>Default circular progress</FormLabel>
        <div className='display-flex gap-50 margin-top-15'>
            <CircularProgress value={30} />
        </div>

        <Divider spacing={25} />

        <FormLabel>Circular progress customizations</FormLabel>
        <div className='display-flex gap-50 margin-top-15'>
            <CircularProgress
                color='warning'
                formatOptions={{ style: 'unit', unit: 'kilometer-per-hour' }}
                valueLabelClassName='text-italic'
                label='Speed'
                size='lg'
                strokeWidth={4}
                value={85}
            />
            <CircularProgress
                color='info'
                formatOptions={{ style: 'unit', unit: 'percent' }}
                valueLabelClassName='text-size-16 text-medium text-color-dark'
                label='Custom label'
                strokeWidth={3}
                value={40}
            />
            <CircularProgress valueLabelClassName='text-size-' label='With max value' value={100} maxValue={300} />
            <CircularProgress showValueLabel={false} value={0} />
        </div>

        <Divider spacing={25} />

        <FormLabel>Different sizes with custom value label</FormLabel>
        <div className='display-flex gap-50 margin-top-15'>
            <CircularProgress
                color='success'
                valueLabel={<span className='rioglyph rioglyph-ok text-color-success text-size-14' />}
                size='xs'
                label='xs'
                animationDelay={1}
                value={70}
            />
            <CircularProgress
                color='success'
                valueLabel={<span className='rioglyph rioglyph-ok text-color-success text-size-18' />}
                size='sm'
                label='sm'
                animationDelay={1.2}
                value={70}
            />
            <CircularProgress
                color='success'
                valueLabel={<span className='rioglyph rioglyph-ok text-color-success text-size-h3' />}
                size='md'
                label='md'
                animationDelay={1.4}
                value={70}
            />
            <CircularProgress
                color='success'
                valueLabel={<span className='rioglyph rioglyph-ok text-color-success text-size-h2' />}
                size='lg'
                label='lg'
                animationDelay={1.6}
                value={70}
            />
            <CircularProgress
                color='success'
                valueLabel={<span className='rioglyph rioglyph-ok text-color-success text-size-h1' />}
                size='xl'
                label='xl'
                animationDelay={1.8}
                value={70}
            />
        </div>

        <Divider spacing={25} />

        <FormLabel>Strong customization</FormLabel>
        <div className='display-grid place-items-center bg-primary width-200 height-200 rounded'>
            <CircularProgress
                color='white'
                formatOptions={{ style: 'unit', unit: 'percent' }}
                valueLabelClassName='text-medium text-size-h2 text-color-white'
                trackClassName='opacity-30'
                label={
                    <div className='border border-color-white rounded-circle padding-x-10 padding-y-5'>3200 Points</div>
                }
                strokeWidth={12}
                size='xl'
                animationDelay={2}
                value={40}
            />
        </div>
    </>
);
```

#### HTML (html)

```html
<div class="text-color-dark max-width-100pct text-size-12 display-inline-block margin-bottom-5">Default circular progress</div>
<div class="display-flex gap-50 margin-top-15">
    <div class="display-flex flex-column align-items-center text-center gap-10 ">
        <div class="" role="progressbar" aria-valuemin="0" aria-valuemax="100" aria-valuenow="30" aria-valuetext="30" style="width: 64px; height: 64px; position: relative; display: grid; place-items: center;">
            <svg width="64" height="64" viewBox="0 0 100 100" style="transform: rotate(-90deg);">
                <circle cx="50" cy="50" r="46" fill="none" stroke="var(--gray-lighter)" stroke-width="8" class="">
                </circle>
                <circle cx="50" cy="50" r="46" fill="none" stroke="var(--brand-primary)" stroke-width="8" stroke-linecap="round" stroke-dasharray="289.02652413026095" stroke-dashoffset="232.49266533852068">
                </circle>
            </svg>
            <div class="position-absolute display-grid place-items-center">30</div>
        </div>
    </div>
</div>
<div class="Divider position-relative width-100pct" style="padding-top: 25px; padding-bottom: 25px;">
    <div class="divider-line bg-light" style="width: 100%; height: 1px;">
    </div>
</div>
<div class="text-color-dark max-width-100pct text-size-12 display-inline-block margin-bottom-5">Circular progress customizations</div>
<div class="display-flex gap-50 margin-top-15">
    <div class="display-flex flex-column align-items-center text-center gap-10 " aria-labelledby="circular-progress-label-:r1:">
        <div class="" role="progressbar" aria-valuemin="0" aria-valuemax="100" aria-valuenow="85" aria-valuetext="85 km/h" style="width: 80px; height: 80px; position: relative; display: grid; place-items: center;">
            <svg width="80" height="80" viewBox="0 0 100 100" style="transform: rotate(-90deg);">
                <circle cx="50" cy="50" r="48" fill="none" stroke="var(--gray-lighter)" stroke-width="4" class="">
                </circle>
                <circle cx="50" cy="50" r="48" fill="none" stroke="var(--brand-warning)" stroke-width="4" stroke-linecap="round" stroke-dasharray="301.59289474462014" stroke-dashoffset="134.44931222990982">
                </circle>
            </svg>
            <div class="position-absolute display-grid place-items-center text-italic">85 km/h</div>
        </div>
        <div id="circular-progress-label-:r1:" class="">Speed</div>
    </div>
    <div class="display-flex flex-column align-items-center text-center gap-10 " aria-labelledby="circular-progress-label-:r2:">
        <div class="" role="progressbar" aria-valuemin="0" aria-valuemax="100" aria-valuenow="40" aria-valuetext="40%" style="width: 64px; height: 64px; position: relative; display: grid; place-items: center;">
            <svg width="64" height="64" viewBox="0 0 100 100" style="transform: rotate(-90deg);">
                <circle cx="50" cy="50" r="48.5" fill="none" stroke="var(--gray-lighter)" stroke-width="3" class="">
                </circle>
                <circle cx="50" cy="50" r="48.5" fill="none" stroke="var(--brand-info)" stroke-width="3" stroke-linecap="round" stroke-dasharray="304.7344873982099" stroke-dashoffset="225.25935257503883">
                </circle>
            </svg>
            <div class="position-absolute display-grid place-items-center text-size-16 text-medium text-color-dark">40%</div>
        </div>
        <div id="circular-progress-label-:r2:" class="">Custom label</div>
    </div>
    <div class="display-flex flex-column align-items-center text-center gap-10 " aria-labelledby="circular-progress-label-:r3:">
        <div class="" role="progressbar" aria-valuemin="0" aria-valuemax="300" aria-valuenow="100" aria-valuetext="100" style="width: 64px; height: 64px; position: relative; display: grid; place-items: center;">
            <svg width="64" height="64" viewBox="0 0 100 100" style="transform: rotate(-90deg);">
                <circle cx="50" cy="50" r="46" fill="none" stroke="var(--gray-lighter)" stroke-width="8" class="">
                </circle>
                <circle cx="50" cy="50" r="46" fill="none" stroke="var(--brand-primary)" stroke-width="8" stroke-linecap="round" stroke-dasharray="289.02652413026095" stroke-dashoffset="226.21112547277178">
                </circle>
            </svg>
            <div class="position-absolute display-grid place-items-center text-size-">100</div>
        </div>
        <div id="circular-progress-label-:r3:" class="">With max value</div>
    </div>
    <div class="display-flex flex-column align-items-center text-center gap-10 ">
        <div class="" role="progressbar" aria-valuemin="0" aria-valuemax="100" aria-valuenow="0" style="width: 64px; height: 64px; position: relative; display: grid; place-items: center;">
            <svg width="64" height="64" viewBox="0 0 100 100" style="transform: rotate(-90deg);">
                <circle cx="50" cy="50" r="46" fill="none" stroke="var(--gray-lighter)" stroke-width="8" class="">
                </circle>
                <circle cx="50" cy="50" r="46" fill="none" stroke="var(--brand-primary)" stroke-width="8" stroke-linecap="round" stroke-dasharray="289.02652413026095" stroke-dashoffset="289.02652413026095">
                </circle>
            </svg>
        </div>
    </div>
</div>
<div class="Divider position-relative width-100pct" style="padding-top: 25px; padding-bottom: 25px;">
    <div class="divider-line bg-light" style="width: 100%; height: 1px;">
    </div>
</div>
<div class="text-color-dark max-width-100pct text-size-12 display-inline-block margin-bottom-5">Different sizes with custom value label</div>
<div class="display-flex gap-50 margin-top-15">
    <div class="display-flex flex-column align-items-center text-center gap-10 " aria-labelledby="circular-progress-label-:r5:">
        <div class="" role="progressbar" aria-valuemin="0" aria-valuemax="100" aria-valuenow="70" style="width: 32px; height: 32px; position: relative; display: grid; place-items: center;">
            <svg width="32" height="32" viewBox="0 0 100 100" style="transform: rotate(-90deg);">
                <circle cx="50" cy="50" r="46" fill="none" stroke="var(--gray-lighter)" stroke-width="8" class="">
                </circle>
                <circle cx="50" cy="50" r="46" fill="none" stroke="var(--brand-success)" stroke-width="8" stroke-linecap="round" stroke-dasharray="289.02652413026095" stroke-dashoffset="289.02652413026095">
                </circle>
            </svg>
            <div class="position-absolute display-grid place-items-center">
                <span class="rioglyph rioglyph-ok text-color-success text-size-14">
                </span>
            </div>
        </div>
        <div id="circular-progress-label-:r5:" class="">xs</div>
    </div>
    <div class="display-flex flex-column align-items-center text-center gap-10 " aria-labelledby="circular-progress-label-:r6:">
        <div class="" role="progressbar" aria-valuemin="0" aria-valuemax="100" aria-valuenow="70" style="width: 48px; height: 48px; position: relative; display: grid; place-items: center;">
            <svg width="48" height="48" viewBox="0 0 100 100" style="transform: rotate(-90deg);">
                <circle cx="50" cy="50" r="46" fill="none" stroke="var(--gray-lighter)" stroke-width="8" class="">
                </circle>
                <circle cx="50" cy="50" r="46" fill="none" stroke="var(--brand-success)" stroke-width="8" stroke-linecap="round" stroke-dasharray="289.02652413026095" stroke-dashoffset="289.02652413026095">
                </circle>
            </svg>
            <div class="position-absolute display-grid place-items-center">
                <span class="rioglyph rioglyph-ok text-color-success text-size-18">
                </span>
            </div>
        </div>
        <div id="circular-progress-label-:r6:" class="">sm</div>
    </div>
    <div class="display-flex flex-column align-items-center text-center gap-10 " aria-labelledby="circular-progress-label-:r7:">
        <div class="" role="progressbar" aria-valuemin="0" aria-valuemax="100" aria-valuenow="70" style="width: 64px; height: 64px; position: relative; display: grid; place-items: center;">
            <svg width="64" height="64" viewBox="0 0 100 100" style="transform: rotate(-90deg);">
                <circle cx="50" cy="50" r="46" fill="none" stroke="var(--gray-lighter)" stroke-width="8" class="">
                </circle>
                <circle cx="50" cy="50" r="46" fill="none" stroke="var(--brand-success)" stroke-width="8" stroke-linecap="round" stroke-dasharray="289.02652413026095" stroke-dashoffset="289.02652413026095">
                </circle>
            </svg>
            <div class="position-absolute display-grid place-items-center">
                <span class="rioglyph rioglyph-ok text-color-success text-size-h3">
                </span>
            </div>
        </div>
        <div id="circular-progress-label-:r7:" class="">md</div>
    </div>
    <div class="display-flex flex-column align-items-center text-center gap-10 " aria-labelledby="circular-progress-label-:r8:">
        <div class="" role="progressbar" aria-valuemin="0" aria-valuemax="100" aria-valuenow="70" style="width: 80px; height: 80px; position: relative; display: grid; place-items: center;">
            <svg width="80" height="80" viewBox="0 0 100 100" style="transform: rotate(-90deg);">
                <circle cx="50" cy="50" r="46" fill="none" stroke="var(--gray-lighter)" stroke-width="8" class="">
                </circle>
                <circle cx="50" cy="50" r="46" fill="none" stroke="var(--brand-success)" stroke-width="8" stroke-linecap="round" stroke-dasharray="289.02652413026095" stroke-dashoffset="289.02652413026095">
                </circle>
            </svg>
            <div class="position-absolute display-grid place-items-center">
                <span class="rioglyph rioglyph-ok text-color-success text-size-h2">
                </span>
            </div>
        </div>
        <div id="circular-progress-label-:r8:" class="">lg</div>
    </div>
    <div class="display-flex flex-column align-items-center text-center gap-10 " aria-labelledby="circular-progress-label-:r9:">
        <div class="" role="progressbar" aria-valuemin="0" aria-valuemax="100" aria-valuenow="70" style="width: 120px; height: 120px; position: relative; display: grid; place-items: center;">
            <svg width="120" height="120" viewBox="0 0 100 100" style="transform: rotate(-90deg);">
                <circle cx="50" cy="50" r="46" fill="none" stroke="var(--gray-lighter)" stroke-width="8" class="">
                </circle>
                <circle cx="50" cy="50" r="46" fill="none" stroke="var(--brand-success)" stroke-width="8" stroke-linecap="round" stroke-dasharray="289.02652413026095" stroke-dashoffset="289.02652413026095">
                </circle>
            </svg>
            <div class="position-absolute display-grid place-items-center">
                <span class="rioglyph rioglyph-ok text-color-success text-size-h1">
                </span>
            </div>
        </div>
        <div id="circular-progress-label-:r9:" class="">xl</div>
    </div>
</div>
<div class="Divider position-relative width-100pct" style="padding-top: 25px; padding-bottom: 25px;">
    <div class="divider-line bg-light" style="width: 100%; height: 1px;">
    </div>
</div>
<div class="text-color-dark max-width-100pct text-size-12 display-inline-block margin-bottom-5">Strong customization</div>
<div class="display-grid place-items-center bg-primary width-200 height-200 rounded">
    <div class="display-flex flex-column align-items-center text-center gap-10 " aria-labelledby="circular-progress-label-:ra:">
        <div class="" role="progressbar" aria-valuemin="0" aria-valuemax="100" aria-valuenow="40" aria-valuetext="40%" style="width: 120px; height: 120px; position: relative; display: grid; place-items: center;">
            <svg width="120" height="120" viewBox="0 0 100 100" style="transform: rotate(-90deg);">
                <circle cx="50" cy="50" r="44" fill="none" stroke="var(--gray-lighter)" stroke-width="12" class="opacity-30">
                </circle>
                <circle cx="50" cy="50" r="44" fill="none" stroke="var(--color-white)" stroke-width="12" stroke-linecap="round" stroke-dasharray="276.46015351590177" stroke-dashoffset="276.46015351590177">
                </circle>
            </svg>
            <div class="position-absolute display-grid place-items-center text-medium text-size-h2 text-color-white">40%</div>
        </div>
        <div id="circular-progress-label-:ra:" class="">
            <div class="border border-color-white rounded-circle padding-x-10 padding-y-5">3200 Points</div>
        </div>
    </div>
</div>
```

#### Props

| Name | Type | Default | Description |
| --- | --- | --- | --- |
| label | React.ReactNode | — | Optional text or node shown below the ring. |
| size | CircularProgressSize | 'md' | Preset size for the component. Possible values are: 'xs' 'sm' 'md' 'lg' 'xl' |
| color | CircularProgressColor | 'primary' | Color preset for the progress ring. Possible values are: 'default' 'primary' 'secondary' 'info' 'success' 'warning' 'danger' 'white' |
| value | number | 0 | Defaults to 0 to avoid indeterminate/spinner visuals. |
| valueLabel | React.ReactNode | — | Override the rendered value label content. |
| minValue | number | 0 | Minimum value for the range. |
| maxValue | number | 100 | Maximum value for the range. |
| formatOptions | Intl.NumberFormatOptions | — | Formatting for the visible value label. - If style === "percent": formats ratio (value-min)/(max-min) - Otherwise: formats the raw value (e.g. unit) |
| isIndeterminate | boolean | false | Indeterminate mode is opt-in. Animates the progress indefinitely. May come in handy when the value still loads to prevent layout shifting. |
| showValueLabel | boolean | true | Toggles the value label in the center of the ring. |
| strokeWidth | number | 8 | Stroke width used for the ring and track. |
| trackColor | CircularProgressTrackColor | 'lighter' | Track color preset for the background ring. Possible values are: 'decent' 'lightest' 'lighter' 'light' 'gray' 'dark' 'darker' 'darkest' 'white' |
| trackClassName | string | — | Class name for the track (background ring). |
| disableAnimation | boolean | false | Disable motion even if the user allows animations. |
| animationDelay | number | 0 | Delay before the progress animation starts (in seconds). |
| className | string | — | Class name for the outer wrapper. |
| ringWrapClassName | string | — | Class name for the ring wrapper. |
| valueLabelClassName | string | — | Class name for the center value label. |
| labelClassName | string | — | Class name for the label under the ring. |

### Example: Example 2

0%

Processing configuration...

#### React (tsx)

```tsx
import CircularProgress from '@rio-cloud/rio-uikit/CircularProgress';
import { useEffect, useState } from 'react';

export default () => {
    const [value, setValue] = useState(0);

    useEffect(() => {
        const interval = setInterval(() => {
            setValue(v => (v >= 100 ? 0 : v + 10));
        }, 500);

        return () => clearInterval(interval);
    }, []);

    return (
        <CircularProgress
            label='Processing configuration...'
            color='info'
            value={value}
            formatOptions={{ style: 'unit', unit: 'percent' }}
        />
    );
};
```

#### HTML (html)

```html
<div class="display-flex flex-column align-items-center text-center gap-10 " aria-labelledby="circular-progress-label-:rb:">
    <div class="" role="progressbar" aria-valuemin="0" aria-valuemax="100" aria-valuenow="20" aria-valuetext="20%" style="width: 64px; height: 64px; position: relative; display: grid; place-items: center;">
        <svg width="64" height="64" viewBox="0 0 100 100" style="transform: rotate(-90deg);">
            <circle cx="50" cy="50" r="46" fill="none" stroke="var(--gray-lighter)" stroke-width="8" class="">
            </circle>
            <circle cx="50" cy="50" r="46" fill="none" stroke="var(--brand-info)" stroke-width="8" stroke-linecap="round" stroke-dasharray="289.02652413026095" stroke-dashoffset="261.38903288417055">
            </circle>
        </svg>
        <div class="position-absolute display-grid place-items-center">20%</div>
    </div>
    <div id="circular-progress-label-:rb:" class="">Processing configuration...</div>
</div>
```

#### Props

| Name | Type | Default | Description |
| --- | --- | --- | --- |
| label | React.ReactNode | — | Optional text or node shown below the ring. |
| size | CircularProgressSize | 'md' | Preset size for the component. Possible values are: 'xs' 'sm' 'md' 'lg' 'xl' |
| color | CircularProgressColor | 'primary' | Color preset for the progress ring. Possible values are: 'default' 'primary' 'secondary' 'info' 'success' 'warning' 'danger' 'white' |
| value | number | 0 | Defaults to 0 to avoid indeterminate/spinner visuals. |
| valueLabel | React.ReactNode | — | Override the rendered value label content. |
| minValue | number | 0 | Minimum value for the range. |
| maxValue | number | 100 | Maximum value for the range. |
| formatOptions | Intl.NumberFormatOptions | — | Formatting for the visible value label. - If style === "percent": formats ratio (value-min)/(max-min) - Otherwise: formats the raw value (e.g. unit) |
| isIndeterminate | boolean | false | Indeterminate mode is opt-in. Animates the progress indefinitely. May come in handy when the value still loads to prevent layout shifting. |
| showValueLabel | boolean | true | Toggles the value label in the center of the ring. |
| strokeWidth | number | 8 | Stroke width used for the ring and track. |
| trackColor | CircularProgressTrackColor | 'lighter' | Track color preset for the background ring. Possible values are: 'decent' 'lightest' 'lighter' 'light' 'gray' 'dark' 'darker' 'darkest' 'white' |
| trackClassName | string | — | Class name for the track (background ring). |
| disableAnimation | boolean | false | Disable motion even if the user allows animations. |
| animationDelay | number | 0 | Delay before the progress animation starts (in seconds). |
| className | string | — | Class name for the outer wrapper. |
| ringWrapClassName | string | — | Class name for the ring wrapper. |
| valueLabelClassName | string | — | Class name for the center value label. |
| labelClassName | string | — | Class name for the label under the ring. |