@acorex-platform/framework-client 0.0.28 → 0.0.32

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.
Files changed (60) hide show
  1. package/fesm2022/{acorex-platform-framework-client-common-common-settings.provider-CLm2BVk-.mjs → acorex-platform-framework-client-common-common-settings.provider-CzBr0cRi.mjs} +23 -2
  2. package/fesm2022/acorex-platform-framework-client-common-common-settings.provider-CzBr0cRi.mjs.map +1 -0
  3. package/fesm2022/acorex-platform-framework-client-common.mjs +678 -112
  4. package/fesm2022/acorex-platform-framework-client-common.mjs.map +1 -1
  5. package/fesm2022/acorex-platform-framework-client-core.mjs +85 -9
  6. package/fesm2022/acorex-platform-framework-client-core.mjs.map +1 -1
  7. package/fesm2022/acorex-platform-framework-client-layout-builder.mjs +3 -6
  8. package/fesm2022/acorex-platform-framework-client-layout-builder.mjs.map +1 -1
  9. package/fesm2022/acorex-platform-framework-client-layout-components.mjs +469 -73
  10. package/fesm2022/acorex-platform-framework-client-layout-components.mjs.map +1 -1
  11. package/fesm2022/{acorex-platform-framework-client-layout-entity-acorex-platform-framework-client-layout-entity-BXOMs6oD.mjs → acorex-platform-framework-client-layout-entity-acorex-platform-framework-client-layout-entity-Bu8LLCVa.mjs} +3324 -2169
  12. package/fesm2022/acorex-platform-framework-client-layout-entity-acorex-platform-framework-client-layout-entity-Bu8LLCVa.mjs.map +1 -0
  13. package/fesm2022/{acorex-platform-framework-client-layout-entity-attachments-page.component-DCK-qb-F.mjs → acorex-platform-framework-client-layout-entity-attachments-page.component-EU1dgVH_.mjs} +2 -2
  14. package/fesm2022/{acorex-platform-framework-client-layout-entity-attachments-page.component-DCK-qb-F.mjs.map → acorex-platform-framework-client-layout-entity-attachments-page.component-EU1dgVH_.mjs.map} +1 -1
  15. package/fesm2022/{acorex-platform-framework-client-layout-entity-bulk-entity.command-Cs3agnpF.mjs → acorex-platform-framework-client-layout-entity-bulk-entity.command-DNBhGkO8.mjs} +43 -15
  16. package/fesm2022/acorex-platform-framework-client-layout-entity-bulk-entity.command-DNBhGkO8.mjs.map +1 -0
  17. package/fesm2022/{acorex-platform-framework-client-layout-entity-file-list-popup.component-p0hxDb0W.mjs → acorex-platform-framework-client-layout-entity-file-list-popup.component-B3__csKW.mjs} +3 -3
  18. package/fesm2022/{acorex-platform-framework-client-layout-entity-file-list-popup.component-p0hxDb0W.mjs.map → acorex-platform-framework-client-layout-entity-file-list-popup.component-B3__csKW.mjs.map} +1 -1
  19. package/fesm2022/{acorex-platform-framework-client-layout-entity-gallery-page.component-DYV9YPyw.mjs → acorex-platform-framework-client-layout-entity-gallery-page.component-DtNSVjeF.mjs} +2 -2
  20. package/fesm2022/{acorex-platform-framework-client-layout-entity-gallery-page.component-DYV9YPyw.mjs.map → acorex-platform-framework-client-layout-entity-gallery-page.component-DtNSVjeF.mjs.map} +1 -1
  21. package/fesm2022/acorex-platform-framework-client-layout-entity.mjs +1 -1
  22. package/fesm2022/acorex-platform-framework-client-layout-views.mjs +37 -6
  23. package/fesm2022/acorex-platform-framework-client-layout-views.mjs.map +1 -1
  24. package/fesm2022/acorex-platform-framework-client-layout-widget-core.mjs +148 -130
  25. package/fesm2022/acorex-platform-framework-client-layout-widget-core.mjs.map +1 -1
  26. package/fesm2022/{acorex-platform-framework-client-layout-widgets-repeater-widget-column.component-3CO4xJB3.mjs → acorex-platform-framework-client-layout-widgets-repeater-widget-column.component-4mX8aYzA.mjs} +3 -3
  27. package/fesm2022/{acorex-platform-framework-client-layout-widgets-repeater-widget-column.component-3CO4xJB3.mjs.map → acorex-platform-framework-client-layout-widgets-repeater-widget-column.component-4mX8aYzA.mjs.map} +1 -1
  28. package/fesm2022/{acorex-platform-framework-client-layout-widgets-tabular-data-edit-popup.component-CRST84ou.mjs → acorex-platform-framework-client-layout-widgets-tabular-data-edit-popup.component-D3pnOGmB.mjs} +3 -3
  29. package/fesm2022/{acorex-platform-framework-client-layout-widgets-tabular-data-edit-popup.component-CRST84ou.mjs.map → acorex-platform-framework-client-layout-widgets-tabular-data-edit-popup.component-D3pnOGmB.mjs.map} +1 -1
  30. package/fesm2022/acorex-platform-framework-client-layout-widgets.mjs +1127 -717
  31. package/fesm2022/acorex-platform-framework-client-layout-widgets.mjs.map +1 -1
  32. package/fesm2022/acorex-platform-framework-client-realtime.mjs +70 -5
  33. package/fesm2022/acorex-platform-framework-client-realtime.mjs.map +1 -1
  34. package/fesm2022/acorex-platform-framework-client-runtime.mjs +121 -6
  35. package/fesm2022/acorex-platform-framework-client-runtime.mjs.map +1 -1
  36. package/fesm2022/{acorex-platform-framework-client-themes-default-entity-master-single-view.component-C2Abf7Lb.mjs → acorex-platform-framework-client-themes-default-entity-master-single-view.component-DCpl6AXq.mjs} +51 -12
  37. package/fesm2022/acorex-platform-framework-client-themes-default-entity-master-single-view.component-DCpl6AXq.mjs.map +1 -0
  38. package/fesm2022/acorex-platform-framework-client-themes-default.mjs +770 -679
  39. package/fesm2022/acorex-platform-framework-client-themes-default.mjs.map +1 -1
  40. package/fesm2022/{acorex-platform-framework-client-themes-shared-settings.provider-D2XPkc71.mjs → acorex-platform-framework-client-themes-shared-settings.provider-CpsAIsxj.mjs} +76 -1
  41. package/fesm2022/acorex-platform-framework-client-themes-shared-settings.provider-CpsAIsxj.mjs.map +1 -0
  42. package/fesm2022/acorex-platform-framework-client-themes-shared.mjs +320 -32
  43. package/fesm2022/acorex-platform-framework-client-themes-shared.mjs.map +1 -1
  44. package/package.json +7 -7
  45. package/types/acorex-platform-framework-client-common.d.ts +137 -9
  46. package/types/acorex-platform-framework-client-core.d.ts +4 -1
  47. package/types/acorex-platform-framework-client-layout-components.d.ts +139 -20
  48. package/types/acorex-platform-framework-client-layout-entity.d.ts +518 -256
  49. package/types/acorex-platform-framework-client-layout-views.d.ts +48 -0
  50. package/types/acorex-platform-framework-client-layout-widget-core.d.ts +2 -2
  51. package/types/acorex-platform-framework-client-layout-widgets.d.ts +130 -80
  52. package/types/acorex-platform-framework-client-realtime.d.ts +39 -2
  53. package/types/acorex-platform-framework-client-runtime.d.ts +56 -5
  54. package/types/acorex-platform-framework-client-themes-default.d.ts +144 -14
  55. package/types/acorex-platform-framework-client-themes-shared.d.ts +36 -3
  56. package/fesm2022/acorex-platform-framework-client-common-common-settings.provider-CLm2BVk-.mjs.map +0 -1
  57. package/fesm2022/acorex-platform-framework-client-layout-entity-acorex-platform-framework-client-layout-entity-BXOMs6oD.mjs.map +0 -1
  58. package/fesm2022/acorex-platform-framework-client-layout-entity-bulk-entity.command-Cs3agnpF.mjs.map +0 -1
  59. package/fesm2022/acorex-platform-framework-client-themes-default-entity-master-single-view.component-C2Abf7Lb.mjs.map +0 -1
  60. package/fesm2022/acorex-platform-framework-client-themes-shared-settings.provider-D2XPkc71.mjs.map +0 -1
@@ -1,4 +1,4 @@
1
- import { getSystemActions, AXPFileStorageStatus, AXP_QUERY_QUICK_SEARCH_FIELD, AXPKeyboardShortcutPriority, runtimeQueryCollectionData, compareMultiLanguageStrings, containsHtmlMarkup, isFormValueEqual, extractTextFromHtml, AXPWidgetsCatalog, AXPRegionalSetting, AXP_PREVIEW_WIDGET_FIELD_COMMAND_KEY } from '@acorex-platform/framework-shared/core';
1
+ import { getSystemActions, resolveToSurfaceClass, AXPFileStorageStatus, AXP_QUERY_QUICK_SEARCH_FIELD, AXPKeyboardShortcutPriority, runtimeQueryCollectionData, compareMultiLanguageStrings, containsHtmlMarkup, isFormValueEqual, extractTextFromHtml, AXPWidgetsCatalog, AXPRegionalSetting, AXP_PREVIEW_WIDGET_FIELD_COMMAND_KEY } from '@acorex-platform/framework-shared/core';
2
2
  import * as i1$2 from '@acorex/components/button';
3
3
  import { AXButtonModule } from '@acorex/components/button';
4
4
  import * as i1$6 from '@acorex/cdk/common';
@@ -6,7 +6,7 @@ import { AXCommonModule } from '@acorex/cdk/common';
6
6
  import * as i2$1 from '@acorex/components/decorators';
7
7
  import { AXDecoratorModule } from '@acorex/components/decorators';
8
8
  import * as i3 from '@acorex/core/translation';
9
- import { AXTranslationModule, AXTranslationService } from '@acorex/core/translation';
9
+ import { AXTranslationService, AXTranslationModule } from '@acorex/core/translation';
10
10
  import * as i2 from '@acorex/components/skeleton';
11
11
  import { AXSkeletonModule } from '@acorex/components/skeleton';
12
12
  import * as i4 from '@acorex/core/format';
@@ -15,9 +15,11 @@ import { AXPLayoutRendererComponent, AXPLayoutBuilderService } from '@acorex-pla
15
15
  import * as i1 from '@angular/common';
16
16
  import { CommonModule, NgTemplateOutlet, AsyncPipe, isPlatformBrowser, DOCUMENT } from '@angular/common';
17
17
  import * as i0 from '@angular/core';
18
- import { input, ChangeDetectionStrategy, ViewEncapsulation, Component, inject, output, signal, effect, linkedSignal, computed, InjectionToken, Injector, Injectable, Directive, viewChild, contentChild, ElementRef, afterNextRender, model, EventEmitter, forwardRef, ViewChild, Output, Input, untracked, DestroyRef, PLATFORM_ID, createComponent, runInInjectionContext, EnvironmentInjector, ApplicationRef, makeEnvironmentProviders, ViewChildren, TemplateRef, contentChildren } from '@angular/core';
18
+ import { inject, input, output, signal, effect, ViewEncapsulation, ChangeDetectionStrategy, Component, linkedSignal, computed, InjectionToken, Injector, Injectable, Directive, viewChild, contentChild, ElementRef, afterNextRender, model, EventEmitter, forwardRef, ViewChild, Output, Input, untracked, DestroyRef, PLATFORM_ID, createComponent, runInInjectionContext, EnvironmentInjector, ApplicationRef, makeEnvironmentProviders, ViewChildren, TemplateRef, contentChildren } from '@angular/core';
19
19
  import { AXAccordionCdkModule } from '@acorex/cdk/accordion';
20
20
  import { AXTagModule } from '@acorex/components/tag';
21
+ import { AXPStateMessageComponent, AXPSettingsService, AXPFileChooserSettings, normalizeStoredImageRef, extractFileExtension, AXPFileStorageService, AXPFileTypeProviderService, resolveFileTypeDisplay, AXPFilterOperatorMiddlewareService, AXPCommonSettings, ALL_DEFAULT_OPERATORS, withDefaultMultiLanguageOnWidgetProperty, AXPDefaultMultiLanguageConfigService, resolveSearchableText, isStoredImageFileId, resolveStoredImageDisplayUrl } from '@acorex-platform/framework-client/common';
22
+ export { AXPFileChooserSettings, AXPStateMessageComponent } from '@acorex-platform/framework-client/common';
21
23
  import * as i1$1 from '@acorex/components/avatar';
22
24
  import { AXAvatarModule } from '@acorex/components/avatar';
23
25
  import * as i3$1 from '@acorex/components/image';
@@ -32,6 +34,8 @@ import { AXDropdownModule } from '@acorex/components/dropdown';
32
34
  import * as i5 from '@acorex/components/search-box';
33
35
  import { AXSearchBoxModule } from '@acorex/components/search-box';
34
36
  import { AXTreeViewComponent } from '@acorex/components/tree-view';
37
+ import { ensureRuntimeSurfaceClasses, setupPopupFooterKeyboardShortcuts, AXPExpressionEvaluatorService, AXPColumnWidthService, AXPDataGenerator, AXPHookService, AXP_DISTRIBUTED_EVENT_LISTENER_PROVIDER, AXPKeyboardShortcutRegistry, chordToKbdItemKeys, AXPDeviceService } from '@acorex-platform/framework-client/core';
38
+ export { AXPLogoComponent } from '@acorex-platform/framework-client/core';
35
39
  import * as i2$2 from '@acorex/components/popover';
36
40
  import { AXPopoverModule } from '@acorex/components/popover';
37
41
  import * as i3$2 from '@acorex/components/switch';
@@ -53,8 +57,6 @@ import { AXPWidgetCoreModule, AXPWidgetRegistryService, AXPWidgetContainerCompon
53
57
  import * as i3$4 from '@acorex/components/dropdown-button';
54
58
  import { AXDropdownButtonModule } from '@acorex/components/dropdown-button';
55
59
  import { AXBasePageComponent } from '@acorex/components/page';
56
- import { setupPopupFooterKeyboardShortcuts, AXPExpressionEvaluatorService, AXPColumnWidthService, AXPDataGenerator, AXPHookService, AXP_DISTRIBUTED_EVENT_LISTENER_PROVIDER, AXPKeyboardShortcutRegistry, chordToKbdItemKeys } from '@acorex-platform/framework-client/core';
57
- export { AXPLogoComponent } from '@acorex-platform/framework-client/core';
58
60
  import * as i7 from '@acorex/components/loading';
59
61
  import { AXLoadingModule } from '@acorex/components/loading';
60
62
  import { AXPopupService } from '@acorex/components/popup';
@@ -62,8 +64,6 @@ import { moveItemInArray as moveItemInArray$1, AXDragDirective, AXDragHandleDire
62
64
  import * as i2$4 from '@acorex/components/select-box';
63
65
  import { AXSelectBoxModule } from '@acorex/components/select-box';
64
66
  import { AXToastService } from '@acorex/components/toast';
65
- import { AXPSettingsService, AXPFileChooserSettings, normalizeStoredImageRef, extractFileExtension, AXPFileStorageService, AXPFileTypeProviderService, resolveFileTypeDisplay, AXPFilterOperatorMiddlewareService, AXPCommonSettings, ALL_DEFAULT_OPERATORS, withDefaultMultiLanguageOnWidgetProperty, AXPDefaultMultiLanguageConfigService, resolveSearchableText, isStoredImageFileId, resolveStoredImageDisplayUrl } from '@acorex-platform/framework-client/common';
66
- export { AXPFileChooserSettings } from '@acorex-platform/framework-client/common';
67
67
  import { getFileExtension, AXFileService } from '@acorex/core/file';
68
68
  import { AXDialogService } from '@acorex/components/dialog';
69
69
  import { resolveFileViewerFileType, AXFileViewerContainerComponent, AXFileViewerService, AXFileViewerGalleryService } from '@acorex/components/file-viewer';
@@ -101,39 +101,15 @@ import { AXOverlayService } from '@acorex/cdk/overlay';
101
101
  import { AXLocaleService } from '@acorex/core/locale';
102
102
  import { AXPlatform } from '@acorex/core/platform';
103
103
  import { Router, NavigationStart } from '@angular/router';
104
- import * as i5$3 from '@acorex/components/tooltip';
104
+ import * as i6 from '@acorex/components/tooltip';
105
105
  import { AXTooltipModule } from '@acorex/components/tooltip';
106
106
 
107
+ //#region ----- Re-export -----
108
+ /**
109
+ * Implementation lives in `framework-client/common` so `common` can render empty
110
+ * states without importing this entry (ng-packagr secondary-entry cycle).
111
+ */
107
112
  //#endregion
108
- //#region ---- Component Definition ----
109
- //#endregion
110
- //#region ---- Component Class ----
111
- class AXPStateMessageComponent {
112
- constructor() {
113
- // Core properties
114
- this.mode = input('empty', /* @ts-ignore */
115
- ...(ngDevMode ? [{ debugName: "mode" }] : /* istanbul ignore next */ []));
116
- this.icon = input('', /* @ts-ignore */
117
- ...(ngDevMode ? [{ debugName: "icon" }] : /* istanbul ignore next */ []));
118
- this.title = input('', /* @ts-ignore */
119
- ...(ngDevMode ? [{ debugName: "title" }] : /* istanbul ignore next */ []));
120
- this.description = input('', /* @ts-ignore */
121
- ...(ngDevMode ? [{ debugName: "description" }] : /* istanbul ignore next */ []));
122
- this.titleParams = input({}, /* @ts-ignore */
123
- ...(ngDevMode ? [{ debugName: "titleParams" }] : /* istanbul ignore next */ []));
124
- this.descriptionParams = input({}, /* @ts-ignore */
125
- ...(ngDevMode ? [{ debugName: "descriptionParams" }] : /* istanbul ignore next */ []));
126
- // Optional styling
127
- this.look = input('default', /* @ts-ignore */
128
- ...(ngDevMode ? [{ debugName: "look" }] : /* istanbul ignore next */ []));
129
- }
130
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPStateMessageComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
131
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: AXPStateMessageComponent, isStandalone: true, selector: "axp-state-message", inputs: { mode: { classPropertyName: "mode", publicName: "mode", isSignal: true, isRequired: false, transformFunction: null }, icon: { classPropertyName: "icon", publicName: "icon", isSignal: true, isRequired: false, transformFunction: null }, title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, description: { classPropertyName: "description", publicName: "description", isSignal: true, isRequired: false, transformFunction: null }, titleParams: { classPropertyName: "titleParams", publicName: "titleParams", isSignal: true, isRequired: false, transformFunction: null }, descriptionParams: { classPropertyName: "descriptionParams", publicName: "descriptionParams", isSignal: true, isRequired: false, transformFunction: null }, look: { classPropertyName: "look", publicName: "look", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<div class=\"axp-state-message\" [attr.data-mode]=\"mode()\" [attr.data-look]=\"look()\">\n @if (icon()) {\n <div class=\"__icon\">\n <i [class]=\"icon()\"></i>\n </div>\n }\n <div class=\"__content\">\n @if (title()) {\n <h3 class=\"__title\">{{ title() | translate: { params: titleParams() } | async }}</h3>\n }\n @if (description()) {\n <p class=\"__description\">{{ description() | translate: { params: descriptionParams() } | async }}</p>\n }\n <div class=\"__actions\">\n <ng-content select=\"[slot=actions]\"></ng-content>\n </div>\n </div>\n</div>", styles: ["@layer properties;.axp-state-message{display:flex;height:100%;flex-direction:column;align-items:center;justify-content:center;padding-inline:calc(var(--spacing, .25rem) * 4);padding-block:calc(var(--spacing, .25rem) * 12);text-align:center}.axp-state-message .__icon{margin-bottom:calc(var(--spacing, .25rem) * 4)}.axp-state-message .__icon i{opacity:74%;display:block;font-size:1rem;font-weight:400;line-height:1.625rem;font-size:var(--text-4xl, 2.25rem);line-height:var(--tw-leading, var(--text-4xl--line-height, calc(2.5 / 2.25)))}.axp-state-message .__content{max-width:var(--container-md, 28rem)}.axp-state-message .__title{margin-bottom:calc(var(--spacing, .25rem) * 2);font-size:var(--text-lg, 1.125rem);line-height:var(--tw-leading, var(--text-lg--line-height, calc(1.75 / 1.125)));--tw-font-weight: var(--font-weight-medium, 500);font-weight:var(--font-weight-medium, 500)}.axp-state-message .__description{margin-bottom:calc(var(--spacing, .25rem) * 4);opacity:74%;display:block;font-size:1rem;font-weight:400;line-height:1.625rem;font-size:var(--text-sm, .875rem);line-height:var(--tw-leading, var(--text-sm--line-height, calc(1.25 / .875)))}.axp-state-message .__actions{display:flex;flex-direction:column;align-items:center;gap:calc(var(--spacing, .25rem) * 2)}.axp-state-message[data-mode=empty] .__icon i{color:var(--color-gray-400, oklch(70.7% .022 261.325))}.axp-state-message[data-mode=error] .__icon i{color:var(--color-red-500, oklch(63.7% .237 25.331))}.axp-state-message[data-mode=error] .__title{color:var(--color-red-600, oklch(57.7% .245 27.325))}.axp-state-message[data-mode=loading] .__icon i{color:var(--color-blue-500, oklch(62.3% .214 259.815))}.axp-state-message[data-mode=loading] .__title{color:var(--color-blue-600, oklch(54.6% .245 262.881))}.axp-state-message[data-mode=warning] .__icon i{color:var(--color-orange-500, oklch(70.5% .213 47.604))}.axp-state-message[data-mode=warning] .__title{color:var(--color-orange-600, oklch(64.6% .222 41.116))}.axp-state-message[data-mode=info] .__icon i{color:var(--color-blue-500, oklch(62.3% .214 259.815))}.axp-state-message[data-mode=info] .__title{color:var(--color-blue-600, oklch(54.6% .245 262.881))}.axp-state-message[data-mode=success] .__icon i{color:var(--color-green-500, oklch(72.3% .219 149.579))}.axp-state-message[data-mode=success] .__title{color:var(--color-green-600, oklch(62.7% .194 149.214))}.axp-state-message[data-look=compact]{padding-inline:calc(var(--spacing, .25rem) * 3);padding-block:calc(var(--spacing, .25rem) * 6)}.axp-state-message[data-look=compact] .__icon{margin-bottom:calc(var(--spacing, .25rem) * 2)}.axp-state-message[data-look=compact] .__icon i{font-size:var(--text-2xl, 1.5rem);line-height:var(--tw-leading, var(--text-2xl--line-height, calc(2 / 1.5)))}.axp-state-message[data-look=compact] .__title{margin-bottom:var(--spacing, .25rem);font-size:var(--text-base, 1rem);line-height:var(--tw-leading, var(--text-base--line-height, 1.5 ))}.axp-state-message[data-look=compact] .__description{margin-bottom:calc(var(--spacing, .25rem) * 2);font-size:var(--text-xs, .75rem);line-height:var(--tw-leading, var(--text-xs--line-height, calc(1 / .75)))}.axp-state-message[data-look=minimal]{padding-inline:calc(var(--spacing, .25rem) * 2);padding-block:calc(var(--spacing, .25rem) * 4)}.axp-state-message[data-look=minimal] .__icon{margin-bottom:var(--spacing, .25rem)}.axp-state-message[data-look=minimal] .__icon i{font-size:var(--text-xl, 1.25rem);line-height:var(--tw-leading, var(--text-xl--line-height, calc(1.75 / 1.25)))}.axp-state-message[data-look=minimal] .__title{margin-bottom:var(--spacing, .25rem);font-size:var(--text-sm, .875rem);line-height:var(--tw-leading, var(--text-sm--line-height, calc(1.25 / .875)))}.axp-state-message[data-look=minimal] .__description{margin-bottom:var(--spacing, .25rem);font-size:var(--text-xs, .75rem);line-height:var(--tw-leading, var(--text-xs--line-height, calc(1 / .75)))}@property --tw-font-weight{syntax: \"*\"; inherits: false;}@layer properties{@supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-font-weight: initial}}}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }, { kind: "pipe", type: i3.AXTranslatorPipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
132
- }
133
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPStateMessageComponent, decorators: [{
134
- type: Component,
135
- args: [{ selector: 'axp-state-message', standalone: true, imports: [CommonModule, AXTranslationModule], encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"axp-state-message\" [attr.data-mode]=\"mode()\" [attr.data-look]=\"look()\">\n @if (icon()) {\n <div class=\"__icon\">\n <i [class]=\"icon()\"></i>\n </div>\n }\n <div class=\"__content\">\n @if (title()) {\n <h3 class=\"__title\">{{ title() | translate: { params: titleParams() } | async }}</h3>\n }\n @if (description()) {\n <p class=\"__description\">{{ description() | translate: { params: descriptionParams() } | async }}</p>\n }\n <div class=\"__actions\">\n <ng-content select=\"[slot=actions]\"></ng-content>\n </div>\n </div>\n</div>", styles: ["@layer properties;.axp-state-message{display:flex;height:100%;flex-direction:column;align-items:center;justify-content:center;padding-inline:calc(var(--spacing, .25rem) * 4);padding-block:calc(var(--spacing, .25rem) * 12);text-align:center}.axp-state-message .__icon{margin-bottom:calc(var(--spacing, .25rem) * 4)}.axp-state-message .__icon i{opacity:74%;display:block;font-size:1rem;font-weight:400;line-height:1.625rem;font-size:var(--text-4xl, 2.25rem);line-height:var(--tw-leading, var(--text-4xl--line-height, calc(2.5 / 2.25)))}.axp-state-message .__content{max-width:var(--container-md, 28rem)}.axp-state-message .__title{margin-bottom:calc(var(--spacing, .25rem) * 2);font-size:var(--text-lg, 1.125rem);line-height:var(--tw-leading, var(--text-lg--line-height, calc(1.75 / 1.125)));--tw-font-weight: var(--font-weight-medium, 500);font-weight:var(--font-weight-medium, 500)}.axp-state-message .__description{margin-bottom:calc(var(--spacing, .25rem) * 4);opacity:74%;display:block;font-size:1rem;font-weight:400;line-height:1.625rem;font-size:var(--text-sm, .875rem);line-height:var(--tw-leading, var(--text-sm--line-height, calc(1.25 / .875)))}.axp-state-message .__actions{display:flex;flex-direction:column;align-items:center;gap:calc(var(--spacing, .25rem) * 2)}.axp-state-message[data-mode=empty] .__icon i{color:var(--color-gray-400, oklch(70.7% .022 261.325))}.axp-state-message[data-mode=error] .__icon i{color:var(--color-red-500, oklch(63.7% .237 25.331))}.axp-state-message[data-mode=error] .__title{color:var(--color-red-600, oklch(57.7% .245 27.325))}.axp-state-message[data-mode=loading] .__icon i{color:var(--color-blue-500, oklch(62.3% .214 259.815))}.axp-state-message[data-mode=loading] .__title{color:var(--color-blue-600, oklch(54.6% .245 262.881))}.axp-state-message[data-mode=warning] .__icon i{color:var(--color-orange-500, oklch(70.5% .213 47.604))}.axp-state-message[data-mode=warning] .__title{color:var(--color-orange-600, oklch(64.6% .222 41.116))}.axp-state-message[data-mode=info] .__icon i{color:var(--color-blue-500, oklch(62.3% .214 259.815))}.axp-state-message[data-mode=info] .__title{color:var(--color-blue-600, oklch(54.6% .245 262.881))}.axp-state-message[data-mode=success] .__icon i{color:var(--color-green-500, oklch(72.3% .219 149.579))}.axp-state-message[data-mode=success] .__title{color:var(--color-green-600, oklch(62.7% .194 149.214))}.axp-state-message[data-look=compact]{padding-inline:calc(var(--spacing, .25rem) * 3);padding-block:calc(var(--spacing, .25rem) * 6)}.axp-state-message[data-look=compact] .__icon{margin-bottom:calc(var(--spacing, .25rem) * 2)}.axp-state-message[data-look=compact] .__icon i{font-size:var(--text-2xl, 1.5rem);line-height:var(--tw-leading, var(--text-2xl--line-height, calc(2 / 1.5)))}.axp-state-message[data-look=compact] .__title{margin-bottom:var(--spacing, .25rem);font-size:var(--text-base, 1rem);line-height:var(--tw-leading, var(--text-base--line-height, 1.5 ))}.axp-state-message[data-look=compact] .__description{margin-bottom:calc(var(--spacing, .25rem) * 2);font-size:var(--text-xs, .75rem);line-height:var(--tw-leading, var(--text-xs--line-height, calc(1 / .75)))}.axp-state-message[data-look=minimal]{padding-inline:calc(var(--spacing, .25rem) * 2);padding-block:calc(var(--spacing, .25rem) * 4)}.axp-state-message[data-look=minimal] .__icon{margin-bottom:var(--spacing, .25rem)}.axp-state-message[data-look=minimal] .__icon i{font-size:var(--text-xl, 1.25rem);line-height:var(--tw-leading, var(--text-xl--line-height, calc(1.75 / 1.25)))}.axp-state-message[data-look=minimal] .__title{margin-bottom:var(--spacing, .25rem);font-size:var(--text-sm, .875rem);line-height:var(--tw-leading, var(--text-sm--line-height, calc(1.25 / .875)))}.axp-state-message[data-look=minimal] .__description{margin-bottom:var(--spacing, .25rem);font-size:var(--text-xs, .75rem);line-height:var(--tw-leading, var(--text-xs--line-height, calc(1 / .75)))}@property --tw-font-weight{syntax: \"*\"; inherits: false;}@layer properties{@supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-font-weight: initial}}}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"] }]
136
- }], propDecorators: { mode: [{ type: i0.Input, args: [{ isSignal: true, alias: "mode", required: false }] }], icon: [{ type: i0.Input, args: [{ isSignal: true, alias: "icon", required: false }] }], title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: false }] }], description: [{ type: i0.Input, args: [{ isSignal: true, alias: "description", required: false }] }], titleParams: [{ type: i0.Input, args: [{ isSignal: true, alias: "titleParams", required: false }] }], descriptionParams: [{ type: i0.Input, args: [{ isSignal: true, alias: "descriptionParams", required: false }] }], look: [{ type: i0.Input, args: [{ isSignal: true, alias: "look", required: false }] }] } });
137
113
 
