@mskcc/carbon-react
Version:
Carbon react components for the MSKCC DSM
137 lines (130 loc) • 4.26 kB
JavaScript
/**
* MSKCC 2021, 2024
*/
import { extends as _extends } from '../../_virtual/_rollupPluginBabelHelpers.js';
import cx from 'classnames';
import React__default, { useMemo, Children, isValidElement, cloneElement } from 'react';
import { StepperStep } from './Step/StepperStep.js';
import StepperContext from './StepperContext.js';
import PropTypes from 'prop-types';
import useIsomorphicEffect from '../../internal/useIsomorphicEffect.js';
const Stepper = _ref => {
let {
title,
steps,
children,
className,
stepClassName = '',
activeStep = 0,
size = 'default',
vertical = false,
...rest
} = _ref;
const contextValue = useMemo(() => ({
activeStep,
vertical
}), [activeStep, vertical]);
const useStepsProp = steps instanceof Array && steps.length > 0;
const stepsArray = useStepsProp ? steps : Children.toArray(children);
const stepsToRender = stepsArray.map((step, index) => {
if (!useStepsProp && ! /*#__PURE__*/isValidElement(step)) {
return null;
}
const stepProps = {
className: stepClassName,
index
};
return /*#__PURE__*/React__default.createElement("div", {
key: index,
className: "stepper-step-container"
}, /*#__PURE__*/isValidElement(step) ? /*#__PURE__*/cloneElement(step, {
...stepProps,
...step.props
}) : /*#__PURE__*/React__default.createElement(StepperStep, _extends({}, stepProps, typeof step === 'object' ? step : {})));
});
const ref = /*#__PURE__*/React__default.createRef();
const stepperRef = /*#__PURE__*/React__default.createRef();
// for horizontal stepper
useIsomorphicEffect(() => {
const progressBar = ref.current;
if (!progressBar) {
return;
}
if (activeStep === -1) {
if (vertical) {
progressBar.style.height = '0%';
} else {
progressBar.style.width = '0%';
}
} else {
const percentage = activeStep / (stepsArray.length - 1) * 100;
if (vertical) {
if (activeStep > stepsArray.length - 1) {
progressBar.style.height = '100%';
} else {
progressBar.style.height = `${percentage}%`;
}
} else {
if (activeStep > stepsArray.length - 1) {
progressBar.style.width = '100%';
} else {
progressBar.style.width = `${percentage}%`;
}
}
}
}, [activeStep, stepsArray.length, vertical, ref]);
// for vertical stepper
useIsomorphicEffect(() => {
const stepper = stepperRef.current;
if (!stepper) {
return;
}
}, [stepperRef]);
return /*#__PURE__*/React__default.createElement(StepperContext.Provider, {
value: contextValue
}, /*#__PURE__*/React__default.createElement("div", {
className: cx('msk-stepper-container', className)
}, /*#__PURE__*/React__default.createElement("div", _extends({
ref: stepperRef,
role: "progressbar",
"aria-valuemin": 1,
"aria-valuemax": stepsArray.length,
"aria-valuenow": activeStep + 1
// eslint-disable-next-line react/no-unknown-property, jsx-a11y/aria-props
,
"aria-defaultValue": activeStep + 1,
"aria-label": title || `Stepper ${activeStep + 1} of ${stepsArray.length}`,
className: cx('msk-stepper', `msk-stepper-${size}`, {
'msk-stepper-vertical': vertical,
'msk-stepper-horizontal': !vertical
}),
style: {
height: `${vertical ? `${stepsArray.length * 4}rem` : 'auto'}`
}
}, rest), stepsToRender, /*#__PURE__*/React__default.createElement("div", {
className: `msk-stepper--progress-bar`,
ref: ref
}))));
};
Stepper.displayName = 'Stepper';
Stepper.propTypes = {
activeStep: PropTypes.number,
children: PropTypes.node,
className: PropTypes.string,
size: PropTypes.oneOf(['small', 'default']),
stepClassName: PropTypes.string,
steps: PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.shape({
label: PropTypes.string,
active: PropTypes.bool,
completed: PropTypes.bool,
disabled: PropTypes.bool,
icon: PropTypes.node,
index: PropTypes.number,
className: PropTypes.string,
children: PropTypes.node
}), PropTypes.element // Allow for JSX elements
])),
title: PropTypes.string,
vertical: PropTypes.bool
};
export { Stepper };