Compare commits

...

2 Commits

Author SHA1 Message Date
6096c28669 feat: add loading icon 2023-04-19 08:30:24 +08:00
786877b629 chore: change 2023-04-19 08:16:23 +08:00
4 changed files with 103 additions and 1 deletions

View File

@ -21,6 +21,7 @@ import {
isUnBorderedButtonType,
spaceChildren
} from './button-helper'
import LoadingIcon from './loading-icon'
type Loading = number | boolean
function getLoadingConfig(loading: ButtonProps['loading']): LoadingConfigType {
@ -183,7 +184,17 @@ const Button = defineComponent({
compactItemClassnames.value,
rootClassName
)
const iconNode = icon && (!innerLoading.value ? icon?.() : <>L</>)
const iconNode =
icon &&
(!innerLoading.value ? (
icon?.()
) : (
<LoadingIcon
existIcon={!!icon}
prefixCls={prefixCls.value}
loading={!!innerLoading.value}
/>
))
const kids =
children || children === 0

View File

@ -0,0 +1,67 @@
import { Transition, defineComponent, nextTick } from 'vue'
import { booleanType, someType, stringType } from '@v-c/utils'
import LoadingOutlined from '@ant-design/icons-vue/LoadingOutlined'
export interface LoadingIconProps {
prefixCls: string
existIcon: boolean
loading?: boolean | object
}
export const loadingIconProps = {
prefixCls: stringType(),
existIcon: booleanType(),
loading: someType<boolean | object>([Boolean, Object])
}
const getCollapsedWidth = (el: Element) => {
const node: HTMLElement = el as HTMLElement
if (node) {
node.style.width = '0'
node.style.opacity = '0'
node.style.transform = 'scale(0)'
}
}
const getRealWidth = (el: Element) => {
const node: HTMLElement = el as HTMLElement
nextTick(() => {
if (node) {
node.style.width = `${node.scrollWidth}px`
node.style.opacity = '1'
node.style.transform = 'scale(1)'
}
}).then()
}
const LoadingIcon = defineComponent({
name: 'LoadingIcon',
props: loadingIconProps,
setup(props) {
return () => {
const { loading, existIcon, prefixCls } = props
const visible = !!loading
if (existIcon) {
return (
<span class={`${prefixCls}-loading-icon`}>
<LoadingOutlined />
</span>
)
}
return (
<Transition
name={`${prefixCls}-loading-icon-motion`}
onBeforeEnter={getCollapsedWidth}
onEnter={getRealWidth}
>
{visible ? (
<span class={`${prefixCls}-loading-icon`}>
<LoadingOutlined />
</span>
) : null}
</Transition>
)
}
}
})
export default LoadingIcon

View File

@ -23,6 +23,7 @@
},
"dependencies": {
"@ant-design/colors": "^7.0.0",
"@ant-design/icons-vue": "^6.1.0",
"@antd-tiny-vue/cssinjs": "0.0.8",
"@ctrl/tinycolor": "^3.6.0",
"@v-c/utils": "^0.0.22",

View File

@ -4,6 +4,9 @@ dependencies:
'@ant-design/colors':
specifier: ^7.0.0
version: 7.0.0
'@ant-design/icons-vue':
specifier: ^6.1.0
version: 6.1.0(vue@3.2.47)
'@antd-tiny-vue/cssinjs':
specifier: 0.0.8
version: 0.0.8(vue@3.2.47)
@ -196,12 +199,32 @@ packages:
'@jridgewell/trace-mapping': 0.3.18
dev: true
/@ant-design/colors@6.0.0:
resolution: {integrity: sha512-qAZRvPzfdWHtfameEGP2Qvuf838NhergR35o+EuVyB5XvSA98xod5r4utvi4TJ3ywmevm290g9nsCG5MryrdWQ==}
dependencies:
'@ctrl/tinycolor': 3.6.0
dev: false
/@ant-design/colors@7.0.0:
resolution: {integrity: sha512-iVm/9PfGCbC0dSMBrz7oiEXZaaGH7ceU40OJEfKmyuzR9R5CRimJYPlRiFtMQGQcbNMea/ePcoIebi4ASGYXtg==}
dependencies:
'@ctrl/tinycolor': 3.6.0
dev: false
/@ant-design/icons-svg@4.2.1:
resolution: {integrity: sha512-EB0iwlKDGpG93hW8f85CTJTs4SvMX7tt5ceupvhALp1IF44SeUFOMhKUOYqpsoYWQKAOuTRDMqn75rEaKDp0Xw==}
dev: false
/@ant-design/icons-vue@6.1.0(vue@3.2.47):
resolution: {integrity: sha512-EX6bYm56V+ZrKN7+3MT/ubDkvJ5rK/O2t380WFRflDcVFgsvl3NLH7Wxeau6R8DbrO5jWR6DSTC3B6gYFp77AA==}
peerDependencies:
vue: '>=3.0.3'
dependencies:
'@ant-design/colors': 6.0.0
'@ant-design/icons-svg': 4.2.1
vue: 3.2.47
dev: false
/@antd-tiny-vue/cssinjs@0.0.8(vue@3.2.47):
resolution: {integrity: sha512-Q5/4ugRfaIn0jfG/D5eXu2DtGfmMbsNAvAcx6M0aRjY3gfvd4h/W7YDIfI4N9lfighnvJ8A4CgW6d9xAHlP5pw==}
peerDependencies: