Added progress component

This commit is contained in:
2025-08-09 14:25:27 -04:00
parent e1b3000121
commit 4e3c984125
17 changed files with 447 additions and 2 deletions

View File

@@ -0,0 +1,79 @@
import type { ProgressProps } from "$/types/Progress";
import clsx from "clsx";
import { useMemo } from "react";
export default function Progress({
id,
className,
value,
min,
max,
size = "md",
rounding = "full",
label,
tabIndex,
progressColor,
backgroundColor
}: ProgressProps){
const percentage = useMemo(() => {
const num = !value || Number.isNaN(value) ? min : Math.max(value, min);
const den = (!value || Number.isNaN(value) ? max : Math.max(value, max)) - min;
const percentage = (num / den) * 100;
return percentage && percentage > max ? max : percentage;
}, [ min, max, value ]);
return (
<div
id={id}
className={clsx(
"relative w-full overflow-hidden",
//Size
{
"": size === "none",
"h-2": size === "xs",
"h-3": size === "sm",
"h-4": size === "md",
"h-5": size === "lg",
"h-6": size === "xl",
"h-full": size === "full"
},
//Rounding
{
"": rounding === "none",
"rounded-sm": rounding === "sm",
"rounded-md": rounding === "md",
"rounded-lg": rounding === "lg",
"rounded-full": rounding === "full"
},
className
)}
role="progressbar"
aria-valuemin={min}
aria-valuemax={max}
aria-valuenow={value ? Math.round(value * 10000) / 100 : undefined}
aria-label={label}
tabIndex={tabIndex ?? 0}
>
<div
className={clsx(
"absolute -left-[0.52px] h-full transition-all duration-250",
)}
style={{
backgroundColor: progressColor,
width: `calc(${percentage}% + 1.04px)`
}}
/>
<div
className={clsx(
"absolute -right-[0.52px] h-full transition-all duration-250",
)}
style={{
backgroundColor: backgroundColor,
width: `${100 - percentage}%`
}}
/>
</div>
);
}