@starterlib/ui 0.3.0 → 0.5.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 CHANGED
@@ -14,22 +14,24 @@ des dependances de pair : c'est l'application qui les installe, et elles doivent
14
14
  etre **identiques dans l'hote et dans chaque remote**. Deux versions du socle
15
15
  dans le meme navigateur, ce sont deux jeux de jetons d'injection.
16
16
 
17
- ## Trois points d'entree
17
+ ## Quatre points d'entree
18
18
 
19
19
  Un composant sort du tronc quand il traine un pair lourd, et seulement alors ;
20
20
  le point d'entree secondaire ou il va se choisit ensuite par ce qu'il EST pour
21
21
  qui l'emploie.
22
22
 
23
- | Point d'entree | Contenu | Ce qu'il traine | Gzippe |
24
- | ----------------------------- | ------------------------------------------------------------------------------------------ | -------------------------------------------------- | ------- |
25
- | `@starterlib/ui` | le tronc : etats, texte, actions, structure, transverses | `@angular/router`, deja exige par `core` | 22,4 Ko |
26
- | `@starterlib/ui/surfaces` | ce qui se pose AU-DESSUS de la page : menu, dialogues, tiroirs, messages ephemeres | `@angular/cdk`, `@angular/aria/menu` | 7,1 Ko |
27
- | `@starterlib/ui/interactions` | ce qui fait PARTIE de la page et traine Aria ou une surface : onglets, navigation laterale | `@angular/aria`, qui exige lui-meme `@angular/cdk` | 2,0 Ko |
23
+ | Point d'entree | Contenu | Ce qu'il traine a l'execution | Gzippe |
24
+ | ----------------------------- | ----------------------------------------------------------------------------------------------------------- | -------------------------------------------------- | ------- |
25
+ | `@starterlib/ui` | le tronc : etats, texte, actions, structure, transverses, saisie native, calendrier, listes et tableaux | `@angular/router`, deja exige par `core` | 48,8 Ko |
26
+ | `@starterlib/ui/surfaces` | ce qui se pose AU-DESSUS de la page : menu, dialogues, tiroirs, messages ephemeres | `@angular/cdk`, `@angular/aria/menu` | 9,7 Ko |
27
+ | `@starterlib/ui/interactions` | ce qui fait PARTIE de la page et traine Aria ou une surface : onglets, navigation laterale, combobox, arbre | `@angular/aria`, qui exige lui-meme `@angular/cdk` | 8,1 Ko |
28
+ | `@starterlib/ui/formulaires` | les champs qui LISENT leur saisie : montant, date, plage de dates | le code d'`@angular/forms` (`transformedValue`) | 4,5 Ko |
28
29
 
29
30
  ```ts
30
- import { StButton, StAppShell } from '@starterlib/ui';
31
+ import { StButton, StInput, StSelect } from '@starterlib/ui';
31
32
  import { StDialog, StToast } from '@starterlib/ui/surfaces';
32
- import { StTabs, StTabPanel, StTabContent } from '@starterlib/ui/interactions';
33
+ import { StTabs, StCombobox, StMultiselect } from '@starterlib/ui/interactions';
34
+ import { StAmountField, StDateField } from '@starterlib/ui/formulaires';
33
35
  ```
34
36
 
35
37
  ⚠️ Un paquet partage en federation **ne s'elague pas** : declare singleton, il
@@ -38,17 +40,21 @@ pour but le poids, mais le **train de singletons** : une application qui
38
40
  n'affiche ni menu, ni dialogue, ni onglets ne charge ni le CDK ni Aria, et n'a
39
41
  pas a se redeployer quand ils montent de version.
40
42
 
41
- `@angular/cdk` et `@angular/aria` sont des pairs **optionnels** : le tronc ne les
42
- importe pas. Ils deviennent obligatoires des le premier import d'un point
43
- d'entree secondaire, et leur absence se voit alors a la resolution, pas a
44
- l'execution. ⚠️ `@angular/aria` exige `@angular/cdk` a la version EXACTE : les
45
- deux montent ensemble.
43
+ `@angular/cdk`, `@angular/aria` et `@angular/forms` sont des pairs
44
+ **optionnels** : le tronc n'en importe que des TYPES. Ils deviennent obligatoires
45
+ des le premier import d'un point d'entree secondaire qui les emploie, et leur
46
+ absence se voit alors a la resolution, pas a l'execution. ⚠️ `@angular/aria`
47
+ exige `@angular/cdk` a la version EXACTE : les deux montent ensemble.
46
48
 
