analytica-frontend-lib 1.2.44 → 1.2.45

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (134) hide show
  1. package/dist/Accordation/index.js.map +1 -1
  2. package/dist/Accordation/index.mjs.map +1 -1
  3. package/dist/ActivityCardQuestionBanks/index.js.map +1 -1
  4. package/dist/ActivityCardQuestionBanks/index.mjs.map +1 -1
  5. package/dist/ActivityCardQuestionPreview/index.js.map +1 -1
  6. package/dist/ActivityCardQuestionPreview/index.mjs.map +1 -1
  7. package/dist/ActivityDetails/index.d.ts.map +1 -1
  8. package/dist/ActivityDetails/index.js +59 -50
  9. package/dist/ActivityDetails/index.js.map +1 -1
  10. package/dist/ActivityDetails/index.mjs +59 -50
  11. package/dist/ActivityDetails/index.mjs.map +1 -1
  12. package/dist/ActivityFilters/index.js.map +1 -1
  13. package/dist/ActivityFilters/index.mjs.map +1 -1
  14. package/dist/ActivityPreview/index.js.map +1 -1
  15. package/dist/ActivityPreview/index.mjs.map +1 -1
  16. package/dist/Alert/index.js.map +1 -1
  17. package/dist/Alert/index.mjs.map +1 -1
  18. package/dist/AlertDialog/index.js.map +1 -1
  19. package/dist/AlertDialog/index.mjs.map +1 -1
  20. package/dist/AlertManager/index.js.map +1 -1
  21. package/dist/AlertManager/index.mjs.map +1 -1
  22. package/dist/AlertManagerView/index.js.map +1 -1
  23. package/dist/AlertManagerView/index.mjs.map +1 -1
  24. package/dist/Alternative/index.js.map +1 -1
  25. package/dist/Alternative/index.mjs.map +1 -1
  26. package/dist/Badge/index.js.map +1 -1
  27. package/dist/Badge/index.mjs.map +1 -1
  28. package/dist/BreadcrumbMenu/index.js.map +1 -1
  29. package/dist/BreadcrumbMenu/index.mjs.map +1 -1
  30. package/dist/Button/index.js.map +1 -1
  31. package/dist/Button/index.mjs.map +1 -1
  32. package/dist/Calendar/index.js.map +1 -1
  33. package/dist/Calendar/index.mjs.map +1 -1
  34. package/dist/Card/index.js.map +1 -1
  35. package/dist/Card/index.mjs.map +1 -1
  36. package/dist/CheckBox/index.js.map +1 -1
  37. package/dist/CheckBox/index.mjs.map +1 -1
  38. package/dist/Chips/index.js.map +1 -1
  39. package/dist/Chips/index.mjs.map +1 -1
  40. package/dist/CorrectActivityModal/index.js.map +1 -1
  41. package/dist/CorrectActivityModal/index.mjs.map +1 -1
  42. package/dist/Divider/index.js.map +1 -1
  43. package/dist/Divider/index.mjs.map +1 -1
  44. package/dist/DownloadButton/index.js.map +1 -1
  45. package/dist/DownloadButton/index.mjs.map +1 -1
  46. package/dist/DropdownMenu/index.js.map +1 -1
  47. package/dist/DropdownMenu/index.mjs.map +1 -1
  48. package/dist/EmptyState/index.js.map +1 -1
  49. package/dist/EmptyState/index.mjs.map +1 -1
  50. package/dist/FileAttachment/index.js.map +1 -1
  51. package/dist/FileAttachment/index.mjs.map +1 -1
  52. package/dist/IconButton/index.js.map +1 -1
  53. package/dist/IconButton/index.mjs.map +1 -1
  54. package/dist/IconRoundedButton/index.js.map +1 -1
  55. package/dist/IconRoundedButton/index.mjs.map +1 -1
  56. package/dist/LatexRenderer/index.js.map +1 -1
  57. package/dist/LatexRenderer/index.mjs.map +1 -1
  58. package/dist/Menu/index.js.map +1 -1
  59. package/dist/Menu/index.mjs.map +1 -1
  60. package/dist/Modal/index.js.map +1 -1
  61. package/dist/Modal/index.mjs.map +1 -1
  62. package/dist/MultipleChoice/index.js.map +1 -1
  63. package/dist/MultipleChoice/index.mjs.map +1 -1
  64. package/dist/NavButton/index.js.map +1 -1
  65. package/dist/NavButton/index.mjs.map +1 -1
  66. package/dist/NoSearchResult/index.js.map +1 -1
  67. package/dist/NoSearchResult/index.mjs.map +1 -1
  68. package/dist/NotFound/index.js.map +1 -1
  69. package/dist/NotFound/index.mjs.map +1 -1
  70. package/dist/NotificationCard/index.js.map +1 -1
  71. package/dist/NotificationCard/index.mjs.map +1 -1
  72. package/dist/ProgressBar/index.js.map +1 -1
  73. package/dist/ProgressBar/index.mjs.map +1 -1
  74. package/dist/ProgressCircle/index.js.map +1 -1
  75. package/dist/ProgressCircle/index.mjs.map +1 -1
  76. package/dist/Quiz/index.js.map +1 -1
  77. package/dist/Quiz/index.mjs.map +1 -1
  78. package/dist/Radio/index.js.map +1 -1
  79. package/dist/Radio/index.mjs.map +1 -1
  80. package/dist/Search/index.js.map +1 -1
  81. package/dist/Search/index.mjs.map +1 -1
  82. package/dist/Select/index.js.map +1 -1
  83. package/dist/Select/index.mjs.map +1 -1
  84. package/dist/SelectionButton/index.js.map +1 -1
  85. package/dist/SelectionButton/index.mjs.map +1 -1
  86. package/dist/SendActivityModal/index.js.map +1 -1
  87. package/dist/SendActivityModal/index.mjs.map +1 -1
  88. package/dist/Skeleton/index.js.map +1 -1
  89. package/dist/Skeleton/index.mjs.map +1 -1
  90. package/dist/StatisticsCard/index.js.map +1 -1
  91. package/dist/StatisticsCard/index.mjs.map +1 -1
  92. package/dist/Stepper/index.js.map +1 -1
  93. package/dist/Stepper/index.mjs.map +1 -1
  94. package/dist/Support/TicketModal/index.js.map +1 -1
  95. package/dist/Support/TicketModal/index.mjs.map +1 -1
  96. package/dist/Support/index.js.map +1 -1
  97. package/dist/Support/index.mjs.map +1 -1
  98. package/dist/Table/TablePagination/index.js.map +1 -1
  99. package/dist/Table/TablePagination/index.mjs.map +1 -1
  100. package/dist/Table/index.js.map +1 -1
  101. package/dist/Table/index.mjs.map +1 -1
  102. package/dist/TableProvider/index.js.map +1 -1
  103. package/dist/TableProvider/index.mjs.map +1 -1
  104. package/dist/Text/index.js.map +1 -1
  105. package/dist/Text/index.mjs.map +1 -1
  106. package/dist/TextArea/index.js.map +1 -1
  107. package/dist/TextArea/index.mjs.map +1 -1
  108. package/dist/ThemeToggle/index.js.map +1 -1
  109. package/dist/ThemeToggle/index.mjs.map +1 -1
  110. package/dist/Toast/Toaster/index.js.map +1 -1
  111. package/dist/Toast/Toaster/index.mjs.map +1 -1
  112. package/dist/Toast/index.js.map +1 -1
  113. package/dist/Toast/index.mjs.map +1 -1
  114. package/dist/VideoPlayer/index.js.map +1 -1
  115. package/dist/VideoPlayer/index.mjs.map +1 -1
  116. package/dist/Whiteboard/index.js.map +1 -1
  117. package/dist/Whiteboard/index.mjs.map +1 -1
  118. package/dist/index.d.ts +2 -1
  119. package/dist/index.d.ts.map +1 -1
  120. package/dist/index.js +62 -55
  121. package/dist/index.js.map +1 -1
  122. package/dist/index.mjs +62 -55
  123. package/dist/index.mjs.map +1 -1
  124. package/dist/types/activityDetails.d.ts +0 -24
  125. package/dist/types/activityDetails.d.ts.map +1 -1
  126. package/dist/utils/activityDetailsUtils.d.ts +30 -0
  127. package/dist/utils/activityDetailsUtils.d.ts.map +1 -0
  128. package/dist/utils/index.d.ts +1 -0
  129. package/dist/utils/index.d.ts.map +1 -1
  130. package/dist/utils/index.js +65 -0
  131. package/dist/utils/index.js.map +1 -1
  132. package/dist/utils/index.mjs +61 -0
  133. package/dist/utils/index.mjs.map +1 -1
  134. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/components/Skeleton/Skeleton.tsx","../../src/utils/utils.ts"],"sourcesContent":["import { forwardRef, HTMLAttributes, CSSProperties } from 'react';\nimport { cn } from '../../utils/utils';\n\ninterface SkeletonProps extends HTMLAttributes<HTMLDivElement> {\n variant?: 'text' | 'circular' | 'rectangular' | 'rounded';\n width?: string | number;\n height?: string | number;\n animation?: 'pulse' | 'none';\n lines?: number;\n spacing?: 'none' | 'small' | 'medium' | 'large';\n}\n\nconst SKELETON_ANIMATION_CLASSES = {\n pulse: 'animate-pulse',\n none: '',\n};\n\nconst SKELETON_VARIANT_CLASSES = {\n text: 'h-4 bg-background-200 rounded',\n circular: 'bg-background-200 rounded-full',\n rectangular: 'bg-background-200',\n rounded: 'bg-background-200 rounded-lg',\n};\n\nconst SPACING_CLASSES = {\n none: '',\n small: 'space-y-1',\n medium: 'space-y-2',\n large: 'space-y-3',\n};\n\nconst Skeleton = forwardRef<HTMLDivElement, SkeletonProps>(\n (\n {\n variant = 'text',\n width,\n height,\n animation = 'pulse',\n lines = 1,\n spacing = 'none',\n className = '',\n children,\n ...props\n },\n ref\n ) => {\n const animationClass = SKELETON_ANIMATION_CLASSES[animation];\n const variantClass = SKELETON_VARIANT_CLASSES[variant];\n const spacingClass = SPACING_CLASSES[spacing];\n\n const style: CSSProperties = {\n width: typeof width === 'number' ? `${width}px` : width,\n height: typeof height === 'number' ? `${height}px` : height,\n };\n\n // Se for múltiplas linhas de texto\n if (variant === 'text' && lines > 1) {\n return (\n <div\n ref={ref}\n className={cn('flex flex-col', spacingClass, className)}\n {...props}\n >\n {Array.from({ length: lines }, (_, index) => (\n <div\n key={index}\n className={cn(variantClass, animationClass)}\n style={index === lines - 1 ? { width: '60%' } : undefined}\n />\n ))}\n </div>\n );\n }\n\n // Se for um único elemento\n return (\n <div\n ref={ref}\n className={cn(variantClass, animationClass, className)}\n style={style}\n {...props}\n >\n {children}\n </div>\n );\n }\n);\n\n// Componentes específicos para casos comuns\nconst SkeletonText = forwardRef<HTMLDivElement, Omit<SkeletonProps, 'variant'>>(\n (props, ref) => <Skeleton ref={ref} variant=\"text\" {...props} />\n);\n\nconst SkeletonCircle = forwardRef<\n HTMLDivElement,\n Omit<SkeletonProps, 'variant'>\n>((props, ref) => <Skeleton ref={ref} variant=\"circular\" {...props} />);\n\nconst SkeletonRectangle = forwardRef<\n HTMLDivElement,\n Omit<SkeletonProps, 'variant'>\n>((props, ref) => <Skeleton ref={ref} variant=\"rectangular\" {...props} />);\n\nconst SkeletonRounded = forwardRef<\n HTMLDivElement,\n Omit<SkeletonProps, 'variant'>\n>((props, ref) => <Skeleton ref={ref} variant=\"rounded\" {...props} />);\n\n// Componente para card skeleton\ninterface SkeletonCardProps extends HTMLAttributes<HTMLDivElement> {\n showAvatar?: boolean;\n showTitle?: boolean;\n showDescription?: boolean;\n showActions?: boolean;\n lines?: number;\n}\n\nconst SkeletonCard = forwardRef<HTMLDivElement, SkeletonCardProps>(\n (\n {\n showAvatar = true,\n showTitle = true,\n showDescription = true,\n showActions = true,\n lines = 2,\n className = '',\n ...props\n },\n ref\n ) => {\n return (\n <div\n ref={ref}\n className={cn(\n 'w-full p-4 bg-background border border-border-200 rounded-lg',\n className\n )}\n {...props}\n >\n <div className=\"flex items-start space-x-3\">\n {showAvatar && <SkeletonCircle width={40} height={40} />}\n\n <div className=\"flex-1 space-y-2\">\n {showTitle && <SkeletonText width=\"60%\" height={20} />}\n\n {showDescription && <SkeletonText lines={lines} spacing=\"small\" />}\n </div>\n </div>\n\n {showActions && (\n <div className=\"flex justify-end space-x-2 mt-4\">\n <SkeletonRectangle width={80} height={32} />\n <SkeletonRectangle width={80} height={32} />\n </div>\n )}\n </div>\n );\n }\n);\n\n// Componente para lista skeleton\ninterface SkeletonListProps extends HTMLAttributes<HTMLDivElement> {\n items?: number;\n showAvatar?: boolean;\n showTitle?: boolean;\n showDescription?: boolean;\n lines?: number;\n}\n\nconst SkeletonList = forwardRef<HTMLDivElement, SkeletonListProps>(\n (\n {\n items = 3,\n showAvatar = true,\n showTitle = true,\n showDescription = true,\n lines = 1,\n className = '',\n ...props\n },\n ref\n ) => {\n return (\n <div ref={ref} className={cn('space-y-3', className)} {...props}>\n {Array.from({ length: items }, (_, index) => (\n <div key={index} className=\"flex items-start space-x-3 p-3\">\n {showAvatar && <SkeletonCircle width={32} height={32} />}\n\n <div className=\"flex-1 space-y-2\">\n {showTitle && <SkeletonText width=\"40%\" height={16} />}\n\n {showDescription && (\n <SkeletonText lines={lines} spacing=\"small\" />\n )}\n </div>\n </div>\n ))}\n </div>\n );\n }\n);\n\n// Componente para tabela skeleton\ninterface SkeletonTableProps extends HTMLAttributes<HTMLDivElement> {\n rows?: number;\n columns?: number;\n showHeader?: boolean;\n}\n\nconst SkeletonTable = forwardRef<HTMLDivElement, SkeletonTableProps>(\n (\n { rows = 5, columns = 4, showHeader = true, className = '', ...props },\n ref\n ) => {\n return (\n <div ref={ref} className={cn('w-full', className)} {...props}>\n {showHeader && (\n <div className=\"flex space-x-2 mb-3\">\n {Array.from({ length: columns }, (_, index) => (\n <SkeletonText\n key={index}\n width={`${100 / columns}%`}\n height={20}\n />\n ))}\n </div>\n )}\n\n <div className=\"space-y-2\">\n {Array.from({ length: rows }, (_, rowIndex) => (\n <div key={rowIndex} className=\"flex space-x-2\">\n {Array.from({ length: columns }, (_, colIndex) => (\n <SkeletonText\n key={colIndex}\n width={`${100 / columns}%`}\n height={16}\n />\n ))}\n </div>\n ))}\n </div>\n </div>\n );\n }\n);\n\nexport {\n Skeleton,\n SkeletonText,\n SkeletonCircle,\n SkeletonRectangle,\n SkeletonRounded,\n SkeletonCard,\n SkeletonList,\n SkeletonTable,\n};\n","import { clsx, type ClassValue } from 'clsx';\nimport { twMerge } from 'tailwind-merge';\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs));\n}\n\nexport { syncDropdownState } from './dropdown';\nexport {\n getSelectedIdsFromCategories,\n toggleArrayItem,\n toggleSingleValue,\n} from './activityFilters';\n\n/**\n * Retorna a cor hexadecimal com opacidade 0.3 (4d) se não estiver em dark mode.\n * Se estiver em dark mode, retorna a cor original.\n *\n * @param hexColor - Cor hexadecimal (ex: \"#0066b8\" ou \"0066b8\")\n * @param isDark - booleano indicando se está em dark mode\n * @returns string - cor hexadecimal com opacidade se necessário\n */\nexport function getSubjectColorWithOpacity(\n hexColor: string | undefined,\n isDark: boolean\n): string | undefined {\n if (!hexColor) return undefined;\n // Remove o '#' se existir\n let color = hexColor.replace(/^#/, '').toLowerCase();\n\n if (isDark) {\n // Se está em dark mode, sempre remove opacidade se existir\n if (color.length === 8) {\n color = color.slice(0, 6);\n }\n return `#${color}`;\n } else {\n // Se não está em dark mode (light mode)\n let resultColor: string;\n if (color.length === 6) {\n // Adiciona opacidade 0.3 (4D) para cores de 6 dígitos\n resultColor = `#${color}4d`;\n } else if (color.length === 8) {\n // Já tem opacidade, retorna como está\n resultColor = `#${color}`;\n } else {\n // Para outros tamanhos (3, 4, 5 dígitos), retorna como está\n resultColor = `#${color}`;\n }\n return resultColor;\n }\n}\n"],"mappings":"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","names":["_"]}
1
+ {"version":3,"sources":["../../src/components/Skeleton/Skeleton.tsx","../../src/utils/utils.ts"],"sourcesContent":["import { forwardRef, HTMLAttributes, CSSProperties } from 'react';\nimport { cn } from '../../utils/utils';\n\ninterface SkeletonProps extends HTMLAttributes<HTMLDivElement> {\n variant?: 'text' | 'circular' | 'rectangular' | 'rounded';\n width?: string | number;\n height?: string | number;\n animation?: 'pulse' | 'none';\n lines?: number;\n spacing?: 'none' | 'small' | 'medium' | 'large';\n}\n\nconst SKELETON_ANIMATION_CLASSES = {\n pulse: 'animate-pulse',\n none: '',\n};\n\nconst SKELETON_VARIANT_CLASSES = {\n text: 'h-4 bg-background-200 rounded',\n circular: 'bg-background-200 rounded-full',\n rectangular: 'bg-background-200',\n rounded: 'bg-background-200 rounded-lg',\n};\n\nconst SPACING_CLASSES = {\n none: '',\n small: 'space-y-1',\n medium: 'space-y-2',\n large: 'space-y-3',\n};\n\nconst Skeleton = forwardRef<HTMLDivElement, SkeletonProps>(\n (\n {\n variant = 'text',\n width,\n height,\n animation = 'pulse',\n lines = 1,\n spacing = 'none',\n className = '',\n children,\n ...props\n },\n ref\n ) => {\n const animationClass = SKELETON_ANIMATION_CLASSES[animation];\n const variantClass = SKELETON_VARIANT_CLASSES[variant];\n const spacingClass = SPACING_CLASSES[spacing];\n\n const style: CSSProperties = {\n width: typeof width === 'number' ? `${width}px` : width,\n height: typeof height === 'number' ? `${height}px` : height,\n };\n\n // Se for múltiplas linhas de texto\n if (variant === 'text' && lines > 1) {\n return (\n <div\n ref={ref}\n className={cn('flex flex-col', spacingClass, className)}\n {...props}\n >\n {Array.from({ length: lines }, (_, index) => (\n <div\n key={index}\n className={cn(variantClass, animationClass)}\n style={index === lines - 1 ? { width: '60%' } : undefined}\n />\n ))}\n </div>\n );\n }\n\n // Se for um único elemento\n return (\n <div\n ref={ref}\n className={cn(variantClass, animationClass, className)}\n style={style}\n {...props}\n >\n {children}\n </div>\n );\n }\n);\n\n// Componentes específicos para casos comuns\nconst SkeletonText = forwardRef<HTMLDivElement, Omit<SkeletonProps, 'variant'>>(\n (props, ref) => <Skeleton ref={ref} variant=\"text\" {...props} />\n);\n\nconst SkeletonCircle = forwardRef<\n HTMLDivElement,\n Omit<SkeletonProps, 'variant'>\n>((props, ref) => <Skeleton ref={ref} variant=\"circular\" {...props} />);\n\nconst SkeletonRectangle = forwardRef<\n HTMLDivElement,\n Omit<SkeletonProps, 'variant'>\n>((props, ref) => <Skeleton ref={ref} variant=\"rectangular\" {...props} />);\n\nconst SkeletonRounded = forwardRef<\n HTMLDivElement,\n Omit<SkeletonProps, 'variant'>\n>((props, ref) => <Skeleton ref={ref} variant=\"rounded\" {...props} />);\n\n// Componente para card skeleton\ninterface SkeletonCardProps extends HTMLAttributes<HTMLDivElement> {\n showAvatar?: boolean;\n showTitle?: boolean;\n showDescription?: boolean;\n showActions?: boolean;\n lines?: number;\n}\n\nconst SkeletonCard = forwardRef<HTMLDivElement, SkeletonCardProps>(\n (\n {\n showAvatar = true,\n showTitle = true,\n showDescription = true,\n showActions = true,\n lines = 2,\n className = '',\n ...props\n },\n ref\n ) => {\n return (\n <div\n ref={ref}\n className={cn(\n 'w-full p-4 bg-background border border-border-200 rounded-lg',\n className\n )}\n {...props}\n >\n <div className=\"flex items-start space-x-3\">\n {showAvatar && <SkeletonCircle width={40} height={40} />}\n\n <div className=\"flex-1 space-y-2\">\n {showTitle && <SkeletonText width=\"60%\" height={20} />}\n\n {showDescription && <SkeletonText lines={lines} spacing=\"small\" />}\n </div>\n </div>\n\n {showActions && (\n <div className=\"flex justify-end space-x-2 mt-4\">\n <SkeletonRectangle width={80} height={32} />\n <SkeletonRectangle width={80} height={32} />\n </div>\n )}\n </div>\n );\n }\n);\n\n// Componente para lista skeleton\ninterface SkeletonListProps extends HTMLAttributes<HTMLDivElement> {\n items?: number;\n showAvatar?: boolean;\n showTitle?: boolean;\n showDescription?: boolean;\n lines?: number;\n}\n\nconst SkeletonList = forwardRef<HTMLDivElement, SkeletonListProps>(\n (\n {\n items = 3,\n showAvatar = true,\n showTitle = true,\n showDescription = true,\n lines = 1,\n className = '',\n ...props\n },\n ref\n ) => {\n return (\n <div ref={ref} className={cn('space-y-3', className)} {...props}>\n {Array.from({ length: items }, (_, index) => (\n <div key={index} className=\"flex items-start space-x-3 p-3\">\n {showAvatar && <SkeletonCircle width={32} height={32} />}\n\n <div className=\"flex-1 space-y-2\">\n {showTitle && <SkeletonText width=\"40%\" height={16} />}\n\n {showDescription && (\n <SkeletonText lines={lines} spacing=\"small\" />\n )}\n </div>\n </div>\n ))}\n </div>\n );\n }\n);\n\n// Componente para tabela skeleton\ninterface SkeletonTableProps extends HTMLAttributes<HTMLDivElement> {\n rows?: number;\n columns?: number;\n showHeader?: boolean;\n}\n\nconst SkeletonTable = forwardRef<HTMLDivElement, SkeletonTableProps>(\n (\n { rows = 5, columns = 4, showHeader = true, className = '', ...props },\n ref\n ) => {\n return (\n <div ref={ref} className={cn('w-full', className)} {...props}>\n {showHeader && (\n <div className=\"flex space-x-2 mb-3\">\n {Array.from({ length: columns }, (_, index) => (\n <SkeletonText\n key={index}\n width={`${100 / columns}%`}\n height={20}\n />\n ))}\n </div>\n )}\n\n <div className=\"space-y-2\">\n {Array.from({ length: rows }, (_, rowIndex) => (\n <div key={rowIndex} className=\"flex space-x-2\">\n {Array.from({ length: columns }, (_, colIndex) => (\n <SkeletonText\n key={colIndex}\n width={`${100 / columns}%`}\n height={16}\n />\n ))}\n </div>\n ))}\n </div>\n </div>\n );\n }\n);\n\nexport {\n Skeleton,\n SkeletonText,\n SkeletonCircle,\n SkeletonRectangle,\n SkeletonRounded,\n SkeletonCard,\n SkeletonList,\n SkeletonTable,\n};\n","import { clsx, type ClassValue } from 'clsx';\nimport { twMerge } from 'tailwind-merge';\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs));\n}\n\nexport { syncDropdownState } from './dropdown';\nexport {\n getSelectedIdsFromCategories,\n toggleArrayItem,\n toggleSingleValue,\n} from './activityFilters';\nexport {\n getStatusBadgeConfig,\n formatTimeSpent,\n formatQuestionNumbers,\n formatDateToBrazilian,\n} from './activityDetailsUtils';\n\n/**\n * Retorna a cor hexadecimal com opacidade 0.3 (4d) se não estiver em dark mode.\n * Se estiver em dark mode, retorna a cor original.\n *\n * @param hexColor - Cor hexadecimal (ex: \"#0066b8\" ou \"0066b8\")\n * @param isDark - booleano indicando se está em dark mode\n * @returns string - cor hexadecimal com opacidade se necessário\n */\nexport function getSubjectColorWithOpacity(\n hexColor: string | undefined,\n isDark: boolean\n): string | undefined {\n if (!hexColor) return undefined;\n // Remove o '#' se existir\n let color = hexColor.replace(/^#/, '').toLowerCase();\n\n if (isDark) {\n // Se está em dark mode, sempre remove opacidade se existir\n if (color.length === 8) {\n color = color.slice(0, 6);\n }\n return `#${color}`;\n } else {\n // Se não está em dark mode (light mode)\n let resultColor: string;\n if (color.length === 6) {\n // Adiciona opacidade 0.3 (4D) para cores de 6 dígitos\n resultColor = `#${color}4d`;\n } else if (color.length === 8) {\n // Já tem opacidade, retorna como está\n resultColor = `#${color}`;\n } else {\n // Para outros tamanhos (3, 4, 5 dígitos), retorna como está\n resultColor = `#${color}`;\n }\n return resultColor;\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,mBAA0D;;;ACA1D,kBAAsC;AACtC,4BAAwB;AAEjB,SAAS,MAAM,QAAsB;AAC1C,aAAO,mCAAQ,kBAAK,MAAM,CAAC;AAC7B;;;AD2DY;AApDZ,IAAM,6BAA6B;AAAA,EACjC,OAAO;AAAA,EACP,MAAM;AACR;AAEA,IAAM,2BAA2B;AAAA,EAC/B,MAAM;AAAA,EACN,UAAU;AAAA,EACV,aAAa;AAAA,EACb,SAAS;AACX;AAEA,IAAM,kBAAkB;AAAA,EACtB,MAAM;AAAA,EACN,OAAO;AAAA,EACP,QAAQ;AAAA,EACR,OAAO;AACT;AAEA,IAAM,eAAW;AAAA,EACf,CACE;AAAA,IACE,UAAU;AAAA,IACV;AAAA,IACA;AAAA,IACA,YAAY;AAAA,IACZ,QAAQ;AAAA,IACR,UAAU;AAAA,IACV,YAAY;AAAA,IACZ;AAAA,IACA,GAAG;AAAA,EACL,GACA,QACG;AACH,UAAM,iBAAiB,2BAA2B,SAAS;AAC3D,UAAM,eAAe,yBAAyB,OAAO;AACrD,UAAM,eAAe,gBAAgB,OAAO;AAE5C,UAAM,QAAuB;AAAA,MAC3B,OAAO,OAAO,UAAU,WAAW,GAAG,KAAK,OAAO;AAAA,MAClD,QAAQ,OAAO,WAAW,WAAW,GAAG,MAAM,OAAO;AAAA,IACvD;AAGA,QAAI,YAAY,UAAU,QAAQ,GAAG;AACnC,aACE;AAAA,QAAC;AAAA;AAAA,UACC;AAAA,UACA,WAAW,GAAG,iBAAiB,cAAc,SAAS;AAAA,UACrD,GAAG;AAAA,UAEH,gBAAM,KAAK,EAAE,QAAQ,MAAM,GAAG,CAAC,GAAG,UACjC;AAAA,YAAC;AAAA;AAAA,cAEC,WAAW,GAAG,cAAc,cAAc;AAAA,cAC1C,OAAO,UAAU,QAAQ,IAAI,EAAE,OAAO,MAAM,IAAI;AAAA;AAAA,YAF3C;AAAA,UAGP,CACD;AAAA;AAAA,MACH;AAAA,IAEJ;AAGA,WACE;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA,WAAW,GAAG,cAAc,gBAAgB,SAAS;AAAA,QACrD;AAAA,QACC,GAAG;AAAA,QAEH;AAAA;AAAA,IACH;AAAA,EAEJ;AACF;AAGA,IAAM,mBAAe;AAAA,EACnB,CAAC,OAAO,QAAQ,4CAAC,YAAS,KAAU,SAAQ,QAAQ,GAAG,OAAO;AAChE;AAEA,IAAM,qBAAiB,yBAGrB,CAAC,OAAO,QAAQ,4CAAC,YAAS,KAAU,SAAQ,YAAY,GAAG,OAAO,CAAE;AAEtE,IAAM,wBAAoB,yBAGxB,CAAC,OAAO,QAAQ,4CAAC,YAAS,KAAU,SAAQ,eAAe,GAAG,OAAO,CAAE;AAEzE,IAAM,sBAAkB,yBAGtB,CAAC,OAAO,QAAQ,4CAAC,YAAS,KAAU,SAAQ,WAAW,GAAG,OAAO,CAAE;AAWrE,IAAM,mBAAe;AAAA,EACnB,CACE;AAAA,IACE,aAAa;AAAA,IACb,YAAY;AAAA,IACZ,kBAAkB;AAAA,IAClB,cAAc;AAAA,IACd,QAAQ;AAAA,IACR,YAAY;AAAA,IACZ,GAAG;AAAA,EACL,GACA,QACG;AACH,WACE;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA,WAAW;AAAA,UACT;AAAA,UACA;AAAA,QACF;AAAA,QACC,GAAG;AAAA,QAEJ;AAAA,uDAAC,SAAI,WAAU,8BACZ;AAAA,0BAAc,4CAAC,kBAAe,OAAO,IAAI,QAAQ,IAAI;AAAA,YAEtD,6CAAC,SAAI,WAAU,oBACZ;AAAA,2BAAa,4CAAC,gBAAa,OAAM,OAAM,QAAQ,IAAI;AAAA,cAEnD,mBAAmB,4CAAC,gBAAa,OAAc,SAAQ,SAAQ;AAAA,eAClE;AAAA,aACF;AAAA,UAEC,eACC,6CAAC,SAAI,WAAU,mCACb;AAAA,wDAAC,qBAAkB,OAAO,IAAI,QAAQ,IAAI;AAAA,YAC1C,4CAAC,qBAAkB,OAAO,IAAI,QAAQ,IAAI;AAAA,aAC5C;AAAA;AAAA;AAAA,IAEJ;AAAA,EAEJ;AACF;AAWA,IAAM,mBAAe;AAAA,EACnB,CACE;AAAA,IACE,QAAQ;AAAA,IACR,aAAa;AAAA,IACb,YAAY;AAAA,IACZ,kBAAkB;AAAA,IAClB,QAAQ;AAAA,IACR,YAAY;AAAA,IACZ,GAAG;AAAA,EACL,GACA,QACG;AACH,WACE,4CAAC,SAAI,KAAU,WAAW,GAAG,aAAa,SAAS,GAAI,GAAG,OACvD,gBAAM,KAAK,EAAE,QAAQ,MAAM,GAAG,CAAC,GAAG,UACjC,6CAAC,SAAgB,WAAU,kCACxB;AAAA,oBAAc,4CAAC,kBAAe,OAAO,IAAI,QAAQ,IAAI;AAAA,MAEtD,6CAAC,SAAI,WAAU,oBACZ;AAAA,qBAAa,4CAAC,gBAAa,OAAM,OAAM,QAAQ,IAAI;AAAA,QAEnD,mBACC,4CAAC,gBAAa,OAAc,SAAQ,SAAQ;AAAA,SAEhD;AAAA,SATQ,KAUV,CACD,GACH;AAAA,EAEJ;AACF;AASA,IAAM,oBAAgB;AAAA,EACpB,CACE,EAAE,OAAO,GAAG,UAAU,GAAG,aAAa,MAAM,YAAY,IAAI,GAAG,MAAM,GACrE,QACG;AACH,WACE,6CAAC,SAAI,KAAU,WAAW,GAAG,UAAU,SAAS,GAAI,GAAG,OACpD;AAAA,oBACC,4CAAC,SAAI,WAAU,uBACZ,gBAAM,KAAK,EAAE,QAAQ,QAAQ,GAAG,CAAC,GAAG,UACnC;AAAA,QAAC;AAAA;AAAA,UAEC,OAAO,GAAG,MAAM,OAAO;AAAA,UACvB,QAAQ;AAAA;AAAA,QAFH;AAAA,MAGP,CACD,GACH;AAAA,MAGF,4CAAC,SAAI,WAAU,aACZ,gBAAM,KAAK,EAAE,QAAQ,KAAK,GAAG,CAAC,GAAG,aAChC,4CAAC,SAAmB,WAAU,kBAC3B,gBAAM,KAAK,EAAE,QAAQ,QAAQ,GAAG,CAACA,IAAG,aACnC;AAAA,QAAC;AAAA;AAAA,UAEC,OAAO,GAAG,MAAM,OAAO;AAAA,UACvB,QAAQ;AAAA;AAAA,QAFH;AAAA,MAGP,CACD,KAPO,QAQV,CACD,GACH;AAAA,OACF;AAAA,EAEJ;AACF;","names":["_"]}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/components/Skeleton/Skeleton.tsx","../../src/utils/utils.ts"],"sourcesContent":["import { forwardRef, HTMLAttributes, CSSProperties } from 'react';\nimport { cn } from '../../utils/utils';\n\ninterface SkeletonProps extends HTMLAttributes<HTMLDivElement> {\n variant?: 'text' | 'circular' | 'rectangular' | 'rounded';\n width?: string | number;\n height?: string | number;\n animation?: 'pulse' | 'none';\n lines?: number;\n spacing?: 'none' | 'small' | 'medium' | 'large';\n}\n\nconst SKELETON_ANIMATION_CLASSES = {\n pulse: 'animate-pulse',\n none: '',\n};\n\nconst SKELETON_VARIANT_CLASSES = {\n text: 'h-4 bg-background-200 rounded',\n circular: 'bg-background-200 rounded-full',\n rectangular: 'bg-background-200',\n rounded: 'bg-background-200 rounded-lg',\n};\n\nconst SPACING_CLASSES = {\n none: '',\n small: 'space-y-1',\n medium: 'space-y-2',\n large: 'space-y-3',\n};\n\nconst Skeleton = forwardRef<HTMLDivElement, SkeletonProps>(\n (\n {\n variant = 'text',\n width,\n height,\n animation = 'pulse',\n lines = 1,\n spacing = 'none',\n className = '',\n children,\n ...props\n },\n ref\n ) => {\n const animationClass = SKELETON_ANIMATION_CLASSES[animation];\n const variantClass = SKELETON_VARIANT_CLASSES[variant];\n const spacingClass = SPACING_CLASSES[spacing];\n\n const style: CSSProperties = {\n width: typeof width === 'number' ? `${width}px` : width,\n height: typeof height === 'number' ? `${height}px` : height,\n };\n\n // Se for múltiplas linhas de texto\n if (variant === 'text' && lines > 1) {\n return (\n <div\n ref={ref}\n className={cn('flex flex-col', spacingClass, className)}\n {...props}\n >\n {Array.from({ length: lines }, (_, index) => (\n <div\n key={index}\n className={cn(variantClass, animationClass)}\n style={index === lines - 1 ? { width: '60%' } : undefined}\n />\n ))}\n </div>\n );\n }\n\n // Se for um único elemento\n return (\n <div\n ref={ref}\n className={cn(variantClass, animationClass, className)}\n style={style}\n {...props}\n >\n {children}\n </div>\n );\n }\n);\n\n// Componentes específicos para casos comuns\nconst SkeletonText = forwardRef<HTMLDivElement, Omit<SkeletonProps, 'variant'>>(\n (props, ref) => <Skeleton ref={ref} variant=\"text\" {...props} />\n);\n\nconst SkeletonCircle = forwardRef<\n HTMLDivElement,\n Omit<SkeletonProps, 'variant'>\n>((props, ref) => <Skeleton ref={ref} variant=\"circular\" {...props} />);\n\nconst SkeletonRectangle = forwardRef<\n HTMLDivElement,\n Omit<SkeletonProps, 'variant'>\n>((props, ref) => <Skeleton ref={ref} variant=\"rectangular\" {...props} />);\n\nconst SkeletonRounded = forwardRef<\n HTMLDivElement,\n Omit<SkeletonProps, 'variant'>\n>((props, ref) => <Skeleton ref={ref} variant=\"rounded\" {...props} />);\n\n// Componente para card skeleton\ninterface SkeletonCardProps extends HTMLAttributes<HTMLDivElement> {\n showAvatar?: boolean;\n showTitle?: boolean;\n showDescription?: boolean;\n showActions?: boolean;\n lines?: number;\n}\n\nconst SkeletonCard = forwardRef<HTMLDivElement, SkeletonCardProps>(\n (\n {\n showAvatar = true,\n showTitle = true,\n showDescription = true,\n showActions = true,\n lines = 2,\n className = '',\n ...props\n },\n ref\n ) => {\n return (\n <div\n ref={ref}\n className={cn(\n 'w-full p-4 bg-background border border-border-200 rounded-lg',\n className\n )}\n {...props}\n >\n <div className=\"flex items-start space-x-3\">\n {showAvatar && <SkeletonCircle width={40} height={40} />}\n\n <div className=\"flex-1 space-y-2\">\n {showTitle && <SkeletonText width=\"60%\" height={20} />}\n\n {showDescription && <SkeletonText lines={lines} spacing=\"small\" />}\n </div>\n </div>\n\n {showActions && (\n <div className=\"flex justify-end space-x-2 mt-4\">\n <SkeletonRectangle width={80} height={32} />\n <SkeletonRectangle width={80} height={32} />\n </div>\n )}\n </div>\n );\n }\n);\n\n// Componente para lista skeleton\ninterface SkeletonListProps extends HTMLAttributes<HTMLDivElement> {\n items?: number;\n showAvatar?: boolean;\n showTitle?: boolean;\n showDescription?: boolean;\n lines?: number;\n}\n\nconst SkeletonList = forwardRef<HTMLDivElement, SkeletonListProps>(\n (\n {\n items = 3,\n showAvatar = true,\n showTitle = true,\n showDescription = true,\n lines = 1,\n className = '',\n ...props\n },\n ref\n ) => {\n return (\n <div ref={ref} className={cn('space-y-3', className)} {...props}>\n {Array.from({ length: items }, (_, index) => (\n <div key={index} className=\"flex items-start space-x-3 p-3\">\n {showAvatar && <SkeletonCircle width={32} height={32} />}\n\n <div className=\"flex-1 space-y-2\">\n {showTitle && <SkeletonText width=\"40%\" height={16} />}\n\n {showDescription && (\n <SkeletonText lines={lines} spacing=\"small\" />\n )}\n </div>\n </div>\n ))}\n </div>\n );\n }\n);\n\n// Componente para tabela skeleton\ninterface SkeletonTableProps extends HTMLAttributes<HTMLDivElement> {\n rows?: number;\n columns?: number;\n showHeader?: boolean;\n}\n\nconst SkeletonTable = forwardRef<HTMLDivElement, SkeletonTableProps>(\n (\n { rows = 5, columns = 4, showHeader = true, className = '', ...props },\n ref\n ) => {\n return (\n <div ref={ref} className={cn('w-full', className)} {...props}>\n {showHeader && (\n <div className=\"flex space-x-2 mb-3\">\n {Array.from({ length: columns }, (_, index) => (\n <SkeletonText\n key={index}\n width={`${100 / columns}%`}\n height={20}\n />\n ))}\n </div>\n )}\n\n <div className=\"space-y-2\">\n {Array.from({ length: rows }, (_, rowIndex) => (\n <div key={rowIndex} className=\"flex space-x-2\">\n {Array.from({ length: columns }, (_, colIndex) => (\n <SkeletonText\n key={colIndex}\n width={`${100 / columns}%`}\n height={16}\n />\n ))}\n </div>\n ))}\n </div>\n </div>\n );\n }\n);\n\nexport {\n Skeleton,\n SkeletonText,\n SkeletonCircle,\n SkeletonRectangle,\n SkeletonRounded,\n SkeletonCard,\n SkeletonList,\n SkeletonTable,\n};\n","import { clsx, type ClassValue } from 'clsx';\nimport { twMerge } from 'tailwind-merge';\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs));\n}\n\nexport { syncDropdownState } from './dropdown';\nexport {\n getSelectedIdsFromCategories,\n toggleArrayItem,\n toggleSingleValue,\n} from './activityFilters';\n\n/**\n * Retorna a cor hexadecimal com opacidade 0.3 (4d) se não estiver em dark mode.\n * Se estiver em dark mode, retorna a cor original.\n *\n * @param hexColor - Cor hexadecimal (ex: \"#0066b8\" ou \"0066b8\")\n * @param isDark - booleano indicando se está em dark mode\n * @returns string - cor hexadecimal com opacidade se necessário\n */\nexport function getSubjectColorWithOpacity(\n hexColor: string | undefined,\n isDark: boolean\n): string | undefined {\n if (!hexColor) return undefined;\n // Remove o '#' se existir\n let color = hexColor.replace(/^#/, '').toLowerCase();\n\n if (isDark) {\n // Se está em dark mode, sempre remove opacidade se existir\n if (color.length === 8) {\n color = color.slice(0, 6);\n }\n return `#${color}`;\n } else {\n // Se não está em dark mode (light mode)\n let resultColor: string;\n if (color.length === 6) {\n // Adiciona opacidade 0.3 (4D) para cores de 6 dígitos\n resultColor = `#${color}4d`;\n } else if (color.length === 8) {\n // Já tem opacidade, retorna como está\n resultColor = `#${color}`;\n } else {\n // Para outros tamanhos (3, 4, 5 dígitos), retorna como está\n resultColor = `#${color}`;\n }\n return resultColor;\n }\n}\n"],"mappings":"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","names":["_"]}
1
+ {"version":3,"sources":["../../src/components/Skeleton/Skeleton.tsx","../../src/utils/utils.ts"],"sourcesContent":["import { forwardRef, HTMLAttributes, CSSProperties } from 'react';\nimport { cn } from '../../utils/utils';\n\ninterface SkeletonProps extends HTMLAttributes<HTMLDivElement> {\n variant?: 'text' | 'circular' | 'rectangular' | 'rounded';\n width?: string | number;\n height?: string | number;\n animation?: 'pulse' | 'none';\n lines?: number;\n spacing?: 'none' | 'small' | 'medium' | 'large';\n}\n\nconst SKELETON_ANIMATION_CLASSES = {\n pulse: 'animate-pulse',\n none: '',\n};\n\nconst SKELETON_VARIANT_CLASSES = {\n text: 'h-4 bg-background-200 rounded',\n circular: 'bg-background-200 rounded-full',\n rectangular: 'bg-background-200',\n rounded: 'bg-background-200 rounded-lg',\n};\n\nconst SPACING_CLASSES = {\n none: '',\n small: 'space-y-1',\n medium: 'space-y-2',\n large: 'space-y-3',\n};\n\nconst Skeleton = forwardRef<HTMLDivElement, SkeletonProps>(\n (\n {\n variant = 'text',\n width,\n height,\n animation = 'pulse',\n lines = 1,\n spacing = 'none',\n className = '',\n children,\n ...props\n },\n ref\n ) => {\n const animationClass = SKELETON_ANIMATION_CLASSES[animation];\n const variantClass = SKELETON_VARIANT_CLASSES[variant];\n const spacingClass = SPACING_CLASSES[spacing];\n\n const style: CSSProperties = {\n width: typeof width === 'number' ? `${width}px` : width,\n height: typeof height === 'number' ? `${height}px` : height,\n };\n\n // Se for múltiplas linhas de texto\n if (variant === 'text' && lines > 1) {\n return (\n <div\n ref={ref}\n className={cn('flex flex-col', spacingClass, className)}\n {...props}\n >\n {Array.from({ length: lines }, (_, index) => (\n <div\n key={index}\n className={cn(variantClass, animationClass)}\n style={index === lines - 1 ? { width: '60%' } : undefined}\n />\n ))}\n </div>\n );\n }\n\n // Se for um único elemento\n return (\n <div\n ref={ref}\n className={cn(variantClass, animationClass, className)}\n style={style}\n {...props}\n >\n {children}\n </div>\n );\n }\n);\n\n// Componentes específicos para casos comuns\nconst SkeletonText = forwardRef<HTMLDivElement, Omit<SkeletonProps, 'variant'>>(\n (props, ref) => <Skeleton ref={ref} variant=\"text\" {...props} />\n);\n\nconst SkeletonCircle = forwardRef<\n HTMLDivElement,\n Omit<SkeletonProps, 'variant'>\n>((props, ref) => <Skeleton ref={ref} variant=\"circular\" {...props} />);\n\nconst SkeletonRectangle = forwardRef<\n HTMLDivElement,\n Omit<SkeletonProps, 'variant'>\n>((props, ref) => <Skeleton ref={ref} variant=\"rectangular\" {...props} />);\n\nconst SkeletonRounded = forwardRef<\n HTMLDivElement,\n Omit<SkeletonProps, 'variant'>\n>((props, ref) => <Skeleton ref={ref} variant=\"rounded\" {...props} />);\n\n// Componente para card skeleton\ninterface SkeletonCardProps extends HTMLAttributes<HTMLDivElement> {\n showAvatar?: boolean;\n showTitle?: boolean;\n showDescription?: boolean;\n showActions?: boolean;\n lines?: number;\n}\n\nconst SkeletonCard = forwardRef<HTMLDivElement, SkeletonCardProps>(\n (\n {\n showAvatar = true,\n showTitle = true,\n showDescription = true,\n showActions = true,\n lines = 2,\n className = '',\n ...props\n },\n ref\n ) => {\n return (\n <div\n ref={ref}\n className={cn(\n 'w-full p-4 bg-background border border-border-200 rounded-lg',\n className\n )}\n {...props}\n >\n <div className=\"flex items-start space-x-3\">\n {showAvatar && <SkeletonCircle width={40} height={40} />}\n\n <div className=\"flex-1 space-y-2\">\n {showTitle && <SkeletonText width=\"60%\" height={20} />}\n\n {showDescription && <SkeletonText lines={lines} spacing=\"small\" />}\n </div>\n </div>\n\n {showActions && (\n <div className=\"flex justify-end space-x-2 mt-4\">\n <SkeletonRectangle width={80} height={32} />\n <SkeletonRectangle width={80} height={32} />\n </div>\n )}\n </div>\n );\n }\n);\n\n// Componente para lista skeleton\ninterface SkeletonListProps extends HTMLAttributes<HTMLDivElement> {\n items?: number;\n showAvatar?: boolean;\n showTitle?: boolean;\n showDescription?: boolean;\n lines?: number;\n}\n\nconst SkeletonList = forwardRef<HTMLDivElement, SkeletonListProps>(\n (\n {\n items = 3,\n showAvatar = true,\n showTitle = true,\n showDescription = true,\n lines = 1,\n className = '',\n ...props\n },\n ref\n ) => {\n return (\n <div ref={ref} className={cn('space-y-3', className)} {...props}>\n {Array.from({ length: items }, (_, index) => (\n <div key={index} className=\"flex items-start space-x-3 p-3\">\n {showAvatar && <SkeletonCircle width={32} height={32} />}\n\n <div className=\"flex-1 space-y-2\">\n {showTitle && <SkeletonText width=\"40%\" height={16} />}\n\n {showDescription && (\n <SkeletonText lines={lines} spacing=\"small\" />\n )}\n </div>\n </div>\n ))}\n </div>\n );\n }\n);\n\n// Componente para tabela skeleton\ninterface SkeletonTableProps extends HTMLAttributes<HTMLDivElement> {\n rows?: number;\n columns?: number;\n showHeader?: boolean;\n}\n\nconst SkeletonTable = forwardRef<HTMLDivElement, SkeletonTableProps>(\n (\n { rows = 5, columns = 4, showHeader = true, className = '', ...props },\n ref\n ) => {\n return (\n <div ref={ref} className={cn('w-full', className)} {...props}>\n {showHeader && (\n <div className=\"flex space-x-2 mb-3\">\n {Array.from({ length: columns }, (_, index) => (\n <SkeletonText\n key={index}\n width={`${100 / columns}%`}\n height={20}\n />\n ))}\n </div>\n )}\n\n <div className=\"space-y-2\">\n {Array.from({ length: rows }, (_, rowIndex) => (\n <div key={rowIndex} className=\"flex space-x-2\">\n {Array.from({ length: columns }, (_, colIndex) => (\n <SkeletonText\n key={colIndex}\n width={`${100 / columns}%`}\n height={16}\n />\n ))}\n </div>\n ))}\n </div>\n </div>\n );\n }\n);\n\nexport {\n Skeleton,\n SkeletonText,\n SkeletonCircle,\n SkeletonRectangle,\n SkeletonRounded,\n SkeletonCard,\n SkeletonList,\n SkeletonTable,\n};\n","import { clsx, type ClassValue } from 'clsx';\nimport { twMerge } from 'tailwind-merge';\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs));\n}\n\nexport { syncDropdownState } from './dropdown';\nexport {\n getSelectedIdsFromCategories,\n toggleArrayItem,\n toggleSingleValue,\n} from './activityFilters';\nexport {\n getStatusBadgeConfig,\n formatTimeSpent,\n formatQuestionNumbers,\n formatDateToBrazilian,\n} from './activityDetailsUtils';\n\n/**\n * Retorna a cor hexadecimal com opacidade 0.3 (4d) se não estiver em dark mode.\n * Se estiver em dark mode, retorna a cor original.\n *\n * @param hexColor - Cor hexadecimal (ex: \"#0066b8\" ou \"0066b8\")\n * @param isDark - booleano indicando se está em dark mode\n * @returns string - cor hexadecimal com opacidade se necessário\n */\nexport function getSubjectColorWithOpacity(\n hexColor: string | undefined,\n isDark: boolean\n): string | undefined {\n if (!hexColor) return undefined;\n // Remove o '#' se existir\n let color = hexColor.replace(/^#/, '').toLowerCase();\n\n if (isDark) {\n // Se está em dark mode, sempre remove opacidade se existir\n if (color.length === 8) {\n color = color.slice(0, 6);\n }\n return `#${color}`;\n } else {\n // Se não está em dark mode (light mode)\n let resultColor: string;\n if (color.length === 6) {\n // Adiciona opacidade 0.3 (4D) para cores de 6 dígitos\n resultColor = `#${color}4d`;\n } else if (color.length === 8) {\n // Já tem opacidade, retorna como está\n resultColor = `#${color}`;\n } else {\n // Para outros tamanhos (3, 4, 5 dígitos), retorna como está\n resultColor = `#${color}`;\n }\n return resultColor;\n }\n}\n"],"mappings":"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","names":["_"]}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/components/StatisticsCard/StatisticsCard.tsx","../../src/utils/utils.ts","../../src/components/Text/Text.tsx","../../src/components/Button/Button.tsx","../../src/components/Select/Select.tsx"],"sourcesContent":["import Text from '../Text/Text';\nimport Button from '../Button/Button';\nimport Select, {\n SelectTrigger,\n SelectValue,\n SelectContent,\n SelectItem,\n} from '../Select/Select';\nimport { Plus } from 'phosphor-react';\n\n/**\n * Statistics data item\n */\ninterface StatItem {\n /** Statistic label */\n label: string;\n /** Statistic value */\n value: string | number;\n /** Color variant */\n variant: 'high' | 'medium' | 'low' | 'total';\n}\n\n/**\n * Props for StatisticsCard component\n */\ninterface StatisticsCardProps {\n /** Title displayed at the top of the card */\n title: string;\n /** Statistics data to display */\n data?: StatItem[];\n /** Show placeholder \"-\" in values when true (for created items without data yet) */\n showPlaceholder?: boolean;\n /** Message shown in empty state */\n emptyStateMessage?: string;\n /** Text for the empty state button */\n emptyStateButtonText?: string;\n /** Callback when empty state button is clicked */\n onEmptyStateButtonClick?: () => void;\n /** Optional dropdown options for filtering */\n dropdownOptions?: Array<{\n label: string;\n value: string;\n }>;\n /** Currently selected dropdown value */\n selectedDropdownValue?: string;\n /** Callback when dropdown value changes */\n onDropdownChange?: (value: string) => void;\n /** Placeholder text for the dropdown select */\n selectPlaceholder?: string;\n /** Accessible label for the dropdown select */\n dropdownAriaLabel?: string;\n /** Additional CSS classes */\n className?: string;\n}\n\n/**\n * Variant styles mapping\n */\nconst VARIANT_STYLES = {\n high: 'bg-success-background',\n medium: 'bg-warning-background',\n low: 'bg-error-background',\n total: 'bg-info-background',\n} as const;\n\n/**\n * Value text colors mapping\n */\nconst VALUE_TEXT_COLORS = {\n high: 'text-success-700',\n medium: 'text-warning-600',\n low: 'text-error-700',\n total: 'text-info-700',\n} as const;\n\n/**\n * Internal StatCard component\n */\ninterface StatCardProps {\n item: StatItem;\n showPlaceholder?: boolean;\n}\n\nconst StatCard = ({ item, showPlaceholder = false }: StatCardProps) => {\n return (\n <div\n className={`rounded-xl py-[17px] px-6 min-h-[105px] flex flex-col justify-center items-start gap-1 ${VARIANT_STYLES[item.variant]}`}\n >\n <Text\n size=\"4xl\"\n weight=\"bold\"\n className={`${VALUE_TEXT_COLORS[item.variant]} leading-[42px] tracking-[0.2px] self-stretch`}\n >\n {showPlaceholder ? '-' : item.value}\n </Text>\n <Text\n size=\"xs\"\n weight=\"bold\"\n className=\"uppercase text-[8px] leading-[9px] text-text-800 whitespace-nowrap\"\n >\n {item.label}\n </Text>\n </div>\n );\n};\n\n/**\n * Get grid column class based on number of items\n */\nconst getGridColumnsClass = (itemCount: number): string => {\n if (itemCount === 4) return 'lg:grid-cols-4';\n if (itemCount === 3) return 'lg:grid-cols-3';\n if (itemCount === 2) return 'lg:grid-cols-2';\n return 'lg:grid-cols-1';\n};\n\n/**\n * StatisticsCard component - displays statistics with empty state support\n *\n * @example\n * ```tsx\n * // With data\n * <StatisticsCard\n * title=\"Estatística das atividades\"\n * data={[\n * { label: 'Acertos', value: '85%', variant: 'high' },\n * { label: 'Em andamento', value: 12, variant: 'medium' },\n * { label: 'Erros', value: '15%', variant: 'low' },\n * { label: 'Concluídas', value: 24, variant: 'total' }\n * ]}\n * dropdownOptions={[\n * { label: '1 ano', value: '1year' },\n * { label: '6 meses', value: '6months' }\n * ]}\n * selectedDropdownValue=\"1year\"\n * onDropdownChange={(value) => console.log(value)}\n * />\n *\n * // Empty state\n * <StatisticsCard\n * title=\"Estatística das atividades\"\n * emptyStateMessage=\"Sem dados por enquanto. Crie uma atividade para que os resultados apareçam aqui.\"\n * emptyStateButtonText=\"Criar atividade\"\n * onEmptyStateButtonClick={() => console.log('Create activity')}\n * />\n * ```\n */\nexport const StatisticsCard = ({\n title,\n data,\n showPlaceholder = false,\n emptyStateMessage,\n emptyStateButtonText,\n onEmptyStateButtonClick,\n dropdownOptions,\n selectedDropdownValue,\n onDropdownChange,\n selectPlaceholder = 'Selecione um período',\n dropdownAriaLabel = 'Filtro de período',\n className = '',\n}: StatisticsCardProps) => {\n const hasData = data && data.length > 0;\n const gridColumnsClass = hasData ? getGridColumnsClass(data.length) : '';\n\n return (\n <div\n className={`bg-background rounded-xl p-4 h-auto lg:h-[185px] flex flex-col gap-2 ${className}`}\n >\n {/* Header with title and optional dropdown */}\n <div className=\"flex flex-row justify-between items-center gap-4\">\n <Text\n as=\"h3\"\n size=\"sm\"\n weight=\"medium\"\n color=\"text-text-600\"\n className=\"flex-1 min-w-0\"\n >\n {title}\n </Text>\n\n {dropdownOptions && dropdownOptions.length > 0 && (\n <div className=\"w-[120px] min-w-[90px] sm:shrink-0\">\n <Select\n value={selectedDropdownValue}\n onValueChange={onDropdownChange}\n size=\"medium\"\n >\n <SelectTrigger\n className=\"border border-border-300 rounded [&>span]:whitespace-nowrap [&>span]:overflow-hidden [&>span]:text-ellipsis\"\n aria-label={dropdownAriaLabel}\n >\n <SelectValue placeholder={selectPlaceholder} />\n </SelectTrigger>\n <SelectContent className=\"min-w-[120px]\">\n {dropdownOptions.map((option) => (\n <SelectItem\n key={option.value}\n value={option.value}\n className=\"whitespace-nowrap\"\n >\n {option.label}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n )}\n </div>\n\n {/* Content: Data Grid or Empty State */}\n {hasData ? (\n <div\n className={`grid grid-cols-1 sm:grid-cols-2 gap-[13px] ${gridColumnsClass}`}\n >\n {data.map((item, index) => (\n <StatCard\n key={`${item.variant}-${item.label}-${index}`}\n item={item}\n showPlaceholder={showPlaceholder}\n />\n ))}\n </div>\n ) : (\n <div className=\"border border-dashed border-border-300 rounded-lg p-6 min-h-[105px] flex flex-col items-center justify-center gap-2\">\n <Text\n size=\"sm\"\n color=\"text-text-600\"\n className=\"text-center max-w-md\"\n >\n {emptyStateMessage}\n </Text>\n\n {onEmptyStateButtonClick && (\n <Button\n variant=\"outline\"\n action=\"primary\"\n size=\"small\"\n onClick={onEmptyStateButtonClick}\n iconLeft={<Plus size={16} weight=\"bold\" />}\n >\n {emptyStateButtonText}\n </Button>\n )}\n </div>\n )}\n </div>\n );\n};\n","import { clsx, type ClassValue } from 'clsx';\nimport { twMerge } from 'tailwind-merge';\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs));\n}\n\nexport { syncDropdownState } from './dropdown';\nexport {\n getSelectedIdsFromCategories,\n toggleArrayItem,\n toggleSingleValue,\n} from './activityFilters';\n\n/**\n * Retorna a cor hexadecimal com opacidade 0.3 (4d) se não estiver em dark mode.\n * Se estiver em dark mode, retorna a cor original.\n *\n * @param hexColor - Cor hexadecimal (ex: \"#0066b8\" ou \"0066b8\")\n * @param isDark - booleano indicando se está em dark mode\n * @returns string - cor hexadecimal com opacidade se necessário\n */\nexport function getSubjectColorWithOpacity(\n hexColor: string | undefined,\n isDark: boolean\n): string | undefined {\n if (!hexColor) return undefined;\n // Remove o '#' se existir\n let color = hexColor.replace(/^#/, '').toLowerCase();\n\n if (isDark) {\n // Se está em dark mode, sempre remove opacidade se existir\n if (color.length === 8) {\n color = color.slice(0, 6);\n }\n return `#${color}`;\n } else {\n // Se não está em dark mode (light mode)\n let resultColor: string;\n if (color.length === 6) {\n // Adiciona opacidade 0.3 (4D) para cores de 6 dígitos\n resultColor = `#${color}4d`;\n } else if (color.length === 8) {\n // Já tem opacidade, retorna como está\n resultColor = `#${color}`;\n } else {\n // Para outros tamanhos (3, 4, 5 dígitos), retorna como está\n resultColor = `#${color}`;\n }\n return resultColor;\n }\n}\n","import { ComponentPropsWithoutRef, ElementType, ReactNode } from 'react';\nimport { cn } from '../../utils/utils';\n\n/**\n * Base text component props\n */\ntype BaseTextProps = {\n /** Content to be displayed */\n children?: ReactNode;\n /** Text size variant */\n size?:\n | '2xs'\n | 'xs'\n | 'sm'\n | 'md'\n | 'lg'\n | 'xl'\n | '2xl'\n | '3xl'\n | '4xl'\n | '5xl'\n | '6xl';\n /** Font weight variant */\n weight?:\n | 'hairline'\n | 'light'\n | 'normal'\n | 'medium'\n | 'semibold'\n | 'bold'\n | 'extrabold'\n | 'black';\n /** Color variant - white for light backgrounds, black for dark backgrounds */\n color?: string;\n /** Additional CSS classes to apply */\n className?: string;\n};\n\n/**\n * Polymorphic text component props that ensures type safety based on the 'as' prop\n */\ntype TextProps<T extends ElementType = 'p'> = BaseTextProps & {\n /** HTML tag to render */\n as?: T;\n} & Omit<ComponentPropsWithoutRef<T>, keyof BaseTextProps>;\n\n/**\n * Text component for Analytica Ensino platforms\n *\n * A flexible polymorphic text component with multiple sizes, weights, and colors.\n * Automatically adapts to dark and light themes with full type safety.\n *\n * @param children - The content to display\n * @param size - The text size variant (2xs, xs, sm, md, lg, xl, 2xl, 3xl, 4xl, 5xl, 6xl)\n * @param weight - The font weight variant (hairline, light, normal, medium, semibold, bold, extrabold, black)\n * @param color - The color variant - adapts to theme\n * @param as - The HTML tag to render - determines allowed attributes via TypeScript\n * @param className - Additional CSS classes\n * @param props - HTML attributes valid for the chosen tag only\n * @returns A styled text element with type-safe attributes\n *\n * @example\n * ```tsx\n * <Text size=\"lg\" weight=\"bold\" color=\"text-info-800\">\n * This is a large, bold text\n * </Text>\n *\n * <Text as=\"a\" href=\"/link\" target=\"_blank\">\n * Link with type-safe anchor attributes\n * </Text>\n *\n * <Text as=\"button\" onClick={handleClick} disabled>\n * Button with type-safe button attributes\n * </Text>\n * ```\n */\nconst Text = <T extends ElementType = 'p'>({\n children,\n size = 'md',\n weight = 'normal',\n color = 'text-text-950',\n as,\n className = '',\n ...props\n}: TextProps<T>) => {\n let sizeClasses = '';\n let weightClasses = '';\n\n // Text size classes mapping\n const sizeClassMap = {\n '2xs': 'text-2xs',\n xs: 'text-xs',\n sm: 'text-sm',\n md: 'text-md',\n lg: 'text-lg',\n xl: 'text-xl',\n '2xl': 'text-2xl',\n '3xl': 'text-3xl',\n '4xl': 'text-4xl',\n '5xl': 'text-5xl',\n '6xl': 'text-6xl',\n } as const;\n\n sizeClasses = sizeClassMap[size] ?? sizeClassMap.md;\n\n // Font weight classes mapping\n const weightClassMap = {\n hairline: 'font-hairline',\n light: 'font-light',\n normal: 'font-normal',\n medium: 'font-medium',\n semibold: 'font-semibold',\n bold: 'font-bold',\n extrabold: 'font-extrabold',\n black: 'font-black',\n } as const;\n\n weightClasses = weightClassMap[weight] ?? weightClassMap.normal;\n\n const baseClasses = 'font-primary';\n const Component = as ?? ('p' as ElementType);\n\n return (\n <Component\n className={cn(baseClasses, sizeClasses, weightClasses, color, className)}\n {...props}\n >\n {children}\n </Component>\n );\n};\n\nexport default Text;\n","import { ButtonHTMLAttributes, ReactNode } from 'react';\nimport { cn } from '../../utils/utils';\n\n/**\n * Lookup table for variant and action class combinations\n */\nconst VARIANT_ACTION_CLASSES = {\n solid: {\n primary:\n 'bg-primary-950 text-text border border-primary-950 hover:bg-primary-800 hover:border-primary-800 focus-visible:outline-none focus-visible:bg-primary-950 focus-visible:ring-2 focus-visible:ring-offset-0 focus-visible:ring-indicator-info active:bg-primary-700 active:border-primary-700 disabled:bg-primary-500 disabled:border-primary-500 disabled:opacity-40 disabled:cursor-not-allowed',\n positive:\n 'bg-success-500 text-text border border-success-500 hover:bg-success-600 hover:border-success-600 focus-visible:outline-none focus-visible:bg-success-500 focus-visible:ring-2 focus-visible:ring-offset-0 focus-visible:ring-indicator-info active:bg-success-700 active:border-success-700 disabled:bg-success-500 disabled:border-success-500 disabled:opacity-40 disabled:cursor-not-allowed',\n negative:\n 'bg-error-500 text-text border border-error-500 hover:bg-error-600 hover:border-error-600 focus-visible:outline-none focus-visible:bg-error-500 focus-visible:ring-2 focus-visible:ring-offset-0 focus-visible:ring-indicator-info active:bg-error-700 active:border-error-700 disabled:bg-error-500 disabled:border-error-500 disabled:opacity-40 disabled:cursor-not-allowed',\n },\n outline: {\n primary:\n 'bg-transparent text-primary-950 border border-primary-950 hover:bg-background-50 hover:text-primary-400 hover:border-primary-400 focus-visible:border-0 focus-visible:outline-none focus-visible:text-primary-600 focus-visible:ring-2 focus-visible:ring-offset-0 focus-visible:ring-indicator-info active:text-primary-700 active:border-primary-700 disabled:opacity-40 disabled:cursor-not-allowed',\n positive:\n 'bg-transparent text-success-500 border border-success-300 hover:bg-background-50 hover:text-success-400 hover:border-success-400 focus-visible:border-0 focus-visible:outline-none focus-visible:text-success-600 focus-visible:ring-2 focus-visible:ring-offset-0 focus-visible:ring-indicator-info active:text-success-700 active:border-success-700 disabled:opacity-40 disabled:cursor-not-allowed',\n negative:\n 'bg-transparent text-error-500 border border-error-300 hover:bg-background-50 hover:text-error-400 hover:border-error-400 focus-visible:border-0 focus-visible:outline-none focus-visible:text-error-600 focus-visible:ring-2 focus-visible:ring-offset-0 focus-visible:ring-indicator-info active:text-error-700 active:border-error-700 disabled:opacity-40 disabled:cursor-not-allowed',\n },\n link: {\n primary:\n 'bg-transparent text-primary-950 hover:text-primary-400 focus-visible:outline-none focus-visible:text-primary-600 focus-visible:ring-2 focus-visible:ring-offset-0 focus-visible:ring-indicator-info active:text-primary-700 disabled:opacity-40 disabled:cursor-not-allowed',\n positive:\n 'bg-transparent text-success-500 hover:text-success-400 focus-visible:outline-none focus-visible:text-success-600 focus-visible:ring-2 focus-visible:ring-offset-0 focus-visible:ring-indicator-info active:text-success-700 disabled:opacity-40 disabled:cursor-not-allowed',\n negative:\n 'bg-transparent text-error-500 hover:text-error-400 focus-visible:outline-none focus-visible:text-error-600 focus-visible:ring-2 focus-visible:ring-offset-0 focus-visible:ring-indicator-info active:text-error-700 disabled:opacity-40 disabled:cursor-not-allowed',\n },\n} as const;\n\n/**\n * Lookup table for size classes\n */\nconst SIZE_CLASSES = {\n 'extra-small': 'text-xs px-3.5 py-2',\n small: 'text-sm px-4 py-2.5',\n medium: 'text-md px-5 py-2.5',\n large: 'text-lg px-6 py-3',\n 'extra-large': 'text-lg px-7 py-3.5',\n} as const;\n\n/**\n * Button component props interface\n */\ntype ButtonProps = {\n /** Content to be displayed inside the button */\n children: ReactNode;\n /** Ícone à esquerda do texto */\n iconLeft?: ReactNode;\n /** Ícone à direita do texto */\n iconRight?: ReactNode;\n /** Size of the button */\n size?: 'extra-small' | 'small' | 'medium' | 'large' | 'extra-large';\n /** Visual variant of the button */\n variant?: 'solid' | 'outline' | 'link';\n /** Action type of the button */\n action?: 'primary' | 'positive' | 'negative';\n /** Additional CSS classes to apply */\n className?: string;\n} & ButtonHTMLAttributes<HTMLButtonElement>;\n\n/**\n * Button component for Analytica Ensino platforms\n *\n * A flexible button component with multiple variants, sizes and actions.\n *\n * @param children - The content to display inside the button\n * @param size - The size variant (extra-small, small, medium, large, extra-large)\n * @param variant - The visual style variant (solid, outline, link)\n * @param action - The action type (primary, positive, negative)\n * @param className - Additional CSS classes\n * @param props - All other standard button HTML attributes\n * @returns A styled button element\n *\n * @example\n * ```tsx\n * <Button variant=\"solid\" action=\"primary\" size=\"medium\" onClick={() => console.log('clicked')}>\n * Click me\n * </Button>\n * ```\n */\nconst Button = ({\n children,\n iconLeft,\n iconRight,\n size = 'medium',\n variant = 'solid',\n action = 'primary',\n className = '',\n disabled,\n type = 'button',\n ...props\n}: ButtonProps) => {\n // Get classes from lookup tables\n const sizeClasses = SIZE_CLASSES[size];\n const variantClasses = VARIANT_ACTION_CLASSES[variant][action];\n\n const baseClasses =\n 'inline-flex items-center justify-center rounded-full cursor-pointer font-medium';\n\n return (\n <button\n className={cn(baseClasses, variantClasses, sizeClasses, className)}\n disabled={disabled}\n type={type}\n {...props}\n >\n {iconLeft && <span className=\"mr-2 flex items-center\">{iconLeft}</span>}\n {children}\n {iconRight && <span className=\"ml-2 flex items-center\">{iconRight}</span>}\n </button>\n );\n};\n\nexport default Button;\n","import { create, StoreApi, useStore } from 'zustand';\nimport {\n ReactNode,\n useEffect,\n useRef,\n ButtonHTMLAttributes,\n forwardRef,\n HTMLAttributes,\n KeyboardEvent,\n MouseEvent,\n ReactElement,\n isValidElement,\n Children,\n cloneElement,\n useId,\n} from 'react';\nimport { CaretDown, Check, WarningCircle } from 'phosphor-react';\nimport { cn } from '../../utils/utils';\n\nconst VARIANT_CLASSES = {\n outlined: 'border-2 rounded-lg focus:border-primary-950',\n underlined: 'border-b-2 focus:border-primary-950',\n rounded: 'border-2 rounded-full focus:border-primary-950',\n} as const;\n\nconst SIZE_CLASSES = {\n small: 'text-sm',\n medium: 'text-md',\n large: 'text-lg',\n 'extra-large': 'text-lg',\n} as const;\n\nconst HEIGHT_CLASSES = {\n small: 'h-8',\n medium: 'h-9',\n large: 'h-10',\n 'extra-large': 'h-12',\n} as const;\n\nconst PADDING_CLASSES = {\n small: 'px-2 py-1',\n medium: 'px-3 py-2',\n large: 'px-4 py-3',\n 'extra-large': 'px-5 py-4',\n} as const;\n\nconst SIDE_CLASSES = {\n top: 'bottom-full -translate-y-1',\n right: 'top-full translate-y-1',\n bottom: 'top-full translate-y-1',\n left: 'top-full translate-y-1',\n};\nconst ALIGN_CLASSES = {\n start: 'left-0',\n center: 'left-1/2 -translate-x-1/2',\n end: 'right-0',\n};\n\ninterface SelectStore {\n open: boolean;\n setOpen: (open: boolean) => void;\n value: string;\n setValue: (value: string) => void;\n selectedLabel: ReactNode;\n setSelectedLabel: (label: ReactNode) => void;\n onValueChange?: (value: string) => void;\n}\n\ntype SelectStoreApi = StoreApi<SelectStore>;\n\nexport function createSelectStore(\n onValueChange?: (value: string) => void\n): SelectStoreApi {\n return create<SelectStore>((set) => ({\n open: false,\n setOpen: (open) => set({ open }),\n value: '',\n setValue: (value) => set({ value }),\n selectedLabel: '',\n setSelectedLabel: (label) => set({ selectedLabel: label }),\n onValueChange,\n }));\n}\n\nexport const useSelectStore = (externalStore?: SelectStoreApi) => {\n if (!externalStore) {\n throw new Error(\n 'Component must be used within a Select (store is missing)'\n );\n }\n\n return externalStore;\n};\n\nexport function getLabelAsNode(children: ReactNode): ReactNode {\n if (typeof children === 'string' || typeof children === 'number') {\n return children;\n }\n const flattened = Children.toArray(children);\n\n if (flattened.length === 1) return flattened[0];\n\n return <>{flattened}</>;\n}\n\ninterface SelectProps {\n className?: string;\n children: ReactNode;\n defaultValue?: string;\n value?: string;\n onValueChange?: (value: string) => void;\n size?: 'small' | 'medium' | 'large' | 'extra-large';\n label?: string;\n helperText?: string;\n errorMessage?: string;\n id?: string;\n}\n\nconst injectStore = (\n children: ReactNode,\n store: SelectStoreApi,\n size: string,\n selectId: string\n): ReactNode => {\n return Children.map(children, (child) => {\n if (isValidElement(child)) {\n const typedChild = child as ReactElement<{\n store?: SelectStoreApi;\n children?: ReactNode;\n size?: string;\n selectId?: string;\n }>;\n\n const newProps: Partial<{\n store: SelectStoreApi;\n children: ReactNode;\n size: string;\n selectId: string;\n }> = {\n store,\n };\n\n // Only pass size and selectId to SelectTrigger\n if (typedChild.type === SelectTrigger) {\n newProps.size = size;\n newProps.selectId = selectId;\n }\n\n if (typedChild.props.children) {\n newProps.children = injectStore(\n typedChild.props.children,\n store,\n size,\n selectId\n );\n }\n\n return cloneElement(typedChild, newProps);\n }\n return child;\n });\n};\n\nconst Select = ({\n children,\n defaultValue = '',\n className,\n value: propValue,\n onValueChange,\n size = 'small',\n label,\n helperText,\n errorMessage,\n id,\n}: SelectProps) => {\n const storeRef = useRef<SelectStoreApi | null>(null);\n storeRef.current ??= createSelectStore(onValueChange);\n const store = storeRef.current;\n\n const selectRef = useRef<HTMLDivElement>(null);\n const { open, setOpen, setValue, selectedLabel } = useStore(store, (s) => s);\n\n // Generate unique ID if not provided\n const generatedId = useId();\n const selectId = id ?? `select-${generatedId}`;\n\n const findLabelForValue = (\n children: ReactNode,\n targetValue: string\n ): string | null => {\n let found: string | null = null;\n const search = (nodes: ReactNode) => {\n Children.forEach(nodes, (child) => {\n if (!isValidElement(child)) return;\n const typedChild = child as ReactElement<{\n value?: string;\n children?: ReactNode;\n }>;\n if (\n typedChild.type === SelectItem &&\n typedChild.props.value === targetValue\n ) {\n if (typeof typedChild.props.children === 'string')\n found = typedChild.props.children;\n }\n if (typedChild.props.children && !found)\n search(typedChild.props.children);\n });\n };\n search(children);\n return found;\n };\n\n useEffect(() => {\n if (!selectedLabel && defaultValue) {\n const label = findLabelForValue(children, defaultValue);\n if (label) store.setState({ selectedLabel: label });\n }\n }, [children, defaultValue, selectedLabel]);\n\n useEffect(() => {\n const handleClickOutside = (event: globalThis.MouseEvent) => {\n if (\n selectRef.current &&\n !selectRef.current.contains(event.target as Node)\n ) {\n setOpen(false);\n }\n };\n\n const handleArrowKeys = (event: globalThis.KeyboardEvent) => {\n const selectContent = selectRef.current?.querySelector('[role=\"menu\"]');\n if (selectContent) {\n event.preventDefault();\n const items = Array.from(\n selectContent.querySelectorAll(\n '[role=\"menuitem\"]:not([aria-disabled=\"true\"])'\n )\n ).filter((el): el is HTMLElement => el instanceof HTMLElement);\n\n const focused = document.activeElement as HTMLElement;\n const currentIndex = items.findIndex((item) => item === focused);\n\n let nextIndex = 0;\n if (event.key === 'ArrowDown') {\n nextIndex =\n currentIndex === -1 ? 0 : (currentIndex + 1) % items.length;\n } else {\n nextIndex =\n currentIndex === -1\n ? items.length - 1\n : (currentIndex - 1 + items.length) % items.length;\n }\n items[nextIndex]?.focus();\n }\n };\n\n if (open) {\n document.addEventListener('mousedown', handleClickOutside);\n document.addEventListener('keydown', handleArrowKeys);\n }\n return () => {\n document.removeEventListener('mousedown', handleClickOutside);\n document.removeEventListener('keydown', handleArrowKeys);\n };\n }, [open]);\n\n useEffect(() => {\n if (propValue) {\n setValue(propValue);\n const label = findLabelForValue(children, propValue);\n if (label) store.setState({ selectedLabel: label });\n }\n }, [propValue]);\n\n const sizeClasses = SIZE_CLASSES[size];\n\n return (\n <div className={cn('w-full', className)}>\n {/* Label */}\n {label && (\n <label\n htmlFor={selectId}\n className={cn('block font-bold text-text-900 mb-1.5', sizeClasses)}\n >\n {label}\n </label>\n )}\n\n {/* Select Container */}\n <div className={cn('relative w-full')} ref={selectRef}>\n {injectStore(children, store, size, selectId)}\n </div>\n\n {/* Helper Text or Error Message */}\n {(helperText || errorMessage) && (\n <div className=\"mt-1.5 gap-1.5\">\n {helperText && <p className=\"text-sm text-text-500\">{helperText}</p>}\n {errorMessage && (\n <p className=\"flex gap-1 items-center text-sm text-indicator-error\">\n <WarningCircle size={16} /> {errorMessage}\n </p>\n )}\n </div>\n )}\n </div>\n );\n};\n\nconst SelectValue = ({\n placeholder,\n store: externalStore,\n}: {\n placeholder?: string;\n store?: SelectStoreApi;\n}) => {\n const store = useSelectStore(externalStore);\n\n const selectedLabel = useStore(store, (s) => s.selectedLabel);\n const value = useStore(store, (s) => s.value);\n return (\n <span className=\"text-inherit flex gap-2 items-center\">\n {selectedLabel || placeholder || value}\n </span>\n );\n};\n\ninterface SelectTriggerProps extends ButtonHTMLAttributes<HTMLButtonElement> {\n className?: string;\n invalid?: boolean;\n variant?: 'outlined' | 'underlined' | 'rounded';\n store?: SelectStoreApi;\n size?: 'small' | 'medium' | 'large' | 'extra-large';\n selectId?: string;\n}\n\nconst SelectTrigger = forwardRef<HTMLButtonElement, SelectTriggerProps>(\n (\n {\n className,\n invalid = false,\n variant = 'outlined',\n store: externalStore,\n disabled,\n size = 'medium',\n selectId,\n ...props\n },\n ref\n ) => {\n const store = useSelectStore(externalStore);\n const open = useStore(store, (s) => s.open);\n const toggleOpen = () => store.setState({ open: !open });\n\n const variantClasses = VARIANT_CLASSES[variant];\n const heightClasses = HEIGHT_CLASSES[size];\n const paddingClasses = PADDING_CLASSES[size];\n\n return (\n <button\n ref={ref}\n id={selectId}\n className={cn(\n 'flex w-full items-center justify-between border-border-300',\n heightClasses,\n paddingClasses,\n invalid &&\n `${variant == 'underlined' ? 'border-b-2' : 'border-2'} border-indicator-error text-text-600`,\n disabled\n ? 'cursor-not-allowed text-text-400 pointer-events-none opacity-50'\n : 'cursor-pointer hover:bg-background-50 focus:bg-accent focus:text-accent-foreground hover:bg-accent hover:text-accent-foreground',\n !invalid && !disabled ? 'text-text-700' : '',\n variantClasses,\n className\n )}\n onClick={toggleOpen}\n aria-expanded={open}\n aria-haspopup=\"listbox\"\n aria-controls={open ? 'select-content' : undefined}\n {...props}\n >\n {props.children}\n <CaretDown\n className={cn(\n 'h-[1em] w-[1em] opacity-50 transition-transform',\n open ? 'rotate-180' : ''\n )}\n />\n </button>\n );\n }\n);\nSelectTrigger.displayName = 'SelectTrigger';\n\ninterface SelectContentProps extends HTMLAttributes<HTMLDivElement> {\n className?: string;\n align?: 'start' | 'center' | 'end';\n side?: 'top' | 'right' | 'bottom' | 'left';\n store?: SelectStoreApi;\n}\n\nconst SelectContent = forwardRef<HTMLDivElement, SelectContentProps>(\n (\n {\n children,\n className,\n align = 'start',\n side = 'bottom',\n store: externalStore,\n ...props\n },\n ref\n ) => {\n const store = useSelectStore(externalStore);\n\n const open = useStore(store, (s) => s.open);\n if (!open) return null;\n\n const getPositionClasses = () =>\n `w-full min-w-full absolute ${SIDE_CLASSES[side]} ${ALIGN_CLASSES[align]}`;\n\n return (\n <div\n role=\"menu\"\n ref={ref}\n className={cn(\n 'bg-secondary z-50 min-w-[210px] max-h-[300px] overflow-y-auto overflow-x-hidden rounded-md border p-1 shadow-md border-border-100',\n getPositionClasses(),\n className\n )}\n {...props}\n >\n {children}\n </div>\n );\n }\n);\nSelectContent.displayName = 'SelectContent';\n\ninterface SelectItemProps extends HTMLAttributes<HTMLDivElement> {\n value: string;\n disabled?: boolean;\n store?: SelectStoreApi;\n}\n\nconst SelectItem = forwardRef<HTMLDivElement, SelectItemProps>(\n (\n {\n className,\n children,\n value,\n disabled = false,\n store: externalStore,\n ...props\n },\n ref\n ) => {\n const store = useSelectStore(externalStore);\n const {\n value: selectedValue,\n setValue,\n setOpen,\n setSelectedLabel,\n onValueChange,\n } = useStore(store, (s) => s);\n\n const handleClick = (\n e: MouseEvent<HTMLDivElement> | KeyboardEvent<HTMLDivElement>\n ) => {\n const labelNode = getLabelAsNode(children);\n if (!disabled) {\n // Always set the clicked value, even if it's already selected\n setValue(value);\n setSelectedLabel(labelNode);\n setOpen(false);\n onValueChange?.(value);\n }\n props.onClick?.(e as MouseEvent<HTMLDivElement>);\n };\n\n return (\n <div\n role=\"menuitem\"\n aria-disabled={disabled}\n ref={ref}\n className={`\n bg-secondary focus-visible:bg-background-50\n relative flex select-none items-center gap-2 rounded-sm p-3 outline-none transition-colors [&>svg]:size-4 [&>svg]:shrink-0\n ${className}\n ${\n disabled\n ? 'cursor-not-allowed text-text-400 pointer-events-none opacity-50'\n : 'cursor-pointer hover:bg-background-50 text-text-700 focus:bg-accent focus:text-accent-foreground hover:bg-accent hover:text-accent-foreground'\n }\n ${selectedValue === value && 'bg-background-50'}\n `}\n onClick={handleClick}\n onKeyDown={(e) => {\n if (e.key === 'Enter' || e.key === ' ') handleClick(e);\n }}\n tabIndex={disabled ? -1 : 0}\n {...props}\n >\n <span className=\"absolute right-2 flex h-3.5 w-3.5 items-center justify-center\">\n {selectedValue === value && <Check className=\"\" />}\n </span>\n {children}\n </div>\n );\n }\n);\n\nSelectItem.displayName = 'SelectItem';\n\nexport default Select;\nexport { SelectTrigger, SelectContent, SelectItem, SelectValue };\n"],"mappings":"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","names":["import_jsx_runtime","import_jsx_runtime","SIZE_CLASSES","children","label","import_phosphor_react","import_jsx_runtime"]}
1
+ {"version":3,"sources":["../../src/components/StatisticsCard/StatisticsCard.tsx","../../src/utils/utils.ts","../../src/components/Text/Text.tsx","../../src/components/Button/Button.tsx","../../src/components/Select/Select.tsx"],"sourcesContent":["import Text from '../Text/Text';\nimport Button from '../Button/Button';\nimport Select, {\n SelectTrigger,\n SelectValue,\n SelectContent,\n SelectItem,\n} from '../Select/Select';\nimport { Plus } from 'phosphor-react';\n\n/**\n * Statistics data item\n */\ninterface StatItem {\n /** Statistic label */\n label: string;\n /** Statistic value */\n value: string | number;\n /** Color variant */\n variant: 'high' | 'medium' | 'low' | 'total';\n}\n\n/**\n * Props for StatisticsCard component\n */\ninterface StatisticsCardProps {\n /** Title displayed at the top of the card */\n title: string;\n /** Statistics data to display */\n data?: StatItem[];\n /** Show placeholder \"-\" in values when true (for created items without data yet) */\n showPlaceholder?: boolean;\n /** Message shown in empty state */\n emptyStateMessage?: string;\n /** Text for the empty state button */\n emptyStateButtonText?: string;\n /** Callback when empty state button is clicked */\n onEmptyStateButtonClick?: () => void;\n /** Optional dropdown options for filtering */\n dropdownOptions?: Array<{\n label: string;\n value: string;\n }>;\n /** Currently selected dropdown value */\n selectedDropdownValue?: string;\n /** Callback when dropdown value changes */\n onDropdownChange?: (value: string) => void;\n /** Placeholder text for the dropdown select */\n selectPlaceholder?: string;\n /** Accessible label for the dropdown select */\n dropdownAriaLabel?: string;\n /** Additional CSS classes */\n className?: string;\n}\n\n/**\n * Variant styles mapping\n */\nconst VARIANT_STYLES = {\n high: 'bg-success-background',\n medium: 'bg-warning-background',\n low: 'bg-error-background',\n total: 'bg-info-background',\n} as const;\n\n/**\n * Value text colors mapping\n */\nconst VALUE_TEXT_COLORS = {\n high: 'text-success-700',\n medium: 'text-warning-600',\n low: 'text-error-700',\n total: 'text-info-700',\n} as const;\n\n/**\n * Internal StatCard component\n */\ninterface StatCardProps {\n item: StatItem;\n showPlaceholder?: boolean;\n}\n\nconst StatCard = ({ item, showPlaceholder = false }: StatCardProps) => {\n return (\n <div\n className={`rounded-xl py-[17px] px-6 min-h-[105px] flex flex-col justify-center items-start gap-1 ${VARIANT_STYLES[item.variant]}`}\n >\n <Text\n size=\"4xl\"\n weight=\"bold\"\n className={`${VALUE_TEXT_COLORS[item.variant]} leading-[42px] tracking-[0.2px] self-stretch`}\n >\n {showPlaceholder ? '-' : item.value}\n </Text>\n <Text\n size=\"xs\"\n weight=\"bold\"\n className=\"uppercase text-[8px] leading-[9px] text-text-800 whitespace-nowrap\"\n >\n {item.label}\n </Text>\n </div>\n );\n};\n\n/**\n * Get grid column class based on number of items\n */\nconst getGridColumnsClass = (itemCount: number): string => {\n if (itemCount === 4) return 'lg:grid-cols-4';\n if (itemCount === 3) return 'lg:grid-cols-3';\n if (itemCount === 2) return 'lg:grid-cols-2';\n return 'lg:grid-cols-1';\n};\n\n/**\n * StatisticsCard component - displays statistics with empty state support\n *\n * @example\n * ```tsx\n * // With data\n * <StatisticsCard\n * title=\"Estatística das atividades\"\n * data={[\n * { label: 'Acertos', value: '85%', variant: 'high' },\n * { label: 'Em andamento', value: 12, variant: 'medium' },\n * { label: 'Erros', value: '15%', variant: 'low' },\n * { label: 'Concluídas', value: 24, variant: 'total' }\n * ]}\n * dropdownOptions={[\n * { label: '1 ano', value: '1year' },\n * { label: '6 meses', value: '6months' }\n * ]}\n * selectedDropdownValue=\"1year\"\n * onDropdownChange={(value) => console.log(value)}\n * />\n *\n * // Empty state\n * <StatisticsCard\n * title=\"Estatística das atividades\"\n * emptyStateMessage=\"Sem dados por enquanto. Crie uma atividade para que os resultados apareçam aqui.\"\n * emptyStateButtonText=\"Criar atividade\"\n * onEmptyStateButtonClick={() => console.log('Create activity')}\n * />\n * ```\n */\nexport const StatisticsCard = ({\n title,\n data,\n showPlaceholder = false,\n emptyStateMessage,\n emptyStateButtonText,\n onEmptyStateButtonClick,\n dropdownOptions,\n selectedDropdownValue,\n onDropdownChange,\n selectPlaceholder = 'Selecione um período',\n dropdownAriaLabel = 'Filtro de período',\n className = '',\n}: StatisticsCardProps) => {\n const hasData = data && data.length > 0;\n const gridColumnsClass = hasData ? getGridColumnsClass(data.length) : '';\n\n return (\n <div\n className={`bg-background rounded-xl p-4 h-auto lg:h-[185px] flex flex-col gap-2 ${className}`}\n >\n {/* Header with title and optional dropdown */}\n <div className=\"flex flex-row justify-between items-center gap-4\">\n <Text\n as=\"h3\"\n size=\"sm\"\n weight=\"medium\"\n color=\"text-text-600\"\n className=\"flex-1 min-w-0\"\n >\n {title}\n </Text>\n\n {dropdownOptions && dropdownOptions.length > 0 && (\n <div className=\"w-[120px] min-w-[90px] sm:shrink-0\">\n <Select\n value={selectedDropdownValue}\n onValueChange={onDropdownChange}\n size=\"medium\"\n >\n <SelectTrigger\n className=\"border border-border-300 rounded [&>span]:whitespace-nowrap [&>span]:overflow-hidden [&>span]:text-ellipsis\"\n aria-label={dropdownAriaLabel}\n >\n <SelectValue placeholder={selectPlaceholder} />\n </SelectTrigger>\n <SelectContent className=\"min-w-[120px]\">\n {dropdownOptions.map((option) => (\n <SelectItem\n key={option.value}\n value={option.value}\n className=\"whitespace-nowrap\"\n >\n {option.label}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n )}\n </div>\n\n {/* Content: Data Grid or Empty State */}\n {hasData ? (\n <div\n className={`grid grid-cols-1 sm:grid-cols-2 gap-[13px] ${gridColumnsClass}`}\n >\n {data.map((item, index) => (\n <StatCard\n key={`${item.variant}-${item.label}-${index}`}\n item={item}\n showPlaceholder={showPlaceholder}\n />\n ))}\n </div>\n ) : (\n <div className=\"border border-dashed border-border-300 rounded-lg p-6 min-h-[105px] flex flex-col items-center justify-center gap-2\">\n <Text\n size=\"sm\"\n color=\"text-text-600\"\n className=\"text-center max-w-md\"\n >\n {emptyStateMessage}\n </Text>\n\n {onEmptyStateButtonClick && (\n <Button\n variant=\"outline\"\n action=\"primary\"\n size=\"small\"\n onClick={onEmptyStateButtonClick}\n iconLeft={<Plus size={16} weight=\"bold\" />}\n >\n {emptyStateButtonText}\n </Button>\n )}\n </div>\n )}\n </div>\n );\n};\n","import { clsx, type ClassValue } from 'clsx';\nimport { twMerge } from 'tailwind-merge';\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs));\n}\n\nexport { syncDropdownState } from './dropdown';\nexport {\n getSelectedIdsFromCategories,\n toggleArrayItem,\n toggleSingleValue,\n} from './activityFilters';\nexport {\n getStatusBadgeConfig,\n formatTimeSpent,\n formatQuestionNumbers,\n formatDateToBrazilian,\n} from './activityDetailsUtils';\n\n/**\n * Retorna a cor hexadecimal com opacidade 0.3 (4d) se não estiver em dark mode.\n * Se estiver em dark mode, retorna a cor original.\n *\n * @param hexColor - Cor hexadecimal (ex: \"#0066b8\" ou \"0066b8\")\n * @param isDark - booleano indicando se está em dark mode\n * @returns string - cor hexadecimal com opacidade se necessário\n */\nexport function getSubjectColorWithOpacity(\n hexColor: string | undefined,\n isDark: boolean\n): string | undefined {\n if (!hexColor) return undefined;\n // Remove o '#' se existir\n let color = hexColor.replace(/^#/, '').toLowerCase();\n\n if (isDark) {\n // Se está em dark mode, sempre remove opacidade se existir\n if (color.length === 8) {\n color = color.slice(0, 6);\n }\n return `#${color}`;\n } else {\n // Se não está em dark mode (light mode)\n let resultColor: string;\n if (color.length === 6) {\n // Adiciona opacidade 0.3 (4D) para cores de 6 dígitos\n resultColor = `#${color}4d`;\n } else if (color.length === 8) {\n // Já tem opacidade, retorna como está\n resultColor = `#${color}`;\n } else {\n // Para outros tamanhos (3, 4, 5 dígitos), retorna como está\n resultColor = `#${color}`;\n }\n return resultColor;\n }\n}\n","import { ComponentPropsWithoutRef, ElementType, ReactNode } from 'react';\nimport { cn } from '../../utils/utils';\n\n/**\n * Base text component props\n */\ntype BaseTextProps = {\n /** Content to be displayed */\n children?: ReactNode;\n /** Text size variant */\n size?:\n | '2xs'\n | 'xs'\n | 'sm'\n | 'md'\n | 'lg'\n | 'xl'\n | '2xl'\n | '3xl'\n | '4xl'\n | '5xl'\n | '6xl';\n /** Font weight variant */\n weight?:\n | 'hairline'\n | 'light'\n | 'normal'\n | 'medium'\n | 'semibold'\n | 'bold'\n | 'extrabold'\n | 'black';\n /** Color variant - white for light backgrounds, black for dark backgrounds */\n color?: string;\n /** Additional CSS classes to apply */\n className?: string;\n};\n\n/**\n * Polymorphic text component props that ensures type safety based on the 'as' prop\n */\ntype TextProps<T extends ElementType = 'p'> = BaseTextProps & {\n /** HTML tag to render */\n as?: T;\n} & Omit<ComponentPropsWithoutRef<T>, keyof BaseTextProps>;\n\n/**\n * Text component for Analytica Ensino platforms\n *\n * A flexible polymorphic text component with multiple sizes, weights, and colors.\n * Automatically adapts to dark and light themes with full type safety.\n *\n * @param children - The content to display\n * @param size - The text size variant (2xs, xs, sm, md, lg, xl, 2xl, 3xl, 4xl, 5xl, 6xl)\n * @param weight - The font weight variant (hairline, light, normal, medium, semibold, bold, extrabold, black)\n * @param color - The color variant - adapts to theme\n * @param as - The HTML tag to render - determines allowed attributes via TypeScript\n * @param className - Additional CSS classes\n * @param props - HTML attributes valid for the chosen tag only\n * @returns A styled text element with type-safe attributes\n *\n * @example\n * ```tsx\n * <Text size=\"lg\" weight=\"bold\" color=\"text-info-800\">\n * This is a large, bold text\n * </Text>\n *\n * <Text as=\"a\" href=\"/link\" target=\"_blank\">\n * Link with type-safe anchor attributes\n * </Text>\n *\n * <Text as=\"button\" onClick={handleClick} disabled>\n * Button with type-safe button attributes\n * </Text>\n * ```\n */\nconst Text = <T extends ElementType = 'p'>({\n children,\n size = 'md',\n weight = 'normal',\n color = 'text-text-950',\n as,\n className = '',\n ...props\n}: TextProps<T>) => {\n let sizeClasses = '';\n let weightClasses = '';\n\n // Text size classes mapping\n const sizeClassMap = {\n '2xs': 'text-2xs',\n xs: 'text-xs',\n sm: 'text-sm',\n md: 'text-md',\n lg: 'text-lg',\n xl: 'text-xl',\n '2xl': 'text-2xl',\n '3xl': 'text-3xl',\n '4xl': 'text-4xl',\n '5xl': 'text-5xl',\n '6xl': 'text-6xl',\n } as const;\n\n sizeClasses = sizeClassMap[size] ?? sizeClassMap.md;\n\n // Font weight classes mapping\n const weightClassMap = {\n hairline: 'font-hairline',\n light: 'font-light',\n normal: 'font-normal',\n medium: 'font-medium',\n semibold: 'font-semibold',\n bold: 'font-bold',\n extrabold: 'font-extrabold',\n black: 'font-black',\n } as const;\n\n weightClasses = weightClassMap[weight] ?? weightClassMap.normal;\n\n const baseClasses = 'font-primary';\n const Component = as ?? ('p' as ElementType);\n\n return (\n <Component\n className={cn(baseClasses, sizeClasses, weightClasses, color, className)}\n {...props}\n >\n {children}\n </Component>\n );\n};\n\nexport default Text;\n","import { ButtonHTMLAttributes, ReactNode } from 'react';\nimport { cn } from '../../utils/utils';\n\n/**\n * Lookup table for variant and action class combinations\n */\nconst VARIANT_ACTION_CLASSES = {\n solid: {\n primary:\n 'bg-primary-950 text-text border border-primary-950 hover:bg-primary-800 hover:border-primary-800 focus-visible:outline-none focus-visible:bg-primary-950 focus-visible:ring-2 focus-visible:ring-offset-0 focus-visible:ring-indicator-info active:bg-primary-700 active:border-primary-700 disabled:bg-primary-500 disabled:border-primary-500 disabled:opacity-40 disabled:cursor-not-allowed',\n positive:\n 'bg-success-500 text-text border border-success-500 hover:bg-success-600 hover:border-success-600 focus-visible:outline-none focus-visible:bg-success-500 focus-visible:ring-2 focus-visible:ring-offset-0 focus-visible:ring-indicator-info active:bg-success-700 active:border-success-700 disabled:bg-success-500 disabled:border-success-500 disabled:opacity-40 disabled:cursor-not-allowed',\n negative:\n 'bg-error-500 text-text border border-error-500 hover:bg-error-600 hover:border-error-600 focus-visible:outline-none focus-visible:bg-error-500 focus-visible:ring-2 focus-visible:ring-offset-0 focus-visible:ring-indicator-info active:bg-error-700 active:border-error-700 disabled:bg-error-500 disabled:border-error-500 disabled:opacity-40 disabled:cursor-not-allowed',\n },\n outline: {\n primary:\n 'bg-transparent text-primary-950 border border-primary-950 hover:bg-background-50 hover:text-primary-400 hover:border-primary-400 focus-visible:border-0 focus-visible:outline-none focus-visible:text-primary-600 focus-visible:ring-2 focus-visible:ring-offset-0 focus-visible:ring-indicator-info active:text-primary-700 active:border-primary-700 disabled:opacity-40 disabled:cursor-not-allowed',\n positive:\n 'bg-transparent text-success-500 border border-success-300 hover:bg-background-50 hover:text-success-400 hover:border-success-400 focus-visible:border-0 focus-visible:outline-none focus-visible:text-success-600 focus-visible:ring-2 focus-visible:ring-offset-0 focus-visible:ring-indicator-info active:text-success-700 active:border-success-700 disabled:opacity-40 disabled:cursor-not-allowed',\n negative:\n 'bg-transparent text-error-500 border border-error-300 hover:bg-background-50 hover:text-error-400 hover:border-error-400 focus-visible:border-0 focus-visible:outline-none focus-visible:text-error-600 focus-visible:ring-2 focus-visible:ring-offset-0 focus-visible:ring-indicator-info active:text-error-700 active:border-error-700 disabled:opacity-40 disabled:cursor-not-allowed',\n },\n link: {\n primary:\n 'bg-transparent text-primary-950 hover:text-primary-400 focus-visible:outline-none focus-visible:text-primary-600 focus-visible:ring-2 focus-visible:ring-offset-0 focus-visible:ring-indicator-info active:text-primary-700 disabled:opacity-40 disabled:cursor-not-allowed',\n positive:\n 'bg-transparent text-success-500 hover:text-success-400 focus-visible:outline-none focus-visible:text-success-600 focus-visible:ring-2 focus-visible:ring-offset-0 focus-visible:ring-indicator-info active:text-success-700 disabled:opacity-40 disabled:cursor-not-allowed',\n negative:\n 'bg-transparent text-error-500 hover:text-error-400 focus-visible:outline-none focus-visible:text-error-600 focus-visible:ring-2 focus-visible:ring-offset-0 focus-visible:ring-indicator-info active:text-error-700 disabled:opacity-40 disabled:cursor-not-allowed',\n },\n} as const;\n\n/**\n * Lookup table for size classes\n */\nconst SIZE_CLASSES = {\n 'extra-small': 'text-xs px-3.5 py-2',\n small: 'text-sm px-4 py-2.5',\n medium: 'text-md px-5 py-2.5',\n large: 'text-lg px-6 py-3',\n 'extra-large': 'text-lg px-7 py-3.5',\n} as const;\n\n/**\n * Button component props interface\n */\ntype ButtonProps = {\n /** Content to be displayed inside the button */\n children: ReactNode;\n /** Ícone à esquerda do texto */\n iconLeft?: ReactNode;\n /** Ícone à direita do texto */\n iconRight?: ReactNode;\n /** Size of the button */\n size?: 'extra-small' | 'small' | 'medium' | 'large' | 'extra-large';\n /** Visual variant of the button */\n variant?: 'solid' | 'outline' | 'link';\n /** Action type of the button */\n action?: 'primary' | 'positive' | 'negative';\n /** Additional CSS classes to apply */\n className?: string;\n} & ButtonHTMLAttributes<HTMLButtonElement>;\n\n/**\n * Button component for Analytica Ensino platforms\n *\n * A flexible button component with multiple variants, sizes and actions.\n *\n * @param children - The content to display inside the button\n * @param size - The size variant (extra-small, small, medium, large, extra-large)\n * @param variant - The visual style variant (solid, outline, link)\n * @param action - The action type (primary, positive, negative)\n * @param className - Additional CSS classes\n * @param props - All other standard button HTML attributes\n * @returns A styled button element\n *\n * @example\n * ```tsx\n * <Button variant=\"solid\" action=\"primary\" size=\"medium\" onClick={() => console.log('clicked')}>\n * Click me\n * </Button>\n * ```\n */\nconst Button = ({\n children,\n iconLeft,\n iconRight,\n size = 'medium',\n variant = 'solid',\n action = 'primary',\n className = '',\n disabled,\n type = 'button',\n ...props\n}: ButtonProps) => {\n // Get classes from lookup tables\n const sizeClasses = SIZE_CLASSES[size];\n const variantClasses = VARIANT_ACTION_CLASSES[variant][action];\n\n const baseClasses =\n 'inline-flex items-center justify-center rounded-full cursor-pointer font-medium';\n\n return (\n <button\n className={cn(baseClasses, variantClasses, sizeClasses, className)}\n disabled={disabled}\n type={type}\n {...props}\n >\n {iconLeft && <span className=\"mr-2 flex items-center\">{iconLeft}</span>}\n {children}\n {iconRight && <span className=\"ml-2 flex items-center\">{iconRight}</span>}\n </button>\n );\n};\n\nexport default Button;\n","import { create, StoreApi, useStore } from 'zustand';\nimport {\n ReactNode,\n useEffect,\n useRef,\n ButtonHTMLAttributes,\n forwardRef,\n HTMLAttributes,\n KeyboardEvent,\n MouseEvent,\n ReactElement,\n isValidElement,\n Children,\n cloneElement,\n useId,\n} from 'react';\nimport { CaretDown, Check, WarningCircle } from 'phosphor-react';\nimport { cn } from '../../utils/utils';\n\nconst VARIANT_CLASSES = {\n outlined: 'border-2 rounded-lg focus:border-primary-950',\n underlined: 'border-b-2 focus:border-primary-950',\n rounded: 'border-2 rounded-full focus:border-primary-950',\n} as const;\n\nconst SIZE_CLASSES = {\n small: 'text-sm',\n medium: 'text-md',\n large: 'text-lg',\n 'extra-large': 'text-lg',\n} as const;\n\nconst HEIGHT_CLASSES = {\n small: 'h-8',\n medium: 'h-9',\n large: 'h-10',\n 'extra-large': 'h-12',\n} as const;\n\nconst PADDING_CLASSES = {\n small: 'px-2 py-1',\n medium: 'px-3 py-2',\n large: 'px-4 py-3',\n 'extra-large': 'px-5 py-4',\n} as const;\n\nconst SIDE_CLASSES = {\n top: 'bottom-full -translate-y-1',\n right: 'top-full translate-y-1',\n bottom: 'top-full translate-y-1',\n left: 'top-full translate-y-1',\n};\nconst ALIGN_CLASSES = {\n start: 'left-0',\n center: 'left-1/2 -translate-x-1/2',\n end: 'right-0',\n};\n\ninterface SelectStore {\n open: boolean;\n setOpen: (open: boolean) => void;\n value: string;\n setValue: (value: string) => void;\n selectedLabel: ReactNode;\n setSelectedLabel: (label: ReactNode) => void;\n onValueChange?: (value: string) => void;\n}\n\ntype SelectStoreApi = StoreApi<SelectStore>;\n\nexport function createSelectStore(\n onValueChange?: (value: string) => void\n): SelectStoreApi {\n return create<SelectStore>((set) => ({\n open: false,\n setOpen: (open) => set({ open }),\n value: '',\n setValue: (value) => set({ value }),\n selectedLabel: '',\n setSelectedLabel: (label) => set({ selectedLabel: label }),\n onValueChange,\n }));\n}\n\nexport const useSelectStore = (externalStore?: SelectStoreApi) => {\n if (!externalStore) {\n throw new Error(\n 'Component must be used within a Select (store is missing)'\n );\n }\n\n return externalStore;\n};\n\nexport function getLabelAsNode(children: ReactNode): ReactNode {\n if (typeof children === 'string' || typeof children === 'number') {\n return children;\n }\n const flattened = Children.toArray(children);\n\n if (flattened.length === 1) return flattened[0];\n\n return <>{flattened}</>;\n}\n\ninterface SelectProps {\n className?: string;\n children: ReactNode;\n defaultValue?: string;\n value?: string;\n onValueChange?: (value: string) => void;\n size?: 'small' | 'medium' | 'large' | 'extra-large';\n label?: string;\n helperText?: string;\n errorMessage?: string;\n id?: string;\n}\n\nconst injectStore = (\n children: ReactNode,\n store: SelectStoreApi,\n size: string,\n selectId: string\n): ReactNode => {\n return Children.map(children, (child) => {\n if (isValidElement(child)) {\n const typedChild = child as ReactElement<{\n store?: SelectStoreApi;\n children?: ReactNode;\n size?: string;\n selectId?: string;\n }>;\n\n const newProps: Partial<{\n store: SelectStoreApi;\n children: ReactNode;\n size: string;\n selectId: string;\n }> = {\n store,\n };\n\n // Only pass size and selectId to SelectTrigger\n if (typedChild.type === SelectTrigger) {\n newProps.size = size;\n newProps.selectId = selectId;\n }\n\n if (typedChild.props.children) {\n newProps.children = injectStore(\n typedChild.props.children,\n store,\n size,\n selectId\n );\n }\n\n return cloneElement(typedChild, newProps);\n }\n return child;\n });\n};\n\nconst Select = ({\n children,\n defaultValue = '',\n className,\n value: propValue,\n onValueChange,\n size = 'small',\n label,\n helperText,\n errorMessage,\n id,\n}: SelectProps) => {\n const storeRef = useRef<SelectStoreApi | null>(null);\n storeRef.current ??= createSelectStore(onValueChange);\n const store = storeRef.current;\n\n const selectRef = useRef<HTMLDivElement>(null);\n const { open, setOpen, setValue, selectedLabel } = useStore(store, (s) => s);\n\n // Generate unique ID if not provided\n const generatedId = useId();\n const selectId = id ?? `select-${generatedId}`;\n\n const findLabelForValue = (\n children: ReactNode,\n targetValue: string\n ): string | null => {\n let found: string | null = null;\n const search = (nodes: ReactNode) => {\n Children.forEach(nodes, (child) => {\n if (!isValidElement(child)) return;\n const typedChild = child as ReactElement<{\n value?: string;\n children?: ReactNode;\n }>;\n if (\n typedChild.type === SelectItem &&\n typedChild.props.value === targetValue\n ) {\n if (typeof typedChild.props.children === 'string')\n found = typedChild.props.children;\n }\n if (typedChild.props.children && !found)\n search(typedChild.props.children);\n });\n };\n search(children);\n return found;\n };\n\n useEffect(() => {\n if (!selectedLabel && defaultValue) {\n const label = findLabelForValue(children, defaultValue);\n if (label) store.setState({ selectedLabel: label });\n }\n }, [children, defaultValue, selectedLabel]);\n\n useEffect(() => {\n const handleClickOutside = (event: globalThis.MouseEvent) => {\n if (\n selectRef.current &&\n !selectRef.current.contains(event.target as Node)\n ) {\n setOpen(false);\n }\n };\n\n const handleArrowKeys = (event: globalThis.KeyboardEvent) => {\n const selectContent = selectRef.current?.querySelector('[role=\"menu\"]');\n if (selectContent) {\n event.preventDefault();\n const items = Array.from(\n selectContent.querySelectorAll(\n '[role=\"menuitem\"]:not([aria-disabled=\"true\"])'\n )\n ).filter((el): el is HTMLElement => el instanceof HTMLElement);\n\n const focused = document.activeElement as HTMLElement;\n const currentIndex = items.findIndex((item) => item === focused);\n\n let nextIndex = 0;\n if (event.key === 'ArrowDown') {\n nextIndex =\n currentIndex === -1 ? 0 : (currentIndex + 1) % items.length;\n } else {\n nextIndex =\n currentIndex === -1\n ? items.length - 1\n : (currentIndex - 1 + items.length) % items.length;\n }\n items[nextIndex]?.focus();\n }\n };\n\n if (open) {\n document.addEventListener('mousedown', handleClickOutside);\n document.addEventListener('keydown', handleArrowKeys);\n }\n return () => {\n document.removeEventListener('mousedown', handleClickOutside);\n document.removeEventListener('keydown', handleArrowKeys);\n };\n }, [open]);\n\n useEffect(() => {\n if (propValue) {\n setValue(propValue);\n const label = findLabelForValue(children, propValue);\n if (label) store.setState({ selectedLabel: label });\n }\n }, [propValue]);\n\n const sizeClasses = SIZE_CLASSES[size];\n\n return (\n <div className={cn('w-full', className)}>\n {/* Label */}\n {label && (\n <label\n htmlFor={selectId}\n className={cn('block font-bold text-text-900 mb-1.5', sizeClasses)}\n >\n {label}\n </label>\n )}\n\n {/* Select Container */}\n <div className={cn('relative w-full')} ref={selectRef}>\n {injectStore(children, store, size, selectId)}\n </div>\n\n {/* Helper Text or Error Message */}\n {(helperText || errorMessage) && (\n <div className=\"mt-1.5 gap-1.5\">\n {helperText && <p className=\"text-sm text-text-500\">{helperText}</p>}\n {errorMessage && (\n <p className=\"flex gap-1 items-center text-sm text-indicator-error\">\n <WarningCircle size={16} /> {errorMessage}\n </p>\n )}\n </div>\n )}\n </div>\n );\n};\n\nconst SelectValue = ({\n placeholder,\n store: externalStore,\n}: {\n placeholder?: string;\n store?: SelectStoreApi;\n}) => {\n const store = useSelectStore(externalStore);\n\n const selectedLabel = useStore(store, (s) => s.selectedLabel);\n const value = useStore(store, (s) => s.value);\n return (\n <span className=\"text-inherit flex gap-2 items-center\">\n {selectedLabel || placeholder || value}\n </span>\n );\n};\n\ninterface SelectTriggerProps extends ButtonHTMLAttributes<HTMLButtonElement> {\n className?: string;\n invalid?: boolean;\n variant?: 'outlined' | 'underlined' | 'rounded';\n store?: SelectStoreApi;\n size?: 'small' | 'medium' | 'large' | 'extra-large';\n selectId?: string;\n}\n\nconst SelectTrigger = forwardRef<HTMLButtonElement, SelectTriggerProps>(\n (\n {\n className,\n invalid = false,\n variant = 'outlined',\n store: externalStore,\n disabled,\n size = 'medium',\n selectId,\n ...props\n },\n ref\n ) => {\n const store = useSelectStore(externalStore);\n const open = useStore(store, (s) => s.open);\n const toggleOpen = () => store.setState({ open: !open });\n\n const variantClasses = VARIANT_CLASSES[variant];\n const heightClasses = HEIGHT_CLASSES[size];\n const paddingClasses = PADDING_CLASSES[size];\n\n return (\n <button\n ref={ref}\n id={selectId}\n className={cn(\n 'flex w-full items-center justify-between border-border-300',\n heightClasses,\n paddingClasses,\n invalid &&\n `${variant == 'underlined' ? 'border-b-2' : 'border-2'} border-indicator-error text-text-600`,\n disabled\n ? 'cursor-not-allowed text-text-400 pointer-events-none opacity-50'\n : 'cursor-pointer hover:bg-background-50 focus:bg-accent focus:text-accent-foreground hover:bg-accent hover:text-accent-foreground',\n !invalid && !disabled ? 'text-text-700' : '',\n variantClasses,\n className\n )}\n onClick={toggleOpen}\n aria-expanded={open}\n aria-haspopup=\"listbox\"\n aria-controls={open ? 'select-content' : undefined}\n {...props}\n >\n {props.children}\n <CaretDown\n className={cn(\n 'h-[1em] w-[1em] opacity-50 transition-transform',\n open ? 'rotate-180' : ''\n )}\n />\n </button>\n );\n }\n);\nSelectTrigger.displayName = 'SelectTrigger';\n\ninterface SelectContentProps extends HTMLAttributes<HTMLDivElement> {\n className?: string;\n align?: 'start' | 'center' | 'end';\n side?: 'top' | 'right' | 'bottom' | 'left';\n store?: SelectStoreApi;\n}\n\nconst SelectContent = forwardRef<HTMLDivElement, SelectContentProps>(\n (\n {\n children,\n className,\n align = 'start',\n side = 'bottom',\n store: externalStore,\n ...props\n },\n ref\n ) => {\n const store = useSelectStore(externalStore);\n\n const open = useStore(store, (s) => s.open);\n if (!open) return null;\n\n const getPositionClasses = () =>\n `w-full min-w-full absolute ${SIDE_CLASSES[side]} ${ALIGN_CLASSES[align]}`;\n\n return (\n <div\n role=\"menu\"\n ref={ref}\n className={cn(\n 'bg-secondary z-50 min-w-[210px] max-h-[300px] overflow-y-auto overflow-x-hidden rounded-md border p-1 shadow-md border-border-100',\n getPositionClasses(),\n className\n )}\n {...props}\n >\n {children}\n </div>\n );\n }\n);\nSelectContent.displayName = 'SelectContent';\n\ninterface SelectItemProps extends HTMLAttributes<HTMLDivElement> {\n value: string;\n disabled?: boolean;\n store?: SelectStoreApi;\n}\n\nconst SelectItem = forwardRef<HTMLDivElement, SelectItemProps>(\n (\n {\n className,\n children,\n value,\n disabled = false,\n store: externalStore,\n ...props\n },\n ref\n ) => {\n const store = useSelectStore(externalStore);\n const {\n value: selectedValue,\n setValue,\n setOpen,\n setSelectedLabel,\n onValueChange,\n } = useStore(store, (s) => s);\n\n const handleClick = (\n e: MouseEvent<HTMLDivElement> | KeyboardEvent<HTMLDivElement>\n ) => {\n const labelNode = getLabelAsNode(children);\n if (!disabled) {\n // Always set the clicked value, even if it's already selected\n setValue(value);\n setSelectedLabel(labelNode);\n setOpen(false);\n onValueChange?.(value);\n }\n props.onClick?.(e as MouseEvent<HTMLDivElement>);\n };\n\n return (\n <div\n role=\"menuitem\"\n aria-disabled={disabled}\n ref={ref}\n className={`\n bg-secondary focus-visible:bg-background-50\n relative flex select-none items-center gap-2 rounded-sm p-3 outline-none transition-colors [&>svg]:size-4 [&>svg]:shrink-0\n ${className}\n ${\n disabled\n ? 'cursor-not-allowed text-text-400 pointer-events-none opacity-50'\n : 'cursor-pointer hover:bg-background-50 text-text-700 focus:bg-accent focus:text-accent-foreground hover:bg-accent hover:text-accent-foreground'\n }\n ${selectedValue === value && 'bg-background-50'}\n `}\n onClick={handleClick}\n onKeyDown={(e) => {\n if (e.key === 'Enter' || e.key === ' ') handleClick(e);\n }}\n tabIndex={disabled ? -1 : 0}\n {...props}\n >\n <span className=\"absolute right-2 flex h-3.5 w-3.5 items-center justify-center\">\n {selectedValue === value && <Check className=\"\" />}\n </span>\n {children}\n </div>\n );\n }\n);\n\nSelectItem.displayName = 'SelectItem';\n\nexport default Select;\nexport { SelectTrigger, SelectContent, SelectItem, SelectValue };\n"],"mappings":"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","names":["import_jsx_runtime","import_jsx_runtime","SIZE_CLASSES","children","label","import_phosphor_react","import_jsx_runtime"]}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/utils/utils.ts","../../src/components/Text/Text.tsx","../../src/components/Button/Button.tsx","../../src/components/Select/Select.tsx","../../src/components/StatisticsCard/StatisticsCard.tsx"],"sourcesContent":["import { clsx, type ClassValue } from 'clsx';\nimport { twMerge } from 'tailwind-merge';\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs));\n}\n\nexport { syncDropdownState } from './dropdown';\nexport {\n getSelectedIdsFromCategories,\n toggleArrayItem,\n toggleSingleValue,\n} from './activityFilters';\n\n/**\n * Retorna a cor hexadecimal com opacidade 0.3 (4d) se não estiver em dark mode.\n * Se estiver em dark mode, retorna a cor original.\n *\n * @param hexColor - Cor hexadecimal (ex: \"#0066b8\" ou \"0066b8\")\n * @param isDark - booleano indicando se está em dark mode\n * @returns string - cor hexadecimal com opacidade se necessário\n */\nexport function getSubjectColorWithOpacity(\n hexColor: string | undefined,\n isDark: boolean\n): string | undefined {\n if (!hexColor) return undefined;\n // Remove o '#' se existir\n let color = hexColor.replace(/^#/, '').toLowerCase();\n\n if (isDark) {\n // Se está em dark mode, sempre remove opacidade se existir\n if (color.length === 8) {\n color = color.slice(0, 6);\n }\n return `#${color}`;\n } else {\n // Se não está em dark mode (light mode)\n let resultColor: string;\n if (color.length === 6) {\n // Adiciona opacidade 0.3 (4D) para cores de 6 dígitos\n resultColor = `#${color}4d`;\n } else if (color.length === 8) {\n // Já tem opacidade, retorna como está\n resultColor = `#${color}`;\n } else {\n // Para outros tamanhos (3, 4, 5 dígitos), retorna como está\n resultColor = `#${color}`;\n }\n return resultColor;\n }\n}\n","import { ComponentPropsWithoutRef, ElementType, ReactNode } from 'react';\nimport { cn } from '../../utils/utils';\n\n/**\n * Base text component props\n */\ntype BaseTextProps = {\n /** Content to be displayed */\n children?: ReactNode;\n /** Text size variant */\n size?:\n | '2xs'\n | 'xs'\n | 'sm'\n | 'md'\n | 'lg'\n | 'xl'\n | '2xl'\n | '3xl'\n | '4xl'\n | '5xl'\n | '6xl';\n /** Font weight variant */\n weight?:\n | 'hairline'\n | 'light'\n | 'normal'\n | 'medium'\n | 'semibold'\n | 'bold'\n | 'extrabold'\n | 'black';\n /** Color variant - white for light backgrounds, black for dark backgrounds */\n color?: string;\n /** Additional CSS classes to apply */\n className?: string;\n};\n\n/**\n * Polymorphic text component props that ensures type safety based on the 'as' prop\n */\ntype TextProps<T extends ElementType = 'p'> = BaseTextProps & {\n /** HTML tag to render */\n as?: T;\n} & Omit<ComponentPropsWithoutRef<T>, keyof BaseTextProps>;\n\n/**\n * Text component for Analytica Ensino platforms\n *\n * A flexible polymorphic text component with multiple sizes, weights, and colors.\n * Automatically adapts to dark and light themes with full type safety.\n *\n * @param children - The content to display\n * @param size - The text size variant (2xs, xs, sm, md, lg, xl, 2xl, 3xl, 4xl, 5xl, 6xl)\n * @param weight - The font weight variant (hairline, light, normal, medium, semibold, bold, extrabold, black)\n * @param color - The color variant - adapts to theme\n * @param as - The HTML tag to render - determines allowed attributes via TypeScript\n * @param className - Additional CSS classes\n * @param props - HTML attributes valid for the chosen tag only\n * @returns A styled text element with type-safe attributes\n *\n * @example\n * ```tsx\n * <Text size=\"lg\" weight=\"bold\" color=\"text-info-800\">\n * This is a large, bold text\n * </Text>\n *\n * <Text as=\"a\" href=\"/link\" target=\"_blank\">\n * Link with type-safe anchor attributes\n * </Text>\n *\n * <Text as=\"button\" onClick={handleClick} disabled>\n * Button with type-safe button attributes\n * </Text>\n * ```\n */\nconst Text = <T extends ElementType = 'p'>({\n children,\n size = 'md',\n weight = 'normal',\n color = 'text-text-950',\n as,\n className = '',\n ...props\n}: TextProps<T>) => {\n let sizeClasses = '';\n let weightClasses = '';\n\n // Text size classes mapping\n const sizeClassMap = {\n '2xs': 'text-2xs',\n xs: 'text-xs',\n sm: 'text-sm',\n md: 'text-md',\n lg: 'text-lg',\n xl: 'text-xl',\n '2xl': 'text-2xl',\n '3xl': 'text-3xl',\n '4xl': 'text-4xl',\n '5xl': 'text-5xl',\n '6xl': 'text-6xl',\n } as const;\n\n sizeClasses = sizeClassMap[size] ?? sizeClassMap.md;\n\n // Font weight classes mapping\n const weightClassMap = {\n hairline: 'font-hairline',\n light: 'font-light',\n normal: 'font-normal',\n medium: 'font-medium',\n semibold: 'font-semibold',\n bold: 'font-bold',\n extrabold: 'font-extrabold',\n black: 'font-black',\n } as const;\n\n weightClasses = weightClassMap[weight] ?? weightClassMap.normal;\n\n const baseClasses = 'font-primary';\n const Component = as ?? ('p' as ElementType);\n\n return (\n <Component\n className={cn(baseClasses, sizeClasses, weightClasses, color, className)}\n {...props}\n >\n {children}\n </Component>\n );\n};\n\nexport default Text;\n","import { ButtonHTMLAttributes, ReactNode } from 'react';\nimport { cn } from '../../utils/utils';\n\n/**\n * Lookup table for variant and action class combinations\n */\nconst VARIANT_ACTION_CLASSES = {\n solid: {\n primary:\n 'bg-primary-950 text-text border border-primary-950 hover:bg-primary-800 hover:border-primary-800 focus-visible:outline-none focus-visible:bg-primary-950 focus-visible:ring-2 focus-visible:ring-offset-0 focus-visible:ring-indicator-info active:bg-primary-700 active:border-primary-700 disabled:bg-primary-500 disabled:border-primary-500 disabled:opacity-40 disabled:cursor-not-allowed',\n positive:\n 'bg-success-500 text-text border border-success-500 hover:bg-success-600 hover:border-success-600 focus-visible:outline-none focus-visible:bg-success-500 focus-visible:ring-2 focus-visible:ring-offset-0 focus-visible:ring-indicator-info active:bg-success-700 active:border-success-700 disabled:bg-success-500 disabled:border-success-500 disabled:opacity-40 disabled:cursor-not-allowed',\n negative:\n 'bg-error-500 text-text border border-error-500 hover:bg-error-600 hover:border-error-600 focus-visible:outline-none focus-visible:bg-error-500 focus-visible:ring-2 focus-visible:ring-offset-0 focus-visible:ring-indicator-info active:bg-error-700 active:border-error-700 disabled:bg-error-500 disabled:border-error-500 disabled:opacity-40 disabled:cursor-not-allowed',\n },\n outline: {\n primary:\n 'bg-transparent text-primary-950 border border-primary-950 hover:bg-background-50 hover:text-primary-400 hover:border-primary-400 focus-visible:border-0 focus-visible:outline-none focus-visible:text-primary-600 focus-visible:ring-2 focus-visible:ring-offset-0 focus-visible:ring-indicator-info active:text-primary-700 active:border-primary-700 disabled:opacity-40 disabled:cursor-not-allowed',\n positive:\n 'bg-transparent text-success-500 border border-success-300 hover:bg-background-50 hover:text-success-400 hover:border-success-400 focus-visible:border-0 focus-visible:outline-none focus-visible:text-success-600 focus-visible:ring-2 focus-visible:ring-offset-0 focus-visible:ring-indicator-info active:text-success-700 active:border-success-700 disabled:opacity-40 disabled:cursor-not-allowed',\n negative:\n 'bg-transparent text-error-500 border border-error-300 hover:bg-background-50 hover:text-error-400 hover:border-error-400 focus-visible:border-0 focus-visible:outline-none focus-visible:text-error-600 focus-visible:ring-2 focus-visible:ring-offset-0 focus-visible:ring-indicator-info active:text-error-700 active:border-error-700 disabled:opacity-40 disabled:cursor-not-allowed',\n },\n link: {\n primary:\n 'bg-transparent text-primary-950 hover:text-primary-400 focus-visible:outline-none focus-visible:text-primary-600 focus-visible:ring-2 focus-visible:ring-offset-0 focus-visible:ring-indicator-info active:text-primary-700 disabled:opacity-40 disabled:cursor-not-allowed',\n positive:\n 'bg-transparent text-success-500 hover:text-success-400 focus-visible:outline-none focus-visible:text-success-600 focus-visible:ring-2 focus-visible:ring-offset-0 focus-visible:ring-indicator-info active:text-success-700 disabled:opacity-40 disabled:cursor-not-allowed',\n negative:\n 'bg-transparent text-error-500 hover:text-error-400 focus-visible:outline-none focus-visible:text-error-600 focus-visible:ring-2 focus-visible:ring-offset-0 focus-visible:ring-indicator-info active:text-error-700 disabled:opacity-40 disabled:cursor-not-allowed',\n },\n} as const;\n\n/**\n * Lookup table for size classes\n */\nconst SIZE_CLASSES = {\n 'extra-small': 'text-xs px-3.5 py-2',\n small: 'text-sm px-4 py-2.5',\n medium: 'text-md px-5 py-2.5',\n large: 'text-lg px-6 py-3',\n 'extra-large': 'text-lg px-7 py-3.5',\n} as const;\n\n/**\n * Button component props interface\n */\ntype ButtonProps = {\n /** Content to be displayed inside the button */\n children: ReactNode;\n /** Ícone à esquerda do texto */\n iconLeft?: ReactNode;\n /** Ícone à direita do texto */\n iconRight?: ReactNode;\n /** Size of the button */\n size?: 'extra-small' | 'small' | 'medium' | 'large' | 'extra-large';\n /** Visual variant of the button */\n variant?: 'solid' | 'outline' | 'link';\n /** Action type of the button */\n action?: 'primary' | 'positive' | 'negative';\n /** Additional CSS classes to apply */\n className?: string;\n} & ButtonHTMLAttributes<HTMLButtonElement>;\n\n/**\n * Button component for Analytica Ensino platforms\n *\n * A flexible button component with multiple variants, sizes and actions.\n *\n * @param children - The content to display inside the button\n * @param size - The size variant (extra-small, small, medium, large, extra-large)\n * @param variant - The visual style variant (solid, outline, link)\n * @param action - The action type (primary, positive, negative)\n * @param className - Additional CSS classes\n * @param props - All other standard button HTML attributes\n * @returns A styled button element\n *\n * @example\n * ```tsx\n * <Button variant=\"solid\" action=\"primary\" size=\"medium\" onClick={() => console.log('clicked')}>\n * Click me\n * </Button>\n * ```\n */\nconst Button = ({\n children,\n iconLeft,\n iconRight,\n size = 'medium',\n variant = 'solid',\n action = 'primary',\n className = '',\n disabled,\n type = 'button',\n ...props\n}: ButtonProps) => {\n // Get classes from lookup tables\n const sizeClasses = SIZE_CLASSES[size];\n const variantClasses = VARIANT_ACTION_CLASSES[variant][action];\n\n const baseClasses =\n 'inline-flex items-center justify-center rounded-full cursor-pointer font-medium';\n\n return (\n <button\n className={cn(baseClasses, variantClasses, sizeClasses, className)}\n disabled={disabled}\n type={type}\n {...props}\n >\n {iconLeft && <span className=\"mr-2 flex items-center\">{iconLeft}</span>}\n {children}\n {iconRight && <span className=\"ml-2 flex items-center\">{iconRight}</span>}\n </button>\n );\n};\n\nexport default Button;\n","import { create, StoreApi, useStore } from 'zustand';\nimport {\n ReactNode,\n useEffect,\n useRef,\n ButtonHTMLAttributes,\n forwardRef,\n HTMLAttributes,\n KeyboardEvent,\n MouseEvent,\n ReactElement,\n isValidElement,\n Children,\n cloneElement,\n useId,\n} from 'react';\nimport { CaretDown, Check, WarningCircle } from 'phosphor-react';\nimport { cn } from '../../utils/utils';\n\nconst VARIANT_CLASSES = {\n outlined: 'border-2 rounded-lg focus:border-primary-950',\n underlined: 'border-b-2 focus:border-primary-950',\n rounded: 'border-2 rounded-full focus:border-primary-950',\n} as const;\n\nconst SIZE_CLASSES = {\n small: 'text-sm',\n medium: 'text-md',\n large: 'text-lg',\n 'extra-large': 'text-lg',\n} as const;\n\nconst HEIGHT_CLASSES = {\n small: 'h-8',\n medium: 'h-9',\n large: 'h-10',\n 'extra-large': 'h-12',\n} as const;\n\nconst PADDING_CLASSES = {\n small: 'px-2 py-1',\n medium: 'px-3 py-2',\n large: 'px-4 py-3',\n 'extra-large': 'px-5 py-4',\n} as const;\n\nconst SIDE_CLASSES = {\n top: 'bottom-full -translate-y-1',\n right: 'top-full translate-y-1',\n bottom: 'top-full translate-y-1',\n left: 'top-full translate-y-1',\n};\nconst ALIGN_CLASSES = {\n start: 'left-0',\n center: 'left-1/2 -translate-x-1/2',\n end: 'right-0',\n};\n\ninterface SelectStore {\n open: boolean;\n setOpen: (open: boolean) => void;\n value: string;\n setValue: (value: string) => void;\n selectedLabel: ReactNode;\n setSelectedLabel: (label: ReactNode) => void;\n onValueChange?: (value: string) => void;\n}\n\ntype SelectStoreApi = StoreApi<SelectStore>;\n\nexport function createSelectStore(\n onValueChange?: (value: string) => void\n): SelectStoreApi {\n return create<SelectStore>((set) => ({\n open: false,\n setOpen: (open) => set({ open }),\n value: '',\n setValue: (value) => set({ value }),\n selectedLabel: '',\n setSelectedLabel: (label) => set({ selectedLabel: label }),\n onValueChange,\n }));\n}\n\nexport const useSelectStore = (externalStore?: SelectStoreApi) => {\n if (!externalStore) {\n throw new Error(\n 'Component must be used within a Select (store is missing)'\n );\n }\n\n return externalStore;\n};\n\nexport function getLabelAsNode(children: ReactNode): ReactNode {\n if (typeof children === 'string' || typeof children === 'number') {\n return children;\n }\n const flattened = Children.toArray(children);\n\n if (flattened.length === 1) return flattened[0];\n\n return <>{flattened}</>;\n}\n\ninterface SelectProps {\n className?: string;\n children: ReactNode;\n defaultValue?: string;\n value?: string;\n onValueChange?: (value: string) => void;\n size?: 'small' | 'medium' | 'large' | 'extra-large';\n label?: string;\n helperText?: string;\n errorMessage?: string;\n id?: string;\n}\n\nconst injectStore = (\n children: ReactNode,\n store: SelectStoreApi,\n size: string,\n selectId: string\n): ReactNode => {\n return Children.map(children, (child) => {\n if (isValidElement(child)) {\n const typedChild = child as ReactElement<{\n store?: SelectStoreApi;\n children?: ReactNode;\n size?: string;\n selectId?: string;\n }>;\n\n const newProps: Partial<{\n store: SelectStoreApi;\n children: ReactNode;\n size: string;\n selectId: string;\n }> = {\n store,\n };\n\n // Only pass size and selectId to SelectTrigger\n if (typedChild.type === SelectTrigger) {\n newProps.size = size;\n newProps.selectId = selectId;\n }\n\n if (typedChild.props.children) {\n newProps.children = injectStore(\n typedChild.props.children,\n store,\n size,\n selectId\n );\n }\n\n return cloneElement(typedChild, newProps);\n }\n return child;\n });\n};\n\nconst Select = ({\n children,\n defaultValue = '',\n className,\n value: propValue,\n onValueChange,\n size = 'small',\n label,\n helperText,\n errorMessage,\n id,\n}: SelectProps) => {\n const storeRef = useRef<SelectStoreApi | null>(null);\n storeRef.current ??= createSelectStore(onValueChange);\n const store = storeRef.current;\n\n const selectRef = useRef<HTMLDivElement>(null);\n const { open, setOpen, setValue, selectedLabel } = useStore(store, (s) => s);\n\n // Generate unique ID if not provided\n const generatedId = useId();\n const selectId = id ?? `select-${generatedId}`;\n\n const findLabelForValue = (\n children: ReactNode,\n targetValue: string\n ): string | null => {\n let found: string | null = null;\n const search = (nodes: ReactNode) => {\n Children.forEach(nodes, (child) => {\n if (!isValidElement(child)) return;\n const typedChild = child as ReactElement<{\n value?: string;\n children?: ReactNode;\n }>;\n if (\n typedChild.type === SelectItem &&\n typedChild.props.value === targetValue\n ) {\n if (typeof typedChild.props.children === 'string')\n found = typedChild.props.children;\n }\n if (typedChild.props.children && !found)\n search(typedChild.props.children);\n });\n };\n search(children);\n return found;\n };\n\n useEffect(() => {\n if (!selectedLabel && defaultValue) {\n const label = findLabelForValue(children, defaultValue);\n if (label) store.setState({ selectedLabel: label });\n }\n }, [children, defaultValue, selectedLabel]);\n\n useEffect(() => {\n const handleClickOutside = (event: globalThis.MouseEvent) => {\n if (\n selectRef.current &&\n !selectRef.current.contains(event.target as Node)\n ) {\n setOpen(false);\n }\n };\n\n const handleArrowKeys = (event: globalThis.KeyboardEvent) => {\n const selectContent = selectRef.current?.querySelector('[role=\"menu\"]');\n if (selectContent) {\n event.preventDefault();\n const items = Array.from(\n selectContent.querySelectorAll(\n '[role=\"menuitem\"]:not([aria-disabled=\"true\"])'\n )\n ).filter((el): el is HTMLElement => el instanceof HTMLElement);\n\n const focused = document.activeElement as HTMLElement;\n const currentIndex = items.findIndex((item) => item === focused);\n\n let nextIndex = 0;\n if (event.key === 'ArrowDown') {\n nextIndex =\n currentIndex === -1 ? 0 : (currentIndex + 1) % items.length;\n } else {\n nextIndex =\n currentIndex === -1\n ? items.length - 1\n : (currentIndex - 1 + items.length) % items.length;\n }\n items[nextIndex]?.focus();\n }\n };\n\n if (open) {\n document.addEventListener('mousedown', handleClickOutside);\n document.addEventListener('keydown', handleArrowKeys);\n }\n return () => {\n document.removeEventListener('mousedown', handleClickOutside);\n document.removeEventListener('keydown', handleArrowKeys);\n };\n }, [open]);\n\n useEffect(() => {\n if (propValue) {\n setValue(propValue);\n const label = findLabelForValue(children, propValue);\n if (label) store.setState({ selectedLabel: label });\n }\n }, [propValue]);\n\n const sizeClasses = SIZE_CLASSES[size];\n\n return (\n <div className={cn('w-full', className)}>\n {/* Label */}\n {label && (\n <label\n htmlFor={selectId}\n className={cn('block font-bold text-text-900 mb-1.5', sizeClasses)}\n >\n {label}\n </label>\n )}\n\n {/* Select Container */}\n <div className={cn('relative w-full')} ref={selectRef}>\n {injectStore(children, store, size, selectId)}\n </div>\n\n {/* Helper Text or Error Message */}\n {(helperText || errorMessage) && (\n <div className=\"mt-1.5 gap-1.5\">\n {helperText && <p className=\"text-sm text-text-500\">{helperText}</p>}\n {errorMessage && (\n <p className=\"flex gap-1 items-center text-sm text-indicator-error\">\n <WarningCircle size={16} /> {errorMessage}\n </p>\n )}\n </div>\n )}\n </div>\n );\n};\n\nconst SelectValue = ({\n placeholder,\n store: externalStore,\n}: {\n placeholder?: string;\n store?: SelectStoreApi;\n}) => {\n const store = useSelectStore(externalStore);\n\n const selectedLabel = useStore(store, (s) => s.selectedLabel);\n const value = useStore(store, (s) => s.value);\n return (\n <span className=\"text-inherit flex gap-2 items-center\">\n {selectedLabel || placeholder || value}\n </span>\n );\n};\n\ninterface SelectTriggerProps extends ButtonHTMLAttributes<HTMLButtonElement> {\n className?: string;\n invalid?: boolean;\n variant?: 'outlined' | 'underlined' | 'rounded';\n store?: SelectStoreApi;\n size?: 'small' | 'medium' | 'large' | 'extra-large';\n selectId?: string;\n}\n\nconst SelectTrigger = forwardRef<HTMLButtonElement, SelectTriggerProps>(\n (\n {\n className,\n invalid = false,\n variant = 'outlined',\n store: externalStore,\n disabled,\n size = 'medium',\n selectId,\n ...props\n },\n ref\n ) => {\n const store = useSelectStore(externalStore);\n const open = useStore(store, (s) => s.open);\n const toggleOpen = () => store.setState({ open: !open });\n\n const variantClasses = VARIANT_CLASSES[variant];\n const heightClasses = HEIGHT_CLASSES[size];\n const paddingClasses = PADDING_CLASSES[size];\n\n return (\n <button\n ref={ref}\n id={selectId}\n className={cn(\n 'flex w-full items-center justify-between border-border-300',\n heightClasses,\n paddingClasses,\n invalid &&\n `${variant == 'underlined' ? 'border-b-2' : 'border-2'} border-indicator-error text-text-600`,\n disabled\n ? 'cursor-not-allowed text-text-400 pointer-events-none opacity-50'\n : 'cursor-pointer hover:bg-background-50 focus:bg-accent focus:text-accent-foreground hover:bg-accent hover:text-accent-foreground',\n !invalid && !disabled ? 'text-text-700' : '',\n variantClasses,\n className\n )}\n onClick={toggleOpen}\n aria-expanded={open}\n aria-haspopup=\"listbox\"\n aria-controls={open ? 'select-content' : undefined}\n {...props}\n >\n {props.children}\n <CaretDown\n className={cn(\n 'h-[1em] w-[1em] opacity-50 transition-transform',\n open ? 'rotate-180' : ''\n )}\n />\n </button>\n );\n }\n);\nSelectTrigger.displayName = 'SelectTrigger';\n\ninterface SelectContentProps extends HTMLAttributes<HTMLDivElement> {\n className?: string;\n align?: 'start' | 'center' | 'end';\n side?: 'top' | 'right' | 'bottom' | 'left';\n store?: SelectStoreApi;\n}\n\nconst SelectContent = forwardRef<HTMLDivElement, SelectContentProps>(\n (\n {\n children,\n className,\n align = 'start',\n side = 'bottom',\n store: externalStore,\n ...props\n },\n ref\n ) => {\n const store = useSelectStore(externalStore);\n\n const open = useStore(store, (s) => s.open);\n if (!open) return null;\n\n const getPositionClasses = () =>\n `w-full min-w-full absolute ${SIDE_CLASSES[side]} ${ALIGN_CLASSES[align]}`;\n\n return (\n <div\n role=\"menu\"\n ref={ref}\n className={cn(\n 'bg-secondary z-50 min-w-[210px] max-h-[300px] overflow-y-auto overflow-x-hidden rounded-md border p-1 shadow-md border-border-100',\n getPositionClasses(),\n className\n )}\n {...props}\n >\n {children}\n </div>\n );\n }\n);\nSelectContent.displayName = 'SelectContent';\n\ninterface SelectItemProps extends HTMLAttributes<HTMLDivElement> {\n value: string;\n disabled?: boolean;\n store?: SelectStoreApi;\n}\n\nconst SelectItem = forwardRef<HTMLDivElement, SelectItemProps>(\n (\n {\n className,\n children,\n value,\n disabled = false,\n store: externalStore,\n ...props\n },\n ref\n ) => {\n const store = useSelectStore(externalStore);\n const {\n value: selectedValue,\n setValue,\n setOpen,\n setSelectedLabel,\n onValueChange,\n } = useStore(store, (s) => s);\n\n const handleClick = (\n e: MouseEvent<HTMLDivElement> | KeyboardEvent<HTMLDivElement>\n ) => {\n const labelNode = getLabelAsNode(children);\n if (!disabled) {\n // Always set the clicked value, even if it's already selected\n setValue(value);\n setSelectedLabel(labelNode);\n setOpen(false);\n onValueChange?.(value);\n }\n props.onClick?.(e as MouseEvent<HTMLDivElement>);\n };\n\n return (\n <div\n role=\"menuitem\"\n aria-disabled={disabled}\n ref={ref}\n className={`\n bg-secondary focus-visible:bg-background-50\n relative flex select-none items-center gap-2 rounded-sm p-3 outline-none transition-colors [&>svg]:size-4 [&>svg]:shrink-0\n ${className}\n ${\n disabled\n ? 'cursor-not-allowed text-text-400 pointer-events-none opacity-50'\n : 'cursor-pointer hover:bg-background-50 text-text-700 focus:bg-accent focus:text-accent-foreground hover:bg-accent hover:text-accent-foreground'\n }\n ${selectedValue === value && 'bg-background-50'}\n `}\n onClick={handleClick}\n onKeyDown={(e) => {\n if (e.key === 'Enter' || e.key === ' ') handleClick(e);\n }}\n tabIndex={disabled ? -1 : 0}\n {...props}\n >\n <span className=\"absolute right-2 flex h-3.5 w-3.5 items-center justify-center\">\n {selectedValue === value && <Check className=\"\" />}\n </span>\n {children}\n </div>\n );\n }\n);\n\nSelectItem.displayName = 'SelectItem';\n\nexport default Select;\nexport { SelectTrigger, SelectContent, SelectItem, SelectValue };\n","import Text from '../Text/Text';\nimport Button from '../Button/Button';\nimport Select, {\n SelectTrigger,\n SelectValue,\n SelectContent,\n SelectItem,\n} from '../Select/Select';\nimport { Plus } from 'phosphor-react';\n\n/**\n * Statistics data item\n */\ninterface StatItem {\n /** Statistic label */\n label: string;\n /** Statistic value */\n value: string | number;\n /** Color variant */\n variant: 'high' | 'medium' | 'low' | 'total';\n}\n\n/**\n * Props for StatisticsCard component\n */\ninterface StatisticsCardProps {\n /** Title displayed at the top of the card */\n title: string;\n /** Statistics data to display */\n data?: StatItem[];\n /** Show placeholder \"-\" in values when true (for created items without data yet) */\n showPlaceholder?: boolean;\n /** Message shown in empty state */\n emptyStateMessage?: string;\n /** Text for the empty state button */\n emptyStateButtonText?: string;\n /** Callback when empty state button is clicked */\n onEmptyStateButtonClick?: () => void;\n /** Optional dropdown options for filtering */\n dropdownOptions?: Array<{\n label: string;\n value: string;\n }>;\n /** Currently selected dropdown value */\n selectedDropdownValue?: string;\n /** Callback when dropdown value changes */\n onDropdownChange?: (value: string) => void;\n /** Placeholder text for the dropdown select */\n selectPlaceholder?: string;\n /** Accessible label for the dropdown select */\n dropdownAriaLabel?: string;\n /** Additional CSS classes */\n className?: string;\n}\n\n/**\n * Variant styles mapping\n */\nconst VARIANT_STYLES = {\n high: 'bg-success-background',\n medium: 'bg-warning-background',\n low: 'bg-error-background',\n total: 'bg-info-background',\n} as const;\n\n/**\n * Value text colors mapping\n */\nconst VALUE_TEXT_COLORS = {\n high: 'text-success-700',\n medium: 'text-warning-600',\n low: 'text-error-700',\n total: 'text-info-700',\n} as const;\n\n/**\n * Internal StatCard component\n */\ninterface StatCardProps {\n item: StatItem;\n showPlaceholder?: boolean;\n}\n\nconst StatCard = ({ item, showPlaceholder = false }: StatCardProps) => {\n return (\n <div\n className={`rounded-xl py-[17px] px-6 min-h-[105px] flex flex-col justify-center items-start gap-1 ${VARIANT_STYLES[item.variant]}`}\n >\n <Text\n size=\"4xl\"\n weight=\"bold\"\n className={`${VALUE_TEXT_COLORS[item.variant]} leading-[42px] tracking-[0.2px] self-stretch`}\n >\n {showPlaceholder ? '-' : item.value}\n </Text>\n <Text\n size=\"xs\"\n weight=\"bold\"\n className=\"uppercase text-[8px] leading-[9px] text-text-800 whitespace-nowrap\"\n >\n {item.label}\n </Text>\n </div>\n );\n};\n\n/**\n * Get grid column class based on number of items\n */\nconst getGridColumnsClass = (itemCount: number): string => {\n if (itemCount === 4) return 'lg:grid-cols-4';\n if (itemCount === 3) return 'lg:grid-cols-3';\n if (itemCount === 2) return 'lg:grid-cols-2';\n return 'lg:grid-cols-1';\n};\n\n/**\n * StatisticsCard component - displays statistics with empty state support\n *\n * @example\n * ```tsx\n * // With data\n * <StatisticsCard\n * title=\"Estatística das atividades\"\n * data={[\n * { label: 'Acertos', value: '85%', variant: 'high' },\n * { label: 'Em andamento', value: 12, variant: 'medium' },\n * { label: 'Erros', value: '15%', variant: 'low' },\n * { label: 'Concluídas', value: 24, variant: 'total' }\n * ]}\n * dropdownOptions={[\n * { label: '1 ano', value: '1year' },\n * { label: '6 meses', value: '6months' }\n * ]}\n * selectedDropdownValue=\"1year\"\n * onDropdownChange={(value) => console.log(value)}\n * />\n *\n * // Empty state\n * <StatisticsCard\n * title=\"Estatística das atividades\"\n * emptyStateMessage=\"Sem dados por enquanto. Crie uma atividade para que os resultados apareçam aqui.\"\n * emptyStateButtonText=\"Criar atividade\"\n * onEmptyStateButtonClick={() => console.log('Create activity')}\n * />\n * ```\n */\nexport const StatisticsCard = ({\n title,\n data,\n showPlaceholder = false,\n emptyStateMessage,\n emptyStateButtonText,\n onEmptyStateButtonClick,\n dropdownOptions,\n selectedDropdownValue,\n onDropdownChange,\n selectPlaceholder = 'Selecione um período',\n dropdownAriaLabel = 'Filtro de período',\n className = '',\n}: StatisticsCardProps) => {\n const hasData = data && data.length > 0;\n const gridColumnsClass = hasData ? getGridColumnsClass(data.length) : '';\n\n return (\n <div\n className={`bg-background rounded-xl p-4 h-auto lg:h-[185px] flex flex-col gap-2 ${className}`}\n >\n {/* Header with title and optional dropdown */}\n <div className=\"flex flex-row justify-between items-center gap-4\">\n <Text\n as=\"h3\"\n size=\"sm\"\n weight=\"medium\"\n color=\"text-text-600\"\n className=\"flex-1 min-w-0\"\n >\n {title}\n </Text>\n\n {dropdownOptions && dropdownOptions.length > 0 && (\n <div className=\"w-[120px] min-w-[90px] sm:shrink-0\">\n <Select\n value={selectedDropdownValue}\n onValueChange={onDropdownChange}\n size=\"medium\"\n >\n <SelectTrigger\n className=\"border border-border-300 rounded [&>span]:whitespace-nowrap [&>span]:overflow-hidden [&>span]:text-ellipsis\"\n aria-label={dropdownAriaLabel}\n >\n <SelectValue placeholder={selectPlaceholder} />\n </SelectTrigger>\n <SelectContent className=\"min-w-[120px]\">\n {dropdownOptions.map((option) => (\n <SelectItem\n key={option.value}\n value={option.value}\n className=\"whitespace-nowrap\"\n >\n {option.label}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n )}\n </div>\n\n {/* Content: Data Grid or Empty State */}\n {hasData ? (\n <div\n className={`grid grid-cols-1 sm:grid-cols-2 gap-[13px] ${gridColumnsClass}`}\n >\n {data.map((item, index) => (\n <StatCard\n key={`${item.variant}-${item.label}-${index}`}\n item={item}\n showPlaceholder={showPlaceholder}\n />\n ))}\n </div>\n ) : (\n <div className=\"border border-dashed border-border-300 rounded-lg p-6 min-h-[105px] flex flex-col items-center justify-center gap-2\">\n <Text\n size=\"sm\"\n color=\"text-text-600\"\n className=\"text-center max-w-md\"\n >\n {emptyStateMessage}\n </Text>\n\n {onEmptyStateButtonClick && (\n <Button\n variant=\"outline\"\n action=\"primary\"\n size=\"small\"\n onClick={onEmptyStateButtonClick}\n iconLeft={<Plus size={16} weight=\"bold\" />}\n >\n {emptyStateButtonText}\n </Button>\n )}\n </div>\n )}\n </div>\n );\n};\n"],"mappings":"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","names":["jsx","jsx","jsxs","SIZE_CLASSES","children","label","jsx","jsxs"]}
1
+ {"version":3,"sources":["../../src/utils/utils.ts","../../src/components/Text/Text.tsx","../../src/components/Button/Button.tsx","../../src/components/Select/Select.tsx","../../src/components/StatisticsCard/StatisticsCard.tsx"],"sourcesContent":["import { clsx, type ClassValue } from 'clsx';\nimport { twMerge } from 'tailwind-merge';\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs));\n}\n\nexport { syncDropdownState } from './dropdown';\nexport {\n getSelectedIdsFromCategories,\n toggleArrayItem,\n toggleSingleValue,\n} from './activityFilters';\nexport {\n getStatusBadgeConfig,\n formatTimeSpent,\n formatQuestionNumbers,\n formatDateToBrazilian,\n} from './activityDetailsUtils';\n\n/**\n * Retorna a cor hexadecimal com opacidade 0.3 (4d) se não estiver em dark mode.\n * Se estiver em dark mode, retorna a cor original.\n *\n * @param hexColor - Cor hexadecimal (ex: \"#0066b8\" ou \"0066b8\")\n * @param isDark - booleano indicando se está em dark mode\n * @returns string - cor hexadecimal com opacidade se necessário\n */\nexport function getSubjectColorWithOpacity(\n hexColor: string | undefined,\n isDark: boolean\n): string | undefined {\n if (!hexColor) return undefined;\n // Remove o '#' se existir\n let color = hexColor.replace(/^#/, '').toLowerCase();\n\n if (isDark) {\n // Se está em dark mode, sempre remove opacidade se existir\n if (color.length === 8) {\n color = color.slice(0, 6);\n }\n return `#${color}`;\n } else {\n // Se não está em dark mode (light mode)\n let resultColor: string;\n if (color.length === 6) {\n // Adiciona opacidade 0.3 (4D) para cores de 6 dígitos\n resultColor = `#${color}4d`;\n } else if (color.length === 8) {\n // Já tem opacidade, retorna como está\n resultColor = `#${color}`;\n } else {\n // Para outros tamanhos (3, 4, 5 dígitos), retorna como está\n resultColor = `#${color}`;\n }\n return resultColor;\n }\n}\n","import { ComponentPropsWithoutRef, ElementType, ReactNode } from 'react';\nimport { cn } from '../../utils/utils';\n\n/**\n * Base text component props\n */\ntype BaseTextProps = {\n /** Content to be displayed */\n children?: ReactNode;\n /** Text size variant */\n size?:\n | '2xs'\n | 'xs'\n | 'sm'\n | 'md'\n | 'lg'\n | 'xl'\n | '2xl'\n | '3xl'\n | '4xl'\n | '5xl'\n | '6xl';\n /** Font weight variant */\n weight?:\n | 'hairline'\n | 'light'\n | 'normal'\n | 'medium'\n | 'semibold'\n | 'bold'\n | 'extrabold'\n | 'black';\n /** Color variant - white for light backgrounds, black for dark backgrounds */\n color?: string;\n /** Additional CSS classes to apply */\n className?: string;\n};\n\n/**\n * Polymorphic text component props that ensures type safety based on the 'as' prop\n */\ntype TextProps<T extends ElementType = 'p'> = BaseTextProps & {\n /** HTML tag to render */\n as?: T;\n} & Omit<ComponentPropsWithoutRef<T>, keyof BaseTextProps>;\n\n/**\n * Text component for Analytica Ensino platforms\n *\n * A flexible polymorphic text component with multiple sizes, weights, and colors.\n * Automatically adapts to dark and light themes with full type safety.\n *\n * @param children - The content to display\n * @param size - The text size variant (2xs, xs, sm, md, lg, xl, 2xl, 3xl, 4xl, 5xl, 6xl)\n * @param weight - The font weight variant (hairline, light, normal, medium, semibold, bold, extrabold, black)\n * @param color - The color variant - adapts to theme\n * @param as - The HTML tag to render - determines allowed attributes via TypeScript\n * @param className - Additional CSS classes\n * @param props - HTML attributes valid for the chosen tag only\n * @returns A styled text element with type-safe attributes\n *\n * @example\n * ```tsx\n * <Text size=\"lg\" weight=\"bold\" color=\"text-info-800\">\n * This is a large, bold text\n * </Text>\n *\n * <Text as=\"a\" href=\"/link\" target=\"_blank\">\n * Link with type-safe anchor attributes\n * </Text>\n *\n * <Text as=\"button\" onClick={handleClick} disabled>\n * Button with type-safe button attributes\n * </Text>\n * ```\n */\nconst Text = <T extends ElementType = 'p'>({\n children,\n size = 'md',\n weight = 'normal',\n color = 'text-text-950',\n as,\n className = '',\n ...props\n}: TextProps<T>) => {\n let sizeClasses = '';\n let weightClasses = '';\n\n // Text size classes mapping\n const sizeClassMap = {\n '2xs': 'text-2xs',\n xs: 'text-xs',\n sm: 'text-sm',\n md: 'text-md',\n lg: 'text-lg',\n xl: 'text-xl',\n '2xl': 'text-2xl',\n '3xl': 'text-3xl',\n '4xl': 'text-4xl',\n '5xl': 'text-5xl',\n '6xl': 'text-6xl',\n } as const;\n\n sizeClasses = sizeClassMap[size] ?? sizeClassMap.md;\n\n // Font weight classes mapping\n const weightClassMap = {\n hairline: 'font-hairline',\n light: 'font-light',\n normal: 'font-normal',\n medium: 'font-medium',\n semibold: 'font-semibold',\n bold: 'font-bold',\n extrabold: 'font-extrabold',\n black: 'font-black',\n } as const;\n\n weightClasses = weightClassMap[weight] ?? weightClassMap.normal;\n\n const baseClasses = 'font-primary';\n const Component = as ?? ('p' as ElementType);\n\n return (\n <Component\n className={cn(baseClasses, sizeClasses, weightClasses, color, className)}\n {...props}\n >\n {children}\n </Component>\n );\n};\n\nexport default Text;\n","import { ButtonHTMLAttributes, ReactNode } from 'react';\nimport { cn } from '../../utils/utils';\n\n/**\n * Lookup table for variant and action class combinations\n */\nconst VARIANT_ACTION_CLASSES = {\n solid: {\n primary:\n 'bg-primary-950 text-text border border-primary-950 hover:bg-primary-800 hover:border-primary-800 focus-visible:outline-none focus-visible:bg-primary-950 focus-visible:ring-2 focus-visible:ring-offset-0 focus-visible:ring-indicator-info active:bg-primary-700 active:border-primary-700 disabled:bg-primary-500 disabled:border-primary-500 disabled:opacity-40 disabled:cursor-not-allowed',\n positive:\n 'bg-success-500 text-text border border-success-500 hover:bg-success-600 hover:border-success-600 focus-visible:outline-none focus-visible:bg-success-500 focus-visible:ring-2 focus-visible:ring-offset-0 focus-visible:ring-indicator-info active:bg-success-700 active:border-success-700 disabled:bg-success-500 disabled:border-success-500 disabled:opacity-40 disabled:cursor-not-allowed',\n negative:\n 'bg-error-500 text-text border border-error-500 hover:bg-error-600 hover:border-error-600 focus-visible:outline-none focus-visible:bg-error-500 focus-visible:ring-2 focus-visible:ring-offset-0 focus-visible:ring-indicator-info active:bg-error-700 active:border-error-700 disabled:bg-error-500 disabled:border-error-500 disabled:opacity-40 disabled:cursor-not-allowed',\n },\n outline: {\n primary:\n 'bg-transparent text-primary-950 border border-primary-950 hover:bg-background-50 hover:text-primary-400 hover:border-primary-400 focus-visible:border-0 focus-visible:outline-none focus-visible:text-primary-600 focus-visible:ring-2 focus-visible:ring-offset-0 focus-visible:ring-indicator-info active:text-primary-700 active:border-primary-700 disabled:opacity-40 disabled:cursor-not-allowed',\n positive:\n 'bg-transparent text-success-500 border border-success-300 hover:bg-background-50 hover:text-success-400 hover:border-success-400 focus-visible:border-0 focus-visible:outline-none focus-visible:text-success-600 focus-visible:ring-2 focus-visible:ring-offset-0 focus-visible:ring-indicator-info active:text-success-700 active:border-success-700 disabled:opacity-40 disabled:cursor-not-allowed',\n negative:\n 'bg-transparent text-error-500 border border-error-300 hover:bg-background-50 hover:text-error-400 hover:border-error-400 focus-visible:border-0 focus-visible:outline-none focus-visible:text-error-600 focus-visible:ring-2 focus-visible:ring-offset-0 focus-visible:ring-indicator-info active:text-error-700 active:border-error-700 disabled:opacity-40 disabled:cursor-not-allowed',\n },\n link: {\n primary:\n 'bg-transparent text-primary-950 hover:text-primary-400 focus-visible:outline-none focus-visible:text-primary-600 focus-visible:ring-2 focus-visible:ring-offset-0 focus-visible:ring-indicator-info active:text-primary-700 disabled:opacity-40 disabled:cursor-not-allowed',\n positive:\n 'bg-transparent text-success-500 hover:text-success-400 focus-visible:outline-none focus-visible:text-success-600 focus-visible:ring-2 focus-visible:ring-offset-0 focus-visible:ring-indicator-info active:text-success-700 disabled:opacity-40 disabled:cursor-not-allowed',\n negative:\n 'bg-transparent text-error-500 hover:text-error-400 focus-visible:outline-none focus-visible:text-error-600 focus-visible:ring-2 focus-visible:ring-offset-0 focus-visible:ring-indicator-info active:text-error-700 disabled:opacity-40 disabled:cursor-not-allowed',\n },\n} as const;\n\n/**\n * Lookup table for size classes\n */\nconst SIZE_CLASSES = {\n 'extra-small': 'text-xs px-3.5 py-2',\n small: 'text-sm px-4 py-2.5',\n medium: 'text-md px-5 py-2.5',\n large: 'text-lg px-6 py-3',\n 'extra-large': 'text-lg px-7 py-3.5',\n} as const;\n\n/**\n * Button component props interface\n */\ntype ButtonProps = {\n /** Content to be displayed inside the button */\n children: ReactNode;\n /** Ícone à esquerda do texto */\n iconLeft?: ReactNode;\n /** Ícone à direita do texto */\n iconRight?: ReactNode;\n /** Size of the button */\n size?: 'extra-small' | 'small' | 'medium' | 'large' | 'extra-large';\n /** Visual variant of the button */\n variant?: 'solid' | 'outline' | 'link';\n /** Action type of the button */\n action?: 'primary' | 'positive' | 'negative';\n /** Additional CSS classes to apply */\n className?: string;\n} & ButtonHTMLAttributes<HTMLButtonElement>;\n\n/**\n * Button component for Analytica Ensino platforms\n *\n * A flexible button component with multiple variants, sizes and actions.\n *\n * @param children - The content to display inside the button\n * @param size - The size variant (extra-small, small, medium, large, extra-large)\n * @param variant - The visual style variant (solid, outline, link)\n * @param action - The action type (primary, positive, negative)\n * @param className - Additional CSS classes\n * @param props - All other standard button HTML attributes\n * @returns A styled button element\n *\n * @example\n * ```tsx\n * <Button variant=\"solid\" action=\"primary\" size=\"medium\" onClick={() => console.log('clicked')}>\n * Click me\n * </Button>\n * ```\n */\nconst Button = ({\n children,\n iconLeft,\n iconRight,\n size = 'medium',\n variant = 'solid',\n action = 'primary',\n className = '',\n disabled,\n type = 'button',\n ...props\n}: ButtonProps) => {\n // Get classes from lookup tables\n const sizeClasses = SIZE_CLASSES[size];\n const variantClasses = VARIANT_ACTION_CLASSES[variant][action];\n\n const baseClasses =\n 'inline-flex items-center justify-center rounded-full cursor-pointer font-medium';\n\n return (\n <button\n className={cn(baseClasses, variantClasses, sizeClasses, className)}\n disabled={disabled}\n type={type}\n {...props}\n >\n {iconLeft && <span className=\"mr-2 flex items-center\">{iconLeft}</span>}\n {children}\n {iconRight && <span className=\"ml-2 flex items-center\">{iconRight}</span>}\n </button>\n );\n};\n\nexport default Button;\n","import { create, StoreApi, useStore } from 'zustand';\nimport {\n ReactNode,\n useEffect,\n useRef,\n ButtonHTMLAttributes,\n forwardRef,\n HTMLAttributes,\n KeyboardEvent,\n MouseEvent,\n ReactElement,\n isValidElement,\n Children,\n cloneElement,\n useId,\n} from 'react';\nimport { CaretDown, Check, WarningCircle } from 'phosphor-react';\nimport { cn } from '../../utils/utils';\n\nconst VARIANT_CLASSES = {\n outlined: 'border-2 rounded-lg focus:border-primary-950',\n underlined: 'border-b-2 focus:border-primary-950',\n rounded: 'border-2 rounded-full focus:border-primary-950',\n} as const;\n\nconst SIZE_CLASSES = {\n small: 'text-sm',\n medium: 'text-md',\n large: 'text-lg',\n 'extra-large': 'text-lg',\n} as const;\n\nconst HEIGHT_CLASSES = {\n small: 'h-8',\n medium: 'h-9',\n large: 'h-10',\n 'extra-large': 'h-12',\n} as const;\n\nconst PADDING_CLASSES = {\n small: 'px-2 py-1',\n medium: 'px-3 py-2',\n large: 'px-4 py-3',\n 'extra-large': 'px-5 py-4',\n} as const;\n\nconst SIDE_CLASSES = {\n top: 'bottom-full -translate-y-1',\n right: 'top-full translate-y-1',\n bottom: 'top-full translate-y-1',\n left: 'top-full translate-y-1',\n};\nconst ALIGN_CLASSES = {\n start: 'left-0',\n center: 'left-1/2 -translate-x-1/2',\n end: 'right-0',\n};\n\ninterface SelectStore {\n open: boolean;\n setOpen: (open: boolean) => void;\n value: string;\n setValue: (value: string) => void;\n selectedLabel: ReactNode;\n setSelectedLabel: (label: ReactNode) => void;\n onValueChange?: (value: string) => void;\n}\n\ntype SelectStoreApi = StoreApi<SelectStore>;\n\nexport function createSelectStore(\n onValueChange?: (value: string) => void\n): SelectStoreApi {\n return create<SelectStore>((set) => ({\n open: false,\n setOpen: (open) => set({ open }),\n value: '',\n setValue: (value) => set({ value }),\n selectedLabel: '',\n setSelectedLabel: (label) => set({ selectedLabel: label }),\n onValueChange,\n }));\n}\n\nexport const useSelectStore = (externalStore?: SelectStoreApi) => {\n if (!externalStore) {\n throw new Error(\n 'Component must be used within a Select (store is missing)'\n );\n }\n\n return externalStore;\n};\n\nexport function getLabelAsNode(children: ReactNode): ReactNode {\n if (typeof children === 'string' || typeof children === 'number') {\n return children;\n }\n const flattened = Children.toArray(children);\n\n if (flattened.length === 1) return flattened[0];\n\n return <>{flattened}</>;\n}\n\ninterface SelectProps {\n className?: string;\n children: ReactNode;\n defaultValue?: string;\n value?: string;\n onValueChange?: (value: string) => void;\n size?: 'small' | 'medium' | 'large' | 'extra-large';\n label?: string;\n helperText?: string;\n errorMessage?: string;\n id?: string;\n}\n\nconst injectStore = (\n children: ReactNode,\n store: SelectStoreApi,\n size: string,\n selectId: string\n): ReactNode => {\n return Children.map(children, (child) => {\n if (isValidElement(child)) {\n const typedChild = child as ReactElement<{\n store?: SelectStoreApi;\n children?: ReactNode;\n size?: string;\n selectId?: string;\n }>;\n\n const newProps: Partial<{\n store: SelectStoreApi;\n children: ReactNode;\n size: string;\n selectId: string;\n }> = {\n store,\n };\n\n // Only pass size and selectId to SelectTrigger\n if (typedChild.type === SelectTrigger) {\n newProps.size = size;\n newProps.selectId = selectId;\n }\n\n if (typedChild.props.children) {\n newProps.children = injectStore(\n typedChild.props.children,\n store,\n size,\n selectId\n );\n }\n\n return cloneElement(typedChild, newProps);\n }\n return child;\n });\n};\n\nconst Select = ({\n children,\n defaultValue = '',\n className,\n value: propValue,\n onValueChange,\n size = 'small',\n label,\n helperText,\n errorMessage,\n id,\n}: SelectProps) => {\n const storeRef = useRef<SelectStoreApi | null>(null);\n storeRef.current ??= createSelectStore(onValueChange);\n const store = storeRef.current;\n\n const selectRef = useRef<HTMLDivElement>(null);\n const { open, setOpen, setValue, selectedLabel } = useStore(store, (s) => s);\n\n // Generate unique ID if not provided\n const generatedId = useId();\n const selectId = id ?? `select-${generatedId}`;\n\n const findLabelForValue = (\n children: ReactNode,\n targetValue: string\n ): string | null => {\n let found: string | null = null;\n const search = (nodes: ReactNode) => {\n Children.forEach(nodes, (child) => {\n if (!isValidElement(child)) return;\n const typedChild = child as ReactElement<{\n value?: string;\n children?: ReactNode;\n }>;\n if (\n typedChild.type === SelectItem &&\n typedChild.props.value === targetValue\n ) {\n if (typeof typedChild.props.children === 'string')\n found = typedChild.props.children;\n }\n if (typedChild.props.children && !found)\n search(typedChild.props.children);\n });\n };\n search(children);\n return found;\n };\n\n useEffect(() => {\n if (!selectedLabel && defaultValue) {\n const label = findLabelForValue(children, defaultValue);\n if (label) store.setState({ selectedLabel: label });\n }\n }, [children, defaultValue, selectedLabel]);\n\n useEffect(() => {\n const handleClickOutside = (event: globalThis.MouseEvent) => {\n if (\n selectRef.current &&\n !selectRef.current.contains(event.target as Node)\n ) {\n setOpen(false);\n }\n };\n\n const handleArrowKeys = (event: globalThis.KeyboardEvent) => {\n const selectContent = selectRef.current?.querySelector('[role=\"menu\"]');\n if (selectContent) {\n event.preventDefault();\n const items = Array.from(\n selectContent.querySelectorAll(\n '[role=\"menuitem\"]:not([aria-disabled=\"true\"])'\n )\n ).filter((el): el is HTMLElement => el instanceof HTMLElement);\n\n const focused = document.activeElement as HTMLElement;\n const currentIndex = items.findIndex((item) => item === focused);\n\n let nextIndex = 0;\n if (event.key === 'ArrowDown') {\n nextIndex =\n currentIndex === -1 ? 0 : (currentIndex + 1) % items.length;\n } else {\n nextIndex =\n currentIndex === -1\n ? items.length - 1\n : (currentIndex - 1 + items.length) % items.length;\n }\n items[nextIndex]?.focus();\n }\n };\n\n if (open) {\n document.addEventListener('mousedown', handleClickOutside);\n document.addEventListener('keydown', handleArrowKeys);\n }\n return () => {\n document.removeEventListener('mousedown', handleClickOutside);\n document.removeEventListener('keydown', handleArrowKeys);\n };\n }, [open]);\n\n useEffect(() => {\n if (propValue) {\n setValue(propValue);\n const label = findLabelForValue(children, propValue);\n if (label) store.setState({ selectedLabel: label });\n }\n }, [propValue]);\n\n const sizeClasses = SIZE_CLASSES[size];\n\n return (\n <div className={cn('w-full', className)}>\n {/* Label */}\n {label && (\n <label\n htmlFor={selectId}\n className={cn('block font-bold text-text-900 mb-1.5', sizeClasses)}\n >\n {label}\n </label>\n )}\n\n {/* Select Container */}\n <div className={cn('relative w-full')} ref={selectRef}>\n {injectStore(children, store, size, selectId)}\n </div>\n\n {/* Helper Text or Error Message */}\n {(helperText || errorMessage) && (\n <div className=\"mt-1.5 gap-1.5\">\n {helperText && <p className=\"text-sm text-text-500\">{helperText}</p>}\n {errorMessage && (\n <p className=\"flex gap-1 items-center text-sm text-indicator-error\">\n <WarningCircle size={16} /> {errorMessage}\n </p>\n )}\n </div>\n )}\n </div>\n );\n};\n\nconst SelectValue = ({\n placeholder,\n store: externalStore,\n}: {\n placeholder?: string;\n store?: SelectStoreApi;\n}) => {\n const store = useSelectStore(externalStore);\n\n const selectedLabel = useStore(store, (s) => s.selectedLabel);\n const value = useStore(store, (s) => s.value);\n return (\n <span className=\"text-inherit flex gap-2 items-center\">\n {selectedLabel || placeholder || value}\n </span>\n );\n};\n\ninterface SelectTriggerProps extends ButtonHTMLAttributes<HTMLButtonElement> {\n className?: string;\n invalid?: boolean;\n variant?: 'outlined' | 'underlined' | 'rounded';\n store?: SelectStoreApi;\n size?: 'small' | 'medium' | 'large' | 'extra-large';\n selectId?: string;\n}\n\nconst SelectTrigger = forwardRef<HTMLButtonElement, SelectTriggerProps>(\n (\n {\n className,\n invalid = false,\n variant = 'outlined',\n store: externalStore,\n disabled,\n size = 'medium',\n selectId,\n ...props\n },\n ref\n ) => {\n const store = useSelectStore(externalStore);\n const open = useStore(store, (s) => s.open);\n const toggleOpen = () => store.setState({ open: !open });\n\n const variantClasses = VARIANT_CLASSES[variant];\n const heightClasses = HEIGHT_CLASSES[size];\n const paddingClasses = PADDING_CLASSES[size];\n\n return (\n <button\n ref={ref}\n id={selectId}\n className={cn(\n 'flex w-full items-center justify-between border-border-300',\n heightClasses,\n paddingClasses,\n invalid &&\n `${variant == 'underlined' ? 'border-b-2' : 'border-2'} border-indicator-error text-text-600`,\n disabled\n ? 'cursor-not-allowed text-text-400 pointer-events-none opacity-50'\n : 'cursor-pointer hover:bg-background-50 focus:bg-accent focus:text-accent-foreground hover:bg-accent hover:text-accent-foreground',\n !invalid && !disabled ? 'text-text-700' : '',\n variantClasses,\n className\n )}\n onClick={toggleOpen}\n aria-expanded={open}\n aria-haspopup=\"listbox\"\n aria-controls={open ? 'select-content' : undefined}\n {...props}\n >\n {props.children}\n <CaretDown\n className={cn(\n 'h-[1em] w-[1em] opacity-50 transition-transform',\n open ? 'rotate-180' : ''\n )}\n />\n </button>\n );\n }\n);\nSelectTrigger.displayName = 'SelectTrigger';\n\ninterface SelectContentProps extends HTMLAttributes<HTMLDivElement> {\n className?: string;\n align?: 'start' | 'center' | 'end';\n side?: 'top' | 'right' | 'bottom' | 'left';\n store?: SelectStoreApi;\n}\n\nconst SelectContent = forwardRef<HTMLDivElement, SelectContentProps>(\n (\n {\n children,\n className,\n align = 'start',\n side = 'bottom',\n store: externalStore,\n ...props\n },\n ref\n ) => {\n const store = useSelectStore(externalStore);\n\n const open = useStore(store, (s) => s.open);\n if (!open) return null;\n\n const getPositionClasses = () =>\n `w-full min-w-full absolute ${SIDE_CLASSES[side]} ${ALIGN_CLASSES[align]}`;\n\n return (\n <div\n role=\"menu\"\n ref={ref}\n className={cn(\n 'bg-secondary z-50 min-w-[210px] max-h-[300px] overflow-y-auto overflow-x-hidden rounded-md border p-1 shadow-md border-border-100',\n getPositionClasses(),\n className\n )}\n {...props}\n >\n {children}\n </div>\n );\n }\n);\nSelectContent.displayName = 'SelectContent';\n\ninterface SelectItemProps extends HTMLAttributes<HTMLDivElement> {\n value: string;\n disabled?: boolean;\n store?: SelectStoreApi;\n}\n\nconst SelectItem = forwardRef<HTMLDivElement, SelectItemProps>(\n (\n {\n className,\n children,\n value,\n disabled = false,\n store: externalStore,\n ...props\n },\n ref\n ) => {\n const store = useSelectStore(externalStore);\n const {\n value: selectedValue,\n setValue,\n setOpen,\n setSelectedLabel,\n onValueChange,\n } = useStore(store, (s) => s);\n\n const handleClick = (\n e: MouseEvent<HTMLDivElement> | KeyboardEvent<HTMLDivElement>\n ) => {\n const labelNode = getLabelAsNode(children);\n if (!disabled) {\n // Always set the clicked value, even if it's already selected\n setValue(value);\n setSelectedLabel(labelNode);\n setOpen(false);\n onValueChange?.(value);\n }\n props.onClick?.(e as MouseEvent<HTMLDivElement>);\n };\n\n return (\n <div\n role=\"menuitem\"\n aria-disabled={disabled}\n ref={ref}\n className={`\n bg-secondary focus-visible:bg-background-50\n relative flex select-none items-center gap-2 rounded-sm p-3 outline-none transition-colors [&>svg]:size-4 [&>svg]:shrink-0\n ${className}\n ${\n disabled\n ? 'cursor-not-allowed text-text-400 pointer-events-none opacity-50'\n : 'cursor-pointer hover:bg-background-50 text-text-700 focus:bg-accent focus:text-accent-foreground hover:bg-accent hover:text-accent-foreground'\n }\n ${selectedValue === value && 'bg-background-50'}\n `}\n onClick={handleClick}\n onKeyDown={(e) => {\n if (e.key === 'Enter' || e.key === ' ') handleClick(e);\n }}\n tabIndex={disabled ? -1 : 0}\n {...props}\n >\n <span className=\"absolute right-2 flex h-3.5 w-3.5 items-center justify-center\">\n {selectedValue === value && <Check className=\"\" />}\n </span>\n {children}\n </div>\n );\n }\n);\n\nSelectItem.displayName = 'SelectItem';\n\nexport default Select;\nexport { SelectTrigger, SelectContent, SelectItem, SelectValue };\n","import Text from '../Text/Text';\nimport Button from '../Button/Button';\nimport Select, {\n SelectTrigger,\n SelectValue,\n SelectContent,\n SelectItem,\n} from '../Select/Select';\nimport { Plus } from 'phosphor-react';\n\n/**\n * Statistics data item\n */\ninterface StatItem {\n /** Statistic label */\n label: string;\n /** Statistic value */\n value: string | number;\n /** Color variant */\n variant: 'high' | 'medium' | 'low' | 'total';\n}\n\n/**\n * Props for StatisticsCard component\n */\ninterface StatisticsCardProps {\n /** Title displayed at the top of the card */\n title: string;\n /** Statistics data to display */\n data?: StatItem[];\n /** Show placeholder \"-\" in values when true (for created items without data yet) */\n showPlaceholder?: boolean;\n /** Message shown in empty state */\n emptyStateMessage?: string;\n /** Text for the empty state button */\n emptyStateButtonText?: string;\n /** Callback when empty state button is clicked */\n onEmptyStateButtonClick?: () => void;\n /** Optional dropdown options for filtering */\n dropdownOptions?: Array<{\n label: string;\n value: string;\n }>;\n /** Currently selected dropdown value */\n selectedDropdownValue?: string;\n /** Callback when dropdown value changes */\n onDropdownChange?: (value: string) => void;\n /** Placeholder text for the dropdown select */\n selectPlaceholder?: string;\n /** Accessible label for the dropdown select */\n dropdownAriaLabel?: string;\n /** Additional CSS classes */\n className?: string;\n}\n\n/**\n * Variant styles mapping\n */\nconst VARIANT_STYLES = {\n high: 'bg-success-background',\n medium: 'bg-warning-background',\n low: 'bg-error-background',\n total: 'bg-info-background',\n} as const;\n\n/**\n * Value text colors mapping\n */\nconst VALUE_TEXT_COLORS = {\n high: 'text-success-700',\n medium: 'text-warning-600',\n low: 'text-error-700',\n total: 'text-info-700',\n} as const;\n\n/**\n * Internal StatCard component\n */\ninterface StatCardProps {\n item: StatItem;\n showPlaceholder?: boolean;\n}\n\nconst StatCard = ({ item, showPlaceholder = false }: StatCardProps) => {\n return (\n <div\n className={`rounded-xl py-[17px] px-6 min-h-[105px] flex flex-col justify-center items-start gap-1 ${VARIANT_STYLES[item.variant]}`}\n >\n <Text\n size=\"4xl\"\n weight=\"bold\"\n className={`${VALUE_TEXT_COLORS[item.variant]} leading-[42px] tracking-[0.2px] self-stretch`}\n >\n {showPlaceholder ? '-' : item.value}\n </Text>\n <Text\n size=\"xs\"\n weight=\"bold\"\n className=\"uppercase text-[8px] leading-[9px] text-text-800 whitespace-nowrap\"\n >\n {item.label}\n </Text>\n </div>\n );\n};\n\n/**\n * Get grid column class based on number of items\n */\nconst getGridColumnsClass = (itemCount: number): string => {\n if (itemCount === 4) return 'lg:grid-cols-4';\n if (itemCount === 3) return 'lg:grid-cols-3';\n if (itemCount === 2) return 'lg:grid-cols-2';\n return 'lg:grid-cols-1';\n};\n\n/**\n * StatisticsCard component - displays statistics with empty state support\n *\n * @example\n * ```tsx\n * // With data\n * <StatisticsCard\n * title=\"Estatística das atividades\"\n * data={[\n * { label: 'Acertos', value: '85%', variant: 'high' },\n * { label: 'Em andamento', value: 12, variant: 'medium' },\n * { label: 'Erros', value: '15%', variant: 'low' },\n * { label: 'Concluídas', value: 24, variant: 'total' }\n * ]}\n * dropdownOptions={[\n * { label: '1 ano', value: '1year' },\n * { label: '6 meses', value: '6months' }\n * ]}\n * selectedDropdownValue=\"1year\"\n * onDropdownChange={(value) => console.log(value)}\n * />\n *\n * // Empty state\n * <StatisticsCard\n * title=\"Estatística das atividades\"\n * emptyStateMessage=\"Sem dados por enquanto. Crie uma atividade para que os resultados apareçam aqui.\"\n * emptyStateButtonText=\"Criar atividade\"\n * onEmptyStateButtonClick={() => console.log('Create activity')}\n * />\n * ```\n */\nexport const StatisticsCard = ({\n title,\n data,\n showPlaceholder = false,\n emptyStateMessage,\n emptyStateButtonText,\n onEmptyStateButtonClick,\n dropdownOptions,\n selectedDropdownValue,\n onDropdownChange,\n selectPlaceholder = 'Selecione um período',\n dropdownAriaLabel = 'Filtro de período',\n className = '',\n}: StatisticsCardProps) => {\n const hasData = data && data.length > 0;\n const gridColumnsClass = hasData ? getGridColumnsClass(data.length) : '';\n\n return (\n <div\n className={`bg-background rounded-xl p-4 h-auto lg:h-[185px] flex flex-col gap-2 ${className}`}\n >\n {/* Header with title and optional dropdown */}\n <div className=\"flex flex-row justify-between items-center gap-4\">\n <Text\n as=\"h3\"\n size=\"sm\"\n weight=\"medium\"\n color=\"text-text-600\"\n className=\"flex-1 min-w-0\"\n >\n {title}\n </Text>\n\n {dropdownOptions && dropdownOptions.length > 0 && (\n <div className=\"w-[120px] min-w-[90px] sm:shrink-0\">\n <Select\n value={selectedDropdownValue}\n onValueChange={onDropdownChange}\n size=\"medium\"\n >\n <SelectTrigger\n className=\"border border-border-300 rounded [&>span]:whitespace-nowrap [&>span]:overflow-hidden [&>span]:text-ellipsis\"\n aria-label={dropdownAriaLabel}\n >\n <SelectValue placeholder={selectPlaceholder} />\n </SelectTrigger>\n <SelectContent className=\"min-w-[120px]\">\n {dropdownOptions.map((option) => (\n <SelectItem\n key={option.value}\n value={option.value}\n className=\"whitespace-nowrap\"\n >\n {option.label}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n )}\n </div>\n\n {/* Content: Data Grid or Empty State */}\n {hasData ? (\n <div\n className={`grid grid-cols-1 sm:grid-cols-2 gap-[13px] ${gridColumnsClass}`}\n >\n {data.map((item, index) => (\n <StatCard\n key={`${item.variant}-${item.label}-${index}`}\n item={item}\n showPlaceholder={showPlaceholder}\n />\n ))}\n </div>\n ) : (\n <div className=\"border border-dashed border-border-300 rounded-lg p-6 min-h-[105px] flex flex-col items-center justify-center gap-2\">\n <Text\n size=\"sm\"\n color=\"text-text-600\"\n className=\"text-center max-w-md\"\n >\n {emptyStateMessage}\n </Text>\n\n {onEmptyStateButtonClick && (\n <Button\n variant=\"outline\"\n action=\"primary\"\n size=\"small\"\n onClick={onEmptyStateButtonClick}\n iconLeft={<Plus size={16} weight=\"bold\" />}\n >\n {emptyStateButtonText}\n </Button>\n )}\n </div>\n )}\n </div>\n );\n};\n"],"mappings":"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","names":["jsx","jsx","jsxs","SIZE_CLASSES","children","label","jsx","jsxs"]}