From 349a2e9c161b201e1ff019479b5bbb46fb160067 Mon Sep 17 00:00:00 2001 From: Evan <80675236+piskesocute@users.noreply.github.com> Date: Sun, 24 Nov 2024 11:46:48 +0800 Subject: [PATCH] feat(components): [transfer] add custom empty slot for transfer panels (#18929) * feat(components): [transfer] add custom empty slot for transfer panels * docs: [transfer] add description and example * test(components): add transfer component test * docs: add version tag * Update docs/en-US/component/transfer.md Co-authored-by: btea <2356281422@qq.com> --------- Co-authored-by: qiang Co-authored-by: btea <2356281422@qq.com> --- docs/en-US/component/transfer.md | 22 +++++++-- docs/examples/transfer/empty-content.vue | 33 +++++++++++++ .../transfer/__tests__/transfer.test.tsx | 48 +++++++++++++++++++ .../transfer/src/transfer-panel.vue | 11 +++-- packages/components/transfer/src/transfer.vue | 6 +++ 5 files changed, 112 insertions(+), 8 deletions(-) create mode 100644 docs/examples/transfer/empty-content.vue diff --git a/docs/en-US/component/transfer.md b/docs/en-US/component/transfer.md index 4e2ea5f451..8996ca9925 100644 --- a/docs/en-US/component/transfer.md +++ b/docs/en-US/component/transfer.md @@ -33,6 +33,16 @@ transfer/customizable ::: +## Custom empty content ^(2.9.0) + +You can customize the content when the list is empty or when no filtering results are found. + +:::demo Use `left-empty` and `right-empty` slots to customize the empty content for each panel. + +transfer/empty-content + +::: + ## Prop aliases By default, Transfer looks for `key`, `label` and `disabled` in a data item. If your data items have different key names, you can use the `props` attribute to define aliases. @@ -74,11 +84,13 @@ transfer/prop-alias ### Transfer Slots -| Name | Description | -| ------------ | ------------------------------------------------------------------ | -| default | Custom content for data items. The scope parameter is `{ option }` | -| left-footer | content of left list footer | -| right-footer | content of right list footer | +| Name | Description | +| -------------------- | -------------------------------------------------------------------- | +| default | Custom content for data items. The scope parameter is `{ option }` | +| left-footer | content of left list footer | +| right-footer | content of right list footer | +| left-empty ^(2.9.0) | content when left panel is empty or when no data matches the filter | +| right-empty ^(2.9.0) | content when right panel is empty or when no data matches the filter | ### Transfer Exposes diff --git a/docs/examples/transfer/empty-content.vue b/docs/examples/transfer/empty-content.vue new file mode 100644 index 0000000000..d6f1ec5690 --- /dev/null +++ b/docs/examples/transfer/empty-content.vue @@ -0,0 +1,33 @@ + + + diff --git a/packages/components/transfer/__tests__/transfer.test.tsx b/packages/components/transfer/__tests__/transfer.test.tsx index 7dba8f802c..fc501de189 100644 --- a/packages/components/transfer/__tests__/transfer.test.tsx +++ b/packages/components/transfer/__tests__/transfer.test.tsx @@ -332,4 +332,52 @@ describe('Transfer', () => { `) }) }) + + describe('empty slots', () => { + it('render left-empty and right-empty slots', () => { + const wrapper = mount(() => ( + No data, + 'right-empty': () => No data, + }} + /> + )) + + const panels = wrapper.findAll('.el-transfer-panel__empty') + expect(panels).toHaveLength(2) + expect(panels[0].text()).toBe('No data') + expect(panels[1].text()).toBe('No data') + }) + + it('render default empty content when slots not provided', () => { + const wrapper = mount(() => ) + + const panels = wrapper.findAll('.el-transfer-panel__empty') + expect(panels).toHaveLength(2) + expect(panels[0].text()).toBe('No data') + expect(panels[1].text()).toBe('No data') + }) + + it('show no match content when filtering', async () => { + const wrapper = mount(() => ( + No data, + }} + /> + )) + + const leftPanel: any = wrapper.findComponent({ name: 'ElTransferPanel' }) + leftPanel.vm.query = 'non-existing-data' + await nextTick() + + const emptyContent = wrapper.find('.el-transfer-panel__empty') + expect(emptyContent.exists()).toBe(true) + expect(emptyContent.text()).toBe('No data') + }) + }) }) diff --git a/packages/components/transfer/src/transfer-panel.vue b/packages/components/transfer/src/transfer-panel.vue index 7d97a3db86..02754e1315 100644 --- a/packages/components/transfer/src/transfer-panel.vue +++ b/packages/components/transfer/src/transfer-panel.vue @@ -40,9 +40,14 @@ -

- {{ hasNoMatch ? t('el.transfer.noMatch') : t('el.transfer.noData') }} -

+
+ + {{ hasNoMatch ? t('el.transfer.noMatch') : t('el.transfer.noData') }} + +

diff --git a/packages/components/transfer/src/transfer.vue b/packages/components/transfer/src/transfer.vue index 41c1549450..2a1d6078da 100644 --- a/packages/components/transfer/src/transfer.vue +++ b/packages/components/transfer/src/transfer.vue @@ -13,6 +13,9 @@ :props="props.props" @checked-change="onSourceCheckedChange" > +

@@ -48,6 +51,9 @@ :props="props.props" @checked-change="onTargetCheckedChange" > +