diff --git a/components/_util/type.ts b/components/_util/type.ts index 4059fa18c..ec6b1aeec 100644 --- a/components/_util/type.ts +++ b/components/_util/type.ts @@ -1,4 +1,4 @@ -import { PropType } from 'vue'; +import { PropType, VNodeChild } from 'vue'; export type Omit = Pick>; // https://stackoverflow.com/questions/46176165/ways-to-get-string-literal-type-of-array-values-without-enum-overhead @@ -29,3 +29,5 @@ export interface PropOptions { default?: D | DefaultFactory | null | undefined | object; validator?(value: unknown): boolean; } + +export type VueNode = VNodeChild | JSX.Element; diff --git a/components/affix/style/index.js b/components/affix/style/index.ts similarity index 100% rename from components/affix/style/index.js rename to components/affix/style/index.ts diff --git a/components/alert/style/index.js b/components/alert/style/index.ts similarity index 100% rename from components/alert/style/index.js rename to components/alert/style/index.ts diff --git a/components/anchor/style/index.js b/components/anchor/style/index.ts similarity index 100% rename from components/anchor/style/index.js rename to components/anchor/style/index.ts diff --git a/components/auto-complete/style/index.js b/components/auto-complete/style/index.ts similarity index 100% rename from components/auto-complete/style/index.js rename to components/auto-complete/style/index.ts diff --git a/components/avatar/Avatar.jsx b/components/avatar/Avatar.tsx similarity index 75% rename from components/avatar/Avatar.jsx rename to components/avatar/Avatar.tsx index 14c4ffc5a..200c328e3 100644 --- a/components/avatar/Avatar.jsx +++ b/components/avatar/Avatar.tsx @@ -1,31 +1,28 @@ -import { inject } from 'vue'; +import { tuple, VueNode } from '../_util/type'; +import { CSSProperties, defineComponent, inject, PropType } from 'vue'; import { defaultConfigProvider } from '../config-provider'; import { getComponent } from '../_util/props-util'; import PropTypes from '../_util/vue-types'; -export default { +export default defineComponent({ name: 'AAvatar', props: { - prefixCls: { - type: String, - default: undefined, - }, - shape: { - validator: val => ['circle', 'square'].includes(val), - default: 'circle', - }, + prefixCls: PropTypes.string, + shape: PropTypes.oneOf(tuple('circle', 'square')), size: { - validator: val => { - return typeof val === 'number' || ['small', 'large', 'default'].includes(val); - }, - default: 'default', + type: [Number, String] as PropType<'large' | 'small' | 'default' | number>, + default: 'default' }, - src: String, + src: PropTypes.string, /** Srcset of image avatar */ - srcSet: String, - icon: PropTypes.any, - alt: String, - loadError: Function, + srcset: PropTypes.string, + /** @deprecated please use `srcset` instead `srcSet` */ + srcSet: PropTypes.string, + icon: PropTypes.VNodeChild, + alt: PropTypes.string, + loadError: { + type: Function as PropType<()=>boolean> + }, }, setup() { return { @@ -37,6 +34,8 @@ export default { isImgExist: true, isMounted: false, scale: 1, + lastChildrenWidth: undefined, + lastNodeWidth: undefined }; }, watch: { @@ -65,8 +64,8 @@ export default { if (!this.$refs.avatarChildren || !this.$refs.avatarNode) { return; } - const childrenWidth = this.$refs.avatarChildren.offsetWidth; // offsetWidth avoid affecting be transform scale - const nodeWidth = this.$refs.avatarNode.offsetWidth; + const childrenWidth = (this.$refs.avatarChildren as HTMLElement).offsetWidth; // offsetWidth avoid affecting be transform scale + const nodeWidth = (this.$refs.avatarNode as HTMLElement).offsetWidth; // denominator is 0 is no meaning if ( childrenWidth === 0 || @@ -89,7 +88,7 @@ export default { }, }, render() { - const { prefixCls: customizePrefixCls, shape, size, src, alt, srcSet } = this.$props; + const { prefixCls: customizePrefixCls, shape, size, src, alt, srcset, srcSet } = this.$props; const icon = getComponent(this, 'icon'); const getPrefixCls = this.configProvider.getPrefixCls; const prefixCls = getPrefixCls('avatar', customizePrefixCls); @@ -109,7 +108,7 @@ export default { [`${prefixCls}-icon`]: icon, }; - const sizeStyle = + const sizeStyle: CSSProperties = typeof size === 'number' ? { width: `${size}px`, @@ -119,16 +118,16 @@ export default { } : {}; - let children = this.$slots.default && this.$slots.default(); + let children: VueNode = this.$slots.default && this.$slots.default(); if (src && isImgExist) { - children = {alt}; + children = {alt}; } else if (icon) { children = icon; } else { const childrenNode = this.$refs.avatarChildren; if (childrenNode || scale !== 1) { const transformString = `scale(${scale}) translateX(-50%)`; - const childrenStyle = { + const childrenStyle: CSSProperties = { msTransform: transformString, WebkitTransform: transformString, transform: transformString, @@ -149,7 +148,7 @@ export default { ); } else { - const childrenStyle = {}; + const childrenStyle: CSSProperties = {}; if (!isMounted) { childrenStyle.opacity = 0; } @@ -166,4 +165,4 @@ export default { ); }, -}; +}); diff --git a/components/avatar/index.js b/components/avatar/index.ts similarity index 65% rename from components/avatar/index.js rename to components/avatar/index.ts index 72d914710..356239782 100644 --- a/components/avatar/index.js +++ b/components/avatar/index.ts @@ -1,7 +1,8 @@ +import { App } from 'vue'; import Avatar from './Avatar'; /* istanbul ignore next */ -Avatar.install = function(app) { +Avatar.install = function(app: App) { app.component(Avatar.name, Avatar); }; diff --git a/components/avatar/style/index.js b/components/avatar/style/index.ts similarity index 100% rename from components/avatar/style/index.js rename to components/avatar/style/index.ts diff --git a/components/back-top/backTopTypes.js b/components/back-top/backTopTypes.ts similarity index 100% rename from components/back-top/backTopTypes.js rename to components/back-top/backTopTypes.ts diff --git a/components/back-top/index.jsx b/components/back-top/index.tsx similarity index 94% rename from components/back-top/index.jsx rename to components/back-top/index.tsx index 487e9af46..7453f914f 100644 --- a/components/back-top/index.jsx +++ b/components/back-top/index.tsx @@ -1,4 +1,4 @@ -import { inject, Transition } from 'vue'; +import { App, defineComponent, inject, Transition } from 'vue'; import classNames from '../_util/classNames'; import PropTypes from '../_util/vue-types'; import backTopTypes from './backTopTypes'; @@ -15,7 +15,7 @@ function getDefaultTarget() { const props = backTopTypes(); -const BackTop = { +const BackTop = defineComponent({ name: 'ABackTop', inheritAttrs: false, mixins: [BaseMixin], @@ -29,9 +29,9 @@ const BackTop = { }; }, data() { - this.scrollEvent = null; return { visible: false, + scrollEvent: null, }; }, mounted() { @@ -97,10 +97,10 @@ const BackTop = { const transitionProps = getTransitionProps('fade'); return {backTopBtn}; }, -}; +}); /* istanbul ignore next */ -BackTop.install = function(app) { +BackTop.install = function(app: App) { app.component(BackTop.name, BackTop); }; diff --git a/components/badge/Badge.jsx b/components/badge/Badge.tsx similarity index 90% rename from components/badge/Badge.jsx rename to components/badge/Badge.tsx index cfd218b98..d81e1c653 100644 --- a/components/badge/Badge.jsx +++ b/components/badge/Badge.tsx @@ -7,11 +7,12 @@ import { cloneElement } from '../_util/vnode'; import getTransitionProps from '../_util/getTransitionProps'; import isNumeric from '../_util/isNumeric'; import { defaultConfigProvider } from '../config-provider'; -import { inject, Transition } from 'vue'; +import { inject, Transition, defineComponent, CSSProperties } from 'vue'; +import { tuple } from '../_util/type'; const BadgeProps = { /** Number to show in badge */ - count: PropTypes.any, + count: PropTypes.VNodeChild, showZero: PropTypes.looseBool, /** Max count to show */ overflowCount: PropTypes.number, @@ -19,26 +20,27 @@ const BadgeProps = { dot: PropTypes.looseBool, prefixCls: PropTypes.string, scrollNumberPrefixCls: PropTypes.string, - status: PropTypes.oneOf(['success', 'processing', 'default', 'error', 'warning']), + status: PropTypes.oneOf(tuple('success', 'processing', 'default', 'error', 'warning')), color: PropTypes.string, - text: PropTypes.any, - offset: PropTypes.array, - numberStyle: PropTypes.object.def(() => ({})), + text: PropTypes.VNodeChild, + offset: PropTypes.arrayOf(PropTypes.oneOfType([String, Number])), + numberStyle: PropTypes.style, title: PropTypes.string, }; -function isPresetColor(color) { - return PresetColorTypes.indexOf(color) !== -1; +function isPresetColor(color?: string): boolean { + return (PresetColorTypes as any[]).indexOf(color) !== -1; } -export default { +export default defineComponent({ name: 'ABadge', props: initDefaultProps(BadgeProps, { showZero: false, dot: false, overflowCount: 99, - }), + }) as typeof BadgeProps, setup() { return { configProvider: inject('configProvider', defaultConfigProvider), + badgeCount: undefined }; }, methods: { @@ -71,7 +73,7 @@ export default { const { offset, numberStyle } = this.$props; return offset ? { - right: `${-parseInt(offset[0], 10)}px`, + right: `${-parseInt(offset[0] as string, 10)}px`, marginTop: isNumeric(offset[1]) ? `${offset[1]}px` : offset[1], ...numberStyle, } @@ -156,7 +158,7 @@ export default { ); }, -}; +}); diff --git a/components/badge/ScrollNumber.jsx b/components/badge/ScrollNumber.tsx similarity index 94% rename from components/badge/ScrollNumber.jsx rename to components/badge/ScrollNumber.tsx index 675ce6028..3e5d945be 100644 --- a/components/badge/ScrollNumber.jsx +++ b/components/badge/ScrollNumber.tsx @@ -4,7 +4,7 @@ import BaseMixin from '../_util/BaseMixin'; import omit from 'omit.js'; import { cloneElement } from '../_util/vnode'; import { defaultConfigProvider } from '../config-provider'; -import { inject } from 'vue'; +import { CSSProperties, defineComponent, inject } from 'vue'; function getNumberArray(num) { return num @@ -28,7 +28,7 @@ const ScrollNumberProps = { onAnimated: PropTypes.func, }; -export default { +export default defineComponent({ name: 'ScrollNumber', mixins: [BaseMixin], inheritAttrs: false, @@ -36,10 +36,11 @@ export default { setup() { return { configProvider: inject('configProvider', defaultConfigProvider), + lastCount: undefined, + timeout: undefined, }; }, data() { - this.lastCount = undefined; return { animateStarted: true, sCount: this.count, @@ -159,10 +160,10 @@ export default { }, render() { - const { prefixCls: customizePrefixCls, title, component: Tag = 'sup', displayComponent } = this; + const { prefixCls: customizePrefixCls, title, component: Tag = 'sup' as any, displayComponent } = this; const getPrefixCls = this.configProvider.getPrefixCls; const prefixCls = getPrefixCls('scroll-number', customizePrefixCls); - const { class: className, style = {} } = this.$attrs; + const { class: className, style = {} } = this.$attrs as {class?: string, style?: CSSProperties}; if (displayComponent) { return cloneElement(displayComponent, { class: classNames( @@ -195,4 +196,4 @@ export default { return {this.renderNumberElement(prefixCls)}; }, -}; +}); diff --git a/components/badge/index.js b/components/badge/index.ts similarity index 65% rename from components/badge/index.js rename to components/badge/index.ts index 536522bcd..487616115 100644 --- a/components/badge/index.js +++ b/components/badge/index.ts @@ -1,7 +1,8 @@ +import { App } from 'vue'; import Badge from './Badge'; /* istanbul ignore next */ -Badge.install = function(app) { +Badge.install = function(app: App) { app.component(Badge.name, Badge); }; diff --git a/components/index.js b/components/index.ts similarity index 97% rename from components/index.js rename to components/index.ts index 5d9c73dc4..b719cc047 100644 --- a/components/index.js +++ b/components/index.ts @@ -14,6 +14,7 @@ if ( ); } /* @remove-on-es-build-end */ +import { App } from 'vue'; import { default as Affix } from './affix'; @@ -210,9 +211,9 @@ const components = [ Space, ]; -const install = function(app) { - components.map(component => { - app.use(component); +const install = function(app: App) { + components.forEach(component => { + app.use(component as { install: () => any }); }); app.config.globalProperties.$message = message; diff --git a/components/style.js b/components/style.ts similarity index 100% rename from components/style.js rename to components/style.ts diff --git a/examples/index.js b/examples/index.js index ed2e2c975..2eac35440 100644 --- a/examples/index.js +++ b/examples/index.js @@ -1,8 +1,8 @@ import '@babel/polyfill'; -import 'ant-design-vue/style.js'; +import 'ant-design-vue/style'; import { createApp, version } from 'vue'; import App from './App.vue'; -import antd from 'ant-design-vue/index.js'; +import antd from 'ant-design-vue/index.ts'; // eslint-disable-next-line no-console console.log('Vue version: ', version);