Skip to content
Brok UI

Loading…

No results

Meters

Open source

Single-value readouts of a fraction of a whole — an arc gauge, a circular progress ring, linear/radial usage readouts and a liquid-fill gauge.

Version
v2.1.3
Stability
stable
License
MIT
Related
Gauge
Circular Progress
Usage Meter
Liquid Chart
4 of 5

Usage Gauge — A radial usage meter built on the gauge primitive: a semicircular used/total readout or a full-ring percentage with an optional caption.

Preview

12,000 / 32,000 Storage

Resets in 12 days

Variant
previews.components.usage-gauge.default.blade.php Blade
<div class="w-full flex flex-wrap items-end justify-center gap-8">
    <x-ui.usage-gauge :used="12000" :total="32000" label="Storage" variant="semi" />
    <x-ui.usage-gauge :used="6800" :total="10000" label="Monthly quota" variant="arc" caption="Resets in 12 days" />
</div>
Semi Current
Arc Current

Installation

terminal
php artisan ui:add usage-gauge

Registry contract

php artisan ui:add usage-gauge writes only the files below. The CLI validates each file hash before writing and asks before it replaces a local change, unless you pass --force.

  • blade resources/views/components/ui/usage-gauge.blade.php
Registry dependencies
gauge
Packages
composer: jml/brok:^0.2

Use with AI

A brief for your coding agent: install command, usage, props, guidance and the rules. Copy it, or open a prompt about this component in an assistant.

usage-gauge.md
# Brok UI: Usage Gauge (`usage-gauge`)

A radial usage meter built on the gauge primitive: a semicircular used/total readout or a full-ring percentage with an optional caption.

Brok UI is a Laravel Blade component registry. Installed components are plain Blade files the app owns.

## Install

```bash
php artisan ui:add usage-gauge
```

## Usage

```blade
<div class="w-full flex flex-wrap items-end justify-center gap-8">
    <x-ui.usage-gauge :used="12000" :total="32000" label="Storage" variant="semi" />
    <x-ui.usage-gauge :used="6800" :total="10000" label="Monthly quota" variant="arc" caption="Resets in 12 days" />
</div>
```

## Props

- `used` (int, default `18`) — Amount currently used.
- `total` (int, default `24`) — Total capacity used is measured against.
- `label` (string, default `Usage`) — Accessible name for the underlying gauge, and the caption shown under the semi variant's readout.
- `caption` (mixed|null, default `null`) — Optional small caption rendered under the gauge in either variant.
- `variant` (semi|arc, default `semi`) — semi shows a used/total readout under a half-ring arc; arc centres a percentage inside a full ring.

## Use when

- Use when trend, distribution, flow, intensity, or relationship questions are easier to answer visually than in raw numbers.
- Showing a used/total quantity (seats, licences, storage, quota) as a radial dial that warns as it nears its ceiling.
- Wanting the threshold colour (comfortable, tight, near-limit) computed automatically from the ratio instead of set by hand.

## Avoid when

- Do not use a chart when users mainly need exact lookup or when a single metric would be clearer as text or a stat.
- A horizontal layout fits the surrounding UI better; use usage-meter instead.
- The value has no meaningful ceiling to warn against; use gauge or circular-progress directly instead.

## Anti-patterns

- Decorative charts without a meaningful question

## Rules

- Use the `<brok:usage-gauge>` tag (or `<x-ui.usage-gauge>`) in Blade; do not rewrite the component.
- Prefer the documented props and variants over utility-class overrides; when a utility must win, use the `!` important modifier.
- Use semantic design tokens (`bg-primary`, `text-muted-foreground`), never raw colour utilities.
- Keep the `data-slot` attributes; they are the styling and test hooks.

## Links

- Docs: https://brokui.dev/docs/components/usage-gauge
- Registry JSON (files, props, contract): https://brokui.dev/r/open/usage-gauge.json

Working in Claude Code, Cursor or Codex? Give the agent the whole registry through the MCP server or the Brok UI skill.

API

manifest knowledge + registry-derived coverage

Props

Props accepted by this component: name, type, default value and description.
Prop Type Default Description
used int 18 Amount currently used.
total int 24 Total capacity used is measured against.
label string Usage Accessible name for the underlying gauge, and the caption shown under the semi variant's readout.
caption mixed | null null Optional small caption rendered under the gauge in either variant.
variant semi | arc semi semi shows a used/total readout under a half-ring arc; arc centres a percentage inside a full ring.

Slots

  • default — Unused; the gauge renders from props only.

Data slots

Stable hooks for CSS overrides and browser tests.

usage-gauge

Behavior

  • Computes the used/total ratio and colours the arc primary, warning, or destructive as the ratio crosses shared thresholds from the usage-meter recipe, so usage-gauge and usage-meter never disagree on where "warning" starts.
  • Composes gauge, suppressing its built-in value readout and overlaying its own percentage or used/total text.
  • arc adds an optional caption line below the ring; semi always shows the used/total pair below the arc.
  • Declares registry capability flags: a11y, responsive, rtl, darkMode, localized, reducedMotion.

Guidance

Chart and visual analytics

Reveal a visual trend, distribution, flow, or relationship.

