@starterlib/ui 0.2.0 → 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,6 +1,6 @@
1
1
  import * as _angular_core from '@angular/core';
2
- import { InjectionToken, Signal, Provider, Resource, TemplateRef } from '@angular/core';
3
- import { Ton, Montant, TonSemantique, EtatDeBloc } 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
4
  export { ETATS_DE_BLOC, EtatDeBloc } from '@starterlib/util';
5
5
 
6
6
  /**
@@ -31,6 +31,7 @@ interface LibellesUi {
31
31
  /** Valeur technique copiable. */
32
32
  readonly copier: string;
33
33
  readonly copieEffectuee: string;
34
+ readonly copieImpossible: string;
34
35
  /** Valeur masquee. */
35
36
  readonly afficher: string;
36
37
  readonly masquer: string;
@@ -42,6 +43,27 @@ interface LibellesUi {
42
43
  /** Lien sortant, etiquette de retrait, temps relatif. */
43
44
  readonly nouvelleFenetre: string;
44
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;
45
67
  readonly aLInstant: string;
46
68
  }
47
69
  /**
@@ -53,6 +75,14 @@ interface LibellesUi {
53
75
  * sous forme de signal — sinon la moitie de l'interface reste en francais quand
54
76
  * l'utilisateur passe a l'anglais, et rien ne le signale.
55
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
+ */
56
86
  declare const LIBELLES_FR: LibellesUi;
57
87
  /** Traduction anglaise du meme dictionnaire. La paire est obligatoire. */
58
88
  declare const LIBELLES_EN: LibellesUi;
@@ -143,6 +173,59 @@ declare const REGION_VIVANTE_PARENTE: InjectionToken<true>;
143
173
  */
144
174
  declare const FUSEAU_PAR_DEFAUT: InjectionToken<string>;
145
175
 
176
+ /**
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.
226
+ */
227
+ declare function formaterDuree(totalEnSecondes: number, locale: string): string;
228
+
146
229
  type TailleDIcone = 'xs' | 'sm' | 'md' | 'lg' | 'xl';
147
230
  /** Une icone prend n'importe quel ton sauf `inverse`, qui vise un fond plein. */
148
231
  type TonDIcone = Exclude<Ton, 'inverse'>;
@@ -160,7 +243,7 @@ type TonDIcone = Exclude<Ton, 'inverse'>;
160
243
  */