138
114
  //#region ---- Component Definition ----
139
115
  class AXPActivityLogComponent {
@@ -317,6 +293,9 @@ class AXPAvatarComponent {
317
293
  /** Display name used for title and initials fallback. */
318
294
  this.fullName = input('', /* @ts-ignore */
319
295
  ...(ngDevMode ? [{ debugName: "fullName" }] : /* istanbul ignore next */ []));
296
+ /** Native browser tooltip. Off when a user card or nearby label already shows the name. */
297
+ this.showTitle = input(true, /* @ts-ignore */
298
+ ...(ngDevMode ? [{ debugName: "showTitle" }] : /* istanbul ignore next */ []));
320
299
  /** Optional override for fallback text shown when image is not available. */
321
300
  this.fallbackText = input(undefined, /* @ts-ignore */
322
301
  ...(ngDevMode ? [{ debugName: "fallbackText" }] : /* istanbul ignore next */ []));
@@ -345,7 +324,10 @@ class AXPAvatarComponent {
345
324
  return this.computeInitials(this.normalizedName());
346
325
  }, /* @ts-ignore */
347
326
  ...(ngDevMode ? [{ debugName: "avatarText" }] : /* istanbul ignore next */ []));
348
- this.avatarColor = computed(() => this.pickColor(this.avatarText()), /* @ts-ignore */
327
+ this.avatarColor = computed(() => {
328
+ const colorKey = this.normalizedName() || this.avatarText();
329
+ return this.pickColor(colorKey);
330
+ }, /* @ts-ignore */
349
331
  ...(ngDevMode ? [{ debugName: "avatarColor" }] : /* istanbul ignore next */ []));
350
332
  this.title = computed(() => this.normalizedName(), /* @ts-ignore */
351
333
  ...(ngDevMode ? [{ debugName: "title" }] : /* istanbul ignore next */ []));
@@ -360,13 +342,11 @@ class AXPAvatarComponent {
360
342
  if (!name) {
361
343
  return '?';
362
344
  }
363
- const parts = name
364
- .split(/\s+/)
365
- .filter(Boolean);
366
- if (parts.length === 1) {
367
- return parts[0].slice(0, 2).toUpperCase();
345
+ const firstWord = name.split(/\s+/).find(Boolean);
346
+ if (!firstWord) {
347
+ return '?';
368
348
  }
369
- return (parts[0][0] + parts[parts.length - 1][0]).toUpperCase();
349
+ return firstWord.charAt(0).toUpperCase();
370
350
  }
371
351
  hashString(value) {
372
352
  let hash = 0;
@@ -382,12 +362,12 @@ class AXPAvatarComponent {
382
362
  return colors[index];
383
363
  }
384
364
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPAvatarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
385
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: AXPAvatarComponent, isStandalone: true, selector: "axp-avatar", inputs: { size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, src: { classPropertyName: "src", publicName: "src", isSignal: true, isRequired: false, transformFunction: null }, fullName: { classPropertyName: "fullName", publicName: "fullName", isSignal: true, isRequired: false, transformFunction: null }, fallbackText: { classPropertyName: "fallbackText", publicName: "fallbackText", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<ax-avatar\n [size]=\"size()\"\n class=\"cursor-pointer relative border\"\n [color]=\"avatarColor()\"\n [look]=\"'twotone'\"\n [attr.data-avatar-color]=\"avatarColor()\"\n [title]=\"title()\"\n>\n @if (hasAvatar()) {\n <ax-image\n (onError)=\"onImageError($event)\"\n (onLoad)=\"onImageLoad($event)\"\n [src]=\"resolvedSrc()\"\n />\n } @else {\n <ax-text class=\"axp-avatar__initials-wrap\">\n <span class=\"axp-avatar__initials\" [style.font-size]=\"size() * 0.35 + 'px'\">{{\n avatarText()\n }}</span>\n </ax-text>\n }\n</ax-avatar>\n", styles: [":host{display:inline-flex;align-items:center;justify-content:center;line-height:0}:host ax-avatar{display:inline-flex!important;align-items:center;justify-content:center;line-height:0}:host ax-avatar[data-avatar-color=primary]{background-color:var(--color-primary-lightest);color:var(--color-on-primary-lightest);border-color:var(--color-border-primary-lightest)}:host ax-avatar[data-avatar-color=secondary]{background-color:var(--color-secondary-lightest);color:var(--color-on-secondary-lightest);border-color:var(--color-border-secondary-lightest)}:host ax-avatar[data-avatar-color=danger]{background-color:var(--color-danger-lightest);color:var(--color-on-danger-lightest);border-color:var(--color-border-danger-lightest)}:host ax-avatar[data-avatar-color=warning]{background-color:var(--color-warning-lightest);color:var(--color-on-warning-lightest);border-color:var(--color-border-warning-lightest)}:host ax-avatar[data-avatar-color=success]{background-color:var(--color-success-lightest);color:var(--color-on-success-lightest);border-color:var(--color-border-success-lightest)}:host ax-avatar[data-avatar-color=accent1]{background-color:var(--color-accent1-lightest);color:var(--color-on-accent1-lightest);border-color:var(--color-border-accent1-lightest)}:host ax-avatar[data-avatar-color=accent2]{background-color:var(--color-accent2-lightest);color:var(--color-on-accent2-lightest);border-color:var(--color-border-accent2-lightest)}:host ax-avatar[data-avatar-color=accent3]{background-color:var(--color-accent3-lightest);color:var(--color-on-accent3-lightest);border-color:var(--color-border-accent3-lightest)}:host ax-avatar ax-text,:host .axp-avatar__initials-wrap{display:flex;align-items:center;justify-content:center;--tw-border-style: none;border-style:none;background-color:transparent;color:inherit!important;width:100%;height:100%;line-height:1}:host .axp-avatar__initials{display:flex;align-items:center;justify-content:center;font-weight:600;line-height:1}:host ax-image{position:absolute!important;inset:0;width:100%!important;height:100%!important}:host ax-image img{display:block!important}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"], dependencies: [{ kind: "ngmodule", type: AXAvatarModule }, { kind: "component", type: i1$1.AXAvatarComponent, selector: "ax-avatar", inputs: ["color", "size", "shape", "look"], outputs: ["sizeChange"] }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i2$1.AXDecoratorGenericComponent, selector: "ax-footer, ax-header, ax-content, ax-divider, ax-form-hint, ax-prefix, ax-suffix, ax-text, ax-title, ax-subtitle, ax-placeholder, ax-overlay" }, { kind: "ngmodule", type: AXImageModule }, { kind: "component", type: i3$1.AXImageComponent, selector: "ax-image", inputs: ["width", "height", "overlayMode", "src", "alt", "priority", "lazy"], outputs: ["onLoad", "onError"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
365
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: AXPAvatarComponent, isStandalone: true, selector: "axp-avatar", inputs: { size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, src: { classPropertyName: "src", publicName: "src", isSignal: true, isRequired: false, transformFunction: null }, fullName: { classPropertyName: "fullName", publicName: "fullName", isSignal: true, isRequired: false, transformFunction: null }, showTitle: { classPropertyName: "showTitle", publicName: "showTitle", isSignal: true, isRequired: false, transformFunction: null }, fallbackText: { classPropertyName: "fallbackText", publicName: "fallbackText", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<ax-avatar\n [size]=\"size()\"\n class=\"cursor-pointer relative border\"\n [color]=\"avatarColor()\"\n [look]=\"'twotone'\"\n [attr.data-avatar-color]=\"avatarColor()\"\n [attr.title]=\"showTitle() && title() ? title() : null\"\n>\n @if (hasAvatar()) {\n <ax-image\n (onError)=\"onImageError($event)\"\n (onLoad)=\"onImageLoad($event)\"\n [src]=\"resolvedSrc()\"\n />\n } @else {\n <ax-text class=\"axp-avatar__initials-wrap\">\n <span class=\"axp-avatar__initials\" [style.font-size]=\"size() * 0.35 + 'px'\">{{\n avatarText()\n }}</span>\n </ax-text>\n }\n</ax-avatar>\n", styles: [":host{display:inline-flex;align-items:center;justify-content:center;line-height:0}:host ax-avatar{display:inline-flex!important;align-items:center;justify-content:center;line-height:0}:host ax-avatar[data-avatar-color=primary]{background-color:var(--color-primary-lightest);color:var(--color-on-primary-lightest);border-color:var(--color-border-primary-lightest)}:host ax-avatar[data-avatar-color=secondary]{background-color:var(--color-secondary-lightest);color:var(--color-on-secondary-lightest);border-color:var(--color-border-secondary-lightest)}:host ax-avatar[data-avatar-color=danger]{background-color:var(--color-danger-lightest);color:var(--color-on-danger-lightest);border-color:var(--color-border-danger-lightest)}:host ax-avatar[data-avatar-color=warning]{background-color:var(--color-warning-lightest);color:var(--color-on-warning-lightest);border-color:var(--color-border-warning-lightest)}:host ax-avatar[data-avatar-color=success]{background-color:var(--color-success-lightest);color:var(--color-on-success-lightest);border-color:var(--color-border-success-lightest)}:host ax-avatar[data-avatar-color=accent1]{background-color:var(--color-accent1-lightest);color:var(--color-on-accent1-lightest);border-color:var(--color-border-accent1-lightest)}:host ax-avatar[data-avatar-color=accent2]{background-color:var(--color-accent2-lightest);color:var(--color-on-accent2-lightest);border-color:var(--color-border-accent2-lightest)}:host ax-avatar[data-avatar-color=accent3]{background-color:var(--color-accent3-lightest);color:var(--color-on-accent3-lightest);border-color:var(--color-border-accent3-lightest)}:host ax-avatar ax-text,:host .axp-avatar__initials-wrap{display:flex;align-items:center;justify-content:center;--tw-border-style: none;border-style:none;background-color:transparent;color:inherit!important;width:100%;height:100%;line-height:1}:host .axp-avatar__initials{display:flex;align-items:center;justify-content:center;font-weight:600;line-height:1}:host ax-image{position:absolute!important;inset:0;width:100%!important;height:100%!important}:host ax-image img{display:block!important}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"], dependencies: [{ kind: "ngmodule", type: AXAvatarModule }, { kind: "component", type: i1$1.AXAvatarComponent, selector: "ax-avatar", inputs: ["color", "size", "shape", "look"], outputs: ["sizeChange"] }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i2$1.AXDecoratorGenericComponent, selector: "ax-footer, ax-header, ax-content, ax-divider, ax-form-hint, ax-prefix, ax-suffix, ax-text, ax-title, ax-subtitle, ax-placeholder, ax-overlay" }, { kind: "ngmodule", type: AXImageModule }, { kind: "component", type: i3$1.AXImageComponent, selector: "ax-image", inputs: ["width", "height", "overlayMode", "src", "alt", "priority", "lazy"], outputs: ["onLoad", "onError"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
386
366
  }
387
367
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPAvatarComponent, decorators: [{
388
368
  type: Component,
389
- args: [{ selector: 'axp-avatar', imports: [AXAvatarModule, AXDecoratorModule, AXImageModule], changeDetection: ChangeDetectionStrategy.OnPush, template: "<ax-avatar\n [size]=\"size()\"\n class=\"cursor-pointer relative border\"\n [color]=\"avatarColor()\"\n [look]=\"'twotone'\"\n [attr.data-avatar-color]=\"avatarColor()\"\n [title]=\"title()\"\n>\n @if (hasAvatar()) {\n <ax-image\n (onError)=\"onImageError($event)\"\n (onLoad)=\"onImageLoad($event)\"\n [src]=\"resolvedSrc()\"\n />\n } @else {\n <ax-text class=\"axp-avatar__initials-wrap\">\n <span class=\"axp-avatar__initials\" [style.font-size]=\"size() * 0.35 + 'px'\">{{\n avatarText()\n }}</span>\n </ax-text>\n }\n</ax-avatar>\n", styles: [":host{display:inline-flex;align-items:center;justify-content:center;line-height:0}:host ax-avatar{display:inline-flex!important;align-items:center;justify-content:center;line-height:0}:host ax-avatar[data-avatar-color=primary]{background-color:var(--color-primary-lightest);color:var(--color-on-primary-lightest);border-color:var(--color-border-primary-lightest)}:host ax-avatar[data-avatar-color=secondary]{background-color:var(--color-secondary-lightest);color:var(--color-on-secondary-lightest);border-color:var(--color-border-secondary-lightest)}:host ax-avatar[data-avatar-color=danger]{background-color:var(--color-danger-lightest);color:var(--color-on-danger-lightest);border-color:var(--color-border-danger-lightest)}:host ax-avatar[data-avatar-color=warning]{background-color:var(--color-warning-lightest);color:var(--color-on-warning-lightest);border-color:var(--color-border-warning-lightest)}:host ax-avatar[data-avatar-color=success]{background-color:var(--color-success-lightest);color:var(--color-on-success-lightest);border-color:var(--color-border-success-lightest)}:host ax-avatar[data-avatar-color=accent1]{background-color:var(--color-accent1-lightest);color:var(--color-on-accent1-lightest);border-color:var(--color-border-accent1-lightest)}:host ax-avatar[data-avatar-color=accent2]{background-color:var(--color-accent2-lightest);color:var(--color-on-accent2-lightest);border-color:var(--color-border-accent2-lightest)}:host ax-avatar[data-avatar-color=accent3]{background-color:var(--color-accent3-lightest);color:var(--color-on-accent3-lightest);border-color:var(--color-border-accent3-lightest)}:host ax-avatar ax-text,:host .axp-avatar__initials-wrap{display:flex;align-items:center;justify-content:center;--tw-border-style: none;border-style:none;background-color:transparent;color:inherit!important;width:100%;height:100%;line-height:1}:host .axp-avatar__initials{display:flex;align-items:center;justify-content:center;font-weight:600;line-height:1}:host ax-image{position:absolute!important;inset:0;width:100%!important;height:100%!important}:host ax-image img{display:block!important}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"] }]
390
- }], propDecorators: { size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], src: [{ type: i0.Input, args: [{ isSignal: true, alias: "src", required: false }] }], fullName: [{ type: i0.Input, args: [{ isSignal: true, alias: "fullName", required: false }] }], fallbackText: [{ type: i0.Input, args: [{ isSignal: true, alias: "fallbackText", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }] } });
369
+ args: [{ selector: 'axp-avatar', imports: [AXAvatarModule, AXDecoratorModule, AXImageModule], changeDetection: ChangeDetectionStrategy.OnPush, template: "<ax-avatar\n [size]=\"size()\"\n class=\"cursor-pointer relative border\"\n [color]=\"avatarColor()\"\n [look]=\"'twotone'\"\n [attr.data-avatar-color]=\"avatarColor()\"\n [attr.title]=\"showTitle() && title() ? title() : null\"\n>\n @if (hasAvatar()) {\n <ax-image\n (onError)=\"onImageError($event)\"\n (onLoad)=\"onImageLoad($event)\"\n [src]=\"resolvedSrc()\"\n />\n } @else {\n <ax-text class=\"axp-avatar__initials-wrap\">\n <span class=\"axp-avatar__initials\" [style.font-size]=\"size() * 0.35 + 'px'\">{{\n avatarText()\n }}</span>\n </ax-text>\n }\n</ax-avatar>\n", styles: [":host{display:inline-flex;align-items:center;justify-content:center;line-height:0}:host ax-avatar{display:inline-flex!important;align-items:center;justify-content:center;line-height:0}:host ax-avatar[data-avatar-color=primary]{background-color:var(--color-primary-lightest);color:var(--color-on-primary-lightest);border-color:var(--color-border-primary-lightest)}:host ax-avatar[data-avatar-color=secondary]{background-color:var(--color-secondary-lightest);color:var(--color-on-secondary-lightest);border-color:var(--color-border-secondary-lightest)}:host ax-avatar[data-avatar-color=danger]{background-color:var(--color-danger-lightest);color:var(--color-on-danger-lightest);border-color:var(--color-border-danger-lightest)}:host ax-avatar[data-avatar-color=warning]{background-color:var(--color-warning-lightest);color:var(--color-on-warning-lightest);border-color:var(--color-border-warning-lightest)}:host ax-avatar[data-avatar-color=success]{background-color:var(--color-success-lightest);color:var(--color-on-success-lightest);border-color:var(--color-border-success-lightest)}:host ax-avatar[data-avatar-color=accent1]{background-color:var(--color-accent1-lightest);color:var(--color-on-accent1-lightest);border-color:var(--color-border-accent1-lightest)}:host ax-avatar[data-avatar-color=accent2]{background-color:var(--color-accent2-lightest);color:var(--color-on-accent2-lightest);border-color:var(--color-border-accent2-lightest)}:host ax-avatar[data-avatar-color=accent3]{background-color:var(--color-accent3-lightest);color:var(--color-on-accent3-lightest);border-color:var(--color-border-accent3-lightest)}:host ax-avatar ax-text,:host .axp-avatar__initials-wrap{display:flex;align-items:center;justify-content:center;--tw-border-style: none;border-style:none;background-color:transparent;color:inherit!important;width:100%;height:100%;line-height:1}:host .axp-avatar__initials{display:flex;align-items:center;justify-content:center;font-weight:600;line-height:1}:host ax-image{position:absolute!important;inset:0;width:100%!important;height:100%!important}:host ax-image img{display:block!important}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"] }]
370
+ }], propDecorators: { size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], src: [{ type: i0.Input, args: [{ isSignal: true, alias: "src", required: false }] }], fullName: [{ type: i0.Input, args: [{ isSignal: true, alias: "fullName", required: false }] }], showTitle: [{ type: i0.Input, args: [{ isSignal: true, alias: "showTitle", required: false }] }], fallbackText: [{ type: i0.Input, args: [{ isSignal: true, alias: "fallbackText", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }] } });
391
371
 
392
372
  const AXP_TASK_BADGE_PROVIDERS = new InjectionToken('AXP_TASK_BADGE_PROVIDERS');
393
373
  class AXPTaskBadgeProvider {
@@ -1277,7 +1257,7 @@ class AXPCategoryTreeComponent {
1277
1257
  this.isLoading.set(false);
1278
1258
  }
1279
1259
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPCategoryTreeComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1280
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: AXPCategoryTreeComponent, isStandalone: true, selector: "axp-category-tree", inputs: { dataSource: { classPropertyName: "dataSource", publicName: "dataSource", isSignal: true, isRequired: true, transformFunction: null }, config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: false, transformFunction: null }, actions: { classPropertyName: "actions", publicName: "actions", isSignal: true, isRequired: false, transformFunction: null }, events: { classPropertyName: "events", publicName: "events", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { nodeClick: "nodeClick", nodeSelect: "nodeSelect", nodeCreate: "nodeCreate", nodeUpdate: "nodeUpdate", nodeDelete: "nodeDelete", searchChange: "searchChange", collapseChange: "collapseChange" }, viewQueries: [{ propertyName: "tree", first: true, predicate: ["tree"], descendants: true, isSignal: true }], ngImport: i0, template: "<axp-layout-header>\n <axp-layout-toolbar>\n @if (config().searchable) {\n <ax-search-box\n (onValueChanged)=\"handleSearchChange($event)\"\n [delayTime]=\"300\"\n [placeholder]=\"config().searchPlaceholder! | translate | async\"\n >\n </ax-search-box>\n }\n </axp-layout-toolbar>\n</axp-layout-header>\n\n<axp-layout-content>\n @if (isLoading()) {\n <div class=\"p-4 flex flex-col gap-3\" [class.pt-2]=\"config().searchable\">\n <ax-skeleton class=\"w-full h-6 rounded-md\"></ax-skeleton>\n <ax-skeleton class=\"w-full h-6 rounded-md\"></ax-skeleton>\n <ax-skeleton class=\"w-full h-6 rounded-md\"></ax-skeleton>\n <ax-skeleton class=\"w-full h-6 rounded-md\"></ax-skeleton>\n <ax-skeleton class=\"w-full h-6 rounded-md\"></ax-skeleton>\n <ax-skeleton class=\"w-full h-6 rounded-md\"></ax-skeleton>\n </div>\n } @else if (treeItems()[0].children?.length) {\n <div\n class=\"px-4 flex-1 min-h-0 min-w-0 overflow-y-auto overflow-x-hidden\"\n [class.pt-2]=\"config().searchable\"\n >\n <ax-tree-view\n [datasource]=\"datasource\"\n [selectMode]=\"config().showCheckbox ? 'multiple' : 'none'\"\n [dragBehavior]=\"'none'\"\n [showIcons]=\"false\"\n [showChildrenBadge]=\"false\"\n (onNodeClick)=\"handleNodeClick($event)\"\n (onNodeToggle)=\"handleNodeToggle($event)\"\n [nodeTemplate]=\"itemTemplate\"\n [titleField]=\"config().textField || 'title'\"\n [idField]=\"config().valueField || 'id'\"\n [expandedField]=\"config().expandedField || 'expand'\"\n #tree\n >\n </ax-tree-view>\n </div>\n } @else {\n <axp-state-message\n [icon]=\"config().emptyStateIcon || 'fa-light fa-folder-open'\"\n [title]=\"emptyStateTitle()\"\n [titleParams]=\"emptyStateTitleParams()\"\n [description]=\"emptyStateDescription()\"\n >\n @if (actions().canCreate) {\n <ax-button\n slot=\"actions\"\n (onClick)=\"handleCreateRootClick($event)\"\n look=\"solid\"\n color=\"primary\"\n [text]=\"\n (actions().createLabel || '@general:actions.add-new.title'\n | translate\n | async)!\n \"\n >\n <ax-icon class=\"fas fa-plus\"></ax-icon>\n </ax-button>\n }\n </axp-state-message>\n }\n\n <ng-template #itemTemplate let-node=\"node\">\n @let item = node;\n @let textField = config().textField || 'title';\n @let rawTitle = item[textField] ?? item.title;\n <div class=\"flex items-center justify-between w-full gap-2 overflow-hidden\">\n <div class=\"flex items-center gap-2 min-w-0\">\n <ax-icon class=\"fas text-warning fa-folder\"></ax-icon>\n <span class=\"truncate\">\n @if (item.id === 'root') {\n {{ categoryTreeRootTitleI18nKey | translate | async }}\n } @else {\n {{ rawTitle | translate | async }}\n }\n </span>\n </div>\n @if (item.id && item.id !== 'root') {\n @if (\n actions().canCreateChild || actions().canUpdate || actions().canDelete\n ) {\n <div class=\"flex items-center gap-1\">\n <ax-button\n class=\"ax-xs\"\n color=\"default\"\n look=\"none\"\n (onClick)=\"$event.nativeEvent.stopPropagation()\"\n >\n <ax-icon class=\"fas fa-ellipsis-v\"></ax-icon>\n <ax-dropdown-panel>\n <ax-button-item-list>\n @if (actions().canCreateChild) {\n <ax-button-item\n (onClick)=\"handleCreateChildClick(item, $event)\"\n look=\"blank\"\n color=\"default\"\n [text]=\"\n (actions().createChildLabel ||\n '@general:actions.add-new-child.title'\n | translate\n | async)!\n \"\n >\n <ax-icon class=\"fas fa-plus\"></ax-icon>\n </ax-button-item>\n }\n @if (actions().canUpdate) {\n <ax-button-item\n (onClick)=\"handleUpdateNodeClick(item, $event)\"\n look=\"blank\"\n [text]=\"\n (actions().updateLabel || '@general:actions.edit.title'\n | translate\n | async)!\n \"\n >\n <ax-icon class=\"fas fa-pen\"></ax-icon>\n </ax-button-item>\n }\n @if (actions().canDelete) {\n <ax-button-item\n (onClick)=\"handleDeleteNodeClick(item, $event)\"\n color=\"danger\"\n look=\"blank\"\n [text]=\"\n (actions().deleteLabel ||\n '@general:actions.delete.title'\n | translate\n | async)!\n \"\n >\n <ax-icon class=\"fas fa-trash\"></ax-icon>\n </ax-button-item>\n }\n </ax-button-item-list>\n </ax-dropdown-panel>\n </ax-button>\n </div>\n }\n } @else if (item.id === 'root' && actions().canCreate) {\n <div class=\"flex items-center gap-1\">\n <ax-button\n class=\"ax-sm\"\n (onClick)=\"handleCreateRootClick($event)\"\n look=\"blank\"\n color=\"default\"\n >\n <ax-icon class=\"fas fa-plus\"></ax-icon>\n </ax-button>\n </div>\n }\n </div>\n </ng-template>\n</axp-layout-content>\n", styles: [":host{display:block;height:100%;width:100%}:host axp-layout-content{display:flex;min-height:0px;min-width:0px;flex:1;flex-direction:column;overflow:hidden}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i2$1.AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { kind: "component", type: AXTreeViewComponent, selector: "ax-tree-view", inputs: ["datasource", "selectMode", "selectionBehavior", "dragArea", "dragBehavior", "showIcons", "showChildrenBadge", "expandedIcon", "collapsedIcon", "indentSize", "look", "nodeTemplate", "idField", "titleField", "tooltipField", "iconField", "expandedField", "selectedField", "indeterminateField", "disabledField", "hiddenField", "childrenField", "childrenCountField", "dataField", "inheritDisabled", "expandOnDoubleClick", "doubleClickDuration", "tooltipDelay", "controlledSelection", "selectedIds"], outputs: ["datasourceChange", "selectedIdsChange", "onBeforeDrop", "onNodeToggle", "onNodeSelect", "onNodeDoubleClick", "onNodeClick", "onSelectionChange", "onOrderChange", "onMoveChange", "onItemsChange"] }, { kind: "ngmodule", type: AXSkeletonModule }, { kind: "component", type: i2.AXSkeletonComponent, selector: "ax-skeleton", inputs: ["animated"] }, { kind: "component", type: AXPThemeLayoutBlockComponent, selector: "\n\n axp-page-content, \n axp-page-footer-container,\n axp-page-footer,\n axp-page-header,\n axp-page-header-container,\n axp-page-toolbar,\n\n axp-layout-content, \n axp-layout-page-content, \n\n axp-layout-sections,\n axp-layout-body,\n axp-layout-page-body,\n axp-layout-prefix,\n axp-layout-suffix,\n axp-layout-title-bar,\n axp-layout-title, \n axp-layout-title-actions, \n axp-layout-nav-button, \n axp-layout-description, \n axp-layout-breadcrumbs,\n axp-layout-list-action,\n " }, { kind: "ngmodule", type: AXSearchBoxModule }, { kind: "component", type: i5.AXSearchBoxComponent, selector: "ax-search-box", inputs: ["disabled", "readonly", "tabIndex", "placeholder", "value", "state", "name", "id", "look", "class", "delayTime", "type", "autoSearch"], outputs: ["valueChange", "stateChange", "onValueChanged", "onBlur", "onFocus", "readonlyChange", "disabledChange", "onKeyDown", "onKeyUp", "onKeyPress"] }, { kind: "component", type: AXPThemeLayoutHeaderComponent, selector: "axp-layout-header" }, { kind: "component", type: AXPThemeLayoutToolbarComponent, selector: "axp-layout-toolbar" }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "ngmodule", type: AXButtonModule }, { kind: "component", type: i1$2.AXButtonComponent, selector: "ax-button", inputs: ["disabled", "size", "tabIndex", "color", "look", "text", "toggleable", "selected", "iconOnly", "type", "loadingText"], outputs: ["onBlur", "onFocus", "onClick", "selectedChange", "toggleableChange", "lookChange", "colorChange", "disabledChange", "loadingTextChange"] }, { kind: "component", type: i1$2.AXButtonItemComponent, selector: "ax-button-item", inputs: ["color", "disabled", "text", "selected", "divided", "data", "name"], outputs: ["onClick", "onFocus", "onBlur", "disabledChange"] }, { kind: "component", type: i1$2.AXButtonItemListComponent, selector: "ax-button-item-list", inputs: ["items", "closeParentOnClick", "lockOnLoading"], outputs: ["onItemClick"] }, { kind: "ngmodule", type: AXDropdownModule }, { kind: "component", type: i5$1.AXDropdownPanelComponent, selector: "ax-dropdown-panel", inputs: ["isOpen", "fitParent", "dropdownWidth", "position", "placement", "_target", "adaptivityEnabled"], outputs: ["onOpened", "onClosed"] }, { kind: "component", type: AXPStateMessageComponent, selector: "axp-state-message", inputs: ["mode", "icon", "title", "description", "titleParams", "descriptionParams", "look"] }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }, { kind: "pipe", type: i3.AXTranslatorPipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.Eager, encapsulation: i0.ViewEncapsulation.None }); }
1260
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: AXPCategoryTreeComponent, isStandalone: true, selector: "axp-category-tree", inputs: { dataSource: { classPropertyName: "dataSource", publicName: "dataSource", isSignal: true, isRequired: true, transformFunction: null }, config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: false, transformFunction: null }, actions: { classPropertyName: "actions", publicName: "actions", isSignal: true, isRequired: false, transformFunction: null }, events: { classPropertyName: "events", publicName: "events", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { nodeClick: "nodeClick", nodeSelect: "nodeSelect", nodeCreate: "nodeCreate", nodeUpdate: "nodeUpdate", nodeDelete: "nodeDelete", searchChange: "searchChange", collapseChange: "collapseChange" }, viewQueries: [{ propertyName: "tree", first: true, predicate: ["tree"], descendants: true, isSignal: true }], ngImport: i0, template: "<axp-layout-header>\n <axp-layout-toolbar>\n @if (config().searchable) {\n <ax-search-box\n (onValueChanged)=\"handleSearchChange($event)\"\n [delayTime]=\"300\"\n [placeholder]=\"config().searchPlaceholder! | translate | async\"\n >\n </ax-search-box>\n }\n </axp-layout-toolbar>\n</axp-layout-header>\n\n<axp-layout-content>\n @if (isLoading()) {\n <div class=\"p-4 flex flex-col gap-3\" [class.pt-2]=\"config().searchable\">\n <ax-skeleton class=\"w-full h-6 rounded-md\"></ax-skeleton>\n <ax-skeleton class=\"w-full h-6 rounded-md\"></ax-skeleton>\n <ax-skeleton class=\"w-full h-6 rounded-md\"></ax-skeleton>\n <ax-skeleton class=\"w-full h-6 rounded-md\"></ax-skeleton>\n <ax-skeleton class=\"w-full h-6 rounded-md\"></ax-skeleton>\n <ax-skeleton class=\"w-full h-6 rounded-md\"></ax-skeleton>\n </div>\n } @else if (treeItems()[0].children?.length) {\n <div\n class=\"px-4 flex-1 min-h-0 min-w-0 overflow-y-auto overflow-x-hidden\"\n [class.pt-2]=\"config().searchable\"\n >\n <ax-tree-view\n [datasource]=\"datasource\"\n [selectMode]=\"config().showCheckbox ? 'multiple' : 'none'\"\n [dragBehavior]=\"'none'\"\n [showIcons]=\"false\"\n [showChildrenBadge]=\"false\"\n (onNodeClick)=\"handleNodeClick($event)\"\n (onNodeToggle)=\"handleNodeToggle($event)\"\n [nodeTemplate]=\"itemTemplate\"\n [titleField]=\"config().textField || 'title'\"\n [idField]=\"config().valueField || 'id'\"\n [expandedField]=\"config().expandedField || 'expand'\"\n #tree\n >\n </ax-tree-view>\n </div>\n } @else {\n <axp-state-message\n [icon]=\"config().emptyStateIcon || 'fa-light fa-folder-open'\"\n [title]=\"emptyStateTitle()\"\n [titleParams]=\"emptyStateTitleParams()\"\n [description]=\"emptyStateDescription()\"\n >\n @if (actions().canCreate) {\n <ax-button\n slot=\"actions\"\n (onClick)=\"handleCreateRootClick($event)\"\n look=\"solid\"\n color=\"primary\"\n [text]=\"\n (actions().createLabel || '@general:actions.add-new.title'\n | translate\n | async)!\n \"\n >\n <ax-icon class=\"fas fa-plus\"></ax-icon>\n </ax-button>\n }\n </axp-state-message>\n }\n\n <ng-template #itemTemplate let-node=\"node\">\n @let item = node;\n @let textField = config().textField || 'title';\n @let rawTitle = item[textField] ?? item.title;\n <div class=\"flex items-center justify-between w-full gap-2 overflow-hidden\">\n <div class=\"flex items-center gap-2 min-w-0\">\n <ax-icon class=\"fas text-warning fa-folder\"></ax-icon>\n <span class=\"truncate\">\n @if (item.id === 'root') {\n {{ categoryTreeRootTitleI18nKey | translate | async }}\n } @else {\n {{ rawTitle | translate | async }}\n }\n </span>\n </div>\n @if (item.id && item.id !== 'root') {\n @if (\n actions().canCreateChild || actions().canUpdate || actions().canDelete\n ) {\n <div class=\"flex items-center gap-1\">\n <ax-button\n class=\"ax-xs\"\n color=\"default\"\n look=\"none\"\n (onClick)=\"$event.nativeEvent.stopPropagation()\"\n >\n <ax-icon class=\"fas fa-ellipsis-v\"></ax-icon>\n <ax-dropdown-panel>\n <ax-button-item-list>\n @if (actions().canCreateChild) {\n <ax-button-item\n (onClick)=\"handleCreateChildClick(item, $event)\"\n look=\"blank\"\n color=\"default\"\n [text]=\"\n (actions().createChildLabel ||\n '@general:actions.add-new-child.title'\n | translate\n | async)!\n \"\n >\n <ax-icon class=\"fas fa-plus\"></ax-icon>\n </ax-button-item>\n }\n @if (actions().canUpdate) {\n <ax-button-item\n (onClick)=\"handleUpdateNodeClick(item, $event)\"\n look=\"blank\"\n [text]=\"\n (actions().updateLabel || '@general:actions.edit.title'\n | translate\n | async)!\n \"\n >\n <ax-icon class=\"fas fa-pen\"></ax-icon>\n </ax-button-item>\n }\n @if (actions().canDelete) {\n <ax-button-item\n (onClick)=\"handleDeleteNodeClick(item, $event)\"\n color=\"danger\"\n look=\"blank\"\n [text]=\"\n (actions().deleteLabel ||\n '@general:actions.delete.title'\n | translate\n | async)!\n \"\n >\n <ax-icon class=\"fas fa-trash\"></ax-icon>\n </ax-button-item>\n }\n </ax-button-item-list>\n </ax-dropdown-panel>\n </ax-button>\n </div>\n }\n } @else if (item.id === 'root' && actions().canCreate) {\n <div class=\"flex items-center gap-1\">\n <ax-button\n class=\"ax-sm\"\n (onClick)=\"handleCreateRootClick($event)\"\n look=\"blank\"\n color=\"default\"\n >\n <ax-icon class=\"fas fa-plus\"></ax-icon>\n </ax-button>\n </div>\n }\n </div>\n </ng-template>\n</axp-layout-content>\n", styles: [":host{display:block;height:100%;width:100%}:host axp-layout-content{display:flex;min-height:0px;min-width:0px;flex:1;flex-direction:column;overflow:hidden}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i2$1.AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { kind: "component", type: AXTreeViewComponent, selector: "ax-tree-view", inputs: ["datasource", "selectMode", "selectionBehavior", "dragArea", "dragBehavior", "showIcons", "showChildrenBadge", "expandedIcon", "collapsedIcon", "indentSize", "look", "alternate", "nodeTemplate", "idField", "titleField", "tooltipField", "iconField", "expandedField", "selectedField", "indeterminateField", "disabledField", "hiddenField", "childrenField", "childrenCountField", "dataField", "inheritDisabled", "expandOnDoubleClick", "doubleClickDuration", "tooltipDelay", "controlledSelection", "selectedIds"], outputs: ["datasourceChange", "selectedIdsChange", "onBeforeDrop", "onNodeToggle", "onNodeSelect", "onNodeDoubleClick", "onNodeClick", "onSelectionChange", "onOrderChange", "onMoveChange", "onItemsChange"] }, { kind: "ngmodule", type: AXSkeletonModule }, { kind: "component", type: i2.AXSkeletonComponent, selector: "ax-skeleton", inputs: ["animated"] }, { kind: "component", type: AXPThemeLayoutBlockComponent, selector: "\n\n axp-page-content, \n axp-page-footer-container,\n axp-page-footer,\n axp-page-header,\n axp-page-header-container,\n axp-page-toolbar,\n\n axp-layout-content, \n axp-layout-page-content, \n\n axp-layout-sections,\n axp-layout-body,\n axp-layout-page-body,\n axp-layout-prefix,\n axp-layout-suffix,\n axp-layout-title-bar,\n axp-layout-title, \n axp-layout-title-actions, \n axp-layout-nav-button, \n axp-layout-description, \n axp-layout-breadcrumbs,\n axp-layout-list-action,\n " }, { kind: "ngmodule", type: AXSearchBoxModule }, { kind: "component", type: i5.AXSearchBoxComponent, selector: "ax-search-box", inputs: ["disabled", "readonly", "tabIndex", "placeholder", "value", "state", "name", "id", "look", "class", "delayTime", "type", "autoSearch"], outputs: ["valueChange", "stateChange", "onValueChanged", "onBlur", "onFocus", "readonlyChange", "disabledChange", "onKeyDown", "onKeyUp", "onKeyPress"] }, { kind: "component", type: AXPThemeLayoutHeaderComponent, selector: "axp-layout-header" }, { kind: "component", type: AXPThemeLayoutToolbarComponent, selector: "axp-layout-toolbar" }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "ngmodule", type: AXButtonModule }, { kind: "component", type: i1$2.AXButtonComponent, selector: "ax-button", inputs: ["disabled", "size", "tabIndex", "color", "look", "text", "toggleable", "selected", "iconOnly", "type", "loadingText"], outputs: ["onBlur", "onFocus", "onClick", "selectedChange", "toggleableChange", "lookChange", "colorChange", "disabledChange", "loadingTextChange"] }, { kind: "component", type: i1$2.AXButtonItemComponent, selector: "ax-button-item", inputs: ["color", "disabled", "text", "selected", "divided", "data", "name"], outputs: ["onClick", "onFocus", "onBlur", "disabledChange"] }, { kind: "component", type: i1$2.AXButtonItemListComponent, selector: "ax-button-item-list", inputs: ["items", "closeParentOnClick", "lockOnLoading"], outputs: ["onItemClick"] }, { kind: "ngmodule", type: AXDropdownModule }, { kind: "component", type: i5$1.AXDropdownPanelComponent, selector: "ax-dropdown-panel", inputs: ["isOpen", "fitParent", "dropdownWidth", "position", "placement", "_target", "adaptivityEnabled"], outputs: ["onOpened", "onClosed"] }, { kind: "component", type: AXPStateMessageComponent, selector: "axp-state-message", inputs: ["mode", "icon", "title", "description", "titleParams", "descriptionParams", "look"] }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }, { kind: "pipe", type: i3.AXTranslatorPipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.Eager, encapsulation: i0.ViewEncapsulation.None }); }
1281
1261
  }
1282
1262
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPCategoryTreeComponent, decorators: [{
1283
1263
  type: Component,
@@ -1300,6 +1280,151 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
1300
1280
  //#region ---- Tree Node Interface ----
1301
1281
  //#endregion
1302
1282
 
1283
+ //#region ----- Imports -----
1284
+ //#endregion
1285
+ //#region ----- Constants -----
1286
+ const POPOVER_MIN_WIDTH_PX = 288;
1287
+ //#endregion
1288
+ //#region ----- Component -----
1289
+ class AXPColorChooserComponent {
1290
+ //#endregion
1291
+ //#region ----- Lifecycle -----
1292
+ constructor() {
1293
+ //#region ----- Services & Dependencies -----
1294
+ this.host = inject((ElementRef));
1295
+ this.paletteDropdown = viewChild('paletteDropdown', /* @ts-ignore */
1296
+ ...(ngDevMode ? [{ debugName: "paletteDropdown" }] : /* istanbul ignore next */ []));
1297
+ //#endregion
1298
+ //#region ----- Inputs -----
1299
+ this.groups = input([], /* @ts-ignore */
1300
+ ...(ngDevMode ? [{ debugName: "groups" }] : /* istanbul ignore next */ []));
1301
+ this.selectedClass = input(/* @ts-ignore */
1302
+ ...(ngDevMode ? [undefined, { debugName: "selectedClass" }] : /* istanbul ignore next */ []));
1303
+ this.look = input('strip', /* @ts-ignore */
1304
+ ...(ngDevMode ? [{ debugName: "look" }] : /* istanbul ignore next */ []));
1305
+ this.disabled = input(false, /* @ts-ignore */
1306
+ ...(ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []));
1307
+ this.readonly = input(false, /* @ts-ignore */
1308
+ ...(ngDevMode ? [{ debugName: "readonly" }] : /* istanbul ignore next */ []));
1309
+ this.allowClear = input(true, /* @ts-ignore */
1310
+ ...(ngDevMode ? [{ debugName: "allowClear" }] : /* istanbul ignore next */ []));
1311
+ //#endregion
1312
+ //#region ----- Outputs -----
1313
+ this.classSelected = output();
1314
+ //#endregion
1315
+ //#region ----- Computed Properties -----
1316
+ this.isInteractive = computed(() => !this.disabled() && !this.readonly(), /* @ts-ignore */
1317
+ ...(ngDevMode ? [{ debugName: "isInteractive" }] : /* istanbul ignore next */ []));
1318
+ this.resolvedGroups = computed(() => this.groups().filter((group) => group.swatches.length > 0), /* @ts-ignore */
1319
+ ...(ngDevMode ? [{ debugName: "resolvedGroups" }] : /* istanbul ignore next */ []));
1320
+ this.usePopover = computed(() => this.resolvedGroups().length > 1, /* @ts-ignore */
1321
+ ...(ngDevMode ? [{ debugName: "usePopover" }] : /* istanbul ignore next */ []));
1322
+ this.pendingSelected = signal(undefined, /* @ts-ignore */
1323
+ ...(ngDevMode ? [{ debugName: "pendingSelected" }] : /* istanbul ignore next */ []));
1324
+ this.effectiveSelected = computed(() => {
1325
+ const pending = this.pendingSelected();
1326
+ return pending !== undefined ? pending : this.selectedClass();
1327
+ }, /* @ts-ignore */
1328
+ ...(ngDevMode ? [{ debugName: "effectiveSelected" }] : /* istanbul ignore next */ []));
1329
+ this.selectedSwatch = computed(() => {
1330
+ const selected = resolveToSurfaceClass(this.effectiveSelected() ?? undefined);
1331
+ if (!selected) {
1332
+ return undefined;
1333
+ }
1334
+ for (const group of this.resolvedGroups()) {
1335
+ const swatch = group.swatches.find((item) => resolveToSurfaceClass(item.className) === selected);
1336
+ if (swatch) {
1337
+ return swatch;
1338
+ }
1339
+ }
1340
+ return undefined;
1341
+ }, /* @ts-ignore */
1342
+ ...(ngDevMode ? [{ debugName: "selectedSwatch" }] : /* istanbul ignore next */ []));
1343
+ this.selectedGroup = computed(() => {
1344
+ const swatch = this.selectedSwatch();
1345
+ if (!swatch) {
1346
+ return undefined;
1347
+ }
1348
+ return this.resolvedGroups().find((group) => group.swatches.some((item) => item.className === swatch.className));
1349
+ }, /* @ts-ignore */
1350
+ ...(ngDevMode ? [{ debugName: "selectedGroup" }] : /* istanbul ignore next */ []));
1351
+ this.hasSelection = computed(() => Boolean(this.selectedSwatch() || this.effectiveSelected()), /* @ts-ignore */
1352
+ ...(ngDevMode ? [{ debugName: "hasSelection" }] : /* istanbul ignore next */ []));
1353
+ this.dropdownWidth = signal(`${POPOVER_MIN_WIDTH_PX}px`, /* @ts-ignore */
1354
+ ...(ngDevMode ? [{ debugName: "dropdownWidth" }] : /* istanbul ignore next */ []));
1355
+ this.dropdownOpen = signal(false, /* @ts-ignore */
1356
+ ...(ngDevMode ? [{ debugName: "dropdownOpen" }] : /* istanbul ignore next */ []));
1357
+ effect(() => {
1358
+ const classNames = this.groups().flatMap((group) => group.swatches.map((swatch) => swatch.className));
1359
+ ensureRuntimeSurfaceClasses(classNames);
1360
+ ensureRuntimeSurfaceClasses([this.selectedClass(), this.pendingSelected()]);
1361
+ });
1362
+ effect(() => {
1363
+ this.selectedClass();
1364
+ this.pendingSelected.set(undefined);
1365
+ });
1366
+ afterNextRender(() => this.syncDropdownWidth());
1367
+ }
1368
+ //#endregion
1369
+ //#region ----- Event Handlers -----
1370
+ handleSelect(swatch) {
1371
+ if (!this.isInteractive()) {
1372
+ return;
1373
+ }
1374
+ this.pendingSelected.set(swatch.className);
1375
+ this.classSelected.emit(swatch.className);
1376
+ this.paletteDropdown()?.close();
1377
+ }
1378
+ handleClear(event) {
1379
+ event?.preventDefault();
1380
+ event?.stopPropagation();
1381
+ if (!this.isInteractive()) {
1382
+ return;
1383
+ }
1384
+ this.pendingSelected.set(null);
1385
+ this.classSelected.emit(null);
1386
+ this.paletteDropdown()?.close();
1387
+ }
1388
+ hostClickListener() {
1389
+ if (!this.usePopover() || !this.isInteractive()) {
1390
+ return;
1391
+ }
1392
+ this.syncDropdownWidth();
1393
+ this.paletteDropdown()?.toggle();
1394
+ }
1395
+ handleDropdownOpened() {
1396
+ this.syncDropdownWidth();
1397
+ this.dropdownOpen.set(true);
1398
+ }
1399
+ handleDropdownClosed() {
1400
+ this.dropdownOpen.set(false);
1401
+ }
1402
+ isSelected(className) {
1403
+ const selected = resolveToSurfaceClass(this.effectiveSelected() ?? undefined);
1404
+ const candidate = resolveToSurfaceClass(className ?? undefined);
1405
+ return Boolean(selected) && selected === candidate;
1406
+ }
1407
+ displayLabel(label) {
1408
+ return label.startsWith('#') ? label.slice(1).toUpperCase() : label;
1409
+ }
1410
+ syncDropdownWidth() {
1411
+ const hostWidth = Math.round(this.host.nativeElement.getBoundingClientRect().width);
1412
+ this.dropdownWidth.set(`${Math.max(hostWidth, POPOVER_MIN_WIDTH_PX)}px`);
1413
+ }
1414
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPColorChooserComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1415
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: AXPColorChooserComponent, isStandalone: true, selector: "axp-color-chooser", inputs: { groups: { classPropertyName: "groups", publicName: "groups", isSignal: true, isRequired: false, transformFunction: null }, selectedClass: { classPropertyName: "selectedClass", publicName: "selectedClass", isSignal: true, isRequired: false, transformFunction: null }, look: { classPropertyName: "look", publicName: "look", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, readonly: { classPropertyName: "readonly", publicName: "readonly", isSignal: true, isRequired: false, transformFunction: null }, allowClear: { classPropertyName: "allowClear", publicName: "allowClear", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { classSelected: "classSelected" }, host: { listeners: { "click": "hostClickListener()" }, classAttribute: "axp-color-chooser" }, viewQueries: [{ propertyName: "paletteDropdown", first: true, predicate: ["paletteDropdown"], descendants: true, isSignal: true }], ngImport: i0, template: "<div class=\"__root\" [class.__disabled]=\"disabled()\" [class.__readonly]=\"readonly()\">\n @if (usePopover()) {\n <!-- ----- Same shell as ax-select-box: dropdown-box + input slot + panel ----- -->\n <ax-dropdown-box\n #paletteDropdown\n [disabled]=\"disabled()\"\n [popoverWidth]=\"dropdownWidth()\"\n (onOpened)=\"handleDropdownOpened()\"\n (onClosed)=\"handleDropdownClosed()\"\n >\n <ng-container input>\n <div class=\"ax-editor ax-content ax-input\">\n <ng-container *ngTemplateOutlet=\"selectedItem\"></ng-container>\n </div>\n @if (allowClear() && hasSelection() && isInteractive()) {\n <button\n type=\"button\"\n class=\"ax-general-button-icon\"\n tabindex=\"-1\"\n (click)=\"handleClear($event)\"\n >\n <span class=\"ax-icon ax-icon-close\"></span>\n </button>\n }\n <button type=\"button\" class=\"ax-general-button-icon\" [disabled]=\"!isInteractive()\" tabindex=\"-1\">\n <span\n class=\"ax-icon\"\n [class.ax-icon-chevron-down]=\"!dropdownOpen()\"\n [class.ax-icon-chevron-up]=\"dropdownOpen()\"\n ></span>\n </button>\n </ng-container>\n <ng-container panel>\n <div class=\"__popover\" [style.min-width]=\"dropdownWidth()\">\n <ng-container *ngTemplateOutlet=\"paletteGroups; context: { showTitles: true }\"></ng-container>\n </div>\n </ng-container>\n </ax-dropdown-box>\n }\n <!-- ----- Single named row stays inline at select height ----- -->\n @else {\n <ng-container *ngTemplateOutlet=\"paletteGroups; context: { showTitles: false }\"></ng-container>\n <!-- ----- Clear under the single inline strip ----- -->\n @if (allowClear()) {\n <button\n type=\"button\"\n class=\"__clear\"\n [class.__selected]=\"selectedClass() == null\"\n [disabled]=\"!isInteractive()\"\n (click)=\"handleClear($event)\"\n >\n <span class=\"ax-icon ax-icon-close\"></span>\n </button>\n }\n }\n</div>\n\n<ng-template #selectedItem>\n @if (selectedSwatch(); as swatch) {\n <!-- ----- Selected value as a surface-colored pill ----- -->\n <div class=\"__selected-item {{ swatch.className }}\">\n <span class=\"__selected-text\">\n <!-- ----- Group title before the selected variant ----- -->\n @if (selectedGroup()?.title; as groupTitle) {\n {{ groupTitle | translate | async }}\n <span class=\"__trigger-sep\">\u00B7</span>\n }\n {{ displayLabel(swatch.label) | translate | async }}\n </span>\n </div>\n }\n <!-- ----- Empty state uses the same control height as a select ----- -->\n @else {\n <div class=\"ax-placeholder\">\n {{ '@platform-layout-widgets:widgets.color-chooser.placeholder' | translate | async }}\n </div>\n }\n</ng-template>\n\n<ng-template #paletteGroups let-showTitles=\"showTitles\">\n <div class=\"__groups\" [class.__look-strip]=\"look() === 'strip'\" [class.__look-swatches]=\"look() === 'swatches'\">\n @for (group of resolvedGroups(); track group.id) {\n <div class=\"__group\">\n <!-- ----- Named row title inside the dropdown list ----- -->\n @if (showTitles && group.title) {\n <div class=\"__group-title\">{{ group.title | translate | async }}</div>\n }\n <!-- ----- Coolors bar: thin columns, hover expands and shows the label ----- -->\n <div class=\"__strip\" role=\"listbox\">\n @for (swatch of group.swatches; track swatch.className) {\n <button\n type=\"button\"\n class=\"__column {{ swatch.className }}\"\n [class.__selected]=\"isSelected(swatch.className)\"\n [disabled]=\"!isInteractive()\"\n [attr.aria-label]=\"displayLabel(swatch.label)\"\n [attr.aria-selected]=\"isSelected(swatch.className)\"\n (click)=\"handleSelect(swatch)\"\n >\n <span class=\"__label\">{{ displayLabel(swatch.label) | translate | async }}</span>\n </button>\n }\n </div>\n </div>\n }\n </div>\n</ng-template>\n", styles: [":host{display:block;min-height:var(--ax-sys-size-base, 2.5rem);width:100%}:host ax-dropdown-box{width:100%}:host .ax-editor-container{padding-block:0}:host .ax-content{display:flex;min-height:var(--ax-sys-size-base, 2.5rem);min-width:0;flex:1;cursor:pointer;align-items:center;outline:none;-webkit-user-select:none;user-select:none}.__root{display:flex;flex-direction:column;gap:.5rem}.__selected-item{display:inline-flex;align-items:center;max-width:100%;min-height:1.5rem;padding-inline:.5rem;border-radius:.375rem}.__selected-text{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.__placeholder{opacity:.65}.__trigger-sep{margin-inline:.25rem}.__popover{box-sizing:border-box;width:100%;max-height:min(24rem,70vh);overflow:auto;padding:.75rem}.__groups{display:flex;flex-direction:column;gap:.75rem;min-width:0}.__group-title{font-size:.75rem;font-weight:500;color:rgb(var(--ax-sys-color-on-lighter-surface))}.__strip{display:flex;flex-wrap:nowrap;align-items:stretch;width:100%;height:var(--ax-sys-size-base, 2.5rem);overflow:hidden;border-radius:.5rem}.__column{position:relative;flex:1 1 0;min-width:0;margin:0;padding:0;border:0;border-radius:0;appearance:none;cursor:pointer;transition:flex .22s ease}.__label{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;pointer-events:none;font-size:var(--ax-sys-text-xs-base, .75rem);font-weight:600;letter-spacing:.04em;white-space:nowrap;opacity:0;transition:opacity .16s ease}.__look-strip .__column.__selected,.__look-strip .__column:hover:not(:disabled),.__look-strip .__column:focus-visible:not(:disabled){flex:4 1 0}.__look-strip .__column.__selected .__label,.__look-strip .__column:hover:not(:disabled) .__label,.__look-strip .__column:focus-visible:not(:disabled) .__label{opacity:1}.__look-strip .__strip:has(.__column:hover:not(.__selected)) .__column.__selected:not(:hover),.__look-strip .__strip:has(.__column:focus-visible:not(.__selected)) .__column.__selected:not(:focus-visible){flex:1 1 0}.__look-strip .__strip:has(.__column:hover:not(.__selected)) .__column.__selected:not(:hover) .__label,.__look-strip .__strip:has(.__column:focus-visible:not(.__selected)) .__column.__selected:not(:focus-visible) .__label{opacity:0}.__column.__selected{box-shadow:inset 0 0 0 2px rgb(var(--ax-sys-color-on-lighter-surface) / .4)}.__column:disabled{cursor:not-allowed}.__clear{align-self:flex-start;display:inline-flex;height:1.75rem;width:1.75rem;align-items:center;justify-content:center;border-radius:999px;border:1px dashed rgb(var(--ax-sys-color-border-lighter-surface));background:rgb(var(--ax-sys-color-lighter-surface));color:rgb(var(--ax-sys-color-on-lighter-surface));font-size:.75rem}.__clear.__selected,.__clear:focus-visible:not(:disabled){outline:2px solid rgb(var(--ax-sys-color-primary));outline-offset:2px}.__clear:disabled{cursor:not-allowed;opacity:.5}.__look-swatches .__strip{height:auto;flex-wrap:wrap;gap:.25rem;overflow:visible;border-radius:0}.__look-swatches .__column{flex:0 0 2rem;width:2rem;height:2rem;min-width:2rem;border-radius:.375rem;transition:transform .16s ease}.__look-swatches .__label{display:none}.__look-swatches .__column:hover:not(:disabled),.__look-swatches .__column:focus-visible:not(:disabled){flex:0 0 2rem;transform:scale(1.08)}.__disabled .__column,.__readonly .__column,.__disabled .__clear,.__readonly .__clear,.__disabled .ax-content,.__readonly .ax-content{cursor:default}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "ngmodule", type: AXDropdownModule }, { kind: "component", type: i5$1.AXDropdownBoxComponent, selector: "ax-dropdown-box", inputs: ["disabled", "look", "hasInput", "popoverWidth"], outputs: ["disabledChange", "onBlur", "onFocus", "onClick", "onOpened", "onClosed"] }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }, { kind: "pipe", type: i3.AXTranslatorPipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1416
+ }
1417
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPColorChooserComponent, decorators: [{
1418
+ type: Component,
1419
+ args: [{ selector: 'axp-color-chooser', changeDetection: ChangeDetectionStrategy.OnPush, imports: [CommonModule, AXTranslationModule, AXDropdownModule], host: {
1420
+ class: 'axp-color-chooser',
1421
+ '(click)': 'hostClickListener()',
1422
+ }, template: "<div class=\"__root\" [class.__disabled]=\"disabled()\" [class.__readonly]=\"readonly()\">\n @if (usePopover()) {\n <!-- ----- Same shell as ax-select-box: dropdown-box + input slot + panel ----- -->\n <ax-dropdown-box\n #paletteDropdown\n [disabled]=\"disabled()\"\n [popoverWidth]=\"dropdownWidth()\"\n (onOpened)=\"handleDropdownOpened()\"\n (onClosed)=\"handleDropdownClosed()\"\n >\n <ng-container input>\n <div class=\"ax-editor ax-content ax-input\">\n <ng-container *ngTemplateOutlet=\"selectedItem\"></ng-container>\n </div>\n @if (allowClear() && hasSelection() && isInteractive()) {\n <button\n type=\"button\"\n class=\"ax-general-button-icon\"\n tabindex=\"-1\"\n (click)=\"handleClear($event)\"\n >\n <span class=\"ax-icon ax-icon-close\"></span>\n </button>\n }\n <button type=\"button\" class=\"ax-general-button-icon\" [disabled]=\"!isInteractive()\" tabindex=\"-1\">\n <span\n class=\"ax-icon\"\n [class.ax-icon-chevron-down]=\"!dropdownOpen()\"\n [class.ax-icon-chevron-up]=\"dropdownOpen()\"\n ></span>\n </button>\n </ng-container>\n <ng-container panel>\n <div class=\"__popover\" [style.min-width]=\"dropdownWidth()\">\n <ng-container *ngTemplateOutlet=\"paletteGroups; context: { showTitles: true }\"></ng-container>\n </div>\n </ng-container>\n </ax-dropdown-box>\n }\n <!-- ----- Single named row stays inline at select height ----- -->\n @else {\n <ng-container *ngTemplateOutlet=\"paletteGroups; context: { showTitles: false }\"></ng-container>\n <!-- ----- Clear under the single inline strip ----- -->\n @if (allowClear()) {\n <button\n type=\"button\"\n class=\"__clear\"\n [class.__selected]=\"selectedClass() == null\"\n [disabled]=\"!isInteractive()\"\n (click)=\"handleClear($event)\"\n >\n <span class=\"ax-icon ax-icon-close\"></span>\n </button>\n }\n }\n</div>\n\n<ng-template #selectedItem>\n @if (selectedSwatch(); as swatch) {\n <!-- ----- Selected value as a surface-colored pill ----- -->\n <div class=\"__selected-item {{ swatch.className }}\">\n <span class=\"__selected-text\">\n <!-- ----- Group title before the selected variant ----- -->\n @if (selectedGroup()?.title; as groupTitle) {\n {{ groupTitle | translate | async }}\n <span class=\"__trigger-sep\">\u00B7</span>\n }\n {{ displayLabel(swatch.label) | translate | async }}\n </span>\n </div>\n }\n <!-- ----- Empty state uses the same control height as a select ----- -->\n @else {\n <div class=\"ax-placeholder\">\n {{ '@platform-layout-widgets:widgets.color-chooser.placeholder' | translate | async }}\n </div>\n }\n</ng-template>\n\n<ng-template #paletteGroups let-showTitles=\"showTitles\">\n <div class=\"__groups\" [class.__look-strip]=\"look() === 'strip'\" [class.__look-swatches]=\"look() === 'swatches'\">\n @for (group of resolvedGroups(); track group.id) {\n <div class=\"__group\">\n <!-- ----- Named row title inside the dropdown list ----- -->\n @if (showTitles && group.title) {\n <div class=\"__group-title\">{{ group.title | translate | async }}</div>\n }\n <!-- ----- Coolors bar: thin columns, hover expands and shows the label ----- -->\n <div class=\"__strip\" role=\"listbox\">\n @for (swatch of group.swatches; track swatch.className) {\n <button\n type=\"button\"\n class=\"__column {{ swatch.className }}\"\n [class.__selected]=\"isSelected(swatch.className)\"\n [disabled]=\"!isInteractive()\"\n [attr.aria-label]=\"displayLabel(swatch.label)\"\n [attr.aria-selected]=\"isSelected(swatch.className)\"\n (click)=\"handleSelect(swatch)\"\n >\n <span class=\"__label\">{{ displayLabel(swatch.label) | translate | async }}</span>\n </button>\n }\n </div>\n </div>\n }\n </div>\n</ng-template>\n", styles: [":host{display:block;min-height:var(--ax-sys-size-base, 2.5rem);width:100%}:host ax-dropdown-box{width:100%}:host .ax-editor-container{padding-block:0}:host .ax-content{display:flex;min-height:var(--ax-sys-size-base, 2.5rem);min-width:0;flex:1;cursor:pointer;align-items:center;outline:none;-webkit-user-select:none;user-select:none}.__root{display:flex;flex-direction:column;gap:.5rem}.__selected-item{display:inline-flex;align-items:center;max-width:100%;min-height:1.5rem;padding-inline:.5rem;border-radius:.375rem}.__selected-text{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.__placeholder{opacity:.65}.__trigger-sep{margin-inline:.25rem}.__popover{box-sizing:border-box;width:100%;max-height:min(24rem,70vh);overflow:auto;padding:.75rem}.__groups{display:flex;flex-direction:column;gap:.75rem;min-width:0}.__group-title{font-size:.75rem;font-weight:500;color:rgb(var(--ax-sys-color-on-lighter-surface))}.__strip{display:flex;flex-wrap:nowrap;align-items:stretch;width:100%;height:var(--ax-sys-size-base, 2.5rem);overflow:hidden;border-radius:.5rem}.__column{position:relative;flex:1 1 0;min-width:0;margin:0;padding:0;border:0;border-radius:0;appearance:none;cursor:pointer;transition:flex .22s ease}.__label{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;pointer-events:none;font-size:var(--ax-sys-text-xs-base, .75rem);font-weight:600;letter-spacing:.04em;white-space:nowrap;opacity:0;transition:opacity .16s ease}.__look-strip .__column.__selected,.__look-strip .__column:hover:not(:disabled),.__look-strip .__column:focus-visible:not(:disabled){flex:4 1 0}.__look-strip .__column.__selected .__label,.__look-strip .__column:hover:not(:disabled) .__label,.__look-strip .__column:focus-visible:not(:disabled) .__label{opacity:1}.__look-strip .__strip:has(.__column:hover:not(.__selected)) .__column.__selected:not(:hover),.__look-strip .__strip:has(.__column:focus-visible:not(.__selected)) .__column.__selected:not(:focus-visible){flex:1 1 0}.__look-strip .__strip:has(.__column:hover:not(.__selected)) .__column.__selected:not(:hover) .__label,.__look-strip .__strip:has(.__column:focus-visible:not(.__selected)) .__column.__selected:not(:focus-visible) .__label{opacity:0}.__column.__selected{box-shadow:inset 0 0 0 2px rgb(var(--ax-sys-color-on-lighter-surface) / .4)}.__column:disabled{cursor:not-allowed}.__clear{align-self:flex-start;display:inline-flex;height:1.75rem;width:1.75rem;align-items:center;justify-content:center;border-radius:999px;border:1px dashed rgb(var(--ax-sys-color-border-lighter-surface));background:rgb(var(--ax-sys-color-lighter-surface));color:rgb(var(--ax-sys-color-on-lighter-surface));font-size:.75rem}.__clear.__selected,.__clear:focus-visible:not(:disabled){outline:2px solid rgb(var(--ax-sys-color-primary));outline-offset:2px}.__clear:disabled{cursor:not-allowed;opacity:.5}.__look-swatches .__strip{height:auto;flex-wrap:wrap;gap:.25rem;overflow:visible;border-radius:0}.__look-swatches .__column{flex:0 0 2rem;width:2rem;height:2rem;min-width:2rem;border-radius:.375rem;transition:transform .16s ease}.__look-swatches .__label{display:none}.__look-swatches .__column:hover:not(:disabled),.__look-swatches .__column:focus-visible:not(:disabled){flex:0 0 2rem;transform:scale(1.08)}.__disabled .__column,.__readonly .__column,.__disabled .__clear,.__readonly .__clear,.__disabled .ax-content,.__readonly .ax-content{cursor:default}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"] }]
1423
+ }], ctorParameters: () => [], propDecorators: { paletteDropdown: [{ type: i0.ViewChild, args: ['paletteDropdown', { isSignal: true }] }], groups: [{ type: i0.Input, args: [{ isSignal: true, alias: "groups", required: false }] }], selectedClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectedClass", required: false }] }], look: [{ type: i0.Input, args: [{ isSignal: true, alias: "look", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], readonly: [{ type: i0.Input, args: [{ isSignal: true, alias: "readonly", required: false }] }], allowClear: [{ type: i0.Input, args: [{ isSignal: true, alias: "allowClear", required: false }] }], classSelected: [{ type: i0.Output, args: ["classSelected"] }] } });
1424
+
1425
+ //#region ----- Types -----
1426
+ //#endregion
1427
+
1303
1428
  //#region ---- Component ----
1304
1429
  /**
1305
1430
  * Color Palette Picker Component
@@ -6138,6 +6263,105 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
6138
6263
  args: [{ providedIn: 'root' }]
6139
6264
  }] });
6140
6265
 
6266
+ //#region ----- Types -----
6267
+ //#endregion
6268
+ //#region ----- Constants -----
6269
+ const AXP_PAGE_LAYOUT_ELEMENT_ID = 'axp-page-layout';
6270
+ const AXP_INFINITE_SCROLL_DEFAULT_ROOT_MARGIN = '160px';
6271
+ //#endregion
6272
+
6273
+ //#region ----- Root resolution -----
6274
+ function resolveInfiniteScrollRoot(root) {
6275
+ if (root === null) {
6276
+ return null;
6277
+ }
6278
+ if (typeof Element !== 'undefined' && root instanceof Element) {
6279
+ return root;
6280
+ }
6281
+ if (typeof document === 'undefined') {
6282
+ return null;
6283
+ }
6284
+ if (typeof root === 'string' && root.trim()) {
6285
+ const selector = root.trim();
6286
+ const id = selector.startsWith('#') ? selector.slice(1) : selector;
6287
+ return document.getElementById(id) ?? document.querySelector(selector);
6288
+ }
6289
+ return document.getElementById(AXP_PAGE_LAYOUT_ELEMENT_ID);
6290
+ }
6291
+ //#endregion
6292
+ //#region ----- Observer -----
6293
+ /** Observes a sentinel and calls `onReached` when it intersects the scroll root. Returns a disconnect function. */
6294
+ function observeInfiniteScroll(options) {
6295
+ const observer = new IntersectionObserver((entries) => {
6296
+ if (entries.some((entry) => entry.isIntersecting)) {
6297
+ options.onReached();
6298
+ }
6299
+ }, {
6300
+ root: resolveInfiniteScrollRoot(options.root),
6301
+ rootMargin: options.rootMargin ?? AXP_INFINITE_SCROLL_DEFAULT_ROOT_MARGIN,
6302
+ threshold: options.threshold ?? 0,
6303
+ });
6304
+ observer.observe(options.sentinel);
6305
+ return () => observer.disconnect();
6306
+ }
6307
+ //#endregion
6308
+ //#region ----- Page merge -----
6309
+ /** Appends or replaces a paged result and computes the next skip / hasMore flags. */
6310
+ function mergeInfiniteScrollPage(current, page, options) {
6311
+ if (!page) {
6312
+ return {
6313
+ items: options.reset ? [] : [...current],
6314
+ skip: options.reset ? 0 : options.skip,
6315
+ hasMore: false,
6316
+ };
6317
+ }
6318
+ const nextItems = [...(page.items ?? [])];
6319
+ const items = options.reset ? nextItems : [...current, ...nextItems];
6320
+ const skip = (options.reset ? 0 : Math.max(0, options.skip)) + nextItems.length;
6321
+ const hasMore = nextItems.length > 0 && skip < (page.total ?? 0);
6322
+ return { items, skip, hasMore };
6323
+ }
6324
+ //#endregion
6325
+
6326
+ //#region ----- Directive -----
6327
+ class AXPInfiniteScrollDirective {
6328
+ //#endregion
6329
+ //#region ----- Lifecycle -----
6330
+ constructor() {
6331
+ //#region ----- Services & Dependencies -----
6332
+ this.host = inject(ElementRef);
6333
+ //#endregion
6334
+ //#region ----- Inputs & Outputs -----
6335
+ this.enabled = input(true, { ...(ngDevMode ? { debugName: "enabled" } : /* istanbul ignore next */ {}), alias: 'axpInfiniteScrollEnabled' });
6336
+ this.root = input(undefined, { ...(ngDevMode ? { debugName: "root" } : /* istanbul ignore next */ {}), alias: 'axpInfiniteScrollRoot' });
6337
+ this.rootMargin = input(AXP_INFINITE_SCROLL_DEFAULT_ROOT_MARGIN, { ...(ngDevMode ? { debugName: "rootMargin" } : /* istanbul ignore next */ {}), alias: 'axpInfiniteScrollRootMargin' });
6338
+ this.threshold = input(0, { ...(ngDevMode ? { debugName: "threshold" } : /* istanbul ignore next */ {}), alias: 'axpInfiniteScrollThreshold' });
6339
+ this.reached = output({ alias: 'axpInfiniteScrollReached' });
6340
+ effect((onCleanup) => {
6341
+ if (!this.enabled()) {
6342
+ return;
6343
+ }
6344
+ const disconnect = observeInfiniteScroll({
6345
+ sentinel: this.host.nativeElement,
6346
+ root: this.root(),
6347
+ rootMargin: this.rootMargin(),
6348
+ threshold: this.threshold(),
6349
+ onReached: () => this.reached.emit(),
6350
+ });
6351
+ onCleanup(disconnect);
6352
+ });
6353
+ }
6354
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPInfiniteScrollDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
6355
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.0.8", type: AXPInfiniteScrollDirective, isStandalone: true, selector: "[axpInfiniteScroll]", inputs: { enabled: { classPropertyName: "enabled", publicName: "axpInfiniteScrollEnabled", isSignal: true, isRequired: false, transformFunction: null }, root: { classPropertyName: "root", publicName: "axpInfiniteScrollRoot", isSignal: true, isRequired: false, transformFunction: null }, rootMargin: { classPropertyName: "rootMargin", publicName: "axpInfiniteScrollRootMargin", isSignal: true, isRequired: false, transformFunction: null }, threshold: { classPropertyName: "threshold", publicName: "axpInfiniteScrollThreshold", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { reached: "axpInfiniteScrollReached" }, ngImport: i0 }); }
6356
+ }
6357
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPInfiniteScrollDirective, decorators: [{
6358
+ type: Directive,
6359
+ args: [{
6360
+ selector: '[axpInfiniteScroll]',
6361
+ standalone: true,
6362
+ }]
6363
+ }], ctorParameters: () => [], propDecorators: { enabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "axpInfiniteScrollEnabled", required: false }] }], root: [{ type: i0.Input, args: [{ isSignal: true, alias: "axpInfiniteScrollRoot", required: false }] }], rootMargin: [{ type: i0.Input, args: [{ isSignal: true, alias: "axpInfiniteScrollRootMargin", required: false }] }], threshold: [{ type: i0.Input, args: [{ isSignal: true, alias: "axpInfiniteScrollThreshold", required: false }] }], reached: [{ type: i0.Output, args: ["axpInfiniteScrollReached"] }] } });
6364
+
6141
6365
  //#region ---- Signature editor types ----
6142
6366
  //#endregion
6143
6367
 
@@ -8192,7 +8416,7 @@ class AXPMenuCustomizerComponent {
8192
8416
  this.toastService.warning(message);
8193
8417
  }
8194
8418
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPMenuCustomizerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
8195
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: AXPMenuCustomizerComponent, isStandalone: true, selector: "axp-menu-customizer", inputs: { scopeKey: { classPropertyName: "scopeKey", publicName: "scopeKey", isSignal: true, isRequired: true, transformFunction: null }, showToolbar: { classPropertyName: "showToolbar", publicName: "showToolbar", isSignal: true, isRequired: false, transformFunction: null }, allowAddItems: { classPropertyName: "allowAddItems", publicName: "allowAddItems", isSignal: true, isRequired: false, transformFunction: null }, dragBehavior: { classPropertyName: "dragBehavior", publicName: "dragBehavior", isSignal: true, isRequired: false, transformFunction: null }, dragArea: { classPropertyName: "dragArea", publicName: "dragArea", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { saved: "saved", cancelled: "cancelled" }, host: { classAttribute: "axp-menu-customizer" }, viewQueries: [{ propertyName: "tree", first: true, predicate: AXTreeViewComponent, descendants: true, isSignal: true }], ngImport: i0, template: "<!-- i18n path constants -->\n@let i18nBase = '@platform-management:menu-management';\n@let i18nEmptyStates = i18nBase + '.components.menu-list.empty-states';\n@let i18nActions = i18nBase + '.actions';\n\n<!-- Loading State -->\n@if (isLoading()) {\n <axp-state-message\n mode=\"loading\"\n icon=\"fa-light fa-spinner-third fa-spin\"\n [title]=\"(i18nEmptyStates + '.loading.title' | translate | async)!\"\n [description]=\"(i18nEmptyStates + '.loading.description' | translate | async)!\"\n />\n}\n\n<!-- Error State -->\n@else if (hasError()) {\n <axp-state-message\n mode=\"error\"\n icon=\"fa-light fa-circle-exclamation\"\n [title]=\"(i18nEmptyStates + '.error.title' | translate | async)!\"\n [description]=\"(i18nEmptyStates + '.error.description' | translate | async)!\"\n >\n <ax-button\n slot=\"actions\"\n [text]=\"'@general:actions.retry.title' | translate | async\"\n look=\"outline\"\n color=\"primary\"\n (onClick)=\"loadMenuItems()\"\n >\n <i class=\"fa-light fa-rotate-left\"></i>\n </ax-button>\n </axp-state-message>\n}\n\n<!-- Empty State -->\n@else if (showEmptyState()) {\n <axp-state-message\n mode=\"empty\"\n icon=\"fa-light fa-bars\"\n [title]=\"(i18nEmptyStates + '.no-data.title' | translate | async)!\"\n [description]=\"(i18nEmptyStates + '.no-data.description' | translate | async)!\"\n >\n @if (allowAddItems()) {\n <ax-button\n slot=\"actions\"\n [text]=\"i18nActions + '.add-root.title' | translate | async\"\n look=\"solid\"\n color=\"primary\"\n (onClick)=\"addRootMenuItem()\"\n >\n <i class=\"fa-light fa-plus\"></i>\n </ax-button>\n }\n </axp-state-message>\n}\n\n<!-- Main Content -->\n@else if (showContent()) {\n <!-- Toolbar -->\n @if (showToolbar()) {\n <div class=\"axp-menu-customizer__toolbar\">\n @if (allowAddItems()) {\n <ax-button\n [text]=\"i18nActions + '.add-root.title' | translate | async\"\n look=\"solid\"\n color=\"primary\"\n (onClick)=\"addRootMenuItem()\"\n >\n <ax-prefix>\n <i class=\"fa-light fa-plus\"></i>\n </ax-prefix>\n </ax-button>\n }\n\n <div class=\"axp-menu-customizer__toolbar-spacer\"></div>\n <!-- \n <ax-button\n [text]=\"i18nActions + '.collapse.title' | translate | async\"\n look=\"outline\"\n (onClick)=\"collapseAll()\"\n >\n <ax-prefix>\n <i class=\"fa-light fa-minus-square\"></i>\n </ax-prefix>\n </ax-button>\n\n <ax-button\n [text]=\"i18nActions + '.expand.title' | translate | async\"\n look=\"outline\"\n (onClick)=\"expandAll()\"\n >\n <ax-prefix>\n <i class=\"fa-light fa-plus-square\"></i>\n </ax-prefix>\n </ax-button> -->\n\n <ax-button\n [text]=\"i18nActions + '.reset.title' | translate | async\"\n look=\"outline\"\n color=\"danger\"\n (onClick)=\"resetCustomizations()\"\n >\n <ax-prefix>\n <i class=\"fa-light fa-rotate-left\"></i>\n </ax-prefix>\n </ax-button>\n </div>\n }\n\n <!-- Menu Tree -->\n <div class=\"axp-menu-customizer__container\">\n <div class=\"axp-menu-customizer__tree\">\n <ax-tree-view\n [(datasource)]=\"treeNodes\"\n look=\"default\"\n [nodeTemplate]=\"itemTemplate\"\n selectMode=\"none\"\n [showIcons]=\"false\"\n [showChildrenBadge]=\"false\"\n [dragBehavior]=\"dragBehavior()\"\n [dragArea]=\"dragArea()\"\n (onBeforeDrop)=\"handleBeforeDrop($event)\"\n (onOrderChange)=\"handleOrderChange($event)\"\n (onMoveChange)=\"handleMoveChange($event)\"\n />\n </div>\n </div>\n}\n\n<!-- Custom Item Template -->\n<ng-template #itemTemplate let-node=\"node\" let-level=\"level\">\n @let nodeData = node['data'];\n @let item = nodeData.menuItem;\n @let metadata = nodeData.metadata;\n @let isGroup = item.type === 'group';\n @let isBreak = item.type === 'break';\n @let isMenu = item.type === 'menu' || !item.type;\n @let canAddChild = !item.path && isMenu && allowAddItems();\n @let canToggleVisibility = item.name && metadata.isBuiltIn;\n @let canDelete = item.name && metadata.isCustom;\n @let i18nStates = '@platform-management:menu-management.states';\n\n <div\n class=\"axp-menu-customizer__item\"\n [class.axp-menu-customizer__item--hidden]=\"metadata.isHidden\"\n [class.axp-menu-customizer__item--custom]=\"metadata.isCustom\"\n [class.axp-menu-customizer__item--group]=\"isGroup\"\n >\n <!-- Icon (hidden for groups) -->\n @if (item.icon && !isGroup) {\n <i class=\"axp-menu-customizer__item-icon\" [class]=\"item.icon\"></i>\n }\n\n <!-- Content based on item type -->\n @if (isGroup) {\n <span class=\"axp-menu-customizer__item-group\">\n <i class=\"fa-light fa-layer-group\"></i>\n {{ item.text | translate | async }}\n </span>\n } @else if (isBreak) {\n <span class=\"axp-menu-customizer__item-divider\">\n <i class=\"fa-light fa-minus\"></i>\n {{ i18nStates + '.divider' | translate | async }}\n </span>\n } @else if (item.text) {\n <span class=\"axp-menu-customizer__item-text\">\n {{ item.text | translate | async }}\n </span>\n } @else if (item.path) {\n <span class=\"axp-menu-customizer__item-path\">\n <i class=\"fa-light fa-link\"></i>\n {{ item.path }}\n </span>\n }\n\n <!-- Menu Name/Key -->\n @if (item.name) {\n <code class=\"axp-menu-customizer__item-name\">{{ item.name }}</code>\n }\n\n <!-- Status Badges -->\n @if (metadata.isHidden) {\n <ax-badge [text]=\"(i18nStates + '.hidden' | translate | async)!\" color=\"danger\" />\n } @else if (metadata.isCustom) {\n <ax-badge [text]=\"(i18nStates + '.custom' | translate | async)!\" color=\"success\" />\n } @else if (metadata.isBuiltIn) {\n <ax-badge [text]=\"(i18nStates + '.built-in' | translate | async)!\" color=\"primary\" />\n }\n\n <!-- Actions Dropdown -->\n <ax-button class=\"axp-menu-customizer__item-actions\" look=\"blank\" size=\"sm\" [iconOnly]=\"true\">\n <ax-prefix>\n <i class=\"fa-light fa-ellipsis-vertical\"></i>\n </ax-prefix>\n\n <ax-dropdown-panel #panel>\n <ax-button-item-list>\n <!-- Edit (only for items with names) -->\n @if (item.name) {\n <ax-button-item\n [text]=\"('@general:actions.edit.title' | translate | async)!\"\n (onClick)=\"onAction('edit', nodeData); panel.close()\"\n >\n <ax-prefix>\n <i class=\"fa-light fa-edit\"></i>\n </ax-prefix>\n </ax-button-item>\n }\n\n <!-- Show/Hide (only for built-in items with names) -->\n @if (canToggleVisibility) {\n @if (metadata.isHidden) {\n <ax-button-item\n [text]=\"(i18nActions + '.show.title' | translate | async)!\"\n (onClick)=\"onAction('show', nodeData); panel.close()\"\n >\n <ax-prefix>\n <i class=\"fa-light fa-eye\"></i>\n </ax-prefix>\n </ax-button-item>\n } @else {\n <ax-button-item\n [text]=\"(i18nActions + '.hide.title' | translate | async)!\"\n (onClick)=\"onAction('hide', nodeData); panel.close()\"\n >\n <ax-prefix>\n <i class=\"fa-light fa-eye-slash\"></i>\n </ax-prefix>\n </ax-button-item>\n }\n }\n\n <!-- Add Child -->\n @if (canAddChild) {\n <ax-button-item\n [text]=\"(i18nActions + '.add-child.title' | translate | async)!\"\n (onClick)=\"onAction('add-child', nodeData); panel.close()\"\n >\n <ax-prefix>\n <i class=\"fa-light fa-plus\"></i>\n </ax-prefix>\n </ax-button-item>\n }\n\n <!-- Delete (only for custom items with names) -->\n @if (canDelete) {\n <ax-divider />\n <ax-button-item\n color=\"danger\"\n [text]=\"('@general:actions.delete.title' | translate | async)!\"\n (onClick)=\"onAction('delete', nodeData); panel.close()\"\n >\n <ax-prefix>\n <i class=\"fa-light fa-trash\"></i>\n </ax-prefix>\n </ax-button-item>\n }\n\n <!-- Info message for items without names -->\n @if (!item.name) {\n <ax-divider />\n <div class=\"p-2 text-xs text-neutral-500 italic\">\n {{ i18nBase + '.messages.info.no-name' | translate | async }}\n </div>\n }\n </ax-button-item-list>\n </ax-dropdown-panel>\n </ax-button>\n </div>\n</ng-template>\n", styles: ["@layer properties;.axp-menu-customizer{display:flex;height:100%;min-height:0px;flex-direction:column}.axp-menu-customizer .axp-menu-customizer__toolbar{display:flex;flex-shrink:0;flex-wrap:wrap;align-items:center;gap:calc(var(--spacing, .25rem) * 2);border-bottom-style:var(--tw-border-style);border-bottom-width:1px;--tw-border-style: solid;border-style:solid;border-color:var(--color-neutral-200, oklch(92.2% 0 none));padding:calc(var(--spacing, .25rem) * 4)}.axp-menu-customizer .axp-menu-customizer__toolbar-spacer{min-width:calc(var(--spacing, .25rem) * 4);flex:1}.axp-menu-customizer .axp-menu-customizer__container{display:flex;min-height:0px;flex:1;flex-direction:column;gap:calc(var(--spacing, .25rem) * 4);overflow:auto;padding:calc(var(--spacing, .25rem) * 4)}.axp-menu-customizer .axp-menu-customizer__tree{display:flex;flex-direction:column;gap:calc(var(--spacing, .25rem) * 2)}.axp-menu-customizer .axp-menu-customizer__tree ax-tree-view{flex:1}.axp-menu-customizer .axp-menu-customizer__item{display:flex;flex:1;align-items:center;gap:calc(var(--spacing, .25rem) * 3);border-radius:var(--radius-md, .375rem);border-style:var(--tw-border-style);border-width:1px;--tw-border-style: solid;border-style:solid;border-color:var(--color-neutral-200, oklch(92.2% 0 none));background-color:var(--color-white, #fff);padding-inline:calc(var(--spacing, .25rem) * 3);padding-block:calc(var(--spacing, .25rem) * 2);transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease, var(--default-transition-timing-function, cubic-bezier(.4, 0, .2, 1)));transition-duration:var(--tw-duration, var(--default-transition-duration, .15s));--tw-duration: .15s;transition-duration:.15s}.axp-menu-customizer .axp-menu-customizer__item:hover{background-color:var(--color-neutral-50, oklch(98.5% 0 none))}.axp-menu-customizer .axp-menu-customizer__item:hover .axp-menu-customizer__item-actions{opacity:100%}.axp-menu-customizer .axp-menu-customizer__item--hidden{opacity:50%}.axp-menu-customizer .axp-menu-customizer__item--hidden .axp-menu-customizer__item-text,.axp-menu-customizer .axp-menu-customizer__item--hidden .axp-menu-customizer__item-icon{text-decoration-line:line-through}.axp-menu-customizer .axp-menu-customizer__item--custom{border-color:rgba(var(--ax-sys-color-primary-200));background-color:rgba(var(--ax-sys-color-primary-50))}@supports (color: color-mix(in lab,red,red)){.axp-menu-customizer .axp-menu-customizer__item--custom{background-color:color-mix(in oklab,rgba(var(--ax-sys-color-primary-50)) 30%,transparent)}}.axp-menu-customizer .axp-menu-customizer__item--group{background-color:var(--color-neutral-50, oklch(98.5% 0 none));padding-block:calc(var(--spacing, .25rem) * 3)}.axp-menu-customizer .axp-menu-customizer__item-icon{display:flex;height:calc(var(--spacing, .25rem) * 6);width:calc(var(--spacing, .25rem) * 6);flex-shrink:0;align-items:center;justify-content:center;color:rgba(var(--ax-sys-color-primary-600))}.axp-menu-customizer .axp-menu-customizer__item-text{min-width:0px;flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:var(--text-sm, .875rem);line-height:var(--tw-leading, var(--text-sm--line-height, calc(1.25 / .875)));--tw-font-weight: var(--font-weight-medium, 500);font-weight:var(--font-weight-medium, 500)}.axp-menu-customizer .axp-menu-customizer__item-group{display:flex;flex:1;align-items:center;gap:calc(var(--spacing, .25rem) * 2);font-size:var(--text-xs, .75rem);line-height:var(--tw-leading, var(--text-xs--line-height, calc(1 / .75)));--tw-tracking: var(--tracking-wide, .025em);letter-spacing:var(--tracking-wide, .025em);color:var(--color-neutral-500, oklch(55.6% 0 none));text-transform:uppercase;font-style:italic}.axp-menu-customizer .axp-menu-customizer__item-group i{color:var(--color-neutral-400, oklch(70.8% 0 none))}.axp-menu-customizer .axp-menu-customizer__item-divider,.axp-menu-customizer .axp-menu-customizer__item-path{display:flex;min-width:0px;flex:1;align-items:center;gap:calc(var(--spacing, .25rem) * 2);font-size:var(--text-xs, .75rem);line-height:var(--tw-leading, var(--text-xs--line-height, calc(1 / .75)));color:var(--color-neutral-500, oklch(55.6% 0 none));font-style:italic}:is(.axp-menu-customizer .axp-menu-customizer__item-divider,.axp-menu-customizer .axp-menu-customizer__item-path) i{flex-shrink:0;color:var(--color-neutral-400, oklch(70.8% 0 none))}.axp-menu-customizer .axp-menu-customizer__item-name{display:inline-flex;max-width:calc(var(--spacing, .25rem) * 48);flex-shrink:0;overflow:hidden;text-overflow:ellipsis;border-radius:.25rem;border-style:var(--tw-border-style);border-width:1px;border-color:var(--color-neutral-200, oklch(92.2% 0 none));background-color:var(--color-neutral-100, oklch(97% 0 none));padding-inline:calc(var(--spacing, .25rem) * 2);padding-block:var(--spacing, .25rem);font-family:var(--font-mono, ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace);font-size:var(--text-xs, .75rem);line-height:var(--tw-leading, var(--text-xs--line-height, calc(1 / .75)));--tw-font-weight: var(--font-weight-normal, 400);font-weight:var(--font-weight-normal, 400);white-space:nowrap;color:var(--color-neutral-600, oklch(43.9% 0 none));-webkit-user-select:all;user-select:all}.axp-menu-customizer .axp-menu-customizer__item-actions{margin-left:auto;flex-shrink:0;opacity:60%;transition-property:opacity;transition-timing-function:var(--tw-ease, var(--default-transition-timing-function, cubic-bezier(.4, 0, .2, 1)));transition-duration:var(--tw-duration, var(--default-transition-duration, .15s));--tw-duration: .15s;transition-duration:.15s}@property --tw-border-style{syntax: \"*\"; inherits: false; initial-value: solid;}@property --tw-duration{syntax: \"*\"; inherits: false;}@property --tw-font-weight{syntax: \"*\"; inherits: false;}@property --tw-tracking{syntax: \"*\"; inherits: false;}@layer properties{@supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-border-style: solid;--tw-duration: initial;--tw-font-weight: initial;--tw-tracking: initial}}}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"], dependencies: [{ kind: "ngmodule", type: AXButtonModule }, { kind: "component", type: i1$2.AXButtonComponent, selector: "ax-button", inputs: ["disabled", "size", "tabIndex", "color", "look", "text", "toggleable", "selected", "iconOnly", "type", "loadingText"], outputs: ["onBlur", "onFocus", "onClick", "selectedChange", "toggleableChange", "lookChange", "colorChange", "disabledChange", "loadingTextChange"] }, { kind: "component", type: i1$2.AXButtonItemComponent, selector: "ax-button-item", inputs: ["color", "disabled", "text", "selected", "divided", "data", "name"], outputs: ["onClick", "onFocus", "onBlur", "disabledChange"] }, { kind: "component", type: i1$2.AXButtonItemListComponent, selector: "ax-button-item-list", inputs: ["items", "closeParentOnClick", "lockOnLoading"], outputs: ["onItemClick"] }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i2$1.AXDecoratorGenericComponent, selector: "ax-footer, ax-header, ax-content, ax-divider, ax-form-hint, ax-prefix, ax-suffix, ax-text, ax-title, ax-subtitle, ax-placeholder, ax-overlay" }, { kind: "ngmodule", type: AXDropdownButtonModule }, { kind: "ngmodule", type: AXDropdownModule }, { kind: "component", type: i5$1.AXDropdownPanelComponent, selector: "ax-dropdown-panel", inputs: ["isOpen", "fitParent", "dropdownWidth", "position", "placement", "_target", "adaptivityEnabled"], outputs: ["onOpened", "onClosed"] }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "component", type: AXTreeViewComponent, selector: "ax-tree-view", inputs: ["datasource", "selectMode", "selectionBehavior", "dragArea", "dragBehavior", "showIcons", "showChildrenBadge", "expandedIcon", "collapsedIcon", "indentSize", "look", "nodeTemplate", "idField", "titleField", "tooltipField", "iconField", "expandedField", "selectedField", "indeterminateField", "disabledField", "hiddenField", "childrenField", "childrenCountField", "dataField", "inheritDisabled", "expandOnDoubleClick", "doubleClickDuration", "tooltipDelay", "controlledSelection", "selectedIds"], outputs: ["datasourceChange", "selectedIdsChange", "onBeforeDrop", "onNodeToggle", "onNodeSelect", "onNodeDoubleClick", "onNodeClick", "onSelectionChange", "onOrderChange", "onMoveChange", "onItemsChange"] }, { kind: "component", type: AXPStateMessageComponent, selector: "axp-state-message", inputs: ["mode", "icon", "title", "description", "titleParams", "descriptionParams", "look"] }, { kind: "ngmodule", type: AXBadgeModule }, { kind: "component", type: i1$3.AXBadgeComponent, selector: "ax-badge", inputs: ["color", "look", "text"] }, { kind: "pipe", type: i3.AXTranslatorPipe, name: "translate" }, { kind: "pipe", type: AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
8419
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: AXPMenuCustomizerComponent, isStandalone: true, selector: "axp-menu-customizer", inputs: { scopeKey: { classPropertyName: "scopeKey", publicName: "scopeKey", isSignal: true, isRequired: true, transformFunction: null }, showToolbar: { classPropertyName: "showToolbar", publicName: "showToolbar", isSignal: true, isRequired: false, transformFunction: null }, allowAddItems: { classPropertyName: "allowAddItems", publicName: "allowAddItems", isSignal: true, isRequired: false, transformFunction: null }, dragBehavior: { classPropertyName: "dragBehavior", publicName: "dragBehavior", isSignal: true, isRequired: false, transformFunction: null }, dragArea: { classPropertyName: "dragArea", publicName: "dragArea", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { saved: "saved", cancelled: "cancelled" }, host: { classAttribute: "axp-menu-customizer" }, viewQueries: [{ propertyName: "tree", first: true, predicate: AXTreeViewComponent, descendants: true, isSignal: true }], ngImport: i0, template: "<!-- i18n path constants -->\n@let i18nBase = '@platform-management:menu-management';\n@let i18nEmptyStates = i18nBase + '.components.menu-list.empty-states';\n@let i18nActions = i18nBase + '.actions';\n\n<!-- Loading State -->\n@if (isLoading()) {\n <axp-state-message\n mode=\"loading\"\n icon=\"fa-light fa-spinner-third fa-spin\"\n [title]=\"(i18nEmptyStates + '.loading.title' | translate | async)!\"\n [description]=\"(i18nEmptyStates + '.loading.description' | translate | async)!\"\n />\n}\n\n<!-- Error State -->\n@else if (hasError()) {\n <axp-state-message\n mode=\"error\"\n icon=\"fa-light fa-circle-exclamation\"\n [title]=\"(i18nEmptyStates + '.error.title' | translate | async)!\"\n [description]=\"(i18nEmptyStates + '.error.description' | translate | async)!\"\n >\n <ax-button\n slot=\"actions\"\n [text]=\"'@general:actions.retry.title' | translate | async\"\n look=\"outline\"\n color=\"primary\"\n (onClick)=\"loadMenuItems()\"\n >\n <i class=\"fa-light fa-rotate-left\"></i>\n </ax-button>\n </axp-state-message>\n}\n\n<!-- Empty State -->\n@else if (showEmptyState()) {\n <axp-state-message\n mode=\"empty\"\n icon=\"fa-light fa-bars\"\n [title]=\"(i18nEmptyStates + '.no-data.title' | translate | async)!\"\n [description]=\"(i18nEmptyStates + '.no-data.description' | translate | async)!\"\n >\n @if (allowAddItems()) {\n <ax-button\n slot=\"actions\"\n [text]=\"i18nActions + '.add-root.title' | translate | async\"\n look=\"solid\"\n color=\"primary\"\n (onClick)=\"addRootMenuItem()\"\n >\n <i class=\"fa-light fa-plus\"></i>\n </ax-button>\n }\n </axp-state-message>\n}\n\n<!-- Main Content -->\n@else if (showContent()) {\n <!-- Toolbar -->\n @if (showToolbar()) {\n <div class=\"axp-menu-customizer__toolbar\">\n @if (allowAddItems()) {\n <ax-button\n [text]=\"i18nActions + '.add-root.title' | translate | async\"\n look=\"solid\"\n color=\"primary\"\n (onClick)=\"addRootMenuItem()\"\n >\n <ax-prefix>\n <i class=\"fa-light fa-plus\"></i>\n </ax-prefix>\n </ax-button>\n }\n\n <div class=\"axp-menu-customizer__toolbar-spacer\"></div>\n <!-- \n <ax-button\n [text]=\"i18nActions + '.collapse.title' | translate | async\"\n look=\"outline\"\n (onClick)=\"collapseAll()\"\n >\n <ax-prefix>\n <i class=\"fa-light fa-minus-square\"></i>\n </ax-prefix>\n </ax-button>\n\n <ax-button\n [text]=\"i18nActions + '.expand.title' | translate | async\"\n look=\"outline\"\n (onClick)=\"expandAll()\"\n >\n <ax-prefix>\n <i class=\"fa-light fa-plus-square\"></i>\n </ax-prefix>\n </ax-button> -->\n\n <ax-button\n [text]=\"i18nActions + '.reset.title' | translate | async\"\n look=\"outline\"\n color=\"danger\"\n (onClick)=\"resetCustomizations()\"\n >\n <ax-prefix>\n <i class=\"fa-light fa-rotate-left\"></i>\n </ax-prefix>\n </ax-button>\n </div>\n }\n\n <!-- Menu Tree -->\n <div class=\"axp-menu-customizer__container\">\n <div class=\"axp-menu-customizer__tree\">\n <ax-tree-view\n [(datasource)]=\"treeNodes\"\n look=\"default\"\n [nodeTemplate]=\"itemTemplate\"\n selectMode=\"none\"\n [showIcons]=\"false\"\n [showChildrenBadge]=\"false\"\n [dragBehavior]=\"dragBehavior()\"\n [dragArea]=\"dragArea()\"\n (onBeforeDrop)=\"handleBeforeDrop($event)\"\n (onOrderChange)=\"handleOrderChange($event)\"\n (onMoveChange)=\"handleMoveChange($event)\"\n />\n </div>\n </div>\n}\n\n<!-- Custom Item Template -->\n<ng-template #itemTemplate let-node=\"node\" let-level=\"level\">\n @let nodeData = node['data'];\n @let item = nodeData.menuItem;\n @let metadata = nodeData.metadata;\n @let isGroup = item.type === 'group';\n @let isBreak = item.type === 'break';\n @let isMenu = item.type === 'menu' || !item.type;\n @let canAddChild = !item.path && isMenu && allowAddItems();\n @let canToggleVisibility = item.name && metadata.isBuiltIn;\n @let canDelete = item.name && metadata.isCustom;\n @let i18nStates = '@platform-management:menu-management.states';\n\n <div\n class=\"axp-menu-customizer__item\"\n [class.axp-menu-customizer__item--hidden]=\"metadata.isHidden\"\n [class.axp-menu-customizer__item--custom]=\"metadata.isCustom\"\n [class.axp-menu-customizer__item--group]=\"isGroup\"\n >\n <!-- Icon (hidden for groups) -->\n @if (item.icon && !isGroup) {\n <i class=\"axp-menu-customizer__item-icon\" [class]=\"item.icon\"></i>\n }\n\n <!-- Content based on item type -->\n @if (isGroup) {\n <span class=\"axp-menu-customizer__item-group\">\n <i class=\"fa-light fa-layer-group\"></i>\n {{ item.text | translate | async }}\n </span>\n } @else if (isBreak) {\n <span class=\"axp-menu-customizer__item-divider\">\n <i class=\"fa-light fa-minus\"></i>\n {{ i18nStates + '.divider' | translate | async }}\n </span>\n } @else if (item.text) {\n <span class=\"axp-menu-customizer__item-text\">\n {{ item.text | translate | async }}\n </span>\n } @else if (item.path) {\n <span class=\"axp-menu-customizer__item-path\">\n <i class=\"fa-light fa-link\"></i>\n {{ item.path }}\n </span>\n }\n\n <!-- Menu Name/Key -->\n @if (item.name) {\n <code class=\"axp-menu-customizer__item-name\">{{ item.name }}</code>\n }\n\n <!-- Status Badges -->\n @if (metadata.isHidden) {\n <ax-badge [text]=\"(i18nStates + '.hidden' | translate | async)!\" color=\"danger\" />\n } @else if (metadata.isCustom) {\n <ax-badge [text]=\"(i18nStates + '.custom' | translate | async)!\" color=\"success\" />\n } @else if (metadata.isBuiltIn) {\n <ax-badge [text]=\"(i18nStates + '.built-in' | translate | async)!\" color=\"primary\" />\n }\n\n <!-- Actions Dropdown -->\n <ax-button class=\"axp-menu-customizer__item-actions\" look=\"blank\" size=\"sm\" [iconOnly]=\"true\">\n <ax-prefix>\n <i class=\"fa-light fa-ellipsis-vertical\"></i>\n </ax-prefix>\n\n <ax-dropdown-panel #panel>\n <ax-button-item-list>\n <!-- Edit (only for items with names) -->\n @if (item.name) {\n <ax-button-item\n [text]=\"('@general:actions.edit.title' | translate | async)!\"\n (onClick)=\"onAction('edit', nodeData); panel.close()\"\n >\n <ax-prefix>\n <i class=\"fa-light fa-edit\"></i>\n </ax-prefix>\n </ax-button-item>\n }\n\n <!-- Show/Hide (only for built-in items with names) -->\n @if (canToggleVisibility) {\n @if (metadata.isHidden) {\n <ax-button-item\n [text]=\"(i18nActions + '.show.title' | translate | async)!\"\n (onClick)=\"onAction('show', nodeData); panel.close()\"\n >\n <ax-prefix>\n <i class=\"fa-light fa-eye\"></i>\n </ax-prefix>\n </ax-button-item>\n } @else {\n <ax-button-item\n [text]=\"(i18nActions + '.hide.title' | translate | async)!\"\n (onClick)=\"onAction('hide', nodeData); panel.close()\"\n >\n <ax-prefix>\n <i class=\"fa-light fa-eye-slash\"></i>\n </ax-prefix>\n </ax-button-item>\n }\n }\n\n <!-- Add Child -->\n @if (canAddChild) {\n <ax-button-item\n [text]=\"(i18nActions + '.add-child.title' | translate | async)!\"\n (onClick)=\"onAction('add-child', nodeData); panel.close()\"\n >\n <ax-prefix>\n <i class=\"fa-light fa-plus\"></i>\n </ax-prefix>\n </ax-button-item>\n }\n\n <!-- Delete (only for custom items with names) -->\n @if (canDelete) {\n <ax-divider />\n <ax-button-item\n color=\"danger\"\n [text]=\"('@general:actions.delete.title' | translate | async)!\"\n (onClick)=\"onAction('delete', nodeData); panel.close()\"\n >\n <ax-prefix>\n <i class=\"fa-light fa-trash\"></i>\n </ax-prefix>\n </ax-button-item>\n }\n\n <!-- Info message for items without names -->\n @if (!item.name) {\n <ax-divider />\n <div class=\"p-2 text-xs text-neutral-500 italic\">\n {{ i18nBase + '.messages.info.no-name' | translate | async }}\n </div>\n }\n </ax-button-item-list>\n </ax-dropdown-panel>\n </ax-button>\n </div>\n</ng-template>\n", styles: ["@layer properties;.axp-menu-customizer{display:flex;height:100%;min-height:0px;flex-direction:column}.axp-menu-customizer .axp-menu-customizer__toolbar{display:flex;flex-shrink:0;flex-wrap:wrap;align-items:center;gap:calc(var(--spacing, .25rem) * 2);border-bottom-style:var(--tw-border-style);border-bottom-width:1px;--tw-border-style: solid;border-style:solid;border-color:var(--color-neutral-200, oklch(92.2% 0 none));padding:calc(var(--spacing, .25rem) * 4)}.axp-menu-customizer .axp-menu-customizer__toolbar-spacer{min-width:calc(var(--spacing, .25rem) * 4);flex:1}.axp-menu-customizer .axp-menu-customizer__container{display:flex;min-height:0px;flex:1;flex-direction:column;gap:calc(var(--spacing, .25rem) * 4);overflow:auto;padding:calc(var(--spacing, .25rem) * 4)}.axp-menu-customizer .axp-menu-customizer__tree{display:flex;flex-direction:column;gap:calc(var(--spacing, .25rem) * 2)}.axp-menu-customizer .axp-menu-customizer__tree ax-tree-view{flex:1}.axp-menu-customizer .axp-menu-customizer__item{display:flex;flex:1;align-items:center;gap:calc(var(--spacing, .25rem) * 3);border-radius:var(--radius-md, .375rem);border-style:var(--tw-border-style);border-width:1px;--tw-border-style: solid;border-style:solid;border-color:var(--color-neutral-200, oklch(92.2% 0 none));background-color:var(--color-white, #fff);padding-inline:calc(var(--spacing, .25rem) * 3);padding-block:calc(var(--spacing, .25rem) * 2);transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease, var(--default-transition-timing-function, cubic-bezier(.4, 0, .2, 1)));transition-duration:var(--tw-duration, var(--default-transition-duration, .15s));--tw-duration: .15s;transition-duration:.15s}.axp-menu-customizer .axp-menu-customizer__item:hover{background-color:var(--color-neutral-50, oklch(98.5% 0 none))}.axp-menu-customizer .axp-menu-customizer__item:hover .axp-menu-customizer__item-actions{opacity:100%}.axp-menu-customizer .axp-menu-customizer__item--hidden{opacity:50%}.axp-menu-customizer .axp-menu-customizer__item--hidden .axp-menu-customizer__item-text,.axp-menu-customizer .axp-menu-customizer__item--hidden .axp-menu-customizer__item-icon{text-decoration-line:line-through}.axp-menu-customizer .axp-menu-customizer__item--custom{border-color:rgba(var(--ax-sys-color-primary-200));background-color:rgba(var(--ax-sys-color-primary-50))}@supports (color: color-mix(in lab,red,red)){.axp-menu-customizer .axp-menu-customizer__item--custom{background-color:color-mix(in oklab,rgba(var(--ax-sys-color-primary-50)) 30%,transparent)}}.axp-menu-customizer .axp-menu-customizer__item--group{background-color:var(--color-neutral-50, oklch(98.5% 0 none));padding-block:calc(var(--spacing, .25rem) * 3)}.axp-menu-customizer .axp-menu-customizer__item-icon{display:flex;height:calc(var(--spacing, .25rem) * 6);width:calc(var(--spacing, .25rem) * 6);flex-shrink:0;align-items:center;justify-content:center;color:rgba(var(--ax-sys-color-primary-600))}.axp-menu-customizer .axp-menu-customizer__item-text{min-width:0px;flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:var(--text-sm, .875rem);line-height:var(--tw-leading, var(--text-sm--line-height, calc(1.25 / .875)));--tw-font-weight: var(--font-weight-medium, 500);font-weight:var(--font-weight-medium, 500)}.axp-menu-customizer .axp-menu-customizer__item-group{display:flex;flex:1;align-items:center;gap:calc(var(--spacing, .25rem) * 2);font-size:var(--text-xs, .75rem);line-height:var(--tw-leading, var(--text-xs--line-height, calc(1 / .75)));--tw-tracking: var(--tracking-wide, .025em);letter-spacing:var(--tracking-wide, .025em);color:var(--color-neutral-500, oklch(55.6% 0 none));text-transform:uppercase;font-style:italic}.axp-menu-customizer .axp-menu-customizer__item-group i{color:var(--color-neutral-400, oklch(70.8% 0 none))}.axp-menu-customizer .axp-menu-customizer__item-divider,.axp-menu-customizer .axp-menu-customizer__item-path{display:flex;min-width:0px;flex:1;align-items:center;gap:calc(var(--spacing, .25rem) * 2);font-size:var(--text-xs, .75rem);line-height:var(--tw-leading, var(--text-xs--line-height, calc(1 / .75)));color:var(--color-neutral-500, oklch(55.6% 0 none));font-style:italic}:is(.axp-menu-customizer .axp-menu-customizer__item-divider,.axp-menu-customizer .axp-menu-customizer__item-path) i{flex-shrink:0;color:var(--color-neutral-400, oklch(70.8% 0 none))}.axp-menu-customizer .axp-menu-customizer__item-name{display:inline-flex;max-width:calc(var(--spacing, .25rem) * 48);flex-shrink:0;overflow:hidden;text-overflow:ellipsis;border-radius:.25rem;border-style:var(--tw-border-style);border-width:1px;border-color:var(--color-neutral-200, oklch(92.2% 0 none));background-color:var(--color-neutral-100, oklch(97% 0 none));padding-inline:calc(var(--spacing, .25rem) * 2);padding-block:var(--spacing, .25rem);font-family:var(--font-mono, ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace);font-size:var(--text-xs, .75rem);line-height:var(--tw-leading, var(--text-xs--line-height, calc(1 / .75)));--tw-font-weight: var(--font-weight-normal, 400);font-weight:var(--font-weight-normal, 400);white-space:nowrap;color:var(--color-neutral-600, oklch(43.9% 0 none));-webkit-user-select:all;user-select:all}.axp-menu-customizer .axp-menu-customizer__item-actions{margin-left:auto;flex-shrink:0;opacity:60%;transition-property:opacity;transition-timing-function:var(--tw-ease, var(--default-transition-timing-function, cubic-bezier(.4, 0, .2, 1)));transition-duration:var(--tw-duration, var(--default-transition-duration, .15s));--tw-duration: .15s;transition-duration:.15s}@property --tw-border-style{syntax: \"*\"; inherits: false; initial-value: solid;}@property --tw-duration{syntax: \"*\"; inherits: false;}@property --tw-font-weight{syntax: \"*\"; inherits: false;}@property --tw-tracking{syntax: \"*\"; inherits: false;}@layer properties{@supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-border-style: solid;--tw-duration: initial;--tw-font-weight: initial;--tw-tracking: initial}}}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"], dependencies: [{ kind: "ngmodule", type: AXButtonModule }, { kind: "component", type: i1$2.AXButtonComponent, selector: "ax-button", inputs: ["disabled", "size", "tabIndex", "color", "look", "text", "toggleable", "selected", "iconOnly", "type", "loadingText"], outputs: ["onBlur", "onFocus", "onClick", "selectedChange", "toggleableChange", "lookChange", "colorChange", "disabledChange", "loadingTextChange"] }, { kind: "component", type: i1$2.AXButtonItemComponent, selector: "ax-button-item", inputs: ["color", "disabled", "text", "selected", "divided", "data", "name"], outputs: ["onClick", "onFocus", "onBlur", "disabledChange"] }, { kind: "component", type: i1$2.AXButtonItemListComponent, selector: "ax-button-item-list", inputs: ["items", "closeParentOnClick", "lockOnLoading"], outputs: ["onItemClick"] }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i2$1.AXDecoratorGenericComponent, selector: "ax-footer, ax-header, ax-content, ax-divider, ax-form-hint, ax-prefix, ax-suffix, ax-text, ax-title, ax-subtitle, ax-placeholder, ax-overlay" }, { kind: "ngmodule", type: AXDropdownButtonModule }, { kind: "ngmodule", type: AXDropdownModule }, { kind: "component", type: i5$1.AXDropdownPanelComponent, selector: "ax-dropdown-panel", inputs: ["isOpen", "fitParent", "dropdownWidth", "position", "placement", "_target", "adaptivityEnabled"], outputs: ["onOpened", "onClosed"] }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "component", type: AXTreeViewComponent, selector: "ax-tree-view", inputs: ["datasource", "selectMode", "selectionBehavior", "dragArea", "dragBehavior", "showIcons", "showChildrenBadge", "expandedIcon", "collapsedIcon", "indentSize", "look", "alternate", "nodeTemplate", "idField", "titleField", "tooltipField", "iconField", "expandedField", "selectedField", "indeterminateField", "disabledField", "hiddenField", "childrenField", "childrenCountField", "dataField", "inheritDisabled", "expandOnDoubleClick", "doubleClickDuration", "tooltipDelay", "controlledSelection", "selectedIds"], outputs: ["datasourceChange", "selectedIdsChange", "onBeforeDrop", "onNodeToggle", "onNodeSelect", "onNodeDoubleClick", "onNodeClick", "onSelectionChange", "onOrderChange", "onMoveChange", "onItemsChange"] }, { kind: "component", type: AXPStateMessageComponent, selector: "axp-state-message", inputs: ["mode", "icon", "title", "description", "titleParams", "descriptionParams", "look"] }, { kind: "ngmodule", type: AXBadgeModule }, { kind: "component", type: i1$3.AXBadgeComponent, selector: "ax-badge", inputs: ["color", "look", "text"] }, { kind: "pipe", type: i3.AXTranslatorPipe, name: "translate" }, { kind: "pipe", type: AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
8196
8420
  }
8197
8421
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPMenuCustomizerComponent, decorators: [{
8198
8422
  type: Component,
@@ -11489,12 +11713,27 @@ class AXPUserAvatarComponent {
11489
11713
  effect((onCleanup) => {
11490
11714
  const id = String(this.userId() ?? '').trim();
11491
11715
  const showPresence = this.showPresence();
11716
+ void this.displayName();
11492
11717
  void this.displayAvatar();
11493
11718
  if (!id) {
11494
- this.userInfo.set(null);
11495
- this.src.set('');
11496
- this.lastResolvedRef = null;
11719
+ const fallbackName = this.displayName()?.trim() ?? '';
11720
+ const fallbackAvatar = this.displayAvatar()?.trim();
11497
11721
  this.presenceStatus.set(null);
11722
+ if (!fallbackName && !fallbackAvatar) {
11723
+ this.userInfo.set(null);
11724
+ this.src.set('');
11725
+ this.lastResolvedRef = null;
11726
+ return;
11727
+ }
11728
+ const fallback = {
11729
+ id: '',
11730
+ status: 'offline',
11731
+ username: fallbackName,
11732
+ firstName: fallbackName,
11733
+ avatarUrl: fallbackAvatar,
11734
+ };
11735
+ this.userInfo.set(fallback);
11736
+ void this.resolveAvatarSrc(fallback, '');
11498
11737
  return;
11499
11738
  }
11500
11739
  const subscriptions = [
@@ -11612,16 +11851,20 @@ class AXPUserAvatarComponent {
11612
11851
  return info.username.trim();
11613
11852
  }
11614
11853
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPUserAvatarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
11615
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: AXPUserAvatarComponent, isStandalone: true, selector: "axp-user-avatar", inputs: { size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, userId: { classPropertyName: "userId", publicName: "userId", isSignal: true, isRequired: false, transformFunction: null }, showPresence: { classPropertyName: "showPresence", publicName: "showPresence", isSignal: true, isRequired: false, transformFunction: null }, displayName: { classPropertyName: "displayName", publicName: "displayName", isSignal: true, isRequired: false, transformFunction: null }, displayAvatar: { classPropertyName: "displayAvatar", publicName: "displayAvatar", isSignal: true, isRequired: false, transformFunction: null } }, providers: [], ngImport: i0, template: "<div\n class=\"axp-user-avatar-wrap\"\n [style.width.px]=\"size()\"\n [style.height.px]=\"size()\"\n>\n <div\n class=\"axp-user-avatar\"\n [class.axp-user-avatar--has-image]=\"!!src()\"\n [style.width.px]=\"size()\"\n [style.height.px]=\"size()\"\n >\n @if (src()) {\n <img\n class=\"axp-user-avatar__image\"\n [src]=\"src()\"\n [attr.alt]=\"title()\"\n [attr.title]=\"title()\"\n />\n } @else {\n <axp-avatar [size]=\"size()\" [fullName]=\"title()\" />\n }\n </div>\n <!-- ----- Live presence indicator from the platform presence store ----- -->\n @if (showPresenceDot()) {\n <span\n class=\"axp-user-avatar__presence\"\n [class.axp-user-avatar__presence--online]=\"isOnline()\"\n [class.axp-user-avatar__presence--away]=\"isAway()\"\n [class.axp-user-avatar__presence--busy]=\"isBusy()\"\n [attr.aria-hidden]=\"true\"\n ></span>\n }\n</div>\n", styles: ["@layer properties;.axp-user-avatar-wrap{position:relative;display:inline-flex;flex-shrink:0}.axp-user-avatar{position:relative;display:inline-flex;flex-shrink:0;align-items:center;justify-content:center;overflow:hidden;border-radius:calc(infinity * 1px);line-height:0}.axp-user-avatar axp-avatar{display:inline-flex;align-items:center;justify-content:center}.axp-user-avatar .axp-user-avatar__image{display:block;width:100%;height:100%;object-fit:cover;object-position:center}.axp-user-avatar--has-image{background-color:var(--color-lighter);color:var(--color-on-lighter);border-color:var(--color-border-lighter)}.axp-user-avatar__presence{pointer-events:none;position:absolute;width:calc(var(--spacing, .25rem) * 2.5);height:calc(var(--spacing, .25rem) * 2.5);border-radius:calc(infinity * 1px);border-style:var(--tw-border-style);border-width:2px;background-color:var(--color-neutral-400, oklch(70.8% 0 none));border-color:rgba(var(--ax-sys-color-border-lightest-surface),1);inset-block-end:0;inset-inline-end:0}.axp-user-avatar__presence--online{background-color:rgba(var(--ax-sys-color-success-surface))}.axp-user-avatar__presence--away{background-color:rgba(var(--ax-sys-color-warning-surface))}.axp-user-avatar__presence--busy{background-color:rgba(var(--ax-sys-color-danger-surface))}@property --tw-border-style{syntax: \"*\"; inherits: false; initial-value: solid;}@layer properties{@supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-border-style: solid}}}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"], dependencies: [{ kind: "component", type: AXPAvatarComponent, selector: "axp-avatar", inputs: ["size", "src", "fullName", "fallbackText", "placeholder"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
11854
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: AXPUserAvatarComponent, isStandalone: true, selector: "axp-user-avatar", inputs: { size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, userId: { classPropertyName: "userId", publicName: "userId", isSignal: true, isRequired: false, transformFunction: null }, showPresence: { classPropertyName: "showPresence", publicName: "showPresence", isSignal: true, isRequired: false, transformFunction: null }, displayName: { classPropertyName: "displayName", publicName: "displayName", isSignal: true, isRequired: false, transformFunction: null }, displayAvatar: { classPropertyName: "displayAvatar", publicName: "displayAvatar", isSignal: true, isRequired: false, transformFunction: null } }, providers: [], ngImport: i0, template: "<div\n class=\"axp-user-avatar-wrap\"\n [style.width.px]=\"size()\"\n [style.height.px]=\"size()\"\n>\n <div\n class=\"axp-user-avatar\"\n [class.axp-user-avatar--has-image]=\"!!src()\"\n [style.width.px]=\"size()\"\n [style.height.px]=\"size()\"\n >\n @if (src()) {\n <img\n class=\"axp-user-avatar__image\"\n [src]=\"src()\"\n [attr.alt]=\"title()\"\n />\n } @else {\n <axp-avatar [size]=\"size()\" [fullName]=\"title()\" [showTitle]=\"false\" />\n }\n </div>\n <!-- ----- Live presence indicator from the platform presence store ----- -->\n @if (showPresenceDot()) {\n <span\n class=\"axp-user-avatar__presence\"\n [class.axp-user-avatar__presence--online]=\"isOnline()\"\n [class.axp-user-avatar__presence--away]=\"isAway()\"\n [class.axp-user-avatar__presence--busy]=\"isBusy()\"\n [attr.aria-hidden]=\"true\"\n ></span>\n }\n</div>\n", styles: ["@layer properties;.axp-user-avatar-wrap{position:relative;display:inline-flex;flex-shrink:0}.axp-user-avatar{position:relative;display:inline-flex;flex-shrink:0;align-items:center;justify-content:center;overflow:hidden;border-radius:calc(infinity * 1px);line-height:0}.axp-user-avatar axp-avatar{display:inline-flex;align-items:center;justify-content:center}.axp-user-avatar .axp-user-avatar__image{display:block;width:100%;height:100%;object-fit:cover;object-position:center}.axp-user-avatar--has-image{background-color:var(--color-lighter);color:var(--color-on-lighter);border-color:var(--color-border-lighter)}.axp-user-avatar__presence{pointer-events:none;position:absolute;width:calc(var(--spacing, .25rem) * 2.5);height:calc(var(--spacing, .25rem) * 2.5);border-radius:calc(infinity * 1px);border-style:var(--tw-border-style);border-width:2px;background-color:var(--color-neutral-400, oklch(70.8% 0 none));border-color:rgba(var(--ax-sys-color-border-lightest-surface),1);inset-block-end:0;inset-inline-end:0}.axp-user-avatar__presence--online{background-color:rgba(var(--ax-sys-color-success-surface))}.axp-user-avatar__presence--away{background-color:rgba(var(--ax-sys-color-warning-surface))}.axp-user-avatar__presence--busy{background-color:rgba(var(--ax-sys-color-danger-surface))}@property --tw-border-style{syntax: \"*\"; inherits: false; initial-value: solid;}@layer properties{@supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-border-style: solid}}}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"], dependencies: [{ kind: "component", type: AXPAvatarComponent, selector: "axp-avatar", inputs: ["size", "src", "fullName", "showTitle", "fallbackText", "placeholder"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
11616
11855
  }
11617
11856
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPUserAvatarComponent, decorators: [{
11618
11857
  type: Component,
11619
- args: [{ selector: 'axp-user-avatar', imports: [AXPAvatarComponent], encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, providers: [], template: "<div\n class=\"axp-user-avatar-wrap\"\n [style.width.px]=\"size()\"\n [style.height.px]=\"size()\"\n>\n <div\n class=\"axp-user-avatar\"\n [class.axp-user-avatar--has-image]=\"!!src()\"\n [style.width.px]=\"size()\"\n [style.height.px]=\"size()\"\n >\n @if (src()) {\n <img\n class=\"axp-user-avatar__image\"\n [src]=\"src()\"\n [attr.alt]=\"title()\"\n [attr.title]=\"title()\"\n />\n } @else {\n <axp-avatar [size]=\"size()\" [fullName]=\"title()\" />\n }\n </div>\n <!-- ----- Live presence indicator from the platform presence store ----- -->\n @if (showPresenceDot()) {\n <span\n class=\"axp-user-avatar__presence\"\n [class.axp-user-avatar__presence--online]=\"isOnline()\"\n [class.axp-user-avatar__presence--away]=\"isAway()\"\n [class.axp-user-avatar__presence--busy]=\"isBusy()\"\n [attr.aria-hidden]=\"true\"\n ></span>\n }\n</div>\n", styles: ["@layer properties;.axp-user-avatar-wrap{position:relative;display:inline-flex;flex-shrink:0}.axp-user-avatar{position:relative;display:inline-flex;flex-shrink:0;align-items:center;justify-content:center;overflow:hidden;border-radius:calc(infinity * 1px);line-height:0}.axp-user-avatar axp-avatar{display:inline-flex;align-items:center;justify-content:center}.axp-user-avatar .axp-user-avatar__image{display:block;width:100%;height:100%;object-fit:cover;object-position:center}.axp-user-avatar--has-image{background-color:var(--color-lighter);color:var(--color-on-lighter);border-color:var(--color-border-lighter)}.axp-user-avatar__presence{pointer-events:none;position:absolute;width:calc(var(--spacing, .25rem) * 2.5);height:calc(var(--spacing, .25rem) * 2.5);border-radius:calc(infinity * 1px);border-style:var(--tw-border-style);border-width:2px;background-color:var(--color-neutral-400, oklch(70.8% 0 none));border-color:rgba(var(--ax-sys-color-border-lightest-surface),1);inset-block-end:0;inset-inline-end:0}.axp-user-avatar__presence--online{background-color:rgba(var(--ax-sys-color-success-surface))}.axp-user-avatar__presence--away{background-color:rgba(var(--ax-sys-color-warning-surface))}.axp-user-avatar__presence--busy{background-color:rgba(var(--ax-sys-color-danger-surface))}@property --tw-border-style{syntax: \"*\"; inherits: false; initial-value: solid;}@layer properties{@supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-border-style: solid}}}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"] }]
11858
+ args: [{ selector: 'axp-user-avatar', imports: [AXPAvatarComponent], encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, providers: [], template: "<div\n class=\"axp-user-avatar-wrap\"\n [style.width.px]=\"size()\"\n [style.height.px]=\"size()\"\n>\n <div\n class=\"axp-user-avatar\"\n [class.axp-user-avatar--has-image]=\"!!src()\"\n [style.width.px]=\"size()\"\n [style.height.px]=\"size()\"\n >\n @if (src()) {\n <img\n class=\"axp-user-avatar__image\"\n [src]=\"src()\"\n [attr.alt]=\"title()\"\n />\n } @else {\n <axp-avatar [size]=\"size()\" [fullName]=\"title()\" [showTitle]=\"false\" />\n }\n </div>\n <!-- ----- Live presence indicator from the platform presence store ----- -->\n @if (showPresenceDot()) {\n <span\n class=\"axp-user-avatar__presence\"\n [class.axp-user-avatar__presence--online]=\"isOnline()\"\n [class.axp-user-avatar__presence--away]=\"isAway()\"\n [class.axp-user-avatar__presence--busy]=\"isBusy()\"\n [attr.aria-hidden]=\"true\"\n ></span>\n }\n</div>\n", styles: ["@layer properties;.axp-user-avatar-wrap{position:relative;display:inline-flex;flex-shrink:0}.axp-user-avatar{position:relative;display:inline-flex;flex-shrink:0;align-items:center;justify-content:center;overflow:hidden;border-radius:calc(infinity * 1px);line-height:0}.axp-user-avatar axp-avatar{display:inline-flex;align-items:center;justify-content:center}.axp-user-avatar .axp-user-avatar__image{display:block;width:100%;height:100%;object-fit:cover;object-position:center}.axp-user-avatar--has-image{background-color:var(--color-lighter);color:var(--color-on-lighter);border-color:var(--color-border-lighter)}.axp-user-avatar__presence{pointer-events:none;position:absolute;width:calc(var(--spacing, .25rem) * 2.5);height:calc(var(--spacing, .25rem) * 2.5);border-radius:calc(infinity * 1px);border-style:var(--tw-border-style);border-width:2px;background-color:var(--color-neutral-400, oklch(70.8% 0 none));border-color:rgba(var(--ax-sys-color-border-lightest-surface),1);inset-block-end:0;inset-inline-end:0}.axp-user-avatar__presence--online{background-color:rgba(var(--ax-sys-color-success-surface))}.axp-user-avatar__presence--away{background-color:rgba(var(--ax-sys-color-warning-surface))}.axp-user-avatar__presence--busy{background-color:rgba(var(--ax-sys-color-danger-surface))}@property --tw-border-style{syntax: \"*\"; inherits: false; initial-value: solid;}@layer properties{@supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-border-style: solid}}}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"] }]
11620
11859
  }], ctorParameters: () => [], propDecorators: { size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], userId: [{ type: i0.Input, args: [{ isSignal: true, alias: "userId", required: false }] }], showPresence: [{ type: i0.Input, args: [{ isSignal: true, alias: "showPresence", required: false }] }], displayName: [{ type: i0.Input, args: [{ isSignal: true, alias: "displayName", required: false }] }], displayAvatar: [{ type: i0.Input, args: [{ isSignal: true, alias: "displayAvatar", required: false }] }] } });
11621
11860
 
11622
11861
  //#region ----- Hook keys -----
11623
11862
  /** Waterfall hook: modules append identity chips and CTAs for a user card. */
11624
11863
  const USER_CARD_ITEMS_HOOK = 'user-card.items';
11864
+ /** Hover must stay on the host this long before the overlay opens. */
11865
+ const USER_CARD_HOVER_OPEN_DELAY_MS = 400;
11866
+ /** Show badge/action skeletons only if extras are still loading after this delay. */
11867
+ const USER_CARD_ITEMS_SKELETON_DELAY_MS = 150;
11625
11868
  //#endregion
11626
11869
  //#region ----- Helpers -----
11627
11870
  /** Visible card CTAs (`visible === false` hides the item). */
@@ -11735,6 +11978,8 @@ class AXPUserCardComponent {
11735
11978
  ...(ngDevMode ? [{ debugName: "extraRows" }] : /* istanbul ignore next */ []));
11736
11979
  this.extraActions = signal([], /* @ts-ignore */
11737
11980
  ...(ngDevMode ? [{ debugName: "extraActions" }] : /* istanbul ignore next */ []));
11981
+ this.itemsLoading = signal(false, /* @ts-ignore */
11982
+ ...(ngDevMode ? [{ debugName: "itemsLoading" }] : /* istanbul ignore next */ []));
11738
11983
  this.displayName = computed(() => this.resolveDisplayName(this.identity()), /* @ts-ignore */
11739
11984
  ...(ngDevMode ? [{ debugName: "displayName" }] : /* istanbul ignore next */ []));
11740
11985
  this.username = computed(() => this.identity()?.username?.trim() || '', /* @ts-ignore */
@@ -11808,18 +12053,25 @@ class AXPUserCardComponent {
11808
12053
  if (cached) {
11809
12054
  this.extraRows.set(cached.rows);
11810
12055
  this.extraActions.set(cached.actions);
12056
+ this.itemsLoading.set(false);
11811
12057
  return;
11812
12058
  }
11813
- const payload = await this.hooks.runAsync(USER_CARD_ITEMS_HOOK, {
11814
- userId,
11815
- rows: [],
11816
- actions: [],
11817
- });
11818
- const rows = sortUserCardRows(payload.rows ?? []);
11819
- const actions = sortUserCardActions(visibleUserCardActions(payload.actions ?? []));
11820
- this.itemsCache.set(userId, { rows, actions });
11821
- this.extraRows.set(rows);
11822
- this.extraActions.set(actions);
12059
+ this.itemsLoading.set(true);
12060
+ try {
12061
+ const payload = await this.hooks.runAsync(USER_CARD_ITEMS_HOOK, {
12062
+ userId,
12063
+ rows: [],
12064
+ actions: [],
12065
+ });
12066
+ const rows = sortUserCardRows(payload.rows ?? []);
12067
+ const actions = sortUserCardActions(visibleUserCardActions(payload.actions ?? []));
12068
+ this.itemsCache.set(userId, { rows, actions });
12069
+ this.extraRows.set(rows);
12070
+ this.extraActions.set(actions);
12071
+ }
12072
+ finally {
12073
+ this.itemsLoading.set(false);
12074
+ }
11823
12075
  }
11824
12076
  async refreshTooltip(presence) {
11825
12077
  this.clearTooltipTimer();
@@ -11907,7 +12159,7 @@ class AXPUserCardComponent {
11907
12159
  }
11908
12160
  }
11909
12161
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPUserCardComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
11910
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: AXPUserCardComponent, isStandalone: true, selector: "axp-user-card", inputs: { userId: { classPropertyName: "userId", publicName: "userId", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: "<div class=\"axp-user-card lightest-surface dark:dark-surface\">\n <!-- ----- Presence badge in the top-right of the card ----- -->\n @if (showPresence()) {\n <span\n class=\"axp-user-card__presence\"\n [axTooltip]=\"tooltipText()\"\n [axTooltipDisabled]=\"tooltipDisabled()\"\n axTooltipPlacement=\"bottom\"\n >\n <ax-badge\n size=\"sm\"\n look=\"twotone\"\n [color]=\"presenceBadgeColor()\"\n [text]=\"(presenceLabelKey() | translate | async) ?? ''\"\n ></ax-badge>\n </span>\n }\n\n <div class=\"axp-user-card__identity\">\n <axp-user-avatar [size]=\"56\" [userId]=\"userId()\" [showPresence]=\"false\"></axp-user-avatar>\n <div class=\"axp-user-card__names\">\n <div class=\"axp-user-card__name\">{{ displayName() }}</div>\n <!-- ----- Username when the identity cache has one ----- -->\n @if (username()) {\n <div class=\"axp-user-card__username\">@{{ username() }}</div>\n }\n </div>\n </div>\n\n <!-- ----- Contributed identity chips (position, business unit, \u2026) ----- -->\n @if (extraRows().length > 0) {\n <div class=\"axp-user-card__badges\">\n @for (row of extraRows(); track row.id) {\n <span\n class=\"axp-user-card__badge\"\n [axTooltip]=\"(row.label | translate | async) ?? ''\"\n axTooltipPlacement=\"bottom\"\n >\n <ax-badge\n size=\"sm\"\n look=\"twotone\"\n color=\"primary\"\n [text]=\"(row.value | translate | async) ?? ''\"\n ></ax-badge>\n </span>\n }\n </div>\n }\n\n <!-- ----- Contributed CTAs: button, or dropdown when the action has nested items ----- -->\n @if (extraActions().length > 0) {\n <div class=\"axp-user-card__actions ax-xs\">\n @for (action of extraActions(); track action.name || action.title) {\n <ax-button\n class=\"axp-user-card__action\"\n look=\"outline\"\n [text]=\"(actionTitle(action) | translate | async) ?? ''\"\n [disabled]=\"action.disabled\"\n [color]=\"action.color\"\n (onClick)=\"onActionClick(action)\"\n >\n <!-- ----- Action icon when the contributor provided one ----- -->\n @if (action.icon) {\n <ax-prefix>\n <ax-icon [icon]=\"action.icon\"></ax-icon>\n </ax-prefix>\n }\n <!-- ----- Nested items turn the CTA into a dropdown ----- -->\n @if (nestedActions(action).length > 0) {\n <ax-dropdown-panel>\n <ax-button-item-list>\n @for (sub of nestedActions(action); track sub.name || sub.title) {\n <!-- ----- Visible nested action ----- -->\n @if (sub.visible != false) {\n <ax-button-item\n [text]=\"(actionTitle(sub) | translate | async) ?? ''\"\n [color]=\"sub.color\"\n [disabled]=\"sub.disabled\"\n (onClick)=\"onNestedActionClick(sub)\"\n >\n <!-- ----- Nested action icon ----- -->\n @if (sub.icon) {\n <ax-prefix>\n <ax-icon [icon]=\"sub.icon\"></ax-icon>\n </ax-prefix>\n }\n </ax-button-item>\n <!-- ----- Divider after a nested item marked as a break ----- -->\n @if (sub.break) {\n <ax-divider></ax-divider>\n }\n }\n }\n </ax-button-item-list>\n </ax-dropdown-panel>\n }\n </ax-button>\n }\n </div>\n }\n</div>\n", styles: ["@layer properties;.axp-user-card{position:relative;display:flex;max-width:20rem;min-width:16rem;flex-direction:column;gap:calc(var(--spacing, .25rem) * 3);border-radius:var(--radius-lg, .5rem);padding:calc(var(--spacing, .25rem) * 4);--tw-shadow: 0 10px 15px -3px var(--tw-shadow-color, rgb(0 0 0 / .1)), 0 4px 6px -4px var(--tw-shadow-color, rgb(0 0 0 / .1));box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.axp-user-card__presence{position:absolute;inset-inline-end:calc(var(--spacing, .25rem) * 3);top:calc(var(--spacing, .25rem) * 3);z-index:10;display:inline-flex;flex-shrink:0}.axp-user-card__identity{display:flex;align-items:center;gap:calc(var(--spacing, .25rem) * 3);padding-inline-end:calc(var(--spacing, .25rem) * 16)}.axp-user-card__names{min-width:0px;flex:1}.axp-user-card__name{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:var(--text-base, 1rem);line-height:var(--tw-leading, var(--text-base--line-height, 1.5 ));--tw-font-weight: var(--font-weight-semibold, 600);font-weight:var(--font-weight-semibold, 600)}.axp-user-card__username{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:var(--text-xs, .75rem);line-height:var(--tw-leading, var(--text-xs--line-height, calc(1 / .75)));color:var(--color-neutral-500, oklch(55.6% 0 none))}.axp-user-card__badges{display:flex;flex-wrap:wrap;gap:calc(var(--spacing, .25rem) * 1.5);border-top-style:var(--tw-border-style);border-top-width:1px;padding-top:calc(var(--spacing, .25rem) * 2)}.axp-user-card__badge{max-width:100%}.axp-user-card__actions{display:flex;flex-wrap:wrap;gap:calc(var(--spacing, .25rem) * 2);border-top-style:var(--tw-border-style);border-top-width:1px;padding-top:calc(var(--spacing, .25rem) * 2)}.axp-user-card__action{min-width:0px}@property --tw-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-shadow-color{syntax: \"*\"; inherits: false;}@property --tw-shadow-alpha{syntax: \"<percentage>\"; inherits: false; initial-value: 100%;}@property --tw-inset-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-inset-shadow-color{syntax: \"*\"; inherits: false;}@property --tw-inset-shadow-alpha{syntax: \"<percentage>\"; inherits: false; initial-value: 100%;}@property --tw-ring-color{syntax: \"*\"; inherits: false;}@property --tw-ring-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-inset-ring-color{syntax: \"*\"; inherits: false;}@property --tw-inset-ring-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-ring-inset{syntax: \"*\"; inherits: false;}@property --tw-ring-offset-width{syntax: \"<length>\"; inherits: false; initial-value: 0px;}@property --tw-ring-offset-color{syntax: \"*\"; inherits: false; initial-value: #fff;}@property --tw-ring-offset-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-font-weight{syntax: \"*\"; inherits: false;}@property --tw-border-style{syntax: \"*\"; inherits: false; initial-value: solid;}@layer properties{@supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-shadow: 0 0 #0000;--tw-shadow-color: initial;--tw-shadow-alpha: 100%;--tw-inset-shadow: 0 0 #0000;--tw-inset-shadow-color: initial;--tw-inset-shadow-alpha: 100%;--tw-ring-color: initial;--tw-ring-shadow: 0 0 #0000;--tw-inset-ring-color: initial;--tw-inset-ring-shadow: 0 0 #0000;--tw-ring-inset: initial;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-offset-shadow: 0 0 #0000;--tw-font-weight: initial;--tw-border-style: solid}}}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"], dependencies: [{ kind: "component", type: AXPUserAvatarComponent, selector: "axp-user-avatar", inputs: ["size", "userId", "showPresence", "displayName", "displayAvatar"] }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "ngmodule", type: AXBadgeModule }, { kind: "component", type: i1$3.AXBadgeComponent, selector: "ax-badge", inputs: ["color", "look", "text"] }, { kind: "ngmodule", type: AXButtonModule }, { kind: "component", type: i1$2.AXButtonComponent, selector: "ax-button", inputs: ["disabled", "size", "tabIndex", "color", "look", "text", "toggleable", "selected", "iconOnly", "type", "loadingText"], outputs: ["onBlur", "onFocus", "onClick", "selectedChange", "toggleableChange", "lookChange", "colorChange", "disabledChange", "loadingTextChange"] }, { kind: "component", type: i1$2.AXButtonItemComponent, selector: "ax-button-item", inputs: ["color", "disabled", "text", "selected", "divided", "data", "name"], outputs: ["onClick", "onFocus", "onBlur", "disabledChange"] }, { kind: "component", type: i1$2.AXButtonItemListComponent, selector: "ax-button-item-list", inputs: ["items", "closeParentOnClick", "lockOnLoading"], outputs: ["onItemClick"] }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i2$1.AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { kind: "component", type: i2$1.AXDecoratorGenericComponent, selector: "ax-footer, ax-header, ax-content, ax-divider, ax-form-hint, ax-prefix, ax-suffix, ax-text, ax-title, ax-subtitle, ax-placeholder, ax-overlay" }, { kind: "ngmodule", type: AXDropdownModule }, { kind: "component", type: i5$1.AXDropdownPanelComponent, selector: "ax-dropdown-panel", inputs: ["isOpen", "fitParent", "dropdownWidth", "position", "placement", "_target", "adaptivityEnabled"], outputs: ["onOpened", "onClosed"] }, { kind: "ngmodule", type: AXTooltipModule }, { kind: "directive", type: i5$3.AXTooltipDirective, selector: "[axTooltip]", inputs: ["axTooltipDisabled", "axTooltip", "axTooltipContext", "axTooltipPlacement", "axTooltipOffsetX", "axTooltipOffsetY", "axTooltipOpenAfter", "axTooltipCloseAfter"] }, { kind: "pipe", type: i3.AXTranslatorPipe, name: "translate" }, { kind: "pipe", type: AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
12162
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: AXPUserCardComponent, isStandalone: true, selector: "axp-user-card", inputs: { userId: { classPropertyName: "userId", publicName: "userId", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: "<div class=\"axp-user-card lightest-surface dark:dark-surface\">\n <!-- ----- Presence badge in the top-right of the card ----- -->\n @if (showPresence()) {\n <span\n class=\"axp-user-card__presence\"\n [axTooltip]=\"tooltipText()\"\n [axTooltipDisabled]=\"tooltipDisabled()\"\n axTooltipPlacement=\"bottom\"\n >\n <ax-badge\n size=\"sm\"\n look=\"twotone\"\n [color]=\"presenceBadgeColor()\"\n [text]=\"(presenceLabelKey() | translate | async) ?? ''\"\n ></ax-badge>\n </span>\n }\n\n <div class=\"axp-user-card__identity\">\n <axp-user-avatar [size]=\"56\" [userId]=\"userId()\" [showPresence]=\"false\"></axp-user-avatar>\n <div class=\"axp-user-card__names\">\n <div class=\"axp-user-card__name\">{{ displayName() }}</div>\n <!-- ----- Username when the identity cache has one ----- -->\n @if (username()) {\n <div class=\"axp-user-card__username\">@{{ username() }}</div>\n }\n </div>\n </div>\n\n <!-- ----- Placeholder extras while contributed items are still loading ----- -->\n @if (itemsLoading()) {\n <div class=\"axp-user-card__badges\" aria-hidden=\"true\">\n <ax-skeleton [animated]=\"true\" class=\"axp-user-card__skeleton-badge\"></ax-skeleton>\n <ax-skeleton [animated]=\"true\" class=\"axp-user-card__skeleton-badge axp-user-card__skeleton-badge--wide\"></ax-skeleton>\n </div>\n <div class=\"axp-user-card__actions\" aria-hidden=\"true\">\n <ax-skeleton [animated]=\"true\" class=\"axp-user-card__skeleton-action\"></ax-skeleton>\n </div>\n }\n\n <!-- ----- Contributed identity chips (position, business unit, \u2026) ----- -->\n @if (!itemsLoading() && extraRows().length > 0) {\n <div class=\"axp-user-card__badges\">\n @for (row of extraRows(); track row.id) {\n <span\n class=\"axp-user-card__badge\"\n [axTooltip]=\"(row.label | translate | async) ?? ''\"\n axTooltipPlacement=\"bottom\"\n >\n <ax-badge\n size=\"sm\"\n look=\"twotone\"\n color=\"primary\"\n [text]=\"(row.value | translate | async) ?? ''\"\n ></ax-badge>\n </span>\n }\n </div>\n }\n\n <!-- ----- Contributed CTAs: button, or dropdown when the action has nested items ----- -->\n @if (!itemsLoading() && extraActions().length > 0) {\n <div class=\"axp-user-card__actions\">\n @for (action of extraActions(); track action.name || action.title) {\n <ax-button\n class=\"axp-user-card__action ax-xs\"\n look=\"outline\"\n [text]=\"(actionTitle(action) | translate | async) ?? ''\"\n [disabled]=\"action.disabled\"\n [color]=\"action.color\"\n (onClick)=\"onActionClick(action)\"\n >\n <!-- ----- Action icon when the contributor provided one ----- -->\n @if (action.icon) {\n <ax-prefix>\n <ax-icon [icon]=\"action.icon\"></ax-icon>\n </ax-prefix>\n }\n <!-- ----- Nested items turn the CTA into a dropdown ----- -->\n @if (nestedActions(action).length > 0) {\n <ax-dropdown-panel>\n <ax-button-item-list>\n @for (sub of nestedActions(action); track sub.name || sub.title) {\n <!-- ----- Visible nested action ----- -->\n @if (sub.visible != false) {\n <ax-button-item\n [text]=\"(actionTitle(sub) | translate | async) ?? ''\"\n [color]=\"sub.color\"\n [disabled]=\"sub.disabled\"\n (onClick)=\"onNestedActionClick(sub)\"\n >\n <!-- ----- Nested action icon ----- -->\n @if (sub.icon) {\n <ax-prefix>\n <ax-icon [icon]=\"sub.icon\"></ax-icon>\n </ax-prefix>\n }\n </ax-button-item>\n <!-- ----- Divider after a nested item marked as a break ----- -->\n @if (sub.break) {\n <ax-divider></ax-divider>\n }\n }\n }\n </ax-button-item-list>\n </ax-dropdown-panel>\n }\n </ax-button>\n }\n </div>\n }\n</div>\n", styles: ["@layer properties;:host{display:block;min-width:20rem;width:20rem;max-width:min(24rem,calc(100vw - 2rem))}.axp-user-card{position:relative;display:flex;width:100%;max-width:24rem;min-width:20rem;flex-direction:column;gap:calc(var(--spacing, .25rem) * 3);border-radius:var(--radius-lg, .5rem);padding:calc(var(--spacing, .25rem) * 4);--tw-shadow: 0 10px 15px -3px var(--tw-shadow-color, rgb(0 0 0 / .1)), 0 4px 6px -4px var(--tw-shadow-color, rgb(0 0 0 / .1));box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.axp-user-card-overlay,.axp-user-card-overlay.ax-overlay-container,.axp-user-card-overlay.ax-overlay-pane,.axp-user-card-overlay .ax-overlay-pane,.axp-user-card-overlay .overlay-pane{min-width:20rem;width:20rem;max-width:min(24rem,calc(100vw - 2rem))}.axp-user-card-overlay--pending,.axp-user-card-overlay--pending.ax-overlay-container,.axp-user-card-overlay--pending.ax-overlay-pane,.axp-user-card-overlay--pending .ax-overlay-pane,.axp-user-card-overlay--pending .overlay-pane{visibility:hidden;pointer-events:none}.axp-user-card__presence{position:absolute;inset-inline-end:calc(var(--spacing, .25rem) * 3);top:calc(var(--spacing, .25rem) * 3);z-index:10;display:inline-flex;flex-shrink:0}.axp-user-card__identity{display:flex;align-items:center;gap:calc(var(--spacing, .25rem) * 3);padding-inline-end:calc(var(--spacing, .25rem) * 16)}.axp-user-card__names{min-width:0px;flex:1}.axp-user-card__name{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:var(--text-base, 1rem);line-height:var(--tw-leading, var(--text-base--line-height, 1.5 ));--tw-font-weight: var(--font-weight-semibold, 600);font-weight:var(--font-weight-semibold, 600)}.axp-user-card__username{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:var(--text-xs, .75rem);line-height:var(--tw-leading, var(--text-xs--line-height, calc(1 / .75)));color:var(--color-neutral-500, oklch(55.6% 0 none))}.axp-user-card__badges{display:flex;flex-wrap:wrap;gap:calc(var(--spacing, .25rem) * 1.5);border-top-style:var(--tw-border-style);border-top-width:1px;padding-top:calc(var(--spacing, .25rem) * 2)}.axp-user-card__badge{max-width:100%}.axp-user-card__actions{display:flex;flex-wrap:wrap;gap:calc(var(--spacing, .25rem) * 2);border-top-style:var(--tw-border-style);border-top-width:1px;padding-top:calc(var(--spacing, .25rem) * 2)}.axp-user-card__action{min-width:0px}.axp-user-card__skeleton-badge{height:calc(var(--spacing, .25rem) * 5);width:calc(var(--spacing, .25rem) * 20);border-radius:calc(infinity * 1px)}.axp-user-card__skeleton-badge--wide{width:calc(var(--spacing, .25rem) * 36)}.axp-user-card__skeleton-action{height:calc(var(--spacing, .25rem) * 6);width:calc(var(--spacing, .25rem) * 24);border-radius:var(--radius-md, .375rem)}@property --tw-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-shadow-color{syntax: \"*\"; inherits: false;}@property --tw-shadow-alpha{syntax: \"<percentage>\"; inherits: false; initial-value: 100%;}@property --tw-inset-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-inset-shadow-color{syntax: \"*\"; inherits: false;}@property --tw-inset-shadow-alpha{syntax: \"<percentage>\"; inherits: false; initial-value: 100%;}@property --tw-ring-color{syntax: \"*\"; inherits: false;}@property --tw-ring-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-inset-ring-color{syntax: \"*\"; inherits: false;}@property --tw-inset-ring-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-ring-inset{syntax: \"*\"; inherits: false;}@property --tw-ring-offset-width{syntax: \"<length>\"; inherits: false; initial-value: 0px;}@property --tw-ring-offset-color{syntax: \"*\"; inherits: false; initial-value: #fff;}@property --tw-ring-offset-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-font-weight{syntax: \"*\"; inherits: false;}@property --tw-border-style{syntax: \"*\"; inherits: false; initial-value: solid;}@layer properties{@supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-shadow: 0 0 #0000;--tw-shadow-color: initial;--tw-shadow-alpha: 100%;--tw-inset-shadow: 0 0 #0000;--tw-inset-shadow-color: initial;--tw-inset-shadow-alpha: 100%;--tw-ring-color: initial;--tw-ring-shadow: 0 0 #0000;--tw-inset-ring-color: initial;--tw-inset-ring-shadow: 0 0 #0000;--tw-ring-inset: initial;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-offset-shadow: 0 0 #0000;--tw-font-weight: initial;--tw-border-style: solid}}}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"], dependencies: [{ kind: "component", type: AXPUserAvatarComponent, selector: "axp-user-avatar", inputs: ["size", "userId", "showPresence", "displayName", "displayAvatar"] }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "ngmodule", type: AXBadgeModule }, { kind: "component", type: i1$3.AXBadgeComponent, selector: "ax-badge", inputs: ["color", "look", "text"] }, { kind: "ngmodule", type: AXButtonModule }, { kind: "component", type: i1$2.AXButtonComponent, selector: "ax-button", inputs: ["disabled", "size", "tabIndex", "color", "look", "text", "toggleable", "selected", "iconOnly", "type", "loadingText"], outputs: ["onBlur", "onFocus", "onClick", "selectedChange", "toggleableChange", "lookChange", "colorChange", "disabledChange", "loadingTextChange"] }, { kind: "component", type: i1$2.AXButtonItemComponent, selector: "ax-button-item", inputs: ["color", "disabled", "text", "selected", "divided", "data", "name"], outputs: ["onClick", "onFocus", "onBlur", "disabledChange"] }, { kind: "component", type: i1$2.AXButtonItemListComponent, selector: "ax-button-item-list", inputs: ["items", "closeParentOnClick", "lockOnLoading"], outputs: ["onItemClick"] }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i2$1.AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { kind: "component", type: i2$1.AXDecoratorGenericComponent, selector: "ax-footer, ax-header, ax-content, ax-divider, ax-form-hint, ax-prefix, ax-suffix, ax-text, ax-title, ax-subtitle, ax-placeholder, ax-overlay" }, { kind: "ngmodule", type: AXDropdownModule }, { kind: "component", type: i5$1.AXDropdownPanelComponent, selector: "ax-dropdown-panel", inputs: ["isOpen", "fitParent", "dropdownWidth", "position", "placement", "_target", "adaptivityEnabled"], outputs: ["onOpened", "onClosed"] }, { kind: "ngmodule", type: AXSkeletonModule }, { kind: "component", type: i2.AXSkeletonComponent, selector: "ax-skeleton", inputs: ["animated"] }, { kind: "ngmodule", type: AXTooltipModule }, { kind: "directive", type: i6.AXTooltipDirective, selector: "[axTooltip]", inputs: ["axTooltipDisabled", "axTooltip", "axTooltipContext", "axTooltipPlacement", "axTooltipOffsetX", "axTooltipOffsetY", "axTooltipOpenAfter", "axTooltipCloseAfter"] }, { kind: "pipe", type: i3.AXTranslatorPipe, name: "translate" }, { kind: "pipe", type: AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
11911
12163
  }
11912
12164
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPUserCardComponent, decorators: [{
11913
12165
  type: Component,
@@ -11919,8 +12171,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
11919
12171
  AXButtonModule,
11920
12172
  AXDecoratorModule,
11921
12173
  AXDropdownModule,
12174
+ AXSkeletonModule,
11922
12175
  AXTooltipModule,
11923
- ], encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"axp-user-card lightest-surface dark:dark-surface\">\n <!-- ----- Presence badge in the top-right of the card ----- -->\n @if (showPresence()) {\n <span\n class=\"axp-user-card__presence\"\n [axTooltip]=\"tooltipText()\"\n [axTooltipDisabled]=\"tooltipDisabled()\"\n axTooltipPlacement=\"bottom\"\n >\n <ax-badge\n size=\"sm\"\n look=\"twotone\"\n [color]=\"presenceBadgeColor()\"\n [text]=\"(presenceLabelKey() | translate | async) ?? ''\"\n ></ax-badge>\n </span>\n }\n\n <div class=\"axp-user-card__identity\">\n <axp-user-avatar [size]=\"56\" [userId]=\"userId()\" [showPresence]=\"false\"></axp-user-avatar>\n <div class=\"axp-user-card__names\">\n <div class=\"axp-user-card__name\">{{ displayName() }}</div>\n <!-- ----- Username when the identity cache has one ----- -->\n @if (username()) {\n <div class=\"axp-user-card__username\">@{{ username() }}</div>\n }\n </div>\n </div>\n\n <!-- ----- Contributed identity chips (position, business unit, \u2026) ----- -->\n @if (extraRows().length > 0) {\n <div class=\"axp-user-card__badges\">\n @for (row of extraRows(); track row.id) {\n <span\n class=\"axp-user-card__badge\"\n [axTooltip]=\"(row.label | translate | async) ?? ''\"\n axTooltipPlacement=\"bottom\"\n >\n <ax-badge\n size=\"sm\"\n look=\"twotone\"\n color=\"primary\"\n [text]=\"(row.value | translate | async) ?? ''\"\n ></ax-badge>\n </span>\n }\n </div>\n }\n\n <!-- ----- Contributed CTAs: button, or dropdown when the action has nested items ----- -->\n @if (extraActions().length > 0) {\n <div class=\"axp-user-card__actions ax-xs\">\n @for (action of extraActions(); track action.name || action.title) {\n <ax-button\n class=\"axp-user-card__action\"\n look=\"outline\"\n [text]=\"(actionTitle(action) | translate | async) ?? ''\"\n [disabled]=\"action.disabled\"\n [color]=\"action.color\"\n (onClick)=\"onActionClick(action)\"\n >\n <!-- ----- Action icon when the contributor provided one ----- -->\n @if (action.icon) {\n <ax-prefix>\n <ax-icon [icon]=\"action.icon\"></ax-icon>\n </ax-prefix>\n }\n <!-- ----- Nested items turn the CTA into a dropdown ----- -->\n @if (nestedActions(action).length > 0) {\n <ax-dropdown-panel>\n <ax-button-item-list>\n @for (sub of nestedActions(action); track sub.name || sub.title) {\n <!-- ----- Visible nested action ----- -->\n @if (sub.visible != false) {\n <ax-button-item\n [text]=\"(actionTitle(sub) | translate | async) ?? ''\"\n [color]=\"sub.color\"\n [disabled]=\"sub.disabled\"\n (onClick)=\"onNestedActionClick(sub)\"\n >\n <!-- ----- Nested action icon ----- -->\n @if (sub.icon) {\n <ax-prefix>\n <ax-icon [icon]=\"sub.icon\"></ax-icon>\n </ax-prefix>\n }\n </ax-button-item>\n <!-- ----- Divider after a nested item marked as a break ----- -->\n @if (sub.break) {\n <ax-divider></ax-divider>\n }\n }\n }\n </ax-button-item-list>\n </ax-dropdown-panel>\n }\n </ax-button>\n }\n </div>\n }\n</div>\n", styles: ["@layer properties;.axp-user-card{position:relative;display:flex;max-width:20rem;min-width:16rem;flex-direction:column;gap:calc(var(--spacing, .25rem) * 3);border-radius:var(--radius-lg, .5rem);padding:calc(var(--spacing, .25rem) * 4);--tw-shadow: 0 10px 15px -3px var(--tw-shadow-color, rgb(0 0 0 / .1)), 0 4px 6px -4px var(--tw-shadow-color, rgb(0 0 0 / .1));box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.axp-user-card__presence{position:absolute;inset-inline-end:calc(var(--spacing, .25rem) * 3);top:calc(var(--spacing, .25rem) * 3);z-index:10;display:inline-flex;flex-shrink:0}.axp-user-card__identity{display:flex;align-items:center;gap:calc(var(--spacing, .25rem) * 3);padding-inline-end:calc(var(--spacing, .25rem) * 16)}.axp-user-card__names{min-width:0px;flex:1}.axp-user-card__name{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:var(--text-base, 1rem);line-height:var(--tw-leading, var(--text-base--line-height, 1.5 ));--tw-font-weight: var(--font-weight-semibold, 600);font-weight:var(--font-weight-semibold, 600)}.axp-user-card__username{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:var(--text-xs, .75rem);line-height:var(--tw-leading, var(--text-xs--line-height, calc(1 / .75)));color:var(--color-neutral-500, oklch(55.6% 0 none))}.axp-user-card__badges{display:flex;flex-wrap:wrap;gap:calc(var(--spacing, .25rem) * 1.5);border-top-style:var(--tw-border-style);border-top-width:1px;padding-top:calc(var(--spacing, .25rem) * 2)}.axp-user-card__badge{max-width:100%}.axp-user-card__actions{display:flex;flex-wrap:wrap;gap:calc(var(--spacing, .25rem) * 2);border-top-style:var(--tw-border-style);border-top-width:1px;padding-top:calc(var(--spacing, .25rem) * 2)}.axp-user-card__action{min-width:0px}@property --tw-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-shadow-color{syntax: \"*\"; inherits: false;}@property --tw-shadow-alpha{syntax: \"<percentage>\"; inherits: false; initial-value: 100%;}@property --tw-inset-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-inset-shadow-color{syntax: \"*\"; inherits: false;}@property --tw-inset-shadow-alpha{syntax: \"<percentage>\"; inherits: false; initial-value: 100%;}@property --tw-ring-color{syntax: \"*\"; inherits: false;}@property --tw-ring-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-inset-ring-color{syntax: \"*\"; inherits: false;}@property --tw-inset-ring-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-ring-inset{syntax: \"*\"; inherits: false;}@property --tw-ring-offset-width{syntax: \"<length>\"; inherits: false; initial-value: 0px;}@property --tw-ring-offset-color{syntax: \"*\"; inherits: false; initial-value: #fff;}@property --tw-ring-offset-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-font-weight{syntax: \"*\"; inherits: false;}@property --tw-border-style{syntax: \"*\"; inherits: false; initial-value: solid;}@layer properties{@supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-shadow: 0 0 #0000;--tw-shadow-color: initial;--tw-shadow-alpha: 100%;--tw-inset-shadow: 0 0 #0000;--tw-inset-shadow-color: initial;--tw-inset-shadow-alpha: 100%;--tw-ring-color: initial;--tw-ring-shadow: 0 0 #0000;--tw-inset-ring-color: initial;--tw-inset-ring-shadow: 0 0 #0000;--tw-ring-inset: initial;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-offset-shadow: 0 0 #0000;--tw-font-weight: initial;--tw-border-style: solid}}}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"] }]
12176
+ ], encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"axp-user-card lightest-surface dark:dark-surface\">\n <!-- ----- Presence badge in the top-right of the card ----- -->\n @if (showPresence()) {\n <span\n class=\"axp-user-card__presence\"\n [axTooltip]=\"tooltipText()\"\n [axTooltipDisabled]=\"tooltipDisabled()\"\n axTooltipPlacement=\"bottom\"\n >\n <ax-badge\n size=\"sm\"\n look=\"twotone\"\n [color]=\"presenceBadgeColor()\"\n [text]=\"(presenceLabelKey() | translate | async) ?? ''\"\n ></ax-badge>\n </span>\n }\n\n <div class=\"axp-user-card__identity\">\n <axp-user-avatar [size]=\"56\" [userId]=\"userId()\" [showPresence]=\"false\"></axp-user-avatar>\n <div class=\"axp-user-card__names\">\n <div class=\"axp-user-card__name\">{{ displayName() }}</div>\n <!-- ----- Username when the identity cache has one ----- -->\n @if (username()) {\n <div class=\"axp-user-card__username\">@{{ username() }}</div>\n }\n </div>\n </div>\n\n <!-- ----- Placeholder extras while contributed items are still loading ----- -->\n @if (itemsLoading()) {\n <div class=\"axp-user-card__badges\" aria-hidden=\"true\">\n <ax-skeleton [animated]=\"true\" class=\"axp-user-card__skeleton-badge\"></ax-skeleton>\n <ax-skeleton [animated]=\"true\" class=\"axp-user-card__skeleton-badge axp-user-card__skeleton-badge--wide\"></ax-skeleton>\n </div>\n <div class=\"axp-user-card__actions\" aria-hidden=\"true\">\n <ax-skeleton [animated]=\"true\" class=\"axp-user-card__skeleton-action\"></ax-skeleton>\n </div>\n }\n\n <!-- ----- Contributed identity chips (position, business unit, \u2026) ----- -->\n @if (!itemsLoading() && extraRows().length > 0) {\n <div class=\"axp-user-card__badges\">\n @for (row of extraRows(); track row.id) {\n <span\n class=\"axp-user-card__badge\"\n [axTooltip]=\"(row.label | translate | async) ?? ''\"\n axTooltipPlacement=\"bottom\"\n >\n <ax-badge\n size=\"sm\"\n look=\"twotone\"\n color=\"primary\"\n [text]=\"(row.value | translate | async) ?? ''\"\n ></ax-badge>\n </span>\n }\n </div>\n }\n\n <!-- ----- Contributed CTAs: button, or dropdown when the action has nested items ----- -->\n @if (!itemsLoading() && extraActions().length > 0) {\n <div class=\"axp-user-card__actions\">\n @for (action of extraActions(); track action.name || action.title) {\n <ax-button\n class=\"axp-user-card__action ax-xs\"\n look=\"outline\"\n [text]=\"(actionTitle(action) | translate | async) ?? ''\"\n [disabled]=\"action.disabled\"\n [color]=\"action.color\"\n (onClick)=\"onActionClick(action)\"\n >\n <!-- ----- Action icon when the contributor provided one ----- -->\n @if (action.icon) {\n <ax-prefix>\n <ax-icon [icon]=\"action.icon\"></ax-icon>\n </ax-prefix>\n }\n <!-- ----- Nested items turn the CTA into a dropdown ----- -->\n @if (nestedActions(action).length > 0) {\n <ax-dropdown-panel>\n <ax-button-item-list>\n @for (sub of nestedActions(action); track sub.name || sub.title) {\n <!-- ----- Visible nested action ----- -->\n @if (sub.visible != false) {\n <ax-button-item\n [text]=\"(actionTitle(sub) | translate | async) ?? ''\"\n [color]=\"sub.color\"\n [disabled]=\"sub.disabled\"\n (onClick)=\"onNestedActionClick(sub)\"\n >\n <!-- ----- Nested action icon ----- -->\n @if (sub.icon) {\n <ax-prefix>\n <ax-icon [icon]=\"sub.icon\"></ax-icon>\n </ax-prefix>\n }\n </ax-button-item>\n <!-- ----- Divider after a nested item marked as a break ----- -->\n @if (sub.break) {\n <ax-divider></ax-divider>\n }\n }\n }\n </ax-button-item-list>\n </ax-dropdown-panel>\n }\n </ax-button>\n }\n </div>\n }\n</div>\n", styles: ["@layer properties;:host{display:block;min-width:20rem;width:20rem;max-width:min(24rem,calc(100vw - 2rem))}.axp-user-card{position:relative;display:flex;width:100%;max-width:24rem;min-width:20rem;flex-direction:column;gap:calc(var(--spacing, .25rem) * 3);border-radius:var(--radius-lg, .5rem);padding:calc(var(--spacing, .25rem) * 4);--tw-shadow: 0 10px 15px -3px var(--tw-shadow-color, rgb(0 0 0 / .1)), 0 4px 6px -4px var(--tw-shadow-color, rgb(0 0 0 / .1));box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.axp-user-card-overlay,.axp-user-card-overlay.ax-overlay-container,.axp-user-card-overlay.ax-overlay-pane,.axp-user-card-overlay .ax-overlay-pane,.axp-user-card-overlay .overlay-pane{min-width:20rem;width:20rem;max-width:min(24rem,calc(100vw - 2rem))}.axp-user-card-overlay--pending,.axp-user-card-overlay--pending.ax-overlay-container,.axp-user-card-overlay--pending.ax-overlay-pane,.axp-user-card-overlay--pending .ax-overlay-pane,.axp-user-card-overlay--pending .overlay-pane{visibility:hidden;pointer-events:none}.axp-user-card__presence{position:absolute;inset-inline-end:calc(var(--spacing, .25rem) * 3);top:calc(var(--spacing, .25rem) * 3);z-index:10;display:inline-flex;flex-shrink:0}.axp-user-card__identity{display:flex;align-items:center;gap:calc(var(--spacing, .25rem) * 3);padding-inline-end:calc(var(--spacing, .25rem) * 16)}.axp-user-card__names{min-width:0px;flex:1}.axp-user-card__name{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:var(--text-base, 1rem);line-height:var(--tw-leading, var(--text-base--line-height, 1.5 ));--tw-font-weight: var(--font-weight-semibold, 600);font-weight:var(--font-weight-semibold, 600)}.axp-user-card__username{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:var(--text-xs, .75rem);line-height:var(--tw-leading, var(--text-xs--line-height, calc(1 / .75)));color:var(--color-neutral-500, oklch(55.6% 0 none))}.axp-user-card__badges{display:flex;flex-wrap:wrap;gap:calc(var(--spacing, .25rem) * 1.5);border-top-style:var(--tw-border-style);border-top-width:1px;padding-top:calc(var(--spacing, .25rem) * 2)}.axp-user-card__badge{max-width:100%}.axp-user-card__actions{display:flex;flex-wrap:wrap;gap:calc(var(--spacing, .25rem) * 2);border-top-style:var(--tw-border-style);border-top-width:1px;padding-top:calc(var(--spacing, .25rem) * 2)}.axp-user-card__action{min-width:0px}.axp-user-card__skeleton-badge{height:calc(var(--spacing, .25rem) * 5);width:calc(var(--spacing, .25rem) * 20);border-radius:calc(infinity * 1px)}.axp-user-card__skeleton-badge--wide{width:calc(var(--spacing, .25rem) * 36)}.axp-user-card__skeleton-action{height:calc(var(--spacing, .25rem) * 6);width:calc(var(--spacing, .25rem) * 24);border-radius:var(--radius-md, .375rem)}@property --tw-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-shadow-color{syntax: \"*\"; inherits: false;}@property --tw-shadow-alpha{syntax: \"<percentage>\"; inherits: false; initial-value: 100%;}@property --tw-inset-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-inset-shadow-color{syntax: \"*\"; inherits: false;}@property --tw-inset-shadow-alpha{syntax: \"<percentage>\"; inherits: false; initial-value: 100%;}@property --tw-ring-color{syntax: \"*\"; inherits: false;}@property --tw-ring-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-inset-ring-color{syntax: \"*\"; inherits: false;}@property --tw-inset-ring-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-ring-inset{syntax: \"*\"; inherits: false;}@property --tw-ring-offset-width{syntax: \"<length>\"; inherits: false; initial-value: 0px;}@property --tw-ring-offset-color{syntax: \"*\"; inherits: false; initial-value: #fff;}@property --tw-ring-offset-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-font-weight{syntax: \"*\"; inherits: false;}@property --tw-border-style{syntax: \"*\"; inherits: false; initial-value: solid;}@layer properties{@supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-shadow: 0 0 #0000;--tw-shadow-color: initial;--tw-shadow-alpha: 100%;--tw-inset-shadow: 0 0 #0000;--tw-inset-shadow-color: initial;--tw-inset-shadow-alpha: 100%;--tw-ring-color: initial;--tw-ring-shadow: 0 0 #0000;--tw-inset-ring-color: initial;--tw-inset-ring-shadow: 0 0 #0000;--tw-ring-inset: initial;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-offset-shadow: 0 0 #0000;--tw-font-weight: initial;--tw-border-style: solid}}}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"] }]
11924
12177
  }], propDecorators: { userId: [{ type: i0.Input, args: [{ isSignal: true, alias: "userId", required: true }] }] } });
11925
12178
 
11926
12179
  //#region ----- User card overlay -----
@@ -11936,32 +12189,40 @@ class AXPUserCardService {
11936
12189
  //#region ----- Private Properties -----
11937
12190
  this.overlayRef = null;
11938
12191
  this.componentRef = null;
12192
+ this.overlayElement = null;
11939
12193
  this.anchorElement = null;
11940
12194
  this.activeUserId = null;
12195
+ this.dismissOnPointerLeave = false;
12196
+ this.hideTimer = null;
11941
12197
  this.outsideClickHandler = null;
11942
12198
  this.keydownHandler = null;
12199
+ this.overlayPointerEnterHandler = null;
12200
+ this.overlayPointerLeaveHandler = null;
11943
12201
  this.routerSubscription = null;
11944
12202
  }
11945
12203
  //#endregion
11946
12204
  //#region ----- Public Methods -----
11947
- async show(target, userId) {
12205
+ async show(target, userId, options) {
11948
12206
  const id = userId?.trim();
11949
12207
  const anchorElement = this.resolveAnchorElement(target);
11950
12208
  if (!id || !anchorElement) {
11951
12209
  return;
11952
12210
  }
12211
+ this.cancelScheduledHide();
11953
12212
  if (this.overlayRef && this.activeUserId === id && this.anchorElement === anchorElement) {
12213
+ this.dismissOnPointerLeave = options?.dismissOnPointerLeave === true;
11954
12214
  return;
11955
12215
  }
11956
12216
  this.hide();
11957
- const panelClasses = ['animate-fadeIn', 'animate-faster', 'axp-user-card-overlay'];
12217
+ this.dismissOnPointerLeave = options?.dismissOnPointerLeave === true;
12218
+ const panelClasses = ['animate-fadeIn', 'animate-faster', 'axp-user-card-overlay', 'axp-user-card-overlay--pending'];
11958
12219
  if (this.platform.isDark()) {
11959
12220
  panelClasses.push('ax-dark');
11960
12221
  }
11961
12222
  try {
11962
12223
  const ref = await this.overlayService.create(AXPUserCardComponent, {
11963
12224
  centered: false,
11964
- width: 'fit-content',
12225
+ width: '20rem',
11965
12226
  actionSheetStyle: false,
11966
12227
  panelClass: panelClasses,
11967
12228
  backdrop: {
@@ -11985,16 +12246,27 @@ class AXPUserCardService {
11985
12246
  });
11986
12247
  this.overlayRef = ref;
11987
12248
  this.componentRef = ref.instance;
12249
+ this.overlayElement = ref.overlayElement ?? null;
11988
12250
  this.componentRef.instance.hideHost = () => {
11989
12251
  this.hide();
11990
12252
  };
11991
12253
  this.anchorElement = anchorElement;
11992
12254
  this.activeUserId = id;
11993
12255
  setTimeout(() => {
12256
+ if (this.overlayRef !== ref) {
12257
+ return;
12258
+ }
11994
12259
  ref.updatePosition();
12260
+ this.overlayElement = ref.overlayElement ?? this.overlayElement;
11995
12261
  this.bindDismissHandlers(ref.overlayElement, anchorElement);
11996
12262
  }, 0);
11997
- await this.componentRef.instance.loadCard();
12263
+ const loadPromise = this.componentRef.instance.loadCard();
12264
+ await this.revealWhenReady(ref, loadPromise);
12265
+ await loadPromise;
12266
+ if (this.overlayRef !== ref) {
12267
+ return;
12268
+ }
12269
+ ref.updatePosition();
11998
12270
  }
11999
12271
  catch (error) {
12000
12272
  console.error('[UserCard] Failed to open overlay:', error);
@@ -12002,11 +12274,28 @@ class AXPUserCardService {
12002
12274
  }
12003
12275
  }
12004
12276
  hide() {
12277
+ this.cancelScheduledHide();
12005
12278
  this.removeDismissHandlers();
12006
12279
  if (this.overlayRef) {
12007
12280
  this.overlayRef.dispose();
12008
12281
  }
12009
12282
  }
12283
+ scheduleHide(delayMs = 180) {
12284
+ if (!this.dismissOnPointerLeave) {
12285
+ return;
12286
+ }
12287
+ this.cancelScheduledHide();
12288
+ this.hideTimer = setTimeout(() => {
12289
+ this.hideTimer = null;
12290
+ this.hide();
12291
+ }, delayMs);
12292
+ }
12293
+ cancelScheduledHide() {
12294
+ if (this.hideTimer) {
12295
+ clearTimeout(this.hideTimer);
12296
+ this.hideTimer = null;
12297
+ }
12298
+ }
12010
12299
  isShowing(userId, anchor) {
12011
12300
  if (!this.overlayRef) {
12012
12301
  return false;
@@ -12021,6 +12310,30 @@ class AXPUserCardService {
12021
12310
  }
12022
12311
  //#endregion
12023
12312
  //#region ----- Utility Methods -----
12313
+ async revealWhenReady(ref, loadPromise) {
12314
+ await Promise.race([
12315
+ loadPromise,
12316
+ new Promise((resolve) => {
12317
+ setTimeout(resolve, USER_CARD_ITEMS_SKELETON_DELAY_MS);
12318
+ }),
12319
+ ]);
12320
+ if (this.overlayRef !== ref) {
12321
+ return;
12322
+ }
12323
+ this.overlayElement = ref.overlayElement ?? this.overlayElement;
12324
+ this.clearPendingOverlayClass(this.overlayElement);
12325
+ ref.updatePosition();
12326
+ }
12327
+ clearPendingOverlayClass(root) {
12328
+ let current = root;
12329
+ for (let depth = 0; current && depth < 4; depth += 1) {
12330
+ current.classList.remove('axp-user-card-overlay--pending');
12331
+ current = current.parentElement;
12332
+ }
12333
+ root?.querySelectorAll('.axp-user-card-overlay--pending').forEach((node) => {
12334
+ node.classList.remove('axp-user-card-overlay--pending');
12335
+ });
12336
+ }
12024
12337
  resolveAnchorElement(target) {
12025
12338
  if (target instanceof ElementRef) {
12026
12339
  return target.nativeElement;
@@ -12065,6 +12378,16 @@ class AXPUserCardService {
12065
12378
  this.hide();
12066
12379
  };
12067
12380
  this.document.addEventListener('mousedown', this.outsideClickHandler);
12381
+ if (this.dismissOnPointerLeave && overlayElement) {
12382
+ this.overlayPointerEnterHandler = () => {
12383
+ this.cancelScheduledHide();
12384
+ };
12385
+ this.overlayPointerLeaveHandler = () => {
12386
+ this.scheduleHide();
12387
+ };
12388
+ overlayElement.addEventListener('pointerenter', this.overlayPointerEnterHandler);
12389
+ overlayElement.addEventListener('pointerleave', this.overlayPointerLeaveHandler);
12390
+ }
12068
12391
  this.routerSubscription = this.router.events
12069
12392
  .pipe(filter((event) => event instanceof NavigationStart))
12070
12393
  .subscribe(() => {
@@ -12080,17 +12403,28 @@ class AXPUserCardService {
12080
12403
  this.document.removeEventListener('mousedown', this.outsideClickHandler);
12081
12404
  this.outsideClickHandler = null;
12082
12405
  }
12406
+ if (this.overlayPointerEnterHandler) {
12407
+ this.overlayElement?.removeEventListener('pointerenter', this.overlayPointerEnterHandler);
12408
+ this.overlayPointerEnterHandler = null;
12409
+ }
12410
+ if (this.overlayPointerLeaveHandler) {
12411
+ this.overlayElement?.removeEventListener('pointerleave', this.overlayPointerLeaveHandler);
12412
+ this.overlayPointerLeaveHandler = null;
12413
+ }
12083
12414
  if (this.routerSubscription) {
12084
12415
  this.routerSubscription.unsubscribe();
12085
12416
  this.routerSubscription = null;
12086
12417
  }
12087
12418
  }
12088
12419
  handleOverlayDisposed() {
12420
+ this.cancelScheduledHide();
12089
12421
  this.removeDismissHandlers();
12090
12422
  this.overlayRef = null;
12091
12423
  this.componentRef = null;
12424
+ this.overlayElement = null;
12092
12425
  this.anchorElement = null;
12093
12426
  this.activeUserId = null;
12427
+ this.dismissOnPointerLeave = false;
12094
12428
  }
12095
12429
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPUserCardService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
12096
12430
  static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPUserCardService, providedIn: 'root' }); }
@@ -12107,17 +12441,22 @@ class AXPUserCardDirective {
12107
12441
  constructor() {
12108
12442
  //#region ----- Services & Dependencies -----
12109
12443
  this.cardService = inject(AXPUserCardService);
12444
+ this.deviceService = inject(AXPDeviceService);
12110
12445
  this.host = inject(ElementRef);
12446
+ this.showTimer = null;
12111
12447
  //#endregion
12112
12448
  //#region ----- Inputs -----
12113
12449
  this.axpUserCard = input('', /* @ts-ignore */
12114
12450
  ...(ngDevMode ? [{ debugName: "axpUserCard" }] : /* istanbul ignore next */ []));
12115
12451
  this.axpUserCardDisabled = input(false, /* @ts-ignore */
12116
12452
  ...(ngDevMode ? [{ debugName: "axpUserCardDisabled" }] : /* istanbul ignore next */ []));
12453
+ this.axpUserCardTrigger = input('auto', /* @ts-ignore */
12454
+ ...(ngDevMode ? [{ debugName: "axpUserCardTrigger" }] : /* istanbul ignore next */ []));
12117
12455
  }
12118
12456
  //#endregion
12119
12457
  //#region ----- Lifecycle -----
12120
12458
  ngOnDestroy() {
12459
+ this.cancelScheduledShow();
12121
12460
  if (this.cardService.isShowing(this.resolvedUserId(), this.host.nativeElement)) {
12122
12461
  this.cardService.hide();
12123
12462
  }
@@ -12134,14 +12473,69 @@ class AXPUserCardDirective {
12134
12473
  }
12135
12474
  event.preventDefault();
12136
12475
  event.stopPropagation();
12476
+ if (this.shouldUseHover(this.pointerTypeOf(event))) {
12477
+ return;
12478
+ }
12137
12479
  if (this.cardService.isShowing(userId, this.host.nativeElement)) {
12138
12480
  this.cardService.hide();
12139
12481
  return;
12140
12482
  }
12141
12483
  void this.cardService.show(this.host, userId);
12142
12484
  }
12485
+ onPointerEnter(event) {
12486
+ if (!this.shouldUseHover(event.pointerType) || !this.canOpen()) {
12487
+ return;
12488
+ }
12489
+ this.cardService.cancelScheduledHide();
12490
+ const userId = this.resolvedUserId();
12491
+ if (this.cardService.isShowing(userId, this.host.nativeElement)) {
12492
+ return;
12493
+ }
12494
+ this.cancelScheduledShow();
12495
+ this.showTimer = setTimeout(() => {
12496
+ this.showTimer = null;
12497
+ if (!this.canOpen()) {
12498
+ return;
12499
+ }
12500
+ void this.cardService.show(this.host, userId, { dismissOnPointerLeave: true });
12501
+ }, USER_CARD_HOVER_OPEN_DELAY_MS);
12502
+ }
12503
+ onPointerLeave(event) {
12504
+ if (!this.shouldUseHover(event.pointerType) || this.axpUserCardDisabled()) {
12505
+ return;
12506
+ }
12507
+ this.cancelScheduledShow();
12508
+ this.cardService.scheduleHide();
12509
+ }
12510
+ //#endregion
12511
+ //#region ----- Private Helpers -----
12512
+ canOpen() {
12513
+ return !!this.resolvedUserId() && !this.axpUserCardDisabled();
12514
+ }
12515
+ shouldUseHover(pointerType) {
12516
+ const trigger = this.axpUserCardTrigger();
12517
+ if (trigger === 'hover') {
12518
+ return true;
12519
+ }
12520
+ if (trigger === 'click') {
12521
+ return false;
12522
+ }
12523
+ if (pointerType === 'touch') {
12524
+ return false;
12525
+ }
12526
+ return this.deviceService.isDesktopDevice();
12527
+ }
12528
+ pointerTypeOf(event) {
12529
+ return event instanceof PointerEvent ? event.pointerType : undefined;
12530
+ }
12531
+ cancelScheduledShow() {
12532
+ if (this.showTimer) {
12533
+ clearTimeout(this.showTimer);
12534
+ this.showTimer = null;
12535
+ }
12536
+ }
12143
12537
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPUserCardDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
12144
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.0.8", type: AXPUserCardDirective, isStandalone: true, selector: "[axpUserCard]", inputs: { axpUserCard: { classPropertyName: "axpUserCard", publicName: "axpUserCard", isSignal: true, isRequired: false, transformFunction: null }, axpUserCardDisabled: { classPropertyName: "axpUserCardDisabled", publicName: "axpUserCardDisabled", isSignal: true, isRequired: false, transformFunction: null } }, host: { listeners: { "click": "onClick($event)" }, properties: { "style.cursor": "!axpUserCardDisabled() && resolvedUserId() ? \"pointer\" : null" }, classAttribute: "axp-user-card-host" }, ngImport: i0 }); }
12538
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.0.8", type: AXPUserCardDirective, isStandalone: true, selector: "[axpUserCard]", inputs: { axpUserCard: { classPropertyName: "axpUserCard", publicName: "axpUserCard", isSignal: true, isRequired: false, transformFunction: null }, axpUserCardDisabled: { classPropertyName: "axpUserCardDisabled", publicName: "axpUserCardDisabled", isSignal: true, isRequired: false, transformFunction: null }, axpUserCardTrigger: { classPropertyName: "axpUserCardTrigger", publicName: "axpUserCardTrigger", isSignal: true, isRequired: false, transformFunction: null } }, host: { listeners: { "click": "onClick($event)", "pointerenter": "onPointerEnter($event)", "pointerleave": "onPointerLeave($event)" }, properties: { "style.cursor": "!axpUserCardDisabled() && resolvedUserId() ? \"pointer\" : null" }, classAttribute: "axp-user-card-host" }, ngImport: i0 }); }
12145
12539
  }
12146
12540
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPUserCardDirective, decorators: [{
12147
12541
  type: Directive,
@@ -12152,9 +12546,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
12152
12546
  class: 'axp-user-card-host',
12153
12547
  '[style.cursor]': '!axpUserCardDisabled() && resolvedUserId() ? "pointer" : null',
12154
12548
  '(click)': 'onClick($event)',
12549
+ '(pointerenter)': 'onPointerEnter($event)',
12550
+ '(pointerleave)': 'onPointerLeave($event)',
12155
12551
  },
12156
12552
  }]
12157
- }], propDecorators: { axpUserCard: [{ type: i0.Input, args: [{ isSignal: true, alias: "axpUserCard", required: false }] }], axpUserCardDisabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "axpUserCardDisabled", required: false }] }] } });
12553
+ }], propDecorators: { axpUserCard: [{ type: i0.Input, args: [{ isSignal: true, alias: "axpUserCard", required: false }] }], axpUserCardDisabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "axpUserCardDisabled", required: false }] }], axpUserCardTrigger: [{ type: i0.Input, args: [{ isSignal: true, alias: "axpUserCardTrigger", required: false }] }] } });
12158
12554
 
