diff --git a/src/packages/switch/demo.taro.tsx b/src/packages/switch/demo.taro.tsx
index ac961c8b0d..cf8e3ffc3e 100644
--- a/src/packages/switch/demo.taro.tsx
+++ b/src/packages/switch/demo.taro.tsx
@@ -10,6 +10,7 @@ import Demo4 from './demos/taro/demo4'
import Demo5 from './demos/taro/demo5'
import Demo6 from './demos/taro/demo6'
import Demo7 from './demos/taro/demo7'
+import Demo8 from './demos/taro/demo8'
const SwitchDemo = () => {
const [translated] = useTranslate({
@@ -17,6 +18,7 @@ const SwitchDemo = () => {
basic: '非受控',
disabled: '禁用状态',
asyncControl: '受控',
+ loadingControl: 'loading 态受控',
customColor: '自定义颜色',
supportText: '支持文字',
supportIcon: '支持Icon',
@@ -26,6 +28,7 @@ const SwitchDemo = () => {
basic: '非受控',
disabled: '禁用狀態',
asyncControl: '受控',
+ loadingControl: 'loading 態受控',
customColor: '自定義顏色',
supportText: '支持文字',
supportIcon: '支持Icon',
@@ -35,6 +38,7 @@ const SwitchDemo = () => {
basic: 'Uncontrolled',
disabled: 'Disabled',
asyncControl: 'controlled',
+ loadingControl: 'Controlled with loading',
customColor: 'Custom Color',
supportText: 'Support Text',
supportIcon: 'Support Icon',
@@ -49,6 +53,8 @@ const SwitchDemo = () => {
{translated.asyncControl}
+ {translated.loadingControl}
+
{translated.disabled}
{translated.supportText}
diff --git a/src/packages/switch/demo.tsx b/src/packages/switch/demo.tsx
index 7d33a634d2..758aeaf5ad 100644
--- a/src/packages/switch/demo.tsx
+++ b/src/packages/switch/demo.tsx
@@ -7,6 +7,7 @@ import Demo4 from './demos/h5/demo4'
import Demo5 from './demos/h5/demo5'
import Demo6 from './demos/h5/demo6'
import Demo7 from './demos/h5/demo7'
+import Demo8 from './demos/h5/demo8'
const SwitchDemo = () => {
const [translated] = useTranslate({
@@ -14,6 +15,7 @@ const SwitchDemo = () => {
basic: '非受控',
disabled: '禁用状态',
asyncControl: '受控',
+ loadingControl: 'loading 态受控',
customColor: '自定义颜色',
supportText: '支持文字',
supportIcon: '支持Icon',
@@ -23,6 +25,7 @@ const SwitchDemo = () => {
basic: '非受控',
disabled: '禁用狀態',
asyncControl: '受控',
+ loadingControl: 'loading 態受控',
customColor: '自定義顏色',
supportText: '支持文字',
supportIcon: '支持Icon',
@@ -32,6 +35,7 @@ const SwitchDemo = () => {
basic: 'Uncontrolled',
disabled: 'Disabled',
asyncControl: 'controlled',
+ loadingControl: 'Controlled with loading',
customColor: 'Custom Color',
supportText: 'Support Text',
supportIcon: 'Support Icon',
@@ -45,6 +49,8 @@ const SwitchDemo = () => {
{translated.asyncControl}
+ {translated.loadingControl}
+
{translated.disabled}
{translated.supportText}
diff --git a/src/packages/switch/demos/h5/demo8.tsx b/src/packages/switch/demos/h5/demo8.tsx
new file mode 100644
index 0000000000..c137687c35
--- /dev/null
+++ b/src/packages/switch/demos/h5/demo8.tsx
@@ -0,0 +1,35 @@
+import React, { useState } from 'react'
+import { Cell, Switch, Toast } from '@nutui/nutui-react'
+
+const Demo8 = () => {
+ const [checkedAsync, setCheckedAsync] = useState(true)
+ const [externalLoading, setExternalLoading] = useState(false)
+
+ const mockRequest = (): Promise => {
+ return new Promise((resolve) => {
+ setTimeout(() => {
+ resolve()
+ }, 2000)
+ })
+ }
+
+ const onChangeAsync = async (value: boolean) => {
+ Toast.show(`2秒后异步触发 ${value}`)
+ await mockRequest()
+ setCheckedAsync(value)
+ // setExternalLoading(false)
+ }
+ return (
+
+ {
+ setExternalLoading(loading)
+ }}
+ checked={checkedAsync}
+ onChange={(value) => onChangeAsync(value)}
+ />
+ |
+ )
+}
+export default Demo8
diff --git a/src/packages/switch/demos/taro/demo8.tsx b/src/packages/switch/demos/taro/demo8.tsx
new file mode 100644
index 0000000000..13f847b6f9
--- /dev/null
+++ b/src/packages/switch/demos/taro/demo8.tsx
@@ -0,0 +1,46 @@
+import React, { useState } from 'react'
+import { Cell, Switch, Toast } from '@nutui/nutui-react-taro'
+
+const Demo8 = () => {
+ const [checkedAsync, setCheckedAsync] = useState(true)
+ const [value, setValue] = useState(false)
+ const [showToast, setShowToast] = useState(false)
+ const [externalLoading, setExternalLoading] = useState(false)
+ const mockRequest = (): Promise => {
+ return new Promise((resolve) => {
+ setTimeout(() => {
+ resolve()
+ }, 2000)
+ })
+ }
+
+ const onChangeAsync = async (value: boolean) => {
+ setValue(value)
+ setShowToast(true)
+ await mockRequest()
+ setCheckedAsync(value)
+ // setExternalLoading(false)
+ }
+ return (
+ <>
+
+ {
+ setExternalLoading(loading)
+ }}
+ checked={checkedAsync}
+ onChange={(value) => onChangeAsync(value)}
+ />
+ |
+ {
+ setShowToast(false)
+ }}
+ />
+ >
+ )
+}
+export default Demo8
diff --git a/src/packages/switch/doc.en-US.md b/src/packages/switch/doc.en-US.md
index b4090e42d0..3495efdb10 100644
--- a/src/packages/switch/doc.en-US.md
+++ b/src/packages/switch/doc.en-US.md
@@ -26,6 +26,14 @@ import { Switch } from '@nutui/nutui-react'
:::
+### loading 态受控
+
+:::demo
+
+
+
+:::
+
### disabled status
:::demo
@@ -77,8 +85,10 @@ import { Switch } from '@nutui/nutui-react'
| disabled | Disabled | `boolean` | `false` |
| activeText | Text description when opening | `ReactNode` | `-` |
| inactiveText | Text description when closed | `ReactNode` | `-` |
-| loadingIcon | Controlled loading state icon | `ReactNode` | `` |
-| onChange | Trigger when switching switches | `onChange:(value: boolean, event: Event)` | `-` |
+| loadingIcon | Control the loading state icon, disable the loading state when a null | `ReactNode` | `` |
+| loading | loading state, controlled | `boolean` | `-` |
+| onLoadingChange | Triggered when switching loading | `onLoadingChange:(value: boolean)` | `-` |
+| onChange | Trigger when switching switches | `onChange:(value: boolean)` | `-` |
## Theming
diff --git a/src/packages/switch/doc.md b/src/packages/switch/doc.md
index d699265bd2..3a9e7b2afc 100644
--- a/src/packages/switch/doc.md
+++ b/src/packages/switch/doc.md
@@ -26,6 +26,14 @@ import { Switch } from '@nutui/nutui-react'
:::
+### loading 态受控
+
+:::demo
+
+
+
+:::
+
### 禁用状态
:::demo
@@ -77,8 +85,10 @@ import { Switch } from '@nutui/nutui-react'
| disabled | 禁用状态 | `boolean` | `false` |
| activeText | 打开时文字描述 | `ReactNode` | `-` |
| inactiveText | 关闭时文字描述 | `ReactNode` | `-` |
-| loadingIcon | 受控 loading 态图标 | `ReactNode` | `` |
-| onChange | 切换开关时触发 | `onChange:(value: boolean, event: Event)` | `-` |
+| loadingIcon | 控制加载状态的图标,传入空值时禁用 loading 态 | `ReactNode` | `` |
+| loading | loading 态,受控 | `boolean` | `-` |
+| onLoadingChange | 切换 loading 态时触发 | `onLoadingChange:(value: boolean)` | `-` |
+| onChange | 切换开关时触发 | `onChange:(value: boolean)` | `-` |
## 主题定制
diff --git a/src/packages/switch/doc.taro.md b/src/packages/switch/doc.taro.md
index 77a4646b2f..c11f5a5581 100644
--- a/src/packages/switch/doc.taro.md
+++ b/src/packages/switch/doc.taro.md
@@ -26,6 +26,14 @@ import { Switch } from '@nutui/nutui-react-taro'
:::
+### loading 态受控
+
+:::demo
+
+
+
+:::
+
### 禁用状态
:::demo
@@ -77,8 +85,10 @@ import { Switch } from '@nutui/nutui-react-taro'
| disabled | 禁用状态 | `boolean` | `false` |
| activeText | 打开时文字描述 | `ReactNode` | `-` |
| inactiveText | 关闭时文字描述 | `ReactNode` | `-` |
-| loadingIcon | 受控 loading 态图标 | `ReactNode` | `` |
-| onChange | 切换开关时触发 | `onChange:(value: boolean, event: Event)` | `-` |
+| loadingIcon | 控制加载状态的图标,传入空值时禁用 loading 态 | `ReactNode` | `` |
+| loading | loading 态,受控 | `boolean` | `-` |
+| onLoadingChange | 切换 loading 态时触发 | `onLoadingChange:(value: boolean)` | `-` |
+| onChange | 切换开关时触发 | `onChange:(value: boolean)` | `-` |
## 主题定制
diff --git a/src/packages/switch/doc.zh-TW.md b/src/packages/switch/doc.zh-TW.md
index 0f12e4205a..e392e58924 100644
--- a/src/packages/switch/doc.zh-TW.md
+++ b/src/packages/switch/doc.zh-TW.md
@@ -26,6 +26,14 @@ import { Switch } from '@nutui/nutui-react'
:::
+### loading 態受控
+
+:::demo
+
+
+
+:::
+
### 禁用狀態
:::demo
@@ -77,8 +85,10 @@ import { Switch } from '@nutui/nutui-react'
| disabled | 禁用狀態 | `boolean` | `false` |
| activeText | 打開時文字描述 | `ReactNode` | `-` |
| inactiveText | 關閉時文字描述 | `ReactNode` | `-` |
-| loadingIcon | 受控 loading 態圖標 | `ReactNode` | `` |
-| onChange | 切換開關時觸發 | `onChange:(value: boolean, event: Event)` | `-` |
+| loadingIcon | 控制加載狀態的圖標,當傳入空值時禁用 loading 狀態 | `ReactNode` | `` |
+| loading | loading 態,受控 | `boolean` | `-` |
+| onLoadingChange | 切換 loading 態時觸發 | `onLoadingChange:(value: boolean)` | `-` |
+| onChange | 切換開關時觸發 | `onChange:(value: boolean)` | `-` |
## 主題定製
diff --git a/src/packages/switch/switch.taro.tsx b/src/packages/switch/switch.taro.tsx
index 1d71905a6d..5d72b21c7f 100644
--- a/src/packages/switch/switch.taro.tsx
+++ b/src/packages/switch/switch.taro.tsx
@@ -1,5 +1,4 @@
import React, { FunctionComponent, useEffect, useState } from 'react'
-
import { View } from '@tarojs/components'
import classNames from 'classnames'
import { Loading1 } from '@nutui/icons-react-taro'
@@ -14,6 +13,8 @@ const defaultProps = {
activeText: '',
inactiveText: '',
loadingIcon: ,
+ loading: undefined,
+ onLoadingChange: (loading: boolean) => {},
} as TaroSwitchProps
export const Switch: FunctionComponent> = (props) => {
const {
@@ -26,6 +27,8 @@ export const Switch: FunctionComponent> = (props) => {
className,
style,
onChange,
+ loading: propLoading,
+ onLoadingChange,
...rest
} = {
...defaultProps,
@@ -38,12 +41,21 @@ export const Switch: FunctionComponent> = (props) => {
defaultValue: defaultChecked,
})
+ const [internalLoading, setInternalLoading] = useState(false)
+ const loading = propLoading !== undefined ? propLoading : internalLoading
+
+ const setLoading = (val: boolean) => {
+ if (propLoading !== undefined) {
+ onLoadingChange(val)
+ } else {
+ setInternalLoading(val)
+ }
+ }
+
useEffect(() => {
- changing && setChanging(false)
+ loading && setLoading(false)
}, [value])
- const [changing, setChanging] = useState(false)
-
const classes = () => {
return classNames([
classPrefix,
@@ -57,13 +69,14 @@ export const Switch: FunctionComponent> = (props) => {
}
const onClick = async () => {
- if (disabled || changing) return
+ if (disabled || loading) return
if (onChange) {
- setChanging(true)
+ loadingIcon && setLoading(true)
+ onChange(!value)
try {
await onChange(!value)
} catch (e) {
- setChanging(false)
+ setLoading(false)
}
}
setValue(!value)
@@ -84,7 +97,7 @@ export const Switch: FunctionComponent> = (props) => {
},
])}
>
- {changing && loadingIcon ? (
+ {loading && loadingIcon ? (
<>{loadingIcon}>
) : (
<>
diff --git a/src/packages/switch/switch.tsx b/src/packages/switch/switch.tsx
index b8a9d487fe..7622a9d50d 100644
--- a/src/packages/switch/switch.tsx
+++ b/src/packages/switch/switch.tsx
@@ -12,6 +12,8 @@ const defaultProps = {
activeText: '',
inactiveText: '',
loadingIcon: ,
+ loading: undefined,
+ onLoadingChange: (loading: boolean) => {},
} as WebSwitchProps
export const Switch: FunctionComponent> = (props) => {
const {
@@ -24,6 +26,8 @@ export const Switch: FunctionComponent> = (props) => {
className,
style,
onChange,
+ loading: propLoading,
+ onLoadingChange,
...rest
} = {
...defaultProps,
@@ -38,12 +42,21 @@ export const Switch: FunctionComponent> = (props) => {
defaultValue: defaultChecked,
})
+ const [internalLoading, setInternalLoading] = useState(false)
+ const loading = propLoading !== undefined ? propLoading : internalLoading
+
+ const setLoading = (val: boolean) => {
+ if (propLoading !== undefined) {
+ onLoadingChange(val)
+ } else {
+ setInternalLoading(val)
+ }
+ }
+
useEffect(() => {
- changing && setChanging(false)
+ loading && setLoading(false)
}, [value])
- const [changing, setChanging] = useState(false)
-
const classes = () => {
return classNames([
classPrefix,
@@ -57,13 +70,13 @@ export const Switch: FunctionComponent> = (props) => {
}
const onClick = async () => {
- if (disabled || changing) return
+ if (disabled || loading) return
if (onChange) {
- setChanging(true)
+ loadingIcon && setLoading(true)
try {
await onChange(!value)
} catch (e) {
- setChanging(false)
+ setLoading(false)
}
}
setValue(!value)
@@ -84,7 +97,7 @@ export const Switch: FunctionComponent> = (props) => {
},
])}
>
- {changing && loadingIcon ? (
+ {loading && loadingIcon ? (
<>{loadingIcon}>
) : (
<>
diff --git a/src/sites/sites-react/doc/docs/react/migrate-from-v2.md b/src/sites/sites-react/doc/docs/react/migrate-from-v2.md
index f986185539..aa80122103 100644
--- a/src/sites/sites-react/doc/docs/react/migrate-from-v2.md
+++ b/src/sites/sites-react/doc/docs/react/migrate-from-v2.md
@@ -239,6 +239,8 @@ plugins: [
- `activeText` 属性类型更改为`ReactNode`
- `inactiveText` 属性类型更改为 `ReactNode`
- 新增 `loadingIcon` 属性,受控 loading 态图标
+- 新增 `loading` 属性,loading 态受控
+- 新增 `onLodingingChange` ,切换 loading 态时触发
[//]: # '#### Toast'
diff --git a/src/sites/sites-react/doc/docs/react/official-theme-react.md b/src/sites/sites-react/doc/docs/react/official-theme-react.md
index e851e1c5b8..3d641eb27c 100644
--- a/src/sites/sites-react/doc/docs/react/official-theme-react.md
+++ b/src/sites/sites-react/doc/docs/react/official-theme-react.md
@@ -12,7 +12,6 @@ NutUI 默认提供多套官方`UI`主题,同时允许在一定程度上定制
| 京东 JDesign 主题 ([预览](https://nutui.jd.com/h5/react/jdesign-3x/#/zh-CN/component/button)) | `variables-jmapp.scss` |
| 京东 JRKF 主题 | `variables-jrkf.scss` |
-
## 使用方式
需要注意的是,配置主题时,你还需要在入口文件中引入 global 类的文件来加载一些 NutUI React 的全局性逻辑和样式:
diff --git a/src/sites/sites-react/doc/docs/taro/migrate-from-v2.md b/src/sites/sites-react/doc/docs/taro/migrate-from-v2.md
index e7f888b66d..5391e76faa 100644
--- a/src/sites/sites-react/doc/docs/taro/migrate-from-v2.md
+++ b/src/sites/sites-react/doc/docs/taro/migrate-from-v2.md
@@ -238,6 +238,8 @@ plugins: [
- `activeText` 属性类型更改为`ReactNode`
- `inactiveText` 属性类型更改为 `ReactNode`
- 新增 `loadingIcon` 属性,受控 loading 态图标
+- 新增 `loading` 属性,loading 态受控
+- 新增 `onLodingingChange` ,切换 loading 态时触发
[//]: # '#### Toast'
diff --git a/src/types/spec/switch/base.ts b/src/types/spec/switch/base.ts
index 156821089c..e0b81fd5d0 100644
--- a/src/types/spec/switch/base.ts
+++ b/src/types/spec/switch/base.ts
@@ -8,5 +8,7 @@ export interface BaseSwitch extends BaseProps {
activeText: ReactNode
inactiveText: ReactNode
loadingIcon: ReactNode
+ loading: boolean | undefined
+ onLoadingChange: (loading: boolean) => void
onChange: (val: boolean) => void
}