Loading...
Loading...
Compare original and translation side by side
| Rule | File | Impact | When to Use |
|---|---|---|---|
| Skeleton Loading | | HIGH | Content-shaped placeholders for async data |
| Infinite Scroll | | CRITICAL | Paginated content with a11y and keyboard support |
| Progressive Disclosure | | HIGH | Revealing complexity based on user need |
| Modal / Drawer / Inline | | HIGH | Choosing overlay vs inline display patterns |
| Drag & Drop | | CRITICAL | Reorderable lists with keyboard alternatives |
| Tabs Overflow | | MEDIUM | Tab bars with 7+ items or dynamic tabs |
| Toast Notifications | | HIGH | Success/error feedback and notification stacking |
| Cognitive Load Thresholds | | HIGH | Enforcing Miller's Law, Hick's Law, and Doherty Threshold with numeric limits |
| Form UX | | HIGH | Target sizing, label placement, error prevention, and smart defaults |
| Persuasion Ethics | | HIGH | Detecting dark patterns and applying ethical engagement principles |
| 规则 | 文件 | 影响程度 | 适用场景 |
|---|---|---|---|
| 骨架屏加载 | | 高 | 异步数据的内容形状占位符 |
| 无限滚动 | | 关键 | 带a11y及键盘支持的分页内容 |
| 渐进式展示 | | 高 | 根据用户需求逐步展示复杂内容 |
| 模态框/侧边栏/内联展示 | | 高 | 选择覆盖层 vs 内联展示模式 |
| 拖拽功能 | | 关键 | 带键盘替代方案的可重排列表 |
| 标签栏溢出处理 | | 中 | 包含7个以上标签或动态标签的标签栏 |
| 通知提示 | | 高 | 成功/错误反馈及通知堆叠 |
| 认知负荷阈值 | | 高 | 通过数值限制执行米勒定律、希克定律和多尔蒂阈值 |
| 表单UX | | 高 | 目标尺寸、标签布局、错误预防及智能默认值 |
| 说服伦理 | | 高 | 检测暗黑模式并应用伦理参与原则 |
| 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 |
| 场景 | 模式 | 原因 |
|---|---|---|
| 列表/卡片内容加载 | 骨架屏 | 匹配内容形状,降低感知延迟 |
| 表单提交 | 加载动画 | 不确定时长的短期操作 |
| 文件上传 | 进度条 | 可衡量进度的已知总任务 |
| 图片加载 | 模糊占位符 | 防止布局偏移,渐进式展示 |
| 路由切换 | 骨架屏 | 数据加载时保留布局结构 |
| 后台同步 | 无/细微指示器 | 非阻塞、低优先级任务 |
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>
)
}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>
)
}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>
)
}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>
)
}Load:rules/interaction-skeleton-loading.md
查看详情:rules/interaction-skeleton-loading.md
Load:rules/interaction-infinite-scroll.md
查看详情:rules/interaction-infinite-scroll.md
Load:rules/interaction-progressive-disclosure.md
查看详情:rules/interaction-progressive-disclosure.md
Load:rules/interaction-modal-drawer-inline.md
查看详情:rules/interaction-modal-drawer-inline.md
@dnd-kit/coreLoad:rules/interaction-drag-drop.md
@dnd-kit/core查看详情:rules/interaction-drag-drop.md
Load:rules/interaction-tabs-overflow.md
查看详情:rules/interaction-tabs-overflow.md
Load:rules/interaction-toast-notifications.md
查看详情:rules/interaction-toast-notifications.md
Load:rules/interaction-cognitive-load-thresholds.md
查看详情:rules/interaction-cognitive-load-thresholds.md
Load:rules/interaction-form-ux.md
查看详情:rules/interaction-form-ux.md
Load:rules/interaction-persuasion-ethics.md
查看详情:rules/interaction-persuasion-ethics.md
<dialog><details>role="feed"aria-live<dialog><details>role="feed"aria-liverole="status"role="alert"role="status"role="alert"| Resource | Description |
|---|---|
| references/loading-states-decision-tree.md | Decision tree for skeleton vs spinner vs progress bar |
| references/interaction-pattern-catalog.md | Catalog of 15+ interaction patterns with when-to-use guidance |
| references/keyboard-interaction-matrix.md | Keyboard shortcuts matrix for all interactive patterns (WAI-ARIA APG) |
| 资源 | 说明 |
|---|---|
| references/loading-states-decision-tree.md | 骨架屏vs加载动画vs进度条的决策树 |
| references/interaction-pattern-catalog.md | 包含15+种交互模式及适用场景的目录 |
| references/keyboard-interaction-matrix.md | 所有交互模式的键盘快捷键矩阵(符合WAI-ARIA APG) |
ork:ui-componentsork:animation-motion-designork:accessibilityork:responsive-patternsork:performanceork:ui-componentsork:animation-motion-designork:accessibilityork:responsive-patternsork:performance