@ng-nest/ui 21.0.10 → 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.
Files changed (82) hide show
  1. package/fesm2022/ng-nest-ui-auto-complete.mjs +11 -3
  2. package/fesm2022/ng-nest-ui-auto-complete.mjs.map +1 -1
  3. package/fesm2022/ng-nest-ui-base-form.mjs +25 -45
  4. package/fesm2022/ng-nest-ui-base-form.mjs.map +1 -1
  5. package/fesm2022/ng-nest-ui-cascade.mjs +10 -2
  6. package/fesm2022/ng-nest-ui-cascade.mjs.map +1 -1
  7. package/fesm2022/ng-nest-ui-color-picker.mjs +10 -2
  8. package/fesm2022/ng-nest-ui-color-picker.mjs.map +1 -1
  9. package/fesm2022/ng-nest-ui-contextmenu.mjs +441 -0
  10. package/fesm2022/ng-nest-ui-contextmenu.mjs.map +1 -0
  11. package/fesm2022/ng-nest-ui-core.mjs +2 -2
  12. package/fesm2022/ng-nest-ui-core.mjs.map +1 -1
  13. package/fesm2022/ng-nest-ui-date-picker.mjs +20 -4
  14. package/fesm2022/ng-nest-ui-date-picker.mjs.map +1 -1
  15. package/fesm2022/ng-nest-ui-dialog.mjs +2 -0
  16. package/fesm2022/ng-nest-ui-dialog.mjs.map +1 -1
  17. package/fesm2022/ng-nest-ui-divider.mjs +124 -0
  18. package/fesm2022/ng-nest-ui-divider.mjs.map +1 -0
  19. package/fesm2022/ng-nest-ui-dropdown.mjs +15 -3
  20. package/fesm2022/ng-nest-ui-dropdown.mjs.map +1 -1
  21. package/fesm2022/ng-nest-ui-find.mjs.map +1 -1
  22. package/fesm2022/ng-nest-ui-form.mjs +7 -12
  23. package/fesm2022/ng-nest-ui-form.mjs.map +1 -1
  24. package/fesm2022/ng-nest-ui-image.mjs +83 -44
  25. package/fesm2022/ng-nest-ui-image.mjs.map +1 -1
  26. package/fesm2022/ng-nest-ui-input-number.mjs +1 -1
  27. package/fesm2022/ng-nest-ui-input-number.mjs.map +1 -1
  28. package/fesm2022/ng-nest-ui-input.mjs +1 -3
  29. package/fesm2022/ng-nest-ui-input.mjs.map +1 -1
  30. package/fesm2022/ng-nest-ui-message-box.mjs.map +1 -1
  31. package/fesm2022/ng-nest-ui-select.mjs +50 -15
  32. package/fesm2022/ng-nest-ui-select.mjs.map +1 -1
  33. package/fesm2022/ng-nest-ui-sender.mjs +1 -1
  34. package/fesm2022/ng-nest-ui-sender.mjs.map +1 -1
  35. package/fesm2022/ng-nest-ui-splitter.mjs +407 -0
  36. package/fesm2022/ng-nest-ui-splitter.mjs.map +1 -0
  37. package/fesm2022/ng-nest-ui-textarea.mjs +1 -1
  38. package/fesm2022/ng-nest-ui-textarea.mjs.map +1 -1
  39. package/fesm2022/ng-nest-ui-time-picker.mjs +40 -21
  40. package/fesm2022/ng-nest-ui-time-picker.mjs.map +1 -1
  41. package/fesm2022/ng-nest-ui-tree-select.mjs +12 -4
  42. package/fesm2022/ng-nest-ui-tree-select.mjs.map +1 -1
  43. package/fesm2022/ng-nest-ui-watermark.mjs +378 -0
  44. package/fesm2022/ng-nest-ui-watermark.mjs.map +1 -0
  45. package/fesm2022/ng-nest-ui.mjs +4 -0
  46. package/fesm2022/ng-nest-ui.mjs.map +1 -1
  47. package/package.json +17 -1
  48. package/types/ng-nest-ui-attachments.d.ts +4 -5
  49. package/types/ng-nest-ui-auto-complete.d.ts +11 -12
  50. package/types/ng-nest-ui-base-form.d.ts +8 -9
  51. package/types/ng-nest-ui-cascade.d.ts +12 -13
  52. package/types/ng-nest-ui-checkbox.d.ts +4 -5
  53. package/types/ng-nest-ui-color-picker.d.ts +12 -13
  54. package/types/ng-nest-ui-contextmenu.d.ts +176 -0
  55. package/types/ng-nest-ui-core.d.ts +36 -1
  56. package/types/ng-nest-ui-coversations.d.ts +4 -5
  57. package/types/ng-nest-ui-date-picker.d.ts +23 -25
  58. package/types/ng-nest-ui-dialog.d.ts +12 -0
  59. package/types/ng-nest-ui-divider.d.ts +113 -0
  60. package/types/ng-nest-ui-dropdown.d.ts +12 -2
  61. package/types/ng-nest-ui-find.d.ts +6 -7
  62. package/types/ng-nest-ui-form.d.ts +9 -10
  63. package/types/ng-nest-ui-image.d.ts +2 -1
  64. package/types/ng-nest-ui-input-number.d.ts +8 -9
  65. package/types/ng-nest-ui-input.d.ts +8 -9
  66. package/types/ng-nest-ui-list.d.ts +4 -5
  67. package/types/ng-nest-ui-message-box.d.ts +2 -2
  68. package/types/ng-nest-ui-radio.d.ts +4 -5
  69. package/types/ng-nest-ui-rate.d.ts +4 -5
  70. package/types/ng-nest-ui-select.d.ts +36 -12
  71. package/types/ng-nest-ui-sender.d.ts +6 -7
  72. package/types/ng-nest-ui-slider-select.d.ts +4 -5
  73. package/types/ng-nest-ui-splitter.d.ts +163 -0
  74. package/types/ng-nest-ui-switch.d.ts +4 -5
  75. package/types/ng-nest-ui-textarea.d.ts +8 -9
  76. package/types/ng-nest-ui-theme.d.ts +4 -5
  77. package/types/ng-nest-ui-time-picker.d.ts +15 -14
  78. package/types/ng-nest-ui-transfer.d.ts +4 -5
  79. package/types/ng-nest-ui-tree-select.d.ts +12 -13
  80. package/types/ng-nest-ui-upload.d.ts +4 -5
  81. package/types/ng-nest-ui-watermark.d.ts +267 -0
  82. package/types/ng-nest-ui.d.ts +4 -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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"}
@@ -1077,8 +1077,8 @@ const X_THEME_LIGHT_COLORS = {
1077
1077
  };
1078
1078
  const X_THEME_DARK_COLORS = {
1079
1079
  text: '#dddddd',
1080
- border: '#252022',
1081
- background: '#0f0f11'
1080
+ border: '#363636',
1081
+ background: '#1e1e1e'
1082
1082
  };
1083
1083
  const X_THEME_COLORS = {
1084
1084
  primary: '#3B82F6',