analytica-frontend-lib 1.1.68 → 1.1.70

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 (119) hide show
  1. package/dist/Accordation/index.js +3 -3
  2. package/dist/Accordation/index.js.map +1 -1
  3. package/dist/Accordation/index.mjs +3 -3
  4. package/dist/Accordation/index.mjs.map +1 -1
  5. package/dist/Alert/index.js.map +1 -1
  6. package/dist/Alert/index.mjs.map +1 -1
  7. package/dist/AlertDialog/index.js.map +1 -1
  8. package/dist/AlertDialog/index.mjs.map +1 -1
  9. package/dist/Alternative/index.js.map +1 -1
  10. package/dist/Alternative/index.mjs.map +1 -1
  11. package/dist/Badge/index.js.map +1 -1
  12. package/dist/Badge/index.mjs.map +1 -1
  13. package/dist/Button/index.js.map +1 -1
  14. package/dist/Button/index.mjs.map +1 -1
  15. package/dist/Calendar/index.js +1 -1
  16. package/dist/Calendar/index.js.map +1 -1
  17. package/dist/Calendar/index.mjs +1 -1
  18. package/dist/Calendar/index.mjs.map +1 -1
  19. package/dist/Card/index.js +3 -3
  20. package/dist/Card/index.js.map +1 -1
  21. package/dist/Card/index.mjs +3 -3
  22. package/dist/Card/index.mjs.map +1 -1
  23. package/dist/CheckBox/index.js.map +1 -1
  24. package/dist/CheckBox/index.mjs.map +1 -1
  25. package/dist/Chips/index.js.map +1 -1
  26. package/dist/Chips/index.mjs.map +1 -1
  27. package/dist/Divider/index.js.map +1 -1
  28. package/dist/Divider/index.mjs.map +1 -1
  29. package/dist/DropdownMenu/index.js +110 -75
  30. package/dist/DropdownMenu/index.js.map +1 -1
  31. package/dist/DropdownMenu/index.mjs +114 -79
  32. package/dist/DropdownMenu/index.mjs.map +1 -1
  33. package/dist/IconButton/index.js.map +1 -1
  34. package/dist/IconButton/index.mjs.map +1 -1
  35. package/dist/IconRoundedButton/index.js.map +1 -1
  36. package/dist/IconRoundedButton/index.mjs.map +1 -1
  37. package/dist/Menu/index.js.map +1 -1
  38. package/dist/Menu/index.mjs.map +1 -1
  39. package/dist/Modal/index.js.map +1 -1
  40. package/dist/Modal/index.mjs.map +1 -1
  41. package/dist/MultipleChoice/index.js.map +1 -1
  42. package/dist/MultipleChoice/index.mjs.map +1 -1
  43. package/dist/NavButton/index.js.map +1 -1
  44. package/dist/NavButton/index.mjs.map +1 -1
  45. package/dist/NotFound/index.js.map +1 -1
  46. package/dist/NotFound/index.mjs.map +1 -1
  47. package/dist/NotificationCard/index.js +112 -77
  48. package/dist/NotificationCard/index.js.map +1 -1
  49. package/dist/NotificationCard/index.mjs +123 -88
  50. package/dist/NotificationCard/index.mjs.map +1 -1
  51. package/dist/ProgressBar/index.js.map +1 -1
  52. package/dist/ProgressBar/index.mjs.map +1 -1
  53. package/dist/ProgressCircle/index.js.map +1 -1
  54. package/dist/ProgressCircle/index.mjs.map +1 -1
  55. package/dist/Quiz/index.js +4 -4
  56. package/dist/Quiz/index.js.map +1 -1
  57. package/dist/Quiz/index.mjs +4 -4
  58. package/dist/Quiz/index.mjs.map +1 -1
  59. package/dist/Radio/index.js.map +1 -1
  60. package/dist/Radio/index.mjs.map +1 -1
  61. package/dist/Search/index.js +110 -75
  62. package/dist/Search/index.js.map +1 -1
  63. package/dist/Search/index.mjs +119 -84
  64. package/dist/Search/index.mjs.map +1 -1
  65. package/dist/Select/index.js.map +1 -1
  66. package/dist/Select/index.mjs.map +1 -1
  67. package/dist/SelectionButton/index.js.map +1 -1
  68. package/dist/SelectionButton/index.mjs.map +1 -1
  69. package/dist/Skeleton/index.js.map +1 -1
  70. package/dist/Skeleton/index.mjs.map +1 -1
  71. package/dist/Stepper/index.js.map +1 -1
  72. package/dist/Stepper/index.mjs.map +1 -1
  73. package/dist/Table/index.js.map +1 -1
  74. package/dist/Table/index.mjs.map +1 -1
  75. package/dist/Text/index.js.map +1 -1
  76. package/dist/Text/index.mjs.map +1 -1
  77. package/dist/TextArea/index.js.map +1 -1
  78. package/dist/TextArea/index.mjs.map +1 -1
  79. package/dist/ThemeToggle/index.d.mts +3 -1
  80. package/dist/ThemeToggle/index.d.ts +3 -1
  81. package/dist/ThemeToggle/index.js +102 -67
  82. package/dist/ThemeToggle/index.js.map +1 -1
  83. package/dist/ThemeToggle/index.mjs +105 -70
  84. package/dist/ThemeToggle/index.mjs.map +1 -1
  85. package/dist/Toast/Toaster/index.js.map +1 -1
  86. package/dist/Toast/Toaster/index.mjs.map +1 -1
  87. package/dist/Toast/index.js.map +1 -1
  88. package/dist/Toast/index.mjs.map +1 -1
  89. package/dist/VideoPlayer/index.js.map +1 -1
  90. package/dist/VideoPlayer/index.mjs.map +1 -1
  91. package/dist/Whiteboard/index.js +1 -1
  92. package/dist/Whiteboard/index.js.map +1 -1
  93. package/dist/Whiteboard/index.mjs +1 -1
  94. package/dist/Whiteboard/index.mjs.map +1 -1
  95. package/dist/hooks/useTheme/index.d.mts +6 -2
  96. package/dist/hooks/useTheme/index.d.ts +6 -2
  97. package/dist/hooks/useTheme/index.js +102 -67
  98. package/dist/hooks/useTheme/index.js.map +1 -1
  99. package/dist/hooks/useTheme/index.mjs +103 -68
  100. package/dist/hooks/useTheme/index.mjs.map +1 -1
  101. package/dist/index.css +3 -4
  102. package/dist/index.css.map +1 -1
  103. package/dist/index.d.mts +3 -1
  104. package/dist/index.d.ts +3 -1
  105. package/dist/index.js +138 -101
  106. package/dist/index.js.map +1 -1
  107. package/dist/index.mjs +257 -221
  108. package/dist/index.mjs.map +1 -1
  109. package/dist/styles.css +3 -4
  110. package/dist/styles.css.map +1 -1
  111. package/dist/themeStore-P2X64zC-.d.mts +79 -0
  112. package/dist/themeStore-P2X64zC-.d.ts +79 -0
  113. package/dist/utils/index.d.mts +10 -1
  114. package/dist/utils/index.d.ts +10 -1
  115. package/dist/utils/index.js +24 -2
  116. package/dist/utils/index.js.map +1 -1
  117. package/dist/utils/index.mjs +22 -1
  118. package/dist/utils/index.mjs.map +1 -1
  119. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/components/Whiteboard/Whiteboard.tsx","../../src/utils/utils.ts"],"sourcesContent":["import { HTMLAttributes, useCallback, useState } from 'react';\nimport { ArrowsOut } from 'phosphor-react';\nimport { cn } from '../../utils/utils';\n\n// Design constants for critical layout dimensions\nconst IMAGE_WIDTH = 225;\nconst IMAGE_HEIGHT = 90;\n\n/**\n * Whiteboard image item interface\n */\nexport interface WhiteboardImage {\n id: string;\n imageUrl: string;\n title?: string;\n}\n\n/**\n * Whiteboard component props interface\n */\nexport interface WhiteboardProps extends HTMLAttributes<HTMLDivElement> {\n /** Array of images to display in the whiteboard */\n images: WhiteboardImage[];\n /** Whether to show download button on images */\n showDownload?: boolean;\n /** Custom className for the container */\n className?: string;\n /** Callback when download button is clicked */\n onDownload?: (image: WhiteboardImage) => void;\n /** Maximum number of images to display per row on desktop */\n imagesPerRow?: 2 | 3 | 4;\n}\n\n/**\n * Whiteboard component for displaying classroom board images\n * @param props Component properties\n * @returns Whiteboard component\n */\nconst Whiteboard = ({\n images,\n showDownload = true,\n className,\n onDownload,\n imagesPerRow = 2,\n ...rest\n}: WhiteboardProps) => {\n // State to track images that failed to load\n const [imageErrors, setImageErrors] = useState<Set<string>>(new Set());\n\n /**\n * Handle image download\n */\n const handleDownload = useCallback(\n (image: WhiteboardImage) => {\n if (onDownload) {\n onDownload(image);\n } else {\n const link = document.createElement('a');\n link.href = image.imageUrl;\n link.download = image.title || `whiteboard-${image.id}`;\n link.target = '_blank';\n link.rel = 'noopener noreferrer';\n document.body.appendChild(link);\n link.click();\n document.body.removeChild(link);\n }\n },\n [onDownload]\n );\n\n /**\n * Handle image loading error\n */\n const handleImageError = useCallback((imageId: string) => {\n setImageErrors((prev) => new Set(prev).add(imageId));\n }, []);\n\n const gridColsClass =\n images?.length === 1\n ? 'grid-cols-1'\n : {\n 2: 'grid-cols-1 sm:grid-cols-2',\n 3: 'grid-cols-1 sm:grid-cols-2 lg:grid-cols-3',\n 4: 'grid-cols-1 sm:grid-cols-2 lg:grid-cols-4',\n }[imagesPerRow];\n\n // Let CSS handle sizing responsively\n\n if (!images || images.length === 0) {\n return (\n <div\n className={cn(\n 'flex items-center justify-center p-8 bg-white border border-gray-100 rounded-xl',\n className\n )}\n {...rest}\n >\n <p className=\"text-gray-400 text-sm\">Nenhuma imagem disponível</p>\n </div>\n );\n }\n\n return (\n <div\n className={cn(\n 'flex flex-col bg-white border border-gray-100 p-4 gap-2 rounded-xl w-fit mx-auto',\n className\n )}\n {...rest}\n >\n <div className={cn('grid gap-4', gridColsClass)}>\n {images.map((image) => (\n <div\n key={image.id}\n className=\"relative group overflow-hidden bg-gray-100 rounded-lg\"\n style={{\n width: `${IMAGE_WIDTH}px`,\n }}\n >\n <div\n className=\"relative\"\n style={{\n width: `${IMAGE_WIDTH}px`,\n height: `${IMAGE_HEIGHT}px`,\n }}\n >\n {imageErrors.has(image.id) ? (\n <div className=\"absolute inset-0 flex items-center justify-center bg-gray-200\">\n <p className=\"text-gray-500 text-sm text-center px-2\">\n Imagem indisponível\n </p>\n </div>\n ) : (\n <>\n <img\n src={image.imageUrl}\n alt={image.title || `Whiteboard ${image.id}`}\n className=\"absolute inset-0 w-full h-full object-cover\"\n loading=\"lazy\"\n onError={() => handleImageError(image.id)}\n />\n <div className=\"absolute inset-0 bg-gradient-to-t from-black/20 to-transparent\" />\n </>\n )}\n </div>\n {showDownload && (\n <button\n type=\"button\"\n onClick={() => handleDownload(image)}\n className=\"cursor-pointer absolute bottom-3 right-3 flex items-center justify-center bg-black/20 backdrop-blur-sm rounded hover:bg-black/30 transition-colors duration-200 group/button w-6 h-6\"\n aria-label={`Download ${image.title || 'imagem'}`}\n >\n <ArrowsOut\n size={24}\n weight=\"regular\"\n className=\"text-white group-hover/button:scale-110 transition-transform duration-200\"\n />\n </button>\n )}\n </div>\n ))}\n </div>\n </div>\n );\n};\n\nexport default Whiteboard;\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"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../src/components/Whiteboard/Whiteboard.tsx","../../src/utils/utils.ts"],"sourcesContent":["import { HTMLAttributes, useCallback, useState } from 'react';\nimport { ArrowsOut } from 'phosphor-react';\nimport { cn } from '../../utils/utils';\n\n// Design constants for critical layout dimensions\nconst IMAGE_WIDTH = 225;\nconst IMAGE_HEIGHT = 90;\n\n/**\n * Whiteboard image item interface\n */\nexport interface WhiteboardImage {\n id: string;\n imageUrl: string;\n title?: string;\n}\n\n/**\n * Whiteboard component props interface\n */\nexport interface WhiteboardProps extends HTMLAttributes<HTMLDivElement> {\n /** Array of images to display in the whiteboard */\n images: WhiteboardImage[];\n /** Whether to show download button on images */\n showDownload?: boolean;\n /** Custom className for the container */\n className?: string;\n /** Callback when download button is clicked */\n onDownload?: (image: WhiteboardImage) => void;\n /** Maximum number of images to display per row on desktop */\n imagesPerRow?: 2 | 3 | 4;\n}\n\n/**\n * Whiteboard component for displaying classroom board images\n * @param props Component properties\n * @returns Whiteboard component\n */\nconst Whiteboard = ({\n images,\n showDownload = true,\n className,\n onDownload,\n imagesPerRow = 2,\n ...rest\n}: WhiteboardProps) => {\n // State to track images that failed to load\n const [imageErrors, setImageErrors] = useState<Set<string>>(new Set());\n\n /**\n * Handle image download\n */\n const handleDownload = useCallback(\n (image: WhiteboardImage) => {\n if (onDownload) {\n onDownload(image);\n } else {\n const link = document.createElement('a');\n link.href = image.imageUrl;\n link.download = image.title || `whiteboard-${image.id}`;\n link.target = '_blank';\n link.rel = 'noopener noreferrer';\n document.body.appendChild(link);\n link.click();\n document.body.removeChild(link);\n }\n },\n [onDownload]\n );\n\n /**\n * Handle image loading error\n */\n const handleImageError = useCallback((imageId: string) => {\n setImageErrors((prev) => new Set(prev).add(imageId));\n }, []);\n\n const gridColsClass =\n images?.length === 1\n ? 'grid-cols-1'\n : {\n 2: 'grid-cols-1 sm:grid-cols-2',\n 3: 'grid-cols-1 sm:grid-cols-2 lg:grid-cols-3',\n 4: 'grid-cols-1 sm:grid-cols-2 lg:grid-cols-4',\n }[imagesPerRow];\n\n // Let CSS handle sizing responsively\n\n if (!images || images.length === 0) {\n return (\n <div\n className={cn(\n 'flex items-center justify-center p-8 bg-background border border-gray-100 rounded-xl',\n className\n )}\n {...rest}\n >\n <p className=\"text-gray-400 text-sm\">Nenhuma imagem disponível</p>\n </div>\n );\n }\n\n return (\n <div\n className={cn(\n 'flex flex-col bg-white border border-gray-100 p-4 gap-2 rounded-xl w-fit mx-auto',\n className\n )}\n {...rest}\n >\n <div className={cn('grid gap-4', gridColsClass)}>\n {images.map((image) => (\n <div\n key={image.id}\n className=\"relative group overflow-hidden bg-gray-100 rounded-lg\"\n style={{\n width: `${IMAGE_WIDTH}px`,\n }}\n >\n <div\n className=\"relative\"\n style={{\n width: `${IMAGE_WIDTH}px`,\n height: `${IMAGE_HEIGHT}px`,\n }}\n >\n {imageErrors.has(image.id) ? (\n <div className=\"absolute inset-0 flex items-center justify-center bg-gray-200\">\n <p className=\"text-gray-500 text-sm text-center px-2\">\n Imagem indisponível\n </p>\n </div>\n ) : (\n <>\n <img\n src={image.imageUrl}\n alt={image.title || `Whiteboard ${image.id}`}\n className=\"absolute inset-0 w-full h-full object-cover\"\n loading=\"lazy\"\n onError={() => handleImageError(image.id)}\n />\n <div className=\"absolute inset-0 bg-gradient-to-t from-black/20 to-transparent\" />\n </>\n )}\n </div>\n {showDownload && (\n <button\n type=\"button\"\n onClick={() => handleDownload(image)}\n className=\"cursor-pointer absolute bottom-3 right-3 flex items-center justify-center bg-black/20 backdrop-blur-sm rounded hover:bg-black/30 transition-colors duration-200 group/button w-6 h-6\"\n aria-label={`Download ${image.title || 'imagem'}`}\n >\n <ArrowsOut\n size={24}\n weight=\"regular\"\n className=\"text-white group-hover/button:scale-110 transition-transform duration-200\"\n />\n </button>\n )}\n </div>\n ))}\n </div>\n </div>\n );\n};\n\nexport default Whiteboard;\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\n/**\n * Retorna a cor hexadecimal com opacidade 0.7 (b3) 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.7 (b3) para cores de 6 dígitos\n resultColor = `#${color}b3`;\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":[]}
