@sia-ui/react-web 0.5.0 → 0.7.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/dist/index.d.cts CHANGED
@@ -1,10 +1,10 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
  import * as react from 'react';
3
- import { ReactNode, ReactElement, HTMLAttributes, RefObject, ImgHTMLAttributes, ButtonHTMLAttributes, InputHTMLAttributes, Key, TextareaHTMLAttributes, ForwardRefExoticComponent, RefAttributes, SVGProps, CSSProperties, PropsWithChildren } from 'react';
4
- import { ComponentTone, ComponentSize } from '@sia-ui/tokens';
3
+ import { ReactNode, Key, RefObject, ReactElement, HTMLAttributes, ImgHTMLAttributes, ButtonHTMLAttributes, InputHTMLAttributes, TextareaHTMLAttributes, ForwardRefExoticComponent, RefAttributes, SVGProps, CSSProperties, PropsWithChildren } from 'react';
5
4
  import * as _sia_ui_headless from '@sia-ui/headless';
6
- import { PermissionRule, Placement, SliderValue, FormAdapter, FormValidator, FormSubmitResult, TableQueryStorage, TableQueryState, TableQuery, SessionStore, SessionState, ToastPlacement, ToastId, ToastOptions } from '@sia-ui/headless';
5
+ import { PermissionRule, Placement, TableQuery, SliderValue, FormAdapter, FormValidator, FormSubmitResult, TableQueryStorage, TableQueryState, TableParamsMapping, SessionStore, SessionState, ToastPlacement, ToastId, ToastOptions } from '@sia-ui/headless';
7
6
  export { SliderValue, ToastId, ToastOptions, ToastPlacement, ToastTone, toast, toastStore } from '@sia-ui/headless';
7
+ import { ComponentTone, ComponentSize } from '@sia-ui/tokens';
8
8
  import { Rule } from '@sia-ui/utils/validation';
9
9
 
