@ktortu/aaa 0.9.0 → 0.9.1
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 +5 -3
- package/fesm2022/ktortu-aaa-cdk.mjs +1 -0
- package/fesm2022/ktortu-aaa-cdk.mjs.map +1 -1
- package/fesm2022/ktortu-aaa-dialog.mjs +69 -16
- package/fesm2022/ktortu-aaa-dialog.mjs.map +1 -1
- package/fesm2022/ktortu-aaa-forms.mjs +328 -69
- package/fesm2022/ktortu-aaa-forms.mjs.map +1 -1
- package/fesm2022/ktortu-aaa-i18n.mjs +27 -2
- package/fesm2022/ktortu-aaa-i18n.mjs.map +1 -1
- package/fesm2022/ktortu-aaa-menu.mjs.map +1 -1
- package/fesm2022/ktortu-aaa-snackbar.mjs +465 -0
- package/fesm2022/ktortu-aaa-snackbar.mjs.map +1 -0
- package/fesm2022/ktortu-aaa-tabs.mjs.map +1 -1
- package/fesm2022/ktortu-aaa.mjs +1 -0
- package/fesm2022/ktortu-aaa.mjs.map +1 -1
- package/forms/checkbox/checkbox-group.css +0 -8
- package/forms/chips/chip-list.css +5 -0
- package/forms/radio/radio-group.css +1 -9
- package/forms/styles/field-box.css +3 -1
- package/forms/styles/field-pending.css +46 -0
- package/forms/styles/select-panel.css +4 -0
- package/package.json +5 -1
- package/snackbar/snackbar-tokens.css +53 -0
- package/snackbar/snackbar.css +175 -0
- package/styles/forms.css +1 -0
- package/styles/snackbar.css +9 -0
- package/styles/styles.css +1 -0
- package/types/ktortu-aaa-dialog.d.ts +89 -27
- package/types/ktortu-aaa-forms.d.ts +180 -24
- package/types/ktortu-aaa-i18n.d.ts +3 -0
- package/types/ktortu-aaa-snackbar.d.ts +275 -0
- package/types/ktortu-aaa.d.ts +1 -0
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { InjectionToken, inject, computed, ElementRef, Directive, input, output, booleanAttribute, contentChild, viewChild, forwardRef, ChangeDetectionStrategy, Component, model, TemplateRef, afterNextRender, isDevMode, effect, NgZone, PLATFORM_ID, DestroyRef, signal, untracked, Injector, ChangeDetectorRef, viewChildren,
|
|
2
|
+
import { InjectionToken, inject, computed, ElementRef, Directive, input, output, booleanAttribute, contentChild, viewChild, forwardRef, ChangeDetectionStrategy, Component, Injectable, model, TemplateRef, afterNextRender, isDevMode, effect, NgZone, PLATFORM_ID, DestroyRef, signal, untracked, Injector, ChangeDetectorRef, viewChildren, LOCALE_ID, Pipe } from '@angular/core';
|
|
3
3
|
import { KtTooltip } from '@ktortu/aaa/tooltip';
|
|
4
4
|
import { KtIdGenerator, KtViewport, createKtSheetDrag } from '@ktortu/aaa/cdk';
|
|
5
5
|
import { NgTemplateOutlet, DOCUMENT, isPlatformBrowser } from '@angular/common';
|
|
@@ -11,15 +11,33 @@ import { Combobox, ComboboxPopup, ComboboxWidget } from '@angular/aria/combobox'
|
|
|
11
11
|
const defaultKtFieldErrorMatcher = (state) => state.invalid && state.touched;
|
|
12
12
|
const KT_FIELD_CONFIG = new InjectionToken('KT_FIELD_CONFIG');
|
|
13
13
|
/**
|
|
14
|
-
* Fournit des défauts de champ (apparence, libellés, matcher d'erreurs
|
|
15
|
-
* l'application entière. Idéal pour une transition globale — ex. tout
|
|
16
|
-
* Material en un seul provider.
|
|
14
|
+
* Fournit des défauts de champ (apparence, libellés, matcher d'erreurs, messages d'erreur par
|
|
15
|
+
* défaut…) pour un sous-arbre ou l'application entière. Idéal pour une transition globale — ex. tout
|
|
16
|
+
* passer en `outline` façon Material en un seul provider.
|
|
17
17
|
*
|
|
18
18
|
* @example
|
|
19
19
|
* ```ts
|
|
20
|
-
* // app.config.ts
|
|
20
|
+
* // app.config.ts — apparence globale
|
|
21
21
|
* providers: [provideKtField({ appearance: 'outline' })]
|
|
22
22
|
* ```
|
|
23
|
+
*
|
|
24
|
+
* @example
|
|
25
|
+
* ```ts
|
|
26
|
+
* // Surcharger des messages d'erreur par défaut (fusionnés par-dessus les défauts anglais).
|
|
27
|
+
* // Une fabrique reçoit l'erreur complète : ses params typés sont lisibles via `ktErrorParam`.
|
|
28
|
+
* providers: [
|
|
29
|
+
* provideKtField({
|
|
30
|
+
* errorMessages: {
|
|
31
|
+
* required: 'Champ obligatoire.',
|
|
32
|
+
* minLength: (e) => `Au moins ${ktErrorParam<number>(e, 'minLength')} caractères.`,
|
|
33
|
+
* pattern: '', // '' supprime le texte de ce kind : champ rouge, sans message
|
|
34
|
+
* },
|
|
35
|
+
* }),
|
|
36
|
+
* ]
|
|
37
|
+
* ```
|
|
38
|
+
*
|
|
39
|
+
* @remarks Pour passer toute la lib en français d'un coup (libellés + messages d'erreur), préférez
|
|
40
|
+
* `provideKtDefaultFR()` (paquet `@ktortu/aaa/i18n`), qui fournit déjà un dictionnaire complet.
|
|
23
41
|
*/
|
|
24
42
|
function provideKtField(config) {
|
|
25
43
|
return { provide: KT_FIELD_CONFIG, useValue: config };
|
|
@@ -48,14 +66,16 @@ class KtFieldControl {
|
|
|
48
66
|
/** Élément DOM hôte du contrôle (exposé pour le focus / la mesure par le parent). */
|
|
49
67
|
element = inject(ElementRef).nativeElement;
|
|
50
68
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.1", ngImport: i0, type: KtFieldControl, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
51
|
-
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.0.1", type: KtFieldControl, isStandalone: true, selector: "[ktFieldControl]", host: { properties: { "id": "id()", "attr.aria-describedby": "describedBy()", "attr.aria-invalid": "invalid() ? \"true\" : null", "attr.aria-required": "required() ? \"true\" : null" } }, ngImport: i0 });
|
|
69
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.0.1", type: KtFieldControl, isStandalone: true, selector: "[ktFieldControl]", host: { properties: { "attr.id": "id()", "attr.aria-describedby": "describedBy()", "attr.aria-invalid": "invalid() ? \"true\" : null", "attr.aria-required": "required() ? \"true\" : null" } }, ngImport: i0 });
|
|
52
70
|
}
|
|
53
71
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.1", ngImport: i0, type: KtFieldControl, decorators: [{
|
|
54
72
|
type: Directive,
|
|
55
73
|
args: [{
|
|
56
74
|
selector: '[ktFieldControl]',
|
|
57
75
|
host: {
|
|
58
|
-
|
|
76
|
+
// `[attr.id]` (et non `[id]`) : quand le contrôle est orphelin (pas de parent KtField), `id()`
|
|
77
|
+
// vaut null et l'attribut doit DISPARAÎTRE — un binding de propriété poserait `id="null"`.
|
|
78
|
+
'[attr.id]': 'id()',
|
|
59
79
|
'[attr.aria-describedby]': 'describedBy()',
|
|
60
80
|
'[attr.aria-invalid]': 'invalid() ? "true" : null',
|
|
61
81
|
'[attr.aria-required]': 'required() ? "true" : null',
|
|
@@ -182,6 +202,89 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.1", ngImpor
|
|
|
182
202
|
}, providers: [{ provide: KT_FIELD, useExisting: forwardRef(() => KtField) }], template: "<div class=\"kt-field__header\">\n @if (label(); as labelText) {\n <label class=\"kt-field__label\" [id]=\"labelId()\" [for]=\"baseId()\">\n {{ labelText }}\n @if (required()) {\n <span class=\"kt-field__required\" aria-hidden=\"true\">*</span>\n }\n </label>\n }\n\n @if (helpText(); as help) {\n <button\n type=\"button\"\n class=\"kt-field__help\"\n [ktTooltip]=\"help\"\n [attr.aria-label]=\"helpLabel()\"\n [attr.aria-describedby]=\"null\"\n (click)=\"onHelpClick($event)\"\n >\n <span class=\"kt-field__help-icon\" aria-hidden=\"true\">help</span>\n </button>\n }\n\n <ng-content select=\"[ktFieldHelp]\" />\n</div>\n\n<div class=\"kt-field__control\">\n <ng-content />\n</div>\n\n@if (showHint()) {\n <p class=\"kt-field__hint\" [id]=\"hintId()\">{{ hint() }}</p>\n}\n\n<!-- R\u00E9gion live toujours pr\u00E9sente : les AT annoncent l'erreur d\u00E8s son apparition. -->\n<p class=\"kt-field__error\" [id]=\"errorId()\" aria-live=\"polite\">\n @if (hasError()) {\n @for (error of displayedErrors(); track $index) {\n <span class=\"kt-field__error-message\">{{ error.message }}</span>\n }\n }\n</p>\n", styles: ["@layer kt-aaa.components{:host{display:flex;flex-direction:column;gap:var(--field-gap, .375rem);font-size:var(--field-font-size, 1rem);color:var(--field-color, inherit)}.kt-field__header{display:flex;align-items:center;gap:.375rem}.kt-field__label{font-size:var(--field-label-font-size, .875rem);font-weight:var(--field-label-weight, 500);text-transform:var(--field-label-transform, none);letter-spacing:var(--field-label-letter-spacing, normal);color:var(--field-label-color, inherit)}.kt-field__help{display:inline-flex;align-items:center;justify-content:center;padding:0;border:0;background:transparent;color:var(--field-icon-color, #474747);cursor:pointer;position:relative}.kt-field__help:after{content:\"\";position:absolute;inset:-12px}.kt-field__help-icon{font-family:Material Symbols Outlined;font-size:1.25rem;line-height:1;font-feature-settings:\"liga\";-webkit-font-smoothing:antialiased}.kt-field__required{margin-inline-start:.125rem;color:var(--field-required-color, #8c1d18)}.kt-field__hint{margin:0;font-size:var(--field-hint-font-size, .8125rem);color:var(--field-hint-color, #474747)}.kt-field__error{margin:0;display:flex;flex-direction:column;font-size:var(--field-hint-font-size, .8125rem);color:var(--field-error-color, #8c1d18)}.kt-field__error-message{animation:var(--field-error-animation, none)}@media(prefers-reduced-motion:reduce){.kt-field__error-message{animation:none}}}\n"] }]
|
|
183
203
|
}], propDecorators: { label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], hint: [{ type: i0.Input, args: [{ isSignal: true, alias: "hint", required: false }] }], helpText: [{ type: i0.Input, args: [{ isSignal: true, alias: "helpText", required: false }] }], helpLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "helpLabel", required: false }] }], customDescribedBy: [{ type: i0.Input, args: [{ isSignal: true, alias: "customDescribedBy", required: false }] }], helpClick: [{ type: i0.Output, args: ["helpClick"] }], errors: [{ type: i0.Input, args: [{ isSignal: true, alias: "errors", required: false }] }], invalid: [{ type: i0.Input, args: [{ isSignal: true, alias: "invalid", required: false }] }], required: [{ type: i0.Input, args: [{ isSignal: true, alias: "required", required: false }] }], fieldId: [{ type: i0.Input, args: [{ isSignal: true, alias: "fieldId", required: false }] }], hideHintWhenInvalid: [{ type: i0.Input, args: [{ isSignal: true, alias: "hideHintWhenInvalid", required: false }] }], showAllErrors: [{ type: i0.Input, args: [{ isSignal: true, alias: "showAllErrors", required: false }] }], appearance: [{ type: i0.Input, args: [{ isSignal: true, alias: "appearance", required: false }] }], floatLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "floatLabel", required: false }] }], control: [{ type: i0.ContentChild, args: [i0.forwardRef(() => KtFieldControl), { isSignal: true }] }], templateTooltip: [{ type: i0.ViewChild, args: [i0.forwardRef(() => KtTooltip), { isSignal: true }] }], projectedTooltip: [{ type: i0.ContentChild, args: [i0.forwardRef(() => KtTooltip), { ...{ descendants: true }, isSignal: true }] }] } });
|
|
184
204
|
|
|
205
|
+
/**
|
|
206
|
+
* Lit un param typé d'une `ValidationError` (ex. `min`, `minLength`, `maxLength`, `minDate`…).
|
|
207
|
+
* Les sous-types d'erreur de Signal Forms exposent ces params, mais le type de base `ValidationError`
|
|
208
|
+
* ne les déclare pas : ce helper centralise l'accès pour les fabriques de message, sans `any`.
|
|
209
|
+
*
|
|
210
|
+
* @example
|
|
211
|
+
* ```ts
|
|
212
|
+
* minLength: (e) => `Au moins ${ktErrorParam<number>(e, 'minLength')} caractères.`
|
|
213
|
+
* ```
|
|
214
|
+
*/
|
|
215
|
+
function ktErrorParam(error, key) {
|
|
216
|
+
return error[key];
|
|
217
|
+
}
|
|
218
|
+
/**
|
|
219
|
+
* Messages d'erreur **anglais** par défaut de la lib, indexés par `kind`. Couvrent tous les
|
|
220
|
+
* validateurs natifs de Signal Forms (`required`, `email`, `min`, `max`, `minLength`, `maxLength`,
|
|
221
|
+
* `minDate`, `maxDate`, `pattern`). Surchargeables famille par famille via `KT_FIELD_CONFIG.errorMessages`
|
|
222
|
+
* (ou globalement par langue, cf. `provideKtDefaultFR`). Le `numberParseError` reste géré à la source
|
|
223
|
+
* par `kt-number-field` (kind `parse`).
|
|
224
|
+
*/
|
|
225
|
+
const KT_DEFAULT_FIELD_ERROR_MESSAGES = {
|
|
226
|
+
required: 'This field is required.',
|
|
227
|
+
email: 'Enter a valid email address.',
|
|
228
|
+
min: (e) => `Enter a value greater than or equal to ${ktErrorParam(e, 'min')}.`,
|
|
229
|
+
max: (e) => `Enter a value less than or equal to ${ktErrorParam(e, 'max')}.`,
|
|
230
|
+
minLength: (e) => `Enter at least ${ktErrorParam(e, 'minLength')} characters.`,
|
|
231
|
+
maxLength: (e) => `Enter at most ${ktErrorParam(e, 'maxLength')} characters.`,
|
|
232
|
+
minDate: (e) => `Choose a date on or after ${ktErrorParam(e, 'minDate').toLocaleDateString()}.`,
|
|
233
|
+
maxDate: (e) => `Choose a date on or before ${ktErrorParam(e, 'maxDate').toLocaleDateString()}.`,
|
|
234
|
+
pattern: 'The value is not in the expected format.',
|
|
235
|
+
};
|
|
236
|
+
/**
|
|
237
|
+
* Résout le **message par défaut** d'une erreur de validation à partir de son `kind` (et de ses
|
|
238
|
+
* params typés), en fusionnant les défauts anglais embarqués avec les surcharges du `KT_FIELD_CONFIG`.
|
|
239
|
+
*
|
|
240
|
+
* Utilisé par chaque contrôle `kt-*` au moment du rendu, là où la `ValidationError` complète (params)
|
|
241
|
+
* est encore disponible — `kt-field` reste agnostique de Signal Forms. Précédence du texte affiché :
|
|
242
|
+
* `message` du validateur > `KT_FIELD_CONFIG.errorMessages[kind]` > défaut anglais > rien.
|
|
243
|
+
*
|
|
244
|
+
* Injectable racine : un seul résolveur partagé par tous les champs.
|
|
245
|
+
*/
|
|
246
|
+
// Stryker disable next-line all: `providedIn` doit rester statiquement analysable par l'AOT Angular
|
|
247
|
+
// (NG1010) ; aucune logique à muter dans le décorateur.
|
|
248
|
+
class KtFieldErrorResolver {
|
|
249
|
+
config = inject(KT_FIELD_CONFIG, { optional: true });
|
|
250
|
+
/** Map effective : défauts anglais + surcharges du `KT_FIELD_CONFIG`, par `kind`. */
|
|
251
|
+
messages = {
|
|
252
|
+
...KT_DEFAULT_FIELD_ERROR_MESSAGES,
|
|
253
|
+
...this.config?.errorMessages,
|
|
254
|
+
};
|
|
255
|
+
/**
|
|
256
|
+
* Message par défaut d'une erreur (selon son `kind` + params), ou `undefined` si aucun défaut
|
|
257
|
+
* n'est connu pour ce `kind` (l'UI n'affiche alors rien).
|
|
258
|
+
*/
|
|
259
|
+
resolve(error) {
|
|
260
|
+
const entry = this.messages[error.kind];
|
|
261
|
+
if (entry === undefined)
|
|
262
|
+
return undefined;
|
|
263
|
+
return typeof entry === 'function' ? entry(error) : entry;
|
|
264
|
+
}
|
|
265
|
+
/**
|
|
266
|
+
* Prépare une liste d'erreurs pour l'affichage : applique la précédence (message du validateur
|
|
267
|
+
* sinon défaut résolu) et **écarte les erreurs au message vide** — suppression explicite via
|
|
268
|
+
* `{ message: '' }`. Le champ reste invalide (rouge / `aria-invalid`), simplement sans texte.
|
|
269
|
+
*/
|
|
270
|
+
resolveAll(errors) {
|
|
271
|
+
const resolved = [];
|
|
272
|
+
for (const error of errors) {
|
|
273
|
+
const message = error.message ?? this.resolve(error);
|
|
274
|
+
if (message === undefined || message.trim() === '')
|
|
275
|
+
continue;
|
|
276
|
+
resolved.push({ kind: error.kind, message });
|
|
277
|
+
}
|
|
278
|
+
return resolved;
|
|
279
|
+
}
|
|
280
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.1", ngImport: i0, type: KtFieldErrorResolver, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
281
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.1", ngImport: i0, type: KtFieldErrorResolver, providedIn: 'root' });
|
|
282
|
+
}
|
|
283
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.1", ngImport: i0, type: KtFieldErrorResolver, decorators: [{
|
|
284
|
+
type: Injectable,
|
|
285
|
+
args: [{ providedIn: 'root' }]
|
|
286
|
+
}] });
|
|
287
|
+
|
|
185
288
|
/** Base partagée des champs simples (TextField, NumberField) : état FormValueControl,
|
|
186
289
|
présentation (label/hint/prefix/suffix/clear) et politique d'affichage des erreurs.
|
|
187
290
|
La valeur, son parsing et la notion de « vide » sont fournis par la sous-classe.
|
|
@@ -199,6 +302,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.1", ngImpor
|
|
|
199
302
|
``` */
|
|
200
303
|
class KtBaseInputField {
|
|
201
304
|
config = inject(KT_FIELD_CONFIG, { optional: true });
|
|
305
|
+
errorResolver = inject(KtFieldErrorResolver);
|
|
202
306
|
// --- État poussé par [formField] ---
|
|
203
307
|
// Ces entrées sont généralement câblées par l'intégration Signal Forms (`[formField]`) ;
|
|
204
308
|
// tu peux aussi les piloter à la main en usage contrôlé.
|
|
@@ -215,6 +319,8 @@ class KtBaseInputField {
|
|
|
215
319
|
required = input(false, { ...(ngDevMode ? { debugName: "required" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
216
320
|
/** Le champ a-t-il été modifié depuis sa valeur initiale. @default false */
|
|
217
321
|
dirty = input(false, { ...(ngDevMode ? { debugName: "dirty" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
322
|
+
/** Validation asynchrone en cours (poussé par `[field]`) : pose `aria-busy` + `data-pending`. @default false */
|
|
323
|
+
pending = input(false, { ...(ngDevMode ? { debugName: "pending" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
218
324
|
/** Liste des erreurs de validation à afficher. @default [] */
|
|
219
325
|
errors = input([], /* @ts-ignore */
|
|
220
326
|
...(ngDevMode ? [{ debugName: "errors" }] : /* istanbul ignore next */ []));
|
|
@@ -282,6 +388,9 @@ class KtBaseInputField {
|
|
|
282
388
|
// L'erreur ne s'affiche qu'au déclenchement décidé par le matcher (invalid/touched/dirty).
|
|
283
389
|
showInvalid = computed(() => this.matcher()({ invalid: this.invalid(), touched: this.touched(), dirty: this.dirty() }), /* @ts-ignore */
|
|
284
390
|
...(ngDevMode ? [{ debugName: "showInvalid" }] : /* istanbul ignore next */ []));
|
|
391
|
+
/** Erreurs prêtes pour `kt-field` : messages par défaut résolus, suppressions (`message: ''`) écartées. */
|
|
392
|
+
displayErrors = computed(() => this.errorResolver.resolveAll(this.errors()), /* @ts-ignore */
|
|
393
|
+
...(ngDevMode ? [{ debugName: "displayErrors" }] : /* istanbul ignore next */ []));
|
|
285
394
|
showClear = computed(() => this.clearable() && !this.disabled() && !this.readonly() && !this.isEmpty(this.value()), /* @ts-ignore */
|
|
286
395
|
...(ngDevMode ? [{ debugName: "showClear" }] : /* istanbul ignore next */ []));
|
|
287
396
|
/** Apparence effective (input ?? config ?? 'fill'). Sert aux templates : forward à `kt-field` et,
|
|
@@ -318,17 +427,32 @@ class KtBaseInputField {
|
|
|
318
427
|
this.clear();
|
|
319
428
|
}
|
|
320
429
|
}
|
|
430
|
+
/** Focus le contrôle natif (utilisé par Signal Forms `focusBoundControl`). */
|
|
431
|
+
focus(options) {
|
|
432
|
+
this.inputRef()?.nativeElement.focus(options);
|
|
433
|
+
}
|
|
434
|
+
/** Ré-aligne le texte affiché sur la valeur courante (utilisé par Signal Forms `reset`). */
|
|
435
|
+
reset() {
|
|
436
|
+
const el = this.inputRef()?.nativeElement;
|
|
437
|
+
if (el)
|
|
438
|
+
el.value = this.displayValue();
|
|
439
|
+
}
|
|
440
|
+
/** Représentation texte de la valeur pour l'input natif. Surchargeable par sous-classe. */
|
|
441
|
+
displayValue() {
|
|
442
|
+
const v = this.value();
|
|
443
|
+
return v == null ? '' : String(v);
|
|
444
|
+
}
|
|
321
445
|
clear() {
|
|
322
446
|
this.value.set(this.emptyValue());
|
|
323
447
|
this.touched.set(true);
|
|
324
|
-
this.
|
|
448
|
+
this.focus();
|
|
325
449
|
}
|
|
326
450
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.1", ngImport: i0, type: KtBaseInputField, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
327
|
-
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.2.0", version: "22.0.1", type: KtBaseInputField, isStandalone: true, inputs: { touched: { classPropertyName: "touched", publicName: "touched", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, readonly: { classPropertyName: "readonly", publicName: "readonly", isSignal: true, isRequired: false, transformFunction: null }, invalid: { classPropertyName: "invalid", publicName: "invalid", isSignal: true, isRequired: false, transformFunction: null }, required: { classPropertyName: "required", publicName: "required", isSignal: true, isRequired: false, transformFunction: null }, dirty: { classPropertyName: "dirty", publicName: "dirty", isSignal: true, isRequired: false, transformFunction: null }, errors: { classPropertyName: "errors", publicName: "errors", isSignal: true, isRequired: false, transformFunction: null }, name: { classPropertyName: "name", publicName: "name", isSignal: true, isRequired: false, transformFunction: null }, id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, hint: { classPropertyName: "hint", publicName: "hint", isSignal: true, isRequired: false, transformFunction: null }, helpText: { classPropertyName: "helpText", publicName: "helpText", isSignal: true, isRequired: false, transformFunction: null }, helpLabel: { classPropertyName: "helpLabel", publicName: "helpLabel", isSignal: true, isRequired: false, transformFunction: null }, customDescribedBy: { classPropertyName: "customDescribedBy", publicName: "customDescribedBy", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, autocomplete: { classPropertyName: "autocomplete", publicName: "autocomplete", isSignal: true, isRequired: false, transformFunction: null }, icon: { classPropertyName: "icon", publicName: "icon", isSignal: true, isRequired: false, transformFunction: null }, clearable: { classPropertyName: "clearable", publicName: "clearable", isSignal: true, isRequired: false, transformFunction: null }, prefix: { classPropertyName: "prefix", publicName: "prefix", isSignal: true, isRequired: false, transformFunction: null }, suffix: { classPropertyName: "suffix", publicName: "suffix", isSignal: true, isRequired: false, transformFunction: null }, clearLabel: { classPropertyName: "clearLabel", publicName: "clearLabel", isSignal: true, isRequired: false, transformFunction: null }, errorMatcher: { classPropertyName: "errorMatcher", publicName: "errorMatcher", isSignal: true, isRequired: false, transformFunction: null }, appearance: { classPropertyName: "appearance", publicName: "appearance", isSignal: true, isRequired: false, transformFunction: null }, floatLabel: { classPropertyName: "floatLabel", publicName: "floatLabel", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { touched: "touchedChange", helpClick: "helpClick" }, viewQueries: [{ propertyName: "inputRef", first: true, predicate: ["input"], descendants: true, isSignal: true }], ngImport: i0 });
|
|
451
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.2.0", version: "22.0.1", type: KtBaseInputField, isStandalone: true, inputs: { touched: { classPropertyName: "touched", publicName: "touched", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, readonly: { classPropertyName: "readonly", publicName: "readonly", isSignal: true, isRequired: false, transformFunction: null }, invalid: { classPropertyName: "invalid", publicName: "invalid", isSignal: true, isRequired: false, transformFunction: null }, required: { classPropertyName: "required", publicName: "required", isSignal: true, isRequired: false, transformFunction: null }, dirty: { classPropertyName: "dirty", publicName: "dirty", isSignal: true, isRequired: false, transformFunction: null }, pending: { classPropertyName: "pending", publicName: "pending", isSignal: true, isRequired: false, transformFunction: null }, errors: { classPropertyName: "errors", publicName: "errors", isSignal: true, isRequired: false, transformFunction: null }, name: { classPropertyName: "name", publicName: "name", isSignal: true, isRequired: false, transformFunction: null }, id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, hint: { classPropertyName: "hint", publicName: "hint", isSignal: true, isRequired: false, transformFunction: null }, helpText: { classPropertyName: "helpText", publicName: "helpText", isSignal: true, isRequired: false, transformFunction: null }, helpLabel: { classPropertyName: "helpLabel", publicName: "helpLabel", isSignal: true, isRequired: false, transformFunction: null }, customDescribedBy: { classPropertyName: "customDescribedBy", publicName: "customDescribedBy", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, autocomplete: { classPropertyName: "autocomplete", publicName: "autocomplete", isSignal: true, isRequired: false, transformFunction: null }, icon: { classPropertyName: "icon", publicName: "icon", isSignal: true, isRequired: false, transformFunction: null }, clearable: { classPropertyName: "clearable", publicName: "clearable", isSignal: true, isRequired: false, transformFunction: null }, prefix: { classPropertyName: "prefix", publicName: "prefix", isSignal: true, isRequired: false, transformFunction: null }, suffix: { classPropertyName: "suffix", publicName: "suffix", isSignal: true, isRequired: false, transformFunction: null }, clearLabel: { classPropertyName: "clearLabel", publicName: "clearLabel", isSignal: true, isRequired: false, transformFunction: null }, errorMatcher: { classPropertyName: "errorMatcher", publicName: "errorMatcher", isSignal: true, isRequired: false, transformFunction: null }, appearance: { classPropertyName: "appearance", publicName: "appearance", isSignal: true, isRequired: false, transformFunction: null }, floatLabel: { classPropertyName: "floatLabel", publicName: "floatLabel", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { touched: "touchedChange", helpClick: "helpClick" }, viewQueries: [{ propertyName: "inputRef", first: true, predicate: ["input"], descendants: true, isSignal: true }], ngImport: i0 });
|
|
328
452
|
}
|
|
329
453
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.1", ngImport: i0, type: KtBaseInputField, decorators: [{
|
|
330
454
|
type: Directive
|
|
331
|
-
}], propDecorators: { touched: [{ type: i0.Input, args: [{ isSignal: true, alias: "touched", required: false }] }, { type: i0.Output, args: ["touchedChange"] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], readonly: [{ type: i0.Input, args: [{ isSignal: true, alias: "readonly", required: false }] }], invalid: [{ type: i0.Input, args: [{ isSignal: true, alias: "invalid", required: false }] }], required: [{ type: i0.Input, args: [{ isSignal: true, alias: "required", required: false }] }], dirty: [{ type: i0.Input, args: [{ isSignal: true, alias: "dirty", required: false }] }], errors: [{ type: i0.Input, args: [{ isSignal: true, alias: "errors", required: false }] }], name: [{ type: i0.Input, args: [{ isSignal: true, alias: "name", required: false }] }], id: [{ type: i0.Input, args: [{ isSignal: true, alias: "id", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], hint: [{ type: i0.Input, args: [{ isSignal: true, alias: "hint", required: false }] }], helpText: [{ type: i0.Input, args: [{ isSignal: true, alias: "helpText", required: false }] }], helpLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "helpLabel", required: false }] }], customDescribedBy: [{ type: i0.Input, args: [{ isSignal: true, alias: "customDescribedBy", required: false }] }], helpClick: [{ type: i0.Output, args: ["helpClick"] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], autocomplete: [{ type: i0.Input, args: [{ isSignal: true, alias: "autocomplete", required: false }] }], icon: [{ type: i0.Input, args: [{ isSignal: true, alias: "icon", required: false }] }], clearable: [{ type: i0.Input, args: [{ isSignal: true, alias: "clearable", required: false }] }], prefix: [{ type: i0.Input, args: [{ isSignal: true, alias: "prefix", required: false }] }], suffix: [{ type: i0.Input, args: [{ isSignal: true, alias: "suffix", required: false }] }], clearLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "clearLabel", required: false }] }], errorMatcher: [{ type: i0.Input, args: [{ isSignal: true, alias: "errorMatcher", required: false }] }], appearance: [{ type: i0.Input, args: [{ isSignal: true, alias: "appearance", required: false }] }], floatLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "floatLabel", required: false }] }], inputRef: [{ type: i0.ViewChild, args: ['input', { isSignal: true }] }] } });
|
|
455
|
+
}], propDecorators: { touched: [{ type: i0.Input, args: [{ isSignal: true, alias: "touched", required: false }] }, { type: i0.Output, args: ["touchedChange"] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], readonly: [{ type: i0.Input, args: [{ isSignal: true, alias: "readonly", required: false }] }], invalid: [{ type: i0.Input, args: [{ isSignal: true, alias: "invalid", required: false }] }], required: [{ type: i0.Input, args: [{ isSignal: true, alias: "required", required: false }] }], dirty: [{ type: i0.Input, args: [{ isSignal: true, alias: "dirty", required: false }] }], pending: [{ type: i0.Input, args: [{ isSignal: true, alias: "pending", required: false }] }], errors: [{ type: i0.Input, args: [{ isSignal: true, alias: "errors", required: false }] }], name: [{ type: i0.Input, args: [{ isSignal: true, alias: "name", required: false }] }], id: [{ type: i0.Input, args: [{ isSignal: true, alias: "id", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], hint: [{ type: i0.Input, args: [{ isSignal: true, alias: "hint", required: false }] }], helpText: [{ type: i0.Input, args: [{ isSignal: true, alias: "helpText", required: false }] }], helpLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "helpLabel", required: false }] }], customDescribedBy: [{ type: i0.Input, args: [{ isSignal: true, alias: "customDescribedBy", required: false }] }], helpClick: [{ type: i0.Output, args: ["helpClick"] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], autocomplete: [{ type: i0.Input, args: [{ isSignal: true, alias: "autocomplete", required: false }] }], icon: [{ type: i0.Input, args: [{ isSignal: true, alias: "icon", required: false }] }], clearable: [{ type: i0.Input, args: [{ isSignal: true, alias: "clearable", required: false }] }], prefix: [{ type: i0.Input, args: [{ isSignal: true, alias: "prefix", required: false }] }], suffix: [{ type: i0.Input, args: [{ isSignal: true, alias: "suffix", required: false }] }], clearLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "clearLabel", required: false }] }], errorMatcher: [{ type: i0.Input, args: [{ isSignal: true, alias: "errorMatcher", required: false }] }], appearance: [{ type: i0.Input, args: [{ isSignal: true, alias: "appearance", required: false }] }], floatLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "floatLabel", required: false }] }], inputRef: [{ type: i0.ViewChild, args: ['input', { isSignal: true }] }] } });
|
|
332
456
|
|
|
333
457
|
/** Normalise une liste de suggestions en options `<datalist>`. `toValue` sérialise la valeur en
|
|
334
458
|
chaîne attendue par l'input natif (identité pour le texte, `String()` pour les nombres,
|
|
@@ -449,6 +573,11 @@ class KtNumberField extends KtBaseInputField {
|
|
|
449
573
|
}
|
|
450
574
|
this.value.set(newValue);
|
|
451
575
|
}
|
|
576
|
+
// `rawValue` est un `transformedValue` : on passe par son canal officiel (et non par
|
|
577
|
+
// `nativeElement.value`) pour ne pas désynchroniser la représentation brute interne.
|
|
578
|
+
reset() {
|
|
579
|
+
this.rawValue.set(this.value() === null ? '' : String(this.value()));
|
|
580
|
+
}
|
|
452
581
|
emptyValue() {
|
|
453
582
|
return null;
|
|
454
583
|
}
|
|
@@ -456,11 +585,11 @@ class KtNumberField extends KtBaseInputField {
|
|
|
456
585
|
return value === null;
|
|
457
586
|
}
|
|
458
587
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.1", ngImport: i0, type: KtNumberField, deps: null, target: i0.ɵɵFactoryTarget.Component });
|
|
459
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.1", type: KtNumberField, isStandalone: true, selector: "kt-number-field", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, min: { classPropertyName: "min", publicName: "min", isSignal: true, isRequired: false, transformFunction: null }, max: { classPropertyName: "max", publicName: "max", isSignal: true, isRequired: false, transformFunction: null }, step: { classPropertyName: "step", publicName: "step", isSignal: true, isRequired: false, transformFunction: null }, suggestions: { classPropertyName: "suggestions", publicName: "suggestions", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange" }, usesInheritance: true, ngImport: i0, template: "<kt-field\n [label]=\"label()\"\n [hint]=\"hint()\"\n [helpText]=\"helpText()\"\n [helpLabel]=\"helpLabel()\"\n [customDescribedBy]=\"customDescribedBy()\"\n [errors]=\"
|
|
588
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.1", type: KtNumberField, isStandalone: true, selector: "kt-number-field", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, min: { classPropertyName: "min", publicName: "min", isSignal: true, isRequired: false, transformFunction: null }, max: { classPropertyName: "max", publicName: "max", isSignal: true, isRequired: false, transformFunction: null }, step: { classPropertyName: "step", publicName: "step", isSignal: true, isRequired: false, transformFunction: null }, suggestions: { classPropertyName: "suggestions", publicName: "suggestions", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange" }, usesInheritance: true, ngImport: i0, template: "<kt-field\n [label]=\"label()\"\n [hint]=\"hint()\"\n [helpText]=\"helpText()\"\n [helpLabel]=\"helpLabel()\"\n [customDescribedBy]=\"customDescribedBy()\"\n [errors]=\"displayErrors()\"\n [invalid]=\"showInvalid()\"\n [required]=\"required()\"\n [fieldId]=\"id()\"\n [appearance]=\"appearance()\"\n [floatLabel]=\"floatLabel()\"\n (helpClick)=\"helpClick.emit($event)\"\n>\n <ng-content select=\"[ktFieldHelp]\" />\n <div\n class=\"kt-field-box\"\n [attr.data-invalid]=\"showInvalid() ? '' : null\"\n [attr.data-disabled]=\"disabled() ? '' : null\"\n [attr.data-pending]=\"pending() ? '' : null\"\n >\n @if (icon(); as icon) {\n <span class=\"kt-field-box__icon\" aria-hidden=\"true\">{{ icon }}</span>\n }\n\n @if (prefix(); as prefix) {\n <span class=\"kt-field-box__affix\">\n @if (asTemplate(prefix); as tpl) {\n <ng-container [ngTemplateOutlet]=\"tpl\" />\n } @else {\n {{ asText(prefix) }}\n }\n </span>\n }\n\n <input\n #input\n ktFieldControl\n class=\"kt-field-box__input\"\n type=\"text\"\n inputmode=\"decimal\"\n role=\"spinbutton\"\n [attr.aria-valuemin]=\"min() ?? null\"\n [attr.aria-valuemax]=\"max() ?? null\"\n [attr.aria-valuenow]=\"value() ?? null\"\n [value]=\"rawValue()\"\n [disabled]=\"disabled()\"\n [readOnly]=\"readonly()\"\n [attr.aria-busy]=\"pending() ? 'true' : null\"\n [attr.name]=\"name() || null\"\n [attr.placeholder]=\"placeholderAttr()\"\n [attr.autocomplete]=\"autocomplete() || null\"\n [attr.min]=\"min() ?? null\"\n [attr.max]=\"max() ?? null\"\n [attr.step]=\"step() ?? null\"\n [attr.list]=\"hasSuggestions() ? datalistId : null\"\n (input)=\"rawValue.set($event.target.value)\"\n (keydown)=\"onKeyDown($event)\"\n (blur)=\"touched.set(true)\"\n />\n\n @if (hasSuggestions()) {\n <datalist [id]=\"datalistId\">\n @for (option of datalistOptions(); track $index) {\n <option [value]=\"option.value\" [attr.label]=\"option.label\"></option>\n }\n </datalist>\n }\n\n @if (showClear()) {\n <button type=\"button\" class=\"kt-field-box__clear\" [attr.aria-label]=\"clearLabel()\" (click)=\"clear()\">\n <span class=\"kt-field-box__icon\" aria-hidden=\"true\">close</span>\n </button>\n }\n\n @if (suffix(); as suffix) {\n <span class=\"kt-field-box__affix\">\n @if (asTemplate(suffix); as tpl) {\n <ng-container [ngTemplateOutlet]=\"tpl\" />\n } @else {\n {{ asText(suffix) }}\n }\n </span>\n }\n </div>\n</kt-field>\n", dependencies: [{ kind: "component", type: KtField, selector: "kt-field", inputs: ["label", "hint", "helpText", "helpLabel", "customDescribedBy", "errors", "invalid", "required", "fieldId", "hideHintWhenInvalid", "showAllErrors", "appearance", "floatLabel"], outputs: ["helpClick"] }, { kind: "directive", type: KtFieldControl, selector: "[ktFieldControl]" }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
460
589
|
}
|
|
461
590
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.1", ngImport: i0, type: KtNumberField, decorators: [{
|
|
462
591
|
type: Component,
|
|
463
|
-
args: [{ selector: 'kt-number-field', imports: [KtField, KtFieldControl, NgTemplateOutlet], changeDetection: ChangeDetectionStrategy.OnPush, template: "<kt-field\n [label]=\"label()\"\n [hint]=\"hint()\"\n [helpText]=\"helpText()\"\n [helpLabel]=\"helpLabel()\"\n [customDescribedBy]=\"customDescribedBy()\"\n [errors]=\"
|
|
592
|
+
args: [{ selector: 'kt-number-field', imports: [KtField, KtFieldControl, NgTemplateOutlet], changeDetection: ChangeDetectionStrategy.OnPush, template: "<kt-field\n [label]=\"label()\"\n [hint]=\"hint()\"\n [helpText]=\"helpText()\"\n [helpLabel]=\"helpLabel()\"\n [customDescribedBy]=\"customDescribedBy()\"\n [errors]=\"displayErrors()\"\n [invalid]=\"showInvalid()\"\n [required]=\"required()\"\n [fieldId]=\"id()\"\n [appearance]=\"appearance()\"\n [floatLabel]=\"floatLabel()\"\n (helpClick)=\"helpClick.emit($event)\"\n>\n <ng-content select=\"[ktFieldHelp]\" />\n <div\n class=\"kt-field-box\"\n [attr.data-invalid]=\"showInvalid() ? '' : null\"\n [attr.data-disabled]=\"disabled() ? '' : null\"\n [attr.data-pending]=\"pending() ? '' : null\"\n >\n @if (icon(); as icon) {\n <span class=\"kt-field-box__icon\" aria-hidden=\"true\">{{ icon }}</span>\n }\n\n @if (prefix(); as prefix) {\n <span class=\"kt-field-box__affix\">\n @if (asTemplate(prefix); as tpl) {\n <ng-container [ngTemplateOutlet]=\"tpl\" />\n } @else {\n {{ asText(prefix) }}\n }\n </span>\n }\n\n <input\n #input\n ktFieldControl\n class=\"kt-field-box__input\"\n type=\"text\"\n inputmode=\"decimal\"\n role=\"spinbutton\"\n [attr.aria-valuemin]=\"min() ?? null\"\n [attr.aria-valuemax]=\"max() ?? null\"\n [attr.aria-valuenow]=\"value() ?? null\"\n [value]=\"rawValue()\"\n [disabled]=\"disabled()\"\n [readOnly]=\"readonly()\"\n [attr.aria-busy]=\"pending() ? 'true' : null\"\n [attr.name]=\"name() || null\"\n [attr.placeholder]=\"placeholderAttr()\"\n [attr.autocomplete]=\"autocomplete() || null\"\n [attr.min]=\"min() ?? null\"\n [attr.max]=\"max() ?? null\"\n [attr.step]=\"step() ?? null\"\n [attr.list]=\"hasSuggestions() ? datalistId : null\"\n (input)=\"rawValue.set($event.target.value)\"\n (keydown)=\"onKeyDown($event)\"\n (blur)=\"touched.set(true)\"\n />\n\n @if (hasSuggestions()) {\n <datalist [id]=\"datalistId\">\n @for (option of datalistOptions(); track $index) {\n <option [value]=\"option.value\" [attr.label]=\"option.label\"></option>\n }\n </datalist>\n }\n\n @if (showClear()) {\n <button type=\"button\" class=\"kt-field-box__clear\" [attr.aria-label]=\"clearLabel()\" (click)=\"clear()\">\n <span class=\"kt-field-box__icon\" aria-hidden=\"true\">close</span>\n </button>\n }\n\n @if (suffix(); as suffix) {\n <span class=\"kt-field-box__affix\">\n @if (asTemplate(suffix); as tpl) {\n <ng-container [ngTemplateOutlet]=\"tpl\" />\n } @else {\n {{ asText(suffix) }}\n }\n </span>\n }\n </div>\n</kt-field>\n" }]
|
|
464
593
|
}], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }, { type: i0.Output, args: ["valueChange"] }], min: [{ type: i0.Input, args: [{ isSignal: true, alias: "min", required: false }] }], max: [{ type: i0.Input, args: [{ isSignal: true, alias: "max", required: false }] }], step: [{ type: i0.Input, args: [{ isSignal: true, alias: "step", required: false }] }], suggestions: [{ type: i0.Input, args: [{ isSignal: true, alias: "suggestions", required: false }] }] } });
|
|
465
594
|
|
|
466
595
|
/**
|
|
@@ -479,9 +608,19 @@ class KtTextArea extends KtBaseInputField {
|
|
|
479
608
|
/** Hauteur initiale (lignes). L'autosize est géré en CSS via `field-sizing: content`. @default 3 */
|
|
480
609
|
rows = input(3, /* @ts-ignore */
|
|
481
610
|
...(ngDevMode ? [{ debugName: "rows" }] : /* istanbul ignore next */ []));
|
|
611
|
+
/** Plancher de caractères (attribut `minlength` natif ; poussé par le validateur minLength). @default undefined */
|
|
612
|
+
minLength = input(/* @ts-ignore */
|
|
613
|
+
...(ngDevMode ? [undefined, { debugName: "minLength" }] : /* istanbul ignore next */ []));
|
|
482
614
|
/** Plafond de caractères ; poussé par le form (validateur maxLength) ou par le consommateur. @default undefined */
|
|
483
615
|
maxLength = input(/* @ts-ignore */
|
|
484
616
|
...(ngDevMode ? [undefined, { debugName: "maxLength" }] : /* istanbul ignore next */ []));
|
|
617
|
+
/** Motifs de validation (contrat Signal Forms). L'attribut natif `pattern` ne prend qu'une regex →
|
|
618
|
+
seule la première est posée. @default [] */
|
|
619
|
+
pattern = input([], /* @ts-ignore */
|
|
620
|
+
...(ngDevMode ? [{ debugName: "pattern" }] : /* istanbul ignore next */ []));
|
|
621
|
+
/** Source de la première regex pour l'attribut `pattern` natif (`null` si aucune). */
|
|
622
|
+
patternAttr = computed(() => this.pattern()[0]?.source ?? null, /* @ts-ignore */
|
|
623
|
+
...(ngDevMode ? [{ debugName: "patternAttr" }] : /* istanbul ignore next */ []));
|
|
485
624
|
parse(raw) {
|
|
486
625
|
return raw;
|
|
487
626
|
}
|
|
@@ -492,12 +631,12 @@ class KtTextArea extends KtBaseInputField {
|
|
|
492
631
|
return value.length === 0;
|
|
493
632
|
}
|
|
494
633
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.1", ngImport: i0, type: KtTextArea, deps: null, target: i0.ɵɵFactoryTarget.Component });
|
|
495
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.1", type: KtTextArea, isStandalone: true, selector: "kt-text-area", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, rows: { classPropertyName: "rows", publicName: "rows", isSignal: true, isRequired: false, transformFunction: null }, maxLength: { classPropertyName: "maxLength", publicName: "maxLength", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange" }, usesInheritance: true, ngImport: i0, template: "<kt-field\n [label]=\"label()\"\n [hint]=\"hint()\"\n [helpText]=\"helpText()\"\n [helpLabel]=\"helpLabel()\"\n [customDescribedBy]=\"customDescribedBy()\"\n [errors]=\"
|
|
634
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.1", type: KtTextArea, isStandalone: true, selector: "kt-text-area", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, rows: { classPropertyName: "rows", publicName: "rows", isSignal: true, isRequired: false, transformFunction: null }, minLength: { classPropertyName: "minLength", publicName: "minLength", isSignal: true, isRequired: false, transformFunction: null }, maxLength: { classPropertyName: "maxLength", publicName: "maxLength", isSignal: true, isRequired: false, transformFunction: null }, pattern: { classPropertyName: "pattern", publicName: "pattern", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange" }, usesInheritance: true, ngImport: i0, template: "<kt-field\n [label]=\"label()\"\n [hint]=\"hint()\"\n [helpText]=\"helpText()\"\n [helpLabel]=\"helpLabel()\"\n [customDescribedBy]=\"customDescribedBy()\"\n [errors]=\"displayErrors()\"\n [invalid]=\"showInvalid()\"\n [required]=\"required()\"\n [fieldId]=\"id()\"\n [appearance]=\"appearance()\"\n [floatLabel]=\"floatLabel()\"\n (helpClick)=\"helpClick.emit($event)\"\n>\n <ng-content select=\"[ktFieldHelp]\" />\n <div\n class=\"kt-field-box\"\n data-multiline\n [attr.data-invalid]=\"showInvalid() ? '' : null\"\n [attr.data-disabled]=\"disabled() ? '' : null\"\n [attr.data-pending]=\"pending() ? '' : null\"\n >\n @if (icon(); as icon) {\n <span class=\"kt-field-box__icon\" aria-hidden=\"true\">{{ icon }}</span>\n }\n\n @if (prefix(); as prefix) {\n <span class=\"kt-field-box__affix\">\n @if (asTemplate(prefix); as tpl) {\n <ng-container [ngTemplateOutlet]=\"tpl\" />\n } @else {\n {{ asText(prefix) }}\n }\n </span>\n }\n\n <textarea\n #input\n ktFieldControl\n class=\"kt-field-box__input\"\n [value]=\"value()\"\n [rows]=\"rows()\"\n [style.min-height.lh]=\"rows()\"\n [disabled]=\"disabled()\"\n [readOnly]=\"readonly()\"\n [attr.aria-busy]=\"pending() ? 'true' : null\"\n [attr.name]=\"name() || null\"\n [attr.placeholder]=\"placeholderAttr()\"\n [attr.autocomplete]=\"autocomplete() || null\"\n [attr.minlength]=\"minLength() ?? null\"\n [attr.maxlength]=\"maxLength() ?? null\"\n [attr.pattern]=\"patternAttr()\"\n (keydown)=\"onKeyDown($event)\"\n (input)=\"onInput($event)\"\n (blur)=\"touched.set(true)\"\n ></textarea>\n\n @if (showClear()) {\n <button type=\"button\" class=\"kt-field-box__clear\" [attr.aria-label]=\"clearLabel()\" (click)=\"clear()\">\n <span class=\"kt-field-box__icon\" aria-hidden=\"true\">close</span>\n </button>\n }\n\n @if (suffix(); as suffix) {\n <span class=\"kt-field-box__affix\">\n @if (asTemplate(suffix); as tpl) {\n <ng-container [ngTemplateOutlet]=\"tpl\" />\n } @else {\n {{ asText(suffix) }}\n }\n </span>\n }\n </div>\n</kt-field>\n", dependencies: [{ kind: "component", type: KtField, selector: "kt-field", inputs: ["label", "hint", "helpText", "helpLabel", "customDescribedBy", "errors", "invalid", "required", "fieldId", "hideHintWhenInvalid", "showAllErrors", "appearance", "floatLabel"], outputs: ["helpClick"] }, { kind: "directive", type: KtFieldControl, selector: "[ktFieldControl]" }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
496
635
|
}
|
|
497
636
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.1", ngImport: i0, type: KtTextArea, decorators: [{
|
|
498
637
|
type: Component,
|
|
499
|
-
args: [{ selector: 'kt-text-area', imports: [KtField, KtFieldControl, NgTemplateOutlet], changeDetection: ChangeDetectionStrategy.OnPush, template: "<kt-field\n [label]=\"label()\"\n [hint]=\"hint()\"\n [helpText]=\"helpText()\"\n [helpLabel]=\"helpLabel()\"\n [customDescribedBy]=\"customDescribedBy()\"\n [errors]=\"
|
|
500
|
-
}], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }, { type: i0.Output, args: ["valueChange"] }], rows: [{ type: i0.Input, args: [{ isSignal: true, alias: "rows", required: false }] }], maxLength: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxLength", required: false }] }] } });
|
|
638
|
+
args: [{ selector: 'kt-text-area', imports: [KtField, KtFieldControl, NgTemplateOutlet], changeDetection: ChangeDetectionStrategy.OnPush, template: "<kt-field\n [label]=\"label()\"\n [hint]=\"hint()\"\n [helpText]=\"helpText()\"\n [helpLabel]=\"helpLabel()\"\n [customDescribedBy]=\"customDescribedBy()\"\n [errors]=\"displayErrors()\"\n [invalid]=\"showInvalid()\"\n [required]=\"required()\"\n [fieldId]=\"id()\"\n [appearance]=\"appearance()\"\n [floatLabel]=\"floatLabel()\"\n (helpClick)=\"helpClick.emit($event)\"\n>\n <ng-content select=\"[ktFieldHelp]\" />\n <div\n class=\"kt-field-box\"\n data-multiline\n [attr.data-invalid]=\"showInvalid() ? '' : null\"\n [attr.data-disabled]=\"disabled() ? '' : null\"\n [attr.data-pending]=\"pending() ? '' : null\"\n >\n @if (icon(); as icon) {\n <span class=\"kt-field-box__icon\" aria-hidden=\"true\">{{ icon }}</span>\n }\n\n @if (prefix(); as prefix) {\n <span class=\"kt-field-box__affix\">\n @if (asTemplate(prefix); as tpl) {\n <ng-container [ngTemplateOutlet]=\"tpl\" />\n } @else {\n {{ asText(prefix) }}\n }\n </span>\n }\n\n <textarea\n #input\n ktFieldControl\n class=\"kt-field-box__input\"\n [value]=\"value()\"\n [rows]=\"rows()\"\n [style.min-height.lh]=\"rows()\"\n [disabled]=\"disabled()\"\n [readOnly]=\"readonly()\"\n [attr.aria-busy]=\"pending() ? 'true' : null\"\n [attr.name]=\"name() || null\"\n [attr.placeholder]=\"placeholderAttr()\"\n [attr.autocomplete]=\"autocomplete() || null\"\n [attr.minlength]=\"minLength() ?? null\"\n [attr.maxlength]=\"maxLength() ?? null\"\n [attr.pattern]=\"patternAttr()\"\n (keydown)=\"onKeyDown($event)\"\n (input)=\"onInput($event)\"\n (blur)=\"touched.set(true)\"\n ></textarea>\n\n @if (showClear()) {\n <button type=\"button\" class=\"kt-field-box__clear\" [attr.aria-label]=\"clearLabel()\" (click)=\"clear()\">\n <span class=\"kt-field-box__icon\" aria-hidden=\"true\">close</span>\n </button>\n }\n\n @if (suffix(); as suffix) {\n <span class=\"kt-field-box__affix\">\n @if (asTemplate(suffix); as tpl) {\n <ng-container [ngTemplateOutlet]=\"tpl\" />\n } @else {\n {{ asText(suffix) }}\n }\n </span>\n }\n </div>\n</kt-field>\n" }]
|
|
639
|
+
}], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }, { type: i0.Output, args: ["valueChange"] }], rows: [{ type: i0.Input, args: [{ isSignal: true, alias: "rows", required: false }] }], minLength: [{ type: i0.Input, args: [{ isSignal: true, alias: "minLength", required: false }] }], maxLength: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxLength", required: false }] }], pattern: [{ type: i0.Input, args: [{ isSignal: true, alias: "pattern", required: false }] }] } });
|
|
501
640
|
|
|
502
641
|
/**
|
|
503
642
|
* Champ texte (valeur `string`) intégré aux Signal Forms via `FormValueControl`. Hérite de la
|
|
@@ -515,6 +654,19 @@ class KtTextField extends KtBaseInputField {
|
|
|
515
654
|
/** Variante HTML du champ (pilote `type` natif et le clavier mobile). @default 'text' */
|
|
516
655
|
type = input('text', /* @ts-ignore */
|
|
517
656
|
...(ngDevMode ? [{ debugName: "type" }] : /* istanbul ignore next */ []));
|
|
657
|
+
/** Plancher de caractères (attribut `minlength` natif ; poussé par le validateur minLength). @default undefined */
|
|
658
|
+
minLength = input(/* @ts-ignore */
|
|
659
|
+
...(ngDevMode ? [undefined, { debugName: "minLength" }] : /* istanbul ignore next */ []));
|
|
660
|
+
/** Plafond de caractères (attribut `maxlength` natif ; poussé par le validateur maxLength). @default undefined */
|
|
661
|
+
maxLength = input(/* @ts-ignore */
|
|
662
|
+
...(ngDevMode ? [undefined, { debugName: "maxLength" }] : /* istanbul ignore next */ []));
|
|
663
|
+
/** Motifs de validation (contrat Signal Forms). L'attribut natif `pattern` ne prend qu'une regex →
|
|
664
|
+
seule la première est posée. @default [] */
|
|
665
|
+
pattern = input([], /* @ts-ignore */
|
|
666
|
+
...(ngDevMode ? [{ debugName: "pattern" }] : /* istanbul ignore next */ []));
|
|
667
|
+
/** Source de la première regex pour l'attribut `pattern` natif (`null` si aucune). */
|
|
668
|
+
patternAttr = computed(() => this.pattern()[0]?.source ?? null, /* @ts-ignore */
|
|
669
|
+
...(ngDevMode ? [{ debugName: "patternAttr" }] : /* istanbul ignore next */ []));
|
|
518
670
|
/** Suggestions d'autocomplétion proposées via un `<datalist>` natif (la saisie reste libre).
|
|
519
671
|
Valeurs simples (`string[]`) ou couples `{ value, label }` pour distinguer libellé affiché et
|
|
520
672
|
valeur insérée. @default undefined */
|
|
@@ -537,12 +689,12 @@ class KtTextField extends KtBaseInputField {
|
|
|
537
689
|
return value.length === 0;
|
|
538
690
|
}
|
|
539
691
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.1", ngImport: i0, type: KtTextField, deps: null, target: i0.ɵɵFactoryTarget.Component });
|
|
540
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.1", type: KtTextField, isStandalone: true, selector: "kt-text-field", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, type: { classPropertyName: "type", publicName: "type", isSignal: true, isRequired: false, transformFunction: null }, suggestions: { classPropertyName: "suggestions", publicName: "suggestions", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange" }, usesInheritance: true, ngImport: i0, template: "<kt-field\n [label]=\"label()\"\n [hint]=\"hint()\"\n [helpText]=\"helpText()\"\n [helpLabel]=\"helpLabel()\"\n [customDescribedBy]=\"customDescribedBy()\"\n [errors]=\"
|
|
692
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.1", type: KtTextField, isStandalone: true, selector: "kt-text-field", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, type: { classPropertyName: "type", publicName: "type", isSignal: true, isRequired: false, transformFunction: null }, minLength: { classPropertyName: "minLength", publicName: "minLength", isSignal: true, isRequired: false, transformFunction: null }, maxLength: { classPropertyName: "maxLength", publicName: "maxLength", isSignal: true, isRequired: false, transformFunction: null }, pattern: { classPropertyName: "pattern", publicName: "pattern", isSignal: true, isRequired: false, transformFunction: null }, suggestions: { classPropertyName: "suggestions", publicName: "suggestions", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange" }, usesInheritance: true, ngImport: i0, template: "<kt-field\n [label]=\"label()\"\n [hint]=\"hint()\"\n [helpText]=\"helpText()\"\n [helpLabel]=\"helpLabel()\"\n [customDescribedBy]=\"customDescribedBy()\"\n [errors]=\"displayErrors()\"\n [invalid]=\"showInvalid()\"\n [required]=\"required()\"\n [fieldId]=\"id()\"\n [appearance]=\"appearance()\"\n [floatLabel]=\"floatLabel()\"\n (helpClick)=\"helpClick.emit($event)\"\n>\n <ng-content select=\"[ktFieldHelp]\" />\n <div\n class=\"kt-field-box\"\n [attr.data-invalid]=\"showInvalid() ? '' : null\"\n [attr.data-disabled]=\"disabled() ? '' : null\"\n [attr.data-pending]=\"pending() ? '' : null\"\n >\n @if (icon(); as icon) {\n <span class=\"kt-field-box__icon\" aria-hidden=\"true\">{{ icon }}</span>\n }\n\n @if (prefix(); as prefix) {\n <span class=\"kt-field-box__affix\">\n @if (asTemplate(prefix); as tpl) {\n <ng-container [ngTemplateOutlet]=\"tpl\" />\n } @else {\n {{ asText(prefix) }}\n }\n </span>\n }\n\n <input\n #input\n ktFieldControl\n class=\"kt-field-box__input\"\n [type]=\"type()\"\n [value]=\"value()\"\n [disabled]=\"disabled()\"\n [readOnly]=\"readonly()\"\n [attr.aria-busy]=\"pending() ? 'true' : null\"\n [attr.name]=\"name() || null\"\n [attr.placeholder]=\"placeholderAttr()\"\n [attr.autocomplete]=\"autocomplete() || null\"\n [attr.minlength]=\"minLength() ?? null\"\n [attr.maxlength]=\"maxLength() ?? null\"\n [attr.pattern]=\"patternAttr()\"\n [attr.list]=\"hasSuggestions() ? datalistId : null\"\n (keydown)=\"onKeyDown($event)\"\n (input)=\"onInput($event)\"\n (blur)=\"touched.set(true)\"\n />\n\n @if (hasSuggestions()) {\n <datalist [id]=\"datalistId\">\n @for (option of datalistOptions(); track $index) {\n <option [value]=\"option.value\" [attr.label]=\"option.label\"></option>\n }\n </datalist>\n }\n\n @if (showClear()) {\n <button type=\"button\" class=\"kt-field-box__clear\" [attr.aria-label]=\"clearLabel()\" (click)=\"clear()\">\n <span class=\"kt-field-box__icon\" aria-hidden=\"true\">close</span>\n </button>\n }\n\n @if (suffix(); as suffix) {\n <span class=\"kt-field-box__affix\">\n @if (asTemplate(suffix); as tpl) {\n <ng-container [ngTemplateOutlet]=\"tpl\" />\n } @else {\n {{ asText(suffix) }}\n }\n </span>\n }\n </div>\n</kt-field>\n", dependencies: [{ kind: "component", type: KtField, selector: "kt-field", inputs: ["label", "hint", "helpText", "helpLabel", "customDescribedBy", "errors", "invalid", "required", "fieldId", "hideHintWhenInvalid", "showAllErrors", "appearance", "floatLabel"], outputs: ["helpClick"] }, { kind: "directive", type: KtFieldControl, selector: "[ktFieldControl]" }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
541
693
|
}
|
|
542
694
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.1", ngImport: i0, type: KtTextField, decorators: [{
|
|
543
695
|
type: Component,
|
|
544
|
-
args: [{ selector: 'kt-text-field', imports: [KtField, KtFieldControl, NgTemplateOutlet], changeDetection: ChangeDetectionStrategy.OnPush, template: "<kt-field\n [label]=\"label()\"\n [hint]=\"hint()\"\n [helpText]=\"helpText()\"\n [helpLabel]=\"helpLabel()\"\n [customDescribedBy]=\"customDescribedBy()\"\n [errors]=\"
|
|
545
|
-
}], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }, { type: i0.Output, args: ["valueChange"] }], type: [{ type: i0.Input, args: [{ isSignal: true, alias: "type", required: false }] }], suggestions: [{ type: i0.Input, args: [{ isSignal: true, alias: "suggestions", required: false }] }] } });
|
|
696
|
+
args: [{ selector: 'kt-text-field', imports: [KtField, KtFieldControl, NgTemplateOutlet], changeDetection: ChangeDetectionStrategy.OnPush, template: "<kt-field\n [label]=\"label()\"\n [hint]=\"hint()\"\n [helpText]=\"helpText()\"\n [helpLabel]=\"helpLabel()\"\n [customDescribedBy]=\"customDescribedBy()\"\n [errors]=\"displayErrors()\"\n [invalid]=\"showInvalid()\"\n [required]=\"required()\"\n [fieldId]=\"id()\"\n [appearance]=\"appearance()\"\n [floatLabel]=\"floatLabel()\"\n (helpClick)=\"helpClick.emit($event)\"\n>\n <ng-content select=\"[ktFieldHelp]\" />\n <div\n class=\"kt-field-box\"\n [attr.data-invalid]=\"showInvalid() ? '' : null\"\n [attr.data-disabled]=\"disabled() ? '' : null\"\n [attr.data-pending]=\"pending() ? '' : null\"\n >\n @if (icon(); as icon) {\n <span class=\"kt-field-box__icon\" aria-hidden=\"true\">{{ icon }}</span>\n }\n\n @if (prefix(); as prefix) {\n <span class=\"kt-field-box__affix\">\n @if (asTemplate(prefix); as tpl) {\n <ng-container [ngTemplateOutlet]=\"tpl\" />\n } @else {\n {{ asText(prefix) }}\n }\n </span>\n }\n\n <input\n #input\n ktFieldControl\n class=\"kt-field-box__input\"\n [type]=\"type()\"\n [value]=\"value()\"\n [disabled]=\"disabled()\"\n [readOnly]=\"readonly()\"\n [attr.aria-busy]=\"pending() ? 'true' : null\"\n [attr.name]=\"name() || null\"\n [attr.placeholder]=\"placeholderAttr()\"\n [attr.autocomplete]=\"autocomplete() || null\"\n [attr.minlength]=\"minLength() ?? null\"\n [attr.maxlength]=\"maxLength() ?? null\"\n [attr.pattern]=\"patternAttr()\"\n [attr.list]=\"hasSuggestions() ? datalistId : null\"\n (keydown)=\"onKeyDown($event)\"\n (input)=\"onInput($event)\"\n (blur)=\"touched.set(true)\"\n />\n\n @if (hasSuggestions()) {\n <datalist [id]=\"datalistId\">\n @for (option of datalistOptions(); track $index) {\n <option [value]=\"option.value\" [attr.label]=\"option.label\"></option>\n }\n </datalist>\n }\n\n @if (showClear()) {\n <button type=\"button\" class=\"kt-field-box__clear\" [attr.aria-label]=\"clearLabel()\" (click)=\"clear()\">\n <span class=\"kt-field-box__icon\" aria-hidden=\"true\">close</span>\n </button>\n }\n\n @if (suffix(); as suffix) {\n <span class=\"kt-field-box__affix\">\n @if (asTemplate(suffix); as tpl) {\n <ng-container [ngTemplateOutlet]=\"tpl\" />\n } @else {\n {{ asText(suffix) }}\n }\n </span>\n }\n </div>\n</kt-field>\n" }]
|
|
697
|
+
}], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }, { type: i0.Output, args: ["valueChange"] }], type: [{ type: i0.Input, args: [{ isSignal: true, alias: "type", required: false }] }], minLength: [{ type: i0.Input, args: [{ isSignal: true, alias: "minLength", required: false }] }], maxLength: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxLength", required: false }] }], pattern: [{ type: i0.Input, args: [{ isSignal: true, alias: "pattern", required: false }] }], suggestions: [{ type: i0.Input, args: [{ isSignal: true, alias: "suggestions", required: false }] }] } });
|
|
546
698
|
|
|
547
699
|
/**
|
|
548
700
|
* Bouton bascule (Switch / Slide-Toggle) accessible conforme aux normes WAI-ARIA.
|
|
@@ -571,6 +723,8 @@ class KtSwitch {
|
|
|
571
723
|
required = input(false, { ...(ngDevMode ? { debugName: "required" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
572
724
|
/** État « modifié » (entre dans la logique d'affichage des erreurs). @default false */
|
|
573
725
|
dirty = input(false, { ...(ngDevMode ? { debugName: "dirty" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
726
|
+
/** Validation asynchrone en cours (poussé par `[field]`) : pose `aria-busy` + `data-pending`. @default false */
|
|
727
|
+
pending = input(false, { ...(ngDevMode ? { debugName: "pending" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
574
728
|
/** Erreurs de validation à afficher sous la bascule. @default [] */
|
|
575
729
|
errors = input([], /* @ts-ignore */
|
|
576
730
|
...(ngDevMode ? [{ debugName: "errors" }] : /* istanbul ignore next */ []));
|
|
@@ -595,6 +749,8 @@ class KtSwitch {
|
|
|
595
749
|
...(ngDevMode ? [undefined, { debugName: "errorMatcher" }] : /* istanbul ignore next */ []));
|
|
596
750
|
/** Afficher toutes les erreurs au lieu de la première seule. @default KT_FIELD_CONFIG.showAllErrors ?? false */
|
|
597
751
|
showAllErrors = input(this.config?.showAllErrors ?? false, { ...(ngDevMode ? { debugName: "showAllErrors" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
752
|
+
switchBtn = viewChild.required('switchBtn');
|
|
753
|
+
errorResolver = inject(KtFieldErrorResolver);
|
|
598
754
|
idGen = inject(KtIdGenerator);
|
|
599
755
|
uid = this.idGen.generateId('switch');
|
|
600
756
|
baseId = computed(() => this.id() ?? `kt-switch-${this.uid}`, /* @ts-ignore */
|
|
@@ -609,7 +765,10 @@ class KtSwitch {
|
|
|
609
765
|
...(ngDevMode ? [{ debugName: "matcher" }] : /* istanbul ignore next */ []));
|
|
610
766
|
showInvalid = computed(() => this.matcher()({ invalid: this.invalid(), touched: this.touched(), dirty: this.dirty() }), /* @ts-ignore */
|
|
611
767
|
...(ngDevMode ? [{ debugName: "showInvalid" }] : /* istanbul ignore next */ []));
|
|
612
|
-
|
|
768
|
+
/** Erreurs résolues (messages par défaut appliqués, suppressions `message: ''` écartées). */
|
|
769
|
+
resolvedErrors = computed(() => this.errorResolver.resolveAll(this.errors()), /* @ts-ignore */
|
|
770
|
+
...(ngDevMode ? [{ debugName: "resolvedErrors" }] : /* istanbul ignore next */ []));
|
|
771
|
+
displayedErrors = computed(() => this.showAllErrors() ? this.resolvedErrors() : this.resolvedErrors().slice(0, 1), /* @ts-ignore */
|
|
613
772
|
...(ngDevMode ? [{ debugName: "displayedErrors" }] : /* istanbul ignore next */ []));
|
|
614
773
|
resolvedAriaLabel = computed(() => this.ariaLabel() ?? null, /* @ts-ignore */
|
|
615
774
|
...(ngDevMode ? [{ debugName: "resolvedAriaLabel" }] : /* istanbul ignore next */ []));
|
|
@@ -617,7 +776,7 @@ class KtSwitch {
|
|
|
617
776
|
const ids = [];
|
|
618
777
|
if (this.hint() && !this.showInvalid())
|
|
619
778
|
ids.push(this.hintId());
|
|
620
|
-
if (this.showInvalid() && this.
|
|
779
|
+
if (this.showInvalid() && this.resolvedErrors().length > 0)
|
|
621
780
|
ids.push(this.errorId());
|
|
622
781
|
return ids.length ? ids.join(' ') : null;
|
|
623
782
|
}, /* @ts-ignore */
|
|
@@ -631,6 +790,10 @@ class KtSwitch {
|
|
|
631
790
|
console.warn('[ktSwitch] sans `label` ni `ariaLabel` : le contrôle est annoncé sans nom accessible (WCAG 4.1.2).');
|
|
632
791
|
});
|
|
633
792
|
}
|
|
793
|
+
/** Focus le bouton bascule natif (utilisé par Signal Forms `focusBoundControl`). */
|
|
794
|
+
focus(options) {
|
|
795
|
+
this.switchBtn().nativeElement.focus(options);
|
|
796
|
+
}
|
|
634
797
|
toggle() {
|
|
635
798
|
if (this.disabled())
|
|
636
799
|
return;
|
|
@@ -642,11 +805,12 @@ class KtSwitch {
|
|
|
642
805
|
this.toggle();
|
|
643
806
|
}
|
|
644
807
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.1", ngImport: i0, type: KtSwitch, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
645
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.1", type: KtSwitch, isStandalone: true, selector: "kt-switch", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, touched: { classPropertyName: "touched", publicName: "touched", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, invalid: { classPropertyName: "invalid", publicName: "invalid", isSignal: true, isRequired: false, transformFunction: null }, required: { classPropertyName: "required", publicName: "required", isSignal: true, isRequired: false, transformFunction: null }, dirty: { classPropertyName: "dirty", publicName: "dirty", isSignal: true, isRequired: false, transformFunction: null }, errors: { classPropertyName: "errors", publicName: "errors", isSignal: true, isRequired: false, transformFunction: null }, name: { classPropertyName: "name", publicName: "name", isSignal: true, isRequired: false, transformFunction: null }, id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, hint: { classPropertyName: "hint", publicName: "hint", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, errorMatcher: { classPropertyName: "errorMatcher", publicName: "errorMatcher", isSignal: true, isRequired: false, transformFunction: null }, showAllErrors: { classPropertyName: "showAllErrors", publicName: "showAllErrors", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange", touched: "touchedChange" }, ngImport: i0, template: `
|
|
808
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.1", type: KtSwitch, isStandalone: true, selector: "kt-switch", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, touched: { classPropertyName: "touched", publicName: "touched", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, invalid: { classPropertyName: "invalid", publicName: "invalid", isSignal: true, isRequired: false, transformFunction: null }, required: { classPropertyName: "required", publicName: "required", isSignal: true, isRequired: false, transformFunction: null }, dirty: { classPropertyName: "dirty", publicName: "dirty", isSignal: true, isRequired: false, transformFunction: null }, pending: { classPropertyName: "pending", publicName: "pending", isSignal: true, isRequired: false, transformFunction: null }, errors: { classPropertyName: "errors", publicName: "errors", isSignal: true, isRequired: false, transformFunction: null }, name: { classPropertyName: "name", publicName: "name", isSignal: true, isRequired: false, transformFunction: null }, id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, hint: { classPropertyName: "hint", publicName: "hint", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, errorMatcher: { classPropertyName: "errorMatcher", publicName: "errorMatcher", isSignal: true, isRequired: false, transformFunction: null }, showAllErrors: { classPropertyName: "showAllErrors", publicName: "showAllErrors", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange", touched: "touchedChange" }, viewQueries: [{ propertyName: "switchBtn", first: true, predicate: ["switchBtn"], descendants: true, isSignal: true }], ngImport: i0, template: `
|
|
646
809
|
<div
|
|
647
810
|
class="kt-switch-field"
|
|
648
811
|
[class.kt-switch-field--invalid]="showInvalid()"
|
|
649
812
|
[class.kt-switch-field--disabled]="disabled()"
|
|
813
|
+
[attr.data-pending]="pending() ? '' : null"
|
|
650
814
|
>
|
|
651
815
|
<div class="kt-switch-row">
|
|
652
816
|
<button
|
|
@@ -660,6 +824,7 @@ class KtSwitch {
|
|
|
660
824
|
[attr.aria-describedby]="describedBy()"
|
|
661
825
|
[attr.aria-invalid]="showInvalid() ? 'true' : null"
|
|
662
826
|
[attr.aria-required]="required() ? 'true' : null"
|
|
827
|
+
[attr.aria-busy]="pending() ? 'true' : null"
|
|
663
828
|
[disabled]="disabled()"
|
|
664
829
|
(click)="toggle()"
|
|
665
830
|
(keydown.space)="onSpacebar($event)"
|
|
@@ -699,6 +864,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.1", ngImpor
|
|
|
699
864
|
class="kt-switch-field"
|
|
700
865
|
[class.kt-switch-field--invalid]="showInvalid()"
|
|
701
866
|
[class.kt-switch-field--disabled]="disabled()"
|
|
867
|
+
[attr.data-pending]="pending() ? '' : null"
|
|
702
868
|
>
|
|
703
869
|
<div class="kt-switch-row">
|
|
704
870
|
<button
|
|
@@ -712,6 +878,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.1", ngImpor
|
|
|
712
878
|
[attr.aria-describedby]="describedBy()"
|
|
713
879
|
[attr.aria-invalid]="showInvalid() ? 'true' : null"
|
|
714
880
|
[attr.aria-required]="required() ? 'true' : null"
|
|
881
|
+
[attr.aria-busy]="pending() ? 'true' : null"
|
|
715
882
|
[disabled]="disabled()"
|
|
716
883
|
(click)="toggle()"
|
|
717
884
|
(keydown.space)="onSpacebar($event)"
|
|
@@ -743,7 +910,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.1", ngImpor
|
|
|
743
910
|
</div>
|
|
744
911
|
</div>
|
|
745
912
|
`, styles: ["@layer kt-aaa.components{:host{display:block}.kt-switch-field{display:flex;flex-direction:column;gap:var(--field-gap, .375rem)}.kt-switch-row{display:flex;align-items:center;gap:var(--field-control-gap, .5rem)}.kt-switch{position:relative;display:inline-flex;align-items:center;box-sizing:border-box;inline-size:var(--switch-width, 2.75rem);block-size:var(--switch-height, 1.5rem);padding:var(--switch-padding, 2px);border-radius:var(--switch-radius, 999px);border:var(--switch-border-width, 2px) solid var(--switch-border-color, var(--field-border-color, var(--kt-outline, #c4c7c5)));background-color:var(--switch-bg, var(--field-bg, var(--kt-surface, #ffffff)));cursor:pointer;outline:none;box-shadow:var(--switch-shadow, var(--field-shadow, none));transition:var( --switch-transition, background-color .2s cubic-bezier(.4, 0, .2, 1), border-color .2s cubic-bezier(.4, 0, .2, 1), box-shadow .2s ease )}.kt-switch:after{content:\"\";position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);width:100%;height:44px}.kt-switch__thumb{display:block;inline-size:var(--switch-thumb-size, 1rem);block-size:var(--switch-thumb-size, 1rem);border-radius:var(--switch-thumb-radius, 50%);background-color:var(--switch-thumb-bg, var(--kt-outline-strong, #5f6368));box-shadow:var(--switch-thumb-shadow, 0 1px 3px rgba(0, 0, 0, .2));transition:var( --switch-thumb-transition, transform .2s cubic-bezier(.34, 1.56, .64, 1), background-color .2s ease );transform:translate(0)}.kt-switch[aria-checked=true]{background-color:var(--switch-bg-active, var(--kt-primary, #0b57d0));border-color:var(--switch-border-color-active, var(--kt-primary, #0b57d0));box-shadow:var( --switch-shadow-active, 0 0 8px color-mix(in srgb, var(--switch-bg-active, var(--kt-primary, #0b57d0)) 50%, transparent) )}.kt-switch[aria-checked=true] .kt-switch__thumb{background-color:var(--switch-thumb-bg-active, #ffffff);transform:translate(calc(var(--switch-width, 2.75rem) - var(--switch-thumb-size, 1rem) - (var(--switch-padding, 2px) * 2) - (var(--switch-border-width, 2px) * 2)))}.kt-switch:hover:not(:disabled){border-color:var(--switch-border-color-hover, var(--field-border-color-hover, var(--kt-outline-strong, #5f6368)));box-shadow:var(--switch-shadow-hover, var(--field-shadow-hover, var(--switch-shadow, var(--field-shadow, none))))}.kt-switch[aria-checked=true]:hover:not(:disabled){background-color:var(--switch-bg-active-hover, color-mix(in srgb, var(--kt-primary, #0b57d0) 90%, black));border-color:var(--switch-border-color-active-hover, color-mix(in srgb, var(--kt-primary, #0b57d0) 90%, black))}.kt-switch:focus-visible{outline:var(--kt-focus-ring-width, 2px) solid var(--kt-focus-ring-color, #0b57d0);outline-offset:var(--switch-focus-ring-offset, 2px);box-shadow:var(--switch-shadow-focus, var(--field-shadow-focus, var(--switch-shadow, var(--field-shadow, none))))}.kt-switch:disabled{cursor:not-allowed;opacity:.5;background-color:var(--field-disabled-bg, #f1f3f4);border-color:var(--field-border-color, #c4c7c5)}.kt-switch:disabled .kt-switch__thumb{background-color:var(--kt-outline, #c4c7c5);box-shadow:none}.kt-switch-field--invalid .kt-switch{border-color:var(--field-error-color, var(--kt-danger, #b3261e))}.kt-switch-field--invalid .kt-switch[aria-checked=true]{background-color:var(--field-error-color, var(--kt-danger, #b3261e));border-color:var(--field-error-color, var(--kt-danger, #b3261e))}.kt-switch-label{font-size:var(--field-label-font-size, .875rem);font-weight:var(--field-label-weight, 500);color:var(--field-label-color, inherit);cursor:pointer;-webkit-user-select:none;user-select:none}.kt-switch-field--disabled .kt-switch-label{cursor:not-allowed;color:var(--field-hint-color, #5f6368);opacity:.6}.kt-switch-label__required{margin-inline-start:.125rem;color:var(--field-required-color, #8c1d18)}.kt-switch-hint{margin:0;font-size:var(--field-hint-font-size, .8125rem);color:var(--field-hint-color, #474747)}.kt-switch-error{margin:0;display:flex;flex-direction:column;font-size:var(--field-hint-font-size, .8125rem);color:var(--field-error-color, #8c1d18)}.kt-switch-error-message{animation:var(--field-error-animation, none)}@media(prefers-reduced-motion:reduce){.kt-switch,.kt-switch__thumb{transition:none}.kt-switch-error-message{animation:none}}}\n"] }]
|
|
746
|
-
}], ctorParameters: () => [], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }, { type: i0.Output, args: ["valueChange"] }], touched: [{ type: i0.Input, args: [{ isSignal: true, alias: "touched", required: false }] }, { type: i0.Output, args: ["touchedChange"] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], invalid: [{ type: i0.Input, args: [{ isSignal: true, alias: "invalid", required: false }] }], required: [{ type: i0.Input, args: [{ isSignal: true, alias: "required", required: false }] }], dirty: [{ type: i0.Input, args: [{ isSignal: true, alias: "dirty", required: false }] }], errors: [{ type: i0.Input, args: [{ isSignal: true, alias: "errors", required: false }] }], name: [{ type: i0.Input, args: [{ isSignal: true, alias: "name", required: false }] }], id: [{ type: i0.Input, args: [{ isSignal: true, alias: "id", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], hint: [{ type: i0.Input, args: [{ isSignal: true, alias: "hint", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], errorMatcher: [{ type: i0.Input, args: [{ isSignal: true, alias: "errorMatcher", required: false }] }], showAllErrors: [{ type: i0.Input, args: [{ isSignal: true, alias: "showAllErrors", required: false }] }] } });
|
|
913
|
+
}], ctorParameters: () => [], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }, { type: i0.Output, args: ["valueChange"] }], touched: [{ type: i0.Input, args: [{ isSignal: true, alias: "touched", required: false }] }, { type: i0.Output, args: ["touchedChange"] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], invalid: [{ type: i0.Input, args: [{ isSignal: true, alias: "invalid", required: false }] }], required: [{ type: i0.Input, args: [{ isSignal: true, alias: "required", required: false }] }], dirty: [{ type: i0.Input, args: [{ isSignal: true, alias: "dirty", required: false }] }], pending: [{ type: i0.Input, args: [{ isSignal: true, alias: "pending", required: false }] }], errors: [{ type: i0.Input, args: [{ isSignal: true, alias: "errors", required: false }] }], name: [{ type: i0.Input, args: [{ isSignal: true, alias: "name", required: false }] }], id: [{ type: i0.Input, args: [{ isSignal: true, alias: "id", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], hint: [{ type: i0.Input, args: [{ isSignal: true, alias: "hint", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], errorMatcher: [{ type: i0.Input, args: [{ isSignal: true, alias: "errorMatcher", required: false }] }], showAllErrors: [{ type: i0.Input, args: [{ isSignal: true, alias: "showAllErrors", required: false }] }], switchBtn: [{ type: i0.ViewChild, args: ['switchBtn', { isSignal: true }] }] } });
|
|
747
914
|
|
|
748
915
|
/**
|
|
749
916
|
* Groupe de cases à cocher (Checkbox Group) conforme à l'ARIA APG / RGAA.
|
|
@@ -780,6 +947,8 @@ class KtCheckboxGroup {
|
|
|
780
947
|
required = input(false, { ...(ngDevMode ? { debugName: "required" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
781
948
|
/** État « modifié » (entre dans la logique d'affichage des erreurs). @default false */
|
|
782
949
|
dirty = input(false, { ...(ngDevMode ? { debugName: "dirty" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
950
|
+
/** Validation asynchrone en cours (poussé par `[field]`) : pose `aria-busy` + `data-pending`. @default false */
|
|
951
|
+
pending = input(false, { ...(ngDevMode ? { debugName: "pending" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
783
952
|
/** Erreurs de validation à afficher sous le groupe. @default [] */
|
|
784
953
|
errors = input([], /* @ts-ignore */
|
|
785
954
|
...(ngDevMode ? [{ debugName: "errors" }] : /* istanbul ignore next */ []));
|
|
@@ -809,6 +978,8 @@ class KtCheckboxGroup {
|
|
|
809
978
|
/** Égalité des valeurs en mode objet (défaut : identité `===`). */
|
|
810
979
|
compareWith = input(/* @ts-ignore */
|
|
811
980
|
...(ngDevMode ? [undefined, { debugName: "compareWith" }] : /* istanbul ignore next */ []));
|
|
981
|
+
el = inject(ElementRef);
|
|
982
|
+
errorResolver = inject(KtFieldErrorResolver);
|
|
812
983
|
idGen = inject(KtIdGenerator);
|
|
813
984
|
uid = this.idGen.generateId('checkbox-group');
|
|
814
985
|
baseId = computed(() => this.id() ?? `kt-checkbox-group-${this.uid}`, /* @ts-ignore */
|
|
@@ -823,7 +994,10 @@ class KtCheckboxGroup {
|
|
|
823
994
|
...(ngDevMode ? [{ debugName: "matcher" }] : /* istanbul ignore next */ []));
|
|
824
995
|
showInvalid = computed(() => this.matcher()({ invalid: this.invalid(), touched: this.touched(), dirty: this.dirty() }), /* @ts-ignore */
|
|
825
996
|
...(ngDevMode ? [{ debugName: "showInvalid" }] : /* istanbul ignore next */ []));
|
|
826
|
-
|
|
997
|
+
/** Erreurs résolues (messages par défaut appliqués, suppressions `message: ''` écartées). */
|
|
998
|
+
resolvedErrors = computed(() => this.errorResolver.resolveAll(this.errors()), /* @ts-ignore */
|
|
999
|
+
...(ngDevMode ? [{ debugName: "resolvedErrors" }] : /* istanbul ignore next */ []));
|
|
1000
|
+
displayedErrors = computed(() => this.showAllErrors() ? this.resolvedErrors() : this.resolvedErrors().slice(0, 1), /* @ts-ignore */
|
|
827
1001
|
...(ngDevMode ? [{ debugName: "displayedErrors" }] : /* istanbul ignore next */ []));
|
|
828
1002
|
resolvedAriaLabel = computed(() => this.ariaLabel() ?? null, /* @ts-ignore */
|
|
829
1003
|
...(ngDevMode ? [{ debugName: "resolvedAriaLabel" }] : /* istanbul ignore next */ []));
|
|
@@ -831,7 +1005,7 @@ class KtCheckboxGroup {
|
|
|
831
1005
|
const ids = [];
|
|
832
1006
|
if (this.hint() && !this.showInvalid())
|
|
833
1007
|
ids.push(this.hintId());
|
|
834
|
-
if (this.showInvalid() && this.
|
|
1008
|
+
if (this.showInvalid() && this.resolvedErrors().length > 0)
|
|
835
1009
|
ids.push(this.errorId());
|
|
836
1010
|
return ids.length ? ids.join(' ') : null;
|
|
837
1011
|
}, /* @ts-ignore */
|
|
@@ -844,6 +1018,10 @@ class KtCheckboxGroup {
|
|
|
844
1018
|
const cmp = this.comparator();
|
|
845
1019
|
return arr.some((v) => cmp(v, optionValue));
|
|
846
1020
|
}
|
|
1021
|
+
/** Focus la première case activable (utilisé par Signal Forms `focusBoundControl`). */
|
|
1022
|
+
focus(options) {
|
|
1023
|
+
this.el.nativeElement.querySelector('input[type="checkbox"]:not([disabled])')?.focus(options);
|
|
1024
|
+
}
|
|
847
1025
|
/** Ajoute/retire une valeur d'option de la sélection (émis par un enfant au `change` natif). */
|
|
848
1026
|
toggle(optionValue, checked) {
|
|
849
1027
|
if (this.disabled())
|
|
@@ -860,7 +1038,7 @@ class KtCheckboxGroup {
|
|
|
860
1038
|
this.touched.set(true);
|
|
861
1039
|
}
|
|
862
1040
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.1", ngImport: i0, type: KtCheckboxGroup, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
863
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.1", type: KtCheckboxGroup, isStandalone: true, selector: "kt-checkbox-group", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, touched: { classPropertyName: "touched", publicName: "touched", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, invalid: { classPropertyName: "invalid", publicName: "invalid", isSignal: true, isRequired: false, transformFunction: null }, required: { classPropertyName: "required", publicName: "required", isSignal: true, isRequired: false, transformFunction: null }, dirty: { classPropertyName: "dirty", publicName: "dirty", isSignal: true, isRequired: false, transformFunction: null }, errors: { classPropertyName: "errors", publicName: "errors", isSignal: true, isRequired: false, transformFunction: null }, name: { classPropertyName: "name", publicName: "name", isSignal: true, isRequired: false, transformFunction: null }, id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, hint: { classPropertyName: "hint", publicName: "hint", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, errorMatcher: { classPropertyName: "errorMatcher", publicName: "errorMatcher", isSignal: true, isRequired: false, transformFunction: null }, showAllErrors: { classPropertyName: "showAllErrors", publicName: "showAllErrors", isSignal: true, isRequired: false, transformFunction: null }, compareWith: { classPropertyName: "compareWith", publicName: "compareWith", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange", touched: "touchedChange" }, ngImport: i0, template: `
|
|
1041
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.1", type: KtCheckboxGroup, isStandalone: true, selector: "kt-checkbox-group", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, touched: { classPropertyName: "touched", publicName: "touched", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, invalid: { classPropertyName: "invalid", publicName: "invalid", isSignal: true, isRequired: false, transformFunction: null }, required: { classPropertyName: "required", publicName: "required", isSignal: true, isRequired: false, transformFunction: null }, dirty: { classPropertyName: "dirty", publicName: "dirty", isSignal: true, isRequired: false, transformFunction: null }, pending: { classPropertyName: "pending", publicName: "pending", isSignal: true, isRequired: false, transformFunction: null }, errors: { classPropertyName: "errors", publicName: "errors", isSignal: true, isRequired: false, transformFunction: null }, name: { classPropertyName: "name", publicName: "name", isSignal: true, isRequired: false, transformFunction: null }, id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, hint: { classPropertyName: "hint", publicName: "hint", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, errorMatcher: { classPropertyName: "errorMatcher", publicName: "errorMatcher", isSignal: true, isRequired: false, transformFunction: null }, showAllErrors: { classPropertyName: "showAllErrors", publicName: "showAllErrors", isSignal: true, isRequired: false, transformFunction: null }, compareWith: { classPropertyName: "compareWith", publicName: "compareWith", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange", touched: "touchedChange" }, ngImport: i0, template: `
|
|
864
1042
|
<div
|
|
865
1043
|
class="kt-checkbox-group-field"
|
|
866
1044
|
[class.kt-checkbox-group-field--invalid]="showInvalid()"
|
|
@@ -871,6 +1049,8 @@ class KtCheckboxGroup {
|
|
|
871
1049
|
[attr.aria-describedby]="describedBy()"
|
|
872
1050
|
[attr.aria-required]="required() ? 'true' : null"
|
|
873
1051
|
[attr.aria-invalid]="showInvalid() ? 'true' : null"
|
|
1052
|
+
[attr.aria-busy]="pending() ? 'true' : null"
|
|
1053
|
+
[attr.data-pending]="pending() ? '' : null"
|
|
874
1054
|
>
|
|
875
1055
|
@if (label(); as labelText) {
|
|
876
1056
|
<span [id]="labelId()" class="kt-checkbox-group__legend">
|
|
@@ -896,7 +1076,7 @@ class KtCheckboxGroup {
|
|
|
896
1076
|
}
|
|
897
1077
|
</div>
|
|
898
1078
|
</div>
|
|
899
|
-
`, isInline: true, styles: ["@layer kt-aaa.components{:host{display:block}.kt-checkbox-group-field{display:flex;flex-direction:column;gap:var(--field-gap, .375rem)}.kt-checkbox-group__legend{font-size:var(--field-label-font-size, .875rem);font-weight:var(--field-label-weight, 500);color:var(--field-label-color, inherit)}.kt-checkbox-group__required{margin-inline-start:.125rem;color:var(--field-required-color, var(--kt-danger, #8c1d18))}.kt-checkbox-
|
|
1079
|
+
`, isInline: true, styles: ["@layer kt-aaa.components{:host{display:block}.kt-checkbox-group-field{display:flex;flex-direction:column;gap:var(--field-gap, .375rem)}.kt-checkbox-group__legend{font-size:var(--field-label-font-size, .875rem);font-weight:var(--field-label-weight, 500);color:var(--field-label-color, inherit)}.kt-checkbox-group__required{margin-inline-start:.125rem;color:var(--field-required-color, var(--kt-danger, #8c1d18))}.kt-checkbox-group__hint{margin:0;font-size:var(--field-hint-font-size, .8125rem);color:var(--field-hint-color, #474747)}.kt-checkbox-group__error{margin:0;display:flex;flex-direction:column;font-size:var(--field-hint-font-size, .8125rem);color:var(--field-error-color, #8c1d18)}.kt-checkbox-group__error-message{animation:var(--field-error-animation, none)}@media(prefers-reduced-motion:reduce){.kt-checkbox-group__error-message{animation:none}}}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
900
1080
|
}
|
|
901
1081
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.1", ngImport: i0, type: KtCheckboxGroup, decorators: [{
|
|
902
1082
|
type: Component,
|
|
@@ -911,6 +1091,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.1", ngImpor
|
|
|
911
1091
|
[attr.aria-describedby]="describedBy()"
|
|
912
1092
|
[attr.aria-required]="required() ? 'true' : null"
|
|
913
1093
|
[attr.aria-invalid]="showInvalid() ? 'true' : null"
|
|
1094
|
+
[attr.aria-busy]="pending() ? 'true' : null"
|
|
1095
|
+
[attr.data-pending]="pending() ? '' : null"
|
|
914
1096
|
>
|
|
915
1097
|
@if (label(); as labelText) {
|
|
916
1098
|
<span [id]="labelId()" class="kt-checkbox-group__legend">
|
|
@@ -936,8 +1118,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.1", ngImpor
|
|
|
936
1118
|
}
|
|
937
1119
|
</div>
|
|
938
1120
|
</div>
|
|
939
|
-
`, styles: ["@layer kt-aaa.components{:host{display:block}.kt-checkbox-group-field{display:flex;flex-direction:column;gap:var(--field-gap, .375rem)}.kt-checkbox-group__legend{font-size:var(--field-label-font-size, .875rem);font-weight:var(--field-label-weight, 500);color:var(--field-label-color, inherit)}.kt-checkbox-group__required{margin-inline-start:.125rem;color:var(--field-required-color, var(--kt-danger, #8c1d18))}.kt-checkbox-
|
|
940
|
-
}], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }, { type: i0.Output, args: ["valueChange"] }], touched: [{ type: i0.Input, args: [{ isSignal: true, alias: "touched", required: false }] }, { type: i0.Output, args: ["touchedChange"] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], invalid: [{ type: i0.Input, args: [{ isSignal: true, alias: "invalid", required: false }] }], required: [{ type: i0.Input, args: [{ isSignal: true, alias: "required", required: false }] }], dirty: [{ type: i0.Input, args: [{ isSignal: true, alias: "dirty", required: false }] }], errors: [{ type: i0.Input, args: [{ isSignal: true, alias: "errors", required: false }] }], name: [{ type: i0.Input, args: [{ isSignal: true, alias: "name", required: false }] }], id: [{ type: i0.Input, args: [{ isSignal: true, alias: "id", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], hint: [{ type: i0.Input, args: [{ isSignal: true, alias: "hint", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], errorMatcher: [{ type: i0.Input, args: [{ isSignal: true, alias: "errorMatcher", required: false }] }], showAllErrors: [{ type: i0.Input, args: [{ isSignal: true, alias: "showAllErrors", required: false }] }], compareWith: [{ type: i0.Input, args: [{ isSignal: true, alias: "compareWith", required: false }] }] } });
|
|
1121
|
+
`, styles: ["@layer kt-aaa.components{:host{display:block}.kt-checkbox-group-field{display:flex;flex-direction:column;gap:var(--field-gap, .375rem)}.kt-checkbox-group__legend{font-size:var(--field-label-font-size, .875rem);font-weight:var(--field-label-weight, 500);color:var(--field-label-color, inherit)}.kt-checkbox-group__required{margin-inline-start:.125rem;color:var(--field-required-color, var(--kt-danger, #8c1d18))}.kt-checkbox-group__hint{margin:0;font-size:var(--field-hint-font-size, .8125rem);color:var(--field-hint-color, #474747)}.kt-checkbox-group__error{margin:0;display:flex;flex-direction:column;font-size:var(--field-hint-font-size, .8125rem);color:var(--field-error-color, #8c1d18)}.kt-checkbox-group__error-message{animation:var(--field-error-animation, none)}@media(prefers-reduced-motion:reduce){.kt-checkbox-group__error-message{animation:none}}}\n"] }]
|
|
1122
|
+
}], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }, { type: i0.Output, args: ["valueChange"] }], touched: [{ type: i0.Input, args: [{ isSignal: true, alias: "touched", required: false }] }, { type: i0.Output, args: ["touchedChange"] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], invalid: [{ type: i0.Input, args: [{ isSignal: true, alias: "invalid", required: false }] }], required: [{ type: i0.Input, args: [{ isSignal: true, alias: "required", required: false }] }], dirty: [{ type: i0.Input, args: [{ isSignal: true, alias: "dirty", required: false }] }], pending: [{ type: i0.Input, args: [{ isSignal: true, alias: "pending", required: false }] }], errors: [{ type: i0.Input, args: [{ isSignal: true, alias: "errors", required: false }] }], name: [{ type: i0.Input, args: [{ isSignal: true, alias: "name", required: false }] }], id: [{ type: i0.Input, args: [{ isSignal: true, alias: "id", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], hint: [{ type: i0.Input, args: [{ isSignal: true, alias: "hint", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], errorMatcher: [{ type: i0.Input, args: [{ isSignal: true, alias: "errorMatcher", required: false }] }], showAllErrors: [{ type: i0.Input, args: [{ isSignal: true, alias: "showAllErrors", required: false }] }], compareWith: [{ type: i0.Input, args: [{ isSignal: true, alias: "compareWith", required: false }] }] } });
|
|
941
1123
|
|
|
942
1124
|
/**
|
|
943
1125
|
* Case à cocher (Checkbox) accessible conforme aux normes WAI-ARIA / RGAA.
|
|
@@ -992,6 +1174,8 @@ class KtCheckbox {
|
|
|
992
1174
|
required = input(false, { ...(ngDevMode ? { debugName: "required" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
993
1175
|
/** État « modifié » (entre dans la logique d'affichage des erreurs). @default false */
|
|
994
1176
|
dirty = input(false, { ...(ngDevMode ? { debugName: "dirty" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
1177
|
+
/** Validation asynchrone en cours (poussé par `[field]`) : pose `aria-busy` + `data-pending`. @default false */
|
|
1178
|
+
pending = input(false, { ...(ngDevMode ? { debugName: "pending" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
995
1179
|
/** Erreurs de validation à afficher sous la case. @default [] */
|
|
996
1180
|
errors = input([], /* @ts-ignore */
|
|
997
1181
|
...(ngDevMode ? [{ debugName: "errors" }] : /* istanbul ignore next */ []));
|
|
@@ -1018,6 +1202,7 @@ class KtCheckbox {
|
|
|
1018
1202
|
showAllErrors = input(this.config?.showAllErrors ?? false, { ...(ngDevMode ? { debugName: "showAllErrors" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
1019
1203
|
inputEl = viewChild.required('input');
|
|
1020
1204
|
el = inject(ElementRef);
|
|
1205
|
+
errorResolver = inject(KtFieldErrorResolver);
|
|
1021
1206
|
idGen = inject(KtIdGenerator);
|
|
1022
1207
|
uid = this.idGen.generateId('checkbox');
|
|
1023
1208
|
baseId = computed(() => this.id() ?? `kt-checkbox-${this.uid}`, /* @ts-ignore */
|
|
@@ -1037,7 +1222,10 @@ class KtCheckbox {
|
|
|
1037
1222
|
...(ngDevMode ? [{ debugName: "matcher" }] : /* istanbul ignore next */ []));
|
|
1038
1223
|
showInvalid = computed(() => this.matcher()({ invalid: this.invalid(), touched: this.touched(), dirty: this.dirty() }), /* @ts-ignore */
|
|
1039
1224
|
...(ngDevMode ? [{ debugName: "showInvalid" }] : /* istanbul ignore next */ []));
|
|
1040
|
-
|
|
1225
|
+
/** Erreurs résolues (messages par défaut appliqués, suppressions `message: ''` écartées). */
|
|
1226
|
+
resolvedErrors = computed(() => this.errorResolver.resolveAll(this.errors()), /* @ts-ignore */
|
|
1227
|
+
...(ngDevMode ? [{ debugName: "resolvedErrors" }] : /* istanbul ignore next */ []));
|
|
1228
|
+
displayedErrors = computed(() => this.showAllErrors() ? this.resolvedErrors() : this.resolvedErrors().slice(0, 1), /* @ts-ignore */
|
|
1041
1229
|
...(ngDevMode ? [{ debugName: "displayedErrors" }] : /* istanbul ignore next */ []));
|
|
1042
1230
|
resolvedAriaLabel = computed(() => this.ariaLabel() ?? null, /* @ts-ignore */
|
|
1043
1231
|
...(ngDevMode ? [{ debugName: "resolvedAriaLabel" }] : /* istanbul ignore next */ []));
|
|
@@ -1045,7 +1233,7 @@ class KtCheckbox {
|
|
|
1045
1233
|
const ids = [];
|
|
1046
1234
|
if (this.hint() && !this.showInvalid())
|
|
1047
1235
|
ids.push(this.hintId());
|
|
1048
|
-
if (this.showInvalid() && this.
|
|
1236
|
+
if (this.showInvalid() && this.resolvedErrors().length > 0)
|
|
1049
1237
|
ids.push(this.errorId());
|
|
1050
1238
|
return ids.length ? ids.join(' ') : null;
|
|
1051
1239
|
}, /* @ts-ignore */
|
|
@@ -1060,12 +1248,19 @@ class KtCheckbox {
|
|
|
1060
1248
|
afterNextRender(() => {
|
|
1061
1249
|
if (!isDevMode() || this.label() || this.ariaLabel())
|
|
1062
1250
|
return;
|
|
1063
|
-
const labelText = this.el.nativeElement
|
|
1251
|
+
const labelText = this.el.nativeElement
|
|
1252
|
+
.querySelector('.kt-checkbox__label')
|
|
1253
|
+
?.textContent?.replace('*', '')
|
|
1254
|
+
.trim();
|
|
1064
1255
|
if (!labelText) {
|
|
1065
1256
|
console.warn('[ktCheckbox] sans `label`, `ariaLabel` ni contenu projeté : annoncée sans nom accessible (WCAG 4.1.2).');
|
|
1066
1257
|
}
|
|
1067
1258
|
});
|
|
1068
1259
|
}
|
|
1260
|
+
/** Focus la case native (utilisé par Signal Forms `focusBoundControl`). */
|
|
1261
|
+
focus(options) {
|
|
1262
|
+
this.inputEl().nativeElement.focus(options);
|
|
1263
|
+
}
|
|
1069
1264
|
onChange(event) {
|
|
1070
1265
|
if (this.isDisabled())
|
|
1071
1266
|
return;
|
|
@@ -1082,11 +1277,12 @@ class KtCheckbox {
|
|
|
1082
1277
|
(this.group?.touched ?? this.touched).set(true);
|
|
1083
1278
|
}
|
|
1084
1279
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.1", ngImport: i0, type: KtCheckbox, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1085
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.1", type: KtCheckbox, isStandalone: true, selector: "kt-checkbox", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, optionValue: { classPropertyName: "optionValue", publicName: "optionValue", isSignal: true, isRequired: false, transformFunction: null }, indeterminate: { classPropertyName: "indeterminate", publicName: "indeterminate", isSignal: true, isRequired: false, transformFunction: null }, touched: { classPropertyName: "touched", publicName: "touched", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, invalid: { classPropertyName: "invalid", publicName: "invalid", isSignal: true, isRequired: false, transformFunction: null }, required: { classPropertyName: "required", publicName: "required", isSignal: true, isRequired: false, transformFunction: null }, dirty: { classPropertyName: "dirty", publicName: "dirty", isSignal: true, isRequired: false, transformFunction: null }, errors: { classPropertyName: "errors", publicName: "errors", isSignal: true, isRequired: false, transformFunction: null }, name: { classPropertyName: "name", publicName: "name", isSignal: true, isRequired: false, transformFunction: null }, id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, hint: { classPropertyName: "hint", publicName: "hint", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, errorMatcher: { classPropertyName: "errorMatcher", publicName: "errorMatcher", isSignal: true, isRequired: false, transformFunction: null }, showAllErrors: { classPropertyName: "showAllErrors", publicName: "showAllErrors", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange", touched: "touchedChange" }, viewQueries: [{ propertyName: "inputEl", first: true, predicate: ["input"], descendants: true, isSignal: true }], ngImport: i0, template: `
|
|
1280
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.1", type: KtCheckbox, isStandalone: true, selector: "kt-checkbox", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, optionValue: { classPropertyName: "optionValue", publicName: "optionValue", isSignal: true, isRequired: false, transformFunction: null }, indeterminate: { classPropertyName: "indeterminate", publicName: "indeterminate", isSignal: true, isRequired: false, transformFunction: null }, touched: { classPropertyName: "touched", publicName: "touched", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, invalid: { classPropertyName: "invalid", publicName: "invalid", isSignal: true, isRequired: false, transformFunction: null }, required: { classPropertyName: "required", publicName: "required", isSignal: true, isRequired: false, transformFunction: null }, dirty: { classPropertyName: "dirty", publicName: "dirty", isSignal: true, isRequired: false, transformFunction: null }, pending: { classPropertyName: "pending", publicName: "pending", isSignal: true, isRequired: false, transformFunction: null }, errors: { classPropertyName: "errors", publicName: "errors", isSignal: true, isRequired: false, transformFunction: null }, name: { classPropertyName: "name", publicName: "name", isSignal: true, isRequired: false, transformFunction: null }, id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, hint: { classPropertyName: "hint", publicName: "hint", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, errorMatcher: { classPropertyName: "errorMatcher", publicName: "errorMatcher", isSignal: true, isRequired: false, transformFunction: null }, showAllErrors: { classPropertyName: "showAllErrors", publicName: "showAllErrors", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange", touched: "touchedChange" }, viewQueries: [{ propertyName: "inputEl", first: true, predicate: ["input"], descendants: true, isSignal: true }], ngImport: i0, template: `
|
|
1086
1281
|
<div
|
|
1087
1282
|
class="kt-checkbox-field"
|
|
1088
1283
|
[class.kt-checkbox-field--invalid]="showInvalid()"
|
|
1089
1284
|
[class.kt-checkbox-field--disabled]="isDisabled()"
|
|
1285
|
+
[attr.data-pending]="pending() ? '' : null"
|
|
1090
1286
|
>
|
|
1091
1287
|
<label class="kt-checkbox">
|
|
1092
1288
|
<input
|
|
@@ -1101,6 +1297,7 @@ class KtCheckbox {
|
|
|
1101
1297
|
[attr.aria-describedby]="describedBy()"
|
|
1102
1298
|
[attr.aria-invalid]="showInvalid() ? 'true' : null"
|
|
1103
1299
|
[attr.aria-required]="required() ? 'true' : null"
|
|
1300
|
+
[attr.aria-busy]="pending() ? 'true' : null"
|
|
1104
1301
|
(change)="onChange($event)"
|
|
1105
1302
|
(blur)="onBlur()"
|
|
1106
1303
|
/>
|
|
@@ -1132,6 +1329,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.1", ngImpor
|
|
|
1132
1329
|
class="kt-checkbox-field"
|
|
1133
1330
|
[class.kt-checkbox-field--invalid]="showInvalid()"
|
|
1134
1331
|
[class.kt-checkbox-field--disabled]="isDisabled()"
|
|
1332
|
+
[attr.data-pending]="pending() ? '' : null"
|
|
1135
1333
|
>
|
|
1136
1334
|
<label class="kt-checkbox">
|
|
1137
1335
|
<input
|
|
@@ -1146,6 +1344,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.1", ngImpor
|
|
|
1146
1344
|
[attr.aria-describedby]="describedBy()"
|
|
1147
1345
|
[attr.aria-invalid]="showInvalid() ? 'true' : null"
|
|
1148
1346
|
[attr.aria-required]="required() ? 'true' : null"
|
|
1347
|
+
[attr.aria-busy]="pending() ? 'true' : null"
|
|
1149
1348
|
(change)="onChange($event)"
|
|
1150
1349
|
(blur)="onBlur()"
|
|
1151
1350
|
/>
|
|
@@ -1169,7 +1368,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.1", ngImpor
|
|
|
1169
1368
|
</div>
|
|
1170
1369
|
</div>
|
|
1171
1370
|
`, styles: ["@layer kt-aaa.components{:host{display:block}.kt-checkbox-field{display:flex;flex-direction:column;gap:var(--field-gap, .375rem)}.kt-checkbox{display:flex;align-items:center;gap:var(--field-control-gap, .5rem);inline-size:100%;box-sizing:border-box;min-block-size:var(--checkbox-target-size, 44px);padding:var(--checkbox-padding, 0);border-radius:inherit;cursor:pointer;-webkit-user-select:none;user-select:none}.kt-checkbox__input{appearance:none;-webkit-appearance:none;margin:0;flex:none;box-sizing:border-box;display:grid;place-content:center;font-size:var(--checkbox-size, 1.25rem);inline-size:1em;block-size:1em;border:var(--checkbox-border-width, 2px) solid var(--checkbox-border-color, var(--field-border-color, var(--kt-outline, #c4c7c5)));border-radius:var(--checkbox-radius, .25rem);background-color:var(--checkbox-bg, var(--field-bg, var(--kt-surface, #ffffff)));cursor:pointer;box-shadow:var(--checkbox-shadow, var(--field-shadow, none));transition:var( --checkbox-transition, background-color .15s cubic-bezier(.4, 0, .2, 1), border-color .15s cubic-bezier(.4, 0, .2, 1), box-shadow .2s ease )}.kt-checkbox__input:before{content:\"\";inline-size:.65em;block-size:.65em;transform:scale(0);transform-origin:center;box-shadow:inset 1em 1em var(--checkbox-mark-color, #ffffff);clip-path:polygon(14% 44%,0 65%,50% 100%,100% 16%,80% 0%,43% 62%);transition:var(--checkbox-mark-transition, transform .12s ease-in)}.kt-checkbox__input:checked:before,.kt-checkbox__input:indeterminate:before{transform:scale(1);animation:var(--checkbox-mark-animation, kt-checkbox-pop .22s cubic-bezier(.34, 1.56, .64, 1))}.kt-checkbox__input:indeterminate:before{clip-path:inset(42% 12%)}@keyframes kt-checkbox-pop{0%{transform:scale(0)}}.kt-checkbox__input:checked,.kt-checkbox__input:indeterminate{background-color:var(--checkbox-bg-checked, var(--kt-primary, #0842a0));border-color:var(--checkbox-border-color-checked, var(--checkbox-bg-checked, var(--kt-primary, #0842a0)));box-shadow:var( --checkbox-shadow-checked, 0 0 8px color-mix(in srgb, var(--checkbox-bg-checked, var(--kt-primary, #0842a0)) 50%, transparent) )}.kt-checkbox__input:hover:not(:disabled){border-color:var( --checkbox-border-color-hover, var(--field-border-color-hover, var(--kt-outline-strong, #5f6368)) );box-shadow:var( --checkbox-shadow-hover, var(--field-shadow-hover, var(--checkbox-shadow, var(--field-shadow, none))) )}.kt-checkbox__input:checked:hover:not(:disabled),.kt-checkbox__input:indeterminate:hover:not(:disabled){background-color:var(--checkbox-bg-checked-hover, color-mix(in srgb, var(--kt-primary, #0842a0) 90%, black));border-color:var(--checkbox-bg-checked-hover, color-mix(in srgb, var(--kt-primary, #0842a0) 90%, black))}.kt-checkbox__input:focus-visible{outline:var(--kt-focus-ring-width, 2px) solid var(--kt-focus-ring-color, #0842a0);outline-offset:var(--checkbox-focus-ring-offset, 2px);box-shadow:var(--checkbox-shadow-focus, var(--field-shadow-focus, var(--field-shadow, none)))}.kt-checkbox__input:disabled{cursor:not-allowed;opacity:.5}.kt-checkbox-field--disabled .kt-checkbox{cursor:not-allowed}.kt-checkbox-field--invalid .kt-checkbox__input:not(:checked):not(:indeterminate){border-color:var(--field-error-color, var(--kt-danger, #8c1d18))}.kt-checkbox__label{font-size:var(--field-label-font-size, .875rem);font-weight:var(--field-label-weight, 500);color:var(--field-label-color, inherit)}.kt-checkbox-field--disabled .kt-checkbox__label{color:var(--field-hint-color, #5f6368);opacity:.6}.kt-checkbox__required{margin-inline-start:.125rem;color:var(--field-required-color, var(--kt-danger, #8c1d18))}.kt-checkbox-hint{margin:0;font-size:var(--field-hint-font-size, .8125rem);color:var(--field-hint-color, #474747)}.kt-checkbox-error{margin:0;display:flex;flex-direction:column;font-size:var(--field-hint-font-size, .8125rem);color:var(--field-error-color, #8c1d18)}.kt-checkbox-error-message{animation:var(--field-error-animation, none)}@media(forced-colors:active){.kt-checkbox__input{border-color:CanvasText;background-color:Canvas}.kt-checkbox__input:checked,.kt-checkbox__input:indeterminate{background-color:Highlight;border-color:Highlight}.kt-checkbox__input:before{box-shadow:inset 1em 1em HighlightText}.kt-checkbox__input:disabled{border-color:GrayText}.kt-checkbox__input:focus-visible{outline:2px solid CanvasText;outline-offset:2px}}@media(prefers-reduced-motion:reduce){.kt-checkbox__input,.kt-checkbox__input:before{transition:none;animation:none}.kt-checkbox-error-message{animation:none}}}\n"] }]
|
|
1172
|
-
}], ctorParameters: () => [], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }, { type: i0.Output, args: ["valueChange"] }], optionValue: [{ type: i0.Input, args: [{ isSignal: true, alias: "optionValue", required: false }] }], indeterminate: [{ type: i0.Input, args: [{ isSignal: true, alias: "indeterminate", required: false }] }], touched: [{ type: i0.Input, args: [{ isSignal: true, alias: "touched", required: false }] }, { type: i0.Output, args: ["touchedChange"] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], invalid: [{ type: i0.Input, args: [{ isSignal: true, alias: "invalid", required: false }] }], required: [{ type: i0.Input, args: [{ isSignal: true, alias: "required", required: false }] }], dirty: [{ type: i0.Input, args: [{ isSignal: true, alias: "dirty", required: false }] }], errors: [{ type: i0.Input, args: [{ isSignal: true, alias: "errors", required: false }] }], name: [{ type: i0.Input, args: [{ isSignal: true, alias: "name", required: false }] }], id: [{ type: i0.Input, args: [{ isSignal: true, alias: "id", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], hint: [{ type: i0.Input, args: [{ isSignal: true, alias: "hint", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], errorMatcher: [{ type: i0.Input, args: [{ isSignal: true, alias: "errorMatcher", required: false }] }], showAllErrors: [{ type: i0.Input, args: [{ isSignal: true, alias: "showAllErrors", required: false }] }], inputEl: [{ type: i0.ViewChild, args: ['input', { isSignal: true }] }] } });
|
|
1371
|
+
}], ctorParameters: () => [], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }, { type: i0.Output, args: ["valueChange"] }], optionValue: [{ type: i0.Input, args: [{ isSignal: true, alias: "optionValue", required: false }] }], indeterminate: [{ type: i0.Input, args: [{ isSignal: true, alias: "indeterminate", required: false }] }], touched: [{ type: i0.Input, args: [{ isSignal: true, alias: "touched", required: false }] }, { type: i0.Output, args: ["touchedChange"] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], invalid: [{ type: i0.Input, args: [{ isSignal: true, alias: "invalid", required: false }] }], required: [{ type: i0.Input, args: [{ isSignal: true, alias: "required", required: false }] }], dirty: [{ type: i0.Input, args: [{ isSignal: true, alias: "dirty", required: false }] }], pending: [{ type: i0.Input, args: [{ isSignal: true, alias: "pending", required: false }] }], errors: [{ type: i0.Input, args: [{ isSignal: true, alias: "errors", required: false }] }], name: [{ type: i0.Input, args: [{ isSignal: true, alias: "name", required: false }] }], id: [{ type: i0.Input, args: [{ isSignal: true, alias: "id", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], hint: [{ type: i0.Input, args: [{ isSignal: true, alias: "hint", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], errorMatcher: [{ type: i0.Input, args: [{ isSignal: true, alias: "errorMatcher", required: false }] }], showAllErrors: [{ type: i0.Input, args: [{ isSignal: true, alias: "showAllErrors", required: false }] }], inputEl: [{ type: i0.ViewChild, args: ['input', { isSignal: true }] }] } });
|
|
1173
1372
|
|
|
1174
1373
|
/**
|
|
1175
1374
|
* Groupe de boutons radio (Radio Group) conforme à l'ARIA APG / RGAA.
|
|
@@ -1207,6 +1406,8 @@ class KtRadioGroup {
|
|
|
1207
1406
|
required = input(false, { ...(ngDevMode ? { debugName: "required" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
1208
1407
|
/** État « modifié » (entre dans la logique d'affichage des erreurs). @default false */
|
|
1209
1408
|
dirty = input(false, { ...(ngDevMode ? { debugName: "dirty" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
1409
|
+
/** Validation asynchrone en cours (poussé par `[field]`) : pose `aria-busy` + `data-pending`. @default false */
|
|
1410
|
+
pending = input(false, { ...(ngDevMode ? { debugName: "pending" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
1210
1411
|
/** Erreurs de validation à afficher sous le groupe. @default [] */
|
|
1211
1412
|
errors = input([], /* @ts-ignore */
|
|
1212
1413
|
...(ngDevMode ? [{ debugName: "errors" }] : /* istanbul ignore next */ []));
|
|
@@ -1234,6 +1435,8 @@ class KtRadioGroup {
|
|
|
1234
1435
|
/** Égalité des valeurs en mode objet (défaut : identité `===`). Seul rescapé du contrat select. */
|
|
1235
1436
|
compareWith = input(/* @ts-ignore */
|
|
1236
1437
|
...(ngDevMode ? [undefined, { debugName: "compareWith" }] : /* istanbul ignore next */ []));
|
|
1438
|
+
el = inject(ElementRef);
|
|
1439
|
+
errorResolver = inject(KtFieldErrorResolver);
|
|
1237
1440
|
idGen = inject(KtIdGenerator);
|
|
1238
1441
|
uid = this.idGen.generateId('radio-group');
|
|
1239
1442
|
baseId = computed(() => this.id() ?? `kt-radio-group-${this.uid}`, /* @ts-ignore */
|
|
@@ -1251,7 +1454,10 @@ class KtRadioGroup {
|
|
|
1251
1454
|
...(ngDevMode ? [{ debugName: "matcher" }] : /* istanbul ignore next */ []));
|
|
1252
1455
|
showInvalid = computed(() => this.matcher()({ invalid: this.invalid(), touched: this.touched(), dirty: this.dirty() }), /* @ts-ignore */
|
|
1253
1456
|
...(ngDevMode ? [{ debugName: "showInvalid" }] : /* istanbul ignore next */ []));
|
|
1254
|
-
|
|
1457
|
+
/** Erreurs résolues (messages par défaut appliqués, suppressions `message: ''` écartées). */
|
|
1458
|
+
resolvedErrors = computed(() => this.errorResolver.resolveAll(this.errors()), /* @ts-ignore */
|
|
1459
|
+
...(ngDevMode ? [{ debugName: "resolvedErrors" }] : /* istanbul ignore next */ []));
|
|
1460
|
+
displayedErrors = computed(() => this.showAllErrors() ? this.resolvedErrors() : this.resolvedErrors().slice(0, 1), /* @ts-ignore */
|
|
1255
1461
|
...(ngDevMode ? [{ debugName: "displayedErrors" }] : /* istanbul ignore next */ []));
|
|
1256
1462
|
resolvedAriaLabel = computed(() => this.ariaLabel() ?? null, /* @ts-ignore */
|
|
1257
1463
|
...(ngDevMode ? [{ debugName: "resolvedAriaLabel" }] : /* istanbul ignore next */ []));
|
|
@@ -1259,7 +1465,7 @@ class KtRadioGroup {
|
|
|
1259
1465
|
const ids = [];
|
|
1260
1466
|
if (this.hint() && !this.showInvalid())
|
|
1261
1467
|
ids.push(this.hintId());
|
|
1262
|
-
if (this.showInvalid() && this.
|
|
1468
|
+
if (this.showInvalid() && this.resolvedErrors().length > 0)
|
|
1263
1469
|
ids.push(this.errorId());
|
|
1264
1470
|
return ids.length ? ids.join(' ') : null;
|
|
1265
1471
|
}, /* @ts-ignore */
|
|
@@ -1273,6 +1479,14 @@ class KtRadioGroup {
|
|
|
1273
1479
|
return false;
|
|
1274
1480
|
return this.comparator()(radioValue, v);
|
|
1275
1481
|
}
|
|
1482
|
+
/** Focus l'option pertinente (utilisé par Signal Forms `focusBoundControl`) : le radio coché
|
|
1483
|
+
s'il existe, sinon le premier radio activable — conforme au roving tabindex natif. */
|
|
1484
|
+
focus(options) {
|
|
1485
|
+
const root = this.el.nativeElement;
|
|
1486
|
+
const target = root.querySelector('input[type="radio"]:checked') ??
|
|
1487
|
+
root.querySelector('input[type="radio"]:not([disabled])');
|
|
1488
|
+
target?.focus(options);
|
|
1489
|
+
}
|
|
1276
1490
|
/** Commit d'une sélection émis par un enfant au `change` natif. */
|
|
1277
1491
|
select(radioValue) {
|
|
1278
1492
|
if (this.disabled())
|
|
@@ -1281,7 +1495,7 @@ class KtRadioGroup {
|
|
|
1281
1495
|
this.touched.set(true);
|
|
1282
1496
|
}
|
|
1283
1497
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.1", ngImport: i0, type: KtRadioGroup, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1284
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.1", type: KtRadioGroup, isStandalone: true, selector: "kt-radio-group", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, touched: { classPropertyName: "touched", publicName: "touched", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, invalid: { classPropertyName: "invalid", publicName: "invalid", isSignal: true, isRequired: false, transformFunction: null }, required: { classPropertyName: "required", publicName: "required", isSignal: true, isRequired: false, transformFunction: null }, dirty: { classPropertyName: "dirty", publicName: "dirty", isSignal: true, isRequired: false, transformFunction: null }, errors: { classPropertyName: "errors", publicName: "errors", isSignal: true, isRequired: false, transformFunction: null }, name: { classPropertyName: "name", publicName: "name", isSignal: true, isRequired: false, transformFunction: null }, id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, hint: { classPropertyName: "hint", publicName: "hint", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, errorMatcher: { classPropertyName: "errorMatcher", publicName: "errorMatcher", isSignal: true, isRequired: false, transformFunction: null }, showAllErrors: { classPropertyName: "showAllErrors", publicName: "showAllErrors", isSignal: true, isRequired: false, transformFunction: null }, compareWith: { classPropertyName: "compareWith", publicName: "compareWith", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange", touched: "touchedChange" }, ngImport: i0, template: `
|
|
1498
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.1", type: KtRadioGroup, isStandalone: true, selector: "kt-radio-group", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, touched: { classPropertyName: "touched", publicName: "touched", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, invalid: { classPropertyName: "invalid", publicName: "invalid", isSignal: true, isRequired: false, transformFunction: null }, required: { classPropertyName: "required", publicName: "required", isSignal: true, isRequired: false, transformFunction: null }, dirty: { classPropertyName: "dirty", publicName: "dirty", isSignal: true, isRequired: false, transformFunction: null }, pending: { classPropertyName: "pending", publicName: "pending", isSignal: true, isRequired: false, transformFunction: null }, errors: { classPropertyName: "errors", publicName: "errors", isSignal: true, isRequired: false, transformFunction: null }, name: { classPropertyName: "name", publicName: "name", isSignal: true, isRequired: false, transformFunction: null }, id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, hint: { classPropertyName: "hint", publicName: "hint", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, errorMatcher: { classPropertyName: "errorMatcher", publicName: "errorMatcher", isSignal: true, isRequired: false, transformFunction: null }, showAllErrors: { classPropertyName: "showAllErrors", publicName: "showAllErrors", isSignal: true, isRequired: false, transformFunction: null }, compareWith: { classPropertyName: "compareWith", publicName: "compareWith", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange", touched: "touchedChange" }, ngImport: i0, template: `
|
|
1285
1499
|
<div
|
|
1286
1500
|
class="kt-radio-group-field"
|
|
1287
1501
|
[class.kt-radio-group-field--invalid]="showInvalid()"
|
|
@@ -1292,6 +1506,8 @@ class KtRadioGroup {
|
|
|
1292
1506
|
[attr.aria-describedby]="describedBy()"
|
|
1293
1507
|
[attr.aria-required]="required() ? 'true' : null"
|
|
1294
1508
|
[attr.aria-invalid]="showInvalid() ? 'true' : null"
|
|
1509
|
+
[attr.aria-busy]="pending() ? 'true' : null"
|
|
1510
|
+
[attr.data-pending]="pending() ? '' : null"
|
|
1295
1511
|
>
|
|
1296
1512
|
@if (label(); as labelText) {
|
|
1297
1513
|
<span [id]="labelId()" class="kt-radio-group__legend">
|
|
@@ -1317,7 +1533,7 @@ class KtRadioGroup {
|
|
|
1317
1533
|
}
|
|
1318
1534
|
</div>
|
|
1319
1535
|
</div>
|
|
1320
|
-
`, isInline: true, styles: ["@layer kt-aaa.components{:host{display:block}.kt-radio-group-field{display:flex;flex-direction:column;gap:var(--field-gap, .375rem)}.kt-radio-group__legend{font-size:var(--field-label-font-size, .875rem);font-weight:var(--field-label-weight, 500);color:var(--field-label-color, inherit)}.kt-radio-group__required{margin-inline-start:.125rem;color:var(--field-required-color, var(--kt-danger, #8c1d18))}.kt-radio-
|
|
1536
|
+
`, isInline: true, styles: ["@layer kt-aaa.components{:host{display:block}.kt-radio-group-field{display:flex;flex-direction:column;gap:var(--field-gap, .375rem)}.kt-radio-group__legend{font-size:var(--field-label-font-size, .875rem);font-weight:var(--field-label-weight, 500);color:var(--field-label-color, inherit)}.kt-radio-group__required{margin-inline-start:.125rem;color:var(--field-required-color, var(--kt-danger, #8c1d18))}.kt-radio-group__hint{margin:0;font-size:var(--field-hint-font-size, .8125rem);color:var(--field-hint-color, #474747)}.kt-radio-group__error{margin:0;display:flex;flex-direction:column;font-size:var(--field-hint-font-size, .8125rem);color:var(--field-error-color, #8c1d18)}.kt-radio-group__error-message{animation:var(--field-error-animation, none)}@media(prefers-reduced-motion:reduce){.kt-radio-group__error-message{animation:none}}}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
1321
1537
|
}
|
|
1322
1538
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.1", ngImport: i0, type: KtRadioGroup, decorators: [{
|
|
1323
1539
|
type: Component,
|
|
@@ -1332,6 +1548,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.1", ngImpor
|
|
|
1332
1548
|
[attr.aria-describedby]="describedBy()"
|
|
1333
1549
|
[attr.aria-required]="required() ? 'true' : null"
|
|
1334
1550
|
[attr.aria-invalid]="showInvalid() ? 'true' : null"
|
|
1551
|
+
[attr.aria-busy]="pending() ? 'true' : null"
|
|
1552
|
+
[attr.data-pending]="pending() ? '' : null"
|
|
1335
1553
|
>
|
|
1336
1554
|
@if (label(); as labelText) {
|
|
1337
1555
|
<span [id]="labelId()" class="kt-radio-group__legend">
|
|
@@ -1357,8 +1575,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.1", ngImpor
|
|
|
1357
1575
|
}
|
|
1358
1576
|
</div>
|
|
1359
1577
|
</div>
|
|
1360
|
-
`, styles: ["@layer kt-aaa.components{:host{display:block}.kt-radio-group-field{display:flex;flex-direction:column;gap:var(--field-gap, .375rem)}.kt-radio-group__legend{font-size:var(--field-label-font-size, .875rem);font-weight:var(--field-label-weight, 500);color:var(--field-label-color, inherit)}.kt-radio-group__required{margin-inline-start:.125rem;color:var(--field-required-color, var(--kt-danger, #8c1d18))}.kt-radio-
|
|
1361
|
-
}], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }, { type: i0.Output, args: ["valueChange"] }], touched: [{ type: i0.Input, args: [{ isSignal: true, alias: "touched", required: false }] }, { type: i0.Output, args: ["touchedChange"] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], invalid: [{ type: i0.Input, args: [{ isSignal: true, alias: "invalid", required: false }] }], required: [{ type: i0.Input, args: [{ isSignal: true, alias: "required", required: false }] }], dirty: [{ type: i0.Input, args: [{ isSignal: true, alias: "dirty", required: false }] }], errors: [{ type: i0.Input, args: [{ isSignal: true, alias: "errors", required: false }] }], name: [{ type: i0.Input, args: [{ isSignal: true, alias: "name", required: false }] }], id: [{ type: i0.Input, args: [{ isSignal: true, alias: "id", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], hint: [{ type: i0.Input, args: [{ isSignal: true, alias: "hint", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], errorMatcher: [{ type: i0.Input, args: [{ isSignal: true, alias: "errorMatcher", required: false }] }], showAllErrors: [{ type: i0.Input, args: [{ isSignal: true, alias: "showAllErrors", required: false }] }], compareWith: [{ type: i0.Input, args: [{ isSignal: true, alias: "compareWith", required: false }] }] } });
|
|
1578
|
+
`, styles: ["@layer kt-aaa.components{:host{display:block}.kt-radio-group-field{display:flex;flex-direction:column;gap:var(--field-gap, .375rem)}.kt-radio-group__legend{font-size:var(--field-label-font-size, .875rem);font-weight:var(--field-label-weight, 500);color:var(--field-label-color, inherit)}.kt-radio-group__required{margin-inline-start:.125rem;color:var(--field-required-color, var(--kt-danger, #8c1d18))}.kt-radio-group__hint{margin:0;font-size:var(--field-hint-font-size, .8125rem);color:var(--field-hint-color, #474747)}.kt-radio-group__error{margin:0;display:flex;flex-direction:column;font-size:var(--field-hint-font-size, .8125rem);color:var(--field-error-color, #8c1d18)}.kt-radio-group__error-message{animation:var(--field-error-animation, none)}@media(prefers-reduced-motion:reduce){.kt-radio-group__error-message{animation:none}}}\n"] }]
|
|
1579
|
+
}], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }, { type: i0.Output, args: ["valueChange"] }], touched: [{ type: i0.Input, args: [{ isSignal: true, alias: "touched", required: false }] }, { type: i0.Output, args: ["touchedChange"] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], invalid: [{ type: i0.Input, args: [{ isSignal: true, alias: "invalid", required: false }] }], required: [{ type: i0.Input, args: [{ isSignal: true, alias: "required", required: false }] }], dirty: [{ type: i0.Input, args: [{ isSignal: true, alias: "dirty", required: false }] }], pending: [{ type: i0.Input, args: [{ isSignal: true, alias: "pending", required: false }] }], errors: [{ type: i0.Input, args: [{ isSignal: true, alias: "errors", required: false }] }], name: [{ type: i0.Input, args: [{ isSignal: true, alias: "name", required: false }] }], id: [{ type: i0.Input, args: [{ isSignal: true, alias: "id", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], hint: [{ type: i0.Input, args: [{ isSignal: true, alias: "hint", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], errorMatcher: [{ type: i0.Input, args: [{ isSignal: true, alias: "errorMatcher", required: false }] }], showAllErrors: [{ type: i0.Input, args: [{ isSignal: true, alias: "showAllErrors", required: false }] }], compareWith: [{ type: i0.Input, args: [{ isSignal: true, alias: "compareWith", required: false }] }] } });
|
|
1362
1580
|
|
|
1363
1581
|
/**
|
|
1364
1582
|
* Bouton radio individuel (enfant déclaratif de `kt-radio-group`).
|
|
@@ -1554,6 +1772,7 @@ function normalizeForFilter(s) {
|
|
|
1554
1772
|
ou la clé extraite quand `optionValue` est fourni). */
|
|
1555
1773
|
class KtBaseSelect {
|
|
1556
1774
|
fieldConfig = inject(KT_FIELD_CONFIG, { optional: true });
|
|
1775
|
+
errorResolver = inject(KtFieldErrorResolver);
|
|
1557
1776
|
config = inject(KT_SELECT_CONFIG, { optional: true });
|
|
1558
1777
|
host = inject(ElementRef);
|
|
1559
1778
|
ngZone = inject(NgZone);
|
|
@@ -1595,6 +1814,8 @@ class KtBaseSelect {
|
|
|
1595
1814
|
required = input(false, { ...(ngDevMode ? { debugName: "required" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
1596
1815
|
/** Le champ a-t-il été modifié depuis sa valeur initiale ? Poussé par `[formField]`. @default false */
|
|
1597
1816
|
dirty = input(false, { ...(ngDevMode ? { debugName: "dirty" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
1817
|
+
/** Validation asynchrone en cours (poussé par `[field]`) : pose `aria-busy` + `data-pending`. @default false */
|
|
1818
|
+
pending = input(false, { ...(ngDevMode ? { debugName: "pending" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
1598
1819
|
/** Erreurs de validation à afficher. Poussé par `[formField]`. @default [] */
|
|
1599
1820
|
errors = input([], /* @ts-ignore */
|
|
1600
1821
|
...(ngDevMode ? [{ debugName: "errors" }] : /* istanbul ignore next */ []));
|
|
@@ -1709,8 +1930,9 @@ class KtBaseSelect {
|
|
|
1709
1930
|
this.config?.truncatedResultsAnnouncement ??
|
|
1710
1931
|
DEFAULT_KT_SELECT_CONFIG.truncatedResultsAnnouncement, /* @ts-ignore */
|
|
1711
1932
|
...(ngDevMode ? [{ debugName: "resolvedTruncatedResultsAnnouncement" }] : /* istanbul ignore next */ []));
|
|
1712
|
-
// Field attend des { kind, message } ; on
|
|
1713
|
-
|
|
1933
|
+
// Field attend des { kind, message } ; on résout les messages par défaut et on écarte les
|
|
1934
|
+
// suppressions explicites (`message: ''`).
|
|
1935
|
+
fieldErrors = computed(() => this.errorResolver.resolveAll(this.errors()), /* @ts-ignore */
|
|
1714
1936
|
...(ngDevMode ? [{ debugName: "fieldErrors" }] : /* istanbul ignore next */ []));
|
|
1715
1937
|
// --- Accès aux options ---
|
|
1716
1938
|
labelAccessor = computed(() => accessor(this.optionLabel(), defaultLabel), /* @ts-ignore */
|
|
@@ -1966,6 +2188,16 @@ class KtBaseSelect {
|
|
|
1966
2188
|
return;
|
|
1967
2189
|
listbox.value.set(expected);
|
|
1968
2190
|
}
|
|
2191
|
+
/** Focus le trigger natif (utilisé par Signal Forms `focusBoundControl`). */
|
|
2192
|
+
focus(options) {
|
|
2193
|
+
this.triggerEl()?.nativeElement.focus(options);
|
|
2194
|
+
}
|
|
2195
|
+
/** Referme le panneau et vide le filtre (utilisé par Signal Forms `reset`). La sélection du
|
|
2196
|
+
listbox dérive de `value()` (computed) et se resynchronise seule. */
|
|
2197
|
+
reset() {
|
|
2198
|
+
this.expanded.set(false);
|
|
2199
|
+
this.filterText.set('');
|
|
2200
|
+
}
|
|
1969
2201
|
/** Desktop filtrable : le focus DOM vit dans le popup (champ/options) — on le rend au trigger
|
|
1970
2202
|
à la fermeture, sinon il tombe sur `<body>`. (Écran compact : déjà géré par l'effect `compact`.) */
|
|
1971
2203
|
refocusTriggerAfterFilterClose() {
|
|
@@ -2039,7 +2271,7 @@ class KtBaseSelect {
|
|
|
2039
2271
|
}, durationMs + 50);
|
|
2040
2272
|
}
|
|
2041
2273
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.1", ngImport: i0, type: KtBaseSelect, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
2042
|
-
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.2.0", version: "22.0.1", type: KtBaseSelect, isStandalone: true, inputs: { options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: true, transformFunction: null }, optionLabel: { classPropertyName: "optionLabel", publicName: "optionLabel", isSignal: true, isRequired: false, transformFunction: null }, optionValue: { classPropertyName: "optionValue", publicName: "optionValue", isSignal: true, isRequired: false, transformFunction: null }, optionDisabled: { classPropertyName: "optionDisabled", publicName: "optionDisabled", isSignal: true, isRequired: false, transformFunction: null }, compareWith: { classPropertyName: "compareWith", publicName: "compareWith", isSignal: true, isRequired: false, transformFunction: null }, touched: { classPropertyName: "touched", publicName: "touched", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, readonly: { classPropertyName: "readonly", publicName: "readonly", isSignal: true, isRequired: false, transformFunction: null }, invalid: { classPropertyName: "invalid", publicName: "invalid", isSignal: true, isRequired: false, transformFunction: null }, required: { classPropertyName: "required", publicName: "required", isSignal: true, isRequired: false, transformFunction: null }, dirty: { classPropertyName: "dirty", publicName: "dirty", isSignal: true, isRequired: false, transformFunction: null }, errors: { classPropertyName: "errors", publicName: "errors", isSignal: true, isRequired: false, transformFunction: null }, name: { classPropertyName: "name", publicName: "name", isSignal: true, isRequired: false, transformFunction: null }, id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, hint: { classPropertyName: "hint", publicName: "hint", isSignal: true, isRequired: false, transformFunction: null }, helpText: { classPropertyName: "helpText", publicName: "helpText", isSignal: true, isRequired: false, transformFunction: null }, helpLabel: { classPropertyName: "helpLabel", publicName: "helpLabel", isSignal: true, isRequired: false, transformFunction: null }, customDescribedBy: { classPropertyName: "customDescribedBy", publicName: "customDescribedBy", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, errorMatcher: { classPropertyName: "errorMatcher", publicName: "errorMatcher", isSignal: true, isRequired: false, transformFunction: null }, appearance: { classPropertyName: "appearance", publicName: "appearance", isSignal: true, isRequired: false, transformFunction: null }, floatLabel: { classPropertyName: "floatLabel", publicName: "floatLabel", isSignal: true, isRequired: false, transformFunction: null }, filterable: { classPropertyName: "filterable", publicName: "filterable", isSignal: true, isRequired: false, transformFunction: null }, filterPlaceholder: { classPropertyName: "filterPlaceholder", publicName: "filterPlaceholder", isSignal: true, isRequired: false, transformFunction: null }, filterLabel: { classPropertyName: "filterLabel", publicName: "filterLabel", isSignal: true, isRequired: false, transformFunction: null }, filterFn: { classPropertyName: "filterFn", publicName: "filterFn", isSignal: true, isRequired: false, transformFunction: null }, maxVisibleOptions: { classPropertyName: "maxVisibleOptions", publicName: "maxVisibleOptions", isSignal: true, isRequired: false, transformFunction: null }, truncatedResultsText: { classPropertyName: "truncatedResultsText", publicName: "truncatedResultsText", isSignal: true, isRequired: false, transformFunction: null }, truncatedResultsAnnouncement: { classPropertyName: "truncatedResultsAnnouncement", publicName: "truncatedResultsAnnouncement", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { helpClick: "helpClick", touched: "touchedChange" }, host: { listeners: { "keydown": "onHostKeydown($event)" } }, viewQueries: [{ propertyName: "triggerEl", first: true, predicate: ["trigger"], descendants: true, isSignal: true }, { propertyName: "popupEl", first: true, predicate: ["popup"], descendants: true, isSignal: true }, { propertyName: "filterInputEl", first: true, predicate: ["filterInput"], descendants: true, isSignal: true }, { propertyName: "listboxEl", first: true, predicate: ["listboxEl"], descendants: true, isSignal: true }, { propertyName: "listboxDir", first: true, predicate: Listbox, descendants: true, isSignal: true }, { propertyName: "comboboxDir", first: true, predicate: Combobox, descendants: true, isSignal: true }], ngImport: i0 });
|
|
2274
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.2.0", version: "22.0.1", type: KtBaseSelect, isStandalone: true, inputs: { options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: true, transformFunction: null }, optionLabel: { classPropertyName: "optionLabel", publicName: "optionLabel", isSignal: true, isRequired: false, transformFunction: null }, optionValue: { classPropertyName: "optionValue", publicName: "optionValue", isSignal: true, isRequired: false, transformFunction: null }, optionDisabled: { classPropertyName: "optionDisabled", publicName: "optionDisabled", isSignal: true, isRequired: false, transformFunction: null }, compareWith: { classPropertyName: "compareWith", publicName: "compareWith", isSignal: true, isRequired: false, transformFunction: null }, touched: { classPropertyName: "touched", publicName: "touched", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, readonly: { classPropertyName: "readonly", publicName: "readonly", isSignal: true, isRequired: false, transformFunction: null }, invalid: { classPropertyName: "invalid", publicName: "invalid", isSignal: true, isRequired: false, transformFunction: null }, required: { classPropertyName: "required", publicName: "required", isSignal: true, isRequired: false, transformFunction: null }, dirty: { classPropertyName: "dirty", publicName: "dirty", isSignal: true, isRequired: false, transformFunction: null }, pending: { classPropertyName: "pending", publicName: "pending", isSignal: true, isRequired: false, transformFunction: null }, errors: { classPropertyName: "errors", publicName: "errors", isSignal: true, isRequired: false, transformFunction: null }, name: { classPropertyName: "name", publicName: "name", isSignal: true, isRequired: false, transformFunction: null }, id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, hint: { classPropertyName: "hint", publicName: "hint", isSignal: true, isRequired: false, transformFunction: null }, helpText: { classPropertyName: "helpText", publicName: "helpText", isSignal: true, isRequired: false, transformFunction: null }, helpLabel: { classPropertyName: "helpLabel", publicName: "helpLabel", isSignal: true, isRequired: false, transformFunction: null }, customDescribedBy: { classPropertyName: "customDescribedBy", publicName: "customDescribedBy", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, errorMatcher: { classPropertyName: "errorMatcher", publicName: "errorMatcher", isSignal: true, isRequired: false, transformFunction: null }, appearance: { classPropertyName: "appearance", publicName: "appearance", isSignal: true, isRequired: false, transformFunction: null }, floatLabel: { classPropertyName: "floatLabel", publicName: "floatLabel", isSignal: true, isRequired: false, transformFunction: null }, filterable: { classPropertyName: "filterable", publicName: "filterable", isSignal: true, isRequired: false, transformFunction: null }, filterPlaceholder: { classPropertyName: "filterPlaceholder", publicName: "filterPlaceholder", isSignal: true, isRequired: false, transformFunction: null }, filterLabel: { classPropertyName: "filterLabel", publicName: "filterLabel", isSignal: true, isRequired: false, transformFunction: null }, filterFn: { classPropertyName: "filterFn", publicName: "filterFn", isSignal: true, isRequired: false, transformFunction: null }, maxVisibleOptions: { classPropertyName: "maxVisibleOptions", publicName: "maxVisibleOptions", isSignal: true, isRequired: false, transformFunction: null }, truncatedResultsText: { classPropertyName: "truncatedResultsText", publicName: "truncatedResultsText", isSignal: true, isRequired: false, transformFunction: null }, truncatedResultsAnnouncement: { classPropertyName: "truncatedResultsAnnouncement", publicName: "truncatedResultsAnnouncement", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { helpClick: "helpClick", touched: "touchedChange" }, host: { listeners: { "keydown": "onHostKeydown($event)" } }, viewQueries: [{ propertyName: "triggerEl", first: true, predicate: ["trigger"], descendants: true, isSignal: true }, { propertyName: "popupEl", first: true, predicate: ["popup"], descendants: true, isSignal: true }, { propertyName: "filterInputEl", first: true, predicate: ["filterInput"], descendants: true, isSignal: true }, { propertyName: "listboxEl", first: true, predicate: ["listboxEl"], descendants: true, isSignal: true }, { propertyName: "listboxDir", first: true, predicate: Listbox, descendants: true, isSignal: true }, { propertyName: "comboboxDir", first: true, predicate: Combobox, descendants: true, isSignal: true }], ngImport: i0 });
|
|
2043
2275
|
}
|
|
2044
2276
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.1", ngImport: i0, type: KtBaseSelect, decorators: [{
|
|
2045
2277
|
type: Directive,
|
|
@@ -2048,7 +2280,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.1", ngImpor
|
|
|
2048
2280
|
'(keydown)': 'onHostKeydown($event)',
|
|
2049
2281
|
},
|
|
2050
2282
|
}]
|
|
2051
|
-
}], ctorParameters: () => [], propDecorators: { options: [{ type: i0.Input, args: [{ isSignal: true, alias: "options", required: true }] }], optionLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "optionLabel", required: false }] }], optionValue: [{ type: i0.Input, args: [{ isSignal: true, alias: "optionValue", required: false }] }], optionDisabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "optionDisabled", required: false }] }], compareWith: [{ type: i0.Input, args: [{ isSignal: true, alias: "compareWith", required: false }] }], helpClick: [{ type: i0.Output, args: ["helpClick"] }], touched: [{ type: i0.Input, args: [{ isSignal: true, alias: "touched", required: false }] }, { type: i0.Output, args: ["touchedChange"] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], readonly: [{ type: i0.Input, args: [{ isSignal: true, alias: "readonly", required: false }] }], invalid: [{ type: i0.Input, args: [{ isSignal: true, alias: "invalid", required: false }] }], required: [{ type: i0.Input, args: [{ isSignal: true, alias: "required", required: false }] }], dirty: [{ type: i0.Input, args: [{ isSignal: true, alias: "dirty", required: false }] }], errors: [{ type: i0.Input, args: [{ isSignal: true, alias: "errors", required: false }] }], name: [{ type: i0.Input, args: [{ isSignal: true, alias: "name", required: false }] }], id: [{ type: i0.Input, args: [{ isSignal: true, alias: "id", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], hint: [{ type: i0.Input, args: [{ isSignal: true, alias: "hint", required: false }] }], helpText: [{ type: i0.Input, args: [{ isSignal: true, alias: "helpText", required: false }] }], helpLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "helpLabel", required: false }] }], customDescribedBy: [{ type: i0.Input, args: [{ isSignal: true, alias: "customDescribedBy", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], errorMatcher: [{ type: i0.Input, args: [{ isSignal: true, alias: "errorMatcher", required: false }] }], appearance: [{ type: i0.Input, args: [{ isSignal: true, alias: "appearance", required: false }] }], floatLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "floatLabel", required: false }] }], filterable: [{ type: i0.Input, args: [{ isSignal: true, alias: "filterable", required: false }] }], filterPlaceholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "filterPlaceholder", required: false }] }], filterLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "filterLabel", required: false }] }], filterFn: [{ type: i0.Input, args: [{ isSignal: true, alias: "filterFn", required: false }] }], maxVisibleOptions: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxVisibleOptions", required: false }] }], truncatedResultsText: [{ type: i0.Input, args: [{ isSignal: true, alias: "truncatedResultsText", required: false }] }], truncatedResultsAnnouncement: [{ type: i0.Input, args: [{ isSignal: true, alias: "truncatedResultsAnnouncement", required: false }] }], triggerEl: [{ type: i0.ViewChild, args: ['trigger', { isSignal: true }] }], popupEl: [{ type: i0.ViewChild, args: ['popup', { isSignal: true }] }], filterInputEl: [{ type: i0.ViewChild, args: ['filterInput', { isSignal: true }] }], listboxEl: [{ type: i0.ViewChild, args: ['listboxEl', { isSignal: true }] }], listboxDir: [{ type: i0.ViewChild, args: [i0.forwardRef(() => Listbox), { isSignal: true }] }], comboboxDir: [{ type: i0.ViewChild, args: [i0.forwardRef(() => Combobox), { isSignal: true }] }] } });
|
|
2283
|
+
}], ctorParameters: () => [], propDecorators: { options: [{ type: i0.Input, args: [{ isSignal: true, alias: "options", required: true }] }], optionLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "optionLabel", required: false }] }], optionValue: [{ type: i0.Input, args: [{ isSignal: true, alias: "optionValue", required: false }] }], optionDisabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "optionDisabled", required: false }] }], compareWith: [{ type: i0.Input, args: [{ isSignal: true, alias: "compareWith", required: false }] }], helpClick: [{ type: i0.Output, args: ["helpClick"] }], touched: [{ type: i0.Input, args: [{ isSignal: true, alias: "touched", required: false }] }, { type: i0.Output, args: ["touchedChange"] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], readonly: [{ type: i0.Input, args: [{ isSignal: true, alias: "readonly", required: false }] }], invalid: [{ type: i0.Input, args: [{ isSignal: true, alias: "invalid", required: false }] }], required: [{ type: i0.Input, args: [{ isSignal: true, alias: "required", required: false }] }], dirty: [{ type: i0.Input, args: [{ isSignal: true, alias: "dirty", required: false }] }], pending: [{ type: i0.Input, args: [{ isSignal: true, alias: "pending", required: false }] }], errors: [{ type: i0.Input, args: [{ isSignal: true, alias: "errors", required: false }] }], name: [{ type: i0.Input, args: [{ isSignal: true, alias: "name", required: false }] }], id: [{ type: i0.Input, args: [{ isSignal: true, alias: "id", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], hint: [{ type: i0.Input, args: [{ isSignal: true, alias: "hint", required: false }] }], helpText: [{ type: i0.Input, args: [{ isSignal: true, alias: "helpText", required: false }] }], helpLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "helpLabel", required: false }] }], customDescribedBy: [{ type: i0.Input, args: [{ isSignal: true, alias: "customDescribedBy", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], errorMatcher: [{ type: i0.Input, args: [{ isSignal: true, alias: "errorMatcher", required: false }] }], appearance: [{ type: i0.Input, args: [{ isSignal: true, alias: "appearance", required: false }] }], floatLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "floatLabel", required: false }] }], filterable: [{ type: i0.Input, args: [{ isSignal: true, alias: "filterable", required: false }] }], filterPlaceholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "filterPlaceholder", required: false }] }], filterLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "filterLabel", required: false }] }], filterFn: [{ type: i0.Input, args: [{ isSignal: true, alias: "filterFn", required: false }] }], maxVisibleOptions: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxVisibleOptions", required: false }] }], truncatedResultsText: [{ type: i0.Input, args: [{ isSignal: true, alias: "truncatedResultsText", required: false }] }], truncatedResultsAnnouncement: [{ type: i0.Input, args: [{ isSignal: true, alias: "truncatedResultsAnnouncement", required: false }] }], triggerEl: [{ type: i0.ViewChild, args: ['trigger', { isSignal: true }] }], popupEl: [{ type: i0.ViewChild, args: ['popup', { isSignal: true }] }], filterInputEl: [{ type: i0.ViewChild, args: ['filterInput', { isSignal: true }] }], listboxEl: [{ type: i0.ViewChild, args: ['listboxEl', { isSignal: true }] }], listboxDir: [{ type: i0.ViewChild, args: [i0.forwardRef(() => Listbox), { isSignal: true }] }], comboboxDir: [{ type: i0.ViewChild, args: [i0.forwardRef(() => Combobox), { isSignal: true }] }] } });
|
|
2052
2284
|
|
|
2053
2285
|
/** Template de rendu d'une option, posé sur un `<ng-template>` projeté dans `kt-select`.
|
|
2054
2286
|
L'input sert UNIQUEMENT à inférer `T` (re-bind de la liste d'options) ; `ngTemplateContextGuard`
|
|
@@ -2188,11 +2420,11 @@ class KtSelect extends KtBaseSelect {
|
|
|
2188
2420
|
}
|
|
2189
2421
|
}
|
|
2190
2422
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.1", ngImport: i0, type: KtSelect, deps: null, target: i0.ɵɵFactoryTarget.Component });
|
|
2191
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.1", type: KtSelect, isStandalone: true, selector: "kt-select", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange", selectionChange: "selectionChange" }, queries: [{ propertyName: "optionDef", first: true, predicate: KtSelectOptionDef, descendants: true, isSignal: true }, { propertyName: "triggerDef", first: true, predicate: KtSelectTriggerDef, descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: "<kt-field\n [label]=\"label()\"\n [hint]=\"hint()\"\n [helpText]=\"helpText()\"\n [helpLabel]=\"helpLabel()\"\n [customDescribedBy]=\"customDescribedBy()\"\n [errors]=\"fieldErrors()\"\n [invalid]=\"showInvalid()\"\n [required]=\"required()\"\n [fieldId]=\"id()\"\n [appearance]=\"appearance()\"\n [floatLabel]=\"floatLabel()\"\n (helpClick)=\"helpClick.emit($event)\"\n>\n <ng-content select=\"[ktFieldHelp]\" />\n <div class=\"kt-select\" [class.kt-select--open]=\"expanded()\">\n <button\n #combobox=\"ngCombobox\"\n #trigger\n ngCombobox\n ktFieldControl\n type=\"button\"\n class=\"kt-field-box kt-select__trigger\"\n [(expanded)]=\"expanded\"\n [disabled]=\"disabled()\"\n [softDisabled]=\"false\"\n [attr.data-invalid]=\"showInvalid() ? '' : null\"\n [attr.data-disabled]=\"disabled() ? '' : null\"\n [attr.data-filled]=\"selectedOption() ? '' : null\"\n >\n <span class=\"kt-select__value\">\n @if (triggerDef(); as def) {\n <ng-container [ngTemplateOutlet]=\"def.template\" [ngTemplateOutletContext]=\"{ $implicit: selectedOption() }\" />\n } @else if (selectedOption(); as option) {\n {{ labelOf(option) }}\n } @else {\n <span class=\"kt-select__placeholder\">{{ resolvedPlaceholder() }}</span>\n }\n </span>\n <span class=\"kt-select__arrow\" aria-hidden=\"true\">arrow_drop_down</span>\n </button>\n\n <!-- Un seul Popover (top-layer). CSS @media : dropdown ancr\u00E9 (desktop) \u2194 bottom-sheet (t\u00E9l\u00E9phone).\n Pas de <dialog>.showModal() : ce combobox se ferme au blur, et showModal volerait le focus. -->\n <ng-template ngComboboxPopup [combobox]=\"combobox\" [popupType]=\"filterable() ? 'dialog' : 'listbox'\">\n <div #popup popover=\"manual\" class=\"kt-select__popup\" [class.kt-select__popup--sheet]=\"compact()\">\n @if (compact()) {\n <div class=\"kt-select__sheet-scrim\" aria-hidden=\"true\" (click)=\"expanded.set(false)\"></div>\n }\n <div class=\"kt-select__sheet-card\">\n @if (compact()) {\n <div\n class=\"kt-select__sheet-grab\"\n aria-hidden=\"true\"\n (pointerdown)=\"onDragStart($event)\"\n (mousedown)=\"$event.preventDefault()\"\n ></div>\n <header class=\"kt-select__sheet-header\">\n <span class=\"kt-select__sheet-title\">{{ label() }}</span>\n <button\n type=\"button\"\n class=\"kt-select__sheet-close\"\n [attr.aria-label]=\"resolvedCloseLabel()\"\n (click)=\"expanded.set(false)\"\n >\n <span class=\"kt-select__sheet-close-icon\" aria-hidden=\"true\">close</span>\n </button>\n </header>\n }\n @if (filterable()) {\n <!-- Mode filtrable : le widget combobox est le panneau ENTIER (champ + annonce + liste).\n Indispensable : un focus pos\u00E9 hors de l'\u00E9l\u00E9ment ngComboboxWidget ferme le popup\n (closePopupOnBlur de @angular/aria) \u2014 le champ doit donc vivre dans ce sous-arbre. -->\n <div\n ngComboboxWidget\n role=\"dialog\"\n class=\"kt-select__panel\"\n [id]=\"panelId\"\n [attr.aria-label]=\"label()\"\n [activeDescendant]=\"lb.activeDescendant()\"\n >\n <div class=\"kt-select__filter\">\n <input\n #filterInput\n type=\"search\"\n role=\"combobox\"\n aria-autocomplete=\"list\"\n aria-expanded=\"true\"\n class=\"kt-select__filter-input\"\n autocomplete=\"off\"\n [placeholder]=\"resolvedFilterPlaceholder()\"\n [attr.aria-label]=\"resolvedFilterLabel()\"\n [attr.aria-controls]=\"lb.id()\"\n [attr.aria-activedescendant]=\"lb.activeDescendant()\"\n [value]=\"filterText()\"\n (input)=\"onFilterInput($event)\"\n (keydown)=\"onFilterKeydown($event)\"\n />\n </div>\n <!-- Nombre de r\u00E9sultats annonc\u00E9 (diff\u00E9r\u00E9) aux lecteurs d'\u00E9cran : une liste qui\n r\u00E9tr\u00E9cit en silence est per\u00E7ue comme un bug (tests utilisateurs S. Higley). -->\n <div class=\"kt-select__sr-only\" role=\"status\" aria-live=\"polite\">{{ announcedCount() }}</div>\n <ul\n #lb=\"ngListbox\"\n #listboxEl\n ngListbox\n [focusMode]=\"compact() && !filterable() ? 'roving' : 'activedescendant'\"\n selectionMode=\"explicit\"\n class=\"kt-select__listbox\"\n [attr.aria-label]=\"label()\"\n [value]=\"listboxValue()\"\n (valueChange)=\"onListboxValueChange($event)\"\n [disabled]=\"disabled()\"\n [readonly]=\"readonly()\"\n >\n @for (item of displayedOptions(); track keyOf(item)) {\n <li\n #opt=\"ngOption\"\n ngOption\n class=\"kt-select__option\"\n [value]=\"keyOf(item)\"\n [label]=\"labelOf(item)\"\n [disabled]=\"disabledOf(item)\"\n [class.kt-select__option--active]=\"opt.active()\"\n >\n @if (optionDef(); as def) {\n <ng-container\n [ngTemplateOutlet]=\"def.template\"\n [ngTemplateOutletContext]=\"{\n $implicit: item,\n selected: !!opt.selected(),\n active: opt.active(),\n }\"\n />\n } @else {\n {{ labelOf(item) }}\n }\n </li>\n } @empty {\n <li class=\"kt-select__empty\" role=\"option\" aria-disabled=\"true\" aria-selected=\"false\">\n {{ resolvedEmptyText() }}\n </li>\n }\n @if (filterable() && filteredOptions().length > maxVisibleOptions()) {\n <li class=\"kt-select__truncated-info\" role=\"option\" aria-disabled=\"true\" aria-selected=\"false\">\n {{ resolvedTruncatedResultsText()(maxVisibleOptions(), filteredOptions().length) }}\n </li>\n }\n </ul>\n </div>\n } @else {\n <ul\n #listbox=\"ngListbox\"\n #listboxEl\n ngComboboxWidget\n ngListbox\n [focusMode]=\"compact() ? 'roving' : 'activedescendant'\"\n selectionMode=\"explicit\"\n class=\"kt-select__listbox\"\n [attr.aria-label]=\"label()\"\n [value]=\"listboxValue()\"\n (valueChange)=\"onListboxValueChange($event)\"\n [disabled]=\"disabled()\"\n [readonly]=\"readonly()\"\n [activeDescendant]=\"listbox.activeDescendant()\"\n >\n @for (item of options(); track keyOf(item)) {\n <li\n #opt=\"ngOption\"\n ngOption\n class=\"kt-select__option\"\n [value]=\"keyOf(item)\"\n [label]=\"labelOf(item)\"\n [disabled]=\"disabledOf(item)\"\n [class.kt-select__option--active]=\"opt.active()\"\n >\n @if (optionDef(); as def) {\n <ng-container\n [ngTemplateOutlet]=\"def.template\"\n [ngTemplateOutletContext]=\"{ $implicit: item, selected: !!opt.selected(), active: opt.active() }\"\n />\n } @else {\n {{ labelOf(item) }}\n }\n </li>\n } @empty {\n <li class=\"kt-select__empty\" role=\"option\" aria-disabled=\"true\" aria-selected=\"false\">\n {{ resolvedEmptyText() }}\n </li>\n }\n </ul>\n }\n </div>\n </div>\n </ng-template>\n </div>\n</kt-field>\n", styles: ["@layer kt-aaa.components{:host{display:block}.kt-select{position:relative}.kt-select__trigger{display:flex;align-items:center;justify-content:space-between;gap:var(--field-control-gap, .5rem);inline-size:100%;cursor:pointer;text-align:start;font:inherit;color:var(--field-color, inherit)}.kt-select__trigger:disabled{cursor:not-allowed;background:var(--field-disabled-bg, #f1f3f4);color:color-mix(in srgb,currentColor 50%,transparent)}.kt-select__value{flex:1;min-inline-size:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.kt-select__placeholder{color:var(--field-hint-color, #5f6368)}.kt-select__arrow{flex:none;font-family:Material Symbols Outlined;font-size:1.25em;line-height:1;font-feature-settings:\"liga\";color:var(--field-icon-color, #5f6368);transition:var(--select-arrow-transition, transform .12s ease);-webkit-font-smoothing:antialiased}.kt-select--open .kt-select__arrow{transform:rotate(180deg)}.kt-select__popup{box-sizing:border-box;display:flex;flex-direction:column;margin:0;padding:0;border-width:var(--select-popup-border-width, var(--field-border-width, 1px));border-style:var(--field-border-style, solid);border-color:var(--field-border-color, #c4c7c5);border-radius:var(--field-radius, 8px);background:var(--select-popup-bg, var(--kt-surface, #fff));color:var(--field-color, inherit);box-shadow:var(--select-popup-shadow, 0 4px 12px rgb(0 0 0 / 12%));-webkit-backdrop-filter:var(--select-popup-backdrop-filter, none);backdrop-filter:var(--select-popup-backdrop-filter, none);max-block-size:var(--select-popup-max-height, 16rem);overflow:hidden}.kt-select__sheet-card{display:contents}.kt-select__popup:not(:popover-open){display:none!important}.kt-select__popup:popover-open{animation:var(--select-popup-enter-animation, none)}@media(prefers-reduced-motion:reduce){.kt-select__popup:popover-open{animation:none}}.kt-select__listbox{flex:1 1 auto;min-block-size:0;margin:0;padding:.25rem;list-style:none;overflow-y:auto}.kt-select__panel{display:flex;flex-direction:column;flex:1 1 auto;min-block-size:0}.kt-select__filter{flex:none;padding:.5rem;border-block-end:1px solid var(--field-border-color, #c4c7c5)}.kt-select__filter-input{box-sizing:border-box;inline-size:100%;min-block-size:var(--field-min-height, 44px);padding:.375rem .625rem;border:var(--field-border-width, 1px) var(--field-border-style, solid) var(--field-border-color, #c4c7c5);border-radius:calc(var(--field-radius, 8px) * .75);background:var(--select-popup-bg, var(--kt-surface, #fff));color:var(--field-color, inherit);font:inherit;appearance:none}.kt-select__filter-input::placeholder{color:var(--field-hint-color, #5f6368)}.kt-select__filter-input:focus-visible{outline:2px solid var(--field-border-color-focus, #0b57d0);outline-offset:-1px}.kt-select__filter-input::-webkit-search-cancel-button{appearance:none;inline-size:1rem;block-size:1rem;margin-inline-start:.375rem;cursor:pointer;background-color:var(--field-icon-color, #5f6368);-webkit-mask:url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M19 6.41 17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z'/%3E%3C/svg%3E\") center / contain no-repeat;mask:url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M19 6.41 17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z'/%3E%3C/svg%3E\") center / contain no-repeat}.kt-select__sr-only{position:absolute;inline-size:1px;block-size:1px;padding:0;margin:-1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap;border:0}@supports (anchor-name: --x){.kt-select__popup{position:fixed;inset:auto;top:anchor(bottom);left:anchor(left);margin-block-start:.25rem;min-inline-size:anchor-size(width);width:max-content;max-inline-size:min(90vw,28rem);position-try-fallbacks:flip-block,flip-inline,flip-block flip-inline}}@supports not (anchor-name: --x){.kt-select__popup{position:fixed;inset:auto 0 0;inline-size:100%;max-inline-size:100%;border-radius:var(--kt-sheet-radius, 16px) var(--kt-sheet-radius, 16px) 0 0}}.kt-select__popup--sheet{position:fixed!important;inset:0!important;inline-size:100%!important;max-inline-size:100%!important;min-inline-size:0!important;width:100%!important;height:100%!important;max-block-size:none!important;margin:0!important;padding:0!important;border:none!important;background:transparent!important;box-shadow:none!important;border-radius:0!important;overflow:visible!important;display:flex;flex-direction:column!important;justify-content:flex-end!important}.kt-select__popup--sheet .kt-select__sheet-card{position:relative;z-index:2;display:flex;flex-direction:column;background:var(--select-popup-bg, var(--kt-surface, #fff));border-radius:var(--kt-sheet-radius, 16px) var(--kt-sheet-radius, 16px) 0 0;box-shadow:var(--kt-sheet-shadow, 0 -4px 16px rgb(0 0 0 / 12%));max-block-size:var(--kt-sheet-max-block-size, 85svh);width:100%;overflow:hidden;translate:0 0;transition:translate var(--kt-sheet-anim-duration, .12s) ease}.kt-select__popup--sheet .kt-select__sheet-card:has(.kt-select__filter){block-size:var(--kt-sheet-max-block-size, 85svh);max-block-size:var(--kt-sheet-max-block-size, 85svh)}.kt-select__popup--sheet:popover-open .kt-select__sheet-card{translate:0 0;animation:var(--select-sheet-enter-animation, kt-sheet-in var(--kt-sheet-anim-duration, .12s) ease)}.kt-select__popup--sheet .kt-select__sheet-card.kt-select__popup--dragging{transition:none}.kt-select__popup--sheet.kt-select__popup--closing .kt-select__sheet-card,.kt-select__popup--sheet:popover-open.kt-select__popup--closing .kt-select__sheet-card{translate:0 100%;transition:translate var(--kt-sheet-exit-duration, 90ms) cubic-bezier(.4,0,.2,1)}::ng-deep .kt-select__popup--sheet::backdrop{display:none!important}.kt-select__sheet-scrim{display:none}.kt-select__popup--sheet .kt-select__sheet-scrim{display:block;position:fixed;inset:0;z-index:1;background:var(--kt-sheet-scrim, rgb(0 0 0 / 40%));opacity:0;pointer-events:auto;transition:opacity var(--kt-sheet-anim-duration, .12s) ease,overlay var(--kt-sheet-anim-duration, .12s) allow-discrete,display var(--kt-sheet-anim-duration, .12s) allow-discrete}.kt-select__popup--sheet:popover-open .kt-select__sheet-scrim{opacity:1}@starting-style{.kt-select__popup--sheet:popover-open .kt-select__sheet-scrim{opacity:0}}.kt-select__popup--sheet.kt-select__popup--closing .kt-select__sheet-scrim,.kt-select__popup--sheet:popover-open.kt-select__popup--closing .kt-select__sheet-scrim{opacity:0;transition:opacity var(--kt-sheet-exit-duration, 90ms) ease}.kt-select__popup--sheet .kt-select__option{--select-option-min-height: 44px;padding-block:.625rem}.kt-select__popup--sheet .kt-select__filter-input{font-size:1rem;min-block-size:44px}@media(prefers-reduced-motion:reduce){.kt-select__popup--sheet .kt-select__sheet-card,.kt-select__popup--sheet .kt-select__sheet-scrim{transition:none;translate:0 0}}.kt-select__sheet-grab{display:flex;align-items:center;justify-content:center;flex:none;block-size:44px;cursor:grab;touch-action:none}.kt-select__sheet-grab:active{cursor:grabbing}.kt-select__sheet-grab:before{content:\"\";inline-size:2.25rem;block-size:.25rem;border-radius:999px;background:var(--kt-sheet-grab-color, var(--kt-outline, #c4c7c5))}.kt-select__sheet-header{display:flex;align-items:center;justify-content:space-between;gap:.5rem;flex:none;padding-block:.5rem;padding-inline:1rem .5rem;border-block-end:1px solid var(--field-border-color, #c4c7c5)}.kt-select__sheet-title{font-weight:600}.kt-select__sheet-close{display:inline-flex;align-items:center;justify-content:center;flex:none;inline-size:44px;block-size:44px;padding:0;border:0;border-radius:50%;background:transparent;color:var(--field-icon-color, #5f6368);cursor:pointer}.kt-select__sheet-close:focus-visible{outline:2px solid var(--field-border-color-focus, #0b57d0);outline-offset:2px}.kt-select__sheet-close-icon{font-family:Material Symbols Outlined;font-feature-settings:\"liga\";font-size:1.5rem;line-height:1;-webkit-font-smoothing:antialiased}.kt-select__option{display:flex;align-items:center;gap:.5rem;box-sizing:border-box;min-block-size:var( --select-option-min-height, 44px );padding:.5rem .625rem;border-radius:6px;cursor:pointer}.kt-select__option[aria-selected=true]{background:var(--select-option-selected-bg, color-mix(in srgb, var(--kt-primary, #0b57d0) 14%, transparent));color:var(--select-option-selected-color, inherit);font-weight:var(--select-option-selected-weight, 600)}.kt-select__option--active:not([aria-disabled=true]),.kt-select__option:hover:not([aria-disabled=true]){background:var(--select-option-hover-bg, color-mix(in srgb, currentColor 8%, transparent))}.kt-select__option[aria-disabled=true]{opacity:.5;cursor:not-allowed}.kt-select__empty{padding:.5rem .625rem;color:var(--field-hint-color, #5f6368)}.kt-select__truncated-info{box-sizing:border-box;padding:.5rem .625rem;font-size:.875rem;font-style:italic;color:var(--field-hint-color, #5f6368);border-block-start:1px solid var(--field-border-color, #c4c7c5);pointer-events:none}}\n"], dependencies: [{ kind: "component", type: KtField, selector: "kt-field", inputs: ["label", "hint", "helpText", "helpLabel", "customDescribedBy", "errors", "invalid", "required", "fieldId", "hideHintWhenInvalid", "showAllErrors", "appearance", "floatLabel"], outputs: ["helpClick"] }, { kind: "directive", type: KtFieldControl, selector: "[ktFieldControl]" }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: Combobox, selector: "[ngCombobox]", inputs: ["disabled", "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"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
2423
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.1", type: KtSelect, isStandalone: true, selector: "kt-select", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange", selectionChange: "selectionChange" }, queries: [{ propertyName: "optionDef", first: true, predicate: KtSelectOptionDef, descendants: true, isSignal: true }, { propertyName: "triggerDef", first: true, predicate: KtSelectTriggerDef, descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: "<kt-field\n [label]=\"label()\"\n [hint]=\"hint()\"\n [helpText]=\"helpText()\"\n [helpLabel]=\"helpLabel()\"\n [customDescribedBy]=\"customDescribedBy()\"\n [errors]=\"fieldErrors()\"\n [invalid]=\"showInvalid()\"\n [required]=\"required()\"\n [fieldId]=\"id()\"\n [appearance]=\"appearance()\"\n [floatLabel]=\"floatLabel()\"\n (helpClick)=\"helpClick.emit($event)\"\n>\n <ng-content select=\"[ktFieldHelp]\" />\n <div class=\"kt-select\" [class.kt-select--open]=\"expanded()\">\n <button\n #combobox=\"ngCombobox\"\n #trigger\n ngCombobox\n ktFieldControl\n type=\"button\"\n class=\"kt-field-box kt-select__trigger\"\n [(expanded)]=\"expanded\"\n [disabled]=\"disabled()\"\n [softDisabled]=\"false\"\n [attr.data-invalid]=\"showInvalid() ? '' : null\"\n [attr.data-disabled]=\"disabled() ? '' : null\"\n [attr.data-filled]=\"selectedOption() ? '' : null\"\n [attr.data-pending]=\"pending() ? '' : null\"\n [attr.aria-busy]=\"pending() ? 'true' : null\"\n >\n <span class=\"kt-select__value\">\n @if (triggerDef(); as def) {\n <ng-container [ngTemplateOutlet]=\"def.template\" [ngTemplateOutletContext]=\"{ $implicit: selectedOption() }\" />\n } @else if (selectedOption(); as option) {\n {{ labelOf(option) }}\n } @else {\n <span class=\"kt-select__placeholder\">{{ resolvedPlaceholder() }}</span>\n }\n </span>\n <span class=\"kt-select__arrow\" aria-hidden=\"true\">arrow_drop_down</span>\n </button>\n\n <!-- Un seul Popover (top-layer). CSS @media : dropdown ancr\u00E9 (desktop) \u2194 bottom-sheet (t\u00E9l\u00E9phone).\n Pas de <dialog>.showModal() : ce combobox se ferme au blur, et showModal volerait le focus. -->\n <ng-template ngComboboxPopup [combobox]=\"combobox\" [popupType]=\"filterable() ? 'dialog' : 'listbox'\">\n <div #popup popover=\"manual\" class=\"kt-select__popup\" [class.kt-select__popup--sheet]=\"compact()\">\n @if (compact()) {\n <div class=\"kt-select__sheet-scrim\" aria-hidden=\"true\" (click)=\"expanded.set(false)\"></div>\n }\n <div class=\"kt-select__sheet-card\">\n @if (compact()) {\n <div\n class=\"kt-select__sheet-grab\"\n aria-hidden=\"true\"\n (pointerdown)=\"onDragStart($event)\"\n (mousedown)=\"$event.preventDefault()\"\n ></div>\n <header class=\"kt-select__sheet-header\">\n <span class=\"kt-select__sheet-title\">{{ label() }}</span>\n <button\n type=\"button\"\n class=\"kt-select__sheet-close\"\n [attr.aria-label]=\"resolvedCloseLabel()\"\n (click)=\"expanded.set(false)\"\n >\n <span class=\"kt-select__sheet-close-icon\" aria-hidden=\"true\">close</span>\n </button>\n </header>\n }\n @if (filterable()) {\n <!-- Mode filtrable : le widget combobox est le panneau ENTIER (champ + annonce + liste).\n Indispensable : un focus pos\u00E9 hors de l'\u00E9l\u00E9ment ngComboboxWidget ferme le popup\n (closePopupOnBlur de @angular/aria) \u2014 le champ doit donc vivre dans ce sous-arbre. -->\n <div\n ngComboboxWidget\n role=\"dialog\"\n class=\"kt-select__panel\"\n [id]=\"panelId\"\n [attr.aria-label]=\"label()\"\n [activeDescendant]=\"lb.activeDescendant()\"\n >\n <div class=\"kt-select__filter\">\n <input\n #filterInput\n type=\"search\"\n role=\"combobox\"\n aria-autocomplete=\"list\"\n aria-expanded=\"true\"\n class=\"kt-select__filter-input\"\n autocomplete=\"off\"\n [placeholder]=\"resolvedFilterPlaceholder()\"\n [attr.aria-label]=\"resolvedFilterLabel()\"\n [attr.aria-controls]=\"lb.id()\"\n [attr.aria-activedescendant]=\"lb.activeDescendant()\"\n [value]=\"filterText()\"\n (input)=\"onFilterInput($event)\"\n (keydown)=\"onFilterKeydown($event)\"\n />\n </div>\n <!-- Nombre de r\u00E9sultats annonc\u00E9 (diff\u00E9r\u00E9) aux lecteurs d'\u00E9cran : une liste qui\n r\u00E9tr\u00E9cit en silence est per\u00E7ue comme un bug (tests utilisateurs S. Higley). -->\n <div class=\"kt-select__sr-only\" role=\"status\" aria-live=\"polite\">{{ announcedCount() }}</div>\n <ul\n #lb=\"ngListbox\"\n #listboxEl\n ngListbox\n [focusMode]=\"compact() && !filterable() ? 'roving' : 'activedescendant'\"\n selectionMode=\"explicit\"\n class=\"kt-select__listbox\"\n [attr.aria-label]=\"label()\"\n [value]=\"listboxValue()\"\n (valueChange)=\"onListboxValueChange($event)\"\n [disabled]=\"disabled()\"\n [readonly]=\"readonly()\"\n >\n @for (item of displayedOptions(); track keyOf(item)) {\n <li\n #opt=\"ngOption\"\n ngOption\n class=\"kt-select__option\"\n [value]=\"keyOf(item)\"\n [label]=\"labelOf(item)\"\n [disabled]=\"disabledOf(item)\"\n [class.kt-select__option--active]=\"opt.active()\"\n >\n @if (optionDef(); as def) {\n <ng-container\n [ngTemplateOutlet]=\"def.template\"\n [ngTemplateOutletContext]=\"{\n $implicit: item,\n selected: !!opt.selected(),\n active: opt.active(),\n }\"\n />\n } @else {\n {{ labelOf(item) }}\n }\n </li>\n } @empty {\n <li class=\"kt-select__empty\" role=\"option\" aria-disabled=\"true\" aria-selected=\"false\">\n {{ resolvedEmptyText() }}\n </li>\n }\n @if (filterable() && filteredOptions().length > maxVisibleOptions()) {\n <li class=\"kt-select__truncated-info\" role=\"option\" aria-disabled=\"true\" aria-selected=\"false\">\n {{ resolvedTruncatedResultsText()(maxVisibleOptions(), filteredOptions().length) }}\n </li>\n }\n </ul>\n </div>\n } @else {\n <ul\n #listbox=\"ngListbox\"\n #listboxEl\n ngComboboxWidget\n ngListbox\n [focusMode]=\"compact() ? 'roving' : 'activedescendant'\"\n selectionMode=\"explicit\"\n class=\"kt-select__listbox\"\n [attr.aria-label]=\"label()\"\n [value]=\"listboxValue()\"\n (valueChange)=\"onListboxValueChange($event)\"\n [disabled]=\"disabled()\"\n [readonly]=\"readonly()\"\n [activeDescendant]=\"listbox.activeDescendant()\"\n >\n @for (item of options(); track keyOf(item)) {\n <li\n #opt=\"ngOption\"\n ngOption\n class=\"kt-select__option\"\n [value]=\"keyOf(item)\"\n [label]=\"labelOf(item)\"\n [disabled]=\"disabledOf(item)\"\n [class.kt-select__option--active]=\"opt.active()\"\n >\n @if (optionDef(); as def) {\n <ng-container\n [ngTemplateOutlet]=\"def.template\"\n [ngTemplateOutletContext]=\"{ $implicit: item, selected: !!opt.selected(), active: opt.active() }\"\n />\n } @else {\n {{ labelOf(item) }}\n }\n </li>\n } @empty {\n <li class=\"kt-select__empty\" role=\"option\" aria-disabled=\"true\" aria-selected=\"false\">\n {{ resolvedEmptyText() }}\n </li>\n }\n </ul>\n }\n </div>\n </div>\n </ng-template>\n </div>\n</kt-field>\n", styles: ["@layer kt-aaa.components{:host{display:block}.kt-select{position:relative}.kt-select__trigger{display:flex;align-items:center;justify-content:space-between;gap:var(--field-control-gap, .5rem);inline-size:100%;cursor:pointer;text-align:start;font:inherit;color:var(--field-color, inherit)}.kt-select__trigger:disabled{cursor:not-allowed;background:var(--field-disabled-bg, #f1f3f4);color:color-mix(in srgb,currentColor 50%,transparent)}.kt-select__value{flex:1;min-inline-size:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.kt-select__placeholder{color:var(--field-hint-color, #5f6368)}.kt-select__arrow{flex:none;font-family:Material Symbols Outlined;font-size:1.25em;line-height:1;font-feature-settings:\"liga\";color:var(--field-icon-color, #5f6368);transition:var(--select-arrow-transition, transform .12s ease);-webkit-font-smoothing:antialiased}.kt-select--open .kt-select__arrow{transform:rotate(180deg)}.kt-select__popup{box-sizing:border-box;display:flex;flex-direction:column;margin:0;padding:0;border-width:var(--select-popup-border-width, var(--field-border-width, 1px));border-style:var(--field-border-style, solid);border-color:var(--field-border-color, #c4c7c5);border-radius:var(--field-radius, 8px);background:var(--select-popup-bg, var(--kt-surface, #fff));color:var(--field-color, inherit);box-shadow:var(--select-popup-shadow, 0 4px 12px rgb(0 0 0 / 12%));-webkit-backdrop-filter:var(--select-popup-backdrop-filter, none);backdrop-filter:var(--select-popup-backdrop-filter, none);max-block-size:var(--select-popup-max-height, 16rem);overflow:hidden}.kt-select__sheet-card{display:contents}.kt-select__popup:not(:popover-open){display:none!important}.kt-select__popup:popover-open{animation:var(--select-popup-enter-animation, none)}@media(prefers-reduced-motion:reduce){.kt-select__popup:popover-open{animation:none}}.kt-select__listbox{flex:1 1 auto;min-block-size:0;margin:0;padding:.25rem;list-style:none;overflow-y:auto}.kt-select__panel{display:flex;flex-direction:column;flex:1 1 auto;min-block-size:0}.kt-select__filter{flex:none;padding:.5rem;border-block-end:1px solid var(--field-border-color, #c4c7c5)}.kt-select__filter-input{box-sizing:border-box;inline-size:100%;min-block-size:var(--field-min-height, 44px);padding:.375rem .625rem;border:var(--field-border-width, 1px) var(--field-border-style, solid) var(--field-border-color, #c4c7c5);border-radius:calc(var(--field-radius, 8px) * .75);background:var(--select-popup-bg, var(--kt-surface, #fff));color:var(--field-color, inherit);font:inherit;appearance:none}.kt-select__filter-input::placeholder{color:var(--field-hint-color, #5f6368)}.kt-select__filter-input:focus-visible{outline:2px solid var(--field-border-color-focus, #0b57d0);outline-offset:-1px}.kt-select__filter-input::-webkit-search-cancel-button{appearance:none;inline-size:1rem;block-size:1rem;margin-inline-start:.375rem;cursor:pointer;background-color:var(--field-icon-color, #5f6368);-webkit-mask:url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M19 6.41 17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z'/%3E%3C/svg%3E\") center / contain no-repeat;mask:url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M19 6.41 17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z'/%3E%3C/svg%3E\") center / contain no-repeat}.kt-select__sr-only{position:absolute;inset-block-start:0;inset-inline-start:0;inline-size:1px;block-size:1px;padding:0;margin:-1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap;border:0}@supports (anchor-name: --x){.kt-select__popup{position:fixed;inset:auto;top:anchor(bottom);left:anchor(left);margin-block-start:.25rem;min-inline-size:anchor-size(width);width:max-content;max-inline-size:min(90vw,28rem);position-try-fallbacks:flip-block,flip-inline,flip-block flip-inline}}@supports not (anchor-name: --x){.kt-select__popup{position:fixed;inset:auto 0 0;inline-size:100%;max-inline-size:100%;border-radius:var(--kt-sheet-radius, 16px) var(--kt-sheet-radius, 16px) 0 0}}.kt-select__popup--sheet{position:fixed!important;inset:0!important;inline-size:100%!important;max-inline-size:100%!important;min-inline-size:0!important;width:100%!important;height:100%!important;max-block-size:none!important;margin:0!important;padding:0!important;border:none!important;background:transparent!important;box-shadow:none!important;border-radius:0!important;overflow:visible!important;display:flex;flex-direction:column!important;justify-content:flex-end!important}.kt-select__popup--sheet .kt-select__sheet-card{position:relative;z-index:2;display:flex;flex-direction:column;background:var(--select-popup-bg, var(--kt-surface, #fff));border-radius:var(--kt-sheet-radius, 16px) var(--kt-sheet-radius, 16px) 0 0;box-shadow:var(--kt-sheet-shadow, 0 -4px 16px rgb(0 0 0 / 12%));max-block-size:var(--kt-sheet-max-block-size, 85svh);width:100%;overflow:hidden;translate:0 0;transition:translate var(--kt-sheet-anim-duration, .12s) ease}.kt-select__popup--sheet .kt-select__sheet-card:has(.kt-select__filter){block-size:var(--kt-sheet-max-block-size, 85svh);max-block-size:var(--kt-sheet-max-block-size, 85svh)}.kt-select__popup--sheet:popover-open .kt-select__sheet-card{translate:0 0;animation:var(--select-sheet-enter-animation, kt-sheet-in var(--kt-sheet-anim-duration, .12s) ease)}.kt-select__popup--sheet .kt-select__sheet-card.kt-select__popup--dragging{transition:none}.kt-select__popup--sheet.kt-select__popup--closing .kt-select__sheet-card,.kt-select__popup--sheet:popover-open.kt-select__popup--closing .kt-select__sheet-card{translate:0 100%;transition:translate var(--kt-sheet-exit-duration, 90ms) cubic-bezier(.4,0,.2,1)}::ng-deep .kt-select__popup--sheet::backdrop{display:none!important}.kt-select__sheet-scrim{display:none}.kt-select__popup--sheet .kt-select__sheet-scrim{display:block;position:fixed;inset:0;z-index:1;background:var(--kt-sheet-scrim, rgb(0 0 0 / 40%));opacity:0;pointer-events:auto;transition:opacity var(--kt-sheet-anim-duration, .12s) ease,overlay var(--kt-sheet-anim-duration, .12s) allow-discrete,display var(--kt-sheet-anim-duration, .12s) allow-discrete}.kt-select__popup--sheet:popover-open .kt-select__sheet-scrim{opacity:1}@starting-style{.kt-select__popup--sheet:popover-open .kt-select__sheet-scrim{opacity:0}}.kt-select__popup--sheet.kt-select__popup--closing .kt-select__sheet-scrim,.kt-select__popup--sheet:popover-open.kt-select__popup--closing .kt-select__sheet-scrim{opacity:0;transition:opacity var(--kt-sheet-exit-duration, 90ms) ease}.kt-select__popup--sheet .kt-select__option{--select-option-min-height: 44px;padding-block:.625rem}.kt-select__popup--sheet .kt-select__filter-input{font-size:1rem;min-block-size:44px}@media(prefers-reduced-motion:reduce){.kt-select__popup--sheet .kt-select__sheet-card,.kt-select__popup--sheet .kt-select__sheet-scrim{transition:none;translate:0 0}}.kt-select__sheet-grab{display:flex;align-items:center;justify-content:center;flex:none;block-size:44px;cursor:grab;touch-action:none}.kt-select__sheet-grab:active{cursor:grabbing}.kt-select__sheet-grab:before{content:\"\";inline-size:2.25rem;block-size:.25rem;border-radius:999px;background:var(--kt-sheet-grab-color, var(--kt-outline, #c4c7c5))}.kt-select__sheet-header{display:flex;align-items:center;justify-content:space-between;gap:.5rem;flex:none;padding-block:.5rem;padding-inline:1rem .5rem;border-block-end:1px solid var(--field-border-color, #c4c7c5)}.kt-select__sheet-title{font-weight:600}.kt-select__sheet-close{display:inline-flex;align-items:center;justify-content:center;flex:none;inline-size:44px;block-size:44px;padding:0;border:0;border-radius:50%;background:transparent;color:var(--field-icon-color, #5f6368);cursor:pointer}.kt-select__sheet-close:focus-visible{outline:2px solid var(--field-border-color-focus, #0b57d0);outline-offset:2px}.kt-select__sheet-close-icon{font-family:Material Symbols Outlined;font-feature-settings:\"liga\";font-size:1.5rem;line-height:1;-webkit-font-smoothing:antialiased}.kt-select__option{display:flex;align-items:center;gap:.5rem;box-sizing:border-box;min-block-size:var( --select-option-min-height, 44px );padding:.5rem .625rem;border-radius:6px;cursor:pointer}.kt-select__option[aria-selected=true]{background:var(--select-option-selected-bg, color-mix(in srgb, var(--kt-primary, #0b57d0) 14%, transparent));color:var(--select-option-selected-color, inherit);font-weight:var(--select-option-selected-weight, 600)}.kt-select__option--active:not([aria-disabled=true]),.kt-select__option:hover:not([aria-disabled=true]){background:var(--select-option-hover-bg, color-mix(in srgb, currentColor 8%, transparent))}.kt-select__option[aria-disabled=true]{opacity:.5;cursor:not-allowed}.kt-select__empty{padding:.5rem .625rem;color:var(--field-hint-color, #5f6368)}.kt-select__truncated-info{box-sizing:border-box;padding:.5rem .625rem;font-size:.875rem;font-style:italic;color:var(--field-hint-color, #5f6368);border-block-start:1px solid var(--field-border-color, #c4c7c5);pointer-events:none}}\n"], dependencies: [{ kind: "component", type: KtField, selector: "kt-field", inputs: ["label", "hint", "helpText", "helpLabel", "customDescribedBy", "errors", "invalid", "required", "fieldId", "hideHintWhenInvalid", "showAllErrors", "appearance", "floatLabel"], outputs: ["helpClick"] }, { kind: "directive", type: KtFieldControl, selector: "[ktFieldControl]" }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: Combobox, selector: "[ngCombobox]", inputs: ["disabled", "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"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
2192
2424
|
}
|
|
2193
2425
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.1", ngImport: i0, type: KtSelect, decorators: [{
|
|
2194
2426
|
type: Component,
|
|
2195
|
-
args: [{ selector: 'kt-select', changeDetection: ChangeDetectionStrategy.OnPush, imports: [KtField, KtFieldControl, NgTemplateOutlet, Combobox, ComboboxPopup, ComboboxWidget, Listbox, Option], template: "<kt-field\n [label]=\"label()\"\n [hint]=\"hint()\"\n [helpText]=\"helpText()\"\n [helpLabel]=\"helpLabel()\"\n [customDescribedBy]=\"customDescribedBy()\"\n [errors]=\"fieldErrors()\"\n [invalid]=\"showInvalid()\"\n [required]=\"required()\"\n [fieldId]=\"id()\"\n [appearance]=\"appearance()\"\n [floatLabel]=\"floatLabel()\"\n (helpClick)=\"helpClick.emit($event)\"\n>\n <ng-content select=\"[ktFieldHelp]\" />\n <div class=\"kt-select\" [class.kt-select--open]=\"expanded()\">\n <button\n #combobox=\"ngCombobox\"\n #trigger\n ngCombobox\n ktFieldControl\n type=\"button\"\n class=\"kt-field-box kt-select__trigger\"\n [(expanded)]=\"expanded\"\n [disabled]=\"disabled()\"\n [softDisabled]=\"false\"\n [attr.data-invalid]=\"showInvalid() ? '' : null\"\n [attr.data-disabled]=\"disabled() ? '' : null\"\n [attr.data-filled]=\"selectedOption() ? '' : null\"\n >\n <span class=\"kt-select__value\">\n @if (triggerDef(); as def) {\n <ng-container [ngTemplateOutlet]=\"def.template\" [ngTemplateOutletContext]=\"{ $implicit: selectedOption() }\" />\n } @else if (selectedOption(); as option) {\n {{ labelOf(option) }}\n } @else {\n <span class=\"kt-select__placeholder\">{{ resolvedPlaceholder() }}</span>\n }\n </span>\n <span class=\"kt-select__arrow\" aria-hidden=\"true\">arrow_drop_down</span>\n </button>\n\n <!-- Un seul Popover (top-layer). CSS @media : dropdown ancr\u00E9 (desktop) \u2194 bottom-sheet (t\u00E9l\u00E9phone).\n Pas de <dialog>.showModal() : ce combobox se ferme au blur, et showModal volerait le focus. -->\n <ng-template ngComboboxPopup [combobox]=\"combobox\" [popupType]=\"filterable() ? 'dialog' : 'listbox'\">\n <div #popup popover=\"manual\" class=\"kt-select__popup\" [class.kt-select__popup--sheet]=\"compact()\">\n @if (compact()) {\n <div class=\"kt-select__sheet-scrim\" aria-hidden=\"true\" (click)=\"expanded.set(false)\"></div>\n }\n <div class=\"kt-select__sheet-card\">\n @if (compact()) {\n <div\n class=\"kt-select__sheet-grab\"\n aria-hidden=\"true\"\n (pointerdown)=\"onDragStart($event)\"\n (mousedown)=\"$event.preventDefault()\"\n ></div>\n <header class=\"kt-select__sheet-header\">\n <span class=\"kt-select__sheet-title\">{{ label() }}</span>\n <button\n type=\"button\"\n class=\"kt-select__sheet-close\"\n [attr.aria-label]=\"resolvedCloseLabel()\"\n (click)=\"expanded.set(false)\"\n >\n <span class=\"kt-select__sheet-close-icon\" aria-hidden=\"true\">close</span>\n </button>\n </header>\n }\n @if (filterable()) {\n <!-- Mode filtrable : le widget combobox est le panneau ENTIER (champ + annonce + liste).\n Indispensable : un focus pos\u00E9 hors de l'\u00E9l\u00E9ment ngComboboxWidget ferme le popup\n (closePopupOnBlur de @angular/aria) \u2014 le champ doit donc vivre dans ce sous-arbre. -->\n <div\n ngComboboxWidget\n role=\"dialog\"\n class=\"kt-select__panel\"\n [id]=\"panelId\"\n [attr.aria-label]=\"label()\"\n [activeDescendant]=\"lb.activeDescendant()\"\n >\n <div class=\"kt-select__filter\">\n <input\n #filterInput\n type=\"search\"\n role=\"combobox\"\n aria-autocomplete=\"list\"\n aria-expanded=\"true\"\n class=\"kt-select__filter-input\"\n autocomplete=\"off\"\n [placeholder]=\"resolvedFilterPlaceholder()\"\n [attr.aria-label]=\"resolvedFilterLabel()\"\n [attr.aria-controls]=\"lb.id()\"\n [attr.aria-activedescendant]=\"lb.activeDescendant()\"\n [value]=\"filterText()\"\n (input)=\"onFilterInput($event)\"\n (keydown)=\"onFilterKeydown($event)\"\n />\n </div>\n <!-- Nombre de r\u00E9sultats annonc\u00E9 (diff\u00E9r\u00E9) aux lecteurs d'\u00E9cran : une liste qui\n r\u00E9tr\u00E9cit en silence est per\u00E7ue comme un bug (tests utilisateurs S. Higley). -->\n <div class=\"kt-select__sr-only\" role=\"status\" aria-live=\"polite\">{{ announcedCount() }}</div>\n <ul\n #lb=\"ngListbox\"\n #listboxEl\n ngListbox\n [focusMode]=\"compact() && !filterable() ? 'roving' : 'activedescendant'\"\n selectionMode=\"explicit\"\n class=\"kt-select__listbox\"\n [attr.aria-label]=\"label()\"\n [value]=\"listboxValue()\"\n (valueChange)=\"onListboxValueChange($event)\"\n [disabled]=\"disabled()\"\n [readonly]=\"readonly()\"\n >\n @for (item of displayedOptions(); track keyOf(item)) {\n <li\n #opt=\"ngOption\"\n ngOption\n class=\"kt-select__option\"\n [value]=\"keyOf(item)\"\n [label]=\"labelOf(item)\"\n [disabled]=\"disabledOf(item)\"\n [class.kt-select__option--active]=\"opt.active()\"\n >\n @if (optionDef(); as def) {\n <ng-container\n [ngTemplateOutlet]=\"def.template\"\n [ngTemplateOutletContext]=\"{\n $implicit: item,\n selected: !!opt.selected(),\n active: opt.active(),\n }\"\n />\n } @else {\n {{ labelOf(item) }}\n }\n </li>\n } @empty {\n <li class=\"kt-select__empty\" role=\"option\" aria-disabled=\"true\" aria-selected=\"false\">\n {{ resolvedEmptyText() }}\n </li>\n }\n @if (filterable() && filteredOptions().length > maxVisibleOptions()) {\n <li class=\"kt-select__truncated-info\" role=\"option\" aria-disabled=\"true\" aria-selected=\"false\">\n {{ resolvedTruncatedResultsText()(maxVisibleOptions(), filteredOptions().length) }}\n </li>\n }\n </ul>\n </div>\n } @else {\n <ul\n #listbox=\"ngListbox\"\n #listboxEl\n ngComboboxWidget\n ngListbox\n [focusMode]=\"compact() ? 'roving' : 'activedescendant'\"\n selectionMode=\"explicit\"\n class=\"kt-select__listbox\"\n [attr.aria-label]=\"label()\"\n [value]=\"listboxValue()\"\n (valueChange)=\"onListboxValueChange($event)\"\n [disabled]=\"disabled()\"\n [readonly]=\"readonly()\"\n [activeDescendant]=\"listbox.activeDescendant()\"\n >\n @for (item of options(); track keyOf(item)) {\n <li\n #opt=\"ngOption\"\n ngOption\n class=\"kt-select__option\"\n [value]=\"keyOf(item)\"\n [label]=\"labelOf(item)\"\n [disabled]=\"disabledOf(item)\"\n [class.kt-select__option--active]=\"opt.active()\"\n >\n @if (optionDef(); as def) {\n <ng-container\n [ngTemplateOutlet]=\"def.template\"\n [ngTemplateOutletContext]=\"{ $implicit: item, selected: !!opt.selected(), active: opt.active() }\"\n />\n } @else {\n {{ labelOf(item) }}\n }\n </li>\n } @empty {\n <li class=\"kt-select__empty\" role=\"option\" aria-disabled=\"true\" aria-selected=\"false\">\n {{ resolvedEmptyText() }}\n </li>\n }\n </ul>\n }\n </div>\n </div>\n </ng-template>\n </div>\n</kt-field>\n", styles: ["@layer kt-aaa.components{:host{display:block}.kt-select{position:relative}.kt-select__trigger{display:flex;align-items:center;justify-content:space-between;gap:var(--field-control-gap, .5rem);inline-size:100%;cursor:pointer;text-align:start;font:inherit;color:var(--field-color, inherit)}.kt-select__trigger:disabled{cursor:not-allowed;background:var(--field-disabled-bg, #f1f3f4);color:color-mix(in srgb,currentColor 50%,transparent)}.kt-select__value{flex:1;min-inline-size:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.kt-select__placeholder{color:var(--field-hint-color, #5f6368)}.kt-select__arrow{flex:none;font-family:Material Symbols Outlined;font-size:1.25em;line-height:1;font-feature-settings:\"liga\";color:var(--field-icon-color, #5f6368);transition:var(--select-arrow-transition, transform .12s ease);-webkit-font-smoothing:antialiased}.kt-select--open .kt-select__arrow{transform:rotate(180deg)}.kt-select__popup{box-sizing:border-box;display:flex;flex-direction:column;margin:0;padding:0;border-width:var(--select-popup-border-width, var(--field-border-width, 1px));border-style:var(--field-border-style, solid);border-color:var(--field-border-color, #c4c7c5);border-radius:var(--field-radius, 8px);background:var(--select-popup-bg, var(--kt-surface, #fff));color:var(--field-color, inherit);box-shadow:var(--select-popup-shadow, 0 4px 12px rgb(0 0 0 / 12%));-webkit-backdrop-filter:var(--select-popup-backdrop-filter, none);backdrop-filter:var(--select-popup-backdrop-filter, none);max-block-size:var(--select-popup-max-height, 16rem);overflow:hidden}.kt-select__sheet-card{display:contents}.kt-select__popup:not(:popover-open){display:none!important}.kt-select__popup:popover-open{animation:var(--select-popup-enter-animation, none)}@media(prefers-reduced-motion:reduce){.kt-select__popup:popover-open{animation:none}}.kt-select__listbox{flex:1 1 auto;min-block-size:0;margin:0;padding:.25rem;list-style:none;overflow-y:auto}.kt-select__panel{display:flex;flex-direction:column;flex:1 1 auto;min-block-size:0}.kt-select__filter{flex:none;padding:.5rem;border-block-end:1px solid var(--field-border-color, #c4c7c5)}.kt-select__filter-input{box-sizing:border-box;inline-size:100%;min-block-size:var(--field-min-height, 44px);padding:.375rem .625rem;border:var(--field-border-width, 1px) var(--field-border-style, solid) var(--field-border-color, #c4c7c5);border-radius:calc(var(--field-radius, 8px) * .75);background:var(--select-popup-bg, var(--kt-surface, #fff));color:var(--field-color, inherit);font:inherit;appearance:none}.kt-select__filter-input::placeholder{color:var(--field-hint-color, #5f6368)}.kt-select__filter-input:focus-visible{outline:2px solid var(--field-border-color-focus, #0b57d0);outline-offset:-1px}.kt-select__filter-input::-webkit-search-cancel-button{appearance:none;inline-size:1rem;block-size:1rem;margin-inline-start:.375rem;cursor:pointer;background-color:var(--field-icon-color, #5f6368);-webkit-mask:url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M19 6.41 17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z'/%3E%3C/svg%3E\") center / contain no-repeat;mask:url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M19 6.41 17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z'/%3E%3C/svg%3E\") center / contain no-repeat}.kt-select__sr-only{position:absolute;inline-size:1px;block-size:1px;padding:0;margin:-1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap;border:0}@supports (anchor-name: --x){.kt-select__popup{position:fixed;inset:auto;top:anchor(bottom);left:anchor(left);margin-block-start:.25rem;min-inline-size:anchor-size(width);width:max-content;max-inline-size:min(90vw,28rem);position-try-fallbacks:flip-block,flip-inline,flip-block flip-inline}}@supports not (anchor-name: --x){.kt-select__popup{position:fixed;inset:auto 0 0;inline-size:100%;max-inline-size:100%;border-radius:var(--kt-sheet-radius, 16px) var(--kt-sheet-radius, 16px) 0 0}}.kt-select__popup--sheet{position:fixed!important;inset:0!important;inline-size:100%!important;max-inline-size:100%!important;min-inline-size:0!important;width:100%!important;height:100%!important;max-block-size:none!important;margin:0!important;padding:0!important;border:none!important;background:transparent!important;box-shadow:none!important;border-radius:0!important;overflow:visible!important;display:flex;flex-direction:column!important;justify-content:flex-end!important}.kt-select__popup--sheet .kt-select__sheet-card{position:relative;z-index:2;display:flex;flex-direction:column;background:var(--select-popup-bg, var(--kt-surface, #fff));border-radius:var(--kt-sheet-radius, 16px) var(--kt-sheet-radius, 16px) 0 0;box-shadow:var(--kt-sheet-shadow, 0 -4px 16px rgb(0 0 0 / 12%));max-block-size:var(--kt-sheet-max-block-size, 85svh);width:100%;overflow:hidden;translate:0 0;transition:translate var(--kt-sheet-anim-duration, .12s) ease}.kt-select__popup--sheet .kt-select__sheet-card:has(.kt-select__filter){block-size:var(--kt-sheet-max-block-size, 85svh);max-block-size:var(--kt-sheet-max-block-size, 85svh)}.kt-select__popup--sheet:popover-open .kt-select__sheet-card{translate:0 0;animation:var(--select-sheet-enter-animation, kt-sheet-in var(--kt-sheet-anim-duration, .12s) ease)}.kt-select__popup--sheet .kt-select__sheet-card.kt-select__popup--dragging{transition:none}.kt-select__popup--sheet.kt-select__popup--closing .kt-select__sheet-card,.kt-select__popup--sheet:popover-open.kt-select__popup--closing .kt-select__sheet-card{translate:0 100%;transition:translate var(--kt-sheet-exit-duration, 90ms) cubic-bezier(.4,0,.2,1)}::ng-deep .kt-select__popup--sheet::backdrop{display:none!important}.kt-select__sheet-scrim{display:none}.kt-select__popup--sheet .kt-select__sheet-scrim{display:block;position:fixed;inset:0;z-index:1;background:var(--kt-sheet-scrim, rgb(0 0 0 / 40%));opacity:0;pointer-events:auto;transition:opacity var(--kt-sheet-anim-duration, .12s) ease,overlay var(--kt-sheet-anim-duration, .12s) allow-discrete,display var(--kt-sheet-anim-duration, .12s) allow-discrete}.kt-select__popup--sheet:popover-open .kt-select__sheet-scrim{opacity:1}@starting-style{.kt-select__popup--sheet:popover-open .kt-select__sheet-scrim{opacity:0}}.kt-select__popup--sheet.kt-select__popup--closing .kt-select__sheet-scrim,.kt-select__popup--sheet:popover-open.kt-select__popup--closing .kt-select__sheet-scrim{opacity:0;transition:opacity var(--kt-sheet-exit-duration, 90ms) ease}.kt-select__popup--sheet .kt-select__option{--select-option-min-height: 44px;padding-block:.625rem}.kt-select__popup--sheet .kt-select__filter-input{font-size:1rem;min-block-size:44px}@media(prefers-reduced-motion:reduce){.kt-select__popup--sheet .kt-select__sheet-card,.kt-select__popup--sheet .kt-select__sheet-scrim{transition:none;translate:0 0}}.kt-select__sheet-grab{display:flex;align-items:center;justify-content:center;flex:none;block-size:44px;cursor:grab;touch-action:none}.kt-select__sheet-grab:active{cursor:grabbing}.kt-select__sheet-grab:before{content:\"\";inline-size:2.25rem;block-size:.25rem;border-radius:999px;background:var(--kt-sheet-grab-color, var(--kt-outline, #c4c7c5))}.kt-select__sheet-header{display:flex;align-items:center;justify-content:space-between;gap:.5rem;flex:none;padding-block:.5rem;padding-inline:1rem .5rem;border-block-end:1px solid var(--field-border-color, #c4c7c5)}.kt-select__sheet-title{font-weight:600}.kt-select__sheet-close{display:inline-flex;align-items:center;justify-content:center;flex:none;inline-size:44px;block-size:44px;padding:0;border:0;border-radius:50%;background:transparent;color:var(--field-icon-color, #5f6368);cursor:pointer}.kt-select__sheet-close:focus-visible{outline:2px solid var(--field-border-color-focus, #0b57d0);outline-offset:2px}.kt-select__sheet-close-icon{font-family:Material Symbols Outlined;font-feature-settings:\"liga\";font-size:1.5rem;line-height:1;-webkit-font-smoothing:antialiased}.kt-select__option{display:flex;align-items:center;gap:.5rem;box-sizing:border-box;min-block-size:var( --select-option-min-height, 44px );padding:.5rem .625rem;border-radius:6px;cursor:pointer}.kt-select__option[aria-selected=true]{background:var(--select-option-selected-bg, color-mix(in srgb, var(--kt-primary, #0b57d0) 14%, transparent));color:var(--select-option-selected-color, inherit);font-weight:var(--select-option-selected-weight, 600)}.kt-select__option--active:not([aria-disabled=true]),.kt-select__option:hover:not([aria-disabled=true]){background:var(--select-option-hover-bg, color-mix(in srgb, currentColor 8%, transparent))}.kt-select__option[aria-disabled=true]{opacity:.5;cursor:not-allowed}.kt-select__empty{padding:.5rem .625rem;color:var(--field-hint-color, #5f6368)}.kt-select__truncated-info{box-sizing:border-box;padding:.5rem .625rem;font-size:.875rem;font-style:italic;color:var(--field-hint-color, #5f6368);border-block-start:1px solid var(--field-border-color, #c4c7c5);pointer-events:none}}\n"] }]
|
|
2427
|
+
args: [{ selector: 'kt-select', changeDetection: ChangeDetectionStrategy.OnPush, imports: [KtField, KtFieldControl, NgTemplateOutlet, Combobox, ComboboxPopup, ComboboxWidget, Listbox, Option], template: "<kt-field\n [label]=\"label()\"\n [hint]=\"hint()\"\n [helpText]=\"helpText()\"\n [helpLabel]=\"helpLabel()\"\n [customDescribedBy]=\"customDescribedBy()\"\n [errors]=\"fieldErrors()\"\n [invalid]=\"showInvalid()\"\n [required]=\"required()\"\n [fieldId]=\"id()\"\n [appearance]=\"appearance()\"\n [floatLabel]=\"floatLabel()\"\n (helpClick)=\"helpClick.emit($event)\"\n>\n <ng-content select=\"[ktFieldHelp]\" />\n <div class=\"kt-select\" [class.kt-select--open]=\"expanded()\">\n <button\n #combobox=\"ngCombobox\"\n #trigger\n ngCombobox\n ktFieldControl\n type=\"button\"\n class=\"kt-field-box kt-select__trigger\"\n [(expanded)]=\"expanded\"\n [disabled]=\"disabled()\"\n [softDisabled]=\"false\"\n [attr.data-invalid]=\"showInvalid() ? '' : null\"\n [attr.data-disabled]=\"disabled() ? '' : null\"\n [attr.data-filled]=\"selectedOption() ? '' : null\"\n [attr.data-pending]=\"pending() ? '' : null\"\n [attr.aria-busy]=\"pending() ? 'true' : null\"\n >\n <span class=\"kt-select__value\">\n @if (triggerDef(); as def) {\n <ng-container [ngTemplateOutlet]=\"def.template\" [ngTemplateOutletContext]=\"{ $implicit: selectedOption() }\" />\n } @else if (selectedOption(); as option) {\n {{ labelOf(option) }}\n } @else {\n <span class=\"kt-select__placeholder\">{{ resolvedPlaceholder() }}</span>\n }\n </span>\n <span class=\"kt-select__arrow\" aria-hidden=\"true\">arrow_drop_down</span>\n </button>\n\n <!-- Un seul Popover (top-layer). CSS @media : dropdown ancr\u00E9 (desktop) \u2194 bottom-sheet (t\u00E9l\u00E9phone).\n Pas de <dialog>.showModal() : ce combobox se ferme au blur, et showModal volerait le focus. -->\n <ng-template ngComboboxPopup [combobox]=\"combobox\" [popupType]=\"filterable() ? 'dialog' : 'listbox'\">\n <div #popup popover=\"manual\" class=\"kt-select__popup\" [class.kt-select__popup--sheet]=\"compact()\">\n @if (compact()) {\n <div class=\"kt-select__sheet-scrim\" aria-hidden=\"true\" (click)=\"expanded.set(false)\"></div>\n }\n <div class=\"kt-select__sheet-card\">\n @if (compact()) {\n <div\n class=\"kt-select__sheet-grab\"\n aria-hidden=\"true\"\n (pointerdown)=\"onDragStart($event)\"\n (mousedown)=\"$event.preventDefault()\"\n ></div>\n <header class=\"kt-select__sheet-header\">\n <span class=\"kt-select__sheet-title\">{{ label() }}</span>\n <button\n type=\"button\"\n class=\"kt-select__sheet-close\"\n [attr.aria-label]=\"resolvedCloseLabel()\"\n (click)=\"expanded.set(false)\"\n >\n <span class=\"kt-select__sheet-close-icon\" aria-hidden=\"true\">close</span>\n </button>\n </header>\n }\n @if (filterable()) {\n <!-- Mode filtrable : le widget combobox est le panneau ENTIER (champ + annonce + liste).\n Indispensable : un focus pos\u00E9 hors de l'\u00E9l\u00E9ment ngComboboxWidget ferme le popup\n (closePopupOnBlur de @angular/aria) \u2014 le champ doit donc vivre dans ce sous-arbre. -->\n <div\n ngComboboxWidget\n role=\"dialog\"\n class=\"kt-select__panel\"\n [id]=\"panelId\"\n [attr.aria-label]=\"label()\"\n [activeDescendant]=\"lb.activeDescendant()\"\n >\n <div class=\"kt-select__filter\">\n <input\n #filterInput\n type=\"search\"\n role=\"combobox\"\n aria-autocomplete=\"list\"\n aria-expanded=\"true\"\n class=\"kt-select__filter-input\"\n autocomplete=\"off\"\n [placeholder]=\"resolvedFilterPlaceholder()\"\n [attr.aria-label]=\"resolvedFilterLabel()\"\n [attr.aria-controls]=\"lb.id()\"\n [attr.aria-activedescendant]=\"lb.activeDescendant()\"\n [value]=\"filterText()\"\n (input)=\"onFilterInput($event)\"\n (keydown)=\"onFilterKeydown($event)\"\n />\n </div>\n <!-- Nombre de r\u00E9sultats annonc\u00E9 (diff\u00E9r\u00E9) aux lecteurs d'\u00E9cran : une liste qui\n r\u00E9tr\u00E9cit en silence est per\u00E7ue comme un bug (tests utilisateurs S. Higley). -->\n <div class=\"kt-select__sr-only\" role=\"status\" aria-live=\"polite\">{{ announcedCount() }}</div>\n <ul\n #lb=\"ngListbox\"\n #listboxEl\n ngListbox\n [focusMode]=\"compact() && !filterable() ? 'roving' : 'activedescendant'\"\n selectionMode=\"explicit\"\n class=\"kt-select__listbox\"\n [attr.aria-label]=\"label()\"\n [value]=\"listboxValue()\"\n (valueChange)=\"onListboxValueChange($event)\"\n [disabled]=\"disabled()\"\n [readonly]=\"readonly()\"\n >\n @for (item of displayedOptions(); track keyOf(item)) {\n <li\n #opt=\"ngOption\"\n ngOption\n class=\"kt-select__option\"\n [value]=\"keyOf(item)\"\n [label]=\"labelOf(item)\"\n [disabled]=\"disabledOf(item)\"\n [class.kt-select__option--active]=\"opt.active()\"\n >\n @if (optionDef(); as def) {\n <ng-container\n [ngTemplateOutlet]=\"def.template\"\n [ngTemplateOutletContext]=\"{\n $implicit: item,\n selected: !!opt.selected(),\n active: opt.active(),\n }\"\n />\n } @else {\n {{ labelOf(item) }}\n }\n </li>\n } @empty {\n <li class=\"kt-select__empty\" role=\"option\" aria-disabled=\"true\" aria-selected=\"false\">\n {{ resolvedEmptyText() }}\n </li>\n }\n @if (filterable() && filteredOptions().length > maxVisibleOptions()) {\n <li class=\"kt-select__truncated-info\" role=\"option\" aria-disabled=\"true\" aria-selected=\"false\">\n {{ resolvedTruncatedResultsText()(maxVisibleOptions(), filteredOptions().length) }}\n </li>\n }\n </ul>\n </div>\n } @else {\n <ul\n #listbox=\"ngListbox\"\n #listboxEl\n ngComboboxWidget\n ngListbox\n [focusMode]=\"compact() ? 'roving' : 'activedescendant'\"\n selectionMode=\"explicit\"\n class=\"kt-select__listbox\"\n [attr.aria-label]=\"label()\"\n [value]=\"listboxValue()\"\n (valueChange)=\"onListboxValueChange($event)\"\n [disabled]=\"disabled()\"\n [readonly]=\"readonly()\"\n [activeDescendant]=\"listbox.activeDescendant()\"\n >\n @for (item of options(); track keyOf(item)) {\n <li\n #opt=\"ngOption\"\n ngOption\n class=\"kt-select__option\"\n [value]=\"keyOf(item)\"\n [label]=\"labelOf(item)\"\n [disabled]=\"disabledOf(item)\"\n [class.kt-select__option--active]=\"opt.active()\"\n >\n @if (optionDef(); as def) {\n <ng-container\n [ngTemplateOutlet]=\"def.template\"\n [ngTemplateOutletContext]=\"{ $implicit: item, selected: !!opt.selected(), active: opt.active() }\"\n />\n } @else {\n {{ labelOf(item) }}\n }\n </li>\n } @empty {\n <li class=\"kt-select__empty\" role=\"option\" aria-disabled=\"true\" aria-selected=\"false\">\n {{ resolvedEmptyText() }}\n </li>\n }\n </ul>\n }\n </div>\n </div>\n </ng-template>\n </div>\n</kt-field>\n", styles: ["@layer kt-aaa.components{:host{display:block}.kt-select{position:relative}.kt-select__trigger{display:flex;align-items:center;justify-content:space-between;gap:var(--field-control-gap, .5rem);inline-size:100%;cursor:pointer;text-align:start;font:inherit;color:var(--field-color, inherit)}.kt-select__trigger:disabled{cursor:not-allowed;background:var(--field-disabled-bg, #f1f3f4);color:color-mix(in srgb,currentColor 50%,transparent)}.kt-select__value{flex:1;min-inline-size:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.kt-select__placeholder{color:var(--field-hint-color, #5f6368)}.kt-select__arrow{flex:none;font-family:Material Symbols Outlined;font-size:1.25em;line-height:1;font-feature-settings:\"liga\";color:var(--field-icon-color, #5f6368);transition:var(--select-arrow-transition, transform .12s ease);-webkit-font-smoothing:antialiased}.kt-select--open .kt-select__arrow{transform:rotate(180deg)}.kt-select__popup{box-sizing:border-box;display:flex;flex-direction:column;margin:0;padding:0;border-width:var(--select-popup-border-width, var(--field-border-width, 1px));border-style:var(--field-border-style, solid);border-color:var(--field-border-color, #c4c7c5);border-radius:var(--field-radius, 8px);background:var(--select-popup-bg, var(--kt-surface, #fff));color:var(--field-color, inherit);box-shadow:var(--select-popup-shadow, 0 4px 12px rgb(0 0 0 / 12%));-webkit-backdrop-filter:var(--select-popup-backdrop-filter, none);backdrop-filter:var(--select-popup-backdrop-filter, none);max-block-size:var(--select-popup-max-height, 16rem);overflow:hidden}.kt-select__sheet-card{display:contents}.kt-select__popup:not(:popover-open){display:none!important}.kt-select__popup:popover-open{animation:var(--select-popup-enter-animation, none)}@media(prefers-reduced-motion:reduce){.kt-select__popup:popover-open{animation:none}}.kt-select__listbox{flex:1 1 auto;min-block-size:0;margin:0;padding:.25rem;list-style:none;overflow-y:auto}.kt-select__panel{display:flex;flex-direction:column;flex:1 1 auto;min-block-size:0}.kt-select__filter{flex:none;padding:.5rem;border-block-end:1px solid var(--field-border-color, #c4c7c5)}.kt-select__filter-input{box-sizing:border-box;inline-size:100%;min-block-size:var(--field-min-height, 44px);padding:.375rem .625rem;border:var(--field-border-width, 1px) var(--field-border-style, solid) var(--field-border-color, #c4c7c5);border-radius:calc(var(--field-radius, 8px) * .75);background:var(--select-popup-bg, var(--kt-surface, #fff));color:var(--field-color, inherit);font:inherit;appearance:none}.kt-select__filter-input::placeholder{color:var(--field-hint-color, #5f6368)}.kt-select__filter-input:focus-visible{outline:2px solid var(--field-border-color-focus, #0b57d0);outline-offset:-1px}.kt-select__filter-input::-webkit-search-cancel-button{appearance:none;inline-size:1rem;block-size:1rem;margin-inline-start:.375rem;cursor:pointer;background-color:var(--field-icon-color, #5f6368);-webkit-mask:url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M19 6.41 17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z'/%3E%3C/svg%3E\") center / contain no-repeat;mask:url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M19 6.41 17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z'/%3E%3C/svg%3E\") center / contain no-repeat}.kt-select__sr-only{position:absolute;inset-block-start:0;inset-inline-start:0;inline-size:1px;block-size:1px;padding:0;margin:-1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap;border:0}@supports (anchor-name: --x){.kt-select__popup{position:fixed;inset:auto;top:anchor(bottom);left:anchor(left);margin-block-start:.25rem;min-inline-size:anchor-size(width);width:max-content;max-inline-size:min(90vw,28rem);position-try-fallbacks:flip-block,flip-inline,flip-block flip-inline}}@supports not (anchor-name: --x){.kt-select__popup{position:fixed;inset:auto 0 0;inline-size:100%;max-inline-size:100%;border-radius:var(--kt-sheet-radius, 16px) var(--kt-sheet-radius, 16px) 0 0}}.kt-select__popup--sheet{position:fixed!important;inset:0!important;inline-size:100%!important;max-inline-size:100%!important;min-inline-size:0!important;width:100%!important;height:100%!important;max-block-size:none!important;margin:0!important;padding:0!important;border:none!important;background:transparent!important;box-shadow:none!important;border-radius:0!important;overflow:visible!important;display:flex;flex-direction:column!important;justify-content:flex-end!important}.kt-select__popup--sheet .kt-select__sheet-card{position:relative;z-index:2;display:flex;flex-direction:column;background:var(--select-popup-bg, var(--kt-surface, #fff));border-radius:var(--kt-sheet-radius, 16px) var(--kt-sheet-radius, 16px) 0 0;box-shadow:var(--kt-sheet-shadow, 0 -4px 16px rgb(0 0 0 / 12%));max-block-size:var(--kt-sheet-max-block-size, 85svh);width:100%;overflow:hidden;translate:0 0;transition:translate var(--kt-sheet-anim-duration, .12s) ease}.kt-select__popup--sheet .kt-select__sheet-card:has(.kt-select__filter){block-size:var(--kt-sheet-max-block-size, 85svh);max-block-size:var(--kt-sheet-max-block-size, 85svh)}.kt-select__popup--sheet:popover-open .kt-select__sheet-card{translate:0 0;animation:var(--select-sheet-enter-animation, kt-sheet-in var(--kt-sheet-anim-duration, .12s) ease)}.kt-select__popup--sheet .kt-select__sheet-card.kt-select__popup--dragging{transition:none}.kt-select__popup--sheet.kt-select__popup--closing .kt-select__sheet-card,.kt-select__popup--sheet:popover-open.kt-select__popup--closing .kt-select__sheet-card{translate:0 100%;transition:translate var(--kt-sheet-exit-duration, 90ms) cubic-bezier(.4,0,.2,1)}::ng-deep .kt-select__popup--sheet::backdrop{display:none!important}.kt-select__sheet-scrim{display:none}.kt-select__popup--sheet .kt-select__sheet-scrim{display:block;position:fixed;inset:0;z-index:1;background:var(--kt-sheet-scrim, rgb(0 0 0 / 40%));opacity:0;pointer-events:auto;transition:opacity var(--kt-sheet-anim-duration, .12s) ease,overlay var(--kt-sheet-anim-duration, .12s) allow-discrete,display var(--kt-sheet-anim-duration, .12s) allow-discrete}.kt-select__popup--sheet:popover-open .kt-select__sheet-scrim{opacity:1}@starting-style{.kt-select__popup--sheet:popover-open .kt-select__sheet-scrim{opacity:0}}.kt-select__popup--sheet.kt-select__popup--closing .kt-select__sheet-scrim,.kt-select__popup--sheet:popover-open.kt-select__popup--closing .kt-select__sheet-scrim{opacity:0;transition:opacity var(--kt-sheet-exit-duration, 90ms) ease}.kt-select__popup--sheet .kt-select__option{--select-option-min-height: 44px;padding-block:.625rem}.kt-select__popup--sheet .kt-select__filter-input{font-size:1rem;min-block-size:44px}@media(prefers-reduced-motion:reduce){.kt-select__popup--sheet .kt-select__sheet-card,.kt-select__popup--sheet .kt-select__sheet-scrim{transition:none;translate:0 0}}.kt-select__sheet-grab{display:flex;align-items:center;justify-content:center;flex:none;block-size:44px;cursor:grab;touch-action:none}.kt-select__sheet-grab:active{cursor:grabbing}.kt-select__sheet-grab:before{content:\"\";inline-size:2.25rem;block-size:.25rem;border-radius:999px;background:var(--kt-sheet-grab-color, var(--kt-outline, #c4c7c5))}.kt-select__sheet-header{display:flex;align-items:center;justify-content:space-between;gap:.5rem;flex:none;padding-block:.5rem;padding-inline:1rem .5rem;border-block-end:1px solid var(--field-border-color, #c4c7c5)}.kt-select__sheet-title{font-weight:600}.kt-select__sheet-close{display:inline-flex;align-items:center;justify-content:center;flex:none;inline-size:44px;block-size:44px;padding:0;border:0;border-radius:50%;background:transparent;color:var(--field-icon-color, #5f6368);cursor:pointer}.kt-select__sheet-close:focus-visible{outline:2px solid var(--field-border-color-focus, #0b57d0);outline-offset:2px}.kt-select__sheet-close-icon{font-family:Material Symbols Outlined;font-feature-settings:\"liga\";font-size:1.5rem;line-height:1;-webkit-font-smoothing:antialiased}.kt-select__option{display:flex;align-items:center;gap:.5rem;box-sizing:border-box;min-block-size:var( --select-option-min-height, 44px );padding:.5rem .625rem;border-radius:6px;cursor:pointer}.kt-select__option[aria-selected=true]{background:var(--select-option-selected-bg, color-mix(in srgb, var(--kt-primary, #0b57d0) 14%, transparent));color:var(--select-option-selected-color, inherit);font-weight:var(--select-option-selected-weight, 600)}.kt-select__option--active:not([aria-disabled=true]),.kt-select__option:hover:not([aria-disabled=true]){background:var(--select-option-hover-bg, color-mix(in srgb, currentColor 8%, transparent))}.kt-select__option[aria-disabled=true]{opacity:.5;cursor:not-allowed}.kt-select__empty{padding:.5rem .625rem;color:var(--field-hint-color, #5f6368)}.kt-select__truncated-info{box-sizing:border-box;padding:.5rem .625rem;font-size:.875rem;font-style:italic;color:var(--field-hint-color, #5f6368);border-block-start:1px solid var(--field-border-color, #c4c7c5);pointer-events:none}}\n"] }]
|
|
2196
2428
|
}], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }, { type: i0.Output, args: ["valueChange"] }], selectionChange: [{ type: i0.Output, args: ["selectionChange"] }], optionDef: [{ type: i0.ContentChild, args: [i0.forwardRef(() => KtSelectOptionDef), { isSignal: true }] }], triggerDef: [{ type: i0.ContentChild, args: [i0.forwardRef(() => KtSelectTriggerDef), { isSignal: true }] }] } });
|
|
2197
2429
|
|
|
2198
2430
|
/** Configure les `kt-select` d'un sous-arbre via DI (équivalent du Context provider de react-select).
|
|
@@ -2635,7 +2867,7 @@ class KtChipList {
|
|
|
2635
2867
|
}
|
|
2636
2868
|
}
|
|
2637
2869
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.1", ngImport: i0, type: KtChipList, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
2638
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.1", type: KtChipList, isStandalone: true, selector: "kt-chip-list", inputs: { items: { classPropertyName: "items", publicName: "items", isSignal: true, isRequired: true, transformFunction: null }, itemLabel: { classPropertyName: "itemLabel", publicName: "itemLabel", isSignal: true, isRequired: false, transformFunction: null }, itemKey: { classPropertyName: "itemKey", publicName: "itemKey", isSignal: true, isRequired: false, transformFunction: null }, removable: { classPropertyName: "removable", publicName: "removable", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, readonly: { classPropertyName: "readonly", publicName: "readonly", isSignal: true, isRequired: false, transformFunction: null }, maxVisible: { classPropertyName: "maxVisible", publicName: "maxVisible", isSignal: true, isRequired: false, transformFunction: null }, listLabel: { classPropertyName: "listLabel", publicName: "listLabel", isSignal: true, isRequired: false, transformFunction: null }, removeItemLabel: { classPropertyName: "removeItemLabel", publicName: "removeItemLabel", isSignal: true, isRequired: false, transformFunction: null }, itemRemovedText: { classPropertyName: "itemRemovedText", publicName: "itemRemovedText", isSignal: true, isRequired: false, transformFunction: null }, moreLabel: { classPropertyName: "moreLabel", publicName: "moreLabel", isSignal: true, isRequired: false, transformFunction: null }, lessLabel: { classPropertyName: "lessLabel", publicName: "lessLabel", isSignal: true, isRequired: false, transformFunction: null }, chipTemplate: { classPropertyName: "chipTemplate", publicName: "chipTemplate", isSignal: true, isRequired: false, transformFunction: null }, emptyFocusTarget: { classPropertyName: "emptyFocusTarget", publicName: "emptyFocusTarget", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { removed: "removed" }, host: { listeners: { "keydown": "onKeydown($event)" }, properties: { "attr.data-empty": "items().length === 0 ? '' : null", "attr.data-vt-active": "transitioning() ? '' : null" } }, providers: [{ provide: ChipTransitionScope, useExisting: KtChipList }], queries: [{ propertyName: "itemDef", first: true, predicate: KtChipItemDef, descendants: true, isSignal: true }], viewQueries: [{ propertyName: "chips", predicate: KtChip, descendants: true, isSignal: true }], ngImport: i0, template: "@if (items().length > 0) {\n <div class=\"kt-chip-list\">\n <div class=\"kt-chip-list__items\" role=\"list\" [attr.aria-label]=\"resolvedListLabel()\">\n @for (item of visibleItems(); track keyOf(item); let i = $index) {\n @if (effectiveTemplate(); as tpl) {\n <div role=\"listitem\" class=\"kt-chip-list__item\">\n <ng-container\n [ngTemplateOutlet]=\"tpl\"\n [ngTemplateOutletContext]=\"{ $implicit: item, remove: removeCallback(item, i) }\"\n />\n </div>\n } @else {\n <kt-chip\n role=\"listitem\"\n [removable]=\"showRemove()\"\n [disabled]=\"disabled()\"\n [removeLabel]=\"removeLabelFor(item)\"\n (remove)=\"removeAt(item, i)\"\n >{{ labelOf(item) }}</kt-chip\n >\n }\n }\n </div>\n <!-- Le bouton de repli/d\u00E9pli n'est PAS un chip : hors du role=\"list\" pour ne pas \u00EAtre\n annonc\u00E9 comme un item de la liste (reste dans la m\u00EAme rang\u00E9e flex). -->\n @if (overflow()) {\n <button\n type=\"button\"\n class=\"kt-chip-list__more\"\n [attr.aria-expanded]=\"expanded()\"\n [style.view-transition-name]=\"transitioning() ? moreBtnTransitionName : null\"\n [style.view-transition-class]=\"'chip-transition'\"\n (click)=\"toggleExpanded()\"\n >\n {{ expanded() ? resolvedLessLabel() : resolvedMoreLabel()(hiddenCount()) }}\n </button>\n }\n </div>\n}\n<!-- Annonce des retraits : TOUJOURS rendue (hors du @if, sinon elle dispara\u00EEt avec le dernier chip). -->\n<div class=\"kt-chip-list__status\" role=\"status\" aria-live=\"polite\">{{ status() }}</div>\n", styles: ["@layer kt-aaa.components{:host{display:block}.kt-chip-list{display:flex;flex-wrap:wrap;gap:.5rem}.kt-chip-list__items,.kt-chip-list__item{display:contents}.kt-chip-list__more{display:inline-flex;align-items:center;gap:var(--chip-gap);padding:var(--chip-padding-y) var(--chip-padding-x);border-radius:var(--chip-radius);background:var(--chip-bg);border:1px solid var(--chip-border);box-shadow:var(--chip-shadow, none);font:inherit;font-size:var(--chip-font-size);color:var(--chip-color);cursor:pointer;min-block-size:24px}.kt-chip-list__more:hover{background:var(--chip-bg-hover);box-shadow:var(--chip-shadow-hover, var(--chip-shadow, none))}.kt-chip-list__more:focus-visible{outline:2px solid var(--chip-focus-ring);outline-offset:1px}.kt-chip-list__status{position:absolute;inline-size:1px;block-size:1px;padding:0;margin:-1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap;border:0}@media(pointer:coarse){.kt-chip-list__more{min-block-size:32px}}}\n"], dependencies: [{ kind: "component", type: KtChip, selector: "kt-chip", inputs: ["removable", "disabled", "removeLabel"], outputs: ["remove"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
2870
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.1", type: KtChipList, isStandalone: true, selector: "kt-chip-list", inputs: { items: { classPropertyName: "items", publicName: "items", isSignal: true, isRequired: true, transformFunction: null }, itemLabel: { classPropertyName: "itemLabel", publicName: "itemLabel", isSignal: true, isRequired: false, transformFunction: null }, itemKey: { classPropertyName: "itemKey", publicName: "itemKey", isSignal: true, isRequired: false, transformFunction: null }, removable: { classPropertyName: "removable", publicName: "removable", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, readonly: { classPropertyName: "readonly", publicName: "readonly", isSignal: true, isRequired: false, transformFunction: null }, maxVisible: { classPropertyName: "maxVisible", publicName: "maxVisible", isSignal: true, isRequired: false, transformFunction: null }, listLabel: { classPropertyName: "listLabel", publicName: "listLabel", isSignal: true, isRequired: false, transformFunction: null }, removeItemLabel: { classPropertyName: "removeItemLabel", publicName: "removeItemLabel", isSignal: true, isRequired: false, transformFunction: null }, itemRemovedText: { classPropertyName: "itemRemovedText", publicName: "itemRemovedText", isSignal: true, isRequired: false, transformFunction: null }, moreLabel: { classPropertyName: "moreLabel", publicName: "moreLabel", isSignal: true, isRequired: false, transformFunction: null }, lessLabel: { classPropertyName: "lessLabel", publicName: "lessLabel", isSignal: true, isRequired: false, transformFunction: null }, chipTemplate: { classPropertyName: "chipTemplate", publicName: "chipTemplate", isSignal: true, isRequired: false, transformFunction: null }, emptyFocusTarget: { classPropertyName: "emptyFocusTarget", publicName: "emptyFocusTarget", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { removed: "removed" }, host: { listeners: { "keydown": "onKeydown($event)" }, properties: { "attr.data-empty": "items().length === 0 ? '' : null", "attr.data-vt-active": "transitioning() ? '' : null" } }, providers: [{ provide: ChipTransitionScope, useExisting: KtChipList }], queries: [{ propertyName: "itemDef", first: true, predicate: KtChipItemDef, descendants: true, isSignal: true }], viewQueries: [{ propertyName: "chips", predicate: KtChip, descendants: true, isSignal: true }], ngImport: i0, template: "@if (items().length > 0) {\n <div class=\"kt-chip-list\">\n <div class=\"kt-chip-list__items\" role=\"list\" [attr.aria-label]=\"resolvedListLabel()\">\n @for (item of visibleItems(); track keyOf(item); let i = $index) {\n @if (effectiveTemplate(); as tpl) {\n <div role=\"listitem\" class=\"kt-chip-list__item\">\n <ng-container\n [ngTemplateOutlet]=\"tpl\"\n [ngTemplateOutletContext]=\"{ $implicit: item, remove: removeCallback(item, i) }\"\n />\n </div>\n } @else {\n <kt-chip\n role=\"listitem\"\n [removable]=\"showRemove()\"\n [disabled]=\"disabled()\"\n [removeLabel]=\"removeLabelFor(item)\"\n (remove)=\"removeAt(item, i)\"\n >{{ labelOf(item) }}</kt-chip\n >\n }\n }\n </div>\n <!-- Le bouton de repli/d\u00E9pli n'est PAS un chip : hors du role=\"list\" pour ne pas \u00EAtre\n annonc\u00E9 comme un item de la liste (reste dans la m\u00EAme rang\u00E9e flex). -->\n @if (overflow()) {\n <button\n type=\"button\"\n class=\"kt-chip-list__more\"\n [attr.aria-expanded]=\"expanded()\"\n [style.view-transition-name]=\"transitioning() ? moreBtnTransitionName : null\"\n [style.view-transition-class]=\"'chip-transition'\"\n (click)=\"toggleExpanded()\"\n >\n {{ expanded() ? resolvedLessLabel() : resolvedMoreLabel()(hiddenCount()) }}\n </button>\n }\n </div>\n}\n<!-- Annonce des retraits : TOUJOURS rendue (hors du @if, sinon elle dispara\u00EEt avec le dernier chip). -->\n<div class=\"kt-chip-list__status\" role=\"status\" aria-live=\"polite\">{{ status() }}</div>\n", styles: ["@layer kt-aaa.components{:host{display:block}.kt-chip-list{display:flex;flex-wrap:wrap;gap:.5rem}.kt-chip-list__items,.kt-chip-list__item{display:contents}.kt-chip-list__more{display:inline-flex;align-items:center;gap:var(--chip-gap);padding:var(--chip-padding-y) var(--chip-padding-x);border-radius:var(--chip-radius);background:var(--chip-bg);border:1px solid var(--chip-border);box-shadow:var(--chip-shadow, none);font:inherit;font-size:var(--chip-font-size);color:var(--chip-color);cursor:pointer;min-block-size:24px}.kt-chip-list__more:hover{background:var(--chip-bg-hover);box-shadow:var(--chip-shadow-hover, var(--chip-shadow, none))}.kt-chip-list__more:focus-visible{outline:2px solid var(--chip-focus-ring);outline-offset:1px}.kt-chip-list__status{position:absolute;inset-block-start:0;inset-inline-start:0;inline-size:1px;block-size:1px;padding:0;margin:-1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap;border:0}@media(pointer:coarse){.kt-chip-list__more{min-block-size:32px}}}\n"], dependencies: [{ kind: "component", type: KtChip, selector: "kt-chip", inputs: ["removable", "disabled", "removeLabel"], outputs: ["remove"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
2639
2871
|
}
|
|
2640
2872
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.1", ngImport: i0, type: KtChipList, decorators: [{
|
|
2641
2873
|
type: Component,
|
|
@@ -2645,7 +2877,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.1", ngImpor
|
|
|
2645
2877
|
// nomment les chips à template custom QUE sous ce marqueur (cf. ChipTransitionScope).
|
|
2646
2878
|
'[attr.data-vt-active]': "transitioning() ? '' : null",
|
|
2647
2879
|
'(keydown)': 'onKeydown($event)',
|
|
2648
|
-
}, template: "@if (items().length > 0) {\n <div class=\"kt-chip-list\">\n <div class=\"kt-chip-list__items\" role=\"list\" [attr.aria-label]=\"resolvedListLabel()\">\n @for (item of visibleItems(); track keyOf(item); let i = $index) {\n @if (effectiveTemplate(); as tpl) {\n <div role=\"listitem\" class=\"kt-chip-list__item\">\n <ng-container\n [ngTemplateOutlet]=\"tpl\"\n [ngTemplateOutletContext]=\"{ $implicit: item, remove: removeCallback(item, i) }\"\n />\n </div>\n } @else {\n <kt-chip\n role=\"listitem\"\n [removable]=\"showRemove()\"\n [disabled]=\"disabled()\"\n [removeLabel]=\"removeLabelFor(item)\"\n (remove)=\"removeAt(item, i)\"\n >{{ labelOf(item) }}</kt-chip\n >\n }\n }\n </div>\n <!-- Le bouton de repli/d\u00E9pli n'est PAS un chip : hors du role=\"list\" pour ne pas \u00EAtre\n annonc\u00E9 comme un item de la liste (reste dans la m\u00EAme rang\u00E9e flex). -->\n @if (overflow()) {\n <button\n type=\"button\"\n class=\"kt-chip-list__more\"\n [attr.aria-expanded]=\"expanded()\"\n [style.view-transition-name]=\"transitioning() ? moreBtnTransitionName : null\"\n [style.view-transition-class]=\"'chip-transition'\"\n (click)=\"toggleExpanded()\"\n >\n {{ expanded() ? resolvedLessLabel() : resolvedMoreLabel()(hiddenCount()) }}\n </button>\n }\n </div>\n}\n<!-- Annonce des retraits : TOUJOURS rendue (hors du @if, sinon elle dispara\u00EEt avec le dernier chip). -->\n<div class=\"kt-chip-list__status\" role=\"status\" aria-live=\"polite\">{{ status() }}</div>\n", styles: ["@layer kt-aaa.components{:host{display:block}.kt-chip-list{display:flex;flex-wrap:wrap;gap:.5rem}.kt-chip-list__items,.kt-chip-list__item{display:contents}.kt-chip-list__more{display:inline-flex;align-items:center;gap:var(--chip-gap);padding:var(--chip-padding-y) var(--chip-padding-x);border-radius:var(--chip-radius);background:var(--chip-bg);border:1px solid var(--chip-border);box-shadow:var(--chip-shadow, none);font:inherit;font-size:var(--chip-font-size);color:var(--chip-color);cursor:pointer;min-block-size:24px}.kt-chip-list__more:hover{background:var(--chip-bg-hover);box-shadow:var(--chip-shadow-hover, var(--chip-shadow, none))}.kt-chip-list__more:focus-visible{outline:2px solid var(--chip-focus-ring);outline-offset:1px}.kt-chip-list__status{position:absolute;inline-size:1px;block-size:1px;padding:0;margin:-1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap;border:0}@media(pointer:coarse){.kt-chip-list__more{min-block-size:32px}}}\n"] }]
|
|
2880
|
+
}, template: "@if (items().length > 0) {\n <div class=\"kt-chip-list\">\n <div class=\"kt-chip-list__items\" role=\"list\" [attr.aria-label]=\"resolvedListLabel()\">\n @for (item of visibleItems(); track keyOf(item); let i = $index) {\n @if (effectiveTemplate(); as tpl) {\n <div role=\"listitem\" class=\"kt-chip-list__item\">\n <ng-container\n [ngTemplateOutlet]=\"tpl\"\n [ngTemplateOutletContext]=\"{ $implicit: item, remove: removeCallback(item, i) }\"\n />\n </div>\n } @else {\n <kt-chip\n role=\"listitem\"\n [removable]=\"showRemove()\"\n [disabled]=\"disabled()\"\n [removeLabel]=\"removeLabelFor(item)\"\n (remove)=\"removeAt(item, i)\"\n >{{ labelOf(item) }}</kt-chip\n >\n }\n }\n </div>\n <!-- Le bouton de repli/d\u00E9pli n'est PAS un chip : hors du role=\"list\" pour ne pas \u00EAtre\n annonc\u00E9 comme un item de la liste (reste dans la m\u00EAme rang\u00E9e flex). -->\n @if (overflow()) {\n <button\n type=\"button\"\n class=\"kt-chip-list__more\"\n [attr.aria-expanded]=\"expanded()\"\n [style.view-transition-name]=\"transitioning() ? moreBtnTransitionName : null\"\n [style.view-transition-class]=\"'chip-transition'\"\n (click)=\"toggleExpanded()\"\n >\n {{ expanded() ? resolvedLessLabel() : resolvedMoreLabel()(hiddenCount()) }}\n </button>\n }\n </div>\n}\n<!-- Annonce des retraits : TOUJOURS rendue (hors du @if, sinon elle dispara\u00EEt avec le dernier chip). -->\n<div class=\"kt-chip-list__status\" role=\"status\" aria-live=\"polite\">{{ status() }}</div>\n", styles: ["@layer kt-aaa.components{:host{display:block}.kt-chip-list{display:flex;flex-wrap:wrap;gap:.5rem}.kt-chip-list__items,.kt-chip-list__item{display:contents}.kt-chip-list__more{display:inline-flex;align-items:center;gap:var(--chip-gap);padding:var(--chip-padding-y) var(--chip-padding-x);border-radius:var(--chip-radius);background:var(--chip-bg);border:1px solid var(--chip-border);box-shadow:var(--chip-shadow, none);font:inherit;font-size:var(--chip-font-size);color:var(--chip-color);cursor:pointer;min-block-size:24px}.kt-chip-list__more:hover{background:var(--chip-bg-hover);box-shadow:var(--chip-shadow-hover, var(--chip-shadow, none))}.kt-chip-list__more:focus-visible{outline:2px solid var(--chip-focus-ring);outline-offset:1px}.kt-chip-list__status{position:absolute;inset-block-start:0;inset-inline-start:0;inline-size:1px;block-size:1px;padding:0;margin:-1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap;border:0}@media(pointer:coarse){.kt-chip-list__more{min-block-size:32px}}}\n"] }]
|
|
2649
2881
|
}], ctorParameters: () => [], propDecorators: { items: [{ type: i0.Input, args: [{ isSignal: true, alias: "items", required: true }] }], itemLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "itemLabel", required: false }] }], itemKey: [{ type: i0.Input, args: [{ isSignal: true, alias: "itemKey", required: false }] }], removable: [{ type: i0.Input, args: [{ isSignal: true, alias: "removable", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], readonly: [{ type: i0.Input, args: [{ isSignal: true, alias: "readonly", required: false }] }], maxVisible: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxVisible", required: false }] }], listLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "listLabel", required: false }] }], removeItemLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "removeItemLabel", required: false }] }], itemRemovedText: [{ type: i0.Input, args: [{ isSignal: true, alias: "itemRemovedText", required: false }] }], moreLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "moreLabel", required: false }] }], lessLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "lessLabel", required: false }] }], chipTemplate: [{ type: i0.Input, args: [{ isSignal: true, alias: "chipTemplate", required: false }] }], emptyFocusTarget: [{ type: i0.Input, args: [{ isSignal: true, alias: "emptyFocusTarget", required: false }] }], removed: [{ type: i0.Output, args: ["removed"] }], itemDef: [{ type: i0.ContentChild, args: [i0.forwardRef(() => KtChipItemDef), { isSignal: true }] }], chips: [{ type: i0.ViewChildren, args: [i0.forwardRef(() => KtChip), { isSignal: true }] }] } });
|
|
2650
2882
|
|
|
2651
2883
|
/** Template de rendu d'une option dans la liste du multi-select. L'input sert à inférer `T` ;
|
|
@@ -2982,7 +3214,7 @@ class KtMultiSelect extends KtBaseSelect {
|
|
|
2982
3214
|
this.announceNow(this.resolvedSelectionCountText()(this.selectedOptions().length));
|
|
2983
3215
|
}
|
|
2984
3216
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.1", ngImport: i0, type: KtMultiSelect, deps: null, target: i0.ɵɵFactoryTarget.Component });
|
|
2985
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.1", type: KtMultiSelect, isStandalone: true, selector: "kt-multi-select", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, clearable: { classPropertyName: "clearable", publicName: "clearable", isSignal: true, isRequired: false, transformFunction: null }, clearLabel: { classPropertyName: "clearLabel", publicName: "clearLabel", isSignal: true, isRequired: false, transformFunction: null }, selectionActions: { classPropertyName: "selectionActions", publicName: "selectionActions", isSignal: true, isRequired: false, transformFunction: null }, maxVisibleChips: { classPropertyName: "maxVisibleChips", publicName: "maxVisibleChips", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange", selectionChange: "selectionChange" }, queries: [{ propertyName: "optionDef", first: true, predicate: KtMultiSelectOptionDef, descendants: true, isSignal: true }, { propertyName: "triggerDef", first: true, predicate: KtMultiSelectTriggerDef, descendants: true, isSignal: true }, { propertyName: "chipDef", first: true, predicate: KtMultiSelectChipDef, descendants: true, isSignal: true }], viewQueries: [{ propertyName: "chipList", first: true, predicate: KtChipList, descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: "<kt-field\n [label]=\"label()\"\n [hint]=\"hint()\"\n [helpText]=\"helpText()\"\n [helpLabel]=\"helpLabel()\"\n [customDescribedBy]=\"customDescribedBy()\"\n [errors]=\"fieldErrors()\"\n [invalid]=\"showInvalid()\"\n [required]=\"required()\"\n [fieldId]=\"id()\"\n [appearance]=\"appearance()\"\n [floatLabel]=\"floatLabel()\"\n (helpClick)=\"helpClick.emit($event)\"\n>\n <ng-content select=\"[ktFieldHelp]\" />\n <div class=\"kt-select\" [class.kt-select--open]=\"expanded()\">\n <button\n #combobox=\"ngCombobox\"\n #trigger\n ngCombobox\n ktFieldControl\n type=\"button\"\n class=\"kt-field-box kt-select__trigger\"\n [class.kt-select__trigger--clearable]=\"showClear()\"\n [(expanded)]=\"expanded\"\n [disabled]=\"disabled()\"\n [softDisabled]=\"false\"\n [attr.data-invalid]=\"showInvalid() ? '' : null\"\n [attr.data-disabled]=\"disabled() ? '' : null\"\n [attr.data-filled]=\"selectedOptions().length ? '' : null\"\n (keydown)=\"onTriggerKeydown($event)\"\n >\n <span class=\"kt-select__value\">\n @if (triggerDef(); as def) {\n <ng-container\n [ngTemplateOutlet]=\"def.template\"\n [ngTemplateOutletContext]=\"{ $implicit: selectedOptions() }\"\n />\n } @else if (selectedOptions().length > 0) {\n {{ triggerText() }}\n } @else {\n <span class=\"kt-select__placeholder\">{{ resolvedPlaceholder() }}</span>\n }\n </span>\n <span class=\"kt-select__arrow\" aria-hidden=\"true\">arrow_drop_down</span>\n </button>\n\n <!-- Tout effacer depuis le champ : sibling du trigger (pas de bouton imbriqu\u00E9 dans un bouton). -->\n @if (showClear()) {\n <button\n type=\"button\"\n class=\"kt-select__clear\"\n [attr.aria-label]=\"clearLabel()\"\n (mousedown)=\"$event.preventDefault()\"\n (click)=\"clearSelection()\"\n >\n <span class=\"kt-select__clear-icon\" aria-hidden=\"true\">close</span>\n </button>\n }\n\n <!-- Popup Popover (top-layer). M\u00EAme logique mobile bottom-sheet adaptative que le select classique. -->\n <ng-template ngComboboxPopup [combobox]=\"combobox\" [popupType]=\"dialogMode() ? 'dialog' : 'listbox'\">\n <div #popup popover=\"manual\" class=\"kt-select__popup\" [class.kt-select__popup--sheet]=\"compact()\">\n @if (compact()) {\n <div class=\"kt-select__sheet-scrim\" aria-hidden=\"true\" (click)=\"expanded.set(false)\"></div>\n }\n <div class=\"kt-select__sheet-card\">\n @if (compact()) {\n <div\n class=\"kt-select__sheet-grab\"\n aria-hidden=\"true\"\n (pointerdown)=\"onDragStart($event)\"\n (mousedown)=\"$event.preventDefault()\"\n ></div>\n <header class=\"kt-select__sheet-header\">\n <span class=\"kt-select__sheet-title\">{{ label() }}</span>\n <button\n type=\"button\"\n class=\"kt-select__sheet-close\"\n [attr.aria-label]=\"resolvedCloseLabel()\"\n (click)=\"expanded.set(false)\"\n >\n <span class=\"kt-select__sheet-close-icon\" aria-hidden=\"true\">close</span>\n </button>\n </header>\n }\n @if (dialogMode()) {\n <!-- Mode panneau (filtre et/ou actions de masse) : Widget Dialog -->\n <div\n ngComboboxWidget\n role=\"dialog\"\n class=\"kt-select__panel\"\n [id]=\"panelId\"\n [attr.aria-label]=\"label()\"\n [activeDescendant]=\"lb.activeDescendant()\"\n (keydown)=\"onPanelKeydown($event)\"\n >\n @if (selectionActions()) {\n <div class=\"kt-select__actions\">\n <button type=\"button\" class=\"kt-select__action\" (click)=\"selectAllFiltered()\">\n {{ resolvedSelectAllLabel() }}\n </button>\n <button type=\"button\" class=\"kt-select__action\" (click)=\"clearAllFiltered()\">\n {{ resolvedClearAllLabel() }}\n </button>\n </div>\n }\n @if (filterable()) {\n <div class=\"kt-select__filter\">\n <input\n #filterInput\n type=\"search\"\n role=\"combobox\"\n aria-autocomplete=\"list\"\n aria-expanded=\"true\"\n class=\"kt-select__filter-input\"\n autocomplete=\"off\"\n [placeholder]=\"resolvedFilterPlaceholder()\"\n [attr.aria-label]=\"resolvedFilterLabel()\"\n [attr.aria-controls]=\"lb.id()\"\n [attr.aria-activedescendant]=\"lb.activeDescendant()\"\n [value]=\"filterText()\"\n (input)=\"onFilterInput($event)\"\n (keydown)=\"onFilterKeydown($event)\"\n />\n </div>\n }\n @if (selectedOptions().length > 0) {\n <!-- Rappel visuel (s\u00E9lections potentiellement masqu\u00E9es par le filtre) ;\n l'info SR passe par la live region ci-dessous \u2192 aria-hidden. -->\n <div class=\"kt-select__count\" aria-hidden=\"true\">{{ selectionCountLabel() }}</div>\n }\n <div class=\"kt-select__sr-only kt-select__filter-status\" role=\"status\" aria-live=\"polite\">\n {{ announcedCount() }}\n </div>\n <ul\n #lb=\"ngListbox\"\n #listboxEl\n ngListbox\n [multi]=\"true\"\n [focusMode]=\"compact() && !filterable() ? 'roving' : 'activedescendant'\"\n selectionMode=\"explicit\"\n class=\"kt-select__listbox\"\n [attr.aria-label]=\"label()\"\n [value]=\"listboxValue()\"\n (valueChange)=\"onListboxValueChange($event)\"\n [disabled]=\"disabled()\"\n [readonly]=\"readonly()\"\n >\n @for (item of displayedOptions(); track keyOf(item)) {\n <li\n #opt=\"ngOption\"\n ngOption\n class=\"kt-select__option kt-select__option--multiple\"\n [value]=\"keyOf(item)\"\n [label]=\"labelOf(item)\"\n [disabled]=\"disabledOf(item)\"\n [class.kt-select__option--active]=\"opt.active()\"\n >\n <span class=\"kt-select__checkbox\" aria-hidden=\"true\">\n @if (opt.selected()) {\n <span class=\"kt-select__checkbox-icon\">check_box</span>\n } @else {\n <span class=\"kt-select__checkbox-icon\">check_box_outline_blank</span>\n }\n </span>\n <span class=\"kt-select__option-content\">\n @if (optionDef(); as def) {\n <ng-container\n [ngTemplateOutlet]=\"def.template\"\n [ngTemplateOutletContext]=\"{\n $implicit: item,\n selected: !!opt.selected(),\n active: opt.active(),\n }\"\n />\n } @else {\n {{ labelOf(item) }}\n }\n </span>\n </li>\n } @empty {\n <li class=\"kt-select__empty\" role=\"option\" aria-disabled=\"true\" aria-selected=\"false\">\n {{ resolvedEmptyText() }}\n </li>\n }\n @if (filterable() && filteredOptions().length > maxVisibleOptions()) {\n <li class=\"kt-select__truncated-info\" role=\"option\" aria-disabled=\"true\" aria-selected=\"false\">\n {{ resolvedTruncatedResultsText()(maxVisibleOptions(), filteredOptions().length) }}\n </li>\n }\n </ul>\n </div>\n } @else {\n <!-- Mode simple : Widget Listbox direct -->\n <ul\n #listbox=\"ngListbox\"\n #listboxEl\n ngComboboxWidget\n ngListbox\n [multi]=\"true\"\n [focusMode]=\"compact() ? 'roving' : 'activedescendant'\"\n selectionMode=\"explicit\"\n class=\"kt-select__listbox\"\n [attr.aria-label]=\"label()\"\n [value]=\"listboxValue()\"\n (valueChange)=\"onListboxValueChange($event)\"\n [disabled]=\"disabled()\"\n [readonly]=\"readonly()\"\n [activeDescendant]=\"listbox.activeDescendant()\"\n >\n @for (item of options(); track keyOf(item)) {\n <li\n #opt=\"ngOption\"\n ngOption\n class=\"kt-select__option kt-select__option--multiple\"\n [value]=\"keyOf(item)\"\n [label]=\"labelOf(item)\"\n [disabled]=\"disabledOf(item)\"\n [class.kt-select__option--active]=\"opt.active()\"\n >\n <span class=\"kt-select__checkbox\" aria-hidden=\"true\">\n @if (opt.selected()) {\n <span class=\"kt-select__checkbox-icon\">check_box</span>\n } @else {\n <span class=\"kt-select__checkbox-icon\">check_box_outline_blank</span>\n }\n </span>\n <span class=\"kt-select__option-content\">\n @if (optionDef(); as def) {\n <ng-container\n [ngTemplateOutlet]=\"def.template\"\n [ngTemplateOutletContext]=\"{\n $implicit: item,\n selected: !!opt.selected(),\n active: opt.active(),\n }\"\n />\n } @else {\n {{ labelOf(item) }}\n }\n </span>\n </li>\n } @empty {\n <li class=\"kt-select__empty\" role=\"option\" aria-disabled=\"true\" aria-selected=\"false\">\n {{ resolvedEmptyText() }}\n </li>\n }\n </ul>\n }\n </div>\n </div>\n </ng-template>\n </div>\n\n <!-- Chips r\u00E9vocables (Option 1) sous le trigger : d\u00E9l\u00E9gu\u00E9s au composant r\u00E9utilisable\n kt-chip-list (focus management, repli +N, live region). Les textes r\u00E9solus depuis\n KT_SELECT_CONFIG sont pass\u00E9s en inputs (ils priment sur un \u00E9ventuel KT_CHIPS_CONFIG). -->\n <kt-chip-list\n [items]=\"selectedOptions()\"\n [itemLabel]=\"chipLabelOf\"\n [itemKey]=\"chipKeyOf\"\n [disabled]=\"disabled()\"\n [readonly]=\"readonly()\"\n [maxVisible]=\"maxVisibleChips()\"\n [listLabel]=\"resolvedSelectedItemsLabel()\"\n [removeItemLabel]=\"resolvedRemoveItemLabel()\"\n [itemRemovedText]=\"resolvedItemRemovedText()\"\n [moreLabel]=\"resolvedMoreChipsLabel()\"\n [lessLabel]=\"resolvedLessChipsLabel()\"\n [chipTemplate]=\"chipDef()?.template ?? null\"\n [emptyFocusTarget]=\"triggerEl()?.nativeElement\"\n (removed)=\"removeOption($event.item)\"\n />\n</kt-field>\n", styles: ["@layer kt-aaa.components{:host{display:block}.kt-select{position:relative}.kt-select__trigger{display:flex;align-items:center;justify-content:space-between;gap:var(--field-control-gap, .5rem);inline-size:100%;cursor:pointer;text-align:start;font:inherit;color:var(--field-color, inherit)}.kt-select__trigger:disabled{cursor:not-allowed;background:var(--field-disabled-bg, #f1f3f4);color:color-mix(in srgb,currentColor 50%,transparent)}.kt-select__value{flex:1;min-inline-size:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.kt-select__placeholder{color:var(--field-hint-color, #5f6368)}.kt-select__arrow{flex:none;font-family:Material Symbols Outlined;font-size:1.25em;line-height:1;font-feature-settings:\"liga\";color:var(--field-icon-color, #5f6368);transition:var(--select-arrow-transition, transform .12s ease);-webkit-font-smoothing:antialiased}.kt-select--open .kt-select__arrow{transform:rotate(180deg)}.kt-select__popup{box-sizing:border-box;display:flex;flex-direction:column;margin:0;padding:0;border-width:var(--select-popup-border-width, var(--field-border-width, 1px));border-style:var(--field-border-style, solid);border-color:var(--field-border-color, #c4c7c5);border-radius:var(--field-radius, 8px);background:var(--select-popup-bg, var(--kt-surface, #fff));color:var(--field-color, inherit);box-shadow:var(--select-popup-shadow, 0 4px 12px rgb(0 0 0 / 12%));-webkit-backdrop-filter:var(--select-popup-backdrop-filter, none);backdrop-filter:var(--select-popup-backdrop-filter, none);max-block-size:var(--select-popup-max-height, 16rem);overflow:hidden}.kt-select__sheet-card{display:contents}.kt-select__popup:not(:popover-open){display:none!important}.kt-select__popup:popover-open{animation:var(--select-popup-enter-animation, none)}@media(prefers-reduced-motion:reduce){.kt-select__popup:popover-open{animation:none}}.kt-select__listbox{flex:1 1 auto;min-block-size:0;margin:0;padding:.25rem;list-style:none;overflow-y:auto}.kt-select__panel{display:flex;flex-direction:column;flex:1 1 auto;min-block-size:0}.kt-select__filter{flex:none;padding:.5rem;border-block-end:1px solid var(--field-border-color, #c4c7c5)}.kt-select__filter-input{box-sizing:border-box;inline-size:100%;min-block-size:var(--field-min-height, 44px);padding:.375rem .625rem;border:var(--field-border-width, 1px) var(--field-border-style, solid) var(--field-border-color, #c4c7c5);border-radius:calc(var(--field-radius, 8px) * .75);background:var(--select-popup-bg, var(--kt-surface, #fff));color:var(--field-color, inherit);font:inherit;appearance:none}.kt-select__filter-input::placeholder{color:var(--field-hint-color, #5f6368)}.kt-select__filter-input:focus-visible{outline:2px solid var(--field-border-color-focus, #0b57d0);outline-offset:-1px}.kt-select__filter-input::-webkit-search-cancel-button{appearance:none;inline-size:1rem;block-size:1rem;margin-inline-start:.375rem;cursor:pointer;background-color:var(--field-icon-color, #5f6368);-webkit-mask:url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M19 6.41 17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z'/%3E%3C/svg%3E\") center / contain no-repeat;mask:url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M19 6.41 17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z'/%3E%3C/svg%3E\") center / contain no-repeat}.kt-select__sr-only{position:absolute;inline-size:1px;block-size:1px;padding:0;margin:-1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap;border:0}@supports (anchor-name: --x){.kt-select__popup{position:fixed;inset:auto;top:anchor(bottom);left:anchor(left);margin-block-start:.25rem;min-inline-size:anchor-size(width);width:max-content;max-inline-size:min(90vw,28rem);position-try-fallbacks:flip-block,flip-inline,flip-block flip-inline}}@supports not (anchor-name: --x){.kt-select__popup{position:fixed;inset:auto 0 0;inline-size:100%;max-inline-size:100%;border-radius:var(--kt-sheet-radius, 16px) var(--kt-sheet-radius, 16px) 0 0}}.kt-select__popup--sheet{position:fixed!important;inset:0!important;inline-size:100%!important;max-inline-size:100%!important;min-inline-size:0!important;width:100%!important;height:100%!important;max-block-size:none!important;margin:0!important;padding:0!important;border:none!important;background:transparent!important;box-shadow:none!important;border-radius:0!important;overflow:visible!important;display:flex;flex-direction:column!important;justify-content:flex-end!important}.kt-select__popup--sheet .kt-select__sheet-card{position:relative;z-index:2;display:flex;flex-direction:column;background:var(--select-popup-bg, var(--kt-surface, #fff));border-radius:var(--kt-sheet-radius, 16px) var(--kt-sheet-radius, 16px) 0 0;box-shadow:var(--kt-sheet-shadow, 0 -4px 16px rgb(0 0 0 / 12%));max-block-size:var(--kt-sheet-max-block-size, 85svh);width:100%;overflow:hidden;translate:0 0;transition:translate var(--kt-sheet-anim-duration, .12s) ease}.kt-select__popup--sheet .kt-select__sheet-card:has(.kt-select__filter){block-size:var(--kt-sheet-max-block-size, 85svh);max-block-size:var(--kt-sheet-max-block-size, 85svh)}.kt-select__popup--sheet:popover-open .kt-select__sheet-card{translate:0 0;animation:var(--select-sheet-enter-animation, kt-sheet-in var(--kt-sheet-anim-duration, .12s) ease)}.kt-select__popup--sheet .kt-select__sheet-card.kt-select__popup--dragging{transition:none}.kt-select__popup--sheet.kt-select__popup--closing .kt-select__sheet-card,.kt-select__popup--sheet:popover-open.kt-select__popup--closing .kt-select__sheet-card{translate:0 100%;transition:translate var(--kt-sheet-exit-duration, 90ms) cubic-bezier(.4,0,.2,1)}::ng-deep .kt-select__popup--sheet::backdrop{display:none!important}.kt-select__sheet-scrim{display:none}.kt-select__popup--sheet .kt-select__sheet-scrim{display:block;position:fixed;inset:0;z-index:1;background:var(--kt-sheet-scrim, rgb(0 0 0 / 40%));opacity:0;pointer-events:auto;transition:opacity var(--kt-sheet-anim-duration, .12s) ease,overlay var(--kt-sheet-anim-duration, .12s) allow-discrete,display var(--kt-sheet-anim-duration, .12s) allow-discrete}.kt-select__popup--sheet:popover-open .kt-select__sheet-scrim{opacity:1}@starting-style{.kt-select__popup--sheet:popover-open .kt-select__sheet-scrim{opacity:0}}.kt-select__popup--sheet.kt-select__popup--closing .kt-select__sheet-scrim,.kt-select__popup--sheet:popover-open.kt-select__popup--closing .kt-select__sheet-scrim{opacity:0;transition:opacity var(--kt-sheet-exit-duration, 90ms) ease}.kt-select__popup--sheet .kt-select__option{--select-option-min-height: 44px;padding-block:.625rem}.kt-select__popup--sheet .kt-select__filter-input{font-size:1rem;min-block-size:44px}@media(prefers-reduced-motion:reduce){.kt-select__popup--sheet .kt-select__sheet-card,.kt-select__popup--sheet .kt-select__sheet-scrim{transition:none;translate:0 0}}.kt-select__sheet-grab{display:flex;align-items:center;justify-content:center;flex:none;block-size:44px;cursor:grab;touch-action:none}.kt-select__sheet-grab:active{cursor:grabbing}.kt-select__sheet-grab:before{content:\"\";inline-size:2.25rem;block-size:.25rem;border-radius:999px;background:var(--kt-sheet-grab-color, var(--kt-outline, #c4c7c5))}.kt-select__sheet-header{display:flex;align-items:center;justify-content:space-between;gap:.5rem;flex:none;padding-block:.5rem;padding-inline:1rem .5rem;border-block-end:1px solid var(--field-border-color, #c4c7c5)}.kt-select__sheet-title{font-weight:600}.kt-select__sheet-close{display:inline-flex;align-items:center;justify-content:center;flex:none;inline-size:44px;block-size:44px;padding:0;border:0;border-radius:50%;background:transparent;color:var(--field-icon-color, #5f6368);cursor:pointer}.kt-select__sheet-close:focus-visible{outline:2px solid var(--field-border-color-focus, #0b57d0);outline-offset:2px}.kt-select__sheet-close-icon{font-family:Material Symbols Outlined;font-feature-settings:\"liga\";font-size:1.5rem;line-height:1;-webkit-font-smoothing:antialiased}.kt-select__option{display:flex;align-items:center;gap:.5rem;box-sizing:border-box;min-block-size:var( --select-option-min-height, 44px );padding:.5rem .625rem;border-radius:6px;cursor:pointer}.kt-select__option[aria-selected=true]{background:var(--select-option-selected-bg, color-mix(in srgb, var(--kt-primary, #0b57d0) 14%, transparent));color:var(--select-option-selected-color, inherit);font-weight:var(--select-option-selected-weight, 600)}.kt-select__option--active:not([aria-disabled=true]),.kt-select__option:hover:not([aria-disabled=true]){background:var(--select-option-hover-bg, color-mix(in srgb, currentColor 8%, transparent))}.kt-select__option[aria-disabled=true]{opacity:.5;cursor:not-allowed}.kt-select__empty{padding:.5rem .625rem;color:var(--field-hint-color, #5f6368)}.kt-select__truncated-info{box-sizing:border-box;padding:.5rem .625rem;font-size:.875rem;font-style:italic;color:var(--field-hint-color, #5f6368);border-block-start:1px solid var(--field-border-color, #c4c7c5);pointer-events:none}}\n", "@layer kt-aaa.components{.kt-select__trigger--clearable .kt-select__value{margin-inline-end:2rem}.kt-select__clear{position:absolute;inset-block-start:50%;inset-inline-end:2.5rem;translate:0 -50%;display:inline-flex;align-items:center;justify-content:center;inline-size:24px;block-size:24px;padding:0;border:0;border-radius:50%;background:transparent;color:var(--field-icon-color, #5f6368);cursor:pointer}.kt-select__clear:after{content:\"\";position:absolute;inset:-10px}.kt-select__clear:hover{background-color:color-mix(in srgb,currentColor 12%,transparent);color:var(--field-color, inherit)}.kt-select__clear:focus-visible{outline:2px solid var(--field-border-color-focus, #0b57d0);outline-offset:1px}.kt-select__clear-icon{font-family:Material Symbols Outlined;font-feature-settings:\"liga\";font-size:1.25rem;line-height:1;-webkit-font-smoothing:antialiased}.kt-select__actions{display:flex;gap:.25rem;flex:none;padding:.25rem .5rem;border-block-end:1px solid var(--field-border-color, #c4c7c5)}.kt-select__action{flex:1;min-block-size:44px;padding:.375rem .625rem;border:0;border-radius:calc(var(--field-radius, 8px) * .75);background:transparent;color:var(--kt-primary, #0b57d0);font:inherit;font-weight:500;cursor:pointer}.kt-select__action:hover{background:var(--select-option-hover-bg, color-mix(in srgb, currentColor 8%, transparent))}.kt-select__action:focus-visible{outline:2px solid var(--field-border-color-focus, #0b57d0);outline-offset:-2px}.kt-select__count{flex:none;padding:.25rem .75rem;font-size:.8125rem;color:var(--field-hint-color, #5f6368);border-block-end:1px solid var(--field-border-color, #c4c7c5)}.kt-select__checkbox{display:inline-flex;align-items:center;justify-content:center;flex:none;margin-inline-end:.25rem;-webkit-user-select:none;user-select:none}.kt-select__checkbox-icon{font-family:Material Symbols Outlined;font-feature-settings:\"liga\";font-size:1.25rem;line-height:1;color:var(--field-icon-color, #5f6368);-webkit-font-smoothing:antialiased}.kt-select__option[aria-selected=true] .kt-select__checkbox-icon{color:var(--kt-primary, #0b57d0)}.kt-select__option--multiple{display:flex;align-items:center;gap:.5rem}.kt-select__option-content{flex:1;min-inline-size:0}kt-chip-list:not([data-empty]){margin-block-start:.5rem}}\n"], dependencies: [{ kind: "component", type: KtField, selector: "kt-field", inputs: ["label", "hint", "helpText", "helpLabel", "customDescribedBy", "errors", "invalid", "required", "fieldId", "hideHintWhenInvalid", "showAllErrors", "appearance", "floatLabel"], outputs: ["helpClick"] }, { kind: "directive", type: KtFieldControl, selector: "[ktFieldControl]" }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: Combobox, selector: "[ngCombobox]", inputs: ["disabled", "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: "component", type: KtChipList, selector: "kt-chip-list", inputs: ["items", "itemLabel", "itemKey", "removable", "disabled", "readonly", "maxVisible", "listLabel", "removeItemLabel", "itemRemovedText", "moreLabel", "lessLabel", "chipTemplate", "emptyFocusTarget"], outputs: ["removed"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
3217
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.1", type: KtMultiSelect, isStandalone: true, selector: "kt-multi-select", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, clearable: { classPropertyName: "clearable", publicName: "clearable", isSignal: true, isRequired: false, transformFunction: null }, clearLabel: { classPropertyName: "clearLabel", publicName: "clearLabel", isSignal: true, isRequired: false, transformFunction: null }, selectionActions: { classPropertyName: "selectionActions", publicName: "selectionActions", isSignal: true, isRequired: false, transformFunction: null }, maxVisibleChips: { classPropertyName: "maxVisibleChips", publicName: "maxVisibleChips", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange", selectionChange: "selectionChange" }, queries: [{ propertyName: "optionDef", first: true, predicate: KtMultiSelectOptionDef, descendants: true, isSignal: true }, { propertyName: "triggerDef", first: true, predicate: KtMultiSelectTriggerDef, descendants: true, isSignal: true }, { propertyName: "chipDef", first: true, predicate: KtMultiSelectChipDef, descendants: true, isSignal: true }], viewQueries: [{ propertyName: "chipList", first: true, predicate: KtChipList, descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: "<kt-field\n [label]=\"label()\"\n [hint]=\"hint()\"\n [helpText]=\"helpText()\"\n [helpLabel]=\"helpLabel()\"\n [customDescribedBy]=\"customDescribedBy()\"\n [errors]=\"fieldErrors()\"\n [invalid]=\"showInvalid()\"\n [required]=\"required()\"\n [fieldId]=\"id()\"\n [appearance]=\"appearance()\"\n [floatLabel]=\"floatLabel()\"\n (helpClick)=\"helpClick.emit($event)\"\n>\n <ng-content select=\"[ktFieldHelp]\" />\n <div class=\"kt-select\" [class.kt-select--open]=\"expanded()\">\n <button\n #combobox=\"ngCombobox\"\n #trigger\n ngCombobox\n ktFieldControl\n type=\"button\"\n class=\"kt-field-box kt-select__trigger\"\n [class.kt-select__trigger--clearable]=\"showClear()\"\n [(expanded)]=\"expanded\"\n [disabled]=\"disabled()\"\n [softDisabled]=\"false\"\n [attr.data-invalid]=\"showInvalid() ? '' : null\"\n [attr.data-disabled]=\"disabled() ? '' : null\"\n [attr.data-filled]=\"selectedOptions().length ? '' : null\"\n [attr.data-pending]=\"pending() ? '' : null\"\n [attr.aria-busy]=\"pending() ? 'true' : null\"\n (keydown)=\"onTriggerKeydown($event)\"\n >\n <span class=\"kt-select__value\">\n @if (triggerDef(); as def) {\n <ng-container\n [ngTemplateOutlet]=\"def.template\"\n [ngTemplateOutletContext]=\"{ $implicit: selectedOptions() }\"\n />\n } @else if (selectedOptions().length > 0) {\n {{ triggerText() }}\n } @else {\n <span class=\"kt-select__placeholder\">{{ resolvedPlaceholder() }}</span>\n }\n </span>\n <span class=\"kt-select__arrow\" aria-hidden=\"true\">arrow_drop_down</span>\n </button>\n\n <!-- Tout effacer depuis le champ : sibling du trigger (pas de bouton imbriqu\u00E9 dans un bouton). -->\n @if (showClear()) {\n <button\n type=\"button\"\n class=\"kt-select__clear\"\n [attr.aria-label]=\"clearLabel()\"\n (mousedown)=\"$event.preventDefault()\"\n (click)=\"clearSelection()\"\n >\n <span class=\"kt-select__clear-icon\" aria-hidden=\"true\">close</span>\n </button>\n }\n\n <!-- Popup Popover (top-layer). M\u00EAme logique mobile bottom-sheet adaptative que le select classique. -->\n <ng-template ngComboboxPopup [combobox]=\"combobox\" [popupType]=\"dialogMode() ? 'dialog' : 'listbox'\">\n <div #popup popover=\"manual\" class=\"kt-select__popup\" [class.kt-select__popup--sheet]=\"compact()\">\n @if (compact()) {\n <div class=\"kt-select__sheet-scrim\" aria-hidden=\"true\" (click)=\"expanded.set(false)\"></div>\n }\n <div class=\"kt-select__sheet-card\">\n @if (compact()) {\n <div\n class=\"kt-select__sheet-grab\"\n aria-hidden=\"true\"\n (pointerdown)=\"onDragStart($event)\"\n (mousedown)=\"$event.preventDefault()\"\n ></div>\n <header class=\"kt-select__sheet-header\">\n <span class=\"kt-select__sheet-title\">{{ label() }}</span>\n <button\n type=\"button\"\n class=\"kt-select__sheet-close\"\n [attr.aria-label]=\"resolvedCloseLabel()\"\n (click)=\"expanded.set(false)\"\n >\n <span class=\"kt-select__sheet-close-icon\" aria-hidden=\"true\">close</span>\n </button>\n </header>\n }\n @if (dialogMode()) {\n <!-- Mode panneau (filtre et/ou actions de masse) : Widget Dialog -->\n <div\n ngComboboxWidget\n role=\"dialog\"\n class=\"kt-select__panel\"\n [id]=\"panelId\"\n [attr.aria-label]=\"label()\"\n [activeDescendant]=\"lb.activeDescendant()\"\n (keydown)=\"onPanelKeydown($event)\"\n >\n @if (selectionActions()) {\n <div class=\"kt-select__actions\">\n <button type=\"button\" class=\"kt-select__action\" (click)=\"selectAllFiltered()\">\n {{ resolvedSelectAllLabel() }}\n </button>\n <button type=\"button\" class=\"kt-select__action\" (click)=\"clearAllFiltered()\">\n {{ resolvedClearAllLabel() }}\n </button>\n </div>\n }\n @if (filterable()) {\n <div class=\"kt-select__filter\">\n <input\n #filterInput\n type=\"search\"\n role=\"combobox\"\n aria-autocomplete=\"list\"\n aria-expanded=\"true\"\n class=\"kt-select__filter-input\"\n autocomplete=\"off\"\n [placeholder]=\"resolvedFilterPlaceholder()\"\n [attr.aria-label]=\"resolvedFilterLabel()\"\n [attr.aria-controls]=\"lb.id()\"\n [attr.aria-activedescendant]=\"lb.activeDescendant()\"\n [value]=\"filterText()\"\n (input)=\"onFilterInput($event)\"\n (keydown)=\"onFilterKeydown($event)\"\n />\n </div>\n }\n @if (selectedOptions().length > 0) {\n <!-- Rappel visuel (s\u00E9lections potentiellement masqu\u00E9es par le filtre) ;\n l'info SR passe par la live region ci-dessous \u2192 aria-hidden. -->\n <div class=\"kt-select__count\" aria-hidden=\"true\">{{ selectionCountLabel() }}</div>\n }\n <div class=\"kt-select__sr-only kt-select__filter-status\" role=\"status\" aria-live=\"polite\">\n {{ announcedCount() }}\n </div>\n <ul\n #lb=\"ngListbox\"\n #listboxEl\n ngListbox\n [multi]=\"true\"\n [focusMode]=\"compact() && !filterable() ? 'roving' : 'activedescendant'\"\n selectionMode=\"explicit\"\n class=\"kt-select__listbox\"\n [attr.aria-label]=\"label()\"\n [value]=\"listboxValue()\"\n (valueChange)=\"onListboxValueChange($event)\"\n [disabled]=\"disabled()\"\n [readonly]=\"readonly()\"\n >\n @for (item of displayedOptions(); track keyOf(item)) {\n <li\n #opt=\"ngOption\"\n ngOption\n class=\"kt-select__option kt-select__option--multiple\"\n [value]=\"keyOf(item)\"\n [label]=\"labelOf(item)\"\n [disabled]=\"disabledOf(item)\"\n [class.kt-select__option--active]=\"opt.active()\"\n >\n <span class=\"kt-select__checkbox\" aria-hidden=\"true\">\n @if (opt.selected()) {\n <span class=\"kt-select__checkbox-icon\">check_box</span>\n } @else {\n <span class=\"kt-select__checkbox-icon\">check_box_outline_blank</span>\n }\n </span>\n <span class=\"kt-select__option-content\">\n @if (optionDef(); as def) {\n <ng-container\n [ngTemplateOutlet]=\"def.template\"\n [ngTemplateOutletContext]=\"{\n $implicit: item,\n selected: !!opt.selected(),\n active: opt.active(),\n }\"\n />\n } @else {\n {{ labelOf(item) }}\n }\n </span>\n </li>\n } @empty {\n <li class=\"kt-select__empty\" role=\"option\" aria-disabled=\"true\" aria-selected=\"false\">\n {{ resolvedEmptyText() }}\n </li>\n }\n @if (filterable() && filteredOptions().length > maxVisibleOptions()) {\n <li class=\"kt-select__truncated-info\" role=\"option\" aria-disabled=\"true\" aria-selected=\"false\">\n {{ resolvedTruncatedResultsText()(maxVisibleOptions(), filteredOptions().length) }}\n </li>\n }\n </ul>\n </div>\n } @else {\n <!-- Mode simple : Widget Listbox direct -->\n <ul\n #listbox=\"ngListbox\"\n #listboxEl\n ngComboboxWidget\n ngListbox\n [multi]=\"true\"\n [focusMode]=\"compact() ? 'roving' : 'activedescendant'\"\n selectionMode=\"explicit\"\n class=\"kt-select__listbox\"\n [attr.aria-label]=\"label()\"\n [value]=\"listboxValue()\"\n (valueChange)=\"onListboxValueChange($event)\"\n [disabled]=\"disabled()\"\n [readonly]=\"readonly()\"\n [activeDescendant]=\"listbox.activeDescendant()\"\n >\n @for (item of options(); track keyOf(item)) {\n <li\n #opt=\"ngOption\"\n ngOption\n class=\"kt-select__option kt-select__option--multiple\"\n [value]=\"keyOf(item)\"\n [label]=\"labelOf(item)\"\n [disabled]=\"disabledOf(item)\"\n [class.kt-select__option--active]=\"opt.active()\"\n >\n <span class=\"kt-select__checkbox\" aria-hidden=\"true\">\n @if (opt.selected()) {\n <span class=\"kt-select__checkbox-icon\">check_box</span>\n } @else {\n <span class=\"kt-select__checkbox-icon\">check_box_outline_blank</span>\n }\n </span>\n <span class=\"kt-select__option-content\">\n @if (optionDef(); as def) {\n <ng-container\n [ngTemplateOutlet]=\"def.template\"\n [ngTemplateOutletContext]=\"{\n $implicit: item,\n selected: !!opt.selected(),\n active: opt.active(),\n }\"\n />\n } @else {\n {{ labelOf(item) }}\n }\n </span>\n </li>\n } @empty {\n <li class=\"kt-select__empty\" role=\"option\" aria-disabled=\"true\" aria-selected=\"false\">\n {{ resolvedEmptyText() }}\n </li>\n }\n </ul>\n }\n </div>\n </div>\n </ng-template>\n </div>\n\n <!-- Chips r\u00E9vocables (Option 1) sous le trigger : d\u00E9l\u00E9gu\u00E9s au composant r\u00E9utilisable\n kt-chip-list (focus management, repli +N, live region). Les textes r\u00E9solus depuis\n KT_SELECT_CONFIG sont pass\u00E9s en inputs (ils priment sur un \u00E9ventuel KT_CHIPS_CONFIG). -->\n <kt-chip-list\n [items]=\"selectedOptions()\"\n [itemLabel]=\"chipLabelOf\"\n [itemKey]=\"chipKeyOf\"\n [disabled]=\"disabled()\"\n [readonly]=\"readonly()\"\n [maxVisible]=\"maxVisibleChips()\"\n [listLabel]=\"resolvedSelectedItemsLabel()\"\n [removeItemLabel]=\"resolvedRemoveItemLabel()\"\n [itemRemovedText]=\"resolvedItemRemovedText()\"\n [moreLabel]=\"resolvedMoreChipsLabel()\"\n [lessLabel]=\"resolvedLessChipsLabel()\"\n [chipTemplate]=\"chipDef()?.template ?? null\"\n [emptyFocusTarget]=\"triggerEl()?.nativeElement\"\n (removed)=\"removeOption($event.item)\"\n />\n</kt-field>\n", styles: ["@layer kt-aaa.components{:host{display:block}.kt-select{position:relative}.kt-select__trigger{display:flex;align-items:center;justify-content:space-between;gap:var(--field-control-gap, .5rem);inline-size:100%;cursor:pointer;text-align:start;font:inherit;color:var(--field-color, inherit)}.kt-select__trigger:disabled{cursor:not-allowed;background:var(--field-disabled-bg, #f1f3f4);color:color-mix(in srgb,currentColor 50%,transparent)}.kt-select__value{flex:1;min-inline-size:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.kt-select__placeholder{color:var(--field-hint-color, #5f6368)}.kt-select__arrow{flex:none;font-family:Material Symbols Outlined;font-size:1.25em;line-height:1;font-feature-settings:\"liga\";color:var(--field-icon-color, #5f6368);transition:var(--select-arrow-transition, transform .12s ease);-webkit-font-smoothing:antialiased}.kt-select--open .kt-select__arrow{transform:rotate(180deg)}.kt-select__popup{box-sizing:border-box;display:flex;flex-direction:column;margin:0;padding:0;border-width:var(--select-popup-border-width, var(--field-border-width, 1px));border-style:var(--field-border-style, solid);border-color:var(--field-border-color, #c4c7c5);border-radius:var(--field-radius, 8px);background:var(--select-popup-bg, var(--kt-surface, #fff));color:var(--field-color, inherit);box-shadow:var(--select-popup-shadow, 0 4px 12px rgb(0 0 0 / 12%));-webkit-backdrop-filter:var(--select-popup-backdrop-filter, none);backdrop-filter:var(--select-popup-backdrop-filter, none);max-block-size:var(--select-popup-max-height, 16rem);overflow:hidden}.kt-select__sheet-card{display:contents}.kt-select__popup:not(:popover-open){display:none!important}.kt-select__popup:popover-open{animation:var(--select-popup-enter-animation, none)}@media(prefers-reduced-motion:reduce){.kt-select__popup:popover-open{animation:none}}.kt-select__listbox{flex:1 1 auto;min-block-size:0;margin:0;padding:.25rem;list-style:none;overflow-y:auto}.kt-select__panel{display:flex;flex-direction:column;flex:1 1 auto;min-block-size:0}.kt-select__filter{flex:none;padding:.5rem;border-block-end:1px solid var(--field-border-color, #c4c7c5)}.kt-select__filter-input{box-sizing:border-box;inline-size:100%;min-block-size:var(--field-min-height, 44px);padding:.375rem .625rem;border:var(--field-border-width, 1px) var(--field-border-style, solid) var(--field-border-color, #c4c7c5);border-radius:calc(var(--field-radius, 8px) * .75);background:var(--select-popup-bg, var(--kt-surface, #fff));color:var(--field-color, inherit);font:inherit;appearance:none}.kt-select__filter-input::placeholder{color:var(--field-hint-color, #5f6368)}.kt-select__filter-input:focus-visible{outline:2px solid var(--field-border-color-focus, #0b57d0);outline-offset:-1px}.kt-select__filter-input::-webkit-search-cancel-button{appearance:none;inline-size:1rem;block-size:1rem;margin-inline-start:.375rem;cursor:pointer;background-color:var(--field-icon-color, #5f6368);-webkit-mask:url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M19 6.41 17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z'/%3E%3C/svg%3E\") center / contain no-repeat;mask:url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M19 6.41 17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z'/%3E%3C/svg%3E\") center / contain no-repeat}.kt-select__sr-only{position:absolute;inset-block-start:0;inset-inline-start:0;inline-size:1px;block-size:1px;padding:0;margin:-1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap;border:0}@supports (anchor-name: --x){.kt-select__popup{position:fixed;inset:auto;top:anchor(bottom);left:anchor(left);margin-block-start:.25rem;min-inline-size:anchor-size(width);width:max-content;max-inline-size:min(90vw,28rem);position-try-fallbacks:flip-block,flip-inline,flip-block flip-inline}}@supports not (anchor-name: --x){.kt-select__popup{position:fixed;inset:auto 0 0;inline-size:100%;max-inline-size:100%;border-radius:var(--kt-sheet-radius, 16px) var(--kt-sheet-radius, 16px) 0 0}}.kt-select__popup--sheet{position:fixed!important;inset:0!important;inline-size:100%!important;max-inline-size:100%!important;min-inline-size:0!important;width:100%!important;height:100%!important;max-block-size:none!important;margin:0!important;padding:0!important;border:none!important;background:transparent!important;box-shadow:none!important;border-radius:0!important;overflow:visible!important;display:flex;flex-direction:column!important;justify-content:flex-end!important}.kt-select__popup--sheet .kt-select__sheet-card{position:relative;z-index:2;display:flex;flex-direction:column;background:var(--select-popup-bg, var(--kt-surface, #fff));border-radius:var(--kt-sheet-radius, 16px) var(--kt-sheet-radius, 16px) 0 0;box-shadow:var(--kt-sheet-shadow, 0 -4px 16px rgb(0 0 0 / 12%));max-block-size:var(--kt-sheet-max-block-size, 85svh);width:100%;overflow:hidden;translate:0 0;transition:translate var(--kt-sheet-anim-duration, .12s) ease}.kt-select__popup--sheet .kt-select__sheet-card:has(.kt-select__filter){block-size:var(--kt-sheet-max-block-size, 85svh);max-block-size:var(--kt-sheet-max-block-size, 85svh)}.kt-select__popup--sheet:popover-open .kt-select__sheet-card{translate:0 0;animation:var(--select-sheet-enter-animation, kt-sheet-in var(--kt-sheet-anim-duration, .12s) ease)}.kt-select__popup--sheet .kt-select__sheet-card.kt-select__popup--dragging{transition:none}.kt-select__popup--sheet.kt-select__popup--closing .kt-select__sheet-card,.kt-select__popup--sheet:popover-open.kt-select__popup--closing .kt-select__sheet-card{translate:0 100%;transition:translate var(--kt-sheet-exit-duration, 90ms) cubic-bezier(.4,0,.2,1)}::ng-deep .kt-select__popup--sheet::backdrop{display:none!important}.kt-select__sheet-scrim{display:none}.kt-select__popup--sheet .kt-select__sheet-scrim{display:block;position:fixed;inset:0;z-index:1;background:var(--kt-sheet-scrim, rgb(0 0 0 / 40%));opacity:0;pointer-events:auto;transition:opacity var(--kt-sheet-anim-duration, .12s) ease,overlay var(--kt-sheet-anim-duration, .12s) allow-discrete,display var(--kt-sheet-anim-duration, .12s) allow-discrete}.kt-select__popup--sheet:popover-open .kt-select__sheet-scrim{opacity:1}@starting-style{.kt-select__popup--sheet:popover-open .kt-select__sheet-scrim{opacity:0}}.kt-select__popup--sheet.kt-select__popup--closing .kt-select__sheet-scrim,.kt-select__popup--sheet:popover-open.kt-select__popup--closing .kt-select__sheet-scrim{opacity:0;transition:opacity var(--kt-sheet-exit-duration, 90ms) ease}.kt-select__popup--sheet .kt-select__option{--select-option-min-height: 44px;padding-block:.625rem}.kt-select__popup--sheet .kt-select__filter-input{font-size:1rem;min-block-size:44px}@media(prefers-reduced-motion:reduce){.kt-select__popup--sheet .kt-select__sheet-card,.kt-select__popup--sheet .kt-select__sheet-scrim{transition:none;translate:0 0}}.kt-select__sheet-grab{display:flex;align-items:center;justify-content:center;flex:none;block-size:44px;cursor:grab;touch-action:none}.kt-select__sheet-grab:active{cursor:grabbing}.kt-select__sheet-grab:before{content:\"\";inline-size:2.25rem;block-size:.25rem;border-radius:999px;background:var(--kt-sheet-grab-color, var(--kt-outline, #c4c7c5))}.kt-select__sheet-header{display:flex;align-items:center;justify-content:space-between;gap:.5rem;flex:none;padding-block:.5rem;padding-inline:1rem .5rem;border-block-end:1px solid var(--field-border-color, #c4c7c5)}.kt-select__sheet-title{font-weight:600}.kt-select__sheet-close{display:inline-flex;align-items:center;justify-content:center;flex:none;inline-size:44px;block-size:44px;padding:0;border:0;border-radius:50%;background:transparent;color:var(--field-icon-color, #5f6368);cursor:pointer}.kt-select__sheet-close:focus-visible{outline:2px solid var(--field-border-color-focus, #0b57d0);outline-offset:2px}.kt-select__sheet-close-icon{font-family:Material Symbols Outlined;font-feature-settings:\"liga\";font-size:1.5rem;line-height:1;-webkit-font-smoothing:antialiased}.kt-select__option{display:flex;align-items:center;gap:.5rem;box-sizing:border-box;min-block-size:var( --select-option-min-height, 44px );padding:.5rem .625rem;border-radius:6px;cursor:pointer}.kt-select__option[aria-selected=true]{background:var(--select-option-selected-bg, color-mix(in srgb, var(--kt-primary, #0b57d0) 14%, transparent));color:var(--select-option-selected-color, inherit);font-weight:var(--select-option-selected-weight, 600)}.kt-select__option--active:not([aria-disabled=true]),.kt-select__option:hover:not([aria-disabled=true]){background:var(--select-option-hover-bg, color-mix(in srgb, currentColor 8%, transparent))}.kt-select__option[aria-disabled=true]{opacity:.5;cursor:not-allowed}.kt-select__empty{padding:.5rem .625rem;color:var(--field-hint-color, #5f6368)}.kt-select__truncated-info{box-sizing:border-box;padding:.5rem .625rem;font-size:.875rem;font-style:italic;color:var(--field-hint-color, #5f6368);border-block-start:1px solid var(--field-border-color, #c4c7c5);pointer-events:none}}\n", "@layer kt-aaa.components{.kt-select__trigger--clearable .kt-select__value{margin-inline-end:2rem}.kt-select__clear{position:absolute;inset-block-start:50%;inset-inline-end:2.5rem;translate:0 -50%;display:inline-flex;align-items:center;justify-content:center;inline-size:24px;block-size:24px;padding:0;border:0;border-radius:50%;background:transparent;color:var(--field-icon-color, #5f6368);cursor:pointer}.kt-select__clear:after{content:\"\";position:absolute;inset:-10px}.kt-select__clear:hover{background-color:color-mix(in srgb,currentColor 12%,transparent);color:var(--field-color, inherit)}.kt-select__clear:focus-visible{outline:2px solid var(--field-border-color-focus, #0b57d0);outline-offset:1px}.kt-select__clear-icon{font-family:Material Symbols Outlined;font-feature-settings:\"liga\";font-size:1.25rem;line-height:1;-webkit-font-smoothing:antialiased}.kt-select__actions{display:flex;gap:.25rem;flex:none;padding:.25rem .5rem;border-block-end:1px solid var(--field-border-color, #c4c7c5)}.kt-select__action{flex:1;min-block-size:44px;padding:.375rem .625rem;border:0;border-radius:calc(var(--field-radius, 8px) * .75);background:transparent;color:var(--kt-primary, #0b57d0);font:inherit;font-weight:500;cursor:pointer}.kt-select__action:hover{background:var(--select-option-hover-bg, color-mix(in srgb, currentColor 8%, transparent))}.kt-select__action:focus-visible{outline:2px solid var(--field-border-color-focus, #0b57d0);outline-offset:-2px}.kt-select__count{flex:none;padding:.25rem .75rem;font-size:.8125rem;color:var(--field-hint-color, #5f6368);border-block-end:1px solid var(--field-border-color, #c4c7c5)}.kt-select__checkbox{display:inline-flex;align-items:center;justify-content:center;flex:none;margin-inline-end:.25rem;-webkit-user-select:none;user-select:none}.kt-select__checkbox-icon{font-family:Material Symbols Outlined;font-feature-settings:\"liga\";font-size:1.25rem;line-height:1;color:var(--field-icon-color, #5f6368);-webkit-font-smoothing:antialiased}.kt-select__option[aria-selected=true] .kt-select__checkbox-icon{color:var(--kt-primary, #0b57d0)}.kt-select__option--multiple{display:flex;align-items:center;gap:.5rem}.kt-select__option-content{flex:1;min-inline-size:0}kt-chip-list:not([data-empty]){margin-block-start:.5rem}}\n"], dependencies: [{ kind: "component", type: KtField, selector: "kt-field", inputs: ["label", "hint", "helpText", "helpLabel", "customDescribedBy", "errors", "invalid", "required", "fieldId", "hideHintWhenInvalid", "showAllErrors", "appearance", "floatLabel"], outputs: ["helpClick"] }, { kind: "directive", type: KtFieldControl, selector: "[ktFieldControl]" }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: Combobox, selector: "[ngCombobox]", inputs: ["disabled", "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: "component", type: KtChipList, selector: "kt-chip-list", inputs: ["items", "itemLabel", "itemKey", "removable", "disabled", "readonly", "maxVisible", "listLabel", "removeItemLabel", "itemRemovedText", "moreLabel", "lessLabel", "chipTemplate", "emptyFocusTarget"], outputs: ["removed"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
2986
3218
|
}
|
|
2987
3219
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.1", ngImport: i0, type: KtMultiSelect, decorators: [{
|
|
2988
3220
|
type: Component,
|
|
@@ -2996,7 +3228,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.1", ngImpor
|
|
|
2996
3228
|
Listbox,
|
|
2997
3229
|
Option,
|
|
2998
3230
|
KtChipList,
|
|
2999
|
-
], template: "<kt-field\n [label]=\"label()\"\n [hint]=\"hint()\"\n [helpText]=\"helpText()\"\n [helpLabel]=\"helpLabel()\"\n [customDescribedBy]=\"customDescribedBy()\"\n [errors]=\"fieldErrors()\"\n [invalid]=\"showInvalid()\"\n [required]=\"required()\"\n [fieldId]=\"id()\"\n [appearance]=\"appearance()\"\n [floatLabel]=\"floatLabel()\"\n (helpClick)=\"helpClick.emit($event)\"\n>\n <ng-content select=\"[ktFieldHelp]\" />\n <div class=\"kt-select\" [class.kt-select--open]=\"expanded()\">\n <button\n #combobox=\"ngCombobox\"\n #trigger\n ngCombobox\n ktFieldControl\n type=\"button\"\n class=\"kt-field-box kt-select__trigger\"\n [class.kt-select__trigger--clearable]=\"showClear()\"\n [(expanded)]=\"expanded\"\n [disabled]=\"disabled()\"\n [softDisabled]=\"false\"\n [attr.data-invalid]=\"showInvalid() ? '' : null\"\n [attr.data-disabled]=\"disabled() ? '' : null\"\n [attr.data-filled]=\"selectedOptions().length ? '' : null\"\n (keydown)=\"onTriggerKeydown($event)\"\n >\n <span class=\"kt-select__value\">\n @if (triggerDef(); as def) {\n <ng-container\n [ngTemplateOutlet]=\"def.template\"\n [ngTemplateOutletContext]=\"{ $implicit: selectedOptions() }\"\n />\n } @else if (selectedOptions().length > 0) {\n {{ triggerText() }}\n } @else {\n <span class=\"kt-select__placeholder\">{{ resolvedPlaceholder() }}</span>\n }\n </span>\n <span class=\"kt-select__arrow\" aria-hidden=\"true\">arrow_drop_down</span>\n </button>\n\n <!-- Tout effacer depuis le champ : sibling du trigger (pas de bouton imbriqu\u00E9 dans un bouton). -->\n @if (showClear()) {\n <button\n type=\"button\"\n class=\"kt-select__clear\"\n [attr.aria-label]=\"clearLabel()\"\n (mousedown)=\"$event.preventDefault()\"\n (click)=\"clearSelection()\"\n >\n <span class=\"kt-select__clear-icon\" aria-hidden=\"true\">close</span>\n </button>\n }\n\n <!-- Popup Popover (top-layer). M\u00EAme logique mobile bottom-sheet adaptative que le select classique. -->\n <ng-template ngComboboxPopup [combobox]=\"combobox\" [popupType]=\"dialogMode() ? 'dialog' : 'listbox'\">\n <div #popup popover=\"manual\" class=\"kt-select__popup\" [class.kt-select__popup--sheet]=\"compact()\">\n @if (compact()) {\n <div class=\"kt-select__sheet-scrim\" aria-hidden=\"true\" (click)=\"expanded.set(false)\"></div>\n }\n <div class=\"kt-select__sheet-card\">\n @if (compact()) {\n <div\n class=\"kt-select__sheet-grab\"\n aria-hidden=\"true\"\n (pointerdown)=\"onDragStart($event)\"\n (mousedown)=\"$event.preventDefault()\"\n ></div>\n <header class=\"kt-select__sheet-header\">\n <span class=\"kt-select__sheet-title\">{{ label() }}</span>\n <button\n type=\"button\"\n class=\"kt-select__sheet-close\"\n [attr.aria-label]=\"resolvedCloseLabel()\"\n (click)=\"expanded.set(false)\"\n >\n <span class=\"kt-select__sheet-close-icon\" aria-hidden=\"true\">close</span>\n </button>\n </header>\n }\n @if (dialogMode()) {\n <!-- Mode panneau (filtre et/ou actions de masse) : Widget Dialog -->\n <div\n ngComboboxWidget\n role=\"dialog\"\n class=\"kt-select__panel\"\n [id]=\"panelId\"\n [attr.aria-label]=\"label()\"\n [activeDescendant]=\"lb.activeDescendant()\"\n (keydown)=\"onPanelKeydown($event)\"\n >\n @if (selectionActions()) {\n <div class=\"kt-select__actions\">\n <button type=\"button\" class=\"kt-select__action\" (click)=\"selectAllFiltered()\">\n {{ resolvedSelectAllLabel() }}\n </button>\n <button type=\"button\" class=\"kt-select__action\" (click)=\"clearAllFiltered()\">\n {{ resolvedClearAllLabel() }}\n </button>\n </div>\n }\n @if (filterable()) {\n <div class=\"kt-select__filter\">\n <input\n #filterInput\n type=\"search\"\n role=\"combobox\"\n aria-autocomplete=\"list\"\n aria-expanded=\"true\"\n class=\"kt-select__filter-input\"\n autocomplete=\"off\"\n [placeholder]=\"resolvedFilterPlaceholder()\"\n [attr.aria-label]=\"resolvedFilterLabel()\"\n [attr.aria-controls]=\"lb.id()\"\n [attr.aria-activedescendant]=\"lb.activeDescendant()\"\n [value]=\"filterText()\"\n (input)=\"onFilterInput($event)\"\n (keydown)=\"onFilterKeydown($event)\"\n />\n </div>\n }\n @if (selectedOptions().length > 0) {\n <!-- Rappel visuel (s\u00E9lections potentiellement masqu\u00E9es par le filtre) ;\n l'info SR passe par la live region ci-dessous \u2192 aria-hidden. -->\n <div class=\"kt-select__count\" aria-hidden=\"true\">{{ selectionCountLabel() }}</div>\n }\n <div class=\"kt-select__sr-only kt-select__filter-status\" role=\"status\" aria-live=\"polite\">\n {{ announcedCount() }}\n </div>\n <ul\n #lb=\"ngListbox\"\n #listboxEl\n ngListbox\n [multi]=\"true\"\n [focusMode]=\"compact() && !filterable() ? 'roving' : 'activedescendant'\"\n selectionMode=\"explicit\"\n class=\"kt-select__listbox\"\n [attr.aria-label]=\"label()\"\n [value]=\"listboxValue()\"\n (valueChange)=\"onListboxValueChange($event)\"\n [disabled]=\"disabled()\"\n [readonly]=\"readonly()\"\n >\n @for (item of displayedOptions(); track keyOf(item)) {\n <li\n #opt=\"ngOption\"\n ngOption\n class=\"kt-select__option kt-select__option--multiple\"\n [value]=\"keyOf(item)\"\n [label]=\"labelOf(item)\"\n [disabled]=\"disabledOf(item)\"\n [class.kt-select__option--active]=\"opt.active()\"\n >\n <span class=\"kt-select__checkbox\" aria-hidden=\"true\">\n @if (opt.selected()) {\n <span class=\"kt-select__checkbox-icon\">check_box</span>\n } @else {\n <span class=\"kt-select__checkbox-icon\">check_box_outline_blank</span>\n }\n </span>\n <span class=\"kt-select__option-content\">\n @if (optionDef(); as def) {\n <ng-container\n [ngTemplateOutlet]=\"def.template\"\n [ngTemplateOutletContext]=\"{\n $implicit: item,\n selected: !!opt.selected(),\n active: opt.active(),\n }\"\n />\n } @else {\n {{ labelOf(item) }}\n }\n </span>\n </li>\n } @empty {\n <li class=\"kt-select__empty\" role=\"option\" aria-disabled=\"true\" aria-selected=\"false\">\n {{ resolvedEmptyText() }}\n </li>\n }\n @if (filterable() && filteredOptions().length > maxVisibleOptions()) {\n <li class=\"kt-select__truncated-info\" role=\"option\" aria-disabled=\"true\" aria-selected=\"false\">\n {{ resolvedTruncatedResultsText()(maxVisibleOptions(), filteredOptions().length) }}\n </li>\n }\n </ul>\n </div>\n } @else {\n <!-- Mode simple : Widget Listbox direct -->\n <ul\n #listbox=\"ngListbox\"\n #listboxEl\n ngComboboxWidget\n ngListbox\n [multi]=\"true\"\n [focusMode]=\"compact() ? 'roving' : 'activedescendant'\"\n selectionMode=\"explicit\"\n class=\"kt-select__listbox\"\n [attr.aria-label]=\"label()\"\n [value]=\"listboxValue()\"\n (valueChange)=\"onListboxValueChange($event)\"\n [disabled]=\"disabled()\"\n [readonly]=\"readonly()\"\n [activeDescendant]=\"listbox.activeDescendant()\"\n >\n @for (item of options(); track keyOf(item)) {\n <li\n #opt=\"ngOption\"\n ngOption\n class=\"kt-select__option kt-select__option--multiple\"\n [value]=\"keyOf(item)\"\n [label]=\"labelOf(item)\"\n [disabled]=\"disabledOf(item)\"\n [class.kt-select__option--active]=\"opt.active()\"\n >\n <span class=\"kt-select__checkbox\" aria-hidden=\"true\">\n @if (opt.selected()) {\n <span class=\"kt-select__checkbox-icon\">check_box</span>\n } @else {\n <span class=\"kt-select__checkbox-icon\">check_box_outline_blank</span>\n }\n </span>\n <span class=\"kt-select__option-content\">\n @if (optionDef(); as def) {\n <ng-container\n [ngTemplateOutlet]=\"def.template\"\n [ngTemplateOutletContext]=\"{\n $implicit: item,\n selected: !!opt.selected(),\n active: opt.active(),\n }\"\n />\n } @else {\n {{ labelOf(item) }}\n }\n </span>\n </li>\n } @empty {\n <li class=\"kt-select__empty\" role=\"option\" aria-disabled=\"true\" aria-selected=\"false\">\n {{ resolvedEmptyText() }}\n </li>\n }\n </ul>\n }\n </div>\n </div>\n </ng-template>\n </div>\n\n <!-- Chips r\u00E9vocables (Option 1) sous le trigger : d\u00E9l\u00E9gu\u00E9s au composant r\u00E9utilisable\n kt-chip-list (focus management, repli +N, live region). Les textes r\u00E9solus depuis\n KT_SELECT_CONFIG sont pass\u00E9s en inputs (ils priment sur un \u00E9ventuel KT_CHIPS_CONFIG). -->\n <kt-chip-list\n [items]=\"selectedOptions()\"\n [itemLabel]=\"chipLabelOf\"\n [itemKey]=\"chipKeyOf\"\n [disabled]=\"disabled()\"\n [readonly]=\"readonly()\"\n [maxVisible]=\"maxVisibleChips()\"\n [listLabel]=\"resolvedSelectedItemsLabel()\"\n [removeItemLabel]=\"resolvedRemoveItemLabel()\"\n [itemRemovedText]=\"resolvedItemRemovedText()\"\n [moreLabel]=\"resolvedMoreChipsLabel()\"\n [lessLabel]=\"resolvedLessChipsLabel()\"\n [chipTemplate]=\"chipDef()?.template ?? null\"\n [emptyFocusTarget]=\"triggerEl()?.nativeElement\"\n (removed)=\"removeOption($event.item)\"\n />\n</kt-field>\n", styles: ["@layer kt-aaa.components{:host{display:block}.kt-select{position:relative}.kt-select__trigger{display:flex;align-items:center;justify-content:space-between;gap:var(--field-control-gap, .5rem);inline-size:100%;cursor:pointer;text-align:start;font:inherit;color:var(--field-color, inherit)}.kt-select__trigger:disabled{cursor:not-allowed;background:var(--field-disabled-bg, #f1f3f4);color:color-mix(in srgb,currentColor 50%,transparent)}.kt-select__value{flex:1;min-inline-size:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.kt-select__placeholder{color:var(--field-hint-color, #5f6368)}.kt-select__arrow{flex:none;font-family:Material Symbols Outlined;font-size:1.25em;line-height:1;font-feature-settings:\"liga\";color:var(--field-icon-color, #5f6368);transition:var(--select-arrow-transition, transform .12s ease);-webkit-font-smoothing:antialiased}.kt-select--open .kt-select__arrow{transform:rotate(180deg)}.kt-select__popup{box-sizing:border-box;display:flex;flex-direction:column;margin:0;padding:0;border-width:var(--select-popup-border-width, var(--field-border-width, 1px));border-style:var(--field-border-style, solid);border-color:var(--field-border-color, #c4c7c5);border-radius:var(--field-radius, 8px);background:var(--select-popup-bg, var(--kt-surface, #fff));color:var(--field-color, inherit);box-shadow:var(--select-popup-shadow, 0 4px 12px rgb(0 0 0 / 12%));-webkit-backdrop-filter:var(--select-popup-backdrop-filter, none);backdrop-filter:var(--select-popup-backdrop-filter, none);max-block-size:var(--select-popup-max-height, 16rem);overflow:hidden}.kt-select__sheet-card{display:contents}.kt-select__popup:not(:popover-open){display:none!important}.kt-select__popup:popover-open{animation:var(--select-popup-enter-animation, none)}@media(prefers-reduced-motion:reduce){.kt-select__popup:popover-open{animation:none}}.kt-select__listbox{flex:1 1 auto;min-block-size:0;margin:0;padding:.25rem;list-style:none;overflow-y:auto}.kt-select__panel{display:flex;flex-direction:column;flex:1 1 auto;min-block-size:0}.kt-select__filter{flex:none;padding:.5rem;border-block-end:1px solid var(--field-border-color, #c4c7c5)}.kt-select__filter-input{box-sizing:border-box;inline-size:100%;min-block-size:var(--field-min-height, 44px);padding:.375rem .625rem;border:var(--field-border-width, 1px) var(--field-border-style, solid) var(--field-border-color, #c4c7c5);border-radius:calc(var(--field-radius, 8px) * .75);background:var(--select-popup-bg, var(--kt-surface, #fff));color:var(--field-color, inherit);font:inherit;appearance:none}.kt-select__filter-input::placeholder{color:var(--field-hint-color, #5f6368)}.kt-select__filter-input:focus-visible{outline:2px solid var(--field-border-color-focus, #0b57d0);outline-offset:-1px}.kt-select__filter-input::-webkit-search-cancel-button{appearance:none;inline-size:1rem;block-size:1rem;margin-inline-start:.375rem;cursor:pointer;background-color:var(--field-icon-color, #5f6368);-webkit-mask:url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M19 6.41 17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z'/%3E%3C/svg%3E\") center / contain no-repeat;mask:url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M19 6.41 17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z'/%3E%3C/svg%3E\") center / contain no-repeat}.kt-select__sr-only{position:absolute;inline-size:1px;block-size:1px;padding:0;margin:-1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap;border:0}@supports (anchor-name: --x){.kt-select__popup{position:fixed;inset:auto;top:anchor(bottom);left:anchor(left);margin-block-start:.25rem;min-inline-size:anchor-size(width);width:max-content;max-inline-size:min(90vw,28rem);position-try-fallbacks:flip-block,flip-inline,flip-block flip-inline}}@supports not (anchor-name: --x){.kt-select__popup{position:fixed;inset:auto 0 0;inline-size:100%;max-inline-size:100%;border-radius:var(--kt-sheet-radius, 16px) var(--kt-sheet-radius, 16px) 0 0}}.kt-select__popup--sheet{position:fixed!important;inset:0!important;inline-size:100%!important;max-inline-size:100%!important;min-inline-size:0!important;width:100%!important;height:100%!important;max-block-size:none!important;margin:0!important;padding:0!important;border:none!important;background:transparent!important;box-shadow:none!important;border-radius:0!important;overflow:visible!important;display:flex;flex-direction:column!important;justify-content:flex-end!important}.kt-select__popup--sheet .kt-select__sheet-card{position:relative;z-index:2;display:flex;flex-direction:column;background:var(--select-popup-bg, var(--kt-surface, #fff));border-radius:var(--kt-sheet-radius, 16px) var(--kt-sheet-radius, 16px) 0 0;box-shadow:var(--kt-sheet-shadow, 0 -4px 16px rgb(0 0 0 / 12%));max-block-size:var(--kt-sheet-max-block-size, 85svh);width:100%;overflow:hidden;translate:0 0;transition:translate var(--kt-sheet-anim-duration, .12s) ease}.kt-select__popup--sheet .kt-select__sheet-card:has(.kt-select__filter){block-size:var(--kt-sheet-max-block-size, 85svh);max-block-size:var(--kt-sheet-max-block-size, 85svh)}.kt-select__popup--sheet:popover-open .kt-select__sheet-card{translate:0 0;animation:var(--select-sheet-enter-animation, kt-sheet-in var(--kt-sheet-anim-duration, .12s) ease)}.kt-select__popup--sheet .kt-select__sheet-card.kt-select__popup--dragging{transition:none}.kt-select__popup--sheet.kt-select__popup--closing .kt-select__sheet-card,.kt-select__popup--sheet:popover-open.kt-select__popup--closing .kt-select__sheet-card{translate:0 100%;transition:translate var(--kt-sheet-exit-duration, 90ms) cubic-bezier(.4,0,.2,1)}::ng-deep .kt-select__popup--sheet::backdrop{display:none!important}.kt-select__sheet-scrim{display:none}.kt-select__popup--sheet .kt-select__sheet-scrim{display:block;position:fixed;inset:0;z-index:1;background:var(--kt-sheet-scrim, rgb(0 0 0 / 40%));opacity:0;pointer-events:auto;transition:opacity var(--kt-sheet-anim-duration, .12s) ease,overlay var(--kt-sheet-anim-duration, .12s) allow-discrete,display var(--kt-sheet-anim-duration, .12s) allow-discrete}.kt-select__popup--sheet:popover-open .kt-select__sheet-scrim{opacity:1}@starting-style{.kt-select__popup--sheet:popover-open .kt-select__sheet-scrim{opacity:0}}.kt-select__popup--sheet.kt-select__popup--closing .kt-select__sheet-scrim,.kt-select__popup--sheet:popover-open.kt-select__popup--closing .kt-select__sheet-scrim{opacity:0;transition:opacity var(--kt-sheet-exit-duration, 90ms) ease}.kt-select__popup--sheet .kt-select__option{--select-option-min-height: 44px;padding-block:.625rem}.kt-select__popup--sheet .kt-select__filter-input{font-size:1rem;min-block-size:44px}@media(prefers-reduced-motion:reduce){.kt-select__popup--sheet .kt-select__sheet-card,.kt-select__popup--sheet .kt-select__sheet-scrim{transition:none;translate:0 0}}.kt-select__sheet-grab{display:flex;align-items:center;justify-content:center;flex:none;block-size:44px;cursor:grab;touch-action:none}.kt-select__sheet-grab:active{cursor:grabbing}.kt-select__sheet-grab:before{content:\"\";inline-size:2.25rem;block-size:.25rem;border-radius:999px;background:var(--kt-sheet-grab-color, var(--kt-outline, #c4c7c5))}.kt-select__sheet-header{display:flex;align-items:center;justify-content:space-between;gap:.5rem;flex:none;padding-block:.5rem;padding-inline:1rem .5rem;border-block-end:1px solid var(--field-border-color, #c4c7c5)}.kt-select__sheet-title{font-weight:600}.kt-select__sheet-close{display:inline-flex;align-items:center;justify-content:center;flex:none;inline-size:44px;block-size:44px;padding:0;border:0;border-radius:50%;background:transparent;color:var(--field-icon-color, #5f6368);cursor:pointer}.kt-select__sheet-close:focus-visible{outline:2px solid var(--field-border-color-focus, #0b57d0);outline-offset:2px}.kt-select__sheet-close-icon{font-family:Material Symbols Outlined;font-feature-settings:\"liga\";font-size:1.5rem;line-height:1;-webkit-font-smoothing:antialiased}.kt-select__option{display:flex;align-items:center;gap:.5rem;box-sizing:border-box;min-block-size:var( --select-option-min-height, 44px );padding:.5rem .625rem;border-radius:6px;cursor:pointer}.kt-select__option[aria-selected=true]{background:var(--select-option-selected-bg, color-mix(in srgb, var(--kt-primary, #0b57d0) 14%, transparent));color:var(--select-option-selected-color, inherit);font-weight:var(--select-option-selected-weight, 600)}.kt-select__option--active:not([aria-disabled=true]),.kt-select__option:hover:not([aria-disabled=true]){background:var(--select-option-hover-bg, color-mix(in srgb, currentColor 8%, transparent))}.kt-select__option[aria-disabled=true]{opacity:.5;cursor:not-allowed}.kt-select__empty{padding:.5rem .625rem;color:var(--field-hint-color, #5f6368)}.kt-select__truncated-info{box-sizing:border-box;padding:.5rem .625rem;font-size:.875rem;font-style:italic;color:var(--field-hint-color, #5f6368);border-block-start:1px solid var(--field-border-color, #c4c7c5);pointer-events:none}}\n", "@layer kt-aaa.components{.kt-select__trigger--clearable .kt-select__value{margin-inline-end:2rem}.kt-select__clear{position:absolute;inset-block-start:50%;inset-inline-end:2.5rem;translate:0 -50%;display:inline-flex;align-items:center;justify-content:center;inline-size:24px;block-size:24px;padding:0;border:0;border-radius:50%;background:transparent;color:var(--field-icon-color, #5f6368);cursor:pointer}.kt-select__clear:after{content:\"\";position:absolute;inset:-10px}.kt-select__clear:hover{background-color:color-mix(in srgb,currentColor 12%,transparent);color:var(--field-color, inherit)}.kt-select__clear:focus-visible{outline:2px solid var(--field-border-color-focus, #0b57d0);outline-offset:1px}.kt-select__clear-icon{font-family:Material Symbols Outlined;font-feature-settings:\"liga\";font-size:1.25rem;line-height:1;-webkit-font-smoothing:antialiased}.kt-select__actions{display:flex;gap:.25rem;flex:none;padding:.25rem .5rem;border-block-end:1px solid var(--field-border-color, #c4c7c5)}.kt-select__action{flex:1;min-block-size:44px;padding:.375rem .625rem;border:0;border-radius:calc(var(--field-radius, 8px) * .75);background:transparent;color:var(--kt-primary, #0b57d0);font:inherit;font-weight:500;cursor:pointer}.kt-select__action:hover{background:var(--select-option-hover-bg, color-mix(in srgb, currentColor 8%, transparent))}.kt-select__action:focus-visible{outline:2px solid var(--field-border-color-focus, #0b57d0);outline-offset:-2px}.kt-select__count{flex:none;padding:.25rem .75rem;font-size:.8125rem;color:var(--field-hint-color, #5f6368);border-block-end:1px solid var(--field-border-color, #c4c7c5)}.kt-select__checkbox{display:inline-flex;align-items:center;justify-content:center;flex:none;margin-inline-end:.25rem;-webkit-user-select:none;user-select:none}.kt-select__checkbox-icon{font-family:Material Symbols Outlined;font-feature-settings:\"liga\";font-size:1.25rem;line-height:1;color:var(--field-icon-color, #5f6368);-webkit-font-smoothing:antialiased}.kt-select__option[aria-selected=true] .kt-select__checkbox-icon{color:var(--kt-primary, #0b57d0)}.kt-select__option--multiple{display:flex;align-items:center;gap:.5rem}.kt-select__option-content{flex:1;min-inline-size:0}kt-chip-list:not([data-empty]){margin-block-start:.5rem}}\n"] }]
|
|
3231
|
+
], template: "<kt-field\n [label]=\"label()\"\n [hint]=\"hint()\"\n [helpText]=\"helpText()\"\n [helpLabel]=\"helpLabel()\"\n [customDescribedBy]=\"customDescribedBy()\"\n [errors]=\"fieldErrors()\"\n [invalid]=\"showInvalid()\"\n [required]=\"required()\"\n [fieldId]=\"id()\"\n [appearance]=\"appearance()\"\n [floatLabel]=\"floatLabel()\"\n (helpClick)=\"helpClick.emit($event)\"\n>\n <ng-content select=\"[ktFieldHelp]\" />\n <div class=\"kt-select\" [class.kt-select--open]=\"expanded()\">\n <button\n #combobox=\"ngCombobox\"\n #trigger\n ngCombobox\n ktFieldControl\n type=\"button\"\n class=\"kt-field-box kt-select__trigger\"\n [class.kt-select__trigger--clearable]=\"showClear()\"\n [(expanded)]=\"expanded\"\n [disabled]=\"disabled()\"\n [softDisabled]=\"false\"\n [attr.data-invalid]=\"showInvalid() ? '' : null\"\n [attr.data-disabled]=\"disabled() ? '' : null\"\n [attr.data-filled]=\"selectedOptions().length ? '' : null\"\n [attr.data-pending]=\"pending() ? '' : null\"\n [attr.aria-busy]=\"pending() ? 'true' : null\"\n (keydown)=\"onTriggerKeydown($event)\"\n >\n <span class=\"kt-select__value\">\n @if (triggerDef(); as def) {\n <ng-container\n [ngTemplateOutlet]=\"def.template\"\n [ngTemplateOutletContext]=\"{ $implicit: selectedOptions() }\"\n />\n } @else if (selectedOptions().length > 0) {\n {{ triggerText() }}\n } @else {\n <span class=\"kt-select__placeholder\">{{ resolvedPlaceholder() }}</span>\n }\n </span>\n <span class=\"kt-select__arrow\" aria-hidden=\"true\">arrow_drop_down</span>\n </button>\n\n <!-- Tout effacer depuis le champ : sibling du trigger (pas de bouton imbriqu\u00E9 dans un bouton). -->\n @if (showClear()) {\n <button\n type=\"button\"\n class=\"kt-select__clear\"\n [attr.aria-label]=\"clearLabel()\"\n (mousedown)=\"$event.preventDefault()\"\n (click)=\"clearSelection()\"\n >\n <span class=\"kt-select__clear-icon\" aria-hidden=\"true\">close</span>\n </button>\n }\n\n <!-- Popup Popover (top-layer). M\u00EAme logique mobile bottom-sheet adaptative que le select classique. -->\n <ng-template ngComboboxPopup [combobox]=\"combobox\" [popupType]=\"dialogMode() ? 'dialog' : 'listbox'\">\n <div #popup popover=\"manual\" class=\"kt-select__popup\" [class.kt-select__popup--sheet]=\"compact()\">\n @if (compact()) {\n <div class=\"kt-select__sheet-scrim\" aria-hidden=\"true\" (click)=\"expanded.set(false)\"></div>\n }\n <div class=\"kt-select__sheet-card\">\n @if (compact()) {\n <div\n class=\"kt-select__sheet-grab\"\n aria-hidden=\"true\"\n (pointerdown)=\"onDragStart($event)\"\n (mousedown)=\"$event.preventDefault()\"\n ></div>\n <header class=\"kt-select__sheet-header\">\n <span class=\"kt-select__sheet-title\">{{ label() }}</span>\n <button\n type=\"button\"\n class=\"kt-select__sheet-close\"\n [attr.aria-label]=\"resolvedCloseLabel()\"\n (click)=\"expanded.set(false)\"\n >\n <span class=\"kt-select__sheet-close-icon\" aria-hidden=\"true\">close</span>\n </button>\n </header>\n }\n @if (dialogMode()) {\n <!-- Mode panneau (filtre et/ou actions de masse) : Widget Dialog -->\n <div\n ngComboboxWidget\n role=\"dialog\"\n class=\"kt-select__panel\"\n [id]=\"panelId\"\n [attr.aria-label]=\"label()\"\n [activeDescendant]=\"lb.activeDescendant()\"\n (keydown)=\"onPanelKeydown($event)\"\n >\n @if (selectionActions()) {\n <div class=\"kt-select__actions\">\n <button type=\"button\" class=\"kt-select__action\" (click)=\"selectAllFiltered()\">\n {{ resolvedSelectAllLabel() }}\n </button>\n <button type=\"button\" class=\"kt-select__action\" (click)=\"clearAllFiltered()\">\n {{ resolvedClearAllLabel() }}\n </button>\n </div>\n }\n @if (filterable()) {\n <div class=\"kt-select__filter\">\n <input\n #filterInput\n type=\"search\"\n role=\"combobox\"\n aria-autocomplete=\"list\"\n aria-expanded=\"true\"\n class=\"kt-select__filter-input\"\n autocomplete=\"off\"\n [placeholder]=\"resolvedFilterPlaceholder()\"\n [attr.aria-label]=\"resolvedFilterLabel()\"\n [attr.aria-controls]=\"lb.id()\"\n [attr.aria-activedescendant]=\"lb.activeDescendant()\"\n [value]=\"filterText()\"\n (input)=\"onFilterInput($event)\"\n (keydown)=\"onFilterKeydown($event)\"\n />\n </div>\n }\n @if (selectedOptions().length > 0) {\n <!-- Rappel visuel (s\u00E9lections potentiellement masqu\u00E9es par le filtre) ;\n l'info SR passe par la live region ci-dessous \u2192 aria-hidden. -->\n <div class=\"kt-select__count\" aria-hidden=\"true\">{{ selectionCountLabel() }}</div>\n }\n <div class=\"kt-select__sr-only kt-select__filter-status\" role=\"status\" aria-live=\"polite\">\n {{ announcedCount() }}\n </div>\n <ul\n #lb=\"ngListbox\"\n #listboxEl\n ngListbox\n [multi]=\"true\"\n [focusMode]=\"compact() && !filterable() ? 'roving' : 'activedescendant'\"\n selectionMode=\"explicit\"\n class=\"kt-select__listbox\"\n [attr.aria-label]=\"label()\"\n [value]=\"listboxValue()\"\n (valueChange)=\"onListboxValueChange($event)\"\n [disabled]=\"disabled()\"\n [readonly]=\"readonly()\"\n >\n @for (item of displayedOptions(); track keyOf(item)) {\n <li\n #opt=\"ngOption\"\n ngOption\n class=\"kt-select__option kt-select__option--multiple\"\n [value]=\"keyOf(item)\"\n [label]=\"labelOf(item)\"\n [disabled]=\"disabledOf(item)\"\n [class.kt-select__option--active]=\"opt.active()\"\n >\n <span class=\"kt-select__checkbox\" aria-hidden=\"true\">\n @if (opt.selected()) {\n <span class=\"kt-select__checkbox-icon\">check_box</span>\n } @else {\n <span class=\"kt-select__checkbox-icon\">check_box_outline_blank</span>\n }\n </span>\n <span class=\"kt-select__option-content\">\n @if (optionDef(); as def) {\n <ng-container\n [ngTemplateOutlet]=\"def.template\"\n [ngTemplateOutletContext]=\"{\n $implicit: item,\n selected: !!opt.selected(),\n active: opt.active(),\n }\"\n />\n } @else {\n {{ labelOf(item) }}\n }\n </span>\n </li>\n } @empty {\n <li class=\"kt-select__empty\" role=\"option\" aria-disabled=\"true\" aria-selected=\"false\">\n {{ resolvedEmptyText() }}\n </li>\n }\n @if (filterable() && filteredOptions().length > maxVisibleOptions()) {\n <li class=\"kt-select__truncated-info\" role=\"option\" aria-disabled=\"true\" aria-selected=\"false\">\n {{ resolvedTruncatedResultsText()(maxVisibleOptions(), filteredOptions().length) }}\n </li>\n }\n </ul>\n </div>\n } @else {\n <!-- Mode simple : Widget Listbox direct -->\n <ul\n #listbox=\"ngListbox\"\n #listboxEl\n ngComboboxWidget\n ngListbox\n [multi]=\"true\"\n [focusMode]=\"compact() ? 'roving' : 'activedescendant'\"\n selectionMode=\"explicit\"\n class=\"kt-select__listbox\"\n [attr.aria-label]=\"label()\"\n [value]=\"listboxValue()\"\n (valueChange)=\"onListboxValueChange($event)\"\n [disabled]=\"disabled()\"\n [readonly]=\"readonly()\"\n [activeDescendant]=\"listbox.activeDescendant()\"\n >\n @for (item of options(); track keyOf(item)) {\n <li\n #opt=\"ngOption\"\n ngOption\n class=\"kt-select__option kt-select__option--multiple\"\n [value]=\"keyOf(item)\"\n [label]=\"labelOf(item)\"\n [disabled]=\"disabledOf(item)\"\n [class.kt-select__option--active]=\"opt.active()\"\n >\n <span class=\"kt-select__checkbox\" aria-hidden=\"true\">\n @if (opt.selected()) {\n <span class=\"kt-select__checkbox-icon\">check_box</span>\n } @else {\n <span class=\"kt-select__checkbox-icon\">check_box_outline_blank</span>\n }\n </span>\n <span class=\"kt-select__option-content\">\n @if (optionDef(); as def) {\n <ng-container\n [ngTemplateOutlet]=\"def.template\"\n [ngTemplateOutletContext]=\"{\n $implicit: item,\n selected: !!opt.selected(),\n active: opt.active(),\n }\"\n />\n } @else {\n {{ labelOf(item) }}\n }\n </span>\n </li>\n } @empty {\n <li class=\"kt-select__empty\" role=\"option\" aria-disabled=\"true\" aria-selected=\"false\">\n {{ resolvedEmptyText() }}\n </li>\n }\n </ul>\n }\n </div>\n </div>\n </ng-template>\n </div>\n\n <!-- Chips r\u00E9vocables (Option 1) sous le trigger : d\u00E9l\u00E9gu\u00E9s au composant r\u00E9utilisable\n kt-chip-list (focus management, repli +N, live region). Les textes r\u00E9solus depuis\n KT_SELECT_CONFIG sont pass\u00E9s en inputs (ils priment sur un \u00E9ventuel KT_CHIPS_CONFIG). -->\n <kt-chip-list\n [items]=\"selectedOptions()\"\n [itemLabel]=\"chipLabelOf\"\n [itemKey]=\"chipKeyOf\"\n [disabled]=\"disabled()\"\n [readonly]=\"readonly()\"\n [maxVisible]=\"maxVisibleChips()\"\n [listLabel]=\"resolvedSelectedItemsLabel()\"\n [removeItemLabel]=\"resolvedRemoveItemLabel()\"\n [itemRemovedText]=\"resolvedItemRemovedText()\"\n [moreLabel]=\"resolvedMoreChipsLabel()\"\n [lessLabel]=\"resolvedLessChipsLabel()\"\n [chipTemplate]=\"chipDef()?.template ?? null\"\n [emptyFocusTarget]=\"triggerEl()?.nativeElement\"\n (removed)=\"removeOption($event.item)\"\n />\n</kt-field>\n", styles: ["@layer kt-aaa.components{:host{display:block}.kt-select{position:relative}.kt-select__trigger{display:flex;align-items:center;justify-content:space-between;gap:var(--field-control-gap, .5rem);inline-size:100%;cursor:pointer;text-align:start;font:inherit;color:var(--field-color, inherit)}.kt-select__trigger:disabled{cursor:not-allowed;background:var(--field-disabled-bg, #f1f3f4);color:color-mix(in srgb,currentColor 50%,transparent)}.kt-select__value{flex:1;min-inline-size:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.kt-select__placeholder{color:var(--field-hint-color, #5f6368)}.kt-select__arrow{flex:none;font-family:Material Symbols Outlined;font-size:1.25em;line-height:1;font-feature-settings:\"liga\";color:var(--field-icon-color, #5f6368);transition:var(--select-arrow-transition, transform .12s ease);-webkit-font-smoothing:antialiased}.kt-select--open .kt-select__arrow{transform:rotate(180deg)}.kt-select__popup{box-sizing:border-box;display:flex;flex-direction:column;margin:0;padding:0;border-width:var(--select-popup-border-width, var(--field-border-width, 1px));border-style:var(--field-border-style, solid);border-color:var(--field-border-color, #c4c7c5);border-radius:var(--field-radius, 8px);background:var(--select-popup-bg, var(--kt-surface, #fff));color:var(--field-color, inherit);box-shadow:var(--select-popup-shadow, 0 4px 12px rgb(0 0 0 / 12%));-webkit-backdrop-filter:var(--select-popup-backdrop-filter, none);backdrop-filter:var(--select-popup-backdrop-filter, none);max-block-size:var(--select-popup-max-height, 16rem);overflow:hidden}.kt-select__sheet-card{display:contents}.kt-select__popup:not(:popover-open){display:none!important}.kt-select__popup:popover-open{animation:var(--select-popup-enter-animation, none)}@media(prefers-reduced-motion:reduce){.kt-select__popup:popover-open{animation:none}}.kt-select__listbox{flex:1 1 auto;min-block-size:0;margin:0;padding:.25rem;list-style:none;overflow-y:auto}.kt-select__panel{display:flex;flex-direction:column;flex:1 1 auto;min-block-size:0}.kt-select__filter{flex:none;padding:.5rem;border-block-end:1px solid var(--field-border-color, #c4c7c5)}.kt-select__filter-input{box-sizing:border-box;inline-size:100%;min-block-size:var(--field-min-height, 44px);padding:.375rem .625rem;border:var(--field-border-width, 1px) var(--field-border-style, solid) var(--field-border-color, #c4c7c5);border-radius:calc(var(--field-radius, 8px) * .75);background:var(--select-popup-bg, var(--kt-surface, #fff));color:var(--field-color, inherit);font:inherit;appearance:none}.kt-select__filter-input::placeholder{color:var(--field-hint-color, #5f6368)}.kt-select__filter-input:focus-visible{outline:2px solid var(--field-border-color-focus, #0b57d0);outline-offset:-1px}.kt-select__filter-input::-webkit-search-cancel-button{appearance:none;inline-size:1rem;block-size:1rem;margin-inline-start:.375rem;cursor:pointer;background-color:var(--field-icon-color, #5f6368);-webkit-mask:url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M19 6.41 17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z'/%3E%3C/svg%3E\") center / contain no-repeat;mask:url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M19 6.41 17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z'/%3E%3C/svg%3E\") center / contain no-repeat}.kt-select__sr-only{position:absolute;inset-block-start:0;inset-inline-start:0;inline-size:1px;block-size:1px;padding:0;margin:-1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap;border:0}@supports (anchor-name: --x){.kt-select__popup{position:fixed;inset:auto;top:anchor(bottom);left:anchor(left);margin-block-start:.25rem;min-inline-size:anchor-size(width);width:max-content;max-inline-size:min(90vw,28rem);position-try-fallbacks:flip-block,flip-inline,flip-block flip-inline}}@supports not (anchor-name: --x){.kt-select__popup{position:fixed;inset:auto 0 0;inline-size:100%;max-inline-size:100%;border-radius:var(--kt-sheet-radius, 16px) var(--kt-sheet-radius, 16px) 0 0}}.kt-select__popup--sheet{position:fixed!important;inset:0!important;inline-size:100%!important;max-inline-size:100%!important;min-inline-size:0!important;width:100%!important;height:100%!important;max-block-size:none!important;margin:0!important;padding:0!important;border:none!important;background:transparent!important;box-shadow:none!important;border-radius:0!important;overflow:visible!important;display:flex;flex-direction:column!important;justify-content:flex-end!important}.kt-select__popup--sheet .kt-select__sheet-card{position:relative;z-index:2;display:flex;flex-direction:column;background:var(--select-popup-bg, var(--kt-surface, #fff));border-radius:var(--kt-sheet-radius, 16px) var(--kt-sheet-radius, 16px) 0 0;box-shadow:var(--kt-sheet-shadow, 0 -4px 16px rgb(0 0 0 / 12%));max-block-size:var(--kt-sheet-max-block-size, 85svh);width:100%;overflow:hidden;translate:0 0;transition:translate var(--kt-sheet-anim-duration, .12s) ease}.kt-select__popup--sheet .kt-select__sheet-card:has(.kt-select__filter){block-size:var(--kt-sheet-max-block-size, 85svh);max-block-size:var(--kt-sheet-max-block-size, 85svh)}.kt-select__popup--sheet:popover-open .kt-select__sheet-card{translate:0 0;animation:var(--select-sheet-enter-animation, kt-sheet-in var(--kt-sheet-anim-duration, .12s) ease)}.kt-select__popup--sheet .kt-select__sheet-card.kt-select__popup--dragging{transition:none}.kt-select__popup--sheet.kt-select__popup--closing .kt-select__sheet-card,.kt-select__popup--sheet:popover-open.kt-select__popup--closing .kt-select__sheet-card{translate:0 100%;transition:translate var(--kt-sheet-exit-duration, 90ms) cubic-bezier(.4,0,.2,1)}::ng-deep .kt-select__popup--sheet::backdrop{display:none!important}.kt-select__sheet-scrim{display:none}.kt-select__popup--sheet .kt-select__sheet-scrim{display:block;position:fixed;inset:0;z-index:1;background:var(--kt-sheet-scrim, rgb(0 0 0 / 40%));opacity:0;pointer-events:auto;transition:opacity var(--kt-sheet-anim-duration, .12s) ease,overlay var(--kt-sheet-anim-duration, .12s) allow-discrete,display var(--kt-sheet-anim-duration, .12s) allow-discrete}.kt-select__popup--sheet:popover-open .kt-select__sheet-scrim{opacity:1}@starting-style{.kt-select__popup--sheet:popover-open .kt-select__sheet-scrim{opacity:0}}.kt-select__popup--sheet.kt-select__popup--closing .kt-select__sheet-scrim,.kt-select__popup--sheet:popover-open.kt-select__popup--closing .kt-select__sheet-scrim{opacity:0;transition:opacity var(--kt-sheet-exit-duration, 90ms) ease}.kt-select__popup--sheet .kt-select__option{--select-option-min-height: 44px;padding-block:.625rem}.kt-select__popup--sheet .kt-select__filter-input{font-size:1rem;min-block-size:44px}@media(prefers-reduced-motion:reduce){.kt-select__popup--sheet .kt-select__sheet-card,.kt-select__popup--sheet .kt-select__sheet-scrim{transition:none;translate:0 0}}.kt-select__sheet-grab{display:flex;align-items:center;justify-content:center;flex:none;block-size:44px;cursor:grab;touch-action:none}.kt-select__sheet-grab:active{cursor:grabbing}.kt-select__sheet-grab:before{content:\"\";inline-size:2.25rem;block-size:.25rem;border-radius:999px;background:var(--kt-sheet-grab-color, var(--kt-outline, #c4c7c5))}.kt-select__sheet-header{display:flex;align-items:center;justify-content:space-between;gap:.5rem;flex:none;padding-block:.5rem;padding-inline:1rem .5rem;border-block-end:1px solid var(--field-border-color, #c4c7c5)}.kt-select__sheet-title{font-weight:600}.kt-select__sheet-close{display:inline-flex;align-items:center;justify-content:center;flex:none;inline-size:44px;block-size:44px;padding:0;border:0;border-radius:50%;background:transparent;color:var(--field-icon-color, #5f6368);cursor:pointer}.kt-select__sheet-close:focus-visible{outline:2px solid var(--field-border-color-focus, #0b57d0);outline-offset:2px}.kt-select__sheet-close-icon{font-family:Material Symbols Outlined;font-feature-settings:\"liga\";font-size:1.5rem;line-height:1;-webkit-font-smoothing:antialiased}.kt-select__option{display:flex;align-items:center;gap:.5rem;box-sizing:border-box;min-block-size:var( --select-option-min-height, 44px );padding:.5rem .625rem;border-radius:6px;cursor:pointer}.kt-select__option[aria-selected=true]{background:var(--select-option-selected-bg, color-mix(in srgb, var(--kt-primary, #0b57d0) 14%, transparent));color:var(--select-option-selected-color, inherit);font-weight:var(--select-option-selected-weight, 600)}.kt-select__option--active:not([aria-disabled=true]),.kt-select__option:hover:not([aria-disabled=true]){background:var(--select-option-hover-bg, color-mix(in srgb, currentColor 8%, transparent))}.kt-select__option[aria-disabled=true]{opacity:.5;cursor:not-allowed}.kt-select__empty{padding:.5rem .625rem;color:var(--field-hint-color, #5f6368)}.kt-select__truncated-info{box-sizing:border-box;padding:.5rem .625rem;font-size:.875rem;font-style:italic;color:var(--field-hint-color, #5f6368);border-block-start:1px solid var(--field-border-color, #c4c7c5);pointer-events:none}}\n", "@layer kt-aaa.components{.kt-select__trigger--clearable .kt-select__value{margin-inline-end:2rem}.kt-select__clear{position:absolute;inset-block-start:50%;inset-inline-end:2.5rem;translate:0 -50%;display:inline-flex;align-items:center;justify-content:center;inline-size:24px;block-size:24px;padding:0;border:0;border-radius:50%;background:transparent;color:var(--field-icon-color, #5f6368);cursor:pointer}.kt-select__clear:after{content:\"\";position:absolute;inset:-10px}.kt-select__clear:hover{background-color:color-mix(in srgb,currentColor 12%,transparent);color:var(--field-color, inherit)}.kt-select__clear:focus-visible{outline:2px solid var(--field-border-color-focus, #0b57d0);outline-offset:1px}.kt-select__clear-icon{font-family:Material Symbols Outlined;font-feature-settings:\"liga\";font-size:1.25rem;line-height:1;-webkit-font-smoothing:antialiased}.kt-select__actions{display:flex;gap:.25rem;flex:none;padding:.25rem .5rem;border-block-end:1px solid var(--field-border-color, #c4c7c5)}.kt-select__action{flex:1;min-block-size:44px;padding:.375rem .625rem;border:0;border-radius:calc(var(--field-radius, 8px) * .75);background:transparent;color:var(--kt-primary, #0b57d0);font:inherit;font-weight:500;cursor:pointer}.kt-select__action:hover{background:var(--select-option-hover-bg, color-mix(in srgb, currentColor 8%, transparent))}.kt-select__action:focus-visible{outline:2px solid var(--field-border-color-focus, #0b57d0);outline-offset:-2px}.kt-select__count{flex:none;padding:.25rem .75rem;font-size:.8125rem;color:var(--field-hint-color, #5f6368);border-block-end:1px solid var(--field-border-color, #c4c7c5)}.kt-select__checkbox{display:inline-flex;align-items:center;justify-content:center;flex:none;margin-inline-end:.25rem;-webkit-user-select:none;user-select:none}.kt-select__checkbox-icon{font-family:Material Symbols Outlined;font-feature-settings:\"liga\";font-size:1.25rem;line-height:1;color:var(--field-icon-color, #5f6368);-webkit-font-smoothing:antialiased}.kt-select__option[aria-selected=true] .kt-select__checkbox-icon{color:var(--kt-primary, #0b57d0)}.kt-select__option--multiple{display:flex;align-items:center;gap:.5rem}.kt-select__option-content{flex:1;min-inline-size:0}kt-chip-list:not([data-empty]){margin-block-start:.5rem}}\n"] }]
|
|
3000
3232
|
}], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }, { type: i0.Output, args: ["valueChange"] }], selectionChange: [{ type: i0.Output, args: ["selectionChange"] }], clearable: [{ type: i0.Input, args: [{ isSignal: true, alias: "clearable", required: false }] }], clearLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "clearLabel", required: false }] }], selectionActions: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectionActions", required: false }] }], maxVisibleChips: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxVisibleChips", required: false }] }], optionDef: [{ type: i0.ContentChild, args: [i0.forwardRef(() => KtMultiSelectOptionDef), { isSignal: true }] }], triggerDef: [{ type: i0.ContentChild, args: [i0.forwardRef(() => KtMultiSelectTriggerDef), { isSignal: true }] }], chipDef: [{ type: i0.ContentChild, args: [i0.forwardRef(() => KtMultiSelectChipDef), { isSignal: true }] }], chipList: [{ type: i0.ViewChild, args: [i0.forwardRef(() => KtChipList), { isSignal: true }] }] } });
|
|
3001
3233
|
|
|
3002
3234
|
/** Base partagée des champs Temporal (Date/Time/DateTime/YearMonth).
|
|
@@ -3053,6 +3285,20 @@ class KtBaseTemporalField extends KtBaseInputField {
|
|
|
3053
3285
|
return null;
|
|
3054
3286
|
}
|
|
3055
3287
|
}
|
|
3288
|
+
displayValue() {
|
|
3289
|
+
const v = this.value();
|
|
3290
|
+
return v === null ? '' : this.serialize(v);
|
|
3291
|
+
}
|
|
3292
|
+
/** Efface AUSSI l'input natif. L'effet de synchro ignore une mise à `null` quand l'input est
|
|
3293
|
+
focalisé (pour ne pas écraser une saisie partielle en cours), or `clear()` focalise justement
|
|
3294
|
+
le champ — sans ce forçage, le bouton « effacer » (et Échap) resterait sans effet sur les
|
|
3295
|
+
champs temporels. */
|
|
3296
|
+
clear() {
|
|
3297
|
+
super.clear();
|
|
3298
|
+
const el = this.inputRef()?.nativeElement;
|
|
3299
|
+
if (el)
|
|
3300
|
+
el.value = '';
|
|
3301
|
+
}
|
|
3056
3302
|
emptyValue() {
|
|
3057
3303
|
return null;
|
|
3058
3304
|
}
|
|
@@ -3131,16 +3377,28 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.1", ngImpor
|
|
|
3131
3377
|
type: Directive
|
|
3132
3378
|
}], propDecorators: { precision: [{ type: i0.Input, args: [{ isSignal: true, alias: "precision", required: false }] }] } });
|
|
3133
3379
|
|
|
3134
|
-
/**
|
|
3135
|
-
|
|
3136
|
-
|
|
3137
|
-
|
|
3138
|
-
|
|
3139
|
-
|
|
3140
|
-
|
|
3141
|
-
|
|
3380
|
+
/** Résout la valeur runtime `Temporal` (native ou polyfill) au moment de l'APPEL, pas à
|
|
3381
|
+
l'évaluation du module. Capturer `globalThis.Temporal` à l'import rendrait la lib fragile à
|
|
3382
|
+
l'ordre d'initialisation des modules décidé par le bundler : sur un moteur sans Temporal natif
|
|
3383
|
+
(Safari/WebKit), le module Temporal de la lib pouvait s'évaluer avant l'installation du polyfill
|
|
3384
|
+
et jeter au boot. */
|
|
3385
|
+
function resolveTemporal() {
|
|
3386
|
+
const value = globalThis.Temporal;
|
|
3387
|
+
if (value == null) {
|
|
3388
|
+
throw new Error(`[ktortu/aaa] L'espace de noms 'Temporal' est introuvable. ` +
|
|
3389
|
+
`Veuillez vous assurer que le polyfill 'temporal-polyfill/global' est correctement importé ` +
|
|
3390
|
+
`dans le fichier 'main.ts' de votre application.`);
|
|
3391
|
+
}
|
|
3392
|
+
return value;
|
|
3142
3393
|
}
|
|
3143
|
-
|
|
3394
|
+
/** Point d'accès `Temporal` de la lib. Proxy à résolution paresseuse : le namespace réel n'est lu
|
|
3395
|
+
qu'au premier accès de propriété (`Temporal.PlainDate`…), jamais à l'import — ce qui supprime la
|
|
3396
|
+
dépendance à l'ordre d'init des modules et fait booter Safari/WebKit tant que le polyfill est
|
|
3397
|
+
importé dans `main.ts`. */
|
|
3398
|
+
const Temporal = new Proxy({}, {
|
|
3399
|
+
get: (_target, property) => Reflect.get(resolveTemporal(), property),
|
|
3400
|
+
has: (_target, property) => Reflect.has(resolveTemporal(), property),
|
|
3401
|
+
});
|
|
3144
3402
|
|
|
3145
3403
|
/** Champ « date sans heure » : valeur = `Temporal.PlainDate`, input natif `type="date"`.
|
|
3146
3404
|
*
|
|
@@ -3162,11 +3420,11 @@ class KtDateField extends KtBaseTemporalField {
|
|
|
3162
3420
|
return value.toString();
|
|
3163
3421
|
}
|
|
3164
3422
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.1", ngImport: i0, type: KtDateField, deps: null, target: i0.ɵɵFactoryTarget.Component });
|
|
3165
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.1", type: KtDateField, isStandalone: true, selector: "kt-date-field", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange" }, usesInheritance: true, ngImport: i0, template: "<kt-field\n [label]=\"label()\"\n [hint]=\"hint()\"\n [helpText]=\"helpText()\"\n [helpLabel]=\"helpLabel()\"\n [customDescribedBy]=\"customDescribedBy()\"\n [errors]=\"
|
|
3423
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.1", type: KtDateField, isStandalone: true, selector: "kt-date-field", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange" }, usesInheritance: true, ngImport: i0, template: "<kt-field\n [label]=\"label()\"\n [hint]=\"hint()\"\n [helpText]=\"helpText()\"\n [helpLabel]=\"helpLabel()\"\n [customDescribedBy]=\"customDescribedBy()\"\n [errors]=\"displayErrors()\"\n [invalid]=\"showInvalid()\"\n [required]=\"required()\"\n [fieldId]=\"id()\"\n [appearance]=\"appearance()\"\n [floatLabel]=\"floatLabel()\"\n (helpClick)=\"helpClick.emit($event)\"\n>\n <ng-content select=\"[ktFieldHelp]\" />\n <div\n class=\"kt-field-box\"\n [attr.data-invalid]=\"showInvalid() ? '' : null\"\n [attr.data-disabled]=\"disabled() ? '' : null\"\n [attr.data-pending]=\"pending() ? '' : null\"\n >\n @if (icon(); as icon) {\n <span class=\"kt-field-box__icon\" aria-hidden=\"true\">{{ icon }}</span>\n }\n\n @if (prefix(); as prefix) {\n <span class=\"kt-field-box__affix\">\n @if (asTemplate(prefix); as tpl) {\n <ng-container [ngTemplateOutlet]=\"tpl\" />\n } @else {\n {{ asText(prefix) }}\n }\n </span>\n }\n\n <input\n #input\n ktFieldControl\n class=\"kt-field-box__input\"\n type=\"date\"\n [disabled]=\"disabled()\"\n [readOnly]=\"readonly()\"\n [attr.aria-busy]=\"pending() ? 'true' : null\"\n [attr.name]=\"name() || null\"\n [attr.placeholder]=\"placeholder()\"\n [attr.min]=\"serializedMin()\"\n [attr.max]=\"serializedMax()\"\n [attr.list]=\"hasSuggestions() ? datalistId : null\"\n (input)=\"onInput($event)\"\n (keydown)=\"onKeyDown($event)\"\n (blur)=\"touched.set(true)\"\n />\n\n @if (hasSuggestions()) {\n <datalist [id]=\"datalistId\">\n @for (option of datalistOptions(); track $index) {\n <option [value]=\"option.value\" [attr.label]=\"option.label\"></option>\n }\n </datalist>\n }\n\n @if (showClear()) {\n <button type=\"button\" class=\"kt-field-box__clear\" [attr.aria-label]=\"clearLabel()\" (click)=\"clear()\">\n <span class=\"kt-field-box__icon\" aria-hidden=\"true\">close</span>\n </button>\n }\n\n @if (suffix(); as suffix) {\n <span class=\"kt-field-box__affix\">\n @if (asTemplate(suffix); as tpl) {\n <ng-container [ngTemplateOutlet]=\"tpl\" />\n } @else {\n {{ asText(suffix) }}\n }\n </span>\n }\n </div>\n</kt-field>\n", dependencies: [{ kind: "component", type: KtField, selector: "kt-field", inputs: ["label", "hint", "helpText", "helpLabel", "customDescribedBy", "errors", "invalid", "required", "fieldId", "hideHintWhenInvalid", "showAllErrors", "appearance", "floatLabel"], outputs: ["helpClick"] }, { kind: "directive", type: KtFieldControl, selector: "[ktFieldControl]" }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
3166
3424
|
}
|
|
3167
3425
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.1", ngImport: i0, type: KtDateField, decorators: [{
|
|
3168
3426
|
type: Component,
|
|
3169
|
-
args: [{ selector: 'kt-date-field', imports: [KtField, KtFieldControl, NgTemplateOutlet], changeDetection: ChangeDetectionStrategy.OnPush, template: "<kt-field\n [label]=\"label()\"\n [hint]=\"hint()\"\n [helpText]=\"helpText()\"\n [helpLabel]=\"helpLabel()\"\n [customDescribedBy]=\"customDescribedBy()\"\n [errors]=\"
|
|
3427
|
+
args: [{ selector: 'kt-date-field', imports: [KtField, KtFieldControl, NgTemplateOutlet], changeDetection: ChangeDetectionStrategy.OnPush, template: "<kt-field\n [label]=\"label()\"\n [hint]=\"hint()\"\n [helpText]=\"helpText()\"\n [helpLabel]=\"helpLabel()\"\n [customDescribedBy]=\"customDescribedBy()\"\n [errors]=\"displayErrors()\"\n [invalid]=\"showInvalid()\"\n [required]=\"required()\"\n [fieldId]=\"id()\"\n [appearance]=\"appearance()\"\n [floatLabel]=\"floatLabel()\"\n (helpClick)=\"helpClick.emit($event)\"\n>\n <ng-content select=\"[ktFieldHelp]\" />\n <div\n class=\"kt-field-box\"\n [attr.data-invalid]=\"showInvalid() ? '' : null\"\n [attr.data-disabled]=\"disabled() ? '' : null\"\n [attr.data-pending]=\"pending() ? '' : null\"\n >\n @if (icon(); as icon) {\n <span class=\"kt-field-box__icon\" aria-hidden=\"true\">{{ icon }}</span>\n }\n\n @if (prefix(); as prefix) {\n <span class=\"kt-field-box__affix\">\n @if (asTemplate(prefix); as tpl) {\n <ng-container [ngTemplateOutlet]=\"tpl\" />\n } @else {\n {{ asText(prefix) }}\n }\n </span>\n }\n\n <input\n #input\n ktFieldControl\n class=\"kt-field-box__input\"\n type=\"date\"\n [disabled]=\"disabled()\"\n [readOnly]=\"readonly()\"\n [attr.aria-busy]=\"pending() ? 'true' : null\"\n [attr.name]=\"name() || null\"\n [attr.placeholder]=\"placeholder()\"\n [attr.min]=\"serializedMin()\"\n [attr.max]=\"serializedMax()\"\n [attr.list]=\"hasSuggestions() ? datalistId : null\"\n (input)=\"onInput($event)\"\n (keydown)=\"onKeyDown($event)\"\n (blur)=\"touched.set(true)\"\n />\n\n @if (hasSuggestions()) {\n <datalist [id]=\"datalistId\">\n @for (option of datalistOptions(); track $index) {\n <option [value]=\"option.value\" [attr.label]=\"option.label\"></option>\n }\n </datalist>\n }\n\n @if (showClear()) {\n <button type=\"button\" class=\"kt-field-box__clear\" [attr.aria-label]=\"clearLabel()\" (click)=\"clear()\">\n <span class=\"kt-field-box__icon\" aria-hidden=\"true\">close</span>\n </button>\n }\n\n @if (suffix(); as suffix) {\n <span class=\"kt-field-box__affix\">\n @if (asTemplate(suffix); as tpl) {\n <ng-container [ngTemplateOutlet]=\"tpl\" />\n } @else {\n {{ asText(suffix) }}\n }\n </span>\n }\n </div>\n</kt-field>\n" }]
|
|
3170
3428
|
}], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }, { type: i0.Output, args: ["valueChange"] }] } });
|
|
3171
3429
|
|
|
3172
3430
|
/** Champ « heure sans date » : valeur = `Temporal.PlainTime`, input natif `type="time"`.
|
|
@@ -3190,11 +3448,11 @@ class KtTimeField extends KtBaseTimeTemporalField {
|
|
|
3190
3448
|
return value.toString({ smallestUnit: this.precision() });
|
|
3191
3449
|
}
|
|
3192
3450
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.1", ngImport: i0, type: KtTimeField, deps: null, target: i0.ɵɵFactoryTarget.Component });
|
|
3193
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.1", type: KtTimeField, isStandalone: true, selector: "kt-time-field", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange" }, usesInheritance: true, ngImport: i0, template: "<kt-field\n [label]=\"label()\"\n [hint]=\"hint()\"\n [helpText]=\"helpText()\"\n [helpLabel]=\"helpLabel()\"\n [customDescribedBy]=\"customDescribedBy()\"\n [errors]=\"
|
|
3451
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.1", type: KtTimeField, isStandalone: true, selector: "kt-time-field", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange" }, usesInheritance: true, ngImport: i0, template: "<kt-field\n [label]=\"label()\"\n [hint]=\"hint()\"\n [helpText]=\"helpText()\"\n [helpLabel]=\"helpLabel()\"\n [customDescribedBy]=\"customDescribedBy()\"\n [errors]=\"displayErrors()\"\n [invalid]=\"showInvalid()\"\n [required]=\"required()\"\n [fieldId]=\"id()\"\n [appearance]=\"appearance()\"\n [floatLabel]=\"floatLabel()\"\n (helpClick)=\"helpClick.emit($event)\"\n>\n <ng-content select=\"[ktFieldHelp]\" />\n <div\n class=\"kt-field-box\"\n [attr.data-invalid]=\"showInvalid() ? '' : null\"\n [attr.data-disabled]=\"disabled() ? '' : null\"\n [attr.data-pending]=\"pending() ? '' : null\"\n >\n @if (icon(); as icon) {\n <span class=\"kt-field-box__icon\" aria-hidden=\"true\">{{ icon }}</span>\n }\n\n @if (prefix(); as prefix) {\n <span class=\"kt-field-box__affix\">\n @if (asTemplate(prefix); as tpl) {\n <ng-container [ngTemplateOutlet]=\"tpl\" />\n } @else {\n {{ asText(prefix) }}\n }\n </span>\n }\n\n <input\n #input\n ktFieldControl\n class=\"kt-field-box__input\"\n type=\"time\"\n [disabled]=\"disabled()\"\n [readOnly]=\"readonly()\"\n [attr.aria-busy]=\"pending() ? 'true' : null\"\n [attr.name]=\"name() || null\"\n [attr.placeholder]=\"placeholder()\"\n [attr.min]=\"serializedMin()\"\n [attr.max]=\"serializedMax()\"\n [attr.step]=\"step()\"\n [attr.list]=\"hasSuggestions() ? datalistId : null\"\n (input)=\"onInput($event)\"\n (keydown)=\"onKeyDown($event)\"\n (blur)=\"touched.set(true)\"\n />\n\n @if (hasSuggestions()) {\n <datalist [id]=\"datalistId\">\n @for (option of datalistOptions(); track $index) {\n <option [value]=\"option.value\" [attr.label]=\"option.label\"></option>\n }\n </datalist>\n }\n\n @if (showClear()) {\n <button type=\"button\" class=\"kt-field-box__clear\" [attr.aria-label]=\"clearLabel()\" (click)=\"clear()\">\n <span class=\"kt-field-box__icon\" aria-hidden=\"true\">close</span>\n </button>\n }\n\n @if (suffix(); as suffix) {\n <span class=\"kt-field-box__affix\">\n @if (asTemplate(suffix); as tpl) {\n <ng-container [ngTemplateOutlet]=\"tpl\" />\n } @else {\n {{ asText(suffix) }}\n }\n </span>\n }\n </div>\n</kt-field>\n", dependencies: [{ kind: "component", type: KtField, selector: "kt-field", inputs: ["label", "hint", "helpText", "helpLabel", "customDescribedBy", "errors", "invalid", "required", "fieldId", "hideHintWhenInvalid", "showAllErrors", "appearance", "floatLabel"], outputs: ["helpClick"] }, { kind: "directive", type: KtFieldControl, selector: "[ktFieldControl]" }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
3194
3452
|
}
|
|
3195
3453
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.1", ngImport: i0, type: KtTimeField, decorators: [{
|
|
3196
3454
|
type: Component,
|
|
3197
|
-
args: [{ selector: 'kt-time-field', imports: [KtField, KtFieldControl, NgTemplateOutlet], changeDetection: ChangeDetectionStrategy.OnPush, template: "<kt-field\n [label]=\"label()\"\n [hint]=\"hint()\"\n [helpText]=\"helpText()\"\n [helpLabel]=\"helpLabel()\"\n [customDescribedBy]=\"customDescribedBy()\"\n [errors]=\"
|
|
3455
|
+
args: [{ selector: 'kt-time-field', imports: [KtField, KtFieldControl, NgTemplateOutlet], changeDetection: ChangeDetectionStrategy.OnPush, template: "<kt-field\n [label]=\"label()\"\n [hint]=\"hint()\"\n [helpText]=\"helpText()\"\n [helpLabel]=\"helpLabel()\"\n [customDescribedBy]=\"customDescribedBy()\"\n [errors]=\"displayErrors()\"\n [invalid]=\"showInvalid()\"\n [required]=\"required()\"\n [fieldId]=\"id()\"\n [appearance]=\"appearance()\"\n [floatLabel]=\"floatLabel()\"\n (helpClick)=\"helpClick.emit($event)\"\n>\n <ng-content select=\"[ktFieldHelp]\" />\n <div\n class=\"kt-field-box\"\n [attr.data-invalid]=\"showInvalid() ? '' : null\"\n [attr.data-disabled]=\"disabled() ? '' : null\"\n [attr.data-pending]=\"pending() ? '' : null\"\n >\n @if (icon(); as icon) {\n <span class=\"kt-field-box__icon\" aria-hidden=\"true\">{{ icon }}</span>\n }\n\n @if (prefix(); as prefix) {\n <span class=\"kt-field-box__affix\">\n @if (asTemplate(prefix); as tpl) {\n <ng-container [ngTemplateOutlet]=\"tpl\" />\n } @else {\n {{ asText(prefix) }}\n }\n </span>\n }\n\n <input\n #input\n ktFieldControl\n class=\"kt-field-box__input\"\n type=\"time\"\n [disabled]=\"disabled()\"\n [readOnly]=\"readonly()\"\n [attr.aria-busy]=\"pending() ? 'true' : null\"\n [attr.name]=\"name() || null\"\n [attr.placeholder]=\"placeholder()\"\n [attr.min]=\"serializedMin()\"\n [attr.max]=\"serializedMax()\"\n [attr.step]=\"step()\"\n [attr.list]=\"hasSuggestions() ? datalistId : null\"\n (input)=\"onInput($event)\"\n (keydown)=\"onKeyDown($event)\"\n (blur)=\"touched.set(true)\"\n />\n\n @if (hasSuggestions()) {\n <datalist [id]=\"datalistId\">\n @for (option of datalistOptions(); track $index) {\n <option [value]=\"option.value\" [attr.label]=\"option.label\"></option>\n }\n </datalist>\n }\n\n @if (showClear()) {\n <button type=\"button\" class=\"kt-field-box__clear\" [attr.aria-label]=\"clearLabel()\" (click)=\"clear()\">\n <span class=\"kt-field-box__icon\" aria-hidden=\"true\">close</span>\n </button>\n }\n\n @if (suffix(); as suffix) {\n <span class=\"kt-field-box__affix\">\n @if (asTemplate(suffix); as tpl) {\n <ng-container [ngTemplateOutlet]=\"tpl\" />\n } @else {\n {{ asText(suffix) }}\n }\n </span>\n }\n </div>\n</kt-field>\n" }]
|
|
3198
3456
|
}], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }, { type: i0.Output, args: ["valueChange"] }] } });
|
|
3199
3457
|
|
|
3200
3458
|
/** Champ « date-heure sans fuseau » : valeur = `Temporal.PlainDateTime`, input
|
|
@@ -3219,11 +3477,11 @@ class KtDateTimeField extends KtBaseTimeTemporalField {
|
|
|
3219
3477
|
return value.toString({ smallestUnit: this.precision() });
|
|
3220
3478
|
}
|
|
3221
3479
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.1", ngImport: i0, type: KtDateTimeField, deps: null, target: i0.ɵɵFactoryTarget.Component });
|
|
3222
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.1", type: KtDateTimeField, isStandalone: true, selector: "kt-date-time-field", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange" }, usesInheritance: true, ngImport: i0, template: "<kt-field\n [label]=\"label()\"\n [hint]=\"hint()\"\n [helpText]=\"helpText()\"\n [helpLabel]=\"helpLabel()\"\n [customDescribedBy]=\"customDescribedBy()\"\n [errors]=\"
|
|
3480
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.1", type: KtDateTimeField, isStandalone: true, selector: "kt-date-time-field", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange" }, usesInheritance: true, ngImport: i0, template: "<kt-field\n [label]=\"label()\"\n [hint]=\"hint()\"\n [helpText]=\"helpText()\"\n [helpLabel]=\"helpLabel()\"\n [customDescribedBy]=\"customDescribedBy()\"\n [errors]=\"displayErrors()\"\n [invalid]=\"showInvalid()\"\n [required]=\"required()\"\n [fieldId]=\"id()\"\n [appearance]=\"appearance()\"\n [floatLabel]=\"floatLabel()\"\n (helpClick)=\"helpClick.emit($event)\"\n>\n <ng-content select=\"[ktFieldHelp]\" />\n <div\n class=\"kt-field-box\"\n [attr.data-invalid]=\"showInvalid() ? '' : null\"\n [attr.data-disabled]=\"disabled() ? '' : null\"\n [attr.data-pending]=\"pending() ? '' : null\"\n >\n @if (icon(); as icon) {\n <span class=\"kt-field-box__icon\" aria-hidden=\"true\">{{ icon }}</span>\n }\n\n @if (prefix(); as prefix) {\n <span class=\"kt-field-box__affix\">\n @if (asTemplate(prefix); as tpl) {\n <ng-container [ngTemplateOutlet]=\"tpl\" />\n } @else {\n {{ asText(prefix) }}\n }\n </span>\n }\n\n <input\n #input\n ktFieldControl\n class=\"kt-field-box__input\"\n type=\"datetime-local\"\n [disabled]=\"disabled()\"\n [readOnly]=\"readonly()\"\n [attr.aria-busy]=\"pending() ? 'true' : null\"\n [attr.name]=\"name() || null\"\n [attr.placeholder]=\"placeholder()\"\n [attr.min]=\"serializedMin()\"\n [attr.max]=\"serializedMax()\"\n [attr.step]=\"step()\"\n [attr.list]=\"hasSuggestions() ? datalistId : null\"\n (input)=\"onInput($event)\"\n (keydown)=\"onKeyDown($event)\"\n (blur)=\"touched.set(true)\"\n />\n\n @if (hasSuggestions()) {\n <datalist [id]=\"datalistId\">\n @for (option of datalistOptions(); track $index) {\n <option [value]=\"option.value\" [attr.label]=\"option.label\"></option>\n }\n </datalist>\n }\n\n @if (showClear()) {\n <button type=\"button\" class=\"kt-field-box__clear\" [attr.aria-label]=\"clearLabel()\" (click)=\"clear()\">\n <span class=\"kt-field-box__icon\" aria-hidden=\"true\">close</span>\n </button>\n }\n\n @if (suffix(); as suffix) {\n <span class=\"kt-field-box__affix\">\n @if (asTemplate(suffix); as tpl) {\n <ng-container [ngTemplateOutlet]=\"tpl\" />\n } @else {\n {{ asText(suffix) }}\n }\n </span>\n }\n </div>\n</kt-field>\n", dependencies: [{ kind: "component", type: KtField, selector: "kt-field", inputs: ["label", "hint", "helpText", "helpLabel", "customDescribedBy", "errors", "invalid", "required", "fieldId", "hideHintWhenInvalid", "showAllErrors", "appearance", "floatLabel"], outputs: ["helpClick"] }, { kind: "directive", type: KtFieldControl, selector: "[ktFieldControl]" }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
3223
3481
|
}
|
|
3224
3482
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.1", ngImport: i0, type: KtDateTimeField, decorators: [{
|
|
3225
3483
|
type: Component,
|
|
3226
|
-
args: [{ selector: 'kt-date-time-field', imports: [KtField, KtFieldControl, NgTemplateOutlet], changeDetection: ChangeDetectionStrategy.OnPush, template: "<kt-field\n [label]=\"label()\"\n [hint]=\"hint()\"\n [helpText]=\"helpText()\"\n [helpLabel]=\"helpLabel()\"\n [customDescribedBy]=\"customDescribedBy()\"\n [errors]=\"
|
|
3484
|
+
args: [{ selector: 'kt-date-time-field', imports: [KtField, KtFieldControl, NgTemplateOutlet], changeDetection: ChangeDetectionStrategy.OnPush, template: "<kt-field\n [label]=\"label()\"\n [hint]=\"hint()\"\n [helpText]=\"helpText()\"\n [helpLabel]=\"helpLabel()\"\n [customDescribedBy]=\"customDescribedBy()\"\n [errors]=\"displayErrors()\"\n [invalid]=\"showInvalid()\"\n [required]=\"required()\"\n [fieldId]=\"id()\"\n [appearance]=\"appearance()\"\n [floatLabel]=\"floatLabel()\"\n (helpClick)=\"helpClick.emit($event)\"\n>\n <ng-content select=\"[ktFieldHelp]\" />\n <div\n class=\"kt-field-box\"\n [attr.data-invalid]=\"showInvalid() ? '' : null\"\n [attr.data-disabled]=\"disabled() ? '' : null\"\n [attr.data-pending]=\"pending() ? '' : null\"\n >\n @if (icon(); as icon) {\n <span class=\"kt-field-box__icon\" aria-hidden=\"true\">{{ icon }}</span>\n }\n\n @if (prefix(); as prefix) {\n <span class=\"kt-field-box__affix\">\n @if (asTemplate(prefix); as tpl) {\n <ng-container [ngTemplateOutlet]=\"tpl\" />\n } @else {\n {{ asText(prefix) }}\n }\n </span>\n }\n\n <input\n #input\n ktFieldControl\n class=\"kt-field-box__input\"\n type=\"datetime-local\"\n [disabled]=\"disabled()\"\n [readOnly]=\"readonly()\"\n [attr.aria-busy]=\"pending() ? 'true' : null\"\n [attr.name]=\"name() || null\"\n [attr.placeholder]=\"placeholder()\"\n [attr.min]=\"serializedMin()\"\n [attr.max]=\"serializedMax()\"\n [attr.step]=\"step()\"\n [attr.list]=\"hasSuggestions() ? datalistId : null\"\n (input)=\"onInput($event)\"\n (keydown)=\"onKeyDown($event)\"\n (blur)=\"touched.set(true)\"\n />\n\n @if (hasSuggestions()) {\n <datalist [id]=\"datalistId\">\n @for (option of datalistOptions(); track $index) {\n <option [value]=\"option.value\" [attr.label]=\"option.label\"></option>\n }\n </datalist>\n }\n\n @if (showClear()) {\n <button type=\"button\" class=\"kt-field-box__clear\" [attr.aria-label]=\"clearLabel()\" (click)=\"clear()\">\n <span class=\"kt-field-box__icon\" aria-hidden=\"true\">close</span>\n </button>\n }\n\n @if (suffix(); as suffix) {\n <span class=\"kt-field-box__affix\">\n @if (asTemplate(suffix); as tpl) {\n <ng-container [ngTemplateOutlet]=\"tpl\" />\n } @else {\n {{ asText(suffix) }}\n }\n </span>\n }\n </div>\n</kt-field>\n" }]
|
|
3227
3485
|
}], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }, { type: i0.Output, args: ["valueChange"] }] } });
|
|
3228
3486
|
|
|
3229
3487
|
/** Champ « mois/année » (ex. expiration de carte) : valeur = `Temporal.PlainYearMonth`,
|
|
@@ -3247,11 +3505,11 @@ class KtYearMonthField extends KtBaseTemporalField {
|
|
|
3247
3505
|
return value.toString();
|
|
3248
3506
|
}
|
|
3249
3507
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.1", ngImport: i0, type: KtYearMonthField, deps: null, target: i0.ɵɵFactoryTarget.Component });
|
|
3250
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.1", type: KtYearMonthField, isStandalone: true, selector: "kt-year-month-field", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange" }, usesInheritance: true, ngImport: i0, template: "<kt-field\n [label]=\"label()\"\n [hint]=\"hint()\"\n [helpText]=\"helpText()\"\n [helpLabel]=\"helpLabel()\"\n [customDescribedBy]=\"customDescribedBy()\"\n [errors]=\"
|
|
3508
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.1", type: KtYearMonthField, isStandalone: true, selector: "kt-year-month-field", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange" }, usesInheritance: true, ngImport: i0, template: "<kt-field\n [label]=\"label()\"\n [hint]=\"hint()\"\n [helpText]=\"helpText()\"\n [helpLabel]=\"helpLabel()\"\n [customDescribedBy]=\"customDescribedBy()\"\n [errors]=\"displayErrors()\"\n [invalid]=\"showInvalid()\"\n [required]=\"required()\"\n [fieldId]=\"id()\"\n [appearance]=\"appearance()\"\n [floatLabel]=\"floatLabel()\"\n (helpClick)=\"helpClick.emit($event)\"\n>\n <ng-content select=\"[ktFieldHelp]\" />\n <div\n class=\"kt-field-box\"\n [attr.data-invalid]=\"showInvalid() ? '' : null\"\n [attr.data-disabled]=\"disabled() ? '' : null\"\n [attr.data-pending]=\"pending() ? '' : null\"\n >\n @if (icon(); as icon) {\n <span class=\"kt-field-box__icon\" aria-hidden=\"true\">{{ icon }}</span>\n }\n\n @if (prefix(); as prefix) {\n <span class=\"kt-field-box__affix\">\n @if (asTemplate(prefix); as tpl) {\n <ng-container [ngTemplateOutlet]=\"tpl\" />\n } @else {\n {{ asText(prefix) }}\n }\n </span>\n }\n\n <input\n #input\n ktFieldControl\n class=\"kt-field-box__input\"\n type=\"month\"\n [disabled]=\"disabled()\"\n [readOnly]=\"readonly()\"\n [attr.aria-busy]=\"pending() ? 'true' : null\"\n [attr.name]=\"name() || null\"\n [attr.placeholder]=\"placeholder()\"\n [attr.min]=\"serializedMin()\"\n [attr.max]=\"serializedMax()\"\n [attr.list]=\"hasSuggestions() ? datalistId : null\"\n (input)=\"onInput($event)\"\n (keydown)=\"onKeyDown($event)\"\n (blur)=\"touched.set(true)\"\n />\n\n @if (hasSuggestions()) {\n <datalist [id]=\"datalistId\">\n @for (option of datalistOptions(); track $index) {\n <option [value]=\"option.value\" [attr.label]=\"option.label\"></option>\n }\n </datalist>\n }\n\n @if (showClear()) {\n <button type=\"button\" class=\"kt-field-box__clear\" [attr.aria-label]=\"clearLabel()\" (click)=\"clear()\">\n <span class=\"kt-field-box__icon\" aria-hidden=\"true\">close</span>\n </button>\n }\n\n @if (suffix(); as suffix) {\n <span class=\"kt-field-box__affix\">\n @if (asTemplate(suffix); as tpl) {\n <ng-container [ngTemplateOutlet]=\"tpl\" />\n } @else {\n {{ asText(suffix) }}\n }\n </span>\n }\n </div>\n</kt-field>\n", dependencies: [{ kind: "component", type: KtField, selector: "kt-field", inputs: ["label", "hint", "helpText", "helpLabel", "customDescribedBy", "errors", "invalid", "required", "fieldId", "hideHintWhenInvalid", "showAllErrors", "appearance", "floatLabel"], outputs: ["helpClick"] }, { kind: "directive", type: KtFieldControl, selector: "[ktFieldControl]" }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
3251
3509
|
}
|
|
3252
3510
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.1", ngImport: i0, type: KtYearMonthField, decorators: [{
|
|
3253
3511
|
type: Component,
|
|
3254
|
-
args: [{ selector: 'kt-year-month-field', imports: [KtField, KtFieldControl, NgTemplateOutlet], changeDetection: ChangeDetectionStrategy.OnPush, template: "<kt-field\n [label]=\"label()\"\n [hint]=\"hint()\"\n [helpText]=\"helpText()\"\n [helpLabel]=\"helpLabel()\"\n [customDescribedBy]=\"customDescribedBy()\"\n [errors]=\"
|
|
3512
|
+
args: [{ selector: 'kt-year-month-field', imports: [KtField, KtFieldControl, NgTemplateOutlet], changeDetection: ChangeDetectionStrategy.OnPush, template: "<kt-field\n [label]=\"label()\"\n [hint]=\"hint()\"\n [helpText]=\"helpText()\"\n [helpLabel]=\"helpLabel()\"\n [customDescribedBy]=\"customDescribedBy()\"\n [errors]=\"displayErrors()\"\n [invalid]=\"showInvalid()\"\n [required]=\"required()\"\n [fieldId]=\"id()\"\n [appearance]=\"appearance()\"\n [floatLabel]=\"floatLabel()\"\n (helpClick)=\"helpClick.emit($event)\"\n>\n <ng-content select=\"[ktFieldHelp]\" />\n <div\n class=\"kt-field-box\"\n [attr.data-invalid]=\"showInvalid() ? '' : null\"\n [attr.data-disabled]=\"disabled() ? '' : null\"\n [attr.data-pending]=\"pending() ? '' : null\"\n >\n @if (icon(); as icon) {\n <span class=\"kt-field-box__icon\" aria-hidden=\"true\">{{ icon }}</span>\n }\n\n @if (prefix(); as prefix) {\n <span class=\"kt-field-box__affix\">\n @if (asTemplate(prefix); as tpl) {\n <ng-container [ngTemplateOutlet]=\"tpl\" />\n } @else {\n {{ asText(prefix) }}\n }\n </span>\n }\n\n <input\n #input\n ktFieldControl\n class=\"kt-field-box__input\"\n type=\"month\"\n [disabled]=\"disabled()\"\n [readOnly]=\"readonly()\"\n [attr.aria-busy]=\"pending() ? 'true' : null\"\n [attr.name]=\"name() || null\"\n [attr.placeholder]=\"placeholder()\"\n [attr.min]=\"serializedMin()\"\n [attr.max]=\"serializedMax()\"\n [attr.list]=\"hasSuggestions() ? datalistId : null\"\n (input)=\"onInput($event)\"\n (keydown)=\"onKeyDown($event)\"\n (blur)=\"touched.set(true)\"\n />\n\n @if (hasSuggestions()) {\n <datalist [id]=\"datalistId\">\n @for (option of datalistOptions(); track $index) {\n <option [value]=\"option.value\" [attr.label]=\"option.label\"></option>\n }\n </datalist>\n }\n\n @if (showClear()) {\n <button type=\"button\" class=\"kt-field-box__clear\" [attr.aria-label]=\"clearLabel()\" (click)=\"clear()\">\n <span class=\"kt-field-box__icon\" aria-hidden=\"true\">close</span>\n </button>\n }\n\n @if (suffix(); as suffix) {\n <span class=\"kt-field-box__affix\">\n @if (asTemplate(suffix); as tpl) {\n <ng-container [ngTemplateOutlet]=\"tpl\" />\n } @else {\n {{ asText(suffix) }}\n }\n </span>\n }\n </div>\n</kt-field>\n" }]
|
|
3255
3513
|
}], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }, { type: i0.Output, args: ["valueChange"] }] } });
|
|
3256
3514
|
|
|
3257
3515
|
/** Source unique de l'heure courante et du **fuseau local** de l'utilisateur.
|
|
@@ -3349,11 +3607,11 @@ class KtInstantField extends KtBaseTimeTemporalField {
|
|
|
3349
3607
|
.toString({ smallestUnit: this.precision() });
|
|
3350
3608
|
}
|
|
3351
3609
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.1", ngImport: i0, type: KtInstantField, deps: null, target: i0.ɵɵFactoryTarget.Component });
|
|
3352
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.1", type: KtInstantField, isStandalone: true, selector: "kt-instant-field", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange" }, usesInheritance: true, ngImport: i0, template: "<kt-field\n [label]=\"label()\"\n [hint]=\"hint()\"\n [helpText]=\"helpText()\"\n [helpLabel]=\"helpLabel()\"\n [customDescribedBy]=\"customDescribedBy()\"\n [errors]=\"
|
|
3610
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.1", type: KtInstantField, isStandalone: true, selector: "kt-instant-field", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange" }, usesInheritance: true, ngImport: i0, template: "<kt-field\n [label]=\"label()\"\n [hint]=\"hint()\"\n [helpText]=\"helpText()\"\n [helpLabel]=\"helpLabel()\"\n [customDescribedBy]=\"customDescribedBy()\"\n [errors]=\"displayErrors()\"\n [invalid]=\"showInvalid()\"\n [required]=\"required()\"\n [fieldId]=\"id()\"\n [appearance]=\"appearance()\"\n [floatLabel]=\"floatLabel()\"\n (helpClick)=\"helpClick.emit($event)\"\n>\n <ng-content select=\"[ktFieldHelp]\" />\n <div\n class=\"kt-field-box\"\n [attr.data-invalid]=\"showInvalid() ? '' : null\"\n [attr.data-disabled]=\"disabled() ? '' : null\"\n [attr.data-pending]=\"pending() ? '' : null\"\n >\n @if (icon(); as icon) {\n <span class=\"kt-field-box__icon\" aria-hidden=\"true\">{{ icon }}</span>\n }\n\n @if (prefix(); as prefix) {\n <span class=\"kt-field-box__affix\">\n @if (asTemplate(prefix); as tpl) {\n <ng-container [ngTemplateOutlet]=\"tpl\" />\n } @else {\n {{ asText(prefix) }}\n }\n </span>\n }\n\n <input\n #input\n ktFieldControl\n class=\"kt-field-box__input\"\n type=\"datetime-local\"\n [disabled]=\"disabled()\"\n [readOnly]=\"readonly()\"\n [attr.aria-busy]=\"pending() ? 'true' : null\"\n [attr.name]=\"name() || null\"\n [attr.placeholder]=\"placeholder()\"\n [attr.min]=\"serializedMin()\"\n [attr.max]=\"serializedMax()\"\n [attr.step]=\"step()\"\n [attr.list]=\"hasSuggestions() ? datalistId : null\"\n (input)=\"onInput($event)\"\n (keydown)=\"onKeyDown($event)\"\n (blur)=\"touched.set(true)\"\n />\n\n @if (hasSuggestions()) {\n <datalist [id]=\"datalistId\">\n @for (option of datalistOptions(); track $index) {\n <option [value]=\"option.value\" [attr.label]=\"option.label\"></option>\n }\n </datalist>\n }\n\n @if (showClear()) {\n <button type=\"button\" class=\"kt-field-box__clear\" [attr.aria-label]=\"clearLabel()\" (click)=\"clear()\">\n <span class=\"kt-field-box__icon\" aria-hidden=\"true\">close</span>\n </button>\n }\n\n @if (suffix(); as suffix) {\n <span class=\"kt-field-box__affix\">\n @if (asTemplate(suffix); as tpl) {\n <ng-container [ngTemplateOutlet]=\"tpl\" />\n } @else {\n {{ asText(suffix) }}\n }\n </span>\n }\n </div>\n</kt-field>\n", dependencies: [{ kind: "component", type: KtField, selector: "kt-field", inputs: ["label", "hint", "helpText", "helpLabel", "customDescribedBy", "errors", "invalid", "required", "fieldId", "hideHintWhenInvalid", "showAllErrors", "appearance", "floatLabel"], outputs: ["helpClick"] }, { kind: "directive", type: KtFieldControl, selector: "[ktFieldControl]" }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
3353
3611
|
}
|
|
3354
3612
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.1", ngImport: i0, type: KtInstantField, decorators: [{
|
|
3355
3613
|
type: Component,
|
|
3356
|
-
args: [{ selector: 'kt-instant-field', imports: [KtField, KtFieldControl, NgTemplateOutlet], changeDetection: ChangeDetectionStrategy.OnPush, template: "<kt-field\n [label]=\"label()\"\n [hint]=\"hint()\"\n [helpText]=\"helpText()\"\n [helpLabel]=\"helpLabel()\"\n [customDescribedBy]=\"customDescribedBy()\"\n [errors]=\"
|
|
3614
|
+
args: [{ selector: 'kt-instant-field', imports: [KtField, KtFieldControl, NgTemplateOutlet], changeDetection: ChangeDetectionStrategy.OnPush, template: "<kt-field\n [label]=\"label()\"\n [hint]=\"hint()\"\n [helpText]=\"helpText()\"\n [helpLabel]=\"helpLabel()\"\n [customDescribedBy]=\"customDescribedBy()\"\n [errors]=\"displayErrors()\"\n [invalid]=\"showInvalid()\"\n [required]=\"required()\"\n [fieldId]=\"id()\"\n [appearance]=\"appearance()\"\n [floatLabel]=\"floatLabel()\"\n (helpClick)=\"helpClick.emit($event)\"\n>\n <ng-content select=\"[ktFieldHelp]\" />\n <div\n class=\"kt-field-box\"\n [attr.data-invalid]=\"showInvalid() ? '' : null\"\n [attr.data-disabled]=\"disabled() ? '' : null\"\n [attr.data-pending]=\"pending() ? '' : null\"\n >\n @if (icon(); as icon) {\n <span class=\"kt-field-box__icon\" aria-hidden=\"true\">{{ icon }}</span>\n }\n\n @if (prefix(); as prefix) {\n <span class=\"kt-field-box__affix\">\n @if (asTemplate(prefix); as tpl) {\n <ng-container [ngTemplateOutlet]=\"tpl\" />\n } @else {\n {{ asText(prefix) }}\n }\n </span>\n }\n\n <input\n #input\n ktFieldControl\n class=\"kt-field-box__input\"\n type=\"datetime-local\"\n [disabled]=\"disabled()\"\n [readOnly]=\"readonly()\"\n [attr.aria-busy]=\"pending() ? 'true' : null\"\n [attr.name]=\"name() || null\"\n [attr.placeholder]=\"placeholder()\"\n [attr.min]=\"serializedMin()\"\n [attr.max]=\"serializedMax()\"\n [attr.step]=\"step()\"\n [attr.list]=\"hasSuggestions() ? datalistId : null\"\n (input)=\"onInput($event)\"\n (keydown)=\"onKeyDown($event)\"\n (blur)=\"touched.set(true)\"\n />\n\n @if (hasSuggestions()) {\n <datalist [id]=\"datalistId\">\n @for (option of datalistOptions(); track $index) {\n <option [value]=\"option.value\" [attr.label]=\"option.label\"></option>\n }\n </datalist>\n }\n\n @if (showClear()) {\n <button type=\"button\" class=\"kt-field-box__clear\" [attr.aria-label]=\"clearLabel()\" (click)=\"clear()\">\n <span class=\"kt-field-box__icon\" aria-hidden=\"true\">close</span>\n </button>\n }\n\n @if (suffix(); as suffix) {\n <span class=\"kt-field-box__affix\">\n @if (asTemplate(suffix); as tpl) {\n <ng-container [ngTemplateOutlet]=\"tpl\" />\n } @else {\n {{ asText(suffix) }}\n }\n </span>\n }\n </div>\n</kt-field>\n" }]
|
|
3357
3615
|
}], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }, { type: i0.Output, args: ["valueChange"] }] } });
|
|
3358
3616
|
|
|
3359
3617
|
/** Formate une valeur Temporal pour l'affichage selon la locale active.
|
|
@@ -3376,6 +3634,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.1", ngImpor
|
|
|
3376
3634
|
// Exception R1 ASSUMÉE : le name `temporalDate` (non préfixé `kt`) relève du domaine Temporal,
|
|
3377
3635
|
// exempté de préfixe au même titre que le namespace `Temporal` et ses alias de types. La CLASSE
|
|
3378
3636
|
// reste préfixée (`KtTemporalDatePipe`). Choix ergonomique acté (ADR-4).
|
|
3637
|
+
// Stryker disable next-line all: le `name` du pipe doit rester statiquement analysable par l'AOT (NG1010).
|
|
3379
3638
|
class KtTemporalDatePipe {
|
|
3380
3639
|
locale = inject(LOCALE_ID);
|
|
3381
3640
|
clock = inject(KtClock);
|
|
@@ -3406,5 +3665,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.1", ngImpor
|
|
|
3406
3665
|
* Generated bundle index. Do not edit.
|
|
3407
3666
|
*/
|
|
3408
3667
|
|
|
3409
|
-
export { DEFAULT_KT_SELECT_CONFIG, KT_CHIPS_CONFIG, KT_FIELD, KT_FIELD_CONFIG, KT_SELECT_CONFIG, KtBaseInputField, KtBaseSelect, KtBaseTemporalField, KtBaseTimeTemporalField, KtCheckbox, KtCheckboxGroup, KtChip, KtChipItemDef, KtChipList, KtClock, KtDateField, KtDateTimeField, KtField, KtFieldControl, KtFixedClock, KtInstantField, KtMultiSelect, KtMultiSelectChipDef, KtMultiSelectOptionDef, KtMultiSelectTriggerDef, KtNumberField, KtRadio, KtRadioGroup, KtSelect, KtSelectConfig, KtSelectOptionDef, KtSelectTriggerDef, KtSwitch, KtTemporalDatePipe, KtTextArea, KtTextField, KtTimeField, KtYearMonthField, Temporal, defaultKtFieldErrorMatcher, normalizeKtSuggestions, provideKtField };
|
|
3668
|
+
export { DEFAULT_KT_SELECT_CONFIG, KT_CHIPS_CONFIG, KT_DEFAULT_FIELD_ERROR_MESSAGES, KT_FIELD, KT_FIELD_CONFIG, KT_SELECT_CONFIG, KtBaseInputField, KtBaseSelect, KtBaseTemporalField, KtBaseTimeTemporalField, KtCheckbox, KtCheckboxGroup, KtChip, KtChipItemDef, KtChipList, KtClock, KtDateField, KtDateTimeField, KtField, KtFieldControl, KtFieldErrorResolver, KtFixedClock, KtInstantField, KtMultiSelect, KtMultiSelectChipDef, KtMultiSelectOptionDef, KtMultiSelectTriggerDef, KtNumberField, KtRadio, KtRadioGroup, KtSelect, KtSelectConfig, KtSelectOptionDef, KtSelectTriggerDef, KtSwitch, KtTemporalDatePipe, KtTextArea, KtTextField, KtTimeField, KtYearMonthField, Temporal, defaultKtFieldErrorMatcher, ktErrorParam, normalizeKtSuggestions, provideKtField };
|
|
3410
3669
|
//# sourceMappingURL=ktortu-aaa-forms.mjs.map
|