This document outlines the steps to create Progress
component styled withTailwind CSS and using some npm dependency libraries.
Node.js
and npm
installed on your machine.Tailwind CSS
installed in your project.CVA(class-variance-authority)
is a utility for managing CSS class names based on various conditions.clsx
is a tiny utility for constructing className strings conditionally.1// tailwind.config.js
2module.exports = {
3 ...
4 theme: {
5 ...
6 extend: {
7 ...
8 keyframes: {
9 "progress-bar-stripes": {
10 from: { backgroundPosition: "1rem 0" },
11 to: { backgroundPosition: "0 0" },
12 },
13 },
14 animation: {
15 "progress-bar-stripes": "progress-bar-stripes 1s linear infinite",
16 },
17 },
18 },
19 plugins: [require("tailwindcss-animate")]
20};
21
1// progress.helpers.ts
2import { cva } from "class-variance-authority";
3
4export const progressVariants = cva(
5 "bg-neutral-200 dark:bg-neutral-400 overflow-hidden relative",
6 {
7 variants: {
8 size: {
9 small: "rounded-sm h-2",
10 medium: "rounded-sm h-3",
11 large: "rounded-md h-6",
12 },
13 },
14 defaultVariants: {
15 size: "medium",
16 },
17 },
18);
19
20export const progressBarVariants = cva(
21 [
22 "absolute inset-y-0 left-0 bg-[length:1rem_1rem] data-[animate=true]:animate-progress-bar-stripes",
23 "data-[stripe=true]:bg-[linear-gradient(45deg,rgba(255,255,255,.15)_25%,transparent_25%,transparent_50%,rgba(255,255,255,.15)_50%,rgba(255,255,255,.15)_75%,transparent_75%,transparent)]",
24 ],
25 {
26 variants: {
27 color: {
28 primary: "bg-blue-500",
29 secondary: "bg-gray-500",
30 success: "bg-green-500",
31 danger: "bg-red-500",
32 warning: "bg-yellow-500",
33 info: "bg-cyan-500",
34 light: "bg-gray-300",
35 dark: "bg-black",
36 },
37 },
38 defaultVariants: {
39 color: "primary",
40 },
41 },
42);
43
1// progress.component.tsx
2import clsx from "clsx";
3import type { VariantProps } from "class-variance-authority";
4import { progressBarVariants, progressVariants } from "./progress.helpers";
5
6export interface ProgressProps
7 extends VariantProps<typeof progressVariants>,
8 VariantProps<typeof progressBarVariants> {
9 value: number;
10 hasStripes?: boolean;
11 animateStripes?: boolean;
12 className?: string;
13}
14
15const Progress: React.FC<ProgressProps> = ({
16 value,
17 size,
18 color,
19 hasStripes,
20 animateStripes,
21 className,
22}) => {
23 return (
24 <div className={cn(progressVariants({ size }), className)}>
25 <div
26 data-stripe={Boolean(hasStripes)}
27 data-animate={Boolean(animateStripes)}
28 className={progressBarVariants({ color })}
29 style={{ width: `${value}%` }}
30 />
31 </div>
32 );
33};
34
35export default Progress;
36