refactor(spin, base-loading, base-wave): ts

This commit is contained in:
07akioni 2021-01-17 23:34:37 +08:00
parent e505f6e1b9
commit 5f139182d7
20 changed files with 221 additions and 198 deletions

View File

@ -1 +0,0 @@
export { default } from './src/Loading.vue'

View File

@ -0,0 +1 @@
export { default } from './src/Loading'

View File

@ -0,0 +1,66 @@
import { h, defineComponent, renderSlot } from 'vue'
import { useStyle } from '../../../_mixins'
import NIconSwitchTransition from '../../icon-switch-transition'
import style from './styles/index.cssr'
export default defineComponent({
name: 'BaseLoading',
props: {
scale: {
type: Number,
default: 1
},
radius: {
type: Number,
default: 100
},
strokeWidth: {
type: Number,
default: 28
},
stroke: {
type: String,
default: undefined
},
show: {
type: Boolean,
default: true
}
},
setup () {
useStyle('BaseLoading', style)
},
render () {
return (
<div class="n-base-loading" style={{ stroke: this.stroke }}>
<NIconSwitchTransition>
{{
default: () =>
this.show ? (
<svg
key="loading"
class="n-base-loading-circular n-base-loading__icon"
viewBox={`0 0 ${(this.radius * 2) / this.scale} ${
(this.radius * 2) / this.scale
}`}
>
<circle
style={{ strokeWidth: this.strokeWidth }}
class="n-base-loading-circular-path"
cx={this.radius / this.scale}
cy={this.radius / this.scale}
fill="none"
r={this.radius - this.strokeWidth / 2}
/>
</svg>
) : (
<div key="placeholder" class="n-base-loading__placeholder">
{renderSlot(this.$slots, 'default')}
</div>
)
}}
</NIconSwitchTransition>
</div>
)
}
})

View File

@ -1,70 +0,0 @@
<template>
<div
class="n-base-loading"
:style="{
stroke
}"
>
<n-icon-switch-transition>
<svg
v-if="show"
key="loading"
class="n-base-loading-circular n-base-loading__icon"
:viewBox="`0 0 ${(radius * 2) / scale} ${(radius * 2) / scale}`"
>
<circle
:style="{
strokeWidth
}"
class="n-base-loading-circular-path"
:cx="radius / scale"
:cy="radius / scale"
fill="none"
:r="radius - strokeWidth / 2"
/>
</svg>
<div v-else key="placeholder" class="n-base-loading__placeholder">
<slot />
</div>
</n-icon-switch-transition>
</div>
</template>
<script>
import { defineComponent } from 'vue'
import { useStyle } from '../../../_mixins'
import NIconSwitchTransition from '../../icon-switch-transition'
import style from './styles/index.cssr.js'
export default defineComponent({
name: 'BaseLoading',
components: {
NIconSwitchTransition
},
props: {
scale: {
type: Number,
default: 1
},
radius: {
type: Number,
default: 100
},
strokeWidth: {
type: Number,
default: 28
},
stroke: {
type: String,
default: undefined
},
show: {
type: Boolean,
default: true
}
},
setup () {
useStyle('BaseLoading', style)
}
})
</script>

View File

@ -1 +0,0 @@
export { default } from './src/Wave.vue'

1
src/_base/wave/index.ts Normal file
View File

@ -0,0 +1 @@
export { default } from './src/Wave'

View File

@ -0,0 +1,51 @@
import { h, defineComponent, ref, onBeforeUnmount, nextTick } from 'vue'
import { useStyle } from '../../../_mixins'
import style from './styles/index.cssr'
export default defineComponent({
name: 'BaseWave',
setup () {
useStyle('BaseWave', style)
const selfRef = ref<HTMLElement | null>(null)
const activeRef = ref(false)
let animationTimerId: number | null = null
onBeforeUnmount(() => {
if (animationTimerId !== null) {
window.clearTimeout(animationTimerId)
}
})
return {
active: activeRef,
selfRef,
play () {
if (animationTimerId !== null) {
window.clearTimeout(animationTimerId)
activeRef.value = false
animationTimerId = null
}
void nextTick(() => {
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
void selfRef.value!.offsetHeight
activeRef.value = true
animationTimerId = window.setTimeout(() => {
activeRef.value = false
animationTimerId = null
}, 1000)
})
}
}
},
render () {
return (
<div
ref="selfRef"
class={[
'n-base-wave',
{
'n-base-wave--active': this.active
}
]}
/>
)
}
})

