@educarehq/solaris-ui 0.16.1 → 0.17.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,9 +1,9 @@
1
1
  import * as i0 from '@angular/core';
2
- import { InjectionToken, inject, PLATFORM_ID, Injectable, Pipe, Directive, signal, DestroyRef, DOCUMENT, input, computed, ChangeDetectionStrategy, Component, output, ElementRef, EnvironmentInjector, effect, createComponent, HostListener, contentChild, contentChildren, NgZone, TemplateRef, ViewContainerRef, Injector, viewChild, isDevMode, forwardRef, ChangeDetectorRef, booleanAttribute, numberAttribute, afterNextRender, viewChildren, ApplicationRef, model } from '@angular/core';
3
- import { isPlatformBrowser, NgTemplateOutlet, DOCUMENT as DOCUMENT$1 } from '@angular/common';
4
- import { FormControlDirective, FormControlName, NgModel, NG_VALUE_ACCESSOR, NgControl, FormsModule } from '@angular/forms';
2
+ import { InjectionToken, inject, PLATFORM_ID, Injectable, Pipe, Directive, signal, DestroyRef, DOCUMENT, input, computed, ChangeDetectionStrategy, Component, output, ElementRef, EnvironmentInjector, effect, createComponent, HostListener, model, TemplateRef, ViewContainerRef, contentChild, forwardRef, ViewChild, ViewEncapsulation, Renderer2, contentChildren, NgZone, Injector, viewChild, isDevMode, ChangeDetectorRef, booleanAttribute, numberAttribute, afterNextRender, viewChildren, ApplicationRef } from '@angular/core';
3
+ import { isPlatformBrowser, DOCUMENT as DOCUMENT$1, NgTemplateOutlet } from '@angular/common';
5
4
  import { Overlay, OverlayConfig } from '@angular/cdk/overlay';
6
- import { ComponentPortal } from '@angular/cdk/portal';
5
+ import { TemplatePortal, ComponentPortal } from '@angular/cdk/portal';
6
+ import { FormControlDirective, FormControlName, NgModel, NG_VALUE_ACCESSOR, NgControl, FormsModule } from '@angular/forms';
7
7
  import { DomSanitizer } from '@angular/platform-browser';
8
8
  import { getCountries, getCountryCallingCode, Metadata, AsYouType, parsePhoneNumberFromString, getExampleNumber } from 'libphonenumber-js';
9
9
  import * as FLAG_3X2 from 'country-flag-icons/string/3x2';
@@ -78,6 +78,8 @@ const SOLARIS_TRANSLATE_DEFAULT_CONFIG = {
78
78
  'solaris.toast.continue': 'click to continue',
79
79
  'solaris.toast.expand': 'Expand',
80
80
  'solaris.toast.collapse': 'Collapse',
81
+ 'solaris.menuToggle.open': 'Open menu',
82
+ 'solaris.menuToggle.close': 'Close menu',
81
83
  'solaris.dialog.close': 'Close',
82
84
  'solaris.dialog.confirm': 'Confirm',
83
85
  'solaris.dialog.cancel': 'Cancel',
@@ -2398,6 +2400,24 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImpo
2398
2400
  args: [{ selector: 'solaris-icon', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, template: "@if (definition(); as icon) {\n <svg\n width=\"100%\"\n height=\"100%\"\n [attr.viewBox]=\"icon.viewBox\"\n [attr.fill]=\"icon.fill ?? 'none'\"\n [attr.stroke]=\"resolvedStroke()\"\n [attr.stroke-width]=\"resolvedStrokeWidth()\"\n [attr.stroke-linecap]=\"icon.strokeLinecap ?? 'round'\"\n [attr.stroke-linejoin]=\"icon.strokeLinejoin ?? 'round'\"\n [attr.aria-hidden]=\"isHidden() ? 'true' : null\"\n [attr.aria-label]=\"hasSemanticLabel() ? accessibleLabel() : null\"\n [attr.role]=\"isHidden() ? 'presentation' : 'img'\"\n >\n @for (element of icon.elements; track $index) {\n @switch (element.type) {\n @case ('path') {\n <path\n [attr.d]=\"element.d\"\n [attr.fill]=\"element.fill ?? null\"\n [attr.stroke]=\"element.stroke ?? null\"\n [attr.stroke-width]=\"element.strokeWidth ?? null\"\n [attr.stroke-linecap]=\"element.strokeLinecap ?? null\"\n [attr.stroke-linejoin]=\"element.strokeLinejoin ?? null\"\n />\n }\n @case ('line') {\n <line\n [attr.x1]=\"element.x1\"\n [attr.y1]=\"element.y1\"\n [attr.x2]=\"element.x2\"\n [attr.y2]=\"element.y2\"\n [attr.fill]=\"element.fill ?? null\"\n [attr.stroke]=\"element.stroke ?? null\"\n [attr.stroke-width]=\"element.strokeWidth ?? null\"\n [attr.stroke-linecap]=\"element.strokeLinecap ?? null\"\n [attr.stroke-linejoin]=\"element.strokeLinejoin ?? null\"\n />\n }\n @case ('polyline') {\n <polyline\n [attr.points]=\"element.points\"\n [attr.fill]=\"element.fill ?? null\"\n [attr.stroke]=\"element.stroke ?? null\"\n [attr.stroke-width]=\"element.strokeWidth ?? null\"\n [attr.stroke-linecap]=\"element.strokeLinecap ?? null\"\n [attr.stroke-linejoin]=\"element.strokeLinejoin ?? null\"\n />\n }\n @case ('polygon') {\n <polygon\n [attr.points]=\"element.points\"\n [attr.fill]=\"element.fill ?? null\"\n [attr.stroke]=\"element.stroke ?? null\"\n [attr.stroke-width]=\"element.strokeWidth ?? null\"\n [attr.stroke-linecap]=\"element.strokeLinecap ?? null\"\n [attr.stroke-linejoin]=\"element.strokeLinejoin ?? null\"\n />\n }\n @case ('circle') {\n <circle\n [attr.cx]=\"element.cx\"\n [attr.cy]=\"element.cy\"\n [attr.r]=\"element.r\"\n [attr.fill]=\"element.fill ?? null\"\n [attr.stroke]=\"element.stroke ?? null\"\n [attr.stroke-width]=\"element.strokeWidth ?? null\"\n [attr.stroke-linecap]=\"element.strokeLinecap ?? null\"\n [attr.stroke-linejoin]=\"element.strokeLinejoin ?? null\"\n />\n }\n @case ('rect') {\n <rect\n [attr.x]=\"element.x\"\n [attr.y]=\"element.y\"\n [attr.width]=\"element.width\"\n [attr.height]=\"element.height\"\n [attr.rx]=\"element.rx\"\n [attr.ry]=\"element.ry\"\n [attr.fill]=\"element.fill ?? null\"\n [attr.stroke]=\"element.stroke ?? null\"\n [attr.stroke-width]=\"element.strokeWidth ?? null\"\n [attr.stroke-linecap]=\"element.strokeLinecap ?? null\"\n [attr.stroke-linejoin]=\"element.strokeLinejoin ?? null\"\n />\n }\n }\n }\n </svg>\n}\n", styles: [":host{width:1em;height:1em;align-items:center;display:inline-flex;justify-content:center}:host svg{width:100%;height:100%}\n"] }]
2399
2401
  }], propDecorators: { name: [{ type: i0.Input, args: [{ isSignal: true, alias: "name", required: true }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], decorative: [{ type: i0.Input, args: [{ isSignal: true, alias: "decorative", required: false }] }], inheritColor: [{ type: i0.Input, args: [{ isSignal: true, alias: "inheritColor", required: false }] }] } });
2400
2402
 
