--- name: month_heatmap kind: component lang: ts domain: ui version: "1.0.0" framework: react purity: pure signature: "MonthHeatmap(props: MonthHeatmapProps): JSX.Element" description: "Grid mensual de calor (heatmap) con inicio en lunes. Renderiza 7 columnas con header de dias de semana y celdas que muestran numero del dia, hasta dos contadores con icono, borde azul para hoy y fondo tintado segun valores primary/secondary." tags: [calendar, heatmap, grid, month, ui, mantine] uses_functions: [month_grid_ts_core] uses_types: [] returns: [] returns_optional: false error_type: "" imports: - "@mantine/core" - "@tabler/icons-react" - "../core/month_grid" tested: false tests: [] test_file_path: "" props: - name: month type: "Date" required: true description: "Mes a mostrar. Se usan getFullYear() y getMonth(). El dia se ignora." - name: cells type: "Map" required: true description: "Datos por dia. Clave YYYY-MM-DD. Valores: primary (contador azulado) y secondary (contador verdoso)." - name: primaryIcon type: "ReactNode" required: false description: "Icono junto al contador primary. Default: IconPlus de @tabler/icons-react." - name: secondaryIcon type: "ReactNode" required: false description: "Icono junto al contador secondary. Default: IconCheckbox de @tabler/icons-react." - name: primaryColor type: "string" required: false description: "Color Mantine del contador primary. Default: 'blue'." - name: secondaryColor type: "string" required: false description: "Color Mantine del contador secondary. Default: 'green'." - name: dayLabels type: "string[]" required: false description: "Array de 7 strings para el header de columnas, empezando por lunes. Default: ['Lun','Mar','Mie','Jue','Vie','Sab','Dom']." - name: cellMinHeight type: "number" required: false description: "Altura minima de cada celda en px. Default: 72." emits: [] has_state: false params: - name: month desc: "Mes a renderizar como objeto Date (year + month extraidos con getFullYear/getMonth)." - name: cells desc: "Map de YYYY-MM-DD a { primary?, secondary? } con los contadores de cada dia." - name: primaryIcon desc: "ReactNode opcional para el icono del contador primary (creado, pendiente, etc.)." - name: secondaryIcon desc: "ReactNode opcional para el icono del contador secondary (completado, resuelto, etc.)." - name: primaryColor desc: "Nombre de color Mantine para el contador primary y su tinte de fondo (rgba 6%)." - name: secondaryColor desc: "Nombre de color Mantine para el contador secondary y su tinte de fondo (rgba 8%)." - name: dayLabels desc: "Labels del header de dias de semana, 7 elementos, orden lunes-domingo." - name: cellMinHeight desc: "Altura minima en px de cada celda del grid." output: "Componente React que renderiza un grid de 7 columnas con el calendario del mes indicado. Celdas de relleno vacias, celdas del mes con numero, contadores opcionales e iconos, borde azul en el dia de hoy y fondo tintado segun presencia de valores." file_path: "frontend/functions/ui/month_heatmap.tsx" --- ## Ejemplo ```tsx import { MonthHeatmap, type MonthHeatmapCell } from "@fn_library/ui/month_heatmap"; const cells = new Map([ ["2026-05-01", { primary: 3 }], ["2026-05-09", { primary: 1, secondary: 2 }], ["2026-05-15", { secondary: 4 }], ]); ``` ## Ejemplo con iconos y colores custom ```tsx import { IconBug, IconCheck } from "@tabler/icons-react"; } secondaryIcon={} primaryColor="red" secondaryColor="teal" cellMinHeight={88} /> ``` ## Notas Componente puro (sin estado propio, sin efectos). El calculo del grid se delega a `month_grid_ts_core` (`monthGrid(year, month)`), que genera un array de celdas de longitud multiplo de 7 con `date: null` para el padding. La deteccion de "hoy" usa `Date` nativo sin dayjs para no introducir dependencias. El fondo tintado prioriza `secondary` sobre `primary` cuando ambos son > 0, replicando la logica del componente original en `apps/kanban`. Compatible con Mantine v9. No usa CSS variables custom — emplea props de Mantine (`c`, `fw`, `p`, `gap`, `radius`) y solo dos `style` inline para `minHeight` y `borderColor` condicional (que no tienen equivalente en props Mantine).