Skip to content

Commit 55a5bb4

Browse files
authored
feat(switch): loading 态受控 (#3149)
* feat: 控制加载状态的图标,传入空值时禁用 loading 态 * feat(switch): loading 态受控 * chore: 修正更新文档 * feat: 修改props定义 * fix: 更新升级文档
1 parent f594bc9 commit 55a5bb4

File tree

13 files changed

+188
-23
lines changed

13 files changed

+188
-23
lines changed

src/packages/switch/demo.taro.tsx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,15 @@ import Demo4 from './demos/taro/demo4'
1010
import Demo5 from './demos/taro/demo5'
1111
import Demo6 from './demos/taro/demo6'
1212
import Demo7 from './demos/taro/demo7'
13+
import Demo8 from './demos/taro/demo8'
1314

1415
const SwitchDemo = () => {
1516
const [translated] = useTranslate({
1617
'zh-CN': {
1718
basic: '非受控',
1819
disabled: '禁用状态',
1920
asyncControl: '受控',
21+
loadingControl: 'loading 态受控',
2022
customColor: '自定义颜色',
2123
supportText: '支持文字',
2224
supportIcon: '支持Icon',
@@ -26,6 +28,7 @@ const SwitchDemo = () => {
2628
basic: '非受控',
2729
disabled: '禁用狀態',
2830
asyncControl: '受控',
31+
loadingControl: 'loading 態受控',
2932
customColor: '自定義顏色',
3033
supportText: '支持文字',
3134
supportIcon: '支持Icon',
@@ -35,6 +38,7 @@ const SwitchDemo = () => {
3538
basic: 'Uncontrolled',
3639
disabled: 'Disabled',
3740
asyncControl: 'controlled',
41+
loadingControl: 'Controlled with loading',
3842
customColor: 'Custom Color',
3943
supportText: 'Support Text',
4044
supportIcon: 'Support Icon',
@@ -49,6 +53,8 @@ const SwitchDemo = () => {
4953
<Demo1 />
5054
<View className="h2">{translated.asyncControl}</View>
5155
<Demo2 />
56+
<View className="h2">{translated.loadingControl}</View>
57+
<Demo8 />
5258
<View className="h2">{translated.disabled}</View>
5359
<Demo3 />
5460
<View className="h2">{translated.supportText}</View>

src/packages/switch/demo.tsx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,15 @@ import Demo4 from './demos/h5/demo4'
77
import Demo5 from './demos/h5/demo5'
88
import Demo6 from './demos/h5/demo6'
99
import Demo7 from './demos/h5/demo7'
10+
import Demo8 from './demos/h5/demo8'
1011

1112
const SwitchDemo = () => {
1213
const [translated] = useTranslate({
1314
'zh-CN': {
1415
basic: '非受控',
1516
disabled: '禁用状态',
1617
asyncControl: '受控',
18+
loadingControl: 'loading 态受控',
1719
customColor: '自定义颜色',
1820
supportText: '支持文字',
1921
supportIcon: '支持Icon',
@@ -23,6 +25,7 @@ const SwitchDemo = () => {
2325
basic: '非受控',
2426
disabled: '禁用狀態',
2527
asyncControl: '受控',
28+
loadingControl: 'loading 態受控',
2629
customColor: '自定義顏色',
2730
supportText: '支持文字',
2831
supportIcon: '支持Icon',
@@ -32,6 +35,7 @@ const SwitchDemo = () => {
3235
basic: 'Uncontrolled',
3336
disabled: 'Disabled',
3437
asyncControl: 'controlled',
38+
loadingControl: 'Controlled with loading',
3539
customColor: 'Custom Color',
3640
supportText: 'Support Text',
3741
supportIcon: 'Support Icon',
@@ -45,6 +49,8 @@ const SwitchDemo = () => {
4549
<Demo1 />
4650
<h2>{translated.asyncControl}</h2>
4751
<Demo2 />
52+
<h2>{translated.loadingControl}</h2>
53+
<Demo8 />
4854
<h2>{translated.disabled}</h2>
4955
<Demo3 />
5056
<h2>{translated.supportText}</h2>
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import React, { useState } from 'react'
2+
import { Cell, Switch, Toast } from '@nutui/nutui-react'
3+
4+
const Demo8 = () => {
5+
const [checkedAsync, setCheckedAsync] = useState(true)
6+
const [externalLoading, setExternalLoading] = useState(false)
7+
8+
const mockRequest = (): Promise<void> => {
9+
return new Promise((resolve) => {
10+
setTimeout(() => {
11+
resolve()
12+
}, 2000)
13+
})
14+
}
15+
16+
const onChangeAsync = async (value: boolean) => {
17+
Toast.show(`2秒后异步触发 ${value}`)
18+
await mockRequest()
19+
setCheckedAsync(value)
20+
// setExternalLoading(false)
21+
}
22+
return (
23+
<Cell>
24+
<Switch
25+
loading={externalLoading}
26+
onLoadingChange={async (loading: boolean) => {
27+
setExternalLoading(loading)
28+
}}
29+
checked={checkedAsync}
30+
onChange={(value) => onChangeAsync(value)}
31+
/>
32+
</Cell>
33+
)
34+
}
35+
export default Demo8
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
import React, { useState } from 'react'
2+
import { Cell, Switch, Toast } from '@nutui/nutui-react-taro'
3+
4+
const Demo8 = () => {
5+
const [checkedAsync, setCheckedAsync] = useState(true)
6+
const [value, setValue] = useState(false)
7+
const [showToast, setShowToast] = useState(false)
8+
const [externalLoading, setExternalLoading] = useState(false)
9+
const mockRequest = (): Promise<void> => {
10+
return new Promise((resolve) => {
11+
setTimeout(() => {
12+
resolve()
13+
}, 2000)
14+
})
15+
}
16+
17+
const onChangeAsync = async (value: boolean) => {
18+
setValue(value)
19+
setShowToast(true)
20+
await mockRequest()
21+
setCheckedAsync(value)
22+
// setExternalLoading(false)
23+
}
24+
return (
25+
<>
26+
<Cell>
27+
<Switch
28+
loading={externalLoading}
29+
onLoadingChange={async (loading: boolean) => {
30+
setExternalLoading(loading)
31+
}}
32+
checked={checkedAsync}
33+
onChange={(value) => onChangeAsync(value)}
34+
/>
35+
</Cell>
36+
<Toast
37+
content={`2秒后异步触发 ${value}`}
38+
visible={showToast}
39+
onClose={() => {
40+
setShowToast(false)
41+
}}
42+
/>
43+
</>
44+
)
45+
}
46+
export default Demo8

src/packages/switch/doc.en-US.md

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,14 @@ import { Switch } from '@nutui/nutui-react'
2626

2727
:::
2828

29+
### loading 态受控
30+
31+
:::demo
32+
33+
<CodeBlock src='h5/demo8.tsx'></CodeBlock>
34+
35+
:::
36+
2937
### disabled status
3038

3139
:::demo
@@ -77,8 +85,10 @@ import { Switch } from '@nutui/nutui-react'
7785
| disabled | Disabled | `boolean` | `false` |
7886
| activeText | Text description when opening | `ReactNode` | `-` |
7987
| inactiveText | Text description when closed | `ReactNode` | `-` |
80-
| loadingIcon | Controlled loading state icon | `ReactNode` | `<Loading1 />` |
81-
| onChange | Trigger when switching switches | `onChange:(value: boolean, event: Event)` | `-` |
88+
| loadingIcon | Control the loading state icon, disable the loading state when a null | `ReactNode` | `<Loading1 />` |
89+
| loading | loading state, controlled | `boolean` | `-` |
90+
| onLoadingChange | Triggered when switching loading | `onLoadingChange:(value: boolean)` | `-` |
91+
| onChange | Trigger when switching switches | `onChange:(value: boolean)` | `-` |
8292

8393
## Theming
8494

src/packages/switch/doc.md

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,14 @@ import { Switch } from '@nutui/nutui-react'
2626

2727
:::
2828

29+
### loading 态受控
30+
31+
:::demo
32+
33+
<CodeBlock src='h5/demo8.tsx'></CodeBlock>
34+
35+
:::
36+
2937
### 禁用状态
3038

3139
:::demo
@@ -77,8 +85,10 @@ import { Switch } from '@nutui/nutui-react'
7785
| disabled | 禁用状态 | `boolean` | `false` |
7886
| activeText | 打开时文字描述 | `ReactNode` | `-` |
7987
| inactiveText | 关闭时文字描述 | `ReactNode` | `-` |
80-
| loadingIcon | 受控 loading 态图标 | `ReactNode` | `<Loading1 />` |
81-
| onChange | 切换开关时触发 | `onChange:(value: boolean, event: Event)` | `-` |
88+
| loadingIcon | 控制加载状态的图标,传入空值时禁用 loading 态 | `ReactNode` | `<Loading1 />` |
89+
| loading | loading 态,受控 | `boolean` | `-` |
90+
| onLoadingChange | 切换 loading 态时触发 | `onLoadingChange:(value: boolean)` | `-` |
91+
| onChange | 切换开关时触发 | `onChange:(value: boolean)` | `-` |
8292

8393
## 主题定制
8494

src/packages/switch/doc.taro.md

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,14 @@ import { Switch } from '@nutui/nutui-react-taro'
2626

2727
:::
2828

29+
### loading 态受控
30+
31+
:::demo
32+
33+
<CodeBlock src='taro/demo8.tsx'></CodeBlock>
34+
35+
:::
36+
2937
### 禁用状态
3038

3139
:::demo
@@ -77,8 +85,10 @@ import { Switch } from '@nutui/nutui-react-taro'
7785
| disabled | 禁用状态 | `boolean` | `false` |
7886
| activeText | 打开时文字描述 | `ReactNode` | `-` |
7987
| inactiveText | 关闭时文字描述 | `ReactNode` | `-` |
80-
| loadingIcon | 受控 loading 态图标 | `ReactNode` | `<Loading1 />` |
81-
| onChange | 切换开关时触发 | `onChange:(value: boolean, event: Event)` | `-` |
88+
| loadingIcon | 控制加载状态的图标,传入空值时禁用 loading 态 | `ReactNode` | `<Loading1 />` |
89+
| loading | loading 态,受控 | `boolean` | `-` |
90+
| onLoadingChange | 切换 loading 态时触发 | `onLoadingChange:(value: boolean)` | `-` |
91+
| onChange | 切换开关时触发 | `onChange:(value: boolean)` | `-` |
8292

8393
## 主题定制
8494

src/packages/switch/doc.zh-TW.md

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,14 @@ import { Switch } from '@nutui/nutui-react'
2626

2727
:::
2828

29+
### loading 態受控
30+
31+
:::demo
32+
33+
<CodeBlock src='h5/demo8.tsx'></CodeBlock>
34+
35+
:::
36+
2937
### 禁用狀態
3038

3139
:::demo
@@ -77,8 +85,10 @@ import { Switch } from '@nutui/nutui-react'
7785
| disabled | 禁用狀態 | `boolean` | `false` |
7886
| activeText | 打開時文字描述 | `ReactNode` | `-` |
7987
| inactiveText | 關閉時文字描述 | `ReactNode` | `-` |
80-
| loadingIcon | 受控 loading 態圖標 | `ReactNode` | `<Loading1 />` |
81-
| onChange | 切換開關時觸發 | `onChange:(value: boolean, event: Event)` | `-` |
88+
| loadingIcon | 控制加載狀態的圖標,當傳入空值時禁用 loading 狀態 | `ReactNode` | `<Loading1 />` |
89+
| loading | loading 態,受控 | `boolean` | `-` |
90+
| onLoadingChange | 切換 loading 態時觸發 | `onLoadingChange:(value: boolean)` | `-` |
91+
| onChange | 切換開關時觸發 | `onChange:(value: boolean)` | `-` |
8292

8393
## 主題定製
8494

src/packages/switch/switch.taro.tsx

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import React, { FunctionComponent, useEffect, useState } from 'react'
2-
32
import { View } from '@tarojs/components'
43
import classNames from 'classnames'
54
import { Loading1 } from '@nutui/icons-react-taro'
@@ -14,6 +13,8 @@ const defaultProps = {
1413
activeText: '',
1514
inactiveText: '',
1615
loadingIcon: <Loading1 />,
16+
loading: undefined,
17+
onLoadingChange: (loading: boolean) => {},
1718
} as TaroSwitchProps
1819
export const Switch: FunctionComponent<Partial<TaroSwitchProps>> = (props) => {
1920
const {
@@ -26,6 +27,8 @@ export const Switch: FunctionComponent<Partial<TaroSwitchProps>> = (props) => {
2627
className,
2728
style,
2829
onChange,
30+
loading: propLoading,
31+
onLoadingChange,
2932
...rest
3033
} = {
3134
...defaultProps,
@@ -38,12 +41,21 @@ export const Switch: FunctionComponent<Partial<TaroSwitchProps>> = (props) => {
3841
defaultValue: defaultChecked,
3942
})
4043

44+
const [internalLoading, setInternalLoading] = useState(false)
45+
const loading = propLoading !== undefined ? propLoading : internalLoading
46+
47+
const setLoading = (val: boolean) => {
48+
if (propLoading !== undefined) {
49+
onLoadingChange(val)
50+
} else {
51+
setInternalLoading(val)
52+
}
53+
}
54+
4155
useEffect(() => {
42-
changing && setChanging(false)
56+
loading && setLoading(false)
4357
}, [value])
4458

45-
const [changing, setChanging] = useState(false)
46-
4759
const classes = () => {
4860
return classNames([
4961
classPrefix,
@@ -57,13 +69,14 @@ export const Switch: FunctionComponent<Partial<TaroSwitchProps>> = (props) => {
5769
}
5870

5971
const onClick = async () => {
60-
if (disabled || changing) return
72+
if (disabled || loading) return
6173
if (onChange) {
62-
setChanging(true)
74+
loadingIcon && setLoading(true)
75+
onChange(!value)
6376
try {
6477
await onChange(!value)
6578
} catch (e) {
66-
setChanging(false)
79+
setLoading(false)
6780
}
6881
}
6982
setValue(!value)
@@ -84,7 +97,7 @@ export const Switch: FunctionComponent<Partial<TaroSwitchProps>> = (props) => {
8497
},
8598
])}
8699
>
87-
{changing && loadingIcon ? (
100+
{loading && loadingIcon ? (
88101
<>{loadingIcon}</>
89102
) : (
90103
<>

0 commit comments

Comments
 (0)