Merge remote-tracking branch 'origin/master' into 2.0

pull/2144/head
tanjinzhou 2020-04-23 15:45:01 +08:00
commit c4a72238c0
24 changed files with 150 additions and 76 deletions

View File

@ -7,7 +7,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: checkout
uses: actions/checkout@master
uses: actions/checkout@v2
- name: cache package-lock.json
uses: actions/cache@v1
@ -40,7 +40,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: checkout
uses: actions/checkout@master
uses: actions/checkout@v2
- name: restore cache from package-lock.json
uses: actions/cache@v1
@ -74,7 +74,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: checkout
uses: actions/checkout@master
uses: actions/checkout@v2
- name: restore cache from package-lock.json
uses: actions/cache@v1
@ -96,12 +96,12 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: checkout
uses: actions/checkout@master
uses: actions/checkout@v2
with:
token: ${{ secrets.ACCESS_TOKEN }}
- name: Checkout submodules
uses: actions/checkout@master
uses: actions/checkout@v2
with:
repository: tangjinzhou/antdv-demo
token: ${{ secrets.ACCESS_TOKEN }}
@ -122,4 +122,3 @@ jobs:
- name: test
run: npm test
needs: setup

View File

@ -42,7 +42,7 @@ export default {
renderComponent(props = {}, ready) {
const { visible, forceRender, getContainer, parent } = this;
const self = this;
if (visible || parent.$refs._component || forceRender) {
if (visible || parent._component || parent.$refs._component || forceRender) {
let el = this.componentEl;
if (!this.container) {
this.container = getContainer();
@ -50,12 +50,14 @@ export default {
this.componentEl = el;
this.container.appendChild(el);
}
// self.getComponent render render
const com = { component: self.getComponent(props) };
if (!this._component) {
this._component = new this.$root.constructor({
el,
parent: self,
data: {
comProps: props,
_com: com,
},
mounted() {
this.$nextTick(() => {
@ -72,17 +74,16 @@ export default {
});
},
methods: {
forceRender(p) {
this.comProps = p;
this.$forceUpdate();
setComponent(_com) {
this.$data._com = _com;
},
},
render() {
return self.getComponent(this.comProps);
return this.$data._com.component;
},
});
} else {
this._component.forceRender(props);
this._component.setComponent(com);
}
}
},

View File

@ -81,8 +81,10 @@ export default {
},
getBadgeClassName(prefixCls) {
const children = filterEmpty(this.$slots.default);
const hasStatus = this.hasStatus();
return classNames(prefixCls, {
[`${prefixCls}-status`]: this.hasStatus(),
[`${prefixCls}-status`]: hasStatus,
[`${prefixCls}-dot-status`]: hasStatus && this.dot && !this.isZero(),
[`${prefixCls}-not-a-wrapper`]: !children.length,
});
},

View File

@ -114,6 +114,10 @@
}
}
&-dot-status {
line-height: 1;
}
&-zoom-appear,
&-zoom-enter {
animation: antZoomBadgeIn 0.3s @ease-out-back;

View File

@ -26,6 +26,7 @@ const ConfigProvider = {
autoInsertSpaceInButton: PropTypes.bool,
locale: PropTypes.object,
pageHeader: PropTypes.object,
transformCellText: PropTypes.func,
},
provide() {
const _self = this;
@ -43,7 +44,14 @@ const ConfigProvider = {
};
},
watch: {
...getWatch(['prefixCls', 'csp', 'autoInsertSpaceInButton', 'locale', 'pageHeader']),
...getWatch([
'prefixCls',
'csp',
'autoInsertSpaceInButton',
'locale',
'pageHeader',
'transformCellText',
]),
},
methods: {
renderEmptyComponent(h, name) {

View File

@ -35,6 +35,7 @@ export const PickerProps = () => ({
autoFocus: PropTypes.bool,
tagPrefixCls: PropTypes.string,
tabIndex: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
align: PropTypes.object.def(() => ({})),
});
export const SinglePickerProps = () => ({

View File

@ -17,6 +17,7 @@ export const FormProps = {
hideRequiredMark: PropTypes.bool,
model: PropTypes.object,
rules: PropTypes.object,
validateMessages: PropTypes.any,
validateOnRuleChange: PropTypes.bool,
};

View File

@ -142,6 +142,9 @@ export default {
}
descriptor[this.prop] = rules;
const validator = new AsyncValidator(descriptor);
if (this.FormContext && this.FormContext.validateMessages) {
validator.messages(this.FormContext.validateMessages);
}
const model = {};
model[this.prop] = this.fieldValue;
validator.validate(model, { firstFields: true }, (errors, invalidFields) => {

View File

@ -160,7 +160,7 @@
}
.@{slider-prefix-cls}-handle {
margin-bottom: -7px;
margin-top: -6px;
margin-left: -5px;
}

View File

@ -1161,6 +1161,7 @@ export default {
dropdownPrefixCls,
contextLocale,
getPopupContainer: contextGetPopupContainer,
transformCellText,
}) {
const { showHeader, locale, getPopupContainer, ...restProps } = getOptionProps(this);
const data = this.getCurrentPageData();
@ -1217,6 +1218,7 @@ export default {
expandIconColumnIndex,
expandIconAsCell,
emptyText: mergedLocale.emptyText,
transformCellText,
},
on: getListeners(this),
class: classString,
@ -1227,10 +1229,18 @@ export default {
},
render() {
const { prefixCls: customizePrefixCls, dropdownPrefixCls: customizeDropdownPrefixCls } = this;
const {
prefixCls: customizePrefixCls,
dropdownPrefixCls: customizeDropdownPrefixCls,
transformCellText: customizeTransformCellText,
} = this;
const data = this.getCurrentPageData();
const { getPopupContainer: getContextPopupContainer } = this.configProvider;
const {
getPopupContainer: getContextPopupContainer,
transformCellText: tct,
} = this.configProvider;
const getPopupContainer = this.getPopupContainer || getContextPopupContainer;
const transformCellText = customizeTransformCellText || tct;
let loading = this.loading;
if (typeof loading === 'boolean') {
loading = {
@ -1260,6 +1270,7 @@ export default {
dropdownPrefixCls,
contextLocale: locale,
getPopupContainer,
transformCellText,
})
}
/>

View File

@ -11,7 +11,9 @@ describe('Table.filter', () => {
beforeEach(() => {
document.body.innerHTML = '';
});
const filterFn = (value, record) => record.name.indexOf(value) !== -1;
const filterFn = (value, record) => {
return record.name.indexOf(value) !== -1;
};
const column = {
title: 'Name',
dataIndex: 'name',
@ -49,6 +51,7 @@ describe('Table.filter', () => {
...listeners,
},
sync: false,
attachToDocument: true,
};
}
@ -309,24 +312,15 @@ describe('Table.filter', () => {
],
}),
);
// jest.useFakeTimers()
const dropdownWrapper = mount(
{
render() {
return wrapper.find({ name: 'Trigger' }).vm.getComponent();
},
},
{ sync: false, attachToDocument: true },
);
await asyncExpect(() => {
dropdownWrapper
.findAll('.ant-dropdown-menu-submenu-title')
.at(0)
.trigger('mouseenter');
$$('.ant-dropdown-trigger')[0].click();
});
await asyncExpect(() => {
$$('.ant-dropdown-menu-submenu-title')[0].dispatchEvent(new MouseEvent('mouseenter'));
}, 0);
await asyncExpect(() => {
$$('.ant-dropdown-menu-submenu-title')[1].dispatchEvent(new MouseEvent('mouseenter'));
}, 1000);
}, 500);
await asyncExpect(() => {
const menuItem = $$('.ant-dropdown-menu-item');
menuItem[menuItem.length - 1].click();
@ -439,22 +433,35 @@ describe('Table.filter', () => {
});
});
// it('confirm filter when dropdown hidden', (done) => {
// const handleChange = jest.fn()
// const wrapper = mount(Table, { ...getTableOptions({
// columns: [{
// ...column,
// filters: [
// { text: 'Jack', value: 'Jack' },
// { text: 'Lucy', value: 'Lucy' },
// ],
// }],
// }, { change: handleChange }), attachToDocument: true })
fit('confirm filter when dropdown hidden', async () => {
const handleChange = jest.fn();
const wrapper = mount(Table, {
...getTableOptions(
{
columns: [
{
...column,
filters: [
{ text: 'Jack', value: 'Jack' },
{ text: 'Lucy', value: 'Lucy' },
],
},
],
},
{ change: handleChange },
),
attachToDocument: true,
});
await asyncExpect(() => {
wrapper.find('.ant-dropdown-trigger').trigger('click');
}, 0);
await asyncExpect(() => {
$$('.ant-dropdown-menu-item')[0].click();
}, 500);
await asyncExpect(() => {
wrapper.find('.ant-dropdown-trigger').trigger('click');
}, 500);
// wrapper.find('.ant-dropdown-trigger').first().simulate('click')
// wrapper.find('.ant-dropdown-menu-item').first().simulate('click')
// wrapper.find('.ant-dropdown-trigger').first().simulate('click')
// expect(handleChange).toBeCalled()
// })
expect(handleChange).toBeCalled();
});
});

View File

@ -135,6 +135,7 @@ export const TableProps = {
tableLayout: PropTypes.string,
getPopupContainer: PropTypes.func,
expandIcon: PropTypes.func,
transformCellText: PropTypes.func,
// className?: PropTypes.string,
// style?: React.CSSProperties;
// children?: React.ReactNode;

View File

@ -169,7 +169,7 @@ export default {
$slots[slots.switcherIcon] ||
restProps.switcherIcon,
title:
($scopedSlots[scopedSlots.title] && $scopedSlots[scopedSlots.title](item)) ||
$scopedSlots[scopedSlots.title] ||
$slots[slots.title] ||
restProps[replaceFields.title],
dataRef: item,

View File

@ -32,6 +32,10 @@ export default {
visible(val) {
if (!val) {
this.lastVisible = val;
} else {
this.$nextTick(() => {
this.scrollActiveItemToView();
});
}
},
},
@ -50,11 +54,11 @@ export default {
},
updated() {
const props = this.$props;
if (!this.prevVisible && props.visible) {
this.$nextTick(() => {
this.scrollActiveItemToView();
});
}
// if (!this.prevVisible && props.visible) {
// this.$nextTick(() => {
// this.scrollActiveItemToView();
// });
// }
this.lastVisible = props.visible;
this.lastInputValue = props.inputValue;
this.prevVisible = this.visible;

View File

@ -67,6 +67,7 @@ export default {
expandRowByClick: PropTypes.bool,
expandIcon: PropTypes.func,
tableLayout: PropTypes.string,
transformCellText: PropTypes.func,
},
{
data: [],

View File

@ -21,6 +21,9 @@ export default {
expandIcon: PropTypes.any,
component: PropTypes.any,
},
inject: {
table: { default: () => ({}) },
},
methods: {
handleClick(e) {
const {
@ -45,6 +48,7 @@ export default {
component: BodyCell,
} = this;
const { dataIndex, customRender, className = '' } = column;
const { transformCellText } = this.table;
// We should return undefined if no dataIndex is specified, but in order to
// be compatible with object-path's behavior, we return the record object instead.
let text;
@ -87,6 +91,10 @@ export default {
text = null;
}
if (transformCellText) {
text = transformCellText({ text, column, record, index });
}
const indentText = expandIcon ? (
<span
style={{ paddingLeft: `${indentSize * indent}px` }}

View File

@ -224,14 +224,14 @@ const Select = {
this.forcePopupAlign();
});
},
'$data._open'() {
'$data._open'(open) {
this.$nextTick(() => {
const { prefixCls } = this.$props;
const { _selectorValueList: selectorValueList, _valueEntities: valueEntities } = this.$data;
const isMultiple = this.isMultiple();
// Scroll to value position, only need sync on single mode
if (!isMultiple && selectorValueList.length && this.popup) {
if (!isMultiple && selectorValueList.length && open && this.popup) {
const { value } = selectorValueList[0];
const { domTreeNodes } = this.popup.getTree();
const { key } = valueEntities[value] || {};
@ -823,7 +823,7 @@ const Select = {
onDropdownVisibleChange(open) {
const { multiple, treeCheckable } = this.$props;
const { _searchValue } = this;
const { _searchValue } = this.$data;
// When set open success and single mode,
// we will reset the input content.

View File

@ -345,7 +345,7 @@ const TreeNode = {
class={classNames(`${prefixCls}-switcher`, `${prefixCls}-switcher-noop`)}
>
{typeof switcherIcon === 'function'
? switcherIcon({ ...this.$props, isLeaf: true })
? switcherIcon({ ...this.$props, ...this.$props.dataRef, isLeaf: true })
: switcherIcon}
</span>
);
@ -358,7 +358,7 @@ const TreeNode = {
return (
<span key="switcher" onClick={this.onExpand} class={switcherCls}>
{typeof switcherIcon === 'function'
? switcherIcon({ ...this.$props, isLeaf: false })
? switcherIcon({ ...this.$props, ...this.$props.dataRef, isLeaf: false })
: switcherIcon}
</span>
);
@ -420,7 +420,7 @@ const TreeNode = {
vcTree: { prefixCls, showIcon, icon: treeIcon, draggable, loadData },
} = this;
const disabled = this.isDisabled();
const title = getComponentFromProp(this, 'title') || defaultTitle;
const title = getComponentFromProp(this, 'title', {}, false);
const wrapClass = `${prefixCls}-node-content-wrapper`;
// Icon - Still show loading icon when loading without showIcon
@ -430,7 +430,9 @@ const TreeNode = {
const currentIcon = icon || treeIcon;
$icon = currentIcon ? (
<span class={classNames(`${prefixCls}-iconEle`, `${prefixCls}-icon__customize`)}>
{typeof currentIcon === 'function' ? currentIcon({ ...this.$props }, h) : currentIcon}
{typeof currentIcon === 'function'
? currentIcon({ ...this.$props, ...this.$props.dataRef }, h)
: currentIcon}
</span>
) : (
this.renderIcon()
@ -439,8 +441,16 @@ const TreeNode = {
$icon = this.renderIcon();
}
// Title
const $title = <span class={`${prefixCls}-title`}>{title}</span>;
const currentTitle = title;
let $title = currentTitle ? (
<span class={`${prefixCls}-title`}>
{typeof currentTitle === 'function'
? currentTitle({ ...this.$props, ...this.$props.dataRef }, h)
: currentTitle}
</span>
) : (
<span class={`${prefixCls}-title`}>{defaultTitle}</span>
);
return (
<span

View File

@ -46,12 +46,14 @@ export default {
this.setStretchSize();
});
},
beforeUpdate() {
if (this.domEl && this.domEl.rcEndListener) {
this.domEl.rcEndListener();
this.domEl = null;
}
},
// https://github.com/vueComponent/ant-design-vue/issues/1327
// ()
// beforeUpdate() {
// if (this.domEl && this.domEl.rcEndListener) {
// this.domEl.rcEndListener();
// this.domEl = null;
// }
// },
updated() {
this.$nextTick(() => {
this.setStretchSize();
@ -207,10 +209,10 @@ export default {
style: { ...sizeStyle, ...popupStyle, ...this.getZIndexStyle() },
};
let transitionProps = {
props: Object.assign({
props: {
appear: true,
css: false,
}),
},
};
const transitionName = getTransitionName();
let useTransition = !!transitionName;
@ -227,6 +229,8 @@ export default {
this.domEl = el;
animate(el, `${transitionName}-enter`, done);
});
} else {
done();
}
});
},

View File

@ -128,9 +128,10 @@ export default {
if (this.sPopupVisible !== this.prevPopupVisible) {
this.afterPopupVisibleChange(this.sPopupVisible);
}
this.prevPopupVisible = this.sPopupVisible;
};
this.renderComponent(null, triggerAfterPopupVisibleChange);
this.$nextTick(() => {
this.renderComponent(null, triggerAfterPopupVisibleChange);
this.updatedCal();
});
},

View File

@ -13,4 +13,5 @@ export declare class ConfigProvider extends AntdComponent {
renderEmpty: Function;
csp?: CSPConfig;
autoInsertSpaceInButton?: boolean;
transformCellText?: Function;
}

View File

@ -132,8 +132,14 @@ export declare class FormModel extends AntdComponent {
* validation rules of form
* @type object
*/
rules: object;
/**
* Default validate message. And its format is similar with newMessages's returned value
* @type any
*/
validateMessages?: any;
/**
* whether to trigger validation when the rules prop is changed
* @type Boolean

View File

@ -389,7 +389,7 @@ export declare class Form extends AntdComponent {
*/
options: object;
createForm(context: Vue, options?: IformCreateOption): any;
createForm(context: Vue, options?: IformCreateOption): WrappedFormUtils;
/**
* Convert props to field value

View File

@ -300,4 +300,5 @@ export declare class Table extends AntdComponent {
style: object;
nativeOn: object;
};
transformCellText: Function;
}