@sfperusacdev/sf-ui 0.1.33 → 0.1.35

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 (67) hide show
  1. package/dist/sf-ui.css +1 -1
  2. package/dist/sf-ui.js +2885 -2024
  3. package/dist/sf-ui.js.map +1 -1
  4. package/dist/sf-ui.umd.cjs +7 -7
  5. package/dist/sf-ui.umd.cjs.map +1 -1
  6. package/dist/theme/sf-tokens.css +1 -0
  7. package/dist/types/src/components/cards/KPICard.d.ts +44 -1
  8. package/dist/types/src/components/cards/MetricBar.test.d.ts +1 -0
  9. package/dist/types/src/components/cards/SplitBar.d.ts +17 -0
  10. package/dist/types/src/components/cards/SplitBar.test.d.ts +1 -0
  11. package/dist/types/src/components/cards/index.d.ts +4 -2
  12. package/dist/types/src/components/cards/types.d.ts +36 -0
  13. package/dist/types/src/components/charts/Chart.d.ts +1 -1
  14. package/dist/types/src/components/charts/Chart.test.d.ts +1 -0
  15. package/dist/types/src/components/charts/DeviationBand.d.ts +7 -0
  16. package/dist/types/src/components/charts/DeviationBand.test.d.ts +1 -0
  17. package/dist/types/src/components/charts/DiagnosticRadar.d.ts +12 -0
  18. package/dist/types/src/components/charts/DiagnosticRadar.test.d.ts +1 -0
  19. package/dist/types/src/components/charts/Sparkline.d.ts +1 -1
  20. package/dist/types/src/components/charts/Sparkline.test.d.ts +1 -0
  21. package/dist/types/src/components/charts/chartUtils.d.ts +16 -0
  22. package/dist/types/src/components/charts/chartUtils.test.d.ts +1 -0
  23. package/dist/types/src/components/charts/index.d.ts +4 -2
  24. package/dist/types/src/components/charts/types.d.ts +95 -0
  25. package/dist/types/src/components/dashboard/AlertSummaryList.d.ts +31 -0
  26. package/dist/types/src/components/dashboard/AlertSummaryList.test.d.ts +1 -0
  27. package/dist/types/src/components/dashboard/ComparisonTable.d.ts +24 -0
  28. package/dist/types/src/components/dashboard/ComparisonTable.test.d.ts +1 -0
  29. package/dist/types/src/components/dashboard/DashboardCard.d.ts +31 -4
  30. package/dist/types/src/components/dashboard/DashboardCard.test.d.ts +1 -0
  31. package/dist/types/src/components/dashboard/DetailSection.d.ts +26 -0
  32. package/dist/types/src/components/dashboard/DetailSection.test.d.ts +1 -0
  33. package/dist/types/src/components/dashboard/EventLog.d.ts +6 -2
  34. package/dist/types/src/components/dashboard/EvidenceFootnote.d.ts +19 -0
  35. package/dist/types/src/components/dashboard/EvidenceFootnote.test.d.ts +1 -0
  36. package/dist/types/src/components/dashboard/StatCard.d.ts +5 -1
  37. package/dist/types/src/components/dashboard/StatCard.test.d.ts +1 -0
  38. package/dist/types/src/components/dashboard/Stepper.test.d.ts +1 -0
  39. package/dist/types/src/components/dashboard/index.d.ts +10 -1
  40. package/dist/types/src/components/dashboard/types.d.ts +22 -1
  41. package/dist/types/src/components/display/MediaPanel.d.ts +29 -0
  42. package/dist/types/src/components/display/MediaPanel.test.d.ts +1 -0
  43. package/dist/types/src/components/display/index.d.ts +2 -0
  44. package/dist/types/src/components/feedback/Alert.actions.test.d.ts +1 -0
  45. package/dist/types/src/components/feedback/Alert.d.ts +8 -1
  46. package/dist/types/src/components/feedback/index.d.ts +1 -1
  47. package/dist/types/src/components/inputs/AsyncSearchTableSelect.d.ts +8 -1
  48. package/dist/types/src/components/inputs/Input.d.ts +7 -1
  49. package/dist/types/src/components/inputs/Input.test.d.ts +1 -0
  50. package/dist/types/src/components/inputs/SearchTableSelect.d.ts +16 -1
  51. package/dist/types/src/components/inputs/SearchTableSelect.test.d.ts +1 -0
  52. package/dist/types/src/components/inputs/index.d.ts +1 -0
  53. package/dist/types/src/components/interactive-inputs/AllocationBar.d.ts +25 -0
  54. package/dist/types/src/components/interactive-inputs/AllocationBar.test.d.ts +1 -0
  55. package/dist/types/src/components/interactive-inputs/CardRadioGroup.d.ts +5 -0
  56. package/dist/types/src/components/interactive-inputs/CardRadioGroup.test.d.ts +1 -0
  57. package/dist/types/src/components/interactive-inputs/SemanticSlider.d.ts +21 -0
  58. package/dist/types/src/components/interactive-inputs/SemanticSlider.test.d.ts +1 -0
  59. package/dist/types/src/components/interactive-inputs/TemporalScrub.d.ts +29 -0
  60. package/dist/types/src/components/interactive-inputs/TemporalScrub.test.d.ts +1 -0
  61. package/dist/types/src/components/interactive-inputs/index.d.ts +6 -0
  62. package/dist/types/src/components/layout/PageHeader.d.ts +7 -3
  63. package/dist/types/src/components/layout/PageHeader.test.d.ts +1 -0
  64. package/dist/types/src/components/layout/index.d.ts +1 -0
  65. package/dist/types/src/components/table/EditableDataGrid.cellTone.test.d.ts +1 -0
  66. package/dist/types/src/components/table/EditableDataGrid.d.ts +6 -0
  67. package/package.json +1 -1
