패턴

겹쳐 쌓였다 펼쳐지는 스택 토스트

토스트가 화면 한쪽에 겹쳐 쌓였다가, 마우스를 올리면 세로로 펼쳐져 전부 읽을 수 있습니다. 스와이프로 닫고, 두면 자동으로 사라지는 Sonner 스타일 알림.

ReactTypeScriptPointer EventsCSS transform/transitionperformance.now
라이브 데모
새 탭에서 열기
데모 불러오는 중…

제작 과정

한 줄 요약

여러 알림을 한 화면에 쌓되, 평소엔 겹쳐 공간을 아끼고 hover 시 펼쳐 전부 읽게 하는 토스트 스택입니다.

이럴 때 필요해요

알림이 동시에 여러 개 뜨면 화면을 가득 메워 정작 본 작업을 방해합니다. 그렇다고 하나씩만 보여주면 놓치는 게 생기죠. 겹쳐 쌓아두면 공간은 카드 한 장 크기로 유지되면서도 "뒤에 더 있다"는 신호를 주고, 사용자가 확인하고 싶을 때만 펼쳐 읽게 할 수 있습니다.

어떻게 동작하나

  1. 토스트마다 스택 내 index로 translateYscaleopacity를 계산합니다 collapsed는 살짝 겹치고, expanded는 카드 높이만큼 벌립니다.

  2. 컨테이너 hover를 감지해 collapsedexpanded를 전환합니다.

  3. 각 토스트는 performance.now()로 남은 시간을 보존해, hover 중엔 타이머를 멈췄다가 벗어나면 이어서 갑니다.

놓치기 쉬운 것

  • 자동 닫힘 타이머를 단순 정지/재시작하면 hover할 때마다 시간이 초기화됩니다 남은 시간을 따로 보존해야 자연스럽습니다.

  • 스와이프 닫기는 Pointer Events로 처리하고 touch-action: pan-y를 줘야 세로 스크롤과 충돌하지 않습니다.

  • 화면을 다 메우지 않도록 최대 개수를 정해 오래된 것을 밀어내야 합니다.

이런 곳에 써요

  • 저장동기화업로드 결과 같은 연속 알림

  • 협업 툴의 실시간 이벤트 알림

소스 코드

· 데모 페이지에서 자동 추출
import type { Metadata } from "next";
import { StackedToast } from "./-components/StackedToast";

export const metadata: Metadata = {
  title: "아코디언 스택 토스트 (데모)",
  description:
    "평소엔 겹쳐 쌓였다가 hover하면 세로로 펼쳐지는 Sonner 스타일 토스트. 자동 dismiss(hover 시 일시정지) + 스와이프 닫기 + 접근성 대응.",
  robots: { index: false, follow: false },
};

export default function Page() {
  return (
    <main className="flex min-h-[100dvh] items-center justify-center bg-gradient-to-br from-slate-50 via-white to-violet-50/40">
      <StackedToast />
    </main>
  );
}
20조회수

댓글