@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.
- package/README.md +95 -42
- package/fesm2022/starterlib-ui-arbre.mjs +82 -0
- package/fesm2022/starterlib-ui-arbre.mjs.map +1 -0
- package/fesm2022/starterlib-ui-donnees.mjs +532 -0
- package/fesm2022/starterlib-ui-donnees.mjs.map +1 -0
- package/fesm2022/starterlib-ui-formulaires.mjs +2 -1
- package/fesm2022/starterlib-ui-formulaires.mjs.map +1 -1
- package/fesm2022/starterlib-ui-interactions.mjs +34 -589
- package/fesm2022/starterlib-ui-interactions.mjs.map +1 -1
- package/fesm2022/starterlib-ui-libelles-en.mjs +142 -0
- package/fesm2022/starterlib-ui-libelles-en.mjs.map +1 -0
- package/fesm2022/starterlib-ui-listes.mjs +671 -0
- package/fesm2022/starterlib-ui-listes.mjs.map +1 -0
- package/fesm2022/starterlib-ui-navigation.mjs +246 -0
- package/fesm2022/starterlib-ui-navigation.mjs.map +1 -0
- package/fesm2022/starterlib-ui-onglets.mjs +137 -0
- package/fesm2022/starterlib-ui-onglets.mjs.map +1 -0
- package/fesm2022/starterlib-ui-saisie.mjs +1632 -0
- package/fesm2022/starterlib-ui-saisie.mjs.map +1 -0
- package/fesm2022/starterlib-ui-selection.mjs +269 -0
- package/fesm2022/starterlib-ui-selection.mjs.map +1 -0
- package/fesm2022/starterlib-ui.mjs +105 -2931
- package/fesm2022/starterlib-ui.mjs.map +1 -1
- package/package.json +35 -3
- package/types/starterlib-ui-arbre.d.ts +51 -0
- package/types/starterlib-ui-donnees.d.ts +228 -0
- package/types/starterlib-ui-formulaires.d.ts +5 -4
- package/types/starterlib-ui-interactions.d.ts +4 -316
- package/types/starterlib-ui-libelles-en.d.ts +25 -0
- package/types/starterlib-ui-listes.d.ts +432 -0
- package/types/starterlib-ui-navigation.d.ts +104 -0
- package/types/starterlib-ui-onglets.d.ts +89 -0
- package/types/starterlib-ui-saisie.d.ts +924 -0
- package/types/starterlib-ui-selection.d.ts +112 -0
- package/types/starterlib-ui.d.ts +9 -1575
|
@@ -1,598 +1,43 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
* ⚠️ **La liste d'onglets est rendue par le composant, a partir de donnees**, et
|
|
30
|
-
* non projetee. Les primitives d'Aria relient un onglet a sa liste par
|
|
31
|
-
* INJECTION, et un contenu projete garde l'injecteur de l'endroit ou il est
|
|
32
|
-
* ecrit : c'est la lecon de `st-menu`, ou des elements projetes ne
|
|
33
|
-
* s'enregistraient jamais. Rendue ici, la liste est a coup sur sous la bonne
|
|
34
|
-
* primitive — et ses valeurs peuvent etre dites en francais.
|
|
35
|
-
*
|
|
36
|
-
* Les PANNEAUX, eux, sont projetes : ecrits directement sous `st-tabs`, leur
|
|
37
|
-
* injecteur parent est celui de l'hote, qui porte la primitive `Tabs`.
|
|
38
|
-
*
|
|
39
|
-
* ⚠️ **Activation manuelle par defaut.** En activation automatique, chaque
|
|
40
|
-
* fleche SELECTIONNE l'onglet atteint ; son contenu differe se rend, et charge
|
|
41
|
-
* ses donnees. Parcourir cinq onglets au clavier lancerait cinq requetes pour en
|
|
42
|
-
* lire un. En manuelle, les fleches deplacent le focus et Entree ou Espace
|
|
43
|
-
* selectionne. `automatique` reste le bon choix quand les panneaux sont deja la
|
|
44
|
-
* et s'affichent sans delai.
|
|
45
|
-
*/
|
|
46
|
-
class StTabs {
|
|
47
|
-
onglets = input.required(/* @ts-ignore */
|
|
48
|
-
...(ngDevMode ? [{ debugName: "onglets" }] : /* istanbul ignore next */ []));
|
|
49
|
-
/** Nom accessible de la liste : sans lui, plusieurs listes d'onglets se confondent. */
|
|
50
|
-
etiquette = input.required(/* @ts-ignore */
|
|
51
|
-
...(ngDevMode ? [{ debugName: "etiquette" }] : /* istanbul ignore next */ []));
|
|
52
|
-
activation = input('manuelle', /* @ts-ignore */
|
|
53
|
-
...(ngDevMode ? [{ debugName: "activation" }] : /* istanbul ignore next */ []));
|
|
54
|
-
orientation = input('horizontale', /* @ts-ignore */
|
|
55
|
-
...(ngDevMode ? [{ debugName: "orientation" }] : /* istanbul ignore next */ []));
|
|
56
|
-
/** Valeur de l'onglet selectionne. `undefined` : le premier onglet disponible. */
|
|
57
|
-
selection = model(undefined, /* @ts-ignore */
|
|
58
|
-
...(ngDevMode ? [{ debugName: "selection" }] : /* istanbul ignore next */ []));
|
|
59
|
-
/**
|
|
60
|
-
* ⚠️ Toujours un onglet selectionne. Le motif ARIA l'exige : une liste sans
|
|
61
|
-
* selection n'affiche aucun panneau, et la page parait vide sans raison.
|
|
62
|
-
*/
|
|
63
|
-
selectionEffective = computed(() => this.selection() ?? this.onglets().find((onglet) => onglet.desactive !== true)?.valeur, /* @ts-ignore */
|
|
64
|
-
...(ngDevMode ? [{ debugName: "selectionEffective" }] : /* istanbul ignore next */ []));
|
|
65
|
-
modeAria = computed(() => this.activation() === 'automatique' ? 'follow' : 'explicit', /* @ts-ignore */
|
|
66
|
-
...(ngDevMode ? [{ debugName: "modeAria" }] : /* istanbul ignore next */ []));
|
|
67
|
-
orientationAria = computed(() => this.orientation() === 'verticale' ? 'vertical' : 'horizontal', /* @ts-ignore */
|
|
68
|
-
...(ngDevMode ? [{ debugName: "orientationAria" }] : /* istanbul ignore next */ []));
|
|
69
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: StTabs, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
70
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: StTabs, isStandalone: true, selector: "st-tabs", inputs: { onglets: { classPropertyName: "onglets", publicName: "onglets", isSignal: true, isRequired: true, transformFunction: null }, etiquette: { classPropertyName: "etiquette", publicName: "etiquette", isSignal: true, isRequired: true, transformFunction: null }, activation: { classPropertyName: "activation", publicName: "activation", isSignal: true, isRequired: false, transformFunction: null }, orientation: { classPropertyName: "orientation", publicName: "orientation", isSignal: true, isRequired: false, transformFunction: null }, selection: { classPropertyName: "selection", publicName: "selection", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { selection: "selectionChange" }, host: { properties: { "attr.data-orientation": "orientation()" }, classAttribute: "st-tabs" }, hostDirectives: [{ directive: i1.Tabs }], ngImport: i0, template: "<div\n class=\"st-tabs__liste\"\n ngTabList\n [attr.aria-label]=\"etiquette()\"\n [selectionMode]=\"modeAria()\"\n [orientation]=\"orientationAria()\"\n [selectedTab]=\"selectionEffective()\"\n (selectedTabChange)=\"selection.set($event)\"\n>\n @for (onglet of onglets(); track onglet.valeur) {\n <button\n class=\"st-tabs__onglet\"\n type=\"button\"\n ngTab\n [value]=\"onglet.valeur\"\n [disabled]=\"onglet.desactive === true\"\n >\n {{ onglet.libelle }}\n </button>\n }\n</div>\n\n<div class=\"st-tabs__panneaux\">\n <ng-content />\n</div>\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([hidden]){display:none!important}:host{display:block}:host([data-orientation=verticale]){display:flex;gap:var(--st-espacement-4)}.st-tabs__liste{display:flex;gap:var(--st-espacement-1);border-block-end:1px solid var(--st-couleur-bordure)}:host([data-orientation=verticale]) .st-tabs__liste{flex-direction:column;border-block-end:0;border-inline-end:1px solid var(--st-couleur-bordure)}.st-tabs__panneaux{flex:1 1 auto;min-inline-size:0}.st-tabs__onglet:focus-visible{outline:2px solid var(--st-couleur-anneau-focus);outline-offset:2px}.st-tabs__onglet{min-block-size:var(--st-cible-tactile-min);padding:var(--st-espacement-2) var(--st-espacement-4);font:inherit;color:var(--st-couleur-texte-discret);cursor:pointer;background:none;border:0;border-block-end:3px solid transparent}@media(hover:hover){.st-tabs__onglet:hover{color:var(--st-couleur-texte)}}.st-tabs__onglet[aria-selected=true]{font-weight:var(--st-graisse-semi);color:var(--st-couleur-texte);border-block-end-color:var(--st-couleur-primaire)}.st-tabs__onglet[aria-disabled=true]{color:var(--st-couleur-texte-desactive);cursor:not-allowed}@media(forced-colors:active){.st-tabs__onglet[aria-selected=true]{border-block-end-color:Highlight}}\n"], dependencies: [{ kind: "directive", type: TabList, selector: "[ngTabList]", inputs: ["orientation", "wrap", "softDisabled", "focusMode", "selectionMode", "selectedTab", "disabled"], outputs: ["selectedTabChange"], exportAs: ["ngTabList"] }, { kind: "directive", type: Tab, selector: "[ngTab]", inputs: ["id", "disabled", "value"], exportAs: ["ngTab"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
71
|
-
}
|
|
72
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: StTabs, decorators: [{
|
|
73
|
-
type: Component,
|
|
74
|
-
args: [{ selector: 'st-tabs', changeDetection: ChangeDetectionStrategy.OnPush, imports: [TabList, Tab], hostDirectives: [Tabs], host: {
|
|
75
|
-
class: 'st-tabs',
|
|
76
|
-
'[attr.data-orientation]': 'orientation()',
|
|
77
|
-
}, template: "<div\n class=\"st-tabs__liste\"\n ngTabList\n [attr.aria-label]=\"etiquette()\"\n [selectionMode]=\"modeAria()\"\n [orientation]=\"orientationAria()\"\n [selectedTab]=\"selectionEffective()\"\n (selectedTabChange)=\"selection.set($event)\"\n>\n @for (onglet of onglets(); track onglet.valeur) {\n <button\n class=\"st-tabs__onglet\"\n type=\"button\"\n ngTab\n [value]=\"onglet.valeur\"\n [disabled]=\"onglet.desactive === true\"\n >\n {{ onglet.libelle }}\n </button>\n }\n</div>\n\n<div class=\"st-tabs__panneaux\">\n <ng-content />\n</div>\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([hidden]){display:none!important}:host{display:block}:host([data-orientation=verticale]){display:flex;gap:var(--st-espacement-4)}.st-tabs__liste{display:flex;gap:var(--st-espacement-1);border-block-end:1px solid var(--st-couleur-bordure)}:host([data-orientation=verticale]) .st-tabs__liste{flex-direction:column;border-block-end:0;border-inline-end:1px solid var(--st-couleur-bordure)}.st-tabs__panneaux{flex:1 1 auto;min-inline-size:0}.st-tabs__onglet:focus-visible{outline:2px solid var(--st-couleur-anneau-focus);outline-offset:2px}.st-tabs__onglet{min-block-size:var(--st-cible-tactile-min);padding:var(--st-espacement-2) var(--st-espacement-4);font:inherit;color:var(--st-couleur-texte-discret);cursor:pointer;background:none;border:0;border-block-end:3px solid transparent}@media(hover:hover){.st-tabs__onglet:hover{color:var(--st-couleur-texte)}}.st-tabs__onglet[aria-selected=true]{font-weight:var(--st-graisse-semi);color:var(--st-couleur-texte);border-block-end-color:var(--st-couleur-primaire)}.st-tabs__onglet[aria-disabled=true]{color:var(--st-couleur-texte-desactive);cursor:not-allowed}@media(forced-colors:active){.st-tabs__onglet[aria-selected=true]{border-block-end-color:Highlight}}\n"] }]
|
|
78
|
-
}], propDecorators: { onglets: [{ type: i0.Input, args: [{ isSignal: true, alias: "onglets", required: true }] }], etiquette: [{ type: i0.Input, args: [{ isSignal: true, alias: "etiquette", required: true }] }], activation: [{ type: i0.Input, args: [{ isSignal: true, alias: "activation", required: false }] }], orientation: [{ type: i0.Input, args: [{ isSignal: true, alias: "orientation", required: false }] }], selection: [{ type: i0.Input, args: [{ isSignal: true, alias: "selection", required: false }] }, { type: i0.Output, args: ["selectionChange"] }] } });
|
|
79
|
-
|
|
80
|
-
/**
|
|
81
|
-
* Panneau d'un onglet, relie par sa `valeur`.
|
|
82
|
-
*
|
|
83
|
-
* ⚠️ La primitive d'Aria ne masque RIEN : elle pose `inert` sur le panneau
|
|
84
|
-
* inactif, ce qui le retire de l'arbre d'accessibilite et du clavier, mais le
|
|
85
|
-
* laisse a l'ecran. Sa documentation le dit en une ligne. Sans le style de ce
|
|
86
|
-
* composant, tous les panneaux s'affichaient empiles, muets et intouchables.
|
|
87
|
-
*/
|
|
88
|
-
/* eslint-disable-next-line @typescript-eslint/no-extraneous-class --
|
|
89
|
-
Vide par construction : tout le comportement vient de la primitive d'Aria
|
|
90
|
-
composee en directive d'hote. La classe porte le selecteur et le style du
|
|
91
|
-
socle, rien d'autre ; y ajouter un membre pour satisfaire la regle serait
|
|
92
|
-
inventer de l'API. */
|
|
93
|
-
class StTabPanel {
|
|
94
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: StTabPanel, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
95
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.1.6", type: StTabPanel, isStandalone: true, selector: "st-tab-panel", host: { classAttribute: "st-tab-panel" }, hostDirectives: [{ directive: i1.TabPanel, inputs: ["value", "valeur"] }], ngImport: i0, template: "<ng-content />\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([hidden]){display:none!important}:host:focus-visible{outline:2px solid var(--st-couleur-anneau-focus);outline-offset:2px}:host{display:block;padding-block:var(--st-espacement-4)}:host([inert]){display:none}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
96
|
-
}
|
|
97
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: StTabPanel, decorators: [{
|
|
98
|
-
type: Component,
|
|
99
|
-
args: [{ selector: 'st-tab-panel', changeDetection: ChangeDetectionStrategy.OnPush, hostDirectives: [{ directive: TabPanel, inputs: ['value: valeur'] }], host: { class: 'st-tab-panel' }, template: "<ng-content />\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([hidden]){display:none!important}:host:focus-visible{outline:2px solid var(--st-couleur-anneau-focus);outline-offset:2px}:host{display:block;padding-block:var(--st-espacement-4)}:host([inert]){display:none}\n"] }]
|
|
100
|
-
}] });
|
|
101
|
-
|
|
102
|
-
/**
|
|
103
|
-
* Contenu differe d'un panneau : rendu a la premiere selection de son onglet.
|
|
104
|
-
*
|
|
105
|
-
* Un ecran a cinq onglets ne charge ainsi que celui qu'on regarde. Voir
|
|
106
|
-
* l'activation manuelle de `st-tabs` : c'est ce qui empeche qu'un simple
|
|
107
|
-
* parcours au clavier les rende tous.
|
|
108
|
-
*/
|
|
109
|
-
/* eslint-disable-next-line @typescript-eslint/no-extraneous-class --
|
|
110
|
-
Vide par construction : tout le comportement vient de la primitive d'Aria
|
|
111
|
-
composee en directive d'hote. La classe porte le selecteur et le style du
|
|
112
|
-
socle, rien d'autre ; y ajouter un membre pour satisfaire la regle serait
|
|
113
|
-
inventer de l'API. */
|
|
114
|
-
class StTabContent {
|
|
115
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: StTabContent, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
116
|
-
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.1.6", type: StTabContent, isStandalone: true, selector: "ng-template[stTabContent]", hostDirectives: [{ directive: i1.TabContent }], ngImport: i0 });
|
|
117
|
-
}
|
|
118
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: StTabContent, decorators: [{
|
|
119
|
-
type: Directive,
|
|
120
|
-
args: [{
|
|
121
|
-
selector: 'ng-template[stTabContent]',
|
|
122
|
-
hostDirectives: [TabContent],
|
|
123
|
-
}]
|
|
124
|
-
}] });
|
|
125
|
-
|
|
126
|
-
/**
|
|
127
|
-
* Au-dela, la navigation tient a cote du contenu. Meme seuil que `st-app-shell`,
|
|
128
|
-
* lu dans les jetons : ecrit en dur ici, il avait deja diverge une fois de la
|
|
129
|
-
* feuille (F7 du plan de la coquille).
|
|
130
|
-
*/
|
|
131
|
-
const ECRAN_LARGE = RUPTURES.lg.requete;
|
|
132
|
-
let compteur = 0;
|
|
133
|
-
/**
|
|
134
|
-
* Navigation laterale : une region a cote du contenu sur grand ecran, un tiroir
|
|
135
|
-
* sur petit ecran.
|
|
136
|
-
*
|
|
137
|
-
* ```html
|
|
138
|
-
* <st-app-shell>
|
|
139
|
-
* <button entete stButton [stSidenavToggle]="navigation">Menu</button>
|
|
140
|
-
* <st-sidenav navigation #navigation etiquette="Navigation principale">
|
|
141
|
-
* <a routerLink="/comptes">Comptes</a>
|
|
142
|
-
* </st-sidenav>
|
|
143
|
-
* …
|
|
144
|
-
* </st-app-shell>
|
|
145
|
-
* ```
|
|
146
|
-
*
|
|
147
|
-
* ⚠️ **Deux modes, jamais confondus.** Persistante, c'est une REGION de la page :
|
|
148
|
-
* aucun piege, rien a ouvrir. Modale, c'est un TIROIR, donc un `StDialog` — role,
|
|
149
|
-
* piegeage du focus, Echap, retour du focus au bouton — et non une region
|
|
150
|
-
* glissee par-dessus la page avec un peu de CSS, qui laisserait le clavier
|
|
151
|
-
* parcourir la page cachee dessous.
|
|
152
|
-
*
|
|
153
|
-
* ⚠️ **Elle porte son propre `<nav>`, et un seul a la fois.** Sur petit ecran,
|
|
154
|
-
* la region en ligne DISPARAIT quand le tiroir prend le relais : laissee en
|
|
155
|
-
* place, elle resterait un repere de navigation vide, que le lecteur d'ecran
|
|
156
|
-
* proposerait sans rien y trouver.
|
|
157
|
-
*
|
|
158
|
-
* Un lien suivi dans le tiroir le ferme : `StDialog` se ferme a toute navigation
|
|
159
|
-
* du routeur.
|
|
160
|
-
*/
|
|
161
|
-
class StSidenav {
|
|
162
|
-
dialogues = inject(StDialog);
|
|
163
|
-
libelles = inject(ST_LIBELLES);
|
|
164
|
-
/**
|
|
165
|
-
* Nom du repere. `null` : « Navigation principale », du dictionnaire. A
|
|
166
|
-
* renseigner des qu'une page compte deux navigations, qui doivent se
|
|
167
|
-
* distinguer.
|
|
168
|
-
*/
|
|
169
|
-
etiquette = input(null, /* @ts-ignore */
|
|
170
|
-
...(ngDevMode ? [{ debugName: "etiquette" }] : /* istanbul ignore next */ []));
|
|
171
|
-
etiquetteLue = computed(() => this.etiquette() ?? this.libelles().navigationPrincipale, /* @ts-ignore */
|
|
172
|
-
...(ngDevMode ? [{ debugName: "etiquetteLue" }] : /* istanbul ignore next */ []));
|
|
173
|
-
/** `auto` : persistante sur grand ecran, tiroir en dessous. */
|
|
174
|
-
mode = input('auto', /* @ts-ignore */
|
|
175
|
-
...(ngDevMode ? [{ debugName: "mode" }] : /* istanbul ignore next */ []));
|
|
176
|
-
identifiant = `st-sidenav-${(compteur += 1).toString()}`;
|
|
177
|
-
ecranLarge = signal(false, /* @ts-ignore */
|
|
178
|
-
...(ngDevMode ? [{ debugName: "ecranLarge" }] : /* istanbul ignore next */ []));
|
|
179
|
-
/** Mode reellement applique. Lu par le bouton, qui ne s'affiche qu'en tiroir. */
|
|
180
|
-
modeEffectif = computed(() => {
|
|
181
|
-
const mode = this.mode();
|
|
182
|
-
if (mode !== 'auto')
|
|
183
|
-
return mode;
|
|
184
|
-
return this.ecranLarge() ? 'persistant' : 'modal';
|
|
185
|
-
}, /* @ts-ignore */
|
|
186
|
-
...(ngDevMode ? [{ debugName: "modeEffectif" }] : /* istanbul ignore next */ []));
|
|
187
|
-
ouvertInterne = signal(false, /* @ts-ignore */
|
|
188
|
-
...(ngDevMode ? [{ debugName: "ouvertInterne" }] : /* istanbul ignore next */ []));
|
|
189
|
-
ouvert = this.ouvertInterne.asReadonly();
|
|
190
|
-
// Nomme autrement que la variable `#contenu` du gabarit, qui la masquerait.
|
|
191
|
-
gabarit = viewChild.required('contenu', /* @ts-ignore */
|
|
192
|
-
...(ngDevMode ? [{ debugName: "gabarit" }] : /* istanbul ignore next */ []));
|
|
193
|
-
reference = null;
|
|
194
|
-
constructor() {
|
|
195
|
-
const abonnement = inject(BreakpointObserver)
|
|
196
|
-
.observe(ECRAN_LARGE)
|
|
197
|
-
.subscribe((etat) => {
|
|
198
|
-
this.ecranLarge.set(etat.matches);
|
|
199
|
-
});
|
|
200
|
-
// Un ecran qui s'elargit pendant que le tiroir est ouvert : la navigation
|
|
201
|
-
// redevient une region, et le tiroir n'a plus de raison d'etre.
|
|
202
|
-
effect(() => {
|
|
203
|
-
if (this.modeEffectif() === 'persistant')
|
|
204
|
-
this.fermer();
|
|
205
|
-
});
|
|
206
|
-
inject(DestroyRef).onDestroy(() => {
|
|
207
|
-
abonnement.unsubscribe();
|
|
208
|
-
this.fermer();
|
|
209
|
-
});
|
|
210
|
-
}
|
|
211
|
-
ouvrir() {
|
|
212
|
-
if (this.modeEffectif() !== 'modal' || this.reference !== null)
|
|
213
|
-
return;
|
|
214
|
-
const reference = this.dialogues.ouvrir(this.gabarit(), {
|
|
215
|
-
cote: 'debut',
|
|
216
|
-
etiquette: this.etiquetteLue(),
|
|
217
|
-
});
|
|
218
|
-
this.reference = reference;
|
|
219
|
-
this.ouvertInterne.set(true);
|
|
220
|
-
void reference.ferme.then(() => {
|
|
221
|
-
if (this.reference !== reference)
|
|
222
|
-
return;
|
|
223
|
-
this.reference = null;
|
|
224
|
-
this.ouvertInterne.set(false);
|
|
225
|
-
});
|
|
226
|
-
}
|
|
227
|
-
fermer() {
|
|
228
|
-
const reference = this.reference;
|
|
229
|
-
if (reference === null)
|
|
230
|
-
return;
|
|
231
|
-
this.reference = null;
|
|
232
|
-
this.ouvertInterne.set(false);
|
|
233
|
-
reference.fermer();
|
|
234
|
-
}
|
|
235
|
-
basculer() {
|
|
236
|
-
if (this.ouvertInterne())
|
|
237
|
-
this.fermer();
|
|
238
|
-
else
|
|
239
|
-
this.ouvrir();
|
|
240
|
-
}
|
|
241
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: StSidenav, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
242
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: StSidenav, isStandalone: true, selector: "st-sidenav", inputs: { etiquette: { classPropertyName: "etiquette", publicName: "etiquette", isSignal: true, isRequired: false, transformFunction: null }, mode: { classPropertyName: "mode", publicName: "mode", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "attr.data-mode": "modeEffectif()" }, classAttribute: "st-sidenav" }, viewQueries: [{ propertyName: "gabarit", first: true, predicate: ["contenu"], descendants: true, isSignal: true }], ngImport: i0, template: "<ng-template #contenu>\n <nav class=\"st-sidenav__navigation\" [attr.id]=\"identifiant\" [attr.aria-label]=\"etiquetteLue()\">\n <ng-content />\n </nav>\n</ng-template>\n\n@if (modeEffectif() === 'persistant') {\n <ng-container [ngTemplateOutlet]=\"contenu\" />\n}\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([hidden]){display:none!important}:host{display:block}:host([data-mode=modal]){display:none}.st-sidenav__navigation{display:flex;flex-direction:column;gap:var(--st-espacement-1);padding:var(--st-espacement-4)}\n"], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
243
|
-
}
|
|
244
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: StSidenav, decorators: [{
|
|
245
|
-
type: Component,
|
|
246
|
-
args: [{ selector: 'st-sidenav', changeDetection: ChangeDetectionStrategy.OnPush, imports: [NgTemplateOutlet], host: {
|
|
247
|
-
class: 'st-sidenav',
|
|
248
|
-
'[attr.data-mode]': 'modeEffectif()',
|
|
249
|
-
}, template: "<ng-template #contenu>\n <nav class=\"st-sidenav__navigation\" [attr.id]=\"identifiant\" [attr.aria-label]=\"etiquetteLue()\">\n <ng-content />\n </nav>\n</ng-template>\n\n@if (modeEffectif() === 'persistant') {\n <ng-container [ngTemplateOutlet]=\"contenu\" />\n}\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([hidden]){display:none!important}:host{display:block}:host([data-mode=modal]){display:none}.st-sidenav__navigation{display:flex;flex-direction:column;gap:var(--st-espacement-1);padding:var(--st-espacement-4)}\n"] }]
|
|
250
|
-
}], ctorParameters: () => [], propDecorators: { etiquette: [{ type: i0.Input, args: [{ isSignal: true, alias: "etiquette", required: false }] }], mode: [{ type: i0.Input, args: [{ isSignal: true, alias: "mode", required: false }] }], gabarit: [{ type: i0.ViewChild, args: ['contenu', { isSignal: true }] }] } });
|
|
251
|
-
|
|
252
|
-
/**
|
|
253
|
-
* Bouton qui ouvre la navigation en tiroir.
|
|
254
|
-
*
|
|
255
|
-
* ⚠️ **Masque quand la navigation est persistante.** Un bouton « Menu » qui ne
|
|
256
|
-
* fait rien, parce que la navigation est deja affichee a cote, est un arret de
|
|
257
|
-
* tabulation inutile et une promesse non tenue.
|
|
258
|
-
*
|
|
259
|
-
* ⚠️ `aria-expanded` suit l'ouverture du tiroir : sans lui, rien ne dit a qui
|
|
260
|
-
* n'en voit pas l'effet que le bouton a agi.
|
|
261
|
-
*/
|
|
262
|
-
class StSidenavToggle {
|
|
263
|
-
stSidenavToggle = input.required(/* @ts-ignore */
|
|
264
|
-
...(ngDevMode ? [{ debugName: "stSidenavToggle" }] : /* istanbul ignore next */ []));
|
|
265
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: StSidenavToggle, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
266
|
-
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.1.6", type: StSidenavToggle, isStandalone: true, selector: "[stSidenavToggle]", inputs: { stSidenavToggle: { classPropertyName: "stSidenavToggle", publicName: "stSidenavToggle", isSignal: true, isRequired: true, transformFunction: null } }, host: { attributes: { "aria-haspopup": "dialog" }, listeners: { "click": "stSidenavToggle().basculer()" }, properties: { "attr.aria-expanded": "stSidenavToggle().ouvert()", "attr.hidden": "stSidenavToggle().modeEffectif() === \"modal\" ? null : \"\"" } }, ngImport: i0 });
|
|
267
|
-
}
|
|
268
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: StSidenavToggle, decorators: [{
|
|
269
|
-
type: Directive,
|
|
270
|
-
args: [{
|
|
271
|
-
selector: '[stSidenavToggle]',
|
|
272
|
-
host: {
|
|
273
|
-
'aria-haspopup': 'dialog',
|
|
274
|
-
'[attr.aria-expanded]': 'stSidenavToggle().ouvert()',
|
|
275
|
-
'[attr.hidden]': 'stSidenavToggle().modeEffectif() === "modal" ? null : ""',
|
|
276
|
-
'(click)': 'stSidenavToggle().basculer()',
|
|
277
|
-
},
|
|
278
|
-
}]
|
|
279
|
-
}], propDecorators: { stSidenavToggle: [{ type: i0.Input, args: [{ isSignal: true, alias: "stSidenavToggle", required: true }] }] } });
|
|
280
|
-
|
|
281
|
-
/**
|
|
282
|
-
* Liste de choix a filtrer en tapant, sur `@angular/aria/combobox` et
|
|
283
|
-
* `@angular/aria/listbox`.
|
|
284
|
-
*
|
|
285
|
-
* ```html
|
|
286
|
-
* <st-combobox libelle="Beneficiaire" [options]="beneficiaires" [formField]="virement.beneficiaire" />
|
|
287
|
-
* <!-- liste servie par le serveur : -->
|
|
288
|
-
* <st-combobox libelle="Commune" filtrage="distant" [options]="communes()"
|
|
289
|
-
* (recherche)="terme.set($event)" [formField]="adresse.commune" />
|
|
290
|
-
* ```
|
|
291
|
-
*
|
|
292
|
-
* Le modele est la VALEUR de l'option choisie, `''` sans choix. Le texte tape ne
|
|
293
|
-
* part jamais dans le modele : « Pari » n'est pas une commune.
|
|
294
|
-
*
|
|
295
|
-
* ⚠️ **Pour une longue liste seulement.** Sous une vingtaine d'options,
|
|
296
|
-
* `st-select` — natif — est plus sur, et plus rapide sur mobile.
|
|
297
|
-
*
|
|
298
|
-
* - La liste s'ouvre a la frappe et a la fleche bas ; Entree choisit, Echap
|
|
299
|
-
* ferme. Le focus reste dans le champ (`aria-activedescendant`).
|
|
300
|
-
* - Le nombre de resultats s'annonce apres la frappe, une fois : le lecteur
|
|
301
|
-
* d'ecran ne voit pas la liste se reduire.
|
|
302
|
-
* - ⚠️ **Quitter le champ sans choisir rend le texte du choix precedent.** Un
|
|
303
|
-
* texte qui ne correspond a aucune option ne reste pas affiche comme s'il etait
|
|
304
|
-
* retenu ; un champ vide, lui, retire le choix.
|
|
305
|
-
* - La liste est posee dans la couche superieure du navigateur (`popover`) par le
|
|
306
|
-
* CDK : un dialogue ou un tableau defilant ne la rogne pas.
|
|
307
|
-
*
|
|
308
|
-
* ⚠️ En `distant`, `recherche` est emis a chaque frappe : a l'application de
|
|
309
|
-
* temporiser, et de ne pas mettre le terme dans l'adresse (SEC-6).
|
|
310
|
-
*/
|
|
311
|
-
class StCombobox extends ControleDeSaisie {
|
|
312
|
-
libelles = inject(ST_LIBELLES);
|
|
313
|
-
element = inject(ElementRef);
|
|
314
|
-
injecteur = inject(Injector);
|
|
315
|
-
options = input.required(/* @ts-ignore */
|
|
316
|
-
...(ngDevMode ? [{ debugName: "options" }] : /* istanbul ignore next */ []));
|
|
317
|
-
filtrage = input('local', /* @ts-ignore */
|
|
318
|
-
...(ngDevMode ? [{ debugName: "filtrage" }] : /* istanbul ignore next */ []));
|
|
319
|
-
/** Texte tape, a chaque frappe. Sert au filtrage `distant`. */
|
|
320
|
-
recherche = output();
|
|
321
|
-
annonce = new AnnonceLocale(inject(DestroyRef));
|
|
322
|
-
ouvert = signal(false, /* @ts-ignore */
|
|
323
|
-
...(ngDevMode ? [{ debugName: "ouvert" }] : /* istanbul ignore next */ []));
|
|
324
|
-
/** Texte du champ : le libelle du choix, tant que la personne ne tape pas. */
|
|
325
|
-
texte = linkedSignal(() => this.libelleDe(this.value()), /* @ts-ignore */
|
|
326
|
-
...(ngDevMode ? [{ debugName: "texte" }] : /* istanbul ignore next */ []));
|
|
327
|
-
/** Ce qui filtre : vide a l'ouverture par la fleche, pour montrer toute la liste. */
|
|
328
|
-
filtre = signal('', /* @ts-ignore */
|
|
329
|
-
...(ngDevMode ? [{ debugName: "filtre" }] : /* istanbul ignore next */ []));
|
|
330
|
-
/** Option active dans la liste ; le choix n'est retenu qu'a la validation. */
|
|
331
|
-
surlignee = linkedSignal(() => this.value() === '' ? [] : [this.value()], /* @ts-ignore */
|
|
332
|
-
...(ngDevMode ? [{ debugName: "surlignee" }] : /* istanbul ignore next */ []));
|
|
333
|
-
visibles = computed(() => this.filtrage() === 'local' ? filtrerOptions(this.options(), this.filtre()) : this.options(), /* @ts-ignore */
|
|
334
|
-
...(ngDevMode ? [{ debugName: "visibles" }] : /* istanbul ignore next */ []));
|
|
335
|
-
liste = viewChild(Listbox, /* @ts-ignore */
|
|
336
|
-
...(ngDevMode ? [{ debugName: "liste" }] : /* istanbul ignore next */ []));
|
|
337
|
-
constructor() {
|
|
338
|
-
super();
|
|
339
|
-
afterRenderEffect(() => {
|
|
340
|
-
if (this.ouvert())
|
|
341
|
-
this.liste()?.scrollActiveItemIntoView({ block: 'nearest' });
|
|
342
|
-
});
|
|
343
|
-
}
|
|
344
|
-
surSaisie(evenement) {
|
|
345
|
-
const saisie = this.texteSaisi(evenement);
|
|
346
|
-
this.filtre.set(saisie);
|
|
347
|
-
this.recherche.emit(saisie);
|
|
348
|
-
if (this.filtrage() === 'local') {
|
|
349
|
-
this.annonce.annoncer(this.libelles().nombreDeResultats(this.visibles().length));
|
|
350
|
-
}
|
|
351
|
-
}
|
|
352
|
-
basculer() {
|
|
353
|
-
if (this.disabled() || this.readonly())
|
|
354
|
-
return;
|
|
355
|
-
this.filtre.set('');
|
|
356
|
-
this.ouvert.update((ouvert) => !ouvert);
|
|
357
|
-
this.focus();
|
|
358
|
-
}
|
|
359
|
-
valider() {
|
|
360
|
-
const choisie = this.surlignee()[0];
|
|
361
|
-
if (choisie === undefined)
|
|
362
|
-
return;
|
|
363
|
-
this.value.set(choisie);
|
|
364
|
-
this.texte.set(this.libelleDe(choisie));
|
|
365
|
-
this.filtre.set('');
|
|
366
|
-
this.ouvert.set(false);
|
|
367
|
-
afterNextRender(() => {
|
|
368
|
-
this.focus();
|
|
369
|
-
}, { injector: this.injecteur });
|
|
370
|
-
}
|
|
371
|
-
aLaSortie(evenement) {
|
|
372
|
-
const suivant = evenement.relatedTarget;
|
|
373
|
-
if (suivant !== null && this.element.nativeElement.contains(suivant))
|
|
374
|
-
return;
|
|
375
|
-
if (this.texte().trim() === '')
|
|
376
|
-
this.value.set('');
|
|
377
|
-
this.texte.set(this.libelleDe(this.value()));
|
|
378
|
-
this.filtre.set('');
|
|
379
|
-
this.touch.emit();
|
|
380
|
-
}
|
|
381
|
-
libelleDe(valeur) {
|
|
382
|
-
if (valeur === '')
|
|
383
|
-
return '';
|
|
384
|
-
return this.options().find((option) => option.valeur === valeur)?.libelle ?? '';
|
|
385
|
-
}
|
|
386
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: StCombobox, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
387
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: StCombobox, isStandalone: true, selector: "st-combobox", inputs: { options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: true, transformFunction: null }, filtrage: { classPropertyName: "filtrage", publicName: "filtrage", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { recherche: "recherche" }, host: { listeners: { "focusout": "aLaSortie($event)" }, classAttribute: "st-combobox" }, viewQueries: [{ propertyName: "liste", first: true, predicate: Listbox, descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: "<st-form-field\n [libelle]=\"libelle()\"\n [aide]=\"aide()\"\n [erreurs]=\"errors()\"\n [afficherErreurs]=\"touched()\"\n [obligatoire]=\"required()\"\n>\n <div #cadre class=\"st-combobox__cadre\">\n <input\n #champ\n #combobox=\"ngCombobox\"\n class=\"st-combobox__champ\"\n stControleDeChamp\n ngCombobox\n type=\"text\"\n autocomplete=\"off\"\n spellcheck=\"false\"\n [(value)]=\"texte\"\n [(expanded)]=\"ouvert\"\n [attr.name]=\"name() || null\"\n [disabled]=\"disabled()\"\n [readonly]=\"readonly()\"\n (input)=\"surSaisie($event)\"\n />\n <!-- Voie de la souris vers la liste. Hors tabulation et masque au lecteur\n d'ecran : au clavier, la fleche bas ouvre la liste depuis le champ. -->\n <span\n class=\"st-combobox__ouvrir\"\n aria-hidden=\"true\"\n (mousedown)=\"$event.preventDefault()\"\n (click)=\"basculer()\"\n >\n <st-icon nom=\"chevron-bas\" taille=\"sm\" />\n </span>\n </div>\n\n <!-- \u26A0\uFE0F La primitive de popup ENVELOPPE la surcouche, et non l'inverse (exemple\n de la documentation d'Aria). Enfermee dans la surcouche, elle ne\n s'enregistre qu'a l'ouverture : liste fermee, le champ annonce\n aria-autocomplete=\"none\" et aucun aria-haspopup, et le lecteur d'ecran\n ignore qu'une liste existe. -->\n <ng-template ngComboboxPopup [combobox]=\"combobox\">\n <ng-template\n [cdkConnectedOverlay]=\"{ origin: cadre, usePopover: 'inline', matchWidth: true }\"\n [cdkConnectedOverlayOpen]=\"ouvert()\"\n >\n <div class=\"st-combobox__popup\">\n @if (visibles().length === 0) {\n <p class=\"st-combobox__vide\">{{ libelles().aucunResultat }}</p>\n }\n <div\n #liste=\"ngListbox\"\n class=\"st-combobox__liste\"\n ngListbox\n ngComboboxWidget\n focusMode=\"activedescendant\"\n [tabindex]=\"-1\"\n [attr.aria-label]=\"libelle()\"\n [activeDescendant]=\"liste.activeDescendant()\"\n [(value)]=\"surlignee\"\n (click)=\"valider()\"\n (keydown.enter)=\"valider()\"\n >\n @for (option of visibles(); track option.valeur) {\n <div\n class=\"st-combobox__option\"\n ngOption\n [value]=\"option.valeur\"\n [label]=\"option.libelle\"\n [disabled]=\"option.desactivee === true\"\n >\n <span>{{ option.libelle }}</span>\n <st-icon class=\"st-combobox__coche\" nom=\"coche\" taille=\"sm\" />\n </div>\n }\n </div>\n </div>\n </ng-template>\n </ng-template>\n</st-form-field>\n<span class=\"st-vh\" aria-live=\"polite\">{{ annonce.texte() }}</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([hidden]){display:none!important}:host{display:block}.st-combobox__cadre{position:relative}.st-combobox__champ:focus-visible{outline:2px solid var(--st-couleur-anneau-focus);outline-offset:2px}.st-combobox__champ{box-sizing:border-box;inline-size:100%;min-block-size:var(--st-commande-hauteur, var(--st-cible-tactile-min));padding:var(--st-espacement-2) var(--st-espacement-3);font:inherit;color:var(--st-couleur-texte);background:var(--st-couleur-surface);border:1px solid var(--st-couleur-bordure-forte);border-radius:var(--st-commande-rayon, var(--st-rayon-md))}.st-combobox__champ[aria-invalid=true]{border-color:var(--st-couleur-danger);box-shadow:inset 0 0 0 1px var(--st-couleur-danger)}.st-combobox__champ:disabled{color:var(--st-couleur-texte-desactive);cursor:not-allowed;background:var(--st-couleur-surface-enfoncee)}.st-combobox__champ:read-only:not(:disabled){background:var(--st-couleur-surface-enfoncee)}.st-combobox__champ{padding-inline-end:calc(var(--st-espacement-3) * 2 + 1rem)}.st-combobox__ouvrir{position:absolute;inset-block:0;inset-inline-end:0;display:flex;align-items:center;padding-inline:var(--st-espacement-3);color:var(--st-couleur-texte-discret);cursor:pointer}.st-combobox__popup{max-block-size:18rem;overflow-y:auto;color:var(--st-couleur-texte);background:var(--st-couleur-surface);border:1px solid var(--st-couleur-bordure-forte);border-radius:var(--st-rayon-sm);box-shadow:var(--st-ombre-md)}.st-combobox__vide{padding:var(--st-espacement-2) var(--st-espacement-3);margin:0;color:var(--st-couleur-texte-discret)}.st-combobox__option{display:flex;gap:var(--st-espacement-2);align-items:center;justify-content:space-between;min-block-size:var(--st-cible-tactile-min);padding:var(--st-espacement-2) var(--st-espacement-3);cursor:pointer}.st-combobox__option[data-active=true]{outline:2px solid var(--st-couleur-anneau-focus);outline-offset:-2px;background:var(--st-couleur-surface-enfoncee)}.st-combobox__option[aria-disabled=true]{color:var(--st-couleur-texte-desactive);cursor:not-allowed}.st-combobox__option[aria-selected=true]{font-weight:var(--st-graisse-semi)}.st-combobox__coche{visibility:hidden}[aria-selected=true]>.st-combobox__coche{visibility:visible}\n"], dependencies: [{ kind: "component", type: StFormField, selector: "st-form-field", inputs: ["libelle", "aide", "complement", "erreurs", "afficherErreurs", "obligatoire", "disposition", "libelleMasque"] }, { kind: "directive", type: StControleDeChamp, selector: "[stControleDeChamp]" }, { kind: "component", type: StIcon, selector: "st-icon", inputs: ["nom", "sprite", "nomMetier", "taille", "ton", "etiquette"] }, { kind: "directive", type: Combobox, selector: "[ngCombobox]", inputs: ["disabled", "readonly", "softDisabled", "alwaysExpanded", "tabindex", "expanded", "value", "inlineSuggestion"], outputs: ["expandedChange", "valueChange"], exportAs: ["ngCombobox"] }, { kind: "directive", type: ComboboxPopup, selector: "ng-template[ngComboboxPopup]", inputs: ["combobox", "popupType"], exportAs: ["ngComboboxPopup"] }, { kind: "directive", type: ComboboxWidget, selector: "[ngComboboxWidget]", inputs: ["activeDescendant"], exportAs: ["ngComboboxWidget"] }, { kind: "directive", type: Listbox, selector: "[ngListbox]", inputs: ["id", "orientation", "multi", "wrap", "softDisabled", "focusMode", "selectionMode", "typeaheadDelay", "disabled", "readonly", "tabindex", "value"], outputs: ["valueChange"], exportAs: ["ngListbox"] }, { kind: "directive", type: Option, selector: "[ngOption]", inputs: ["id", "value", "disabled", "label"], exportAs: ["ngOption"] }, { kind: "directive", type: CdkConnectedOverlay, selector: "[cdk-connected-overlay], [connected-overlay], [cdkConnectedOverlay]", inputs: ["cdkConnectedOverlayOrigin", "cdkConnectedOverlayPositions", "cdkConnectedOverlayPositionStrategy", "cdkConnectedOverlayOffsetX", "cdkConnectedOverlayOffsetY", "cdkConnectedOverlayWidth", "cdkConnectedOverlayHeight", "cdkConnectedOverlayMinWidth", "cdkConnectedOverlayMinHeight", "cdkConnectedOverlayBackdropClass", "cdkConnectedOverlayPanelClass", "cdkConnectedOverlayViewportMargin", "cdkConnectedOverlayScrollStrategy", "cdkConnectedOverlayOpen", "cdkConnectedOverlayDisableClose", "cdkConnectedOverlayTransformOriginOn", "cdkConnectedOverlayHasBackdrop", "cdkConnectedOverlayLockPosition", "cdkConnectedOverlayFlexibleDimensions", "cdkConnectedOverlayGrowAfterOpen", "cdkConnectedOverlayPush", "cdkConnectedOverlayDisposeOnNavigation", "cdkConnectedOverlayUsePopover", "cdkConnectedOverlayMatchWidth", "cdkConnectedOverlay"], outputs: ["backdropClick", "positionChange", "attach", "detach", "overlayKeydown", "overlayOutsideClick"], exportAs: ["cdkConnectedOverlay"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
388
|
-
}
|
|
389
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: StCombobox, decorators: [{
|
|
390
|
-
type: Component,
|
|
391
|
-
args: [{ selector: 'st-combobox', changeDetection: ChangeDetectionStrategy.OnPush, imports: [
|
|
392
|
-
StFormField,
|
|
393
|
-
StControleDeChamp,
|
|
394
|
-
StIcon,
|
|
395
|
-
Combobox,
|
|
396
|
-
ComboboxPopup,
|
|
397
|
-
ComboboxWidget,
|
|
398
|
-
Listbox,
|
|
399
|
-
Option,
|
|
400
|
-
CdkConnectedOverlay,
|
|
401
|
-
], host: {
|
|
402
|
-
class: 'st-combobox',
|
|
403
|
-
'(focusout)': 'aLaSortie($event)',
|
|
404
|
-
}, template: "<st-form-field\n [libelle]=\"libelle()\"\n [aide]=\"aide()\"\n [erreurs]=\"errors()\"\n [afficherErreurs]=\"touched()\"\n [obligatoire]=\"required()\"\n>\n <div #cadre class=\"st-combobox__cadre\">\n <input\n #champ\n #combobox=\"ngCombobox\"\n class=\"st-combobox__champ\"\n stControleDeChamp\n ngCombobox\n type=\"text\"\n autocomplete=\"off\"\n spellcheck=\"false\"\n [(value)]=\"texte\"\n [(expanded)]=\"ouvert\"\n [attr.name]=\"name() || null\"\n [disabled]=\"disabled()\"\n [readonly]=\"readonly()\"\n (input)=\"surSaisie($event)\"\n />\n <!-- Voie de la souris vers la liste. Hors tabulation et masque au lecteur\n d'ecran : au clavier, la fleche bas ouvre la liste depuis le champ. -->\n <span\n class=\"st-combobox__ouvrir\"\n aria-hidden=\"true\"\n (mousedown)=\"$event.preventDefault()\"\n (click)=\"basculer()\"\n >\n <st-icon nom=\"chevron-bas\" taille=\"sm\" />\n </span>\n </div>\n\n <!-- \u26A0\uFE0F La primitive de popup ENVELOPPE la surcouche, et non l'inverse (exemple\n de la documentation d'Aria). Enfermee dans la surcouche, elle ne\n s'enregistre qu'a l'ouverture : liste fermee, le champ annonce\n aria-autocomplete=\"none\" et aucun aria-haspopup, et le lecteur d'ecran\n ignore qu'une liste existe. -->\n <ng-template ngComboboxPopup [combobox]=\"combobox\">\n <ng-template\n [cdkConnectedOverlay]=\"{ origin: cadre, usePopover: 'inline', matchWidth: true }\"\n [cdkConnectedOverlayOpen]=\"ouvert()\"\n >\n <div class=\"st-combobox__popup\">\n @if (visibles().length === 0) {\n <p class=\"st-combobox__vide\">{{ libelles().aucunResultat }}</p>\n }\n <div\n #liste=\"ngListbox\"\n class=\"st-combobox__liste\"\n ngListbox\n ngComboboxWidget\n focusMode=\"activedescendant\"\n [tabindex]=\"-1\"\n [attr.aria-label]=\"libelle()\"\n [activeDescendant]=\"liste.activeDescendant()\"\n [(value)]=\"surlignee\"\n (click)=\"valider()\"\n (keydown.enter)=\"valider()\"\n >\n @for (option of visibles(); track option.valeur) {\n <div\n class=\"st-combobox__option\"\n ngOption\n [value]=\"option.valeur\"\n [label]=\"option.libelle\"\n [disabled]=\"option.desactivee === true\"\n >\n <span>{{ option.libelle }}</span>\n <st-icon class=\"st-combobox__coche\" nom=\"coche\" taille=\"sm\" />\n </div>\n }\n </div>\n </div>\n </ng-template>\n </ng-template>\n</st-form-field>\n<span class=\"st-vh\" aria-live=\"polite\">{{ annonce.texte() }}</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([hidden]){display:none!important}:host{display:block}.st-combobox__cadre{position:relative}.st-combobox__champ:focus-visible{outline:2px solid var(--st-couleur-anneau-focus);outline-offset:2px}.st-combobox__champ{box-sizing:border-box;inline-size:100%;min-block-size:var(--st-commande-hauteur, var(--st-cible-tactile-min));padding:var(--st-espacement-2) var(--st-espacement-3);font:inherit;color:var(--st-couleur-texte);background:var(--st-couleur-surface);border:1px solid var(--st-couleur-bordure-forte);border-radius:var(--st-commande-rayon, var(--st-rayon-md))}.st-combobox__champ[aria-invalid=true]{border-color:var(--st-couleur-danger);box-shadow:inset 0 0 0 1px var(--st-couleur-danger)}.st-combobox__champ:disabled{color:var(--st-couleur-texte-desactive);cursor:not-allowed;background:var(--st-couleur-surface-enfoncee)}.st-combobox__champ:read-only:not(:disabled){background:var(--st-couleur-surface-enfoncee)}.st-combobox__champ{padding-inline-end:calc(var(--st-espacement-3) * 2 + 1rem)}.st-combobox__ouvrir{position:absolute;inset-block:0;inset-inline-end:0;display:flex;align-items:center;padding-inline:var(--st-espacement-3);color:var(--st-couleur-texte-discret);cursor:pointer}.st-combobox__popup{max-block-size:18rem;overflow-y:auto;color:var(--st-couleur-texte);background:var(--st-couleur-surface);border:1px solid var(--st-couleur-bordure-forte);border-radius:var(--st-rayon-sm);box-shadow:var(--st-ombre-md)}.st-combobox__vide{padding:var(--st-espacement-2) var(--st-espacement-3);margin:0;color:var(--st-couleur-texte-discret)}.st-combobox__option{display:flex;gap:var(--st-espacement-2);align-items:center;justify-content:space-between;min-block-size:var(--st-cible-tactile-min);padding:var(--st-espacement-2) var(--st-espacement-3);cursor:pointer}.st-combobox__option[data-active=true]{outline:2px solid var(--st-couleur-anneau-focus);outline-offset:-2px;background:var(--st-couleur-surface-enfoncee)}.st-combobox__option[aria-disabled=true]{color:var(--st-couleur-texte-desactive);cursor:not-allowed}.st-combobox__option[aria-selected=true]{font-weight:var(--st-graisse-semi)}.st-combobox__coche{visibility:hidden}[aria-selected=true]>.st-combobox__coche{visibility:visible}\n"] }]
|
|
405
|
-
}], ctorParameters: () => [], propDecorators: { options: [{ type: i0.Input, args: [{ isSignal: true, alias: "options", required: true }] }], filtrage: [{ type: i0.Input, args: [{ isSignal: true, alias: "filtrage", required: false }] }], recherche: [{ type: i0.Output, args: ["recherche"] }], liste: [{ type: i0.ViewChild, args: [i0.forwardRef(() => Listbox), { isSignal: true }] }] } });
|
|
406
|
-
|
|
407
|
-
/**
|
|
408
|
-
* Choix de plusieurs valeurs dans une liste, sur `@angular/aria/combobox` et
|
|
409
|
-
* `@angular/aria/listbox`.
|
|
410
|
-
*
|
|
411
|
-
* ```html
|
|
412
|
-
* <st-multiselect libelle="Comptes a inclure" [options]="comptes" [formField]="releve.comptes" />
|
|
413
|
-
* ```
|
|
414
|
-
*
|
|
415
|
-
* Le modele est la liste des VALEURS choisies, dans l'ordre des options.
|
|
416
|
-
*
|
|
417
|
-
* - Fleche bas, Entree ou Espace ouvrent la liste ; Espace coche ou decoche
|
|
418
|
-
* l'option active sans fermer ; Echap ferme.
|
|
419
|
-
* - ⚠️ **Chaque choix reste visible et retirable** sous le champ, par un bouton
|
|
420
|
-
* « Retirer … ». Un resume « 3 choix » dans le declencheur ne dit pas lesquels,
|
|
421
|
-
* et obligerait a rouvrir la liste pour en retirer un.
|
|
422
|
-
* - Un choix retire rend le focus au retrait suivant, ou au champ : le focus ne
|
|
423
|
-
* tombe jamais sur le document.
|
|
424
|
-
*
|
|
425
|
-
* ⚠️ Sous une dizaine d'options, un groupe de cases a cocher (`st-fieldset` et
|
|
426
|
-
* `st-checkbox`) est plus simple : tout est visible, rien a ouvrir.
|
|
427
|
-
*/
|
|
428
|
-
class StMultiselect extends ContratDeChamp {
|
|
429
|
-
libelles = inject(ST_LIBELLES);
|
|
430
|
-
element = inject(ElementRef);
|
|
431
|
-
injecteur = inject(Injector);
|
|
432
|
-
value = model([], /* @ts-ignore */
|
|
433
|
-
...(ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []));
|
|
434
|
-
options = input.required(/* @ts-ignore */
|
|
435
|
-
...(ngDevMode ? [{ debugName: "options" }] : /* istanbul ignore next */ []));
|
|
436
|
-
annonce = new AnnonceLocale(inject(DestroyRef));
|
|
437
|
-
ouvert = signal(false, /* @ts-ignore */
|
|
438
|
-
...(ngDevMode ? [{ debugName: "ouvert" }] : /* istanbul ignore next */ []));
|
|
439
|
-
liste = viewChild(Listbox, /* @ts-ignore */
|
|
440
|
-
...(ngDevMode ? [{ debugName: "liste" }] : /* istanbul ignore next */ []));
|
|
441
|
-
/** La liste d'Aria attend un tableau modifiable ; le modele, lui, est en lecture seule. */
|
|
442
|
-
valeursDeListe = computed(() => [...this.value()], /* @ts-ignore */
|
|
443
|
-
...(ngDevMode ? [{ debugName: "valeursDeListe" }] : /* istanbul ignore next */ []));
|
|
444
|
-
choisies = computed(() => {
|
|
445
|
-
const valeurs = new Set(this.value());
|
|
446
|
-
return this.options().filter((option) => valeurs.has(option.valeur));
|
|
447
|
-
}, /* @ts-ignore */
|
|
448
|
-
...(ngDevMode ? [{ debugName: "choisies" }] : /* istanbul ignore next */ []));
|
|
449
|
-
resume = computed(() => {
|
|
450
|
-
const choisies = this.choisies();
|
|
451
|
-
return choisies.length === 0
|
|
452
|
-
? this.libelles().choisir
|
|
453
|
-
: choisies.map((option) => option.libelle).join(', ');
|
|
454
|
-
}, /* @ts-ignore */
|
|
455
|
-
...(ngDevMode ? [{ debugName: "resume" }] : /* istanbul ignore next */ []));
|
|
456
|
-
constructor() {
|
|
457
|
-
super();
|
|
458
|
-
afterRenderEffect(() => {
|
|
459
|
-
if (this.ouvert())
|
|
460
|
-
this.liste()?.scrollActiveItemIntoView({ block: 'nearest' });
|
|
461
|
-
});
|
|
462
|
-
}
|
|
463
|
-
/** Le declencheur n'est pas un champ natif : la base ne le trouve pas par `#champ`. */
|
|
464
|
-
focus(options) {
|
|
465
|
-
this.element.nativeElement.querySelector('[ngCombobox]')?.focus(options);
|
|
466
|
-
}
|
|
467
|
-
surChoix(valeurs) {
|
|
468
|
-
if (this.readonly())
|
|
469
|
-
return;
|
|
470
|
-
// Dans l'ordre des options, et non dans l'ordre des clics : un modele stable
|
|
471
|
-
// ne change pas de forme selon le chemin pris pour le remplir.
|
|
472
|
-
const retenues = new Set(valeurs);
|
|
473
|
-
this.value.set(this.options()
|
|
474
|
-
.filter((option) => retenues.has(option.valeur))
|
|
475
|
-
.map((option) => option.valeur));
|
|
476
|
-
}
|
|
477
|
-
retirer(valeur, indice) {
|
|
478
|
-
const restantes = this.value().filter((choisie) => choisie !== valeur);
|
|
479
|
-
this.value.set(restantes);
|
|
480
|
-
this.annonce.annoncer(this.libelles().nombreDeSelections(restantes.length));
|
|
481
|
-
afterNextRender(() => {
|
|
482
|
-
const boutons = this.element.nativeElement.querySelectorAll('.st-multiselect__retrait');
|
|
483
|
-
const suivant = boutons[Math.min(indice, boutons.length - 1)];
|
|
484
|
-
if (suivant !== undefined)
|
|
485
|
-
suivant.focus();
|
|
486
|
-
else
|
|
487
|
-
this.focus();
|
|
488
|
-
}, { injector: this.injecteur });
|
|
489
|
-
}
|
|
490
|
-
aLaSortie(evenement) {
|
|
491
|
-
const suivant = evenement.relatedTarget;
|
|
492
|
-
if (suivant !== null && this.element.nativeElement.contains(suivant))
|
|
493
|
-
return;
|
|
494
|
-
this.touch.emit();
|
|
495
|
-
}
|
|
496
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: StMultiselect, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
497
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: StMultiselect, isStandalone: true, selector: "st-multiselect", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { value: "valueChange" }, host: { listeners: { "focusout": "aLaSortie($event)" }, classAttribute: "st-multiselect" }, viewQueries: [{ propertyName: "liste", first: true, predicate: Listbox, descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: "<st-form-field\n [libelle]=\"libelle()\"\n [aide]=\"aide()\"\n [erreurs]=\"errors()\"\n [afficherErreurs]=\"touched()\"\n [obligatoire]=\"required()\"\n>\n <div\n #combobox=\"ngCombobox\"\n class=\"st-multiselect__declencheur\"\n stControleDeChamp\n ngCombobox\n [attr.data-vide]=\"choisies().length === 0 ? '' : null\"\n [(expanded)]=\"ouvert\"\n [disabled]=\"disabled()\"\n [readonly]=\"readonly()\"\n >\n <span class=\"st-multiselect__resume\">{{ resume() }}</span>\n <st-icon class=\"st-multiselect__chevron\" nom=\"chevron-bas\" taille=\"sm\" />\n </div>\n\n <!-- \u26A0\uFE0F La primitive de popup ENVELOPPE la surcouche, et non l'inverse (exemple\n de la documentation d'Aria). Enfermee dans la surcouche, elle ne\n s'enregistre qu'a l'ouverture : liste fermee, le champ annonce\n aria-autocomplete=\"none\" et aucun aria-haspopup, et le lecteur d'ecran\n ignore qu'une liste existe. -->\n <ng-template ngComboboxPopup [combobox]=\"combobox\">\n <ng-template\n [cdkConnectedOverlay]=\"{ origin: combobox.element, usePopover: 'inline', matchWidth: true }\"\n [cdkConnectedOverlayOpen]=\"ouvert()\"\n >\n <div class=\"st-multiselect__popup\">\n <div\n #liste=\"ngListbox\"\n class=\"st-multiselect__liste\"\n ngListbox\n ngComboboxWidget\n focusMode=\"activedescendant\"\n selectionMode=\"explicit\"\n [multi]=\"true\"\n [tabindex]=\"-1\"\n [attr.aria-label]=\"libelle()\"\n [activeDescendant]=\"liste.activeDescendant()\"\n [value]=\"valeursDeListe()\"\n (valueChange)=\"surChoix($event)\"\n >\n @for (option of options(); track option.valeur) {\n <div\n class=\"st-multiselect__option\"\n ngOption\n [value]=\"option.valeur\"\n [label]=\"option.libelle\"\n [disabled]=\"option.desactivee === true\"\n >\n <span>{{ option.libelle }}</span>\n <st-icon class=\"st-multiselect__coche\" nom=\"coche\" taille=\"sm\" />\n </div>\n }\n </div>\n </div>\n </ng-template>\n </ng-template>\n\n @if (choisies().length > 0) {\n <ul class=\"st-multiselect__choix\">\n @for (option of choisies(); track option.valeur; let indice = $index) {\n <li class=\"st-multiselect__puce\">\n <span>{{ option.libelle }}</span>\n <!-- eslint-disable-next-line @angular-eslint/template/elements-content --\n Le contenu vient du gabarit de stIconButton, et l'etiquette est requise. -->\n <button\n class=\"st-multiselect__retrait\"\n stIconButton\n type=\"button\"\n icone=\"croix\"\n taille=\"sm\"\n [etiquette]=\"libelles().retirerLeChoix(option.libelle)\"\n [disabled]=\"disabled() || readonly()\"\n (click)=\"retirer(option.valeur, indice)\"\n ></button>\n </li>\n }\n </ul>\n }\n</st-form-field>\n<span class=\"st-vh\" aria-live=\"polite\">{{ annonce.texte() }}</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([hidden]){display:none!important}:host{display:block}.st-multiselect__declencheur:focus-visible{outline:2px solid var(--st-couleur-anneau-focus);outline-offset:2px}.st-multiselect__declencheur{box-sizing:border-box;inline-size:100%;min-block-size:var(--st-commande-hauteur, var(--st-cible-tactile-min));padding:var(--st-espacement-2) var(--st-espacement-3);font:inherit;color:var(--st-couleur-texte);background:var(--st-couleur-surface);border:1px solid var(--st-couleur-bordure-forte);border-radius:var(--st-commande-rayon, var(--st-rayon-md))}.st-multiselect__declencheur[aria-invalid=true]{border-color:var(--st-couleur-danger);box-shadow:inset 0 0 0 1px var(--st-couleur-danger)}.st-multiselect__declencheur:disabled{color:var(--st-couleur-texte-desactive);cursor:not-allowed;background:var(--st-couleur-surface-enfoncee)}.st-multiselect__declencheur:read-only:not(:disabled){background:var(--st-couleur-surface-enfoncee)}.st-multiselect__declencheur{display:flex;gap:var(--st-espacement-2);align-items:center;justify-content:space-between;cursor:pointer}.st-multiselect__declencheur[aria-disabled=true]{color:var(--st-couleur-texte-desactive);cursor:not-allowed;background:var(--st-couleur-surface-enfoncee)}.st-multiselect__resume{min-inline-size:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}[data-vide]>.st-multiselect__resume{color:var(--st-couleur-texte-discret)}.st-multiselect__chevron{flex:none;color:var(--st-couleur-texte-discret)}.st-multiselect__popup{max-block-size:18rem;overflow-y:auto;color:var(--st-couleur-texte);background:var(--st-couleur-surface);border:1px solid var(--st-couleur-bordure-forte);border-radius:var(--st-rayon-sm);box-shadow:var(--st-ombre-md)}.st-multiselect__option{display:flex;gap:var(--st-espacement-2);align-items:center;justify-content:space-between;min-block-size:var(--st-cible-tactile-min);padding:var(--st-espacement-2) var(--st-espacement-3);cursor:pointer}.st-multiselect__option[data-active=true]{outline:2px solid var(--st-couleur-anneau-focus);outline-offset:-2px;background:var(--st-couleur-surface-enfoncee)}.st-multiselect__option[aria-disabled=true]{color:var(--st-couleur-texte-desactive);cursor:not-allowed}.st-multiselect__option[aria-selected=true]{font-weight:var(--st-graisse-semi)}.st-multiselect__coche{visibility:hidden}[aria-selected=true]>.st-multiselect__coche{visibility:visible}.st-multiselect__choix{display:flex;flex-wrap:wrap;gap:var(--st-espacement-2);padding:0;margin:var(--st-espacement-2) 0 0;list-style:none}.st-multiselect__puce{display:inline-flex;gap:var(--st-espacement-1);align-items:center;padding-inline-start:var(--st-espacement-3);background:var(--st-couleur-surface-enfoncee);border:1px solid var(--st-couleur-bordure);border-radius:var(--st-rayon-pleine)}\n"], dependencies: [{ kind: "component", type: StFormField, selector: "st-form-field", inputs: ["libelle", "aide", "complement", "erreurs", "afficherErreurs", "obligatoire", "disposition", "libelleMasque"] }, { kind: "directive", type: StControleDeChamp, selector: "[stControleDeChamp]" }, { kind: "component", type: StIcon, selector: "st-icon", inputs: ["nom", "sprite", "nomMetier", "taille", "ton", "etiquette"] }, { kind: "component", type: StIconButton, selector: "button[stIconButton]", inputs: ["icone", "etiquette", "variante", "taille", "enfonce"] }, { kind: "directive", type: Combobox, selector: "[ngCombobox]", inputs: ["disabled", "readonly", "softDisabled", "alwaysExpanded", "tabindex", "expanded", "value", "inlineSuggestion"], outputs: ["expandedChange", "valueChange"], exportAs: ["ngCombobox"] }, { kind: "directive", type: ComboboxPopup, selector: "ng-template[ngComboboxPopup]", inputs: ["combobox", "popupType"], exportAs: ["ngComboboxPopup"] }, { kind: "directive", type: ComboboxWidget, selector: "[ngComboboxWidget]", inputs: ["activeDescendant"], exportAs: ["ngComboboxWidget"] }, { kind: "directive", type: Listbox, selector: "[ngListbox]", inputs: ["id", "orientation", "multi", "wrap", "softDisabled", "focusMode", "selectionMode", "typeaheadDelay", "disabled", "readonly", "tabindex", "value"], outputs: ["valueChange"], exportAs: ["ngListbox"] }, { kind: "directive", type: Option, selector: "[ngOption]", inputs: ["id", "value", "disabled", "label"], exportAs: ["ngOption"] }, { kind: "directive", type: CdkConnectedOverlay, selector: "[cdk-connected-overlay], [connected-overlay], [cdkConnectedOverlay]", inputs: ["cdkConnectedOverlayOrigin", "cdkConnectedOverlayPositions", "cdkConnectedOverlayPositionStrategy", "cdkConnectedOverlayOffsetX", "cdkConnectedOverlayOffsetY", "cdkConnectedOverlayWidth", "cdkConnectedOverlayHeight", "cdkConnectedOverlayMinWidth", "cdkConnectedOverlayMinHeight", "cdkConnectedOverlayBackdropClass", "cdkConnectedOverlayPanelClass", "cdkConnectedOverlayViewportMargin", "cdkConnectedOverlayScrollStrategy", "cdkConnectedOverlayOpen", "cdkConnectedOverlayDisableClose", "cdkConnectedOverlayTransformOriginOn", "cdkConnectedOverlayHasBackdrop", "cdkConnectedOverlayLockPosition", "cdkConnectedOverlayFlexibleDimensions", "cdkConnectedOverlayGrowAfterOpen", "cdkConnectedOverlayPush", "cdkConnectedOverlayDisposeOnNavigation", "cdkConnectedOverlayUsePopover", "cdkConnectedOverlayMatchWidth", "cdkConnectedOverlay"], outputs: ["backdropClick", "positionChange", "attach", "detach", "overlayKeydown", "overlayOutsideClick"], exportAs: ["cdkConnectedOverlay"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
498
|
-
}
|
|
499
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: StMultiselect, decorators: [{
|
|
500
|
-
type: Component,
|
|
501
|
-
args: [{ selector: 'st-multiselect', changeDetection: ChangeDetectionStrategy.OnPush, imports: [
|
|
502
|
-
StFormField,
|
|
503
|
-
StControleDeChamp,
|
|
504
|
-
StIcon,
|
|
505
|
-
StIconButton,
|
|
506
|
-
Combobox,
|
|
507
|
-
ComboboxPopup,
|
|
508
|
-
ComboboxWidget,
|
|
509
|
-
Listbox,
|
|
510
|
-
Option,
|
|
511
|
-
CdkConnectedOverlay,
|
|
512
|
-
], host: {
|
|
513
|
-
class: 'st-multiselect',
|
|
514
|
-
'(focusout)': 'aLaSortie($event)',
|
|
515
|
-
}, template: "<st-form-field\n [libelle]=\"libelle()\"\n [aide]=\"aide()\"\n [erreurs]=\"errors()\"\n [afficherErreurs]=\"touched()\"\n [obligatoire]=\"required()\"\n>\n <div\n #combobox=\"ngCombobox\"\n class=\"st-multiselect__declencheur\"\n stControleDeChamp\n ngCombobox\n [attr.data-vide]=\"choisies().length === 0 ? '' : null\"\n [(expanded)]=\"ouvert\"\n [disabled]=\"disabled()\"\n [readonly]=\"readonly()\"\n >\n <span class=\"st-multiselect__resume\">{{ resume() }}</span>\n <st-icon class=\"st-multiselect__chevron\" nom=\"chevron-bas\" taille=\"sm\" />\n </div>\n\n <!-- \u26A0\uFE0F La primitive de popup ENVELOPPE la surcouche, et non l'inverse (exemple\n de la documentation d'Aria). Enfermee dans la surcouche, elle ne\n s'enregistre qu'a l'ouverture : liste fermee, le champ annonce\n aria-autocomplete=\"none\" et aucun aria-haspopup, et le lecteur d'ecran\n ignore qu'une liste existe. -->\n <ng-template ngComboboxPopup [combobox]=\"combobox\">\n <ng-template\n [cdkConnectedOverlay]=\"{ origin: combobox.element, usePopover: 'inline', matchWidth: true }\"\n [cdkConnectedOverlayOpen]=\"ouvert()\"\n >\n <div class=\"st-multiselect__popup\">\n <div\n #liste=\"ngListbox\"\n class=\"st-multiselect__liste\"\n ngListbox\n ngComboboxWidget\n focusMode=\"activedescendant\"\n selectionMode=\"explicit\"\n [multi]=\"true\"\n [tabindex]=\"-1\"\n [attr.aria-label]=\"libelle()\"\n [activeDescendant]=\"liste.activeDescendant()\"\n [value]=\"valeursDeListe()\"\n (valueChange)=\"surChoix($event)\"\n >\n @for (option of options(); track option.valeur) {\n <div\n class=\"st-multiselect__option\"\n ngOption\n [value]=\"option.valeur\"\n [label]=\"option.libelle\"\n [disabled]=\"option.desactivee === true\"\n >\n <span>{{ option.libelle }}</span>\n <st-icon class=\"st-multiselect__coche\" nom=\"coche\" taille=\"sm\" />\n </div>\n }\n </div>\n </div>\n </ng-template>\n </ng-template>\n\n @if (choisies().length > 0) {\n <ul class=\"st-multiselect__choix\">\n @for (option of choisies(); track option.valeur; let indice = $index) {\n <li class=\"st-multiselect__puce\">\n <span>{{ option.libelle }}</span>\n <!-- eslint-disable-next-line @angular-eslint/template/elements-content --\n Le contenu vient du gabarit de stIconButton, et l'etiquette est requise. -->\n <button\n class=\"st-multiselect__retrait\"\n stIconButton\n type=\"button\"\n icone=\"croix\"\n taille=\"sm\"\n [etiquette]=\"libelles().retirerLeChoix(option.libelle)\"\n [disabled]=\"disabled() || readonly()\"\n (click)=\"retirer(option.valeur, indice)\"\n ></button>\n </li>\n }\n </ul>\n }\n</st-form-field>\n<span class=\"st-vh\" aria-live=\"polite\">{{ annonce.texte() }}</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([hidden]){display:none!important}:host{display:block}.st-multiselect__declencheur:focus-visible{outline:2px solid var(--st-couleur-anneau-focus);outline-offset:2px}.st-multiselect__declencheur{box-sizing:border-box;inline-size:100%;min-block-size:var(--st-commande-hauteur, var(--st-cible-tactile-min));padding:var(--st-espacement-2) var(--st-espacement-3);font:inherit;color:var(--st-couleur-texte);background:var(--st-couleur-surface);border:1px solid var(--st-couleur-bordure-forte);border-radius:var(--st-commande-rayon, var(--st-rayon-md))}.st-multiselect__declencheur[aria-invalid=true]{border-color:var(--st-couleur-danger);box-shadow:inset 0 0 0 1px var(--st-couleur-danger)}.st-multiselect__declencheur:disabled{color:var(--st-couleur-texte-desactive);cursor:not-allowed;background:var(--st-couleur-surface-enfoncee)}.st-multiselect__declencheur:read-only:not(:disabled){background:var(--st-couleur-surface-enfoncee)}.st-multiselect__declencheur{display:flex;gap:var(--st-espacement-2);align-items:center;justify-content:space-between;cursor:pointer}.st-multiselect__declencheur[aria-disabled=true]{color:var(--st-couleur-texte-desactive);cursor:not-allowed;background:var(--st-couleur-surface-enfoncee)}.st-multiselect__resume{min-inline-size:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}[data-vide]>.st-multiselect__resume{color:var(--st-couleur-texte-discret)}.st-multiselect__chevron{flex:none;color:var(--st-couleur-texte-discret)}.st-multiselect__popup{max-block-size:18rem;overflow-y:auto;color:var(--st-couleur-texte);background:var(--st-couleur-surface);border:1px solid var(--st-couleur-bordure-forte);border-radius:var(--st-rayon-sm);box-shadow:var(--st-ombre-md)}.st-multiselect__option{display:flex;gap:var(--st-espacement-2);align-items:center;justify-content:space-between;min-block-size:var(--st-cible-tactile-min);padding:var(--st-espacement-2) var(--st-espacement-3);cursor:pointer}.st-multiselect__option[data-active=true]{outline:2px solid var(--st-couleur-anneau-focus);outline-offset:-2px;background:var(--st-couleur-surface-enfoncee)}.st-multiselect__option[aria-disabled=true]{color:var(--st-couleur-texte-desactive);cursor:not-allowed}.st-multiselect__option[aria-selected=true]{font-weight:var(--st-graisse-semi)}.st-multiselect__coche{visibility:hidden}[aria-selected=true]>.st-multiselect__coche{visibility:visible}.st-multiselect__choix{display:flex;flex-wrap:wrap;gap:var(--st-espacement-2);padding:0;margin:var(--st-espacement-2) 0 0;list-style:none}.st-multiselect__puce{display:inline-flex;gap:var(--st-espacement-1);align-items:center;padding-inline-start:var(--st-espacement-3);background:var(--st-couleur-surface-enfoncee);border:1px solid var(--st-couleur-bordure);border-radius:var(--st-rayon-pleine)}\n"] }]
|
|
516
|
-
}], ctorParameters: () => [], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }, { type: i0.Output, args: ["valueChange"] }], options: [{ type: i0.Input, args: [{ isSignal: true, alias: "options", required: true }] }], liste: [{ type: i0.ViewChild, args: [i0.forwardRef(() => Listbox), { isSignal: true }] }] } });
|
|
517
|
-
|
|
518
|
-
/**
|
|
519
|
-
* Arbre de donnees hierarchiques, sur `@angular/aria/tree` : dossiers, plan
|
|
520
|
-
* comptable, organisation.
|
|
521
|
-
*
|
|
522
|
-
* ```html
|
|
523
|
-
* <st-tree etiquette="Plan comptable" [noeuds]="comptes" [(selection)]="compte" [(deplies)]="ouverts" />
|
|
524
|
-
* ```
|
|
525
|
-
*
|
|
526
|
-
* ⚠️ **Jamais pour la navigation du site** (UX-17) : une navigation est une liste
|
|
527
|
-
* de liens, que le lecteur d'ecran liste et parcourt comme telle. Un arbre se
|
|
528
|
-
* parcourt aux fleches, un element a la fois, et ses elements ne sont pas des
|
|
529
|
-
* liens. Le mode « navigation » de la primitive n'est donc pas expose.
|
|
530
|
-
*
|
|
531
|
-
* ⚠️ **Les noeuds sont rendus par le composant, a partir de donnees** (FE-6) : la
|
|
532
|
-
* primitive relie un element a son arbre par injection, et un contenu projete
|
|
533
|
-
* garde l'injecteur de l'endroit ou il est ecrit — lecon de `st-menu`.
|
|
534
|
-
*
|
|
535
|
-
* Clavier de la primitive : fleches haut et bas entre les elements visibles,
|
|
536
|
-
* droite pour deplier ou entrer, gauche pour replier ou remonter, Debut et Fin,
|
|
537
|
-
* recherche a la frappe ; Espace ou Entree choisit. Selection et depliage sont des
|
|
538
|
-
* listes de VALEURS, lisibles et restaurables par l'application.
|
|
539
|
-
*/
|
|
540
|
-
class StTree {
|
|
541
|
-
/** Nom de l'arbre, lu a l'entree. Obligatoire. */
|
|
542
|
-
etiquette = input.required(/* @ts-ignore */
|
|
543
|
-
...(ngDevMode ? [{ debugName: "etiquette" }] : /* istanbul ignore next */ []));
|
|
544
|
-
noeuds = input.required(/* @ts-ignore */
|
|
545
|
-
...(ngDevMode ? [{ debugName: "noeuds" }] : /* istanbul ignore next */ []));
|
|
546
|
-
multiple = input(false, { ...(ngDevMode ? { debugName: "multiple" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
547
|
-
selection = model([], /* @ts-ignore */
|
|
548
|
-
...(ngDevMode ? [{ debugName: "selection" }] : /* istanbul ignore next */ []));
|
|
549
|
-
deplies = model([], /* @ts-ignore */
|
|
550
|
-
...(ngDevMode ? [{ debugName: "deplies" }] : /* istanbul ignore next */ []));
|
|
551
|
-
/** La primitive attend un tableau modifiable ; le modele est en lecture seule. */
|
|
552
|
-
valeursChoisies = computed(() => [...this.selection()], /* @ts-ignore */
|
|
553
|
-
...(ngDevMode ? [{ debugName: "valeursChoisies" }] : /* istanbul ignore next */ []));
|
|
554
|
-
ensembleDeplie = computed(() => new Set(this.deplies()), /* @ts-ignore */
|
|
555
|
-
...(ngDevMode ? [{ debugName: "ensembleDeplie" }] : /* istanbul ignore next */ []));
|
|
556
|
-
estDeplie(noeud) {
|
|
557
|
-
return this.ensembleDeplie().has(noeud.valeur);
|
|
558
|
-
}
|
|
559
|
-
surDepliage(noeud, deplie) {
|
|
560
|
-
const deplies = this.deplies().filter((valeur) => valeur !== noeud.valeur);
|
|
561
|
-
this.deplies.set(deplie ? [...deplies, noeud.valeur] : deplies);
|
|
562
|
-
}
|
|
563
|
-
surSelection(valeurs) {
|
|
564
|
-
this.selection.set([...valeurs]);
|
|
565
|
-
}
|
|
566
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: StTree, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
567
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: StTree, isStandalone: true, selector: "st-tree", inputs: { etiquette: { classPropertyName: "etiquette", publicName: "etiquette", isSignal: true, isRequired: true, transformFunction: null }, noeuds: { classPropertyName: "noeuds", publicName: "noeuds", isSignal: true, isRequired: true, transformFunction: null }, multiple: { classPropertyName: "multiple", publicName: "multiple", isSignal: true, isRequired: false, transformFunction: null }, selection: { classPropertyName: "selection", publicName: "selection", isSignal: true, isRequired: false, transformFunction: null }, deplies: { classPropertyName: "deplies", publicName: "deplies", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { selection: "selectionChange", deplies: "depliesChange" }, host: { classAttribute: "st-tree" }, ngImport: i0, template: "<ul\n #arbre=\"ngTree\"\n class=\"st-tree__racine\"\n ngTree\n selectionMode=\"explicit\"\n [attr.aria-label]=\"etiquette()\"\n [multi]=\"multiple()\"\n [value]=\"valeursChoisies()\"\n (valueChange)=\"surSelection($event)\"\n>\n <ng-container\n *ngTemplateOutlet=\"niveau; context: { noeuds: noeuds(), parent: arbre, niveau: 1 }\"\n />\n</ul>\n\n<ng-template #niveau let-noeuds=\"noeuds\" let-parent=\"parent\" let-profondeur=\"niveau\">\n @for (noeud of noeuds; track noeud.valeur) {\n <li\n #element=\"ngTreeItem\"\n class=\"st-tree__element\"\n ngTreeItem\n [parent]=\"parent\"\n [value]=\"noeud.valeur\"\n [label]=\"noeud.libelle\"\n [disabled]=\"noeud.desactive === true\"\n [expanded]=\"estDeplie(noeud)\"\n [style.--st-arbre-niveau]=\"profondeur\"\n (expandedChange)=\"surDepliage(noeud, $event)\"\n >\n @if (noeud.enfants?.length) {\n <st-icon\n class=\"st-tree__chevron\"\n taille=\"sm\"\n [nom]=\"estDeplie(noeud) ? 'chevron-bas' : 'chevron-droite'\"\n />\n } @else {\n <span class=\"st-tree__espace\"></span>\n }\n <span class=\"st-tree__libelle\">{{ noeud.libelle }}</span>\n <st-icon class=\"st-tree__coche\" nom=\"coche\" taille=\"sm\" />\n </li>\n @if (noeud.enfants?.length) {\n <ul class=\"st-tree__groupe\" role=\"group\">\n <ng-template ngTreeItemGroup [ownedBy]=\"element\" #groupe=\"ngTreeItemGroup\">\n <ng-container\n *ngTemplateOutlet=\"\n niveau;\n context: { noeuds: noeud.enfants, parent: groupe, niveau: profondeur + 1 }\n \"\n />\n </ng-template>\n </ul>\n }\n }\n</ng-template>\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([hidden]){display:none!important}:host{display:block}.st-tree__racine,.st-tree__groupe{padding:0;margin:0;list-style:none}.st-tree__element{display:flex;gap:var(--st-espacement-1);align-items:center;min-block-size:var(--st-cible-tactile-min);padding-inline:calc((var(--st-arbre-niveau, 1) - 1) * 1.5rem + var(--st-espacement-2)) var(--st-espacement-2);cursor:pointer;border-radius:var(--st-rayon-sm)}@media(hover:hover){.st-tree__element:hover{background:var(--st-couleur-surface-survol)}}.st-tree__element:focus-visible{outline:2px solid var(--st-couleur-anneau-focus);outline-offset:-2px}.st-tree__element[aria-selected=true]{font-weight:var(--st-graisse-semi);background:var(--st-couleur-primaire-discret)}.st-tree__element[aria-disabled=true]{color:var(--st-couleur-texte-desactive);cursor:not-allowed}.st-tree__chevron,.st-tree__espace{flex:none;inline-size:1rem}.st-tree__coche{margin-inline-start:auto;visibility:hidden}[aria-selected=true]>.st-tree__coche{visibility:visible}.st-tree__groupe:empty{display:none}\n"], dependencies: [{ kind: "directive", type: Tree, selector: "[ngTree]", inputs: ["id", "orientation", "multi", "disabled", "selectionMode", "focusMode", "wrap", "softDisabled", "typeaheadDelay", "tabindex", "value", "nav", "currentType"], outputs: ["valueChange"], exportAs: ["ngTree"] }, { kind: "directive", type: TreeItem, selector: "[ngTreeItem]", inputs: ["id", "value", "parent", "disabled", "selectable", "expanded", "label"], outputs: ["expandedChange"], exportAs: ["ngTreeItem"] }, { kind: "directive", type: TreeItemGroup, selector: "ng-template[ngTreeItemGroup]", inputs: ["ownedBy"], exportAs: ["ngTreeItemGroup"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: StIcon, selector: "st-icon", inputs: ["nom", "sprite", "nomMetier", "taille", "ton", "etiquette"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
568
|
-
}
|
|
569
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: StTree, decorators: [{
|
|
570
|
-
type: Component,
|
|
571
|
-
args: [{ selector: 'st-tree', changeDetection: ChangeDetectionStrategy.OnPush, imports: [Tree, TreeItem, TreeItemGroup, NgTemplateOutlet, StIcon], host: { class: 'st-tree' }, template: "<ul\n #arbre=\"ngTree\"\n class=\"st-tree__racine\"\n ngTree\n selectionMode=\"explicit\"\n [attr.aria-label]=\"etiquette()\"\n [multi]=\"multiple()\"\n [value]=\"valeursChoisies()\"\n (valueChange)=\"surSelection($event)\"\n>\n <ng-container\n *ngTemplateOutlet=\"niveau; context: { noeuds: noeuds(), parent: arbre, niveau: 1 }\"\n />\n</ul>\n\n<ng-template #niveau let-noeuds=\"noeuds\" let-parent=\"parent\" let-profondeur=\"niveau\">\n @for (noeud of noeuds; track noeud.valeur) {\n <li\n #element=\"ngTreeItem\"\n class=\"st-tree__element\"\n ngTreeItem\n [parent]=\"parent\"\n [value]=\"noeud.valeur\"\n [label]=\"noeud.libelle\"\n [disabled]=\"noeud.desactive === true\"\n [expanded]=\"estDeplie(noeud)\"\n [style.--st-arbre-niveau]=\"profondeur\"\n (expandedChange)=\"surDepliage(noeud, $event)\"\n >\n @if (noeud.enfants?.length) {\n <st-icon\n class=\"st-tree__chevron\"\n taille=\"sm\"\n [nom]=\"estDeplie(noeud) ? 'chevron-bas' : 'chevron-droite'\"\n />\n } @else {\n <span class=\"st-tree__espace\"></span>\n }\n <span class=\"st-tree__libelle\">{{ noeud.libelle }}</span>\n <st-icon class=\"st-tree__coche\" nom=\"coche\" taille=\"sm\" />\n </li>\n @if (noeud.enfants?.length) {\n <ul class=\"st-tree__groupe\" role=\"group\">\n <ng-template ngTreeItemGroup [ownedBy]=\"element\" #groupe=\"ngTreeItemGroup\">\n <ng-container\n *ngTemplateOutlet=\"\n niveau;\n context: { noeuds: noeud.enfants, parent: groupe, niveau: profondeur + 1 }\n \"\n />\n </ng-template>\n </ul>\n }\n }\n</ng-template>\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([hidden]){display:none!important}:host{display:block}.st-tree__racine,.st-tree__groupe{padding:0;margin:0;list-style:none}.st-tree__element{display:flex;gap:var(--st-espacement-1);align-items:center;min-block-size:var(--st-cible-tactile-min);padding-inline:calc((var(--st-arbre-niveau, 1) - 1) * 1.5rem + var(--st-espacement-2)) var(--st-espacement-2);cursor:pointer;border-radius:var(--st-rayon-sm)}@media(hover:hover){.st-tree__element:hover{background:var(--st-couleur-surface-survol)}}.st-tree__element:focus-visible{outline:2px solid var(--st-couleur-anneau-focus);outline-offset:-2px}.st-tree__element[aria-selected=true]{font-weight:var(--st-graisse-semi);background:var(--st-couleur-primaire-discret)}.st-tree__element[aria-disabled=true]{color:var(--st-couleur-texte-desactive);cursor:not-allowed}.st-tree__chevron,.st-tree__espace{flex:none;inline-size:1rem}.st-tree__coche{margin-inline-start:auto;visibility:hidden}[aria-selected=true]>.st-tree__coche{visibility:visible}.st-tree__groupe:empty{display:none}\n"] }]
|
|
572
|
-
}], propDecorators: { etiquette: [{ type: i0.Input, args: [{ isSignal: true, alias: "etiquette", required: true }] }], noeuds: [{ type: i0.Input, args: [{ isSignal: true, alias: "noeuds", required: true }] }], multiple: [{ type: i0.Input, args: [{ isSignal: true, alias: "multiple", required: false }] }], selection: [{ type: i0.Input, args: [{ isSignal: true, alias: "selection", required: false }] }, { type: i0.Output, args: ["selectionChange"] }], deplies: [{ type: i0.Input, args: [{ isSignal: true, alias: "deplies", required: false }] }, { type: i0.Output, args: ["depliesChange"] }] } });
|
|
573
|
-
|
|
574
|
-
/**
|
|
575
|
-
* @starterlib/ui/interactions — les composants montes sur Angular Aria qui ne
|
|
576
|
-
* se posent pas au-dessus de la page.
|
|
577
|
-
*
|
|
578
|
-
* ⚠️ Un point d'entree separe pour la meme raison que `ui/surfaces` : ce qui vit
|
|
579
|
-
* ici traine `@angular/aria`, pair optionnel. Laisse dans le tronc, il entrerait
|
|
580
|
-
* dans le train de singletons de chaque application. Mais ce n'est pas une
|
|
581
|
-
* surface : des onglets font partie de la page. Le ranger sous `ui/surfaces`
|
|
582
|
-
* aurait fait mentir le nom, et l'ADR 0003 aurait perdu sa lisibilite (audit de
|
|
583
|
-
* la vague 2, decision 5.1).
|
|
584
|
-
*
|
|
585
|
-
* ⚠️ En federation, ce point d'entree se partage SEPAREMENT : c'est un
|
|
586
|
-
* specificateur de module distinct.
|
|
1
|
+
export * from '@starterlib/ui/onglets';
|
|
2
|
+
export * from '@starterlib/ui/navigation';
|
|
3
|
+
export * from '@starterlib/ui/selection';
|
|
4
|
+
export * from '@starterlib/ui/arbre';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* @starterlib/ui/interactions — **DEPRECIE depuis la 0.8.0**. Baril de
|
|
8
|
+
* compatibilite : il ne contient plus une ligne de code, il re-exporte les
|
|
9
|
+
* quatre points d'entree qui l'ont remplace.
|
|
10
|
+
*
|
|
11
|
+
* | Ce qu'on importait ici | Ou il vit desormais |
|
|
12
|
+
* |---|---|
|
|
13
|
+
* | `StSidenav`, `StSidenavToggle` | `@starterlib/ui/navigation` |
|
|
14
|
+
* | `StTabs`, `StTabPanel`, `StTabContent` | `@starterlib/ui/onglets` |
|
|
15
|
+
* | `StCombobox`, `StMultiselect` | `@starterlib/ui/selection` |
|
|
16
|
+
* | `StTree` | `@starterlib/ui/arbre` |
|
|
17
|
+
*
|
|
18
|
+
* ⚠️ **Ce qui s'importe d'ici pese les QUATRE familles.** Le baril agrege
|
|
19
|
+
* `@angular/aria/tabs`, `/combobox`, `/listbox`, `/tree`, `@angular/cdk/overlay`
|
|
20
|
+
* et `@angular/cdk/layout` : une page qui ne veut qu'un panneau lateral paie
|
|
21
|
+
* tout le reste (ADR 0031, decision 2). C'est exactement le defaut mesure sur
|
|
22
|
+
* la coquille — 15,2 Ko d'`@angular/aria` pour un seul `StSidenav`.
|
|
23
|
+
*
|
|
24
|
+
* Il survit pour que la migration soit PROGRESSIVE : un remote reste en
|
|
25
|
+
* 0.7.x qui importe `StTabs` d'ici recoit la MEME CLASSE que l'hote qui
|
|
26
|
+
* l'importe de `@starterlib/ui/onglets`, puisque les deux specificateurs sont
|
|
27
|
+
* partages en singleton et que le baril ne fait que re-exporter. A retirer
|
|
28
|
+
* quand plus aucun consommateur ne l'importe.
|
|
587
29
|
*
|
|
588
30
|
* ```ts
|
|
589
|
-
*
|
|
31
|
+
* // Ne plus ecrire :
|
|
32
|
+
* import { StSidenav } from '@starterlib/ui/interactions';
|
|
33
|
+
* // Ecrire :
|
|
34
|
+
* import { StSidenav } from '@starterlib/ui/navigation';
|
|
590
35
|
* ```
|
|
36
|
+
*
|
|
37
|
+
* @deprecated Importer le point d'entree etroit correspondant.
|
|
591
38
|
*/
|
|
592
39
|
|
|
593
40
|
/**
|
|
594
41
|
* Generated bundle index. Do not edit.
|
|
595
42
|
*/
|
|
596
|
-
|
|
597
|
-
export { StCombobox, StMultiselect, StSidenav, StSidenavToggle, StTabContent, StTabPanel, StTabs, StTree };
|
|
598
43
|
//# sourceMappingURL=starterlib-ui-interactions.mjs.map
|