@starterlib/ui 0.2.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +83 -16
- package/assets/icones/sprite.svg +3 -0
- package/fesm2022/starterlib-ui-formulaires.mjs +446 -0
- package/fesm2022/starterlib-ui-formulaires.mjs.map +1 -0
- package/fesm2022/starterlib-ui-interactions.mjs +536 -0
- package/fesm2022/starterlib-ui-interactions.mjs.map +1 -0
- package/fesm2022/starterlib-ui-surfaces.mjs +1106 -11
- package/fesm2022/starterlib-ui-surfaces.mjs.map +1 -1
- package/fesm2022/starterlib-ui.mjs +2719 -105
- package/fesm2022/starterlib-ui.mjs.map +1 -1
- package/package.json +24 -3
- package/types/starterlib-ui-formulaires.d.ts +198 -0
- package/types/starterlib-ui-interactions.d.ts +269 -0
- package/types/starterlib-ui-surfaces.d.ts +607 -16
- package/types/starterlib-ui.d.ts +1598 -24
|
@@ -1,6 +1,10 @@
|
|
|
1
|
-
import * as
|
|
1
|
+
import * as i0 from '@angular/core';
|
|
2
|
+
import { InjectionToken, Type, TemplateRef, Signal } from '@angular/core';
|
|
2
3
|
import * as i1 from '@angular/aria/menu';
|
|
3
|
-
import { Ton } from '@starterlib/util';
|
|
4
|
+
import { Ton, TonSemantique } from '@starterlib/util';
|
|
5
|
+
import { CdkDialogContainer } from '@angular/cdk/dialog';
|
|
6
|
+
export { DIALOG_DATA as DONNEES_DE_DIALOGUE } from '@angular/cdk/dialog';
|
|
7
|
+
import { NomDIcone, AnnonceLocale } from '@starterlib/ui';
|
|
4
8
|
|
|
5
9
|
type AlignementDeMenu = 'debut' | 'fin';
|
|
6
10
|
/**
|
|
@@ -36,10 +40,10 @@ declare class StMenu {
|
|
|
36
40
|
private readonly overlay;
|
|
37
41
|
private readonly aria;
|
|
38
42
|
/** Nom du menu pour les technologies d'assistance. */
|
|
39
|
-
readonly etiquette:
|
|
40
|
-
readonly alignement:
|
|
43
|
+
readonly etiquette: i0.InputSignal<string>;
|
|
44
|
+
readonly alignement: i0.InputSignal<AlignementDeMenu>;
|
|
41
45
|
private readonly ouvertInterne;
|
|
42
|
-
readonly ouvert:
|
|
46
|
+
readonly ouvert: i0.Signal<boolean>;
|
|
43
47
|
private couche;
|
|
44
48
|
private declencheur;
|
|
45
49
|
constructor();
|
|
@@ -54,8 +58,8 @@ declare class StMenu {
|
|
|
54
58
|
basculerDepuis(declencheur: HTMLElement): void;
|
|
55
59
|
protected auClavier(evenement: KeyboardEvent): void;
|
|
56
60
|
private detruireLaCouche;
|
|
57
|
-
static ɵfac:
|
|
58
|
-
static ɵcmp:
|
|
61
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<StMenu, never>;
|
|
62
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<StMenu, "st-menu", never, { "etiquette": { "alias": "etiquette"; "required": true; "isSignal": true; }; "alignement": { "alias": "alignement"; "required": false; "isSignal": true; }; }, {}, never, ["*"], true, [{ directive: typeof i1.Menu; inputs: { "wrap": "wrap"; "typeaheadDelay": "typeaheadDelay"; "disabled": "disabled"; }; outputs: { "itemSelected": "selection"; }; }]>;
|
|
59
63
|
}
|
|
60
64
|
|
|
61
65
|
/**
|
|
@@ -78,10 +82,10 @@ type TonDElementDeMenu = Extract<Ton, 'neutre' | 'danger'>;
|
|
|
78
82
|
* actions par leur libelle, donc par leur traduction.
|
|
79
83
|
*/
|
|
80
84
|
declare class StMenuItem {
|
|
81
|
-
readonly icone:
|
|
82
|
-
readonly ton:
|
|
83
|
-
static ɵfac:
|
|
84
|
-
static ɵcmp:
|
|
85
|
+
readonly icone: i0.InputSignal<"boite-vide" | "calendrier" | "cercle" | "cercle-coche" | "cercle-croix" | "cercle-info" | "chevron-bas" | "chevron-droite" | "chevron-gauche" | "chevron-haut" | "coche" | "copie" | "corbeille" | "croix" | "fichier" | "hors-ligne" | "lien-externe" | "menu" | "oeil" | "oeil-barre" | "plus" | "rafraichir" | "recherche" | "serveur" | "televerser" | "triangle-alerte" | "utilisateur" | null>;
|
|
86
|
+
readonly ton: i0.InputSignal<TonDElementDeMenu>;
|
|
87
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<StMenuItem, never>;
|
|
88
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<StMenuItem, "button[stMenuItem]", never, { "icone": { "alias": "icone"; "required": false; "isSignal": true; }; "ton": { "alias": "ton"; "required": false; "isSignal": true; }; }, {}, never, ["*"], true, [{ directive: typeof i1.MenuItem; inputs: { "value": "valeur"; "disabled": "desactive"; "role": "role"; }; outputs: {}; }]>;
|
|
85
89
|
}
|
|
86
90
|
|
|
87
91
|
/**
|
|
@@ -97,12 +101,599 @@ declare class StMenuItem {
|
|
|
97
101
|
*/
|
|
98
102
|
declare class StMenuTrigger {
|
|
99
103
|
private readonly element;
|
|
100
|
-
readonly menu:
|
|
104
|
+
readonly menu: i0.InputSignal<StMenu>;
|
|
101
105
|
protected basculer(): void;
|
|
102
106
|
protected auClavier(evenement: KeyboardEvent): void;
|
|
103
|
-
static ɵfac:
|
|
104
|
-
static ɵdir:
|
|
107
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<StMenuTrigger, never>;
|
|
108
|
+
static ɵdir: i0.ɵɵDirectiveDeclaration<StMenuTrigger, "[stMenuTrigger]", never, { "menu": { "alias": "menu"; "required": true; "isSignal": true; }; }, {}, never, never, true, never>;
|
|
105
109
|
}
|
|
106
110
|
|
|
107
|
-
|
|
108
|
-
|
|
111
|
+
/**
|
|
112
|
+
* Identifiant du titre du dialogue, decide a l'ouverture et fourni au contenu.
|
|
113
|
+
*
|
|
114
|
+
* ⚠️ Il est engendre par le service et non par le composant de titre : c'est la
|
|
115
|
+
* configuration du dialogue qui doit porter `aria-labelledby`, et elle est
|
|
116
|
+
* figee a l'ouverture. Un identifiant decide plus tard arriverait apres que le
|
|
117
|
+
* conteneur a lu sa configuration, et le dialogue s'ouvrirait sans nom.
|
|
118
|
+
*/
|
|
119
|
+
declare const IDENTIFIANT_DU_TITRE: InjectionToken<string>;
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Ce que l'appelant decrit pour obtenir une confirmation.
|
|
123
|
+
*
|
|
124
|
+
* ⚠️ **Une confirmation d'interface n'est pas un controle.** Elle protege
|
|
125
|
+
* contre le geste distrait, pas contre quelqu'un qui appelle l'API directement.
|
|
126
|
+
* Le serveur autorise, et une action sensible — suppression de compte,
|
|
127
|
+
* changement d'IBAN — merite une re-authentification par second facteur, que le
|
|
128
|
+
* backend sait deja demander.
|
|
129
|
+
*/
|
|
130
|
+
interface DemandeDeConfirmation {
|
|
131
|
+
readonly titre: string;
|
|
132
|
+
readonly message: string;
|
|
133
|
+
readonly libelleConfirmation?: string;
|
|
134
|
+
readonly libelleAnnulation?: string;
|
|
135
|
+
/** L'action detruit quelque chose : le bouton passe en `danger`. */
|
|
136
|
+
readonly destructeur?: boolean;
|
|
137
|
+
/**
|
|
138
|
+
* Texte que la personne doit recopier pour confirmer.
|
|
139
|
+
*
|
|
140
|
+
* ⚠️ A reserver a l'irreversible. Ce n'est pas une ceinture de securite de
|
|
141
|
+
* plus : c'est le seul moyen de rompre l'automatisme de qui clique « Oui »
|
|
142
|
+
* sans lire, et son cout — une saisie — n'est justifie que la ou l'erreur ne
|
|
143
|
+
* se repare pas.
|
|
144
|
+
*/
|
|
145
|
+
readonly saisieDeConfirmation?: string;
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Dialogue de confirmation.
|
|
149
|
+
*
|
|
150
|
+
* ⚠️ **Le bouton de confirmation n'est jamais celui qui recoit le focus.** Le
|
|
151
|
+
* dialogue entier le recoit (voir `StDialog`), et le premier arret de
|
|
152
|
+
* tabulation est l'annulation. Un dialogue destructeur dont le bouton dangereux
|
|
153
|
+
* est deja focalise se valide par une seule touche Entree — c'est-a-dire par le
|
|
154
|
+
* geste que la personne etait en train de faire quand il s'est ouvert.
|
|
155
|
+
*/
|
|
156
|
+
declare class StConfirmDialog {
|
|
157
|
+
private readonly reference;
|
|
158
|
+
private readonly libelles;
|
|
159
|
+
protected readonly demande: DemandeDeConfirmation;
|
|
160
|
+
protected readonly saisie: i0.WritableSignal<string>;
|
|
161
|
+
/** Unique par instance : deux confirmations empilees dupliqueraient un identifiant fixe. */
|
|
162
|
+
protected readonly identifiantDeSaisie: string;
|
|
163
|
+
protected readonly ton: i0.Signal<TonSemantique>;
|
|
164
|
+
protected readonly libelleConfirmation: i0.Signal<string>;
|
|
165
|
+
protected readonly libelleAnnulation: i0.Signal<string>;
|
|
166
|
+
protected readonly libelleRecopie: i0.Signal<string>;
|
|
167
|
+
/**
|
|
168
|
+
* ⚠️ La comparaison ignore la casse et les espaces de bord, mais RIEN
|
|
169
|
+
* d'autre. Exiger la casse exacte transforme une confirmation en jeu
|
|
170
|
+
* d'adresse, et pousse a copier-coller — ce qui annule precisement l'effet
|
|
171
|
+
* recherche.
|
|
172
|
+
*/
|
|
173
|
+
protected readonly confirmationPossible: i0.Signal<boolean>;
|
|
174
|
+
protected auChangement(evenement: Event): void;
|
|
175
|
+
protected confirmer(): void;
|
|
176
|
+
protected annuler(): void;
|
|
177
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<StConfirmDialog, never>;
|
|
178
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<StConfirmDialog, "st-confirm-dialog", never, {}, {}, never, never, true, never>;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
/** Ce que l'appelant regle a l'ouverture. */
|
|
182
|
+
interface OptionsDeDialogue<D = unknown> {
|
|
183
|
+
/** Donnees passees au composant, lisibles par `DONNEES_DE_DIALOGUE`. */
|
|
184
|
+
readonly donnees?: D;
|
|
185
|
+
/**
|
|
186
|
+
* Nom accessible quand le dialogue n'affiche pas de `st-dialog-title`.
|
|
187
|
+
* Inutile — et ignore — des qu'un titre est present.
|
|
188
|
+
*/
|
|
189
|
+
readonly etiquette?: string;
|
|
190
|
+
/**
|
|
191
|
+
* Interdit Echap et le clic sur le fond.
|
|
192
|
+
*
|
|
193
|
+
* ⚠️ A reserver aux dialogues qui perdraient du travail en se fermant. Un
|
|
194
|
+
* dialogue qu'on ne peut pas fermer au clavier est une impasse pour qui
|
|
195
|
+
* n'utilise pas la souris ; la fermeture doit alors exister ailleurs, en
|
|
196
|
+
* toutes lettres.
|
|
197
|
+
*/
|
|
198
|
+
readonly fermetureInterdite?: boolean;
|
|
199
|
+
/**
|
|
200
|
+
* Ignore le clic sur le fond, mais laisse Echap fermer.
|
|
201
|
+
*
|
|
202
|
+
* ⚠️ La distinction compte, et le CDK ne la fait pas : son `disableClose`
|
|
203
|
+
* bloque les DEUX. Or le clic hors du panneau est le geste le plus facile a
|
|
204
|
+
* faire par megarde, tandis qu'Echap est un choix delibere — et, sur une
|
|
205
|
+
* confirmation, il vaut ANNULER, ce qui est sans danger. Bloquer Echap ne
|
|
206
|
+
* protege rien et prive le clavier de sa sortie.
|
|
207
|
+
*/
|
|
208
|
+
readonly fondInerte?: boolean;
|
|
209
|
+
/**
|
|
210
|
+
* `alertdialog` pour ce qui exige une reponse immediate : une session qui
|
|
211
|
+
* expire, une perte imminente. Le lecteur d'ecran l'annonce avec plus
|
|
212
|
+
* d'insistance qu'un dialogue ordinaire — a ne pas galvauder.
|
|
213
|
+
*/
|
|
214
|
+
readonly role?: 'dialog' | 'alertdialog';
|
|
215
|
+
/**
|
|
216
|
+
* Selecteur de l'element qui recoit le focus a l'ouverture, a la place du
|
|
217
|
+
* dialogue lui-meme.
|
|
218
|
+
*
|
|
219
|
+
* ⚠️ Pour un `alertdialog`, le motif ARIA veut le focus sur l'action la MOINS
|
|
220
|
+
* destructrice : « Rester connecte », jamais « Se deconnecter ». Une touche
|
|
221
|
+
* Entree reflexe ne doit rien detruire.
|
|
222
|
+
*/
|
|
223
|
+
readonly focusInitial?: string;
|
|
224
|
+
/** Identifiant du texte qui DECRIT le dialogue, lu a l'ouverture apres son nom. */
|
|
225
|
+
readonly descriptionDe?: string;
|
|
226
|
+
readonly largeur?: string;
|
|
227
|
+
readonly classe?: string;
|
|
228
|
+
/**
|
|
229
|
+
* Ancre le panneau sur un bord : c'est le TIROIR.
|
|
230
|
+
*
|
|
231
|
+
* ⚠️ Un tiroir modal EST un dialogue — meme role, meme piegeage du focus,
|
|
232
|
+
* meme Echap. Seule sa geometrie change. Lui donner son propre service
|
|
233
|
+
* dupliquerait toute la machinerie d'accessibilite pour une difference de
|
|
234
|
+
* position, et la copie finirait par deriver de l'original.
|
|
235
|
+
*
|
|
236
|
+
* `debut` et `fin` suivent le sens d'ecriture ; `bas` donne la feuille
|
|
237
|
+
* inferieure, qui est la forme utile sur telephone.
|
|
238
|
+
*/
|
|
239
|
+
readonly cote?: CoteDuTiroir;
|
|
240
|
+
}
|
|
241
|
+
/** Bord auquel un tiroir s'ancre. Logique, donc juste aussi en ecriture droite a gauche. */
|
|
242
|
+
type CoteDuTiroir = 'debut' | 'fin' | 'bas';
|
|
243
|
+
/** Reference sur un dialogue ouvert. */
|
|
244
|
+
interface ReferenceDeDialogue<R> {
|
|
245
|
+
/** Resout a la fermeture. `undefined` quand le dialogue est simplement quitte. */
|
|
246
|
+
readonly ferme: Promise<R | undefined>;
|
|
247
|
+
fermer(resultat?: R): void;
|
|
248
|
+
}
|
|
249
|
+
/**
|
|
250
|
+
* Ouvre des dialogues modaux.
|
|
251
|
+
*
|
|
252
|
+
* ⚠️ Monte sur `@angular/cdk/dialog`, et c'est un choix defendu : le piegeage
|
|
253
|
+
* du focus, sa restauration au declencheur, `aria-modal`, la mise en retrait du
|
|
254
|
+
* reste de la page, Echap et le blocage du defilement sont longs a ecrire,
|
|
255
|
+
* faciles a croire finis, et c'est exactement la que l'accessibilite se perd.
|
|
256
|
+
* Le socle n'en reecrit aucune part.
|
|
257
|
+
*
|
|
258
|
+
* Ce qu'il ajoute au CDK : le focus sur le dialogue, `aria-modal`, un fond inerte
|
|
259
|
+
* qui laisse Echap fermer, et la fermeture a toute navigation du routeur.
|
|
260
|
+
*/
|
|
261
|
+
declare class StDialog {
|
|
262
|
+
private readonly cdk;
|
|
263
|
+
private readonly overlay;
|
|
264
|
+
/** Une fonction de fermeture par dialogue ouvert : c'est tout ce qu'il faut garder. */
|
|
265
|
+
private readonly ouverts;
|
|
266
|
+
constructor();
|
|
267
|
+
/**
|
|
268
|
+
* Ouvre un composant, ou un GABARIT.
|
|
269
|
+
*
|
|
270
|
+
* Un gabarit sert quand le contenu vit deja dans le composant appelant — un
|
|
271
|
+
* tiroir de navigation qui deplace ses propres liens sur petit ecran. ⚠️ Son
|
|
272
|
+
* injecteur reste celui de l'endroit ou il est ECRIT : un `st-dialog-title`
|
|
273
|
+
* pose dedans ne recoit pas l'identifiant de titre, et le dialogue se nomme
|
|
274
|
+
* alors par `etiquette`.
|
|
275
|
+
*/
|
|
276
|
+
ouvrir<R = unknown, D = unknown>(composant: Type<unknown> | TemplateRef<unknown>, options?: OptionsDeDialogue<D>): ReferenceDeDialogue<R>;
|
|
277
|
+
/**
|
|
278
|
+
* ⚠️ Un tiroir occupe toute la hauteur du bord ou il s'ancre, et une feuille
|
|
279
|
+
* inferieure toute la largeur. Sans cela, le panneau flotte au milieu et ne
|
|
280
|
+
* se lit plus comme un tiroir.
|
|
281
|
+
*/
|
|
282
|
+
private geometrie;
|
|
283
|
+
private classes;
|
|
284
|
+
/**
|
|
285
|
+
* Demande une confirmation, et rend `true` seulement si elle est donnee.
|
|
286
|
+
*
|
|
287
|
+
* ⚠️ La fermeture par Echap ou par le fond rend `false` : quitter n'est pas
|
|
288
|
+
* confirmer. C'est pourquoi la valeur est comparee explicitement plutot que
|
|
289
|
+
* testee pour sa veracite — `undefined` doit valoir non.
|
|
290
|
+
*/
|
|
291
|
+
confirmer(demande: DemandeDeConfirmation): Promise<boolean>;
|
|
292
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<StDialog, never>;
|
|
293
|
+
static ɵprov: i0.ɵɵInjectableDeclaration<any>;
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
/**
|
|
297
|
+
* Le panneau du dialogue : sa surface, son arrondi, son ombre.
|
|
298
|
+
*
|
|
299
|
+
* ⚠️ Pourquoi ce composant existe. `CdkDialogContainer` n'a **aucune
|
|
300
|
+
* apparence** : c'est voulu de la part du CDK, qui ne decide d'aucun style. Le
|
|
301
|
+
* dialogue fonctionnait donc parfaitement — role, nom, piegeage du focus,
|
|
302
|
+
* Echap — tout en s'affichant SANS FOND, le texte flottant par-dessus la page.
|
|
303
|
+
* Aucun test ne pouvait le voir : jsdom ne calcule pas la mise en page, et les
|
|
304
|
+
* tests verifiaient le comportement, pas l'aspect.
|
|
305
|
+
*
|
|
306
|
+
* ⚠️ Un conteneur maison plutot qu'une feuille de style globale a importer :
|
|
307
|
+
* une SPA qui oublierait l'import retrouverait exactement le meme defaut, et
|
|
308
|
+
* l'oubli ne se verrait qu'a l'ecran. Ici, l'apparence voyage avec le
|
|
309
|
+
* composant.
|
|
310
|
+
*
|
|
311
|
+
* L'encapsulation reste EMULEE : seuls l'hote et le panneau qui l'enveloppe
|
|
312
|
+
* sont styles, par `:host` et `:host-context()`. Aucun contenu projete n'est
|
|
313
|
+
* vise, donc rien ne justifie de rendre ces styles globaux.
|
|
314
|
+
*/
|
|
315
|
+
declare class StDialogContainer extends CdkDialogContainer {
|
|
316
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<StDialogContainer, never>;
|
|
317
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<StDialogContainer, "st-dialog-container", never, {}, {}, never, never, true, never>;
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
/**
|
|
321
|
+
* Titre du dialogue. Il porte l'identifiant que la configuration a designe en
|
|
322
|
+
* `aria-labelledby` : c'est lui qui NOMME le dialogue.
|
|
323
|
+
*
|
|
324
|
+
* ⚠️ Un `h2` et non un `h1` : le dialogue s'ouvre par-dessus une page qui a
|
|
325
|
+
* deja son titre de niveau 1, et deux `h1` cassent la table des matieres que
|
|
326
|
+
* les lecteurs d'ecran construisent.
|
|
327
|
+
*/
|
|
328
|
+
declare class StDialogTitle {
|
|
329
|
+
protected readonly identifiant: string | null;
|
|
330
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<StDialogTitle, never>;
|
|
331
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<StDialogTitle, "st-dialog-title", never, {}, {}, never, ["*"], true, never>;
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
/**
|
|
335
|
+
* Corps du dialogue, defilant quand il deborde.
|
|
336
|
+
*
|
|
337
|
+
* ⚠️ Le defilement est ICI et non sur le dialogue entier : titre et actions
|
|
338
|
+
* doivent rester visibles. Un dialogue long dont les boutons partent hors de
|
|
339
|
+
* l'ecran est le defaut classique, et il ne se voit qu'a 200 % d'echelle ou sur
|
|
340
|
+
* un ecran bas.
|
|
341
|
+
*
|
|
342
|
+
* ⚠️ **Focalisable seulement quand il defile.** Une zone defilante sans
|
|
343
|
+
* controle doit recevoir le focus, sinon le clavier ne peut pas la faire
|
|
344
|
+
* defiler — le texte d'une condition generale, par exemple. Mais la premiere
|
|
345
|
+
* version posait `tabindex="0"` sans condition : sur un dialogue court, la zone
|
|
346
|
+
* de texte devenait le premier arret de tabulation, AVANT le bouton
|
|
347
|
+
* d'annulation, contrairement a ce que `StConfirmDialog` affirmait.
|
|
348
|
+
*/
|
|
349
|
+
declare class StDialogContent {
|
|
350
|
+
/** `aucun` pour un contenu qui gere ses propres marges, comme un tableau. */
|
|
351
|
+
readonly rembourrage: i0.InputSignal<"aucun" | "md">;
|
|
352
|
+
protected readonly defilante: i0.WritableSignal<boolean>;
|
|
353
|
+
constructor();
|
|
354
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<StDialogContent, never>;
|
|
355
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<StDialogContent, "st-dialog-content", never, { "rembourrage": { "alias": "rembourrage"; "required": false; "isSignal": true; }; }, {}, never, ["*"], true, never>;
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
/**
|
|
359
|
+
* Barre d'actions du dialogue.
|
|
360
|
+
*
|
|
361
|
+
* ⚠️ L'action de confirmation est a DROITE et l'annulation a gauche, dans cet
|
|
362
|
+
* ordre dans le DOM : l'ordre de tabulation doit suivre l'ordre visuel, sinon
|
|
363
|
+
* le clavier et la souris ne donnent pas le meme parcours. Inverser
|
|
364
|
+
* visuellement par `row-reverse` casserait cette correspondance.
|
|
365
|
+
*/
|
|
366
|
+
declare class StDialogActions {
|
|
367
|
+
readonly alignement: i0.InputSignal<"debut" | "fin" | "entre">;
|
|
368
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<StDialogActions, never>;
|
|
369
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<StDialogActions, "st-dialog-actions", never, { "alignement": { "alias": "alignement"; "required": false; "isSignal": true; }; }, {}, never, ["*"], true, never>;
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
/** Action offerte dans le message, comme « Annuler ». */
|
|
373
|
+
interface ActionDeToast {
|
|
374
|
+
readonly libelle: string;
|
|
375
|
+
readonly faire: () => void;
|
|
376
|
+
}
|
|
377
|
+
/** Ce que l'appelant demande a afficher. */
|
|
378
|
+
interface DemandeDeToast {
|
|
379
|
+
/**
|
|
380
|
+
* ⚠️ Aucune donnee personnelle complete : un message reste a l'ecran le temps
|
|
381
|
+
* qu'il faut pour etre lu — et lu par-dessus l'epaule. Un IBAN, un numero de
|
|
382
|
+
* carte ou de telephone s'y ecrivent masques, comme le fait `st-masked`.
|
|
383
|
+
*/
|
|
384
|
+
readonly message: string;
|
|
385
|
+
readonly ton?: TonSemantique;
|
|
386
|
+
/**
|
|
387
|
+
* ⚠️ Un message porteur d'action ne disparait PAS tout seul. WCAG 2.2.1 :
|
|
388
|
+
* un contenu qui s'efface sur minuterie doit pouvoir etre prolonge ou
|
|
389
|
+
* desactive. Un « Annuler » qui s'evanouit en quatre secondes est inutilisable
|
|
390
|
+
* pour qui lit lentement, navigue au clavier ou emploie un lecteur d'ecran —
|
|
391
|
+
* et c'est precisement la personne a qui l'annulation sert le plus.
|
|
392
|
+
*/
|
|
393
|
+
readonly action?: ActionDeToast;
|
|
394
|
+
/**
|
|
395
|
+
* Duree d'affichage en millisecondes. Ignoree des qu'une action est fournie.
|
|
396
|
+
* `null` : le message reste jusqu'a sa fermeture.
|
|
397
|
+
*/
|
|
398
|
+
readonly dureeMs?: number | null;
|
|
399
|
+
}
|
|
400
|
+
/** Un message affiche, tel que le conteneur le connait. */
|
|
401
|
+
interface Toast extends DemandeDeToast {
|
|
402
|
+
readonly identifiant: number;
|
|
403
|
+
readonly ton: TonSemantique;
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
/**
|
|
407
|
+
* Messages ephemeres.
|
|
408
|
+
*
|
|
409
|
+
* ```ts
|
|
410
|
+
* const messages = inject(StToast);
|
|
411
|
+
* messages.montrer({ message: 'Virement enregistre', ton: 'succes' });
|
|
412
|
+
* messages.montrer({
|
|
413
|
+
* message: 'Beneficiaire supprime',
|
|
414
|
+
* action: { libelle: 'Annuler', faire: () => this.retablir() },
|
|
415
|
+
* });
|
|
416
|
+
* ```
|
|
417
|
+
*
|
|
418
|
+
* ⚠️ **Un seul conteneur pour toute l'application**, cree a la premiere
|
|
419
|
+
* demande. Deux piles superposees se recouvrent, et la seconde masque la
|
|
420
|
+
* premiere sans que rien ne le signale.
|
|
421
|
+
*
|
|
422
|
+
* ⚠️ **A n'employer que pour ce qui peut etre manque.** Un message ephemere
|
|
423
|
+
* n'est pas une facon d'annoncer une erreur : si l'information compte, elle
|
|
424
|
+
* doit rester a l'ecran — `st-banner` pour la page, `st-inline-message` pour un
|
|
425
|
+
* champ. La regle de tri : si la personne qui n'a pas vu le message est
|
|
426
|
+
* penalisee, ce n'est pas un toast.
|
|
427
|
+
*/
|
|
428
|
+
declare class StToast {
|
|
429
|
+
private readonly overlay;
|
|
430
|
+
private couche;
|
|
431
|
+
private conteneur;
|
|
432
|
+
constructor();
|
|
433
|
+
/** Affiche un message. Rend son identifiant, pour pouvoir le retirer. */
|
|
434
|
+
montrer(demande: DemandeDeToast): number;
|
|
435
|
+
retirer(identifiant: number): void;
|
|
436
|
+
private pile;
|
|
437
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<StToast, never>;
|
|
438
|
+
static ɵprov: i0.ɵɵInjectableDeclaration<any>;
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
/**
|
|
442
|
+
* Pile des messages ephemeres. Un seul exemplaire, pose par `StToast`.
|
|
443
|
+
*
|
|
444
|
+
* ⚠️ **Les messages visibles ne portent AUCUN role.** L'annonce passe par deux
|
|
445
|
+
* regions vivantes permanentes, creees vides avec le conteneur. La premiere
|
|
446
|
+
* version posait `role="status"` sur chaque message insere avec son texte :
|
|
447
|
+
* c'est la sequence que les lecteurs d'ecran n'annoncent pas de facon fiable,
|
|
448
|
+
* puisqu'ils rapportent les CHANGEMENTS d'une region deja observee. Les
|
|
449
|
+
* confirmations — le cas courant — risquaient le silence.
|
|
450
|
+
*
|
|
451
|
+
* ⚠️ Il ne prend JAMAIS le focus. Un message qui s'affiche pendant une saisie
|
|
452
|
+
* et vole le curseur fait perdre la frappe en cours.
|
|
453
|
+
*/
|
|
454
|
+
declare class StToastContainer {
|
|
455
|
+
private readonly libelles;
|
|
456
|
+
private readonly pile;
|
|
457
|
+
private readonly minuteries;
|
|
458
|
+
private readonly minuteriesDAnnonce;
|
|
459
|
+
private compteur;
|
|
460
|
+
protected readonly messages: i0.Signal<readonly Toast[]>;
|
|
461
|
+
protected readonly annoncePolie: i0.WritableSignal<string>;
|
|
462
|
+
protected readonly annonceAssertive: i0.WritableSignal<string>;
|
|
463
|
+
protected readonly libelleFermeture: i0.Signal<string>;
|
|
464
|
+
constructor();
|
|
465
|
+
ajouter(demande: DemandeDeToast): number;
|
|
466
|
+
retirer(identifiant: number): void;
|
|
467
|
+
/**
|
|
468
|
+
* ⚠️ La minuterie s'arrete au survol ET au focus. Sans la seconde, une
|
|
469
|
+
* personne qui atteint le bouton au clavier le voit disparaitre sous son
|
|
470
|
+
* doigt ; sans la premiere, celle qui lit lentement n'a aucun moyen de
|
|
471
|
+
* retenir le message.
|
|
472
|
+
*/
|
|
473
|
+
protected suspendre(identifiant: number): void;
|
|
474
|
+
protected reprendre(identifiant: number): void;
|
|
475
|
+
protected agir(toast: Toast): void;
|
|
476
|
+
protected iconeDe(toast: Toast): NomDIcone;
|
|
477
|
+
/**
|
|
478
|
+
* ⚠️ Un message porteur d'action n'est JAMAIS evince. La premiere version
|
|
479
|
+
* gardait les trois plus recents sans distinction : trois confirmations
|
|
480
|
+
* successives faisaient disparaitre un « Annuler » en silence — exactement ce
|
|
481
|
+
* que WCAG 2.2.1 interdit, et ce que le modele promettait d'eviter.
|
|
482
|
+
*
|
|
483
|
+
* Les plus anciens messages sans action partent d'abord. S'il ne reste que des
|
|
484
|
+
* messages porteurs d'action, la borne cede : mieux vaut une pile haute qu'une
|
|
485
|
+
* annulation perdue.
|
|
486
|
+
*/
|
|
487
|
+
private borner;
|
|
488
|
+
private annoncer;
|
|
489
|
+
/**
|
|
490
|
+
* Un message porteur d'action ne s'efface pas seul : voir `DemandeDeToast`,
|
|
491
|
+
* et WCAG 2.2.1.
|
|
492
|
+
*/
|
|
493
|
+
private programmer;
|
|
494
|
+
private arreterLaMinuterie;
|
|
495
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<StToastContainer, never>;
|
|
496
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<StToastContainer, "st-toast-container", never, {}, {}, never, never, true, never>;
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
/** Reponse donnee a l'avertissement. */
|
|
500
|
+
type ReponseDInactivite = 'prolonger' | 'deconnecter';
|
|
501
|
+
/** Ce que l'avertissement passe a son panneau. */
|
|
502
|
+
interface DonneesDInactivite {
|
|
503
|
+
readonly restant: Signal<number>;
|
|
504
|
+
readonly identifiantDeDescription: string;
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
/**
|
|
508
|
+
* Avertissement avant fermeture de session pour inactivite.
|
|
509
|
+
*
|
|
510
|
+
* ```html
|
|
511
|
+
* <st-idle-warning
|
|
512
|
+
* [secondesRestantes]="inactivite.secondesRestantes()"
|
|
513
|
+
* (prolonge)="inactivite.prolonger()"
|
|
514
|
+
* (deconnecte)="session.deconnecter()"
|
|
515
|
+
* />
|
|
516
|
+
* ```
|
|
517
|
+
*
|
|
518
|
+
* ⚠️ **Composant de PRESENTATION.** Il n'injecte pas `StInactivite` : `ui` ne
|
|
519
|
+
* depend pas de `@starterlib/core` (ADR 0003). Il s'ouvre quand
|
|
520
|
+
* `secondesRestantes` cesse d'etre `null`, et se ferme quand il y revient. La
|
|
521
|
+
* decision de fermer la session reste au noyau, qui la prend cote serveur.
|
|
522
|
+
*
|
|
523
|
+
* ⚠️ **Un `alertdialog`, focus sur « Rester connecte ».** Le motif ARIA veut le
|
|
524
|
+
* focus sur l'action la moins destructrice : une touche Entree reflexe doit
|
|
525
|
+
* garder la session, jamais la fermer.
|
|
526
|
+
*
|
|
527
|
+
* ⚠️ **Le clic a cote ne prolonge rien**, pour la raison que donne `StInactivite`
|
|
528
|
+
* du noyau : le dialogue disparaitrait sans que la session ait ete prolongee cote
|
|
529
|
+
* serveur. Il faut repondre. Echap, geste delibere, vaut « Rester connecte ».
|
|
530
|
+
*/
|
|
531
|
+
declare class StIdleWarning {
|
|
532
|
+
private readonly dialogues;
|
|
533
|
+
/** `null` : aucun avertissement en cours. */
|
|
534
|
+
readonly secondesRestantes: i0.InputSignal<number | null>;
|
|
535
|
+
readonly prolonge: i0.OutputEmitterRef<void>;
|
|
536
|
+
readonly deconnecte: i0.OutputEmitterRef<void>;
|
|
537
|
+
private readonly restant;
|
|
538
|
+
private reference;
|
|
539
|
+
private readonly identifiantDeDescription;
|
|
540
|
+
constructor();
|
|
541
|
+
private ouvrir;
|
|
542
|
+
private fermerSansReponse;
|
|
543
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<StIdleWarning, never>;
|
|
544
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<StIdleWarning, "st-idle-warning", never, { "secondesRestantes": { "alias": "secondesRestantes"; "required": false; "isSignal": true; }; }, { "prolonge": "prolonge"; "deconnecte": "deconnecte"; }, never, never, true, never>;
|
|
545
|
+
}
|
|
546
|
+
|
|
547
|
+
/** Contenu du dialogue d'avertissement. Ouvert par `st-idle-warning`, jamais directement. */
|
|
548
|
+
declare class StIdleWarningPanel {
|
|
549
|
+
private readonly reference;
|
|
550
|
+
private readonly libelles;
|
|
551
|
+
private readonly locale;
|
|
552
|
+
protected readonly donnees: DonneesDInactivite;
|
|
553
|
+
protected readonly annonce: AnnonceLocale;
|
|
554
|
+
protected readonly titre: i0.Signal<string>;
|
|
555
|
+
protected readonly message: i0.Signal<string>;
|
|
556
|
+
protected readonly libelleRester: i0.Signal<string>;
|
|
557
|
+
protected readonly libelleDeconnecter: i0.Signal<string>;
|
|
558
|
+
constructor();
|
|
559
|
+
protected rester(): void;
|
|
560
|
+
protected deconnecter(): void;
|
|
561
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<StIdleWarningPanel, never>;
|
|
562
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<StIdleWarningPanel, "st-idle-warning-panel", never, {}, {}, never, never, true, never>;
|
|
563
|
+
}
|
|
564
|
+
|
|
565
|
+
type PositionDInfobulle = 'haut' | 'bas';
|
|
566
|
+
/**
|
|
567
|
+
* Infobulle : un complement de texte, au survol ET au focus.
|
|
568
|
+
*
|
|
569
|
+
* ```html
|
|
570
|
+
* <button stIconButton icone="corbeille" etiquette="Supprimer" stTooltip="Supprimer le beneficiaire"></button>
|
|
571
|
+
* ```
|
|
572
|
+
*
|
|
573
|
+
* WCAG 1.4.13, les trois exigences, chacune tenue ici :
|
|
574
|
+
*
|
|
575
|
+
* - **Refermable** : Echap la masque SANS deplacer le focus, et sans fermer le
|
|
576
|
+
* dialogue qui la contiendrait — la premiere touche est pour elle.
|
|
577
|
+
* - **Survolable** : le pointeur peut passer du declencheur a la bulle sans
|
|
578
|
+
* qu'elle disparaisse.
|
|
579
|
+
* - **Persistante** : elle reste tant que le survol ou le focus dure.
|
|
580
|
+
*
|
|
581
|
+
* ⚠️ **Le texte est une DESCRIPTION posee des le depart**, par un noeud
|
|
582
|
+
* persistant. Un `aria-describedby` qui viserait la bulle elle-meme pointerait
|
|
583
|
+
* vers un element absent au moment ou le focus arrive : le lecteur d'ecran,
|
|
584
|
+
* qui calcule la description a cet instant, ne lirait rien.
|
|
585
|
+
*
|
|
586
|
+
* ⚠️ **Jamais d'information exclusive, jamais de contenu interactif.** Sur un
|
|
587
|
+
* ecran tactile, il n'y a ni survol ni focus visible : l'infobulle n'existe pas.
|
|
588
|
+
* Ce qu'elle dit doit pouvoir manquer. Un lien ou un bouton dedans serait
|
|
589
|
+
* inatteignable — c'est un `st-popover` qu'il faut alors.
|
|
590
|
+
*/
|
|
591
|
+
declare class StTooltip {
|
|
592
|
+
private readonly element;
|
|
593
|
+
private readonly overlay;
|
|
594
|
+
private readonly descripteur;
|
|
595
|
+
private readonly document;
|
|
596
|
+
readonly stTooltip: i0.InputSignal<string>;
|
|
597
|
+
readonly positionDInfobulle: i0.InputSignal<PositionDInfobulle>;
|
|
598
|
+
private couche;
|
|
599
|
+
private minuterie;
|
|
600
|
+
private description;
|
|
601
|
+
private readonly echap;
|
|
602
|
+
constructor();
|
|
603
|
+
protected auSurvol(): void;
|
|
604
|
+
protected auDepartDuPointeur(): void;
|
|
605
|
+
afficher(): void;
|
|
606
|
+
masquer(): void;
|
|
607
|
+
private programmer;
|
|
608
|
+
private annulerLaMinuterie;
|
|
609
|
+
private retirerLaDescription;
|
|
610
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<StTooltip, never>;
|
|
611
|
+
static ɵdir: i0.ɵɵDirectiveDeclaration<StTooltip, "[stTooltip]", never, { "stTooltip": { "alias": "stTooltip"; "required": true; "isSignal": true; }; "positionDInfobulle": { "alias": "positionDInfobulle"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
|
|
612
|
+
}
|
|
613
|
+
|
|
614
|
+
/**
|
|
615
|
+
* Bulle visible d'une infobulle. Posee par `stTooltip`, jamais directement.
|
|
616
|
+
*
|
|
617
|
+
* ⚠️ Muette (`aria-hidden`) : le texte est deja lu comme DESCRIPTION du
|
|
618
|
+
* declencheur, par un noeud persistant. L'exposer aussi ici le ferait lire deux
|
|
619
|
+
* fois.
|
|
620
|
+
*/
|
|
621
|
+
declare class StTooltipPanel {
|
|
622
|
+
readonly texte: i0.InputSignal<string>;
|
|
623
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<StTooltipPanel, never>;
|
|
624
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<StTooltipPanel, "st-tooltip-panel", never, { "texte": { "alias": "texte"; "required": true; "isSignal": true; }; }, {}, never, never, true, never>;
|
|
625
|
+
}
|
|
626
|
+
|
|
627
|
+
type AlignementDePopover = 'debut' | 'fin';
|
|
628
|
+
/**
|
|
629
|
+
* Couche NON modale attachee a un declencheur : filtres rapides, detail d'une
|
|
630
|
+
* ligne, petit formulaire.
|
|
631
|
+
*
|
|
632
|
+
* ```html
|
|
633
|
+
* <button stButton [stPopoverTrigger]="filtres">Filtres</button>
|
|
634
|
+
* <st-popover #filtres etiquette="Filtres des operations">…</st-popover>
|
|
635
|
+
* ```
|
|
636
|
+
*
|
|
637
|
+
* Distinct de l'infobulle, qui ne contient que du texte, et du dialogue, qui
|
|
638
|
+
* piege le focus et met la page en retrait.
|
|
639
|
+
*
|
|
640
|
+
* ⚠️ **Non modale, donc aucun piege.** La tabulation peut en sortir, et la page
|
|
641
|
+
* reste utilisable. Mais une couche que le focus a quittee flotterait sans lien
|
|
642
|
+
* avec ce qu'on fait : elle se ferme quand le focus part ailleurs que sur elle
|
|
643
|
+
* ou son declencheur.
|
|
644
|
+
*
|
|
645
|
+
* ⚠️ **Deux fermetures, deux destinations du focus.** Echap rend le focus au
|
|
646
|
+
* declencheur : la personne n'a rien choisi d'autre. Un clic a l'exterieur le
|
|
647
|
+
* laisse la ou il a ete pose : le lui reprendre annulerait ce clic.
|
|
648
|
+
*
|
|
649
|
+
* Meme structure que `st-menu` : le declencheur DESIGNE la couche, et l'element
|
|
650
|
+
* est DEPLACE dans la couche d'overlay a l'ouverture, avec ses liaisons et son
|
|
651
|
+
* etat.
|
|
652
|
+
*/
|
|
653
|
+
declare class StPopover {
|
|
654
|
+
private readonly element;
|
|
655
|
+
private readonly overlay;
|
|
656
|
+
/** Nom accessible : sans lui, la couche s'annonce « dialogue » et rien d'autre. */
|
|
657
|
+
readonly etiquette: i0.InputSignal<string>;
|
|
658
|
+
readonly alignement: i0.InputSignal<AlignementDePopover>;
|
|
659
|
+
readonly identifiant: string;
|
|
660
|
+
private readonly ouvertInterne;
|
|
661
|
+
readonly ouvert: i0.Signal<boolean>;
|
|
662
|
+
private couche;
|
|
663
|
+
private declencheur;
|
|
664
|
+
constructor();
|
|
665
|
+
basculerDepuis(declencheur: HTMLElement): void;
|
|
666
|
+
ouvrirDepuis(declencheur: HTMLElement): void;
|
|
667
|
+
fermer(options?: {
|
|
668
|
+
readonly rendreLeFocus?: boolean;
|
|
669
|
+
}): void;
|
|
670
|
+
protected auClavier(evenement: KeyboardEvent): void;
|
|
671
|
+
/**
|
|
672
|
+
* ⚠️ L'element actif est lu APRES la transition de focus, et non dans
|
|
673
|
+
* `relatedTarget`. Ce dernier est vide quand le focus part vers un element
|
|
674
|
+
* sans focus, et n'est pas renseigne partout ; pendant la transition elle-meme,
|
|
675
|
+
* l'element actif est encore le corps du document.
|
|
676
|
+
*/
|
|
677
|
+
protected aLaPerteDuFocus(): void;
|
|
678
|
+
private detruireLaCouche;
|
|
679
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<StPopover, never>;
|
|
680
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<StPopover, "st-popover", never, { "etiquette": { "alias": "etiquette"; "required": true; "isSignal": true; }; "alignement": { "alias": "alignement"; "required": false; "isSignal": true; }; }, {}, never, ["*"], true, never>;
|
|
681
|
+
}
|
|
682
|
+
|
|
683
|
+
/**
|
|
684
|
+
* Declencheur d'un `st-popover`.
|
|
685
|
+
*
|
|
686
|
+
* ⚠️ `aria-controls` vise la couche meme fermee : le lien entre les deux existe
|
|
687
|
+
* pour les technologies d'assistance avant l'ouverture, et `aria-expanded` dit
|
|
688
|
+
* son etat.
|
|
689
|
+
*/
|
|
690
|
+
declare class StPopoverTrigger {
|
|
691
|
+
private readonly element;
|
|
692
|
+
readonly stPopoverTrigger: i0.InputSignal<StPopover>;
|
|
693
|
+
protected basculer(): void;
|
|
694
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<StPopoverTrigger, never>;
|
|
695
|
+
static ɵdir: i0.ɵɵDirectiveDeclaration<StPopoverTrigger, "[stPopoverTrigger]", never, { "stPopoverTrigger": { "alias": "stPopoverTrigger"; "required": true; "isSignal": true; }; }, {}, never, never, true, never>;
|
|
696
|
+
}
|
|
697
|
+
|
|
698
|
+
export { IDENTIFIANT_DU_TITRE, StConfirmDialog, StDialog, StDialogActions, StDialogContainer, StDialogContent, StDialogTitle, StIdleWarning, StIdleWarningPanel, StMenu, StMenuItem, StMenuTrigger, StPopover, StPopoverTrigger, StToast, StToastContainer, StTooltip, StTooltipPanel };
|
|
699
|
+
export type { ActionDeToast, AlignementDeMenu, AlignementDePopover, CoteDuTiroir, DemandeDeConfirmation, DemandeDeToast, DonneesDInactivite, OptionsDeDialogue, PositionDInfobulle, ReferenceDeDialogue, ReponseDInactivite, Toast, TonDElementDeMenu };
|