diff --git a/components/mentions/index.jsx b/components/mentions/index.tsx
similarity index 75%
rename from components/mentions/index.jsx
rename to components/mentions/index.tsx
index c5af332fc..afab4c8f8 100644
--- a/components/mentions/index.jsx
+++ b/components/mentions/index.tsx
@@ -1,4 +1,4 @@
-import { inject } from 'vue';
+import { App, defineComponent, inject, PropType, VNodeTypes } from 'vue';
import classNames from '../_util/classNames';
import omit from 'omit.js';
import PropTypes from '../_util/vue-types';
@@ -8,14 +8,27 @@ import Spin from '../spin';
import BaseMixin from '../_util/BaseMixin';
import { defaultConfigProvider } from '../config-provider';
import { getOptionProps, getComponent, getSlot } from '../_util/props-util';
+import { RenderEmptyHandler } from '../config-provider/renderEmpty';
const { Option } = VcMentions;
+interface MentionsConfig {
+ prefix?: string | string[];
+ split?: string;
+}
+
+export interface OptionProps {
+ value: string;
+ disabled: boolean;
+ children: VNodeTypes;
+ [key: string]: any;
+}
+
function loadingFilterOption() {
return true;
}
-function getMentions(value = '', config) {
+function getMentions(value: string = '', config: MentionsConfig) {
const { prefix = '@', split = ' ' } = config || {};
const prefixList = Array.isArray(prefix) ? prefix : [prefix];
@@ -44,7 +57,7 @@ function getMentions(value = '', config) {
.filter(entity => !!entity && !!entity.value);
}
-const Mentions = {
+const Mentions = defineComponent({
name: 'AMentions',
mixins: [BaseMixin],
inheritAttrs: false,
@@ -53,12 +66,20 @@ const Mentions = {
props: {
...mentionsProps,
loading: PropTypes.looseBool,
- onFocus: PropTypes.func,
- onBlur: PropTypes.func,
- onSelect: PropTypes.func,
- onChange: PropTypes.func,
- 'onUpdate:value': PropTypes.func,
+ onFocus: {
+ type: Function as PropType<(e: FocusEvent) => void>,
+ },
+ onBlur: {
+ type: Function as PropType<(e: FocusEvent) => void>,
+ },
+ onSelect: {
+ type: Function as PropType<(option: OptionProps, prefix: string) => void>,
+ },
+ onChange: {
+ type: Function as PropType<(text: string) => void>,
+ },
},
+ emits: ['update:value', 'change', 'focus', 'blur', 'select'],
setup() {
return {
configProvider: inject('configProvider', defaultConfigProvider),
@@ -79,29 +100,29 @@ const Mentions = {
});
},
methods: {
- handleFocus(...args) {
- this.$emit('focus', ...args);
+ handleFocus(e: FocusEvent) {
+ this.$emit('focus', e);
this.setState({
focused: true,
});
},
- handleBlur(...args) {
- this.$emit('blur', ...args);
+ handleBlur(e: FocusEvent) {
+ this.$emit('blur', e);
this.setState({
focused: false,
});
},
- handleSelect(...args) {
+ handleSelect(...args: [OptionProps, string]) {
this.$emit('select', ...args);
this.setState({
focused: true,
});
},
- handleChange(val) {
+ handleChange(val: string) {
this.$emit('update:value', val);
this.$emit('change', val);
},
- getNotFoundContent(renderEmpty) {
+ getNotFoundContent(renderEmpty: RenderEmptyHandler) {
const notFoundContent = getComponent(this, 'notFoundContent');
if (notFoundContent !== undefined) {
return notFoundContent;
@@ -130,10 +151,10 @@ const Mentions = {
return filterOption;
},
focus() {
- this.$refs.vcMentions.focus();
+ (this.$refs.vcMentions as any).focus();
},
blur() {
- this.$refs.vcMentions.blur();
+ (this.$refs.vcMentions as any).blur();
},
},
render() {
@@ -144,7 +165,7 @@ const Mentions = {
disabled,
getPopupContainer,
...restProps
- } = getOptionProps(this);
+ } = getOptionProps(this) as any;
const { class: className, ...otherAttrs } = this.$attrs;
const prefixCls = getPrefixCls('mentions', customizePrefixCls);
const otherProps = omit(restProps, ['loading', 'onUpdate:value']);
@@ -174,10 +195,10 @@ const Mentions = {
return ;
},
-};
+});
/* istanbul ignore next */
-Mentions.install = function(app) {
+Mentions.install = function(app: App) {
app.component(Mentions.name, Mentions);
app.component(Mentions.Option.name, Mentions.Option);
return app;
diff --git a/components/mentions/style/index.js b/components/mentions/style/index.ts
similarity index 100%
rename from components/mentions/style/index.js
rename to components/mentions/style/index.ts
diff --git a/components/vc-mentions/src/mentionsProps.js b/components/vc-mentions/src/mentionsProps.ts
similarity index 68%
rename from components/vc-mentions/src/mentionsProps.js
rename to components/vc-mentions/src/mentionsProps.ts
index 8da68ca74..d2aacc16b 100644
--- a/components/vc-mentions/src/mentionsProps.js
+++ b/components/vc-mentions/src/mentionsProps.ts
@@ -1,5 +1,6 @@
+import { PropType } from 'vue';
import PropTypes from '../../_util/vue-types';
-import { initDefaultProps } from '../../_util/props-util';
+import initDefaultProps from '../../_util/props-util/initDefaultProps';
import {
filterOption as defaultFilterOption,
validateSearch as defaultValidateSearch,
@@ -13,15 +14,21 @@ export const mentionsProps = {
value: PropTypes.string,
defaultValue: PropTypes.string,
disabled: PropTypes.looseBool,
- notFoundContent: PropTypes.any,
+ notFoundContent: PropTypes.VNodeChild,
split: PropTypes.string,
transitionName: PropTypes.string,
placement: PropTypes.oneOf(PlaceMent),
character: PropTypes.any,
characterRender: PropTypes.func,
- filterOption: PropTypes.func,
- validateSearch: PropTypes.func,
- getPopupContainer: PropTypes.func,
+ filterOption: {
+ type: [Boolean, Function] as PropType,
+ },
+ validateSearch: {
+ type: Function as PropType,
+ },
+ getPopupContainer: {
+ type: Function as PropType<() => HTMLElement>,
+ },
};
export const vcMentionsProps = {
diff --git a/components/vc-mentions/src/placement.js b/components/vc-mentions/src/placement.js
index 772cbcf33..6ee6165b8 100644
--- a/components/vc-mentions/src/placement.js
+++ b/components/vc-mentions/src/placement.js
@@ -1 +1,3 @@
-export const PlaceMent = ['top', 'bottom'];
+import { tuple } from '../../_util/type';
+
+export const PlaceMent = tuple('top', 'bottom');