@starterlib/ui 0.8.0 → 0.9.1

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.
Files changed (55) hide show
  1. package/LICENCES-TIERCES.md +236 -0
  2. package/README.md +101 -47
  3. package/assets/icones/catalogue.json +3296 -0
  4. package/assets/icones/sprite.svg +235 -35
  5. package/fesm2022/starterlib-ui-arbre.mjs +473 -80
  6. package/fesm2022/starterlib-ui-arbre.mjs.map +1 -1
  7. package/fesm2022/starterlib-ui-donnees.mjs +3551 -522
  8. package/fesm2022/starterlib-ui-donnees.mjs.map +1 -1
  9. package/fesm2022/starterlib-ui-formulaires.mjs +3186 -443
  10. package/fesm2022/starterlib-ui-formulaires.mjs.map +1 -1
  11. package/fesm2022/starterlib-ui-libelles-en.mjs +380 -139
  12. package/fesm2022/starterlib-ui-libelles-en.mjs.map +1 -1
  13. package/fesm2022/starterlib-ui-listes.mjs +5354 -658
  14. package/fesm2022/starterlib-ui-listes.mjs.map +1 -1
  15. package/fesm2022/starterlib-ui-messagerie.mjs +737 -0
  16. package/fesm2022/starterlib-ui-messagerie.mjs.map +1 -0
  17. package/fesm2022/starterlib-ui-navigation.mjs +506 -243
  18. package/fesm2022/starterlib-ui-navigation.mjs.map +1 -1
  19. package/fesm2022/starterlib-ui-onglets.mjs +369 -135
  20. package/fesm2022/starterlib-ui-onglets.mjs.map +1 -1
  21. package/fesm2022/starterlib-ui-parcours.mjs +2449 -0
  22. package/fesm2022/starterlib-ui-parcours.mjs.map +1 -0
  23. package/fesm2022/starterlib-ui-qr.mjs +907 -0
  24. package/fesm2022/starterlib-ui-qr.mjs.map +1 -0
  25. package/fesm2022/starterlib-ui-saisie.mjs +8566 -1589
  26. package/fesm2022/starterlib-ui-saisie.mjs.map +1 -1
  27. package/fesm2022/starterlib-ui-selection.mjs +1340 -268
  28. package/fesm2022/starterlib-ui-selection.mjs.map +1 -1
  29. package/fesm2022/starterlib-ui-sens.mjs +59 -0
  30. package/fesm2022/starterlib-ui-sens.mjs.map +1 -0
  31. package/fesm2022/starterlib-ui-surfaces.mjs +5140 -1387
  32. package/fesm2022/starterlib-ui-surfaces.mjs.map +1 -1
  33. package/fesm2022/starterlib-ui.mjs +10721 -2871
  34. package/fesm2022/starterlib-ui.mjs.map +1 -1
  35. package/package.json +27 -18
  36. package/styles/amorce.css +69 -0
  37. package/styles/couches.css +178 -0
  38. package/types/starterlib-ui-arbre.d.ts +199 -25
  39. package/types/starterlib-ui-donnees.d.ts +1441 -180
  40. package/types/starterlib-ui-formulaires.d.ts +1174 -139
  41. package/types/starterlib-ui-libelles-en.d.ts +3 -23
  42. package/types/starterlib-ui-listes.d.ts +2310 -255
  43. package/types/starterlib-ui-messagerie.d.ts +317 -0
  44. package/types/starterlib-ui-navigation.d.ts +201 -63
  45. package/types/starterlib-ui-onglets.d.ts +172 -43
  46. package/types/starterlib-ui-parcours.d.ts +916 -0
  47. package/types/starterlib-ui-qr.d.ts +105 -0
  48. package/types/starterlib-ui-saisie.d.ts +3431 -549
  49. package/types/starterlib-ui-selection.d.ts +441 -65
  50. package/types/starterlib-ui-sens.d.ts +44 -0
  51. package/types/starterlib-ui-surfaces.d.ts +1899 -510
  52. package/types/starterlib-ui.d.ts +4749 -1115
  53. package/fesm2022/starterlib-ui-interactions.mjs +0 -43
  54. package/fesm2022/starterlib-ui-interactions.mjs.map +0 -1
  55. package/types/starterlib-ui-interactions.d.ts +0 -4
