diff --git a/examples/dev.html b/examples/dev.html index 092b90c16..009f32b8d 100644 --- a/examples/dev.html +++ b/examples/dev.html @@ -2,7 +2,7 @@ - + @@ -24,6 +24,13 @@ height: 200, width: 600 }, + beforeInit: function () { + return new Promise(function (resolve) { + setTimeout(function () { + resolve(); + }, 1000); + }); + }, _store: function () { return BI.Models.getModel("demo.model"); }, @@ -49,7 +56,7 @@ type: "bi.button", text: "点击", handler: function () { - store.model.columnSize = [300, "fill"] + store.model.columnSize = [300, "fill"]; } }] }] diff --git a/package.json b/package.json index 545bac21e..fbbb2e06a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "fineui", - "version": "2.0.20211110155219", + "version": "2.0.20211116211231", "description": "fineui", "main": "dist/fineui.min.js", "types": "dist/lib/index.d.ts", 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/base/single/editor/editor.multifile.js b/src/base/single/editor/editor.multifile.js index 68b5bcc2e..1175d01c7 100644 --- a/src/base/single/editor/editor.multifile.js +++ b/src/base/single/editor/editor.multifile.js @@ -91,6 +91,12 @@ BI.MultifileEditor = BI.inherit(BI.Widget, { this.file.upload(); }, + sendFiles: function (files) { + this._reset(); + + this.file.sendFiles(files); + }, + reset: function () { this._reset(); } diff --git a/src/base/single/input/file.js b/src/base/single/input/file.js index fa589681b..904fbfcf5 100644 --- a/src/base/single/input/file.js +++ b/src/base/single/input/file.js @@ -683,6 +683,16 @@ } }, + sendFiles: function (files) { + if (!this.wrap) return; + + this.wrap.dom.input.files = files; + + var event = new CustomEvent("change"); + + this.wrap.dom.input.dispatchEvent(event); + }, + _setEnable: function (enable) { BI.File.superclass._setEnable.apply(this, arguments); if (enable === true) { diff --git a/src/base/single/tip/tip.toast.js b/src/base/single/tip/tip.toast.js index 68e59a88a..aca66e47a 100644 --- a/src/base/single/tip/tip.toast.js +++ b/src/base/single/tip/tip.toast.js @@ -61,13 +61,13 @@ BI.Toast = BI.inherit(BI.Tip, { cls: cls + " toast-icon", width: 36 }, { - el: BI.isString(o.text) ? { + el: BI.isPlainObject(o.text) ? o.text : { type: "bi.label", whiteSpace: "normal", text: o.text, textHeight: 16, textAlign: "left" - } : o.text, + }, rgap: o.autoClose ? this._const.hgap : 0 }]; diff --git a/src/core/4.widget.js b/src/core/4.widget.js index c3d1e0bc5..90ea28ad8 100644 --- a/src/core/4.widget.js +++ b/src/core/4.widget.js @@ -133,7 +133,10 @@ if (self.options.beforeRender || self.beforeRender) { self.__async = true; - (self.options.beforeRender || self.beforeRender).call(self, render); + var beforeRenderResult = (self.options.beforeRender || self.beforeRender).call(self, render); + if (beforeRenderResult instanceof Promise) { + beforeRenderResult.then(render); + } } else { self._render(); self.__afterRender(); @@ -142,7 +145,10 @@ if (this.options.beforeInit || this.beforeInit) { this.__asking = true; - (this.options.beforeInit || this.beforeInit).call(this, init); + var beforeInitResult = (this.options.beforeInit || this.beforeInit).call(this, init); + if (beforeInitResult instanceof Promise) { + beforeInitResult.then(init); + } } else { init(); } 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 +} diff --git a/src/polyfill/event.js b/src/polyfill/event.js new file mode 100644 index 000000000..346ec16c8 --- /dev/null +++ b/src/polyfill/event.js @@ -0,0 +1,15 @@ +(function () { + if (typeof window.CustomEvent === "function") return false; // If not IE + + function CustomEvent (event, params) { + params = params || { bubbles: false, cancelable: false, detail: undefined }; + var evt = document.createEvent("CustomEvent"); + evt.initCustomEvent(event, params.bubbles, params.cancelable, params.detail); + + return evt; + } + + CustomEvent.prototype = window.Event.prototype; + + window.CustomEvent = CustomEvent; +}()); diff --git a/typescript/widget/editor/editor.multifile.ts b/typescript/widget/editor/editor.multifile.ts index 3a29e0960..905d423e6 100644 --- a/typescript/widget/editor/editor.multifile.ts +++ b/typescript/widget/editor/editor.multifile.ts @@ -30,4 +30,6 @@ export declare class MultifileEditor extends Widget { size: number; type: string; }[]; + + sendFiles(files: FileList): void; }