首页
/ Reach UI 复选框组件深度解析:构建可访问的三态复选框

Reach UI 复选框组件深度解析:构建可访问的三态复选框

2025-07-07 07:30:43作者:沈韬淼Beryl

前言

在现代 Web 应用中,复选框(Checkbox)是最常用的表单控件之一。Reach UI 提供了一套强大的复选框组件,不仅支持标准的选中/未选中状态,还支持"混合"(indeterminate)状态,同时保证了极佳的可访问性。本文将深入解析 Reach UI 中的复选框组件体系。

核心组件概览

Reach UI 提供了两类主要的复选框组件:

  1. MixedCheckbox - 支持三态(选中/未选中/混合)的标准复选框
  2. CustomCheckbox - 可高度自定义样式的复选框组件

MixedCheckbox:三态复选框

基本概念

MixedCheckbox 扩展了原生 HTML input 元素的复选框功能,增加了第三种"混合"状态(indeterminate)。这种状态在 UI 设计中非常有用,特别是在处理层级复选框时。

[-] 所有水果
-- [ ] 苹果
-- [x] 香蕉
-- [x] 橙子

在上例中,"所有水果"复选框处于混合状态,表示部分(而非全部)子项被选中。

关键特性

  • 支持三种状态:true(选中)、false(未选中)、"mixed"(混合)
  • 自动处理 ARIA 属性和相关 DOM 属性
  • 必须作为受控组件使用(需提供 checkedonChange 属性)

使用示例

function FruitSelector() {
  const [fruits, setFruits] = React.useState({
    apple: false,
    banana: true,
    orange: true
  });

  const allChecked = Object.values(fruits).every(Boolean);
  const someChecked = !allChecked && Object.values(fruits).some(Boolean);
  
  const parentState = allChecked ? true : someChecked ? "mixed" : false;

  function handleParentChange(e) {
    const newState = !allChecked;
    setFruits({
      apple: newState,
      banana: newState,
      orange: newState
    });
  }

  function handleChildChange(e) {
    setFruits({
      ...fruits,
      [e.target.value]: e.target.checked
    });
  }

  return (
    <fieldset>
      <label>
        <MixedCheckbox
          checked={parentState}
          onChange={handleParentChange}
        />
        所有水果
      </label>
      <ul>
        {Object.entries(fruits).map(([fruit, checked]) => (
          <li key={fruit}>
            <label>
              <MixedCheckbox
                value={fruit}
                checked={checked}
                onChange={handleChildChange}
              />
              {fruit}
            </label>
          </li>
        ))}
      </ul>
    </fieldset>
  );
}

CustomCheckbox:自定义样式复选框

设计初衷

原生 HTML 复选框的样式定制能力有限。CustomCheckbox 提供了灵活的解决方案,允许开发者完全自定义复选框的外观,同时保留原生复选框的所有交互行为和可访问性。

两种使用模式

  1. 高阶 API - 使用单一的 CustomCheckbox 组件
  2. 组合 API - 使用 CustomCheckboxContainer + CustomCheckboxInput

高阶 API 示例

function StyledCheckbox({ children, ...props }) {
  return (
    <label style={{ display: 'flex', alignItems: 'center' }}>
      <CustomCheckbox {...props} />
      {children}
    </label>
  );
}

function ColorSelector() {
  return (
    <fieldset>
      <legend>选择你喜欢的颜色</legend>
      <StyledCheckbox name="colors" value="red">
        红色
      </StyledCheckbox>
      <StyledCheckbox name="colors" value="blue">
        蓝色
      </StyledCheckbox>
    </fieldset>
  );
}

组合 API 示例

function CustomCheckboxExample(props) {
  const [checked, setChecked] = React.useState(false);
  
  return (
    <CustomCheckboxContainer
      checked={checked}
      onChange={(e) => setChecked(e.target.checked)}
      style={{
        width: 24,
        height: 24,
        border: '2px solid #333',
        borderRadius: 4,
        background: checked ? '#333' : 'transparent'
      }}
    >
      <CustomCheckboxInput {...props} />
      {checked && (
        <span style={{ color: 'white', fontSize: 18 }}></span>
      )}
    </CustomCheckboxContainer>
  );
}

可访问性最佳实践

使用自定义复选框时,必须遵循 WAI-ARIA 规范:

  1. 确保有清晰的焦点样式
  2. 提供适当的 ARIA 属性
  3. 保持足够的颜色对比度
  4. 支持键盘导航

Reach UI 已内置处理了大部分可访问性需求,但开发者仍需确保自定义样式符合规范。

总结

Reach UI 的复选框组件提供了:

  • 开箱即用的三态复选框支持
  • 灵活的自定义样式能力
  • 完善的键盘导航和屏幕阅读器支持
  • 简单直观的 API 设计

无论是需要简单的三态复选框,还是完全自定义设计的复选框,Reach UI 都能提供优雅的解决方案。通过合理使用这些组件,开发者可以构建出既美观又具备良好可访问性的用户界面。