View File

@ -1,51 +0,0 @@
<template>
<div
class="n-base-wave"
:class="{
'n-base-wave--active': active
}"
/>
</template>
<script>
import { defineComponent } from 'vue'
import { useStyle } from '../../../_mixins'
import style from './styles/index.cssr.js'
export default defineComponent({
name: 'BaseWave',
setup () {
useStyle('BaseWave', style)
},
data () {
return {
active: false,
animationTimerId: null
}
},
beforeUnmount () {
const animationTimerId = this.animationTimerId
if (animationTimerId !== null) {
window.clearTimeout(animationTimerId)
}
},
methods: {
play () {
const animationTimerId = this.animationTimerId
if (animationTimerId !== null) {
window.clearTimeout(this.animationTimerId)
this.active = false
this.animationTimerId = null
}
this.$nextTick(() => {
void this.$el.offsetHeight
this.active = true
this.animationTimerId = window.setTimeout(() => {
this.active = false
this.animationTimerId = null
}, 1000)
})
}
}
})
</script>

View File

@ -1,4 +1,4 @@
import { cB } from '../../../../_utils/cssr/index.js'
import { cB } from '../../../../_utils/cssr/index'
export default cB('base-wave', `
position: absolute;

View File

@ -37,7 +37,7 @@ export default defineComponent({
},
size: {
type: [String, Number, Array] as PropType<
'small' | 'medium' | 'large' | number | [number, number]
'small' | 'medium' | 'large' | number | [number, number]
>,
default: 'medium'
},
@ -49,7 +49,7 @@ export default defineComponent({
setup (props) {
const themeRef = useTheme('Space', 'Space', undefined, spaceLight, props)
return {
margin: computed<{ horizontal: number; vertical: number }>(() => {
margin: computed<{ horizontal: number, vertical: number }>(() => {
const { size } = props
if (Array.isArray(size)) {
return {
@ -79,9 +79,9 @@ export default defineComponent({
render () {
const { vertical, align, inline, justify, itemStyle, margin } = this
const children = flatten(getSlot(this))
const horizontalMargin = margin.horizontal + 'px'
const verticalMargin = margin.vertical + 'px'
const semiVerticalMargin = margin.vertical / 2 + 'px'
const horizontalMargin = `${margin.horizontal}px`
const verticalMargin = `${margin.vertical}px`
const semiVerticalMargin = `${margin.vertical / 2}px`
const lastIndex = children.length - 1
return h(
'div',

View File

@ -1,2 +0,0 @@
/* istanbul ignore file */
export { default as NSpin } from './src/Spin.vue'

2
src/spin/index.ts Normal file
View File

@ -0,0 +1,2 @@
/* istanbul ignore file */
export { default as NSpin } from './src/Spin'

View File

@ -1,39 +1,20 @@
<template>
<div v-if="$slots.default" class="n-spin-container" :style="cssVars">
<div
:class="{
'n-spin-content--spinning': compitableShow
}"
class="n-spin-content"
>
<slot />
</div>
<transition name="n-fade-in-transition">
<n-base-loading
v-if="compitableShow"
:stroke="stroke"
:stroke-width="mergedStrokeWidth"
class="n-spin"
/>
</transition>
</div>
<n-base-loading
v-else
:style="cssVars"
:stroke="stroke"
:stroke-width="mergedStrokeWidth"
class="n-spin"
/>
</template>
<script>
import { computed, defineComponent } from 'vue'
import {
computed,
defineComponent,
h,
renderSlot,
Transition,
PropType,
CSSProperties
} from 'vue'
import { useCompitable } from 'vooks'
import { NBaseLoading } from '../../_base'
import { useTheme } from '../../_mixins'
import type { ThemeProps } from '../../_mixins'
import { createKey, warn } from '../../_utils'
import { spinLight } from '../styles'
import style from './styles/index.cssr.js'
import type { SpinTheme } from '../styles'
import style from './styles/index.cssr'
const STROKE_WIDTH = {
small: 22,
@ -43,17 +24,14 @@ const STROKE_WIDTH = {
export default defineComponent({
name: 'Spin',
components: {
NBaseLoading
},
props: {
...useTheme.props,
...(useTheme.props as ThemeProps<SpinTheme>),
stroke: {
type: String,
default: undefined
},
size: {
type: [String, Number],
type: [String, Number] as PropType<'small' | 'medium' | 'large'>,
default: 'medium'
},
show: {
@ -65,7 +43,8 @@ export default defineComponent({
default: undefined
},
spinning: {
validator () {
type: Boolean,
validator: () => {
warn('spin', '`spinning` is deprecated, please use `show` instead.')
return true
},
@ -96,6 +75,41 @@ export default defineComponent({
}
})
}
},
render () {
const { $slots } = this
return $slots.default ? (
<div class="n-spin-container" style={this.cssVars as CSSProperties}>
<div
class={[
'n-spin-content',
{
'n-spin-content--spinning': this.compitableShow
}
]}
>
{renderSlot($slots, 'default')}
</div>
<Transition name="n-fade-in-transition">
{{
default: () =>
this.compitableShow ? (
<NBaseLoading
stroke={this.stroke}
strokeWidth={this.mergedStrokeWidth}
class="n-spin"
/>
) : null
}}
</Transition>
</div>
) : (
<NBaseLoading
style={this.cssVars as CSSProperties}
stroke={this.stroke}
stroke-width={this.mergedStrokeWidth}
class="n-spin"
/>
)
}
})
</script>

View File

@ -1,6 +1,7 @@
import { commonDark } from '../../_styles/new-common'
import type { SpinTheme } from './light'
export default {
const spinDark: SpinTheme = {
name: 'Spin',
common: commonDark,
self (vars) {
@ -24,3 +25,5 @@ export default {
}
}
}
export default spinDark

View File

@ -1,2 +0,0 @@
export { default as spinDark } from './dark.js'
export { default as spinLight } from './light.js'

3
src/spin/styles/index.ts Normal file
View File

@ -0,0 +1,3 @@
export { default as spinDark } from './dark'
export { default as spinLight } from './light'
export type { SpinThemeVars, SpinTheme } from './light'

View File

@ -1,26 +0,0 @@
import { commonLight } from '../../_styles/new-common'
export default {
name: 'Spin',
common: commonLight,
self (vars) {
const {
opacityDisabled,
heightTiny,
heightSmall,
heightMedium,
heightLarge,
heightHuge,
primaryColor
} = vars
return {
sizeTiny: heightTiny,
sizeSmall: heightSmall,
sizeMedium: heightMedium,
sizeLarge: heightLarge,
sizeHuge: heightHuge,
color: primaryColor,
opacitySpinning: opacityDisabled
}
}
}

35
src/spin/styles/light.ts Normal file
View File

@ -0,0 +1,35 @@
import { Theme } from '../../_mixins'
import { commonLight } from '../../_styles/new-common'
import type { ThemeCommonVars } from '../../_styles/new-common'
const self = (vars: ThemeCommonVars) => {
const {
opacityDisabled,
heightTiny,
heightSmall,
heightMedium,
heightLarge,
heightHuge,
primaryColor
} = vars
return {
sizeTiny: heightTiny,
sizeSmall: heightSmall,
sizeMedium: heightMedium,
sizeLarge: heightLarge,
sizeHuge: heightHuge,
color: primaryColor,
opacitySpinning: opacityDisabled
}
}
export type SpinThemeVars = ReturnType<typeof self>
const spinLight: Theme<SpinThemeVars> = {
name: 'Spin',
common: commonLight,
self
}
export default spinLight
export type SpinTheme = typeof spinLight