@ktortu/aaa 0.9.2 → 0.9.4

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.
@@ -1,7 +1,9 @@
1
1
  import * as i0 from '@angular/core';
2
- import { inject, ElementRef, input, booleanAttribute, DestroyRef, afterNextRender, Directive, ChangeDetectionStrategy, Component, model, contentChildren } from '@angular/core';
2
+ import { InjectionToken, inject, ElementRef, input, booleanAttribute, Directive, ChangeDetectionStrategy, Component, model, contentChildren, forwardRef } from '@angular/core';
3
3
  import { KT_AUDIT_ENABLED, KtIdGenerator } from '@ktortu/aaa/cdk';
4
4
 
5
+ const KT_DISCLOSURE = new InjectionToken('KT_DISCLOSURE');
6
+
5
7
  /**
6
8
  * Déclencheur d'un [ktDisclosure] : posé sur un **vrai `<button>`** (clavier Entrée/Espace
7
9
  * gratuit). Câble `(click)` → `toggle()` et reflète l'état via `aria-expanded` / `aria-controls`
@@ -19,34 +21,28 @@ import { KT_AUDIT_ENABLED, KtIdGenerator } from '@ktortu/aaa/cdk';
19
21
  * ```
20
22
  */
21
23
  class KtDisclosureToggle {
22
- disclosure = inject(KtDisclosure);
24
+ disclosure = inject(KT_DISCLOSURE);
23
25
  host = inject(ElementRef).nativeElement;
24
26
  auditEnabled = inject(KT_AUDIT_ENABLED);
25
- isDestroyed = false;
26
27
  /** Affiche le chevron décoratif (qui pivote selon l'état). @default true */
27
28
  chevron = input(true, { ...(ngDevMode ? { debugName: "chevron" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
28
29
  constructor() {
29
- inject(DestroyRef).onDestroy(() => {
30
- this.isDestroyed = true;
31
- });
32
30
  // `type="button"` SI ABSENT (comme @angular/aria) : un attribut statique de host ne surchargerait
33
31
  // pas un `type` posé dans le template, donc on le force impérativement à la construction.
34
32
  if (!this.host.hasAttribute('type')) {
35
33
  this.host.setAttribute('type', 'button');
36
34
  }
37
- afterNextRender(() => {
38
- if (this.isDestroyed)
39
- return;
40
- if (!this.auditEnabled)
41
- return;
42
- const hasName = !!this.host.textContent?.trim() ||
43
- !!this.host.getAttribute('aria-label')?.trim() ||
44
- this.host.hasAttribute('aria-labelledby');
45
- if (!hasName) {
46
- console.warn('[ktDisclosureToggle] bouton sans nom accessible : ajoutez du texte visible, ' +
47
- '[attr.aria-label] ou aria-labelledby (WCAG 4.1.2).');
48
- }
49
- });
35
+ }
36
+ ngAfterViewInit() {
37
+ if (!this.auditEnabled)
38
+ return;
39
+ const hasName = !!this.host.textContent?.trim() ||
40
+ !!this.host.getAttribute('aria-label')?.trim() ||
41
+ this.host.hasAttribute('aria-labelledby');
42
+ if (!hasName) {
43
+ console.warn('[ktDisclosureToggle] bouton sans nom accessible : ajoutez du texte visible, ' +
44
+ '[attr.aria-label] ou aria-labelledby (WCAG 4.1.2).');
45
+ }
50
46
  }
51
47
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.1", ngImport: i0, type: KtDisclosureToggle, deps: [], target: i0.ɵɵFactoryTarget.Directive });
52
48
  static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.0.1", type: KtDisclosureToggle, isStandalone: true, selector: "button[ktDisclosureToggle]", inputs: { chevron: { classPropertyName: "chevron", publicName: "chevron", isSignal: true, isRequired: false, transformFunction: null } }, host: { listeners: { "click": "disclosure.toggle()" }, properties: { "attr.aria-expanded": "disclosure.expanded()", "attr.aria-controls": "disclosure.contentId", "class.kt-disclosure-toggle--chevron": "chevron()" } }, ngImport: i0 });
@@ -67,7 +63,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.1", ngImpor
67
63
  /**
68
64
  * Panneau repliable d'un [ktDisclosure]. **Composant** (et non directive) car l'animation grid
69
65
  * `0fr ↔ 1fr` exige un **unique enfant `overflow:hidden`** autour du contenu projeté — ce wrapper
70
- * (`.kt-disclosure-content__inner`) est fourni par le template, le consommateur reste libre d'y
66
+ * (`.kt-disclosure-content__inner`) est fourni by le template, le consommateur reste libre d'y
71
67
  * mettre autant de blocs qu'il veut.
72
68
  *
73
69
  * Porte l'`id` (cible de `aria-controls`) et passe **`inert`** quand c'est fermé : le contenu
@@ -83,7 +79,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.1", ngImpor
83
79
  * ```
84
80
  */
85
81
  class KtDisclosureContent {
86
- disclosure = inject(KtDisclosure);
82
+ disclosure = inject(KT_DISCLOSURE);
87
83
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.1", ngImport: i0, type: KtDisclosureContent, deps: [], target: i0.ɵɵFactoryTarget.Component });
88
84
  static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.0.1", type: KtDisclosureContent, isStandalone: true, selector: "kt-disclosure-content", host: { properties: { "id": "disclosure.contentId", "attr.inert": "!disclosure.expanded() ? \"\" : null", "attr.data-expanded": "disclosure.expanded()" } }, ngImport: i0, template: '<div class="kt-disclosure-content__inner"><ng-content /></div>', isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush });
89
85
  }
@@ -128,7 +124,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.1", ngImpor
128
124
  class KtDisclosure {
129
125
  idGen = inject(KtIdGenerator);
130
126
  host = inject(ElementRef).nativeElement;
131
- isDestroyed = false;
132
127
  /** Identifiant stable du panneau contrôlé : cible de l'`aria-controls` du déclencheur. */
133
128
  contentId = `kt-disclosure-content-${this.idGen.generateId('disclosure')}`;
134
129
  /**
@@ -140,26 +135,18 @@ class KtDisclosure {
140
135
  expanded = model(false, /* @ts-ignore */
141
136
  ...(ngDevMode ? [{ debugName: "expanded" }] : /* istanbul ignore next */ []));
142
137
  auditEnabled = inject(KT_AUDIT_ENABLED);
143
- toggles = contentChildren(KtDisclosureToggle, { ...(ngDevMode ? { debugName: "toggles" } : /* istanbul ignore next */ {}), descendants: true });
144
- contents = contentChildren(KtDisclosureContent, { ...(ngDevMode ? { debugName: "contents" } : /* istanbul ignore next */ {}), descendants: true });
145
- constructor() {
146
- inject(DestroyRef).onDestroy(() => {
147
- this.isDestroyed = true;
148
- });
149
- // Garde-fou dev : un disclosure = UN toggle + UN panneau.
150
- afterNextRender(() => {
151
- if (this.isDestroyed)
152
- return;
153
- if (!this.auditEnabled)
154
- return;
155
- const myToggles = this.toggles().filter((t) => t.disclosure === this);
156
- const myContents = this.contents().filter((c) => c.disclosure === this);
157
- if (myToggles.length > 1 || myContents.length > 1) {
158
- console.warn('[ktDisclosure] attend UN seul [ktDisclosureToggle] et UN seul <kt-disclosure-content> par ' +
159
- 'hôte (id de panneau unique / aria-controls non ambigu). Pour plusieurs volets, utilisez ' +
160
- 'plusieurs [ktDisclosure].');
161
- }
162
- });
138
+ toggles = contentChildren(forwardRef(() => KtDisclosureToggle), { ...(ngDevMode ? { debugName: "toggles" } : /* istanbul ignore next */ {}), descendants: true });
139
+ contents = contentChildren(forwardRef(() => KtDisclosureContent), { ...(ngDevMode ? { debugName: "contents" } : /* istanbul ignore next */ {}), descendants: true });
140
+ ngAfterContentInit() {
141
+ if (!this.auditEnabled)
142
+ return;
143
+ const myToggles = this.toggles().filter((t) => t.disclosure === this);
144
+ const myContents = this.contents().filter((c) => c.disclosure === this);
145
+ if (myToggles.length > 1 || myContents.length > 1) {
146
+ console.warn('[ktDisclosure] attend UN seul [ktDisclosureToggle] et UN seul <kt-disclosure-content> par ' +
147
+ 'hôte (id de panneau unique / aria-controls non ambigu). Pour plusieurs volets, utilisez ' +
148
+ 'plusieurs [ktDisclosure].');
149
+ }
163
150
  }
164
151
  /** Bascule l'état. */
165
152
  toggle() {
@@ -174,7 +161,12 @@ class KtDisclosure {
174
161
  this.expanded.set(false);
175
162
  }
176
163
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.1", ngImport: i0, type: KtDisclosure, deps: [], target: i0.ɵɵFactoryTarget.Directive });
177
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.2.0", version: "22.0.1", type: KtDisclosure, isStandalone: true, selector: "[ktDisclosure]", inputs: { expanded: { classPropertyName: "expanded", publicName: "expanded", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { expanded: "expandedChange" }, host: { properties: { "attr.data-expanded": "expanded()" } }, queries: [{ propertyName: "toggles", predicate: KtDisclosureToggle, descendants: true, isSignal: true }, { propertyName: "contents", predicate: KtDisclosureContent, descendants: true, isSignal: true }], exportAs: ["ktDisclosure"], ngImport: i0 });
164
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.2.0", version: "22.0.1", type: KtDisclosure, isStandalone: true, selector: "[ktDisclosure]", inputs: { expanded: { classPropertyName: "expanded", publicName: "expanded", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { expanded: "expandedChange" }, host: { properties: { "attr.data-expanded": "expanded()" } }, providers: [
165
+ {
166
+ provide: KT_DISCLOSURE,
167
+ useExisting: forwardRef(() => KtDisclosure),
168
+ },
169
+ ], queries: [{ propertyName: "toggles", predicate: i0.forwardRef(() => KtDisclosureToggle), descendants: true, isSignal: true }, { propertyName: "contents", predicate: i0.forwardRef(() => KtDisclosureContent), descendants: true, isSignal: true }], exportAs: ["ktDisclosure"], ngImport: i0 });
178
170
  }
