Add popup renderer

This commit is contained in:
2022-03-22 17:31:49 +08:00
parent 93e1a8d3ef
commit 90398b593e
5 changed files with 207 additions and 3 deletions
+7 -1
View File
@@ -68,7 +68,13 @@ class CommandBar extends Component<ICommandBarProps & IMixinSettingProps & IMixi
{this.getRenderButton({ iconName: "Camera", i18NKey: "Command.Bar.Camera.Info" })}
</div>
<div>
{this.getRenderButton({ iconName: "Settings", i18NKey: "Command.Bar.Setting.Info" })}
{this.getRenderButton({
iconName: "Settings",
i18NKey: "Command.Bar.Setting.Info",
click: () => {
this.props.status ? this.props.status.popup.showPopup() : undefined;
}
})}
</div>
</Theme>
}
+71
View File
@@ -0,0 +1,71 @@
@import "../Theme/Theme.scss";
@keyframes show-scale{
from {
transform: scale3d(1.15, 1.15, 1);
}
to {
transform: scale3d(1, 1, 1);
}
}
@keyframes show-fade{
from {
opacity: 0;
}
to {
opacity: 1;
}
}
div.popup-mask.show-fade {
animation: show-fade .1s cubic-bezier(0, 0, 1, 1) both;
opacity: 1;
}
div.popup-layer.show-scale {
animation: show-scale .3s cubic-bezier(.1, .9, .2, 1) both,
show-fade .1s cubic-bezier(0, 0, 1, 1) both;
transform: scale3d(1, 1, 1);
opacity: 1;
}
div.popup-mask {
position: absolute;
cursor: pointer;
width: 100%;
height: 100%;
}
div.popup-layer {
position: absolute;
border-radius: 3px;
overflow: hidden;
div.popup-layer-header {
min-height: 32px;
max-height: 32px;
}
}
div.popup-layer.dark {
div.popup-layer-header {
background-color: $lt-bg-color-lvl3-dark;
}
}
div.popup-layer.light {
div.popup-layer-header {
background-color: $lt-bg-color-lvl3-light;
}
}
div.dark.popup-mask {
background-color: rgba(0, 0, 0, 0.55);
}
div.light.popup-mask {
background-color: rgba(0, 0, 0, 0.15);
}
+97
View File
@@ -0,0 +1,97 @@
import { Component, ReactNode } from "react";
import { IMixinStatusProps, useStatusWithEvent } from "@Context/Status";
import { BackgroundLevel, Theme } from "@Component/Theme/Theme";
import { Popup as PopupModel } from "@Context/Popups";
import "./Popup.scss";
interface IPopupProps {}
@useStatusWithEvent("popupChange")
class Popup extends Component<IPopupProps & IMixinStatusProps> {
public renderMask(index?: number, click?: () => void, key?: string): ReactNode {
const classList: string[] = ["popup-mask", "show-fade"];
return <Theme
key={key}
onClick={click}
className={classList.join(" ")}
style={{
zIndex: index,
}}
/>
}
public renderRootMask(): ReactNode {
if (this.props.status) {
const needMask = this.props.status.popup.popups.some(popup => popup.needMask);
if (!needMask) return null;
return this.renderMask(this.props.status.popup.zIndex,
() => {
this.props.status?.popup.popups.forEach(
popup => popup.onClose()
)
}
);
} else {
return null;
}
}
public renderMaskList(): ReactNode {
if (this.props.status) {
return this.props.status.popup.popups
.filter((popup) => {
return popup.needMask && popup.maskForSelf;
})
.filter((_, index) => {
if (index === 0) return false;
return true;
})
.map((popup) => {
return this.renderMask(popup.zIndex() - 1,
() => {
popup.onClose();
}, popup.id
);
})
} else {
return null;
}
}
public renderLayer(popup: PopupModel) {
const pageWidth = document.documentElement.clientWidth;
const pageHeight = document.documentElement.clientHeight;
const top = (pageHeight - popup.height) / 2;
const left = (pageWidth - popup.width) / 2;
return <Theme
style={{
width: popup.width,
height: popup.height,
zIndex: popup.zIndex(),
top: top,
left: left
}}
key={popup.id}
backgroundLevel={BackgroundLevel.Level4}
className="popup-layer show-scale"
>
<div className="popup-layer-header">
</div>
</Theme>
}
public render(): ReactNode {
return <>
{this.renderRootMask()}
{this.renderMaskList()}
{this.props.status?.popup.popups.map((popup) => {
return this.renderLayer(popup);
})}
</>;
}
}
export { Popup };