Communitygithub.com

YepAPI/skills

Radix/shadcn 기반의 대화상자(Dialog), 확인 대화상자, 모바일 시트, 포커스 트래핑, 스크롤 잠금 및 중첩 대화상자 지원

skills란 무엇인가요?

이 스킬은 Radix UI와 shadcn/ui 라이브러리를 기반으로 접근성과 사용자 경험이 뛰어난 모달 및 대화상자 컴포넌트를 구현하기 위한 규칙과 패턴을 제공합니다. 주요 기능으로는 포커스 트래핑, 스크롤 잠금, Esc 키 또는 외부 클릭을 통한 닫기, 중첩 대화상자 지원 등이 있습니다. 파괴적 작업(예: 프로젝트 삭제)에는 `AlertDialog`를 사용하여 취소/삭제 버튼을 제공하고, 모바일 환경에서는 중앙 정렬 모달 대신 아래에서 슬라이드되는 `Sheet` 컴포넌트를 사용하도록 권장합니다. 또한 양식(Form)이 포함된 대화상자에서 유효성 검사 실패 시 대화상자를 닫지 않고 인라인 오류 메시지를 표시하는 등의 세부 규칙을 포함합니다. React, Next.js 등 shadcn/ui와 통합된 모든 프론트엔드 프로젝트에서 사용 가능합니다.

지원 대상~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/YepAPI/skills/tree/HEAD/skills/modals-dialogs

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

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

문서

모달 & 대화상자

규칙

  • Radix Dialog 또는 shadcn <Dialog>를 사용하세요 — 기본적으로 접근 가능하고, 포커스가 트래핑되며, 스크롤이 잠깁니다.
  • 파괴적 작업에 대한 확인 대화상자: "이 프로젝트를 삭제하시겠습니까?"와 함께 취소(보조) 및 삭제(파괴적) 버튼을 제공합니다.
  • 모바일용 시트/서랍: shadcn의 <Sheet>를 사용하세요 — 아래나 측면에서 슬라이드되며, 중앙 모달보다 터치 대상이 더 좋습니다.
  • 포커스 트래핑: Radix가 자동으로 처리합니다 — 열릴 때 첫 번째 포커스 가능 요소에 포커스가 이동하고, 닫힐 때 돌아옵니다.
  • 스크롤 잠금: 모달이 열려 있을 때 본문 스크롤을 방지합니다 — Radix가 <Dialog.Overlay>로 처리합니다.
  • 닫기 트리거: Esc 키, 오버레이 외부 클릭, 명시적인 닫기 버튼 — 모두 Radix에서 제공합니다.
  • 제어 상태: open + onOpenChange props — 외부 이벤트로 트리거되는 모달의 경우 내부 상태에 의존하지 마세요.
  • 대화상자 내 양식: Enter로 제출, 성공 시 닫기, 오류는 인라인으로 표시 — 유효성 검사 실패 시 닫지 마세요.
  • 모바일: 작은 화면에서 작업을 위해 중앙 정렬 <Dialog> 대신 <Sheet> (하단 서랍)를 사용하세요.

패턴

// shadcn을 사용한 확인 대화상자
import {
  AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent,
  AlertDialogDescription, AlertDialogFooter, AlertDialogHeader,
  AlertDialogTitle, AlertDialogTrigger,
} from "@/components/ui/alert-dialog";

function DeleteButton({ onDelete }: { onDelete: () => Promise<void> }) {
  const [loading, setLoading] = useState(false);
  return (
    <AlertDialog>
      <AlertDialogTrigger asChild>
        <Button variant="destructive">프로젝트 삭제</Button>
      </AlertDialogTrigger>
      <AlertDialogContent>
        <AlertDialogHeader>
          <AlertDialogTitle>이 프로젝트를 삭제하시겠습니까?</AlertDialogTitle>
          <AlertDialogDescription>
            이 작업은 프로젝트와 모든 데이터를 영구적으로 삭제하며 되돌릴 수 없습니다.
          </AlertDialogDescription>
        </AlertDialogHeader>
        <AlertDialogFooter>
          <AlertDialogCancel>취소</AlertDialogCancel>
          <AlertDialogAction
            onClick={async () => { setLoading(true); await onDelete(); setLoading(false); }}
            disabled={loading}
          >
            {loading ? "삭제 중..." : "삭제"}
          </AlertDialogAction>
        </AlertDialogFooter>
      </AlertDialogContent>
    </AlertDialog>
  );
}

