diff --git a/packages/components/table-v2/src/renderers/empty.tsx b/packages/components/table-v2/src/renderers/empty.tsx new file mode 100644 index 0000000000..df96792a4c --- /dev/null +++ b/packages/components/table-v2/src/renderers/empty.tsx @@ -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 = (props, { slots }) => { + return ( +
+ {slots.default ? slots.default() : } +
+ ) +} + +Footer.displayName = 'ElTableV2Empty' + +export default Footer diff --git a/packages/components/table-v2/src/renderers/header-cell.tsx b/packages/components/table-v2/src/renderers/header-cell.tsx index 4c3668f7da..24a08b5cfb 100644 --- a/packages/components/table-v2/src/renderers/header-cell.tsx +++ b/packages/components/table-v2/src/renderers/header-cell.tsx @@ -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 = ( onColumnSorted, } = props - const style = columnsStyles[column.key] + const style = enforceUnit(columnsStyles[column.key]) if (column.placeholderSign === placeholderSign) { return
diff --git a/packages/components/table-v2/src/table-header-cell.tsx b/packages/components/table-v2/src/table-header-cell.tsx index 8fb70e2a7b..9d50d0f5d1 100644 --- a/packages/components/table-v2/src/table-header-cell.tsx +++ b/packages/components/table-v2/src/table-header-cell.tsx @@ -1,6 +1,7 @@ +import type { FunctionalComponent } from 'vue' import type { TableV2HeaderCell } from './header-cell' -const HeaderCell = (props: TableV2HeaderCell, { slots }) => +const HeaderCell: FunctionalComponent = (props, { slots }) => slots.default ? ( slots.default(props) ) : ( @@ -9,6 +10,6 @@ const HeaderCell = (props: TableV2HeaderCell, { slots }) =>
) -HeaderCell.componentName = 'ElTableV2HeaderCell' +HeaderCell.displayName = 'ElTableV2HeaderCell' export default HeaderCell diff --git a/packages/components/table-v2/src/table-v2.tsx b/packages/components/table-v2/src/table-v2.tsx index 4a13f835f5..a604e4cb83 100644 --- a/packages/components/table-v2/src/table-v2.tsx +++ b/packages/components/table-v2/src/table-v2.tsx @@ -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({ {tableSlots} {tableSlots}
{{ default: slots.footer }}
+ {unref(showEmpty) && ( + + {{ default: slots.empty }} + + )} ) } diff --git a/packages/components/table-v2/src/use-table.ts b/packages/components/table-v2/src/use-table.ts index 1b3e2ff7ec..5e63d77a22 100644 --- a/packages/components/table-v2/src/use-table.ts +++ b/packages/components/table-v2/src/use-table.ts @@ -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(() => ({ + 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, diff --git a/packages/theme-chalk/src/table-v2.scss b/packages/theme-chalk/src/table-v2.scss index 33f05c21c2..33adf26603 100644 --- a/packages/theme-chalk/src/table-v2.scss +++ b/packages/theme-chalk/src/table-v2.scss @@ -118,6 +118,11 @@ overflow: hidden; } + @include e('empty') { + position: absolute; + left: 0; + } + @include e('header-row') { display: flex; border-bottom: getCssVar('table', 'border');