@starterlib/ui 0.7.2 → 0.8.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.
Files changed (35) hide show
  1. package/README.md +95 -42
  2. package/fesm2022/starterlib-ui-arbre.mjs +82 -0
  3. package/fesm2022/starterlib-ui-arbre.mjs.map +1 -0
  4. package/fesm2022/starterlib-ui-donnees.mjs +532 -0
  5. package/fesm2022/starterlib-ui-donnees.mjs.map +1 -0
  6. package/fesm2022/starterlib-ui-formulaires.mjs +2 -1
  7. package/fesm2022/starterlib-ui-formulaires.mjs.map +1 -1
  8. package/fesm2022/starterlib-ui-interactions.mjs +34 -589
  9. package/fesm2022/starterlib-ui-interactions.mjs.map +1 -1
  10. package/fesm2022/starterlib-ui-libelles-en.mjs +142 -0
  11. package/fesm2022/starterlib-ui-libelles-en.mjs.map +1 -0
  12. package/fesm2022/starterlib-ui-listes.mjs +671 -0
  13. package/fesm2022/starterlib-ui-listes.mjs.map +1 -0
  14. package/fesm2022/starterlib-ui-navigation.mjs +246 -0
  15. package/fesm2022/starterlib-ui-navigation.mjs.map +1 -0
  16. package/fesm2022/starterlib-ui-onglets.mjs +137 -0
  17. package/fesm2022/starterlib-ui-onglets.mjs.map +1 -0
  18. package/fesm2022/starterlib-ui-saisie.mjs +1632 -0
  19. package/fesm2022/starterlib-ui-saisie.mjs.map +1 -0
  20. package/fesm2022/starterlib-ui-selection.mjs +269 -0
  21. package/fesm2022/starterlib-ui-selection.mjs.map +1 -0
  22. package/fesm2022/starterlib-ui.mjs +105 -2931
  23. package/fesm2022/starterlib-ui.mjs.map +1 -1
  24. package/package.json +35 -3
  25. package/types/starterlib-ui-arbre.d.ts +51 -0
  26. package/types/starterlib-ui-donnees.d.ts +228 -0
  27. package/types/starterlib-ui-formulaires.d.ts +5 -4
  28. package/types/starterlib-ui-interactions.d.ts +4 -316
  29. package/types/starterlib-ui-libelles-en.d.ts +25 -0
  30. package/types/starterlib-ui-listes.d.ts +432 -0
  31. package/types/starterlib-ui-navigation.d.ts +104 -0
  32. package/types/starterlib-ui-onglets.d.ts +89 -0
  33. package/types/starterlib-ui-saisie.d.ts +924 -0
  34. package/types/starterlib-ui-selection.d.ts +112 -0
  35. package/types/starterlib-ui.d.ts +9 -1575
