---
title: Progress
description: "Displays an indicator showing the completion progress of a task."
---

```tsx
'use client';

import * as React from 'react';

import * as stylex from '@stylexjs/stylex';

import {
  Progress,
  ProgressLabel,
  ProgressValue,
} from '@/components/ui/progress';
import { container } from '@/lib/constants.stylex';

export default function ProgressDemo() {
  const [value, setValue] = React.useState(13);

  React.useEffect(() => {
    const timer = setTimeout(() => setValue(66), 500);
    return () => clearTimeout(timer);
  }, []);

  return (
    <Progress value={value} locale="en-US" style={styles.root}>
      <ProgressLabel>Uploading…</ProgressLabel>
      <ProgressValue />
    </Progress>
  );
}

const styles = stylex.create({
  root: {
    maxWidth: container.sm,
  },
});
```

## Install

```bash
npx shadcn@latest add @madeui/progress
```

## Usage

```tsx
import {
  Progress,
  ProgressLabel,
  ProgressValue,
} from '@/components/ui/progress';
```

## Composition

```tsx
<Progress value={66}>
  <ProgressLabel />
  <ProgressValue />
</Progress>
```

`Progress` renders the track and indicator itself; `ProgressLabel` and `ProgressValue` are optional children placed above the track.

## Label

Use `ProgressLabel` and `ProgressValue` to add a label and percentage text.

```tsx
import * as stylex from '@stylexjs/stylex';

import { Progress, ProgressLabel, ProgressValue } from '@/components/ui/progress';
import { container } from '@/lib/constants.stylex';

export default function ProgressLabelExample() {
  return (
    <Progress value={72} locale="en-US" style={styles.root}>
      <ProgressLabel>Storage used</ProgressLabel>
      <ProgressValue />
    </Progress>
  );
}

const styles = stylex.create({
  root: {
    maxWidth: container.sm,
  },
});
```

## Controlled

Drive `value` from state — here a button advances it.

```tsx
'use client';

import * as React from 'react';

import * as stylex from '@stylexjs/stylex';

import { Button } from '@/components/ui/button';
import { Progress, ProgressValue } from '@/components/ui/progress';
import { container, space } from '@/lib/constants.stylex';

export default function ProgressControlled() {
  const [value, setValue] = React.useState(20);

  return (
    <div {...stylex.props(styles.wrap)}>
      <Progress value={value} locale="en-US">
        <ProgressValue />
      </Progress>
      <Button
        variant="outline"
        size="sm"
        onClick={() => setValue((current) => Math.min(current + 20, 100))}
        style={styles.button}
      >
        Advance
      </Button>
    </div>
  );
}

const styles = stylex.create({
  wrap: {
    alignItems: 'flex-start',
    display: 'flex',
    flexDirection: 'column',
    gap: space.s3,
    width: container.sm,
  },
  button: {
    alignSelf: 'flex-start',
  },
});
```

## API reference

Built on [Base UI Progress](https://base-ui.com/react/components/progress). All props are forwarded to the underlying Base UI parts — pass `value` (or `value={null}` for indeterminate), `min`, `max`; see the [Base UI Progress API reference](https://base-ui.com/react/components/progress#api-reference).

`ProgressValue` formats via `Intl.NumberFormat` using the runtime locale. In SSR apps, pass an explicit `locale` on `Progress` (e.g. `locale="en-US"`) — otherwise the server and a browser with a different locale render different text and React reports a hydration mismatch. Every part also accepts a `style` prop (`StyleXStyles`, merged last). `ProgressTrack` and `ProgressIndicator` are exported for custom layouts.
