@iclips/ui 2.0.3 → 3.1.0

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 (130) hide show
  1. package/DESIGN.md +246 -0
  2. package/MIGRATION-v3.md +244 -0
  3. package/README.md +4 -0
  4. package/dist/alert-theme.css +20 -79
  5. package/dist/components/ui/charts/donut-chart.cjs +1 -1
  6. package/dist/components/ui/charts/donut-chart.cjs.map +1 -1
  7. package/dist/components/ui/charts/donut-chart.js +39 -60
  8. package/dist/components/ui/charts/donut-chart.js.map +1 -1
  9. package/dist/components/ui/charts/kpi-card.cjs +1 -1
  10. package/dist/components/ui/charts/kpi-card.cjs.map +1 -1
  11. package/dist/components/ui/charts/kpi-card.js +19 -19
  12. package/dist/components/ui/charts/kpi-card.js.map +1 -1
  13. package/dist/components/ui/data/comment-system.cjs +1 -1
  14. package/dist/components/ui/data/comment-system.cjs.map +1 -1
  15. package/dist/components/ui/data/comment-system.js +67 -67
  16. package/dist/components/ui/data/comment-system.js.map +1 -1
  17. package/dist/components/ui/data/data-table.cjs +1 -1
  18. package/dist/components/ui/data/data-table.cjs.map +1 -1
  19. package/dist/components/ui/data/data-table.js +112 -101
  20. package/dist/components/ui/data/data-table.js.map +1 -1
  21. package/dist/components/ui/data/editorial-calendar.cjs +1 -1
  22. package/dist/components/ui/data/editorial-calendar.cjs.map +1 -1
  23. package/dist/components/ui/data/editorial-calendar.js +291 -291
  24. package/dist/components/ui/data/editorial-calendar.js.map +1 -1
  25. package/dist/components/ui/data/filter-builder.cjs +1 -1
  26. package/dist/components/ui/data/filter-builder.cjs.map +1 -1
  27. package/dist/components/ui/data/filter-builder.js +1 -1
  28. package/dist/components/ui/data/filter-builder.js.map +1 -1
  29. package/dist/components/ui/feedback/empty-state.cjs +1 -1
  30. package/dist/components/ui/feedback/empty-state.cjs.map +1 -1
  31. package/dist/components/ui/feedback/empty-state.js +14 -14
  32. package/dist/components/ui/feedback/empty-state.js.map +1 -1
  33. package/dist/components/ui/feedback/toast.cjs +1 -1
  34. package/dist/components/ui/feedback/toast.cjs.map +1 -1
  35. package/dist/components/ui/feedback/toast.js +53 -22
  36. package/dist/components/ui/feedback/toast.js.map +1 -1
  37. package/dist/components/ui/forms/calendar.cjs +1 -1
  38. package/dist/components/ui/forms/calendar.cjs.map +1 -1
  39. package/dist/components/ui/forms/calendar.js +16 -16
  40. package/dist/components/ui/forms/calendar.js.map +1 -1
  41. package/dist/components/ui/forms/combobox.cjs +1 -1
  42. package/dist/components/ui/forms/combobox.cjs.map +1 -1
  43. package/dist/components/ui/forms/combobox.js +78 -76
  44. package/dist/components/ui/forms/combobox.js.map +1 -1
  45. package/dist/components/ui/forms/file-attachment-list.cjs +1 -1
  46. package/dist/components/ui/forms/file-attachment-list.cjs.map +1 -1
  47. package/dist/components/ui/forms/file-attachment-list.js +4 -4
  48. package/dist/components/ui/forms/file-attachment-list.js.map +1 -1
  49. package/dist/components/ui/forms/file-upload-zone.cjs +2 -2
  50. package/dist/components/ui/forms/file-upload-zone.cjs.map +1 -1
  51. package/dist/components/ui/forms/file-upload-zone.js +55 -49
  52. package/dist/components/ui/forms/file-upload-zone.js.map +1 -1
  53. package/dist/components/ui/forms/form.cjs +1 -1
  54. package/dist/components/ui/forms/form.cjs.map +1 -1
  55. package/dist/components/ui/forms/form.js +11 -11
  56. package/dist/components/ui/forms/form.js.map +1 -1
  57. package/dist/components/ui/forms/input-validation.cjs +1 -1
  58. package/dist/components/ui/forms/input-validation.cjs.map +1 -1
  59. package/dist/components/ui/forms/input-validation.js +20 -20
  60. package/dist/components/ui/forms/input-validation.js.map +1 -1
  61. package/dist/components/ui/forms/multi-select.cjs +1 -1
  62. package/dist/components/ui/forms/multi-select.cjs.map +1 -1
  63. package/dist/components/ui/forms/multi-select.js +69 -67
  64. package/dist/components/ui/forms/multi-select.js.map +1 -1
  65. package/dist/components/ui/forms/radio-group.cjs +1 -1
  66. package/dist/components/ui/forms/radio-group.cjs.map +1 -1
  67. package/dist/components/ui/forms/radio-group.js +19 -19
  68. package/dist/components/ui/forms/radio-group.js.map +1 -1
  69. package/dist/components/ui/forms/social-button.cjs +1 -1
  70. package/dist/components/ui/forms/social-button.cjs.map +1 -1
  71. package/dist/components/ui/forms/social-button.js +6 -6
  72. package/dist/components/ui/forms/social-button.js.map +1 -1
  73. package/dist/components/ui/forms/toggle.cjs +1 -1
  74. package/dist/components/ui/forms/toggle.cjs.map +1 -1
  75. package/dist/components/ui/forms/toggle.js +7 -7
  76. package/dist/components/ui/forms/toggle.js.map +1 -1
  77. package/dist/components/ui/navigation/navigation-menu.cjs +1 -1
  78. package/dist/components/ui/navigation/navigation-menu.cjs.map +1 -1
  79. package/dist/components/ui/navigation/navigation-menu.js +14 -14
  80. package/dist/components/ui/navigation/navigation-menu.js.map +1 -1
  81. package/dist/components/ui/navigation/sidebar.cjs +1 -1
  82. package/dist/components/ui/navigation/sidebar.cjs.map +1 -1
  83. package/dist/components/ui/navigation/sidebar.js +44 -44
  84. package/dist/components/ui/navigation/sidebar.js.map +1 -1
  85. package/dist/components/ui/overlays/context-menu.cjs +1 -1
  86. package/dist/components/ui/overlays/context-menu.cjs.map +1 -1
  87. package/dist/components/ui/overlays/context-menu.js +1 -1
  88. package/dist/components/ui/overlays/context-menu.js.map +1 -1
  89. package/dist/components/ui/overlays/dropdown-menu.cjs +1 -1
  90. package/dist/components/ui/overlays/dropdown-menu.cjs.map +1 -1
  91. package/dist/components/ui/overlays/dropdown-menu.js +5 -5
  92. package/dist/components/ui/overlays/dropdown-menu.js.map +1 -1
  93. package/dist/components/ui/overlays/menubar.cjs +1 -1
  94. package/dist/components/ui/overlays/menubar.cjs.map +1 -1
  95. package/dist/components/ui/overlays/menubar.js +29 -29
  96. package/dist/components/ui/overlays/menubar.js.map +1 -1
  97. package/dist/components/ui/overlays/tooltip.cjs +1 -1
  98. package/dist/components/ui/overlays/tooltip.cjs.map +1 -1
  99. package/dist/components/ui/overlays/tooltip.js +12 -12
  100. package/dist/components/ui/overlays/tooltip.js.map +1 -1
  101. package/dist/components/ui/primitives/avatar.cjs +1 -1
  102. package/dist/components/ui/primitives/avatar.cjs.map +1 -1
  103. package/dist/components/ui/primitives/avatar.js +20 -27
  104. package/dist/components/ui/primitives/avatar.js.map +1 -1
  105. package/dist/components/ui/primitives/badge.cjs +1 -1
  106. package/dist/components/ui/primitives/badge.cjs.map +1 -1
  107. package/dist/components/ui/primitives/badge.js +21 -18
  108. package/dist/components/ui/primitives/badge.js.map +1 -1
  109. package/dist/components/ui/primitives/button.cjs +1 -1
  110. package/dist/components/ui/primitives/button.cjs.map +1 -1
  111. package/dist/components/ui/primitives/button.js +11 -8
  112. package/dist/components/ui/primitives/button.js.map +1 -1
  113. package/dist/index.cjs +1 -1
  114. package/dist/index.css +1 -1
  115. package/dist/index.d.cts +6 -6
  116. package/dist/index.d.ts +6 -6
  117. package/dist/index.js +34 -35
  118. package/dist/index.js.map +1 -1
  119. package/dist/preset.css +1 -2
  120. package/dist/toast-theme.css +100 -64
  121. package/dist/tokens.css +59 -159
  122. package/docs/README.md +44 -0
  123. package/docs/acoes.md +103 -0
  124. package/docs/escolha.md +171 -0
  125. package/docs/formularios.md +137 -0
  126. package/docs/mensagens.md +114 -0
  127. package/docs/overlays.md +192 -0
  128. package/docs/status.md +71 -0
  129. package/package.json +7 -3
  130. package/scripts/check-colors.mjs +208 -0
