import React, { forwardRef } from 'react'; import { Tone, Surface, cn, toneMap, surfaceClasses, useEffectiveSurface, } from '../common'; /* ───────────────────────────────────────────────────────────────────────── PixelProgress — Pixel surface renders 10 segmented HP-bar blocks; linear surface renders a smooth filled bar. ───────────────────────────────────────────────────────────────────────── */ /** Public prop bag for {@link PixelProgress}. */ export interface PixelProgressProps { /** Current value 0-100 (clamped). */ value: number; /** Tone determines fill color. Defaults to `'green'`. */ tone?: Tone; /** * Optional label rendered above the bar. Also used as the progressbar's * accessible name; falls back to "Progress" when omitted. */ label?: string; /** Whether to show the numeric percentage on the right. Defaults to `true`. */ showValue?: boolean; /** Surface override; falls back to nearest provider. */ surface?: Surface; /** When `true`, switches to indeterminate animation (visual only — ARIA still reports value). */ indeterminate?: boolean; } export const PixelProgress = forwardRef(function PixelProgress( { value, tone = 'green', label, showValue = true, surface: surfaceProp, indeterminate = false }, ref, ) { const surface = useEffectiveSurface(surfaceProp); const s = surfaceClasses(surface); const safe = Math.max(0, Math.min(100, value)); return (
{(label || showValue) && (
{label && {label}} {showValue && !indeterminate && {safe}%}
)} {surface === 'pixel' ? (
{Array.from({ length: 10 }).map((_, i) => { const filled = (i + 1) * 10 <= safe; const partial = !filled && i * 10 < safe; return (
); })}
) : (
)}
); }); PixelProgress.displayName = 'PixelProgress';