10
10
  interface AccordionItem {
@@ -54,6 +54,330 @@ interface CollapseProps {
54
54
  /** Une section seule. Le même rendu, pour le cas le plus courant. */
55
55
  declare function Collapse({ title, children, description, meta, icon, open, defaultOpen, onOpenChange, variant, disabled, className, }: CollapseProps): react_jsx_runtime.JSX.Element;
56
56
 
57
+ /** Liste dense, ou grille de cartes. */
58
+ type DataTableView = "table" | "cards";
59
+ /**
60
+ * Le rôle d'une colonne dans la carte.
61
+ *
62
+ * `title` sert d'en-tête — la première colonne le prend si rien n'est
63
+ * déclaré. `meta` s'affiche en paire libellé / valeur. `hidden` reste au
64
+ * tableau seul : une carte qui recopie douze colonnes n'est plus une carte.
65
+ */
66
+ type ColumnCardRole = "title" | "meta" | "hidden";
67
+ interface DataTableColumn<T> {
68
+ key: string;
69
+ header: ReactNode;
70
+ /**
71
+ * Où lire la valeur : une clé de l'objet, ou une fonction pour les valeurs
72
+ * calculées. Sert au rendu par défaut, à la carte et à la recherche locale.
73
+ */
74
+ accessor?: keyof T | ((row: T) => unknown);
75
+ /** Rendu personnalisé. Prioritaire sur `accessor`. */
76
+ cell?: (row: T, index: number) => ReactNode;
77
+ align?: "start" | "center" | "end";
78
+ /**
79
+ * Largeur suggérée — `120px`, `20%`.
80
+ *
81
+ * En `layout="auto"` (défaut) le navigateur n'y voit qu'une indication.
82
+ * Pour qu'elle soit tenue, passer en `layout="fixed"`.
83
+ */
84
+ width?: string;
85
+ minWidth?: string;
86
+ /** Coupe au lieu d'élargir. Indispensable en `layout="fixed"`. */
87
+ truncate?: boolean;
88
+ /** Retire la colonne du tableau sans toucher à la carte. */
89
+ hidden?: boolean;
90
+ /** Rend l'en-tête cliquable. Le tri lui-même reste au serveur. */
91
+ sortable?: boolean;
92
+ /** Le champ envoyé au serveur, si différent de `key`. */
93
+ sortKey?: string;
94
+ /** Place de la colonne dans la carte. */
95
+ card?: ColumnCardRole;
96
+ headerClassName?: string;
97
+ cellClassName?: string;
98
+ }
99
+ interface RowAction<T> {
100
+ key: string;
101
+ label: ReactNode;
102
+ icon?: ReactNode;
103
+ tone?: ComponentTone;
104
+ /** Masque l'action pour cette ligne — un solde nul, un envoi déjà annulé. */
105
+ hidden?: (row: T, index: number) => boolean;
106
+ disabled?: (row: T, index: number) => boolean;
107
+ /** Même grammaire de droits que la navigation. */
108
+ permission?: PermissionRule;
109
+ /** Demande confirmation. Obligatoire pour tout ce qui détruit. */
110
+ confirm?: {
111
+ title: ReactNode;
112
+ description?: ReactNode;
113
+ confirmLabel?: string;
114
+ cancelLabel?: string;
115
+ destructive?: boolean;
116
+ };
117
+ onSelect: (row: T, index: number) => void | Promise<void>;
118
+ }
119
+ interface DataTableProps<T> {
120
+ columns: Array<DataTableColumn<T>>;
121
+ data: T[];
122
+ /** La clé d'une ligne. Sans elle, l'index — à éviter si les lignes bougent. */
123
+ getRowKey?: (row: T, index: number) => Key;
124
+ title?: ReactNode;
125
+ description?: ReactNode;
126
+ /** Zone libre : filtres, sélecteur de période. */
127
+ toolbar?: ReactNode;
128
+ /** Actions globales, à droite. */
129
+ actions?: ReactNode;
130
+ /**
131
+ * Les clés sur lesquelles porte la recherche.
132
+ *
133
+ * Absente, aucun champ n'est affiché : un tableau sans champ déclaré n'a
134
+ * rien à chercher. Le filtrage est local, sur les lignes déjà chargées.
135
+ */
136
+ searchKeys?: string[];
137
+ searchPlaceholder?: string;
138
+ /** Recherche déléguée. Fournie, le tableau cesse de filtrer lui-même. */
139
+ onSearch?: (query: string) => void;
140
+ /**
141
+ * Millisecondes d'inactivité avant d'appeler `onSearch`.
142
+ *
143
+ * `0` — le défaut — l'appelle à chaque frappe, ce qui convient à un
144
+ * filtrage local. Pour une recherche serveur, 300 évite une requête par
145
+ * lettre ; Entrée et l'effacement déclenchent sans attendre.
146
+ */
147
+ searchDelay?: number;
148
+ layout?: "auto" | "fixed";
149
+ /** Hauteur du corps. Sans elle, `stickyHeader` n'a rien où se coller. */
150
+ maxHeight?: string;
151
+ stickyHeader?: boolean;
152
+ density?: "compact" | "default" | "comfortable";
153
+ /** Un fond alterné, une ligne sur deux. */
154
+ striped?: boolean;
155
+ bordered?: boolean;
156
+ rowActions?: Array<RowAction<T>> | ((row: T, index: number) => Array<RowAction<T>>);
157
+ /** Au-delà, les actions passent dans un menu. */
158
+ inlineActionsLimit?: number;
159
+ actionsHeader?: ReactNode;
160
+ /** `icon` garde la colonne étroite sur un tableau déjà large. */
161
+ actionsDisplay?: "icon" | "label";
162
+ /** Évalue les règles de permission des actions. */
163
+ can?: (rule: PermissionRule) => boolean;
164
+ view?: DataTableView;
165
+ defaultView?: DataTableView;
166
+ onViewChange?: (view: DataTableView) => void;
167
+ showViewToggle?: boolean;
168
+ /**
169
+ * Bascule en cartes sous le point de rupture. Actif par défaut : un
170
+ * tableau à sept colonnes est illisible sur un téléphone.
171
+ */
172
+ responsive?: boolean;
173
+ cardsBreakpoint?: number;
174
+ /** Rendu complet d'une carte. Sans lui, elle est déduite des colonnes. */
175
+ renderCard?: (row: T, index: number) => ReactNode;
176
+ loading?: boolean;
177
+ /** Lignes fantômes pendant le premier chargement. */
178
+ skeletonRows?: number;
179
+ error?: ReactNode;
180
+ onRetry?: () => void;
181
+ empty?: {
182
+ title?: ReactNode;
183
+ description?: ReactNode;
184
+ action?: ReactNode;
185
+ };
186
+ /**
187
+ * Ajoute une colonne de cases à cocher.
188
+ *
189
+ * Sur une liste paginée côté serveur, la case d'en-tête ne porte que sur la
190
+ * page affichée : le composant ne connaît pas les lignes qu'il n'a pas
191
+ * reçues, et prétendre « tout sélectionner » serait un mensonge.
192
+ */
193
+ selectable?: boolean;
194
+ selectedKeys?: Key[];
195
+ defaultSelectedKeys?: Key[];
196
+ onSelectionChange?: (keys: Key[], rows: T[]) => void;
197
+ isRowSelectable?: (row: T, index: number) => boolean;
198
+ /** Barre affichée dès qu'une ligne est cochée. */
199
+ selectionActions?: (context: {
200
+ keys: Key[];
201
+ rows: T[];
202
+ clear: () => void;
203
+ }) => ReactNode;
204
+ sort?: {
205
+ field: string;
206
+ direction: "asc" | "desc";
207
+ } | null;
208
+ onSortChange?: (field: string) => void;
209
+ onRowClick?: (row: T, index: number) => void;
210
+ rowClassName?: (row: T, index: number) => string | undefined;
211
+ caption?: string;
212
+ className?: string;
213
+ }
214
+
215
+ /**
216
+ * Les douze placements du moteur de géométrie.
217
+ *
218
+ * Ce composant n'en exposait que quatre — haut et bas — parce qu'il calculait
219
+ * lui-même sa position, en vertical seulement. Le calcul vit dans
220
+ * `@sia-ui/headless`, sait basculer et recadrer dans les deux axes, et sert
221
+ * déjà le natif : le refaire ici privait tous les flottants des côtés.
222
+ */
223
+ type OverlayPlacement = Placement;
224
+ interface OverlayProps {
225
+ open: boolean;
226
+ anchorRef: RefObject<HTMLElement | null>;
227
+ onOpenChange: (open: boolean) => void;
228
+ children: ReactNode;
229
+ placement?: OverlayPlacement;
230
+ offset?: number;
231
+ matchAnchorWidth?: boolean;
232
+ viewportPadding?: number;
233
+ className?: string;
234
+ id?: string;
235
+ role?: string;
236
+ }
237
+ /**
238
+ * Ce qui flotte à côté d'un élément.
239
+ *
240
+ * Le socle des menus, des listes déroulantes et des infobulles. Il place le
241
+ * panneau parmi douze positions, le retourne quand le bord de la fenêtre
242
+ * approche, et le ramène dans la vue plutôt que de le laisser déborder.
243
+ *
244
+ * Le calcul vit dans `@sia-ui/headless` : il ne dépend d'aucun rendu, et
245
+ * sert donc aussi à ce qui n'est pas le DOM.
246
+ */
247
+ declare function Overlay({ open, anchorRef, onOpenChange, children, placement, offset, matchAnchorWidth, viewportPadding, className, ...props }: OverlayProps): react.ReactPortal | null;
248
+
249
+ interface SelectOption {
250
+ value: string;
251
+ label: ReactNode;
252
+ description?: ReactNode;
253
+ disabled?: boolean;
254
+ keywords?: string[];
255
+ }
256
+ interface SelectProps {
257
+ id?: string;
258
+ name?: string;
259
+ options?: SelectOption[];
260
+ /** Compatibility path. Prefer the options prop. */
261
+ children?: ReactNode;
262
+ value?: string;
263
+ defaultValue?: string;
264
+ onValueChange?: (value: string, option?: SelectOption) => void;
265
+ placeholder?: string;
266
+ searchable?: boolean;
267
+ searchPlaceholder?: string;
268
+ fetcher?: (query: string, signal?: AbortSignal) => Promise<SelectOption[]>;
269
+ debounce?: number;
270
+ loadingText?: ReactNode;
271
+ emptyText?: ReactNode;
272
+ errorText?: ReactNode;
273
+ clearable?: boolean;
274
+ disabled?: boolean;
275
+ invalid?: boolean;
276
+ required?: boolean;
277
+ placement?: OverlayPlacement;
278
+ /**
279
+ * Ce que montre le déclencheur. Par défaut, le libellé de l'option.
280
+ *
281
+ * La liste garde ses libellés complets — « 🇨🇲 Cameroun (+237) » — pendant
282
+ * que le champ fermé n'affiche que ce qui tient : « 🇨🇲 +237 ».
283
+ */
284
+ renderValue?: (option: SelectOption | undefined) => ReactNode;
285
+ /**
286
+ * `embedded` retire bordure, fond et largeur pleine du déclencheur : le
287
+ * `Select` se loge alors dans un autre contrôle — l'indicatif d'un
288
+ * `PhoneInput`, la taille de page d'une `Pagination`.
289
+ */
290
+ variant?: "default" | "embedded";
291
+ className?: string;
292
+ "aria-label"?: string;
293
+ "aria-describedby"?: string;
294
+ "aria-labelledby"?: string;
295
+ "aria-invalid"?: boolean;
296
+ "aria-required"?: boolean;
297
+ }
298
+ /**
299
+ * Un choix parmi une liste.
300
+ *
301
+ * Le champ n'est pas un `<select>` natif : celui-ci ne sait ni chercher, ni
302
+ * afficher une description sous chaque option, ni charger ses choix à la
303
+ * demande. Le comportement clavier du natif, lui, est reproduit — flèches,
304
+ * première lettre, échappement.
305
+ *
306
+ * `fetcher` sert les listes qu'on ne peut pas descendre en entier : la
307
+ * requête part après la frappe et s'annule si l'on continue à taper.
308
+ */
309
+ declare const Select: react.ForwardRefExoticComponent<SelectProps & react.RefAttributes<HTMLButtonElement>>;
310
+
311
+ /** Une entrée de journal, dans sa forme la plus courante. */
312
+ interface ActivityEntry {
313
+ id: string | number;
314
+ /** Quand : une date ISO, un horodatage ou une `Date`. */
315
+ at: string | number | Date;
316
+ /** Qui : un nom lisible. */
317
+ actor: string;
318
+ /** Quoi : un code — `create`, `delete`, `login`. */
319
+ action: string;
320
+ /** Sur quoi : « Projet Atlas », « Compte ovh-prod ». */
321
+ target?: string | undefined;
322
+ /** Le type de la cible : `project`, `account`. */
323
+ targetType?: string | undefined;
324
+ /** Une phrase de contexte, facultative. */
325
+ summary?: ReactNode;
326
+ }
327
+ /** Un filtre déclaré : une clé de requête et ses choix. */
328
+ interface ActivityLogFilter {
329
+ /** La clé envoyée au serveur : `actor`, `action`, `targetType`. */
330
+ key: string;
331
+ label: string;
332
+ options: SelectOption[];
333
+ /** Cherchable au-delà d'une dizaine de choix. */
334
+ searchable?: boolean;
335
+ }
336
+ interface ActivityLogProps<T = ActivityEntry> {
337
+ entries: T[];
338
+ /**
339
+ * L'état de la requête : page, taille, recherche, filtres.
340
+ *
341
+ * `useDataTableQuery()` le fournit, synchronisé avec l'URL ou le routeur ;
342
+ * `query.params` part tel quel au serveur. Le journal ne filtre rien
343
+ * lui-même : un journal se compte en milliers de lignes.
344
+ */
345
+ query: TableQuery;
346
+ totalPages?: number;
347
+ filters?: ActivityLogFilter[];
348
+ /** Absente, la recherche n'est pas proposée. */
349
+ searchPlaceholder?: string;
350
+ /** Par défaut, les colonnes d'une `ActivityEntry`. */
351
+ columns?: Array<DataTableColumn<T>>;
352
+ getRowKey?: (row: T, index: number) => Key;
353
+ /** Le ton de chaque action dans les colonnes par défaut. */
354
+ actionTones?: Record<string, ComponentTone>;
355
+ /** Le libellé de chaque action — « Suppression » pour `delete`. */
356
+ actionLabels?: Record<string, ReactNode>;
357
+ title?: ReactNode;
358
+ description?: ReactNode;
359
+ headingLevel?: 1 | 2 | 3;
360
+ loading?: boolean;
361
+ error?: ReactNode;
362
+ onRetry?: () => void;
363
+ empty?: DataTableProps<T>["empty"];
364
+ className?: string;
365
+ }
366
+ /** Les colonnes d'une `ActivityEntry` : quand, qui, quoi, sur quoi. */
367
+ declare function activityColumns(options?: {
368
+ actionTones?: Record<string, ComponentTone> | undefined;
369
+ actionLabels?: Record<string, ReactNode> | undefined;
370
+ }): Array<DataTableColumn<ActivityEntry>>;
371
+ /**
372
+ * Un journal d'activité, filtrable et paginé par le serveur.
373
+ *
374
+ * `AuditMeta` et `Timeline` racontent l'histoire d'un objet ; ce bloc sert
375
+ * l'autre question — qui a fait quoi, sur tout le système, cette semaine.
376
+ * Filtres déclarés, recherche temporisée, pagination et taille de page : tout
377
+ * passe par la requête, rien n'est filtré dans le navigateur.
378
+ */
379
+ declare function ActivityLog<T = ActivityEntry>({ entries, query, totalPages, filters, searchPlaceholder, columns, getRowKey, actionTones, actionLabels, title, description, headingLevel, loading, error, onRetry, empty, className, }: ActivityLogProps<T>): react_jsx_runtime.JSX.Element;
380
+
57
381
  interface AlertProps {
58
382
  tone?: ComponentTone;
59
383
  title?: ReactNode;
@@ -423,134 +747,38 @@ interface AuditEvent {
423
747
  }
424
748
  interface AuditMetaProps {
425
749
  events: AuditEvent[];
426
- locale?: string;
427
- title?: ReactNode;
428
- emptyLabel?: ReactNode;
429
- className?: string;
430
- }
431
- /**
432
- * Qui a fait quoi, et quand.
433
- *
434
- * Une liste d'événements plutôt qu'un dernier état : savoir qu'une facture
435
- * a été validée n'apprend rien si l'on ignore qu'elle avait été rejetée la
436
- * veille. Les dates sont relatives — « il y a deux jours » se compare sans
437
- * calcul mental.
438
- */
439
- declare function AuditMeta({ events, locale, title, emptyLabel, className }: AuditMetaProps): react_jsx_runtime.JSX.Element;
440
-
441
- interface AuthLayoutProps {
442
- title: ReactNode;
443
- description?: ReactNode;
444
- logo?: ReactNode;
445
- aside?: ReactNode;
446
- children: ReactNode;
447
- footer?: ReactNode;
448
- className?: string;
449
- }
450
- /**
451
- * La page qui précède l'application : connexion, inscription, mot de passe
452
- * oublié.
453
- *
454
- * Elle n'a ni navigation ni coquille, et c'est délibéré : tout ce qui mène
455
- * ailleurs est hors de portée de quelqu'un qui n'est pas encore entré.
456
- */
457
- declare function AuthLayout({ title, description, logo, aside, children, footer, className, }: AuthLayoutProps): react_jsx_runtime.JSX.Element;
458
-
459
- /**
460
- * Les douze placements du moteur de géométrie.
461
- *
462
- * Ce composant n'en exposait que quatre — haut et bas — parce qu'il calculait
463
- * lui-même sa position, en vertical seulement. Le calcul vit dans
464
- * `@sia-ui/headless`, sait basculer et recadrer dans les deux axes, et sert
465
- * déjà le natif : le refaire ici privait tous les flottants des côtés.
466
- */
467
- type OverlayPlacement = Placement;
468
- interface OverlayProps {
469
- open: boolean;
470
- anchorRef: RefObject<HTMLElement | null>;
471
- onOpenChange: (open: boolean) => void;
472
- children: ReactNode;
473
- placement?: OverlayPlacement;
474
- offset?: number;
475
- matchAnchorWidth?: boolean;
476
- viewportPadding?: number;
477
- className?: string;
478
- id?: string;
479
- role?: string;
480
- }
481
- /**
482
- * Ce qui flotte à côté d'un élément.
483
- *
484
- * Le socle des menus, des listes déroulantes et des infobulles. Il place le
485
- * panneau parmi douze positions, le retourne quand le bord de la fenêtre
486
- * approche, et le ramène dans la vue plutôt que de le laisser déborder.
487
- *
488
- * Le calcul vit dans `@sia-ui/headless` : il ne dépend d'aucun rendu, et
489
- * sert donc aussi à ce qui n'est pas le DOM.
490
- */
491
- declare function Overlay({ open, anchorRef, onOpenChange, children, placement, offset, matchAnchorWidth, viewportPadding, className, ...props }: OverlayProps): react.ReactPortal | null;
492
-
493
- interface SelectOption {
494
- value: string;
495
- label: ReactNode;
496
- description?: ReactNode;
497
- disabled?: boolean;
498
- keywords?: string[];
499
- }
500
- interface SelectProps {
501
- id?: string;
502
- name?: string;
503
- options?: SelectOption[];
504
- /** Compatibility path. Prefer the options prop. */
505
- children?: ReactNode;
506
- value?: string;
507
- defaultValue?: string;
508
- onValueChange?: (value: string, option?: SelectOption) => void;
509
- placeholder?: string;
510
- searchable?: boolean;
511
- searchPlaceholder?: string;
512
- fetcher?: (query: string, signal?: AbortSignal) => Promise<SelectOption[]>;
513
- debounce?: number;
514
- loadingText?: ReactNode;
515
- emptyText?: ReactNode;
516
- errorText?: ReactNode;
517
- clearable?: boolean;
518
- disabled?: boolean;
519
- invalid?: boolean;
520
- required?: boolean;
521
- placement?: OverlayPlacement;
522
- /**
523
- * Ce que montre le déclencheur. Par défaut, le libellé de l'option.
524
- *
525
- * La liste garde ses libellés complets — « 🇨🇲 Cameroun (+237) » — pendant
526
- * que le champ fermé n'affiche que ce qui tient : « 🇨🇲 +237 ».
527
- */
528
- renderValue?: (option: SelectOption | undefined) => ReactNode;
529
- /**
530
- * `embedded` retire bordure, fond et largeur pleine du déclencheur : le
531
- * `Select` se loge alors dans un autre contrôle — l'indicatif d'un
532
- * `PhoneInput`, la taille de page d'une `Pagination`.
533
- */
534
- variant?: "default" | "embedded";
535
- className?: string;
536
- "aria-label"?: string;
537
- "aria-describedby"?: string;
538
- "aria-labelledby"?: string;
539
- "aria-invalid"?: boolean;
540
- "aria-required"?: boolean;
750
+ locale?: string;
751
+ title?: ReactNode;
752
+ emptyLabel?: ReactNode;
753
+ className?: string;
541
754
  }
542
755
  /**
543
- * Un choix parmi une liste.
756
+ * Qui a fait quoi, et quand.
544
757
  *
545
- * Le champ n'est pas un `<select>` natif : celui-ci ne sait ni chercher, ni
546
- * afficher une description sous chaque option, ni charger ses choix à la
547
- * demande. Le comportement clavier du natif, lui, est reproduit — flèches,
548
- * première lettre, échappement.
758
+ * Une liste d'événements plutôt qu'un dernier état : savoir qu'une facture
759
+ * a été validée n'apprend rien si l'on ignore qu'elle avait été rejetée la
760
+ * veille. Les dates sont relatives — « il y a deux jours » se compare sans
761
+ * calcul mental.
762
+ */
763
+ declare function AuditMeta({ events, locale, title, emptyLabel, className }: AuditMetaProps): react_jsx_runtime.JSX.Element;
764
+
765
+ interface AuthLayoutProps {
766
+ title: ReactNode;
767
+ description?: ReactNode;
768
+ logo?: ReactNode;
769
+ aside?: ReactNode;
770
+ children: ReactNode;
771
+ footer?: ReactNode;
772
+ className?: string;
773
+ }
774
+ /**
775
+ * La page qui précède l'application : connexion, inscription, mot de passe
776
+ * oublié.
549
777
  *
550
- * `fetcher` sert les listes qu'on ne peut pas descendre en entier : la
551
- * requête part après la frappe et s'annule si l'on continue à taper.
778
+ * Elle n'a ni navigation ni coquille, et c'est délibéré : tout ce qui mène
779
+ * ailleurs est hors de portée de quelqu'un qui n'est pas encore entré.
552
780
  */
553
- declare const Select: react.ForwardRefExoticComponent<SelectProps & react.RefAttributes<HTMLButtonElement>>;
781
+ declare function AuthLayout({ title, description, logo, aside, children, footer, className, }: AuthLayoutProps): react_jsx_runtime.JSX.Element;
554
782
 
555
783
  interface AutocompleteProps {
556
784
  id?: string;
@@ -688,6 +916,39 @@ interface BadgeProps extends HTMLAttributes<HTMLSpanElement> {
688
916
  * qui agit est un bouton.
689
917
  */
690
918
  declare function Badge({ tone: toneProp, variant: variantProp, left, right, loading, loadingLabel: loadingLabelProp, spinnerProps, className, children, ...props }: BadgeProps): react_jsx_runtime.JSX.Element;
919
+ /**
920
+ * Le ton d'une valeur, lu dans une table de correspondance.
921
+ *
922
+ * Un statut, une action de journal, un environnement : chaque écran tenait
923
+ * sa propre table et sa propre fonction pour la lire. Celle-ci est la seule.
924
+ *
925
+ * ```ts
926
+ * const TONS = { payee: "success", attente: "warning", annulee: "danger" };
927
+ * toneOf(TONS, facture.statut); // "success" | … | "neutral"
928
+ * ```
929
+ */
930
+ declare function toneOf(tones: Readonly<Record<string, ComponentTone>> | undefined, value: unknown, fallback?: ComponentTone): ComponentTone;
931
+ interface StatusBadgeProps extends Omit<BadgeProps, "tone" | "children"> {
932
+ /** La valeur brute : `"payee"`, `"prod"`, `"delete"`. */
933
+ value: string | number | null | undefined;
934
+ /** Le ton de chaque valeur. */
935
+ tones?: Readonly<Record<string, ComponentTone>>;
936
+ /** Le libellé de chaque valeur. À défaut, la valeur elle-même. */
937
+ labels?: Readonly<Record<string, ReactNode>>;
938
+ /** Le ton d'une valeur absente de `tones`. `neutral` par défaut. */
939
+ fallbackTone?: ComponentTone;
940
+ /** Ce qui s'affiche sans valeur. Rien par défaut. */
941
+ empty?: ReactNode;
942
+ }
943
+ /**
944
+ * Une valeur rendue en pastille, ton et libellé tirés de deux tables.
945
+ *
946
+ * Déclarées une fois par domaine — les statuts de facture, les actions du
947
+ * journal — puis passées partout où la valeur s'affiche : colonne libre,
948
+ * détail, carte. Une valeur inconnue garde une pastille neutre plutôt que de
949
+ * disparaître.
950
+ */
951
+ declare function StatusBadge({ value, tones, labels, fallbackTone, empty, ...props }: StatusBadgeProps): react_jsx_runtime.JSX.Element;
691
952
 
692
953
  interface BreadcrumbItem {
693
954
  key?: string;
@@ -1038,164 +1299,6 @@ type CountdownProps = Omit<TimerProps, "direction">;
1038
1299
  */
1039
1300
  declare function Countdown(props: CountdownProps): react_jsx_runtime.JSX.Element;
1040
1301
 
1041
- /** Liste dense, ou grille de cartes. */
1042
- type DataTableView = "table" | "cards";
1043
- /**
1044
- * Le rôle d'une colonne dans la carte.
1045
- *
1046
- * `title` sert d'en-tête — la première colonne le prend si rien n'est
1047
- * déclaré. `meta` s'affiche en paire libellé / valeur. `hidden` reste au
1048
- * tableau seul : une carte qui recopie douze colonnes n'est plus une carte.
1049
- */
1050
- type ColumnCardRole = "title" | "meta" | "hidden";
1051
- interface DataTableColumn<T> {
1052
- key: string;
1053
- header: ReactNode;
1054
- /**
1055
- * Où lire la valeur : une clé de l'objet, ou une fonction pour les valeurs
1056
- * calculées. Sert au rendu par défaut, à la carte et à la recherche locale.
1057
- */
1058
- accessor?: keyof T | ((row: T) => unknown);
1059
- /** Rendu personnalisé. Prioritaire sur `accessor`. */
1060
- cell?: (row: T, index: number) => ReactNode;
1061
- align?: "start" | "center" | "end";
1062
- /**
1063
- * Largeur suggérée — `120px`, `20%`.
1064
- *
1065
- * En `layout="auto"` (défaut) le navigateur n'y voit qu'une indication.
1066
- * Pour qu'elle soit tenue, passer en `layout="fixed"`.
1067
- */
1068
- width?: string;
1069
- minWidth?: string;
1070
- /** Coupe au lieu d'élargir. Indispensable en `layout="fixed"`. */
1071
- truncate?: boolean;
1072
- /** Retire la colonne du tableau sans toucher à la carte. */
1073
- hidden?: boolean;
1074
- /** Rend l'en-tête cliquable. Le tri lui-même reste au serveur. */
1075
- sortable?: boolean;
1076
- /** Le champ envoyé au serveur, si différent de `key`. */
1077
- sortKey?: string;
1078
- /** Place de la colonne dans la carte. */
1079
- card?: ColumnCardRole;
1080
- headerClassName?: string;
1081
- cellClassName?: string;
1082
- }
1083
- interface RowAction<T> {
1084
- key: string;
1085
- label: ReactNode;
1086
- icon?: ReactNode;
1087
- tone?: ComponentTone;
1088
- /** Masque l'action pour cette ligne — un solde nul, un envoi déjà annulé. */
1089
- hidden?: (row: T, index: number) => boolean;
1090
- disabled?: (row: T, index: number) => boolean;
1091
- /** Même grammaire de droits que la navigation. */
1092
- permission?: PermissionRule;
1093
- /** Demande confirmation. Obligatoire pour tout ce qui détruit. */
1094
- confirm?: {
1095
- title: ReactNode;
1096
- description?: ReactNode;
1097
- confirmLabel?: string;
1098
- cancelLabel?: string;
1099
- destructive?: boolean;
1100
- };
1101
- onSelect: (row: T, index: number) => void | Promise<void>;
1102
- }
1103
- interface DataTableProps<T> {
1104
- columns: Array<DataTableColumn<T>>;
1105
- data: T[];
1106
- /** La clé d'une ligne. Sans elle, l'index — à éviter si les lignes bougent. */
1107
- getRowKey?: (row: T, index: number) => Key;
1108
- title?: ReactNode;
1109
- description?: ReactNode;
1110
- /** Zone libre : filtres, sélecteur de période. */
1111
- toolbar?: ReactNode;
1112
- /** Actions globales, à droite. */
1113
- actions?: ReactNode;
1114
- /**
1115
- * Les clés sur lesquelles porte la recherche.
1116
- *
1117
- * Absente, aucun champ n'est affiché : un tableau sans champ déclaré n'a
1118
- * rien à chercher. Le filtrage est local, sur les lignes déjà chargées.
1119
- */
1120
- searchKeys?: string[];
1121
- searchPlaceholder?: string;
1122
- /** Recherche déléguée. Fournie, le tableau cesse de filtrer lui-même. */
1123
- onSearch?: (query: string) => void;
1124
- /**
1125
- * Millisecondes d'inactivité avant d'appeler `onSearch`.
1126
- *
1127
- * `0` — le défaut — l'appelle à chaque frappe, ce qui convient à un
1128
- * filtrage local. Pour une recherche serveur, 300 évite une requête par
1129
- * lettre ; Entrée et l'effacement déclenchent sans attendre.
1130
- */
1131
- searchDelay?: number;
1132
- layout?: "auto" | "fixed";
1133
- /** Hauteur du corps. Sans elle, `stickyHeader` n'a rien où se coller. */
1134
- maxHeight?: string;
1135
- stickyHeader?: boolean;
1136
- density?: "compact" | "default" | "comfortable";
1137
- /** Un fond alterné, une ligne sur deux. */
1138
- striped?: boolean;
1139
- bordered?: boolean;
1140
- rowActions?: Array<RowAction<T>> | ((row: T, index: number) => Array<RowAction<T>>);
1141
- /** Au-delà, les actions passent dans un menu. */
1142
- inlineActionsLimit?: number;
1143
- actionsHeader?: ReactNode;
1144
- /** `icon` garde la colonne étroite sur un tableau déjà large. */
1145
- actionsDisplay?: "icon" | "label";
1146
- /** Évalue les règles de permission des actions. */
1147
- can?: (rule: PermissionRule) => boolean;
1148
- view?: DataTableView;
1149
- defaultView?: DataTableView;
1150
- onViewChange?: (view: DataTableView) => void;
1151
- showViewToggle?: boolean;
1152
- /**
1153
- * Bascule en cartes sous le point de rupture. Actif par défaut : un
1154
- * tableau à sept colonnes est illisible sur un téléphone.
1155
- */
1156
- responsive?: boolean;
1157
- cardsBreakpoint?: number;
1158
- /** Rendu complet d'une carte. Sans lui, elle est déduite des colonnes. */
1159
- renderCard?: (row: T, index: number) => ReactNode;
1160
- loading?: boolean;
1161
- /** Lignes fantômes pendant le premier chargement. */
1162
- skeletonRows?: number;
1163
- error?: ReactNode;
1164
- onRetry?: () => void;
1165
- empty?: {
1166
- title?: ReactNode;
1167
- description?: ReactNode;
1168
- action?: ReactNode;
1169
- };
1170
- /**
1171
- * Ajoute une colonne de cases à cocher.
1172
- *
1173
- * Sur une liste paginée côté serveur, la case d'en-tête ne porte que sur la
1174
- * page affichée : le composant ne connaît pas les lignes qu'il n'a pas
1175
- * reçues, et prétendre « tout sélectionner » serait un mensonge.
1176
- */
1177
- selectable?: boolean;
1178
- selectedKeys?: Key[];
1179
- defaultSelectedKeys?: Key[];
1180
- onSelectionChange?: (keys: Key[], rows: T[]) => void;
1181
- isRowSelectable?: (row: T, index: number) => boolean;
1182
- /** Barre affichée dès qu'une ligne est cochée. */
1183
- selectionActions?: (context: {
1184
- keys: Key[];
1185
- rows: T[];
1186
- clear: () => void;
1187
- }) => ReactNode;
1188
- sort?: {
1189
- field: string;
1190
- direction: "asc" | "desc";
1191
- } | null;
1192
- onSortChange?: (field: string) => void;
1193
- onRowClick?: (row: T, index: number) => void;
1194
- rowClassName?: (row: T, index: number) => string | undefined;
1195
- caption?: string;
1196
- className?: string;
1197
- }
1198
-
1199
1302
  interface InputProps extends InputHTMLAttributes<HTMLInputElement> {
1200
1303
  invalid?: boolean;
1201
1304
  left?: ReactNode;
@@ -1831,6 +1934,8 @@ declare function Form<TValues extends FormShape = FormShape>({ fields, form: ada
1831
1934
  * même client finissent toujours par diverger, et c'est le formulaire qui
1832
1935
  * oublie le champ que le tableau affiche.
1833
1936
  */
1937
+ /** Le formulaire ouvert : une création, ou la modification d'une ligne. */
1938
+ type ResourceFormMode = "create" | "edit";
1834
1939
  interface ResourceField<T = unknown> {
1835
1940
  /** Le contrôle de saisie et le rendu par défaut. `text` sans précision. */
1836
1941
  type?: FieldType;
@@ -1839,7 +1944,13 @@ interface ResourceField<T = unknown> {
1839
1944
  description?: ReactNode;
1840
1945
  helpText?: ReactNode;
1841
1946
  placeholder?: string;
1842
- required?: boolean;
1947
+ /**
1948
+ * Obligatoire toujours, ou dans un seul mode.
1949
+ *
1950
+ * `"create"` sert au mot de passe initial : exigé à la création, facultatif
1951
+ * ensuite — le laisser vide en modification veut dire « inchangé ».
1952
+ */
1953
+ required?: boolean | ResourceFormMode;
1843
1954
  /** Les règles en plus de `required`. Celles du type sont ajoutées seules. */
1844
1955
  rules?: Array<Rule<never>>;
1845
1956
  /** Les choix d'un `select`, `radio` ou `multiselect`. */
@@ -1856,8 +1967,11 @@ interface ResourceField<T = unknown> {
1856
1967
  readOnly?: boolean;
1857
1968
  /** Par défaut, tout sauf les types trop longs pour une cellule. */
1858
1969
  inTable?: boolean;
1859
- /** Par défaut, tout sauf `readOnly`. */
1860
- inForm?: boolean;
1970
+ /**
1971
+ * Par défaut, tout sauf `readOnly` et les valeurs calculées. `"create"` ou
1972
+ * `"edit"` limitent le champ à l'un des deux formulaires.
1973
+ */
1974
+ inForm?: boolean | ResourceFormMode;
1861
1975
  /** Par défaut, tout. */
1862
1976
  inDetail?: boolean;
1863
1977
  /** Par défaut, les types textuels. */
@@ -1884,6 +1998,15 @@ interface ResourceField<T = unknown> {
1884
1998
  tones?: Record<string, ComponentTone>;
1885
1999
  /** Le rendu en tableau et en détail. Écrase celui déduit du type. */
1886
2000
  render?: (row: T, index: number) => ReactNode;
2001
+ /**
2002
+ * Une valeur calculée plutôt que lue sur la ligne.
2003
+ *
2004
+ * La colonne peut alors porter une clé qui n'est pas une propriété de `T`
2005
+ * — un nom complet, un solde — sans élargir le type de la ligne. Le rendu
2006
+ * par défaut, la carte et la recherche locale passent par elle. Une valeur
2007
+ * calculée ne se saisit pas : elle sort du formulaire, sauf `inForm`.
2008
+ */
2009
+ value?: (row: T) => unknown;
1887
2010
  }
1888
2011
  interface ResourceDefinition<T> {
1889
2012
  /** L'identifiant technique — sert aux droits et aux clés de cache. */
@@ -1958,17 +2081,17 @@ declare function resourceColumns<T>(resource: ResourceDefinition<T>): Array<Data
1958
2081
  */
1959
2082
  declare function resourceDetailColumns<T>(resource: ResourceDefinition<T>): Array<DataTableColumn<T>>;
1960
2083
  /** Les champs du formulaire, groupés si la déclaration les groupe. */
1961
- declare function resourceFormFields<T>(resource: ResourceDefinition<T>): FormEntry[];
2084
+ declare function resourceFormFields<T>(resource: ResourceDefinition<T>, mode?: ResourceFormMode): FormEntry[];
1962
2085
  /**
1963
2086
  * La validation, dérivée des types et des `required`.
1964
2087
  *
1965
2088
  * Un champ `email` valide une adresse sans qu'on le demande : le type le dit
1966
2089
  * déjà. Les règles déclarées s'y ajoutent, elles ne les remplacent pas.
1967
2090
  */
1968
- declare function resourceValidator<T>(resource: ResourceDefinition<T>): FormValidator<FormShape> | undefined;
2091
+ declare function resourceValidator<T>(resource: ResourceDefinition<T>, mode?: ResourceFormMode): FormValidator<FormShape> | undefined;
1969
2092
  /** Les clés que la recherche locale parcourt. */
1970
2093
  declare function resourceSearchKeys<T>(resource: ResourceDefinition<T>): string[];
1971
- /** Les valeurs de départ d'une création. */
2094
+ /** Les valeurs de départ d'une création : les champs du mode `create`. */
1972
2095
  declare function resourceDefaults<T>(resource: ResourceDefinition<T>): FormShape;
1973
2096
  /** Comment lire la clé d'une ligne. */
1974
2097
  declare function resourceRowKey<T>(resource: ResourceDefinition<T>): (row: T, index: number) => Key;
@@ -2012,6 +2135,13 @@ interface CrudDialogsProps<T> {
2012
2135
  columns: Array<DataTableColumn<T>>;
2013
2136
  fields?: FormEntry[] | undefined;
2014
2137
  validate?: FormValidator<FormShape> | undefined;
2138
+ /**
2139
+ * Les champs et la validation de la modification, quand ils diffèrent de
2140
+ * la création — un mot de passe exigé à la création seulement. À défaut,
2141
+ * `fields` et `validate` servent aux deux.
2142
+ */
2143
+ editFields?: FormEntry[] | undefined;
2144
+ editValidate?: FormValidator<FormShape> | undefined;
2015
2145
  onSubmit?: ((values: FormShape, context: {
2016
2146
  mode: "create" | "edit";
2017
2147
  row?: T;
@@ -2031,7 +2161,7 @@ interface CrudDialogsProps<T> {
2031
2161
  * laquelle ouvrir, avec quelles valeurs, et de refermer une fois l'envoi
2032
2162
  * passé.
2033
2163
  */
2034
- declare function CrudDialogs<T>({ state, onClose, columns, fields, validate, onSubmit, createDefaults, toFormValues, renderDetail, getRowKey, dialog, }: CrudDialogsProps<T>): react_jsx_runtime.JSX.Element;
2164
+ declare function CrudDialogs<T>({ state, onClose, columns, fields: champsCreation, validate: validationCreation, editFields, editValidate, onSubmit, createDefaults, toFormValues, renderDetail, getRowKey, dialog, }: CrudDialogsProps<T>): react_jsx_runtime.JSX.Element;
2035
2165
 
2036
2166
  /**
2037
2167
  * La personnalisation d'une action standard.
@@ -2060,6 +2190,12 @@ interface CrudPageBase<T> {
2060
2190
  title?: ReactNode;
2061
2191
  description?: ReactNode;
2062
2192
  eyebrow?: ReactNode;
2193
+ /**
2194
+ * Le niveau du titre. `1` pour un écran ; `2` quand la liste est une
2195
+ * section d'une fiche — les comptes d'un fournisseur — qui a déjà son
2196
+ * `<h1>`.
2197
+ */
2198
+ headingLevel?: 1 | 2 | 3;
2063
2199
  data: T[];
2064
2200
  getRowKey?: (row: T, index: number) => Key;
2065
2201
  /**
@@ -2200,7 +2336,7 @@ type CrudPageProps<T> = CrudPageBase<T> & ({
2200
2336
  *
2201
2337
  * Ici, fournir le gestionnaire suffit. Ne pas le fournir retire l'action.
2202
2338
  */
2203
- declare function CrudPage<T>({ resource, title, description, eyebrow, columns: colonnesFournies, data, getRowKey: cleFournie, onCreate, onView, onEdit, onDelete, fields: champsFournis, onSubmit, validate: validationFournie, createDefaults, toFormValues, detail, dialog, operations, extraRowActions, onBulkDelete, can, headerActions, toolbar, searchKeys: clesDeRecherche, searchPlaceholder, onSearch, searchDelay, loading, error, onRetry, empty, page, totalPages, onPageChange, pageSize, onPageSizeChange, pageSizeOptions, table, children, className, }: CrudPageProps<T>): react_jsx_runtime.JSX.Element;
2339
+ declare function CrudPage<T>({ resource, title, description, eyebrow, headingLevel, columns: colonnesFournies, data, getRowKey: cleFournie, onCreate, onView, onEdit, onDelete, fields: champsFournis, onSubmit, validate: validationFournie, createDefaults, toFormValues, detail, dialog, operations, extraRowActions, onBulkDelete, can, headerActions, toolbar, searchKeys: clesDeRecherche, searchPlaceholder, onSearch, searchDelay, loading, error, onRetry, empty, page, totalPages, onPageChange, pageSize, onPageSizeChange, pageSizeOptions, table, children, className, }: CrudPageProps<T>): react_jsx_runtime.JSX.Element;
2204
2340
 
2205
2341
  /**
2206
2342
  * L'état du tableau dans la barre d'adresse.
@@ -2210,6 +2346,41 @@ declare function CrudPage<T>({ resource, title, description, eyebrow, columns: c
2210
2346
  * d'où l'on vient.
2211
2347
  */
2212
2348
  declare function createUrlTableStorage(mode?: "replace" | "push"): TableQueryStorage;
2349
+ /**
2350
+ * Ce que l'adaptateur demande d'un routeur : la forme du `router` de
2351
+ * TanStack Router, sans en dépendre. Méthodes écrites en syntaxe de méthode :
2352
+ * leurs paramètres se comparent alors de façon bivariante, et le routeur typé
2353
+ * de l'application s'y passe sans transtypage.
2354
+ */
2355
+ interface TanStackRouterLike {
2356
+ state: {
2357
+ location: {
2358
+ search: object;
2359
+ };
2360
+ };
2361
+ navigate(options: {
2362
+ to: string;
2363
+ search: Record<string, unknown>;
2364
+ replace: boolean;
2365
+ }): unknown;
2366
+ subscribe(event: "onResolved", listener: () => void): () => void;
2367
+ }
2368
+ /**
2369
+ * L'état du tableau dans les paramètres de TanStack Router.
2370
+ *
2371
+ * Deux pièges de la recette qu'on écrivait à la main :
2372
+ *
2373
+ * - TanStack Router sérialise les paramètres en JSON. Une chaîne qui a l'air
2374
+ * d'un nombre y est mise entre guillemets — `page=2` devenait
2375
+ * `page=%222%22`. L'adaptateur passe donc de vrais nombres ; les autres
2376
+ * valeurs restent des chaînes, que le routeur relit à l'identique.
2377
+ * - La lecture part de l'objet déjà décodé par le routeur, jamais de la chaîne
2378
+ * brute, qui porte ces guillemets.
2379
+ *
2380
+ * Les paramètres étrangers au tableau sont gardés par `useTableQuery`, qui
2381
+ * n'écrit que ses propres clés.
2382
+ */
2383
+ declare function createTanStackRouterStorage(router: TanStackRouterLike, mode?: "replace" | "push"): TableQueryStorage;
2213
2384
  interface UseDataTableQueryOptions {
2214
2385
  defaultState?: Partial<TableQueryState>;
2215
2386
  /** `false` garde l'état en mémoire — utile dans une modale. */
@@ -2218,6 +2389,22 @@ interface UseDataTableQueryOptions {
2218
2389
  history?: "replace" | "push";
2219
2390
  /** Préfixe des clés, pour deux tableaux sur la même page. */
2220
2391
  prefix?: string;
2392
+ /**
2393
+ * Un autre endroit où ranger l'état — le plus souvent le routeur.
2394
+ *
2395
+ * La barre d'adresse écrite directement passe sous le nez d'un routeur qui
2396
+ * tient ses propres paramètres (TanStack Router, React Router) : il ne voit
2397
+ * pas le changement, et le réécrit au prochain rendu. Fourni, ce stockage
2398
+ * remplace celui de l'URL, et `syncUrl` / `history` sont ignorés.
2399
+ */
2400
+ storage?: TableQueryStorage;
2401
+ /**
2402
+ * Le routeur TanStack Router de l'application. Raccourci de
2403
+ * `storage: createTanStackRouterStorage(router)` ; `history` s'applique.
2404
+ */
2405
+ router?: TanStackRouterLike;
2406
+ /** Les noms des paramètres serveur — `limit`, `sort` + `order`… */
2407
+ serverParams?: TableParamsMapping;
2221
2408
  }
2222
2409
  /**
2223
2410
  * Tri, filtres et pagination d'un tableau, synchronisés avec l'URL.
@@ -2623,6 +2810,16 @@ declare function InfoIcon(props: IconProps): react_jsx_runtime.JSX.Element;
2623
2810
  declare function SettingsIcon(props: IconProps): react_jsx_runtime.JSX.Element;
2624
2811
  declare function EyeIcon(props: IconProps): react_jsx_runtime.JSX.Element;
2625
2812
  declare function EyeOffIcon(props: IconProps): react_jsx_runtime.JSX.Element;
2813
+ declare function HomeIcon(props: IconProps): react_jsx_runtime.JSX.Element;
2814
+ declare function FolderIcon(props: IconProps): react_jsx_runtime.JSX.Element;
2815
+ declare function ServerIcon(props: IconProps): react_jsx_runtime.JSX.Element;
2816
+ declare function UserIcon(props: IconProps): react_jsx_runtime.JSX.Element;
2817
+ declare function UsersIcon(props: IconProps): react_jsx_runtime.JSX.Element;
2818
+ declare function ActivityIcon(props: IconProps): react_jsx_runtime.JSX.Element;
2819
+ declare function KeyIcon(props: IconProps): react_jsx_runtime.JSX.Element;
2820
+ declare function LockIcon(props: IconProps): react_jsx_runtime.JSX.Element;
2821
+ declare function LogOutIcon(props: IconProps): react_jsx_runtime.JSX.Element;
2822
+ declare function PencilIcon(props: IconProps): react_jsx_runtime.JSX.Element;
2626
2823
 
2627
2824
  interface InputNumberProps extends Omit<InputProps, "value" | "defaultValue" | "onChange" | "type" | "right"> {
2628
2825
  value?: number | null;
@@ -2727,6 +2924,14 @@ interface PageHeaderProps {
2727
2924
  description?: ReactNode;
2728
2925
  eyebrow?: ReactNode;
2729
2926
  actions?: ReactNode;
2927
+ /**
2928
+ * Le niveau du titre. `1` — le défaut — pour l'en-tête d'un écran.
2929
+ *
2930
+ * `2` ou `3` pour une section dans un écran qui a déjà son `<h1>` : la
2931
+ * liste des environnements dans la fiche d'un projet. Le titre y est plus
2932
+ * petit et l'espace sous l'en-tête plus court.
2933
+ */
2934
+ level?: 1 | 2 | 3;
2730
2935
  className?: string;
2731
2936
  }
2732
2937
  /**
@@ -2734,9 +2939,10 @@ interface PageHeaderProps {
2734
2939
  *
2735
2940
  * Un seul `<h1>` par page, rendu ici : la hiérarchie des titres est ce qui
2736
2941
  * permet de parcourir un écran au lecteur d'écran, et deux `<h1>` la
2737
- * cassent sans que rien ne se voie.
2942
+ * cassent sans que rien ne se voie. Une section imbriquée passe donc
2943
+ * `level={2}`.
2738
2944
  */
2739
- declare function PageHeader({ title, description, eyebrow, actions, className }: PageHeaderProps): react_jsx_runtime.JSX.Element;
2945
+ declare function PageHeader({ title, description, eyebrow, actions, level, className, }: PageHeaderProps): react_jsx_runtime.JSX.Element;
2740
2946
 
2741
2947
  interface PaginationProps {
2742
2948
  page: number;
@@ -3088,6 +3294,77 @@ interface SearchInputProps extends Omit<InputHTMLAttributes<HTMLInputElement>, "
3088
3294
  */
3089
3295
  declare const SearchInput: react.ForwardRefExoticComponent<SearchInputProps & react.RefAttributes<HTMLInputElement>>;
3090
3296
 
3297
+ /** Une paire nom / valeur. La valeur n'est jamais relue du serveur. */
3298
+ interface SecretEntry {
3299
+ key: string;
3300
+ value: string;
3301
+ }
3302
+ interface SecretFieldsProps {
3303
+ value?: SecretEntry[];
3304
+ defaultValue?: SecretEntry[];
3305
+ onValueChange?: (entries: SecretEntry[]) => void;
3306
+ /**
3307
+ * Les noms déjà enregistrés côté serveur.
3308
+ *
3309
+ * Affichés, mais leur valeur reste vide : un secret ne revient jamais au
3310
+ * navigateur. Une valeur laissée vide sur l'un d'eux veut dire « inchangé » ;
3311
+ * en saisir une, c'est le remplacer — une rotation.
3312
+ */
3313
+ storedKeys?: string[];
3314
+ /** Des noms proposés d'un clic : `DATABASE_URL`, `API_KEY`… */
3315
+ templates?: string[];
3316
+ /** La forme d'un nom valide. Par défaut, aucune contrainte. */
3317
+ keyPattern?: RegExp;
3318
+ keyPatternMessage?: string;
3319
+ keyLabel?: string;
3320
+ valueLabel?: string;
3321
+ addLabel?: ReactNode;
3322
+ disabled?: boolean;
3323
+ className?: string;
3324
+ }
3325
+ /** Les valeurs effacées, les noms gardés — ce qu'on affiche après l'envoi. */
3326
+ declare function clearSecretValues(entries: SecretEntry[]): SecretEntry[];
3327
+ /**
3328
+ * Des secrets en écriture seule : les noms se lisent, les valeurs jamais.
3329
+ *
3330
+ * Chaque ligne est un nom et une valeur masquée. Les noms déjà enregistrés
3331
+ * s'affichent sans leur valeur — le serveur ne la renvoie pas, et ne doit pas
3332
+ * la renvoyer. Les champs refusent l'autocomplétion du navigateur, qui
3333
+ * proposerait sinon le mot de passe du compte à la place d'une clé d'API.
3334
+ *
3335
+ * Après l'envoi, `clearSecretValues` vide les valeurs : un secret ne reste pas
3336
+ * affiché dans un formulaire ouvert.
3337
+ */
3338
+ declare function SecretFields({ value, defaultValue, onValueChange, storedKeys, templates, keyPattern, keyPatternMessage, keyLabel, valueLabel, addLabel, disabled, className, }: SecretFieldsProps): react_jsx_runtime.JSX.Element;
3339
+ /** Ce qu'il faut envoyer au serveur après une saisie dans `SecretFields`. */
3340
+ interface SecretChanges {
3341
+ /** À créer ou à remplacer (rotation) : nom → nouvelle valeur. */
3342
+ set: Record<string, string>;
3343
+ /** Noms enregistrés retirés de la liste : à supprimer. */
3344
+ remove: string[];
3345
+ /**
3346
+ * Noms nouveaux restés sans valeur. Rien à envoyer pour eux — mais les
3347
+ * ignorer sans le dire perdrait une saisie : à signaler avant l'envoi.
3348
+ */
3349
+ missing: string[];
3350
+ }
3351
+ /**
3352
+ * Ce qui change, calculé une fois pour tous les projets.
3353
+ *
3354
+ * Un nom enregistré laissé vide est inchangé ; saisi, il est remplacé. Un nom
3355
+ * enregistré absent de la liste est à supprimer — y compris quand il a été
3356
+ * renommé : l'ancien part, le nouveau arrive avec sa valeur. Les lignes sans
3357
+ * nom sont ignorées ; un nom en double garde sa dernière valeur saisie.
3358
+ *
3359
+ * ```ts
3360
+ * const { set, remove, missing } = secretChanges(secrets, enregistres);
3361
+ * if (missing.length) return; // à compléter
3362
+ * await api.patch(`/projets/${id}/secrets`, { body: { set, remove } });
3363
+ * setSecrets(clearSecretValues(secrets));
3364
+ * ```
3365
+ */
3366
+ declare function secretChanges(entries: SecretEntry[], storedKeys?: string[]): SecretChanges;
3367
+
3091
3368
  interface SkeletonProps extends HTMLAttributes<HTMLDivElement> {
3092
3369
  width?: CSSProperties["width"];
3093
3370
  height?: CSSProperties["height"];
@@ -3498,4 +3775,4 @@ interface YearPickerProps {
3498
3775
  */
3499
3776
  declare function YearPicker({ value, defaultValue, min, max, onValueChange, className }: YearPickerProps): react_jsx_runtime.JSX.Element;
3500
3777
 
3501
- export { Accordion, type AccordionItem, type AccordionProps, Alert, AlertCircleIcon, type AlertProps, AmountDisplay, type AmountDisplayProps, AppShell, AppShellBrand, type AppShellBrandProps, type AppShellCollapsible, type AppShellContentWidth, type AppShellMobileNav, type AppShellProps, AppShellRailItem, type AppShellRailItemProps, ArrowRightIcon, AspectRatio, type AspectRatioProps, AsyncState, type AsyncStateProps, type AuditEvent, AuditMeta, type AuditMetaProps, AuthLayout, type AuthLayoutProps, Autocomplete, type AutocompleteProps, Avatar, AvatarGroup, type AvatarGroupProps, type AvatarProps, type AvatarShape, type AvatarSize, type AvatarStatus, type AvatarTint, type AvatarVariant, Badge, type BadgeProps, BottomTabs, type BottomTabsProps, Breadcrumb, type BreadcrumbItem, type BreadcrumbProps, Button, type ButtonProps, Calendar, type CalendarDay, type CalendarEvent, CalendarIcon, type CalendarMode, type CalendarProps, type CalendarRangeValue, Can, type CanProps, Card, CardBody, CardFooter, CardHeader, Chart, type ChartProps, type ChartSeries, CheckIcon, Checkbox, CheckboxGroup, type CheckboxGroupProps, type CheckboxProps, ChevronDownIcon, ChevronLeftIcon, ChevronRightIcon, ChevronUpIcon, ClockIcon, Collapse, type CollapseProps, ColorPicker, type ColorPickerProps, type ColumnCardRole, type CommandItem, CommandPalette, type CommandPaletteProps, ConfirmDialog, type ConfirmDialogProps, Container, ContextMenu, type ContextMenuProps, Countdown, type CountdownProps, type CrudActionOptions, type CrudCreateOptions, type CrudDialogOptions, type CrudDialogState, CrudDialogs, CrudPage, type CrudPageProps, CurrencyInput, type CurrencyInputProps, DEFAULT_COUNTRIES, DEFAULT_PAGE_SIZE_OPTIONS, DataTable, type DataTableColumn, type DataTableProps, type DataTableView, DatePicker, type DatePickerProps, DateRangeFilter, type DateRangeFilterProps, DateRangePicker, type DateRangePickerProps, type DateRangePreset, type DateRangeValue, DateTimePicker, type DateTimePickerProps, type DateTimeValue, type DescriptionItem, Descriptions, type DescriptionsProps, Divider, type DividerProps, Drawer, DrawerBody, DrawerClose, type DrawerComponent, DrawerFooter, DrawerHeader, type DrawerPosition, type DrawerProps, type DrawerRef, type DrawerSize, DrawerTitle, DropdownMenu, type DropdownMenuProps, DurationDisplay, type DurationDisplayProps, EmptyState, type EmptyStateProps, EntityMeta, type EntityMetaProps, ErrorState, type ErrorStateProps, EventCalendar, type EventCalendarProps, EyeIcon, EyeOffIcon, Field, type FieldBindingLike, type FieldProps, type FieldStatus, type FieldType, type FieldValue, FileUpload, type FileUploadProps, FiltersBar, type FiltersBarProps, Form, type FormEntry, Field as FormField, type FormFieldConfig, type FormFieldGroup, type FieldProps as FormFieldProps, type FormProps, type FormShape, Heading, type HeadingProps, HoverCard, type HoverCardProps, type IDrawerProps, type ILabelProps, type ITooltipProps, type ITooltipVariant, IconButton, type IconButtonProps, ImageUpload, type ImageUploadProps, InfoIcon, InlineCode, Input, InputNumber, type InputNumberProps, type InputProps, JsonEditor, type JsonEditorProps, KpiGrid, type KpiGridProps, Label, type LabelProps, MarkdownEditor, type MarkdownEditorProps, type MenuEntry, type MenuItem, type MenuLabel, MenuList, type MenuListProps, type MenuSeparator, MiniCalendar, MinusIcon, Modal, type ModalProps, MonthPicker, type MonthPickerProps, MoreHorizontalIcon, MultiSelect, type MultiSelectProps, OtpInput, type OtpInputProps, Overlay, type OverlayPlacement, type OverlayProps, PageHeader, type PageHeaderProps, type PageSizeContext, Pagination, type PaginationProps, PasswordInput, type PasswordInputProps, type PasswordStrength, PermissionGate, type PermissionGateProps, type PhoneCountry, PhoneInput, type PhoneInputProps, PlusIcon, Popover, type PopoverProps, Progress, type ProgressProps, QRCode, type QRCodeProps, Radio, RadioButton, type RadioButtonProps, RadioGroup, type RadioGroupProps, type RadioProps, Rating, type RatingProps, type ReferenceOption, ReferenceSelect, type ReferenceSelectProps, RelativeTime, type RelativeTimeProps, RequireSession, type RequireSessionProps, ResizablePanel, type ResizablePanelProps, type ResourceDefinition, type ResourceField, RichTextEditor, type RichTextEditorProps, type RowAction, ScrollArea, type ScrollAreaProps, SearchIcon, SearchInput, type SearchInputProps, Select, type SelectOption, type SelectProps, SettingsIcon, Sidebar, type SidebarEntry, type SidebarItem, type SidebarProps, type SidebarRenderLink, type SidebarSection, type SidebarState, Skeleton, type SkeletonProps, Slider, type SliderProps, type SliderRangeValue, Sparkline, type SparklineProps, Spinner, type SpinnerProps, Stack, StarIcon, StatCard, type StatCardProps, Statistic, type StatisticProps, type StepItem, type StepStatus, Steps, type StepsProps, Switch, type SwitchProps, Tabs, TabsContent, TabsList, type TabsProps, TabsTrigger, TagsInput, type TagsInputProps, Text, type TextProps, Textarea, type TextareaProps, type TimeParts, TimePicker, type TimePickerProps, TimeRangePicker, type TimeRangePickerProps, type TimeRangeValue, Timeline, type TimelineItem, type TimelineProps, Timer, type TimerProps, ToastProvider, type ToastProviderProps, Toaster, type ToasterProps, Toggle, ToggleGroup, type ToggleGroupOption, type ToggleGroupProps, type ToggleProps, Tooltip, type TooltipProps, type TooltipVariant, Tour, type TourProps, type TourStep, Transfer, type TransferItem, type TransferProps, TrashIcon, Tree, type TreeNode, type TreeProps, TreeSelect, type TreeSelectProps, UnsavedChangesGuard, type UnsavedChangesGuardProps, UploadIcon, type UseDataTableQueryOptions, WeekPicker, type WeekPickerProps, XIcon, YearPicker, type YearPickerProps, confirmUnsavedNavigation, createUrlTableStorage, defineResource, formFieldNames, formatDuration, formatTimeValue, initialsOf, parseTimeValue, resourceColumns, resourceDefaults, resourceDetailColumns, resourceFormFields, resourcePermissions, resourceRowKey, resourceSearchKeys, resourceValidator, tintForName, useDataTableQuery, useToast };
3778
+ export { Accordion, type AccordionItem, type AccordionProps, type ActivityEntry, ActivityIcon, ActivityLog, type ActivityLogFilter, type ActivityLogProps, Alert, AlertCircleIcon, type AlertProps, AmountDisplay, type AmountDisplayProps, AppShell, AppShellBrand, type AppShellBrandProps, type AppShellCollapsible, type AppShellContentWidth, type AppShellMobileNav, type AppShellProps, AppShellRailItem, type AppShellRailItemProps, ArrowRightIcon, AspectRatio, type AspectRatioProps, AsyncState, type AsyncStateProps, type AuditEvent, AuditMeta, type AuditMetaProps, AuthLayout, type AuthLayoutProps, Autocomplete, type AutocompleteProps, Avatar, AvatarGroup, type AvatarGroupProps, type AvatarProps, type AvatarShape, type AvatarSize, type AvatarStatus, type AvatarTint, type AvatarVariant, Badge, type BadgeProps, BottomTabs, type BottomTabsProps, Breadcrumb, type BreadcrumbItem, type BreadcrumbProps, Button, type ButtonProps, Calendar, type CalendarDay, type CalendarEvent, CalendarIcon, type CalendarMode, type CalendarProps, type CalendarRangeValue, Can, type CanProps, Card, CardBody, CardFooter, CardHeader, Chart, type ChartProps, type ChartSeries, CheckIcon, Checkbox, CheckboxGroup, type CheckboxGroupProps, type CheckboxProps, ChevronDownIcon, ChevronLeftIcon, ChevronRightIcon, ChevronUpIcon, ClockIcon, Collapse, type CollapseProps, ColorPicker, type ColorPickerProps, type ColumnCardRole, type CommandItem, CommandPalette, type CommandPaletteProps, ConfirmDialog, type ConfirmDialogProps, Container, ContextMenu, type ContextMenuProps, Countdown, type CountdownProps, type CrudActionOptions, type CrudCreateOptions, type CrudDialogOptions, type CrudDialogState, CrudDialogs, CrudPage, type CrudPageProps, CurrencyInput, type CurrencyInputProps, DEFAULT_COUNTRIES, DEFAULT_PAGE_SIZE_OPTIONS, DataTable, type DataTableColumn, type DataTableProps, type DataTableView, DatePicker, type DatePickerProps, DateRangeFilter, type DateRangeFilterProps, DateRangePicker, type DateRangePickerProps, type DateRangePreset, type DateRangeValue, DateTimePicker, type DateTimePickerProps, type DateTimeValue, type DescriptionItem, Descriptions, type DescriptionsProps, Divider, type DividerProps, Drawer, DrawerBody, DrawerClose, type DrawerComponent, DrawerFooter, DrawerHeader, type DrawerPosition, type DrawerProps, type DrawerRef, type DrawerSize, DrawerTitle, DropdownMenu, type DropdownMenuProps, DurationDisplay, type DurationDisplayProps, EmptyState, type EmptyStateProps, EntityMeta, type EntityMetaProps, ErrorState, type ErrorStateProps, EventCalendar, type EventCalendarProps, EyeIcon, EyeOffIcon, Field, type FieldBindingLike, type FieldProps, type FieldStatus, type FieldType, type FieldValue, FileUpload, type FileUploadProps, FiltersBar, type FiltersBarProps, FolderIcon, Form, type FormEntry, Field as FormField, type FormFieldConfig, type FormFieldGroup, type FieldProps as FormFieldProps, type FormProps, type FormShape, Heading, type HeadingProps, HomeIcon, HoverCard, type HoverCardProps, type IDrawerProps, type ILabelProps, type ITooltipProps, type ITooltipVariant, IconButton, type IconButtonProps, ImageUpload, type ImageUploadProps, InfoIcon, InlineCode, Input, InputNumber, type InputNumberProps, type InputProps, JsonEditor, type JsonEditorProps, KeyIcon, KpiGrid, type KpiGridProps, Label, type LabelProps, LockIcon, LogOutIcon, MarkdownEditor, type MarkdownEditorProps, type MenuEntry, type MenuItem, type MenuLabel, MenuList, type MenuListProps, type MenuSeparator, MiniCalendar, MinusIcon, Modal, type ModalProps, MonthPicker, type MonthPickerProps, MoreHorizontalIcon, MultiSelect, type MultiSelectProps, OtpInput, type OtpInputProps, Overlay, type OverlayPlacement, type OverlayProps, PageHeader, type PageHeaderProps, type PageSizeContext, Pagination, type PaginationProps, PasswordInput, type PasswordInputProps, type PasswordStrength, PencilIcon, PermissionGate, type PermissionGateProps, type PhoneCountry, PhoneInput, type PhoneInputProps, PlusIcon, Popover, type PopoverProps, Progress, type ProgressProps, QRCode, type QRCodeProps, Radio, RadioButton, type RadioButtonProps, RadioGroup, type RadioGroupProps, type RadioProps, Rating, type RatingProps, type ReferenceOption, ReferenceSelect, type ReferenceSelectProps, RelativeTime, type RelativeTimeProps, RequireSession, type RequireSessionProps, ResizablePanel, type ResizablePanelProps, type ResourceDefinition, type ResourceField, type ResourceFormMode, RichTextEditor, type RichTextEditorProps, type RowAction, ScrollArea, type ScrollAreaProps, SearchIcon, SearchInput, type SearchInputProps, type SecretChanges, type SecretEntry, SecretFields, type SecretFieldsProps, Select, type SelectOption, type SelectProps, ServerIcon, SettingsIcon, Sidebar, type SidebarEntry, type SidebarItem, type SidebarProps, type SidebarRenderLink, type SidebarSection, type SidebarState, Skeleton, type SkeletonProps, Slider, type SliderProps, type SliderRangeValue, Sparkline, type SparklineProps, Spinner, type SpinnerProps, Stack, StarIcon, StatCard, type StatCardProps, Statistic, type StatisticProps, StatusBadge, type StatusBadgeProps, type StepItem, type StepStatus, Steps, type StepsProps, Switch, type SwitchProps, Tabs, TabsContent, TabsList, type TabsProps, TabsTrigger, TagsInput, type TagsInputProps, type TanStackRouterLike, Text, type TextProps, Textarea, type TextareaProps, type TimeParts, TimePicker, type TimePickerProps, TimeRangePicker, type TimeRangePickerProps, type TimeRangeValue, Timeline, type TimelineItem, type TimelineProps, Timer, type TimerProps, ToastProvider, type ToastProviderProps, Toaster, type ToasterProps, Toggle, ToggleGroup, type ToggleGroupOption, type ToggleGroupProps, type ToggleProps, Tooltip, type TooltipProps, type TooltipVariant, Tour, type TourProps, type TourStep, Transfer, type TransferItem, type TransferProps, TrashIcon, Tree, type TreeNode, type TreeProps, TreeSelect, type TreeSelectProps, UnsavedChangesGuard, type UnsavedChangesGuardProps, UploadIcon, type UseDataTableQueryOptions, UserIcon, UsersIcon, WeekPicker, type WeekPickerProps, XIcon, YearPicker, type YearPickerProps, activityColumns, clearSecretValues, confirmUnsavedNavigation, createTanStackRouterStorage, createUrlTableStorage, defineResource, formFieldNames, formatDuration, formatTimeValue, initialsOf, parseTimeValue, resourceColumns, resourceDefaults, resourceDetailColumns, resourceFormFields, resourcePermissions, resourceRowKey, resourceSearchKeys, resourceValidator, secretChanges, tintForName, toneOf, useDataTableQuery, useToast };