@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.
- package/dialog/dialog.css +6 -0
- package/disclosure/disclosure-tokens.css +18 -0
- package/disclosure/disclosure.css +84 -0
- package/fesm2022/ktortu-aaa-card.mjs +109 -105
- package/fesm2022/ktortu-aaa-card.mjs.map +1 -1
- package/fesm2022/ktortu-aaa-dialog.mjs +222 -2
- package/fesm2022/ktortu-aaa-dialog.mjs.map +1 -1
- package/fesm2022/ktortu-aaa-disclosure.mjs +47 -45
- package/fesm2022/ktortu-aaa-disclosure.mjs.map +1 -1
- package/fesm2022/ktortu-aaa-forms.mjs +10 -13
- package/fesm2022/ktortu-aaa-forms.mjs.map +1 -1
- package/fesm2022/ktortu-aaa.mjs +1 -0
- package/fesm2022/ktortu-aaa.mjs.map +1 -1
- package/package.json +1 -1
- package/types/ktortu-aaa-card.d.ts +68 -67
- package/types/ktortu-aaa-dialog.d.ts +128 -2
- package/types/ktortu-aaa-disclosure.d.ts +18 -9
- package/types/ktortu-aaa-forms.d.ts +3 -2
- package/types/ktortu-aaa.d.ts +1 -0
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { inject, ElementRef, input, booleanAttribute,
|
|
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(
|
|
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
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
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
|
|
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(
|
|
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
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
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()" } },
|
|
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
|
-
}],
|
|
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":"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"}
|
|
@@ -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
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
|
|
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) {
|