@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
JavaScript
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