// @flow strict import * as React from 'react'; import * as COLORS from '../../styles/variables/_color'; import classify from '../../utils/classify'; import {BodyLargeBold} from '../Text'; import css from './ProgressDonut.module.css'; const STROKE_WIDTH = 8; const MIN_PERCENTAGE = 0; const DIVISOR_TWO = 2; const MAX_PERCENTAGE = 100; const SUCCESS_THRESHOLD = 80; const LARGE_DONUT_SIZE = 72; const INFO_THRESHOLD = 50; const WARNING_THRESHOLD = 30; type ClassNames = $ReadOnly<{ wrapper?: string, }>; export type ProgressDonutProps = { classNames?: ClassNames, color?: $Keys, percentage: number, }; const getProgressDonutColor = (percentage: number): string => { if (percentage >= SUCCESS_THRESHOLD) { return COLORS.colorSuccess; } else if (percentage >= INFO_THRESHOLD && percentage < SUCCESS_THRESHOLD) { return COLORS.colorInformation; } else if (percentage >= WARNING_THRESHOLD && percentage < INFO_THRESHOLD) { return COLORS.colorWarning; } else { return COLORS.colorDanger; } }; export const ProgressDonut: React$AbstractComponent< ProgressDonutProps, HTMLDivElement, > = React.forwardRef( ({classNames, percentage = 0, color = ''}: ProgressDonutProps, ref) => { const donutPercentage = React.useMemo( () => Math.min(Math.max(percentage, MIN_PERCENTAGE), MAX_PERCENTAGE), [percentage], ); const donutColor = React.useMemo( () => getProgressDonutColor(donutPercentage), [donutPercentage], ); const radius = React.useMemo( () => (LARGE_DONUT_SIZE - STROKE_WIDTH) / DIVISOR_TWO, [LARGE_DONUT_SIZE], ); const circumference = React.useMemo( () => DIVISOR_TWO * Math.PI * radius, [radius], ); const offset = React.useMemo( () => circumference - (donutPercentage / MAX_PERCENTAGE) * circumference, [circumference, donutPercentage], ); return (
{`${donutPercentage}%`}
); }, );