@acorex/components 18.10.15 → 18.11.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (44) hide show
  1. package/esm2022/common/lib/classes/events.class.mjs +1 -1
  2. package/esm2022/image-editor/lib/image-editor-toolbar/image-editor-toolbar.component.mjs +1 -1
  3. package/esm2022/image-editor/lib/image-editor-view/image-editor-view.component.mjs +1 -1
  4. package/esm2022/menu/index.mjs +4 -4
  5. package/esm2022/menu/lib/context-menu.component.mjs +181 -0
  6. package/esm2022/menu/lib/menu-item.component.mjs +311 -0
  7. package/esm2022/menu/lib/menu.component.mjs +24 -30
  8. package/esm2022/menu/lib/menu.module.mjs +7 -7
  9. package/esm2022/menu/lib/menu.service.mjs +10 -8
  10. package/esm2022/menu/lib/menu.types.mjs +22 -0
  11. package/esm2022/popover/lib/popover.component.mjs +55 -34
  12. package/esm2022/popup/lib/popup.component.mjs +2 -2
  13. package/esm2022/select-box/lib/select-box.component.mjs +3 -3
  14. package/esm2022/wysiwyg/lib/wysiwyg/wysiwyg-container/wysiwyg-container.component.mjs +1 -2
  15. package/esm2022/wysiwyg/lib/wysiwyg/wysiwyg-toolbar/wysiwyg-toolbar.component.mjs +3 -3
  16. package/esm2022/wysiwyg/lib/wysiwyg/wysiwyg-tools/wysiwyg-font-style/wysiwyg-font-style.component.mjs +1 -1
  17. package/fesm2022/acorex-components-common.mjs.map +1 -1
  18. package/fesm2022/acorex-components-image-editor.mjs.map +1 -1
  19. package/fesm2022/acorex-components-menu.mjs +494 -161
  20. package/fesm2022/acorex-components-menu.mjs.map +1 -1
  21. package/fesm2022/acorex-components-popover.mjs +54 -33
  22. package/fesm2022/acorex-components-popover.mjs.map +1 -1
  23. package/fesm2022/acorex-components-popup.mjs +2 -2
  24. package/fesm2022/acorex-components-popup.mjs.map +1 -1
  25. package/fesm2022/acorex-components-select-box.mjs +2 -2
  26. package/fesm2022/acorex-components-select-box.mjs.map +1 -1
  27. package/fesm2022/acorex-components-wysiwyg.mjs +2 -3
  28. package/fesm2022/acorex-components-wysiwyg.mjs.map +1 -1
  29. package/menu/index.d.ts +3 -3
  30. package/menu/lib/context-menu.component.d.ts +41 -0
  31. package/menu/lib/menu-item.component.d.ts +60 -0
  32. package/menu/lib/menu.component.d.ts +8 -10
  33. package/menu/lib/menu.module.d.ts +9 -9
  34. package/menu/lib/menu.service.d.ts +14 -3
  35. package/menu/lib/menu.types.d.ts +43 -0
  36. package/package.json +53 -53
  37. package/popover/lib/popover.component.d.ts +36 -34
  38. package/wysiwyg/lib/wysiwyg/wysiwyg-container/wysiwyg-container.component.d.ts +1 -2
  39. package/esm2022/menu/lib/class/popover.class.mjs +0 -2
  40. package/esm2022/menu/lib/class/root-menu.class.mjs +0 -8
  41. package/esm2022/menu/lib/menu-item/menu-item.component.mjs +0 -160
  42. package/menu/lib/class/popover.class.d.ts +0 -2
  43. package/menu/lib/class/root-menu.class.d.ts +0 -7
  44. package/menu/lib/menu-item/menu-item.component.d.ts +0 -81
@@ -1,188 +1,529 @@
1
+ import { AXClickEvent, AXEvent, MXBaseComponent } from '@acorex/components/common';
1
2
  import * as i0 from '@angular/core';
2
- import { signal, Injectable, inject, input, output, afterNextRender, Component, ViewEncapsulation, ViewChild, ContentChildren, HostBinding, HostListener, NgModule } from '@angular/core';
3
- import { MXInteractiveComponent, MXBaseComponent } from '@acorex/components/common';
4
- import * as i1 from '@acorex/components/popover';
5
- import { AXPopoverComponent, AXPopoverModule } from '@acorex/components/popover';
6
- import { BehaviorSubject } from 'rxjs';
7
- import { AXButtonModule } from '@acorex/components/button';
3
+ import { Injectable, signal, inject, computed, output, input, afterNextRender, Component, ViewEncapsulation, ChangeDetectionStrategy, HostListener, HostBinding, NgModule } from '@angular/core';
4
+ import { Subject } from 'rxjs';
5
+ import { AXUnsubscriber, AXHtmlUtil } from '@acorex/core/utils';
6
+ import { cloneDeep } from 'lodash-es';
7
+ import * as i1 from '@angular/common';
8
+ import { CommonModule } from '@angular/common';
9
+ import * as i2 from '@acorex/components/decorators';
8
10
  import { AXDecoratorModule } from '@acorex/components/decorators';
9
11
  import { AXLoadingModule } from '@acorex/components/loading';
12
+ import { AXPopoverModule } from '@acorex/components/popover';
10
13
  import { AXTranslationModule } from '@acorex/core/translation';
11
14
  import { OverlayModule } from '@angular/cdk/overlay';
12
- import { CommonModule } from '@angular/common';
13
15
 
14
16
  class AXRootMenu {
17
+ }
18
+ class AXMenuItemComponentBase {
19
+ }
20
+ class AXMenuItem {
21
+ }
22
+ class AXMenuItemClickEventItemData {
23
+ }
24
+ class AXMenuItemClickEvent extends AXClickEvent {
25
+ constructor() {
26
+ super(...arguments);
27
+ this.canceled = false;
28
+ }
29
+ }
30
+ class AXContextMenuOpeningEvent extends AXEvent {
15
31
  constructor() {
16
- this.orientation = signal('horizontal');
17
- this.openOn = signal('toggle');
32
+ super(...arguments);
33
+ this.canceled = false;
18
34
  }
19
35
  }
20
36
 
21
37
  class AXMenuService {
22
38
  constructor() {
23
- this.activeMenus$ = new BehaviorSubject([]);
39
+ this.closeAll$ = new Subject();
40
+ this.open$ = new Subject();
41
+ this.close$ = new Subject();
42
+ this.closeExcept$ = new Subject();
43
+ this.openContextMenu$ = new Subject();
44
+ this.closeAllContextMenu$ = new Subject();
24
45
  }
25
46
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.0", ngImport: i0, type: AXMenuService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
26
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.0", ngImport: i0, type: AXMenuService, providedIn: 'root' }); }
47
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.0", ngImport: i0, type: AXMenuService }); }
27
48
  }
28
49
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.0", ngImport: i0, type: AXMenuService, decorators: [{
29
- type: Injectable,
30
- args: [{
31
- providedIn: 'root',
32
- }]
50
+ type: Injectable
33
51
  }] });
34
52
 
35
53
  /**
36
54
  * Represents a menu item component used within an `ax-menu`.
37
55
  * @category Components
38
56
  */
