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;
}