diff --git a/changelog.md b/changelog.md index 043dae7b7..0aecc31a7 100644 --- a/changelog.md +++ b/changelog.md @@ -1,5 +1,6 @@ # 更新日志 2.0(2021-12) +- 新增气泡弹框控件 - BI.point支持widget添加埋点 - childContext废弃,替换成provide - 支持BI.useContext获取上下文环境 diff --git a/src/base/combination/bubble.js b/src/base/combination/bubble.js new file mode 100644 index 000000000..cf0548fb1 --- /dev/null +++ b/src/base/combination/bubble.js @@ -0,0 +1,513 @@ +!(function () { + /** + * @class BI.Bubble + * @extends BI.Widget + */ + BI.Bubble = BI.inherit(BI.Widget, { + _defaultConfig: function () { + var conf = BI.Bubble.superclass._defaultConfig.apply(this, arguments); + return BI.extend(conf, { + baseCls: (conf.baseCls || "") + " bi-popper", + attributes: { + tabIndex: -1 + }, + trigger: "click", // click || hover || click-hover || "" + toggle: true, + direction: "", + placement: "bottom-start", // top-start/top/top-end/bottom-start/bottom/bottom-end/left-start/left/left-end/right-start/right/right-end + logic: { + dynamic: true + }, + container: null, // popupview放置的容器,默认为this.element + isDefaultInit: false, + destroyWhenHide: false, + hideWhenClickOutside: true, + showArrow: true, + hideWhenBlur: false, + isNeedAdjustHeight: true, // 是否需要高度调整 + isNeedAdjustWidth: true, + stopEvent: false, + stopPropagation: false, + adjustLength: 0, // 调整的距离 + adjustXOffset: 0, + adjustYOffset: 0, + hideChecker: BI.emptyFn, + offsetStyle: "left", // left,right,center + el: {}, + popup: {}, + comboClass: "bi-combo-popup", + hoverClass: "bi-combo-hover", + }); + }, + + render: function () { + var self = this, o = this.options; + this._initCombo(); + // 延迟绑定事件,这样可以将自己绑定的事情优先执行 + BI.nextTick(this._initPullDownAction.bind(this)); + this.combo.on(BI.Controller.EVENT_CHANGE, function (type, value, obj) { + if (self.isEnabled() && self.isValid()) { + if (type === BI.Events.EXPAND) { + self._popupView(); + } + if (type === BI.Events.COLLAPSE) { + self._hideView(); + } + if (type === BI.Events.EXPAND) { + self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); + self.fireEvent(BI.Bubble.EVENT_EXPAND); + } + if (type === BI.Events.COLLAPSE) { + self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); + self.isViewVisible() && self.fireEvent(BI.Bubble.EVENT_COLLAPSE); + } + if (type === BI.Events.CLICK) { + self.fireEvent(BI.Bubble.EVENT_TRIGGER_CHANGE, obj); + } + } + }); + + self.element.on("mouseenter." + self.getName(), function (e) { + if (self.isEnabled() && self.isValid() && self.combo.isEnabled() && self.combo.isValid()) { + self.element.addClass(o.hoverClass); + } + }); + self.element.on("mouseleave." + self.getName(), function (e) { + if (self.isEnabled() && self.isValid() && self.combo.isEnabled() && self.combo.isValid()) { + self.element.removeClass(o.hoverClass); + } + }); + + BI.createWidget(BI.extend({ + element: this + }, BI.LogicFactory.createLogic("vertical", BI.extend(o.logic, { + items: [ + {el: this.combo} + ] + })))); + o.isDefaultInit && (this._assertPopupView()); + }, + + _toggle: function (e) { + this._assertPopupViewRender(); + if (this.popupView.isVisible()) { + this._hideView(e); + } else { + if (this.isEnabled()) { + this._popupView(e); + } + } + }, + + _initPullDownAction: function () { + var self = this, o = this.options; + var evs = (this.options.trigger || "").split(","); + var st = function (e) { + if (o.stopEvent) { + e.stopEvent(); + } + if (o.stopPropagation) { + e.stopPropagation(); + } + }; + + var enterPopup = false; + + function hide (e) { + if (self.isEnabled() && self.isValid() && self.combo.isEnabled() && self.combo.isValid() && o.toggle === true) { + self._hideView(e); + self.fireEvent(BI.Controller.EVENT_CHANGE, BI.Events.COLLAPSE, "", self.combo); + self.fireEvent(BI.Bubble.EVENT_COLLAPSE); + } + self.popupView && self.popupView.element.off("mouseenter." + self.getName()).off("mouseleave." + self.getName()); + enterPopup = false; + } + + BI.each(evs, function (i, ev) { + switch (ev) { + case "hover": + self.element.on("mouseenter." + self.getName(), function (e) { + if (self.isEnabled() && self.isValid() && self.combo.isEnabled() && self.combo.isValid()) { + self._popupView(e); + self.fireEvent(BI.Controller.EVENT_CHANGE, BI.Events.EXPAND, "", self.combo); + self.fireEvent(BI.Bubble.EVENT_EXPAND); + } + }); + self.element.on("mouseleave." + self.getName(), function (e) { + if (self.popupView) { + self.popupView.element.on("mouseenter." + self.getName(), function (e) { + enterPopup = true; + self.popupView.element.on("mouseleave." + self.getName(), function (e) { + hide(e); + }); + self.popupView.element.off("mouseenter." + self.getName()); + }); + BI.defer(function () { + if (!enterPopup) { + hide(e); + } + }, 50); + } + }); + break; + case "click": + var debounce = BI.debounce(function (e) { + if (self.combo.element.__isMouseInBounds__(e)) { + if (self.isEnabled() && self.isValid() && self.combo.isEnabled() && self.combo.isValid()) { + // if (!o.toggle && self.isViewVisible()) { + // return; + // } + o.toggle ? self._toggle(e) : self._popupView(e); + if (self.isViewVisible()) { + self.fireEvent(BI.Controller.EVENT_CHANGE, BI.Events.EXPAND, "", self.combo); + self.fireEvent(BI.Bubble.EVENT_EXPAND); + } else { + self.fireEvent(BI.Controller.EVENT_CHANGE, BI.Events.COLLAPSE, "", self.combo); + self.fireEvent(BI.Bubble.EVENT_COLLAPSE); + } + } + } + }, BI.EVENT_RESPONSE_TIME, { + "leading": true, + "trailing": false + }); + self.element.off(ev + "." + self.getName()).on(ev + "." + self.getName(), function (e) { + debounce(e); + st(e); + }); + break; + case "click-hover": + var debounce = BI.debounce(function (e) { + if (self.combo.element.__isMouseInBounds__(e)) { + if (self.isEnabled() && self.isValid() && self.combo.isEnabled() && self.combo.isValid()) { + // if (self.isViewVisible()) { + // return; + // } + self._popupView(e); + if (self.isViewVisible()) { + self.fireEvent(BI.Controller.EVENT_CHANGE, BI.Events.EXPAND, "", self.combo); + self.fireEvent(BI.Bubble.EVENT_EXPAND); + } + } + } + }, BI.EVENT_RESPONSE_TIME, { + "leading": true, + "trailing": false + }); + self.element.off("click." + self.getName()).on("click." + self.getName(), function (e) { + debounce(e); + st(e); + }); + self.element.on("mouseleave." + self.getName(), function (e) { + if (self.popupView) { + self.popupView.element.on("mouseenter." + self.getName(), function (e) { + enterPopup = true; + self.popupView.element.on("mouseleave." + self.getName(), function (e) { + hide(e); + }); + self.popupView.element.off("mouseenter." + self.getName()); + }); + BI.delay(function () { + if (!enterPopup) { + hide(e); + } + }, 50); + } + }); + break; + } + }); + }, + + _initCombo: function () { + this.combo = BI.createWidget(this.options.el, { + value: this.options.value + }); + + if (this.options.showArrow) { + this.arrow = BI.createWidget({ + type: "bi.absolute", + cls: "bi-bubble-arrow", + items: [{ + type: "bi.layout", + cls: "bubble-arrow" + }] + }); + } + }, + + _assertPopupView: function () { + var self = this, o = this.options; + if (this.popupView == null) { + this.popupView = BI.createWidget(this.options.popup, { + type: "bi.bubble_popup_view", + value: o.value + }, this); + if (this.options.showArrow) { + BI.createWidget({ + type: "bi.absolute", + element: this.popupView, + items: [{ + el: this.arrow + }] + }); + } + this.popupView.on(BI.Controller.EVENT_CHANGE, function (type, value, obj) { + if (type === BI.Events.CLICK) { + self.combo.setValue(self.getValue()); + self.fireEvent(BI.Bubble.EVENT_CHANGE, value, obj); + } + self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); + }); + this.popupView.setVisible(false); + BI.nextTick(function () { + self.fireEvent(BI.Bubble.EVENT_AFTER_INIT); + }); + } + }, + + _assertPopupViewRender: function () { + this._assertPopupView(); + if (!this._rendered) { + BI.createWidget({ + type: "bi.vertical", + scrolly: false, + element: this.options.container || this, + items: [ + {el: this.popupView} + ] + }); + this._rendered = true; + } + }, + + _hideIf: function (e, skipTriggerChecker) { + // if (this.element.__isMouseInBounds__(e) || (this.popupView && this.popupView.element.__isMouseInBounds__(e))) { + // return; + // } + // BI-10290 公式combo双击公式内容会收起 + if (e && ((skipTriggerChecker !== true && this.element.find(e.target).length > 0) + || (this.popupView && this.popupView.element.find(e.target).length > 0) + || e.target.className === "CodeMirror-cursor" || BI.Widget._renderEngine.createElement(e.target).closest(".CodeMirror-hints").length > 0)) {// BI-9887 CodeMirror的公式弹框需要特殊处理下 + var directions = this.options.direction.split(","); + if (BI.contains(directions, "innerLeft") || BI.contains(directions, "innerRight")) { + // popup可以出现在trigger内部的combo,滚动时不需要消失,而是调整位置 + this.adjustWidth(); + this.adjustHeight(); + } + + return; + } + var isHide = this.options.hideChecker.apply(this, [e]); + if (isHide === false) { + return; + } + this._hideView(e); + return true; + }, + + _hideView: function (e) { + var o = this.options; + this.fireEvent(BI.Bubble.EVENT_BEFORE_HIDEVIEW); + if (this.options.destroyWhenHide === true) { + this.popupView && this.popupView.destroy(); + this.popupView = null; + this._rendered = false; + } else { + this.popupView && this.popupView.invisible(); + } + + if (!e || !this.combo.element.__isMouseInBounds__(e)) { + this.element.removeClass(this.options.hoverClass); + // 应对bi-focus-shadow在收起时不失焦 + this.element.blur(); + } + + if (this.popper) { + this.popper.destroy(); + this.popper = null; + } + + this.element.removeClass(this.options.comboClass); + + BI.Widget._renderEngine.createElement(document).unbind("mousedown." + this.getName()).unbind("mousewheel." + this.getName()); + BI.EVENT_BLUR && o.hideWhenBlur && BI.Widget._renderEngine.createElement(window).unbind("blur." + this.getName()); + this.fireEvent(BI.Bubble.EVENT_AFTER_HIDEVIEW); + }, + + _popupView: function (e) { + var self = this, o = this.options; + this._assertPopupViewRender(); + this.fireEvent(BI.Bubble.EVENT_BEFORE_POPUPVIEW); + // popupVisible是为了获取其宽高, 放到可视范围之外以防止在IE下闪一下 + this.popupView.css({left: -999999999, top: -99999999}); + this.popupView.visible(); + this.adjustWidth(e); + + if (this.popper) { + this.popper.destroy(); + } + var modifiers = [{ + name: "offset", + options: { + offset: function () { + return [o.adjustXOffset, (o.showArrow ? 9 : 0) + (o.adjustYOffset || o.adjustLength)]; + } + } + }]; + if (this.options.showArrow) { + modifiers.push({ + name: "arrow", + options: { + padding: 5, + element: this.arrow.element[0] + } + }); + } + this.popper = BI.Popper.createPopper(this.combo.element[0], this.popupView.element[0], { + placement: o.placement, + strategy: "fixed", + modifiers: modifiers + }); + + // this.adjustHeight(e); + + this.element.addClass(this.options.comboClass); + o.hideWhenClickOutside && BI.Widget._renderEngine.createElement(document).unbind("mousedown." + this.getName()); + BI.EVENT_BLUR && o.hideWhenBlur && BI.Widget._renderEngine.createElement(window).unbind("blur." + this.getName()); + + o.hideWhenClickOutside && BI.Widget._renderEngine.createElement(document).bind("mousedown." + this.getName(), BI.bind(this._hideIf, this)); + BI.EVENT_BLUR && o.hideWhenBlur && BI.Widget._renderEngine.createElement(window).bind("blur." + this.getName(), BI.bind(this._hideIf, this)); + this.fireEvent(BI.Bubble.EVENT_AFTER_POPUPVIEW); + }, + + adjustWidth: function (e) { + var o = this.options; + if (!this.popupView) { + return; + } + if (o.isNeedAdjustWidth === true) { + this.resetListWidth(""); + var width = this.popupView.element.outerWidth(); + var maxW = this.element.outerWidth() || o.width; + // BI-93885 最大列宽算法调整 + if (maxW < 500) { + if (width >= 500) { + maxW = 500; + } else if (width > maxW) { + // 防止小数导致差那么一点 + maxW = width + 1; + } + } + + // if (width > maxW + 80) { + // maxW = maxW + 80; + // } else if (width > maxW) { + // maxW = width; + // } + this.resetListWidth(maxW < 100 ? 100 : maxW); + } + }, + + adjustHeight: function () { + + }, + + resetListHeight: function (h) { + this._assertPopupView(); + this.popupView.resetHeight && this.popupView.resetHeight(h); + }, + + resetListWidth: function (w) { + this._assertPopupView(); + this.popupView.resetWidth && this.popupView.resetWidth(w); + }, + + populate: function (items) { + this._assertPopupView(); + this.popupView.populate.apply(this.popupView, arguments); + this.combo.populate && this.combo.populate.apply(this.combo, arguments); + }, + + _setEnable: function (arg) { + BI.Bubble.superclass._setEnable.apply(this, arguments); + if (arg === true) { + this.element.removeClass("base-disabled disabled"); + } else if (arg === false) { + this.element.addClass("base-disabled disabled"); + } + !arg && this.element.removeClass(this.options.hoverClass); + !arg && this.isViewVisible() && this._hideView(); + }, + + setValue: function (v) { + this.combo.setValue(v); + if (BI.isNull(this.popupView)) { + this.options.popup.value = v; + } else { + this.popupView.setValue(v); + } + }, + + getValue: function () { + if (BI.isNull(this.popupView)) { + return this.options.popup.value; + } else { + return this.popupView.getValue(); + } + }, + + isViewVisible: function () { + return this.isEnabled() && this.combo.isEnabled() && !!this.popupView && this.popupView.isVisible(); + }, + + showView: function (e) { + // 减少popup 调整宽高的次数 + if (this.isEnabled() && this.combo.isEnabled() && !this.isViewVisible()) { + this._popupView(e); + } + }, + + hideView: function (e) { + this._hideView(e); + }, + + getView: function () { + return this.popupView; + }, + + getPopupPosition: function () { + return this.position; + }, + + toggle: function () { + this._toggle(); + }, + + destroyed: function () { + BI.Widget._renderEngine.createElement(document) + .unbind("click." + this.getName()) + .unbind("mousedown." + this.getName()) + .unbind("mouseenter." + this.getName()) + .unbind("mouseleave." + this.getName()); + BI.Widget._renderEngine.createElement(window) + .unbind("blur." + this.getName()); + this.popper && this.popper.destroy(); + this.popper = null; + this.popupView && this.popupView._destroy(); + } + }); + BI.Bubble.EVENT_TRIGGER_CHANGE = "EVENT_TRIGGER_CHANGE"; + BI.Bubble.EVENT_CHANGE = "EVENT_CHANGE"; + BI.Bubble.EVENT_EXPAND = "EVENT_EXPAND"; + BI.Bubble.EVENT_COLLAPSE = "EVENT_COLLAPSE"; + BI.Bubble.EVENT_AFTER_INIT = "EVENT_AFTER_INIT"; + + + BI.Bubble.EVENT_BEFORE_POPUPVIEW = "EVENT_BEFORE_POPUPVIEW"; + BI.Bubble.EVENT_AFTER_POPUPVIEW = "EVENT_AFTER_POPUPVIEW"; + BI.Bubble.EVENT_BEFORE_HIDEVIEW = "EVENT_BEFORE_HIDEVIEW"; + BI.Bubble.EVENT_AFTER_HIDEVIEW = "EVENT_AFTER_HIDEVIEW"; + + BI.shortcut("bi.bubble", BI.Bubble); +}()); diff --git a/src/base/combination/combo.js b/src/base/combination/combo.js index 540b693b8..94c2fab8a 100644 --- a/src/base/combination/combo.js +++ b/src/base/combination/combo.js @@ -4,9 +4,9 @@ * @class BI.Combo * @extends BI.Widget */ - BI.Combo = BI.inherit(BI.Widget, { + BI.Combo = BI.inherit(BI.Bubble, { _defaultConfig: function () { - var conf = BI.Combo.superclass._defaultConfig.apply(this, arguments); + var conf = BI.Bubble.superclass._defaultConfig.apply(this, arguments); return BI.extend(conf, { baseCls: (conf.baseCls || "") + " bi-combo" + (BI.isIE() ? " hack" : ""), attributes: { @@ -23,6 +23,7 @@ destroyWhenHide: false, hideWhenBlur: true, hideWhenAnotherComboOpen: false, + hideWhenClickOutside: true, isNeedAdjustHeight: true, // 是否需要高度调整 isNeedAdjustWidth: true, stopEvent: false, @@ -94,137 +95,6 @@ }, this)); }, - _toggle: function (e) { - this._assertPopupViewRender(); - if (this.popupView.isVisible()) { - this._hideView(e); - } else { - if (this.isEnabled()) { - this._popupView(e); - } - } - }, - - _initPullDownAction: function () { - var self = this, o = this.options; - var evs = (this.options.trigger || "").split(","); - var st = function (e) { - if (o.stopEvent) { - e.stopEvent(); - } - if (o.stopPropagation) { - e.stopPropagation(); - } - }; - - var enterPopup = false; - - function hide(e) { - if (self.isEnabled() && self.isValid() && self.combo.isEnabled() && self.combo.isValid() && o.toggle === true) { - self._hideView(e); - self.fireEvent(BI.Controller.EVENT_CHANGE, BI.Events.COLLAPSE, "", self.combo); - self.fireEvent(BI.Combo.EVENT_COLLAPSE); - } - self.popupView && self.popupView.element.off("mouseenter." + self.getName()).off("mouseleave." + self.getName()); - enterPopup = false; - } - - BI.each(evs, function (i, ev) { - switch (ev) { - case "hover": - self.element.on("mouseenter." + self.getName(), function (e) { - if (self.isEnabled() && self.isValid() && self.combo.isEnabled() && self.combo.isValid()) { - self._popupView(e); - self.fireEvent(BI.Controller.EVENT_CHANGE, BI.Events.EXPAND, "", self.combo); - self.fireEvent(BI.Combo.EVENT_EXPAND); - } - }); - self.element.on("mouseleave." + self.getName(), function (e) { - if (self.popupView) { - self.popupView.element.on("mouseenter." + self.getName(), function (e) { - enterPopup = true; - self.popupView.element.on("mouseleave." + self.getName(), function (e) { - hide(e); - }); - self.popupView.element.off("mouseenter." + self.getName()); - }); - BI.defer(function () { - if (!enterPopup) { - hide(e); - } - }, 50); - } - }); - break; - case "click": - var debounce = BI.debounce(function (e) { - if (self.combo.element.__isMouseInBounds__(e)) { - if (self.isEnabled() && self.isValid() && self.combo.isEnabled() && self.combo.isValid()) { - // if (!o.toggle && self.isViewVisible()) { - // return; - // } - o.toggle ? self._toggle(e) : self._popupView(e); - if (self.isViewVisible()) { - self.fireEvent(BI.Controller.EVENT_CHANGE, BI.Events.EXPAND, "", self.combo); - self.fireEvent(BI.Combo.EVENT_EXPAND); - } else { - self.fireEvent(BI.Controller.EVENT_CHANGE, BI.Events.COLLAPSE, "", self.combo); - self.fireEvent(BI.Combo.EVENT_COLLAPSE); - } - } - } - }, BI.EVENT_RESPONSE_TIME, { - "leading": true, - "trailing": false - }); - self.element.off(ev + "." + self.getName()).on(ev + "." + self.getName(), function (e) { - debounce(e); - st(e); - }); - break; - case "click-hover": - var debounce = BI.debounce(function (e) { - if (self.combo.element.__isMouseInBounds__(e)) { - if (self.isEnabled() && self.isValid() && self.combo.isEnabled() && self.combo.isValid()) { - // if (self.isViewVisible()) { - // return; - // } - self._popupView(e); - if (self.isViewVisible()) { - self.fireEvent(BI.Controller.EVENT_CHANGE, BI.Events.EXPAND, "", self.combo); - self.fireEvent(BI.Combo.EVENT_EXPAND); - } - } - } - }, BI.EVENT_RESPONSE_TIME, { - "leading": true, - "trailing": false - }); - self.element.off("click." + self.getName()).on("click." + self.getName(), function (e) { - debounce(e); - st(e); - }); - self.element.on("mouseleave." + self.getName(), function (e) { - if (self.popupView) { - self.popupView.element.on("mouseenter." + self.getName(), function (e) { - enterPopup = true; - self.popupView.element.on("mouseleave." + self.getName(), function (e) { - hide(e); - }); - self.popupView.element.off("mouseenter." + self.getName()); - }); - BI.delay(function () { - if (!enterPopup) { - hide(e); - } - }, 50); - } - }); - break; - } - }); - }, - _initCombo: function () { this.combo = BI.createWidget(this.options.el, { value: this.options.value @@ -252,46 +122,6 @@ } }, - _assertPopupViewRender: function () { - this._assertPopupView(); - if (!this._rendered) { - BI.createWidget({ - type: "bi.vertical", - scrolly: false, - element: this.options.container || this, - items: [ - { el: this.popupView } - ] - }); - this._rendered = true; - } - }, - - _hideIf: function (e, skipTriggerChecker) { - // if (this.element.__isMouseInBounds__(e) || (this.popupView && this.popupView.element.__isMouseInBounds__(e))) { - // return; - // } - // BI-10290 公式combo双击公式内容会收起 - if (e && ((skipTriggerChecker !== true && this.element.find(e.target).length > 0) - || (this.popupView && this.popupView.element.find(e.target).length > 0) - || e.target.className === "CodeMirror-cursor" || BI.Widget._renderEngine.createElement(e.target).closest(".CodeMirror-hints").length > 0)) {// BI-9887 CodeMirror的公式弹框需要特殊处理下 - var directions = this.options.direction.split(","); - if (BI.contains(directions, "innerLeft") || BI.contains(directions, "innerRight")) { - // popup可以出现在trigger内部的combo,滚动时不需要消失,而是调整位置 - this.adjustWidth(); - this.adjustHeight(); - } - - return; - } - var isHide = this.options.hideChecker.apply(this, [e]); - if (isHide === false) { - return; - } - this._hideView(e); - return true; - }, - _hideView: function (e) { var o = this.options; this.fireEvent(BI.Combo.EVENT_BEFORE_HIDEVIEW); @@ -336,42 +166,16 @@ this.adjustHeight(e); this.element.addClass(this.options.comboClass); - BI.Widget._renderEngine.createElement(document).unbind("mousedown." + this.getName()).unbind("mousewheel." + this.getName()); + o.hideWhenClickOutside && BI.Widget._renderEngine.createElement(document).unbind("mousedown." + this.getName()).unbind("mousewheel." + this.getName()); + BI.Widget._renderEngine.createElement(document).unbind("mousewheel." + this.getName()); BI.EVENT_BLUR && o.hideWhenBlur && BI.Widget._renderEngine.createElement(window).unbind("blur." + this.getName()); - BI.Widget._renderEngine.createElement(document).bind("mousedown." + this.getName(), BI.bind(this._hideIf, this)).bind("mousewheel." + this.getName(), BI.bind(this._hideIf, this)); + o.hideWhenClickOutside && BI.Widget._renderEngine.createElement(document).bind("mousedown." + this.getName(), BI.bind(this._hideIf, this)).bind("mousewheel." + this.getName(), BI.bind(this._hideIf, this)); + BI.Widget._renderEngine.createElement(document).bind("mousewheel." + this.getName(), BI.bind(this._hideIf, this)); BI.EVENT_BLUR && o.hideWhenBlur && BI.Widget._renderEngine.createElement(window).bind("blur." + this.getName(), BI.bind(this._hideIf, this)); this.fireEvent(BI.Combo.EVENT_AFTER_POPUPVIEW); }, - adjustWidth: function (e) { - var o = this.options; - if (!this.popupView) { - return; - } - if (o.isNeedAdjustWidth === true) { - this.resetListWidth(""); - var width = this.popupView.element.outerWidth(); - var maxW = this.element.outerWidth() || o.width; - // BI-93885 最大列宽算法调整 - if (maxW < 500) { - if (width >= 500) { - maxW = 500; - } else if(width > maxW) { - // 防止小数导致差那么一点 - maxW = width + 1; - } - } - - // if (width > maxW + 80) { - // maxW = maxW + 80; - // } else if (width > maxW) { - // maxW = width; - // } - this.resetListWidth(maxW < 100 ? 100 : maxW); - } - }, - adjustHeight: function (e) { var o = this.options, p = {}; if (!this.popupView) { @@ -484,84 +288,12 @@ this.popupView.setVisible(isVisible); }, - resetListHeight: function (h) { - this._assertPopupView(); - this.popupView.resetHeight && this.popupView.resetHeight(h); - }, - - resetListWidth: function (w) { - this._assertPopupView(); - this.popupView.resetWidth && this.popupView.resetWidth(w); - }, - - populate: function (items) { - this._assertPopupView(); - this.popupView.populate.apply(this.popupView, arguments); - this.combo.populate && this.combo.populate.apply(this.combo, arguments); - }, - - _setEnable: function (arg) { - BI.Combo.superclass._setEnable.apply(this, arguments); - if (arg === true) { - this.element.removeClass("base-disabled disabled"); - } else if (arg === false) { - this.element.addClass("base-disabled disabled"); - } - !arg && this.element.removeClass(this.options.hoverClass); - !arg && this.isViewVisible() && this._hideView(); - }, - - setValue: function (v) { - this.combo.setValue(v); - if (BI.isNull(this.popupView)) { - this.options.popup.value = v; - } else { - this.popupView.setValue(v); - } - }, - - getValue: function () { - if (BI.isNull(this.popupView)) { - return this.options.popup.value; - } else { - return this.popupView.getValue(); - } - }, - - isViewVisible: function () { - return this.isEnabled() && this.combo.isEnabled() && !!this.popupView && this.popupView.isVisible(); - }, - - showView: function (e) { - // 减少popup 调整宽高的次数 - if (this.isEnabled() && this.combo.isEnabled() && !this.isViewVisible()) { - this._popupView(e); - } - }, - - hideView: function (e) { - this._hideView(e); - }, - - getView: function () { - return this.popupView; - }, - - getPopupPosition: function () { - return this.position; - }, - - toggle: function () { - this._toggle(); - }, - destroyed: function () { BI.Widget._renderEngine.createElement(document) .unbind("click." + this.getName()) .unbind("mousedown." + this.getName()) .unbind("mousewheel." + this.getName()) .unbind("mouseenter." + this.getName()) - .unbind("mousemove." + this.getName()) .unbind("mouseleave." + this.getName()); BI.Widget._renderEngine.createElement(window) .unbind("blur." + this.getName()); diff --git a/src/case/combo/bubblecombo/combo.bubble.js b/src/case/combo/bubblecombo/combo.bubble.js index 8a0af89b3..dd77173f3 100644 --- a/src/case/combo/bubblecombo/combo.bubble.js +++ b/src/case/combo/bubblecombo/combo.bubble.js @@ -137,6 +137,7 @@ BI.BubbleCombo = BI.inherit(BI.Widget, { this.triangle && this.triangle.destroy(); this.triangle = BI.createWidget(op, { type: "bi.center_adapt", + scrollable: false, cls: "button-combo-triangle-wrapper", items: [{ type: "bi.layout", diff --git a/src/less/base/combo/combo.bubble.less b/src/less/base/combo/combo.bubble.less index 337077402..fe2867772 100644 --- a/src/less/base/combo/combo.bubble.less +++ b/src/less/base/combo/combo.bubble.less @@ -32,7 +32,68 @@ } } +.bi-popup-view[data-popper-placement^='top'] { + > .bi-bubble-arrow { + bottom: -10px; + > .bubble-arrow { + bottom: 6px; + } + } +} +.bi-popup-view[data-popper-placement^='bottom'] { + > .bi-bubble-arrow { + top: -10px; + > .bubble-arrow { + top: 6px; + } + } +} +.bi-popup-view[data-popper-placement^='left'] { + > .bi-bubble-arrow { + right: -10px; + > .bubble-arrow { + right: 6px; + } + } +} +.bi-popup-view[data-popper-placement^='right'] { + > .bi-bubble-arrow { + left: -10px; + > .bubble-arrow { + left: 6px; + } + } +} + +.bi-bubble-arrow { + width: 10px; + height: 10px; + overflow: hidden; + .bubble-arrow { + width: 10px; + height: 10px; + position: absolute; + &:before { + width: 10px; + height: 10px; + position: absolute; + content: ""; + background: @color-bi-background-default; + top: 0; + left: 0; + transition: transform 0.2s ease-out 0s, visibility 0.2s ease-out 0s; + visibility: visible; + transform: translateX(0px) rotate(-135deg); + transform-origin: center center; + .box-shadow(3px 3px 10px 0,rgba(0,0,0,6%)); + } + } +} + .bi-theme-dark { + .bubble-arrow:before { + background: @color-bi-background-default-theme-dark; + } .bi-bubble-combo { & .bubble-combo-triangle-left, & .bubble-combo-triangle-right, & .bubble-combo-triangle-top, & .bubble-combo-triangle-bottom { &:before {