Skip to content

Commit

Permalink
feat(table): resizable模式下设置最小列宽 (#2639)
Browse files Browse the repository at this point in the history
  • Loading branch information
zyprepare committed Oct 30, 2023
1 parent 92fc9f5 commit 54387a8
Show file tree
Hide file tree
Showing 7 changed files with 153 additions and 22 deletions.
5 changes: 5 additions & 0 deletions .changeset/blue-glasses-nail.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@hi-ui/hiui": patch
---

Table perf: 优化 resizable 模式下可调整的最小宽度
5 changes: 5 additions & 0 deletions .changeset/silent-lions-yawn.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@hi-ui/table": patch
---

perf: 优化 resizable 模式下可调整的最小宽度
11 changes: 9 additions & 2 deletions packages/ui/table/src/TheadContent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ export const TheadContent = forwardRef<HTMLDivElement | null, TheadContentProps>
onColumnResizable,
getStickyColProps,
showColMenu,
setHeaderTableElement,
} = useTableContext()

const activeColumnKeysAction = useCheckState()
Expand All @@ -30,10 +31,16 @@ export const TheadContent = forwardRef<HTMLDivElement | null, TheadContentProps>
{/* 渲染列 */}
{groupedColumns.map((cols, colsIndex) => {
return (
<tr key={colsIndex}>
<tr key={colsIndex} ref={setHeaderTableElement}>
{cols.map((col, colIndex) => {
const { dataKey, title, raw } = col || {}
const titleContent = isFunction(title) ? title(col) : title
let titleContent = isFunction(title) ? title(col) : title

titleContent = resizable ? (
<span className={`${prefixCls}-header__title`}>{titleContent}</span>
) : (
titleContent
)

const cell = (
<th
Expand Down
41 changes: 24 additions & 17 deletions packages/ui/table/src/hooks/use-col-width.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,39 +95,46 @@ export const useColWidth = ({
// 测量元素在内容列为空时会是空,切换会使测量元素变化,导致后续的resize时间无法响应,此处测量元素变化时需要重新绑定
}, [getVirtualWidths, virtual])

const [headerTableElement, setHeaderTableElement] = React.useState<HTMLTableElement | null>(null)
const [headerTableElement, setHeaderTableElement] = React.useState<HTMLTableRowElement | null>(
null
)

/**
* 控制列最小可调整宽度
*/
const minColWidth = React.useMemo(() => {
if (
headerTableElement &&
headerTableElement.childNodes &&
headerTableElement.childNodes[1].childNodes[0]
) {
const _minColWidth = Array.from(
headerTableElement.childNodes[1].childNodes[0].childNodes
).map((th) => {
// @ts-ignore
return th.childNodes[0].className === 'hi-table__header__title'
? // @ts-ignore
th.childNodes[0].offsetWidth
: 0
if (resizable && headerTableElement) {
const resizableHandlerWidth = 4
const _minColWidth = Array.from(headerTableElement.childNodes).map((th) => {
const thPaddingLeft = parseFloat(
window.getComputedStyle(th as Element).getPropertyValue('padding-left')
)
const childNodes = Array.from(th.childNodes)

return (
childNodes
.map((child) => (child as HTMLElement).offsetWidth)
.reduce((prev, next) => {
return prev + next
}) +
thPaddingLeft * 2 +
resizableHandlerWidth
)
})

return _minColWidth
}

return Array(columns.length).fill(0)
}, [columns, headerTableElement])
}, [columns.length, headerTableElement, resizable])

/**
* 列宽拖拽 resize,只处理拖拽线两边的列宽度
*/
const onColumnResizable = React.useCallback(
(_, { size }, index: number) => {
const minWidth = minColWidth[index] + 31
const anotherMinWidth = minColWidth[index + 1] + 31
const minWidth = minColWidth[index]
const anotherMinWidth = minColWidth[index + 1]
let nextWidth = size.width > minWidth ? size.width : minWidth

setColWidths((prev) => {
Expand Down
9 changes: 8 additions & 1 deletion packages/ui/table/src/use-table.ts
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,13 @@ export const useTable = ({

// ************************ 列宽 resizable ************************ //

const { measureRowElementRef, getColgroupProps, onColumnResizable, colWidths } = useColWidth({
const {
measureRowElementRef,
getColgroupProps,
onColumnResizable,
colWidths,
setHeaderTableElement,
} = useColWidth({
data,
columns,
resizable,
Expand Down Expand Up @@ -635,6 +641,7 @@ export const useTable = ({
cellRender,
showColMenu,
onLoadChildren,
setHeaderTableElement,
}
}

Expand Down
52 changes: 50 additions & 2 deletions packages/ui/table/stories/custom-filter.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import Table from '../src'
import Input from '@hi-ui/input'
import Button from '@hi-ui/button'
import CheckSelect from '@hi-ui/check-select'
import EllipsisTooltip from '@hi-ui/ellipsis-tooltip'

/**
* @title 自定义过滤
Expand Down Expand Up @@ -162,6 +163,9 @@ export const CustomFilter = () => {
</div>
)
},
render(text) {
return <EllipsisTooltip>{text}</EllipsisTooltip>
},
},
{
title: 'Age',
Expand All @@ -174,7 +178,7 @@ export const CustomFilter = () => {
},
{
title: (
<div>
<div style={{ display: 'inline-flex', alignItems: 'center' }}>
Home phone
<CheckSelect
style={{ width: 'auto', marginLeft: 2 }}
Expand All @@ -194,81 +198,117 @@ export const CustomFilter = () => {
),
colSpan: 2,
width: 180,
render(text) {
return <EllipsisTooltip>{text}</EllipsisTooltip>
},
dataKey: 'tel',
key: 3,
},
{
title: 'Home phone1',
dataKey: 'tel1',
width: 180,
render(text) {
return <EllipsisTooltip>{text}</EllipsisTooltip>
},
key: 4,
},
{
title: 'Home phone2',
colSpan: 2,
width: 180,
render(text) {
return <EllipsisTooltip>{text}</EllipsisTooltip>
},
dataKey: 'tel2',
key: 5,
},
{
title: 'Home phone3',
width: 180,
render(text) {
return <EllipsisTooltip>{text}</EllipsisTooltip>
},
colSpan: 2,
dataKey: 'tel3',
key: 6,
},
{
title: 'Home phone4',
width: 180,
render(text) {
return <EllipsisTooltip>{text}</EllipsisTooltip>
},
colSpan: 2,
dataKey: 'tel4',
key: 7,
},
{
title: 'Home phone5',
width: 180,
render(text) {
return <EllipsisTooltip>{text}</EllipsisTooltip>
},
colSpan: 2,
dataKey: 'tel5',
key: 8,
},
{
title: 'Home phone6',
width: 180,
render(text) {
return <EllipsisTooltip>{text}</EllipsisTooltip>
},
colSpan: 2,
dataKey: 'tel6',
key: 9,
},
{
title: 'Home phone7',
width: 180,
render(text) {
return <EllipsisTooltip>{text}</EllipsisTooltip>
},
colSpan: 2,
dataKey: 'tel7',
key: 10,
},
{
title: 'Home phone8',
width: 180,
render(text) {
return <EllipsisTooltip>{text}</EllipsisTooltip>
},
colSpan: 2,
dataKey: 'tel8',
key: 11,
},
{
title: 'Home phone9',
width: 180,
render(text) {
return <EllipsisTooltip>{text}</EllipsisTooltip>
},
colSpan: 2,
dataKey: 'tel9',
key: 12,
},
{
title: 'Home phone10',
width: 180,
render(text) {
return <EllipsisTooltip>{text}</EllipsisTooltip>
},
colSpan: 2,
dataKey: 'tel10',
key: 13,
},
{
title: 'Home phone11',
width: 180,
render(text) {
return <EllipsisTooltip>{text}</EllipsisTooltip>
},
colSpan: 2,
dataKey: 'tel11',
key: 14,
Expand All @@ -277,15 +317,20 @@ export const CustomFilter = () => {
{
title: 'Home phone12',
width: 180,
render(text) {
return <EllipsisTooltip>{text}</EllipsisTooltip>
},
colSpan: 2,
dataKey: 'tel12',
key: 15,
},

{
title: 'Phone',
dataKey: 'phone',
width: 180,
render(text) {
return <EllipsisTooltip>{text}</EllipsisTooltip>
},
key: 16,
sorter(pre, next) {
return pre.phone - next.phone
Expand All @@ -294,6 +339,9 @@ export const CustomFilter = () => {
{
title: 'Address',
width: 240,
render(text) {
return <EllipsisTooltip>{text}</EllipsisTooltip>
},
dataKey: 'address',
key: 17,
},
Expand Down
Loading

0 comments on commit 54387a8

Please sign in to comment.