2.9.5 • Published 3 months ago

use-antd-resizable-header v2.9.5

Weekly downloads
-
License
MIT
Repository
github
Last release
3 months ago

use-antd-resizable-header

antd 表格头拖拽 Hook,兼容 Table ProTable

预览

preview

在线地址

Demo

安装

npm i use-antd-resizable-header

or

yarn add use-antd-resizable-header

or

pnpm add use-antd-resizable-header

API

Properties

NameTypeDefaultDescription
columnsColumnType[]undefinedantd table 的 columns
defaultWidthnumber120某一列不能拖动,设置该列的最小展示宽度,默认 120
minConstraintsnumber60拖动最小宽度 默认 defaultWidth/2
maxConstraintsnumberInfinity拖动最大宽度 默认无穷
cachebooleantrue是否缓存宽度,避免渲染重置拖拽宽度
columnsStateColumnsStateTypeundefined列状态的配置,可以用来操作列拖拽宽度
onResizeStartFunctionundefined开始拖拽时触发
onResizeEndFunctionundefined结束拖拽时触发
tooltipRenderFunctionundefined使用tooltip渲染表格头,当表格头文字溢出时展示tooltip

Return

NameDescription
resizableColumns拖拽 columns,用在 Table columns
components拖拽 components, 用在 Table components
tableWidth表格宽度,用在 Table width
resetColumns重置宽度方法

注意事项

  • 默认拖动颜色为#000,可通过global或设置 css 变量--arh-color设置颜色
  • 至少一列不能拖动(width 不设置即可),请保持至少一列的自适应
  • 若 column 未传入dataIndex,请传入一个唯一的key,否则按照将按照 column 的序号 index 计算唯一 key
  • 若 column 有副作用,请把依赖项传入 useMemo deps 中

Break-Change

  • v2.9.0起,不需要再手动引入css样式文件
  • 请安装 use-antd-resizable-header,而非 @minko-fe/use-antd-resizable-header

Example

import ProTable from '@ant-design/pro-table'
import { Button, Table, Tooltip } from 'antd'
import { useAntdResizableHeader } from 'use-antd-resizable-header'

function App() {
  const columns: ColumnsType<object> = []
  const { components, resizableColumns, tableWidth, resetColumns } = useAntdResizableHeader({
    columns: useMemo(() => columns, []),
    // 保存拖拽宽度至本地localStorage
    columnsState: {
      persistenceKey: 'localKey',
      persistenceType: 'localStorage',
    },
    tooltipRender: (props) => <Tooltip {...props} />,
  })

  const proColumns: ProColumns[] = []
  const { components: proComponents, resizableColumns: proResizableColumns, tableWidth: proTableWidth, resetColumns: proResetColumns } = useAntdResizableHeader({
      columns: useMemo(() => proColumns, []),
      tooltipRender: (props) => <Tooltip {...props} />,
    })
  

  return (
    <>
      <Table columns={resizableColumns} components={components} dataSource={data} scroll={{ x: tableWidth }} />
      <ProTable columns={proResizableColumns} components={proComponents} dataSource={data} scroll={{ x: proTableWidth }} />
      <Button onClick={() => resetColumns()}>重置宽度</Button>
    </>
  )
}

基本用例

/* index.css */
--arh-color: red;
import { Space, Table, Tag } from 'antd'
import React, { useReducer } from 'react'
import { useAntdResizableHeader } from 'use-antd-resizable-header'

const data = [
  {
    key: '1',
    name: 'John Brown',
    age: 32,
    address: 'New York No. 1 Lake Park',
    tags: ['nice', 'developer'],
  },
  {
    key: '2',
    name: 'Jim Green',
    age: 42,
    address: 'London No. 1 Lake Park',
    tags: ['loser'],
  },
  {
    key: '3',
    name: 'Joe Black',
    age: 32,
    address: 'Sidney No. 1 Lake Park',
    tags: ['cool', 'teacher'],
  },
]

