@starterlib/ui 0.1.1 → 0.3.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.
@@ -1,7 +1,111 @@
1
1
  import * as _angular_core from '@angular/core';
2
- import { InjectionToken, Provider, TemplateRef } from '@angular/core';
3
- import { Montant } from '@starterlib/util';
2
+ import { InjectionToken, Signal, Provider, DestroyRef, Resource, TemplateRef } from '@angular/core';
3
+ import { Ton, Montant, TonSemantique, ChoixDeTheme, Langue, EtatDeBloc } from '@starterlib/util';
4
+ export { ETATS_DE_BLOC, EtatDeBloc } from '@starterlib/util';
4
5
 
6
+ /**
7
+ * Les textes que les composants portent eux-memes.
8
+ *
9
+ * ⚠️ Ce ne sont pas « les textes de l'application » : le socle ne connait aucun
10
+ * ecran. Ce sont les quelques mots qu'un composant doit dire sans que
11
+ * l'appelant ait a les fournir a chaque usage — le nom d'un bouton de copie,
12
+ * l'annonce d'un chargement, la mention d'une ouverture dans une autre fenetre.
13
+ * Tout le reste est un `input` de l'appelant.
14
+ *
15
+ * Les entrees a trou sont des FONCTIONS, et non des gabarits a interpoler :
16
+ * l'ordre des mots change d'une langue a l'autre (« IBAN se terminant par
17
+ * 2606 » contre « IBAN ending in 2606 »), et une fonction laisse la langue
18
+ * decider, sans inventer un mini-langage de gabarit dans la librairie.
19
+ */
20
+ interface LibellesUi {
21
+ /** Indicateur d'activite, et etat de chargement d'un bloc. */
22
+ readonly chargementEnCours: string;
23
+ readonly erreurSurvenue: string;
24
+ readonly aucunResultat: string;
25
+ readonly horsConnexion: string;
26
+ /** Erreur : action de rejeu, et etiquette de l'identifiant technique. */
27
+ readonly reessayer: string;
28
+ readonly identifiantDeTrace: string;
29
+ /** Etiquette du code machine affiche a cote du message. */
30
+ readonly codeTechnique: string;
31
+ /** Valeur technique copiable. */
32
+ readonly copier: string;
33
+ readonly copieEffectuee: string;
34
+ readonly copieImpossible: string;
35
+ /** Valeur masquee. */
36
+ readonly afficher: string;
37
+ readonly masquer: string;
38
+ readonly valeurMasqueeANouveau: string;
39
+ readonly natureIban: string;
40
+ readonly natureCarte: string;
41
+ readonly natureTelephone: string;
42
+ readonly seTerminantPar: (nature: string, quatreDerniers: string) => string;
43
+ /** Lien sortant, etiquette de retrait, temps relatif. */
44
+ readonly nouvelleFenetre: string;
45
+ readonly retirer: string;
46
+ /** Structure */
47
+ readonly filDAriane: string;
48
+ readonly allerAuContenu: string;
49
+ readonly navigationPrincipale: string;
50
+ /** Transverses */
51
+ readonly theme: string;
52
+ readonly themeSysteme: string;
53
+ readonly themeClair: string;
54
+ readonly themeSombre: string;
55
+ readonly langue: string;
56
+ readonly reessayerDans: (duree: string) => string;
57
+ readonly reessayerMaintenant: string;
58
+ readonly sessionBientotExpiree: string;
59
+ readonly sessionExpireDans: (duree: string) => string;
60
+ readonly resterConnecte: string;
61
+ readonly seDeconnecter: string;
62
+ readonly fermerLeMessage: string;
63
+ /** Dialogues */
64
+ readonly confirmer: string;
65
+ readonly annuler: string;
66
+ readonly recopierPourConfirmer: (texte: string) => string;
67
+ readonly aLInstant: string;
68
+ }
69
+ /**
70
+ * Defaut francais, identique mot pour mot aux textes ecrits en dur jusqu'a la
71
+ * 0.1.1 : une application qui ne fournit rien ne change pas de comportement.
72
+ *
73
+ * Il existe pour que le socle reste utilisable sans i18n, pas pour dispenser
74
+ * d'en avoir une. Une application bilingue DOIT fournir son propre dictionnaire
75
+ * sous forme de signal — sinon la moitie de l'interface reste en francais quand
76
+ * l'utilisateur passe a l'anglais, et rien ne le signale.
77
+ */
78
+ /**
79
+ * ⚠️ Les textes AFFICHES portent leurs accents. La regle « sans accents » du
80
+ * depot vise la documentation et les commentaires, jamais ce que lit la
81
+ * personne qui utilise l'application : « Reessayer » ou « Aucun resultat » sont
82
+ * des fautes a l'ecran, et une synthese vocale les prononce de travers. La 0.2.0
83
+ * les a livres ainsi. Les accents s'ecrivent en sequence d'echappement, comme
84
+ * l'apostrophe typographique, pour garder la source en ASCII.
85
+ */
86
+ declare const LIBELLES_FR: LibellesUi;
87
+ /** Traduction anglaise du meme dictionnaire. La paire est obligatoire. */
88
+ declare const LIBELLES_EN: LibellesUi;
89
+
90
+ /**
91
+ * Locale de formatage des montants, des dates et des nombres, **sous forme de
92
+ * signal**.
93
+ *
94
+ * ⚠️ Pourquoi pas `LOCALE_ID` : il est fige au demarrage de l'application. Or
95
+ * l'ADR 0014 du backend exige de changer de langue SANS recharger — la coquille
96
+ * detient la langue, et tout doit basculer d'un coup. Un composant qui lit
97
+ * `LOCALE_ID` continuerait d'afficher « 1 234,50 € » dans une interface passee
98
+ * a l'anglais.
99
+ *
100
+ * Le defaut lit `LOCALE_ID` : une application qui ne fournit rien garde le
101
+ * comportement d'avant, simplement sans pouvoir changer de langue a chaud.
102
+ */
103
+ declare const ST_LOCALE: InjectionToken<Signal<string>>;
104
+ /**
105
+ * Textes portes par les composants eux-memes, sous forme de signal pour la
106
+ * meme raison que la locale.
107
+ */
108
+ declare const ST_LIBELLES: InjectionToken<Signal<LibellesUi>>;
5
109
  /**
6
110
  * Chemin du sprite SVG des icones, **fourni par l'application**.
7
111
  *
@@ -28,6 +132,29 @@ declare const CHEMIN_DU_SPRITE: InjectionToken<string>;
28
132
  * pourraient viser deux sprites differents.
29
133
  */
30
134
  declare function fournirCheminDuSprite(chemin: string): Provider;
135
+ /** Ce que l'application fournit a `@starterlib/ui`, et rien d'autre. */
136
+ interface ConfigurationUi {
137
+ /** Obligatoire : voir `CHEMIN_DU_SPRITE`. */
138
+ readonly cheminDuSprite: string;
139
+ /**
140
+ * Locale de formatage. Un signal quand la langue change a l'execution, ce
141
+ * qui est le cas des que la coquille porte un selecteur de langue.
142
+ */
143
+ readonly locale?: Signal<string> | string;
144
+ /** Textes portes par les composants. Un signal, pour la meme raison. */
145
+ readonly libelles?: Signal<LibellesUi> | LibellesUi;
146
+ /** Fuseau de rendu des dates. Vient de la personne connectee, pas du poste. */
147
+ readonly fuseau?: string;
148
+ }
149
+ /**
150
+ * Configure `@starterlib/ui` pour toute l'application.
151
+ *
152
+ * ⚠️ A appeler dans l'HOTE uniquement. Dans un assemblage federe, un remote qui
153
+ * la rappellerait poserait un second jeu de valeurs dans son injecteur de
154
+ * route : deux locales, deux dictionnaires, et la moitie de l'ecran resterait
155
+ * dans l'ancienne langue apres une bascule.
156
+ */
157
+ declare function provideStarterUi(configuration: ConfigurationUi): Provider[];
31
158
  /**
32
159
  * Marque la presence d'une region vivante possedee par un ancetre, en pratique
33
160
  * le composant `st-state`.
@@ -47,14 +174,61 @@ declare const REGION_VIVANTE_PARENTE: InjectionToken<true>;
47
174
  declare const FUSEAU_PAR_DEFAUT: InjectionToken<string>;
48
175
 
49
176
  /**
50
- * Les cinq etats que tout bloc consommant l'API doit traiter. Le type les
51
- * enumere pour qu'aucun ne s'oublie : un `switch` non exhaustif ne compile pas.
177
+ * Texte d'une petite region vivante propre a un composant.
178
+ *
179
+ * ```ts
180
+ * protected readonly annonce = new AnnonceLocale(inject(DestroyRef));
181
+ * // gabarit : <span class="st-vh" aria-live="polite">{{ annonce.texte() }}</span>
182
+ * ```
183
+ *
184
+ * ⚠️ La region doit exister VIDE dans le gabarit des la creation du composant ;
185
+ * cette classe ne gere que son texte.
186
+ *
187
+ * ⚠️ Nee de deux defauts de `st-code` en 0.2.0 : un `onDestroy` enregistre a
188
+ * chaque clic, et une confirmation identique reposee dans la meme tache — la
189
+ * seconde copie n'etait jamais annoncee.
190
+ */
191
+ declare class AnnonceLocale {
192
+ private readonly contenu;
193
+ private minuteries;
194
+ readonly texte: _angular_core.Signal<string>;
195
+ constructor(destruction: DestroyRef);
196
+ annoncer(message: string): void;
197
+ private arreter;
198
+ }
199
+
200
+ /** Issue d'une copie. */
201
+ type IssueDeCopie = 'copie' | 'indisponible' | 'refusee';
202
+ /**
203
+ * Ecrit un texte dans le presse-papiers.
204
+ *
205
+ * ⚠️ Trois issues, et non deux. `navigator.clipboard` n'existe qu'en contexte
206
+ * securise (HTTPS, ou `localhost`) : absent, c'est `indisponible`. Present, il
207
+ * peut encore refuser — permission, document sans focus — et c'est `refusee`.
208
+ * Confondre les deux conduit a cacher un bouton qui aurait fonctionne au clic
209
+ * suivant, ou a laisser croire qu'une copie a eu lieu.
210
+ *
211
+ * ⚠️ Ce qui entre dans le presse-papiers en sort difficilement : les
212
+ * gestionnaires d'historique le conservent, et la synchronisation entre
213
+ * appareils le propage. Jamais de secret — mot de passe, jeton, code a usage
214
+ * unique — et une donnee sensible seulement a la demande explicite de la
215
+ * personne.
216
+ */
217
+ declare function copierDansLePressePapiers(document: Document, texte: string): Promise<IssueDeCopie>;
218
+ /** Vrai si le navigateur expose un presse-papiers ecrivable par script. */
219
+ declare function pressePapiersDisponible(document: Document): boolean;
220
+
221
+ /**
222
+ * Formate une duree en secondes : « 45 s », « 2 min 05 s ».
223
+ *
224
+ * Unites courtes de la langue donnee, par `Intl.NumberFormat` : l'ordre, les
225
+ * espaces et les abreviations suivent la locale, sans table maison.
52
226
  */
53
- type EtatDeBloc = 'chargement' | 'erreur' | 'vide' | 'hors-ligne' | 'succes';
54
- declare const ETATS_DE_BLOC: readonly EtatDeBloc[];
227
+ declare function formaterDuree(totalEnSecondes: number, locale: string): string;
55
228
 
56
229
  type TailleDIcone = 'xs' | 'sm' | 'md' | 'lg' | 'xl';
57
- type TonDIcone = 'courant' | 'discret' | 'primaire' | 'succes' | 'avertissement' | 'danger';
230
+ /** Une icone prend n'importe quel ton sauf `inverse`, qui vise un fond plein. */
231
+ type TonDIcone = Exclude<Ton, 'inverse'>;
58
232
  /**
59
233
  * Icone tiree d'un sprite SVG servi en meme origine.
60
234
  *
@@ -69,13 +243,13 @@ type TonDIcone = 'courant' | 'discret' | 'primaire' | 'succes' | 'avertissement'
69
243
  */
