Initial Commit
This commit is contained in:
@@ -0,0 +1,94 @@
|
||||
# Progress
|
||||
|
||||
<!-- begin:auto-docs -->
|
||||
_(no submodules)_
|
||||
<!-- end:auto-docs --> - progress.variants — `progressVariants` is the cva c…
|
||||
- [progress.variants](./progress.variants.md) — `progressVariants` is the cva config that powers the `<Progress>` 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 `<Progress>` 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 `<Progress>` 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 `<Progress>` chassis component (paired with `progressIndicatorVari…
|
||||
- [progress.variants](./progress.variants.md) — `progressVariants` is the cva config that powers the `<Progress>` chassis component (paired with `progressIndicatorVari…
|
||||
|
||||
## Purpose
|
||||
|
||||
`<Progress>` 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 <Progress value={percent} />;
|
||||
}
|
||||
```
|
||||
|
||||
## Usage: Advanced Example
|
||||
|
||||
```tsx
|
||||
import { Progress } from "@suaveplan/react-ui";
|
||||
|
||||
export function MultiStageUpload({
|
||||
currentStage,
|
||||
totalStages,
|
||||
isLoading,
|
||||
}: {
|
||||
currentStage: number;
|
||||
totalStages: number;
|
||||
isLoading: boolean;
|
||||
}) {
|
||||
return (
|
||||
<Progress
|
||||
size="lg"
|
||||
value={isLoading ? undefined : (currentStage / totalStages) * 100}
|
||||
aria-label="react-ui.loading"
|
||||
className="w-64"
|
||||
/>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
## API Reference
|
||||
|
||||
### `<Progress>`
|
||||
|
||||
`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 `<TranslationProvider>` / `<ReactUiProvider>`; 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 `<span>{percent}%</span>` 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.
|
||||
Reference in New Issue
Block a user