UNPKG

@carbon/react

Version:

React components for the Carbon Design System

140 lines (138 loc) 5.41 kB
/** * Copyright IBM Corp. 2016, 2026 * * 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 { usePrefix } from "../../internal/usePrefix.js"; import { noopFn } from "../../internal/noopFn.js"; import Button_default from "../Button/index.js"; import ButtonSet_default from "../ButtonSet/index.js"; import InlineLoading_default from "../InlineLoading/index.js"; import classNames from "classnames"; import React from "react"; import PropTypes from "prop-types"; import { Fragment, jsx, jsxs } from "react/jsx-runtime"; //#region src/components/ComposedModal/ModalFooter.tsx /** * Copyright IBM Corp. 2023, 2025 * * This source code is licensed under the Apache-2.0 license found in the * LICENSE file in the root directory of this source tree. */ function SecondaryButtonSet({ secondaryButtons, secondaryButtonText, secondaryClassName, closeModal, onRequestClose, disabled }) { function handleRequestClose(evt) { closeModal(evt); onRequestClose(evt); } if (Array.isArray(secondaryButtons) && secondaryButtons.length <= 2) return /* @__PURE__ */ jsx(Fragment, { children: secondaryButtons.map(({ buttonText, onClick: onButtonClick }, i) => /* @__PURE__ */ jsx(Button_default, { className: secondaryClassName, kind: "secondary", onClick: onButtonClick || handleRequestClose, children: buttonText }, `${buttonText}-${i}`)) }); if (secondaryButtonText) return /* @__PURE__ */ jsx(Button_default, { disabled, className: secondaryClassName, onClick: handleRequestClose, kind: "secondary", children: 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 /* @__PURE__ */ 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 = 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 = classNames(`${prefix}--modal-footer`, customClassName, Array.isArray(secondaryButtons) && secondaryButtons.length === 2 ? `${prefix}--modal-footer--three-button` : null); const primaryButtonClass = classNames(primaryClassName, loadingStatus !== "inactive" ? `${prefix}--btn--loading` : null); const loadingActive = loadingStatus !== "inactive"; const secondaryButtonProps = { closeModal, secondaryButtons, secondaryButtonText, secondaryClassName, onRequestClose, disabled: loadingActive }; return /* @__PURE__ */ jsxs(ButtonSet_default, { className: footerClass, ...rest, ref, "aria-busy": loadingActive, children: [ /* @__PURE__ */ jsx(SecondaryButtonSet, { ...secondaryButtonProps }), primaryButtonText && /* @__PURE__ */ jsx(Button_default, { onClick: onRequestSubmit, className: primaryButtonClass, disabled: loadingActive || primaryButtonDisabled, kind: danger ? "danger" : "primary", ref: inputref, children: loadingStatus === "inactive" ? primaryButtonText : /* @__PURE__ */ jsx(InlineLoading_default, { status: loadingStatus, description: loadingDescription, iconDescription: loadingIconDescription, className: `${prefix}--inline-loading--btn`, onSuccess: onLoadingSuccess }) }), children ] }); }); ModalFooter.propTypes = { children: PropTypes.node, className: PropTypes.string, closeModal: PropTypes.func, danger: PropTypes.bool, inputref: PropTypes.oneOfType([PropTypes.func, PropTypes.shape({ current: PropTypes.any })]), loadingDescription: PropTypes.string, loadingIconDescription: PropTypes.string, loadingStatus: PropTypes.oneOf([ "inactive", "active", "finished", "error" ]), onLoadingSuccess: PropTypes.func, onRequestClose: PropTypes.func, onRequestSubmit: PropTypes.func, primaryButtonDisabled: PropTypes.bool, primaryButtonText: PropTypes.string, primaryClassName: PropTypes.string, secondaryButtonText: PropTypes.string, secondaryButtons: (props, propName, componentName) => { if (props.secondaryButtons) { if (!Array.isArray(props.secondaryButtons) || props.secondaryButtons.length !== 2) return /* @__PURE__ */ 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 }; //#endregion export { ModalFooter };