구석에서 밀려 올라오는 새 댓글 알림 카드
배너 블록화면 구석에서 살짝 튀며 올라오는 알림 카드입니다. 아이콘 뒤로 퍼지는 파동, '나중에'와 '댓글 보기' 버튼이 있습니다.
Claude Code · claude-opus-5-5 · React (TSX)
결과 코드펼치기
import { useEffect, useRef, useState } from "react";
export default function CommentToast() {
const card = useRef<HTMLDivElement>(null);
const [visible, setVisible] = useState(true);
const [round, setRound] = useState(0);
useEffect(() => {
if (!visible || window.matchMedia("(prefers-reduced-motion: reduce)").matches) return;
const anim = card.current?.animate(
[
{ opacity: 0, transform: "translateY(16px) scale(0.98)" },
{ opacity: 1, transform: "none" },
],
{ duration: 420, easing: "cubic-bezier(0.2, 0.9, 0.3, 1.2)", fill: "both" },
);
return () => anim?.cancel();
}, [visible, round]);
return (
<section className="w-full bg-[#0b0b0f] px-5 py-16 text-zinc-100 sm:px-8">
<div className="relative mx-auto flex min-h-[320px] max-w-5xl items-end justify-end overflow-hidden rounded-2xl border border-white/10 bg-[radial-gradient(60%_80%_at_20%_10%,rgba(56,189,248,0.10),transparent_70%)] p-4 sm:p-6">
<div className="absolute left-6 top-6 max-w-sm">
<p className="text-sm font-medium">새 소식 알림 카드</p>
<p className="mt-1 text-[13px] text-zinc-500">화면 구석에서 밀려 올라와 할 일을 알려 줍니다.</p>
{!visible && (
<button
type="button"
onClick={() => {
setVisible(true);
setRound((r) => r + 1);
}}
className="mt-3 h-8 rounded-lg border border-white/10 bg-white/[0.05] px-3 text-[13px] hover:bg-white/[0.1]"
>
다시 띄우기
</button>
)}
</div>
{visible && (
<div ref={card} role="status" aria-label="새 댓글 알림" className="w-full sm:w-[360px]">
<div className="rounded-2xl border border-sky-400/30 bg-[#16161d]/95 p-4 shadow-[0_20px_50px_-12px_rgba(0,0,0,0.8)] backdrop-blur">
<div className="flex items-start gap-3">
<span aria-hidden className="relative mt-0.5 flex h-9 w-9 shrink-0 items-center justify-center rounded-full bg-gradient-to-br from-sky-500 to-indigo-500 text-white">
<span className="absolute inset-0 animate-ping rounded-full bg-sky-500/50" />
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" className="relative">
<path
d="M2.5 4A1.5 1.5 0 0 1 4 2.5h8A1.5 1.5 0 0 1 13.5 4v5.5A1.5 1.5 0 0 1 12 11H7l-3 2.5V11a1.5 1.5 0 0 1-1.5-1.5V4Z"
stroke="currentColor"
strokeWidth="1.5"
strokeLinejoin="round"
/>
</svg>
</span>
<div className="min-w-0 flex-1">
<p className="text-sm font-medium">지윤님이 시안에 댓글 3개를 남겼어요</p>
<p className="mt-0.5 text-[13px] text-zinc-400">랜딩 페이지 v2 · 방금 전. 다른 알림 2개가 더 있어요.</p>
</div>
</div>
<div className="mt-3 flex justify-end gap-2">
<button
type="button"
onClick={() => setVisible(false)}
className="h-8 rounded-lg px-3 text-[13px] text-zinc-400 transition hover:bg-white/[0.06] hover:text-zinc-100"
>
나중에
</button>
<a
href="#"
className="flex h-8 items-center rounded-lg bg-gradient-to-r from-sky-500 to-indigo-500 px-3 text-[13px] font-medium text-white shadow-[0_0_24px_-6px_rgba(56,189,248,0.7)] transition hover:brightness-110"
>
댓글 보기
</a>
</div>
</div>
</div>
)}
</div>
</section>
);
}
적용 사이트 0
이 블록이 실제로 쓰인 사이트입니다.
아직 등록된 사이트가 없습니다. 이 블록을 쓴 사이트가 있다면 알려 주세요.
재현 후기
v1 · 0개아직 이 버전의 프롬프트로 직접 만들어 본 사람이 없습니다. 첫 번째로 재현해 보세요.