fineui是帆软报表和BI产品线所使用的前端框架。
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

263 lines
7.2 KiB

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() {}
}