161
244
  declare class StIcon {
162
245
  private readonly cheminDuSprite;
163
- readonly nom: _angular_core.InputSignal<"boite-vide" | "cercle" | "cercle-coche" | "cercle-croix" | "cercle-info" | "chevron-bas" | "chevron-droite" | "chevron-gauche" | "chevron-haut" | "coche" | "copie" | "corbeille" | "croix" | "hors-ligne" | "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">;
164
247
  readonly taille: _angular_core.InputSignal<TailleDIcone>;
165
248
  readonly ton: _angular_core.InputSignal<TonDIcone>;
166
249
  /** `null` : l'icone est decorative et reste muette pour les lecteurs. */
@@ -336,23 +419,34 @@ declare class StButton {
336
419
  readonly variante: _angular_core.InputSignal<VarianteDeBouton>;
337
420
  readonly taille: _angular_core.InputSignal<TailleDeBouton>;
338
421
  readonly pleineLargeur: _angular_core.InputSignalWithTransform<boolean, unknown>;
339
- readonly iconeAvant: _angular_core.InputSignal<"boite-vide" | "cercle" | "cercle-coche" | "cercle-croix" | "cercle-info" | "chevron-bas" | "chevron-droite" | "chevron-gauche" | "chevron-haut" | "coche" | "copie" | "corbeille" | "croix" | "hors-ligne" | "lien-externe" | "menu" | "oeil" | "oeil-barre" | "plus" | "rafraichir" | "recherche" | "serveur" | "triangle-alerte" | "utilisateur" | null>;
340
- readonly iconeApres: _angular_core.InputSignal<"boite-vide" | "cercle" | "cercle-coche" | "cercle-croix" | "cercle-info" | "chevron-bas" | "chevron-droite" | "chevron-gauche" | "chevron-haut" | "coche" | "copie" | "corbeille" | "croix" | "hors-ligne" | "lien-externe" | "menu" | "oeil" | "oeil-barre" | "plus" | "rafraichir" | "recherche" | "serveur" | "triangle-alerte" | "utilisateur" | null>;
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>;
341
424
  /**
342
425
  * Action en cours. Tant qu'il vaut vrai, les clics sont avales : c'est le
343
426
  * mecanisme d'anti double soumission. L'appelant doit le lever DES la
344
427
  * soumission, pas a l'arrivee de la reponse.
345
428
  */
346
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>;
347
441
  /**
348
442
  * Le ton suit le FOND du bouton, et non le bouton en general : sur une
349
443
  * variante posee sur la surface (`secondaire`, qui est le defaut, et
350
444
  * `discret`), un indicateur en ton inverse tombait a 1,00:1 — invisible.
351
445
  */
352
- readonly tonDuChargement: _angular_core.Signal<TonDeSpinner>;
446
+ protected readonly tonDuChargement: _angular_core.Signal<TonDeSpinner>;
353
447
  constructor();
354
448
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<StButton, never>;
355
- 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>;
356
450
  }
357
451
 
358
452
  type VarianteDeBoutonIcone = Extract<VarianteDeBouton, 'discret' | 'secondaire' | 'danger'>;
@@ -364,7 +458,7 @@ type VarianteDeBoutonIcone = Extract<VarianteDeBouton, 'discret' | 'secondaire'
364
458
  * de facon fiable.
365
459
  */
366
460
  declare class StIconButton {
367
- readonly icone: _angular_core.InputSignal<"boite-vide" | "cercle" | "cercle-coche" | "cercle-croix" | "cercle-info" | "chevron-bas" | "chevron-droite" | "chevron-gauche" | "chevron-haut" | "coche" | "copie" | "corbeille" | "croix" | "hors-ligne" | "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">;
368
462
  /** Nom accessible du controle. Sans lui, l'icone ne dit rien. */
369
463
  readonly etiquette: _angular_core.InputSignal<string>;
370
464
  readonly variante: _angular_core.InputSignal<VarianteDeBoutonIcone>;
@@ -437,7 +531,6 @@ declare class StButtonGroup {
437
531
  */
438
532
  declare class StCode {
439
533
  private readonly document;
440
- private readonly destruction;
441
534
  private readonly libelles;
442
535
  readonly valeur: _angular_core.InputSignal<string>;
443
536
  readonly copiable: _angular_core.InputSignalWithTransform<boolean, unknown>;
@@ -448,9 +541,7 @@ declare class StCode {
448
541
  protected readonly etiquetteLue: _angular_core.Signal<string>;
449
542
  protected readonly libelleCopierLu: _angular_core.Signal<string>;
450
543
  readonly copie: _angular_core.OutputEmitterRef<string>;
451
- private readonly confirmation;
452
- private minuterie;
453
- protected readonly texteDeConfirmation: _angular_core.Signal<string>;
544
+ protected readonly annonce: AnnonceLocale;
454
545
  /**
455
546
  * Le bouton n'apparait que si le navigateur sait copier. Sans presse-papiers,
456
547
  * un bouton qui ne fait rien vaut moins que la selection manuelle, que la
@@ -476,7 +567,6 @@ type TypeMasque = 'iban' | 'carte' | 'telephone';
476
567
  */
477
568
  declare class StMasked {
478
569
  private readonly libelles;
479
- private readonly destruction;
480
570
  readonly valeur: _angular_core.InputSignal<string>;
481
571
  readonly type: _angular_core.InputSignal<TypeMasque>;
482
572
  readonly revele: _angular_core.ModelSignal<boolean>;
@@ -488,9 +578,14 @@ declare class StMasked {
488
578
  readonly revelation: _angular_core.OutputEmitterRef<{
489
579
  type: TypeMasque;
490
580
  }>;
491
- private readonly annonce;
492
- protected 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;
493
587
  private minuterie;
588
+ constructor();
494
589
  protected readonly valeurMasquee: _angular_core.Signal<string>;
495
590
  protected readonly valeurAffichee: _angular_core.Signal<string>;
496
591
  /**
@@ -655,7 +750,7 @@ declare class StStatusPill {
655
750
  readonly statut: _angular_core.InputSignal<string>;
656
751
  /** Texte deja traduit par l'appelant : le socle ne traduit rien. */
657
752
  readonly libelle: _angular_core.InputSignal<string>;
658
- readonly icone: _angular_core.InputSignal<"boite-vide" | "cercle" | "cercle-coche" | "cercle-croix" | "cercle-info" | "chevron-bas" | "chevron-droite" | "chevron-gauche" | "chevron-haut" | "coche" | "copie" | "corbeille" | "croix" | "hors-ligne" | "lien-externe" | "menu" | "oeil" | "oeil-barre" | "plus" | "rafraichir" | "recherche" | "serveur" | "triangle-alerte" | "utilisateur">;
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">;
659
754
  readonly ton: _angular_core.InputSignal<TonSemantique>;
660
755
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<StStatusPill, never>;
661
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>;
@@ -748,7 +843,7 @@ declare class StAvatar {
748
843
  declare class StEmpty {
749
844
  readonly titre: _angular_core.InputSignal<string>;
750
845
  readonly description: _angular_core.InputSignal<string | null>;
751
- readonly icone: _angular_core.InputSignal<"boite-vide" | "cercle" | "cercle-coche" | "cercle-croix" | "cercle-info" | "chevron-bas" | "chevron-droite" | "chevron-gauche" | "chevron-haut" | "coche" | "copie" | "corbeille" | "croix" | "hors-ligne" | "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">;
752
847
  readonly niveauDuTitre: _angular_core.InputSignal<NiveauDeTitre>;
753
848
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<StEmpty, never>;
754
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>;
@@ -786,7 +881,7 @@ declare class StError {
786
881
  protected readonly libelleRejeuLu: _angular_core.Signal<string>;
787
882
  protected readonly etiquetteDeTraceLue: _angular_core.Signal<string>;
788
883
  protected readonly etiquetteDuCode: _angular_core.Signal<string>;
789
- protected readonly icone: _angular_core.Signal<"boite-vide" | "cercle" | "cercle-coche" | "cercle-croix" | "cercle-info" | "chevron-bas" | "chevron-droite" | "chevron-gauche" | "chevron-haut" | "coche" | "copie" | "corbeille" | "croix" | "hors-ligne" | "lien-externe" | "menu" | "oeil" | "oeil-barre" | "plus" | "rafraichir" | "recherche" | "serveur" | "triangle-alerte" | "utilisateur">;
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">;
790
885
  protected readonly sAnnonce: _angular_core.Signal<boolean>;
791
886
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<StError, never>;
792
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>;
@@ -813,6 +908,540 @@ declare class StOfflineBanner {
813
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>;
814
909
  }
815
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
+
816
1445
  /**
817
1446
  * Impose les cinq etats a un bloc qui consomme l'API, et centralise leur
818
1447
  * annonce.
@@ -871,7 +1500,7 @@ declare class StState<T> {
871
1500
  private readonly valeurRetenue;
872
1501
  /** Etat deduit de la ressource, valeur retenue comprise. */
873
1502
  private readonly etatDeLaRessource;
874
- readonly etatEffectif: _angular_core.Signal<EtatDeBloc>;
1503
+ protected readonly etatEffectif: _angular_core.Signal<EtatDeBloc>;
875
1504
  /**
876
1505
  * Une valeur est affichee, et une autre arrive — par rappel explicite ou par
877
1506
  * changement de parametre.
@@ -881,7 +1510,7 @@ declare class StState<T> {
881
1510
  private readonly annoncesLues;
882
1511
  protected readonly annonce: _angular_core.Signal<string>;
883
1512
  /** Contexte passe au gabarit : la valeur en succes, l'erreur en erreur. */
884
- readonly contexte: _angular_core.Signal<{
1513
+ protected readonly contexte: _angular_core.Signal<{
885
1514
  $implicit: unknown;
886
1515
  }>;
887
1516
  /**
@@ -890,7 +1519,7 @@ declare class StState<T> {
890
1519
  * l'illusion que les cinq etats sont traites. Il vaut mieux que le manque se
891
1520
  * voie, en developpement.
892
1521
  */
893
- readonly gabaritDeLEtat: _angular_core.Signal<TemplateRef<unknown> | null>;
1522
+ protected readonly gabaritDeLEtat: _angular_core.Signal<TemplateRef<unknown> | null>;
894
1523
  private readonly chargementVisible;
895
1524
  /** La silhouette par defaut, une fois le delai anti-clignotement passe. */
896
1525
  protected readonly montreLaSilhouetteParDefaut: _angular_core.Signal<boolean>;
@@ -962,5 +1591,5 @@ declare class StChargement {
962
1591
  /** Toutes les directives de gabarit, a importer d'un coup. */
963
1592
  declare const GABARITS_D_ETAT: readonly [typeof StSucces, typeof StErreur, typeof StVide, typeof StHorsLigne, typeof StChargement];
964
1593
 
965
- export { CHEMIN_DU_SPRITE, FUSEAU_PAR_DEFAUT, GABARITS_D_ETAT, LIBELLES_EN, LIBELLES_FR, NOMS_DICONE, REGION_VIVANTE_PARENTE, ST_LIBELLES, ST_LOCALE, StAvatar, StBadge, StButton, StButtonGroup, StChargement, StCode, StCount, StDate, StEmpty, StErreur, StError, StHeading, StHorsLigne, StIcon, StIconButton, StLink, StMasked, StMoney, StOfflineBanner, StProgress, StRelativeTime, StSkeleton, StSpinner, StState, StStatusPill, StSucces, StTag, StText, StVide, fournirCheminDuSprite, provideStarterUi };
966
- export type { ConfigurationUi, FormatDeDate, GraisseDeTexte, LibellesUi, 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 };