---
title: Progress
description: Determinate or indeterminate progress indicator with optional step labels.
sidebar:
  order: 10
search:
  tags: [loading, percentage, steps, indicator]
---

# Progress

> Determinate or indeterminate progress indicator with optional step labels.

## Import

```tsx
import { Progress } from 'moraine'
```

## Slot Structure

Track with a fill indicator, optional status text, and step labels.

```text
root
├── status (optional, determinate only)
├── track
│   └── indicator
└── steps (optional, step mode)
    └── step (×n)
```

## Examples

### Sizes

Size scale from `xs` to `xl`.

```tsx
function Sizes() {
  const SIZES: ProgressSize[] = ['xs', 'sm', 'md', 'lg', 'xl']

  return (
    <div class="w-xl space-y-3">
      <For each={SIZES}>
        {(size) => (
          <div class="flex gap-3 items-center">
            <span class="text-xs text-muted-foreground font-mono w-8">{size}</span>
            <div class="flex-1">
              <Progress value={56} size={size} />
            </div>
          </div>
        )}
      </For>
    </div>
  )
}
```

### Orientations

Horizontal and vertical layouts with consistent value rendering.

```tsx
function Orientations() {
  return (
    <div class="flex gap-6 w-xl items-end">
      <div class="flex-1 space-y-2">
        <p class="text-xs text-muted-foreground font-mono">horizontal</p>
        <Progress value={32} status />
      </div>

      <div class="space-y-2">
        <p class="text-xs text-muted-foreground font-mono">vertical</p>
        <div class="h-44">
          <Progress value={32} status orientation="vertical" />
        </div>
      </div>
    </div>
  )
}
```

### Determinate

Standard progress bar with status text and custom status renderer.

```tsx
function Determinate() {
  const [value, setValue] = createSignal(35)

  const increment = () => {
    setValue((current) => Math.min(current + 10, 100))
  }

  const reset = () => {
    setValue(0)
  }

  return (
    <div class="w-xl space-y-3">
      <Progress value={value()} status statusRender={(props) => <>Completed {props.percent}%</>} />
      <div class="flex gap-2">
        <Button size="sm" variant="outline" onClick={increment}>
          +10%
        </Button>
        <Button size="sm" variant="ghost" onClick={reset}>
          Reset
        </Button>
      </div>
    </div>
  )
}
```

### Animations

Indeterminate animation variants: `carousel`, `reverse`, `swing`, and `elastic`.

```tsx
function Animations() {
  const ANIMATIONS: ProgressAnimation[] = ['carousel', 'reverse', 'swing', 'elastic']

  return (
    <div class="w-xl space-y-3">
      <For each={ANIMATIONS}>
        {(animation) => (
          <div class="flex gap-3 items-center">
            <span class="text-xs text-muted-foreground font-mono w-16">{animation}</span>
            <div class="flex-1">
              <Progress value={null} animation={animation} />
            </div>
          </div>
        )}
      </For>
    </div>
  )
}
```

### Step Mode

String-array max renders named steps.

```tsx
function StepMode() {
  const STEPS = ['Queued', 'Building', 'Deploying', 'Done']
  const [value, setValue] = createSignal(0)

  const next = () => {
    setValue((current) => Math.min(current + 1, STEPS.length - 1))
  }

  const previous = () => {
    setValue((current) => Math.max(current - 1, 0))
  }

  const reset = () => {
    setValue(0)
  }

  return (
    <div class="w-xl space-y-3">
      <Progress value={value()} max={STEPS} status />
      <div class="text-xs text-muted-foreground">
        Current: {STEPS[value()]} ({value() + 1}/{STEPS.length})
      </div>
      <div class="flex gap-2">
        <Button size="sm" variant="outline" onClick={previous}>
          Back
        </Button>
        <Button size="sm" variant="outline" onClick={next}>
          Next
        </Button>
        <Button size="sm" variant="ghost" onClick={reset}>
          Reset
        </Button>
      </div>
    </div>
  )
}
```

## API Reference

### Attributes

#### `root`

Progress container that owns track, indicator, labels, and step markers.

##### Data Attributes

| Attribute | Type | Description |
| --- | --- | --- |
| data-orientation | string \| undefined | Stores the rendered orientation. |

##### ARIA Attributes

| Attribute | Type | Description |
| --- | --- | --- |
| aria-valuemax | boolean \| string \| undefined | Defines the maximum value for range-like controls. |
| aria-valuemin | boolean \| string \| undefined | Defines the minimum value for range-like controls. |
| aria-valuenow | boolean \| string \| undefined | Defines the current numeric value for range-like controls. |
| aria-valuetext | boolean \| string \| undefined | Provides human-readable text for the current value. |
| role | string | Defines the semantic role exposed to assistive technology. |

#### `status`

Text region that displays the current progress status.

#### `track`

Background rail that represents the full progress range.

#### `indicator`

Filled bar that represents the current progress value.

#### `steps`

Wrapper for step labels when progress is driven by named steps.

#### `step`

Individual step label or marker rendered along the progress scale.

### Props

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| animation | "carousel" \| "reverse" \| "swing" \| "elastic" \| undefined | — | — |
| class | ClassValue | — | Class applied to the component root or trigger element. |
| classes | ProgressT.Classes \| undefined | — | — |
| getValueLabel | ((params: { value: number; min: number; max: number; }) => string) \| undefined | — | Callback to get a localized label for the current value. |
| max | number \| string[] \| undefined | 100 | The maximum value of the progress bar, or an array of step labels. |
| orientation | "horizontal" \| "vertical" \| undefined | — | — |
| ref | JSX.HTMLElementTags["div"] extends { ref?: infer Ref; } ? Ref : never \| undefined | — | — |
| size | "xs" \| "sm" \| "md" \| "lg" \| "xl" \| undefined | — | — |
| status | boolean \| undefined | false | Whether to show the status label. |
| statusRender | ComponentOrElement<ProgressT.StatusRenderProps> \| undefined | — | Custom render function for the status label. |
| stepRender | ComponentOrElement<ProgressT.StepRenderProps> \| undefined | — | Custom render function for each step when `max` is an array. |
| style | JSX.CSSProperties \| undefined | — | — |
| styles | ProgressT.Styles \| undefined | — | — |
| value | number \| null \| undefined | null | The current value of the progress bar. If null/undefined, it is indeterminate. |

### ARIA

Accessibility attributes and roles emitted by the component markup.

| Attribute | Type | Description |
| --- | --- | --- |
| aria-valuemax | boolean \| string \| undefined | Defines the maximum value for range-like controls. |
| aria-valuemin | boolean \| string \| undefined | Defines the minimum value for range-like controls. |
| aria-valuenow | boolean \| string \| undefined | Defines the current numeric value for range-like controls. |
| aria-valuetext | boolean \| string \| undefined | Provides human-readable text for the current value. |
| role | string | Defines the semantic role exposed to assistive technology. |

### Data Attributes

State and slot attributes exposed for styling hooks and selectors.

| Attribute | Type | Description |
| --- | --- | --- |
| data-orientation | string \| undefined | Stores the rendered orientation. |
| data-slot | string | Identifies the rendered slot for styling hooks and selectors. |
