Skip to content

Commit

Permalink
fix: defaultValue not work
Browse files Browse the repository at this point in the history
  • Loading branch information
hemengke1997 committed Jan 5, 2023
1 parent 5f0fb07 commit 91d8b3f
Show file tree
Hide file tree
Showing 9 changed files with 85 additions and 58 deletions.
22 changes: 14 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ pnpm add @minko-fe/use-antd-resizable-header
| maxConstraints | number | Infinity | 拖动最大宽度 默认无穷 |
| cache | boolean | true | 是否缓存宽度,避免渲染重置拖拽宽度 |
| columnsState | ColumnsStateType | undefined | 列状态的配置,可以用来操作列拖拽宽度 |
| onResizeStart | Function | undefined | 开始拖拽时触发
| onResizeEnd | Function | undefined | 结束拖拽时触发
| onResizeStart | Function | undefined | 开始拖拽时触发 |
| onResizeEnd | Function | undefined | 结束拖拽时触发 |

### Return

Expand Down Expand Up @@ -71,12 +71,7 @@ function App() {
return (
<>
<Table columns={resizableColumns} components={components} dataSource={data} scroll={{ x: tableWidth }} />
<ProTable
columns={resizableColumns}
components={components}
dataSource={data}
scroll={{ x: tableWidth }}
/>
<ProTable columns={resizableColumns} components={components} dataSource={data} scroll={{ x: tableWidth }} />
<Button onClick={() => resetColumns()}>重置宽度</Button>
</>
)
Expand Down Expand Up @@ -304,6 +299,17 @@ function App() {

可以采用其他阻止 render 的方案,如: `columns` 是 prop 或 组件外常量

## ProTable 需要特殊处理的点

### fixed

[ProTable 默认会给 fixed 列添加宽度](https://github.com/ant-design/pro-components/blob/master/packages/table/src/utils/genProColumnToColumn.tsx#L115-L116),所以可能会造成 `至少一列宽度为0` 的条件无法满足。

#### 解决方案

1. 手动给 fixed 列添加宽度,然后不设置其余某一个非 fixed 列宽度
2. 不设置 fixed 列宽度(默认 200),然后其余某一列也不设置宽度

## MIT

[LICENSE](https://github.com/hemengke1997/use-antd-resizable-header/blob/master/LICENSE)
13 changes: 9 additions & 4 deletions example/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,14 @@ function App() {
() => [
{
title: 'Name',
width: 100,
dataIndex: 'name',
key: 'name',
fixed: 'left',
width: 300,
filters: [
{ text: 'test', value: '1' },
{ text: 'test2', value: '2' },
],
defaultFilteredValue: ['1'],
},
{
title: 'Age',
Expand All @@ -49,8 +53,10 @@ function App() {
},
{
title: 'Column 1',
width: 100,
dataIndex: 'address',
},

{
title: 'test render',
dataIndex: 'testRender',
Expand All @@ -63,7 +69,6 @@ function App() {
title: 'Action',
key: 'operation',
fixed: 'right',
width: 100,
render: (_, record) => {
return <span>{record?.age}</span>
},
Expand Down Expand Up @@ -119,10 +124,10 @@ function App() {
title: 'Action',
key: 'operation',
fixed: 'right',
width: 100,
render: (_, record) => {
return <span>{record?.age}</span>
},
width: 100,
},
],
[x],
Expand Down
27 changes: 18 additions & 9 deletions src/ResizableHeader.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import type { ThHTMLAttributes } from 'react'
import React from 'react'
import type { FC, ThHTMLAttributes } from 'react'
import { memo, useEffect, useRef } from 'react'
import type { ResizeCallbackData } from 'react-resizable'
import { Resizable } from 'react-resizable'
import { isString } from 'lodash-es'
import { useSafeState } from './utils/useSafeState'

import './index.css'
Expand All @@ -17,7 +18,7 @@ type ComponentProp = {
maxWidth: number
} & ThHTMLAttributes<HTMLTableCellElement>

const ResizableHeader: React.FC<ComponentProp> = (props) => {
const ResizableHeader: FC<ComponentProp> = (props) => {
const {
width,
minWidth,
Expand All @@ -34,21 +35,22 @@ const ResizableHeader: React.FC<ComponentProp> = (props) => {
rowSpan,
colSpan,
title,
scope,
...rest
} = props

const thRef = React.useRef<HTMLTableCellElement>(null)
const thRef = useRef<HTMLTableCellElement>(null)

const [resizeWidth, setResizeWidth] = useSafeState<number>(0)

React.useEffect(() => {
useEffect(() => {
if (width) {
setResizeWidth(width)
onMount?.(width)
}
}, [triggerRender])

React.useEffect(() => {
useEffect(() => {
if (width) {
setResizeWidth(width)
}
Expand Down Expand Up @@ -93,9 +95,16 @@ const ResizableHeader: React.FC<ComponentProp> = (props) => {
onResizeEnd?.(resizeWidth)
}

const isSimpleChildren = () => {
if (Array.isArray(children)) {
return isString(children[children.length - 1])
}
return false
}

return (
<th
scope='col'
scope={scope}
className={`resizable-container ${className}`}
style={{
...style,
Expand Down Expand Up @@ -130,12 +139,12 @@ const ResizableHeader: React.FC<ComponentProp> = (props) => {
>
<div style={{ width: resizeWidth, height: '100%' }} />
</Resizable>
<div {...rest} className='resizable-title'>
<div {...rest} className={`resizable-title ${isSimpleChildren() ? 'ellipsis' : ''}`}>
<span title={title}>{children}</span>
</div>
</th>
)
}

// eslint-disable-next-line no-restricted-syntax
export default React.memo(ResizableHeader)
export default memo(ResizableHeader)
10 changes: 6 additions & 4 deletions src/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
position: absolute;
right: -5px;
bottom: 0;
z-index: 3;
z-index: 2;
display: flex;
justify-content: center;
width: 10px;
Expand Down Expand Up @@ -52,9 +52,11 @@
}

.resizable-title {
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
position: relative;
z-index: 0;
&.ellipsis {
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
}
}
53 changes: 29 additions & 24 deletions src/useAntdResizableHeader.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import React from 'react'
import type { ReactNode } from 'react'
import { useCallback, useEffect, useMemo, useReducer, useRef } from 'react'
import { isEmpty } from 'lodash-es'
import ResizableHeader from './ResizableHeader'
import { useThrottleEffect } from './utils/useThrottleEffect'
Expand Down Expand Up @@ -48,9 +49,9 @@ type Width = number | string

export interface ColumnOriginType<T> {
width?: Width
dataIndex?: React.Key
key?: React.Key
title?: React.ReactNode | string
dataIndex?: string | number
key?: string | number
title?: ReactNode | string
children?: T[]
resizable?: boolean
ellipsis?: any
Expand Down Expand Up @@ -80,9 +81,9 @@ function useAntdResizableHeader<ColumnType extends ColumnOriginType<ColumnType>>

// column的宽度缓存,避免render导致columns宽度重置
// add column width cache to avoid column's width reset after render
const widthCache = React.useRef<Map<React.Key, CacheType>>(new Map())
const widthCache = useRef<Map<string | number, CacheType>>(new Map())

const [resizableColumns, setResizableColumns] = useSafeState<ColumnType[]>([])
const [resizableColumns, setResizableColumns] = useSafeState<ColumnType[]>(columnsProp || []) // keep all default vlaue (e.g. defaultFilterValue)

const lastestColumns = useLatest(resizableColumns)

Expand All @@ -94,21 +95,19 @@ function useAntdResizableHeader<ColumnType extends ColumnOriginType<ColumnType>>

const [tableWidth, setTableWidth] = useSafeState<number>()

const [triggerRender, forceRender] = React.useReducer((s) => s + 1, 0)
const [triggerRender, forceRender] = useReducer((s) => s + 1, 0)

const resetColumns = useMemoizedFn(() => {
widthCache.current = new Map()
resetLocalColumns()
})

const onMount = React.useCallback(
(id: React.Key | undefined) => (width?: number) => {
const onMount = useCallback(
(id?: string | number) => (width?: number) => {
if (width) {
setResizableColumns((t) => {
const nextColumns = depthFirstSearch(t, (col) => col[GETKEY] === id, width)

const kvMap = new Map<React.Key, CacheType>()

const nextColumns = depthFirstSearch(t, (col) => col[GETKEY] === id && !!col.width, width)
const kvMap = new Map<string | number, CacheType>()
function dig(cols: ColumnType[]) {
cols.forEach((col, i) => {
const key = col[GETKEY]
Expand All @@ -118,19 +117,16 @@ function useAntdResizableHeader<ColumnType extends ColumnOriginType<ColumnType>>
}
})
}

dig(nextColumns)

widthCache.current = kvMap

return nextColumns
})
}
},
[setResizableColumns],
[],
)

const onResize = React.useMemo(() => onMount, [onMount])
const onResize = useMemo(() => onMount, [onMount])

const onResizeStart = (col: ColumnType) => (width: number) => {
onResizeStartProp?.({
Expand All @@ -150,14 +146,23 @@ function useAntdResizableHeader<ColumnType extends ColumnOriginType<ColumnType>>

const getColumns = useMemoizedFn((list: ColumnType[]) => {
const trulyColumns = list?.filter((item) => !isEmpty(item))

const c = trulyColumns.map((col) => {
return {
...col,
children: col?.children?.length ? getColumns(col.children) : undefined,
onHeaderCell: (column: ColumnType) => {
const columnWidth = () => {
const colWitdh = col.width && column.width
if (cache) {
return widthCache.current?.get(column[GETKEY] ?? '')?.width || colWitdh
}
return colWitdh
}

return {
title: typeof col?.title === 'string' ? col?.title : '',
width: cache ? widthCache.current?.get(column[GETKEY] ?? '')?.width || column?.width : column?.width,
width: columnWidth(),
resizable: column.resizable,
onMount: onMount(column?.[GETKEY]),
onResize: onResize(column?.[GETKEY]),
Expand All @@ -177,12 +182,12 @@ function useAntdResizableHeader<ColumnType extends ColumnOriginType<ColumnType>>
return c
})

React.useEffect(() => {
useEffect(() => {
if (columns) {
const c = getColumns(columns)
setResizableColumns(c)
}
}, [columns, getColumns, setResizableColumns])
}, [columns, getColumns])

useThrottleEffect(
() => {
Expand All @@ -195,7 +200,7 @@ function useAntdResizableHeader<ColumnType extends ColumnOriginType<ColumnType>>
},
)

React.useEffect(() => {
useEffect(() => {
let width = 0

;(function loop(cls: ColumnType[]) {
Expand All @@ -215,14 +220,14 @@ function useAntdResizableHeader<ColumnType extends ColumnOriginType<ColumnType>>

const { run: debounceRender } = useDebounceFn(forceRender)

React.useEffect(() => {
useEffect(() => {
window.addEventListener('resize', debounceRender)
return () => {
window.removeEventListener('resize', debounceRender)
}
}, [debounceRender])

const components = React.useMemo(() => {
const components = useMemo(() => {
return {
header: {
cell: ResizableHeader,
Expand Down
4 changes: 2 additions & 2 deletions src/utils/useDebounceFn.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useRef } from 'react'
import { useEffect, useRef } from 'react'
import { debounce } from 'lodash-es'
import { useCreation } from './useCreation'
import type { Options } from './options'
Expand All @@ -23,7 +23,7 @@ function useDebounceFn<T extends Fn>(fn: T, options?: Options) {
[],
)

React.useEffect(() => {
useEffect(() => {
debounced.cancel()
}, [])

Expand Down
4 changes: 2 additions & 2 deletions src/utils/useGetDataIndexColumns.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React from 'react'
import { useMemo } from 'react'
import type { ColumnOriginType } from '../useAntdResizableHeader'

export const GETKEY = 'dataIndex'
Expand Down Expand Up @@ -27,7 +27,7 @@ function getColumns<T extends ColumnOriginType<T>>(list: T[] | undefined): any {
*/

export function useGetDataIndexColumns<T extends ColumnOriginType<T>>(columns: T[] | undefined) {
const dataIndexColumns = React.useMemo(() => getColumns(columns), [columns]) as T[] | undefined
const dataIndexColumns = useMemo(() => getColumns(columns), [columns]) as T[] | undefined

return dataIndexColumns || columns
}
6 changes: 3 additions & 3 deletions src/utils/useLocalColumns.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useEffect, useMemo } from 'react'
import { useEffect, useMemo, useState } from 'react'
import type { ColumnOriginType, ColumnsStateType } from '../useAntdResizableHeader'
import { useGetDataIndexColumns } from './useGetDataIndexColumns'
import { useMemoizedFn } from './useMemoizedFn'
Expand Down Expand Up @@ -53,7 +53,7 @@ function useLocalColumns<T extends ColumnOriginType<T>>({
}
})

const [localColumns, setLocalColumns] = React.useState<T[] | undefined>(initLocalColumns)
const [localColumns, setLocalColumns] = useState<T[] | undefined>(initLocalColumns)

useEffect(() => {
setLocalColumns(initLocalColumns())
Expand All @@ -62,7 +62,7 @@ function useLocalColumns<T extends ColumnOriginType<T>>({
/**
* 把resizableColumns存储在本地
*/
React.useEffect(() => {
useEffect(() => {
const { persistenceType, persistenceKey } = columnsState || {}

if (!persistenceKey || !persistenceType || !resizableColumns?.length) {
Expand Down
Loading

0 comments on commit 91d8b3f

Please sign in to comment.