import "./progress.css"; import type * as React from "react"; import { useRender } from "@base-ui/react/use-render"; import { type StyleProps } from "./style_props"; export type ProgressShape = "bar" | "ring"; export type ProgressReading = "used" | "remaining"; export type ProgressFormat = "percentage" | "fraction" | "none"; /** One share of a whole. Each segment's width is `value` over the bar's `max`. */ export interface ProgressSegment { key: string; value: number; color: string; } /** Overrides for the `remaining` reading's two derived captions. Each key falls * back to the locale pack. */ export interface ProgressRemainingLabels { applied?: (used: string, total: string) => string; remaining?: (remainder: string) => string; over?: (amount: string) => string; exact?: string; } interface ProgressCommon extends StyleProps { /** The track's thickness, or the ring's stroke. Defaults to 10 on a bar; on a * ring, to a tenth of `size` floored at 2px, because one fixed default cannot * serve a 140px dashboard figure and a 16px control-row arc. */ thickness?: number; /** How `value` and `max` render inside the caption. Defaults to the reader's * locale grouping. Pass the true numbers so the fill and the percentage stay * exact and let this reshape only the text. */ formatValue?: (n: number) => string; /** The UNFILLED remainder. Defaults to the theme's `--muted`. */ trackColor?: string; testID?: string; ref?: React.Ref; render?: useRender.RenderProp; } /** A `progressbar` is name-required (WAI-ARIA, Name From: author), so the * compiler asks for one of the two. Where a `title` is DRAWN it is the * announced name whatever else is passed. */ type Named = { title: string; accessibilityLabel?: string; } | { title?: string; accessibilityLabel: string; }; interface ScalarCommon extends ProgressCommon { value: number; /** `null` = no bound: the caption states the value and `unboundedLabel` in * place of a fraction, and the track stays empty. */ max: number | null; reading?: "used"; /** `percentage` → "50%", `fraction` → "1,250 / 2,500 (50%)". Reports the TRUE * ratio — over `max` it reads "105%" while the track stays clamped. A ring * reads `fraction` as `percentage`. */ format?: ProgressFormat; /** The qualifier beside the value when `max` is null — "1,250 (no limit)". */ unboundedLabel?: string; /** What the quantity is COUNTED IN, named once after the pair — "0/8 pcs". A * percentage has no unit and takes none. */ unit?: string; /** How the PERCENTAGE renders, given `value / max` as a fraction (which can * exceed 1). Defaults to whole points. Separate from `formatValue` so a * surface that renders percentages of its own can make them agree. */ formatPercent?: (fraction: number) => string; /** Context beside the title, in place of the derived figure. */ caption?: string; /** THE METER'S OWN VERDICT — how close the quantity is to a ceiling somebody * cares about. A variant rather than a colour, so the two fills agree * everywhere a meter appears; `color` answers which SERIES this bar draws. */ tone?: "warning" | "danger"; /** The fill's colour while it is short of `max` — a series colour. */ color?: string; /** The fill's colour once it reaches `max`. */ completeColor?: string; } interface BarProps extends ScalarCommon { shape?: "bar"; /** COMPACT: one row — the track with a count beside it, for cells, headings * and peek triggers where the stacked anatomy is too tall. */ compact?: boolean; } interface RingProps extends Omit { shape: "ring"; /** What `value` is a fraction OF. Default 100, so a value already expressed as * a percentage reads directly. Pass the real pair rather than pre-computing: * the arc and the figure then derive from the same untouched numbers. */ max?: number | null; /** Diameter in px. Default 140 — the dashboard figure. Drop to ~16 for a * control row, where the arc is the whole content. */ size?: number; } interface SegmentedProps extends ProgressCommon { shape?: "bar"; reading?: "used"; /** The shares. Zero-value segments collapse and the shortfall against `max` * paints as the unfilled tail — sizing them against each OTHER makes the bar * full at every input. Shares that need naming are a `Breakdown`. */ value: ProgressSegment[]; max: number; caption?: string; /** Naming a split makes it announce the FILLED share; unnamed it is * `aria-hidden`, because a bar whose shares nothing names is a picture. */ title?: string; accessibilityLabel?: string; } interface RemainingProps extends ProgressCommon { shape?: "bar"; /** The reading is what is LEFT rather than what is used. It announces as a * `meter` rather than a `progressbar`, and the fill's colour IS the verdict: * the accent under, green at exact, red once over-allocated. */ reading: "remaining"; /** How much of `max` has been placed. */ value: number; /** The source being distributed — the payment, the available stock. */ max: number; labels?: ProgressRemainingLabels; title?: string; accessibilityLabel?: string; } export type ProgressProps = (BarProps & Named) | (RingProps & Named) | SegmentedProps | RemainingProps; /** * A VALUE AGAINST ITS MAXIMUM — one entry, three axes, each of them about * meaning. **`shape`** asks whether the reading is drawn straight or round; * **`value`** asks whether it is one number or a whole split into shares; and * **`reading`** asks whether the figure is what has been USED or what is LEFT. * * Countable stages are a `Stepper`, and nested cohorts that shrink are a * `Funnel` — a split here claims the shares add to the whole. * * The caption is MUTED at every ratio, so the verdict stays where the caller * states it, on the FILL. The one exception is `reading="remaining"`. */ export declare function Progress(props: ProgressProps): React.JSX.Element; export {};