raise-common-lib 0.0.221 → 0.0.222-beta
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/bundles/raise-common-lib.umd.js +428 -129
- package/bundles/raise-common-lib.umd.js.map +1 -1
- package/bundles/raise-common-lib.umd.min.js +1 -1
- package/bundles/raise-common-lib.umd.min.js.map +1 -1
- package/esm2015/lib/smart-popup/index.component.js +430 -133
- package/esm5/lib/smart-popup/index.component.js +429 -130
- package/fesm2015/raise-common-lib.js +429 -132
- package/fesm2015/raise-common-lib.js.map +1 -1
- package/fesm5/raise-common-lib.js +428 -129
- package/fesm5/raise-common-lib.js.map +1 -1
- package/package.json +1 -1
- package/raise-common-lib.metadata.json +1 -1
|
@@ -22884,22 +22884,91 @@ class SmartPopupComponent {
|
|
|
22884
22884
|
if (this.opened === "yes" &&
|
|
22885
22885
|
previousTrigger !== this.currentTriggerElement &&
|
|
22886
22886
|
this.currentTriggerElement) {
|
|
22887
|
-
//
|
|
22888
|
-
this.
|
|
22889
|
-
|
|
22890
|
-
|
|
22891
|
-
|
|
22892
|
-
|
|
22893
|
-
() => {
|
|
22887
|
+
// 如果提供了固定尺寸,直接重新计算位置(避免位置跳动)
|
|
22888
|
+
if (this._width !== null && this._height !== null) {
|
|
22889
|
+
// 先隐藏弹窗(positioning = yes)
|
|
22890
|
+
this.positioning = "yes";
|
|
22891
|
+
this.ref.markForCheck();
|
|
22892
|
+
this.ref.detectChanges(); // 立即应用隐藏状态
|
|
22894
22893
|
requestAnimationFrame((/**
|
|
22895
22894
|
* @return {?}
|
|
22896
22895
|
*/
|
|
22897
22896
|
() => {
|
|
22898
|
-
this.
|
|
22899
|
-
|
|
22900
|
-
|
|
22897
|
+
if (this.currentTriggerElement) {
|
|
22898
|
+
/** @type {?} */
|
|
22899
|
+
const triggerRect = this.currentTriggerElement.getBoundingClientRect();
|
|
22900
|
+
/** @type {?} */
|
|
22901
|
+
const popupSize = {
|
|
22902
|
+
width: (/** @type {?} */ (this._width)),
|
|
22903
|
+
height: (/** @type {?} */ (this._height)),
|
|
22904
|
+
};
|
|
22905
|
+
/** @type {?} */
|
|
22906
|
+
const targetInfo = this.placementInfo;
|
|
22907
|
+
/** @type {?} */
|
|
22908
|
+
let finalPlacement = targetInfo.placement;
|
|
22909
|
+
/** @type {?} */
|
|
22910
|
+
const finalPosition = targetInfo.position;
|
|
22911
|
+
if (this.autoAdjust) {
|
|
22912
|
+
/** @type {?} */
|
|
22913
|
+
const popupRect = (/** @type {?} */ ({
|
|
22914
|
+
width: popupSize.width,
|
|
22915
|
+
height: popupSize.height,
|
|
22916
|
+
top: 0,
|
|
22917
|
+
left: 0,
|
|
22918
|
+
right: popupSize.width,
|
|
22919
|
+
bottom: popupSize.height,
|
|
22920
|
+
x: 0,
|
|
22921
|
+
y: 0,
|
|
22922
|
+
toJSON: (/**
|
|
22923
|
+
* @return {?}
|
|
22924
|
+
*/
|
|
22925
|
+
() => ({})),
|
|
22926
|
+
}));
|
|
22927
|
+
/** @type {?} */
|
|
22928
|
+
const optimal = this.calculateOptimalPlacement(triggerRect, popupRect, window.innerWidth, window.innerHeight);
|
|
22929
|
+
finalPlacement = optimal.placement;
|
|
22930
|
+
}
|
|
22931
|
+
this.actualPlacement = finalPlacement;
|
|
22932
|
+
this.actualPosition = finalPosition;
|
|
22933
|
+
/** @type {?} */
|
|
22934
|
+
const position = this.calculatePositionCoordinates(triggerRect, finalPlacement, finalPosition, popupSize);
|
|
22935
|
+
if (this.popupElement && this.popupElement.nativeElement) {
|
|
22936
|
+
/** @type {?} */
|
|
22937
|
+
const popupEl = this.popupElement.nativeElement;
|
|
22938
|
+
popupEl.style.top = position.top;
|
|
22939
|
+
popupEl.style.left = position.left;
|
|
22940
|
+
popupEl.style.transform = `translate(${position.translateX}, ${position.translateY})`;
|
|
22941
|
+
popupEl.offsetHeight; // 强制同步应用样式
|
|
22942
|
+
// 位置设置完成后,再显示弹窗
|
|
22943
|
+
requestAnimationFrame((/**
|
|
22944
|
+
* @return {?}
|
|
22945
|
+
*/
|
|
22946
|
+
() => {
|
|
22947
|
+
this.positioning = "no";
|
|
22948
|
+
this.ref.markForCheck();
|
|
22949
|
+
}));
|
|
22950
|
+
}
|
|
22951
|
+
}
|
|
22901
22952
|
}));
|
|
22902
|
-
}
|
|
22953
|
+
}
|
|
22954
|
+
else {
|
|
22955
|
+
// 使用新的打开方式更新位置
|
|
22956
|
+
this.positioning = "yes";
|
|
22957
|
+
this.ref.markForCheck();
|
|
22958
|
+
requestAnimationFrame((/**
|
|
22959
|
+
* @return {?}
|
|
22960
|
+
*/
|
|
22961
|
+
() => {
|
|
22962
|
+
requestAnimationFrame((/**
|
|
22963
|
+
* @return {?}
|
|
22964
|
+
*/
|
|
22965
|
+
() => {
|
|
22966
|
+
this.updatePopupPosition();
|
|
22967
|
+
this.positioning = "no";
|
|
22968
|
+
this.ref.markForCheck();
|
|
22969
|
+
}));
|
|
22970
|
+
}));
|
|
22971
|
+
}
|
|
22903
22972
|
}
|
|
22904
22973
|
}
|
|
22905
22974
|
// 处理 open 变化(确保在触发元素更新后处理)
|
|
@@ -23015,22 +23084,92 @@ class SmartPopupComponent {
|
|
|
23015
23084
|
console.warn("SmartPopupComponent: No trigger element found");
|
|
23016
23085
|
return;
|
|
23017
23086
|
}
|
|
23018
|
-
//
|
|
23087
|
+
// 如果已经打开,且提供了固定尺寸,直接重新计算位置(避免关闭再打开导致的跳动)
|
|
23019
23088
|
if (this.opened === "yes") {
|
|
23020
|
-
|
|
23021
|
-
|
|
23022
|
-
|
|
23023
|
-
|
|
23024
|
-
|
|
23025
|
-
|
|
23026
|
-
|
|
23027
|
-
|
|
23028
|
-
|
|
23029
|
-
|
|
23030
|
-
|
|
23031
|
-
|
|
23032
|
-
|
|
23033
|
-
|
|
23089
|
+
if (this._width !== null && this._height !== null) {
|
|
23090
|
+
// 有固定尺寸,直接重新计算位置,不关闭弹窗
|
|
23091
|
+
// 先隐藏弹窗(positioning = yes)
|
|
23092
|
+
this.positioning = "yes";
|
|
23093
|
+
this.ref.markForCheck();
|
|
23094
|
+
this.ref.detectChanges(); // 立即应用隐藏状态
|
|
23095
|
+
requestAnimationFrame((/**
|
|
23096
|
+
* @return {?}
|
|
23097
|
+
*/
|
|
23098
|
+
() => {
|
|
23099
|
+
// 再次确保触发元素已更新
|
|
23100
|
+
this.updateTriggerElement();
|
|
23101
|
+
if (this.currentTriggerElement) {
|
|
23102
|
+
/** @type {?} */
|
|
23103
|
+
const triggerRect = this.currentTriggerElement.getBoundingClientRect();
|
|
23104
|
+
/** @type {?} */
|
|
23105
|
+
const popupSize = {
|
|
23106
|
+
width: (/** @type {?} */ (this._width)),
|
|
23107
|
+
height: (/** @type {?} */ (this._height)),
|
|
23108
|
+
};
|
|
23109
|
+
/** @type {?} */
|
|
23110
|
+
const targetInfo = this.placementInfo;
|
|
23111
|
+
/** @type {?} */
|
|
23112
|
+
let finalPlacement = targetInfo.placement;
|
|
23113
|
+
/** @type {?} */
|
|
23114
|
+
const finalPosition = targetInfo.position;
|
|
23115
|
+
if (this.autoAdjust) {
|
|
23116
|
+
/** @type {?} */
|
|
23117
|
+
const popupRect = (/** @type {?} */ ({
|
|
23118
|
+
width: popupSize.width,
|
|
23119
|
+
height: popupSize.height,
|
|
23120
|
+
top: 0,
|
|
23121
|
+
left: 0,
|
|
23122
|
+
right: popupSize.width,
|
|
23123
|
+
bottom: popupSize.height,
|
|
23124
|
+
x: 0,
|
|
23125
|
+
y: 0,
|
|
23126
|
+
toJSON: (/**
|
|
23127
|
+
* @return {?}
|
|
23128
|
+
*/
|
|
23129
|
+
() => ({})),
|
|
23130
|
+
}));
|
|
23131
|
+
/** @type {?} */
|
|
23132
|
+
const optimal = this.calculateOptimalPlacement(triggerRect, popupRect, window.innerWidth, window.innerHeight);
|
|
23133
|
+
finalPlacement = optimal.placement;
|
|
23134
|
+
}
|
|
23135
|
+
this.actualPlacement = finalPlacement;
|
|
23136
|
+
this.actualPosition = finalPosition;
|
|
23137
|
+
/** @type {?} */
|
|
23138
|
+
const position = this.calculatePositionCoordinates(triggerRect, finalPlacement, finalPosition, popupSize);
|
|
23139
|
+
if (this.popupElement && this.popupElement.nativeElement) {
|
|
23140
|
+
/** @type {?} */
|
|
23141
|
+
const popupEl = this.popupElement.nativeElement;
|
|
23142
|
+
popupEl.style.top = position.top;
|
|
23143
|
+
popupEl.style.left = position.left;
|
|
23144
|
+
popupEl.style.transform = `translate(${position.translateX}, ${position.translateY})`;
|
|
23145
|
+
popupEl.offsetHeight; // 强制同步应用样式
|
|
23146
|
+
// 位置设置完成后,再显示弹窗
|
|
23147
|
+
requestAnimationFrame((/**
|
|
23148
|
+
* @return {?}
|
|
23149
|
+
*/
|
|
23150
|
+
() => {
|
|
23151
|
+
this.positioning = "no";
|
|
23152
|
+
this.ref.markForCheck();
|
|
23153
|
+
}));
|
|
23154
|
+
}
|
|
23155
|
+
}
|
|
23156
|
+
}));
|
|
23157
|
+
return;
|
|
23158
|
+
}
|
|
23159
|
+
else {
|
|
23160
|
+
// 没有固定尺寸,先关闭再打开
|
|
23161
|
+
this.opened = "no";
|
|
23162
|
+
this.positioning = "no";
|
|
23163
|
+
this.ref.markForCheck();
|
|
23164
|
+
requestAnimationFrame((/**
|
|
23165
|
+
* @return {?}
|
|
23166
|
+
*/
|
|
23167
|
+
() => {
|
|
23168
|
+
this.updateTriggerElement();
|
|
23169
|
+
this.openPopup();
|
|
23170
|
+
}));
|
|
23171
|
+
return;
|
|
23172
|
+
}
|
|
23034
23173
|
}
|
|
23035
23174
|
// 确保触发元素已更新
|
|
23036
23175
|
this.updateTriggerElement();
|
|
@@ -23080,13 +23219,15 @@ class SmartPopupComponent {
|
|
|
23080
23219
|
const targetInfo = this.placementInfo;
|
|
23081
23220
|
/** @type {?} */
|
|
23082
23221
|
let finalPlacement = targetInfo.placement;
|
|
23222
|
+
// 始终使用用户指定的 position,autoAdjust 只调整 placement(方向),不改变对齐方式
|
|
23083
23223
|
/** @type {?} */
|
|
23084
|
-
|
|
23224
|
+
const finalPosition = targetInfo.position;
|
|
23085
23225
|
if (this.autoAdjust) {
|
|
23086
23226
|
/** @type {?} */
|
|
23087
23227
|
const optimal = this.calculateOptimalPlacement(triggerRect, popupRect, viewportWidth, viewportHeight);
|
|
23228
|
+
// autoAdjust 只调整 placement(上下左右),保持用户指定的 position(对齐方式)
|
|
23088
23229
|
finalPlacement = optimal.placement;
|
|
23089
|
-
finalPosition
|
|
23230
|
+
// finalPosition 保持用户指定的值,不改变
|
|
23090
23231
|
}
|
|
23091
23232
|
this.actualPlacement = finalPlacement;
|
|
23092
23233
|
this.actualPosition = finalPosition;
|
|
@@ -23094,56 +23235,57 @@ class SmartPopupComponent {
|
|
|
23094
23235
|
/** @type {?} */
|
|
23095
23236
|
const position = this.calculatePositionCoordinates(triggerRect, finalPlacement, finalPosition, popupSize);
|
|
23096
23237
|
// 先设置打开状态,但保持隐藏(positioning = yes)
|
|
23097
|
-
|
|
23238
|
+
// 注意:先设置 positioning = yes,再设置 opened = yes,确保弹窗在位置计算完成前始终隐藏
|
|
23098
23239
|
this.positioning = "yes";
|
|
23240
|
+
this.opened = "yes";
|
|
23099
23241
|
this.openChange.emit(true);
|
|
23100
23242
|
this.ref.markForCheck();
|
|
23101
|
-
// 强制更新视图,确保DOM
|
|
23243
|
+
// 强制更新视图,确保DOM已更新,但弹窗仍然隐藏(因为 positioning = yes)
|
|
23102
23244
|
this.ref.detectChanges();
|
|
23103
|
-
//
|
|
23245
|
+
// 设置位置的函数
|
|
23246
|
+
/** @type {?} */
|
|
23247
|
+
const setPosition = (/**
|
|
23248
|
+
* @return {?}
|
|
23249
|
+
*/
|
|
23250
|
+
() => {
|
|
23251
|
+
if (this.popupElement && this.popupElement.nativeElement) {
|
|
23252
|
+
/** @type {?} */
|
|
23253
|
+
const popupEl = this.popupElement.nativeElement;
|
|
23254
|
+
// 立即设置尺寸和位置
|
|
23255
|
+
popupEl.style.width = this._width + "px";
|
|
23256
|
+
popupEl.style.height = this._height + "px";
|
|
23257
|
+
popupEl.style.minWidth = this._width + "px";
|
|
23258
|
+
popupEl.style.maxWidth = this._width + "px";
|
|
23259
|
+
popupEl.style.minHeight = this._height + "px";
|
|
23260
|
+
popupEl.style.maxHeight = this._height + "px";
|
|
23261
|
+
popupEl.style.top = position.top;
|
|
23262
|
+
popupEl.style.left = position.left;
|
|
23263
|
+
popupEl.style.transform = `translate(${position.translateX}, ${position.translateY})`;
|
|
23264
|
+
// 强制同步应用样式,确保位置已设置
|
|
23265
|
+
popupEl.offsetHeight;
|
|
23266
|
+
// 位置设置完成后,再显示弹窗(设置 positioning = no)
|
|
23267
|
+
// 使用 requestAnimationFrame 确保样式已应用
|
|
23268
|
+
requestAnimationFrame((/**
|
|
23269
|
+
* @return {?}
|
|
23270
|
+
*/
|
|
23271
|
+
() => {
|
|
23272
|
+
this.positioning = "no";
|
|
23273
|
+
this.ref.markForCheck();
|
|
23274
|
+
}));
|
|
23275
|
+
}
|
|
23276
|
+
});
|
|
23277
|
+
// 如果元素已经存在,立即设置位置
|
|
23104
23278
|
if (this.popupElement && this.popupElement.nativeElement) {
|
|
23105
|
-
|
|
23106
|
-
const popupEl = this.popupElement.nativeElement;
|
|
23107
|
-
// 立即设置尺寸和位置
|
|
23108
|
-
popupEl.style.width = this._width + "px";
|
|
23109
|
-
popupEl.style.height = this._height + "px";
|
|
23110
|
-
popupEl.style.minWidth = this._width + "px";
|
|
23111
|
-
popupEl.style.maxWidth = this._width + "px";
|
|
23112
|
-
popupEl.style.minHeight = this._height + "px";
|
|
23113
|
-
popupEl.style.maxHeight = this._height + "px";
|
|
23114
|
-
popupEl.style.top = position.top;
|
|
23115
|
-
popupEl.style.left = position.left;
|
|
23116
|
-
popupEl.style.transform = `translate(${position.translateX}, ${position.translateY})`;
|
|
23117
|
-
// 强制同步应用样式
|
|
23118
|
-
popupEl.offsetHeight;
|
|
23119
|
-
// 位置设置完成后,立即显示弹窗
|
|
23120
|
-
this.positioning = "no";
|
|
23121
|
-
this.ref.markForCheck();
|
|
23279
|
+
setPosition();
|
|
23122
23280
|
}
|
|
23123
23281
|
else {
|
|
23124
|
-
//
|
|
23282
|
+
// 如果元素还不存在,等待渲染后再设置位置
|
|
23125
23283
|
requestAnimationFrame((/**
|
|
23126
23284
|
* @return {?}
|
|
23127
23285
|
*/
|
|
23128
23286
|
() => {
|
|
23129
23287
|
if (this.popupElement && this.popupElement.nativeElement) {
|
|
23130
|
-
|
|
23131
|
-
const popupEl = this.popupElement.nativeElement;
|
|
23132
|
-
// 立即设置尺寸和位置
|
|
23133
|
-
popupEl.style.width = this._width + "px";
|
|
23134
|
-
popupEl.style.height = this._height + "px";
|
|
23135
|
-
popupEl.style.minWidth = this._width + "px";
|
|
23136
|
-
popupEl.style.maxWidth = this._width + "px";
|
|
23137
|
-
popupEl.style.minHeight = this._height + "px";
|
|
23138
|
-
popupEl.style.maxHeight = this._height + "px";
|
|
23139
|
-
popupEl.style.top = position.top;
|
|
23140
|
-
popupEl.style.left = position.left;
|
|
23141
|
-
popupEl.style.transform = `translate(${position.translateX}, ${position.translateY})`;
|
|
23142
|
-
// 强制同步应用样式
|
|
23143
|
-
popupEl.offsetHeight;
|
|
23144
|
-
// 位置设置完成后,立即显示弹窗
|
|
23145
|
-
this.positioning = "no";
|
|
23146
|
-
this.ref.markForCheck();
|
|
23288
|
+
setPosition();
|
|
23147
23289
|
}
|
|
23148
23290
|
}));
|
|
23149
23291
|
}
|
|
@@ -23275,13 +23417,15 @@ class SmartPopupComponent {
|
|
|
23275
23417
|
const targetInfo = this.placementInfo;
|
|
23276
23418
|
/** @type {?} */
|
|
23277
23419
|
let finalPlacement = targetInfo.placement;
|
|
23420
|
+
// 始终使用用户指定的 position,autoAdjust 只调整 placement(方向),不改变对齐方式
|
|
23278
23421
|
/** @type {?} */
|
|
23279
|
-
|
|
23422
|
+
const finalPosition = targetInfo.position;
|
|
23280
23423
|
if (this.autoAdjust) {
|
|
23281
23424
|
/** @type {?} */
|
|
23282
23425
|
const optimal = this.calculateOptimalPlacement(triggerRect, popupRect, viewportWidth, viewportHeight);
|
|
23426
|
+
// autoAdjust 只调整 placement(上下左右),保持用户指定的 position(对齐方式)
|
|
23283
23427
|
finalPlacement = optimal.placement;
|
|
23284
|
-
finalPosition
|
|
23428
|
+
// finalPosition 保持用户指定的值,不改变
|
|
23285
23429
|
}
|
|
23286
23430
|
this.actualPlacement = finalPlacement;
|
|
23287
23431
|
this.actualPosition = finalPosition;
|
|
@@ -23332,13 +23476,15 @@ class SmartPopupComponent {
|
|
|
23332
23476
|
const targetInfo = this.placementInfo;
|
|
23333
23477
|
/** @type {?} */
|
|
23334
23478
|
let finalPlacement = targetInfo.placement;
|
|
23479
|
+
// 始终使用用户指定的 position,autoAdjust 只调整 placement(方向),不改变对齐方式
|
|
23335
23480
|
/** @type {?} */
|
|
23336
|
-
|
|
23481
|
+
const finalPosition = targetInfo.position;
|
|
23337
23482
|
if (this.autoAdjust) {
|
|
23338
23483
|
/** @type {?} */
|
|
23339
23484
|
const optimal = this.calculateOptimalPlacement(triggerRect, popupRect, viewportWidth, viewportHeight);
|
|
23485
|
+
// autoAdjust 只调整 placement(上下左右),保持用户指定的 position(对齐方式)
|
|
23340
23486
|
finalPlacement = optimal.placement;
|
|
23341
|
-
finalPosition
|
|
23487
|
+
// finalPosition 保持用户指定的值,不改变
|
|
23342
23488
|
}
|
|
23343
23489
|
this.actualPlacement = finalPlacement;
|
|
23344
23490
|
this.actualPosition = finalPosition;
|
|
@@ -23499,17 +23645,12 @@ class SmartPopupComponent {
|
|
|
23499
23645
|
});
|
|
23500
23646
|
// 如果首选位置有足够空间,优先使用用户指定的position
|
|
23501
23647
|
if (hasEnoughSpace(preferred)) {
|
|
23502
|
-
//
|
|
23503
|
-
|
|
23504
|
-
|
|
23505
|
-
placement: preferred,
|
|
23506
|
-
position: preferredPosition,
|
|
23507
|
-
};
|
|
23508
|
-
}
|
|
23509
|
-
// 如果指定的position空间不足,自动计算最佳position
|
|
23648
|
+
// 即使指定的position空间不足,也尽量保持用户指定的position
|
|
23649
|
+
// 边界约束逻辑会在 calculatePositionCoordinates 中处理位置调整
|
|
23650
|
+
// 这样可以保持用户期望的对齐方式
|
|
23510
23651
|
return {
|
|
23511
23652
|
placement: preferred,
|
|
23512
|
-
position:
|
|
23653
|
+
position: preferredPosition,
|
|
23513
23654
|
};
|
|
23514
23655
|
}
|
|
23515
23656
|
// 根据首选位置选择备选位置
|
|
@@ -23550,6 +23691,7 @@ class SmartPopupComponent {
|
|
|
23550
23691
|
};
|
|
23551
23692
|
}
|
|
23552
23693
|
// 计算位置坐标(纯计算,不依赖DOM,包含边界约束)
|
|
23694
|
+
// 注意:弹窗使用 position: fixed,所以坐标应该是相对于视口的,不需要加上滚动偏移
|
|
23553
23695
|
/**
|
|
23554
23696
|
* @private
|
|
23555
23697
|
* @param {?} triggerRect
|
|
@@ -23568,10 +23710,6 @@ class SmartPopupComponent {
|
|
|
23568
23710
|
/** @type {?} */
|
|
23569
23711
|
const viewportHeight = window.innerHeight;
|
|
23570
23712
|
/** @type {?} */
|
|
23571
|
-
const scrollX = window.scrollX;
|
|
23572
|
-
/** @type {?} */
|
|
23573
|
-
const scrollY = window.scrollY;
|
|
23574
|
-
/** @type {?} */
|
|
23575
23713
|
let top = 0;
|
|
23576
23714
|
/** @type {?} */
|
|
23577
23715
|
let left = 0;
|
|
@@ -23581,109 +23719,268 @@ class SmartPopupComponent {
|
|
|
23581
23719
|
let translateY = "0";
|
|
23582
23720
|
switch (placement) {
|
|
23583
23721
|
case "top":
|
|
23584
|
-
|
|
23722
|
+
// 弹窗在触发元素上方
|
|
23723
|
+
top = triggerRect.top - this.offset;
|
|
23585
23724
|
translateY = "-100%";
|
|
23586
23725
|
if (position === "start") {
|
|
23587
|
-
|
|
23726
|
+
// 左对齐
|
|
23727
|
+
left = triggerRect.left;
|
|
23728
|
+
translateX = "0";
|
|
23588
23729
|
}
|
|
23589
23730
|
else if (position === "center") {
|
|
23590
|
-
|
|
23731
|
+
// 居中对齐
|
|
23732
|
+
left = triggerRect.left + triggerWidth / 2;
|
|
23591
23733
|
translateX = "-50%";
|
|
23592
23734
|
}
|
|
23593
23735
|
else {
|
|
23594
|
-
|
|
23736
|
+
// 右对齐(end)
|
|
23737
|
+
left = triggerRect.right;
|
|
23595
23738
|
translateX = "-100%";
|
|
23596
23739
|
}
|
|
23597
23740
|
// 边界约束:确保弹窗不超出视口
|
|
23598
|
-
|
|
23599
|
-
|
|
23741
|
+
/** @type {?} */
|
|
23742
|
+
const popupTop = top - popupSize.height;
|
|
23743
|
+
if (popupTop < 0) {
|
|
23744
|
+
top = popupSize.height + 8; // 距离顶部至少8px
|
|
23745
|
+
translateY = "0"; // 取消向上偏移
|
|
23600
23746
|
}
|
|
23601
|
-
|
|
23602
|
-
|
|
23603
|
-
|
|
23747
|
+
// 水平边界约束:尽量保持原始对齐方式
|
|
23748
|
+
if (position === "start") {
|
|
23749
|
+
// 左对齐:如果超出右边界,调整到右边界;如果超出左边界,调整到左边界
|
|
23750
|
+
if (left + popupSize.width > viewportWidth) {
|
|
23751
|
+
left = viewportWidth - popupSize.width - 8;
|
|
23752
|
+
}
|
|
23753
|
+
if (left < 8) {
|
|
23754
|
+
left = 8;
|
|
23755
|
+
}
|
|
23604
23756
|
}
|
|
23605
|
-
else if (
|
|
23606
|
-
|
|
23607
|
-
|
|
23757
|
+
else if (position === "center") {
|
|
23758
|
+
// 居中对齐:计算实际左边界
|
|
23759
|
+
/** @type {?} */
|
|
23760
|
+
const actualLeft = left - popupSize.width / 2;
|
|
23761
|
+
if (actualLeft < 8) {
|
|
23762
|
+
// 左边界不足,尽量保持居中,但调整到不超出左边界
|
|
23763
|
+
left = 8 + popupSize.width / 2;
|
|
23764
|
+
translateX = "-50%";
|
|
23765
|
+
}
|
|
23766
|
+
else if (actualLeft + popupSize.width > viewportWidth - 8) {
|
|
23767
|
+
// 右边界不足,尽量保持居中,但调整到不超出右边界
|
|
23768
|
+
left = viewportWidth - 8 - popupSize.width / 2;
|
|
23769
|
+
translateX = "-50%";
|
|
23770
|
+
}
|
|
23771
|
+
}
|
|
23772
|
+
else {
|
|
23773
|
+
// 右对齐(end):弹窗右边缘与触发元素右边缘对齐
|
|
23774
|
+
// left 是弹窗的右边缘位置(因为 translateX = "-100%")
|
|
23775
|
+
// 弹窗的左边缘在 left - popupSize.width
|
|
23776
|
+
/** @type {?} */
|
|
23777
|
+
const popupLeftEdge = left - popupSize.width;
|
|
23778
|
+
// 如果弹窗左边缘超出左边界,调整位置但保持右对齐
|
|
23779
|
+
if (popupLeftEdge < 8) {
|
|
23780
|
+
left = 8 + popupSize.width;
|
|
23781
|
+
translateX = "-100%";
|
|
23782
|
+
}
|
|
23783
|
+
// 如果弹窗右边缘超出右边界,调整位置但保持右对齐
|
|
23784
|
+
if (left > viewportWidth - 8) {
|
|
23785
|
+
left = viewportWidth - 8;
|
|
23786
|
+
translateX = "-100%";
|
|
23787
|
+
}
|
|
23608
23788
|
}
|
|
23609
23789
|
break;
|
|
23610
23790
|
case "bottom":
|
|
23611
|
-
|
|
23791
|
+
// 弹窗在触发元素下方
|
|
23792
|
+
top = triggerRect.bottom + this.offset;
|
|
23612
23793
|
if (position === "start") {
|
|
23613
|
-
|
|
23794
|
+
// 左对齐
|
|
23795
|
+
left = triggerRect.left;
|
|
23796
|
+
translateX = "0";
|
|
23614
23797
|
}
|
|
23615
23798
|
else if (position === "center") {
|
|
23616
|
-
|
|
23799
|
+
// 居中对齐
|
|
23800
|
+
left = triggerRect.left + triggerWidth / 2;
|
|
23617
23801
|
translateX = "-50%";
|
|
23618
23802
|
}
|
|
23619
23803
|
else {
|
|
23620
|
-
|
|
23804
|
+
// 右对齐(end)
|
|
23805
|
+
left = triggerRect.right;
|
|
23621
23806
|
translateX = "-100%";
|
|
23622
23807
|
}
|
|
23623
23808
|
// 边界约束:确保弹窗不超出视口
|
|
23624
|
-
if (top + popupSize.height >
|
|
23625
|
-
top =
|
|
23809
|
+
if (top + popupSize.height > viewportHeight) {
|
|
23810
|
+
top = viewportHeight - popupSize.height - 8; // 距离底部至少8px
|
|
23626
23811
|
}
|
|
23627
|
-
|
|
23628
|
-
|
|
23629
|
-
|
|
23812
|
+
// 水平边界约束:尽量保持原始对齐方式
|
|
23813
|
+
if (position === "start") {
|
|
23814
|
+
// 左对齐:如果超出右边界,调整到右边界;如果超出左边界,调整到左边界
|
|
23815
|
+
if (left + popupSize.width > viewportWidth) {
|
|
23816
|
+
left = viewportWidth - popupSize.width - 8;
|
|
23817
|
+
}
|
|
23818
|
+
if (left < 8) {
|
|
23819
|
+
left = 8;
|
|
23820
|
+
}
|
|
23630
23821
|
}
|
|
23631
|
-
else if (
|
|
23632
|
-
|
|
23633
|
-
|
|
23822
|
+
else if (position === "center") {
|
|
23823
|
+
// 居中对齐:计算实际左边界
|
|
23824
|
+
/** @type {?} */
|
|
23825
|
+
const actualLeft = left - popupSize.width / 2;
|
|
23826
|
+
if (actualLeft < 8) {
|
|
23827
|
+
// 左边界不足,尽量保持居中,但调整到不超出左边界
|
|
23828
|
+
left = 8 + popupSize.width / 2;
|
|
23829
|
+
translateX = "-50%";
|
|
23830
|
+
}
|
|
23831
|
+
else if (actualLeft + popupSize.width > viewportWidth - 8) {
|
|
23832
|
+
// 右边界不足,尽量保持居中,但调整到不超出右边界
|
|
23833
|
+
left = viewportWidth - 8 - popupSize.width / 2;
|
|
23834
|
+
translateX = "-50%";
|
|
23835
|
+
}
|
|
23836
|
+
}
|
|
23837
|
+
else {
|
|
23838
|
+
// 右对齐(end):弹窗右边缘与触发元素右边缘对齐
|
|
23839
|
+
// left 是弹窗的右边缘位置(因为 translateX = "-100%")
|
|
23840
|
+
// 弹窗的左边缘在 left - popupSize.width
|
|
23841
|
+
/** @type {?} */
|
|
23842
|
+
const popupLeftEdge = left - popupSize.width;
|
|
23843
|
+
// 优先保持与触发元素右对齐,只在必要时调整
|
|
23844
|
+
// 如果弹窗右边缘超出右边界,调整位置但保持右对齐
|
|
23845
|
+
if (left > viewportWidth - 8) {
|
|
23846
|
+
left = viewportWidth - 8;
|
|
23847
|
+
translateX = "-100%";
|
|
23848
|
+
}
|
|
23849
|
+
// 如果弹窗左边缘超出左边界,且弹窗可以完全显示在视口内,才调整位置
|
|
23850
|
+
// 这样可以确保在可能的情况下,弹窗始终与触发元素右对齐
|
|
23851
|
+
if (popupLeftEdge < 8 && popupSize.width < viewportWidth - 16) {
|
|
23852
|
+
// 只有当弹窗可以完全显示在视口内时,才调整位置
|
|
23853
|
+
// 否则保持与触发元素右对齐,即使部分超出左边界
|
|
23854
|
+
left = 8 + popupSize.width;
|
|
23855
|
+
translateX = "-100%";
|
|
23856
|
+
}
|
|
23634
23857
|
}
|
|
23635
23858
|
break;
|
|
23636
23859
|
case "left":
|
|
23637
|
-
|
|
23860
|
+
// 弹窗在触发元素左侧
|
|
23861
|
+
left = triggerRect.left - this.offset;
|
|
23638
23862
|
translateX = "-100%";
|
|
23639
23863
|
if (position === "start") {
|
|
23640
|
-
|
|
23864
|
+
// 上对齐
|
|
23865
|
+
top = triggerRect.top;
|
|
23866
|
+
translateY = "0";
|
|
23641
23867
|
}
|
|
23642
23868
|
else if (position === "center") {
|
|
23643
|
-
|
|
23869
|
+
// 居中对齐
|
|
23870
|
+
top = triggerRect.top + triggerHeight / 2;
|
|
23644
23871
|
translateY = "-50%";
|
|
23645
23872
|
}
|
|
23646
23873
|
else {
|
|
23647
|
-
|
|
23874
|
+
// 下对齐(end)
|
|
23875
|
+
top = triggerRect.bottom;
|
|
23648
23876
|
translateY = "-100%";
|
|
23649
23877
|
}
|
|
23650
23878
|
// 边界约束:确保弹窗不超出视口
|
|
23651
|
-
|
|
23652
|
-
|
|
23879
|
+
/** @type {?} */
|
|
23880
|
+
const popupLeftSide = left - popupSize.width;
|
|
23881
|
+
if (popupLeftSide < 0) {
|
|
23882
|
+
left = 8; // 距离左侧至少8px
|
|
23883
|
+
translateX = "0"; // 取消向左偏移
|
|
23653
23884
|
}
|
|
23654
|
-
|
|
23655
|
-
|
|
23656
|
-
|
|
23885
|
+
// 垂直边界约束:尽量保持原始对齐方式
|
|
23886
|
+
if (position === "start") {
|
|
23887
|
+
// 上对齐:如果超出下边界,调整到下边界;如果超出上边界,调整到上边界
|
|
23888
|
+
if (top + popupSize.height > viewportHeight) {
|
|
23889
|
+
top = viewportHeight - popupSize.height - 8;
|
|
23890
|
+
}
|
|
23891
|
+
if (top < 8) {
|
|
23892
|
+
top = 8;
|
|
23893
|
+
}
|
|
23657
23894
|
}
|
|
23658
|
-
else if (
|
|
23659
|
-
|
|
23660
|
-
|
|
23895
|
+
else if (position === "center") {
|
|
23896
|
+
// 居中对齐:计算实际上边界
|
|
23897
|
+
/** @type {?} */
|
|
23898
|
+
const actualTop = top - popupSize.height / 2;
|
|
23899
|
+
if (actualTop < 8) {
|
|
23900
|
+
// 上边界不足,尽量保持居中,但调整到不超出上边界
|
|
23901
|
+
top = 8 + popupSize.height / 2;
|
|
23902
|
+
translateY = "-50%";
|
|
23903
|
+
}
|
|
23904
|
+
else if (actualTop + popupSize.height > viewportHeight - 8) {
|
|
23905
|
+
// 下边界不足,尽量保持居中,但调整到不超出下边界
|
|
23906
|
+
top = viewportHeight - 8 - popupSize.height / 2;
|
|
23907
|
+
translateY = "-50%";
|
|
23908
|
+
}
|
|
23909
|
+
}
|
|
23910
|
+
else {
|
|
23911
|
+
// 下对齐(end):如果超出上边界,调整到上边界;如果超出下边界,调整到下边界
|
|
23912
|
+
/** @type {?} */
|
|
23913
|
+
const actualTop = top - popupSize.height;
|
|
23914
|
+
if (actualTop < 8) {
|
|
23915
|
+
top = 8 + popupSize.height;
|
|
23916
|
+
translateY = "-100%";
|
|
23917
|
+
}
|
|
23918
|
+
if (top > viewportHeight - 8) {
|
|
23919
|
+
top = viewportHeight - 8;
|
|
23920
|
+
translateY = "-100%";
|
|
23921
|
+
}
|
|
23661
23922
|
}
|
|
23662
23923
|
break;
|
|
23663
23924
|
case "right":
|
|
23664
|
-
|
|
23925
|
+
// 弹窗在触发元素右侧
|
|
23926
|
+
left = triggerRect.right + this.offset;
|
|
23927
|
+
translateX = "0";
|
|
23665
23928
|
if (position === "start") {
|
|
23666
|
-
|
|
23929
|
+
// 上对齐
|
|
23930
|
+
top = triggerRect.top;
|
|
23931
|
+
translateY = "0";
|
|
23667
23932
|
}
|
|
23668
23933
|
else if (position === "center") {
|
|
23669
|
-
|
|
23934
|
+
// 居中对齐
|
|
23935
|
+
top = triggerRect.top + triggerHeight / 2;
|
|
23670
23936
|
translateY = "-50%";
|
|
23671
23937
|
}
|
|
23672
23938
|
else {
|
|
23673
|
-
|
|
23939
|
+
// 下对齐(end)
|
|
23940
|
+
top = triggerRect.bottom;
|
|
23674
23941
|
translateY = "-100%";
|
|
23675
23942
|
}
|
|
23676
23943
|
// 边界约束:确保弹窗不超出视口
|
|
23677
|
-
if (left + popupSize.width >
|
|
23678
|
-
left =
|
|
23944
|
+
if (left + popupSize.width > viewportWidth) {
|
|
23945
|
+
left = viewportWidth - popupSize.width - 8; // 距离右侧至少8px
|
|
23679
23946
|
}
|
|
23680
|
-
|
|
23681
|
-
|
|
23682
|
-
|
|
23947
|
+
// 垂直边界约束:尽量保持原始对齐方式
|
|
23948
|
+
if (position === "start") {
|
|
23949
|
+
// 上对齐:如果超出下边界,调整到下边界;如果超出上边界,调整到上边界
|
|
23950
|
+
if (top + popupSize.height > viewportHeight) {
|
|
23951
|
+
top = viewportHeight - popupSize.height - 8;
|
|
23952
|
+
}
|
|
23953
|
+
if (top < 8) {
|
|
23954
|
+
top = 8;
|
|
23955
|
+
}
|
|
23683
23956
|
}
|
|
23684
|
-
else if (
|
|
23685
|
-
|
|
23686
|
-
|
|
23957
|
+
else if (position === "center") {
|
|
23958
|
+
// 居中对齐:计算实际上边界
|
|
23959
|
+
/** @type {?} */
|
|
23960
|
+
const actualTop = top - popupSize.height / 2;
|
|
23961
|
+
if (actualTop < 8) {
|
|
23962
|
+
// 上边界不足,尽量保持居中,但调整到不超出上边界
|
|
23963
|
+
top = 8 + popupSize.height / 2;
|
|
23964
|
+
translateY = "-50%";
|
|
23965
|
+
}
|
|
23966
|
+
else if (actualTop + popupSize.height > viewportHeight - 8) {
|
|
23967
|
+
// 下边界不足,尽量保持居中,但调整到不超出下边界
|
|
23968
|
+
top = viewportHeight - 8 - popupSize.height / 2;
|
|
23969
|
+
translateY = "-50%";
|
|
23970
|
+
}
|
|
23971
|
+
}
|
|
23972
|
+
else {
|
|
23973
|
+
// 下对齐(end):如果超出上边界,调整到上边界;如果超出下边界,调整到下边界
|
|
23974
|
+
/** @type {?} */
|
|
23975
|
+
const actualTop = top - popupSize.height;
|
|
23976
|
+
if (actualTop < 8) {
|
|
23977
|
+
top = 8 + popupSize.height;
|
|
23978
|
+
translateY = "-100%";
|
|
23979
|
+
}
|
|
23980
|
+
if (top > viewportHeight - 8) {
|
|
23981
|
+
top = viewportHeight - 8;
|
|
23982
|
+
translateY = "-100%";
|
|
23983
|
+
}
|
|
23687
23984
|
}
|
|
23688
23985
|
break;
|
|
23689
23986
|
}
|
|
@@ -23738,7 +24035,7 @@ SmartPopupComponent.decorators = [
|
|
|
23738
24035
|
{ type: Component, args: [{
|
|
23739
24036
|
selector: "rs-smart-popup",
|
|
23740
24037
|
template: "<!-- \u89E6\u53D1\u5143\u7D20\u63D2\u69FD -->\r\n<ng-container #trigger>\r\n <ng-content select=\"[trigger]\"></ng-content>\r\n</ng-container>\r\n\r\n<!-- \u5F39\u7A97\u5185\u5BB9 -->\r\n<div\r\n #popup\r\n class=\"rs-smart-popup-content\"\r\n [attr.data-opened]=\"opened\"\r\n [attr.data-positioning]=\"positioning\"\r\n (wheel)=\"onPopupWheel($event)\"\r\n (scroll)=\"onPopupScroll($event)\"\r\n>\r\n <div *ngIf=\"loading\" class=\"rs-smart-popup-loading\">\r\n <div class=\"loading-spinner\"></div>\r\n </div>\r\n <div *ngIf=\"!loading\" class=\"rs-smart-popup-body\">\r\n <ng-content></ng-content>\r\n </div>\r\n</div>\r\n\r\n",
|
|
23741
|
-
styles: [".rs-smart-popup-trigger{display:inline-block;cursor:pointer}::ng-deep #rs-smart-popup-fixed-container{width:0;height:0;z-index:100000;pointer-events:none}::ng-deep #rs-smart-popup-fixed-container .rs-smart-popup-content{pointer-events:auto;position:fixed;z-index:100001;padding:8px;border-radius:8px;background:#fff;box-shadow:0 0 8px 0 rgba(0,0,0,.25);min-width:200px;max-width:400px;max-height:500px;overflow:auto}::ng-deep #rs-smart-popup-fixed-container .rs-smart-popup-content[data-opened=no]{display:none}::ng-deep #rs-smart-popup-fixed-container .rs-smart-popup-content[data-opened=yes]{display:block}::ng-deep #rs-smart-popup-fixed-container .rs-smart-popup-content[data-opened=yes][data-positioning=yes]{display:none!important}::ng-deep #rs-smart-popup-fixed-container .rs-smart-popup-content[data-opened=yes][data-positioning=no]{display:block;visibility:visible;opacity:1;pointer-events:auto
|
|
24038
|
+
styles: [".rs-smart-popup-trigger{display:inline-block;cursor:pointer}::ng-deep #rs-smart-popup-fixed-container{width:0;height:0;z-index:100000;pointer-events:none}::ng-deep #rs-smart-popup-fixed-container .rs-smart-popup-content{pointer-events:auto;position:fixed;z-index:100001;padding:8px;border-radius:8px;background:#fff;box-shadow:0 0 8px 0 rgba(0,0,0,.25);min-width:200px;max-width:400px;max-height:500px;overflow:auto}::ng-deep #rs-smart-popup-fixed-container .rs-smart-popup-content[data-opened=no]{display:none}::ng-deep #rs-smart-popup-fixed-container .rs-smart-popup-content[data-opened=yes]{display:block}::ng-deep #rs-smart-popup-fixed-container .rs-smart-popup-content[data-opened=yes][data-positioning=yes]{display:none!important}::ng-deep #rs-smart-popup-fixed-container .rs-smart-popup-content[data-opened=yes][data-positioning=no]{display:block;visibility:visible;opacity:1;pointer-events:auto}::ng-deep #rs-smart-popup-fixed-container .rs-smart-popup-content .rs-smart-popup-loading{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:20px;min-height:100px}::ng-deep #rs-smart-popup-fixed-container .rs-smart-popup-content .rs-smart-popup-loading .loading-spinner{width:24px;height:24px;border:3px solid #f3f3f3;border-top:3px solid #3498db;border-radius:50%;-webkit-animation:1s linear infinite spin;animation:1s linear infinite spin;margin-bottom:12px}::ng-deep #rs-smart-popup-fixed-container .rs-smart-popup-content .rs-smart-popup-loading .loading-text{color:#666;font-size:14px}@-webkit-keyframes spin{0%{transform:rotate(0)}100%{transform:rotate(360deg)}}@keyframes spin{0%{transform:rotate(0)}100%{transform:rotate(360deg)}}::ng-deep #rs-smart-popup-fixed-container .rs-smart-popup-content .rs-smart-popup-body{width:100%}"]
|
|
23742
24039
|
}] }
|
|
23743
24040
|
];
|
|
23744
24041
|
/** @nocollapse */
|