@cadriciel/ui 0.1.0 → 0.2.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.
@@ -232,6 +232,10 @@ const CAD_ICONS_UI = {
232
232
  'panel-right': '<rect width="18" height="18" x="3" y="3" rx="2"/><path d="M15 3v18"/>',
233
233
  'panel-top': '<rect width="18" height="18" x="3" y="3" rx="2"/><path d="M3 9h18"/>',
234
234
  'panel-bottom': '<rect width="18" height="18" x="3" y="3" rx="2"/><path d="M3 15h18"/>',
235
+ // Ajoutée le 19/08 : le jeu n'avait aucune icône d'appareil, alors que le showcase et les
236
+ // applications en ont besoin dès qu'elles parlent de mobile.
237
+ smartphone: '<rect width="14" height="20" x="5" y="2" rx="2.5"/><path d="M11 18.5h2"/>',
238
+ tablet: '<rect width="16" height="20" x="4" y="2" rx="2"/><path d="M10.5 18.5h3"/>',
235
239
  'sidebar-open': '<rect width="18" height="18" x="3" y="3" rx="2"/><path d="M9 3v18M14 9l3 3-3 3"/>',
236
240
  'sidebar-close': '<rect width="18" height="18" x="3" y="3" rx="2"/><path d="M9 3v18M16 15l-3-3 3-3"/>',
237
241
  rows: '<rect width="18" height="18" x="3" y="3" rx="2"/><path d="M3 12h18"/>',
@@ -8164,12 +8168,29 @@ class CadAccordionPanelComponent {
8164
8168
  constructor() {
8165
8169
  effect(() => { if (this.isOpen())
8166
8170
  this.rendered.set(true); });
8167
- // expanded (local) accordéon
8168
- effect(() => { const e = this.expanded(); if (e !== this.acc.isOpen(this.value()))
8169
- this.acc.setOpen(this.value(), e, this); });
8170
- // accordéon expanded (local)
8171
- effect(() => { const o = this.isOpen(); if (o !== this.expanded())
8172
- this.expanded.set(o); });
8171
+ // DEUX MIROIRS ENTRE `expanded` (local) ET L'ACCORDÉON. Règle : un miroir ne
8172
+ // s'abonne QU'À SA SOURCE, jamais à sa destination sinon les deux se réveillent
8173
+ // mutuellement et celui créé en premier écrase l'autre avec une valeur périmée.
8174
+ // C'est ce qui refermait le panneau 55 ms après son ouverture (corrigé le 21/08/2026).
8175
+ // accordéon expanded : l'accordéon est la SOURCE DE VÉRITÉ, il passe en premier
8176
+ // pour que `expanded` soit aligné avant que le miroir inverse ne s'exécute.
8177
+ effect(() => {
8178
+ const o = this.isOpen();
8179
+ untracked(() => { if (o !== this.expanded())
8180
+ this.expanded.set(o); });
8181
+ });
8182
+ // expanded → accordéon : seulement sur un VRAI changement local. Au premier passage
8183
+ // `expanded` vaut son défaut (`false`), qui n'exprime aucune intention : le pousser
8184
+ // écraserait la valeur initiale déclarée sur l'accordéon.
8185
+ let precedent = untracked(() => this.expanded());
8186
+ effect(() => {
8187
+ const e = this.expanded();
8188
+ if (e === precedent)
8189
+ return;
8190
+ precedent = e;
8191
+ untracked(() => { if (e !== this.acc.isOpen(this.value()))
8192
+ this.acc.setOpen(this.value(), e, this); });
8193
+ });
8173
8194
  }
8174
8195
  toggle() { if (!this.disabled())
8175
8196
  this.acc.setOpen(this.value(), !this.isOpen(), this); }
@@ -9040,6 +9061,483 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.20", ngImpo
9040
9061
  `, styles: [":host{position:relative;display:inline-block;z-index:5}.cad-speed-dial__fab{width:48px;height:48px;border-radius:50%;border:0;background:var(--cad-accent);color:var(--cad-fg-on-accent);display:grid;place-items:center;cursor:pointer;box-shadow:var(--cad-shadow-md);transition:transform var(--cad-dur),background var(--cad-dur)}.cad-speed-dial__fab:hover{background:var(--cad-accent-hover)}.cad-speed-dial__fab:focus-visible{outline:2px solid var(--cad-ring);outline-offset:2px}:host(.is-open) .cad-speed-dial__fab cad-icon{transform:rotate(0)}.cad-speed-dial__items{position:absolute;left:50%;top:50%;width:0;height:0;pointer-events:none}.cad-speed-dial__item{position:absolute;left:-18px;top:-18px;width:36px;height:36px;border-radius:50%;border:1px solid var(--cad-border);background:var(--cad-surface);color:var(--cad-fg-secondary);display:grid;place-items:center;cursor:pointer;box-shadow:var(--cad-shadow-md);transition:transform .18s var(--cad-ease),opacity .15s;pointer-events:auto}.cad-speed-dial__item:hover{color:var(--cad-accent);border-color:var(--cad-accent)}.cad-speed-dial__item:focus-visible{outline:2px solid var(--cad-ring)}:host(:not(.is-open)) .cad-speed-dial__item{pointer-events:none}.cad-speed-dial__mask{position:fixed;inset:0;background:var(--cad-backdrop, rgba(2,6,23,.45));z-index:-1}@media(prefers-reduced-motion:reduce){.cad-speed-dial__item{transition:none}}\n"] }]
9041
9062
  }], ctorParameters: () => [], propDecorators: { items: [{ type: i0.Input, args: [{ isSignal: true, alias: "items", required: false }] }], direction: [{ type: i0.Input, args: [{ isSignal: true, alias: "direction", required: false }] }], type: [{ type: i0.Input, args: [{ isSignal: true, alias: "type", required: false }] }], radius: [{ type: i0.Input, args: [{ isSignal: true, alias: "radius", required: false }] }], spacing: [{ type: i0.Input, args: [{ isSignal: true, alias: "spacing", required: false }] }], visible: [{ type: i0.Input, args: [{ isSignal: true, alias: "visible", required: false }] }, { type: i0.Output, args: ["visibleChange"] }], mask: [{ type: i0.Input, args: [{ isSignal: true, alias: "mask", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], showIcon: [{ type: i0.Input, args: [{ isSignal: true, alias: "showIcon", required: false }] }], hideIcon: [{ type: i0.Input, args: [{ isSignal: true, alias: "hideIcon", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], itemClick: [{ type: i0.Output, args: ["itemClick"] }], opened: [{ type: i0.Output, args: ["opened"] }], closed: [{ type: i0.Output, args: ["closed"] }] } });
9042
9063
 
9064
+ /**
9065
+ * <cad-bottom-nav [(value)]="page" [items]="items" labels="always|selected|never" (changed)/>
9066
+ *
9067
+ * Barre de navigation basse : 3 à 5 destinations à portée de pouce, sur mobile uniquement.
9068
+ *
9069
+ * POURQUOI UNE LISTE PROPRE, DISTINCTE DU TIROIR — la tentation est de reprendre les premières
9070
+ * entrées de `cad-nav-drawer`. On ne le fait pas : une barre basse ne supporte pas plus de cinq
9071
+ * destinations, et surtout on ne met pas en avant les mêmes choses au pouce que dans un menu
9072
+ * complet. Les deux listes pointent volontiers les mêmes routes, mais elles sont écrites
9073
+ * séparément — l'implicite se paierait en surprises au premier ajout d'entrée.
9074
+ *
9075
+ * ACCESSIBILITÉ — la destination courante est marquée par une pastille pleine EN PLUS de la
9076
+ * couleur : la couleur seule disparaît pour une personne daltonienne. Les cibles font 44 px de
9077
+ * haut au minimum, et la barre réserve la zone sûre des téléphones à encoche
9078
+ * (`env(safe-area-inset-bottom)`), sans quoi la dernière rangée passe sous la barre d'accueil.
9079
+ */
9080
+ class CadBottomNavComponent {
9081
+ bp = inject(CadBreakpointService);
9082
+ items = input([], ...(ngDevMode ? [{ debugName: "items" }] : /* istanbul ignore next */ []));
9083
+ /** Destination courante. Bidirectionnel. */
9084
+ value = model(null, ...(ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []));
9085
+ /** Quand afficher le libellé sous l'icône. */
9086
+ labels = input('always', ...(ngDevMode ? [{ debugName: "labels" }] : /* istanbul ignore next */ []));
9087
+ /**
9088
+ * Au-delà, les destinations en trop ne sont PAS affichées : cinq est la limite tenable
9089
+ * en largeur, et tronquer silencieusement vaut mieux que rendre la barre illisible.
9090
+ * Prévoir une destination « Plus » qui ouvre le reste en feuille.
9091
+ */
9092
+ maxItems = input(5, { ...(ngDevMode ? { debugName: "maxItems" } : /* istanbul ignore next */ {}), transform: numberAttribute });
9093
+ /** Seuil au-delà duquel la barre disparaît : elle n'a de sens que sur petit écran. */
9094
+ breakpoint = input('md', ...(ngDevMode ? [{ debugName: "breakpoint" }] : /* istanbul ignore next */ []));
9095
+ /** Force l'affichage quel que soit le seuil — utile en démonstration. */
9096
+ alwaysShow = input(false, { ...(ngDevMode ? { debugName: "alwaysShow" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
9097
+ ariaLabel = input('Navigation principale', ...(ngDevMode ? [{ debugName: "ariaLabel" }] : /* istanbul ignore next */ []));
9098
+ changed = output();
9099
+ itemClick = output();
9100
+ /** Les entrées au-delà de `maxItems` sont écartées, jamais compressées. */
9101
+ shown = computed(() => this.items().slice(0, Math.max(1, this.maxItems())), ...(ngDevMode ? [{ debugName: "shown" }] : /* istanbul ignore next */ []));
9102
+ visible = computed(() => this.alwaysShow() || this.bp.down(this.breakpoint()), ...(ngDevMode ? [{ debugName: "visible" }] : /* istanbul ignore next */ []));
9103
+ isActive(it) {
9104
+ return this.value() === it.value;
9105
+ }
9106
+ showLabel(it) {
9107
+ const mode = this.labels();
9108
+ return mode === 'always' || (mode === 'selected' && this.isActive(it));
9109
+ }
9110
+ /** « 99+ » plutôt qu'un nombre qui ferait déborder la pastille. */
9111
+ cap(badge) {
9112
+ if (typeof badge === 'number')
9113
+ return badge > 99 ? '99+' : String(badge);
9114
+ return String(badge);
9115
+ }
9116
+ pick(it, ev) {
9117
+ if (it.disabled) {
9118
+ ev.preventDefault();
9119
+ return;
9120
+ }
9121
+ this.itemClick.emit({ item: it, originalEvent: ev });
9122
+ if (this.value() === it.value)
9123
+ return;
9124
+ this.value.set(it.value);
9125
+ this.changed.emit(it);
9126
+ }
9127
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: CadBottomNavComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
9128
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.20", type: CadBottomNavComponent, isStandalone: true, selector: "cad-bottom-nav", inputs: { items: { classPropertyName: "items", publicName: "items", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, labels: { classPropertyName: "labels", publicName: "labels", isSignal: true, isRequired: false, transformFunction: null }, maxItems: { classPropertyName: "maxItems", publicName: "maxItems", isSignal: true, isRequired: false, transformFunction: null }, breakpoint: { classPropertyName: "breakpoint", publicName: "breakpoint", isSignal: true, isRequired: false, transformFunction: null }, alwaysShow: { classPropertyName: "alwaysShow", publicName: "alwaysShow", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange", changed: "changed", itemClick: "itemClick" }, host: { properties: { "class.is-hidden": "!visible()", "attr.role": "\"navigation\"", "attr.aria-label": "ariaLabel()" }, classAttribute: "cad-bottom-nav" }, ngImport: i0, template: `
9129
+ @if (visible()) {
9130
+ <ul class="cad-bottom-nav__list" role="list">
9131
+ @for (it of shown(); track it.value) {
9132
+ <li>
9133
+ @if (it.routerLink) {
9134
+ <a
9135
+ class="cad-bottom-nav__item"
9136
+ [class.is-active]="isActive(it)"
9137
+ [class.is-disabled]="it.disabled"
9138
+ [routerLink]="it.routerLink"
9139
+ [queryParams]="it.queryParams"
9140
+ routerLinkActive="is-route-active"
9141
+ [attr.aria-current]="isActive(it) ? 'page' : null"
9142
+ [attr.aria-disabled]="it.disabled || null"
9143
+ [attr.aria-label]="it.ariaLabel || null"
9144
+ (click)="pick(it, $event)"
9145
+ >
9146
+ <ng-container *ngTemplateOutlet="body; context: { $implicit: it }"/>
9147
+ </a>
9148
+ } @else if (it.url) {
9149
+ <a class="cad-bottom-nav__item" [class.is-active]="isActive(it)" [class.is-disabled]="it.disabled"
9150
+ [href]="it.url" [attr.aria-current]="isActive(it) ? 'page' : null" [attr.aria-label]="it.ariaLabel || null"
9151
+ (click)="pick(it, $event)">
9152
+ <ng-container *ngTemplateOutlet="body; context: { $implicit: it }"/>
9153
+ </a>
9154
+ } @else {
9155
+ <button
9156
+ type="button"
9157
+ class="cad-bottom-nav__item"
9158
+ [class.is-active]="isActive(it)"
9159
+ [disabled]="it.disabled"
9160
+ [attr.aria-current]="isActive(it) ? 'page' : null"
9161
+ [attr.aria-label]="it.ariaLabel || null"
9162
+ (click)="pick(it, $event)"
9163
+ >
9164
+ <ng-container *ngTemplateOutlet="body; context: { $implicit: it }"/>
9165
+ </button>
9166
+ }
9167
+ </li>
9168
+ }
9169
+ </ul>
9170
+ }
9171
+
9172
+ <ng-template #body let-it>
9173
+ <span class="cad-bottom-nav__icon">
9174
+ <!-- La pastille est un élément à part : c'est elle qui porte l'état actif, pas la couleur. -->
9175
+ <span class="cad-bottom-nav__pill" aria-hidden="true"></span>
9176
+ <cad-icon [name]="(isActive(it) && it.activeIcon) || it.icon" [size]="22"/>
9177
+ @if (it.badge !== undefined && it.badge !== false && it.badge !== null) {
9178
+ <span class="cad-bottom-nav__badge" [class.is-dot]="it.badge === true">
9179
+ @if (it.badge !== true) {{{ cap(it.badge) }}}
9180
+ </span>
9181
+ }
9182
+ </span>
9183
+ @if (showLabel(it)) {<span class="cad-bottom-nav__label">{{ it.label }}</span>}
9184
+ </ng-template>
9185
+ `, isInline: true, styles: [":host{display:block;position:sticky;bottom:0;z-index:20;background:var(--cad-overlay);border-top:1px solid var(--cad-border);padding-bottom:env(safe-area-inset-bottom,0px)}:host(.is-hidden){display:none}.cad-bottom-nav__list{display:flex;margin:0;padding:4px 4px 2px;list-style:none}.cad-bottom-nav__list>li{flex:1;min-width:0;display:flex}.cad-bottom-nav__item{all:unset;box-sizing:border-box;flex:1;min-width:0;cursor:pointer;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:2px;min-height:44px;padding:5px 2px 6px;color:var(--cad-fg-muted);font:10px var(--cad-font);text-align:center;text-decoration:none;border-radius:var(--cad-radius);position:relative}.cad-bottom-nav__item:hover{color:var(--cad-fg-secondary)}.cad-bottom-nav__item:focus-visible{outline:2px solid var(--cad-accent);outline-offset:-2px}.cad-bottom-nav__item.is-active{color:var(--cad-accent)}.cad-bottom-nav__item.is-disabled,.cad-bottom-nav__item:disabled{opacity:.45;cursor:not-allowed}.cad-bottom-nav__icon{position:relative;display:grid;place-items:center;width:100%;height:26px}.cad-bottom-nav__pill{position:absolute;width:38px;height:26px;border-radius:var(--cad-radius-pill);background:transparent;transition:background var(--cad-dur) var(--cad-ease)}.cad-bottom-nav__item.is-active .cad-bottom-nav__pill{background:var(--cad-accent-soft)}.cad-bottom-nav__icon cad-icon{position:relative;z-index:1}.cad-bottom-nav__label{max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;line-height:1.3;position:relative;z-index:1}.cad-bottom-nav__item.is-active .cad-bottom-nav__label{font-weight:500}.cad-bottom-nav__badge{position:absolute;top:-2px;left:50%;margin-left:6px;z-index:2;min-width:15px;height:15px;padding:0 4px;border-radius:var(--cad-radius-pill);background:var(--cad-danger, #f85149);color:#fff;font-size:9px;font-weight:600;line-height:15px;text-align:center;border:2px solid var(--cad-overlay);box-sizing:content-box}.cad-bottom-nav__badge.is-dot{min-width:8px;height:8px;padding:0;margin-left:8px}:host-context(.cad-touch) .cad-bottom-nav__item{min-height:52px}@media(prefers-reduced-motion:reduce){.cad-bottom-nav__pill{transition:none}}\n"], dependencies: [{ kind: "component", type: CadIconComponent, selector: "cad-icon", inputs: ["name", "size", "strokeWidth", "label", "title", "spin", "filled", "flip", "rotate"] }, { kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "directive", type: RouterLinkActive, selector: "[routerLinkActive]", inputs: ["routerLinkActiveOptions", "ariaCurrentWhenActive", "routerLinkActive"], outputs: ["isActiveChange"], exportAs: ["routerLinkActive"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
9186
+ }
9187
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: CadBottomNavComponent, decorators: [{
9188
+ type: Component,
9189
+ args: [{ selector: 'cad-bottom-nav', standalone: true, imports: [CadIconComponent, RouterLink, RouterLinkActive, NgTemplateOutlet], changeDetection: ChangeDetectionStrategy.OnPush, host: {
9190
+ class: 'cad-bottom-nav',
9191
+ '[class.is-hidden]': '!visible()',
9192
+ '[attr.role]': '"navigation"',
9193
+ '[attr.aria-label]': 'ariaLabel()',
9194
+ }, template: `
9195
+ @if (visible()) {
9196
+ <ul class="cad-bottom-nav__list" role="list">
9197
+ @for (it of shown(); track it.value) {
9198
+ <li>
9199
+ @if (it.routerLink) {
9200
+ <a
9201
+ class="cad-bottom-nav__item"
9202
+ [class.is-active]="isActive(it)"
9203
+ [class.is-disabled]="it.disabled"
9204
+ [routerLink]="it.routerLink"
9205
+ [queryParams]="it.queryParams"
9206
+ routerLinkActive="is-route-active"
9207
+ [attr.aria-current]="isActive(it) ? 'page' : null"
9208
+ [attr.aria-disabled]="it.disabled || null"
9209
+ [attr.aria-label]="it.ariaLabel || null"
9210
+ (click)="pick(it, $event)"
9211
+ >
9212
+ <ng-container *ngTemplateOutlet="body; context: { $implicit: it }"/>
9213
+ </a>
9214
+ } @else if (it.url) {
9215
+ <a class="cad-bottom-nav__item" [class.is-active]="isActive(it)" [class.is-disabled]="it.disabled"
9216
+ [href]="it.url" [attr.aria-current]="isActive(it) ? 'page' : null" [attr.aria-label]="it.ariaLabel || null"
9217
+ (click)="pick(it, $event)">
9218
+ <ng-container *ngTemplateOutlet="body; context: { $implicit: it }"/>
9219
+ </a>
9220
+ } @else {
9221
+ <button
9222
+ type="button"
9223
+ class="cad-bottom-nav__item"
9224
+ [class.is-active]="isActive(it)"
9225
+ [disabled]="it.disabled"
9226
+ [attr.aria-current]="isActive(it) ? 'page' : null"
9227
+ [attr.aria-label]="it.ariaLabel || null"
9228
+ (click)="pick(it, $event)"
9229
+ >
9230
+ <ng-container *ngTemplateOutlet="body; context: { $implicit: it }"/>
9231
+ </button>
9232
+ }
9233
+ </li>
9234
+ }
9235
+ </ul>
9236
+ }
9237
+
9238
+ <ng-template #body let-it>
9239
+ <span class="cad-bottom-nav__icon">
9240
+ <!-- La pastille est un élément à part : c'est elle qui porte l'état actif, pas la couleur. -->
9241
+ <span class="cad-bottom-nav__pill" aria-hidden="true"></span>
9242
+ <cad-icon [name]="(isActive(it) && it.activeIcon) || it.icon" [size]="22"/>
9243
+ @if (it.badge !== undefined && it.badge !== false && it.badge !== null) {
9244
+ <span class="cad-bottom-nav__badge" [class.is-dot]="it.badge === true">
9245
+ @if (it.badge !== true) {{{ cap(it.badge) }}}
9246
+ </span>
9247
+ }
9248
+ </span>
9249
+ @if (showLabel(it)) {<span class="cad-bottom-nav__label">{{ it.label }}</span>}
9250
+ </ng-template>
9251
+ `, styles: [":host{display:block;position:sticky;bottom:0;z-index:20;background:var(--cad-overlay);border-top:1px solid var(--cad-border);padding-bottom:env(safe-area-inset-bottom,0px)}:host(.is-hidden){display:none}.cad-bottom-nav__list{display:flex;margin:0;padding:4px 4px 2px;list-style:none}.cad-bottom-nav__list>li{flex:1;min-width:0;display:flex}.cad-bottom-nav__item{all:unset;box-sizing:border-box;flex:1;min-width:0;cursor:pointer;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:2px;min-height:44px;padding:5px 2px 6px;color:var(--cad-fg-muted);font:10px var(--cad-font);text-align:center;text-decoration:none;border-radius:var(--cad-radius);position:relative}.cad-bottom-nav__item:hover{color:var(--cad-fg-secondary)}.cad-bottom-nav__item:focus-visible{outline:2px solid var(--cad-accent);outline-offset:-2px}.cad-bottom-nav__item.is-active{color:var(--cad-accent)}.cad-bottom-nav__item.is-disabled,.cad-bottom-nav__item:disabled{opacity:.45;cursor:not-allowed}.cad-bottom-nav__icon{position:relative;display:grid;place-items:center;width:100%;height:26px}.cad-bottom-nav__pill{position:absolute;width:38px;height:26px;border-radius:var(--cad-radius-pill);background:transparent;transition:background var(--cad-dur) var(--cad-ease)}.cad-bottom-nav__item.is-active .cad-bottom-nav__pill{background:var(--cad-accent-soft)}.cad-bottom-nav__icon cad-icon{position:relative;z-index:1}.cad-bottom-nav__label{max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;line-height:1.3;position:relative;z-index:1}.cad-bottom-nav__item.is-active .cad-bottom-nav__label{font-weight:500}.cad-bottom-nav__badge{position:absolute;top:-2px;left:50%;margin-left:6px;z-index:2;min-width:15px;height:15px;padding:0 4px;border-radius:var(--cad-radius-pill);background:var(--cad-danger, #f85149);color:#fff;font-size:9px;font-weight:600;line-height:15px;text-align:center;border:2px solid var(--cad-overlay);box-sizing:content-box}.cad-bottom-nav__badge.is-dot{min-width:8px;height:8px;padding:0;margin-left:8px}:host-context(.cad-touch) .cad-bottom-nav__item{min-height:52px}@media(prefers-reduced-motion:reduce){.cad-bottom-nav__pill{transition:none}}\n"] }]
9252
+ }], propDecorators: { items: [{ type: i0.Input, args: [{ isSignal: true, alias: "items", required: false }] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }, { type: i0.Output, args: ["valueChange"] }], labels: [{ type: i0.Input, args: [{ isSignal: true, alias: "labels", required: false }] }], maxItems: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxItems", required: false }] }], breakpoint: [{ type: i0.Input, args: [{ isSignal: true, alias: "breakpoint", required: false }] }], alwaysShow: [{ type: i0.Input, args: [{ isSignal: true, alias: "alwaysShow", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], changed: [{ type: i0.Output, args: ["changed"] }], itemClick: [{ type: i0.Output, args: ["itemClick"] }] } });
9253
+
9254
+ /**
9255
+ * En-tête et pied sont des SLOTS, pas des gabarits : `<div cadNavDrawerFooter>` sur n'importe
9256
+ * quel élément, sans `<ng-template>` à écrire. Ces directives sont de simples marqueurs — elles
9257
+ * n'injectent surtout pas `TemplateRef`, qui n'existe que sur un `<ng-template>` et ferait
9258
+ * échouer l'injection sur un `<div>` (NG0201).
9259
+ */
9260
+ class CadNavDrawerHeaderDirective {
9261
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: CadNavDrawerHeaderDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
9262
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.20", type: CadNavDrawerHeaderDirective, isStandalone: true, selector: "[cadNavDrawerHeader]", ngImport: i0 });
9263
+ }
9264
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: CadNavDrawerHeaderDirective, decorators: [{
9265
+ type: Directive,
9266
+ args: [{ selector: '[cadNavDrawerHeader]', standalone: true }]
9267
+ }] });
9268
+ class CadNavDrawerFooterDirective {
9269
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: CadNavDrawerFooterDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
9270
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.20", type: CadNavDrawerFooterDirective, isStandalone: true, selector: "[cadNavDrawerFooter]", ngImport: i0 });
9271
+ }
9272
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: CadNavDrawerFooterDirective, decorators: [{
9273
+ type: Directive,
9274
+ args: [{ selector: '[cadNavDrawerFooter]', standalone: true }]
9275
+ }] });
9276
+ /**
9277
+ * <cad-nav-drawer [items]="items" [(open)]="open" [(value)]="page" mode="auto" (itemClick)/>
9278
+ *
9279
+ * Menu principal de l'application : UN composant pour les trois états, pas deux à tenir en
9280
+ * parallèle. En `auto` (défaut) il est permanent en colonne au-dessus du seuil, et bascule
9281
+ * en tiroir par-dessus le contenu en dessous, ouvert au hamburger. `rail` n'affiche que les
9282
+ * icônes, le libellé passant en `title`.
9283
+ *
9284
+ * POURQUOI PAS `cad-drawer` — celui-ci est un panneau générique : il ne connaît ni items, ni
9285
+ * route active, ni sections, et surtout il est toujours temporaire. Le mode permanent n'est
9286
+ * pas une surcouche cosmétique : le tiroir occupe alors une colonne dans le flux et pousse le
9287
+ * contenu, au lieu de le recouvrir.
9288
+ *
9289
+ * LA LISTE EST DISTINCTE DE CELLE DE `cad-bottom-nav`, volontairement — voir la note qui s'y
9290
+ * trouve : on ne met pas en avant les mêmes destinations au pouce que dans un menu complet.
9291
+ */
9292
+ class CadNavDrawerComponent {
9293
+ bp = inject(CadBreakpointService);
9294
+ items = input([], ...(ngDevMode ? [{ debugName: "items" }] : /* istanbul ignore next */ []));
9295
+ /** Ouverture du tiroir. Sans effet en mode permanent, où le panneau est toujours là. */
9296
+ open = model(false, ...(ngDevMode ? [{ debugName: "open" }] : /* istanbul ignore next */ []));
9297
+ /** Entrée courante, comparée à `item.value`. */
9298
+ value = model(null, ...(ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []));
9299
+ mode = input('auto', ...(ngDevMode ? [{ debugName: "mode" }] : /* istanbul ignore next */ []));
9300
+ /** Seuil de bascule permanent → tiroir, en mode `auto`. */
9301
+ breakpoint = input('md', ...(ngDevMode ? [{ debugName: "breakpoint" }] : /* istanbul ignore next */ []));
9302
+ position = input('left', ...(ngDevMode ? [{ debugName: "position" }] : /* istanbul ignore next */ []));
9303
+ title = input('', ...(ngDevMode ? [{ debugName: "title" }] : /* istanbul ignore next */ []));
9304
+ icon = input('', ...(ngDevMode ? [{ debugName: "icon" }] : /* istanbul ignore next */ []));
9305
+ ariaLabel = input('Menu principal', ...(ngDevMode ? [{ debugName: "ariaLabel" }] : /* istanbul ignore next */ []));
9306
+ /** Referme le tiroir après un clic sur une entrée. Sans objet en permanent. */
9307
+ closeOnNavigate = input(true, { ...(ngDevMode ? { debugName: "closeOnNavigate" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
9308
+ closeOnEscape = input(true, { ...(ngDevMode ? { debugName: "closeOnEscape" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
9309
+ /** Clic sur le voile. */
9310
+ dismissableScrim = input(true, { ...(ngDevMode ? { debugName: "dismissableScrim" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
9311
+ opened = output();
9312
+ closed = output();
9313
+ itemClick = output();
9314
+ changed = output();
9315
+ /** Présence des slots : sert à décider du repli sur l'en-tête par défaut et du cadre du pied. */
9316
+ headerSlot = contentChild(CadNavDrawerHeaderDirective, ...(ngDevMode ? [{ debugName: "headerSlot" }] : /* istanbul ignore next */ []));
9317
+ footerSlot = contentChild(CadNavDrawerFooterDirective, ...(ngDevMode ? [{ debugName: "footerSlot" }] : /* istanbul ignore next */ []));
9318
+ /** Mode effectif : `auto` se résout au seuil, les autres sont imposés. */
9319
+ effective = computed(() => {
9320
+ const m = this.mode();
9321
+ if (m !== 'auto')
9322
+ return m;
9323
+ return this.bp.down(this.breakpoint()) ? 'temporary' : 'permanent';
9324
+ }, ...(ngDevMode ? [{ debugName: "effective" }] : /* istanbul ignore next */ []));
9325
+ temporary = computed(() => this.effective() === 'temporary', ...(ngDevMode ? [{ debugName: "temporary" }] : /* istanbul ignore next */ []));
9326
+ rail = computed(() => this.effective() === 'rail', ...(ngDevMode ? [{ debugName: "rail" }] : /* istanbul ignore next */ []));
9327
+ wasOpen = signal(false, ...(ngDevMode ? [{ debugName: "wasOpen" }] : /* istanbul ignore next */ []));
9328
+ constructor() {
9329
+ effect(() => {
9330
+ const o = this.open() && this.temporary();
9331
+ if (o === this.wasOpen())
9332
+ return;
9333
+ this.wasOpen.set(o);
9334
+ (o ? this.opened : this.closed).emit();
9335
+ });
9336
+ // Repasser en permanent laisse un tiroir « ouvert » qui n'a plus de sens : on le solde,
9337
+ // sinon le retour en mode tiroir le rouvrirait tout seul.
9338
+ effect(() => {
9339
+ if (!this.temporary() && this.open())
9340
+ this.open.set(false);
9341
+ });
9342
+ }
9343
+ isActive(it) {
9344
+ return it.value !== undefined && this.value() === it.value;
9345
+ }
9346
+ toggle() { this.open.set(!this.open()); }
9347
+ show() { this.open.set(true); }
9348
+ hide() { this.open.set(false); }
9349
+ dismiss() {
9350
+ if (this.dismissableScrim())
9351
+ this.open.set(false);
9352
+ }
9353
+ onEscape() {
9354
+ if (this.closeOnEscape() && this.temporary() && this.open())
9355
+ this.open.set(false);
9356
+ }
9357
+ pick(it, ev) {
9358
+ if (it.disabled) {
9359
+ ev.preventDefault();
9360
+ return;
9361
+ }
9362
+ this.itemClick.emit({ item: it, originalEvent: ev });
9363
+ it.command?.({ item: it, originalEvent: ev });
9364
+ if (it.value !== undefined && this.value() !== it.value) {
9365
+ this.value.set(it.value);
9366
+ this.changed.emit(it);
9367
+ }
9368
+ if (this.temporary() && this.closeOnNavigate())
9369
+ this.open.set(false);
9370
+ }
9371
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: CadNavDrawerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
9372
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.20", type: CadNavDrawerComponent, isStandalone: true, selector: "cad-nav-drawer", inputs: { items: { classPropertyName: "items", publicName: "items", isSignal: true, isRequired: false, transformFunction: null }, open: { classPropertyName: "open", publicName: "open", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, mode: { classPropertyName: "mode", publicName: "mode", isSignal: true, isRequired: false, transformFunction: null }, breakpoint: { classPropertyName: "breakpoint", publicName: "breakpoint", isSignal: true, isRequired: false, transformFunction: null }, position: { classPropertyName: "position", publicName: "position", isSignal: true, isRequired: false, transformFunction: null }, title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, icon: { classPropertyName: "icon", publicName: "icon", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, closeOnNavigate: { classPropertyName: "closeOnNavigate", publicName: "closeOnNavigate", isSignal: true, isRequired: false, transformFunction: null }, closeOnEscape: { classPropertyName: "closeOnEscape", publicName: "closeOnEscape", isSignal: true, isRequired: false, transformFunction: null }, dismissableScrim: { classPropertyName: "dismissableScrim", publicName: "dismissableScrim", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { open: "openChange", value: "valueChange", opened: "opened", closed: "closed", itemClick: "itemClick", changed: "changed" }, host: { listeners: { "document:keydown.escape": "onEscape()" }, properties: { "class.is-temporary": "temporary()", "class.is-permanent": "!temporary()", "class.is-rail": "rail()", "class.is-open": "open()", "class.is-right": "position() === \"right\"" }, classAttribute: "cad-nav-drawer" }, queries: [{ propertyName: "headerSlot", first: true, predicate: CadNavDrawerHeaderDirective, descendants: true, isSignal: true }, { propertyName: "footerSlot", first: true, predicate: CadNavDrawerFooterDirective, descendants: true, isSignal: true }], ngImport: i0, template: `
9373
+ <!-- Le voile n'existe qu'en mode tiroir : en permanent il n'y a rien à recouvrir. -->
9374
+ @if (temporary() && open()) {
9375
+ <div class="cad-nav-drawer__scrim" (click)="dismiss()" aria-hidden="true"></div>
9376
+ }
9377
+
9378
+ <nav
9379
+ class="cad-nav-drawer__panel"
9380
+ [attr.aria-label]="ariaLabel()"
9381
+ [attr.aria-hidden]="temporary() && !open() ? 'true' : null"
9382
+ [attr.inert]="temporary() && !open() ? '' : null"
9383
+ >
9384
+ <div class="cad-nav-drawer__head">
9385
+ <ng-content select="[cadNavDrawerHeader]"/>
9386
+ @if (!headerSlot()) {
9387
+ @if (icon()) {<cad-icon [name]="icon()" [size]="18"/>}
9388
+ @if (!rail()) {<b>{{ title() }}</b>}
9389
+ }
9390
+ </div>
9391
+
9392
+ <ul class="cad-nav-drawer__list" role="list">
9393
+ @for (it of items(); track $index) {
9394
+ @if (it.section) {
9395
+ <!-- En rail, un intertitre n'a plus de place : un filet le remplace. -->
9396
+ @if (rail()) {
9397
+ <li class="cad-nav-drawer__rule" role="separator"></li>
9398
+ } @else {
9399
+ <li class="cad-nav-drawer__section">{{ it.label }}</li>
9400
+ }
9401
+ } @else {
9402
+ <li>
9403
+ @if (it.routerLink) {
9404
+ <a class="cad-nav-drawer__item" [class.is-active]="isActive(it)" [class.is-disabled]="it.disabled"
9405
+ [routerLink]="it.routerLink" [queryParams]="it.queryParams"
9406
+ [attr.aria-current]="isActive(it) ? 'page' : null" [attr.aria-disabled]="it.disabled || null"
9407
+ [attr.title]="rail() ? it.label : null" [attr.aria-label]="it.ariaLabel || (rail() ? it.label : null)"
9408
+ (click)="pick(it, $event)">
9409
+ <ng-container *ngTemplateOutlet="row; context: { $implicit: it }"/>
9410
+ </a>
9411
+ } @else if (it.url) {
9412
+ <a class="cad-nav-drawer__item" [class.is-active]="isActive(it)" [class.is-disabled]="it.disabled"
9413
+ [href]="it.url" [attr.target]="it.target || null"
9414
+ [attr.title]="rail() ? it.label : null" [attr.aria-label]="it.ariaLabel || (rail() ? it.label : null)"
9415
+ (click)="pick(it, $event)">
9416
+ <ng-container *ngTemplateOutlet="row; context: { $implicit: it }"/>
9417
+ </a>
9418
+ } @else {
9419
+ <button type="button" class="cad-nav-drawer__item" [class.is-active]="isActive(it)"
9420
+ [disabled]="it.disabled" [attr.title]="rail() ? it.label : null"
9421
+ [attr.aria-label]="it.ariaLabel || (rail() ? it.label : null)"
9422
+ [attr.aria-current]="isActive(it) ? 'page' : null" (click)="pick(it, $event)">
9423
+ <ng-container *ngTemplateOutlet="row; context: { $implicit: it }"/>
9424
+ </button>
9425
+ }
9426
+ </li>
9427
+ }
9428
+ }
9429
+ </ul>
9430
+
9431
+ <!-- Toujours rendu : la projection a lieu quoi qu'il arrive. Le cadre ne s'affiche
9432
+ que si un pied a bien été fourni, sinon on verrait un filet et un vide. -->
9433
+ <div class="cad-nav-drawer__foot" [class.is-empty]="!footerSlot()">
9434
+ <ng-content select="[cadNavDrawerFooter]"/>
9435
+ </div>
9436
+ </nav>
9437
+
9438
+ <ng-template #row let-it>
9439
+ @if (it.icon) {<cad-icon [name]="it.icon" [size]="17"/>}
9440
+ @if (!rail()) {
9441
+ <span class="cad-nav-drawer__label">{{ it.label }}</span>
9442
+ @if (it.badge !== undefined && it.badge !== null) {<span class="cad-nav-drawer__badge">{{ it.badge }}</span>}
9443
+ } @else if (it.badge !== undefined && it.badge !== null) {
9444
+ <!-- En rail le compte ne tient pas : il devient un point, le nombre reste en title. -->
9445
+ <span class="cad-nav-drawer__dot" [attr.title]="it.badge"></span>
9446
+ }
9447
+ </ng-template>
9448
+ `, isInline: true, styles: [":host{display:block}:host(.is-permanent){flex:none}.cad-nav-drawer__panel{display:flex;flex-direction:column;min-height:0;height:100%;width:var(--cad-nav-drawer-w, 240px);background:var(--cad-bg-subtle);border-right:1px solid var(--cad-border);transition:width var(--cad-dur) var(--cad-ease)}:host(.is-rail) .cad-nav-drawer__panel{width:var(--cad-nav-drawer-rail-w, 56px)}:host(.is-right) .cad-nav-drawer__panel{border-right:0;border-left:1px solid var(--cad-border)}:host(.is-temporary){position:fixed;inset:0 auto 0 0;z-index:var(--cad-z-overlay, 100002);pointer-events:none}:host(.is-temporary.is-right){inset:0 0 0 auto}:host(.is-temporary) .cad-nav-drawer__panel{pointer-events:auto;height:100%;box-shadow:var(--cad-shadow-lg, 0 12px 24px rgba(15,23,42,.18));transform:translate(-100%);transition:transform var(--cad-dur) var(--cad-ease)}:host(.is-temporary.is-right) .cad-nav-drawer__panel{transform:translate(100%)}:host(.is-temporary.is-open) .cad-nav-drawer__panel{transform:translate(0)}.cad-nav-drawer__scrim{position:fixed;inset:0;background:var(--cad-backdrop, rgba(2,6,23,.45));pointer-events:auto;z-index:-1}.cad-nav-drawer__head{display:flex;align-items:center;gap:9px;flex:none;padding:14px 14px 12px;border-bottom:1px solid var(--cad-border);min-height:48px;color:var(--cad-fg);font-size:13px}:host(.is-rail) .cad-nav-drawer__head{justify-content:center;padding:14px 0 12px}.cad-nav-drawer__head cad-icon{color:var(--cad-accent);flex:none}.cad-nav-drawer__list{list-style:none;margin:0;padding:8px 0;flex:1;min-height:0;overflow-y:auto}.cad-nav-drawer__section{padding:12px 14px 5px;font-size:10px;font-weight:500;letter-spacing:.07em;text-transform:uppercase;color:var(--cad-fg-muted)}.cad-nav-drawer__rule{height:1px;margin:8px 12px;background:var(--cad-border)}.cad-nav-drawer__item{all:unset;box-sizing:border-box;display:flex;align-items:center;gap:10px;width:100%;cursor:pointer;padding:8px 14px;min-height:38px;color:var(--cad-fg-secondary);font:12.5px var(--cad-font);text-decoration:none}:host(.is-rail) .cad-nav-drawer__item{justify-content:center;padding:10px 0}.cad-nav-drawer__item:hover{background:var(--cad-hover);color:var(--cad-fg)}.cad-nav-drawer__item:focus-visible{outline:2px solid var(--cad-accent);outline-offset:-2px}.cad-nav-drawer__item.is-active{background:var(--cad-accent-soft);color:var(--cad-accent);font-weight:500;box-shadow:inset 3px 0 0 var(--cad-accent)}:host(.is-right) .cad-nav-drawer__item.is-active{box-shadow:inset -3px 0 0 var(--cad-accent)}.cad-nav-drawer__item.is-disabled,.cad-nav-drawer__item:disabled{opacity:.45;cursor:not-allowed}.cad-nav-drawer__label{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.cad-nav-drawer__badge{flex:none;font-size:10.5px;font-family:var(--cad-font-mono);border-radius:var(--cad-radius-pill);padding:1px 7px;background:var(--cad-elevated, var(--cad-border));color:var(--cad-fg-secondary)}.cad-nav-drawer__item.is-active .cad-nav-drawer__badge{background:var(--cad-accent);color:var(--cad-fg-on-accent)}.cad-nav-drawer__dot{position:absolute;margin:-14px 0 0 14px;width:7px;height:7px;border-radius:50%;background:var(--cad-danger, #f85149)}.cad-nav-drawer__foot{flex:none;border-top:1px solid var(--cad-border);padding:10px 14px}.cad-nav-drawer__foot.is-empty{display:none}:host(.is-rail) .cad-nav-drawer__foot{padding:10px 0;display:flex;justify-content:center}:host-context(.cad-touch) .cad-nav-drawer__item{min-height:44px}@media(prefers-reduced-motion:reduce){.cad-nav-drawer__panel{transition:none}}\n"], dependencies: [{ kind: "component", type: CadIconComponent, selector: "cad-icon", inputs: ["name", "size", "strokeWidth", "label", "title", "spin", "filled", "flip", "rotate"] }, { kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
9449
+ }
9450
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: CadNavDrawerComponent, decorators: [{
9451
+ type: Component,
9452
+ args: [{ selector: 'cad-nav-drawer', standalone: true, imports: [CadIconComponent, RouterLink, NgTemplateOutlet], changeDetection: ChangeDetectionStrategy.OnPush, host: {
9453
+ class: 'cad-nav-drawer',
9454
+ '[class.is-temporary]': 'temporary()',
9455
+ '[class.is-permanent]': '!temporary()',
9456
+ '[class.is-rail]': 'rail()',
9457
+ '[class.is-open]': 'open()',
9458
+ '[class.is-right]': 'position() === "right"',
9459
+ }, template: `
9460
+ <!-- Le voile n'existe qu'en mode tiroir : en permanent il n'y a rien à recouvrir. -->
9461
+ @if (temporary() && open()) {
9462
+ <div class="cad-nav-drawer__scrim" (click)="dismiss()" aria-hidden="true"></div>
9463
+ }
9464
+
9465
+ <nav
9466
+ class="cad-nav-drawer__panel"
9467
+ [attr.aria-label]="ariaLabel()"
9468
+ [attr.aria-hidden]="temporary() && !open() ? 'true' : null"
9469
+ [attr.inert]="temporary() && !open() ? '' : null"
9470
+ >
9471
+ <div class="cad-nav-drawer__head">
9472
+ <ng-content select="[cadNavDrawerHeader]"/>
9473
+ @if (!headerSlot()) {
9474
+ @if (icon()) {<cad-icon [name]="icon()" [size]="18"/>}
9475
+ @if (!rail()) {<b>{{ title() }}</b>}
9476
+ }
9477
+ </div>
9478
+
9479
+ <ul class="cad-nav-drawer__list" role="list">
9480
+ @for (it of items(); track $index) {
9481
+ @if (it.section) {
9482
+ <!-- En rail, un intertitre n'a plus de place : un filet le remplace. -->
9483
+ @if (rail()) {
9484
+ <li class="cad-nav-drawer__rule" role="separator"></li>
9485
+ } @else {
9486
+ <li class="cad-nav-drawer__section">{{ it.label }}</li>
9487
+ }
9488
+ } @else {
9489
+ <li>
9490
+ @if (it.routerLink) {
9491
+ <a class="cad-nav-drawer__item" [class.is-active]="isActive(it)" [class.is-disabled]="it.disabled"
9492
+ [routerLink]="it.routerLink" [queryParams]="it.queryParams"
9493
+ [attr.aria-current]="isActive(it) ? 'page' : null" [attr.aria-disabled]="it.disabled || null"
9494
+ [attr.title]="rail() ? it.label : null" [attr.aria-label]="it.ariaLabel || (rail() ? it.label : null)"
9495
+ (click)="pick(it, $event)">
9496
+ <ng-container *ngTemplateOutlet="row; context: { $implicit: it }"/>
9497
+ </a>
9498
+ } @else if (it.url) {
9499
+ <a class="cad-nav-drawer__item" [class.is-active]="isActive(it)" [class.is-disabled]="it.disabled"
9500
+ [href]="it.url" [attr.target]="it.target || null"
9501
+ [attr.title]="rail() ? it.label : null" [attr.aria-label]="it.ariaLabel || (rail() ? it.label : null)"
9502
+ (click)="pick(it, $event)">
9503
+ <ng-container *ngTemplateOutlet="row; context: { $implicit: it }"/>
9504
+ </a>
9505
+ } @else {
9506
+ <button type="button" class="cad-nav-drawer__item" [class.is-active]="isActive(it)"
9507
+ [disabled]="it.disabled" [attr.title]="rail() ? it.label : null"
9508
+ [attr.aria-label]="it.ariaLabel || (rail() ? it.label : null)"
9509
+ [attr.aria-current]="isActive(it) ? 'page' : null" (click)="pick(it, $event)">
9510
+ <ng-container *ngTemplateOutlet="row; context: { $implicit: it }"/>
9511
+ </button>
9512
+ }
9513
+ </li>
9514
+ }
9515
+ }
9516
+ </ul>
9517
+
9518
+ <!-- Toujours rendu : la projection a lieu quoi qu'il arrive. Le cadre ne s'affiche
9519
+ que si un pied a bien été fourni, sinon on verrait un filet et un vide. -->
9520
+ <div class="cad-nav-drawer__foot" [class.is-empty]="!footerSlot()">
9521
+ <ng-content select="[cadNavDrawerFooter]"/>
9522
+ </div>
9523
+ </nav>
9524
+
9525
+ <ng-template #row let-it>
9526
+ @if (it.icon) {<cad-icon [name]="it.icon" [size]="17"/>}
9527
+ @if (!rail()) {
9528
+ <span class="cad-nav-drawer__label">{{ it.label }}</span>
9529
+ @if (it.badge !== undefined && it.badge !== null) {<span class="cad-nav-drawer__badge">{{ it.badge }}</span>}
9530
+ } @else if (it.badge !== undefined && it.badge !== null) {
9531
+ <!-- En rail le compte ne tient pas : il devient un point, le nombre reste en title. -->
9532
+ <span class="cad-nav-drawer__dot" [attr.title]="it.badge"></span>
9533
+ }
9534
+ </ng-template>
9535
+ `, styles: [":host{display:block}:host(.is-permanent){flex:none}.cad-nav-drawer__panel{display:flex;flex-direction:column;min-height:0;height:100%;width:var(--cad-nav-drawer-w, 240px);background:var(--cad-bg-subtle);border-right:1px solid var(--cad-border);transition:width var(--cad-dur) var(--cad-ease)}:host(.is-rail) .cad-nav-drawer__panel{width:var(--cad-nav-drawer-rail-w, 56px)}:host(.is-right) .cad-nav-drawer__panel{border-right:0;border-left:1px solid var(--cad-border)}:host(.is-temporary){position:fixed;inset:0 auto 0 0;z-index:var(--cad-z-overlay, 100002);pointer-events:none}:host(.is-temporary.is-right){inset:0 0 0 auto}:host(.is-temporary) .cad-nav-drawer__panel{pointer-events:auto;height:100%;box-shadow:var(--cad-shadow-lg, 0 12px 24px rgba(15,23,42,.18));transform:translate(-100%);transition:transform var(--cad-dur) var(--cad-ease)}:host(.is-temporary.is-right) .cad-nav-drawer__panel{transform:translate(100%)}:host(.is-temporary.is-open) .cad-nav-drawer__panel{transform:translate(0)}.cad-nav-drawer__scrim{position:fixed;inset:0;background:var(--cad-backdrop, rgba(2,6,23,.45));pointer-events:auto;z-index:-1}.cad-nav-drawer__head{display:flex;align-items:center;gap:9px;flex:none;padding:14px 14px 12px;border-bottom:1px solid var(--cad-border);min-height:48px;color:var(--cad-fg);font-size:13px}:host(.is-rail) .cad-nav-drawer__head{justify-content:center;padding:14px 0 12px}.cad-nav-drawer__head cad-icon{color:var(--cad-accent);flex:none}.cad-nav-drawer__list{list-style:none;margin:0;padding:8px 0;flex:1;min-height:0;overflow-y:auto}.cad-nav-drawer__section{padding:12px 14px 5px;font-size:10px;font-weight:500;letter-spacing:.07em;text-transform:uppercase;color:var(--cad-fg-muted)}.cad-nav-drawer__rule{height:1px;margin:8px 12px;background:var(--cad-border)}.cad-nav-drawer__item{all:unset;box-sizing:border-box;display:flex;align-items:center;gap:10px;width:100%;cursor:pointer;padding:8px 14px;min-height:38px;color:var(--cad-fg-secondary);font:12.5px var(--cad-font);text-decoration:none}:host(.is-rail) .cad-nav-drawer__item{justify-content:center;padding:10px 0}.cad-nav-drawer__item:hover{background:var(--cad-hover);color:var(--cad-fg)}.cad-nav-drawer__item:focus-visible{outline:2px solid var(--cad-accent);outline-offset:-2px}.cad-nav-drawer__item.is-active{background:var(--cad-accent-soft);color:var(--cad-accent);font-weight:500;box-shadow:inset 3px 0 0 var(--cad-accent)}:host(.is-right) .cad-nav-drawer__item.is-active{box-shadow:inset -3px 0 0 var(--cad-accent)}.cad-nav-drawer__item.is-disabled,.cad-nav-drawer__item:disabled{opacity:.45;cursor:not-allowed}.cad-nav-drawer__label{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.cad-nav-drawer__badge{flex:none;font-size:10.5px;font-family:var(--cad-font-mono);border-radius:var(--cad-radius-pill);padding:1px 7px;background:var(--cad-elevated, var(--cad-border));color:var(--cad-fg-secondary)}.cad-nav-drawer__item.is-active .cad-nav-drawer__badge{background:var(--cad-accent);color:var(--cad-fg-on-accent)}.cad-nav-drawer__dot{position:absolute;margin:-14px 0 0 14px;width:7px;height:7px;border-radius:50%;background:var(--cad-danger, #f85149)}.cad-nav-drawer__foot{flex:none;border-top:1px solid var(--cad-border);padding:10px 14px}.cad-nav-drawer__foot.is-empty{display:none}:host(.is-rail) .cad-nav-drawer__foot{padding:10px 0;display:flex;justify-content:center}:host-context(.cad-touch) .cad-nav-drawer__item{min-height:44px}@media(prefers-reduced-motion:reduce){.cad-nav-drawer__panel{transition:none}}\n"] }]
9536
+ }], ctorParameters: () => [], propDecorators: { items: [{ type: i0.Input, args: [{ isSignal: true, alias: "items", required: false }] }], open: [{ type: i0.Input, args: [{ isSignal: true, alias: "open", required: false }] }, { type: i0.Output, args: ["openChange"] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }, { type: i0.Output, args: ["valueChange"] }], mode: [{ type: i0.Input, args: [{ isSignal: true, alias: "mode", required: false }] }], breakpoint: [{ type: i0.Input, args: [{ isSignal: true, alias: "breakpoint", required: false }] }], position: [{ type: i0.Input, args: [{ isSignal: true, alias: "position", required: false }] }], title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: false }] }], icon: [{ type: i0.Input, args: [{ isSignal: true, alias: "icon", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], closeOnNavigate: [{ type: i0.Input, args: [{ isSignal: true, alias: "closeOnNavigate", required: false }] }], closeOnEscape: [{ type: i0.Input, args: [{ isSignal: true, alias: "closeOnEscape", required: false }] }], dismissableScrim: [{ type: i0.Input, args: [{ isSignal: true, alias: "dismissableScrim", required: false }] }], opened: [{ type: i0.Output, args: ["opened"] }], closed: [{ type: i0.Output, args: ["closed"] }], itemClick: [{ type: i0.Output, args: ["itemClick"] }], changed: [{ type: i0.Output, args: ["changed"] }], headerSlot: [{ type: i0.ContentChild, args: [i0.forwardRef(() => CadNavDrawerHeaderDirective), { isSignal: true }] }], footerSlot: [{ type: i0.ContentChild, args: [i0.forwardRef(() => CadNavDrawerFooterDirective), { isSignal: true }] }], onEscape: [{
9537
+ type: HostListener,
9538
+ args: ['document:keydown.escape']
9539
+ }] } });
9540
+
9043
9541
  /**
9044
9542
  * Déclarations (inputs / outputs / models / contenu projeté) de cad-table — classe de base pour tenir la limite de taille du composant.
9045
9543
  * Toute la logique reste dans CadTableComponent.
@@ -13645,7 +14143,11 @@ class CadMapComponent {
13645
14143
  tm.jumpTo({ center: [c.lng, c.lat], zoom: this.map.getZoom(), bearing: this.map.getBearing(), pitch: this.map.getPitch() });
13646
14144
  t.syncing = false;
13647
14145
  }
13648
- destroy() { this.chromeRef?.destroy(); this.ro?.disconnect(); this.roCorners?.disconnect(); this.themeObs?.disconnect(); this.closePopup(); this.tooltip?.remove(); try {
14146
+ destroy() { this.chromeRef?.destroy(); this.ro?.disconnect(); this.roCorners?.disconnect(); this.themeObs?.disconnect(); try {
14147
+ this.closePopup();
14148
+ this.tooltip?.remove();
14149
+ }
14150
+ catch { /* carte déjà démontée */ } try {
13649
14151
  this.map?.remove();
13650
14152
  }
13651
14153
  catch { /* déjà détruit */ } this.map = null; }
@@ -13686,6 +14188,14 @@ const FR_LOCALE = {
13686
14188
  'ScaleControl.Meters': 'm', 'ScaleControl.Kilometers': 'km', 'CooperativeGesturesHandler.WindowsHelpText': 'Utilisez Ctrl + molette pour zoomer', 'CooperativeGesturesHandler.MacHelpText': 'Utilisez ⌘ + molette pour zoomer', 'CooperativeGesturesHandler.MobileHelpText': 'Utilisez deux doigts pour déplacer la carte',
13687
14189
  };
13688
14190
 
14191
+ /**
14192
+ * Une carte MapLibre détruite garde son objet mais perd son `style`. Tout appel qui le
14193
+ * traverse — `getLayer`, `getSource`, `off` — lève alors un TypeError. C'est le seul signe
14194
+ * fiable qu'on puisse encore lui parler.
14195
+ */
14196
+ function cadMapEstVivante(map) {
14197
+ return !!map && !!map.style;
14198
+ }
13689
14199
  /**
13690
14200
  * <cad-map-layer id="oa" label="Ouvrages d'art" type="geojson" [data]="geojson" [style]="{ color: { field:'etat', categories:{…} }, radius: 6 }" cluster [popupTemplate]="tpl" (featureClick)/>
13691
14201
  * <cad-map-layer id="ppri" label="PPRI" type="wms" url="https://…/wms" layers="PPRI" [opacity]=".6"/>
@@ -13776,7 +14286,38 @@ class CadMapLayerComponent {
13776
14286
  this.bindEvents(map);
13777
14287
  this.loaded.emit();
13778
14288
  }
13779
- detach(map) { this.unbindEvents(map); this.removeAll(map); this.attached = false; }
14289
+ /**
14290
+ * Chemin de DÉMONTAGE : il ne doit JAMAIS lever.
14291
+ *
14292
+ * Bug signalé par SZU le 21/08/2026 — « au clic sur un élément de menu, parfois, le
14293
+ * contenu est blanc, puis quelques secondes plus tard le menu redevient fonctionnel et
14294
+ * la page est la bonne ». En quittant une page portant une carte :
14295
+ *
14296
+ * TypeError: Cannot read properties of undefined (reading 'getLayer')
14297
+ * at removeAll -> detach -> ... -> ComponentRef.destroy
14298
+ *
14299
+ * `detach` était appelé DEUX fois à la destruction : une fois par `unregisterChild`
14300
+ * (protégé côté cad-map) et une fois directement, sans garde. Le second passage
14301
+ * s'exécutait sur une carte déjà démontée par MapLibre — `map.style` vaut alors
14302
+ * `undefined` et `map.getLayer()` lève. Une exception pendant la destruction interrompt
14303
+ * le démontage de la vue : d'où l'écran blanc et le menu figé.
14304
+ *
14305
+ * Deux verrous, parce qu'un seul ne suffit pas : on ne touche à la carte que si elle est
14306
+ * encore vivante, ET on avale ce qui pourrait malgré tout échapper. Un nettoyage qui lève
14307
+ * est toujours pire que le déchet qu'il aurait laissé.
14308
+ */
14309
+ detach(map) {
14310
+ try {
14311
+ if (cadMapEstVivante(map)) {
14312
+ this.unbindEvents(map);
14313
+ this.removeAll(map);
14314
+ }
14315
+ }
14316
+ catch {
14317
+ /* carte déjà démontée : il n'y a plus rien à retirer */
14318
+ }
14319
+ this.attached = false;
14320
+ }
13780
14321
  removeAll(map) {
13781
14322
  for (const id of this.allLayerIds())
13782
14323
  if (map.getLayer(id))
@@ -14136,7 +14677,17 @@ class CadMapSearchComponent {
14136
14677
  timer = null;
14137
14678
  ctrl = null;
14138
14679
  mk = null;
14139
- constructor() { inject(DestroyRef).onDestroy(() => { this.mk?.remove(); this.ctrl?.abort(); }); }
14680
+ constructor() {
14681
+ // Démontage : la carte peut déjà avoir été détruite par cad-map, auquel cas retirer le
14682
+ // marqueur lève et casse le reste du cycle (même défaut que cad-map-layer.detach, 21/08).
14683
+ inject(DestroyRef).onDestroy(() => {
14684
+ try {
14685
+ this.mk?.remove();
14686
+ }
14687
+ catch { /* carte déjà démontée */ }
14688
+ this.ctrl?.abort();
14689
+ });
14690
+ }
14140
14691
  onInput(v) {
14141
14692
  this.q.set(v);
14142
14693
  this.searched.set(false);
@@ -17447,5 +17998,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.20", ngImpo
17447
17998
  * Generated bundle index. Do not edit.
17448
17999
  */
17449
18000
 
17450
- export { BanGeocoder, CAD_BREAKPOINTS, CAD_CHART_PALETTE, CAD_COLOR_PRESETS, CAD_DEFAULT_BASEMAPS, CAD_DEFAULT_PRIORITY_BREAKPOINTS, CAD_DIALOG_DATA, CAD_FILTER_OPERATORS, CAD_GEOCODER, CAD_ICONS, CAD_ICONS_CEREMA, CAD_ICONS_CORE, CAD_ICONS_DATA, CAD_ICONS_FILES, CAD_ICONS_GEO, CAD_ICONS_SUBSET, CAD_ICONS_TOKEN, CAD_ICONS_UI, CAD_ICON_ALIASES, CAD_ICON_CATEGORIES, CAD_MAPLIBRE_CSS_URL, CAD_MAP_CHILD, CAD_MAP_DEFAULTS, CAD_MAP_GLOBAL_STYLES, CAD_MAP_GLYPHS, CAD_MAP_PALETTE, CAD_MASK_PRESETS, CAD_MOBILE_BREAKPOINT, CAD_SELECT_POSITIONS, CAD_SELECT_TRIGGER_STYLES, CAD_SHEET_DATA, CAD_TOUCH_DENSITY, CadAccordionComponent, CadAccordionPanelComponent, CadAvatarComponent, CadAvatarGroupComponent, CadBadgeComponent, CadBadgeDirective, CadBlockDirective, CadBlockOverlayComponent, CadBlockUiComponent, CadBreadcrumbComponent, CadBreadcrumbItemDirective, CadBreakpointService, CadButtonComponent, CadButtonGroupComponent, CadCaptionDirective, CadCardComponent, CadCardDirective, CadCardHeaderDirective, CadCarouselComponent, CadCarouselItemDirective, CadCascadeSelectComponent, CadCellTemplateDirective, CadCenterComponent, CadChartComponent, CadCheckboxComponent, CadChipComponent, CadClusterComponent, CadColDirective, CadColorpickerComponent, CadColumnComponent, CadComboComponent, CadConfirmContentComponent, CadConfirmDialogComponent, CadConfirmService, CadContainerComponent, CadDataviewComponent, CadDataviewGridDirective, CadDataviewListDirective, CadDatepickerComponent, CadDialogComponent, CadDialogContainerComponent, CadDialogFooterDirective, CadDialogHeaderDirective, CadDialogRef, CadDialogService, CadDividerComponent, CadDrawerComponent, CadEditFocusDirective, CadEditorTemplateDirective, CadEmptyDirective, CadFieldComponent, CadFieldsetComponent, CadFieldsetLegendDirective, CadFilterChipComponent, CadFilterTemplateDirective, CadGeocodingService, CadGridComponent, CadGroupFooterDirective, CadGroupHeaderDirective, CadHeaderTemplateDirective, CadIconComponent, CadIconRegistry, CadIfDirective, CadImageComponent, CadInplaceComponent, CadInplaceContentDirective, CadInplaceDisplayDirective, CadInputDirective, CadJsonEditorComponent, CadKeyFilterDirective, CadListEmptyDirective, CadListFooterDirective, CadListHeaderDirective, CadListItemDirective, CadListboxComponent, CadMapBasemapRegistry, CadMapBasemapsComponent, CadMapCardComponent, CadMapChromeComponent, CadMapComponent, CadMapDrawEngine, CadMapLayerComponent, CadMapLayerGroupComponent, CadMapLayerToggleComponent, CadMapLegendComponent, CadMapMenuComponent, CadMapPanelComponent, CadMapPanels, CadMapRailComponent, CadMapRailItemComponent, CadMapSearchComponent, CadMapSectionComponent, CadMaskDirective, CadMenuComponent, CadMenubarComponent, CadMessageComponent, CadMeterComponent, CadMeterLabelDirective, CadMultiselectComponent, CadNumberComponent, CadOptionListComponent, CadOrderlistComponent, CadOrgNodeDirective, CadOrgchartComponent, CadOverlayBase, CadPaginatorComponent, CadPanelComponent, CadPanelContentDirective, CadPanelHeaderDirective, CadPanelHeadingDirective, CadPasswordComponent, CadPicklistComponent, CadPopoverComponent, CadProgressComponent, CadRadioComponent, CadRadioGroupComponent, CadRatingComponent, CadRowActionsDirective, CadRowCountDirective, CadRowExpansionDirective, CadScrollTopComponent, CadSegmentedComponent, CadSelectBase, CadSelectComponent, CadSelectEmptyDirective, CadSelectFooterDirective, CadSelectHeaderDirective, CadSelectItemDirective, CadSelectSelectedDirective, CadSheetContainerComponent, CadSheetRef, CadSheetService, CadSidebarComponent, CadSidebarPanelDirective, CadSkeletonComponent, CadSliderComponent, CadSpacerComponent, CadSpeedDialComponent, CadSpinnerComponent, CadSplitButtonComponent, CadSplitComponent, CadSplitterComponent, CadSplitterPanelComponent, CadStackComponent, CadStepComponent, CadStepperComponent, CadSwitchComponent, CadTabComponent, CadTabContentDirective, CadTabLabelDirective, CadTableBase, CadTableComponent, CadTableEdit, CadTableEditUi, CadTableFooterDirective, CadTablePanelComponent, CadTableResponsive, CadTableSelection, CadTableSticky, CadTableVirtual, CadTabsComponent, CadTagComponent, CadTimelineComponent, CadTimelineContentDirective, CadTimelineMarkerDirective, CadTimelineOppositeDirective, CadToastComponent, CadToastItemDirective, CadToastService, CadToggleButtonComponent, CadTooltipComponent, CadTooltipDirective, CadTreeAdapter, CadTreeComponent, CadTreeNodeDirective, CadTreeselectComponent, CadUploadComponent, CadUploadContentDirective, CadUploadEmptyDirective, CadUploadItemDirective, CadValueAccessor, MAPLIBRE_MIN_CSS, addDays, addMonths, addYears, cadAggregate, cadApplyColumnOrder, cadApplyMask, cadArea, cadAutosizeWidth, cadBasemapThumbnail, cadBoundsOf, cadCategories, cadCentroid, cadColorExpr, cadCompare, cadCurrentOperator, cadDefaultMatchMode, cadDistance, cadDownloadCsv, cadFilterData, cadFilterKindOf, cadFilterOperators, cadFilterRows, cadFmtArea, cadFmtLength, cadFormatCell, cadFormatColor, cadFormatSize, cadGap, cadGeoJSONStats, cadGeometryKinds, cadHeaderMenuItems, cadHighlightJson, cadHslToRgb, cadHsvToRgb, cadId, cadIsGroupKey, cadJsonErrorPos, cadLegendFromStyle, cadLength, cadMapLayerOf, cadMapLayersOf, cadMatch, cadMoveColumn, cadMoveItems, cadNormalize, cadNormalizeOptions, cadNumberExpr, cadPadBounds, cadParseColor, cadParseResponsive, cadPropsTable, cadResolve, cadResolveResponsive, cadResponsive, cadRgbToHsl, cadRgbToHsv, cadRingArea, cadRowKey, cadRowPredicate, cadSameValue, cadSortData, cadStartResize, cadStyleToExpressions, cadUnmask, cadValidateGeoJSON, cadValueForOperator, cadWriteField, compareDay, daysInMonth, endOfMonth, ensureMaplibreCss, formatDate, isBetweenDay, isSameDay, isSameMonth, isValidDate, isoOf, isoWeek, loadChartJs, loadMaplibre, monthNames, pad2, parseIso, parseWithFormat, provideCadIcons, startOfDay, startOfMonth, toDate, weekdayNames };
18001
+ export { BanGeocoder, CAD_BREAKPOINTS, CAD_CHART_PALETTE, CAD_COLOR_PRESETS, CAD_DEFAULT_BASEMAPS, CAD_DEFAULT_PRIORITY_BREAKPOINTS, CAD_DIALOG_DATA, CAD_FILTER_OPERATORS, CAD_GEOCODER, CAD_ICONS, CAD_ICONS_CEREMA, CAD_ICONS_CORE, CAD_ICONS_DATA, CAD_ICONS_FILES, CAD_ICONS_GEO, CAD_ICONS_SUBSET, CAD_ICONS_TOKEN, CAD_ICONS_UI, CAD_ICON_ALIASES, CAD_ICON_CATEGORIES, CAD_MAPLIBRE_CSS_URL, CAD_MAP_CHILD, CAD_MAP_DEFAULTS, CAD_MAP_GLOBAL_STYLES, CAD_MAP_GLYPHS, CAD_MAP_PALETTE, CAD_MASK_PRESETS, CAD_MOBILE_BREAKPOINT, CAD_SELECT_POSITIONS, CAD_SELECT_TRIGGER_STYLES, CAD_SHEET_DATA, CAD_TOUCH_DENSITY, CadAccordionComponent, CadAccordionPanelComponent, CadAvatarComponent, CadAvatarGroupComponent, CadBadgeComponent, CadBadgeDirective, CadBlockDirective, CadBlockOverlayComponent, CadBlockUiComponent, CadBottomNavComponent, CadBreadcrumbComponent, CadBreadcrumbItemDirective, CadBreakpointService, CadButtonComponent, CadButtonGroupComponent, CadCaptionDirective, CadCardComponent, CadCardDirective, CadCardHeaderDirective, CadCarouselComponent, CadCarouselItemDirective, CadCascadeSelectComponent, CadCellTemplateDirective, CadCenterComponent, CadChartComponent, CadCheckboxComponent, CadChipComponent, CadClusterComponent, CadColDirective, CadColorpickerComponent, CadColumnComponent, CadComboComponent, CadConfirmContentComponent, CadConfirmDialogComponent, CadConfirmService, CadContainerComponent, CadDataviewComponent, CadDataviewGridDirective, CadDataviewListDirective, CadDatepickerComponent, CadDialogComponent, CadDialogContainerComponent, CadDialogFooterDirective, CadDialogHeaderDirective, CadDialogRef, CadDialogService, CadDividerComponent, CadDrawerComponent, CadEditFocusDirective, CadEditorTemplateDirective, CadEmptyDirective, CadFieldComponent, CadFieldsetComponent, CadFieldsetLegendDirective, CadFilterChipComponent, CadFilterTemplateDirective, CadGeocodingService, CadGridComponent, CadGroupFooterDirective, CadGroupHeaderDirective, CadHeaderTemplateDirective, CadIconComponent, CadIconRegistry, CadIfDirective, CadImageComponent, CadInplaceComponent, CadInplaceContentDirective, CadInplaceDisplayDirective, CadInputDirective, CadJsonEditorComponent, CadKeyFilterDirective, CadListEmptyDirective, CadListFooterDirective, CadListHeaderDirective, CadListItemDirective, CadListboxComponent, CadMapBasemapRegistry, CadMapBasemapsComponent, CadMapCardComponent, CadMapChromeComponent, CadMapComponent, CadMapDrawEngine, CadMapLayerComponent, CadMapLayerGroupComponent, CadMapLayerToggleComponent, CadMapLegendComponent, CadMapMenuComponent, CadMapPanelComponent, CadMapPanels, CadMapRailComponent, CadMapRailItemComponent, CadMapSearchComponent, CadMapSectionComponent, CadMaskDirective, CadMenuComponent, CadMenubarComponent, CadMessageComponent, CadMeterComponent, CadMeterLabelDirective, CadMultiselectComponent, CadNavDrawerComponent, CadNavDrawerFooterDirective, CadNavDrawerHeaderDirective, CadNumberComponent, CadOptionListComponent, CadOrderlistComponent, CadOrgNodeDirective, CadOrgchartComponent, CadOverlayBase, CadPaginatorComponent, CadPanelComponent, CadPanelContentDirective, CadPanelHeaderDirective, CadPanelHeadingDirective, CadPasswordComponent, CadPicklistComponent, CadPopoverComponent, CadProgressComponent, CadRadioComponent, CadRadioGroupComponent, CadRatingComponent, CadRowActionsDirective, CadRowCountDirective, CadRowExpansionDirective, CadScrollTopComponent, CadSegmentedComponent, CadSelectBase, CadSelectComponent, CadSelectEmptyDirective, CadSelectFooterDirective, CadSelectHeaderDirective, CadSelectItemDirective, CadSelectSelectedDirective, CadSheetContainerComponent, CadSheetRef, CadSheetService, CadSidebarComponent, CadSidebarPanelDirective, CadSkeletonComponent, CadSliderComponent, CadSpacerComponent, CadSpeedDialComponent, CadSpinnerComponent, CadSplitButtonComponent, CadSplitComponent, CadSplitterComponent, CadSplitterPanelComponent, CadStackComponent, CadStepComponent, CadStepperComponent, CadSwitchComponent, CadTabComponent, CadTabContentDirective, CadTabLabelDirective, CadTableBase, CadTableComponent, CadTableEdit, CadTableEditUi, CadTableFooterDirective, CadTablePanelComponent, CadTableResponsive, CadTableSelection, CadTableSticky, CadTableVirtual, CadTabsComponent, CadTagComponent, CadTimelineComponent, CadTimelineContentDirective, CadTimelineMarkerDirective, CadTimelineOppositeDirective, CadToastComponent, CadToastItemDirective, CadToastService, CadToggleButtonComponent, CadTooltipComponent, CadTooltipDirective, CadTreeAdapter, CadTreeComponent, CadTreeNodeDirective, CadTreeselectComponent, CadUploadComponent, CadUploadContentDirective, CadUploadEmptyDirective, CadUploadItemDirective, CadValueAccessor, MAPLIBRE_MIN_CSS, addDays, addMonths, addYears, cadAggregate, cadApplyColumnOrder, cadApplyMask, cadArea, cadAutosizeWidth, cadBasemapThumbnail, cadBoundsOf, cadCategories, cadCentroid, cadColorExpr, cadCompare, cadCurrentOperator, cadDefaultMatchMode, cadDistance, cadDownloadCsv, cadFilterData, cadFilterKindOf, cadFilterOperators, cadFilterRows, cadFmtArea, cadFmtLength, cadFormatCell, cadFormatColor, cadFormatSize, cadGap, cadGeoJSONStats, cadGeometryKinds, cadHeaderMenuItems, cadHighlightJson, cadHslToRgb, cadHsvToRgb, cadId, cadIsGroupKey, cadJsonErrorPos, cadLegendFromStyle, cadLength, cadMapEstVivante, cadMapLayerOf, cadMapLayersOf, cadMatch, cadMoveColumn, cadMoveItems, cadNormalize, cadNormalizeOptions, cadNumberExpr, cadPadBounds, cadParseColor, cadParseResponsive, cadPropsTable, cadResolve, cadResolveResponsive, cadResponsive, cadRgbToHsl, cadRgbToHsv, cadRingArea, cadRowKey, cadRowPredicate, cadSameValue, cadSortData, cadStartResize, cadStyleToExpressions, cadUnmask, cadValidateGeoJSON, cadValueForOperator, cadWriteField, compareDay, daysInMonth, endOfMonth, ensureMaplibreCss, formatDate, isBetweenDay, isSameDay, isSameMonth, isValidDate, isoOf, isoWeek, loadChartJs, loadMaplibre, monthNames, pad2, parseIso, parseWithFormat, provideCadIcons, startOfDay, startOfMonth, toDate, weekdayNames };
17451
18002
  //# sourceMappingURL=cadriciel-ui.mjs.map