@ktortu/aaa 0.9.0 → 0.9.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,5 +1,6 @@
1
1
  import { makeEnvironmentProviders } from '@angular/core';
2
- import { KT_FIELD_CONFIG, KT_SELECT_CONFIG, KT_CHIPS_CONFIG } from '@ktortu/aaa/forms';
2
+ import { KT_FIELD_CONFIG, KT_SELECT_CONFIG, KT_CHIPS_CONFIG, ktErrorParam } from '@ktortu/aaa/forms';
3
+ import { KT_SNACKBAR_CONFIG } from '@ktortu/aaa/snackbar';
3
4
  import { KT_TABS_CONFIG } from '@ktortu/aaa/tabs';
4
5
 
5
6
  /**
@@ -24,6 +25,8 @@ function provideKtTranslations(t) {
24
25
  providers.push({ provide: KT_SELECT_CONFIG, useValue: t.select });
25
26
  if (t.chips)
26
27
  providers.push({ provide: KT_CHIPS_CONFIG, useValue: t.chips });
28
+ if (t.snackbar)
29
+ providers.push({ provide: KT_SNACKBAR_CONFIG, useValue: t.snackbar });
27
30
  if (t.tabs)
28
31
  providers.push({ provide: KT_TABS_CONFIG, useValue: t.tabs });
29
32
  return makeEnvironmentProviders(providers);
@@ -37,9 +40,17 @@ function provideKtTranslations(t) {
37
40
  */
38
41
  function mergeKtTranslations(base, over) {
39
42
  return {
40
- field: { ...base.field, ...over.field },
43
+ // `errorMessages` est lui-même une map par `kind` : fusion PROFONDE pour qu'un override ponctuel
44
+ // (ex. `provideKtDefaultFR({ field: { errorMessages: { required: '…' } } })`) ne fasse pas tomber
45
+ // les autres messages de la langue de base.
46
+ field: {
47
+ ...base.field,
48
+ ...over.field,
49
+ errorMessages: { ...base.field?.errorMessages, ...over.field?.errorMessages },
50
+ },
41
51
  select: { ...base.select, ...over.select },
42
52
  chips: { ...base.chips, ...over.chips },
53
+ snackbar: { ...base.snackbar, ...over.snackbar },
43
54
  tabs: { ...base.tabs, ...over.tabs },
44
55
  };
45
56
  }
@@ -54,6 +65,17 @@ const KT_FR_TRANSLATIONS = {
54
65
  clearLabel: 'Effacer',
55
66
  helpLabel: 'Aide',
56
67
  numberParseError: 'La valeur saisie doit être un nombre valide.',
68
+ errorMessages: {
69
+ required: 'Ce champ est requis.',
70
+ email: 'Saisissez une adresse e-mail valide.',
71
+ min: (e) => `Saisissez une valeur supérieure ou égale à ${ktErrorParam(e, 'min')}.`,
72
+ max: (e) => `Saisissez une valeur inférieure ou égale à ${ktErrorParam(e, 'max')}.`,
73
+ minLength: (e) => `Saisissez au moins ${ktErrorParam(e, 'minLength')} caractères.`,
74
+ maxLength: (e) => `Saisissez au plus ${ktErrorParam(e, 'maxLength')} caractères.`,
75
+ minDate: (e) => `Choisissez une date à partir du ${ktErrorParam(e, 'minDate').toLocaleDateString('fr')}.`,
76
+ maxDate: (e) => `Choisissez une date jusqu'au ${ktErrorParam(e, 'maxDate').toLocaleDateString('fr')}.`,
77
+ pattern: 'Le format saisi est invalide.',
78
+ },
57
79
  },
