Merge remote-tracking branch 'origin/next' into refactor-tree
commit
eff286d0e5
|
@ -33,7 +33,7 @@ const AutoComplete = defineComponent({
|
||||||
inheritAttrs: false,
|
inheritAttrs: false,
|
||||||
props: {
|
props: {
|
||||||
...autoCompleteProps,
|
...autoCompleteProps,
|
||||||
prefixCls: PropTypes.string.def('ant-select'),
|
prefixCls: PropTypes.string,
|
||||||
showSearch: PropTypes.looseBool,
|
showSearch: PropTypes.looseBool,
|
||||||
transitionName: PropTypes.string.def('slide-up'),
|
transitionName: PropTypes.string.def('slide-up'),
|
||||||
choiceTransitionName: PropTypes.string.def('zoom'),
|
choiceTransitionName: PropTypes.string.def('zoom'),
|
||||||
|
|
|
@ -318,14 +318,16 @@ const Form = defineComponent({
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
emit('submit', e);
|
emit('submit', e);
|
||||||
const res = validateFields();
|
if (props.model) {
|
||||||
res
|
const res = validateFields();
|
||||||
.then(values => {
|
res
|
||||||
emit('finish', values);
|
.then(values => {
|
||||||
})
|
emit('finish', values);
|
||||||
.catch(errors => {
|
})
|
||||||
handleFinishFailed(errors);
|
.catch(errors => {
|
||||||
});
|
handleFinishFailed(errors);
|
||||||
|
});
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
expose({
|
expose({
|
||||||
|
|
|
@ -107,6 +107,8 @@ function useForm(
|
||||||
validateInfos: validateInfos;
|
validateInfos: validateInfos;
|
||||||
resetFields: (newValues?: Props) => void;
|
resetFields: (newValues?: Props) => void;
|
||||||
validate: <T = any>(names?: namesType, option?: validateOptions) => Promise<T>;
|
validate: <T = any>(names?: namesType, option?: validateOptions) => Promise<T>;
|
||||||
|
|
||||||
|
/** This is an internal usage. Do not use in your prod */
|
||||||
validateField: (
|
validateField: (
|
||||||
name: string,
|
name: string,
|
||||||
value: any,
|
value: any,
|
||||||
|
@ -117,19 +119,33 @@ function useForm(
|
||||||
clearValidate: (names?: namesType) => void;
|
clearValidate: (names?: namesType) => void;
|
||||||
} {
|
} {
|
||||||
const initialModel = cloneDeep(unref(modelRef));
|
const initialModel = cloneDeep(unref(modelRef));
|
||||||
let validateInfos: validateInfos = {};
|
const validateInfos = reactive<validateInfos>({});
|
||||||
|
|
||||||
const rulesKeys = computed(() => {
|
const rulesKeys = computed(() => {
|
||||||
return Object.keys(unref(rulesRef));
|
return Object.keys(unref(rulesRef));
|
||||||
});
|
});
|
||||||
|
|
||||||
rulesKeys.value.forEach(key => {
|
watch(
|
||||||
validateInfos[key] = {
|
rulesKeys,
|
||||||
autoLink: false,
|
() => {
|
||||||
required: isRequired(unref(rulesRef)[key]),
|
const newValidateInfos = {};
|
||||||
};
|
rulesKeys.value.forEach(key => {
|
||||||
});
|
newValidateInfos[key] = validateInfos[key] || {
|
||||||
validateInfos = reactive(validateInfos);
|
autoLink: false,
|
||||||
|
required: isRequired(unref(rulesRef)[key]),
|
||||||
|
};
|
||||||
|
delete validateInfos[key];
|
||||||
|
});
|
||||||
|
for (const key in validateInfos) {
|
||||||
|
if (Object.prototype.hasOwnProperty.call(validateInfos, key)) {
|
||||||
|
delete validateInfos[key];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Object.assign(validateInfos, newValidateInfos);
|
||||||
|
},
|
||||||
|
{ immediate: true },
|
||||||
|
);
|
||||||
|
|
||||||
const resetFields = (newValues: Props) => {
|
const resetFields = (newValues: Props) => {
|
||||||
Object.assign(unref(modelRef), {
|
Object.assign(unref(modelRef), {
|
||||||
...cloneDeep(initialModel),
|
...cloneDeep(initialModel),
|
||||||
|
@ -249,6 +265,9 @@ function useForm(
|
||||||
},
|
},
|
||||||
!!option.validateFirst,
|
!!option.validateFirst,
|
||||||
);
|
);
|
||||||
|
if (!validateInfos[name]) {
|
||||||
|
return promise.catch((e: any) => e);
|
||||||
|
}
|
||||||
validateInfos[name].validateStatus = 'validating';
|
validateInfos[name].validateStatus = 'validating';
|
||||||
promise
|
promise
|
||||||
.catch((e: any) => e)
|
.catch((e: any) => e)
|
||||||
|
@ -325,7 +344,9 @@ function useForm(
|
||||||
validate(names, { trigger: 'change' });
|
validate(names, { trigger: 'change' });
|
||||||
oldModel = cloneDeep(model);
|
oldModel = cloneDeep(model);
|
||||||
};
|
};
|
||||||
|
|
||||||
const debounceOptions = options?.debounce;
|
const debounceOptions = options?.debounce;
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
modelRef,
|
modelRef,
|
||||||
debounceOptions && debounceOptions.wait
|
debounceOptions && debounceOptions.wait
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
// mixins for clearfix
|
// mixins for clearfix
|
||||||
// ------------------------
|
// ------------------------
|
||||||
.clearfix() {
|
.clearfix() {
|
||||||
zoom: 1;
|
|
||||||
&::before,
|
&::before,
|
||||||
&::after {
|
&::after {
|
||||||
display: table;
|
display: table;
|
||||||
|
|
|
@ -70,4 +70,35 @@ describe('Switch', () => {
|
||||||
});
|
});
|
||||||
expect(checked.value).toBe(1);
|
expect(checked.value).toBe(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('customize checked value and children should work', async () => {
|
||||||
|
resetWarned();
|
||||||
|
const checked = ref(1);
|
||||||
|
const onUpdate = val => (checked.value = val);
|
||||||
|
const wrapper = mount({
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<Switch
|
||||||
|
{...{ 'onUpdate:checked': onUpdate }}
|
||||||
|
checked={checked.value}
|
||||||
|
unCheckedValue={1}
|
||||||
|
checkedValue={2}
|
||||||
|
checkedChildren="on"
|
||||||
|
unCheckedChildren="off"
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
await asyncExpect(() => {
|
||||||
|
wrapper.find('button').trigger('click');
|
||||||
|
});
|
||||||
|
expect(checked.value).toBe(2);
|
||||||
|
expect(wrapper.find('.ant-switch-inner').text()).toBe('on');
|
||||||
|
|
||||||
|
await asyncExpect(() => {
|
||||||
|
wrapper.find('button').trigger('click');
|
||||||
|
});
|
||||||
|
expect(checked.value).toBe(1);
|
||||||
|
expect(wrapper.find('.ant-switch-inner').text()).toBe('off');
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -134,6 +134,7 @@ const Switch = defineComponent({
|
||||||
[`${prefixCls.value}-disabled`]: props.disabled,
|
[`${prefixCls.value}-disabled`]: props.disabled,
|
||||||
[prefixCls.value]: true,
|
[prefixCls.value]: true,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
return () => (
|
return () => (
|
||||||
<Wave insertExtraNode>
|
<Wave insertExtraNode>
|
||||||
<button
|
<button
|
||||||
|
@ -160,7 +161,7 @@ const Switch = defineComponent({
|
||||||
>
|
>
|
||||||
{props.loading ? <LoadingOutlined class={`${prefixCls.value}-loading-icon`} /> : null}
|
{props.loading ? <LoadingOutlined class={`${prefixCls.value}-loading-icon`} /> : null}
|
||||||
<span class={`${prefixCls.value}-inner`}>
|
<span class={`${prefixCls.value}-inner`}>
|
||||||
{checked.value
|
{checkedStatus.value
|
||||||
? getPropsSlot(slots, props, 'checkedChildren')
|
? getPropsSlot(slots, props, 'checkedChildren')
|
||||||
: getPropsSlot(slots, props, 'unCheckedChildren')}
|
: getPropsSlot(slots, props, 'unCheckedChildren')}
|
||||||
</span>
|
</span>
|
||||||
|
|
|
@ -115,6 +115,9 @@ const Mentions = {
|
||||||
const { measureText: prevMeasureText, measuring } = this.$data;
|
const { measureText: prevMeasureText, measuring } = this.$data;
|
||||||
const { prefix = '', validateSearch } = this.$props;
|
const { prefix = '', validateSearch } = this.$props;
|
||||||
const target = event.target;
|
const target = event.target;
|
||||||
|
if (target.composing) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
const selectionStartText = getBeforeSelectionText(target);
|
const selectionStartText = getBeforeSelectionText(target);
|
||||||
const { location: measureIndex, prefix: measurePrefix } = getLastMeasureIndex(
|
const { location: measureIndex, prefix: measurePrefix } = getLastMeasureIndex(
|
||||||
selectionStartText,
|
selectionStartText,
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
import warning, { noteOnce } from '../../vc-util/warning';
|
import warning, { noteOnce } from '../../vc-util/warning';
|
||||||
import type { SelectProps } from '..';
|
import type { SelectProps } from '..';
|
||||||
import { convertChildrenToData } from './legacyUtil';
|
import { convertChildrenToData } from './legacyUtil';
|
||||||
import type { OptionData } from '../interface';
|
|
||||||
import { toArray } from './commonUtil';
|
import { toArray } from './commonUtil';
|
||||||
import type { RawValueType, LabelValueType } from '../interface/generator';
|
import type { RawValueType, LabelValueType } from '../interface/generator';
|
||||||
import { isValidElement } from '../../_util/props-util';
|
import { isValidElement } from '../../_util/props-util';
|
||||||
|
@ -36,23 +35,6 @@ function warningProps(props: SelectProps) {
|
||||||
'Please avoid setting option to disabled in tags mode since user can always type text as tag.',
|
'Please avoid setting option to disabled in tags mode since user can always type text as tag.',
|
||||||
);
|
);
|
||||||
|
|
||||||
// `combobox` & `tags` should option be `string` type
|
|
||||||
if (mode === 'tags' || mode === 'combobox') {
|
|
||||||
const hasNumberValue = mergedOptions.some(item => {
|
|
||||||
if (item.options) {
|
|
||||||
return item.options.some(
|
|
||||||
(opt: OptionData) => typeof ('value' in opt ? opt.value : opt.key) === 'number',
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return typeof ('value' in item ? item.value : item.key) === 'number';
|
|
||||||
});
|
|
||||||
|
|
||||||
warning(
|
|
||||||
!hasNumberValue,
|
|
||||||
'`value` of Option should not use number type when `mode` is `tags` or `combobox`.',
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// `combobox` should not use `optionLabelProp`
|
// `combobox` should not use `optionLabelProp`
|
||||||
warning(
|
warning(
|
||||||
mode !== 'combobox' || !optionLabelProp,
|
mode !== 'combobox' || !optionLabelProp,
|
||||||
|
|
|
@ -196,7 +196,7 @@
|
||||||
"webpack": "^5.0.0",
|
"webpack": "^5.0.0",
|
||||||
"webpack-bundle-analyzer": "^4.0.0",
|
"webpack-bundle-analyzer": "^4.0.0",
|
||||||
"webpack-cli": "^4.6.0",
|
"webpack-cli": "^4.6.0",
|
||||||
"webpack-dev-server": "^3.1.14",
|
"webpack-dev-server": "^4.0.0",
|
||||||
"webpack-merge": "^5.0.0",
|
"webpack-merge": "^5.0.0",
|
||||||
"webpackbar": "^5.0.0-3",
|
"webpackbar": "^5.0.0-3",
|
||||||
"xhr-mock": "^2.5.1"
|
"xhr-mock": "^2.5.1"
|
||||||
|
|
|
@ -130,7 +130,6 @@ module.exports = {
|
||||||
historyApiFallback: {
|
historyApiFallback: {
|
||||||
rewrites: [{ from: /./, to: '/index.html' }],
|
rewrites: [{ from: /./, to: '/index.html' }],
|
||||||
},
|
},
|
||||||
disableHostCheck: true,
|
|
||||||
hot: true,
|
hot: true,
|
||||||
open: true,
|
open: true,
|
||||||
},
|
},
|
||||||
|
|
Loading…
Reference in New Issue