@@ -1,18 +1,58 @@
1
- import * as _angular_core from '@angular/core';
2
- import * as _starterlib_ui from '@starterlib/ui';
3
- import { AnnonceLocale } from '@starterlib/ui';
4
- import { ControleDeSaisie, OptionDeListe, ContratDeChamp } from '@starterlib/ui/saisie';
5
- import { FormValueControl } from '@angular/forms/signals';
6
-
1
+ import { AnnonceLocale } from "@starterlib/ui";
2
+ import { ContratDeChamp, ControleDeSaisie, OptionDeListe, PresentationDeLibelle } from "@starterlib/ui/saisie";
3
+ import { SuggestionDAdresse, sansCommandesDeDirection } from "@starterlib/util";
4
+ import * as i0 from "@angular/core";
5
+ import { TemplateRef } from "@angular/core";
6
+ import { FormValueControl } from "@angular/forms/signals";
7
+ /** Contexte du gabarit d'option de `st-combobox`. */
8
+ export interface ContexteDOption {
9
+ /** L'option rendue. */
10
+ readonly $implicit: OptionDeListe;
11
+ /**
12
+ * L'option porte-t-elle la coche ? Meme etat que la coche posee par le composant : l'option
13
+ * `aria-selected`, celle qu'Entree retiendrait (la selection suit l'option active au clavier).
14
+ */
15
+ readonly choisie: boolean;
16
+ }
17
+ /**
18
+ * Rendu d'une option de `st-combobox`, quand deux lignes de texte ne suffisent pas (code mono et
19
+ * libelle, planche 15) :
20
+ *
21
+ * ```html
22
+ * <st-combobox libelle="Instrument" [options]="instruments">
23
+ * <ng-template stOption let-option>
24
+ * <span class="code">{{ option.valeur }}</span> {{ option.libelle }}
25
+ * </ng-template>
26
+ * </st-combobox>
27
+ * ```
28
+ *
29
+ * ⚠️ **Ce que le gabarit AFFICHE est ce qui se LIT.** L'option est nommee par le texte que le
30
+ * gabarit rend (`aria-labelledby` vers une seconde copie, masquee, du meme rendu) : le code de l'exemple fait partie du nom, une
31
+ * commande vocale le trouve (WCAG 1.3.1, 2.5.3). L'`aide` reste lue en description. Le `libelle`
32
+ * sert toujours au filtrage, a la recherche au clavier et au texte du champ une fois le choix fait :
33
+ * que le gabarit le rende, pour que le nom commence par ce que la personne tape.
34
+ *
35
+ * Le gabarit est donc rendu deux fois par option : qu'il reste leger et sans effet de bord. Sa
36
+ * copie visible est INERTE (`inert`) : une option ne contient aucun element interactif, et un
37
+ * lien ou un bouton qui s'y glisserait ne prendrait jamais le focus.
38
+ *
39
+ * Sans gabarit, l'option rend son `libelle` (son nom) et, dessous, son `aide` en texte discret.
40
+ */
41
+ export declare class StOption {
42
+ readonly gabarit: TemplateRef<ContexteDOption>;
43
+ static ngTemplateContextGuard(_directive: StOption, _contexte: unknown): _contexte is ContexteDOption;
44
+ static ɵfac: i0.ɵɵFactoryDeclaration<StOption, never>;
45
+ static ɵdir: i0.ɵɵDirectiveDeclaration<StOption, "ng-template[stOption]", never, {}, {}, never, never, true, never>;
46
+ }
7
47
  /** `local` : le composant filtre `options`. `distant` : l'application filtre, sur `recherche`. */
8
- type FiltrageDeListe = 'local' | 'distant';
48
+ export type FiltrageDeListe = 'local' | 'distant';
9
49
  /**
10
50
  * Liste de choix a filtrer en tapant, sur `@angular/aria/combobox` et
11
51
  * `@angular/aria/listbox`.
12
52
  *
13
53
  * ```html
14
54
  * <st-combobox libelle="Beneficiaire" [options]="beneficiaires" [formField]="virement.beneficiaire" />
15
- * <!-- liste servie par le serveur : -->
55
+ * <!-- liste servie par le serveur, temporisee : -->
16
56
  * <st-combobox libelle="Commune" filtrage="distant" [options]="communes()"
17
57
  * (recherche)="terme.set($event)" [formField]="adresse.commune" />
18
58
  * ```
@@ -26,44 +66,205 @@ type FiltrageDeListe = 'local' | 'distant';
26
66
  * - La liste s'ouvre a la frappe et a la fleche bas ; Entree choisit, Echap
27
67
  * ferme. Le focus reste dans le champ (`aria-activedescendant`).
28
68
  * - Le nombre de resultats s'annonce apres la frappe, une fois : le lecteur
29
- * d'ecran ne voit pas la liste se reduire.
69
+ * d'ecran ne voit pas la liste se reduire — en local comme en distant, des
70
+ * que l'application remplace `options` pendant une recherche en cours.
30
71
  * - ⚠️ **Quitter le champ sans choisir rend le texte du choix precedent.** Un
31
72
  * texte qui ne correspond a aucune option ne reste pas affiche comme s'il etait
32
73
  * retenu ; un champ vide, lui, retire le choix.
74
+ * - ⚠️ **La frappe n'est jamais effacee par une reponse du serveur** (A1124,
75
+ * A1151) : le texte affiche ne depend que du CHOIX (`value`), jamais de
76
+ * `options` — une liste remplacee pendant que la personne tape ne touche pas
77
+ * a ce qu'elle a ecrit. Si le libelle du choix n'etait pas encore connu (liste
78
+ * servie vide au depart, valeur preremplie par le serveur), il se met a jour
79
+ * des que `options` l'apporte, mais seulement hors frappe et hors focus.
33
80
  * - La liste est posee dans la couche superieure du navigateur (`popover`) par le
34
81
  * CDK : un dialogue ou un tableau defilant ne la rogne pas.
82
+ * - `readonly` : le champ reste tabulable et lisible, mais ne s'ouvre plus (Fleche
83
+ * bas, Entree, Espace et la frappe sans effet), comme `st-select`.
84
+ * - Le CHOIX retenu s'affiche en graisse semi (planche 13-2) : ce qui est tape, et
85
+ * pas encore choisi, reste en graisse normale — on voit ce qui partira.
86
+ * - Une option porte son `aide` sur une seconde ligne, lue en description. Avec un
87
+ * gabarit `stOption`, l'option est nommee par le texte que le gabarit rend (ce qui
88
+ * se voit se lit), et ce contenu est inerte (voir `StOption`).
89
+ * - `chargement` (distant, reponse attendue) : l'indicateur prend la place du
90
+ * chevron apres le delai d'attente, `aria-busy` sur le champ et la liste. Le
91
+ * composant affiche ce que `options` contient : une liste vide pendant l'attente
92
+ * ne dit pas « Aucun resultat » (ni a l'ecran ni a l'annonce) mais « Chargement en
93
+ * cours » ; le nombre de resultats s'annonce a la FIN de l'attente.
94
+ * - `longueurMinimale` (distant) : sous ce nombre de caracteres, une liste vide dit « Saisissez
95
+ * au moins 3 caracteres. » et non « Aucun resultat » — l'application ne cherche pas encore, ce
96
+ * n'est pas une recherche sans reponse.
35
97
  *
36
- * ⚠️ En `distant`, `recherche` est emis a chaque frappe : a l'application de
37
- * temporiser, et de ne pas mettre le terme dans l'adresse (SEC-6).
98
+ * ⚠️ En `distant`, `recherche` n'est emis QU'EN MODE DISTANT (jamais en local, ou
99
+ * l'application n'a rien a filtrer elle-meme), et TEMPORISE (`temporisationEnMs`,
100
+ * 250 ms par defaut) : la derniere frappe gagne, sauf un champ vide qui part
101
+ * aussitot. A l'application de ne jamais mettre le terme dans l'adresse (SEC-6).
38
102
  */
