Skip to content

Commit

Permalink
Merge pull request #388 from easyops-cn/steve/modal-stack
Browse files Browse the repository at this point in the history
Steve/modal-stack
  • Loading branch information
WHChen-Alex authored Oct 16, 2024
2 parents 0e5ee34 + d8624b4 commit a822cc2
Show file tree
Hide file tree
Showing 9 changed files with 202 additions and 96 deletions.
34 changes: 26 additions & 8 deletions bricks/basic-bricks/src/general-drawer/GeneralDrawer.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import React, { useRef, useEffect } from "react";
import React, { useRef, useEffect, useState } from "react";
import { Drawer, Spin } from "antd";
import { Icon as LegacyIcon } from "@ant-design/compatible";
import { GeneralIcon } from "@next-libs/basic-components";
import { DrawerProps } from "antd/lib/drawer";
import type { ModalStack } from "@next-core/brick-kit";
import { ICustomSwitchConfig } from "./index";
interface GeneralDrawerProps {
visible: boolean;
Expand All @@ -22,10 +22,12 @@ interface GeneralDrawerProps {
useBigOuterSwitch?: boolean;
customSwitchConfig?: ICustomSwitchConfig;
scrollToTopWhenOpen?: boolean;
stack: ModalStack;
stackable?: boolean;
}

export function GeneralDrawer(props: GeneralDrawerProps): React.ReactElement {
const { scrollToTopWhenOpen } = props;
const { scrollToTopWhenOpen, stack, stackable } = props;

const contentRef = useRef<HTMLDivElement>();

Expand All @@ -36,11 +38,26 @@ export function GeneralDrawer(props: GeneralDrawerProps): React.ReactElement {
}
};

useEffect(() => {
scrollToTopWhenOpen &&
props.visible &&
findDrawerBody(contentRef.current)?.scrollTo(0, 0);
}, [props.visible]);
const [zIndex, setZIndex] = useState<number>(undefined);
useEffect(
() => {
scrollToTopWhenOpen &&
props.visible &&
findDrawerBody(contentRef.current)?.scrollTo(0, 0);

if (stack && stackable !== false) {
if (props.visible) {
setZIndex(stack.push());
} else {
stack.pull();
setZIndex(undefined);
}
}
},
// Only re-run the effect if visible changes
// eslint-disable-next-line react-hooks/exhaustive-deps
[props.visible]
);

const title = (
<div className="header">
Expand Down Expand Up @@ -117,6 +134,7 @@ export function GeneralDrawer(props: GeneralDrawerProps): React.ReactElement {
headerStyle={props.headerStyle}
forceRender={!!props.hasOuterSwitch}
className={classNameList.join(" ")}
zIndex={zIndex}
>
{props.hasOuterSwitch && (
<div
Expand Down
14 changes: 14 additions & 0 deletions bricks/basic-bricks/src/general-drawer/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
method,
event,
EventEmitter,
instantiateModalStack,
} from "@next-core/brick-kit";
import { GeneralDrawer } from "./GeneralDrawer";
import style from "./index.shadow.less";
Expand Down Expand Up @@ -189,6 +190,16 @@ export class GeneralDrawerElement extends UpdatingElement {
@property({ attribute: false })
scrollToTopWhenOpen = true;

/**
* @description 是否可堆叠,开启后每次打开抽屉会将新的抽屉置于上层(zIndex ++)。注意:仅初始设置有效。
*
* @default true
*/
@property({ attribute: false })
stackable = true;

private _stack = instantiateModalStack?.();

constructor() {
super();

Expand Down Expand Up @@ -276,6 +287,7 @@ export class GeneralDrawerElement extends UpdatingElement {
document.body.style.overflow = "";
document.body.style.touchAction = "";
ReactDOM.unmountComponentAtNode(this);
this._stack?.pull();
}

protected _render(): void {
Expand All @@ -301,6 +313,8 @@ export class GeneralDrawerElement extends UpdatingElement {
useBigOuterSwitch={this.useBigOuterSwitch}
customSwitchConfig={this.customSwitchConfig}
scrollToTopWhenOpen={this.scrollToTopWhenOpen}
stack={this._stack}
stackable={this.stackable}
/>
</BrickWrapper>,
this._mountPoint
Expand Down
23 changes: 23 additions & 0 deletions bricks/basic-bricks/src/general-modal/GeneralModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { GeneralIcon } from "@next-libs/basic-components";
import { MenuIcon } from "@next-core/brick-types";
import { NS_BASIC_BRICKS, K } from "../i18n/constants";
import { useTranslation } from "react-i18next";
import type { ModalStack } from "@next-core/brick-kit";

const fullscreenMargin = 20;
const titleAlignPropertyMap: Record<string, string> = {
Expand Down Expand Up @@ -40,6 +41,8 @@ interface GeneralModalProps {
isHiddenModalTitle?: boolean;
isHiddenModalFooter?: boolean;
isShowCustomHeader?: boolean;
stack: ModalStack;
stackable?: boolean;
onAfterClose?: () => void;
}

Expand All @@ -63,6 +66,8 @@ export function GeneralModal(props: GeneralModalProps): React.ReactElement {
isHiddenModalFooter,
isShowCustomHeader,
footerPosition = "right",
stack,
stackable,
} = props;
const modalHeaderRef = useRef<HTMLDivElement>();
const modalFooterRef = useRef<HTMLDivElement>();
Expand Down Expand Up @@ -172,6 +177,23 @@ export function GeneralModal(props: GeneralModalProps): React.ReactElement {
}
}

const [zIndex, setZIndex] = useState<number>(undefined);
useEffect(
() => {
if (stack && stackable !== false) {
if (visible) {
setZIndex(stack.push());
} else {
stack.pull();
setZIndex(undefined);
}
}
},
// Only re-run the effect if visible changes
// eslint-disable-next-line react-hooks/exhaustive-deps
[visible]
);

return (
<Modal
className={classnames({
Expand Down Expand Up @@ -205,6 +227,7 @@ export function GeneralModal(props: GeneralModalProps): React.ReactElement {
width={fullscreen ? `calc(100% - ${fullscreenMargin * 2}px)` : undefined}
bodyStyle={fullscreen ? { height: bodyHeight } : undefined}
wrapClassName={classnames({ fullscreen })}
zIndex={zIndex}
{...configProps}
afterClose={onAfterClose}
cancelButtonProps={{ type: "link", ...configProps?.cancelButtonProps }}
Expand Down
15 changes: 15 additions & 0 deletions bricks/basic-bricks/src/general-modal/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
method,
event,
EventEmitter,
instantiateModalStack,
} from "@next-core/brick-kit";
import { GeneralModal, positionType } from "./GeneralModal";
import style from "./index.shadow.less";
Expand Down Expand Up @@ -314,6 +315,16 @@ export class GeneralModalElement extends UpdatingElement {
modalTitle: string;
};

/**
* @description 是否可堆叠,开启后每次打开抽屉会将新的抽屉置于上层(zIndex ++)。注意:仅初始设置有效。
*
* @default true
*/
@property({ attribute: false })
stackable = true;

private _stack = instantiateModalStack?.();

private _mountPoint: HTMLElement;
private isVisible = false;
private modalProps: ModalProps = {};
Expand Down Expand Up @@ -395,7 +406,9 @@ export class GeneralModalElement extends UpdatingElement {
document.body.style.overflow = "";
document.body.style.touchAction = "";
ReactDOM.unmountComponentAtNode(this);
this._stack?.pull();
}

private initData(mutableProps: { modalTitle: string }): void {
const pickFields = pick(this.fields, ["modalTitle"]);
forEach(pickFields, (fieldKey, field: string) => {
Expand Down Expand Up @@ -447,6 +460,8 @@ export class GeneralModalElement extends UpdatingElement {
isHiddenModalTitle={this.isHiddenModalTitle}
isHiddenModalFooter={this.isHiddenModalFooter}
isShowCustomHeader={this.isShowCustomHeader}
stack={this._stack}
stackable={this.stackable}
/>
</BrickWrapper>,
this._mountPoint
Expand Down
24 changes: 23 additions & 1 deletion bricks/forms/src/general-modal/GeneralModal.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import React from "react";
import React, { useEffect, useState } from "react";
import { Button, Modal } from "antd";
import { ButtonType } from "antd/lib/button";
import { FormItemWrapper, FormItemWrapperProps } from "@next-libs/forms";
import i18n from "i18next";
import { NS_FORMS, K } from "../i18n/constants";
import { GeneralIcon } from "@next-libs/basic-components";
import { MenuIcon } from "@next-core/brick-types";
import type { ModalStack } from "@next-core/brick-kit";

declare type SrcIcon = {
imgSrc?: string;
Expand All @@ -23,9 +24,12 @@ interface GeneralModalProps extends FormItemWrapperProps {
btnText?: string;
okDisabled?: boolean;
titleIcon?: MenuIcon | SrcIcon;
stack: ModalStack;
stackable?: boolean;
}

export function GeneralModal(props: GeneralModalProps): React.ReactElement {
const { stack, stackable } = props;
const footer = (
<>
<Button className="cancelBtn" type="text">
Expand Down Expand Up @@ -67,6 +71,23 @@ export function GeneralModal(props: GeneralModalProps): React.ReactElement {
}
}

const [zIndex, setZIndex] = useState<number>(undefined);
useEffect(
() => {
if (stack && stackable !== false) {
if (props.visible) {
setZIndex(stack.push());
} else {
stack.pull();
setZIndex(undefined);
}
}
},
// Only re-run the effect if visible changes
// eslint-disable-next-line react-hooks/exhaustive-deps
[props.visible]
);

return (
<FormItemWrapper {...props}>
<>
Expand Down Expand Up @@ -94,6 +115,7 @@ export function GeneralModal(props: GeneralModalProps): React.ReactElement {
getContainer={props.container}
footer={footer}
destroyOnClose={true}
zIndex={zIndex}
>
<slot id="content" name="content"></slot>
</Modal>
Expand Down
14 changes: 14 additions & 0 deletions bricks/forms/src/general-modal/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
event,
method,
EventEmitter,
instantiateModalStack,
} from "@next-core/brick-kit";
import { GeneralModal } from "./GeneralModal";
import { FormItemElement } from "@next-libs/forms";
Expand Down Expand Up @@ -210,6 +211,16 @@ export class GeneralModalElement extends FormItemElement {
modalTitle: string;
};

/**
* @description 是否可堆叠,开启后每次打开抽屉会将新的抽屉置于上层(zIndex ++)。注意:仅初始设置有效。
*
* @default true
*/
@property({ attribute: false })
stackable = true;

private _stack = instantiateModalStack?.();

private _mountPoint: HTMLElement;

private _childFormElement: ChildeFormElement;
Expand Down Expand Up @@ -295,6 +306,7 @@ export class GeneralModalElement extends FormItemElement {
document.body.style.touchAction = "";
ReactDOM.unmountComponentAtNode(this._mountPoint);
this.removeEventListener("click", this.listenToClick);
this._stack?.pull();
}

protected _render(): void {
Expand Down Expand Up @@ -333,6 +345,8 @@ export class GeneralModalElement extends FormItemElement {
labelCol={this.labelCol}
wrapperCol={this.wrapperCol}
titleIcon={this.titleIcon}
stack={this._stack}
stackable={this.stackable}
/>
</BrickWrapper>,
this._mountPoint,
Expand Down
2 changes: 1 addition & 1 deletion bricks/next-builder/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
},
"sideEffects": true,
"devDependencies": {
"@next-core/storyboard-function-types": "^0.2.16",
"@next-core/storyboard-function-types": "^0.2.18",
"@next-libs/basic-components": "^5.5.0",
"@next-libs/cmdb-instances": "^7.21.8",
"@next-libs/code-editor-components": "^4.12.1",
Expand Down
16 changes: 8 additions & 8 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,17 +38,17 @@
"@fortawesome/react-fontawesome": "^0.2.0",
"@next-core/babel-runtime-helpers": "^1.0.27",
"@next-core/brick-http": "^2.8.2",
"@next-core/brick-icons": "^2.33.49",
"@next-core/brick-kit": "^2.199.8",
"@next-core/brick-icons": "^2.33.53",
"@next-core/brick-kit": "^2.201.0",
"@next-core/brick-types": "^2.98.1",
"@next-core/brick-utils": "^2.52.6",
"@next-core/dev-dependencies": "^1.18.60",
"@next-core/brick-utils": "^2.52.10",
"@next-core/dev-dependencies": "^1.19.8",
"@next-core/easyops-analytics": "^0.12.1",
"@next-core/editor-bricks-helper": "^0.50.81",
"@next-core/editor-bricks-helper": "^0.50.89",
"@next-core/fontawesome-library": "^1.1.38",
"@next-core/illustrations": "^0.11.34",
"@next-core/loader": "^1.6.7",
"@next-core/pipes": "^1.0.18",
"@next-core/loader": "^1.6.10",
"@next-core/pipes": "^1.0.20",
"@next-libs/cmdb-utils": "^3.7.3",
"@size-limit/file": "^8.1.0",
"@testing-library/react-hooks": "^8.0.1",
Expand Down Expand Up @@ -105,6 +105,6 @@
"ua-parser-js": "0.7.19"
},
"easyops": {
"dev-dependencies": "1.18.60"
"dev-dependencies": "1.19.8"
}
}
Loading

0 comments on commit a822cc2

Please sign in to comment.