@starterlib/ui 0.1.0 → 0.2.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
@@ -1,64 +1,124 @@
1
- # Ui
1
+ # @starterlib/ui
2
2
 
3
- This project was generated using [Angular CLI](https://github.com/angular/angular-cli) version 22.1.0.
3
+ Composants `st-*` du socle frontal starter. Zoneless, signal-first, `OnPush`,
4
+ autonomes. Ils consomment les jetons de `@starterlib/tokens`.
4
5
 
5
- ## Code scaffolding
6
-
7
- Angular CLI includes powerful code scaffolding tools. To generate a new component, run:
6
+ ## Installation
8
7
 
9
8
  ```bash
10
- ng generate component component-name
9
+ pnpm add @starterlib/ui @starterlib/tokens @starterlib/util
11
10
  ```
12
11
 
13
- For a complete list of available schematics (such as `components`, `directives`, or `pipes`), run:
12
+ Les versions d'Angular, de `@starterlib/tokens` et de `@starterlib/util` sont
13
+ des dependances de pair : c'est l'application qui les installe, et elles doivent
14
+ etre **identiques dans l'hote et dans chaque remote**. Deux versions du socle
15
+ dans le meme navigateur, ce sont deux jeux de jetons d'injection.
14
16
 
15
- ```bash
16
- ng generate --help
17
- ```
17
+ ## Deux points d'entree
18
18
 
19
- ## Building
19
+ Decoupes par **dependance**, jamais par famille : un composant sort du tronc
20
+ quand il traine un pair lourd, et seulement alors.
20
21
 
21
- To build the library, run:
22
+ | Point d'entree | Contenu | Ce qu'il traine |
23
+ | ------------------------- | ----------------------------------- | ------------------------------------------------- |
24
+ | `@starterlib/ui` | 22 composants | rien de lourd |
25
+ | `@starterlib/ui/surfaces` | ce qui se pose AU-DESSUS de la page | `@angular/cdk` overlay et portal, `@angular/aria` |
22
26
 
23
- ```bash
24
- ng build ui
27
+ ```ts
28
+ import { StButton, StIcon } from '@starterlib/ui';
29
+ import { StMenu, StMenuItem, StMenuTrigger } from '@starterlib/ui/surfaces';
30
+ ```
31
+
32
+ ⚠️ Un paquet partage en federation **ne s'elague pas** : declare singleton, il
33
+ est charge en entier des qu'un remote le reference. La separation n'a donc pas
34
+ pour but le poids — 16,8 Ko gzippes pour le tronc — mais le **train de
35
+ singletons** : une application qui n'affiche ni menu ni dialogue ne charge pas
36
+ le CDK, et n'a pas a se redeployer quand celui-ci monte de version.
37
+
38
+ `@angular/cdk` reste declare en pair du paquet, mais n'est importe que par
39
+ `ui/surfaces`. Voir `docs/adr/0003-points-d-entree-decoupes-par-dependance.md`.
40
+
41
+ ## Configuration — une fois, dans l'hote
42
+
43
+ ```ts
44
+ import { provideStarterUi, LIBELLES_FR } from '@starterlib/ui';
45
+
46
+ export const appConfig: ApplicationConfig = {
47
+ providers: [
48
+ provideStarterUi({
49
+ cheminDuSprite: '/ui/socle/assets/icones/sprite.svg',
50
+ locale, // Signal<string> : les formats suivent la langue a chaud
51
+ libelles, // Signal<LibellesUi> : LIBELLES_FR, LIBELLES_EN, ou le votre
52
+ fuseau: 'Europe/Paris',
53
+ }),
54
+ ],
55
+ };
25
56
  ```
26
57
 
27
- This command will compile your project, and the build artifacts will be placed in the `dist/` directory.
58
+ ⚠️ **Dans l'hote uniquement.** Un remote qui la rappellerait poserait un second
59
+ jeu de valeurs dans son injecteur de route : deux locales, deux dictionnaires,
60
+ et la moitie de l'ecran resterait dans l'ancienne langue apres une bascule.
28
61
 
29
- ### Publishing the Library
62
+ Sans configuration, les composants prennent `LOCALE_ID` et le francais. C'est un
63
+ depannage, pas une i18n : une application bilingue doit fournir des signaux,
64
+ sinon la bascule de langue ne touche pas les composants du socle.
30
65
 
31
- Once the project is built, you can publish your library by following these steps:
66
+ ## Sprite d'icones — a cabler avant le premier rendu
32
67
 
33
- 1. Navigate to the `dist` directory:
68
+ `st-icon` lit un sprite SVG servi **en meme origine**. Le paquet livre l'actif,
69
+ l'application le sert et en donne le chemin. Aucun chemin par defaut : une
70
+ reference `use` qui ne resout pas ne leve rien, et toutes les icones resteraient
71
+ vides en silence.
34
72
 
35
- ```bash
36
- cd dist/ui
37
- ```
73
+ `angular.json`, cible `build` :
38
74
 
39
- 2. Run the `npm publish` command to publish your library to the npm registry:
40
- ```bash
41
- npm publish
42
- ```
75
+ ```jsonc
76
+ "assets": [
77
+ {
78
+ "glob": "sprite.svg",
79
+ "input": "node_modules/@starterlib/ui/assets/icones",
80
+ "output": "assets/icones",
81
+ },
82
+ ]
83
+ ```
43
84
 
44
- ## Running unit tests
85
+ `app.config.ts` :
45
86
 
46
- To execute unit tests with the [Vitest](https://vitest.dev/) test runner, use the following command:
87
+ ```ts
88
+ import { fournirCheminDuSprite } from '@starterlib/ui';
47
89
 
48
- ```bash
49
- ng test
90
+ export const appConfig: ApplicationConfig = {
91
+ providers: [fournirCheminDuSprite('/ui/socle/assets/icones/sprite.svg')],
92
+ };
50
93
  ```
51
94
 
52
- ## Running end-to-end tests
95
+ Le prefixe est celui sous lequel l'interface est servie (`/ui/<interface>/`).
96
+ Un chemin empreinte (`sprite.<hash>.svg`) donne un cache immuable.
53
97
 
54
- For end-to-end (e2e) testing, run:
98
+ ## Feuille de jetons
55
99
 
56
- ```bash
57
- ng e2e
100
+ Les composants ne portent aucune couleur en dur : ils lisent les variables CSS
101
+ de `@starterlib/tokens`. Sans la feuille, tout s'affiche sans style.
102
+
103
+ ```css
104
+ @import '@starterlib/tokens/styles/starter-tokens.css';
58
105
  ```
59
106
 
60
- Angular CLI does not come with an end-to-end testing framework by default. You can choose one that suits your needs.
107
+ ## Ce qui est livre
108
+
109
+ Vague 1 : etats (`st-spinner`, `st-skeleton`, `st-empty`, `st-error`,
110
+ `st-offline-banner`, `st-progress`, `st-state`), texte (`st-text`,
111
+ `st-heading`), donnees (`st-money`, `st-date`, `st-relative-time`, `st-masked`,
112
+ `st-code`, `st-count`), actions (`st-button`, `st-icon-button`, `st-link`,
113
+ `st-button-group`), indicateurs (`st-badge`, `st-status-pill`, `st-tag`,
114
+ `st-avatar`), iconographie (`st-icon`).
115
+
116
+ Inventaire des vagues suivantes : `docs/plan-librairie.md` du depot.
61
117
 
62
- ## Additional Resources
118
+ ## Regles tenues par les composants
63
119
 
64
- For more information on using the Angular CLI, including detailed command references, visit the [Angular CLI Overview and Command Reference](https://angular.dev/tools/cli) page.
120
+ - Un statut se lit par une icone **et** un texte, jamais par la couleur seule.
121
+ - Aucun acces a `window` ni `document` hors `afterNextRender` : le rendu serveur
122
+ reste possible sans reecriture.
123
+ - Aucun style en ligne : la politique de securite du contenu a nonce l'interdit.
124
+ - Aucun stockage navigateur.
@@ -0,0 +1,32 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <!-- Sprite d'icones du socle frontal, tenu a la main. Ajouter un symbole, c'est
3
+ aussi ajouter son nom dans src/lib/icone/noms-d-icone.ts : trois tests de
4
+ st-icon.spec.ts gardent les deux listes identiques et verifient que chaque
5
+ symbole peint en currentColor. Le ton se pose donc par la propriete CSS
6
+ color, jamais par un attribut de gabarit. -->
7
+ <svg xmlns="http://www.w3.org/2000/svg" style="display:none">
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="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
+ <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
+ <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>
12
+ <symbol id="cercle-info" 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="12" y1="16" x2="12" y2="12"/><line x1="12" y1="8" x2="12.01" y2="8"/></symbol>
13
+ <symbol id="chevron-bas" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="6 9 12 15 18 9"/></symbol>
14
+ <symbol id="chevron-droite" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="9 18 15 12 9 6"/></symbol>
15
+ <symbol id="chevron-gauche" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="15 18 9 12 15 6"/></symbol>
16
+ <symbol id="chevron-haut" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="18 15 12 9 6 15"/></symbol>
17
+ <symbol id="coche" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="20 6 9 17 4 12"/></symbol>
18
+ <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
+ <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
+ <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>
21
+ <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
+ <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
+ <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>
24
+ <symbol id="oeil" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"/><circle cx="12" cy="12" r="3"/></symbol>
25
+ <symbol id="oeil-barre" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M17.94 17.94A10.07 10.07 0 0 1 12 20c-7 0-11-8-11-8a18.45 18.45 0 0 1 5.06-5.94M9.9 4.24A9.12 9.12 0 0 1 12 4c7 0 11 8 11 8a18.5 18.5 0 0 1-2.16 3.19m-6.72-1.07a3 3 0 1 1-4.24-4.24"/><line x1="1" y1="1" x2="23" y2="23"/></symbol>
26
+ <symbol id="plus" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="12" y1="5" x2="12" y2="19"/><line x1="5" y1="12" x2="19" y2="12"/></symbol>
27
+ <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
+ <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
+ <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>
30
+ <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
+ <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
+ </svg>
@@ -0,0 +1,244 @@
1
+ import { Overlay } from '@angular/cdk/overlay';
2
+ import { DomPortal } from '@angular/cdk/portal';
3
+ import * as i0 from '@angular/core';
4
+ import { inject, ElementRef, input, signal, DestroyRef, ChangeDetectionStrategy, Component, Directive } from '@angular/core';
5
+ import * as i1 from '@angular/aria/menu';
6
+ import { Menu, MenuItem } from '@angular/aria/menu';
7
+ import { StIcon } from '@starterlib/ui';
8
+
9
+ const POSITIONS = {
10
+ debut: [
11
+ { originX: 'start', originY: 'bottom', overlayX: 'start', overlayY: 'top', offsetY: 4 },
12
+ { originX: 'start', originY: 'top', overlayX: 'start', overlayY: 'bottom', offsetY: -4 },
13
+ ],
14
+ fin: [
15
+ { originX: 'end', originY: 'bottom', overlayX: 'end', overlayY: 'top', offsetY: 4 },
16
+ { originX: 'end', originY: 'top', overlayX: 'end', overlayY: 'bottom', offsetY: -4 },
17
+ ],
18
+ };
19
+ /**
20
+ * Menu d'actions. Le declencheur le designe, comme chez Material :
21
+ *
22
+ * ```html
23
+ * <button stMenuTrigger [menu]="compte" stButton>Actions</button>
24
+ *
25
+ * <st-menu #compte etiquette="Compte" (selection)="agir($event)">
26
+ * <button stMenuItem valeur="profil">Mon profil</button>
27
+ * <button stMenuItem valeur="quitter" ton="destructeur">Se deconnecter</button>
28
+ * </st-menu>
29
+ * ```
30
+ *
31
+ * ⚠️ Pourquoi le declencheur est DEHORS et les elements DEDANS. La primitive
32
+ * `Menu` d'`@angular/aria` relie ses elements au menu par injection, et un
33
+ * contenu projete garde l'injecteur de l'endroit ou il est ECRIT — jamais celui
34
+ * qui le rend. Les elements doivent donc etre ecrits a l'interieur de l'element
35
+ * qui porte le menu, sans quoi ils ne s'y enregistrent pas : le clavier ne
36
+ * bouge plus, et rien ne le signale. Le declencheur, lui, n'a rien a faire dans
37
+ * un `role="menu"`, qui ne contient que des elements de menu.
38
+ *
39
+ * Le clavier vient d'Aria, le placement du CDK. Le socle n'ecrit ni l'un ni
40
+ * l'autre : deux motifs longs, que l'on croit finis avant de les avoir
41
+ * eprouves au lecteur d'ecran ou au bord de l'ecran.
42
+ *
43
+ * ⚠️ A l'ouverture, l'element est DEPLACE dans la couche d'overlay
44
+ * (`DomPortal`), il n'est pas recree : ses liaisons, son etat et son injecteur
45
+ * survivent au passage, ce qu'un gabarit reconstruit perdrait.
46
+ */
47
+ class StMenu {
48
+ element = inject(ElementRef);
49
+ overlay = inject(Overlay);
50
+ aria = inject(Menu);
51
+ /** Nom du menu pour les technologies d'assistance. */
52
+ etiquette = input.required(/* @ts-ignore */
53
+ ...(ngDevMode ? [{ debugName: "etiquette" }] : /* istanbul ignore next */ []));
54
+ alignement = input('debut', /* @ts-ignore */
55
+ ...(ngDevMode ? [{ debugName: "alignement" }] : /* istanbul ignore next */ []));
56
+ ouvertInterne = signal(false, /* @ts-ignore */
57
+ ...(ngDevMode ? [{ debugName: "ouvertInterne" }] : /* istanbul ignore next */ []));
58
+ ouvert = this.ouvertInterne.asReadonly();
59
+ couche = null;
60
+ declencheur = null;
61
+ constructor() {
62
+ // La primitive detecte la selection ; elle ne connait rien de la couche
63
+ // d'overlay, donc c'est ici que le menu se referme.
64
+ this.aria.itemSelected.subscribe(() => {
65
+ this.fermer();
66
+ });
67
+ inject(DestroyRef).onDestroy(() => {
68
+ this.detruireLaCouche();
69
+ });
70
+ }
71
+ ouvrirDepuis(declencheur) {
72
+ if (this.ouvertInterne())
73
+ return;
74
+ this.declencheur = declencheur;
75
+ this.couche = this.overlay.create({
76
+ positionStrategy: this.overlay
77
+ .position()
78
+ .flexibleConnectedTo(declencheur)
79
+ .withPositions(POSITIONS[this.alignement()])
80
+ .withPush(true),
81
+ // Le menu suit son declencheur au defilement : le figer le laisserait
82
+ // seul au milieu de l'ecran, sans lien visible avec ce qu'il commande.
83
+ scrollStrategy: this.overlay.scrollStrategies.reposition(),
84
+ });
85
+ this.couche.attach(new DomPortal(this.element));
86
+ this.ouvertInterne.set(true);
87
+ this.couche.outsidePointerEvents().subscribe(() => {
88
+ this.fermer({ rendreLeFocus: false });
89
+ });
90
+ // Le panneau prend le focus : la primitive y tient l'indice de tabulation
91
+ // glissant, donc c'est elle qui decide de l'element actif.
92
+ this.element.nativeElement.focus();
93
+ }
94
+ /**
95
+ * Ferme, et rend le focus au declencheur : sans cela, le focus retombe sur le
96
+ * corps du document, et la navigation clavier reprend en haut de page.
97
+ */
98
+ fermer(options = {}) {
99
+ if (!this.ouvertInterne())
100
+ return;
101
+ this.ouvertInterne.set(false);
102
+ this.detruireLaCouche();
103
+ const declencheur = this.declencheur;
104
+ this.declencheur = null;
105
+ if (options.rendreLeFocus !== false)
106
+ declencheur?.focus();
107
+ }
108
+ basculerDepuis(declencheur) {
109
+ if (this.ouvertInterne())
110
+ this.fermer();
111
+ else
112
+ this.ouvrirDepuis(declencheur);
113
+ }
114
+ auClavier(evenement) {
115
+ if (evenement.key !== 'Escape')
116
+ return;
117
+ evenement.preventDefault();
118
+ this.fermer();
119
+ }
120
+ detruireLaCouche() {
121
+ // `detach` avant `dispose` : le portail rend l'element a sa place d'origine,
122
+ // et le composant reste utilisable pour une reouverture.
123
+ this.couche?.detach();
124
+ this.couche?.dispose();
125
+ this.couche = null;
126
+ }
127
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: StMenu, deps: [], target: i0.ɵɵFactoryTarget.Component });
128
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.1.6", type: StMenu, isStandalone: true, selector: "st-menu", inputs: { etiquette: { classPropertyName: "etiquette", publicName: "etiquette", isSignal: true, isRequired: true, transformFunction: null }, alignement: { classPropertyName: "alignement", publicName: "alignement", isSignal: true, isRequired: false, transformFunction: null } }, host: { listeners: { "keydown": "auClavier($event)" }, properties: { "attr.aria-label": "etiquette()", "attr.data-ouvert": "ouvert() ? \"\" : null" }, classAttribute: "st-menu" }, hostDirectives: [{ directive: i1.Menu, inputs: ["wrap", "wrap", "typeaheadDelay", "typeaheadDelay", "disabled", "disabled"], outputs: ["itemSelected", "selection"] }], ngImport: i0, template: "<ng-content />\n", styles: [":host{display:none}:host([data-ouvert]){display:flex;flex-direction:column;gap:2px;min-inline-size:12rem;max-block-size:80vh;padding:var(--st-espacement-1);overflow-y:auto;background:var(--st-couleur-surface-elevee);border:1px solid var(--st-couleur-bordure);border-radius:var(--st-rayon-md);box-shadow:var(--st-ombre-2)}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
129
+ }
130
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: StMenu, decorators: [{
131
+ type: Component,
132
+ args: [{ selector: 'st-menu', changeDetection: ChangeDetectionStrategy.OnPush, hostDirectives: [
133
+ {
134
+ directive: Menu,
135
+ inputs: ['wrap', 'typeaheadDelay', 'disabled'],
136
+ outputs: ['itemSelected: selection'],
137
+ },
138
+ ], host: {
139
+ class: 'st-menu',
140
+ '[attr.aria-label]': 'etiquette()',
141
+ '[attr.data-ouvert]': 'ouvert() ? "" : null',
142
+ '(keydown)': 'auClavier($event)',
143
+ }, template: "<ng-content />\n", styles: [":host{display:none}:host([data-ouvert]){display:flex;flex-direction:column;gap:2px;min-inline-size:12rem;max-block-size:80vh;padding:var(--st-espacement-1);overflow-y:auto;background:var(--st-couleur-surface-elevee);border:1px solid var(--st-couleur-bordure);border-radius:var(--st-rayon-md);box-shadow:var(--st-ombre-2)}\n"] }]
144
+ }], ctorParameters: () => [], propDecorators: { etiquette: [{ type: i0.Input, args: [{ isSignal: true, alias: "etiquette", required: true }] }], alignement: [{ type: i0.Input, args: [{ isSignal: true, alias: "alignement", required: false }] }] } });
145
+
146
+ /**
147
+ * Element de menu, pose en ATTRIBUT sur un `<button>` natif — meme raison que
148
+ * `st-button` : une enveloppe casserait le comportement natif du bouton.
149
+ *
150
+ * Le clavier (fleches, Debut, Fin, saisie au vol, indice de tabulation
151
+ * glissant) vient de la primitive `MenuItem` d'`@angular/aria`, composee en
152
+ * directive d'hote. Le socle n'en reecrit aucune part : ces motifs sont longs a
153
+ * ecrire, faciles a croire finis, et c'est la ou l'accessibilite se perd.
154
+ *
155
+ * ⚠️ `valeur` est OBLIGATOIRE parce que la primitive l'exige, et c'est un bon
156
+ * defaut : c'est elle que `st-menu` emet a la selection. Un menu dont les
157
+ * elements n'ont pas d'identite stable oblige l'appelant a distinguer ses
158
+ * actions par leur libelle, donc par leur traduction.
159
+ */
160
+ class StMenuItem {
161
+ icone = input(null, /* @ts-ignore */
162
+ ...(ngDevMode ? [{ debugName: "icone" }] : /* istanbul ignore next */ []));
163
+ ton = input('neutre', /* @ts-ignore */
164
+ ...(ngDevMode ? [{ debugName: "ton" }] : /* istanbul ignore next */ []));
165
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: StMenuItem, deps: [], target: i0.ɵɵFactoryTarget.Component });
166
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: StMenuItem, isStandalone: true, selector: "button[stMenuItem]", inputs: { icone: { classPropertyName: "icone", publicName: "icone", isSignal: true, isRequired: false, transformFunction: null }, ton: { classPropertyName: "ton", publicName: "ton", isSignal: true, isRequired: false, transformFunction: null } }, host: { attributes: { "type": "button" }, properties: { "attr.data-ton": "ton()" }, classAttribute: "st-menu-item" }, hostDirectives: [{ directive: i1.MenuItem, inputs: ["value", "valeur", "disabled", "desactive", "role", "role"] }], ngImport: i0, template: "@if (icone(); as nom) {\n <st-icon [nom]=\"nom\" taille=\"sm\" />\n}\n\n<span class=\"st-menu-item__libelle\"><ng-content /></span>\n", styles: [".st-vh{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap;border:0}:host{display:flex;gap:var(--st-espacement-2);align-items:center;inline-size:100%;min-block-size:2.25rem;padding-block:var(--st-espacement-2);padding-inline:var(--st-espacement-3);font-family:var(--st-police-base);font-size:var(--st-taille-sm);color:var(--st-couleur-texte);text-align:start;cursor:pointer;background:transparent;border:0;border-radius:var(--st-rayon-sm)}:host:focus-visible{outline:2px solid var(--st-couleur-anneau-focus);outline-offset:-2px}:host:hover:not([aria-disabled=true]){background:var(--st-couleur-surface-survol)}:host[data-active=true]{background:var(--st-couleur-surface-survol)}:host[aria-disabled=true]{color:var(--st-couleur-texte-desactive);cursor:not-allowed}@media(any-pointer:coarse){:host{min-block-size:var(--st-cible-tactile-min)}}:host([data-ton=danger]){color:var(--st-couleur-danger)}:host([data-ton=danger]):hover:not([aria-disabled=true]),:host([data-ton=danger])[data-active=true]{background:var(--st-couleur-danger-discret)}.st-menu-item__libelle{flex:1}\n"], dependencies: [{ kind: "component", type: StIcon, selector: "st-icon", inputs: ["nom", "taille", "ton", "etiquette"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
167
+ }
168
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: StMenuItem, decorators: [{
169
+ type: Component,
170
+ args: [{ selector: 'button[stMenuItem]', changeDetection: ChangeDetectionStrategy.OnPush, imports: [StIcon], hostDirectives: [
171
+ { directive: MenuItem, inputs: ['value: valeur', 'disabled: desactive', 'role'] },
172
+ ], host: {
173
+ class: 'st-menu-item',
174
+ type: 'button',
175
+ '[attr.data-ton]': 'ton()',
176
+ }, template: "@if (icone(); as nom) {\n <st-icon [nom]=\"nom\" taille=\"sm\" />\n}\n\n<span class=\"st-menu-item__libelle\"><ng-content /></span>\n", styles: [".st-vh{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap;border:0}:host{display:flex;gap:var(--st-espacement-2);align-items:center;inline-size:100%;min-block-size:2.25rem;padding-block:var(--st-espacement-2);padding-inline:var(--st-espacement-3);font-family:var(--st-police-base);font-size:var(--st-taille-sm);color:var(--st-couleur-texte);text-align:start;cursor:pointer;background:transparent;border:0;border-radius:var(--st-rayon-sm)}:host:focus-visible{outline:2px solid var(--st-couleur-anneau-focus);outline-offset:-2px}:host:hover:not([aria-disabled=true]){background:var(--st-couleur-surface-survol)}:host[data-active=true]{background:var(--st-couleur-surface-survol)}:host[aria-disabled=true]{color:var(--st-couleur-texte-desactive);cursor:not-allowed}@media(any-pointer:coarse){:host{min-block-size:var(--st-cible-tactile-min)}}:host([data-ton=danger]){color:var(--st-couleur-danger)}:host([data-ton=danger]):hover:not([aria-disabled=true]),:host([data-ton=danger])[data-active=true]{background:var(--st-couleur-danger-discret)}.st-menu-item__libelle{flex:1}\n"] }]
177
+ }], propDecorators: { icone: [{ type: i0.Input, args: [{ isSignal: true, alias: "icone", required: false }] }], ton: [{ type: i0.Input, args: [{ isSignal: true, alias: "ton", required: false }] }] } });
178
+
179
+ /**
180
+ * Controle qui ouvre un menu. Il le DESIGNE, il ne le contient pas :
181
+ *
182
+ * ```html
183
+ * <button stMenuTrigger [menu]="compte" stButton>Actions</button>
184
+ * <st-menu #compte etiquette="Compte">…</st-menu>
185
+ * ```
186
+ *
187
+ * ⚠️ Le type de `menu` est importe en TYPE seulement : `st-menu` n'a pas besoin
188
+ * de cette directive, et l'importer dans les deux sens formerait un cycle.
189
+ */
190
+ class StMenuTrigger {
191
+ element = inject(ElementRef).nativeElement;
192
+ menu = input.required(/* @ts-ignore */
193
+ ...(ngDevMode ? [{ debugName: "menu" }] : /* istanbul ignore next */ []));
194
+ basculer() {
195
+ this.menu().basculerDepuis(this.element);
196
+ }
197
+ auClavier(evenement) {
198
+ // La fleche bas ouvre sans activer : convention des menus, et elle evite
199
+ // d'ouvrir a chaque frappe sur un controle qui porte deja une action.
200
+ if (evenement.key !== 'ArrowDown' || this.menu().ouvert())
201
+ return;
202
+ evenement.preventDefault();
203
+ this.menu().ouvrirDepuis(this.element);
204
+ }
205
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: StMenuTrigger, deps: [], target: i0.ɵɵFactoryTarget.Directive });
206
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.1.6", type: StMenuTrigger, isStandalone: true, selector: "[stMenuTrigger]", inputs: { menu: { classPropertyName: "menu", publicName: "menu", isSignal: true, isRequired: true, transformFunction: null } }, host: { attributes: { "aria-haspopup": "menu" }, listeners: { "click": "basculer()", "keydown": "auClavier($event)" }, properties: { "attr.aria-expanded": "menu().ouvert()", "attr.data-ouvert": "menu().ouvert() ? \"\" : null" } }, ngImport: i0 });
207
+ }
208
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: StMenuTrigger, decorators: [{
209
+ type: Directive,
210
+ args: [{
211
+ selector: '[stMenuTrigger]',
212
+ host: {
213
+ 'aria-haspopup': 'menu',
214
+ '[attr.aria-expanded]': 'menu().ouvert()',
215
+ '[attr.data-ouvert]': 'menu().ouvert() ? "" : null',
216
+ '(click)': 'basculer()',
217
+ '(keydown)': 'auClavier($event)',
218
+ },
219
+ }]
220
+ }], propDecorators: { menu: [{ type: i0.Input, args: [{ isSignal: true, alias: "menu", required: true }] }] } });
221
+
222
+ /**
223
+ * @starterlib/ui/surfaces — ce qui se pose AU-DESSUS de la page.
224
+ *
225
+ * ⚠️ Un point d'entree separe pour une raison de dependance, et non de rangement :
226
+ * tout ce qui vit ici traine `@angular/cdk/overlay` et `@angular/cdk/portal`.
227
+ * Laisse dans le tronc, le CDK entrerait dans le train de singletons de CHAQUE
228
+ * application federee, y compris celles qui n'affichent ni menu ni dialogue.
229
+ *
230
+ * Le decoupage suit donc les pairs lourds, pas les familles de composants : un
231
+ * decoupage par famille multiplierait les points d'entree a tenir sans rien
232
+ * retirer de plus au chargement.
233
+ *
234
+ * ```ts
235
+ * import { StMenu, StMenuItem, StMenuTrigger } from '@starterlib/ui/surfaces';
236
+ * ```
237
+ */
238
+
239
+ /**
240
+ * Generated bundle index. Do not edit.
241
+ */
242
+
243
+ export { StMenu, StMenuItem, StMenuTrigger };
244
+ //# sourceMappingURL=starterlib-ui-surfaces.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"starterlib-ui-surfaces.mjs","sources":["../../../../packages/ui/surfaces/src/lib/menu/st-menu.ts","../../../../packages/ui/surfaces/src/lib/menu/st-menu.html","../../../../packages/ui/surfaces/src/lib/menu/st-menu-item.ts","../../../../packages/ui/surfaces/src/lib/menu/st-menu-item.html","../../../../packages/ui/surfaces/src/lib/menu/st-menu-trigger.ts","../../../../packages/ui/surfaces/src/public-api.ts","../../../../packages/ui/surfaces/src/starterlib-ui-surfaces.ts"],"names":[],"mappings":"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"}