Browse Source

Merge pull request #210835 in DEC/fineui from master to feature/x

* commit 'f1b12d3bed4a6f6dadf8fabd54f1e06c674e891e':
  demo
  KERNEL-11877 BI-118434 等比下scale缩放下拉偏移
master
superman 2 years ago
parent
commit
e28508cd10
  1. 6
      demo/js/west.js
  2. 9
      src/base/combination/bubble.js
  3. 39
      src/base/combination/combo.js
  4. 116
      src/core/platform/web/dom.js

6
demo/js/west.js

@ -9,6 +9,10 @@ Demo.West = BI.inherit(BI.Widget, {
render: function () {
var self = this;
var selectedId = BI.Router.$router.currentRoute.params?.componentId;
return {
type: "bi.vtape",
items: [{
@ -60,7 +64,7 @@ Demo.West = BI.inherit(BI.Widget, {
self.fireEvent(Demo.West.EVENT_VALUE_CHANGE, v);
}
}],
value: Demo.showIndex,
value: selectedId || Demo.showIndex,
items: Demo.CONFIG,
ref: function (ref) {
self.tree = ref;

9
src/base/combination/bubble.js

@ -106,6 +106,7 @@
_initPullDownAction: function () {
var self = this, o = this.options;
var evs = (this.options.trigger || "").split(",");
function st(e) {
if (o.stopEvent) {
e.stopEvent();
@ -268,7 +269,7 @@
BI.createWidget({
type: "bi.vertical",
scrolly: false,
element: this.options.container || this,
element: BI.isFunction(this.options.container) ? this.options.container() : (this.options.container || this),
items: [
{ el: this.popupView }
],
@ -344,14 +345,16 @@
if (this.popper) {
this.popper.destroy();
}
var modifiers = [{
var modifiers = [
{
name: "offset",
options: {
offset: function () {
return [o.adjustXOffset, (o.showArrow ? 12 : 0) + (o.adjustYOffset + o.adjustLength)];
},
},
}];
}
];
if (this.options.showArrow) {
modifiers.push({
name: "arrow",

39
src/base/combination/combo.js

@ -38,6 +38,7 @@
adjustLength: 0, // 调整的距离
adjustXOffset: 0,
adjustYOffset: 0,
supportCSSTransform: false,
hideChecker: BI.emptyFn,
offsetStyle: "left", // left,right,center
el: {},
@ -218,46 +219,47 @@
},
},
} : this.combo;
var positionRelativeElement = o.supportCSSTransform ? BI.DOM.getPositionRelativeContainingBlock(BI.Widget._renderEngine.createElement(BI.isFunction(o.container) ? o.container() : o.container)[0]) : null;
switch (o.direction) {
case "bottom":
case "bottom,right":
p = BI.DOM.getComboPosition(combo, this.popupView, o.adjustXOffset, (o.adjustYOffset + o.adjustLength) + (o.showArrow ? this._const.TRIANGLE_LENGTH : 0), o.isNeedAdjustHeight, ["bottom", "top", "right", "left"], o.offsetStyle);
p = BI.DOM.getComboPosition(combo, this.popupView, o.adjustXOffset, (o.adjustYOffset + o.adjustLength) + (o.showArrow ? this._const.TRIANGLE_LENGTH : 0), o.isNeedAdjustHeight, ["bottom", "top", "right", "left"], o.offsetStyle, positionRelativeElement);
break;
case "top":
case "top,right":
p = BI.DOM.getComboPosition(combo, this.popupView, o.adjustXOffset, (o.adjustYOffset + o.adjustLength) + (o.showArrow ? this._const.TRIANGLE_LENGTH : 0), o.isNeedAdjustHeight, ["top", "bottom", "right", "left"], o.offsetStyle);
p = BI.DOM.getComboPosition(combo, this.popupView, o.adjustXOffset, (o.adjustYOffset + o.adjustLength) + (o.showArrow ? this._const.TRIANGLE_LENGTH : 0), o.isNeedAdjustHeight, ["top", "bottom", "right", "left"], o.offsetStyle, positionRelativeElement);
break;
case "left":
case "left,bottom":
p = BI.DOM.getComboPosition(combo, this.popupView, (o.adjustXOffset + o.adjustLength) + (o.showArrow ? this._const.TRIANGLE_LENGTH : 0), o.adjustYOffset, o.isNeedAdjustHeight, ["left", "right", "bottom", "top"], o.offsetStyle);
p = BI.DOM.getComboPosition(combo, this.popupView, (o.adjustXOffset + o.adjustLength) + (o.showArrow ? this._const.TRIANGLE_LENGTH : 0), o.adjustYOffset, o.isNeedAdjustHeight, ["left", "right", "bottom", "top"], o.offsetStyle, positionRelativeElement);
break;
case "right":
case "right,bottom":
p = BI.DOM.getComboPosition(combo, this.popupView, (o.adjustXOffset + o.adjustLength) + (o.showArrow ? this._const.TRIANGLE_LENGTH : 0), o.adjustYOffset, o.isNeedAdjustHeight, ["right", "left", "bottom", "top"], o.offsetStyle);
p = BI.DOM.getComboPosition(combo, this.popupView, (o.adjustXOffset + o.adjustLength) + (o.showArrow ? this._const.TRIANGLE_LENGTH : 0), o.adjustYOffset, o.isNeedAdjustHeight, ["right", "left", "bottom", "top"], o.offsetStyle, positionRelativeElement);
break;
case "top,left":
p = BI.DOM.getComboPosition(combo, this.popupView, o.adjustXOffset, (o.adjustYOffset + o.adjustLength) + (o.showArrow ? this._const.TRIANGLE_LENGTH : 0), o.isNeedAdjustHeight, ["top", "bottom", "left", "right"], o.offsetStyle);
p = BI.DOM.getComboPosition(combo, this.popupView, o.adjustXOffset, (o.adjustYOffset + o.adjustLength) + (o.showArrow ? this._const.TRIANGLE_LENGTH : 0), o.isNeedAdjustHeight, ["top", "bottom", "left", "right"], o.offsetStyle, positionRelativeElement);
break;
case "bottom,left":
p = BI.DOM.getComboPosition(combo, this.popupView, o.adjustXOffset, (o.adjustYOffset + o.adjustLength) + (o.showArrow ? this._const.TRIANGLE_LENGTH : 0), o.isNeedAdjustHeight, ["bottom", "top", "left", "right"], o.offsetStyle);
p = BI.DOM.getComboPosition(combo, this.popupView, o.adjustXOffset, (o.adjustYOffset + o.adjustLength) + (o.showArrow ? this._const.TRIANGLE_LENGTH : 0), o.isNeedAdjustHeight, ["bottom", "top", "left", "right"], o.offsetStyle, positionRelativeElement);
break;
case "left,top":
p = BI.DOM.getComboPosition(combo, this.popupView, (o.adjustXOffset + o.adjustLength) + (o.showArrow ? this._const.TRIANGLE_LENGTH : 0), o.adjustYOffset, o.isNeedAdjustHeight, ["left", "right", "top", "bottom"], o.offsetStyle);
p = BI.DOM.getComboPosition(combo, this.popupView, (o.adjustXOffset + o.adjustLength) + (o.showArrow ? this._const.TRIANGLE_LENGTH : 0), o.adjustYOffset, o.isNeedAdjustHeight, ["left", "right", "top", "bottom"], o.offsetStyle, positionRelativeElement);
break;
case "right,top":
p = BI.DOM.getComboPosition(combo, this.popupView, (o.adjustXOffset + o.adjustLength) + (o.showArrow ? this._const.TRIANGLE_LENGTH : 0), o.adjustYOffset, o.isNeedAdjustHeight, ["right", "left", "top", "bottom"], o.offsetStyle);
p = BI.DOM.getComboPosition(combo, this.popupView, (o.adjustXOffset + o.adjustLength) + (o.showArrow ? this._const.TRIANGLE_LENGTH : 0), o.adjustYOffset, o.isNeedAdjustHeight, ["right", "left", "top", "bottom"], o.offsetStyle, positionRelativeElement);
break;
case "right,innerRight":
p = BI.DOM.getComboPosition(combo, this.popupView, (o.adjustXOffset + o.adjustLength) + (o.showArrow ? this._const.TRIANGLE_LENGTH : 0), o.adjustYOffset, o.isNeedAdjustHeight, ["right", "left", "innerRight", "innerLeft", "bottom", "top"], o.offsetStyle);
p = BI.DOM.getComboPosition(combo, this.popupView, (o.adjustXOffset + o.adjustLength) + (o.showArrow ? this._const.TRIANGLE_LENGTH : 0), o.adjustYOffset, o.isNeedAdjustHeight, ["right", "left", "innerRight", "innerLeft", "bottom", "top"], o.offsetStyle, positionRelativeElement);
break;
case "right,innerLeft":
p = BI.DOM.getComboPosition(combo, this.popupView, (o.adjustXOffset + o.adjustLength) + (o.showArrow ? this._const.TRIANGLE_LENGTH : 0), o.adjustYOffset, o.isNeedAdjustHeight, ["right", "left", "innerLeft", "innerRight", "bottom", "top"], o.offsetStyle);
p = BI.DOM.getComboPosition(combo, this.popupView, (o.adjustXOffset + o.adjustLength) + (o.showArrow ? this._const.TRIANGLE_LENGTH : 0), o.adjustYOffset, o.isNeedAdjustHeight, ["right", "left", "innerLeft", "innerRight", "bottom", "top"], o.offsetStyle, positionRelativeElement);
break;
case "innerRight":
p = BI.DOM.getComboPosition(combo, this.popupView, (o.adjustXOffset + o.adjustLength) + (o.showArrow ? this._const.TRIANGLE_LENGTH : 0), o.adjustYOffset, o.isNeedAdjustHeight, ["innerRight", "innerLeft", "right", "left", "bottom", "top"], o.offsetStyle);
p = BI.DOM.getComboPosition(combo, this.popupView, (o.adjustXOffset + o.adjustLength) + (o.showArrow ? this._const.TRIANGLE_LENGTH : 0), o.adjustYOffset, o.isNeedAdjustHeight, ["innerRight", "innerLeft", "right", "left", "bottom", "top"], o.offsetStyle, positionRelativeElement);
break;
case "innerLeft":
p = BI.DOM.getComboPosition(combo, this.popupView, (o.adjustXOffset + o.adjustLength) + (o.showArrow ? this._const.TRIANGLE_LENGTH : 0), o.adjustYOffset, o.isNeedAdjustHeight, ["innerLeft", "innerRight", "left", "right", "bottom", "top"], o.offsetStyle);
p = BI.DOM.getComboPosition(combo, this.popupView, (o.adjustXOffset + o.adjustLength) + (o.showArrow ? this._const.TRIANGLE_LENGTH : 0), o.adjustYOffset, o.isNeedAdjustHeight, ["innerLeft", "innerRight", "left", "right", "bottom", "top"], o.offsetStyle, positionRelativeElement);
break;
case "top,custom":
case "custom,top":
@ -290,6 +292,7 @@
if ("adaptHeight" in p) {
this.resetListHeight(p.adaptHeight);
}
var width = this.combo.element.outerWidth();
var height = this.combo.element.outerHeight();
this.popupView.setDirection && this.popupView.setDirection(p.dir, {
@ -300,6 +303,18 @@
adjustYOffset: o.adjustYOffset,
offset: this.combo.element.offset(),
});
if (o.supportCSSTransform) {
var positonedRect = positionRelativeElement.getBoundingClientRect();
var scaleX = positonedRect.width / positionRelativeElement.offsetWidth;
var scaleY = positonedRect.height / positionRelativeElement.offsetHeight;
p.top && (p.top = p.top / scaleY);
p.left && (p.left = p.left / scaleX);
}
if ("left" in p) {
this.popupView.element.css({
left: p.left,

116
src/core/platform/web/dom.js

@ -151,9 +151,15 @@
BI.extend(BI.DOM, {
getLeftPosition: function (combo, popup, extraWidth) {
getLeftPosition: function (combo, popup, extraWidth, container) {
var el = combo.element;
var popupEl = popup.element;
var elRect = el[0].getBoundingClientRect();
var popupElRect = popupEl[0].getBoundingClientRect();
var containerRect = container ? container.getBoundingClientRect() : { left: 0 };
return {
left: combo.element.offset().left - popup.element.outerWidth() - (extraWidth || 0)
left: elRect.left - containerRect.left - popupElRect.width - (extraWidth || 0)
};
},
@ -163,10 +169,13 @@
};
},
getRightPosition: function (combo, popup, extraWidth) {
getRightPosition: function (combo, popup, extraWidth, container) {
var el = combo.element;
var elRect = el[0].getBoundingClientRect();
var containerRect = container ? container.getBoundingClientRect() : { left: 0 };
return {
left: el.offset().left + el.outerWidth() + (extraWidth || 0)
left: elRect.left + elRect.width - containerRect.left + (extraWidth || 0)
};
},
@ -177,16 +186,25 @@
};
},
getTopPosition: function (combo, popup, extraHeight) {
getTopPosition: function (combo, popup, extraHeight, container) {
var el = combo.element;
var popupEl = popup.element;
var elRect = el[0].getBoundingClientRect();
var popupElRect = popupEl[0].getBoundingClientRect();
var containerRect = container ? container.getBoundingClientRect() : { top: 0 };
return {
top: combo.element.offset().top - popup.element.outerHeight() - (extraHeight || 0)
top: elRect.top - containerRect.top - popupElRect.height - (extraHeight || 0)
};
},
getBottomPosition: function (combo, popup, extraHeight) {
getBottomPosition: function (combo, popup, extraHeight, container) {
var el = combo.element;
var elRect = el[0].getBoundingClientRect();
var containerRect = container ? container.getBoundingClientRect() : { top: 0 };
return {
top: el.offset().top + el.outerHeight() + (extraHeight || 0)
top: elRect.top - containerRect.top + elRect.height + (extraHeight || 0)
};
},
@ -230,18 +248,19 @@
return windowBounds.height - combo.element.offset().top - combo.element.bounds().height >= combo.element.offset().top;
},
_getLeftAlignPosition: function (combo, popup, extraWidth) {
_getLeftAlignPosition: function (combo, popup, extraWidth, container) {
var viewBounds = popup.element.bounds(),
windowBounds = BI.Widget._renderEngine.createElement("body").bounds();
var left = combo.element.offset().left + extraWidth;
var left = combo.element.offset().left - (container ? container.getBoundingClientRect().left : 0) + extraWidth;
if (left + viewBounds.width > windowBounds.width) {
left = windowBounds.width - viewBounds.width;
}
return left;
},
getLeftAlignPosition: function (combo, popup, extraWidth) {
var left = this._getLeftAlignPosition(combo, popup, extraWidth);
getLeftAlignPosition: function (combo, popup, extraWidth, container) {
var left = this._getLeftAlignPosition(combo, popup, extraWidth, container);
var dir = "";
// 如果放不下,优先使用RightAlign, 如果RightAlign也放不下, 再使用left=0
if (left < 0) {
@ -297,13 +316,14 @@
};
},
getTopAlignPosition: function (combo, popup, extraHeight, needAdaptHeight) {
getTopAlignPosition: function (combo, popup, extraHeight, needAdaptHeight, container) {
var comboOffset = combo.element.offset();
var comboBounds = combo.element.bounds(), popupBounds = popup.element.bounds(),
windowBounds = BI.Widget._renderEngine.createElement("body").bounds();
windowBounds = BI.Widget._renderEngine.createElement("body").bounds(),
containerBounds = container ? container.getBoundingClientRect() : { top: 0 };
var top, adaptHeight, dir;
if (BI.DOM.isBottomSpaceEnough(combo, popup, -1 * comboBounds.height + extraHeight)) {
top = comboOffset.top + extraHeight;
top = comboOffset.top - containerBounds.top + extraHeight;
} else if (needAdaptHeight) {
top = comboOffset.top + extraHeight;
adaptHeight = windowBounds.height - top;
@ -353,13 +373,15 @@
};
},
getBottomAlignPosition: function (combo, popup, extraHeight, needAdaptHeight) {
getBottomAlignPosition: function (combo, popup, extraHeight, needAdaptHeight, container) {
var comboOffset = combo.element.offset();
var comboBounds = combo.element.bounds(), popupBounds = popup.element.bounds(),
windowBounds = BI.Widget._renderEngine.createElement("body").bounds();
var comboBounds = combo.element[0].getBoundingClientRect(),
popupBounds = popup.element[0].getBoundingClientRect(),
windowBounds = BI.Widget._renderEngine.createElement("body").bounds(),
containerBounds = container ? container.getBoundingClientRect() : { top: 0 };
var top, adaptHeight, dir;
if (BI.DOM.isTopSpaceEnough(combo, popup, -1 * comboBounds.height + extraHeight)) {
top = comboOffset.top + comboBounds.height - popupBounds.height - extraHeight;
top = comboOffset.top + comboBounds.height - containerBounds.top - popupBounds.height;
} else if (needAdaptHeight) {
top = 0;
adaptHeight = comboOffset.top + comboBounds.height - extraHeight;
@ -446,7 +468,7 @@
};
},
getComboPositionByDirections: function (combo, popup, extraWidth, extraHeight, needAdaptHeight, directions) {
getComboPositionByDirections: function (combo, popup, extraWidth, extraHeight, needAdaptHeight, directions, container) {
extraWidth || (extraWidth = 0);
extraHeight || (extraHeight = 0);
var i, direct;
@ -483,11 +505,11 @@
if (!isNeedAdaptHeight) {
var tW = tbFirst ? extraHeight : extraWidth, tH = tbFirst ? 0 : extraHeight;
if (BI.DOM.isLeftSpaceEnough(combo, popup, tW)) {
left = BI.DOM.getLeftPosition(combo, popup, tW).left;
left = BI.DOM.getLeftPosition(combo, popup, tW, container).left;
if (topBottom[0] === "bottom") {
pos = BI.DOM.getTopAlignPosition(combo, popup, tH, needAdaptHeight);
pos = BI.DOM.getTopAlignPosition(combo, popup, tH, needAdaptHeight, container);
} else {
pos = BI.DOM.getBottomAlignPosition(combo, popup, tH, needAdaptHeight);
pos = BI.DOM.getBottomAlignPosition(combo, popup, tH, needAdaptHeight, container);
}
pos.dir = "left," + pos.dir;
if (tbFirst) {
@ -503,11 +525,11 @@
if (!isNeedAdaptHeight) {
var tW = tbFirst ? extraHeight : extraWidth, tH = tbFirst ? extraWidth : extraHeight;
if (BI.DOM.isRightSpaceEnough(combo, popup, tW)) {
left = BI.DOM.getRightPosition(combo, popup, tW).left;
left = BI.DOM.getRightPosition(combo, popup, tW, container).left;
if (topBottom[0] === "bottom") {
pos = BI.DOM.getTopAlignPosition(combo, popup, tH, needAdaptHeight);
pos = BI.DOM.getTopAlignPosition(combo, popup, tH, needAdaptHeight, container);
} else {
pos = BI.DOM.getBottomAlignPosition(combo, popup, tH, needAdaptHeight);
pos = BI.DOM.getBottomAlignPosition(combo, popup, tH, needAdaptHeight, container);
}
pos.dir = "right," + pos.dir;
if (tbFirst) {
@ -522,11 +544,11 @@
case "top":
var tW = lrFirst ? extraHeight : extraWidth, tH = lrFirst ? extraWidth : extraHeight;
if (BI.DOM.isTopSpaceEnough(combo, popup, tH)) {
top = BI.DOM.getTopPosition(combo, popup, tH).top;
top = BI.DOM.getTopPosition(combo, popup, tH, container).top;
if (leftRight[0] === "right") {
pos = BI.DOM.getLeftAlignPosition(combo, popup, tW, needAdaptHeight);
pos = BI.DOM.getLeftAlignPosition(combo, popup, tW, container);
} else {
pos = BI.DOM.getRightAlignPosition(combo, popup, tW);
pos = BI.DOM.getRightAlignPosition(combo, popup, tW, container);
}
pos.dir = "top," + pos.dir;
if (lrFirst) {
@ -543,11 +565,11 @@
case "bottom":
var tW = lrFirst ? extraHeight : extraWidth, tH = lrFirst ? extraWidth : extraHeight;
if (BI.DOM.isBottomSpaceEnough(combo, popup, tH)) {
top = BI.DOM.getBottomPosition(combo, popup, tH).top;
top = BI.DOM.getBottomPosition(combo, popup, tH, container).top;
if (leftRight[0] === "right") {
pos = BI.DOM.getLeftAlignPosition(combo, popup, tW, needAdaptHeight);
pos = BI.DOM.getLeftAlignPosition(combo, popup, tW, container);
} else {
pos = BI.DOM.getRightAlignPosition(combo, popup, tW);
pos = BI.DOM.getRightAlignPosition(combo, popup, tW, container);
}
pos.dir = "bottom," + pos.dir;
if (lrFirst) {
@ -648,13 +670,13 @@
},
getComboPosition: function (combo, popup, extraWidth, extraHeight, needAdaptHeight, directions, offsetStyle) {
getComboPosition: function (combo, popup, extraWidth, extraHeight, needAdaptHeight, directions, offsetStyle, container) {
extraWidth || (extraWidth = 0);
extraHeight || (extraHeight = 0);
var bodyHeight = BI.Widget._renderEngine.createElement("body").bounds().height - extraHeight;
var maxHeight = Math.min(popup.attr("maxHeight") || bodyHeight, bodyHeight);
popup.resetHeight && popup.resetHeight(maxHeight);
var position = BI.DOM.getComboPositionByDirections(combo, popup, extraWidth, extraHeight, needAdaptHeight, directions || ["bottom", "top", "right", "left"]);
var position = BI.DOM.getComboPositionByDirections(combo, popup, extraWidth, extraHeight, needAdaptHeight, directions || ["bottom", "top", "right", "left"], container);
switch (offsetStyle) {
case "center":
if (position.change) {
@ -679,6 +701,32 @@
popup.resetHeight && popup.resetHeight(Math.min(bodyHeight - position.top, maxHeight));
}
return position;
},
/**
* 获取position:fixed相对定位的元素
*/
getPositionRelativeContainingBlock: function (element) {
if (['html', 'body', '#document'].indexOf((element.nodeName || '').toLowerCase()) >= 0) {
// $FlowFixMe[incompatible-return]: assume body is always available
return element.ownerDocument.body;
}
function isExcept(node) {
var _computedStyle = getComputedStyle(node);
var transform = _computedStyle.transform;
var perspective = _computedStyle.perspective;
var filter = _computedStyle.filter;
var willChange = _computedStyle["will-change"];
return [transform, perspective, filter].some(value => value !== 'none') || (willChange === "transform");
}
if (isExcept(element)) {
return element;
}
return BI.DOM.getPositionRelativeContainingBlock(element.parentNode);
},
});
})();

Loading…
Cancel
Save