UNPKG

@carbon/ibm-products

Version:
146 lines (144 loc) 5.71 kB
/** * Copyright IBM Corp. 2020, 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 { getDevtoolsProps } from "../../global/js/utils/devtools.js"; import { clamp } from "../../global/js/utils/clamp.js"; import { InterstitialScreenContext, blockClass } from "./context.js"; import React, { useContext, useEffect, useMemo, useRef, useState } from "react"; import PropTypes from "prop-types"; import { Button, ButtonSet, InlineLoading, ModalFooter, usePrefix } from "@carbon/react"; import { ArrowRight } from "@carbon/react/icons"; //#region src/components/InterstitialScreen/InterstitialScreenFooter.tsx /** * Copyright IBM Corp. 2024, 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. */ const InterstitialScreenFooter = React.forwardRef((props, ref) => { const { className = "", skipButtonLabel = "Skip", previousButtonLabel = "Back", nextButtonLabel = "Next", startButtonLabel = "Get Started", actionButtonRenderer, onAction, ...rest } = props; const footerBlockClass = `${blockClass}--footer`; const { handleClose, progStep, handleGotoStep, stepCount, disableButtonConfig, isFullScreen } = useContext(InterstitialScreenContext); const startButtonRef = useRef(null); const nextButtonRef = useRef(null); const [loadingAction, setLoadingAction] = useState(""); const carbonPrefix = usePrefix(); const isMultiStep = !!stepCount && stepCount > 1; const progStepFloor = 0; const progStepCeil = stepCount - 1; useEffect(() => { if (progStep + 1 === stepCount && startButtonRef.current) startButtonRef.current.focus(); }, [progStep]); const handleAction = async (actionType) => { setLoadingAction(actionType); const abortContinue = await onAction?.(actionType, { handleGotoStep, progStep, stepCount, disableButtonConfig }); setLoadingAction(""); if (abortContinue) return; if (actionType === "next" || actionType === "back") { const targetStep = clamp(progStep + (actionType === "next" ? 1 : -1), progStepFloor, progStepCeil); handleGotoStep?.(targetStep); } else handleClose?.(actionType); }; const handleStart = () => handleAction("start"); const handleSkip = () => handleAction("skip"); const handleClickNext = () => handleAction("next"); const handleClickPrev = () => handleAction("back"); const getRenderIcon = useMemo(() => { if (loadingAction !== "start" && isMultiStep && progStep === progStepCeil) return { renderIcon: ArrowRight }; return {}; }, [ loadingAction, isMultiStep, progStep, progStepCeil ]); const getFooterContent = () => /* @__PURE__ */ React.createElement(ButtonSet, null, isMultiStep && skipButtonLabel !== "" && /* @__PURE__ */ React.createElement(Button, { className: `${blockClass}--skip-btn`, kind: "ghost", size: "lg", title: skipButtonLabel, onClick: handleSkip, disabled: disableButtonConfig?.skip }, skipButtonLabel, loadingAction === "skip" && /* @__PURE__ */ React.createElement(InlineLoading, null)), isMultiStep && progStep > 0 && /* @__PURE__ */ React.createElement(Button, { className: `${blockClass}--prev-btn`, kind: "secondary", size: "lg", title: previousButtonLabel, disabled: disableButtonConfig?.back, onClick: handleClickPrev }, previousButtonLabel, loadingAction === "back" && /* @__PURE__ */ React.createElement(InlineLoading, null)), isMultiStep && progStep < progStepCeil && /* @__PURE__ */ React.createElement(Button, { className: `${blockClass}--next-btn`, renderIcon: loadingAction !== "next" ? ArrowRight : void 0, ref: nextButtonRef, size: "lg", title: nextButtonLabel, disabled: disableButtonConfig?.next, onClick: handleClickNext }, nextButtonLabel, loadingAction === "next" && /* @__PURE__ */ React.createElement(InlineLoading, null)), (isMultiStep && progStep === progStepCeil || !isMultiStep) && /* @__PURE__ */ React.createElement(Button, { className: `${blockClass}--start-btn`, ref: startButtonRef, size: "lg", title: startButtonLabel, disabled: disableButtonConfig?.start, onClick: handleStart, ...getRenderIcon }, startButtonLabel, loadingAction === "start" && /* @__PURE__ */ React.createElement(InlineLoading, null))); const footerContent = actionButtonRenderer ? actionButtonRenderer({ handleGotoStep, progStep, stepCount, disableButtonConfig }) : getFooterContent(); return isFullScreen ? /* @__PURE__ */ React.createElement("div", { ref, className: `${footerBlockClass} ${className} ${carbonPrefix}--modal-footer`, ...getDevtoolsProps("InterstitialScreenFooter"), ...rest }, footerContent) : /* @__PURE__ */ React.createElement(ModalFooter, { className: `${footerBlockClass} ${className}`, ref, ...rest }, footerContent); }); InterstitialScreenFooter.propTypes = { /** * This is an optional callback prop that allows to render your custom footer action buttons. */ actionButtonRenderer: PropTypes.func, /** * Provide an optional class to be applied to the containing node. */ className: PropTypes.string, /** * The label for the Next button. */ nextButtonLabel: PropTypes.string, /** * optional asynchronous callback on action button click (skip, previous, next and start) * note: this is applicable when not using custom actionButtonRenderer */ onAction: PropTypes.func, /** * The label for the Previous button. * */ previousButtonLabel: PropTypes.string, /** * The label for the skip button. */ skipButtonLabel: PropTypes.string, /** * The label for the start button. */ startButtonLabel: PropTypes.string }; //#endregion export { InterstitialScreenFooter as default };