diff --git a/src/data-table/src/DataTable.tsx b/src/data-table/src/DataTable.tsx
index 7ef8f7279bc..385ae05ea31 100644
--- a/src/data-table/src/DataTable.tsx
+++ b/src/data-table/src/DataTable.tsx
@@ -225,6 +225,7 @@ export default defineComponent({
scrollXRef: computed(() => props.scrollX),
rowsRef,
colsRef,
+ captionRef: toRef(props, 'caption'),
paginatedDataRef,
leftActiveFixedColKeyRef,
leftActiveFixedChildrenColKeysRef,
diff --git a/src/data-table/src/TableParts/Body.tsx b/src/data-table/src/TableParts/Body.tsx
index f0e33046d43..9e1b996b505 100644
--- a/src/data-table/src/TableParts/Body.tsx
+++ b/src/data-table/src/TableParts/Body.tsx
@@ -109,6 +109,7 @@ function flatten(
const VirtualListItemWrapper = defineComponent({
props: {
+ caption: String,
clsPrefix: {
type: String,
required: true
@@ -125,7 +126,7 @@ const VirtualListItemWrapper = defineComponent({
onMouseleave: Function as PropType<(e: MouseEvent) => void>
},
render() {
- const { clsPrefix, id, cols, onMouseenter, onMouseleave } = this
+ const { caption, clsPrefix, id, cols, onMouseenter, onMouseleave } = this
return (
+ {caption ? {caption} : null}
{cols.map(col => (
@@ -202,6 +204,7 @@ export default defineComponent({
handleTableBodyScroll,
doCheck,
doUncheck,
+ captionRef,
renderCell
} = inject(dataTableInjectionKey)!
const NConfigProvider = inject(configProviderInjectionKey)
@@ -526,6 +529,7 @@ export default defineComponent({
handleRadioUpdateChecked,
handleUpdateExpanded,
renderCell,
+ caption: captionRef,
...exposedMethods
}
},
@@ -584,6 +588,7 @@ export default defineComponent({
// coordinate to related hover keys
const cordKey: Record> = {}
const {
+ caption,
cols,
paginatedDataAndInfo,
mergedTheme,
@@ -1043,6 +1048,7 @@ export default defineComponent({
tableLayout: this.mergedTableLayout
}}
>
+ {caption ? {caption} : null}
{cols.map(col => (
@@ -1080,6 +1086,7 @@ export default defineComponent({
itemSize={this.minRowHeight}
visibleItemsTag={VirtualListItemWrapper}
visibleItemsProps={{
+ caption,
clsPrefix: mergedClsPrefix,
id: componentId,
cols,
diff --git a/src/data-table/src/TableParts/Header.tsx b/src/data-table/src/TableParts/Header.tsx
index dfef1ef32c6..a6b5a3b513b 100644
--- a/src/data-table/src/TableParts/Header.tsx
+++ b/src/data-table/src/TableParts/Header.tsx
@@ -38,6 +38,7 @@ function renderTitle(
const VirtualListItemWrapper = defineComponent({
props: {
+ caption: String,
clsPrefix: {
type: String,
required: true
@@ -59,6 +60,7 @@ const VirtualListItemWrapper = defineComponent({
style={{ tableLayout: 'fixed', width }}
class={`${clsPrefix}-data-table-table`}
>
+ {this.caption ? {this.caption} : null}
{cols.map(col => (
@@ -91,6 +93,7 @@ export default defineComponent({
someRowsCheckedRef,
rowsRef,
colsRef,
+ captionRef,
mergedThemeRef,
checkOptionsRef,
mergedSortStateRef,
@@ -178,6 +181,7 @@ export default defineComponent({
someRowsChecked: someRowsCheckedRef,
rows: rowsRef,
cols: colsRef,
+ caption: captionRef,
mergedTheme: mergedThemeRef,
checkOptions: checkOptionsRef,
mergedTableLayout: mergedTableLayoutRef,
@@ -203,6 +207,7 @@ export default defineComponent({
someRowsChecked,
rows,
cols,
+ caption,
mergedTheme,
checkOptions,
componentId,
@@ -223,137 +228,148 @@ export default defineComponent({
getLeft: ((index: number) => number) | null,
headerHeightPx: string | undefined
) =>
- row.map(({ column, colIndex, colSpan, rowSpan, isLast }) => {
- const key = getColKey(column)
- const { ellipsis } = column
- if (!hasEllipsis && ellipsis)
- hasEllipsis = true
- const createColumnVNode = (): VNode | null => {
- if (column.type === 'selection') {
- return column.multiple !== false ? (
+ row.map(
+ ({ column, colIndex, colSpan, rowSpan, isLast }, actualRowIndex) => {
+ const key = getColKey(column)
+ const { ellipsis } = column
+ if (!hasEllipsis && ellipsis)
+ hasEllipsis = true
+ const createColumnVNode = (): VNode | null => {
+ if (column.type === 'selection') {
+ return column.multiple !== false ? (
+ <>
+
+ {checkOptions ? (
+
+ ) : null}
+ >
+ ) : null
+ }
+ return (
<>
-
- {checkOptions ? (
-
+
+
+ {ellipsis === true || (ellipsis && !ellipsis.tooltip) ? (
+
+ {renderTitle(column)}
+
+ ) : ellipsis && typeof ellipsis === 'object' ? (
+
+ {{
+ default: () => renderTitle(column)
+ }}
+
+ ) : (
+ renderTitle(column)
+ )}
+
+ {isColumnSortable(column) ? (
+
+ ) : null}
+
+ {isColumnFilterable(column) ? (
+
+ ) : null}
+ {isColumnResizable(column) ? (
+ {
+ handleColumnResizeStart(column as TableBaseColumn)
+ }}
+ onResize={(displacementX) => {
+ handleColumnResize(
+ column as TableBaseColumn,
+ displacementX
+ )
+ }}
+ />
) : null}
>
- ) : null
+ )
}
+ const leftFixed = key in fixedColumnLeftMap
+ const rightFixed = key in fixedColumnRightMap
+ const { headerCellProps } = column
+ const resolvedHeaderCellProps = headerCellProps?.(
+ column,
+ actualRowIndex
+ )
+ const CellComponent = (
+ getLeft && !column.fixed ? 'div' : 'th'
+ ) as 'th'
return (
- <>
-
-
- {ellipsis === true || (ellipsis && !ellipsis.tooltip) ? (
-
- {renderTitle(column)}
-
- ) : ellipsis && typeof ellipsis === 'object' ? (
-
- {{
- default: () => renderTitle(column)
- }}
-
- ) : (
- renderTitle(column)
- )}
-
- {isColumnSortable(column) ? (
-
- ) : null}
-
- {isColumnFilterable(column) ? (
-
- ) : null}
- {isColumnResizable(column) ? (
- {
- handleColumnResizeStart(column as TableBaseColumn)
- }}
- onResize={(displacementX) => {
- handleColumnResize(column as TableBaseColumn, displacementX)
- }}
- />
- ) : null}
- >
+ (cellElsRef[key] = el as HTMLTableCellElement)}
+ key={key}
+ style={[
+ getLeft && !column.fixed
+ ? {
+ position: 'absolute',
+ left: pxfy(getLeft(colIndex)),
+ top: 0,
+ bottom: 0
+ }
+ : {
+ left: pxfy(fixedColumnLeftMap[key]?.start),
+ right: pxfy(fixedColumnRightMap[key]?.start)
+ },
+ {
+ width: pxfy(column.width),
+ textAlign: column.titleAlign || column.align,
+ height: headerHeightPx
+ }
+ ]}
+ colspan={colSpan}
+ rowspan={rowSpan}
+ data-col-key={key}
+ class={[
+ `${mergedClsPrefix}-data-table-th`,
+ (leftFixed || rightFixed)
+ && `${mergedClsPrefix}-data-table-th--fixed-${
+ leftFixed ? 'left' : 'right'
+ }`,
+ {
+ [`${mergedClsPrefix}-data-table-th--sorting`]:
+ isColumnSorting(column, mergedSortState),
+ [`${mergedClsPrefix}-data-table-th--filterable`]:
+ isColumnFilterable(column),
+ [`${mergedClsPrefix}-data-table-th--sortable`]:
+ isColumnSortable(column),
+ [`${mergedClsPrefix}-data-table-th--selection`]:
+ column.type === 'selection',
+ [`${mergedClsPrefix}-data-table-th--last`]: isLast
+ },
+ column.className
+ ]}
+ onClick={
+ column.type !== 'selection'
+ && column.type !== 'expand'
+ && !('children' in column)
+ ? (e) => {
+ handleColHeaderClick(e, column)
+ }
+ : undefined
+ }
+ >
+ {createColumnVNode()}
+
)
}
- const leftFixed = key in fixedColumnLeftMap
- const rightFixed = key in fixedColumnRightMap
- const CellComponent = (getLeft && !column.fixed ? 'div' : 'th') as 'th'
- return (
- (cellElsRef[key] = el as HTMLTableCellElement)}
- key={key}
- style={[
- getLeft && !column.fixed
- ? {
- position: 'absolute',
- left: pxfy(getLeft(colIndex)),
- top: 0,
- bottom: 0
- }
- : {
- left: pxfy(fixedColumnLeftMap[key]?.start),
- right: pxfy(fixedColumnRightMap[key]?.start)
- },
- {
- width: pxfy(column.width),
- textAlign: column.titleAlign || column.align,
- height: headerHeightPx
- }
- ]}
- colspan={colSpan}
- rowspan={rowSpan}
- data-col-key={key}
- class={[
- `${mergedClsPrefix}-data-table-th`,
- (leftFixed || rightFixed)
- && `${mergedClsPrefix}-data-table-th--fixed-${
- leftFixed ? 'left' : 'right'
- }`,
- {
- [`${mergedClsPrefix}-data-table-th--sorting`]: isColumnSorting(
- column,
- mergedSortState
- ),
- [`${mergedClsPrefix}-data-table-th--filterable`]:
- isColumnFilterable(column),
- [`${mergedClsPrefix}-data-table-th--sortable`]:
- isColumnSortable(column),
- [`${mergedClsPrefix}-data-table-th--selection`]:
- column.type === 'selection',
- [`${mergedClsPrefix}-data-table-th--last`]: isLast
- },
- column.className
- ]}
- onClick={
- column.type !== 'selection'
- && column.type !== 'expand'
- && !('children' in column)
- ? (e) => {
- handleColHeaderClick(e, column)
- }
- : undefined
- }
- >
- {createColumnVNode()}
-
- )
- })
+ )
if (virtualScrollHeader) {
const { headerHeight } = this
@@ -383,6 +399,7 @@ export default defineComponent({
itemResizable={false}
visibleItemsTag={VirtualListItemWrapper}
visibleItemsProps={{
+ caption,
clsPrefix: mergedClsPrefix,
id: componentId,
cols,
@@ -467,6 +484,7 @@ export default defineComponent({
tableLayout: mergedTableLayout
}}
>
+ {caption ? {caption} : null}
{cols.map(col => (
diff --git a/src/data-table/src/interface.ts b/src/data-table/src/interface.ts
index 3029d8dcedb..40f94bec243 100644
--- a/src/data-table/src/interface.ts
+++ b/src/data-table/src/interface.ts
@@ -128,6 +128,10 @@ export const dataTableProps = {
renderCell: Function as PropType<
(value: any, rowData: object, column: TableBaseColumn) => VNodeChild
>,
+ caption: {
+ type: String,
+ default: ''
+ },
renderExpandIcon: Function as PropType,
spinProps: { type: Object as PropType, default: {} },
getCsvCell: Function as PropType,
@@ -244,6 +248,7 @@ export interface CommonColumnInfo {
ellipsisComponent?: 'ellipsis' | 'performant-ellipsis'
allowExport?: boolean
cellProps?: (rowData: T, rowIndex: number) => HTMLAttributes
+ headerCellProps?: (column: TableColumn, rowIndex: number) => HTMLAttributes
}
export type DataTableHeightForRow = (
@@ -457,6 +462,7 @@ export interface DataTableInjection {
| undefined
| ((value: any, rowData: object, column: TableBaseColumn) => VNodeChild)
>
+ captionRef: Ref
}
export const dataTableInjectionKey