Skip to content

Latest commit

 

History

History
 
 

progress

Solid Aria - Progress

@solid-aria/progress

pnpm turborepo size version stage

Progress bars show either determinate or indeterminate progress of an operation over time.

  • createProgressBar - Provides the accessibility implementation for a progress bar component.

Installation

npm install @solid-aria/progress
# or
yarn add @solid-aria/progress
# or
pnpm add @solid-aria/progress

createProgressBar

Features

The <progress> HTML element can be used to build a progress bar, however it is very difficult to style cross browser. createProgressBar helps achieve accessible progress bars and spinners that can be styled as needed.

  • Exposed to assistive technology as a progress bar via ARIA
  • Labeling support for accessibility
  • Internationalized number formatting as a percentage or value
  • Determinate and indeterminate progress support

How to use it

import { AriaProgressBarProps, createProgressBar } from "@solid-aria/progress";
import { createMemo, Show } from "solid-js";

function ProgressBar(props: AriaProgressBarProps) {
  const { progressBarProps, labelProps, percentage } = createProgressBar(props);

  const barWidth = createMemo(() => `${Math.round(percentage() * 100)}%`);

  return (
    <div {...progressBarProps} style={{ width: "200px" }}>
      <div style={{ display: "flex", "justify-content": "space-between" }}>
        <Show when={props.label}>
          <span {...labelProps}>{props.label}</span>
          <span>{progressBarProps["aria-valuetext"]}</span>
        </Show>
      </div>
      <div style={{ height: "10px", background: "gray" }}>
        <div style={{ width: barWidth(), height: "10px", background: "orange" }} />
      </div>
    </div>
  );
}

function App() {
  return <ProgressBar label="Loading..." value={30} />;
}

Indeterminate state

Progress bars can represent an indeterminate operation. They may also be used to represent progress visually as a circle rather than as a line. The following example shows an indeterminate progress bar visualized as a circular spinner using SVG.

import { createProgressBar } from "@solid-aria/progress";

function Spinner() {
  const { progressBarProps } = createProgressBar({
    isIndeterminate: true,
    "aria-label": "Loading..."
  });

  const center = 16;
  const strokeWidth = 4;
  const r = 16 - strokeWidth;
  const c = 2 * r * Math.PI;
  const offset = c - (1 / 4) * c;

  return (
    <svg
      {...progressBarProps}
      width={32}
      height={32}
      viewBox="0 0 32 32"
      fill="none"
      stroke-width={strokeWidth}
    >
      <circle cx={center} cy={center} r={r} stroke="gray" />
      <circle
        cx={center}
        cy={center}
        r={r}
        stroke="orange"
        stroke-dasharray={c.toString()}
        stroke-dashoffset={offset}
      >
        <animateTransform
          attributeName="transform"
          type="rotate"
          begin="0s"
          dur="1s"
          from="0 16 16"
          to="360 16 16"
          repeatCount="indefinite"
        />
      </circle>
    </svg>
  );
}

function App() {
  return <Spinner />;
}

Internationalization

Value formatting

createProgressBar will handle localized formatting of the value label for accessibility automatically. This is returned in the aria-valuetext prop in progressBarProps. You can use this to create a visible label if needed and ensure that it is formatted correctly. The number formatting can also be controlled using the formatOptions prop.

RTL

In right-to-left languages, the progress bar should be mirrored. Ensure that your CSS accounts for this.

Changelog

All notable changes are described in the CHANGELOG.md file.