Docs
Direction Card
A direction card which adapts itself on directions and distance
Installation
Install dependencies
bash npm install lucide-react
Run the following command
It will create a new file called direction-card.tsx
inside the components/animata/widget
directory.
mkdir -p components/animata/widget && touch components/animata/widget/direction-card.tsx
Paste the code
Open the newly created file and paste the following code:
"use client";
import { ElementType, useEffect, useState } from "react";
import { ArrowUp, CornerUpLeft, CornerUpRight } from "lucide-react";
import { cn } from "@/lib/utils";
interface Direction {
distance: number;
direction: string;
to: string;
iconType: ElementType;
}
interface IDirectionCardProps {
directionValues: Direction[];
duration?: number;
}
export const testDirectionProps: IDirectionCardProps = {
directionValues: [
{
distance: 350,
direction: "right",
to: "Gurkha St.",
iconType: CornerUpRight,
},
{
distance: 700,
direction: "left",
to: "Rounding St.",
iconType: CornerUpLeft,
},
{
distance: 100,
direction: "left",
to: "Fulbari marga",
iconType: CornerUpLeft,
},
{
distance: 1000,
direction: "straight",
to: "hwy 16",
iconType: ArrowUp,
},
],
};
function DirectionCard({
directionValues = testDirectionProps.directionValues,
duration = 5000,
}: IDirectionCardProps) {
const [currentIndex, setCurrentIndex] = useState(0);
const [iconState, setIconState] = useState({
prevIconType: directionValues[directionValues.length - 1].iconType,
currentIconType: directionValues[0].iconType,
nextIconType: directionValues[1].iconType,
});
const [progress, setProgress] = useState(0);
useEffect(() => {
//this would change the states based on direction change. Currently set to setInterval.
const changeDirectionInterval = setInterval(() => {
setCurrentIndex((prevIndex) => {
const newIndex = (prevIndex + 1) % directionValues.length;
const prev =
newIndex === 0
? directionValues[directionValues.length - 1].iconType
: directionValues[newIndex - 1].iconType;
const next =
newIndex === directionValues.length - 1
? directionValues[0].iconType
: directionValues[newIndex + 1].iconType;
setIconState({
prevIconType: prev,
currentIconType: directionValues[newIndex].iconType,
nextIconType: next,
});
return newIndex;
});
setProgress(0);
}, duration ?? 5000);
const progressIncrement = 100 / ((duration ?? 5000) / 100);
const progressInterval = setInterval(() => {
setProgress((prevProgress) => {
if (prevProgress >= 100) {
return 100;
}
return prevProgress + progressIncrement;
});
}, 100);
return () => {
clearInterval(changeDirectionInterval);
clearInterval(progressInterval);
};
}, [directionValues, duration]);
const currentDirection = directionValues[currentIndex];
const renderIcon = (IconComponent: ElementType, size = 52, color = "text-gray-300") => (
<IconComponent size={size} className={cn("text-white", color)} />
);
return (
<div className="direction-card flex size-52 items-start justify-between rounded-3xl bg-black p-4">
<div className="direction-container flex h-full w-[80%] flex-col items-center justify-center gap-3">
<p className="text-3xl font-bold text-white">
{currentDirection.distance}
<span className="text-opacity-50">m</span>
</p>
<p className="animate-pulse">{renderIcon(iconState.currentIconType, 52, "text-white")}</p>
<p className="text-md h-8 w-20 text-ellipsis break-all text-center text-gray-400">
{currentDirection.to}
</p>
</div>
<div className="progress-icon-container flex h-full w-[100px] flex-row-reverse justify-around">
<div className="relative flex flex-col justify-evenly">
<div
style={{ boxShadow: "inset 0px -30px 20px 0px black" }}
className="absolute inset-0 shadow"
/>
{renderIcon(iconState.prevIconType, 32)}
{renderIcon(iconState.currentIconType, 32, "text-green-300")}
{renderIcon(iconState.nextIconType, 32)}
</div>
<div
style={{ height: "100%" }}
className="progress-bar flex h-full w-[6px] items-end rounded-xl bg-gray-400"
>
<div
style={{ height: `${progress}%` }}
className="progress-bar h-full w-[6px] rounded-xl bg-green-300 shadow-glow2"
/>
</div>
</div>
</div>
);
}
export default DirectionCard;
Credits
Built by Aadarsh Baral