interaction-patterns
$
npx mdskill add yonatangross/orchestkit/interaction-patternsProvides UI interaction patterns for loading states, pagination, overlays, reordering, and notifications with accessibility.
- Helps implement skeleton loading, infinite scroll, progressive disclosure, and drag-and-drop with keyboard alternatives.
- Integrates with tools like Read, Glob, Grep, WebFetch, and WebSearch for data retrieval.
- Decides recommendations based on codifiable rules to prevent common UX failures in frontend development.
- Presents results as documented patterns in files for reference by a frontend UI developer agent.
SKILL.md
.github/skills/interaction-patternsView on GitHub ↗
---
name: interaction-patterns
license: MIT
compatibility: "Claude Code 2.1.76+."
description: UI interaction design patterns for skeleton loading, infinite scroll with accessibility, progressive disclosure, modal/drawer/inline selection, drag-and-drop with keyboard alternatives, tab overflow handling, and toast notification positioning. Use when implementing loading states, content pagination, disclosure patterns, overlay components, reorderable lists, or notification systems.
tags: [interaction-design, skeleton-loading, infinite-scroll, progressive-disclosure, modal, drawer, drag-drop, tabs, toast, ux-patterns]
context: fork
agent: frontend-ui-developer
version: 1.0.0
author: OrchestKit
user-invocable: false
disable-model-invocation: true
complexity: medium
persuasion-type: reference
metadata:
category: document-asset-creation
allowed-tools:
- Read
- Glob
- Grep
- WebFetch
- WebSearch
---
# Interaction Patterns
Codifiable UI interaction patterns that prevent common UX failures. Covers loading states, content pagination, disclosure patterns, overlays, drag-and-drop, tab overflow, and notification systems — all with accessibility baked in.
## Quick Reference
| Rule | File | Impact | When to Use |
|------|------|--------|-------------|
| Skeleton Loading | `rules/interaction-skeleton-loading.md` | HIGH | Content-shaped placeholders for async data |
| Infinite Scroll | `rules/interaction-infinite-scroll.md` | CRITICAL | Paginated content with a11y and keyboard support |
| Progressive Disclosure | `rules/interaction-progressive-disclosure.md` | HIGH | Revealing complexity based on user need |
| Modal / Drawer / Inline | `rules/interaction-modal-drawer-inline.md` | HIGH | Choosing overlay vs inline display patterns |
| Drag & Drop | `rules/interaction-drag-drop.md` | CRITICAL | Reorderable lists with keyboard alternatives |
| Tabs Overflow | `rules/interaction-tabs-overflow.md` | MEDIUM | Tab bars with 7+ items or dynamic tabs |
| Toast Notifications | `rules/interaction-toast-notifications.md` | HIGH | Success/error feedback and notification stacking |
| Cognitive Load Thresholds | `rules/interaction-cognitive-load-thresholds.md` | HIGH | Enforcing Miller's Law, Hick's Law, and Doherty Threshold with numeric limits |
| Form UX | `rules/interaction-form-ux.md` | HIGH | Target sizing, label placement, error prevention, and smart defaults |
| Persuasion Ethics | `rules/interaction-persuasion-ethics.md` | HIGH | Detecting dark patterns and applying ethical engagement principles |
**Total: 10 rules across 6 categories**
## Decision Table — Loading States
| Scenario | Pattern | Why |
|----------|---------|-----|
| List/card content loading | Skeleton | Matches content shape, reduces perceived latency |
| Form submission | Spinner | Indeterminate, short-lived action |
| File upload | Progress bar | Measurable operation with known total |
| Image loading | Blur placeholder | Prevents layout shift, progressive reveal |
| Route transition | Skeleton | Preserves layout while data loads |
| Background sync | None / subtle indicator | Non-blocking, low priority |
## Quick Start
### Skeleton Loading
```tsx
function CardSkeleton() {
return (
<div className="animate-pulse space-y-3">
<div className="h-48 w-full rounded-lg bg-muted" />
<div className="h-4 w-3/4 rounded bg-muted" />
<div className="h-4 w-1/2 rounded bg-muted" />
</div>
)
}
function CardList({ items, isLoading }: { items: Item[]; isLoading: boolean }) {
if (isLoading) {
return (
<div className="grid grid-cols-3 gap-4">
{Array.from({ length: 6 }).map((_, i) => (
<CardSkeleton key={i} />
))}
</div>
)
}
return (
<div className="grid grid-cols-3 gap-4">
{items.map((item) => <Card key={item.id} item={item} />)}
</div>
)
}
```
### Infinite Scroll with Accessibility
```tsx
function InfiniteList({ fetchNextPage, hasNextPage, items }: Props) {
const sentinelRef = useRef<HTMLDivElement>(null)
useEffect(() => {
const observer = new IntersectionObserver(
([entry]) => { if (entry.isIntersecting && hasNextPage) fetchNextPage() },
{ rootMargin: "200px" }
)
if (sentinelRef.current) observer.observe(sentinelRef.current)
return () => observer.disconnect()
}, [fetchNextPage, hasNextPage])
return (
<div role="feed" aria-busy={isFetching}>
{items.map((item) => (
<article key={item.id} aria-posinset={item.index} aria-setsize={-1}>
<ItemCard item={item} />
</article>
))}
<div ref={sentinelRef} />
{hasNextPage && (
<button onClick={() => fetchNextPage()}>Load more items</button>
)}
<div aria-live="polite" className="sr-only">
{`Showing ${items.length} items`}
</div>
</div>
)
}
```
## Rule Details
### Skeleton Loading
Content-shaped placeholders that match the final layout. Use skeleton for lists, cards, and text blocks.
> **Load**: `rules/interaction-skeleton-loading.md`
### Infinite Scroll
Accessible infinite scroll with IntersectionObserver, screen reader announcements, and "Load more" fallback.
> **Load**: `rules/interaction-infinite-scroll.md`
### Progressive Disclosure
Reveal complexity progressively: tooltip, accordion, wizard, contextual panel.
> **Load**: `rules/interaction-progressive-disclosure.md`
### Modal / Drawer / Inline
Choose the right overlay pattern: modal for confirmations, drawer for detail views, inline for simple toggles.
> **Load**: `rules/interaction-modal-drawer-inline.md`
### Drag & Drop
Drag-and-drop with mandatory keyboard alternatives using `@dnd-kit/core`.
> **Load**: `rules/interaction-drag-drop.md`
### Tabs Overflow
Scrollable tab bars with overflow menus for dynamic or numerous tabs.
> **Load**: `rules/interaction-tabs-overflow.md`
### Toast Notifications
Positioned, auto-dismissing notifications with ARIA roles and stacking.
> **Load**: `rules/interaction-toast-notifications.md`
### Cognitive Load Thresholds
Miller's Law (max 7 items per group), Hick's Law (max 1 primary CTA), and Doherty Threshold (400ms feedback) with specific, countable limits.
> **Load**: `rules/interaction-cognitive-load-thresholds.md`
### Form UX
Fitts's Law touch targets (44px mobile), top-aligned labels, Poka-Yoke error prevention with blur-only validation, and smart defaults.
> **Load**: `rules/interaction-form-ux.md`
### Persuasion Ethics
13 dark pattern red flags to detect and reject, the Hook Model ethical test (aware, reversible, user-benefits), and EU DSA Art. 25 compliance.
> **Load**: `rules/interaction-persuasion-ethics.md`
## Key Principles
1. **Keyboard parity** — Every mouse interaction MUST have a keyboard equivalent. No drag-only, no hover-only.
2. **Skeleton over spinner** — Use content-shaped placeholders for data loading; reserve spinners for indeterminate actions.
3. **Native HTML first** — Prefer `<dialog>`, `<details>`, `role="feed"` over custom implementations.
4. **Progressive enhancement** — Features should work without JS where possible, then enhance with interaction.
5. **Announce state changes** — Use `aria-live` regions to announce dynamic content changes to screen readers.
6. **Respect scroll position** — Back navigation must restore scroll position; infinite scroll must not lose user's place.
## Anti-Patterns (FORBIDDEN)
- **Spinner for content loading** — Spinners give no spatial hint. Use skeletons matching the content shape.
- **Infinite scroll without Load More** — Screen readers and keyboard users cannot reach footer content. Always provide a button fallback.
- **Modal for browsable content** — Modals trap focus and block interaction. Use drawers or inline expansion for browsing.
- **Drag-only reorder** — Excludes keyboard and assistive tech users. Always provide arrow key + Enter alternatives.
- **Toast without ARIA role** — Toasts are invisible to screen readers. Use `role="status"` for success, `role="alert"` for errors.
- **Auto-dismiss error toasts** — Users need time to read errors. Never auto-dismiss error notifications.
## Detailed Documentation
| Resource | Description |
|----------|-------------|
| [references/loading-states-decision-tree.md](references/loading-states-decision-tree.md) | Decision tree for skeleton vs spinner vs progress bar |
| [references/interaction-pattern-catalog.md](references/interaction-pattern-catalog.md) | Catalog of 15+ interaction patterns with when-to-use guidance |
| [references/keyboard-interaction-matrix.md](references/keyboard-interaction-matrix.md) | Keyboard shortcuts matrix for all interactive patterns (WAI-ARIA APG) |
## Related Skills
- `ork:ui-components` — shadcn/ui component patterns and CVA variants
- `ork:animation-motion-design` — Motion library and View Transitions API
- `ork:accessibility` — WCAG compliance, ARIA patterns, screen reader support
- `ork:responsive-patterns` — Responsive layout and container query patterns
- `ork:performance` — Core Web Vitals and runtime performance optimization