diff --git a/.changeset/beige-months-poke.md b/.changeset/beige-months-poke.md new file mode 100644 index 000000000..63d1a15cb --- /dev/null +++ b/.changeset/beige-months-poke.md @@ -0,0 +1,6 @@ +--- +"@hi-ui/table": minor +"@hi-ui/hiui": minor +--- + +feat(table): add tableWidthAdjustOnResize api (#3046) diff --git a/packages/ui/table/src/hooks/use-col-width.ts b/packages/ui/table/src/hooks/use-col-width.ts index 704aa484c..52f638d4e 100644 --- a/packages/ui/table/src/hooks/use-col-width.ts +++ b/packages/ui/table/src/hooks/use-col-width.ts @@ -5,11 +5,13 @@ import { useUpdateEffect } from '@hi-ui/use-update-effect' export const useColWidth = ({ resizable, + tableWidthAdjustOnResize, data, columns, virtual, }: { resizable: boolean + tableWidthAdjustOnResize: boolean data: TableRowRecord[] columns: TableColumnItem[] virtual?: boolean @@ -119,7 +121,7 @@ export const useColWidth = ({ const measureRowElement = measureRowElementRef.current if (measureRowElement) { - const resizeObserver = new ResizeObserver(() => { + resizeObserver = new ResizeObserver(() => { if (virtual) { setColWidths(getVirtualWidths()) } else { @@ -136,9 +138,7 @@ export const useColWidth = ({ } return () => { - if (resizeObserver) { - resizeObserver.disconnect() - } + resizeObserver?.disconnect() } // 测量元素在内容列为空时会是空,切换会使测量元素变化,导致后续的resize时间无法响应,此处测量元素变化时需要重新绑定 }, [columns, getVirtualWidths, getWidths, virtual]) @@ -182,9 +182,7 @@ export const useColWidth = ({ } return () => { - if (resizeObserver) { - resizeObserver.disconnect() - } + resizeObserver?.disconnect() } }, [columns.length, headerTableElement, resizable]) @@ -228,6 +226,12 @@ export const useColWidth = ({ setColWidths((prev) => { const nextColWidths = [...prev] + + if (tableWidthAdjustOnResize) { + nextColWidths[index] = nextWidth + return nextColWidths + } + let anotherWidth = nextColWidths[index + 1]! + nextColWidths[index]! - nextWidth if (anotherWidth <= anotherMinWidth) { @@ -240,7 +244,7 @@ export const useColWidth = ({ return nextColWidths }) }, - [minColWidth] + [minColWidth, tableWidthAdjustOnResize] ) const getColgroupProps = React.useCallback( diff --git a/packages/ui/table/src/styles/table.scss b/packages/ui/table/src/styles/table.scss index 130eb92ad..c03f4c448 100644 --- a/packages/ui/table/src/styles/table.scss +++ b/packages/ui/table/src/styles/table.scss @@ -186,6 +186,7 @@ $emptyContent: '#{$component-prefix}-table-body-empty-content' !default; .#{$prefix}-header__resizable-handle { border-left-color: use-color('gray', 200); + border-right-color: use-color('gray', 200); } } @@ -196,7 +197,9 @@ $emptyContent: '#{$component-prefix}-table-body-empty-content' !default; height: 100%; bottom: 0; right: 0; - border-left: 2px solid use-color('gray', 50); + margin-right: -2px; + border-left: 2px solid transparent; + border-right: 2px solid transparent; cursor: col-resize; z-index: 1; @@ -207,6 +210,7 @@ $emptyContent: '#{$component-prefix}-table-body-empty-content' !default; &:hover { background-color: use-color-mode('primary'); border-left-color: use-color('gray', 200); + border-right-color: use-color('gray', 200); } } } diff --git a/packages/ui/table/src/use-table.ts b/packages/ui/table/src/use-table.ts index 94ab60914..76495cf89 100644 --- a/packages/ui/table/src/use-table.ts +++ b/packages/ui/table/src/use-table.ts @@ -54,6 +54,7 @@ export const useTable = ({ onFixedToColumn, scrollWidth, resizable = false, + tableWidthAdjustOnResize = false, // highlight errorRowKeys = DEFAULT_ERROR_ROW_KEYS, highlightedColKeys: highlightedColKeysProp, @@ -197,6 +198,7 @@ export const useTable = ({ data, columns, resizable, + tableWidthAdjustOnResize, virtual: !!virtual, }) @@ -778,6 +780,11 @@ export interface UseTableProps { * 是否能够动态控制列宽 */ resizable?: boolean + /** + * 调整列宽时是否改变表格宽度,在 resizable 模式下生效 + * @private + */ + tableWidthAdjustOnResize?: boolean /** * 是否支持虚拟滚动, * 列宽:column设置的width或200作为宽度,内容区填充不满时,宽度等比分配。 diff --git a/packages/ui/table/stories/data-sorter.stories.tsx b/packages/ui/table/stories/data-sorter.stories.tsx index 7db12381d..826119563 100644 --- a/packages/ui/table/stories/data-sorter.stories.tsx +++ b/packages/ui/table/stories/data-sorter.stories.tsx @@ -220,15 +220,11 @@ export const DataSorter = () => { }, ]) - const onChange = (pagination, sorter, extra) => { - console.log(pagination, sorter, extra) - } - return ( <>

DataSorter for Table

- +
) diff --git a/packages/ui/table/stories/scrollbar.stories.tsx b/packages/ui/table/stories/scrollbar.stories.tsx index cb40987b6..6d6e439a0 100644 --- a/packages/ui/table/stories/scrollbar.stories.tsx +++ b/packages/ui/table/stories/scrollbar.stories.tsx @@ -345,6 +345,19 @@ export const Scrollbar = () => { }, ]) + const scrollbarInnerRef = React.useRef(null) + const update = () => scrollbarInnerRef.current?.update?.() + + // 在外部滚动时更新 Scrollbar 滚动条的位置 + // 该处理是针对 scrollbarXStickToBottom 参数为 true 的情况,让滚动条始终保持在底部,详见 Scrollbar 组件文档 + React.useEffect(() => { + document.addEventListener('scroll', update) + + return () => { + document.removeEventListener('scroll', update) + } + }, []) + return ( <>

Scrollbar for Table

@@ -359,13 +372,14 @@ export const Scrollbar = () => { { // 保持滚动条始终可见 keepVisible: true, + innerRef: scrollbarInnerRef, // 设置滚动条的 z-index 值 zIndex: 9, settings: { // 垂直滑动时,让横向滚动条一直显示在容器底部 - // scrollbarXStickToBottom: true, + scrollbarXStickToBottom: true, // 横向滚动条距离底部的距离 - // scrollbarXStickToBottomGap: 20, + scrollbarXStickToBottomGap: 20, }, } } diff --git a/stories/Introduction.stories.mdx b/stories/Introduction.stories.mdx index 4ab9fc303..045155307 100644 --- a/stories/Introduction.stories.mdx +++ b/stories/Introduction.stories.mdx @@ -1,6 +1,6 @@ import { Meta } from "@storybook/addon-docs/blocks"; - +