feat(components): [table-column] add filter-icon slot (#17272)

* feat(components): [table] add `filter-icon` prop

* chore: remove

* chore: remove

* Update docs/en-US/component/table.md

* feat: filter-icon slot

* test: test case

* chore: update

* chore: update
This commit is contained in:
btea 2024-07-24 14:47:42 +08:00 committed by GitHub
parent 06ab1a0183
commit c7dea71e81
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 112 additions and 13 deletions

View File

@ -371,10 +371,11 @@ table/table-layout
### Table-column Slots
| Name | Description | Type |
| ------- | -------------------------------- | ---------------------------------------------------- |
| default | Custom content for table columns | ^[object]`{ row: any, column: any, $index: number }` |
| header | Custom content for table header | ^[object]`{ column: any, $index: number }` |
| Name | Description | Type |
| -------------------- | -------------------------------- | ---------------------------------------------------- |
| default | Custom content for table columns | ^[object]`{ row: any, column: any, $index: number }` |
| header | Custom content for table header | ^[object]`{ column: any, $index: number }` |
| filter-icon ^(2.7.8) | Custom content for filter icon | ^[object]`{ filterOpened: boolean }` |
## Type Declarations

View File

@ -4,6 +4,7 @@ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
import ElCheckbox from '@element-plus/components/checkbox'
import triggerEvent from '@element-plus/test-utils/trigger-event'
import { rAF } from '@element-plus/test-utils/tick'
import { CaretBottom, CaretTop } from '@element-plus/icons-vue'
import ElTable from '../src/table.vue'
import ElTableColumn from '../src/table-column'
import {
@ -439,6 +440,84 @@ describe('Table.vue', () => {
})
})
describe('filter filter-icon slot', () => {
let wrapper: VueWrapper<ComponentPublicInstance>
beforeEach(async () => {
wrapper = mount({
components: {
ElTable,
ElTableColumn,
CaretBottom,
CaretTop,
},
template: `
<el-table ref="table" :data="testData" @filter-change="handleFilterChange">
<el-table-column prop="name" label="片名" />
<el-table-column prop="release" label="发行日期" />
<el-table-column
prop="director"
column-key="director"
:filters="[
{ text: 'John Lasseter', value: 'John Lasseter' },
{ text: 'Peter Docter', value: 'Peter Docter' },
{ text: 'Andrew Stanton', value: 'Andrew Stanton' }
]"
:filter-method="filterMethod"
label="导演">
<template #filter-icon="{ filterOpened }">
<CaretTop v-if="filterOpened" class="top" />
<CaretBottom v-else class="bottom" />
</template>
</el-table-column>
<el-table-column prop="runtime" label="时长(分)" />
</el-table>
`,
created() {
this.testData = getTestData()
},
methods: {
filterMethod(value, row) {
return value === row.director
},
handleFilterChange(filters) {
this.filters = filters
},
},
})
await doubleWait()
})
afterEach(() => wrapper.unmount())
it('render', () => {
expect(
wrapper.find('.el-table__column-filter-trigger')
).not.toBeUndefined()
expect(
wrapper.find('.el-table__column-filter-trigger .bottom')
).not.toBeUndefined()
})
it('click filter-trigger', async () => {
const btn = wrapper.find('.el-table__column-filter-trigger')
btn.trigger('click')
await doubleWait()
expect(
wrapper.find('.el-table__column-filter-trigger .top')
).not.toBeUndefined()
btn.trigger('click')
await doubleWait()
expect(
wrapper.find('.el-table__column-filter-trigger .bottom')
).not.toBeUndefined()
})
})
describe('events', () => {
const createTable = function (prop = '') {
return mount({

View File

@ -78,8 +78,10 @@
@click="showFilterPanel"
>
<el-icon>
<arrow-up v-if="column.filterOpened" />
<arrow-down v-else />
<slot name="filter-icon">
<arrow-up v-if="column.filterOpened" />
<arrow-down v-else />
</slot>
</el-icon>
</span>
</template>

View File

@ -124,6 +124,12 @@ function useRender<T>(
}
}
if (slots['filter-icon']) {
column.renderFilterIcon = (scope) => {
return renderSlot(slots, 'filter-icon', scope)
}
}
let originRenderCell = column.renderCell
// TODO: 这里的实现调整
if (column.type === 'expand') {

View File

@ -224,14 +224,25 @@ export default defineComponent({
]
),
column.filterable &&
h(FilterPanel, {
store,
placement: column.filterPlacement || 'bottom-start',
column,
upDataColumn: (key, value) => {
column[key] = value
h(
FilterPanel,
{
store,
placement: column.filterPlacement || 'bottom-start',
column,
upDataColumn: (key, value) => {
column[key] = value
},
},
}),
{
'filter-icon': () =>
column.renderFilterIcon
? column.renderFilterIcon({
filterOpened: column.filterOpened,
})
: null,
}
),
]
),
]