* feat: wip import csv * feat: start implementing twenty UI * feat: new radio button component * feat: use new radio button component and fix scroll issue * fix: max height modal * feat: wip try to customize react-data-grid to match design * feat: wip match columns * feat: wip match column selection * feat: match column * feat: clean heading component & try to fix scroll in last step * feat: validation step * fix: small cleaning and remove unused component * feat: clean folder architecture * feat: remove translations * feat: remove chackra theme * feat: remove unused libraries * feat: use option button to open spreadsheet & fix stories * Fix lint and fix imports --------- Co-authored-by: Charles Bochet <charles@twenty.com>
72 lines
1.8 KiB
TypeScript
72 lines
1.8 KiB
TypeScript
import React, { useEffect, useMemo } from 'react';
|
|
import { motion, useAnimation } from 'framer-motion';
|
|
|
|
interface Props {
|
|
size?: number;
|
|
barWidth?: number;
|
|
barColor?: string;
|
|
}
|
|
|
|
export function CircularProgressBar({
|
|
size = 50,
|
|
barWidth = 5,
|
|
barColor = 'currentColor',
|
|
}: Props) {
|
|
const controls = useAnimation();
|
|
|
|
const circumference = useMemo(
|
|
() => 2 * Math.PI * (size / 2 - barWidth),
|
|
[size, barWidth],
|
|
);
|
|
|
|
useEffect(() => {
|
|
async function animateIndeterminate() {
|
|
const baseSegment = Math.max(5, circumference / 10); // Adjusting for smaller values
|
|
|
|
// Adjusted sequence based on baseSegment
|
|
const dashSequences = [
|
|
`${baseSegment} ${circumference - baseSegment}`,
|
|
`${baseSegment * 2} ${circumference - baseSegment * 2}`,
|
|
`${baseSegment * 3} ${circumference - baseSegment * 3}`,
|
|
`${baseSegment * 2} ${circumference - baseSegment * 2}`,
|
|
`${baseSegment} ${circumference - baseSegment}`,
|
|
];
|
|
|
|
await controls.start({
|
|
strokeDasharray: dashSequences,
|
|
rotate: [0, 720],
|
|
transition: {
|
|
strokeDasharray: {
|
|
duration: 2,
|
|
ease: 'linear',
|
|
repeat: Infinity,
|
|
repeatType: 'loop',
|
|
},
|
|
rotate: {
|
|
duration: 2,
|
|
ease: 'linear',
|
|
repeat: Infinity,
|
|
repeatType: 'loop',
|
|
},
|
|
},
|
|
});
|
|
}
|
|
|
|
animateIndeterminate();
|
|
}, [circumference, controls]);
|
|
|
|
return (
|
|
<motion.svg width={size} height={size} animate={controls}>
|
|
<motion.circle
|
|
cx={size / 2}
|
|
cy={size / 2}
|
|
r={size / 2 - barWidth}
|
|
fill="none"
|
|
stroke={barColor}
|
|
strokeWidth={barWidth}
|
|
strokeLinecap="round"
|
|
/>
|
|
</motion.svg>
|
|
);
|
|
}
|