aura-glass
Version:
A comprehensive glassmorphism design system for React applications with 142+ production-ready components
212 lines (209 loc) • 7.36 kB
JavaScript
'use client';
import { jsxs, jsx } from 'react/jsx-runtime';
import React, { forwardRef } from 'react';
import { GlassProgress } from '../../data-display/GlassProgress.js';
import { VStack, HStack } from '../../layout/GlassStack.js';
import { cn } from '../../../lib/utilsComprehensive.js';
/**
* StepIndicator component
* Individual step indicator for wizard navigation
*/
const StepIndicator = /*#__PURE__*/forwardRef(({
step,
index,
isActive,
isCompleted,
isClickable,
onClick,
layout = "default"
}, ref) => {
const handleClick = event => {
if (isClickable && onClick) {
onClick(event);
}
};
const renderStepIcon = () => {
if (isCompleted) {
return jsx("div", {
"data-glass-component": true,
className: 'w-8 h-8 glass-radius-full bg-success glass-flex glass-items-center glass-justify-center',
children: jsx("svg", {
className: 'w-4 h-4 text-success-foreground',
fill: "currentColor",
viewBox: "0 0 20 20",
children: jsx("path", {
fillRule: "evenodd",
d: "M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z",
clipRule: "evenodd"
})
})
});
}
return jsx("div", {
className: cn("w-8 h-8 glass-radius-full flex items-center justify-center glass-text-sm font-medium border-2 transition-colors", isActive ? "bg-primary border-primary text-primary-foreground" : "bg-background border-border glass-text-secondary"),
children: index + 1
});
};
const renderStepContent = () => {
if (layout === "compact") {
return renderStepIcon();
}
return jsxs(VStack, {
space: "xs",
align: "center",
children: [renderStepIcon(), jsxs(VStack, {
space: "xs",
align: "center",
children: [jsx("span", {
className: cn("glass-text-sm font-medium transition-colors", isActive ? "text-primary" : isCompleted ? "text-success" : "glass-text-secondary"),
children: step.title
}), step.optional && jsx("span", {
className: "glass-text-xs glass-text-secondary glass-surface-subtle glass-px-1.5 glass-py-0.5 glass-radius-md",
children: "Optional"
})]
})]
});
};
if (layout === "vertical") {
return jsxs("div", {
ref: ref,
className: "glass-flex glass-items-start glass-gap-4",
children: [jsxs("div", {
className: "glass-flex glass-flex-col glass-items-center",
children: [renderStepIcon(), index < step.title.length - 1 && jsx("div", {
className: cn("w-0.5 h-8 glass-mt-2 transition-colors", isCompleted ? "bg-success" : "bg-border")
})]
}), jsxs(VStack, {
space: "xs",
className: "glass-flex-1",
children: [jsx("span", {
className: cn("font-medium transition-colors", isActive ? "text-primary" : isCompleted ? "text-success" : "glass-text-secondary"),
children: step.title
}), step.description && jsx("p", {
className: "glass-text-sm glass-text-secondary",
children: step.description
}), step.optional && jsx("span", {
className: 'glass-text-xs glass-text-secondary glass-surface-subtle glass-px-1.5 glass-py-0.5 glass-radius-md w-fit',
children: "Optional"
})]
})]
});
}
return jsx("div", {
ref: ref,
className: cn("flex flex-col items-center transition-opacity", isClickable && "cursor-pointer hover:opacity-80", !isClickable && "cursor-default"),
onClick: handleClick,
children: renderStepContent()
});
});
StepIndicator.displayName = "StepIndicator";
/**
* GlassFormWizardSteps component
* Step indicator and navigation for wizard forms
*/
const GlassFormWizardSteps = /*#__PURE__*/forwardRef(({
steps = [],
currentStep,
completedSteps,
onStepClick,
layout = "default",
showProgress = true,
showNumbers = true,
clickable = true,
className,
...props
}, ref) => {
const totalSteps = steps?.length || 0;
const progressValue = totalSteps > 0 ? (currentStep + 1) / totalSteps * 100 : 0;
const handleStepClick = stepIndex => {
if (clickable && onStepClick) {
onStepClick(stepIndex);
}
};
const isStepClickable = stepIndex => {
if (!clickable) return false;
// Allow clicking on current step, completed steps, and next step if previous is completed
return stepIndex === currentStep || completedSteps.has(stepIndex) || stepIndex === currentStep + 1 && completedSteps.has(stepIndex - 1);
};
const renderProgressBar = () => {
if (!showProgress) return null;
return jsxs(VStack, {
space: "sm",
children: [jsxs(HStack, {
space: "sm",
align: "center",
justify: "between",
children: [jsxs("span", {
className: 'glass-text-sm font-medium text-primary',
children: ["Step ", currentStep + 1, " of ", totalSteps]
}), jsxs("span", {
className: "glass-text-sm glass-text-secondary",
children: [Math.round(progressValue), "% Complete"]
})]
}), jsx(GlassProgress, {
value: progressValue,
size: "sm",
variant: "default",
showValue: false
})]
});
};
const renderSteps = () => {
if (layout === "vertical") {
return jsx(VStack, {
space: "md",
children: steps.map((step, index) => jsx("div", {
className: 'animate-slide-in-left',
style: {
animationDelay: `${Math.min(index, 5) * 100}ms`,
animationFillMode: "both"
},
children: jsx(StepIndicator, {
step: step,
index: index,
isActive: index === currentStep,
isCompleted: completedSteps.has(index),
isClickable: isStepClickable(index),
onClick: e => handleStepClick(index),
layout: layout
})
}, step.id))
});
}
return jsx("div", {
className: cn("flex items-center", layout === "compact" ? "justify-center glass-gap-2" : "justify-between"),
children: steps.map((step, index) => jsxs(React.Fragment, {
children: [jsx("div", {
className: 'animate-slide-in-up',
style: {
animationDelay: `${Math.min(index, 5) * 100}ms`,
animationFillMode: "both"
},
children: jsx(StepIndicator, {
step: step,
index: index,
isActive: index === currentStep,
isCompleted: completedSteps.has(index),
isClickable: isStepClickable(index),
onClick: e => handleStepClick(index),
layout: layout
})
}), index < totalSteps - 1 && layout !== "compact" && jsx("div", {
className: cn("flex-1 h-0.5 glass-mx-4 transition-colors", completedSteps.has(index) ? "bg-success" : "bg-border")
})]
}, step.id))
});
};
return jsx("div", {
ref: ref,
className: cn("w-full", className),
...props,
children: jsxs(VStack, {
space: "lg",
children: [renderProgressBar(), renderSteps()]
})
});
});
GlassFormWizardSteps.displayName = "GlassFormWizardSteps";
export { GlassFormWizardSteps };
//# sourceMappingURL=GlassFormWizardSteps.js.map