UNPKG

@carbon/react

Version:

React components for the Carbon Design System

222 lines (218 loc) 6.98 kB
/** * Copyright IBM Corp. 2016, 2023 * * This source code is licensed under the Apache-2.0 license found in the * LICENSE file in the root directory of this source tree. */ import { extends as _extends } from '../../_virtual/_rollupPluginBabelHelpers.js'; import React from 'react'; import PropTypes from 'prop-types'; import Button from '../Button/Button.js'; import '../Button/Button.Skeleton.js'; import ButtonSet from '../ButtonSet/ButtonSet.js'; import cx from 'classnames'; import { usePrefix } from '../../internal/usePrefix.js'; import { noopFn } from '../../internal/noopFn.js'; import InlineLoading from '../InlineLoading/InlineLoading.js'; function SecondaryButtonSet({ secondaryButtons, secondaryButtonText, secondaryClassName, closeModal, onRequestClose, disabled }) { function handleRequestClose(evt) { closeModal(evt); onRequestClose(evt); } if (Array.isArray(secondaryButtons) && secondaryButtons.length <= 2) { return /*#__PURE__*/React.createElement(React.Fragment, null, secondaryButtons.map(({ buttonText, onClick: onButtonClick }, i) => /*#__PURE__*/React.createElement(Button, { key: `${buttonText}-${i}`, className: secondaryClassName, kind: "secondary", onClick: onButtonClick || handleRequestClose }, buttonText))); } if (secondaryButtonText) { return /*#__PURE__*/React.createElement(Button, { disabled: disabled, className: secondaryClassName, onClick: handleRequestClose, kind: "secondary" }, secondaryButtonText); } return null; } SecondaryButtonSet.propTypes = { closeModal: PropTypes.func, disabled: PropTypes.bool, onRequestClose: PropTypes.func, secondaryButtonText: PropTypes.string, secondaryButtons: (props, propName, componentName) => { if (props.secondaryButtons) { if (!Array.isArray(props.secondaryButtons) || props.secondaryButtons.length !== 2) { return new Error(`${propName} needs to be an array of two button config objects`); } const shape = { buttonText: PropTypes.node, onClick: PropTypes.func }; props[propName].forEach(secondaryButton => { PropTypes.checkPropTypes(shape, secondaryButton, propName, componentName); }); } return null; }, secondaryClassName: PropTypes.string }; const ModalFooter = /*#__PURE__*/React.forwardRef(function ModalFooter({ children, className: customClassName, closeModal = noopFn, danger, inputref, onRequestClose = noopFn, onRequestSubmit = noopFn, primaryButtonDisabled, primaryButtonText, primaryClassName, secondaryButtonText, secondaryButtons, secondaryClassName, loadingStatus = 'inactive', loadingDescription, loadingIconDescription, onLoadingSuccess = noopFn, ...rest }, ref) { const prefix = usePrefix(); const footerClass = cx(`${prefix}--modal-footer`, customClassName, Array.isArray(secondaryButtons) && secondaryButtons.length === 2 ? `${prefix}--modal-footer--three-button` : null); const primaryButtonClass = cx(primaryClassName, loadingStatus !== 'inactive' ? `${prefix}--btn--loading` : null); const loadingActive = loadingStatus !== 'inactive'; const secondaryButtonProps = { closeModal, secondaryButtons, secondaryButtonText, secondaryClassName, onRequestClose, disabled: loadingActive }; return /*#__PURE__*/React.createElement(ButtonSet, _extends({ className: footerClass }, rest, { // @ts-expect-error: Invalid derived types, will be fine once explicit types are added ref: ref, "aria-busy": loadingActive }), /*#__PURE__*/React.createElement(SecondaryButtonSet, secondaryButtonProps), primaryButtonText && /*#__PURE__*/React.createElement(Button, { onClick: onRequestSubmit, className: primaryButtonClass, disabled: loadingActive || primaryButtonDisabled, kind: danger ? 'danger' : 'primary', ref: inputref }, loadingStatus === 'inactive' ? primaryButtonText : /*#__PURE__*/React.createElement(InlineLoading, { status: loadingStatus, description: loadingDescription, iconDescription: loadingIconDescription, className: `${prefix}--inline-loading--btn`, onSuccess: onLoadingSuccess })), children); }); ModalFooter.propTypes = { /** * Pass in content that will be rendered in the Modal Footer */ children: PropTypes.node, /** * Specify a custom className to be applied to the Modal Footer container */ className: PropTypes.string, /** * Specify an optional function that is called whenever the modal is closed */ closeModal: PropTypes.func, /** * Specify whether the primary button should be replaced with danger button. * Note that this prop is not applied if you render primary/danger button by yourself */ danger: PropTypes.bool, /** * The `ref` callback for the primary button. */ inputref: PropTypes.oneOfType([PropTypes.func, PropTypes.shape({ current: PropTypes.any })]), /** * Specify the description for the loading text */ loadingDescription: PropTypes.string, /** * Specify the description for the loading text */ loadingIconDescription: PropTypes.string, /** * loading status */ loadingStatus: PropTypes.oneOf(['inactive', 'active', 'finished', 'error']), /** * Provide an optional handler to be invoked when loading is * successful */ onLoadingSuccess: PropTypes.func, /** * Specify an optional function for when the modal is requesting to be * closed */ onRequestClose: PropTypes.func, /** * Specify an optional function for when the modal is requesting to be * submitted */ onRequestSubmit: PropTypes.func, /** * Specify whether the primary button should be disabled */ primaryButtonDisabled: PropTypes.bool, /** * Specify the text for the primary button */ primaryButtonText: PropTypes.string, /** * Specify a custom className to be applied to the primary button */ primaryClassName: PropTypes.string, /** * Specify the text for the secondary button */ secondaryButtonText: PropTypes.string, /** * Specify an array of config objects for secondary buttons * (`Array<{ * buttonText: string, * onClick: function, * }>`). */ secondaryButtons: (props, propName, componentName) => { if (props.secondaryButtons) { if (!Array.isArray(props.secondaryButtons) || props.secondaryButtons.length !== 2) { return new Error(`${propName} needs to be an array of two button config objects`); } const shape = { buttonText: PropTypes.node, onClick: PropTypes.func }; props[propName].forEach(secondaryButton => { PropTypes.checkPropTypes(shape, secondaryButton, propName, componentName); }); } return null; }, /** * Specify a custom className to be applied to the secondary button */ secondaryClassName: PropTypes.string }; export { ModalFooter };