shadimage
quiz-ui
componentquiz-progresssource: ok · hit

QuizProgress

Progress bar with a 'Step N of M' label, on Radix Progress.

npx shadcn add "https://quiz-ui-phi.vercel.app/r/quiz-progress.json"
free

No selection tags yet — empty means no evidence, not lack of support.

Dependencies

Bundle weight · light
ui-primitives@radix-ui/react-progress

Registry dependencies

@quiz-ui/quiz-core@quiz-ui/quiz-cn

Files1 · source cached 10/9/2026, 9:26:58 PM

components/ui/quiz/quiz-progress.tsx
"use client";

import * as React from "react";
import * as ProgressPrimitive from "@radix-ui/react-progress";
import { useQuizEngine } from "./core";

export interface QuizProgressProps
  extends React.ComponentPropsWithoutRef<typeof ProgressPrimitive.Root> {
  showLabel?: boolean;
  /** Applied to the "Step N of M" text. */
  labelClassName?: string;
  /** Applied to the track (Progress.Root) — needs a visible size/background to read as a bar. */
  trackClassName?: string;
  /** Applied to the filled indicator. Position is computed via inline style; color/height is yours. */
  indicatorClassName?: string;
}

export function QuizProgress({
  className,
  showLabel = true,
  labelClassName,
  trackClassName,
  indicatorClassName,
  ...props
}: QuizProgressProps) {
  const { progress, definition, state } = useQuizEngine();
  const stepNumber = state.history.length;
  const totalSteps = definition.steps.length;

  return (
    <div className={className}>
      {showLabel ? (
        <span className={labelClassName}>
          Step {stepNumber} of {totalSteps}
        </span>
      ) : null}
      <ProgressPrimitive.Root
        className={trackClassName}
        value={Math.round(progress * 100)}
        {...props}
      >
        <ProgressPrimitive.Indicator
          className={indicatorClassName}
          style={{ transform: `translateX(-${100 - progress * 100}%)` }}
        />
      </ProgressPrimitive.Root>
    </div>
  );
}

More from quiz-ui

Browse all components in this library →