Skip to content
All components

Components

KPI

A KPI tile answers one question with one number. The figure is a count, grouped as 12,480 and counted up as it appears, or ready text such as 98.2% or 1.4 s. When the figure is compacted, exact holds the full value as a tooltip; a delta or a badge sits beside the label, and a spark draws the recent trend under the figure.

With a comparison

A number with what it is measured against, and a spark of the trend.

Open tickets

−36

1,284

Against last week

Kpi {
    label: "Open tickets".into(),
    figure: Figure::Count(1_284),
    delta: Some(Delta { by: -36, against: 1_320, fewer_is_better: true }),
    caption: Some("Against last week".into()),
    spark: Some(vec![9.0, 11.0, 10.0, 13.0, 12.0, 15.0, 14.0]),
    ..Default::default()
}

A row of tiles

Tiles say how it is going; at most eight on a screen.

Resolved today

+41

342

First reply

4 min

Median, last 24 hours

Spend this month

On budget

$8,420

out.push_str(r#"<div class="u-kpis">"#);
Kpi {
    label: "Resolved today".into(),
    figure: Figure::Count(342),
    delta: Some(Delta { by: 41, against: 301, fewer_is_better: false }),
    ..Default::default()
}.html(out);
Kpi {
    label: "First reply".into(),
    figure: Figure::Text("4 min".into()),
    caption: Some("Median, last 24 hours".into()),
    ..Default::default()
}.html(out);
Kpi {
    label: "Spend this month".into(),
    figure: Figure::Text("$8,420".into()),
    badge: Some(Badge { text: "On budget".into(), tone: Tone::Ok }),
    ..Default::default()
}.html(out);
out.push_str("</div>");

Compact figure

A large count is shortened; the exact value is its tooltip.

Rows synced

2.4M

Since the first sync

Kpi {
    label: "Rows synced".into(),
    figure: Figure::Text("2.4M".into()),
    exact: Some("2,418,903".into()),
    caption: Some("Since the first sync".into()),
    ..Default::default()
}

On the Mac

The same vocabulary drawn by Ocean UI's native face (egui on Metal), as the gallery's snapshot.

KPI drawn by Ocean UI's native face, darkKPI drawn by Ocean UI's native face, light

Use it

Web

use ocean_ui_core::{Delta, Figure, Kpi};
let delta = Some(Delta { by: -6, against: 134, fewer_is_better: true });
Kpi { label: "Open tickets".into(), figure: Figure::Count(128), delta, ..Default::default() }

Native

use ocean_ui_native::{Show, core::{Delta, Figure, Kpi}};
let delta = Some(Delta { by: 6, against: 24, fewer_is_better: false });
Kpi { label: "Commits".into(), figure: Figure::Count(12_480), delta, ..Default::default() }.show(ui);

Cargo feature tiles of ocean-ui-core, ocean-ui-web and ocean-ui-native; available since 2026-10-29.

In App UI, the kpis block draws it from YAML.

Props

NameTypeDefaultWhat
labelString—What the figure counts, in sentence case.
figureFigureCount(0)Figure::Count(n), a whole number grouped and counted up, or Figure::Text(s), ready words.
exactOption<String>NoneThe full value as a tooltip when the figure is compacted.
deltaOption<Delta>NoneThe change since the last period, beside the label.
badgeOption<Badge>NoneA short state beside the label.
captionOption<String>NoneOne line under the figure, such as the period it covers.
sparkOption<Vec<f32>>NoneRecent values drawn as a small line under the figure.

Accessibility

  • The tile is a section with its label as an h3, so it shows in the page's heading outline.
  • A count is written into the page as grouped text, so a screen reader reads the final number; the count-up does not run under reduced motion.
  • The spark is aria-hidden and the exact value is only a title tooltip, so put anything that matters in the caption or the delta.

Related

Markdown

The same page as Markdown, for an agent or a pull request.

Search

esc

Components

Blocks

Screens built from blocks

The Ocean app

Ocean Base console