@synertech/ui 0.40.1 → 0.42.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.
- package/.claude/skills/use-synertech-ui/SKILL.md +178 -0
- package/dist/index.cjs +10 -10
- package/dist/index.d.cts +1193 -33
- package/dist/index.d.ts +1193 -33
- package/dist/index.js +10 -10
- package/dist/styles.css +134 -0
- package/package.json +2 -2
|
@@ -156,6 +156,16 @@ import { cn } from "@synertech/ui";
|
|
|
156
156
|
- `ScatterChart` - Corrélation entre deux variables numériques (3 séries max)
|
|
157
157
|
- `StatCard` / `StatCardGroup` - Valeur unique avec variation et sparkline
|
|
158
158
|
- `Sparkline` - Courbe sans axe, pour une cellule ou une carte
|
|
159
|
+
- `Heatmap` - Une grandeur sur une grille (jour × heure, cohortes, matrice)
|
|
160
|
+
- `BulletChart` - Réalisé, objectif et plages qualitatives sur une seule ligne
|
|
161
|
+
- `ChartFacets` - Petits multiples : un même graphique répété, à échelle partagée
|
|
162
|
+
- `ChartScaleLegend` - La légende d'une rampe de couleur
|
|
163
|
+
- `WaterfallChart` - Comment on passe de A à B : chaque contribution, positive ou négative
|
|
164
|
+
- `FunnelChart` - Des étapes ordonnées et leur déperdition (rampe ordinale)
|
|
165
|
+
- `DumbbellChart` - Avant → après par élément, ou une plage min–max
|
|
166
|
+
- `BoxPlot` - Médiane, quartiles, moustaches et valeurs aberrantes
|
|
167
|
+
- `CandlestickChart` - Ouverture, haut, bas, clôture (couleurs de statut)
|
|
168
|
+
- `GanttChart` - Des tâches dans le temps, avec dépendances et jalons
|
|
159
169
|
|
|
160
170
|
### Feedback & Overlays
|
|
161
171
|
|
|
@@ -586,6 +596,26 @@ const data = [
|
|
|
586
596
|
showValues
|
|
587
597
|
/>
|
|
588
598
|
|
|
599
|
+
// Barres divergentes : l'écart à une référence
|
|
600
|
+
<BarChart
|
|
601
|
+
data={gaps}
|
|
602
|
+
x={{ key: "region" }}
|
|
603
|
+
series={[{ key: "gap" }]}
|
|
604
|
+
orientation="horizontal"
|
|
605
|
+
diverging // true | un nombre (le centre) | une clé de série
|
|
606
|
+
y={{ label: "Écart à la cible (%)" }}
|
|
607
|
+
/>
|
|
608
|
+
|
|
609
|
+
// Échelle d'accord : la série nommée est à cheval sur le centre
|
|
610
|
+
<BarChart
|
|
611
|
+
data={survey}
|
|
612
|
+
x={{ key: "question" }}
|
|
613
|
+
series={[{ key: "awful" }, { key: "bad" }, { key: "ok" }, { key: "good" }, { key: "great" }]}
|
|
614
|
+
orientation="horizontal"
|
|
615
|
+
stack="stacked"
|
|
616
|
+
diverging="ok"
|
|
617
|
+
/>
|
|
618
|
+
|
|
589
619
|
// Camembert ou anneau
|
|
590
620
|
<PieChart
|
|
591
621
|
data={sources}
|
|
@@ -604,6 +634,118 @@ const data = [
|
|
|
604
634
|
bubble={{ key: "clients", range: [4, 18] }}
|
|
605
635
|
trendLine
|
|
606
636
|
/>
|
|
637
|
+
|
|
638
|
+
// Histogramme — `bins` lit x.key comme une mesure, la range et la compte
|
|
639
|
+
<BarChart
|
|
640
|
+
data={sessions} // [{ duration: 42 }, { duration: 118 }, ...]
|
|
641
|
+
x={{ key: "duration", label: "Durée (s)" }}
|
|
642
|
+
series={[{ key: "sessions", label: "Sessions" }]} // nomme le COMPTE
|
|
643
|
+
bins={12} // ou true (auto), ou [0, 15, 30, 60, 120]
|
|
644
|
+
/>
|
|
645
|
+
|
|
646
|
+
// Barres + ligne — une série typée, un seul axe
|
|
647
|
+
<BarChart
|
|
648
|
+
data={monthly}
|
|
649
|
+
x={{ key: "month" }}
|
|
650
|
+
series={[
|
|
651
|
+
{ key: "commandes", label: "Commandes" },
|
|
652
|
+
{ key: "retours", label: "Retours", type: "line" },
|
|
653
|
+
]}
|
|
654
|
+
curve="monotone"
|
|
655
|
+
/>
|
|
656
|
+
```
|
|
657
|
+
|
|
658
|
+
```tsx
|
|
659
|
+
// Carte de chaleur — une ligne de données par case
|
|
660
|
+
<Heatmap
|
|
661
|
+
data={load} // [{ day, hour, sessions }, ...]
|
|
662
|
+
x={{ key: "hour", label: "Heure" }}
|
|
663
|
+
y={{ key: "day", label: "Jour" }}
|
|
664
|
+
value="sessions"
|
|
665
|
+
scale="sequential" // "sequential" | "diverging" (+ center)
|
|
666
|
+
steps={undefined} // la rampe reste continue tant qu'on ne la découpe pas
|
|
667
|
+
legendLabel="Sessions" // la légende d'échelle est affichée par défaut
|
|
668
|
+
showValues
|
|
669
|
+
tableView="toggle" // la grille pivotée : une ligne par catégorie de rangée
|
|
670
|
+
/>
|
|
671
|
+
|
|
672
|
+
// Graphique à puce — réalisé, objectif, plages
|
|
673
|
+
<BulletChart
|
|
674
|
+
data={[{ measure: "Revenu", value: 38400, target: 42000, bands: [20000, 34000, 50000] }]}
|
|
675
|
+
x={{ key: "measure" }}
|
|
676
|
+
value="value"
|
|
677
|
+
target="target"
|
|
678
|
+
ranges="bands" // bornes croissantes, peintes en gris derrière la barre
|
|
679
|
+
normalize="row" // "row" (par défaut) | "shared" → ramène l'axe des valeurs
|
|
680
|
+
/>
|
|
681
|
+
|
|
682
|
+
// Cascade — chaque pas flotte entre le cumul avant et après lui
|
|
683
|
+
<WaterfallChart
|
|
684
|
+
data={budget} // [{ poste, montant, jalon? }, ...]
|
|
685
|
+
x={{ key: "poste" }}
|
|
686
|
+
value="montant"
|
|
687
|
+
total="jalon" // ligne de contrôle dessinée depuis zéro
|
|
688
|
+
start={0} // cumul d'ouverture
|
|
689
|
+
/>
|
|
690
|
+
|
|
691
|
+
// Tunnel — étapes ORDONNÉES, donc rampe ordinale (jamais les créneaux)
|
|
692
|
+
<FunnelChart
|
|
693
|
+
data={stages} // [{ etape, utilisateurs }, ...]
|
|
694
|
+
x={{ key: "etape" }}
|
|
695
|
+
value="utilisateurs"
|
|
696
|
+
align="center" // "center" (silhouette) | "left" (comparaison)
|
|
697
|
+
showConversion // le ratio d'un pas au suivant : le constat
|
|
698
|
+
/>
|
|
699
|
+
|
|
700
|
+
// Haltère — avant → après, ou une plage. L'écart EST la marque
|
|
701
|
+
<DumbbellChart
|
|
702
|
+
data={satisfaction}
|
|
703
|
+
x={{ key: "service" }}
|
|
704
|
+
series={[{ key: "avant", label: "2025" }, { key: "apres", label: "2026" }]}
|
|
705
|
+
sort="gap" // les plus gros mouvements en tête
|
|
706
|
+
/>
|
|
707
|
+
|
|
708
|
+
// Boîte à moustaches — `values` (observations) ou `quantiles` (résumé)
|
|
709
|
+
<BoxPlot
|
|
710
|
+
data={teams} // [{ equipe, durees: [12, 14, ...] }, ...]
|
|
711
|
+
x={{ key: "equipe" }}
|
|
712
|
+
values="durees" // moustaches de Tukey + aberrations calculées
|
|
713
|
+
showMean // le losange : l'écart moyenne/médiane = la queue
|
|
714
|
+
/>
|
|
715
|
+
|
|
716
|
+
// Chandeliers — couleurs de statut + corps creux/plein, jamais la teinte seule
|
|
717
|
+
<CandlestickChart
|
|
718
|
+
data={sessions}
|
|
719
|
+
x={{ key: "jour" }}
|
|
720
|
+
open="ouverture" high="haut" low="bas" close="cloture"
|
|
721
|
+
/>
|
|
722
|
+
|
|
723
|
+
// Planning — dates, dépendances, jalons. Ce n'est pas un `Calendar`
|
|
724
|
+
<GanttChart
|
|
725
|
+
data={project}
|
|
726
|
+
x={{ key: "tache" }}
|
|
727
|
+
start="debut" end="fin"
|
|
728
|
+
id="id" dependencies="depend" // les flèches : ce qui bloque quoi
|
|
729
|
+
progress="avancement" // 0 à 1
|
|
730
|
+
milestone="jalon"
|
|
731
|
+
group="lot" // un créneau de palette par lot
|
|
732
|
+
today="2026-04-14"
|
|
733
|
+
/>
|
|
734
|
+
|
|
735
|
+
// Petits multiples — le domaine est calculé sur l'ensemble et imposé à chaque panneau
|
|
736
|
+
<ChartFacets data={rows} by="region" values={["revenue"]} columns={3}>
|
|
737
|
+
{({ data, domain, label }) => (
|
|
738
|
+
<LineChart
|
|
739
|
+
data={data}
|
|
740
|
+
series={[{ key: "revenue" }]}
|
|
741
|
+
x={{ key: "month" }}
|
|
742
|
+
y={{ domain }} // ← toujours le passer, c'est tout l'intérêt
|
|
743
|
+
plotLabel={label}
|
|
744
|
+
height={130}
|
|
745
|
+
legend={false}
|
|
746
|
+
/>
|
|
747
|
+
)}
|
|
748
|
+
</ChartFacets>
|
|
607
749
|
```
|
|
608
750
|
|
|
609
751
|
**Ce que les composants refusent de faire, et pourquoi :**
|
|
@@ -617,6 +759,33 @@ const data = [
|
|
|
617
759
|
Un nuage de points s'arrête à 3 séries.
|
|
618
760
|
- **`PieChart` n'est pas fait pour comparer des valeurs proches** — l'œil compare
|
|
619
761
|
mal des angles. Deux parts, c'est une `StatCard`.
|
|
762
|
+
- **La palette catégorielle ne peint pas une grandeur.** Les huit créneaux
|
|
763
|
+
répondent à « lequel » ; une rampe répond à « combien ». Dès qu'une couleur
|
|
764
|
+
encode une grandeur, la légende d'échelle est obligatoire.
|
|
765
|
+
- **Une `Heatmap` ne se découpe pas au-delà de 7 classes de couleur** — les cases
|
|
766
|
+
voisines cessent d'être distinguables. Sans `steps`, la rampe reste continue.
|
|
767
|
+
- **Les panneaux d'un `ChartFacets` partagent leur domaine.** Des échelles libres
|
|
768
|
+
ont l'air comparables et ne le sont pas : passez toujours le `domain` reçu.
|
|
769
|
+
- **La rampe divergente dit un sens, pas un jugement.** « Au-dessus » n'est pas
|
|
770
|
+
« bon » : un délai qui glisse est au-dessus. Le jugement appartient aux
|
|
771
|
+
couleurs de statut, toujours accompagnées d'un libellé.
|
|
772
|
+
- **Un `BarChart` combiné garde un seul axe.** Une série `type: "line"` partage
|
|
773
|
+
l'échelle des barres. Deux axes laissent deux mesures étrangères se croiser
|
|
774
|
+
là où le cadrage les place, ce qui se lit comme une corrélation inventée.
|
|
775
|
+
- **Un histogramme ne se trie pas.** `sort`, `stack` et `diverging` sont ignorés
|
|
776
|
+
avec `bins` : les seaux ont un ordre, et le réordonner détruit la forme.
|
|
777
|
+
- **Un tunnel encode une longueur, pas une surface.** Le trapèze classique
|
|
778
|
+
demande de comparer deux surfaces, ce que l'œil ne sait pas faire.
|
|
779
|
+
- **Un `BoxPlot` nourri d'un résumé ne dessine aucune valeur aberrante.** Les
|
|
780
|
+
bornes de Tukey ont besoin des observations ; le composant préfère ne rien
|
|
781
|
+
affirmer plutôt qu'inventer.
|
|
782
|
+
- **`DumbbellChart` et `BoxPlot` ne s'ancrent pas à zéro.** Ils se lisent à un
|
|
783
|
+
écart et à un étalement, pas à la longueur d'une marque depuis une base.
|
|
784
|
+
- **`CandlestickChart` porte le sens deux fois** : couleur de statut ET corps
|
|
785
|
+
creux (hausse) contre plein (baisse). Vert contre rouge est la pire paire
|
|
786
|
+
sous déficience de vision des couleurs.
|
|
787
|
+
- **`GanttChart` n'est pas un `Calendar`.** Le calendrier sélectionne une date
|
|
788
|
+
et la renvoie ; le planning se lit. Une ligne sans largeur est un jalon.
|
|
620
789
|
|
|
621
790
|
### Cartes KPI
|
|
622
791
|
|
|
@@ -653,9 +822,18 @@ tout le kit sur une charte :
|
|
|
653
822
|
--color-chart-1: #0f766e;
|
|
654
823
|
--color-chart-2: #b45309;
|
|
655
824
|
/* ... jusqu'à 8 */
|
|
825
|
+
|
|
826
|
+
/* Les trois rampes de grandeur, si le kit en affiche */
|
|
827
|
+
--color-chart-seq-1: #e0f2f1; /* ... jusqu'à 6, du clair au foncé */
|
|
828
|
+
--color-chart-ord-1: #4db6ac; /* ... jusqu'à 5, paliers ordonnés */
|
|
829
|
+
--color-chart-div-1: #00695c; /* ... jusqu'à 7, milieu neutre au 4 */
|
|
656
830
|
}
|
|
657
831
|
```
|
|
658
832
|
|
|
833
|
+
Redéfinissez-les aussi sous `:root.dark` / `[data-theme="dark"]` : les rampes
|
|
834
|
+
sombres du kit ne sont pas les claires éclaircies, elles courent en sens inverse
|
|
835
|
+
(sur fond sombre, « plus » doit s'éloigner du fond).
|
|
836
|
+
|
|
659
837
|
### Card (Composable)
|
|
660
838
|
|
|
661
839
|
```tsx
|