diff --git a/src/base/0.base.js b/src/base/0.base.js index e5eec1d1a..a8aa11a21 100644 --- a/src/base/0.base.js +++ b/src/base/0.base.js @@ -5,6 +5,7 @@ BI.prepares.push(function () { BI.Bubbles = new BI.BubblesController(); BI.Tooltips = new BI.TooltipsController(); BI.Popovers = new BI.PopoverController(); + BI.Drawers = new BI.DrawerController(); BI.Broadcasts = new BI.BroadcastController(); BI.StyleLoaders = new BI.StyleLoaderManager(); }); diff --git a/src/base/layer/layer.drawer.js b/src/base/layer/layer.drawer.js new file mode 100644 index 000000000..6b93a4324 --- /dev/null +++ b/src/base/layer/layer.drawer.js @@ -0,0 +1,192 @@ +/** + * Popover弹出层, + * @class BI.Popover + * @extends BI.Widget + */ +BI.Drawer = BI.inherit(BI.Widget, { + props: { + baseCls: "bi-drawer bi-card", + placement: "right", // top/bottom/left/right + header: null, + headerHeight: 40, + body: null, + closable: true, // BI-40839 是否显示右上角的关闭按钮 + bodyHgap: 20, + bodyTgap: 10, + bodyBgap: 10 + }, + + render: function () { + var self = this; + var o = this.options; + var items = [{ + el: { + type: "bi.htape", + cls: "bi-message-title bi-header-background", + items: [{ + type: "bi.absolute", + items: [{ + el: BI.isPlainObject(o.header) ? BI.extend({}, o.header, { + extraCls: "bi-font-bold" + }) : { + type: "bi.label", + cls: "bi-font-bold", + height: o.headerHeight, + text: o.header, + title: o.header, + textAlign: "left" + }, + left: 20, + top: 0, + right: 0, + bottom: 0 + }] + }, { + el: o.closable ? { + type: "bi.icon_button", + cls: "bi-message-close close-font", + height: o.headerHeight, + handler: function () { + self.close(); + } + } : { + type: "bi.layout" + }, + width: 56 + }], + height: o.headerHeight + }, + height: o.headerHeight + }, { + el: { + type: "bi.vertical", + scrolly: true, + cls: "drawer-body", + ref: function () { + self.body = this; + }, + items: [{ + el: o.body + }] + }, + hgap: o.bodyHgap, + tgap: o.bodyTgap, + bgap: o.bodyBgap + }]; + + return { + type: "bi.vtape", + items: items + }; + }, + + mounted: function () { + var self = this, o = this.options; + switch (o.placement) { + case "right": + self.element.css({ + top: 0, + left: "100%", + bottom: 0 + }); + break; + case "left": + self.element.css({ + top: 0, + right: "100%", + bottom: 0 + }); + break; + case "top": + self.element.css({ + left: 0, + right: 0, + bottom: "100%" + }); + break; + case "bottom": + self.element.css({ + left: 0, + right: 0, + top: "100%" + }); + break; + } + }, + + show: function (callback) { + var self = this, o = this.options; + requestAnimationFrame(function () { + switch (o.placement) { + case "right": + self.element.css({ + transform: "translateX(-" + self.getWidth() + "px)" + }); + break; + case "left": + self.element.css({ + transform: "translateX(" + self.getWidth() + "px)" + }); + break; + case "top": + self.element.css({ + transform: "translateY(" + self.getHeight() + "px)" + }); + break; + case "bottom": + self.element.css({ + transform: "translateY(-" + self.getHeight() + "px)" + }); + break; + } + callback && callback(); + }); + }, + + hide: function (callback) { + var self = this, o = this.options; + requestAnimationFrame(function () { + switch (o.placement) { + case "right": + case "left": + self.element.css({ + transform: "translateX(0px)" + }); + break; + case "top": + case "bottom": + self.element.css({ + transform: "translateY(0px)" + }); + break; + } + setTimeout(callback, 300) + }); + }, + + open: function () { + var self = this; + this.show(function () { + self.fireEvent(BI.Drawer.EVENT_OPEN); + }); + }, + + close: function () { + var self = this; + this.hide(function () { + self.fireEvent(BI.Drawer.EVENT_CLOSE); + }); + }, + + setZindex: function (zindex) { + this.element.css({"z-index": zindex}); + }, + + destroyed: function () { + } +}); + +BI.shortcut("bi.drawer", BI.Drawer); + +BI.Drawer.EVENT_CLOSE = "EVENT_CLOSE"; +BI.Drawer.EVENT_OPEN = "EVENT_OPEN"; diff --git a/src/core/controller/controller.drawer.js b/src/core/controller/controller.drawer.js new file mode 100644 index 000000000..1b7bae664 --- /dev/null +++ b/src/core/controller/controller.drawer.js @@ -0,0 +1,161 @@ +/** + * guy + * popover弹出层控制器, z-index在100w层级 + * @class BI.popoverController + * @extends BI.Controller + */ +BI.DrawerController = BI.inherit(BI.Controller, { + props: function () { + return { + modal: true, // 模态窗口 + render: "body" + }; + }, + + init: function () { + this.modal = this.options.modal; + this.floatManager = {}; + this.floatLayer = {}; + this.floatContainer = {}; + this.floatOpened = {}; + this.zindex = BI.zIndex_popover; + this.zindexMap = {}; + }, + + create: function (name, options, context) { + if (this.has(name)) { + return this; + } + var popover = BI.createWidget(options || {}, { + type: "bi.drawer" + }, context); + this.add(name, popover, options, context); + return this; + }, + + open: function (name) { + var self = this, o = this.options; + if (!this.has(name)) { + return this; + } + if (!this.floatOpened[name]) { + this.floatOpened[name] = true; + var container = this.floatContainer[name]; + container.element.css("zIndex", this.zindex++); + this.modal && container.element.__hasZIndexMask__(this.zindexMap[name]) && container.element.__releaseZIndexMask__(this.zindexMap[name]); + this.zindexMap[name] = this.zindex; + if (this.modal) { + var mask = container.element.__buildZIndexMask__(this.zindex++); + mask.click(function () { + mask.destroy(); + self.get(name).close(); + }); + } + this.get(name).setZindex(this.zindex++); + this.floatContainer[name].visible(); + var popover = this.get(name); + popover.show && popover.show(); + } + return this; + }, + + close: function (name) { + if (!this.has(name)) { + return this; + } + if (this.floatOpened[name]) { + delete this.floatOpened[name]; + this.floatContainer[name].invisible(); + this.modal && this.floatContainer[name].element.__releaseZIndexMask__(this.zindexMap[name]); + } + return this; + }, + + show: function (name) { + return this.open(name); + }, + + hide: function (name) { + return this.close(name); + }, + + isVisible: function (name) { + return this.has(name) && this.floatOpened[name] === true; + }, + + add: function (name, popover, options, context) { + var self = this; + options || (options = {}); + if (this.has(name)) { + return this; + } + this.floatContainer[name] = BI.createWidget({ + type: "bi.absolute", + cls: "bi-popup-view", + items: [{ + el: (this.floatLayer[name] = BI.createWidget({ + type: "bi.absolute", + items: [popover] + }, context)), + left: 0, + right: 0, + top: 0, + bottom: 0 + }] + }); + this.floatManager[name] = popover; + (function (key) { + popover.on(BI.Drawer.EVENT_CLOSE, function () { + self.close(key); + }); + })(name); + BI.createWidget({ + type: "bi.absolute", + element: options.container || this.options.render, + items: [{ + el: this.floatContainer[name], + left: 0, + right: 0, + top: 0, + bottom: 0 + }] + }); + return this; + }, + + get: function (name) { + return this.floatManager[name]; + }, + + has: function (name) { + return BI.isNotNull(this.floatManager[name]); + }, + + remove: function (name) { + if (!this.has(name)) { + return this; + } + this.floatContainer[name].destroy(); + this.modal && this.floatContainer[name].element.__releaseZIndexMask__(this.zindexMap[name]); + delete this.floatManager[name]; + delete this.floatLayer[name]; + delete this.zindexMap[name]; + delete this.floatContainer[name]; + delete this.floatOpened[name]; + return this; + }, + + removeAll: function () { + var self = this; + BI.each(this.floatContainer, function (name, container) { + container.destroy(); + self.modal && self.floatContainer[name].element.__releaseZIndexMask__(self.zindexMap[name]); + }); + this.floatManager = {}; + this.floatLayer = {}; + this.floatContainer = {}; + this.floatOpened = {}; + this.zindexMap = {}; + return this; + } +}); diff --git a/src/less/base/view/drawer.less b/src/less/base/view/drawer.less new file mode 100644 index 000000000..f364457e3 --- /dev/null +++ b/src/less/base/view/drawer.less @@ -0,0 +1,6 @@ +@import "../../index"; + +.bi-drawer { + .box-shadow(-6px 0 16px -8px #00000014, -9px 0 28px #0000000d, -12px 0 48px 16px #00000008); + .transition(transform .3s cubic-bezier(.23, 1, .32, 1), box-shadow .3s cubic-bezier(.23, 1, .32, 1)); +} diff --git a/src/less/base/view/popover.less b/src/less/base/view/popover.less index 4600d797c..27b65a895 100644 --- a/src/less/base/view/popover.less +++ b/src/less/base/view/popover.less @@ -2,4 +2,4 @@ .bi-popover { border: 1px solid transparent; -} \ No newline at end of file +}