@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,407 @@
|
|
|
1
|
+
import * as i0 from '@angular/core';
|
|
2
|
+
import { input, Component, signal, effect, HostBinding, ChangeDetectionStrategy, ViewEncapsulation, output, inject, ElementRef, contentChildren, ChangeDetectorRef, computed, NgModule } from '@angular/core';
|
|
3
|
+
import { XPropertyFunction } from '@ng-nest/ui/core';
|
|
4
|
+
import { DOCUMENT, CommonModule } from '@angular/common';
|
|
5
|
+
import { fromEvent, takeUntil } from 'rxjs';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Splitter
|
|
9
|
+
* @selector x-splitter
|
|
10
|
+
* @decorator component
|
|
11
|
+
*/
|
|
12
|
+
const XSplitterPrefix = 'x-splitter';
|
|
13
|
+
/**
|
|
14
|
+
* Splitter Bar
|
|
15
|
+
* @selector x-splitter-bar
|
|
16
|
+
* @decorator component
|
|
17
|
+
*/
|
|
18
|
+
const XSplitterBarPrefix = 'x-splitter-bar';
|
|
19
|
+
/**
|
|
20
|
+
* Splitter Panel
|
|
21
|
+
* @selector x-splitter-panel
|
|
22
|
+
* @decorator component
|
|
23
|
+
*/
|
|
24
|
+
const XSplitterPanelPrefix = 'x-splitter-panel';
|
|
25
|
+
const X_SPLITTER_CONFIG_NAME = 'splitter';
|
|
26
|
+
/**
|
|
27
|
+
* Splitter Property
|
|
28
|
+
*/
|
|
29
|
+
class XSplitterProperty extends XPropertyFunction(X_SPLITTER_CONFIG_NAME) {
|
|
30
|
+
constructor() {
|
|
31
|
+
super(...arguments);
|
|
32
|
+
/**
|
|
33
|
+
* @zh_CN 分割方向
|
|
34
|
+
* @en_US Split direction
|
|
35
|
+
* @example
|
|
36
|
+
*
|
|
37
|
+
* ```html
|
|
38
|
+
* <x-splitter direction="horizontal">
|
|
39
|
+
* <x-splitter-panel>Panel 1</x-splitter-panel>
|
|
40
|
+
* <x-splitter-panel>Panel 2</x-splitter-panel>
|
|
41
|
+
* </x-splitter>
|
|
42
|
+
* ```
|
|
43
|
+
*
|
|
44
|
+
*/
|
|
45
|
+
this.direction = input(this.config?.direction ?? 'horizontal', ...(ngDevMode ? [{ debugName: "direction" }] : []));
|
|
46
|
+
}
|
|
47
|
+
/** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: XSplitterProperty, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
|
|
48
|
+
/** @nocollapse */ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.1.1", type: XSplitterProperty, isStandalone: true, selector: "x-splitter-property", inputs: { direction: { classPropertyName: "direction", publicName: "direction", isSignal: true, isRequired: false, transformFunction: null } }, usesInheritance: true, ngImport: i0, template: '', isInline: true }); }
|
|
49
|
+
}
|
|
50
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: XSplitterProperty, decorators: [{
|
|
51
|
+
type: Component,
|
|
52
|
+
args: [{ selector: `${XSplitterPrefix}-property`, template: '' }]
|
|
53
|
+
}], propDecorators: { direction: [{ type: i0.Input, args: [{ isSignal: true, alias: "direction", required: false }] }] } });
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Splitter Panel
|
|
57
|
+
* @selector x-splitter-panel
|
|
58
|
+
* @decorator component
|
|
59
|
+
*/
|
|
60
|
+
class XSplitterPanelComponent {
|
|
61
|
+
constructor() {
|
|
62
|
+
this.className = XSplitterPanelPrefix;
|
|
63
|
+
/**
|
|
64
|
+
* @zh_CN 面板最小尺寸
|
|
65
|
+
* @en_US Panel minimum size
|
|
66
|
+
*/
|
|
67
|
+
this.min = input('0', ...(ngDevMode ? [{ debugName: "min" }] : []));
|
|
68
|
+
/**
|
|
69
|
+
* @zh_CN 面板最大尺寸
|
|
70
|
+
* @en_US Panel maximum size
|
|
71
|
+
*/
|
|
72
|
+
this.max = input('100%', ...(ngDevMode ? [{ debugName: "max" }] : []));
|
|
73
|
+
/**
|
|
74
|
+
* @zh_CN 面板默认尺寸
|
|
75
|
+
* @en_US Panel default size
|
|
76
|
+
*/
|
|
77
|
+
this.size = input(...(ngDevMode ? [undefined, { debugName: "size" }] : []));
|
|
78
|
+
/**
|
|
79
|
+
* @zh_CN 面板当前尺寸
|
|
80
|
+
* @en_US Panel current size
|
|
81
|
+
*/
|
|
82
|
+
this.currentSize = signal(undefined, ...(ngDevMode ? [{ debugName: "currentSize" }] : []));
|
|
83
|
+
// 监听 currentSize 变化
|
|
84
|
+
effect(() => {
|
|
85
|
+
this.currentSize();
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* @zh_CN 动态样式绑定
|
|
90
|
+
* @en_US Dynamic style binding
|
|
91
|
+
*/
|
|
92
|
+
get flexStyle() {
|
|
93
|
+
const size = this.currentSize();
|
|
94
|
+
// 如果没有设置尺寸,使用 flex: 1 让面板自动分配空间
|
|
95
|
+
return size ? `0 0 ${size}` : '1 1 auto';
|
|
96
|
+
}
|
|
97
|
+
/** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: XSplitterPanelComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
98
|
+
/** @nocollapse */ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.1.1", type: XSplitterPanelComponent, isStandalone: true, selector: "x-splitter-panel", inputs: { min: { classPropertyName: "min", publicName: "min", isSignal: true, isRequired: false, transformFunction: null }, max: { classPropertyName: "max", publicName: "max", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class": "this.className", "style.flex": "this.flexStyle" } }, ngImport: i0, template: '<ng-content></ng-content>', isInline: true, styles: [".x-splitter-panel{overflow:hidden;flex-shrink:0;min-width:0;min-height:0}.x-splitter-panel>x-splitter{width:100%;height:100%}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
|
|
99
|
+
}
|
|
100
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: XSplitterPanelComponent, decorators: [{
|
|
101
|
+
type: Component,
|
|
102
|
+
args: [{ selector: `${XSplitterPanelPrefix}`, template: '<ng-content></ng-content>', encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, styles: [".x-splitter-panel{overflow:hidden;flex-shrink:0;min-width:0;min-height:0}.x-splitter-panel>x-splitter{width:100%;height:100%}\n"] }]
|
|
103
|
+
}], ctorParameters: () => [], propDecorators: { className: [{
|
|
104
|
+
type: HostBinding,
|
|
105
|
+
args: ['class']
|
|
106
|
+
}], min: [{ type: i0.Input, args: [{ isSignal: true, alias: "min", required: false }] }], max: [{ type: i0.Input, args: [{ isSignal: true, alias: "max", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], flexStyle: [{
|
|
107
|
+
type: HostBinding,
|
|
108
|
+
args: ['style.flex']
|
|
109
|
+
}] } });
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Splitter Bar
|
|
113
|
+
* @selector x-splitter-bar
|
|
114
|
+
* @decorator component
|
|
115
|
+
*/
|
|
116
|
+
class XSplitterBarComponent {
|
|
117
|
+
constructor() {
|
|
118
|
+
this.className = XSplitterBarPrefix;
|
|
119
|
+
/**
|
|
120
|
+
* @zh_CN 拖动开始事件
|
|
121
|
+
* @en_US Drag start event
|
|
122
|
+
*/
|
|
123
|
+
this.dragStart = output();
|
|
124
|
+
/**
|
|
125
|
+
* @zh_CN 拖动中事件
|
|
126
|
+
* @en_US Dragging event
|
|
127
|
+
*/
|
|
128
|
+
this.dragging = output();
|
|
129
|
+
/**
|
|
130
|
+
* @zh_CN 拖动结束事件
|
|
131
|
+
* @en_US Drag end event
|
|
132
|
+
*/
|
|
133
|
+
this.dragEnd = output();
|
|
134
|
+
this.document = inject(DOCUMENT);
|
|
135
|
+
this.elementRef = inject(ElementRef);
|
|
136
|
+
}
|
|
137
|
+
ngAfterViewInit() {
|
|
138
|
+
this.initDrag();
|
|
139
|
+
}
|
|
140
|
+
initDrag() {
|
|
141
|
+
const element = this.elementRef.nativeElement;
|
|
142
|
+
element.addEventListener('mousedown', (event) => {
|
|
143
|
+
event.preventDefault();
|
|
144
|
+
event.stopPropagation();
|
|
145
|
+
this.dragStart.emit(event);
|
|
146
|
+
const mouseMoveSub = fromEvent(this.document, 'mousemove')
|
|
147
|
+
.pipe(takeUntil(fromEvent(this.document, 'mouseup')))
|
|
148
|
+
.subscribe((moveEvent) => {
|
|
149
|
+
this.dragging.emit(moveEvent);
|
|
150
|
+
});
|
|
151
|
+
fromEvent(this.document, 'mouseup').subscribe((upEvent) => {
|
|
152
|
+
this.dragEnd.emit(upEvent);
|
|
153
|
+
mouseMoveSub.unsubscribe();
|
|
154
|
+
});
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
/** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: XSplitterBarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
158
|
+
/** @nocollapse */ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.1.1", type: XSplitterBarComponent, isStandalone: true, selector: "x-splitter-bar", outputs: { dragStart: "dragStart", dragging: "dragging", dragEnd: "dragEnd" }, host: { properties: { "class": "this.className" } }, ngImport: i0, template: '', isInline: true, styles: [".x-splitter-bar{display:block;box-sizing:border-box}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
|
|
159
|
+
}
|
|
160
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: XSplitterBarComponent, decorators: [{
|
|
161
|
+
type: Component,
|
|
162
|
+
args: [{ selector: `${XSplitterBarPrefix}`, template: '', encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, styles: [".x-splitter-bar{display:block;box-sizing:border-box}\n"] }]
|
|
163
|
+
}], propDecorators: { className: [{
|
|
164
|
+
type: HostBinding,
|
|
165
|
+
args: ['class']
|
|
166
|
+
}], dragStart: [{ type: i0.Output, args: ["dragStart"] }], dragging: [{ type: i0.Output, args: ["dragging"] }], dragEnd: [{ type: i0.Output, args: ["dragEnd"] }] } });
|
|
167
|
+
|
|
168
|
+
class XSplitterComponent extends XSplitterProperty {
|
|
169
|
+
constructor() {
|
|
170
|
+
super(...arguments);
|
|
171
|
+
this.panels = contentChildren(XSplitterPanelComponent, ...(ngDevMode ? [{ debugName: "panels" }] : []));
|
|
172
|
+
this.bars = contentChildren(XSplitterBarComponent, ...(ngDevMode ? [{ debugName: "bars" }] : []));
|
|
173
|
+
this.elementRef = inject(ElementRef);
|
|
174
|
+
this.cdr = inject(ChangeDetectorRef);
|
|
175
|
+
// 缓存 splitter 的尺寸信息,避免频繁调用 getBoundingClientRect
|
|
176
|
+
this.cachedSplitterRect = null;
|
|
177
|
+
this.cachedBarSize = null;
|
|
178
|
+
// 用于 requestAnimationFrame 的 ID,避免重复调度
|
|
179
|
+
this.rafId = null;
|
|
180
|
+
/**
|
|
181
|
+
* @zh_CN 类名映射
|
|
182
|
+
* @en_US Class map
|
|
183
|
+
*/
|
|
184
|
+
this.classMap = computed(() => ({
|
|
185
|
+
[`${XSplitterPrefix}-${this.direction()}`]: true
|
|
186
|
+
}), ...(ngDevMode ? [{ debugName: "classMap" }] : []));
|
|
187
|
+
}
|
|
188
|
+
ngAfterContentInit() {
|
|
189
|
+
this.initBars();
|
|
190
|
+
this.initPanelSizes();
|
|
191
|
+
}
|
|
192
|
+
initPanelSizes() {
|
|
193
|
+
const panels = this.panels();
|
|
194
|
+
panels.forEach((panel) => {
|
|
195
|
+
const size = panel.size();
|
|
196
|
+
if (size !== undefined && size !== null) {
|
|
197
|
+
// 直接使用原始尺寸值,不转换
|
|
198
|
+
panel.currentSize.set(size);
|
|
199
|
+
}
|
|
200
|
+
});
|
|
201
|
+
}
|
|
202
|
+
initBars() {
|
|
203
|
+
const barComponents = this.bars();
|
|
204
|
+
barComponents.forEach((bar, index) => {
|
|
205
|
+
bar.dragStart.subscribe(() => this.onDragStart(index));
|
|
206
|
+
bar.dragging.subscribe((event) => this.onDragging(index, event));
|
|
207
|
+
bar.dragEnd.subscribe(() => this.onDragEnd(index));
|
|
208
|
+
});
|
|
209
|
+
}
|
|
210
|
+
onDragStart(_barIndex) {
|
|
211
|
+
// 缓存 splitter 的尺寸和 bar 的大小,避免在拖动过程中重复计算
|
|
212
|
+
this.cachedSplitterRect = this.elementRef.nativeElement.getBoundingClientRect();
|
|
213
|
+
this.cachedBarSize = this.getBarSize();
|
|
214
|
+
}
|
|
215
|
+
onDragging(barIndex, event) {
|
|
216
|
+
// 取消之前的动画帧请求,避免累积
|
|
217
|
+
if (this.rafId !== null) {
|
|
218
|
+
cancelAnimationFrame(this.rafId);
|
|
219
|
+
}
|
|
220
|
+
// 使用 requestAnimationFrame 确保在下一帧更新,避免闪动
|
|
221
|
+
this.rafId = requestAnimationFrame(() => {
|
|
222
|
+
this.rafId = null;
|
|
223
|
+
this.updatePanelSizes(barIndex, event);
|
|
224
|
+
});
|
|
225
|
+
}
|
|
226
|
+
updatePanelSizes(barIndex, event) {
|
|
227
|
+
const panelElements = this.elementRef.nativeElement.querySelectorAll('x-splitter-panel');
|
|
228
|
+
if (panelElements.length < 2)
|
|
229
|
+
return;
|
|
230
|
+
// 获取 panel 组件实例
|
|
231
|
+
const panels = this.panels();
|
|
232
|
+
if (panels.length < 2)
|
|
233
|
+
return;
|
|
234
|
+
const prevPanel = panels[barIndex];
|
|
235
|
+
const nextPanel = panels[barIndex + 1];
|
|
236
|
+
if (!prevPanel || !nextPanel)
|
|
237
|
+
return;
|
|
238
|
+
// 使用缓存的尺寸信息,提高性能
|
|
239
|
+
const splitterRect = this.cachedSplitterRect || this.elementRef.nativeElement.getBoundingClientRect();
|
|
240
|
+
const isHorizontal = this.direction() === 'horizontal';
|
|
241
|
+
// 获取鼠标位置相对于 splitter 的位置
|
|
242
|
+
const position = isHorizontal ? event.clientX - splitterRect.left : event.clientY - splitterRect.top;
|
|
243
|
+
// 获取 splitter 的总尺寸
|
|
244
|
+
const totalSize = isHorizontal ? splitterRect.width : splitterRect.height;
|
|
245
|
+
// 计算前一个面板的新尺寸(像素)
|
|
246
|
+
let newSizePx = position;
|
|
247
|
+
// 应用最小和最大限制(转换为像素)
|
|
248
|
+
const minSizePx = this.parseSizeToPx(prevPanel.min(), totalSize);
|
|
249
|
+
const maxSizePx = this.parseSizeToPx(prevPanel.max(), totalSize);
|
|
250
|
+
newSizePx = Math.max(minSizePx, Math.min(maxSizePx, newSizePx));
|
|
251
|
+
// 确保后一个面板也有最小限制
|
|
252
|
+
const remainingPx = totalSize - newSizePx;
|
|
253
|
+
const nextMinSizePx = this.parseSizeToPx(nextPanel.min(), totalSize);
|
|
254
|
+
const nextMaxSizePx = this.parseSizeToPx(nextPanel.max(), totalSize);
|
|
255
|
+
if (remainingPx < nextMinSizePx) {
|
|
256
|
+
newSizePx = totalSize - nextMinSizePx;
|
|
257
|
+
}
|
|
258
|
+
else if (remainingPx > nextMaxSizePx) {
|
|
259
|
+
newSizePx = totalSize - nextMaxSizePx;
|
|
260
|
+
}
|
|
261
|
+
// 确保不会把 bar 挤出可见区域
|
|
262
|
+
// bar 需要占据一定的空间,所以要为 bar 预留空间
|
|
263
|
+
const barSize = this.cachedBarSize || this.getBarSize();
|
|
264
|
+
// 前一个面板 + bar + 后一个面板 <= totalSize
|
|
265
|
+
// 所以:newSizePx + barSize + nextMinSizePx <= totalSize
|
|
266
|
+
if (newSizePx + barSize + nextMinSizePx > totalSize) {
|
|
267
|
+
newSizePx = totalSize - barSize - nextMinSizePx;
|
|
268
|
+
}
|
|
269
|
+
// 同时确保前一个面板不小于其最小值
|
|
270
|
+
newSizePx = Math.max(minSizePx, newSizePx);
|
|
271
|
+
// 检查原始尺寸是否是固定单位
|
|
272
|
+
const prevOriginalSize = prevPanel.size();
|
|
273
|
+
const prevIsFixedSize = prevOriginalSize && typeof prevOriginalSize === 'string' && !prevOriginalSize.endsWith('%');
|
|
274
|
+
// 更新前一个面板的尺寸
|
|
275
|
+
if (prevIsFixedSize) {
|
|
276
|
+
// 如果前一个面板是固定单位,使用像素值
|
|
277
|
+
prevPanel.currentSize.set(`${Math.round(newSizePx)}px`);
|
|
278
|
+
}
|
|
279
|
+
else {
|
|
280
|
+
// 如果前一个面板是百分比或数字,使用百分比
|
|
281
|
+
const newSizePercent = (newSizePx / totalSize) * 100;
|
|
282
|
+
prevPanel.currentSize.set(`${newSizePercent}%`);
|
|
283
|
+
}
|
|
284
|
+
// 关键修复:对于后面的所有 panel,需要保持它们的实际像素尺寸不变
|
|
285
|
+
// 获取后面所有 panel 的当前实际尺寸
|
|
286
|
+
const remainingPanels = panels.slice(barIndex + 1);
|
|
287
|
+
const barCount = remainingPanels.length - 1; // bar 的数量比 panel 少 1
|
|
288
|
+
const totalBarSize = barCount * barSize;
|
|
289
|
+
// 计算剩余空间
|
|
290
|
+
const remainingSpace = totalSize - newSizePx - totalBarSize;
|
|
291
|
+
// 首先获取每个 panel 的当前实际像素尺寸(在修改之前)
|
|
292
|
+
const currentSizes = [];
|
|
293
|
+
let totalCurrentSize = 0;
|
|
294
|
+
remainingPanels.forEach((panel) => {
|
|
295
|
+
const panelElement = panelElements[panels.indexOf(panel)];
|
|
296
|
+
const computedSize = isHorizontal ? panelElement.offsetWidth : panelElement.offsetHeight;
|
|
297
|
+
currentSizes.push(computedSize);
|
|
298
|
+
totalCurrentSize += computedSize;
|
|
299
|
+
});
|
|
300
|
+
// 如果只有一个后续 panel,直接设置它的尺寸为剩余空间
|
|
301
|
+
if (remainingPanels.length === 1) {
|
|
302
|
+
const panel = remainingPanels[0];
|
|
303
|
+
// 始终使用像素值,确保尺寸固定
|
|
304
|
+
panel.currentSize.set(`${Math.round(remainingSpace)}px`);
|
|
305
|
+
}
|
|
306
|
+
else {
|
|
307
|
+
// 如果有多个后续 panel,按当前尺寸的比例分配剩余空间
|
|
308
|
+
remainingPanels.forEach((panel, index) => {
|
|
309
|
+
if (totalCurrentSize > 0) {
|
|
310
|
+
// 按当前尺寸的比例分配
|
|
311
|
+
const ratio = currentSizes[index] / totalCurrentSize;
|
|
312
|
+
const newSize = remainingSpace * ratio;
|
|
313
|
+
// 始终使用像素值,确保尺寸固定
|
|
314
|
+
panel.currentSize.set(`${Math.round(newSize)}px`);
|
|
315
|
+
}
|
|
316
|
+
else {
|
|
317
|
+
// 如果没有当前尺寸,平均分配
|
|
318
|
+
const avgSize = remainingSpace / remainingPanels.length;
|
|
319
|
+
panel.currentSize.set(`${Math.round(avgSize)}px`);
|
|
320
|
+
}
|
|
321
|
+
});
|
|
322
|
+
}
|
|
323
|
+
// 手动触发变更检测
|
|
324
|
+
this.cdr.markForCheck();
|
|
325
|
+
}
|
|
326
|
+
onDragEnd(_barIndex) {
|
|
327
|
+
// 取消未完成的动画帧
|
|
328
|
+
if (this.rafId !== null) {
|
|
329
|
+
cancelAnimationFrame(this.rafId);
|
|
330
|
+
this.rafId = null;
|
|
331
|
+
}
|
|
332
|
+
// 清除缓存
|
|
333
|
+
this.cachedSplitterRect = null;
|
|
334
|
+
this.cachedBarSize = null;
|
|
335
|
+
}
|
|
336
|
+
/**
|
|
337
|
+
* @zh_CN 将尺寸值转换为像素
|
|
338
|
+
* @en_US Convert size value to pixels
|
|
339
|
+
*/
|
|
340
|
+
parseSizeToPx(size, totalSize) {
|
|
341
|
+
if (typeof size === 'number') {
|
|
342
|
+
// 数字默认当作像素
|
|
343
|
+
return size;
|
|
344
|
+
}
|
|
345
|
+
if (size.endsWith('%')) {
|
|
346
|
+
const percent = parseFloat(size);
|
|
347
|
+
return (percent / 100) * totalSize;
|
|
348
|
+
}
|
|
349
|
+
if (size.endsWith('px')) {
|
|
350
|
+
return parseFloat(size);
|
|
351
|
+
}
|
|
352
|
+
if (size.endsWith('rem')) {
|
|
353
|
+
const remValue = parseFloat(size);
|
|
354
|
+
// 获取根元素的字体大小(默认 16px)
|
|
355
|
+
const rootFontSize = parseFloat(getComputedStyle(document.documentElement).fontSize) || 16;
|
|
356
|
+
return remValue * rootFontSize;
|
|
357
|
+
}
|
|
358
|
+
if (size.endsWith('em')) {
|
|
359
|
+
const emValue = parseFloat(size);
|
|
360
|
+
// 获取父元素的字体大小(这里使用 splitter 的字体大小)
|
|
361
|
+
const parentFontSize = parseFloat(getComputedStyle(this.elementRef.nativeElement).fontSize) || 16;
|
|
362
|
+
return emValue * parentFontSize;
|
|
363
|
+
}
|
|
364
|
+
// 默认当作像素处理
|
|
365
|
+
return parseFloat(size) || 0;
|
|
366
|
+
}
|
|
367
|
+
/**
|
|
368
|
+
* @zh_CN 获取 bar 的尺寸(像素)
|
|
369
|
+
* @en_US Get bar size in pixels
|
|
370
|
+
*/
|
|
371
|
+
getBarSize() {
|
|
372
|
+
const barElement = this.elementRef.nativeElement.querySelector('.x-splitter-bar');
|
|
373
|
+
if (barElement) {
|
|
374
|
+
const computedStyle = getComputedStyle(barElement);
|
|
375
|
+
const isHorizontal = this.direction() === 'horizontal';
|
|
376
|
+
const size = isHorizontal ? computedStyle.width : computedStyle.height;
|
|
377
|
+
return parseFloat(size) || 4; // 默认 4px
|
|
378
|
+
}
|
|
379
|
+
return 4; // 默认值
|
|
380
|
+
}
|
|
381
|
+
/** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: XSplitterComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
|
|
382
|
+
/** @nocollapse */ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "21.1.1", type: XSplitterComponent, isStandalone: true, selector: "x-splitter", queries: [{ propertyName: "panels", predicate: XSplitterPanelComponent, isSignal: true }, { propertyName: "bars", predicate: XSplitterBarComponent, isSignal: true }], usesInheritance: true, ngImport: i0, template: "<div class=\"x-splitter\" [class]=\"classMap()\">\r\n <ng-content></ng-content>\r\n</div>\r\n", styles: [".x-splitter{margin:0;padding:0}.x-splitter{display:flex;width:100%;height:100%}.x-splitter-horizontal{flex-direction:row}.x-splitter-horizontal>.x-splitter-panel{height:100%}.x-splitter-horizontal>.x-splitter-bar{width:var(--x-splitter-bar-size, 4px);height:100%;cursor:col-resize;flex-shrink:0}.x-splitter-vertical{flex-direction:column}.x-splitter-vertical>.x-splitter-panel{width:100%}.x-splitter-vertical>.x-splitter-bar{width:100%;height:var(--x-splitter-bar-size, 4px);cursor:row-resize;flex-shrink:0}.x-splitter-bar{position:relative;background-color:var(--x-splitter-bar-color, var(--x-border));transition:background-color .2s;z-index:1}.x-splitter-bar:hover,.x-splitter-bar:active{background-color:var(--x-splitter-bar-hover-color, var(--x-primary))}.x-splitter-bar:before{content:\"\";position:absolute;top:50%;left:50%;transform:translate(-50%,-50%)}.x-splitter-horizontal .x-splitter-bar:before{width:.125rem;height:1.25rem;background-color:#ffffff80}.x-splitter-vertical .x-splitter-bar:before{width:.125rem;height:.125rem;background-color:#ffffff80}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
|
|
383
|
+
}
|
|
384
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: XSplitterComponent, decorators: [{
|
|
385
|
+
type: Component,
|
|
386
|
+
args: [{ selector: `${XSplitterPrefix}`, imports: [CommonModule], encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"x-splitter\" [class]=\"classMap()\">\r\n <ng-content></ng-content>\r\n</div>\r\n", styles: [".x-splitter{margin:0;padding:0}.x-splitter{display:flex;width:100%;height:100%}.x-splitter-horizontal{flex-direction:row}.x-splitter-horizontal>.x-splitter-panel{height:100%}.x-splitter-horizontal>.x-splitter-bar{width:var(--x-splitter-bar-size, 4px);height:100%;cursor:col-resize;flex-shrink:0}.x-splitter-vertical{flex-direction:column}.x-splitter-vertical>.x-splitter-panel{width:100%}.x-splitter-vertical>.x-splitter-bar{width:100%;height:var(--x-splitter-bar-size, 4px);cursor:row-resize;flex-shrink:0}.x-splitter-bar{position:relative;background-color:var(--x-splitter-bar-color, var(--x-border));transition:background-color .2s;z-index:1}.x-splitter-bar:hover,.x-splitter-bar:active{background-color:var(--x-splitter-bar-hover-color, var(--x-primary))}.x-splitter-bar:before{content:\"\";position:absolute;top:50%;left:50%;transform:translate(-50%,-50%)}.x-splitter-horizontal .x-splitter-bar:before{width:.125rem;height:1.25rem;background-color:#ffffff80}.x-splitter-vertical .x-splitter-bar:before{width:.125rem;height:.125rem;background-color:#ffffff80}\n"] }]
|
|
387
|
+
}], propDecorators: { panels: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => XSplitterPanelComponent), { isSignal: true }] }], bars: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => XSplitterBarComponent), { isSignal: true }] }] } });
|
|
388
|
+
|
|
389
|
+
class XSplitterModule {
|
|
390
|
+
/** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: XSplitterModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
|
|
391
|
+
/** @nocollapse */ static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "21.1.1", ngImport: i0, type: XSplitterModule, imports: [XSplitterComponent, XSplitterPanelComponent, XSplitterBarComponent], exports: [XSplitterComponent, XSplitterPanelComponent, XSplitterBarComponent] }); }
|
|
392
|
+
/** @nocollapse */ static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: XSplitterModule, imports: [XSplitterComponent] }); }
|
|
393
|
+
}
|
|
394
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: XSplitterModule, decorators: [{
|
|
395
|
+
type: NgModule,
|
|
396
|
+
args: [{
|
|
397
|
+
imports: [XSplitterComponent, XSplitterPanelComponent, XSplitterBarComponent],
|
|
398
|
+
exports: [XSplitterComponent, XSplitterPanelComponent, XSplitterBarComponent]
|
|
399
|
+
}]
|
|
400
|
+
}] });
|
|
401
|
+
|
|
402
|
+
/**
|
|
403
|
+
* Generated bundle index. Do not edit.
|
|
404
|
+
*/
|
|
405
|
+
|
|
406
|
+
export { XSplitterBarComponent, XSplitterBarPrefix, XSplitterComponent, XSplitterModule, XSplitterPanelComponent, XSplitterPanelPrefix, XSplitterPrefix, XSplitterProperty };
|
|
407
|
+
//# sourceMappingURL=ng-nest-ui-splitter.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ng-nest-ui-splitter.mjs","sources":["../../../../lib/ng-nest/ui/splitter/splitter.property.ts","../../../../lib/ng-nest/ui/splitter/splitter-panel.component.ts","../../../../lib/ng-nest/ui/splitter/splitter-bar.component.ts","../../../../lib/ng-nest/ui/splitter/splitter.component.ts","../../../../lib/ng-nest/ui/splitter/splitter.component.html","../../../../lib/ng-nest/ui/splitter/splitter.module.ts","../../../../lib/ng-nest/ui/splitter/ng-nest-ui-splitter.ts"],"sourcesContent":["import { Component, input } from '@angular/core';\r\nimport { XPropertyFunction } from '@ng-nest/ui/core';\r\n\r\n/**\r\n * Splitter\r\n * @selector x-splitter\r\n * @decorator component\r\n */\r\nexport const XSplitterPrefix = 'x-splitter';\r\n\r\n/**\r\n * Splitter Bar\r\n * @selector x-splitter-bar\r\n * @decorator component\r\n */\r\nexport const XSplitterBarPrefix = 'x-splitter-bar';\r\n\r\n/**\r\n * Splitter Panel\r\n * @selector x-splitter-panel\r\n * @decorator component\r\n */\r\nexport const XSplitterPanelPrefix = 'x-splitter-panel';\r\n\r\nconst X_SPLITTER_CONFIG_NAME = 'splitter';\r\n\r\n/**\r\n * Splitter Property\r\n */\r\n@Component({ selector: `${XSplitterPrefix}-property`, template: '' })\r\nexport class XSplitterProperty extends XPropertyFunction(X_SPLITTER_CONFIG_NAME) {\r\n /**\r\n * @zh_CN 分割方向\r\n * @en_US Split direction\r\n * @example\r\n *\r\n * ```html\r\n * <x-splitter direction=\"horizontal\">\r\n * <x-splitter-panel>Panel 1</x-splitter-panel>\r\n * <x-splitter-panel>Panel 2</x-splitter-panel>\r\n * </x-splitter>\r\n * ```\r\n *\r\n */\r\n readonly direction = input<XSplitterDirection>(this.config?.direction ?? 'horizontal');\r\n}\r\n\r\n/**\r\n * @zh_CN 分割方向\r\n * @en_US Split direction\r\n */\r\nexport type XSplitterDirection = 'horizontal' | 'vertical';\r\n","import { Component, ViewEncapsulation, ChangeDetectionStrategy, input, signal, HostBinding, effect } from '@angular/core';\r\nimport { XSplitterPanelPrefix } from './splitter.property';\r\n\r\n/**\r\n * Splitter Panel\r\n * @selector x-splitter-panel\r\n * @decorator component\r\n */\r\n@Component({\r\n selector: `${XSplitterPanelPrefix}`,\r\n template: '<ng-content></ng-content>',\r\n styleUrls: ['./splitter-panel.component.scss'],\r\n encapsulation: ViewEncapsulation.None,\r\n changeDetection: ChangeDetectionStrategy.OnPush\r\n})\r\nexport class XSplitterPanelComponent {\r\n @HostBinding('class') className = XSplitterPanelPrefix;\r\n \r\n /**\r\n * @zh_CN 面板最小尺寸\r\n * @en_US Panel minimum size\r\n */\r\n readonly min = input<string | number>('0');\r\n\r\n /**\r\n * @zh_CN 面板最大尺寸\r\n * @en_US Panel maximum size\r\n */\r\n readonly max = input<string | number>('100%');\r\n\r\n /**\r\n * @zh_CN 面板默认尺寸\r\n * @en_US Panel default size\r\n */\r\n readonly size = input<string | number>();\r\n\r\n /**\r\n * @zh_CN 面板当前尺寸\r\n * @en_US Panel current size\r\n */\r\n readonly currentSize = signal<string | number | undefined>(undefined);\r\n \r\n constructor() {\r\n // 监听 currentSize 变化\r\n effect(() => {\r\n this.currentSize();\r\n });\r\n }\r\n\r\n /**\r\n * @zh_CN 动态样式绑定\r\n * @en_US Dynamic style binding\r\n */\r\n @HostBinding('style.flex')\r\n get flexStyle() {\r\n const size = this.currentSize();\r\n // 如果没有设置尺寸,使用 flex: 1 让面板自动分配空间\r\n return size ? `0 0 ${size}` : '1 1 auto';\r\n }\r\n}\r\n","import { Component, ViewEncapsulation, ChangeDetectionStrategy, inject, ElementRef, output, HostBinding } from '@angular/core';\r\nimport { DOCUMENT } from '@angular/common';\r\nimport { fromEvent, takeUntil } from 'rxjs';\r\nimport { XSplitterBarPrefix } from './splitter.property';\r\n\r\n/**\r\n * Splitter Bar\r\n * @selector x-splitter-bar\r\n * @decorator component\r\n */\r\n@Component({\r\n selector: `${XSplitterBarPrefix}`,\r\n template: '',\r\n styleUrls: ['./splitter-bar.component.scss'],\r\n encapsulation: ViewEncapsulation.None,\r\n changeDetection: ChangeDetectionStrategy.OnPush\r\n})\r\nexport class XSplitterBarComponent {\r\n @HostBinding('class') className = XSplitterBarPrefix;\r\n\r\n /**\r\n * @zh_CN 拖动开始事件\r\n * @en_US Drag start event\r\n */\r\n readonly dragStart = output<MouseEvent>();\r\n\r\n /**\r\n * @zh_CN 拖动中事件\r\n * @en_US Dragging event\r\n */\r\n readonly dragging = output<MouseEvent>();\r\n\r\n /**\r\n * @zh_CN 拖动结束事件\r\n * @en_US Drag end event\r\n */\r\n readonly dragEnd = output<MouseEvent>();\r\n\r\n private document = inject(DOCUMENT);\r\n private elementRef = inject(ElementRef);\r\n\r\n ngAfterViewInit() {\r\n this.initDrag();\r\n }\r\n\r\n private initDrag() {\r\n const element = this.elementRef.nativeElement;\r\n\r\n element.addEventListener('mousedown', (event: MouseEvent) => {\r\n event.preventDefault();\r\n event.stopPropagation();\r\n this.dragStart.emit(event);\r\n\r\n const mouseMoveSub = fromEvent(this.document, 'mousemove')\r\n .pipe(takeUntil(fromEvent(this.document, 'mouseup')))\r\n .subscribe((moveEvent: Event) => {\r\n this.dragging.emit(moveEvent as MouseEvent);\r\n });\r\n\r\n fromEvent(this.document, 'mouseup').subscribe((upEvent: Event) => {\r\n this.dragEnd.emit(upEvent as MouseEvent);\r\n mouseMoveSub.unsubscribe();\r\n });\r\n });\r\n }\r\n}\r\n","import {\r\n Component,\r\n ViewEncapsulation,\r\n ChangeDetectionStrategy,\r\n computed,\r\n contentChildren,\r\n AfterContentInit,\r\n ElementRef,\r\n inject,\r\n ChangeDetectorRef\r\n} from '@angular/core';\r\nimport { XSplitterPrefix, XSplitterProperty } from './splitter.property';\r\nimport { XSplitterPanelComponent } from './splitter-panel.component';\r\nimport { XSplitterBarComponent } from './splitter-bar.component';\r\nimport { CommonModule } from '@angular/common';\r\n\r\n@Component({\r\n selector: `${XSplitterPrefix}`,\r\n imports: [CommonModule],\r\n templateUrl: './splitter.component.html',\r\n styleUrls: ['./splitter.component.scss'],\r\n encapsulation: ViewEncapsulation.None,\r\n changeDetection: ChangeDetectionStrategy.OnPush\r\n})\r\nexport class XSplitterComponent extends XSplitterProperty implements AfterContentInit {\r\n panels = contentChildren(XSplitterPanelComponent);\r\n bars = contentChildren(XSplitterBarComponent);\r\n private elementRef = inject(ElementRef);\r\n private cdr = inject(ChangeDetectorRef);\r\n\r\n // 缓存 splitter 的尺寸信息,避免频繁调用 getBoundingClientRect\r\n private cachedSplitterRect: DOMRect | null = null;\r\n private cachedBarSize: number | null = null;\r\n\r\n // 用于 requestAnimationFrame 的 ID,避免重复调度\r\n private rafId: number | null = null;\r\n\r\n /**\r\n * @zh_CN 类名映射\r\n * @en_US Class map\r\n */\r\n classMap = computed(() => ({\r\n [`${XSplitterPrefix}-${this.direction()}`]: true\r\n }));\r\n\r\n ngAfterContentInit() {\r\n this.initBars();\r\n this.initPanelSizes();\r\n }\r\n\r\n private initPanelSizes() {\r\n const panels = this.panels();\r\n\r\n panels.forEach((panel) => {\r\n const size = panel.size();\r\n if (size !== undefined && size !== null) {\r\n // 直接使用原始尺寸值,不转换\r\n panel.currentSize.set(size);\r\n }\r\n });\r\n }\r\n\r\n private initBars() {\r\n const barComponents = this.bars();\r\n barComponents.forEach((bar, index) => {\r\n bar.dragStart.subscribe(() => this.onDragStart(index));\r\n bar.dragging.subscribe((event) => this.onDragging(index, event));\r\n bar.dragEnd.subscribe(() => this.onDragEnd(index));\r\n });\r\n }\r\n\r\n private onDragStart(_barIndex: number) {\r\n // 缓存 splitter 的尺寸和 bar 的大小,避免在拖动过程中重复计算\r\n this.cachedSplitterRect = this.elementRef.nativeElement.getBoundingClientRect();\r\n this.cachedBarSize = this.getBarSize();\r\n }\r\n\r\n private onDragging(barIndex: number, event: MouseEvent) {\r\n // 取消之前的动画帧请求,避免累积\r\n if (this.rafId !== null) {\r\n cancelAnimationFrame(this.rafId);\r\n }\r\n\r\n // 使用 requestAnimationFrame 确保在下一帧更新,避免闪动\r\n this.rafId = requestAnimationFrame(() => {\r\n this.rafId = null;\r\n this.updatePanelSizes(barIndex, event);\r\n });\r\n }\r\n\r\n private updatePanelSizes(barIndex: number, event: MouseEvent) {\r\n const panelElements = this.elementRef.nativeElement.querySelectorAll('x-splitter-panel');\r\n if (panelElements.length < 2) return;\r\n\r\n // 获取 panel 组件实例\r\n const panels = this.panels();\r\n if (panels.length < 2) return;\r\n\r\n const prevPanel = panels[barIndex];\r\n const nextPanel = panels[barIndex + 1];\r\n\r\n if (!prevPanel || !nextPanel) return;\r\n\r\n // 使用缓存的尺寸信息,提高性能\r\n const splitterRect = this.cachedSplitterRect || this.elementRef.nativeElement.getBoundingClientRect();\r\n const isHorizontal = this.direction() === 'horizontal';\r\n\r\n // 获取鼠标位置相对于 splitter 的位置\r\n const position = isHorizontal ? event.clientX - splitterRect.left : event.clientY - splitterRect.top;\r\n\r\n // 获取 splitter 的总尺寸\r\n const totalSize = isHorizontal ? splitterRect.width : splitterRect.height;\r\n\r\n // 计算前一个面板的新尺寸(像素)\r\n let newSizePx = position;\r\n\r\n // 应用最小和最大限制(转换为像素)\r\n const minSizePx = this.parseSizeToPx(prevPanel.min(), totalSize);\r\n const maxSizePx = this.parseSizeToPx(prevPanel.max(), totalSize);\r\n newSizePx = Math.max(minSizePx, Math.min(maxSizePx, newSizePx));\r\n\r\n // 确保后一个面板也有最小限制\r\n const remainingPx = totalSize - newSizePx;\r\n const nextMinSizePx = this.parseSizeToPx(nextPanel.min(), totalSize);\r\n const nextMaxSizePx = this.parseSizeToPx(nextPanel.max(), totalSize);\r\n\r\n if (remainingPx < nextMinSizePx) {\r\n newSizePx = totalSize - nextMinSizePx;\r\n } else if (remainingPx > nextMaxSizePx) {\r\n newSizePx = totalSize - nextMaxSizePx;\r\n }\r\n\r\n // 确保不会把 bar 挤出可见区域\r\n // bar 需要占据一定的空间,所以要为 bar 预留空间\r\n const barSize = this.cachedBarSize || this.getBarSize();\r\n // 前一个面板 + bar + 后一个面板 <= totalSize\r\n // 所以:newSizePx + barSize + nextMinSizePx <= totalSize\r\n if (newSizePx + barSize + nextMinSizePx > totalSize) {\r\n newSizePx = totalSize - barSize - nextMinSizePx;\r\n }\r\n // 同时确保前一个面板不小于其最小值\r\n newSizePx = Math.max(minSizePx, newSizePx);\r\n\r\n // 检查原始尺寸是否是固定单位\r\n const prevOriginalSize = prevPanel.size();\r\n const prevIsFixedSize = prevOriginalSize && typeof prevOriginalSize === 'string' && !prevOriginalSize.endsWith('%');\r\n\r\n // 更新前一个面板的尺寸\r\n if (prevIsFixedSize) {\r\n // 如果前一个面板是固定单位,使用像素值\r\n prevPanel.currentSize.set(`${Math.round(newSizePx)}px`);\r\n } else {\r\n // 如果前一个面板是百分比或数字,使用百分比\r\n const newSizePercent = (newSizePx / totalSize) * 100;\r\n prevPanel.currentSize.set(`${newSizePercent}%`);\r\n }\r\n\r\n // 关键修复:对于后面的所有 panel,需要保持它们的实际像素尺寸不变\r\n // 获取后面所有 panel 的当前实际尺寸\r\n const remainingPanels = panels.slice(barIndex + 1);\r\n const barCount = remainingPanels.length - 1; // bar 的数量比 panel 少 1\r\n const totalBarSize = barCount * barSize;\r\n\r\n // 计算剩余空间\r\n const remainingSpace = totalSize - newSizePx - totalBarSize;\r\n\r\n // 首先获取每个 panel 的当前实际像素尺寸(在修改之前)\r\n const currentSizes: number[] = [];\r\n let totalCurrentSize = 0;\r\n\r\n remainingPanels.forEach((panel) => {\r\n const panelElement = panelElements[panels.indexOf(panel)];\r\n const computedSize = isHorizontal ? panelElement.offsetWidth : panelElement.offsetHeight;\r\n currentSizes.push(computedSize);\r\n totalCurrentSize += computedSize;\r\n });\r\n\r\n // 如果只有一个后续 panel,直接设置它的尺寸为剩余空间\r\n if (remainingPanels.length === 1) {\r\n const panel = remainingPanels[0];\r\n // 始终使用像素值,确保尺寸固定\r\n panel.currentSize.set(`${Math.round(remainingSpace)}px`);\r\n } else {\r\n // 如果有多个后续 panel,按当前尺寸的比例分配剩余空间\r\n remainingPanels.forEach((panel, index) => {\r\n if (totalCurrentSize > 0) {\r\n // 按当前尺寸的比例分配\r\n const ratio = currentSizes[index] / totalCurrentSize;\r\n const newSize = remainingSpace * ratio;\r\n // 始终使用像素值,确保尺寸固定\r\n panel.currentSize.set(`${Math.round(newSize)}px`);\r\n } else {\r\n // 如果没有当前尺寸,平均分配\r\n const avgSize = remainingSpace / remainingPanels.length;\r\n panel.currentSize.set(`${Math.round(avgSize)}px`);\r\n }\r\n });\r\n }\r\n\r\n // 手动触发变更检测\r\n this.cdr.markForCheck();\r\n }\r\n\r\n private onDragEnd(_barIndex: number) {\r\n // 取消未完成的动画帧\r\n if (this.rafId !== null) {\r\n cancelAnimationFrame(this.rafId);\r\n this.rafId = null;\r\n }\r\n // 清除缓存\r\n this.cachedSplitterRect = null;\r\n this.cachedBarSize = null;\r\n }\r\n\r\n /**\r\n * @zh_CN 将尺寸值转换为像素\r\n * @en_US Convert size value to pixels\r\n */\r\n private parseSizeToPx(size: string | number, totalSize: number): number {\r\n if (typeof size === 'number') {\r\n // 数字默认当作像素\r\n return size;\r\n }\r\n\r\n if (size.endsWith('%')) {\r\n const percent = parseFloat(size);\r\n return (percent / 100) * totalSize;\r\n }\r\n\r\n if (size.endsWith('px')) {\r\n return parseFloat(size);\r\n }\r\n\r\n if (size.endsWith('rem')) {\r\n const remValue = parseFloat(size);\r\n // 获取根元素的字体大小(默认 16px)\r\n const rootFontSize = parseFloat(getComputedStyle(document.documentElement).fontSize) || 16;\r\n return remValue * rootFontSize;\r\n }\r\n\r\n if (size.endsWith('em')) {\r\n const emValue = parseFloat(size);\r\n // 获取父元素的字体大小(这里使用 splitter 的字体大小)\r\n const parentFontSize = parseFloat(getComputedStyle(this.elementRef.nativeElement).fontSize) || 16;\r\n return emValue * parentFontSize;\r\n }\r\n\r\n // 默认当作像素处理\r\n return parseFloat(size) || 0;\r\n }\r\n\r\n /**\r\n * @zh_CN 获取 bar 的尺寸(像素)\r\n * @en_US Get bar size in pixels\r\n */\r\n private getBarSize(): number {\r\n const barElement = this.elementRef.nativeElement.querySelector('.x-splitter-bar');\r\n if (barElement) {\r\n const computedStyle = getComputedStyle(barElement);\r\n const isHorizontal = this.direction() === 'horizontal';\r\n const size = isHorizontal ? computedStyle.width : computedStyle.height;\r\n return parseFloat(size) || 4; // 默认 4px\r\n }\r\n return 4; // 默认值\r\n }\r\n}\r\n","<div class=\"x-splitter\" [class]=\"classMap()\">\r\n <ng-content></ng-content>\r\n</div>\r\n","import { NgModule } from '@angular/core';\r\nimport { XSplitterComponent } from './splitter.component';\r\nimport { XSplitterPanelComponent } from './splitter-panel.component';\r\nimport { XSplitterBarComponent } from './splitter-bar.component';\r\n\r\n@NgModule({\r\n imports: [XSplitterComponent, XSplitterPanelComponent, XSplitterBarComponent],\r\n exports: [XSplitterComponent, XSplitterPanelComponent, XSplitterBarComponent]\r\n})\r\nexport class XSplitterModule {}\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|
|
@@ -841,7 +841,15 @@ class XTimePickerComponent extends XTimePickerProperty {
|
|
|
841
841
|
setPlacement() {
|
|
842
842
|
return this.portalService.setPlacement({
|
|
843
843
|
elementRef: this.inputCom().inputRef(),
|
|
844
|
-
placement: [
|
|
844
|
+
placement: [
|
|
845
|
+
this.placement(),
|
|
846
|
+
'bottom-start',
|
|
847
|
+
'bottom-end',
|
|
848
|
+
'bottom',
|
|
849
|
+
'top-start',
|
|
850
|
+
'top-end',
|
|
851
|
+
'top'
|
|
852
|
+
],
|
|
845
853
|
transformOriginOn: 'x-time-picker-portal'
|
|
846
854
|
});
|
|
847
855
|
}
|