179
171
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.1", ngImport: i0, type: KtDisclosure, decorators: [{
180
172
  type: Directive,
@@ -184,8 +176,18 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.1", ngImpor
184
176
  host: {
185
177
  '[attr.data-expanded]': 'expanded()',
186
178
  },
179
+ providers: [
180
+ {
181
+ provide: KT_DISCLOSURE,
182
+ useExisting: forwardRef(() => KtDisclosure),
183
+ },
184
+ ],
187
185
  }]
188
- }], ctorParameters: () => [], propDecorators: { expanded: [{ type: i0.Input, args: [{ isSignal: true, alias: "expanded", required: false }] }, { type: i0.Output, args: ["expandedChange"] }], toggles: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => KtDisclosureToggle), { ...{ descendants: true }, isSignal: true }] }], contents: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => KtDisclosureContent), { ...{ descendants: true }, isSignal: true }] }] } });
186
+ }], propDecorators: { expanded: [{ type: i0.Input, args: [{ isSignal: true, alias: "expanded", required: false }] }, { type: i0.Output, args: ["expandedChange"] }], toggles: [{ type: i0.ContentChildren, args: [forwardRef(() => KtDisclosureToggle), { ...{
187
+ descendants: true,
188
+ }, isSignal: true }] }], contents: [{ type: i0.ContentChildren, args: [forwardRef(() => KtDisclosureContent), { ...{
189
+ descendants: true,
190
+ }, isSignal: true }] }] } });
189
191
 
