Donut

A ring with rounded caps and 2px gaps, the total in the center; ShareBar is the same split in one pill.

View source
$183.70Total spend
  • gpt-5$84.2046%
  • claude-sonnet-4-5$61.4033%
  • gpt-5-mini$22.8012%
  • claude-haiku-4-5$14.108%
  • gpt-4.1-nano$1.201%
Spend by model
SliceValueShare
gpt-5$84.2045.8%
claude-sonnet-4-5$61.4033.4%
gpt-5-mini$22.8012.4%
claude-haiku-4-5$14.107.7%
gpt-4.1-nano$1.200.7%
import { Donut, ShareBar } from "@logicplanes/kaeso-ui";

Props

  • aria-label
    string

    The chart's accessible name ("Requests by model").

  • empty
    boolean

    Shows the empty state (emptyText) in place of the data. By default it shows when every value is 0.

  • emptyText
    ReactNode

    What the empty state says. Defaults to "No data for this period" in the provider's language.

  • error
    ReactNode

    The data failed to load: the chart keeps its height, says so quietly and offers Try again. Errors are toasts, so the value isn't shown; toast the message where the request fails.

  • formatValue
    ((v: number) => string) = (v) => formatNumber(v)

    Formats the total in the center and the values in the legend. Defaults to formatNumber.

  • loading
    boolean

    The data is loading: the chart keeps its height and shows a quiet loading bar.

  • onRetry
    (() => void)

    Called when Try again is pressed after error; without it, the button doesn't show.

  • size
    "md" | "sm" | "lg" = md

    The ring's diameter: sm 140px, md 160px (default) or lg 180px.

  • slices
    Slice[]

    The parts of the whole, each with an id, a label, a value and an optional color. Slices under 2% are grouped as Other when there are two or more.

  • total
    ReactNode

    Replaces the total in the center, which is otherwise the sum of the slices written with formatValue.

  • totalLabel
    ReactNode

    The word under the total. Defaults to "Total" in the provider's language.