@whitesev/pops
Version:
弹窗库,包含了alert、confirm、prompt、drawer、folder、loading、iframe、panel、tooltip、searchSuggestion、rightClickMenu组件
254 lines (232 loc) • 8.28 kB
text/typescript
import { GlobalConfig } from "../../config/GlobalConfig";
import { EventEmiter } from "../../event/EventEmiter";
import { PopsElementHandler } from "../../handler/PopsElementHandler";
import { PopsHandler } from "../../handler/PopsHandler";
import { PopsCSS } from "../../PopsCSS";
import type { PopsHandlerEventConfig } from "../../types/event";
import type { EventMap } from "../../types/EventEmitter";
import type { PopsType } from "../../types/main";
import { popsDOMUtils } from "../../utils/PopsDOMUtils";
import { popsUtils } from "../../utils/PopsUtils";
import { PopsDrawerDefaultConfig } from "./defaultConfig";
import type { PopsDrawerConfig } from "./types";
export const PopsDrawer = {
init(__config__: PopsDrawerConfig) {
const guid = popsUtils.getRandomGUID();
// 设置当前类型
const popsType: PopsType = "drawer";
let config = PopsDrawerDefaultConfig();
config = popsUtils.assign(config, GlobalConfig.getGlobalConfig());
config = popsUtils.assign(config, __config__);
config = PopsHandler.handleOnly(popsType, config);
const emitter = config.emitter ?? new EventEmiter<EventMap>(popsType);
const { $shadowContainer, $shadowRoot } = PopsHandler.handlerShadow(config);
PopsHandler.handleInit($shadowRoot, [
{
name: "index",
css: PopsCSS.index,
},
{
name: "ninePalaceGridPosition",
css: PopsCSS.ninePalaceGridPosition,
},
{
name: "scrollbar",
css: PopsCSS.scrollbar,
},
{
name: "button",
css: PopsCSS.button,
},
{
name: "anim",
css: PopsCSS.anim,
},
{
name: "common",
css: PopsCSS.common,
},
{
name: "skeleton",
css: PopsCSS.skeletonCSS,
},
{
name: "drawerCSS",
css: PopsCSS.drawerCSS,
},
]);
// 先把z-index提取出来
const zIndex = PopsHandler.getTargerOrFunctionValue(config.zIndex);
const maskHTML = PopsElementHandler.createMask(guid, zIndex);
const headerBtnHTML = PopsElementHandler.createHeader(popsType, config);
const bottomBtnHTML = PopsElementHandler.createBottom(popsType, config);
const { headerStyle, headerPStyle } = PopsElementHandler.createHeaderStyle(popsType, config);
const { contentStyle, contentPStyle } = PopsElementHandler.createContentStyle(popsType, config);
const animHTML = PopsElementHandler.createAnim(
guid,
popsType,
config,
/*html*/ `
${
config.title.enable
? /*html*/ `<div class="pops-title pops-${popsType}-title" style="${headerStyle}">${
config.title.html
? config.title.text
: /*html*/ `<p pops class="pops-${popsType}-title-text" style="width: 100%;text-align: ${config.title.position};${headerPStyle}">${config.title.text}</p>`
}${headerBtnHTML}</div>`
: ""
}
<div class="pops-content pops-${popsType}-content" style="${contentStyle}">${
config.content.html
? config.content.text
: `<p pops class="pops-${popsType}-content-text" style="${contentPStyle}">${config.content.text}</p>`
}</div>${bottomBtnHTML}`,
bottomBtnHTML,
zIndex
);
/**
* 弹窗的主元素,包括动画层
*/
const $anim = PopsElementHandler.parseElement<HTMLDivElement>(animHTML);
const {
$pops: popsElement,
$headerBtnClose: headerCloseBtnElement,
$btnCancel: btnCancelElement,
$btnOk: btnOkElement,
$btnOther: btnOtherElement,
} = PopsHandler.handleQueryElement($anim, popsType);
const $pops = popsElement!;
const $headerCloseBtn = headerCloseBtnElement!;
const $btnCancel = btnCancelElement!;
const $btnOk = btnOkElement!;
const $btnOther = btnOtherElement!;
/**
* 遮罩层元素
*/
let $mask: HTMLDivElement | undefined = void 0;
/**
* 已创建的元素列表
*/
const $elList: HTMLElement[] = [$anim];
if (config.mask.enable) {
const handleMask = PopsHandler.handleMask({
type: popsType,
guid: guid,
config: config,
animElement: $anim,
maskHTML: maskHTML,
});
$mask = handleMask.maskElement;
$elList.push($mask);
}
const evtConfig = PopsHandler.handleEventConfig(
config,
guid,
$shadowContainer,
$shadowRoot,
popsType,
$anim,
$pops,
emitter,
$mask
);
const result = PopsHandler.handleResultConfig(evtConfig);
// 处理方向
$pops.setAttribute("direction", config.direction);
// 处理border-radius
// 处理动画前的宽高
if (config.direction === "top") {
$pops.style.setProperty("height", "0");
$pops.style.setProperty("border-radius", `0px 0px ${config.borderRadius}px ${config.borderRadius}px`);
} else if (config.direction === "bottom") {
$pops.style.setProperty("height", "0");
$pops.style.setProperty("border-radius", `${config.borderRadius}px ${config.borderRadius}px 0px 0px`);
} else if (config.direction === "left") {
$pops.style.setProperty("width", "0");
$pops.style.setProperty("border-radius", `0px ${config.borderRadius}px 0px ${config.borderRadius}px`);
} else if (config.direction === "right") {
$pops.style.setProperty("width", "0");
$pops.style.setProperty("border-radius", `${config.borderRadius}px 0px ${config.borderRadius}px 0px`);
}
// 按下Esc键触发关闭
if (config.closeOnPressEscape) {
const listener = PopsHandler.handleKeyboardEvent("Escape", [], function () {
evtConfig.close();
});
emitter.on("pops:destory", () => {
listener.off();
});
}
// 待处理的点击事件列表
const needHandleClickEventList: {
type: PopsHandlerEventConfig<typeof emitter>["type"];
ele: HTMLElement;
}[] = [
{
type: "close",
ele: $headerCloseBtn,
},
{
type: "cancel",
ele: $btnCancel,
},
{
type: "ok",
ele: $btnOk,
},
{
type: "other",
ele: $btnOther,
},
];
needHandleClickEventList.forEach((item) => {
PopsHandler.handleClickEvent(item.type, item.ele, evtConfig, (evtConfig, event) => {
const callback = config.btn[item.type].callback;
if (typeof callback === "function") {
callback(evtConfig, event);
}
});
});
// 先隐藏,然后根据config.openDelay来显示
$elList.forEach((element) => {
element.style.setProperty("display", "none");
if (["top"].includes(config.direction)) {
$pops.style.setProperty("height", config.size.toString());
$pops.style.setProperty("transform", "translateY(-100%)");
} else if (["bottom"].includes(config.direction)) {
$pops.style.setProperty("height", config.size.toString());
$pops.style.setProperty("transform", "translateY(100%)");
} else if (["left"].includes(config.direction)) {
$pops.style.setProperty("width", config.size.toString());
$pops.style.setProperty("transform", "translateX(-100%)");
} else if (["right"].includes(config.direction)) {
$pops.style.setProperty("width", config.size.toString());
$pops.style.setProperty("transform", "translateX(100%)");
}
element.style.setProperty("display", "");
});
// 创建到页面中
popsDOMUtils.append($shadowRoot, $elList);
emitter.emit("pops:before-append-to-page", $shadowRoot, $shadowContainer);
popsDOMUtils.appendBody($shadowContainer);
popsUtils.setTimeout(() => {
popsUtils.setTimeout(() => {
$pops.style.setProperty("transform", "");
}, config.openDelay);
}, 50);
if ($mask != null) {
$anim.after($mask);
}
PopsHandler.handlePush(popsType, {
guid: guid,
$anim: $anim,
$pops: $pops,
$mask: $mask!,
$shadowContainer: $shadowContainer,
$shadowRoot: $shadowRoot,
config: config,
emitter: emitter,
});
return result;
},
};