# Progress

Displays an indicator showing the completion progress of a task, typically as a
slim passive progress bar.

Use Progress for uploads, background jobs, onboarding steps, and other cases
where the user should understand status without directly interacting with the
bar itself.

## Import

```ts
import { ProgressComponent } from '@edsis/component/progress';
```

For the visible label and slider-driven examples below, also import the existing
label and slider entrypoints:

```ts
import { LabelComponent } from '@edsis/component/label';
import { SliderComponent } from '@edsis/component/slider';
```

## Basic usage

Provide an accessible name directly when the bar stands on its own.

```html
<ProgressBar [value]="33" aria-label="Upload progress" class="w-full max-w-sm" />
```

## Common patterns

### Visible label row

The current shadcn Radix docs place Progress inside a Field layout with a
visible label and percentage. In Angular, keep the visible copy outside the
bar and connect it with `aria-labelledby`.

```html
<label id="progress-upload-label" class="mb-2 flex items-center gap-3">
  <span>Upload progress</span>
  <span class="ms-auto text-muted-foreground">66%</span>
</label>

<ProgressBar [value]="66" aria-labelledby="progress-upload-label" class="w-full max-w-sm" />
```

Use `aria-labelledby` here instead of `label[for]`, because `ProgressBar` is a
custom element with `role="progressbar"`, not a native labelable form control.

### Controlled progress

Keep the progress bar passive and let surrounding controls own the interaction.
The built-in range slider directive works well for the same pattern shown in the
upstream docs.

```ts
const controlledValue = signal(50);

<Label id="progress-controlled-label" class="mb-2 flex items-center gap-3">
  <span>Upload progress</span>
  <span class="ms-auto text-muted-foreground">{{ controlledValue() }}%</span>
</Label>

<ProgressBar [value]="controlledValue()" aria-labelledby="progress-controlled-label" class="w-full" />

<Label for="progress-controlled-slider" class="mb-2 block">Adjust progress</Label>
<input
  id="progress-controlled-slider"
  type="range"
  Slider
  min="0"
  max="100"
  step="1"
  [value]="controlledValue()"
  (input)="onControlledInput($event)" />
```

### Indeterminate loading

Switch to `indeterminate` when work is running but no stable percentage is
available yet.

```html
<ProgressBar [indeterminate]="true" aria-label="Loading deployment" class="w-full max-w-sm" />
```

### RTL

Follow the upstream guidance by setting `dir="rtl"` on the surrounding
container and flipping the bar with `rtl:rotate-180`.

```html
<section dir="rtl" lang="ar" class="w-full max-w-sm text-right">
  <label id="progress-rtl-label" class="mb-2 flex items-center gap-3">
    <span>تقدم الرفع</span>
    <span class="ms-auto text-muted-foreground">٦٦%</span>
  </label>

  <ProgressBar [value]="66" aria-labelledby="progress-rtl-label" class="w-full rtl:rotate-180" />
</section>
```

## API reference

| Input             | Type             | Default |
| ----------------- | ---------------- | ------- |
| `value`           | `number \| null` | `0`     |
| `max`             | `number`         | `100`   |
| `indeterminate`   | `boolean`        | `false` |
| `aria-label`      | `string \| null` | `null`  |
| `aria-labelledby` | `string \| null` | `null`  |
| `class`           | `string`         | `''`    |

Native host attributes such as `id`, `dir`, and `data-*` still pass through to
the rendered custom element and can be used for surrounding composition.

## Styling and theming

Tokens consumed:

- `--secondary` for the track.
- `--primary` for the indicator.

Use the `class` input for width and layout utilities such as `w-full`,
`max-w-sm`, or `rtl:rotate-180`. Indeterminate state is animated via a CSS
keyframe that respects `prefers-reduced-motion`.

## Accessibility

- Host is `role="progressbar"`.
- Determinate mode sets `aria-valuemin="0"`, `aria-valuemax="max"`, and
  `aria-valuenow="clamped value"`.
- Indeterminate mode omits `aria-valuenow` and adds `data-state="indeterminate"`.
- Always provide an accessible name via `aria-label` or `aria-labelledby`.
- If visible label text already exists on the page, connect it with
  `aria-labelledby` instead of relying on native label semantics.

## Keyboard interactions

Progress is passive and not focusable by default. Any keyboard interaction
belongs to surrounding controls such as the slider used in the controlled
example.

## Angular notes

- Keep Progress focused on status display. Do not nest buttons or other
  interactive controls inside the bar.
- Drive determinate state from signals, reactive forms, or any other existing
  Angular state source.
- For visible label rows, `Label` is a good lightweight companion, but plain
  text with the right ARIA wiring works too.

## Source parity

This Angular implementation follows the shadcn Radix progress examples while
translating `Field` and `FieldLabel` to ordinary Angular markup plus explicit
ARIA wiring. The controlled example reuses the existing range slider directive,
and the RTL pattern matches the upstream `rtl:rotate-180` approach.
