@ktortu/aaa 0.9.4 → 0.9.5

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.
@@ -0,0 +1,41 @@
1
+ @layer kt-aaa.components {
2
+ .kt-chip-listbox-field {
3
+ display: flex;
4
+ flex-direction: column;
5
+ gap: 0.5rem;
6
+ }
7
+
8
+ .kt-chip-listbox__legend {
9
+ font-size: 0.875rem;
10
+ font-weight: 500;
11
+ color: var(--field-label-color, currentColor);
12
+ }
13
+
14
+ .kt-chip-listbox__required {
15
+ color: var(--kt-danger);
16
+ margin-inline-start: 0.125rem;
17
+ }
18
+
19
+ .kt-chip-listbox__options {
20
+ display: flex;
21
+ flex-wrap: wrap;
22
+ gap: 0.5rem;
23
+ outline: none;
24
+ }
25
+
26
+ .kt-chip-listbox__hint {
27
+ font-size: 0.75rem;
28
+ color: var(--field-hint-color);
29
+ margin: 0;
30
+ }
31
+
32
+ .kt-chip-listbox__error {
33
+ font-size: 0.75rem;
34
+ color: var(--field-error-color);
35
+ min-block-size: 1.25rem;
36
+ }
37
+
38
+ .kt-chip-listbox__error-message {
39
+ display: block;
40
+ }
41
+ }
@@ -89,4 +89,51 @@
89
89
  inset: -8px;
90
90
  }
91
91
  }
92
+
93
+ :host(.kt-chip--selected) {
94
+ background: var(--chip-selected-bg, var(--chip-bg-hover));
95
+ border-color: var(--chip-selected-border, var(--chip-focus-ring));
96
+ color: var(--chip-selected-color, var(--chip-color));
97
+ }
98
+
99
+ .kt-chip__selected-icon {
100
+ font-family: 'Material Symbols Outlined';
101
+ font-feature-settings: 'liga';
102
+ font-size: 1rem;
103
+ line-height: 1;
104
+ -webkit-font-smoothing: antialiased;
105
+ margin-inline-end: 0.125rem;
106
+ }
107
+
108
+ /* --- Styles pour les puces sélectionnables (role="option") --- */
109
+ :host([role='option']) {
110
+ transition:
111
+ background-color 0.15s ease,
112
+ border-color 0.15s ease,
113
+ color 0.15s ease,
114
+ box-shadow 0.15s ease;
115
+ }
116
+
117
+ :host([role='option']:not([aria-disabled='true'])) {
118
+ cursor: pointer;
119
+ }
120
+
121
+ :host([role='option']:not([aria-disabled='true']):hover) {
122
+ background-color: var(--chip-bg-hover);
123
+ box-shadow: var(--chip-shadow-hover, var(--chip-shadow, none));
124
+ }
125
+
126
+ :host([role='option'].kt-chip--selected:not([aria-disabled='true']):hover) {
127
+ background-color: color-mix(in srgb, var(--chip-selected-bg) 85%, var(--kt-primary));
128
+ }
129
+
130
+ :host([role='option']:focus-visible) {
131
+ outline: 2px solid var(--chip-focus-ring);
132
+ outline-offset: 2px;
133
+ }
134
+
135
+ :host([role='option'][aria-disabled='true']) {
136
+ cursor: not-allowed;
137
+ opacity: 0.5;
138
+ }
92
139
  }
@@ -14,6 +14,11 @@
14
14
  --chip-bg-hover: color-mix(in srgb, var(--kt-primary) 18%, transparent);
15
15
  --chip-border: color-mix(in srgb, var(--kt-primary) 20%, transparent);
16
16
 
17
+ /* État sélectionné */
18
+ --chip-selected-bg: color-mix(in srgb, var(--kt-primary) 15%, transparent);
19
+ --chip-selected-border: var(--kt-primary);
20
+ --chip-selected-color: var(--kt-primary);
21
+
17
22
  /* Texte et icônes */
18
23
  --chip-color: var(--field-color);
19
24
  --chip-remove-color: var(--field-icon-color);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ktortu/aaa",
3
- "version": "0.9.4",
3
+ "version": "0.9.5",
4
4
  "description": "Bibliothèque de composants Angular headless + thémés par tokens CSS.",