47
- ⚠️ **En federation, chaque point d'entree se partage SEPAREMENT.** Ce sont trois
48
- specificateurs de module distincts : partager `@starterlib/ui` ne couvre ni
49
- `surfaces` ni `interactions`. Omis de la configuration, chaque remote en embarque
50
- sa propre copie — et la regle `singleton: true, strictVersion: true` qui protege
51
- le tronc ne protege plus rien au-dessus.
49
+ Ce que chaque point d'entree importe a l'execution est verifie sur le paquet
50
+ construit (`pnpm paquets:check`) : un import de trop dans le tronc echoue avant
51
+ la publication.
52
+
53
+ ⚠️ **En federation, chaque point d'entree se partage SEPAREMENT.** Ce sont quatre
54
+ specificateurs de module distincts : partager `@starterlib/ui` ne couvre aucun
55
+ des trois autres. Omis de la configuration, chaque remote en embarque sa propre
56
+ copie — et la regle `singleton: true, strictVersion: true` qui protege le tronc
57
+ ne protege plus rien au-dessus.
52
58
 
53
59
  ```js
54
60
  // federation.config.mjs de l'hote ET de chaque remote
@@ -56,6 +62,7 @@ shared: {
56
62
  '@starterlib/ui': { singleton: true, strictVersion: true },
57
63
  '@starterlib/ui/surfaces': { singleton: true, strictVersion: true },
58
64
  '@starterlib/ui/interactions': { singleton: true, strictVersion: true },
65
+ '@starterlib/ui/formulaires': { singleton: true, strictVersion: true },
59
66
  // ...
60
67
  }
61
68
  ```
@@ -148,8 +155,74 @@ Vague 2 :
148
155
  - **`ui/interactions`** — `st-tabs`, `st-tab-panel`, `stTabContent`, `st-sidenav`,
149
156
  `stSidenavToggle`.
150
157
 
151
- Inventaire et regles de la suite : `docs/plan-librairie.md` et
152
- `docs/audit-vague-2-2026-09-17.md` du depot.
158
+ Vague 3 — la saisie, sur Signal Forms :
159
+
160
+ - **Tronc** — `st-form-field`, `st-input`, `st-textarea`, `st-fieldset`,
161
+ `st-checkbox`, `st-radio-group`, `st-switch`, `st-error-summary`,
162
+ `st-password-field`, `st-otp-field`, `st-search-field`, `st-iban-field`,
163
+ `st-phone-field`, `st-select` (natif), `st-file-upload`, `st-calendar` ;
164
+ messages d'erreur traduits et fonctions de schema (`erreurIban`,
165
+ `erreurTelephone`, `erreurDate`, `erreurPlageDeDates`, `erreursDeFichiers`).
166
+ - **`ui/interactions`** — `st-combobox`, `st-multiselect`.
167
+ - **`ui/formulaires`** — `st-amount-field`, `st-date-field`, `st-date-range`.
168
+
169
+ Un champ s'emploie avec un formulaire, par `[formField]`, ou seul, par
170
+ `[(value)]`. Les regles d'un schema sont des fonctions PURES du socle, a brancher
171
+ par `validate` : les fournir toutes faites importerait `@angular/forms` a
172
+ l'execution dans le tronc.
173
+
174
+ ```ts
175
+ readonly virement = form(this.modele, (chemin) => {
176
+ required(chemin.beneficiaire);
177
+ validate(chemin.iban, ({ value }) => erreurIban(value()));
178
+ validate(chemin.execution, ({ value }) => erreurDate(value(), { min: aujourdHui }));
179
+ });
180
+ ```
181
+
182
+ Vague 4 — listes et tableaux, au contrat du backend (curseur vers l'avant, sans
183
+ total ni tri serveur) :
184
+
185
+ - **Tronc** — `st-data-table` (`stCellule`, `stTableauVide`, `stActionsDeTableau`),
186
+ `st-sort-header`, `st-pagination`, `st-list` (`stElementDeListe`),
187
+ `st-description-list` (`stDescription`), `st-filter-bar`, `st-filter-chip`.
188
+ - **`ui/interactions`** — `st-tree`.
189
+ - **`@starterlib/core`** — `NavigationParCurseur` ; **`@starterlib/util`** —
190
+ `PageParCurseur<T>`.
191
+
192
+ ```ts
193
+ readonly navigation = new NavigationParCurseur();
194
+ readonly page = httpResource<PageParCurseur<Expedition>>(() => ({
195
+ url: '/api/v1/expeditions',
196
+ params: this.navigation.parametres(),
197
+ }));
198
+ ```
199
+
200
+ ```html
201
+ <st-data-table
202
+ #tableau
203
+ legende="Expeditions"
204
+ cle="id"
205
+ [colonnes]="colonnes"
206
+ [lignes]="page.value()?.content ?? []"
207
+ [chargement]="page.isLoading()"
208
+ >
209
+ <ng-template stCellule="reference" [stCelluleDe]="page.value()?.content" let-ligne>
210
+ <a [routerLink]="['/expeditions', ligne.id]">{{ ligne.reference }}</a>
211
+ </ng-template>
212
+ </st-data-table>
213
+ <st-pagination
214
+ [cible]="tableau"
215
+ [numero]="navigation.numeroDePage()"
216
+ [precedenteDisponible]="navigation.precedenteDisponible()"
217
+ [suivanteDisponible]="page.value()?.hasMore ?? false"
218
+ [chargement]="page.isLoading()"
219
+ (precedente)="navigation.precedente()"
220
+ (suivante)="navigation.suivante(page.value())"
221
+ />
222
+ ```
223
+
224
+ Inventaire et regles de la suite : `docs/plan-librairie.md` et les audits de
225
+ vague (`docs/audit-vague-2-…`, `-3-…`, `-4-2026-09-17.md`) du depot.
153
226
 
