@acorex/components 21.0.2-next.43 → 21.0.2-next.44
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.
|
@@ -2,11 +2,11 @@ import { NXClickEvent, NXComponent, AXComponent, NXEvent } from '@acorex/cdk/com
|
|
|
2
2
|
import { AXDecoratorGenericComponent, AXDecoratorIconComponent } from '@acorex/components/decorators';
|
|
3
3
|
import { isBrowser } from '@acorex/core/platform';
|
|
4
4
|
import { AXTranslatorPipe } from '@acorex/core/translation';
|
|
5
|
-
import {
|
|
5
|
+
import { AXHtmlUtil, AXUnsubscriber } from '@acorex/core/utils';
|
|
6
6
|
import { AXZIndexService } from '@acorex/core/z-index';
|
|
7
7
|
import { isPlatformBrowser, NgTemplateOutlet, AsyncPipe } from '@angular/common';
|
|
8
8
|
import * as i0 from '@angular/core';
|
|
9
|
-
import { Injectable, signal,
|
|
9
|
+
import { inject, DestroyRef, DOCUMENT, PLATFORM_ID, Injectable, signal, computed, contentChildren, Renderer2, Injector, output, input, afterNextRender, HostBinding, HostListener, ChangeDetectionStrategy, ViewEncapsulation, Component, NgModule } from '@angular/core';
|
|
10
10
|
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
|
11
11
|
import { Router, NavigationStart } from '@angular/router';
|
|
12
12
|
import { filter } from 'rxjs/operators';
|
|
@@ -18,16 +18,81 @@ class AXMenuService {
|
|
|
18
18
|
this.closeAll$ = new Subject();
|
|
19
19
|
this.open$ = new Subject();
|
|
20
20
|
this.close$ = new Subject();
|
|
21
|
-
this.closeExcept$ = new Subject();
|
|
22
21
|
this.openContextMenu$ = new Subject();
|
|
23
22
|
this.closeAllContextMenu$ = new Subject();
|
|
23
|
+
this.destroyRef = inject(DestroyRef);
|
|
24
|
+
this.document = inject(DOCUMENT);
|
|
25
|
+
this.platformId = inject(PLATFORM_ID);
|
|
26
|
+
this.openItems = new Set();
|
|
27
|
+
this.globalListenersBound = false;
|
|
28
|
+
this.scrollableParents = [];
|
|
29
|
+
this.onDocumentClick = (event) => {
|
|
30
|
+
if (this.rootElement && !this.rootElement.contains(event.target)) {
|
|
31
|
+
this.closeAll$.next();
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
this.onWindowOrScrollEvent = () => {
|
|
35
|
+
this.closeAll$.next();
|
|
36
|
+
};
|
|
37
|
+
this.closeAll$.pipe(takeUntilDestroyed(this.destroyRef)).subscribe(() => {
|
|
38
|
+
this.openItems.clear();
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Registers a single set of document/window/scroll listeners for the whole menu tree.
|
|
43
|
+
*/
|
|
44
|
+
initGlobalListeners(rootElement) {
|
|
45
|
+
if (!isPlatformBrowser(this.platformId) || this.globalListenersBound) {
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
this.globalListenersBound = true;
|
|
49
|
+
this.rootElement = rootElement;
|
|
50
|
+
this.document.addEventListener('click', this.onDocumentClick);
|
|
51
|
+
window.addEventListener('scroll', this.onWindowOrScrollEvent, { capture: true });
|
|
52
|
+
window.addEventListener('resize', this.onWindowOrScrollEvent);
|
|
53
|
+
this.scrollableParents = AXHtmlUtil.getScrollableParents(rootElement);
|
|
54
|
+
this.scrollableParents.forEach((parent) => {
|
|
55
|
+
parent.addEventListener('scroll', this.onWindowOrScrollEvent);
|
|
56
|
+
});
|
|
57
|
+
this.destroyRef.onDestroy(() => {
|
|
58
|
+
this.document.removeEventListener('click', this.onDocumentClick);
|
|
59
|
+
window.removeEventListener('scroll', this.onWindowOrScrollEvent, { capture: true });
|
|
60
|
+
window.removeEventListener('resize', this.onWindowOrScrollEvent);
|
|
61
|
+
this.scrollableParents.forEach((parent) => {
|
|
62
|
+
parent.removeEventListener('scroll', this.onWindowOrScrollEvent);
|
|
63
|
+
});
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Closes open submenus that are not on the ancestor path of the item being opened.
|
|
68
|
+
*/
|
|
69
|
+
closeExcept(opener) {
|
|
70
|
+
const keepOpen = new Set();
|
|
71
|
+
let current = opener;
|
|
72
|
+
while (current) {
|
|
73
|
+
keepOpen.add(current);
|
|
74
|
+
current = current.parent;
|
|
75
|
+
}
|
|
76
|
+
for (const openItem of [...this.openItems]) {
|
|
77
|
+
if (!keepOpen.has(openItem)) {
|
|
78
|
+
this.markClosed(openItem);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
markOpen(item) {
|
|
83
|
+
this.openItems.add(item);
|
|
84
|
+
this.open$.next(item);
|
|
85
|
+
}
|
|
86
|
+
markClosed(item) {
|
|
87
|
+
this.openItems.delete(item);
|
|
88
|
+
this.close$.next(item);
|
|
24
89
|
}
|
|
25
90
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXMenuService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
26
91
|
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXMenuService }); }
|
|
27
92
|
}
|
|
28
93
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXMenuService, decorators: [{
|
|
29
94
|
type: Injectable
|
|
30
|
-
}] });
|
|
95
|
+
}], ctorParameters: () => [] });
|
|
31
96
|
|
|
32
97
|
class AXRootMenu {
|
|
33
98
|
}
|
|
@@ -48,12 +113,14 @@ class AXMenuItemComponent extends NXComponent {
|
|
|
48
113
|
constructor() {
|
|
49
114
|
super();
|
|
50
115
|
this.isOpen = signal(false, ...(ngDevMode ? [{ debugName: "isOpen" }] : /* istanbul ignore next */ []));
|
|
51
|
-
this.
|
|
52
|
-
this.
|
|
116
|
+
this.submenuRendered = signal(false, ...(ngDevMode ? [{ debugName: "submenuRendered" }] : /* istanbul ignore next */ []));
|
|
117
|
+
this.parent = inject(AXMenuItemComponent, { optional: true, skipSelf: true });
|
|
118
|
+
this.isRoot = computed(() => this.parent == null, ...(ngDevMode ? [{ debugName: "isRoot" }] : /* istanbul ignore next */ []));
|
|
119
|
+
this.isFirstLevel = computed(() => this.parent == null, ...(ngDevMode ? [{ debugName: "isFirstLevel" }] : /* istanbul ignore next */ []));
|
|
120
|
+
this.childMenuItems = contentChildren(AXMenuItemComponent, { ...(ngDevMode ? { debugName: "childMenuItems" } : /* istanbul ignore next */ {}), descendants: false });
|
|
121
|
+
this.hasSubItems = computed(() => this.childMenuItems().length > 0, ...(ngDevMode ? [{ debugName: "hasSubItems" }] : /* istanbul ignore next */ []));
|
|
53
122
|
this.root = inject(AXRootMenu);
|
|
54
|
-
this.isRoot = () => this.parent == null;
|
|
55
123
|
this.service = inject(AXMenuService);
|
|
56
|
-
this.scrollableParents = [];
|
|
57
124
|
this.unsuscriber = inject(AXUnsubscriber);
|
|
58
125
|
this.renderer = inject(Renderer2);
|
|
59
126
|
this.injector = inject(Injector);
|
|
@@ -72,13 +139,7 @@ class AXMenuItemComponent extends NXComponent {
|
|
|
72
139
|
this.data = input(...(ngDevMode ? [undefined, { debugName: "data" }] : /* istanbul ignore next */ []));
|
|
73
140
|
this.disabled = input(...(ngDevMode ? [undefined, { debugName: "disabled" }] : /* istanbul ignore next */ []));
|
|
74
141
|
this.color = input(...(ngDevMode ? [undefined, { debugName: "color" }] : /* istanbul ignore next */ []));
|
|
75
|
-
|
|
76
|
-
afterNextRender(() => {
|
|
77
|
-
this.detectSubItems();
|
|
78
|
-
this.observeMutations();
|
|
79
|
-
this.bindScrollEvents();
|
|
80
|
-
});
|
|
81
|
-
//
|
|
142
|
+
this.mouseLeaveTimeout = null;
|
|
82
143
|
this.service.closeAll$.pipe(this.unsuscriber.takeUntilDestroy).subscribe(() => this.close());
|
|
83
144
|
this.service.open$.pipe(this.unsuscriber.takeUntilDestroy).subscribe((item) => {
|
|
84
145
|
if (this === item) {
|
|
@@ -86,89 +147,34 @@ class AXMenuItemComponent extends NXComponent {
|
|
|
86
147
|
this.schedulePositionCalculation();
|
|
87
148
|
}
|
|
88
149
|
});
|
|
89
|
-
//
|
|
90
150
|
this.service.close$.pipe(this.unsuscriber.takeUntilDestroy).subscribe((item) => {
|
|
91
151
|
if (this == item) {
|
|
92
152
|
this.isOpen.set(false);
|
|
93
153
|
}
|
|
94
154
|
});
|
|
95
|
-
//
|
|
96
|
-
this.service.closeExcept$.pipe(this.unsuscriber.takeUntilDestroy).subscribe((item) => {
|
|
97
|
-
this.closeExcept(item);
|
|
98
|
-
});
|
|
99
|
-
}
|
|
100
|
-
closeExcept(item) {
|
|
101
|
-
const list = [item];
|
|
102
|
-
// TODO: Check for better solution
|
|
103
|
-
const parentEl = this.nativeElement.parentElement?.parentElement;
|
|
104
|
-
this.parent = parentEl?.tagName == 'AX-MENU-ITEM' ? parentEl?.['__axContext__'] : null;
|
|
105
|
-
//
|
|
106
|
-
let parent = item.parent;
|
|
107
|
-
while (parent != null) {
|
|
108
|
-
list.push(parent);
|
|
109
|
-
parent = parent.parent;
|
|
110
|
-
}
|
|
111
|
-
//
|
|
112
|
-
if (!list.includes(this)) {
|
|
113
|
-
this.close();
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
observeMutations() {
|
|
117
|
-
this.mutationObserver = new MutationObserver(() => {
|
|
118
|
-
this.detectSubItems();
|
|
119
|
-
});
|
|
120
|
-
// Start observing changes in child elements
|
|
121
|
-
this.mutationObserver.observe(this.nativeElement, {
|
|
122
|
-
childList: true,
|
|
123
|
-
subtree: true,
|
|
124
|
-
});
|
|
125
155
|
}
|
|
126
156
|
getText() {
|
|
127
157
|
return this.nativeElement.querySelector('ax-text')?.innerText;
|
|
128
158
|
}
|
|
129
|
-
/**
|
|
130
|
-
* Manually detect all `ax-menu-item` elements and check if this menu item has sub-items.
|
|
131
|
-
*/
|
|
132
|
-
detectSubItems() {
|
|
133
|
-
//
|
|
134
|
-
const parentEl = this.nativeElement.parentElement?.parentElement;
|
|
135
|
-
this.parent = parentEl?.tagName == 'AX-MENU-ITEM' ? parentEl?.['__axContext__'] : null;
|
|
136
|
-
//
|
|
137
|
-
const tag = this.nativeElement.parentElement?.tagName;
|
|
138
|
-
this.isFirstLevel.set(tag == 'AX-MENU' || tag == 'AX-CONTEXT-MENU');
|
|
139
|
-
const subItems = this.nativeElement.querySelectorAll('ax-menu-item');
|
|
140
|
-
if (subItems.length > 0) {
|
|
141
|
-
this.hasSubItems.set(true);
|
|
142
|
-
}
|
|
143
|
-
else {
|
|
144
|
-
this.hasSubItems.set(false);
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
159
|
/**
|
|
148
160
|
* Opens the submenu of this menu item if it has sub-items and is not disabled.
|
|
149
|
-
*
|
|
150
|
-
* Inherited behavior: Uses the injected service to notify other items to close.
|
|
151
|
-
*
|
|
152
|
-
* @returns void - No return value. Triggers submenu opening side-effects.
|
|
153
161
|
*/
|
|
154
162
|
open() {
|
|
155
|
-
this.
|
|
156
|
-
|
|
157
|
-
// Acquire z-index token for this submenu
|
|
158
|
-
if (!this.zToken) {
|
|
159
|
-
this.zToken = this.zIndexService.acquire();
|
|
160
|
-
}
|
|
161
|
-
this.service.open$.next(this);
|
|
163
|
+
if (this.disabled() || !this.hasSubItems()) {
|
|
164
|
+
return;
|
|
162
165
|
}
|
|
166
|
+
this.submenuRendered.set(true);
|
|
167
|
+
this.service.closeExcept(this);
|
|
168
|
+
if (!this.zToken) {
|
|
169
|
+
this.zToken = this.zIndexService.acquire();
|
|
170
|
+
}
|
|
171
|
+
this.service.markOpen(this);
|
|
163
172
|
}
|
|
164
173
|
/**
|
|
165
174
|
* Closes the submenu of this menu item if open.
|
|
166
|
-
*
|
|
167
|
-
* @returns void - No return value. Triggers submenu closing side-effects.
|
|
168
175
|
*/
|
|
169
176
|
close() {
|
|
170
|
-
this.service.
|
|
171
|
-
// Release z-index token
|
|
177
|
+
this.service.markClosed(this);
|
|
172
178
|
this.zIndexService.release(this.zToken);
|
|
173
179
|
this.zToken = null;
|
|
174
180
|
}
|
|
@@ -176,10 +182,14 @@ class AXMenuItemComponent extends NXComponent {
|
|
|
176
182
|
* Positions the submenu after layout so nested levels measure their full height.
|
|
177
183
|
*/
|
|
178
184
|
schedulePositionCalculation() {
|
|
179
|
-
this.calculatePosition();
|
|
180
185
|
afterNextRender(() => {
|
|
181
186
|
if (this.isOpen()) {
|
|
182
187
|
this.calculatePosition();
|
|
188
|
+
afterNextRender(() => {
|
|
189
|
+
if (this.isOpen()) {
|
|
190
|
+
this.calculatePosition();
|
|
191
|
+
}
|
|
192
|
+
}, { injector: this.injector });
|
|
183
193
|
}
|
|
184
194
|
}, { injector: this.injector });
|
|
185
195
|
}
|
|
@@ -197,11 +207,10 @@ class AXMenuItemComponent extends NXComponent {
|
|
|
197
207
|
const isRtl = AXHtmlUtil.isRtl(this.nativeElement);
|
|
198
208
|
let finalTop;
|
|
199
209
|
let finalLeft;
|
|
200
|
-
// --- 1. VERTICAL POSITIONING ---
|
|
201
210
|
const preferredTop = this.isFirstLevel() && this.root.orientation() === 'horizontal'
|
|
202
|
-
? itemRect.bottom
|
|
203
|
-
: itemRect.top;
|
|
204
|
-
const alternateTop = itemRect.top - submenuRect.height;
|
|
211
|
+
? itemRect.bottom
|
|
212
|
+
: itemRect.top;
|
|
213
|
+
const alternateTop = itemRect.top - submenuRect.height;
|
|
205
214
|
if (preferredTop + submenuRect.height <= windowHeight) {
|
|
206
215
|
finalTop = preferredTop;
|
|
207
216
|
}
|
|
@@ -212,7 +221,6 @@ class AXMenuItemComponent extends NXComponent {
|
|
|
212
221
|
finalTop = windowHeight - submenuRect.height;
|
|
213
222
|
}
|
|
214
223
|
finalTop = this.clampVerticalPosition(finalTop, submenuRect.height, windowHeight);
|
|
215
|
-
// --- 2. HORIZONTAL POSITIONING ---
|
|
216
224
|
if (this.isFirstLevel() && this.root.orientation() === 'horizontal') {
|
|
217
225
|
const preferredLeft = isRtl ? itemRect.right - submenuRect.width : itemRect.left;
|
|
218
226
|
const alternateLeft = isRtl ? itemRect.left : itemRect.right - submenuRect.width;
|
|
@@ -251,7 +259,6 @@ class AXMenuItemComponent extends NXComponent {
|
|
|
251
259
|
}
|
|
252
260
|
}
|
|
253
261
|
}
|
|
254
|
-
// --- 3. OVERLAP-AWARE VERTICAL SHIFT ---
|
|
255
262
|
const isNestedMenu = !(this.isFirstLevel() && this.root.orientation() === 'horizontal');
|
|
256
263
|
if (isNestedMenu) {
|
|
257
264
|
const overlapsParent = finalLeft < itemRect.right && itemRect.left < finalLeft + submenuRect.width;
|
|
@@ -263,11 +270,9 @@ class AXMenuItemComponent extends NXComponent {
|
|
|
263
270
|
}
|
|
264
271
|
}
|
|
265
272
|
finalTop = this.clampVerticalPosition(finalTop, submenuRect.height, windowHeight);
|
|
266
|
-
// --- 4. APPLY FINAL STYLES ---
|
|
267
273
|
this.renderer.setStyle(submenu, 'position', 'fixed');
|
|
268
274
|
this.renderer.setStyle(submenu, 'top', `${finalTop}px`);
|
|
269
275
|
this.renderer.setStyle(submenu, 'left', `${finalLeft}px`);
|
|
270
|
-
// Apply z-index from token
|
|
271
276
|
if (this.zToken) {
|
|
272
277
|
this.renderer.setStyle(submenu, 'z-index', String(this.zToken.zIndex));
|
|
273
278
|
}
|
|
@@ -295,7 +300,6 @@ class AXMenuItemComponent extends NXComponent {
|
|
|
295
300
|
e.stopPropagation();
|
|
296
301
|
if (this.disabled())
|
|
297
302
|
return;
|
|
298
|
-
//
|
|
299
303
|
const event = {
|
|
300
304
|
sender: this,
|
|
301
305
|
nativeEvent: e,
|
|
@@ -306,10 +310,8 @@ class AXMenuItemComponent extends NXComponent {
|
|
|
306
310
|
data: this.data(),
|
|
307
311
|
},
|
|
308
312
|
};
|
|
309
|
-
//
|
|
310
313
|
this.onClick.emit(event);
|
|
311
314
|
this.root.onItemClick.emit({ ...event, ...{ sender: this.root } });
|
|
312
|
-
//
|
|
313
315
|
if (this.hasSubItems() && !event.canceled) {
|
|
314
316
|
this.open();
|
|
315
317
|
}
|
|
@@ -320,10 +322,9 @@ class AXMenuItemComponent extends NXComponent {
|
|
|
320
322
|
}
|
|
321
323
|
handleMouseEnter(event) {
|
|
322
324
|
event.stopPropagation();
|
|
323
|
-
// Cancel the close delay if the mouse re-enters the element
|
|
324
325
|
if (this.mouseLeaveTimeout) {
|
|
325
326
|
clearTimeout(this.mouseLeaveTimeout);
|
|
326
|
-
this.mouseLeaveTimeout = null;
|
|
327
|
+
this.mouseLeaveTimeout = null;
|
|
327
328
|
}
|
|
328
329
|
if (!this.isFirstLevel() || this.root.openOn() == 'hover') {
|
|
329
330
|
this.open();
|
|
@@ -332,48 +333,18 @@ class AXMenuItemComponent extends NXComponent {
|
|
|
332
333
|
handleMouseLeave(event) {
|
|
333
334
|
event.stopPropagation();
|
|
334
335
|
if (this.hasSubItems() && this.root.closeOn() === 'leave') {
|
|
335
|
-
// Clear any previous timeout to avoid multiple triggers
|
|
336
336
|
if (this.mouseLeaveTimeout) {
|
|
337
337
|
clearTimeout(this.mouseLeaveTimeout);
|
|
338
338
|
}
|
|
339
|
-
// Set a delay before closing the submenu
|
|
340
339
|
this.mouseLeaveTimeout = setTimeout(() => {
|
|
341
340
|
this.close();
|
|
342
|
-
}, 500);
|
|
343
|
-
}
|
|
344
|
-
}
|
|
345
|
-
onWindowEvent() {
|
|
346
|
-
this.service.closeAll$.next(); // Close all menus on scroll or resize
|
|
347
|
-
}
|
|
348
|
-
/**
|
|
349
|
-
* Close all menus if clicking outside the root menu and all sub-items.
|
|
350
|
-
*/
|
|
351
|
-
onClickOutside(event) {
|
|
352
|
-
const hostElement = this.root.nativeElement;
|
|
353
|
-
if (!hostElement.contains(event.target)) {
|
|
354
|
-
this.service.closeAll$.next(); // Close all menus if click is outside the root and sub-items
|
|
341
|
+
}, 500);
|
|
355
342
|
}
|
|
356
343
|
}
|
|
357
344
|
ngOnDestroy() {
|
|
358
|
-
this.
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
this.scrollableParents = AXHtmlUtil.getScrollableParents(this.nativeElement);
|
|
362
|
-
this.scrollableParents.forEach((parent) => {
|
|
363
|
-
parent.addEventListener('scroll', this.onContainerScroll.bind(this));
|
|
364
|
-
});
|
|
365
|
-
}
|
|
366
|
-
// Remove scroll event listeners
|
|
367
|
-
removeScrollEvents() {
|
|
368
|
-
this.scrollableParents.forEach((parent) => {
|
|
369
|
-
parent.removeEventListener('scroll', this.onContainerScroll.bind(this));
|
|
370
|
-
});
|
|
371
|
-
}
|
|
372
|
-
/**
|
|
373
|
-
* Handler for scroll events (window or scrollable parent containers)
|
|
374
|
-
*/
|
|
375
|
-
onContainerScroll() {
|
|
376
|
-
this.service.closeAll$.next(); // Close all menus on scroll
|
|
345
|
+
if (this.isOpen()) {
|
|
346
|
+
this.close();
|
|
347
|
+
}
|
|
377
348
|
}
|
|
378
349
|
/** @ignore */
|
|
379
350
|
get __hostClass() {
|
|
@@ -385,7 +356,7 @@ class AXMenuItemComponent extends NXComponent {
|
|
|
385
356
|
return list;
|
|
386
357
|
}
|
|
387
358
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXMenuItemComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
388
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: AXMenuItemComponent, isStandalone: true, 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)"
|
|
359
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: AXMenuItemComponent, isStandalone: true, 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)" }, properties: { "class": "this.__hostClass" } }, providers: [
|
|
389
360
|
{
|
|
390
361
|
provide: AXMenuItemComponentBase,
|
|
391
362
|
useExisting: AXMenuItemComponent,
|
|
@@ -395,7 +366,7 @@ class AXMenuItemComponent extends NXComponent {
|
|
|
395
366
|
provide: AXComponent,
|
|
396
367
|
useExisting: AXMenuItemComponent,
|
|
397
368
|
},
|
|
398
|
-
], usesInheritance: true, ngImport: i0, template: "<div class=\"ax-action-item-prefix\">\n <ng-content select=\"ax-prefix\"></ng-content>\n <ng-content select=\"ax-text\"></ng-content>\n</div>\n<div class=\"ax-action-item-suffix\">\n <ng-content select=\"ax-suffix\"></ng-content>\n @if (hasSubItems() && (!isRoot() || root
|
|
369
|
+
], queries: [{ propertyName: "childMenuItems", predicate: AXMenuItemComponent, isSignal: true }], usesInheritance: true, ngImport: i0, template: "<div class=\"ax-action-item-prefix\">\n <ng-content select=\"ax-prefix\"></ng-content>\n <ng-content select=\"ax-text\"></ng-content>\n</div>\n<div class=\"ax-action-item-suffix\">\n <ng-content select=\"ax-suffix\"></ng-content>\n @if (hasSubItems() && (!isRoot() || root.hasArrow())) {\n <i class=\"ax-icon ax-icon-solid {{ arrowIcon() }} \"></i>\n }\n</div>\n<div class=\"ax-menu-items ax-action-list ax-action-list-vertical\" [class.ax-state-open]=\"isOpen()\">\n @if (submenuRendered()) {\n <ng-content select=\"ax-menu-item,ax-title,ax-divider,ng-container\"></ng-content>\n }\n</div>\n", changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
|
|
399
370
|
}
|
|
400
371
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXMenuItemComponent, decorators: [{
|
|
401
372
|
type: Component,
|
|
@@ -409,8 +380,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
|
|
|
409
380
|
provide: AXComponent,
|
|
410
381
|
useExisting: AXMenuItemComponent,
|
|
411
382
|
},
|
|
412
|
-
], template: "<div class=\"ax-action-item-prefix\">\n <ng-content select=\"ax-prefix\"></ng-content>\n <ng-content select=\"ax-text\"></ng-content>\n</div>\n<div class=\"ax-action-item-suffix\">\n <ng-content select=\"ax-suffix\"></ng-content>\n @if (hasSubItems() && (!isRoot() || root
|
|
413
|
-
}], ctorParameters: () => [], propDecorators: { onClick: [{ type: i0.Output, args: ["onClick"] }], name: [{ type: i0.Input, args: [{ isSignal: true, alias: "name", required: false }] }], data: [{ type: i0.Input, args: [{ isSignal: true, alias: "data", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], color: [{ type: i0.Input, args: [{ isSignal: true, alias: "color", required: false }] }], handleClick: [{
|
|
383
|
+
], template: "<div class=\"ax-action-item-prefix\">\n <ng-content select=\"ax-prefix\"></ng-content>\n <ng-content select=\"ax-text\"></ng-content>\n</div>\n<div class=\"ax-action-item-suffix\">\n <ng-content select=\"ax-suffix\"></ng-content>\n @if (hasSubItems() && (!isRoot() || root.hasArrow())) {\n <i class=\"ax-icon ax-icon-solid {{ arrowIcon() }} \"></i>\n }\n</div>\n<div class=\"ax-menu-items ax-action-list ax-action-list-vertical\" [class.ax-state-open]=\"isOpen()\">\n @if (submenuRendered()) {\n <ng-content select=\"ax-menu-item,ax-title,ax-divider,ng-container\"></ng-content>\n }\n</div>\n" }]
|
|
384
|
+
}], ctorParameters: () => [], propDecorators: { childMenuItems: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => AXMenuItemComponent), { ...{ descendants: false }, isSignal: true }] }], onClick: [{ type: i0.Output, args: ["onClick"] }], name: [{ type: i0.Input, args: [{ isSignal: true, alias: "name", required: false }] }], data: [{ type: i0.Input, args: [{ isSignal: true, alias: "data", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], color: [{ type: i0.Input, args: [{ isSignal: true, alias: "color", required: false }] }], handleClick: [{
|
|
414
385
|
type: HostListener,
|
|
415
386
|
args: ['click', ['$event']]
|
|
416
387
|
}], handleMouseEnter: [{
|
|
@@ -419,15 +390,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
|
|
|
419
390
|
}], handleMouseLeave: [{
|
|
420
391
|
type: HostListener,
|
|
421
392
|
args: ['mouseleave', ['$event']]
|
|
422
|
-
}], onWindowEvent: [{
|
|
423
|
-
type: HostListener,
|
|
424
|
-
args: ['window:scroll']
|
|
425
|
-
}, {
|
|
426
|
-
type: HostListener,
|
|
427
|
-
args: ['window:resize']
|
|
428
|
-
}], onClickOutside: [{
|
|
429
|
-
type: HostListener,
|
|
430
|
-
args: ['document:click', ['$event']]
|
|
431
393
|
}], __hostClass: [{
|
|
432
394
|
type: HostBinding,
|
|
433
395
|
args: ['class']
|
|
@@ -478,6 +440,7 @@ class AXContextMenuComponent extends NXComponent {
|
|
|
478
440
|
//
|
|
479
441
|
afterNextRender(() => {
|
|
480
442
|
this.bindContextEvent();
|
|
443
|
+
this.service.initGlobalListeners(this.nativeElement);
|
|
481
444
|
});
|
|
482
445
|
this.setupCloseOnRouteChange();
|
|
483
446
|
this.service.closeAllContextMenu$.subscribe(() => {
|
|
@@ -803,7 +766,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
|
|
|
803
766
|
*/
|
|
804
767
|
class AXMenuComponent extends NXComponent {
|
|
805
768
|
constructor() {
|
|
806
|
-
super(
|
|
769
|
+
super();
|
|
807
770
|
this.orientation = input('horizontal', ...(ngDevMode ? [{ debugName: "orientation" }] : /* istanbul ignore next */ []));
|
|
808
771
|
this.openOn = input('hover', ...(ngDevMode ? [{ debugName: "openOn" }] : /* istanbul ignore next */ []));
|
|
809
772
|
this.closeOn = input('leave', ...(ngDevMode ? [{ debugName: "closeOn" }] : /* istanbul ignore next */ []));
|
|
@@ -811,6 +774,9 @@ class AXMenuComponent extends NXComponent {
|
|
|
811
774
|
this.onItemClick = output();
|
|
812
775
|
this.items = input([], ...(ngDevMode ? [{ debugName: "items" }] : /* istanbul ignore next */ []));
|
|
813
776
|
this.hasArrow = input(true, ...(ngDevMode ? [{ debugName: "hasArrow" }] : /* istanbul ignore next */ []));
|
|
777
|
+
afterNextRender(() => {
|
|
778
|
+
this.service.initGlobalListeners(this.nativeElement);
|
|
779
|
+
});
|
|
814
780
|
}
|
|
815
781
|
/** @ignore */
|
|
816
782
|
get __hostClass() {
|
|
@@ -829,7 +795,7 @@ class AXMenuComponent extends NXComponent {
|
|
|
829
795
|
close() {
|
|
830
796
|
this.service.closeAll$.next();
|
|
831
797
|
}
|
|
832
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXMenuComponent, deps:
|
|
798
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXMenuComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
833
799
|
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: AXMenuComponent, isStandalone: true, 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 }, hasArrow: { classPropertyName: "hasArrow", publicName: "hasArrow", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { onItemClick: "onItemClick" }, host: { properties: { "class": "this.__hostClass" } }, providers: [
|
|
834
800
|
AXMenuService,
|
|
835
801
|
{
|
|
@@ -862,7 +828,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
|
|
|
862
828
|
AsyncPipe,
|
|
863
829
|
AXTranslatorPipe,
|
|
864
830
|
], template: "<ng-content select=\"ax-menu-item,ax-divider,ax-title,ng-container\"></ng-content>\n\n@for (node of items(); track node) {\n <ng-container [ngTemplateOutlet]=\"Recursion\" [ngTemplateOutletContext]=\"{ $implicit: node }\"> </ng-container>\n}\n\n<ng-template #Recursion let-item>\n @if (item.group?.title) {\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 @if (item.icon) {\n <ax-prefix>\n <ax-icon [icon]=\"item.icon\"> </ax-icon>\n </ax-prefix>\n }\n @if (item.text) {\n <ax-text>{{ item.text | translate | async }}</ax-text>\n }\n @if (item.suffix) {\n <ax-suffix>\n <ax-text>{{ item.suffix.text | translate | async }}</ax-text>\n </ax-suffix>\n }\n @for (child of item.items; track child) {\n <ng-container [ngTemplateOutlet]=\"Recursion\" [ngTemplateOutletContext]=\"{ $implicit: child }\"></ng-container>\n }\n </ax-menu-item>\n @if (item.break) {\n <ax-divider></ax-divider>\n }\n</ng-template>\n", styles: ["ax-context-menu,ax-menu{width:max-content;color:inherit;display:flex}:is(ax-context-menu,ax-menu).ax-menu-container,:is(ax-context-menu,ax-menu) .ax-menu-items{visibility:hidden;width:max-content;height:max-content;min-width:calc(var(--spacing,.25rem) * 48);border-radius:var(--radius-default,var(--ax-sys-border-radius));border-style:solid;border-width:1px;border-color:var(--color-border-lightest,rgba(var(--ax-sys-color-border-lightest-surface)));background-color:var(--color-lightest,rgba(var(--ax-sys-color-lightest-surface)));color:var(--color-on-lightest,rgba(var(--ax-sys-color-on-lightest-surface)));padding-block:calc(var(--spacing,.25rem) * 2);opacity:0;transition-property:all;transition-duration:var(--ax-sys-transition-duration);transition-timing-function:var(--ax-sys-transition-timing-function);flex-direction:column;display:flex;position:fixed;box-shadow:0 1px 3px #0000001a,0 1px 2px -1px #0000001a}:is(:is(ax-context-menu,ax-menu).ax-menu-container,:is(ax-context-menu,ax-menu) .ax-menu-items).ax-state-open{visibility:visible;opacity:1}:is(:is(ax-context-menu,ax-menu).ax-menu-container,:is(ax-context-menu,ax-menu) .ax-menu-items) ax-menu-item{color:var(--ax-comp-bg)}:is(:is(ax-context-menu,ax-menu).ax-menu-container,:is(ax-context-menu,ax-menu) .ax-menu-items) ax-menu-item:hover:not(.ax-state-disabled){background-color:var(--ax-comp-bg);color:var(--ax-comp-bg)}:is(:is(ax-context-menu,ax-menu).ax-menu-container,:is(ax-context-menu,ax-menu) .ax-menu-items) ax-menu-item:hover:not(.ax-state-disabled) ax-suffix ax-text{color:var(--ax-comp-bg)}:is(:is(ax-context-menu,ax-menu).ax-menu-container,:is(ax-context-menu,ax-menu) .ax-menu-items) ax-menu-item ax-suffix ax-text{font-weight:400!important}ax-context-menu.ax-action-list-horizontal{padding-inline:calc(var(--spacing,.25rem) * 4)}ax-menu>ax-menu-item:has(>.ax-action-item-suffix:not(:empty)){gap:calc(var(--spacing,.25rem) * 2)}ax-menu.ax-action-list-horizontal{min-width:calc(var(--spacing,.25rem) * 48);gap:calc(var(--spacing,.25rem) * 5)}ax-menu.ax-action-list-horizontal>ax-title{display:none}ax-menu.ax-action-list-horizontal>ax-menu-item{font-weight:500}ax-menu.ax-action-list-horizontal>ax-menu-item>.ax-action-item-prefix{padding-inline-start:0!important}ax-menu.ax-action-list-horizontal>ax-menu-item>.ax-action-item-suffix:not(ax-menu.ax-action-list-horizontal>ax-menu-item>.ax-action-item-suffix:empty){margin-inline-end:0!important;padding-inline-start:0!important}ax-menu.ax-action-list-horizontal>ax-menu-item:hover:not(ax-menu.ax-action-list-horizontal>ax-menu-item.ax-state-disabled){background-color:#0000!important}ax-menu.ax-action-list-horizontal>ax-menu-item:hover:not(ax-menu.ax-action-list-horizontal>ax-menu-item.ax-state-disabled)>.ax-action-item-prefix,ax-menu.ax-action-list-horizontal>ax-menu-item:hover:not(ax-menu.ax-action-list-horizontal>ax-menu-item.ax-state-disabled)>.ax-action-item-suffix{opacity:.7}ax-menu.ax-action-list-vertical{width:max-content;min-width:calc(var(--spacing,.25rem) * 48)}ax-menu.ax-action-list-vertical>ax-menu-item{font-weight:500}ax-menu.ax-action-list-vertical>ax-menu-item:hover:not(ax-menu.ax-action-list-vertical>ax-menu-item.ax-state-disabled){background-color:#0000!important}ax-menu.ax-action-list-vertical>ax-menu-item:hover:not(ax-menu.ax-action-list-vertical>ax-menu-item.ax-state-disabled)>.ax-action-item-prefix,ax-menu.ax-action-list-vertical>ax-menu-item:hover:not(ax-menu.ax-action-list-vertical>ax-menu-item.ax-state-disabled)>.ax-action-item-suffix{opacity:.7}ax-menu>ax-menu-item{padding-block:calc(var(--spacing,.25rem) * 2)}ax-menu>ax-menu-item:hover:not(ax-menu>ax-menu-item.ax-state-disabled){border-radius:var(--radius-default,var(--ax-sys-border-radius))}ax-menu>ax-menu-item:hover:not(ax-menu>ax-menu-item.ax-state-disabled)>ax-icon,ax-menu>ax-menu-item:hover:not(ax-menu>ax-menu-item.ax-state-disabled)>ax-text{opacity:.7}\n"] }]
|
|
865
|
-
}], propDecorators: { orientation: [{ type: i0.Input, args: [{ isSignal: true, alias: "orientation", required: false }] }], openOn: [{ type: i0.Input, args: [{ isSignal: true, alias: "openOn", required: false }] }], closeOn: [{ type: i0.Input, args: [{ isSignal: true, alias: "closeOn", required: false }] }], onItemClick: [{ type: i0.Output, args: ["onItemClick"] }], items: [{ type: i0.Input, args: [{ isSignal: true, alias: "items", required: false }] }], hasArrow: [{ type: i0.Input, args: [{ isSignal: true, alias: "hasArrow", required: false }] }], __hostClass: [{
|
|
831
|
+
}], ctorParameters: () => [], propDecorators: { orientation: [{ type: i0.Input, args: [{ isSignal: true, alias: "orientation", required: false }] }], openOn: [{ type: i0.Input, args: [{ isSignal: true, alias: "openOn", required: false }] }], closeOn: [{ type: i0.Input, args: [{ isSignal: true, alias: "closeOn", required: false }] }], onItemClick: [{ type: i0.Output, args: ["onItemClick"] }], items: [{ type: i0.Input, args: [{ isSignal: true, alias: "items", required: false }] }], hasArrow: [{ type: i0.Input, args: [{ isSignal: true, alias: "hasArrow", required: false }] }], __hostClass: [{
|
|
866
832
|
type: HostBinding,
|
|
867
833
|
args: ['class']
|
|
868
834
|
}] } });
|