@@ -1 +1 @@
1
- {"version":3,"file":"donut-chart.cjs","sources":["../../../../src/components/ui/charts/donut-chart.tsx"],"sourcesContent":["\"use client\";\n\nimport * as React from \"react\";\nimport { Label, Pie, PieChart, ResponsiveContainer, Sector, Tooltip } from \"recharts\";\nimport { cn } from \"../utils\";\n\n// ── Paleta padrão ─────────────────────────────────────────────────────────────\nconst DEFAULT_COLORS = [\n \"#3b82f6\", // blue-500\n \"#10b981\", // emerald-500\n \"#f59e0b\", // amber-500\n \"#ef4444\", // red-500\n \"#8b5cf6\", // violet-500\n \"#06b6d4\", // cyan-500\n \"#f97316\", // orange-500\n \"#14b8a6\", // teal-500\n \"#ec4899\", // pink-500\n \"#6366f1\", // indigo-500\n];\n\n// ── Tipos ─────────────────────────────────────────────────────────────────────\n\nexport interface DonutChartItem {\n label: string;\n value: number;\n color?: string;\n}\n\nexport interface DonutChartProps {\n data: DonutChartItem[];\n title?: string;\n formatValue?: (v: number) => string;\n className?: string;\n isLoading?: boolean;\n /**\n * Orientação da legenda em relação ao gráfico.\n * - \"vertical\": legenda abaixo do donut (padrão)\n * - \"horizontal\": legenda ao lado direito do donut\n */\n layout?: \"vertical\" | \"horizontal\";\n /**\n * Quando true, exibe o nome, valor e % da categoria no centro do\n * donut ao passar o mouse — desabilita o tooltip flutuante padrão.\n */\n activeLabel?: boolean;\n /**\n * Tamanho (px) do container do gráfico no eixo fixo.\n * - horizontal: largura e altura do donut (padrão: 140)\n * - vertical: altura do donut (padrão: 220)\n */\n chartSize?: number;\n}\n\n// ── Helpers ───────────────────────────────────────────────────────────────────\n\nfunction defaultFormat(v: number): string {\n return new Intl.NumberFormat(\"pt-BR\", { style: \"currency\", currency: \"BRL\" }).format(v);\n}\n\n// ── Skeleton ──────────────────────────────────────────────────────────────────\n\nfunction DonutSkeleton({ layout, chartSize }: { layout: \"vertical\" | \"horizontal\"; chartSize: number }) {\n const legendItems = [1, 2, 3].map((i) => (\n <div key={i} className=\"flex items-center gap-2\">\n <div className=\"w-2.5 h-2.5 rounded-full bg-muted shrink-0\" />\n <div className=\"h-3 bg-muted rounded flex-1\" />\n </div>\n ));\n\n if (layout === \"horizontal\") {\n return (\n <div className=\"flex items-center gap-6 w-full animate-pulse\">\n <div className=\"rounded-full bg-muted shrink-0\" style={{ width: chartSize, height: chartSize }} />\n <div className=\"flex flex-col gap-2 flex-1\">{legendItems}</div>\n </div>\n );\n }\n\n return (\n <div className=\"flex flex-col items-center justify-center w-full animate-pulse gap-4\">\n <div className=\"rounded-full bg-muted\" style={{ width: 140, height: 140 }} />\n <div className=\"flex flex-col gap-2 w-full max-w-50\">{legendItems}</div>\n </div>\n );\n}\n\n// ── Empty state ───────────────────────────────────────────────────────────────\n\nfunction DonutEmpty() {\n return (\n <div className=\"flex flex-col items-center justify-center w-full h-full text-muted-foreground gap-2\">\n <div\n className=\"rounded-full border-4 border-dashed border-muted\"\n style={{ width: 100, height: 100 }}\n />\n <span className=\"text-sm\">Sem dados para exibir</span>\n </div>\n );\n}\n\n// ── Tooltip flutuante (usado quando activeLabel=false) ────────────────────────\n\nfunction CustomTooltip({\n active,\n payload,\n formatValue,\n total,\n}: {\n active?: boolean;\n payload?: any[];\n formatValue: (v: number) => string;\n total: number;\n}) {\n if (!active || !payload?.length) return null;\n const item = payload[0];\n const pct = total > 0 ? ((item.value / total) * 100).toFixed(1) : \"0.0\";\n return (\n <div className=\"bg-popover border border-border rounded shadow-lg p-2 text-xs min-w-35\">\n <div className=\"font-medium mb-1\">{item.name}</div>\n <div className=\"flex justify-between gap-4\">\n <span className=\"text-muted-foreground\">Valor</span>\n <span className=\"font-mono\">{formatValue(item.value)}</span>\n </div>\n <div className=\"flex justify-between gap-4\">\n <span className=\"text-muted-foreground\">%</span>\n <span className=\"font-mono\">{pct}%</span>\n </div>\n </div>\n );\n}\n\n// ── Label central (usado quando activeLabel=true) ─────────────────────────────\n\ninterface CenterLabelProps {\n viewBox?: { cx: number; cy: number; innerRadius?: number; outerRadius?: number };\n activeIndex: number | null;\n chartData: Array<{ name: string; value: number; color: string }>;\n formatValue: (v: number) => string;\n total: number;\n}\n\nfunction CenterLabel({ viewBox, activeIndex, chartData, formatValue, total }: CenterLabelProps) {\n const cx = viewBox?.cx ?? 0;\n const cy = viewBox?.cy ?? 0;\n\n const item = activeIndex !== null && activeIndex >= 0 ? chartData[activeIndex] : null;\n\n if (item) {\n const pct = total > 0 ? ((item.value / total) * 100).toFixed(1) : \"0.0\";\n const maxLen = 13;\n const name = item.name.length > maxLen ? item.name.substring(0, maxLen - 1) + \"…\" : item.name;\n return (\n <g>\n <text\n x={cx}\n y={cy - 14}\n textAnchor=\"middle\"\n dominantBaseline=\"middle\"\n style={{ fontSize: 10, fill: \"var(--muted-foreground)\" }}\n >\n {name}\n </text>\n <text\n x={cx}\n y={cy + 2}\n textAnchor=\"middle\"\n dominantBaseline=\"middle\"\n style={{ fontSize: 11, fontWeight: 700, fill: item.color }}\n >\n {formatValue(item.value)}\n </text>\n <text\n x={cx}\n y={cy + 18}\n textAnchor=\"middle\"\n dominantBaseline=\"middle\"\n style={{ fontSize: 11, fill: \"var(--muted-foreground)\" }}\n >\n {pct}%\n </text>\n </g>\n );\n }\n\n return (\n <g>\n <text\n x={cx}\n y={cy - 8}\n textAnchor=\"middle\"\n dominantBaseline=\"middle\"\n style={{ fontSize: 10, fill: \"var(--muted-foreground)\" }}\n >\n Total\n </text>\n <text\n x={cx}\n y={cy + 8}\n textAnchor=\"middle\"\n dominantBaseline=\"middle\"\n style={{ fontSize: 13, fontWeight: 700, fill: \"currentColor\" }}\n >\n {formatValue(total)}\n </text>\n </g>\n );\n}\n\n// ── Legenda ───────────────────────────────────────────────────────────────────\n\nfunction DonutLegend({\n chartData,\n total,\n formatValue,\n activeIndex,\n onHover,\n}: {\n chartData: Array<{ name: string; value: number; color: string }>;\n total: number;\n formatValue: (v: number) => string;\n activeIndex: number | null;\n onHover: (index: number | null) => void;\n}) {\n return (\n <div className=\"flex flex-col gap-1.5\">\n {chartData.map((item, i) => {\n const pct = total > 0 ? ((item.value / total) * 100).toFixed(1) : \"0.0\";\n const isActive = activeIndex === i;\n const isDimmed = activeIndex !== null && !isActive;\n return (\n <div\n key={i}\n className=\"flex items-center gap-2 text-xs cursor-default rounded px-1 py-0.5 transition-opacity\"\n style={{ opacity: isDimmed ? 0.4 : 1 }}\n onMouseEnter={() => onHover(i)}\n onMouseLeave={() => onHover(null)}\n >\n <span\n className=\"inline-block w-2.5 h-2.5 rounded-full shrink-0 transition-transform\"\n style={{\n background: item.color,\n transform: isActive ? \"scale(1.3)\" : \"scale(1)\",\n }}\n />\n <span className=\"flex-1 truncate text-muted-foreground\">{item.name}</span>\n <span className=\"font-mono text-foreground\">{formatValue(item.value)}</span>\n <span className=\"text-muted-foreground w-10.5 text-right\">{pct}%</span>\n </div>\n );\n })}\n <div className=\"flex items-center gap-2 text-xs border-t border-border pt-1.5 mt-0.5\">\n <span className=\"flex-1 font-medium\">Total</span>\n <span className=\"font-mono font-semibold\">{formatValue(total)}</span>\n </div>\n </div>\n );\n}\n\n// ── Componente principal ──────────────────────────────────────────────────────\n\nexport function DonutChart({\n data,\n title,\n formatValue = defaultFormat,\n className,\n isLoading = false,\n layout = \"vertical\",\n activeLabel = false,\n chartSize: chartSizeProp,\n}: DonutChartProps) {\n const [activeIndex, setActiveIndex] = React.useState<number | null>(null);\n\n const total = React.useMemo(() => data.reduce((acc, d) => acc + d.value, 0), [data]);\n\n const chartData = React.useMemo(\n () =>\n data.map((item, i) => ({\n name: item.label,\n value: item.value,\n color: item.color ?? DEFAULT_COLORS[i % DEFAULT_COLORS.length],\n })),\n [data],\n );\n\n const isHorizontal = layout === \"horizontal\";\n const chartSize = chartSizeProp ?? (isHorizontal ? 140 : 220);\n const innerRadius = isHorizontal ? Math.round(chartSize * 0.34) : 55;\n const outerRadius = isHorizontal ? Math.round(chartSize * 0.51) : 85;\n\n return (\n <div className={cn(\"flex flex-col gap-4 w-full\", className)}>\n {title && <div className=\"text-sm font-semibold text-foreground\">{title}</div>}\n\n {isLoading ? (\n <DonutSkeleton layout={layout} chartSize={chartSize} />\n ) : data.length === 0 ? (\n <DonutEmpty />\n ) : (\n <div className={cn(isHorizontal ? \"flex items-center gap-4\" : \"flex flex-col gap-4\")}>\n {/* Gráfico */}\n <div\n className=\"shrink-0\"\n style={\n isHorizontal\n ? { width: chartSize, height: chartSize }\n : { width: \"100%\", height: chartSize }\n }\n >\n <ResponsiveContainer width=\"100%\" height=\"100%\">\n <PieChart>\n <Pie\n data={chartData}\n cx=\"50%\"\n cy=\"50%\"\n innerRadius={innerRadius}\n outerRadius={outerRadius}\n paddingAngle={2}\n dataKey=\"value\"\n nameKey=\"name\"\n onMouseEnter={(_, index) => setActiveIndex(index)}\n onMouseLeave={() => setActiveIndex(null)}\n shape={(props, index) => (\n <Sector\n {...props}\n fill={chartData[index]?.color}\n stroke=\"transparent\"\n opacity={activeIndex !== null && activeIndex !== index ? 0.4 : 1}\n />\n )}\n >\n {activeLabel && (\n <Label\n content={\n <CenterLabel\n activeIndex={activeIndex}\n chartData={chartData}\n formatValue={formatValue}\n total={total}\n />\n }\n />\n )}\n </Pie>\n {!activeLabel && (\n <Tooltip\n content={<CustomTooltip formatValue={formatValue} total={total} />}\n />\n )}\n </PieChart>\n </ResponsiveContainer>\n </div>\n\n {/* Legenda */}\n <div className={cn(isHorizontal ? \"flex-1 min-w-0\" : \"\")}>\n <DonutLegend\n chartData={chartData}\n total={total}\n formatValue={formatValue}\n activeIndex={activeIndex}\n onHover={setActiveIndex}\n />\n </div>\n </div>\n )}\n </div>\n );\n}\n"],"names":["DEFAULT_COLORS","defaultFormat","v","DonutSkeleton","layout","chartSize","legendItems","i","jsxs","jsx","DonutEmpty","CustomTooltip","active","payload","formatValue","total","item","pct","CenterLabel","viewBox","activeIndex","chartData","cx","cy","maxLen","name","DonutLegend","onHover","isActive","isDimmed","DonutChart","data","title","className","isLoading","activeLabel","chartSizeProp","setActiveIndex","React","acc","d","isHorizontal","innerRadius","outerRadius","cn","ResponsiveContainer","PieChart","Pie","_","index","props","Sector","_a","Label","Tooltip"],"mappings":"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"}
1
+ {"version":3,"file":"donut-chart.cjs","sources":["../../../../src/components/ui/charts/donut-chart.tsx"],"sourcesContent":["\"use client\";\n\nimport * as React from \"react\";\nimport { Label, Pie, PieChart, ResponsiveContainer, Sector, Tooltip } from \"recharts\";\nimport { cn } from \"../utils\";\n\n// ── Paleta padrão ─────────────────────────────────────────────────────────────\n// Séries de gráfico da paleta iClips (roxo + cinza, vizinhas distintas em luminância).\nconst DEFAULT_COLORS = Array.from({ length: 8 }, (_, i) => `var(--chart-${i + 1})`);\n\n// ── Tipos ─────────────────────────────────────────────────────────────────────\n\nexport interface DonutChartItem {\n label: string;\n value: number;\n color?: string;\n}\n\nexport interface DonutChartProps {\n data: DonutChartItem[];\n title?: string;\n formatValue?: (v: number) => string;\n className?: string;\n isLoading?: boolean;\n /**\n * Orientação da legenda em relação ao gráfico.\n * - \"vertical\": legenda abaixo do donut (padrão)\n * - \"horizontal\": legenda ao lado direito do donut\n */\n layout?: \"vertical\" | \"horizontal\";\n /**\n * Quando true, exibe o nome, valor e % da categoria no centro do\n * donut ao passar o mouse — desabilita o tooltip flutuante padrão.\n */\n activeLabel?: boolean;\n /**\n * Tamanho (px) do container do gráfico no eixo fixo.\n * - horizontal: largura e altura do donut (padrão: 140)\n * - vertical: altura do donut (padrão: 220)\n */\n chartSize?: number;\n}\n\n// ── Helpers ───────────────────────────────────────────────────────────────────\n\nfunction defaultFormat(v: number): string {\n return new Intl.NumberFormat(\"pt-BR\", { style: \"currency\", currency: \"BRL\" }).format(v);\n}\n\n// ── Skeleton ──────────────────────────────────────────────────────────────────\n\nfunction DonutSkeleton({ layout, chartSize }: { layout: \"vertical\" | \"horizontal\"; chartSize: number }) {\n const legendItems = [1, 2, 3].map((i) => (\n <div key={i} className=\"flex items-center gap-2\">\n <div className=\"w-2.5 h-2.5 rounded-full bg-muted shrink-0\" />\n <div className=\"h-3 bg-muted rounded flex-1\" />\n </div>\n ));\n\n if (layout === \"horizontal\") {\n return (\n <div className=\"flex items-center gap-6 w-full animate-pulse\">\n <div className=\"rounded-full bg-muted shrink-0\" style={{ width: chartSize, height: chartSize }} />\n <div className=\"flex flex-col gap-2 flex-1\">{legendItems}</div>\n </div>\n );\n }\n\n return (\n <div className=\"flex flex-col items-center justify-center w-full animate-pulse gap-4\">\n <div className=\"rounded-full bg-muted\" style={{ width: 140, height: 140 }} />\n <div className=\"flex flex-col gap-2 w-full max-w-50\">{legendItems}</div>\n </div>\n );\n}\n\n// ── Empty state ───────────────────────────────────────────────────────────────\n\nfunction DonutEmpty() {\n return (\n <div className=\"flex flex-col items-center justify-center w-full h-full text-muted-foreground gap-2\">\n <div\n className=\"rounded-full border-4 border-dashed border-muted\"\n style={{ width: 100, height: 100 }}\n />\n <span className=\"text-sm\">Sem dados para exibir</span>\n </div>\n );\n}\n\n// ── Tooltip flutuante (usado quando activeLabel=false) ────────────────────────\n\nfunction CustomTooltip({\n active,\n payload,\n formatValue,\n total,\n}: {\n active?: boolean;\n payload?: any[];\n formatValue: (v: number) => string;\n total: number;\n}) {\n if (!active || !payload?.length) return null;\n const item = payload[0];\n const pct = total > 0 ? ((item.value / total) * 100).toFixed(1) : \"0.0\";\n return (\n <div className=\"bg-popover border border-border rounded shadow-lg p-2 text-xs min-w-35\">\n <div className=\"font-medium mb-1\">{item.name}</div>\n <div className=\"flex justify-between gap-4\">\n <span className=\"text-muted-foreground\">Valor</span>\n <span className=\"font-mono\">{formatValue(item.value)}</span>\n </div>\n <div className=\"flex justify-between gap-4\">\n <span className=\"text-muted-foreground\">%</span>\n <span className=\"font-mono\">{pct}%</span>\n </div>\n </div>\n );\n}\n\n// ── Label central (usado quando activeLabel=true) ─────────────────────────────\n\ninterface CenterLabelProps {\n viewBox?: { cx: number; cy: number; innerRadius?: number; outerRadius?: number };\n activeIndex: number | null;\n chartData: Array<{ name: string; value: number; color: string }>;\n formatValue: (v: number) => string;\n total: number;\n}\n\nfunction CenterLabel({ viewBox, activeIndex, chartData, formatValue, total }: CenterLabelProps) {\n const cx = viewBox?.cx ?? 0;\n const cy = viewBox?.cy ?? 0;\n\n const item = activeIndex !== null && activeIndex >= 0 ? chartData[activeIndex] : null;\n\n if (item) {\n const pct = total > 0 ? ((item.value / total) * 100).toFixed(1) : \"0.0\";\n const maxLen = 13;\n const name = item.name.length > maxLen ? item.name.substring(0, maxLen - 1) + \"…\" : item.name;\n return (\n <g>\n <text\n x={cx}\n y={cy - 14}\n textAnchor=\"middle\"\n dominantBaseline=\"middle\"\n style={{ fontSize: 10, fill: \"var(--muted-foreground)\" }}\n >\n {name}\n </text>\n <text\n x={cx}\n y={cy + 2}\n textAnchor=\"middle\"\n dominantBaseline=\"middle\"\n style={{ fontSize: 11, fontWeight: 700, fill: item.color }}\n >\n {formatValue(item.value)}\n </text>\n <text\n x={cx}\n y={cy + 18}\n textAnchor=\"middle\"\n dominantBaseline=\"middle\"\n style={{ fontSize: 11, fill: \"var(--muted-foreground)\" }}\n >\n {pct}%\n </text>\n </g>\n );\n }\n\n return (\n <g>\n <text\n x={cx}\n y={cy - 8}\n textAnchor=\"middle\"\n dominantBaseline=\"middle\"\n style={{ fontSize: 10, fill: \"var(--muted-foreground)\" }}\n >\n Total\n </text>\n <text\n x={cx}\n y={cy + 8}\n textAnchor=\"middle\"\n dominantBaseline=\"middle\"\n style={{ fontSize: 13, fontWeight: 700, fill: \"currentColor\" }}\n >\n {formatValue(total)}\n </text>\n </g>\n );\n}\n\n// ── Legenda ───────────────────────────────────────────────────────────────────\n\nfunction DonutLegend({\n chartData,\n total,\n formatValue,\n activeIndex,\n onHover,\n}: {\n chartData: Array<{ name: string; value: number; color: string }>;\n total: number;\n formatValue: (v: number) => string;\n activeIndex: number | null;\n onHover: (index: number | null) => void;\n}) {\n return (\n <div className=\"flex flex-col gap-1.5\">\n {chartData.map((item, i) => {\n const pct = total > 0 ? ((item.value / total) * 100).toFixed(1) : \"0.0\";\n const isActive = activeIndex === i;\n const isDimmed = activeIndex !== null && !isActive;\n return (\n <div\n key={i}\n className=\"flex items-center gap-2 text-xs cursor-default rounded px-1 py-0.5 transition-opacity\"\n style={{ opacity: isDimmed ? 0.4 : 1 }}\n onMouseEnter={() => onHover(i)}\n onMouseLeave={() => onHover(null)}\n >\n <span\n className=\"inline-block w-2.5 h-2.5 rounded-full shrink-0 transition-transform\"\n style={{\n background: item.color,\n transform: isActive ? \"scale(1.3)\" : \"scale(1)\",\n }}\n />\n <span className=\"flex-1 truncate text-muted-foreground\">{item.name}</span>\n <span className=\"font-mono text-foreground\">{formatValue(item.value)}</span>\n <span className=\"text-muted-foreground w-10.5 text-right\">{pct}%</span>\n </div>\n );\n })}\n <div className=\"flex items-center gap-2 text-xs border-t border-border pt-1.5 mt-0.5\">\n <span className=\"flex-1 font-medium\">Total</span>\n <span className=\"font-mono font-semibold\">{formatValue(total)}</span>\n </div>\n </div>\n );\n}\n\n// ── Componente principal ──────────────────────────────────────────────────────\n\nexport function DonutChart({\n data,\n title,\n formatValue = defaultFormat,\n className,\n isLoading = false,\n layout = \"vertical\",\n activeLabel = false,\n chartSize: chartSizeProp,\n}: DonutChartProps) {\n const [activeIndex, setActiveIndex] = React.useState<number | null>(null);\n\n const total = React.useMemo(() => data.reduce((acc, d) => acc + d.value, 0), [data]);\n\n const chartData = React.useMemo(\n () =>\n data.map((item, i) => ({\n name: item.label,\n value: item.value,\n color: item.color ?? DEFAULT_COLORS[i % DEFAULT_COLORS.length],\n })),\n [data],\n );\n\n const isHorizontal = layout === \"horizontal\";\n const chartSize = chartSizeProp ?? (isHorizontal ? 140 : 220);\n const innerRadius = isHorizontal ? Math.round(chartSize * 0.34) : 55;\n const outerRadius = isHorizontal ? Math.round(chartSize * 0.51) : 85;\n\n return (\n <div className={cn(\"flex flex-col gap-4 w-full\", className)}>\n {title && <div className=\"text-sm font-semibold text-foreground\">{title}</div>}\n\n {isLoading ? (\n <DonutSkeleton layout={layout} chartSize={chartSize} />\n ) : data.length === 0 ? (\n <DonutEmpty />\n ) : (\n <div className={cn(isHorizontal ? \"flex items-center gap-4\" : \"flex flex-col gap-4\")}>\n {/* Gráfico */}\n <div\n className=\"shrink-0\"\n style={\n isHorizontal\n ? { width: chartSize, height: chartSize }\n : { width: \"100%\", height: chartSize }\n }\n >\n <ResponsiveContainer width=\"100%\" height=\"100%\">\n <PieChart>\n <Pie\n data={chartData}\n cx=\"50%\"\n cy=\"50%\"\n innerRadius={innerRadius}\n outerRadius={outerRadius}\n paddingAngle={2}\n dataKey=\"value\"\n nameKey=\"name\"\n onMouseEnter={(_, index) => setActiveIndex(index)}\n onMouseLeave={() => setActiveIndex(null)}\n shape={(props, index) => (\n <Sector\n {...props}\n fill={chartData[index]?.color}\n stroke=\"transparent\"\n opacity={activeIndex !== null && activeIndex !== index ? 0.4 : 1}\n />\n )}\n >\n {activeLabel && (\n <Label\n content={\n <CenterLabel\n activeIndex={activeIndex}\n chartData={chartData}\n formatValue={formatValue}\n total={total}\n />\n }\n />\n )}\n </Pie>\n {!activeLabel && (\n <Tooltip\n content={<CustomTooltip formatValue={formatValue} total={total} />}\n />\n )}\n </PieChart>\n </ResponsiveContainer>\n </div>\n\n {/* Legenda */}\n <div className={cn(isHorizontal ? \"flex-1 min-w-0\" : \"\")}>\n <DonutLegend\n chartData={chartData}\n total={total}\n formatValue={formatValue}\n activeIndex={activeIndex}\n onHover={setActiveIndex}\n />\n </div>\n </div>\n )}\n </div>\n );\n}\n"],"names":["DEFAULT_COLORS","_","i","defaultFormat","v","DonutSkeleton","layout","chartSize","legendItems","jsxs","jsx","DonutEmpty","CustomTooltip","active","payload","formatValue","total","item","pct","CenterLabel","viewBox","activeIndex","chartData","cx","cy","maxLen","name","DonutLegend","onHover","isActive","isDimmed","DonutChart","data","title","className","isLoading","activeLabel","chartSizeProp","setActiveIndex","React","acc","d","isHorizontal","innerRadius","outerRadius","cn","ResponsiveContainer","PieChart","Pie","index","props","Sector","_a","Label","Tooltip"],"mappings":"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"}
@@ -1,30 +1,9 @@
1
1
  "use client";
