diff --git a/.changeset/cyan-ads-sparkle.md b/.changeset/cyan-ads-sparkle.md new file mode 100644 index 000000000..576949b41 --- /dev/null +++ b/.changeset/cyan-ads-sparkle.md @@ -0,0 +1,5 @@ +--- +"@hi-ui/hiui": patch +--- + +feat(table): Add onResizeStop api diff --git a/.changeset/grumpy-swans-sing.md b/.changeset/grumpy-swans-sing.md new file mode 100644 index 000000000..1ac21243c --- /dev/null +++ b/.changeset/grumpy-swans-sing.md @@ -0,0 +1,5 @@ +--- +"@hi-ui/table": minor +--- + +feat: virtual 模式增加 onVisibleChange api diff --git a/.changeset/plenty-jeans-guess.md b/.changeset/plenty-jeans-guess.md new file mode 100644 index 000000000..7616b750d --- /dev/null +++ b/.changeset/plenty-jeans-guess.md @@ -0,0 +1,5 @@ +--- +"@hi-ui/hiui": patch +--- + +feat(table): virtual 模式增加 onVisibleChange api diff --git a/.changeset/sharp-days-repeat.md b/.changeset/sharp-days-repeat.md new file mode 100644 index 000000000..639238c48 --- /dev/null +++ b/.changeset/sharp-days-repeat.md @@ -0,0 +1,5 @@ +--- +"@hi-ui/table": minor +--- + +feat: Add onResizeStop api diff --git a/packages/ui/table/src/BaseTable.tsx b/packages/ui/table/src/BaseTable.tsx index e0fd9845c..908ad3c29 100644 --- a/packages/ui/table/src/BaseTable.tsx +++ b/packages/ui/table/src/BaseTable.tsx @@ -17,7 +17,8 @@ import { useEmbedExpand, UseEmbedExpandProps } from './hooks/use-embed-expand' import { TheadContent } from './TheadContent' import { ColGroupContent } from './ColGroupContent' import { TbodyContent } from './TbodyContent' -import { SELECTION_DATA_KEY } from './Table'; +import { SELECTION_DATA_KEY } from './Table' +import { ResizeCallbackData } from 'react-resizable' const _role = 'table' const _prefix = getPrefixCls('table') @@ -52,6 +53,7 @@ export const BaseTable = forwardRef( emptyContent, virtual, needDoubleTable, + onResizeStop, ...rest }, ref @@ -151,7 +153,7 @@ export const BaseTable = forwardRef( let hasSumColumn = false columns.forEach((column, index) => { - if (index === 0 || (index === 1 && columns[0].dataKey === SELECTION_DATA_KEY)) { + if (index === 0 || (index === 1 && columns[0].dataKey === SELECTION_DATA_KEY)) { // @ts-ignore sumRow.raw[column.dataKey] = i18n.get('table.total') } @@ -312,6 +314,7 @@ export const BaseTable = forwardRef( sumRow, hasSumColumn, virtual, + onResizeStop, }} > {renderTable()} @@ -368,8 +371,18 @@ export interface BaseTableProps fixedColumnTrigger?: 'auto' | 'always' /** * 是否需要使用双表格 + * @private */ needDoubleTable?: boolean + /** + * resizable 模式下,列宽变化后触发的回调 + */ + onResizeStop?: ( + evt: React.SyntheticEvent, + size: ResizeCallbackData['size'], + index: number, + columnsWidth: number[] + ) => void } if (__DEV__) { diff --git a/packages/ui/table/src/TableBody.tsx b/packages/ui/table/src/TableBody.tsx index 3c9bb1cc7..962d493c8 100644 --- a/packages/ui/table/src/TableBody.tsx +++ b/packages/ui/table/src/TableBody.tsx @@ -58,7 +58,8 @@ export const TableBody = forwardRef( if (virtual) { // TODO: avg和summay row的逻辑 - const realHeight = (virtualListRef.current as (HTMLTableElement | null))?.getBoundingClientRect().height + const realHeight = (virtualListRef.current as HTMLTableElement | null)?.getBoundingClientRect() + .height const maxHeightNumStr = String(maxHeight).replace(/px$/, '') const vMaxHeight = maxHeight ? !isNaN(Number(maxHeightNumStr)) @@ -86,7 +87,10 @@ export const TableBody = forwardRef( style={{ height: 2, marginTop: -1, background: 'transparent', width: rowWidth }} > {isArrayNonEmpty(transitionData) ? ( -
+
( fullHeight={false} itemHeight={10} itemKey="id" + onVisibleChange={(...args) => { + isObject(virtual) && + typeof virtual?.onVisibleChange === 'function' && + virtual?.onVisibleChange(...args) + }} children={(row, index) => { return (
getStickyColProps, showColMenu, setHeaderTableElement, + onResizeStop, } = useTableContext() const activeColumnKeysAction = useCheckState() @@ -97,6 +98,9 @@ export const TheadContent = forwardRef onResize={(evt, options) => { onColumnResizable(evt, options, colIndex) }} + onResizeStop={(evt, options) => { + onResizeStop?.(evt, options?.size, colIndex, colWidths) + }} > {cell} diff --git a/packages/ui/table/src/context.ts b/packages/ui/table/src/context.ts index 61be15a37..d71311156 100644 --- a/packages/ui/table/src/context.ts +++ b/packages/ui/table/src/context.ts @@ -1,8 +1,9 @@ -import { createContext, useContext } from 'react' +import { createContext, SyntheticEvent, useContext } from 'react' import { UseEmbedExpandReturn } from './hooks/use-embed-expand' import { UseTableReturn } from './use-table' import { TableOnRowReturn } from './types' +import { ResizeCallbackData } from 'react-resizable' const TableContext = createContext< | (Omit & @@ -13,7 +14,26 @@ const TableContext = createContext< hasSumColumn: boolean onRow?: (rowData: Record | null, index: number) => TableOnRowReturn striped: boolean - virtual?: boolean + virtual?: + | boolean + | { + onVisibleChange?: ( + visibleList: any[], + fullList: any[], + virtualInfo?: { + start: number + end: number + scrollTop: number + heights: number[] + } + ) => void + } + onResizeStop?: ( + evt: SyntheticEvent, + size: ResizeCallbackData['size'], + index: number, + columnsWidth: number[] + ) => void }) | null >(null) diff --git a/packages/ui/table/src/hooks/use-col-width.ts b/packages/ui/table/src/hooks/use-col-width.ts index 2b7562bda..704aa484c 100644 --- a/packages/ui/table/src/hooks/use-col-width.ts +++ b/packages/ui/table/src/hooks/use-col-width.ts @@ -221,7 +221,7 @@ export const useColWidth = ({ * 列宽拖拽 resize,只处理拖拽线两边的列宽度 */ const onColumnResizable = React.useCallback( - (_, { size }, index: number) => { + (evt, { size }, index: number) => { const minWidth = minColWidth[index] const anotherMinWidth = minColWidth[index + 1] let nextWidth = size.width > minWidth ? size.width : minWidth diff --git a/packages/ui/table/src/use-table.ts b/packages/ui/table/src/use-table.ts index 24cbd7f6a..40cf1295b 100644 --- a/packages/ui/table/src/use-table.ts +++ b/packages/ui/table/src/use-table.ts @@ -192,7 +192,7 @@ export const useTable = ({ data, columns, resizable, - virtual: virtual, + virtual: !!virtual, }) // ************************ 列冻结 ************************ // @@ -776,7 +776,20 @@ export interface UseTableProps { * -Cell: colspan,rowspan * -统计:平局行,总数行 */ - virtual?: boolean + virtual?: + | boolean + | { + onVisibleChange?: ( + visibleList: any[], + fullList: any[], + virtualInfo?: { + start: number + end: number + scrollTop: number + heights: number[] + } + ) => void + } /** * 加载中状态 */ diff --git a/packages/ui/table/stories/resizable.stories.tsx b/packages/ui/table/stories/resizable.stories.tsx index a9be2c14f..50dbf4f56 100644 --- a/packages/ui/table/stories/resizable.stories.tsx +++ b/packages/ui/table/stories/resizable.stories.tsx @@ -13,6 +13,9 @@ export const Resizable = () => { { + console.log('onResizeStop', e, data, index, columnsWidth) + }} columns={[ { title: '商品名', diff --git a/packages/ui/table/stories/virtual.stories.tsx b/packages/ui/table/stories/virtual.stories.tsx index ea16f9703..e20a662a0 100644 --- a/packages/ui/table/stories/virtual.stories.tsx +++ b/packages/ui/table/stories/virtual.stories.tsx @@ -55,6 +55,11 @@ export const Virtual = () => { columns={column} data={data} virtual={true} + // virtual={{ + // onVisibleChange(...args) { + // console.log('onVisibleChange', ...args) + // }, + // }} fixedToColumn={{ right: 'operation' }} /> diff --git a/patches/rc-virtual-list+3.4.8.patch b/patches/rc-virtual-list+3.4.8.patch index c7f54b4d6..0bfa42f94 100644 --- a/patches/rc-virtual-list+3.4.8.patch +++ b/patches/rc-virtual-list+3.4.8.patch @@ -1,5 +1,41 @@ +diff --git a/node_modules/rc-virtual-list/es/List.d.ts b/node_modules/rc-virtual-list/es/List.d.ts +index 116f737..6480fef 100644 +--- a/node_modules/rc-virtual-list/es/List.d.ts ++++ b/node_modules/rc-virtual-list/es/List.d.ts +@@ -28,7 +28,12 @@ export interface ListProps extends Omit, 'children' + virtual?: boolean; + onScroll?: React.UIEventHandler; + /** Trigger when render list item changed */ +- onVisibleChange?: (visibleList: T[], fullList: T[]) => void; ++ onVisibleChange?: (visibleList: T[], fullList: T[], virtualInfo: { ++ start: number ++ end: number ++ scrollTop: number ++ heights: number[] ++ }) => void; + } + export declare function RawList(props: ListProps, ref: React.Ref): JSX.Element; + declare const _default: (props: ListProps & { +diff --git a/node_modules/rc-virtual-list/es/List.js b/node_modules/rc-virtual-list/es/List.js +index ff61435..768eafe 100644 +--- a/node_modules/rc-virtual-list/es/List.js ++++ b/node_modules/rc-virtual-list/es/List.js +@@ -309,7 +309,12 @@ export function RawList(props, ref) { + useLayoutEffect(function () { + if (onVisibleChange) { + var renderList = mergedData.slice(start, end + 1); +- onVisibleChange(renderList, mergedData); ++ onVisibleChange(renderList, mergedData, { ++ start, ++ end, ++ scrollTop, ++ heights, ++ }); + } + }, [start, end, mergedData]); // ================================ Render ================================ + diff --git a/node_modules/rc-virtual-list/es/hooks/useHeights.js b/node_modules/rc-virtual-list/es/hooks/useHeights.js -index 2557625..e81f056 100644 +index 2557625..71d2cef 100644 --- a/node_modules/rc-virtual-list/es/hooks/useHeights.js +++ b/node_modules/rc-virtual-list/es/hooks/useHeights.js @@ -15,6 +15,18 @@ import { useRef, useEffect } from 'react'; @@ -35,8 +71,44 @@ index 2557625..e81f056 100644 } } }); // Always trigger update mark to tell parent that should re-calculate heights when resized +diff --git a/node_modules/rc-virtual-list/lib/List.d.ts b/node_modules/rc-virtual-list/lib/List.d.ts +index 116f737..6480fef 100644 +--- a/node_modules/rc-virtual-list/lib/List.d.ts ++++ b/node_modules/rc-virtual-list/lib/List.d.ts +@@ -28,7 +28,12 @@ export interface ListProps extends Omit, 'children' + virtual?: boolean; + onScroll?: React.UIEventHandler; + /** Trigger when render list item changed */ +- onVisibleChange?: (visibleList: T[], fullList: T[]) => void; ++ onVisibleChange?: (visibleList: T[], fullList: T[], virtualInfo: { ++ start: number ++ end: number ++ scrollTop: number ++ heights: number[] ++ }) => void; + } + export declare function RawList(props: ListProps, ref: React.Ref): JSX.Element; + declare const _default: (props: ListProps & { +diff --git a/node_modules/rc-virtual-list/lib/List.js b/node_modules/rc-virtual-list/lib/List.js +index 5d191af..26dbc70 100644 +--- a/node_modules/rc-virtual-list/lib/List.js ++++ b/node_modules/rc-virtual-list/lib/List.js +@@ -337,7 +337,12 @@ function RawList(props, ref) { + (0, _useLayoutEffect.default)(function () { + if (onVisibleChange) { + var renderList = mergedData.slice(start, end + 1); +- onVisibleChange(renderList, mergedData); ++ onVisibleChange(renderList, mergedData, { ++ start, ++ end, ++ scrollTop, ++ heights, ++ }); + } + }, [start, end, mergedData]); // ================================ Render ================================ + diff --git a/node_modules/rc-virtual-list/lib/hooks/useHeights.js b/node_modules/rc-virtual-list/lib/hooks/useHeights.js -index 13d5d07..8f9e56c 100644 +index 13d5d07..592ee02 100644 --- a/node_modules/rc-virtual-list/lib/hooks/useHeights.js +++ b/node_modules/rc-virtual-list/lib/hooks/useHeights.js @@ -33,6 +33,17 @@ function _iterableToArrayLimit(arr, i) { var _i = arr == null ? null : typeof Sy