import { VTapeLayout, HTapeLayout, AbsoluteLayout, Layout, VerticalLayout, Widget, shortcut, isPlainObject, extend } from "@/core"; import { Label, IconButton } from "../single"; /** * Popover弹出层, * @class BI.Popover * @extends BI.Widget */ @shortcut() export class Drawer extends Widget { SIZE = { SMALL: "small", NORMAL: "normal", BIG: "big", }; props = { baseCls: "bi-drawer bi-card", size: "normal", placement: "right", // top/bottom/left/right header: null, headerHeight: 40, body: null, closable: true, // BI-40839 是否显示右上角的关闭按钮 bodyHgap: 20, bodyTgap: 10, bodyBgap: 10, }; static xtype = "bi.drawer"; static EVENT_CLOSE = "EVENT_CLOSE"; static EVENT_OPEN = "EVENT_OPEN"; _getSuitableSize() { const { size, height, placement, width } = this.options; let sizeValue = 0; switch (size) { case "big": sizeValue = 736; break; case "small": sizeValue = 200; break; case "normal": default: sizeValue = 378; break; } if (placement === "top" || placement === "bottom") { return { height: height || sizeValue, }; } if (placement === "left" || placement === "right") { return { width: width || sizeValue, }; } } render() { const { header, headerHeight, closable, body, bodyHgap, bodyTgap, bodyBgap } = this.options; const items = [ { el: { type: HTapeLayout.xtype, cls: "bi-message-title bi-header-background", items: [ { type: AbsoluteLayout.xtype, items: [ { el: isPlainObject(header) ? extend({}, header, { extraCls: "bi-font-bold", }) : { type: Label.xtype, cls: "bi-font-bold", height: headerHeight, text: header, title: header, textAlign: "left", }, left: 20, top: 0, right: 0, bottom: 0, } ], }, { el: closable ? { type: IconButton.xtype, cls: "bi-message-close close-font", height: headerHeight, handler: () => { this.close(); }, } : { type: Layout.xtype, }, width: 56, } ], height: headerHeight, }, height: headerHeight, }, { el: { type: VerticalLayout.xtype, scrolly: true, cls: "drawer-body", ref: _ref => { this.body = _ref; }, items: [ { el: body, } ], }, hgap: bodyHgap, tgap: bodyTgap, bgap: bodyBgap, } ]; return extend( { type: VTapeLayout.xtype, items, }, this._getSuitableSize() ); } mounted() { const { placement } = this.options; switch (placement) { case "right": this.element.css({ top: 0, left: "100%", bottom: 0, }); break; case "left": this.element.css({ top: 0, right: "100%", bottom: 0, }); break; case "top": this.element.css({ left: 0, right: 0, bottom: "100%", }); break; case "bottom": this.element.css({ left: 0, right: 0, top: "100%", }); break; default: break; } } show(callback) { const { placement } = this.options; requestAnimationFrame(() => { const size = this._getSuitableSize(); switch (placement) { case "right": this.element.css({ left: `calc(100% - ${size.width}px)`, }); break; case "left": this.element.css({ right: `calc(100% - ${size.width}px)`, }); break; case "top": this.element.css({ bottom: `calc(100% - ${size.height}px)`, }); break; case "bottom": this.element.css({ top: `calc(100% - ${size.height}px)`, }); break; default: break; } callback && callback(); }); } hide(callback) { const { placement } = this.options; requestAnimationFrame(() => { switch (placement) { case "right": this.element.css({ left: "100%", }); break; case "left": this.element.css({ right: "100%", }); break; case "top": this.element.css({ bottom: "100%", }); break; case "bottom": this.element.css({ top: "100%", }); break; default: break; } setTimeout(callback, 300); }); } open() { this.show(() => { this.fireEvent(Drawer.EVENT_OPEN); }); } close() { this.hide(() => { this.fireEvent(Drawer.EVENT_CLOSE); }); } setZindex(zindex) { this.element.css({ "z-index": zindex }); } destroyed() {} }