@boomerang-io/carbon-addons-boomerang-react
Version:
Carbon Addons for Boomerang apps
92 lines (89 loc) • 3.92 kB
JavaScript
import React, { useEffect } from 'react';
import { ModalHeader } from '@carbon/react';
import cx from 'classnames';
import { Modal } from '../Modal/Modal.js';
import ConfirmModal from '../ConfirmModal/ConfirmModal.js';
import { prefix } from '../../internal/settings.js';
import useSetState from '../../tools/useSetState.js';
/*
IBM Confidential
694970X, 69497O0
© Copyright IBM Corp. 2022, 2024
*/
function ComposedModal(props) {
const { appElement = "#app", composedModalProps = {}, isOpen = false, modalHeaderProps = {} } = props;
const [state, setState] = useSetState({
isConfirmModalOpen: false,
isOpen: isOpen,
shouldConfirmModalClose: false,
step: 0,
...props.initialState,
});
// Let it be externally controlled
useEffect(() => {
setState({ isOpen });
// eslint-disable-next-line
}, [isOpen]);
/**
* Reset to initial state
* and let parent know
*/
const resetInitialState = (stateUpdate) => {
setState({
isConfirmModalOpen: false,
shouldConfirmModalClose: false,
...props.initialState,
...stateUpdate,
});
};
const handleOpenModal = () => {
setState({ isOpen: true });
};
/**
* Close modal and call event function for parent if provided
*/
const handleCloseModal = () => {
resetInitialState({ isOpen: false });
if (typeof props.onCloseModal === "function") {
props.onCloseModal();
}
};
/**
* Check if should confirm exit with confirm modal or just exit modal flow
*/
const handleShouldCloseModal = () => {
if (state.shouldConfirmModalClose) {
setState({ isConfirmModalOpen: true });
}
else {
handleCloseModal();
}
};
const closeConfirmModal = () => {
setState({ isConfirmModalOpen: false });
};
/**
* Method passed to children components and they determine if should confirm exit of modal
* @param {bool} shouldConfirmModalClose - boolean of current component
*/
const handleSetShouldConfirmModalClose = (shouldConfirmModalClose) => {
setState({ shouldConfirmModalClose });
};
const { containerClassName, ...restComposedModalProps } = composedModalProps;
const { subtitle, ...restModalHeaderProps } = modalHeaderProps;
return (React.createElement(React.Fragment, null,
props.modalTrigger && props.modalTrigger({ openModal: handleOpenModal }),
React.createElement(Modal, { appElement: appElement, containerClassName: cx(`${prefix}--bmrg-modal-composed-container`, `${prefix}--modal-container`, props.size ? `${prefix}--modal-container--${props.size}` : "modal-container-fix-width", containerClassName), isOpen: state.isOpen, onRequestClose: handleShouldCloseModal, shouldCloseOnOverlayClick: false, ...restComposedModalProps },
React.createElement(ModalHeader, { closeModal: handleShouldCloseModal, ...restModalHeaderProps }, subtitle && React.createElement("p", { className: `${prefix}--bmrg-modal-composed-subtitle` }, subtitle)),
state.isOpen &&
typeof props.children === "function" &&
props.children({
closeModal: handleShouldCloseModal,
forceCloseModal: handleCloseModal,
resetInitialState: resetInitialState,
setShouldConfirmModalClose: handleSetShouldConfirmModalClose,
shouldConfirmModalClose: state.shouldConfirmModalClose,
}),
React.createElement(ConfirmModal, { affirmativeAction: handleCloseModal, appElement: appElement, negativeAction: closeConfirmModal, isOpen: state.isConfirmModalOpen, onCloseModal: closeConfirmModal, ...props.confirmModalProps }))));
}
export { ComposedModal, ComposedModal as default };