Use when

  • Use when trend, distribution, flow, intensity, or relationship questions are easier to answer visually than in raw numbers.
  • Showing a used/total quantity (seats, licences, storage, quota) as a radial dial that warns as it nears its ceiling.
  • Wanting the threshold colour (comfortable, tight, near-limit) computed automatically from the ratio instead of set by hand.

Avoid when

  • Do not use a chart when users mainly need exact lookup or when a single metric would be clearer as text or a stat.
  • A horizontal layout fits the surrounding UI better; use usage-meter instead.
  • The value has no meaningful ceiling to warn against; use gauge or circular-progress directly instead.

Use instead

  • Table for exact lookup
  • Stat for a single value

Anti-patterns

  • Decorative charts without a meaningful question
Anatomy
root
Theming hooks
usage-meter

Accessibility

WCAG 2.2 AA Keyboard focus-visible RTL-ready Localized labels Dark mode
Keyboard
No component-owned keyboard interaction; native element behavior applies.
Focus
none
  • Composes gauge, which sets aria-label from label on the underlying role="meter" element even though its own visual readout is hidden.
  • The threshold colour is reinforced by the visible used/total or percentage text, never conveyed by colour alone.
  • Semantic HTML and a stable data-slot attribute for styling and scripting hooks.
  • Focus-visible rings use the ring token, so keyboard focus is always visible.
  • Disabled and invalid states are conveyed to assistive tech, not by color alone.
  • Targets WCAG 2.2 AA; verify contrast in light, dark, admin and customer surfaces in the preview.
  • Labels go through __() and layout uses logical properties (ms-*, text-start), so it mirrors under dir="rtl" — flip the preview to RTL to confirm.
  • Dark mode uses the same semantic tokens under the dark class; high contrast follows forced-color system tokens.

Livewire

Safe

Livewire can update this component through forwarded wire:* attributes.

Source

The exact, editable file ui:add writes into your app. Previews render this same code; there are no preview-only components.

resources/views/components/ui/usage-gauge.blade.php Blade
@props([
    'used' => 18,
    'total' => 24,
    'label' => 'Usage',
    'caption' => null,
    'variant' => 'semi',
])

@php
    $styles = require base_path(config('ui.component_path', 'resources/views/components/ui').'/_styles.php');
    $variant = $styles['normalizeVariant']($variant);
    $used = max(0, (int) $used);
    $total = max(1, (int) $total);
    $ratio = min(1, $used / $total);
    $percent = (int) round($ratio * 100);

    // Threshold colour: comfortable → primary, tight → warning, near-limit →
    // destructive. Floors come from the usage-meter recipe so usage-gauge and
    // usage-meter can never drift apart on where "warning" starts.
    $thresholds = $styles['usage-meter']['thresholds'];
    $color = $ratio >= $thresholds['destructive'] ? 'destructive' : ($ratio >= $thresholds['warning'] ? 'warning' : 'primary');

    $variant = in_array($variant, ['semi', 'arc'], true) ? $variant : 'semi';

    $percentClass = match ($color) {
        'warning' => 'text-warning',
        'destructive' => 'text-destructive',
        default => 'text-foreground',
    };
@endphp

{{--
    Usage gauge — a radial usage meter built on <x-ui.gauge>. The gauge owns the
    role="meter" semantics and value text; we suppress its built-in readout and
    overlay our own. Two shapes via `variant`: `semi` shows a used/total readout
    under the arc (e.g. seats or licences used); `arc` centres a percentage inside
    a full ring (e.g. storage or monthly quota) and accepts an optional `caption`.
    Colour steps primary → warning → destructive by threshold.
--}}
<div
    data-slot="usage-gauge"
    {{ $attributes->merge(['class' => 'inline-flex flex-col items-center gap-1 text-foreground']) }}
>
    @if ($variant === 'arc')
        <div class="relative inline-flex items-center justify-center">
            <x-ui.gauge
                :value="$percent"
                :max="100"
                variant="arc"
                :show-value="false"
                :color="$color"
                :aria-label="__($label)"
            />
            <div class="pointer-events-none absolute inset-0 flex flex-col items-center justify-center" aria-hidden="true">
                <span class="text-2xl font-semibold leading-none tabular-nums {{ $percentClass }}">{{ $percent }}%</span>
                <span class="text-xs text-muted-foreground">{{ __('used') }}</span>
            </div>
        </div>
        @if ($caption !== null)
            <p class="text-xs text-muted-foreground">{{ __($caption) }}</p>
        @endif
    @else
        <x-ui.gauge
            :value="$percent"
            :max="100"
            variant="semi"
            :show-value="false"
            :color="$color"
            :aria-label="__($label)"
        />
        <div class="-mt-1 flex flex-col items-center">
            <span class="text-sm font-medium tabular-nums">{{ number_format($used) }} / {{ number_format($total) }}</span>
            <span class="text-xs text-muted-foreground">{{ __($label) }}</span>
        </div>
        @if ($caption !== null)
            <p class="text-xs text-muted-foreground">{{ __($caption) }}</p>
        @endif
    @endif
</div>

Ownership & lifecycle

Owner, release state, review evidence and adoption for this item.
Owner
Platform UI (@JoshJML)
Current version
2.1.3
Status
Stable
License
open
Accessibility reviewed
No review date recorded
Last breaking change
No date recorded
Deprecation
Not deprecated
Contract
v6
Foundation
≥ 1.0.0