@@ -1,316 +1,4 @@
1
- import * as _angular_core from '@angular/core';
2
- import * as i1 from '@angular/aria/tabs';
3
- import * as _starterlib_ui from '@starterlib/ui';
4
- import { ControleDeSaisie, OptionDeListe, AnnonceLocale, ContratDeChamp } from '@starterlib/ui';
5
- import { FormValueControl } from '@angular/forms/signals';
6
-
7
- /** Un onglet, decrit par l'appelant. */
8
- interface Onglet {
9
- /** Identifiant stable, qui relie l'onglet a son `st-tab-panel`. */
10
- readonly valeur: string;
11
- readonly libelle: string;
12
- readonly desactive?: boolean;
13
- }
14
- type ActivationDOnglet = 'manuelle' | 'automatique';
15
- type OrientationDOnglets = 'horizontale' | 'verticale';
16
- /**
17
- * Onglets, sur les primitives `@angular/aria/tabs`.
18
- *
19
- * ```html
20
- * <st-tabs etiquette="Compte" [onglets]="onglets" [(selection)]="onglet">
21
- * <st-tab-panel valeur="operations">
22
- * <ng-template stTabContent><app-operations /></ng-template>
23
- * </st-tab-panel>
24
- * <st-tab-panel valeur="virements">
25
- * <ng-template stTabContent><app-virements /></ng-template>
26
- * </st-tab-panel>
27
- * </st-tabs>
28
- * ```
29
- *
30
- * ⚠️ **La liste d'onglets est rendue par le composant, a partir de donnees**, et
31
- * non projetee. Les primitives d'Aria relient un onglet a sa liste par
32
- * INJECTION, et un contenu projete garde l'injecteur de l'endroit ou il est
33
- * ecrit : c'est la lecon de `st-menu`, ou des elements projetes ne
34
- * s'enregistraient jamais. Rendue ici, la liste est a coup sur sous la bonne
35
- * primitive — et ses valeurs peuvent etre dites en francais.
36
- *
37
- * Les PANNEAUX, eux, sont projetes : ecrits directement sous `st-tabs`, leur
38
- * injecteur parent est celui de l'hote, qui porte la primitive `Tabs`.
39
- *
40
- * ⚠️ **Activation manuelle par defaut.** En activation automatique, chaque
41
- * fleche SELECTIONNE l'onglet atteint ; son contenu differe se rend, et charge
42
- * ses donnees. Parcourir cinq onglets au clavier lancerait cinq requetes pour en
43
- * lire un. En manuelle, les fleches deplacent le focus et Entree ou Espace
44
- * selectionne. `automatique` reste le bon choix quand les panneaux sont deja la
45
- * et s'affichent sans delai.
46
- */
47
- declare class StTabs {
48
- readonly onglets: _angular_core.InputSignal<readonly Onglet[]>;
49
- /** Nom accessible de la liste : sans lui, plusieurs listes d'onglets se confondent. */
50
- readonly etiquette: _angular_core.InputSignal<string>;
51
- readonly activation: _angular_core.InputSignal<ActivationDOnglet>;
52
- readonly orientation: _angular_core.InputSignal<OrientationDOnglets>;
53
- /** Valeur de l'onglet selectionne. `undefined` : le premier onglet disponible. */
54
- readonly selection: _angular_core.ModelSignal<string | undefined>;
55
- /**
56
- * ⚠️ Toujours un onglet selectionne. Le motif ARIA l'exige : une liste sans
57
- * selection n'affiche aucun panneau, et la page parait vide sans raison.
58
- */
59
- protected readonly selectionEffective: _angular_core.Signal<string | undefined>;
60
- protected readonly modeAria: _angular_core.Signal<"follow" | "explicit">;
61
- protected readonly orientationAria: _angular_core.Signal<"vertical" | "horizontal">;
62
- static ɵfac: _angular_core.ɵɵFactoryDeclaration<StTabs, never>;
63
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<StTabs, "st-tabs", never, { "onglets": { "alias": "onglets"; "required": true; "isSignal": true; }; "etiquette": { "alias": "etiquette"; "required": true; "isSignal": true; }; "activation": { "alias": "activation"; "required": false; "isSignal": true; }; "orientation": { "alias": "orientation"; "required": false; "isSignal": true; }; "selection": { "alias": "selection"; "required": false; "isSignal": true; }; }, { "selection": "selectionChange"; }, never, ["*"], true, [{ directive: typeof i1.Tabs; inputs: {}; outputs: {}; }]>;
64
- }
65
-
66
- /**
67
- * Panneau d'un onglet, relie par sa `valeur`.
68
- *
69
- * ⚠️ La primitive d'Aria ne masque RIEN : elle pose `inert` sur le panneau
70
- * inactif, ce qui le retire de l'arbre d'accessibilite et du clavier, mais le
71
- * laisse a l'ecran. Sa documentation le dit en une ligne. Sans le style de ce
72
- * composant, tous les panneaux s'affichaient empiles, muets et intouchables.
73
- */
74
- declare class StTabPanel {
75
- static ɵfac: _angular_core.ɵɵFactoryDeclaration<StTabPanel, never>;
76
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<StTabPanel, "st-tab-panel", never, {}, {}, never, ["*"], true, [{ directive: typeof i1.TabPanel; inputs: { "value": "valeur"; }; outputs: {}; }]>;
77
- }
78
-
79
- /**
80
- * Contenu differe d'un panneau : rendu a la premiere selection de son onglet.
81
- *
82
- * Un ecran a cinq onglets ne charge ainsi que celui qu'on regarde. Voir
83
- * l'activation manuelle de `st-tabs` : c'est ce qui empeche qu'un simple
84
- * parcours au clavier les rende tous.
85
- */
86
- declare class StTabContent {
87
- static ɵfac: _angular_core.ɵɵFactoryDeclaration<StTabContent, never>;
88
- static ɵdir: _angular_core.ɵɵDirectiveDeclaration<StTabContent, "ng-template[stTabContent]", never, {}, {}, never, never, true, [{ directive: typeof i1.TabContent; inputs: {}; outputs: {}; }]>;
89
- }
90
-
91
- type ModeDeNavigation = 'auto' | 'persistant' | 'modal';
92
- /**
93
- * Navigation laterale : une region a cote du contenu sur grand ecran, un tiroir
94
- * sur petit ecran.
95
- *
96
- * ```html
97
- * <st-app-shell>
98
- * <button entete stButton [stSidenavToggle]="navigation">Menu</button>
99
- * <st-sidenav navigation #navigation etiquette="Navigation principale">
100
- * <a routerLink="/comptes">Comptes</a>
101
- * </st-sidenav>
102
- * …
103
- * </st-app-shell>
104
- * ```
105
- *
106
- * ⚠️ **Deux modes, jamais confondus.** Persistante, c'est une REGION de la page :
107
- * aucun piege, rien a ouvrir. Modale, c'est un TIROIR, donc un `StDialog` — role,
108
- * piegeage du focus, Echap, retour du focus au bouton — et non une region
109
- * glissee par-dessus la page avec un peu de CSS, qui laisserait le clavier
110
- * parcourir la page cachee dessous.
111
- *
112
- * ⚠️ **Elle porte son propre `<nav>`, et un seul a la fois.** Sur petit ecran,
113
- * la region en ligne DISPARAIT quand le tiroir prend le relais : laissee en
114
- * place, elle resterait un repere de navigation vide, que le lecteur d'ecran
115
- * proposerait sans rien y trouver.
116
- *
117
- * Un lien suivi dans le tiroir le ferme : `StDialog` se ferme a toute navigation
118
- * du routeur.
119
- */
120
- declare class StSidenav {
121
- private readonly dialogues;
122
- private readonly libelles;
123
- /**
124
- * Nom du repere. `null` : « Navigation principale », du dictionnaire. A
125
- * renseigner des qu'une page compte deux navigations, qui doivent se
126
- * distinguer.
127
- */
128
- readonly etiquette: _angular_core.InputSignal<string | null>;
129
- protected readonly etiquetteLue: _angular_core.Signal<string>;
130
- /** `auto` : persistante sur grand ecran, tiroir en dessous. */
131
- readonly mode: _angular_core.InputSignal<ModeDeNavigation>;
132
- readonly identifiant: string;
133
- private readonly ecranLarge;
134
- /** Mode reellement applique. Lu par le bouton, qui ne s'affiche qu'en tiroir. */
135
- readonly modeEffectif: _angular_core.Signal<"persistant" | "modal">;
136
- private readonly ouvertInterne;
137
- readonly ouvert: _angular_core.Signal<boolean>;
138
- private readonly gabarit;
139
- private reference;
140
- constructor();
141
- ouvrir(): void;
142
- fermer(): void;
143
- basculer(): void;
144
- static ɵfac: _angular_core.ɵɵFactoryDeclaration<StSidenav, never>;
145
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<StSidenav, "st-sidenav", never, { "etiquette": { "alias": "etiquette"; "required": false; "isSignal": true; }; "mode": { "alias": "mode"; "required": false; "isSignal": true; }; }, {}, never, ["*"], true, never>;
146
- }
147
-
148
- /**
149
- * Bouton qui ouvre la navigation en tiroir.
150
- *
151
- * ⚠️ **Masque quand la navigation est persistante.** Un bouton « Menu » qui ne
152
- * fait rien, parce que la navigation est deja affichee a cote, est un arret de
153
- * tabulation inutile et une promesse non tenue.
154
- *
155
- * ⚠️ `aria-expanded` suit l'ouverture du tiroir : sans lui, rien ne dit a qui
156
- * n'en voit pas l'effet que le bouton a agi.
157
- */
158
- declare class StSidenavToggle {
159
- readonly stSidenavToggle: _angular_core.InputSignal<StSidenav>;
160
- static ɵfac: _angular_core.ɵɵFactoryDeclaration<StSidenavToggle, never>;
161
- static ɵdir: _angular_core.ɵɵDirectiveDeclaration<StSidenavToggle, "[stSidenavToggle]", never, { "stSidenavToggle": { "alias": "stSidenavToggle"; "required": true; "isSignal": true; }; }, {}, never, never, true, never>;
162
- }
163
-
164
- /** `local` : le composant filtre `options`. `distant` : l'application filtre, sur `recherche`. */
165
- type FiltrageDeListe = 'local' | 'distant';
166
- /**
167
- * Liste de choix a filtrer en tapant, sur `@angular/aria/combobox` et
168
- * `@angular/aria/listbox`.
169
- *
170
- * ```html
171
- * <st-combobox libelle="Beneficiaire" [options]="beneficiaires" [formField]="virement.beneficiaire" />
172
- * <!-- liste servie par le serveur : -->
173
- * <st-combobox libelle="Commune" filtrage="distant" [options]="communes()"
174
- * (recherche)="terme.set($event)" [formField]="adresse.commune" />
175
- * ```
176
- *
177
- * Le modele est la VALEUR de l'option choisie, `''` sans choix. Le texte tape ne
178
- * part jamais dans le modele : « Pari » n'est pas une commune.
179
- *
180
- * ⚠️ **Pour une longue liste seulement.** Sous une vingtaine d'options,
181
- * `st-select` — natif — est plus sur, et plus rapide sur mobile.
182
- *
183
- * - La liste s'ouvre a la frappe et a la fleche bas ; Entree choisit, Echap
184
- * ferme. Le focus reste dans le champ (`aria-activedescendant`).
185
- * - Le nombre de resultats s'annonce apres la frappe, une fois : le lecteur
186
- * d'ecran ne voit pas la liste se reduire.
187
- * - ⚠️ **Quitter le champ sans choisir rend le texte du choix precedent.** Un
188
- * texte qui ne correspond a aucune option ne reste pas affiche comme s'il etait
189
- * retenu ; un champ vide, lui, retire le choix.
190
- * - La liste est posee dans la couche superieure du navigateur (`popover`) par le
191
- * CDK : un dialogue ou un tableau defilant ne la rogne pas.
192
- *
193
- * ⚠️ En `distant`, `recherche` est emis a chaque frappe : a l'application de
194
- * temporiser, et de ne pas mettre le terme dans l'adresse (SEC-6).
195
- */
196
- declare class StCombobox extends ControleDeSaisie {
197
- protected readonly libelles: _angular_core.Signal<_starterlib_ui.LibellesUi>;
198
- private readonly element;
199
- private readonly injecteur;
200
- readonly options: _angular_core.InputSignal<readonly OptionDeListe[]>;
201
- readonly filtrage: _angular_core.InputSignal<FiltrageDeListe>;
202
- /** Texte tape, a chaque frappe. Sert au filtrage `distant`. */
203
- readonly recherche: _angular_core.OutputEmitterRef<string>;
204
- protected readonly annonce: AnnonceLocale;
205
- protected readonly ouvert: _angular_core.WritableSignal<boolean>;
206
- /** Texte du champ : le libelle du choix, tant que la personne ne tape pas. */
207
- protected readonly texte: _angular_core.WritableSignal<string>;
208
- /** Ce qui filtre : vide a l'ouverture par la fleche, pour montrer toute la liste. */
209
- private readonly filtre;
210
- /** Option active dans la liste ; le choix n'est retenu qu'a la validation. */
211
- protected readonly surlignee: _angular_core.WritableSignal<string[]>;
212
- protected readonly visibles: _angular_core.Signal<readonly OptionDeListe[]>;
213
- private readonly liste;
214
- constructor();
215
- protected surSaisie(evenement: Event): void;
216
- protected basculer(): void;
217
- protected valider(): void;
218
- protected aLaSortie(evenement: FocusEvent): void;
219
- private libelleDe;
220
- static ɵfac: _angular_core.ɵɵFactoryDeclaration<StCombobox, never>;
221
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<StCombobox, "st-combobox", never, { "options": { "alias": "options"; "required": true; "isSignal": true; }; "filtrage": { "alias": "filtrage"; "required": false; "isSignal": true; }; }, { "recherche": "recherche"; }, never, never, true, never>;
222
- }
223
-
224
- /**
225
- * Choix de plusieurs valeurs dans une liste, sur `@angular/aria/combobox` et
226
- * `@angular/aria/listbox`.
227
- *
228
- * ```html
229
- * <st-multiselect libelle="Comptes a inclure" [options]="comptes" [formField]="releve.comptes" />
230
- * ```
231
- *
232
- * Le modele est la liste des VALEURS choisies, dans l'ordre des options.
233
- *
234
- * - Fleche bas, Entree ou Espace ouvrent la liste ; Espace coche ou decoche
235
- * l'option active sans fermer ; Echap ferme.
236
- * - ⚠️ **Chaque choix reste visible et retirable** sous le champ, par un bouton
237
- * « Retirer … ». Un resume « 3 choix » dans le declencheur ne dit pas lesquels,
238
- * et obligerait a rouvrir la liste pour en retirer un.
239
- * - Un choix retire rend le focus au retrait suivant, ou au champ : le focus ne
240
- * tombe jamais sur le document.
241
- *
242
- * ⚠️ Sous une dizaine d'options, un groupe de cases a cocher (`st-fieldset` et
243
- * `st-checkbox`) est plus simple : tout est visible, rien a ouvrir.
244
- */
245
- declare class StMultiselect extends ContratDeChamp implements FormValueControl<readonly string[]> {
246
- protected readonly libelles: _angular_core.Signal<_starterlib_ui.LibellesUi>;
247
- private readonly element;
248
- private readonly injecteur;
249
- readonly value: _angular_core.ModelSignal<readonly string[]>;
250
- readonly options: _angular_core.InputSignal<readonly OptionDeListe[]>;
251
- protected readonly annonce: AnnonceLocale;
252
- protected readonly ouvert: _angular_core.WritableSignal<boolean>;
253
- private readonly liste;
254
- /** La liste d'Aria attend un tableau modifiable ; le modele, lui, est en lecture seule. */
255
- protected readonly valeursDeListe: _angular_core.Signal<string[]>;
256
- protected readonly choisies: _angular_core.Signal<OptionDeListe[]>;
257
- protected readonly resume: _angular_core.Signal<string>;
258
- constructor();
259
- /** Le declencheur n'est pas un champ natif : la base ne le trouve pas par `#champ`. */
260
- focus(options?: FocusOptions): void;
261
- protected surChoix(valeurs: readonly string[]): void;
262
- protected retirer(valeur: string, indice: number): void;
263
- protected aLaSortie(evenement: FocusEvent): void;
264
- static ɵfac: _angular_core.ɵɵFactoryDeclaration<StMultiselect, never>;
265
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<StMultiselect, "st-multiselect", never, { "value": { "alias": "value"; "required": false; "isSignal": true; }; "options": { "alias": "options"; "required": true; "isSignal": true; }; }, { "value": "valueChange"; }, never, never, true, never>;
266
- }
267
-
268
- /** Un noeud, decrit en donnees. */
269
- interface NoeudDArbre {
270
- /** Identifiant stable : il porte la selection et le depliage. */
271
- readonly valeur: string;
272
- readonly libelle: string;
273
- readonly enfants?: readonly NoeudDArbre[];
274
- readonly desactive?: boolean;
275
- }
276
- /**
277
- * Arbre de donnees hierarchiques, sur `@angular/aria/tree` : dossiers, plan
278
- * comptable, organisation.
279
- *
280
- * ```html
281
- * <st-tree etiquette="Plan comptable" [noeuds]="comptes" [(selection)]="compte" [(deplies)]="ouverts" />
282
- * ```
283
- *
284
- * ⚠️ **Jamais pour la navigation du site** (UX-17) : une navigation est une liste
285
- * de liens, que le lecteur d'ecran liste et parcourt comme telle. Un arbre se
286
- * parcourt aux fleches, un element a la fois, et ses elements ne sont pas des
287
- * liens. Le mode « navigation » de la primitive n'est donc pas expose.
288
- *
289
- * ⚠️ **Les noeuds sont rendus par le composant, a partir de donnees** (FE-6) : la
290
- * primitive relie un element a son arbre par injection, et un contenu projete
291
- * garde l'injecteur de l'endroit ou il est ecrit — lecon de `st-menu`.
292
- *
293
- * Clavier de la primitive : fleches haut et bas entre les elements visibles,
294
- * droite pour deplier ou entrer, gauche pour replier ou remonter, Debut et Fin,
295
- * recherche a la frappe ; Espace ou Entree choisit. Selection et depliage sont des
296
- * listes de VALEURS, lisibles et restaurables par l'application.
297
- */
298
- declare class StTree {
299
- /** Nom de l'arbre, lu a l'entree. Obligatoire. */
300
- readonly etiquette: _angular_core.InputSignal<string>;
301
- readonly noeuds: _angular_core.InputSignal<readonly NoeudDArbre[]>;
302
- readonly multiple: _angular_core.InputSignalWithTransform<boolean, unknown>;
303
- readonly selection: _angular_core.ModelSignal<readonly string[]>;
304
- readonly deplies: _angular_core.ModelSignal<readonly string[]>;
305
- /** La primitive attend un tableau modifiable ; le modele est en lecture seule. */
306
- protected readonly valeursChoisies: _angular_core.Signal<string[]>;
307
- private readonly ensembleDeplie;
308
- protected estDeplie(noeud: NoeudDArbre): boolean;
309
- protected surDepliage(noeud: NoeudDArbre, deplie: boolean): void;
310
- protected surSelection(valeurs: readonly string[]): void;
311
- static ɵfac: _angular_core.ɵɵFactoryDeclaration<StTree, never>;
312
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<StTree, "st-tree", never, { "etiquette": { "alias": "etiquette"; "required": true; "isSignal": true; }; "noeuds": { "alias": "noeuds"; "required": true; "isSignal": true; }; "multiple": { "alias": "multiple"; "required": false; "isSignal": true; }; "selection": { "alias": "selection"; "required": false; "isSignal": true; }; "deplies": { "alias": "deplies"; "required": false; "isSignal": true; }; }, { "selection": "selectionChange"; "deplies": "depliesChange"; }, never, never, true, never>;
313
- }
314
-
315
- export { StCombobox, StMultiselect, StSidenav, StSidenavToggle, StTabContent, StTabPanel, StTabs, StTree };
316
- export type { ActivationDOnglet, FiltrageDeListe, ModeDeNavigation, NoeudDArbre, Onglet, OrientationDOnglets };
1
+ export * from '@starterlib/ui/onglets';
2
+ export * from '@starterlib/ui/navigation';
3
+ export * from '@starterlib/ui/selection';
4
+ export * from '@starterlib/ui/arbre';
@@ -0,0 +1,25 @@
1
+ import { LibellesUi } from '@starterlib/ui';
2
+
3
+ /**
4
+ * @starterlib/ui/libelles-en — le catalogue anglais des textes portes par les
5
+ * composants.
6
+ *
7
+ * ⚠️ Un point d'entree separe pour une raison de MOMENT, et non de dependance
8
+ * (ADR 0031, decision 2) : une application francaise n'affiche jamais ces
9
+ * textes, et laisses au tronc ils partaient dans le train de singletons de
10
+ * TOUTE application federee. Une langue se charge quand on en change.
11
+ *
12
+ * ```ts
13
+ * const { LIBELLES_EN } = await import('@starterlib/ui/libelles-en');
14
+ * ```
15
+ *
16
+ * ⚠️ Les textes AFFICHES portent leurs accents et leurs apostrophes
17
+ * typographiques, ecrits en sequence d'echappement pour garder la source en
18
+ * ASCII. La regle « sans accents » du depot vise la documentation, jamais ce
19
+ * que lit la personne devant l'ecran.
20
+ */
21
+
22
+ /** Traduction anglaise du meme dictionnaire. La paire est obligatoire. */
23
+ declare const LIBELLES_EN: LibellesUi;
24
+
25
+ export { LIBELLES_EN };