190
192
  /**
191
193
  * Import ergonomique de toute la famille disclosure en une fois :
@@ -197,5 +199,5 @@ const KtDisclosureImports = [KtDisclosure, KtDisclosureToggle, KtDisclosureConte
197
199
  * Generated bundle index. Do not edit.
198
200
  */
199
201
 
200
- export { KtDisclosure, KtDisclosureContent, KtDisclosureImports, KtDisclosureToggle };
202
+ export { KT_DISCLOSURE, KtDisclosure, KtDisclosureContent, KtDisclosureImports, KtDisclosureToggle };
201
203
  //# sourceMappingURL=ktortu-aaa-disclosure.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"ktortu-aaa-disclosure.mjs","sources":["../../../../projects/ktortu/aaa/disclosure/disclosure-toggle.ts","../../../../projects/ktortu/aaa/disclosure/disclosure-content.ts","../../../../projects/ktortu/aaa/disclosure/disclosure.ts","../../../../projects/ktortu/aaa/disclosure/public-api.ts","../../../../projects/ktortu/aaa/disclosure/ktortu-aaa-disclosure.ts"],"sourcesContent":["import { DestroyRef, Directive, ElementRef, afterNextRender, booleanAttribute, inject, input } from '@angular/core';\nimport { KT_AUDIT_ENABLED } from '@ktortu/aaa/cdk';\nimport { KtDisclosure } from './disclosure';\n\n/**\n * Déclencheur d'un [ktDisclosure] : posé sur un **vrai `<button>`** (clavier Entrée/Espace\n * gratuit). Câble `(click)` → `toggle()` et reflète l'état via `aria-expanded` / `aria-controls`\n * (cf. ADR-0004). `type=\"button\"` est posé **s'il est absent** (ne pas soumettre un formulaire,\n * sans écraser un `type` explicite du consommateur).\n *\n * Le contenu du bouton appartient au consommateur (texte, icône, libellé piloté par `expanded()`). Un\n * **chevron** décoratif (qui pivote selon l'état) est affiché par défaut ; le désactiver avec\n * `[chevron]=\"false\"`. La directive applique elle-même la classe de style — rien à écrire.\n *\n * @example\n * ```html\n * <button ktDisclosureToggle>Détails</button> <!-- avec chevron -->\n * <button ktDisclosureToggle [chevron]=\"false\">Détails</button> <!-- sans chevron -->\n * ```\n */\n@Directive({\n selector: 'button[ktDisclosureToggle]',\n host: {\n '[attr.aria-expanded]': 'disclosure.expanded()',\n '[attr.aria-controls]': 'disclosure.contentId',\n '[class.kt-disclosure-toggle--chevron]': 'chevron()',\n '(click)': 'disclosure.toggle()',\n },\n})\nexport class KtDisclosureToggle {\n readonly disclosure = inject(KtDisclosure);\n private readonly host = inject<ElementRef<HTMLElement>>(ElementRef).nativeElement;\n private readonly auditEnabled = inject(KT_AUDIT_ENABLED);\n private isDestroyed = false;\n\n /** Affiche le chevron décoratif (qui pivote selon l'état). @default true */\n readonly chevron = input(true, { transform: booleanAttribute });\n\n constructor() {\n inject(DestroyRef).onDestroy(() => {\n this.isDestroyed = true;\n });\n\n // `type=\"button\"` SI ABSENT (comme @angular/aria) : un attribut statique de host ne surchargerait\n // pas un `type` posé dans le template, donc on le force impérativement à la construction.\n if (!this.host.hasAttribute('type')) {\n this.host.setAttribute('type', 'button');\n }\n\n afterNextRender(() => {\n if (this.isDestroyed) return;\n if (!this.auditEnabled) return;\n\n const hasName =\n !!this.host.textContent?.trim() ||\n !!this.host.getAttribute('aria-label')?.trim() ||\n this.host.hasAttribute('aria-labelledby');\n if (!hasName) {\n console.warn(\n '[ktDisclosureToggle] bouton sans nom accessible : ajoutez du texte visible, ' +\n '[attr.aria-label] ou aria-labelledby (WCAG 4.1.2).',\n );\n }\n });\n }\n}\n","import { ChangeDetectionStrategy, Component, inject } from '@angular/core';\nimport { KtDisclosure } from './disclosure';\n\n/**\n * Panneau repliable d'un [ktDisclosure]. **Composant** (et non directive) car l'animation grid\n * `0fr ↔ 1fr` exige un **unique enfant `overflow:hidden`** autour du contenu projeté — ce wrapper\n * (`.kt-disclosure-content__inner`) est fourni par le template, le consommateur reste libre d'y\n * mettre autant de blocs qu'il veut.\n *\n * Porte l'`id` (cible de `aria-controls`) et passe **`inert`** quand c'est fermé : le contenu\n * masqué sort de l'ordre de tabulation et de l'arbre d'accessibilité (jamais de focus dans\n * l'invisible). Pas de `role=region` (anti-pollution du rotor de régions). Cf. ADR-0004.\n *\n * @example\n * ```html\n * <kt-disclosure-content>\n * <p>Premier bloc</p>\n * <p>Second bloc…</p>\n * </kt-disclosure-content>\n * ```\n */\n@Component({\n selector: 'kt-disclosure-content',\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: '<div class=\"kt-disclosure-content__inner\"><ng-content /></div>',\n host: {\n '[id]': 'disclosure.contentId',\n '[attr.inert]': '!disclosure.expanded() ? \"\" : null',\n '[attr.data-expanded]': 'disclosure.expanded()',\n },\n})\nexport class KtDisclosureContent {\n readonly disclosure = inject(KtDisclosure);\n}\n","import { DestroyRef, Directive, ElementRef, afterNextRender, contentChildren, inject, model } from '@angular/core';\nimport { KT_AUDIT_ENABLED, KtIdGenerator } from '@ktortu/aaa/cdk';\nimport { KtDisclosureToggle } from './disclosure-toggle';\nimport { KtDisclosureContent } from './disclosure-content';\n\n/**\n * Disclosure : replie/déplie un **bloc d'interface** (volet d'options, module de dashboard,\n * section d'une fiche produit). Directive HÔTE d'une famille à trois marqueurs — elle possède\n * l'état, génère l'`id` du panneau et expose des méthodes impératives ; le câblage ARIA et\n * l'animation vivent sur `[ktDisclosureToggle]` / `<kt-disclosure-content>`.\n *\n * Pour une **section de contenu** de page (façon Wikipédia / FAQ), préférer `<details>` natif\n * (sémantique, find-in-page, SEO, zéro JS) — cf. ADR-0004.\n *\n * L'état est exposé via `exportAs: 'ktDisclosure'` : lisez `expanded()` pour piloter le template\n * (ex. libellé « Voir plus / Voir moins ») sans input de libellé (i18n côté consommateur,\n * cf. ADR-0003).\n *\n * Contrat : **un** `[ktDisclosureToggle]` et **un** `<kt-disclosure-content>` par hôte (id de\n * panneau unique / `aria-controls` non ambigu) ; un avertissement dev le signale sinon.\n *\n * @example\n * ```html\n * <div ktDisclosure #d=\"ktDisclosure\">\n * <button ktDisclosureToggle>{{ d.expanded() ? 'Voir moins' : 'Voir plus' }}</button>\n * <kt-disclosure-content><p>Mon contenu</p></kt-disclosure-content>\n * </div>\n * ```\n */\n@Directive({\n selector: '[ktDisclosure]',\n exportAs: 'ktDisclosure',\n host: {\n '[attr.data-expanded]': 'expanded()',\n },\n})\nexport class KtDisclosure {\n private readonly idGen = inject(KtIdGenerator);\n private readonly host = inject<ElementRef<HTMLElement>>(ElementRef).nativeElement;\n private isDestroyed = false;\n\n /** Identifiant stable du panneau contrôlé : cible de l'`aria-controls` du déclencheur. */\n readonly contentId = `kt-disclosure-content-${this.idGen.generateId('disclosure')}`;\n\n /**\n * État ouvert/fermé. **Toujours utilisé en binding** (`[(expanded)]` / `[expanded]`), jamais en\n * attribut nu : un `model()` n'accepte pas de `booleanAttribute`, donc `<div ktDisclosure expanded>`\n * pousserait la chaîne `''` au lieu de `true`. En binding, la valeur est garantie booléenne.\n * @default false\n */\n readonly expanded = model<boolean>(false);\n\n private readonly auditEnabled = inject(KT_AUDIT_ENABLED);\n\n readonly toggles = contentChildren(KtDisclosureToggle, { descendants: true });\n readonly contents = contentChildren(KtDisclosureContent, { descendants: true });\n\n constructor() {\n inject(DestroyRef).onDestroy(() => {\n this.isDestroyed = true;\n });\n\n // Garde-fou dev : un disclosure = UN toggle + UN panneau.\n afterNextRender(() => {\n if (this.isDestroyed) return;\n if (!this.auditEnabled) return;\n const myToggles = this.toggles().filter((t) => t.disclosure === this);\n const myContents = this.contents().filter((c) => c.disclosure === this);\n if (myToggles.length > 1 || myContents.length > 1) {\n console.warn(\n '[ktDisclosure] attend UN seul [ktDisclosureToggle] et UN seul <kt-disclosure-content> par ' +\n 'hôte (id de panneau unique / aria-controls non ambigu). Pour plusieurs volets, utilisez ' +\n 'plusieurs [ktDisclosure].',\n );\n }\n });\n }\n\n /** Bascule l'état. */\n toggle(): void {\n this.expanded.set(!this.expanded());\n }\n\n /** Ouvre le panneau. */\n expand(): void {\n this.expanded.set(true);\n }\n\n /** Ferme le panneau. */\n collapse(): void {\n this.expanded.set(false);\n }\n}\n","import { KtDisclosure } from './disclosure';\nimport { KtDisclosureContent } from './disclosure-content';\nimport { KtDisclosureToggle } from './disclosure-toggle';\n\nexport * from './disclosure';\nexport * from './disclosure-toggle';\nexport * from './disclosure-content';\n\n/**\n * Import ergonomique de toute la famille disclosure en une fois :\n * `imports: [KtDisclosureImports]` au lieu d'énumérer chaque marqueur.\n */\nexport const KtDisclosureImports = [KtDisclosure, KtDisclosureToggle, KtDisclosureContent] as const;\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ktortu-aaa-disclosure.mjs","sources":["../../../../projects/ktortu/aaa/disclosure/disclosure-token.ts","../../../../projects/ktortu/aaa/disclosure/disclosure-toggle.ts","../../../../projects/ktortu/aaa/disclosure/disclosure-content.ts","../../../../projects/ktortu/aaa/disclosure/disclosure.ts","../../../../projects/ktortu/aaa/disclosure/public-api.ts","../../../../projects/ktortu/aaa/disclosure/ktortu-aaa-disclosure.ts"],"sourcesContent":["import { InjectionToken } from '@angular/core';\n\nexport interface KtDisclosureInterface {\n readonly contentId: string;\n readonly expanded: () => boolean;\n toggle(): void;\n}\n\nexport const KT_DISCLOSURE = new InjectionToken<KtDisclosureInterface>('KT_DISCLOSURE');\n","import { AfterViewInit, Directive, ElementRef, booleanAttribute, inject, input } from '@angular/core';\nimport { KT_AUDIT_ENABLED } from '@ktortu/aaa/cdk';\nimport { KT_DISCLOSURE } from './disclosure-token';\n\n/**\n * Déclencheur d'un [ktDisclosure] : posé sur un **vrai `<button>`** (clavier Entrée/Espace\n * gratuit). Câble `(click)` → `toggle()` et reflète l'état via `aria-expanded` / `aria-controls`\n * (cf. ADR-0004). `type=\"button\"` est posé **s'il est absent** (ne pas soumettre un formulaire,\n * sans écraser un `type` explicite du consommateur).\n *\n * Le contenu du bouton appartient au consommateur (texte, icône, libellé piloté par `expanded()`). Un\n * **chevron** décoratif (qui pivote selon l'état) est affiché par défaut ; le désactiver avec\n * `[chevron]=\"false\"`. La directive applique elle-même la classe de style — rien à écrire.\n *\n * @example\n * ```html\n * <button ktDisclosureToggle>Détails</button> <!-- avec chevron -->\n * <button ktDisclosureToggle [chevron]=\"false\">Détails</button> <!-- sans chevron -->\n * ```\n */\n@Directive({\n selector: 'button[ktDisclosureToggle]',\n host: {\n '[attr.aria-expanded]': 'disclosure.expanded()',\n '[attr.aria-controls]': 'disclosure.contentId',\n '[class.kt-disclosure-toggle--chevron]': 'chevron()',\n '(click)': 'disclosure.toggle()',\n },\n})\nexport class KtDisclosureToggle implements AfterViewInit {\n readonly disclosure = inject(KT_DISCLOSURE);\n private readonly host = inject<ElementRef<HTMLElement>>(ElementRef).nativeElement;\n private readonly auditEnabled = inject(KT_AUDIT_ENABLED);\n\n /** Affiche le chevron décoratif (qui pivote selon l'état). @default true */\n readonly chevron = input(true, { transform: booleanAttribute });\n\n constructor() {\n // `type=\"button\"` SI ABSENT (comme @angular/aria) : un attribut statique de host ne surchargerait\n // pas un `type` posé dans le template, donc on le force impérativement à la construction.\n if (!this.host.hasAttribute('type')) {\n this.host.setAttribute('type', 'button');\n }\n }\n\n ngAfterViewInit(): void {\n if (!this.auditEnabled) return;\n\n const hasName =\n !!this.host.textContent?.trim() ||\n !!this.host.getAttribute('aria-label')?.trim() ||\n this.host.hasAttribute('aria-labelledby');\n if (!hasName) {\n console.warn(\n '[ktDisclosureToggle] bouton sans nom accessible : ajoutez du texte visible, ' +\n '[attr.aria-label] ou aria-labelledby (WCAG 4.1.2).',\n );\n }\n }\n}\n","import { ChangeDetectionStrategy, Component, inject } from '@angular/core';\nimport { KT_DISCLOSURE } from './disclosure-token';\n\n/**\n * Panneau repliable d'un [ktDisclosure]. **Composant** (et non directive) car l'animation grid\n * `0fr ↔ 1fr` exige un **unique enfant `overflow:hidden`** autour du contenu projeté — ce wrapper\n * (`.kt-disclosure-content__inner`) est fourni by le template, le consommateur reste libre d'y\n * mettre autant de blocs qu'il veut.\n *\n * Porte l'`id` (cible de `aria-controls`) et passe **`inert`** quand c'est fermé : le contenu\n * masqué sort de l'ordre de tabulation et de l'arbre d'accessibilité (jamais de focus dans\n * l'invisible). Pas de `role=region` (anti-pollution du rotor de régions). Cf. ADR-0004.\n *\n * @example\n * ```html\n * <kt-disclosure-content>\n * <p>Premier bloc</p>\n * <p>Second bloc…</p>\n * </kt-disclosure-content>\n * ```\n */\n@Component({\n selector: 'kt-disclosure-content',\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: '<div class=\"kt-disclosure-content__inner\"><ng-content /></div>',\n host: {\n '[id]': 'disclosure.contentId',\n '[attr.inert]': '!disclosure.expanded() ? \"\" : null',\n '[attr.data-expanded]': 'disclosure.expanded()',\n },\n})\nexport class KtDisclosureContent {\n readonly disclosure = inject(KT_DISCLOSURE);\n}\n","import { AfterContentInit, Directive, ElementRef, contentChildren, forwardRef, inject, model } from '@angular/core';\nimport { KT_AUDIT_ENABLED, KtIdGenerator } from '@ktortu/aaa/cdk';\nimport { KT_DISCLOSURE } from './disclosure-token';\nimport { KtDisclosureToggle } from './disclosure-toggle';\nimport { KtDisclosureContent } from './disclosure-content';\n\n/**\n * Disclosure : replie/déplie un **bloc d'interface** (volet d'options, module de dashboard,\n * section d'une fiche produit). Directive HÔTE d'une famille à trois marqueurs — elle possède\n * l'état, génère l'`id` du panneau et expose des méthodes impératives ; le câblage ARIA et\n * l'animation vivent sur `[ktDisclosureToggle]` / `<kt-disclosure-content>`.\n *\n * Pour une **section de contenu** de page (façon Wikipédia / FAQ), préférer `<details>` natif\n * (sémantique, find-in-page, SEO, zéro JS) — cf. ADR-0004.\n *\n * L'état est exposé via `exportAs: 'ktDisclosure'` : lisez `expanded()` pour piloter le template\n * (ex. libellé « Voir plus / Voir moins ») sans input de libellé (i18n côté consommateur,\n * cf. ADR-0003).\n *\n * Contrat : **un** `[ktDisclosureToggle]` et **un** `<kt-disclosure-content>` par hôte (id de\n * panneau unique / `aria-controls` non ambigu) ; un avertissement dev le signale sinon.\n *\n * @example\n * ```html\n * <div ktDisclosure #d=\"ktDisclosure\">\n * <button ktDisclosureToggle>{{ d.expanded() ? 'Voir moins' : 'Voir plus' }}</button>\n * <kt-disclosure-content><p>Mon contenu</p></kt-disclosure-content>\n * </div>\n * ```\n */\n@Directive({\n selector: '[ktDisclosure]',\n exportAs: 'ktDisclosure',\n host: {\n '[attr.data-expanded]': 'expanded()',\n },\n providers: [\n {\n provide: KT_DISCLOSURE,\n useExisting: forwardRef(() => KtDisclosure),\n },\n ],\n})\nexport class KtDisclosure implements AfterContentInit {\n private readonly idGen = inject(KtIdGenerator);\n private readonly host = inject<ElementRef<HTMLElement>>(ElementRef).nativeElement;\n\n /** Identifiant stable du panneau contrôlé : cible de l'`aria-controls` du déclencheur. */\n readonly contentId = `kt-disclosure-content-${this.idGen.generateId('disclosure')}`;\n\n /**\n * État ouvert/fermé. **Toujours utilisé en binding** (`[(expanded)]` / `[expanded]`), jamais en\n * attribut nu : un `model()` n'accepte pas de `booleanAttribute`, donc `<div ktDisclosure expanded>`\n * pousserait la chaîne `''` au lieu de `true`. En binding, la valeur est garantie booléenne.\n * @default false\n */\n readonly expanded = model<boolean>(false);\n\n private readonly auditEnabled = inject(KT_AUDIT_ENABLED);\n\n readonly toggles = contentChildren<KtDisclosureToggle>(\n forwardRef(() => KtDisclosureToggle),\n {\n descendants: true,\n },\n );\n readonly contents = contentChildren<KtDisclosureContent>(\n forwardRef(() => KtDisclosureContent),\n {\n descendants: true,\n },\n );\n\n ngAfterContentInit(): void {\n if (!this.auditEnabled) return;\n const myToggles = this.toggles().filter((t) => t.disclosure === this);\n const myContents = this.contents().filter((c) => c.disclosure === this);\n if (myToggles.length > 1 || myContents.length > 1) {\n console.warn(\n '[ktDisclosure] attend UN seul [ktDisclosureToggle] et UN seul <kt-disclosure-content> par ' +\n 'hôte (id de panneau unique / aria-controls non ambigu). Pour plusieurs volets, utilisez ' +\n 'plusieurs [ktDisclosure].',\n );\n }\n }\n\n /** Bascule l'état. */\n toggle(): void {\n this.expanded.set(!this.expanded());\n }\n\n /** Ouvre le panneau. */\n expand(): void {\n this.expanded.set(true);\n }\n\n /** Ferme le panneau. */\n collapse(): void {\n this.expanded.set(false);\n }\n}\n","import { KtDisclosure } from './disclosure';\nimport { KtDisclosureContent } from './disclosure-content';\nimport { KtDisclosureToggle } from './disclosure-toggle';\n\nexport * from './disclosure';\nexport * from './disclosure-toggle';\nexport * from './disclosure-content';\nexport * from './disclosure-token';\n\n/**\n * Import ergonomique de toute la famille disclosure en une fois :\n * `imports: [KtDisclosureImports]` au lieu d'énumérer chaque marqueur.\n */\nexport const KtDisclosureImports = [KtDisclosure, KtDisclosureToggle, KtDisclosureContent] as const;\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":";;;;MAQa,aAAa,GAAG,IAAI,cAAc,CAAwB,eAAe;;ACJtF;;;;;;;;;;;;;;;AAeG;MAUU,kBAAkB,CAAA;AACpB,IAAA,UAAU,GAAG,MAAM,CAAC,aAAa,CAAC;AAC1B,IAAA,IAAI,GAAG,MAAM,CAA0B,UAAU,CAAC,CAAC,aAAa;AAChE,IAAA,YAAY,GAAG,MAAM,CAAC,gBAAgB,CAAC;;IAG/C,OAAO,GAAG,KAAK,CAAC,IAAI,+EAAI,SAAS,EAAE,gBAAgB,EAAA,CAAG;AAE/D,IAAA,WAAA,GAAA;;;QAGE,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,EAAE;YACnC,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,QAAQ,CAAC;QAC1C;IACF;IAEA,eAAe,GAAA;QACb,IAAI,CAAC,IAAI,CAAC,YAAY;YAAE;QAExB,MAAM,OAAO,GACX,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,IAAI,EAAE;YAC/B,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,YAAY,CAAC,EAAE,IAAI,EAAE;AAC9C,YAAA,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,iBAAiB,CAAC;QAC3C,IAAI,CAAC,OAAO,EAAE;YACZ,OAAO,CAAC,IAAI,CACV,8EAA8E;AAC5E,gBAAA,oDAAoD,CACvD;QACH;IACF;uGA7BW,kBAAkB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;2FAAlB,kBAAkB,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,4BAAA,EAAA,MAAA,EAAA,EAAA,OAAA,EAAA,EAAA,iBAAA,EAAA,SAAA,EAAA,UAAA,EAAA,SAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,EAAA,IAAA,EAAA,EAAA,SAAA,EAAA,EAAA,OAAA,EAAA,qBAAA,EAAA,EAAA,UAAA,EAAA,EAAA,oBAAA,EAAA,uBAAA,EAAA,oBAAA,EAAA,sBAAA,EAAA,qCAAA,EAAA,WAAA,EAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,CAAA;;2FAAlB,kBAAkB,EAAA,UAAA,EAAA,CAAA;kBAT9B,SAAS;AAAC,YAAA,IAAA,EAAA,CAAA;AACT,oBAAA,QAAQ,EAAE,4BAA4B;AACtC,oBAAA,IAAI,EAAE;AACJ,wBAAA,sBAAsB,EAAE,uBAAuB;AAC/C,wBAAA,sBAAsB,EAAE,sBAAsB;AAC9C,wBAAA,uCAAuC,EAAE,WAAW;AACpD,wBAAA,SAAS,EAAE,qBAAqB;AACjC,qBAAA;AACF,iBAAA;;;ACzBD;;;;;;;;;;;;;;;;;AAiBG;MAWU,mBAAmB,CAAA;AACrB,IAAA,UAAU,GAAG,MAAM,CAAC,aAAa,CAAC;uGADhC,mBAAmB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAAnB,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,mBAAmB,8OAPpB,gEAAgE,EAAA,QAAA,EAAA,IAAA,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,MAAA,EAAA,CAAA;;2FAO/D,mBAAmB,EAAA,UAAA,EAAA,CAAA;kBAV/B,SAAS;AAAC,YAAA,IAAA,EAAA,CAAA;AACT,oBAAA,QAAQ,EAAE,uBAAuB;oBACjC,eAAe,EAAE,uBAAuB,CAAC,MAAM;AAC/C,oBAAA,QAAQ,EAAE,gEAAgE;AAC1E,oBAAA,IAAI,EAAE;AACJ,wBAAA,MAAM,EAAE,sBAAsB;AAC9B,wBAAA,cAAc,EAAE,oCAAoC;AACpD,wBAAA,sBAAsB,EAAE,uBAAuB;AAChD,qBAAA;AACF,iBAAA;;;ACxBD;;;;;;;;;;;;;;;;;;;;;;;AAuBG;MAcU,YAAY,CAAA;AACN,IAAA,KAAK,GAAG,MAAM,CAAC,aAAa,CAAC;AAC7B,IAAA,IAAI,GAAG,MAAM,CAA0B,UAAU,CAAC,CAAC,aAAa;;IAGxE,SAAS,GAAG,CAAA,sBAAA,EAAyB,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,YAAY,CAAC,CAAA,CAAE;AAEnF;;;;;AAKG;IACM,QAAQ,GAAG,KAAK,CAAU,KAAK;iFAAC;AAExB,IAAA,YAAY,GAAG,MAAM,CAAC,gBAAgB,CAAC;AAE/C,IAAA,OAAO,GAAG,eAAe,CAChC,UAAU,CAAC,MAAM,kBAAkB,CAAC,EAAA,EAAA,IAAA,SAAA,GAAA,EAAA,SAAA,EAAA,SAAA,EAAA,8BAAA,EAAA,CAAA,EAElC,WAAW,EAAE,IAAI,GAEpB;AACQ,IAAA,QAAQ,GAAG,eAAe,CACjC,UAAU,CAAC,MAAM,mBAAmB,CAAC,EAAA,EAAA,IAAA,SAAA,GAAA,EAAA,SAAA,EAAA,UAAA,EAAA,8BAAA,EAAA,CAAA,EAEnC,WAAW,EAAE,IAAI,GAEpB;IAED,kBAAkB,GAAA;QAChB,IAAI,CAAC,IAAI,CAAC,YAAY;YAAE;QACxB,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,UAAU,KAAK,IAAI,CAAC;QACrE,MAAM,UAAU,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,UAAU,KAAK,IAAI,CAAC;AACvE,QAAA,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE;YACjD,OAAO,CAAC,IAAI,CACV,4FAA4F;gBAC1F,0FAA0F;AAC1F,gBAAA,2BAA2B,CAC9B;QACH;IACF;;IAGA,MAAM,GAAA;QACJ,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC;IACrC;;IAGA,MAAM,GAAA;AACJ,QAAA,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC;IACzB;;IAGA,QAAQ,GAAA;AACN,QAAA,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC;IAC1B;uGAxDW,YAAY,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAAZ,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,YAAY,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,gBAAA,EAAA,MAAA,EAAA,EAAA,QAAA,EAAA,EAAA,iBAAA,EAAA,UAAA,EAAA,UAAA,EAAA,UAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,EAAA,OAAA,EAAA,EAAA,QAAA,EAAA,gBAAA,EAAA,EAAA,IAAA,EAAA,EAAA,UAAA,EAAA,EAAA,oBAAA,EAAA,YAAA,EAAA,EAAA,EAAA,SAAA,EAPZ;AACT,YAAA;AACE,gBAAA,OAAO,EAAE,aAAa;AACtB,gBAAA,WAAW,EAAE,UAAU,CAAC,MAAM,YAAY,CAAC;AAC5C,aAAA;SACF,EAAA,OAAA,EAAA,CAAA,EAAA,YAAA,EAAA,SAAA,EAAA,SAAA,EAAA,EAAA,CAAA,UAAA,CAAA,MAoBkB,kBAAkB,mGAMlB,mBAAmB,CAAA,EAAA,WAAA,EAAA,IAAA,EAAA,QAAA,EAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,CAAA,cAAA,CAAA,EAAA,QAAA,EAAA,EAAA,EAAA,CAAA;;2FAxB3B,YAAY,EAAA,UAAA,EAAA,CAAA;kBAbxB,SAAS;AAAC,YAAA,IAAA,EAAA,CAAA;AACT,oBAAA,QAAQ,EAAE,gBAAgB;AAC1B,oBAAA,QAAQ,EAAE,cAAc;AACxB,oBAAA,IAAI,EAAE;AACJ,wBAAA,sBAAsB,EAAE,YAAY;AACrC,qBAAA;AACD,oBAAA,SAAS,EAAE;AACT,wBAAA;AACE,4BAAA,OAAO,EAAE,aAAa;AACtB,4BAAA,WAAW,EAAE,UAAU,CAAC,kBAAkB,CAAC;AAC5C,yBAAA;AACF,qBAAA;AACF,iBAAA;AAmBG,SAAA,CAAA,EAAA,cAAA,EAAA,EAAA,QAAA,EAAA,CAAA,EAAA,IAAA,EAAA,EAAA,CAAA,KAAA,EAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,IAAA,EAAA,KAAA,EAAA,UAAA,EAAA,QAAA,EAAA,KAAA,EAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,EAAA,CAAA,MAAA,EAAA,IAAA,EAAA,CAAA,gBAAA,CAAA,EAAA,CAAA,EAAA,OAAA,EAAA,CAAA,EAAA,IAAA,EAAA,EAAA,CAAA,eAAA,EAAA,IAAA,EAAA,CAAA,UAAU,CAAC,MAAM,kBAAkB,CAAC,EAAA,EAAA,GACpC;AACE,4BAAA,WAAW,EAAE,IAAI;AAClB,yBAAA,EAAA,QAAA,EAAA,IAAA,EAAA,CAAA,EAAA,CAAA,EAAA,QAAA,EAAA,CAAA,EAAA,IAAA,EAAA,EAAA,CAAA,eAAA,EAAA,IAAA,EAAA,CAGD,UAAU,CAAC,MAAM,mBAAmB,CAAC,EAAA,EAAA,GACrC;AACE,4BAAA,WAAW,EAAE,IAAI;AAClB,yBAAA,EAAA,QAAA,EAAA,IAAA,EAAA,CAAA,EAAA,CAAA,EAAA,EAAA,CAAA;;AC7DL;;;AAGG;AACI,MAAM,mBAAmB,GAAG,CAAC,YAAY,EAAE,kBAAkB,EAAE,mBAAmB;;ACbzF;;AAEG;;;;"}
