@synertech/ui 0.42.0 → 0.44.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 +139 -1
- package/dist/index.cjs +10 -9
- package/dist/index.d.cts +1096 -55
- package/dist/index.d.ts +1096 -55
- package/dist/index.js +10 -9
- package/dist/styles.css +55 -0
- package/package.json +1 -1
|
@@ -160,12 +160,17 @@ import { cn } from "@synertech/ui";
|
|
|
160
160
|
- `BulletChart` - Réalisé, objectif et plages qualitatives sur une seule ligne
|
|
161
161
|
- `ChartFacets` - Petits multiples : un même graphique répété, à échelle partagée
|
|
162
162
|
- `ChartScaleLegend` - La légende d'une rampe de couleur
|
|
163
|
+
- `ChartFilterBar` - Les filtres en une rangée au-dessus des graphiques qu'ils cadrent
|
|
164
|
+
- `ChartPeriodPicker` - La fenêtre d'un tableau de bord : préréglages nommés + calendrier
|
|
163
165
|
- `WaterfallChart` - Comment on passe de A à B : chaque contribution, positive ou négative
|
|
164
166
|
- `FunnelChart` - Des étapes ordonnées et leur déperdition (rampe ordinale)
|
|
165
167
|
- `DumbbellChart` - Avant → après par élément, ou une plage min–max
|
|
166
168
|
- `BoxPlot` - Médiane, quartiles, moustaches et valeurs aberrantes
|
|
167
169
|
- `CandlestickChart` - Ouverture, haut, bas, clôture (couleurs de statut)
|
|
168
170
|
- `GanttChart` - Des tâches dans le temps, avec dépendances et jalons
|
|
171
|
+
- `ChartSyncProvider` - Plusieurs panneaux qui se lisent comme un seul objet :
|
|
172
|
+
survol partagé et fenêtre brossée en commun
|
|
173
|
+
- `ChartExportButton` - Le tableau du graphique en CSV ou JSON
|
|
169
174
|
|
|
170
175
|
### Feedback & Overlays
|
|
171
176
|
|
|
@@ -550,7 +555,10 @@ Tous les graphiques partagent la même forme de données : un tableau de lignes
|
|
|
550
555
|
et des séries qui pointent un champ, exactement comme `DataGrid`.
|
|
551
556
|
|
|
552
557
|
```tsx
|
|
553
|
-
import {
|
|
558
|
+
import {
|
|
559
|
+
LineChart, AreaChart, BarChart, PieChart, ScatterChart,
|
|
560
|
+
ChartSyncProvider, ChartExportButton, brushToPeriod,
|
|
561
|
+
} from "@synertech/ui";
|
|
554
562
|
|
|
555
563
|
const data = [
|
|
556
564
|
{ month: "Jan", revenue: 18400, cost: 12200 },
|
|
@@ -732,6 +740,99 @@ const data = [
|
|
|
732
740
|
today="2026-04-14"
|
|
733
741
|
/>
|
|
734
742
|
|
|
743
|
+
// Annotations — ce qui s'est passé, dessiné là où ça s'est passé
|
|
744
|
+
// (`referenceLines` = un seuil sur l'axe des valeurs ; les annotations = un
|
|
745
|
+
// moment sur l'axe des catégories. Lisible sur LineChart, AreaChart, BarChart)
|
|
746
|
+
<LineChart
|
|
747
|
+
data={monthly}
|
|
748
|
+
series={[{ key: "revenue" }]}
|
|
749
|
+
x={{ key: "month" }}
|
|
750
|
+
annotations={[
|
|
751
|
+
{ type: "band", from: "Fév", to: "Mar", label: "Campagne" },
|
|
752
|
+
{ type: "line", x: "Mai", label: "Refonte du tunnel" },
|
|
753
|
+
{ type: "point", x: "Août", y: 39900, label: "Record" },
|
|
754
|
+
]}
|
|
755
|
+
/>
|
|
756
|
+
|
|
757
|
+
// Trames — le canal de secours quand la teinte échoue (CVD sévère, impression
|
|
758
|
+
// en niveaux de gris, forced-colors). Jamais par défaut : c'est de l'a11y
|
|
759
|
+
<BarChart data={channels} series={channelSeries} x={{ key: "quarter" }} stack="stacked" patterns />
|
|
760
|
+
|
|
761
|
+
// La rangée de filtres — une seule, au-dessus de TOUS les graphiques
|
|
762
|
+
<ChartFilterBar actions={<Button size="sm">Exporter</Button>}>
|
|
763
|
+
<ChartPeriodPicker size="sm" value={period} onChange={setPeriod} />
|
|
764
|
+
<Select size="sm" options={regions} value={region} onValueChange={setRegion} />
|
|
765
|
+
</ChartFilterBar>
|
|
766
|
+
|
|
767
|
+
// L'état d'erreur — distinct de l'état vide, sur TOUS les graphiques du kit
|
|
768
|
+
// (« il n'y a rien » et « on n'a pas réussi à charger » sont deux affirmations
|
|
769
|
+
// différentes ; seule la seconde appelle une reprise)
|
|
770
|
+
<LineChart
|
|
771
|
+
data={rows}
|
|
772
|
+
series={series}
|
|
773
|
+
x={{ key: "month" }}
|
|
774
|
+
loading={query.isFetching}
|
|
775
|
+
error={query.isError}
|
|
776
|
+
onRetry={() => query.refetch()}
|
|
777
|
+
/>
|
|
778
|
+
|
|
779
|
+
// L'export — le tableau exact du graphique, dans la fente `actions`
|
|
780
|
+
<LineChart
|
|
781
|
+
data={rows}
|
|
782
|
+
series={series}
|
|
783
|
+
x={{ key: "month", label: "Mois" }}
|
|
784
|
+
actions={
|
|
785
|
+
<ChartExportButton
|
|
786
|
+
data={rows}
|
|
787
|
+
series={series}
|
|
788
|
+
xKey="month"
|
|
789
|
+
xLabel="Mois"
|
|
790
|
+
filename="revenus"
|
|
791
|
+
size="sm"
|
|
792
|
+
/>
|
|
793
|
+
}
|
|
794
|
+
/>
|
|
795
|
+
|
|
796
|
+
// La trappe d'évasion — dessiner DANS le tracé, avec les échelles du graphique
|
|
797
|
+
// (Line, Area, Bar, Scatter. Une fonction dessine par-dessus les marques ;
|
|
798
|
+
// `{ under, over }` atteint aussi le dessous. Coordonnées relatives à la zone
|
|
799
|
+
// de dessin, et sans clip : la marge est à la charge de l'appelant)
|
|
800
|
+
<LineChart
|
|
801
|
+
data={rows}
|
|
802
|
+
series={series}
|
|
803
|
+
x={{ key: "month" }}
|
|
804
|
+
y={{ domain: [100, 230] }} // ← réserver la place de l'annotation
|
|
805
|
+
overlay={({ xAt, yAt, dimensions }) => (
|
|
806
|
+
<rect
|
|
807
|
+
x={0}
|
|
808
|
+
y={yAt(200)}
|
|
809
|
+
width={dimensions.innerWidth}
|
|
810
|
+
height={Math.abs(yAt(160) - yAt(200))}
|
|
811
|
+
className="fill-green-500"
|
|
812
|
+
opacity={0.1}
|
|
813
|
+
/>
|
|
814
|
+
)}
|
|
815
|
+
/>
|
|
816
|
+
|
|
817
|
+
// La volumétrie — allège le TRACÉ, jamais les données
|
|
818
|
+
// (LTTB sur Line/Area, échantillon régulier sur Scatter. Le tableau, l'infobulle
|
|
819
|
+
// et la droite de tendance continuent de lire chaque ligne)
|
|
820
|
+
<LineChart data={fiftyThousandRows} series={series} x={{ key: "t", scale: "linear" }} maxPoints={400} />
|
|
821
|
+
|
|
822
|
+
// Le tableau de bord synchronisé — un pointeur, une infobulle ; une plage, toutes
|
|
823
|
+
// les cartes. `brushToPeriod` rend la fenêtre au `ChartPeriodPicker`
|
|
824
|
+
<ChartSyncProvider brush={null} onBrushChange={(range) => {
|
|
825
|
+
const next = range && brushToPeriod(range);
|
|
826
|
+
if (next) setPeriod(next);
|
|
827
|
+
}}>
|
|
828
|
+
<ChartFilterBar>
|
|
829
|
+
<ChartPeriodPicker size="sm" value={period} onChange={setPeriod} />
|
|
830
|
+
</ChartFilterBar>
|
|
831
|
+
|
|
832
|
+
<LineChart data={rows} series={series} x={xAxis} brush />
|
|
833
|
+
<BarChart data={rows} series={series} x={{ key: "day" }} />
|
|
834
|
+
</ChartSyncProvider>
|
|
835
|
+
|
|
735
836
|
// Petits multiples — le domaine est calculé sur l'ensemble et imposé à chaque panneau
|
|
736
837
|
<ChartFacets data={rows} by="region" values={["revenue"]} columns={3}>
|
|
737
838
|
{({ data, domain, label }) => (
|
|
@@ -786,6 +887,43 @@ const data = [
|
|
|
786
887
|
sous déficience de vision des couleurs.
|
|
787
888
|
- **`GanttChart` n'est pas un `Calendar`.** Le calendrier sélectionne une date
|
|
788
889
|
et la renvoie ; le planning se lit. Une ligne sans largeur est un jalon.
|
|
890
|
+
- **Les filtres vivent dans UNE rangée, au-dessus des graphiques.** Jamais dans
|
|
891
|
+
une carte, jamais par graphique : deux panneaux filtrés séparément répondent à
|
|
892
|
+
deux questions et rien à l'écran ne le dit.
|
|
893
|
+
- **Les trames ne sont jamais activées par défaut.** C'est une option
|
|
894
|
+
d'accessibilité, pas une décoration — et elles ne peignent que des identités :
|
|
895
|
+
une rampe (Heatmap, `diverging`, tunnel) encode une grandeur, ce qu'aucune
|
|
896
|
+
trame ne sait dire.
|
|
897
|
+
- **Les annotations se lisent sur l'axe des catégories.** Un `BarChart`
|
|
898
|
+
horizontal les ignore, avec un avertissement : un moment placé sur une liste
|
|
899
|
+
de noms n'en est plus un.
|
|
900
|
+
- **`error` n'est jamais `empty`.** Un panneau qui affiche « Aucune donnée »
|
|
901
|
+
après une requête échouée affirme quelque chose de faux, et ne propose aucune
|
|
902
|
+
sortie. `loading` l'emporte sur les deux : une reprise remplace le message par
|
|
903
|
+
le voyant.
|
|
904
|
+
- **Rien n'est décimé tout seul.** Un graphique qui dessinerait en douce une
|
|
905
|
+
autre forme que celle qu'on lui a remise serait pire qu'un graphique lent :
|
|
906
|
+
au-delà de 2 000 points il avertit, et `maxPoints` est à vous. Il n'allège
|
|
907
|
+
que le tracé — le tableau garde chaque ligne.
|
|
908
|
+
- **`BarChart` n'a pas de `maxPoints`.** Décimer des barres, c'est supprimer des
|
|
909
|
+
catégories : `bins` est la réponse là-bas.
|
|
910
|
+
- **`ScatterChart` échantillonne régulièrement, pas en LTTB.** Un nuage se lit à
|
|
911
|
+
sa densité ; garder les plus grands triangles en découperait l'enveloppe et
|
|
912
|
+
jetterait précisément ce qu'on regarde.
|
|
913
|
+
- **`overlay` n'est pas `children`.** Les graphiques restent des objets fermés ;
|
|
914
|
+
la trappe remet la géométrie résolue et rien d'autre. C'est elle qui rend
|
|
915
|
+
défendable chaque refus de cette liste — « prenez un `BarChart` groupé » ne
|
|
916
|
+
tient que si l'application peut dessiner ce qu'elle n'obtiendra jamais du kit.
|
|
917
|
+
- **Un `ScatterChart` ne se brosse pas.** Ses deux axes sont des mesures, et une
|
|
918
|
+
fenêtre sur l'une d'elles n'est pas le geste qu'un nuage appelle.
|
|
919
|
+
- **Une plage se pose aussi au clavier.** Maj + flèches l'étend, Échap la retire :
|
|
920
|
+
un filtre qui ne s'atteint qu'à la souris est inaccessible à la moitié des
|
|
921
|
+
lecteurs.
|
|
922
|
+
- **Une fenêtre qui a déjà recadré le tableau de bord n'a plus à être teintée.**
|
|
923
|
+
Les panneaux SONT la fenêtre ; la bande lave alors chaque tracé de bord à bord
|
|
924
|
+
et n'énonce rien. Repassez `brush={null}` après l'avoir appliquée.
|
|
925
|
+
- **L'export écrit les mesures brutes.** Ce qui ouvre le fichier va calculer
|
|
926
|
+
dessus, et `1 234,5 $` est une chaîne. Seule la catégorie est formatée.
|
|
789
927
|
|
|
790
928
|
### Cartes KPI
|
|
791
929
|
|