# ProgressBar

Eine ProgressBar zeigt den Fortschritt eines laufenden Prozesses visuell in Form eines horizontalen Balkens an. Sie eignet sich sowohl für temporäre Prozesse als auch für Zustände mit konstantem Monitoring.

## Overview

# Playground

Verwende `<ProgressBar />`, um eine ProgressBar darzustellen.

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

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

---

# Mit Unit

Im Standard 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>
```

---

# 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**. Diese Status helfen insbesondere bei der
Darstellung von Speicherplatzauslastung, um Schwellenwerte visuell hervorzuheben
(z. B. Statuswechsel ab 80 % Auslastung zur Warning).

```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>
</>
```

---

# 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>
```


## Develop

# Properties

| Property | Type | Default | Description |
| --- | --- | --- | --- |
| `status` | `"info" \| "success" \| "warning" \| "danger"` | - | - |
| `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>>` | - | - |
| `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. |


## Guidelines

# Grundlagen

Eine ProgressBar zeigt den Fortschritt eines laufenden Prozesses visuell in Form
eines horizontalen Balkens an. Sie eignet sich sowohl für temporäre Prozesse
(z. B. Uploads) als auch für Zustände mit konstantem Monitoring, wie z. B. die
Auslastung von Speicherplatz.

## Best practices

Achte bei der Verwendung einer ProgressBar darauf, dass ...

- der Fortschritt eindeutig kommuniziert wird (z. B. 8 GB von 10 GB).
- bei der Darstellung von Speicherplatzauslastung Schwellenwerte visuell
  hervorgehoben werden (z. B. Statuswechsel ab 80 % Auslastung zur Warning).
- bei indeterminate Zuständen (z. B. unklarer Ladefortschritt) eine Alternative,
  wie zum Beispiel der
  [LoadingSpinner](/04-components/status/loading-spinner/overview), verwendet
  wird.
- bei statischen Anwendungen wie Speicherplatzauslastung regelmäßige
  Aktualisierung durch das System erfolgt, um Verlässlichkeit zu gewährleisten.

## Verwendung

Verwende eine ProgressBar, um ...

- Prozesse mit vorhersehbarer Dauer visuell zu begleiten (z. B. Datei-Uploads
  oder Installationen).
- Usern ein Gefühl für verbleibende Zeit oder verfügbare Kapazitäten zu geben.
- kontinuierlich überwachte Zustände darzustellen (z. B.
  Speicherplatzauslastung).
- kritische Zustände frühzeitig visuell hervorzuheben (z. B. durch Farbwechsel
  bei hoher Auslastung).
- in Dashboards platzsparend Informationen darzustellen.

