Skip to content

Commit

Permalink
feat(table): cellEmptyContent support
Browse files Browse the repository at this point in the history
  • Loading branch information
chaishi committed Aug 6, 2022
1 parent e386d81 commit 21656ac
Show file tree
Hide file tree
Showing 29 changed files with 80 additions and 27 deletions.
2 changes: 1 addition & 1 deletion examples/table/demos/affix.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<template>
<!-- 注意组件父元素的宽度 -->
<div class="tdesign-demo-block-column-large tdesign-demo__table-affix" style="width: 100%">
<div class="tdesign-demo-block-column-large tdesign-demo__table tdesign-demo__table-affix" style="width: 100%">
<div>
<t-checkbox v-model="headerAffixedTop">表头吸顶</t-checkbox>
<t-checkbox v-model="footerAffixedBottom" style="margin-left: 32px">表尾吸底</t-checkbox>
Expand Down
2 changes: 1 addition & 1 deletion examples/table/demos/async-loading.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<template>
<div class="tdesign-demo-block-column-large">
<div class="tdesign-demo-block-column-large tdesign-demo__table">
<div>
<t-radio-group v-model="asyncLoading" variant="default-filled">
<t-radio-button value="load-more">加载更多</t-radio-button>
Expand Down
13 changes: 11 additions & 2 deletions examples/table/demos/base.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<template>
<div class="tdesign-demo-block-column-large">
<div class="tdesign-demo-block-column-large tdesign-demo__table">
<!-- 按钮操作区域 -->
<div>
<t-radio-group v-model="size" variant="default-filled">
Expand All @@ -14,6 +14,7 @@
<t-checkbox v-model="tableLayout">宽度自适应</t-checkbox>
</div>

<!-- 当数据为空需要占位时,会显示 cellEmptyContent -->
<t-table
rowKey="index"
:data="data"
Expand All @@ -24,6 +25,7 @@
:size="size"
:table-layout="tableLayout ? 'auto' : 'fixed'"
:pagination="pagination"
cellEmptyContent="-"
resizable
></t-table>
</div>
Expand All @@ -36,7 +38,7 @@ for (let i = 0; i < total; i++) {
index: i,
platform: i % 2 === 0 ? '共有' : '私有',
type: ['String', 'Number', 'Array', 'Object'][i % 4],
default: ['-', '0', '[]', '{}'][i % 4],
default: ['0', '[]'][i % 5],
detail: {
position: `读取 ${i} 个数据的嵌套信息值`,
},
Expand Down Expand Up @@ -119,3 +121,10 @@ export default {
},
};
</script>

<style>
/* 不要改成 scope,就是要全局间距 */
.tdesign-demo__table .t-checkbox + .t-checkbox {
margin-left: 16px;
}
</style>
2 changes: 1 addition & 1 deletion examples/table/demos/custom-cell.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<template>
<div>
<div class="tdesign-demo__table">
<t-table :data="data" :columns="columns" rowKey="property" verticalAlign="top">
<!-- 插槽方式 自定义单元格:cell 的值为插槽名称,参数有:{col, colIndex, row, rowIndex} -->
<template #type-slot-name="{ col, row }"> 自定义插槽名称:{{ row[col.colKey] }} </template>
Expand Down
2 changes: 1 addition & 1 deletion examples/table/demos/custom-col-button.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<template>
<div class="tdesign-demo-block-column-large">
<div class="tdesign-demo-block-column-large tdesign-demo__table">
<!-- 按钮操作区域 -->
<div>
<t-radio-group v-model="placement" variant="default-filled">
Expand Down
2 changes: 1 addition & 1 deletion examples/table/demos/custom-col.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<template>
<div class="tdesign-demo-block-column-large">
<div class="tdesign-demo-block-column-large tdesign-demo__table">
<!-- 按钮操作区域 -->
<div>
<t-button @click="columnControllerVisible = true">显示列配置弹窗</t-button>
Expand Down
2 changes: 1 addition & 1 deletion examples/table/demos/custom-footer.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<template>
<div class="tdesign-demo-block-column-large">
<div class="tdesign-demo-block-column-large tdesign-demo__table">
<div>
<!-- 表尾有 3 种方式 -->
<t-radio-group v-model="footerType" variant="default-filled">
Expand Down
2 changes: 1 addition & 1 deletion examples/table/demos/data-sort.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<template>
<div class="demo-container t-table-demo-sort">
<div class="demo-container t-table-demo-sort tdesign-demo__table">
<!-- t-locale-provider 一般用于全局配置某个组件的特性,此代码示例 示范了如何对表格排序图标进行统一配置 -->
<t-config-provider :globalConfig="globalLocale">
<div class="item">
Expand Down
2 changes: 1 addition & 1 deletion examples/table/demos/drag-col-sort.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<template>
<div class="demo-container t-table-demo-sort">
<div class="demo-container t-table-demo-sort tdesign-demo__table">
<div class="item">
<t-table rowKey="id" :columns="columns" :data="data" dragSort="col" @drag-sort="onDragSort">
<template #status="{ row }">
Expand Down
2 changes: 1 addition & 1 deletion examples/table/demos/drag-sort-handler.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<template>
<div class="demo-container t-table-demo-sort">
<div class="demo-container t-table-demo-sort tdesign-demo__table">
<div>
<t-checkbox v-model="loading">加载状态</t-checkbox>
</div>
Expand Down
2 changes: 1 addition & 1 deletion examples/table/demos/drag-sort.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<template>
<div class="demo-container t-table-demo-sort">
<div class="demo-container t-table-demo-sort tdesign-demo__table">
<div class="item">
<!-- 拖拽排序涉及到 data 的变更,相对比较慎重,因此仅支持受控用法 -->