2
2
  import { jsxs as l, jsx as e } from "react/jsx-runtime";
3
3
  import * as N from "react";
4
- import { ResponsiveContainer as z, PieChart as A, Pie as k, Label as D, Sector as L, Tooltip as M } from "recharts";
5
- import { cn as b } from "../utils.js";
6
- const y = [
7
- "#3b82f6",
8
- // blue-500
9
- "#10b981",
10
- // emerald-500
11
- "#f59e0b",
12
- // amber-500
13
- "#ef4444",
14
- // red-500
15
- "#8b5cf6",
16
- // violet-500
17
- "#06b6d4",
18
- // cyan-500
19
- "#f97316",
20
- // orange-500
21
- "#14b8a6",
22
- // teal-500
23
- "#ec4899",
24
- // pink-500
25
- "#6366f1"
26
- // indigo-500
27
- ];
4
+ import { ResponsiveContainer as A, PieChart as z, Pie as k, Label as D, Sector as L, Tooltip as M } from "recharts";
5
+ import { cn as v } from "../utils.js";
6
+ const b = Array.from({ length: 8 }, (n, t) => `var(--chart-${t + 1})`);
28
7
  function C(n) {
29
8
  return new Intl.NumberFormat("pt-BR", { style: "currency", currency: "BRL" }).format(n);
30
9
  }
@@ -77,15 +56,15 @@ function F({
77
56
  ] });
78
57
  }
