From 389f90c566535be73114eb90da22bd53956ba0e0 Mon Sep 17 00:00:00 2001 From: jahnli Date: Thu, 2 Oct 2025 23:14:55 +0800 Subject: [PATCH] feat(data-table): add resize events --- CHANGELOG.en-US.md | 8 ++ CHANGELOG.zh-CN.md | 8 ++ build/utils/terse-cssr.ts | 2 +- src/data-table/demos/enUS/index.demo-entry.md | 4 + .../demos/enUS/resize-event.demo.vue | 99 +++++++++++++++++ src/data-table/demos/zhCN/index.demo-entry.md | 4 + .../demos/zhCN/resize-event.demo.vue | 100 ++++++++++++++++++ src/data-table/src/DataTable.tsx | 3 + src/data-table/src/TableParts/Header.tsx | 17 ++- src/data-table/src/interface.ts | 8 ++ 10 files changed, 250 insertions(+), 3 deletions(-) create mode 100644 src/data-table/demos/enUS/resize-event.demo.vue create mode 100644 src/data-table/demos/zhCN/resize-event.demo.vue diff --git a/CHANGELOG.en-US.md b/CHANGELOG.en-US.md index ccf50bcf260..9121ad49195 100644 --- a/CHANGELOG.en-US.md +++ b/CHANGELOG.en-US.md @@ -1,5 +1,13 @@ # CHANGELOG +## `NEXT_VERSION` + +`NEXT_VERSION` + +### Features + +- `n-data-table` adds `on-resize-start`, `on-resize` and `on-resize-end` events + ## 2.43.1 `2025-09-15` diff --git a/CHANGELOG.zh-CN.md b/CHANGELOG.zh-CN.md index 7c0e0300828..0fdf78d61e5 100644 --- a/CHANGELOG.zh-CN.md +++ b/CHANGELOG.zh-CN.md @@ -1,5 +1,13 @@ # CHANGELOG +## `NEXT_VERSION` + +`NEXT_VERSION` + +### Features + +- `n-data-table` 新增 `on-resize-start`、`on-resize` 和 `on-resize-end` 事件 + ## 2.43.1 `2025-09-15` diff --git a/build/utils/terse-cssr.ts b/build/utils/terse-cssr.ts index 252f6b46fb6..ee5011a352b 100644 --- a/build/utils/terse-cssr.ts +++ b/build/utils/terse-cssr.ts @@ -10,7 +10,7 @@ export function terseCssr(code: string): string { sourceType: 'module' }) - traverse(ast, { + traverse.default(ast, { TemplateElement(path: any) { ;(['raw', 'cooked'] as const).forEach((type) => { path.node.value[type] = path.node.value[type] diff --git a/src/data-table/demos/enUS/index.demo-entry.md b/src/data-table/demos/enUS/index.demo-entry.md index cc4bb048d90..2a1539b43cb 100644 --- a/src/data-table/demos/enUS/index.demo-entry.md +++ b/src/data-table/demos/enUS/index.demo-entry.md @@ -32,6 +32,7 @@ pagination-behavior-on-filter.vue multiple-sorter.vue custom-sorter.vue column-draggable.vue +resize-event.vue select.vue select-single.vue custom-select.vue @@ -116,6 +117,9 @@ export-csv.vue | virtual-scroll-header | `boolean` | `false` | Whether to use virtual scrolling in table header. If there are too many columns, you can enable the prop. You must configure `header-height` at the same time. Enabling the prop will disable header cells that cross columns & rows. | 2.40.0 | | virtual-scroll-x | `boolean` | `false` | Whether to use horizontal virtual scrolling in table body. If there are too many columns, you can enable the prop. Enabling the prop will disable body cells that cross columns & rows. If the prop is enabled, every column should have `width` prop configured and `virtual-scroll`, `scroll-x`, `min-row-height`, `height-for-row`, `virtual-scroll-header` (optional), `header-height` (optional) props should be configured at the same time. You can refer to the example. | 2.40.0 | | on-load | `(rowData: object) => Promise` | `undefined` | Callback of async tree data expanding. | 2.27.0 | +| on-resize-start | `(column: DataTableBaseColumn) => void` | `undefined` | Callback when column resizing starts. | NEXT_VERSION | +| on-resize | `(column: DataTableBaseColumn, width: number) => void` | `undefined` | Callback when column is being resized. | NEXT_VERSION | +| on-resize-end | `(column: DataTableBaseColumn) => void` | `undefined` | Callback when column resizing ends. | NEXT_VERSION | | on-scroll | `(e: Event) => void` | `undefined` | Callback of table body scrolling. | 2.29.1 | | on-update:checked-row-keys | `(keys: Array, rows: object[], meta: { row: object \| undefined, action: 'check' \| 'uncheck' \| 'checkAll' \| 'uncheckAll' }) => void` | `undefined` | The callback function triggered when the checked-row-keys value changes. | `rows` 2.30.5, `meta` 2.33.4 | | on-update:expanded-row-keys | `(keys: Array) => void` | `undefined` | The callback function triggered when the expanded-row-keys value changes. | | diff --git a/src/data-table/demos/enUS/resize-event.demo.vue b/src/data-table/demos/enUS/resize-event.demo.vue new file mode 100644 index 00000000000..28fd0e90c30 --- /dev/null +++ b/src/data-table/demos/enUS/resize-event.demo.vue @@ -0,0 +1,99 @@ + + # 列宽拖拽事件 + + 使用 `on-resize-start`、`on-resize` 和 `on-resize-end` 监听列宽拖拽事件。 + + + + + diff --git a/src/data-table/demos/zhCN/index.demo-entry.md b/src/data-table/demos/zhCN/index.demo-entry.md index 0ce99a0b461..1def5912116 100644 --- a/src/data-table/demos/zhCN/index.demo-entry.md +++ b/src/data-table/demos/zhCN/index.demo-entry.md @@ -34,6 +34,7 @@ pagination-behavior-on-filter.vue multiple-sorter.vue custom-sorter.vue column-draggable.vue +resize-event.vue select.vue select-single.vue custom-select.vue @@ -127,6 +128,9 @@ rtl-debug.vue | virtual-scroll-header | `boolean` | `false` | 是否打开表头的虚拟滚动,如果横向列太多,可以考虑打开此属性,打开此属性会导致表头单元格跨行列的功能不可用,同时必须要配置 `header-height` | 2.40.0 | | virtual-scroll-x | `boolean` | `false` | 是否打开表主体的横向虚拟滚动,如果横向列太多,可以考虑打开此属性,打开此属性会导致单元格跨行列的功能不可用,此属性开启时,必须要和 `virtual-scroll`、`scroll-x`、`min-row-height`、`height-for-row`、`virtual-scroll-header`、`header-height` 属性配合使用,同时每一列必须都配置 `width` 属性,你可以参考 完整的例子 | 2.40.0 | | on-load | `(rowData: object) => Promise` | `undefined` | 异步展开树形数据的回调 | 2.27.0 | +| on-resize-start | `(column: DataTableBaseColumn) => void` | `undefined` | 列宽开始拖拽时触发的回调函数 | NEXT_VERSION | +| on-resize | `(column: DataTableBaseColumn, width: number) => void` | `undefined` | 列宽拖拽中触发的回调函数 | NEXT_VERSION | +| on-resize-end | `(column: DataTableBaseColumn) => void` | `undefined` | 列宽拖拽结束时触发的回调函数 | NEXT_VERSION | | on-scroll | `(e: Event) => void` | `undefined` | 表格主体滚动的回调 | 2.29.1 | | on-update:checked-row-keys | `(keys: Array, rows: object[], meta: { row: object \| undefined, action: 'check' \| 'uncheck' \| 'checkAll' \| 'uncheckAll' }) => void` | `undefined` | checked-row-keys 值改变时触发的回调函数 | `rows` 2.30.5, `meta` 2.33.4 | | on-update:expanded-row-keys | `(keys: Array) => void` | `undefined` | expanded-row-keys 值改变时触发的回调函数 | | diff --git a/src/data-table/demos/zhCN/resize-event.demo.vue b/src/data-table/demos/zhCN/resize-event.demo.vue new file mode 100644 index 00000000000..2fb313b88c5 --- /dev/null +++ b/src/data-table/demos/zhCN/resize-event.demo.vue @@ -0,0 +1,100 @@ + +# 列宽拖拽事件 + +使用 `on-resize-start`、`on-resize` 和 `on-resize-end` 监听列宽拖拽事件。 + + + + + diff --git a/src/data-table/src/DataTable.tsx b/src/data-table/src/DataTable.tsx index 7ef8f7279bc..544951dc0a0 100644 --- a/src/data-table/src/DataTable.tsx +++ b/src/data-table/src/DataTable.tsx @@ -288,6 +288,9 @@ export default defineComponent({ doUpdateFilters, getResizableWidth, onUnstableColumnResize, + onResizeStart: props.onResizeStart, + onResize: props.onResize, + onResizeEnd: props.onResizeEnd, clearResizableWidth, doUpdateResizableWidth, deriveNextSorter, diff --git a/src/data-table/src/TableParts/Header.tsx b/src/data-table/src/TableParts/Header.tsx index dfef1ef32c6..ecaed2aef4a 100644 --- a/src/data-table/src/TableParts/Header.tsx +++ b/src/data-table/src/TableParts/Header.tsx @@ -100,6 +100,9 @@ export default defineComponent({ virtualScrollHeaderRef, headerHeightRef, onUnstableColumnResize, + onResizeStart, + onResize, + onResizeEnd, doUpdateResizableWidth, handleTableHeaderScroll, deriveNextSorter, @@ -142,6 +145,7 @@ export default defineComponent({ const resizeStartWidthMap = new Map() function handleColumnResizeStart(column: TableBaseColumn): void { resizeStartWidthMap.set(column.key, getCellActualWidth(column.key)) + onResizeStart?.(column) } function handleColumnResize( column: TableBaseColumn, @@ -164,6 +168,10 @@ export default defineComponent({ getCellActualWidth ) doUpdateResizableWidth(column, limitWidth) + onResize?.(column, limitWidth) + } + function handleColumnResizeEnd(column: TableBaseColumn): void { + onResizeEnd?.(column) } return { cellElsRef, @@ -189,7 +197,8 @@ export default defineComponent({ handleColHeaderClick, handleTableHeaderScroll, handleColumnResizeStart, - handleColumnResize + handleColumnResize, + handleColumnResizeEnd } }, render() { @@ -214,7 +223,8 @@ export default defineComponent({ handleColHeaderClick, handleCheckboxUpdateChecked, handleColumnResizeStart, - handleColumnResize + handleColumnResize, + handleColumnResizeEnd } = this let hasEllipsis = false @@ -286,6 +296,9 @@ export default defineComponent({ onResize={(displacementX) => { handleColumnResize(column as TableBaseColumn, displacementX) }} + onResizeEnd={() => { + handleColumnResizeEnd(column as TableBaseColumn) + }} /> ) : null} diff --git a/src/data-table/src/interface.ts b/src/data-table/src/interface.ts index 3029d8dcedb..92b641f8e21 100644 --- a/src/data-table/src/interface.ts +++ b/src/data-table/src/interface.ts @@ -33,6 +33,11 @@ export const dataTableProps = { getColumnWidth: (key: ColumnKey) => number | undefined ) => void >, + onResizeStart: Function as PropType<(column: TableBaseColumn) => void>, + onResize: Function as PropType< + (column: TableBaseColumn, width: number) => void + >, + onResizeEnd: Function as PropType<(column: TableBaseColumn) => void>, pagination: { type: [Object, Boolean] as PropType, default: false @@ -437,6 +442,9 @@ export interface DataTableInjection { column: TableBaseColumn, getColumnWidth: (key: ColumnKey) => number | undefined ) => void + onResizeStart: ((column: TableBaseColumn) => void) | undefined + onResize: ((column: TableBaseColumn, width: number) => void) | undefined + onResizeEnd: ((column: TableBaseColumn) => void) | undefined getResizableWidth: (key: ColumnKey) => number | undefined clearResizableWidth: () => void doUpdateResizableWidth: (column: TableColumn, width: number) => void