구현의 첫 단계는 기본적인 데이터 모델 설정입니다. ActiveModel::Model
을 포함하는 Card
클래스를 정의하여 subject
와 description
을 관리하고, PagesController
에서 샘플 Card
객체들을 생성하여 뷰에 전달합니다. 각 카드는 간단한 _card.html.erb
부분 템플릿을 통해 렌더링됩니다. 시각적 구현을 위해 application.html.erb
레이아웃에 Tailwind CSS 그라디언트 배경을 추가하고, pages/show.html.erb
에서 카드 목록을 화면 하단에 고정 배치합니다. 개별 카드는 bg-white/80
, backdrop-blur-sm
, rounded-lg
, shadow-lg
등의 Tailwind 클래스를 사용하여 시각적으로 매력적인 디자인을 갖도록 스타일링됩니다.
카드들이 겹쳐진 스택 효과를 만들기 위해 Rails의 class_names
헬퍼를 활용합니다. card_counter
변수를 기반으로 각 카드에 scale
, opacity
, translate-y
속성을 조건부로 적용하여 입체적인 스택 형태를 구현합니다. 예를 들어, 가장 위에 있는 카드는 scale-100 translate-y-0
이 적용되고, 그 아래 카드는 scale-95 opacity-75 -translate-y-2
와 같이 점진적으로 변화합니다.
다음으로, 카드 스택의 펼침/접힘 기능을 제어하기 위해 간단한 Stimulus 컨트롤러(cards_controller.js
)를 구현합니다. 이 컨트롤러는 open
이라는 불리언 static value
를 통해 상태를 관리하며, show()
및 hide()
메서드를 통해 openValue
를 토글합니다. HTML에서는 data-controller="cards"
와 data-cards-open-value="false"
를 설정하고, click->cards#show
액션을 통해 클릭 시 스택이 펼쳐지도록 합니다.
카드 부분 템플릿에서는 group-data-[cards-open-value=false]/cards:
및 group-data-[cards-open-value=true]/cards:
와 같은 Tailwind CSS 그룹 데이터 변형자를 사용하여 Stimulus 컨트롤러의 open
상태에 따라 카드의 scale
, translate
, rotate
속성을 동적으로 변경합니다. 이를 통해 카드가 펼쳐질 때 부드럽게 회전하며 분산되는 ‘팬’ 효과를 연출합니다.
사용자 경험을 향상시키기 위해 카드 스택 외부 클릭 시 스택을 접는 기능을 추가합니다. 이를 위해 Stimulus FX 패키지를 설치하고 registerActionOptions
를 통해 애플리케이션에 등록합니다. data-action="click->cards#show click@window->cards#hide:stop:whenOutside"
액션을 사용하여, 카드 스택 내부 클릭 시 show()
메서드를 호출하고, 윈도우 전체에서 발생하는 클릭 이벤트 중 스택 외부에서 발생한 경우에만 whenOutside
수정자를 통해 hide()
메서드를 호출하도록 설정합니다.
마지막으로, 카드 스택이 닫힌 상태에서 개별 카드를 클릭했을 때 링크가 활성화되어 페이지가 이동하는 버그를 해결합니다. 이는 Tailwind CSS의 pointer-events-none
유틸리티 클래스를 group-data-[cards-open-value=false]/cards:pointer-events-none
와 같이 조건부로 적용하여 해결합니다. 이 CSS 속성은 요소가 마우스 이벤트를 수신하지 않도록 하여, 클릭 이벤트가 하위 요소로 전달되도록 합니다. 이를 통해 JavaScript 없이 CSS만으로 인터랙션 문제를 해결하는 우아한 방법을 제시합니다.