70
244
  declare class StIcon {
71
245
  private readonly cheminDuSprite;
72
- readonly nom: _angular_core.InputSignal<"hors-ligne" | "boite-vide" | "cercle" | "cercle-coche" | "cercle-croix" | "cercle-info" | "chevron-bas" | "chevron-droite" | "chevron-gauche" | "chevron-haut" | "coche" | "copie" | "corbeille" | "croix" | "lien-externe" | "menu" | "oeil" | "oeil-barre" | "plus" | "rafraichir" | "recherche" | "serveur" | "triangle-alerte" | "utilisateur">;
246
+ readonly nom: _angular_core.InputSignal<"copie" | "boite-vide" | "cercle" | "cercle-coche" | "cercle-croix" | "cercle-info" | "chevron-bas" | "chevron-droite" | "chevron-gauche" | "chevron-haut" | "coche" | "corbeille" | "croix" | "hors-ligne" | "lien-externe" | "menu" | "oeil" | "oeil-barre" | "plus" | "rafraichir" | "recherche" | "serveur" | "triangle-alerte" | "utilisateur">;
73
247
  readonly taille: _angular_core.InputSignal<TailleDIcone>;
74
248
  readonly ton: _angular_core.InputSignal<TonDIcone>;
75
249
  /** `null` : l'icone est decorative et reste muette pour les lecteurs. */
76
250
  readonly etiquette: _angular_core.InputSignal<string | null>;
77
- readonly estDecorative: _angular_core.Signal<boolean>;
78
- readonly reference: _angular_core.Signal<string>;
251
+ protected readonly estDecorative: _angular_core.Signal<boolean>;
252
+ protected readonly reference: _angular_core.Signal<string>;
79
253
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<StIcon, never>;
80
254
  static ɵcmp: _angular_core.ɵɵComponentDeclaration<StIcon, "st-icon", never, { "nom": { "alias": "nom"; "required": true; "isSignal": true; }; "taille": { "alias": "taille"; "required": false; "isSignal": true; }; "ton": { "alias": "ton"; "required": false; "isSignal": true; }; "etiquette": { "alias": "etiquette"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
81
255
  }
@@ -103,7 +277,7 @@ type GraisseDeTexte = 'normale' | 'moyenne' | 'semi';
103
277
  declare class StText {
104
278
  readonly variante: _angular_core.InputSignal<VarianteDeTexte>;
105
279
  readonly graisse: _angular_core.InputSignal<GraisseDeTexte>;
106
- readonly enLigne: _angular_core.InputSignal<boolean>;
280
+ readonly enLigne: _angular_core.InputSignalWithTransform<boolean, unknown>;
107
281
  /**
108
282
  * Nombre de lignes au-dela duquel le texte est coupe.
109
283
  *
@@ -134,13 +308,13 @@ declare class StHeading {
134
308
  readonly taille: _angular_core.InputSignal<TailleDeTitre | null>;
135
309
  /** Cible d'un `aria-labelledby` : une region se nomme par son titre. */
136
310
  readonly identifiant: _angular_core.InputSignal<string | null>;
137
- readonly tailleEffective: _angular_core.Signal<TailleDeTitre>;
311
+ protected readonly tailleEffective: _angular_core.Signal<TailleDeTitre>;
138
312
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<StHeading, never>;
139
313
  static ɵcmp: _angular_core.ɵɵComponentDeclaration<StHeading, "st-heading", never, { "niveau": { "alias": "niveau"; "required": true; "isSignal": true; }; "taille": { "alias": "taille"; "required": false; "isSignal": true; }; "identifiant": { "alias": "identifiant"; "required": false; "isSignal": true; }; }, {}, never, ["*"], true, never>;
140
314
  }
141
315
 
142
316
  type TailleDeSpinner = 'sm' | 'md' | 'lg';
143
- type TonDeSpinner = 'courant' | 'primaire' | 'inverse';
317
+ type TonDeSpinner = Extract<Ton, 'neutre' | 'primaire' | 'inverse'>;
144
318
  /**
145
319
  * Indicateur d'activite indeterminee.
146
320
  *
@@ -156,15 +330,18 @@ type TonDeSpinner = 'courant' | 'primaire' | 'inverse';
156
330
  */
157
331
  declare class StSpinner {
158
332
  private readonly regionParente;
333
+ private readonly libelles;
159
334
  readonly taille: _angular_core.InputSignal<TailleDeSpinner>;
160
335
  readonly ton: _angular_core.InputSignal<TonDeSpinner>;
161
- readonly etiquette: _angular_core.InputSignal<string>;
162
- readonly sAnnonce: _angular_core.Signal<boolean>;
336
+ /** `null` : le texte vient du dictionnaire de l'application. */
337
+ readonly etiquette: _angular_core.InputSignal<string | null>;
338
+ protected readonly etiquetteLue: _angular_core.Signal<string>;
339
+ protected readonly sAnnonce: _angular_core.Signal<boolean>;
163
340
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<StSpinner, never>;
164
341
  static ɵcmp: _angular_core.ɵɵComponentDeclaration<StSpinner, "st-spinner", never, { "taille": { "alias": "taille"; "required": false; "isSignal": true; }; "ton": { "alias": "ton"; "required": false; "isSignal": true; }; "etiquette": { "alias": "etiquette"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
165
342
  }
166
343
 
167
- type TonDeProgression = 'primaire' | 'succes' | 'danger';
344
+ type TonDeProgression = Extract<Ton, 'primaire' | 'succes' | 'danger'>;
168
345
  /**
169
346
  * Barre de progression, determinee ou indeterminee.
170
347
  *
@@ -181,10 +358,10 @@ declare class StProgress {
181
358
  readonly ton: _angular_core.InputSignal<TonDeProgression>;
182
359
  /** Texte lu a la place du pourcentage quand celui-ci n'est pas parlant. */
183
360
  readonly texteDeValeur: _angular_core.InputSignal<string | null>;
184
- readonly estIndeterminee: _angular_core.Signal<boolean>;
361
+ protected readonly estIndeterminee: _angular_core.Signal<boolean>;
185
362
  /** Omis quand la progression est indeterminee : l'annoncer serait faux. */
186
- readonly valeurAnnoncee: _angular_core.Signal<number | null>;
187
- readonly pourcentage: _angular_core.Signal<number>;
363
+ protected readonly valeurAnnoncee: _angular_core.Signal<number | null>;
364
+ protected readonly pourcentage: _angular_core.Signal<number>;
188
365
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<StProgress, never>;
189
366
  static ɵcmp: _angular_core.ɵɵComponentDeclaration<StProgress, "st-progress", never, { "valeur": { "alias": "valeur"; "required": false; "isSignal": true; }; "max": { "alias": "max"; "required": false; "isSignal": true; }; "etiquette": { "alias": "etiquette"; "required": true; "isSignal": true; }; "ton": { "alias": "ton"; "required": false; "isSignal": true; }; "texteDeValeur": { "alias": "texteDeValeur"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
190
367
  }
@@ -204,14 +381,20 @@ declare class StSkeleton {
204
381
  readonly variante: _angular_core.InputSignal<VarianteDeSquelette>;
205
382
  readonly lignes: _angular_core.InputSignal<number>;
206
383
  readonly colonnes: _angular_core.InputSignal<number>;
207
- readonly anime: _angular_core.InputSignal<boolean>;
208
- readonly indicesDeLigne: _angular_core.Signal<number[]>;
209
- readonly indicesDeColonne: _angular_core.Signal<number[]>;
384
+ readonly anime: _angular_core.InputSignalWithTransform<boolean, unknown>;
385
+ protected readonly indicesDeLigne: _angular_core.Signal<number[]>;
386
+ protected readonly indicesDeColonne: _angular_core.Signal<number[]>;
210
387
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<StSkeleton, never>;
211
388
  static ɵcmp: _angular_core.ɵɵComponentDeclaration<StSkeleton, "st-skeleton", never, { "variante": { "alias": "variante"; "required": false; "isSignal": true; }; "lignes": { "alias": "lignes"; "required": false; "isSignal": true; }; "colonnes": { "alias": "colonnes"; "required": false; "isSignal": true; }; "anime": { "alias": "anime"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
212
389
  }
213
390
 
214
- type VarianteDeBouton = 'primaire' | 'secondaire' | 'discret' | 'destructeur';
391
+ /**
392
+ * ⚠️ Une variante dit quel FOND le bouton prend, pas ce qu'il signifie ; c'est
393
+ * un axe distinct du ton, et il le reste. Mais son quatrieme membre s'appelle
394
+ * `danger` comme partout ailleurs : il n'y a aucune raison qu'un bouton rouge
395
+ * et une pastille rouge portent deux mots differents.
396
+ */
397
+ type VarianteDeBouton = 'primaire' | 'secondaire' | 'discret' | 'danger';
215
398
  type TailleDeBouton = 'sm' | 'md' | 'lg';
216
399
  /**
217
400
  * Bouton du socle, pose en ATTRIBUT sur un `<button>` natif.
@@ -235,27 +418,38 @@ type TailleDeBouton = 'sm' | 'md' | 'lg';
235
418
  declare class StButton {
236
419
  readonly variante: _angular_core.InputSignal<VarianteDeBouton>;
237
420
  readonly taille: _angular_core.InputSignal<TailleDeBouton>;
238
- readonly pleineLargeur: _angular_core.InputSignal<boolean>;
239
- readonly iconeAvant: _angular_core.InputSignal<"hors-ligne" | "boite-vide" | "cercle" | "cercle-coche" | "cercle-croix" | "cercle-info" | "chevron-bas" | "chevron-droite" | "chevron-gauche" | "chevron-haut" | "coche" | "copie" | "corbeille" | "croix" | "lien-externe" | "menu" | "oeil" | "oeil-barre" | "plus" | "rafraichir" | "recherche" | "serveur" | "triangle-alerte" | "utilisateur" | null>;
240
- readonly iconeApres: _angular_core.InputSignal<"hors-ligne" | "boite-vide" | "cercle" | "cercle-coche" | "cercle-croix" | "cercle-info" | "chevron-bas" | "chevron-droite" | "chevron-gauche" | "chevron-haut" | "coche" | "copie" | "corbeille" | "croix" | "lien-externe" | "menu" | "oeil" | "oeil-barre" | "plus" | "rafraichir" | "recherche" | "serveur" | "triangle-alerte" | "utilisateur" | null>;
421
+ readonly pleineLargeur: _angular_core.InputSignalWithTransform<boolean, unknown>;
422
+ readonly iconeAvant: _angular_core.InputSignal<"copie" | "boite-vide" | "cercle" | "cercle-coche" | "cercle-croix" | "cercle-info" | "chevron-bas" | "chevron-droite" | "chevron-gauche" | "chevron-haut" | "coche" | "corbeille" | "croix" | "hors-ligne" | "lien-externe" | "menu" | "oeil" | "oeil-barre" | "plus" | "rafraichir" | "recherche" | "serveur" | "triangle-alerte" | "utilisateur" | null>;
423
+ readonly iconeApres: _angular_core.InputSignal<"copie" | "boite-vide" | "cercle" | "cercle-coche" | "cercle-croix" | "cercle-info" | "chevron-bas" | "chevron-droite" | "chevron-gauche" | "chevron-haut" | "coche" | "corbeille" | "croix" | "hors-ligne" | "lien-externe" | "menu" | "oeil" | "oeil-barre" | "plus" | "rafraichir" | "recherche" | "serveur" | "triangle-alerte" | "utilisateur" | null>;
241
424
  /**
242
425
  * Action en cours. Tant qu'il vaut vrai, les clics sont avales : c'est le
243
426
  * mecanisme d'anti double soumission. L'appelant doit le lever DES la
244
427
  * soumission, pas a l'arrivee de la reponse.
245
428
  */
246
- readonly chargement: _angular_core.InputSignal<boolean>;
429
+ readonly chargement: _angular_core.InputSignalWithTransform<boolean, unknown>;
430
+ /**
431
+ * L'action existe mais n'est pas disponible : une condition n'est pas encore
432
+ * remplie.
433
+ *
434
+ * ⚠️ `aria-disabled` et NON l'attribut natif `disabled`, qui retire le bouton
435
+ * de l'ordre de tabulation. Une personne au clavier ne l'atteindrait plus, et
436
+ * ne decouvrirait donc jamais la condition qui le bloque — le bouton aurait
437
+ * simplement disparu de son parcours. Ici il reste atteignable, annonce comme
438
+ * indisponible, et ses clics sont avales.
439
+ */
440
+ readonly indisponible: _angular_core.InputSignalWithTransform<boolean, unknown>;
247
441
  /**
248
442
  * Le ton suit le FOND du bouton, et non le bouton en general : sur une
249
443
  * variante posee sur la surface (`secondaire`, qui est le defaut, et
250
444
  * `discret`), un indicateur en ton inverse tombait a 1,00:1 — invisible.
251
445
  */
252
- readonly tonDuChargement: _angular_core.Signal<TonDeSpinner>;
446
+ protected readonly tonDuChargement: _angular_core.Signal<TonDeSpinner>;
253
447
  constructor();
254
448
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<StButton, never>;
255
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<StButton, "button[stButton]", never, { "variante": { "alias": "variante"; "required": false; "isSignal": true; }; "taille": { "alias": "taille"; "required": false; "isSignal": true; }; "pleineLargeur": { "alias": "pleineLargeur"; "required": false; "isSignal": true; }; "iconeAvant": { "alias": "iconeAvant"; "required": false; "isSignal": true; }; "iconeApres": { "alias": "iconeApres"; "required": false; "isSignal": true; }; "chargement": { "alias": "chargement"; "required": false; "isSignal": true; }; }, {}, never, ["*"], true, never>;
449
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<StButton, "button[stButton]", never, { "variante": { "alias": "variante"; "required": false; "isSignal": true; }; "taille": { "alias": "taille"; "required": false; "isSignal": true; }; "pleineLargeur": { "alias": "pleineLargeur"; "required": false; "isSignal": true; }; "iconeAvant": { "alias": "iconeAvant"; "required": false; "isSignal": true; }; "iconeApres": { "alias": "iconeApres"; "required": false; "isSignal": true; }; "chargement": { "alias": "chargement"; "required": false; "isSignal": true; }; "indisponible": { "alias": "indisponible"; "required": false; "isSignal": true; }; }, {}, never, ["*"], true, never>;
256
450
  }
257
451
 
258
- type VarianteDeBoutonIcone = 'discret' | 'secondaire' | 'destructeur';
452
+ type VarianteDeBoutonIcone = Extract<VarianteDeBouton, 'discret' | 'secondaire' | 'danger'>;
259
453
  /**
260
454
  * Bouton reduit a une icone, pose en attribut sur un `<button>` natif.
261
455
  *
@@ -264,15 +458,22 @@ type VarianteDeBoutonIcone = 'discret' | 'secondaire' | 'destructeur';
264
458
  * de facon fiable.
265
459
  */
266
460
  declare class StIconButton {
267
- readonly icone: _angular_core.InputSignal<"hors-ligne" | "boite-vide" | "cercle" | "cercle-coche" | "cercle-croix" | "cercle-info" | "chevron-bas" | "chevron-droite" | "chevron-gauche" | "chevron-haut" | "coche" | "copie" | "corbeille" | "croix" | "lien-externe" | "menu" | "oeil" | "oeil-barre" | "plus" | "rafraichir" | "recherche" | "serveur" | "triangle-alerte" | "utilisateur">;
461
+ readonly icone: _angular_core.InputSignal<"copie" | "boite-vide" | "cercle" | "cercle-coche" | "cercle-croix" | "cercle-info" | "chevron-bas" | "chevron-droite" | "chevron-gauche" | "chevron-haut" | "coche" | "corbeille" | "croix" | "hors-ligne" | "lien-externe" | "menu" | "oeil" | "oeil-barre" | "plus" | "rafraichir" | "recherche" | "serveur" | "triangle-alerte" | "utilisateur">;
268
462
  /** Nom accessible du controle. Sans lui, l'icone ne dit rien. */
269
463
  readonly etiquette: _angular_core.InputSignal<string>;
270
464
  readonly variante: _angular_core.InputSignal<VarianteDeBoutonIcone>;
271
465
  readonly taille: _angular_core.InputSignal<"sm" | "md">;
272
- /** `null` : le bouton n'est pas a deux etats et n'annonce aucune pression. */
273
- readonly enfonce: _angular_core.ModelSignal<boolean | null>;
466
+ /**
467
+ * `null` : le bouton n'est pas a deux etats et n'annonce aucune pression.
468
+ *
469
+ * ⚠️ Une ENTREE, et non un `model`. Le composant ne bascule rien de lui-meme :
470
+ * l'etat enfonce reflete une donnee que l'appelant detient. En `model`,
471
+ * `[(enfonce)]` compilait et ne remontait jamais — une liaison bidirectionnelle
472
+ * muette est pire qu'absente, puisqu'elle se relit comme fonctionnelle.
473
+ */
474
+ readonly enfonce: _angular_core.InputSignal<boolean | null>;
274
475
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<StIconButton, never>;
275
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<StIconButton, "button[stIconButton]", never, { "icone": { "alias": "icone"; "required": true; "isSignal": true; }; "etiquette": { "alias": "etiquette"; "required": true; "isSignal": true; }; "variante": { "alias": "variante"; "required": false; "isSignal": true; }; "taille": { "alias": "taille"; "required": false; "isSignal": true; }; "enfonce": { "alias": "enfonce"; "required": false; "isSignal": true; }; }, { "enfonce": "enfonceChange"; }, never, never, true, never>;
476
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<StIconButton, "button[stIconButton]", never, { "icone": { "alias": "icone"; "required": true; "isSignal": true; }; "etiquette": { "alias": "etiquette"; "required": true; "isSignal": true; }; "variante": { "alias": "variante"; "required": false; "isSignal": true; }; "taille": { "alias": "taille"; "required": false; "isSignal": true; }; "enfonce": { "alias": "enfonce"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
276
477
  }
277
478
 
278
479
  type VarianteDeLien = 'texte' | 'autonome' | 'discret';
@@ -287,11 +488,16 @@ type VarianteDeLien = 'texte' | 'autonome' | 'discret';
287
488
  * quiconque regarde l'ecran.
288
489
  */
289
490
  declare class StLink {
491
+ private readonly libelles;
290
492
  readonly variante: _angular_core.InputSignal<VarianteDeLien>;
291
493
  /** Ouvre dans un nouvel onglet, et l'annonce dans le nom accessible. */
292
- readonly externe: _angular_core.InputSignal<boolean>;
293
- /** Mention lue par les lecteurs d'ecran quand le lien sort du site. */
294
- readonly mentionExterne: _angular_core.InputSignal<string>;
494
+ readonly externe: _angular_core.InputSignalWithTransform<boolean, unknown>;
495
+ /**
496
+ * Mention lue par les lecteurs d'ecran quand le lien sort du site.
497
+ * `null` : le texte vient du dictionnaire de l'application.
498
+ */
499
+ readonly mentionExterne: _angular_core.InputSignal<string | null>;
500
+ protected readonly mentionExterneLue: _angular_core.Signal<string>;
295
501
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<StLink, never>;
296
502
  static ɵcmp: _angular_core.ɵɵComponentDeclaration<StLink, "a[stLink]", never, { "variante": { "alias": "variante"; "required": false; "isSignal": true; }; "externe": { "alias": "externe"; "required": false; "isSignal": true; }; "mentionExterne": { "alias": "mentionExterne"; "required": false; "isSignal": true; }; }, {}, never, ["*"], true, never>;
297
503
  }
@@ -309,7 +515,7 @@ declare class StButtonGroup {
309
515
  readonly etiquette: _angular_core.InputSignal<string>;
310
516
  readonly orientation: _angular_core.InputSignal<"horizontale" | "verticale">;
311
517
  /** Boutons jointifs, rayons fusionnes. */
312
- readonly attache: _angular_core.InputSignal<boolean>;
518
+ readonly attache: _angular_core.InputSignalWithTransform<boolean, unknown>;
313
519
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<StButtonGroup, never>;
314
520
  static ɵcmp: _angular_core.ɵɵComponentDeclaration<StButtonGroup, "st-button-group", never, { "etiquette": { "alias": "etiquette"; "required": true; "isSignal": true; }; "orientation": { "alias": "orientation"; "required": false; "isSignal": true; }; "attache": { "alias": "attache"; "required": false; "isSignal": true; }; }, {}, never, ["*"], true, never>;
315
521
  }
@@ -325,25 +531,26 @@ declare class StButtonGroup {
325
531
  */
326
532
  declare class StCode {
327
533
  private readonly document;
328
- private readonly destruction;
534
+ private readonly libelles;
329
535
  readonly valeur: _angular_core.InputSignal<string>;
330
- readonly etiquette: _angular_core.InputSignal<string>;
331
- readonly copiable: _angular_core.InputSignal<boolean>;
332
- readonly libelleCopier: _angular_core.InputSignal<string>;
333
- readonly messageDeConfirmation: _angular_core.InputSignal<string>;
536
+ readonly copiable: _angular_core.InputSignalWithTransform<boolean, unknown>;
537
+ /** `null` : les textes viennent du dictionnaire de l'application. */
538
+ readonly etiquette: _angular_core.InputSignal<string | null>;
539
+ readonly libelleCopier: _angular_core.InputSignal<string | null>;
540
+ readonly messageDeConfirmation: _angular_core.InputSignal<string | null>;
541
+ protected readonly etiquetteLue: _angular_core.Signal<string>;
542
+ protected readonly libelleCopierLu: _angular_core.Signal<string>;
334
543
  readonly copie: _angular_core.OutputEmitterRef<string>;
335
- private readonly confirmation;
336
- private minuterie;
337
- readonly texteDeConfirmation: _angular_core.Signal<string>;
544
+ protected readonly annonce: AnnonceLocale;
338
545
  /**
339
546
  * Le bouton n'apparait que si le navigateur sait copier. Sans presse-papiers,
340
547
  * un bouton qui ne fait rien vaut moins que la selection manuelle, que la
341
548
  * feuille garde possible (`user-select: all`).
342
549
  */
343
- readonly copiePossible: _angular_core.Signal<boolean>;
550
+ protected readonly copiePossible: _angular_core.Signal<boolean>;
344
551
  protected auClicDeCopie(): Promise<void>;
345
552
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<StCode, never>;
346
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<StCode, "st-code", never, { "valeur": { "alias": "valeur"; "required": true; "isSignal": true; }; "etiquette": { "alias": "etiquette"; "required": false; "isSignal": true; }; "copiable": { "alias": "copiable"; "required": false; "isSignal": true; }; "libelleCopier": { "alias": "libelleCopier"; "required": false; "isSignal": true; }; "messageDeConfirmation": { "alias": "messageDeConfirmation"; "required": false; "isSignal": true; }; }, { "copie": "copie"; }, never, never, true, never>;
553
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<StCode, "st-code", never, { "valeur": { "alias": "valeur"; "required": true; "isSignal": true; }; "copiable": { "alias": "copiable"; "required": false; "isSignal": true; }; "etiquette": { "alias": "etiquette"; "required": false; "isSignal": true; }; "libelleCopier": { "alias": "libelleCopier"; "required": false; "isSignal": true; }; "messageDeConfirmation": { "alias": "messageDeConfirmation"; "required": false; "isSignal": true; }; }, { "copie": "copie"; }, never, never, true, never>;
347
554
  }
348
555
 
349
556
  type TypeMasque = 'iban' | 'carte' | 'telephone';
@@ -359,24 +566,35 @@ type TypeMasque = 'iban' | 'carte' | 'telephone';
359
566
  * journal.
360
567
  */
361
568
  declare class StMasked {
362
- private readonly destruction;
569
+ private readonly libelles;
363
570
  readonly valeur: _angular_core.InputSignal<string>;
364
571
  readonly type: _angular_core.InputSignal<TypeMasque>;
365
572
  readonly revele: _angular_core.ModelSignal<boolean>;
366
- readonly revelationAutorisee: _angular_core.InputSignal<boolean>;
573
+ readonly revelationAutorisee: _angular_core.InputSignalWithTransform<boolean, unknown>;
367
574
  readonly dureeDeRevelationEnSecondes: _angular_core.InputSignal<number>;
368
- readonly libelleAfficher: _angular_core.InputSignal<string>;
369
- readonly libelleMasquer: _angular_core.InputSignal<string>;
575
+ /** `null` : les textes viennent du dictionnaire de l'application. */
576
+ readonly libelleAfficher: _angular_core.InputSignal<string | null>;
577
+ readonly libelleMasquer: _angular_core.InputSignal<string | null>;
370
578
  readonly revelation: _angular_core.OutputEmitterRef<{
371
579
  type: TypeMasque;
372
580
  }>;
373
- private readonly annonce;
374
- readonly texteDAnnonce: _angular_core.Signal<string>;
581
+ /**
582
+ * ⚠️ Par `AnnonceLocale`, et non par un signal pose directement. La 0.2.0
583
+ * reposait « Valeur masquee a nouveau » a l'identique : aucune mutation, donc
584
+ * une seconde remise en masque jamais annoncee.
585
+ */
586
+ protected readonly annonce: AnnonceLocale;
375
587
  private minuterie;
376
- readonly valeurMasquee: _angular_core.Signal<string>;
377
- readonly valeurAffichee: _angular_core.Signal<string>;
378
- readonly nomAccessible: _angular_core.Signal<string>;
379
- readonly libelleDuBouton: _angular_core.Signal<string>;
588
+ constructor();
589
+ protected readonly valeurMasquee: _angular_core.Signal<string>;
590
+ protected readonly valeurAffichee: _angular_core.Signal<string>;
591
+ /**
592
+ * La nature et la tournure viennent du dictionnaire : l'ordre des mots change
593
+ * d'une langue a l'autre, « IBAN se terminant par 2606 » contre « IBAN ending
594
+ * in 2606 ». Une chaine a trous ne suffirait pas.
595
+ */
596
+ protected readonly nomAccessible: _angular_core.Signal<string>;
597
+ protected readonly libelleDuBouton: _angular_core.Signal<string>;
380
598
  private valeurLisible;
381
599
  protected basculer(): void;
382
600
  private masquer;
@@ -398,11 +616,11 @@ declare class StMasked {
398
616
  declare class StMoney {
399
617
  private readonly locale;
400
618
  readonly valeur: _angular_core.InputSignal<Montant>;
401
- readonly signeExplicite: _angular_core.InputSignal<boolean>;
402
- readonly sansDevise: _angular_core.InputSignal<boolean>;
619
+ readonly signeExplicite: _angular_core.InputSignalWithTransform<boolean, unknown>;
620
+ readonly sansDevise: _angular_core.InputSignalWithTransform<boolean, unknown>;
403
621
  readonly taille: _angular_core.InputSignal<"sm" | "md" | "lg" | "xl">;
404
- readonly signe: _angular_core.Signal<"negatif" | "positif" | "nul">;
405
- readonly texte: _angular_core.Signal<string>;
622
+ protected readonly signe: _angular_core.Signal<"negatif" | "positif" | "nul">;
623
+ protected readonly texte: _angular_core.Signal<string>;
406
624
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<StMoney, never>;
407
625
  static ɵcmp: _angular_core.ɵɵComponentDeclaration<StMoney, "st-money", never, { "valeur": { "alias": "valeur"; "required": true; "isSignal": true; }; "signeExplicite": { "alias": "signeExplicite"; "required": false; "isSignal": true; }; "sansDevise": { "alias": "sansDevise"; "required": false; "isSignal": true; }; "taille": { "alias": "taille"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
408
626
  }
@@ -425,12 +643,33 @@ declare class StDate {
425
643
  readonly valeur: _angular_core.InputSignal<string | Date>;
426
644
  readonly format: _angular_core.InputSignal<FormatDeDate>;
427
645
  readonly fuseau: _angular_core.InputSignal<string | null>;
646
+ /**
647
+ * Une DATE DE CALENDRIER (`2026-09-12`) n'est pas un instant : une date de
648
+ * naissance, une echeance ou un jour de valeur n'ont pas d'heure, et ne
649
+ * doivent pas changer de jour selon le fuseau de qui les regarde.
650
+ *
651
+ * ⚠️ Le piege est dans la norme : `new Date('2026-09-12')` vaut minuit UTC,
652
+ * donc le 11 septembre partout a l'ouest de Greenwich. Une echeance affichee
653
+ * la veille est un defaut que personne ne voit depuis l'Europe.
654
+ */
655
+ private readonly estDateDeCalendrier;
428
656
  private readonly date;
429
- readonly estValide: _angular_core.Signal<boolean>;
430
- readonly iso: _angular_core.Signal<string | null>;
431
- readonly texte: _angular_core.Signal<string>;
657
+ protected readonly estValide: _angular_core.Signal<boolean>;
658
+ /**
659
+ * Le fuseau de rendu. Pour une date de calendrier, c'est UTC : la valeur a
660
+ * ete construite a minuit UTC, la relire en UTC rend donc le jour ecrit.
661
+ */
662
+ private readonly fuseauDeRendu;
663
+ /**
664
+ * Une date de calendrier porte `2026-09-12`, sans heure ni decalage : c'est
665
+ * la forme que la norme HTML attend, et la seule qui ne mente pas.
666
+ */
667
+ protected readonly iso: _angular_core.Signal<string | null>;
668
+ /** Une date sans heure ne peut pas en afficher une. */
669
+ private readonly optionsDeFormat;
670
+ protected readonly texte: _angular_core.Signal<string>;
432
671
  /** Forme longue, lue par les technologies d'assistance. */
433
- readonly texteAccessible: _angular_core.Signal<string | null>;
672
+ protected readonly texteAccessible: _angular_core.Signal<string | null>;
434
673
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<StDate, never>;
435
674
  static ɵcmp: _angular_core.ɵɵComponentDeclaration<StDate, "st-date", never, { "valeur": { "alias": "valeur"; "required": true; "isSignal": true; }; "format": { "alias": "format"; "required": false; "isSignal": true; }; "fuseau": { "alias": "fuseau"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
436
675
  }
@@ -447,20 +686,21 @@ declare class StDate {
447
686
  */
448
687
  declare class StRelativeTime {
449
688
  private readonly locale;
689
+ private readonly libelles;
450
690
  private readonly fuseau;
451
691
  readonly valeur: _angular_core.InputSignal<string | Date>;
452
- readonly rafraichir: _angular_core.InputSignal<boolean>;
692
+ readonly rafraichir: _angular_core.InputSignalWithTransform<boolean, unknown>;
453
693
  /** Au-dela de ce nombre de jours, la date absolue est plus parlante. */
454
694
  readonly seuilAbsoluEnJours: _angular_core.InputSignal<number>;
455
695
  private readonly destruction;
456
696
  private readonly maintenant;
457
697
  constructor();
458
698
  private dateEnMillisecondes;
459
- readonly estValide: _angular_core.Signal<boolean>;
460
- readonly iso: _angular_core.Signal<string | null>;
461
- readonly depasseLeSeuil: _angular_core.Signal<boolean>;
462
- readonly texte: _angular_core.Signal<string>;
463
- readonly texteAccessible: _angular_core.Signal<string>;
699
+ protected readonly estValide: _angular_core.Signal<boolean>;
700
+ protected readonly iso: _angular_core.Signal<string | null>;
701
+ protected readonly depasseLeSeuil: _angular_core.Signal<boolean>;
702
+ protected readonly texte: _angular_core.Signal<string>;
703
+ protected readonly texteAccessible: _angular_core.Signal<string>;
464
704
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<StRelativeTime, never>;
465
705
  static ɵcmp: _angular_core.ɵɵComponentDeclaration<StRelativeTime, "st-relative-time", never, { "valeur": { "alias": "valeur"; "required": true; "isSignal": true; }; "rafraichir": { "alias": "rafraichir"; "required": false; "isSignal": true; }; "seuilAbsoluEnJours": { "alias": "seuilAbsoluEnJours"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
466
706
  }
@@ -477,17 +717,22 @@ declare class StRelativeTime {
477
717
  declare class StCount {
478
718
  private readonly locale;
479
719
  readonly valeur: _angular_core.InputSignal<number>;
480
- readonly ton: _angular_core.InputSignal<"courant" | "discret">;
720
+ readonly ton: _angular_core.InputSignal<"neutre" | "discret">;
481
721
  /** `null` : jamais d'abreviation. */
482
722
  readonly abregerAuDela: _angular_core.InputSignal<number | null>;
483
- readonly estAbrege: _angular_core.Signal<boolean>;
484
- readonly texteComplet: _angular_core.Signal<string>;
485
- readonly texte: _angular_core.Signal<string>;
723
+ protected readonly estAbrege: _angular_core.Signal<boolean>;
724
+ protected readonly texteComplet: _angular_core.Signal<string>;
725
+ protected readonly texte: _angular_core.Signal<string>;
486
726
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<StCount, never>;
487
727
  static ɵcmp: _angular_core.ɵɵComponentDeclaration<StCount, "st-count", never, { "valeur": { "alias": "valeur"; "required": true; "isSignal": true; }; "ton": { "alias": "ton"; "required": false; "isSignal": true; }; "abregerAuDela": { "alias": "abregerAuDela"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
488
728
  }
489
729
 
490
- type TonDeStatut = 'neutre' | 'info' | 'succes' | 'avertissement' | 'danger';
730
+ /**
731
+ * ⚠️ `primaire` et non « info » : les deux designaient deja la meme couleur
732
+ * d'accent, et rien ne distinguait un statut « info » d'un statut « primaire »
733
+ * ailleurs dans le socle.
734
+ */
735
+ type TonDeStatut = TonSemantique;
491
736
  /**
492
737
  * Pastille de statut.
493
738
  *
@@ -505,13 +750,13 @@ declare class StStatusPill {
505
750
  readonly statut: _angular_core.InputSignal<string>;
506
751
  /** Texte deja traduit par l'appelant : le socle ne traduit rien. */
507
752
  readonly libelle: _angular_core.InputSignal<string>;
508
- readonly icone: _angular_core.InputSignal<"hors-ligne" | "boite-vide" | "cercle" | "cercle-coche" | "cercle-croix" | "cercle-info" | "chevron-bas" | "chevron-droite" | "chevron-gauche" | "chevron-haut" | "coche" | "copie" | "corbeille" | "croix" | "lien-externe" | "menu" | "oeil" | "oeil-barre" | "plus" | "rafraichir" | "recherche" | "serveur" | "triangle-alerte" | "utilisateur">;
509
- readonly ton: _angular_core.InputSignal<TonDeStatut>;
753
+ readonly icone: _angular_core.InputSignal<"copie" | "boite-vide" | "cercle" | "cercle-coche" | "cercle-croix" | "cercle-info" | "chevron-bas" | "chevron-droite" | "chevron-gauche" | "chevron-haut" | "coche" | "corbeille" | "croix" | "hors-ligne" | "lien-externe" | "menu" | "oeil" | "oeil-barre" | "plus" | "rafraichir" | "recherche" | "serveur" | "triangle-alerte" | "utilisateur">;
754
+ readonly ton: _angular_core.InputSignal<TonSemantique>;
510
755
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<StStatusPill, never>;
511
756
  static ɵcmp: _angular_core.ɵɵComponentDeclaration<StStatusPill, "st-status-pill", never, { "statut": { "alias": "statut"; "required": true; "isSignal": true; }; "libelle": { "alias": "libelle"; "required": true; "isSignal": true; }; "icone": { "alias": "icone"; "required": true; "isSignal": true; }; "ton": { "alias": "ton"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
512
757
  }
513
758
 
514
- type TonDeBadge = 'neutre' | 'primaire' | 'succes' | 'avertissement' | 'danger';
759
+ type TonDeBadge = TonSemantique;
515
760
  /**
516
761
  * Pastille de comptage superposee a un autre element.
517
762
  *
@@ -524,10 +769,10 @@ type TonDeBadge = 'neutre' | 'primaire' | 'succes' | 'avertissement' | 'danger';
524
769
  declare class StBadge {
525
770
  readonly valeur: _angular_core.InputSignal<string | number | null>;
526
771
  readonly max: _angular_core.InputSignal<number>;
527
- readonly ton: _angular_core.InputSignal<TonDeBadge>;
772
+ readonly ton: _angular_core.InputSignal<TonSemantique>;
528
773
  /** Point seul, sans chiffre : signale une nouveaute sans la quantifier. */
529
- readonly point: _angular_core.InputSignal<boolean>;
530
- readonly texte: _angular_core.Signal<string>;
774
+ readonly point: _angular_core.InputSignalWithTransform<boolean, unknown>;
775
+ protected readonly texte: _angular_core.Signal<string>;
531
776
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<StBadge, never>;
532
777
  static ɵcmp: _angular_core.ɵɵComponentDeclaration<StBadge, "st-badge", never, { "valeur": { "alias": "valeur"; "required": false; "isSignal": true; }; "max": { "alias": "max"; "required": false; "isSignal": true; }; "ton": { "alias": "ton"; "required": false; "isSignal": true; }; "point": { "alias": "point"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
533
778
  }
@@ -542,12 +787,14 @@ declare class StBadge {
542
787
  */
543
788
  declare class StTag {
544
789
  private readonly element;
790
+ private readonly libelles;
545
791
  readonly libelle: _angular_core.InputSignal<string>;
546
- readonly supprimable: _angular_core.InputSignal<boolean>;
547
- readonly ton: _angular_core.InputSignal<"primaire" | "neutre">;
548
- readonly prefixeDeSuppression: _angular_core.InputSignal<string>;
792
+ readonly supprimable: _angular_core.InputSignalWithTransform<boolean, unknown>;
793
+ readonly ton: _angular_core.InputSignal<"neutre" | "primaire">;
794
+ /** `null` : le texte vient du dictionnaire de l'application. */
795
+ readonly prefixeDeSuppression: _angular_core.InputSignal<string | null>;
549
796
  readonly supprime: _angular_core.OutputEmitterRef<void>;
550
- readonly libelleDeSuppression: _angular_core.Signal<string>;
797
+ protected readonly libelleDeSuppression: _angular_core.Signal<string>;
551
798
  protected auRetrait(): void;
552
799
  /**
553
800
  * Cible, dans l'ordre : le bouton de l'etiquette suivante, celui de la
@@ -575,12 +822,12 @@ declare class StAvatar {
575
822
  * `true` quand le nom figure deja a cote de l'avatar, ce qui est le cas
576
823
  * courant : l'avatar devient alors decoratif et se tait.
577
824
  */
578
- readonly nomAdjacent: _angular_core.InputSignal<boolean>;
825
+ readonly nomAdjacent: _angular_core.InputSignalWithTransform<boolean, unknown>;
579
826
  private readonly imageEchouee;
580
- readonly afficheLImage: _angular_core.Signal<boolean>;
581
- readonly initiales: _angular_core.Signal<string>;
827
+ protected readonly afficheLImage: _angular_core.Signal<boolean>;
828
+ protected readonly initiales: _angular_core.Signal<string>;
582
829
  /** Vide quand le nom est deja lisible a cote : eviter la double lecture. */
583
- readonly texteAlternatif: _angular_core.Signal<string>;
830
+ protected readonly texteAlternatif: _angular_core.Signal<string>;
584
831
  protected auxEchecsDImage(): void;
585
832
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<StAvatar, never>;
586
833
  static ɵcmp: _angular_core.ɵɵComponentDeclaration<StAvatar, "st-avatar", never, { "nom": { "alias": "nom"; "required": true; "isSignal": true; }; "sourceImage": { "alias": "sourceImage"; "required": false; "isSignal": true; }; "taille": { "alias": "taille"; "required": false; "isSignal": true; }; "forme": { "alias": "forme"; "required": false; "isSignal": true; }; "nomAdjacent": { "alias": "nomAdjacent"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
@@ -596,7 +843,7 @@ declare class StAvatar {
596
843
  declare class StEmpty {
597
844
  readonly titre: _angular_core.InputSignal<string>;
598
845
  readonly description: _angular_core.InputSignal<string | null>;
599
- readonly icone: _angular_core.InputSignal<"hors-ligne" | "boite-vide" | "cercle" | "cercle-coche" | "cercle-croix" | "cercle-info" | "chevron-bas" | "chevron-droite" | "chevron-gauche" | "chevron-haut" | "coche" | "copie" | "corbeille" | "croix" | "lien-externe" | "menu" | "oeil" | "oeil-barre" | "plus" | "rafraichir" | "recherche" | "serveur" | "triangle-alerte" | "utilisateur">;
846
+ readonly icone: _angular_core.InputSignal<"copie" | "boite-vide" | "cercle" | "cercle-coche" | "cercle-croix" | "cercle-info" | "chevron-bas" | "chevron-droite" | "chevron-gauche" | "chevron-haut" | "coche" | "corbeille" | "croix" | "hors-ligne" | "lien-externe" | "menu" | "oeil" | "oeil-barre" | "plus" | "rafraichir" | "recherche" | "serveur" | "triangle-alerte" | "utilisateur">;
600
847
  readonly niveauDuTitre: _angular_core.InputSignal<NiveauDeTitre>;
601
848
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<StEmpty, never>;
602
849
  static ɵcmp: _angular_core.ɵɵComponentDeclaration<StEmpty, "st-empty", never, { "titre": { "alias": "titre"; "required": true; "isSignal": true; }; "description": { "alias": "description"; "required": false; "isSignal": true; }; "icone": { "alias": "icone"; "required": false; "isSignal": true; }; "niveauDuTitre": { "alias": "niveauDuTitre"; "required": false; "isSignal": true; }; }, {}, never, ["*"], true, never>;
@@ -617,6 +864,7 @@ type VarianteDErreur = 'hors-ligne' | 'serveur' | 'client';
617
864
  */
618
865
  declare class StError {
619
866
  private readonly regionParente;
867
+ private readonly libelles;
620
868
  readonly variante: _angular_core.InputSignal<VarianteDErreur>;
621
869
  /** Code machine stable, tel que rendu par le backend. */
622
870
  readonly code: _angular_core.InputSignal<string>;
@@ -624,15 +872,19 @@ declare class StError {
624
872
  readonly message: _angular_core.InputSignal<string>;
625
873
  readonly traceId: _angular_core.InputSignal<string | null>;
626
874
  readonly niveauDuTitre: _angular_core.InputSignal<NiveauDeTitre>;
627
- readonly rejouable: _angular_core.InputSignal<boolean>;
628
- readonly libelleRejeu: _angular_core.InputSignal<string>;
629
- readonly rejeuEnCours: _angular_core.InputSignal<boolean>;
630
- readonly etiquetteDeTrace: _angular_core.InputSignal<string>;
875
+ readonly rejouable: _angular_core.InputSignalWithTransform<boolean, unknown>;
876
+ readonly rejeuEnCours: _angular_core.InputSignalWithTransform<boolean, unknown>;
877
+ /** `null` : les textes viennent du dictionnaire de l'application. */
878
+ readonly libelleRejeu: _angular_core.InputSignal<string | null>;
879
+ readonly etiquetteDeTrace: _angular_core.InputSignal<string | null>;
631
880
  readonly rejeu: _angular_core.OutputEmitterRef<void>;
632
- readonly icone: _angular_core.Signal<"hors-ligne" | "boite-vide" | "cercle" | "cercle-coche" | "cercle-croix" | "cercle-info" | "chevron-bas" | "chevron-droite" | "chevron-gauche" | "chevron-haut" | "coche" | "copie" | "corbeille" | "croix" | "lien-externe" | "menu" | "oeil" | "oeil-barre" | "plus" | "rafraichir" | "recherche" | "serveur" | "triangle-alerte" | "utilisateur">;
633
- readonly sAnnonce: _angular_core.Signal<boolean>;
881
+ protected readonly libelleRejeuLu: _angular_core.Signal<string>;
882
+ protected readonly etiquetteDeTraceLue: _angular_core.Signal<string>;
883
+ protected readonly etiquetteDuCode: _angular_core.Signal<string>;
884
+ protected readonly icone: _angular_core.Signal<"copie" | "boite-vide" | "cercle" | "cercle-coche" | "cercle-croix" | "cercle-info" | "chevron-bas" | "chevron-droite" | "chevron-gauche" | "chevron-haut" | "coche" | "corbeille" | "croix" | "hors-ligne" | "lien-externe" | "menu" | "oeil" | "oeil-barre" | "plus" | "rafraichir" | "recherche" | "serveur" | "triangle-alerte" | "utilisateur">;
885
+ protected readonly sAnnonce: _angular_core.Signal<boolean>;
634
886
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<StError, never>;
635
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<StError, "st-error", never, { "variante": { "alias": "variante"; "required": false; "isSignal": true; }; "code": { "alias": "code"; "required": true; "isSignal": true; }; "titre": { "alias": "titre"; "required": true; "isSignal": true; }; "message": { "alias": "message"; "required": true; "isSignal": true; }; "traceId": { "alias": "traceId"; "required": false; "isSignal": true; }; "niveauDuTitre": { "alias": "niveauDuTitre"; "required": false; "isSignal": true; }; "rejouable": { "alias": "rejouable"; "required": false; "isSignal": true; }; "libelleRejeu": { "alias": "libelleRejeu"; "required": false; "isSignal": true; }; "rejeuEnCours": { "alias": "rejeuEnCours"; "required": false; "isSignal": true; }; "etiquetteDeTrace": { "alias": "etiquetteDeTrace"; "required": false; "isSignal": true; }; }, { "rejeu": "rejeu"; }, never, never, true, never>;
887
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<StError, "st-error", never, { "variante": { "alias": "variante"; "required": false; "isSignal": true; }; "code": { "alias": "code"; "required": true; "isSignal": true; }; "titre": { "alias": "titre"; "required": true; "isSignal": true; }; "message": { "alias": "message"; "required": true; "isSignal": true; }; "traceId": { "alias": "traceId"; "required": false; "isSignal": true; }; "niveauDuTitre": { "alias": "niveauDuTitre"; "required": false; "isSignal": true; }; "rejouable": { "alias": "rejouable"; "required": false; "isSignal": true; }; "rejeuEnCours": { "alias": "rejeuEnCours"; "required": false; "isSignal": true; }; "libelleRejeu": { "alias": "libelleRejeu"; "required": false; "isSignal": true; }; "etiquetteDeTrace": { "alias": "etiquetteDeTrace"; "required": false; "isSignal": true; }; }, { "rejeu": "rejeu"; }, never, never, true, never>;
636
888
  }
637
889
 
638
890
  /**
@@ -650,51 +902,694 @@ declare class StError {
650
902
  declare class StOfflineBanner {
651
903
  readonly message: _angular_core.InputSignal<string>;
652
904
  readonly libelleRejeu: _angular_core.InputSignal<string | null>;
653
- readonly rejeuEnCours: _angular_core.InputSignal<boolean>;
905
+ readonly rejeuEnCours: _angular_core.InputSignalWithTransform<boolean, unknown>;
654
906
  readonly rejeu: _angular_core.OutputEmitterRef<void>;
655
907
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<StOfflineBanner, never>;
656
908
  static ɵcmp: _angular_core.ɵɵComponentDeclaration<StOfflineBanner, "st-offline-banner", never, { "message": { "alias": "message"; "required": true; "isSignal": true; }; "libelleRejeu": { "alias": "libelleRejeu"; "required": false; "isSignal": true; }; "rejeuEnCours": { "alias": "rejeuEnCours"; "required": false; "isSignal": true; }; }, { "rejeu": "rejeu"; }, never, never, true, never>;
657
909
  }
658
910
 
911
+ type ReliefDeCarte = 'plat' | 'pose' | 'flottant';
912
+ type RembourrageDeCarte = 'aucun' | 'sm' | 'md' | 'lg';
913
+ /**
914
+ * Surface qui regroupe un contenu.
915
+ *
916
+ * ⚠️ **Elle n'est jamais cliquable en entier**, et c'est un refus delibere. Une
917
+ * carte munie d'un `(click)` produit, pour qui ecoute la page, UN seul controle
918
+ * dont le nom accessible est tout le texte de la carte — titre, montant, date,
919
+ * mention legale d'un trait. Elle est aussi injoignable au clavier sans
920
+ * `tabindex`, qui la ferait alors annoncer deux fois.
921
+ *
922
+ * Le motif correct : un lien ou un bouton unique DANS la carte, etendu
923
+ * visuellement a toute sa surface par la classe `st-carte__lien-etendu`. Le
924
+ * nom accessible reste celui du lien, le clavier fonctionne sans rien ajouter,
925
+ * et la zone cliquable est la meme.
926
+ *
927
+ * ```html
928
+ * <st-card>
929
+ * <st-heading [niveau]="3">
930
+ * <a class="st-carte__lien-etendu" routerLink="/comptes/12">Compte courant</a>
931
+ * </st-heading>
932
+ * <st-money [montant]="solde" />
933
+ * </st-card>
934
+ * ```
935
+ */
936
+ declare class StCard {
937
+ readonly relief: _angular_core.InputSignal<ReliefDeCarte>;
938
+ readonly rembourrage: _angular_core.InputSignal<RembourrageDeCarte>;
939
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<StCard, never>;
940
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<StCard, "st-card", never, { "relief": { "alias": "relief"; "required": false; "isSignal": true; }; "rembourrage": { "alias": "rembourrage"; "required": false; "isSignal": true; }; }, {}, never, ["*"], true, never>;
941
+ }
942
+
943
+ /**
944
+ * Regroupement de contenu, expose comme REPERE de navigation quand il porte un
945
+ * nom.
946
+ *
947
+ * ⚠️ Le point qui decide de tout : `role="region"` n'est expose comme repere
948
+ * que s'il a un NOM ACCESSIBLE. Sans nom, la plupart des lecteurs d'ecran
949
+ * l'ignorent purement et simplement — la balise est la, le repere n'existe pas,
950
+ * et rien ne le signale. Le composant refuse donc de poser le role quand il ne
951
+ * peut pas le nommer : une section anonyme reste un simple bloc, ce qu'elle est
952
+ * reellement.
953
+ *
954
+ * Deux facons de la nommer, et la seconde vaut mieux : `titreDe` pointe le
955
+ * titre deja affiche, ce qui garde un seul texte a traduire et a maintenir.
956
+ *
957
+ * ```html
958
+ * <st-heading [niveau]="2" identifiant="titre-operations">Operations</st-heading>
959
+ * <st-section titreDe="titre-operations">…</st-section>
960
+ * ```
961
+ */
962
+ declare class StSection {
963
+ /** Nom accessible ecrit a la main. A preferer `titreDe` quand un titre existe. */
964
+ readonly etiquette: _angular_core.InputSignal<string | null>;
965
+ /** Identifiant du titre qui nomme la section. Prime sur `etiquette`. */
966
+ readonly titreDe: _angular_core.InputSignal<string | null>;
967
+ readonly espacement: _angular_core.InputSignal<"sm" | "md" | "lg" | "aucun">;
968
+ protected readonly estUnRepere: _angular_core.Signal<boolean>;
969
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<StSection, never>;
970
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<StSection, "st-section", never, { "etiquette": { "alias": "etiquette"; "required": false; "isSignal": true; }; "titreDe": { "alias": "titreDe"; "required": false; "isSignal": true; }; "espacement": { "alias": "espacement"; "required": false; "isSignal": true; }; }, {}, never, ["*"], true, never>;
971
+ }
972
+
973
+ type OrientationDeSeparateur = 'horizontale' | 'verticale';
974
+ /**
975
+ * Trait de separation.
976
+ *
977
+ * ⚠️ **Decoratif par defaut, et c'est le bon defaut.** Un `<hr>` porte le role
978
+ * `separator` de facon implicite, que les lecteurs d'ecran annoncent. Sur une
979
+ * page qui en compte huit — ce qui est courant dans une liste de reglages — la
980
+ * lecture est ponctuee de huit « separateur » qui n'apprennent rien.
981
+ *
982
+ * Le role ne se pose que lorsque le trait porte vraiment du sens : il separe
983
+ * alors deux GROUPES que rien d'autre ne distingue, comme les sections d'un
984
+ * menu. Regle de tri : si le retirer ne retire aucune information, il est
985
+ * decoratif.
986
+ */
987
+ declare class StDivider {
988
+ readonly orientation: _angular_core.InputSignal<OrientationDeSeparateur>;
989
+ /** Le trait separe deux groupes distincts, et doit donc etre annonce. */
990
+ readonly porteurDeSens: _angular_core.InputSignalWithTransform<boolean, unknown>;
991
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<StDivider, never>;
992
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<StDivider, "st-divider", never, { "orientation": { "alias": "orientation"; "required": false; "isSignal": true; }; "porteurDeSens": { "alias": "porteurDeSens"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
993
+ }
994
+
995
+ /**
996
+ * Titre de page : le `h1`, et les actions qui lui sont attachees.
997
+ *
998
+ * ⚠️ Il rend une **vraie balise `h1`**, la ou `st-heading` porte
999
+ * `role="heading"` sur son hote. La raison est precise : `StNavigation` de
1000
+ * `@starterlib/core` vise le titre de niveau 1 pour y poser le focus apres une
1001
+ * navigation, et une vraie balise est ce que trouvent aussi les extensions, le
1002
+ * mode lecture et les outils d'audit. Un `h1` par page, jamais deux.
1003
+ *
1004
+ * ⚠️ **Il ne gere PAS le focus**, et ce n'est pas un oubli. Le noyau le fait
1005
+ * deja a chaque changement de route. Deux mecanismes qui deplacent le focus a
1006
+ * la meme milliseconde ne se completent pas : ils se battent, et le gagnant
1007
+ * depend de l'ordre de rendu — donc du hasard.
1008
+ *
1009
+ * ```html
1010
+ * <st-page-title>
1011
+ * Mes operations
1012
+ * <button stButton variante="primaire" actions>Exporter</button>
1013
+ * </st-page-title>
1014
+ * ```
1015
+ */
1016
+ declare class StPageTitle {
1017
+ /** Texte secondaire sous le titre. Jamais porteur d'information critique. */
1018
+ readonly precision: _angular_core.InputSignal<string | null>;
1019
+ /** Cible d'un `aria-labelledby` : une region se nomme par son titre. */
1020
+ readonly identifiant: _angular_core.InputSignal<string | null>;
1021
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<StPageTitle, never>;
1022
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<StPageTitle, "st-page-title", never, { "precision": { "alias": "precision"; "required": false; "isSignal": true; }; "identifiant": { "alias": "identifiant"; "required": false; "isSignal": true; }; }, {}, never, ["*", "[actions]"], true, never>;
1023
+ }
1024
+
1025
+ /** Un maillon du fil. Sans `lien`, il n'est pas cliquable. */
1026
+ interface MaillonDeFil {
1027
+ readonly libelle: string;
1028
+ /**
1029
+ * Chemin INTERNE de l'application, suivi par le routeur.
1030
+ *
1031
+ * ⚠️ Jamais une adresse externe : un fil d'Ariane decrit ou l'on se trouve
1032
+ * dans CETTE application. Passe par le routeur, un domaine tiers n'est pas
1033
+ * une destination possible.
1034
+ */
1035
+ readonly lien?: string;
1036
+ }
1037
+ /**
1038
+ * Fil d'Ariane.
1039
+ *
1040
+ * ⚠️ **Le dernier maillon n'est pas un lien.** C'est la page courante : un lien
1041
+ * vers l'endroit ou l'on se trouve deja n'apporte rien, et il ajoute un arret
1042
+ * de tabulation sur chaque page du site. Il porte `aria-current="page"`, qui
1043
+ * est ce que le lecteur d'ecran annonce a sa place.
1044
+ *
1045
+ * ⚠️ **Les separateurs sont poses en `aria-hidden`.** Un chevron ou une barre
1046
+ * oblique laisses dans l'arbre d'accessibilite se lit « barre oblique » entre
1047
+ * chaque maillon : « Accueil barre oblique Comptes barre oblique Operations ».
1048
+ * Les poser en contenu engendre par CSS ne suffit pas — Chrome et Firefox
1049
+ * exposent `content` a l'arbre d'accessibilite.
1050
+ *
1051
+ * ⚠️ La liste est ORDONNEE (`ol`) : l'ordre des maillons est l'information.
1052
+ *
1053
+ * ⚠️ **Les liens passent par le routeur.** La premiere version posait des
1054
+ * `href` bruts : dans une SPA, un clic quittait l'application, repassait par la
1055
+ * coquille du BFF et perdait tout l'etat en memoire — sur le composant de
1056
+ * navigation le plus clique apres le menu.
1057
+ */
1058
+ declare class StBreadcrumb {
1059
+ private readonly libelles;
1060
+ readonly maillons: _angular_core.InputSignal<readonly MaillonDeFil[]>;
1061
+ /** `null` : le texte vient du dictionnaire de l'application. */
1062
+ readonly etiquette: _angular_core.InputSignal<string | null>;
1063
+ /** Caractere de separation. Muet pour les technologies d'assistance. */
1064
+ readonly separateur: _angular_core.InputSignal<string>;
1065
+ protected readonly etiquetteLue: _angular_core.Signal<string>;
1066
+ /** Le dernier maillon est la page courante, jamais un lien. */
1067
+ protected readonly derniereIndice: _angular_core.Signal<number>;
1068
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<StBreadcrumb, never>;
1069
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<StBreadcrumb, "st-breadcrumb", never, { "maillons": { "alias": "maillons"; "required": true; "isSignal": true; }; "etiquette": { "alias": "etiquette"; "required": false; "isSignal": true; }; "separateur": { "alias": "separateur"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
1070
+ }
1071
+
1072
+ /** Identifiant par defaut du contenu principal, pose par `st-app-shell`. */
1073
+ declare const IDENTIFIANT_DU_CONTENU_PRINCIPAL = "contenu-principal";
1074
+ /**
1075
+ * Lien d'evitement : aller au contenu sans traverser la navigation.
1076
+ *
1077
+ * WCAG 2.4.1. Sans lui, chaque page impose a qui navigue au clavier de
1078
+ * traverser l'en-tete et tout le menu avant d'atteindre ce qu'il est venu lire —
1079
+ * trente arrets de tabulation, a chaque changement de page.
1080
+ *
1081
+ * ⚠️ **Le focus est pose par script, et la navigation par ancre est annulee.**
1082
+ * Deux raisons, et chacune suffit :
1083
+ *
1084
+ * 1. Un `href="#contenu"` se resout contre `<base href>`. Sous
1085
+ * `/ui/<interface>/`, il vise `/ui/<interface>/#contenu` : un rechargement
1086
+ * complet de la coquille, au lieu d'un saut dans la page.
1087
+ * 2. Suivre une ancre deplace la vue sans toujours deplacer le FOCUS. La
1088
+ * tabulation suivante repart alors du lien d'evitement, et le saut n'a servi
1089
+ * a rien.
1090
+ *
1091
+ * Le `href` reste pose : c'est lui qui fait du lien un lien, pour le lecteur
1092
+ * d'ecran comme pour le clic du milieu.
1093
+ *
1094
+ * ⚠️ Il doit etre le PREMIER element focalisable du document. Le composant ne
1095
+ * peut pas l'imposer ; `st-app-shell` le fait.
1096
+ */
1097
+ declare class StSkipLink {
1098
+ private readonly document;
1099
+ private readonly libelles;
1100
+ /** Identifiant de l'element a atteindre. */
1101
+ readonly cible: _angular_core.InputSignal<string>;
1102
+ /** `null` : le texte vient du dictionnaire de l'application. */
1103
+ readonly libelle: _angular_core.InputSignal<string | null>;
1104
+ protected readonly libelleLu: _angular_core.Signal<string>;
1105
+ protected readonly ancre: _angular_core.Signal<string>;
1106
+ protected aller(evenement: MouseEvent): void;
1107
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<StSkipLink, never>;
1108
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<StSkipLink, "st-skip-link", never, { "cible": { "alias": "cible"; "required": false; "isSignal": true; }; "libelle": { "alias": "libelle"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
1109
+ }
1110
+
1111
+ /**
1112
+ * Coquille d'une application : lien d'evitement, en-tete, navigation, contenu
1113
+ * principal, pied de page.
1114
+ *
1115
+ * ```html
1116
+ * <st-app-shell>
1117
+ * <ng-container entete>…</ng-container>
1118
+ * <ng-container navigation>…</ng-container>
1119
+ * <router-outlet />
1120
+ * <ng-container pied>…</ng-container>
1121
+ * </st-app-shell>
1122
+ * ```
1123
+ *
1124
+ * ⚠️ Son role est de garantir les REPERES, et un seul de chaque. Une page qui
1125
+ * compte deux `main` — frequent quand une micro-SPA pose le sien dans celui de
1126
+ * la coquille — prive le lecteur d'ecran du raccourci « aller au contenu
1127
+ * principal » : il ne sait plus lequel viser. Les remotes ne posent donc
1128
+ * jamais de `main`, `header` ni `footer` de premier niveau.
1129
+ *
1130
+ * ⚠️ Le lien d'evitement est rendu EN PREMIER, avant l'en-tete : c'est la seule
1131
+ * place ou il sert. Place apres, il faut deja avoir traverse ce qu'il permet
1132
+ * d'eviter.
1133
+ *
1134
+ * Le contenu principal porte l'identifiant vise par le lien d'evitement.
1135
+ * Le focus de navigation, lui, vise le titre de niveau 1 : voir `StNavigation`
1136
+ * de `@starterlib/core`. Les deux se completent — l'un au chargement d'une
1137
+ * page, l'autre a chaque changement de route.
1138
+ *
1139
+ * ⚠️ La coquille ne pose PAS de `<nav>` autour de la navigation : c'est
1140
+ * `st-sidenav` qui porte ce repere. Pose ici aussi, il s'imbriquerait — le
1141
+ * lecteur d'ecran annoncerait « navigation, navigation » — et resterait vide
1142
+ * sur petit ecran, quand le contenu part dans le tiroir.
1143
+ */
1144
+ declare class StAppShell {
1145
+ protected readonly identifiantDuContenu = "contenu-principal";
1146
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<StAppShell, never>;
1147
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<StAppShell, "st-app-shell", never, {}, {}, never, ["[entete]", "[navigation]", "*", "[pied]"], true, never>;
1148
+ }
1149
+
1150
+ /**
1151
+ * Contenu de l'en-tete : bouton de navigation, marque, puis actions.
1152
+ *
1153
+ * ```html
1154
+ * <st-app-shell>
1155
+ * <st-header entete>
1156
+ * <button bascule stButton [stSidenavToggle]="navigation">Menu</button>
1157
+ * <a marque routerLink="/"><st-logo nom="Banque Exemple" clair="/logo.svg" /></a>
1158
+ * <st-lang-switch [courante]="langue.courante()" (choisie)="langue.changer($event)" />
1159
+ * <button stButton [stMenuTrigger]="compte">Mon compte</button>
1160
+ * </st-header>
1161
+ * </st-app-shell>
1162
+ * ```
1163
+ *
1164
+ * ⚠️ **Aucun repere pose ici.** Le `header` de `st-app-shell` est deja le
1165
+ * repere « banniere » ; en ajouter un second dans le premier ferait annoncer
1166
+ * deux bannieres.
1167
+ *
1168
+ * ⚠️ **Composition, pas assemblage.** Il ne cree ni menu, ni bascule, ni logo :
1169
+ * il les place. C'est ce qui le garde dans le tronc — importer `st-menu` l'aurait
1170
+ * fait sortir vers un point d'entree secondaire — et qui laisse chaque SPA
1171
+ * choisir ses actions.
1172
+ *
1173
+ * L'ordre du DOM est l'ordre de lecture et de tabulation : bouton de
1174
+ * navigation, marque, actions. Il n'est jamais inverse par le style.
1175
+ */
1176
+ declare class StHeader {
1177
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<StHeader, never>;
1178
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<StHeader, "st-header", never, {}, {}, never, ["[bascule]", "[marque]", "*"], true, never>;
1179
+ }
1180
+
1181
+ type TonDeBanniere = TonSemantique;
1182
+ /**
1183
+ * Message de page, persistant jusqu'a ce qu'on le ferme.
1184
+ *
1185
+ * Distinct de `st-offline-banner`, qui dit un fait qu'on ne peut pas fermer, et
1186
+ * de `st-error`, qui remplace un contenu au lieu de l'accompagner.
1187
+ *
1188
+ * ⚠️ **Elle est une region vivante, et ce n'est pas redondant au chargement.**
1189
+ * Un lecteur d'ecran annonce les MUTATIONS d'une region qu'il observe deja :
1190
+ * une banniere presente des l'affichage est lue avec la page, une fois, puis
1191
+ * son apparition ulterieure est annoncee. Le meme mecanisme sert les deux cas.
1192
+ *
1193
+ * ⚠️ Le ton `danger` passe en `alert` (assertif) : une operation qui vient
1194
+ * d'echouer doit interrompre. Les autres restent en `status`, sinon une
1195
+ * confirmation couperait la lecture en cours et ferait perdre sa place.
1196
+ *
1197
+ * ⚠️ Comme `st-spinner` et `st-error`, elle se tait dans une region vivante
1198
+ * existante : sans cela, le lecteur annonce deux fois le meme message.
1199
+ */
1200
+ declare class StBanner {
1201
+ private readonly element;
1202
+ private readonly regionParente;
1203
+ private readonly libelles;
1204
+ readonly ton: _angular_core.InputSignal<TonSemantique>;
1205
+ readonly message: _angular_core.InputSignal<string>;
1206
+ /** Titre court au-dessus du message. Le message seul suffit le plus souvent. */
1207
+ readonly titre: _angular_core.InputSignal<string | null>;
1208
+ readonly fermable: _angular_core.InputSignalWithTransform<boolean, unknown>;
1209
+ /** `null` : le texte vient du dictionnaire de l'application. */
1210
+ readonly libelleFermeture: _angular_core.InputSignal<string | null>;
1211
+ readonly ferme: _angular_core.OutputEmitterRef<void>;
1212
+ protected readonly icone: _angular_core.Signal<"copie" | "boite-vide" | "cercle" | "cercle-coche" | "cercle-croix" | "cercle-info" | "chevron-bas" | "chevron-droite" | "chevron-gauche" | "chevron-haut" | "coche" | "corbeille" | "croix" | "hors-ligne" | "lien-externe" | "menu" | "oeil" | "oeil-barre" | "plus" | "rafraichir" | "recherche" | "serveur" | "triangle-alerte" | "utilisateur">;
1213
+ protected readonly libelleFermetureLu: _angular_core.Signal<string>;
1214
+ protected readonly roleLu: _angular_core.Signal<"status" | "alert" | null>;
1215
+ /**
1216
+ * ⚠️ Le focus est DEPLACE avant l'emission. Sans cela, le bouton disparait
1217
+ * sous le doigt de l'utilisateur clavier, le focus retombe sur le corps du
1218
+ * document, et la navigation repart du haut de la page — le meme defaut que
1219
+ * sur une liste d'etiquettes, et l'un des plus frequents.
1220
+ */
1221
+ protected fermer(): void;
1222
+ /**
1223
+ * Cible, dans l'ordre : le premier element focalisable qui SUIT la banniere
1224
+ * dans le document, sinon le dernier qui la precede, sinon le conteneur s'il
1225
+ * est focalisable par script.
1226
+ *
1227
+ * ⚠️ L'ordre du DOCUMENT, et non les descendants du voisin. La premiere
1228
+ * version cherchait dans `nextElementSibling` : un bouton pose directement
1229
+ * apres la banniere n'etait pas trouve, puisqu'il n'est pas son propre
1230
+ * descendant, et le focus retombait sur le corps du document.
1231
+ */
1232
+ private deplacerLeFocus;
1233
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<StBanner, never>;
1234
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<StBanner, "st-banner", never, { "ton": { "alias": "ton"; "required": false; "isSignal": true; }; "message": { "alias": "message"; "required": true; "isSignal": true; }; "titre": { "alias": "titre"; "required": false; "isSignal": true; }; "fermable": { "alias": "fermable"; "required": false; "isSignal": true; }; "libelleFermeture": { "alias": "libelleFermeture"; "required": false; "isSignal": true; }; }, { "ferme": "ferme"; }, never, ["*"], true, never>;
1235
+ }
1236
+
1237
+ type TonDeMessage = TonSemantique;
1238
+ /**
1239
+ * Message court attache a une zone precise : une aide sous un champ, une
1240
+ * consequence sous un choix, une contrainte au-dessus d'un bouton.
1241
+ *
1242
+ * Distinct de `st-banner`, qui parle de la PAGE et se ferme.
1243
+ *
1244
+ * ⚠️ **Aucun role, aucune region vivante**, et c'est la difference qui compte.
1245
+ * Un message en ligne est lu quand on atteint l'endroit auquel il se rattache ;
1246
+ * en faire une region vivante le ferait annoncer hors contexte, et une
1247
+ * vingtaine de champs produiraient vingt annonces a l'ouverture de l'ecran.
1248
+ *
1249
+ * ⚠️ Pour une erreur de SAISIE, ce composant ne suffit pas : le champ doit
1250
+ * porter `aria-describedby` vers l'identifiant du message, sans quoi le lien
1251
+ * entre les deux n'existe que visuellement. C'est `st-form-field` de la
1252
+ * vague 3 qui posera ce lien.
1253
+ */
1254
+ declare class StInlineMessage {
1255
+ readonly ton: _angular_core.InputSignal<TonSemantique>;
1256
+ /** Cible d'un `aria-describedby` pose par le champ decrit. */
1257
+ readonly identifiant: _angular_core.InputSignal<string | null>;
1258
+ protected readonly icone: _angular_core.Signal<"copie" | "boite-vide" | "cercle" | "cercle-coche" | "cercle-croix" | "cercle-info" | "chevron-bas" | "chevron-droite" | "chevron-gauche" | "chevron-haut" | "coche" | "corbeille" | "croix" | "hors-ligne" | "lien-externe" | "menu" | "oeil" | "oeil-barre" | "plus" | "rafraichir" | "recherche" | "serveur" | "triangle-alerte" | "utilisateur">;
1259
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<StInlineMessage, never>;
1260
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<StInlineMessage, "st-inline-message", never, { "ton": { "alias": "ton"; "required": false; "isSignal": true; }; "identifiant": { "alias": "identifiant"; "required": false; "isSignal": true; }; }, {}, never, ["*"], true, never>;
1261
+ }
1262
+
1263
+ /**
1264
+ * Choix du theme : systeme, clair, sombre.
1265
+ *
1266
+ * ⚠️ **Trois etats, donc PAS un interrupteur.** `role="switch"` et
1267
+ * `aria-pressed` sont binaires : poses sur un choix a trois valeurs, ils
1268
+ * annoncent « active » ou « desactive » sans jamais dire lequel des trois est
1269
+ * retenu. Un groupe de boutons radio dit exactement « Sombre, bouton radio,
1270
+ * coche, 3 sur 3 ».
1271
+ *
1272
+ * ⚠️ **Composant de PRESENTATION.** Il n'injecte pas `StTheme` : `ui` ne depend
1273
+ * pas de `@starterlib/core` (ADR 0003). La coquille le relie au noyau :
1274
+ *
1275
+ * ```html
1276
+ * <st-theme-toggle [choix]="theme.choix()" (choisi)="theme.choisir($event)" />
1277
+ * ```
1278
+ */
1279
+ declare class StThemeToggle {
1280
+ private readonly libelles;
1281
+ readonly choix: _angular_core.InputSignal<ChoixDeTheme>;
1282
+ /** Legende visible. Masquee par defaut, mais toujours lue : elle nomme le groupe. */
1283
+ readonly legendeVisible: _angular_core.InputSignalWithTransform<boolean, unknown>;
1284
+ readonly choisi: _angular_core.OutputEmitterRef<ChoixDeTheme>;
1285
+ /** Unique par instance : deux bascules sur la meme page partageraient leur groupe radio. */
1286
+ protected readonly nom: string;
1287
+ protected readonly legende: _angular_core.Signal<string>;
1288
+ protected readonly options: _angular_core.Signal<{
1289
+ valeur: ChoixDeTheme;
1290
+ libelle: string;
1291
+ }[]>;
1292
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<StThemeToggle, never>;
1293
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<StThemeToggle, "st-theme-toggle", never, { "choix": { "alias": "choix"; "required": true; "isSignal": true; }; "legendeVisible": { "alias": "legendeVisible"; "required": false; "isSignal": true; }; }, { "choisi": "choisi"; }, never, never, true, never>;
1294
+ }
1295
+
1296
+ /**
1297
+ * Choix de la langue de l'interface.
1298
+ *
1299
+ * ⚠️ **Chaque option porte son propre `lang`.** Sans lui, un lecteur d'ecran
1300
+ * regle en francais lit « English » avec une voix francaise, et le mot devient
1301
+ * incomprehensible pour la personne anglophone qui cherchait justement a
1302
+ * l'entendre.
1303
+ *
1304
+ * ⚠️ **Composant de PRESENTATION.** Il n'injecte pas `StLangue` : `ui` ne depend
1305
+ * pas de `@starterlib/core` (ADR 0003). La coquille le relie au noyau :
1306
+ *
1307
+ * ```html
1308
+ * <st-lang-switch [courante]="langue.courante()" (choisie)="langue.changer($event)" />
1309
+ * ```
1310
+ */
1311
+ declare class StLangSwitch {
1312
+ private readonly libelles;
1313
+ readonly courante: _angular_core.InputSignal<Langue>;
1314
+ readonly langues: _angular_core.InputSignal<readonly Langue[]>;
1315
+ readonly legendeVisible: _angular_core.InputSignalWithTransform<boolean, unknown>;
1316
+ readonly choisie: _angular_core.OutputEmitterRef<Langue>;
1317
+ protected readonly nom: string;
1318
+ protected readonly legende: _angular_core.Signal<string>;
1319
+ protected readonly options: _angular_core.Signal<{
1320
+ code: Langue;
1321
+ endonyme: string;
1322
+ }[]>;
1323
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<StLangSwitch, never>;
1324
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<StLangSwitch, "st-lang-switch", never, { "courante": { "alias": "courante"; "required": true; "isSignal": true; }; "langues": { "alias": "langues"; "required": false; "isSignal": true; }; "legendeVisible": { "alias": "legendeVisible"; "required": false; "isSignal": true; }; }, { "choisie": "choisie"; }, never, never, true, never>;
1325
+ }
1326
+
1327
+ /**
1328
+ * Bouton qui copie une valeur : reference de virement, adresse de depot, lien
1329
+ * de partage.
1330
+ *
1331
+ * ⚠️ **Un element, et non un attribut pose sur un `<button>`.** La confirmation
1332
+ * passe par une region vivante voisine du bouton ; posee DANS le bouton, elle
1333
+ * entrerait dans son nom accessible, qui deviendrait « Copier Copie ».
1334
+ *
1335
+ * ⚠️ **Le libelle du bouton ne change pas** apres la copie, pour la raison que
1336
+ * donne `st-code` : le lecteur d'ecran annoncerait un autre controle que celui
1337
+ * qu'il a sous le doigt.
1338
+ *
1339
+ * ⚠️ **Jamais de secret.** Ce qui entre dans le presse-papiers est conserve par
1340
+ * les gestionnaires d'historique et synchronise entre appareils : ni mot de
1341
+ * passe, ni jeton, ni code a usage unique.
1342
+ *
1343
+ * Sans presse-papiers — hors contexte securise — le bouton n'est pas rendu : un
1344
+ * controle qui ne peut rien faire ne doit pas s'offrir.
1345
+ */
1346
+ declare class StCopyButton {
1347
+ private readonly document;
1348
+ private readonly libelles;
1349
+ readonly valeur: _angular_core.InputSignal<string>;
1350
+ /**
1351
+ * `null` : le texte vient du dictionnaire de l'application.
1352
+ *
1353
+ * ⚠️ En icone seule, c'est le nom accessible du bouton : il doit dire CE qui
1354
+ * est copie quand la page en offre plusieurs — « Copier l'IBAN » et non
1355
+ * « Copier » repete cinq fois.
1356
+ */
1357
+ readonly libelle: _angular_core.InputSignal<string | null>;
1358
+ readonly iconeSeule: _angular_core.InputSignalWithTransform<boolean, unknown>;
1359
+ readonly messageDeConfirmation: _angular_core.InputSignal<string | null>;
1360
+ readonly copie: _angular_core.OutputEmitterRef<string>;
1361
+ protected readonly annonce: AnnonceLocale;
1362
+ protected readonly disponible: boolean;
1363
+ protected readonly libelleLu: _angular_core.Signal<string>;
1364
+ protected copier(): Promise<void>;
1365
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<StCopyButton, never>;
1366
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<StCopyButton, "st-copy-button", never, { "valeur": { "alias": "valeur"; "required": true; "isSignal": true; }; "libelle": { "alias": "libelle"; "required": false; "isSignal": true; }; "iconeSeule": { "alias": "iconeSeule"; "required": false; "isSignal": true; }; "messageDeConfirmation": { "alias": "messageDeConfirmation"; "required": false; "isSignal": true; }; }, { "copie": "copie"; }, never, never, true, never>;
1367
+ }
1368
+
1369
+ /**
1370
+ * Compte a rebours avant un nouvel essai, pour une reponse `429` et son en-tete
1371
+ * `Retry-After`.
1372
+ *
1373
+ * ```html
1374
+ * @if (erreur.reessayerDans !== null) {
1375
+ * <st-timer [secondes]="erreur.reessayerDans" (termine)="reessayable.set(true)" />
1376
+ * }
1377
+ * ```
1378
+ *
1379
+ * ⚠️ **Il n'annonce PAS chaque seconde.** Une region vivante qui change toutes les
1380
+ * secondes recouvre tout ce que le lecteur d'ecran essaie de dire, et empeche de
1381
+ * lire le formulaire que la personne est justement en train de garder pret. Le
1382
+ * decompte porte `role="timer"`, dont la valeur implicite est
1383
+ * `aria-live="off"` : il se LIT quand on l'atteint. Seule la fin s'annonce.
1384
+ *
1385
+ * ⚠️ **Le temps restant se calcule contre l'horloge, pas en comptant les
1386
+ * battements.** Un onglet en arriere-plan voit ses minuteries ralenties a une par
1387
+ * minute : un compteur decremente a chaque battement afficherait encore
1388
+ * « 45 s » a son retour, bien apres que le serveur a leve la limite.
1389
+ */
1390
+ declare class StTimer {
1391
+ private readonly libelles;
1392
+ private readonly locale;
1393
+ /** Duree d'attente en secondes, telle que `Retry-After` la donne. */
1394
+ readonly secondes: _angular_core.InputSignal<number>;
1395
+ readonly termine: _angular_core.OutputEmitterRef<void>;
1396
+ protected readonly annonce: AnnonceLocale;
1397
+ private readonly restant;
1398
+ private echeance;
1399
+ private minuterie;
1400
+ protected readonly texte: _angular_core.Signal<string>;
1401
+ constructor();
1402
+ private demarrer;
1403
+ private battre;
1404
+ private arreter;
1405
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<StTimer, never>;
1406
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<StTimer, "st-timer", never, { "secondes": { "alias": "secondes"; "required": true; "isSignal": true; }; }, { "termine": "termine"; }, never, never, true, never>;
1407
+ }
1408
+
1409
+ /**
1410
+ * Logo de l'organisation, en variante claire, sombre et monochrome.
1411
+ *
1412
+ * ⚠️ **Le texte alternatif est le NOM de l'organisation, jamais « logo ».** Un
1413
+ * lecteur d'ecran annonce deja « image » : « Logo Banque Exemple » se lit
1414
+ * « image, logo Banque Exemple ». Pose dans un lien vers l'accueil, ce nom
1415
+ * devient celui du lien — il doit donc dire ou il mene.
1416
+ *
1417
+ * ⚠️ **Decoratif quand le nom est ecrit a cote.** Le repeter ferait lire
1418
+ * « Banque Exemple Banque Exemple ».
1419
+ *
1420
+ * La variante suit le theme EFFECTIF pose par `StTheme` sur `<html data-theme>`,
1421
+ * et non `prefers-color-scheme` : une personne qui a choisi le clair sur un
1422
+ * systeme sombre doit voir le logo clair. Sous contraste force, la variante
1423
+ * monochrome prend le relais — un logo en couleurs peut y disparaitre sur le
1424
+ * fond impose.
1425
+ *
1426
+ * Les images viennent de la meme origine : la politique de securite du contenu
1427
+ * n'autorise pas d'autre source d'image sans extension explicite cote BFF.
1428
+ */
1429
+ declare class StLogo {
1430
+ /** Nom de l'organisation : c'est le texte alternatif. */
1431
+ readonly nom: _angular_core.InputSignal<string>;
1432
+ readonly clair: _angular_core.InputSignal<string>;
1433
+ /** `null` : la variante claire sert aussi sur fond sombre. */
1434
+ readonly sombre: _angular_core.InputSignal<string | null>;
1435
+ /** `null` : aucune variante dediee au contraste force. */
1436
+ readonly monochrome: _angular_core.InputSignal<string | null>;
1437
+ readonly decoratif: _angular_core.InputSignalWithTransform<boolean, unknown>;
1438
+ readonly hauteur: _angular_core.InputSignal<string>;
1439
+ protected readonly texteAlternatif: _angular_core.Signal<string>;
1440
+ protected readonly sourceSombre: _angular_core.Signal<string>;
1441
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<StLogo, never>;
1442
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<StLogo, "st-logo", never, { "nom": { "alias": "nom"; "required": true; "isSignal": true; }; "clair": { "alias": "clair"; "required": true; "isSignal": true; }; "sombre": { "alias": "sombre"; "required": false; "isSignal": true; }; "monochrome": { "alias": "monochrome"; "required": false; "isSignal": true; }; "decoratif": { "alias": "decoratif"; "required": false; "isSignal": true; }; "hauteur": { "alias": "hauteur"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
1443
+ }
1444
+
659
1445
  /**
660
1446
  * Impose les cinq etats a un bloc qui consomme l'API, et centralise leur
661
1447
  * annonce.
662
1448
  *
1449
+ * Deux usages. Le plus courant passe la ressource, et l'etat s'en deduit :
1450
+ *
1451
+ * ```html
1452
+ * <st-state [ressource]="operations">
1453
+ * <ng-template [stSucces]="operations" let-page>…</ng-template>
1454
+ * <ng-template stErreur let-erreur><st-error … /></ng-template>
1455
+ * <ng-template stVide><st-empty … /></ng-template>
1456
+ * </st-state>
1457
+ * ```
1458
+ *
1459
+ * L'autre pose `[etat]` a la main, pour un bloc qui ne vient pas d'une
1460
+ * ressource — une soumission de formulaire, par exemple.
1461
+ *
1462
+ * ⚠️ Un RECHARGEMENT garde le contenu affiche. Revenir a la silhouette a chaque
1463
+ * changement de filtre fait clignoter la page entiere et perd la position de
1464
+ * lecture ; seul le premier chargement n'a rien a montrer.
1465
+ *
663
1466
  * ⚠️ L'hote ne porte PAS `role="status"`, contrairement a ce qu'on attendrait :
664
1467
  * un remplacement de contenu A L'INTERIEUR d'une region vivante fait relire
665
1468
  * tout le sous-arbre par le lecteur d'ecran a chaque bascule d'etat. Seule une
666
- * petite zone masquee porte l'annonce, qui tient en quelques mots. L'hote se
667
- * contente d'`aria-busy`.
668
- *
669
- * Il fournit `REGION_VIVANTE_PARENTE` : les composants qu'il rend (indicateur
670
- * de chargement, erreur) detectent sa presence et se taisent, au lieu
671
- * d'annoncer une deuxieme fois le meme fait.
672
- */
673
- declare class StState {
674
- readonly etat: _angular_core.InputSignal<EtatDeBloc>;
675
- /** Le chemin nominal. Obligatoire : un bloc sans succes n'a pas de raison d'etre. */
676
- readonly succes: _angular_core.InputSignal<TemplateRef<unknown>>;
677
- readonly chargement: _angular_core.InputSignal<TemplateRef<unknown> | null>;
678
- readonly erreur: _angular_core.InputSignal<TemplateRef<unknown> | null>;
679
- readonly vide: _angular_core.InputSignal<TemplateRef<unknown> | null>;
680
- readonly horsLigne: _angular_core.InputSignal<TemplateRef<unknown> | null>;
1469
+ * petite zone masquee porte l'annonce, qui tient en quelques mots.
1470
+ */
1471
+ declare class StState<T> {
1472
+ private readonly libelles;
1473
+ /** La ressource dont l'etat se deduit. */
1474
+ readonly ressource: _angular_core.InputSignal<Resource<T> | null>;
1475
+ /** Etat pose a la main. Il prime sur la ressource quand les deux existent. */
1476
+ readonly etat: _angular_core.InputSignal<EtatDeBloc | null>;
1477
+ /** Ce qui compte comme « vide » : par defaut, une collection sans element. */
1478
+ readonly estVide: _angular_core.InputSignal<(valeur: T) => boolean>;
681
1479
  /** Silhouette par defaut du chargement. `null` : un indicateur tournant. */
682
1480
  readonly squelette: _angular_core.InputSignal<VarianteDeSquelette | null>;
683
1481
  readonly lignesDeSquelette: _angular_core.InputSignal<number>;
684
- readonly annonces: _angular_core.InputSignal<Readonly<Record<EtatDeBloc, string>>>;
685
- readonly annonce: _angular_core.Signal<string>;
1482
+ /** `null` : les annonces viennent du dictionnaire de l'application. */
1483
+ readonly annonces: _angular_core.InputSignal<Readonly<Record<EtatDeBloc, string>> | null>;
1484
+ private readonly gabaritSucces;
1485
+ private readonly gabaritErreur;
1486
+ private readonly gabaritVide;
1487
+ private readonly gabaritHorsLigne;
1488
+ private readonly gabaritChargement;
1489
+ private readonly instantane;
1490
+ /**
1491
+ * La derniere valeur connue, gardee pendant qu'une autre se charge.
1492
+ *
1493
+ * ⚠️ Necessaire, et pas seulement confortable : un changement de PARAMETRE
1494
+ * n'est pas un `reload`. Angular traite le premier comme une nouvelle
1495
+ * requete — statut « loading », valeur videe. Sans cette memoire, changer un
1496
+ * filtre ou tourner une page ferait donc disparaitre le tableau, clignoter la
1497
+ * page, et perdre la position de lecture. Une erreur, elle, ne garde rien :
1498
+ * afficher des donnees perimees sous un message d'erreur serait mentir.
1499
+ */
1500
+ private readonly valeurRetenue;
1501
+ /** Etat deduit de la ressource, valeur retenue comprise. */
1502
+ private readonly etatDeLaRessource;
1503
+ protected readonly etatEffectif: _angular_core.Signal<EtatDeBloc>;
1504
+ /**
1505
+ * Une valeur est affichee, et une autre arrive — par rappel explicite ou par
1506
+ * changement de parametre.
1507
+ */
1508
+ protected readonly enRechargement: _angular_core.Signal<boolean>;
1509
+ protected readonly enAttente: _angular_core.Signal<boolean>;
1510
+ private readonly annoncesLues;
1511
+ protected readonly annonce: _angular_core.Signal<string>;
1512
+ /** Contexte passe au gabarit : la valeur en succes, l'erreur en erreur. */
1513
+ protected readonly contexte: _angular_core.Signal<{
1514
+ $implicit: unknown;
1515
+ }>;
686
1516
  /**
687
1517
  * Les etats degrades n'ont pas de rendu par defaut : afficher un texte
688
1518
  * generique a la place d'un vrai ecran vide ou d'une vraie erreur donnerait
689
1519
  * l'illusion que les cinq etats sont traites. Il vaut mieux que le manque se
690
1520
  * voie, en developpement.
691
1521
  */
692
- readonly gabaritDeLEtat: _angular_core.Signal<TemplateRef<unknown> | null>;
693
- readonly montreLaSilhouetteParDefaut: _angular_core.Signal<boolean>;
1522
+ protected readonly gabaritDeLEtat: _angular_core.Signal<TemplateRef<unknown> | null>;
1523
+ private readonly chargementVisible;
1524
+ /** La silhouette par defaut, une fois le delai anti-clignotement passe. */
1525
+ protected readonly montreLaSilhouetteParDefaut: _angular_core.Signal<boolean>;
1526
+ constructor();
694
1527
  private signalerSiAbsent;
695
- static ɵfac: _angular_core.ɵɵFactoryDeclaration<StState, never>;
696
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<StState, "st-state", never, { "etat": { "alias": "etat"; "required": true; "isSignal": true; }; "succes": { "alias": "succes"; "required": true; "isSignal": true; }; "chargement": { "alias": "chargement"; "required": false; "isSignal": true; }; "erreur": { "alias": "erreur"; "required": false; "isSignal": true; }; "vide": { "alias": "vide"; "required": false; "isSignal": true; }; "horsLigne": { "alias": "horsLigne"; "required": false; "isSignal": true; }; "squelette": { "alias": "squelette"; "required": false; "isSignal": true; }; "lignesDeSquelette": { "alias": "lignesDeSquelette"; "required": false; "isSignal": true; }; "annonces": { "alias": "annonces"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
1528
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<StState<any>, never>;
1529
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<StState<any>, "st-state", never, { "ressource": { "alias": "ressource"; "required": false; "isSignal": true; }; "etat": { "alias": "etat"; "required": false; "isSignal": true; }; "estVide": { "alias": "estVide"; "required": false; "isSignal": true; }; "squelette": { "alias": "squelette"; "required": false; "isSignal": true; }; "lignesDeSquelette": { "alias": "lignesDeSquelette"; "required": false; "isSignal": true; }; "annonces": { "alias": "annonces"; "required": false; "isSignal": true; }; }, {}, ["gabaritSucces", "gabaritErreur", "gabaritVide", "gabaritHorsLigne", "gabaritChargement"], never, true, never>;
1530
+ }
1531
+
1532
+ /**
1533
+ * Les gabarits des cinq etats, declares DANS `<st-state>`.
1534
+ *
1535
+ * ⚠️ Pourquoi des directives de contenu plutot que des entrees `TemplateRef` :
1536
+ * un `<ng-template>` declare a l'exterieur du composant appartient a
1537
+ * l'injecteur de l'endroit ou il est ECRIT, pas de celui qui le rend. Les
1538
+ * fournisseurs de `st-state` — dont `REGION_VIVANTE_PARENTE`, qui fait taire
1539
+ * les annonces en double — ne l'atteignaient donc pas, et l'erreur etait
1540
+ * annoncee deux fois. Passer par le contenu rend la declaration a l'exterieur
1541
+ * impossible : le defaut ne peut plus revenir.
1542
+ */
1543
+ declare class StSucces<T> {
1544
+ readonly gabarit: TemplateRef<{
1545
+ $implicit: Exclude<T, undefined>;
1546
+ }>;
1547
+ /**
1548
+ * La ressource n'est lue nulle part : elle porte le TYPE de la valeur, pour
1549
+ * que `let-valeur` soit type dans le gabarit au lieu d'etre `unknown`.
1550
+ */
1551
+ readonly stSucces: _angular_core.InputSignal<Resource<T> | undefined>;
1552
+ /**
1553
+ * `Exclude<T, undefined>` : une ressource sans valeur initiale se type
1554
+ * `T | undefined`, mais st-state ne rend ce gabarit QUE lorsqu'une valeur
1555
+ * existe. Sans cela, chaque gabarit de succes devrait ecrire `page?.length`
1556
+ * pour un cas qui ne se produit pas.
1557
+ */
1558
+ static ngTemplateContextGuard<T>(_directive: StSucces<T>, _contexte: unknown): _contexte is {
1559
+ $implicit: Exclude<T, undefined>;
1560
+ };
1561
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<StSucces<any>, never>;
1562
+ static ɵdir: _angular_core.ɵɵDirectiveDeclaration<StSucces<any>, "ng-template[stSucces]", never, { "stSucces": { "alias": "stSucces"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
1563
+ }
1564
+ /** Erreur. Le contexte porte l'erreur elle-meme, pour l'afficher ou la traduire. */
1565
+ declare class StErreur {
1566
+ readonly gabarit: TemplateRef<{
1567
+ $implicit: unknown;
1568
+ }>;
1569
+ static ngTemplateContextGuard(_directive: StErreur, _contexte: unknown): _contexte is {
1570
+ $implicit: unknown;
1571
+ };
1572
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<StErreur, never>;
1573
+ static ɵdir: _angular_core.ɵɵDirectiveDeclaration<StErreur, "ng-template[stErreur]", never, {}, {}, never, never, true, never>;
1574
+ }
1575
+ declare class StVide {
1576
+ readonly gabarit: TemplateRef<void>;
1577
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<StVide, never>;
1578
+ static ɵdir: _angular_core.ɵɵDirectiveDeclaration<StVide, "ng-template[stVide]", never, {}, {}, never, never, true, never>;
1579
+ }
1580
+ declare class StHorsLigne {
1581
+ readonly gabarit: TemplateRef<void>;
1582
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<StHorsLigne, never>;
1583
+ static ɵdir: _angular_core.ɵɵDirectiveDeclaration<StHorsLigne, "ng-template[stHorsLigne]", never, {}, {}, never, never, true, never>;
1584
+ }
1585
+ /** Chargement sur mesure. Sans lui, `st-state` rend sa silhouette par defaut. */
1586
+ declare class StChargement {
1587
+ readonly gabarit: TemplateRef<void>;
1588
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<StChargement, never>;
1589
+ static ɵdir: _angular_core.ɵɵDirectiveDeclaration<StChargement, "ng-template[stChargement]", never, {}, {}, never, never, true, never>;
697
1590
  }
1591
+ /** Toutes les directives de gabarit, a importer d'un coup. */
1592
+ declare const GABARITS_D_ETAT: readonly [typeof StSucces, typeof StErreur, typeof StVide, typeof StHorsLigne, typeof StChargement];
698
1593
 
699
- export { CHEMIN_DU_SPRITE, ETATS_DE_BLOC, FUSEAU_PAR_DEFAUT, NOMS_DICONE, REGION_VIVANTE_PARENTE, StAvatar, StBadge, StButton, StButtonGroup, StCode, StCount, StDate, StEmpty, StError, StHeading, StIcon, StIconButton, StLink, StMasked, StMoney, StOfflineBanner, StProgress, StRelativeTime, StSkeleton, StSpinner, StState, StStatusPill, StTag, StText, fournirCheminDuSprite };
700
- export type { EtatDeBloc, FormatDeDate, GraisseDeTexte, NiveauDeTitre, NomDIcone, TailleDIcone, TailleDeBouton, TailleDeSpinner, TailleDeTitre, TonDIcone, TonDeBadge, TonDeProgression, TonDeSpinner, TonDeStatut, TypeMasque, VarianteDErreur, VarianteDeBouton, VarianteDeBoutonIcone, VarianteDeLien, VarianteDeSquelette, VarianteDeTexte };
1594
+ export { AnnonceLocale, CHEMIN_DU_SPRITE, FUSEAU_PAR_DEFAUT, GABARITS_D_ETAT, IDENTIFIANT_DU_CONTENU_PRINCIPAL, LIBELLES_EN, LIBELLES_FR, NOMS_DICONE, REGION_VIVANTE_PARENTE, ST_LIBELLES, ST_LOCALE, StAppShell, StAvatar, StBadge, StBanner, StBreadcrumb, StButton, StButtonGroup, StCard, StChargement, StCode, StCopyButton, StCount, StDate, StDivider, StEmpty, StErreur, StError, StHeader, StHeading, StHorsLigne, StIcon, StIconButton, StInlineMessage, StLangSwitch, StLink, StLogo, StMasked, StMoney, StOfflineBanner, StPageTitle, StProgress, StRelativeTime, StSection, StSkeleton, StSkipLink, StSpinner, StState, StStatusPill, StSucces, StTag, StText, StThemeToggle, StTimer, StVide, copierDansLePressePapiers, formaterDuree, fournirCheminDuSprite, pressePapiersDisponible, provideStarterUi };
1595
+ export type { ConfigurationUi, FormatDeDate, GraisseDeTexte, IssueDeCopie, LibellesUi, MaillonDeFil, NiveauDeTitre, NomDIcone, OrientationDeSeparateur, ReliefDeCarte, RembourrageDeCarte, TailleDIcone, TailleDeBouton, TailleDeSpinner, TailleDeTitre, TonDIcone, TonDeBadge, TonDeBanniere, TonDeMessage, TonDeProgression, TonDeSpinner, TonDeStatut, TypeMasque, VarianteDErreur, VarianteDeBouton, VarianteDeBoutonIcone, VarianteDeLien, VarianteDeSquelette, VarianteDeTexte };