diff --git a/components/_util/transButton.tsx b/components/_util/transButton.tsx index eca8c6991..66861efaf 100644 --- a/components/_util/transButton.tsx +++ b/components/_util/transButton.tsx @@ -5,7 +5,6 @@ import { defineComponent, ref, onMounted } from 'vue'; * This helps accessibility reader to tread as a interactive button to operation. */ import KeyCode from './KeyCode'; -import PropTypes from './vue-types'; const inlineStyle = { border: 0, diff --git a/components/components.ts b/components/components.ts index 74bd0da3e..020c5add2 100644 --- a/components/components.ts +++ b/components/components.ts @@ -105,7 +105,14 @@ export { default as List, ListItem, ListItemMeta } from './list'; export type { MessageArgsProps } from './message'; export { default as message } from './message'; -export type { MenuProps, MenuTheme, SubMenuProps, MenuItemProps, MenuMode } from './menu'; +export type { + MenuProps, + MenuTheme, + SubMenuProps, + MenuItemProps, + MenuMode, + MenuDividerProps, +} from './menu'; export { default as Menu, MenuDivider, MenuItem, MenuItemGroup, SubMenu } from './menu'; export type { MentionsProps } from './mentions'; diff --git a/components/input/ClearableLabeledInput.tsx b/components/input/ClearableLabeledInput.tsx index f880ead58..74cb8e536 100644 --- a/components/input/ClearableLabeledInput.tsx +++ b/components/input/ClearableLabeledInput.tsx @@ -21,7 +21,7 @@ export default defineComponent({ defaultValue: PropTypes.any, allowClear: { type: Boolean, default: undefined }, element: PropTypes.any, - handleReset: Function, + handleReset: Function as PropType, disabled: { type: Boolean, default: undefined }, direction: { type: String as PropType }, size: { type: String as PropType }, diff --git a/components/menu/index.tsx b/components/menu/index.tsx index 6987cc85d..a3d992e76 100644 --- a/components/menu/index.tsx +++ b/components/menu/index.tsx @@ -7,6 +7,7 @@ import SubMenu from './src/SubMenu'; import type { MenuItemGroupProps } from './src/ItemGroup'; import ItemGroup from './src/ItemGroup'; import Divider from './src/Divider'; +import type { MenuDividerProps } from './src/Divider'; import type { App, Plugin } from 'vue'; import type { MenuTheme, MenuMode } from './src/interface'; /* istanbul ignore next */ @@ -23,7 +24,15 @@ Menu.Item = MenuItem; Menu.Divider = Divider; Menu.SubMenu = SubMenu; Menu.ItemGroup = ItemGroup; -export type { MenuProps, SubMenuProps, MenuItemProps, MenuItemGroupProps, MenuTheme, MenuMode }; +export type { + MenuProps, + SubMenuProps, + MenuItemProps, + MenuItemGroupProps, + MenuTheme, + MenuMode, + MenuDividerProps, +}; export { SubMenu, MenuItem as Item, diff --git a/components/menu/src/Divider.tsx b/components/menu/src/Divider.tsx index 05ba5fedb..8bcedee8a 100644 --- a/components/menu/src/Divider.tsx +++ b/components/menu/src/Divider.tsx @@ -1,12 +1,17 @@ import useConfigInject from '../../_util/hooks/useConfigInject'; +import type { ExtractPropTypes } from 'vue'; import { computed, defineComponent } from 'vue'; +export const menuDividerProps = () => ({ + prefixCls: String, + dashed: Boolean, +}); + +export type MenuDividerProps = Partial>>; + export default defineComponent({ name: 'AMenuDivider', - props: { - prefixCls: String, - dashed: Boolean, - }, + props: menuDividerProps(), setup(props) { const { prefixCls } = useConfigInject('menu', props); const cls = computed(() => { diff --git a/components/menu/src/ItemGroup.tsx b/components/menu/src/ItemGroup.tsx index ba8d2d660..6ea5d7a33 100644 --- a/components/menu/src/ItemGroup.tsx +++ b/components/menu/src/ItemGroup.tsx @@ -5,16 +5,16 @@ import PropTypes from '../../_util/vue-types'; import { useInjectMenu } from './hooks/useMenuContext'; import { useMeasure } from './hooks/useKeyPath'; -export const menuItemGroupProps = { +export const menuItemGroupProps = () => ({ title: PropTypes.any, -}; +}); -export type MenuItemGroupProps = Partial>; +export type MenuItemGroupProps = Partial>>; export default defineComponent({ name: 'AMenuItemGroup', inheritAttrs: false, - props: menuItemGroupProps, + props: menuItemGroupProps(), slots: ['title'], setup(props, { slots, attrs }) { const { prefixCls } = useInjectMenu(); diff --git a/components/menu/src/Menu.tsx b/components/menu/src/Menu.tsx index c2b5060d7..d3980ee69 100644 --- a/components/menu/src/Menu.tsx +++ b/components/menu/src/Menu.tsx @@ -29,15 +29,15 @@ import { OVERFLOW_KEY, PathContext } from './hooks/useKeyPath'; import type { FocusEventHandler, MouseEventHandler } from '../../_util/EventInterface'; import collapseMotion from '../../_util/collapseMotion'; -export const menuProps = { +export const menuProps = () => ({ id: String, prefixCls: String, disabled: Boolean, inlineCollapsed: Boolean, disabledOverflow: Boolean, forceSubMenuRender: Boolean, - openKeys: Array, - selectedKeys: Array, + openKeys: Array as PropType, + selectedKeys: Array as PropType, activeKey: String, // 内部组件使用 selectable: { type: Boolean, default: true }, multiple: { type: Boolean, default: false }, @@ -68,15 +68,15 @@ export const menuProps = { 'onUpdate:openKeys': Function as PropType<(keys: Key[]) => void>, 'onUpdate:selectedKeys': Function as PropType<(keys: Key[]) => void>, 'onUpdate:activeKey': Function as PropType<(key: Key) => void>, -}; +}); -export type MenuProps = Partial>; +export type MenuProps = Partial>>; const EMPTY_LIST: string[] = []; export default defineComponent({ name: 'AMenu', inheritAttrs: false, - props: menuProps, + props: menuProps(), slots: ['expandIcon', 'overflowedIndicator'], setup(props, { slots, emit, attrs }) { const { prefixCls, direction, getPrefixCls } = useConfigInject('menu', props); diff --git a/components/menu/src/MenuItem.tsx b/components/menu/src/MenuItem.tsx index b68199bca..db9b41741 100644 --- a/components/menu/src/MenuItem.tsx +++ b/components/menu/src/MenuItem.tsx @@ -1,6 +1,6 @@ import { flattenChildren, getPropsSlot, isValidElement } from '../../_util/props-util'; import PropTypes from '../../_util/vue-types'; -import type { ExtractPropTypes } from 'vue'; +import type { ExtractPropTypes, PropType } from 'vue'; import { computed, defineComponent, getCurrentInstance, onBeforeUnmount, ref, watch } from 'vue'; import { useInjectKeyPath, useMeasure } from './hooks/useKeyPath'; import { useInjectFirstLevel, useInjectMenu } from './hooks/useMenuContext'; @@ -11,24 +11,30 @@ import KeyCode from '../../_util/KeyCode'; import useDirectionStyle from './hooks/useDirectionStyle'; import Overflow from '../../vc-overflow'; import devWarning from '../../vc-util/devWarning'; +import type { MouseEventHandler } from '../../_util/EventInterface'; let indexGuid = 0; -export const menuItemProps = { +export const menuItemProps = () => ({ id: String, role: String, disabled: Boolean, danger: Boolean, title: { type: [String, Boolean], default: undefined }, icon: PropTypes.any, -}; + onMouseenter: Function as PropType, + onMouseleave: Function as PropType, + onClick: Function as PropType, + onKeydown: Function as PropType, + onFocus: Function as PropType, +}); -export type MenuItemProps = Partial>; +export type MenuItemProps = Partial>>; export default defineComponent({ name: 'AMenuItem', inheritAttrs: false, - props: menuItemProps, - emits: ['mouseenter', 'mouseleave', 'click', 'keydown', 'focus'], + props: menuItemProps(), + // emits: ['mouseenter', 'mouseleave', 'click', 'keydown', 'focus'], slots: ['icon', 'title'], setup(props, { slots, emit, attrs }) { const instance = getCurrentInstance(); diff --git a/components/menu/src/SubMenu.tsx b/components/menu/src/SubMenu.tsx index a8c2d5664..3eb4269f8 100644 --- a/components/menu/src/SubMenu.tsx +++ b/components/menu/src/SubMenu.tsx @@ -19,10 +19,12 @@ import { cloneElement } from '../../_util/vnode'; import Overflow from '../../vc-overflow'; import devWarning from '../../vc-util/devWarning'; import isValid from '../../_util/isValid'; +import type { MouseEventHandler } from '../../_util/EventInterface'; +import type { Key } from 'ant-design-vue/es/_util/type'; let indexGuid = 0; -export const subMenuProps = { +export const subMenuProps = () => ({ icon: PropTypes.any, title: PropTypes.any, disabled: Boolean, @@ -32,16 +34,19 @@ export const subMenuProps = { internalPopupClose: Boolean, eventKey: String, expandIcon: Function as PropType<(p?: { isOpen: boolean; [key: string]: any }) => any>, -}; + onMouseenter: Function as PropType, + onMouseleave: Function as PropType, + onTitleClick: Function as PropType<(e: MouseEvent, key: Key) => void>, +}); -export type SubMenuProps = Partial>; +export type SubMenuProps = Partial>>; export default defineComponent({ name: 'ASubMenu', inheritAttrs: false, - props: subMenuProps, + props: subMenuProps(), slots: ['icon', 'title', 'expandIcon'], - emits: ['titleClick', 'mouseenter', 'mouseleave'], + // emits: ['titleClick', 'mouseenter', 'mouseleave'], setup(props, { slots, attrs, emit }) { useProvideFirstLevel(false); const isMeasure = useMeasure(); diff --git a/components/page-header/index.tsx b/components/page-header/index.tsx index 8936ab304..86768b508 100644 --- a/components/page-header/index.tsx +++ b/components/page-header/index.tsx @@ -1,4 +1,4 @@ -import type { ExtractPropTypes } from 'vue'; +import type { ExtractPropTypes, PropType } from 'vue'; import { defineComponent, ref, computed } from 'vue'; import PropTypes from '../_util/vue-types'; import { filterEmpty, flattenChildren, isEmptyContent } from '../_util/props-util'; @@ -13,8 +13,9 @@ import useConfigInject from '../_util/hooks/useConfigInject'; import classNames from '../_util/classNames'; import ResizeObserver from '../vc-resize-observer'; import useDestroyed from '../_util/hooks/useDestroyed'; +import type { MouseEventHandler } from '../_util/EventInterface'; -export const pageHeaderProps = { +export const pageHeaderProps = () => ({ backIcon: PropTypes.any, prefixCls: String, title: PropTypes.any, @@ -25,15 +26,15 @@ export const pageHeaderProps = { extra: PropTypes.any, avatar: PropTypes.object, ghost: { type: Boolean, default: undefined }, - onBack: Function, -}; + onBack: Function as PropType, +}); -export type PageHeaderProps = Partial>; +export type PageHeaderProps = Partial>>; const PageHeader = defineComponent({ name: 'APageHeader', - props: pageHeaderProps, - emits: ['back'], + props: pageHeaderProps(), + // emits: ['back'], slots: ['backIcon', 'avatar', 'breadcrumb', 'title', 'subTitle', 'tags', 'extra', 'footer'], setup(props, { emit, slots }) { const { prefixCls, direction, pageHeader } = useConfigInject('page-header', props); diff --git a/components/pagination/Pagination.tsx b/components/pagination/Pagination.tsx index 6c544d99e..be101e9f0 100644 --- a/components/pagination/Pagination.tsx +++ b/components/pagination/Pagination.tsx @@ -78,7 +78,7 @@ export default defineComponent({ name: 'APagination', inheritAttrs: false, props: paginationProps(), - emits: ['change', 'showSizeChange', 'update:current', 'update:pageSize'], + // emits: ['change', 'showSizeChange', 'update:current', 'update:pageSize'], setup(props, { slots, attrs }) { const { prefixCls, configProvider, direction } = useConfigInject('pagination', props); const selectPrefixCls = computed(() => diff --git a/components/popconfirm/index.tsx b/components/popconfirm/index.tsx index a011a4be7..153641292 100644 --- a/components/popconfirm/index.tsx +++ b/components/popconfirm/index.tsx @@ -1,4 +1,4 @@ -import type { ExtractPropTypes, PropType } from 'vue'; +import type { ExtractPropTypes, HTMLAttributes, PropType } from 'vue'; import { computed, onMounted, ref, toRef, defineComponent } from 'vue'; import Tooltip from '../tooltip'; import abstractTooltipProps from '../tooltip/abstractTooltipProps'; @@ -35,8 +35,14 @@ export const popconfirmProps = () => ({ okText: PropTypes.any, cancelText: PropTypes.any, icon: PropTypes.any, - okButtonProps: PropTypes.object, - cancelButtonProps: PropTypes.object, + okButtonProps: { + type: Object as PropType, + default: undefined as ButtonProps & HTMLAttributes, + }, + cancelButtonProps: { + type: Object as PropType, + default: undefined as ButtonProps & HTMLAttributes, + }, showCancel: { type: Boolean, default: true }, onConfirm: Function as PropType<(e: MouseEvent) => void>, onCancel: Function as PropType<(e: MouseEvent) => void>, @@ -52,10 +58,9 @@ export interface PopconfirmLocale { const Popconfirm = defineComponent({ name: 'APopconfirm', props: initDefaultProps(popconfirmProps(), { - ...tooltipDefaultProps, + ...tooltipDefaultProps(), trigger: 'click', transitionName: 'zoom-big', - align: () => ({}), placement: 'top', mouseEnterDelay: 0.1, mouseLeaveDelay: 0.1, diff --git a/components/popover/index.tsx b/components/popover/index.tsx index 3e189de9b..3b4a8db93 100644 --- a/components/popover/index.tsx +++ b/components/popover/index.tsx @@ -21,7 +21,7 @@ export type PopoverProps = Partial ({ ...progressProps(), prefixCls: String, direction: { type: String as PropType, }, -}; +}); -export type LineProps = Partial>; +export type LineProps = Partial>>; /** * { @@ -69,7 +69,7 @@ export const handleGradient = (strokeColor: ProgressGradient, directionConfig: D export default defineComponent({ name: 'Line', - props: lineProps, + props: lineProps(), setup(props, { slots }) { const backgroundProps = computed(() => { const { strokeColor, direction } = props; diff --git a/components/progress/Steps.tsx b/components/progress/Steps.tsx index b4f676168..bd3346783 100644 --- a/components/progress/Steps.tsx +++ b/components/progress/Steps.tsx @@ -4,7 +4,7 @@ import type { VueNode } from '../_util/type'; import type { ProgressSize } from './props'; import { progressProps } from './props'; -export const stepsProps = { +export const stepsProps = () => ({ ...progressProps(), steps: Number, size: { @@ -12,12 +12,13 @@ export const stepsProps = { }, strokeColor: String, trailColor: String, -}; +}); export type StepsProps = Partial>; export default defineComponent({ - props: stepsProps, + name: 'Steps', + props: stepsProps(), setup(props, { slots }) { const current = computed(() => Math.round(props.steps * ((props.percent || 0) / 100))); const stepWidth = computed(() => (props.size === 'small' ? 2 : 14)); diff --git a/components/progress/props.ts b/components/progress/props.ts index 7d9f8a128..78e66a93b 100644 --- a/components/progress/props.ts +++ b/components/progress/props.ts @@ -26,9 +26,10 @@ export const progressProps = () => ({ status: PropTypes.oneOf(progressStatuses), showInfo: { type: Boolean, default: undefined }, strokeWidth: Number, - strokeLinecap: PropTypes.oneOf(tuple('butt', 'round', 'square')), + strokeLinecap: String as PropType<'butt' | 'square' | 'round'>, strokeColor: { type: [String, Object] as PropType, + default: undefined as string | ProgressGradient, }, trailColor: String, width: Number, @@ -37,7 +38,7 @@ export const progressProps = () => ({ default: (): SuccessProps => ({}), }, gapDegree: Number, - gapPosition: PropTypes.oneOf(tuple('top', 'bottom', 'left', 'right')), + gapPosition: String as PropType<'top' | 'bottom' | 'left' | 'right'>, size: PropTypes.oneOf(ProgressSize), steps: Number, /** @deprecated Use `success` instead */ diff --git a/components/radio/Group.tsx b/components/radio/Group.tsx index 9387b431d..59c901dce 100644 --- a/components/radio/Group.tsx +++ b/components/radio/Group.tsx @@ -5,16 +5,14 @@ import PropTypes from '../_util/vue-types'; import Radio from './Radio'; import useConfigInject from '../_util/hooks/useConfigInject'; import { tuple } from '../_util/type'; -import type { RadioChangeEvent } from './interface'; +import type { RadioChangeEvent, RadioGroupButtonStyle, RadioGroupOptionType } from './interface'; import { useInjectFormItemContext } from '../form/FormItemContext'; const RadioGroupSizeTypes = tuple('large', 'default', 'small'); export type RadioGroupSize = typeof RadioGroupSizeTypes[number]; -const RadioGroupOptionTypes = tuple('default', 'button'); - -export type RadioGroupOption = typeof RadioGroupOptionTypes[number]; +export type RadioGroupOption = RadioGroupOptionType; export type RadioGroupChildOption = { label?: any; @@ -22,7 +20,7 @@ export type RadioGroupChildOption = { disabled?: boolean; }; -export const radioGroupProps = { +export const radioGroupProps = () => ({ prefixCls: String, value: PropTypes.any, size: PropTypes.oneOf(RadioGroupSizeTypes).def('default'), @@ -31,17 +29,19 @@ export const radioGroupProps = { }, disabled: { type: Boolean, default: undefined }, name: String, - buttonStyle: PropTypes.string.def('outline'), + buttonStyle: { type: String as PropType, default: 'outline' }, id: String, - optionType: PropTypes.oneOf(RadioGroupOptionTypes).def('default'), -}; + optionType: { type: String as PropType, default: 'default' }, + onChange: Function as PropType<(e: RadioChangeEvent) => void>, + 'onUpdate:value': Function as PropType<(val: any) => void>, +}); -export type RadioGroupProps = Partial>; +export type RadioGroupProps = Partial>>; export default defineComponent({ name: 'ARadioGroup', - props: radioGroupProps, - emits: ['update:value', 'change'], + props: radioGroupProps(), + // emits: ['update:value', 'change'], setup(props, { slots, emit }) { const formItemContext = useInjectFormItemContext(); const { prefixCls, direction, size } = useConfigInject('radio', props); diff --git a/components/radio/Radio.tsx b/components/radio/Radio.tsx index 387a0246f..c8a8cae30 100644 --- a/components/radio/Radio.tsx +++ b/components/radio/Radio.tsx @@ -1,4 +1,4 @@ -import type { ExtractPropTypes } from 'vue'; +import type { ExtractPropTypes, PropType } from 'vue'; import { defineComponent, inject, ref } from 'vue'; import PropTypes from '../_util/vue-types'; import VcCheckbox from '../vc-checkbox/Checkbox'; @@ -6,8 +6,10 @@ import classNames from '../_util/classNames'; import useConfigInject from '../_util/hooks/useConfigInject'; import type { RadioChangeEvent, RadioGroupContext } from './interface'; import { useInjectFormItemContext } from '../form/FormItemContext'; +import omit from '../_util/omit'; +import type { FocusEventHandler, MouseEventHandler } from '../_util/EventInterface'; -export const radioProps = { +export const radioProps = () => ({ prefixCls: String, checked: { type: Boolean, default: undefined }, disabled: { type: Boolean, default: undefined }, @@ -16,18 +18,20 @@ export const radioProps = { name: String, id: String, autofocus: { type: Boolean, default: undefined }, - onChange: Function, - onFocus: Function, - onBlur: Function, - onClick: Function, -}; + onChange: Function as PropType<(event: RadioChangeEvent) => void>, + onFocus: Function as PropType, + onBlur: Function as PropType, + onClick: Function as PropType, + 'onUpdate:checked': Function as PropType<(checked: boolean) => void>, + 'onUpdate:value': Function as PropType<(checked: boolean) => void>, +}); -export type RadioProps = Partial>; +export type RadioProps = Partial>>; export default defineComponent({ name: 'ARadio', - props: radioProps, - emits: ['update:checked', 'update:value', 'change', 'blur', 'focus'], + props: radioProps(), + // emits: ['update:checked', 'update:value', 'change', 'blur', 'focus'], setup(props, { emit, expose, slots }) { const formItemContext = useInjectFormItemContext(); const vcCheckbox = ref(); @@ -66,7 +70,7 @@ export default defineComponent({ const rProps: RadioProps = { prefixCls: prefixCls.value, id, - ...restProps, + ...omit(restProps, ['onUpdate:checked', 'onUpdate:value']), }; if (radioGroup) { diff --git a/components/radio/RadioButton.tsx b/components/radio/RadioButton.tsx index e493a0d7f..e2c37d2c3 100644 --- a/components/radio/RadioButton.tsx +++ b/components/radio/RadioButton.tsx @@ -6,8 +6,8 @@ import type { RadioGroupContext } from './interface'; export default defineComponent({ name: 'ARadioButton', - props: radioProps, - setup(props: RadioProps, { slots }) { + props: radioProps(), + setup(props, { slots }) { const { prefixCls } = useConfigInject('radio-button', props); const radioGroupContext = inject('radioGroupContext', undefined); diff --git a/components/radio/demo/radioGroup-options.vue b/components/radio/demo/radioGroup-options.vue index 8b766d91d..55cf87de2 100644 --- a/components/radio/demo/radioGroup-options.vue +++ b/components/radio/demo/radioGroup-options.vue @@ -16,20 +16,14 @@ Render radios by configuring `options`.