# Progress

<FrameworkCodeSwitcher>
  <div slot="astro">
```astro
---
import { Progress } from "@/components/starwind/progress";
---

<div class="w-full max-w-[400px]">
  <Progress id="demo-progress" value={50} />
</div>
```
  </div>
  <div slot="react">
```tsx
import { Progress } from "@/components/starwind/progress";

export function Example() {
  return (
    <>
      <div className="w-full max-w-[400px]">
        <Progress id="demo-progress" value={50} />
      </div>
    </>
  );
}
```
  </div>
  <div slot="vue">
```vue
<script setup lang="ts">
import { Progress } from "@/components/starwind/progress";
</script>

<template>
  <div class="w-full max-w-[400px]">
    <Progress id="demo-progress" :value="50" />
  </div>
</template>
```
  </div>
</FrameworkCodeSwitcher>

## Installation

```bash
npx starwind@latest add progress --framework astro
```
</DocsTabsContent>
```bash
npx starwind@latest add progress --framework react
```
</DocsTabsContent>
```bash
npx starwind@latest add progress --framework vue
```
</DocsTabsContent>
</DocsTabs>

## Usage

<FrameworkCodeSwitcher>
  <div slot="astro">
```astro
---
import { Progress } from "@/components/starwind/progress";
---

<div class="w-full max-w-[400px]">
  <Progress id="demo-progress" value={50} />
</div>
```
  </div>
  <div slot="react">
```tsx
import { Progress } from "@/components/starwind/progress";

export function Example() {
  return (
    <>
      <div className="w-full max-w-[400px]">
        <Progress id="demo-progress" value={50} />
      </div>
    </>
  );
}
```
  </div>
  <div slot="vue">
```vue
<script setup lang="ts">
import { Progress } from "@/components/starwind/progress";
</script>

<template>
  <div class="w-full max-w-[400px]">
    <Progress id="demo-progress" :value="50" />
  </div>
</template>
```
  </div>
</FrameworkCodeSwitcher>

## Variants

<FrameworkCodeSwitcher>
  <div slot="astro">
```astro
---
import { Progress } from "@/components/starwind/progress";
---

<div class="flex flex-col gap-4 w-full max-w-[400px]" slot="preview">
  <Progress id="default" value={60} variant="default" />
  <Progress id="primary" value={60} variant="primary" />
  <Progress id="secondary" value={60} variant="secondary" />
  <Progress id="info" value={60} variant="info" />
  <Progress id="success" value={60} variant="success" />
  <Progress id="warning" value={60} variant="warning" />
  <Progress id="error" value={60} variant="error" />
</div>
```
  </div>
  <div slot="react">
```tsx
import { Progress } from "@/components/starwind/progress";

export function Example() {
  return (
    <>
      <div className="flex flex-col gap-4 w-full max-w-[400px]">
        <Progress id="default" value={60} variant="default" />
        <Progress id="primary" value={60} variant="primary" />
        <Progress id="secondary" value={60} variant="secondary" />
        <Progress id="info" value={60} variant="info" />
        <Progress id="success" value={60} variant="success" />
        <Progress id="warning" value={60} variant="warning" />
        <Progress id="error" value={60} variant="error" />
      </div>
    </>
  );
}
```
  </div>
  <div slot="vue">
```vue
<script setup lang="ts">
import { Progress } from "@/components/starwind/progress";
</script>

<template>
  <div class="flex flex-col gap-4 w-full max-w-[400px]">
    <Progress id="default" :value="60" variant="default" />
    <Progress id="primary" :value="60" variant="primary" />
    <Progress id="secondary" :value="60" variant="secondary" />
    <Progress id="info" :value="60" variant="info" />
    <Progress id="success" :value="60" variant="success" />
    <Progress id="warning" :value="60" variant="warning" />
    <Progress id="error" :value="60" variant="error" />
  </div>
</template>
```
  </div>
</FrameworkCodeSwitcher>

## Indeterminate

When you need to show a loading state without a specific value, omit the `value` prop to create an indeterminate progress bar.

<FrameworkCodeSwitcher>
  <div slot="astro">
```astro
---
import { Progress } from "@/components/starwind/progress";
---

<Progress id="indeterminate" />
```
  </div>
  <div slot="react">
```tsx
import { Progress } from "@/components/starwind/progress";

export function Example() {
  return (
    <>
      <Progress id="indeterminate" />
    </>
  );
}
```
  </div>
  <div slot="vue">
```vue
<script setup lang="ts">
import { Progress } from "@/components/starwind/progress";
</script>

<template>
  <Progress id="indeterminate" />
</template>
```
  </div>
</FrameworkCodeSwitcher>

## Dynamic Updates

