@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.
- package/LICENCES-TIERCES.md +236 -0
- package/README.md +101 -47
- package/assets/icones/catalogue.json +3296 -0
- package/assets/icones/sprite.svg +235 -35
- package/fesm2022/starterlib-ui-arbre.mjs +473 -80
- package/fesm2022/starterlib-ui-arbre.mjs.map +1 -1
- package/fesm2022/starterlib-ui-donnees.mjs +3551 -522
- package/fesm2022/starterlib-ui-donnees.mjs.map +1 -1
- package/fesm2022/starterlib-ui-formulaires.mjs +3186 -443
- package/fesm2022/starterlib-ui-formulaires.mjs.map +1 -1
- package/fesm2022/starterlib-ui-libelles-en.mjs +380 -139
- package/fesm2022/starterlib-ui-libelles-en.mjs.map +1 -1
- package/fesm2022/starterlib-ui-listes.mjs +5354 -658
- package/fesm2022/starterlib-ui-listes.mjs.map +1 -1
- package/fesm2022/starterlib-ui-messagerie.mjs +737 -0
- package/fesm2022/starterlib-ui-messagerie.mjs.map +1 -0
- package/fesm2022/starterlib-ui-navigation.mjs +506 -243
- package/fesm2022/starterlib-ui-navigation.mjs.map +1 -1
- package/fesm2022/starterlib-ui-onglets.mjs +369 -135
- package/fesm2022/starterlib-ui-onglets.mjs.map +1 -1
- package/fesm2022/starterlib-ui-parcours.mjs +2449 -0
- package/fesm2022/starterlib-ui-parcours.mjs.map +1 -0
- package/fesm2022/starterlib-ui-qr.mjs +907 -0
- package/fesm2022/starterlib-ui-qr.mjs.map +1 -0
- package/fesm2022/starterlib-ui-saisie.mjs +8566 -1589
- package/fesm2022/starterlib-ui-saisie.mjs.map +1 -1
- package/fesm2022/starterlib-ui-selection.mjs +1340 -268
- package/fesm2022/starterlib-ui-selection.mjs.map +1 -1
- package/fesm2022/starterlib-ui-sens.mjs +59 -0
- package/fesm2022/starterlib-ui-sens.mjs.map +1 -0
- package/fesm2022/starterlib-ui-surfaces.mjs +5140 -1387
- package/fesm2022/starterlib-ui-surfaces.mjs.map +1 -1
- package/fesm2022/starterlib-ui.mjs +10721 -2871
- package/fesm2022/starterlib-ui.mjs.map +1 -1
- package/package.json +27 -18
- package/styles/amorce.css +69 -0
- package/styles/couches.css +178 -0
- package/types/starterlib-ui-arbre.d.ts +199 -25
- package/types/starterlib-ui-donnees.d.ts +1441 -180
- package/types/starterlib-ui-formulaires.d.ts +1174 -139
- package/types/starterlib-ui-libelles-en.d.ts +3 -23
- package/types/starterlib-ui-listes.d.ts +2310 -255
- package/types/starterlib-ui-messagerie.d.ts +317 -0
- package/types/starterlib-ui-navigation.d.ts +201 -63
- package/types/starterlib-ui-onglets.d.ts +172 -43
- package/types/starterlib-ui-parcours.d.ts +916 -0
- package/types/starterlib-ui-qr.d.ts +105 -0
- package/types/starterlib-ui-saisie.d.ts +3431 -549
- package/types/starterlib-ui-selection.d.ts +441 -65
- package/types/starterlib-ui-sens.d.ts +44 -0
- package/types/starterlib-ui-surfaces.d.ts +1899 -510
- package/types/starterlib-ui.d.ts +4749 -1115
- package/fesm2022/starterlib-ui-interactions.mjs +0 -43
- package/fesm2022/starterlib-ui-interactions.mjs.map +0 -1
- package/types/starterlib-ui-interactions.d.ts +0 -4
|
@@ -1,9 +1,8 @@
|
|
|
1
|
-
import { DateIso, PlageDeDates,
|
|
2
|
-
import {
|
|
3
|
-
import
|
|
4
|
-
import
|
|
5
|
-
import
|
|
6
|
-
|
|
1
|
+
import { Adresse, DateIso, DescriptionDeFichier, FormatDAdresse, HeureIso, NatureDeRegion, PartieDAdresse, PlageDeDates, sansCommandesDeDirection } from "@starterlib/util";
|
|
2
|
+
import { DisabledReason, FormCheckboxControl, FormValueControl, ValidationError, WithOptionalFieldTree } from "@angular/forms/signals";
|
|
3
|
+
import { AnnonceLocale, EtiquetteDeGroupe, Icone, LibellesUi } from "@starterlib/ui";
|
|
4
|
+
import * as i0 from "@angular/core";
|
|
5
|
+
import { InjectionToken, Signal } from "@angular/core";
|
|
7
6
|
/**
|
|
8
7
|
* Forme minimale d'une erreur de validation, telle que Signal Forms la rend :
|
|
9
8
|
* un genre, et parfois un message.
|
|
@@ -12,9 +11,45 @@ import * as _angular_core from '@angular/core';
|
|
|
12
11
|
* vague 3, V3-1). Les proprietes propres a chaque genre — `minLength`, `max`… —
|
|
13
12
|
* se lisent par leur nom.
|
|
14
13
|
*/
|
|
15
|
-
interface ErreurAffichable {
|
|
16
|
-
|
|
17
|
-
|
|
14
|
+
export interface ErreurAffichable {
|
|
15
|
+
readonly kind: string;
|
|
16
|
+
readonly message?: string;
|
|
17
|
+
}
|
|
18
|
+
/** Erreur de longueur : `minLength`, `maxLength`, et `longueur` (les deux bornes, du serveur). */
|
|
19
|
+
export interface ErreurDeLongueur extends ErreurAffichable {
|
|
20
|
+
readonly kind: 'minLength' | 'maxLength' | 'longueur';
|
|
21
|
+
readonly minLength?: number;
|
|
22
|
+
readonly maxLength?: number;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Erreur de borne : un nombre (`min`, `max`), une date ISO (`dateMin`, `dateMax`) ou une heure
|
|
26
|
+
* ISO (`heureMin`, `heureMax`) ; `DateIso` et `HeureIso` sont deux chaines.
|
|
27
|
+
*/
|
|
28
|
+
export interface ErreurDeBorne extends ErreurAffichable {
|
|
29
|
+
readonly kind: 'min' | 'max' | 'dateMin' | 'dateMax' | 'heureMin' | 'heureMax';
|
|
30
|
+
readonly min?: number | DateIso;
|
|
31
|
+
readonly max?: number | DateIso;
|
|
32
|
+
/** Borne EXCLUSIVE du serveur (`@DecimalMin(inclusive = false)`) : dite strictement (lot 201). */
|
|
33
|
+
readonly strict?: boolean;
|
|
34
|
+
}
|
|
35
|
+
/** Erreur d'un fichier ou d'une liste de fichiers : lequel, et la limite franchie. */
|
|
36
|
+
export interface ErreurDeFichier extends ErreurAffichable {
|
|
37
|
+
readonly kind: 'fichierTaille' | 'fichierType' | 'fichiersNombre';
|
|
38
|
+
readonly fichier?: string;
|
|
39
|
+
/** En octets pour `fichierTaille`, en nombre de fichiers pour `fichiersNombre`. */
|
|
40
|
+
readonly max?: number;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Erreur d'une adresse, sur une PARTIE (cle `partie`, comme `st-date-range`) : `adresse` pour une
|
|
44
|
+
* partie exigee restee vide, `codePostal` pour un code qui n'a pas la forme du pays (avec un
|
|
45
|
+
* exemple reel), `pays` pour un pays hors de la liste admise.
|
|
46
|
+
*/
|
|
47
|
+
export interface ErreurDAdresse extends ErreurAffichable {
|
|
48
|
+
readonly kind: 'adresse' | 'codePostal' | 'pays';
|
|
49
|
+
readonly partie: PartieDAdresse;
|
|
50
|
+
/** Ce que la region designe dans le pays : le message la nomme comme le champ. */
|
|
51
|
+
readonly nature?: NatureDeRegion;
|
|
52
|
+
readonly exemple?: string;
|
|
18
53
|
}
|
|
19
54
|
/**
|
|
20
55
|
* Le texte d'une erreur, dans la langue courante.
|
|
@@ -27,17 +62,30 @@ interface ErreurAffichable {
|
|
|
27
62
|
* Afficher `ibanChecksum` a une personne qui saisit un IBAN, c'est lui montrer le
|
|
28
63
|
* code source.
|
|
29
64
|
*
|
|
30
|
-
* La locale sert aux messages qui citent un format, une date
|
|
31
|
-
* format jj/mm/aaaa » n'est pas « mm/dd/yyyy ».
|
|
65
|
+
* La locale sert aux messages qui citent un format, une date, une taille ou un nombre : « au
|
|
66
|
+
* format jj/mm/aaaa » n'est pas « mm/dd/yyyy », et « 1 000,5 » n'est pas « 1,000.5 ». Les
|
|
67
|
+
* composants la lisent dans `ST_LOCALE`.
|
|
68
|
+
*
|
|
69
|
+
* ⚠️ **Un parametre malforme rend le message generique, il ne leve jamais** : l'appel vit dans
|
|
70
|
+
* un `computed` du champ, et une exception y viderait le champ, voire la page (constat A1132). Une
|
|
71
|
+
* date qui n'est pas ISO, une devise qui n'est pas un code de trois lettres : « valeur invalide ».
|
|
72
|
+
*
|
|
73
|
+
* `minLength` et `maxLength` sur une LISTE (les options cochees d'un `st-checkbox-group`, lot 248)
|
|
74
|
+
* comptent des options : « Choisissez au moins 1 option. », et non « Saisissez au moins
|
|
75
|
+
* 1 caracteres. ».
|
|
32
76
|
*/
|
|
33
|
-
declare function messageDErreur(erreur: ErreurAffichable, libelles: LibellesUi, locale?: string): string;
|
|
77
|
+
export declare function messageDErreur(erreur: ErreurAffichable, libelles: LibellesUi, locale?: string): string;
|
|
78
|
+
/** Le libelle d'une partie d'adresse, tel que le champ l'affiche. */
|
|
79
|
+
export declare function libelleDePartie(libelles: LibellesUi, partie: string, nature?: string): string;
|
|
34
80
|
/** Le motif a taper dans la langue courante : `jj/mm/aaaa`. */
|
|
35
|
-
declare function motifLocal(libelles: LibellesUi, locale: string): string;
|
|
81
|
+
export declare function motifLocal(libelles: LibellesUi, locale: string): string;
|
|
82
|
+
/** Le motif d'une heure dans la langue courante : `hh:mm`, `hh:mm AM/PM`. */
|
|
83
|
+
export declare function motifDHeureLocal(libelles: LibellesUi, locale: string, secondes?: boolean): string;
|
|
36
84
|
/**
|
|
37
85
|
* Un jour superieur a 12 : « 31/03/2026 » montre sans ambiguite ou va le jour,
|
|
38
86
|
* ce que « 01/02/2026 » ne dit pas.
|
|
39
87
|
*/
|
|
40
|
-
declare function exempleDeDate(locale: string): string;
|
|
88
|
+
export declare function exempleDeDate(locale: string): string;
|
|
41
89
|
/**
|
|
42
90
|
* Erreur d'IBAN, a brancher sur un schema :
|
|
43
91
|
*
|
|
@@ -53,23 +101,40 @@ declare function exempleDeDate(locale: string): string;
|
|
|
53
101
|
* vide n'est pas « invalide » ici — c'est `required` qui le dit, avec le bon
|
|
54
102
|
* message.
|
|
55
103
|
*/
|
|
56
|
-
declare function erreurIban(valeur: string): ErreurAffichable | null;
|
|
104
|
+
export declare function erreurIban(valeur: string): ErreurAffichable | null;
|
|
57
105
|
/**
|
|
58
|
-
* Erreur de FORME d'un numero de telephone : chiffres
|
|
59
|
-
* de 4 a 15 chiffres — la longueur maximale d'un
|
|
106
|
+
* Erreur de FORME d'un numero de telephone : chiffres et separateurs usuels (espace, point,
|
|
107
|
+
* tiret, parentheses), `+` de tete facultatif, de 4 a 15 chiffres — la longueur maximale d'un
|
|
108
|
+
* numero international (E.164).
|
|
60
109
|
*
|
|
61
110
|
* ```ts
|
|
62
111
|
* validate(chemin.telephone, ({ value }) => erreurTelephone(value()));
|
|
63
112
|
* ```
|
|
64
113
|
*
|
|
114
|
+
* ⚠️ La forme se juge sur le texte RECU : « 06 12 AB » est refuse, meme si `normaliserTelephone`
|
|
115
|
+
* en tire « 0612 ». `st-phone-field` le signale aussi sur sa saisie, dont le modele ne garde que
|
|
116
|
+
* les chiffres et le `+` de tete.
|
|
117
|
+
*
|
|
65
118
|
* ⚠️ Une forme valide ne dit pas que le numero existe : seul le serveur le sait.
|
|
66
119
|
* Un champ vide n'est pas une erreur de forme : l'obligation est une autre regle.
|
|
67
120
|
*/
|
|
68
|
-
declare function erreurTelephone(valeur: string): ErreurAffichable | null;
|
|
121
|
+
export declare function erreurTelephone(valeur: string): ErreurAffichable | null;
|
|
122
|
+
/**
|
|
123
|
+
* Erreur d'un code a usage unique : exactement `longueur` chiffres (6 par defaut), rien d'autre.
|
|
124
|
+
*
|
|
125
|
+
* ```ts
|
|
126
|
+
* validate(chemin.code, ({ value }) => erreurCode(value(), 6));
|
|
127
|
+
* ```
|
|
128
|
+
*
|
|
129
|
+
* ⚠️ Vide, le code n'est pas « incomplet » : l'obligation est une autre regle, avec son message.
|
|
130
|
+
* Le message dit la longueur attendue (« Saisissez les 6 chiffres du code. ») et non « invalide » :
|
|
131
|
+
* un code refuse par le serveur (« Code incorrect. ») arrive par `errors`, avec son propre texte.
|
|
132
|
+
*/
|
|
133
|
+
export declare function erreurCode(valeur: string, longueur?: number): ErreurAffichable | null;
|
|
69
134
|
/** Bornes d'une date, en ISO. Absente : pas de borne. */
|
|
70
|
-
interface BornesDeDate {
|
|
71
|
-
|
|
72
|
-
|
|
135
|
+
export interface BornesDeDate {
|
|
136
|
+
readonly min?: DateIso | null;
|
|
137
|
+
readonly max?: DateIso | null;
|
|
73
138
|
}
|
|
74
139
|
/**
|
|
75
140
|
* Erreur de bornes d'une date, a brancher sur un schema :
|
|
@@ -81,16 +146,59 @@ interface BornesDeDate {
|
|
|
81
146
|
* Les bornes du schema et celles passees au calendrier doivent etre les memes :
|
|
82
147
|
* le calendrier grise, le schema refuse une date tapee a la main.
|
|
83
148
|
*/
|
|
84
|
-
declare function erreurDate(valeur: DateIso | null, bornes: BornesDeDate):
|
|
149
|
+
export declare function erreurDate(valeur: DateIso | null, bornes: BornesDeDate): ErreurDeBorne | null;
|
|
150
|
+
/** Bornes d'une heure, `HH:MM` ou `HH:MM:SS`. Absente : pas de borne. */
|
|
151
|
+
export interface BornesDHeure {
|
|
152
|
+
readonly min?: HeureIso | null;
|
|
153
|
+
readonly max?: HeureIso | null;
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* Erreur de bornes d'une heure, a brancher sur un schema, comme `erreurDate` :
|
|
157
|
+
*
|
|
158
|
+
* ```ts
|
|
159
|
+
* validate(chemin.execution, ({ value }) => erreurHeure(value(), { min: '08:00', max: '18:00' }));
|
|
160
|
+
* ```
|
|
161
|
+
*
|
|
162
|
+
* Les bornes du schema et celles passees au champ (`heureMin`, `heureMax`, dites dans l'aide)
|
|
163
|
+
* doivent etre les memes. Une heure absente n'est pas hors bornes : c'est `required` qui le dit.
|
|
164
|
+
*/
|
|
165
|
+
export declare function erreurHeure(valeur: HeureIso | null, bornes: BornesDHeure): ErreurDeBorne | null;
|
|
85
166
|
/** Une fin anterieure au debut. Une borne manquante n'est pas une erreur de plage. */
|
|
86
|
-
declare function erreurPlageDeDates(plage: PlageDeDates): ErreurAffichable | null;
|
|
167
|
+
export declare function erreurPlageDeDates(plage: PlageDeDates): ErreurAffichable | null;
|
|
168
|
+
/** Regles d'une adresse, les memes que les entrees de `st-address-fieldset`. */
|
|
169
|
+
export interface ReglesDAdresse {
|
|
170
|
+
/** Faux : une adresse vide est admise ; une adresse commencee doit quand meme etre complete. */
|
|
171
|
+
readonly requise?: boolean;
|
|
172
|
+
/** Les pays admis (codes ISO) ; absent : tous. */
|
|
173
|
+
readonly codesDesPays?: readonly string[];
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* Erreurs d'une adresse, une par partie a corriger, dans l'ordre du champ (le pays d'abord) :
|
|
177
|
+
*
|
|
178
|
+
* ```ts
|
|
179
|
+
* required(chemin.adresse); // la mention « obligatoire » et aria-required
|
|
180
|
+
* validate(chemin.adresse, ({ value }) => erreursDAdresse(value()));
|
|
181
|
+
* ```
|
|
182
|
+
*
|
|
183
|
+
* ⚠️ `required` seul ne suffit pas : une adresse est un objet, jamais « vide » pour Signal Forms.
|
|
184
|
+
* Ce sont ces erreurs qui bloquent l'envoi. Les parties exigees suivent le format du pays
|
|
185
|
+
* (`partiesExigees`) : la province au Canada, rien de tel en France.
|
|
186
|
+
*
|
|
187
|
+
* ⚠️ Confort de saisie (SEC-5) : le serveur revalide ; le motif d'un code postal n'est qu'une forme.
|
|
188
|
+
*/
|
|
189
|
+
export declare function erreursDAdresse(adresse: Adresse, regles?: ReglesDAdresse): ErreurDAdresse[];
|
|
190
|
+
/**
|
|
191
|
+
* Un pays hors de la liste admise (`st-country-field` avec `codes`) : la valeur deja dans le
|
|
192
|
+
* modele reste affichee, et cette erreur dit pourquoi elle ne passe pas.
|
|
193
|
+
*/
|
|
194
|
+
export declare function erreurPays(code: string, codesAdmis: readonly string[]): ErreurAffichable | null;
|
|
87
195
|
/** Regles de `st-file-upload`, les memes que ses entrees. */
|
|
88
|
-
interface ReglesDeFichiers {
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
196
|
+
export interface ReglesDeFichiers {
|
|
197
|
+
/** Attribut `accept` : `.pdf, image/*`. */
|
|
198
|
+
readonly accept?: string;
|
|
199
|
+
/** En octets. */
|
|
200
|
+
readonly tailleMax?: number;
|
|
201
|
+
readonly nombreMax?: number;
|
|
94
202
|
}
|
|
95
203
|
/**
|
|
96
204
|
* Erreurs d'une liste de fichiers, une par fichier refuse, pour dire LEQUEL :
|
|
@@ -102,7 +210,7 @@ interface ReglesDeFichiers {
|
|
|
102
210
|
* ⚠️ Confort, jamais securite (SEC-5) : le type se deduit de l'extension, et le
|
|
103
211
|
* serveur relit le contenu.
|
|
104
212
|
*/
|
|
105
|
-
declare function erreursDeFichiers(fichiers: readonly DescriptionDeFichier[], regles: ReglesDeFichiers):
|
|
213
|
+
export declare function erreursDeFichiers(fichiers: readonly DescriptionDeFichier[], regles: ReglesDeFichiers): ErreurDeFichier[];
|
|
106
214
|
/**
|
|
107
215
|
* Erreurs a afficher par un champ qui LIT sa saisie (`transformedValue`) : celles
|
|
108
216
|
* du formulaire, plus les erreurs de lecture qu'il ne connait pas encore.
|
|
@@ -112,54 +220,361 @@ declare function erreursDeFichiers(fichiers: readonly DescriptionDeFichier[], re
|
|
|
112
220
|
* sans cette fusion, « 12,5,3 » s'afficherait sans le moindre message. Une erreur
|
|
113
221
|
* deja presente — meme genre, meme partie — n'est pas repetee.
|
|
114
222
|
*/
|
|
115
|
-
declare function fusionnerErreurs(formulaire: readonly ValidationError.WithOptionalFieldTree[], lecture: readonly ValidationError.WithoutFieldTree[]): readonly ErreurAffichable[];
|
|
116
|
-
|
|
223
|
+
export declare function fusionnerErreurs(formulaire: readonly ValidationError.WithOptionalFieldTree[], lecture: readonly ValidationError.WithoutFieldTree[]): readonly ErreurAffichable[];
|
|
117
224
|
/** Elements natifs qui portent la saisie d'un champ du socle. */
|
|
118
|
-
type ElementDeSaisie = HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement;
|
|
225
|
+
export type ElementDeSaisie = HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement;
|
|
119
226
|
/**
|
|
120
227
|
* Base des champs du socle : le contrat Signal Forms, ecrit une fois — tout sauf
|
|
121
|
-
* `value
|
|
228
|
+
* `value` (ou `checked`), dont le type depend du champ (texte, montant, date, case).
|
|
122
229
|
*
|
|
123
|
-
* ⚠️ **Une base, et non une copie par champ.**
|
|
124
|
-
* dans
|
|
125
|
-
* voit pas :
|
|
126
|
-
*
|
|
230
|
+
* ⚠️ **Une base, et non une copie par champ.** Seize membres de contrat recopies
|
|
231
|
+
* dans dix-sept composants, c'est dix-sept occasions d'en oublier un — et l'oubli ne se
|
|
232
|
+
* voit pas : [formField] ne pose que les entrees DECLAREES, sans erreur pour les autres. Un
|
|
233
|
+
* champ sans `touched` n'affiche jamais ses erreurs, un champ sans `readonly` reste modifiable
|
|
234
|
+
* sous une regle `readonly()` du schema, un champ sans reflet de `hidden` ne se masque pas.
|
|
235
|
+
*
|
|
236
|
+
* Les bornes de VALEUR (`min`, `max`) sont a part, dans `ContratDeChampABornes` : Signal Forms
|
|
237
|
+
* les type par la valeur du champ, et une borne mal typee casse la liaison `[formField]`.
|
|
127
238
|
*
|
|
128
239
|
* Les noms restent anglais : voir le glossaire, § 8.
|
|
129
240
|
*
|
|
130
241
|
* Le gabarit du champ doit nommer son element natif `#champ`, et le brancher sur
|
|
131
242
|
* `touch` a la perte du focus.
|
|
132
243
|
*/
|
|
133
|
-
declare abstract class ContratDeChamp {
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
244
|
+
export declare abstract class ContratDeChamp {
|
|
245
|
+
readonly libelle: import("@angular/core").InputSignal<string>;
|
|
246
|
+
readonly aide: import("@angular/core").InputSignal<string | null>;
|
|
247
|
+
readonly errors: import("@angular/core").InputSignal<readonly ValidationError.WithOptionalFieldTree[]>;
|
|
248
|
+
readonly touched: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
|
|
249
|
+
readonly dirty: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
|
|
250
|
+
/** Une validation asynchrone est en cours (« Verification… »). */
|
|
251
|
+
readonly pending: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
|
|
252
|
+
readonly disabled: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
|
|
253
|
+
/** Pourquoi le champ est desactive : a dire en aide, jamais a taire. */
|
|
254
|
+
readonly disabledReasons: import("@angular/core").InputSignal<readonly WithOptionalFieldTree<DisabledReason>[]>;
|
|
255
|
+
readonly readonly: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
|
|
256
|
+
readonly required: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
|
|
257
|
+
readonly hidden: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
|
|
258
|
+
readonly name: import("@angular/core").InputSignal<string>;
|
|
259
|
+
readonly minLength: import("@angular/core").InputSignal<number | undefined>;
|
|
260
|
+
readonly maxLength: import("@angular/core").InputSignal<number | undefined>;
|
|
261
|
+
readonly pattern: import("@angular/core").InputSignal<readonly RegExp[]>;
|
|
262
|
+
readonly touch: import("@angular/core").OutputEmitterRef<void>;
|
|
263
|
+
private readonly champ;
|
|
264
|
+
/** Le groupe (`st-fieldset`) qui contient le champ, s'il y en a un. */
|
|
265
|
+
private readonly groupe;
|
|
266
|
+
/**
|
|
267
|
+
* Desactive par le schema OU par son groupe. ⚠️ `fieldset[disabled]` natif ne gele que les
|
|
268
|
+
* elements natifs : un controle NON natif (declencheur `div role=combobox`) lit ce signal, et
|
|
269
|
+
* non `disabled()`, pour sortir de la tabulation et s'annoncer inactif dans un groupe gele.
|
|
270
|
+
* Le gel du groupe est un etat d'INTERFACE : il ne retire pas le champ de la validation (le
|
|
271
|
+
* schema le fait, par `disabled()`).
|
|
272
|
+
*/
|
|
273
|
+
protected readonly desactive: import("@angular/core").Signal<boolean>;
|
|
274
|
+
/**
|
|
275
|
+
* L'aide a afficher : celle du champ, suivie des raisons de desactivation quand il l'est
|
|
276
|
+
* (« Reserve aux comptes Corporate »). Un champ grise sans raison laisse chercher pourquoi.
|
|
277
|
+
*/
|
|
278
|
+
protected readonly aideEtRaisons: import("@angular/core").Signal<string | null>;
|
|
279
|
+
/** Appele par Signal Forms pour amener le focus sur un champ en erreur. */
|
|
280
|
+
focus(options?: FocusOptions): void;
|
|
281
|
+
protected texteSaisi(evenement: Event): string;
|
|
282
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<ContratDeChamp, never>;
|
|
283
|
+
static ɵdir: i0.ɵɵDirectiveDeclaration<ContratDeChamp, never, never, {
|
|
284
|
+
"libelle": {
|
|
285
|
+
"alias": "libelle";
|
|
286
|
+
"required": true;
|
|
287
|
+
"isSignal": true;
|
|
288
|
+
};
|
|
289
|
+
"aide": {
|
|
290
|
+
"alias": "aide";
|
|
291
|
+
"required": false;
|
|
292
|
+
"isSignal": true;
|
|
293
|
+
};
|
|
294
|
+
"errors": {
|
|
295
|
+
"alias": "errors";
|
|
296
|
+
"required": false;
|
|
297
|
+
"isSignal": true;
|
|
298
|
+
};
|
|
299
|
+
"touched": {
|
|
300
|
+
"alias": "touched";
|
|
301
|
+
"required": false;
|
|
302
|
+
"isSignal": true;
|
|
303
|
+
};
|
|
304
|
+
"dirty": {
|
|
305
|
+
"alias": "dirty";
|
|
306
|
+
"required": false;
|
|
307
|
+
"isSignal": true;
|
|
308
|
+
};
|
|
309
|
+
"pending": {
|
|
310
|
+
"alias": "pending";
|
|
311
|
+
"required": false;
|
|
312
|
+
"isSignal": true;
|
|
313
|
+
};
|
|
314
|
+
"disabled": {
|
|
315
|
+
"alias": "disabled";
|
|
316
|
+
"required": false;
|
|
317
|
+
"isSignal": true;
|
|
318
|
+
};
|
|
319
|
+
"disabledReasons": {
|
|
320
|
+
"alias": "disabledReasons";
|
|
321
|
+
"required": false;
|
|
322
|
+
"isSignal": true;
|
|
323
|
+
};
|
|
324
|
+
"readonly": {
|
|
325
|
+
"alias": "readonly";
|
|
326
|
+
"required": false;
|
|
327
|
+
"isSignal": true;
|
|
328
|
+
};
|
|
329
|
+
"required": {
|
|
330
|
+
"alias": "required";
|
|
331
|
+
"required": false;
|
|
332
|
+
"isSignal": true;
|
|
333
|
+
};
|
|
334
|
+
"hidden": {
|
|
335
|
+
"alias": "hidden";
|
|
336
|
+
"required": false;
|
|
337
|
+
"isSignal": true;
|
|
338
|
+
};
|
|
339
|
+
"name": {
|
|
340
|
+
"alias": "name";
|
|
341
|
+
"required": false;
|
|
342
|
+
"isSignal": true;
|
|
343
|
+
};
|
|
344
|
+
"minLength": {
|
|
345
|
+
"alias": "minLength";
|
|
346
|
+
"required": false;
|
|
347
|
+
"isSignal": true;
|
|
348
|
+
};
|
|
349
|
+
"maxLength": {
|
|
350
|
+
"alias": "maxLength";
|
|
351
|
+
"required": false;
|
|
352
|
+
"isSignal": true;
|
|
353
|
+
};
|
|
354
|
+
"pattern": {
|
|
355
|
+
"alias": "pattern";
|
|
356
|
+
"required": false;
|
|
357
|
+
"isSignal": true;
|
|
358
|
+
};
|
|
359
|
+
}, {
|
|
360
|
+
"touch": "touch";
|
|
361
|
+
}, never, never, true, never>;
|
|
362
|
+
}
|
|
363
|
+
/**
|
|
364
|
+
* Base des champs a bornes de valeur (nombre, montant, date) : `min` et `max` du schema, du type
|
|
365
|
+
* de la valeur (`NonNullable<TValeur>`, comme Signal Forms les pose).
|
|
366
|
+
*/
|
|
367
|
+
export declare abstract class ContratDeChampABornes<TValeur> extends ContratDeChamp {
|
|
368
|
+
readonly min: import("@angular/core").InputSignal<NonNullable<TValeur> | undefined>;
|
|
369
|
+
readonly max: import("@angular/core").InputSignal<NonNullable<TValeur> | undefined>;
|
|
370
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<ContratDeChampABornes<any>, never>;
|
|
371
|
+
static ɵdir: i0.ɵɵDirectiveDeclaration<ContratDeChampABornes<any>, never, never, {
|
|
372
|
+
"min": {
|
|
373
|
+
"alias": "min";
|
|
374
|
+
"required": false;
|
|
375
|
+
"isSignal": true;
|
|
376
|
+
};
|
|
377
|
+
"max": {
|
|
378
|
+
"alias": "max";
|
|
379
|
+
"required": false;
|
|
380
|
+
"isSignal": true;
|
|
381
|
+
};
|
|
382
|
+
}, {}, never, never, true, never>;
|
|
150
383
|
}
|
|
151
384
|
/** Base des champs dont la valeur est le texte saisi. */
|
|
152
|
-
declare abstract class ControleDeSaisie extends ContratDeChamp implements FormValueControl<string> {
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
385
|
+
export declare abstract class ControleDeSaisie extends ContratDeChamp implements FormValueControl<string> {
|
|
386
|
+
readonly value: import("@angular/core").ModelSignal<string>;
|
|
387
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<ControleDeSaisie, never>;
|
|
388
|
+
static ɵdir: i0.ɵɵDirectiveDeclaration<ControleDeSaisie, never, never, {
|
|
389
|
+
"value": {
|
|
390
|
+
"alias": "value";
|
|
391
|
+
"required": false;
|
|
392
|
+
"isSignal": true;
|
|
393
|
+
};
|
|
394
|
+
}, {
|
|
395
|
+
"value": "valueChange";
|
|
396
|
+
}, never, never, true, never>;
|
|
397
|
+
}
|
|
398
|
+
/**
|
|
399
|
+
* Base des cases a cocher et des interrupteurs : le meme contrat, avec `checked` a la place de
|
|
400
|
+
* `value` (FormCheckboxControl).
|
|
401
|
+
*
|
|
402
|
+
* ⚠️ `readonly` n'existe pas sur une case native : le clic la bascule quand meme. `surClic`
|
|
403
|
+
* l'annule avant la bascule (`preventDefault`), `surBascule` n'ecrit le modele qu'hors lecture
|
|
404
|
+
* seule ; le gabarit pose `aria-readonly`. La case reste focalisable et lue (a l'inverse de
|
|
405
|
+
* `disabled`, qui la retire de la tabulation).
|
|
406
|
+
*/
|
|
407
|
+
export declare abstract class ContratDeCase extends ContratDeChamp implements FormCheckboxControl {
|
|
408
|
+
readonly checked: import("@angular/core").ModelSignal<boolean>;
|
|
409
|
+
/**
|
|
410
|
+
* A brancher sur `(click)` de la case native : en lecture seule, le clic (souris, ou Espace qui
|
|
411
|
+
* passe par lui) est annule AVANT la bascule — aucun etat coche transitoire expose a l'arbre
|
|
412
|
+
* d'accessibilite, aucun evenement `input` ni `change`.
|
|
413
|
+
*/
|
|
414
|
+
protected surClic(evenement: MouseEvent): void;
|
|
415
|
+
/** A brancher sur `(change)` de la case native : ecrit le modele (filet si le clic passe). */
|
|
416
|
+
protected surBascule(evenement: Event): void;
|
|
417
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<ContratDeCase, never>;
|
|
418
|
+
static ɵdir: i0.ɵɵDirectiveDeclaration<ContratDeCase, never, never, {
|
|
419
|
+
"checked": {
|
|
420
|
+
"alias": "checked";
|
|
421
|
+
"required": false;
|
|
422
|
+
"isSignal": true;
|
|
423
|
+
};
|
|
424
|
+
}, {
|
|
425
|
+
"checked": "checkedChange";
|
|
426
|
+
}, never, never, true, never>;
|
|
427
|
+
}
|
|
428
|
+
/**
|
|
429
|
+
* Un choix d'une liste : `st-select`, `st-combobox`, `st-multiselect`.
|
|
430
|
+
*
|
|
431
|
+
* La `valeur` part dans le modele, le `libelle` s'affiche : un identifiant
|
|
432
|
+
* technique ne s'affiche jamais, et un libelle traduit ne s'envoie jamais.
|
|
433
|
+
*/
|
|
434
|
+
export interface OptionDeListe {
|
|
435
|
+
readonly valeur: string;
|
|
436
|
+
readonly libelle: string;
|
|
437
|
+
/** Une precision sous le libelle (« Reglement brut en temps reel »), lue avec l'option. */
|
|
438
|
+
readonly aide?: string;
|
|
439
|
+
readonly desactivee?: boolean;
|
|
440
|
+
/** Regroupe les options consecutives sous un intitule (`optgroup`). */
|
|
441
|
+
readonly groupe?: string;
|
|
156
442
|
}
|
|
157
|
-
|
|
158
443
|
/**
|
|
159
444
|
* `empilee` : etiquette au-dessus du controle, pour un champ texte.
|
|
160
|
-
* `case` : controle AVANT son etiquette, pour une case a cocher
|
|
445
|
+
* `case` : controle AVANT son etiquette, centre sur la colonne de textes, pour une case a cocher.
|
|
446
|
+
* `reglage` : controle APRES son etiquette (texte a gauche, commande a droite), pour un
|
|
447
|
+
* interrupteur dans sa ligne de reglage (planches 3a, 3b).
|
|
448
|
+
* `en-ligne` : etiquette A GAUCHE du controle, sur une colonne commune reglable
|
|
449
|
+
* par `--st-champ-largeur-libelle` (formulaire horizontal de back-office).
|
|
450
|
+
*/
|
|
451
|
+
export type DispositionDeChamp = 'empilee' | 'case' | 'reglage' | 'en-ligne';
|
|
452
|
+
/**
|
|
453
|
+
* Les jetons d'`autocomplete` qu'un champ du socle emploie (WHATWG, « autofill field names ») :
|
|
454
|
+
* WCAG 1.3.5 demande le bon jeton sur tout champ qui porte une donnee de la personne. Un jeton
|
|
455
|
+
* absent de la liste reste possible (`section-*`, `shipping`…) par la chaine libre.
|
|
456
|
+
*/
|
|
457
|
+
export type TypeDAutocompletion = 'off' | 'on' | 'name' | 'honorific-prefix' | 'given-name' | 'additional-name' | 'family-name' | 'nickname' | 'email' | 'username' | 'new-password' | 'current-password' | 'one-time-code' | 'organization-title' | 'organization' | 'street-address' | 'address-line1' | 'address-line2' | 'address-line3' | 'address-level1' | 'address-level2' | 'country' | 'country-name' | 'postal-code' | 'cc-name' | 'cc-number' | 'cc-exp' | 'cc-csc' | 'transaction-currency' | 'transaction-amount' | 'language' | 'bday' | 'sex' | 'tel' | 'tel-national' | 'url' | (string & Record<never, never>);
|
|
458
|
+
/** Le clavier virtuel adapte (`inputmode`) : `numeric` pour un code, `decimal` pour un montant. */
|
|
459
|
+
export type ModeDeSaisie = 'none' | 'text' | 'decimal' | 'numeric' | 'tel' | 'search' | 'email' | 'url';
|
|
460
|
+
/**
|
|
461
|
+
* Sans accents ni casse : « eleve » trouve « Eleve ».
|
|
462
|
+
*
|
|
463
|
+
* La casse se replie dans la langue de la page (`ST_LOCALE`), passee par le composant qui cherche :
|
|
464
|
+
* les regles de casse ne sont pas les memes d'une langue a l'autre. Sans locale, celle du moteur.
|
|
465
|
+
*/
|
|
466
|
+
export declare function normaliserPourRecherche(texte: string, locale?: string): string;
|
|
467
|
+
/** Options dont le libelle CONTIENT le texte cherche, sans accents ni casse. */
|
|
468
|
+
export declare function filtrerOptions(options: readonly OptionDeListe[], recherche: string, locale?: string): readonly OptionDeListe[];
|
|
469
|
+
/** Un bloc d'options consecutives partageant le meme `groupe` (ou aucun). */
|
|
470
|
+
export interface BlocDOptions {
|
|
471
|
+
/** Identite stable du bloc dans un `@for track` : la valeur de sa premiere option. */
|
|
472
|
+
readonly cle: string;
|
|
473
|
+
readonly groupe: string | null;
|
|
474
|
+
readonly options: readonly OptionDeListe[];
|
|
475
|
+
}
|
|
476
|
+
/**
|
|
477
|
+
* Regroupe des options CONSECUTIVES d'un meme `groupe`, dans l'ordre fourni (`st-select`,
|
|
478
|
+
* `st-combobox`, `st-multiselect`) : un `optgroup` natif ou un `role=group` ARIA se construit sur
|
|
479
|
+
* des blocs adjacents, jamais en triant par nom de groupe.
|
|
480
|
+
*/
|
|
481
|
+
export declare function groupesDOptions(options: readonly OptionDeListe[]): readonly BlocDOptions[];
|
|
482
|
+
/** Identifiants que la base cite dans `aria-describedby`. */
|
|
483
|
+
interface IdentifiantsDeDescription {
|
|
484
|
+
readonly aide: string;
|
|
485
|
+
readonly erreur: string;
|
|
486
|
+
}
|
|
487
|
+
/**
|
|
488
|
+
* Ce que le champ et le groupe partagent : l'aide, les erreurs, l'obligation, et le calcul des
|
|
489
|
+
* descriptions qui les relie.
|
|
490
|
+
*
|
|
491
|
+
* ⚠️ **Une base, et non deux copies** (lot 215). `st-form-field` et `st-fieldset` recopiaient le
|
|
492
|
+
* meme calcul ; la copie du groupe avait garde le defaut que le champ avait perdu (une aide vide
|
|
493
|
+
* citee dans `aria-describedby`, constat A1163). Le repere d'erreur est donc le meme partout :
|
|
494
|
+
* memes messages, meme ordre, meme invalidite.
|
|
495
|
+
*
|
|
496
|
+
* ⚠️ **Un champ montre une seule erreur par defaut** : la premiere, celle que le recapitulatif
|
|
497
|
+
* d'erreurs dit pour ce champ. Deux messages differents pour un meme champ, l'un sous les yeux et
|
|
498
|
+
* l'autre dans le recapitulatif, font chercher la seconde erreur qui n'existe pas.
|
|
499
|
+
* `toutesLesErreurs` les montre toutes, pour un champ dont chaque regle se corrige a part (mot de
|
|
500
|
+
* passe) ou dont chaque erreur vise une partie distincte (un fichier refuse chacun).
|
|
501
|
+
*
|
|
502
|
+
* ⚠️ **Un groupe les montre toutes par defaut** (`st-fieldset` redefinit l'entree a vrai) : ses
|
|
503
|
+
* erreurs visent des parties distinctes (debut ET fin d'une plage), et taire la seconde laisserait
|
|
504
|
+
* une partie `aria-invalid` sans aucun texte qui dise pourquoi (WCAG 3.3.1).
|
|
505
|
+
*/
|
|
506
|
+
declare abstract class PorteurDErreurs {
|
|
507
|
+
private readonly libelles;
|
|
508
|
+
private readonly locale;
|
|
509
|
+
/** Aide permanente : format attendu, exemple. Une chaine vide n'est pas une aide. */
|
|
510
|
+
readonly aide: import("@angular/core").InputSignal<string | null>;
|
|
511
|
+
readonly erreurs: import("@angular/core").InputSignal<readonly ErreurAffichable[]>;
|
|
512
|
+
/**
|
|
513
|
+
* ⚠️ Faux tant que la personne n'a pas quitte le champ ou tente l'envoi (UX-3) : un formulaire
|
|
514
|
+
* vierge couvert d'erreurs accuse avant qu'on ait rien fait.
|
|
515
|
+
*/
|
|
516
|
+
readonly afficherErreurs: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
|
|
517
|
+
/** Montre toutes les erreurs au lieu de la premiere (vrai par defaut sur un groupe). */
|
|
518
|
+
readonly toutesLesErreurs: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
|
|
519
|
+
readonly obligatoire: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
|
|
520
|
+
/** Racine des identifiants, tiree du service d'application (jamais d'un compteur de module). */
|
|
521
|
+
protected readonly racine: string;
|
|
522
|
+
/** Les identifiants de l'aide et de l'erreur, construits par la classe fille depuis `racine`. */
|
|
523
|
+
abstract readonly identifiants: IdentifiantsDeDescription;
|
|
524
|
+
protected readonly libelleObligatoire: import("@angular/core").Signal<string>;
|
|
525
|
+
/** L'aide a rendre : `null` pour une aide absente OU vide, le gabarit et `aria-describedby` d'accord. */
|
|
526
|
+
protected readonly aideRendue: import("@angular/core").Signal<string | null>;
|
|
527
|
+
/** Messages a afficher, dans la langue courante. Vide tant qu'ils ne doivent pas l'etre. */
|
|
528
|
+
protected readonly messages: import("@angular/core").Signal<string[]>;
|
|
529
|
+
/** Vrai quand des messages sont AFFICHES : c'est lui que lisent `aria-invalid` et le lisere. */
|
|
530
|
+
readonly enErreur: import("@angular/core").Signal<boolean>;
|
|
531
|
+
/**
|
|
532
|
+
* ⚠️ Seuls les elements PRESENTS sont references : un `aria-describedby` qui vise un identifiant
|
|
533
|
+
* absent est ignore par certains lecteurs d'ecran — tout entier, y compris les references valides
|
|
534
|
+
* qui l'accompagnent. Ordre de lecture : aide, descriptions propres (complement), erreur.
|
|
535
|
+
*/
|
|
536
|
+
readonly descriptions: import("@angular/core").Signal<string | null>;
|
|
537
|
+
/** `st-champ` ou `st-groupe` : lu une fois, a la construction. */
|
|
538
|
+
protected abstract prefixeDIdentifiant(): string;
|
|
539
|
+
/** Identifiants propres a la classe fille, lus entre l'aide et l'erreur. */
|
|
540
|
+
protected descriptionsPropres(): readonly string[];
|
|
541
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<PorteurDErreurs, never>;
|
|
542
|
+
static ɵdir: i0.ɵɵDirectiveDeclaration<PorteurDErreurs, never, never, {
|
|
543
|
+
"aide": {
|
|
544
|
+
"alias": "aide";
|
|
545
|
+
"required": false;
|
|
546
|
+
"isSignal": true;
|
|
547
|
+
};
|
|
548
|
+
"erreurs": {
|
|
549
|
+
"alias": "erreurs";
|
|
550
|
+
"required": false;
|
|
551
|
+
"isSignal": true;
|
|
552
|
+
};
|
|
553
|
+
"afficherErreurs": {
|
|
554
|
+
"alias": "afficherErreurs";
|
|
555
|
+
"required": false;
|
|
556
|
+
"isSignal": true;
|
|
557
|
+
};
|
|
558
|
+
"toutesLesErreurs": {
|
|
559
|
+
"alias": "toutesLesErreurs";
|
|
560
|
+
"required": false;
|
|
561
|
+
"isSignal": true;
|
|
562
|
+
};
|
|
563
|
+
"obligatoire": {
|
|
564
|
+
"alias": "obligatoire";
|
|
565
|
+
"required": false;
|
|
566
|
+
"isSignal": true;
|
|
567
|
+
};
|
|
568
|
+
}, {}, never, never, true, never>;
|
|
569
|
+
}
|
|
570
|
+
/** Un texte a rendre, ou `null` : une chaine vide ou blanche ne se rend pas. */
|
|
571
|
+
declare function texteRendu(texte: string | null | undefined): string | null;
|
|
572
|
+
/**
|
|
573
|
+
* `libelle` : l'etiquette de champ, 14/500 (D18).
|
|
574
|
+
* `micro-capitales` : 11/600 en capitales espacees, pour un champ de dialogue ou de panneau dense
|
|
575
|
+
* (planches 4, 5, 13) ; le controle, lui, ne change pas.
|
|
161
576
|
*/
|
|
162
|
-
type
|
|
577
|
+
export type PresentationDeLibelle = 'libelle' | 'micro-capitales';
|
|
163
578
|
/**
|
|
164
579
|
* Etiquette, aide, erreur et controle d'un champ de saisie — et le cablage qui
|
|
165
580
|
* les relie.
|
|
@@ -169,73 +584,123 @@ type DispositionDeChamp = 'empilee' | 'case';
|
|
|
169
584
|
* `aria-invalid` : c'est precisement le code que l'on croit fini et qui se perd,
|
|
170
585
|
* un champ specialise a la fois.
|
|
171
586
|
*
|
|
172
|
-
*
|
|
173
|
-
*
|
|
587
|
+
* Anatomie (planche 3b, reference unique D23) : une ligne d'en-tete (etiquette 14/500, mention
|
|
588
|
+
* « (obligatoire) » ou meta `[stMeta]` a droite), l'aide, puis le message — l'erreur, ou a
|
|
589
|
+
* defaut l'indication projetee `[stIndication]` (« Conforme au registre », « Selectionnable &
|
|
590
|
+
* copiable ») —, puis le controle. L'erreur est AU-DESSUS du controle, pour etre vue avant de
|
|
591
|
+
* retaper.
|
|
592
|
+
*
|
|
593
|
+
* ⚠️ **Le lisere d'erreur vit dans la gouttiere**, a -12 px du controle et sur SA hauteur : il
|
|
594
|
+
* ne decale rien, et le controle garde sa largeur et son bord. Le MESSAGE, lui, est au-dessus du
|
|
595
|
+
* controle (D23) : il le pousse vers le bas de sa hauteur (30 px pour une ligne). Chromium compte
|
|
596
|
+
* ce decalage au CLS, meme juste apres Tab : il est mesure au banc, et non nie.
|
|
174
597
|
*
|
|
175
598
|
* ⚠️ **L'erreur n'est pas une region vivante.** Annoncee a la perte du focus, elle
|
|
176
599
|
* couperait la lecture du champ suivant, ou la personne est deja passee. Elle est
|
|
177
600
|
* reliee au controle, donc lue quand on y revient ; a l'envoi, c'est le
|
|
178
601
|
* recapitulatif d'erreurs qui prend le focus et les enumere.
|
|
179
602
|
*/
|
|
180
|
-
declare class StFormField {
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
readonly
|
|
213
|
-
|
|
214
|
-
readonly
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
603
|
+
export declare class StFormField extends PorteurDErreurs {
|
|
604
|
+
/**
|
|
605
|
+
* ⚠️ OBLIGATOIRE et toujours visible (UX-1). Un texte indicatif ne le remplace
|
|
606
|
+
* jamais : il disparait a la premiere frappe.
|
|
607
|
+
*/
|
|
608
|
+
readonly libelle: import("@angular/core").InputSignal<string>;
|
|
609
|
+
/** Texte complementaire tenu a jour par le controle, comme un compteur. Lu apres l'aide. */
|
|
610
|
+
readonly complement: import("@angular/core").InputSignal<string | null>;
|
|
611
|
+
/**
|
|
612
|
+
* ⚠️ Change l'ordre VISUEL, jamais celui du document : l'etiquette reste
|
|
613
|
+
* reliee par `for`, et l'ordre de tabulation ne passe que par le controle.
|
|
614
|
+
* `en-ligne` revient a `empilee` sous la rupture `md` de sa propre largeur.
|
|
615
|
+
*/
|
|
616
|
+
readonly disposition: import("@angular/core").InputSignal<DispositionDeChamp>;
|
|
617
|
+
/** Le style de l'etiquette ; n'agit qu'en disposition `empilee` ou `en-ligne`. */
|
|
618
|
+
readonly presentation: import("@angular/core").InputSignal<PresentationDeLibelle>;
|
|
619
|
+
/**
|
|
620
|
+
* Etiquette lue mais non affichee.
|
|
621
|
+
*
|
|
622
|
+
* ⚠️ Reservee a la RECHERCHE, ou l'icone, le bouton et la position en tete de
|
|
623
|
+
* page disent deja le but du champ. Partout ailleurs, une etiquette masquee est
|
|
624
|
+
* l'etiquette qui manque au moment ou l'on tape (UX-1).
|
|
625
|
+
*/
|
|
626
|
+
readonly libelleMasque: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
|
|
627
|
+
/**
|
|
628
|
+
* Identifiants d'elements DU CONTROLE qui le decrivent (le suffixe « Contrats » d'un
|
|
629
|
+
* `st-input`), lus apres la meta : une unite dite dans le cadre n'est pas perdue au focus.
|
|
630
|
+
*/
|
|
631
|
+
readonly descriptionsDuControle: import("@angular/core").InputSignal<readonly string[]>;
|
|
632
|
+
/** Identifiants du champ, lus par `stControleDeChamp` et par le gabarit. */
|
|
633
|
+
readonly identifiants: {
|
|
634
|
+
readonly controle: string;
|
|
635
|
+
readonly libelle: `${string}-libelle`;
|
|
636
|
+
readonly aide: `${string}-aide`;
|
|
637
|
+
readonly meta: `${string}-meta`;
|
|
638
|
+
readonly indication: `${string}-indication`;
|
|
639
|
+
readonly complement: `${string}-complement`;
|
|
640
|
+
readonly erreur: `${string}-erreur`;
|
|
641
|
+
};
|
|
642
|
+
protected readonly complementRendu: import("@angular/core").Signal<string | null>;
|
|
643
|
+
/**
|
|
644
|
+
* Le controle projete, par reference : c'est lui que le clic sur l'etiquette focalise (et non
|
|
645
|
+
* un `querySelector` sur un identifiant, qui trouverait le controle d'un champ imbrique).
|
|
646
|
+
*/
|
|
647
|
+
private readonly controle;
|
|
648
|
+
/**
|
|
649
|
+
* La meta et l'indication projetees existent-elles ? Relevees au rendu, et non par une requete
|
|
650
|
+
* de contenu : relayees par un champ du socle (`st-input` projette `[stMeta]` et
|
|
651
|
+
* `[stIndication]` plus loin), elles echappent aux requetes de `st-form-field`.
|
|
652
|
+
*/
|
|
653
|
+
private readonly zoneDeMeta;
|
|
654
|
+
private readonly zoneDIndication;
|
|
655
|
+
private readonly metaPresente;
|
|
656
|
+
private readonly indicationPresente;
|
|
657
|
+
/**
|
|
658
|
+
* Un libelle riche `[stLibelle]` est-il projete (lot 218) ? Il remplace alors le texte de
|
|
659
|
+
* `libelle`, qui reste le nom cite par le recapitulatif d'erreurs et doit dire la meme chose.
|
|
660
|
+
*/
|
|
661
|
+
private readonly zoneDuLibelleRiche;
|
|
662
|
+
protected readonly libelleRichePresent: import("@angular/core").WritableSignal<boolean>;
|
|
663
|
+
constructor();
|
|
664
|
+
protected prefixeDIdentifiant(): string;
|
|
665
|
+
protected descriptionsPropres(): readonly string[];
|
|
666
|
+
/**
|
|
667
|
+
* Un clic sur l'etiquette d'un controle non natif n'y mene pas de lui-meme :
|
|
668
|
+
* on y amene le focus, comme le navigateur le fait pour un champ natif.
|
|
669
|
+
*/
|
|
670
|
+
protected focaliserLeControle(): void;
|
|
671
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<StFormField, never>;
|
|
672
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<StFormField, "st-form-field", never, {
|
|
673
|
+
"libelle": {
|
|
674
|
+
"alias": "libelle";
|
|
675
|
+
"required": true;
|
|
676
|
+
"isSignal": true;
|
|
677
|
+
};
|
|
678
|
+
"complement": {
|
|
679
|
+
"alias": "complement";
|
|
680
|
+
"required": false;
|
|
681
|
+
"isSignal": true;
|
|
682
|
+
};
|
|
683
|
+
"disposition": {
|
|
684
|
+
"alias": "disposition";
|
|
685
|
+
"required": false;
|
|
686
|
+
"isSignal": true;
|
|
687
|
+
};
|
|
688
|
+
"presentation": {
|
|
689
|
+
"alias": "presentation";
|
|
690
|
+
"required": false;
|
|
691
|
+
"isSignal": true;
|
|
692
|
+
};
|
|
693
|
+
"libelleMasque": {
|
|
694
|
+
"alias": "libelleMasque";
|
|
695
|
+
"required": false;
|
|
696
|
+
"isSignal": true;
|
|
697
|
+
};
|
|
698
|
+
"descriptionsDuControle": {
|
|
699
|
+
"alias": "descriptionsDuControle";
|
|
700
|
+
"required": false;
|
|
701
|
+
"isSignal": true;
|
|
702
|
+
};
|
|
703
|
+
}, {}, ["controle"], ["[stLibelle]", "[stAide]", "[stMeta]", "[stIndication]", "*"], true, never>;
|
|
239
704
|
}
|
|
240
705
|
/**
|
|
241
706
|
* Pose sur l'element natif d'un champ le cablage de son `st-form-field` :
|
|
@@ -245,21 +710,74 @@ declare class StFormField {
|
|
|
245
710
|
* validation du navigateur a l'envoi : une bulle « Veuillez renseigner ce champ »
|
|
246
711
|
* dans la langue du NAVIGATEUR, pas dans celle de l'application, et qui double
|
|
247
712
|
* le message du socle.
|
|
713
|
+
*
|
|
714
|
+
* `aria-errormessage` s'AJOUTE a `aria-describedby` (qui garde l'erreur) : les lecteurs
|
|
715
|
+
* d'ecran qui le lisent annoncent l'erreur comme telle, les autres la lisent en description.
|
|
248
716
|
*/
|
|
249
|
-
declare class StControleDeChamp {
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
717
|
+
export declare class StControleDeChamp {
|
|
718
|
+
protected readonly champ: StFormField;
|
|
719
|
+
/**
|
|
720
|
+
* ⚠️ `label for` n'etiquette que les elements natifs de formulaire. Le
|
|
721
|
+
* declencheur d'une selection multiple est un `div` de role `combobox` : sans
|
|
722
|
+
* `aria-labelledby`, il n'aurait aucun nom, et l'etiquette visible ne dirait
|
|
723
|
+
* rien au lecteur d'ecran.
|
|
724
|
+
*/
|
|
725
|
+
protected readonly etiquetable: boolean;
|
|
726
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<StControleDeChamp, never>;
|
|
727
|
+
static ɵdir: i0.ɵɵDirectiveDeclaration<StControleDeChamp, "[stControleDeChamp]", never, {}, {}, never, never, true, never>;
|
|
260
728
|
}
|
|
261
|
-
|
|
262
|
-
|
|
729
|
+
/**
|
|
730
|
+
* Base des champs de texte dont la LONGUEUR se compte (`st-input`, `st-textarea`, lot 217) : un
|
|
731
|
+
* comportement, ecrit une fois.
|
|
732
|
+
*
|
|
733
|
+
* - `maxLength` (du schema ou pose a la main) : compteur en complement, « N caracteres
|
|
734
|
+
* restants », puis « N caracteres en trop » au depassement.
|
|
735
|
+
* - `minLength` : « Saisissez au moins N caracteres. » en aide, si l'appelant n'en donne pas.
|
|
736
|
+
*
|
|
737
|
+
* ⚠️ **Le compteur n'est pas annonce a chaque frappe** : une region vivante qui change a chaque
|
|
738
|
+
* caractere recouvre ce que la personne tape. Il est RELIE au champ — donc lu quand on y
|
|
739
|
+
* revient — et seuls les seuils (20, 10, 0 restants) et le depassement s'annoncent (UX-11), par
|
|
740
|
+
* `annonce`, que le gabarit rend dans sa region `polite`.
|
|
741
|
+
*
|
|
742
|
+
* ⚠️ **Pas de `maxlength` natif** : un texte colle serait tronque en silence. Pendant la frappe,
|
|
743
|
+
* le compteur SEUL dit le depassement (rouge, « N en trop », annonce polie) : rien ne s'insere
|
|
744
|
+
* au-dessus du champ sous le curseur (P6). Hors formulaire, le depassement devient une erreur
|
|
745
|
+
* LOCALE (`maxLength`), affichee et posee en `aria-invalid` a la SORTIE du champ ; dans un
|
|
746
|
+
* formulaire, l'erreur du schema suit `touched`, comme avant.
|
|
747
|
+
*
|
|
748
|
+
* Le gabarit relie `compteur()` au `complement` de `st-form-field`, `aideAffichee()`, `erreurs()`
|
|
749
|
+
* et `afficherErreurs()` a l'enveloppe, et branche `surSortie()` sur la perte du focus ; l'hote
|
|
750
|
+
* pose `data-depassement` quand `enDepassement()`.
|
|
751
|
+
*/
|
|
752
|
+
declare abstract class ControleDeSaisieCompte extends ControleDeSaisie {
|
|
753
|
+
protected readonly libelles: Signal<import("@starterlib/ui").LibellesUi>;
|
|
754
|
+
protected readonly annonce: AnnonceLocale;
|
|
755
|
+
private readonly restants;
|
|
756
|
+
protected readonly enDepassement: Signal<boolean>;
|
|
757
|
+
protected readonly compteur: Signal<string | null>;
|
|
758
|
+
/**
|
|
759
|
+
* L'aide fournie (et les raisons de desactivation), sinon « Saisissez au moins N caracteres. »
|
|
760
|
+
* quand le schema le demande ; puis « Verification… » pendant une validation asynchrone.
|
|
761
|
+
*/
|
|
762
|
+
protected readonly aideAffichee: Signal<string | null>;
|
|
763
|
+
/** Les erreurs du formulaire, et le depassement local s'il n'y est pas deja. */
|
|
764
|
+
protected readonly erreurs: Signal<readonly ErreurAffichable[]>;
|
|
765
|
+
/** La personne est-elle deja sortie du champ ? Pose au `blur`, pour l'erreur LOCALE seulement. */
|
|
766
|
+
private readonly sorti;
|
|
767
|
+
/**
|
|
768
|
+
* Les erreurs se montrent a la sortie du champ, jamais pendant la frappe : `touched` dans un
|
|
769
|
+
* formulaire ; hors formulaire (personne ne pose `touched`), la sortie du champ, pour que le
|
|
770
|
+
* depassement local devienne une erreur affichee.
|
|
771
|
+
*/
|
|
772
|
+
protected readonly afficherErreurs: Signal<boolean>;
|
|
773
|
+
constructor();
|
|
774
|
+
protected surSortie(): void;
|
|
775
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<ControleDeSaisieCompte, never>;
|
|
776
|
+
static ɵdir: i0.ɵɵDirectiveDeclaration<ControleDeSaisieCompte, never, never, {}, {}, never, never, true, never>;
|
|
777
|
+
}
|
|
778
|
+
export type TypeDeSaisie = 'text' | 'email' | 'tel' | 'url' | 'search';
|
|
779
|
+
/** Presentation des chiffres de la valeur saisie. */
|
|
780
|
+
export type ChiffresDeSaisie = 'texte' | 'reference';
|
|
263
781
|
/**
|
|
264
782
|
* Champ de saisie d'une ligne, integre a Signal Forms.
|
|
265
783
|
*
|
|
@@ -267,6 +785,10 @@ type TypeDeSaisie = 'text' | 'email' | 'tel' | 'url' | 'search';
|
|
|
267
785
|
* <st-input libelle="Nom du beneficiaire" autocomplete="name" [formField]="virement.beneficiaire" />
|
|
268
786
|
* <!-- ou, sans formulaire : -->
|
|
269
787
|
* <st-input libelle="Reference" [(value)]="reference" />
|
|
788
|
+
* <!-- prefixe et suffixe DANS le cadre du champ : -->
|
|
789
|
+
* <st-input libelle="Quantite" [(value)]="quantite">
|
|
790
|
+
* <span stSuffixe>Contrats</span>
|
|
791
|
+
* </st-input>
|
|
270
792
|
* ```
|
|
271
793
|
*
|
|
272
794
|
* ⚠️ **Contrat Signal Forms, noms anglais.** `value`, `errors`, `touched`,
|
|
@@ -277,49 +799,184 @@ type TypeDeSaisie = 'text' | 'email' | 'tel' | 'url' | 'search';
|
|
|
277
799
|
*
|
|
278
800
|
* ⚠️ **Pas d'attribut `maxlength` natif.** Il TRONQUE en silence un texte colle
|
|
279
801
|
* trop long : la personne croit avoir saisi sa reference entiere, et n'en envoie
|
|
280
|
-
* que le debut. La limite passe par la validation, qui DIT le depassement
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
802
|
+
* que le debut. La limite passe par la validation, qui DIT le depassement : `maxLength`
|
|
803
|
+
* (du schema ou pose a la main) donne un compteur en complement, `minLength` une aide
|
|
804
|
+
* automatique, comme `st-textarea` (`ControleDeSaisieCompte`, lot 217).
|
|
805
|
+
*
|
|
806
|
+
* ⚠️ **Prefixe et suffixe PROJETES, jamais recomposes a cote** (`[stPrefixe]`,
|
|
807
|
+
* `[stSuffixe]`, ou `icone` pour un glyphe de tete). Le cadre porte alors le filet, le fond,
|
|
808
|
+
* l'anneau et l'erreur : un seul cadre (EA-11), la meme hauteur. Un emplacement n'entre PAS
|
|
809
|
+
* dans le NOM du champ, mais un emplacement de texte entre dans sa DESCRIPTION (lue au focus,
|
|
810
|
+
* apres l'aide et la meta) : l'unite « Contrats (= 303 625.00 CHF) » n'est jamais perdue.
|
|
811
|
+
* Un clic dans le cadre, hors d'un element interactif, donne le focus a la zone de frappe.
|
|
812
|
+
* Trop long pour la largeur, un emplacement de texte se coupe (points de suspension) : la zone
|
|
813
|
+
* de frappe garde toujours au moins huit chiffres visibles (WCAG 1.4.10). Un emplacement
|
|
814
|
+
* interactif se projette directement (`<button stSuffixe stIconButton …>`), jamais dans un
|
|
815
|
+
* `span` : il serait coupe avec lui.
|
|
816
|
+
*/
|
|
817
|
+
export declare class StInput extends ControleDeSaisieCompte {
|
|
818
|
+
private readonly racineDuCadre;
|
|
819
|
+
/** Identifiants des emplacements, references en description quand ils portent du texte. */
|
|
820
|
+
protected readonly idPrefixe: string;
|
|
821
|
+
protected readonly idSuffixe: string;
|
|
822
|
+
private readonly zoneDePrefixe;
|
|
823
|
+
private readonly zoneDeSuffixe;
|
|
824
|
+
/** Emplacements qui decrivent le champ, releves au rendu (le contenu projete peut changer). */
|
|
825
|
+
protected readonly emplacementsQuiDecrivent: import("@angular/core").WritableSignal<readonly string[]>;
|
|
826
|
+
readonly type: import("@angular/core").InputSignal<TypeDeSaisie>;
|
|
827
|
+
/**
|
|
828
|
+
* WCAG 1.3.5 : identifie le but du champ, pour le remplissage automatique et les
|
|
829
|
+
* aides techniques. `null` : laisse le navigateur decider.
|
|
830
|
+
*/
|
|
831
|
+
readonly autocomplete: import("@angular/core").InputSignal<TypeDAutocompletion | null>;
|
|
832
|
+
/** Clavier virtuel adapte : `numeric`, `decimal`, `email`… */
|
|
833
|
+
readonly inputmode: import("@angular/core").InputSignal<ModeDeSaisie | null>;
|
|
834
|
+
/** Glyphe decoratif de tete, dans le cadre (l'etiquette porte le sens). */
|
|
835
|
+
readonly icone: import("@angular/core").InputSignal<"iban" | "code" | "devise" | "fichier" | "message" | "menu" | "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-qr" | "code-qr-scanner" | "coffre-fort" | "colonnes" | "connexion" | "contraste" | "copie" | "corbeille" | "corbeille-croix" | "courriel" | "crayon" | "croix" | "curseur-clic" | "deconnexion" | "disposition" | "dollar" | "dossier" | "dossier-barre" | "dossier-ouvert" | "double-coche" | "echange" | "eclair" | "empreinte-digitale" | "enregistrer" | "entree" | "envoyer" | "epaisseur-de-trait" | "epingle" | "etoile" | "euro" | "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" | "imprimer" | "interdit" | "jalons" | "jauge" | "lien" | "lien-externe" | "lignes" | "lignes-crayon" | "liste" | "liste-coche" | "liste-controle" | "liste-numerotee" | "luminosite" | "lune" | "maillet" | "maison" | "marque-page" | "menu-ouvert" | "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>;
|
|
836
|
+
/**
|
|
837
|
+
* `reference` : IBAN, BIC, reference structuree — chasse fixe, chiffres a zero barre
|
|
838
|
+
* (`--st-chiffres-references`), pour qu'un 0 ne se lise pas O ; de gauche a droite en RTL.
|
|
839
|
+
*/
|
|
840
|
+
readonly chiffres: import("@angular/core").InputSignal<ChiffresDeSaisie>;
|
|
841
|
+
/** Le style de l'etiquette (voir `st-form-field`). */
|
|
842
|
+
readonly presentation: import("@angular/core").InputSignal<PresentationDeLibelle>;
|
|
843
|
+
/**
|
|
844
|
+
* Identifiants d'autres textes qui decrivent le champ (`aria-describedby`), lus entre l'aide et
|
|
845
|
+
* l'erreur : les essais restants de `st-challenge` (audit UI du 2026-09-27, D-20). Des elements
|
|
846
|
+
* PRESENTS seulement : un identifiant absent fait ignorer toute la description par certains
|
|
847
|
+
* lecteurs d'ecran.
|
|
848
|
+
*/
|
|
849
|
+
readonly decritPar: import("@angular/core").InputSignal<readonly string[]>;
|
|
850
|
+
/** Ce qui decrit le controle : les textes de l'appelant, puis les emplacements de texte. */
|
|
851
|
+
protected readonly descriptionsDuControle: import("@angular/core").Signal<readonly string[]>;
|
|
852
|
+
/**
|
|
853
|
+
* Des valeurs a PROPOSER, jamais a imposer : une liste `datalist` native, que le navigateur offre
|
|
854
|
+
* sous le champ et filtre a la frappe ; toute autre saisie reste admise (la ville d'une adresse,
|
|
855
|
+
* D133). `null` ou vide : aucune. Une liste FERMEE est un `st-select` ; une longue liste a filtrer
|
|
856
|
+
* dans une liste du socle, un `st-combobox`.
|
|
857
|
+
*/
|
|
858
|
+
readonly suggestions: import("@angular/core").InputSignal<readonly string[] | null>;
|
|
859
|
+
protected readonly idDesSuggestions: string;
|
|
860
|
+
protected readonly avecSuggestions: import("@angular/core").Signal<boolean>;
|
|
861
|
+
/**
|
|
862
|
+
* L'indicateur d'attente n'apparait qu'apres `rythme.delai.attente` et reste au moins
|
|
863
|
+
* `rythme.tenue.affichageMinimal` : une verification de 150 ms ne fait rien clignoter.
|
|
864
|
+
*/
|
|
865
|
+
protected readonly attenteVisible: import("@angular/core").Signal<boolean>;
|
|
866
|
+
/**
|
|
867
|
+
* Un courriel, un telephone, une adresse web, une reference structuree (IBAN, BIC) restent de
|
|
868
|
+
* gauche a droite en RTL : latins par nature, ils s'y alignaient a droite et un IBAN trop long
|
|
869
|
+
* pour la largeur y perdait son debut (« H93 0076… » au lieu de « CH93 0076… », instantanes du
|
|
870
|
+
* lot 217).
|
|
871
|
+
*/
|
|
872
|
+
protected readonly sens: import("@angular/core").Signal<"ltr" | null>;
|
|
873
|
+
constructor();
|
|
874
|
+
/**
|
|
875
|
+
* Le cadre est UN champ : un clic sur le prefixe, l'icone, le suffixe texte ou la marge donne
|
|
876
|
+
* le focus a la zone de frappe (le survol du cadre l'a promis). Un bouton projete garde le sien.
|
|
877
|
+
*/
|
|
878
|
+
protected surPressionDuCadre(evenement: MouseEvent): void;
|
|
879
|
+
protected surSaisie(evenement: Event): void;
|
|
880
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<StInput, never>;
|
|
881
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<StInput, "st-input", never, {
|
|
882
|
+
"type": {
|
|
883
|
+
"alias": "type";
|
|
884
|
+
"required": false;
|
|
885
|
+
"isSignal": true;
|
|
886
|
+
};
|
|
887
|
+
"autocomplete": {
|
|
888
|
+
"alias": "autocomplete";
|
|
889
|
+
"required": false;
|
|
890
|
+
"isSignal": true;
|
|
891
|
+
};
|
|
892
|
+
"inputmode": {
|
|
893
|
+
"alias": "inputmode";
|
|
894
|
+
"required": false;
|
|
895
|
+
"isSignal": true;
|
|
896
|
+
};
|
|
897
|
+
"icone": {
|
|
898
|
+
"alias": "icone";
|
|
899
|
+
"required": false;
|
|
900
|
+
"isSignal": true;
|
|
901
|
+
};
|
|
902
|
+
"chiffres": {
|
|
903
|
+
"alias": "chiffres";
|
|
904
|
+
"required": false;
|
|
905
|
+
"isSignal": true;
|
|
906
|
+
};
|
|
907
|
+
"presentation": {
|
|
908
|
+
"alias": "presentation";
|
|
909
|
+
"required": false;
|
|
910
|
+
"isSignal": true;
|
|
911
|
+
};
|
|
912
|
+
"decritPar": {
|
|
913
|
+
"alias": "decritPar";
|
|
914
|
+
"required": false;
|
|
915
|
+
"isSignal": true;
|
|
916
|
+
};
|
|
917
|
+
"suggestions": {
|
|
918
|
+
"alias": "suggestions";
|
|
919
|
+
"required": false;
|
|
920
|
+
"isSignal": true;
|
|
921
|
+
};
|
|
922
|
+
}, {}, never, ["[stMeta]", "[stAide]", "[stIndication]", "[stPrefixe]", "[stSuffixe]"], true, never>;
|
|
294
923
|
}
|
|
295
|
-
|
|
296
924
|
/**
|
|
297
925
|
* Zone de texte, integree a Signal Forms, avec compteur quand une longueur
|
|
298
|
-
* maximale est fixee
|
|
299
|
-
*
|
|
300
|
-
*
|
|
301
|
-
*
|
|
302
|
-
*
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
926
|
+
* maximale est fixee : le compteur, ses annonces aux seuils, le depassement local et l'aide de
|
|
927
|
+
* longueur minimale sont ceux de `ControleDeSaisieCompte`, partages avec `st-input`.
|
|
928
|
+
*
|
|
929
|
+
* La zone suit son texte (`field-sizing: content`), bornee entre `lignes` et `lignesMax` :
|
|
930
|
+
* jamais une fente d'une ligne, jamais une page entiere ; la poignee respecte les memes bornes.
|
|
931
|
+
*/
|
|
932
|
+
export declare class StTextarea extends ControleDeSaisieCompte {
|
|
933
|
+
/** Hauteur de depart, et hauteur minimale, en lignes. */
|
|
934
|
+
readonly lignes: import("@angular/core").InputSignalWithTransform<number, unknown>;
|
|
935
|
+
/** Hauteur maximale en lignes : au-dela, la zone defile. */
|
|
936
|
+
readonly lignesMax: import("@angular/core").InputSignalWithTransform<number, unknown>;
|
|
937
|
+
/** Bornes effectives : `lignesMax` ne descend jamais sous `lignes`. */
|
|
938
|
+
protected readonly bornes: import("@angular/core").Signal<{
|
|
939
|
+
lignes: number;
|
|
940
|
+
lignesMax: number;
|
|
941
|
+
}>;
|
|
942
|
+
protected surSaisie(evenement: Event): void;
|
|
943
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<StTextarea, never>;
|
|
944
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<StTextarea, "st-textarea", never, {
|
|
945
|
+
"lignes": {
|
|
946
|
+
"alias": "lignes";
|
|
947
|
+
"required": false;
|
|
948
|
+
"isSignal": true;
|
|
949
|
+
};
|
|
950
|
+
"lignesMax": {
|
|
951
|
+
"alias": "lignesMax";
|
|
952
|
+
"required": false;
|
|
953
|
+
"isSignal": true;
|
|
954
|
+
};
|
|
955
|
+
}, {}, never, never, true, never>;
|
|
321
956
|
}
|
|
322
|
-
|
|
957
|
+
/**
|
|
958
|
+
* Ce qu'un groupe (`st-fieldset`) dit a ses controles.
|
|
959
|
+
*
|
|
960
|
+
* ⚠️ `fieldset[disabled]` natif ne desactive que les elements de formulaire NATIFS. Un controle
|
|
961
|
+
* non natif (le declencheur `div role=combobox` d'une selection multiple) resterait focalisable,
|
|
962
|
+
* annonce actif et ouvrable dans un groupe gele : il lit donc ce jeton, par `ContratDeChamp`.
|
|
963
|
+
*/
|
|
964
|
+
interface GroupeDeSaisie {
|
|
965
|
+
/** Vrai quand le groupe entier est desactive. */
|
|
966
|
+
readonly disabled: Signal<boolean>;
|
|
967
|
+
}
|
|
968
|
+
declare const ST_GROUPE_DE_SAISIE: InjectionToken<GroupeDeSaisie>;
|
|
969
|
+
/**
|
|
970
|
+
* `champs` : des champs empiles a 20 px (nom et IBAN d'un beneficiaire).
|
|
971
|
+
* `choix` : des cases ou des radios a 12 px (un groupe d'options, `st-radio-group`).
|
|
972
|
+
*/
|
|
973
|
+
export type ContenuDeGroupe = 'champs' | 'choix';
|
|
974
|
+
/**
|
|
975
|
+
* `colonne` : les controles l'un sous l'autre.
|
|
976
|
+
* `en-ligne` : cote a cote, pour deux champs courts (une plage de dates) ; en colonne sous la
|
|
977
|
+
* rupture `sm` de la largeur du groupe.
|
|
978
|
+
*/
|
|
979
|
+
export type DispositionDeGroupe = 'colonne' | 'en-ligne';
|
|
323
980
|
/**
|
|
324
981
|
* Groupe de controles, nomme par sa QUESTION.
|
|
325
982
|
*
|
|
@@ -327,34 +984,105 @@ declare class StTextarea extends ControleDeSaisie {
|
|
|
327
984
|
* annonce « Oui, bouton radio » et « Non, bouton radio » : la reponse, jamais la
|
|
328
985
|
* question. La legende est lue a l'entree dans le groupe.
|
|
329
986
|
*
|
|
330
|
-
* C'est le pendant de `st-form-field` pour un GROUPE
|
|
331
|
-
* reliees au `fieldset` par `aria-describedby`,
|
|
332
|
-
* entier — « Choisissez un mode de reglement » — et non sur chaque option
|
|
987
|
+
* C'est le pendant de `st-form-field` pour un GROUPE, sur la meme base (`PorteurDErreurs`) :
|
|
988
|
+
* l'aide et l'erreur sont reliees au `fieldset` par `aria-describedby`, l'erreur porte sur le
|
|
989
|
+
* groupe entier — « Choisissez un mode de reglement » — et non sur chaque option, et son lisere
|
|
990
|
+
* est a la place de celui du champ : dans la gouttiere, sur la hauteur des controles.
|
|
333
991
|
*
|
|
334
992
|
* ⚠️ L'obligation se dit dans la legende, en texte : `aria-required` n'est pas
|
|
335
993
|
* valide sur un groupe, et `required` natif ferait parler le navigateur dans sa
|
|
336
|
-
* propre langue.
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
994
|
+
* propre langue. Un groupe a choix EXCLUSIF (`choixExclusif`, pose par `st-radio-group`) est un
|
|
995
|
+
* `radiogroup` : lui porte aussi `aria-required`, `aria-invalid` et `aria-readonly`.
|
|
996
|
+
*
|
|
997
|
+
* ⚠️ `disabled` pose le `fieldset[disabled]` NATIF, qui desactive d'un coup les controles natifs
|
|
998
|
+
* du groupe, et le fournit aux controles du socle (`ST_GROUPE_DE_SAISIE`) : un controle non natif
|
|
999
|
+
* (declencheur `div role=combobox`) doit lire `desactive()` de `ContratDeChamp` pour s'y plier
|
|
1000
|
+
* (adoption par st-combobox et st-multiselect : lot 227). C'est un gel d'INTERFACE : la validation
|
|
1001
|
+
* continue, le schema seul retire un champ (`disabled()`). La raison se dit en aide.
|
|
1002
|
+
*
|
|
1003
|
+
* ⚠️ Toutes les erreurs du groupe sont montrees par defaut (`toutesLesErreurs` vrai) : elles visent
|
|
1004
|
+
* des parties distinctes, et chacune doit dire pourquoi sa partie est invalide.
|
|
1005
|
+
*/
|
|
1006
|
+
export declare class StFieldset extends PorteurDErreurs implements GroupeDeSaisie {
|
|
1007
|
+
/** La question posee par le groupe. Obligatoire. */
|
|
1008
|
+
readonly legende: import("@angular/core").InputSignal<string>;
|
|
1009
|
+
/** L'ecart entre les controles : 20 px entre des champs, 12 entre des cases ou des radios. */
|
|
1010
|
+
readonly contenu: import("@angular/core").InputSignal<ContenuDeGroupe>;
|
|
1011
|
+
readonly disposition: import("@angular/core").InputSignal<DispositionDeGroupe>;
|
|
1012
|
+
/** Toutes les erreurs du groupe, par defaut : chacune vise une partie distincte. */
|
|
1013
|
+
readonly toutesLesErreurs: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
|
|
1014
|
+
/**
|
|
1015
|
+
* Des radios : le `fieldset` devient un `radiogroup`, qui porte l'obligation, l'erreur et la
|
|
1016
|
+
* lecture seule du groupe (ARIA ne les prevoit ni sur `group` ni sur `radio`).
|
|
1017
|
+
*/
|
|
1018
|
+
readonly choixExclusif: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
|
|
1019
|
+
/** Lecture seule du groupe, annoncee par `aria-readonly` (groupe a `choixExclusif` seulement). */
|
|
1020
|
+
readonly readonly: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
|
|
1021
|
+
/** Desactive tous les controles du groupe (`fieldset[disabled]` natif, et jeton de groupe). */
|
|
1022
|
+
readonly disabled: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
|
|
1023
|
+
/** Masque le groupe entier. */
|
|
1024
|
+
readonly hidden: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
|
|
1025
|
+
/**
|
|
1026
|
+
* Identifiants d'autres textes qui decrivent le groupe (`aria-describedby`), lus entre l'aide et
|
|
1027
|
+
* l'erreur : le recapitulatif de `st-recurrence-field` (lot 255), relie sans etre annonce.
|
|
1028
|
+
*/
|
|
1029
|
+
readonly decritPar: import("@angular/core").InputSignal<readonly string[]>;
|
|
1030
|
+
/** Identifiants de l'aide et de l'erreur, cites par `aria-describedby`. */
|
|
1031
|
+
readonly identifiants: {
|
|
1032
|
+
readonly aide: `${string}-aide`;
|
|
1033
|
+
readonly erreur: `${string}-erreur`;
|
|
1034
|
+
};
|
|
1035
|
+
protected prefixeDIdentifiant(): string;
|
|
1036
|
+
protected descriptionsPropres(): readonly string[];
|
|
1037
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<StFieldset, never>;
|
|
1038
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<StFieldset, "st-fieldset", never, {
|
|
1039
|
+
"legende": {
|
|
1040
|
+
"alias": "legende";
|
|
1041
|
+
"required": true;
|
|
1042
|
+
"isSignal": true;
|
|
1043
|
+
};
|
|
1044
|
+
"contenu": {
|
|
1045
|
+
"alias": "contenu";
|
|
1046
|
+
"required": false;
|
|
1047
|
+
"isSignal": true;
|
|
1048
|
+
};
|
|
1049
|
+
"disposition": {
|
|
1050
|
+
"alias": "disposition";
|
|
1051
|
+
"required": false;
|
|
1052
|
+
"isSignal": true;
|
|
1053
|
+
};
|
|
1054
|
+
"toutesLesErreurs": {
|
|
1055
|
+
"alias": "toutesLesErreurs";
|
|
1056
|
+
"required": false;
|
|
1057
|
+
"isSignal": true;
|
|
1058
|
+
};
|
|
1059
|
+
"choixExclusif": {
|
|
1060
|
+
"alias": "choixExclusif";
|
|
1061
|
+
"required": false;
|
|
1062
|
+
"isSignal": true;
|
|
1063
|
+
};
|
|
1064
|
+
"readonly": {
|
|
1065
|
+
"alias": "readonly";
|
|
1066
|
+
"required": false;
|
|
1067
|
+
"isSignal": true;
|
|
1068
|
+
};
|
|
1069
|
+
"disabled": {
|
|
1070
|
+
"alias": "disabled";
|
|
1071
|
+
"required": false;
|
|
1072
|
+
"isSignal": true;
|
|
1073
|
+
};
|
|
1074
|
+
"hidden": {
|
|
1075
|
+
"alias": "hidden";
|
|
1076
|
+
"required": false;
|
|
1077
|
+
"isSignal": true;
|
|
1078
|
+
};
|
|
1079
|
+
"decritPar": {
|
|
1080
|
+
"alias": "decritPar";
|
|
1081
|
+
"required": false;
|
|
1082
|
+
"isSignal": true;
|
|
1083
|
+
};
|
|
1084
|
+
}, {}, never, ["*"], true, never>;
|
|
356
1085
|
}
|
|
357
|
-
|
|
358
1086
|
/**
|
|
359
1087
|
* Case a cocher, integree a Signal Forms.
|
|
360
1088
|
*
|
|
@@ -362,39 +1090,71 @@ declare class StFieldset {
|
|
|
362
1090
|
* <st-checkbox libelle="J'accepte les conditions generales" [formField]="inscription.conditions" />
|
|
363
1091
|
* ```
|
|
364
1092
|
*
|
|
365
|
-
* Un element `input type="checkbox"` natif
|
|
366
|
-
* et la case
|
|
1093
|
+
* Un element `input type="checkbox"` natif, dessine par le socle (planches 3a, 3b) : Espace coche,
|
|
1094
|
+
* l'etat est annonce, et la case est la meme sous Windows, macOS et Android. La ligne entiere (case,
|
|
1095
|
+
* etiquette, aide) fait 44 px au moins ; cochee, elle se teinte ; en erreur, elle rougit, la case
|
|
1096
|
+
* double son filet et le message s'ecrit sous l'etiquette.
|
|
367
1097
|
*
|
|
368
1098
|
* ⚠️ **Pour un choix a envoyer avec un formulaire.** Un reglage qui s'applique
|
|
369
1099
|
* IMMEDIATEMENT est un `st-switch` : la case promet un effet a l'envoi, et
|
|
370
1100
|
* l'interrupteur un effet tout de suite (UX-8).
|
|
1101
|
+
*
|
|
1102
|
+
* `indetermine` (« tout selectionner » d'une liste partiellement choisie) pose l'etat natif
|
|
1103
|
+
* `indeterminate`, que le lecteur d'ecran annonce « partiellement coche » (`mixed`) ; un clic le
|
|
1104
|
+
* leve et coche la case, comme le fait le navigateur.
|
|
1105
|
+
*
|
|
1106
|
+
* `readonly` (regle `readonly()` du schema) : la case reste focalisable et lue, mais ni le clic ni
|
|
1107
|
+
* Espace ne la basculent (`ContratDeCase`).
|
|
1108
|
+
*
|
|
1109
|
+
* Libelle riche (lot 218) : un element `[stLibelle]` projete remplace le texte de l'etiquette, pour
|
|
1110
|
+
* un lien dans la phrase. L'etiquette reste le `label` de la case, et le lien son nom accessible ;
|
|
1111
|
+
* un clic sur le lien suit le lien sans cocher (un contenu interactif dans un `label` ne l'active
|
|
1112
|
+
* pas). `libelle` reste obligatoire et dit la meme chose en texte : c'est lui que cite le
|
|
1113
|
+
* recapitulatif d'erreurs.
|
|
1114
|
+
*
|
|
1115
|
+
* ```html
|
|
1116
|
+
* <st-checkbox libelle="J'accepte les conditions generales" [formField]="inscription.conditions">
|
|
1117
|
+
* <span stLibelle>J'accepte les <a stLink href="/cgu">conditions generales</a></span>
|
|
1118
|
+
* </st-checkbox>
|
|
1119
|
+
* ```
|
|
371
1120
|
*/
|
|
372
|
-
declare class StCheckbox
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
1121
|
+
export declare class StCheckbox extends ContratDeCase {
|
|
1122
|
+
/**
|
|
1123
|
+
* Etat intermediaire (« 3 sur 7 »). Un modele : la bascule par la personne le leve, et
|
|
1124
|
+
* l'application le lit (`[(indetermine)]`) pour savoir que le choix est devenu franc.
|
|
1125
|
+
*/
|
|
1126
|
+
readonly indetermine: import("@angular/core").ModelSignal<boolean>;
|
|
1127
|
+
/**
|
|
1128
|
+
* L'aide dit l'etat OBTENU (« Recommande · Actif », planche 3a) : une fois la case cochee, elle
|
|
1129
|
+
* passe au vert de succes, en 500. A choisir explicitement : une aide ordinaire (« Un courriel
|
|
1130
|
+
* vous sera envoye. ») ne prend pas la couleur du succes parce qu'on a coche.
|
|
1131
|
+
*/
|
|
1132
|
+
readonly aideDEtat: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
|
|
1133
|
+
/** L'erreur se montre-t-elle ? La meme regle que le champ : apres la sortie du controle. */
|
|
1134
|
+
protected readonly enErreur: import("@angular/core").Signal<boolean>;
|
|
1135
|
+
protected surChangement(evenement: Event): void;
|
|
1136
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<StCheckbox, never>;
|
|
1137
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<StCheckbox, "st-checkbox", never, {
|
|
1138
|
+
"indetermine": {
|
|
1139
|
+
"alias": "indetermine";
|
|
1140
|
+
"required": false;
|
|
1141
|
+
"isSignal": true;
|
|
1142
|
+
};
|
|
1143
|
+
"aideDEtat": {
|
|
1144
|
+
"alias": "aideDEtat";
|
|
1145
|
+
"required": false;
|
|
1146
|
+
"isSignal": true;
|
|
1147
|
+
};
|
|
1148
|
+
}, {
|
|
1149
|
+
"indetermine": "indetermineChange";
|
|
1150
|
+
}, never, ["[stLibelle]"], true, never>;
|
|
389
1151
|
}
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
readonly aide?: string;
|
|
397
|
-
readonly desactivee?: boolean;
|
|
1152
|
+
/**
|
|
1153
|
+
* Une option du groupe : la forme d'option de toutes les listes (`OptionDeListe`), avec la RAISON
|
|
1154
|
+
* d'une option desactivee, lue en aide (« Indisponible pour ce compte. ») plutot que tue.
|
|
1155
|
+
*/
|
|
1156
|
+
export interface OptionRadio extends OptionDeListe {
|
|
1157
|
+
readonly raison?: string;
|
|
398
1158
|
}
|
|
399
1159
|
/**
|
|
400
1160
|
* Groupe de boutons radio, integre a Signal Forms.
|
|
@@ -407,44 +1167,1209 @@ interface OptionRadio {
|
|
|
407
1167
|
* groupe, deplacement aux fleches, « 2 sur 3 » annonce. Les recrire en ARIA,
|
|
408
1168
|
* c'est cent lignes pour obtenir moins bien — meme raison que `st-theme-toggle`.
|
|
409
1169
|
*
|
|
410
|
-
* ⚠️ **
|
|
411
|
-
*
|
|
1170
|
+
* ⚠️ **Le message d'erreur porte sur le groupe**, par `st-fieldset` : « Choisissez un mode de
|
|
1171
|
+
* reglement », une fois. L'ETAT d'erreur, lui, est pose sur chaque radio (`aria-invalid`) : le
|
|
1172
|
+
* lecteur d'ecran le dit sur l'option ou se trouve le focus (WCAG 4.1.2), pas seulement a
|
|
1173
|
+
* l'entree du groupe. Le `fieldset` est un `radiogroup` (`choixExclusif`) : c'est lui qui porte
|
|
1174
|
+
* `aria-required`, `aria-invalid` et `aria-readonly`, qu'ARIA ne prevoit pas sur un radio.
|
|
1175
|
+
*
|
|
1176
|
+
* Chaque option est une ligne de 44 px au moins (planches 3a, 3b) : radio de 24, libelle et aide ;
|
|
1177
|
+
* l'option choisie se teinte.
|
|
412
1178
|
*
|
|
413
1179
|
* `touch` n'est emis que lorsque le focus QUITTE le groupe : passer d'une option a
|
|
414
1180
|
* l'autre aux fleches n'est pas une fin de saisie, et l'erreur n'a pas a surgir
|
|
415
1181
|
* pendant qu'on choisit.
|
|
1182
|
+
*
|
|
1183
|
+
* `readonly` : les options restent focalisables et lues, mais le choix ne change pas (un clic ou
|
|
1184
|
+
* une fleche est annule, l'option du modele reste cochee) ; le groupe l'annonce
|
|
1185
|
+
* (`aria-readonly` du `radiogroup`) et le curseur reste celui par defaut.
|
|
1186
|
+
*/
|
|
1187
|
+
export declare class StRadioGroup implements FormValueControl<string> {
|
|
1188
|
+
private readonly element;
|
|
1189
|
+
readonly legende: import("@angular/core").InputSignal<string>;
|
|
1190
|
+
readonly aide: import("@angular/core").InputSignal<string | null>;
|
|
1191
|
+
readonly options: import("@angular/core").InputSignal<readonly OptionRadio[]>;
|
|
1192
|
+
/** `en-ligne` : options cote a cote (deux ou trois choix courts), en colonne quand la place manque. */
|
|
1193
|
+
readonly disposition: import("@angular/core").InputSignal<DispositionDeGroupe>;
|
|
1194
|
+
/** Contrat Signal Forms. */
|
|
1195
|
+
readonly value: import("@angular/core").ModelSignal<string>;
|
|
1196
|
+
readonly errors: import("@angular/core").InputSignal<readonly ValidationError.WithOptionalFieldTree[]>;
|
|
1197
|
+
readonly touched: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
|
|
1198
|
+
readonly dirty: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
|
|
1199
|
+
readonly pending: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
|
|
1200
|
+
readonly disabled: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
|
|
1201
|
+
readonly disabledReasons: import("@angular/core").InputSignal<readonly WithOptionalFieldTree<DisabledReason>[]>;
|
|
1202
|
+
readonly readonly: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
|
|
1203
|
+
readonly required: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
|
|
1204
|
+
readonly hidden: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
|
|
1205
|
+
readonly name: import("@angular/core").InputSignal<string>;
|
|
1206
|
+
readonly touch: import("@angular/core").OutputEmitterRef<void>;
|
|
1207
|
+
private readonly radios;
|
|
1208
|
+
/** Nom partage par les options : sans lui, chaque radio forme son propre groupe. */
|
|
1209
|
+
private readonly nomParDefaut;
|
|
1210
|
+
/** L'erreur se montre apres la sortie du groupe, comme son message. */
|
|
1211
|
+
protected readonly enErreur: import("@angular/core").Signal<boolean>;
|
|
1212
|
+
/** L'aide du groupe, suivie des raisons de sa desactivation. */
|
|
1213
|
+
protected readonly aideEtRaisons: import("@angular/core").Signal<string | null>;
|
|
1214
|
+
protected nomDuGroupe(): string;
|
|
1215
|
+
protected identifiantOption(indice: number): string;
|
|
1216
|
+
protected identifiantAide(indice: number): string;
|
|
1217
|
+
/** L'aide d'une option : la sienne, et la raison de sa desactivation. */
|
|
1218
|
+
protected aideDe(option: OptionRadio): string | null;
|
|
1219
|
+
/**
|
|
1220
|
+
* Focus sur l'option du MODELE, sinon la premiere active : c'est l'arret de tabulation du groupe.
|
|
1221
|
+
* Lu sur l'etat (valeur et options), et non sur le DOM coche.
|
|
1222
|
+
*/
|
|
1223
|
+
focus(options?: FocusOptions): void;
|
|
1224
|
+
protected choisir(evenement: Event, valeur: string): void;
|
|
1225
|
+
/** En lecture seule, le clic est annule avant que l'option ne change. */
|
|
1226
|
+
protected surClic(evenement: MouseEvent): void;
|
|
1227
|
+
protected aLaSortie(evenement: FocusEvent): void;
|
|
1228
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<StRadioGroup, never>;
|
|
1229
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<StRadioGroup, "st-radio-group", never, {
|
|
1230
|
+
"legende": {
|
|
1231
|
+
"alias": "legende";
|
|
1232
|
+
"required": true;
|
|
1233
|
+
"isSignal": true;
|
|
1234
|
+
};
|
|
1235
|
+
"aide": {
|
|
1236
|
+
"alias": "aide";
|
|
1237
|
+
"required": false;
|
|
1238
|
+
"isSignal": true;
|
|
1239
|
+
};
|
|
1240
|
+
"options": {
|
|
1241
|
+
"alias": "options";
|
|
1242
|
+
"required": true;
|
|
1243
|
+
"isSignal": true;
|
|
1244
|
+
};
|
|
1245
|
+
"disposition": {
|
|
1246
|
+
"alias": "disposition";
|
|
1247
|
+
"required": false;
|
|
1248
|
+
"isSignal": true;
|
|
1249
|
+
};
|
|
1250
|
+
"value": {
|
|
1251
|
+
"alias": "value";
|
|
1252
|
+
"required": false;
|
|
1253
|
+
"isSignal": true;
|
|
1254
|
+
};
|
|
1255
|
+
"errors": {
|
|
1256
|
+
"alias": "errors";
|
|
1257
|
+
"required": false;
|
|
1258
|
+
"isSignal": true;
|
|
1259
|
+
};
|
|
1260
|
+
"touched": {
|
|
1261
|
+
"alias": "touched";
|
|
1262
|
+
"required": false;
|
|
1263
|
+
"isSignal": true;
|
|
1264
|
+
};
|
|
1265
|
+
"dirty": {
|
|
1266
|
+
"alias": "dirty";
|
|
1267
|
+
"required": false;
|
|
1268
|
+
"isSignal": true;
|
|
1269
|
+
};
|
|
1270
|
+
"pending": {
|
|
1271
|
+
"alias": "pending";
|
|
1272
|
+
"required": false;
|
|
1273
|
+
"isSignal": true;
|
|
1274
|
+
};
|
|
1275
|
+
"disabled": {
|
|
1276
|
+
"alias": "disabled";
|
|
1277
|
+
"required": false;
|
|
1278
|
+
"isSignal": true;
|
|
1279
|
+
};
|
|
1280
|
+
"disabledReasons": {
|
|
1281
|
+
"alias": "disabledReasons";
|
|
1282
|
+
"required": false;
|
|
1283
|
+
"isSignal": true;
|
|
1284
|
+
};
|
|
1285
|
+
"readonly": {
|
|
1286
|
+
"alias": "readonly";
|
|
1287
|
+
"required": false;
|
|
1288
|
+
"isSignal": true;
|
|
1289
|
+
};
|
|
1290
|
+
"required": {
|
|
1291
|
+
"alias": "required";
|
|
1292
|
+
"required": false;
|
|
1293
|
+
"isSignal": true;
|
|
1294
|
+
};
|
|
1295
|
+
"hidden": {
|
|
1296
|
+
"alias": "hidden";
|
|
1297
|
+
"required": false;
|
|
1298
|
+
"isSignal": true;
|
|
1299
|
+
};
|
|
1300
|
+
"name": {
|
|
1301
|
+
"alias": "name";
|
|
1302
|
+
"required": false;
|
|
1303
|
+
"isSignal": true;
|
|
1304
|
+
};
|
|
1305
|
+
}, {
|
|
1306
|
+
"value": "valueChange";
|
|
1307
|
+
"touch": "touch";
|
|
1308
|
+
}, never, never, true, never>;
|
|
1309
|
+
}
|
|
1310
|
+
/**
|
|
1311
|
+
* Une option du groupe : la forme d'option de toutes les listes (`OptionDeListe`), avec la RAISON
|
|
1312
|
+
* d'une option desactivee, lue en aide (« Obligatoire pour les virements. ») plutot que tue. La meme
|
|
1313
|
+
* forme que `OptionRadio`.
|
|
416
1314
|
*/
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
1315
|
+
export interface OptionDeChoix extends OptionDeListe {
|
|
1316
|
+
readonly raison?: string;
|
|
1317
|
+
}
|
|
1318
|
+
/** Ce que montre la case « Tout selectionner » : rien, une partie, ou toutes les options libres. */
|
|
1319
|
+
type EtatDuTout$1 = 'vide' | 'partiel' | 'coche';
|
|
1320
|
+
/**
|
|
1321
|
+
* Groupe de cases a cocher, integre a Signal Forms : la valeur est la LISTE des options cochees.
|
|
1322
|
+
*
|
|
1323
|
+
* ```html
|
|
1324
|
+
* <st-checkbox-group
|
|
1325
|
+
* legende="Canaux de notification"
|
|
1326
|
+
* toutSelectionner
|
|
1327
|
+
* [options]="canaux"
|
|
1328
|
+
* [formField]="preferences.canaux"
|
|
1329
|
+
* />
|
|
1330
|
+
* ```
|
|
1331
|
+
*
|
|
1332
|
+
* Le pendant multiple de `st-radio-group`, sur le meme `st-fieldset` : la legende pose la
|
|
1333
|
+
* question, chaque option est une case native de 24 px sur une ligne de 44 px au moins (la hauteur
|
|
1334
|
+
* de commande), avec son aide et la raison de sa desactivation.
|
|
1335
|
+
*
|
|
1336
|
+
* ⚠️ **Les bornes viennent du schema** : `minLength(chemin.canaux, 1)` et `maxLength(chemin.canaux,
|
|
1337
|
+
* 3)` de Signal Forms comptent les options cochees ; leur message parle d'options, pas de
|
|
1338
|
+
* caracteres (`messageDErreur` lit la valeur visee). Le groupe n'ajoute aucune entree de borne.
|
|
1339
|
+
*
|
|
1340
|
+
* ⚠️ **Le message d'erreur porte sur le groupe**, par `st-fieldset` : « Choisissez au moins
|
|
1341
|
+
* 1 option. », une fois. L'ETAT d'erreur, lui, est pose sur chaque case (`aria-invalid`), comme
|
|
1342
|
+
* sur chaque radio : le lecteur d'ecran le dit sur la case ou se trouve le focus (WCAG 4.1.2).
|
|
1343
|
+
* L'obligation se dit dans la legende, en texte : `aria-required` sur une case voudrait dire que
|
|
1344
|
+
* CETTE case doit etre cochee.
|
|
1345
|
+
*
|
|
1346
|
+
* `toutSelectionner` pose une case « Tout selectionner » en tete du groupe, hors de la valeur : elle
|
|
1347
|
+
* est cochee quand toutes les options libres le sont, PARTIELLE (`indeterminate`, annonce
|
|
1348
|
+
* « mixed ») quand une partie l'est, et nomme par `aria-controls` les cases qu'elle commande. Un
|
|
1349
|
+
* clic coche toutes les options libres, ou les decoche toutes quand elles l'etaient deja. Une
|
|
1350
|
+
* option desactivee garde son etat : la personne ne peut pas la changer, la case « Tout » non plus.
|
|
1351
|
+
*
|
|
1352
|
+
* `touch` n'est emis que lorsque le focus QUITTE le groupe : passer d'une case a l'autre n'est pas
|
|
1353
|
+
* une fin de saisie, et « choisissez au moins une option » n'a pas a surgir pendant qu'on coche.
|
|
1354
|
+
*
|
|
1355
|
+
* `readonly` : les cases restent focalisables et lues (`aria-readonly`), mais ni le clic ni Espace
|
|
1356
|
+
* ne les basculent, la case « Tout » comprise.
|
|
1357
|
+
*
|
|
1358
|
+
* La valeur suit l'ordre des options, quel que soit l'ordre des clics ; une valeur que les options
|
|
1359
|
+
* ne connaissent pas est gardee a la fin, jamais effacee en silence.
|
|
1360
|
+
*/
|
|
1361
|
+
export declare class StCheckboxGroup implements FormValueControl<readonly string[]> {
|
|
1362
|
+
private readonly element;
|
|
1363
|
+
private readonly libelles;
|
|
1364
|
+
readonly legende: import("@angular/core").InputSignal<string>;
|
|
1365
|
+
readonly aide: import("@angular/core").InputSignal<string | null>;
|
|
1366
|
+
readonly options: import("@angular/core").InputSignal<readonly OptionDeChoix[]>;
|
|
1367
|
+
/** `en-ligne` : cases cote a cote (deux ou trois choix courts), en colonne quand la place manque. */
|
|
1368
|
+
readonly disposition: import("@angular/core").InputSignal<DispositionDeGroupe>;
|
|
1369
|
+
/** Une case « Tout selectionner » en tete du groupe, partielle quand une partie est cochee. */
|
|
1370
|
+
readonly toutSelectionner: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
|
|
1371
|
+
/** Contrat Signal Forms. */
|
|
1372
|
+
readonly value: import("@angular/core").ModelSignal<readonly string[]>;
|
|
1373
|
+
readonly errors: import("@angular/core").InputSignal<readonly ValidationError.WithOptionalFieldTree[]>;
|
|
1374
|
+
readonly touched: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
|
|
1375
|
+
readonly dirty: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
|
|
1376
|
+
readonly pending: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
|
|
1377
|
+
readonly disabled: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
|
|
1378
|
+
readonly disabledReasons: import("@angular/core").InputSignal<readonly WithOptionalFieldTree<DisabledReason>[]>;
|
|
1379
|
+
readonly readonly: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
|
|
1380
|
+
readonly required: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
|
|
1381
|
+
readonly hidden: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
|
|
1382
|
+
readonly name: import("@angular/core").InputSignal<string>;
|
|
1383
|
+
readonly touch: import("@angular/core").OutputEmitterRef<void>;
|
|
1384
|
+
private readonly cases;
|
|
1385
|
+
/** Racine des identifiants des cases et de leurs aides. */
|
|
1386
|
+
private readonly racine;
|
|
1387
|
+
protected readonly identifiantDuTout: string;
|
|
1388
|
+
protected readonly libelleDuTout: import("@angular/core").Signal<string>;
|
|
1389
|
+
/** L'erreur se montre apres la sortie du groupe, comme son message. */
|
|
1390
|
+
protected readonly enErreur: import("@angular/core").Signal<boolean>;
|
|
1391
|
+
private readonly choisies;
|
|
1392
|
+
/** Les options que la personne peut changer : celles que la case « Tout » commande. */
|
|
1393
|
+
private readonly libres;
|
|
1394
|
+
protected readonly etatDuTout: import("@angular/core").Signal<EtatDuTout$1>;
|
|
1395
|
+
/** Les cases que commande la case « Tout », pour `aria-controls`. */
|
|
1396
|
+
protected readonly casesCommandees: import("@angular/core").Signal<string>;
|
|
1397
|
+
/** L'aide du groupe, suivie des raisons de sa desactivation. */
|
|
1398
|
+
protected readonly aideEtRaisons: import("@angular/core").Signal<string | null>;
|
|
1399
|
+
protected estChoisie(valeur: string): boolean;
|
|
1400
|
+
protected identifiantOption(indice: number): string;
|
|
1401
|
+
protected identifiantAide(indice: number): string;
|
|
1402
|
+
/** L'aide d'une option : la sienne, et la raison de sa desactivation. */
|
|
1403
|
+
protected aideDe(option: OptionDeChoix): string | null;
|
|
1404
|
+
/**
|
|
1405
|
+
* Focus sur la premiere option libre (Signal Forms l'appelle pour « choisissez au moins une
|
|
1406
|
+
* option ») : une case qui compte, jamais la case « Tout ».
|
|
1407
|
+
*/
|
|
1408
|
+
focus(options?: FocusOptions): void;
|
|
1409
|
+
/** En lecture seule, le clic (souris, ou Espace qui passe par lui) est annule avant la bascule. */
|
|
1410
|
+
protected surClic(evenement: MouseEvent): void;
|
|
1411
|
+
protected basculer(evenement: Event, valeur: string): void;
|
|
1412
|
+
protected basculerTout(evenement: Event): void;
|
|
1413
|
+
protected aLaSortie(evenement: FocusEvent): void;
|
|
1414
|
+
/** Les valeurs dans l'ordre des options, puis celles que les options ne connaissent pas. */
|
|
1415
|
+
private dansLOrdre;
|
|
1416
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<StCheckboxGroup, never>;
|
|
1417
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<StCheckboxGroup, "st-checkbox-group", never, {
|
|
1418
|
+
"legende": {
|
|
1419
|
+
"alias": "legende";
|
|
1420
|
+
"required": true;
|
|
1421
|
+
"isSignal": true;
|
|
1422
|
+
};
|
|
1423
|
+
"aide": {
|
|
1424
|
+
"alias": "aide";
|
|
1425
|
+
"required": false;
|
|
1426
|
+
"isSignal": true;
|
|
1427
|
+
};
|
|
1428
|
+
"options": {
|
|
1429
|
+
"alias": "options";
|
|
1430
|
+
"required": true;
|
|
1431
|
+
"isSignal": true;
|
|
1432
|
+
};
|
|
1433
|
+
"disposition": {
|
|
1434
|
+
"alias": "disposition";
|
|
1435
|
+
"required": false;
|
|
1436
|
+
"isSignal": true;
|
|
1437
|
+
};
|
|
1438
|
+
"toutSelectionner": {
|
|
1439
|
+
"alias": "toutSelectionner";
|
|
1440
|
+
"required": false;
|
|
1441
|
+
"isSignal": true;
|
|
1442
|
+
};
|
|
1443
|
+
"value": {
|
|
1444
|
+
"alias": "value";
|
|
1445
|
+
"required": false;
|
|
1446
|
+
"isSignal": true;
|
|
1447
|
+
};
|
|
1448
|
+
"errors": {
|
|
1449
|
+
"alias": "errors";
|
|
1450
|
+
"required": false;
|
|
1451
|
+
"isSignal": true;
|
|
1452
|
+
};
|
|
1453
|
+
"touched": {
|
|
1454
|
+
"alias": "touched";
|
|
1455
|
+
"required": false;
|
|
1456
|
+
"isSignal": true;
|
|
1457
|
+
};
|
|
1458
|
+
"dirty": {
|
|
1459
|
+
"alias": "dirty";
|
|
1460
|
+
"required": false;
|
|
1461
|
+
"isSignal": true;
|
|
1462
|
+
};
|
|
1463
|
+
"pending": {
|
|
1464
|
+
"alias": "pending";
|
|
1465
|
+
"required": false;
|
|
1466
|
+
"isSignal": true;
|
|
1467
|
+
};
|
|
1468
|
+
"disabled": {
|
|
1469
|
+
"alias": "disabled";
|
|
1470
|
+
"required": false;
|
|
1471
|
+
"isSignal": true;
|
|
1472
|
+
};
|
|
1473
|
+
"disabledReasons": {
|
|
1474
|
+
"alias": "disabledReasons";
|
|
1475
|
+
"required": false;
|
|
1476
|
+
"isSignal": true;
|
|
1477
|
+
};
|
|
1478
|
+
"readonly": {
|
|
1479
|
+
"alias": "readonly";
|
|
1480
|
+
"required": false;
|
|
1481
|
+
"isSignal": true;
|
|
1482
|
+
};
|
|
1483
|
+
"required": {
|
|
1484
|
+
"alias": "required";
|
|
1485
|
+
"required": false;
|
|
1486
|
+
"isSignal": true;
|
|
1487
|
+
};
|
|
1488
|
+
"hidden": {
|
|
1489
|
+
"alias": "hidden";
|
|
1490
|
+
"required": false;
|
|
1491
|
+
"isSignal": true;
|
|
1492
|
+
};
|
|
1493
|
+
"name": {
|
|
1494
|
+
"alias": "name";
|
|
1495
|
+
"required": false;
|
|
1496
|
+
"isSignal": true;
|
|
1497
|
+
};
|
|
1498
|
+
}, {
|
|
1499
|
+
"value": "valueChange";
|
|
1500
|
+
"touch": "touch";
|
|
1501
|
+
}, never, never, true, never>;
|
|
1502
|
+
}
|
|
1503
|
+
/** Une ligne de la matrice : un evenement (« Operation carte »), et sa precision eventuelle. */
|
|
1504
|
+
export interface LigneDeMatrice {
|
|
1505
|
+
readonly cle: string;
|
|
1506
|
+
readonly libelle: string;
|
|
1507
|
+
readonly precision?: string;
|
|
1508
|
+
}
|
|
1509
|
+
/** Une colonne de la matrice : un canal (« Courriel »), et son icone eventuelle (decorative). */
|
|
1510
|
+
export interface ColonneDeMatrice {
|
|
1511
|
+
readonly cle: string;
|
|
1512
|
+
readonly libelle: string;
|
|
1513
|
+
readonly icone?: Icone;
|
|
1514
|
+
}
|
|
1515
|
+
/** Une cellule qu'on ne peut pas changer, et pourquoi (D39 : elle reste focalisable et le dit). */
|
|
1516
|
+
export interface CelluleIndisponible {
|
|
1517
|
+
/** `ligne:colonne`. */
|
|
1518
|
+
readonly cle: string;
|
|
1519
|
+
readonly raison: string;
|
|
1520
|
+
}
|
|
1521
|
+
/**
|
|
1522
|
+
* `formulaire` : la valeur part avec le formulaire (contrat Signal Forms, erreurs a la sortie).
|
|
1523
|
+
* `immediat` : chaque case s'applique tout de suite (un reglage, UX-8) : aucune erreur de
|
|
1524
|
+
* validation, `aria-busy` sur les cellules que l'application enregistre, et l'issue de chaque
|
|
1525
|
+
* enregistrement annoncee.
|
|
1526
|
+
*/
|
|
1527
|
+
export type ModeDeMatrice = 'formulaire' | 'immediat';
|
|
1528
|
+
type EtatDuTout = 'vide' | 'partiel' | 'coche';
|
|
1529
|
+
/**
|
|
1530
|
+
* Matrice de cases : des evenements en lignes, des canaux en colonnes (preferences d'alertes,
|
|
1531
|
+
* droits par role, documents par canal). La valeur est la liste des cles `ligne:colonne` cochees.
|
|
1532
|
+
*
|
|
1533
|
+
* ```html
|
|
1534
|
+
* <st-choice-matrix
|
|
1535
|
+
* legende="Alertes"
|
|
1536
|
+
* [lignes]="evenements"
|
|
1537
|
+
* [colonnes]="canaux"
|
|
1538
|
+
* toutParColonne
|
|
1539
|
+
* [formField]="preferences.alertes"
|
|
1540
|
+
* />
|
|
1541
|
+
* ```
|
|
1542
|
+
*
|
|
1543
|
+
* ⚠️ **Un tableau natif, pas une grille ARIA ni des cartes** (UX-5) : `caption` pour son nom,
|
|
1544
|
+
* `th scope="col"` et `th scope="row"` : le lecteur d'ecran lit l'en-tete de ligne et de colonne en
|
|
1545
|
+
* se deplacant. Chaque case porte son nom COMPLET et unique (« Operation carte, Courriel ») :
|
|
1546
|
+
* quinze cases « Courriel » seraient indiscernables hors du tableau (liste des champs d'un lecteur
|
|
1547
|
+
* d'ecran). Sous la largeur du tableau, il defile dans une zone NOMMEE par la legende, focalisable
|
|
1548
|
+
* quand elle deborde ; il ne se transforme jamais en cartes.
|
|
1549
|
+
*
|
|
1550
|
+
* `toutParColonne` et `toutParLigne` posent une case « tout » dans chaque en-tete : partielle
|
|
1551
|
+
* (`indeterminate`) quand une partie des cases disponibles l'est, elle coche ou decoche les cases
|
|
1552
|
+
* disponibles de sa ligne ou de sa colonne. Une cellule indisponible (`cellulesIndisponibles`) reste
|
|
1553
|
+
* focalisable (`aria-disabled`, D39), dit sa raison, et garde son etat.
|
|
1554
|
+
*
|
|
1555
|
+
* Le message d'erreur porte sur la matrice (mode `formulaire`), une fois, a la sortie de la matrice ;
|
|
1556
|
+
* l'etat (`aria-invalid`) sur chaque case. `readonly` : rien ne bascule. `focus()` : la premiere case
|
|
1557
|
+
* disponible.
|
|
1558
|
+
*
|
|
1559
|
+
* ⚠️ **Mode immediat : l'issue de l'enregistrement se dit, et elle seule.** La case native dit
|
|
1560
|
+
* deja son nouvel etat a la bascule ; l'annoncer en plus le disait deux fois (audit UI du
|
|
1561
|
+
* 2026-09-27, D-21). Une cellule basculee par la personne, puis posee dans `cellulesEnAttente` par
|
|
1562
|
+
* l'application, se dit en en sortant : enregistree (`celluleBasculee`) si elle garde l'etat
|
|
1563
|
+
* demande, refusee (`choixNonEnregistre`) si l'application l'a rendu. L'application rend donc la
|
|
1564
|
+
* valeur d'avant AVANT ou AVEC la sortie de `cellulesEnAttente`. Sans `cellulesEnAttente`, rien de
|
|
1565
|
+
* plus ne se dit que la case elle-meme.
|
|
1566
|
+
*/
|
|
1567
|
+
export declare class StChoiceMatrix implements FormValueControl<readonly string[]> {
|
|
1568
|
+
private readonly element;
|
|
1569
|
+
private readonly destruction;
|
|
1570
|
+
protected readonly libelles: import("@angular/core").Signal<import("@starterlib/ui").LibellesUi>;
|
|
1571
|
+
private readonly locale;
|
|
1572
|
+
readonly legende: import("@angular/core").InputSignal<string>;
|
|
1573
|
+
readonly aide: import("@angular/core").InputSignal<string | null>;
|
|
1574
|
+
readonly lignes: import("@angular/core").InputSignal<readonly LigneDeMatrice[]>;
|
|
1575
|
+
readonly colonnes: import("@angular/core").InputSignal<readonly ColonneDeMatrice[]>;
|
|
1576
|
+
readonly toutParColonne: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
|
|
1577
|
+
readonly toutParLigne: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
|
|
1578
|
+
readonly cellulesIndisponibles: import("@angular/core").InputSignal<readonly CelluleIndisponible[]>;
|
|
1579
|
+
readonly mode: import("@angular/core").InputSignal<ModeDeMatrice>;
|
|
1580
|
+
/** Mode `immediat` : les cles `ligne:colonne` que l'application enregistre (`aria-busy`). */
|
|
1581
|
+
readonly cellulesEnAttente: import("@angular/core").InputSignal<readonly string[]>;
|
|
1582
|
+
/** Contrat Signal Forms. */
|
|
1583
|
+
readonly value: import("@angular/core").ModelSignal<readonly string[]>;
|
|
1584
|
+
readonly errors: import("@angular/core").InputSignal<readonly ValidationError.WithOptionalFieldTree[]>;
|
|
1585
|
+
readonly touched: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
|
|
1586
|
+
readonly dirty: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
|
|
1587
|
+
readonly pending: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
|
|
1588
|
+
readonly disabled: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
|
|
1589
|
+
readonly disabledReasons: import("@angular/core").InputSignal<readonly WithOptionalFieldTree<DisabledReason>[]>;
|
|
1590
|
+
readonly readonly: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
|
|
1591
|
+
readonly required: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
|
|
1592
|
+
readonly hidden: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
|
|
1593
|
+
readonly name: import("@angular/core").InputSignal<string>;
|
|
1594
|
+
readonly touch: import("@angular/core").OutputEmitterRef<void>;
|
|
1595
|
+
private readonly cases;
|
|
1596
|
+
private readonly zone;
|
|
1597
|
+
private readonly racine;
|
|
1598
|
+
protected readonly identifiants: {
|
|
1599
|
+
readonly legende: `${string}-legende`;
|
|
1600
|
+
readonly aide: `${string}-aide`;
|
|
1601
|
+
readonly erreur: `${string}-erreur`;
|
|
1602
|
+
readonly deborde: `${string}-deborde`;
|
|
1603
|
+
};
|
|
1604
|
+
protected readonly annonce: AnnonceLocale;
|
|
1605
|
+
/** La zone deborde : elle devient focalisable, pour defiler au clavier (UX-6). */
|
|
1606
|
+
protected readonly deborde: import("@angular/core").WritableSignal<boolean>;
|
|
1607
|
+
private readonly choisies;
|
|
1608
|
+
private readonly indisponibles;
|
|
1609
|
+
private readonly enAttente;
|
|
1610
|
+
/** Mode immediat : les bascules de la personne dont l'issue n'est pas encore dite, par cle. */
|
|
1611
|
+
private readonly bascules;
|
|
1612
|
+
/** Les erreurs ne se disent qu'en mode formulaire, apres la sortie de la matrice. */
|
|
1613
|
+
protected readonly enErreur: import("@angular/core").Signal<boolean>;
|
|
1614
|
+
protected readonly messages: import("@angular/core").Signal<string[]>;
|
|
1615
|
+
/** L'aide de la matrice, suivie des raisons de sa desactivation. */
|
|
1616
|
+
protected readonly aideEtRaisons: import("@angular/core").Signal<string | null>;
|
|
1617
|
+
/** Ce qui decrit le tableau : l'aide, le debordement, puis l'erreur. */
|
|
1618
|
+
protected readonly descriptions: import("@angular/core").Signal<string | null>;
|
|
1619
|
+
constructor();
|
|
1620
|
+
/** Protegee : lue par la classe et son gabarit seuls, elle n'est pas de la surface (Q-17). */
|
|
1621
|
+
protected cle(ligne: LigneDeMatrice, colonne: ColonneDeMatrice): string;
|
|
1622
|
+
protected estCochee(ligne: LigneDeMatrice, colonne: ColonneDeMatrice): boolean;
|
|
1623
|
+
protected raisonDe(ligne: LigneDeMatrice, colonne: ColonneDeMatrice): string | null;
|
|
1624
|
+
protected estEnAttente(ligne: LigneDeMatrice, colonne: ColonneDeMatrice): boolean;
|
|
1625
|
+
protected idColonne(indice: number): string;
|
|
1626
|
+
protected idLigne(indice: number): string;
|
|
1627
|
+
protected idCase(ligne: number, colonne: number): string;
|
|
1628
|
+
protected idRaison(ligne: number, colonne: number): string;
|
|
1629
|
+
/** Les cases disponibles d'une colonne ou d'une ligne, par leurs cles. */
|
|
1630
|
+
private disponibles;
|
|
1631
|
+
private clesDeColonne;
|
|
1632
|
+
private clesDeLigne;
|
|
1633
|
+
private etatDe;
|
|
1634
|
+
protected etatDeColonne(colonne: ColonneDeMatrice): EtatDuTout;
|
|
1635
|
+
protected etatDeLigne(ligne: LigneDeMatrice): EtatDuTout;
|
|
1636
|
+
/** Les cases qu'une case « tout » commande, pour `aria-controls`. */
|
|
1637
|
+
protected casesDeColonne(colonne: ColonneDeMatrice, indice: number): string;
|
|
1638
|
+
protected casesDeLigne(ligne: LigneDeMatrice, indice: number): string;
|
|
1639
|
+
/** La premiere case disponible : ce que Signal Forms appelle pour une erreur de la matrice. */
|
|
1640
|
+
focus(options?: FocusOptions): void;
|
|
1641
|
+
/**
|
|
1642
|
+
* Le clic est annule AVANT la bascule quand rien ne doit changer : lecture seule, cellule
|
|
1643
|
+
* indisponible (aucun etat coche transitoire, aucun evenement `change`).
|
|
1644
|
+
*/
|
|
1645
|
+
protected surClic(evenement: MouseEvent, indisponible?: boolean): void;
|
|
1646
|
+
protected basculer(evenement: Event, ligne: LigneDeMatrice, colonne: ColonneDeMatrice): void;
|
|
1647
|
+
protected basculerColonne(evenement: Event, colonne: ColonneDeMatrice): void;
|
|
1648
|
+
protected basculerLigne(evenement: Event, ligne: LigneDeMatrice): void;
|
|
1649
|
+
private basculerTout;
|
|
1650
|
+
/** La valeur dans l'ordre de la matrice (lignes, puis colonnes), les cles inconnues a la fin. */
|
|
1651
|
+
private ecrire;
|
|
1652
|
+
protected aLaSortie(evenement: FocusEvent): void;
|
|
1653
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<StChoiceMatrix, never>;
|
|
1654
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<StChoiceMatrix, "st-choice-matrix", never, {
|
|
1655
|
+
"legende": {
|
|
1656
|
+
"alias": "legende";
|
|
1657
|
+
"required": true;
|
|
1658
|
+
"isSignal": true;
|
|
1659
|
+
};
|
|
1660
|
+
"aide": {
|
|
1661
|
+
"alias": "aide";
|
|
1662
|
+
"required": false;
|
|
1663
|
+
"isSignal": true;
|
|
1664
|
+
};
|
|
1665
|
+
"lignes": {
|
|
1666
|
+
"alias": "lignes";
|
|
1667
|
+
"required": true;
|
|
1668
|
+
"isSignal": true;
|
|
1669
|
+
};
|
|
1670
|
+
"colonnes": {
|
|
1671
|
+
"alias": "colonnes";
|
|
1672
|
+
"required": true;
|
|
1673
|
+
"isSignal": true;
|
|
1674
|
+
};
|
|
1675
|
+
"toutParColonne": {
|
|
1676
|
+
"alias": "toutParColonne";
|
|
1677
|
+
"required": false;
|
|
1678
|
+
"isSignal": true;
|
|
1679
|
+
};
|
|
1680
|
+
"toutParLigne": {
|
|
1681
|
+
"alias": "toutParLigne";
|
|
1682
|
+
"required": false;
|
|
1683
|
+
"isSignal": true;
|
|
1684
|
+
};
|
|
1685
|
+
"cellulesIndisponibles": {
|
|
1686
|
+
"alias": "cellulesIndisponibles";
|
|
1687
|
+
"required": false;
|
|
1688
|
+
"isSignal": true;
|
|
1689
|
+
};
|
|
1690
|
+
"mode": {
|
|
1691
|
+
"alias": "mode";
|
|
1692
|
+
"required": false;
|
|
1693
|
+
"isSignal": true;
|
|
1694
|
+
};
|
|
1695
|
+
"cellulesEnAttente": {
|
|
1696
|
+
"alias": "cellulesEnAttente";
|
|
1697
|
+
"required": false;
|
|
1698
|
+
"isSignal": true;
|
|
1699
|
+
};
|
|
1700
|
+
"value": {
|
|
1701
|
+
"alias": "value";
|
|
1702
|
+
"required": false;
|
|
1703
|
+
"isSignal": true;
|
|
1704
|
+
};
|
|
1705
|
+
"errors": {
|
|
1706
|
+
"alias": "errors";
|
|
1707
|
+
"required": false;
|
|
1708
|
+
"isSignal": true;
|
|
1709
|
+
};
|
|
1710
|
+
"touched": {
|
|
1711
|
+
"alias": "touched";
|
|
1712
|
+
"required": false;
|
|
1713
|
+
"isSignal": true;
|
|
1714
|
+
};
|
|
1715
|
+
"dirty": {
|
|
1716
|
+
"alias": "dirty";
|
|
1717
|
+
"required": false;
|
|
1718
|
+
"isSignal": true;
|
|
1719
|
+
};
|
|
1720
|
+
"pending": {
|
|
1721
|
+
"alias": "pending";
|
|
1722
|
+
"required": false;
|
|
1723
|
+
"isSignal": true;
|
|
1724
|
+
};
|
|
1725
|
+
"disabled": {
|
|
1726
|
+
"alias": "disabled";
|
|
1727
|
+
"required": false;
|
|
1728
|
+
"isSignal": true;
|
|
1729
|
+
};
|
|
1730
|
+
"disabledReasons": {
|
|
1731
|
+
"alias": "disabledReasons";
|
|
1732
|
+
"required": false;
|
|
1733
|
+
"isSignal": true;
|
|
1734
|
+
};
|
|
1735
|
+
"readonly": {
|
|
1736
|
+
"alias": "readonly";
|
|
1737
|
+
"required": false;
|
|
1738
|
+
"isSignal": true;
|
|
1739
|
+
};
|
|
1740
|
+
"required": {
|
|
1741
|
+
"alias": "required";
|
|
1742
|
+
"required": false;
|
|
1743
|
+
"isSignal": true;
|
|
1744
|
+
};
|
|
1745
|
+
"hidden": {
|
|
1746
|
+
"alias": "hidden";
|
|
1747
|
+
"required": false;
|
|
1748
|
+
"isSignal": true;
|
|
1749
|
+
};
|
|
1750
|
+
"name": {
|
|
1751
|
+
"alias": "name";
|
|
1752
|
+
"required": false;
|
|
1753
|
+
"isSignal": true;
|
|
1754
|
+
};
|
|
1755
|
+
}, {
|
|
1756
|
+
"value": "valueChange";
|
|
1757
|
+
"touch": "touch";
|
|
1758
|
+
}, never, never, true, never>;
|
|
1759
|
+
}
|
|
1760
|
+
/**
|
|
1761
|
+
* Largeur LOGIQUE d'un champ dans une rangee : sa part de la ligne, jamais des px. Un champ en px
|
|
1762
|
+
* ne suit ni la police de la personne ni le reflow a 320 px ; une part, si.
|
|
1763
|
+
*/
|
|
1764
|
+
export type LargeurDeChamp = 'etroite' | 'normale' | 'large';
|
|
1765
|
+
/**
|
|
1766
|
+
* Deux ou trois champs courts cote a cote : code postal et ville, indicatif et numero, quantite et
|
|
1767
|
+
* unite.
|
|
1768
|
+
*
|
|
1769
|
+
* ```html
|
|
1770
|
+
* <st-form-row [largeurs]="['etroite', 'large']">
|
|
1771
|
+
* <st-input libelle="Code postal" [formField]="adresse.codePostal" />
|
|
1772
|
+
* <st-input libelle="Ville" [formField]="adresse.ville" />
|
|
1773
|
+
* </st-form-row>
|
|
1774
|
+
* ```
|
|
1775
|
+
*
|
|
1776
|
+
* ⚠️ **Aucun etat, aucune semantique** : chaque champ garde son `st-form-field`, son etiquette et
|
|
1777
|
+
* ses erreurs ; la rangee n'ajoute ni role ni nom. L'ordre du DOM est l'ordre de lecture et de
|
|
1778
|
+
* tabulation.
|
|
1779
|
+
*
|
|
1780
|
+
* La rangee repasse en colonne sous la rupture `sm` de SON conteneur (30 rem), et non de l'ecran :
|
|
1781
|
+
* dans une colonne etroite comme a 320 px, et quand la personne agrandit le texte a 200 % (le
|
|
1782
|
+
* conteneur, mesure en rem, retrecit d'autant). Les colonnes : `colonnes` (2, 3, ou `auto`, autant
|
|
1783
|
+
* que la place en laisse), ou `largeurs`, une part logique par champ ; une largeur inconnue (des px)
|
|
1784
|
+
* est refusee en developpement et vaut `normale`.
|
|
1785
|
+
*/
|
|
1786
|
+
export declare class StFormRow {
|
|
1787
|
+
/** `auto` : autant de colonnes que la place en laisse, 10 rem au moins chacune. */
|
|
1788
|
+
readonly colonnes: import("@angular/core").InputSignal<2 | 3 | "auto">;
|
|
1789
|
+
/** Une part logique par champ, dans l'ordre ; l'emporte sur `colonnes`. */
|
|
1790
|
+
readonly largeurs: import("@angular/core").InputSignal<readonly LargeurDeChamp[] | null>;
|
|
1791
|
+
protected readonly gabarit: import("@angular/core").Signal<string>;
|
|
1792
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<StFormRow, never>;
|
|
1793
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<StFormRow, "st-form-row", never, {
|
|
1794
|
+
"colonnes": {
|
|
1795
|
+
"alias": "colonnes";
|
|
1796
|
+
"required": false;
|
|
1797
|
+
"isSignal": true;
|
|
1798
|
+
};
|
|
1799
|
+
"largeurs": {
|
|
1800
|
+
"alias": "largeurs";
|
|
1801
|
+
"required": false;
|
|
1802
|
+
"isSignal": true;
|
|
1803
|
+
};
|
|
1804
|
+
}, {}, never, ["*"], true, never>;
|
|
1805
|
+
}
|
|
1806
|
+
/**
|
|
1807
|
+
* Ce qu'un `st-consent-group` offre a ses `st-consent-row` : la valeur de chaque cle, l'ecriture
|
|
1808
|
+
* d'une decision, et les etats du groupe (mode, desactive, lecture seule, erreur). Une ligne hors
|
|
1809
|
+
* d'un groupe n'a pas de sens (sa valeur vit dans le groupe) : elle echoue a l'injection.
|
|
1810
|
+
*/
|
|
1811
|
+
interface GroupeDeConsentements {
|
|
1812
|
+
readonly mode: Signal<'formulaire' | 'immediat'>;
|
|
1813
|
+
readonly desactive: Signal<boolean>;
|
|
1814
|
+
readonly lectureSeule: Signal<boolean>;
|
|
1815
|
+
readonly enErreur: Signal<boolean>;
|
|
1816
|
+
valeurDe(cle: string): boolean | undefined;
|
|
1817
|
+
ecrire(cle: string, valeur: boolean): void;
|
|
1818
|
+
}
|
|
1819
|
+
declare const ST_GROUPE_DE_CONSENTEMENTS: InjectionToken<GroupeDeConsentements>;
|
|
1820
|
+
/**
|
|
1821
|
+
* `formulaire` : les choix partent avec le formulaire (cases, contrat Signal Forms, erreurs a la
|
|
1822
|
+
* sortie). `immediat` : chaque choix s'applique tout de suite (interrupteurs, UX-8) : aucune erreur
|
|
1823
|
+
* de validation ; l'application enregistre chaque `decision` et dit un refus par la ligne.
|
|
1824
|
+
*/
|
|
1825
|
+
export type ModeDeConsentement = 'formulaire' | 'immediat';
|
|
1826
|
+
/**
|
|
1827
|
+
* Consentements et acceptations : finalites RGPD (prospection, partage, profilage), CGU a une
|
|
1828
|
+
* version donnee, mandat SEPA. La valeur est un dictionnaire `cle -> accepte` ; chaque ligne est un
|
|
1829
|
+
* `st-consent-row`.
|
|
1830
|
+
*
|
|
1831
|
+
* ```html
|
|
1832
|
+
* <st-consent-group legende="Vos choix" toutAccepter toutRefuser [formField]="inscription.choix">
|
|
1833
|
+
* <st-consent-row cle="offres" titre="Offres commerciales" description="Par courriel." />
|
|
1834
|
+
* <st-consent-row cle="cgu" titre="Conditions generales" obligatoire versionDuDocument="3.2" />
|
|
1835
|
+
* </st-consent-group>
|
|
1836
|
+
* ```
|
|
1837
|
+
*
|
|
1838
|
+
* Un `st-fieldset` (la legende pose la question). `toutAccepter` et `toutRefuser` posent deux boutons
|
|
1839
|
+
* de MEME POIDS (CNIL : refuser aussi simplement qu'accepter ; deux boutons secondaires, jamais un
|
|
1840
|
+
* lien ni un bouton plus discret que l'autre). Ils n'agissent que sur les lignes FACULTATIVES : une
|
|
1841
|
+
* ligne obligatoire (les CGU) ne s'accepte que par sa propre case, et « Tout refuser » ne la decoche
|
|
1842
|
+
* pas. Le retrait d'un consentement n'exige aucune confirmation.
|
|
1843
|
+
*
|
|
1844
|
+
* Le message d'erreur porte sur le groupe (mode formulaire), a la sortie du groupe ; `aria-invalid`
|
|
1845
|
+
* sur chaque ligne obligatoire non acceptee. `readonly` : rien ne change (les boutons restent
|
|
1846
|
+
* focalisables, `aria-disabled`). `focus()` : la premiere ligne.
|
|
1847
|
+
*/
|
|
1848
|
+
export declare class StConsentGroup implements FormValueControl<Readonly<Record<string, boolean>>>, GroupeDeConsentements {
|
|
1849
|
+
private readonly element;
|
|
1850
|
+
protected readonly libelles: import("@angular/core").Signal<import("@starterlib/ui").LibellesUi>;
|
|
1851
|
+
readonly legende: import("@angular/core").InputSignal<string>;
|
|
1852
|
+
readonly aide: import("@angular/core").InputSignal<string | null>;
|
|
1853
|
+
readonly mode: import("@angular/core").InputSignal<ModeDeConsentement>;
|
|
1854
|
+
readonly toutAccepter: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
|
|
1855
|
+
readonly toutRefuser: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
|
|
1856
|
+
/** Contrat Signal Forms. */
|
|
1857
|
+
readonly value: import("@angular/core").ModelSignal<Readonly<Record<string, boolean>>>;
|
|
1858
|
+
readonly errors: import("@angular/core").InputSignal<readonly ValidationError.WithOptionalFieldTree[]>;
|
|
1859
|
+
readonly touched: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
|
|
1860
|
+
readonly dirty: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
|
|
1861
|
+
readonly pending: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
|
|
1862
|
+
readonly disabled: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
|
|
1863
|
+
readonly disabledReasons: import("@angular/core").InputSignal<readonly WithOptionalFieldTree<DisabledReason>[]>;
|
|
1864
|
+
readonly readonly: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
|
|
1865
|
+
readonly required: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
|
|
1866
|
+
readonly hidden: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
|
|
1867
|
+
readonly name: import("@angular/core").InputSignal<string>;
|
|
1868
|
+
readonly touch: import("@angular/core").OutputEmitterRef<void>;
|
|
1869
|
+
private readonly lignes;
|
|
1870
|
+
readonly desactive: import("@angular/core").Signal<boolean>;
|
|
1871
|
+
readonly lectureSeule: import("@angular/core").Signal<boolean>;
|
|
1872
|
+
/** Les erreurs ne se disent qu'en mode formulaire, apres la sortie du groupe. */
|
|
1873
|
+
readonly enErreur: import("@angular/core").Signal<boolean>;
|
|
1874
|
+
/** L'aide du groupe, suivie des raisons de sa desactivation. */
|
|
1875
|
+
protected readonly aideEtRaisons: import("@angular/core").Signal<string | null>;
|
|
1876
|
+
valeurDe(cle: string): boolean | undefined;
|
|
1877
|
+
ecrire(cle: string, valeur: boolean): void;
|
|
1878
|
+
focus(options?: FocusOptions): void;
|
|
1879
|
+
/** Les lignes FACULTATIVES seulement : une ligne obligatoire ne s'accepte que par sa case. */
|
|
1880
|
+
protected toutDecider(valeur: boolean): void;
|
|
1881
|
+
protected aLaSortie(evenement: FocusEvent): void;
|
|
1882
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<StConsentGroup, never>;
|
|
1883
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<StConsentGroup, "st-consent-group", never, {
|
|
1884
|
+
"legende": {
|
|
1885
|
+
"alias": "legende";
|
|
1886
|
+
"required": true;
|
|
1887
|
+
"isSignal": true;
|
|
1888
|
+
};
|
|
1889
|
+
"aide": {
|
|
1890
|
+
"alias": "aide";
|
|
1891
|
+
"required": false;
|
|
1892
|
+
"isSignal": true;
|
|
1893
|
+
};
|
|
1894
|
+
"mode": {
|
|
1895
|
+
"alias": "mode";
|
|
1896
|
+
"required": false;
|
|
1897
|
+
"isSignal": true;
|
|
1898
|
+
};
|
|
1899
|
+
"toutAccepter": {
|
|
1900
|
+
"alias": "toutAccepter";
|
|
1901
|
+
"required": false;
|
|
1902
|
+
"isSignal": true;
|
|
1903
|
+
};
|
|
1904
|
+
"toutRefuser": {
|
|
1905
|
+
"alias": "toutRefuser";
|
|
1906
|
+
"required": false;
|
|
1907
|
+
"isSignal": true;
|
|
1908
|
+
};
|
|
1909
|
+
"value": {
|
|
1910
|
+
"alias": "value";
|
|
1911
|
+
"required": false;
|
|
1912
|
+
"isSignal": true;
|
|
1913
|
+
};
|
|
1914
|
+
"errors": {
|
|
1915
|
+
"alias": "errors";
|
|
1916
|
+
"required": false;
|
|
1917
|
+
"isSignal": true;
|
|
1918
|
+
};
|
|
1919
|
+
"touched": {
|
|
1920
|
+
"alias": "touched";
|
|
1921
|
+
"required": false;
|
|
1922
|
+
"isSignal": true;
|
|
1923
|
+
};
|
|
1924
|
+
"dirty": {
|
|
1925
|
+
"alias": "dirty";
|
|
1926
|
+
"required": false;
|
|
1927
|
+
"isSignal": true;
|
|
1928
|
+
};
|
|
1929
|
+
"pending": {
|
|
1930
|
+
"alias": "pending";
|
|
1931
|
+
"required": false;
|
|
1932
|
+
"isSignal": true;
|
|
1933
|
+
};
|
|
1934
|
+
"disabled": {
|
|
1935
|
+
"alias": "disabled";
|
|
1936
|
+
"required": false;
|
|
1937
|
+
"isSignal": true;
|
|
1938
|
+
};
|
|
1939
|
+
"disabledReasons": {
|
|
1940
|
+
"alias": "disabledReasons";
|
|
1941
|
+
"required": false;
|
|
1942
|
+
"isSignal": true;
|
|
1943
|
+
};
|
|
1944
|
+
"readonly": {
|
|
1945
|
+
"alias": "readonly";
|
|
1946
|
+
"required": false;
|
|
1947
|
+
"isSignal": true;
|
|
1948
|
+
};
|
|
1949
|
+
"required": {
|
|
1950
|
+
"alias": "required";
|
|
1951
|
+
"required": false;
|
|
1952
|
+
"isSignal": true;
|
|
1953
|
+
};
|
|
1954
|
+
"hidden": {
|
|
1955
|
+
"alias": "hidden";
|
|
1956
|
+
"required": false;
|
|
1957
|
+
"isSignal": true;
|
|
1958
|
+
};
|
|
1959
|
+
"name": {
|
|
1960
|
+
"alias": "name";
|
|
1961
|
+
"required": false;
|
|
1962
|
+
"isSignal": true;
|
|
1963
|
+
};
|
|
1964
|
+
}, {
|
|
1965
|
+
"value": "valueChange";
|
|
1966
|
+
"touch": "touch";
|
|
1967
|
+
}, ["lignes"], ["*"], true, never>;
|
|
1968
|
+
}
|
|
1969
|
+
/** Ce qu'une ligne emet a chaque decision de la personne : l'application le journalise (audit). */
|
|
1970
|
+
export interface DecisionDeConsentement {
|
|
1971
|
+
readonly cle: string;
|
|
1972
|
+
readonly valeur: boolean;
|
|
1973
|
+
/** La version du document que la personne a vue en decidant. */
|
|
1974
|
+
readonly version: string | null;
|
|
1975
|
+
}
|
|
1976
|
+
/**
|
|
1977
|
+
* Un consentement dans un `st-consent-group` : une finalite (« Offres commerciales »), les CGU a une
|
|
1978
|
+
* version donnee, un mandat SEPA.
|
|
1979
|
+
*
|
|
1980
|
+
* ```html
|
|
1981
|
+
* <st-consent-row cle="cgu" titre="Conditions generales" obligatoire versionDuDocument="3.2">
|
|
1982
|
+
* <span stLibelle>J'accepte les <a stLink href="/cgu">conditions generales</a></span>
|
|
1983
|
+
* </st-consent-row>
|
|
1984
|
+
* ```
|
|
1985
|
+
*
|
|
1986
|
+
* Une case (mode `formulaire` du groupe) ou un interrupteur (mode `immediat`, UX-8), son titre
|
|
1987
|
+
* (`titre`, et un titre riche projete `[stLibelle]` pour le lien vers le document : le lien reste
|
|
1988
|
+
* un arret de tabulation a part, hors de la case), sa description et la mention de version, datee
|
|
1989
|
+
* par `decideLe` (« Version 3.2, acceptee le 12 septembre 2026. »), reliees a la case.
|
|
1990
|
+
*
|
|
1991
|
+
* ⚠️ **Jamais cochee d'office** (CNIL) : une cle a `true` sans decision enregistree (`decideLe`)
|
|
1992
|
+
* ni decision de la personne dans la page s'affiche DECOCHEE, et le developpement le signale. Une
|
|
1993
|
+
* ligne `obligatoire` dit « (obligatoire) » en texte ; les actions de groupe ne la touchent jamais.
|
|
1994
|
+
*
|
|
1995
|
+
* Mode immediat : `enregistrement` pose `aria-busy` pendant que l'application enregistre ; un
|
|
1996
|
+
* `refus` (le message du serveur) remet la ligne a son etat d'avant la decision, s'affiche relie a
|
|
1997
|
+
* la ligne et s'annonce (« Choix non enregistre. »). Chaque decision sort par `decision`
|
|
1998
|
+
* (`{ cle, valeur, version }`) : le socle ne journalise ni n'appelle rien. L'application remet
|
|
1999
|
+
* `refus` a `null` a chaque nouvelle decision : un meme message deux fois de suite ne change rien
|
|
2000
|
+
* a un signal, et le second refus ne rendrait rien.
|
|
2001
|
+
*
|
|
2002
|
+
* ⚠️ **L'enregistrement avale toute nouvelle decision** (la case, et les actions du groupe) :
|
|
2003
|
+
* `aria-disabled`, focalisable, comme la lecture seule. Une seconde decision pendant la premiere
|
|
2004
|
+
* ecrasait l'etat d'avant retenu, et un refus de la premiere rendait l'etat intermediaire, qu'aucun
|
|
2005
|
+
* enregistrement n'avait jamais porte. Un refus sans decision a rendre (deja rendu, ou present des
|
|
2006
|
+
* l'affichage) ne s'annonce pas : il n'y a aucun choix a dire perdu (audit UI du 2026-09-27, D-10).
|
|
2007
|
+
*/
|
|
2008
|
+
export declare class StConsentRow {
|
|
2009
|
+
protected readonly groupe: GroupeDeConsentements;
|
|
2010
|
+
protected readonly libelles: import("@angular/core").Signal<import("@starterlib/ui").LibellesUi>;
|
|
2011
|
+
private readonly locale;
|
|
2012
|
+
readonly cle: import("@angular/core").InputSignal<string>;
|
|
2013
|
+
/** Le titre en texte : le nom de la case sans titre riche, et celui du recapitulatif d'erreurs. */
|
|
2014
|
+
readonly titre: import("@angular/core").InputSignal<string>;
|
|
2015
|
+
readonly description: import("@angular/core").InputSignal<string | null>;
|
|
2016
|
+
readonly obligatoire: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
|
|
2017
|
+
readonly versionDuDocument: import("@angular/core").InputSignal<string | null>;
|
|
2018
|
+
/** Date de la derniere decision enregistree, `null` si la personne n'a jamais decide. */
|
|
2019
|
+
readonly decideLe: import("@angular/core").InputSignal<string | null>;
|
|
2020
|
+
/** Mode immediat : l'application enregistre la decision (`aria-busy`). */
|
|
2021
|
+
readonly enregistrement: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
|
|
2022
|
+
/** Mode immediat : le refus du serveur, dit a la personne ; la ligne revient a son etat d'avant. */
|
|
2023
|
+
readonly refus: import("@angular/core").InputSignal<string | null>;
|
|
2024
|
+
readonly decision: import("@angular/core").OutputEmitterRef<DecisionDeConsentement>;
|
|
2025
|
+
private readonly champ;
|
|
2026
|
+
protected readonly identifiantDuRefus: string;
|
|
2027
|
+
protected readonly annonce: AnnonceLocale;
|
|
2028
|
+
/** La personne a decide dans la page : sa decision s'affiche, meme sans `decideLe`. */
|
|
2029
|
+
private readonly decideeIci;
|
|
2030
|
+
/** Mode immediat : la valeur d'avant la derniere decision, rendue sur un refus. */
|
|
2031
|
+
private precedente;
|
|
2032
|
+
protected readonly immediat: import("@angular/core").Signal<boolean>;
|
|
2033
|
+
protected readonly coche: import("@angular/core").Signal<boolean>;
|
|
2034
|
+
protected readonly enAttente: import("@angular/core").Signal<boolean>;
|
|
2035
|
+
protected readonly enErreur: import("@angular/core").Signal<boolean>;
|
|
2036
|
+
/** La description, puis la version du document et la decision datee. */
|
|
2037
|
+
protected readonly aide: import("@angular/core").Signal<string | null>;
|
|
2038
|
+
protected readonly descriptionsDuRefus: import("@angular/core").Signal<string[]>;
|
|
2039
|
+
constructor();
|
|
2040
|
+
/**
|
|
2041
|
+
* Une decision de la personne (sa case, ou une action du groupe) : ecrite dans le groupe et
|
|
2042
|
+
* emise. Rien en lecture seule, desactive, ni pendant l'enregistrement de la precedente :
|
|
2043
|
+
* `precedente` reste l'etat d'avant la decision en cours d'enregistrement, le seul qu'un refus
|
|
2044
|
+
* puisse rendre (D-10).
|
|
2045
|
+
*/
|
|
2046
|
+
decider(valeur: boolean): void;
|
|
2047
|
+
focus(options?: FocusOptions): void;
|
|
2048
|
+
/** En lecture seule et pendant l'enregistrement, le clic (souris, ou Espace) est annule. */
|
|
2049
|
+
protected surClic(evenement: MouseEvent): void;
|
|
2050
|
+
protected surBascule(evenement: Event): void;
|
|
2051
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<StConsentRow, never>;
|
|
2052
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<StConsentRow, "st-consent-row", never, {
|
|
2053
|
+
"cle": {
|
|
2054
|
+
"alias": "cle";
|
|
2055
|
+
"required": true;
|
|
2056
|
+
"isSignal": true;
|
|
2057
|
+
};
|
|
2058
|
+
"titre": {
|
|
2059
|
+
"alias": "titre";
|
|
2060
|
+
"required": true;
|
|
2061
|
+
"isSignal": true;
|
|
2062
|
+
};
|
|
2063
|
+
"description": {
|
|
2064
|
+
"alias": "description";
|
|
2065
|
+
"required": false;
|
|
2066
|
+
"isSignal": true;
|
|
2067
|
+
};
|
|
2068
|
+
"obligatoire": {
|
|
2069
|
+
"alias": "obligatoire";
|
|
2070
|
+
"required": false;
|
|
2071
|
+
"isSignal": true;
|
|
2072
|
+
};
|
|
2073
|
+
"versionDuDocument": {
|
|
2074
|
+
"alias": "versionDuDocument";
|
|
2075
|
+
"required": false;
|
|
2076
|
+
"isSignal": true;
|
|
2077
|
+
};
|
|
2078
|
+
"decideLe": {
|
|
2079
|
+
"alias": "decideLe";
|
|
2080
|
+
"required": false;
|
|
2081
|
+
"isSignal": true;
|
|
2082
|
+
};
|
|
2083
|
+
"enregistrement": {
|
|
2084
|
+
"alias": "enregistrement";
|
|
2085
|
+
"required": false;
|
|
2086
|
+
"isSignal": true;
|
|
2087
|
+
};
|
|
2088
|
+
"refus": {
|
|
2089
|
+
"alias": "refus";
|
|
2090
|
+
"required": false;
|
|
2091
|
+
"isSignal": true;
|
|
2092
|
+
};
|
|
2093
|
+
}, {
|
|
2094
|
+
"decision": "decision";
|
|
2095
|
+
}, never, ["[stLibelle]"], true, never>;
|
|
2096
|
+
}
|
|
2097
|
+
/**
|
|
2098
|
+
* Ce qu'un `st-choice-group` offre a ses `st-choice` : le mode (radios ou cases), le nom partage
|
|
2099
|
+
* par les controles, les etats du groupe, et la lecture et l'ecriture de la valeur. Une carte hors
|
|
2100
|
+
* d'un groupe n'a pas de sens (sa valeur vit dans le groupe) : elle echoue a l'injection.
|
|
2101
|
+
*/
|
|
2102
|
+
interface GroupeDeChoix {
|
|
2103
|
+
readonly multiple: Signal<boolean>;
|
|
2104
|
+
readonly nom: Signal<string>;
|
|
2105
|
+
readonly desactive: Signal<boolean>;
|
|
2106
|
+
readonly lectureSeule: Signal<boolean>;
|
|
2107
|
+
readonly enErreur: Signal<boolean>;
|
|
2108
|
+
estChoisie(valeur: string): boolean;
|
|
2109
|
+
choisir(valeur: string, coche: boolean): void;
|
|
2110
|
+
/** Remet chaque controle natif a l'etat du modele, apres une bascule refusee. */
|
|
2111
|
+
resynchroniser(): void;
|
|
2112
|
+
}
|
|
2113
|
+
declare const ST_GROUPE_DE_CHOIX: InjectionToken<GroupeDeChoix>;
|
|
2114
|
+
/** `unique` : des radios, un seul choix. `multiple` : des cases, plusieurs choix. */
|
|
2115
|
+
export type ModeDeChoix = 'unique' | 'multiple';
|
|
2116
|
+
/**
|
|
2117
|
+
* La valeur d'un groupe de cartes : une chaine en mode `unique` (vide tant que rien n'est choisi),
|
|
2118
|
+
* la LISTE des valeurs choisies en mode `multiple`.
|
|
2119
|
+
*/
|
|
2120
|
+
export type ChoixDeGroupe = string | readonly string[];
|
|
2121
|
+
/** `colonne` : les cartes l'une sous l'autre. `grille` : deux colonnes des la rupture `md`. */
|
|
2122
|
+
export type DispositionDeChoix = 'colonne' | 'grille';
|
|
2123
|
+
/**
|
|
2124
|
+
* Cartes de choix : un compte a debiter, un beneficiaire, une offre, un moyen de connexion. Chaque
|
|
2125
|
+
* option est un `st-choice` projete, qui porte un titre, une precision riche (`st-masked`,
|
|
2126
|
+
* `st-money`), une icone ou un avatar, et un detail revele quand il est choisi.
|
|
2127
|
+
*
|
|
2128
|
+
* ```html
|
|
2129
|
+
* <st-choice-group legende="Compte a debiter" [formField]="virement.compte">
|
|
2130
|
+
* <st-choice valeur="courant">
|
|
2131
|
+
* <st-icon nom="compte" />
|
|
2132
|
+
* Compte courant
|
|
2133
|
+
* <st-masked precision type="iban" valeur="FR76 •••• •••• •••• •••• •••• 189" />
|
|
2134
|
+
* </st-choice>
|
|
2135
|
+
* <st-choice valeur="epargne" desactivee raisonDIndisponibilite="Solde insuffisant.">
|
|
2136
|
+
* Livret d'epargne
|
|
2137
|
+
* <st-money precision [valeur]="solde" />
|
|
2138
|
+
* </st-choice>
|
|
2139
|
+
* </st-choice-group>
|
|
2140
|
+
* ```
|
|
2141
|
+
*
|
|
2142
|
+
* ⚠️ **De vrais radios ou de vraies cases, visibles** (`mode`) : un seul arret de tabulation et les
|
|
2143
|
+
* fleches en mode `unique`, « 2 sur 3 » annonce, Espace coche. La carte entiere est l'ETIQUETTE du
|
|
2144
|
+
* controle, jamais une carte cliquable sans nom ni clavier (UX-3) : c'est ce que le groupe
|
|
2145
|
+
* remplace, et pourquoi `st-choice-card` n'existe pas.
|
|
2146
|
+
*
|
|
2147
|
+
* Un `st-fieldset` : la legende pose la question, l'aide la precise ; le message d'erreur porte sur
|
|
2148
|
+
* le groupe, a la sortie du groupe, et l'ETAT d'erreur sur chaque controle (`aria-invalid`). En mode
|
|
2149
|
+
* `unique`, le `fieldset` est un `radiogroup` qui porte l'obligation et la lecture seule (ARIA ne
|
|
2150
|
+
* les prevoit pas sur un radio) ; en mode `multiple`, chaque case porte `aria-readonly`.
|
|
2151
|
+
*
|
|
2152
|
+
* La valeur est une chaine en mode `unique` et une liste en mode `multiple` (`ChoixDeGroupe`) : le
|
|
2153
|
+
* champ lie par `[formField]` a le type de son mode, et le developpement signale une valeur de
|
|
2154
|
+
* l'autre forme. En mode `multiple`, la liste suit l'ordre des cartes quel que soit l'ordre des
|
|
2155
|
+
* clics ; une valeur qu'aucune carte ne porte est gardee a la fin, jamais effacee en silence. Les
|
|
2156
|
+
* bornes (`minLength`, `maxLength`) viennent du schema, comme pour `st-checkbox-group`.
|
|
2157
|
+
*
|
|
2158
|
+
* `touch` n'est emis que lorsque le focus QUITTE le groupe. `readonly` : les cartes restent
|
|
2159
|
+
* focalisables et lues, mais rien ne change. `focus()` : la carte choisie en mode `unique`, sinon
|
|
2160
|
+
* la premiere disponible.
|
|
2161
|
+
*/
|
|
2162
|
+
export declare class StChoiceGroup implements FormValueControl<ChoixDeGroupe>, GroupeDeChoix {
|
|
2163
|
+
private readonly element;
|
|
2164
|
+
readonly legende: import("@angular/core").InputSignal<string>;
|
|
2165
|
+
readonly aide: import("@angular/core").InputSignal<string | null>;
|
|
2166
|
+
readonly mode: import("@angular/core").InputSignal<ModeDeChoix>;
|
|
2167
|
+
readonly disposition: import("@angular/core").InputSignal<DispositionDeChoix>;
|
|
2168
|
+
/** Contrat Signal Forms. */
|
|
2169
|
+
readonly value: import("@angular/core").ModelSignal<ChoixDeGroupe>;
|
|
2170
|
+
readonly errors: import("@angular/core").InputSignal<readonly ValidationError.WithOptionalFieldTree[]>;
|
|
2171
|
+
readonly touched: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
|
|
2172
|
+
readonly dirty: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
|
|
2173
|
+
readonly pending: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
|
|
2174
|
+
readonly disabled: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
|
|
2175
|
+
readonly disabledReasons: import("@angular/core").InputSignal<readonly WithOptionalFieldTree<DisabledReason>[]>;
|
|
2176
|
+
readonly readonly: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
|
|
2177
|
+
readonly required: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
|
|
2178
|
+
readonly hidden: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
|
|
2179
|
+
readonly name: import("@angular/core").InputSignal<string>;
|
|
2180
|
+
readonly touch: import("@angular/core").OutputEmitterRef<void>;
|
|
2181
|
+
private readonly cartes;
|
|
2182
|
+
/** Nom partage par les controles : sans lui, chaque radio forme son propre groupe. */
|
|
2183
|
+
private readonly nomParDefaut;
|
|
2184
|
+
readonly multiple: import("@angular/core").Signal<boolean>;
|
|
2185
|
+
readonly nom: import("@angular/core").Signal<string>;
|
|
2186
|
+
readonly desactive: import("@angular/core").Signal<boolean>;
|
|
2187
|
+
readonly lectureSeule: import("@angular/core").Signal<boolean>;
|
|
2188
|
+
/** L'erreur se montre apres la sortie du groupe, comme son message. */
|
|
2189
|
+
readonly enErreur: import("@angular/core").Signal<boolean>;
|
|
2190
|
+
/** Les valeurs choisies, quelle que soit la forme de la valeur. */
|
|
2191
|
+
private readonly choisies;
|
|
2192
|
+
/** L'aide du groupe, suivie des raisons de sa desactivation. */
|
|
2193
|
+
protected readonly aideEtRaisons: import("@angular/core").Signal<string | null>;
|
|
2194
|
+
constructor();
|
|
2195
|
+
estChoisie(valeur: string): boolean;
|
|
2196
|
+
/** Une decision de la personne : en mode `unique`, seul un choix coche ecrit la valeur. */
|
|
2197
|
+
choisir(valeur: string, coche: boolean): void;
|
|
2198
|
+
resynchroniser(): void;
|
|
2199
|
+
/**
|
|
2200
|
+
* Focus sur la carte choisie (mode `unique` : c'est l'arret de tabulation du groupe), sinon sur la
|
|
2201
|
+
* premiere disponible. Lu sur l'etat (valeur et cartes), et non sur le DOM coche.
|
|
2202
|
+
*/
|
|
2203
|
+
focus(options?: FocusOptions): void;
|
|
2204
|
+
protected aLaSortie(evenement: FocusEvent): void;
|
|
2205
|
+
/** Les valeurs dans l'ordre des cartes, puis celles qu'aucune carte ne porte. */
|
|
2206
|
+
private dansLOrdre;
|
|
2207
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<StChoiceGroup, never>;
|
|
2208
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<StChoiceGroup, "st-choice-group", never, {
|
|
2209
|
+
"legende": {
|
|
2210
|
+
"alias": "legende";
|
|
2211
|
+
"required": true;
|
|
2212
|
+
"isSignal": true;
|
|
2213
|
+
};
|
|
2214
|
+
"aide": {
|
|
2215
|
+
"alias": "aide";
|
|
2216
|
+
"required": false;
|
|
2217
|
+
"isSignal": true;
|
|
2218
|
+
};
|
|
2219
|
+
"mode": {
|
|
2220
|
+
"alias": "mode";
|
|
2221
|
+
"required": false;
|
|
2222
|
+
"isSignal": true;
|
|
2223
|
+
};
|
|
2224
|
+
"disposition": {
|
|
2225
|
+
"alias": "disposition";
|
|
2226
|
+
"required": false;
|
|
2227
|
+
"isSignal": true;
|
|
2228
|
+
};
|
|
2229
|
+
"value": {
|
|
2230
|
+
"alias": "value";
|
|
2231
|
+
"required": false;
|
|
2232
|
+
"isSignal": true;
|
|
2233
|
+
};
|
|
2234
|
+
"errors": {
|
|
2235
|
+
"alias": "errors";
|
|
2236
|
+
"required": false;
|
|
2237
|
+
"isSignal": true;
|
|
2238
|
+
};
|
|
2239
|
+
"touched": {
|
|
2240
|
+
"alias": "touched";
|
|
2241
|
+
"required": false;
|
|
2242
|
+
"isSignal": true;
|
|
2243
|
+
};
|
|
2244
|
+
"dirty": {
|
|
2245
|
+
"alias": "dirty";
|
|
2246
|
+
"required": false;
|
|
2247
|
+
"isSignal": true;
|
|
2248
|
+
};
|
|
2249
|
+
"pending": {
|
|
2250
|
+
"alias": "pending";
|
|
2251
|
+
"required": false;
|
|
2252
|
+
"isSignal": true;
|
|
2253
|
+
};
|
|
2254
|
+
"disabled": {
|
|
2255
|
+
"alias": "disabled";
|
|
2256
|
+
"required": false;
|
|
2257
|
+
"isSignal": true;
|
|
2258
|
+
};
|
|
2259
|
+
"disabledReasons": {
|
|
2260
|
+
"alias": "disabledReasons";
|
|
2261
|
+
"required": false;
|
|
2262
|
+
"isSignal": true;
|
|
2263
|
+
};
|
|
2264
|
+
"readonly": {
|
|
2265
|
+
"alias": "readonly";
|
|
2266
|
+
"required": false;
|
|
2267
|
+
"isSignal": true;
|
|
2268
|
+
};
|
|
2269
|
+
"required": {
|
|
2270
|
+
"alias": "required";
|
|
2271
|
+
"required": false;
|
|
2272
|
+
"isSignal": true;
|
|
2273
|
+
};
|
|
2274
|
+
"hidden": {
|
|
2275
|
+
"alias": "hidden";
|
|
2276
|
+
"required": false;
|
|
2277
|
+
"isSignal": true;
|
|
2278
|
+
};
|
|
2279
|
+
"name": {
|
|
2280
|
+
"alias": "name";
|
|
2281
|
+
"required": false;
|
|
2282
|
+
"isSignal": true;
|
|
2283
|
+
};
|
|
2284
|
+
}, {
|
|
2285
|
+
"value": "valueChange";
|
|
2286
|
+
"touch": "touch";
|
|
2287
|
+
}, ["cartes"], ["*"], true, never>;
|
|
2288
|
+
}
|
|
2289
|
+
/**
|
|
2290
|
+
* Une carte de choix dans un `st-choice-group` : un radio (mode `unique`) ou une case (mode
|
|
2291
|
+
* `multiple`) natifs et visibles, que la carte entiere etiquette.
|
|
2292
|
+
*
|
|
2293
|
+
* ```html
|
|
2294
|
+
* <st-choice valeur="courant">
|
|
2295
|
+
* <st-icon nom="compte" />
|
|
2296
|
+
* Compte courant
|
|
2297
|
+
* <st-masked precision type="iban" valeur="FR76 •••• •••• •••• •••• •••• 189" />
|
|
2298
|
+
* <div detail><st-input libelle="Reference du virement" /></div>
|
|
2299
|
+
* </st-choice>
|
|
2300
|
+
* ```
|
|
2301
|
+
*
|
|
2302
|
+
* Projections : le TITRE (contenu par defaut), la PRECISION (`[precision]` : `st-masked`,
|
|
2303
|
+
* `st-money`, un texte discret), une icone ou un avatar (`st-icon`, `st-avatar`), et le DETAIL
|
|
2304
|
+
* (`[detail]`), revele sous la carte tant qu'elle est choisie (motif « conditional reveal » de
|
|
2305
|
+
* GOV.UK, dans le flux, jamais dans un dialogue).
|
|
2306
|
+
*
|
|
2307
|
+
* ⚠️ Le nom du controle est le texte de son etiquette : le titre, puis la precision (`st-masked`
|
|
2308
|
+
* y donne « IBAN se terminant par 0189 »). L'etiquette ne contient donc AUCUN autre controle :
|
|
2309
|
+
* pas de `st-masked` a bouton de revelation (`charger`), pas de lien. Ce qui se manipule va dans
|
|
2310
|
+
* le detail, hors de l'etiquette.
|
|
2311
|
+
*
|
|
2312
|
+
* Le detail est relie au controle par `aria-controls` ; une case porte aussi `aria-expanded`
|
|
2313
|
+
* (ARIA ne le prevoit pas sur un radio). Le focus n'y est jamais deplace d'office (WCAG 3.2.2) :
|
|
2314
|
+
* il suit la carte dans l'ordre de tabulation, et n'y entre que visible.
|
|
2315
|
+
*
|
|
2316
|
+
* `desactivee` : la carte reste FOCALISABLE (`aria-disabled`, D39, comme une cellule de
|
|
2317
|
+
* `st-choice-matrix`), dit sa raison (`raisonDIndisponibilite`, reliee par `aria-describedby`) et
|
|
2318
|
+
* ne se choisit pas. Le groupe desactive (le schema) gele toutes ses cartes nativement.
|
|
2319
|
+
*/
|
|
2320
|
+
export declare class StChoice {
|
|
2321
|
+
protected readonly groupe: GroupeDeChoix;
|
|
2322
|
+
readonly valeur: import("@angular/core").InputSignal<string>;
|
|
2323
|
+
/** La carte ne se choisit pas, mais reste focalisable et dit pourquoi (D39). */
|
|
2324
|
+
readonly desactivee: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
|
|
2325
|
+
/** Pourquoi la carte ne se choisit pas : lu avec le controle, affiche sous la carte. */
|
|
2326
|
+
readonly raisonDIndisponibilite: import("@angular/core").InputSignal<string | null>;
|
|
2327
|
+
private readonly controle;
|
|
2328
|
+
private readonly zoneDuDetail;
|
|
2329
|
+
private readonly racine;
|
|
2330
|
+
protected readonly identifiantDeLaRaison: string;
|
|
2331
|
+
protected readonly identifiantDuDetail: string;
|
|
2332
|
+
protected readonly coche: import("@angular/core").Signal<boolean>;
|
|
2333
|
+
/** La raison ne se dit que d'une carte indisponible. */
|
|
2334
|
+
protected readonly raison: import("@angular/core").Signal<string | null>;
|
|
2335
|
+
/** Un detail est projete : le controle le designe (`aria-controls`). */
|
|
2336
|
+
protected readonly aUnDetail: import("@angular/core").WritableSignal<boolean>;
|
|
2337
|
+
constructor();
|
|
2338
|
+
focus(options?: FocusOptions): void;
|
|
2339
|
+
/** Remet le controle natif a l'etat du modele (le groupe l'appelle apres une bascule refusee). */
|
|
2340
|
+
resynchroniser(): void;
|
|
2341
|
+
private immobile;
|
|
2342
|
+
/**
|
|
2343
|
+
* Le clic est annule AVANT la bascule quand rien ne doit changer (lecture seule, carte
|
|
2344
|
+
* indisponible). Chromium rend alors la coche a l'option du modele, mais pas tous les moteurs
|
|
2345
|
+
* (jsdom ne restaure que le radio clique) : le groupe la rend lui-meme, l'evenement retombe.
|
|
2346
|
+
*/
|
|
2347
|
+
protected surClic(evenement: MouseEvent): void;
|
|
2348
|
+
protected surBascule(evenement: Event): void;
|
|
2349
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<StChoice, never>;
|
|
2350
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<StChoice, "st-choice", never, {
|
|
2351
|
+
"valeur": {
|
|
2352
|
+
"alias": "valeur";
|
|
2353
|
+
"required": true;
|
|
2354
|
+
"isSignal": true;
|
|
2355
|
+
};
|
|
2356
|
+
"desactivee": {
|
|
2357
|
+
"alias": "desactivee";
|
|
2358
|
+
"required": false;
|
|
2359
|
+
"isSignal": true;
|
|
2360
|
+
};
|
|
2361
|
+
"raisonDIndisponibilite": {
|
|
2362
|
+
"alias": "raisonDIndisponibilite";
|
|
2363
|
+
"required": false;
|
|
2364
|
+
"isSignal": true;
|
|
2365
|
+
};
|
|
2366
|
+
}, {}, never, ["st-icon, st-avatar", "*", "[precision]", "[detail]"], true, never>;
|
|
441
2367
|
}
|
|
442
|
-
|
|
443
2368
|
/**
|
|
444
2369
|
* Interrupteur : un reglage qui s'applique IMMEDIATEMENT.
|
|
445
2370
|
*
|
|
446
2371
|
* ```html
|
|
447
|
-
* <st-switch libelle="Notifications par SMS" [(checked)]="sms" (checkedChange)="enregistrer($event)" />
|
|
2372
|
+
* <st-switch libelle="Notifications par SMS" libelleEtat [(checked)]="sms" (checkedChange)="enregistrer($event)" />
|
|
448
2373
|
* ```
|
|
449
2374
|
*
|
|
450
2375
|
* ⚠️ **Jamais dans un formulaire a envoyer** (UX-8). Un interrupteur promet que
|
|
@@ -454,83 +2379,233 @@ declare class StRadioGroup implements FormValueControl<string> {
|
|
|
454
2379
|
*
|
|
455
2380
|
* C'est pourquoi il n'affiche aucune erreur de validation : un reglage immediat
|
|
456
2381
|
* ne se valide pas a l'envoi. Un refus du serveur se dit par un message, et
|
|
457
|
-
* l'interrupteur revient a son etat precedent.
|
|
2382
|
+
* l'interrupteur revient a son etat precedent. Une regle du schema posee sur lui (`required`,
|
|
2383
|
+
* `validate`) bloquerait pourtant l'envoi d'un formulaire sans rien montrer : en developpement,
|
|
2384
|
+
* il le signale une fois dans la console.
|
|
458
2385
|
*
|
|
459
2386
|
* ⚠️ Une case a cocher native avec `role="switch"` : Espace bascule, l'etiquette
|
|
460
2387
|
* est reliee par `for`, et le lecteur d'ecran annonce « active » ou
|
|
461
2388
|
* « desactive » — mieux qu'un `div` qui imiterait tout cela.
|
|
2389
|
+
*
|
|
2390
|
+
* Une ligne de reglage (planches 3a, 3b) : l'etiquette et son etat a gauche, le rail de 44 x 24 a
|
|
2391
|
+
* droite (a gauche en RTL). `libelleEtat` ecrit l'etat en mots sous l'etiquette (« Etat :
|
|
2392
|
+
* Active », en vert ; « Etat : Desactive ») : la position d'un curseur n'est pas lue par tous.
|
|
2393
|
+
*
|
|
2394
|
+
* Enregistrement en attente (03 §3.3) : `enAttente` pose `aria-busy` sur le
|
|
2395
|
+
* controle pendant que l'appelant enregistre, et remplace l'aide par « Enregistrement en cours… »
|
|
2396
|
+
* (ou `libelleAttente`), relie au controle. Le curseur est DEJA a sa nouvelle position
|
|
2397
|
+
* (optimiste) ; sur un refus, l'appelant remet `checked` et dit pourquoi.
|
|
2398
|
+
*
|
|
2399
|
+
* ⚠️ **L'attente avale toute nouvelle bascule** (`aria-disabled`, focalisable, comme la lecture
|
|
2400
|
+
* seule) : une seconde bascule partait pendant la premiere, et le retour d'un refus ne savait plus
|
|
2401
|
+
* quel etat rendre. Un `checked` remis par l'appelant pendant l'attente, ou en la levant, est un
|
|
2402
|
+
* refus : le curseur revenait en silence, il s'annonce (`choixNonEnregistre`, comme
|
|
2403
|
+
* `st-consent-row`). Aboutie, l'attente ne dit rien : l'etat obtenu s'est dit a la bascule (audit
|
|
2404
|
+
* UI du 2026-09-27, D-10).
|
|
462
2405
|
*/
|
|
463
|
-
declare class StSwitch
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
2406
|
+
export declare class StSwitch extends ContratDeCase {
|
|
2407
|
+
private readonly libelles;
|
|
2408
|
+
protected readonly annonce: AnnonceLocale;
|
|
2409
|
+
/**
|
|
2410
|
+
* Le reglage s'enregistre : `aria-busy`, curseur d'attente ; le controle reste focalisable, et
|
|
2411
|
+
* avale toute nouvelle bascule jusqu'a la fin de l'attente.
|
|
2412
|
+
*/
|
|
2413
|
+
readonly enAttente: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
|
|
2414
|
+
/** Le texte de l'attente ; `null` : « Enregistrement en cours… », du dictionnaire. */
|
|
2415
|
+
readonly libelleAttente: import("@angular/core").InputSignal<string | null>;
|
|
2416
|
+
/**
|
|
2417
|
+
* L'aide dit l'etat OBTENU (« Actif · Chiffrement HSM », planche 3a) : actif, elle passe au vert
|
|
2418
|
+
* de succes, en 500. A choisir explicitement, comme sur `st-checkbox`.
|
|
2419
|
+
*/
|
|
2420
|
+
readonly aideDEtat: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
|
|
2421
|
+
/** Ecrit l'etat en mots sous l'etiquette (« Etat : Active » / « Etat : Desactive »). */
|
|
2422
|
+
readonly libelleEtat: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
|
|
2423
|
+
constructor();
|
|
2424
|
+
/** En attente, une nouvelle bascule est annulee AVANT d'avoir lieu, comme en lecture seule. */
|
|
2425
|
+
protected surClic(evenement: MouseEvent): void;
|
|
2426
|
+
/** Filet si le clic passe malgre tout : en attente, la case reprend l'etat du modele. */
|
|
2427
|
+
protected surBascule(evenement: Event): void;
|
|
2428
|
+
/** Pendant l'attente, l'aide cede la place au texte d'attente. */
|
|
2429
|
+
protected readonly aideAffichee: import("@angular/core").Signal<string | null>;
|
|
2430
|
+
/** La ligne d'etat, s'il y en a une : l'attente, sinon l'etat en mots. */
|
|
2431
|
+
protected readonly etat: import("@angular/core").Signal<string | null>;
|
|
2432
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<StSwitch, never>;
|
|
2433
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<StSwitch, "st-switch", never, {
|
|
2434
|
+
"enAttente": {
|
|
2435
|
+
"alias": "enAttente";
|
|
2436
|
+
"required": false;
|
|
2437
|
+
"isSignal": true;
|
|
2438
|
+
};
|
|
2439
|
+
"libelleAttente": {
|
|
2440
|
+
"alias": "libelleAttente";
|
|
2441
|
+
"required": false;
|
|
2442
|
+
"isSignal": true;
|
|
2443
|
+
};
|
|
2444
|
+
"aideDEtat": {
|
|
2445
|
+
"alias": "aideDEtat";
|
|
2446
|
+
"required": false;
|
|
2447
|
+
"isSignal": true;
|
|
2448
|
+
};
|
|
2449
|
+
"libelleEtat": {
|
|
2450
|
+
"alias": "libelleEtat";
|
|
2451
|
+
"required": false;
|
|
2452
|
+
"isSignal": true;
|
|
2453
|
+
};
|
|
2454
|
+
}, {}, never, never, true, never>;
|
|
477
2455
|
}
|
|
478
|
-
|
|
2456
|
+
/**
|
|
2457
|
+
* Ce qu'un formulaire dit de son envoi a ce qu'il contient (lot 247). Fourni par `form[stForm]`
|
|
2458
|
+
* (`@starterlib/ui/formulaires`) ; le `st-error-summary` qu'il contient le lit, et n'a alors rien
|
|
2459
|
+
* a lier. Une application qui ecrit sa propre directive de formulaire peut le fournir a son tour.
|
|
2460
|
+
*/
|
|
2461
|
+
export interface EtatDEnvoi {
|
|
2462
|
+
/**
|
|
2463
|
+
* Les erreurs a recapituler : aucune avant la premiere tentative, pendant l'envoi, ni apres un
|
|
2464
|
+
* envoi reussi.
|
|
2465
|
+
*/
|
|
2466
|
+
readonly recapitulatif: Signal<readonly ValidationError.WithOptionalFieldTree[]>;
|
|
2467
|
+
/** Les tentatives depuis le dernier envoi reussi : chacune ramene le focus au recapitulatif. */
|
|
2468
|
+
readonly tentative: Signal<number>;
|
|
2469
|
+
/** Un envoi court. */
|
|
2470
|
+
readonly enCours: Signal<boolean>;
|
|
2471
|
+
}
|
|
2472
|
+
export declare const ST_ETAT_D_ENVOI: InjectionToken<EtatDEnvoi>;
|
|
2473
|
+
/** Niveau du titre du recapitulatif, selon sa place dans la page. */
|
|
2474
|
+
export type NiveauDeRecapitulatif = 2 | 3 | 4;
|
|
479
2475
|
/** Une ligne du recapitulatif. */
|
|
480
2476
|
interface LigneDErreur {
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
2477
|
+
/** Cle stable : le champ, ou le rang d'une erreur de formulaire entier. */
|
|
2478
|
+
readonly cle: unknown;
|
|
2479
|
+
/** « Montant du virement : », ponctuation de la langue ; `null` pour une ligne sans champ. */
|
|
2480
|
+
readonly libelle: string | null;
|
|
2481
|
+
readonly message: string;
|
|
2482
|
+
readonly aller: () => void;
|
|
484
2483
|
}
|
|
485
2484
|
/**
|
|
486
2485
|
* Recapitulatif des erreurs d'un formulaire, a l'envoi.
|
|
487
2486
|
*
|
|
2487
|
+
* Dans un `form[stForm]` (`@starterlib/ui/formulaires`, lot 247), il n'a rien a lier : le
|
|
2488
|
+
* formulaire lui fournit ses erreurs et ses tentatives.
|
|
2489
|
+
*
|
|
488
2490
|
* ```html
|
|
489
|
-
* <
|
|
2491
|
+
* <form [stForm]="virement" [envoyerAvec]="envoyer">
|
|
2492
|
+
* <st-error-summary />
|
|
2493
|
+
* ...
|
|
2494
|
+
* </form>
|
|
490
2495
|
* ```
|
|
491
2496
|
*
|
|
492
|
-
*
|
|
493
|
-
*
|
|
494
|
-
*
|
|
2497
|
+
* Hors d'un tel formulaire (en tete de page, loin du formulaire), il se lie :
|
|
2498
|
+
*
|
|
2499
|
+
* ```html
|
|
2500
|
+
* <st-error-summary [erreurs]="formulaire.recapitulatif()" [tentative]="formulaire.tentative()" />
|
|
2501
|
+
* ```
|
|
2502
|
+
*
|
|
2503
|
+
* ⚠️ **Il prend le focus en apparaissant, ET a chaque nouvelle tentative** (UX-5). Sans lui, une
|
|
2504
|
+
* personne au clavier ou au lecteur d'ecran appuie sur « Envoyer », et rien ne se passe : le
|
|
2505
|
+
* champ refuse est en haut de la page, hors de sa vue, et personne ne le lui dit. Un second envoi
|
|
2506
|
+
* refuse (meme avec le meme nombre d'erreurs) incremente `tentative` : le focus revient au cadre
|
|
2507
|
+
* sans que l'application appelle `focus()`. Il ne le reprend PAS a chaque correction : ce serait
|
|
2508
|
+
* arracher la personne au champ qu'elle corrige.
|
|
495
2509
|
*
|
|
496
2510
|
* ⚠️ **Chaque ligne nomme son champ.** « Ce champ est obligatoire. » repete cinq
|
|
497
2511
|
* fois n'apprend rien ; « Nom du beneficiaire : ce champ est obligatoire. », si.
|
|
498
|
-
* Le libelle est
|
|
499
|
-
*
|
|
2512
|
+
* Le libelle est celui du champ LIE (son `st-form-field` direct, sinon son etiquette native, sinon
|
|
2513
|
+
* `aria-label`) ; un champ sans nom lisible donne quand meme un lien (« Champ 2 »).
|
|
500
2514
|
*
|
|
501
2515
|
* ⚠️ **Une ligne par champ**, la premiere erreur seulement : trois erreurs sur le
|
|
502
2516
|
* meme IBAN font trois lignes pour une seule correction.
|
|
503
2517
|
*
|
|
504
|
-
* ⚠️ **Une region nommee par son titre.**
|
|
505
|
-
*
|
|
506
|
-
*
|
|
507
|
-
*
|
|
508
|
-
*
|
|
509
|
-
*
|
|
510
|
-
* qu'il faut corriger. Une erreur
|
|
511
|
-
* serveur sur un champ inconnu — s'affiche sans lien.
|
|
512
|
-
*/
|
|
513
|
-
declare class StErrorSummary {
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
2518
|
+
* ⚠️ **Une region nommee par son titre.** L'hote est la region focalisee : le focus annonce
|
|
2519
|
+
* « 3 erreurs a corriger » a l'arrivee, et la region se retrouve dans la liste des reperes. Ni
|
|
2520
|
+
* `alert` ni `aria-live` : c'est le focus qui annonce.
|
|
2521
|
+
*
|
|
2522
|
+
* Anatomie (planche 3b) : icone, titre (`niveau` 2 a 4), etiquette projetee `[stEtiquette]` a
|
|
2523
|
+
* droite (« Blocage »), `introduction` facultative, puis une ligne par erreur. Chaque ligne amene
|
|
2524
|
+
* le focus sur son champ : c'est le champ, et non la ligne, qu'il faut corriger. Une erreur
|
|
2525
|
+
* rattachee au formulaire entier — un refus du serveur sur un champ inconnu — s'affiche sans lien.
|
|
2526
|
+
*/
|
|
2527
|
+
export declare class StErrorSummary {
|
|
2528
|
+
private readonly libelles;
|
|
2529
|
+
private readonly locale;
|
|
2530
|
+
private readonly element;
|
|
2531
|
+
private readonly injecteur;
|
|
2532
|
+
private readonly envoi;
|
|
2533
|
+
/**
|
|
2534
|
+
* Les erreurs a recapituler. A omettre dans un `form[stForm]`, qui les fournit avec ses
|
|
2535
|
+
* tentatives ; liees, elles l'emportent, et `tentative` se lie avec elles.
|
|
2536
|
+
*/
|
|
2537
|
+
readonly erreurs: import("@angular/core").InputSignal<readonly ValidationError.WithOptionalFieldTree[] | undefined>;
|
|
2538
|
+
/** `null` : « N erreurs a corriger », du dictionnaire. */
|
|
2539
|
+
readonly titre: import("@angular/core").InputSignal<string | null>;
|
|
2540
|
+
/** Niveau du titre : 2 en tete de page, 3 ou 4 dans une section ou un dialogue. */
|
|
2541
|
+
readonly niveau: import("@angular/core").InputSignal<NiveauDeRecapitulatif>;
|
|
2542
|
+
/** Phrase d'introduction sous le titre (« Cliquez sur une anomalie pour aller au champ. »). */
|
|
2543
|
+
readonly introduction: import("@angular/core").InputSignal<string | null>;
|
|
2544
|
+
/**
|
|
2545
|
+
* Compteur d'envois refuses, tenu par l'application (ou `form[stForm]`) : chaque changement
|
|
2546
|
+
* ramene le focus au recapitulatif, meme quand ses lignes n'ont pas change.
|
|
2547
|
+
*
|
|
2548
|
+
* ⚠️ Un NOMBRE, jamais un booleen : `[tentative]="aEnvoye()"` resterait `true` au second envoi
|
|
2549
|
+
* (aucun retour du focus). Le type refuse le booleen a la compilation ; une valeur illisible
|
|
2550
|
+
* (chaine vide, `NaN`) vaut 0, et la comparaison par `Object.is` ne voit pas `NaN` changer.
|
|
2551
|
+
*/
|
|
2552
|
+
readonly tentative: import("@angular/core").InputSignalWithTransform<number, number | `${number}`>;
|
|
2553
|
+
/** Les erreurs lues : celles liees, sinon celles du formulaire qui l'entoure. */
|
|
2554
|
+
private readonly erreursLues;
|
|
2555
|
+
/** La tentative lue : celle du formulaire qui l'entoure, quand les erreurs viennent de lui. */
|
|
2556
|
+
private readonly tentativeLue;
|
|
2557
|
+
/** Unique par instance : deux recapitulatifs sur une page partageraient leur titre. */
|
|
2558
|
+
protected readonly identifiantDuTitre: string;
|
|
2559
|
+
protected readonly lignes: import("@angular/core").Signal<readonly LigneDErreur[]>;
|
|
2560
|
+
protected readonly titreLu: import("@angular/core").Signal<string>;
|
|
2561
|
+
constructor();
|
|
2562
|
+
/** Amene le focus sur le recapitulatif (s'il est visible). */
|
|
2563
|
+
focus(options?: FocusOptions): void;
|
|
2564
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<StErrorSummary, never>;
|
|
2565
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<StErrorSummary, "st-error-summary", never, {
|
|
2566
|
+
"erreurs": {
|
|
2567
|
+
"alias": "erreurs";
|
|
2568
|
+
"required": false;
|
|
2569
|
+
"isSignal": true;
|
|
2570
|
+
};
|
|
2571
|
+
"titre": {
|
|
2572
|
+
"alias": "titre";
|
|
2573
|
+
"required": false;
|
|
2574
|
+
"isSignal": true;
|
|
2575
|
+
};
|
|
2576
|
+
"niveau": {
|
|
2577
|
+
"alias": "niveau";
|
|
2578
|
+
"required": false;
|
|
2579
|
+
"isSignal": true;
|
|
2580
|
+
};
|
|
2581
|
+
"introduction": {
|
|
2582
|
+
"alias": "introduction";
|
|
2583
|
+
"required": false;
|
|
2584
|
+
"isSignal": true;
|
|
2585
|
+
};
|
|
2586
|
+
"tentative": {
|
|
2587
|
+
"alias": "tentative";
|
|
2588
|
+
"required": false;
|
|
2589
|
+
"isSignal": true;
|
|
2590
|
+
};
|
|
2591
|
+
}, {}, never, ["[stEtiquette]"], true, never>;
|
|
530
2592
|
}
|
|
531
|
-
|
|
532
2593
|
/** `connexion` : un mot de passe existant. `creation` : un nouveau. */
|
|
533
|
-
type UsageDuMotDePasse = 'connexion' | 'creation';
|
|
2594
|
+
export type UsageDuMotDePasse = 'connexion' | 'creation';
|
|
2595
|
+
/**
|
|
2596
|
+
* Une regle de creation, montree AVANT la saisie. `respectee` la coche pendant la frappe ; sans
|
|
2597
|
+
* elle, la regle reste a respecter (le serveur juge, SEC-5).
|
|
2598
|
+
*/
|
|
2599
|
+
export interface RegleDeMotDePasse {
|
|
2600
|
+
/** Une phrase complete, avec son point : « Au moins 12 caracteres. » */
|
|
2601
|
+
readonly texte: string;
|
|
2602
|
+
readonly respectee?: (motDePasse: string) => boolean;
|
|
2603
|
+
}
|
|
2604
|
+
/** Une regle telle que le gabarit la rend. */
|
|
2605
|
+
interface RegleRendue {
|
|
2606
|
+
readonly texte: string;
|
|
2607
|
+
readonly respectee: boolean;
|
|
2608
|
+
}
|
|
534
2609
|
/**
|
|
535
2610
|
* Mot de passe, avec revelation.
|
|
536
2611
|
*
|
|
@@ -546,41 +2621,88 @@ type UsageDuMotDePasse = 'connexion' | 'creation';
|
|
|
546
2621
|
* pousse vers des mots de passe courts, retenus de tete, et casse les
|
|
547
2622
|
* gestionnaires de mots de passe.
|
|
548
2623
|
*
|
|
549
|
-
* ⚠️ **Revele, il se remasque des que le focus quitte le champ,
|
|
550
|
-
* formulaire** (SEC-4) : un mot de passe laisse en clair reste lisible
|
|
551
|
-
* l'epaule, sur l'ecran suivant comme sur celui-ci. L'envoi par
|
|
552
|
-
* pas quitter le champ : d'ou l'ecoute de `submit`,
|
|
2624
|
+
* ⚠️ **Revele, il se remasque des que le focus quitte le champ, a l'envoi du
|
|
2625
|
+
* formulaire et avant l'impression** (SEC-4) : un mot de passe laisse en clair reste lisible
|
|
2626
|
+
* par-dessus l'epaule, sur l'ecran suivant comme sur celui-ci, et sur le papier. L'envoi par
|
|
2627
|
+
* Entree ne fait pas quitter le champ : d'ou l'ecoute de `submit`, UNE pour toute la page
|
|
2628
|
+
* (`EnvoisDeFormulaire`), et non une par champ.
|
|
2629
|
+
*
|
|
2630
|
+
* Le bouton de revelation est un bouton bascule DANS le cadre du champ (planche 3a) :
|
|
2631
|
+
* `aria-pressed` porte l'etat, et l'etiquette ne change PAS — « Masquer le mot de passe,
|
|
2632
|
+
* enfonce » se lirait comme une double negation. En lecture seule, il est desactive : on ne
|
|
2633
|
+
* revele pas ce qu'on ne peut pas modifier.
|
|
553
2634
|
*
|
|
554
|
-
*
|
|
555
|
-
*
|
|
556
|
-
*
|
|
2635
|
+
* ⚠️ **Verrouillage des majuscules** : dit SOUS le champ (ton avertissement, icone et texte,
|
|
2636
|
+
* jamais la couleur seule) et annonce une fois (WCAG 4.1.3). Le champ, lui, ne bouge pas ; a la
|
|
2637
|
+
* creation, la ligne du message est reservee entre le champ et les regles, qui ne sautent pas.
|
|
557
2638
|
*
|
|
558
2639
|
* ⚠️ **Aucun indicateur de « force »**, et c'est un refus. Une estimation faite
|
|
559
2640
|
* dans le navigateur donne « fort » a `Motdepasse1!` : elle rassure a tort. Les
|
|
560
|
-
* regles sont affichees AVANT la saisie (UX-10),
|
|
561
|
-
*
|
|
562
|
-
* voit.
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
2641
|
+
* regles sont affichees AVANT la saisie (UX-10), en liste, a la creation seulement, et
|
|
2642
|
+
* chacune se coche quand la saisie la respecte ; c'est le serveur qui verifie — y compris
|
|
2643
|
+
* contre les mots de passe deja divulgues, qu'aucune regle locale ne voit.
|
|
2644
|
+
*
|
|
2645
|
+
* `maxLength` du schema montre un compteur (« 12 caracteres restants ») en complement.
|
|
2646
|
+
*/
|
|
2647
|
+
export declare class StPasswordField extends ControleDeSaisie {
|
|
2648
|
+
protected readonly libelles: import("@angular/core").Signal<import("@starterlib/ui").LibellesUi>;
|
|
2649
|
+
private readonly element;
|
|
2650
|
+
protected readonly annonce: AnnonceLocale;
|
|
2651
|
+
private readonly racineDesParties;
|
|
2652
|
+
protected readonly idRegles: string;
|
|
2653
|
+
protected readonly idMajuscules: string;
|
|
2654
|
+
readonly usage: import("@angular/core").InputSignal<UsageDuMotDePasse>;
|
|
2655
|
+
/**
|
|
2656
|
+
* Regles de creation, montrees sous le champ en `usage="creation"` seulement : une phrase
|
|
2657
|
+
* seule, ou une phrase et le test qui la coche.
|
|
2658
|
+
*/
|
|
2659
|
+
readonly regles: import("@angular/core").InputSignal<readonly (string | RegleDeMotDePasse)[]>;
|
|
2660
|
+
/** Titre de la liste des regles ; par defaut « Exigences du mot de passe : ». */
|
|
2661
|
+
readonly titreDesRegles: import("@angular/core").InputSignal<string | null>;
|
|
2662
|
+
protected readonly revele: import("@angular/core").WritableSignal<boolean>;
|
|
2663
|
+
/** La touche Verr. Maj est active pendant la frappe dans le champ. */
|
|
2664
|
+
protected readonly majusculesVerrouillees: import("@angular/core").WritableSignal<boolean>;
|
|
2665
|
+
protected readonly autocomplete: import("@angular/core").Signal<"new-password" | "current-password">;
|
|
2666
|
+
protected readonly reglesRendues: import("@angular/core").Signal<readonly RegleRendue[]>;
|
|
2667
|
+
protected readonly titreRendu: import("@angular/core").Signal<string>;
|
|
2668
|
+
/** « 12 caracteres restants », quand le schema borne la longueur. */
|
|
2669
|
+
protected readonly compteur: import("@angular/core").Signal<string | null>;
|
|
2670
|
+
/** Les regles et l'avertissement Verr. Maj decrivent le champ : lus au focus, apres l'aide. */
|
|
2671
|
+
protected readonly descriptionsDuControle: import("@angular/core").Signal<string[]>;
|
|
2672
|
+
constructor();
|
|
2673
|
+
protected basculer(): void;
|
|
2674
|
+
protected surSaisie(evenement: Event): void;
|
|
2675
|
+
/** Lit Verr. Maj a chaque touche : l'etat se voit des la premiere frappe, et s'annonce. */
|
|
2676
|
+
protected surTouche(evenement: KeyboardEvent): void;
|
|
2677
|
+
protected remasquer(): void;
|
|
2678
|
+
protected aLaSortie(evenement: FocusEvent): void;
|
|
2679
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<StPasswordField, never>;
|
|
2680
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<StPasswordField, "st-password-field", never, {
|
|
2681
|
+
"usage": {
|
|
2682
|
+
"alias": "usage";
|
|
2683
|
+
"required": false;
|
|
2684
|
+
"isSignal": true;
|
|
2685
|
+
};
|
|
2686
|
+
"regles": {
|
|
2687
|
+
"alias": "regles";
|
|
2688
|
+
"required": false;
|
|
2689
|
+
"isSignal": true;
|
|
2690
|
+
};
|
|
2691
|
+
"titreDesRegles": {
|
|
2692
|
+
"alias": "titreDesRegles";
|
|
2693
|
+
"required": false;
|
|
2694
|
+
"isSignal": true;
|
|
2695
|
+
};
|
|
2696
|
+
}, {}, never, ["[stMeta]", "[stAide]", "[stIndication]"], true, never>;
|
|
579
2697
|
}
|
|
580
|
-
|
|
581
2698
|
/**
|
|
582
2699
|
* Code a usage unique : second facteur, code recu par SMS ou par courriel.
|
|
583
2700
|
*
|
|
2701
|
+
* ```html
|
|
2702
|
+
* <st-otp-field libelle="Code recu par SMS" [formField]="verification.code" />
|
|
2703
|
+
* <!-- schema : validate(chemin.code, ({ value }) => erreurCode(value(), 6)) -->
|
|
2704
|
+
* ```
|
|
2705
|
+
*
|
|
584
2706
|
* ⚠️ **UN seul champ, pas six cases** (UX-9). Six champs cassent le collage, le
|
|
585
2707
|
* remplissage automatique du code recu par SMS, et la lecture au lecteur d'ecran,
|
|
586
2708
|
* qui annonce six champs sans nom au lieu d'un seul.
|
|
@@ -591,45 +2713,126 @@ declare class StPasswordField extends ControleDeSaisie {
|
|
|
591
2713
|
*
|
|
592
2714
|
* ⚠️ **Aucun envoi automatique** a la sixieme saisie : un formulaire qui part de
|
|
593
2715
|
* lui-meme surprend (WCAG 3.2.2), et part aussi avec un code mal colle. Le code
|
|
594
|
-
* colle est nettoye de
|
|
2716
|
+
* colle est nettoye de tout ce qui n'est pas un chiffre — « 123 456 », un tiret, un caractere
|
|
2717
|
+
* invisible colle avec le SMS — ; un chiffre d'une autre ecriture (clavier arabe, pleine chasse
|
|
2718
|
+
* d'un IME) est lu comme son chiffre ASCII, pas avale. Jamais tronque (aucun `maxlength`) : un code trop long se voit
|
|
2719
|
+
* et se dit (`erreurCode`), il ne part pas ampute.
|
|
2720
|
+
*
|
|
2721
|
+
* Le renvoi du code est projete a droite du champ (`[stRenvoi]` : un `st-timer`, un lien) : le
|
|
2722
|
+
* composant ne l'envoie jamais lui-meme.
|
|
2723
|
+
*
|
|
2724
|
+
* Chasse fixe a zero barre, 700, centree, un pas d'espacement entre chiffres (planches 3 et 8) :
|
|
2725
|
+
* six chiffres qui se comptent d'un regard, sans six cases. Le champ reste de gauche a droite en
|
|
2726
|
+
* ecriture inverse.
|
|
595
2727
|
*/
|
|
596
|
-
declare class StOtpField extends ControleDeSaisie {
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
2728
|
+
export declare class StOtpField extends ControleDeSaisie {
|
|
2729
|
+
private readonly libelles;
|
|
2730
|
+
/** Nombre de chiffres attendus : il ecrit l'aide (« Code a 6 chiffres. »). */
|
|
2731
|
+
readonly longueur: import("@angular/core").InputSignalWithTransform<number, unknown>;
|
|
2732
|
+
/**
|
|
2733
|
+
* Identifiants d'autres textes qui decrivent le champ (`aria-describedby`), lus entre l'aide et
|
|
2734
|
+
* l'erreur : les essais restants de `st-challenge` (audit UI du 2026-09-27, D-20). Des elements
|
|
2735
|
+
* PRESENTS seulement : un identifiant absent fait ignorer toute la description par certains
|
|
2736
|
+
* lecteurs d'ecran.
|
|
2737
|
+
*/
|
|
2738
|
+
readonly decritPar: import("@angular/core").InputSignal<readonly string[]>;
|
|
2739
|
+
protected readonly aideLue: import("@angular/core").Signal<string>;
|
|
2740
|
+
protected surSaisie(evenement: Event): void;
|
|
2741
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<StOtpField, never>;
|
|
2742
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<StOtpField, "st-otp-field", never, {
|
|
2743
|
+
"longueur": {
|
|
2744
|
+
"alias": "longueur";
|
|
2745
|
+
"required": false;
|
|
2746
|
+
"isSignal": true;
|
|
2747
|
+
};
|
|
2748
|
+
"decritPar": {
|
|
2749
|
+
"alias": "decritPar";
|
|
2750
|
+
"required": false;
|
|
2751
|
+
"isSignal": true;
|
|
2752
|
+
};
|
|
2753
|
+
}, {}, never, ["[stMeta]", "[stAide]", "[stIndication]", "[stRenvoi]"], true, never>;
|
|
603
2754
|
}
|
|
604
|
-
|
|
605
2755
|
/**
|
|
606
2756
|
* Champ de recherche : un repere, un champ, un bouton.
|
|
607
2757
|
*
|
|
608
2758
|
* ```html
|
|
609
2759
|
* <st-search-field libelle="Rechercher un beneficiaire" (recherche)="filtrer($event)" />
|
|
2760
|
+
* <!-- Barre de filtres (planches 4 et 10) : sans bouton, etiquette visible, raccourci. -->
|
|
2761
|
+
* <st-search-field compact libelleVisible presentation="micro-capitales" libelle="Recherche"
|
|
2762
|
+
* [(value)]="terme"><kbd stRaccourci>⌘K</kbd></st-search-field>
|
|
610
2763
|
* ```
|
|
611
2764
|
*
|
|
612
|
-
* ⚠️ **Un repere `search
|
|
613
|
-
*
|
|
2765
|
+
* ⚠️ **Un repere `search` NOMME** (`aria-label` = `libelle`) : deux recherches d'une page se
|
|
2766
|
+
* distinguent dans la liste des reperes du lecteur d'ecran.
|
|
614
2767
|
*
|
|
615
2768
|
* L'etiquette est lue sans etre affichee — seule exception au socle (UX-1) : la
|
|
616
|
-
* loupe, le bouton et la position disent deja le but du champ.
|
|
2769
|
+
* loupe, le bouton et la position disent deja le but du champ. `libelleVisible` l'affiche
|
|
2770
|
+
* (barre de filtres, ou chaque filtre porte son etiquette).
|
|
2771
|
+
*
|
|
2772
|
+
* La croix « Effacer la recherche » est celle du socle, atteignable au clavier : celle de
|
|
2773
|
+
* WebKit n'etait ni stylee ni tabulable. Echap vide aussi le champ (comportement natif de
|
|
2774
|
+
* `type="search"`).
|
|
2775
|
+
*
|
|
2776
|
+
* ⚠️ **Recherche en cours** : `chargement` passe au BOUTON (`aria-busy`, indicateur differe),
|
|
2777
|
+
* jamais `disabled` — le focus ne tombe pas au milieu de l'attente. En `compact`, sans bouton,
|
|
2778
|
+
* l'indicateur du socle prend la place de la loupe, avec le meme rythme que celui du bouton
|
|
2779
|
+
* (rien avant `rythme.delai.attente`, puis au moins la tenue minimale) et MUET : une barre de
|
|
2780
|
+
* filtres cherche a chaque Entree, et « Chargement en cours » y etait dit a chaque fois, avant
|
|
2781
|
+
* les resultats que l'application annonce (audit UI du 2026-09-27, D-13).
|
|
617
2782
|
*
|
|
618
2783
|
* ⚠️ **Jamais dans l'adresse quand le terme est personnel** (SEC-6). Chercher un
|
|
619
2784
|
* nom, un IBAN ou un numero en `?q=` inscrit la donnee dans l'historique, dans les
|
|
620
2785
|
* journaux des intermediaires, et dans l'en-tete `Referer` des pages suivantes.
|
|
621
2786
|
* `recherche` emet le terme : c'est a l'appelant de ne pas le mettre dans l'URL.
|
|
622
2787
|
*/
|
|
623
|
-
declare class StSearchField extends ControleDeSaisie {
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
2788
|
+
export declare class StSearchField extends ControleDeSaisie {
|
|
2789
|
+
protected readonly libelles: import("@angular/core").Signal<import("@starterlib/ui").LibellesUi>;
|
|
2790
|
+
private readonly saisie;
|
|
2791
|
+
/** Sans bouton « Rechercher » : Entree lance (barres de filtres, planches 4, 10, 12, 14, 15). */
|
|
2792
|
+
readonly compact: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
|
|
2793
|
+
/** Etiquette affichee au-dessus du champ (barre de filtres) ; lue dans tous les cas. */
|
|
2794
|
+
readonly libelleVisible: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
|
|
2795
|
+
/** Style de l'etiquette affichee : `micro-capitales` dans une barre de filtres (EA-90). */
|
|
2796
|
+
readonly presentation: import("@angular/core").InputSignal<PresentationDeLibelle>;
|
|
2797
|
+
/**
|
|
2798
|
+
* Recherche en cours : le bouton attend (`aria-busy`), il n'est jamais desactive ; en `compact`,
|
|
2799
|
+
* un indicateur muet remplace la loupe.
|
|
2800
|
+
*/
|
|
2801
|
+
readonly chargement: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
|
|
2802
|
+
/** Emis a la validation — Entree ou bouton —, et non a chaque frappe. */
|
|
2803
|
+
readonly recherche: import("@angular/core").OutputEmitterRef<string>;
|
|
2804
|
+
/** L'indicateur compact, differe et tenu : une reponse en 150 ms ne fait rien clignoter. */
|
|
2805
|
+
protected readonly attenteVisible: import("@angular/core").Signal<boolean>;
|
|
2806
|
+
protected surSaisie(evenement: Event): void;
|
|
2807
|
+
protected lancer(evenement?: Event): void;
|
|
2808
|
+
/** La croix vide le champ et rend le focus au champ : la saisie reprend la ou elle etait. */
|
|
2809
|
+
protected effacer(): void;
|
|
2810
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<StSearchField, never>;
|
|
2811
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<StSearchField, "st-search-field", never, {
|
|
2812
|
+
"compact": {
|
|
2813
|
+
"alias": "compact";
|
|
2814
|
+
"required": false;
|
|
2815
|
+
"isSignal": true;
|
|
2816
|
+
};
|
|
2817
|
+
"libelleVisible": {
|
|
2818
|
+
"alias": "libelleVisible";
|
|
2819
|
+
"required": false;
|
|
2820
|
+
"isSignal": true;
|
|
2821
|
+
};
|
|
2822
|
+
"presentation": {
|
|
2823
|
+
"alias": "presentation";
|
|
2824
|
+
"required": false;
|
|
2825
|
+
"isSignal": true;
|
|
2826
|
+
};
|
|
2827
|
+
"chargement": {
|
|
2828
|
+
"alias": "chargement";
|
|
2829
|
+
"required": false;
|
|
2830
|
+
"isSignal": true;
|
|
2831
|
+
};
|
|
2832
|
+
}, {
|
|
2833
|
+
"recherche": "recherche";
|
|
2834
|
+
}, never, ["[stRaccourci]"], true, never>;
|
|
631
2835
|
}
|
|
632
|
-
|
|
633
2836
|
/**
|
|
634
2837
|
* IBAN. La valeur du modele est NORMALISEE — sans espaces, en majuscules —, et
|
|
635
2838
|
* l'affichage groupe par quatre.
|
|
@@ -637,94 +2840,115 @@ declare class StSearchField extends ControleDeSaisie {
|
|
|
637
2840
|
* ```html
|
|
638
2841
|
* <st-iban-field libelle="IBAN du beneficiaire" [formField]="virement.iban" />
|
|
639
2842
|
* <!-- schema : validate(chemin.iban, ({ value }) => erreurIban(value())) -->
|
|
2843
|
+
* <!-- un IBAN deja connu, masque au repos : -->
|
|
2844
|
+
* <st-iban-field libelle="IBAN du compte" masque readonly [value]="compte.iban" />
|
|
640
2845
|
* ```
|
|
641
2846
|
*
|
|
642
2847
|
* ⚠️ **Le groupement se fait a la sortie du champ, jamais pendant la frappe.**
|
|
643
2848
|
* Reformater a chaque caractere deplace le curseur a la fin : corriger une
|
|
644
2849
|
* erreur au milieu de 27 caracteres devient impossible, chaque frappe renvoyant a
|
|
645
|
-
* la fin de la ligne.
|
|
2850
|
+
* la fin de la ligne. Le changement de forme s'annonce (« IBAN : FR76 3000 … »).
|
|
646
2851
|
*
|
|
647
2852
|
* ⚠️ **Aucune verification de validite ici** : elle appartient au schema, par
|
|
648
2853
|
* `erreurIban`, pour s'afficher au bon moment et par le bon canal. Et elle reste un
|
|
649
2854
|
* confort (SEC-5) : le serveur revalide.
|
|
650
2855
|
*
|
|
651
|
-
* `
|
|
652
|
-
*
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
private readonly brut;
|
|
658
|
-
protected readonly aideLue: _angular_core.Signal<string>;
|
|
659
|
-
/**
|
|
660
|
-
* Brut pendant la saisie ; groupe par quatre au repos. Une valeur changee de
|
|
661
|
-
* l'exterieur pendant la saisie — remise a zero du formulaire — l'emporte sur
|
|
662
|
-
* le brut, qui ne la represente plus.
|
|
663
|
-
*/
|
|
664
|
-
protected readonly affichage: _angular_core.Signal<string>;
|
|
665
|
-
protected auFocus(): void;
|
|
666
|
-
protected surSaisie(evenement: Event): void;
|
|
667
|
-
protected aLaSortie(): void;
|
|
668
|
-
static ɵfac: _angular_core.ɵɵFactoryDeclaration<StIbanField, never>;
|
|
669
|
-
static ɵcmp: _angular_core.ɵɵComponentDeclaration<StIbanField, "st-iban-field", never, {}, {}, never, never, true, never>;
|
|
670
|
-
}
|
|
671
|
-
|
|
672
|
-
/** `tel` : numero complet, indicatif compris. `tel-national` : sans indicatif. */
|
|
673
|
-
type RemplissageDeTelephone = 'tel' | 'tel-national';
|
|
674
|
-
/**
|
|
675
|
-
* Numero de telephone. La valeur du modele ne garde que les chiffres et le `+` de
|
|
676
|
-
* tete ; la saisie s'affiche telle qu'elle a ete tapee.
|
|
677
|
-
*
|
|
678
|
-
* ```html
|
|
679
|
-
* <st-phone-field libelle="Telephone portable" [formField]="contact.telephone" />
|
|
680
|
-
* <!-- schema : validate(chemin.telephone, ({ value }) => erreurTelephone(value())) -->
|
|
681
|
-
* ```
|
|
2856
|
+
* ⚠️ **`masque` : un IBAN connu ne s'expose pas par-dessus l'epaule.** Au repos, le champ montre
|
|
2857
|
+
* `masquerIban` (« CH74 •••• •••• •••• •291 1 ») ; « Reveler 30s », bouton bascule a
|
|
2858
|
+
* `aria-pressed` dans le cadre, le montre en clair pour `rythme.tenue.revelation`, puis il se
|
|
2859
|
+
* remasque — aussi a la sortie du champ, a l'envoi du formulaire et avant l'impression. Modifiable,
|
|
2860
|
+
* le champ montre la valeur en clair pendant la saisie et en erreur : on ne corrige pas des points.
|
|
2861
|
+
* En lecture seule, il reste masque meme en erreur ; sur papier, il est toujours masque.
|
|
682
2862
|
*
|
|
683
|
-
* ⚠️
|
|
684
|
-
*
|
|
685
|
-
*
|
|
2863
|
+
* ⚠️ **`aria-pressed` dit ce qui est A L'ECRAN** : vrai des que la valeur est en clair, quelle
|
|
2864
|
+
* qu'en soit la raison (revelation, saisie, erreur). Enfonce, le bouton masque : en saisie, il
|
|
2865
|
+
* prend le focus, et la sortie du champ masque la valeur (on ne tape pas dans des points). Le
|
|
2866
|
+
* fond enfonce et l'oeil barre, eux, disent la revelation A LA DEMANDE, pour sa duree. Le nom
|
|
2867
|
+
* « Reveler 30s » est complete par une description : l'etiquette du champ et la duree en toutes
|
|
2868
|
+
* lettres (« 30s » se lirait « thirties » en anglais).
|
|
686
2869
|
*
|
|
687
|
-
*
|
|
688
|
-
*
|
|
689
|
-
* de dire si le numero existe (SEC-5). `erreurTelephone` ne verifie que la forme.
|
|
2870
|
+
* Le glyphe `banque` en tete du cadre est DECORATIF : l'etiquette porte le sens. Chasse fixe a
|
|
2871
|
+
* zero barre (O et 0 ne se confondent plus), ilot de gauche a droite en ecriture inverse.
|
|
690
2872
|
*
|
|
691
|
-
* `
|
|
692
|
-
*
|
|
2873
|
+
* `autocapitalize="characters"` et correction orthographique coupee : un IBAN
|
|
2874
|
+
* n'est pas un mot, et une correction automatique le fausserait.
|
|
693
2875
|
*/
|
|
694
|
-
declare class
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
2876
|
+
export declare class StIbanField extends ControleDeSaisie {
|
|
2877
|
+
protected readonly libelles: import("@angular/core").Signal<import("@starterlib/ui").LibellesUi>;
|
|
2878
|
+
private readonly locale;
|
|
2879
|
+
private readonly element;
|
|
2880
|
+
protected readonly annonce: AnnonceLocale;
|
|
2881
|
+
/** Masque au repos, revelable pour `rythme.tenue.revelation` (un IBAN deja connu). */
|
|
2882
|
+
readonly masque: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
|
|
2883
|
+
private readonly detection;
|
|
2884
|
+
private readonly bouton;
|
|
2885
|
+
protected readonly idDuBouton: string;
|
|
2886
|
+
private readonly enSaisie;
|
|
2887
|
+
private readonly brut;
|
|
2888
|
+
protected readonly revele: import("@angular/core").WritableSignal<boolean>;
|
|
2889
|
+
/** Masque demande par le bouton alors que la valeur etait en clair (erreur). */
|
|
2890
|
+
private readonly masqueDemande;
|
|
2891
|
+
/** Impression en cours : sur papier, la valeur est masquee quoi qu'il arrive. */
|
|
2892
|
+
private readonly impression;
|
|
2893
|
+
private minuterie;
|
|
2894
|
+
/** L'exemple aide a TAPER : en lecture seule, il n'a rien a dire. */
|
|
2895
|
+
protected readonly aideLue: import("@angular/core").Signal<string | null>;
|
|
2896
|
+
/** « Reveler 30s » : la duree de la revelation dite dans le nom du bouton, qui ne change pas. */
|
|
2897
|
+
protected readonly libelleDuBouton: import("@angular/core").Signal<string>;
|
|
2898
|
+
/** Ce que le bouton revele, et pour combien de temps : « IBAN du compte : 30 secondes ». */
|
|
2899
|
+
protected readonly descriptionDuBouton: import("@angular/core").Signal<string>;
|
|
2900
|
+
/**
|
|
2901
|
+
* Masquee : au repos ; en lecture seule, meme au focus et meme en erreur ; toujours a
|
|
2902
|
+
* l'impression. Modifiable, jamais pendant la saisie ni en erreur — un IBAN refuse n'est pas un
|
|
2903
|
+
* IBAN connu, et on ne corrige pas des points (planche 3b) —, sauf masque demande par le bouton.
|
|
2904
|
+
*/
|
|
2905
|
+
protected readonly masquee: import("@angular/core").Signal<boolean>;
|
|
2906
|
+
/** Valeur en clair dans un champ `masque` : l'etat que dit le bouton bascule. */
|
|
2907
|
+
protected readonly enClair: import("@angular/core").Signal<boolean>;
|
|
2908
|
+
/**
|
|
2909
|
+
* Brut pendant la saisie ; groupe par quatre au repos ; masque si demande. Une valeur changee de
|
|
2910
|
+
* l'exterieur pendant la saisie — remise a zero du formulaire — l'emporte sur le brut, qui ne
|
|
2911
|
+
* la represente plus.
|
|
2912
|
+
*/
|
|
2913
|
+
protected readonly affichage: import("@angular/core").Signal<string>;
|
|
2914
|
+
constructor();
|
|
2915
|
+
protected auFocus(): void;
|
|
2916
|
+
protected surSaisie(evenement: Event): void;
|
|
2917
|
+
protected aLaSortie(): void;
|
|
2918
|
+
protected basculer(): void;
|
|
2919
|
+
protected remasquer(): void;
|
|
2920
|
+
/** Avant l'impression : masque, et rendu tout de suite (l'impression n'attend pas le rendu). */
|
|
2921
|
+
protected avantImpression(): void;
|
|
2922
|
+
protected apresImpression(): void;
|
|
2923
|
+
/**
|
|
2924
|
+
* Enfonce, le bouton masque. En saisie, la valeur ne se masque qu'a la sortie du champ (on ne
|
|
2925
|
+
* tape pas dans des points) : le focus passe au bouton, ou le clic l'avait laisse au champ.
|
|
2926
|
+
*/
|
|
2927
|
+
private masquerALaDemande;
|
|
2928
|
+
private duree;
|
|
2929
|
+
/** Le focus quitte le champ ET son bouton : la valeur revelee se remasque. */
|
|
2930
|
+
protected aLaSortieDuChamp(evenement: FocusEvent): void;
|
|
2931
|
+
private arreterLaMinuterie;
|
|
2932
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<StIbanField, never>;
|
|
2933
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<StIbanField, "st-iban-field", never, {
|
|
2934
|
+
"masque": {
|
|
2935
|
+
"alias": "masque";
|
|
2936
|
+
"required": false;
|
|
2937
|
+
"isSignal": true;
|
|
2938
|
+
};
|
|
2939
|
+
}, {}, never, ["[stMeta]", "[stAide]", "[stIndication]"], true, never>;
|
|
705
2940
|
}
|
|
706
|
-
|
|
707
2941
|
/**
|
|
708
|
-
*
|
|
709
|
-
*
|
|
710
|
-
*
|
|
711
|
-
* technique ne s'affiche jamais, et un libelle traduit ne s'envoie jamais.
|
|
2942
|
+
* `standard` : le controle pose sur la surface. `tonale` : le meme controle sur un fond teinte
|
|
2943
|
+
* (`surfaceConteneurBas`), sous le meme filet lisible (EA-07) : une barre de filtres, le compte
|
|
2944
|
+
* debiteur d'une coquille etroite (planches 10 et 6, D108).
|
|
712
2945
|
*/
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
}
|
|
720
|
-
/** Sans accents ni casse : « eleve » trouve « Élève ». */
|
|
721
|
-
declare function normaliserPourRecherche(texte: string): string;
|
|
722
|
-
/** Options dont le libelle CONTIENT le texte cherche, sans accents ni casse. */
|
|
723
|
-
declare function filtrerOptions(options: readonly OptionDeListe[], recherche: string): readonly OptionDeListe[];
|
|
724
|
-
|
|
725
|
-
interface BlocDOptions {
|
|
726
|
-
readonly groupe: string | null;
|
|
727
|
-
readonly options: readonly OptionDeListe[];
|
|
2946
|
+
export type VarianteDeSelect = 'standard' | 'tonale';
|
|
2947
|
+
interface BlocDOptions$1 {
|
|
2948
|
+
/** Identite stable du bloc : la valeur de sa premiere option. */
|
|
2949
|
+
readonly cle: string;
|
|
2950
|
+
readonly groupe: string | null;
|
|
2951
|
+
readonly options: readonly OptionDeListe[];
|
|
728
2952
|
}
|
|
729
2953
|
/**
|
|
730
2954
|
* Liste deroulante, sur un `select` NATIF.
|
|
@@ -743,45 +2967,120 @@ interface BlocDOptions {
|
|
|
743
2967
|
* option paraitrait choisie alors que personne ne l'a fait. Le modele vaut
|
|
744
2968
|
* alors `''`, que `required` refuse.
|
|
745
2969
|
*
|
|
746
|
-
* `readonly` n'existe pas sur un `select` : le champ annonce `aria-readonly
|
|
747
|
-
*
|
|
748
|
-
* l'ordre de tabulation, et sa valeur ne se lit plus.
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
2970
|
+
* `readonly` n'existe pas sur un `select` : le champ annonce `aria-readonly`, et le
|
|
2971
|
+
* selecteur ne s'ouvre plus (clic et touches annules) plutot que d'etre desactive — un
|
|
2972
|
+
* champ desactive sort de l'ordre de tabulation, et sa valeur ne se lit plus. Sans chevron :
|
|
2973
|
+
* une liste qui ne s'ouvre pas ne promet pas de s'ouvrir.
|
|
2974
|
+
*
|
|
2975
|
+
* ⚠️ **Une valeur absente des options n'est jamais tue** (A1131). Beneficiaire cloture,
|
|
2976
|
+
* options rechargees : le modele garde un identifiant qu'aucune option ne porte, et le
|
|
2977
|
+
* navigateur afficherait « Choisir… » pendant que le formulaire part avec la valeur
|
|
2978
|
+
* invisible. Elle s'affiche « Valeur non affichable » (option desactivee, choisie), et un
|
|
2979
|
+
* avertissement le dit en developpement — SANS la valeur, qui peut etre un compte ou un IBAN
|
|
2980
|
+
* (une valeur sensible n'est jamais journalisee).
|
|
2981
|
+
*/
|
|
2982
|
+
export declare class StSelect extends ControleDeSaisie {
|
|
2983
|
+
/**
|
|
2984
|
+
* Un texte de donnees : sans commande de direction, et isole par son element (`dir="auto"` ou
|
|
2985
|
+
* `<bdi>`), il ne reordonne ni lui-meme ni ce qui l'entoure (audit du 2026-09-26, S-1 ; audit
|
|
2986
|
+
* etendu du 2026-09-27, A-2).
|
|
2987
|
+
*/
|
|
2988
|
+
protected readonly affichable: typeof sansCommandesDeDirection;
|
|
2989
|
+
protected readonly libelles: import("@angular/core").Signal<import("@starterlib/ui").LibellesUi>;
|
|
2990
|
+
readonly options: import("@angular/core").InputSignal<readonly OptionDeListe[]>;
|
|
2991
|
+
/** Texte de l'option vide. Par defaut : « Choisir… ». */
|
|
2992
|
+
readonly texteVide: import("@angular/core").InputSignal<string | null>;
|
|
2993
|
+
/** WCAG 1.3.5 : `country`, `sex`, `honorific-prefix`… */
|
|
2994
|
+
readonly autocomplete: import("@angular/core").InputSignal<TypeDAutocompletion | null>;
|
|
2995
|
+
/** Glyphe decoratif de tete, dans le cadre (l'etiquette porte le sens). */
|
|
2996
|
+
readonly icone: import("@angular/core").InputSignal<"iban" | "code" | "devise" | "fichier" | "message" | "menu" | "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-qr" | "code-qr-scanner" | "coffre-fort" | "colonnes" | "connexion" | "contraste" | "copie" | "corbeille" | "corbeille-croix" | "courriel" | "crayon" | "croix" | "curseur-clic" | "deconnexion" | "disposition" | "dollar" | "dossier" | "dossier-barre" | "dossier-ouvert" | "double-coche" | "echange" | "eclair" | "empreinte-digitale" | "enregistrer" | "entree" | "envoyer" | "epaisseur-de-trait" | "epingle" | "etoile" | "euro" | "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" | "imprimer" | "interdit" | "jalons" | "jauge" | "lien" | "lien-externe" | "lignes" | "lignes-crayon" | "liste" | "liste-coche" | "liste-controle" | "liste-numerotee" | "luminosite" | "lune" | "maillet" | "maison" | "marque-page" | "menu-ouvert" | "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>;
|
|
2997
|
+
/** Le style de l'etiquette (voir `st-form-field`). */
|
|
2998
|
+
readonly presentation: import("@angular/core").InputSignal<PresentationDeLibelle>;
|
|
2999
|
+
/**
|
|
3000
|
+
* `tonale` pose le controle sur un fond teinte, memes etats et meme filet (D108). La lecture
|
|
3001
|
+
* seule et la desactivation gardent leur fond propre : elles se lisent d'abord.
|
|
3002
|
+
*/
|
|
3003
|
+
readonly variante: import("@angular/core").InputSignal<VarianteDeSelect>;
|
|
3004
|
+
/** Options consecutives d'un meme groupe, dans l'ordre fourni. */
|
|
3005
|
+
protected readonly blocs: import("@angular/core").Signal<readonly BlocDOptions$1[]>;
|
|
3006
|
+
/** La valeur du modele, quand aucune option ne la porte (sinon `null`). */
|
|
3007
|
+
protected readonly valeurInconnue: import("@angular/core").Signal<string | null>;
|
|
3008
|
+
constructor();
|
|
3009
|
+
/** Lecture seule : le selecteur ne s'ouvre pas au clic (le focus, lui, se prend). */
|
|
3010
|
+
protected surPression(evenement: MouseEvent): void;
|
|
3011
|
+
/** Lecture seule : ni Espace, ni Entree, ni fleches, ni lettres ne changent la valeur. */
|
|
3012
|
+
protected surTouche(evenement: KeyboardEvent): void;
|
|
3013
|
+
protected surChoix(evenement: Event): void;
|
|
3014
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<StSelect, never>;
|
|
3015
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<StSelect, "st-select", never, {
|
|
3016
|
+
"options": {
|
|
3017
|
+
"alias": "options";
|
|
3018
|
+
"required": true;
|
|
3019
|
+
"isSignal": true;
|
|
3020
|
+
};
|
|
3021
|
+
"texteVide": {
|
|
3022
|
+
"alias": "texteVide";
|
|
3023
|
+
"required": false;
|
|
3024
|
+
"isSignal": true;
|
|
3025
|
+
};
|
|
3026
|
+
"autocomplete": {
|
|
3027
|
+
"alias": "autocomplete";
|
|
3028
|
+
"required": false;
|
|
3029
|
+
"isSignal": true;
|
|
3030
|
+
};
|
|
3031
|
+
"icone": {
|
|
3032
|
+
"alias": "icone";
|
|
3033
|
+
"required": false;
|
|
3034
|
+
"isSignal": true;
|
|
3035
|
+
};
|
|
3036
|
+
"presentation": {
|
|
3037
|
+
"alias": "presentation";
|
|
3038
|
+
"required": false;
|
|
3039
|
+
"isSignal": true;
|
|
3040
|
+
};
|
|
3041
|
+
"variante": {
|
|
3042
|
+
"alias": "variante";
|
|
3043
|
+
"required": false;
|
|
3044
|
+
"isSignal": true;
|
|
3045
|
+
};
|
|
3046
|
+
}, {}, never, ["[stMeta]", "[stAide]", "[stIndication]"], true, never>;
|
|
762
3047
|
}
|
|
763
|
-
|
|
3048
|
+
/**
|
|
3049
|
+
* Disque plein d'un jour : borne de debut ou de fin d'une plage (capsule d'un cote), ou date
|
|
3050
|
+
* seule (jour choisi, plage d'un jour, borne sans son autre).
|
|
3051
|
+
*/
|
|
3052
|
+
type Borne = 'debut' | 'fin' | 'seule';
|
|
764
3053
|
interface Jour {
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
3054
|
+
readonly date: DateIso;
|
|
3055
|
+
/** Jour d'un mois voisin : cellule vide, la date vit dans son propre mois. */
|
|
3056
|
+
readonly horsDuMois: boolean;
|
|
3057
|
+
readonly numero: string;
|
|
3058
|
+
readonly nom: string;
|
|
3059
|
+
readonly horsBornes: boolean;
|
|
3060
|
+
readonly borne: Borne | null;
|
|
3061
|
+
readonly dansLaPlage: boolean;
|
|
3062
|
+
readonly aujourdHui: boolean;
|
|
3063
|
+
readonly rejete: boolean;
|
|
3064
|
+
}
|
|
3065
|
+
/** Annees offertes par le saut d'annee, bornes comprises. */
|
|
3066
|
+
export interface AnneesDuCalendrier {
|
|
3067
|
+
readonly min: number;
|
|
3068
|
+
readonly max: number;
|
|
774
3069
|
}
|
|
775
3070
|
/**
|
|
776
|
-
* Calendrier d'un mois, pour choisir une date.
|
|
3071
|
+
* Calendrier d'un mois, pour choisir une date ou montrer une periode.
|
|
777
3072
|
*
|
|
778
3073
|
* ```html
|
|
779
3074
|
* <st-calendar [selection]="depart()" dateMin="2026-09-17" (choix)="depart.set($event)" />
|
|
3075
|
+
* <st-calendar pleineLargeur [plage]="periode()" [annees]="{ min: 1900, max: 2026 }">
|
|
3076
|
+
* <span stPied>Periode : 8 jours</span>
|
|
3077
|
+
* </st-calendar>
|
|
780
3078
|
* ```
|
|
781
3079
|
*
|
|
782
3080
|
* ⚠️ **Une aide, jamais la seule voie.** Dans `st-date-field`, le calendrier
|
|
783
3081
|
* complete un champ texte : une date de naissance se tape plus vite qu'elle ne se
|
|
784
|
-
* cherche mois par mois, et un calendrier reste penible au lecteur d'ecran.
|
|
3082
|
+
* cherche mois par mois, et un calendrier reste penible au lecteur d'ecran. Le saut
|
|
3083
|
+
* d'annee (liste native) evite les quarante Maj + Page d'une date de naissance.
|
|
785
3084
|
*
|
|
786
3085
|
* ⚠️ **Le clavier navigue de DATE en date, pas de cellule en cellule** (decision
|
|
787
3086
|
* D7 de l'audit de la vague 3). Fleche droite le 30 septembre mene au 1er
|
|
@@ -790,71 +3089,179 @@ interface Jour {
|
|
|
790
3089
|
* entre cellules affichees : il aurait fallu la contourner sur chaque touche qui
|
|
791
3090
|
* compte, et elle aurait fait entrer le CDK dans les formulaires.
|
|
792
3091
|
*
|
|
793
|
-
*
|
|
794
|
-
*
|
|
795
|
-
*
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
3092
|
+
* ⚠️ **Echap n'appartient au calendrier que s'il est `fermable`** (pose par
|
|
3093
|
+
* `st-date-field` et `st-date-range`) : il la consomme alors, et l'arrete — sans quoi le
|
|
3094
|
+
* `st-dialog` qui contient le formulaire se fermerait avec lui. Seul, il la laisse passer.
|
|
3095
|
+
*
|
|
3096
|
+
* ⚠️ **Un clic ne deplace pas le focus** (`mousedown` annule partout, sauf sur la liste
|
|
3097
|
+
* d'annees) : sous WebKit, un bouton clique ne prend pas le focus mais retire celui de l'element
|
|
3098
|
+
* actif, et un clic dans le blanc le donnait a l'ancetre focalisable (`cdk-dialog-container`) ;
|
|
3099
|
+
* le conteneur qui ferme a la sortie du focus retirait le calendrier avant le clic. Quand le
|
|
3100
|
+
* focus est dans la grille, un changement de mois ou un choix au clic le pose sur la nouvelle
|
|
3101
|
+
* date active : le bouton du jour qui le portait disparait avec son mois.
|
|
3102
|
+
*
|
|
3103
|
+
* Reference Claude Design (planches 3a et 3b) : bornes et jour choisi en disques pleins de
|
|
3104
|
+
* 40 px, capsule de plage coupee carrement au changement de ligne, aujourd'hui marque d'un point.
|
|
3105
|
+
* Semaine commencant au jour de la locale, noms de jours et de mois dans la langue courante,
|
|
3106
|
+
* « aujourd'hui » dans le fuseau de la personne (`FUSEAU_PAR_DEFAUT`) et non celui du poste,
|
|
3107
|
+
* relu a chaque prise de focus (un calendrier ouvert la veille ne garde pas la veille).
|
|
3108
|
+
*/
|
|
3109
|
+
export declare class StCalendar {
|
|
3110
|
+
protected readonly libelles: import("@angular/core").Signal<import("@starterlib/ui").LibellesUi>;
|
|
3111
|
+
private readonly locale;
|
|
3112
|
+
private readonly fuseau;
|
|
3113
|
+
private readonly element;
|
|
3114
|
+
private readonly injecteur;
|
|
3115
|
+
private readonly aujourdHui;
|
|
3116
|
+
readonly selection: import("@angular/core").InputSignal<string | null>;
|
|
3117
|
+
readonly dateMin: import("@angular/core").InputSignal<string | null>;
|
|
3118
|
+
readonly dateMax: import("@angular/core").InputSignal<string | null>;
|
|
3119
|
+
/** Periode a faire ressortir, pour un choix de plage. */
|
|
3120
|
+
readonly plage: import("@angular/core").InputSignal<PlageDeDates | null>;
|
|
3121
|
+
/**
|
|
3122
|
+
* Date refusee par une regle de l'application (validation differee) : tuile rouge barree. La
|
|
3123
|
+
* raison se dit dans le pied (`[stPied]`), en texte.
|
|
3124
|
+
*/
|
|
3125
|
+
readonly rejet: import("@angular/core").InputSignal<string | null>;
|
|
3126
|
+
/**
|
|
3127
|
+
* Annees du saut d'annee. Par defaut : celles des bornes, sinon dix ans de part et d'autre
|
|
3128
|
+
* de l'annee courante. Une date de naissance passe `{ min: 1900, max: <annee courante> }`.
|
|
3129
|
+
*/
|
|
3130
|
+
readonly annees: import("@angular/core").InputSignal<AnneesDuCalendrier | null>;
|
|
3131
|
+
/** Occupe la largeur de son conteneur (cases fluides, 44 px de haut) : calendrier deploye. */
|
|
3132
|
+
readonly pleineLargeur: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
|
|
3133
|
+
/** Un conteneur ecoute `fermeture` : Echap lui appartient, et l'aide le dit. */
|
|
3134
|
+
readonly fermable: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
|
|
3135
|
+
readonly choix: import("@angular/core").OutputEmitterRef<string>;
|
|
3136
|
+
/** Echap (calendrier `fermable`) : le conteneur decide de fermer, et ou rendre le focus. */
|
|
3137
|
+
readonly fermeture: import("@angular/core").OutputEmitterRef<void>;
|
|
3138
|
+
protected readonly identifiants: {
|
|
3139
|
+
readonly titre: `${string}-titre`;
|
|
3140
|
+
readonly aide: `${string}-aide`;
|
|
3141
|
+
readonly pied: `${string}-pied`;
|
|
3142
|
+
};
|
|
3143
|
+
/** La date qui porte le focus. Suit la selection, bornee. */
|
|
3144
|
+
private readonly active;
|
|
3145
|
+
private readonly premierJour;
|
|
3146
|
+
protected readonly anneeActive: import("@angular/core").Signal<number>;
|
|
3147
|
+
protected readonly titre: import("@angular/core").Signal<string>;
|
|
3148
|
+
protected readonly listeDAnnees: import("@angular/core").Signal<readonly number[]>;
|
|
3149
|
+
/** « Lun », « Mar » : l'abreviation de la langue, sans son point, a l'initiale. */
|
|
3150
|
+
protected readonly joursDeLaSemaine: import("@angular/core").Signal<{
|
|
3151
|
+
court: string;
|
|
3152
|
+
long: string;
|
|
3153
|
+
}[]>;
|
|
3154
|
+
protected readonly semaines: import("@angular/core").Signal<readonly (readonly Jour[])[]>;
|
|
3155
|
+
protected readonly moisPrecedentPossible: import("@angular/core").Signal<boolean>;
|
|
3156
|
+
protected readonly moisSuivantPossible: import("@angular/core").Signal<boolean>;
|
|
3157
|
+
constructor();
|
|
3158
|
+
protected estActive(date: DateIso): boolean;
|
|
3159
|
+
/** Amene le focus sur la date active. */
|
|
3160
|
+
focus(): void;
|
|
3161
|
+
protected relireAujourdHui(): void;
|
|
3162
|
+
protected changerDeMois(ecart: number): void;
|
|
3163
|
+
protected changerDAnnee(evenement: Event): void;
|
|
3164
|
+
protected choisir(jour: Jour): void;
|
|
3165
|
+
/** Un clic ne deplace pas le focus, sauf sur la liste d'annees (liste native a ouvrir). */
|
|
3166
|
+
protected surAppui(evenement: MouseEvent): void;
|
|
3167
|
+
private focusDansLaGrille;
|
|
3168
|
+
private focusApresRendu;
|
|
3169
|
+
protected surTouche(evenement: KeyboardEvent): void;
|
|
3170
|
+
/**
|
|
3171
|
+
* Le sens d'ecriture HERITE, sans style calcule (ni global `getComputedStyle`, ni mise en
|
|
3172
|
+
* page) : `:dir()` quand le moteur le connait, sinon l'attribut `dir` le plus proche.
|
|
3173
|
+
*/
|
|
3174
|
+
private ecritDeDroiteAGauche;
|
|
3175
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<StCalendar, never>;
|
|
3176
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<StCalendar, "st-calendar", never, {
|
|
3177
|
+
"selection": {
|
|
3178
|
+
"alias": "selection";
|
|
3179
|
+
"required": false;
|
|
3180
|
+
"isSignal": true;
|
|
3181
|
+
};
|
|
3182
|
+
"dateMin": {
|
|
3183
|
+
"alias": "dateMin";
|
|
3184
|
+
"required": false;
|
|
3185
|
+
"isSignal": true;
|
|
3186
|
+
};
|
|
3187
|
+
"dateMax": {
|
|
3188
|
+
"alias": "dateMax";
|
|
3189
|
+
"required": false;
|
|
3190
|
+
"isSignal": true;
|
|
3191
|
+
};
|
|
3192
|
+
"plage": {
|
|
3193
|
+
"alias": "plage";
|
|
3194
|
+
"required": false;
|
|
3195
|
+
"isSignal": true;
|
|
3196
|
+
};
|
|
3197
|
+
"rejet": {
|
|
3198
|
+
"alias": "rejet";
|
|
3199
|
+
"required": false;
|
|
3200
|
+
"isSignal": true;
|
|
3201
|
+
};
|
|
3202
|
+
"annees": {
|
|
3203
|
+
"alias": "annees";
|
|
3204
|
+
"required": false;
|
|
3205
|
+
"isSignal": true;
|
|
3206
|
+
};
|
|
3207
|
+
"pleineLargeur": {
|
|
3208
|
+
"alias": "pleineLargeur";
|
|
3209
|
+
"required": false;
|
|
3210
|
+
"isSignal": true;
|
|
3211
|
+
};
|
|
3212
|
+
"fermable": {
|
|
3213
|
+
"alias": "fermable";
|
|
3214
|
+
"required": false;
|
|
3215
|
+
"isSignal": true;
|
|
3216
|
+
};
|
|
3217
|
+
}, {
|
|
3218
|
+
"choix": "choix";
|
|
3219
|
+
"fermeture": "fermeture";
|
|
3220
|
+
}, never, ["[stPied]"], true, never>;
|
|
834
3221
|
}
|
|
835
|
-
|
|
836
3222
|
/**
|
|
837
3223
|
* Cle d'un fichier choisi : deux choix du meme fichier ne l'ajoutent pas deux
|
|
838
3224
|
* fois, et l'application s'en sert pour dire ou en est chaque televersement.
|
|
839
3225
|
*/
|
|
840
|
-
declare function cleDeFichier(fichier: File): string;
|
|
3226
|
+
export declare function cleDeFichier(fichier: File): string;
|
|
841
3227
|
/**
|
|
842
3228
|
* Ou en est un fichier, vu de l'application. `message` dit POURQUOI un fichier
|
|
843
3229
|
* est refuse — « antivirus indisponible » et « type refuse » n'appellent pas la
|
|
844
3230
|
* meme suite (UX-3 de la 0.6.0).
|
|
845
3231
|
*/
|
|
846
|
-
interface EtatDeTeleversementAffiche {
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
3232
|
+
export interface EtatDeTeleversementAffiche {
|
|
3233
|
+
readonly etape: 'en-cours' | 'depose' | 'refuse';
|
|
3234
|
+
/** 0 a 100, pendant l'envoi. */
|
|
3235
|
+
readonly progression?: number;
|
|
3236
|
+
/** Ce que dit la ligne sous le nom : « Chiffrement en cours... », la raison d'un refus. */
|
|
3237
|
+
readonly message?: string;
|
|
3238
|
+
/**
|
|
3239
|
+
* Texte court en fin de ligne : debit, duree, verdict (« 68 % (1,4 Mo/s) »). Par defaut, le
|
|
3240
|
+
* pourcentage pendant l'envoi, et rien ensuite.
|
|
3241
|
+
*/
|
|
3242
|
+
readonly detail?: string;
|
|
3243
|
+
/**
|
|
3244
|
+
* Pendant l'envoi : `false` quand il ne peut plus etre interrompu (confirmation du depot en
|
|
3245
|
+
* cours). Le bouton « Annuler » n'est alors pas rendu. Vrai par defaut.
|
|
3246
|
+
*/
|
|
3247
|
+
readonly annulable?: boolean;
|
|
3248
|
+
}
|
|
3249
|
+
/** Un morceau d'une phrase affichee : du texte, ou un nom de fichier a isoler. */
|
|
3250
|
+
interface MorceauDePhrase {
|
|
3251
|
+
readonly texte: string;
|
|
3252
|
+
readonly nom: boolean;
|
|
3253
|
+
}
|
|
3254
|
+
/** Des fichiers ecartes par `nombreMax` : leur phrase (annonce, presence), et ses morceaux. */
|
|
3255
|
+
interface RefusDuNombre {
|
|
3256
|
+
readonly texte: string;
|
|
3257
|
+
readonly morceaux: readonly MorceauDePhrase[];
|
|
851
3258
|
}
|
|
852
3259
|
/**
|
|
853
3260
|
* Choix de fichiers, sur un `input type="file"` natif.
|
|
854
3261
|
*
|
|
855
3262
|
* ```html
|
|
856
3263
|
* <st-file-upload libelle="Justificatifs" accept=".pdf, image/*" [tailleMax]="5_000_000" multiple
|
|
857
|
-
* [formField]="dossier.pieces" />
|
|
3264
|
+
* [nombreMax]="3" [formField]="dossier.pieces" />
|
|
858
3265
|
* <!-- schema : validate(chemin.pieces, ({ value }) => erreursDeFichiers(value(), regles)) -->
|
|
859
3266
|
* ```
|
|
860
3267
|
*
|
|
@@ -863,62 +3270,537 @@ interface EtatDeTeleversementAffiche {
|
|
|
863
3270
|
*
|
|
864
3271
|
* ⚠️ **L'element natif reste la voie principale** (FE-4) : il ouvre le selecteur
|
|
865
3272
|
* du systeme, l'appareil photo sur mobile, et se commande au clavier. Il est
|
|
866
|
-
* masque visuellement, pas retire : le bouton affiche est son
|
|
867
|
-
* depot par glisser est un complement
|
|
3273
|
+
* masque visuellement, pas retire : le bouton affiche est son substitut a la souris,
|
|
3274
|
+
* et montre son focus. Le depot par glisser est un complement, jamais la seule voie
|
|
3275
|
+
* (WCAG 2.5.7).
|
|
868
3276
|
*
|
|
869
3277
|
* ⚠️ **Aucun apercu d'image** (SEC-7). Un apercu passe par une adresse `blob:`
|
|
870
3278
|
* que la politique de securite du contenu doit autoriser, et un SVG affiche peut
|
|
871
3279
|
* porter du script. Le nom et la taille suffisent a reconnaitre un fichier.
|
|
872
3280
|
*
|
|
873
|
-
* ⚠️
|
|
874
|
-
*
|
|
875
|
-
*
|
|
3281
|
+
* ⚠️ **Les noms s'affichent sans commandes de direction** (`nomAffichable`) : un
|
|
3282
|
+
* `facture\u202efdp.exe` ne se presente pas en PDF, ni a l'ecran, ni dans les etiquettes, ni
|
|
3283
|
+
* dans les annonces. Cite dans une phrase du dictionnaire (un statut, des fichiers ecartes), le
|
|
3284
|
+
* nom est en plus isole dans son ilot de gauche a droite : la phrase ne se reordonne pas autour
|
|
3285
|
+
* d'un nom en hebreu ou en arabe (audit UI du 2026-09-27, D-4).
|
|
876
3286
|
*
|
|
877
|
-
*
|
|
878
|
-
*
|
|
879
|
-
*
|
|
3287
|
+
* ⚠️ **`accept`, `tailleMax` et `nombreMax` sont un confort** (SEC-5) : ils
|
|
3288
|
+
* s'affichent en consignes et filtrent le choix, mais la verification est dans le schema —
|
|
3289
|
+
* `erreursDeFichiers` —, et le serveur relit le contenu.
|
|
3290
|
+
*
|
|
3291
|
+
* ⚠️ **`readonly` ne desactive pas** : le champ natif reste dans la tabulation (sa liste se
|
|
3292
|
+
* parcourt et se lit) et n'ouvre ni selecteur ni depot ; les retraits sont indisponibles
|
|
3293
|
+
* (`aria-disabled`), pas retires. Chromium expose `input type="file"` en role `button`, qui ne
|
|
3294
|
+
* prend pas `aria-readonly` en charge : le champ natif porte donc `aria-disabled` (focalisable,
|
|
3295
|
+
* annonce indisponible), et le substitut dit « Lecture seule », lu en description.
|
|
3296
|
+
*
|
|
3297
|
+
* Chaque changement s'annonce : « 2 fichiers choisis. », « X depose. », « X refuse : raison. ».
|
|
3298
|
+
* Des fichiers qui changent d'etat ensemble se disent en UNE annonce (D-15). Les fichiers ecartes
|
|
3299
|
+
* par `nombreMax` sont NOMMES en texte visible, en liste de la langue, relie au champ natif, et
|
|
3300
|
+
* l'annonce reprend ce texte. Un fichier retire rend le focus au bouton de retrait suivant, ou au
|
|
3301
|
+
* choix de fichiers ; un fichier remplace, au bouton de sa nouvelle ligne : le focus ne tombe
|
|
3302
|
+
* jamais sur le document.
|
|
880
3303
|
*
|
|
881
3304
|
* ⚠️ **Il ne televerse pas.** `etats` dit ou en est chaque fichier, et le bouton
|
|
882
|
-
* de la ligne devient « Annuler » pendant l'envoi :
|
|
3305
|
+
* de la ligne devient « Annuler » pendant l'envoi (le MEME bouton : il garde le focus a
|
|
3306
|
+
* l'arrivee ; absent quand l'envoi n'est plus annulable, le focus passant alors au choix de
|
|
3307
|
+
* fichiers) : le trajet — declaration, depot
|
|
883
3308
|
* pre-signe, confirmation antivirus — vit dans `StTeleversement`
|
|
884
3309
|
* (`@starterlib/core`), seul a parler au reseau.
|
|
885
3310
|
*/
|
|
886
|
-
declare class StFileUpload extends ContratDeChamp implements FormValueControl<readonly File[]> {
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
3311
|
+
export declare class StFileUpload extends ContratDeChamp implements FormValueControl<readonly File[]> {
|
|
3312
|
+
protected readonly libelles: import("@angular/core").Signal<LibellesUi>;
|
|
3313
|
+
private readonly locale;
|
|
3314
|
+
private readonly element;
|
|
3315
|
+
private readonly document;
|
|
3316
|
+
private readonly injecteur;
|
|
3317
|
+
private readonly natif;
|
|
3318
|
+
readonly value: import("@angular/core").ModelSignal<readonly File[]>;
|
|
3319
|
+
/** Attribut `accept` natif : `.pdf, image/*`. Dit en clair dans les consignes. */
|
|
3320
|
+
readonly accept: import("@angular/core").InputSignal<string>;
|
|
3321
|
+
readonly multiple: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
|
|
3322
|
+
/** En octets. Dit dans les consignes ; la verification est dans le schema. */
|
|
3323
|
+
readonly tailleMax: import("@angular/core").InputSignal<number | null>;
|
|
3324
|
+
/**
|
|
3325
|
+
* Nombre de fichiers au plus, en choix multiple : dit dans les consignes, et un choix qui le
|
|
3326
|
+
* depasse n'ajoute que ce qui tient ; les fichiers ecartes sont nommes en texte visible.
|
|
3327
|
+
*/
|
|
3328
|
+
readonly nombreMax: import("@angular/core").InputSignal<number | null>;
|
|
3329
|
+
/** Texte du bouton de choix. `null` : « Choisir un fichier » ou « Choisir des fichiers ». */
|
|
3330
|
+
readonly libelleDuChoix: import("@angular/core").InputSignal<string | null>;
|
|
3331
|
+
/**
|
|
3332
|
+
* Ou en est chaque fichier, par `cleDeFichier`. Le composant AFFICHE ce trajet,
|
|
3333
|
+
* il ne le fait pas : `StTeleversement` de `@starterlib/core` s'en charge.
|
|
3334
|
+
*/
|
|
3335
|
+
readonly etats: import("@angular/core").InputSignal<ReadonlyMap<string, EtatDeTeleversementAffiche> | null>;
|
|
3336
|
+
/** Emis quand la personne interrompt un envoi : c'est l'application qui annule. */
|
|
3337
|
+
readonly annulation: import("@angular/core").OutputEmitterRef<File>;
|
|
3338
|
+
/**
|
|
3339
|
+
* Emis avec le fichier REMPLACE (« Remplacer » d'une ligne refusee), une fois le nouveau
|
|
3340
|
+
* choisi : l'application oublie son etat, le nouveau fichier est deja dans le modele.
|
|
3341
|
+
*/
|
|
3342
|
+
readonly remplacement: import("@angular/core").OutputEmitterRef<File>;
|
|
3343
|
+
protected readonly annonce: AnnonceLocale;
|
|
3344
|
+
protected readonly survol: import("@angular/core").WritableSignal<boolean>;
|
|
3345
|
+
private readonly identifiants;
|
|
3346
|
+
protected readonly identifiantDesConsignes: string;
|
|
3347
|
+
protected readonly identifiantDeLaLecture: string;
|
|
3348
|
+
protected readonly identifiantDuRefus: string;
|
|
3349
|
+
/** « c.pdf non ajoute : 2 fichiers au plus. », jusqu'au prochain choix ou retrait. */
|
|
3350
|
+
protected readonly refusDuNombre: import("@angular/core").WritableSignal<RefusDuNombre | null>;
|
|
3351
|
+
/** `dragenter` et `dragleave` se repondent a chaque enfant survole : on les compte. */
|
|
3352
|
+
private entreesDuGlisser;
|
|
3353
|
+
/** L'indice de la ligne a remplacer, le temps que le selecteur du systeme reponde. */
|
|
3354
|
+
private aRemplacer;
|
|
3355
|
+
/** Choix et depot ouverts : ni desactive, ni en lecture seule. */
|
|
3356
|
+
protected readonly ouvert: import("@angular/core").Signal<boolean>;
|
|
3357
|
+
protected readonly texteDuChoix: import("@angular/core").Signal<string>;
|
|
3358
|
+
/** Aide, types acceptes, taille et nombre au plus, raisons de desactivation. */
|
|
3359
|
+
protected readonly consignes: import("@angular/core").Signal<string | null>;
|
|
3360
|
+
protected readonly descriptionsDesConsignes: import("@angular/core").Signal<string[]>;
|
|
3361
|
+
protected readonly lignes: import("@angular/core").Signal<{
|
|
3362
|
+
fichier: File;
|
|
3363
|
+
cle: string;
|
|
3364
|
+
nom: string;
|
|
3365
|
+
etape: "en-cours" | "depose" | "refuse" | null;
|
|
3366
|
+
icone: "iban" | "code" | "devise" | "fichier" | "message" | "menu" | "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-qr" | "code-qr-scanner" | "coffre-fort" | "colonnes" | "connexion" | "contraste" | "copie" | "corbeille" | "corbeille-croix" | "courriel" | "crayon" | "croix" | "curseur-clic" | "deconnexion" | "disposition" | "dollar" | "dossier" | "dossier-barre" | "dossier-ouvert" | "double-coche" | "echange" | "eclair" | "empreinte-digitale" | "enregistrer" | "entree" | "envoyer" | "epaisseur-de-trait" | "epingle" | "etoile" | "euro" | "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" | "imprimer" | "interdit" | "jalons" | "jauge" | "lien" | "lien-externe" | "lignes" | "lignes-crayon" | "liste" | "liste-coche" | "liste-controle" | "liste-numerotee" | "luminosite" | "lune" | "maillet" | "maison" | "marque-page" | "menu-ouvert" | "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";
|
|
3367
|
+
statut: string | null;
|
|
3368
|
+
morceauxDuStatut: readonly MorceauDePhrase[] | null;
|
|
3369
|
+
detail: string | null;
|
|
3370
|
+
progression: number | null;
|
|
3371
|
+
taille: string;
|
|
3372
|
+
annulable: boolean;
|
|
3373
|
+
}[]>;
|
|
3374
|
+
constructor();
|
|
3375
|
+
/** Le substitut, a la souris : il ouvre le selecteur du champ natif. */
|
|
3376
|
+
protected ouvrir(): void;
|
|
3377
|
+
/** En lecture seule, le champ natif garde le focus mais n'ouvre pas le selecteur. */
|
|
3378
|
+
protected surClicDuNatif(evenement: MouseEvent): void;
|
|
3379
|
+
protected surChoix(evenement: Event): void;
|
|
3380
|
+
/** Le selecteur ferme sans choix : un « Remplacer » en attente est oublie. */
|
|
3381
|
+
protected surAbandon(): void;
|
|
3382
|
+
protected surEntreeDuGlisser(evenement: DragEvent): void;
|
|
3383
|
+
/**
|
|
3384
|
+
* ⚠️ `preventDefault` sur CHAQUE `dragover`, sans quoi le navigateur ne delivre pas `drop`
|
|
3385
|
+
* (et ouvre le fichier a la place de la page). Fermee, la zone le dit par `dropEffect`.
|
|
3386
|
+
*/
|
|
3387
|
+
protected surSurvol(evenement: DragEvent): void;
|
|
3388
|
+
protected surSortieDuGlisser(): void;
|
|
3389
|
+
protected surDepot(evenement: DragEvent): void;
|
|
3390
|
+
/** « Remplacer » d'une ligne : le prochain choix prend sa place. */
|
|
3391
|
+
protected remplacer(indice: number): void;
|
|
3392
|
+
/** Le bouton de la ligne : annuler pendant l'envoi, retirer sinon. */
|
|
3393
|
+
protected agirSurLaLigne(fichier: File, etape: EtatDeTeleversementAffiche['etape'] | null, annulable: boolean, indice: number): void;
|
|
3394
|
+
protected retirer(indice: number): void;
|
|
3395
|
+
protected aLaSortie(evenement: FocusEvent): void;
|
|
3396
|
+
/**
|
|
3397
|
+
* UNE annonce pour tous les fichiers qui changent d'etat ensemble : `annoncer` remplace le texte
|
|
3398
|
+
* encore en attente, et une annonce par fichier ne laissait dire que le dernier (audit UI du
|
|
3399
|
+
* 2026-09-27, D-15). Les fichiers deposes en une phrase, leurs noms en liste de la langue, puis
|
|
3400
|
+
* chaque refus avec sa raison.
|
|
3401
|
+
*/
|
|
3402
|
+
private annonceDesEtapes;
|
|
3403
|
+
/** Le refus d'un fichier, et sa raison quand elle n'est pas la phrase du dictionnaire. */
|
|
3404
|
+
private phraseDuRefus;
|
|
3405
|
+
/** Les fichiers ecartes par `nombreMax`, nommes ; chaque nom isole a l'affichage (D-4). */
|
|
3406
|
+
private refusDuNombreMax;
|
|
3407
|
+
private remplacerA;
|
|
3408
|
+
private ajouter;
|
|
3409
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<StFileUpload, never>;
|
|
3410
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<StFileUpload, "st-file-upload", never, {
|
|
3411
|
+
"value": {
|
|
3412
|
+
"alias": "value";
|
|
3413
|
+
"required": false;
|
|
3414
|
+
"isSignal": true;
|
|
3415
|
+
};
|
|
3416
|
+
"accept": {
|
|
3417
|
+
"alias": "accept";
|
|
3418
|
+
"required": false;
|
|
3419
|
+
"isSignal": true;
|
|
3420
|
+
};
|
|
3421
|
+
"multiple": {
|
|
3422
|
+
"alias": "multiple";
|
|
3423
|
+
"required": false;
|
|
3424
|
+
"isSignal": true;
|
|
3425
|
+
};
|
|
3426
|
+
"tailleMax": {
|
|
3427
|
+
"alias": "tailleMax";
|
|
3428
|
+
"required": false;
|
|
3429
|
+
"isSignal": true;
|
|
3430
|
+
};
|
|
3431
|
+
"nombreMax": {
|
|
3432
|
+
"alias": "nombreMax";
|
|
3433
|
+
"required": false;
|
|
3434
|
+
"isSignal": true;
|
|
3435
|
+
};
|
|
3436
|
+
"libelleDuChoix": {
|
|
3437
|
+
"alias": "libelleDuChoix";
|
|
3438
|
+
"required": false;
|
|
3439
|
+
"isSignal": true;
|
|
3440
|
+
};
|
|
3441
|
+
"etats": {
|
|
3442
|
+
"alias": "etats";
|
|
3443
|
+
"required": false;
|
|
3444
|
+
"isSignal": true;
|
|
3445
|
+
};
|
|
3446
|
+
}, {
|
|
3447
|
+
"value": "valueChange";
|
|
3448
|
+
"annulation": "annulation";
|
|
3449
|
+
"remplacement": "remplacement";
|
|
3450
|
+
}, never, never, true, never>;
|
|
3451
|
+
}
|
|
3452
|
+
/**
|
|
3453
|
+
* Plusieurs valeurs LIBRES (courriels a notifier, references, mots-cles), en etiquettes
|
|
3454
|
+
* retirables : ni `st-multiselect` (options fermees) ni `st-input` ne le permettent (lot 252,
|
|
3455
|
+
* ADR 0005 D78, D79, D81).
|
|
3456
|
+
*
|
|
3457
|
+
* ```html
|
|
3458
|
+
* <st-tag-input
|
|
3459
|
+
* libelle="Adresses a notifier"
|
|
3460
|
+
* [valider]="adresseValide"
|
|
3461
|
+
* [nombreMax]="5"
|
|
3462
|
+
* [formField]="notification.adresses"
|
|
3463
|
+
* />
|
|
3464
|
+
* ```
|
|
3465
|
+
*
|
|
3466
|
+
* - Entree ajoute le texte tape, sans soumettre le formulaire englobant ; chaque separateur
|
|
3467
|
+
* aussi (`,` et `;` par defaut), sans s'ecrire. Rien pendant une composition IME : l'Entree
|
|
3468
|
+
* qui la clot valide la composition, pas la valeur.
|
|
3469
|
+
* - Un collage qui contient des separateurs (ou des fins de ligne) ajoute chaque valeur.
|
|
3470
|
+
* - ⚠️ **Le texte en attente reste dans le champ** : jamais ajoute implicitement, ni a la sortie
|
|
3471
|
+
* du champ ni a l'envoi du formulaire. Une valeur ajoutee sans geste serait une valeur que la
|
|
3472
|
+
* personne n'a pas choisie.
|
|
3473
|
+
* - Un doublon, une valeur que `valider` ecarte et une valeur au-dela de `nombreMax` n'entrent
|
|
3474
|
+
* pas : le texte reste a corriger, un message local le dit en texte visible, relie au champ,
|
|
3475
|
+
* et l'annonce le reprend.
|
|
3476
|
+
* - Les valeurs sont un `st-tag-group` nomme par le libelle du champ ; chaque retrait est nomme
|
|
3477
|
+
* par `retirerLEtiquette` (« Retirer x »), rend le focus a la valeur suivante, sinon a la
|
|
3478
|
+
* precedente, sinon au champ. Une seule region d'annonce, celle du champ : ajouts, retraits et
|
|
3479
|
+
* refus y passent.
|
|
3480
|
+
* - `readonly` : le champ reste focalisable, rien n'entre, et les croix sont masquees ;
|
|
3481
|
+
* `disabled` : hors de la tabulation, sur fond blanc (D66).
|
|
3482
|
+
* - Le cadre a une hauteur MINIMALE : les etiquettes passent a la ligne, jamais tronquees.
|
|
3483
|
+
*/
|
|
3484
|
+
export declare class StTagInput extends ContratDeChamp implements FormValueControl<readonly string[]> {
|
|
3485
|
+
private readonly libelles;
|
|
3486
|
+
private readonly element;
|
|
3487
|
+
readonly value: import("@angular/core").ModelSignal<readonly string[]>;
|
|
3488
|
+
/** Ce qui ajoute le texte tape, en plus d'Entree. */
|
|
3489
|
+
readonly separateurs: import("@angular/core").InputSignal<readonly string[]>;
|
|
3490
|
+
/** Refus local d'un texte (une adresse mal formee) ; la validation du schema reste l'arbitre. */
|
|
3491
|
+
readonly valider: import("@angular/core").InputSignal<((texte: string) => boolean) | null>;
|
|
3492
|
+
/** Nombre de valeurs au plus (D78 : `max` est une borne de valeur du contrat Signal Forms). */
|
|
3493
|
+
readonly nombreMax: import("@angular/core").InputSignal<number | null>;
|
|
3494
|
+
protected readonly annonce: AnnonceLocale;
|
|
3495
|
+
protected readonly identifiantDuRefus: string;
|
|
3496
|
+
/** Le dernier refus, jusqu'a la prochaine frappe, au prochain ajout ou au prochain retrait. */
|
|
3497
|
+
protected readonly refus: import("@angular/core").WritableSignal<string | null>;
|
|
3498
|
+
protected readonly modifiable: import("@angular/core").Signal<boolean>;
|
|
3499
|
+
protected readonly elements: import("@angular/core").Signal<readonly EtiquetteDeGroupe[]>;
|
|
3500
|
+
protected readonly descriptionsDuRefus: import("@angular/core").Signal<string[]>;
|
|
3501
|
+
constructor();
|
|
3502
|
+
/** Entree et les separateurs ajoutent le texte tape. */
|
|
3503
|
+
protected auClavier(evenement: KeyboardEvent): void;
|
|
3504
|
+
/**
|
|
3505
|
+
* Un separateur arrive aussi sans touche lisible (clavier virtuel, dictee) : le texte se coupe
|
|
3506
|
+
* a chaque separateur, le dernier morceau reste en attente.
|
|
3507
|
+
*/
|
|
3508
|
+
protected surSaisie(evenement: Event): void;
|
|
3509
|
+
/** Un collage qui contient des separateurs ou des fins de ligne : chaque valeur est ajoutee. */
|
|
3510
|
+
protected surCollage(evenement: ClipboardEvent): void;
|
|
3511
|
+
protected retirer(valeur: string): void;
|
|
3512
|
+
protected aLaSortie(evenement: FocusEvent): void;
|
|
3513
|
+
/**
|
|
3514
|
+
* Ajoute chaque texte qui peut l'etre, dans l'ordre, et rend ce qui reste a corriger dans le
|
|
3515
|
+
* champ. Un refus se dit en texte visible et dans l'annonce, avec les ajouts.
|
|
3516
|
+
*/
|
|
3517
|
+
private ajouter;
|
|
3518
|
+
/** Doublon d'abord, puis la limite, puis `valider` : le blocage le plus utile a lever. */
|
|
3519
|
+
private motifDuRefus;
|
|
3520
|
+
/** Ce qui separe deux textes refuses laisses dans le champ : le premier separateur, puis une espace. */
|
|
3521
|
+
private jointure;
|
|
3522
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<StTagInput, never>;
|
|
3523
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<StTagInput, "st-tag-input", never, {
|
|
3524
|
+
"value": {
|
|
3525
|
+
"alias": "value";
|
|
3526
|
+
"required": false;
|
|
3527
|
+
"isSignal": true;
|
|
3528
|
+
};
|
|
3529
|
+
"separateurs": {
|
|
3530
|
+
"alias": "separateurs";
|
|
3531
|
+
"required": false;
|
|
3532
|
+
"isSignal": true;
|
|
3533
|
+
};
|
|
3534
|
+
"valider": {
|
|
3535
|
+
"alias": "valider";
|
|
3536
|
+
"required": false;
|
|
3537
|
+
"isSignal": true;
|
|
3538
|
+
};
|
|
3539
|
+
"nombreMax": {
|
|
3540
|
+
"alias": "nombreMax";
|
|
3541
|
+
"required": false;
|
|
3542
|
+
"isSignal": true;
|
|
3543
|
+
};
|
|
3544
|
+
}, {
|
|
3545
|
+
"value": "valueChange";
|
|
3546
|
+
}, never, ["[stMeta]", "[stAide]", "[stIndication]"], true, never>;
|
|
3547
|
+
}
|
|
3548
|
+
/**
|
|
3549
|
+
* Ce que `st-address-fieldset` offre a une recherche inseree en son sein (`st-address-search`, de
|
|
3550
|
+
* `@starterlib/ui/selection`) : le champ ne connait pas la recherche, la recherche l'injecte.
|
|
3551
|
+
* `ui/saisie` n'importe que le tronc : c'est le sens de la dependance.
|
|
3552
|
+
*/
|
|
3553
|
+
export interface ChampDAdresse {
|
|
3554
|
+
/** Le pays choisi (code ISO), ou `''` : la recherche s'y restreint. */
|
|
3555
|
+
readonly pays: Signal<string>;
|
|
3556
|
+
/** Ni desactive, ni en lecture seule : une recherche inerte sinon. */
|
|
3557
|
+
readonly modifiable: Signal<boolean>;
|
|
3558
|
+
/**
|
|
3559
|
+
* Reporte une adresse trouvee dans les champs. Le complement deja saisi est garde quand
|
|
3560
|
+
* l'adresse n'en porte pas : aucun service ne connait l'appartement.
|
|
3561
|
+
*/
|
|
3562
|
+
remplir(adresse: Adresse): void;
|
|
3563
|
+
/** Annonce polie, dans la region unique du champ. */
|
|
3564
|
+
annoncer(message: string): void;
|
|
3565
|
+
}
|
|
3566
|
+
export declare const ST_CHAMP_D_ADRESSE: InjectionToken<ChampDAdresse>;
|
|
3567
|
+
/** Ce qui decide des options d'une liste de pays (`optionsDesPays`). */
|
|
3568
|
+
export interface ParametresDesPays {
|
|
3569
|
+
/** La langue des noms et de leur tri (`ST_LOCALE`). */
|
|
3570
|
+
readonly locale: string;
|
|
3571
|
+
/** Les pays proposes (codes ISO) ; `null` : les 249 pays de la norme. */
|
|
3572
|
+
readonly codes: readonly string[] | null;
|
|
3573
|
+
/** Les pays frequents, en tete de liste et dans cet ordre. */
|
|
3574
|
+
readonly enTete: readonly string[];
|
|
3575
|
+
/** Le code du modele : nomme et desactive quand il n'est pas propose. */
|
|
3576
|
+
readonly courant: string | null;
|
|
3577
|
+
/** Les intitules des deux groupes (« Pays frequents », « Tous les pays »). */
|
|
3578
|
+
readonly groupes: {
|
|
3579
|
+
readonly frequents: string;
|
|
3580
|
+
readonly tous: string;
|
|
3581
|
+
};
|
|
3582
|
+
}
|
|
3583
|
+
/**
|
|
3584
|
+
* Les options d'une liste de pays, partagees par `st-country-field` (select natif) et
|
|
3585
|
+
* `st-country-combobox` (`@starterlib/ui/selection`, filtrable) : noms par `Intl` dans la langue
|
|
3586
|
+
* donnee, tries par sa collation ; les pays frequents dans un premier groupe, sans etre repetes
|
|
3587
|
+
* dans le second ; un pays du modele hors de la liste en tete, nomme et desactive, jamais tu.
|
|
3588
|
+
*/
|
|
3589
|
+
export declare function optionsDesPays(parametres: ParametresDesPays): OptionDeListe[];
|
|
3590
|
+
/**
|
|
3591
|
+
* Liste des pays : un `select` natif (`st-select`), la valeur est le code ISO 3166-1 alpha-2.
|
|
3592
|
+
*
|
|
3593
|
+
* ```html
|
|
3594
|
+
* <st-country-field libelle="Pays" [enTete]="['FR', 'BE', 'CH']" [formField]="f.pays" />
|
|
3595
|
+
* ```
|
|
3596
|
+
*
|
|
3597
|
+
* ⚠️ **Les noms viennent d'`Intl`, dans la langue de la page** (`ST_LOCALE`), et se trient par sa
|
|
3598
|
+
* collation : aucune liste de noms n'est ecrite dans le socle, aucune ne reste en francais quand
|
|
3599
|
+
* la page passe en anglais. Le code ISO ne s'affiche jamais.
|
|
3600
|
+
*
|
|
3601
|
+
* `codes` restreint la liste (zone SEPA, pays admis) ; `enTete` place les pays frequents dans un
|
|
3602
|
+
* premier groupe, sans les repeter dans le second. `autocomplete="country"` par defaut : le
|
|
3603
|
+
* navigateur remplit le champ (WCAG 1.3.5).
|
|
3604
|
+
*
|
|
3605
|
+
* ⚠️ **Un pays deja dans le modele et absent de `codes` ne disparait pas** : il reste affiche,
|
|
3606
|
+
* nomme et desactive ; `erreurPays` du schema dit pourquoi il ne passe pas.
|
|
3607
|
+
*/
|
|
3608
|
+
export declare class StCountryField extends ControleDeSaisie {
|
|
3609
|
+
private readonly libelles;
|
|
3610
|
+
private readonly locale;
|
|
3611
|
+
/** Les pays proposes (codes ISO) ; absent : les 249 pays de la norme. */
|
|
3612
|
+
readonly codes: import("@angular/core").InputSignal<readonly string[] | null>;
|
|
3613
|
+
/** Les pays frequents, en tete de liste et dans cet ordre. */
|
|
3614
|
+
readonly enTete: import("@angular/core").InputSignal<readonly string[]>;
|
|
3615
|
+
/** WCAG 1.3.5 : `country` par defaut ; `shipping country` dans un formulaire de livraison. */
|
|
3616
|
+
readonly autocomplete: import("@angular/core").InputSignal<TypeDAutocompletion | null>;
|
|
3617
|
+
/** Texte de l'option vide. Par defaut : « Choisir… ». */
|
|
3618
|
+
readonly texteVide: import("@angular/core").InputSignal<string | null>;
|
|
3619
|
+
/** Le style de l'etiquette (voir `st-form-field`). */
|
|
3620
|
+
readonly presentation: import("@angular/core").InputSignal<PresentationDeLibelle>;
|
|
3621
|
+
private readonly liste;
|
|
3622
|
+
protected readonly options: import("@angular/core").Signal<OptionDeListe[]>;
|
|
3623
|
+
/** Signal Forms amene le focus sur le `select` interne. */
|
|
3624
|
+
focus(options?: FocusOptions): void;
|
|
3625
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<StCountryField, never>;
|
|
3626
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<StCountryField, "st-country-field", never, {
|
|
3627
|
+
"codes": {
|
|
3628
|
+
"alias": "codes";
|
|
3629
|
+
"required": false;
|
|
3630
|
+
"isSignal": true;
|
|
3631
|
+
};
|
|
3632
|
+
"enTete": {
|
|
3633
|
+
"alias": "enTete";
|
|
3634
|
+
"required": false;
|
|
3635
|
+
"isSignal": true;
|
|
3636
|
+
};
|
|
3637
|
+
"autocomplete": {
|
|
3638
|
+
"alias": "autocomplete";
|
|
3639
|
+
"required": false;
|
|
3640
|
+
"isSignal": true;
|
|
3641
|
+
};
|
|
3642
|
+
"texteVide": {
|
|
3643
|
+
"alias": "texteVide";
|
|
3644
|
+
"required": false;
|
|
3645
|
+
"isSignal": true;
|
|
3646
|
+
};
|
|
3647
|
+
"presentation": {
|
|
3648
|
+
"alias": "presentation";
|
|
3649
|
+
"required": false;
|
|
3650
|
+
"isSignal": true;
|
|
3651
|
+
};
|
|
3652
|
+
}, {}, never, never, true, never>;
|
|
3653
|
+
}
|
|
3654
|
+
/**
|
|
3655
|
+
* Ce que la region affiche : sa liste fermee (`liste`), la sienne en chemin (`chargement`), un texte
|
|
3656
|
+
* libre faute de liste pour le pays (`texte`), ou faute de liste servie (`panne`, et elle le dit).
|
|
3657
|
+
*/
|
|
3658
|
+
export type ModeDeRegion = 'liste' | 'chargement' | 'texte' | 'panne';
|
|
3659
|
+
type PartieDeTexte = Exclude<PartieDAdresse, 'pays'>;
|
|
3660
|
+
/**
|
|
3661
|
+
* Adresse postale, en un groupe : le pays d'abord, puis les champs que son format postal emploie,
|
|
3662
|
+
* dans son ordre, avec ses libelles et ses exigences.
|
|
3663
|
+
*
|
|
3664
|
+
* ```html
|
|
3665
|
+
* <st-address-fieldset libelle="Adresse de residence" [formField]="formulaire.adresse">
|
|
3666
|
+
* <st-address-search /> <!-- facultative : @starterlib/ui/selection -->
|
|
3667
|
+
* </st-address-fieldset>
|
|
3668
|
+
* ```
|
|
3669
|
+
*
|
|
3670
|
+
* ```ts
|
|
3671
|
+
* required(chemin.adresse);
|
|
3672
|
+
* validate(chemin.adresse, ({ value }) => erreursDAdresse(value()));
|
|
3673
|
+
* ```
|
|
3674
|
+
*
|
|
3675
|
+
* ⚠️ **Dynamique par pays** (`formatDAdresse` d'`@starterlib/util`) : le code postal avant la
|
|
3676
|
+
* ville en France, apres elle au Canada, absent au Cameroun ; la region nommee « Province ou
|
|
3677
|
+
* territoire », « Etat » ou « Comte », exigee ou non. Changer de pays ne deplace jamais le focus
|
|
3678
|
+
* (WCAG 3.2.2) ; un format qui change s'annonce poliment. Les parties que le nouveau format
|
|
3679
|
+
* n'affiche plus sont VIDEES : aucune donnee cachee ne part avec le formulaire.
|
|
3680
|
+
*
|
|
3681
|
+
* ⚠️ **Un jeton de remplissage exact par champ** (WCAG 1.3.5) : `address-line1`, `address-line2`,
|
|
3682
|
+
* `postal-code`, `address-level2`, `address-level1`, `country` ; `sectionDeRemplissage` les
|
|
3683
|
+
* prefixe (`shipping`, `billing`) quand deux adresses partagent un formulaire. Le remplissage du
|
|
3684
|
+
* navigateur marche sans la recherche, et la rend inutile a qui l'emploie.
|
|
3685
|
+
*
|
|
3686
|
+
* ⚠️ **La valeur est toujours un objet** (`Adresse`, six chaines) : `required` du schema ne peut
|
|
3687
|
+
* donc pas la dire vide. Ce sont les erreurs de `erreursDAdresse`, une par partie (cle `partie`),
|
|
3688
|
+
* qui bloquent l'envoi ; chacune s'affiche sous son champ, et `focus()` va a la premiere.
|
|
3689
|
+
* L'obligation se lit sur chaque champ exige, jamais sur le complement.
|
|
3690
|
+
*
|
|
3691
|
+
* Une recherche projetee (`st-address-search`) remplit les champs par `ST_CHAMP_D_ADRESSE` ; le
|
|
3692
|
+
* complement deja saisi n'est jamais efface.
|
|
3693
|
+
*
|
|
3694
|
+
* ⚠️ **Listes par pays** (`ST_LISTES_D_ADRESSES`, ADR 0005 D133), quand l'hote en relie une source :
|
|
3695
|
+
* la region devient une liste FERMEE des regions du pays (`st-select`, chargee a chaque pays), la
|
|
3696
|
+
* ville un texte a valeurs PROPOSEES, celles du pays ou de la region choisie (une localite peut
|
|
3697
|
+
* manquer a toute liste : rien n'est refuse). Un pays sans liste garde la region en texte libre ;
|
|
3698
|
+
* une liste qui ne se charge pas aussi, et l'aide de la region le dit. Une region rapportee par son
|
|
3699
|
+
* nom (« Ontario ») s'ecrit a la valeur de sa liste (« ON ») ; une valeur que la liste ne porte pas
|
|
3700
|
+
* reste affichee, nommee, jamais tue. Une region choisie dans la liste d'un pays s'efface quand le
|
|
3701
|
+
* pays change ; une region tapee reste, a corriger.
|
|
3702
|
+
*/
|
|
3703
|
+
export declare class StAddressFieldset extends ContratDeChamp implements FormValueControl<Adresse> {
|
|
3704
|
+
protected readonly libelles: import("@angular/core").Signal<import("@starterlib/ui").LibellesUi>;
|
|
3705
|
+
private readonly locale;
|
|
3706
|
+
private readonly element;
|
|
3707
|
+
readonly value: import("@angular/core").ModelSignal<Adresse>;
|
|
3708
|
+
/** Un pays impose (code ISO) : le champ pays disparait, la valeur le porte. */
|
|
3709
|
+
readonly paysFixe: import("@angular/core").InputSignal<string | null>;
|
|
3710
|
+
/** Les pays admis (codes ISO) ; absent : les 249 pays de la norme. */
|
|
3711
|
+
readonly codesDesPays: import("@angular/core").InputSignal<readonly string[] | null>;
|
|
3712
|
+
/** Les pays frequents, en tete de la liste. */
|
|
3713
|
+
readonly paysFrequents: import("@angular/core").InputSignal<readonly string[]>;
|
|
3714
|
+
/** Sans complement d'adresse (une ligne de voie seulement). */
|
|
3715
|
+
readonly ligne2Masquee: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
|
|
3716
|
+
/**
|
|
3717
|
+
* Prefixe des jetons de remplissage (`shipping`, `billing`, `section-<nom>`), quand deux
|
|
3718
|
+
* adresses partagent un formulaire. `null` : les jetons seuls.
|
|
3719
|
+
*/
|
|
3720
|
+
readonly sectionDeRemplissage: import("@angular/core").InputSignal<string | null>;
|
|
3721
|
+
protected readonly annonce: AnnonceLocale;
|
|
3722
|
+
private readonly listes;
|
|
3723
|
+
/** Le pays qui decide du format : l'impose, sinon celui de la valeur. */
|
|
3724
|
+
private readonly pays;
|
|
3725
|
+
protected readonly format: import("@angular/core").Signal<FormatDAdresse>;
|
|
3726
|
+
protected readonly parties: import("@angular/core").Signal<PartieDeTexte[]>;
|
|
3727
|
+
private readonly exigees;
|
|
3728
|
+
protected readonly modifiable: import("@angular/core").Signal<boolean>;
|
|
3729
|
+
/** Les erreurs du schema, par partie ; celles sans partie restent au groupe. */
|
|
3730
|
+
private readonly erreursParPartie;
|
|
3731
|
+
protected readonly erreursDuGroupe: import("@angular/core").Signal<ErreurAffichable[]>;
|
|
3732
|
+
/** La liste des regions a demander : le pays, s'il affiche une region et qu'une source existe. */
|
|
3733
|
+
private readonly demandeDeRegions;
|
|
3734
|
+
private readonly regions;
|
|
3735
|
+
/** Les regions du pays, une fois servies ; `null` sans liste. */
|
|
3736
|
+
private readonly listeDesRegions;
|
|
3737
|
+
protected readonly modeDeRegion: import("@angular/core").Signal<ModeDeRegion>;
|
|
3738
|
+
protected readonly regionEnListe: import("@angular/core").Signal<boolean>;
|
|
3739
|
+
/** Les options de la region : sa liste, et la valeur du modele qu'elle ne porte pas, nommee. */
|
|
3740
|
+
protected readonly optionsDeRegion: import("@angular/core").Signal<OptionDeListe[]>;
|
|
3741
|
+
/** Les villes a demander : le pays, et la region seulement si sa liste la porte. */
|
|
3742
|
+
private readonly demandeDeVilles;
|
|
3743
|
+
private readonly villes;
|
|
3744
|
+
/** Les villes proposees sous le champ ; une liste en panne n'en propose aucune, sans rien bloquer. */
|
|
3745
|
+
protected readonly villesProposees: import("@angular/core").Signal<readonly string[] | null>;
|
|
3746
|
+
private readonly listeDesPays;
|
|
3747
|
+
constructor();
|
|
3748
|
+
protected erreursDe(partie: PartieDAdresse): readonly ErreurAffichable[];
|
|
3749
|
+
protected libelleDe(partie: PartieDeTexte): string;
|
|
3750
|
+
protected aideDe(partie: PartieDeTexte): string | null;
|
|
3751
|
+
protected exigee(partie: PartieDAdresse): boolean;
|
|
3752
|
+
protected jeton(partie: PartieDAdresse): TypeDAutocompletion;
|
|
3753
|
+
protected clavier(partie: PartieDeTexte): ModeDeSaisie | null;
|
|
3754
|
+
protected nomDe(partie: PartieDAdresse): string;
|
|
3755
|
+
protected changer(partie: PartieDeTexte, texte: string): void;
|
|
3756
|
+
protected changerDePays(code: string): void;
|
|
3757
|
+
/** A la sortie du code postal : capitales, espaces reduites (« h2x 1y4 » donne « H2X 1Y4 »). */
|
|
3758
|
+
protected aLaSortieDe(partie: PartieDeTexte): void;
|
|
3759
|
+
/** `touch` quand le focus quitte le groupe entier, et non chaque champ. */
|
|
3760
|
+
protected aLaSortie(evenement: FocusEvent): void;
|
|
3761
|
+
/**
|
|
3762
|
+
* Appele par Signal Forms pour amener le focus sur un champ en erreur : la PREMIERE partie en
|
|
3763
|
+
* erreur, dans l'ordre du champ (le pays d'abord), sinon le premier champ.
|
|
3764
|
+
*/
|
|
3765
|
+
focus(options?: FocusOptions): void;
|
|
3766
|
+
private remplir;
|
|
3767
|
+
/** Vide les parties que le format du pays n'affiche pas : rien de cache ne part. */
|
|
3768
|
+
private nettoyer;
|
|
3769
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<StAddressFieldset, never>;
|
|
3770
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<StAddressFieldset, "st-address-fieldset", never, {
|
|
3771
|
+
"value": {
|
|
3772
|
+
"alias": "value";
|
|
3773
|
+
"required": false;
|
|
3774
|
+
"isSignal": true;
|
|
3775
|
+
};
|
|
3776
|
+
"paysFixe": {
|
|
3777
|
+
"alias": "paysFixe";
|
|
3778
|
+
"required": false;
|
|
3779
|
+
"isSignal": true;
|
|
3780
|
+
};
|
|
3781
|
+
"codesDesPays": {
|
|
3782
|
+
"alias": "codesDesPays";
|
|
3783
|
+
"required": false;
|
|
3784
|
+
"isSignal": true;
|
|
3785
|
+
};
|
|
3786
|
+
"paysFrequents": {
|
|
3787
|
+
"alias": "paysFrequents";
|
|
3788
|
+
"required": false;
|
|
3789
|
+
"isSignal": true;
|
|
3790
|
+
};
|
|
3791
|
+
"ligne2Masquee": {
|
|
3792
|
+
"alias": "ligne2Masquee";
|
|
3793
|
+
"required": false;
|
|
3794
|
+
"isSignal": true;
|
|
3795
|
+
};
|
|
3796
|
+
"sectionDeRemplissage": {
|
|
3797
|
+
"alias": "sectionDeRemplissage";
|
|
3798
|
+
"required": false;
|
|
3799
|
+
"isSignal": true;
|
|
3800
|
+
};
|
|
3801
|
+
}, {
|
|
3802
|
+
"value": "valueChange";
|
|
3803
|
+
}, never, ["*"], true, never>;
|
|
921
3804
|
}
|
|
922
3805
|
|
|
923
|
-
export {
|
|
924
|
-
export type { BornesDeDate, DispositionDeChamp, ElementDeSaisie, ErreurAffichable, EtatDeTeleversementAffiche, OptionDeListe, OptionRadio, ReglesDeFichiers, RemplissageDeTelephone, TypeDeSaisie, UsageDuMotDePasse };
|
|
3806
|
+
export {};
|