79
58
  function T({ viewBox: n, activeIndex: t, chartData: s, formatValue: i, total: o }) {
80
- const r = (n == null ? void 0 : n.cx) ?? 0, c = (n == null ? void 0 : n.cy) ?? 0, d = t !== null && t >= 0 ? s[t] : null;
81
- if (d) {
82
- const a = o > 0 ? (d.value / o * 100).toFixed(1) : "0.0", f = 13, g = d.name.length > f ? d.name.substring(0, f - 1) + "…" : d.name;
59
+ const r = (n == null ? void 0 : n.cx) ?? 0, a = (n == null ? void 0 : n.cy) ?? 0, c = t !== null && t >= 0 ? s[t] : null;
60
+ if (c) {
61
+ const d = o > 0 ? (c.value / o * 100).toFixed(1) : "0.0", f = 13, g = c.name.length > f ? c.name.substring(0, f - 1) + "…" : c.name;
83
62
  return /* @__PURE__ */ l("g", { children: [
84
63
  /* @__PURE__ */ e(
85
64
  "text",
86
65
  {
87
66
  x: r,
88
- y: c - 14,
67
+ y: a - 14,
89
68
  textAnchor: "middle",
90
69
  dominantBaseline: "middle",
91
70
  style: { fontSize: 10, fill: "var(--muted-foreground)" },
@@ -96,23 +75,23 @@ function T({ viewBox: n, activeIndex: t, chartData: s, formatValue: i, total: o
96
75
  "text",
97
76
  {
98
77
  x: r,
99
- y: c + 2,
78
+ y: a + 2,
100
79
  textAnchor: "middle",
101
80
  dominantBaseline: "middle",
102
- style: { fontSize: 11, fontWeight: 700, fill: d.color },
103
- children: i(d.value)
81
+ style: { fontSize: 11, fontWeight: 700, fill: c.color },
82
+ children: i(c.value)
104
83
  }
105
84
  ),
106
85
  /* @__PURE__ */ l(
107
86
  "text",
108
87
  {
109
88
  x: r,
110
- y: c + 18,
89
+ y: a + 18,
111
90
  textAnchor: "middle",
112
91
  dominantBaseline: "middle",
113
92
  style: { fontSize: 11, fill: "var(--muted-foreground)" },
114
93
  children: [
115
- a,
94
+ d,
116
95
  "%"
117
96
  ]
118
97
  }
@@ -124,7 +103,7 @@ function T({ viewBox: n, activeIndex: t, chartData: s, formatValue: i, total: o
124
103
  "text",
125
104
  {
126
105
  x: r,
127
- y: c - 8,
106
+ y: a - 8,
128
107
  textAnchor: "middle",
129
108
  dominantBaseline: "middle",
130
109
  style: { fontSize: 10, fill: "var(--muted-foreground)" },
@@ -135,7 +114,7 @@ function T({ viewBox: n, activeIndex: t, chartData: s, formatValue: i, total: o
135
114
  "text",
136
115
  {
137
116
  x: r,
138
- y: c + 8,
117
+ y: a + 8,
139
118
  textAnchor: "middle",
140
119
  dominantBaseline: "middle",
141
120
  style: { fontSize: 13, fontWeight: 700, fill: "currentColor" },
@@ -152,14 +131,14 @@ function E({
152
131
  onHover: o
153
132
  }) {
154
133
  return /* @__PURE__ */ l("div", { className: "flex flex-col gap-1.5", children: [
155
- n.map((r, c) => {
156
- const d = t > 0 ? (r.value / t * 100).toFixed(1) : "0.0", a = i === c;
134
+ n.map((r, a) => {
135
+ const c = t > 0 ? (r.value / t * 100).toFixed(1) : "0.0", d = i === a;
157
136
  return /* @__PURE__ */ l(
158
137
  "div",
159
138
  {
160
139
  className: "flex items-center gap-2 text-xs cursor-default rounded px-1 py-0.5 transition-opacity",
161
- style: { opacity: i !== null && !a ? 0.4 : 1 },
162
- onMouseEnter: () => o(c),
140
+ style: { opacity: i !== null && !d ? 0.4 : 1 },
141
+ onMouseEnter: () => o(a),
163
142
  onMouseLeave: () => o(null),
164
143
  children: [
165
144
  /* @__PURE__ */ e(
@@ -168,19 +147,19 @@ function E({
168
147
  className: "inline-block w-2.5 h-2.5 rounded-full shrink-0 transition-transform",
169
148
  style: {
170
149
  background: r.color,
171
- transform: a ? "scale(1.3)" : "scale(1)"
150
+ transform: d ? "scale(1.3)" : "scale(1)"
172
151
  }
173
152
  }
174
153
  ),
175
154
  /* @__PURE__ */ e("span", { className: "flex-1 truncate text-muted-foreground", children: r.name }),
176
155
  /* @__PURE__ */ e("span", { className: "font-mono text-foreground", children: s(r.value) }),
177
156
  /* @__PURE__ */ l("span", { className: "text-muted-foreground w-10.5 text-right", children: [
178
- d,
157
+ c,
179
158
  "%"
180
159
  ] })
181
160
  ]
182
161
  },
183
- c
162
+ a
184
163
  );
185
164
  }),
186
165
  /* @__PURE__ */ l("div", { className: "flex items-center gap-2 text-xs border-t border-border pt-1.5 mt-0.5", children: [
@@ -189,33 +168,33 @@ function E({
189
168
  ] })
190
169
  ] });
191
170
  }
192
- function W({
171
+ function P({
193
172
  data: n,
194
173
  title: t,
195
174
  formatValue: s = C,
196
175
  className: i,
197
176
  isLoading: o = !1,
198
177
  layout: r = "vertical",
199
- activeLabel: c = !1,
200
- chartSize: d
178
+ activeLabel: a = !1,
179
+ chartSize: c
201
180
  }) {
202
- const [a, f] = N.useState(null), g = N.useMemo(() => n.reduce((m, u) => m + u.value, 0), [n]), p = N.useMemo(
181
+ const [d, f] = N.useState(null), g = N.useMemo(() => n.reduce((m, u) => m + u.value, 0), [n]), p = N.useMemo(
203
182
  () => n.map((m, u) => ({
204
183
  name: m.label,
205
184
  value: m.value,
206
- color: m.color ?? y[u % y.length]
185
+ color: m.color ?? b[u % b.length]
207
186
  })),
208
187
  [n]
209
- ), h = r === "horizontal", x = d ?? (h ? 140 : 220), w = h ? Math.round(x * 0.34) : 55, S = h ? Math.round(x * 0.51) : 85;
210
- return /* @__PURE__ */ l("div", { className: b("flex flex-col gap-4 w-full", i), children: [
188
+ ), h = r === "horizontal", x = c ?? (h ? 140 : 220), w = h ? Math.round(x * 0.34) : 55, S = h ? Math.round(x * 0.51) : 85;
189
+ return /* @__PURE__ */ l("div", { className: v("flex flex-col gap-4 w-full", i), children: [
211
190
  t && /* @__PURE__ */ e("div", { className: "text-sm font-semibold text-foreground", children: t }),
212
- o ? /* @__PURE__ */ e(R, { layout: r, chartSize: x }) : n.length === 0 ? /* @__PURE__ */ e(j, {}) : /* @__PURE__ */ l("div", { className: b(h ? "flex items-center gap-4" : "flex flex-col gap-4"), children: [
191
+ o ? /* @__PURE__ */ e(R, { layout: r, chartSize: x }) : n.length === 0 ? /* @__PURE__ */ e(j, {}) : /* @__PURE__ */ l("div", { className: v(h ? "flex items-center gap-4" : "flex flex-col gap-4"), children: [
213
192
  /* @__PURE__ */ e(
214
193
  "div",
215
194
  {
216
195
  className: "shrink-0",
217
196
  style: h ? { width: x, height: x } : { width: "100%", height: x },
218
- children: /* @__PURE__ */ e(z, { width: "100%", height: "100%", children: /* @__PURE__ */ l(A, { children: [
197
+ children: /* @__PURE__ */ e(A, { width: "100%", height: "100%", children: /* @__PURE__ */ l(z, { children: [
219
198
  /* @__PURE__ */ e(
220
199
  k,
221
200
  {
@@ -230,24 +209,24 @@ function W({
230
209
  onMouseEnter: (m, u) => f(u),
231
210
  onMouseLeave: () => f(null),
232
211
  shape: (m, u) => {
233
- var v;
212
+ var y;
234
213
  return /* @__PURE__ */ e(
235
214
  L,
236
215
  {
237
216
  ...m,
238
- fill: (v = p[u]) == null ? void 0 : v.color,
217
+ fill: (y = p[u]) == null ? void 0 : y.color,
239
218
  stroke: "transparent",
240
- opacity: a !== null && a !== u ? 0.4 : 1
219
+ opacity: d !== null && d !== u ? 0.4 : 1
241
220
  }
242
221
  );
243
222
  },
244
- children: c && /* @__PURE__ */ e(
223
+ children: a && /* @__PURE__ */ e(
245
224
  D,
246
225
  {
247
226
  content: /* @__PURE__ */ e(
248
227
  T,
249
228
  {
250
- activeIndex: a,
229
+ activeIndex: d,
251
230
  chartData: p,
252
231
  formatValue: s,
253
232
  total: g
@@ -257,7 +236,7 @@ function W({
257
236
  )
258
237
  }
259
238
  ),
260
- !c && /* @__PURE__ */ e(
239
+ !a && /* @__PURE__ */ e(
261
240
  M,
262
241
  {
263
242
  content: /* @__PURE__ */ e(F, { formatValue: s, total: g })
@@ -266,13 +245,13 @@ function W({
266
245
  ] }) })
267
246
  }
268
247
  ),
269
- /* @__PURE__ */ e("div", { className: b(h ? "flex-1 min-w-0" : ""), children: /* @__PURE__ */ e(
248
+ /* @__PURE__ */ e("div", { className: v(h ? "flex-1 min-w-0" : ""), children: /* @__PURE__ */ e(
270
249
  E,
271
250
  {
272
251
  chartData: p,
273
252
  total: g,
274
253
  formatValue: s,
275
- activeIndex: a,
254
+ activeIndex: d,
276
255
  onHover: f
277
256
  }
278
257
  ) })
@@ -280,6 +259,6 @@ function W({
280
259
  ] });
281
260
  }
282
261
  export {
283
- W as DonutChart
262
+ P as DonutChart
284
263
  };
285
264
  //# sourceMappingURL=donut-chart.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"donut-chart.js","sources":["../../../../src/components/ui/charts/donut-chart.tsx"],"sourcesContent":["\"use client\";\n\nimport * as React from \"react\";\nimport { Label, Pie, PieChart, ResponsiveContainer, Sector, Tooltip } from \"recharts\";\nimport { cn } from \"../utils\";\n\n// ── Paleta padrão ─────────────────────────────────────────────────────────────\nconst DEFAULT_COLORS = [\n \"#3b82f6\", // blue-500\n \"#10b981\", // emerald-500\n \"#f59e0b\", // amber-500\n \"#ef4444\", // red-500\n \"#8b5cf6\", // violet-500\n \"#06b6d4\", // cyan-500\n \"#f97316\", // orange-500\n \"#14b8a6\", // teal-500\n \"#ec4899\", // pink-500\n \"#6366f1\", // indigo-500\n];\n\n// ── Tipos ─────────────────────────────────────────────────────────────────────\n\nexport interface DonutChartItem {\n label: string;\n value: number;\n color?: string;\n}\n\nexport interface DonutChartProps {\n data: DonutChartItem[];\n title?: string;\n formatValue?: (v: number) => string;\n className?: string;\n isLoading?: boolean;\n /**\n * Orientação da legenda em relação ao gráfico.\n * - \"vertical\": legenda abaixo do donut (padrão)\n * - \"horizontal\": legenda ao lado direito do donut\n */\n layout?: \"vertical\" | \"horizontal\";\n /**\n * Quando true, exibe o nome, valor e % da categoria no centro do\n * donut ao passar o mouse — desabilita o tooltip flutuante padrão.\n */\n activeLabel?: boolean;\n /**\n * Tamanho (px) do container do gráfico no eixo fixo.\n * - horizontal: largura e altura do donut (padrão: 140)\n * - vertical: altura do donut (padrão: 220)\n */\n chartSize?: number;\n}\n\n// ── Helpers ───────────────────────────────────────────────────────────────────\n\nfunction defaultFormat(v: number): string {\n return new Intl.NumberFormat(\"pt-BR\", { style: \"currency\", currency: \"BRL\" }).format(v);\n}\n\n// ── Skeleton ──────────────────────────────────────────────────────────────────\n\nfunction DonutSkeleton({ layout, chartSize }: { layout: \"vertical\" | \"horizontal\"; chartSize: number }) {\n const legendItems = [1, 2, 3].map((i) => (\n <div key={i} className=\"flex items-center gap-2\">\n <div className=\"w-2.5 h-2.5 rounded-full bg-muted shrink-0\" />\n <div className=\"h-3 bg-muted rounded flex-1\" />\n </div>\n ));\n\n if (layout === \"horizontal\") {\n return (\n <div className=\"flex items-center gap-6 w-full animate-pulse\">\n <div className=\"rounded-full bg-muted shrink-0\" style={{ width: chartSize, height: chartSize }} />\n <div className=\"flex flex-col gap-2 flex-1\">{legendItems}</div>\n </div>\n );\n }\n\n return (\n <div className=\"flex flex-col items-center justify-center w-full animate-pulse gap-4\">\n <div className=\"rounded-full bg-muted\" style={{ width: 140, height: 140 }} />\n <div className=\"flex flex-col gap-2 w-full max-w-50\">{legendItems}</div>\n </div>\n );\n}\n\n// ── Empty state ───────────────────────────────────────────────────────────────\n\nfunction DonutEmpty() {\n return (\n <div className=\"flex flex-col items-center justify-center w-full h-full text-muted-foreground gap-2\">\n <div\n className=\"rounded-full border-4 border-dashed border-muted\"\n style={{ width: 100, height: 100 }}\n />\n <span className=\"text-sm\">Sem dados para exibir</span>\n </div>\n );\n}\n\n// ── Tooltip flutuante (usado quando activeLabel=false) ────────────────────────\n\nfunction CustomTooltip({\n active,\n payload,\n formatValue,\n total,\n}: {\n active?: boolean;\n payload?: any[];\n formatValue: (v: number) => string;\n total: number;\n}) {\n if (!active || !payload?.length) return null;\n const item = payload[0];\n const pct = total > 0 ? ((item.value / total) * 100).toFixed(1) : \"0.0\";\n return (\n <div className=\"bg-popover border border-border rounded shadow-lg p-2 text-xs min-w-35\">\n <div className=\"font-medium mb-1\">{item.name}</div>\n <div className=\"flex justify-between gap-4\">\n <span className=\"text-muted-foreground\">Valor</span>\n <span className=\"font-mono\">{formatValue(item.value)}</span>\n </div>\n <div className=\"flex justify-between gap-4\">\n <span className=\"text-muted-foreground\">%</span>\n <span className=\"font-mono\">{pct}%</span>\n </div>\n </div>\n );\n}\n\n// ── Label central (usado quando activeLabel=true) ─────────────────────────────\n\ninterface CenterLabelProps {\n viewBox?: { cx: number; cy: number; innerRadius?: number; outerRadius?: number };\n activeIndex: number | null;\n chartData: Array<{ name: string; value: number; color: string }>;\n formatValue: (v: number) => string;\n total: number;\n}\n\nfunction CenterLabel({ viewBox, activeIndex, chartData, formatValue, total }: CenterLabelProps) {\n const cx = viewBox?.cx ?? 0;\n const cy = viewBox?.cy ?? 0;\n\n const item = activeIndex !== null && activeIndex >= 0 ? chartData[activeIndex] : null;\n\n if (item) {\n const pct = total > 0 ? ((item.value / total) * 100).toFixed(1) : \"0.0\";\n const maxLen = 13;\n const name = item.name.length > maxLen ? item.name.substring(0, maxLen - 1) + \"…\" : item.name;\n return (\n <g>\n <text\n x={cx}\n y={cy - 14}\n textAnchor=\"middle\"\n dominantBaseline=\"middle\"\n style={{ fontSize: 10, fill: \"var(--muted-foreground)\" }}\n >\n {name}\n </text>\n <text\n x={cx}\n y={cy + 2}\n textAnchor=\"middle\"\n dominantBaseline=\"middle\"\n style={{ fontSize: 11, fontWeight: 700, fill: item.color }}\n >\n {formatValue(item.value)}\n </text>\n <text\n x={cx}\n y={cy + 18}\n textAnchor=\"middle\"\n dominantBaseline=\"middle\"\n style={{ fontSize: 11, fill: \"var(--muted-foreground)\" }}\n >\n {pct}%\n </text>\n </g>\n );\n }\n\n return (\n <g>\n <text\n x={cx}\n y={cy - 8}\n textAnchor=\"middle\"\n dominantBaseline=\"middle\"\n style={{ fontSize: 10, fill: \"var(--muted-foreground)\" }}\n >\n Total\n </text>\n <text\n x={cx}\n y={cy + 8}\n textAnchor=\"middle\"\n dominantBaseline=\"middle\"\n style={{ fontSize: 13, fontWeight: 700, fill: \"currentColor\" }}\n >\n {formatValue(total)}\n </text>\n </g>\n );\n}\n\n// ── Legenda ───────────────────────────────────────────────────────────────────\n\nfunction DonutLegend({\n chartData,\n total,\n formatValue,\n activeIndex,\n onHover,\n}: {\n chartData: Array<{ name: string; value: number; color: string }>;\n total: number;\n formatValue: (v: number) => string;\n activeIndex: number | null;\n onHover: (index: number | null) => void;\n}) {\n return (\n <div className=\"flex flex-col gap-1.5\">\n {chartData.map((item, i) => {\n const pct = total > 0 ? ((item.value / total) * 100).toFixed(1) : \"0.0\";\n const isActive = activeIndex === i;\n const isDimmed = activeIndex !== null && !isActive;\n return (\n <div\n key={i}\n className=\"flex items-center gap-2 text-xs cursor-default rounded px-1 py-0.5 transition-opacity\"\n style={{ opacity: isDimmed ? 0.4 : 1 }}\n onMouseEnter={() => onHover(i)}\n onMouseLeave={() => onHover(null)}\n >\n <span\n className=\"inline-block w-2.5 h-2.5 rounded-full shrink-0 transition-transform\"\n style={{\n background: item.color,\n transform: isActive ? \"scale(1.3)\" : \"scale(1)\",\n }}\n />\n <span className=\"flex-1 truncate text-muted-foreground\">{item.name}</span>\n <span className=\"font-mono text-foreground\">{formatValue(item.value)}</span>\n <span className=\"text-muted-foreground w-10.5 text-right\">{pct}%</span>\n </div>\n );\n })}\n <div className=\"flex items-center gap-2 text-xs border-t border-border pt-1.5 mt-0.5\">\n <span className=\"flex-1 font-medium\">Total</span>\n <span className=\"font-mono font-semibold\">{formatValue(total)}</span>\n </div>\n </div>\n );\n}\n\n// ── Componente principal ──────────────────────────────────────────────────────\n\nexport function DonutChart({\n data,\n title,\n formatValue = defaultFormat,\n className,\n isLoading = false,\n layout = \"vertical\",\n activeLabel = false,\n chartSize: chartSizeProp,\n}: DonutChartProps) {\n const [activeIndex, setActiveIndex] = React.useState<number | null>(null);\n\n const total = React.useMemo(() => data.reduce((acc, d) => acc + d.value, 0), [data]);\n\n const chartData = React.useMemo(\n () =>\n data.map((item, i) => ({\n name: item.label,\n value: item.value,\n color: item.color ?? DEFAULT_COLORS[i % DEFAULT_COLORS.length],\n })),\n [data],\n );\n\n const isHorizontal = layout === \"horizontal\";\n const chartSize = chartSizeProp ?? (isHorizontal ? 140 : 220);\n const innerRadius = isHorizontal ? Math.round(chartSize * 0.34) : 55;\n const outerRadius = isHorizontal ? Math.round(chartSize * 0.51) : 85;\n\n return (\n <div className={cn(\"flex flex-col gap-4 w-full\", className)}>\n {title && <div className=\"text-sm font-semibold text-foreground\">{title}</div>}\n\n {isLoading ? (\n <DonutSkeleton layout={layout} chartSize={chartSize} />\n ) : data.length === 0 ? (\n <DonutEmpty />\n ) : (\n <div className={cn(isHorizontal ? \"flex items-center gap-4\" : \"flex flex-col gap-4\")}>\n {/* Gráfico */}\n <div\n className=\"shrink-0\"\n style={\n isHorizontal\n ? { width: chartSize, height: chartSize }\n : { width: \"100%\", height: chartSize }\n }\n >\n <ResponsiveContainer width=\"100%\" height=\"100%\">\n <PieChart>\n <Pie\n data={chartData}\n cx=\"50%\"\n cy=\"50%\"\n innerRadius={innerRadius}\n outerRadius={outerRadius}\n paddingAngle={2}\n dataKey=\"value\"\n nameKey=\"name\"\n onMouseEnter={(_, index) => setActiveIndex(index)}\n onMouseLeave={() => setActiveIndex(null)}\n shape={(props, index) => (\n <Sector\n {...props}\n fill={chartData[index]?.color}\n stroke=\"transparent\"\n opacity={activeIndex !== null && activeIndex !== index ? 0.4 : 1}\n />\n )}\n >\n {activeLabel && (\n <Label\n content={\n <CenterLabel\n activeIndex={activeIndex}\n chartData={chartData}\n formatValue={formatValue}\n total={total}\n />\n }\n />\n )}\n </Pie>\n {!activeLabel && (\n <Tooltip\n content={<CustomTooltip formatValue={formatValue} total={total} />}\n />\n )}\n </PieChart>\n </ResponsiveContainer>\n </div>\n\n {/* Legenda */}\n <div className={cn(isHorizontal ? \"flex-1 min-w-0\" : \"\")}>\n <DonutLegend\n chartData={chartData}\n total={total}\n formatValue={formatValue}\n activeIndex={activeIndex}\n onHover={setActiveIndex}\n />\n </div>\n </div>\n )}\n </div>\n );\n}\n"],"names":["DEFAULT_COLORS","defaultFormat","v","DonutSkeleton","layout","chartSize","legendItems","jsxs","jsx","DonutEmpty","CustomTooltip","active","payload","formatValue","total","item","pct","CenterLabel","viewBox","activeIndex","chartData","cx","cy","maxLen","name","DonutLegend","onHover","i","isActive","DonutChart","data","title","className","isLoading","activeLabel","chartSizeProp","setActiveIndex","React","acc","d","isHorizontal","innerRadius","outerRadius","cn","ResponsiveContainer","PieChart","Pie","_","index","props","Sector","_a","Label","Tooltip"],"mappings":"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"}
1
+ {"version":3,"file":"donut-chart.js","sources":["../../../../src/components/ui/charts/donut-chart.tsx"],"sourcesContent":["\"use client\";\n\nimport * as React from \"react\";\nimport { Label, Pie, PieChart, ResponsiveContainer, Sector, Tooltip } from \"recharts\";\nimport { cn } from \"../utils\";\n\n// ── Paleta padrão ─────────────────────────────────────────────────────────────\n// Séries de gráfico da paleta iClips (roxo + cinza, vizinhas distintas em luminância).\nconst DEFAULT_COLORS = Array.from({ length: 8 }, (_, i) => `var(--chart-${i + 1})`);\n\n// ── Tipos ─────────────────────────────────────────────────────────────────────\n\nexport interface DonutChartItem {\n label: string;\n value: number;\n color?: string;\n}\n\nexport interface DonutChartProps {\n data: DonutChartItem[];\n title?: string;\n formatValue?: (v: number) => string;\n className?: string;\n isLoading?: boolean;\n /**\n * Orientação da legenda em relação ao gráfico.\n * - \"vertical\": legenda abaixo do donut (padrão)\n * - \"horizontal\": legenda ao lado direito do donut\n */\n layout?: \"vertical\" | \"horizontal\";\n /**\n * Quando true, exibe o nome, valor e % da categoria no centro do\n * donut ao passar o mouse — desabilita o tooltip flutuante padrão.\n */\n activeLabel?: boolean;\n /**\n * Tamanho (px) do container do gráfico no eixo fixo.\n * - horizontal: largura e altura do donut (padrão: 140)\n * - vertical: altura do donut (padrão: 220)\n */\n chartSize?: number;\n}\n\n// ── Helpers ───────────────────────────────────────────────────────────────────\n\nfunction defaultFormat(v: number): string {\n return new Intl.NumberFormat(\"pt-BR\", { style: \"currency\", currency: \"BRL\" }).format(v);\n}\n\n// ── Skeleton ──────────────────────────────────────────────────────────────────\n\nfunction DonutSkeleton({ layout, chartSize }: { layout: \"vertical\" | \"horizontal\"; chartSize: number }) {\n const legendItems = [1, 2, 3].map((i) => (\n <div key={i} className=\"flex items-center gap-2\">\n <div className=\"w-2.5 h-2.5 rounded-full bg-muted shrink-0\" />\n <div className=\"h-3 bg-muted rounded flex-1\" />\n </div>\n ));\n\n if (layout === \"horizontal\") {\n return (\n <div className=\"flex items-center gap-6 w-full animate-pulse\">\n <div className=\"rounded-full bg-muted shrink-0\" style={{ width: chartSize, height: chartSize }} />\n <div className=\"flex flex-col gap-2 flex-1\">{legendItems}</div>\n </div>\n );\n }\n\n return (\n <div className=\"flex flex-col items-center justify-center w-full animate-pulse gap-4\">\n <div className=\"rounded-full bg-muted\" style={{ width: 140, height: 140 }} />\n <div className=\"flex flex-col gap-2 w-full max-w-50\">{legendItems}</div>\n </div>\n );\n}\n\n// ── Empty state ───────────────────────────────────────────────────────────────\n\nfunction DonutEmpty() {\n return (\n <div className=\"flex flex-col items-center justify-center w-full h-full text-muted-foreground gap-2\">\n <div\n className=\"rounded-full border-4 border-dashed border-muted\"\n style={{ width: 100, height: 100 }}\n />\n <span className=\"text-sm\">Sem dados para exibir</span>\n </div>\n );\n}\n\n// ── Tooltip flutuante (usado quando activeLabel=false) ────────────────────────\n\nfunction CustomTooltip({\n active,\n payload,\n formatValue,\n total,\n}: {\n active?: boolean;\n payload?: any[];\n formatValue: (v: number) => string;\n total: number;\n}) {\n if (!active || !payload?.length) return null;\n const item = payload[0];\n const pct = total > 0 ? ((item.value / total) * 100).toFixed(1) : \"0.0\";\n return (\n <div className=\"bg-popover border border-border rounded shadow-lg p-2 text-xs min-w-35\">\n <div className=\"font-medium mb-1\">{item.name}</div>\n <div className=\"flex justify-between gap-4\">\n <span className=\"text-muted-foreground\">Valor</span>\n <span className=\"font-mono\">{formatValue(item.value)}</span>\n </div>\n <div className=\"flex justify-between gap-4\">\n <span className=\"text-muted-foreground\">%</span>\n <span className=\"font-mono\">{pct}%</span>\n </div>\n </div>\n );\n}\n\n// ── Label central (usado quando activeLabel=true) ─────────────────────────────\n\ninterface CenterLabelProps {\n viewBox?: { cx: number; cy: number; innerRadius?: number; outerRadius?: number };\n activeIndex: number | null;\n chartData: Array<{ name: string; value: number; color: string }>;\n formatValue: (v: number) => string;\n total: number;\n}\n\nfunction CenterLabel({ viewBox, activeIndex, chartData, formatValue, total }: CenterLabelProps) {\n const cx = viewBox?.cx ?? 0;\n const cy = viewBox?.cy ?? 0;\n\n const item = activeIndex !== null && activeIndex >= 0 ? chartData[activeIndex] : null;\n\n if (item) {\n const pct = total > 0 ? ((item.value / total) * 100).toFixed(1) : \"0.0\";\n const maxLen = 13;\n const name = item.name.length > maxLen ? item.name.substring(0, maxLen - 1) + \"…\" : item.name;\n return (\n <g>\n <text\n x={cx}\n y={cy - 14}\n textAnchor=\"middle\"\n dominantBaseline=\"middle\"\n style={{ fontSize: 10, fill: \"var(--muted-foreground)\" }}\n >\n {name}\n </text>\n <text\n x={cx}\n y={cy + 2}\n textAnchor=\"middle\"\n dominantBaseline=\"middle\"\n style={{ fontSize: 11, fontWeight: 700, fill: item.color }}\n >\n {formatValue(item.value)}\n </text>\n <text\n x={cx}\n y={cy + 18}\n textAnchor=\"middle\"\n dominantBaseline=\"middle\"\n style={{ fontSize: 11, fill: \"var(--muted-foreground)\" }}\n >\n {pct}%\n </text>\n </g>\n );\n }\n\n return (\n <g>\n <text\n x={cx}\n y={cy - 8}\n textAnchor=\"middle\"\n dominantBaseline=\"middle\"\n style={{ fontSize: 10, fill: \"var(--muted-foreground)\" }}\n >\n Total\n </text>\n <text\n x={cx}\n y={cy + 8}\n textAnchor=\"middle\"\n dominantBaseline=\"middle\"\n style={{ fontSize: 13, fontWeight: 700, fill: \"currentColor\" }}\n >\n {formatValue(total)}\n </text>\n </g>\n );\n}\n\n// ── Legenda ───────────────────────────────────────────────────────────────────\n\nfunction DonutLegend({\n chartData,\n total,\n formatValue,\n activeIndex,\n onHover,\n}: {\n chartData: Array<{ name: string; value: number; color: string }>;\n total: number;\n formatValue: (v: number) => string;\n activeIndex: number | null;\n onHover: (index: number | null) => void;\n}) {\n return (\n <div className=\"flex flex-col gap-1.5\">\n {chartData.map((item, i) => {\n const pct = total > 0 ? ((item.value / total) * 100).toFixed(1) : \"0.0\";\n const isActive = activeIndex === i;\n const isDimmed = activeIndex !== null && !isActive;\n return (\n <div\n key={i}\n className=\"flex items-center gap-2 text-xs cursor-default rounded px-1 py-0.5 transition-opacity\"\n style={{ opacity: isDimmed ? 0.4 : 1 }}\n onMouseEnter={() => onHover(i)}\n onMouseLeave={() => onHover(null)}\n >\n <span\n className=\"inline-block w-2.5 h-2.5 rounded-full shrink-0 transition-transform\"\n style={{\n background: item.color,\n transform: isActive ? \"scale(1.3)\" : \"scale(1)\",\n }}\n />\n <span className=\"flex-1 truncate text-muted-foreground\">{item.name}</span>\n <span className=\"font-mono text-foreground\">{formatValue(item.value)}</span>\n <span className=\"text-muted-foreground w-10.5 text-right\">{pct}%</span>\n </div>\n );\n })}\n <div className=\"flex items-center gap-2 text-xs border-t border-border pt-1.5 mt-0.5\">\n <span className=\"flex-1 font-medium\">Total</span>\n <span className=\"font-mono font-semibold\">{formatValue(total)}</span>\n </div>\n </div>\n );\n}\n\n// ── Componente principal ──────────────────────────────────────────────────────\n\nexport function DonutChart({\n data,\n title,\n formatValue = defaultFormat,\n className,\n isLoading = false,\n layout = \"vertical\",\n activeLabel = false,\n chartSize: chartSizeProp,\n}: DonutChartProps) {\n const [activeIndex, setActiveIndex] = React.useState<number | null>(null);\n\n const total = React.useMemo(() => data.reduce((acc, d) => acc + d.value, 0), [data]);\n\n const chartData = React.useMemo(\n () =>\n data.map((item, i) => ({\n name: item.label,\n value: item.value,\n color: item.color ?? DEFAULT_COLORS[i % DEFAULT_COLORS.length],\n })),\n [data],\n );\n\n const isHorizontal = layout === \"horizontal\";\n const chartSize = chartSizeProp ?? (isHorizontal ? 140 : 220);\n const innerRadius = isHorizontal ? Math.round(chartSize * 0.34) : 55;\n const outerRadius = isHorizontal ? Math.round(chartSize * 0.51) : 85;\n\n return (\n <div className={cn(\"flex flex-col gap-4 w-full\", className)}>\n {title && <div className=\"text-sm font-semibold text-foreground\">{title}</div>}\n\n {isLoading ? (\n <DonutSkeleton layout={layout} chartSize={chartSize} />\n ) : data.length === 0 ? (\n <DonutEmpty />\n ) : (\n <div className={cn(isHorizontal ? \"flex items-center gap-4\" : \"flex flex-col gap-4\")}>\n {/* Gráfico */}\n <div\n className=\"shrink-0\"\n style={\n isHorizontal\n ? { width: chartSize, height: chartSize }\n : { width: \"100%\", height: chartSize }\n }\n >\n <ResponsiveContainer width=\"100%\" height=\"100%\">\n <PieChart>\n <Pie\n data={chartData}\n cx=\"50%\"\n cy=\"50%\"\n innerRadius={innerRadius}\n outerRadius={outerRadius}\n paddingAngle={2}\n dataKey=\"value\"\n nameKey=\"name\"\n onMouseEnter={(_, index) => setActiveIndex(index)}\n onMouseLeave={() => setActiveIndex(null)}\n shape={(props, index) => (\n <Sector\n {...props}\n fill={chartData[index]?.color}\n stroke=\"transparent\"\n opacity={activeIndex !== null && activeIndex !== index ? 0.4 : 1}\n />\n )}\n >\n {activeLabel && (\n <Label\n content={\n <CenterLabel\n activeIndex={activeIndex}\n chartData={chartData}\n formatValue={formatValue}\n total={total}\n />\n }\n />\n )}\n </Pie>\n {!activeLabel && (\n <Tooltip\n content={<CustomTooltip formatValue={formatValue} total={total} />}\n />\n )}\n </PieChart>\n </ResponsiveContainer>\n </div>\n\n {/* Legenda */}\n <div className={cn(isHorizontal ? \"flex-1 min-w-0\" : \"\")}>\n <DonutLegend\n chartData={chartData}\n total={total}\n formatValue={formatValue}\n activeIndex={activeIndex}\n onHover={setActiveIndex}\n />\n </div>\n </div>\n )}\n </div>\n );\n}\n"],"names":["DEFAULT_COLORS","_","i","defaultFormat","v","DonutSkeleton","layout","chartSize","legendItems","jsxs","jsx","DonutEmpty","CustomTooltip","active","payload","formatValue","total","item","pct","CenterLabel","viewBox","activeIndex","chartData","cx","cy","maxLen","name","DonutLegend","onHover","isActive","DonutChart","data","title","className","isLoading","activeLabel","chartSizeProp","setActiveIndex","React","acc","d","isHorizontal","innerRadius","outerRadius","cn","ResponsiveContainer","PieChart","Pie","index","props","Sector","_a","Label","Tooltip"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- "use client";"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("react/jsx-runtime"),p=require("react"),c=require("../layout/card.cjs"),N=require("../primitives/badge.cjs"),l=require("../primitives/skeleton.cjs"),i=require("lucide-react"),m=require("../utils.cjs");function g(s){const r=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(s){for(const t in s)if(t!=="default"){const a=Object.getOwnPropertyDescriptor(s,t);Object.defineProperty(r,t,a.get?a:{enumerable:!0,get:()=>s[t]})}}return r.default=s,Object.freeze(r)}const b=g(p),u=b.forwardRef(({title:s,primaryContent:r,secondaryContent:t,trendValue:a,trendLabel:x,icon:j=i.Activity,isLoading:n=!1,onClick:o,className:h},f)=>{const d=!n&&!!o;return e.jsxs(c.Card,{ref:f,onClick:d?o:void 0,className:m.cn(d&&"cursor-pointer hover:bg-accent/50 transition-colors",h),children:[e.jsx(c.CardHeader,{className:"pb-1",children:e.jsx(c.CardTitle,{className:"flex items-center gap-2 text-sm text-muted-foreground",children:n?e.jsxs(e.Fragment,{children:[e.jsx(l.Skeleton,{className:"size-4 shrink-0 rounded"}),e.jsx(l.Skeleton,{className:"h-4 w-24"})]}):e.jsxs(e.Fragment,{children:[e.jsx(j,{className:"size-4 shrink-0 text-muted-foreground"}),e.jsx("span",{className:"truncate",children:s})]})})}),e.jsxs(c.CardContent,{className:"space-y-1 pt-0",children:[e.jsxs("div",{className:"flex items-baseline gap-2",children:[n?e.jsx(l.Skeleton,{className:"h-8 w-28"}):e.jsx("span",{className:"min-w-0 truncate text-2xl font-bold",title:r,children:r}),!n&&a!==void 0&&e.jsxs(N.Badge,{variant:"secondary",className:m.cn("h-auto shrink-0 px-1.5 py-0 text-xs",a>0?"text-green-600":"text-red-600"),children:[a>0?e.jsx(i.TrendingUp,{className:"mr-0.5 inline h-3 w-3"}):e.jsx(i.TrendingDown,{className:"mr-0.5 inline h-3 w-3"}),x]})]}),e.jsx("div",{className:"min-h-4 text-xs text-muted-foreground",children:n?e.jsx(l.Skeleton,{className:"h-3 w-full max-w-40"}):t&&e.jsx("span",{className:"block truncate",children:t})})]})]})});u.displayName="KPICard";exports.KPICard=u;
1
+ "use client";"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("react/jsx-runtime"),f=require("react"),n=require("../layout/card.cjs"),N=require("../primitives/badge.cjs"),l=require("../primitives/skeleton.cjs"),i=require("lucide-react"),m=require("../utils.cjs");function b(s){const r=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(s){for(const t in s)if(t!=="default"){const a=Object.getOwnPropertyDescriptor(s,t);Object.defineProperty(r,t,a.get?a:{enumerable:!0,get:()=>s[t]})}}return r.default=s,Object.freeze(r)}const g=b(f),u=g.forwardRef(({title:s,primaryContent:r,secondaryContent:t,trendValue:a,trendLabel:x,icon:h=i.Activity,isLoading:c=!1,onClick:o,className:j},p)=>{const d=!c&&!!o;return e.jsxs(n.Card,{ref:p,onClick:d?o:void 0,className:m.cn(d&&"cursor-pointer hover:bg-accent/50 transition-colors",j),children:[e.jsx(n.CardHeader,{className:"pb-1",children:e.jsx(n.CardTitle,{className:"flex items-center gap-2 text-sm text-muted-foreground",children:c?e.jsxs(e.Fragment,{children:[e.jsx(l.Skeleton,{className:"size-4 shrink-0 rounded"}),e.jsx(l.Skeleton,{className:"h-4 w-24"})]}):e.jsxs(e.Fragment,{children:[e.jsx(h,{className:"size-4 shrink-0 text-muted-foreground"}),e.jsx("span",{className:"truncate",children:s})]})})}),e.jsxs(n.CardContent,{className:"space-y-1 pt-0",children:[e.jsxs("div",{className:"flex items-baseline gap-2",children:[c?e.jsx(l.Skeleton,{className:"h-8 w-28"}):e.jsx("span",{className:"min-w-0 truncate text-2xl font-bold",title:r,children:r}),!c&&a!==void 0&&e.jsxs(N.Badge,{variant:"secondary",className:m.cn("h-auto shrink-0 px-1.5 py-0 text-xs",a>0?"text-success-emphasis":"text-destructive-emphasis"),children:[a>0?e.jsx(i.TrendingUp,{className:"mr-0.5 inline h-3 w-3"}):e.jsx(i.TrendingDown,{className:"mr-0.5 inline h-3 w-3"}),x]})]}),e.jsx("div",{className:"min-h-4 text-xs text-muted-foreground",children:c?e.jsx(l.Skeleton,{className:"h-3 w-full max-w-40"}):t&&e.jsx("span",{className:"block truncate",children:t})})]})]})});u.displayName="KPICard";exports.KPICard=u;
2
2
  //# sourceMappingURL=kpi-card.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"kpi-card.cjs","sources":["../../../../src/components/ui/charts/kpi-card.tsx"],"sourcesContent":["\"use client\";\n\nimport * as React from \"react\";\nimport { Card, CardContent, CardHeader, CardTitle } from \"../layout/card\";\nimport { Badge } from \"../primitives/badge\";\nimport { Skeleton } from \"../primitives/skeleton\";\nimport { TrendingUp, TrendingDown, Activity } from \"lucide-react\";\nimport { cn } from \"../utils\";\n\nexport interface KPICardProps {\n /**\n * Título do KPI (ex: \"Receita Mensal\"). Fica em uma linha (trunca com \"…\").\n */\n title: string;\n\n /**\n * Valor principal em destaque (ex: \"R$ 127.361,23\"). Fica em uma linha\n * (trunca com \"…\"; o valor completo aparece no `title` nativo ao passar o mouse).\n */\n primaryContent: string;\n\n /**\n * Texto secundário descritivo (ex: \"vs. mês anterior\"). Uma linha.\n */\n secondaryContent?: string;\n\n /**\n * Valor de tendência para exibir badge com seta\n * Positivo = verde + seta para cima\n * Negativo = vermelho + seta para baixo\n */\n trendValue?: number;\n\n /**\n * Label customizado para tendência (default: \"+X%\" ou \"-X%\")\n */\n trendLabel?: string;\n\n /**\n * Ícone a ser exibido no header (componente Lucide React)\n */\n icon?: React.ComponentType<{ className?: string }>;\n\n /**\n * Estado de loading - exibe skeleton com a mesma altura do estado final.\n */\n isLoading?: boolean;\n\n /**\n * Handler de click - torna o card clicável com hover\n */\n onClick?: () => void;\n\n /**\n * Classes CSS adicionais\n */\n className?: string;\n}\n\n/**\n * KPICard — card de métrica com título, valor em destaque, tendência e texto\n * secundário. O estado de `isLoading` reserva exatamente a mesma altura do\n * estado final (mesma árvore de layout, só troca o conteúdo por `Skeleton`),\n * então não há salto quando os dados chegam. Título, valor e texto secundário\n * ficam sempre em uma linha.\n */\nexport const KPICard = React.forwardRef<HTMLDivElement, KPICardProps>(\n (\n {\n title,\n primaryContent,\n secondaryContent,\n trendValue,\n trendLabel,\n icon: Icon = Activity,\n isLoading = false,\n onClick,\n className,\n },\n ref\n ) => {\n const clickable = !isLoading && !!onClick;\n\n return (\n <Card\n ref={ref}\n onClick={clickable ? onClick : undefined}\n className={cn(\n clickable && \"cursor-pointer hover:bg-accent/50 transition-colors\",\n className\n )}\n >\n <CardHeader className=\"pb-1\">\n <CardTitle className=\"flex items-center gap-2 text-sm text-muted-foreground\">\n {isLoading ? (\n <>\n <Skeleton className=\"size-4 shrink-0 rounded\" />\n <Skeleton className=\"h-4 w-24\" />\n </>\n ) : (\n <>\n <Icon className=\"size-4 shrink-0 text-muted-foreground\" />\n <span className=\"truncate\">{title}</span>\n </>\n )}\n </CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-1 pt-0\">\n <div className=\"flex items-baseline gap-2\">\n {isLoading ? (\n <Skeleton className=\"h-8 w-28\" />\n ) : (\n <span\n className=\"min-w-0 truncate text-2xl font-bold\"\n title={primaryContent}\n >\n {primaryContent}\n </span>\n )}\n {!isLoading && trendValue !== undefined && (\n <Badge\n variant=\"secondary\"\n className={cn(\n \"h-auto shrink-0 px-1.5 py-0 text-xs\",\n trendValue > 0 ? \"text-green-600\" : \"text-red-600\"\n )}\n >\n {trendValue > 0 ? (\n <TrendingUp className=\"mr-0.5 inline h-3 w-3\" />\n ) : (\n <TrendingDown className=\"mr-0.5 inline h-3 w-3\" />\n )}\n {trendLabel}\n </Badge>\n )}\n </div>\n <div className=\"min-h-4 text-xs text-muted-foreground\">\n {isLoading ? (\n <Skeleton className=\"h-3 w-full max-w-40\" />\n ) : (\n secondaryContent && (\n <span className=\"block truncate\">{secondaryContent}</span>\n )\n )}\n </div>\n </CardContent>\n </Card>\n );\n }\n);\n\nKPICard.displayName = \"KPICard\";\n"],"names":["KPICard","React","title","primaryContent","secondaryContent","trendValue","trendLabel","Icon","Activity","isLoading","onClick","className","ref","clickable","jsxs","Card","cn","jsx","CardHeader","CardTitle","Fragment","Skeleton","CardContent","Badge","TrendingUp","TrendingDown"],"mappings":"glBAkEaA,EAAUC,EAAM,WAC3B,CACE,CACE,MAAAC,EACA,eAAAC,EACA,iBAAAC,EACA,WAAAC,EACA,WAAAC,EACA,KAAMC,EAAOC,EAAAA,SACb,UAAAC,EAAY,GACZ,QAAAC,EACA,UAAAC,CAAA,EAEFC,IACG,CACH,MAAMC,EAAY,CAACJ,GAAa,CAAC,CAACC,EAElC,OACEI,EAAAA,KAACC,EAAAA,KAAA,CACC,IAAAH,EACA,QAASC,EAAYH,EAAU,OAC/B,UAAWM,EAAAA,GACTH,GAAa,sDACbF,CAAA,EAGF,SAAA,CAAAM,EAAAA,IAACC,EAAAA,WAAA,CAAW,UAAU,OACpB,SAAAD,EAAAA,IAACE,EAAAA,WAAU,UAAU,wDAClB,WACCL,EAAAA,KAAAM,EAAAA,SAAA,CACE,SAAA,CAAAH,EAAAA,IAACI,EAAAA,SAAA,CAAS,UAAU,yBAAA,CAA0B,EAC9CJ,EAAAA,IAACI,EAAAA,SAAA,CAAS,UAAU,UAAA,CAAW,CAAA,CAAA,CACjC,EAEAP,EAAAA,KAAAM,EAAAA,SAAA,CACE,SAAA,CAAAH,EAAAA,IAACV,EAAA,CAAK,UAAU,uCAAA,CAAwC,EACxDU,EAAAA,IAAC,OAAA,CAAK,UAAU,WAAY,SAAAf,CAAA,CAAM,CAAA,CAAA,CACpC,EAEJ,EACF,EACAY,EAAAA,KAACQ,EAAAA,YAAA,CAAY,UAAU,iBACrB,SAAA,CAAAR,EAAAA,KAAC,MAAA,CAAI,UAAU,4BACZ,SAAA,CAAAL,EACCQ,EAAAA,IAACI,EAAAA,SAAA,CAAS,UAAU,UAAA,CAAW,EAE/BJ,EAAAA,IAAC,OAAA,CACC,UAAU,sCACV,MAAOd,EAEN,SAAAA,CAAA,CAAA,EAGJ,CAACM,GAAaJ,IAAe,QAC5BS,EAAAA,KAACS,EAAAA,MAAA,CACC,QAAQ,YACR,UAAWP,EAAAA,GACT,sCACAX,EAAa,EAAI,iBAAmB,cAAA,EAGrC,SAAA,CAAAA,EAAa,QACXmB,EAAAA,WAAA,CAAW,UAAU,wBAAwB,EAE9CP,EAAAA,IAACQ,EAAAA,aAAA,CAAa,UAAU,uBAAA,CAAwB,EAEjDnB,CAAA,CAAA,CAAA,CACH,EAEJ,QACC,MAAA,CAAI,UAAU,wCACZ,SAAAG,QACEY,EAAAA,SAAA,CAAS,UAAU,qBAAA,CAAsB,EAE1CjB,GACEa,EAAAA,IAAC,OAAA,CAAK,UAAU,iBAAkB,WAAiB,CAAA,CAGzD,CAAA,CAAA,CACF,CAAA,CAAA,CAAA,CAGN,CACF,EAEAjB,EAAQ,YAAc"}
1
+ {"version":3,"file":"kpi-card.cjs","sources":["../../../../src/components/ui/charts/kpi-card.tsx"],"sourcesContent":["\"use client\";\n\nimport * as React from \"react\";\nimport { Card, CardContent, CardHeader, CardTitle } from \"../layout/card\";\nimport { Badge } from \"../primitives/badge\";\nimport { Skeleton } from \"../primitives/skeleton\";\nimport { TrendingUp, TrendingDown, Activity } from \"lucide-react\";\nimport { cn } from \"../utils\";\n\nexport interface KPICardProps {\n /**\n * Título do KPI (ex: \"Receita Mensal\"). Fica em uma linha (trunca com \"…\").\n */\n title: string;\n\n /**\n * Valor principal em destaque (ex: \"R$ 127.361,23\"). Fica em uma linha\n * (trunca com \"…\"; o valor completo aparece no `title` nativo ao passar o mouse).\n */\n primaryContent: string;\n\n /**\n * Texto secundário descritivo (ex: \"vs. mês anterior\"). Uma linha.\n */\n secondaryContent?: string;\n\n /**\n * Valor de tendência para exibir badge com seta\n * Positivo = verde + seta para cima\n * Negativo = vermelho + seta para baixo\n */\n trendValue?: number;\n\n /**\n * Label customizado para tendência (default: \"+X%\" ou \"-X%\")\n */\n trendLabel?: string;\n\n /**\n * Ícone a ser exibido no header (componente Lucide React)\n */\n icon?: React.ComponentType<{ className?: string }>;\n\n /**\n * Estado de loading - exibe skeleton com a mesma altura do estado final.\n */\n isLoading?: boolean;\n\n /**\n * Handler de click - torna o card clicável com hover\n */\n onClick?: () => void;\n\n /**\n * Classes CSS adicionais\n */\n className?: string;\n}\n\n/**\n * KPICard — card de métrica com título, valor em destaque, tendência e texto\n * secundário. O estado de `isLoading` reserva exatamente a mesma altura do\n * estado final (mesma árvore de layout, só troca o conteúdo por `Skeleton`),\n * então não há salto quando os dados chegam. Título, valor e texto secundário\n * ficam sempre em uma linha.\n */\nexport const KPICard = React.forwardRef<HTMLDivElement, KPICardProps>(\n (\n {\n title,\n primaryContent,\n secondaryContent,\n trendValue,\n trendLabel,\n icon: Icon = Activity,\n isLoading = false,\n onClick,\n className,\n },\n ref\n ) => {\n const clickable = !isLoading && !!onClick;\n\n return (\n <Card\n ref={ref}\n onClick={clickable ? onClick : undefined}\n className={cn(\n clickable && \"cursor-pointer hover:bg-accent/50 transition-colors\",\n className\n )}\n >\n <CardHeader className=\"pb-1\">\n <CardTitle className=\"flex items-center gap-2 text-sm text-muted-foreground\">\n {isLoading ? (\n <>\n <Skeleton className=\"size-4 shrink-0 rounded\" />\n <Skeleton className=\"h-4 w-24\" />\n </>\n ) : (\n <>\n <Icon className=\"size-4 shrink-0 text-muted-foreground\" />\n <span className=\"truncate\">{title}</span>\n </>\n )}\n </CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-1 pt-0\">\n <div className=\"flex items-baseline gap-2\">\n {isLoading ? (\n <Skeleton className=\"h-8 w-28\" />\n ) : (\n <span\n className=\"min-w-0 truncate text-2xl font-bold\"\n title={primaryContent}\n >\n {primaryContent}\n </span>\n )}\n {!isLoading && trendValue !== undefined && (\n <Badge\n variant=\"secondary\"\n className={cn(\n \"h-auto shrink-0 px-1.5 py-0 text-xs\",\n trendValue > 0 ? \"text-success-emphasis\" : \"text-destructive-emphasis\"\n )}\n >\n {trendValue > 0 ? (\n <TrendingUp className=\"mr-0.5 inline h-3 w-3\" />\n ) : (\n <TrendingDown className=\"mr-0.5 inline h-3 w-3\" />\n )}\n {trendLabel}\n </Badge>\n )}\n </div>\n <div className=\"min-h-4 text-xs text-muted-foreground\">\n {isLoading ? (\n <Skeleton className=\"h-3 w-full max-w-40\" />\n ) : (\n secondaryContent && (\n <span className=\"block truncate\">{secondaryContent}</span>\n )\n )}\n </div>\n </CardContent>\n </Card>\n );\n }\n);\n\nKPICard.displayName = \"KPICard\";\n"],"names":["KPICard","React","title","primaryContent","secondaryContent","trendValue","trendLabel","Icon","Activity","isLoading","onClick","className","ref","clickable","jsxs","Card","cn","jsx","CardHeader","CardTitle","Fragment","Skeleton","CardContent","Badge","TrendingUp","TrendingDown"],"mappings":"glBAkEaA,EAAUC,EAAM,WAC3B,CACE,CACE,MAAAC,EACA,eAAAC,EACA,iBAAAC,EACA,WAAAC,EACA,WAAAC,EACA,KAAMC,EAAOC,EAAAA,SACb,UAAAC,EAAY,GACZ,QAAAC,EACA,UAAAC,CAAA,EAEFC,IACG,CACH,MAAMC,EAAY,CAACJ,GAAa,CAAC,CAACC,EAElC,OACEI,EAAAA,KAACC,EAAAA,KAAA,CACC,IAAAH,EACA,QAASC,EAAYH,EAAU,OAC/B,UAAWM,EAAAA,GACTH,GAAa,sDACbF,CAAA,EAGF,SAAA,CAAAM,EAAAA,IAACC,EAAAA,WAAA,CAAW,UAAU,OACpB,SAAAD,EAAAA,IAACE,EAAAA,WAAU,UAAU,wDAClB,WACCL,EAAAA,KAAAM,EAAAA,SAAA,CACE,SAAA,CAAAH,EAAAA,IAACI,EAAAA,SAAA,CAAS,UAAU,yBAAA,CAA0B,EAC9CJ,EAAAA,IAACI,EAAAA,SAAA,CAAS,UAAU,UAAA,CAAW,CAAA,CAAA,CACjC,EAEAP,EAAAA,KAAAM,EAAAA,SAAA,CACE,SAAA,CAAAH,EAAAA,IAACV,EAAA,CAAK,UAAU,uCAAA,CAAwC,EACxDU,EAAAA,IAAC,OAAA,CAAK,UAAU,WAAY,SAAAf,CAAA,CAAM,CAAA,CAAA,CACpC,EAEJ,EACF,EACAY,EAAAA,KAACQ,EAAAA,YAAA,CAAY,UAAU,iBACrB,SAAA,CAAAR,EAAAA,KAAC,MAAA,CAAI,UAAU,4BACZ,SAAA,CAAAL,EACCQ,EAAAA,IAACI,EAAAA,SAAA,CAAS,UAAU,UAAA,CAAW,EAE/BJ,EAAAA,IAAC,OAAA,CACC,UAAU,sCACV,MAAOd,EAEN,SAAAA,CAAA,CAAA,EAGJ,CAACM,GAAaJ,IAAe,QAC5BS,EAAAA,KAACS,EAAAA,MAAA,CACC,QAAQ,YACR,UAAWP,EAAAA,GACT,sCACAX,EAAa,EAAI,wBAA0B,2BAAA,EAG5C,SAAA,CAAAA,EAAa,QACXmB,EAAAA,WAAA,CAAW,UAAU,wBAAwB,EAE9CP,EAAAA,IAACQ,EAAAA,aAAA,CAAa,UAAU,uBAAA,CAAwB,EAEjDnB,CAAA,CAAA,CAAA,CACH,EAEJ,QACC,MAAA,CAAI,UAAU,wCACZ,SAAAG,QACEY,EAAAA,SAAA,CAAS,UAAU,qBAAA,CAAsB,EAE1CjB,GACEa,EAAAA,IAAC,OAAA,CAAK,UAAU,iBAAkB,WAAiB,CAAA,CAGzD,CAAA,CAAA,CACF,CAAA,CAAA,CAAA,CAGN,CACF,EAEAjB,EAAQ,YAAc"}
@@ -1,9 +1,9 @@
1
1
  "use client";
2
- import { jsxs as r, jsx as e, Fragment as i } from "react/jsx-runtime";
2
+ import { jsxs as s, jsx as e, Fragment as n } from "react/jsx-runtime";
3
3
  import * as f from "react";
4
- import { Card as u, CardHeader as w, CardTitle as g, CardContent as v } from "../layout/card.js";
5
- import { Badge as b } from "../primitives/badge.js";
6
- import { Skeleton as s } from "../primitives/skeleton.js";
4
+ import { Card as u, CardHeader as w, CardTitle as v, CardContent as b } from "../layout/card.js";
5
+ import { Badge as g } from "../primitives/badge.js";
6
+ import { Skeleton as r } from "../primitives/skeleton.js";
7
7
  import { Activity as k, TrendingUp as C, TrendingDown as y } from "lucide-react";
8
8
  import { cn as o } from "../utils.js";
9
9
  const T = f.forwardRef(
@@ -15,30 +15,30 @@ const T = f.forwardRef(
15
15
  trendLabel: h,
16
16
  icon: p = k,
17
17
  isLoading: a = !1,
18
- onClick: n,
18
+ onClick: i,
19
19
  className: x
20
20
  }, N) => {
21
- const m = !a && !!n;
22
- return /* @__PURE__ */ r(
21
+ const m = !a && !!i;
22
+ return /* @__PURE__ */ s(
23
23
  u,
24
24
  {
25
25
  ref: N,
26
- onClick: m ? n : void 0,
26
+ onClick: m ? i : void 0,
27
27
  className: o(
28
28
  m && "cursor-pointer hover:bg-accent/50 transition-colors",
29
29
  x
30
30
  ),
31
31
  children: [
32
- /* @__PURE__ */ e(w, { className: "pb-1", children: /* @__PURE__ */ e(g, { className: "flex items-center gap-2 text-sm text-muted-foreground", children: a ? /* @__PURE__ */ r(i, { children: [
33
- /* @__PURE__ */ e(s, { className: "size-4 shrink-0 rounded" }),
34
- /* @__PURE__ */ e(s, { className: "h-4 w-24" })
35
- ] }) : /* @__PURE__ */ r(i, { children: [
32
+ /* @__PURE__ */ e(w, { className: "pb-1", children: /* @__PURE__ */ e(v, { className: "flex items-center gap-2 text-sm text-muted-foreground", children: a ? /* @__PURE__ */ s(n, { children: [
33
+ /* @__PURE__ */ e(r, { className: "size-4 shrink-0 rounded" }),
34
+ /* @__PURE__ */ e(r, { className: "h-4 w-24" })
35
+ ] }) : /* @__PURE__ */ s(n, { children: [
36
36
  /* @__PURE__ */ e(p, { className: "size-4 shrink-0 text-muted-foreground" }),
37
37
  /* @__PURE__ */ e("span", { className: "truncate", children: d })
38
38
  ] }) }) }),
39
- /* @__PURE__ */ r(v, { className: "space-y-1 pt-0", children: [
40
- /* @__PURE__ */ r("div", { className: "flex items-baseline gap-2", children: [
41
- a ? /* @__PURE__ */ e(s, { className: "h-8 w-28" }) : /* @__PURE__ */ e(
39
+ /* @__PURE__ */ s(b, { className: "space-y-1 pt-0", children: [
40
+ /* @__PURE__ */ s("div", { className: "flex items-baseline gap-2", children: [
41
+ a ? /* @__PURE__ */ e(r, { className: "h-8 w-28" }) : /* @__PURE__ */ e(
42
42
  "span",
43
43
  {
44
44
  className: "min-w-0 truncate text-2xl font-bold",
@@ -46,13 +46,13 @@ const T = f.forwardRef(
46
46
  children: c
47
47
  }
48
48
  ),
49
- !a && t !== void 0 && /* @__PURE__ */ r(
50
- b,
49
+ !a && t !== void 0 && /* @__PURE__ */ s(
50
+ g,
51
51
  {
52
52
  variant: "secondary",
53
53
  className: o(
54
54
  "h-auto shrink-0 px-1.5 py-0 text-xs",
55
- t > 0 ? "text-green-600" : "text-red-600"
55
+ t > 0 ? "text-success-emphasis" : "text-destructive-emphasis"
56
56
  ),
57
57
  children: [
58
58
  t > 0 ? /* @__PURE__ */ e(C, { className: "mr-0.5 inline h-3 w-3" }) : /* @__PURE__ */ e(y, { className: "mr-0.5 inline h-3 w-3" }),
@@ -61,7 +61,7 @@ const T = f.forwardRef(
61
61
  }
62
62
  )
63
63
  ] }),
64
- /* @__PURE__ */ e("div", { className: "min-h-4 text-xs text-muted-foreground", children: a ? /* @__PURE__ */ e(s, { className: "h-3 w-full max-w-40" }) : l && /* @__PURE__ */ e("span", { className: "block truncate", children: l }) })
64
+ /* @__PURE__ */ e("div", { className: "min-h-4 text-xs text-muted-foreground", children: a ? /* @__PURE__ */ e(r, { className: "h-3 w-full max-w-40" }) : l && /* @__PURE__ */ e("span", { className: "block truncate", children: l }) })
65
65
  ] })
66
66
  ]
67
67
  }