mirror of
https://github.com/tusen-ai/naive-ui.git
synced 2025-02-23 13:31:06 +08:00
feat(spin): add delay
prop (#4781)
* feat(spin): add delay support * feat(spin): add demo for spin delay * test(spin): add tests for spinning * doc: add change log
This commit is contained in:
parent
396eb816fd
commit
9c84e32994
@ -51,11 +51,11 @@
|
||||
- `n-data-table` adds `titleAlign` prop, closes [#3954](https://github.com/tusen-ai/naive-ui/issues/3954).
|
||||
- `n-rate` exposes `index` in the default slot, closes [#4413](https://github.com/tusen-ai/naive-ui/issues/4413).
|
||||
- `n-scrollbar` adds `size` prop, closes [#3896](https://github.com/tusen-ai/naive-ui/issues/3896).
|
||||
- `n-select` adds `keyboard` prop, closes [#4340](https://github.com/tusen-ai/naive-ui/issues/4340).
|
||||
- `n-data-table`'s `render-expand-icon` add `expanded` param, closes [#4439](https://github.com/tusen-ai/naive-ui/issues/4439).
|
||||
- `n-tabs` adds `pane-wrapper-class` `pane-wrapper-style` prop.
|
||||
- `n-collapse` adds `titlePadding` theme variable, closes [#4728](https://github.com/tusen-ai/naive-ui/issues/4728).
|
||||
- `n-tabs` adds `placement` prop.
|
||||
- `n-spin` adds `delay` prop.
|
||||
|
||||
### i18n
|
||||
|
||||
|
@ -57,6 +57,7 @@
|
||||
- `n-tabs` 新增 `pane-wrapper-class` `pane-wrapper-style` 属性
|
||||
- `n-collapse` 新增 `titlePadding` 主题变量,关闭 [#4728](https://github.com/tusen-ai/naive-ui/issues/4728)
|
||||
- `n-tabs` 新增 `placement` 属性
|
||||
- `n-spin` 新增 `delay` 属性,
|
||||
|
||||
### i18n
|
||||
|
||||
|
30
src/spin/demos/enUS/delay.demo.vue
Normal file
30
src/spin/demos/enUS/delay.demo.vue
Normal file
@ -0,0 +1,30 @@
|
||||
<markdown>
|
||||
# Delay
|
||||
|
||||
You can specify a delay for displaying spin. If spinning ends during delay, spin won't appear.
|
||||
</markdown>
|
||||
|
||||
<template>
|
||||
<n-space vertical>
|
||||
<n-spin :show="show" :delay="1000">
|
||||
<n-alert title="La La La" type="success">
|
||||
Leave it till tomorrow to unpack my case. Honey disconnect the phone.
|
||||
</n-alert>
|
||||
</n-spin>
|
||||
<n-button @click="show = !show">
|
||||
{{ show ? 'Click to stop Spin' : 'Click to Spin' }}
|
||||
</n-button>
|
||||
</n-space>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent, ref } from 'vue'
|
||||
|
||||
export default defineComponent({
|
||||
setup () {
|
||||
return {
|
||||
show: ref(false)
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
@ -9,6 +9,7 @@ basic.vue
|
||||
wrap.vue
|
||||
description.vue
|
||||
customize-icon.vue
|
||||
delay.vue
|
||||
```
|
||||
|
||||
## API
|
||||
@ -23,6 +24,7 @@ customize-icon.vue
|
||||
| show | `boolean` | `true` | Specify whether spin is active when spin has content inside. It won't work if you just use spin itself. |
|
||||
| stroke-width | `number` | `undefined` | Relative width of spin's stroke, assuming the outer radius of spin is 100. |
|
||||
| stroke | `string` | `undefined` | Color of the spin. |
|
||||
| delay | `number` | `undefined` | Specifies a delay in milliseconds for loading state (prevent flush). |
|
||||
|
||||
### Spin Slots
|
||||
|
||||
|
30
src/spin/demos/zhCN/delay.demo.vue
Normal file
30
src/spin/demos/zhCN/delay.demo.vue
Normal file
@ -0,0 +1,30 @@
|
||||
<markdown>
|
||||
# 延迟
|
||||
|
||||
你可以设置一个显示延迟时间。在延迟时间到达前结束,Spin 将不会显示
|
||||
</markdown>
|
||||
|
||||
<template>
|
||||
<n-space vertical>
|
||||
<n-spin :show="show" :delay="1000">
|
||||
<n-alert title="La La La" type="success">
|
||||
明天再打开行李箱。宝贝,挂电话啦。
|
||||
</n-alert>
|
||||
</n-spin>
|
||||
<n-button @click="show = !show">
|
||||
{{ show ? '不要再转啦' : '点击来转圈' }}
|
||||
</n-button>
|
||||
</n-space>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent, ref } from 'vue'
|
||||
|
||||
export default defineComponent({
|
||||
setup () {
|
||||
return {
|
||||
show: ref(false)
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
@ -9,6 +9,7 @@ basic.vue
|
||||
wrap.vue
|
||||
description.vue
|
||||
customize-icon.vue
|
||||
delay.vue
|
||||
```
|
||||
|
||||
## API
|
||||
@ -23,6 +24,7 @@ customize-icon.vue
|
||||
| show | `boolean` | `true` | 在填入内容的情况下 Spin 是否激活,直接使用 Spin 时不生效 |
|
||||
| stroke-width | `number` | `undefined` | Spin 边缘的相对宽度,假定 Spin 的外侧半径是 100 |
|
||||
| stroke | `string` | `undefined` | Spin 的颜色 |
|
||||
| delay | `number` | `undefined` | 延迟显示加载效果的时间, 单位为毫秒(避免闪烁) |
|
||||
|
||||
### Spin Slots
|
||||
|
||||
|
@ -5,6 +5,7 @@ import {
|
||||
Transition,
|
||||
type PropType,
|
||||
type CSSProperties,
|
||||
ref,
|
||||
watchEffect
|
||||
} from 'vue'
|
||||
import { useCompitable } from 'vooks'
|
||||
@ -16,6 +17,7 @@ import { createKey, type ExtractPublicPropTypes, warnOnce } from '../../_utils'
|
||||
import { spinLight } from '../styles'
|
||||
import type { SpinTheme } from '../styles'
|
||||
import style from './styles/index.cssr'
|
||||
import { debounce, isNumber } from 'lodash-es'
|
||||
|
||||
const STROKE_WIDTH = {
|
||||
small: 20,
|
||||
@ -46,6 +48,10 @@ export const spinProps = {
|
||||
return true
|
||||
},
|
||||
default: undefined
|
||||
},
|
||||
delay: {
|
||||
type: Number,
|
||||
default: undefined
|
||||
}
|
||||
}
|
||||
|
||||
@ -104,9 +110,29 @@ export default defineComponent({
|
||||
props
|
||||
)
|
||||
: undefined
|
||||
|
||||
const shouldDelay = computed(
|
||||
() => isNumber(props.delay) && props.delay !== 0
|
||||
)
|
||||
const compitableShow = useCompitable(props, ['spinning', 'show'])
|
||||
const spanning = ref(false)
|
||||
|
||||
watchEffect((onCleanup) => {
|
||||
if (compitableShow.value && shouldDelay.value) {
|
||||
const debouncedShow = debounce(
|
||||
() => (spanning.value = true),
|
||||
props.delay
|
||||
)
|
||||
debouncedShow()
|
||||
onCleanup(() => debouncedShow.cancel())
|
||||
} else {
|
||||
spanning.value = compitableShow.value
|
||||
}
|
||||
})
|
||||
|
||||
return {
|
||||
mergedClsPrefix: mergedClsPrefixRef,
|
||||
compitableShow: useCompitable(props, ['spinning', 'show']),
|
||||
spanning,
|
||||
mergedStrokeWidth: computed(() => {
|
||||
const { strokeWidth } = props
|
||||
if (strokeWidth !== undefined) return strokeWidth
|
||||
@ -160,14 +186,14 @@ export default defineComponent({
|
||||
<div
|
||||
class={[
|
||||
`${mergedClsPrefix}-spin-content`,
|
||||
this.compitableShow && `${mergedClsPrefix}-spin-content--spinning`
|
||||
this.spanning && `${mergedClsPrefix}-spin-content--spinning`
|
||||
]}
|
||||
>
|
||||
{$slots}
|
||||
</div>
|
||||
<Transition name="fade-in-transition">
|
||||
{{
|
||||
default: () => (this.compitableShow ? icon : null)
|
||||
default: () => (this.spanning ? icon : null)
|
||||
}}
|
||||
</Transition>
|
||||
</div>
|
||||
|
@ -90,4 +90,51 @@ describe('n-spin', () => {
|
||||
expect(wrapper.find('circle').attributes('stroke-width')).toEqual('40')
|
||||
wrapper.unmount()
|
||||
})
|
||||
|
||||
it('should work with `delay` prop', async () => {
|
||||
const wrapper = mount(NSpin, {
|
||||
props: {
|
||||
show: true,
|
||||
delay: 1000
|
||||
},
|
||||
slots: {
|
||||
default: () => 'test'
|
||||
}
|
||||
})
|
||||
expect(wrapper.find('.n-spin-content').classes()).not.toContain(
|
||||
'n-spin-content--spinning'
|
||||
)
|
||||
await new Promise<void>((resolve) => setTimeout(() => resolve(), 1000))
|
||||
|
||||
expect(wrapper.find('.n-spin-content').classes()).toContain(
|
||||
'n-spin-content--spinning'
|
||||
)
|
||||
})
|
||||
|
||||
it('should `delay` prop not delay close spin', async () => {
|
||||
const wrapper = mount(NSpin, {
|
||||
props: {
|
||||
show: true,
|
||||
delay: 1000
|
||||
},
|
||||
slots: {
|
||||
default: () => 'test'
|
||||
}
|
||||
})
|
||||
expect(wrapper.find('.n-spin-content').classes()).not.toContain(
|
||||
'n-spin-content--spinning'
|
||||
)
|
||||
await new Promise<void>((resolve) => setTimeout(() => resolve(), 1000))
|
||||
|
||||
expect(wrapper.find('.n-spin-content').classes()).toContain(
|
||||
'n-spin-content--spinning'
|
||||
)
|
||||
|
||||
await wrapper.setProps({
|
||||
show: false
|
||||
})
|
||||
expect(wrapper.find('.n-spin-content').classes()).not.toContain(
|
||||
'n-spin-content--spinning'
|
||||
)
|
||||
})
|
||||
})
|
||||
|
Loading…
Reference in New Issue
Block a user