Community코딩 & 개발github.com

astro-ui-patterns

Astro 인터랙션 패턴(네비게이션, 대화상자, 탭, 필터, 카드, 테마 전환)을 구현합니다. 각 패턴의 동작 계약을 유지하면서 프레임워크 기본 요소를 재사용합니다.

astro-ui-patterns란 무엇인가요?

이 아스트로 UI 패턴 및 이식 가능한 컴포넌트 라이브러리는 17개의 드롭인(drop-in) UI 컴포넌트(테마 토글, 모바일 네비게이션 드로어, 검색창, 접근 가능한 모달/아코디언/탭 등)에 대한 표준 동작 계약을 제공합니다. 각 컴포넌트는 엄격한 이식 가능 모델을 따르며, 외부 npm 종속성이나 클라이언트 프레임워크 런타임이 없고 네임스페이스가 적용된 CSS 토큰과 점진적 향상을 지원합니다. 주된 목표는 모든 인터랙션 패턴(키보드 지원, 포커스 관리, 접근성 상태, 점진적 향상)이 프로젝트 전체에서 일관되게 유지되도록 하는 것입니다. 이 라이브러리는 특정 프레임워크에 종속되지 않아 React, Vue, Svelte 기반 프로젝트에서도 의미론적 요구사항과 동작을 유지하면서 기존 구성 스타일을 재사용할 수 있습니다. 이 라이브러리에는 17개의 목록화된 컴포넌트에 없는 새로운 인터랙티브 패턴이 필요할 때 사람이 결정해야 하는 의사 결정 게이트가 포함되어 있으며, 무단 타사 라이브러리 설치나 임시 플레이스홀더를 방지합니다.

지원 대상~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/gdcrosbie/agent-skills/tree/HEAD/skills/astro-ui-patterns

Installed? Explore more 코딩 & 개발 skills: steipete/bluebubbles, steipete/eightctl, steipete/blucli · View all 6 →

즐겨 사용하는 AI에게 물어보기

이 에이전트 스킬이 미리 로드된 새 채팅을 엽니다.

문서

Astro UI 패턴 및 이식 가능한 컴포넌트 라이브러리

이 가이드는 Astro 사이트를 위한 이식 가능한 드롭인 UI 컴포넌트의 표준화된 카탈로그를 정의합니다.

독립 실행형 예제는 이식 가능한 컴포넌트 모델을 사용합니다: npm 종속성 제로, 클라이언트 프레임워크 런타임 제로(React/Vue 없음), 네임스페이스가 적용되고 내장된 폴백이 있는 CSS 토큰, 점진적 향상. 프레임워크 프로젝트에서는 의미론적 및 인터랙션 요구사항을 유지하면서 선택된 계약에 맞게 구성과 스타일을 조정합니다. 렌더링된 프로젝트에서 접근성을 확인하세요. 템플릿만으로는 WCAG 적합성을 보장하지 않습니다.


동작 계약 및 프레임워크 구성

아래 색인의 컴포넌트에 대해 의미론적 및 인터랙션 계약을 사용하세요: 키보드 지원, 포커스 관리, 네이티브 요소, 접근 가능한 이름, 상태 업데이트 및 점진적 향상. 선택된 프로젝트/프레임워크 계약이 스타일링, 토큰, 가져오기 및 컴포넌트 구성을 제어합니다. 사용자 지침이 우선합니다.

예제는 아래의 독립 실행형 이식 가능한 컴포넌트 모델을 사용합니다. 프레임워크 구성 계약 없이 독립적인 컴포넌트를 추가할 때 사용하세요. 프로젝트에 기존 라이브러리가 있는 경우, 중복 버튼, 제목 또는 폼 컨트롤을 만드는 대신 적절한 기본 요소를 사용하여 동작을 조정하세요. 예제의 래퍼와 클래스를 조정하면서 필요한 의미론과 동작을 유지하세요.

컴포넌트 프레임워크(Lumos 등)를 기반으로 구축된 프로젝트의 경우 해당 프레임워크의 구성 및 스타일링을 사용하세요. 해당 기본 요소를 가져올 수 있습니다. 독립 실행형 제로 사이트 임포트 규칙과 네임스페이스가 적용된 폴백 토큰은 선택된 프레임워크의 자체 계약을 재정의하지 않습니다.


이식 가능한 컴포넌트 모델

