* Remove all links legacyBehavior * fix: resolve type errors in Button and Dropdown when using Link without legacyBehavior - Button.tsx: Only pass ref to button element, not to Link (Link manages its own anchor) - Dropdown.tsx: Strip ref from props when using Link to avoid type incompatibility This fixes the type errors that were causing API V1 and V2 builds to fail. Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com> * fix: only pass disabled and type props to button element, not to Link Link component doesn't accept disabled or type props, so these should only be passed when rendering a button element. Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com> * fix: strip ref from passThroughProps when rendering Link The passThroughProps spread was including a ref property that's incompatible with Link's expected ref type. This strips the ref when rendering a Link component. Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com> * fix: use type assertion for React.createElement props to handle union types The Button component uses a union type for props that can be either Link or button props. TypeScript can't narrow the union type properly when using React.createElement with a dynamic element type, so we use a type assertion to cast the props to the correct type. Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com> * fix: render Link and button separately to avoid type conflicts Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com> * fix: preserve data-testid when rendering Button as Link Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com> --------- Co-authored-by: Anik Dhabal Babu <81948346+anikdhabal@users.noreply.github.com> Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
72 lines
2.5 KiB
TypeScript
72 lines
2.5 KiB
TypeScript
import { useAutoAnimate } from "@formkit/auto-animate/react";
|
|
import Link from "next/link";
|
|
|
|
type DefaultStep = {
|
|
title: string;
|
|
};
|
|
|
|
function Stepper<T extends DefaultStep>(props: {
|
|
href: string;
|
|
step: number;
|
|
steps: T[];
|
|
disableSteps?: boolean;
|
|
stepLabel?: (currentStep: number, totalSteps: number) => string;
|
|
}) {
|
|
const {
|
|
href,
|
|
steps,
|
|
stepLabel = (currentStep, totalSteps) => `Step ${currentStep} of ${totalSteps}`,
|
|
} = props;
|
|
const [stepperRef] = useAutoAnimate<HTMLOListElement>();
|
|
return (
|
|
<>
|
|
{steps.length > 1 && (
|
|
<nav className="flex items-center justify-center" aria-label="Progress">
|
|
<p className="text-sm font-medium">{stepLabel(props.step, steps.length)}</p>
|
|
<ol role="list" className="ml-8 flex items-center space-x-5" ref={stepperRef}>
|
|
{steps.map((mapStep, index) => (
|
|
<li key={mapStep.title}>
|
|
{index + 1 < props.step ? (
|
|
<Link
|
|
href={props.disableSteps ? "#" : `${href}?step=${index + 1}`}
|
|
shallow
|
|
replace
|
|
className="hover:bg-inverted block h-2.5 w-2.5 rounded-full bg-gray-600">
|
|
<span className="sr-only">{mapStep.title}</span>
|
|
</Link>
|
|
) : index + 1 === props.step ? (
|
|
<Link
|
|
href={props.disableSteps ? "#" : `${href}?step=${index + 1}`}
|
|
shallow
|
|
replace
|
|
className="relative flex items-center justify-center"
|
|
aria-current="step">
|
|
<span className="absolute flex h-5 w-5 p-px" aria-hidden="true">
|
|
<span className="bg-emphasis h-full w-full rounded-full" />
|
|
</span>
|
|
<span
|
|
className="relative block h-2.5 w-2.5 rounded-full bg-gray-600"
|
|
aria-hidden="true"
|
|
/>
|
|
<span className="sr-only">{mapStep.title}</span>
|
|
</Link>
|
|
) : (
|
|
<Link
|
|
href={props.disableSteps ? "#" : `${href}?step=${index + 1}`}
|
|
shallow
|
|
replace
|
|
className="bg-emphasis block h-2.5 w-2.5 rounded-full hover:bg-gray-400">
|
|
<span className="sr-only">{mapStep.title}</span>
|
|
</Link>
|
|
)}
|
|
</li>
|
|
))}
|
|
</ol>
|
|
</nav>
|
|
)}
|
|
</>
|
|
);
|
|
}
|
|
|
|
export default Stepper;
|