@ng-nest/ui 21.0.11 → 21.0.12
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.
- package/fesm2022/ng-nest-ui-auto-complete.mjs +10 -2
- package/fesm2022/ng-nest-ui-auto-complete.mjs.map +1 -1
- package/fesm2022/ng-nest-ui-cascade.mjs +9 -1
- package/fesm2022/ng-nest-ui-cascade.mjs.map +1 -1
- package/fesm2022/ng-nest-ui-color-picker.mjs +9 -1
- package/fesm2022/ng-nest-ui-color-picker.mjs.map +1 -1
- package/fesm2022/ng-nest-ui-contextmenu.mjs +441 -0
- package/fesm2022/ng-nest-ui-contextmenu.mjs.map +1 -0
- package/fesm2022/ng-nest-ui-core.mjs.map +1 -1
- package/fesm2022/ng-nest-ui-date-picker.mjs +18 -2
- package/fesm2022/ng-nest-ui-date-picker.mjs.map +1 -1
- package/fesm2022/ng-nest-ui-dropdown.mjs +15 -3
- package/fesm2022/ng-nest-ui-dropdown.mjs.map +1 -1
- package/fesm2022/ng-nest-ui-select.mjs +49 -14
- package/fesm2022/ng-nest-ui-select.mjs.map +1 -1
- package/fesm2022/ng-nest-ui-splitter.mjs +407 -0
- package/fesm2022/ng-nest-ui-splitter.mjs.map +1 -0
- package/fesm2022/ng-nest-ui-time-picker.mjs +9 -1
- package/fesm2022/ng-nest-ui-time-picker.mjs.map +1 -1
- package/fesm2022/ng-nest-ui-tree-select.mjs +11 -3
- package/fesm2022/ng-nest-ui-tree-select.mjs.map +1 -1
- package/fesm2022/ng-nest-ui-watermark.mjs +378 -0
- package/fesm2022/ng-nest-ui-watermark.mjs.map +1 -0
- package/fesm2022/ng-nest-ui.mjs +3 -0
- package/fesm2022/ng-nest-ui.mjs.map +1 -1
- package/package.json +13 -1
- package/types/ng-nest-ui-auto-complete.d.ts +3 -3
- package/types/ng-nest-ui-cascade.d.ts +4 -4
- package/types/ng-nest-ui-checkbox.d.ts +1 -1
- package/types/ng-nest-ui-color-picker.d.ts +4 -4
- package/types/ng-nest-ui-contextmenu.d.ts +176 -0
- package/types/ng-nest-ui-core.d.ts +29 -1
- package/types/ng-nest-ui-date-picker.d.ts +7 -7
- package/types/ng-nest-ui-dropdown.d.ts +12 -2
- package/types/ng-nest-ui-radio.d.ts +1 -1
- package/types/ng-nest-ui-select.d.ts +28 -3
- package/types/ng-nest-ui-splitter.d.ts +163 -0
- package/types/ng-nest-ui-time-picker.d.ts +3 -3
- package/types/ng-nest-ui-tree-select.d.ts +4 -4
- package/types/ng-nest-ui-watermark.d.ts +267 -0
- package/types/ng-nest-ui.d.ts +3 -0
|
@@ -0,0 +1,441 @@
|
|
|
1
|
+
import * as i0 from '@angular/core';
|
|
2
|
+
import { input, output, Component, viewChild, signal, inject, DestroyRef, ViewContainerRef, effect, HostBinding, ChangeDetectionStrategy, ViewEncapsulation, computed, ElementRef, HostListener, NgModule } from '@angular/core';
|
|
3
|
+
import { XPropertyFunction, XToDataArray, XToBoolean, XToCssPixelValue, XIsEmpty, XGetChildren, XHasChildren } from '@ng-nest/ui/core';
|
|
4
|
+
import { Subject } from 'rxjs';
|
|
5
|
+
import { XPortalService } from '@ng-nest/ui/portal';
|
|
6
|
+
import { XListComponent } from '@ng-nest/ui/list';
|
|
7
|
+
import { FormsModule } from '@angular/forms';
|
|
8
|
+
import { Overlay } from '@angular/cdk/overlay';
|
|
9
|
+
import { RIGHT_ARROW, LEFT_ARROW } from '@angular/cdk/keycodes';
|
|
10
|
+
import { takeUntil } from 'rxjs/operators';
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Contextmenu
|
|
14
|
+
* @selector x-contextmenu
|
|
15
|
+
* @decorator component
|
|
16
|
+
*/
|
|
17
|
+
const XContextmenuPrefix = 'x-contextmenu';
|
|
18
|
+
const X_CONTEXTMENU_CONFIG_NAME = 'contextmenu';
|
|
19
|
+
/**
|
|
20
|
+
* Contextmenu Property
|
|
21
|
+
*/
|
|
22
|
+
class XContextmenuProperty extends XPropertyFunction(X_CONTEXTMENU_CONFIG_NAME) {
|
|
23
|
+
constructor() {
|
|
24
|
+
super(...arguments);
|
|
25
|
+
/**
|
|
26
|
+
* @zh_CN 触发目标元素
|
|
27
|
+
* @en_US Trigger target element
|
|
28
|
+
*/
|
|
29
|
+
this.target = input(...(ngDevMode ? [undefined, { debugName: "target" }] : []));
|
|
30
|
+
/**
|
|
31
|
+
* @zh_CN 节点数据
|
|
32
|
+
* @en_US Node data
|
|
33
|
+
*/
|
|
34
|
+
this.data = input([], { ...(ngDevMode ? { debugName: "data" } : {}), transform: XToDataArray });
|
|
35
|
+
/**
|
|
36
|
+
* @zh_CN 禁用
|
|
37
|
+
* @en_US Disabled
|
|
38
|
+
*/
|
|
39
|
+
this.disabled = input(false, { ...(ngDevMode ? { debugName: "disabled" } : {}), transform: XToBoolean });
|
|
40
|
+
/**
|
|
41
|
+
* @zh_CN 节点中已经包含子节点数据
|
|
42
|
+
* @en_US The node already contains child node data
|
|
43
|
+
*/
|
|
44
|
+
this.children = input(false, { ...(ngDevMode ? { debugName: "children" } : {}), transform: XToBoolean });
|
|
45
|
+
/**
|
|
46
|
+
* @zh_CN 展示位置
|
|
47
|
+
* @en_US Placement
|
|
48
|
+
*/
|
|
49
|
+
this.placement = input(this.config?.placement ?? 'bottom-start', ...(ngDevMode ? [{ debugName: "placement" }] : []));
|
|
50
|
+
/**
|
|
51
|
+
* @zh_CN 弹框的宽度
|
|
52
|
+
* @en_US The width of the drop-down box
|
|
53
|
+
*/
|
|
54
|
+
this.portalWidth = input('', { ...(ngDevMode ? { debugName: "portalWidth" } : {}), transform: XToCssPixelValue });
|
|
55
|
+
/**
|
|
56
|
+
* @zh_CN 弹框设置样式名
|
|
57
|
+
* @en_US The style class name of the drop-down box
|
|
58
|
+
*/
|
|
59
|
+
this.portalClass = input('', ...(ngDevMode ? [{ debugName: "portalClass" }] : []));
|
|
60
|
+
/**
|
|
61
|
+
* @zh_CN 弹框最大高度
|
|
62
|
+
* @en_US The biggest height of the drop-down box
|
|
63
|
+
*/
|
|
64
|
+
this.portalMaxHeight = input(this.config?.portalMaxHeight ?? '18rem', { ...(ngDevMode ? { debugName: "portalMaxHeight" } : {}), transform: XToCssPixelValue });
|
|
65
|
+
/**
|
|
66
|
+
* @zh_CN 弹框高度,启用虚拟滚动的时候必须设置一个高度
|
|
67
|
+
* @en_US The biggest height of the drop-down box
|
|
68
|
+
*/
|
|
69
|
+
this.portalHeight = input('', { ...(ngDevMode ? { debugName: "portalHeight" } : {}), transform: XToCssPixelValue });
|
|
70
|
+
/**
|
|
71
|
+
* @zh_CN 尺寸
|
|
72
|
+
* @en_US Size
|
|
73
|
+
*/
|
|
74
|
+
this.size = input(this.config?.size ?? 'medium', ...(ngDevMode ? [{ debugName: "size" }] : []));
|
|
75
|
+
/**
|
|
76
|
+
* @zh_CN 节点点击事件
|
|
77
|
+
* @en_US Node click event
|
|
78
|
+
*/
|
|
79
|
+
this.nodeClick = output();
|
|
80
|
+
}
|
|
81
|
+
/** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: XContextmenuProperty, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
|
|
82
|
+
/** @nocollapse */ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.1.1", type: XContextmenuProperty, isStandalone: true, selector: "x-contextmenu-property", inputs: { target: { classPropertyName: "target", publicName: "target", 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 }, children: { classPropertyName: "children", publicName: "children", isSignal: true, isRequired: false, transformFunction: null }, placement: { classPropertyName: "placement", publicName: "placement", isSignal: true, isRequired: false, transformFunction: null }, portalWidth: { classPropertyName: "portalWidth", publicName: "portalWidth", isSignal: true, isRequired: false, transformFunction: null }, portalClass: { classPropertyName: "portalClass", publicName: "portalClass", isSignal: true, isRequired: false, transformFunction: null }, portalMaxHeight: { classPropertyName: "portalMaxHeight", publicName: "portalMaxHeight", isSignal: true, isRequired: false, transformFunction: null }, portalHeight: { classPropertyName: "portalHeight", publicName: "portalHeight", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { nodeClick: "nodeClick" }, usesInheritance: true, ngImport: i0, template: '', isInline: true }); }
|
|
83
|
+
}
|
|
84
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: XContextmenuProperty, decorators: [{
|
|
85
|
+
type: Component,
|
|
86
|
+
args: [{ selector: `${XContextmenuPrefix}-property`, template: '' }]
|
|
87
|
+
}], propDecorators: { target: [{ type: i0.Input, args: [{ isSignal: true, alias: "target", required: false }] }], data: [{ type: i0.Input, args: [{ isSignal: true, alias: "data", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], children: [{ type: i0.Input, args: [{ isSignal: true, alias: "children", required: false }] }], placement: [{ type: i0.Input, args: [{ isSignal: true, alias: "placement", required: false }] }], portalWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "portalWidth", required: false }] }], portalClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "portalClass", required: false }] }], portalMaxHeight: [{ type: i0.Input, args: [{ isSignal: true, alias: "portalMaxHeight", required: false }] }], portalHeight: [{ type: i0.Input, args: [{ isSignal: true, alias: "portalHeight", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], nodeClick: [{ type: i0.Output, args: ["nodeClick"] }] } });
|
|
88
|
+
|
|
89
|
+
class XContextmenuPortalComponent {
|
|
90
|
+
constructor() {
|
|
91
|
+
this.animateEnter = 'x-connect-enter';
|
|
92
|
+
this.animateLeave = 'x-connect-leave';
|
|
93
|
+
this.data = input([], ...(ngDevMode ? [{ debugName: "data" }] : []));
|
|
94
|
+
this.size = input('medium', ...(ngDevMode ? [{ debugName: "size" }] : []));
|
|
95
|
+
this.portalWidth = input(...(ngDevMode ? [undefined, { debugName: "portalWidth" }] : []));
|
|
96
|
+
this.portalHeight = input(...(ngDevMode ? [undefined, { debugName: "portalHeight" }] : []));
|
|
97
|
+
this.portalMaxHeight = input(...(ngDevMode ? [undefined, { debugName: "portalMaxHeight" }] : []));
|
|
98
|
+
this.portalClass = input(...(ngDevMode ? [undefined, { debugName: "portalClass" }] : []));
|
|
99
|
+
this.level = input(0, ...(ngDevMode ? [{ debugName: "level" }] : []));
|
|
100
|
+
this.parentPortalComponent = input(...(ngDevMode ? [undefined, { debugName: "parentPortalComponent" }] : []));
|
|
101
|
+
this.closed = output();
|
|
102
|
+
this.animating = output();
|
|
103
|
+
this.nodeClick = output();
|
|
104
|
+
this.list = viewChild.required('list');
|
|
105
|
+
this.destroy = signal(false, ...(ngDevMode ? [{ debugName: "destroy" }] : []));
|
|
106
|
+
this.active = signal(0, ...(ngDevMode ? [{ debugName: "active" }] : []));
|
|
107
|
+
this.node = signal(null, ...(ngDevMode ? [{ debugName: "node" }] : []));
|
|
108
|
+
this.childAnimating = signal(false, ...(ngDevMode ? [{ debugName: "childAnimating" }] : []));
|
|
109
|
+
this.isKeyboardControlled = signal(true, ...(ngDevMode ? [{ debugName: "isKeyboardControlled" }] : []));
|
|
110
|
+
this.unSubject = new Subject();
|
|
111
|
+
this.destroyRef = inject(DestroyRef);
|
|
112
|
+
this.portalService = inject(XPortalService);
|
|
113
|
+
this.overlay = inject(Overlay);
|
|
114
|
+
this.viewContainerRef = inject(ViewContainerRef);
|
|
115
|
+
this.portalComponent = signal(null, ...(ngDevMode ? [{ debugName: "portalComponent" }] : []));
|
|
116
|
+
this.portalOverlayRef = signal(null, ...(ngDevMode ? [{ debugName: "portalOverlayRef" }] : []));
|
|
117
|
+
effect(() => this.portalComponent()?.setInput('data', this.node()?.children));
|
|
118
|
+
effect(() => this.portalComponent()?.setInput('level', this.level() + 1));
|
|
119
|
+
effect(() => this.portalComponent()?.setInput('size', this.size()));
|
|
120
|
+
effect(() => this.portalComponent()?.setInput('portalWidth', this.portalWidth()));
|
|
121
|
+
effect(() => this.portalComponent()?.setInput('parentPortalComponent', this));
|
|
122
|
+
this.destroyRef.onDestroy(() => {
|
|
123
|
+
this.destroy.set(true);
|
|
124
|
+
this.unSubject.next();
|
|
125
|
+
this.unSubject.complete();
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
ngOnInit() {
|
|
129
|
+
this.closeSubject.subscribe(() => {
|
|
130
|
+
this.data() && this.data().length > 0 && this.list().setUnActive(this.active());
|
|
131
|
+
});
|
|
132
|
+
this.keydownSubject.pipe(takeUntil(this.unSubject)).subscribe((x) => {
|
|
133
|
+
if (!this.isKeyboardControlled())
|
|
134
|
+
return;
|
|
135
|
+
const keyCode = x.keyCode;
|
|
136
|
+
const isRightArrow = [RIGHT_ARROW].includes(keyCode);
|
|
137
|
+
const isLeftArrow = [LEFT_ARROW].includes(keyCode);
|
|
138
|
+
if (isRightArrow) {
|
|
139
|
+
const item = this.list().keyManager.activeItem;
|
|
140
|
+
if (item?.leaf()) {
|
|
141
|
+
const node = item.node();
|
|
142
|
+
node.event = x;
|
|
143
|
+
node.component = item;
|
|
144
|
+
this.isKeyboardControlled.set(false);
|
|
145
|
+
this.onNodeClick(node);
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
if (isLeftArrow && this.level() > 0) {
|
|
149
|
+
this.parentPortalComponent()?.isKeyboardControlled.set(true);
|
|
150
|
+
this.parentPortalComponent()?.closePortal();
|
|
151
|
+
}
|
|
152
|
+
this.data() && this.data().length > 0 && this.list().keydown(x);
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
ngAfterViewInit() {
|
|
156
|
+
this.list().keyManager.setFirstItemActive();
|
|
157
|
+
}
|
|
158
|
+
onNodeClick(node) {
|
|
159
|
+
this.nodeClick.emit(node);
|
|
160
|
+
// 如果有子节点,显示子菜单
|
|
161
|
+
if (node.children && node.children.length > 0) {
|
|
162
|
+
this.showPortal(node);
|
|
163
|
+
}
|
|
164
|
+
else {
|
|
165
|
+
// 叶子节点,关闭所有菜单
|
|
166
|
+
this.closeSubject.next();
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
onActive(num) {
|
|
170
|
+
this.active.set(num);
|
|
171
|
+
}
|
|
172
|
+
onNodeMouseenter(node) {
|
|
173
|
+
// 鼠标悬停时展开子菜单
|
|
174
|
+
if (node.children && node.children.length > 0) {
|
|
175
|
+
this.showPortal(node);
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
onNodeMouseleave() {
|
|
179
|
+
// 可以在这里添加延迟关闭逻辑
|
|
180
|
+
}
|
|
181
|
+
portalAttached() {
|
|
182
|
+
return this.portalOverlayRef()?.hasAttached();
|
|
183
|
+
}
|
|
184
|
+
closePortal() {
|
|
185
|
+
if (this.portalAttached()) {
|
|
186
|
+
this.portalOverlayRef()?.dispose();
|
|
187
|
+
return true;
|
|
188
|
+
}
|
|
189
|
+
return false;
|
|
190
|
+
}
|
|
191
|
+
createPortal() {
|
|
192
|
+
const config = {
|
|
193
|
+
backdropClass: '',
|
|
194
|
+
width: this.portalWidth(),
|
|
195
|
+
panelClass: this.portalClass(),
|
|
196
|
+
positionStrategy: this.setPlacement(),
|
|
197
|
+
scrollStrategy: this.overlay.scrollStrategies.reposition()
|
|
198
|
+
};
|
|
199
|
+
this.portal = this.portalService.attach({
|
|
200
|
+
content: XContextmenuPortalComponent,
|
|
201
|
+
viewContainerRef: this.viewContainerRef,
|
|
202
|
+
overlayConfig: config
|
|
203
|
+
});
|
|
204
|
+
this.setInstance();
|
|
205
|
+
}
|
|
206
|
+
setInstance() {
|
|
207
|
+
let { componentRef, overlayRef } = this.portal;
|
|
208
|
+
if (!componentRef || !overlayRef)
|
|
209
|
+
return;
|
|
210
|
+
this.portalComponent.set(componentRef);
|
|
211
|
+
this.portalOverlayRef.set(overlayRef);
|
|
212
|
+
Object.assign(componentRef.instance, {
|
|
213
|
+
closeSubject: this.closeSubject,
|
|
214
|
+
keydownSubject: this.keydownSubject
|
|
215
|
+
});
|
|
216
|
+
const { closed, animating, nodeClick } = componentRef.instance;
|
|
217
|
+
closed.subscribe(() => this.closePortal());
|
|
218
|
+
animating.subscribe((ing) => this.childAnimating.set(ing));
|
|
219
|
+
nodeClick.subscribe((node) => this.nodeClick.emit(node));
|
|
220
|
+
}
|
|
221
|
+
setPlacement() {
|
|
222
|
+
return this.portalService.setPlacement({
|
|
223
|
+
elementRef: this.node()?.component?.getElementRef(),
|
|
224
|
+
placement: ['right-start', 'right-end', 'left-start', 'left-end'],
|
|
225
|
+
transformOriginOn: 'x-contextmenu-portal'
|
|
226
|
+
});
|
|
227
|
+
}
|
|
228
|
+
showPortal(node) {
|
|
229
|
+
if (this.portalAttached() && this.node()?.id !== node.id) {
|
|
230
|
+
this.portalOverlayRef()?.dispose();
|
|
231
|
+
}
|
|
232
|
+
this.node.set(node);
|
|
233
|
+
if (!this.portalAttached()) {
|
|
234
|
+
this.createPortal();
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
/** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: XContextmenuPortalComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
238
|
+
/** @nocollapse */ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "21.1.1", type: XContextmenuPortalComponent, isStandalone: true, selector: "x-contextmenu-portal", inputs: { data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, portalWidth: { classPropertyName: "portalWidth", publicName: "portalWidth", isSignal: true, isRequired: false, transformFunction: null }, portalHeight: { classPropertyName: "portalHeight", publicName: "portalHeight", isSignal: true, isRequired: false, transformFunction: null }, portalMaxHeight: { classPropertyName: "portalMaxHeight", publicName: "portalMaxHeight", isSignal: true, isRequired: false, transformFunction: null }, portalClass: { classPropertyName: "portalClass", publicName: "portalClass", isSignal: true, isRequired: false, transformFunction: null }, level: { classPropertyName: "level", publicName: "level", isSignal: true, isRequired: false, transformFunction: null }, parentPortalComponent: { classPropertyName: "parentPortalComponent", publicName: "parentPortalComponent", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { closed: "closed", animating: "animating", nodeClick: "nodeClick" }, host: { properties: { "animate.enter": "this.animateEnter", "animate.leave": "this.animateLeave" } }, viewQueries: [{ propertyName: "list", first: true, predicate: ["list"], descendants: true, isSignal: true }], ngImport: i0, template: "<div\r\n #contextmenuPortal\r\n class=\"x-contextmenu-portal\"\r\n [style.maxHeight]=\"portalHeight() ? portalHeight() : portalMaxHeight()\"\r\n [style.height]=\"portalHeight()\"\r\n>\r\n <x-list\r\n #list\r\n [data]=\"data()\"\r\n (nodeClick)=\"onNodeClick($event)\"\r\n (keyManagerChange)=\"onActive($event)\"\r\n [inPortal]=\"true\"\r\n [size]=\"size()\"\r\n (nodeMouseenter)=\"onNodeMouseenter($event)\"\r\n (nodeMouseleave)=\"onNodeMouseleave()\"\r\n ></x-list>\r\n</div>\r\n", styles: ["x-contextmenu-portal{width:100%}.x-contextmenu-portal{margin:.0625rem 0;color:var(--x-text);width:100%;background-color:var(--x-background-100);border-radius:var(--x-border-small-radius);box-shadow:var(--x-box-shadow);position:relative;display:flex;overflow:auto}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "component", type: XListComponent, selector: "x-list" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
|
|
239
|
+
}
|
|
240
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: XContextmenuPortalComponent, decorators: [{
|
|
241
|
+
type: Component,
|
|
242
|
+
args: [{ selector: `x-contextmenu-portal`, imports: [FormsModule, XListComponent], encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, template: "<div\r\n #contextmenuPortal\r\n class=\"x-contextmenu-portal\"\r\n [style.maxHeight]=\"portalHeight() ? portalHeight() : portalMaxHeight()\"\r\n [style.height]=\"portalHeight()\"\r\n>\r\n <x-list\r\n #list\r\n [data]=\"data()\"\r\n (nodeClick)=\"onNodeClick($event)\"\r\n (keyManagerChange)=\"onActive($event)\"\r\n [inPortal]=\"true\"\r\n [size]=\"size()\"\r\n (nodeMouseenter)=\"onNodeMouseenter($event)\"\r\n (nodeMouseleave)=\"onNodeMouseleave()\"\r\n ></x-list>\r\n</div>\r\n", styles: ["x-contextmenu-portal{width:100%}.x-contextmenu-portal{margin:.0625rem 0;color:var(--x-text);width:100%;background-color:var(--x-background-100);border-radius:var(--x-border-small-radius);box-shadow:var(--x-box-shadow);position:relative;display:flex;overflow:auto}\n"] }]
|
|
243
|
+
}], ctorParameters: () => [], propDecorators: { animateEnter: [{
|
|
244
|
+
type: HostBinding,
|
|
245
|
+
args: ['animate.enter']
|
|
246
|
+
}], animateLeave: [{
|
|
247
|
+
type: HostBinding,
|
|
248
|
+
args: ['animate.leave']
|
|
249
|
+
}], data: [{ type: i0.Input, args: [{ isSignal: true, alias: "data", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], portalWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "portalWidth", required: false }] }], portalHeight: [{ type: i0.Input, args: [{ isSignal: true, alias: "portalHeight", required: false }] }], portalMaxHeight: [{ type: i0.Input, args: [{ isSignal: true, alias: "portalMaxHeight", required: false }] }], portalClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "portalClass", required: false }] }], level: [{ type: i0.Input, args: [{ isSignal: true, alias: "level", required: false }] }], parentPortalComponent: [{ type: i0.Input, args: [{ isSignal: true, alias: "parentPortalComponent", required: false }] }], closed: [{ type: i0.Output, args: ["closed"] }], animating: [{ type: i0.Output, args: ["animating"] }], nodeClick: [{ type: i0.Output, args: ["nodeClick"] }], list: [{ type: i0.ViewChild, args: ['list', { isSignal: true }] }] } });
|
|
250
|
+
|
|
251
|
+
class XContextmenuComponent extends XContextmenuProperty {
|
|
252
|
+
constructor() {
|
|
253
|
+
super();
|
|
254
|
+
this.unSubject = new Subject();
|
|
255
|
+
this.portalService = inject(XPortalService);
|
|
256
|
+
this.viewContainerRef = inject(ViewContainerRef);
|
|
257
|
+
this.overlay = inject(Overlay);
|
|
258
|
+
this.nodes = computed(() => {
|
|
259
|
+
const data = this.data();
|
|
260
|
+
if (!this.children()) {
|
|
261
|
+
return data.filter((y) => XIsEmpty(y.pid)).map((y) => XGetChildren(data, y, 0));
|
|
262
|
+
}
|
|
263
|
+
return XHasChildren(data, 0);
|
|
264
|
+
}, ...(ngDevMode ? [{ debugName: "nodes" }] : []));
|
|
265
|
+
this.animating = signal(false, ...(ngDevMode ? [{ debugName: "animating" }] : []));
|
|
266
|
+
this.visibleClass = signal(false, ...(ngDevMode ? [{ debugName: "visibleClass" }] : []));
|
|
267
|
+
this.isClickNodeLeaf = signal(false, ...(ngDevMode ? [{ debugName: "isClickNodeLeaf" }] : []));
|
|
268
|
+
this.minWidth = signal('0px', ...(ngDevMode ? [{ debugName: "minWidth" }] : []));
|
|
269
|
+
this.closeSubject = new Subject();
|
|
270
|
+
this.keydownSubject = new Subject();
|
|
271
|
+
this.positionElement = null;
|
|
272
|
+
this.clickPosition = signal(null, ...(ngDevMode ? [{ debugName: "clickPosition" }] : []));
|
|
273
|
+
this.portalComponent = signal(null, ...(ngDevMode ? [{ debugName: "portalComponent" }] : []));
|
|
274
|
+
effect(() => this.portalComponent()?.setInput('data', this.nodes()));
|
|
275
|
+
effect(() => this.portalComponent()?.setInput('size', this.size()));
|
|
276
|
+
effect(() => this.portalComponent()?.setInput('portalMaxHeight', this.portalMaxHeight()));
|
|
277
|
+
effect(() => this.portalComponent()?.setInput('portalHeight', this.portalHeight()));
|
|
278
|
+
effect(() => this.portalComponent()?.setInput('portalWidth', this.portalWidth()));
|
|
279
|
+
effect(() => this.portalComponent()?.setInput('portalClass', this.portalClass()));
|
|
280
|
+
}
|
|
281
|
+
ngOnInit() {
|
|
282
|
+
this.setSubject();
|
|
283
|
+
// 监听全局键盘事件
|
|
284
|
+
this.keydownSubject.pipe(takeUntil(this.unSubject)).subscribe((event) => {
|
|
285
|
+
if (event.key === 'Escape') {
|
|
286
|
+
this.closePortal();
|
|
287
|
+
}
|
|
288
|
+
});
|
|
289
|
+
}
|
|
290
|
+
ngOnDestroy() {
|
|
291
|
+
this.unSubject.next();
|
|
292
|
+
this.unSubject.complete();
|
|
293
|
+
this.removePositionElement();
|
|
294
|
+
}
|
|
295
|
+
onContextmenu(event) {
|
|
296
|
+
if (this.disabled())
|
|
297
|
+
return;
|
|
298
|
+
const target = this.target();
|
|
299
|
+
if (!target)
|
|
300
|
+
return;
|
|
301
|
+
// 检查点击的目标是否是我们绑定的元素
|
|
302
|
+
const targetElement = target instanceof ElementRef ? target.nativeElement : target;
|
|
303
|
+
if (!targetElement.contains(event.target))
|
|
304
|
+
return;
|
|
305
|
+
// 阻止默认右键菜单
|
|
306
|
+
event.preventDefault();
|
|
307
|
+
// 先关闭已打开的菜单
|
|
308
|
+
this.closePortal();
|
|
309
|
+
// 记录点击位置
|
|
310
|
+
this.clickPosition.set({ x: event.clientX, y: event.clientY });
|
|
311
|
+
// 创建定位元素
|
|
312
|
+
this.createPositionElement(event.clientX, event.clientY);
|
|
313
|
+
// 打开菜单
|
|
314
|
+
this.openPortal();
|
|
315
|
+
}
|
|
316
|
+
onClose() {
|
|
317
|
+
this.closePortal();
|
|
318
|
+
}
|
|
319
|
+
setSubject() {
|
|
320
|
+
this.closeSubject.pipe(takeUntil(this.unSubject)).subscribe(() => {
|
|
321
|
+
this.closePortal();
|
|
322
|
+
});
|
|
323
|
+
}
|
|
324
|
+
openPortal() {
|
|
325
|
+
if (!this.clickPosition())
|
|
326
|
+
return;
|
|
327
|
+
this.visibleClass.set(true);
|
|
328
|
+
const config = {
|
|
329
|
+
backdropClass: '',
|
|
330
|
+
panelClass: this.portalClass(),
|
|
331
|
+
width: this.portalWidth(),
|
|
332
|
+
positionStrategy: this.createPositionStrategy(),
|
|
333
|
+
scrollStrategy: this.overlay.scrollStrategies.reposition(),
|
|
334
|
+
minWidth: this.minWidth()
|
|
335
|
+
};
|
|
336
|
+
this.portal = this.portalService.attach({
|
|
337
|
+
content: XContextmenuPortalComponent,
|
|
338
|
+
viewContainerRef: this.viewContainerRef,
|
|
339
|
+
overlayConfig: config
|
|
340
|
+
});
|
|
341
|
+
this.setInstance();
|
|
342
|
+
}
|
|
343
|
+
closePortal() {
|
|
344
|
+
if (this.portalAttached()) {
|
|
345
|
+
this.portal.overlayRef?.dispose();
|
|
346
|
+
this.visibleClass.set(false);
|
|
347
|
+
this.removePositionElement();
|
|
348
|
+
return true;
|
|
349
|
+
}
|
|
350
|
+
return false;
|
|
351
|
+
}
|
|
352
|
+
portalAttached() {
|
|
353
|
+
return this.portal?.overlayRef?.hasAttached();
|
|
354
|
+
}
|
|
355
|
+
createPositionElement(x, y) {
|
|
356
|
+
this.removePositionElement();
|
|
357
|
+
const element = document.createElement('div');
|
|
358
|
+
element.style.position = 'fixed';
|
|
359
|
+
element.style.left = `${x}px`;
|
|
360
|
+
element.style.top = `${y}px`;
|
|
361
|
+
element.style.width = '0px';
|
|
362
|
+
element.style.height = '0px';
|
|
363
|
+
element.style.pointerEvents = 'none';
|
|
364
|
+
element.className = 'x-contextmenu-position';
|
|
365
|
+
document.body.appendChild(element);
|
|
366
|
+
this.positionElement = element;
|
|
367
|
+
}
|
|
368
|
+
removePositionElement() {
|
|
369
|
+
if (this.positionElement) {
|
|
370
|
+
this.positionElement.remove();
|
|
371
|
+
this.positionElement = null;
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
setInstance() {
|
|
375
|
+
let { componentRef, overlayRef } = this.portal;
|
|
376
|
+
if (!componentRef || !overlayRef)
|
|
377
|
+
return;
|
|
378
|
+
this.portalComponent.set(componentRef);
|
|
379
|
+
Object.assign(componentRef.instance, {
|
|
380
|
+
closeSubject: this.closeSubject,
|
|
381
|
+
keydownSubject: this.keydownSubject
|
|
382
|
+
});
|
|
383
|
+
const { closed, animating, nodeClick } = componentRef.instance;
|
|
384
|
+
closed.subscribe(() => this.closeSubject.next());
|
|
385
|
+
animating.subscribe((ing) => this.animating.set(ing));
|
|
386
|
+
nodeClick.subscribe((node) => {
|
|
387
|
+
this.isClickNodeLeaf.set(node.leaf);
|
|
388
|
+
this.nodeClick.emit(node);
|
|
389
|
+
});
|
|
390
|
+
}
|
|
391
|
+
createPositionStrategy() {
|
|
392
|
+
const pos = this.clickPosition();
|
|
393
|
+
if (!pos)
|
|
394
|
+
return this.overlay.position().global();
|
|
395
|
+
// 使用全局定位策略,直接设置位置
|
|
396
|
+
const strategy = this.overlay.position().global();
|
|
397
|
+
strategy.left(`${pos.x}px`);
|
|
398
|
+
strategy.top(`${pos.y}px`);
|
|
399
|
+
return strategy;
|
|
400
|
+
}
|
|
401
|
+
setPlacement() {
|
|
402
|
+
const positionElement = this.positionElement || document.body;
|
|
403
|
+
return this.portalService.setPlacement({
|
|
404
|
+
elementRef: { nativeElement: positionElement },
|
|
405
|
+
placement: [this.placement(), 'bottom-start', 'bottom-end', 'bottom', 'top-start', 'top-end', 'top'],
|
|
406
|
+
transformOriginOn: 'x-contextmenu-portal'
|
|
407
|
+
});
|
|
408
|
+
}
|
|
409
|
+
/** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: XContextmenuComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
410
|
+
/** @nocollapse */ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.1.1", type: XContextmenuComponent, isStandalone: true, selector: "x-contextmenu", host: { listeners: { "document:contextmenu": "onContextmenu($event)", "document:click": "onClose()" } }, usesInheritance: true, ngImport: i0, template: "<div class=\"x-contextmenu\" [class.x-visible]=\"visibleClass()\">\r\n <ng-content></ng-content>\r\n</div>\r\n", styles: [".x-contextmenu{margin:0;padding:0}.x-contextmenu{display:inline-block}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
|
|
411
|
+
}
|
|
412
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: XContextmenuComponent, decorators: [{
|
|
413
|
+
type: Component,
|
|
414
|
+
args: [{ selector: `${XContextmenuPrefix}`, imports: [], encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, template: "<div class=\"x-contextmenu\" [class.x-visible]=\"visibleClass()\">\r\n <ng-content></ng-content>\r\n</div>\r\n", styles: [".x-contextmenu{margin:0;padding:0}.x-contextmenu{display:inline-block}\n"] }]
|
|
415
|
+
}], ctorParameters: () => [], propDecorators: { onContextmenu: [{
|
|
416
|
+
type: HostListener,
|
|
417
|
+
args: ['document:contextmenu', ['$event']]
|
|
418
|
+
}], onClose: [{
|
|
419
|
+
type: HostListener,
|
|
420
|
+
args: ['document:click']
|
|
421
|
+
}] } });
|
|
422
|
+
|
|
423
|
+
class XContextmenuModule {
|
|
424
|
+
/** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: XContextmenuModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
|
|
425
|
+
/** @nocollapse */ static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "21.1.1", ngImport: i0, type: XContextmenuModule, imports: [XContextmenuComponent], exports: [XContextmenuComponent] }); }
|
|
426
|
+
/** @nocollapse */ static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: XContextmenuModule }); }
|
|
427
|
+
}
|
|
428
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: XContextmenuModule, decorators: [{
|
|
429
|
+
type: NgModule,
|
|
430
|
+
args: [{
|
|
431
|
+
imports: [XContextmenuComponent],
|
|
432
|
+
exports: [XContextmenuComponent]
|
|
433
|
+
}]
|
|
434
|
+
}] });
|
|
435
|
+
|
|
436
|
+
/**
|
|
437
|
+
* Generated bundle index. Do not edit.
|
|
438
|
+
*/
|
|
439
|
+
|
|
440
|
+
export { XContextmenuComponent, XContextmenuModule, XContextmenuPrefix, XContextmenuProperty };
|
|
441
|
+
//# sourceMappingURL=ng-nest-ui-contextmenu.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ng-nest-ui-contextmenu.mjs","sources":["../../../../lib/ng-nest/ui/contextmenu/contextmenu.property.ts","../../../../lib/ng-nest/ui/contextmenu/contextmenu-portal.component.ts","../../../../lib/ng-nest/ui/contextmenu/contextmenu-portal.component.html","../../../../lib/ng-nest/ui/contextmenu/contextmenu.component.ts","../../../../lib/ng-nest/ui/contextmenu/contextmenu.component.html","../../../../lib/ng-nest/ui/contextmenu/contextmenu.module.ts","../../../../lib/ng-nest/ui/contextmenu/ng-nest-ui-contextmenu.ts"],"sourcesContent":["import {\r\n XBoolean,\r\n XPlacement,\r\n XSize,\r\n XPropertyFunction,\r\n XToDataArray,\r\n XDataArray,\r\n XToBoolean,\r\n XNumber,\r\n XToCssPixelValue\r\n} from '@ng-nest/ui/core';\r\nimport { XListNode } from '@ng-nest/ui/list';\r\nimport { Component, input, output, ElementRef } from '@angular/core';\r\n\r\n/**\r\n * Contextmenu\r\n * @selector x-contextmenu\r\n * @decorator component\r\n */\r\nexport const XContextmenuPrefix = 'x-contextmenu';\r\nconst X_CONTEXTMENU_CONFIG_NAME = 'contextmenu';\r\n\r\n/**\r\n * Contextmenu Property\r\n */\r\n@Component({ selector: `${XContextmenuPrefix}-property`, template: '' })\r\nexport class XContextmenuProperty extends XPropertyFunction(X_CONTEXTMENU_CONFIG_NAME) {\r\n /**\r\n * @zh_CN 触发目标元素\r\n * @en_US Trigger target element\r\n */\r\n readonly target = input<ElementRef | HTMLElement>();\r\n /**\r\n * @zh_CN 节点数据\r\n * @en_US Node data\r\n */\r\n readonly data = input<XContextmenuNode[], XDataArray<XContextmenuNode>>([], { transform: XToDataArray });\r\n /**\r\n * @zh_CN 禁用\r\n * @en_US Disabled\r\n */\r\n readonly disabled = input<boolean, XBoolean>(false, { transform: XToBoolean });\r\n /**\r\n * @zh_CN 节点中已经包含子节点数据\r\n * @en_US The node already contains child node data\r\n */\r\n readonly children = input<boolean, XBoolean>(false, { transform: XToBoolean });\r\n /**\r\n * @zh_CN 展示位置\r\n * @en_US Placement\r\n */\r\n readonly placement = input<XPlacement>(this.config?.placement ?? 'bottom-start');\r\n /**\r\n * @zh_CN 弹框的宽度\r\n * @en_US The width of the drop-down box\r\n */\r\n readonly portalWidth = input<string, XNumber>('', { transform: XToCssPixelValue });\r\n /**\r\n * @zh_CN 弹框设置样式名\r\n * @en_US The style class name of the drop-down box\r\n */\r\n readonly portalClass = input<string | string[]>('');\r\n /**\r\n * @zh_CN 弹框最大高度\r\n * @en_US The biggest height of the drop-down box\r\n */\r\n readonly portalMaxHeight = input<string, XNumber>(this.config?.portalMaxHeight ?? '18rem', {\r\n transform: XToCssPixelValue\r\n });\r\n /**\r\n * @zh_CN 弹框高度,启用虚拟滚动的时候必须设置一个高度\r\n * @en_US The biggest height of the drop-down box\r\n */\r\n readonly portalHeight = input<string, XNumber>('', {\r\n transform: XToCssPixelValue\r\n });\r\n /**\r\n * @zh_CN 尺寸\r\n * @en_US Size\r\n */\r\n readonly size = input<XSize>(this.config?.size ?? 'medium');\r\n /**\r\n * @zh_CN 节点点击事件\r\n * @en_US Node click event\r\n */\r\n readonly nodeClick = output<XContextmenuNode>();\r\n}\r\n\r\n/**\r\n * @zh_CN Contextmenu 数据对象\r\n * @en_US Contextmenu data object\r\n */\r\nexport interface XContextmenuNode extends XListNode {}\r\n","import {\r\n Component,\r\n ViewEncapsulation,\r\n ChangeDetectionStrategy,\r\n HostBinding,\r\n input,\r\n output,\r\n signal,\r\n inject,\r\n DestroyRef,\r\n viewChild,\r\n ViewContainerRef,\r\n effect,\r\n ComponentRef\r\n} from '@angular/core';\r\nimport { XContextmenuNode } from './contextmenu.property';\r\nimport { Subject } from 'rxjs';\r\nimport { XListComponent } from '@ng-nest/ui/list';\r\nimport { FormsModule } from '@angular/forms';\r\nimport { XSize } from '@ng-nest/ui/core';\r\nimport { XPortalOverlayRef, XPortalService } from '@ng-nest/ui/portal';\r\nimport { Overlay, OverlayConfig } from '@angular/cdk/overlay';\r\nimport { RIGHT_ARROW, LEFT_ARROW } from '@angular/cdk/keycodes';\r\nimport { takeUntil } from 'rxjs/operators';\r\n\r\n@Component({\r\n selector: `x-contextmenu-portal`,\r\n imports: [FormsModule, XListComponent],\r\n templateUrl: './contextmenu-portal.component.html',\r\n styleUrls: ['./contextmenu-portal.component.scss'],\r\n encapsulation: ViewEncapsulation.None,\r\n changeDetection: ChangeDetectionStrategy.OnPush\r\n})\r\nexport class XContextmenuPortalComponent {\r\n @HostBinding('animate.enter') animateEnter = 'x-connect-enter';\r\n @HostBinding('animate.leave') animateLeave = 'x-connect-leave';\r\n\r\n data = input<XContextmenuNode[]>([]);\r\n size = input<XSize>('medium');\r\n portalWidth = input<string>();\r\n portalHeight = input<string>();\r\n portalMaxHeight = input<string>();\r\n portalClass = input<string>();\r\n\r\n level = input(0);\r\n parentPortalComponent = input<XContextmenuPortalComponent>();\r\n\r\n closed = output();\r\n animating = output<boolean>();\r\n nodeClick = output<XContextmenuNode>();\r\n\r\n list = viewChild.required<XListComponent>('list');\r\n destroy = signal(false);\r\n closeSubject!: Subject<void>;\r\n keydownSubject!: Subject<KeyboardEvent>;\r\n active = signal(0);\r\n node = signal<XContextmenuNode | null>(null);\r\n childAnimating = signal(false);\r\n isKeyboardControlled = signal(true);\r\n private unSubject = new Subject<void>();\r\n private destroyRef = inject(DestroyRef);\r\n private portalService = inject(XPortalService);\r\n private overlay = inject(Overlay);\r\n private viewContainerRef = inject(ViewContainerRef);\r\n\r\n portal!: XPortalOverlayRef<XContextmenuPortalComponent>;\r\n portalComponent = signal<ComponentRef<XContextmenuPortalComponent> | null>(null);\r\n portalOverlayRef = signal<any>(null);\r\n\r\n constructor() {\r\n effect(() => this.portalComponent()?.setInput('data', this.node()?.children));\r\n effect(() => this.portalComponent()?.setInput('level', this.level() + 1));\r\n effect(() => this.portalComponent()?.setInput('size', this.size()));\r\n effect(() => this.portalComponent()?.setInput('portalWidth', this.portalWidth()));\r\n effect(() => this.portalComponent()?.setInput('parentPortalComponent', this));\r\n\r\n this.destroyRef.onDestroy(() => {\r\n this.destroy.set(true);\r\n this.unSubject.next();\r\n this.unSubject.complete();\r\n });\r\n }\r\n\r\n ngOnInit() {\r\n this.closeSubject.subscribe(() => {\r\n this.data() && this.data()!.length > 0 && this.list().setUnActive(this.active());\r\n });\r\n\r\n this.keydownSubject.pipe(takeUntil(this.unSubject)).subscribe((x) => {\r\n if (!this.isKeyboardControlled()) return;\r\n const keyCode = x.keyCode;\r\n const isRightArrow = [RIGHT_ARROW].includes(keyCode);\r\n const isLeftArrow = [LEFT_ARROW].includes(keyCode);\r\n\r\n if (isRightArrow) {\r\n const item = this.list().keyManager.activeItem!;\r\n if (item?.leaf()) {\r\n const node = item.node()!;\r\n node.event = x;\r\n node.component = item;\r\n this.isKeyboardControlled.set(false);\r\n this.onNodeClick(node);\r\n }\r\n }\r\n\r\n if (isLeftArrow && this.level() > 0) {\r\n this.parentPortalComponent()?.isKeyboardControlled.set(true);\r\n this.parentPortalComponent()?.closePortal();\r\n }\r\n\r\n this.data() && this.data()!.length > 0 && this.list().keydown(x);\r\n });\r\n }\r\n\r\n ngAfterViewInit() {\r\n this.list().keyManager.setFirstItemActive();\r\n }\r\n\r\n onNodeClick(node: XContextmenuNode) {\r\n this.nodeClick.emit(node);\r\n\r\n // 如果有子节点,显示子菜单\r\n if (node.children && node.children.length > 0) {\r\n this.showPortal(node);\r\n } else {\r\n // 叶子节点,关闭所有菜单\r\n this.closeSubject.next();\r\n }\r\n }\r\n\r\n onActive(num: number) {\r\n this.active.set(num);\r\n }\r\n\r\n onNodeMouseenter(node: XContextmenuNode) {\r\n // 鼠标悬停时展开子菜单\r\n if (node.children && node.children.length > 0) {\r\n this.showPortal(node);\r\n }\r\n }\r\n\r\n onNodeMouseleave() {\r\n // 可以在这里添加延迟关闭逻辑\r\n }\r\n\r\n portalAttached() {\r\n return this.portalOverlayRef()?.hasAttached();\r\n }\r\n\r\n closePortal() {\r\n if (this.portalAttached()) {\r\n this.portalOverlayRef()?.dispose();\r\n return true;\r\n }\r\n return false;\r\n }\r\n\r\n createPortal() {\r\n const config: OverlayConfig = {\r\n backdropClass: '',\r\n width: this.portalWidth(),\r\n panelClass: this.portalClass(),\r\n positionStrategy: this.setPlacement(),\r\n scrollStrategy: this.overlay.scrollStrategies.reposition()\r\n };\r\n\r\n this.portal = this.portalService.attach({\r\n content: XContextmenuPortalComponent,\r\n viewContainerRef: this.viewContainerRef,\r\n overlayConfig: config\r\n });\r\n\r\n this.setInstance();\r\n }\r\n\r\n setInstance() {\r\n let { componentRef, overlayRef } = this.portal;\r\n if (!componentRef || !overlayRef) return;\r\n\r\n this.portalComponent.set(componentRef);\r\n this.portalOverlayRef.set(overlayRef);\r\n\r\n Object.assign(componentRef.instance, {\r\n closeSubject: this.closeSubject,\r\n keydownSubject: this.keydownSubject\r\n });\r\n\r\n const { closed, animating, nodeClick } = componentRef.instance;\r\n closed.subscribe(() => this.closePortal());\r\n animating.subscribe((ing: boolean) => this.childAnimating.set(ing));\r\n nodeClick.subscribe((node: XContextmenuNode) => this.nodeClick.emit(node));\r\n }\r\n\r\n setPlacement() {\r\n return this.portalService.setPlacement({\r\n elementRef: this.node()?.component?.getElementRef(),\r\n placement: ['right-start', 'right-end', 'left-start', 'left-end'],\r\n transformOriginOn: 'x-contextmenu-portal'\r\n });\r\n }\r\n\r\n showPortal(node: XContextmenuNode) {\r\n if (this.portalAttached() && this.node()?.id !== node.id) {\r\n this.portalOverlayRef()?.dispose();\r\n }\r\n this.node.set(node);\r\n if (!this.portalAttached()) {\r\n this.createPortal();\r\n }\r\n }\r\n}\r\n","<div\r\n #contextmenuPortal\r\n class=\"x-contextmenu-portal\"\r\n [style.maxHeight]=\"portalHeight() ? portalHeight() : portalMaxHeight()\"\r\n [style.height]=\"portalHeight()\"\r\n>\r\n <x-list\r\n #list\r\n [data]=\"data()\"\r\n (nodeClick)=\"onNodeClick($event)\"\r\n (keyManagerChange)=\"onActive($event)\"\r\n [inPortal]=\"true\"\r\n [size]=\"size()\"\r\n (nodeMouseenter)=\"onNodeMouseenter($event)\"\r\n (nodeMouseleave)=\"onNodeMouseleave()\"\r\n ></x-list>\r\n</div>\r\n","import {\r\n Component,\r\n ViewEncapsulation,\r\n ChangeDetectionStrategy,\r\n ViewContainerRef,\r\n inject,\r\n OnDestroy,\r\n OnInit,\r\n signal,\r\n computed,\r\n effect,\r\n ElementRef,\r\n HostListener\r\n} from '@angular/core';\r\nimport { XContextmenuPrefix, XContextmenuNode, XContextmenuProperty } from './contextmenu.property';\r\nimport { XIsEmpty, XHasChildren, XGetChildren } from '@ng-nest/ui/core';\r\nimport { Subject } from 'rxjs';\r\nimport { XPortalOverlayRef, XPortalService } from '@ng-nest/ui/portal';\r\nimport { XContextmenuPortalComponent } from './contextmenu-portal.component';\r\nimport { takeUntil } from 'rxjs/operators';\r\nimport { Overlay, OverlayConfig } from '@angular/cdk/overlay';\r\n\r\n@Component({\r\n selector: `${XContextmenuPrefix}`,\r\n imports: [],\r\n templateUrl: './contextmenu.component.html',\r\n styleUrls: ['./contextmenu.component.scss'],\r\n encapsulation: ViewEncapsulation.None,\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n standalone: true\r\n})\r\nexport class XContextmenuComponent extends XContextmenuProperty implements OnInit, OnDestroy {\r\n private unSubject = new Subject<void>();\r\n private portalService = inject(XPortalService);\r\n private viewContainerRef = inject(ViewContainerRef);\r\n private overlay = inject(Overlay);\r\n\r\n nodes = computed(() => {\r\n const data = this.data();\r\n if (!this.children()) {\r\n return data.filter((y) => XIsEmpty(y.pid)).map((y) => XGetChildren<XContextmenuNode>(data, y, 0));\r\n }\r\n return XHasChildren(data, 0);\r\n });\r\n\r\n portal!: XPortalOverlayRef<XContextmenuPortalComponent>;\r\n animating = signal(false);\r\n visibleClass = signal(false);\r\n isClickNodeLeaf = signal(false);\r\n minWidth = signal<string>('0px');\r\n closeSubject: Subject<void> = new Subject();\r\n keydownSubject: Subject<KeyboardEvent> = new Subject();\r\n\r\n private positionElement: HTMLElement | null = null;\r\n private clickPosition = signal<{ x: number; y: number } | null>(null);\r\n portalComponent = signal<any>(null);\r\n\r\n constructor() {\r\n super();\r\n effect(() => this.portalComponent()?.setInput('data', this.nodes()));\r\n effect(() => this.portalComponent()?.setInput('size', this.size()));\r\n effect(() => this.portalComponent()?.setInput('portalMaxHeight', this.portalMaxHeight()));\r\n effect(() => this.portalComponent()?.setInput('portalHeight', this.portalHeight()));\r\n effect(() => this.portalComponent()?.setInput('portalWidth', this.portalWidth()));\r\n effect(() => this.portalComponent()?.setInput('portalClass', this.portalClass()));\r\n }\r\n\r\n ngOnInit() {\r\n this.setSubject();\r\n\r\n // 监听全局键盘事件\r\n this.keydownSubject.pipe(takeUntil(this.unSubject)).subscribe((event) => {\r\n if (event.key === 'Escape') {\r\n this.closePortal();\r\n }\r\n });\r\n }\r\n\r\n ngOnDestroy(): void {\r\n this.unSubject.next();\r\n this.unSubject.complete();\r\n this.removePositionElement();\r\n }\r\n\r\n @HostListener('document:contextmenu', ['$event'])\r\n onContextmenu(event: MouseEvent) {\r\n if (this.disabled()) return;\r\n\r\n const target = this.target();\r\n if (!target) return;\r\n\r\n // 检查点击的目标是否是我们绑定的元素\r\n const targetElement = target instanceof ElementRef ? target.nativeElement : target;\r\n if (!targetElement.contains(event.target as Node)) return;\r\n\r\n // 阻止默认右键菜单\r\n event.preventDefault();\r\n\r\n // 先关闭已打开的菜单\r\n this.closePortal();\r\n\r\n // 记录点击位置\r\n this.clickPosition.set({ x: event.clientX, y: event.clientY });\r\n\r\n // 创建定位元素\r\n this.createPositionElement(event.clientX, event.clientY);\r\n\r\n // 打开菜单\r\n this.openPortal();\r\n }\r\n\r\n @HostListener('document:click')\r\n onClose() {\r\n this.closePortal();\r\n }\r\n\r\n setSubject() {\r\n this.closeSubject.pipe(takeUntil(this.unSubject)).subscribe(() => {\r\n this.closePortal();\r\n });\r\n }\r\n\r\n openPortal() {\r\n if (!this.clickPosition()) return;\r\n\r\n this.visibleClass.set(true);\r\n\r\n const config: OverlayConfig = {\r\n backdropClass: '',\r\n panelClass: this.portalClass(),\r\n width: this.portalWidth(),\r\n positionStrategy: this.createPositionStrategy(),\r\n scrollStrategy: this.overlay.scrollStrategies.reposition(),\r\n minWidth: this.minWidth()\r\n };\r\n\r\n this.portal = this.portalService.attach({\r\n content: XContextmenuPortalComponent,\r\n viewContainerRef: this.viewContainerRef,\r\n overlayConfig: config\r\n });\r\n\r\n this.setInstance();\r\n }\r\n\r\n closePortal() {\r\n if (this.portalAttached()) {\r\n this.portal.overlayRef?.dispose();\r\n this.visibleClass.set(false);\r\n this.removePositionElement();\r\n return true;\r\n }\r\n return false;\r\n }\r\n\r\n portalAttached() {\r\n return this.portal?.overlayRef?.hasAttached();\r\n }\r\n\r\n createPositionElement(x: number, y: number) {\r\n this.removePositionElement();\r\n\r\n const element = document.createElement('div');\r\n element.style.position = 'fixed';\r\n element.style.left = `${x}px`;\r\n element.style.top = `${y}px`;\r\n element.style.width = '0px';\r\n element.style.height = '0px';\r\n element.style.pointerEvents = 'none';\r\n element.className = 'x-contextmenu-position';\r\n\r\n document.body.appendChild(element);\r\n this.positionElement = element;\r\n }\r\n\r\n removePositionElement() {\r\n if (this.positionElement) {\r\n this.positionElement.remove();\r\n this.positionElement = null;\r\n }\r\n }\r\n\r\n setInstance() {\r\n let { componentRef, overlayRef } = this.portal;\r\n if (!componentRef || !overlayRef) return;\r\n\r\n this.portalComponent.set(componentRef);\r\n\r\n Object.assign(componentRef.instance, {\r\n closeSubject: this.closeSubject,\r\n keydownSubject: this.keydownSubject\r\n });\r\n\r\n const { closed, animating, nodeClick } = componentRef.instance;\r\n closed.subscribe(() => this.closeSubject.next());\r\n animating.subscribe((ing: boolean) => this.animating.set(ing));\r\n nodeClick.subscribe((node: XContextmenuNode) => {\r\n this.isClickNodeLeaf.set(node.leaf!);\r\n this.nodeClick.emit(node);\r\n });\r\n }\r\n\r\n createPositionStrategy() {\r\n const pos = this.clickPosition();\r\n if (!pos) return this.overlay.position().global();\r\n\r\n // 使用全局定位策略,直接设置位置\r\n const strategy = this.overlay.position().global();\r\n strategy.left(`${pos.x}px`);\r\n strategy.top(`${pos.y}px`);\r\n\r\n return strategy;\r\n }\r\n\r\n setPlacement() {\r\n const positionElement = this.positionElement || document.body;\r\n return this.portalService.setPlacement({\r\n elementRef: { nativeElement: positionElement } as ElementRef,\r\n placement: [this.placement(), 'bottom-start', 'bottom-end', 'bottom', 'top-start', 'top-end', 'top'],\r\n transformOriginOn: 'x-contextmenu-portal'\r\n });\r\n }\r\n}\r\n","<div class=\"x-contextmenu\" [class.x-visible]=\"visibleClass()\">\r\n <ng-content></ng-content>\r\n</div>\r\n","import { NgModule } from '@angular/core';\r\nimport { XContextmenuComponent } from './contextmenu.component';\r\n\r\n@NgModule({\r\n imports: [XContextmenuComponent],\r\n exports: [XContextmenuComponent]\r\n})\r\nexport class XContextmenuModule {}\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
|