# Meter

A labelled bar for a bounded measurement, with normal, warning and danger tones and a usage variant.

Source page: https://sproutboat.com/ikada/components/meter

## Installation
```sh
npx shadcn@latest add https://sproutboat.com/ikada/r/meter.json
```
Or from the package: `import { Meter, UsageMeter } from "@sproutboat/ikada";`
## Usage
```tsx
import { Meter, UsageMeter } from "@/components/ikada/meter";

<Meter label="Requests" value={62} />
```
## Examples
### Tones
Normal, warning (amber) and danger (red). The fill grows over 250ms.
```tsx
<Meter label="Requests" value={42} />
<Meter label="Storage" value={85} tone="warning" />
<Meter label="Build minutes" value={100} tone="danger" />
```
### Usage against a plan limit
Amber from 80% and at 100%; red only when the platform is actually refusing work (blocked). The state is written out too.
```tsx
<UsageMeter label="Requests" used={860_000} limit={1_000_000} />
<UsageMeter label="Storage" used={4.4} limit={5} unit="GB" />
<UsageMeter label="Deploys" used={100} limit={100} blocked />
<UsageMeter label="Sprouts" used={4} limit={null} />
```
### Without a visible label
Pass aria-label, and valueLabel={null} to drop the number as well.
```tsx
<Meter aria-label="wren CPU" value={64} valueLabel={null} />
```
## Props
### MeterProps
Also takes every prop of `Omit<ComponentProps<typeof BaseMeter.Root>, "className" | "children" | "locale">`.
| Prop | Type | Description |
| --- | --- | --- |
| className? | `string` | Classes merged onto the root element, after ikada's own. |
| locale? | `string` | Number-formatting locale; defaults to the `LocaleProvider` value, else `en`. |
| label? | `ReactNode` | Visible label above the bar. Without one, pass `aria-label`. |
| tone? | `MeterTone` | Fill colour: normal, warning (amber) or danger (red). Default normal. |
| valueLabel? | `ReactNode` | Right of the label; defaults to the formatted value. |
| style? | `CSSProperties \| ((state: MeterRootState) => CSSProperties)` | Style applied to the element, or a function that returns a style object based on the component's state. |
| render? | `ReactElement<unknown, string \| JSXElementConstructor<any>> \| ComponentRenderFn<HTMLProps, MeterRootState>` | Allows you to replace the component's HTML element with a different tag, or compose it with another component. Accepts a `ReactElement` or a function that returns the element to render. |
### UsageMeterProps
Also takes every prop of `Omit<MeterProps, "value" | "max" | "min" | "tone" | "valueLabel" | "format">`.
| Prop | Type | Description |
| --- | --- | --- |
| used | `number` | Amount used so far, in the same unit as the limit. |
| limit | `number \| null` | `null` is unlimited: the bar is replaced by the number alone. |
| unit? | `string` | Unit suffix, e.g. "GB" or "requests". |
| warnAt? | `number` | Near-limit threshold as a fraction. Default 0.8. |
| blocked? | `boolean` | The platform is actually refusing work (writes rejected, deploys paused). Only then is the meter red. Reaching the limit without being blocked stays amber. Default `false`. |
| formatValue? | `((n: number) => string)` | Defaults to compact units in the resolved locale: 860K, 1M, 4.4. |
| className? | `string` | Classes merged onto the root element, after ikada's own. |
| style? | `CSSProperties \| ((state: MeterRootState) => CSSProperties)` | Style applied to the element, or a function that returns a style object based on the component's state. |
| label? | `ReactNode` | Visible label above the bar. Without one, pass `aria-label`. |
| render? | `ReactElement<unknown, string \| JSXElementConstructor<any>> \| ComponentRenderFn<HTMLProps, MeterRootState>` | Allows you to replace the component's HTML element with a different tag, or compose it with another component. Accepts a `ReactElement` or a function that returns the element to render. |
| locale? | `string` | Number-formatting locale; defaults to the `LocaleProvider` value, else `en`. |
Source: https://github.com/baronunread/ikada/blob/main/src/components/meter.tsx
