UNPKG

@unicity/design-system

Version:

A comprehensive React component library built on Material-UI with advanced theming capabilities including neumorphism design support

151 lines 7.9 kB
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime"; import { Stepper as MuiStepper, Step, StepLabel, StepContent, StepButton, Box, Typography, Button, Collapse, LinearProgress, } from '@mui/material'; import { Check, Error as ErrorIcon, } from '@mui/icons-material'; import { styled } from '@mui/material/styles'; const StyledStepper = styled(MuiStepper, { shouldForwardProp: (prop) => prop !== 'variant', })(({ theme, variant = 'default' }) => ({ ...(variant === 'outlined' && { padding: theme.spacing(2), border: `1px solid ${theme.palette.divider}`, borderRadius: theme.shape.borderRadius, backgroundColor: theme.palette.background.paper, }), ...(variant === 'compact' && { '& .MuiStepLabel-root': { paddingTop: theme.spacing(0.5), paddingBottom: theme.spacing(0.5), }, }), })); const CustomStepIcon = styled('div')(({ theme, ownerState }) => ({ width: 24, height: 24, borderRadius: '50%', display: 'flex', alignItems: 'center', justifyContent: 'center', fontSize: '0.875rem', fontWeight: 500, backgroundColor: theme.palette.grey[300], color: theme.palette.text.secondary, ...(ownerState.active && { backgroundColor: theme.palette.primary.main, color: theme.palette.primary.contrastText, boxShadow: `0 0 0 3px ${theme.palette.primary.main}20`, }), ...(ownerState.completed && { backgroundColor: theme.palette.success.main, color: theme.palette.success.contrastText, }), ...(ownerState.error && { backgroundColor: theme.palette.error.main, color: theme.palette.error.contrastText, }), ...(ownerState.color && ownerState.color !== 'primary' && ownerState.active && { backgroundColor: theme.palette[ownerState.color].main, color: theme.palette[ownerState.color].contrastText, boxShadow: `0 0 0 3px ${theme.palette[ownerState.color].main}20`, }), })); const ProgressContainer = styled(Box)(({ theme }) => ({ display: 'flex', alignItems: 'center', gap: theme.spacing(2), marginBottom: theme.spacing(2), })); const defaultLabels = { next: 'Next', back: 'Back', finish: 'Finish', reset: 'Reset', }; const renderStepIcon = (stepData, index, activeStep) => { const isActive = index === activeStep; const isCompleted = index < activeStep; const hasError = Boolean(stepData.error); if (stepData.icon) { return (_jsx(CustomStepIcon, { ownerState: { active: isActive, completed: isCompleted, error: hasError, icon: stepData.icon, color: stepData.color, }, children: stepData.icon })); } if (hasError) { return (_jsx(CustomStepIcon, { ownerState: { active: isActive, completed: isCompleted, error: hasError, color: stepData.color, }, children: _jsx(ErrorIcon, { fontSize: "small" }) })); } if (isCompleted) { return (_jsx(CustomStepIcon, { ownerState: { active: isActive, completed: isCompleted, error: hasError, color: stepData.color, }, children: _jsx(Check, { fontSize: "small" }) })); } return (_jsx(CustomStepIcon, { ownerState: { active: isActive, completed: isCompleted, error: hasError, color: stepData.color, }, children: index + 1 })); }; export const Stepper = ({ steps, activeStep, onStepClick, orientation = 'horizontal', variant = 'default', nonLinear = false, showProgress = false, alternativeLabel = false, connector, animated = true, }) => { const progress = ((activeStep + 1) / steps.length) * 100; const handleStepClick = (stepIndex) => { if (nonLinear && onStepClick && !steps[stepIndex].disabled) { onStepClick(stepIndex); } }; const renderStep = (stepData, index) => { const isActive = index === activeStep; const isCompleted = index < activeStep; const stepProps = { completed: isCompleted, disabled: Boolean(stepData.disabled), }; if (stepData.error) { stepProps.error = true; } const labelProps = { optional: stepData.optional ? (_jsx(Typography, { variant: "caption", color: "textSecondary", children: "Optional" })) : undefined, error: Boolean(stepData.error), StepIconComponent: () => renderStepIcon(stepData, index, activeStep), }; if (nonLinear) { return (_jsxs(Step, { ...stepProps, children: [_jsxs(StepButton, { onClick: () => handleStepClick(index), ...labelProps, children: [stepData.label, stepData.description && (_jsx(Typography, { variant: "body2", color: "textSecondary", children: stepData.description }))] }), orientation === 'vertical' && stepData.content && (_jsx(StepContent, { children: _jsx(Box, { sx: { pb: 2 }, children: stepData.content }) }))] }, stepData.id)); } return (_jsxs(Step, { ...stepProps, children: [_jsxs(StepLabel, { ...labelProps, children: [stepData.label, stepData.description && orientation === 'vertical' && (_jsx(Typography, { variant: "body2", color: "textSecondary", children: stepData.description }))] }), orientation === 'vertical' && stepData.content && isActive && (_jsx(StepContent, { children: _jsx(Collapse, { in: isActive, timeout: animated ? 300 : 0, children: _jsx(Box, { sx: { pb: 2 }, children: stepData.content }) }) }))] }, stepData.id)); }; return (_jsxs(Box, { children: [showProgress && (_jsxs(ProgressContainer, { children: [_jsxs(Typography, { variant: "body2", color: "textSecondary", sx: { minWidth: 60 }, children: ["Step ", activeStep + 1, " of ", steps.length] }), _jsx(LinearProgress, { variant: "determinate", value: progress, sx: { flex: 1, height: 6, borderRadius: 3 } }), _jsxs(Typography, { variant: "body2", color: "textSecondary", children: [Math.round(progress), "%"] })] })), _jsx(StyledStepper, { activeStep: activeStep, orientation: orientation, alternativeLabel: alternativeLabel, connector: connector, nonLinear: nonLinear, sx: { ...(variant === 'outlined' && { padding: 2, border: 1, borderColor: 'divider', borderRadius: 1, backgroundColor: 'background.paper', }), ...(variant === 'compact' && { '& .MuiStepLabel-root': { paddingTop: 0.5, paddingBottom: 0.5, }, }), }, children: steps.map(renderStep) })] })); }; export const StepperControls = ({ activeStep, totalSteps, onNext, onBack, onReset, nextDisabled = false, backDisabled = false, labels = defaultLabels, showReset = true, }) => { const mergedLabels = { ...defaultLabels, ...labels }; const isLastStep = activeStep === totalSteps - 1; const isCompleted = activeStep >= totalSteps; if (isCompleted && showReset) { return (_jsx(Box, { sx: { display: 'flex', justifyContent: 'center', pt: 2 }, children: _jsx(Button, { onClick: onReset, variant: "outlined", children: mergedLabels.reset }) })); } return (_jsxs(Box, { sx: { display: 'flex', justifyContent: 'space-between', pt: 2 }, children: [_jsx(Button, { disabled: activeStep === 0 || backDisabled, onClick: onBack, variant: "outlined", children: mergedLabels.back }), _jsx(Button, { disabled: nextDisabled, onClick: onNext, variant: "contained", children: isLastStep ? mergedLabels.finish : mergedLabels.next })] })); }; //# sourceMappingURL=Stepper.js.map