5
5
  "keywords": [
6
6
  "angular",
@@ -370,6 +370,17 @@ declare class KtDialogContainer extends CdkDialogContainer {
370
370
  static ɵcmp: i0.ɵɵComponentDeclaration<KtDialogContainer, "kt-dialog-container", never, {}, {}, never, never, true, never>;
371
371
  }
372
372
 
373
+ /** Option de variante visuelle pour le dialogue d'alerte. */
374
+ type KtAlertDialogVariant = 'neutral' | 'info' | 'success' | 'warning' | 'error';
375
+ /**
376
+ * Options pour l'ouverture d'une boîte de dialogue d'alerte.
377
+ */
378
+ interface KtAlertOptions {
379
+ /** Libellé du bouton de fermeture. Par défaut: 'Fermer'. */
380
+ closeLabel?: string;
381
+ /** Variante sémantique (apparence : icône + accent). Par défaut: 'neutral'. */
382
+ variant?: KtAlertDialogVariant;
383
+ }
373
384
  /**
374
385
  * Configuration pour l'ouverture d'une boîte de dialogue d'alerte simple.
375
386
  */
@@ -384,6 +395,8 @@ interface KtAlertData {
384
395
  message: string | string[];
385
396
  /** Libellé du bouton de fermeture. Par défaut: 'Fermer'. */
386
397
  closeLabel?: string;
398
+ /** Variante sémantique (apparence : icône + accent). Par défaut: 'neutral'. */
399
+ variant?: KtAlertDialogVariant;
387
400
  }
388
401
  /**
389
402
  * Composant interne d'alerte générique.
@@ -474,6 +487,15 @@ declare class KtQuickDialog {
474
487
  * @returns La référence DialogRef de la modale ouverte.
475
488
  */
476
489
  alert(title: string, message: string | string[], closeLabel?: string): DialogRef<void, KtAlertDialog>;
490
+ /**
491
+ * Ouvre une boîte de dialogue d'alerte simple.
492
+ *
493
+ * @param title Titre de l'alerte.
494
+ * @param message Message d'explication (string simple ou tableau de strings pour du multi-lignes HTML).
495
+ * @param options Options d'ouverture de l'alerte (libellé de fermeture, variante).
496
+ * @returns La référence DialogRef de la modale ouverte.
497
+ */
498
+ alert(title: string, message: string | string[], options?: KtAlertOptions): DialogRef<void, KtAlertDialog>;
477
499
  /**
478
500
  * Ouvre une boîte de dialogue de confirmation binaire (Oui/Non).
479
501
  *
@@ -500,4 +522,4 @@ declare class KtQuickDialog {
500
522
  declare const KtDialogImports: readonly [typeof KtDialogHeader, typeof KtDialogTitle, typeof KtDialogDescription, typeof KtDialogContent, typeof KtDialogActions, typeof KtDialogClose, typeof KtDialogFocusInitial, typeof KtDialogSheetHandle];
501
523
 
502
524
  export { KT_DIALOG_AAA_DEFAULTS, KtAlertDialog, KtConfirmDialog, KtDialogActions, KtDialogClose, KtDialogContainer, KtDialogContent, KtDialogDescription, KtDialogFocusInitial, KtDialogHeader, KtDialogImports, KtDialogSheetHandle, KtDialogTitle, KtQuickDialog, defineKtDialog, injectAlertDialog, injectConfirmDialog, injectKtDialogOpener, provideKtDialogDefaults, resolveKtDialogPanelClass };
503
- export type { KtAlertData, KtConfirmConfig, KtConfirmResult, KtDecideConfig, KtDialogColor, KtDialogContract, KtDialogOpenerConfig, KtDialogPresentation };
525
+ export type { KtAlertData, KtAlertDialogVariant, KtAlertOptions, KtConfirmConfig, KtConfirmResult, KtDecideConfig, KtDialogColor, KtDialogContract, KtDialogOpenerConfig, KtDialogPresentation };
@@ -1451,7 +1451,88 @@ declare abstract class ChipTransitionScope {
1451
1451
  }
1452
1452
 
1453
1453
  /**
1454
- * Pilule individuelle (tag). Utilisable seule (tag statique) ou dans `kt-chip-list`.
1454
+ * Groupe de puces sélectionnables (Chip Listbox) conforme à l'ARIA Listbox / WCAG AAA.
1455
+ * Orchestrateur : s'intègre aux formulaires réactifs ou de modèle via `FormValueControl`.
1456
+ * Permet la sélection simple ou multiple, avec gestion du roving tabindex et des touches fléchées
1457
+ * de façon autonome et robuste.
1458
+ *
1459
+ * @example
1460
+ * ```html
1461
+ * <kt-chip-listbox label="Filtres" [(value)]="selectedTags" multiple>
1462
+ * <kt-chip [value]="'angular'">Angular</kt-chip>
1463
+ * <kt-chip [value]="'react'">React</kt-chip>
1464
+ * </kt-chip-listbox>
1465
+ * ```
1466
+ */
1467
+ declare class KtChipListbox<V> implements FormValueControl<V | V[] | null> {
1468
+ private readonly config;
1469
+ private readonly doc;
1470
+ /** Valeur sélectionnée (two-way) : tableau de valeurs (si multiple) ou valeur unique (si simple). */
1471
+ readonly value: _angular_core.ModelSignal<V | V[] | null>;
1472
+ /** État « touché » (two-way), piloté par `[formField]`. @default false */
1473
+ readonly touched: _angular_core.ModelSignal<boolean>;
1474
+ /** Désactive le groupe de puces. @default false */
1475
+ readonly disabled: _angular_core.InputSignalWithTransform<boolean, unknown>;
1476
+ /** Mode lecture seule (bloque la sélection). @default false */
1477
+ readonly readonly: _angular_core.InputSignalWithTransform<boolean, unknown>;
1478
+ /** Marque le groupe comme invalide. @default false */
1479
+ readonly invalid: _angular_core.InputSignalWithTransform<boolean, unknown>;
1480
+ /** Affiche l'astérisque requis et aria-required sur le groupe. @default false */
1481
+ readonly required: _angular_core.InputSignalWithTransform<boolean, unknown>;
1482
+ /** État « modifié » (dirty). @default false */
1483
+ readonly dirty: _angular_core.InputSignalWithTransform<boolean, unknown>;
1484
+ /** Validation asynchrone en cours. @default false */
1485
+ readonly pending: _angular_core.InputSignalWithTransform<boolean, unknown>;
1486
+ /** Erreurs de validation à afficher. @default [] */
1487
+ readonly errors: _angular_core.InputSignal<readonly WithOptionalFieldTree<ValidationError>[]>;
1488
+ /** Autorise la sélection de plusieurs puces. @default false */
1489
+ readonly multiple: _angular_core.InputSignalWithTransform<boolean, unknown>;
1490
+ /** Identifiant du composant (sélecteurs de test stables). @default auto-généré */
1491
+ readonly id: _angular_core.InputSignal<string | undefined>;
1492
+ /** Libellé (légende) du groupe de puces. @default undefined */
1493
+ readonly label: _angular_core.InputSignal<string | undefined>;
1494
+ /** Texte d'aide affiché sous le groupe. @default undefined */
1495
+ readonly hint: _angular_core.InputSignal<string | undefined>;
1496
+ /** Nom accessible (aria-label) quand label est absent. @default undefined */
1497
+ readonly ariaLabel: _angular_core.InputSignal<string | undefined>;
1498
+ /** Stratégie d'affichage des erreurs. @default undefined */
1499
+ readonly errorMatcher: _angular_core.InputSignal<KtFieldErrorMatcher | undefined>;
1500
+ /** Afficher toutes les erreurs. @default false */
1501
+ readonly showAllErrors: _angular_core.InputSignalWithTransform<boolean, unknown>;
1502
+ /** Fonction de comparaison de valeurs pour déterminer la sélection. */
1503
+ readonly compareWith: _angular_core.InputSignal<((a: V, b: V) => boolean) | undefined>;
1504
+ private readonly el;
1505
+ private readonly errorResolver;
1506
+ private readonly idGen;
1507
+ private readonly uid;
1508
+ protected readonly baseId: _angular_core.Signal<string>;
1509
+ protected readonly labelId: _angular_core.Signal<string>;
1510
+ protected readonly hintId: _angular_core.Signal<string>;
1511
+ protected readonly errorId: _angular_core.Signal<string>;
1512
+ protected readonly activeIndex: _angular_core.WritableSignal<number>;
1513
+ private readonly matcher;
1514
+ protected readonly showInvalid: _angular_core.Signal<boolean>;
1515
+ protected readonly resolvedErrors: _angular_core.Signal<_ktortu_aaa_forms.KtFieldError[]>;
1516
+ protected readonly displayedErrors: _angular_core.Signal<_ktortu_aaa_forms.KtFieldError[]>;
1517
+ protected readonly resolvedAriaLabel: _angular_core.Signal<string | null>;
1518
+ protected readonly describedBy: _angular_core.Signal<string | null>;
1519
+ private readonly comparator;
1520
+ constructor();
1521
+ private query;
1522
+ /** Détermine si une valeur d'option est sélectionnée. */
1523
+ isSelected(optionValue: V): boolean;
1524
+ /** Bascule la sélection d'une valeur d'option. */
1525
+ toggle(optionValue: V): void;
1526
+ protected onKeydown(event: KeyboardEvent): void;
1527
+ protected onFocusin(event: FocusEvent): void;
1528
+ /** Focus la première option active. */
1529
+ focus(options?: FocusOptions): void;
1530
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<KtChipListbox<any>, never>;
1531
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<KtChipListbox<any>, "kt-chip-listbox", never, { "value": { "alias": "value"; "required": false; "isSignal": true; }; "touched": { "alias": "touched"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "readonly": { "alias": "readonly"; "required": false; "isSignal": true; }; "invalid": { "alias": "invalid"; "required": false; "isSignal": true; }; "required": { "alias": "required"; "required": false; "isSignal": true; }; "dirty": { "alias": "dirty"; "required": false; "isSignal": true; }; "pending": { "alias": "pending"; "required": false; "isSignal": true; }; "errors": { "alias": "errors"; "required": false; "isSignal": true; }; "multiple": { "alias": "multiple"; "required": false; "isSignal": true; }; "id": { "alias": "id"; "required": false; "isSignal": true; }; "label": { "alias": "label"; "required": false; "isSignal": true; }; "hint": { "alias": "hint"; "required": false; "isSignal": true; }; "ariaLabel": { "alias": "ariaLabel"; "required": false; "isSignal": true; }; "errorMatcher": { "alias": "errorMatcher"; "required": false; "isSignal": true; }; "showAllErrors": { "alias": "showAllErrors"; "required": false; "isSignal": true; }; "compareWith": { "alias": "compareWith"; "required": false; "isSignal": true; }; }, { "value": "valueChange"; "touched": "touchedChange"; }, never, ["*"], true, never>;
1532
+ }
1533
+
1534
+ /**
1535
+ * Pilule individuelle (tag). Utilisable seule (tag statique), dans `kt-chip-list` ou dans `kt-chip-listbox`.
1455
1536
  * Le label vient de la projection de contenu ; `removable` ajoute un bouton « retirer »
1456
1537
  * (24px visibles, cible 44px via ::after — technique des boutons icon-only).
1457
1538
  *
@@ -1463,6 +1544,7 @@ declare abstract class ChipTransitionScope {
1463
1544
  */
1464
1545
  declare class KtChip {
1465
1546
  protected readonly scope: ChipTransitionScope | null;
1547
+ protected readonly listbox: KtChipListbox<unknown> | null;
1466
1548
  private readonly idGen;
1467
1549
  /** Nom de View Transition propre au chip (détail interne, posé en host binding). */
1468
1550
  protected readonly viewTransitionName: string;
@@ -1472,9 +1554,19 @@ declare class KtChip {
1472
1554
  readonly disabled: _angular_core.InputSignalWithTransform<boolean, unknown>;
1473
1555
  /** Libellé accessible du bouton « retirer » (inclure le nom de l'item : « Remove X »). @default 'Remove' */
1474
1556
  readonly removeLabel: _angular_core.InputSignal<string>;
1557
+ /** État sélectionné unitaire (quand utilisé hors boîte de liste). @default false */
1558
+ readonly checked: _angular_core.InputSignalWithTransform<boolean, unknown>;
1559
+ /** Valeur portée par la puce (utilisée au sein d'un groupe de sélection). */
1560
+ readonly value: _angular_core.InputSignal<unknown>;
1475
1561
  /** Émis au clic sur le bouton « retirer » (le parent décide de retirer le chip). */
1476
1562
  readonly remove: _angular_core.OutputEmitterRef<void>;
1563
+ private readonly initialRole;
1564
+ /** Rôle d'accessibilité calculé (préserve les rôles statiques comme listitem). */
1565
+ protected readonly role: _angular_core.Signal<string | null>;
1566
+ /** Signal consolidé de l'état de sélection (dérivé du parent listbox ou de l'input checked). */
1567
+ readonly selected: _angular_core.Signal<boolean>;
1477
1568
  private readonly removeBtn;
1569
+ constructor();
1478
1570
  /**
1479
1571
  * Focus programmatique du bouton « retirer ». Helper de coordination interne (focus management
1480
1572
  * d'`kt-chip-list`), non destiné aux consommateurs.
@@ -1482,7 +1574,7 @@ declare class KtChip {
1482
1574
  */
1483
1575
  focusRemove(): void;
1484
1576
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<KtChip, never>;
1485
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<KtChip, "kt-chip", never, { "removable": { "alias": "removable"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "removeLabel": { "alias": "removeLabel"; "required": false; "isSignal": true; }; }, { "remove": "remove"; }, never, ["*"], true, never>;
1577
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<KtChip, "kt-chip", never, { "removable": { "alias": "removable"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "removeLabel": { "alias": "removeLabel"; "required": false; "isSignal": true; }; "checked": { "alias": "checked"; "required": false; "isSignal": true; }; "value": { "alias": "value"; "required": false; "isSignal": true; }; }, { "remove": "remove"; }, never, ["*"], true, never>;
1486
1578
  }
1487
1579
 
1488
1580
  /** Contexte typé reçu par le template d'un chip custom (`ktChipItem`). */
@@ -1966,5 +2058,5 @@ declare class KtFixedClock extends KtClock {
1966
2058
  today(): Temporal$1.PlainDate;
1967
2059
  }
1968
2060
 
1969
- 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, KtPasswordField, KtRadio, KtRadioGroup, KtSelect, KtSelectConfig, KtSelectOptionDef, KtSelectTriggerDef, KtSwitch, KtTemporalDatePipe, KtTextArea, KtTextField, KtTimeField, KtYearMonthField, Temporal, defaultKtFieldErrorMatcher, ktErrorParam, normalizeKtSuggestions, provideKtField };
2061
+ 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, KtChipListbox, KtClock, KtDateField, KtDateTimeField, KtField, KtFieldControl, KtFieldErrorResolver, KtFixedClock, KtInstantField, KtMultiSelect, KtMultiSelectChipDef, KtMultiSelectOptionDef, KtMultiSelectTriggerDef, KtNumberField, KtPasswordField, KtRadio, KtRadioGroup, KtSelect, KtSelectConfig, KtSelectOptionDef, KtSelectTriggerDef, KtSwitch, KtTemporalDatePipe, KtTextArea, KtTextField, KtTimeField, KtYearMonthField, Temporal, defaultKtFieldErrorMatcher, ktErrorParam, normalizeKtSuggestions, provideKtField };
1970
2062
  export type { CalendarDate, KtChipItemContext, KtChipsConfig, KtDatalistOption, KtErrorMessageFactory, KtFieldAppearance, KtFieldConfig, KtFieldError, KtFieldErrorMatcher, KtFieldErrorMessages, KtFieldErrorState, KtFieldParent, KtFloatLabel, KtKeyish, KtMultiSelectChipContext, KtMultiSelectOptionContext, KtMultiSelectSelectionChange, KtMultiSelectTriggerContext, KtPasswordAutocomplete, KtResolvableError, KtSelectConfigOptions, KtSelectOptionContext, KtSelectSelectionChange, KtSelectTriggerContext, KtSuggestion, KtTextFieldType, KtTimePrecision, LocalDateTime, Timestamp, WallTime, ZonedTimestamp };