Expand Down
2 changes: 1 addition & 1 deletion examples/table/demos/expandable.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<template>
<div class="tdesign-demo-block-column" style="width: 100%">
<div class="tdesign-demo-block-column tdesign-demo__table" style="width: 100%">
<!-- t-config-provider 一般用于全局配置某个组件的特性,此代码示例 示范了如何对表格扩展图标进行统一配置 -->
<!-- `globalLocale.table.expandIcon` 可用于自定义展开箭头图标 -->
<!-- <t-config-provider :globalLocale="globalLocale"> -->
Expand Down
2 changes: 1 addition & 1 deletion examples/table/demos/filter-controlled.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<template>
<div class="tdesign-demo-block-column">
<div class="tdesign-demo-block-column tdesign-demo__table">
<!-- 是否显示表格边框 和 对齐方式都决定着 排序图标 和 筛选图标的排列位置 -->
<div>
<t-radio-group v-model="align" variant="default-filled">
Expand Down
2 changes: 1 addition & 1 deletion examples/table/demos/fixed-column.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<template>
<div class="tdesign-demo-block-column" style="max-width: 1200px">
<div class="tdesign-demo-block-column tdesign-demo__table" style="max-width: 1200px">
<div>
<t-radio-group v-model="leftFixedColumn" variant="default-filled">
<t-radio-button :value="1">左侧固定一列</t-radio-button>
Expand Down
2 changes: 1 addition & 1 deletion examples/table/demos/fixed-header-col.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<template>
<!-- 父元素宽度不能超过 100% -->
<div class="tdesign-demo-block-column" style="width: 100%">
<div class="tdesign-demo-block-column tdesign-demo__table" style="width: 100%">
<div>
<t-radio-group v-model="tableLayout" variant="default-filled">
<t-radio-button value="fixed">table-layout: fixed</t-radio-button>
Expand Down
2 changes: 1 addition & 1 deletion examples/table/demos/multi-header.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<template>
<!-- 注意控制父元素宽度 -->
<div style="width: 100%" class="tdesign-demo-block-column-large tdesign-demo-table-multi-header">
<div style="width: 100%" class="tdesign-demo-block-column-large tdesign-demo-table-multi-heade tdesign-demo__tabler">
<!-- 按钮操作区域 -->
<div>
<t-checkbox v-model="bordered">显示表格边框</t-checkbox>
Expand Down
2 changes: 1 addition & 1 deletion examples/table/demos/select-single.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<template>
<div>
<div class="tdesign-demo__table">
<div>
<t-checkbox v-model="highlightSelectedRow">高亮行选中</t-checkbox>
<t-checkbox v-model="selectedOnRowClick">整行选中</t-checkbox>
Expand Down
1 change: 1 addition & 0 deletions examples/table/table.en-US.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ name | type | default | description | required
allowResizeColumnWidth | Boolean | undefined | `deprecated`。allow to resize column width | N
bordered | Boolean | false | show table bordered | N
bottomContent | String / Slot / Function | - | Typescript:`string | TNode`[see more ts definition](https://github.com/Tencent/tdesign-vue/blob/develop/src/common.ts) | N
cellEmptyContent | String / Slot / Function | '' | empty cell content。Typescript:`string | TNode<BaseTableCellParams<T>>`[see more ts definition](https://github.com/Tencent/tdesign-vue/blob/develop/src/common.ts) | N
columns | Array | [] | table column configs。Typescript:`Array<BaseTableCol<T>>` | N
data | Array | [] | table data。Typescript:`Array<T>` | N
disableDataPage | Boolean | false | \- | N
Expand Down
1 change: 1 addition & 0 deletions examples/table/table.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
allowResizeColumnWidth | Boolean | undefined | 已废弃。是否允许调整列宽。请更为使用 `resizable` | N
bordered | Boolean | false | 是否显示表格边框 | N
bottomContent | String / Slot / Function | - | 表格底部内容,可以用于自定义列设置等。TS 类型:`string | TNode`[通用类型定义](https://github.com/Tencent/tdesign-vue/blob/develop/src/common.ts) | N
cellEmptyContent | String / Slot / Function | '' | 单元格数据为空,呈现的内容。TS 类型:`string | TNode<BaseTableCellParams<T>>`[通用类型定义](https://github.com/Tencent/tdesign-vue/blob/develop/src/common.ts) | N
columns | Array | [] | 列配置,泛型 T 指表格数据类型。TS 类型:`Array<BaseTableCol<T>>` | N
data | Array | [] | 数据源,泛型 T 指表格数据类型。TS 类型:`Array<T>` | N
disableDataPage | Boolean | false | 是否禁用本地数据分页。当 `data` 数据长度超过分页大小时,会自动进行本地数据分页。如果 `disableDataPage` 设置为 true,则无论何时,都不会进行本地数据分页 | N
Expand Down
2 changes: 1 addition & 1 deletion src/_common
5 changes: 5 additions & 0 deletions src/table/base-table-props.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,11 @@ export default {
bottomContent: {
type: [String, Function] as PropType<TdBaseTableProps['bottomContent']>,
},
/** 单元格数据为空,呈现的内容 */
cellEmptyContent: {
type: [String, Function] as PropType<TdBaseTableProps['cellEmptyContent']>,
default: '',
},
/** 列配置,泛型 T 指表格数据类型 */
columns: {
type: Array as PropType<TdBaseTableProps['columns']>,
Expand Down
1 change: 1 addition & 0 deletions src/table/base-table.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -427,6 +427,7 @@ export default defineComponent({
trs: this.trs,
bufferSize: this.bufferSize,
scroll: this.scroll,
cellEmptyContent: this.cellEmptyContent,
handleRowMounted: this.handleRowMounted,
renderExpandedRow: this.renderExpandedRow,
...pick(this.$props, extendTableProps),
Expand Down
9 changes: 8 additions & 1 deletion src/table/editable-cell.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,11 @@ import set from 'lodash/set';
import isFunction from 'lodash/isFunction';
import { Edit1Icon } from 'tdesign-icons-vue';
import {
TableRowData, PrimaryTableCol, PrimaryTableRowEditContext, PrimaryTableRowValidateContext,
TableRowData,
PrimaryTableCol,
PrimaryTableRowEditContext,
PrimaryTableRowValidateContext,
TdBaseTableProps,
} from './type';
import { TableClassName } from './hooks/useClassName';
import { renderCell } from './tr';
Expand All @@ -24,6 +28,7 @@ export interface EditableCellProps {
/** 行编辑需要使用 editable。单元格编辑则无需使用,设置为 undefined */
editable?: boolean;
errors?: AllValidateResult[];
cellEmptyContent?: TdBaseTableProps['cellEmptyContent'];
onChange?: (context: PrimaryTableRowEditContext<TableRowData>) => void;
onValidate?: (context: PrimaryTableRowValidateContext<TableRowData>) => void;
onRuleChange?: (context: PrimaryTableRowEditContext<TableRowData>) => void;
Expand All @@ -38,6 +43,7 @@ export default defineComponent({
colIndex: Number,
oldCell: [Function, String] as PropType<EditableCellProps['oldCell']>,
tableBaseClass: Object as PropType<EditableCellProps['tableBaseClass']>,
cellEmptyContent: [Function, String] as PropType<EditableCellProps['cellEmptyContent']>,
editable: {
type: Boolean,
default: undefined,
Expand Down Expand Up @@ -73,6 +79,7 @@ export default defineComponent({
colIndex: props.colIndex,
},
context.slots,
{ cellEmptyContent: props.cellEmptyContent },
);
return node;
});
Expand Down
4 changes: 3 additions & 1 deletion src/table/hooks/useTreeData.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,9 @@ export default function useTreeData(props: TdEnhancedTableProps, context: SetupC
if (!props.tree || col.colKey !== treeNodeCol.value.colKey) return col;
const newCol = { ...treeNodeCol.value };
newCol.cell = (h, p) => {
const cellInfo = renderCell({ ...p, col: { ...treeNodeCol.value } }, context.slots);
const cellInfo = renderCell({ ...p, col: { ...treeNodeCol.value } }, context.slots, {
cellEmptyContent: props.cellEmptyContent,
});
const currentState = store.value.treeDataMap.get(get(p.row, rowDataKeys.value.rowKey));
const colStyle = getTreeNodeStyle(currentState?.level);
const classes = { [tableTreeClasses.inlineCol]: !!col.ellipsis };
Expand Down
1 change: 1 addition & 0 deletions src/table/primary-table.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,7 @@ export default defineComponent({
...p,
oldCell,
tableBaseClass,
cellEmptyContent: props.cellEmptyContent,
onChange: onPrimaryTableRowEdit,
onValidate: onPrimaryTableRowValidate,
onRuleChange,
Expand Down
6 changes: 4 additions & 2 deletions src/table/tbody.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,12 @@ import get from 'lodash/get';
import pick from 'lodash/pick';
import TrElement, { TrProps, ROW_LISTENERS, TABLE_PROPS } from './tr';
import { useConfig } from '../config-provider/useConfig';
import { BaseTableProps, RowAndColFixedPosition } from './interface';

import { useTNodeJSX } from '../hooks/tnode';
import useClassName from './hooks/useClassName';
import baseTableProps from './base-table-props';
import useRowspanAndColspan from './hooks/useRowspanAndColspan';
import { BaseTableProps, RowAndColFixedPosition } from './interface';
import { TdBaseTableProps } from './type';

export const ROW_AND_TD_LISTENERS = ROW_LISTENERS.concat('cell-click');
export interface TableBodyProps extends BaseTableProps {
Expand All @@ -31,6 +31,7 @@ export interface TableBodyProps extends BaseTableProps {
trs: Map<number, object>;
bufferSize: number;
tableContentElm: HTMLDivElement;
cellEmptyContent: TdBaseTableProps['cellEmptyContent'];
handleRowMounted: () => void;
}

Expand All @@ -46,6 +47,7 @@ export const extendTableProps = [
'lastFullRow',
'rowspanAndColspan',
'scroll',
'cellEmptyContent',
'onCellClick',
'onPageChange',
'onRowClick',
Expand Down
26 changes: 22 additions & 4 deletions src/table/tr.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import { RowAndColFixedPosition } from './interface';
import useClassName from './hooks/useClassName';
import TEllipsis from './ellipsis';
import {
BaseTableCellParams, TableRowData, RowspanColspan, TdPrimaryTableProps,
BaseTableCellParams, TableRowData, RowspanColspan, TdPrimaryTableProps, TdBaseTableProps,
} from './type';
import baseTableProps from './base-table-props';
import { getCellKey, SkipSpansValue } from './hooks/useRowspanAndColspan';
Expand All @@ -33,6 +33,7 @@ export interface RenderTdExtra {
columnLength: number;
dataLength: number;
cellSpans: RowspanColspan;
cellEmptyContent: TdBaseTableProps['cellEmptyContent'];
}

export interface RenderEllipsisCellParams {
Expand All @@ -50,6 +51,7 @@ export const TABLE_PROPS = [
'rowAttributes',
'rowspanAndColspan',
'scroll',
'cellEmptyContent',
'onCellClick',
'onRowClick',
'onRowDblclick',
Expand All @@ -75,11 +77,18 @@ export interface TrProps extends TrCommonProps {
trs?: Map<number, object>;
bufferSize?: number;
tableContentElm?: HTMLDivElement;
cellEmptyContent: TdBaseTableProps['cellEmptyContent'];
}

export const ROW_LISTENERS = ['click', 'dblclick', 'mouseover', 'mousedown', 'mouseenter', 'mouseleave', 'mouseup'];

export function renderCell(params: BaseTableCellParams<TableRowData>, slots: SetupContext['slots']) {
export function renderCell(
params: BaseTableCellParams<TableRowData>,
slots: SetupContext['slots'],
extra?: {
cellEmptyContent?: TdBaseTableProps['cellEmptyContent'];
},
) {
const { col, row } = params;
if (isFunction(col.cell)) {
return col.cell(h, params);
Expand All @@ -93,7 +102,15 @@ export function renderCell(params: BaseTableCellParams<TableRowData>, slots: Set
if (isFunction(col.render)) {
return col.render(h, { ...params, type: 'cell' });
}
return get(row, col.colKey);
const r = get(row, col.colKey);
// 0 和 false 属于正常可用之,不能使用兜底逻辑 cellEmptyContent
if (![undefined, '', null].includes(r)) return r;
// cellEmptyContent 作为空数据兜底显示,用户可自定义
if (extra?.cellEmptyContent) {
return isFunction(extra.cellEmptyContent) ? extra.cellEmptyContent(h, params) : extra.cellEmptyContent;
}
if (slots.cellEmptyContent) return slots.cellEmptyContent(params);
return r;
}

// 表格行组件
Expand Down Expand Up @@ -234,7 +251,7 @@ export default defineComponent({
renderTd(h: CreateElement, params: BaseTableCellParams<TableRowData>, extra: RenderTdExtra) {
const { col, colIndex, rowIndex } = params;
const { cellSpans, dataLength, rowAndColFixedPosition } = extra;
const cellNode = renderCell(params, this.tSlots);
const cellNode = renderCell(params, this.tSlots, { cellEmptyContent: extra.cellEmptyContent });
const tdStyles = getColumnFixedStyles(col, colIndex, rowAndColFixedPosition, this.tableColFixedClasses);
const customClasses = isFunction(col.className) ? col.className({ ...params, type: 'td' }) : col.className;
const classes = [
Expand Down Expand Up @@ -288,6 +305,7 @@ export default defineComponent({
rowAndColFixedPosition,
columnLength: this.columns.length,
cellSpans,
cellEmptyContent: this.cellEmptyContent,
});
});
const attrs = this.trAttributes || {};
Expand Down
5 changes: 5 additions & 0 deletions src/table/type.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,11 @@ export interface TdBaseTableProps<T extends TableRowData = TableRowData> {
* 表格底部内容,可以用于自定义列设置等
*/
bottomContent?: string | TNode;
/**
* 单元格数据为空,呈现的内容
* @default ''
*/
cellEmptyContent?: string | TNode<BaseTableCellParams<T>>;
/**
* 列配置,泛型 T 指表格数据类型
* @default []
Expand Down
1 change: 1 addition & 0 deletions test/ssr/__snapshots__/ssr.test.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -15458,6 +15458,7 @@ exports[`ssr snapshot test renders ./examples/table/demos/editable-cell.vue corr

exports[`ssr snapshot test renders ./examples/table/demos/editable-row.vue correctly 1`] = `
<div class="t-table-demo__editable-row">
<div><button type="button" class="t-button t-size-m t-button--variant-base t-button--theme-primary"><span class="t-button__text">校验全部</span></button></div> <br>
<div class="t-table t-table--bordered t-vertical-align-top t-table--row-edit" style="position:relative;">
<div class="t-table__content">
<table class="t-table--layout-fixed" style="width:;">
Expand Down

0 comments on commit 21656ac

Please sign in to comment.