12159
12555
  //#region ---- Imports ----
12160
12556
  //#endregion
@@ -12941,5 +13337,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
12941
13337
  * Generated bundle index. Do not edit.
12942
13338
  */
12943
13339
 
12944
- export { AXPActivityLogComponent, AXPAvatarComponent, AXPCategoryTreeComponent, AXPColorPalettePickerComponent, AXPColumnItemListComponent, AXPCompareViewComponent, AXPConditionBuilderComponent, AXPConditionBuilderConditionComponent, AXPDataSelectorComponent, AXPDataSelectorService, AXPDragDropListComponent, AXPExpressionFieldDefinitions, AXPFileChooserCompressImagesHook, AXPFileChooserDirective, AXPFileChooserHookKeys, AXPFileChooserService, AXPFileChooserZipFilesHook, AXPFileUploaderDirective, AXPFileUploaderHookKeys, AXPFileUploaderService, AXPFileViewerComponent, AXPFileViewerFallbackContentComponent, AXPFileViewerService, AXPImageEditorPopupComponent, AXPImageEditorService, AXPItemConfiguratorComponent, AXPLayoutFloatingZoomBarComponent, AXPLayoutSideDetailPanelComponent, AXPLayoutSideDetailPanelSectionDirective, AXPMarkdownTemplateDirective, AXPMarkdownViewerComponent, AXPMenuBadgeHelper, AXPMenuCustomizerComponent, AXPMenuCustomizerService, AXPOutcomeResultsViewerComponent, AXPPageComponentRegistryService, AXPPreloadFiltersComponent, AXPPropertyViewerComponent, AXPPropertyViewerPopupComponent, AXPPropertyViewerService, AXPQueryColumnsComponent, AXPQueryFiltersComponent, AXPQuerySortsComponent, AXPQueryViewsComponent, AXPRepeaterRowsLayoutComponent, AXPResourceAppointmentBoardProvider, AXPResourceAppointmentComponent, AXPResourceAppointmentService, AXPSectionItemsBuilderComponent, AXPSignatureEditorService, AXPSpreadsheetComponent, AXPStandardSectionItemsBuilderComponent, AXPStateMessageComponent, AXPStopwatchComponent, AXPTableColumnsEditorComponent, AXPTableColumnsEditorPopupComponent, AXPTableColumnsEditorService, AXPTableDataEditorComponent, AXPTableDataEditorPopupComponent, AXPTableDataEditorService, AXPTaskBadgeDirective, AXPTaskBadgeProvider, AXPTaskBadgeService, AXPTemplateViewerComponent, AXPTemplateViewerService, AXPTextCommandColumnComponent, AXPThemeLayoutActionsComponent, AXPThemeLayoutBlockComponent, AXPThemeLayoutContainerComponent, AXPThemeLayoutEndSideComponent, AXPThemeLayoutFooterComponent, AXPThemeLayoutHeaderComponent, AXPThemeLayoutListComponent, AXPThemeLayoutListItemComponent, AXPThemeLayoutListItemsGroupComponent, AXPThemeLayoutPageHeaderComponent, AXPThemeLayoutPagePrimaryActionsComponent, AXPThemeLayoutPageSecondaryActionsComponent, AXPThemeLayoutSectionComponent, AXPThemeLayoutStartSideComponent, AXPThemeLayoutToolbarComponent, AXPUserAvatarComponent, AXPUserAvatarService, AXPUserCardComponent, AXPUserCardDirective, AXPUserCardService, AXPVirtualKeypadComponent, AXPWidgetFieldConfiguratorComponent, AXPWidgetItemComponent, AXPWidgetPropertyViewerComponent, AXPWidgetPropertyViewerPopupComponent, AXPWidgetPropertyViewerService, AXP_EXPRESSION_LOGIC_DEFINITIONS, AXP_EXPRESSION_OPERATION_DEFINITIONS, AXP_FILE_CHOOSER_DEFAULT_ZIP_ARCHIVE_NAME, AXP_FILE_CHOOSER_HOOK_PROVIDERS, AXP_FILE_CHOOSER_OPTION_KEYS, AXP_FILE_CHOOSER_PROVIDERS, AXP_FILE_UPLOADER_PROVIDERS, AXP_MENU_CUSTOMIZER_SERVICE, AXP_PAGE_COMPONENT_PROVIDER, AXP_RESOURCE_APPOINTMENT_PROVIDER, AXP_SYSTEM_FILE_CHOOSER_PROVIDER, AXP_SYSTEM_FILE_UPLOADER_PROVIDER, AXP_TASK_BADGE_PROVIDERS, AXP_USER_AVATAR_PROVIDER, STANDARD_SECTION_ITEMS_SECTION_TABS, USER_CARD_ITEMS_HOOK, buildFileChooserOptions, buildPropertyViewerInitialContextFromProperties, buildPropertyViewerTabsFromProperties, buildTableColumnsEditorLayout, compressImageFile, createZipArchive, fileListItemToFileViewerItem, fileMatchesAccept, filterFileProvidersByContext, filterFilesByAcceptAndMaxSize, formatAcceptForDisplay, formatMaxFileSizeForDisplay, getFieldDefinitions, getLogicDefinition, getOperationDefinition, isPropertyBindingExpressionFormValue, isUnrestrictedFileAccept, mapFileListToViewerItems, normalizeFileViewerBoundValue, notifyFileAcceptRejections, preparePropertyForViewer, preparePropertyViewerTabs, provideFileChooserHooks, registerFieldDefinitions, resolveExcludedFileProviderKeys, resolveFileChooserAccept, resolveFileChooserExtension, resolveFileListItemUrl, resolveFileUploaderEmptyStateDescription, sortUserCardActions, sortUserCardRows, validateFileChooserItems, visibleUserCardActions, withValidationsOnEditorNode };
13340
+ export { AXPActivityLogComponent, AXPAvatarComponent, AXPCategoryTreeComponent, AXPColorChooserComponent, AXPColorPalettePickerComponent, AXPColumnItemListComponent, AXPCompareViewComponent, AXPConditionBuilderComponent, AXPConditionBuilderConditionComponent, AXPDataSelectorComponent, AXPDataSelectorService, AXPDragDropListComponent, AXPExpressionFieldDefinitions, AXPFileChooserCompressImagesHook, AXPFileChooserDirective, AXPFileChooserHookKeys, AXPFileChooserService, AXPFileChooserZipFilesHook, AXPFileUploaderDirective, AXPFileUploaderHookKeys, AXPFileUploaderService, AXPFileViewerComponent, AXPFileViewerFallbackContentComponent, AXPFileViewerService, AXPImageEditorPopupComponent, AXPImageEditorService, AXPInfiniteScrollDirective, AXPItemConfiguratorComponent, AXPLayoutFloatingZoomBarComponent, AXPLayoutSideDetailPanelComponent, AXPLayoutSideDetailPanelSectionDirective, AXPMarkdownTemplateDirective, AXPMarkdownViewerComponent, AXPMenuBadgeHelper, AXPMenuCustomizerComponent, AXPMenuCustomizerService, AXPOutcomeResultsViewerComponent, AXPPageComponentRegistryService, AXPPreloadFiltersComponent, AXPPropertyViewerComponent, AXPPropertyViewerPopupComponent, AXPPropertyViewerService, AXPQueryColumnsComponent, AXPQueryFiltersComponent, AXPQuerySortsComponent, AXPQueryViewsComponent, AXPRepeaterRowsLayoutComponent, AXPResourceAppointmentBoardProvider, AXPResourceAppointmentComponent, AXPResourceAppointmentService, AXPSectionItemsBuilderComponent, AXPSignatureEditorService, AXPSpreadsheetComponent, AXPStandardSectionItemsBuilderComponent, AXPStopwatchComponent, AXPTableColumnsEditorComponent, AXPTableColumnsEditorPopupComponent, AXPTableColumnsEditorService, AXPTableDataEditorComponent, AXPTableDataEditorPopupComponent, AXPTableDataEditorService, AXPTaskBadgeDirective, AXPTaskBadgeProvider, AXPTaskBadgeService, AXPTemplateViewerComponent, AXPTemplateViewerService, AXPTextCommandColumnComponent, AXPThemeLayoutActionsComponent, AXPThemeLayoutBlockComponent, AXPThemeLayoutContainerComponent, AXPThemeLayoutEndSideComponent, AXPThemeLayoutFooterComponent, AXPThemeLayoutHeaderComponent, AXPThemeLayoutListComponent, AXPThemeLayoutListItemComponent, AXPThemeLayoutListItemsGroupComponent, AXPThemeLayoutPageHeaderComponent, AXPThemeLayoutPagePrimaryActionsComponent, AXPThemeLayoutPageSecondaryActionsComponent, AXPThemeLayoutSectionComponent, AXPThemeLayoutStartSideComponent, AXPThemeLayoutToolbarComponent, AXPUserAvatarComponent, AXPUserAvatarService, AXPUserCardComponent, AXPUserCardDirective, AXPUserCardService, AXPVirtualKeypadComponent, AXPWidgetFieldConfiguratorComponent, AXPWidgetItemComponent, AXPWidgetPropertyViewerComponent, AXPWidgetPropertyViewerPopupComponent, AXPWidgetPropertyViewerService, AXP_EXPRESSION_LOGIC_DEFINITIONS, AXP_EXPRESSION_OPERATION_DEFINITIONS, AXP_FILE_CHOOSER_DEFAULT_ZIP_ARCHIVE_NAME, AXP_FILE_CHOOSER_HOOK_PROVIDERS, AXP_FILE_CHOOSER_OPTION_KEYS, AXP_FILE_CHOOSER_PROVIDERS, AXP_FILE_UPLOADER_PROVIDERS, AXP_INFINITE_SCROLL_DEFAULT_ROOT_MARGIN, AXP_MENU_CUSTOMIZER_SERVICE, AXP_PAGE_COMPONENT_PROVIDER, AXP_PAGE_LAYOUT_ELEMENT_ID, AXP_RESOURCE_APPOINTMENT_PROVIDER, AXP_SYSTEM_FILE_CHOOSER_PROVIDER, AXP_SYSTEM_FILE_UPLOADER_PROVIDER, AXP_TASK_BADGE_PROVIDERS, AXP_USER_AVATAR_PROVIDER, STANDARD_SECTION_ITEMS_SECTION_TABS, USER_CARD_HOVER_OPEN_DELAY_MS, USER_CARD_ITEMS_HOOK, USER_CARD_ITEMS_SKELETON_DELAY_MS, buildFileChooserOptions, buildPropertyViewerInitialContextFromProperties, buildPropertyViewerTabsFromProperties, buildTableColumnsEditorLayout, compressImageFile, createZipArchive, fileListItemToFileViewerItem, fileMatchesAccept, filterFileProvidersByContext, filterFilesByAcceptAndMaxSize, formatAcceptForDisplay, formatMaxFileSizeForDisplay, getFieldDefinitions, getLogicDefinition, getOperationDefinition, isPropertyBindingExpressionFormValue, isUnrestrictedFileAccept, mapFileListToViewerItems, mergeInfiniteScrollPage, normalizeFileViewerBoundValue, notifyFileAcceptRejections, observeInfiniteScroll, preparePropertyForViewer, preparePropertyViewerTabs, provideFileChooserHooks, registerFieldDefinitions, resolveExcludedFileProviderKeys, resolveFileChooserAccept, resolveFileChooserExtension, resolveFileListItemUrl, resolveFileUploaderEmptyStateDescription, resolveInfiniteScrollRoot, sortUserCardActions, sortUserCardRows, validateFileChooserItems, visibleUserCardActions, withValidationsOnEditorNode };
12945
13341
  //# sourceMappingURL=acorex-platform-framework-client-layout-components.mjs.map