PlugSnatcher/src/components/common/ProgressBar/ProgressBar.tsx

114 lines
2.7 KiB
TypeScript

import React from 'react';
import './ProgressBar.css';
export interface ProgressBarProps {
/**
* Current value of the progress (should be between min and max)
*/
value: number;
/**
* Maximum value for the progress bar
* @default 100
*/
max?: number;
/**
* Minimum value for the progress bar
* @default 0
*/
min?: number;
/**
* Label to display with the progress
*/
label?: string;
/**
* Whether to show percentage text inside the progress bar
* @default true
*/
showPercentage?: boolean;
/**
* Additional CSS class for custom styling
*/
className?: string;
/**
* Progress bar color
*/
color?: 'primary' | 'success' | 'warning' | 'error' | 'info';
/**
* Whether to display the current value and max next to the bar
* @default false
*/
showValues?: boolean;
/**
* Format for displaying values (when showValues is true)
* @default "{value}/{max}"
*/
valueFormat?: string;
}
/**
* A reusable progress bar component that shows the progress of an operation
*/
const ProgressBar: React.FC<ProgressBarProps> = ({
value,
max = 100,
min = 0,
label,
showPercentage = true,
className = '',
color = 'primary',
showValues = false,
valueFormat = "{value}/{max}"
}) => {
// Calculate percentage
const range = max - min;
const valueInRange = Math.max(min, Math.min(max, value)) - min;
const percentage = range > 0 ? Math.round((valueInRange / range) * 100) : 0;
// Format value display
const formattedValue = valueFormat
.replace('{value}', value.toString())
.replace('{max}', max.toString())
.replace('{min}', min.toString())
.replace('{percentage}', `${percentage}%`);
return (
<div
className={`progress-container ${className}`}
aria-live="polite"
>
{label && <div className="progress-label" id={`progress-label-${label}`}>{label}</div>}
<div
className="progress-bar-wrapper"
role="progressbar"
aria-valuenow={value}
aria-valuemin={min}
aria-valuemax={max}
aria-label={label ? undefined : 'Progress'}
aria-labelledby={label ? `progress-label-${label}` : undefined}
aria-valuetext={showValues ? formattedValue : `${percentage}%`}
>
<div
className={`progress-bar progress-bar-${color}`}
style={{ width: `${percentage}%` }}
>
{showPercentage && (
<span className="progress-percentage">{percentage}%</span>
)}
</div>
</div>
{showValues && (
<div className="progress-values" aria-hidden="true">{formattedValue}</div>
)}
</div>
);
};
export default ProgressBar;