UNPKG

analytica-frontend-lib

Version:

Repositório público dos componentes utilizados nas plataformas da Analytica Ensino

1 lines 5.75 kB
{"version":3,"sources":["../src/components/ScoreCircle/ScoreCircle.tsx"],"sourcesContent":["import { ReactNode } from 'react';\nimport Text from '../Text/Text';\n\nexport type ScoreCircleVariant = 'green' | 'blue' | 'warning';\n\nconst VARIANT_CLASSES: Record<\n ScoreCircleVariant,\n { track: string; fill: string; score: string }\n> = {\n green: {\n track: 'stroke-background-300',\n fill: 'stroke-success-200',\n score: 'text-success-300',\n },\n blue: {\n track: 'stroke-primary-100',\n fill: 'stroke-primary-700',\n score: 'text-primary-700',\n },\n warning: {\n track: 'stroke-background-300',\n fill: 'stroke-warning-300',\n score: 'text-warning-600',\n },\n};\n\nexport interface ScoreCircleProps {\n /** Valor atual do score */\n value: number;\n /** Valor máximo (default: 1000) */\n max?: number;\n /** Variante de cor do anel. Default: 'green' */\n variant?: ScoreCircleVariant;\n /** Tamanho total do círculo em pixels. Default: 180 */\n size?: number;\n /** Largura do traço do anel. Default: 10 */\n strokeWidth?: number;\n /** Label exibido acima do valor (ex: \"Nota final\") */\n label?: string;\n /** Ícone exibido à esquerda do label */\n labelIcon?: ReactNode;\n /** Classes adicionais pro container */\n className?: string;\n}\n\n/**\n * Círculo com anel de progresso exibindo um score e seu valor máximo.\n *\n * Diferente de `ProgressCircle` (que mostra \"%\" no centro), o `ScoreCircle`\n * mostra o valor absoluto (ex: \"800\") com \"de {max}\" abaixo — ideal pra notas\n * e scores onde o usuário precisa ver o número real.\n *\n * @example\n * ```tsx\n * <ScoreCircle\n * value={800}\n * max={1000}\n * label=\"Nota final\"\n * labelIcon={<LightbulbIcon size={14} />}\n * />\n * ```\n */\nconst ScoreCircle = ({\n value,\n max = 1000,\n variant = 'green',\n size = 180,\n strokeWidth = 10,\n label,\n labelIcon,\n className = '',\n}: ScoreCircleProps) => {\n const clamped = Math.max(0, Math.min(value, max));\n const percentage = max === 0 ? 0 : clamped / max;\n const radius = size / 2 - strokeWidth;\n const center = size / 2;\n const circumference = 2 * Math.PI * radius;\n const strokeDashoffset = circumference - percentage * circumference;\n const styles = VARIANT_CLASSES[variant];\n\n return (\n <div\n className={`relative flex flex-col items-center justify-center ${className}`}\n style={{ width: size, height: size }}\n role=\"img\"\n aria-label={label ? `${label}: ${value} de ${max}` : `${value} de ${max}`}\n >\n <svg\n className=\"absolute inset-0 -rotate-90\"\n width={size}\n height={size}\n viewBox={`0 0 ${size} ${size}`}\n aria-hidden=\"true\"\n >\n <circle\n cx={center}\n cy={center}\n r={radius}\n fill=\"none\"\n strokeWidth={strokeWidth}\n className={styles.track}\n />\n <circle\n cx={center}\n cy={center}\n r={radius}\n fill=\"none\"\n strokeWidth={strokeWidth}\n strokeLinecap=\"round\"\n strokeDasharray={circumference}\n strokeDashoffset={strokeDashoffset}\n className={`${styles.fill} transition-all duration-500 ease-out`}\n />\n </svg>\n\n <div className=\"relative z-10 flex flex-col items-center gap-1\">\n {(label || labelIcon) && (\n <div className=\"flex flex-row items-center gap-1 text-text-700\">\n {labelIcon}\n {label && (\n <Text size=\"xs\" className=\"text-text-700\">\n {label}\n </Text>\n )}\n </div>\n )}\n <Text\n size=\"xl\"\n weight=\"bold\"\n className={`${styles.score} leading-none text-4xl`}\n >\n {value}\n </Text>\n <Text size=\"xs\" className=\"text-text-700\">\n de {max}\n </Text>\n </div>\n </div>\n );\n};\n\nexport default ScoreCircle;\n"],"mappings":";;;;;AAuFM,SAOE,KAPF;AAlFN,IAAM,kBAGF;AAAA,EACF,OAAO;AAAA,IACL,OAAO;AAAA,IACP,MAAM;AAAA,IACN,OAAO;AAAA,EACT;AAAA,EACA,MAAM;AAAA,IACJ,OAAO;AAAA,IACP,MAAM;AAAA,IACN,OAAO;AAAA,EACT;AAAA,EACA,SAAS;AAAA,IACP,OAAO;AAAA,IACP,MAAM;AAAA,IACN,OAAO;AAAA,EACT;AACF;AAsCA,IAAM,cAAc,CAAC;AAAA,EACnB;AAAA,EACA,MAAM;AAAA,EACN,UAAU;AAAA,EACV,OAAO;AAAA,EACP,cAAc;AAAA,EACd;AAAA,EACA;AAAA,EACA,YAAY;AACd,MAAwB;AACtB,QAAM,UAAU,KAAK,IAAI,GAAG,KAAK,IAAI,OAAO,GAAG,CAAC;AAChD,QAAM,aAAa,QAAQ,IAAI,IAAI,UAAU;AAC7C,QAAM,SAAS,OAAO,IAAI;AAC1B,QAAM,SAAS,OAAO;AACtB,QAAM,gBAAgB,IAAI,KAAK,KAAK;AACpC,QAAM,mBAAmB,gBAAgB,aAAa;AACtD,QAAM,SAAS,gBAAgB,OAAO;AAEtC,SACE;AAAA,IAAC;AAAA;AAAA,MACC,WAAW,sDAAsD,SAAS;AAAA,MAC1E,OAAO,EAAE,OAAO,MAAM,QAAQ,KAAK;AAAA,MACnC,MAAK;AAAA,MACL,cAAY,QAAQ,GAAG,KAAK,KAAK,KAAK,OAAO,GAAG,KAAK,GAAG,KAAK,OAAO,GAAG;AAAA,MAEvE;AAAA;AAAA,UAAC;AAAA;AAAA,YACC,WAAU;AAAA,YACV,OAAO;AAAA,YACP,QAAQ;AAAA,YACR,SAAS,OAAO,IAAI,IAAI,IAAI;AAAA,YAC5B,eAAY;AAAA,YAEZ;AAAA;AAAA,gBAAC;AAAA;AAAA,kBACC,IAAI;AAAA,kBACJ,IAAI;AAAA,kBACJ,GAAG;AAAA,kBACH,MAAK;AAAA,kBACL;AAAA,kBACA,WAAW,OAAO;AAAA;AAAA,cACpB;AAAA,cACA;AAAA,gBAAC;AAAA;AAAA,kBACC,IAAI;AAAA,kBACJ,IAAI;AAAA,kBACJ,GAAG;AAAA,kBACH,MAAK;AAAA,kBACL;AAAA,kBACA,eAAc;AAAA,kBACd,iBAAiB;AAAA,kBACjB;AAAA,kBACA,WAAW,GAAG,OAAO,IAAI;AAAA;AAAA,cAC3B;AAAA;AAAA;AAAA,QACF;AAAA,QAEA,qBAAC,SAAI,WAAU,kDACX;AAAA,oBAAS,cACT,qBAAC,SAAI,WAAU,kDACZ;AAAA;AAAA,YACA,SACC,oBAAC,gBAAK,MAAK,MAAK,WAAU,iBACvB,iBACH;AAAA,aAEJ;AAAA,UAEF;AAAA,YAAC;AAAA;AAAA,cACC,MAAK;AAAA,cACL,QAAO;AAAA,cACP,WAAW,GAAG,OAAO,KAAK;AAAA,cAEzB;AAAA;AAAA,UACH;AAAA,UACA,qBAAC,gBAAK,MAAK,MAAK,WAAU,iBAAgB;AAAA;AAAA,YACpC;AAAA,aACN;AAAA,WACF;AAAA;AAAA;AAAA,EACF;AAEJ;AAEA,IAAO,sBAAQ;","names":[]}