const Example: React.FC = () => {
  const [, forceRender] = useReducer((s) => s + 1, 0)
  const [deps, setDeps] = useState(0)

  const columns = [
    {
      title: 'Name',
      dataIndex: 'name',
      key: 'name',
      width: 300,
      ellipsis: true,
      render: (text) => (
        <a onClick={() => setDeps((t) => t + 1)}>
          {text}
          {deps}
        </a>
      ),
    },
    {
      title: 'Age',
      dataIndex: 'age',
      key: 'age',
      ellipsis: true,
      width: 200,
    },
    {
      title: 'Address',
      dataIndex: 'address',
      key: 'address',
      ellipsis: true,
      width: 200,
    },
    {
      title: 'Tags',
      key: 'tags',
      dataIndex: 'tags',
      width: 200,
      ellipsis: true,
      render: (tags) => (
        <>
          {tags.map((tag) => {
            let color = tag.length > 5 ? 'geekblue' : 'green'
            if (tag === 'loser') {
              color = 'volcano'
            }
            return (
              <Tag color={color} key={tag}>
                {tag.toUpperCase()}
              </Tag>
            )
          })}
        </>
      ),
    },
    {
      title: 'render',
      key: 'action',
      render: (text, record) => (
        <Space size='middle'>
          <a>Invite {record.name}</a>
          <a
            onClick={() => {
              forceRender()
              alert('render')
            }}
          >
            render
          </a>
        </Space>
      ),
    },
  ]

  const { components, resizableColumns, tableWidth } = useAntdResizableHeader({
    columns: useMemo(() => columns, [deps]),
    minConstraints: 50,
  })

  return <Table columns={resizableColumns} components={components} dataSource={data} scroll={{ x: tableWidth }} />
}

为什么需要 React.useMemo ?

如果不使用 useMemo

组件 render => columns 引用变化 => use-antd-resiable-header render => 组件 render => columns 引用变化···

不使用 useMemo

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

Table 特殊处理

filter 按钮溢出隐藏了

解决方案

.ant-table-filter-trigger {
  margin-inline: 0;
}

ProTable 特殊处理

fixed

ProTable 默认会给 fixed 列添加宽度,所以可能会造成 至少一列宽度为0 的条件无法满足。

解决方案

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

本地开发

# 开发调试工具库
pnpm i

pnpm run dev

# 预览调试 playground
cd playground

pnpm i

pnpm run dev

MIT

LICENSE

2.9.5

3 months ago

2.9.4

3 months ago

2.9.3

4 months ago

2.9.2

4 months ago

2.9.1

4 months ago

2.9.0

5 months ago

2.8.15

6 months ago

2.8.14

7 months ago

2.0.2

2 years ago

2.0.1

2 years ago

2.0.0

2 years ago

1.5.3

2 years ago

1.5.2

2 years ago

1.5.1

2 years ago

1.5.0

2 years ago

2.1.2

2 years ago

2.1.1

2 years ago

2.1.3

2 years ago

2.1.0

2 years ago

1.4.6

3 years ago

1.4.5

3 years ago

1.4.3

3 years ago

1.4.2

3 years ago

1.4.1

3 years ago

1.4.0

3 years ago

1.3.5

3 years ago

1.3.4

3 years ago

1.3.3

3 years ago

1.3.2

3 years ago

1.2.4

3 years ago

1.2.3

3 years ago

1.3.1

3 years ago

1.3.0

3 years ago

1.2.2

3 years ago

1.2.1

3 years ago

1.2.0

3 years ago

1.1.14

3 years ago

1.1.12

3 years ago

1.1.11

3 years ago

1.1.13

3 years ago

1.1.10

3 years ago

1.1.9

3 years ago

1.1.8

3 years ago

1.1.7

3 years ago

1.1.6

3 years ago

1.1.4

3 years ago

1.1.3

3 years ago

1.1.1

3 years ago

1.1.0

3 years ago

1.0.9

3 years ago

1.0.8

3 years ago

1.1.2

3 years ago

1.0.7

3 years ago

1.0.6

3 years ago

1.0.5

3 years ago

1.0.4

3 years ago

1.0.3

3 years ago

1.0.2

3 years ago

1.0.1

3 years ago

1.0.0

3 years ago

0.0.0

3 years ago