39
- declare class StCombobox extends ControleDeSaisie {
40
- protected readonly libelles: _angular_core.Signal<_starterlib_ui.LibellesUi>;
41
- private readonly element;
42
- private readonly injecteur;
43
- readonly options: _angular_core.InputSignal<readonly OptionDeListe[]>;
44
- readonly filtrage: _angular_core.InputSignal<FiltrageDeListe>;
45
- /** Texte tape, a chaque frappe. Sert au filtrage `distant`. */
46
- readonly recherche: _angular_core.OutputEmitterRef<string>;
47
- protected readonly annonce: AnnonceLocale;
48
- protected readonly ouvert: _angular_core.WritableSignal<boolean>;
49
- /** Texte du champ : le libelle du choix, tant que la personne ne tape pas. */
50
- protected readonly texte: _angular_core.WritableSignal<string>;
51
- /** Ce qui filtre : vide a l'ouverture par la fleche, pour montrer toute la liste. */
52
- private readonly filtre;
53
- /** Option active dans la liste ; le choix n'est retenu qu'a la validation. */
54
- protected readonly surlignee: _angular_core.WritableSignal<string[]>;
55
- protected readonly visibles: _angular_core.Signal<readonly OptionDeListe[]>;
56
- private readonly liste;
57
- constructor();
58
- protected surSaisie(evenement: Event): void;
59
- protected basculer(): void;
60
- protected valider(): void;
61
- protected aLaSortie(evenement: FocusEvent): void;
62
- private libelleDe;
63
- static ɵfac: _angular_core.ɵɵFactoryDeclaration<StCombobox, never>;
64
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<StCombobox, "st-combobox", never, { "options": { "alias": "options"; "required": true; "isSignal": true; }; "filtrage": { "alias": "filtrage"; "required": false; "isSignal": true; }; }, { "recherche": "recherche"; }, never, never, true, never>;
103
+ export declare class StCombobox extends ControleDeSaisie {
104
+ /**
105
+ * Un texte de donnees : sans commande de direction, et isole par son element (`dir="auto"` ou
106
+ * `<bdi>`), il ne reordonne ni lui-meme ni ce qui l'entoure (audit du 2026-09-26, S-1 ; audit
107
+ * etendu du 2026-09-27, A-2).
108
+ */
109
+ protected readonly affichable: typeof sansCommandesDeDirection;
110
+ protected readonly libelles: import("@angular/core").Signal<import("@starterlib/ui").LibellesUi>;
111
+ private readonly locale;
112
+ private readonly element;
113
+ private readonly injecteur;
114
+ private readonly document;
115
+ readonly options: import("@angular/core").InputSignal<readonly OptionDeListe[]>;
116
+ readonly filtrage: import("@angular/core").InputSignal<FiltrageDeListe>;
117
+ /** Glyphe de tete, decoratif (planche 13 : banque, entreprise). */
118
+ readonly icone: import("@angular/core").InputSignal<"accessibilite" | "appareils" | "arborescence" | "asterisque" | "badge-coche" | "banque" | "batiment" | "bifurcation" | "billets" | "billets-envoi" | "billets-pile" | "boite" | "boite-de-reception" | "bouclier" | "bouclier-alerte" | "bouclier-coche" | "bouclier-coeur" | "bouclier-croix" | "bouclier-moitie" | "bouclier-recherche" | "bouclier-utilisateur" | "boussole" | "bouton-curseur" | "bulle-question" | "cadenas" | "cadenas-horloge" | "cadenas-ouvert" | "cadre-pied" | "cadre-texte" | "calendrier" | "calendrier-evenement" | "calendrier-horloge" | "calendrier-jour" | "calques" | "carte-bancaire" | "carte-bancaire-barre" | "carte-bancaire-cadenas" | "carte-contact" | "carte-identite" | "cartes-empilees" | "case-cochee" | "casse" | "cercle" | "cercle-alerte" | "cercle-chevron-bas" | "cercle-coche" | "cercle-coche-ouvert" | "cercle-croix" | "cercle-info" | "cercle-moins" | "cercle-plus" | "cercle-question" | "certificat" | "chandelier" | "chargement" | "cheque" | "chevron-bas" | "chevron-droite" | "chevron-gauche" | "chevron-haut" | "chevrons-droite" | "chevrons-haut-bas" | "cle" | "cloche" | "cloche-sonnerie" | "coche" | "code" | "code-qr" | "code-qr-scanner" | "coffre-fort" | "colonnes" | "connexion" | "contraste" | "copie" | "corbeille" | "corbeille-croix" | "courriel" | "crayon" | "croix" | "curseur-clic" | "deconnexion" | "devise" | "disposition" | "dollar" | "dossier" | "dossier-barre" | "dossier-ouvert" | "double-coche" | "echange" | "eclair" | "empreinte-digitale" | "enregistrer" | "entree" | "envoyer" | "epaisseur-de-trait" | "epingle" | "etoile" | "euro" | "fichier" | "fichier-image" | "fichier-pdf" | "fichier-texte" | "filtre" | "filtre-barre" | "filtre-lignes" | "fleche-bas" | "fleche-bas-gauche" | "fleche-bas-ligne" | "fleche-droite" | "fleche-gauche" | "fleche-haut" | "fleche-haut-droite" | "fleche-haut-ligne" | "fleche-large-haut" | "fleches-gauche-droite" | "flocon" | "flou" | "formes" | "globe" | "graphique-anneau" | "graphique-barres" | "graphique-barres-cadre" | "graphique-camembert" | "graphique-ligne" | "graphique-lignes" | "grille" | "grille-lignes" | "hexagone" | "historique" | "horloge" | "horloge-fleche" | "iban" | "imprimer" | "interdit" | "jalons" | "jauge" | "lien" | "lien-externe" | "lignes" | "lignes-crayon" | "liste" | "liste-coche" | "liste-controle" | "liste-numerotee" | "luminosite" | "lune" | "maillet" | "maison" | "marque-page" | "menu" | "menu-ouvert" | "message" | "minuteur" | "mise-au-point" | "mise-en-page-image" | "moins" | "nuage-barre" | "nuage-televerser" | "octogone-alerte" | "oeil" | "oeil-barre" | "panneau-gauche" | "parametres" | "parapluie" | "parchemin" | "pieces" | "plus" | "pointeur" | "points" | "points-verticaux" | "portefeuille" | "portefeuille-cartes" | "presse-papiers-coche" | "presse-papiers-horloge" | "priorite-haute" | "rafraichir" | "recherche" | "recherche-barre" | "recherche-texte" | "rectangle-points" | "recu" | "redemarrer" | "reglages" | "regle" | "reseau-jauge" | "rotation-arriere" | "routeur" | "sablier" | "sablier-bas" | "sablier-haut" | "sac-argent" | "sans-contact" | "serveur" | "soleil" | "style-de-trait" | "synchro" | "synchro-probleme" | "tableau" | "tableau-de-bord" | "tableau-de-bord-plus" | "tablette" | "tabulation" | "telecharger" | "telephone-mobile" | "televerser" | "tendance-baisse" | "tendance-hausse" | "terminal" | "tirelire" | "triangle-alerte" | "triangle-bas" | "triangle-haut" | "trombone" | "utilisateur" | "utilisateur-crayon" | "utilisateurs" | "wifi" | "wifi-barre" | null>;
119
+ /** Le style de l'etiquette (voir `st-form-field`). */
120
+ readonly presentation: import("@angular/core").InputSignal<PresentationDeLibelle>;
121
+ /**
122
+ * Reponse attendue du serveur (mode `distant`) : indicateur a la place du chevron apres
123
+ * `rythme.delai.attente`, `aria-busy`, options affichees conservees. Le composant n'appelle
124
+ * jamais le reseau : c'est l'etat de la ressource de l'application (`isLoading()`).
125
+ */
126
+ readonly chargement: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
127
+ /** Bouton « Effacer le choix » a cote du chevron, des qu'un choix est fait (planche 13). */
128
+ readonly effacable: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
129
+ /**
130
+ * Delai avant l'emission de `recherche` en mode `distant`, et avant l'annonce du nombre de
131
+ * resultats en mode `local` : la derniere frappe gagne.
132
+ */
133
+ readonly temporisationEnMs: import("@angular/core").InputSignalWithTransform<number, unknown>;
134
+ /**
135
+ * Distant : le nombre de caracteres a partir duquel l'application cherche. Au-dessous, une liste
136
+ * vide le dit (« Saisissez au moins 3 caracteres. »). `0` : aucun minimum.
137
+ */
138
+ readonly longueurMinimale: import("@angular/core").InputSignalWithTransform<number, unknown>;
139
+ /** Texte tape, temporise. Sert au filtrage `distant` ; jamais emis en `local`. */
140
+ readonly recherche: import("@angular/core").OutputEmitterRef<string>;
141
+ protected readonly annonce: AnnonceLocale;
142
+ protected readonly gabaritDOption: import("@angular/core").Signal<StOption | undefined>;
143
+ /** L'indicateur n'apparait qu'apres le delai d'attente et reste le temps minimal (P6). */
144
+ protected readonly attenteVisible: import("@angular/core").Signal<boolean>;
145
+ protected readonly ouvert: import("@angular/core").WritableSignal<boolean>;
146
+ /**
147
+ * Texte du champ : le libelle du choix, tant que la personne ne tape pas.
148
+ *
149
+ * ⚠️ La SOURCE est `value` SEULE (et non une fonction unique qui lirait aussi
150
+ * `options`) : un `linkedSignal` a une seule fonction se recalcule — et ECRASE
151
+ * ce que la personne tape — a CHAQUE dependance lue par cette fonction qui
152
+ * change, `options` comprise. En mode `distant`, l'application remplace
153
+ * `options` a chaque reponse : la frappe partirait a la premiere reponse
154
+ * servie apres un choix (A1124, A1151). En scindant source et calcul, seul un
155
+ * changement de VALEUR (un choix, ou `aLaSortie`) reinitialise le texte ;
156
+ * `options` est lue `untracked`, comme une simple consultation.
157
+ */
158
+ protected readonly texte: import("@angular/core").WritableSignal<string>;
159
+ /** Ce qui filtre : vide a l'ouverture par la fleche, pour montrer toute la liste. */
160
+ private readonly filtre;
161
+ /** Option active dans la liste ; le choix n'est retenu qu'a la validation. */
162
+ protected readonly surlignee: import("@angular/core").WritableSignal<string[]>;
163
+ protected readonly visibles: import("@angular/core").Signal<readonly OptionDeListe[]>;
164
+ protected readonly blocs: import("@angular/core").Signal<readonly import("@starterlib/ui/saisie").BlocDOptions[]>;
165
+ /** Distant : un terme tape, plus court que ce que l'application cherche. */
166
+ protected readonly tropCourt: import("@angular/core").Signal<boolean>;
167
+ /** Le bouton « Effacer le choix » est-il rendu ? Pilote aussi la place reservee au champ :
168
+ * une seule cible tactile par defaut (chevron seul), doublee seulement quand ce bouton
169
+ * s'ajoute — jamais 88 px reserves pour un bouton qui n'existe pas. */
170
+ protected readonly afficherEffacer: import("@angular/core").Signal<boolean>;
171
+ /** Le texte affiche est-il le libelle du choix retenu (et non une frappe en cours) ? */
172
+ protected readonly choixAffiche: import("@angular/core").Signal<boolean>;
173
+ protected readonly idListe: string;
174
+ private readonly liste;
175
+ private readonly champNatif;
176
+ private minuterie;
177
+ private derniereAnnonce;
178
+ constructor();
179
+ protected surSaisie(evenement: Event): void;
180
+ /**
181
+ * Local : le nombre de resultats se dit apres `temporisationEnMs`, la derniere frappe gagnant, et
182
+ * seulement s'il a change depuis la derniere annonce, comme en distant. A chaque frappe, meme
183
+ * inchange, il recouvrait l'echo des lettres tapees (audit UI du 2026-09-27, D-16). La minuterie
184
+ * est celle de la recherche distante : un choix, une sortie ou un effacement l'annulent aussi.
185
+ */
186
+ private annoncerLeNombreLocal;
187
+ /** Emet `recherche`, temporise : la derniere frappe gagne, un champ vide part aussitot. */
188
+ private emettreRecherche;
189
+ /**
190
+ * Annule la recherche temporisee en attente : un choix, une sortie du champ ou un effacement
191
+ * survenu avant la fin du delai ne doit pas emettre `recherche` pour un terme abandonne (sinon
192
+ * l'application remplace `options` apres coup, pour une saisie qui n'existe plus).
193
+ */
194
+ private annulerRecherche;
195
+ protected basculer(): void;
196
+ /** Vide le choix et le texte d'un coup (bouton « Effacer le choix », `effacable`). */
197
+ protected effacer(): void;
198
+ /**
199
+ * Le clic sur le listbox valide l'option ACTIVE — mais un en-tete de groupe (`role="group"`,
200
+ * pas une option) est DANS le listbox et fait remonter son clic ici : sans ce garde, cliquer
201
+ * un intitule de groupe validerait l'option active comme un choix involontaire.
202
+ */
203
+ protected surClic(evenement: MouseEvent): void;
204
+ protected valider(): void;
205
+ protected aLaSortie(evenement: FocusEvent): void;
206
+ protected idDuGroupe(indice: number): string;
207
+ /** Id du contenu rendu par le gabarit `stOption`, qui NOMME l'option (`aria-labelledby`). */
208
+ protected idDuContenu(indiceDuBloc: number, indice: number): string;
209
+ /** Id de l'aide d'une option, lue en description (`aria-describedby`). */
210
+ protected idDeLAide(indiceDuBloc: number, indice: number): string;
211
+ private libelleDe;
212
+ static ɵfac: i0.ɵɵFactoryDeclaration<StCombobox, never>;
213
+ static ɵcmp: i0.ɵɵComponentDeclaration<StCombobox, "st-combobox", never, {
214
+ "options": {
215
+ "alias": "options";
216
+ "required": true;
217
+ "isSignal": true;
218
+ };
219
+ "filtrage": {
220
+ "alias": "filtrage";
221
+ "required": false;
222
+ "isSignal": true;
223
+ };
224
+ "icone": {
225
+ "alias": "icone";
226
+ "required": false;
227
+ "isSignal": true;
228
+ };
229
+ "presentation": {
230
+ "alias": "presentation";
231
+ "required": false;
232
+ "isSignal": true;
233
+ };
234
+ "chargement": {
235
+ "alias": "chargement";
236
+ "required": false;
237
+ "isSignal": true;
238
+ };
239
+ "effacable": {
240
+ "alias": "effacable";
241
+ "required": false;
242
+ "isSignal": true;
243
+ };
244
+ "temporisationEnMs": {
245
+ "alias": "temporisationEnMs";
246
+ "required": false;
247
+ "isSignal": true;
248
+ };
249
+ "longueurMinimale": {
250
+ "alias": "longueurMinimale";
251
+ "required": false;
252
+ "isSignal": true;
253
+ };
254
+ }, {
255
+ "recherche": "recherche";
256
+ }, ["gabaritDOption"], never, true, never>;
257
+ }
258
+ /**
259
+ * `auto` (defaut) : jusqu'a trois libelles, puis « N choix ». `liste` : toujours les libelles
260
+ * (passe a la ligne, ne rogne jamais). `nombre` : toujours « N choix ».
261
+ */
262
+ export type ResumeDeMultiselect = 'auto' | 'liste' | 'nombre';
263
+ /** Un morceau du resume : le libelle d'une option (isole a l'affichage), ou un mot de la langue. */
264
+ interface MorceauDeResume {
265
+ readonly texte: string;
266
+ readonly libelle: boolean;
65
267
  }
66
-
67
268
  /**
68
269
  * Choix de plusieurs valeurs dans une liste, sur `@angular/aria/combobox` et
69
270
  * `@angular/aria/listbox`.
@@ -75,38 +276,213 @@ declare class StCombobox extends ControleDeSaisie {
75
276
  * Le modele est la liste des VALEURS choisies, dans l'ordre des options.
76
277
  *
77
278
  * - Fleche bas, Entree ou Espace ouvrent la liste ; Espace coche ou decoche
78
- * l'option active sans fermer ; Echap ferme.
79
- * - ⚠️ **Chaque choix reste visible et retirable** sous le champ, par un bouton
80
- * « Retirer … ». Un resume « 3 choix » dans le declencheur ne dit pas lesquels,
81
- * et obligerait a rouvrir la liste pour en retirer un.
279
+ * l'option active sans fermer, et l'annonce a chaque fois (« Epargne, coche,
280
+ * 2 choix ») : le lecteur d'ecran ne voit ni la case ni le total changer seul ;
281
+ * Echap ferme.
282
+ * - ⚠️ **Chaque choix reste visible et retirable** sous le champ, dans une liste
283
+ * NOMMEE (« Choix retenus »), par un bouton « Retirer … ». Un resume « 3 choix »
284
+ * dans le declencheur ne dit pas lesquels, et obligerait a rouvrir la liste pour
285
+ * en retirer un ; « Tout retirer » vide les deux d'un coup.
82
286
  * - Un choix retire rend le focus au retrait suivant, ou au champ : le focus ne
83
287
  * tombe jamais sur le document.
288
+ * - `readonly` : le declencheur reste tabulable, ne s'ouvre plus, et les puces
289
+ * perdent leur croix de retrait (rien a modifier en lecture seule).
84
290
  *
85
291
  * ⚠️ Sous une dizaine d'options, un groupe de cases a cocher (`st-fieldset` et
86
292
  * `st-checkbox`) est plus simple : tout est visible, rien a ouvrir.
87
293
  */
88
- declare class StMultiselect extends ContratDeChamp implements FormValueControl<readonly string[]> {
89
- protected readonly libelles: _angular_core.Signal<_starterlib_ui.LibellesUi>;
90
- private readonly element;
91
- private readonly injecteur;
92
- readonly value: _angular_core.ModelSignal<readonly string[]>;
93
- readonly options: _angular_core.InputSignal<readonly OptionDeListe[]>;
94
- protected readonly annonce: AnnonceLocale;
95
- protected readonly ouvert: _angular_core.WritableSignal<boolean>;
96
- private readonly liste;
97
- /** La liste d'Aria attend un tableau modifiable ; le modele, lui, est en lecture seule. */
98
- protected readonly valeursDeListe: _angular_core.Signal<string[]>;
99
- protected readonly choisies: _angular_core.Signal<OptionDeListe[]>;
100
- protected readonly resume: _angular_core.Signal<string>;
101
- constructor();
102
- /** Le declencheur n'est pas un champ natif : la base ne le trouve pas par `#champ`. */
103
- focus(options?: FocusOptions): void;
104
- protected surChoix(valeurs: readonly string[]): void;
105
- protected retirer(valeur: string, indice: number): void;
106
- protected aLaSortie(evenement: FocusEvent): void;
107
- static ɵfac: _angular_core.ɵɵFactoryDeclaration<StMultiselect, never>;
108
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<StMultiselect, "st-multiselect", never, { "value": { "alias": "value"; "required": false; "isSignal": true; }; "options": { "alias": "options"; "required": true; "isSignal": true; }; }, { "value": "valueChange"; }, never, never, true, never>;
294
+ export declare class StMultiselect extends ContratDeChamp implements FormValueControl<readonly string[]> {
295
+ /**
296
+ * Un texte de donnees : sans commande de direction, et isole par son element (`dir="auto"` ou
297
+ * `<bdi>`), il ne reordonne ni lui-meme ni ce qui l'entoure (audit du 2026-09-26, S-1 ; audit
298
+ * etendu du 2026-09-27, A-2).
299
+ */
300
+ protected readonly affichable: typeof sansCommandesDeDirection;
301
+ protected readonly libelles: import("@angular/core").Signal<import("@starterlib/ui").LibellesUi>;
302
+ private readonly locale;
303
+ private readonly element;
304
+ private readonly injecteur;
305
+ readonly value: import("@angular/core").ModelSignal<readonly string[]>;
306
+ readonly options: import("@angular/core").InputSignal<readonly OptionDeListe[]>;
307
+ /** Comment le resume se dit dans le declencheur. */
308
+ readonly modeDeResume: import("@angular/core").InputSignal<ResumeDeMultiselect>;
309
+ /** Bouton « Tout retirer » sous les puces, des qu'il y a au moins deux choix. */
310
+ readonly toutRetirer: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
311
+ /** La liste « Choix retenus » sous le declencheur. Sans elle, le resume seul dit les choix. */
312
+ readonly puces: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
313
+ protected readonly annonce: AnnonceLocale;
314
+ protected readonly ouvert: import("@angular/core").WritableSignal<boolean>;
315
+ private readonly liste;
316
+ protected readonly idListe: string;
317
+ /** La liste d'Aria attend un tableau modifiable ; le modele, lui, est en lecture seule. */
318
+ protected readonly valeursDeListe: import("@angular/core").Signal<string[]>;
319
+ protected readonly choisies: import("@angular/core").Signal<OptionDeListe[]>;
320
+ protected readonly blocs: import("@angular/core").Signal<readonly import("@starterlib/ui/saisie").BlocDOptions[]>;
321
+ /**
322
+ * Le resume du declencheur, en morceaux. Chaque libelle y est un texte de donnees comme dans les
323
+ * options et les puces : sans commande de direction, et isole a l'affichage (`dir="auto"`) ; il
324
+ * y passait brut (audit UI du 2026-09-27, D-5). La liste prend la forme de la langue
325
+ * (`Intl.ListFormat` sur `ST_LOCALE` : « Livret A et Compte courant », « Livret A and Compte
326
+ * courant »), et non une virgule ecrite en dur (D-28).
327
+ */
328
+ protected readonly resume: import("@angular/core").Signal<readonly MorceauDeResume[]>;
329
+ constructor();
330
+ /** Le declencheur n'est pas un champ natif : la base ne le trouve pas par `#champ`. */
331
+ focus(options?: FocusOptions): void;
332
+ /**
333
+ * A chaque coche ou decoche (clic, ou Espace sur l'option active) : le modele se range dans
334
+ * l'ordre des options (et non des clics), et l'annonce dit l'option ET le nouveau total —
335
+ * jamais l'un sans l'autre, car un lecteur d'ecran ne voit ni la case ni le compte changer seul.
336
+ */
337
+ protected surChoix(valeurs: readonly string[]): void;
338
+ protected retirer(valeur: string, indice: number): void;
339
+ /** Vide tous les choix d'un coup et rend le focus au declencheur. */
340
+ protected retirerTout(): void;
341
+ protected aLaSortie(evenement: FocusEvent): void;
342
+ protected idDuGroupe(indice: number): string;
343
+ static ɵfac: i0.ɵɵFactoryDeclaration<StMultiselect, never>;
344
+ static ɵcmp: i0.ɵɵComponentDeclaration<StMultiselect, "st-multiselect", never, {
345
+ "value": {
346
+ "alias": "value";
347
+ "required": false;
348
+ "isSignal": true;
349
+ };
350
+ "options": {
351
+ "alias": "options";
352
+ "required": true;
353
+ "isSignal": true;
354
+ };
355
+ "modeDeResume": {
356
+ "alias": "modeDeResume";
357
+ "required": false;
358
+ "isSignal": true;
359
+ };
360
+ "toutRetirer": {
361
+ "alias": "toutRetirer";
362
+ "required": false;
363
+ "isSignal": true;
364
+ };
365
+ "puces": {
366
+ "alias": "puces";
367
+ "required": false;
368
+ "isSignal": true;
369
+ };
370
+ }, {
371
+ "value": "valueChange";
372
+ }, never, never, true, never>;
373
+ }
374
+ /**
375
+ * Recherche d'adresse, a inserer dans `st-address-fieldset` : elle interroge la source que l'HOTE
376
+ * a reliee une fois (`ST_RECHERCHE_D_ADRESSES`), et reporte l'adresse choisie dans les champs.
377
+ *
378
+ * ```html
379
+ * <st-address-fieldset libelle="Adresse de residence" [formField]="formulaire.adresse">
380
+ * <st-address-search />
381
+ * </st-address-fieldset>
382
+ * ```
383
+ *
384
+ * ⚠️ **Le composant n'appelle jamais le reseau** : il appelle l'interface `RechercheDAdresses`
385
+ * (`@starterlib/util`), que le noyau implemente (relais du BFF, Photon). Sans source reliee, il
386
+ * ne rend rien : le champ d'adresse reste entier, et se remplit a la main ou par le navigateur.
387
+ *
388
+ * - Patron combobox de l'APG, sur `st-combobox` (distant) : anti-rebond, attente dite, nombre de
389
+ * resultats annonce ; sous trois caracteres, rien ne part et la liste le dit.
390
+ * - La recherche se restreint au pays choisi dans le champ ; `precision` (region, pays) se lit
391
+ * en seconde ligne de chaque suggestion.
392
+ * - Choisir REMPLIT les champs et laisse le focus dans la recherche (WCAG 3.2.2) ; « Adresse
393
+ * reportee dans les champs. Verifiez-la. » s'annonce dans la region du champ. Le complement
394
+ * saisi n'est jamais efface. Rien n'est remplace sans le choix explicite d'une suggestion.
395
+ * - Une panne ne bloque rien : un message dit de saisir l'adresse dans les champs.
396
+ * - L'attribution exigee par la licence des donnees (« © OpenStreetMap ») s'affiche sous la
397
+ * recherche, liee a sa page.
398
+ *
399
+ * ⚠️ Le texte tape part chez la source a chaque recherche : c'est une donnee personnelle. Le
400
+ * choix de la source (et d'un relais par le BFF) est celui de l'hote ; voir la recette `adresses`.
401
+ */
402
+ export declare class StAddressSearch {
403
+ private readonly source;
404
+ private readonly champ;
405
+ protected readonly libelles: import("@angular/core").Signal<import("@starterlib/ui").LibellesUi>;
406
+ private readonly locale;
407
+ protected readonly minimum = 3;
408
+ /** Rendue seulement avec une source ET dans un champ d'adresse. */
409
+ protected readonly active: boolean;
410
+ protected readonly attribution: import("@starterlib/util").AttributionDeDonnees | null;
411
+ /** Le texte tape, temporise par `st-combobox`. */
412
+ protected readonly terme: import("@angular/core").WritableSignal<string>;
413
+ /** La suggestion choisie (son identifiant), ou `''`. */
414
+ protected readonly choix: import("@angular/core").WritableSignal<string>;
415
+ protected readonly inactive: import("@angular/core").Signal<boolean>;
416
+ private readonly demande;
417
+ protected readonly suggestions: import("@angular/core").ResourceRef<readonly SuggestionDAdresse[] | undefined>;
418
+ /** Les suggestions servies, gardees pour le choix qui suit. */
419
+ private readonly servies;
420
+ protected readonly options: import("@angular/core").Signal<OptionDeListe[]>;
421
+ /** La recherche ou le detail d'une suggestion n'ont pas abouti. */
422
+ protected readonly indisponible: import("@angular/core").WritableSignal<boolean>;
423
+ /** Annule le detail en cours quand le composant disparait. */
424
+ private readonly arret;
425
+ constructor();
426
+ protected choisir(id: string): Promise<void>;
427
+ static ɵfac: i0.ɵɵFactoryDeclaration<StAddressSearch, never>;
428
+ static ɵcmp: i0.ɵɵComponentDeclaration<StAddressSearch, "st-address-search", never, {}, {}, never, never, true, never>;
429
+ }
430
+ /**
431
+ * Liste des pays a filtrer en tapant : la variante filtrable de `st-country-field`, sur
432
+ * `st-combobox`. La valeur est le code ISO 3166-1 alpha-2, `''` sans choix.
433
+ *
434
+ * ```html
435
+ * <st-country-combobox libelle="Nationalite" [enTete]="['FR', 'BE', 'CH']" [formField]="f.nationalite" />
436
+ * ```
437
+ *
438
+ * Memes options que `st-country-field` (`optionsDesPays`) : noms par `Intl` dans la langue de la
439
+ * page, tries par sa collation ; pays frequents en tete, sans etre repetes ; un pays du modele hors
440
+ * de `codes` reste affiche, nomme et desactive, et `erreurPays` du schema dit pourquoi. La frappe
441
+ * filtre sans accents ni casse (« etats » trouve « Etats-Unis ») ; le code ISO ne s'affiche jamais.
442
+ *
443
+ * ⚠️ **Pour la nationalite, le pays de naissance, la residence fiscale** : des questions sans jeton
444
+ * de remplissage automatique (WCAG 1.3.5), sur 249 pays, ou taper vaut mieux que faire defiler.
445
+ * Pour le PAYS D'UNE ADRESSE, `st-country-field` : le navigateur remplit un `select` natif par le
446
+ * jeton `country`, il ne sait pas choisir une option d'une liste filtrable (ADR 0005, D130).
447
+ */
448
+ export declare class StCountryCombobox extends ControleDeSaisie {
449
+ private readonly libelles;
450
+ private readonly locale;
451
+ /** Les pays proposes (codes ISO) ; absent : les 249 pays de la norme. */
452
+ readonly codes: import("@angular/core").InputSignal<readonly string[] | null>;
453
+ /** Les pays frequents, en tete de liste et dans cet ordre. */
454
+ readonly enTete: import("@angular/core").InputSignal<readonly string[]>;
455
+ /** Bouton « Effacer le choix » des qu'un pays est choisi (voir `st-combobox`). */
456
+ readonly effacable: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
457
+ /** Le style de l'etiquette (voir `st-form-field`). */
458
+ readonly presentation: import("@angular/core").InputSignal<PresentationDeLibelle>;
459
+ private readonly liste;
460
+ protected readonly options: import("@angular/core").Signal<OptionDeListe[]>;
461
+ /** Signal Forms amene le focus sur le champ de la liste. */
462
+ focus(options?: FocusOptions): void;
463
+ static ɵfac: i0.ɵɵFactoryDeclaration<StCountryCombobox, never>;
464
+ static ɵcmp: i0.ɵɵComponentDeclaration<StCountryCombobox, "st-country-combobox", never, {
465
+ "codes": {
466
+ "alias": "codes";
467
+ "required": false;
468
+ "isSignal": true;
469
+ };
470
+ "enTete": {
471
+ "alias": "enTete";
472
+ "required": false;
473
+ "isSignal": true;
474
+ };
475
+ "effacable": {
476
+ "alias": "effacable";
477
+ "required": false;
478
+ "isSignal": true;
479
+ };
480
+ "presentation": {
481
+ "alias": "presentation";
482
+ "required": false;
483
+ "isSignal": true;
484
+ };
485
+ }, {}, never, never, true, never>;
109
486
  }
110
487
 
111
- export { StCombobox, StMultiselect };
112
- export type { FiltrageDeListe };
488
+ export {};
@@ -0,0 +1,44 @@
1
+ import { Directionality } from "@angular/cdk/bidi";
2
+ import * as i0 from "@angular/core";
3
+ import { EnvironmentProviders } from "@angular/core";
4
+ /**
5
+ * Le sens d'ecriture du CDK, tenu a jour avec celui du document (lot 228).
6
+ *
7
+ * ⚠️ Le `Directionality` racine du CDK lit `dir` UNE fois, a sa construction. Une bascule a
8
+ * l'execution — `StLangue`, qui pose `dir` sur `<html>` a chaque changement de langue, ou le reglage
9
+ * de sens du banc — ne lui parvenait jamais : chaque couche creee ensuite (menu, popover, liste de
10
+ * choix, dialogue) recevait du CDK `dir="ltr"` sur son hote et s'ecrivait de gauche a droite dans
11
+ * une page de droite a gauche, bords de debut et de fin inverses ; les fleches des primitives
12
+ * d'`@angular/aria` (arbre, onglets, menus) restaient celles de la gauche vers la droite.
13
+ *
14
+ * Celui-ci suit `dir` sur `<html>` et sur `<body>` (le `<body>` l'emporte, comme au CDK) : sa
15
+ * valeur, un signal que lisent les primitives d'`@angular/aria`, change, et `change` emet. Une
16
+ * couche creee apres la bascule porte le bon sens ; une couche deja ouverte garde le sien jusqu'a
17
+ * sa fermeture.
18
+ *
19
+ * La valeur de depart reste celle que le CDK lit a la construction. Ensuite, seul `rtl` se lit de
20
+ * droite a gauche : le socle n'ecrit que `ltr` ou `rtl`, et `dir="auto"` pose en cours de route se
21
+ * lit `ltr`.
22
+ */
23
+ export declare class SensDuDocument extends Directionality {
24
+ constructor();
25
+ static ɵfac: i0.ɵɵFactoryDeclaration<SensDuDocument, never>;
26
+ static ɵprov: i0.ɵɵInjectableDeclaration<any>;
27
+ }
28
+ /**
29
+ * Fait suivre au CDK le sens d'ecriture du document. A poser une fois, dans les fournisseurs de
30
+ * l'APPLICATION hote, a cote de `provideStarterUi` :
31
+ *
32
+ * ```ts
33
+ * bootstrapApplication(Coquille, {
34
+ * providers: [provideStarterUi({ cheminDuSprite }), provideSensDuDocument()],
35
+ * });
36
+ * ```
37
+ *
38
+ * Sans lui, une application qui change de sens sans recharger la page (une langue de droite a
39
+ * gauche) ouvre ses couches dans l'ancien sens. Une application qui ne change jamais de sens n'en a
40
+ * pas besoin.
41
+ */
42
+ export declare function provideSensDuDocument(): EnvironmentProviders;
43
+
44
+ export {};