feat(components): [virtual-table] empty renderer (#7308)

- Add Empty component.
- Add empty render conditions.
- Add empty rendering to table-v2.
This commit is contained in:
JeremyWuuuuu
2022-04-21 18:45:35 +08:00
committed by GitHub
parent 658d396ff7
commit 74a8d8ba32
6 changed files with 56 additions and 5 deletions

View File

@@ -0,0 +1,19 @@
import ElEmpty from '@element-plus/components/empty'
import type { CSSProperties, FunctionalComponent } from 'vue'
type EmptyRendererProps = {
class?: JSX.IntrinsicAttributes['class']
style?: CSSProperties
}
const Footer: FunctionalComponent<EmptyRendererProps> = (props, { slots }) => {
return (
<div class={props.class} style={props.style}>
{slots.default ? slots.default() : <ElEmpty />}
</div>
)
}
Footer.displayName = 'ElTableV2Empty'
export default Footer

View File

@@ -3,7 +3,7 @@ import HeaderCell from '../table-header-cell'
import SortIcon from '../sort-icon'
import { Alignment, SortOrder, oppositeOrderMap } from '../constants'
import { placeholderSign } from '../private'
import { componentToSlot, tryCall } from '../utils'
import { componentToSlot, enforceUnit, tryCall } from '../utils'
import type { FunctionalComponent, UnwrapNestedRefs } from 'vue'
import type { UseNamespaceReturn } from '@element-plus/hooks'
@@ -42,7 +42,7 @@ const HeaderCellRenderer: FunctionalComponent<HeaderCellRendererProps> = (
onColumnSorted,
} = props
const style = columnsStyles[column.key]
const style = enforceUnit(columnsStyles[column.key])
if (column.placeholderSign === placeholderSign) {
return <div class={ns.em('header-row-cell', 'placeholder')} style={style} />

View File

@@ -1,6 +1,7 @@
import type { FunctionalComponent } from 'vue'
import type { TableV2HeaderCell } from './header-cell'
const HeaderCell = (props: TableV2HeaderCell, { slots }) =>
const HeaderCell: FunctionalComponent<TableV2HeaderCell> = (props, { slots }) =>
slots.default ? (
slots.default(props)
) : (
@@ -9,6 +10,6 @@ const HeaderCell = (props: TableV2HeaderCell, { slots }) =>
</div>
)
HeaderCell.componentName = 'ElTableV2HeaderCell'
HeaderCell.displayName = 'ElTableV2HeaderCell'
export default HeaderCell

View File

@@ -12,6 +12,7 @@ import Cell from './renderers/cell'
import Header from './renderers/header'
import HeaderCell from './renderers/header-cell'
import Footer from './renderers/footer'
import Empty from './renderers/empty'
import type { TableGridRowSlotParams } from './table-grid'
import type { TableV2RowCellRenderParam } from './table-row'
@@ -49,10 +50,13 @@ const TableV2 = defineComponent({
isScrolling,
bodyWidth,
emptyStyle,
rootStyle,
headerWidth,
footerHeight,
showEmpty,
getRowHeight,
onColumnSorted,
onRowHeightChange,
@@ -271,6 +275,11 @@ const TableV2 = defineComponent({
<LeftTable {...leftTableProps}>{tableSlots}</LeftTable>
<RightTable {...rightTableProps}>{tableSlots}</RightTable>
<Footer {...footerProps}>{{ default: slots.footer }}</Footer>
{unref(showEmpty) && (
<Empty class={ns.e('empty')} style={unref(emptyStyle)}>
{{ default: slots.empty }}
</Empty>
)}
</div>
)
}

View File

@@ -8,7 +8,7 @@ import {
watch,
} from 'vue'
import { debounce } from 'lodash-unified'
import { isNumber, isObject } from '@element-plus/utils'
import { addUnit, isArray, isNumber, isObject } from '@element-plus/utils'
import { enforceUnit, sum } from './utils'
import { useColumns } from './use-columns'
import { FixedDir, SortOrder, oppositeOrderMap } from './constants'
@@ -116,6 +116,14 @@ function useTable(props: TableV2Props) {
return expandColumnKey ? unref(flattenedData) : data
})
const showEmpty = computed(() => {
const noData = unref(data).length === 0
return isArray(props.fixedData)
? props.fixedData.length === 0 && noData
: noData
})
const isDynamic = computed(() => isNumber(props.estimatedRowHeight))
const bodyWidth = computed(() => {
@@ -157,6 +165,12 @@ function useTable(props: TableV2Props) {
enforceUnit({ height: props.footerHeight })
)
const emptyStyle = computed<CSSProperties>(() => ({
top: addUnit(unref(headerHeight)),
bottom: addUnit(props.footerHeight),
width: addUnit(props.width),
}))
const fixedTableHeight = computed(() => {
const { maxHeight } = props
const tableHeight = unref(mainTableHeight)
@@ -423,6 +437,7 @@ function useTable(props: TableV2Props) {
mainColumns,
// metadata
bodyWidth,
emptyStyle,
rootStyle,
headerWidth,
footerHeight,
@@ -430,6 +445,8 @@ function useTable(props: TableV2Props) {
fixedTableHeight,
leftTableWidth,
rightTableWidth,
// flags
showEmpty,
// methods
getRowHeight,

View File

@@ -118,6 +118,11 @@
overflow: hidden;
}
@include e('empty') {
position: absolute;
left: 0;
}
@include e('header-row') {
display: flex;
border-bottom: getCssVar('table', 'border');