website refactor
This commit is contained in:
@@ -1,53 +1,79 @@
|
||||
import React from 'react';
|
||||
import { Box } from './primitives/Box';
|
||||
import { Text } from './Text';
|
||||
|
||||
|
||||
|
||||
interface CircularProgressProps {
|
||||
export interface CircularProgressProps {
|
||||
value: number;
|
||||
max: number;
|
||||
label: string;
|
||||
color: string;
|
||||
max?: number;
|
||||
size?: number;
|
||||
strokeWidth?: number;
|
||||
intent?: 'primary' | 'success' | 'warning' | 'critical' | 'telemetry';
|
||||
showValue?: boolean;
|
||||
label?: string;
|
||||
color?: string; // Alias for intent
|
||||
}
|
||||
|
||||
export function CircularProgress({ value, max, label, color, size = 80 }: CircularProgressProps) {
|
||||
const percentage = Math.min((value / max) * 100, 100);
|
||||
const strokeWidth = 6;
|
||||
export const CircularProgress = ({
|
||||
value,
|
||||
max = 100,
|
||||
size = 64,
|
||||
strokeWidth = 4,
|
||||
intent = 'primary',
|
||||
showValue = false,
|
||||
label,
|
||||
color: colorProp
|
||||
}: CircularProgressProps) => {
|
||||
const radius = (size - strokeWidth) / 2;
|
||||
const circumference = radius * 2 * Math.PI;
|
||||
const strokeDashoffset = circumference - (percentage / 100) * circumference;
|
||||
const offset = circumference - (value / max) * circumference;
|
||||
|
||||
const intentColorMap = {
|
||||
primary: 'var(--ui-color-intent-primary)',
|
||||
success: 'var(--ui-color-intent-success)',
|
||||
warning: 'var(--ui-color-intent-warning)',
|
||||
critical: 'var(--ui-color-intent-critical)',
|
||||
telemetry: 'var(--ui-color-intent-telemetry)',
|
||||
};
|
||||
|
||||
const color = colorProp || intentColorMap[intent];
|
||||
|
||||
return (
|
||||
<div className="flex flex-col items-center">
|
||||
<div className="relative" style={{ width: size, height: size }}>
|
||||
<svg className="transform -rotate-90" width={size} height={size}>
|
||||
<Box display="flex" flexDirection="col" alignItems="center" gap={2}>
|
||||
<Box position="relative" width={size} height={size} display="flex" alignItems="center" justifyContent="center">
|
||||
<svg width={size} height={size} className="transform -rotate-90">
|
||||
<circle
|
||||
cx={size / 2}
|
||||
cy={size / 2}
|
||||
r={radius}
|
||||
stroke="currentColor"
|
||||
stroke="var(--ui-color-bg-surface-muted)"
|
||||
strokeWidth={strokeWidth}
|
||||
fill="transparent"
|
||||
className="text-charcoal-outline"
|
||||
/>
|
||||
<circle
|
||||
cx={size / 2}
|
||||
cy={size / 2}
|
||||
r={radius}
|
||||
stroke="currentColor"
|
||||
stroke={color}
|
||||
strokeWidth={strokeWidth}
|
||||
fill="transparent"
|
||||
strokeDasharray={circumference}
|
||||
strokeDashoffset={strokeDashoffset}
|
||||
style={{ strokeDashoffset: offset, transition: 'stroke-dashoffset 0.3s ease-in-out' }}
|
||||
strokeLinecap="round"
|
||||
className={color}
|
||||
style={{ transition: 'stroke-dashoffset 0.5s ease-in-out' }}
|
||||
/>
|
||||
</svg>
|
||||
<div className="absolute inset-0 flex items-center justify-center">
|
||||
<span className="text-lg font-bold text-white">{percentage.toFixed(0)}%</span>
|
||||
</div>
|
||||
</div>
|
||||
<span className="text-xs text-gray-400 mt-2">{label}</span>
|
||||
</div>
|
||||
{showValue && (
|
||||
<Box position="absolute" inset={0} display="flex" alignItems="center" justifyContent="center">
|
||||
<Text size="xs" weight="bold" variant="high">
|
||||
{Math.round((value / max) * 100)}%
|
||||
</Text>
|
||||
</Box>
|
||||
)}
|
||||
</Box>
|
||||
{label && (
|
||||
<Text size="xs" weight="bold" variant="low" uppercase letterSpacing="wider">
|
||||
{label}
|
||||
</Text>
|
||||
)}
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user