radix-ui
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseRadix UI - Quick Reference
Radix UI - 快速参考
When to Use This Skill
适用场景
- Accessible Dialog/Modal components
- Dropdown menu, Select, Popover
- Headless components to style with Tailwind
Deep Knowledge: Usewith technology:mcp__documentation__fetch_docsfor comprehensive documentation.radix-ui
- 可访问的 Dialog/Modal 组件
- 下拉菜单、选择器、弹出框
- 可使用 Tailwind 自定义样式的无头组件
深入参考:使用工具,指定技术为mcp__documentation__fetch_docs以获取完整文档。radix-ui
When NOT to Use This Skill
不适用场景
- shadcn/ui project - Use skill for pre-styled components
shadcn-ui - Need styled components - Use Material-UI, Chakra UI, Ant Design
- Vue/Svelte projects - Use Headless UI or framework-specific libraries
- Simple use cases - Native HTML elements might suffice
- shadcn/ui 项目 - 请使用 技能获取预样式组件
shadcn-ui - 需要样式化组件 - 请使用 Material-UI、Chakra UI、Ant Design
- Vue/Svelte 项目 - 请使用 Headless UI 或框架专属库
- 简单场景 - 原生 HTML 元素即可满足需求
Essential Patterns
核心使用模式
Dialog (Modal)
Dialog(模态框)
tsx
import * as Dialog from '@radix-ui/react-dialog';
<Dialog.Root>
<Dialog.Trigger asChild>
<button>Open</button>
</Dialog.Trigger>
<Dialog.Portal>
<Dialog.Overlay className="fixed inset-0 bg-black/50" />
<Dialog.Content className="fixed top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 bg-white p-6 rounded">
<Dialog.Title>Title</Dialog.Title>
<Dialog.Description>Description</Dialog.Description>
<Dialog.Close asChild>
<button>Close</button>
</Dialog.Close>
</Dialog.Content>
</Dialog.Portal>
</Dialog.Root>tsx
import * as Dialog from '@radix-ui/react-dialog';
<Dialog.Root>
<Dialog.Trigger asChild>
<button>Open</button>
</Dialog.Trigger>
<Dialog.Portal>
<Dialog.Overlay className="fixed inset-0 bg-black/50" />
<Dialog.Content className="fixed top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 bg-white p-6 rounded">
<Dialog.Title>Title</Dialog.Title>
<Dialog.Description>Description</Dialog.Description>
<Dialog.Close asChild>
<button>Close</button>
</Dialog.Close>
</Dialog.Content>
</Dialog.Portal>
</Dialog.Root>Dropdown Menu
下拉菜单
tsx
import * as DropdownMenu from '@radix-ui/react-dropdown-menu';
<DropdownMenu.Root>
<DropdownMenu.Trigger asChild>
<button>Menu</button>
</DropdownMenu.Trigger>
<DropdownMenu.Portal>
<DropdownMenu.Content className="bg-white shadow-lg rounded p-2">
<DropdownMenu.Item onSelect={() => handleEdit()}>
Edit
</DropdownMenu.Item>
<DropdownMenu.Item onSelect={() => handleDelete()}>
Delete
</DropdownMenu.Item>
</DropdownMenu.Content>
</DropdownMenu.Portal>
</DropdownMenu.Root>tsx
import * as DropdownMenu from '@radix-ui/react-dropdown-menu';
<DropdownMenu.Root>
<DropdownMenu.Trigger asChild>
<button>Menu</button>
</DropdownMenu.Trigger>
<DropdownMenu.Portal>
<DropdownMenu.Content className="bg-white shadow-lg rounded p-2">
<DropdownMenu.Item onSelect={() => handleEdit()}>
Edit
</DropdownMenu.Item>
<DropdownMenu.Item onSelect={() => handleDelete()}>
Delete
</DropdownMenu.Item>
</DropdownMenu.Content>
</DropdownMenu.Portal>
</DropdownMenu.Root>Select
选择器
tsx
import * as Select from '@radix-ui/react-select';
<Select.Root value={value} onValueChange={setValue}>
<Select.Trigger className="select-trigger">
<Select.Value placeholder="Select..." />
</Select.Trigger>
<Select.Portal>
<Select.Content>
<Select.Viewport>
<Select.Item value="admin">
<Select.ItemText>Admin</Select.ItemText>
</Select.Item>
</Select.Viewport>
</Select.Content>
</Select.Portal>
</Select.Root>tsx
import * as Select from '@radix-ui/react-select';
<Select.Root value={value} onValueChange={setValue}>
<Select.Trigger className="select-trigger">
<Select.Value placeholder="Select..." />
</Select.Trigger>
<Select.Portal>
<Select.Content>
<Select.Viewport>
<Select.Item value="admin">
<Select.ItemText>Admin</Select.ItemText>
</Select.Item>
</Select.Viewport>
</Select.Content>
</Select.Portal>
</Select.Root>Controlled State
受控状态
tsx
const [open, setOpen] = useState(false);
<Dialog.Root open={open} onOpenChange={setOpen}>tsx
const [open, setOpen] = useState(false);
<Dialog.Root open={open} onOpenChange={setOpen}>Common Props
常见属性
| Prop | Usage |
|---|---|
| Merge props to child |
| Controlled state |
| Positioning |
| Distance offset |
| 属性 | 用途 |
|---|---|
| 将属性合并到子元素 |
| 受控状态管理 |
| 定位设置 |
| 位置偏移量 |
Anti-Patterns to Avoid
需避免的反模式
- Do not forget for z-index
Portal - Do not forget to avoid wrapper divs
asChild - Do not neglect accessibility (ARIA labels)
- 不要忘记为层级元素使用
Portal - 不要忘记使用 避免多余的包裹 div
asChild - 不要忽略可访问性(ARIA 标签)
Anti-Patterns
反模式详情
| Anti-Pattern | Why It's Bad | Correct Approach |
|---|---|---|
| No Portal for overlays | Z-index issues | Always use Portal for dialogs/dropdowns |
| Missing asChild | Extra wrapper divs | Use asChild to merge props |
| No controlled state | Can't track open/close | Use open/onOpenChange |
| Missing aria labels | Not accessible | Add proper labels to all interactive elements |
| Inline styles only | Hard to maintain | Use Tailwind classes or CSS modules |
| Not handling keyboard nav | Poor UX | Radix handles it, don't override |
| 反模式 | 问题原因 | 正确做法 |
|---|---|---|
| 遮罩层不使用 Portal | 层级(z-index)问题 | 对话框/下拉菜单始终使用 Portal |
| 缺失 asChild 属性 | 产生多余的包裹 div | 使用 asChild 合并属性 |
| 未使用受控状态 | 无法追踪打开/关闭状态 | 使用 open/onOpenChange 管理状态 |
| 缺失 ARIA 标签 | 不符合可访问性要求 | 为所有交互元素添加合适的标签 |
| 仅使用内联样式 | 难以维护 | 使用 Tailwind 类或 CSS 模块 |
| 自定义键盘导航 | 体验不佳 | Radix 已内置该功能,请勿覆盖 |
Quick Troubleshooting
快速故障排除
| Issue | Cause | Solution |
|---|---|---|
| Overlay behind other elements | No Portal | Wrap in Portal component |
| Extra div wrapper | Not using asChild | Add asChild prop to Trigger/Content |
| Component not opening | No state management | Add open/onOpenChange props |
| Styling not applying | Wrong element | Check Radix docs for data-attributes |
| Keyboard nav broken | Preventing default | Don't preventDefault on Radix events |
| Type errors | Wrong component import | Check @radix-ui/react-[component] package |
| 问题 | 原因 | 解决方案 |
|---|---|---|
| 遮罩层被其他元素遮挡 | 未使用 Portal | 用 Portal 组件包裹 |
| 出现多余的 div 包裹 | 未使用 asChild | 为 Trigger/Content 添加 asChild 属性 |
| 组件无法打开 | 未进行状态管理 | 添加 open/onOpenChange 属性 |
| 样式不生效 | 选择了错误的元素 | 查看 Radix 文档中的 data-attributes 说明 |
| 键盘导航失效 | 阻止了默认事件 | 不要在 Radix 事件中调用 preventDefault |
| 类型错误 | 组件导入错误 | 检查 @radix-ui/react-[component] 包是否正确导入 |
Further Reading
扩展阅读
For complete API reference: Radix UI Docs
完整 API 参考请查看:Radix UI 文档