# Progress _(no submodules)_ - progress.variants — `progressVariants` is the cva c… - [progress.variants](./progress.variants.md) — `progressVariants` is the cva config that powers the `` chassis component (paired with `progressIndicatorVari… - progress.variants — `progressVariants` is the cva c… - [progress.variants](./progress.variants.md) — `progressVariants` is the cva config that powers the `` chassis component (paired with `progressIndicatorVari… - progress.variants — `progressVariants` is the cva c… - [progress.variants](./progress.variants.md) — `progressVariants` is the cva config that powers the `` chassis component (paired with `progressIndicatorVari… - progress.variants — `progressVariants` is the cva c… - [progress.variants](./progress.variants.md) — `progressVariants` is the cva config that powers the `` chassis component (paired with `progressIndicatorVari… - [progress.variants](./progress.variants.md) — `progressVariants` is the cva config that powers the `` chassis component (paired with `progressIndicatorVari… ## Purpose `` is the chassis progress bar built on `@radix-ui/react-progress`. It supports both indeterminate (Radix's loading-state animation when `value === undefined`) and determinate (`value` is `0..max`, default `max=100`) modes. The chassis layers a `size` axis on top — `sm` (4px), `default` (8px), `lg` (12px) — while leaving width consumer-driven via `className` (typically `w-full` inside a card or form row). The accessible name comes from the consumer-supplied `aria-label` (typed as `TranslationKey`); when absent, the chassis falls back to the bundled `react-ui.progress.fallback` translation key so screen-readers always announce something meaningful. This avoids the common bug where developers ship a progress bar with no accessible name and screen-readers read out the percentage without any context. ## Features - Indeterminate mode when `value === undefined` (Radix runs its loading animation). - Determinate mode when `value` is a number `0..max`. - Three sizes via the `size` axis (`sm` / `default` / `lg`). - `aria-label` typed as `TranslationKey` — falls back to bundled `react-ui.progress.fallback` when undefined. - `motion-safe:transition-transform motion-reduce:transition-none` on the indicator so reduced-motion users see instant updates. - Forwards refs to the Radix Root. ## Usage: Basic Example ```tsx import { Progress } from "@suaveplan/react-ui"; export function UploadProgress({ percent }: { percent: number }) { return ; } ``` ## Usage: Advanced Example ```tsx import { Progress } from "@suaveplan/react-ui"; export function MultiStageUpload({ currentStage, totalStages, isLoading, }: { currentStage: number; totalStages: number; isLoading: boolean; }) { return ( ); } ``` ## API Reference ### `` `forwardRef<…, ProgressProps>` — Radix `Root` wrapper that renders an inner `Indicator` translated based on `value`. | Prop | Type | Default | Description | |---|---|---|---| | `value` | `number \| undefined` | `undefined` | When defined, determinate mode; when undefined, indeterminate mode. | | `max` | `number` | `100` | Forwarded to Radix as the upper bound for `value`. | | `size` | `"sm" \| "default" \| "lg"` | `"default"` | Bar height. | | `aria-label` | `TranslationKey \| undefined` | `react-ui.progress.fallback` | Accessible name. Falls back to bundled key. | | _Radix props_ | _Radix-typed_ | — | All `ProgressPrimitive.Root` props (except `aria-label` which the chassis overrides). | #### Errors The Progress component calls `useTranslation()` to resolve the `aria-label` translation key. It MUST render inside a `` / ``; otherwise `useTranslation` throws. ## Implementation Notes - When `value === undefined` the chassis passes `null` to Radix (matching Radix's API for indeterminate mode). Radix toggles its `data-state="indeterminate"` on the root and runs its built-in loading animation; consumers wanting a custom indeterminate animation override the indicator's `transform` via a `[&>*]:` arbitrary descendant. - The accessible-name fallback uses the bundled `react-ui.progress.fallback` key which all five locales translate. This guarantees the screen-reader announcement is meaningful even when consumers forget to supply their own label. - `motion-safe:transition-transform` only runs when the user has not requested reduced motion. Reduced-motion users see the indicator snap to its new position instantly — this is intentional, animated progress with reduced-motion can cause vestibular discomfort. - The chassis does NOT expose a `getValueLabel` prop (Radix supports it) because the chassis-supplied `aria-label` is sufficient for the common case; consumers wanting a percentage-readable label compose their own `{percent}%` next to the bar. - The chassis supports both indeterminate (loading) and determinate (`0..100`) modes from a single component because Radix already handles the state-machine internally; splitting them into two components would force consumers to refactor when the loading-known transition lands.