Communitygithub.com

YepAPI/skills

Radix/shadcn ダイアログ、確認ダイアログ、モバイル用シート、フォーカストラップ、スクロールロック、ネストされたダイアログのサポート。

skills とは?

このスキルは、Radix UI または shadcn/ui の Dialog コンポーネントを使用して、アクセシブルで堅牢なモーダルダイアログを実装するためのルールとパターンを提供します。主な機能として、フォーカストラップ(開いたときに最初のフォーカス可能要素に自動フォーカス)、スクロールロック(モーダル背面のスクロール防止)、Escape キーやオーバーレイクリックによる閉じる動作など、アクセシビリティとユーザビリティのベストプラクティスが Radix によって自動的に処理されます。破壊的操作には確認ダイアログ(AlertDialog)を使用し、モバイルでは中央配置のダイアログではなく、画面下からスライドする Sheet コンポーネントを使用することを推奨します。また、フォームを含むダイアログでは、バリデーション失敗時には閉じずにインラインエラーを表示するパターンや、ネストされたダイアログの適切なスタッキングについても言及しています。対象プラットフォームは React/Next.js などの Radix/shadcn が使用可能なウェブアプリケーションであり、TypeScript コード例とともに具体的な実装パターンが提供されています。

対応~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 が自動処理 — 開くと最初のフォーカス可能要素にフォーカスが移動し、閉じると元の位置に戻る
  • スクロールロック:モーダルが開いているときに body のスクロールを防止 — Radix が <Dialog.Overlay> で処理
  • 閉じるトリガー:Escape キー、オーバーレイ外のクリック、明示的な閉じるボタン — すべて Radix が提供
  • 制御状態:open + onOpenChange プロパティを使用 — 外部イベントによってトリガーされるモーダルでは内部状態に依存しない
  • ダイアログ内のフォーム: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>
  );
}

// モバイルフレンドリーなアクション用シート
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 を使用すること
  • Escape キーとオーバーレイ外クリックでの閉じる動作を省略しない — Radix が両方を処理するため、上書きしないこと
  • モバイルのアクションメニューに中央配置のモーダルを使用しない — 親指のリーチを考慮して下部 Sheet/ドロワーを使用すること
  • フォームのバリデーション失敗時にダイアログを閉じない — 開いたままにし、インラインエラーを表示してユーザーが修正・再送信できるようにすること
  • 適切なスタッキングコンテキストなしでダイアログをネストしない — 必要な場合は、Radix のネストされた Dialog サポートを適切な z-index とともに使用すること

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.

関連スキル