The Progress component can be updated dynamically by changing the `data-value` attribute. This is useful for showing real-time progress like file uploads, form completion, or step-by-step processes.

<FrameworkCodeSwitcher>
  <div slot="astro">
```astro
---
import { Progress } from "@/components/starwind/progress";
import { Button } from "@/components/starwind/button";
---

<div class="flex w-full max-w-[400px] flex-col gap-4">
  <h3 class="text-lg font-medium">Interactive Progress Example</h3>

  <div class="space-y-4">
    <Progress id="interactive-progress" value={25} class="w-full" />

    <Button id="toggle-progress" variant="outline">Toggle Progress (25% ⟷ 75%)</Button>
  </div>
</div>

<script>
  let isHighValue = false;

  function setupProgressExample() {
    const progressElement = document.getElementById("interactive-progress");
    const toggleButton = document.getElementById("toggle-progress");

    if (!progressElement || !toggleButton) return;

    toggleButton.addEventListener("click", () => {
      isHighValue = !isHighValue;
      const newValue = isHighValue ? 75 : 25;

      progressElement.setAttribute("data-value", String(newValue));
    });
  }

  setupProgressExample();
  document.addEventListener("astro:after-swap", setupProgressExample);
</script>
```
  </div>
  <div slot="react">
```tsx
import { useState } from "react";
import { Button } from "@/components/starwind/button";
import { Progress } from "@/components/starwind/progress";

export function Example() {
  const [value, setValue] = useState(25);

  return (
    <div className="flex w-full max-w-[400px] flex-col gap-4">
      <h3 className="text-lg font-medium">Interactive Progress Example</h3>
      <div className="space-y-4">
        <Progress value={value} className="w-full" />
        <Button
          variant="outline"
          onClick={() => setValue((current) => (current === 25 ? 75 : 25))}
        >
          Toggle Progress (25% ↔ 75%)
        </Button>
      </div>
    </div>
  );
}
```
  </div>
  <div slot="vue">
```vue
<script setup lang="ts">
import { Progress } from "@/components/starwind/progress";
import { Button } from "@/components/starwind/button";
import { ref } from "vue";
const value = ref(25);
</script>

<template>
  <div class="flex w-full max-w-[400px] flex-col gap-4">
    <h3 class="text-lg font-medium">Interactive Progress Example</h3>

    <div class="space-y-4">
      <Progress id="interactive-progress" :value="value" class="w-full" />

      <Button @click="value = value === 25 ? 75 : 25" variant="outline"
        >Toggle Progress (25% ⟷ 75%)</Button
      >
    </div>
  </div>
</template>
```
  </div>
</FrameworkCodeSwitcher>

## API Reference
### Progress
| Prop | Type | Required | Default | Kind | Description |
| --- | --- | --- | --- | --- | --- |
| `label` | `string` | No | - | Wrapper prop | Provides accessible text for the component. |
| `max` | `number` | No | `100` | Wrapper prop | Sets the maximum accepted value. |
| `min` | `number` | No | `0` | Wrapper prop | Sets the minimum accepted value. |
| `value` | `number \| null` | No | `null` | Wrapper prop | Controls or identifies the component value. |
| `variant` | `"default" \| "primary" \| "secondary" \| "info" \| "success" \| "warning" \| "error"` | No | `"default"` | Wrapper prop | Selects the component's visual variant. |
- Inherits div attributes. Omits `value`.
### Primitive And Runtime API
Behavior, state, events, form participation, and imperative methods are documented in the lower-level references.
- Primitive: [Progress Primitive](/docs/primitives/progress/)
- Runtime factory: [`createProgress`](/docs/runtime/#create-progress) from `@starwind-ui/runtime/progress`

## Changelog

### v2.0.3

- Progress indicators now use the neutral `default` color variant when `color` is omitted.

### v2.0.2

- Updated React Runtime state synchronization so canceled proposals stay uncommitted and accepted changes remain aligned.

### v2.0.1

- Normalized reversed, equal, invalid, and non-finite ranges and values consistently across the Astro and React components.
- Prevented transitions between incompatible determinate and indeterminate indicator geometries while preserving determinate value transitions and reduced-motion behavior.

### v2.0.0

- Rebuilt Progress on Starwind Runtime for determinate and indeterminate state.
- See the [Progress Primitive](/docs/primitives/progress/) for the underlying unstyled anatomy and behavior API.

### v1.1.3

- Refactor tailwind variants functions into separate `variants.ts` file

### v1.1.1

- Add `starwind:init` event listener to enable initialization of additional Progress loaded after an initial page load, such as when using server islands

### v1.1.0

- Add `data-slot` attribute to enable global styling updates

### v1.0.0

- Initial release with starwind v1.7.0