2403
+ class SolarisAnimatedIconComponent {
2404
+ name = input.required(...(ngDevMode ? [{ debugName: "name" }] : /* istanbul ignore next */ []));
2405
+ active = input(false, ...(ngDevMode ? [{ debugName: "active" }] : /* istanbul ignore next */ []));
2406
+ ariaLabel = input(...(ngDevMode ? [undefined, { debugName: "ariaLabel" }] : /* istanbul ignore next */ []));
2407
+ decorative = input(false, ...(ngDevMode ? [{ debugName: "decorative" }] : /* istanbul ignore next */ []));
2408
+ isHidden = computed(() => this.decorative(), ...(ngDevMode ? [{ debugName: "isHidden" }] : /* istanbul ignore next */ []));
2409
+ accessibleLabel = computed(() => this.ariaLabel() ?? '', ...(ngDevMode ? [{ debugName: "accessibleLabel" }] : /* istanbul ignore next */ []));
2410
+ hasSemanticLabel = computed(() => !this.decorative() && !!this.ariaLabel(), ...(ngDevMode ? [{ debugName: "hasSemanticLabel" }] : /* istanbul ignore next */ []));
2411
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: SolarisAnimatedIconComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
2412
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.17", type: SolarisAnimatedIconComponent, isStandalone: true, selector: "solaris-animated-icon", inputs: { name: { classPropertyName: "name", publicName: "name", isSignal: true, isRequired: true, transformFunction: null }, active: { classPropertyName: "active", publicName: "active", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, decorative: { classPropertyName: "decorative", publicName: "decorative", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "attr.data-active": "active() ? \"\" : null" } }, ngImport: i0, template: "<svg\n width=\"100%\"\n height=\"100%\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n [attr.aria-hidden]=\"isHidden() ? 'true' : null\"\n [attr.aria-label]=\"hasSemanticLabel() ? accessibleLabel() : null\"\n [attr.role]=\"isHidden() ? 'presentation' : 'img'\"\n>\n @switch (name()) {\n @case ('menu') {\n <path\n class=\"solaris-animated-icon__line solaris-animated-icon__line--top\"\n d=\"M2 8h20\"\n />\n <path\n class=\"solaris-animated-icon__line solaris-animated-icon__line--bottom\"\n d=\"M2 16h20\"\n />\n }\n }\n</svg>\n", styles: [":host{width:1em;height:1em;align-items:center;display:inline-flex;justify-content:center}svg{width:100%;height:100%}.solaris-animated-icon__line{transform-box:view-box;transition:transform var(--solaris-motion-duration-normal) var(--solaris-motion-easing-standard)}.solaris-animated-icon__line--top{transform-origin:50% 33.333%}.solaris-animated-icon__line--bottom{transform-origin:50% 66.667%}:host([data-active]) .solaris-animated-icon__line--top{transform:translateY(16.667%) rotate(45deg)}:host([data-active]) .solaris-animated-icon__line--bottom{transform:translateY(-16.667%) rotate(-45deg)}@media(prefers-reduced-motion:reduce){.solaris-animated-icon__line{transition:none}}:host-context([data-reduced-motion=true]) .solaris-animated-icon__line{transition:none}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
2413
+ }
2414
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: SolarisAnimatedIconComponent, decorators: [{
2415
+ type: Component,
2416
+ args: [{ selector: 'solaris-animated-icon', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, host: {
2417
+ '[attr.data-active]': 'active() ? "" : null',
2418
+ }, template: "<svg\n width=\"100%\"\n height=\"100%\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n [attr.aria-hidden]=\"isHidden() ? 'true' : null\"\n [attr.aria-label]=\"hasSemanticLabel() ? accessibleLabel() : null\"\n [attr.role]=\"isHidden() ? 'presentation' : 'img'\"\n>\n @switch (name()) {\n @case ('menu') {\n <path\n class=\"solaris-animated-icon__line solaris-animated-icon__line--top\"\n d=\"M2 8h20\"\n />\n <path\n class=\"solaris-animated-icon__line solaris-animated-icon__line--bottom\"\n d=\"M2 16h20\"\n />\n }\n }\n</svg>\n", styles: [":host{width:1em;height:1em;align-items:center;display:inline-flex;justify-content:center}svg{width:100%;height:100%}.solaris-animated-icon__line{transform-box:view-box;transition:transform var(--solaris-motion-duration-normal) var(--solaris-motion-easing-standard)}.solaris-animated-icon__line--top{transform-origin:50% 33.333%}.solaris-animated-icon__line--bottom{transform-origin:50% 66.667%}:host([data-active]) .solaris-animated-icon__line--top{transform:translateY(16.667%) rotate(45deg)}:host([data-active]) .solaris-animated-icon__line--bottom{transform:translateY(-16.667%) rotate(-45deg)}@media(prefers-reduced-motion:reduce){.solaris-animated-icon__line{transition:none}}:host-context([data-reduced-motion=true]) .solaris-animated-icon__line{transition:none}\n"] }]
2419
+ }], propDecorators: { name: [{ type: i0.Input, args: [{ isSignal: true, alias: "name", required: true }] }], active: [{ type: i0.Input, args: [{ isSignal: true, alias: "active", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], decorative: [{ type: i0.Input, args: [{ isSignal: true, alias: "decorative", required: false }] }] } });
2420
+
2401
2421
  class SolarisBadgeComponent {
2402
2422
  appearance = input('tonal', ...(ngDevMode ? [{ debugName: "appearance" }] : /* istanbul ignore next */ []));
2403
2423
  variant = input('standard', ...(ngDevMode ? [{ debugName: "variant" }] : /* istanbul ignore next */ []));
@@ -2919,12 +2939,20 @@ class SolarisButtonDirective {
2919
2939
  if (this.isButton && initialType === null) {
2920
2940
  el.setAttribute('type', 'button');
2921
2941
  }
2922
- // Apply variant attributes synchronously so the element never flashes the
2923
- // base style before Angular's first change detection (SSR/hydration FOUC).
2924
- el.setAttribute('data-appearance', this.appearance());
2925
- el.setAttribute('data-color', this.color());
2926
- el.setAttribute('data-radius', this.radius());
2927
- el.setAttribute('data-shape', this.shape());
2942
+ // Preserve SSR attributes during hydration. Angular applies input bindings
2943
+ // after directive construction, so writing defaults here would flash them.
2944
+ if (!el.hasAttribute('data-appearance')) {
2945
+ el.setAttribute('data-appearance', this.appearance());
2946
+ }
2947
+ if (!el.hasAttribute('data-color')) {
2948
+ el.setAttribute('data-color', this.color());
2949
+ }
2950
+ if (!el.hasAttribute('data-radius')) {
2951
+ el.setAttribute('data-radius', this.radius());
2952
+ }
2953
+ if (!el.hasAttribute('data-shape')) {
2954
+ el.setAttribute('data-shape', this.shape());
2955
+ }
2928
2956
  effect(() => {
2929
2957
  if (this.loading()) {
2930
2958
  this.attachSpinner();
@@ -3079,12 +3107,20 @@ class SolarisIconButtonDirective {
3079
3107
  if (this.isButton && initialType === null) {
3080
3108
  el.setAttribute('type', 'button');
3081
3109
  }
3082
- // Apply variant attributes synchronously so the element never flashes the
3083
- // base style before Angular's first change detection (SSR/hydration FOUC).
3084
- el.setAttribute('data-appearance', this.appearance());
3085
- el.setAttribute('data-color', this.color());
3086
- el.setAttribute('data-radius', this.radius());
3087
- el.setAttribute('data-shape', this.shape());
3110
+ // Preserve SSR attributes during hydration. Angular applies input bindings
3111
+ // after directive construction, so writing defaults here would flash them.
3112
+ if (!el.hasAttribute('data-appearance')) {
3113
+ el.setAttribute('data-appearance', this.appearance());
3114
+ }
3115
+ if (!el.hasAttribute('data-color')) {
3116
+ el.setAttribute('data-color', this.color());
3117
+ }
3118
+ if (!el.hasAttribute('data-radius')) {
3119
+ el.setAttribute('data-radius', this.radius());
3120
+ }
3121
+ if (!el.hasAttribute('data-shape')) {
3122
+ el.setAttribute('data-shape', this.shape());
3123
+ }
3088
3124
  }
3089
3125
  onClick(event) {
3090
3126
  if (this.isEffectivelyDisabled() && this.isAnchor) {
@@ -3133,6 +3169,57 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImpo
3133
3169
  }]
3134
3170
  }] });
3135
3171
 
3172
+ // SECURITY_EXCEPTION_FILE: ElementRef.nativeElement reads the host button's disabled and loading state before toggling.
3173
+ class SolarisMenuToggleDirective {
3174
+ elementRef = inject(ElementRef);
3175
+ translateService = inject(SolarisTranslateService, {
3176
+ optional: true,
3177
+ });
3178
+ open = model(false, { ...(ngDevMode ? { debugName: "open" } : /* istanbul ignore next */ {}), alias: 'solarisMenuToggleOpen' });
3179
+ controls = input(undefined, { ...(ngDevMode ? { debugName: "controls" } : /* istanbul ignore next */ {}), alias: 'solarisMenuToggleControls' });
3180
+ openLabel = input(undefined, { ...(ngDevMode ? { debugName: "openLabel" } : /* istanbul ignore next */ {}), alias: 'solarisMenuToggleOpenLabel' });
3181
+ closeLabel = input(undefined, { ...(ngDevMode ? { debugName: "closeLabel" } : /* istanbul ignore next */ {}), alias: 'solarisMenuToggleCloseLabel' });
3182
+ resolvedAriaLabel = computed(() => {
3183
+ const label = this.open() ? this.closeLabel() : this.openLabel();
3184
+ if (label) {
3185
+ return label;
3186
+ }
3187
+ const key = this.open()
3188
+ ? 'solaris.menuToggle.close'
3189
+ : 'solaris.menuToggle.open';
3190
+ const fallback = this.open() ? 'Close menu' : 'Open menu';
3191
+ const translated = this.translateService?.translate(key);
3192
+ return translated && translated !== key ? translated : fallback;
3193
+ }, ...(ngDevMode ? [{ debugName: "resolvedAriaLabel" }] : /* istanbul ignore next */ []));
3194
+ toggle() {
3195
+ const button = this.elementRef.nativeElement;
3196
+ if (button.disabled ||
3197
+ button.getAttribute('aria-disabled') === 'true' ||
3198
+ button.hasAttribute('data-loading')) {
3199
+ return;
3200
+ }
3201
+ this.open.update((open) => !open);
3202
+ }
3203
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: SolarisMenuToggleDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
3204
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.17", type: SolarisMenuToggleDirective, isStandalone: true, selector: "button[solaris-icon-button][solaris-menu-toggle]", inputs: { open: { classPropertyName: "open", publicName: "solarisMenuToggleOpen", isSignal: true, isRequired: false, transformFunction: null }, controls: { classPropertyName: "controls", publicName: "solarisMenuToggleControls", isSignal: true, isRequired: false, transformFunction: null }, openLabel: { classPropertyName: "openLabel", publicName: "solarisMenuToggleOpenLabel", isSignal: true, isRequired: false, transformFunction: null }, closeLabel: { classPropertyName: "closeLabel", publicName: "solarisMenuToggleCloseLabel", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { open: "solarisMenuToggleOpenChange" }, host: { listeners: { "click": "toggle()" }, properties: { "attr.data-state": "open() ? \"open\" : \"closed\"", "attr.aria-expanded": "open() ? \"true\" : \"false\"", "attr.aria-controls": "controls() ?? null", "attr.aria-label": "resolvedAriaLabel()" } }, ngImport: i0 });
3205
+ }
3206
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: SolarisMenuToggleDirective, decorators: [{
3207
+ type: Directive,
3208
+ args: [{
3209
+ selector: 'button[solaris-icon-button][solaris-menu-toggle]',
3210
+ standalone: true,
3211
+ host: {
3212
+ '[attr.data-state]': 'open() ? "open" : "closed"',
3213
+ '[attr.aria-expanded]': 'open() ? "true" : "false"',
3214
+ '[attr.aria-controls]': 'controls() ?? null',
3215
+ '[attr.aria-label]': 'resolvedAriaLabel()',
3216
+ },
3217
+ }]
3218
+ }], propDecorators: { open: [{ type: i0.Input, args: [{ isSignal: true, alias: "solarisMenuToggleOpen", required: false }] }, { type: i0.Output, args: ["solarisMenuToggleOpenChange"] }], controls: [{ type: i0.Input, args: [{ isSignal: true, alias: "solarisMenuToggleControls", required: false }] }], openLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "solarisMenuToggleOpenLabel", required: false }] }], closeLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "solarisMenuToggleCloseLabel", required: false }] }], toggle: [{
3219
+ type: HostListener,
3220
+ args: ['click']
3221
+ }] } });
3222
+
3136
3223
  class SolarisButtonGroupComponent {
3137
3224
  orientation = input('horizontal', ...(ngDevMode ? [{ debugName: "orientation" }] : /* istanbul ignore next */ []));
3138
3225
  attached = input(true, ...(ngDevMode ? [{ debugName: "attached" }] : /* istanbul ignore next */ []));
@@ -3175,6 +3262,593 @@ function resolveElementId(ref, prefix) {
3175
3262
  return existingId || nextIdFor(prefix);
3176
3263
  }
3177
3264
 
3265
+ class SolarisMegaMenuPanelDirective {
3266
+ templateRef = inject((TemplateRef));
3267
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: SolarisMegaMenuPanelDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
3268
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.17", type: SolarisMegaMenuPanelDirective, isStandalone: true, selector: "ng-template[solaris-mega-menu-panel]", exportAs: ["solarisMegaMenuPanel"], ngImport: i0 });
3269
+ }
3270
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: SolarisMegaMenuPanelDirective, decorators: [{
3271
+ type: Directive,
3272
+ args: [{
3273
+ selector: 'ng-template[solaris-mega-menu-panel]',
3274
+ standalone: true,
3275
+ exportAs: 'solarisMegaMenuPanel',
3276
+ }]
3277
+ }] });
3278
+
3279
+ const getMegaMenuPanelWidth = (panelWidth, anchor, trigger, viewportWidth) => {
3280
+ switch (panelWidth) {
3281
+ case 'trigger':
3282
+ return trigger.getBoundingClientRect().width;
3283
+ case 'anchor':
3284
+ return anchor.getBoundingClientRect().width;
3285
+ case 'viewport':
3286
+ return viewportWidth;
3287
+ }
3288
+ };
3289
+
3290
+ const SOLARIS_MEGA_MENU = new InjectionToken('SOLARIS_MEGA_MENU');
3291
+ const SOLARIS_MEGA_MENU_GROUP = new InjectionToken('SOLARIS_MEGA_MENU_GROUP');
3292
+ const SOLARIS_MEGA_MENU_ANCHOR = new InjectionToken('SOLARIS_MEGA_MENU_ANCHOR');
3293
+
3294
+ // SECURITY_EXCEPTION_FILE: ElementRef and injected DOCUMENT support focus restoration, overlay geometry, and browser-only event listeners. Angular bindings cannot express these imperative DOM APIs; component specs cover open, close, focus, and viewport behavior.
3295
+ const MEGA_MENU_ANCHOR_ERROR = 'SolarisMegaMenuComponent requires an ancestor with the [solaris-mega-menu-anchor] directive. The anchor defines the menu panel position and width, and the interactive area excluded from the backdrop. Add solaris-mega-menu-anchor to the navigation container that wraps this mega menu.';
3296
+ class SolarisMegaMenuComponent {
3297
+ overlay = inject(Overlay);
3298
+ viewContainerRef = inject(ViewContainerRef);
3299
+ hostElement = inject(ElementRef);
3300
+ platformId = inject(PLATFORM_ID);
3301
+ destroyRef = inject(DestroyRef);
3302
+ document = inject(DOCUMENT$1);
3303
+ group = inject(SOLARIS_MEGA_MENU_GROUP, { optional: true });
3304
+ anchorControl = inject(SOLARIS_MEGA_MENU_ANCHOR, { optional: true });
3305
+ overlayPanel;
3306
+ panel = contentChild(SolarisMegaMenuPanelDirective, ...(ngDevMode ? [{ debugName: "panel" }] : /* istanbul ignore next */ []));
3307
+ openState = model(false, { ...(ngDevMode ? { debugName: "openState" } : /* istanbul ignore next */ {}), alias: 'open' });
3308
+ panelWidth = input('viewport', ...(ngDevMode ? [{ debugName: "panelWidth" }] : /* istanbul ignore next */ []));
3309
+ appearance = input('underline', ...(ngDevMode ? [{ debugName: "appearance" }] : /* istanbul ignore next */ []));
3310
+ backdrop = input(false, ...(ngDevMode ? [{ debugName: "backdrop" }] : /* istanbul ignore next */ []));
3311
+ persistentOnClick = input(false, ...(ngDevMode ? [{ debugName: "persistentOnClick" }] : /* istanbul ignore next */ []));
3312
+ hoverOpenDelay = input(120, ...(ngDevMode ? [{ debugName: "hoverOpenDelay" }] : /* istanbul ignore next */ []));
3313
+ hoverCloseDelay = input(160, ...(ngDevMode ? [{ debugName: "hoverCloseDelay" }] : /* istanbul ignore next */ []));
3314
+ opened = output();
3315
+ closed = output();
3316
+ panelId = nextIdFor('solaris-mega-menu-panel');
3317
+ isOpen = computed(() => this.openState(), ...(ngDevMode ? [{ debugName: "isOpen" }] : /* istanbul ignore next */ []));
3318
+ isPinned = signal(false, ...(ngDevMode ? [{ debugName: "isPinned" }] : /* istanbul ignore next */ []));
3319
+ overlayRef = null;
3320
+ scheduledOpen = null;
3321
+ scheduledClose = null;
3322
+ outsideClickCleanup = null;
3323
+ resizeObserver = null;
3324
+ viewportResizeCleanup = null;
3325
+ backdropClickCleanup = null;
3326
+ backdropRegions = [];
3327
+ anchorUnderline = null;
3328
+ constructor() {
3329
+ if (!this.anchorControl) {
3330
+ throw new Error(MEGA_MENU_ANCHOR_ERROR);
3331
+ }
3332
+ effect(() => {
3333
+ if (!isPlatformBrowser(this.platformId)) {
3334
+ return;
3335
+ }
3336
+ if (this.openState()) {
3337
+ this.attachPanel();
3338
+ }
3339
+ else {
3340
+ this.detachPanel();
3341
+ }
3342
+ });
3343
+ effect(() => {
3344
+ this.appearance();
3345
+ if (this.isOpen()) {
3346
+ this.syncAnchorUnderline();
3347
+ }
3348
+ });
3349
+ this.destroyRef.onDestroy(() => {
3350
+ this.clearTimers();
3351
+ this.removeOutsideClickHandler();
3352
+ this.stopGeometryObserver();
3353
+ this.clearBackdrop();
3354
+ this.clearAnchorUnderline();
3355
+ this.overlayRef?.dispose();
3356
+ });
3357
+ }
3358
+ open() {
3359
+ if (this.isOpen()) {
3360
+ return;
3361
+ }
3362
+ this.clearTimers();
3363
+ this.group?.open(this);
3364
+ this.openState.set(true);
3365
+ }
3366
+ close(restoreFocus = false) {
3367
+ if (!this.isOpen()) {
3368
+ return;
3369
+ }
3370
+ this.clearTimers();
3371
+ this.isPinned.set(false);
3372
+ this.openState.set(false);
3373
+ this.group?.close(this);
3374
+ if (restoreFocus) {
3375
+ this.hostElement.nativeElement
3376
+ .querySelector('[solaris-mega-menu-trigger]')
3377
+ ?.focus();
3378
+ }
3379
+ }
3380
+ toggleFromClick() {
3381
+ if (this.persistentOnClick()) {
3382
+ if (this.isOpen() && this.isPinned()) {
3383
+ this.close();
3384
+ return;
3385
+ }
3386
+ this.open();
3387
+ this.isPinned.set(true);
3388
+ return;
3389
+ }
3390
+ if (this.isOpen()) {
3391
+ this.close();
3392
+ }
3393
+ else {
3394
+ this.open();
3395
+ }
3396
+ }
3397
+ scheduleOpen() {
3398
+ this.clearCloseTimer();
3399
+ if (this.isOpen() || this.scheduledOpen) {
3400
+ return;
3401
+ }
3402
+ this.scheduledOpen = setTimeout(() => {
3403
+ this.scheduledOpen = null;
3404
+ this.open();
3405
+ }, this.hoverOpenDelay());
3406
+ }
3407
+ scheduleClose() {
3408
+ this.clearOpenTimer();
3409
+ if (!this.isOpen() || this.isPinned() || this.scheduledClose) {
3410
+ return;
3411
+ }
3412
+ this.scheduledClose = setTimeout(() => {
3413
+ this.scheduledClose = null;
3414
+ this.close();
3415
+ }, this.hoverCloseDelay());
3416
+ }
3417
+ cancelScheduledClose() {
3418
+ this.clearCloseTimer();
3419
+ }
3420
+ onPanelPointerEnter() {
3421
+ this.cancelScheduledClose();
3422
+ }
3423
+ onPanelPointerLeave() {
3424
+ this.scheduleClose();
3425
+ }
3426
+ onPanelFocusOut() {
3427
+ queueMicrotask(() => {
3428
+ const activeElement = this.hostElement.nativeElement.ownerDocument.activeElement;
3429
+ const trigger = this.hostElement.nativeElement.querySelector('[solaris-mega-menu-trigger]');
3430
+ const panel = this.overlayRef?.overlayElement;
3431
+ if (!trigger?.contains(activeElement) &&
3432
+ !panel?.contains(activeElement)) {
3433
+ this.close();
3434
+ }
3435
+ });
3436
+ }
3437
+ onPanelEscape(event) {
3438
+ event.preventDefault();
3439
+ this.close(true);
3440
+ }
3441
+ attachPanel() {
3442
+ const panel = this.panel();
3443
+ if (!panel || this.overlayRef?.hasAttached()) {
3444
+ return;
3445
+ }
3446
+ this.overlayRef ??= this.createOverlay();
3447
+ this.overlayRef.attach(new TemplatePortal(this.overlayPanel, this.viewContainerRef));
3448
+ this.updatePanelGeometry();
3449
+ this.startGeometryObserver();
3450
+ this.setupBackdrop();
3451
+ if (!this.backdrop()) {
3452
+ this.addOutsideClickHandler();
3453
+ }
3454
+ this.opened.emit();
3455
+ }
3456
+ detachPanel() {
3457
+ if (!this.overlayRef?.hasAttached()) {
3458
+ return;
3459
+ }
3460
+ this.clearBackdrop();
3461
+ const backdrop = this.overlayRef.backdropElement;
3462
+ this.overlayRef.detachBackdrop();
3463
+ backdrop?.remove();
3464
+ this.overlayRef.detach();
3465
+ this.overlayRef.dispose();
3466
+ this.overlayRef = null;
3467
+ this.removeOutsideClickHandler();
3468
+ this.stopGeometryObserver();
3469
+ this.clearAnchorUnderline();
3470
+ this.closed.emit();
3471
+ }
3472
+ createOverlay() {
3473
+ const positionStrategy = this.createPositionStrategy();
3474
+ const config = new OverlayConfig({
3475
+ backdropClass: 'solaris-mega-menu-backdrop',
3476
+ hasBackdrop: this.backdrop(),
3477
+ positionStrategy,
3478
+ scrollStrategy: this.backdrop()
3479
+ ? this.overlay.scrollStrategies.block()
3480
+ : this.overlay.scrollStrategies.reposition(),
3481
+ });
3482
+ const overlayRef = this.overlay.create(config);
3483
+ positionStrategy.positionChanges.subscribe(({ connectionPair }) => {
3484
+ const panel = overlayRef.overlayElement.querySelector('.solaris-mega-menu__panel');
3485
+ if (connectionPair.originY === 'top') {
3486
+ panel?.style.setProperty('--solaris-mega-menu-shadow', 'none');
3487
+ }
3488
+ else {
3489
+ panel?.style.removeProperty('--solaris-mega-menu-shadow');
3490
+ }
3491
+ });
3492
+ overlayRef.keydownEvents().subscribe((event) => {
3493
+ if (event.key === 'Escape') {
3494
+ this.close(true);
3495
+ }
3496
+ });
3497
+ return overlayRef;
3498
+ }
3499
+ addOutsideClickHandler() {
3500
+ this.removeOutsideClickHandler();
3501
+ const onPointerDown = (event) => {
3502
+ const target = event.target;
3503
+ const trigger = this.hostElement.nativeElement.querySelector('[solaris-mega-menu-trigger]');
3504
+ if (!target ||
3505
+ trigger?.contains(target) ||
3506
+ this.overlayRef?.overlayElement.contains(target)) {
3507
+ return;
3508
+ }
3509
+ this.close();
3510
+ };
3511
+ this.document.addEventListener('pointerdown', onPointerDown, true);
3512
+ this.outsideClickCleanup = () => {
3513
+ this.document.removeEventListener('pointerdown', onPointerDown, true);
3514
+ };
3515
+ }
3516
+ removeOutsideClickHandler() {
3517
+ this.outsideClickCleanup?.();
3518
+ this.outsideClickCleanup = null;
3519
+ }
3520
+ createPositionStrategy() {
3521
+ return this.overlay
3522
+ .position()
3523
+ .flexibleConnectedTo(this.anchor.element)
3524
+ .withPositions([
3525
+ {
3526
+ originX: 'start',
3527
+ originY: 'bottom',
3528
+ overlayX: 'start',
3529
+ overlayY: 'top',
3530
+ },
3531
+ {
3532
+ originX: 'start',
3533
+ originY: 'top',
3534
+ overlayX: 'start',
3535
+ overlayY: 'bottom',
3536
+ },
3537
+ ])
3538
+ .withFlexibleDimensions(false)
3539
+ .withPush(true);
3540
+ }
3541
+ get anchor() {
3542
+ if (!this.anchorControl) {
3543
+ throw new Error(MEGA_MENU_ANCHOR_ERROR);
3544
+ }
3545
+ return this.anchorControl;
3546
+ }
3547
+ updatePanelGeometry() {
3548
+ if (!this.overlayRef) {
3549
+ return;
3550
+ }
3551
+ this.overlayRef.updateSize({
3552
+ width: getMegaMenuPanelWidth(this.panelWidth(), this.anchor.element, this.getTrigger(), this.hostElement.nativeElement.ownerDocument.defaultView?.innerWidth ??
3553
+ 0),
3554
+ });
3555
+ this.overlayRef.updatePosition();
3556
+ this.updateBackdropGeometry();
3557
+ this.syncAnchorUnderline();
3558
+ }
3559
+ syncAnchorUnderline() {
3560
+ const anchor = this.anchor.element;
3561
+ if (!this.isOpen() || this.appearance() !== 'underline') {
3562
+ this.clearAnchorUnderline();
3563
+ return;
3564
+ }
3565
+ const anchorRect = anchor.getBoundingClientRect();
3566
+ const triggerRect = this.getTrigger().getBoundingClientRect();
3567
+ this.anchorUnderline ??= this.createAnchorUnderline(anchor);
3568
+ this.anchorUnderline.style.left = `${triggerRect.left - anchorRect.left}px`;
3569
+ this.anchorUnderline.style.width = `${triggerRect.width}px`;
3570
+ }
3571
+ clearAnchorUnderline() {
3572
+ this.anchorUnderline?.remove();
3573
+ this.anchorUnderline = null;
3574
+ }
3575
+ createAnchorUnderline(anchor) {
3576
+ const underline = this.document.createElement('span');
3577
+ underline.className = 'solaris-mega-menu-anchor__underline';
3578
+ anchor.appendChild(underline);
3579
+ return underline;
3580
+ }
3581
+ setupBackdrop() {
3582
+ const backdrop = this.overlayRef?.backdropElement;
3583
+ if (!backdrop) {
3584
+ return;
3585
+ }
3586
+ this.backdropRegions = ['top', 'left', 'right', 'bottom'].map((position) => {
3587
+ const region = this.document.createElement('span');
3588
+ region.className = `solaris-mega-menu-backdrop__region solaris-mega-menu-backdrop__region--${position}`;
3589
+ backdrop.appendChild(region);
3590
+ return region;
3591
+ });
3592
+ const subscription = this.overlayRef?.backdropClick().subscribe(() => {
3593
+ this.close();
3594
+ });
3595
+ this.backdropClickCleanup = () => subscription?.unsubscribe();
3596
+ this.updateBackdropGeometry();
3597
+ }
3598
+ clearBackdrop() {
3599
+ this.backdropClickCleanup?.();
3600
+ this.backdropClickCleanup = null;
3601
+ this.backdropRegions.forEach((region) => region.remove());
3602
+ this.backdropRegions = [];
3603
+ }
3604
+ updateBackdropGeometry() {
3605
+ const backdrop = this.overlayRef?.backdropElement;
3606
+ if (!backdrop || this.backdropRegions.length !== 4) {
3607
+ return;
3608
+ }
3609
+ const backdropRect = backdrop.getBoundingClientRect();
3610
+ const viewport = this.document.defaultView;
3611
+ const width = backdropRect.width || viewport?.innerWidth || 0;
3612
+ const height = backdropRect.height || viewport?.innerHeight || 0;
3613
+ const anchorRect = this.anchor.element.getBoundingClientRect();
3614
+ const inset = 1;
3615
+ const top = Math.max(0, Math.floor(anchorRect.top - backdropRect.top) - inset);
3616
+ const right = Math.min(width, Math.ceil(anchorRect.right - backdropRect.left) + inset);
3617
+ const bottom = Math.min(height, Math.ceil(anchorRect.bottom - backdropRect.top) + inset);
3618
+ const left = Math.max(0, Math.floor(anchorRect.left - backdropRect.left) - inset);
3619
+ const [topRegion, leftRegion, rightRegion, bottomRegion] = this.backdropRegions;
3620
+ topRegion.style.height = `${top}px`;
3621
+ leftRegion.style.top = `${top}px`;
3622
+ leftRegion.style.height = `${bottom - top}px`;
3623
+ leftRegion.style.width = `${left}px`;
3624
+ rightRegion.style.top = `${top}px`;
3625
+ rightRegion.style.height = `${bottom - top}px`;
3626
+ rightRegion.style.width = `${width - right}px`;
3627
+ bottomRegion.style.top = `${bottom}px`;
3628
+ }
3629
+ startGeometryObserver() {
3630
+ const anchor = this.anchor.element;
3631
+ const trigger = this.getTrigger();
3632
+ const updateGeometry = () => this.updatePanelGeometry();
3633
+ if (typeof ResizeObserver !== 'undefined') {
3634
+ this.resizeObserver?.disconnect();
3635
+ this.resizeObserver = new ResizeObserver(updateGeometry);
3636
+ this.resizeObserver.observe(anchor);
3637
+ this.resizeObserver.observe(trigger);
3638
+ }
3639
+ const viewport = this.hostElement.nativeElement.ownerDocument.defaultView;
3640
+ viewport?.addEventListener('resize', updateGeometry);
3641
+ this.viewportResizeCleanup = () => {
3642
+ viewport?.removeEventListener('resize', updateGeometry);
3643
+ };
3644
+ }
3645
+ stopGeometryObserver() {
3646
+ this.resizeObserver?.disconnect();
3647
+ this.resizeObserver = null;
3648
+ this.viewportResizeCleanup?.();
3649
+ this.viewportResizeCleanup = null;
3650
+ }
3651
+ getTrigger() {
3652
+ return (this.hostElement.nativeElement.querySelector('[solaris-mega-menu-trigger]') ?? this.hostElement.nativeElement);
3653
+ }
3654
+ clearTimers() {
3655
+ this.clearOpenTimer();
3656
+ this.clearCloseTimer();
3657
+ }
3658
+ clearOpenTimer() {
3659
+ if (this.scheduledOpen) {
3660
+ clearTimeout(this.scheduledOpen);
3661
+ this.scheduledOpen = null;
3662
+ }
3663
+ }
3664
+ clearCloseTimer() {
3665
+ if (this.scheduledClose) {
3666
+ clearTimeout(this.scheduledClose);
3667
+ this.scheduledClose = null;
3668
+ }
3669
+ }
3670
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: SolarisMegaMenuComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
3671
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "21.2.17", type: SolarisMegaMenuComponent, isStandalone: true, selector: "solaris-mega-menu", inputs: { openState: { classPropertyName: "openState", publicName: "open", isSignal: true, isRequired: false, transformFunction: null }, panelWidth: { classPropertyName: "panelWidth", publicName: "panelWidth", isSignal: true, isRequired: false, transformFunction: null }, appearance: { classPropertyName: "appearance", publicName: "appearance", isSignal: true, isRequired: false, transformFunction: null }, backdrop: { classPropertyName: "backdrop", publicName: "backdrop", isSignal: true, isRequired: false, transformFunction: null }, persistentOnClick: { classPropertyName: "persistentOnClick", publicName: "persistentOnClick", isSignal: true, isRequired: false, transformFunction: null }, hoverOpenDelay: { classPropertyName: "hoverOpenDelay", publicName: "hoverOpenDelay", isSignal: true, isRequired: false, transformFunction: null }, hoverCloseDelay: { classPropertyName: "hoverCloseDelay", publicName: "hoverCloseDelay", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { openState: "openChange", opened: "opened", closed: "closed" }, host: { properties: { "attr.data-open": "isOpen() ? \"\" : null" }, classAttribute: "solaris-mega-menu" }, providers: [
3672
+ {
3673
+ provide: SOLARIS_MEGA_MENU,
3674
+ useExisting: forwardRef(() => SolarisMegaMenuComponent),
3675
+ },
3676
+ ], queries: [{ propertyName: "panel", first: true, predicate: SolarisMegaMenuPanelDirective, descendants: true, isSignal: true }], viewQueries: [{ propertyName: "overlayPanel", first: true, predicate: ["overlayPanel"], descendants: true, static: true }], ngImport: i0, template: "<ng-content select=\"[solaris-mega-menu-trigger]\" />\n<ng-content select=\"ng-template[solaris-mega-menu-panel]\" />\n\n<ng-template #overlayPanel>\n <section\n class=\"solaris-mega-menu__panel\"\n [id]=\"panelId\"\n tabindex=\"-1\"\n (pointerenter)=\"onPanelPointerEnter()\"\n (pointerleave)=\"onPanelPointerLeave()\"\n (focusout)=\"onPanelFocusOut()\"\n (keydown.escape)=\"onPanelEscape($event)\"\n >\n <ng-container *ngTemplateOutlet=\"panel()?.templateRef\" />\n </section>\n</ng-template>\n", styles: ["solaris-mega-menu{display:inline-block}[solaris-mega-menu-trigger]{display:inline-flex;align-items:center;gap:var(--solaris-spacing-2);transition:color var(--solaris-motion-duration-fast) var(--solaris-motion-easing-standard)}.solaris-mega-menu-trigger__chevron{order:1;flex:0 0 auto;transform:rotate(45deg);margin-inline-start:auto;width:var(--solaris-spacing-2);height:var(--solaris-spacing-2);border-right:var(--solaris-border-width-sm) solid currentcolor;border-bottom:var(--solaris-border-width-sm) solid currentcolor;transition:transform var(--solaris-motion-duration-fast) var(--solaris-motion-easing-standard)}[solaris-mega-menu-trigger][data-open] .solaris-mega-menu-trigger__chevron{transform:rotate(-135deg)}[solaris-mega-menu-trigger][data-appearance=underline]{border-bottom:2px solid transparent}[solaris-mega-menu-trigger][data-appearance=underline][data-open]{border-bottom-color:transparent}[solaris-mega-menu-anchor]{position:relative}.solaris-mega-menu-anchor__underline{bottom:1px;height:2px;position:absolute;pointer-events:none;z-index:var(--solaris-z-index-raised);background:var(--solaris-primary-base);transition:left var(--solaris-motion-duration-fast) var(--solaris-motion-easing-standard),width var(--solaris-motion-duration-fast) var(--solaris-motion-easing-standard)}[solaris-mega-menu-trigger][data-appearance=underline]:hover,[solaris-mega-menu-trigger][data-appearance=underline]:focus-visible{background:transparent}[solaris-mega-menu-trigger][data-appearance=text]{color:var(--solaris-text-muted)}[solaris-mega-menu-trigger][data-appearance=text][data-open]{color:var(--solaris-text-strong)}.solaris-mega-menu__panel{--solaris-mega-menu-shadow: var(--solaris-shadow-lg);--solaris-mega-menu-color: var(--solaris-text-default);--solaris-mega-menu-background: var(--solaris-surface-raised);width:100%;box-sizing:border-box;color:var(--solaris-mega-menu-color);box-shadow:var(--solaris-mega-menu-shadow);background:var(--solaris-mega-menu-background);animation:solaris-mega-menu-enter var(--solaris-motion-duration-fast) var(--solaris-motion-easing-decelerate)}.cdk-overlay-backdrop.solaris-mega-menu-backdrop{pointer-events:none;background:transparent}.solaris-mega-menu-backdrop__region{display:block;position:absolute;pointer-events:auto;background:var(--solaris-backdrop)}.solaris-mega-menu-backdrop__region--top,.solaris-mega-menu-backdrop__region--bottom{right:0;left:0}.solaris-mega-menu-backdrop__region--top{top:0}.solaris-mega-menu-backdrop__region--bottom{bottom:0}.solaris-mega-menu-backdrop__region--left{left:0}.solaris-mega-menu-backdrop__region--right{right:0}@keyframes solaris-mega-menu-enter{0%{opacity:0;transform:translateY(calc(-1 * var(--solaris-spacing-1)))}to{opacity:1;transform:translateY(0)}}@media(prefers-reduced-motion:reduce){[solaris-mega-menu-trigger],.solaris-mega-menu-anchor__underline,.solaris-mega-menu-trigger__chevron,.solaris-mega-menu__panel{animation:none;transition:none}}\n"], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }], encapsulation: i0.ViewEncapsulation.None });
3677
+ }
3678
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: SolarisMegaMenuComponent, decorators: [{
3679
+ type: Component,
3680
+ args: [{ selector: 'solaris-mega-menu', standalone: true, encapsulation: ViewEncapsulation.None, imports: [NgTemplateOutlet], providers: [
3681
+ {
3682
+ provide: SOLARIS_MEGA_MENU,
3683
+ useExisting: forwardRef(() => SolarisMegaMenuComponent),
3684
+ },
3685
+ ], host: {
3686
+ class: 'solaris-mega-menu',
3687
+ '[attr.data-open]': 'isOpen() ? "" : null',
3688
+ }, template: "<ng-content select=\"[solaris-mega-menu-trigger]\" />\n<ng-content select=\"ng-template[solaris-mega-menu-panel]\" />\n\n<ng-template #overlayPanel>\n <section\n class=\"solaris-mega-menu__panel\"\n [id]=\"panelId\"\n tabindex=\"-1\"\n (pointerenter)=\"onPanelPointerEnter()\"\n (pointerleave)=\"onPanelPointerLeave()\"\n (focusout)=\"onPanelFocusOut()\"\n (keydown.escape)=\"onPanelEscape($event)\"\n >\n <ng-container *ngTemplateOutlet=\"panel()?.templateRef\" />\n </section>\n</ng-template>\n", styles: ["solaris-mega-menu{display:inline-block}[solaris-mega-menu-trigger]{display:inline-flex;align-items:center;gap:var(--solaris-spacing-2);transition:color var(--solaris-motion-duration-fast) var(--solaris-motion-easing-standard)}.solaris-mega-menu-trigger__chevron{order:1;flex:0 0 auto;transform:rotate(45deg);margin-inline-start:auto;width:var(--solaris-spacing-2);height:var(--solaris-spacing-2);border-right:var(--solaris-border-width-sm) solid currentcolor;border-bottom:var(--solaris-border-width-sm) solid currentcolor;transition:transform var(--solaris-motion-duration-fast) var(--solaris-motion-easing-standard)}[solaris-mega-menu-trigger][data-open] .solaris-mega-menu-trigger__chevron{transform:rotate(-135deg)}[solaris-mega-menu-trigger][data-appearance=underline]{border-bottom:2px solid transparent}[solaris-mega-menu-trigger][data-appearance=underline][data-open]{border-bottom-color:transparent}[solaris-mega-menu-anchor]{position:relative}.solaris-mega-menu-anchor__underline{bottom:1px;height:2px;position:absolute;pointer-events:none;z-index:var(--solaris-z-index-raised);background:var(--solaris-primary-base);transition:left var(--solaris-motion-duration-fast) var(--solaris-motion-easing-standard),width var(--solaris-motion-duration-fast) var(--solaris-motion-easing-standard)}[solaris-mega-menu-trigger][data-appearance=underline]:hover,[solaris-mega-menu-trigger][data-appearance=underline]:focus-visible{background:transparent}[solaris-mega-menu-trigger][data-appearance=text]{color:var(--solaris-text-muted)}[solaris-mega-menu-trigger][data-appearance=text][data-open]{color:var(--solaris-text-strong)}.solaris-mega-menu__panel{--solaris-mega-menu-shadow: var(--solaris-shadow-lg);--solaris-mega-menu-color: var(--solaris-text-default);--solaris-mega-menu-background: var(--solaris-surface-raised);width:100%;box-sizing:border-box;color:var(--solaris-mega-menu-color);box-shadow:var(--solaris-mega-menu-shadow);background:var(--solaris-mega-menu-background);animation:solaris-mega-menu-enter var(--solaris-motion-duration-fast) var(--solaris-motion-easing-decelerate)}.cdk-overlay-backdrop.solaris-mega-menu-backdrop{pointer-events:none;background:transparent}.solaris-mega-menu-backdrop__region{display:block;position:absolute;pointer-events:auto;background:var(--solaris-backdrop)}.solaris-mega-menu-backdrop__region--top,.solaris-mega-menu-backdrop__region--bottom{right:0;left:0}.solaris-mega-menu-backdrop__region--top{top:0}.solaris-mega-menu-backdrop__region--bottom{bottom:0}.solaris-mega-menu-backdrop__region--left{left:0}.solaris-mega-menu-backdrop__region--right{right:0}@keyframes solaris-mega-menu-enter{0%{opacity:0;transform:translateY(calc(-1 * var(--solaris-spacing-1)))}to{opacity:1;transform:translateY(0)}}@media(prefers-reduced-motion:reduce){[solaris-mega-menu-trigger],.solaris-mega-menu-anchor__underline,.solaris-mega-menu-trigger__chevron,.solaris-mega-menu__panel{animation:none;transition:none}}\n"] }]
3689
+ }], ctorParameters: () => [], propDecorators: { overlayPanel: [{
3690
+ type: ViewChild,
3691
+ args: ['overlayPanel', { static: true }]
3692
+ }], panel: [{ type: i0.ContentChild, args: [i0.forwardRef(() => SolarisMegaMenuPanelDirective), { isSignal: true }] }], openState: [{ type: i0.Input, args: [{ isSignal: true, alias: "open", required: false }] }, { type: i0.Output, args: ["openChange"] }], panelWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "panelWidth", required: false }] }], appearance: [{ type: i0.Input, args: [{ isSignal: true, alias: "appearance", required: false }] }], backdrop: [{ type: i0.Input, args: [{ isSignal: true, alias: "backdrop", required: false }] }], persistentOnClick: [{ type: i0.Input, args: [{ isSignal: true, alias: "persistentOnClick", required: false }] }], hoverOpenDelay: [{ type: i0.Input, args: [{ isSignal: true, alias: "hoverOpenDelay", required: false }] }], hoverCloseDelay: [{ type: i0.Input, args: [{ isSignal: true, alias: "hoverCloseDelay", required: false }] }], opened: [{ type: i0.Output, args: ["opened"] }], closed: [{ type: i0.Output, args: ["closed"] }] } });
3693
+
3694
+ // SECURITY_EXCEPTION_FILE: The CDK connected overlay requires the anchor HTMLElement as its positioning origin. Exposing the injected host avoids document lookup; mega-menu component specs cover anchored positioning.
3695
+ class SolarisMegaMenuAnchorDirective {
3696
+ elementRef = inject(ElementRef);
3697
+ get element() {
3698
+ return this.elementRef.nativeElement;
3699
+ }
3700
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: SolarisMegaMenuAnchorDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
3701
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.17", type: SolarisMegaMenuAnchorDirective, isStandalone: true, selector: "[solaris-mega-menu-anchor]", providers: [
3702
+ {
3703
+ provide: SOLARIS_MEGA_MENU_ANCHOR,
3704
+ useExisting: SolarisMegaMenuAnchorDirective,
3705
+ },
3706
+ ], ngImport: i0 });
3707
+ }
3708
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: SolarisMegaMenuAnchorDirective, decorators: [{
3709
+ type: Directive,
3710
+ args: [{
3711
+ selector: '[solaris-mega-menu-anchor]',
3712
+ standalone: true,
3713
+ providers: [
3714
+ {
3715
+ provide: SOLARIS_MEGA_MENU_ANCHOR,
3716
+ useExisting: SolarisMegaMenuAnchorDirective,
3717
+ },
3718
+ ],
3719
+ }]
3720
+ }] });
3721
+
3722
+ class SolarisMegaMenuGroupDirective {
3723
+ activeMenu = null;
3724
+ open(menu) {
3725
+ if (this.activeMenu && this.activeMenu !== menu) {
3726
+ this.activeMenu.close(false);
3727
+ }
3728
+ this.activeMenu = menu;
3729
+ }
3730
+ close(menu) {
3731
+ if (this.activeMenu === menu) {
3732
+ this.activeMenu = null;
3733
+ }
3734
+ }
3735
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: SolarisMegaMenuGroupDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
3736
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.17", type: SolarisMegaMenuGroupDirective, isStandalone: true, selector: "[solaris-mega-menu-group]", providers: [
3737
+ {
3738
+ provide: SOLARIS_MEGA_MENU_GROUP,
3739
+ useExisting: SolarisMegaMenuGroupDirective,
3740
+ },
3741
+ ], ngImport: i0 });
3742
+ }
3743
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: SolarisMegaMenuGroupDirective, decorators: [{
3744
+ type: Directive,
3745
+ args: [{
3746
+ selector: '[solaris-mega-menu-group]',
3747
+ standalone: true,
3748
+ providers: [
3749
+ {
3750
+ provide: SOLARIS_MEGA_MENU_GROUP,
3751
+ useExisting: SolarisMegaMenuGroupDirective,
3752
+ },
3753
+ ],
3754
+ }]
3755
+ }] });
3756
+
3757
+ // SECURITY_EXCEPTION_FILE: Native host access sets the semantic button type. Renderer2 creates the decorative chevron for both SSR and browser rendering; directive specs cover trigger semantics and interaction.
3758
+ class SolarisMegaMenuTriggerDirective {
3759
+ megaMenu = inject(SOLARIS_MEGA_MENU);
3760
+ elementRef = inject(ElementRef);
3761
+ renderer = inject(Renderer2);
3762
+ isPointerInteraction = false;
3763
+ constructor() {
3764
+ if (this.elementRef.nativeElement.getAttribute('type') === null) {
3765
+ this.elementRef.nativeElement.setAttribute('type', 'button');
3766
+ }
3767
+ this.ensureChevron();
3768
+ }
3769
+ onClick() {
3770
+ this.megaMenu.toggleFromClick();
3771
+ this.isPointerInteraction = false;
3772
+ }
3773
+ onPointerDown() {
3774
+ this.isPointerInteraction = true;
3775
+ }
3776
+ onPointerCancel() {
3777
+ this.isPointerInteraction = false;
3778
+ }
3779
+ onPointerEnter() {
3780
+ this.megaMenu.scheduleOpen();
3781
+ }
3782
+ onPointerLeave() {
3783
+ this.megaMenu.scheduleClose();
3784
+ }
3785
+ onFocusIn() {
3786
+ if (this.isPointerInteraction) {
3787
+ return;
3788
+ }
3789
+ this.megaMenu.open();
3790
+ }
3791
+ onArrowDown(event) {
3792
+ event.preventDefault();
3793
+ this.megaMenu.open();
3794
+ }
3795
+ onEscape(event) {
3796
+ event.preventDefault();
3797
+ this.megaMenu.close(true);
3798
+ }
3799
+ ensureChevron() {
3800
+ const host = this.elementRef.nativeElement;
3801
+ if (host.querySelector('.solaris-mega-menu-trigger__chevron')) {
3802
+ return;
3803
+ }
3804
+ const chevron = this.renderer.createElement('span');
3805
+ this.renderer.addClass(chevron, 'solaris-mega-menu-trigger__chevron');
3806
+ this.renderer.setAttribute(chevron, 'aria-hidden', 'true');
3807
+ this.renderer.appendChild(host, chevron);
3808
+ }
3809
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: SolarisMegaMenuTriggerDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
3810
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.17", type: SolarisMegaMenuTriggerDirective, isStandalone: true, selector: "button[solaris-mega-menu-trigger]", host: { listeners: { "click": "onClick()", "pointerdown": "onPointerDown()", "pointercancel": "onPointerCancel()", "pointerenter": "onPointerEnter()", "pointerleave": "onPointerLeave()", "focusin": "onFocusIn()", "keydown.arrowdown": "onArrowDown($event)", "keydown.escape": "onEscape($event)" }, properties: { "attr.aria-controls": "megaMenu.panelId", "attr.aria-expanded": "megaMenu.isOpen() ? \"true\" : \"false\"", "attr.aria-haspopup": "\"true\"", "attr.data-open": "megaMenu.isOpen() ? \"\" : null", "attr.data-appearance": "megaMenu.appearance()" }, classAttribute: "solaris-mega-menu-trigger" }, ngImport: i0 });
3811
+ }
3812
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: SolarisMegaMenuTriggerDirective, decorators: [{
3813
+ type: Directive,
3814
+ args: [{
3815
+ selector: 'button[solaris-mega-menu-trigger]',
3816
+ standalone: true,
3817
+ host: {
3818
+ '[attr.aria-controls]': 'megaMenu.panelId',
3819
+ '[attr.aria-expanded]': 'megaMenu.isOpen() ? "true" : "false"',
3820
+ '[attr.aria-haspopup]': '"true"',
3821
+ '[attr.data-open]': 'megaMenu.isOpen() ? "" : null',
3822
+ '[attr.data-appearance]': 'megaMenu.appearance()',
3823
+ class: 'solaris-mega-menu-trigger',
3824
+ },
3825
+ }]
3826
+ }], ctorParameters: () => [], propDecorators: { onClick: [{
3827
+ type: HostListener,
3828
+ args: ['click']
3829
+ }], onPointerDown: [{
3830
+ type: HostListener,
3831
+ args: ['pointerdown']
3832
+ }], onPointerCancel: [{
3833
+ type: HostListener,
3834
+ args: ['pointercancel']
3835
+ }], onPointerEnter: [{
3836
+ type: HostListener,
3837
+ args: ['pointerenter']
3838
+ }], onPointerLeave: [{
3839
+ type: HostListener,
3840
+ args: ['pointerleave']
3841
+ }], onFocusIn: [{
3842
+ type: HostListener,
3843
+ args: ['focusin']
3844
+ }], onArrowDown: [{
3845
+ type: HostListener,
3846
+ args: ['keydown.arrowdown', ['$event']]
3847
+ }], onEscape: [{
3848
+ type: HostListener,
3849
+ args: ['keydown.escape', ['$event']]
3850
+ }] } });
3851
+
3178
3852
  class SolarisOptionLeadingDirective {
3179
3853
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: SolarisOptionLeadingDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
3180
3854
  static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.17", type: SolarisOptionLeadingDirective, isStandalone: true, selector: "[solaris-option-leading]", ngImport: i0 });
@@ -15227,5 +15901,5 @@ function provideSolaris(config) {
15227
15901
  * Generated bundle index. Do not edit.
15228
15902
  */
15229
15903
 
15230
- export { SOLARIS_ACCESSIBILITY_CONFIG, SOLARIS_BUILT_IN_ICONS, SOLARIS_DIALOG_CONFIG, SOLARIS_DIALOG_DATA, SOLARIS_DIALOG_REF, SOLARIS_ICONS_CONFIG, SOLARIS_SEGMENTED_CONTROL, SOLARIS_STEPPER, SOLARIS_TABS, SOLARIS_THEME_CONFIG, SOLARIS_TOAST_CONFIG, SOLARIS_TRANSLATE_CONFIG, SolarisAccessibilityService, SolarisAccordionComponent, SolarisAlertActionsComponent, SolarisAlertComponent, SolarisAlertDescriptionDirective, SolarisAlertTitleDirective, SolarisBadgeComponent, SolarisBadgeIconDirective, SolarisBreadcrumbComponent, SolarisButtonDirective, SolarisButtonGroupComponent, SolarisButtonIconDirective, SolarisCardActionsDirective, SolarisCardComponent, SolarisCardContentDirective, SolarisCardDescriptionDirective, SolarisCardFooterDirective, SolarisCardHeaderDirective, SolarisCardMediaDirective, SolarisCardTitleDirective, SolarisCheckboxComponent, SolarisCheckboxGroupComponent, SolarisCollapsibleComponent, SolarisDialogActionsComponent, SolarisDialogComponent, SolarisDialogContainerComponent, SolarisDialogContentComponent, SolarisDialogFlowComponent, SolarisDialogHeaderComponent, SolarisDialogRef, SolarisDialogService, SolarisDialogStepComponent, SolarisDividerComponent, SolarisDividerStackComponent, SolarisDropdownMenuComponent, SolarisDropdownMenuGroupComponent, SolarisDropdownMenuItemComponent, SolarisDropdownMenuLabelComponent, SolarisDropdownMenuTriggerDirective, SolarisDropdownSubmenuComponent, SolarisDropdownSubmenuTriggerComponent, SolarisEditableTabComponent, SolarisEditableTabsComponent, SolarisEmailFieldComponent, SolarisFormErrorComponent, SolarisFormFieldComponent, SolarisFormHintComponent, SolarisFormLabelActionDirective, SolarisFormLabelComponent, SolarisFormPrefixDirective, SolarisFormSuffixDirective, SolarisIconButtonBadgeDirective, SolarisIconButtonDirective, SolarisIconComponent, SolarisIconRegistryService, SolarisInputDirective, SolarisLoadingTextComponent, SolarisMultiSelectComponent, SolarisOptionComponent, SolarisOptionDescriptionDirective, SolarisOptionGroupComponent, SolarisOptionLabelDirective, SolarisOptionLeadingDirective, SolarisOptionMetaDirective, SolarisOptionTrailingDirective, SolarisOtpInputComponent, SolarisPasswordFieldComponent, SolarisPhoneCountryListComponent, SolarisPhoneFieldComponent, SolarisPopoverDirective, SolarisPopoverPanelComponent, SolarisPopoverTriggerDirective, SolarisProgressComponent, SolarisRadioComponent, SolarisRadioGroupComponent, SolarisSegmentedControlComponent, SolarisSegmentedItemComponent, SolarisSelectComponent, SolarisSkeletonComponent, SolarisSpinnerComponent, SolarisStepComponent, SolarisStepperActionsComponent, SolarisStepperComponent, SolarisStepperContentComponent, SolarisSwitchComponent, SolarisSwitchGroupComponent, SolarisTabComponent, SolarisTabPanelComponent, SolarisTabsComponent, SolarisTextareaDirective, SolarisThemeService, SolarisToastComponent, SolarisToastContainerComponent, SolarisToastService, SolarisTooltipDirective, SolarisTooltipPanelComponent, SolarisTranslatePipe, SolarisTranslateService, SolarisVisuallyHiddenDirective, configureSolarisTesting, nextIdFor, provideSolaris, provideSolarisAccessibilityTesting, provideSolarisTesting, provideSolarisThemeTesting, provideSolarisTranslateTesting, resolveElementId, solarisAllowedDomainsValidator, solarisBlockedDomainsValidator, solarisEmailValidator, solarisOtpValidator, solarisPasswordValidator, solarisPhoneValidator };
15904
+ export { SOLARIS_ACCESSIBILITY_CONFIG, SOLARIS_BUILT_IN_ICONS, SOLARIS_DIALOG_CONFIG, SOLARIS_DIALOG_DATA, SOLARIS_DIALOG_REF, SOLARIS_ICONS_CONFIG, SOLARIS_SEGMENTED_CONTROL, SOLARIS_STEPPER, SOLARIS_TABS, SOLARIS_THEME_CONFIG, SOLARIS_TOAST_CONFIG, SOLARIS_TRANSLATE_CONFIG, SolarisAccessibilityService, SolarisAccordionComponent, SolarisAlertActionsComponent, SolarisAlertComponent, SolarisAlertDescriptionDirective, SolarisAlertTitleDirective, SolarisAnimatedIconComponent, SolarisBadgeComponent, SolarisBadgeIconDirective, SolarisBreadcrumbComponent, SolarisButtonDirective, SolarisButtonGroupComponent, SolarisButtonIconDirective, SolarisCardActionsDirective, SolarisCardComponent, SolarisCardContentDirective, SolarisCardDescriptionDirective, SolarisCardFooterDirective, SolarisCardHeaderDirective, SolarisCardMediaDirective, SolarisCardTitleDirective, SolarisCheckboxComponent, SolarisCheckboxGroupComponent, SolarisCollapsibleComponent, SolarisDialogActionsComponent, SolarisDialogComponent, SolarisDialogContainerComponent, SolarisDialogContentComponent, SolarisDialogFlowComponent, SolarisDialogHeaderComponent, SolarisDialogRef, SolarisDialogService, SolarisDialogStepComponent, SolarisDividerComponent, SolarisDividerStackComponent, SolarisDropdownMenuComponent, SolarisDropdownMenuGroupComponent, SolarisDropdownMenuItemComponent, SolarisDropdownMenuLabelComponent, SolarisDropdownMenuTriggerDirective, SolarisDropdownSubmenuComponent, SolarisDropdownSubmenuTriggerComponent, SolarisEditableTabComponent, SolarisEditableTabsComponent, SolarisEmailFieldComponent, SolarisFormErrorComponent, SolarisFormFieldComponent, SolarisFormHintComponent, SolarisFormLabelActionDirective, SolarisFormLabelComponent, SolarisFormPrefixDirective, SolarisFormSuffixDirective, SolarisIconButtonBadgeDirective, SolarisIconButtonDirective, SolarisIconComponent, SolarisIconRegistryService, SolarisInputDirective, SolarisLoadingTextComponent, SolarisMegaMenuAnchorDirective, SolarisMegaMenuComponent, SolarisMegaMenuGroupDirective, SolarisMegaMenuPanelDirective, SolarisMegaMenuTriggerDirective, SolarisMenuToggleDirective, SolarisMultiSelectComponent, SolarisOptionComponent, SolarisOptionDescriptionDirective, SolarisOptionGroupComponent, SolarisOptionLabelDirective, SolarisOptionLeadingDirective, SolarisOptionMetaDirective, SolarisOptionTrailingDirective, SolarisOtpInputComponent, SolarisPasswordFieldComponent, SolarisPhoneCountryListComponent, SolarisPhoneFieldComponent, SolarisPopoverDirective, SolarisPopoverPanelComponent, SolarisPopoverTriggerDirective, SolarisProgressComponent, SolarisRadioComponent, SolarisRadioGroupComponent, SolarisSegmentedControlComponent, SolarisSegmentedItemComponent, SolarisSelectComponent, SolarisSkeletonComponent, SolarisSpinnerComponent, SolarisStepComponent, SolarisStepperActionsComponent, SolarisStepperComponent, SolarisStepperContentComponent, SolarisSwitchComponent, SolarisSwitchGroupComponent, SolarisTabComponent, SolarisTabPanelComponent, SolarisTabsComponent, SolarisTextareaDirective, SolarisThemeService, SolarisToastComponent, SolarisToastContainerComponent, SolarisToastService, SolarisTooltipDirective, SolarisTooltipPanelComponent, SolarisTranslatePipe, SolarisTranslateService, SolarisVisuallyHiddenDirective, configureSolarisTesting, nextIdFor, provideSolaris, provideSolarisAccessibilityTesting, provideSolarisTesting, provideSolarisThemeTesting, provideSolarisTranslateTesting, resolveElementId, solarisAllowedDomainsValidator, solarisBlockedDomainsValidator, solarisEmailValidator, solarisOtpValidator, solarisPasswordValidator, solarisPhoneValidator };
15231
15905
  //# sourceMappingURL=educarehq-solaris-ui.mjs.map