# ProgressBar

Eine ProgressBar zeigt den Fortschritt eines laufenden Prozesses als horizontalen Balken an.

```tsx
import {
  Label,
  ProgressBar,
} from "@mittwald/flow-react-components";

<ProgressBar value={50}>
  <Label>Speicher</Label>
</ProgressBar>
```

---

# Best Practices

- Kommuniziere den Fortschritt eindeutig. Ein Beispiel ist „8 GB von 10 GB".
- Kombiniere die Status-Farben gezielt, um Zustände hervorzuheben. Wechsle etwa
  bei hoher Auslastung auf Warning oder Danger.
- Nutze bei unbestimmtem Fortschritt eine Alternative wie den
  [LoadingSpinner](/04-components/status/loading-spinner).
- Aktualisiere dauerhaft angezeigte ProgressBars regelmäßig. Das erhält die
  Verlässlichkeit, etwa bei der Speicherplatzauslastung.

---

# Sizes

ProgressBars sind in drei verschiedenen Größen verfügbar: **Small**, **Medium**
und **Large**.

Die mittlere Größe **Medium** ist Standard und wird am häufigsten verwendet. Die
verschiedenen Größen eignen sich gut, um eine visuelle Hierarchie innerhalb der
Seite zu erzeugen. So kann die größte Variante **Large** sehr gut alleinstehend
eingesetzt werden, wenn die ProgressBar besondere Aufmerksamkeit auf sich ziehen
soll.

```tsx
import {
  Label,
  ProgressBar,
} from "@mittwald/flow-react-components";

<>
  <ProgressBar size="s" value={50}>
    <Label>Größe S</Label>
  </ProgressBar>
  <ProgressBar size="m" value={50}>
    <Label>Größe M</Label>
  </ProgressBar>
  <ProgressBar size="l" value={50}>
    <Label>Größe L</Label>
  </ProgressBar>
</>
```

---

# Status

Je nach Anwendungsfall stehen vier Status-Farben zur Auswahl: **Success**,
**Info**, **Warning** und **Danger**. Wechsle bei einer hohen Auslastung zum
Beispiel auf Warning oder Danger, um den Zustand hervorzuheben.

```tsx
import { ProgressBar } from "@mittwald/flow-react-components";

<>
  <ProgressBar value={100} status="success">
    Success
  </ProgressBar>
  <ProgressBar value={50} status="info">
    Info
  </ProgressBar>
  <ProgressBar value={70} status="warning">
    Warning
  </ProgressBar>
  <ProgressBar value={90} status="danger">
    Danger
  </ProgressBar>
</>
```

---

# Mit Unit

Im Default wird die ProgressBar immer mit Prozentangabe angezeigt. Über das
Property `formatOptions` können aber auch andere Einheiten gewählt werden (s.
[Intl.NumberFormat](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat)).

## Gigabyte

```tsx
import {
  Label,
  ProgressBar,
} from "@mittwald/flow-react-components";

<ProgressBar
  value={500}
  maxValue={1000}
  minValue={0}
  formatOptions={{ style: "unit", unit: "gigabyte" }}
>
  <Label>Speicher</Label>
</ProgressBar>
```

## Dezimalzahl

```tsx
import {
  Label,
  ProgressBar,
} from "@mittwald/flow-react-components";

<ProgressBar
  value={500}
  maxValue={1000}
  minValue={0}
  formatOptions={{ style: "decimal" }}
>
  <Label>Stückzahl</Label>
</ProgressBar>
```

---

# Mit Max Value

Der maximale Wert der ProgressBar lässt sich individuell festlegen, je nachdem,
was dargestellt werden soll. Standardmäßig beträgt dieser Wert 100 %.

```tsx
import {
  Label,
  ProgressBar,
} from "@mittwald/flow-react-components";

<ProgressBar
  showMaxValue
  value={500}
  maxValue={1000}
  minValue={0}
  formatOptions={{ style: "unit", unit: "gigabyte" }}
>
  <Label>Speicher</Label>
</ProgressBar>
```

---

# Segmente

Die Anzeige der ProgressBar kann über das `segments` Property um einzelne
Abschnitte ergänzt werden. Der `value` ergibt sich in diesem Fall aus der Summe
der Werte der einzelnen Segmente. Um die einzelnen Werte näher zu erläutern,
wird automatisch eine Legende angezeigt. Über das `showLegend` Property kann
diese ein- und ausgeblendet werden.

Die Farben der Segmente werden automatisch festgelegt, können aber über das
`color` Property überschrieben werden. Beim Überschreiben muss darauf geachtet
werden, dass nebeneinanderliegende Farben weiterhin einen ausreichenden Kontrast
zueinander haben.

```tsx
import {
  Label,
  ProgressBar,
} from "@mittwald/flow-react-components";

<ProgressBar
  maxValue={1000}
  size="l"
  showMaxValue
  formatOptions={{ style: "unit", unit: "gigabyte" }}
  segments={[
    { value: 280, title: "E-Mails" },
    {
      value: 170,
      title: "Datenbanken",
    },
    {
      value: 110,
      title: "Backups",
    },
  ]}
>
  <Label>Speicher</Label>
</ProgressBar>
```