독립 실행형 이식 가능한 컴포넌트의 경우 다음 다섯 가지 규칙을 사용하세요. 선택된 프레임워크에서는 위에서 설명한 대로 동작 요구사항을 유지하고 구성/스타일링 계약을 따르세요:

  1. 외부/사이트 임포트 제로: 컴포넌트 파일은 사이트 레이아웃, 버튼 또는 타사 클라이언트 UI 라이브러리를 가져오면 안 됩니다. 유일한 예외는 SelfHostedMap으로, 맵 렌더러와 타일 리더가 필요합니다. 사양에 패키지가 나열되어 있으며 소유자의 승인을 받아야만 설치됩니다.
  2. 폴백이 있는 네임스페이스 CSS 변수: 컴포넌트 스타일시트 내에서 호스트 토큰(예: var(--color-brand))을 직접 참조하지 마세요. 항상 var(--comp-property, <fallback>) 형식을 사용하세요.
  3. 범위 지정 BEM 및 CSS 논리 속성: BEM 클래스 이름 지정(.c-theme-toggle, .c-accordion__summary) 및 논리 속성(inline-size, block-size, padding-inline, margin-block)을 사용하세요.
  4. 멱등적인 바닐라 점진적 향상: 스크립트는 로드 시 실행되어야 하며 Astro View Transitions가 활성화된 경우 깔끔하게 다시 연결되어야 합니다(document.addEventListener('astro:after-swap', init)).
  5. 터치 대상 및 ARIA: 버튼과 인터랙티브 컨트롤은 최소 44px (2.75rem) 또는 48px (3rem) 터치 대상, 적절한 ARIA 상태(aria-expanded, aria-selected, aria-pressed, aria-controls) 및 키보드 포커스 링을 가져야 합니다.

컴포넌트 색인

컴포넌트사양 파일목적주요 계약
1. ThemeTogglecomponents/theme-toggle.mdFOUC 없이 SVG 모핑을 사용한 라이트/다크 테마 전환기<head> 인라인 스크립트 + OKLCH 토큰 매핑
2. MobileNavDrawercomponents/mobile-nav-drawer.md애니메이션 햄버거 메뉴가 있는 접근 가능한 슬라이드다운 네비게이션 드로어48px 터치 대상, Escape 키 닫기, GPU 블러 지연 없음
3. SearchBarcomponents/search-bar.md지우기 버튼과 라이브 알리미가 있는 클라이언트 측 검색 입력rAF 디바운싱(최적의 INP), aria-live, 사용자 정의 이벤트 코디네이터
4. FilterChipscomponents/filter-chips.md접근 가능한 눌린 상태가 있는 다중 카테고리 필 칩 필터 바role="group", aria-pressed, 사용자 정의 이벤트 코디네이터
5. SearchFilterBarcomponents/search-filter-bar.mdSearchBar와 FilterChips를 결합한 복합 패턴사전 구성된 스택형 도구 모음, 다중 열 플렉스 레이아웃, 공유 범위
6. AccessibleModalcomponents/accessible-modal.md네이티브 HTML5 <dialog>를 사용한 접근 가능한 대화상자 오버레이네이티브 최상위 레이어, 배경 클릭, Escape 키, 포커스 복원
7. AccessibleAccordioncomponents/accessible-accordion.md부드러운 CSS 그리드 확장을 사용한 네이티브 FAQ/아코디언네이티브 <details name="...">, 0 KB JavaScript
8. AccessibleTabscomponents/accessible-tabs.md가격 계층 또는 다중 패널 뷰를 위한 WAI-ARIA 탭 전환기키보드 화살표 탐색(Left/Right/Home/End)
9. SocialSharecomponents/social-share.mdWeb Share API를 사용한 개인정보 보호 우선 소셜 공유 바100% GDPR 안전, 추적기 0개, 정적 의도 URL
10. TableOfContentscomponents/table-of-contents.md스크롤스파이가 있는 장문 문서 목차IntersectionObserver 제목 추적, 문서 레이아웃과 쌍을 이룸
11. AccessibleCarouselcomponents/accessible-carousel.md리뷰, 카드 또는 로고를 위한 네이티브 CSS 스크롤 스냅 슬라이더네이티브 터치 스와이프(0 KB JS), 접근 가능한 이전/다음 버튼
12. InfiniteTickercomponents/infinite-ticker.md호버/포커스 시 일시 정지 기능이 있는 순수 CSS 무한 로고/텍스트 마키WCAG 2.2.2 준수, 중복 트랙이 aria-hidden으로 숨겨짐
13. StatsCountercomponents/stats-counter.md이즈아웃 스크롤 애니메이션이 있는 HTML 우선 메트릭 카운터 바0 CLS, 정적 HTML 폴백, IntersectionObserver
14. AddToCalendarcomponents/add-to-calendar.md빌드 타임 iCalendar 파일에 대한 "날짜 저장" 링크동일 출처 정적 .ics + <a download>, 유효한 RFC 5545, 0 KB JS
15. SelfHostedMapcomponents/self-hosted-map.md자체 호스팅 PMTiles 추출 항목의 장소 목록을 지도로 표시, 번호가 매겨진 핀이 목록과 일치지연 로드 MapLibre, HTTP 206 타일 라우트, 텍스트 대체물이 있는 aria-hidden 맵, 테마를 따름. npm 패키지 필요(소유자 승인)
16. ClickableParentcomponents/clickable-parent.md하나의 실제 링크 또는 버튼을 통해 전체 카드/행을 클릭 가능하게 함::after 확장 히트 영역, 보조 컨트롤 올림, 컨테이너의 포커스 링, 0 KB JS
17. Cardcomponents/card.md미디어, 메타, 본문 및 보조 작업이 있는 콘텐츠 카드제목 우선 DOM, headingLevel 속성, 컨테이너 쿼리 레이아웃, 연결 시 ClickableParent 계약