@@ -52,7 +52,7 @@ var Whiteboard = ({
52
52
  "div",
53
53
  {
54
54
  className: cn(
55
- "flex items-center justify-center p-8 bg-white border border-gray-100 rounded-xl",
55
+ "flex items-center justify-center p-8 bg-background border border-gray-100 rounded-xl",
56
56
  className
57
57
  ),
58
58
  ...rest,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/components/Whiteboard/Whiteboard.tsx","../../src/utils/utils.ts"],"sourcesContent":["import { HTMLAttributes, useCallback, useState } from 'react';\nimport { ArrowsOut } from 'phosphor-react';\nimport { cn } from '../../utils/utils';\n\n// Design constants for critical layout dimensions\nconst IMAGE_WIDTH = 225;\nconst IMAGE_HEIGHT = 90;\n\n/**\n * Whiteboard image item interface\n */\nexport interface WhiteboardImage {\n id: string;\n imageUrl: string;\n title?: string;\n}\n\n/**\n * Whiteboard component props interface\n */\nexport interface WhiteboardProps extends HTMLAttributes<HTMLDivElement> {\n /** Array of images to display in the whiteboard */\n images: WhiteboardImage[];\n /** Whether to show download button on images */\n showDownload?: boolean;\n /** Custom className for the container */\n className?: string;\n /** Callback when download button is clicked */\n onDownload?: (image: WhiteboardImage) => void;\n /** Maximum number of images to display per row on desktop */\n imagesPerRow?: 2 | 3 | 4;\n}\n\n/**\n * Whiteboard component for displaying classroom board images\n * @param props Component properties\n * @returns Whiteboard component\n */\nconst Whiteboard = ({\n images,\n showDownload = true,\n className,\n onDownload,\n imagesPerRow = 2,\n ...rest\n}: WhiteboardProps) => {\n // State to track images that failed to load\n const [imageErrors, setImageErrors] = useState<Set<string>>(new Set());\n\n /**\n * Handle image download\n */\n const handleDownload = useCallback(\n (image: WhiteboardImage) => {\n if (onDownload) {\n onDownload(image);\n } else {\n const link = document.createElement('a');\n link.href = image.imageUrl;\n link.download = image.title || `whiteboard-${image.id}`;\n link.target = '_blank';\n link.rel = 'noopener noreferrer';\n document.body.appendChild(link);\n link.click();\n document.body.removeChild(link);\n }\n },\n [onDownload]\n );\n\n /**\n * Handle image loading error\n */\n const handleImageError = useCallback((imageId: string) => {\n setImageErrors((prev) => new Set(prev).add(imageId));\n }, []);\n\n const gridColsClass =\n images?.length === 1\n ? 'grid-cols-1'\n : {\n 2: 'grid-cols-1 sm:grid-cols-2',\n 3: 'grid-cols-1 sm:grid-cols-2 lg:grid-cols-3',\n 4: 'grid-cols-1 sm:grid-cols-2 lg:grid-cols-4',\n }[imagesPerRow];\n\n // Let CSS handle sizing responsively\n\n if (!images || images.length === 0) {\n return (\n <div\n className={cn(\n 'flex items-center justify-center p-8 bg-white border border-gray-100 rounded-xl',\n className\n )}\n {...rest}\n >\n <p className=\"text-gray-400 text-sm\">Nenhuma imagem disponível</p>\n </div>\n );\n }\n\n return (\n <div\n className={cn(\n 'flex flex-col bg-white border border-gray-100 p-4 gap-2 rounded-xl w-fit mx-auto',\n className\n )}\n {...rest}\n >\n <div className={cn('grid gap-4', gridColsClass)}>\n {images.map((image) => (\n <div\n key={image.id}\n className=\"relative group overflow-hidden bg-gray-100 rounded-lg\"\n style={{\n width: `${IMAGE_WIDTH}px`,\n }}\n >\n <div\n className=\"relative\"\n style={{\n width: `${IMAGE_WIDTH}px`,\n height: `${IMAGE_HEIGHT}px`,\n }}\n >\n {imageErrors.has(image.id) ? (\n <div className=\"absolute inset-0 flex items-center justify-center bg-gray-200\">\n <p className=\"text-gray-500 text-sm text-center px-2\">\n Imagem indisponível\n </p>\n </div>\n ) : (\n <>\n <img\n src={image.imageUrl}\n alt={image.title || `Whiteboard ${image.id}`}\n className=\"absolute inset-0 w-full h-full object-cover\"\n loading=\"lazy\"\n onError={() => handleImageError(image.id)}\n />\n <div className=\"absolute inset-0 bg-gradient-to-t from-black/20 to-transparent\" />\n </>\n )}\n </div>\n {showDownload && (\n <button\n type=\"button\"\n onClick={() => handleDownload(image)}\n className=\"cursor-pointer absolute bottom-3 right-3 flex items-center justify-center bg-black/20 backdrop-blur-sm rounded hover:bg-black/30 transition-colors duration-200 group/button w-6 h-6\"\n aria-label={`Download ${image.title || 'imagem'}`}\n >\n <ArrowsOut\n size={24}\n weight=\"regular\"\n className=\"text-white group-hover/button:scale-110 transition-transform duration-200\"\n />\n </button>\n )}\n </div>\n ))}\n </div>\n </div>\n );\n};\n\nexport default Whiteboard;\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"],"mappings":";AAAA,SAAyB,aAAa,gBAAgB;AACtD,SAAS,iBAAiB;;;ACD1B,SAAS,YAA6B;AACtC,SAAS,eAAe;AAEjB,SAAS,MAAM,QAAsB;AAC1C,SAAO,QAAQ,KAAK,MAAM,CAAC;AAC7B;;;AD4FQ,SAoCQ,UApCR,KAoCQ,YApCR;AA5FR,IAAM,cAAc;AACpB,IAAM,eAAe;AAgCrB,IAAM,aAAa,CAAC;AAAA,EAClB;AAAA,EACA,eAAe;AAAA,EACf;AAAA,EACA;AAAA,EACA,eAAe;AAAA,EACf,GAAG;AACL,MAAuB;AAErB,QAAM,CAAC,aAAa,cAAc,IAAI,SAAsB,oBAAI,IAAI,CAAC;AAKrE,QAAM,iBAAiB;AAAA,IACrB,CAAC,UAA2B;AAC1B,UAAI,YAAY;AACd,mBAAW,KAAK;AAAA,MAClB,OAAO;AACL,cAAM,OAAO,SAAS,cAAc,GAAG;AACvC,aAAK,OAAO,MAAM;AAClB,aAAK,WAAW,MAAM,SAAS,cAAc,MAAM,EAAE;AACrD,aAAK,SAAS;AACd,aAAK,MAAM;AACX,iBAAS,KAAK,YAAY,IAAI;AAC9B,aAAK,MAAM;AACX,iBAAS,KAAK,YAAY,IAAI;AAAA,MAChC;AAAA,IACF;AAAA,IACA,CAAC,UAAU;AAAA,EACb;AAKA,QAAM,mBAAmB,YAAY,CAAC,YAAoB;AACxD,mBAAe,CAAC,SAAS,IAAI,IAAI,IAAI,EAAE,IAAI,OAAO,CAAC;AAAA,EACrD,GAAG,CAAC,CAAC;AAEL,QAAM,gBACJ,QAAQ,WAAW,IACf,gBACA;AAAA,IACE,GAAG;AAAA,IACH,GAAG;AAAA,IACH,GAAG;AAAA,EACL,EAAE,YAAY;AAIpB,MAAI,CAAC,UAAU,OAAO,WAAW,GAAG;AAClC,WACE;AAAA,MAAC;AAAA;AAAA,QACC,WAAW;AAAA,UACT;AAAA,UACA;AAAA,QACF;AAAA,QACC,GAAG;AAAA,QAEJ,8BAAC,OAAE,WAAU,yBAAwB,0CAAyB;AAAA;AAAA,IAChE;AAAA,EAEJ;AAEA,SACE;AAAA,IAAC;AAAA;AAAA,MACC,WAAW;AAAA,QACT;AAAA,QACA;AAAA,MACF;AAAA,MACC,GAAG;AAAA,MAEJ,8BAAC,SAAI,WAAW,GAAG,cAAc,aAAa,GAC3C,iBAAO,IAAI,CAAC,UACX;AAAA,QAAC;AAAA;AAAA,UAEC,WAAU;AAAA,UACV,OAAO;AAAA,YACL,OAAO,GAAG,WAAW;AAAA,UACvB;AAAA,UAEA;AAAA;AAAA,cAAC;AAAA;AAAA,gBACC,WAAU;AAAA,gBACV,OAAO;AAAA,kBACL,OAAO,GAAG,WAAW;AAAA,kBACrB,QAAQ,GAAG,YAAY;AAAA,gBACzB;AAAA,gBAEC,sBAAY,IAAI,MAAM,EAAE,IACvB,oBAAC,SAAI,WAAU,iEACb,8BAAC,OAAE,WAAU,0CAAyC,oCAEtD,GACF,IAEA,iCACE;AAAA;AAAA,oBAAC;AAAA;AAAA,sBACC,KAAK,MAAM;AAAA,sBACX,KAAK,MAAM,SAAS,cAAc,MAAM,EAAE;AAAA,sBAC1C,WAAU;AAAA,sBACV,SAAQ;AAAA,sBACR,SAAS,MAAM,iBAAiB,MAAM,EAAE;AAAA;AAAA,kBAC1C;AAAA,kBACA,oBAAC,SAAI,WAAU,kEAAiE;AAAA,mBAClF;AAAA;AAAA,YAEJ;AAAA,YACC,gBACC;AAAA,cAAC;AAAA;AAAA,gBACC,MAAK;AAAA,gBACL,SAAS,MAAM,eAAe,KAAK;AAAA,gBACnC,WAAU;AAAA,gBACV,cAAY,YAAY,MAAM,SAAS,QAAQ;AAAA,gBAE/C;AAAA,kBAAC;AAAA;AAAA,oBACC,MAAM;AAAA,oBACN,QAAO;AAAA,oBACP,WAAU;AAAA;AAAA,gBACZ;AAAA;AAAA,YACF;AAAA;AAAA;AAAA,QA5CG,MAAM;AAAA,MA8Cb,CACD,GACH;AAAA;AAAA,EACF;AAEJ;AAEA,IAAO,qBAAQ;","names":[]}
1
+ {"version":3,"sources":["../../src/components/Whiteboard/Whiteboard.tsx","../../src/utils/utils.ts"],"sourcesContent":["import { HTMLAttributes, useCallback, useState } from 'react';\nimport { ArrowsOut } from 'phosphor-react';\nimport { cn } from '../../utils/utils';\n\n// Design constants for critical layout dimensions\nconst IMAGE_WIDTH = 225;\nconst IMAGE_HEIGHT = 90;\n\n/**\n * Whiteboard image item interface\n */\nexport interface WhiteboardImage {\n id: string;\n imageUrl: string;\n title?: string;\n}\n\n/**\n * Whiteboard component props interface\n */\nexport interface WhiteboardProps extends HTMLAttributes<HTMLDivElement> {\n /** Array of images to display in the whiteboard */\n images: WhiteboardImage[];\n /** Whether to show download button on images */\n showDownload?: boolean;\n /** Custom className for the container */\n className?: string;\n /** Callback when download button is clicked */\n onDownload?: (image: WhiteboardImage) => void;\n /** Maximum number of images to display per row on desktop */\n imagesPerRow?: 2 | 3 | 4;\n}\n\n/**\n * Whiteboard component for displaying classroom board images\n * @param props Component properties\n * @returns Whiteboard component\n */\nconst Whiteboard = ({\n images,\n showDownload = true,\n className,\n onDownload,\n imagesPerRow = 2,\n ...rest\n}: WhiteboardProps) => {\n // State to track images that failed to load\n const [imageErrors, setImageErrors] = useState<Set<string>>(new Set());\n\n /**\n * Handle image download\n */\n const handleDownload = useCallback(\n (image: WhiteboardImage) => {\n if (onDownload) {\n onDownload(image);\n } else {\n const link = document.createElement('a');\n link.href = image.imageUrl;\n link.download = image.title || `whiteboard-${image.id}`;\n link.target = '_blank';\n link.rel = 'noopener noreferrer';\n document.body.appendChild(link);\n link.click();\n document.body.removeChild(link);\n }\n },\n [onDownload]\n );\n\n /**\n * Handle image loading error\n */\n const handleImageError = useCallback((imageId: string) => {\n setImageErrors((prev) => new Set(prev).add(imageId));\n }, []);\n\n const gridColsClass =\n images?.length === 1\n ? 'grid-cols-1'\n : {\n 2: 'grid-cols-1 sm:grid-cols-2',\n 3: 'grid-cols-1 sm:grid-cols-2 lg:grid-cols-3',\n 4: 'grid-cols-1 sm:grid-cols-2 lg:grid-cols-4',\n }[imagesPerRow];\n\n // Let CSS handle sizing responsively\n\n if (!images || images.length === 0) {\n return (\n <div\n className={cn(\n 'flex items-center justify-center p-8 bg-background border border-gray-100 rounded-xl',\n className\n )}\n {...rest}\n >\n <p className=\"text-gray-400 text-sm\">Nenhuma imagem disponível</p>\n </div>\n );\n }\n\n return (\n <div\n className={cn(\n 'flex flex-col bg-white border border-gray-100 p-4 gap-2 rounded-xl w-fit mx-auto',\n className\n )}\n {...rest}\n >\n <div className={cn('grid gap-4', gridColsClass)}>\n {images.map((image) => (\n <div\n key={image.id}\n className=\"relative group overflow-hidden bg-gray-100 rounded-lg\"\n style={{\n width: `${IMAGE_WIDTH}px`,\n }}\n >\n <div\n className=\"relative\"\n style={{\n width: `${IMAGE_WIDTH}px`,\n height: `${IMAGE_HEIGHT}px`,\n }}\n >\n {imageErrors.has(image.id) ? (\n <div className=\"absolute inset-0 flex items-center justify-center bg-gray-200\">\n <p className=\"text-gray-500 text-sm text-center px-2\">\n Imagem indisponível\n </p>\n </div>\n ) : (\n <>\n <img\n src={image.imageUrl}\n alt={image.title || `Whiteboard ${image.id}`}\n className=\"absolute inset-0 w-full h-full object-cover\"\n loading=\"lazy\"\n onError={() => handleImageError(image.id)}\n />\n <div className=\"absolute inset-0 bg-gradient-to-t from-black/20 to-transparent\" />\n </>\n )}\n </div>\n {showDownload && (\n <button\n type=\"button\"\n onClick={() => handleDownload(image)}\n className=\"cursor-pointer absolute bottom-3 right-3 flex items-center justify-center bg-black/20 backdrop-blur-sm rounded hover:bg-black/30 transition-colors duration-200 group/button w-6 h-6\"\n aria-label={`Download ${image.title || 'imagem'}`}\n >\n <ArrowsOut\n size={24}\n weight=\"regular\"\n className=\"text-white group-hover/button:scale-110 transition-transform duration-200\"\n />\n </button>\n )}\n </div>\n ))}\n </div>\n </div>\n );\n};\n\nexport default Whiteboard;\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\n/**\n * Retorna a cor hexadecimal com opacidade 0.7 (b3) 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.7 (b3) para cores de 6 dígitos\n resultColor = `#${color}b3`;\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,7 +1,11 @@
1
- type ThemeMode = 'light' | 'dark' | 'system';
1
+ import { T as ThemeMode } from '../../themeStore-P2X64zC-.mjs';
2
+ import 'zustand/middleware';
3
+ import 'zustand';
4
+
2
5
  /**
3
6
  * Hook para gerenciar temas com suporte a alternância manual e detecção automática do sistema
4
7
  * Este hook permite alternar entre temas light, dark e automático baseado nas preferências do sistema
8
+ * Utiliza Zustand para persistir o estado entre múltiplos arquivos e sessões
5
9
  */
6
10
  declare const useTheme: () => {
7
11
  themeMode: ThemeMode;
@@ -10,4 +14,4 @@ declare const useTheme: () => {
10
14
  setTheme: (mode: ThemeMode) => void;
11
15
  };
12
16
 
13
- export { type ThemeMode, useTheme };
17
+ export { ThemeMode, useTheme };
@@ -1,7 +1,11 @@
1
- type ThemeMode = 'light' | 'dark' | 'system';
1
+ import { T as ThemeMode } from '../../themeStore-P2X64zC-.js';
2
+ import 'zustand/middleware';
3
+ import 'zustand';
4
+
2
5
  /**
3
6
  * Hook para gerenciar temas com suporte a alternância manual e detecção automática do sistema
4
7
  * Este hook permite alternar entre temas light, dark e automático baseado nas preferências do sistema
8
+ * Utiliza Zustand para persistir o estado entre múltiplos arquivos e sessões
5
9
  */
6
10
  declare const useTheme: () => {
7
11
  themeMode: ThemeMode;
@@ -10,4 +14,4 @@ declare const useTheme: () => {
10
14
  setTheme: (mode: ThemeMode) => void;
11
15
  };
12
16
 
13
- export { type ThemeMode, useTheme };
17
+ export { ThemeMode, useTheme };
@@ -24,82 +24,117 @@ __export(useTheme_exports, {
24
24
  });
25
25
  module.exports = __toCommonJS(useTheme_exports);
26
26
  var import_react = require("react");
27
- var useTheme = () => {
28
- const [themeMode, setThemeMode] = (0, import_react.useState)("system");
29
- const [isDark, setIsDark] = (0, import_react.useState)(false);
30
- const themeModeRef = (0, import_react.useRef)("system");
31
- const applyTheme = (0, import_react.useCallback)((mode) => {
32
- const htmlElement = document.documentElement;
33
- const originalTheme = htmlElement.getAttribute("data-original-theme");
34
- if (mode === "dark") {
27
+
28
+ // src/store/themeStore.ts
29
+ var import_zustand = require("zustand");
30
+ var import_middleware = require("zustand/middleware");
31
+ var applyThemeToDOM = (mode) => {
32
+ const htmlElement = document.documentElement;
33
+ const originalTheme = htmlElement.getAttribute("data-original-theme");
34
+ if (mode === "dark") {
35
+ htmlElement.setAttribute("data-theme", "dark");
36
+ return true;
37
+ } else if (mode === "light") {
38
+ if (originalTheme) {
39
+ htmlElement.setAttribute("data-theme", originalTheme);
40
+ }
41
+ return false;
42
+ } else if (mode === "system") {
43
+ const isSystemDark = window.matchMedia(
44
+ "(prefers-color-scheme: dark)"
45
+ ).matches;
46
+ if (isSystemDark) {
35
47
  htmlElement.setAttribute("data-theme", "dark");
36
- setIsDark(true);
37
- } else if (mode === "light") {
38
- if (originalTheme) {
39
- htmlElement.setAttribute("data-theme", originalTheme);
40
- }
41
- setIsDark(false);
42
- } else if (mode === "system") {
43
- const isSystemDark = window.matchMedia(
44
- "(prefers-color-scheme: dark)"
45
- ).matches;
46
- if (isSystemDark) {
47
- htmlElement.setAttribute("data-theme", "dark");
48
- setIsDark(true);
49
- } else if (originalTheme) {
50
- htmlElement.setAttribute("data-theme", originalTheme);
51
- setIsDark(false);
52
- }
48
+ return true;
49
+ } else if (originalTheme) {
50
+ htmlElement.setAttribute("data-theme", originalTheme);
51
+ return false;
53
52
  }
54
- }, []);
55
- const toggleTheme = (0, import_react.useCallback)(() => {
56
- let newMode;
57
- if (themeMode === "light") {
58
- newMode = "dark";
59
- } else if (themeMode === "dark") {
60
- newMode = "light";
61
- } else {
62
- newMode = "dark";
53
+ }
54
+ return false;
55
+ };
56
+ var saveOriginalTheme = () => {
57
+ const htmlElement = document.documentElement;
58
+ const currentTheme = htmlElement.getAttribute("data-theme");
59
+ if (currentTheme && !htmlElement.getAttribute("data-original-theme")) {
60
+ htmlElement.setAttribute("data-original-theme", currentTheme);
61
+ }
62
+ };
63
+ var useThemeStore = (0, import_zustand.create)()(
64
+ (0, import_middleware.devtools)(
65
+ (0, import_middleware.persist)(
66
+ (set, get) => ({
67
+ // Initial state
68
+ themeMode: "system",
69
+ isDark: false,
70
+ // Actions
71
+ applyTheme: (mode) => {
72
+ const isDark = applyThemeToDOM(mode);
73
+ set({ isDark });
74
+ },
75
+ toggleTheme: () => {
76
+ const { themeMode, applyTheme } = get();
77
+ let newMode;
78
+ if (themeMode === "light") {
79
+ newMode = "dark";
80
+ } else if (themeMode === "dark") {
81
+ newMode = "light";
82
+ } else {
83
+ newMode = "dark";
84
+ }
85
+ set({ themeMode: newMode });
86
+ applyTheme(newMode);
87
+ },
88
+ setTheme: (mode) => {
89
+ const { applyTheme } = get();
90
+ set({ themeMode: mode });
91
+ applyTheme(mode);
92
+ },
93
+ initializeTheme: () => {
94
+ const { themeMode, applyTheme } = get();
95
+ saveOriginalTheme();
96
+ applyTheme(themeMode);
97
+ },
98
+ handleSystemThemeChange: () => {
99
+ const { themeMode, applyTheme } = get();
100
+ if (themeMode === "system") {
101
+ applyTheme("system");
102
+ }
103
+ }
104
+ }),
105
+ {
106
+ name: "theme-store",
107
+ // Nome da chave no localStorage
108
+ partialize: (state) => ({
109
+ themeMode: state.themeMode
110
+ })
111
+ // Só persiste o themeMode, não o isDark
112
+ }
113
+ ),
114
+ {
115
+ name: "theme-store"
63
116
  }
64
- setThemeMode(newMode);
65
- themeModeRef.current = newMode;
66
- applyTheme(newMode);
67
- localStorage.setItem("theme-mode", newMode);
68
- }, [themeMode, applyTheme]);
69
- const setTheme = (0, import_react.useCallback)(
70
- (mode) => {
71
- setThemeMode(mode);
72
- themeModeRef.current = mode;
73
- applyTheme(mode);
74
- localStorage.setItem("theme-mode", mode);
75
- },
76
- [applyTheme]
77
- );
117
+ )
118
+ );
119
+
120
+ // src/hooks/useTheme.ts
121
+ var useTheme = () => {
122
+ const {
123
+ themeMode,
124
+ isDark,
125
+ toggleTheme,
126
+ setTheme,
127
+ initializeTheme,
128
+ handleSystemThemeChange
129
+ } = useThemeStore();
78
130
  (0, import_react.useEffect)(() => {
79
- const htmlElement = document.documentElement;
80
- const currentTheme = htmlElement.getAttribute("data-theme");
81
- if (currentTheme && !htmlElement.getAttribute("data-original-theme")) {
82
- htmlElement.setAttribute("data-original-theme", currentTheme);
83
- }
84
- const savedThemeMode = localStorage.getItem("theme-mode");
85
- const initialMode = savedThemeMode || "system";
86
- if (!savedThemeMode) {
87
- localStorage.setItem("theme-mode", "system");
88
- }
89
- setThemeMode(initialMode);
90
- themeModeRef.current = initialMode;
91
- applyTheme(initialMode);
131
+ initializeTheme();
92
132
  const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)");
93
- const handleSystemThemeChange = () => {
94
- if (themeModeRef.current === "system") {
95
- applyTheme("system");
96
- }
97
- };
98
133
  mediaQuery.addEventListener("change", handleSystemThemeChange);
99
134
  return () => {
100
135
  mediaQuery.removeEventListener("change", handleSystemThemeChange);
101
136
  };
102
- }, [applyTheme]);
137
+ }, [initializeTheme, handleSystemThemeChange]);
103
138
  return {
104
139
  themeMode,
105
140
  isDark,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/hooks/useTheme.ts"],"sourcesContent":["import { useEffect, useState, useCallback, useRef } from 'react';\n\nexport type ThemeMode = 'light' | 'dark' | 'system';\n\n/**\n * Hook para gerenciar temas com suporte a alternância manual e detecção automática do sistema\n * Este hook permite alternar entre temas light, dark e automático baseado nas preferências do sistema\n */\nexport const useTheme = () => {\n const [themeMode, setThemeMode] = useState<ThemeMode>('system');\n const [isDark, setIsDark] = useState(false);\n\n // Ref para manter o estado atual do tema de forma síncrona\n const themeModeRef = useRef<ThemeMode>('system');\n\n // Função para aplicar o tema baseado no modo selecionado\n const applyTheme = useCallback((mode: ThemeMode) => {\n const htmlElement = document.documentElement;\n const originalTheme = htmlElement.getAttribute('data-original-theme');\n\n if (mode === 'dark') {\n htmlElement.setAttribute('data-theme', 'dark');\n setIsDark(true);\n } else if (mode === 'light') {\n if (originalTheme) {\n htmlElement.setAttribute('data-theme', originalTheme);\n }\n setIsDark(false);\n } else if (mode === 'system') {\n const isSystemDark = window.matchMedia(\n '(prefers-color-scheme: dark)'\n ).matches;\n if (isSystemDark) {\n htmlElement.setAttribute('data-theme', 'dark');\n setIsDark(true);\n } else if (originalTheme) {\n htmlElement.setAttribute('data-theme', originalTheme);\n setIsDark(false);\n }\n }\n }, []);\n\n // Função para alternar entre os temas\n const toggleTheme = useCallback(() => {\n let newMode: ThemeMode;\n if (themeMode === 'light') {\n newMode = 'dark';\n } else if (themeMode === 'dark') {\n newMode = 'light';\n } else {\n // Se estiver em 'system', vai para 'dark'\n newMode = 'dark';\n }\n setThemeMode(newMode);\n themeModeRef.current = newMode;\n applyTheme(newMode);\n localStorage.setItem('theme-mode', newMode);\n }, [themeMode, applyTheme]);\n\n // Função para definir um tema específico\n const setTheme = useCallback(\n (mode: ThemeMode) => {\n setThemeMode(mode);\n themeModeRef.current = mode;\n applyTheme(mode);\n localStorage.setItem('theme-mode', mode);\n },\n [applyTheme]\n );\n\n useEffect(() => {\n const htmlElement = document.documentElement;\n\n // Salva o theme original do white label na primeira execução\n const currentTheme = htmlElement.getAttribute('data-theme');\n if (currentTheme && !htmlElement.getAttribute('data-original-theme')) {\n htmlElement.setAttribute('data-original-theme', currentTheme);\n }\n\n // Carrega o tema salvo no localStorage ou usa 'system' como padrão\n const savedThemeMode = localStorage.getItem('theme-mode') as ThemeMode;\n const initialMode = savedThemeMode || 'system';\n\n // Se não tema salvo, persiste 'system' como padrão\n if (!savedThemeMode) {\n localStorage.setItem('theme-mode', 'system');\n }\n\n setThemeMode(initialMode);\n themeModeRef.current = initialMode;\n applyTheme(initialMode);\n\n // Listener para mudanças nas preferências do sistema (apenas quando mode é 'system')\n const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)');\n const handleSystemThemeChange = () => {\n // Usa o ref para ter acesso ao estado atual de forma síncrona\n if (themeModeRef.current === 'system') {\n applyTheme('system');\n }\n };\n\n mediaQuery.addEventListener('change', handleSystemThemeChange);\n\n return () => {\n mediaQuery.removeEventListener('change', handleSystemThemeChange);\n };\n }, [applyTheme]);\n\n return {\n themeMode,\n isDark,\n toggleTheme,\n setTheme,\n };\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,mBAAyD;AAQlD,IAAM,WAAW,MAAM;AAC5B,QAAM,CAAC,WAAW,YAAY,QAAI,uBAAoB,QAAQ;AAC9D,QAAM,CAAC,QAAQ,SAAS,QAAI,uBAAS,KAAK;AAG1C,QAAM,mBAAe,qBAAkB,QAAQ;AAG/C,QAAM,iBAAa,0BAAY,CAAC,SAAoB;AAClD,UAAM,cAAc,SAAS;AAC7B,UAAM,gBAAgB,YAAY,aAAa,qBAAqB;AAEpE,QAAI,SAAS,QAAQ;AACnB,kBAAY,aAAa,cAAc,MAAM;AAC7C,gBAAU,IAAI;AAAA,IAChB,WAAW,SAAS,SAAS;AAC3B,UAAI,eAAe;AACjB,oBAAY,aAAa,cAAc,aAAa;AAAA,MACtD;AACA,gBAAU,KAAK;AAAA,IACjB,WAAW,SAAS,UAAU;AAC5B,YAAM,eAAe,OAAO;AAAA,QAC1B;AAAA,MACF,EAAE;AACF,UAAI,cAAc;AAChB,oBAAY,aAAa,cAAc,MAAM;AAC7C,kBAAU,IAAI;AAAA,MAChB,WAAW,eAAe;AACxB,oBAAY,aAAa,cAAc,aAAa;AACpD,kBAAU,KAAK;AAAA,MACjB;AAAA,IACF;AAAA,EACF,GAAG,CAAC,CAAC;AAGL,QAAM,kBAAc,0BAAY,MAAM;AACpC,QAAI;AACJ,QAAI,cAAc,SAAS;AACzB,gBAAU;AAAA,IACZ,WAAW,cAAc,QAAQ;AAC/B,gBAAU;AAAA,IACZ,OAAO;AAEL,gBAAU;AAAA,IACZ;AACA,iBAAa,OAAO;AACpB,iBAAa,UAAU;AACvB,eAAW,OAAO;AAClB,iBAAa,QAAQ,cAAc,OAAO;AAAA,EAC5C,GAAG,CAAC,WAAW,UAAU,CAAC;AAG1B,QAAM,eAAW;AAAA,IACf,CAAC,SAAoB;AACnB,mBAAa,IAAI;AACjB,mBAAa,UAAU;AACvB,iBAAW,IAAI;AACf,mBAAa,QAAQ,cAAc,IAAI;AAAA,IACzC;AAAA,IACA,CAAC,UAAU;AAAA,EACb;AAEA,8BAAU,MAAM;AACd,UAAM,cAAc,SAAS;AAG7B,UAAM,eAAe,YAAY,aAAa,YAAY;AAC1D,QAAI,gBAAgB,CAAC,YAAY,aAAa,qBAAqB,GAAG;AACpE,kBAAY,aAAa,uBAAuB,YAAY;AAAA,IAC9D;AAGA,UAAM,iBAAiB,aAAa,QAAQ,YAAY;AACxD,UAAM,cAAc,kBAAkB;AAGtC,QAAI,CAAC,gBAAgB;AACnB,mBAAa,QAAQ,cAAc,QAAQ;AAAA,IAC7C;AAEA,iBAAa,WAAW;AACxB,iBAAa,UAAU;AACvB,eAAW,WAAW;AAGtB,UAAM,aAAa,OAAO,WAAW,8BAA8B;AACnE,UAAM,0BAA0B,MAAM;AAEpC,UAAI,aAAa,YAAY,UAAU;AACrC,mBAAW,QAAQ;AAAA,MACrB;AAAA,IACF;AAEA,eAAW,iBAAiB,UAAU,uBAAuB;AAE7D,WAAO,MAAM;AACX,iBAAW,oBAAoB,UAAU,uBAAuB;AAAA,IAClE;AAAA,EACF,GAAG,CAAC,UAAU,CAAC;AAEf,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;","names":[]}
1
+ {"version":3,"sources":["../../../src/hooks/useTheme.ts","../../../src/store/themeStore.ts"],"sourcesContent":["import { useEffect } from 'react';\nimport { useThemeStore, ThemeMode } from '../store/themeStore';\n\nexport type { ThemeMode };\n\n/**\n * Hook para gerenciar temas com suporte a alternância manual e detecção automática do sistema\n * Este hook permite alternar entre temas light, dark e automático baseado nas preferências do sistema\n * Utiliza Zustand para persistir o estado entre múltiplos arquivos e sessões\n */\nexport const useTheme = () => {\n const {\n themeMode,\n isDark,\n toggleTheme,\n setTheme,\n initializeTheme,\n handleSystemThemeChange,\n } = useThemeStore();\n\n useEffect(() => {\n // Initialize theme on first render\n initializeTheme();\n\n // Listener para mudanças nas preferências do sistema (apenas quando mode é 'system')\n const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)');\n\n mediaQuery.addEventListener('change', handleSystemThemeChange);\n\n return () => {\n mediaQuery.removeEventListener('change', handleSystemThemeChange);\n };\n }, [initializeTheme, handleSystemThemeChange]);\n\n return {\n themeMode,\n isDark,\n toggleTheme,\n setTheme,\n };\n};\n","import { create } from 'zustand';\nimport { devtools, persist } from 'zustand/middleware';\n\nexport type ThemeMode = 'light' | 'dark' | 'system';\n\n/**\n * Theme store state interface\n */\nexport interface ThemeState {\n /**\n * Current theme mode\n */\n themeMode: ThemeMode;\n /**\n * Whether the current theme is dark\n */\n isDark: boolean;\n}\n\n/**\n * Theme store actions interface\n */\nexport interface ThemeActions {\n /**\n * Apply theme based on the mode selected\n */\n applyTheme: (mode: ThemeMode) => void;\n /**\n * Toggle between themes\n */\n toggleTheme: () => void;\n /**\n * Set a specific theme mode\n */\n setTheme: (mode: ThemeMode) => void;\n /**\n * Initialize theme on app start\n */\n initializeTheme: () => void;\n /**\n * Handle system theme change\n */\n handleSystemThemeChange: () => void;\n}\n\nexport type ThemeStore = ThemeState & ThemeActions;\n\n/**\n * Apply theme to DOM based on mode\n */\nconst applyThemeToDOM = (mode: ThemeMode): boolean => {\n const htmlElement = document.documentElement;\n const originalTheme = htmlElement.getAttribute('data-original-theme');\n\n if (mode === 'dark') {\n htmlElement.setAttribute('data-theme', 'dark');\n return true;\n } else if (mode === 'light') {\n if (originalTheme) {\n htmlElement.setAttribute('data-theme', originalTheme);\n }\n return false;\n } else if (mode === 'system') {\n const isSystemDark = window.matchMedia(\n '(prefers-color-scheme: dark)'\n ).matches;\n if (isSystemDark) {\n htmlElement.setAttribute('data-theme', 'dark');\n return true;\n } else if (originalTheme) {\n htmlElement.setAttribute('data-theme', originalTheme);\n return false;\n }\n }\n return false;\n};\n\n/**\n * Save original theme from white label\n */\nconst saveOriginalTheme = () => {\n const htmlElement = document.documentElement;\n const currentTheme = htmlElement.getAttribute('data-theme');\n if (currentTheme && !htmlElement.getAttribute('data-original-theme')) {\n htmlElement.setAttribute('data-original-theme', currentTheme);\n }\n};\n\n/**\n * Theme store using Zustand with persistence\n */\nexport const useThemeStore = create<ThemeStore>()(\n devtools(\n persist(\n (set, get) => ({\n // Initial state\n themeMode: 'system',\n isDark: false,\n\n // Actions\n applyTheme: (mode: ThemeMode) => {\n const isDark = applyThemeToDOM(mode);\n set({ isDark });\n },\n\n toggleTheme: () => {\n const { themeMode, applyTheme } = get();\n let newMode: ThemeMode;\n\n if (themeMode === 'light') {\n newMode = 'dark';\n } else if (themeMode === 'dark') {\n newMode = 'light';\n } else {\n // Se estiver em 'system', vai para 'dark'\n newMode = 'dark';\n }\n\n set({ themeMode: newMode });\n applyTheme(newMode);\n },\n\n setTheme: (mode: ThemeMode) => {\n const { applyTheme } = get();\n set({ themeMode: mode });\n applyTheme(mode);\n },\n\n initializeTheme: () => {\n const { themeMode, applyTheme } = get();\n\n // Save original theme from white label\n saveOriginalTheme();\n\n // Apply the current theme mode\n applyTheme(themeMode);\n },\n\n handleSystemThemeChange: () => {\n const { themeMode, applyTheme } = get();\n // Only respond to system changes when in system mode\n if (themeMode === 'system') {\n applyTheme('system');\n }\n },\n }),\n {\n name: 'theme-store', // Nome da chave no localStorage\n partialize: (state) => ({\n themeMode: state.themeMode,\n }), // Só persiste o themeMode, não o isDark\n }\n ),\n {\n name: 'theme-store',\n }\n )\n);\n"],"mappings":"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","names":[]}
@@ -1,81 +1,116 @@
1
1
  // src/hooks/useTheme.ts
2
- import { useEffect, useState, useCallback, useRef } from "react";
3
- var useTheme = () => {
4
- const [themeMode, setThemeMode] = useState("system");
5
- const [isDark, setIsDark] = useState(false);
6
- const themeModeRef = useRef("system");
7
- const applyTheme = useCallback((mode) => {
8
- const htmlElement = document.documentElement;
9
- const originalTheme = htmlElement.getAttribute("data-original-theme");
10
- if (mode === "dark") {
2
+ import { useEffect } from "react";
3
+
4
+ // src/store/themeStore.ts
5
+ import { create } from "zustand";
6
+ import { devtools, persist } from "zustand/middleware";
7
+ var applyThemeToDOM = (mode) => {
8
+ const htmlElement = document.documentElement;
9
+ const originalTheme = htmlElement.getAttribute("data-original-theme");
10
+ if (mode === "dark") {
11
+ htmlElement.setAttribute("data-theme", "dark");
12
+ return true;
13
+ } else if (mode === "light") {
14
+ if (originalTheme) {
15
+ htmlElement.setAttribute("data-theme", originalTheme);
16
+ }
17
+ return false;
18
+ } else if (mode === "system") {
19
+ const isSystemDark = window.matchMedia(
20
+ "(prefers-color-scheme: dark)"
21
+ ).matches;
22
+ if (isSystemDark) {
11
23
  htmlElement.setAttribute("data-theme", "dark");
12
- setIsDark(true);
13
- } else if (mode === "light") {
14
- if (originalTheme) {
15
- htmlElement.setAttribute("data-theme", originalTheme);
16
- }
17
- setIsDark(false);
18
- } else if (mode === "system") {
19
- const isSystemDark = window.matchMedia(
20
- "(prefers-color-scheme: dark)"
21
- ).matches;
22
- if (isSystemDark) {
23
- htmlElement.setAttribute("data-theme", "dark");
24
- setIsDark(true);
25
- } else if (originalTheme) {
26
- htmlElement.setAttribute("data-theme", originalTheme);
27
- setIsDark(false);
28
- }
24
+ return true;
25
+ } else if (originalTheme) {
26
+ htmlElement.setAttribute("data-theme", originalTheme);
27
+ return false;
29
28
  }
30
- }, []);
31
- const toggleTheme = useCallback(() => {
32
- let newMode;
33
- if (themeMode === "light") {
34
- newMode = "dark";
35
- } else if (themeMode === "dark") {
36
- newMode = "light";
37
- } else {
38
- newMode = "dark";
29
+ }
30
+ return false;
31
+ };
32
+ var saveOriginalTheme = () => {
33
+ const htmlElement = document.documentElement;
34
+ const currentTheme = htmlElement.getAttribute("data-theme");
35
+ if (currentTheme && !htmlElement.getAttribute("data-original-theme")) {
36
+ htmlElement.setAttribute("data-original-theme", currentTheme);
37
+ }
38
+ };
39
+ var useThemeStore = create()(
40
+ devtools(
41
+ persist(
42
+ (set, get) => ({
43
+ // Initial state
44
+ themeMode: "system",
45
+ isDark: false,
46
+ // Actions
47
+ applyTheme: (mode) => {
48
+ const isDark = applyThemeToDOM(mode);
49
+ set({ isDark });
50
+ },
51
+ toggleTheme: () => {
52
+ const { themeMode, applyTheme } = get();
53
+ let newMode;
54
+ if (themeMode === "light") {
55
+ newMode = "dark";
56
+ } else if (themeMode === "dark") {
57
+ newMode = "light";
58
+ } else {
59
+ newMode = "dark";
60
+ }
61
+ set({ themeMode: newMode });
62
+ applyTheme(newMode);
63
+ },
64
+ setTheme: (mode) => {
65
+ const { applyTheme } = get();
66
+ set({ themeMode: mode });
67
+ applyTheme(mode);
68
+ },
69
+ initializeTheme: () => {
70
+ const { themeMode, applyTheme } = get();
71
+ saveOriginalTheme();
72
+ applyTheme(themeMode);
73
+ },
74
+ handleSystemThemeChange: () => {
75
+ const { themeMode, applyTheme } = get();
76
+ if (themeMode === "system") {
77
+ applyTheme("system");
78
+ }
79
+ }
80
+ }),
81
+ {
82
+ name: "theme-store",
83
+ // Nome da chave no localStorage
84
+ partialize: (state) => ({
85
+ themeMode: state.themeMode
86
+ })
87
+ // Só persiste o themeMode, não o isDark
88
+ }
89
+ ),
90
+ {
91
+ name: "theme-store"
39
92
  }
40
- setThemeMode(newMode);
41
- themeModeRef.current = newMode;
42
- applyTheme(newMode);
43
- localStorage.setItem("theme-mode", newMode);
44
- }, [themeMode, applyTheme]);
45
- const setTheme = useCallback(
46
- (mode) => {
47
- setThemeMode(mode);
48
- themeModeRef.current = mode;
49
- applyTheme(mode);
50
- localStorage.setItem("theme-mode", mode);
51
- },
52
- [applyTheme]
53
- );
93
+ )
94
+ );
95
+
96
+ // src/hooks/useTheme.ts
97
+ var useTheme = () => {
98
+ const {
99
+ themeMode,
100
+ isDark,
101
+ toggleTheme,
102
+ setTheme,
103
+ initializeTheme,
104
+ handleSystemThemeChange
105
+ } = useThemeStore();
54
106
  useEffect(() => {
55
- const htmlElement = document.documentElement;
56
- const currentTheme = htmlElement.getAttribute("data-theme");
57
- if (currentTheme && !htmlElement.getAttribute("data-original-theme")) {
58
- htmlElement.setAttribute("data-original-theme", currentTheme);
59
- }
60
- const savedThemeMode = localStorage.getItem("theme-mode");
61
- const initialMode = savedThemeMode || "system";
62
- if (!savedThemeMode) {
63
- localStorage.setItem("theme-mode", "system");
64
- }
65
- setThemeMode(initialMode);
66
- themeModeRef.current = initialMode;
67
- applyTheme(initialMode);
107
+ initializeTheme();
68
108
  const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)");
69
- const handleSystemThemeChange = () => {
70
- if (themeModeRef.current === "system") {
71
- applyTheme("system");
72
- }
73
- };
74
109
  mediaQuery.addEventListener("change", handleSystemThemeChange);
75
110
  return () => {
76
111
  mediaQuery.removeEventListener("change", handleSystemThemeChange);
77
112
  };
78
- }, [applyTheme]);
113
+ }, [initializeTheme, handleSystemThemeChange]);
79
114
  return {
80
115
  themeMode,
81
116
  isDark,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/hooks/useTheme.ts"],"sourcesContent":["import { useEffect, useState, useCallback, useRef } from 'react';\n\nexport type ThemeMode = 'light' | 'dark' | 'system';\n\n/**\n * Hook para gerenciar temas com suporte a alternância manual e detecção automática do sistema\n * Este hook permite alternar entre temas light, dark e automático baseado nas preferências do sistema\n */\nexport const useTheme = () => {\n const [themeMode, setThemeMode] = useState<ThemeMode>('system');\n const [isDark, setIsDark] = useState(false);\n\n // Ref para manter o estado atual do tema de forma síncrona\n const themeModeRef = useRef<ThemeMode>('system');\n\n // Função para aplicar o tema baseado no modo selecionado\n const applyTheme = useCallback((mode: ThemeMode) => {\n const htmlElement = document.documentElement;\n const originalTheme = htmlElement.getAttribute('data-original-theme');\n\n if (mode === 'dark') {\n htmlElement.setAttribute('data-theme', 'dark');\n setIsDark(true);\n } else if (mode === 'light') {\n if (originalTheme) {\n htmlElement.setAttribute('data-theme', originalTheme);\n }\n setIsDark(false);\n } else if (mode === 'system') {\n const isSystemDark = window.matchMedia(\n '(prefers-color-scheme: dark)'\n ).matches;\n if (isSystemDark) {\n htmlElement.setAttribute('data-theme', 'dark');\n setIsDark(true);\n } else if (originalTheme) {\n htmlElement.setAttribute('data-theme', originalTheme);\n setIsDark(false);\n }\n }\n }, []);\n\n // Função para alternar entre os temas\n const toggleTheme = useCallback(() => {\n let newMode: ThemeMode;\n if (themeMode === 'light') {\n newMode = 'dark';\n } else if (themeMode === 'dark') {\n newMode = 'light';\n } else {\n // Se estiver em 'system', vai para 'dark'\n newMode = 'dark';\n }\n setThemeMode(newMode);\n themeModeRef.current = newMode;\n applyTheme(newMode);\n localStorage.setItem('theme-mode', newMode);\n }, [themeMode, applyTheme]);\n\n // Função para definir um tema específico\n const setTheme = useCallback(\n (mode: ThemeMode) => {\n setThemeMode(mode);\n themeModeRef.current = mode;\n applyTheme(mode);\n localStorage.setItem('theme-mode', mode);\n },\n [applyTheme]\n );\n\n useEffect(() => {\n const htmlElement = document.documentElement;\n\n // Salva o theme original do white label na primeira execução\n const currentTheme = htmlElement.getAttribute('data-theme');\n if (currentTheme && !htmlElement.getAttribute('data-original-theme')) {\n htmlElement.setAttribute('data-original-theme', currentTheme);\n }\n\n // Carrega o tema salvo no localStorage ou usa 'system' como padrão\n const savedThemeMode = localStorage.getItem('theme-mode') as ThemeMode;\n const initialMode = savedThemeMode || 'system';\n\n // Se não tema salvo, persiste 'system' como padrão\n if (!savedThemeMode) {\n localStorage.setItem('theme-mode', 'system');\n }\n\n setThemeMode(initialMode);\n themeModeRef.current = initialMode;\n applyTheme(initialMode);\n\n // Listener para mudanças nas preferências do sistema (apenas quando mode é 'system')\n const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)');\n const handleSystemThemeChange = () => {\n // Usa o ref para ter acesso ao estado atual de forma síncrona\n if (themeModeRef.current === 'system') {\n applyTheme('system');\n }\n };\n\n mediaQuery.addEventListener('change', handleSystemThemeChange);\n\n return () => {\n mediaQuery.removeEventListener('change', handleSystemThemeChange);\n };\n }, [applyTheme]);\n\n return {\n themeMode,\n isDark,\n toggleTheme,\n setTheme,\n };\n};\n"],"mappings":";AAAA,SAAS,WAAW,UAAU,aAAa,cAAc;AAQlD,IAAM,WAAW,MAAM;AAC5B,QAAM,CAAC,WAAW,YAAY,IAAI,SAAoB,QAAQ;AAC9D,QAAM,CAAC,QAAQ,SAAS,IAAI,SAAS,KAAK;AAG1C,QAAM,eAAe,OAAkB,QAAQ;AAG/C,QAAM,aAAa,YAAY,CAAC,SAAoB;AAClD,UAAM,cAAc,SAAS;AAC7B,UAAM,gBAAgB,YAAY,aAAa,qBAAqB;AAEpE,QAAI,SAAS,QAAQ;AACnB,kBAAY,aAAa,cAAc,MAAM;AAC7C,gBAAU,IAAI;AAAA,IAChB,WAAW,SAAS,SAAS;AAC3B,UAAI,eAAe;AACjB,oBAAY,aAAa,cAAc,aAAa;AAAA,MACtD;AACA,gBAAU,KAAK;AAAA,IACjB,WAAW,SAAS,UAAU;AAC5B,YAAM,eAAe,OAAO;AAAA,QAC1B;AAAA,MACF,EAAE;AACF,UAAI,cAAc;AAChB,oBAAY,aAAa,cAAc,MAAM;AAC7C,kBAAU,IAAI;AAAA,MAChB,WAAW,eAAe;AACxB,oBAAY,aAAa,cAAc,aAAa;AACpD,kBAAU,KAAK;AAAA,MACjB;AAAA,IACF;AAAA,EACF,GAAG,CAAC,CAAC;AAGL,QAAM,cAAc,YAAY,MAAM;AACpC,QAAI;AACJ,QAAI,cAAc,SAAS;AACzB,gBAAU;AAAA,IACZ,WAAW,cAAc,QAAQ;AAC/B,gBAAU;AAAA,IACZ,OAAO;AAEL,gBAAU;AAAA,IACZ;AACA,iBAAa,OAAO;AACpB,iBAAa,UAAU;AACvB,eAAW,OAAO;AAClB,iBAAa,QAAQ,cAAc,OAAO;AAAA,EAC5C,GAAG,CAAC,WAAW,UAAU,CAAC;AAG1B,QAAM,WAAW;AAAA,IACf,CAAC,SAAoB;AACnB,mBAAa,IAAI;AACjB,mBAAa,UAAU;AACvB,iBAAW,IAAI;AACf,mBAAa,QAAQ,cAAc,IAAI;AAAA,IACzC;AAAA,IACA,CAAC,UAAU;AAAA,EACb;AAEA,YAAU,MAAM;AACd,UAAM,cAAc,SAAS;AAG7B,UAAM,eAAe,YAAY,aAAa,YAAY;AAC1D,QAAI,gBAAgB,CAAC,YAAY,aAAa,qBAAqB,GAAG;AACpE,kBAAY,aAAa,uBAAuB,YAAY;AAAA,IAC9D;AAGA,UAAM,iBAAiB,aAAa,QAAQ,YAAY;AACxD,UAAM,cAAc,kBAAkB;AAGtC,QAAI,CAAC,gBAAgB;AACnB,mBAAa,QAAQ,cAAc,QAAQ;AAAA,IAC7C;AAEA,iBAAa,WAAW;AACxB,iBAAa,UAAU;AACvB,eAAW,WAAW;AAGtB,UAAM,aAAa,OAAO,WAAW,8BAA8B;AACnE,UAAM,0BAA0B,MAAM;AAEpC,UAAI,aAAa,YAAY,UAAU;AACrC,mBAAW,QAAQ;AAAA,MACrB;AAAA,IACF;AAEA,eAAW,iBAAiB,UAAU,uBAAuB;AAE7D,WAAO,MAAM;AACX,iBAAW,oBAAoB,UAAU,uBAAuB;AAAA,IAClE;AAAA,EACF,GAAG,CAAC,UAAU,CAAC;AAEf,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;","names":[]}
1
+ {"version":3,"sources":["../../../src/hooks/useTheme.ts","../../../src/store/themeStore.ts"],"sourcesContent":["import { useEffect } from 'react';\nimport { useThemeStore, ThemeMode } from '../store/themeStore';\n\nexport type { ThemeMode };\n\n/**\n * Hook para gerenciar temas com suporte a alternância manual e detecção automática do sistema\n * Este hook permite alternar entre temas light, dark e automático baseado nas preferências do sistema\n * Utiliza Zustand para persistir o estado entre múltiplos arquivos e sessões\n */\nexport const useTheme = () => {\n const {\n themeMode,\n isDark,\n toggleTheme,\n setTheme,\n initializeTheme,\n handleSystemThemeChange,\n } = useThemeStore();\n\n useEffect(() => {\n // Initialize theme on first render\n initializeTheme();\n\n // Listener para mudanças nas preferências do sistema (apenas quando mode é 'system')\n const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)');\n\n mediaQuery.addEventListener('change', handleSystemThemeChange);\n\n return () => {\n mediaQuery.removeEventListener('change', handleSystemThemeChange);\n };\n }, [initializeTheme, handleSystemThemeChange]);\n\n return {\n themeMode,\n isDark,\n toggleTheme,\n setTheme,\n };\n};\n","import { create } from 'zustand';\nimport { devtools, persist } from 'zustand/middleware';\n\nexport type ThemeMode = 'light' | 'dark' | 'system';\n\n/**\n * Theme store state interface\n */\nexport interface ThemeState {\n /**\n * Current theme mode\n */\n themeMode: ThemeMode;\n /**\n * Whether the current theme is dark\n */\n isDark: boolean;\n}\n\n/**\n * Theme store actions interface\n */\nexport interface ThemeActions {\n /**\n * Apply theme based on the mode selected\n */\n applyTheme: (mode: ThemeMode) => void;\n /**\n * Toggle between themes\n */\n toggleTheme: () => void;\n /**\n * Set a specific theme mode\n */\n setTheme: (mode: ThemeMode) => void;\n /**\n * Initialize theme on app start\n */\n initializeTheme: () => void;\n /**\n * Handle system theme change\n */\n handleSystemThemeChange: () => void;\n}\n\nexport type ThemeStore = ThemeState & ThemeActions;\n\n/**\n * Apply theme to DOM based on mode\n */\nconst applyThemeToDOM = (mode: ThemeMode): boolean => {\n const htmlElement = document.documentElement;\n const originalTheme = htmlElement.getAttribute('data-original-theme');\n\n if (mode === 'dark') {\n htmlElement.setAttribute('data-theme', 'dark');\n return true;\n } else if (mode === 'light') {\n if (originalTheme) {\n htmlElement.setAttribute('data-theme', originalTheme);\n }\n return false;\n } else if (mode === 'system') {\n const isSystemDark = window.matchMedia(\n '(prefers-color-scheme: dark)'\n ).matches;\n if (isSystemDark) {\n htmlElement.setAttribute('data-theme', 'dark');\n return true;\n } else if (originalTheme) {\n htmlElement.setAttribute('data-theme', originalTheme);\n return false;\n }\n }\n return false;\n};\n\n/**\n * Save original theme from white label\n */\nconst saveOriginalTheme = () => {\n const htmlElement = document.documentElement;\n const currentTheme = htmlElement.getAttribute('data-theme');\n if (currentTheme && !htmlElement.getAttribute('data-original-theme')) {\n htmlElement.setAttribute('data-original-theme', currentTheme);\n }\n};\n\n/**\n * Theme store using Zustand with persistence\n */\nexport const useThemeStore = create<ThemeStore>()(\n devtools(\n persist(\n (set, get) => ({\n // Initial state\n themeMode: 'system',\n isDark: false,\n\n // Actions\n applyTheme: (mode: ThemeMode) => {\n const isDark = applyThemeToDOM(mode);\n set({ isDark });\n },\n\n toggleTheme: () => {\n const { themeMode, applyTheme } = get();\n let newMode: ThemeMode;\n\n if (themeMode === 'light') {\n newMode = 'dark';\n } else if (themeMode === 'dark') {\n newMode = 'light';\n } else {\n // Se estiver em 'system', vai para 'dark'\n newMode = 'dark';\n }\n\n set({ themeMode: newMode });\n applyTheme(newMode);\n },\n\n setTheme: (mode: ThemeMode) => {\n const { applyTheme } = get();\n set({ themeMode: mode });\n applyTheme(mode);\n },\n\n initializeTheme: () => {\n const { themeMode, applyTheme } = get();\n\n // Save original theme from white label\n saveOriginalTheme();\n\n // Apply the current theme mode\n applyTheme(themeMode);\n },\n\n handleSystemThemeChange: () => {\n const { themeMode, applyTheme } = get();\n // Only respond to system changes when in system mode\n if (themeMode === 'system') {\n applyTheme('system');\n }\n },\n }),\n {\n name: 'theme-store', // Nome da chave no localStorage\n partialize: (state) => ({\n themeMode: state.themeMode,\n }), // Só persiste o themeMode, não o isDark\n }\n ),\n {\n name: 'theme-store',\n }\n )\n);\n"],"mappings":";AAAA,SAAS,iBAAiB;;;ACA1B,SAAS,cAAc;AACvB,SAAS,UAAU,eAAe;AAiDlC,IAAM,kBAAkB,CAAC,SAA6B;AACpD,QAAM,cAAc,SAAS;AAC7B,QAAM,gBAAgB,YAAY,aAAa,qBAAqB;AAEpE,MAAI,SAAS,QAAQ;AACnB,gBAAY,aAAa,cAAc,MAAM;AAC7C,WAAO;AAAA,EACT,WAAW,SAAS,SAAS;AAC3B,QAAI,eAAe;AACjB,kBAAY,aAAa,cAAc,aAAa;AAAA,IACtD;AACA,WAAO;AAAA,EACT,WAAW,SAAS,UAAU;AAC5B,UAAM,eAAe,OAAO;AAAA,MAC1B;AAAA,IACF,EAAE;AACF,QAAI,cAAc;AAChB,kBAAY,aAAa,cAAc,MAAM;AAC7C,aAAO;AAAA,IACT,WAAW,eAAe;AACxB,kBAAY,aAAa,cAAc,aAAa;AACpD,aAAO;AAAA,IACT;AAAA,EACF;AACA,SAAO;AACT;AAKA,IAAM,oBAAoB,MAAM;AAC9B,QAAM,cAAc,SAAS;AAC7B,QAAM,eAAe,YAAY,aAAa,YAAY;AAC1D,MAAI,gBAAgB,CAAC,YAAY,aAAa,qBAAqB,GAAG;AACpE,gBAAY,aAAa,uBAAuB,YAAY;AAAA,EAC9D;AACF;AAKO,IAAM,gBAAgB,OAAmB;AAAA,EAC9C;AAAA,IACE;AAAA,MACE,CAAC,KAAK,SAAS;AAAA;AAAA,QAEb,WAAW;AAAA,QACX,QAAQ;AAAA;AAAA,QAGR,YAAY,CAAC,SAAoB;AAC/B,gBAAM,SAAS,gBAAgB,IAAI;AACnC,cAAI,EAAE,OAAO,CAAC;AAAA,QAChB;AAAA,QAEA,aAAa,MAAM;AACjB,gBAAM,EAAE,WAAW,WAAW,IAAI,IAAI;AACtC,cAAI;AAEJ,cAAI,cAAc,SAAS;AACzB,sBAAU;AAAA,UACZ,WAAW,cAAc,QAAQ;AAC/B,sBAAU;AAAA,UACZ,OAAO;AAEL,sBAAU;AAAA,UACZ;AAEA,cAAI,EAAE,WAAW,QAAQ,CAAC;AAC1B,qBAAW,OAAO;AAAA,QACpB;AAAA,QAEA,UAAU,CAAC,SAAoB;AAC7B,gBAAM,EAAE,WAAW,IAAI,IAAI;AAC3B,cAAI,EAAE,WAAW,KAAK,CAAC;AACvB,qBAAW,IAAI;AAAA,QACjB;AAAA,QAEA,iBAAiB,MAAM;AACrB,gBAAM,EAAE,WAAW,WAAW,IAAI,IAAI;AAGtC,4BAAkB;AAGlB,qBAAW,SAAS;AAAA,QACtB;AAAA,QAEA,yBAAyB,MAAM;AAC7B,gBAAM,EAAE,WAAW,WAAW,IAAI,IAAI;AAEtC,cAAI,cAAc,UAAU;AAC1B,uBAAW,QAAQ;AAAA,UACrB;AAAA,QACF;AAAA,MACF;AAAA,MACA;AAAA,QACE,MAAM;AAAA;AAAA,QACN,YAAY,CAAC,WAAW;AAAA,UACtB,WAAW,MAAM;AAAA,QACnB;AAAA;AAAA,MACF;AAAA,IACF;AAAA,IACA;AAAA,MACE,MAAM;AAAA,IACR;AAAA,EACF;AACF;;;ADnJO,IAAM,WAAW,MAAM;AAC5B,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,IAAI,cAAc;AAElB,YAAU,MAAM;AAEd,oBAAgB;AAGhB,UAAM,aAAa,OAAO,WAAW,8BAA8B;AAEnE,eAAW,iBAAiB,UAAU,uBAAuB;AAE7D,WAAO,MAAM;AACX,iBAAW,oBAAoB,UAAU,uBAAuB;AAAA,IAClE;AAAA,EACF,GAAG,CAAC,iBAAiB,uBAAuB,CAAC;AAE7C,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;","names":[]}