Docs
Notice Card
A card component for displaying important notices with an accept toggle.
requires interactiontoggle
Installation
Install dependencies
npm install framer-motion
Run the following command
It will create a new file notice-card.tsx
inside the components/animata/card
directory.
mkdir -p components/animata/card && touch components/animata/card/notice-card.tsx
Paste the code
Open the newly created file and paste the following code:
import { useState } from "react";
import { motion } from "framer-motion";
import { cn } from "@/lib/utils";
interface NoticeCardProps {
acceptText?: string;
title?: string;
description?: string;
}
export default function NoticeCard({
acceptText = "Accept",
title = "To your attention!",
description = "Due to severe weather conditions, we will be closed from 11th to 14th of January.",
}: NoticeCardProps) {
const [isAccepted, setIsAccepted] = useState<boolean>(false);
const handleClick = () => {
setIsAccepted(!isAccepted);
};
const bgClass = isAccepted
? "bg-green-300"
: "bg-gradient-to-r from-slate-50 via-slate-50 to-green-100";
return (
<div className="flex items-center justify-center">
{/* Outer container with breathing scaling effect */}
<div className="relative max-w-md p-2">
{/* Mid-level static container */}
<motion.div
className="absolute inset-0 rounded-3xl bg-white shadow-xl"
animate={{ scale: isAccepted ? 0.97 : 1 }}
transition={{
duration: 0.5,
ease: "easeInOut",
repeat: 1,
repeatType: "reverse",
}}
/>
{/* Stable inner content */}
<div className="relative z-10 rounded-3xl p-6 text-center shadow-md" onClick={handleClick}>
<div className="flex min-w-36 flex-col items-center">
{/* Icon */}
<div>
<svg
className="h-10 w-10"
xmlns="http://www.w3.org/2000/svg"
fill="#000"
viewBox="0 0 246.027 246.027"
stroke="#fff"
>
<path
d="M242.751,196.508L143.937,25.358c-4.367-7.564-12.189-12.081-20.924-12.081c-8.735,0-16.557,4.516-20.924,12.081
L3.276,196.508c-4.368,7.564-4.368,16.596,0,24.161s12.189,12.081,20.924,12.081h197.629c8.734,0,16.556-4.516,20.923-12.08
C247.119,213.105,247.118,204.073,242.751,196.508z M123.014,204.906c-8.672,0-15.727-7.055-15.727-15.727
c0-8.671,7.055-15.726,15.727-15.726s15.727,7.055,15.727,15.726C138.74,197.852,131.685,204.906,123.014,204.906z M138.847,137.68
c0,8.73-7.103,15.833-15.833,15.833s-15.833-7.103-15.833-15.833V65.013c0-4.142,3.358-7.5,7.5-7.5h16.667
c4.143,0,7.5,3.358,7.5,7.5V137.68z"
/>
</svg>
</div>
{/* Title */}
<h2 className="mt-2 text-xl font-bold">{title}</h2>
{/* Description */}
<p className="mt-2 text-gray-600">{description}</p>
{/* Toggle Button */}
<div
className={cn(
"relative mt-4 flex h-12 w-4/5 cursor-pointer items-center rounded-xl px-2 py-1 transition-colors duration-300",
bgClass,
)}
>
{/* Toggle Handle */}
<div
className={`h-10 w-1/2 transform rounded-lg bg-white shadow-lg drop-shadow-md transition-transform duration-500 ${
isAccepted ? "translate-x-full" : ""
}`}
></div>
{/* Accept Text */}
<span
className={`absolute right-4 transform font-bold text-green-800 transition-transform duration-500 ${
isAccepted ? "opacity-0" : "opacity-100"
}`}
>
<svg
className="mr-1 inline-block h-5 w-5"
xmlns="http://www.w3.org/2000/svg"
fill="#000"
viewBox="0 0 48 48"
stroke="currentColor"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth="2"
d="m24 8-2.83 2.83L32.34 22H8v4h24.34L21.17 37.17 24 40l16-16z"
/>
</svg>
{acceptText}
</span>
</div>
</div>
</div>
</div>
</div>
);
}
Credits
Built by Abhinandan