@@ -451,6 +451,7 @@
451
451
  --sf-chart-tooltip-bg: var(--sf-card-bg);
452
452
  --sf-chart-tooltip-border: var(--sf-card-border);
453
453
  --sf-chart-tooltip-text: var(--sf-text);
454
+ --sf-chart-reference: var(--sf-text-subtle);
454
455
 
455
456
  /* Network map (Fase 13 / 25) */
456
457
  --sf-network-panel-bg: rgb(255 255 255 / 0.95);
@@ -1,14 +1,41 @@
1
1
  import { ReactNode } from 'react';
2
+ import { ChartDataPoint } from '../charts/types';
2
3
  export type KPICardAccentTone = "emerald" | "blue" | "amber" | "red" | "teal" | "slate";
3
4
  export type KPICardLayout = "stacked" | "leading-icon";
5
+ export type KPICardVariant = "default" | "filled";
4
6
  /** Acabado del tile de icono en `layout="leading-icon"`: "solid" (por defecto) = fondo sólido del tono con
5
7
  * glifo blanco; "soft" = fondo tenue del tono (color-mix 14 % sobre --sf-surface) y glifo del color del tono. */
6
8
  export type KPICardIconStyle = "solid" | "soft";
9
+ /** Tamaño general de la tarjeta (padding + tipografía del valor). "md" (por defecto) = acabado actual. */
10
+ export type KPICardSize = "sm" | "md" | "lg";
11
+ /** Densidad de los espacios internos entre label/valor/sublabel. "comfortable" (por defecto) = acabado
12
+ * actual. "compact" reduce los márgenes verticales, para tableros con muchas tarjetas por fila. */
13
+ export type KPICardDensity = "comfortable" | "compact";
14
+ /** Sentido en que se interpreta `trend` para decidir el color (no cambia la flecha, que siempre refleja
15
+ * el signo real): "up-good" (por defecto, acabado actual) = positivo es verde; "down-good" = negativo es
16
+ * verde (ej. "tiempo de atención", "incidentes"); "neutral" = siempre color neutro, sin connotación. */
17
+ export type KPICardTrendDirection = "up-good" | "down-good" | "neutral";
18
+ export type KPICardValueFormat = "number" | "currency" | "percent";
19
+ export type KPICardFormatOptions = {
20
+ /** Por defecto "es-PE". */
21
+ locale?: string;
22
+ /** Solo aplica a `valueFormat="currency"`. Por defecto "PEN". */
23
+ currency?: string;
24
+ /** Máximo de decimales. Por defecto 0. */
25
+ decimals?: number;
26
+ /** Notación compacta para valores grandes (1.2K, 3.4M). Por defecto `false`. */
27
+ compact?: boolean;
28
+ };
7
29
  export type KPICardProgress = {
8
30
  value: number;
9
31
  max: number;
10
32
  label?: string;
11
33
  };
