diff --git a/app/client/src/components/designSystems/blueprint/ModalComponent.tsx b/app/client/src/components/designSystems/blueprint/ModalComponent.tsx index acf3aa652d..e3dd12ead4 100644 --- a/app/client/src/components/designSystems/blueprint/ModalComponent.tsx +++ b/app/client/src/components/designSystems/blueprint/ModalComponent.tsx @@ -56,6 +56,7 @@ const Content = styled.div<{ export type ModalComponentProps = { isOpen: boolean; onClose: (e: any) => void; + onModalClose?: () => void; children: ReactNode; width?: number; className?: string; @@ -76,6 +77,14 @@ export function ModalComponent(props: ModalComponentProps) { const modalContentRef: RefObject = useRef( null, ); + useEffect(() => { + return () => { + // handle modal close events when this component unmounts + // will be called in all cases :- + // escape key press, click out side, close click from other btn widget + if (props.onModalClose) props.onModalClose(); + }; + }, []); useEffect(() => { if (!props.scrollContents) { modalContentRef.current?.scrollTo({ top: 0, behavior: "smooth" }); diff --git a/app/client/src/constants/AppsmithActionConstants/ActionConstants.tsx b/app/client/src/constants/AppsmithActionConstants/ActionConstants.tsx index 7e63eb2edc..6f8dc9c1dc 100644 --- a/app/client/src/constants/AppsmithActionConstants/ActionConstants.tsx +++ b/app/client/src/constants/AppsmithActionConstants/ActionConstants.tsx @@ -56,6 +56,7 @@ export enum EventType { ON_HOVER = "ON_HOVER", ON_TOGGLE = "ON_TOGGLE", ON_LOAD = "ON_LOAD", + ON_MODAL_CLOSE = "ON_MODAL_CLOSE", ON_TEXT_CHANGE = "ON_TEXT_CHANGE", ON_SUBMIT = "ON_SUBMIT", ON_CHECK_CHANGE = "ON_CHECK_CHANGE", diff --git a/app/client/src/widgets/ModalWidget.tsx b/app/client/src/widgets/ModalWidget.tsx index a740c9eaec..6fae51bd08 100644 --- a/app/client/src/widgets/ModalWidget.tsx +++ b/app/client/src/widgets/ModalWidget.tsx @@ -3,6 +3,7 @@ import React, { ReactNode } from "react"; import { connect } from "react-redux"; import { ReduxActionTypes } from "constants/ReduxActionConstants"; import BaseWidget, { WidgetProps, WidgetState } from "./BaseWidget"; +import { EventType } from "constants/AppsmithActionConstants/ActionConstants"; import WidgetFactory from "utils/WidgetFactory"; import ModalComponent from "components/designSystems/blueprint/ModalComponent"; import { @@ -70,6 +71,20 @@ export class ModalWidget extends BaseWidget { }, ], }, + { + sectionName: "Actions", + children: [ + { + helpText: "Triggers an action when the modal is closed", + propertyName: "onClose", + label: "onClose", + controlType: "ACTION_SELECTOR", + isJSConvertible: true, + isBindProperty: true, + isTriggerProperty: true, + }, + ], + }, ]; } static defaultProps = { @@ -99,6 +114,18 @@ export class ModalWidget extends BaseWidget { return WidgetFactory.createWidget(childWidgetData, this.props.renderMode); }; + onModalClose = () => { + if (this.props.onClose) { + super.executeAction({ + triggerPropertyName: "onClose", + dynamicString: this.props.onClose, + event: { + type: EventType.ON_MODAL_CLOSE, + }, + }); + } + }; + closeModal = (e: any) => { this.props.showPropertyPane(undefined); // TODO(abhinav): Create a static property with is a map of widget properties @@ -124,6 +151,7 @@ export class ModalWidget extends BaseWidget { height={MODAL_SIZE[this.props.size].height} isOpen={!!this.props.isVisible} onClose={this.closeModal} + onModalClose={this.onModalClose} scrollContents={!!this.props.shouldScrollContents} width={this.getModalWidth()} > @@ -159,6 +187,7 @@ export interface ModalWidgetProps extends WidgetProps, WithMeta { canEscapeKeyClose?: boolean; shouldScrollContents?: boolean; size: string; + onClose: string; mainContainer: WidgetProps; }