@ktortu/aaa 0.1.0-beta.0 → 0.9.0
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 +23 -7
- package/cdk/styles/tabs.css +100 -21
- package/fesm2022/ktortu-aaa-button.mjs +18 -11
- package/fesm2022/ktortu-aaa-button.mjs.map +1 -1
- package/fesm2022/ktortu-aaa-card.mjs +29 -4
- package/fesm2022/ktortu-aaa-card.mjs.map +1 -1
- package/fesm2022/ktortu-aaa-cdk.mjs +58 -15
- package/fesm2022/ktortu-aaa-cdk.mjs.map +1 -1
- package/fesm2022/ktortu-aaa-dialog.mjs +69 -12
- package/fesm2022/ktortu-aaa-dialog.mjs.map +1 -1
- package/fesm2022/ktortu-aaa-forms.mjs +455 -260
- package/fesm2022/ktortu-aaa-forms.mjs.map +1 -1
- package/fesm2022/ktortu-aaa-i18n.mjs +114 -0
- package/fesm2022/ktortu-aaa-i18n.mjs.map +1 -0
- package/fesm2022/ktortu-aaa-menu.mjs +38 -13
- package/fesm2022/ktortu-aaa-menu.mjs.map +1 -1
- package/fesm2022/ktortu-aaa-tabs.mjs +319 -42
- package/fesm2022/ktortu-aaa-tabs.mjs.map +1 -1
- package/fesm2022/ktortu-aaa-tooltip.mjs +3 -2
- package/fesm2022/ktortu-aaa-tooltip.mjs.map +1 -1
- package/fesm2022/ktortu-aaa.mjs +1 -0
- package/fesm2022/ktortu-aaa.mjs.map +1 -1
- package/forms/radio/radio-group.css +3 -3
- package/forms/styles/field-box.css +150 -2
- package/forms/styles/tokens.css +3 -0
- package/menu/menu.css +8 -4
- package/package.json +5 -1
- package/types/ktortu-aaa-button.d.ts +22 -8
- package/types/ktortu-aaa-card.d.ts +24 -4
- package/types/ktortu-aaa-cdk.d.ts +38 -0
- package/types/ktortu-aaa-dialog.d.ts +45 -9
- package/types/ktortu-aaa-forms.d.ts +336 -149
- package/types/ktortu-aaa-i18n.d.ts +74 -0
- package/types/ktortu-aaa-menu.d.ts +15 -8
- package/types/ktortu-aaa-tabs.d.ts +130 -13
- package/types/ktortu-aaa-tooltip.d.ts +5 -0
- package/types/ktortu-aaa.d.ts +1 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ktortu-aaa-cdk.mjs","sources":["../../../../projects/ktortu/aaa/cdk/sheet/sheet-drag.ts","../../../../projects/ktortu/aaa/cdk/breakpoints/breakpoints.ts","../../../../projects/ktortu/aaa/cdk/breakpoints/viewport.ts","../../../../projects/ktortu/aaa/cdk/id-generator.ts","../../../../projects/ktortu/aaa/cdk/ktortu-aaa-cdk.ts"],"sourcesContent":["/** Contrôleur de drag-to-dismiss d'une bottom-sheet. À câbler sur le `pointerdown` de la poignée. */\nexport interface KtSheetDrag {\n start(event: PointerEvent): void;\n destroy(): void;\n}\n\nexport interface KtSheetDragOptions {\n /** Élément translaté pendant le glissement (la feuille elle-même). Lu à chaque `start`. */\n pane: () => HTMLElement | null;\n /** Fermeture déclenchée quand le seuil est franchi (ex. `expanded.set(false)` / `dialogRef.close()`). */\n onDismiss: () => void;\n /** Classe togglée sur le pane pendant le drag (coupe la transition CSS du glissement). */\n draggingClass: string;\n /** Fraction de la hauteur de la feuille au-delà de laquelle on ferme (défaut 0.25). */\n threshold?: number;\n}\n\n/**\n * Drag-to-dismiss vertical (vers le BAS uniquement) d'une bottom-sheet, factorisé entre le Select\n * (popup Popover) et le Dialog (pane CDK). Chaque appelant ne fournit que SON élément à translater\n * et SON callback de fermeture.\n *\n * Geste DOUBLÉ côté appelant par Échap + bouton Fermer + tap-extérieur (WCAG 2.5.1) : ce module ne\n * gère que le glissement. Le gating « écran compact uniquement » reste à l'appelant (signal `isCompact`\n * de `KtViewport`) — la primitive est volontairement agnostique.\n */\nexport function createKtSheetDrag(opts: KtSheetDragOptions): KtSheetDrag {\n const threshold = opts.threshold ?? 0.25;\n let startY = 0;\n let pane: HTMLElement | null = null;\n let handle: HTMLElement | null = null;\n\n const cleanupListeners = (): void => {\n if (!handle) return;\n handle.removeEventListener('pointermove', onMove);\n handle.removeEventListener('pointerup', onEnd);\n handle.removeEventListener('pointercancel', onEnd);\n handle.removeEventListener('lostpointercapture', onEnd);\n };\n\n const onMove = (event: PointerEvent): void => {\n if (!pane) return;\n const dy = Math.max(0, event.clientY - startY); // on ne tire que vers le bas\n pane.style.translate = `0 ${dy}px`;\n };\n\n const onEnd = (event: PointerEvent): void => {\n if (!pane || !handle) return;\n cleanupListeners();\n pane.classList.remove(opts.draggingClass);\n\n const dragged = event.clientY - startY;\n if (dragged > pane.getBoundingClientRect().height * threshold) {\n pane.style.translate = '0 100%'; // continue le glissement jusqu'en bas, puis ferme\n opts.onDismiss();\n } else {\n pane.style.translate = ''; // snap-back : la transition CSS ramène à 0\n }\n pane = null;\n handle = null;\n };\n\n return {\n start(event: PointerEvent): void {\n if (event.button !== 0) return;\n const el = opts.pane();\n if (!el) return;\n handle = event.currentTarget as HTMLElement;\n // La poignée ne doit PAS voler le focus (sinon un close-on-blur fermerait prématurément).\n event.preventDefault();\n handle.setPointerCapture(event.pointerId);\n startY = event.clientY;\n pane = el;\n pane.classList.add(opts.draggingClass);\n handle.addEventListener('pointermove', onMove);\n handle.addEventListener('pointerup', onEnd);\n handle.addEventListener('pointercancel', onEnd);\n handle.addEventListener('lostpointercapture', onEnd);\n },\n destroy(): void {\n cleanupListeners();\n pane = null;\n handle = null;\n },\n };\n}\n","import { InjectionToken, Provider } from '@angular/core';\n\n/**\n * Valeur d'un palier de breakpoint, CONFIGURABLE PAR APPLICATION :\n * - un **nombre** = largeur (px) à partir de laquelle le palier commence ; la lib en dérive une\n * media query LARGEUR SEULE (bornes calculées par rapport au palier suivant) ;\n * - une **chaîne** = media query complète du palier, utilisée VERBATIM (échappatoire pour un critère\n * non-largeur : `orientation`, `pointer`, ratio…).\n */\nexport type KtBreakpointValue = number | string;\n\n/**\n * Seuils responsive de la lib, surchargeables par appli via `provideKtBreakpoints`. Sémantique\n * « plancher de palier » : chaque valeur indique où le palier COMMENCE → 3 bandes mutuellement\n * exclusives (`mobile` < `tablet` < `desktop`).\n */\nexport interface KtBreakpoints {\n /** Plancher du mobile (typiquement 0). */\n mobile: KtBreakpointValue;\n /** Largeur où commence la tablette (= plafond mobile). */\n tablet: KtBreakpointValue;\n /** Largeur où commence le desktop (= plafond tablette). */\n desktop: KtBreakpointValue;\n}\n\n/** Défauts : bascule bottom-sheet sous 600px (aligné sur l'ancien `MOBILE_QUERY`). */\nexport const KT_DEFAULT_BREAKPOINTS: KtBreakpoints = { mobile: 0, tablet: 600, desktop: 1024 };\n\n/** Token des seuils responsive. Défaut = `KT_DEFAULT_BREAKPOINTS` ; surchargé par `provideKtBreakpoints`. */\nexport const KT_BREAKPOINTS = new InjectionToken<KtBreakpoints>('KT_BREAKPOINTS', {\n providedIn: 'root',\n factory: () => KT_DEFAULT_BREAKPOINTS,\n});\n\n/**\n * À ajouter aux `providers` de `app.config.ts`. Fusionne avec les défauts → surcharge partielle OK.\n * @example provideKtBreakpoints({ tablet: 768, desktop: 1200 })\n * @example provideKtBreakpoints({ tablet: '(min-width: 768px) and (orientation: landscape)' })\n */\nexport function provideKtBreakpoints(overrides: Partial<KtBreakpoints>): Provider {\n return { provide: KT_BREAKPOINTS, useValue: { ...KT_DEFAULT_BREAKPOINTS, ...overrides } };\n}\n\n/** Trois chaînes de media queries résolues, prêtes pour `matchMedia` / `BreakpointObserver`. */\nexport interface KtBreakpointMedia {\n mobile: string;\n tablet: string;\n desktop: string;\n}\n\n/** Évite le chevauchement d'1px entre deux bandes adjacentes (max-width juste sous le plancher suivant). */\nconst EPSILON = 0.02;\n\nfunction minWidth(v: number): string {\n return `(min-width: ${v}px)`;\n}\n\nfunction maxWidth(nextFloor: number): string {\n return `(max-width: ${nextFloor - EPSILON}px)`;\n}\n\n/** `not all` ne matche jamais : repli sûr (= desktop) si une bande numérique se retrouve sans borne. */\nfunction join(...parts: string[]): string {\n return parts.filter(Boolean).join(' and ') || 'not all';\n}\n\n/**\n * Convertit les seuils (nombres et/ou chaînes) en 3 media queries. Un palier-chaîne est repris\n * verbatim ; un palier-nombre devient la bande `[plancher courant .. plancher suivant[`. Si le\n * plancher suivant est une chaîne (pas de borne numérique), la bande reste ouverte de ce côté.\n */\nexport function resolveKtBreakpointMedia(bp: KtBreakpoints): KtBreakpointMedia {\n const { mobile, tablet, desktop } = bp;\n\n return {\n mobile:\n typeof mobile === 'string'\n ? mobile\n : join(mobile > 0 ? minWidth(mobile) : '', typeof tablet === 'number' ? maxWidth(tablet) : ''),\n tablet:\n typeof tablet === 'string'\n ? tablet\n : join(minWidth(tablet), typeof desktop === 'number' ? maxWidth(desktop) : ''),\n desktop: typeof desktop === 'string' ? desktop : minWidth(desktop),\n };\n}\n","import { Injectable, Signal, inject } from '@angular/core';\nimport { toSignal } from '@angular/core/rxjs-interop';\nimport { BreakpointObserver } from '@angular/cdk/layout';\nimport { map } from 'rxjs';\nimport { KT_BREAKPOINTS, resolveKtBreakpointMedia } from './breakpoints';\n\n/**\n * Expose l'état responsive courant en SIGNALS, dérivé des seuils configurés par l'appli\n * (`KT_BREAKPOINTS` / `provideKtBreakpoints`). Fondé sur `BreakpointObserver` (`@angular/cdk/layout`,\n * déjà dépendance) : SSR-safe (`matches: false` côté serveur → desktop par défaut) et nettoyage des\n * listeners géré par le CDK.\n *\n * À injecter aussi bien dans les composants de la lib (bascule bottom-sheet) que dans le code des\n * applis consommatrices pour leur propre layout responsive.\n */\n@Injectable({ providedIn: 'root' })\nexport class KtViewport {\n private readonly observer = inject(BreakpointObserver);\n\n /** Media queries résolues (largeur dérivée ou verbatim selon le token) — utile pour miroir CSS. */\n readonly media = resolveKtBreakpointMedia(inject(KT_BREAKPOINTS));\n\n /** Le viewport est dans la bande mobile. */\n readonly isMobile = this.matches(this.media.mobile);\n /** Le viewport est dans la bande tablette. */\n readonly isTablet = this.matches(this.media.tablet);\n /** Le viewport est dans la bande desktop. */\n readonly isDesktop = this.matches(this.media.desktop);\n /** Alias de `isMobile` : palier où les composants de la lib basculent en bottom-sheet. */\n readonly isCompact = this.isMobile;\n\n private matches(query: string): Signal<boolean> {\n return toSignal(this.observer.observe(query).pipe(map((state) => state.matches)), {\n initialValue: false,\n });\n }\n}\n","import { Injectable } from '@angular/core';\n\n@Injectable({\n providedIn: 'root',\n})\nexport class KtIdGenerator {\n private readonly counters = new Map<string, number>();\n private nextGlobalId = 0;\n\n generateId(prefix?: string): number {\n if (!prefix) {\n return this.nextGlobalId++;\n }\n const current = this.counters.get(prefix) ?? 0;\n this.counters.set(prefix, current + 1);\n return current;\n }\n}\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-cdk.mjs","sources":["../../../../projects/ktortu/aaa/cdk/sheet/sheet-drag.ts","../../../../projects/ktortu/aaa/cdk/breakpoints/breakpoints.ts","../../../../projects/ktortu/aaa/cdk/breakpoints/viewport.ts","../../../../projects/ktortu/aaa/cdk/id-generator.ts","../../../../projects/ktortu/aaa/cdk/ktortu-aaa-cdk.ts"],"sourcesContent":["/** Contrôleur de drag-to-dismiss d'une bottom-sheet. À câbler sur le `pointerdown` de la poignée. */\nexport interface KtSheetDrag {\n /** Démarre le suivi du glissement ; à brancher sur le `pointerdown` de la poignée. */\n start(event: PointerEvent): void;\n /** Détache les écouteurs et réinitialise l'état ; à appeler à la destruction. */\n destroy(): void;\n}\n\nexport interface KtSheetDragOptions {\n /** Élément translaté pendant le glissement (la feuille elle-même). Lu à chaque `start`. */\n pane: () => HTMLElement | null;\n /** Fermeture déclenchée quand le seuil est franchi (ex. `expanded.set(false)` / `dialogRef.close()`). */\n onDismiss: () => void;\n /** Classe togglée sur le pane pendant le drag (coupe la transition CSS du glissement). */\n draggingClass: string;\n /** Fraction de la hauteur de la feuille au-delà de laquelle on ferme (défaut 0.25). */\n threshold?: number;\n}\n\n/**\n * Drag-to-dismiss vertical (vers le BAS uniquement) d'une bottom-sheet, factorisé entre le Select\n * (popup Popover) et le Dialog (pane CDK). Chaque appelant ne fournit que SON élément à translater\n * et SON callback de fermeture.\n *\n * Geste DOUBLÉ côté appelant par Échap + bouton Fermer + tap-extérieur (WCAG 2.5.1) : ce module ne\n * gère que le glissement. Le gating « écran compact uniquement » reste à l'appelant (signal `isCompact`\n * de `KtViewport`) — la primitive est volontairement agnostique.\n *\n * @param opts Élément à translater, callback de fermeture, classe de drag et seuil optionnel.\n * @returns Un contrôleur {@link KtSheetDrag} (`start` à brancher sur `pointerdown`, `destroy` au teardown).\n * @example\n * ```ts\n * const drag = createKtSheetDrag({\n * pane: () => paneEl(),\n * onDismiss: () => dialogRef.close(),\n * draggingClass: 'kt-sheet--dragging',\n * });\n * // <div class=\"handle\" (pointerdown)=\"drag.start($event)\"></div>\n * ```\n */\nexport function createKtSheetDrag(opts: KtSheetDragOptions): KtSheetDrag {\n const threshold = opts.threshold ?? 0.25;\n let startY = 0;\n let pane: HTMLElement | null = null;\n let handle: HTMLElement | null = null;\n let ownerDoc: Document | null = null;\n\n const cleanupListeners = (): void => {\n if (!ownerDoc) return;\n ownerDoc.removeEventListener('pointermove', onMove);\n ownerDoc.removeEventListener('pointerup', onEnd);\n ownerDoc.removeEventListener('pointercancel', onEnd);\n };\n\n const onMove = (event: PointerEvent): void => {\n if (!pane) return;\n const dy = Math.max(0, event.clientY - startY); // on ne tire que vers le bas\n pane.style.translate = `0 ${dy}px`;\n };\n\n const onEnd = (event: PointerEvent): void => {\n if (!pane || !handle) return;\n cleanupListeners();\n\n const dragged = event.clientY - startY;\n const dismiss = dragged > pane.getBoundingClientRect().height * threshold;\n // WCAG 2.3.3 : sous prefers-reduced-motion, on applique l'état final SANS animation.\n const reduceMotion = !!ownerDoc?.defaultView?.matchMedia?.('(prefers-reduced-motion: reduce)').matches;\n\n if (reduceMotion) {\n // draggingClass (transition coupée) encore présente : la translation finale est instantanée,\n // puis on retire la classe (aucun changement de valeur ⇒ aucune animation déclenchée).\n pane.style.translate = dismiss ? '0 100%' : '';\n pane.classList.remove(opts.draggingClass);\n } else {\n pane.classList.remove(opts.draggingClass); // réactive la transition CSS (glissement / snap-back)\n pane.style.translate = dismiss ? '0 100%' : ''; // dismiss : glisse jusqu'en bas ; sinon snap-back à 0\n }\n if (dismiss) opts.onDismiss();\n\n pane = null;\n handle = null;\n ownerDoc = null;\n };\n\n return {\n start(event: PointerEvent): void {\n if (event.button !== 0) return;\n const el = opts.pane();\n if (!el) return;\n handle = event.currentTarget as HTMLElement;\n ownerDoc = handle.ownerDocument;\n // La poignée ne doit PAS voler le focus (sinon un close-on-blur fermerait prématurément).\n event.preventDefault();\n startY = event.clientY;\n pane = el;\n pane.classList.add(opts.draggingClass);\n // Écoute au niveau du document : un pointer qui sort de la poignée (petite cible) ou une\n // capture perdue n'interrompt plus le suivi du glissement ni le snap-back.\n ownerDoc.addEventListener('pointermove', onMove);\n ownerDoc.addEventListener('pointerup', onEnd);\n ownerDoc.addEventListener('pointercancel', onEnd);\n },\n destroy(): void {\n cleanupListeners();\n pane = null;\n handle = null;\n ownerDoc = null;\n },\n };\n}\n","import { InjectionToken, Provider } from '@angular/core';\n\n/**\n * Valeur d'un palier de breakpoint, CONFIGURABLE PAR APPLICATION :\n * - un **nombre** = largeur (px) à partir de laquelle le palier commence ; la lib en dérive une\n * media query LARGEUR SEULE (bornes calculées par rapport au palier suivant) ;\n * - une **chaîne** = media query complète du palier, utilisée VERBATIM (échappatoire pour un critère\n * non-largeur : `orientation`, `pointer`, ratio…).\n */\nexport type KtBreakpointValue = number | string;\n\n/**\n * Seuils responsive de la lib, surchargeables par appli via `provideKtBreakpoints`. Sémantique\n * « plancher de palier » : chaque valeur indique où le palier COMMENCE → 3 bandes mutuellement\n * exclusives (`mobile` < `tablet` < `desktop`).\n */\nexport interface KtBreakpoints {\n /** Plancher du mobile (typiquement 0). */\n mobile: KtBreakpointValue;\n /** Largeur où commence la tablette (= plafond mobile). */\n tablet: KtBreakpointValue;\n /** Largeur où commence le desktop (= plafond tablette). */\n desktop: KtBreakpointValue;\n}\n\n/** Défauts : bascule bottom-sheet sous 600px (aligné sur l'ancien `MOBILE_QUERY`). */\nexport const KT_DEFAULT_BREAKPOINTS: KtBreakpoints = { mobile: 0, tablet: 600, desktop: 1024 };\n\n/** Token des seuils responsive. Défaut = `KT_DEFAULT_BREAKPOINTS` ; surchargé par `provideKtBreakpoints`. */\nexport const KT_BREAKPOINTS = new InjectionToken<KtBreakpoints>('KT_BREAKPOINTS', {\n providedIn: 'root',\n factory: () => KT_DEFAULT_BREAKPOINTS,\n});\n\n/**\n * À ajouter aux `providers` de `app.config.ts`. Fusionne avec les défauts → surcharge partielle OK.\n * @param overrides Seuils à surcharger ; les clés absentes gardent leur défaut `KT_DEFAULT_BREAKPOINTS`.\n * @returns Provider liant `KT_BREAKPOINTS` aux seuils fusionnés.\n * @example provideKtBreakpoints({ tablet: 768, desktop: 1200 })\n * @example provideKtBreakpoints({ tablet: '(min-width: 768px) and (orientation: landscape)' })\n */\nexport function provideKtBreakpoints(overrides: Partial<KtBreakpoints>): Provider {\n return { provide: KT_BREAKPOINTS, useValue: { ...KT_DEFAULT_BREAKPOINTS, ...overrides } };\n}\n\n/** Trois chaînes de media queries résolues, prêtes pour `matchMedia` / `BreakpointObserver`. */\nexport interface KtBreakpointMedia {\n /** Media query de la bande mobile. */\n mobile: string;\n /** Media query de la bande tablette. */\n tablet: string;\n /** Media query de la bande desktop. */\n desktop: string;\n}\n\n/** Évite le chevauchement d'1px entre deux bandes adjacentes (max-width juste sous le plancher suivant). */\nconst EPSILON = 0.02;\n\nfunction minWidth(v: number): string {\n return `(min-width: ${v}px)`;\n}\n\nfunction maxWidth(nextFloor: number): string {\n return `(max-width: ${nextFloor - EPSILON}px)`;\n}\n\n/** `not all` ne matche jamais : repli sûr (= desktop) si une bande numérique se retrouve sans borne. */\nfunction join(...parts: string[]): string {\n return parts.filter(Boolean).join(' and ') || 'not all';\n}\n\n/**\n * Convertit les seuils (nombres et/ou chaînes) en 3 media queries. Un palier-chaîne est repris\n * verbatim ; un palier-nombre devient la bande `[plancher courant .. plancher suivant[`. Si le\n * plancher suivant est une chaîne (pas de borne numérique), la bande reste ouverte de ce côté.\n * @param bp Seuils responsive à convertir (nombres et/ou chaînes).\n * @returns Les trois media queries résolues (`mobile`, `tablet`, `desktop`).\n * @example resolveKtBreakpointMedia(KT_DEFAULT_BREAKPOINTS)\n */\nexport function resolveKtBreakpointMedia(bp: KtBreakpoints): KtBreakpointMedia {\n const { mobile, tablet, desktop } = bp;\n\n return {\n mobile:\n typeof mobile === 'string'\n ? mobile\n : join(mobile > 0 ? minWidth(mobile) : '', typeof tablet === 'number' ? maxWidth(tablet) : ''),\n tablet:\n typeof tablet === 'string'\n ? tablet\n : join(minWidth(tablet), typeof desktop === 'number' ? maxWidth(desktop) : ''),\n desktop: typeof desktop === 'string' ? desktop : minWidth(desktop),\n };\n}\n","import { Injectable, Signal, inject } from '@angular/core';\nimport { toSignal } from '@angular/core/rxjs-interop';\nimport { BreakpointObserver } from '@angular/cdk/layout';\nimport { map } from 'rxjs';\nimport { KT_BREAKPOINTS, resolveKtBreakpointMedia } from './breakpoints';\n\n/**\n * Expose l'état responsive courant en SIGNALS, dérivé des seuils configurés par l'appli\n * (`KT_BREAKPOINTS` / `provideKtBreakpoints`). Fondé sur `BreakpointObserver` (`@angular/cdk/layout`,\n * déjà dépendance) : SSR-safe (`matches: false` côté serveur → desktop par défaut) et nettoyage des\n * listeners géré par le CDK.\n *\n * À injecter aussi bien dans les composants de la lib (bascule bottom-sheet) que dans le code des\n * applis consommatrices pour leur propre layout responsive.\n */\n@Injectable({ providedIn: 'root' })\nexport class KtViewport {\n private readonly observer = inject(BreakpointObserver);\n\n /** Media queries résolues (largeur dérivée ou verbatim selon le token) — utile pour miroir CSS. */\n readonly media = resolveKtBreakpointMedia(inject(KT_BREAKPOINTS));\n\n /** Le viewport est dans la bande mobile. */\n readonly isMobile = this.matches(this.media.mobile);\n /** Le viewport est dans la bande tablette. */\n readonly isTablet = this.matches(this.media.tablet);\n /** Le viewport est dans la bande desktop. */\n readonly isDesktop = this.matches(this.media.desktop);\n /** Alias de `isMobile` : palier où les composants de la lib basculent en bottom-sheet. */\n readonly isCompact = this.isMobile;\n\n private matches(query: string): Signal<boolean> {\n return toSignal(this.observer.observe(query).pipe(map((state) => state.matches)), {\n initialValue: false,\n });\n }\n}\n","import { Injectable } from '@angular/core';\n\n/**\n * Génère des identifiants numériques incrémentaux uniques au sein de l'application, soit globalement,\n * soit par préfixe (compteur dédié). Sert à construire des `anchor-name` / `id` stables et distincts.\n *\n * @example\n * ```ts\n * const idGen = inject(KtIdGenerator);\n * const anchor = `--kt-menu-anchor-${idGen.generateId('menu')}`;\n * ```\n */\n@Injectable({\n providedIn: 'root',\n})\nexport class KtIdGenerator {\n private readonly counters = new Map<string, number>();\n private nextGlobalId = 0;\n\n /**\n * Renvoie le prochain identifiant. Sans `prefix`, utilise le compteur global ; avec `prefix`,\n * utilise un compteur dédié à ce préfixe (séquences indépendantes).\n * @param prefix Clé optionnelle de compteur ; chaque préfixe a sa propre séquence.\n * @returns Le compteur courant (number) pour la portée demandée, avant incrément.\n */\n generateId(prefix?: string): number {\n if (!prefix) {\n return this.nextGlobalId++;\n }\n const current = this.counters.get(prefix) ?? 0;\n this.counters.set(prefix, current + 1);\n return current;\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { DialogRef, DEFAULT_DIALOG_CONFIG, CdkDialogContainer, DIALOG_DATA, Dialog } from '@angular/cdk/dialog';
|
|
2
2
|
import * as i0 from '@angular/core';
|
|
3
|
-
import { inject, ElementRef, Renderer2, afterNextRender, Directive, input, isDevMode, DestroyRef, PLATFORM_ID, signal, Component, ViewContainerRef } from '@angular/core';
|
|
3
|
+
import { inject, ElementRef, Renderer2, afterNextRender, Directive, input, isDevMode, DestroyRef, PLATFORM_ID, signal, ChangeDetectionStrategy, Component, ViewContainerRef } from '@angular/core';
|
|
4
4
|
import { KtIdGenerator, createKtSheetDrag, KtViewport } from '@ktortu/aaa/cdk';
|
|
5
|
+
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
|
5
6
|
import { isPlatformBrowser } from '@angular/common';
|
|
6
7
|
import * as i1 from '@angular/cdk/portal';
|
|
7
8
|
import { PortalModule } from '@angular/cdk/portal';
|
|
@@ -26,8 +27,11 @@ class KtDialogTitle {
|
|
|
26
27
|
host = inject(ElementRef).nativeElement;
|
|
27
28
|
renderer = inject(Renderer2);
|
|
28
29
|
idGen = inject(KtIdGenerator);
|
|
29
|
-
/**
|
|
30
|
-
|
|
30
|
+
/**
|
|
31
|
+
* Id de l'hôte câblé en `aria-labelledby` : préserve un id fourni par le consommateur, sinon en génère un.
|
|
32
|
+
* @default `host.id` ?? `dialogRef.config.ariaLabelledBy` ?? `kt-dialog-title-<généré>`
|
|
33
|
+
*/
|
|
34
|
+
id = this.host.id || this.dialogRef?.config.ariaLabelledBy || `kt-dialog-title-${this.idGen.generateId('dialog')}`;
|
|
31
35
|
constructor() {
|
|
32
36
|
const preConfigured = this.dialogRef?.config.ariaLabelledBy;
|
|
33
37
|
if (!preConfigured) {
|
|
@@ -72,8 +76,11 @@ class KtDialogDescription {
|
|
|
72
76
|
host = inject(ElementRef).nativeElement;
|
|
73
77
|
renderer = inject(Renderer2);
|
|
74
78
|
idGen = inject(KtIdGenerator);
|
|
75
|
-
/**
|
|
76
|
-
|
|
79
|
+
/**
|
|
80
|
+
* Id de l'hôte câblé en `aria-describedby` : préserve un id fourni par le consommateur, sinon en génère un.
|
|
81
|
+
* @default `host.id` ?? `dialogRef.config.ariaDescribedBy` ?? `kt-dialog-desc-<généré>`
|
|
82
|
+
*/
|
|
83
|
+
id = this.host.id || this.dialogRef?.config.ariaDescribedBy || `kt-dialog-desc-${this.idGen.generateId('dialog')}`;
|
|
77
84
|
constructor() {
|
|
78
85
|
const preConfigured = this.dialogRef?.config.ariaDescribedBy;
|
|
79
86
|
if (!preConfigured) {
|
|
@@ -88,6 +95,9 @@ class KtDialogDescription {
|
|
|
88
95
|
}
|
|
89
96
|
}
|
|
90
97
|
ngOnInit() {
|
|
98
|
+
// Asymétrie ASSUMÉE avec `ktDialogTitle` : la description peut porter un `id` d'hôte fourni par
|
|
99
|
+
// le consommateur ; on aligne alors `config.ariaDescribedBy` dessus (le host binding live du
|
|
100
|
+
// conteneur reflète la valeur). Un titre est posé une fois et n'a pas ce besoin.
|
|
91
101
|
if (this.dialogRef && this.dialogRef.config.ariaDescribedBy !== this.id) {
|
|
92
102
|
this.dialogRef.config.ariaDescribedBy = this.id;
|
|
93
103
|
}
|
|
@@ -305,6 +315,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.1", ngImpor
|
|
|
305
315
|
* Pour focaliser un élément précis à l'ouverture (ex. éviter un bouton destructeur),
|
|
306
316
|
* passez `autoFocus: '[ktDialogFocusInitial]'` dans la config d'ouverture et posez la
|
|
307
317
|
* directive `ktDialogFocusInitial` sur la cible.
|
|
318
|
+
*
|
|
319
|
+
* @example
|
|
320
|
+
* ```ts
|
|
321
|
+
* // valeur de base, généralement consommée via provideKtDialogDefaults()
|
|
322
|
+
* provideKtDialogDefaults({ ...KT_DIALOG_AAA_DEFAULTS });
|
|
323
|
+
* ```
|
|
308
324
|
*/
|
|
309
325
|
const KT_DIALOG_AAA_DEFAULTS = {
|
|
310
326
|
role: 'dialog',
|
|
@@ -319,6 +335,16 @@ const KT_DIALOG_AAA_DEFAULTS = {
|
|
|
319
335
|
* Enregistre les valeurs par défaut AAA du dialog au niveau application.
|
|
320
336
|
* À ajouter aux `providers` de `app.config.ts`. `overrides` permet d'ajuster sans
|
|
321
337
|
* tout réécrire (ex. `provideKtDialogDefaults({ maxWidth: '40rem' })`).
|
|
338
|
+
*
|
|
339
|
+
* @example
|
|
340
|
+
* ```ts
|
|
341
|
+
* // app.config.ts
|
|
342
|
+
* export const appConfig: ApplicationConfig = {
|
|
343
|
+
* providers: [provideKtDialogDefaults({ maxWidth: '40rem' })],
|
|
344
|
+
* };
|
|
345
|
+
* ```
|
|
346
|
+
* @param overrides Surcharges partielles fusionnées par-dessus `KT_DIALOG_AAA_DEFAULTS`.
|
|
347
|
+
* @returns Un `Provider` pour le token `DEFAULT_DIALOG_CONFIG`.
|
|
322
348
|
*/
|
|
323
349
|
function provideKtDialogDefaults(overrides) {
|
|
324
350
|
return {
|
|
@@ -339,6 +365,15 @@ function concreteDialogPanelClass(p) {
|
|
|
339
365
|
* `centered-*`, l'appelant fournit `compact` (= `KtViewport.isCompact()`, largeur seule) — centré
|
|
340
366
|
* sur desktop, plein écran / sheet sur écran compact. Fonction pure (testable sans DOM).
|
|
341
367
|
* Appelée par `injectKtDialogOpener` à chaque ouverture ; exportée pour un usage direct éventuel.
|
|
368
|
+
*
|
|
369
|
+
* @example
|
|
370
|
+
* ```ts
|
|
371
|
+
* resolveKtDialogPanelClass('sheet'); // ['kt-dialog', 'kt-dialog--sheet']
|
|
372
|
+
* resolveKtDialogPanelClass('centered-sheet', true); // bottom-sheet sur écran compact
|
|
373
|
+
* ```
|
|
374
|
+
* @param presentation Présentation choisie par le dev (responsive comprise). Défaut `'centered'`.
|
|
375
|
+
* @param compact `true` quand l'écran est compact (= `KtViewport.isCompact()`), pour résoudre les variantes `centered-*`. Défaut `false`.
|
|
376
|
+
* @returns La liste des classes CSS de la présentation concrète résolue.
|
|
342
377
|
*/
|
|
343
378
|
function resolveKtDialogPanelClass(presentation = 'centered', compact = false) {
|
|
344
379
|
if (presentation === 'centered' || presentation === 'fullscreen' || presentation === 'sheet') {
|
|
@@ -355,6 +390,7 @@ class KtDialogContainer extends CdkDialogContainer {
|
|
|
355
390
|
elementRef = inject(ElementRef);
|
|
356
391
|
host = this.elementRef.nativeElement;
|
|
357
392
|
platformId = inject(PLATFORM_ID);
|
|
393
|
+
destroyRef = inject(DestroyRef);
|
|
358
394
|
isClosing = signal(false, /* @ts-ignore */
|
|
359
395
|
...(ngDevMode ? [{ debugName: "isClosing" }] : /* istanbul ignore next */ []));
|
|
360
396
|
constructor() {
|
|
@@ -364,12 +400,32 @@ class KtDialogContainer extends CdkDialogContainer {
|
|
|
364
400
|
this.dialogRef.close = (result) => {
|
|
365
401
|
this.animateAndClose(result, originalClose);
|
|
366
402
|
};
|
|
403
|
+
// L'ouvreur pré-réserve des ids titre/description ; les directives [ktDialogTitle]/[ktDialogDescription]
|
|
404
|
+
// les adoptent. En leur absence, ces ids pointent dans le vide. Au rendu (navigateur) :
|
|
405
|
+
// - aria-describedby orphelin → on RETIRE l'attribut (pas de description fournie) ;
|
|
406
|
+
// - aucun nom accessible (ni titre ni aria-label) → warn dev (WCAG 4.1.2).
|
|
407
|
+
afterNextRender(() => {
|
|
408
|
+
const doc = this.host.ownerDocument;
|
|
409
|
+
const describedBy = this.host.getAttribute('aria-describedby');
|
|
410
|
+
if (describedBy && !doc.getElementById(describedBy)) {
|
|
411
|
+
this.host.removeAttribute('aria-describedby');
|
|
412
|
+
}
|
|
413
|
+
if (!isDevMode())
|
|
414
|
+
return;
|
|
415
|
+
const labelledBy = this.host.getAttribute('aria-labelledby');
|
|
416
|
+
const hasName = !!this.host.getAttribute('aria-label') || (!!labelledBy && !!doc.getElementById(labelledBy));
|
|
417
|
+
if (!hasName) {
|
|
418
|
+
console.warn('[ktDialog] dialog sans nom accessible : ajoutez un [ktDialogTitle] (ou `aria-label` via la config d’ouverture) — WCAG 4.1.2.');
|
|
419
|
+
}
|
|
420
|
+
});
|
|
367
421
|
}
|
|
368
422
|
ngOnInit() {
|
|
369
423
|
// Si la fermeture par clic extérieur/Échap est autorisée, on l'écoute pour lancer l'animation
|
|
370
424
|
if (!this._config.disableClose) {
|
|
371
|
-
this.dialogRef.backdropClick
|
|
372
|
-
|
|
425
|
+
this.dialogRef.backdropClick
|
|
426
|
+
.pipe(takeUntilDestroyed(this.destroyRef))
|
|
427
|
+
.subscribe(() => this.dialogRef.close());
|
|
428
|
+
this.dialogRef.keydownEvents.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((event) => {
|
|
373
429
|
if (event.key === 'Escape') {
|
|
374
430
|
event.preventDefault();
|
|
375
431
|
this.dialogRef.close();
|
|
@@ -415,12 +471,13 @@ class KtDialogContainer extends CdkDialogContainer {
|
|
|
415
471
|
<div class="kt-dialog-container__layout">
|
|
416
472
|
<ng-template cdkPortalOutlet></ng-template>
|
|
417
473
|
</div>
|
|
418
|
-
`, isInline: true, dependencies: [{ kind: "ngmodule", type: PortalModule }, { kind: "directive", type: i1.CdkPortalOutlet, selector: "[cdkPortalOutlet]", inputs: ["cdkPortalOutlet"], outputs: ["attached"], exportAs: ["cdkPortalOutlet"] }] });
|
|
474
|
+
`, isInline: true, dependencies: [{ kind: "ngmodule", type: PortalModule }, { kind: "directive", type: i1.CdkPortalOutlet, selector: "[cdkPortalOutlet]", inputs: ["cdkPortalOutlet"], outputs: ["attached"], exportAs: ["cdkPortalOutlet"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
419
475
|
}
|
|
420
476
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.1", ngImport: i0, type: KtDialogContainer, decorators: [{
|
|
421
477
|
type: Component,
|
|
422
478
|
args: [{
|
|
423
479
|
selector: 'kt-dialog-container',
|
|
480
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
424
481
|
imports: [PortalModule],
|
|
425
482
|
host: {
|
|
426
483
|
class: 'cdk-dialog-container kt-dialog-container',
|
|
@@ -474,7 +531,7 @@ function injectKtDialogOpener(component, baseConfig) {
|
|
|
474
531
|
// Dédoublonné : une classe déjà fournie par la présentation (ex. `kt-dialog`) et repassée
|
|
475
532
|
// en `panelClass` par le consommateur ne doit pas apparaître deux fois.
|
|
476
533
|
const merged = [...new Set([...resolveKtDialogPanelClass(presentation, viewport.isCompact()), ...extra])];
|
|
477
|
-
const uid = idGen.generateId();
|
|
534
|
+
const uid = idGen.generateId('dialog');
|
|
478
535
|
const titleId = `kt-dialog-title-${uid}`;
|
|
479
536
|
const descId = `kt-dialog-desc-${uid}`;
|
|
480
537
|
return dialog.open(component, {
|
|
@@ -491,9 +548,9 @@ function injectKtDialogOpener(component, baseConfig) {
|
|
|
491
548
|
|
|
492
549
|
/**
|
|
493
550
|
* Import ergonomique de toute la famille dialog en une fois :
|
|
494
|
-
* `imports: [
|
|
551
|
+
* `imports: [KtDialogImports]` au lieu d'énumérer chaque directive structurelle.
|
|
495
552
|
*/
|
|
496
|
-
const
|
|
553
|
+
const KtDialogImports = [
|
|
497
554
|
KtDialogHeader,
|
|
498
555
|
KtDialogTitle,
|
|
499
556
|
KtDialogDescription,
|
|
@@ -508,5 +565,5 @@ const KT_DIALOG = [
|
|
|
508
565
|
* Generated bundle index. Do not edit.
|
|
509
566
|
*/
|
|
510
567
|
|
|
511
|
-
export {
|
|
568
|
+
export { KT_DIALOG_AAA_DEFAULTS, KtDialogActions, KtDialogClose, KtDialogContainer, KtDialogContent, KtDialogDescription, KtDialogFocusInitial, KtDialogHeader, KtDialogImports, KtDialogSheetHandle, KtDialogTitle, injectKtDialogData, injectKtDialogOpener, provideKtDialogDefaults, resolveKtDialogPanelClass };
|
|
512
569
|
//# sourceMappingURL=ktortu-aaa-dialog.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ktortu-aaa-dialog.mjs","sources":["../../../../projects/ktortu/aaa/dialog/dialog-title.directive.ts","../../../../projects/ktortu/aaa/dialog/dialog-description.directive.ts","../../../../projects/ktortu/aaa/dialog/dialog-close.directive.ts","../../../../projects/ktortu/aaa/dialog/dialog-structure.ts","../../../../projects/ktortu/aaa/dialog/dialog-config.ts","../../../../projects/ktortu/aaa/dialog/dialog-container.ts","../../../../projects/ktortu/aaa/dialog/dialog-opener.ts","../../../../projects/ktortu/aaa/dialog/public-api.ts","../../../../projects/ktortu/aaa/dialog/ktortu-aaa-dialog.ts"],"sourcesContent":["import { DialogRef } from '@angular/cdk/dialog';\nimport { Directive, ElementRef, Renderer2, afterNextRender, inject } from '@angular/core';\nimport { KtIdGenerator } from '@ktortu/aaa/cdk';\n\n/**\n * À poser sur le titre VISIBLE (idéalement un `<h2>`) du contenu d'un CDK Dialog.\n * Câble `aria-labelledby` du conteneur de dialogue.\n *\n * Pourquoi écrire l'attribut directement (Renderer2) plutôt que seulement `_addAriaLabelledBy` :\n * sous change detection ZONELESS (cas par défaut moderne), le `markForCheck()` interne du\n * conteneur ne rafraîchit pas ses host bindings à l'ouverture, donc l'attribut n'apparaîtrait\n * jamais. On écrit donc l'attribut nous-mêmes (fiable, indépendant de la CD) ET on alimente la\n * file CDK pour rester cohérent si un cycle de CD survient ensuite.\n *\n * @example\n * ```html\n * <h2 ktDialogTitle>Renommer le fichier</h2>\n * ```\n */\n@Directive({\n selector: '[ktDialogTitle]',\n host: { '[id]': 'id' },\n})\nexport class KtDialogTitle {\n private readonly dialogRef = inject<DialogRef<unknown>>(DialogRef, { optional: true });\n private readonly host = inject<ElementRef<HTMLElement>>(ElementRef).nativeElement;\n private readonly renderer = inject(Renderer2);\n private readonly idGen = inject(KtIdGenerator);\n\n /** Id de l'hôte câblé en `aria-labelledby` : préserve un id fourni par le consommateur, sinon en génère un. */\n readonly id = this.host.id || this.dialogRef?.config.ariaLabelledBy || `kt-dialog-title-${this.idGen.generateId()}`;\n\n constructor() {\n const preConfigured = this.dialogRef?.config.ariaLabelledBy;\n if (!preConfigured) {\n if (this.dialogRef) {\n this.dialogRef.config.ariaLabelledBy = this.id;\n }\n afterNextRender(() => {\n const container = this.host.closest('.cdk-dialog-container');\n if (container) this.renderer.setAttribute(container, 'aria-labelledby', this.id);\n });\n }\n }\n}\n","import { DialogRef } from '@angular/cdk/dialog';\nimport { Directive, ElementRef, OnDestroy, OnInit, Renderer2, afterNextRender, inject } from '@angular/core';\nimport { KtIdGenerator } from '@ktortu/aaa/cdk';\n\n/**\n * À poser sur le paragraphe descriptif COURT du dialog : câble `aria-describedby` du conteneur\n * (texte lu par le lecteur d'écran juste après le titre, à l'ouverture).\n *\n * ⚠️ Ne JAMAIS appliquer sur un formulaire ou un long contenu : `aria-describedby` concatène\n * tout le texte du nœud et serait lu d'un bloc à l'ouverture. Réserver à une phrase de contexte.\n *\n * Écriture directe de l'attribut (Renderer2) pour la même raison que `ktDialogTitle` :\n * fiabilité sous change detection zoneless. La config est tenue à jour pour cohérence CDK.\n *\n * @example\n * ```html\n * <p ktDialogDescription>Cette action est définitive.</p>\n * ```\n */\n@Directive({\n selector: '[ktDialogDescription]',\n host: { '[id]': 'id' },\n})\nexport class KtDialogDescription implements OnInit, OnDestroy {\n private readonly dialogRef = inject<DialogRef<unknown>>(DialogRef, { optional: true });\n private readonly host = inject<ElementRef<HTMLElement>>(ElementRef).nativeElement;\n private readonly renderer = inject(Renderer2);\n private readonly idGen = inject(KtIdGenerator);\n\n /** Id de l'hôte câblé en `aria-describedby` : préserve un id fourni par le consommateur, sinon en génère un. */\n readonly id = this.host.id || this.dialogRef?.config.ariaDescribedBy || `kt-dialog-desc-${this.idGen.generateId()}`;\n\n constructor() {\n const preConfigured = this.dialogRef?.config.ariaDescribedBy;\n if (!preConfigured) {\n if (this.dialogRef) {\n this.dialogRef.config.ariaDescribedBy = this.id;\n }\n afterNextRender(() => {\n const container = this.host.closest('.cdk-dialog-container');\n if (container) this.renderer.setAttribute(container, 'aria-describedby', this.id);\n });\n }\n }\n\n ngOnInit(): void {\n if (this.dialogRef && this.dialogRef.config.ariaDescribedBy !== this.id) {\n this.dialogRef.config.ariaDescribedBy = this.id;\n }\n }\n\n ngOnDestroy(): void {\n if (this.dialogRef?.config.ariaDescribedBy === this.id) {\n this.dialogRef.config.ariaDescribedBy = null;\n }\n }\n}\n","import { DialogRef } from '@angular/cdk/dialog';\nimport { Directive, ElementRef, afterNextRender, inject, input, isDevMode } from '@angular/core';\n\n/**\n * Ferme le CDK Dialog au clic, avec un résultat optionnel renvoyé à l'ouvreur via\n * `DialogRef.close(result)`. Se compose avec `[ktButton]` sur le même `<button>`.\n *\n * Réservé au DISMISS simple (Annuler / Fermer). Pour valider un formulaire, injectez\n * `DialogRef` dans votre composant et appelez `close(valeur)` après validation.\n *\n * @example\n * ```html\n * <button ktButton ktDialogClose>Annuler</button>\n * <button ktButton [ktDialogClose]=\"'confirm'\">Confirmer</button>\n * ```\n */\n@Directive({\n selector: '[ktDialogClose]',\n host: {\n '[attr.type]': 'buttonType',\n '(click)': 'close()',\n },\n})\nexport class KtDialogClose {\n private readonly dialogRef = inject<DialogRef<unknown>>(DialogRef, { optional: true });\n private readonly host = inject<ElementRef<HTMLElement>>(ElementRef).nativeElement;\n\n /**\n * Valeur renvoyée à l'ouvreur via `DialogRef.close(result)`. Liée par l'alias `ktDialogClose`\n * (= nom du sélecteur), d'où l'usage `[ktDialogClose]=\"'confirm'\"`. @default undefined\n */\n readonly dialogResult = input<unknown>(undefined, { alias: 'ktDialogClose' });\n\n // Force type=\"button\" sur un <button> (évite le submit implicite dans un <form>).\n protected readonly buttonType = this.host.tagName === 'BUTTON' ? 'button' : null;\n\n constructor() {\n // Garde-fou a11y (dev) : un bouton de fermeture doit avoir un nom accessible (WCAG 4.1.2).\n afterNextRender(() => {\n if (!isDevMode()) return;\n\n const named =\n (this.host.textContent ?? '').trim().length > 0 ||\n this.host.hasAttribute('aria-label') ||\n this.host.hasAttribute('aria-labelledby');\n if (!named) {\n console.warn(\n '[ktDialogClose] Bouton de fermeture sans nom accessible (WCAG 4.1.2) : ' +\n 'ajoutez du texte visible, aria-label ou aria-labelledby.',\n );\n }\n });\n }\n\n protected close(): void {\n this.dialogRef?.close(this.dialogResult());\n }\n}\n","import { DestroyRef, Directive, ElementRef, inject } from '@angular/core';\nimport { DialogRef } from '@angular/cdk/dialog';\n\nimport { createKtSheetDrag } from '@ktortu/aaa/cdk';\n\n/**\n * En-tête RICHE et OPTIONNEL du dialog : rangée flex pour composer une icône, le titre et/ou un\n * bouton de fermeture. Marqueur structurel sans logique — la mise en forme (flex, padding de\n * région, reset du padding du [ktDialogTitle] qu'il enveloppe) vit dans `dialog.css`.\n *\n * Sépare le LAYOUT (cette région) de l'ÉTIQUETTE ACCESSIBLE ([ktDialogTitle], qui garde\n * aria-labelledby). En usage simple — titre nu sans header — [ktDialogTitle] conserve son propre\n * padding : ce header n'est à utiliser que pour les en-têtes composés (icône, close top-right…).\n *\n * @example\n * ```html\n * <header ktDialogHeader>\n * <h2 ktDialogTitle>Titre</h2>\n * <button ktButton ktDialogClose aria-label=\"Fermer\">✕</button>\n * </header>\n * ```\n */\n@Directive({ selector: '[ktDialogHeader]' })\nexport class KtDialogHeader {}\n\n/**\n * Zone de contenu du dialog. Marqueur structurel sans logique : la mise en forme\n * (rythme vertical) vit dans `dialog.css` via le sélecteur `[ktDialogContent]`.\n *\n * @example\n * ```html\n * <div ktDialogContent>…</div>\n * ```\n */\n@Directive({ selector: '[ktDialogContent]' })\nexport class KtDialogContent {}\n\n/**\n * Barre d'actions du dialog (rangée de boutons). Marqueur structurel sans logique :\n * la mise en forme (flex, gap, sticky bas pour le Reflow AAA) vit dans `dialog.css`\n * via le sélecteur `[ktDialogActions]`.\n *\n * @example\n * ```html\n * <footer ktDialogActions>\n * <button ktButton ktDialogClose>Annuler</button>\n * <button ktButton [ktDialogClose]=\"'ok'\">Valider</button>\n * </footer>\n * ```\n */\n@Directive({ selector: '[ktDialogActions]' })\nexport class KtDialogActions {}\n\n/**\n * Marque l'élément à focaliser à l'ouverture. À coupler avec la config CDK\n * `autoFocus: '[ktDialogFocusInitial]'` (incluse dans `provideKtDialogDefaults`).\n * Permet d'éviter que le focus initial tombe sur une action destructrice.\n *\n * @example\n * ```html\n * <input ktDialogFocusInitial type=\"text\" />\n * ```\n */\n@Directive({ selector: '[ktDialogFocusInitial]' })\nexport class KtDialogFocusInitial {}\n\n/**\n * Poignée de préhension d'un dialog en mode `sheet` (bottom-sheet) : drag-to-dismiss vers le bas,\n * FACTORISÉ avec le Select via `createKtSheetDrag` (@ktortu/aaa). Geste DOUBLÉ par Échap + bouton\n * Fermer + clic sur le scrim (WCAG 2.5.1) — décoratif (`aria-hidden`).\n *\n * À poser sur la barre de préhension, premier enfant du contenu d'un dialog ouvert avec une\n * présentation `sheet` / `centered-sheet`. Le drag n'est actif que si le dialog est EFFECTIVEMENT\n * en mode sheet (la pane porte `kt-dialog--sheet`) — pas de dépendance au viewport : un `sheet`\n * toujours-bottom-sheet se drague aussi à la souris.\n *\n * @example\n * ```html\n * <div ktDialogContent>\n * <div ktDialogSheetHandle></div>\n * …\n * </div>\n * ```\n */\n@Directive({\n selector: '[ktDialogSheetHandle]',\n host: {\n '(pointerdown)': 'onStart($event)',\n '(mousedown)': '$event.preventDefault()',\n 'aria-hidden': 'true',\n },\n})\nexport class KtDialogSheetHandle {\n private readonly dialogRef = inject<DialogRef<unknown>>(DialogRef, { optional: true });\n private readonly host = inject<ElementRef<HTMLElement>>(ElementRef).nativeElement;\n private readonly destroyRef = inject(DestroyRef);\n\n // La feuille translatée = le conteneur CDK (position:fixed en mode sheet), trouvé en remontant.\n private readonly drag = createKtSheetDrag({\n pane: () => this.host.closest<HTMLElement>('.cdk-dialog-container'),\n onDismiss: () => this.dialogRef?.close(),\n draggingClass: 'kt-dialog-sheet--dragging',\n });\n\n constructor() {\n this.destroyRef.onDestroy(() => this.drag.destroy());\n }\n\n protected onStart(event: PointerEvent): void {\n // Actif seulement quand la PRÉSENTATION choisie par le dev est `sheet` (classe sur la pane).\n const pane = this.host.closest('.cdk-overlay-pane');\n if (!pane?.classList.contains('kt-dialog--sheet')) return;\n this.drag.start(event);\n }\n}\n","import { DEFAULT_DIALOG_CONFIG, DialogConfig } from '@angular/cdk/dialog';\nimport { Provider } from '@angular/core';\n\n/**\n * Valeurs par défaut orientées AAA pour `@angular/cdk/dialog`.\n * - `ariaModal: true` : explicite (le CDK le laisse OFF par défaut).\n * - `restoreFocus: true` : rend le focus au déclencheur à la fermeture.\n * - `panelClass` / `backdropClass` : crochets de style consommés par `dialog.css`.\n *\n * Pour focaliser un élément précis à l'ouverture (ex. éviter un bouton destructeur),\n * passez `autoFocus: '[ktDialogFocusInitial]'` dans la config d'ouverture et posez la\n * directive `ktDialogFocusInitial` sur la cible.\n */\nexport const KT_DIALOG_AAA_DEFAULTS: DialogConfig = {\n role: 'dialog',\n ariaModal: true,\n autoFocus: '[ktDialogFocusInitial]',\n restoreFocus: true,\n hasBackdrop: true,\n panelClass: 'kt-dialog',\n backdropClass: 'kt-dialog__backdrop',\n};\n\n/**\n * Enregistre les valeurs par défaut AAA du dialog au niveau application.\n * À ajouter aux `providers` de `app.config.ts`. `overrides` permet d'ajuster sans\n * tout réécrire (ex. `provideKtDialogDefaults({ maxWidth: '40rem' })`).\n */\nexport function provideKtDialogDefaults(overrides?: Partial<DialogConfig>): Provider {\n return {\n provide: DEFAULT_DIALOG_CONFIG,\n useValue: { ...KT_DIALOG_AAA_DEFAULTS, ...overrides },\n };\n}\n\n/**\n * Présentation du dialog, CHOISIE EXPLICITEMENT PAR LE DÉVELOPPEUR à l'ouverture (option\n * `presentation` de `injectKtDialogOpener`). Aucune bascule CSS automatique : le dev décide.\n * - `centered` : toujours centré (ex. confirmation) — DÉFAUT ;\n * - `fullscreen` : toujours plein écran (desktop compris) ;\n * - `sheet` : toujours bottom-sheet (desktop compris) ;\n * - `centered-fullscreen` : centré sur desktop, plein écran sur téléphone compact ;\n * - `centered-sheet` : centré sur desktop, bottom-sheet sur téléphone compact.\n * Les variantes `centered-*` sont résolues EN JS à l'ouverture (signal `KtViewport.isCompact()`), pas par le CSS —\n * la classe CSS finale est donc toujours une présentation CONCRÈTE (centered/fullscreen/sheet).\n */\nexport type KtDialogPresentation = 'centered' | 'fullscreen' | 'sheet' | 'centered-fullscreen' | 'centered-sheet';\n\n/** panelClass d'une présentation CONCRÈTE (sans variante responsive). */\nfunction concreteDialogPanelClass(p: 'centered' | 'fullscreen' | 'sheet'): string[] {\n if (p === 'fullscreen') return ['kt-dialog', 'kt-dialog--fullscreen'];\n if (p === 'sheet') return ['kt-dialog', 'kt-dialog--sheet'];\n return ['kt-dialog'];\n}\n\n/**\n * Résout une `KtDialogPresentation` (responsive comprise) en panelClass concret. Pour les variantes\n * `centered-*`, l'appelant fournit `compact` (= `KtViewport.isCompact()`, largeur seule) — centré\n * sur desktop, plein écran / sheet sur écran compact. Fonction pure (testable sans DOM).\n * Appelée par `injectKtDialogOpener` à chaque ouverture ; exportée pour un usage direct éventuel.\n */\nexport function resolveKtDialogPanelClass(presentation: KtDialogPresentation = 'centered', compact = false): string[] {\n if (presentation === 'centered' || presentation === 'fullscreen' || presentation === 'sheet') {\n return concreteDialogPanelClass(presentation);\n }\n if (presentation === 'centered-fullscreen') {\n return concreteDialogPanelClass(compact ? 'fullscreen' : 'centered');\n }\n return concreteDialogPanelClass(compact ? 'sheet' : 'centered'); // 'centered-sheet'\n}\n","import { Component, ElementRef, OnInit, signal, inject, PLATFORM_ID } from '@angular/core';\nimport { isPlatformBrowser } from '@angular/common';\nimport { CdkDialogContainer, DialogRef } from '@angular/cdk/dialog';\nimport { PortalModule } from '@angular/cdk/portal';\n\n@Component({\n selector: 'kt-dialog-container',\n imports: [PortalModule],\n host: {\n class: 'cdk-dialog-container kt-dialog-container',\n tabindex: '-1',\n '[attr.id]': '_config.id || null',\n '[attr.role]': '_config.role',\n '[attr.aria-modal]': '_config.ariaModal',\n '[attr.aria-labelledby]': '_config.ariaLabel ? null : _ariaLabelledByQueue[0]',\n '[attr.aria-label]': '_config.ariaLabel',\n '[attr.aria-describedby]': '_config.ariaDescribedBy || null',\n '[class.kt-dialog-container--sheet]': 'isSheet()',\n '[class.kt-dialog-container--closing]': 'isClosing()',\n },\n template: `\n <div class=\"kt-dialog-container__layout\">\n <ng-template cdkPortalOutlet></ng-template>\n </div>\n `,\n})\nexport class KtDialogContainer extends CdkDialogContainer implements OnInit {\n private readonly dialogRef = inject(DialogRef);\n private readonly elementRef = inject(ElementRef);\n private readonly host = this.elementRef.nativeElement as HTMLElement;\n private readonly platformId = inject(PLATFORM_ID);\n\n protected readonly isClosing = signal(false);\n\n constructor() {\n super();\n // Monkey-patch de dialogRef.close pour intercepter toutes les demandes de fermeture\n const originalClose = this.dialogRef.close.bind(this.dialogRef);\n this.dialogRef.close = (result?: unknown) => {\n this.animateAndClose(result, originalClose);\n };\n }\n\n ngOnInit(): void {\n // Si la fermeture par clic extérieur/Échap est autorisée, on l'écoute pour lancer l'animation\n if (!this._config.disableClose) {\n this.dialogRef.backdropClick.subscribe(() => this.dialogRef.close());\n this.dialogRef.keydownEvents.subscribe((event: KeyboardEvent) => {\n if (event.key === 'Escape') {\n event.preventDefault();\n this.dialogRef.close();\n }\n });\n }\n }\n\n protected isSheet(): boolean {\n return this._config.panelClass?.includes('kt-dialog--sheet') ?? false;\n }\n\n private animateAndClose(result: unknown, originalCloseFn: (r?: unknown) => void): void {\n if (this.isClosing()) return;\n this.isClosing.set(true);\n\n if (!isPlatformBrowser(this.platformId)) {\n originalCloseFn(result);\n return;\n }\n\n // Récupérer la durée de transition configurée en CSS (ex: \"150ms\" ou \"0.2s\")\n const styles = window.getComputedStyle(this.host);\n const durationStr = styles.transitionDuration || '0s';\n const durationMs = parseFloat(durationStr) * (durationStr.includes('ms') ? 1 : 1000);\n\n if (durationMs === 0) {\n originalCloseFn(result);\n return;\n }\n\n // Écouter la fin de la transition sur la propriété 'translate'\n const onTransitionEnd = (event: TransitionEvent) => {\n if (event.target === this.host && event.propertyName === 'translate') {\n this.host.removeEventListener('transitionend', onTransitionEnd);\n originalCloseFn(result);\n }\n };\n this.host.addEventListener('transitionend', onTransitionEnd);\n\n // Sécurité (au cas où la transition n'aboutirait pas)\n setTimeout(() => {\n this.host.removeEventListener('transitionend', onTransitionEnd);\n originalCloseFn(result);\n }, durationMs + 50);\n }\n}\n","import { DIALOG_DATA, Dialog, DialogConfig, DialogRef } from '@angular/cdk/dialog';\nimport { ComponentType } from '@angular/cdk/portal';\nimport { ViewContainerRef, inject } from '@angular/core';\nimport { KtViewport, KtIdGenerator } from '@ktortu/aaa/cdk';\n\nimport { KtDialogPresentation, resolveKtDialogPanelClass } from './dialog-config';\nimport { KtDialogContainer } from './dialog-container';\n\n/**\n * Sucre typé pour récupérer les données injectées dans un composant de dialogue (`DIALOG_DATA`).\n * À appeler en contexte d'injection (ex. initialiseur de champ).\n *\n * @example\n * ```ts\n * interface RenameData { currentName: string; }\n *\n * @Component({ … })\n * export class RenameDialog {\n * protected readonly data = injectKtDialogData<RenameData>();\n * // this.data.currentName → string\n * }\n * ```\n */\nexport function injectKtDialogData<T>(): T {\n return inject<T>(DIALOG_DATA);\n}\n\n/** Config d'ouverture sans le champ `data` (fourni séparément, typé), enrichie de `presentation`. */\ntype OpenerConfig<D, R, C> = Omit<DialogConfig<D, DialogRef<R, C>>, 'data'> & {\n /** Présentation du dialog (cf. `KtDialogPresentation`) — choisie par le dev. Résolue à CHAQUE\n ouverture : les variantes responsive lisent le signal d'écran compact. Défaut : `'centered'`.\n Combinée à un éventuel `panelClass` additionnel. */\n presentation?: KtDialogPresentation;\n};\n\n/**\n * Crée un ouvreur de dialog **typé et centralisé**, en contexte d'injection.\n * Le contrat (composant + type de `data` + type de résultat + config par défaut) est défini\n * UNE fois ; l'ouvreur renvoyé est une closure appelable ensuite n'importe où dans la classe\n * (handlers compris), 100 % typée, sans nouvel `inject`.\n *\n * Conserve le `ViewContainerRef` du contexte appelant (le dialog hérite donc de l'arbre logique\n * d'injection), reste testable (TestBed fournit `Dialog`) et sans état global (SSR-safe).\n *\n * @example\n * // co-localisé avec le composant\n * export const injectRenameDialog = () =>\n * injectKtDialogOpener<RenameDialog, RenameData, string>(RenameDialog, { autoFocus: '[ktDialogFocusInitial]' });\n *\n * // dans un composant/service consommateur\n * private readonly openRename = injectRenameDialog();\n * rename() { this.openRename({ currentName: 'X' }).closed.subscribe(n => { n: string | undefined }); }\n */\n// Compteur de dialogues pour générer des IDs uniques d'accessibilité SSR-safe.\n\n// Surcharge sans data (D = void) : l'ouvreur ne prend aucun argument (la config par défaut suffit).\nexport function injectKtDialogOpener<C, R = unknown>(\n component: ComponentType<C>,\n baseConfig?: OpenerConfig<void, R, C>,\n): () => DialogRef<R, C>;\n// Surcharge avec data typée.\nexport function injectKtDialogOpener<C, D, R = unknown>(\n component: ComponentType<C>,\n baseConfig?: OpenerConfig<D, R, C>,\n): (data: D, config?: OpenerConfig<D, R, C>) => DialogRef<R, C>;\n\nexport function injectKtDialogOpener<C, D, R = unknown>(\n component: ComponentType<C>,\n baseConfig?: OpenerConfig<D, R, C>,\n) {\n const dialog = inject(Dialog);\n const viewport = inject(KtViewport);\n // Optionnel : hors d'un arbre de vue (ex. service root), il n'y a pas de ViewContainerRef.\n const viewContainerRef = inject(ViewContainerRef, { optional: true }) ?? undefined;\n const idGen = inject(KtIdGenerator);\n\n return (data?: D, config?: OpenerConfig<D, R, C>): DialogRef<R, C> => {\n // La présentation (choisie par le dev) est résolue ICI, à l'ouverture : les variantes\n // responsive lisent le signal d'écran compact. Le panelClass final = présentation concrète + extras.\n const { presentation, panelClass, ...rest } = { ...baseConfig, ...config };\n const extra = panelClass ? (Array.isArray(panelClass) ? panelClass : [panelClass]) : [];\n // Dédoublonné : une classe déjà fournie par la présentation (ex. `kt-dialog`) et repassée\n // en `panelClass` par le consommateur ne doit pas apparaître deux fois.\n const merged = [...new Set([...resolveKtDialogPanelClass(presentation, viewport.isCompact()), ...extra])];\n\n const uid = idGen.generateId();\n const titleId = `kt-dialog-title-${uid}`;\n const descId = `kt-dialog-desc-${uid}`;\n\n return dialog.open<R, D, C>(component, {\n viewContainerRef,\n container: KtDialogContainer,\n ariaLabelledBy: titleId,\n ariaDescribedBy: descId,\n ...rest,\n panelClass: merged,\n data,\n } as DialogConfig<D, DialogRef<R, C>>);\n };\n}\n","import { KtDialogTitle } from './dialog-title.directive';\nimport { KtDialogDescription } from './dialog-description.directive';\nimport { KtDialogClose } from './dialog-close.directive';\nimport {\n KtDialogHeader,\n KtDialogContent,\n KtDialogActions,\n KtDialogFocusInitial,\n KtDialogSheetHandle,\n} from './dialog-structure';\n\nexport * from './dialog-title.directive';\nexport * from './dialog-description.directive';\nexport * from './dialog-close.directive';\nexport * from './dialog-structure';\nexport * from './dialog-config';\nexport * from './dialog-opener';\nexport * from './dialog-container';\n\n/**\n * Import ergonomique de toute la famille dialog en une fois :\n * `imports: [KT_DIALOG]` au lieu d'énumérer chaque directive structurelle.\n */\nexport const KT_DIALOG = [\n KtDialogHeader,\n KtDialogTitle,\n KtDialogDescription,\n KtDialogContent,\n KtDialogActions,\n KtDialogClose,\n KtDialogFocusInitial,\n KtDialogSheetHandle,\n] as const;\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":";;;;;;;;AAIA;;;;;;;;;;;;;;AAcG;MAKU,aAAa,CAAA;IACP,SAAS,GAAG,MAAM,CAAqB,SAAS,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;AACrE,IAAA,IAAI,GAAG,MAAM,CAA0B,UAAU,CAAC,CAAC,aAAa;AAChE,IAAA,QAAQ,GAAG,MAAM,CAAC,SAAS,CAAC;AAC5B,IAAA,KAAK,GAAG,MAAM,CAAC,aAAa,CAAC;;IAGrC,EAAE,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,IAAI,IAAI,CAAC,SAAS,EAAE,MAAM,CAAC,cAAc,IAAI,CAAA,gBAAA,EAAmB,IAAI,CAAC,KAAK,CAAC,UAAU,EAAE,CAAA,CAAE;AAEnH,IAAA,WAAA,GAAA;QACE,MAAM,aAAa,GAAG,IAAI,CAAC,SAAS,EAAE,MAAM,CAAC,cAAc;QAC3D,IAAI,CAAC,aAAa,EAAE;AAClB,YAAA,IAAI,IAAI,CAAC,SAAS,EAAE;gBAClB,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,cAAc,GAAG,IAAI,CAAC,EAAE;YAChD;YACA,eAAe,CAAC,MAAK;gBACnB,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,uBAAuB,CAAC;AAC5D,gBAAA,IAAI,SAAS;AAAE,oBAAA,IAAI,CAAC,QAAQ,CAAC,YAAY,CAAC,SAAS,EAAE,iBAAiB,EAAE,IAAI,CAAC,EAAE,CAAC;AAClF,YAAA,CAAC,CAAC;QACJ;IACF;uGApBW,aAAa,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;2FAAb,aAAa,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,UAAA,EAAA,EAAA,IAAA,EAAA,IAAA,EAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,CAAA;;2FAAb,aAAa,EAAA,UAAA,EAAA,CAAA;kBAJzB,SAAS;AAAC,YAAA,IAAA,EAAA,CAAA;AACT,oBAAA,QAAQ,EAAE,iBAAiB;AAC3B,oBAAA,IAAI,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE;AACvB,iBAAA;;;AClBD;;;;;;;;;;;;;;AAcG;MAKU,mBAAmB,CAAA;IACb,SAAS,GAAG,MAAM,CAAqB,SAAS,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;AACrE,IAAA,IAAI,GAAG,MAAM,CAA0B,UAAU,CAAC,CAAC,aAAa;AAChE,IAAA,QAAQ,GAAG,MAAM,CAAC,SAAS,CAAC;AAC5B,IAAA,KAAK,GAAG,MAAM,CAAC,aAAa,CAAC;;IAGrC,EAAE,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,IAAI,IAAI,CAAC,SAAS,EAAE,MAAM,CAAC,eAAe,IAAI,CAAA,eAAA,EAAkB,IAAI,CAAC,KAAK,CAAC,UAAU,EAAE,CAAA,CAAE;AAEnH,IAAA,WAAA,GAAA;QACE,MAAM,aAAa,GAAG,IAAI,CAAC,SAAS,EAAE,MAAM,CAAC,eAAe;QAC5D,IAAI,CAAC,aAAa,EAAE;AAClB,YAAA,IAAI,IAAI,CAAC,SAAS,EAAE;gBAClB,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,eAAe,GAAG,IAAI,CAAC,EAAE;YACjD;YACA,eAAe,CAAC,MAAK;gBACnB,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,uBAAuB,CAAC;AAC5D,gBAAA,IAAI,SAAS;AAAE,oBAAA,IAAI,CAAC,QAAQ,CAAC,YAAY,CAAC,SAAS,EAAE,kBAAkB,EAAE,IAAI,CAAC,EAAE,CAAC;AACnF,YAAA,CAAC,CAAC;QACJ;IACF;IAEA,QAAQ,GAAA;AACN,QAAA,IAAI,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,eAAe,KAAK,IAAI,CAAC,EAAE,EAAE;YACvE,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,eAAe,GAAG,IAAI,CAAC,EAAE;QACjD;IACF;IAEA,WAAW,GAAA;AACT,QAAA,IAAI,IAAI,CAAC,SAAS,EAAE,MAAM,CAAC,eAAe,KAAK,IAAI,CAAC,EAAE,EAAE;YACtD,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,eAAe,GAAG,IAAI;QAC9C;IACF;uGAhCW,mBAAmB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;2FAAnB,mBAAmB,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,uBAAA,EAAA,IAAA,EAAA,EAAA,UAAA,EAAA,EAAA,IAAA,EAAA,IAAA,EAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,CAAA;;2FAAnB,mBAAmB,EAAA,UAAA,EAAA,CAAA;kBAJ/B,SAAS;AAAC,YAAA,IAAA,EAAA,CAAA;AACT,oBAAA,QAAQ,EAAE,uBAAuB;AACjC,oBAAA,IAAI,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE;AACvB,iBAAA;;;ACnBD;;;;;;;;;;;;AAYG;MAQU,aAAa,CAAA;IACP,SAAS,GAAG,MAAM,CAAqB,SAAS,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;AACrE,IAAA,IAAI,GAAG,MAAM,CAA0B,UAAU,CAAC,CAAC,aAAa;AAEjF;;;AAGG;IACM,YAAY,GAAG,KAAK,CAAU,SAAS,oFAAI,KAAK,EAAE,eAAe,EAAA,CAAG;;AAG1D,IAAA,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,KAAK,QAAQ,GAAG,QAAQ,GAAG,IAAI;AAEhF,IAAA,WAAA,GAAA;;QAEE,eAAe,CAAC,MAAK;YACnB,IAAI,CAAC,SAAS,EAAE;gBAAE;AAElB,YAAA,MAAM,KAAK,GACT,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,IAAI,EAAE,EAAE,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC;AAC/C,gBAAA,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,YAAY,CAAC;AACpC,gBAAA,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,iBAAiB,CAAC;YAC3C,IAAI,CAAC,KAAK,EAAE;gBACV,OAAO,CAAC,IAAI,CACV,yEAAyE;AACvE,oBAAA,0DAA0D,CAC7D;YACH;AACF,QAAA,CAAC,CAAC;IACJ;IAEU,KAAK,GAAA;QACb,IAAI,CAAC,SAAS,EAAE,KAAK,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC;IAC5C;uGAjCW,aAAa,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;2FAAb,aAAa,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,iBAAA,EAAA,MAAA,EAAA,EAAA,YAAA,EAAA,EAAA,iBAAA,EAAA,cAAA,EAAA,UAAA,EAAA,eAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,EAAA,IAAA,EAAA,EAAA,SAAA,EAAA,EAAA,OAAA,EAAA,SAAA,EAAA,EAAA,UAAA,EAAA,EAAA,WAAA,EAAA,YAAA,EAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,CAAA;;2FAAb,aAAa,EAAA,UAAA,EAAA,CAAA;kBAPzB,SAAS;AAAC,YAAA,IAAA,EAAA,CAAA;AACT,oBAAA,QAAQ,EAAE,iBAAiB;AAC3B,oBAAA,IAAI,EAAE;AACJ,wBAAA,aAAa,EAAE,YAAY;AAC3B,wBAAA,SAAS,EAAE,SAAS;AACrB,qBAAA;AACF,iBAAA;;;ACjBD;;;;;;;;;;;;;;;;AAgBG;MAEU,cAAc,CAAA;uGAAd,cAAc,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;2FAAd,cAAc,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,kBAAA,EAAA,QAAA,EAAA,EAAA,EAAA,CAAA;;2FAAd,cAAc,EAAA,UAAA,EAAA,CAAA;kBAD1B,SAAS;mBAAC,EAAE,QAAQ,EAAE,kBAAkB,EAAE;;AAG3C;;;;;;;;AAQG;MAEU,eAAe,CAAA;uGAAf,eAAe,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;2FAAf,eAAe,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,mBAAA,EAAA,QAAA,EAAA,EAAA,EAAA,CAAA;;2FAAf,eAAe,EAAA,UAAA,EAAA,CAAA;kBAD3B,SAAS;mBAAC,EAAE,QAAQ,EAAE,mBAAmB,EAAE;;AAG5C;;;;;;;;;;;;AAYG;MAEU,eAAe,CAAA;uGAAf,eAAe,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;2FAAf,eAAe,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,mBAAA,EAAA,QAAA,EAAA,EAAA,EAAA,CAAA;;2FAAf,eAAe,EAAA,UAAA,EAAA,CAAA;kBAD3B,SAAS;mBAAC,EAAE,QAAQ,EAAE,mBAAmB,EAAE;;AAG5C;;;;;;;;;AASG;MAEU,oBAAoB,CAAA;uGAApB,oBAAoB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;2FAApB,oBAAoB,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,wBAAA,EAAA,QAAA,EAAA,EAAA,EAAA,CAAA;;2FAApB,oBAAoB,EAAA,UAAA,EAAA,CAAA;kBADhC,SAAS;mBAAC,EAAE,QAAQ,EAAE,wBAAwB,EAAE;;AAGjD;;;;;;;;;;;;;;;;;AAiBG;MASU,mBAAmB,CAAA;IACb,SAAS,GAAG,MAAM,CAAqB,SAAS,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;AACrE,IAAA,IAAI,GAAG,MAAM,CAA0B,UAAU,CAAC,CAAC,aAAa;AAChE,IAAA,UAAU,GAAG,MAAM,CAAC,UAAU,CAAC;;IAG/B,IAAI,GAAG,iBAAiB,CAAC;QACxC,IAAI,EAAE,MAAM,IAAI,CAAC,IAAI,CAAC,OAAO,CAAc,uBAAuB,CAAC;QACnE,SAAS,EAAE,MAAM,IAAI,CAAC,SAAS,EAAE,KAAK,EAAE;AACxC,QAAA,aAAa,EAAE,2BAA2B;AAC3C,KAAA,CAAC;AAEF,IAAA,WAAA,GAAA;AACE,QAAA,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;IACtD;AAEU,IAAA,OAAO,CAAC,KAAmB,EAAA;;QAEnC,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,mBAAmB,CAAC;QACnD,IAAI,CAAC,IAAI,EAAE,SAAS,CAAC,QAAQ,CAAC,kBAAkB,CAAC;YAAE;AACnD,QAAA,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC;IACxB;uGArBW,mBAAmB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;2FAAnB,mBAAmB,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,uBAAA,EAAA,IAAA,EAAA,EAAA,UAAA,EAAA,EAAA,aAAA,EAAA,MAAA,EAAA,EAAA,SAAA,EAAA,EAAA,aAAA,EAAA,iBAAA,EAAA,WAAA,EAAA,yBAAA,EAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,CAAA;;2FAAnB,mBAAmB,EAAA,UAAA,EAAA,CAAA;kBAR/B,SAAS;AAAC,YAAA,IAAA,EAAA,CAAA;AACT,oBAAA,QAAQ,EAAE,uBAAuB;AACjC,oBAAA,IAAI,EAAE;AACJ,wBAAA,eAAe,EAAE,iBAAiB;AAClC,wBAAA,aAAa,EAAE,yBAAyB;AACxC,wBAAA,aAAa,EAAE,MAAM;AACtB,qBAAA;AACF,iBAAA;;;ACxFD;;;;;;;;;AASG;AACI,MAAM,sBAAsB,GAAiB;AAClD,IAAA,IAAI,EAAE,QAAQ;AACd,IAAA,SAAS,EAAE,IAAI;AACf,IAAA,SAAS,EAAE,wBAAwB;AACnC,IAAA,YAAY,EAAE,IAAI;AAClB,IAAA,WAAW,EAAE,IAAI;AACjB,IAAA,UAAU,EAAE,WAAW;AACvB,IAAA,aAAa,EAAE,qBAAqB;;AAGtC;;;;AAIG;AACG,SAAU,uBAAuB,CAAC,SAAiC,EAAA;IACvE,OAAO;AACL,QAAA,OAAO,EAAE,qBAAqB;AAC9B,QAAA,QAAQ,EAAE,EAAE,GAAG,sBAAsB,EAAE,GAAG,SAAS,EAAE;KACtD;AACH;AAeA;AACA,SAAS,wBAAwB,CAAC,CAAsC,EAAA;IACtE,IAAI,CAAC,KAAK,YAAY;AAAE,QAAA,OAAO,CAAC,WAAW,EAAE,uBAAuB,CAAC;IACrE,IAAI,CAAC,KAAK,OAAO;AAAE,QAAA,OAAO,CAAC,WAAW,EAAE,kBAAkB,CAAC;IAC3D,OAAO,CAAC,WAAW,CAAC;AACtB;AAEA;;;;;AAKG;AACG,SAAU,yBAAyB,CAAC,YAAA,GAAqC,UAAU,EAAE,OAAO,GAAG,KAAK,EAAA;AACxG,IAAA,IAAI,YAAY,KAAK,UAAU,IAAI,YAAY,KAAK,YAAY,IAAI,YAAY,KAAK,OAAO,EAAE;AAC5F,QAAA,OAAO,wBAAwB,CAAC,YAAY,CAAC;IAC/C;AACA,IAAA,IAAI,YAAY,KAAK,qBAAqB,EAAE;AAC1C,QAAA,OAAO,wBAAwB,CAAC,OAAO,GAAG,YAAY,GAAG,UAAU,CAAC;IACtE;AACA,IAAA,OAAO,wBAAwB,CAAC,OAAO,GAAG,OAAO,GAAG,UAAU,CAAC,CAAC;AAClE;;AC3CM,MAAO,iBAAkB,SAAQ,kBAAkB,CAAA;AACtC,IAAA,SAAS,GAAG,MAAM,CAAC,SAAS,CAAC;AAC7B,IAAA,UAAU,GAAG,MAAM,CAAC,UAAU,CAAC;AAC/B,IAAA,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC,aAA4B;AACnD,IAAA,UAAU,GAAG,MAAM,CAAC,WAAW,CAAC;IAE9B,SAAS,GAAG,MAAM,CAAC,KAAK;kFAAC;AAE5C,IAAA,WAAA,GAAA;AACE,QAAA,KAAK,EAAE;;AAEP,QAAA,MAAM,aAAa,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC;QAC/D,IAAI,CAAC,SAAS,CAAC,KAAK,GAAG,CAAC,MAAgB,KAAI;AAC1C,YAAA,IAAI,CAAC,eAAe,CAAC,MAAM,EAAE,aAAa,CAAC;AAC7C,QAAA,CAAC;IACH;IAEA,QAAQ,GAAA;;AAEN,QAAA,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,YAAY,EAAE;AAC9B,YAAA,IAAI,CAAC,SAAS,CAAC,aAAa,CAAC,SAAS,CAAC,MAAM,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,CAAC;YACpE,IAAI,CAAC,SAAS,CAAC,aAAa,CAAC,SAAS,CAAC,CAAC,KAAoB,KAAI;AAC9D,gBAAA,IAAI,KAAK,CAAC,GAAG,KAAK,QAAQ,EAAE;oBAC1B,KAAK,CAAC,cAAc,EAAE;AACtB,oBAAA,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE;gBACxB;AACF,YAAA,CAAC,CAAC;QACJ;IACF;IAEU,OAAO,GAAA;AACf,QAAA,OAAO,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,QAAQ,CAAC,kBAAkB,CAAC,IAAI,KAAK;IACvE;IAEQ,eAAe,CAAC,MAAe,EAAE,eAAsC,EAAA;QAC7E,IAAI,IAAI,CAAC,SAAS,EAAE;YAAE;AACtB,QAAA,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC;QAExB,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE;YACvC,eAAe,CAAC,MAAM,CAAC;YACvB;QACF;;QAGA,MAAM,MAAM,GAAG,MAAM,CAAC,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC;AACjD,QAAA,MAAM,WAAW,GAAG,MAAM,CAAC,kBAAkB,IAAI,IAAI;QACrD,MAAM,UAAU,GAAG,UAAU,CAAC,WAAW,CAAC,IAAI,WAAW,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC;AAEpF,QAAA,IAAI,UAAU,KAAK,CAAC,EAAE;YACpB,eAAe,CAAC,MAAM,CAAC;YACvB;QACF;;AAGA,QAAA,MAAM,eAAe,GAAG,CAAC,KAAsB,KAAI;AACjD,YAAA,IAAI,KAAK,CAAC,MAAM,KAAK,IAAI,CAAC,IAAI,IAAI,KAAK,CAAC,YAAY,KAAK,WAAW,EAAE;gBACpE,IAAI,CAAC,IAAI,CAAC,mBAAmB,CAAC,eAAe,EAAE,eAAe,CAAC;gBAC/D,eAAe,CAAC,MAAM,CAAC;YACzB;AACF,QAAA,CAAC;QACD,IAAI,CAAC,IAAI,CAAC,gBAAgB,CAAC,eAAe,EAAE,eAAe,CAAC;;QAG5D,UAAU,CAAC,MAAK;YACd,IAAI,CAAC,IAAI,CAAC,mBAAmB,CAAC,eAAe,EAAE,eAAe,CAAC;YAC/D,eAAe,CAAC,MAAM,CAAC;AACzB,QAAA,CAAC,EAAE,UAAU,GAAG,EAAE,CAAC;IACrB;uGAnEW,iBAAiB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAAjB,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,iBAAiB,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,qBAAA,EAAA,IAAA,EAAA,EAAA,UAAA,EAAA,EAAA,UAAA,EAAA,IAAA,EAAA,EAAA,UAAA,EAAA,EAAA,SAAA,EAAA,oBAAA,EAAA,WAAA,EAAA,cAAA,EAAA,iBAAA,EAAA,mBAAA,EAAA,sBAAA,EAAA,oDAAA,EAAA,iBAAA,EAAA,mBAAA,EAAA,uBAAA,EAAA,iCAAA,EAAA,kCAAA,EAAA,WAAA,EAAA,oCAAA,EAAA,aAAA,EAAA,EAAA,cAAA,EAAA,0CAAA,EAAA,EAAA,eAAA,EAAA,IAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,EANlB;;;;AAIT,EAAA,CAAA,EAAA,QAAA,EAAA,IAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EAjBS,YAAY,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,eAAA,EAAA,QAAA,EAAA,mBAAA,EAAA,MAAA,EAAA,CAAA,iBAAA,CAAA,EAAA,OAAA,EAAA,CAAA,UAAA,CAAA,EAAA,QAAA,EAAA,CAAA,iBAAA,CAAA,EAAA,CAAA,EAAA,CAAA;;2FAmBX,iBAAiB,EAAA,UAAA,EAAA,CAAA;kBArB7B,SAAS;AAAC,YAAA,IAAA,EAAA,CAAA;AACT,oBAAA,QAAQ,EAAE,qBAAqB;oBAC/B,OAAO,EAAE,CAAC,YAAY,CAAC;AACvB,oBAAA,IAAI,EAAE;AACJ,wBAAA,KAAK,EAAE,0CAA0C;AACjD,wBAAA,QAAQ,EAAE,IAAI;AACd,wBAAA,WAAW,EAAE,oBAAoB;AACjC,wBAAA,aAAa,EAAE,cAAc;AAC7B,wBAAA,mBAAmB,EAAE,mBAAmB;AACxC,wBAAA,wBAAwB,EAAE,oDAAoD;AAC9E,wBAAA,mBAAmB,EAAE,mBAAmB;AACxC,wBAAA,yBAAyB,EAAE,iCAAiC;AAC5D,wBAAA,oCAAoC,EAAE,WAAW;AACjD,wBAAA,sCAAsC,EAAE,aAAa;AACtD,qBAAA;AACD,oBAAA,QAAQ,EAAE;;;;AAIT,EAAA,CAAA;AACF,iBAAA;;;ACjBD;;;;;;;;;;;;;;AAcG;SACa,kBAAkB,GAAA;AAChC,IAAA,OAAO,MAAM,CAAI,WAAW,CAAC;AAC/B;AAyCM,SAAU,oBAAoB,CAClC,SAA2B,EAC3B,UAAkC,EAAA;AAElC,IAAA,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;AAC7B,IAAA,MAAM,QAAQ,GAAG,MAAM,CAAC,UAAU,CAAC;;AAEnC,IAAA,MAAM,gBAAgB,GAAG,MAAM,CAAC,gBAAgB,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,IAAI,SAAS;AAClF,IAAA,MAAM,KAAK,GAAG,MAAM,CAAC,aAAa,CAAC;AAEnC,IAAA,OAAO,CAAC,IAAQ,EAAE,MAA8B,KAAqB;;;AAGnE,QAAA,MAAM,EAAE,YAAY,EAAE,UAAU,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,UAAU,EAAE,GAAG,MAAM,EAAE;AAC1E,QAAA,MAAM,KAAK,GAAG,UAAU,IAAI,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,GAAG,UAAU,GAAG,CAAC,UAAU,CAAC,IAAI,EAAE;;;QAGvF,MAAM,MAAM,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,yBAAyB,CAAC,YAAY,EAAE,QAAQ,CAAC,SAAS,EAAE,CAAC,EAAE,GAAG,KAAK,CAAC,CAAC,CAAC;AAEzG,QAAA,MAAM,GAAG,GAAG,KAAK,CAAC,UAAU,EAAE;AAC9B,QAAA,MAAM,OAAO,GAAG,CAAA,gBAAA,EAAmB,GAAG,EAAE;AACxC,QAAA,MAAM,MAAM,GAAG,CAAA,eAAA,EAAkB,GAAG,EAAE;AAEtC,QAAA,OAAO,MAAM,CAAC,IAAI,CAAU,SAAS,EAAE;YACrC,gBAAgB;AAChB,YAAA,SAAS,EAAE,iBAAiB;AAC5B,YAAA,cAAc,EAAE,OAAO;AACvB,YAAA,eAAe,EAAE,MAAM;AACvB,YAAA,GAAG,IAAI;AACP,YAAA,UAAU,EAAE,MAAM;YAClB,IAAI;AAC+B,SAAA,CAAC;AACxC,IAAA,CAAC;AACH;;AChFA;;;AAGG;AACI,MAAM,SAAS,GAAG;IACvB,cAAc;IACd,aAAa;IACb,mBAAmB;IACnB,eAAe;IACf,eAAe;IACf,aAAa;IACb,oBAAoB;IACpB,mBAAmB;;;AC/BrB;;AAEG;;;;"}
|
|
1
|
+
{"version":3,"file":"ktortu-aaa-dialog.mjs","sources":["../../../../projects/ktortu/aaa/dialog/dialog-title.directive.ts","../../../../projects/ktortu/aaa/dialog/dialog-description.directive.ts","../../../../projects/ktortu/aaa/dialog/dialog-close.directive.ts","../../../../projects/ktortu/aaa/dialog/dialog-structure.ts","../../../../projects/ktortu/aaa/dialog/dialog-config.ts","../../../../projects/ktortu/aaa/dialog/dialog-container.ts","../../../../projects/ktortu/aaa/dialog/dialog-opener.ts","../../../../projects/ktortu/aaa/dialog/public-api.ts","../../../../projects/ktortu/aaa/dialog/ktortu-aaa-dialog.ts"],"sourcesContent":["import { DialogRef } from '@angular/cdk/dialog';\nimport { Directive, ElementRef, Renderer2, afterNextRender, inject } from '@angular/core';\nimport { KtIdGenerator } from '@ktortu/aaa/cdk';\n\n/**\n * À poser sur le titre VISIBLE (idéalement un `<h2>`) du contenu d'un CDK Dialog.\n * Câble `aria-labelledby` du conteneur de dialogue.\n *\n * Pourquoi écrire l'attribut directement (Renderer2) plutôt que seulement `_addAriaLabelledBy` :\n * sous change detection ZONELESS (cas par défaut moderne), le `markForCheck()` interne du\n * conteneur ne rafraîchit pas ses host bindings à l'ouverture, donc l'attribut n'apparaîtrait\n * jamais. On écrit donc l'attribut nous-mêmes (fiable, indépendant de la CD) ET on alimente la\n * file CDK pour rester cohérent si un cycle de CD survient ensuite.\n *\n * @example\n * ```html\n * <h2 ktDialogTitle>Renommer le fichier</h2>\n * ```\n */\n@Directive({\n selector: '[ktDialogTitle]',\n host: { '[id]': 'id' },\n})\nexport class KtDialogTitle {\n private readonly dialogRef = inject<DialogRef<unknown>>(DialogRef, { optional: true });\n private readonly host = inject<ElementRef<HTMLElement>>(ElementRef).nativeElement;\n private readonly renderer = inject(Renderer2);\n private readonly idGen = inject(KtIdGenerator);\n\n /**\n * Id de l'hôte câblé en `aria-labelledby` : préserve un id fourni par le consommateur, sinon en génère un.\n * @default `host.id` ?? `dialogRef.config.ariaLabelledBy` ?? `kt-dialog-title-<généré>`\n */\n readonly id =\n this.host.id || this.dialogRef?.config.ariaLabelledBy || `kt-dialog-title-${this.idGen.generateId('dialog')}`;\n\n constructor() {\n const preConfigured = this.dialogRef?.config.ariaLabelledBy;\n if (!preConfigured) {\n if (this.dialogRef) {\n this.dialogRef.config.ariaLabelledBy = this.id;\n }\n afterNextRender(() => {\n const container = this.host.closest('.cdk-dialog-container');\n if (container) this.renderer.setAttribute(container, 'aria-labelledby', this.id);\n });\n }\n }\n}\n","import { DialogRef } from '@angular/cdk/dialog';\nimport { Directive, ElementRef, OnDestroy, OnInit, Renderer2, afterNextRender, inject } from '@angular/core';\nimport { KtIdGenerator } from '@ktortu/aaa/cdk';\n\n/**\n * À poser sur le paragraphe descriptif COURT du dialog : câble `aria-describedby` du conteneur\n * (texte lu par le lecteur d'écran juste après le titre, à l'ouverture).\n *\n * ⚠️ Ne JAMAIS appliquer sur un formulaire ou un long contenu : `aria-describedby` concatène\n * tout le texte du nœud et serait lu d'un bloc à l'ouverture. Réserver à une phrase de contexte.\n *\n * Écriture directe de l'attribut (Renderer2) pour la même raison que `ktDialogTitle` :\n * fiabilité sous change detection zoneless. La config est tenue à jour pour cohérence CDK.\n *\n * @example\n * ```html\n * <p ktDialogDescription>Cette action est définitive.</p>\n * ```\n */\n@Directive({\n selector: '[ktDialogDescription]',\n host: { '[id]': 'id' },\n})\nexport class KtDialogDescription implements OnInit, OnDestroy {\n private readonly dialogRef = inject<DialogRef<unknown>>(DialogRef, { optional: true });\n private readonly host = inject<ElementRef<HTMLElement>>(ElementRef).nativeElement;\n private readonly renderer = inject(Renderer2);\n private readonly idGen = inject(KtIdGenerator);\n\n /**\n * Id de l'hôte câblé en `aria-describedby` : préserve un id fourni par le consommateur, sinon en génère un.\n * @default `host.id` ?? `dialogRef.config.ariaDescribedBy` ?? `kt-dialog-desc-<généré>`\n */\n readonly id =\n this.host.id || this.dialogRef?.config.ariaDescribedBy || `kt-dialog-desc-${this.idGen.generateId('dialog')}`;\n\n constructor() {\n const preConfigured = this.dialogRef?.config.ariaDescribedBy;\n if (!preConfigured) {\n if (this.dialogRef) {\n this.dialogRef.config.ariaDescribedBy = this.id;\n }\n afterNextRender(() => {\n const container = this.host.closest('.cdk-dialog-container');\n if (container) this.renderer.setAttribute(container, 'aria-describedby', this.id);\n });\n }\n }\n\n ngOnInit(): void {\n // Asymétrie ASSUMÉE avec `ktDialogTitle` : la description peut porter un `id` d'hôte fourni par\n // le consommateur ; on aligne alors `config.ariaDescribedBy` dessus (le host binding live du\n // conteneur reflète la valeur). Un titre est posé une fois et n'a pas ce besoin.\n if (this.dialogRef && this.dialogRef.config.ariaDescribedBy !== this.id) {\n this.dialogRef.config.ariaDescribedBy = this.id;\n }\n }\n\n ngOnDestroy(): void {\n if (this.dialogRef?.config.ariaDescribedBy === this.id) {\n this.dialogRef.config.ariaDescribedBy = null;\n }\n }\n}\n","import { DialogRef } from '@angular/cdk/dialog';\nimport { Directive, ElementRef, afterNextRender, inject, input, isDevMode } from '@angular/core';\n\n/**\n * Ferme le CDK Dialog au clic, avec un résultat optionnel renvoyé à l'ouvreur via\n * `DialogRef.close(result)`. Se compose avec `[ktButton]` sur le même `<button>`.\n *\n * Réservé au DISMISS simple (Annuler / Fermer). Pour valider un formulaire, injectez\n * `DialogRef` dans votre composant et appelez `close(valeur)` après validation.\n *\n * @example\n * ```html\n * <button ktButton ktDialogClose>Annuler</button>\n * <button ktButton [ktDialogClose]=\"'confirm'\">Confirmer</button>\n * ```\n */\n@Directive({\n selector: '[ktDialogClose]',\n host: {\n '[attr.type]': 'buttonType',\n '(click)': 'close()',\n },\n})\nexport class KtDialogClose {\n private readonly dialogRef = inject<DialogRef<unknown>>(DialogRef, { optional: true });\n private readonly host = inject<ElementRef<HTMLElement>>(ElementRef).nativeElement;\n\n /**\n * Valeur renvoyée à l'ouvreur via `DialogRef.close(result)`. Liée par l'alias `ktDialogClose`\n * (= nom du sélecteur), d'où l'usage `[ktDialogClose]=\"'confirm'\"`. @default undefined\n */\n readonly dialogResult = input<unknown>(undefined, { alias: 'ktDialogClose' });\n\n // Force type=\"button\" sur un <button> (évite le submit implicite dans un <form>).\n protected readonly buttonType = this.host.tagName === 'BUTTON' ? 'button' : null;\n\n constructor() {\n // Garde-fou a11y (dev) : un bouton de fermeture doit avoir un nom accessible (WCAG 4.1.2).\n afterNextRender(() => {\n if (!isDevMode()) return;\n\n const named =\n (this.host.textContent ?? '').trim().length > 0 ||\n this.host.hasAttribute('aria-label') ||\n this.host.hasAttribute('aria-labelledby');\n if (!named) {\n console.warn(\n '[ktDialogClose] Bouton de fermeture sans nom accessible (WCAG 4.1.2) : ' +\n 'ajoutez du texte visible, aria-label ou aria-labelledby.',\n );\n }\n });\n }\n\n protected close(): void {\n this.dialogRef?.close(this.dialogResult());\n }\n}\n","import { DestroyRef, Directive, ElementRef, inject } from '@angular/core';\nimport { DialogRef } from '@angular/cdk/dialog';\n\nimport { createKtSheetDrag } from '@ktortu/aaa/cdk';\n\n/**\n * En-tête RICHE et OPTIONNEL du dialog : rangée flex pour composer une icône, le titre et/ou un\n * bouton de fermeture. Marqueur structurel sans logique — la mise en forme (flex, padding de\n * région, reset du padding du [ktDialogTitle] qu'il enveloppe) vit dans `dialog.css`.\n *\n * Sépare le LAYOUT (cette région) de l'ÉTIQUETTE ACCESSIBLE ([ktDialogTitle], qui garde\n * aria-labelledby). En usage simple — titre nu sans header — [ktDialogTitle] conserve son propre\n * padding : ce header n'est à utiliser que pour les en-têtes composés (icône, close top-right…).\n *\n * @example\n * ```html\n * <header ktDialogHeader>\n * <h2 ktDialogTitle>Titre</h2>\n * <button ktButton ktDialogClose aria-label=\"Fermer\">✕</button>\n * </header>\n * ```\n */\n@Directive({ selector: '[ktDialogHeader]' })\nexport class KtDialogHeader {}\n\n/**\n * Zone de contenu du dialog. Marqueur structurel sans logique : la mise en forme\n * (rythme vertical) vit dans `dialog.css` via le sélecteur `[ktDialogContent]`.\n *\n * @example\n * ```html\n * <div ktDialogContent>…</div>\n * ```\n */\n@Directive({ selector: '[ktDialogContent]' })\nexport class KtDialogContent {}\n\n/**\n * Barre d'actions du dialog (rangée de boutons). Marqueur structurel sans logique :\n * la mise en forme (flex, gap, sticky bas pour le Reflow AAA) vit dans `dialog.css`\n * via le sélecteur `[ktDialogActions]`.\n *\n * @example\n * ```html\n * <footer ktDialogActions>\n * <button ktButton ktDialogClose>Annuler</button>\n * <button ktButton [ktDialogClose]=\"'ok'\">Valider</button>\n * </footer>\n * ```\n */\n@Directive({ selector: '[ktDialogActions]' })\nexport class KtDialogActions {}\n\n/**\n * Marque l'élément à focaliser à l'ouverture. À coupler avec la config CDK\n * `autoFocus: '[ktDialogFocusInitial]'` (incluse dans `provideKtDialogDefaults`).\n * Permet d'éviter que le focus initial tombe sur une action destructrice.\n *\n * @example\n * ```html\n * <input ktDialogFocusInitial type=\"text\" />\n * ```\n */\n@Directive({ selector: '[ktDialogFocusInitial]' })\nexport class KtDialogFocusInitial {}\n\n/**\n * Poignée de préhension d'un dialog en mode `sheet` (bottom-sheet) : drag-to-dismiss vers le bas,\n * FACTORISÉ avec le Select via `createKtSheetDrag` (@ktortu/aaa). Geste DOUBLÉ par Échap + bouton\n * Fermer + clic sur le scrim (WCAG 2.5.1) — décoratif (`aria-hidden`).\n *\n * À poser sur la barre de préhension, premier enfant du contenu d'un dialog ouvert avec une\n * présentation `sheet` / `centered-sheet`. Le drag n'est actif que si le dialog est EFFECTIVEMENT\n * en mode sheet (la pane porte `kt-dialog--sheet`) — pas de dépendance au viewport : un `sheet`\n * toujours-bottom-sheet se drague aussi à la souris.\n *\n * @example\n * ```html\n * <div ktDialogContent>\n * <div ktDialogSheetHandle></div>\n * …\n * </div>\n * ```\n */\n@Directive({\n selector: '[ktDialogSheetHandle]',\n host: {\n '(pointerdown)': 'onStart($event)',\n '(mousedown)': '$event.preventDefault()',\n 'aria-hidden': 'true',\n },\n})\nexport class KtDialogSheetHandle {\n private readonly dialogRef = inject<DialogRef<unknown>>(DialogRef, { optional: true });\n private readonly host = inject<ElementRef<HTMLElement>>(ElementRef).nativeElement;\n private readonly destroyRef = inject(DestroyRef);\n\n // La feuille translatée = le conteneur CDK (position:fixed en mode sheet), trouvé en remontant.\n private readonly drag = createKtSheetDrag({\n pane: () => this.host.closest<HTMLElement>('.cdk-dialog-container'),\n onDismiss: () => this.dialogRef?.close(),\n draggingClass: 'kt-dialog-sheet--dragging',\n });\n\n constructor() {\n this.destroyRef.onDestroy(() => this.drag.destroy());\n }\n\n protected onStart(event: PointerEvent): void {\n // Actif seulement quand la PRÉSENTATION choisie par le dev est `sheet` (classe sur la pane).\n const pane = this.host.closest('.cdk-overlay-pane');\n if (!pane?.classList.contains('kt-dialog--sheet')) return;\n this.drag.start(event);\n }\n}\n","import { DEFAULT_DIALOG_CONFIG, DialogConfig } from '@angular/cdk/dialog';\nimport { Provider } from '@angular/core';\n\n/**\n * Valeurs par défaut orientées AAA pour `@angular/cdk/dialog`.\n * - `ariaModal: true` : explicite (le CDK le laisse OFF par défaut).\n * - `restoreFocus: true` : rend le focus au déclencheur à la fermeture.\n * - `panelClass` / `backdropClass` : crochets de style consommés par `dialog.css`.\n *\n * Pour focaliser un élément précis à l'ouverture (ex. éviter un bouton destructeur),\n * passez `autoFocus: '[ktDialogFocusInitial]'` dans la config d'ouverture et posez la\n * directive `ktDialogFocusInitial` sur la cible.\n *\n * @example\n * ```ts\n * // valeur de base, généralement consommée via provideKtDialogDefaults()\n * provideKtDialogDefaults({ ...KT_DIALOG_AAA_DEFAULTS });\n * ```\n */\nexport const KT_DIALOG_AAA_DEFAULTS: DialogConfig = {\n role: 'dialog',\n ariaModal: true,\n autoFocus: '[ktDialogFocusInitial]',\n restoreFocus: true,\n hasBackdrop: true,\n panelClass: 'kt-dialog',\n backdropClass: 'kt-dialog__backdrop',\n};\n\n/**\n * Enregistre les valeurs par défaut AAA du dialog au niveau application.\n * À ajouter aux `providers` de `app.config.ts`. `overrides` permet d'ajuster sans\n * tout réécrire (ex. `provideKtDialogDefaults({ maxWidth: '40rem' })`).\n *\n * @example\n * ```ts\n * // app.config.ts\n * export const appConfig: ApplicationConfig = {\n * providers: [provideKtDialogDefaults({ maxWidth: '40rem' })],\n * };\n * ```\n * @param overrides Surcharges partielles fusionnées par-dessus `KT_DIALOG_AAA_DEFAULTS`.\n * @returns Un `Provider` pour le token `DEFAULT_DIALOG_CONFIG`.\n */\nexport function provideKtDialogDefaults(overrides?: Partial<DialogConfig>): Provider {\n return {\n provide: DEFAULT_DIALOG_CONFIG,\n useValue: { ...KT_DIALOG_AAA_DEFAULTS, ...overrides },\n };\n}\n\n/**\n * Présentation du dialog, CHOISIE EXPLICITEMENT PAR LE DÉVELOPPEUR à l'ouverture (option\n * `presentation` de `injectKtDialogOpener`). Aucune bascule CSS automatique : le dev décide.\n * - `centered` : toujours centré (ex. confirmation) — DÉFAUT ;\n * - `fullscreen` : toujours plein écran (desktop compris) ;\n * - `sheet` : toujours bottom-sheet (desktop compris) ;\n * - `centered-fullscreen` : centré sur desktop, plein écran sur téléphone compact ;\n * - `centered-sheet` : centré sur desktop, bottom-sheet sur téléphone compact.\n * Les variantes `centered-*` sont résolues EN JS à l'ouverture (signal `KtViewport.isCompact()`), pas par le CSS —\n * la classe CSS finale est donc toujours une présentation CONCRÈTE (centered/fullscreen/sheet).\n */\nexport type KtDialogPresentation = 'centered' | 'fullscreen' | 'sheet' | 'centered-fullscreen' | 'centered-sheet';\n\n/** panelClass d'une présentation CONCRÈTE (sans variante responsive). */\nfunction concreteDialogPanelClass(p: 'centered' | 'fullscreen' | 'sheet'): string[] {\n if (p === 'fullscreen') return ['kt-dialog', 'kt-dialog--fullscreen'];\n if (p === 'sheet') return ['kt-dialog', 'kt-dialog--sheet'];\n return ['kt-dialog'];\n}\n\n/**\n * Résout une `KtDialogPresentation` (responsive comprise) en panelClass concret. Pour les variantes\n * `centered-*`, l'appelant fournit `compact` (= `KtViewport.isCompact()`, largeur seule) — centré\n * sur desktop, plein écran / sheet sur écran compact. Fonction pure (testable sans DOM).\n * Appelée par `injectKtDialogOpener` à chaque ouverture ; exportée pour un usage direct éventuel.\n *\n * @example\n * ```ts\n * resolveKtDialogPanelClass('sheet'); // ['kt-dialog', 'kt-dialog--sheet']\n * resolveKtDialogPanelClass('centered-sheet', true); // bottom-sheet sur écran compact\n * ```\n * @param presentation Présentation choisie par le dev (responsive comprise). Défaut `'centered'`.\n * @param compact `true` quand l'écran est compact (= `KtViewport.isCompact()`), pour résoudre les variantes `centered-*`. Défaut `false`.\n * @returns La liste des classes CSS de la présentation concrète résolue.\n */\nexport function resolveKtDialogPanelClass(presentation: KtDialogPresentation = 'centered', compact = false): string[] {\n if (presentation === 'centered' || presentation === 'fullscreen' || presentation === 'sheet') {\n return concreteDialogPanelClass(presentation);\n }\n if (presentation === 'centered-fullscreen') {\n return concreteDialogPanelClass(compact ? 'fullscreen' : 'centered');\n }\n return concreteDialogPanelClass(compact ? 'sheet' : 'centered'); // 'centered-sheet'\n}\n","import {\n ChangeDetectionStrategy,\n Component,\n DestroyRef,\n ElementRef,\n OnInit,\n afterNextRender,\n isDevMode,\n signal,\n inject,\n PLATFORM_ID,\n} from '@angular/core';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\nimport { isPlatformBrowser } from '@angular/common';\nimport { CdkDialogContainer, DialogRef } from '@angular/cdk/dialog';\nimport { PortalModule } from '@angular/cdk/portal';\n\n@Component({\n selector: 'kt-dialog-container',\n changeDetection: ChangeDetectionStrategy.OnPush,\n imports: [PortalModule],\n host: {\n class: 'cdk-dialog-container kt-dialog-container',\n tabindex: '-1',\n '[attr.id]': '_config.id || null',\n '[attr.role]': '_config.role',\n '[attr.aria-modal]': '_config.ariaModal',\n '[attr.aria-labelledby]': '_config.ariaLabel ? null : _ariaLabelledByQueue[0]',\n '[attr.aria-label]': '_config.ariaLabel',\n '[attr.aria-describedby]': '_config.ariaDescribedBy || null',\n '[class.kt-dialog-container--sheet]': 'isSheet()',\n '[class.kt-dialog-container--closing]': 'isClosing()',\n },\n template: `\n <div class=\"kt-dialog-container__layout\">\n <ng-template cdkPortalOutlet></ng-template>\n </div>\n `,\n})\nexport class KtDialogContainer extends CdkDialogContainer implements OnInit {\n private readonly dialogRef = inject(DialogRef);\n private readonly elementRef = inject(ElementRef);\n private readonly host = this.elementRef.nativeElement as HTMLElement;\n private readonly platformId = inject(PLATFORM_ID);\n private readonly destroyRef = inject(DestroyRef);\n\n protected readonly isClosing = signal(false);\n\n constructor() {\n super();\n // Monkey-patch de dialogRef.close pour intercepter toutes les demandes de fermeture\n const originalClose = this.dialogRef.close.bind(this.dialogRef);\n this.dialogRef.close = (result?: unknown) => {\n this.animateAndClose(result, originalClose);\n };\n\n // L'ouvreur pré-réserve des ids titre/description ; les directives [ktDialogTitle]/[ktDialogDescription]\n // les adoptent. En leur absence, ces ids pointent dans le vide. Au rendu (navigateur) :\n // - aria-describedby orphelin → on RETIRE l'attribut (pas de description fournie) ;\n // - aucun nom accessible (ni titre ni aria-label) → warn dev (WCAG 4.1.2).\n afterNextRender(() => {\n const doc = this.host.ownerDocument;\n\n const describedBy = this.host.getAttribute('aria-describedby');\n if (describedBy && !doc.getElementById(describedBy)) {\n this.host.removeAttribute('aria-describedby');\n }\n\n if (!isDevMode()) return;\n const labelledBy = this.host.getAttribute('aria-labelledby');\n const hasName = !!this.host.getAttribute('aria-label') || (!!labelledBy && !!doc.getElementById(labelledBy));\n if (!hasName) {\n console.warn(\n '[ktDialog] dialog sans nom accessible : ajoutez un [ktDialogTitle] (ou `aria-label` via la config d’ouverture) — WCAG 4.1.2.',\n );\n }\n });\n }\n\n ngOnInit(): void {\n // Si la fermeture par clic extérieur/Échap est autorisée, on l'écoute pour lancer l'animation\n if (!this._config.disableClose) {\n this.dialogRef.backdropClick\n .pipe(takeUntilDestroyed(this.destroyRef))\n .subscribe(() => this.dialogRef.close());\n this.dialogRef.keydownEvents.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((event: KeyboardEvent) => {\n if (event.key === 'Escape') {\n event.preventDefault();\n this.dialogRef.close();\n }\n });\n }\n }\n\n protected isSheet(): boolean {\n return this._config.panelClass?.includes('kt-dialog--sheet') ?? false;\n }\n\n private animateAndClose(result: unknown, originalCloseFn: (r?: unknown) => void): void {\n if (this.isClosing()) return;\n this.isClosing.set(true);\n\n if (!isPlatformBrowser(this.platformId)) {\n originalCloseFn(result);\n return;\n }\n\n // Récupérer la durée de transition configurée en CSS (ex: \"150ms\" ou \"0.2s\")\n const styles = window.getComputedStyle(this.host);\n const durationStr = styles.transitionDuration || '0s';\n const durationMs = parseFloat(durationStr) * (durationStr.includes('ms') ? 1 : 1000);\n\n if (durationMs === 0) {\n originalCloseFn(result);\n return;\n }\n\n // Écouter la fin de la transition sur la propriété 'translate'\n const onTransitionEnd = (event: TransitionEvent) => {\n if (event.target === this.host && event.propertyName === 'translate') {\n this.host.removeEventListener('transitionend', onTransitionEnd);\n originalCloseFn(result);\n }\n };\n this.host.addEventListener('transitionend', onTransitionEnd);\n\n // Sécurité (au cas où la transition n'aboutirait pas)\n setTimeout(() => {\n this.host.removeEventListener('transitionend', onTransitionEnd);\n originalCloseFn(result);\n }, durationMs + 50);\n }\n}\n","import { DIALOG_DATA, Dialog, DialogConfig, DialogRef } from '@angular/cdk/dialog';\nimport { ComponentType } from '@angular/cdk/portal';\nimport { ViewContainerRef, inject } from '@angular/core';\nimport { KtViewport, KtIdGenerator } from '@ktortu/aaa/cdk';\n\nimport { KtDialogPresentation, resolveKtDialogPanelClass } from './dialog-config';\nimport { KtDialogContainer } from './dialog-container';\n\n/**\n * Sucre typé pour récupérer les données injectées dans un composant de dialogue (`DIALOG_DATA`).\n * À appeler en contexte d'injection (ex. initialiseur de champ).\n *\n * @example\n * ```ts\n * interface RenameData { currentName: string; }\n *\n * @Component({ … })\n * export class RenameDialog {\n * protected readonly data = injectKtDialogData<RenameData>();\n * // this.data.currentName → string\n * }\n * ```\n */\nexport function injectKtDialogData<T>(): T {\n return inject<T>(DIALOG_DATA);\n}\n\n/** Config d'ouverture sans le champ `data` (fourni séparément, typé), enrichie de `presentation`. */\nexport type KtDialogOpenerConfig<D, R, C> = Omit<DialogConfig<D, DialogRef<R, C>>, 'data'> & {\n /** Présentation du dialog (cf. `KtDialogPresentation`) — choisie par le dev. Résolue à CHAQUE\n ouverture : les variantes responsive lisent le signal d'écran compact. Défaut : `'centered'`.\n Combinée à un éventuel `panelClass` additionnel. */\n presentation?: KtDialogPresentation;\n};\n\n/**\n * Crée un ouvreur de dialog **typé et centralisé**, en contexte d'injection.\n * Le contrat (composant + type de `data` + type de résultat + config par défaut) est défini\n * UNE fois ; l'ouvreur renvoyé est une closure appelable ensuite n'importe où dans la classe\n * (handlers compris), 100 % typée, sans nouvel `inject`.\n *\n * Conserve le `ViewContainerRef` du contexte appelant (le dialog hérite donc de l'arbre logique\n * d'injection), reste testable (TestBed fournit `Dialog`) et sans état global (SSR-safe).\n *\n * @example\n * // co-localisé avec le composant\n * export const injectRenameDialog = () =>\n * injectKtDialogOpener<RenameDialog, RenameData, string>(RenameDialog, { autoFocus: '[ktDialogFocusInitial]' });\n *\n * // dans un composant/service consommateur\n * private readonly openRename = injectRenameDialog();\n * rename() { this.openRename({ currentName: 'X' }).closed.subscribe(n => { n: string | undefined }); }\n *\n * @param component Composant à monter dans le dialog.\n * @param baseConfig Config d'ouverture par défaut (sans `data`), enrichie de `presentation` ; fusionnée à chaque ouverture.\n * @returns Une closure d'ouverture typée : `() => DialogRef` (sans data) ou `(data, config?) => DialogRef` (avec data).\n */\n// Surcharge sans data (D = void) : l'ouvreur ne prend aucun argument (la config par défaut suffit).\nexport function injectKtDialogOpener<C, R = unknown>(\n component: ComponentType<C>,\n baseConfig?: KtDialogOpenerConfig<void, R, C>,\n): () => DialogRef<R, C>;\n// Surcharge avec data typée.\nexport function injectKtDialogOpener<C, D, R = unknown>(\n component: ComponentType<C>,\n baseConfig?: KtDialogOpenerConfig<D, R, C>,\n): (data: D, config?: KtDialogOpenerConfig<D, R, C>) => DialogRef<R, C>;\n\nexport function injectKtDialogOpener<C, D, R = unknown>(\n component: ComponentType<C>,\n baseConfig?: KtDialogOpenerConfig<D, R, C>,\n) {\n const dialog = inject(Dialog);\n const viewport = inject(KtViewport);\n // Optionnel : hors d'un arbre de vue (ex. service root), il n'y a pas de ViewContainerRef.\n const viewContainerRef = inject(ViewContainerRef, { optional: true }) ?? undefined;\n const idGen = inject(KtIdGenerator);\n\n return (data?: D, config?: KtDialogOpenerConfig<D, R, C>): DialogRef<R, C> => {\n // La présentation (choisie par le dev) est résolue ICI, à l'ouverture : les variantes\n // responsive lisent le signal d'écran compact. Le panelClass final = présentation concrète + extras.\n const { presentation, panelClass, ...rest } = { ...baseConfig, ...config };\n const extra = panelClass ? (Array.isArray(panelClass) ? panelClass : [panelClass]) : [];\n // Dédoublonné : une classe déjà fournie par la présentation (ex. `kt-dialog`) et repassée\n // en `panelClass` par le consommateur ne doit pas apparaître deux fois.\n const merged = [...new Set([...resolveKtDialogPanelClass(presentation, viewport.isCompact()), ...extra])];\n\n const uid = idGen.generateId('dialog');\n const titleId = `kt-dialog-title-${uid}`;\n const descId = `kt-dialog-desc-${uid}`;\n\n return dialog.open<R, D, C>(component, {\n viewContainerRef,\n container: KtDialogContainer,\n ariaLabelledBy: titleId,\n ariaDescribedBy: descId,\n ...rest,\n panelClass: merged,\n data,\n } as DialogConfig<D, DialogRef<R, C>>);\n };\n}\n","import { KtDialogTitle } from './dialog-title.directive';\nimport { KtDialogDescription } from './dialog-description.directive';\nimport { KtDialogClose } from './dialog-close.directive';\nimport {\n KtDialogHeader,\n KtDialogContent,\n KtDialogActions,\n KtDialogFocusInitial,\n KtDialogSheetHandle,\n} from './dialog-structure';\n\nexport * from './dialog-title.directive';\nexport * from './dialog-description.directive';\nexport * from './dialog-close.directive';\nexport * from './dialog-structure';\nexport * from './dialog-config';\nexport * from './dialog-opener';\nexport * from './dialog-container';\n\n/**\n * Import ergonomique de toute la famille dialog en une fois :\n * `imports: [KtDialogImports]` au lieu d'énumérer chaque directive structurelle.\n */\nexport const KtDialogImports = [\n KtDialogHeader,\n KtDialogTitle,\n KtDialogDescription,\n KtDialogContent,\n KtDialogActions,\n KtDialogClose,\n KtDialogFocusInitial,\n KtDialogSheetHandle,\n] as const;\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
|