Skip to content

Commit

Permalink
feat: 《Use Headless style to transform antd》
Browse files Browse the repository at this point in the history
  • Loading branch information
1uokun committed Nov 19, 2024
1 parent 72d33ec commit ed76b99
Show file tree
Hide file tree
Showing 2 changed files with 246 additions and 0 deletions.
122 changes: 122 additions & 0 deletions docs/blog/headless.en-US.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
---
category: Blog
title: Use Headless style to transform antd
author: 1uokun
date: 2024-11-19
---

2024-11-19 [@1uokun](https://github.com/1uokun)

> Take Slider as an example
- **Basic**
- Ant Design
```jsx
<Slider />
```
- Headless UI
```jsx
<Slider.Root>
<Slider.Track>
<Slider.Range />
</Slider.Tack>
<Slider.Thumb />
</Slider.Root>
```

- **Two Slider thumb**
- Ant Design
```jsx
<Slider range/>
```
- Headless UI
```diff
<Slider.Root>
<Slider.Track>
<Slider.Range />
</Slider.Tack>
+ <Slider.Thumb index={0}/>
+ <Slider.Thumb index={1}/>
</Slider.Root>
```

- **修改轨道样式**
- Ant Design
```jsx
<Slider styles={{track:{...}}}/>
```
- Headless UI
```diff
<Slider.Root>
+ <Slider.Track style={{...}} className={{...}}>
- <Slider.Track>
<Slider.Range />
</Slider.Tack>
<Slider.Thumb />
</Slider.Root>
```

- **Track style change**
- Ant Design
(Not support❌)
- Headless UI
```diff
<Slider.Root>
<Slider.Track>
<Slider.Range />
+ <View>
+ ...
+ </View>
</Slider.Tack>
<Slider.Thumb />
</Slider.Root>
```

## Advantages

1. `styles` has been deconstructed, each element style is independent and better supports `tailwind` and `animate style`
2. Functions can be added or removed by adding or removing `react element` instead of `props`
3. Component code is localized and can be expanded by yourself

## Implementation

1. Deconstructing the components of `Slider`
- Track
- Range
- Thumb
- Gesture
- Root

2. Root component uses `Context` to share props to children
```jsx
// <Slier.Root> code
<SliderContext.Provider value={props}>
<Slider.Gesture gesture={gesture}>
{props.children}
</Slider.Gesture>
</SliderContext.Provider>
```

3. Still retain support for **Ant Design**
> Just download a set of antd style template code
```jsx
// @/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>
```
Usage:
```jsx
import { Slider } from "@/components/ui/slider"

<Slider defaultValue={33} max={100} step={1} />
```

## The End

> discussions: https://github.com/ant-design/ant-design-mobile-rn/discussions/1395
124 changes: 124 additions & 0 deletions docs/blog/headless.zh-CN.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
---
category: Blog
title: 使用Headless风格改造antd
author: 1uokun
date: 2024-11-19
---

2024-11-19 [@1uokun](https://github.com/1uokun)

> 以 Slider 为例
- **基础使用**
- Ant Design
```jsx
<Slider />
```
- Headless UI
```jsx
<Slider.Root>
<Slider.Track>
<Slider.Range />
</Slider.Tack>
<Slider.Thumb />
</Slider.Root>
```

- **双滑块**
- Ant Design
```jsx
<Slider range/>
```
- Headless UI
```diff
<Slider.Root>
<Slider.Track>
<Slider.Range />
</Slider.Tack>
+ <Slider.Thumb index={0}/>
+ <Slider.Thumb index={1}/>
</Slider.Root>
```

- **修改轨道样式**
- Ant Design
```jsx
<Slider styles={{track:{...}}}/>
```
- Headless UI
```diff
<Slider.Root>
+ <Slider.Track style={{...}} className={{...}}>
- <Slider.Track>
<Slider.Range />
</Slider.Tack>
<Slider.Thumb />
</Slider.Root>
```

- **轨道内添加元素**
- Ant Design
```
不支持❌
```
- Headless UI
```diff
<Slider.Root>
<Slider.Track>
<Slider.Range />
+ <View>
+ ...
+ </View>
</Slider.Tack>
<Slider.Thumb />
</Slider.Root>
```

## 优势

1. `styles`样式被解构了,每一个元素样式独立并更好地支持`tailwind``animate style`
2. 通过`react element`的增删实现功能的增删,而非`props`
3. 组件内部代码透明,可自行拓展

## 实现过程

1. 将Slider的组成元素解构
- 轨道 Track
- 轨道已填充部分 Range
- 滑块 Thumb
- 手势系统 Gesture
- 根组件 Root

2. 根组件Root使用Context共享props给所有子元素
```jsx
// <Slier.Root> 实现
<SliderContext.Provider value={props}>
<Slider.Gesture gesture={gesture}>
{props.children}
</Slider.Gesture>
</SliderContext.Provider>
```

3. 依然保留支持antd设计语言
> 下载一套antd style template代码即可
```jsx
// @/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>
```
使用:
```jsx
import { Slider } from "@/components/ui/slider"

<Slider defaultValue={33} max={100} step={1} />
```

## 结尾

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

0 comments on commit ed76b99

Please sign in to comment.