sdxc

Type to search, or start from one of these:

ProgressBar

A styled native <progress> control paired with an optional value label, stacked in a single column so a caption can sit alongside the bar it describes.

Uploading 3 files
hero@2x.png0%
walkthrough.mp4Transcoding…
changelog.mdDone
View code
let uploaded = 0;

function startUpload() {
	let timer = setInterval(() => {
		uploaded = Math.min(100, uploaded + STEP);
		void handle.update();
		if (uploaded === 100) clearInterval(timer);
	}, TICK_MS);

	handle.signal.addEventListener("abort", () => clearInterval(timer));
}

<div mix={[vstack({ gap: 5, align: "stretch" })]}>
	<Header mix={[m(0)]}>Uploading 3 files</Header>

	<ProgressBar>
		<div mix={[hstack({ gap: 2, justify: "between" })]}>
			<span mix={[text("sm"), weight("medium")]}>hero@2x.png</span>
			<ProgressBar.ValueLabel>{uploaded}%</ProgressBar.ValueLabel>
		</div>
		<ProgressBar.Indicator value={uploaded} max={100} aria-label="hero@2x.png upload" />
	</ProgressBar>

	<ProgressBar>
		<div mix={[hstack({ gap: 2, justify: "between" })]}>
			<span mix={[text("sm"), weight("medium")]}>walkthrough.mp4</span>
			<ProgressBar.ValueLabel>Transcoding…</ProgressBar.ValueLabel>
		</div>
		<ProgressBar.Indicator aria-label="walkthrough.mp4 transcoding" mix={[shimmer()]} />
	</ProgressBar>

	<ProgressBar>
		<div mix={[hstack({ gap: 2, justify: "between" })]}>
			<span mix={[text("sm"), weight("medium")]}>changelog.md</span>
			<ProgressBar.ValueLabel>Done</ProgressBar.ValueLabel>
		</div>
		<ProgressBar.Indicator value={100} max={100} aria-label="changelog.md upload" />
	</ProgressBar>

	<Button
		type="button"
		variant="outline"
		size="sm"
		mix={[on<HTMLButtonElement, "click">("click", startUpload)]}
	>
		{uploaded === 0 ? "Upload" : uploaded === 100 ? "Upload again" : "Uploading…"}
	</Button>
</div>

Installation

An ordinary dependency: install it, import the theme once, and import the component where it is used.

npm add @sdxc/ui
import "@sdxc/ui/theme.css";

Usage

import { ProgressBar } from "@sdxc/ui";

Renders the root column: a <div> stacking ProgressBar.Indicator and an optional ProgressBar.ValueLabel, carrying no ARIA of its own since the <progress> inside already exposes progressbar semantics.

Composition

The parts the component publishes, each a static property of the host.

  • ProgressBar
  • ProgressBar.IndicatorRenders the busy/progress indicator: a native <progress> restyled as a pill track.
  • ProgressBar.ValueLabelRenders the indicator's caption: a <span> sized as a small run of body copy in the neutral muted foreground color, for a percentage or status string placed alongside ProgressBar.Indicator.

Props

Read from the component's own types, so every prop, every default and every allowed value is listed.

Also accepts everything in TagProps<"div">.

ProgressBar.Indicator

Also accepts everything in TagProps<"progress">.

ProgressBar.ValueLabel

Also accepts everything in TagProps<"span">.