34
+ export type KPICardSparkline = {
35
+ data: ChartDataPoint[];
36
+ dataKey: string;
37
+ color?: string;
38
+ };
12
39
  export type KPICardProps = {
13
40
  label: string;
14
41
  value: string | number;
@@ -17,11 +44,27 @@ export type KPICardProps = {
17
44
  iconClassName?: string;
18
45
  trend?: number;
19
46
  trendLabel?: string;
47
+ /** Ver `KPICardTrendDirection`. Por defecto "up-good" (acabado actual). */
48
+ trendDirection?: KPICardTrendDirection;
20
49
  accentTone?: KPICardAccentTone;
21
50
  progress?: KPICardProgress;
51
+ /** Formato del `value` cuando es numérico. Puede ser uno de los presets o una función propia
52
+ * `(value: number) => string`. Si `value` es un string, se ignora (se muestra tal cual, como hoy). */
53
+ valueFormat?: KPICardValueFormat | ((value: number) => string);
54
+ formatOptions?: KPICardFormatOptions;
55
+ /** Minigráfico opcional debajo del valor (reutiliza `Sparkline`). Se ignora si hay `progress`
56
+ * (ambos compiten por el mismo espacio; `progress` tiene prioridad porque ya existía). */
57
+ sparkline?: KPICardSparkline;
22
58
  /** Disposición visual. "stacked" (por defecto) reproduce el acabado actual; "leading-icon" pone el icono a la
23
59
  * izquierda en un tile de color sólido con label/valor en columna, como en el mockup de Torre de control. */
24
60
  layout?: KPICardLayout;
61
+ /** "default" (por defecto) = tarjeta blanca normal; "filled" = fondo sólido `--sf-primary` con texto
62
+ * blanco (tarjeta destacada, ej. KPI principal del tablero). Ignora `accentBar`/`accentTone`. */
63
+ variant?: KPICardVariant;
64
+ /** Tamaño de la tarjeta. Por defecto "md" (acabado actual). */
65
+ size?: KPICardSize;
66
+ /** Densidad de los espacios internos. Por defecto "comfortable" (acabado actual). */
67
+ density?: KPICardDensity;
25
68
  /** Controla el borde superior de 3px (.sf-kpi-card). Por defecto true en "stacked" (como hoy) y false en
26
69
  * "leading-icon" (el mockup no lo tiene). */
27
70
  accentBar?: boolean;
@@ -34,7 +77,7 @@ export type KPICardProps = {
34
77
  className?: string;
35
78
  onClick?: () => void;
36
79
  };
37
- export declare const KPICard: ({ label, value, sublabel, icon, iconClassName, trend, trendLabel, accentTone, progress, layout, accentBar, iconStyle, labelWrap, className, onClick, }: KPICardProps) => import("react").JSX.Element;
80
+ export declare const KPICard: ({ label, value, sublabel, icon, iconClassName, trend, trendLabel, trendDirection, accentTone, progress, valueFormat, formatOptions, sparkline, layout, variant, size, density, accentBar, iconStyle, labelWrap, className, onClick, }: KPICardProps) => import("react").JSX.Element;
38
81
  type KPIGridProps = {
39
82
  children: ReactNode;
40
83
  cols?: 2 | 3 | 4 | 5;
@@ -0,0 +1,17 @@
1
+ import { SplitBarSegment } from './types';
2
+ export type SplitBarSize = "sm" | "md";
3
+ type SplitBarProps = {
4
+ /** 2 o más segmentos: la barra se reparte proporcional a `value` entre todos. Con exactamente 2
5
+ * (el caso de siempre, ej. sexo M/F), el render es idéntico al de antes. */
6
+ segments: SplitBarSegment[];
7
+ /** Grosor de la barra. "md" (por defecto) = 1.5rem, como KPI destacado. "sm" = 0.625rem, para
8
+ * usos más compactos (ej. dentro de una fila junto a otros elementos). */
9
+ size?: SplitBarSize;
10
+ className?: string;
11
+ };
12
+ /**
13
+ * Una sola barra dividida en 2+ segmentos proporcionales (ej. sexo M/F, o una distribución con más
14
+ * categorías), con labels debajo. Distinto de `MetricBarList`, que apila una barra por fila.
15
+ */
16
+ export declare const SplitBar: ({ segments, size, className }: SplitBarProps) => import("react").JSX.Element;
17
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -2,7 +2,9 @@ export { Badge } from './Badge';
2
2
  export type { BadgeProps } from './Badge';
3
3
  export { badgeClassName, badgeDotClassName } from './badgeClassName';
4
4
  export { KPICard, KPIGrid } from './KPICard';
5
- export type { KPICardAccentTone, KPICardProgress, KPICardLayout, KPICardIconStyle, KPICardProps } from './KPICard';
5
+ export type { KPICardAccentTone, KPICardProgress, KPICardLayout, KPICardVariant, KPICardIconStyle, KPICardSize, KPICardDensity, KPICardTrendDirection, KPICardValueFormat, KPICardFormatOptions, KPICardSparkline, KPICardProps, } from './KPICard';
6
+ export { SplitBar } from './SplitBar';
7
+ export type { SplitBarSize } from './SplitBar';
6
8
  export { QuickActionTile, QuickActionGrid } from './QuickActionTile';
7
9
  export type { QuickActionTileProps, QuickActionGridProps } from './QuickActionTile';
8
10
  export { MetricBarRow, MetricBarList } from './MetricBar';
@@ -12,4 +14,4 @@ export { RecommendationCard } from './RecommendationCard';
12
14
  export type { RecommendationCardProps } from './RecommendationCard';
13
15
  export { ModuleCard, ModuleCardGrid } from './ModuleCard';
14
16
  export type { ModuleCardProps } from './ModuleCard';
15
- export type { BadgeVariant, BadgeSize, BadgeShape, MetricBarTone, MetricBarItem, EntityCardStatus, EntityCardVariant, RecommendationPriority, RecommendationImpact, ModuleCardVariant, ModuleCardDensity, } from './types';
17
+ export type { BadgeVariant, BadgeSize, BadgeShape, MetricBarTone, MetricBarThresholds, MetricBarItem, SplitBarTone, SplitBarSegment, EntityCardStatus, EntityCardVariant, RecommendationPriority, RecommendationImpact, ModuleCardVariant, ModuleCardDensity, } from './types';
@@ -2,11 +2,47 @@ export type BadgeVariant = "neutral" | "primary" | "success" | "warning" | "dang
2
2
  export type BadgeSize = "sm" | "md";
3
3
  export type BadgeShape = "pill" | "circle";
4
4
  export type MetricBarTone = "slate" | "emerald" | "amber" | "red" | "blue";
5
+ export type MetricBarThresholds = {
6
+ /** A partir de este valor (inclusive) la barra pasa a tono ámbar (o esmeralda si `inverse`). */
7
+ warning: number;
8
+ /** A partir de este valor (inclusive) la barra pasa a tono rojo (o esmeralda si `inverse`). */
9
+ critical: number;
10
+ };
5
11
  export type MetricBarItem = {
6
12
  label: string;
13
+ /** Sin `max`: valor ya expresado 0-100, como hoy (compatibilidad total con el uso actual).
14
+ * Con `max`: valor crudo en la escala de `max` — el ancho de la barra se calcula como `value/max*100`. */
7
15
  value: number;
16
+ /** Escala del valor. Si se omite, `value` se interpreta como ya siendo 0-100 (comportamiento actual,
17
+ * sin cambios). Si se define, habilita mostrar valor/máximo reales y calcular `target` en la misma escala. */
18
+ max?: number;
19
+ /** Meta independiente de `max` (ej. objetivo del mes vs. el máximo posible del período). Se dibuja como
20
+ * un marcador vertical sobre la barra en `target/(max ?? 100)`. No participa en el ancho de la barra. */
21
+ target?: number;
22
+ /** Muestra el marcador de `target`. Por defecto `true` si `target` está definido. Permite pasar `target`
23
+ * solo para cálculos propios (ej. en `valueFormat`) sin dibujar el marcador. */
24
+ showTargetMarker?: boolean;
8
25
  tone?: MetricBarTone;
26
+ /** Colorea automáticamente la barra según el PORCENTAJE resultante (0-100, tras aplicar `max` si lo
27
+ * hay) comparado con estos umbrales — igual criterio que `DonutGauge`. Se ignora si `tone` viene
28
+ * explícito (`tone` siempre gana). */
29
+ thresholds?: MetricBarThresholds;
9
30
  inverse?: boolean;
31
+ /** Unidad que se anexa al texto autogenerado del lado derecho (ej. "kg", "pts"). No aplica si
32
+ * `valueLabel` viene explícito — ese texto ya es responsabilidad de quien lo arma. */
33
+ unit?: string;
34
+ /** Formatea el texto del lado derecho a partir del valor crudo y `max`. Se ignora si `valueLabel`
35
+ * viene explícito (`valueLabel` siempre gana, mismo criterio que hoy). */
36
+ valueFormat?: (value: number, max?: number) => string;
37
+ /** Texto a mostrar a la derecha en vez del autogenerado (ej. un conteo real: "442"). NUNCA es lo que
38
+ * dimensiona la barra — eso siempre es `value` (crudo si hay `max`, 0-100 si no lo hay). */
39
+ valueLabel?: string;
40
+ };
41
+ export type SplitBarTone = MetricBarTone;
42
+ export type SplitBarSegment = {
43
+ label: string;
44
+ value: number;
45
+ tone?: SplitBarTone;
10
46
  };
11
47
  export type EntityCardStatus = "default" | "featured" | "warning";
12
48
  export type EntityCardVariant = "entity" | "group";
@@ -1,3 +1,3 @@
1
1
  import { ChartProps } from './types';
2
2
  export type { ChartProps } from './types';
3
- export declare const Chart: ({ type, data, xKey, series, height, ariaLabel, emptyMessage, className, showGrid, showTooltip, showLegend, }: ChartProps) => import("react").JSX.Element;
3
+ export declare const Chart: ({ type, data, xKey, series, height, ariaLabel, emptyMessage, className, showGrid, showTooltip, showLegend, orientation, stacking, unit, yDomain, xAxisFormat, yAxisFormat, tooltipFormat, valueLabelFormat, showValueLabels, referenceLines, onDataPointClick, }: ChartProps) => import("react").JSX.Element;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,7 @@
1
+ import { DeviationBandProps } from './types';
2
+ /**
3
+ * Valor puntual contra su rango esperado (promedio ± margen), con marcador de desviación — ej.
4
+ * "producción -27% respecto al promedio del lote". Distinto de `MetricBar` (que dimensiona 0-100
5
+ * contra un `max`, no contra un promedio) y de `Chart` (que es una serie, no un punto).
6
+ */
7
+ export declare const DeviationBand: ({ value, average, min, max, unit, label, valueFormat, direction, className, }: DeviationBandProps) => import("react").JSX.Element;
@@ -0,0 +1,12 @@
1
+ import { DiagnosticRadarProps } from './types';
2
+ export type { DiagnosticRadarProps, RadarMetric } from './types';
3
+ /**
4
+ * Radar/diagnóstico multi-eje: representa varias métricas reales (0-`max`) sobre un mismo gráfico
5
+ * polar, ej. Digitalización/Integración/Analítica/Automatización/Calidad de datos. Cada eje viene de
6
+ * `data` — no hay nada hardcodeado ni puramente decorativo, el polígono se recalcula solo con las
7
+ * métricas reales.
8
+ *
9
+ * Reutiliza los mismos tokens/formatters que `Chart` (`chartAxisTick`, `chartTooltipStyle`,
10
+ * `buildDefaultFormatter`) para que se vea como parte del mismo sistema, no como un componente aparte.
11
+ */
12
+ export declare const DiagnosticRadar: ({ data, max, color, height, ariaLabel, emptyMessage, className, showTooltip, showLegend, showValues, valueFormat, }: DiagnosticRadarProps) => import("react").JSX.Element;
@@ -1,2 +1,2 @@
1
1
  import { SparklineProps } from './types';
2
- export declare const Sparkline: ({ data, dataKey, height, width, color, ariaLabel, emptyMessage, className, }: SparklineProps) => import("react").JSX.Element;
2
+ export declare const Sparkline: ({ data, dataKey, type, height, width, color, ariaLabel, emptyMessage, className, }: SparklineProps) => import("react").JSX.Element;
@@ -1,4 +1,5 @@
1
1
  import { CSSProperties } from 'react';
2
+ import { ChartDataPoint, ChartSeries, ChartValueFormatter } from './types';
2
3
  export declare const CHART_SERIES_COLORS: readonly ["var(--sf-chart-1)", "var(--sf-chart-2)", "var(--sf-chart-3)", "var(--sf-chart-4)", "var(--sf-chart-5)"];
3
4
  export declare const resolveSeriesColor: (series: {
4
5
  color?: string;
@@ -12,3 +13,18 @@ export declare const chartLegendStyle: {
12
13
  fontSize: string;
13
14
  color: string;
14
15
  };
16
+ export declare const chartValueLabelStyle: CSSProperties;
17
+ /** Formatter por defecto cuando no se pasa uno explícito: número en es-PE + unidad opcional. */
18
+ export declare const buildDefaultFormatter: (unit?: string) => ChartValueFormatter;
19
+ /** Prefijo interno para guardar el valor real de una serie cuando el dato visible se normalizó
20
+ * (ej. `stacking="stacked-100"`). No es parte del contrato público de `ChartDataPoint`. */
21
+ export declare const RAW_VALUE_PREFIX = "__sfRaw_";
22
+ export declare const rawValueKey: (key: string) => string;
23
+ /**
24
+ * Normaliza cada punto de `data` para que la suma de `series` dé 100, conservando el valor real bajo
25
+ * `rawValueKey(key)` (usado por el tooltip). NO muta `data`: retorna un array nuevo.
26
+ * Total 0 o ausente en un punto → todas las series de ese punto quedan en 0 (no se dibuja nada, no NaN).
27
+ * Valores negativos se tratan como 0 para el cálculo del total (una serie negativa no "resta" espacio
28
+ * a las demás en una barra apilada al 100%, que no tiene forma de representar eso).
29
+ */
30
+ export declare const toStacked100Data: (data: ChartDataPoint[], series: ChartSeries[]) => ChartDataPoint[];
@@ -1,5 +1,7 @@
1
1
  export { Chart } from './Chart';
2
2
  export type { ChartProps } from './Chart';
3
3
  export { Sparkline } from './Sparkline';
4
- export { CHART_SERIES_COLORS, resolveSeriesColor } from './chartUtils';
5
- export type { BaseChartProps, ChartDataPoint, ChartSeries, ChartType, SparklineProps } from './types';
4
+ export { DiagnosticRadar } from './DiagnosticRadar';
5
+ export { DeviationBand } from './DeviationBand';
6
+ export { CHART_SERIES_COLORS, resolveSeriesColor, buildDefaultFormatter, toStacked100Data, rawValueKey } from './chartUtils';
7
+ export type { BaseChartProps, ChartDataPoint, ChartOrientation, ChartReferenceLine, ChartSeries, ChartStacking, ChartType, ChartValueFormatter, DiagnosticRadarProps, DeviationBandDirection, DeviationBandProps, RadarMetric, SparklineProps, } from './types';
@@ -1,10 +1,37 @@
1
1
  export type ChartType = "bar" | "line" | "area";
2
+ /** Solo aplica a `type="bar"`. "vertical" (por defecto) = barras verticales de siempre.
3
+ * "horizontal" = barras horizontales (categoría en el eje Y, valor en el eje X) — útil para
4
+ * rankings con etiquetas largas. Se ignora en "line"/"area". */
5
+ export type ChartOrientation = "vertical" | "horizontal";
6
+ /** Solo aplica a `type="bar"`/`"area"` (Line no se apila, recharts no lo soporta con sentido).
7
+ * "none" (por defecto) = series lado a lado si hay más de una (comportamiento actual, sin cambios).
8
+ * "stacked" = todas las series se apilan por su valor real, una sobre otra.
9
+ * "stacked-100" = igual que "stacked" pero normalizado a 100% por punto — el dato original
10
+ * (`data`) NUNCA se modifica; el tooltip sigue mostrando el valor real vía `tooltipFormat`. */
11
+ export type ChartStacking = "none" | "stacked" | "stacked-100";
2
12
  export type ChartSeries = {
3
13
  key: string;
4
14
  label?: string;
5
15
  color?: string;
16
+ /** Id de grupo de apilado explícito, para mezclar series apiladas y sueltas en un mismo chart.
17
+ * Si se omite y `stacking` es "stacked"/"stacked-100", todas las series comparten un solo stack. */
18
+ stackId?: string;
6
19
  };
7
20
  export type ChartDataPoint = Record<string, string | number | null | undefined>;
21
+ /** Formatea un valor numérico de un chart (eje, tooltip o label de barra). `key` es la key de la
22
+ * serie/eje que se está formateando, por si el formato depende de cuál es (ej. unidades distintas). */
23
+ export type ChartValueFormatter = (value: number, key?: string) => string;
24
+ export type ChartReferenceLine = {
25
+ /** Valor en el dominio del eje que recibe la línea (ver `axis`). */
26
+ value: number;
27
+ label?: string;
28
+ color?: string;
29
+ /** Eje sobre el que se traza: "y" (por defecto) = línea horizontal (típico para una meta);
30
+ * "x" = línea vertical. Con `orientation="horizontal"` los ejes están intercambiados en pantalla,
31
+ * pero `axis` sigue refiriéndose al eje lógico (y = valor, x = categoría). */
32
+ axis?: "x" | "y";
33
+ strokeDasharray?: string;
34
+ };
8
35
  export type BaseChartProps = {
9
36
  data: ChartDataPoint[];
10
37
  xKey: string;
@@ -16,13 +43,81 @@ export type BaseChartProps = {
16
43
  showGrid?: boolean;
17
44
  showTooltip?: boolean;
18
45
  showLegend?: boolean;
46
+ /** Ver `ChartOrientation`. Por defecto "vertical". */
47
+ orientation?: ChartOrientation;
48
+ /** Ver `ChartStacking`. Por defecto "none" (comportamiento actual). */
49
+ stacking?: ChartStacking;
50
+ /** Unidad a anexar en los formatos por defecto de eje/tooltip cuando no se pasa un formatter propio
51
+ * (ej. "kg", "%", "S/"). No afecta si `xAxisFormat`/`yAxisFormat`/`tooltipFormat` ya están definidos. */
52
+ unit?: string;
53
+ /** Dominio del eje de valores. Por defecto Recharts calcula `[0, "auto"]`. */
54
+ yDomain?: [number | "auto" | "dataMin" | "dataMax", number | "auto" | "dataMin" | "dataMax"];
55
+ xAxisFormat?: ChartValueFormatter;
56
+ yAxisFormat?: ChartValueFormatter;
57
+ /** Formatea el valor mostrado en el tooltip. En `stacking="stacked-100"` recibe el valor ORIGINAL
58
+ * (no el porcentaje normalizado) — el porcentaje es solo un artificio visual de la barra. */
59
+ tooltipFormat?: ChartValueFormatter;
60
+ /** Formatea las etiquetas de valor sobre cada barra/punto cuando `showValueLabels` está activo. */
61
+ valueLabelFormat?: ChartValueFormatter;
62
+ /** Muestra el valor de cada punto/barra como etiqueta encima. Por defecto `false`. */
63
+ showValueLabels?: boolean;
64
+ /** Líneas de referencia (ej. una meta) dibujadas sobre el chart. */
65
+ referenceLines?: ChartReferenceLine[];
66
+ /** Se dispara al hacer clic sobre el área del chart con el punto de datos más cercano bajo el cursor
67
+ * (comportamiento de Recharts: no es un hit-test exacto de la barra/punto individual, es el punto
68
+ * activo del eje de categorías en esa posición). `series` es la primera serie definida, como referencia. */
69
+ onDataPointClick?: (point: ChartDataPoint, series: ChartSeries) => void;
19
70
  };
20
71
  export type ChartProps = BaseChartProps & {
21
72
  type: ChartType;
22
73
  };
74
+ export type RadarMetric = {
75
+ key: string;
76
+ label: string;
77
+ value: number;
78
+ };
79
+ export type DiagnosticRadarProps = {
80
+ /** Un punto por eje del radar (ej. Digitalización, Integración, Analítica...). Mínimo 3 para que el
81
+ * radar tenga forma — con 1-2 puntos Recharts igual renderiza, pero no se lee como un radar. */
82
+ data: RadarMetric[];
83
+ /** Máximo compartido por TODOS los ejes (Recharts exige un solo dominio radial). Por defecto 100 —
84
+ * pensado para métricas ya expresadas en porcentaje, como las del resto de la librería (`MetricBar`,
85
+ * `DonutGauge`). Si tus métricas usan otra escala, pásalas ya normalizadas o ajusta `max`. */
86
+ max?: number;
87
+ color?: string;
88
+ height?: number;
89
+ ariaLabel?: string;
90
+ emptyMessage?: string;
91
+ className?: string;
92
+ showTooltip?: boolean;
93
+ showLegend?: boolean;
94
+ /** Muestra el valor numérico junto a cada eje (además del tooltip). Por defecto `false`. */
95
+ showValues?: boolean;
96
+ valueFormat?: ChartValueFormatter;
97
+ };
98
+ export type DeviationBandDirection = "up-good" | "down-good" | "neutral";
99
+ export type DeviationBandProps = {
100
+ value: number;
101
+ average: number;
102
+ /** Extremos del track. Si se omiten, se calculan a partir de `value`/`average` con margen — para el
103
+ * caso típico ("¿cuánto se desvía este valor de lo normal?") no hace falta pasarlos. */
104
+ min?: number;
105
+ max?: number;
106
+ unit?: string;
107
+ label?: string;
108
+ valueFormat?: ChartValueFormatter;
109
+ /** Igual criterio que `KPICardTrendDirection`: cómo interpretar el signo de la desviación para
110
+ * colorearla. Por defecto "down-good" (bajar respecto al promedio es la lectura más común: costo,
111
+ * incidencias, tiempo de atención). */
112
+ direction?: DeviationBandDirection;
113
+ className?: string;
114
+ };
23
115
  export type SparklineProps = {
24
116
  data: ChartDataPoint[];
25
117
  dataKey: string;
118
+ /** "line" (por defecto, acabado actual) o "bar" — mini gráfico de barras en vez de línea, para el
119
+ * mismo caso de uso (una tendencia diminuta dentro de una KPICard u otra pieza compacta). */
120
+ type?: "line" | "bar";
26
121
  height?: number;
27
122
  width?: number | string;
28
123
  color?: string;
@@ -0,0 +1,31 @@
1
+ import { ReactNode } from 'react';
2
+ import { AlertActionItem, AlertDensity, EventStatus } from './types';
3
+ export type AlertSummaryRowItem = {
4
+ label: string;
5
+ description?: string;
6
+ value: ReactNode;
7
+ /** Fondo/texto tintado según severidad. "default" = neutro (sin tinte). */
8
+ tone?: EventStatus;
9
+ /** Si viene, la fila es clickeable (cursor pointer, hover) — ej. drill-down a una lista filtrada.
10
+ * Se ignora si `actions` viene con elementos (ver `AlertActionItem`). */
11
+ onClick?: () => void;
12
+ /** Acciones explícitas de la fila (ej. "Ver lista", "Descartar"), renderizadas como botones propios.
13
+ * Cuando vienen, la fila entera deja de ser `role="button"` (evita botón-dentro-de-botón). */
14
+ actions?: AlertActionItem[];
15
+ };
16
+ type AlertSummaryListProps = {
17
+ items: AlertSummaryRowItem[];
18
+ className?: string;
19
+ /** Ver `AlertDensity`. Por defecto "comfortable" (acabado actual). */
20
+ density?: AlertDensity;
21
+ /** Contenido cuando `items` está vacío. Por defecto "Sin alertas". */
22
+ emptyMessage?: ReactNode;
23
+ };
24
+ /**
25
+ * Lista de filas de ancho completo con fondo tintado por severidad y un valor grande
26
+ * a la derecha (ej. "Alertas y pendientes de regularizar" del tablero de Contratos).
27
+ * Distinto de `AlertRowList`: esa es una bitácora de eventos (icono + hora + meta);
28
+ * esta es un resumen de conteos/alertas con el número como protagonista.
29
+ */
30
+ export declare const AlertSummaryList: ({ items, className, density, emptyMessage }: AlertSummaryListProps) => import("react").JSX.Element;
31
+ export {};
@@ -0,0 +1,24 @@
1
+ export type ComparisonRow = {
2
+ key: string;
3
+ label: string;
4
+ plan: number;
5
+ real: number;
6
+ unit?: string;
7
+ /** Igual criterio que `DeviationBandDirection`: cómo interpretar el signo de la desviación para
8
+ * colorearla. Por defecto "up-good" (superar el plan es bueno — típico de ventas/producción). */
9
+ direction?: "up-good" | "down-good" | "neutral";
10
+ valueFormat?: (value: number) => string;
11
+ };
12
+ export type ComparisonTableProps = {
13
+ rows: ComparisonRow[];
14
+ planLabel?: string;
15
+ realLabel?: string;
16
+ className?: string;
17
+ };
18
+ /**
19
+ * Tabla Plan vs. Real con la desviación calculada por fila — cada fila muestra plan, real y el delta
20
+ * (absoluto y %) coloreado según si esa desviación es buena o mala para esa métrica en particular.
21
+ * Distinto de una tabla genérica: la columna de desviación es siempre calculada, nunca un dato que el
22
+ * consumidor tenga que traer aparte.
23
+ */
24
+ export declare const ComparisonTable: ({ rows, planLabel, realLabel, className }: ComparisonTableProps) => import("react").JSX.Element;
@@ -1,27 +1,54 @@
1
1
  import { ReactNode } from 'react';
2
- import { DashboardCardVariant, StatBarItem } from './types';
2
+ import { DashboardCardState, DashboardCardVariant, StatBarItem } from './types';
3
3
  export type DashboardCardProps = {
4
4
  title?: string;
5
5
  subtitle?: string;
6
6
  icon?: ReactNode;
7
7
  headerAction?: ReactNode;
8
8
  variant?: DashboardCardVariant;
9
- span?: 1 | 2 | 3 | 4;
9
+ span?: 1 | 2 | 3 | 4 | 5 | 6;
10
10
  padding?: "sm" | "md" | "lg" | "none";
11
11
  /** Tamaño de la cabecera. "sm" (por defecto) reproduce el acabado actual; "md" usa el título 15px, icono en
12
12
  * círculo de 28px y padding más generoso del mockup de Torre de control. */
13
13
  headerSize?: "sm" | "md";
14
+ /** Permite que la cabecera pase a 2 líneas (título arriba, subtítulo/acción abajo) cuando no entran en
15
+ * una sola fila, en vez de recortar con `truncate` (acabado actual, `false` por defecto). Útil con
16
+ * títulos largos + `headerAction` ancho (ej. un selector de rango de fechas). */
17
+ headerWrap?: boolean;
18
+ /** Contenido opcional bajo el cuerpo, separado por un borde — ej. un resumen o un link "ver todo". */
19
+ footer?: ReactNode;
20
+ /** Estado del cuerpo. "idle" (por defecto) = `children` tal cual. Ver `DashboardCardState`. */
21
+ state?: DashboardCardState;
22
+ loadingMessage?: ReactNode;
23
+ errorMessage?: ReactNode;
24
+ emptyMessage?: ReactNode;
25
+ /** Si viene junto a `state="error"`, el estado de error muestra un botón para reintentar. */
26
+ onRetry?: () => void;
27
+ retryLabel?: string;
28
+ /** Alto mínimo del cuerpo (px si es número). Útil para que los estados de carga/error/vacío no
29
+ * "colapsen" la tarjeta a una línea dentro de un `DashboardGrid` con `alignItems="start"`. */
30
+ minHeight?: number | string;
31
+ /** Comportamiento de desbordamiento del cuerpo. "visible" (por defecto) = acabado actual (sin regla,
32
+ * el contenido puede desbordar). "auto" agrega scroll; "hidden" recorta. */
33
+ bodyOverflow?: "visible" | "auto" | "hidden";
14
34
  className?: string;
15
35
  children?: ReactNode;
16
36
  };
17
- export declare const DashboardCard: ({ title, subtitle, icon, headerAction, variant, span, padding, headerSize, className, children, }: DashboardCardProps) => import("react").JSX.Element;
37
+ export declare const DashboardCard: ({ title, subtitle, icon, headerAction, variant, span, padding, headerSize, headerWrap, footer, state, loadingMessage, errorMessage, emptyMessage, onRetry, retryLabel, minHeight, bodyOverflow, className, children, }: DashboardCardProps) => import("react").JSX.Element;
18
38
  type DashboardGridProps = {
19
39
  cols?: 2 | 3 | 4 | 5 | 6;
20
40
  gap?: "sm" | "md" | "lg";
41
+ /** "stretch" (por defecto, acabado actual) estira todas las tarjetas de la fila a la altura de la
42
+ * más alta. "start" deja que cada tarjeta ocupe solo el alto de su propio contenido — útil cuando
43
+ * las tarjetas de una fila tienen cantidades de contenido muy distintas (ej. Sexo vs Edad). */
44
+ alignItems?: "stretch" | "start";
45
+ /** Si se define, reemplaza `cols` por una grilla `auto-fit` con ancho mínimo por tarjeta (ej. "16rem")
46
+ * — cada tarjeta ocupa lo que necesite y la fila ajusta cuántas entran, sin puntos de quiebre fijos. */
47
+ minColWidth?: string;
21
48
  className?: string;
22
49
  children?: ReactNode;
23
50
  };
24
- export declare const DashboardGrid: ({ cols, gap, className, children }: DashboardGridProps) => import("react").JSX.Element;
51
+ export declare const DashboardGrid: ({ cols, gap, alignItems, minColWidth, className, children }: DashboardGridProps) => import("react").JSX.Element;
25
52
  type DashboardSectionProps = {
26
53
  title: string;
27
54
  subtitle?: string;
@@ -0,0 +1,26 @@
1
+ import { ReactNode } from 'react';
2
+ export type DetailSectionTone = "default" | "info" | "danger" | "warning" | "success";
3
+ export type DetailSectionDensity = "sm" | "md";
4
+ export type DetailSectionRow = {
5
+ label: string;
6
+ value: ReactNode;
7
+ /** Línea de 12px bajo el valor — p.ej. "Vencido hace 72 días". El color lo decide el consumidor en el nodo. */
8
+ hint?: ReactNode;
9
+ };
10
+ export type DetailSectionProps = {
11
+ /** Título de la cabecera, 14px/600 — p.ej. "Carnet del conductor". */
12
+ title: string;
13
+ /** Icono a la izquierda del título (inline-flex). */
14
+ icon?: ReactNode;
15
+ /** "default": cabecera `--sf-surface-alt`. Los demás: fondo tenue del tono e icono/título en su color
16
+ * (mockup 0402 Conductores: "Carnet del conductor" en `danger` cuando está vencido). */
17
+ tone?: DetailSectionTone;
18
+ /** Filas label/valor separadas por línea `--sf-border`; el valor va alineado a la izquierda de su columna. */
19
+ rows?: DetailSectionRow[];
20
+ /** Contenido libre bajo las filas. */
21
+ children?: ReactNode;
22
+ className?: string;
23
+ /** "md" (por defecto) o "sm" = padding y fuente menores para paneles laterales de 380px. */
24
+ density?: DetailSectionDensity;
25
+ };
26
+ export declare const DetailSection: ({ title, icon, tone, rows, children, className, density }: DetailSectionProps) => import("react").JSX.Element;
@@ -1,5 +1,5 @@
1
1
  import { ReactNode } from 'react';
2
- import { AlertRowItem, AlertRowListHeaderLabels, EventItem, EventStatus } from './types';
2
+ import { AlertDensity, AlertRowItem, AlertRowListHeaderLabels, EventItem, EventStatus } from './types';
3
3
  type EventLogProps = {
4
4
  events: EventItem[];
5
5
  title?: string;
@@ -20,8 +20,12 @@ type AlertRowListProps = {
20
20
  columns?: boolean;
21
21
  /** Textos de la cabecera en modo `columns`. Por defecto en español. */
22
22
  headerLabels?: AlertRowListHeaderLabels;
23
+ /** Ver `AlertDensity`. Por defecto "comfortable" (acabado actual). */
24
+ density?: AlertDensity;
25
+ /** Contenido cuando `items` está vacío. Por defecto "Sin alertas" (acabado actual). */
26
+ emptyMessage?: ReactNode;
23
27
  };
24
- export declare const AlertRowList: ({ items, maxHeight, className, columns, headerLabels }: AlertRowListProps) => import("react").JSX.Element;
28
+ export declare const AlertRowList: ({ items, maxHeight, className, columns, headerLabels, density, emptyMessage, }: AlertRowListProps) => import("react").JSX.Element;
25
29
  export type AlertLaneItem = {
26
30
  id?: string;
27
31
  title: ReactNode;
@@ -0,0 +1,19 @@
1
+ export type EvidenceFootnoteItem = {
2
+ label: string;
3
+ value: string;
4
+ };
5
+ export type EvidenceFootnoteProps = {
6
+ /** Datos de procedencia, ej. `{ label: "Período", value: "14 meses" }`. Se pintan separados por "·". */
7
+ items: EvidenceFootnoteItem[];
8
+ /** Nivel de confianza 0-100. Se omite el badge si no se pasa — nunca inventar un número. */
9
+ confidence?: number;
10
+ /** Texto de última actualización, ya formateado (ej. "21 sep 2026"). */
11
+ updatedAt?: string;
12
+ className?: string;
13
+ };
14
+ /**
15
+ * Pie de procedencia de datos reutilizable — "¿de dónde salió esto?" (período analizado, registros,
16
+ * fuentes, confianza, última actualización). Pensado como `footer` de `DashboardCard`/`KPICard` o
17
+ * suelto al pie de cualquier tarjeta analítica, para no improvisar este patrón cada vez.
18
+ */
19
+ export declare const EvidenceFootnote: ({ items, confidence, updatedAt, className }: EvidenceFootnoteProps) => import("react").JSX.Element;
@@ -1,4 +1,5 @@
1
1
  import { ReactNode } from 'react';
2
+ export type StatCardSize = "sm" | "md" | "lg";
2
3
  type StatCardProps = {
3
4
  value: ReactNode;
4
5
  label: ReactNode;
@@ -6,6 +7,9 @@ type StatCardProps = {
6
7
  accent?: string;
7
8
  /** icono opcional; se pinta dentro de un halo del color del acento */
8
9
  icon?: ReactNode;
10
+ /** Tamaño de la tarjeta (padding, icono y tipografía del valor). Por defecto "md" — idéntico al
11
+ * acabado actual, sin cambios visuales para quien no pasa esta prop. */
12
+ size?: StatCardSize;
9
13
  className?: string;
10
14
  };
11
15
  /**
@@ -13,5 +17,5 @@ type StatCardProps = {
13
17
  * icono con halo, valor grande y label. El halo se deriva del acento con
14
18
  * color-mix para no pedir dos colores.
15
19
  */
16
- export declare const StatCard: ({ value, label, accent, icon, className }: StatCardProps) => import("react").JSX.Element;
20
+ export declare const StatCard: ({ value, label, accent, icon, size, className }: StatCardProps) => import("react").JSX.Element;
17
21
  export {};