목록에 없는 컴포넌트 결정 게이트(인간 결정 지점)

프로젝트 요구사항이나 디자인이 위의 17개 목록화된 컴포넌트에 없는 인터랙티브 UI 컴포넌트를 요청하는 경우(예: Before/After 이미지 비교 슬라이더, 날짜 선택기, 범위 선택기, 단계별 마법사 또는 사용자 정의 미디어 플레이어):

[!IMPORTANT] 멈추고 질문하세요: 에이전트는 클라이언트 측 프레임워크 라이브러리(React, Vue, Svelte)를 절대 자동으로 설치해서는 안 되며, 검증되지 않은 타사 npm 패키지를 가져오거나 임시 텍스트 플레이스홀더 블록(예: <div class="c-placeholder">)을 남겨서는 안 됩니다.

에이전트는 반드시 멈추고 프로젝트 소유자에게 세 가지 명확한 선택지를 제시해야 합니다:

  1. 옵션 A: 사용자 정의 바닐라 컴포넌트(권장): 아래의 맞춤형 컴포넌트 폴백 계약을 준수하는 종속성 없는 .astro 컴포넌트를 작성합니다.
  2. 옵션 B: 정적 HTML 기본: 0 KB JavaScript로 완전히 정적인 의미론적 레이아웃(예: 나란히 이미지 또는 표준 스택형 카드)을 구현하고, 인터랙티브 향상을 완전히 생략합니다.
  3. 옵션 C: 카탈로그 패턴 적응: 기존 카탈로그 패턴이 요구사항을 충족할 수 있는지 평가합니다(예: AccessibleModal을 이미지 라이트박스로, 또는 AccessibleTabs를 단계별 패널 뷰로 적응).

맞춤형 컴포넌트 폴백 계약

프로젝트 소유자가 목록에 없는 컴포넌트(옵션 A) 구축을 승인하는 경우, 구현은 다음 여섯 가지 규칙을 충족해야 합니다. 프레임워크 적응의 경우 항목 3-4에 대해 프레임워크의 구성, 클래스 이름 지정 및 토큰 규칙을 사용하세요:

  1. 의미론적 HTML 우선: JavaScript를 작성하기 전에 표준 HTML 요소에 인터페이스를 고정하세요(예: 슬라이더의 <input type="range">, 공개의 <details>, 오버레이의 <dialog> ).
  2. 외부 런타임 종속성 제로: 클라이언트 프레임워크 런타임(React/Vue 없음) 및 타사 UI 위젯 패키지 제로. 브라우저 인터랙션이 진정으로 필요할 때만 순수 바닐라 TypeScript/JavaScript를 작성하세요.
  3. 범위 지정 BEM 및 CSS 논리 속성: 표준 BEM 이름 지정(.c-block, .c-block__element) 및 흐름 상대 레이아웃 속성(inline-size, block-size, padding-block, margin-inline, inset)을 사용하세요.
  4. 폴백이 있는 네임스페이스 토큰: 16진수 값을 하드코딩하지 마세요. 합리적인 폴백과 함께 호스트 의미론적 토큰 또는 네임스페이스 사용자 정의 속성을 사용하세요(var(--comp-color, var(--color-primary))).
  5. JavaScript 없는 점진적 향상: 클라이언트 JavaScript가 비활성화된 경우에도 컴포넌트는 읽기 쉽고 접근 가능하며 작동 가능해야 합니다. @media (scripting: none) 또는 네이티브 CSS 폴백 레이아웃(예: 나란히 또는 스택형 뷰)을 사용하여 콘텐츠가 숨겨지지 않도록 하세요.
  6. WCAG 2.2 AA 준수: 최소 44px (2.75rem) 터치 대상, 고대비 가시적인 :focus-visible 링, 명확한 접근 가능한 이름(aria-label, <label>)을 유지하고 0개의 axe-core 위반을 확인하세요.

에이전트를 위한 선택적 로드 지침

사용자가 위 컴포넌트 중 하나를 구현하거나 편집하도록 요청하는 경우 전체 카탈로그를 읽지 마세요. 대신 필요한 특정 컴포넌트 파일만 읽으세요(예: components/accessible-carousel.md).


통합 확인

빌드/배포된 출력에서 선택된 사양을 확인하세요: 의미론 및 이름, 키보드/포커스 동작, 상태 전환, JavaScript 없음 처리, 반복 초기화 및 호스트 토큰 매핑. 독립 실행형 패키징 규칙은 독립 실행형 컴포넌트에만 적용됩니다. 프레임워크는 기본 요소를 재사용합니다. 프로젝트의 구성된 검사/빌드/테스트를 실행하고 사용할 수 없는 검사 또는 적용 범위 격차를 공개하세요. 44px는 이 라이브러리의 대상 크기 규칙이며 WCAG AA 임계값 자체가 아닙니다.

네이티브 선택 팝업은 소유자가 사용자 정의 콤보박스의 장단점을 승인하지 않는 한 브라우저/OS UI로 유지됩니다.

관련 스킬