使用Headless风格改造antd

2024-11-19 @1uokun

以 Slider 为例

  • 基础使用

    • Ant Design

          <Slider />
    • Headless UI

          <Slider.Root>
              <Slider.Track>
                  <Slider.Range />
              </Slider.Tack>
              <Slider.Thumb />
          </Slider.Root>
  • 双滑块

    • Ant Design

          <Slider range/>
    • Headless UI

          <Slider.Root>
              <Slider.Track>
                  <Slider.Range />
              </Slider.Tack>
      +    <Slider.Thumb index={0}/>
      +    <Slider.Thumb index={1}/>
          </Slider.Root>
  • 修改轨道样式

    • Ant Design

          <Slider styles={{track:{...}}}/>
    • Headless UI

          <Slider.Root>
      +    <Slider.Track style={{...}} className={{...}}>
      -    <Slider.Track>
                  <Slider.Range />
              </Slider.Tack>
              <Slider.Thumb />
          </Slider.Root>
  • 轨道内添加元素

    • Ant Design

      不支持❌
    • Headless UI

          <Slider.Root>
              <Slider.Track>
                  <Slider.Range />
      +         <View>
      +            ...
      +         </View>
              </Slider.Tack>
              <Slider.Thumb />
          </Slider.Root>

优势

  1. styles样式被解构了,每一个元素样式独立并更好地支持tailwindanimate style

  2. 通过react element的增删实现功能的增删,而非props

  3. 组件内部代码透明,可自行拓展

实现过程

  1. 将Slider的组成元素解构

    • 轨道 Track

    • 轨道已填充部分 Range

    • 滑块 Thumb

    • 手势系统 Gesture

    • 根组件 Root

  2. 根组件Root使用Context共享props给所有子元素

     // <Slier.Root> 实现
     <SliderContext.Provider value={props}>
         <Slider.Gesture gesture={gesture}>
             {props.children}
         </Slider.Gesture>
     </SliderContext.Provider>
  3. 依然保留支持antd设计语言

    下载一套antd style template代码即可

    // @/components/ui/slider
     <Slider.Root className="..." {...props}>
         <Slider.Track className="...">
             <Slider.Range className="..."/>
         </Slider.Tack>
         <Slider.Thumb index={0} className="..."/>
         {props.range && <Slider.Thumb index={1} className="..."/>}
     </Slider.Root>

    使用:

    import { Slider } from "@/components/ui/slider"
    
    <Slider defaultValue={33} max={100} step={1} />

结尾

讨论区: https://github.com/ant-design/ant-design-mobile-rn/discussions/1395


不满足业务? 需要定制,联系我,低至 $99 /天 @1uokun