> ## Documentation Index
> Fetch the complete documentation index at: https://docs.twenty.com/llms.txt
> Use this file to discover all available pages before exploring further.

# ProgressRing

> Show a known progress value in a compact circular indicator.

export const StoryEmbed = ({storyId, title, height = 240}) => <>
    <Tabs>
      <Tab title="Light">
        <iframe title={`${title} (light)`} src={`https://storybook.twenty.com/iframe.html?id=${storyId}&viewMode=story&globals=colorScheme:light`} width="100%" height={height} loading="lazy" style={{
  border: 0
}} />
      </Tab>
      <Tab title="Dark">
        <iframe title={`${title} (dark)`} src={`https://storybook.twenty.com/iframe.html?id=${storyId}&viewMode=story&globals=colorScheme:dark`} width="100%" height={height} loading="lazy" style={{
  border: 0
}} />
      </Tab>
    </Tabs>
    <a href={`https://storybook.twenty.com/?path=/story/${storyId}`}>
      Open in Storybook
    </a>
  </>;

`ProgressRing` shows a controlled percentage with accessible progressbar semantics. It can display a preformatted value beside the ring.

<StoryEmbed storyId="ui-feedback-progressring-progressring--default" title="Progress ring example" height={140} />

## Usage

Supply a value from 0 to 100 and an accessible name. Use `aria-valuetext` when a formatted value explains progress more clearly than a percentage.

```tsx theme={null}
import { ProgressRing } from 'twenty-ui/primitives/feedback';

export const ImportProgress = () => (
  <ProgressRing
    value={60}
    aria-label="Importing records"
    aria-valuetext="600 of 1,000 records"
  >
    600 / 1,000
  </ProgressRing>
);
```

Use `aria-labelledby` to associate the ring with an existing visible label. The optional children display a value; they do not provide the ring's accessible name.

## Controlled progress

The application calculates `value` and formats the displayed text. The ring does not fetch data, advance progress, or calculate quotas. Values outside 0 to 100 are bounded to that range, including infinite values. `NaN` renders as zero. Displayed children stay unchanged.

Use [Loader](/ui/primitives/feedback/loader) for indeterminate loading, [ProgressBar](/ui/primitives/feedback/progress-bar) for horizontal progress, or [MetricRow](/ui/components/metric-row) for a label and aligned value.

## Appearance and motion

`size="md"` renders a 16px ring; `size="sm"` renders a 14px ring. Both use a 2px stroke and fill clockwise from the top. `barColor` accepts CSS colors, including theme variables.

Value changes animate for 300ms. The transition is disabled when the user prefers reduced motion. Native attributes, `className`, `style`, and `ref` target the outer progress element. `render` can replace that element while retaining the progress semantics.

## Props

<ParamField body="aria-label" type="string">
  Accessible name identifying the measured operation.
</ParamField>

<ParamField body="aria-labelledby" type="string">
  ID of the visible label that names the measured operation.
</ParamField>

<ParamField body="aria-valuetext" type="string">
  Human-readable progress value when a percentage alone is insufficient.
</ParamField>

<ParamField body="barColor" type="string">
  CSS color of the filled arc. Defaults to the blue theme color.
</ParamField>

<ParamField body="children" type="ReactNode">
  Optional preformatted value displayed before the ring.
</ParamField>

<ParamField body="className" type="string">
  CSS class applied to the progress root.
</ParamField>

<ParamField body="render" type="ReactElement<unknown, string | JSXElementConstructor<any>> | ComponentRenderFn<HTMLProps, {}>">
  Replaces the root element while preserving progress semantics.
</ParamField>

<ParamField body="size" type="&#x22;md&#x22; | &#x22;sm&#x22;" default="md">
  Ring diameter: sm (14px) or md (16px). Defaults to md.
</ParamField>

<ParamField body="style" type="CSSProperties">
  Inline styles applied to the progress root.
</ParamField>

<ParamField body="value" type="number" required>
  Controlled progress from 0 to 100. Out-of-range values are bounded and NaN renders as zero.
</ParamField>
