> ## 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.

# Progress

> Compose accessible progress with shared range, labeling, and value semantics.

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>
  </>;

`Progress` exposes the installed Base UI parts: `Root`, `Track`, `Indicator`, `Label`, and `Value`. Import them from `twenty-ui/primitives/feedback`. Use [ProgressBar](/ui/primitives/feedback/progress-bar) or [ProgressRing](/ui/primitives/feedback/progress-ring) for a convenient appearance with the same semantic contract.

<StoryEmbed storyId="ui-feedback-progress--default" title="Composed progress example" height={180} />

## Compose progress

`Root` owns the controlled value and accessible progressbar semantics. `Label` supplies its accessible name. `Value` displays the formatted value. `Track` and `Indicator` describe the visual fill; the indicator width comes from the root's normalized range. The parts do not impose an appearance.

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

export const ImportProgress = () => (
  <Progress.Root value={70} min={20} max={120} style={{ width: 240 }}>
    <Progress.Label>Importing records</Progress.Label>
    <Progress.Value />
    <Progress.Track
      style={{ height: 8, background: 'var(--t-background-tertiary)' }}
    >
      <Progress.Indicator
        style={{ background: 'var(--t-font-color-primary)' }}
      />
    </Progress.Track>
  </Progress.Root>
);
```

This range displays `50%` while `aria-valuenow` is `70`, `aria-valuemin` is `20`, and `aria-valuemax` is `120`. The application owns requests, timing, and progress updates. There is no `defaultValue` or automatic advancement.

## Values, ranges, and indeterminate progress

`min` defaults to `0`, and `max` defaults to `100`. Supply finite bounds with `min < max`. Finite values outside the range are clamped for the semantic value, formatted value, and visual fill. Completion occurs at the maximum. Changing the range recalculates the percentage without changing the raw value supplied by the application.

Pass `value={null}` when the amount of progress is unknown. The root then has indeterminate status, omits `aria-valuenow`, and uses `indeterminate progress` as its default accessible value text. Non-finite values also remain indeterminate; they are not converted to zero. The raw `Indicator` has no computed percentage width in that state, so the composition chooses its indeterminate appearance.

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

export const PendingImport = () => (
  <ProgressBar value={null} aria-label="Preparing the import" />
);
```

## Labels and formatting

Compose `Progress.Label` inside `Root`, or set native `aria-label` or `aria-labelledby`. Use `aria-valuetext` for a human-readable alternative when a percentage is insufficient.

The default formatter displays the normalized percentage. `locale` and `format` retain the installed `Intl.NumberFormat` contract; an explicit `format` formats the clamped numeric value. `getAriaValueText(formattedValue, value)` receives that formatted text and the raw application value, including `null`. It changes the accessible value text without changing the fill.

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

export const RecordCount = () => (
  <Progress.Root
    value={600}
    max={1000}
    format={{ style: 'decimal' }}
    getAriaValueText={(formattedValue) => `${formattedValue} of 1,000 records`}
  >
    <Progress.Label>Importing records</Progress.Label>
    <Progress.Value>
      {(formattedValue) => `${formattedValue} / 1,000`}
    </Progress.Value>
  </Progress.Root>
);
```

`Progress.Value` receives both the formatted value and raw value through its optional child callback. For indeterminate progress, the callback receives `indeterminate` as formatted text; without a callback, the value part displays no content. Display content does not automatically become the accessible name or accessible value text.

## Native props, refs, and composition

| Part | Default DOM and ref target |
| - | - |
| `Root` | Outer `div` with progressbar semantics |
| `Track` | Track `div` |
| `Indicator` | Fill `div` |
| `Label` | Label `span` |
| `Value` | Value `span` |

Every part preserves native props, refs, and the installed `render` composition contract. Forward the supplied props and ref when replacing an element. `className`, `style`, and `render` callbacks receive the public state with `status`: `progressing`, `complete`, or `indeterminate`. State attributes make the same status available to styles.

The entry point exports `ProgressStatus` and the `Props` and `State` types for every part, including `ProgressRootProps`, `ProgressRootState`, `ProgressIndicatorProps`, and `ProgressIndicatorState`. Each part forwards native event handlers. Applications own feature choreography and completion callbacks.

## Props

### Progress.Root

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

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

<ParamField body="Root.aria-valuetext" type="string">
  Human-readable progress value overriding the default formatted value.
</ParamField>

<ParamField body="Root.children" type="ReactNode">
  Composed Progress parts and supporting content.
</ParamField>

<ParamField body="Root.className" type="string | ((state: ProgressRootState) => string | undefined)">
  Class applied to this part, or a callback receiving its progress status.
</ParamField>

<ParamField body="Root.format" type="NumberFormatOptions">
  Intl.NumberFormat options for the clamped numeric value. The default displays the normalized percentage.
</ParamField>

<ParamField body="Root.getAriaValueText" type="((formattedValue: string, value: number | null) => string)">
  Receives the formatted value and raw value, including null, and returns an accessible value description.
</ParamField>

<ParamField body="Root.locale" type="LocalesArgument">
  Locale or locale list used to format the value. Defaults to the runtime locale.
</ParamField>

<ParamField body="Root.max" type="number" default="100">
  Inclusive maximum. Defaults to 100.
</ParamField>

<ParamField body="Root.min" type="number" default="0">
  Inclusive minimum. Defaults to 0.
</ParamField>

<ParamField body="Root.ref" type="Ref<HTMLDivElement>">
  Ref to the root div, or the element composed through Root.render.
</ParamField>

<ParamField body="Root.render" type="ReactElement<unknown, string | JSXElementConstructor<any>> | ComponentRenderFn<HTMLProps, ProgressRootState>">
  Composes this part with an element or render callback. Forward the supplied props and ref to the corresponding DOM element.
</ParamField>

<ParamField body="Root.style" type="CSSProperties | ((state: ProgressRootState) => CSSProperties | undefined)">
  Inline styles applied to this part, or a callback receiving its progress status.
</ParamField>

<ParamField body="Root.value" type="number | null" required>
  Controlled value in the min/max range. Use null for indeterminate progress.
</ParamField>

### Progress.Track

<ParamField body="Track.children" type="ReactNode">
  The indicator and optional supporting content.
</ParamField>

<ParamField body="Track.className" type="string | ((state: ProgressTrackState) => string | undefined)">
  Class applied to this part, or a callback receiving its progress status.
</ParamField>

<ParamField body="Track.ref" type="Ref<HTMLDivElement>">
  Ref to the track div, or the element composed through Track.render.
</ParamField>

<ParamField body="Track.render" type="ReactElement<unknown, string | JSXElementConstructor<any>> | ComponentRenderFn<HTMLProps, ProgressTrackState>">
  Composes this part with an element or render callback. Forward the supplied props and ref to the corresponding DOM element.
</ParamField>

<ParamField body="Track.style" type="CSSProperties | ((state: ProgressTrackState) => CSSProperties | undefined)">
  Inline styles applied to this part, or a callback receiving its progress status.
</ParamField>

### Progress.Indicator

<ParamField body="Indicator.className" type="string | ((state: ProgressIndicatorState) => string | undefined)">
  Class applied to this part, or a callback receiving its progress status.
</ParamField>

<ParamField body="Indicator.ref" type="Ref<HTMLDivElement>">
  Ref to the indicator div, or the element composed through Indicator.render.
</ParamField>

<ParamField body="Indicator.render" type="ReactElement<unknown, string | JSXElementConstructor<any>> | ComponentRenderFn<HTMLProps, ProgressIndicatorState>">
  Composes this part with an element or render callback. Forward the supplied props and ref to the corresponding DOM element.
</ParamField>

<ParamField body="Indicator.style" type="CSSProperties | ((state: ProgressIndicatorState) => CSSProperties | undefined)">
  Inline styles applied to this part, or a callback receiving its progress status.
</ParamField>

### Progress.Value

<ParamField body="Value.children" type="((formattedValue: string | null, value: number | null) => ReactNode) | null">
  Optional callback receiving the formatted value and raw value. Indeterminate progress passes indeterminate as formatted text. Without a callback, indeterminate progress displays no content.
</ParamField>

<ParamField body="Value.className" type="string | ((state: ProgressValueState) => string | undefined)">
  Class applied to this part, or a callback receiving its progress status.
</ParamField>

<ParamField body="Value.ref" type="Ref<HTMLSpanElement>">
  Ref to the value span, or the element composed through Value.render.
</ParamField>

<ParamField body="Value.render" type="ReactElement<unknown, string | JSXElementConstructor<any>> | ComponentRenderFn<HTMLProps, ProgressValueState>">
  Composes this part with an element or render callback. Forward the supplied props and ref to the corresponding DOM element.
</ParamField>

<ParamField body="Value.style" type="CSSProperties | ((state: ProgressValueState) => CSSProperties | undefined)">
  Inline styles applied to this part, or a callback receiving its progress status.
</ParamField>

### Progress.Label

<ParamField body="Label.children" type="ReactNode">
  Visible text that supplies the accessible name of the root.
</ParamField>

<ParamField body="Label.className" type="string | ((state: ProgressLabelState) => string | undefined)">
  Class applied to this part, or a callback receiving its progress status.
</ParamField>

<ParamField body="Label.ref" type="Ref<HTMLSpanElement>">
  Ref to the label span, or the element composed through Label.render.
</ParamField>

<ParamField body="Label.render" type="ReactElement<unknown, string | JSXElementConstructor<any>> | ComponentRenderFn<HTMLProps, ProgressLabelState>">
  Composes this part with an element or render callback. Forward the supplied props and ref to the corresponding DOM element.
</ParamField>

<ParamField body="Label.style" type="CSSProperties | ((state: ProgressLabelState) => CSSProperties | undefined)">
  Inline styles applied to this part, or a callback receiving its progress status.
</ParamField>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.