---

# Properties

| Property | Type | Default | Description |
| --- | --- | --- | --- |
| `status` | `"info" \| "success" \| "warning" \| "danger"` | - | The status the progress bar is colored by. |
| `showMaxValue` | `boolean` | - | Whether the max value should be displayed. |
| `size` | `"s" \| "m" \| "l"` | `"m"` | The size variant of the progress bar. |
| `segments` | `{ value: number; title: string; color?: CategoricalWithCustomColor; valueText?: string; }[]` | - | Divides the fill of the progress bar into segments |
| `showLegend` | `boolean` | `: true` | Whether the legend component is shown when segments are used. |
| `id` | `string` | - | The element's unique identifier. See [MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/id). |
| `translate` | `"yes" \| "no"` | - | - |
| `className` | `ClassNameOrFunction<ProgressBarRenderProps>` | `'react-aria-ProgressBar'` | The CSS [className](https://developer.mozilla.org/en-US/docs/Web/API/Element/className) for the element. A function may be provided to compute the class based on component state. |
| `style` | `StyleOrFunction<TooltipRenderProps>` | - | The inline [style](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/style) for the element. A function may be provided to compute the style based on component state. |
| `render` | `DOMRenderFunction<"div", TooltipRenderProps>` | - | Overrides the default DOM element with a custom render function. This allows rendering existing components with built-in styles and behaviors such as router links, animation libraries, and pre-styled components. Requirements: - You must render the expected element type (e.g. if `<button>` is expected, you cannot render an `<a>`). - Only a single root DOM element can be rendered (no fragments). - You must pass through props and ref to the underlying DOM element, merging with your own prop as appropriate. |
| `dir` | `string` | - | - |
| `lang` | `string` | - | - |
| `hidden` | `boolean` | - | - |
| `inert` | `boolean` | - | - |
| `minValue` | `number` | `0` | The smallest value allowed for the input. |
| `maxValue` | `number` | `100` | The largest value allowed for the input. |
| `value` | `number` | `0` | The current value (controlled). |
| `slot` | `string` | - | A slot name for the component. Slots allow the component to receive props from a parent component. An explicit `null` value indicates that the local props completely override all props received from a parent. |
| `formatOptions` | `NumberFormatOptions` | `{ style: 'percent' }` | The display format of the value label. |
| `isIndeterminate` | `boolean` | - | Whether presentation is indeterminate when progress isn't known. |
| `valueLabel` | `ReactNode` | - | The content to display as the value's label (e.g. 1 of 4). |
| `children` | `ReactNode` | - | - |
| `wrapWith` | `ReactElement<unknown, string \| JSXElementConstructor<any>>` | - | A React element the component is wrapped with. The element is cloned and receives the component as its only child — useful to render the component inside a link, a tooltip trigger or any other wrapper without changing the surrounding markup. |
| `ref` | `Ref<HTMLSpanElement>` | - | Allows getting a ref to the component instance. Once the component unmounts, React will set `ref.current` to `null` (or call the ref with `null` if you passed a callback ref). @see [React Docs](https://react.dev/learn/referencing-values-with-refs#refs-and-the-dom) |
| `key` | `Key` | - | - |

### Events

| Property | Type | Default | Description |
| --- | --- | --- | --- |
| `onClick` | `MouseEventHandler<HTMLDivElement>` | - | - |
| `onClickCapture` | `MouseEventHandler<HTMLDivElement>` | - | - |
| `onAuxClick` | `MouseEventHandler<HTMLDivElement>` | - | - |
| `onAuxClickCapture` | `MouseEventHandler<HTMLDivElement>` | - | - |
| `onContextMenu` | `MouseEventHandler<HTMLDivElement>` | - | - |
| `onContextMenuCapture` | `MouseEventHandler<HTMLDivElement>` | - | - |
| `onDoubleClick` | `MouseEventHandler<HTMLDivElement>` | - | - |
| `onDoubleClickCapture` | `MouseEventHandler<HTMLDivElement>` | - | - |
| `onMouseDown` | `MouseEventHandler<HTMLDivElement>` | - | - |
| `onMouseDownCapture` | `MouseEventHandler<HTMLDivElement>` | - | - |
| `onMouseEnter` | `MouseEventHandler<HTMLDivElement>` | - | - |
| `onMouseLeave` | `MouseEventHandler<HTMLDivElement>` | - | - |
| `onMouseMove` | `MouseEventHandler<HTMLDivElement>` | - | - |
| `onMouseMoveCapture` | `MouseEventHandler<HTMLDivElement>` | - | - |
| `onMouseOut` | `MouseEventHandler<HTMLDivElement>` | - | - |
| `onMouseOutCapture` | `MouseEventHandler<HTMLDivElement>` | - | - |
| `onMouseOver` | `MouseEventHandler<HTMLDivElement>` | - | - |
| `onMouseOverCapture` | `MouseEventHandler<HTMLDivElement>` | - | - |
| `onMouseUp` | `MouseEventHandler<HTMLDivElement>` | - | - |
| `onMouseUpCapture` | `MouseEventHandler<HTMLDivElement>` | - | - |
| `onTouchCancel` | `TouchEventHandler<HTMLDivElement>` | - | - |
| `onTouchCancelCapture` | `TouchEventHandler<HTMLDivElement>` | - | - |
| `onTouchEnd` | `TouchEventHandler<HTMLDivElement>` | - | - |
| `onTouchEndCapture` | `TouchEventHandler<HTMLDivElement>` | - | - |
| `onTouchMove` | `TouchEventHandler<HTMLDivElement>` | - | - |
| `onTouchMoveCapture` | `TouchEventHandler<HTMLDivElement>` | - | - |
| `onTouchStart` | `TouchEventHandler<HTMLDivElement>` | - | - |
| `onTouchStartCapture` | `TouchEventHandler<HTMLDivElement>` | - | - |
| `onPointerDown` | `PointerEventHandler<HTMLDivElement>` | - | - |
| `onPointerDownCapture` | `PointerEventHandler<HTMLDivElement>` | - | - |
| `onPointerMove` | `PointerEventHandler<HTMLDivElement>` | - | - |
| `onPointerMoveCapture` | `PointerEventHandler<HTMLDivElement>` | - | - |
| `onPointerUp` | `PointerEventHandler<HTMLDivElement>` | - | - |
| `onPointerUpCapture` | `PointerEventHandler<HTMLDivElement>` | - | - |
| `onPointerCancel` | `PointerEventHandler<HTMLDivElement>` | - | - |
| `onPointerCancelCapture` | `PointerEventHandler<HTMLDivElement>` | - | - |
| `onPointerEnter` | `PointerEventHandler<HTMLDivElement>` | - | - |
| `onPointerLeave` | `PointerEventHandler<HTMLDivElement>` | - | - |
| `onPointerOver` | `PointerEventHandler<HTMLDivElement>` | - | - |
| `onPointerOverCapture` | `PointerEventHandler<HTMLDivElement>` | - | - |
| `onPointerOut` | `PointerEventHandler<HTMLDivElement>` | - | - |
| `onPointerOutCapture` | `PointerEventHandler<HTMLDivElement>` | - | - |
| `onGotPointerCapture` | `PointerEventHandler<HTMLDivElement>` | - | - |
| `onGotPointerCaptureCapture` | `PointerEventHandler<HTMLDivElement>` | - | - |
| `onLostPointerCapture` | `PointerEventHandler<HTMLDivElement>` | - | - |
| `onLostPointerCaptureCapture` | `PointerEventHandler<HTMLDivElement>` | - | - |
| `onScroll` | `UIEventHandler<HTMLDivElement>` | - | - |
| `onScrollCapture` | `UIEventHandler<HTMLDivElement>` | - | - |
| `onWheel` | `WheelEventHandler<HTMLDivElement>` | - | - |
| `onWheelCapture` | `WheelEventHandler<HTMLDivElement>` | - | - |
| `onAnimationStart` | `AnimationEventHandler<HTMLDivElement>` | - | - |
| `onAnimationStartCapture` | `AnimationEventHandler<HTMLDivElement>` | - | - |
| `onAnimationEnd` | `AnimationEventHandler<HTMLDivElement>` | - | - |
| `onAnimationEndCapture` | `AnimationEventHandler<HTMLDivElement>` | - | - |
| `onAnimationIteration` | `AnimationEventHandler<HTMLDivElement>` | - | - |
| `onAnimationIterationCapture` | `AnimationEventHandler<HTMLDivElement>` | - | - |
| `onTransitionCancel` | `TransitionEventHandler<HTMLDivElement>` | - | - |
| `onTransitionCancelCapture` | `TransitionEventHandler<HTMLDivElement>` | - | - |
| `onTransitionEnd` | `TransitionEventHandler<HTMLDivElement>` | - | - |
| `onTransitionEndCapture` | `TransitionEventHandler<HTMLDivElement>` | - | - |
| `onTransitionRun` | `TransitionEventHandler<HTMLDivElement>` | - | - |
| `onTransitionRunCapture` | `TransitionEventHandler<HTMLDivElement>` | - | - |
| `onTransitionStart` | `TransitionEventHandler<HTMLDivElement>` | - | - |
| `onTransitionStartCapture` | `TransitionEventHandler<HTMLDivElement>` | - | - |

### Accessibility

| Property | Type | Default | Description |
| --- | --- | --- | --- |
| `aria-label` | `string` | - | Defines a string value that labels the current element. |
| `aria-labelledby` | `string` | - | Identifies the element (or elements) that labels the current element. |
| `aria-describedby` | `string` | - | Identifies the element (or elements) that describes the object. |
| `aria-details` | `string` | - | Identifies the element (or elements) that provide a detailed, extended description for the object. |

