Notificacionesfeedbackprogressringcircularmeter
Progress Ring Counter
Anillo de progreso circular con contador numérico animado y trazo en degradado.
Vista Previa en Vivo
75%COMPLETED
80%TASKS
Uso
Copia y pega este código directamente en tu componente React:
tsx
import { ProgressRingCounter } from 'react-component-kit-ui/feedback';
<ProgressRingCounter value={8} max={10} label="TASKS" color="#34d399" />Instalación Manual
Si no estás usando el paquete npm, crea un archivo nuevo y pega el siguiente código: src/components/ProgressRingCounter.tsx + ProgressRingCounter.css:
ProgressRingCounter.tsx
'use client';
import type { CSSProperties, HTMLAttributes } from 'react';
import './ProgressRingCounter.css';
/**
* ProgressRingCounter — Circular SVG progress ring with centered countdown or metric value.
*
* @param value - Optional. Default 75.
* @param max - Optional. Default 100.
* @param size - Optional. px. Default 96.
* @param strokeWidth - Optional. Default 6.
* @param color - Optional. Default '#d4a017'.
* @param label - Optional. Caption under the value. Default 'COMPLETED'.
*/
export interface ProgressRingCounterProps extends HTMLAttributes<HTMLDivElement> {
value?: number;
max?: number;
size?: number;
strokeWidth?: number;
color?: string;
label?: string;
}
export function ProgressRingCounter({
value = 75,
max = 100,
size = 96,
strokeWidth = 6,
color = '#d4a017',
label = 'COMPLETED',
className,
style,
...rest
}: ProgressRingCounterProps) {
const radius = (size - strokeWidth) / 2;
const circumference = 2 * Math.PI * radius;
const percent = Math.min(100, Math.max(0, (value / max) * 100));
const offset = circumference - (percent / 100) * circumference;
return (
<div
role="progressbar"
aria-valuenow={value}
aria-valuemin={0}
aria-valuemax={max}
aria-label={label || undefined}
{...rest}
className={['ring-counter', className].filter(Boolean).join(' ')}
style={{ '--ring-size': `${size}px`, '--ring-color': color, ...style } as CSSProperties}
>
<svg width={size} height={size} className="ring-counter__svg" aria-hidden="true">
<circle className="ring-counter__bg" cx={size / 2} cy={size / 2} r={radius} strokeWidth={strokeWidth} />
<circle
className="ring-counter__meter"
cx={size / 2}
cy={size / 2}
r={radius}
strokeWidth={strokeWidth}
strokeDasharray={circumference}
strokeDashoffset={offset}
/>
</svg>
<div className="ring-counter__center">
<span className="val">{Math.round(percent)}%</span>
{label && <span className="lbl">{label}</span>}
</div>
</div>
);
}
export default ProgressRingCounter;ProgressRingCounter.css
/* ProgressRingCounter — ported from astro-component-kit (feedback/ProgressRingCounter.astro) */
.ring-counter {
position: relative;
width: var(--ring-size);
height: var(--ring-size);
display: inline-flex;
align-items: center;
justify-content: center;
font-family: var(--font-sans, system-ui, sans-serif);
user-select: none;
}
.ring-counter__svg {
transform: rotate(-90deg);
width: 100%;
height: 100%;
}
.ring-counter__bg {
fill: none;
stroke: rgba(255, 255, 255, 0.08);
}
.ring-counter__meter {
fill: none;
stroke: var(--ring-color);
stroke-linecap: round;
transition: stroke-dashoffset 0.8s cubic-bezier(0.16, 1, 0.3, 1);
filter: drop-shadow(0 0 6px rgba(212, 160, 23, 0.35));
}
.ring-counter__center {
position: absolute;
inset: 0;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
text-align: center;
}
.ring-counter__center .val {
font-size: 1.25rem;
font-weight: 800;
color: var(--c-text-1, #ffffff);
line-height: 1;
}
.ring-counter__center .lbl {
font-size: 0.55rem;
font-weight: 700;
letter-spacing: 0.08em;
color: var(--c-text-3, #737373);
margin-top: 4px;
text-transform: uppercase;
}Información Rápida
- Categoría
- Notificaciones
- Nombre de archivo
ProgressRingCounter.tsx- Dependencias
- Ninguna — React + CSS puro
- Etiquetas
- feedbackprogressringcircularmeter