UNPKG

@kadconsulting/dry

Version:
110 lines 7.63 kB
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