@ktortu/aaa 0.9.7 → 0.9.8
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/dialog/dialog.css +85 -30
- package/fesm2022/ktortu-aaa-cdk.mjs +5 -0
- package/fesm2022/ktortu-aaa-cdk.mjs.map +1 -1
- package/fesm2022/ktortu-aaa-dialog.mjs +157 -44
- package/fesm2022/ktortu-aaa-dialog.mjs.map +1 -1
- package/fesm2022/ktortu-aaa-forms.mjs +173 -69
- package/fesm2022/ktortu-aaa-forms.mjs.map +1 -1
- package/forms/multi-select/multi-select.css +3 -53
- package/forms/styles/select-panel.css +81 -40
- package/package.json +1 -1
- package/themes/theme-catppuccin.css +3 -1
- package/themes/theme-cyberpunk.css +1 -1
- package/types/ktortu-aaa-cdk.d.ts +5 -0
- package/types/ktortu-aaa-dialog.d.ts +31 -21
- package/types/ktortu-aaa-forms.d.ts +51 -10
|
@@ -1,58 +1,8 @@
|
|
|
1
1
|
@layer kt-aaa.components {
|
|
2
2
|
/* Styles SPÉCIFIQUES au multi-select. Tout le panneau commun (trigger, popup, listbox, options,
|
|
3
|
-
filtre, bottom-sheet mobile) vient de ../styles/select-panel.css, chargé en
|
|
4
|
-
styleUrls — ici uniquement :
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
/* Réserve la place de la croix (sibling absolu) : sur le TEXTE, pas sur le padding du
|
|
8
|
-
trigger — la flèche reste collée au bord, la croix se glisse entre texte et flèche. */
|
|
9
|
-
.kt-select__trigger--clearable .kt-select__value {
|
|
10
|
-
margin-inline-end: 2rem;
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
/* Tout effacer : entre le texte et la flèche, disposition standard « texte … ✕ ▾ ».
|
|
14
|
-
24px visibles ; cible étendue à 44px via ::after transparent (AAA). */
|
|
15
|
-
.kt-select__clear {
|
|
16
|
-
position: absolute;
|
|
17
|
-
inset-block-start: 50%;
|
|
18
|
-
inset-inline-end: 2.5rem;
|
|
19
|
-
translate: 0 -50%;
|
|
20
|
-
display: inline-flex;
|
|
21
|
-
align-items: center;
|
|
22
|
-
justify-content: center;
|
|
23
|
-
inline-size: 24px;
|
|
24
|
-
block-size: 24px;
|
|
25
|
-
padding: 0;
|
|
26
|
-
border: 0;
|
|
27
|
-
border-radius: 50%;
|
|
28
|
-
background: transparent;
|
|
29
|
-
color: var(--field-icon-color, #5f6368);
|
|
30
|
-
cursor: pointer;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
.kt-select__clear::after {
|
|
34
|
-
content: '';
|
|
35
|
-
position: absolute;
|
|
36
|
-
inset: -10px;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
.kt-select__clear:hover {
|
|
40
|
-
background-color: color-mix(in srgb, currentColor 12%, transparent);
|
|
41
|
-
color: var(--field-color, inherit);
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
.kt-select__clear:focus-visible {
|
|
45
|
-
outline: 2px solid var(--field-border-color-focus, #0b57d0);
|
|
46
|
-
outline-offset: 1px;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
.kt-select__clear-icon {
|
|
50
|
-
font-family: 'Material Symbols Outlined';
|
|
51
|
-
font-feature-settings: 'liga';
|
|
52
|
-
font-size: 1.25rem;
|
|
53
|
-
line-height: 1;
|
|
54
|
-
-webkit-font-smoothing: antialiased;
|
|
55
|
-
}
|
|
3
|
+
filtre, bottom-sheet mobile, croix « effacer ») vient de ../styles/select-panel.css, chargé en
|
|
4
|
+
premier via styleUrls — ici uniquement : barre d'actions, compteur, checkboxes d'option et
|
|
5
|
+
chips révocables. */
|
|
56
6
|
|
|
57
7
|
/* Barre d'actions de masse (Tout sélectionner / Tout effacer) en tête de panneau. */
|
|
58
8
|
.kt-select__actions {
|
|
@@ -11,7 +11,8 @@
|
|
|
11
11
|
--select-popup-enter-animation (défaut : none — entrée du dropdown desktop ; keyframes de
|
|
12
12
|
thème limitées à transform/opacity/filter, le popup est ancré : ne pas animer la position),
|
|
13
13
|
--kt-sheet-anim-duration (défaut : 120ms — glissement + scrim de la bottom-sheet mobile).
|
|
14
|
-
Les règles spécifiques au multi (chips,
|
|
14
|
+
Les règles spécifiques au multi (chips, actions de masse, compteur, checkbox) vivent dans
|
|
15
|
+
multi-select.css. La croix « effacer » (clearable) est PARTAGÉE (single + multi) : elle est ici. */
|
|
15
16
|
:host {
|
|
16
17
|
display: block;
|
|
17
18
|
}
|
|
@@ -67,6 +68,57 @@
|
|
|
67
68
|
transform: rotate(180deg);
|
|
68
69
|
}
|
|
69
70
|
|
|
71
|
+
/* ===== Croix « effacer » (clearable) — PARTAGÉE single + multi ===== */
|
|
72
|
+
/* Réserve la place de la croix (sibling absolu) : sur le TEXTE, pas sur le padding du trigger —
|
|
73
|
+
la flèche reste collée au bord, la croix se glisse entre texte et flèche. */
|
|
74
|
+
.kt-select__trigger--clearable .kt-select__value {
|
|
75
|
+
margin-inline-end: 2rem;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/* Effacer : entre le texte et la flèche, disposition standard « texte … ✕ ▾ ».
|
|
79
|
+
24px visibles ; cible étendue à 44px via ::after transparent (AAA). */
|
|
80
|
+
.kt-select__clear {
|
|
81
|
+
position: absolute;
|
|
82
|
+
inset-block-start: 50%;
|
|
83
|
+
inset-inline-end: 2.5rem;
|
|
84
|
+
translate: 0 -50%;
|
|
85
|
+
display: inline-flex;
|
|
86
|
+
align-items: center;
|
|
87
|
+
justify-content: center;
|
|
88
|
+
inline-size: 24px;
|
|
89
|
+
block-size: 24px;
|
|
90
|
+
padding: 0;
|
|
91
|
+
border: 0;
|
|
92
|
+
border-radius: 50%;
|
|
93
|
+
background: transparent;
|
|
94
|
+
color: var(--field-icon-color, #5f6368);
|
|
95
|
+
cursor: pointer;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
.kt-select__clear::after {
|
|
99
|
+
content: '';
|
|
100
|
+
position: absolute;
|
|
101
|
+
inset: -10px;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
.kt-select__clear:hover {
|
|
105
|
+
background-color: color-mix(in srgb, currentColor 12%, transparent);
|
|
106
|
+
color: var(--field-color, inherit);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
.kt-select__clear:focus-visible {
|
|
110
|
+
outline: 2px solid var(--field-border-color-focus, #0b57d0);
|
|
111
|
+
outline-offset: 1px;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
.kt-select__clear-icon {
|
|
115
|
+
font-family: 'Material Symbols Outlined';
|
|
116
|
+
font-feature-settings: 'liga';
|
|
117
|
+
font-size: 1.25rem;
|
|
118
|
+
line-height: 1;
|
|
119
|
+
-webkit-font-smoothing: antialiased;
|
|
120
|
+
}
|
|
121
|
+
|
|
70
122
|
/* Conteneur popover (div). Affiché en top-layer via le Popover API.
|
|
71
123
|
border-box pour aligner la largeur sur le trigger. */
|
|
72
124
|
.kt-select__popup {
|
|
@@ -225,7 +277,10 @@
|
|
|
225
277
|
/* ===== ÉCRAN COMPACT : bottom-sheet (même Popover, restylé) =====
|
|
226
278
|
Pilotée par la CLASSE `kt-select__popup--sheet` posée en JS par le composant (signal
|
|
227
279
|
`KtViewport.isCompact()`) — et NON par un `@media` : le seuil est configurable par appli
|
|
228
|
-
(`provideKtBreakpoints`), source unique JS qui pilote aussi ce style.
|
|
280
|
+
(`provideKtBreakpoints`), source unique JS qui pilote aussi ce style.
|
|
281
|
+
ADR-0005 : le popup est un SCROLLER à snap — spacer (un écran, snap « fermé ») puis carte
|
|
282
|
+
(snap « ouvert » en bas). Le drag-to-dismiss « attrapable partout » et l'arbitrage avec la
|
|
283
|
+
listbox interne sont NATIFS (latching) ; l'entrée/sortie = scrolls programmatiques (JS). */
|
|
229
284
|
.kt-select__popup--sheet {
|
|
230
285
|
position: fixed !important;
|
|
231
286
|
inset: 0 !important;
|
|
@@ -241,10 +296,22 @@
|
|
|
241
296
|
background: transparent !important;
|
|
242
297
|
box-shadow: none !important;
|
|
243
298
|
border-radius: 0 !important;
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
299
|
+
display: block;
|
|
300
|
+
overflow-y: auto !important;
|
|
301
|
+
scroll-snap-type: y mandatory;
|
|
302
|
+
/* Pas de scroll chaining vers le fond (le body est déjà verrouillé — ceinture et bretelles). */
|
|
303
|
+
overscroll-behavior: contain;
|
|
304
|
+
/* Le scroller EST le geste : pas de barre de défilement visible sur l'overlay. */
|
|
305
|
+
scrollbar-width: none;
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
/* Spacer de dismiss : un écran entier au-dessus de la carte. Sous le scrim (z-index 1) :
|
|
309
|
+
les clics l'atteignent (fermeture), les gestes tactiles remontent au scroller (drag depuis
|
|
310
|
+
le scrim, façon Instagram). */
|
|
311
|
+
.kt-select__popup--sheet .kt-select__sheet-spacer {
|
|
312
|
+
block-size: 100%;
|
|
313
|
+
scroll-snap-align: start;
|
|
314
|
+
scroll-snap-stop: always;
|
|
248
315
|
}
|
|
249
316
|
|
|
250
317
|
.kt-select__popup--sheet .kt-select__sheet-card {
|
|
@@ -258,11 +325,10 @@
|
|
|
258
325
|
max-block-size: var(--kt-sheet-max-block-size, 85svh);
|
|
259
326
|
width: 100%;
|
|
260
327
|
overflow: hidden;
|
|
261
|
-
/*
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
transition: translate var(--kt-sheet-anim-duration, 120ms) ease;
|
|
328
|
+
/* Snap « ouvert » : bord bas de la carte aligné au bas du viewport. L'entrée (glissement
|
|
329
|
+
du bas) est le scroll programmatique d'ouverture — plus de keyframe kt-sheet-in ici. */
|
|
330
|
+
scroll-snap-align: end;
|
|
331
|
+
scroll-snap-stop: always;
|
|
266
332
|
}
|
|
267
333
|
|
|
268
334
|
/* Sheet FILTRABLE : hauteur STABLE (et non « au contenu plafonné »). Sans ça, filtrer raccourcit
|
|
@@ -273,24 +339,6 @@
|
|
|
273
339
|
max-block-size: var(--kt-sheet-max-block-size, 85svh);
|
|
274
340
|
}
|
|
275
341
|
|
|
276
|
-
.kt-select__popup--sheet:popover-open .kt-select__sheet-card {
|
|
277
|
-
translate: 0 0;
|
|
278
|
-
/* Entrée : glissement du bas (keyframe PARTAGÉE kt-sheet-in). */
|
|
279
|
-
animation: var(--select-sheet-enter-animation, kt-sheet-in var(--kt-sheet-anim-duration, 120ms) ease);
|
|
280
|
-
}
|
|
281
|
-
|
|
282
|
-
/* Pendant le drag : la feuille suit le doigt (translate posé en inline), sans transition. */
|
|
283
|
-
.kt-select__popup--sheet .kt-select__sheet-card.kt-select__popup--dragging {
|
|
284
|
-
transition: none;
|
|
285
|
-
}
|
|
286
|
-
|
|
287
|
-
/* Pendant la fermeture déclenchée par JS */
|
|
288
|
-
.kt-select__popup--sheet.kt-select__popup--closing .kt-select__sheet-card,
|
|
289
|
-
.kt-select__popup--sheet:popover-open.kt-select__popup--closing .kt-select__sheet-card {
|
|
290
|
-
translate: 0 100%;
|
|
291
|
-
transition: translate var(--kt-sheet-exit-duration, 90ms) cubic-bezier(0.4, 0, 0.2, 1);
|
|
292
|
-
}
|
|
293
|
-
|
|
294
342
|
/* Masquer le backdrop popover natif car pointer-events: none y est forcé par le navigateur */
|
|
295
343
|
::ng-deep .kt-select__popup--sheet::backdrop {
|
|
296
344
|
display: none !important;
|
|
@@ -344,27 +392,20 @@
|
|
|
344
392
|
}
|
|
345
393
|
|
|
346
394
|
@media (prefers-reduced-motion: reduce) {
|
|
347
|
-
.kt-select__popup--sheet .kt-select__sheet-card,
|
|
348
395
|
.kt-select__popup--sheet .kt-select__sheet-scrim {
|
|
349
396
|
transition: none;
|
|
350
|
-
translate: 0 0;
|
|
351
397
|
}
|
|
352
398
|
}
|
|
353
399
|
|
|
354
|
-
/* Poignée
|
|
355
|
-
|
|
400
|
+
/* Poignée DÉCORATIVE (ADR-0005) : simple affordance visuelle « ceci se tire » — la sheet
|
|
401
|
+
s'attrape partout au toucher (scroll natif). Ni cursor grab (mensonger : pas de drag souris),
|
|
402
|
+
ni touch-action (le geste EST le scroll), ni cible 44px (ce n'est plus un contrôle). */
|
|
356
403
|
.kt-select__sheet-grab {
|
|
357
404
|
display: flex;
|
|
358
405
|
align-items: center;
|
|
359
406
|
justify-content: center;
|
|
360
407
|
flex: none;
|
|
361
|
-
block-size:
|
|
362
|
-
cursor: grab;
|
|
363
|
-
touch-action: none;
|
|
364
|
-
}
|
|
365
|
-
|
|
366
|
-
.kt-select__sheet-grab:active {
|
|
367
|
-
cursor: grabbing;
|
|
408
|
+
block-size: 28px;
|
|
368
409
|
}
|
|
369
410
|
|
|
370
411
|
.kt-select__sheet-grab::before {
|
package/package.json
CHANGED
|
@@ -13,7 +13,9 @@
|
|
|
13
13
|
/* ============ Socle ============ */
|
|
14
14
|
--kt-surface: light-dark(#eff1f5, #1e1e2e); /* base */
|
|
15
15
|
--kt-on-surface: light-dark(#4c4f69, #cdd6f4); /* text, ~12:1 */
|
|
16
|
-
|
|
16
|
+
/* Latte : subtext1 (subtext0 = 4.36:1, sous AA). 5.5:1 = AA confortable ; 7:1 exigerait
|
|
17
|
+
d'égaler text (#4c4f69) et tuerait la hiérarchie visuelle. Mocha : subtext0, ~7.4:1. */
|
|
18
|
+
--kt-muted: light-dark(#5c5f77, #a6adc8);
|
|
17
19
|
--kt-outline: light-dark(#bcc0cc, #6c7086); /* overlay0 */
|
|
18
20
|
--kt-outline-strong: light-dark(#9ca0b0, #9399b2); /* overlay2 */
|
|
19
21
|
--kt-primary: light-dark(#4a0e94, #cba6f7); /* mauve assombri pour AAA */
|
|
@@ -47,7 +47,7 @@
|
|
|
47
47
|
/* ============ Socle (cyan/magenta sur quasi-noir) ============ */
|
|
48
48
|
--kt-surface: light-dark(#f0f8ff, #0b0f1a);
|
|
49
49
|
--kt-on-surface: light-dark(#04141a, #e6f6ff); /* ~15:1 */
|
|
50
|
-
--kt-muted: light-dark(#
|
|
50
|
+
--kt-muted: light-dark(#3d5468, #94b2c8); /* 7.3:1 (l'ancien #5a7a91 = 4.23:1, sous AA) / ~7:1 */
|
|
51
51
|
--kt-outline: light-dark(#9ec3d9, #2f5a73); /* 3:1 non-texte */
|
|
52
52
|
--kt-outline-strong: light-dark(#5fb6da, #5fb6da);
|
|
53
53
|
--kt-primary: light-dark(#003847, #28d6ef); /* cyan, texte ~10:1 */
|
|
@@ -28,6 +28,11 @@ interface KtSheetDragOptions {
|
|
|
28
28
|
* gère que le glissement. Le gating « écran compact uniquement » reste à l'appelant (signal `isCompact`
|
|
29
29
|
* de `KtViewport`) — la primitive est volontairement agnostique.
|
|
30
30
|
*
|
|
31
|
+
* @deprecated ADR-0005 — les sheets de la lib (Select compact, Dialog `sheet`) sont désormais des
|
|
32
|
+
* scrollers à snap : le drag-to-dismiss « attrapable partout » et l'arbitrage avec le scroll
|
|
33
|
+
* interne sont NATIFS ; cette primitive « poignée + translate » n'a plus de consommateur interne.
|
|
34
|
+
* Sera supprimée dans une prochaine version majeure.
|
|
35
|
+
*
|
|
31
36
|
* @param opts Élément à translater, callback de fermeture, classe de drag et seuil optionnel.
|
|
32
37
|
* @returns Un contrôleur {@link KtSheetDrag} (`start` à brancher sur `pointerdown`, `destroy` au teardown).
|
|
33
38
|
* @example
|
|
@@ -162,30 +162,14 @@ declare class KtDialogFocusInitial {
|
|
|
162
162
|
static ɵdir: i0.ɵɵDirectiveDeclaration<KtDialogFocusInitial, "[ktDialogFocusInitial]", never, {}, {}, never, never, true, never>;
|
|
163
163
|
}
|
|
164
164
|
/**
|
|
165
|
-
*
|
|
166
|
-
*
|
|
167
|
-
*
|
|
168
|
-
*
|
|
169
|
-
*
|
|
170
|
-
* présentation `sheet` / `centered-sheet`. Le drag n'est actif que si le dialog est EFFECTIVEMENT
|
|
171
|
-
* en mode sheet (la pane porte `kt-dialog--sheet`) — pas de dépendance au viewport : un `sheet`
|
|
172
|
-
* toujours-bottom-sheet se drague aussi à la souris.
|
|
173
|
-
*
|
|
174
|
-
* @example
|
|
175
|
-
* ```html
|
|
176
|
-
* <div ktDialogContent>
|
|
177
|
-
* <div ktDialogSheetHandle></div>
|
|
178
|
-
* …
|
|
179
|
-
* </div>
|
|
180
|
-
* ```
|
|
165
|
+
* @deprecated ADR-0005 — la poignée est désormais RENDUE AUTOMATIQUEMENT par `KtDialogContainer`
|
|
166
|
+
* en présentation `sheet` (opt-out : panelClass additionnel `kt-dialog--no-handle`), et le
|
|
167
|
+
* drag-to-dismiss s'attrape sur TOUTE la surface de la sheet (scroll-snap natif). Cette
|
|
168
|
+
* directive est INERTE et son hôte est masqué (évite une double poignée) : retirez-la de vos
|
|
169
|
+
* templates. Sera supprimée dans une prochaine version majeure.
|
|
181
170
|
*/
|
|
182
171
|
declare class KtDialogSheetHandle {
|
|
183
|
-
private readonly dialogRef;
|
|
184
|
-
private readonly host;
|
|
185
|
-
private readonly destroyRef;
|
|
186
|
-
private readonly drag;
|
|
187
172
|
constructor();
|
|
188
|
-
protected onStart(event: PointerEvent): void;
|
|
189
173
|
static ɵfac: i0.ɵɵFactoryDeclaration<KtDialogSheetHandle, never>;
|
|
190
174
|
static ɵdir: i0.ɵɵDirectiveDeclaration<KtDialogSheetHandle, "[ktDialogSheetHandle]", never, {}, {}, never, never, true, never>;
|
|
191
175
|
}
|
|
@@ -357,7 +341,14 @@ declare class KtDialogContainer extends CdkDialogContainer {
|
|
|
357
341
|
private readonly elementRef;
|
|
358
342
|
private readonly host;
|
|
359
343
|
private readonly platformId;
|
|
344
|
+
private readonly destroyRef;
|
|
345
|
+
private readonly bodyScrollLock;
|
|
360
346
|
protected readonly isClosing: i0.WritableSignal<boolean>;
|
|
347
|
+
/** Armé quand l'ouverture a dépassé 50px : un repos à ~0 est alors forcément le snap « fermé ». */
|
|
348
|
+
private sheetArmed;
|
|
349
|
+
/** Fermeture réelle en attente du repos au snap « fermé » (sortie programmatique animée). */
|
|
350
|
+
private pendingSheetClose;
|
|
351
|
+
private sheetCloseTimer;
|
|
361
352
|
/** Premier id de la file `aria-labelledby` exposée par `CdkDialogContainer`. Le membre
|
|
362
353
|
`_ariaLabelledByQueue` est interne au CDK (préfixe `_`) : on l'encapsule ICI, gardé, pour que
|
|
363
354
|
le binding de template ne lise jamais l'interne directement. Si une montée du CDK retire ou
|
|
@@ -365,6 +356,25 @@ declare class KtDialogContainer extends CdkDialogContainer {
|
|
|
365
356
|
protected get ariaLabelledBy(): string | null;
|
|
366
357
|
constructor();
|
|
367
358
|
protected isSheet(): boolean;
|
|
359
|
+
/** Poignée décorative auto-rendue en présentation sheet. Opt-out : panelClass `kt-dialog--no-handle`. */
|
|
360
|
+
protected showSheetHandle(): boolean;
|
|
361
|
+
/** Tap sur le spacer (zone extérieure à la carte) = fermeture, façon backdrop. Le conteneur
|
|
362
|
+
captant désormais le tactile (pointer-events auto, requis pour le drag iOS), le clic ne
|
|
363
|
+
traverse plus vers le backdrop CDK : on porte donc ICI la fermeture au tap-extérieur, en
|
|
364
|
+
respectant `disableClose` (comme le faisait le backdropClick natif). Un drag n'émet pas de
|
|
365
|
+
`click` (le navigateur le supprime après un scroll) : seul un vrai tap ferme. */
|
|
366
|
+
protected onScrimClick(): void;
|
|
367
|
+
/** Sheet scroll-snap : écouteurs (détection du repos + garde molette) et scroll d'ENTRÉE
|
|
368
|
+
programmatique vers le snap « ouvert ». Appelé au premier rendu, en présentation sheet. */
|
|
369
|
+
private initSheetGesture;
|
|
370
|
+
private prefersReducedMotion;
|
|
371
|
+
/** Détection du snap « fermé » par position de scroll (ni scrollsnapchange ni scrollend — cf.
|
|
372
|
+
ADR-0005). Un repos à ~0 finalise la fermeture en attente, ou EST une fermeture par geste. */
|
|
373
|
+
private readonly onSheetScroll;
|
|
374
|
+
/** La molette ne ferme JAMAIS la sheet (pas de geste souris — ADR-0005) : seuls les scrollers
|
|
375
|
+
INTERNES peuvent consommer, dans leurs bornes (générique : un dialog peut imbriquer
|
|
376
|
+
plusieurs zones scrollables). */
|
|
377
|
+
private readonly onSheetWheel;
|
|
368
378
|
private animateAndClose;
|
|
369
379
|
static ɵfac: i0.ɵɵFactoryDeclaration<KtDialogContainer, never>;
|
|
370
380
|
static ɵcmp: i0.ɵɵComponentDeclaration<KtDialogContainer, "kt-dialog-container", never, {}, {}, never, never, true, never>;
|
|
@@ -998,6 +998,11 @@ declare abstract class KtBaseSelect<T, V = T> {
|
|
|
998
998
|
readonly hideLabel: _angular_core.InputSignalWithTransform<boolean, unknown>;
|
|
999
999
|
/** Masquer visuellement le bloc d'erreur. @default KT_FIELD_CONFIG.hideErrors ?? false */
|
|
1000
1000
|
readonly hideErrors: _angular_core.InputSignalWithTransform<boolean, unknown>;
|
|
1001
|
+
/** Bouton « effacer » (×) sur le champ quand une valeur est sélectionnée (même contrat que
|
|
1002
|
+
`clearable` de BaseInputField ; single vide la sélection, multi vide toute la sélection). @default false */
|
|
1003
|
+
readonly clearable: _angular_core.InputSignalWithTransform<boolean, unknown>;
|
|
1004
|
+
/** Libellé i18n du bouton « effacer ». @default 'Clear' (ou KT_FIELD_CONFIG.clearLabel) */
|
|
1005
|
+
readonly clearLabel: _angular_core.InputSignal<string>;
|
|
1001
1006
|
/** Affiche un champ de recherche en tête du popup (desktop) / de la sheet (téléphone).
|
|
1002
1007
|
Pour les listes longues ; le texte tapé ne sert qu'à filtrer (réinitialisé à la fermeture). @default false */
|
|
1003
1008
|
readonly filterable: _angular_core.InputSignalWithTransform<boolean, unknown>;
|
|
@@ -1098,11 +1103,27 @@ declare abstract class KtBaseSelect<T, V = T> {
|
|
|
1098
1103
|
protected refocusTriggerAfterFilterClose(): void;
|
|
1099
1104
|
/** Fermeture synchrone du Popover (l'effect, différé, ne re-cachera pas : flag popoverShown). */
|
|
1100
1105
|
protected closePopupNow(): void;
|
|
1101
|
-
private
|
|
1102
|
-
|
|
1106
|
+
private sheetEl;
|
|
1107
|
+
private sheetState;
|
|
1108
|
+
/** Armé quand l'ouverture a dépassé 50px : un repos à ~0 est alors forcément le snap « fermé »
|
|
1109
|
+
(et non la position initiale) — même logique que le prototype du spike. */
|
|
1110
|
+
private sheetArmed;
|
|
1111
|
+
private sheetCloseTimer;
|
|
1112
|
+
private resetSheetState;
|
|
1113
|
+
private prefersReducedMotion;
|
|
1114
|
+
/** Entrée de la sheet : position « fermée » puis scroll animé vers le snap « ouvert ». */
|
|
1115
|
+
private openSheetByScroll;
|
|
1116
|
+
/** Détection du snap « fermé » par position de scroll (ni scrollsnapchange ni scrollend :
|
|
1117
|
+
non interopérables — cf. ADR-0005). Un geste de l'utilisateur qui amène la sheet au repos
|
|
1118
|
+
à 0 EST la fermeture ; les fermetures programmatiques y convergent aussi. */
|
|
1119
|
+
private readonly onSheetScroll;
|
|
1120
|
+
/** La molette ne ferme JAMAIS la sheet (pas de geste souris — ADR-0005) : seule la listbox
|
|
1121
|
+
peut consommer, dans les limites de son propre défilement. */
|
|
1122
|
+
private readonly onSheetWheel;
|
|
1123
|
+
private finalizeSheetClose;
|
|
1103
1124
|
private animateAndCloseSelect;
|
|
1104
1125
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<KtBaseSelect<any, any>, never>;
|
|
1105
|
-
static ɵdir: _angular_core.ɵɵDirectiveDeclaration<KtBaseSelect<any, any>, never, never, { "options": { "alias": "options"; "required": true; "isSignal": true; }; "optionLabel": { "alias": "optionLabel"; "required": false; "isSignal": true; }; "optionValue": { "alias": "optionValue"; "required": false; "isSignal": true; }; "optionDisabled": { "alias": "optionDisabled"; "required": false; "isSignal": true; }; "compareWith": { "alias": "compareWith"; "required": false; "isSignal": true; }; "touched": { "alias": "touched"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "readonly": { "alias": "readonly"; "required": false; "isSignal": true; }; "invalid": { "alias": "invalid"; "required": false; "isSignal": true; }; "required": { "alias": "required"; "required": false; "isSignal": true; }; "dirty": { "alias": "dirty"; "required": false; "isSignal": true; }; "pending": { "alias": "pending"; "required": false; "isSignal": true; }; "errors": { "alias": "errors"; "required": false; "isSignal": true; }; "name": { "alias": "name"; "required": false; "isSignal": true; }; "id": { "alias": "id"; "required": false; "isSignal": true; }; "label": { "alias": "label"; "required": false; "isSignal": true; }; "hint": { "alias": "hint"; "required": false; "isSignal": true; }; "helpText": { "alias": "helpText"; "required": false; "isSignal": true; }; "helpLabel": { "alias": "helpLabel"; "required": false; "isSignal": true; }; "customDescribedBy": { "alias": "customDescribedBy"; "required": false; "isSignal": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "errorMatcher": { "alias": "errorMatcher"; "required": false; "isSignal": true; }; "appearance": { "alias": "appearance"; "required": false; "isSignal": true; }; "floatLabel": { "alias": "floatLabel"; "required": false; "isSignal": true; }; "hideLabel": { "alias": "hideLabel"; "required": false; "isSignal": true; }; "hideErrors": { "alias": "hideErrors"; "required": false; "isSignal": true; }; "filterable": { "alias": "filterable"; "required": false; "isSignal": true; }; "filterPlaceholder": { "alias": "filterPlaceholder"; "required": false; "isSignal": true; }; "filterLabel": { "alias": "filterLabel"; "required": false; "isSignal": true; }; "filterFn": { "alias": "filterFn"; "required": false; "isSignal": true; }; "maxVisibleOptions": { "alias": "maxVisibleOptions"; "required": false; "isSignal": true; }; "truncatedResultsText": { "alias": "truncatedResultsText"; "required": false; "isSignal": true; }; "truncatedResultsAnnouncement": { "alias": "truncatedResultsAnnouncement"; "required": false; "isSignal": true; }; }, { "helpClick": "helpClick"; "touched": "touchedChange"; }, never, never, true, never>;
|
|
1126
|
+
static ɵdir: _angular_core.ɵɵDirectiveDeclaration<KtBaseSelect<any, any>, never, never, { "options": { "alias": "options"; "required": true; "isSignal": true; }; "optionLabel": { "alias": "optionLabel"; "required": false; "isSignal": true; }; "optionValue": { "alias": "optionValue"; "required": false; "isSignal": true; }; "optionDisabled": { "alias": "optionDisabled"; "required": false; "isSignal": true; }; "compareWith": { "alias": "compareWith"; "required": false; "isSignal": true; }; "touched": { "alias": "touched"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "readonly": { "alias": "readonly"; "required": false; "isSignal": true; }; "invalid": { "alias": "invalid"; "required": false; "isSignal": true; }; "required": { "alias": "required"; "required": false; "isSignal": true; }; "dirty": { "alias": "dirty"; "required": false; "isSignal": true; }; "pending": { "alias": "pending"; "required": false; "isSignal": true; }; "errors": { "alias": "errors"; "required": false; "isSignal": true; }; "name": { "alias": "name"; "required": false; "isSignal": true; }; "id": { "alias": "id"; "required": false; "isSignal": true; }; "label": { "alias": "label"; "required": false; "isSignal": true; }; "hint": { "alias": "hint"; "required": false; "isSignal": true; }; "helpText": { "alias": "helpText"; "required": false; "isSignal": true; }; "helpLabel": { "alias": "helpLabel"; "required": false; "isSignal": true; }; "customDescribedBy": { "alias": "customDescribedBy"; "required": false; "isSignal": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "errorMatcher": { "alias": "errorMatcher"; "required": false; "isSignal": true; }; "appearance": { "alias": "appearance"; "required": false; "isSignal": true; }; "floatLabel": { "alias": "floatLabel"; "required": false; "isSignal": true; }; "hideLabel": { "alias": "hideLabel"; "required": false; "isSignal": true; }; "hideErrors": { "alias": "hideErrors"; "required": false; "isSignal": true; }; "clearable": { "alias": "clearable"; "required": false; "isSignal": true; }; "clearLabel": { "alias": "clearLabel"; "required": false; "isSignal": true; }; "filterable": { "alias": "filterable"; "required": false; "isSignal": true; }; "filterPlaceholder": { "alias": "filterPlaceholder"; "required": false; "isSignal": true; }; "filterLabel": { "alias": "filterLabel"; "required": false; "isSignal": true; }; "filterFn": { "alias": "filterFn"; "required": false; "isSignal": true; }; "maxVisibleOptions": { "alias": "maxVisibleOptions"; "required": false; "isSignal": true; }; "truncatedResultsText": { "alias": "truncatedResultsText"; "required": false; "isSignal": true; }; "truncatedResultsAnnouncement": { "alias": "truncatedResultsAnnouncement"; "required": false; "isSignal": true; }; }, { "helpClick": "helpClick"; "touched": "touchedChange"; }, never, never, true, never>;
|
|
1106
1127
|
}
|
|
1107
1128
|
|
|
1108
1129
|
/** Contexte typé reçu par le template d'une option (`ktSelectOption`). */
|
|
@@ -1191,6 +1212,10 @@ declare class KtSelect<T, V = T> extends KtBaseSelect<T, V> implements FormValue
|
|
|
1191
1212
|
protected readonly triggerDef: _angular_core.Signal<KtSelectTriggerDef<any> | undefined>;
|
|
1192
1213
|
/** Fermer le popup après une sélection (sémantique single ; le multi reste ouvert). */
|
|
1193
1214
|
private readonly closeOnSelect;
|
|
1215
|
+
/** Affiche le bouton « effacer » (×) sur le champ dès qu'une valeur est présente (`clearable`).
|
|
1216
|
+
Basé sur `value()` et non `selectedOption()` : une clé orpheline (option retirée des données)
|
|
1217
|
+
reste effaçable. */
|
|
1218
|
+
protected readonly showClear: _angular_core.Signal<boolean>;
|
|
1194
1219
|
/** Option correspondant à la valeur courante (clé extraite, ou objet si `optionValue` est omis). */
|
|
1195
1220
|
protected readonly selectedOption: _angular_core.Signal<T | null>;
|
|
1196
1221
|
/** Valeur du listbox : tableau de clés (0 ou 1 élément en single). */
|
|
@@ -1199,6 +1224,8 @@ declare class KtSelect<T, V = T> extends KtBaseSelect<T, V> implements FormValue
|
|
|
1199
1224
|
/** La sélection courante est-elle masquée par le filtre ou la troncation ? (≠ retirée des données). */
|
|
1200
1225
|
private isSelectionFilteredOut;
|
|
1201
1226
|
private commitSelection;
|
|
1227
|
+
/** Efface la sélection depuis le champ (bouton `clearable`) et rend le focus au trigger. */
|
|
1228
|
+
protected clearSelection(): void;
|
|
1202
1229
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<KtSelect<any, any>, never>;
|
|
1203
1230
|
static ɵcmp: _angular_core.ɵɵComponentDeclaration<KtSelect<any, any>, "kt-select", never, { "value": { "alias": "value"; "required": false; "isSignal": true; }; }, { "value": "valueChange"; "selectionChange": "selectionChange"; }, ["optionDef", "triggerDef"], ["[ktFieldHelp]"], true, never>;
|
|
1204
1231
|
}
|
|
@@ -1390,10 +1417,6 @@ declare class KtMultiSelect<T, V = T> extends KtBaseSelect<T, V> implements Form
|
|
|
1390
1417
|
/** Émis à chaque (dé)sélection. Payload : `{ value, options }` — `value` le tableau des valeurs émises
|
|
1391
1418
|
(clés ou objets), `options` les objets options correspondants, dans l'ordre de sélection. */
|
|
1392
1419
|
readonly selectionChange: _angular_core.OutputEmitterRef<KtMultiSelectSelectionChange<T, V>>;
|
|
1393
|
-
/** Bouton « tout effacer » sur le champ (même contrat que `clearable` de BaseInputField). @default false */
|
|
1394
|
-
readonly clearable: _angular_core.InputSignalWithTransform<boolean, unknown>;
|
|
1395
|
-
/** Libellé i18n du bouton « tout effacer ». @default 'Clear' (ou KT_FIELD_CONFIG.clearLabel) */
|
|
1396
|
-
readonly clearLabel: _angular_core.InputSignal<string>;
|
|
1397
1420
|
/** Barre « Tout sélectionner / Tout effacer » en tête du popup (bascule le popup en panneau dialog). */
|
|
1398
1421
|
readonly selectionActions: _angular_core.InputSignalWithTransform<boolean, unknown>;
|
|
1399
1422
|
/** Nombre maximal de chips affichés avant repli derrière un bouton « +N more ». Défaut : illimité. */
|
|
@@ -1454,7 +1477,7 @@ declare class KtMultiSelect<T, V = T> extends KtBaseSelect<T, V> implements Form
|
|
|
1454
1477
|
/** Annonce immédiate (action ponctuelle, pas de débounce) du total sélectionné. */
|
|
1455
1478
|
private announceSelectionCount;
|
|
1456
1479
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<KtMultiSelect<any, any>, never>;
|
|
1457
|
-
static ɵcmp: _angular_core.ɵɵComponentDeclaration<KtMultiSelect<any, any>, "kt-multi-select", never, { "value": { "alias": "value"; "required": false; "isSignal": true; }; "
|
|
1480
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<KtMultiSelect<any, any>, "kt-multi-select", never, { "value": { "alias": "value"; "required": false; "isSignal": true; }; "selectionActions": { "alias": "selectionActions"; "required": false; "isSignal": true; }; "maxVisibleChips": { "alias": "maxVisibleChips"; "required": false; "isSignal": true; }; }, { "value": "valueChange"; "selectionChange": "selectionChange"; }, ["optionDef", "triggerDef", "chipDef"], ["[ktFieldHelp]"], true, never>;
|
|
1458
1481
|
}
|
|
1459
1482
|
|
|
1460
1483
|
/** Portée de transition des chips. Fourni par `ChipList` (via `useExisting`) ; injecté en
|
|
@@ -1718,12 +1741,30 @@ declare class KtChipList<T> implements ChipTransitionScope {
|
|
|
1718
1741
|
Public : permet au parent d'annoncer des actions liées (ex. « tout effacer »). */
|
|
1719
1742
|
announce(text: string): void;
|
|
1720
1743
|
private activeTransition;
|
|
1744
|
+
/**
|
|
1745
|
+
* Vrai sur le moteur WebKit (Safari desktop + TOUS les navigateurs iOS, qui embarquent WebKit).
|
|
1746
|
+
*
|
|
1747
|
+
* Contournement DOCUMENTÉ et RÉVERSIBLE d'un bug de compositing des View Transitions au niveau
|
|
1748
|
+
* document sur WebKit : après la transition, les chips (hôtes d'éléments custom dont le
|
|
1749
|
+
* `view-transition-name` est posé puis retiré dynamiquement) ne se repeignent pas — seules les
|
|
1750
|
+
* croix « retirer » (boutons natifs, compositées sur une couche distincte) subsistent à l'écran.
|
|
1751
|
+
* Touche aussi bien le retrait que le déplier/replier : les deux passent par ce wrapper.
|
|
1752
|
+
*
|
|
1753
|
+
* Le défaut n'est PAS feature-detectable : `startViewTransition` répond présente puis rate le
|
|
1754
|
+
* rendu final, d'où la détection de MOTEUR. `navigator.vendor` est gelé pour compat — vaut
|
|
1755
|
+
* « Apple Computer, Inc. » sur WebKit UNIQUEMENT (Blink = « Google Inc. », Gecko = « »). On NE
|
|
1756
|
+
* gate PAS sur l'absence de la variante scopée `element.startViewTransition` : cela exclurait
|
|
1757
|
+
* Firefox à tort (transition document parfaitement rendue chez lui). À RETIRER quand Safari
|
|
1758
|
+
* corrigera le compositing.
|
|
1759
|
+
*/
|
|
1760
|
+
private isWebKitEngine;
|
|
1721
1761
|
/** Exécute `action` dans une View Transition (morph des chips qui se déplacent, entrée/sortie
|
|
1722
1762
|
stylées via `::view-transition-*(.chip-transition)` — cf. tokens.css). Transition SCOPÉE à
|
|
1723
1763
|
l'élément quand le navigateur le permet (`element.startViewTransition`, Chrome 147+) ; sinon
|
|
1724
1764
|
transition document — dans les deux cas, seuls les chips de CETTE liste sont nommés (cf.
|
|
1725
|
-
`transitioning`). Fallback : action directe
|
|
1726
|
-
préfère moins de mouvement
|
|
1765
|
+
`transitioning`). Fallback : action directe (retrait/dépli instantané, état final garanti
|
|
1766
|
+
correct) si l'API est absente, si l'utilisateur préfère moins de mouvement, ou sur WebKit
|
|
1767
|
+
(bug de compositing, cf. `isWebKitEngine`). */
|
|
1727
1768
|
private withViewTransition;
|
|
1728
1769
|
/** Retrait demandé : annonce, émet vers le parent (qui met à jour `items`), puis focus
|
|
1729
1770
|
le chip suivant — sinon `emptyFocusTarget` (le bouton focusé disparaît du DOM). */
|