@kadconsulting/dry
Version:
KAD Reusable Component Library
110 lines • 7.63 kB
JavaScript
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
import { forwardRef, useEffect, useRef, useState } from 'react';
import classnames from 'classnames';
import './ProgressSteps.scss';
import { Icon, TextMd, TextXs, Circle, CheckCircle } from '..';
const ProgressSteps = forwardRef(({ steps, progressBarEnabled = true, size = 'md', orientation = 'horizontal', alignment = 'center', activeColor = '#007bff', onStepClick,
// TODO-p4: Add this to the story book
highlightMethod = 'line', TitleComponent = TextMd, TextComponent = TextXs, typographyProps = {}, hasIcon = true, step, isMobile = false, ...props }, ref) => {
const [activeStep, setActiveStep] = useState(0);
const stepsContainerRef = useRef(null);
const [progressBarHeight, setProgressBarHeight] = useState('0');
useEffect(() => {
if (orientation === 'vertical' && stepsContainerRef.current) {
setProgressBarHeight(`${stepsContainerRef.current.offsetHeight}px`);
}
}, [orientation, steps]);
useEffect(() => {
if (step !== undefined) {
setActiveStep(step);
}
}, [step]);
const handleStepClick = (step) => {
// TODO-p2: we should ba able to change the current step from the props
setActiveStep(step);
if (onStepClick) {
onStepClick(step);
}
};
const progressPercentage = (activeStep / (steps.length - 1)) * 100;
const progressPercentageFillStyle = {
[orientation === 'horizontal'
? 'width'
: 'height']: `${progressPercentage}%`,
};
const generateStyles = (index) => {
const isFirst = index === 0;
if (isFirst)
return {};
if (!hasIcon) {
const progressContainerPercentage = 100;
const progressContainerPercentageFillStyle = {
[orientation === 'horizontal'
? 'width'
: 'height']: `${progressContainerPercentage}%`,
};
return progressContainerPercentageFillStyle;
}
const progressContainerPercentage = steps.length * 100;
const progressContainerPercentageFillStyle = {
[orientation === 'horizontal'
? 'width'
: 'height']: `${progressContainerPercentage}%`,
};
return progressContainerPercentageFillStyle;
};
const generateTextStyles = (index, isLast) => {
const isFirst = index === 0;
const progressPercentage = steps.length * 100;
if (!hasIcon)
return {};
if (!hasIcon) {
const progressContainerPercentage = 100;
const progressContainerPercentageFillStyle = {
[orientation === 'horizontal'
? 'width'
: 'height']: `${progressContainerPercentage}%`,
};
return progressContainerPercentageFillStyle;
}
if (isFirst)
return {
[orientation === 'horizontal'
? 'width'
: 'height']: `${progressPercentage}%`,
transform: 'translateX(-30%)',
};
if (isLast)
return {
[orientation === 'horizontal'
? 'width'
: 'height']: `${progressPercentage}%`,
transform: 'translateX(42%)',
};
const progressContainerPercentage = 100;
const progressContainerPercentageFillStyle = {
[orientation === 'horizontal'
? 'width'
: 'height']: `${progressContainerPercentage}%`,
transform: `translateX(${100 / (steps?.length - 1) + 5}%)`,
};
return progressContainerPercentageFillStyle;
};
return (_jsxs("div", { className: classnames('progress-steps', orientation, alignment), ref: ref, ...props, children: [!isMobile && progressBarEnabled && highlightMethod === 'line' && (_jsx("div", { className: classnames('progress-bar-container', orientation, alignment), style: {
height: orientation === 'vertical' ? progressBarHeight : 'auto',
}, children: _jsx("div", { className: classnames('progress-bar', orientation, alignment), children: _jsx("div", { className: 'fill', style: progressPercentageFillStyle }) }) })), _jsxs("div", { className: classnames('steps-container', orientation, alignment), ref: stepsContainerRef, children: [!isMobile &&
steps.map((step, index) => {
const isActive = activeStep === index;
const isCompleted = activeStep > index;
const isFirst = index === 0;
const isLast = index === steps.length - 1;
return (_jsxs("div", { className: classnames('step', { active: isActive, firstStep: isFirst, lastStep: isLast }, size), style: generateStyles(index), onClick: () => handleStepClick(index), onKeyUp: (event) => {
if (event.key === 'Enter')
handleStepClick(index);
}, tabIndex: 0, children: [hasIcon && (_jsx("div", { className: 'icon-container', children: isCompleted ? (_jsx(Icon, { Path: CheckCircle, fill: 'white' })) : (_jsx(Icon, { Path: Circle, fill: 'white' })) })), _jsxs("div", { className: classnames('text-container', {
'no-icon': !hasIcon,
}), style: generateTextStyles(index, isLast), children: [_jsx("span", { className: 'text-container__title', children: step.title }), _jsx("span", { className: 'text-container__text', children: step.text })] })] }, step.id ?? index));
}), isMobile && (_jsxs(_Fragment, { children: [_jsx("div", { className: 'mobile__steps-container', children: _jsx("div", { className: classnames('mobile__step', { active: true }), onClick: () => handleStepClick(activeStep), children: _jsx("div", { className: 'mobile__icon-container', children: _jsxs("svg", { className: 'mobile__icon-container', viewBox: '0 0 100 100', children: [_jsx("circle", { className: 'mobile__progress-ring-bg', cx: '50', cy: '50', r: '45', fill: 'transparent', strokeWidth: '5', stroke: '#ddd' }), _jsx("circle", { className: 'mobile__progress-ring', cx: '50', cy: '50', r: '45', fill: 'transparent', strokeWidth: '6', stroke: '#002B7A', strokeDasharray: '283', strokeDashoffset: 283 - (activeStep / (steps.length - 1)) * 283, transform: 'rotate(-90 50 50)' }), _jsx("text", { className: 'mobile__step-text', x: '50%', y: '50%', textAnchor: 'middle', dominantBaseline: 'middle', children: `${activeStep} / ${steps.length - 1}` })] }) }) }) }), _jsxs("div", { className: 'mobile__step-info', children: [activeStep > 0 && (_jsxs("div", { className: 'mobile__step-info-text-wrapper', onClick: () => handleStepClick(activeStep - 1), children: [_jsx("span", { className: 'mobile__step-info-text1', children: "Previous:" }), _jsx("span", { className: 'mobile__step-info-text2', children: ` ${steps[activeStep - 1].text}` })] })), activeStep < steps.length - 1 && (_jsxs("div", { className: 'mobile__step-info-text-wrapper', onClick: () => handleStepClick(activeStep + 1), children: [_jsx("span", { className: 'mobile__step-info-text1', children: "Next:" }), _jsx("span", { className: 'mobile__step-info-text2', children: ` ${steps[activeStep + 1].text}` })] }))] })] }))] })] }));
});
export default ProgressSteps;
//# sourceMappingURL=ProgressSteps.js.map