From 41a37f238c79ad22daceed41e7f220ff228d92fb Mon Sep 17 00:00:00 2001 From: tanjinzhou <415800467@qq.com> Date: Thu, 16 Apr 2020 16:44:54 +0800 Subject: [PATCH 01/13] fix: slider style error #2097 close #2097 --- components/slider/style/index.less | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/slider/style/index.less b/components/slider/style/index.less index c9f3bc918..53721ab54 100644 --- a/components/slider/style/index.less +++ b/components/slider/style/index.less @@ -160,7 +160,7 @@ } .@{slider-prefix-cls}-handle { - margin-bottom: -7px; + margin-top: -6px; margin-left: -5px; } From 1112f2f791fd64866284ec82def90baefe81e798 Mon Sep 17 00:00:00 2001 From: tanjinzhou <415800467@qq.com> Date: Fri, 17 Apr 2020 17:26:32 +0800 Subject: [PATCH 02/13] feat: date-picker support align --- components/date-picker/interface.js | 1 + 1 file changed, 1 insertion(+) diff --git a/components/date-picker/interface.js b/components/date-picker/interface.js index 15ed8fc08..1412cde46 100644 --- a/components/date-picker/interface.js +++ b/components/date-picker/interface.js @@ -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 = () => ({ From 32f669bd4854d926f30a2c788142ccfc042ad56b Mon Sep 17 00:00:00 2001 From: cubemoon Date: Fri, 17 Apr 2020 18:27:51 +0800 Subject: [PATCH 03/13] fix: treeNode customTitle cannot get selected prop MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Tree组件中,treeNode配置scopedSlots: {title: 'customeTitle' },无法获取title插槽的slot-scope值 需要定制tree的title时,具体的值在treeNode的数据上,但现在无法获取title处的插槽参数。经过查看ant-design-vue源码,发现TreeNode.jsx文件在title处配置错误,希望能尽快修复 * Update TreeNode.jsx --- components/vc-tree/src/TreeNode.jsx | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/components/vc-tree/src/TreeNode.jsx b/components/vc-tree/src/TreeNode.jsx index 112ebd763..7b679a509 100644 --- a/components/vc-tree/src/TreeNode.jsx +++ b/components/vc-tree/src/TreeNode.jsx @@ -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 @@ -439,9 +439,15 @@ const TreeNode = { $icon = this.renderIcon(); } - // Title - const $title = {title}; - + const currentTitle = title; + let $title = currentTitle ? ( + + {typeof currentTitle === 'function' ? currentTitle({ ...this.$props }, h) : currentTitle} + + ) : ( + {defaultTitle} + ); + return ( Date: Fri, 17 Apr 2020 18:29:44 +0800 Subject: [PATCH 04/13] fix: treeNode customTitle cannot get selected state #2006 --- components/tree/Tree.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/tree/Tree.jsx b/components/tree/Tree.jsx index 05623c5b9..60f833955 100644 --- a/components/tree/Tree.jsx +++ b/components/tree/Tree.jsx @@ -167,7 +167,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, From 3995f25484c06ae83c3ccc7ae6899707eebfb0a4 Mon Sep 17 00:00:00 2001 From: tangjinzhou <415800467@qq.com> Date: Sat, 18 Apr 2020 13:53:46 +0800 Subject: [PATCH 05/13] fix: select-tree throw error when showSearch #2082 --- components/vc-tree-select/src/Select.jsx | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/components/vc-tree-select/src/Select.jsx b/components/vc-tree-select/src/Select.jsx index 81e770043..767927943 100644 --- a/components/vc-tree-select/src/Select.jsx +++ b/components/vc-tree-select/src/Select.jsx @@ -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,15 +823,16 @@ 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. if (open && !multiple && !treeCheckable && _searchValue) { - this.setUncontrolledState({ - _searchValue: '', - _filteredTreeNodes: null, - }); + // 动画会有闪动,该特性先注释 + // this.setUncontrolledState({ + // _searchValue: '', + // _filteredTreeNodes: null, + // }); } this.setOpenState(open, true); }, From 7f1072aa3dcd3ee43cad79fc43d13d918f5b7cbd Mon Sep 17 00:00:00 2001 From: tanjinzhou <415800467@qq.com> Date: Tue, 21 Apr 2020 16:10:37 +0800 Subject: [PATCH 06/13] test: update table --- .../table/__tests__/Table.filter.test.js | 71 ++++++++++--------- 1 file changed, 39 insertions(+), 32 deletions(-) diff --git a/components/table/__tests__/Table.filter.test.js b/components/table/__tests__/Table.filter.test.js index e8e597ec6..d1bcb9b5c 100644 --- a/components/table/__tests__/Table.filter.test.js +++ b/components/table/__tests__/Table.filter.test.js @@ -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(); + }); }); From f9b233f39d7dd97c7e0289f1b7dae3e29d3a5fc7 Mon Sep 17 00:00:00 2001 From: tanjinzhou <415800467@qq.com> Date: Tue, 21 Apr 2020 16:11:43 +0800 Subject: [PATCH 07/13] fix: treeNode cannot get origin column --- components/vc-tree/src/TreeNode.jsx | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/components/vc-tree/src/TreeNode.jsx b/components/vc-tree/src/TreeNode.jsx index 7b679a509..ff6b65551 100644 --- a/components/vc-tree/src/TreeNode.jsx +++ b/components/vc-tree/src/TreeNode.jsx @@ -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} ); @@ -358,7 +358,7 @@ const TreeNode = { return ( {typeof switcherIcon === 'function' - ? switcherIcon({ ...this.$props, isLeaf: false }) + ? switcherIcon({ ...this.$props, ...this.$props.dataRef, isLeaf: false }) : switcherIcon} ); @@ -430,7 +430,9 @@ const TreeNode = { const currentIcon = icon || treeIcon; $icon = currentIcon ? ( - {typeof currentIcon === 'function' ? currentIcon({ ...this.$props }, h) : currentIcon} + {typeof currentIcon === 'function' + ? currentIcon({ ...this.$props, ...this.$props.dataRef }, h) + : currentIcon} ) : ( this.renderIcon() @@ -442,12 +444,14 @@ const TreeNode = { const currentTitle = title; let $title = currentTitle ? ( - {typeof currentTitle === 'function' ? currentTitle({ ...this.$props }, h) : currentTitle} + {typeof currentTitle === 'function' + ? currentTitle({ ...this.$props, ...this.$props.dataRef }, h) + : currentTitle} ) : ( {defaultTitle} ); - + return ( Date: Tue, 21 Apr 2020 16:13:17 +0800 Subject: [PATCH 08/13] perf: trigger animation --- components/_util/ContainerRender.jsx | 15 ++++++++------- components/vc-select/DropdownMenu.jsx | 14 +++++++++----- components/vc-tree-select/src/Select.jsx | 9 ++++----- components/vc-trigger/Popup.jsx | 20 ++++++++++++-------- components/vc-trigger/Trigger.jsx | 3 ++- 5 files changed, 35 insertions(+), 26 deletions(-) diff --git a/components/_util/ContainerRender.jsx b/components/_util/ContainerRender.jsx index 342c47098..cef0a7c27 100644 --- a/components/_util/ContainerRender.jsx +++ b/components/_util/ContainerRender.jsx @@ -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); } } }, diff --git a/components/vc-select/DropdownMenu.jsx b/components/vc-select/DropdownMenu.jsx index ee68e56df..67b3f6bb3 100644 --- a/components/vc-select/DropdownMenu.jsx +++ b/components/vc-select/DropdownMenu.jsx @@ -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; diff --git a/components/vc-tree-select/src/Select.jsx b/components/vc-tree-select/src/Select.jsx index 767927943..69678c7d9 100644 --- a/components/vc-tree-select/src/Select.jsx +++ b/components/vc-tree-select/src/Select.jsx @@ -828,11 +828,10 @@ const Select = { // When set open success and single mode, // we will reset the input content. if (open && !multiple && !treeCheckable && _searchValue) { - // 动画会有闪动,该特性先注释 - // this.setUncontrolledState({ - // _searchValue: '', - // _filteredTreeNodes: null, - // }); + this.setUncontrolledState({ + _searchValue: '', + _filteredTreeNodes: null, + }); } this.setOpenState(open, true); }, diff --git a/components/vc-trigger/Popup.jsx b/components/vc-trigger/Popup.jsx index 22fb31823..d315b48d7 100644 --- a/components/vc-trigger/Popup.jsx +++ b/components/vc-trigger/Popup.jsx @@ -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(); } }); }, diff --git a/components/vc-trigger/Trigger.jsx b/components/vc-trigger/Trigger.jsx index 08b59a9ef..ed462eb7f 100644 --- a/components/vc-trigger/Trigger.jsx +++ b/components/vc-trigger/Trigger.jsx @@ -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(); }); }, From 39bf296b7ae494a0ae339573338e6e37997caa94 Mon Sep 17 00:00:00 2001 From: varHarrie Date: Wed, 22 Apr 2020 11:52:24 +0800 Subject: [PATCH 09/13] feat: form-model add validateMessages prop (#2130) close #2130 --- components/form-model/Form.jsx | 1 + components/form-model/FormItem.jsx | 3 +++ types/form-model/form.d.ts | 8 +++++++- 3 files changed, 11 insertions(+), 1 deletion(-) diff --git a/components/form-model/Form.jsx b/components/form-model/Form.jsx index 0be2b74be..de6fcdcdd 100755 --- a/components/form-model/Form.jsx +++ b/components/form-model/Form.jsx @@ -17,6 +17,7 @@ export const FormProps = { hideRequiredMark: PropTypes.bool, model: PropTypes.object, rules: PropTypes.object, + validateMessages: PropTypes.any, validateOnRuleChange: PropTypes.bool, }; diff --git a/components/form-model/FormItem.jsx b/components/form-model/FormItem.jsx index 9dfba0ff7..bbd1a6778 100644 --- a/components/form-model/FormItem.jsx +++ b/components/form-model/FormItem.jsx @@ -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) => { diff --git a/types/form-model/form.d.ts b/types/form-model/form.d.ts index f8654813e..6e13e810c 100644 --- a/types/form-model/form.d.ts +++ b/types/form-model/form.d.ts @@ -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 From 18ca95d0313643229eb2eac4988c02848cdcae41 Mon Sep 17 00:00:00 2001 From: Baran Date: Wed, 22 Apr 2020 14:57:36 +0800 Subject: [PATCH 10/13] feat: add createForm return ts type (#2116) --- types/form/form.d.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/types/form/form.d.ts b/types/form/form.d.ts index 9c98ab851..8967cde48 100644 --- a/types/form/form.d.ts +++ b/types/form/form.d.ts @@ -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 From c018b7ec0692f01355aa5a881b0a9e957da40f3d Mon Sep 17 00:00:00 2001 From: tanjinzhou <415800467@qq.com> Date: Thu, 23 Apr 2020 11:45:05 +0800 Subject: [PATCH 11/13] fix: badge dot status position not correct #2121 --- components/badge/Badge.jsx | 4 +++- components/badge/style/index.less | 4 ++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/components/badge/Badge.jsx b/components/badge/Badge.jsx index ad89d6340..8531e344b 100644 --- a/components/badge/Badge.jsx +++ b/components/badge/Badge.jsx @@ -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, }); }, diff --git a/components/badge/style/index.less b/components/badge/style/index.less index 4a1e2e0c9..896e2b014 100644 --- a/components/badge/style/index.less +++ b/components/badge/style/index.less @@ -114,6 +114,10 @@ } } + &-dot-status { + line-height: 1; + } + &-zoom-appear, &-zoom-enter { animation: antZoomBadgeIn 0.3s @ease-out-back; From dd830491704eecc5e6070ef2704b822bd0956449 Mon Sep 17 00:00:00 2001 From: tanjinzhou <415800467@qq.com> Date: Thu, 23 Apr 2020 15:38:51 +0800 Subject: [PATCH 12/13] chore: update workflows --- .github/workflows/test.yml | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 81a38caf3..8f53cdd1b 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -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 - From b55fa75b931e39ee5829772f51514c60a9c1653a Mon Sep 17 00:00:00 2001 From: tanjinzhou <415800467@qq.com> Date: Thu, 23 Apr 2020 15:40:17 +0800 Subject: [PATCH 13/13] feat: table add transformCellText for custom render cell #2109 --- components/config-provider/index.jsx | 10 +++++++++- components/table/Table.jsx | 15 +++++++++++++-- components/table/interface.js | 1 + components/vc-table/src/Table.jsx | 1 + components/vc-table/src/TableCell.jsx | 8 ++++++++ types/config-provider.d.ts | 1 + types/table/table.d.ts | 1 + 7 files changed, 34 insertions(+), 3 deletions(-) diff --git a/components/config-provider/index.jsx b/components/config-provider/index.jsx index 1083f40f9..5a591989d 100644 --- a/components/config-provider/index.jsx +++ b/components/config-provider/index.jsx @@ -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) { diff --git a/components/table/Table.jsx b/components/table/Table.jsx index 5fed3809a..21137ee0f 100755 --- a/components/table/Table.jsx +++ b/components/table/Table.jsx @@ -1164,6 +1164,7 @@ export default { dropdownPrefixCls, contextLocale, getPopupContainer: contextGetPopupContainer, + transformCellText, }) { const { showHeader, locale, getPopupContainer, ...restProps } = getOptionProps(this); const data = this.getCurrentPageData(); @@ -1220,6 +1221,7 @@ export default { expandIconColumnIndex, expandIconAsCell, emptyText: mergedLocale.emptyText, + transformCellText, }, on: getListeners(this), class: classString, @@ -1230,10 +1232,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 = { @@ -1263,6 +1273,7 @@ export default { dropdownPrefixCls, contextLocale: locale, getPopupContainer, + transformCellText, }) } /> diff --git a/components/table/interface.js b/components/table/interface.js index b8c3e0ea8..dc26d9fb4 100644 --- a/components/table/interface.js +++ b/components/table/interface.js @@ -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; diff --git a/components/vc-table/src/Table.jsx b/components/vc-table/src/Table.jsx index df0eba052..90dce9b5c 100644 --- a/components/vc-table/src/Table.jsx +++ b/components/vc-table/src/Table.jsx @@ -67,6 +67,7 @@ export default { expandRowByClick: PropTypes.bool, expandIcon: PropTypes.func, tableLayout: PropTypes.string, + transformCellText: PropTypes.func, }, { data: [], diff --git a/components/vc-table/src/TableCell.jsx b/components/vc-table/src/TableCell.jsx index 6dc5e5b47..b82dcf6ec 100644 --- a/components/vc-table/src/TableCell.jsx +++ b/components/vc-table/src/TableCell.jsx @@ -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 ? (