{"version":3,"sources":["../src/components/ProgressCircle/ProgressCircle.tsx"],"sourcesContent":["import { ReactNode } from 'react';\nimport Text from '../Text/Text';\nimport { cn } from '../../utils/utils';\n\n/**\n * Progress circle size variants\n */\ntype ProgressCircleSize = 'small' | 'medium';\n\n/**\n * Progress circle color variants\n */\ntype ProgressCircleVariant = 'blue' | 'green';\n\n/**\n * Size configurations using Tailwind classes\n */\nconst SIZE_CLASSES = {\n  small: {\n    container: 'w-[107px] h-[107px]', // 107px circle to fit labels like \"CONCLUÍDO\"\n    strokeWidth: 4, // 4px stroke width - matches ProgressBar small (h-1)\n    textSize: '2xl', // 24px for percentage (font-size: 24px)\n    textWeight: 'medium', // font-weight: 500\n    labelSize: '2xs' as const, // 10px for status label\n    labelWeight: 'bold', // font-weight: 700\n    spacing: 'gap-0', // Reduced gap between percentage and label for better spacing\n    contentWidth: 'max-w-[85px]', // Width to fit labels like \"CONCLUÍDO\" inside circle\n  },\n  medium: {\n    container: 'w-[152px] h-[152px]', // 151.67px ≈ 152px circle from design specs\n    strokeWidth: 8, // 8px stroke width - matches ProgressBar medium (h-2)\n    textSize: '2xl', // 24px for percentage (font-size: 24px)\n    textWeight: 'medium', // font-weight: 500\n    labelSize: 'xs' as const, // 12px for status label (font-size: 12px)\n    labelWeight: 'medium', // font-weight: 500 (changed from bold)\n    spacing: 'gap-1', // 4px gap between percentage and label\n    contentWidth: 'max-w-[90px]', // Reduced width to fit text inside circle\n  },\n} as const;\n\n/**\n * Color configurations using design system colors\n */\nconst VARIANT_CLASSES = {\n  blue: {\n    background: 'stroke-primary-100', // Light blue background (#BBDCF7)\n    fill: 'stroke-primary-700', // Blue for activity progress (#2271C4)\n    textColor: 'text-primary-700', // Blue text color (#2271C4)\n    labelColor: 'text-text-700', // Gray text for label (#525252)\n  },\n  green: {\n    background: 'stroke-background-300', // Gray background (#D5D4D4 - matches design)\n    fill: 'stroke-success-200', // Green for performance (#84D3A2 - matches design)\n    textColor: 'text-text-800', // Dark gray text (#404040 - matches design)\n    labelColor: 'text-text-600', // Medium gray text for label (#737373 - matches design)\n  },\n} as const;\n\n/**\n * ProgressCircle component props interface\n */\nexport type ProgressCircleProps = {\n  /** Progress value between 0 and 100 */\n  value: number;\n  /** Maximum value (defaults to 100) */\n  max?: number;\n  /** Size variant of the progress circle */\n  size?: ProgressCircleSize;\n  /** Color variant of the progress circle */\n  variant?: ProgressCircleVariant;\n  /**\n   * Overrides the variant's arc colour with a raw CSS value, e.g.\n   * `var(--color-success-400)` or `#489766`. Use this — not a `stroke-*` class\n   * — when the colour encodes data (a score band): consumer apps only ship the\n   * colour utilities the lib itself compiles, so `stroke-*` classes for\n   * arbitrary tokens simply do not exist there and the arc renders invisible.\n   */\n  fillColor?: string;\n  /** Same as `fillColor`, for the track behind the arc. */\n  trackColor?: string;\n  /** Optional label to display below percentage */\n  label?: ReactNode;\n  /** Show percentage text */\n  showPercentage?: boolean;\n  /** Additional CSS classes */\n  className?: string;\n  /** Label CSS classes */\n  labelClassName?: string;\n  /** Percentage text CSS classes */\n  percentageClassName?: string;\n};\n\n/**\n * ProgressCircle component for Analytica Ensino platforms\n *\n * A circular progress indicator with size and color variants designed for tracking\n * activity progress (blue) and performance metrics (green).\n * Uses the Analytica Ensino Design System colors from styles.css with automatic\n * light/dark mode support. Includes Text component integration for consistent typography.\n *\n * @example\n * ```tsx\n * // Basic progress circle\n * <ProgressCircle value={65} />\n *\n * // Activity progress (blue)\n * <ProgressCircle variant=\"blue\" value={45} label=\"CONCLUÍDO\" showPercentage />\n *\n * // Performance metrics (green)\n * <ProgressCircle variant=\"green\" size=\"medium\" value={85} label=\"MÉDIA\" />\n *\n * // Small size with custom max value\n * <ProgressCircle size=\"small\" value={3} max={5} showPercentage />\n * ```\n */\nconst ProgressCircle = ({\n  value,\n  max = 100,\n  size = 'small',\n  variant = 'blue',\n  fillColor,\n  trackColor,\n  label,\n  showPercentage = true,\n  className = '',\n  labelClassName = '',\n  percentageClassName = '',\n}: ProgressCircleProps) => {\n  // Ensure value is within bounds and handle NaN/Infinity\n  const safeValue = isNaN(value) ? 0 : value;\n  const clampedValue = Math.max(0, Math.min(safeValue, max));\n  const percentage = max === 0 ? 0 : (clampedValue / max) * 100;\n\n  // Get size and variant classes\n  const sizeClasses = SIZE_CLASSES[size];\n  const variantClasses = VARIANT_CLASSES[variant];\n  // A cor por valor vence a da variante; quando ausente, mantém a classe.\n  const trackClass = trackColor ? undefined : variantClasses.background;\n  const fillClass = fillColor ? undefined : variantClasses.fill;\n\n  // Calculate SVG dimensions and stroke properties\n  // small: 107px container, radius = (107 - strokeWidth*2) / 2 ≈ 49.5, center = 53.5\n  // medium: 152px container, radius = 64, center = 76\n  const radius = size === 'small' ? 49 : 64;\n  const circumference = 2 * Math.PI * radius;\n  const strokeDashoffset = circumference - (percentage / 100) * circumference;\n  const center = size === 'small' ? 53.5 : 76;\n  const svgSize = size === 'small' ? 107 : 152;\n\n  return (\n    <div\n      className={cn(\n        'relative flex flex-col items-center justify-center',\n        sizeClasses.container,\n        'rounded-lg',\n        className\n      )}\n    >\n      {/* Progress circle SVG */}\n      <svg\n        className=\"absolute inset-0 transform -rotate-90\"\n        width={svgSize}\n        height={svgSize}\n        viewBox={`0 0 ${svgSize} ${svgSize}`}\n        aria-hidden=\"true\"\n      >\n        {/* Background circle */}\n        <circle\n          cx={center}\n          cy={center}\n          r={radius}\n          fill=\"none\"\n          strokeWidth={sizeClasses.strokeWidth}\n          className={cn(trackClass, 'rounded-lg')}\n          style={trackColor ? { stroke: trackColor } : undefined}\n        />\n        {/* Progress circle - SVG stroke properties require style for animation */}\n        <circle\n          cx={center}\n          cy={center}\n          r={radius}\n          fill=\"none\"\n          strokeWidth={sizeClasses.strokeWidth}\n          strokeLinecap=\"round\"\n          strokeDasharray={circumference}\n          strokeDashoffset={strokeDashoffset}\n          className={cn(\n            fillClass,\n            'transition-all duration-500 ease-out shadow-soft-shadow-3 rounded-lg'\n          )}\n          style={fillColor ? { stroke: fillColor } : undefined}\n        />\n      </svg>\n\n      {/* Native progress element for accessibility */}\n      <progress\n        value={clampedValue}\n        max={max}\n        aria-label={typeof label === 'string' ? label : 'Progress'}\n        className=\"absolute opacity-0 w-0 h-0\"\n      />\n\n      {/* Content overlay - centered content */}\n      <div\n        className={cn(\n          'relative z-10 flex flex-col items-center justify-center',\n          sizeClasses.spacing,\n          sizeClasses.contentWidth\n        )}\n      >\n        {/* Percentage text */}\n        {showPercentage && (\n          <Text\n            size={sizeClasses.textSize}\n            weight={sizeClasses.textWeight}\n            className={cn(\n              'text-center w-full',\n              variantClasses.textColor,\n              percentageClassName\n            )}\n          >\n            {Math.round(percentage)}%\n          </Text>\n        )}\n\n        {/* Label text */}\n        {label && (\n          <Text\n            as=\"span\"\n            size={sizeClasses.labelSize}\n            weight={sizeClasses.labelWeight}\n            className={cn(\n              variantClasses.labelColor,\n              'text-center uppercase tracking-wide truncate w-full',\n              labelClassName\n            )}\n          >\n            {label}\n          </Text>\n        )}\n      </div>\n    </div>\n  );\n};\n\nexport default ProgressCircle;\n"],"mappings":"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","names":[]}