Skip to content
kerfjsGitHub

Progress

Shows how far along something is, as a bar or a ring.

SourcePackage @kerf-js/veneerTry it

Preview

tsx
import { Progress, Stack } from '@kerf-js/veneer'export function Bar() {  return (  <Stack gap="group">    <Progress      label="Build"      value={35}    />    <Progress      label="Upload"      value={80}    />  </Stack>  )}

Installation

npm install @kerf-js/veneer

Try it

Change the controls: the preview and its code update together. The address keeps what you set, so you can link to it.

Live preview
Controls
Value64
Shape
Tone
Codeupdates as you change the controls
import { Progress } from '@kerf-js/veneer'<Progress label="Uploading" value={64} />

Usage

tsx
import { Progress } from '@kerf-js/veneer'<Stack gap="group">  <Progress    label="Build"    value={35}  />  <Progress    label="Upload"    value={80}  /></Stack>

Tones

Use tone to say a limit is near.

tsx
import { Progress, Stack } from '@kerf-js/veneer'export function Tones() {  return (  <Stack gap="group">    <Progress      label="Build minutes"      tone="positive"      value={38}    />    <Progress      label="Storage"      tone="caution"      value={82}    />    <Progress      label="Seats"      tone="critical"      value={96}    />  </Stack>  )}

Ring

shape="circle". With no value it spins.

tsx
import { Progress } from '@kerf-js/veneer'export function Circle() {  return (  <>    <Progress      label="Uptime target"      shape="circle"      value={72}    />    <Progress      label="Budget"      shape="circle"      tone="caution"      value={91}    />    <Progress      label="Syncing"      shape="circle"    />  </>  )}

No value yet

Leave out value until you have one.

tsx
import { Progress, Stack } from '@kerf-js/veneer'export function Indeterminate() {  return (  <Stack>    <Progress label="Waiting for a build machine" />  </Stack>  )}

Moving

Change value and the bar follows.

tsx
import { derived, onCleanup, state } from '@kerf-js/core'import { Progress, Stack } from '@kerf-js/veneer'export function Run() {  const pct = state(0)  const steps = derived(() =>    pct.value < 40      ? 'Installing dependencies'      : pct.value < 80        ? 'Building'        : pct.value < 100          ? 'Uploading'          : 'Live',  )  const timer = setInterval(    () => (pct.value = Math.min(100, pct.value + 2)),    80,  )  onCleanup(() => clearInterval(timer))  return (    <Stack>      <Progress        label={steps.value}        tone={pct.value === 100 ? 'positive' : undefined}        value={pct.value}      />    </Stack>  )}

Plan usage

Use value for how full each bar is, and tone to flag one that needs attention.

tsx
import { Card, Progress, Stack } from '@kerf-js/veneer'export function PlanUsage() {  return (  <Card    eyebrow="October"    title="Your plan"  >    <Stack gap="group">      <Progress        label="Build minutes"        value={82}        tone="caution"      />      <Progress        label="Bandwidth"        value={46}      />      <Progress        label="Seats"        value={80}      />    </Stack>  </Card>  )}

When to use

Use it for

  • Work with a known end, such as an upload
  • A usage figure against a limit

Reach for something else

  • Spinner, when it takes a moment and you can't say how long
  • Skeleton, when a page is loading

Accessibility

  • label is required: it names the bar, and it is the text above it.
  • With no value, the bar is announced as busy with its label.

API Reference

PropTypeDefaultDescription
labelstring—Says what is progressing.
valuenumber—From 0 to 100. Leave it out when you can't say yet.
shape"circle" | "linear"—linear or circle.
toneTone—What it means: neutral, accent, positive, caution, critical or info.
showValuebooleantrueThe ring's number in the middle.

Parts

Every element carries a stable name, so you can style it from your own CSS: [data-scope="progress"] [data-part="track"]

trackrangevalue-textrootlabel-row

RelatedSpinnerSkeleton