# Radix UI React Progress

A React progress component that provides an accessible way to display the completion progress of a task, typically displayed as a progress bar. Part of the Radix UI Primitives collection, it offers compound component architecture with Progress as the root container and ProgressIndicator for displaying the visual progress representation.

## Package Information

- **Package Name**: @radix-ui/react-progress
- **Package Type**: npm
- **Language**: TypeScript
- **Installation**: `npm install @radix-ui/react-progress`

## Core Imports

```typescript
import { Progress, ProgressIndicator } from "@radix-ui/react-progress";
```

Import with types:

```typescript
import { 
  Progress, 
  ProgressIndicator, 
  type ProgressProps, 
  type ProgressIndicatorProps 
} from "@radix-ui/react-progress";
```

Import with context scope creation:

```typescript
import { 
  Progress, 
  ProgressIndicator, 
  createProgressScope 
} from "@radix-ui/react-progress";
```

Alternative component name imports:

```typescript
import { Root, Indicator } from "@radix-ui/react-progress";
```

For CommonJS:

```javascript
const { Progress, ProgressIndicator } = require("@radix-ui/react-progress");
```

**Note**: This package includes a `'use client'` directive for Next.js App Router compatibility.

## Basic Usage

```typescript
import * as React from "react";
import { Progress, ProgressIndicator } from "@radix-ui/react-progress";

// Determinate progress (specific value)
function App() {
  const [progress, setProgress] = React.useState(65);

  return (
    <Progress value={progress} max={100} className="progress-root">
      <ProgressIndicator 
        className="progress-indicator" 
        style={{ transform: `translateX(-${100 - progress}%)` }}
      />
    </Progress>
  );
}

// Indeterminate progress (loading state)
function LoadingProgress() {
  return (
    <Progress className="progress-root">
      <ProgressIndicator className="progress-indicator loading" />
    </Progress>
  );
}
```

## Architecture

The Progress component follows Radix UI's compound component pattern:

- **Progress (Root)**: Container component that manages state and accessibility attributes
- **ProgressIndicator**: Visual component that displays the progress representation
- **Context-based Communication**: Components share state through React context
- **Accessibility-first**: Built-in ARIA attributes and screen reader support
- **Styling Flexibility**: Unstyled components that accept className and style props

## Capabilities

### Progress Root Component

The main container component that provides context and accessibility attributes for the progress indicator.

```typescript { .api }
interface ProgressProps extends React.ComponentPropsWithoutRef<'div'> {
  /** The progress value. Use `null` or `undefined` for indeterminate progress */
  value?: number | null | undefined;
  /** The maximum progress value. Defaults to 100 */
  max?: number;
  /** Custom function to generate value label for accessibility. Defaults to percentage calculation */
  getValueLabel?(value: number, max: number): string;
}

declare const Progress: React.ForwardRefExoticComponent<
  ProgressProps & React.RefAttributes<HTMLDivElement>
>;
```

**Progress States:**
- **loading**: Progress value between 0 and max (excluding max)
- **complete**: Progress value equals max value
- **indeterminate**: No value provided (null or undefined)

**Data Attributes:**
- `data-state`: Current progress state ('loading' | 'complete' | 'indeterminate')
- `data-value`: Current progress value (when not indeterminate)
- `data-max`: Maximum progress value

**ARIA Attributes:**
- `role="progressbar"`
- `aria-valuemin="0"`
- `aria-valuemax`: Set to max prop value
- `aria-valuenow`: Current progress value (when not indeterminate)
- `aria-valuetext`: Generated value label for accessibility

### Progress Indicator Component

Visual component that displays the actual progress representation and inherits state from the Progress context.

```typescript { .api }
interface ProgressIndicatorProps extends React.ComponentPropsWithoutRef<'div'> {}

declare const ProgressIndicator: React.ForwardRefExoticComponent<
  ProgressIndicatorProps & React.RefAttributes<HTMLDivElement>
>;
```

The ProgressIndicator automatically receives the same data attributes as the Progress component:
- `data-state`: Inherited progress state
- `data-value`: Inherited progress value
- `data-max`: Inherited maximum value

### Component Aliases

```typescript { .api }
/** Alias for Progress component */
declare const Root: typeof Progress;

/** Alias for ProgressIndicator component */
declare const Indicator: typeof ProgressIndicator;
```

### Context Scope Creation

For advanced use cases requiring multiple Progress components with isolated contexts.

```typescript { .api }
/**
 * Creates a scoped context for Progress components
 * @returns Scope creation function for isolated Progress contexts
 */
declare function createProgressScope(): CreateScope;

/** Create scope function interface */
interface CreateScope {
  scopeName: string;
  (): ScopeHook;
}

/** Scope hook type returned by createProgressScope */
type ScopeHook = (scope: Scope) => { [__scopeProp: string]: Scope };

/** Scope type for context isolation */
type Scope<C = any> = { [scopeName: string]: React.Context<C>[] } | undefined;
```

## Types

```typescript { .api }
/** Props interface for Progress component */
interface ProgressProps extends React.ComponentPropsWithoutRef<'div'> {
  value?: number | null | undefined;
  max?: number;
  getValueLabel?(value: number, max: number): string;
}

/** Props interface for ProgressIndicator component */
interface ProgressIndicatorProps extends React.ComponentPropsWithoutRef<'div'> {}

/** Internal progress state representation */
type ProgressState = 'indeterminate' | 'complete' | 'loading';

/** Element type for Progress component */
type ProgressElement = React.ComponentRef<'div'>;

/** Element type for ProgressIndicator component */
type ProgressIndicatorElement = React.ComponentRef<'div'>;
```

## Validation and Error Handling

The Progress component includes built-in validation with console warnings:

- **Invalid max value**: Must be a positive number greater than 0. Defaults to 100 if invalid.
- **Invalid progress value**: Must be between 0 and max (inclusive) or null/undefined for indeterminate state. Defaults to null if invalid.
- **Default value label**: When no `getValueLabel` function is provided, defaults to percentage calculation (e.g., "65%" for value 65 of max 100).

## Usage Examples

**File Upload Progress:**

```typescript
function FileUploadProgress({ uploadProgress }: { uploadProgress: number | null }) {
  return (
    <Progress 
      value={uploadProgress} 
      max={100}
      getValueLabel={(value, max) => `${value} of ${max} percent uploaded`}
    >
      <ProgressIndicator 
        style={{ 
          transform: uploadProgress ? `translateX(-${100 - uploadProgress}%)` : 'translateX(-100%)',
          transition: 'transform 0.3s ease'
        }}
      />
    </Progress>
  );
}
```

**Multi-step Form Progress:**

```typescript
function FormProgress({ currentStep, totalSteps }: { currentStep: number; totalSteps: number }) {
  const progress = (currentStep / totalSteps) * 100;
  
  return (
    <Progress 
      value={progress} 
      max={100}
      getValueLabel={(value) => `Step ${currentStep} of ${totalSteps}`}
    >
      <ProgressIndicator 
        style={{ width: `${progress}%` }}
      />
    </Progress>
  );
}
```

**Loading State with Animation:**

```typescript
function LoadingProgress() {
  return (
    <Progress className="loading-progress">
      <ProgressIndicator className="loading-indicator" />
    </Progress>
  );
}

// CSS for indeterminate animation
const styles = `
  .loading-progress {
    overflow: hidden;
  }
  
  .loading-indicator {
    animation: loading 2s ease-in-out infinite;
  }
  
  @keyframes loading {
    0% { transform: translateX(-100%); }
    50% { transform: translateX(0%); }
    100% { transform: translateX(100%); }
  }
`;
```