// 모바일 친화적 작업을 위한 Sheet
import { Sheet, SheetContent, SheetHeader, SheetTitle, SheetTrigger } from "@/components/ui/sheet";

function MobileMenu() {
  return (
    <Sheet>
      <SheetTrigger asChild><Button variant="ghost" size="icon"><MenuIcon /></Button></SheetTrigger>
      <SheetContent side="bottom">
        <SheetHeader><SheetTitle>작업</SheetTitle></SheetHeader>
        <nav className="flex flex-col gap-2 py-4">
          <Button variant="ghost">편집</Button>
          <Button variant="ghost">공유</Button>
          <Button variant="destructive">삭제</Button>
        </nav>
      </SheetContent>
    </Sheet>
  );
}

피해야 할 사항

  • position: fixed와 수동 포커스 관리를 사용한 사용자 정의 모달 구축 — Radix/shadcn Dialog를 사용하세요.
  • Esc 키 및 외부 클릭 시 닫기 기능 누락 — Radix가 둘 다 처리하므로 재정의하지 마세요.
  • 모바일에서 작업 메뉴를 위해 중앙 정렬 모달 사용 — 엄지손가락이 닿기 쉬운 하단 Sheet/Drawer를 사용하세요.
  • 양식 유효성 검사 실패 시 대화상자 닫기 — 열린 상태로 유지하고 인라인 오류를 표시하여 사용자가 수정하고 다시 제출하게 하세요.
  • 적절한 쌓임 컨텍스트 없이 중첩 대화상자 사용 — 필요한 경우 적절한 z-index와 함께 Radix의 중첩 Dialog 지원을 사용하세요.

Individual skills in this repo

This repo contains 20 individual skills — each has its own dedicated page.

YepAPI/skills

WCAG 2.1 AA — semantic HTML, keyboard navigation, screen readers.

YepAPI/skills

Experiment setup, variant splitting, statistical significance, and feature flag integration.

YepAPI/skills

CRUD generators, data tables, user management, role-based access, and bulk operations.

YepAPI/skills

Monitor what ChatGPT and Gemini say about your brand using YepAPI.

YepAPI/skills

Queue workers with BullMQ/Inngest/Trigger.dev, job retries, dead letter queues, concurrency.

YepAPI/skills

Commander.js, interactive prompts with Clack, spinners, colors, config files, exit codes, and npm publishing.

YepAPI/skills

cmdk integration, Cmd+K trigger, fuzzy search, grouped actions, keyboard navigation, and dynamic action registration.

YepAPI/skills

Content planning with trend and sentiment data from YepAPI.

YepAPI/skills

Content calendar, keyword-driven planning, and content briefs.

YepAPI/skills

Theme switching with CSS variables, system preference detection, next-themes, and persistence.

YepAPI/skills

Threaded comments, @mentions, reactions, moderation queue, optimistic UI, and cursor pagination.

YepAPI/skills

Competitive analysis between domains using YepAPI.

YepAPI/skills

Layout grids, KPI cards, data tables with sorting/filtering, sidebar navigation, and responsive breakpoints.

YepAPI/skills

Data encryption — TLS everywhere, AES-256-GCM for PII, bcrypt passwords, encrypted backups.

YepAPI/skills

Chart patterns with Recharts/Nivo/D3, responsive containers, color scales, and accessibility.

YepAPI/skills

Drizzle schema definition, push vs migrate, type-safe queries, relations, transactions, and prepared statements.

YepAPI/skills

Upload handling, resize/compress, CDN delivery, blur placeholders, and next/image patterns.

YepAPI/skills

Local business and Google Maps research using YepAPI.

YepAPI/skills

Cursor-based pagination, IntersectionObserver, virtualized lists with @tanstack/react-virtual, and scroll position restoration.

YepAPI/skills

Chat UI components, streaming responses with AI SDK, context window management, and RAG patterns.

관련 스킬