@@ -1321,21 +1321,18 @@ class KtCheckbox {
1321
1321
  effect(() => {
1322
1322
  this.inputEl().nativeElement.indeterminate = this.indeterminate();
1323
1323
  });
1324
+ }
1325
+ ngAfterViewInit() {
1324
1326
  // Garde-fou a11y (navigateur uniquement) : nom accessible = `label`, `ariaLabel` OU contenu
1325
1327
  // projeté. Sans aucun des trois, la case est annoncée vide (WCAG 4.1.2).
1326
- afterNextRender(() => {
1327
- if (this.isDestroyed)
1328
- return;
1329
- if (!this.auditEnabled || this.label() || this.ariaLabel())
1330
- return;
1331
- const labelText = this.el.nativeElement
1332
- .querySelector('.kt-checkbox__label')
1333
- ?.textContent?.replace('*', '')
1334
- .trim();
1335
- if (!labelText) {
1336
- console.warn('[ktCheckbox] sans `label`, `ariaLabel` ni contenu projeté : annoncée sans nom accessible (WCAG 4.1.2).');
1337
- }
1338
- });
1328
+ if (this.isDestroyed)
1329
+ return;
1330
+ if (!this.auditEnabled || this.label() || this.ariaLabel())
1331
+ return;
1332
+ const labelText = this.el.nativeElement.querySelector('.kt-checkbox__label')?.textContent?.replace('*', '').trim();
1333
+ if (!labelText) {
1334
+ console.warn('[ktCheckbox] sans `label`, `ariaLabel` ni contenu projeté : annoncée sans nom accessible (WCAG 4.1.2).');
1335
+ }
1339
1336
  }
1340
1337
  /** Focus la case native (utilisé par Signal Forms `focusBoundControl`). */
1341
1338
  focus(options) {