114 lines
2.7 KiB
TypeScript
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; |