39
- class AXMenuItemComponent extends MXInteractiveComponent {
40
- /** @ignore */
41
- constructor() {
57
+ class AXMenuItemComponent extends MXBaseComponent {
58
+ constructor(renderer) {
42
59
  super();
60
+ this.renderer = renderer;
61
+ this.isOpen = signal(false);
62
+ this.hasSubItems = signal(false);
63
+ this.isFirstLevel = signal(false);
64
+ this.root = inject(AXRootMenu);
43
65
  this.service = inject(AXMenuService);
44
- /**
45
- * Injects the `AXMenuService` for managing menu interactions.
46
- */
47
- this.menuService = inject(AXMenuService);
48
- /**
49
- * The vertical offset for positioning, initialized to 0.
50
- */
51
- this.offsetY = signal(0);
52
- /**
53
- * The horizontal offset for positioning, initialized to 0.
54
- */
55
- this.offsetX = signal(0);
56
- /**
57
- * The text content, initialized to an empty string.
58
- */
59
- // text = input<string>();
60
- /**
61
- * Indicates whether the item is active.
62
- */
63
- this.active = input();
64
- /**
65
- * Emitted when the active state changes.
66
- */
67
- this.activeChange = output();
68
- /**
69
- * Emitted when the element is clicked.
70
- */
66
+ this.scrollableParents = [];
67
+ this.unsuscriber = inject(AXUnsubscriber);
68
+ this.arrowIcon = computed(() => {
69
+ const isRtl = AXHtmlUtil.isRtl(this.getHostElement());
70
+ return this.root.orientation() == 'horizontal' && this.isFirstLevel() ?
71
+ "ax-icon-chevron-down" :
72
+ isRtl ? "ax-icon-chevron-left" : "ax-icon-chevron-right";
73
+ });
71
74
  this.onClick = output();
72
- /**
73
- * Indicates whether the component is a root menu item.
74
- * @defaultValue false
75
- */
76
- this.isRoot = false;
77
- /**
78
- * Injects the root menu service.
79
- */
80
- this.rootMenu = inject(AXRootMenu);
81
- this.arrowState = input(true);
75
+ this.name = input();
76
+ this.data = input();
77
+ this.disabled = input();
78
+ this.color = input();
79
+ //
82
80
  afterNextRender(() => {
83
- this.children.forEach((c) => {
84
- c.parent = this;
85
- });
86
- this.offsetY.set(this.isRoot ? 8 : 0);
87
- this.offsetX.set(this.isRoot ? 0 : 4);
88
- this.getPlacement();
81
+ this.detectSubItems();
82
+ this.observeMutations();
83
+ this.bindScrollEvents();
89
84
  });
90
- }
91
- /**
92
- * Closes the popover if it is open.
93
- */
94
- close() {
95
- this.popover?.close();
96
- }
97
- /** @ignore */
98
- _handleOnOpened() {
99
- this.parent.children.forEach((c) => {
100
- if (c != this) {
101
- c.close();
85
+ //
86
+ this.service.closeAll$
87
+ .pipe(this.unsuscriber.takeUntilDestroy)
88
+ .subscribe(() => this.close());
89
+ this.service.open$
90
+ .pipe(this.unsuscriber.takeUntilDestroy)
91
+ .subscribe((item) => {
92
+ if (this === item) {
93
+ this.isOpen.set(true);
94
+ this.calculatePosition();
102
95
  }
103
96
  });
104
- if (this.children.length) {
105
- this.menuService.activeMenus$.next(this.menuService.activeMenus$.getValue().concat(this));
97
+ //
98
+ this.service.close$
99
+ .pipe(this.unsuscriber.takeUntilDestroy)
100
+ .subscribe(item => {
101
+ if (this == item) {
102
+ this.isOpen.set(false);
103
+ }
104
+ });
105
+ //
106
+ this.service.closeExcept$
107
+ .pipe(this.unsuscriber.takeUntilDestroy)
108
+ .subscribe((item) => {
109
+ this.closeExcept(item);
110
+ });
111
+ }
112
+ closeExcept(item) {
113
+ const list = [item];
114
+ //
115
+ let parent = item.parent;
116
+ while (parent != null) {
117
+ list.push(parent);
118
+ parent = parent.parent;
119
+ }
120
+ //
121
+ if (!list.includes(this)) {
122
+ this.close();
106
123
  }
107
124
  }
108
- /** @ignore */
109
- _handleOnClosed() {
110
- this.children.forEach((c) => {
111
- c.close();
125
+ observeMutations() {
126
+ this.mutationObserver = new MutationObserver(() => {
127
+ this.detectSubItems();
128
+ });
129
+ // Start observing changes in child elements
130
+ this.mutationObserver.observe(this.getHostElement(), {
131
+ childList: true,
132
+ subtree: true,
112
133
  });
113
134
  }
135
+ getText() {
136
+ return this.getHostElement().querySelector('ax-text')?.innerText;
137
+ }
114
138
  /**
115
- * Returns the icon based on the orientation of the root menu.
116
- */
117
- getIcon() {
118
- if (this.rootMenu.orientation() === 'vertical') {
119
- return 'ax-icon-chevron-right';
139
+ * Manually detect all `ax-menu-item` elements and check if this menu item has sub-items.
140
+ */
141
+ detectSubItems() {
142
+ //
143
+ const parentEl = this.getHostElement().parentElement?.parentElement;
144
+ this.parent = parentEl?.tagName == "AX-MENU-ITEM" ? parentEl?.["__axContext__"] : null;
145
+ //
146
+ const tag = this.getHostElement().parentElement?.tagName;
147
+ this.isFirstLevel.set(tag == "AX-MENU" || tag == "AX-CONTEXT-MENU");
148
+ const subItems = this.getHostElement().querySelectorAll('ax-menu-item');
149
+ if (subItems.length > 0) {
150
+ this.hasSubItems.set(true);
151
+ }
152
+ else {
153
+ this.hasSubItems.set(false);
154
+ }
155
+ }
156
+ open() {
157
+ this.service.closeExcept$.next(this);
158
+ if (!this.disabled() && this.hasSubItems()) {
159
+ this.service.open$.next(this);
160
+ }
161
+ }
162
+ close() {
163
+ this.service.close$.next(this);
164
+ }
165
+ /**
166
+ * Calculate the position of the submenu to avoid it going out of the viewport.
167
+ */
168
+ calculatePosition() {
169
+ const submenu = this.getHostElement().querySelector('.ax-menu-items');
170
+ if (!submenu)
171
+ return;
172
+ const submenuRect = submenu.getBoundingClientRect();
173
+ const itemRect = this.getHostElement().getBoundingClientRect();
174
+ const windowWidth = window.innerWidth;
175
+ const windowHeight = window.innerHeight;
176
+ const isRtl = AXHtmlUtil.isRtl(this.getHostElement());
177
+ let top = null;
178
+ let left = null;
179
+ // For first-level menu items
180
+ if (this.isFirstLevel() && this.root.orientation() === 'horizontal') {
181
+ top = itemRect.bottom + submenuRect.height > windowHeight
182
+ ? itemRect.top - submenuRect.height // Open upwards
183
+ : itemRect.bottom; // Open downwards
184
+ if (isRtl) {
185
+ // RTL: Align to the right of the parent item
186
+ left = itemRect.right - submenuRect.width < 0
187
+ ? itemRect.left // Align to the left if not enough space on the right
188
+ : itemRect.right - submenuRect.width; // Open to the left in RTL
189
+ }
190
+ else {
191
+ // LTR: Align to the left of the parent item
192
+ left = itemRect.left + submenuRect.width > windowWidth
193
+ ? itemRect.right - submenuRect.width // Align to the right edge in LTR
194
+ : itemRect.left; // Open to the left
195
+ }
120
196
  }
121
197
  else {
122
- return 'ax-icon-chevron-down';
198
+ // For nested submenus
199
+ if (isRtl) {
200
+ // RTL: Nested submenu opens to the left
201
+ left = itemRect.left - submenuRect.width < 0
202
+ ? itemRect.right // Align to the right if not enough space on the left
203
+ : itemRect.left - submenuRect.width; // Open to the left in RTL
204
+ }
205
+ else {
206
+ // LTR: Nested submenu opens to the right
207
+ left = itemRect.right + submenuRect.width > windowWidth
208
+ ? itemRect.left - submenuRect.width // Open to the left if not enough space
209
+ : itemRect.right; // Open to the right in LTR
210
+ }
211
+ // Adjust top position (align vertically with parent)
212
+ top = itemRect.top + submenuRect.height > windowHeight
213
+ ? itemRect.top - (itemRect.bottom + submenuRect.height - windowHeight) // Adjust upwards
214
+ : itemRect.top; // Align with the parent item
215
+ }
216
+ // Apply calculated styles for RTL/LTR
217
+ this.renderer.setStyle(submenu, 'left', `${left}px`);
218
+ this.renderer.setStyle(submenu, 'top', `${top}px`);
219
+ this.renderer.setStyle(submenu, 'position', 'fixed'); // Fixed position relative to the viewport
220
+ }
221
+ handleClick(e) {
222
+ e.stopPropagation();
223
+ if (this.disabled())
224
+ return;
225
+ //
226
+ const event = {
227
+ component: this,
228
+ htmlElement: this.getHostElement(),
229
+ nativeEvent: e,
230
+ canceled: false,
231
+ item: {
232
+ name: this.name(),
233
+ text: this.getText(),
234
+ data: this.data()
235
+ }
236
+ };
237
+ //
238
+ this.onClick.emit(event);
239
+ this.root.onItemClick.emit(event);
240
+ //
241
+ if (this.hasSubItems() && !event.canceled) {
242
+ this.open();
243
+ }
244
+ else if (!event.canceled) {
245
+ this.service.closeAll$.next();
246
+ this.service.closeAllContextMenu$.next({ sender: this.root });
247
+ }
248
+ }
249
+ handleMouseEnter(event) {
250
+ event.stopPropagation();
251
+ // Cancel the close delay if the mouse re-enters the element
252
+ if (this.mouseLeaveTimeout) {
253
+ clearTimeout(this.mouseLeaveTimeout);
254
+ this.mouseLeaveTimeout = null; // Reset the timeout
255
+ }
256
+ if (!this.isFirstLevel() || this.root.openOn() == 'hover') {
257
+ this.open();
258
+ }
259
+ }
260
+ handleMouseLeave(event) {
261
+ event.stopPropagation();
262
+ if (this.hasSubItems() && this.root.closeOn() === 'leave') {
263
+ // Clear any previous timeout to avoid multiple triggers
264
+ if (this.mouseLeaveTimeout) {
265
+ clearTimeout(this.mouseLeaveTimeout);
266
+ }
267
+ // Set a delay before closing the submenu
268
+ this.mouseLeaveTimeout = setTimeout(() => {
269
+ this.close();
270
+ }, 500); // Adjust the delay (500ms in this case) as per your requirement
123
271
  }
124
272
  }
273
+ onWindowEvent() {
274
+ this.service.closeAll$.next(); // Close all menus on scroll or resize
275
+ }
125
276
  /**
126
- * Determines the placement based on the root menu's orientation: 'bottom-start' for horizontal root, 'end-top' otherwise.
277
+ * Close all menus if clicking outside the root menu and all sub-items.
127
278
  */
128
- getPlacement() {
129
- switch (this.rootMenu.orientation()) {
130
- case 'horizontal':
131
- if (this.isRoot) {
132
- return 'bottom-start';
133
- }
134
- else {
135
- return 'end-top';
136
- }
137
- break;
138
- case 'vertical':
139
- if (this.isRoot) {
140
- return 'end-top';
141
- }
142
- else {
143
- return 'end-top';
144
- }
145
- break;
146
- default:
147
- return 'bottom-start';
279
+ onClickOutside(event) {
280
+ const hostElement = this.root.getHostElement();
281
+ if (!hostElement.contains(event.target)) {
282
+ this.service.closeAll$.next(); // Close all menus if click is outside the root and sub-items
148
283
  }
149
284
  }
285
+ ngOnDestroy() {
286
+ this.removeScrollEvents();
287
+ }
288
+ bindScrollEvents() {
289
+ this.scrollableParents = AXHtmlUtil.getScrollableParents(this.getHostElement());
290
+ this.scrollableParents.forEach((parent) => {
291
+ parent.addEventListener('scroll', this.onContainerScroll.bind(this));
292
+ });
293
+ }
294
+ // Remove scroll event listeners
295
+ removeScrollEvents() {
296
+ this.scrollableParents.forEach((parent) => {
297
+ parent.removeEventListener('scroll', this.onContainerScroll.bind(this));
298
+ });
299
+ }
300
+ /**
301
+ * Handler for scroll events (window or scrollable parent containers)
302
+ */
303
+ onContainerScroll() {
304
+ this.service.closeAll$.next(); // Close all menus on scroll
305
+ }
150
306
  /** @ignore */
151
307
  get __hostClass() {
152
- return [`${this.disabled ? 'ax-state-disabled' : ''}`, `${this.active() ? 'ax-state-active' : ''}`];
308
+ const list = ['ax-el-interactive'];
309
+ if (this.disabled()) {
310
+ list.push('ax-state-disabled');
311
+ }
312
+ if (this.color()) {
313
+ list.push(`ax-el-${this.color()}-blank`);
314
+ }
315
+ return list;
316
+ }
317
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.0", ngImport: i0, type: AXMenuItemComponent, deps: [{ token: i0.Renderer2 }], target: i0.ɵɵFactoryTarget.Component }); }
318
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.0", type: AXMenuItemComponent, selector: "ax-menu-item", inputs: { name: { classPropertyName: "name", publicName: "name", isSignal: true, isRequired: false, transformFunction: null }, data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, color: { classPropertyName: "color", publicName: "color", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { onClick: "onClick" }, host: { listeners: { "click": "handleClick($event)", "mouseenter": "handleMouseEnter($event)", "mouseleave": "handleMouseLeave($event)", "window:scroll": "onWindowEvent($event)", "window:resize": "onWindowEvent($event)", "document:click": "onClickOutside($event)" }, properties: { "class": "this.__hostClass" } }, providers: [
319
+ {
320
+ provide: AXMenuItemComponentBase,
321
+ useExisting: AXMenuItemComponent
322
+ },
323
+ AXUnsubscriber
324
+ ], usesInheritance: true, ngImport: i0, template: "<div class=\"ax-menu-item-prefix\">\n <ng-content select=\"ax-prefix\"></ng-content>\n <ng-content select=\"ax-text\"></ng-content>\n</div>\n<ng-content select=\"ax-suffix\"></ng-content>\n@if (hasSubItems()) {\n<i class=\"ax-icon ax-icon-solid {{ arrowIcon() }} ax-menu-item-child-icon\"></i>\n}\n<div class=\"ax-menu-items\" [class.ax-state-open]=\"isOpen()\">\n <ng-content select=\"ax-menu-item,ax-title,ng-container\"></ng-content>\n</div>", changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
325
+ }
326
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.0", ngImport: i0, type: AXMenuItemComponent, decorators: [{
327
+ type: Component,
328
+ args: [{ selector: 'ax-menu-item', encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, providers: [
329
+ {
330
+ provide: AXMenuItemComponentBase,
331
+ useExisting: AXMenuItemComponent
332
+ },
333
+ AXUnsubscriber
334
+ ], template: "<div class=\"ax-menu-item-prefix\">\n <ng-content select=\"ax-prefix\"></ng-content>\n <ng-content select=\"ax-text\"></ng-content>\n</div>\n<ng-content select=\"ax-suffix\"></ng-content>\n@if (hasSubItems()) {\n<i class=\"ax-icon ax-icon-solid {{ arrowIcon() }} ax-menu-item-child-icon\"></i>\n}\n<div class=\"ax-menu-items\" [class.ax-state-open]=\"isOpen()\">\n <ng-content select=\"ax-menu-item,ax-title,ng-container\"></ng-content>\n</div>" }]
335
+ }], ctorParameters: () => [{ type: i0.Renderer2 }], propDecorators: { handleClick: [{
336
+ type: HostListener,
337
+ args: ["click", ['$event']]
338
+ }], handleMouseEnter: [{
339
+ type: HostListener,
340
+ args: ["mouseenter", ['$event']]
341
+ }], handleMouseLeave: [{
342
+ type: HostListener,
343
+ args: ["mouseleave", ['$event']]
344
+ }], onWindowEvent: [{
345
+ type: HostListener,
346
+ args: ['window:scroll', ['$event']]
347
+ }, {
348
+ type: HostListener,
349
+ args: ['window:resize', ['$event']]
350
+ }], onClickOutside: [{
351
+ type: HostListener,
352
+ args: ['document:click', ['$event']]
353
+ }], __hostClass: [{
354
+ type: HostBinding,
355
+ args: ['class']
356
+ }] } });
357
+
358
+ /**
359
+ * Represents a menu component that displays context menu.
360
+ * @category Components
361
+ */
362
+ class AXContextMenuComponent extends MXBaseComponent {
363
+ // Constructor (Dependency Injection)
364
+ /** @ignore */
365
+ constructor(renderer) {
366
+ super();
367
+ this.renderer = renderer;
368
+ // Inputs and Outputs
369
+ this.orientation = input('vertical');
370
+ this.openOn = input('hover');
371
+ this.closeOn = input('click');
372
+ this.orginalItems = input([], { alias: "items" });
373
+ this.target = input();
374
+ this.onItemClick = output();
375
+ this.onOpening = output();
376
+ // Injected Services
377
+ this.service = inject(AXMenuService);
378
+ // Private Properties
379
+ this.scrollableParents = [];
380
+ this.items = signal([]);
381
+ afterNextRender(() => {
382
+ if (this.target()) {
383
+ this.target().addEventListener('contextmenu', this.handleContextMenu.bind(this));
384
+ }
385
+ this.bindScrollEvents();
386
+ });
387
+ this.service.closeAllContextMenu$.subscribe(() => {
388
+ this.service.closeAll$.next();
389
+ this.close();
390
+ });
391
+ this.service.openContextMenu$.subscribe((e) => {
392
+ if (e.sender == this) {
393
+ this.internalShowAt(e.point);
394
+ }
395
+ });
396
+ }
397
+ // Lifecycle Hooks
398
+ ngOnDestroy() {
399
+ this.removeScrollEvents();
400
+ }
401
+ // Public Methods
402
+ showAt(point) {
403
+ const sender = this;
404
+ this.service.closeAllContextMenu$.next({ sender });
405
+ this.service.openContextMenu$.next({ sender, point });
406
+ }
407
+ close() {
408
+ const elementRef = this.getHostElement();
409
+ elementRef.classList.remove('ax-state-open');
153
410
  }
411
+ // Private Methods (Internal Logic)
154
412
  /** @ignore */
155
- __hostClick(e) {
156
- if (!this.disabled) {
157
- this.onClick.emit({
158
- component: this,
159
- htmlElement: this.getHostElement(),
160
- nativeEvent: e,
161
- });
162
- if (!this.children.length) {
163
- this.menuService.activeMenus$.subscribe((c) => c.forEach((x) => x.close())).unsubscribe();
164
- this.menuService.activeMenus$.next([]);
413
+ handleContextMenu(e) {
414
+ e.preventDefault();
415
+ e.stopPropagation();
416
+ //
417
+ const event = {
418
+ component: this,
419
+ htmlElement: this.getHostElement(),
420
+ nativeEvent: e,
421
+ canceled: false,
422
+ items: cloneDeep(this.orginalItems()),
423
+ };
424
+ this.onOpening.emit(event);
425
+ this.items.set(event.items);
426
+ //
427
+ if (!event.canceled) {
428
+ this.showAt({ x: e.clientX, y: e.clientY });
429
+ }
430
+ }
431
+ internalShowAt(point) {
432
+ const elementRef = this.getHostElement();
433
+ elementRef.classList.add('ax-state-open');
434
+ const itemRect = elementRef.getBoundingClientRect();
435
+ const windowWidth = window.innerWidth;
436
+ const windowHeight = window.innerHeight;
437
+ // Detect RTL (Right-To-Left) mode
438
+ const isRtl = AXHtmlUtil.isRtl(this.getHostElement());
439
+ let left;
440
+ if (isRtl) {
441
+ left = point.x - itemRect.width;
442
+ if (left < 0) {
443
+ left = point.x;
165
444
  }
166
445
  }
446
+ else {
447
+ left = point.x;
448
+ if (left + itemRect.width > windowWidth) {
449
+ left = point.x - itemRect.width;
450
+ }
451
+ }
452
+ const bottom = point.y + itemRect.height;
453
+ let top;
454
+ if (bottom > windowHeight) {
455
+ top = point.y - itemRect.height;
456
+ if (top < 0) {
457
+ top = 0;
458
+ }
459
+ }
460
+ else {
461
+ top = point.y;
462
+ }
463
+ this.renderer.setStyle(elementRef, 'left', `${left}px`);
464
+ this.renderer.setStyle(elementRef, 'top', `${top}px`);
465
+ this.renderer.setStyle(elementRef, 'position', 'fixed');
466
+ }
467
+ bindScrollEvents() {
468
+ this.scrollableParents = AXHtmlUtil.getScrollableParents(this.getHostElement());
469
+ this.scrollableParents.forEach((parent) => {
470
+ parent.addEventListener('scroll', this.onContainerScroll.bind(this));
471
+ });
472
+ }
473
+ removeScrollEvents() {
474
+ this.scrollableParents.forEach((parent) => {
475
+ parent.removeEventListener('scroll', this.onContainerScroll.bind(this));
476
+ });
477
+ }
478
+ onContainerScroll() {
479
+ this.service.closeAllContextMenu$.next({ sender: this });
480
+ }
481
+ // Host Listeners (UI Interaction Handling)
482
+ /** @ignore */
483
+ onClickOutside(event) {
484
+ const hostElement = this.getHostElement();
485
+ if (!hostElement.contains(event.target)) {
486
+ const sender = this;
487
+ this.service.closeAllContextMenu$.next({ sender });
488
+ }
167
489
  }
168
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.0", ngImport: i0, type: AXMenuItemComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
169
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.0", type: AXMenuItemComponent, selector: "ax-menu-item", inputs: { disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: false, isRequired: false, transformFunction: null }, active: { classPropertyName: "active", publicName: "active", isSignal: true, isRequired: false, transformFunction: null }, arrowState: { classPropertyName: "arrowState", publicName: "arrowState", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { activeChange: "activeChange", onClick: "onClick" }, host: { attributes: { "ngSkipHydration": "true" }, listeners: { "click": "__hostClick($event)" }, properties: { "class": "this.__hostClass" } }, queries: [{ propertyName: "children", predicate: AXMenuItemComponent }], viewQueries: [{ propertyName: "popover", first: true, predicate: AXPopoverComponent, descendants: true }], usesInheritance: true, ngImport: i0, template: "<div class=\"ax-menu-item-start-side\">\n <ng-content select=\"ax-prefix\"></ng-content>\n <ng-content select=\"ax-text\"></ng-content>\n <ng-content></ng-content>\n</div>\n<ng-content select=\"ax-suffix\"></ng-content>\n@if (children.length && arrowState()) {\n <i class=\"ax-icon ax-icon-solid {{ getIcon() }} ax-menu-item-child-icon\"></i>\n}\n\n<ax-popover\n #popover\n [closeOn]=\"'clickOut'\"\n [openOn]=\"rootMenu.openOn()\"\n [target]=\"getHostElement()\"\n [offsetY]=\"offsetY()\"\n [offsetX]=\"offsetX()\"\n [placement]=\"getPlacement()\"\n (onOpened)=\"_handleOnOpened()\"\n (onClosed)=\"_handleOnClosed()\"\n>\n <div class=\"ax-menu-item-children ax-parent-{{ this.rootMenu.orientation() }}\">\n <ng-content select=\"ax-menu-item\"></ng-content>\n </div>\n</ax-popover>\n", dependencies: [{ kind: "component", type: i1.AXPopoverComponent, selector: "ax-popover", inputs: ["offsetX", "offsetY", "target", "placement", "content", "openOn", "closeOn", "hasBackdrop", "openAfter", "closeAfter", "backdropClass", "adaptivityEnabled"], outputs: ["onOpened", "onClosed"] }], encapsulation: i0.ViewEncapsulation.None }); }
490
+ onContextMenuOutside(event) {
491
+ if (!this.target().contains(event.target)) {
492
+ const sender = this;
493
+ this.service.closeAllContextMenu$.next({ sender });
494
+ }
495
+ }
496
+ /** @ignore */
497
+ get __hostClass() {
498
+ return ['ax-menu-container', `ax-orientation-${this.orientation()}`];
499
+ }
500
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.0", ngImport: i0, type: AXContextMenuComponent, deps: [{ token: i0.Renderer2 }], target: i0.ɵɵFactoryTarget.Component }); }
501
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.0", type: AXContextMenuComponent, selector: "ax-context-menu", inputs: { orientation: { classPropertyName: "orientation", publicName: "orientation", isSignal: true, isRequired: false, transformFunction: null }, openOn: { classPropertyName: "openOn", publicName: "openOn", isSignal: true, isRequired: false, transformFunction: null }, closeOn: { classPropertyName: "closeOn", publicName: "closeOn", isSignal: true, isRequired: false, transformFunction: null }, orginalItems: { classPropertyName: "orginalItems", publicName: "items", isSignal: true, isRequired: false, transformFunction: null }, target: { classPropertyName: "target", publicName: "target", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { onItemClick: "onItemClick", onOpening: "onOpening" }, host: { listeners: { "document:click": "onClickOutside($event)", "document:contextmenu": "onContextMenuOutside($event)" }, properties: { "class": "this.__hostClass" } }, providers: [
502
+ AXMenuService,
503
+ {
504
+ provide: AXRootMenu,
505
+ useExisting: AXContextMenuComponent
506
+ }
507
+ ], usesInheritance: true, ngImport: i0, template: "<ng-content select=\"ax-menu-item,ax-title,ng-container\"></ng-content>\n\n<ng-container *ngFor=\"let node of items()\" [ngTemplateOutlet]=\"Recursion\"\n [ngTemplateOutletContext]=\"{ $implicit: node }\">\n</ng-container>\n<ng-template #Recursion let-item>\n @if(item.group?.title)\n {\n <ax-title>{{item.group?.title}}</ax-title>\n }\n <ax-menu-item [name]=\"item.name\" [data]=\"item.data\" [disabled]=\"item.disabled\" [color]=\"item.color\">\n <ax-prefix>\n @if(item.icon)\n {\n <ax-icon [icon]=\"item.icon\">\n </ax-icon>\n }\n </ax-prefix>\n @if(item.text)\n {\n <ax-text>{{ item.text }}</ax-text>\n }\n @if(item.suffix)\n {\n <ax-suffix>\n <ax-text>{{ item.suffix.text }}</ax-text>\n </ax-suffix>\n }\n <ng-container *ngFor=\"let child of item.children\" [ngTemplateOutlet]=\"Recursion\"\n [ngTemplateOutletContext]=\"{ $implicit: child }\"></ng-container>\n </ax-menu-item>\n @if(item.break)\n {\n <ax-divider></ax-divider>\n }\n</ng-template>", styles: ["ax-context-menu,ax-menu{width:100%;color:inherit;display:flex;width:max-content}ax-context-menu.ax-orientation-horizontal,ax-menu.ax-orientation-horizontal{flex-direction:row!important}ax-context-menu.ax-orientation-vertical,ax-menu.ax-orientation-vertical{flex-direction:column!important}ax-context-menu ax-title,ax-menu ax-title{display:block;padding-inline:1rem;padding-block:.25rem;font-size:.75rem;line-height:1rem;font-weight:bolder;text-transform:uppercase;opacity:.5}ax-context-menu ax-divider,ax-menu ax-divider{margin-top:.25rem;margin-bottom:.25rem;height:.5px;width:100%;background-color:rgba(var(--ax-color-border-default))}ax-context-menu ax-menu-item,ax-menu ax-menu-item{display:flex;align-items:center;font-size:.875rem;line-height:1.25rem;justify-content:space-between;color:rgba(var(--ax-color-text-default));height:2.25rem;cursor:pointer}ax-context-menu ax-menu-item>.ax-menu-item-prefix,ax-menu ax-menu-item>.ax-menu-item-prefix{display:flex;gap:.5rem}ax-context-menu ax-menu-item.ax-state-disabled,ax-menu ax-menu-item.ax-state-disabled{cursor:not-allowed;opacity:.5}ax-context-menu ax-menu-item ax-suffix ax-text,ax-menu ax-menu-item ax-suffix ax-text{color:rgba(var(--ax-color-text-default))!important;opacity:.5!important;font-weight:200!important;padding-inline-start:2rem}ax-context-menu.ax-menu-container,ax-context-menu .ax-menu-items,ax-menu.ax-menu-container,ax-menu .ax-menu-items{padding-block:.5rem;display:flex;opacity:0;visibility:hidden;transition:opacity .3s;width:max-content;min-width:12rem;height:max-content;position:fixed;flex-direction:column;border-radius:0;border-width:1px;border-color:rgba(var(--ax-color-border-default));background-color:rgba(var(--ax-color-surface));--ax-shadow: 0 4px 6px -1px rgb(0 0 0 / .1), 0 2px 4px -2px rgb(0 0 0 / .1);--ax-shadow-colored: 0 4px 6px -1px var(--ax-shadow-color), 0 2px 4px -2px var(--ax-shadow-color);box-shadow:var(--ax-ring-offset-shadow, 0 0 rgba(0, 0, 0, 0)),var(--ax-ring-shadow, 0 0 rgba(0, 0, 0, 0)),var(--ax-shadow);border-radius:var(--ax-rounded-border-default);z-index:9999}ax-context-menu.ax-menu-container.ax-state-open,ax-context-menu .ax-menu-items.ax-state-open,ax-menu.ax-menu-container.ax-state-open,ax-menu .ax-menu-items.ax-state-open{opacity:1;visibility:visible}ax-context-menu.ax-menu-container ax-menu-item,ax-context-menu .ax-menu-items ax-menu-item,ax-menu.ax-menu-container ax-menu-item,ax-menu .ax-menu-items ax-menu-item{padding-inline:1rem;padding-block:.5rem}ax-context-menu.ax-menu-container ax-menu-item ax-prefix,ax-context-menu .ax-menu-items ax-menu-item ax-prefix,ax-menu.ax-menu-container ax-menu-item ax-prefix,ax-menu .ax-menu-items ax-menu-item ax-prefix{width:1rem}ax-context-menu.ax-menu-container ax-menu-item:hover:not(ax-context-menu.ax-menu-container ax-menu-item:hover.ax-state-disabled,ax-context-menu .ax-menu-items ax-menu-item:hover.ax-state-disabled,ax-menu.ax-menu-container ax-menu-item:hover.ax-state-disabled,ax-menu .ax-menu-items ax-menu-item:hover.ax-state-disabled),ax-context-menu .ax-menu-items ax-menu-item:hover:not(ax-context-menu.ax-menu-container ax-menu-item:hover.ax-state-disabled,ax-context-menu .ax-menu-items ax-menu-item:hover.ax-state-disabled,ax-menu.ax-menu-container ax-menu-item:hover.ax-state-disabled,ax-menu .ax-menu-items ax-menu-item:hover.ax-state-disabled),ax-menu.ax-menu-container ax-menu-item:hover:not(ax-context-menu.ax-menu-container ax-menu-item:hover.ax-state-disabled,ax-context-menu .ax-menu-items ax-menu-item:hover.ax-state-disabled,ax-menu.ax-menu-container ax-menu-item:hover.ax-state-disabled,ax-menu .ax-menu-items ax-menu-item:hover.ax-state-disabled),ax-menu .ax-menu-items ax-menu-item:hover:not(ax-context-menu.ax-menu-container ax-menu-item:hover.ax-state-disabled,ax-context-menu .ax-menu-items ax-menu-item:hover.ax-state-disabled,ax-menu.ax-menu-container ax-menu-item:hover.ax-state-disabled,ax-menu .ax-menu-items ax-menu-item:hover.ax-state-disabled){background-color:rgba(var(--ax-color-on-surface))}ax-context-menu.ax-menu-container ax-menu-item:hover:not(ax-context-menu.ax-menu-container ax-menu-item:hover.ax-state-disabled,ax-context-menu .ax-menu-items ax-menu-item:hover.ax-state-disabled,ax-menu.ax-menu-container ax-menu-item:hover.ax-state-disabled,ax-menu .ax-menu-items ax-menu-item:hover.ax-state-disabled) ax-prefix,ax-context-menu.ax-menu-container ax-menu-item:hover:not(ax-context-menu.ax-menu-container ax-menu-item:hover.ax-state-disabled,ax-context-menu .ax-menu-items ax-menu-item:hover.ax-state-disabled,ax-menu.ax-menu-container ax-menu-item:hover.ax-state-disabled,ax-menu .ax-menu-items ax-menu-item:hover.ax-state-disabled) ax-suffix,ax-context-menu .ax-menu-items ax-menu-item:hover:not(ax-context-menu.ax-menu-container ax-menu-item:hover.ax-state-disabled,ax-context-menu .ax-menu-items ax-menu-item:hover.ax-state-disabled,ax-menu.ax-menu-container ax-menu-item:hover.ax-state-disabled,ax-menu .ax-menu-items ax-menu-item:hover.ax-state-disabled) ax-prefix,ax-context-menu .ax-menu-items ax-menu-item:hover:not(ax-context-menu.ax-menu-container ax-menu-item:hover.ax-state-disabled,ax-context-menu .ax-menu-items ax-menu-item:hover.ax-state-disabled,ax-menu.ax-menu-container ax-menu-item:hover.ax-state-disabled,ax-menu .ax-menu-items ax-menu-item:hover.ax-state-disabled) ax-suffix,ax-menu.ax-menu-container ax-menu-item:hover:not(ax-context-menu.ax-menu-container ax-menu-item:hover.ax-state-disabled,ax-context-menu .ax-menu-items ax-menu-item:hover.ax-state-disabled,ax-menu.ax-menu-container ax-menu-item:hover.ax-state-disabled,ax-menu .ax-menu-items ax-menu-item:hover.ax-state-disabled) ax-prefix,ax-menu.ax-menu-container ax-menu-item:hover:not(ax-context-menu.ax-menu-container ax-menu-item:hover.ax-state-disabled,ax-context-menu .ax-menu-items ax-menu-item:hover.ax-state-disabled,ax-menu.ax-menu-container ax-menu-item:hover.ax-state-disabled,ax-menu .ax-menu-items ax-menu-item:hover.ax-state-disabled) ax-suffix,ax-menu .ax-menu-items ax-menu-item:hover:not(ax-context-menu.ax-menu-container ax-menu-item:hover.ax-state-disabled,ax-context-menu .ax-menu-items ax-menu-item:hover.ax-state-disabled,ax-menu.ax-menu-container ax-menu-item:hover.ax-state-disabled,ax-menu .ax-menu-items ax-menu-item:hover.ax-state-disabled) ax-prefix,ax-menu .ax-menu-items ax-menu-item:hover:not(ax-context-menu.ax-menu-container ax-menu-item:hover.ax-state-disabled,ax-context-menu .ax-menu-items ax-menu-item:hover.ax-state-disabled,ax-menu.ax-menu-container ax-menu-item:hover.ax-state-disabled,ax-menu .ax-menu-items ax-menu-item:hover.ax-state-disabled) ax-suffix{opacity:1}ax-context-menu.ax-orientation-horizontal{padding-inline:1rem}ax-menu.ax-orientation-horizontal{min-width:12rem;gap:.875rem}ax-menu.ax-orientation-horizontal>ax-menu-item{font-weight:500}ax-menu.ax-orientation-vertical{width:max-content;min-width:12rem}ax-menu.ax-orientation-vertical>ax-menu-item{padding-inline:1rem;font-weight:500}ax-menu>ax-menu-item{padding-block:.5rem}ax-menu>ax-menu-item:hover:not(ax-menu>ax-menu-item:hover.ax-state-disabled)>ax-icon,ax-menu>ax-menu-item:hover:not(ax-menu>ax-menu-item:hover.ax-state-disabled)>ax-text{color:rgba(var(--ax-color-primary-500))}\n"], dependencies: [{ kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: i2.AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { kind: "component", type: i2.AXDecoratorGenericComponent, selector: "ax-footer, ax-header, ax-content, ax-divider, ax-form-hint, ax-prefix, ax-suffix, ax-text, ax-title, ax-sub-title, ax-placeholder, ax-overlay" }, { kind: "component", type: AXMenuItemComponent, selector: "ax-menu-item", inputs: ["name", "data", "disabled", "color"], outputs: ["onClick"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
170
508
  }
171
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.0", ngImport: i0, type: AXMenuItemComponent, decorators: [{
509
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.0", ngImport: i0, type: AXContextMenuComponent, decorators: [{
172
510
  type: Component,
173
- args: [{ selector: 'ax-menu-item', inputs: ['disabled'], host: { ngSkipHydration: 'true' }, encapsulation: ViewEncapsulation.None, template: "<div class=\"ax-menu-item-start-side\">\n <ng-content select=\"ax-prefix\"></ng-content>\n <ng-content select=\"ax-text\"></ng-content>\n <ng-content></ng-content>\n</div>\n<ng-content select=\"ax-suffix\"></ng-content>\n@if (children.length && arrowState()) {\n <i class=\"ax-icon ax-icon-solid {{ getIcon() }} ax-menu-item-child-icon\"></i>\n}\n\n<ax-popover\n #popover\n [closeOn]=\"'clickOut'\"\n [openOn]=\"rootMenu.openOn()\"\n [target]=\"getHostElement()\"\n [offsetY]=\"offsetY()\"\n [offsetX]=\"offsetX()\"\n [placement]=\"getPlacement()\"\n (onOpened)=\"_handleOnOpened()\"\n (onClosed)=\"_handleOnClosed()\"\n>\n <div class=\"ax-menu-item-children ax-parent-{{ this.rootMenu.orientation() }}\">\n <ng-content select=\"ax-menu-item\"></ng-content>\n </div>\n</ax-popover>\n" }]
174
- }], ctorParameters: () => [], propDecorators: { popover: [{
175
- type: ViewChild,
176
- args: [AXPopoverComponent]
177
- }], children: [{
178
- type: ContentChildren,
179
- args: [AXMenuItemComponent]
511
+ args: [{ selector: 'ax-context-menu', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, providers: [
512
+ AXMenuService,
513
+ {
514
+ provide: AXRootMenu,
515
+ useExisting: AXContextMenuComponent
516
+ }
517
+ ], template: "<ng-content select=\"ax-menu-item,ax-title,ng-container\"></ng-content>\n\n<ng-container *ngFor=\"let node of items()\" [ngTemplateOutlet]=\"Recursion\"\n [ngTemplateOutletContext]=\"{ $implicit: node }\">\n</ng-container>\n<ng-template #Recursion let-item>\n @if(item.group?.title)\n {\n <ax-title>{{item.group?.title}}</ax-title>\n }\n <ax-menu-item [name]=\"item.name\" [data]=\"item.data\" [disabled]=\"item.disabled\" [color]=\"item.color\">\n <ax-prefix>\n @if(item.icon)\n {\n <ax-icon [icon]=\"item.icon\">\n </ax-icon>\n }\n </ax-prefix>\n @if(item.text)\n {\n <ax-text>{{ item.text }}</ax-text>\n }\n @if(item.suffix)\n {\n <ax-suffix>\n <ax-text>{{ item.suffix.text }}</ax-text>\n </ax-suffix>\n }\n <ng-container *ngFor=\"let child of item.children\" [ngTemplateOutlet]=\"Recursion\"\n [ngTemplateOutletContext]=\"{ $implicit: child }\"></ng-container>\n </ax-menu-item>\n @if(item.break)\n {\n <ax-divider></ax-divider>\n }\n</ng-template>", styles: ["ax-context-menu,ax-menu{width:100%;color:inherit;display:flex;width:max-content}ax-context-menu.ax-orientation-horizontal,ax-menu.ax-orientation-horizontal{flex-direction:row!important}ax-context-menu.ax-orientation-vertical,ax-menu.ax-orientation-vertical{flex-direction:column!important}ax-context-menu ax-title,ax-menu ax-title{display:block;padding-inline:1rem;padding-block:.25rem;font-size:.75rem;line-height:1rem;font-weight:bolder;text-transform:uppercase;opacity:.5}ax-context-menu ax-divider,ax-menu ax-divider{margin-top:.25rem;margin-bottom:.25rem;height:.5px;width:100%;background-color:rgba(var(--ax-color-border-default))}ax-context-menu ax-menu-item,ax-menu ax-menu-item{display:flex;align-items:center;font-size:.875rem;line-height:1.25rem;justify-content:space-between;color:rgba(var(--ax-color-text-default));height:2.25rem;cursor:pointer}ax-context-menu ax-menu-item>.ax-menu-item-prefix,ax-menu ax-menu-item>.ax-menu-item-prefix{display:flex;gap:.5rem}ax-context-menu ax-menu-item.ax-state-disabled,ax-menu ax-menu-item.ax-state-disabled{cursor:not-allowed;opacity:.5}ax-context-menu ax-menu-item ax-suffix ax-text,ax-menu ax-menu-item ax-suffix ax-text{color:rgba(var(--ax-color-text-default))!important;opacity:.5!important;font-weight:200!important;padding-inline-start:2rem}ax-context-menu.ax-menu-container,ax-context-menu .ax-menu-items,ax-menu.ax-menu-container,ax-menu .ax-menu-items{padding-block:.5rem;display:flex;opacity:0;visibility:hidden;transition:opacity .3s;width:max-content;min-width:12rem;height:max-content;position:fixed;flex-direction:column;border-radius:0;border-width:1px;border-color:rgba(var(--ax-color-border-default));background-color:rgba(var(--ax-color-surface));--ax-shadow: 0 4px 6px -1px rgb(0 0 0 / .1), 0 2px 4px -2px rgb(0 0 0 / .1);--ax-shadow-colored: 0 4px 6px -1px var(--ax-shadow-color), 0 2px 4px -2px var(--ax-shadow-color);box-shadow:var(--ax-ring-offset-shadow, 0 0 rgba(0, 0, 0, 0)),var(--ax-ring-shadow, 0 0 rgba(0, 0, 0, 0)),var(--ax-shadow);border-radius:var(--ax-rounded-border-default);z-index:9999}ax-context-menu.ax-menu-container.ax-state-open,ax-context-menu .ax-menu-items.ax-state-open,ax-menu.ax-menu-container.ax-state-open,ax-menu .ax-menu-items.ax-state-open{opacity:1;visibility:visible}ax-context-menu.ax-menu-container ax-menu-item,ax-context-menu .ax-menu-items ax-menu-item,ax-menu.ax-menu-container ax-menu-item,ax-menu .ax-menu-items ax-menu-item{padding-inline:1rem;padding-block:.5rem}ax-context-menu.ax-menu-container ax-menu-item ax-prefix,ax-context-menu .ax-menu-items ax-menu-item ax-prefix,ax-menu.ax-menu-container ax-menu-item ax-prefix,ax-menu .ax-menu-items ax-menu-item ax-prefix{width:1rem}ax-context-menu.ax-menu-container ax-menu-item:hover:not(ax-context-menu.ax-menu-container ax-menu-item:hover.ax-state-disabled,ax-context-menu .ax-menu-items ax-menu-item:hover.ax-state-disabled,ax-menu.ax-menu-container ax-menu-item:hover.ax-state-disabled,ax-menu .ax-menu-items ax-menu-item:hover.ax-state-disabled),ax-context-menu .ax-menu-items ax-menu-item:hover:not(ax-context-menu.ax-menu-container ax-menu-item:hover.ax-state-disabled,ax-context-menu .ax-menu-items ax-menu-item:hover.ax-state-disabled,ax-menu.ax-menu-container ax-menu-item:hover.ax-state-disabled,ax-menu .ax-menu-items ax-menu-item:hover.ax-state-disabled),ax-menu.ax-menu-container ax-menu-item:hover:not(ax-context-menu.ax-menu-container ax-menu-item:hover.ax-state-disabled,ax-context-menu .ax-menu-items ax-menu-item:hover.ax-state-disabled,ax-menu.ax-menu-container ax-menu-item:hover.ax-state-disabled,ax-menu .ax-menu-items ax-menu-item:hover.ax-state-disabled),ax-menu .ax-menu-items ax-menu-item:hover:not(ax-context-menu.ax-menu-container ax-menu-item:hover.ax-state-disabled,ax-context-menu .ax-menu-items ax-menu-item:hover.ax-state-disabled,ax-menu.ax-menu-container ax-menu-item:hover.ax-state-disabled,ax-menu .ax-menu-items ax-menu-item:hover.ax-state-disabled){background-color:rgba(var(--ax-color-on-surface))}ax-context-menu.ax-menu-container ax-menu-item:hover:not(ax-context-menu.ax-menu-container ax-menu-item:hover.ax-state-disabled,ax-context-menu .ax-menu-items ax-menu-item:hover.ax-state-disabled,ax-menu.ax-menu-container ax-menu-item:hover.ax-state-disabled,ax-menu .ax-menu-items ax-menu-item:hover.ax-state-disabled) ax-prefix,ax-context-menu.ax-menu-container ax-menu-item:hover:not(ax-context-menu.ax-menu-container ax-menu-item:hover.ax-state-disabled,ax-context-menu .ax-menu-items ax-menu-item:hover.ax-state-disabled,ax-menu.ax-menu-container ax-menu-item:hover.ax-state-disabled,ax-menu .ax-menu-items ax-menu-item:hover.ax-state-disabled) ax-suffix,ax-context-menu .ax-menu-items ax-menu-item:hover:not(ax-context-menu.ax-menu-container ax-menu-item:hover.ax-state-disabled,ax-context-menu .ax-menu-items ax-menu-item:hover.ax-state-disabled,ax-menu.ax-menu-container ax-menu-item:hover.ax-state-disabled,ax-menu .ax-menu-items ax-menu-item:hover.ax-state-disabled) ax-prefix,ax-context-menu .ax-menu-items ax-menu-item:hover:not(ax-context-menu.ax-menu-container ax-menu-item:hover.ax-state-disabled,ax-context-menu .ax-menu-items ax-menu-item:hover.ax-state-disabled,ax-menu.ax-menu-container ax-menu-item:hover.ax-state-disabled,ax-menu .ax-menu-items ax-menu-item:hover.ax-state-disabled) ax-suffix,ax-menu.ax-menu-container ax-menu-item:hover:not(ax-context-menu.ax-menu-container ax-menu-item:hover.ax-state-disabled,ax-context-menu .ax-menu-items ax-menu-item:hover.ax-state-disabled,ax-menu.ax-menu-container ax-menu-item:hover.ax-state-disabled,ax-menu .ax-menu-items ax-menu-item:hover.ax-state-disabled) ax-prefix,ax-menu.ax-menu-container ax-menu-item:hover:not(ax-context-menu.ax-menu-container ax-menu-item:hover.ax-state-disabled,ax-context-menu .ax-menu-items ax-menu-item:hover.ax-state-disabled,ax-menu.ax-menu-container ax-menu-item:hover.ax-state-disabled,ax-menu .ax-menu-items ax-menu-item:hover.ax-state-disabled) ax-suffix,ax-menu .ax-menu-items ax-menu-item:hover:not(ax-context-menu.ax-menu-container ax-menu-item:hover.ax-state-disabled,ax-context-menu .ax-menu-items ax-menu-item:hover.ax-state-disabled,ax-menu.ax-menu-container ax-menu-item:hover.ax-state-disabled,ax-menu .ax-menu-items ax-menu-item:hover.ax-state-disabled) ax-prefix,ax-menu .ax-menu-items ax-menu-item:hover:not(ax-context-menu.ax-menu-container ax-menu-item:hover.ax-state-disabled,ax-context-menu .ax-menu-items ax-menu-item:hover.ax-state-disabled,ax-menu.ax-menu-container ax-menu-item:hover.ax-state-disabled,ax-menu .ax-menu-items ax-menu-item:hover.ax-state-disabled) ax-suffix{opacity:1}ax-context-menu.ax-orientation-horizontal{padding-inline:1rem}ax-menu.ax-orientation-horizontal{min-width:12rem;gap:.875rem}ax-menu.ax-orientation-horizontal>ax-menu-item{font-weight:500}ax-menu.ax-orientation-vertical{width:max-content;min-width:12rem}ax-menu.ax-orientation-vertical>ax-menu-item{padding-inline:1rem;font-weight:500}ax-menu>ax-menu-item{padding-block:.5rem}ax-menu>ax-menu-item:hover:not(ax-menu>ax-menu-item:hover.ax-state-disabled)>ax-icon,ax-menu>ax-menu-item:hover:not(ax-menu>ax-menu-item:hover.ax-state-disabled)>ax-text{color:rgba(var(--ax-color-primary-500))}\n"] }]
518
+ }], ctorParameters: () => [{ type: i0.Renderer2 }], propDecorators: { onClickOutside: [{
519
+ type: HostListener,
520
+ args: ['document:click', ['$event']]
521
+ }], onContextMenuOutside: [{
522
+ type: HostListener,
523
+ args: ['document:contextmenu', ['$event']]
180
524
  }], __hostClass: [{
181
525
  type: HostBinding,
182
526
  args: ['class']
183
- }], __hostClick: [{
184
- type: HostListener,
185
- args: ['click', ['$event']]
186
527
  }] } });
187
528
 
188
529
  /**
@@ -193,62 +534,54 @@ class AXMenuComponent extends MXBaseComponent {
193
534
  constructor() {
194
535
  super(...arguments);
195
536
  this.orientation = input('horizontal');
196
- this.openOn = input('toggle');
537
+ this.openOn = input('hover');
538
+ this.closeOn = input('leave');
197
539
  this.service = inject(AXMenuService);
198
- }
199
- /** @ignore */
200
- ngAfterViewInit() {
201
- this.children.forEach((c) => {
202
- c.isRoot = true;
203
- c.parent = this;
204
- });
540
+ this.onItemClick = output();
541
+ this.items = input([]);
205
542
  }
206
543
  /** @ignore */
207
544
  get __hostClass() {
208
545
  return `ax-orientation-${this.orientation()}`;
209
546
  }
547
+ close() {
548
+ this.service.closeAll$.next();
549
+ }
210
550
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.0", ngImport: i0, type: AXMenuComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
211
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "18.2.0", type: AXMenuComponent, selector: "ax-menu", inputs: { orientation: { classPropertyName: "orientation", publicName: "orientation", isSignal: true, isRequired: false, transformFunction: null }, openOn: { classPropertyName: "openOn", publicName: "openOn", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class": "this.__hostClass" } }, providers: [
551
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.0", type: AXMenuComponent, selector: "ax-menu", inputs: { orientation: { classPropertyName: "orientation", publicName: "orientation", isSignal: true, isRequired: false, transformFunction: null }, openOn: { classPropertyName: "openOn", publicName: "openOn", isSignal: true, isRequired: false, transformFunction: null }, closeOn: { classPropertyName: "closeOn", publicName: "closeOn", isSignal: true, isRequired: false, transformFunction: null }, items: { classPropertyName: "items", publicName: "items", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { onItemClick: "onItemClick" }, host: { properties: { "class": "this.__hostClass" } }, providers: [
552
+ AXMenuService,
212
553
  {
213
554
  provide: AXRootMenu,
214
- useExisting: AXMenuComponent,
215
- },
216
- {
217
- provide: AXMenuService,
218
- },
219
- ], queries: [{ propertyName: "children", predicate: AXMenuItemComponent }], usesInheritance: true, ngImport: i0, template: ` <ng-content select="ax-menu-item,ng-container"></ng-content>`, isInline: true, styles: ["ax-menu{width:100%;font-size:.875rem;line-height:1.25rem;color:inherit;position:relative}ax-menu.ax-orientation-horizontal{display:flex}ax-menu.ax-orientation-horizontal ax-menu-item:not(ax-menu.ax-orientation-horizontal ax-menu-item:last-child){margin-inline-end:1rem}ax-menu.ax-orientation-vertical{display:flex;flex-direction:column}ax-menu.ax-orientation-vertical ax-menu-item{justify-content:space-between}ax-menu.ax-orientation-vertical ax-menu-item:not(ax-menu.ax-orientation-vertical ax-menu-item:last-child){margin-bottom:1rem}ax-menu ax-menu-item:hover:not(ax-menu ax-menu-item:hover.ax-state-disabled){color:rgba(var(--ax-color-primary-500))}ax-menu-item{position:relative;display:flex;align-items:center;gap:.5rem;font-size:.875rem;line-height:1.25rem;font-weight:500;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s;justify-content:space-between;color:rgba(var(--ax-color-text-default))}ax-menu-item .ax-menu-item-text{white-space:nowrap}ax-menu-item:not(ax-menu-item.ax-state-disabled){cursor:pointer}ax-menu-item .ax-menu-item-start-side{display:flex;align-items:center;gap:.5rem}ax-menu-item.ax-state-disabled{cursor:not-allowed;opacity:.5}ax-menu-item.ax-state-selected{color:rgba(var(--ax-color-primary-500))}ax-menu-item .ax-menu-item-child-icon{width:fit-content;line-height:1;font-size:10px}ax-menu-item ax-popover{position:absolute}.ax-menu-item-children{padding-top:.5rem;padding-bottom:.5rem}.ax-menu-item-children:not(.ax-menu-item-children:empty){display:flex;min-width:12rem;flex-direction:column;border-radius:var(--ax-rounded-border-default);border-width:1px;border-color:rgba(var(--ax-color-border-default));background-color:rgba(var(--ax-color-surface))}.ax-menu-item-children:not(.ax-menu-item-children:empty) ax-menu-item{padding:.5rem 1rem;font-size:.875rem;line-height:1.25rem}.ax-menu-item-children:not(.ax-menu-item-children:empty) ax-menu-item:hover:not(.ax-menu-item-children:not(.ax-menu-item-children:empty) ax-menu-item:hover.ax-state-disabled){background-color:rgba(var(--ax-color-on-surface))}.ax-menu-item-children:not(.ax-menu-item-children:empty) ax-menu-item:hover:not(.ax-menu-item-children:not(.ax-menu-item-children:empty) ax-menu-item:hover.ax-state-disabled) ax-prefix,.ax-menu-item-children:not(.ax-menu-item-children:empty) ax-menu-item:hover:not(.ax-menu-item-children:not(.ax-menu-item-children:empty) ax-menu-item:hover.ax-state-disabled) ax-suffix{opacity:1}.ax-menu-item-children:not(.ax-menu-item-children:empty) ax-menu-item ax-prefix,.ax-menu-item-children:not(.ax-menu-item-children:empty) ax-menu-item ax-suffix{opacity:.75}.ax-menu-item-children:not(.ax-menu-item-children:empty) ax-menu-item .ax-menu-item-text{flex:1 1 0%}html[dir=rtl] .ax-parent-horizontal .ax-menu-item-child-icon{transform:rotate(-90deg)}html[dir=rtl] .ax-parent-horizontal .ax-menu-item-child-icon:before{-moz-transform:scale(1,-1);-webkit-transform:scale(1,-1);-o-transform:scale(1,-1);-ms-transform:scale(1,-1);transform:scaleY(-1)}.ax-parent-horizontal .ax-menu-item-child-icon{transform:rotate(-90deg)}\n"], encapsulation: i0.ViewEncapsulation.None }); }
555
+ useExisting: AXMenuComponent
556
+ }
557
+ ], usesInheritance: true, ngImport: i0, template: "<ng-content select=\"ax-menu-item,ax-title,ng-container\"></ng-content>\n\n<ng-container *ngFor=\"let node of items()\" [ngTemplateOutlet]=\"Recursion\"\n [ngTemplateOutletContext]=\"{ $implicit: node }\">\n</ng-container>\n<ng-template #Recursion let-item>\n @if(item.group?.title)\n {\n <ax-title>{{item.group?.title}}</ax-title>\n }\n <ax-menu-item [name]=\"item.name\" [data]=\"item.data\" [disabled]=\"item.disabled\" [color]=\"item.color\">\n <ax-prefix>\n @if(item.icon)\n {\n <ax-icon [icon]=\"item.icon\">\n </ax-icon>\n }\n </ax-prefix>\n @if(item.text)\n {\n <ax-text>{{ item.text }}</ax-text>\n }\n @if(item.suffix)\n {\n <ax-suffix>\n <ax-text>{{ item.suffix.text }}</ax-text>\n </ax-suffix>\n }\n <ng-container *ngFor=\"let child of item.children\" [ngTemplateOutlet]=\"Recursion\"\n [ngTemplateOutletContext]=\"{ $implicit: child }\"></ng-container>\n </ax-menu-item>\n @if(item.break)\n {\n <ax-divider></ax-divider>\n }\n</ng-template>", styles: ["ax-context-menu,ax-menu{width:100%;color:inherit;display:flex;width:max-content}ax-context-menu.ax-orientation-horizontal,ax-menu.ax-orientation-horizontal{flex-direction:row!important}ax-context-menu.ax-orientation-vertical,ax-menu.ax-orientation-vertical{flex-direction:column!important}ax-context-menu ax-title,ax-menu ax-title{display:block;padding-inline:1rem;padding-block:.25rem;font-size:.75rem;line-height:1rem;font-weight:bolder;text-transform:uppercase;opacity:.5}ax-context-menu ax-divider,ax-menu ax-divider{margin-top:.25rem;margin-bottom:.25rem;height:.5px;width:100%;background-color:rgba(var(--ax-color-border-default))}ax-context-menu ax-menu-item,ax-menu ax-menu-item{display:flex;align-items:center;font-size:.875rem;line-height:1.25rem;justify-content:space-between;color:rgba(var(--ax-color-text-default));height:2.25rem;cursor:pointer}ax-context-menu ax-menu-item>.ax-menu-item-prefix,ax-menu ax-menu-item>.ax-menu-item-prefix{display:flex;gap:.5rem}ax-context-menu ax-menu-item.ax-state-disabled,ax-menu ax-menu-item.ax-state-disabled{cursor:not-allowed;opacity:.5}ax-context-menu ax-menu-item ax-suffix ax-text,ax-menu ax-menu-item ax-suffix ax-text{color:rgba(var(--ax-color-text-default))!important;opacity:.5!important;font-weight:200!important;padding-inline-start:2rem}ax-context-menu.ax-menu-container,ax-context-menu .ax-menu-items,ax-menu.ax-menu-container,ax-menu .ax-menu-items{padding-block:.5rem;display:flex;opacity:0;visibility:hidden;transition:opacity .3s;width:max-content;min-width:12rem;height:max-content;position:fixed;flex-direction:column;border-radius:0;border-width:1px;border-color:rgba(var(--ax-color-border-default));background-color:rgba(var(--ax-color-surface));--ax-shadow: 0 4px 6px -1px rgb(0 0 0 / .1), 0 2px 4px -2px rgb(0 0 0 / .1);--ax-shadow-colored: 0 4px 6px -1px var(--ax-shadow-color), 0 2px 4px -2px var(--ax-shadow-color);box-shadow:var(--ax-ring-offset-shadow, 0 0 rgba(0, 0, 0, 0)),var(--ax-ring-shadow, 0 0 rgba(0, 0, 0, 0)),var(--ax-shadow);border-radius:var(--ax-rounded-border-default);z-index:9999}ax-context-menu.ax-menu-container.ax-state-open,ax-context-menu .ax-menu-items.ax-state-open,ax-menu.ax-menu-container.ax-state-open,ax-menu .ax-menu-items.ax-state-open{opacity:1;visibility:visible}ax-context-menu.ax-menu-container ax-menu-item,ax-context-menu .ax-menu-items ax-menu-item,ax-menu.ax-menu-container ax-menu-item,ax-menu .ax-menu-items ax-menu-item{padding-inline:1rem;padding-block:.5rem}ax-context-menu.ax-menu-container ax-menu-item ax-prefix,ax-context-menu .ax-menu-items ax-menu-item ax-prefix,ax-menu.ax-menu-container ax-menu-item ax-prefix,ax-menu .ax-menu-items ax-menu-item ax-prefix{width:1rem}ax-context-menu.ax-menu-container ax-menu-item:hover:not(ax-context-menu.ax-menu-container ax-menu-item:hover.ax-state-disabled,ax-context-menu .ax-menu-items ax-menu-item:hover.ax-state-disabled,ax-menu.ax-menu-container ax-menu-item:hover.ax-state-disabled,ax-menu .ax-menu-items ax-menu-item:hover.ax-state-disabled),ax-context-menu .ax-menu-items ax-menu-item:hover:not(ax-context-menu.ax-menu-container ax-menu-item:hover.ax-state-disabled,ax-context-menu .ax-menu-items ax-menu-item:hover.ax-state-disabled,ax-menu.ax-menu-container ax-menu-item:hover.ax-state-disabled,ax-menu .ax-menu-items ax-menu-item:hover.ax-state-disabled),ax-menu.ax-menu-container ax-menu-item:hover:not(ax-context-menu.ax-menu-container ax-menu-item:hover.ax-state-disabled,ax-context-menu .ax-menu-items ax-menu-item:hover.ax-state-disabled,ax-menu.ax-menu-container ax-menu-item:hover.ax-state-disabled,ax-menu .ax-menu-items ax-menu-item:hover.ax-state-disabled),ax-menu .ax-menu-items ax-menu-item:hover:not(ax-context-menu.ax-menu-container ax-menu-item:hover.ax-state-disabled,ax-context-menu .ax-menu-items ax-menu-item:hover.ax-state-disabled,ax-menu.ax-menu-container ax-menu-item:hover.ax-state-disabled,ax-menu .ax-menu-items ax-menu-item:hover.ax-state-disabled){background-color:rgba(var(--ax-color-on-surface))}ax-context-menu.ax-menu-container ax-menu-item:hover:not(ax-context-menu.ax-menu-container ax-menu-item:hover.ax-state-disabled,ax-context-menu .ax-menu-items ax-menu-item:hover.ax-state-disabled,ax-menu.ax-menu-container ax-menu-item:hover.ax-state-disabled,ax-menu .ax-menu-items ax-menu-item:hover.ax-state-disabled) ax-prefix,ax-context-menu.ax-menu-container ax-menu-item:hover:not(ax-context-menu.ax-menu-container ax-menu-item:hover.ax-state-disabled,ax-context-menu .ax-menu-items ax-menu-item:hover.ax-state-disabled,ax-menu.ax-menu-container ax-menu-item:hover.ax-state-disabled,ax-menu .ax-menu-items ax-menu-item:hover.ax-state-disabled) ax-suffix,ax-context-menu .ax-menu-items ax-menu-item:hover:not(ax-context-menu.ax-menu-container ax-menu-item:hover.ax-state-disabled,ax-context-menu .ax-menu-items ax-menu-item:hover.ax-state-disabled,ax-menu.ax-menu-container ax-menu-item:hover.ax-state-disabled,ax-menu .ax-menu-items ax-menu-item:hover.ax-state-disabled) ax-prefix,ax-context-menu .ax-menu-items ax-menu-item:hover:not(ax-context-menu.ax-menu-container ax-menu-item:hover.ax-state-disabled,ax-context-menu .ax-menu-items ax-menu-item:hover.ax-state-disabled,ax-menu.ax-menu-container ax-menu-item:hover.ax-state-disabled,ax-menu .ax-menu-items ax-menu-item:hover.ax-state-disabled) ax-suffix,ax-menu.ax-menu-container ax-menu-item:hover:not(ax-context-menu.ax-menu-container ax-menu-item:hover.ax-state-disabled,ax-context-menu .ax-menu-items ax-menu-item:hover.ax-state-disabled,ax-menu.ax-menu-container ax-menu-item:hover.ax-state-disabled,ax-menu .ax-menu-items ax-menu-item:hover.ax-state-disabled) ax-prefix,ax-menu.ax-menu-container ax-menu-item:hover:not(ax-context-menu.ax-menu-container ax-menu-item:hover.ax-state-disabled,ax-context-menu .ax-menu-items ax-menu-item:hover.ax-state-disabled,ax-menu.ax-menu-container ax-menu-item:hover.ax-state-disabled,ax-menu .ax-menu-items ax-menu-item:hover.ax-state-disabled) ax-suffix,ax-menu .ax-menu-items ax-menu-item:hover:not(ax-context-menu.ax-menu-container ax-menu-item:hover.ax-state-disabled,ax-context-menu .ax-menu-items ax-menu-item:hover.ax-state-disabled,ax-menu.ax-menu-container ax-menu-item:hover.ax-state-disabled,ax-menu .ax-menu-items ax-menu-item:hover.ax-state-disabled) ax-prefix,ax-menu .ax-menu-items ax-menu-item:hover:not(ax-context-menu.ax-menu-container ax-menu-item:hover.ax-state-disabled,ax-context-menu .ax-menu-items ax-menu-item:hover.ax-state-disabled,ax-menu.ax-menu-container ax-menu-item:hover.ax-state-disabled,ax-menu .ax-menu-items ax-menu-item:hover.ax-state-disabled) ax-suffix{opacity:1}ax-context-menu.ax-orientation-horizontal{padding-inline:1rem}ax-menu.ax-orientation-horizontal{min-width:12rem;gap:.875rem}ax-menu.ax-orientation-horizontal>ax-menu-item{font-weight:500}ax-menu.ax-orientation-vertical{width:max-content;min-width:12rem}ax-menu.ax-orientation-vertical>ax-menu-item{padding-inline:1rem;font-weight:500}ax-menu>ax-menu-item{padding-block:.5rem}ax-menu>ax-menu-item:hover:not(ax-menu>ax-menu-item:hover.ax-state-disabled)>ax-icon,ax-menu>ax-menu-item:hover:not(ax-menu>ax-menu-item:hover.ax-state-disabled)>ax-text{color:rgba(var(--ax-color-primary-500))}\n"], dependencies: [{ kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: i2.AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { kind: "component", type: i2.AXDecoratorGenericComponent, selector: "ax-footer, ax-header, ax-content, ax-divider, ax-form-hint, ax-prefix, ax-suffix, ax-text, ax-title, ax-sub-title, ax-placeholder, ax-overlay" }, { kind: "component", type: AXMenuItemComponent, selector: "ax-menu-item", inputs: ["name", "data", "disabled", "color"], outputs: ["onClick"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
220
558
  }
221
559
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.0", ngImport: i0, type: AXMenuComponent, decorators: [{
222
560
  type: Component,
223
- args: [{ selector: 'ax-menu', template: ` <ng-content select="ax-menu-item,ng-container"></ng-content>`, encapsulation: ViewEncapsulation.None, providers: [
561
+ args: [{ selector: 'ax-menu', encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, providers: [
562
+ AXMenuService,
224
563
  {
225
564
  provide: AXRootMenu,
226
- useExisting: AXMenuComponent,
227
- },
228
- {
229
- provide: AXMenuService,
230
- },
231
- ], styles: ["ax-menu{width:100%;font-size:.875rem;line-height:1.25rem;color:inherit;position:relative}ax-menu.ax-orientation-horizontal{display:flex}ax-menu.ax-orientation-horizontal ax-menu-item:not(ax-menu.ax-orientation-horizontal ax-menu-item:last-child){margin-inline-end:1rem}ax-menu.ax-orientation-vertical{display:flex;flex-direction:column}ax-menu.ax-orientation-vertical ax-menu-item{justify-content:space-between}ax-menu.ax-orientation-vertical ax-menu-item:not(ax-menu.ax-orientation-vertical ax-menu-item:last-child){margin-bottom:1rem}ax-menu ax-menu-item:hover:not(ax-menu ax-menu-item:hover.ax-state-disabled){color:rgba(var(--ax-color-primary-500))}ax-menu-item{position:relative;display:flex;align-items:center;gap:.5rem;font-size:.875rem;line-height:1.25rem;font-weight:500;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s;justify-content:space-between;color:rgba(var(--ax-color-text-default))}ax-menu-item .ax-menu-item-text{white-space:nowrap}ax-menu-item:not(ax-menu-item.ax-state-disabled){cursor:pointer}ax-menu-item .ax-menu-item-start-side{display:flex;align-items:center;gap:.5rem}ax-menu-item.ax-state-disabled{cursor:not-allowed;opacity:.5}ax-menu-item.ax-state-selected{color:rgba(var(--ax-color-primary-500))}ax-menu-item .ax-menu-item-child-icon{width:fit-content;line-height:1;font-size:10px}ax-menu-item ax-popover{position:absolute}.ax-menu-item-children{padding-top:.5rem;padding-bottom:.5rem}.ax-menu-item-children:not(.ax-menu-item-children:empty){display:flex;min-width:12rem;flex-direction:column;border-radius:var(--ax-rounded-border-default);border-width:1px;border-color:rgba(var(--ax-color-border-default));background-color:rgba(var(--ax-color-surface))}.ax-menu-item-children:not(.ax-menu-item-children:empty) ax-menu-item{padding:.5rem 1rem;font-size:.875rem;line-height:1.25rem}.ax-menu-item-children:not(.ax-menu-item-children:empty) ax-menu-item:hover:not(.ax-menu-item-children:not(.ax-menu-item-children:empty) ax-menu-item:hover.ax-state-disabled){background-color:rgba(var(--ax-color-on-surface))}.ax-menu-item-children:not(.ax-menu-item-children:empty) ax-menu-item:hover:not(.ax-menu-item-children:not(.ax-menu-item-children:empty) ax-menu-item:hover.ax-state-disabled) ax-prefix,.ax-menu-item-children:not(.ax-menu-item-children:empty) ax-menu-item:hover:not(.ax-menu-item-children:not(.ax-menu-item-children:empty) ax-menu-item:hover.ax-state-disabled) ax-suffix{opacity:1}.ax-menu-item-children:not(.ax-menu-item-children:empty) ax-menu-item ax-prefix,.ax-menu-item-children:not(.ax-menu-item-children:empty) ax-menu-item ax-suffix{opacity:.75}.ax-menu-item-children:not(.ax-menu-item-children:empty) ax-menu-item .ax-menu-item-text{flex:1 1 0%}html[dir=rtl] .ax-parent-horizontal .ax-menu-item-child-icon{transform:rotate(-90deg)}html[dir=rtl] .ax-parent-horizontal .ax-menu-item-child-icon:before{-moz-transform:scale(1,-1);-webkit-transform:scale(1,-1);-o-transform:scale(1,-1);-ms-transform:scale(1,-1);transform:scaleY(-1)}.ax-parent-horizontal .ax-menu-item-child-icon{transform:rotate(-90deg)}\n"] }]
232
- }], propDecorators: { children: [{
233
- type: ContentChildren,
234
- args: [AXMenuItemComponent]
235
- }], __hostClass: [{
565
+ useExisting: AXMenuComponent
566
+ }
567
+ ], template: "<ng-content select=\"ax-menu-item,ax-title,ng-container\"></ng-content>\n\n<ng-container *ngFor=\"let node of items()\" [ngTemplateOutlet]=\"Recursion\"\n [ngTemplateOutletContext]=\"{ $implicit: node }\">\n</ng-container>\n<ng-template #Recursion let-item>\n @if(item.group?.title)\n {\n <ax-title>{{item.group?.title}}</ax-title>\n }\n <ax-menu-item [name]=\"item.name\" [data]=\"item.data\" [disabled]=\"item.disabled\" [color]=\"item.color\">\n <ax-prefix>\n @if(item.icon)\n {\n <ax-icon [icon]=\"item.icon\">\n </ax-icon>\n }\n </ax-prefix>\n @if(item.text)\n {\n <ax-text>{{ item.text }}</ax-text>\n }\n @if(item.suffix)\n {\n <ax-suffix>\n <ax-text>{{ item.suffix.text }}</ax-text>\n </ax-suffix>\n }\n <ng-container *ngFor=\"let child of item.children\" [ngTemplateOutlet]=\"Recursion\"\n [ngTemplateOutletContext]=\"{ $implicit: child }\"></ng-container>\n </ax-menu-item>\n @if(item.break)\n {\n <ax-divider></ax-divider>\n }\n</ng-template>", styles: ["ax-context-menu,ax-menu{width:100%;color:inherit;display:flex;width:max-content}ax-context-menu.ax-orientation-horizontal,ax-menu.ax-orientation-horizontal{flex-direction:row!important}ax-context-menu.ax-orientation-vertical,ax-menu.ax-orientation-vertical{flex-direction:column!important}ax-context-menu ax-title,ax-menu ax-title{display:block;padding-inline:1rem;padding-block:.25rem;font-size:.75rem;line-height:1rem;font-weight:bolder;text-transform:uppercase;opacity:.5}ax-context-menu ax-divider,ax-menu ax-divider{margin-top:.25rem;margin-bottom:.25rem;height:.5px;width:100%;background-color:rgba(var(--ax-color-border-default))}ax-context-menu ax-menu-item,ax-menu ax-menu-item{display:flex;align-items:center;font-size:.875rem;line-height:1.25rem;justify-content:space-between;color:rgba(var(--ax-color-text-default));height:2.25rem;cursor:pointer}ax-context-menu ax-menu-item>.ax-menu-item-prefix,ax-menu ax-menu-item>.ax-menu-item-prefix{display:flex;gap:.5rem}ax-context-menu ax-menu-item.ax-state-disabled,ax-menu ax-menu-item.ax-state-disabled{cursor:not-allowed;opacity:.5}ax-context-menu ax-menu-item ax-suffix ax-text,ax-menu ax-menu-item ax-suffix ax-text{color:rgba(var(--ax-color-text-default))!important;opacity:.5!important;font-weight:200!important;padding-inline-start:2rem}ax-context-menu.ax-menu-container,ax-context-menu .ax-menu-items,ax-menu.ax-menu-container,ax-menu .ax-menu-items{padding-block:.5rem;display:flex;opacity:0;visibility:hidden;transition:opacity .3s;width:max-content;min-width:12rem;height:max-content;position:fixed;flex-direction:column;border-radius:0;border-width:1px;border-color:rgba(var(--ax-color-border-default));background-color:rgba(var(--ax-color-surface));--ax-shadow: 0 4px 6px -1px rgb(0 0 0 / .1), 0 2px 4px -2px rgb(0 0 0 / .1);--ax-shadow-colored: 0 4px 6px -1px var(--ax-shadow-color), 0 2px 4px -2px var(--ax-shadow-color);box-shadow:var(--ax-ring-offset-shadow, 0 0 rgba(0, 0, 0, 0)),var(--ax-ring-shadow, 0 0 rgba(0, 0, 0, 0)),var(--ax-shadow);border-radius:var(--ax-rounded-border-default);z-index:9999}ax-context-menu.ax-menu-container.ax-state-open,ax-context-menu .ax-menu-items.ax-state-open,ax-menu.ax-menu-container.ax-state-open,ax-menu .ax-menu-items.ax-state-open{opacity:1;visibility:visible}ax-context-menu.ax-menu-container ax-menu-item,ax-context-menu .ax-menu-items ax-menu-item,ax-menu.ax-menu-container ax-menu-item,ax-menu .ax-menu-items ax-menu-item{padding-inline:1rem;padding-block:.5rem}ax-context-menu.ax-menu-container ax-menu-item ax-prefix,ax-context-menu .ax-menu-items ax-menu-item ax-prefix,ax-menu.ax-menu-container ax-menu-item ax-prefix,ax-menu .ax-menu-items ax-menu-item ax-prefix{width:1rem}ax-context-menu.ax-menu-container ax-menu-item:hover:not(ax-context-menu.ax-menu-container ax-menu-item:hover.ax-state-disabled,ax-context-menu .ax-menu-items ax-menu-item:hover.ax-state-disabled,ax-menu.ax-menu-container ax-menu-item:hover.ax-state-disabled,ax-menu .ax-menu-items ax-menu-item:hover.ax-state-disabled),ax-context-menu .ax-menu-items ax-menu-item:hover:not(ax-context-menu.ax-menu-container ax-menu-item:hover.ax-state-disabled,ax-context-menu .ax-menu-items ax-menu-item:hover.ax-state-disabled,ax-menu.ax-menu-container ax-menu-item:hover.ax-state-disabled,ax-menu .ax-menu-items ax-menu-item:hover.ax-state-disabled),ax-menu.ax-menu-container ax-menu-item:hover:not(ax-context-menu.ax-menu-container ax-menu-item:hover.ax-state-disabled,ax-context-menu .ax-menu-items ax-menu-item:hover.ax-state-disabled,ax-menu.ax-menu-container ax-menu-item:hover.ax-state-disabled,ax-menu .ax-menu-items ax-menu-item:hover.ax-state-disabled),ax-menu .ax-menu-items ax-menu-item:hover:not(ax-context-menu.ax-menu-container ax-menu-item:hover.ax-state-disabled,ax-context-menu .ax-menu-items ax-menu-item:hover.ax-state-disabled,ax-menu.ax-menu-container ax-menu-item:hover.ax-state-disabled,ax-menu .ax-menu-items ax-menu-item:hover.ax-state-disabled){background-color:rgba(var(--ax-color-on-surface))}ax-context-menu.ax-menu-container ax-menu-item:hover:not(ax-context-menu.ax-menu-container ax-menu-item:hover.ax-state-disabled,ax-context-menu .ax-menu-items ax-menu-item:hover.ax-state-disabled,ax-menu.ax-menu-container ax-menu-item:hover.ax-state-disabled,ax-menu .ax-menu-items ax-menu-item:hover.ax-state-disabled) ax-prefix,ax-context-menu.ax-menu-container ax-menu-item:hover:not(ax-context-menu.ax-menu-container ax-menu-item:hover.ax-state-disabled,ax-context-menu .ax-menu-items ax-menu-item:hover.ax-state-disabled,ax-menu.ax-menu-container ax-menu-item:hover.ax-state-disabled,ax-menu .ax-menu-items ax-menu-item:hover.ax-state-disabled) ax-suffix,ax-context-menu .ax-menu-items ax-menu-item:hover:not(ax-context-menu.ax-menu-container ax-menu-item:hover.ax-state-disabled,ax-context-menu .ax-menu-items ax-menu-item:hover.ax-state-disabled,ax-menu.ax-menu-container ax-menu-item:hover.ax-state-disabled,ax-menu .ax-menu-items ax-menu-item:hover.ax-state-disabled) ax-prefix,ax-context-menu .ax-menu-items ax-menu-item:hover:not(ax-context-menu.ax-menu-container ax-menu-item:hover.ax-state-disabled,ax-context-menu .ax-menu-items ax-menu-item:hover.ax-state-disabled,ax-menu.ax-menu-container ax-menu-item:hover.ax-state-disabled,ax-menu .ax-menu-items ax-menu-item:hover.ax-state-disabled) ax-suffix,ax-menu.ax-menu-container ax-menu-item:hover:not(ax-context-menu.ax-menu-container ax-menu-item:hover.ax-state-disabled,ax-context-menu .ax-menu-items ax-menu-item:hover.ax-state-disabled,ax-menu.ax-menu-container ax-menu-item:hover.ax-state-disabled,ax-menu .ax-menu-items ax-menu-item:hover.ax-state-disabled) ax-prefix,ax-menu.ax-menu-container ax-menu-item:hover:not(ax-context-menu.ax-menu-container ax-menu-item:hover.ax-state-disabled,ax-context-menu .ax-menu-items ax-menu-item:hover.ax-state-disabled,ax-menu.ax-menu-container ax-menu-item:hover.ax-state-disabled,ax-menu .ax-menu-items ax-menu-item:hover.ax-state-disabled) ax-suffix,ax-menu .ax-menu-items ax-menu-item:hover:not(ax-context-menu.ax-menu-container ax-menu-item:hover.ax-state-disabled,ax-context-menu .ax-menu-items ax-menu-item:hover.ax-state-disabled,ax-menu.ax-menu-container ax-menu-item:hover.ax-state-disabled,ax-menu .ax-menu-items ax-menu-item:hover.ax-state-disabled) ax-prefix,ax-menu .ax-menu-items ax-menu-item:hover:not(ax-context-menu.ax-menu-container ax-menu-item:hover.ax-state-disabled,ax-context-menu .ax-menu-items ax-menu-item:hover.ax-state-disabled,ax-menu.ax-menu-container ax-menu-item:hover.ax-state-disabled,ax-menu .ax-menu-items ax-menu-item:hover.ax-state-disabled) ax-suffix{opacity:1}ax-context-menu.ax-orientation-horizontal{padding-inline:1rem}ax-menu.ax-orientation-horizontal{min-width:12rem;gap:.875rem}ax-menu.ax-orientation-horizontal>ax-menu-item{font-weight:500}ax-menu.ax-orientation-vertical{width:max-content;min-width:12rem}ax-menu.ax-orientation-vertical>ax-menu-item{padding-inline:1rem;font-weight:500}ax-menu>ax-menu-item{padding-block:.5rem}ax-menu>ax-menu-item:hover:not(ax-menu>ax-menu-item:hover.ax-state-disabled)>ax-icon,ax-menu>ax-menu-item:hover:not(ax-menu>ax-menu-item:hover.ax-state-disabled)>ax-text{color:rgba(var(--ax-color-primary-500))}\n"] }]
568
+ }], propDecorators: { __hostClass: [{
236
569
  type: HostBinding,
237
570
  args: ['class']
238
571
  }] } });
239
572
 
240
- const COMPONENT = [AXMenuItemComponent, AXMenuComponent];
573
+ const COMPONENT = [AXMenuItemComponent, AXMenuComponent, AXContextMenuComponent];
241
574
  const MODULES = [AXDecoratorModule, AXLoadingModule, AXTranslationModule, OverlayModule, AXPopoverModule];
242
575
  class AXMenuModule {
243
576
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.0", ngImport: i0, type: AXMenuModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
244
- static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "18.2.0", ngImport: i0, type: AXMenuModule, declarations: [AXMenuItemComponent, AXMenuComponent], imports: [CommonModule, AXDecoratorModule, AXLoadingModule, AXTranslationModule, OverlayModule, AXPopoverModule, AXButtonModule], exports: [AXMenuItemComponent, AXMenuComponent] }); }
245
- static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "18.2.0", ngImport: i0, type: AXMenuModule, imports: [CommonModule, MODULES, AXButtonModule] }); }
577
+ static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "18.2.0", ngImport: i0, type: AXMenuModule, declarations: [AXMenuItemComponent, AXMenuComponent, AXContextMenuComponent], imports: [CommonModule, AXDecoratorModule, AXLoadingModule, AXTranslationModule, OverlayModule, AXPopoverModule], exports: [AXMenuItemComponent, AXMenuComponent, AXContextMenuComponent] }); }
578
+ static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "18.2.0", ngImport: i0, type: AXMenuModule, imports: [CommonModule, MODULES] }); }
246
579
  }
247
580
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.0", ngImport: i0, type: AXMenuModule, decorators: [{
248
581
  type: NgModule,
249
582
  args: [{
250
583
  declarations: [...COMPONENT],
251
- imports: [CommonModule, ...MODULES, AXButtonModule],
584
+ imports: [CommonModule, ...MODULES],
252
585
  exports: [...COMPONENT],
253
586
  providers: [],
254
587
  }]
@@ -258,5 +591,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.0", ngImpor
258
591
  * Generated bundle index. Do not edit.
259
592
  */
260
593
 
261
- export { AXMenuComponent, AXMenuItemComponent, AXMenuModule, AXMenuService, AXRootMenu };
594
+ export { AXContextMenuComponent, AXContextMenuOpeningEvent, AXMenuComponent, AXMenuItem, AXMenuItemClickEvent, AXMenuItemClickEventItemData, AXMenuItemComponent, AXMenuItemComponentBase, AXMenuModule, AXMenuService, AXRootMenu };
262
595
  //# sourceMappingURL=acorex-components-menu.mjs.map