1 概述

Radix UI 是一个面向 React 开发者的无样式、无障碍优先的 UI 组件库,专注于提供高质量的基础组件,作为设计系统的构建块或渐进式集成到现有项目中。其核心优势在于将复杂的交互逻辑与无障碍特性封装为可组合的组件,同时完全不提供样式约束,让开发者拥有 100% 的视觉控制权。

2 核心特点

2.1 无障碍设计

所有组件严格遵循 WAI - ARIA 规范,内置键盘导航、焦点管理和屏幕阅读器支持。例如 Dialog 组件强制要求设置 Title 和 Description,确保辅助技术用户能够正确理解内容。

2.2 无样式架构

组件仅包含功能逻辑,不提供任何默认样式。开发者可通过 className 或 CSS-in-JS 方案完全自定义外观,避免样式覆盖冲突。

2.3 TypeScript 原生支持

提供完整类型定义,API 设计一致且类型安全。所有组件属性、事件处理函数和状态都有明确的类型约束,支持严格模式开发。

2.4 细粒度组件拆分

每个组件拆分为多个逻辑部分,如 Dialog.Root、Dialog.Trigger、Dialog.Content 等,支持灵活组合和嵌套,满足复杂 UI 需求。

2.5 渐进式采用

支持单个组件独立安装(如 @radix-ui/react-dialog),无需全量引入,最小化 bundle 体积。

3 安装与基础使用

3.1 安装方式

3.1.1 全量安装

npm install radix-ui@latest

3.1.2 单独组件安装

npm install @radix-ui/react-dialog
npm install @radix-ui/react-dropdown-menu

3.2 基础导入

// 全量导入
import { Dialog, DropdownMenu } from 'radix-ui'

// 单独导入
import * as Dialog from '@radix-ui/react-dialog'

4 常用组件示例

4.1 Dialog 组件

import * as Dialog from '@radix-ui/react-dialog'
import { Cross2Icon } from '@radix-ui/react-icons'

const ProfileEditor = () => (
  <Dialog.Root>
    <Dialog.Trigger asChild>
      <button className="edit-button">编辑资料</button>
    </Dialog.Trigger>
    <Dialog.Portal>
      <Dialog.Overlay className="dialog-overlay" />
      <Dialog.Content className="dialog-content">
        <Dialog.Title>编辑个人资料</Dialog.Title>
        <Dialog.Description>
          修改您的个人信息,完成后点击保存
        </Dialog.Description>
        <div className="form-group">
          <label htmlFor="name">姓名</label>
          <input id="name" defaultValue="张三" />
        </div>
        <div className="form-actions">
          <Dialog.Close asChild>
            <button className="save-button">保存更改</button>
          </Dialog.Close>
        </div>
        <Dialog.Close asChild>
          <button aria-label="关闭" className="close-button">
            <Cross2Icon />
          </button>
        </Dialog.Close>
      </Dialog.Content>
    </Dialog.Portal>
  </Dialog.Root>
)

4.2 PasswordToggleField 组件(预览版)

2025 年 5 月新增的密码输入组件,支持一键切换可见性:

import { unstable_PasswordToggleField as PasswordToggleField } from 'radix-ui'
import { EyeOpenIcon, EyeClosedIcon } from '@radix-ui/react-icons'

const SecurePasswordInput = () => (
  <PasswordToggleField.Root>
    <PasswordToggleField.Input 
      type="password" 
      placeholder="请输入密码" 
      className="password-input" 
    />
    <PasswordToggleField.Toggle aria-label="切换密码可见性">
      <PasswordToggleField.Icon 
        visible={<EyeOpenIcon className="icon" />} 
        hidden={<EyeClosedIcon className="icon" />} 
      />
    </PasswordToggleField.Toggle>
  </PasswordToggleField.Root>
)

4.3 DropdownMenu 组件

支持子菜单、复选项和键盘导航:

import * as DropdownMenu from '@radix-ui/react-dropdown-menu'
import { CheckIcon, ChevronRightIcon } from '@radix-ui/react-icons'

const UserMenu = () => (
  <DropdownMenu.Root>
    <DropdownMenu.Trigger asChild>
      <button className="user-button">用户菜单</button>
    </DropdownMenu.Trigger>
    <DropdownMenu.Content className="dropdown-content">
      <DropdownMenu.Item className="dropdown-item">
        个人资料
      </DropdownMenu.Item>
      <DropdownMenu.Item className="dropdown-item">
        设置
      </DropdownMenu.Item>
      <DropdownMenu.Separator />
      <DropdownMenu.Label>主题</DropdownMenu.Label>
      <DropdownMenu.CheckboxItem className="dropdown-item">
        <DropdownMenu.ItemIndicator>
          <CheckIcon />
        </DropdownMenu.ItemIndicator>
        深色模式
      </DropdownMenu.CheckboxItem>
      <DropdownMenu.Sub>
        <DropdownMenu.TriggerItem className="dropdown-item">
          语言
          <ChevronRightIcon className="icon" />
        </DropdownMenu.TriggerItem>
        <DropdownMenu.Content>
          <DropdownMenu.Item>简体中文</DropdownMenu.Item>
          <DropdownMenu.Item>English</DropdownMenu.Item>
        </DropdownMenu.Content>
      </DropdownMenu.Sub>
    </DropdownMenu.Content>
  </DropdownMenu.Root>
)

5 高级用法与最佳实践

5.1 使用 asChild 属性组合自定义组件

import { Button } from '../components/Button' // 自定义按钮组件

// 将 Radix 功能组合到自定义组件
<Dialog.Trigger asChild>
  <Button variant="primary">打开对话框</Button>
</Dialog.Trigger>

5.2 状态样式控制

利用组件暴露的 data-state 属性进行样式控制:

/* 未打开状态 */
.dialog-content[data-state="closed"] {
  opacity: 0;
  transform: scale(0.95);
}

/* 打开状态 */
.dialog-content[data-state="open"] {
  opacity: 1;
  transform: scale(1);
  transition: all 0.2s ease;
}

5.3 响应式设计

结合 CSS 变量和媒体查询实现响应式布局:

<Dialog.Content 
  className="dialog-content"
  style={{ 
    '--dialog-width': window.innerWidth > 768 ? '500px' : '90vw' 
  }}
>
  {/* 内容 */}
</Dialog.Content>
.dialog-content {
  width: var(--dialog-width);
  max-width: 90vw;
}

6 兼容性与生态

  • 支持 React 18+ 和 React Server Components
  • 与 Next.js、Vite 等构建工具无缝集成
  • 提供官方图标库 @radix-ui/react-icons
  • 社区丰富的样式封装方案(如 Radix Themes、shadcn/ui)

7 总结

Radix UI 作为无样式、无障碍优先的组件库,为 React 开发者提供了高质量的 UI 构建块。其核心价值在于:

  1. 无障碍保障:内置符合 WAI-ARIA 规范的交互逻辑,降低 accessibility 实现成本;
  2. 设计自由:无预设样式,支持与任何设计系统集成,避免样式冲突;
  3. 类型安全:完整 TypeScript 类型定义,提升开发效率和代码可靠性;
  4. 灵活组合:细粒度组件拆分支持复杂 UI 场景,适配多样化需求。

适合场景:设计系统构建、需要高度自定义 UI 的应用、对无障碍有严格要求的项目。通过渐进式集成,开发者可快速提升产品交互质量,同时保留视觉设计的完全控制权。

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