58
80
  select: {
59
81
  emptyText: 'Aucune option',
@@ -80,6 +102,9 @@ const KT_FR_TRANSLATIONS = {
80
102
  lessLabel: 'Afficher moins',
81
103
  listLabel: 'Éléments sélectionnés',
82
104
  },
105
+ snackbar: {
106
+ closeLabel: 'Fermer',
107
+ },
83
108
  tabs: {
84
109
  previousLabel: 'Onglets précédents',
85
110
  nextLabel: 'Onglets suivants',
@@ -1 +1 @@
1
- {"version":3,"file":"ktortu-aaa-i18n.mjs","sources":["../../../../projects/ktortu/aaa/i18n/translations.ts","../../../../projects/ktortu/aaa/i18n/fr.ts","../../../../projects/ktortu/aaa/i18n/ktortu-aaa-i18n.ts"],"sourcesContent":["import { EnvironmentProviders, Provider, makeEnvironmentProviders } from '@angular/core';\n\nimport { KT_FIELD_CONFIG, KT_CHIPS_CONFIG, KT_SELECT_CONFIG } from '@ktortu/aaa/forms';\nimport type { KtFieldConfig, KtChipsConfig, KtSelectConfigOptions } from '@ktortu/aaa/forms';\nimport { KT_TABS_CONFIG } from '@ktortu/aaa/tabs';\nimport type { KtTabsConfig } from '@ktortu/aaa/tabs';\n\n/**\n * Agrégat de TOUS les libellés traduisibles de la lib, groupés par famille de composants.\n * Chaque clé reprend la config du token correspondant (`Partial` : tout est optionnel — on ne\n * fournit que ce qu'on veut traduire). C'est l'« interface de traduction » unique de la lib :\n * un point d'entrée pour brancher une langue d'un coup.\n *\n * @see provideKtTranslations pour enregistrer un jeu de libellés.\n * @see provideKtDefaultFR pour partir des libellés français.\n */\nexport interface KtTranslations {\n /** Libellés des champs (`clearLabel`, `helpLabel`) → {@link KT_FIELD_CONFIG}. */\n field?: Partial<KtFieldConfig>;\n /** Libellés des selects / multi-selects → {@link KT_SELECT_CONFIG}. */\n select?: Partial<KtSelectConfigOptions>;\n /** Libellés des listes de chips → {@link KT_CHIPS_CONFIG}. */\n chips?: Partial<KtChipsConfig>;\n /** Libellés de la pagination des onglets → {@link KT_TABS_CONFIG}. */\n tabs?: Partial<KtTabsConfig>;\n}\n\n/**\n * Enregistre, en un seul appel, les libellés fournis sur les tokens de config de la lib.\n * Base = défauts anglais de chaque composant ; seules les familles **présentes** dans `t` sont\n * fournies (les autres gardent leur défaut anglais et restent surchargeables ailleurs).\n *\n * À placer dans les `providers` de `app.config.ts` (ou de tout injecteur).\n *\n * @param t Libellés à fournir, groupés par famille ; seules les familles présentes sont enregistrées.\n * @returns Les `EnvironmentProviders` liant chaque famille présente à son token de config.\n * @example\n * ```ts\n * provideKtTranslations({ tabs: { nextLabel: 'Suivant', previousLabel: 'Précédent' } })\n * ```\n */\nexport function provideKtTranslations(t: KtTranslations): EnvironmentProviders {\n const providers: Provider[] = [];\n if (t.field) providers.push({ provide: KT_FIELD_CONFIG, useValue: t.field });\n if (t.select) providers.push({ provide: KT_SELECT_CONFIG, useValue: t.select });\n if (t.chips) providers.push({ provide: KT_CHIPS_CONFIG, useValue: t.chips });\n if (t.tabs) providers.push({ provide: KT_TABS_CONFIG, useValue: t.tabs });\n return makeEnvironmentProviders(providers);\n}\n\n/**\n * Fusion par famille de deux {@link KtTranslations} : `over` écrase `base`, clé par clé.\n * @param base Libellés de référence (ex. un dictionnaire de langue complet).\n * @param over Libellés prioritaires venant écraser `base`.\n * @returns Un nouveau {@link KtTranslations} fusionné, famille par famille.\n * @example mergeKtTranslations(KT_FR_TRANSLATIONS, { tabs: { nextLabel: 'Suivant' } })\n */\nexport function mergeKtTranslations(base: KtTranslations, over: KtTranslations): KtTranslations {\n return {\n field: { ...base.field, ...over.field },\n select: { ...base.select, ...over.select },\n chips: { ...base.chips, ...over.chips },\n tabs: { ...base.tabs, ...over.tabs },\n };\n}\n","import { EnvironmentProviders } from '@angular/core';\n\nimport { KtTranslations, mergeKtTranslations, provideKtTranslations } from './translations';\n\n/**\n * Dictionnaire **français** complet de tous les libellés de la lib. Figé et réutilisable :\n * importable tel quel (ex. pour le composer avec d'autres réglages) ou via {@link provideKtDefaultFR}.\n * Les libellés à pluriels sont des fonctions, pour laisser la grammaire au consommateur.\n */\nexport const KT_FR_TRANSLATIONS: KtTranslations = {\n field: {\n clearLabel: 'Effacer',\n helpLabel: 'Aide',\n numberParseError: 'La valeur saisie doit être un nombre valide.',\n },\n select: {\n emptyText: 'Aucune option',\n closeLabel: 'Fermer',\n filterLabel: 'Filtrer les options',\n // En français, 0 ET 1 prennent le singulier (≠ anglais où seul 1 est singulier).\n filterResultsText: (count) => (count <= 1 ? `${count} résultat` : `${count} résultats`),\n removeItemLabel: (itemLabel) => `Retirer ${itemLabel}`,\n selectedItemsLabel: (fieldLabel) =>\n fieldLabel ? `Éléments sélectionnés pour ${fieldLabel}` : 'Éléments sélectionnés',\n selectionSummaryText: (count) => (count <= 1 ? `${count} élément sélectionné` : `${count} éléments sélectionnés`),\n itemRemovedText: (itemLabel) => `${itemLabel} retiré`,\n selectionCountText: (count) => (count <= 1 ? `${count} sélectionné` : `${count} sélectionnés`),\n selectAllLabel: 'Tout sélectionner',\n clearAllLabel: 'Tout effacer',\n moreChipsLabel: (hiddenCount) => `+${hiddenCount} de plus`,\n lessChipsLabel: 'Afficher moins',\n truncatedResultsText: (max, total) =>\n `Affichage des ${max} premiers résultats sur ${total}. Affinez votre recherche pour en voir plus.`,\n truncatedResultsAnnouncement: (max, total) =>\n `${max} résultats affichés sur ${total}. Affinez votre recherche pour en voir plus.`,\n },\n chips: {\n removeItemLabel: (itemLabel) => `Retirer ${itemLabel}`,\n itemRemovedText: (itemLabel) => `${itemLabel} retiré`,\n moreLabel: (hiddenCount) => `+${hiddenCount} de plus`,\n lessLabel: 'Afficher moins',\n listLabel: 'Éléments sélectionnés',\n },\n tabs: {\n previousLabel: 'Onglets précédents',\n nextLabel: 'Onglets suivants',\n },\n};\n\n/**\n * Enregistre les libellés **français** par défaut sur toute la lib, en un seul appel.\n * `overrides` permet d'ajuster ponctuellement sans tout réécrire (fusion par famille,\n * cf. {@link mergeKtTranslations}). À placer dans les `providers` de `app.config.ts`.\n *\n * @param overrides Libellés à ajuster par-dessus le français (fusion par famille). Défaut : `{}`.\n * @returns Les `EnvironmentProviders` enregistrant le français (fusionné aux `overrides`).\n * @example\n * ```ts\n * // app.config.ts\n * providers: [\n * provideKtDefaultFR(), // tout en français\n * // ou en ajustant un libellé précis :\n * provideKtDefaultFR({ tabs: { nextLabel: 'Suivant' } }),\n * ]\n * ```\n */\nexport function provideKtDefaultFR(overrides: KtTranslations = {}): EnvironmentProviders {\n return provideKtTranslations(mergeKtTranslations(KT_FR_TRANSLATIONS, overrides));\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-i18n.mjs","sources":["../../../../projects/ktortu/aaa/i18n/translations.ts","../../../../projects/ktortu/aaa/i18n/fr.ts","../../../../projects/ktortu/aaa/i18n/ktortu-aaa-i18n.ts"],"sourcesContent":["import { EnvironmentProviders, Provider, makeEnvironmentProviders } from '@angular/core';\n\nimport { KT_FIELD_CONFIG, KT_CHIPS_CONFIG, KT_SELECT_CONFIG } from '@ktortu/aaa/forms';\nimport type { KtFieldConfig, KtChipsConfig, KtSelectConfigOptions } from '@ktortu/aaa/forms';\nimport { KT_SNACKBAR_CONFIG } from '@ktortu/aaa/snackbar';\nimport type { KtSnackbarConfig } from '@ktortu/aaa/snackbar';\nimport { KT_TABS_CONFIG } from '@ktortu/aaa/tabs';\nimport type { KtTabsConfig } from '@ktortu/aaa/tabs';\n\n/**\n * Agrégat de TOUS les libellés traduisibles de la lib, groupés par famille de composants.\n * Chaque clé reprend la config du token correspondant (`Partial` : tout est optionnel — on ne\n * fournit que ce qu'on veut traduire). C'est l'« interface de traduction » unique de la lib :\n * un point d'entrée pour brancher une langue d'un coup.\n *\n * @see provideKtTranslations pour enregistrer un jeu de libellés.\n * @see provideKtDefaultFR pour partir des libellés français.\n */\nexport interface KtTranslations {\n /** Libellés des champs (`clearLabel`, `helpLabel`) → {@link KT_FIELD_CONFIG}. */\n field?: Partial<KtFieldConfig>;\n /** Libellés des selects / multi-selects → {@link KT_SELECT_CONFIG}. */\n select?: Partial<KtSelectConfigOptions>;\n /** Libellés des listes de chips → {@link KT_CHIPS_CONFIG}. */\n chips?: Partial<KtChipsConfig>;\n /** Libellés de la snackbar (`closeLabel`) → {@link KT_SNACKBAR_CONFIG}. */\n snackbar?: Partial<KtSnackbarConfig>;\n /** Libellés de la pagination des onglets → {@link KT_TABS_CONFIG}. */\n tabs?: Partial<KtTabsConfig>;\n}\n\n/**\n * Enregistre, en un seul appel, les libellés fournis sur les tokens de config de la lib.\n * Base = défauts anglais de chaque composant ; seules les familles **présentes** dans `t` sont\n * fournies (les autres gardent leur défaut anglais et restent surchargeables ailleurs).\n *\n * À placer dans les `providers` de `app.config.ts` (ou de tout injecteur).\n *\n * @param t Libellés à fournir, groupés par famille ; seules les familles présentes sont enregistrées.\n * @returns Les `EnvironmentProviders` liant chaque famille présente à son token de config.\n * @example\n * ```ts\n * provideKtTranslations({ tabs: { nextLabel: 'Suivant', previousLabel: 'Précédent' } })\n * ```\n */\nexport function provideKtTranslations(t: KtTranslations): EnvironmentProviders {\n const providers: Provider[] = [];\n if (t.field) providers.push({ provide: KT_FIELD_CONFIG, useValue: t.field });\n if (t.select) providers.push({ provide: KT_SELECT_CONFIG, useValue: t.select });\n if (t.chips) providers.push({ provide: KT_CHIPS_CONFIG, useValue: t.chips });\n if (t.snackbar) providers.push({ provide: KT_SNACKBAR_CONFIG, useValue: t.snackbar });\n if (t.tabs) providers.push({ provide: KT_TABS_CONFIG, useValue: t.tabs });\n return makeEnvironmentProviders(providers);\n}\n\n/**\n * Fusion par famille de deux {@link KtTranslations} : `over` écrase `base`, clé par clé.\n * @param base Libellés de référence (ex. un dictionnaire de langue complet).\n * @param over Libellés prioritaires venant écraser `base`.\n * @returns Un nouveau {@link KtTranslations} fusionné, famille par famille.\n * @example mergeKtTranslations(KT_FR_TRANSLATIONS, { tabs: { nextLabel: 'Suivant' } })\n */\nexport function mergeKtTranslations(base: KtTranslations, over: KtTranslations): KtTranslations {\n return {\n // `errorMessages` est lui-même une map par `kind` : fusion PROFONDE pour qu'un override ponctuel\n // (ex. `provideKtDefaultFR({ field: { errorMessages: { required: '…' } } })`) ne fasse pas tomber\n // les autres messages de la langue de base.\n field: {\n ...base.field,\n ...over.field,\n errorMessages: { ...base.field?.errorMessages, ...over.field?.errorMessages },\n },\n select: { ...base.select, ...over.select },\n chips: { ...base.chips, ...over.chips },\n snackbar: { ...base.snackbar, ...over.snackbar },\n tabs: { ...base.tabs, ...over.tabs },\n };\n}\n","import { EnvironmentProviders } from '@angular/core';\n\nimport { ktErrorParam } from '@ktortu/aaa/forms';\nimport { KtTranslations, mergeKtTranslations, provideKtTranslations } from './translations';\n\n/**\n * Dictionnaire **français** complet de tous les libellés de la lib. Figé et réutilisable :\n * importable tel quel (ex. pour le composer avec d'autres réglages) ou via {@link provideKtDefaultFR}.\n * Les libellés à pluriels sont des fonctions, pour laisser la grammaire au consommateur.\n */\nexport const KT_FR_TRANSLATIONS: KtTranslations = {\n field: {\n clearLabel: 'Effacer',\n helpLabel: 'Aide',\n numberParseError: 'La valeur saisie doit être un nombre valide.',\n errorMessages: {\n required: 'Ce champ est requis.',\n email: 'Saisissez une adresse e-mail valide.',\n min: (e) => `Saisissez une valeur supérieure ou égale à ${ktErrorParam<number>(e, 'min')}.`,\n max: (e) => `Saisissez une valeur inférieure ou égale à ${ktErrorParam<number>(e, 'max')}.`,\n minLength: (e) => `Saisissez au moins ${ktErrorParam<number>(e, 'minLength')} caractères.`,\n maxLength: (e) => `Saisissez au plus ${ktErrorParam<number>(e, 'maxLength')} caractères.`,\n minDate: (e) => `Choisissez une date à partir du ${ktErrorParam<Date>(e, 'minDate').toLocaleDateString('fr')}.`,\n maxDate: (e) => `Choisissez une date jusqu'au ${ktErrorParam<Date>(e, 'maxDate').toLocaleDateString('fr')}.`,\n pattern: 'Le format saisi est invalide.',\n },\n },\n select: {\n emptyText: 'Aucune option',\n closeLabel: 'Fermer',\n filterLabel: 'Filtrer les options',\n // En français, 0 ET 1 prennent le singulier (≠ anglais où seul 1 est singulier).\n filterResultsText: (count) => (count <= 1 ? `${count} résultat` : `${count} résultats`),\n removeItemLabel: (itemLabel) => `Retirer ${itemLabel}`,\n selectedItemsLabel: (fieldLabel) =>\n fieldLabel ? `Éléments sélectionnés pour ${fieldLabel}` : 'Éléments sélectionnés',\n selectionSummaryText: (count) => (count <= 1 ? `${count} élément sélectionné` : `${count} éléments sélectionnés`),\n itemRemovedText: (itemLabel) => `${itemLabel} retiré`,\n selectionCountText: (count) => (count <= 1 ? `${count} sélectionné` : `${count} sélectionnés`),\n selectAllLabel: 'Tout sélectionner',\n clearAllLabel: 'Tout effacer',\n moreChipsLabel: (hiddenCount) => `+${hiddenCount} de plus`,\n lessChipsLabel: 'Afficher moins',\n truncatedResultsText: (max, total) =>\n `Affichage des ${max} premiers résultats sur ${total}. Affinez votre recherche pour en voir plus.`,\n truncatedResultsAnnouncement: (max, total) =>\n `${max} résultats affichés sur ${total}. Affinez votre recherche pour en voir plus.`,\n },\n chips: {\n removeItemLabel: (itemLabel) => `Retirer ${itemLabel}`,\n itemRemovedText: (itemLabel) => `${itemLabel} retiré`,\n moreLabel: (hiddenCount) => `+${hiddenCount} de plus`,\n lessLabel: 'Afficher moins',\n listLabel: 'Éléments sélectionnés',\n },\n snackbar: {\n closeLabel: 'Fermer',\n },\n tabs: {\n previousLabel: 'Onglets précédents',\n nextLabel: 'Onglets suivants',\n },\n};\n\n/**\n * Enregistre les libellés **français** par défaut sur toute la lib, en un seul appel.\n * `overrides` permet d'ajuster ponctuellement sans tout réécrire (fusion par famille,\n * cf. {@link mergeKtTranslations}). À placer dans les `providers` de `app.config.ts`.\n *\n * @param overrides Libellés à ajuster par-dessus le français (fusion par famille). Défaut : `{}`.\n * @returns Les `EnvironmentProviders` enregistrant le français (fusionné aux `overrides`).\n * @example\n * ```ts\n * // app.config.ts\n * providers: [\n * provideKtDefaultFR(), // tout en français\n * // ou en ajustant un libellé précis :\n * provideKtDefaultFR({ tabs: { nextLabel: 'Suivant' } }),\n * ]\n * ```\n */\nexport function provideKtDefaultFR(overrides: KtTranslations = {}): EnvironmentProviders {\n return provideKtTranslations(mergeKtTranslations(KT_FR_TRANSLATIONS, overrides));\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"ktortu-aaa-menu.mjs","sources":["../../../../projects/ktortu/aaa/menu/menu.ts","../../../../projects/ktortu/aaa/menu/menu-trigger.ts","../../../../projects/ktortu/aaa/menu/menu-toggle.ts","../../../../projects/ktortu/aaa/menu/public-api.ts","../../../../projects/ktortu/aaa/menu/ktortu-aaa-menu.ts"],"sourcesContent":["import { Directive, effect, inject, PLATFORM_ID } from '@angular/core';\nimport { isPlatformBrowser } from '@angular/common';\nimport { MenuItem as AriaMenuItem } from '@angular/aria/menu';\nimport { KtIdGenerator } from '@ktortu/aaa/cdk';\n\n/**\n * `[ktMenu]` — marqueur de THÈME posé sur l'hôte `[ngMenu]` d'`@angular/aria`. Style UNIQUEMENT la\n * SURFACE du menu (fond, bord, ombre, rayon, padding, positionnement en dropdown ancré). N'ajoute\n * AUCUN rôle ni comportement : la sémantique (`role=\"menu\"`), le clavier, le focus roving, le\n * retour de focus au trigger, les sous-menus et le typeahead viennent intégralement d'aria\n * (`[ngMenu]`). Même philosophie que `[ktCard]` : la lib thématise, aria gère l'accessibilité.\n *\n * La directive n'a pas de logique propre : tout vit dans `menu.css` via le sélecteur `[ktMenu]`,\n * piloté par l'attribut `data-visible` qu'aria pose sur l'hôte (ouvert/fermé). Le positionnement\n * (CSS Anchor Positioning) est câblé par `[ktMenuTrigger]` (menu racine) et par `[ktMenuItem]`\n * (sous-menus) qui posent les `anchor-name` / `position-anchor`.\n *\n * @example\n * ```html\n * <button ngMenuTrigger ktMenuTrigger [menu]=\"m\">Options</button>\n * <div ngMenu ktMenu #m=\"ngMenu\" (itemSelected)=\"onSelect($event)\" aria-label=\"Options\">\n * <button ngMenuItem ktMenuItem value=\"new\">Nouveau</button>\n * </div>\n * ```\n */\n@Directive({ selector: '[ktMenu]' })\nexport class KtMenu {}\n\n/**\n * `[ktMenuItem]` — marqueur de thème posé sur l'hôte `[ngMenuItem]`. Style la RANGÉE (hauteur de\n * cible tactile ≥44px, focus, survol, désactivé, item de sous-menu avec chevron). Comme `[ktMenu]`,\n * sans logique de sélection : l'état stylé est lu sur les attributs ARIA déjà posés par aria\n * (`:focus-visible` pour l'item actif via focus roving, `[aria-disabled]`, `[aria-expanded]`,\n * `[aria-haspopup]`, `[aria-checked]`).\n *\n * SEULE responsabilité technique : si l'item porte un sous-menu (`[submenu]` côté aria), on câble\n * l'ancrage CSS du sous-menu sur cet item (anchor-name sur l'item, position-anchor sur la surface\n * du sous-menu, marqueur `data-kt-submenu` pour l'ouvrir en latéral plutôt qu'en dropdown).\n *\n * EXIGENCE DE STRUCTURE (sous-menus) : le `[ngMenu]` d'un sous-menu DOIT être un DESCENDANT DOM du\n * menu parent (et non un frère). aria décide de maintenir un menu ouvert via `element.contains()`\n * sur la cible du focus/survol ; un sous-menu placé hors du sous-arbre du parent ferait croire à\n * aria que le focus a quitté le menu et provoquerait sa fermeture dès qu'on survole le sous-menu.\n * Le sous-menu reste rendu en place (top-layer non requis : `position: fixed` + ancrage CSS).\n *\n * @example\n * ```html\n * <button ngMenuItem ktMenuItem value=\"open\">Ouvrir</button>\n * ```\n */\n@Directive({\n selector: '[ktMenuItem]',\n host: {\n '[style.anchor-name]': 'anchorName',\n },\n})\nexport class KtMenuItem {\n // Optionnel : `[ktMenuItem]` reste utilisable seul (simple thème) même hors d'un `[ngMenuItem]`.\n private readonly ariaItem = inject(AriaMenuItem, { self: true, optional: true });\n private readonly platformId = inject(PLATFORM_ID);\n\n // Alloué à la PREMIÈRE détection d'un sous-menu (et non pour chaque item) : un item simple ne\n // consomme pas d'anchor-name.\n protected anchorName: string | undefined;\n private readonly idGen = inject(KtIdGenerator);\n\n constructor() {\n if (!this.ariaItem) return;\n\n effect(() => {\n const submenu = this.ariaItem!.submenu()?.element;\n if (!submenu) {\n this.anchorName = undefined;\n return;\n }\n this.anchorName ??= `--kt-submenu-anchor-${this.idGen.generateId('menu')}`;\n if (isPlatformBrowser(this.platformId)) {\n submenu.style.setProperty('position-anchor', this.anchorName);\n // Marque la surface comme un SOUS-menu : menu.css l'ouvre en latéral (inline-end) et non\n // sous l'item, avec ses propres fallbacks de débordement.\n submenu.setAttribute('data-kt-submenu', '');\n }\n });\n }\n}\n\n/**\n * `[ktMenuSeparator]` — filet de séparation entre groupes d'items. Pose `role=\"separator\"`\n * (sémantique standard d'un séparateur de menu) ; la ligne elle-même vit dans `menu.css`.\n *\n * @example\n * ```html\n * <hr ktMenuSeparator />\n * ```\n */\n@Directive({\n selector: '[ktMenuSeparator]',\n host: { role: 'separator' },\n})\nexport class KtMenuSeparator {}\n","import { Directive, effect, inject, PLATFORM_ID } from '@angular/core';\nimport { isPlatformBrowser } from '@angular/common';\nimport { MenuTrigger as AriaMenuTrigger } from '@angular/aria/menu';\nimport { KtIdGenerator } from '@ktortu/aaa/cdk';\n\n/**\n * `[ktMenuTrigger]` — sucre de POSITIONNEMENT pour le menu racine. À poser SUR le même élément\n * qu'`[ngMenuTrigger]` (le bouton qui ouvre le menu). Il ne réimplémente RIEN du comportement :\n * l'ouverture/fermeture, `aria-expanded`, Échap, le clic-dehors et le retour de focus sont gérés\n * par aria (`[ngMenuTrigger]`). Sa seule tâche : poser un `anchor-name` sur le trigger et le\n * `position-anchor` correspondant sur la surface du menu, pour que `menu.css` l'ancre en dropdown\n * (CSS Anchor Positioning), comme le popup du Select — sans CDK Overlay (styles scopés conservés,\n * et pas de coordination fragile avec le focus qu'aria pose à l'ouverture).\n *\n * Requiert `[ngMenuTrigger]` sur le même hôte (injecté en `self`).\n *\n * @example\n * ```html\n * <button ngMenuTrigger ktMenuTrigger [menu]=\"m\">Fichier</button>\n * ```\n */\n@Directive({\n selector: '[ktMenuTrigger]',\n host: {\n '[style.anchor-name]': 'anchorName',\n },\n})\nexport class KtMenuTrigger {\n private readonly ariaTrigger = inject(AriaMenuTrigger, { self: true });\n private readonly platformId = inject(PLATFORM_ID);\n\n private readonly idGen = inject(KtIdGenerator);\n protected readonly anchorName = `--kt-menu-anchor-${this.idGen.generateId('menu')}`;\n\n constructor() {\n effect(() => {\n const menuEl = this.ariaTrigger.menu()?.element;\n if (!menuEl) return;\n if (isPlatformBrowser(this.platformId)) {\n menuEl.style.setProperty('position-anchor', this.anchorName);\n }\n });\n }\n}\n","import { Directive, ElementRef, afterNextRender, computed, inject, input, InjectionToken, isDevMode, model } from '@angular/core';\nimport { MenuItem as AriaMenuItem } from '@angular/aria/menu';\n\n/**\n * Items de menu À ÉTAT (checkbox / radio).\n *\n * Pourquoi ces directives existent : `@angular/aria` accepte bien `role=\"menuitemcheckbox\"` /\n * `\"menuitemradio\"` sur `[ngMenuItem]`, MAIS NE POSE JAMAIS `aria-checked` — son pattern se\n * contente d'émettre `itemSelected(value)`. Sans `aria-checked`, l'item coché est MUET pour les\n * lecteurs d'écran (échec WCAG 4.1.2). Ces directives comblent ce trou : elles possèdent l'état\n * coché, le bindent en `aria-checked`, et le basculent à l'activation (clic / Entrée / Espace).\n *\n * Elles ne touchent pas au `role` (laissé à l'input `role` d'aria, posé par le consommateur) pour\n * éviter tout conflit de binding sur `[attr.role]` ; la démo montre l'usage `role=\"menuitemradio\"`.\n */\n\n/**\n * Activation commune : clic ET clavier (Entrée / Espace). Les deux liaisons coexistent VOLONTAIREMENT\n * pour supporter un hôte non-`<button>` (ex. `<div ngMenuItem>`), où le clavier n'émet pas de `click`\n * natif. Sur un `<button>`, `activate()` appelle `event.preventDefault()` sur le `keydown`, ce qui\n * neutralise le `click` synthétique → une seule bascule (pas de double-toggle). Couvert en E2E.\n */\nconst ACTIVATION_HOST = {\n '(click)': 'activate($event)',\n '(keydown.enter)': 'activate($event)',\n '(keydown.space)': 'activate($event)',\n} as const;\n\n/**\n * `[ktMenuItemCheckbox]` — case à cocher de menu (bascule indépendante). À poser sur un\n * `[ngMenuItem] role=\"menuitemcheckbox\"`. Bind `aria-checked` et bascule `checked` à l'activation.\n *\n * @example\n * ```html\n * <button ngMenuItem ktMenuItem ktMenuItemCheckbox role=\"menuitemcheckbox\" [(checked)]=\"wrap\">\n * Retour à la ligne\n * </button>\n * ```\n */\n@Directive({\n selector: '[ktMenuItemCheckbox]',\n host: {\n ...ACTIVATION_HOST,\n '[attr.aria-checked]': 'checked()',\n },\n})\nexport class KtMenuItemCheckbox {\n private readonly ariaItem = inject(AriaMenuItem, { self: true, optional: true });\n private readonly host = inject<ElementRef<HTMLElement>>(ElementRef).nativeElement;\n\n /**\n * État coché, bidirectionnel : `[(checked)]`.\n * @default false\n */\n readonly checked = model<boolean>(false);\n\n constructor() {\n // Garde-fou dev : sans `role=\"menuitemcheckbox\"`, `aria-checked` est ignoré → item muet pour les SR.\n afterNextRender(() => {\n if (!isDevMode() || this.host.getAttribute('role') === 'menuitemcheckbox') return;\n console.warn('[ktMenuItemCheckbox] attend `role=\"menuitemcheckbox\"` sur l’hôte, sinon `aria-checked` est inopérant.');\n });\n }\n\n protected activate(event: Event): void {\n if (this.ariaItem?.disabled()) return;\n if (event.type === 'keydown') {\n event.preventDefault();\n }\n this.checked.update((v) => !v);\n }\n}\n\n/** Source de la valeur sélectionnée d'un groupe radio, exposée aux `[ktMenuItemRadio]` enfants. */\nexport const KT_MENU_RADIO_GROUP = new InjectionToken<KtMenuRadioGroup<unknown>>('KT_MENU_RADIO_GROUP');\n\n/**\n * `[ktMenuRadioGroup]` — coordinateur d'un groupe d'items radio mutuellement exclusifs. À poser sur\n * un conteneur englobant les `[ktMenuItemRadio]` (typiquement un `role=\"group\"`). Détient la valeur\n * sélectionnée ; chaque radio s'y compare pour son `aria-checked` et la met à jour à l'activation.\n *\n * @example\n * ```html\n * <div role=\"group\" ktMenuRadioGroup [(value)]=\"sortBy\" aria-label=\"Trier par\">\n * <button ngMenuItem ktMenuItem ktMenuItemRadio role=\"menuitemradio\" [value]=\"'name'\">Nom</button>\n * <button ngMenuItem ktMenuItem ktMenuItemRadio role=\"menuitemradio\" [value]=\"'date'\">Date</button>\n * </div>\n * ```\n */\n@Directive({\n selector: '[ktMenuRadioGroup]',\n exportAs: 'ktMenuRadioGroup',\n providers: [{ provide: KT_MENU_RADIO_GROUP, useExisting: KtMenuRadioGroup }],\n})\nexport class KtMenuRadioGroup<V> {\n /**\n * Valeur sélectionnée du groupe, bidirectionnelle : `[(value)]`.\n * @default null\n */\n readonly value = model<V | null>(null);\n}\n\n/**\n * `[ktMenuItemRadio]` — bouton radio de menu. À poser sur un `[ngMenuItem] role=\"menuitemradio\"`\n * dans un `[ktMenuRadioGroup]`. `aria-checked` reflète l'égalité avec la valeur du groupe ;\n * l'activation sélectionne cette valeur.\n *\n * @example\n * ```html\n * <button ngMenuItem ktMenuItem ktMenuItemRadio role=\"menuitemradio\" [value]=\"'name'\">Trier par nom</button>\n * ```\n */\n@Directive({\n selector: '[ktMenuItemRadio]',\n host: {\n ...ACTIVATION_HOST,\n '[attr.aria-checked]': 'checked()',\n },\n})\nexport class KtMenuItemRadio<V> {\n private readonly ariaItem = inject(AriaMenuItem, { self: true, optional: true });\n private readonly group = inject<KtMenuRadioGroup<V>>(KT_MENU_RADIO_GROUP, { optional: true });\n private readonly host = inject<ElementRef<HTMLElement>>(ElementRef).nativeElement;\n\n /** Valeur portée par ce radio (comparée à celle du groupe). @default (requis) */\n readonly value = input.required<V>();\n\n protected readonly checked = computed(() => this.group?.value() === this.value());\n\n constructor() {\n // Garde-fou dev : sans [ktMenuRadioGroup] parent, aria-checked reste figé (item muet pour les SR).\n if (isDevMode() && !this.group) {\n console.warn(\n '[ktMenuItemRadio] doit être placé dans un [ktMenuRadioGroup] : ' +\n 'sans groupe, la sélection et `aria-checked` restent inopérants.',\n );\n }\n // Garde-fou dev : sans `role=\"menuitemradio\"`, `aria-checked` est ignoré → item muet pour les SR.\n afterNextRender(() => {\n if (!isDevMode() || this.host.getAttribute('role') === 'menuitemradio') return;\n console.warn('[ktMenuItemRadio] attend `role=\"menuitemradio\"` sur l’hôte, sinon `aria-checked` est inopérant.');\n });\n }\n\n protected activate(event: Event): void {\n if (this.ariaItem?.disabled()) return;\n if (event.type === 'keydown') {\n event.preventDefault();\n }\n this.group?.value.set(this.value());\n }\n}\n","import { KtMenu, KtMenuItem, KtMenuSeparator } from './menu';\nimport { KtMenuTrigger } from './menu-trigger';\nimport { KtMenuItemCheckbox, KtMenuItemRadio, KtMenuRadioGroup } from './menu-toggle';\n\nexport * from './menu';\nexport * from './menu-trigger';\nexport * from './menu-toggle';\n\n/**\n * Import ergonomique de toute la famille menu (couche de THÈME ktortu) en une fois :\n * `imports: [KtMenuImports]` au lieu d'énumérer chaque directive. À composer avec les directives\n * d'`@angular/aria/menu` (`Menu`, `MenuItem`, `MenuTrigger`, `MenuContent`), qui apportent le\n * comportement accessible.\n */\nexport const KtMenuImports = [\n KtMenu,\n KtMenuItem,\n KtMenuSeparator,\n KtMenuTrigger,\n KtMenuItemCheckbox,\n KtMenuItemRadio,\n KtMenuRadioGroup,\n] as const;\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":["AriaMenuItem","AriaMenuTrigger"],"mappings":";;;;;;AAKA;;;;;;;;;;;;;;;;;;;AAmBG;MAEU,MAAM,CAAA;uGAAN,MAAM,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;2FAAN,MAAM,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,UAAA,EAAA,QAAA,EAAA,EAAA,EAAA,CAAA;;2FAAN,MAAM,EAAA,UAAA,EAAA,CAAA;kBADlB,SAAS;mBAAC,EAAE,QAAQ,EAAE,UAAU,EAAE;;AAGnC;;;;;;;;;;;;;;;;;;;;;AAqBG;MAOU,UAAU,CAAA;;AAEJ,IAAA,QAAQ,GAAG,MAAM,CAACA,QAAY,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;AAC/D,IAAA,UAAU,GAAG,MAAM,CAAC,WAAW,CAAC;;;AAIvC,IAAA,UAAU;AACH,IAAA,KAAK,GAAG,MAAM,CAAC,aAAa,CAAC;AAE9C,IAAA,WAAA,GAAA;QACE,IAAI,CAAC,IAAI,CAAC,QAAQ;YAAE;QAEpB,MAAM,CAAC,MAAK;YACV,MAAM,OAAO,GAAG,IAAI,CAAC,QAAS,CAAC,OAAO,EAAE,EAAE,OAAO;YACjD,IAAI,CAAC,OAAO,EAAE;AACZ,gBAAA,IAAI,CAAC,UAAU,GAAG,SAAS;gBAC3B;YACF;AACA,YAAA,IAAI,CAAC,UAAU,KAAK,CAAA,oBAAA,EAAuB,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE;AAC1E,YAAA,IAAI,iBAAiB,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE;gBACtC,OAAO,CAAC,KAAK,CAAC,WAAW,CAAC,iBAAiB,EAAE,IAAI,CAAC,UAAU,CAAC;;;AAG7D,gBAAA,OAAO,CAAC,YAAY,CAAC,iBAAiB,EAAE,EAAE,CAAC;YAC7C;AACF,QAAA,CAAC,CAAC;IACJ;uGA3BW,UAAU,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;2FAAV,UAAU,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,cAAA,EAAA,IAAA,EAAA,EAAA,UAAA,EAAA,EAAA,mBAAA,EAAA,YAAA,EAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,CAAA;;2FAAV,UAAU,EAAA,UAAA,EAAA,CAAA;kBANtB,SAAS;AAAC,YAAA,IAAA,EAAA,CAAA;AACT,oBAAA,QAAQ,EAAE,cAAc;AACxB,oBAAA,IAAI,EAAE;AACJ,wBAAA,qBAAqB,EAAE,YAAY;AACpC,qBAAA;AACF,iBAAA;;AA+BD;;;;;;;;AAQG;MAKU,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,IAAA,EAAA,EAAA,UAAA,EAAA,EAAA,MAAA,EAAA,WAAA,EAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,CAAA;;2FAAf,eAAe,EAAA,UAAA,EAAA,CAAA;kBAJ3B,SAAS;AAAC,YAAA,IAAA,EAAA,CAAA;AACT,oBAAA,QAAQ,EAAE,mBAAmB;AAC7B,oBAAA,IAAI,EAAE,EAAE,IAAI,EAAE,WAAW,EAAE;AAC5B,iBAAA;;;AC7FD;;;;;;;;;;;;;;;AAeG;MAOU,aAAa,CAAA;IACP,WAAW,GAAG,MAAM,CAACC,WAAe,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;AACrD,IAAA,UAAU,GAAG,MAAM,CAAC,WAAW,CAAC;AAEhC,IAAA,KAAK,GAAG,MAAM,CAAC,aAAa,CAAC;IAC3B,UAAU,GAAG,CAAA,iBAAA,EAAoB,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,MAAM,CAAC,CAAA,CAAE;AAEnF,IAAA,WAAA,GAAA;QACE,MAAM,CAAC,MAAK;YACV,MAAM,MAAM,GAAG,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE,EAAE,OAAO;AAC/C,YAAA,IAAI,CAAC,MAAM;gBAAE;AACb,YAAA,IAAI,iBAAiB,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE;gBACtC,MAAM,CAAC,KAAK,CAAC,WAAW,CAAC,iBAAiB,EAAE,IAAI,CAAC,UAAU,CAAC;YAC9D;AACF,QAAA,CAAC,CAAC;IACJ;uGAfW,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,mBAAA,EAAA,YAAA,EAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,CAAA;;2FAAb,aAAa,EAAA,UAAA,EAAA,CAAA;kBANzB,SAAS;AAAC,YAAA,IAAA,EAAA,CAAA;AACT,oBAAA,QAAQ,EAAE,iBAAiB;AAC3B,oBAAA,IAAI,EAAE;AACJ,wBAAA,qBAAqB,EAAE,YAAY;AACpC,qBAAA;AACF,iBAAA;;;ACvBD;;;;;;;;;;;AAWG;AAEH;;;;;AAKG;AACH,MAAM,eAAe,GAAG;AACtB,IAAA,SAAS,EAAE,kBAAkB;AAC7B,IAAA,iBAAiB,EAAE,kBAAkB;AACrC,IAAA,iBAAiB,EAAE,kBAAkB;CAC7B;AAEV;;;;;;;;;;AAUG;MAQU,kBAAkB,CAAA;AACZ,IAAA,QAAQ,GAAG,MAAM,CAACD,QAAY,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;AAC/D,IAAA,IAAI,GAAG,MAAM,CAA0B,UAAU,CAAC,CAAC,aAAa;AAEjF;;;AAGG;IACM,OAAO,GAAG,KAAK,CAAU,KAAK;gFAAC;AAExC,IAAA,WAAA,GAAA;;QAEE,eAAe,CAAC,MAAK;AACnB,YAAA,IAAI,CAAC,SAAS,EAAE,IAAI,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,KAAK,kBAAkB;gBAAE;AAC3E,YAAA,OAAO,CAAC,IAAI,CAAC,uGAAuG,CAAC;AACvH,QAAA,CAAC,CAAC;IACJ;AAEU,IAAA,QAAQ,CAAC,KAAY,EAAA;AAC7B,QAAA,IAAI,IAAI,CAAC,QAAQ,EAAE,QAAQ,EAAE;YAAE;AAC/B,QAAA,IAAI,KAAK,CAAC,IAAI,KAAK,SAAS,EAAE;YAC5B,KAAK,CAAC,cAAc,EAAE;QACxB;AACA,QAAA,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC;IAChC;uGAxBW,kBAAkB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;2FAAlB,kBAAkB,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,sBAAA,EAAA,MAAA,EAAA,EAAA,OAAA,EAAA,EAAA,iBAAA,EAAA,SAAA,EAAA,UAAA,EAAA,SAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,EAAA,OAAA,EAAA,EAAA,OAAA,EAAA,eAAA,EAAA,EAAA,IAAA,EAAA,EAAA,SAAA,EAAA,EAAA,OAAA,EAAA,kBAAA,EAAA,eAAA,EAAA,kBAAA,EAAA,eAAA,EAAA,kBAAA,EAAA,EAAA,UAAA,EAAA,EAAA,mBAAA,EAAA,WAAA,EAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,CAAA;;2FAAlB,kBAAkB,EAAA,UAAA,EAAA,CAAA;kBAP9B,SAAS;AAAC,YAAA,IAAA,EAAA,CAAA;AACT,oBAAA,QAAQ,EAAE,sBAAsB;AAChC,oBAAA,IAAI,EAAE;AACJ,wBAAA,GAAG,eAAe;AAClB,wBAAA,qBAAqB,EAAE,WAAW;AACnC,qBAAA;AACF,iBAAA;;AA4BD;MACa,mBAAmB,GAAG,IAAI,cAAc,CAA4B,qBAAqB;AAEtG;;;;;;;;;;;;AAYG;MAMU,gBAAgB,CAAA;AAC3B;;;AAGG;IACM,KAAK,GAAG,KAAK,CAAW,IAAI;8EAAC;uGAL3B,gBAAgB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;2FAAhB,gBAAgB,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,oBAAA,EAAA,MAAA,EAAA,EAAA,KAAA,EAAA,EAAA,iBAAA,EAAA,OAAA,EAAA,UAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,EAAA,OAAA,EAAA,EAAA,KAAA,EAAA,aAAA,EAAA,EAAA,SAAA,EAFhB,CAAC,EAAE,OAAO,EAAE,mBAAmB,EAAE,WAAW,EAAE,gBAAgB,EAAE,CAAC,EAAA,QAAA,EAAA,CAAA,kBAAA,CAAA,EAAA,QAAA,EAAA,EAAA,EAAA,CAAA;;2FAEjE,gBAAgB,EAAA,UAAA,EAAA,CAAA;kBAL5B,SAAS;AAAC,YAAA,IAAA,EAAA,CAAA;AACT,oBAAA,QAAQ,EAAE,oBAAoB;AAC9B,oBAAA,QAAQ,EAAE,kBAAkB;oBAC5B,SAAS,EAAE,CAAC,EAAE,OAAO,EAAE,mBAAmB,EAAE,WAAW,EAAA,gBAAkB,EAAE,CAAC;AAC7E,iBAAA;;AASD;;;;;;;;;AASG;MAQU,eAAe,CAAA;AACT,IAAA,QAAQ,GAAG,MAAM,CAACA,QAAY,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;IAC/D,KAAK,GAAG,MAAM,CAAsB,mBAAmB,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;AAC5E,IAAA,IAAI,GAAG,MAAM,CAA0B,UAAU,CAAC,CAAC,aAAa;;IAGxE,KAAK,GAAG,KAAK,CAAC,QAAQ;8EAAK;AAEjB,IAAA,OAAO,GAAG,QAAQ,CAAC,MAAM,IAAI,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,IAAI,CAAC,KAAK,EAAE;gFAAC;AAEjF,IAAA,WAAA,GAAA;;QAEE,IAAI,SAAS,EAAE,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE;YAC9B,OAAO,CAAC,IAAI,CACV,iEAAiE;AAC/D,gBAAA,iEAAiE,CACpE;QACH;;QAEA,eAAe,CAAC,MAAK;AACnB,YAAA,IAAI,CAAC,SAAS,EAAE,IAAI,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,KAAK,eAAe;gBAAE;AACxE,YAAA,OAAO,CAAC,IAAI,CAAC,iGAAiG,CAAC;AACjH,QAAA,CAAC,CAAC;IACJ;AAEU,IAAA,QAAQ,CAAC,KAAY,EAAA;AAC7B,QAAA,IAAI,IAAI,CAAC,QAAQ,EAAE,QAAQ,EAAE;YAAE;AAC/B,QAAA,IAAI,KAAK,CAAC,IAAI,KAAK,SAAS,EAAE;YAC5B,KAAK,CAAC,cAAc,EAAE;QACxB;AACA,QAAA,IAAI,CAAC,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC;IACrC;uGA/BW,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,MAAA,EAAA,EAAA,KAAA,EAAA,EAAA,iBAAA,EAAA,OAAA,EAAA,UAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,EAAA,IAAA,EAAA,EAAA,SAAA,EAAA,EAAA,OAAA,EAAA,kBAAA,EAAA,eAAA,EAAA,kBAAA,EAAA,eAAA,EAAA,kBAAA,EAAA,EAAA,UAAA,EAAA,EAAA,mBAAA,EAAA,WAAA,EAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,CAAA;;2FAAf,eAAe,EAAA,UAAA,EAAA,CAAA;kBAP3B,SAAS;AAAC,YAAA,IAAA,EAAA,CAAA;AACT,oBAAA,QAAQ,EAAE,mBAAmB;AAC7B,oBAAA,IAAI,EAAE;AACJ,wBAAA,GAAG,eAAe;AAClB,wBAAA,qBAAqB,EAAE,WAAW;AACnC,qBAAA;AACF,iBAAA;;;AC9GD;;;;;AAKG;AACI,MAAM,aAAa,GAAG;IAC3B,MAAM;IACN,UAAU;IACV,eAAe;IACf,aAAa;IACb,kBAAkB;IAClB,eAAe;IACf,gBAAgB;;;ACrBlB;;AAEG;;;;"}
1
+ {"version":3,"file":"ktortu-aaa-menu.mjs","sources":["../../../../projects/ktortu/aaa/menu/menu.ts","../../../../projects/ktortu/aaa/menu/menu-trigger.ts","../../../../projects/ktortu/aaa/menu/menu-toggle.ts","../../../../projects/ktortu/aaa/menu/public-api.ts","../../../../projects/ktortu/aaa/menu/ktortu-aaa-menu.ts"],"sourcesContent":["import { Directive, effect, inject, PLATFORM_ID } from '@angular/core';\nimport { isPlatformBrowser } from '@angular/common';\nimport { MenuItem as AriaMenuItem } from '@angular/aria/menu';\nimport { KtIdGenerator } from '@ktortu/aaa/cdk';\n\n/**\n * `[ktMenu]` — marqueur de THÈME posé sur l'hôte `[ngMenu]` d'`@angular/aria`. Style UNIQUEMENT la\n * SURFACE du menu (fond, bord, ombre, rayon, padding, positionnement en dropdown ancré). N'ajoute\n * AUCUN rôle ni comportement : la sémantique (`role=\"menu\"`), le clavier, le focus roving, le\n * retour de focus au trigger, les sous-menus et le typeahead viennent intégralement d'aria\n * (`[ngMenu]`). Même philosophie que `[ktCard]` : la lib thématise, aria gère l'accessibilité.\n *\n * La directive n'a pas de logique propre : tout vit dans `menu.css` via le sélecteur `[ktMenu]`,\n * piloté par l'attribut `data-visible` qu'aria pose sur l'hôte (ouvert/fermé). Le positionnement\n * (CSS Anchor Positioning) est câblé par `[ktMenuTrigger]` (menu racine) et par `[ktMenuItem]`\n * (sous-menus) qui posent les `anchor-name` / `position-anchor`.\n *\n * @example\n * ```html\n * <button ngMenuTrigger ktMenuTrigger [menu]=\"m\">Options</button>\n * <div ngMenu ktMenu #m=\"ngMenu\" (itemSelected)=\"onSelect($event)\" aria-label=\"Options\">\n * <button ngMenuItem ktMenuItem value=\"new\">Nouveau</button>\n * </div>\n * ```\n */\n@Directive({ selector: '[ktMenu]' })\nexport class KtMenu {}\n\n/**\n * `[ktMenuItem]` — marqueur de thème posé sur l'hôte `[ngMenuItem]`. Style la RANGÉE (hauteur de\n * cible tactile ≥44px, focus, survol, désactivé, item de sous-menu avec chevron). Comme `[ktMenu]`,\n * sans logique de sélection : l'état stylé est lu sur les attributs ARIA déjà posés par aria\n * (`:focus-visible` pour l'item actif via focus roving, `[aria-disabled]`, `[aria-expanded]`,\n * `[aria-haspopup]`, `[aria-checked]`).\n *\n * SEULE responsabilité technique : si l'item porte un sous-menu (`[submenu]` côté aria), on câble\n * l'ancrage CSS du sous-menu sur cet item (anchor-name sur l'item, position-anchor sur la surface\n * du sous-menu, marqueur `data-kt-submenu` pour l'ouvrir en latéral plutôt qu'en dropdown).\n *\n * EXIGENCE DE STRUCTURE (sous-menus) : le `[ngMenu]` d'un sous-menu DOIT être un DESCENDANT DOM du\n * menu parent (et non un frère). aria décide de maintenir un menu ouvert via `element.contains()`\n * sur la cible du focus/survol ; un sous-menu placé hors du sous-arbre du parent ferait croire à\n * aria que le focus a quitté le menu et provoquerait sa fermeture dès qu'on survole le sous-menu.\n * Le sous-menu reste rendu en place (top-layer non requis : `position: fixed` + ancrage CSS).\n *\n * @example\n * ```html\n * <button ngMenuItem ktMenuItem value=\"open\">Ouvrir</button>\n * ```\n */\n@Directive({\n selector: '[ktMenuItem]',\n host: {\n '[style.anchor-name]': 'anchorName',\n },\n})\nexport class KtMenuItem {\n // Optionnel : `[ktMenuItem]` reste utilisable seul (simple thème) même hors d'un `[ngMenuItem]`.\n private readonly ariaItem = inject(AriaMenuItem, { self: true, optional: true });\n private readonly platformId = inject(PLATFORM_ID);\n\n // Alloué à la PREMIÈRE détection d'un sous-menu (et non pour chaque item) : un item simple ne\n // consomme pas d'anchor-name.\n protected anchorName: string | undefined;\n private readonly idGen = inject(KtIdGenerator);\n\n constructor() {\n if (!this.ariaItem) return;\n\n effect(() => {\n const submenu = this.ariaItem!.submenu()?.element;\n if (!submenu) {\n this.anchorName = undefined;\n return;\n }\n this.anchorName ??= `--kt-submenu-anchor-${this.idGen.generateId('menu')}`;\n if (isPlatformBrowser(this.platformId)) {\n submenu.style.setProperty('position-anchor', this.anchorName);\n // Marque la surface comme un SOUS-menu : menu.css l'ouvre en latéral (inline-end) et non\n // sous l'item, avec ses propres fallbacks de débordement.\n submenu.setAttribute('data-kt-submenu', '');\n }\n });\n }\n}\n\n/**\n * `[ktMenuSeparator]` — filet de séparation entre groupes d'items. Pose `role=\"separator\"`\n * (sémantique standard d'un séparateur de menu) ; la ligne elle-même vit dans `menu.css`.\n *\n * @example\n * ```html\n * <hr ktMenuSeparator />\n * ```\n */\n@Directive({\n selector: '[ktMenuSeparator]',\n host: { role: 'separator' },\n})\nexport class KtMenuSeparator {}\n","import { Directive, effect, inject, PLATFORM_ID } from '@angular/core';\nimport { isPlatformBrowser } from '@angular/common';\nimport { MenuTrigger as AriaMenuTrigger } from '@angular/aria/menu';\nimport { KtIdGenerator } from '@ktortu/aaa/cdk';\n\n/**\n * `[ktMenuTrigger]` — sucre de POSITIONNEMENT pour le menu racine. À poser SUR le même élément\n * qu'`[ngMenuTrigger]` (le bouton qui ouvre le menu). Il ne réimplémente RIEN du comportement :\n * l'ouverture/fermeture, `aria-expanded`, Échap, le clic-dehors et le retour de focus sont gérés\n * par aria (`[ngMenuTrigger]`). Sa seule tâche : poser un `anchor-name` sur le trigger et le\n * `position-anchor` correspondant sur la surface du menu, pour que `menu.css` l'ancre en dropdown\n * (CSS Anchor Positioning), comme le popup du Select — sans CDK Overlay (styles scopés conservés,\n * et pas de coordination fragile avec le focus qu'aria pose à l'ouverture).\n *\n * Requiert `[ngMenuTrigger]` sur le même hôte (injecté en `self`).\n *\n * @example\n * ```html\n * <button ngMenuTrigger ktMenuTrigger [menu]=\"m\">Fichier</button>\n * ```\n */\n@Directive({\n selector: '[ktMenuTrigger]',\n host: {\n '[style.anchor-name]': 'anchorName',\n },\n})\nexport class KtMenuTrigger {\n private readonly ariaTrigger = inject(AriaMenuTrigger, { self: true });\n private readonly platformId = inject(PLATFORM_ID);\n\n private readonly idGen = inject(KtIdGenerator);\n protected readonly anchorName = `--kt-menu-anchor-${this.idGen.generateId('menu')}`;\n\n constructor() {\n effect(() => {\n const menuEl = this.ariaTrigger.menu()?.element;\n if (!menuEl) return;\n if (isPlatformBrowser(this.platformId)) {\n menuEl.style.setProperty('position-anchor', this.anchorName);\n }\n });\n }\n}\n","import {\n Directive,\n ElementRef,\n afterNextRender,\n computed,\n inject,\n input,\n InjectionToken,\n isDevMode,\n model,\n} from '@angular/core';\nimport { MenuItem as AriaMenuItem } from '@angular/aria/menu';\n\n/**\n * Items de menu À ÉTAT (checkbox / radio).\n *\n * Pourquoi ces directives existent : `@angular/aria` accepte bien `role=\"menuitemcheckbox\"` /\n * `\"menuitemradio\"` sur `[ngMenuItem]`, MAIS NE POSE JAMAIS `aria-checked` — son pattern se\n * contente d'émettre `itemSelected(value)`. Sans `aria-checked`, l'item coché est MUET pour les\n * lecteurs d'écran (échec WCAG 4.1.2). Ces directives comblent ce trou : elles possèdent l'état\n * coché, le bindent en `aria-checked`, et le basculent à l'activation (clic / Entrée / Espace).\n *\n * Elles ne touchent pas au `role` (laissé à l'input `role` d'aria, posé par le consommateur) pour\n * éviter tout conflit de binding sur `[attr.role]` ; la démo montre l'usage `role=\"menuitemradio\"`.\n */\n\n/**\n * Activation commune : clic ET clavier (Entrée / Espace). Les deux liaisons coexistent VOLONTAIREMENT\n * pour supporter un hôte non-`<button>` (ex. `<div ngMenuItem>`), où le clavier n'émet pas de `click`\n * natif. Sur un `<button>`, `activate()` appelle `event.preventDefault()` sur le `keydown`, ce qui\n * neutralise le `click` synthétique → une seule bascule (pas de double-toggle). Couvert en E2E.\n */\nconst ACTIVATION_HOST = {\n '(click)': 'activate($event)',\n '(keydown.enter)': 'activate($event)',\n '(keydown.space)': 'activate($event)',\n} as const;\n\n/**\n * `[ktMenuItemCheckbox]` — case à cocher de menu (bascule indépendante). À poser sur un\n * `[ngMenuItem] role=\"menuitemcheckbox\"`. Bind `aria-checked` et bascule `checked` à l'activation.\n *\n * @example\n * ```html\n * <button ngMenuItem ktMenuItem ktMenuItemCheckbox role=\"menuitemcheckbox\" [(checked)]=\"wrap\">\n * Retour à la ligne\n * </button>\n * ```\n */\n@Directive({\n selector: '[ktMenuItemCheckbox]',\n host: {\n ...ACTIVATION_HOST,\n '[attr.aria-checked]': 'checked()',\n },\n})\nexport class KtMenuItemCheckbox {\n private readonly ariaItem = inject(AriaMenuItem, { self: true, optional: true });\n private readonly host = inject<ElementRef<HTMLElement>>(ElementRef).nativeElement;\n\n /**\n * État coché, bidirectionnel : `[(checked)]`.\n * @default false\n */\n readonly checked = model<boolean>(false);\n\n constructor() {\n // Garde-fou dev : sans `role=\"menuitemcheckbox\"`, `aria-checked` est ignoré → item muet pour les SR.\n afterNextRender(() => {\n if (!isDevMode() || this.host.getAttribute('role') === 'menuitemcheckbox') return;\n console.warn(\n '[ktMenuItemCheckbox] attend `role=\"menuitemcheckbox\"` sur l’hôte, sinon `aria-checked` est inopérant.',\n );\n });\n }\n\n protected activate(event: Event): void {\n if (this.ariaItem?.disabled()) return;\n if (event.type === 'keydown') {\n event.preventDefault();\n }\n this.checked.update((v) => !v);\n }\n}\n\n/** Source de la valeur sélectionnée d'un groupe radio, exposée aux `[ktMenuItemRadio]` enfants. */\nexport const KT_MENU_RADIO_GROUP = new InjectionToken<KtMenuRadioGroup<unknown>>('KT_MENU_RADIO_GROUP');\n\n/**\n * `[ktMenuRadioGroup]` — coordinateur d'un groupe d'items radio mutuellement exclusifs. À poser sur\n * un conteneur englobant les `[ktMenuItemRadio]` (typiquement un `role=\"group\"`). Détient la valeur\n * sélectionnée ; chaque radio s'y compare pour son `aria-checked` et la met à jour à l'activation.\n *\n * @example\n * ```html\n * <div role=\"group\" ktMenuRadioGroup [(value)]=\"sortBy\" aria-label=\"Trier par\">\n * <button ngMenuItem ktMenuItem ktMenuItemRadio role=\"menuitemradio\" [value]=\"'name'\">Nom</button>\n * <button ngMenuItem ktMenuItem ktMenuItemRadio role=\"menuitemradio\" [value]=\"'date'\">Date</button>\n * </div>\n * ```\n */\n@Directive({\n selector: '[ktMenuRadioGroup]',\n exportAs: 'ktMenuRadioGroup',\n providers: [{ provide: KT_MENU_RADIO_GROUP, useExisting: KtMenuRadioGroup }],\n})\nexport class KtMenuRadioGroup<V> {\n /**\n * Valeur sélectionnée du groupe, bidirectionnelle : `[(value)]`.\n * @default null\n */\n readonly value = model<V | null>(null);\n}\n\n/**\n * `[ktMenuItemRadio]` — bouton radio de menu. À poser sur un `[ngMenuItem] role=\"menuitemradio\"`\n * dans un `[ktMenuRadioGroup]`. `aria-checked` reflète l'égalité avec la valeur du groupe ;\n * l'activation sélectionne cette valeur.\n *\n * @example\n * ```html\n * <button ngMenuItem ktMenuItem ktMenuItemRadio role=\"menuitemradio\" [value]=\"'name'\">Trier par nom</button>\n * ```\n */\n@Directive({\n selector: '[ktMenuItemRadio]',\n host: {\n ...ACTIVATION_HOST,\n '[attr.aria-checked]': 'checked()',\n },\n})\nexport class KtMenuItemRadio<V> {\n private readonly ariaItem = inject(AriaMenuItem, { self: true, optional: true });\n private readonly group = inject<KtMenuRadioGroup<V>>(KT_MENU_RADIO_GROUP, { optional: true });\n private readonly host = inject<ElementRef<HTMLElement>>(ElementRef).nativeElement;\n\n /** Valeur portée par ce radio (comparée à celle du groupe). @default (requis) */\n readonly value = input.required<V>();\n\n protected readonly checked = computed(() => this.group?.value() === this.value());\n\n constructor() {\n // Garde-fou dev : sans [ktMenuRadioGroup] parent, aria-checked reste figé (item muet pour les SR).\n if (isDevMode() && !this.group) {\n console.warn(\n '[ktMenuItemRadio] doit être placé dans un [ktMenuRadioGroup] : ' +\n 'sans groupe, la sélection et `aria-checked` restent inopérants.',\n );\n }\n // Garde-fou dev : sans `role=\"menuitemradio\"`, `aria-checked` est ignoré → item muet pour les SR.\n afterNextRender(() => {\n if (!isDevMode() || this.host.getAttribute('role') === 'menuitemradio') return;\n console.warn('[ktMenuItemRadio] attend `role=\"menuitemradio\"` sur l’hôte, sinon `aria-checked` est inopérant.');\n });\n }\n\n protected activate(event: Event): void {\n if (this.ariaItem?.disabled()) return;\n if (event.type === 'keydown') {\n event.preventDefault();\n }\n this.group?.value.set(this.value());\n }\n}\n","import { KtMenu, KtMenuItem, KtMenuSeparator } from './menu';\nimport { KtMenuTrigger } from './menu-trigger';\nimport { KtMenuItemCheckbox, KtMenuItemRadio, KtMenuRadioGroup } from './menu-toggle';\n\nexport * from './menu';\nexport * from './menu-trigger';\nexport * from './menu-toggle';\n\n/**\n * Import ergonomique de toute la famille menu (couche de THÈME ktortu) en une fois :\n * `imports: [KtMenuImports]` au lieu d'énumérer chaque directive. À composer avec les directives\n * d'`@angular/aria/menu` (`Menu`, `MenuItem`, `MenuTrigger`, `MenuContent`), qui apportent le\n * comportement accessible.\n */\nexport const KtMenuImports = [\n KtMenu,\n KtMenuItem,\n KtMenuSeparator,\n KtMenuTrigger,\n KtMenuItemCheckbox,\n KtMenuItemRadio,\n KtMenuRadioGroup,\n] as const;\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":["AriaMenuItem","AriaMenuTrigger"],"mappings":"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"}