107 lines
3.9 KiB
TypeScript
107 lines
3.9 KiB
TypeScript
import _ from 'lodash';
|
|
import React from 'react';
|
|
import { ProgressStepsProps, ProgressStepStatus } from './types';
|
|
|
|
export const ProgressSteps: React.FC<ProgressStepsProps> = ({ steps, onNext, onPrevious, onStepClick, children }) => {
|
|
const handleNext = () => {
|
|
if (onNext) {
|
|
onNext();
|
|
}
|
|
};
|
|
const handlePrevious = () => {
|
|
if (onPrevious) {
|
|
onPrevious();
|
|
}
|
|
};
|
|
|
|
const showNextPage = () => {
|
|
if (onNext) {
|
|
return _.some(steps, { status: ProgressStepStatus.Upcoming });
|
|
}
|
|
return false;
|
|
};
|
|
|
|
const showPreviousPage = () => {
|
|
if (onPrevious) {
|
|
return _.some(steps, { status: ProgressStepStatus.Complete });
|
|
}
|
|
return false;
|
|
};
|
|
|
|
const handleStepClick = (stepId: string) => {
|
|
if (onStepClick) {
|
|
onStepClick(stepId);
|
|
}
|
|
};
|
|
|
|
return (
|
|
<>
|
|
<nav aria-label="Progress">
|
|
{/* eslint-disable-next-line jsx-a11y/no-redundant-roles */}
|
|
<ol role="list" className="space-y-4 md:flex md:space-y-0 md:space-x-8 mb-4">
|
|
{steps.map((step) => (
|
|
<li key={step.name} className="md:flex-1" onClick={() => handleStepClick(step.id)}>
|
|
{step.status === ProgressStepStatus.Complete ? (
|
|
<a
|
|
href={step.href}
|
|
className="group pl-4 py-2 flex flex-col border-l-4 border-primary-500 md:pl-0 md:pb-0 md:border-l-0 md:border-t-4"
|
|
>
|
|
<span className="text-xs text-primary-600 font-semibold tracking-wide uppercase group-hover:text-primary-800">
|
|
{step.id}
|
|
</span>
|
|
<span className="text-sm font-medium">{step.name}</span>
|
|
</a>
|
|
) : step.status === ProgressStepStatus.Current ? (
|
|
<a
|
|
href={step.href}
|
|
className="pl-4 py-2 flex flex-col border-l-4 border-primary-500 md:pl-0 md:pb-0 md:border-l-0 md:border-t-4"
|
|
aria-current="step"
|
|
>
|
|
<span className="text-xs text-primary-600 font-semibold tracking-wide uppercase">{step.id}</span>
|
|
<span className="text-sm font-medium">{step.name}</span>
|
|
</a>
|
|
) : (
|
|
<a
|
|
href={step.href}
|
|
className="group pl-4 py-2 flex flex-col border-l-4 border-gray-200 hover:border-gray-300 md:pl-0 md:pb-0 md:border-l-0 md:border-t-4"
|
|
>
|
|
<span className="text-xs text-gray-500 font-semibold tracking-wide uppercase group-hover:text-gray-700">
|
|
{step.id}
|
|
</span>
|
|
<span className="text-sm font-medium">{step.name}</span>
|
|
</a>
|
|
)}
|
|
</li>
|
|
))}
|
|
</ol>
|
|
</nav>
|
|
|
|
{children}
|
|
|
|
{(showNextPage() || showPreviousPage()) && (
|
|
<div className="pt-4 sm sm:flex">
|
|
<div className="ml-auto sm:flex sm:flex-row-reverse">
|
|
{showNextPage() && (
|
|
<button
|
|
type="button"
|
|
className="w-full inline-flex justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-primary-600 text-base font-medium text-white hover:bg-primary-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary-500 sm:ml-3 sm:w-auto sm:text-sm"
|
|
onClick={handleNext}
|
|
>
|
|
Next
|
|
</button>
|
|
)}
|
|
{showPreviousPage() && (
|
|
<button
|
|
type="button"
|
|
className="w-full inline-flex justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-primary-600 text-base font-medium text-white hover:bg-primary-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary-500 sm:ml-3 sm:w-auto sm:text-sm"
|
|
onClick={handlePrevious}
|
|
>
|
|
Previous
|
|
</button>
|
|
)}
|
|
</div>
|
|
</div>
|
|
)}
|
|
</>
|
|
);
|
|
};
|