154
227
  ## Regles tenues par les composants
155
228
 
@@ -6,6 +6,7 @@
6
6
  color, jamais par un attribut de gabarit. -->
7
7
  <svg xmlns="http://www.w3.org/2000/svg" style="display:none">
8
8
  <symbol id="boite-vide" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16z"/><polyline points="3.27 6.96 12 12.01 20.73 6.96"/><line x1="12" y1="22.08" x2="12" y2="12"/></symbol>
9
+ <symbol id="calendrier" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="4" width="18" height="18" rx="2" ry="2"/><line x1="16" y1="2" x2="16" y2="6"/><line x1="8" y1="2" x2="8" y2="6"/><line x1="3" y1="10" x2="21" y2="10"/></symbol>
9
10
  <symbol id="cercle" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/></symbol>
10
11
  <symbol id="cercle-coche" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M22 11.08V12a10 10 0 1 1-5.93-9.14"/><polyline points="22 4 12 14.01 9 11.01"/></symbol>
11
12
  <symbol id="cercle-croix" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><line x1="15" y1="9" x2="9" y2="15"/><line x1="9" y1="9" x2="15" y2="15"/></symbol>
@@ -18,6 +19,7 @@
18
19
  <symbol id="copie" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="9" y="9" width="13" height="13" rx="2" ry="2"/><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"/></symbol>
19
20
  <symbol id="corbeille" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="3 6 5 6 21 6"/><path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"/></symbol>
20
21
  <symbol id="croix" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></symbol>
22
+ <symbol id="fichier" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M13 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V9z"/><polyline points="13 2 13 9 20 9"/></symbol>
21
23
  <symbol id="hors-ligne" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="1" y1="1" x2="23" y2="23"/><path d="M16.72 11.06A10.94 10.94 0 0 1 19 12.55"/><path d="M5 12.55a10.94 10.94 0 0 1 5.17-2.39"/><path d="M10.71 5.05A16 16 0 0 1 22.58 9"/><path d="M1.42 9a15.91 15.91 0 0 1 4.7-2.88"/><path d="M8.53 16.11a6 6 0 0 1 6.95 0"/><line x1="12" y1="20" x2="12.01" y2="20"/></symbol>
22
24
  <symbol id="lien-externe" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"/><polyline points="15 3 21 3 21 9"/><line x1="10" y1="14" x2="21" y2="3"/></symbol>
23
25
  <symbol id="menu" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="3" y1="6" x2="21" y2="6"/><line x1="3" y1="12" x2="21" y2="12"/><line x1="3" y1="18" x2="21" y2="18"/></symbol>
@@ -27,6 +29,8 @@
27
29
  <symbol id="rafraichir" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="23 4 23 10 17 10"/><polyline points="1 20 1 14 7 14"/><path d="M3.51 9a9 9 0 0 1 14.85-3.36L23 10M1 14l4.64 4.36A9 9 0 0 0 20.49 15"/></symbol>
28
30
  <symbol id="recherche" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="11" cy="11" r="8"/><line x1="21" y1="21" x2="16.65" y2="16.65"/></symbol>
29
31
  <symbol id="serveur" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="2" y="2" width="20" height="8" rx="2"/><rect x="2" y="14" width="20" height="8" rx="2"/><line x1="6" y1="6" x2="6.01" y2="6"/><line x1="6" y1="18" x2="6.01" y2="18"/></symbol>
32
+ <symbol id="televerser" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><polyline points="17 8 12 3 7 8"/><line x1="12" y1="3" x2="12" y2="15"/></symbol>
33
+ <symbol id="tri" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="7 9 12 4 17 9"/><polyline points="7 15 12 20 17 15"/></symbol>
30
34
  <symbol id="triangle-alerte" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M10.29 3.86 1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z"/><line x1="12" y1="9" x2="12" y2="13"/><line x1="12" y1="17" x2="12.01" y2="17"/></symbol>
31
35
  <symbol id="utilisateur" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2"/><circle cx="12" cy="7" r="4"/></symbol>
32
36
  </svg>