@sentropic/design-system-react 0.11.0 → 0.12.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.
@@ -0,0 +1,45 @@
1
+ import React from "react";
2
+ export type KpiCardSize = "sm" | "md" | "lg";
3
+ export type KpiCardTrend = "up" | "down" | "flat";
4
+ export type KpiCardFormat = "number" | "currency" | "percent";
5
+ export type KpiCardDeltaFormat = "percent" | "absolute";
6
+ export type KpiCardTone = "category1" | "category2" | "category3" | "category4" | "category5" | "category6" | "category7" | "category8";
7
+ export type KpiCardProps = Omit<React.HTMLAttributes<HTMLElement>, "className"> & {
8
+ /**
9
+ * Valeur principale affichée en grand. Le formatage `format` ne s'applique
10
+ * qu'aux `number` (un `string` est rendu verbatim).
11
+ *
12
+ * Pour `format="percent"`, `Intl.NumberFormat` multiplie par 100 : passez une
13
+ * **fraction** (0–1). Ex. `0.42` → « 42 % », et non `42` (qui donnerait « 4 200 % »).
14
+ */
15
+ value: number | string;
16
+ /** Étiquette de l'indicateur (ex. « Revenu mensuel »). */
17
+ label: string;
18
+ /**
19
+ * Variation par rapport à la période précédente.
20
+ *
21
+ * En `deltaFormat="percent"` (défaut), la valeur est multipliée par 100 :
22
+ * passez une **fraction** (ex. `0.12` → « +12 % »).
23
+ */
24
+ delta?: number;
25
+ /** Comment exprimer le delta : en pourcentage ou en valeur absolue. */
26
+ deltaFormat?: KpiCardDeltaFormat;
27
+ /** Tendance ; déduite du signe du delta si absente. */
28
+ trend?: KpiCardTrend;
29
+ /** Formatage de la valeur principale via Intl.NumberFormat. */
30
+ format?: KpiCardFormat;
31
+ /** Unité suffixée à la valeur (ex. « ms », « €/mois »). */
32
+ unit?: string;
33
+ /** Code devise ISO 4217 pour format="currency" (défaut EUR). */
34
+ currency?: string;
35
+ /** Locale BCP 47 pour le formatage des nombres (défaut undefined = locale du runtime). */
36
+ locale?: string;
37
+ /** Mini-graphique de tendance optionnel. */
38
+ sparkline?: number[];
39
+ size?: KpiCardSize;
40
+ /** Couleur catégorielle pour l'accent (pastille discrète près de l'étiquette). */
41
+ tone?: KpiCardTone;
42
+ className?: string;
43
+ };
44
+ export declare function KpiCard({ value, label, delta, deltaFormat, trend, format, unit, currency, locale, sparkline, size, tone, className, ...rest }: KpiCardProps): import("react/jsx-runtime").JSX.Element;
45
+ //# sourceMappingURL=KpiCard.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"KpiCard.d.ts","sourceRoot":"","sources":["../src/KpiCard.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAI1B,MAAM,MAAM,WAAW,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;AAC7C,MAAM,MAAM,YAAY,GAAG,IAAI,GAAG,MAAM,GAAG,MAAM,CAAC;AAClD,MAAM,MAAM,aAAa,GAAG,QAAQ,GAAG,UAAU,GAAG,SAAS,CAAC;AAC9D,MAAM,MAAM,kBAAkB,GAAG,SAAS,GAAG,UAAU,CAAC;AACxD,MAAM,MAAM,WAAW,GACnB,WAAW,GACX,WAAW,GACX,WAAW,GACX,WAAW,GACX,WAAW,GACX,WAAW,GACX,WAAW,GACX,WAAW,CAAC;AAEhB,MAAM,MAAM,YAAY,GAAG,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,WAAW,CAAC,EAAE,WAAW,CAAC,GAAG;IAChF;;;;;;OAMG;IACH,KAAK,EAAE,MAAM,GAAG,MAAM,CAAC;IACvB,0DAA0D;IAC1D,KAAK,EAAE,MAAM,CAAC;IACd;;;;;OAKG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,uEAAuE;IACvE,WAAW,CAAC,EAAE,kBAAkB,CAAC;IACjC,uDAAuD;IACvD,KAAK,CAAC,EAAE,YAAY,CAAC;IACrB,+DAA+D;IAC/D,MAAM,CAAC,EAAE,aAAa,CAAC;IACvB,2DAA2D;IAC3D,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,gEAAgE;IAChE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,0FAA0F;IAC1F,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,4CAA4C;IAC5C,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB,IAAI,CAAC,EAAE,WAAW,CAAC;IACnB,kFAAkF;IAClF,IAAI,CAAC,EAAE,WAAW,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,wBAAgB,OAAO,CAAC,EACtB,KAAK,EACL,KAAK,EACL,KAAK,EACL,WAAuB,EACvB,KAAK,EACL,MAAiB,EACjB,IAAI,EACJ,QAAgB,EAChB,MAAM,EACN,SAAS,EACT,IAAW,EACX,IAAI,EACJ,SAAS,EACT,GAAG,IAAI,EACR,EAAE,YAAY,2CAgId"}
@@ -0,0 +1,67 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import React from "react";
3
+ import { classNames } from "./classNames.js";
4
+ import { Sparkline } from "./Sparkline.js";
5
+ export function KpiCard({ value, label, delta, deltaFormat = "percent", trend, format = "number", unit, currency = "EUR", locale, sparkline, size = "md", tone, className, ...rest }) {
6
+ const resolvedTrend = trend ?? (delta == null ? undefined : delta > 0 ? "up" : delta < 0 ? "down" : "flat");
7
+ const formattedValue = (() => {
8
+ if (typeof value === "string") {
9
+ return value;
10
+ }
11
+ // Intl rend "NaN"/"∞" pour les valeurs non finies : préférer un tiret cadratin.
12
+ if (!Number.isFinite(value)) {
13
+ return "—";
14
+ }
15
+ if (format === "currency") {
16
+ try {
17
+ return new Intl.NumberFormat(locale, { style: "currency", currency }).format(value);
18
+ }
19
+ catch {
20
+ // Code devise invalide → repli sur un nombre brut plutôt qu'une exception.
21
+ return new Intl.NumberFormat(locale).format(value);
22
+ }
23
+ }
24
+ if (format === "percent") {
25
+ return new Intl.NumberFormat(locale, { style: "percent", maximumFractionDigits: 2 }).format(value);
26
+ }
27
+ return new Intl.NumberFormat(locale).format(value);
28
+ })();
29
+ const formattedDelta = (() => {
30
+ if (delta == null || !Number.isFinite(delta)) {
31
+ return undefined;
32
+ }
33
+ const sign = delta > 0 ? "+" : "";
34
+ if (deltaFormat === "percent") {
35
+ const pct = new Intl.NumberFormat(locale, {
36
+ style: "percent",
37
+ maximumFractionDigits: 1,
38
+ }).format(delta);
39
+ return `${sign}${pct}`;
40
+ }
41
+ return `${sign}${new Intl.NumberFormat(locale).format(delta)}`;
42
+ })();
43
+ /** Le sparkline emprunte la couleur sémantique de la tendance. */
44
+ const sparklineTone = resolvedTrend === "up" ? "success" : resolvedTrend === "down" ? "error" : "neutral";
45
+ const arrow = resolvedTrend === "up"
46
+ ? "M3 8.5 7 4l4 4.5"
47
+ : resolvedTrend === "down"
48
+ ? "M3 5.5 7 10l4-4.5"
49
+ : "M3 7h8";
50
+ const trendLabel = resolvedTrend === "up"
51
+ ? "en hausse"
52
+ : resolvedTrend === "down"
53
+ ? "en baisse"
54
+ : resolvedTrend === "flat"
55
+ ? "stable"
56
+ : undefined;
57
+ const ariaLabel = [
58
+ label,
59
+ formattedValue,
60
+ unit,
61
+ formattedDelta && `${formattedDelta} ${trendLabel ?? ""}`.trim(),
62
+ ]
63
+ .filter(Boolean)
64
+ .join(", ");
65
+ return (_jsxs("article", { ...rest, className: classNames("st-kpiCard", `st-kpiCard--${size}`, tone && `st-kpiCard--${tone}`, tone && "st-kpiCard--toned", className), role: "group", "aria-label": ariaLabel, children: [_jsxs("p", { className: "st-kpiCard__label", children: [tone ? _jsx("span", { className: "st-kpiCard__swatch", "aria-hidden": "true" }) : null, label] }), _jsxs("p", { className: "st-kpiCard__value", children: [_jsx("span", { className: "st-kpiCard__number", children: formattedValue }), unit ? _jsx("span", { className: "st-kpiCard__unit", children: unit }) : null] }), formattedDelta || sparkline ? (_jsxs("div", { className: "st-kpiCard__footer", children: [formattedDelta ? (_jsxs("span", { className: `st-kpiCard__delta st-kpiCard__delta--${resolvedTrend ?? "flat"}`, "aria-hidden": "true", children: [_jsx("svg", { className: "st-kpiCard__arrow", width: "14", height: "14", viewBox: "0 0 14 14", "aria-hidden": "true", focusable: "false", children: _jsx("path", { d: arrow, fill: "none", stroke: "currentColor", strokeWidth: "1.75", strokeLinecap: "round", strokeLinejoin: "round" }) }), _jsx("span", { className: "st-kpiCard__deltaValue", children: formattedDelta })] })) : null, sparkline && sparkline.length > 0 ? (_jsx(Sparkline, { className: "st-kpiCard__sparkline", data: sparkline, tone: sparklineTone, area: true })) : null] })) : null] }));
66
+ }
67
+ //# sourceMappingURL=KpiCard.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"KpiCard.js","sourceRoot":"","sources":["../src/KpiCard.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,25 @@
1
+ import React from "react";
2
+ export type TreemapChartTone = "category1" | "category2" | "category3" | "category4" | "category5" | "category6" | "category7" | "category8";
3
+ export type TreemapChartDatum = {
4
+ label: string;
5
+ value: number;
6
+ tone?: TreemapChartTone;
7
+ children?: TreemapChartDatum[];
8
+ };
9
+ export type TreemapTiling = "squarified";
10
+ export type TreemapChartProps = Omit<React.HTMLAttributes<HTMLDivElement>, "className"> & {
11
+ /** Données hiérarchiques : 1 ou 2 niveaux. Un nœud avec `children` est subdivisé. */
12
+ data: TreemapChartDatum[];
13
+ /** Algorithme de pavage (squarified uniquement pour l'instant). */
14
+ tiling?: TreemapTiling;
15
+ /** Affiche les labels dans les rectangles suffisamment grands. */
16
+ showLabels?: boolean;
17
+ /** Affiche une légende sous le graphique. */
18
+ legend?: boolean;
19
+ width?: number;
20
+ height?: number;
21
+ label: string;
22
+ className?: string;
23
+ };
24
+ export declare function TreemapChart({ data, tiling, showLabels, legend, width, height, label, className, ...rest }: TreemapChartProps): import("react/jsx-runtime").JSX.Element;
25
+ //# sourceMappingURL=TreemapChart.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TreemapChart.d.ts","sourceRoot":"","sources":["../src/TreemapChart.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAK1B,MAAM,MAAM,gBAAgB,GACxB,WAAW,GACX,WAAW,GACX,WAAW,GACX,WAAW,GACX,WAAW,GACX,WAAW,GACX,WAAW,GACX,WAAW,CAAC;AAEhB,MAAM,MAAM,iBAAiB,GAAG;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,gBAAgB,CAAC;IACxB,QAAQ,CAAC,EAAE,iBAAiB,EAAE,CAAC;CAChC,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG,YAAY,CAAC;AAEzC,MAAM,MAAM,iBAAiB,GAAG,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC,EAAE,WAAW,CAAC,GAAG;IACxF,qFAAqF;IACrF,IAAI,EAAE,iBAAiB,EAAE,CAAC;IAC1B,mEAAmE;IACnE,MAAM,CAAC,EAAE,aAAa,CAAC;IACvB,kEAAkE;IAClE,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,6CAA6C;IAC7C,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAqHF,wBAAgB,YAAY,CAAC,EAC3B,IAAI,EACJ,MAAqB,EACrB,UAAiB,EACjB,MAAc,EACd,KAAW,EACX,MAAY,EACZ,KAAK,EACL,SAAS,EACT,GAAG,IAAI,EACR,EAAE,iBAAiB,2CAqLnB"}
@@ -0,0 +1,179 @@
1
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import React from "react";
3
+ import { classNames } from "./classNames.js";
4
+ import { ChartDataList } from "./chartScale.js";
5
+ import { contrastTextForTone } from "./chartContrast.js";
6
+ const TONES = [
7
+ "category1",
8
+ "category2",
9
+ "category3",
10
+ "category4",
11
+ "category5",
12
+ "category6",
13
+ "category7",
14
+ "category8",
15
+ ];
16
+ const PADDING = 2;
17
+ const sumValue = (d) => {
18
+ if (d.children && d.children.length > 0) {
19
+ return d.children.reduce((s, c) => s + sumValue(c), 0);
20
+ }
21
+ return Math.max(d.value, 0);
22
+ };
23
+ // Squarified treemap (Bruls, Huizing, van Wijk 2000).
24
+ function squarify(nodes, rect) {
25
+ const out = [];
26
+ const total = nodes.reduce((s, n) => s + n.value, 0);
27
+ if (total <= 0 || nodes.length === 0)
28
+ return out;
29
+ // Échelle valeur → aire disponible.
30
+ const area = rect.w * rect.h;
31
+ const scale = area / total;
32
+ const items = nodes.map((n) => ({ datum: n.datum, value: n.value, area: n.value * scale }));
33
+ let free = { ...rect };
34
+ let row = [];
35
+ const worst = (r, side) => {
36
+ if (r.length === 0 || side <= 0)
37
+ return Infinity;
38
+ const s = r.reduce((acc, it) => acc + it.area, 0);
39
+ let max = -Infinity;
40
+ let min = Infinity;
41
+ for (const it of r) {
42
+ if (it.area > max)
43
+ max = it.area;
44
+ if (it.area < min)
45
+ min = it.area;
46
+ }
47
+ const s2 = s * s;
48
+ const side2 = side * side;
49
+ return Math.max((side2 * max) / s2, s2 / (side2 * min));
50
+ };
51
+ const layoutRow = (r, side, area2) => {
52
+ const s = r.reduce((acc, it) => acc + it.area, 0);
53
+ if (side <= 0)
54
+ return area2;
55
+ // Largeur (ou hauteur) de la bande consommée.
56
+ const thickness = s / side;
57
+ if (area2.w >= area2.h) {
58
+ // Bande verticale à gauche, items empilés verticalement.
59
+ let oy = area2.y;
60
+ for (const it of r) {
61
+ const h = it.area / thickness;
62
+ out.push({ datum: it.datum, value: it.value, rect: { x: area2.x, y: oy, w: thickness, h } });
63
+ oy += h;
64
+ }
65
+ return { x: area2.x + thickness, y: area2.y, w: area2.w - thickness, h: area2.h };
66
+ }
67
+ else {
68
+ // Bande horizontale en haut, items côte à côte.
69
+ let ox = area2.x;
70
+ for (const it of r) {
71
+ const w = it.area / thickness;
72
+ out.push({ datum: it.datum, value: it.value, rect: { x: ox, y: area2.y, w, h: thickness } });
73
+ ox += w;
74
+ }
75
+ return { x: area2.x, y: area2.y + thickness, w: area2.w, h: area2.h - thickness };
76
+ }
77
+ };
78
+ for (const it of items) {
79
+ const side = Math.min(free.w, free.h);
80
+ const next = [...row, it];
81
+ if (row.length === 0 || worst(next, side) <= worst(row, side)) {
82
+ row = next;
83
+ }
84
+ else {
85
+ free = layoutRow(row, side, free);
86
+ row = [it];
87
+ }
88
+ }
89
+ if (row.length > 0) {
90
+ free = layoutRow(row, Math.min(free.w, free.h), free);
91
+ }
92
+ return out;
93
+ }
94
+ function inset(r, pad) {
95
+ const w = Math.max(r.w - pad * 2, 0);
96
+ const h = Math.max(r.h - pad * 2, 0);
97
+ return { x: r.x + pad, y: r.y + pad, w, h };
98
+ }
99
+ // Seuils (en unités SVG) pour décider quand afficher un label.
100
+ const LABEL_MIN_W = 44;
101
+ const LABEL_MIN_H = 22;
102
+ const VALUE_MIN_H = 38;
103
+ export function TreemapChart({ data, tiling = "squarified", showLabels = true, legend = false, width = 480, height = 300, label, className, ...rest }) {
104
+ void tiling;
105
+ const [hoveredIndex, setHoveredIndex] = React.useState(null);
106
+ const cells = (() => {
107
+ if (!data || data.length === 0)
108
+ return [];
109
+ // Squarify suppose une entrée triée par valeur décroissante pour des ratios d'aspect corrects.
110
+ const roots = data
111
+ .map((d, i) => ({ datum: d, value: sumValue(d), tone: d.tone ?? TONES[i % TONES.length] }))
112
+ .filter((n) => n.value > 0)
113
+ .sort((a, b) => b.value - a.value);
114
+ if (roots.length === 0)
115
+ return [];
116
+ const topRects = squarify(roots.map((r) => ({ datum: r.datum, value: r.value })), { x: 0, y: 0, w: width, h: height });
117
+ const result = [];
118
+ topRects.forEach((tr) => {
119
+ const root = roots.find((r) => r.datum === tr.datum);
120
+ const children = (tr.datum.children?.filter((c) => Math.max(c.value, 0) > 0) ?? [])
121
+ .slice()
122
+ .sort((a, b) => Math.max(b.value, 0) - Math.max(a.value, 0));
123
+ if (children.length > 0) {
124
+ // Niveau 2 : subdiviser l'intérieur du rectangle parent.
125
+ const innerRect = inset(tr.rect, PADDING);
126
+ const childRects = squarify(children.map((c) => ({ datum: c, value: Math.max(c.value, 0) })), innerRect);
127
+ childRects.forEach((cr, ci) => {
128
+ const tone = cr.datum.tone ?? root.tone ?? TONES[ci % TONES.length];
129
+ result.push({
130
+ datum: cr.datum,
131
+ value: cr.value,
132
+ tone,
133
+ textColor: contrastTextForTone(tone),
134
+ rect: inset(cr.rect, PADDING / 2),
135
+ parentLabel: tr.datum.label,
136
+ depth: 1,
137
+ });
138
+ });
139
+ }
140
+ else {
141
+ result.push({
142
+ datum: tr.datum,
143
+ value: tr.value,
144
+ tone: root.tone,
145
+ textColor: contrastTextForTone(root.tone),
146
+ rect: inset(tr.rect, PADDING / 2),
147
+ depth: 0,
148
+ });
149
+ }
150
+ });
151
+ return result;
152
+ })();
153
+ // Légende : un swatch par catégorie de premier niveau.
154
+ const legendItems = (() => {
155
+ if (!data)
156
+ return [];
157
+ return data
158
+ .map((d, i) => ({ label: d.label, tone: d.tone ?? TONES[i % TONES.length] }))
159
+ .filter((_, i) => sumValue(data[i]) > 0);
160
+ })();
161
+ const dataValueItems = cells.map((c) => c.parentLabel ? `${c.parentLabel}, ${c.datum.label}: ${c.value}` : `${c.datum.label}: ${c.value}`);
162
+ function handleVisualPointerMove(event) {
163
+ const target = event.target;
164
+ if (!(target instanceof Element)) {
165
+ setHoveredIndex(null);
166
+ return;
167
+ }
168
+ const index = Number(target.getAttribute("data-chart-index"));
169
+ setHoveredIndex(Number.isInteger(index) ? index : null);
170
+ }
171
+ const hoveredCell = hoveredIndex !== null ? cells[hoveredIndex] : undefined;
172
+ return (_jsxs("div", { ...rest, className: classNames("st-treemapChart", className), children: [_jsx("div", { className: "st-treemapChart__visual", role: "img", "aria-label": label, onPointerMove: handleVisualPointerMove, onPointerLeave: () => setHoveredIndex(null), children: _jsx("svg", { viewBox: `0 0 ${width} ${height}`, preserveAspectRatio: "xMidYMid meet", width: "100%", height: "100%", focusable: "false", "aria-hidden": "true", children: cells.map((cell, i) => (_jsxs("g", { className: "st-treemapChart__cell", "data-chart-index": i, children: [_jsx("rect", { className: classNames("st-treemapChart__rect", `st-treemapChart__rect--${cell.tone}`, hoveredIndex !== null && hoveredIndex !== i && "st-treemapChart__rect--dim"), x: cell.rect.x, y: cell.rect.y, width: cell.rect.w, height: cell.rect.h, rx: "2", "data-chart-index": i }), showLabels && cell.rect.w >= LABEL_MIN_W && cell.rect.h >= LABEL_MIN_H ? (_jsxs(_Fragment, { children: [_jsx("text", { className: "st-treemapChart__label", x: cell.rect.x + 6, y: cell.rect.y + 15, "data-chart-index": i, style: { fill: cell.textColor }, children: cell.datum.label }), cell.rect.h >= VALUE_MIN_H ? (_jsx("text", { className: "st-treemapChart__value", x: cell.rect.x + 6, y: cell.rect.y + 30, "data-chart-index": i, style: { fill: cell.textColor }, children: cell.value })) : null] })) : null] }, cell.parentLabel ? `${cell.parentLabel}/${cell.datum.label}` : cell.datum.label))) }) }), _jsx(ChartDataList, { label: label, items: dataValueItems }), hoveredCell ? (_jsxs("div", { className: "st-treemapChart__tooltip", role: "presentation", style: {
173
+ left: `${((hoveredCell.rect.x + hoveredCell.rect.w / 2) / width) * 100}%`,
174
+ top: `${(hoveredCell.rect.y / height) * 100}%`,
175
+ }, children: [_jsx("span", { className: "st-treemapChart__tooltipLabel", children: hoveredCell.parentLabel
176
+ ? `${hoveredCell.parentLabel} · ${hoveredCell.datum.label}`
177
+ : hoveredCell.datum.label }), _jsx("span", { className: "st-treemapChart__tooltipValue", children: hoveredCell.value })] })) : null, legend && legendItems.length > 0 ? (_jsx("ul", { className: "st-treemapChart__legend", "aria-hidden": "true", children: legendItems.map((item) => (_jsxs("li", { className: "st-treemapChart__legendItem", children: [_jsx("span", { className: `st-treemapChart__legendSwatch st-treemapChart__legendSwatch--${item.tone}`, "aria-hidden": "true" }), item.label] }, item.label))) })) : null] }));
178
+ }
179
+ //# sourceMappingURL=TreemapChart.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TreemapChart.js","sourceRoot":"","sources":["../src/TreemapChart.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ import React from "react";
2
+ export type WaterfallType = "increase" | "decrease" | "total";
3
+ export type WaterfallChartDatum = {
4
+ label: string;
5
+ value: number;
6
+ type?: WaterfallType;
7
+ };
8
+ export type WaterfallChartProps = Omit<React.HTMLAttributes<HTMLDivElement>, "className"> & {
9
+ data: WaterfallChartDatum[];
10
+ width?: number;
11
+ height?: number;
12
+ connectors?: boolean;
13
+ format?: (value: number) => string;
14
+ label: string;
15
+ className?: string;
16
+ };
17
+ export declare function WaterfallChart({ data, width, height, connectors, format, label, className, ...rest }: WaterfallChartProps): import("react/jsx-runtime").JSX.Element;
18
+ //# sourceMappingURL=WaterfallChart.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"WaterfallChart.d.ts","sourceRoot":"","sources":["../src/WaterfallChart.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAI1B,MAAM,MAAM,aAAa,GAAG,UAAU,GAAG,UAAU,GAAG,OAAO,CAAC;AAE9D,MAAM,MAAM,mBAAmB,GAAG;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,aAAa,CAAC;CACtB,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC,EAAE,WAAW,CAAC,GAAG;IAC1F,IAAI,EAAE,mBAAmB,EAAE,CAAC;IAC5B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC;IACnC,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAUF,wBAAgB,cAAc,CAAC,EAC7B,IAAS,EACT,KAAW,EACX,MAAY,EACZ,UAAiB,EACjB,MAAM,EACN,KAAK,EACL,SAAS,EACT,GAAG,IAAI,EACR,EAAE,mBAAmB,2CA6PrB"}
@@ -0,0 +1,133 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import React from "react";
3
+ import { classNames } from "./classNames.js";
4
+ import { ChartDataList, formatTick, niceTicks, scaleLinear } from "./chartScale.js";
5
+ const MARGIN = { top: 12, right: 16, bottom: 32, left: 44 };
6
+ const LEGEND_ITEMS = [
7
+ { type: "increase", label: "Hausse" },
8
+ { type: "decrease", label: "Baisse" },
9
+ { type: "total", label: "Total" },
10
+ ];
11
+ export function WaterfallChart({ data = [], width = 480, height = 240, connectors = true, format, label, className, ...rest }) {
12
+ const [hoveredIndex, setHoveredIndex] = React.useState(null);
13
+ function formatValue(v) {
14
+ return format ? format(v) : formatTick(v);
15
+ }
16
+ // Resolve the floating start/end of each bar, accumulating running totals.
17
+ // - increase: la barre monte de +|value| depuis le cumul courant.
18
+ // - decrease: la barre descend de -|value| depuis le cumul courant.
19
+ // - total: barre repère ancrée à zéro montrant la valeur saisie ; elle
20
+ // recale le cumul courant (point de contrôle), de sorte que les connecteurs
21
+ // et les étapes suivantes repartent du total affiché.
22
+ const computed = (() => {
23
+ let cumulative = 0;
24
+ return data.map((d) => {
25
+ // Valeur non finie → traitée comme 0 (jamais de NaN dans la géométrie/ARIA).
26
+ const raw = Number.isFinite(d.value) ? d.value : 0;
27
+ const inferred = d.type ?? (raw >= 0 ? "increase" : "decrease");
28
+ let start;
29
+ let end;
30
+ let displayValue;
31
+ if (inferred === "total") {
32
+ start = 0;
33
+ end = raw;
34
+ cumulative = raw;
35
+ displayValue = raw;
36
+ }
37
+ else {
38
+ // Le signe est imposé par le type pour rester cohérent avec la légende.
39
+ const signed = inferred === "decrease" ? -Math.abs(raw) : Math.abs(raw);
40
+ start = cumulative;
41
+ end = cumulative + signed;
42
+ cumulative = end;
43
+ displayValue = signed;
44
+ }
45
+ const resolvedType = inferred === "total" ? "total" : end >= start ? "increase" : "decrease";
46
+ return { datum: d, type: resolvedType, start, end, displayValue, cumulative };
47
+ });
48
+ })();
49
+ const scales = (() => {
50
+ const bounds = computed.flatMap((c) => [c.start, c.end]);
51
+ const minRaw = Math.min(0, ...bounds);
52
+ const maxRaw = Math.max(0, ...bounds);
53
+ const ticks = niceTicks(minRaw, maxRaw, 5);
54
+ const domainMin = ticks[0];
55
+ const domainMax = ticks[ticks.length - 1];
56
+ const plotWidth = Math.max(width - MARGIN.left - MARGIN.right, 1);
57
+ const plotHeight = Math.max(height - MARGIN.top - MARGIN.bottom, 1);
58
+ return { ticks, domainMin, domainMax, plotWidth, plotHeight };
59
+ })();
60
+ const bars = (() => {
61
+ const { domainMin, domainMax, plotWidth, plotHeight } = scales;
62
+ if (computed.length === 0)
63
+ return [];
64
+ const band = plotWidth / computed.length;
65
+ const barWidth = band * 0.62;
66
+ return computed.map((c, i) => {
67
+ const startY = scaleLinear(c.start, domainMin, domainMax, plotHeight, 0);
68
+ const endY = scaleLinear(c.end, domainMin, domainMax, plotHeight, 0);
69
+ const y = Math.min(startY, endY);
70
+ const h = Math.abs(endY - startY);
71
+ const x = MARGIN.left + band * i + (band - barWidth) / 2;
72
+ return {
73
+ x,
74
+ y: MARGIN.top + y,
75
+ width: barWidth,
76
+ height: Math.max(h, 0.5),
77
+ topY: MARGIN.top + Math.min(startY, endY),
78
+ bottomY: MARGIN.top + Math.max(startY, endY),
79
+ cx: MARGIN.left + band * (i + 0.5),
80
+ cy: MARGIN.top + Math.min(startY, endY),
81
+ type: c.type,
82
+ datum: c.datum,
83
+ displayValue: c.displayValue,
84
+ cumulative: c.cumulative,
85
+ index: i,
86
+ };
87
+ });
88
+ })();
89
+ // Connector lines join the top edge of each bar to the next, tracing the running total.
90
+ const connectorLines = (() => {
91
+ if (!connectors || bars.length < 2)
92
+ return [];
93
+ const { domainMin, domainMax, plotHeight } = scales;
94
+ const lines = [];
95
+ for (let i = 0; i < computed.length - 1; i++) {
96
+ const level = computed[i].end;
97
+ const y = MARGIN.top + scaleLinear(level, domainMin, domainMax, plotHeight, 0);
98
+ // Le connecteur relie le bord droit de la barre i au bord gauche de i+1,
99
+ // au niveau du cumul courant.
100
+ lines.push({ x1: bars[i].x + bars[i].width, x2: bars[i + 1].x, y });
101
+ }
102
+ return lines;
103
+ })();
104
+ const valueAxisTicks = (() => {
105
+ const { ticks, domainMin, domainMax, plotWidth, plotHeight } = scales;
106
+ return ticks.map((tick) => ({
107
+ value: tick,
108
+ x1: MARGIN.left,
109
+ x2: MARGIN.left + plotWidth,
110
+ y: MARGIN.top + scaleLinear(tick, domainMin, domainMax, plotHeight, 0),
111
+ }));
112
+ })();
113
+ const zeroY = (() => {
114
+ const { domainMin, domainMax, plotHeight } = scales;
115
+ return MARGIN.top + scaleLinear(0, domainMin, domainMax, plotHeight, 0);
116
+ })();
117
+ const dataValueItems = computed.map((c) => `${c.datum.label}: ${formatValue(c.displayValue)}`);
118
+ function handleLeave() {
119
+ setHoveredIndex(null);
120
+ }
121
+ function handleVisualPointerMove(event) {
122
+ const target = event.target;
123
+ if (!(target instanceof Element)) {
124
+ setHoveredIndex(null);
125
+ return;
126
+ }
127
+ const index = Number(target.getAttribute("data-chart-index"));
128
+ setHoveredIndex(Number.isInteger(index) ? index : null);
129
+ }
130
+ const hoveredBar = hoveredIndex !== null ? bars[hoveredIndex] : undefined;
131
+ return (_jsxs("div", { ...rest, className: classNames("st-waterfallChart", className), children: [_jsx("div", { className: "st-waterfallChart__visual", role: "img", "aria-label": label, onPointerMove: handleVisualPointerMove, onPointerLeave: handleLeave, children: _jsxs("svg", { viewBox: `0 0 ${width} ${height}`, preserveAspectRatio: "xMidYMid meet", width: "100%", height: "100%", focusable: "false", "aria-hidden": "true", children: [valueAxisTicks.map((tick) => (_jsxs(React.Fragment, { children: [_jsx("line", { className: "st-waterfallChart__grid", x1: tick.x1, x2: tick.x2, y1: tick.y, y2: tick.y }), _jsx("text", { className: "st-waterfallChart__tickLabel", x: MARGIN.left - 6, y: tick.y, textAnchor: "end", dominantBaseline: "middle", children: formatTick(tick.value) })] }, tick.value))), _jsx("line", { className: "st-waterfallChart__axis", x1: MARGIN.left, x2: MARGIN.left, y1: MARGIN.top, y2: height - MARGIN.bottom }), _jsx("line", { className: "st-waterfallChart__axis", x1: MARGIN.left, x2: width - MARGIN.right, y1: height - MARGIN.bottom, y2: height - MARGIN.bottom }), _jsx("line", { className: "st-waterfallChart__zero", x1: MARGIN.left, x2: width - MARGIN.right, y1: zeroY, y2: zeroY }), connectorLines.map((line, i) => (_jsx("line", { className: "st-waterfallChart__connector", x1: line.x1, x2: line.x2, y1: line.y, y2: line.y }, i))), bars.map((bar) => (_jsx("text", { className: "st-waterfallChart__categoryLabel", x: bar.x + bar.width / 2, y: height - MARGIN.bottom + 16, textAnchor: "middle", children: bar.datum.label }, bar.datum.label))), bars.map((bar, i) => (_jsx("rect", { className: `st-waterfallChart__bar st-waterfallChart__bar--${bar.type}`, x: bar.x, y: bar.y, width: bar.width, height: bar.height, rx: "2", "data-chart-index": i }, bar.datum.label)))] }) }), _jsx(ChartDataList, { label: label, items: dataValueItems }), _jsx("ul", { className: "st-waterfallChart__legend", "aria-hidden": "true", children: LEGEND_ITEMS.map((item) => (_jsxs("li", { className: "st-waterfallChart__legendItem", children: [_jsx("span", { className: `st-waterfallChart__legendSwatch st-waterfallChart__legendSwatch--${item.type}` }), item.label] }, item.type))) }), hoveredBar ? (_jsxs("div", { className: "st-waterfallChart__tooltip", role: "presentation", style: { left: `${(hoveredBar.cx / width) * 100}%`, top: `${(hoveredBar.cy / height) * 100}%` }, children: [_jsx("span", { className: "st-waterfallChart__tooltipLabel", children: hoveredBar.datum.label }), _jsx("span", { className: "st-waterfallChart__tooltipValue", children: formatValue(hoveredBar.displayValue) })] })) : null] }));
132
+ }
133
+ //# sourceMappingURL=WaterfallChart.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"WaterfallChart.js","sourceRoot":"","sources":["../src/WaterfallChart.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Retourne la couleur de texte (`#ffffff` ou `#0f172a`) offrant le meilleur
3
+ * contraste sur un ton catégoriel. Inconnu/non catégoriel → texte clair.
4
+ */
5
+ export declare function contrastTextForTone(tone: string | undefined): string;
6
+ //# sourceMappingURL=chartContrast.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chartContrast.d.ts","sourceRoot":"","sources":["../src/chartContrast.ts"],"names":[],"mappings":"AAqDA;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAKpE"}
@@ -0,0 +1,59 @@
1
+ /**
2
+ * Couleur de texte contrastée pour les labels posés *sur* les couleurs
3
+ * catégorielles (`--st-semantic-data-category*`).
4
+ *
5
+ * Le texte blanc codé en dur échoue WCAG AA sur la plupart des tons clairs de
6
+ * la palette (jaune, rose, sarcelle…). Comme la palette catégorielle est
7
+ * identique sur tous les thèmes (Tableau 10), on peut pré-calculer la couleur
8
+ * de texte (clair vs foncé) qui maximise le contraste pour chaque ton.
9
+ *
10
+ * Valeurs de référence (sent-tech / forge / entropic — identiques) :
11
+ * category1 #4E79A7 category2 #F28E2B category3 #E15759 category4 #76B7B2
12
+ * category5 #59A14F category6 #EDC948 category7 #B07AA1 category8 #FF9DA7
13
+ *
14
+ * Seul `category1` (bleu foncé) atteint un contraste suffisant avec du blanc ;
15
+ * tous les autres tons exigent un texte foncé.
16
+ */
17
+ const CATEGORY_FILLS = {
18
+ category1: "#4E79A7",
19
+ category2: "#F28E2B",
20
+ category3: "#E15759",
21
+ category4: "#76B7B2",
22
+ category5: "#59A14F",
23
+ category6: "#EDC948",
24
+ category7: "#B07AA1",
25
+ category8: "#FF9DA7",
26
+ };
27
+ const LIGHT_TEXT = "#ffffff";
28
+ const DARK_TEXT = "#0f172a";
29
+ function channelToLinear(c) {
30
+ const s = c / 255;
31
+ return s <= 0.03928 ? s / 12.92 : Math.pow((s + 0.055) / 1.055, 2.4);
32
+ }
33
+ /** Luminance relative WCAG d'une couleur `#rrggbb`. */
34
+ function relativeLuminance(hex) {
35
+ const n = parseInt(hex.slice(1), 16);
36
+ const r = channelToLinear((n >> 16) & 0xff);
37
+ const g = channelToLinear((n >> 8) & 0xff);
38
+ const b = channelToLinear(n & 0xff);
39
+ return 0.2126 * r + 0.7152 * g + 0.0722 * b;
40
+ }
41
+ function contrastRatio(l1, l2) {
42
+ const lighter = Math.max(l1, l2);
43
+ const darker = Math.min(l1, l2);
44
+ return (lighter + 0.05) / (darker + 0.05);
45
+ }
46
+ const LIGHT_LUM = relativeLuminance(LIGHT_TEXT);
47
+ const DARK_LUM = relativeLuminance(DARK_TEXT);
48
+ /**
49
+ * Retourne la couleur de texte (`#ffffff` ou `#0f172a`) offrant le meilleur
50
+ * contraste sur un ton catégoriel. Inconnu/non catégoriel → texte clair.
51
+ */
52
+ export function contrastTextForTone(tone) {
53
+ const fill = tone ? CATEGORY_FILLS[tone] : undefined;
54
+ if (!fill)
55
+ return LIGHT_TEXT;
56
+ const bg = relativeLuminance(fill);
57
+ return contrastRatio(bg, DARK_LUM) >= contrastRatio(bg, LIGHT_LUM) ? DARK_TEXT : LIGHT_TEXT;
58
+ }
59
+ //# sourceMappingURL=chartContrast.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chartContrast.js","sourceRoot":"","sources":["../src/chartContrast.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,MAAM,cAAc,GAA2B;IAC7C,SAAS,EAAE,SAAS;IACpB,SAAS,EAAE,SAAS;IACpB,SAAS,EAAE,SAAS;IACpB,SAAS,EAAE,SAAS;IACpB,SAAS,EAAE,SAAS;IACpB,SAAS,EAAE,SAAS;IACpB,SAAS,EAAE,SAAS;IACpB,SAAS,EAAE,SAAS;CACrB,CAAC;AAEF,MAAM,UAAU,GAAG,SAAS,CAAC;AAC7B,MAAM,SAAS,GAAG,SAAS,CAAC;AAE5B,SAAS,eAAe,CAAC,CAAS;IAChC,MAAM,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC;IAClB,OAAO,CAAC,IAAI,OAAO,CAAC,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,GAAG,KAAK,EAAE,GAAG,CAAC,CAAC;AACvE,CAAC;AAED,uDAAuD;AACvD,SAAS,iBAAiB,CAAC,GAAW;IACpC,MAAM,CAAC,GAAG,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IACrC,MAAM,CAAC,GAAG,eAAe,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,GAAG,IAAI,CAAC,CAAC;IAC5C,MAAM,CAAC,GAAG,eAAe,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;IAC3C,MAAM,CAAC,GAAG,eAAe,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;IACpC,OAAO,MAAM,GAAG,CAAC,GAAG,MAAM,GAAG,CAAC,GAAG,MAAM,GAAG,CAAC,CAAC;AAC9C,CAAC;AAED,SAAS,aAAa,CAAC,EAAU,EAAE,EAAU;IAC3C,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;IACjC,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;IAChC,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;AAC5C,CAAC;AAED,MAAM,SAAS,GAAG,iBAAiB,CAAC,UAAU,CAAC,CAAC;AAChD,MAAM,QAAQ,GAAG,iBAAiB,CAAC,SAAS,CAAC,CAAC;AAE9C;;;GAGG;AACH,MAAM,UAAU,mBAAmB,CAAC,IAAwB;IAC1D,MAAM,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IACrD,IAAI,CAAC,IAAI;QAAE,OAAO,UAAU,CAAC;IAC7B,MAAM,EAAE,GAAG,iBAAiB,CAAC,IAAI,CAAC,CAAC;IACnC,OAAO,aAAa,CAAC,EAAE,EAAE,QAAQ,CAAC,IAAI,aAAa,CAAC,EAAE,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,UAAU,CAAC;AAC9F,CAAC"}