import type { HTMLAttributes } from "react"; import { cx } from "../../lib/cx"; import type { RefProp } from "../../lib/refProp"; import { useFormats, useWording } from "../../lib/language"; import { clampFraction, percentDisplay } from "../DataViz/scale"; import styles from "./ProgressBar.module.css"; /** The props of `ProgressBar`. */ export interface ProgressBarProps extends HTMLAttributes, RefProp { /** How far the task has come, from 0 to 1. Left out, the bar is indeterminate: the task runs, and nobody knows how far it is. */ value?: number; /** * What is progressing, e.g. "Import of the invoice records". A progress bar * needs a name from the author. * * @default the wording's "Progress" */ label?: string; /** What a screen reader says instead of the percentage, where a count says it better - "3 of 12 files". */ valueText?: string; /** The percentage beside the bar (Geist Mono). Never for an indeterminate bar - it has no figure to show. */ showLabel?: boolean; } /* How far a task has come - and nothing more. It is not a `Meter`: a meter reads a measured value against limits and takes its colour from that verdict, a progress bar only counts towards an end and has no tone at all. An upload that is 90 per cent done is not a warning. (CONTEXT.md, Progress.) */ /** How far a task has come, from 0 to 1 - or, without a value, that it runs. It has no tone: a measured value judged against limits is a `Meter`. */ export function ProgressBar({ ref, value, label, valueText, showLabel = false, className, ...rest }: ProgressBarProps) { const formats = useFormats(); const wording = useWording(); const determinate = value !== undefined; const fraction = determinate ? clampFraction(value) : 0; return (
{showLabel && determinate && {formats.percent(fraction)}}
); }