UNPKG

component-genie-mcp

Version:

A simplified Model Context Protocol server for querying React components with complete content access

68 lines 148 kB
{ "timestamp": "2025-08-21T12:21:15.279Z", "totalComponents": 7, "successCount": 7, "errorCount": 0, "statistics": { "hasTypeDefinition": 7, "hasComponentCode": 0, "hasDocumentation": 7, "hasWhenToUse": 7, "hasDemos": 7, "totalDemos": 34 }, "components": [ { "name": "AutoTable", "typeDefinition": "/**\n * @file AutoTable 相关定义\n * @author 千旌\n */\n\nimport { ColumnProps as AntdColumnsProps, TableProps as AntdTableProps, TablePaginationConfig } from 'antd/lib/table';\nimport { ColumnTitle, GetRowKey } from 'antd/lib/table/interface';\nimport { TooltipProps } from 'antd/lib/tooltip';\nimport { PaginationProps } from './Pagination';\nimport { TableBatchActionProps } from './TableBatchAction';\n\nexport type RowKey = string | GetRowKey<any>;\n\nexport interface ColumnProps<RecordType extends object = any> extends AntdColumnsProps<RecordType> {\n /** 列标题, title会在固定表头时因表格滚动条出现/消失引起dom结构变化而重新渲染, title自定义组件状态需要在外部维护 */\n title?: ColumnTitle<RecordType>;\n /** 指定宽度, 仅限number, 单位px, 此时该列为固定宽度 */\n width?: number;\n /** 图标数量 */\n iconNumber?: number;\n /** 字符长度(以中文的宽度为单位) */\n length?: number;\n /** 数字位数(纯数字展示使用,为0.6的中文宽度单位) */\n numLen?: number;\n /** 时间格式 (展示时间的列所用), 设置为true,则默认为yyyy-mm-dd hh:mm:ss */\n time?: string | boolean;\n /** 列数据的取值范围, 可以是字符串数组或key-value格式对象,取其中最长字符计算宽度 */\n range?: string[] | Record<string, string>;\n /** 非固宽列占比权重 */\n weights?: number;\n /** 宽度是否固定 */\n isFixed?: boolean;\n /** 是否展示指定行数,用Abbr组件包裹,仅无render方法时生效 */\n line?: number;\n /** 文本高亮关键词,需line生效配合使用 */\n keyword?: string;\n /** 当render方法第一个参数为undefined或null时的展示默认值, 也可自定义何时使用,仅无render方法时生效 */\n defaultValue?: string | ((value: any) => string);\n /** 表头标题后面tooltip的提示, 仅配合字符串型的title使用 */\n titleTip?: React.ReactNode | TooltipProps;\n /** title的最大长度 (适用于自定义列) */\n titleMaxLength?: number;\n /** 列title前是否显示必填样式 */\n required?: boolean;\n}\n\nexport interface TableProps<RecordType extends object = any> extends AntdTableProps<RecordType> {\n /**\n * 非固宽列最小展示宽度\n * @default 100\n */\n colMinWidth?: number;\n\n /** 非固宽列宽度总和占总宽度最大比率, 取值(0, 100) */\n maxRatio?: number;\n\n /** columns */\n columns?: ColumnProps<RecordType>[];\n\n /** 分页器配置 */\n pagination?: false | (PaginationProps & TablePaginationConfig);\n\n /** 表格行是否可选择配置 */\n rowSelection?: RowSelectionProps<RecordType> & AntdTableProps<RecordType>['rowSelection'];\n\n /** 批量操作配置, 需要开启rowSelection */\n batchActions?: TableBatchActionProps;\n\n /**\n * 单元格的左右边距合计大小, 单位px(无特殊情况不需要配置)\n * @default 32\n */\n xPadding?: number;\n\n /**\n * 设置表格字体大小, 单位px(无特殊情况不需要配置)\n * @default 12\n */\n fontSize?: number;\n\n /**\n * 是否固定表头, 为true时pagination属性生成的组件会被替换为AutoTable的Pagination组件\n * @default false\n */\n isFixedHeader?: boolean;\n\n /**\n * 表格行高,用于控制所有行行高, 1行48px,2行56px,3行80px\n * 抽屉&弹窗中单行表格仅展示数据(表格内无输入框)的为40px\n * false表示不指定rowHeight,使用默认样式\n * @default 48\n */\n rowHeight?: false | 40 | 48 | 56 | 80;\n\n /** 自定义虚拟列表动态rowHeight, 会覆盖rowHeight的设置 */\n getItemHeight?: (index: number) => number;\n\n /**\n * 是否开启动画过渡效果,目前仅针对虚拟列表生效\n * @default false\n */\n isAnimation?: boolean;\n\n /**\n * 是否开启虚拟列表, 为了展示正常需同时设置isFixedHeader为true或设置scroll.y属性\n * @default false\n */\n isVirtual?: boolean;\n\n /**\n * 是否开启表格排序功能(非虚拟列表和虚拟列表的拖拽功能有差异,请根据实际情况选择)\n * @default false\n */\n isSortable?: boolean;\n\n /** 表格拖拽排序相关参数配置(虚拟列表下拖拽配置参考SortableOptions,非虚拟列表下拖拽配置参考https://sortablejs.com/options) */\n sortableOptions?: SortableOptions<RecordType> & {\n [key: string]: any;\n };\n\n /** 表格空状态配置 */\n emptyOptions?: EmptyProps;\n\n /** 表格滚动到底部触发的回调,需配合isFixedHeader为true才生效 */\n scrollToBottom?: () => void;\n\n /** 是否展示底部滚动阴影 暂时用openScrollBottomShadow控制 不默认都放开 */\n openScrollBottomShadow?: boolean;\n}\n\nexport interface TableState<RecordType extends object = any> {\n /** 内部使用的cols */\n cols: ColumnProps<RecordType>[];\n /** 是否需要出横向滚动条 */\n isScroll: boolean;\n /** 固定表头的表格高度即scroll.y的值 */\n scrollHeight: number;\n /** 当前表体的高度,用于计算是否需要设置scroll.y */\n bodyHeight: number;\n /** 表格footer属性底部的高度 */\n footerHeight: number;\n}\n\n/** 表格提供内部方法的props */\nexport interface TableFunctionProps {\n /** 根据传入keys高亮目标行3s */\n highLightTableRows?: (keys: (string | number)[]) => void;\n /** 手动滚动Table横向/纵向滚动条到指定位置 */\n scrollTo?: (scrollNumber: number, scrollDirection?: 'horizontal' | 'vertical') => void;\n /** 按指定策略滚动表格到指定行数, 从0计数(此方法暂不支持根据列数横向滚动) */\n scrollToItem?: (index: number, align?: 'center' | 'auto' | 'smart' | 'end' | 'start') => void;\n /** 按指定策略滚动表格到指定行rowKey对应的唯一标识处 */\n scrollToItemById?: (rowId: string | number, align?: 'center' | 'auto' | 'smart' | 'end' | 'start') => void;\n /** 获取表格排序后的数据(虚拟列表排序使用) */\n getCurrentDataSource?: () => any[];\n}\n\n/** 表格排序相关参数配置 */\nexport interface SortableOptions<RecordType extends object = any> {\n /** 设置行是否禁用拖拽 */\n rowDisabled?: (record: RecordType) => boolean;\n /** 设置行是否禁用被移动 */\n rowFixed?: (record: RecordType) => boolean;\n /** 是否展示拖拽手柄 */\n showHandle?: boolean;\n /** 自定义拖拽手柄 */\n customHandle?: (record: RecordType) => React.ReactElement;\n /** 禁用时拖拽手柄的提示文案 */\n disabledHandleTip?: string;\n /** 拖拽中行的类名 */\n draggingRowClassName?: string;\n /** 分组表格使用的key值数组(禁用跨分组拖拽)(GroupTable内部使用属性无需传入) */\n groups?: (string | number)[];\n /** 开始拖拽时的回调 */\n onStart?: (startIndex: number, startRowId: string | number) => void;\n /** 结束拖拽时的回调 */\n onEnd?: (\n indexInfo?: { oldDraggableIndex?: number; newDraggableIndex?: number; item?: any },\n idInfo?: {\n oldRowId: string | number;\n newRowId: string | number;\n },\n ) => void;\n /** 排序变化后的回调 (如有性能问题,建议使用AutoTable实例的方法在完成排序后调用) */\n onChange?: (newData: RecordType[]) => void;\n /** 树型数据拖拽内部节点展开/收起变更的回调 */\n onExpandRowKeysChange?: (expandRowKeys: (string | number)[]) => void;\n /**\n * 悬停展开hover时间\n * @default 300\n */\n hoverTime?: number;\n /**\n * 树型表格是否允许叶子节点作为父节点\n * @default true\n */\n allowLeafAsParent?: boolean;\n}\n\n/** 表格是否可选择配置 */\nexport interface RowSelectionProps<RecordType extends object = any> {\n /** 选择/取消单行数据的回调(同onSelect触发时机,只是返参不同),获取最新已选数据 */\n onSelectRow?: (\n selectedRowKeys: React.Key[],\n getSelectedRows?: (currentSelectedRows: RecordType[]) => RecordType[],\n ) => void;\n}\n\n/** 表格空页面配置参数 */\nexport interface EmptyProps {\n /** 空页面自定义类名 */\n className?: string;\n /** 空页面图片,默认antd的Empty.PRESENTED_IMAGE_SIMPLE */\n image?: React.ReactNode;\n /** 空页面图片样式 */\n imageStyle?: React.CSSProperties;\n /** 空页面文案,默认‘暂无数据’ */\n emptyText?: React.ReactNode;\n /** 表格loading态时空页面文案 */\n loadingText?: React.ReactNode;\n /** 底部额外的引导内容 */\n bottomExtra?: React.ReactNode;\n /** 完全自定义空状态 */\n customEmpty?: React.ReactNode;\n}\n", "componentCode": null, "documentation": "---\ncategory: 展示组件\ntitle: AutoTable\nsubtitle: 基于antd4的Table组件封装的Dataphin表格组件\norder: 1\nmultiColumn: false\nauthor: 千旌\noverview: https://img.alicdn.com/imgextra/i3/O1CN01etlOpg1eEJLvrn7jP_!!6000000003839-0-tps-1312-428.jpg\n---\n\n# AutoTable\n\n## 何时使用\n\n基于antd4的Table组件封装的Dataphin表格组件\n\n以往表格的列宽都是设置一个固定的值或者百分比,在表格宽度变化时按比例拉伸 \n但是表格的某些列的宽度往往是固定不变的,屏幕过大,列留白太多;屏幕过小,展示不全 \n为了更好地合理分配列的宽度,建议您使用此组件使Table适应屏幕大小变化\n\n## 如何使用\n\n[antd Table使用参考](https://4x.ant.design/components/table-cn/)\n\n### 区分固宽列和非固宽列\n\n**固宽列**指列的宽度为固定值,其内容宽度始终不会超过该固定值 \n**非固宽列**指列的宽度不固定,其内容宽度波动大,不能一开始给个明确的值,无法限制其宽度\n\n两者的区分往往需要结合历史经验及业务含义,有时也需要pd确定,下面给一些例子\n- 开始时间、结束时间等时间相关类的列,其数据都是按时间格式的值,如2022-03-01 12:00:00,其可以视为固宽列\n- 操作列,尽管有些操作列会根据内容的不同展示不同的图标,但最大的图标数量是可以确定,其宽度也可确定,故也为固宽列\n- 取值范围一定的列,如开发状态,其值为一个map值,仅包含某几个固定值,视为固宽列\n- 数字相关的列,如某某个数,其数字的量级也是能估量的,为固宽列\n- 创建人,名称之类的列,因为其最大基本可达128字符,最小不过个位数,波动较大,内容不确定性较强,故为非固宽列\n\n### 定义固宽列\n\n属性|类型|描述|使用场景\n--|:--:|--:|--:\nwidth|number|这个是table原有的属性,现在用来描标识为固宽列,仅支持number,单位为px,该列宽度即为width的值|1. 取值范围拿捏不准,但是能确定最长字符不超过该宽度<br /> 2. 图标比较大,如switch的按钮\niconNumber|number|图标的数量,1个图标时为24px,多个图标时计算规则为 2(n - 1)*16px 即图标占16px,图标间距16px,左右无边距|1. 全由图标组成的列,如操作,根据图标数量指定icons<br /> 2. 由图标+固定取值文本组成,如开发状态,由1个图标和已开发/已发布等文案组成\nrange|string[] \\| Record<string, string>|列数据的取值范围,取长度最大的字符作为其宽度的依据|1. 取值从一个map中获取,将该map作为range的值传入\nlength|number|列最长字符的长度,宽度计算时由该数值乘上字体大小|1. 取值在render里由if/else判断,如成功/失败,则取length: 2<br /> 2. 取值为数值为某个范围波动,如果该数不会超过5位数,则取length: 5\nnumLen|number|列展示为纯数字时使用,宽度计算时由该数值乘0.6再乘上字体大小|1. 该列数据为纯数字的id,取其可能的最长位数设置,如7位长设置7\ntime|string \\| boolean|列展示数据为时间格式,则指定该格式用于计算固定宽度,当传入true时,则使用默认格式yyyy-mm-dd hh:mm:ss|1. 该列数据仅为时间,取格式如yyyy-mm-dd\n\n上述几个属性也可搭配使用,如``range``,``length``同时定义时,以range + length的宽度计算,但``width``不行,总体遵循有width时以width值为准,无width时,则为其他属性计算宽度之和\n\n### 定义非固宽列\n\n非固宽列仅由``weights``(权重系数)属性设置,若无固宽列相关属性时,则会被认为是非固宽列,weights值**默认为1**,非固宽列按weights的比例系数分配表格剩余宽度(表格宽度 - 固宽列宽度和)\n\n> 如: A列设置weights为2,B列设置weights为1,C列设置weights为1,剩余宽度400,则各自为200,100,100的宽度\n\n### 如何根据视觉稿快速定义AutoTable的columns\n\n<img src=\"https://img.alicdn.com/imgextra/i3/O1CN01ob56W91JNNN9aaOJU_!!6000000001016-0-tps-1994-879.jpg\" width=\"800\">\n\n如上图<font color=\"red\">红框</font>圈出的就是视觉提供给我们的表格columns相关信息\n> 可变宽列:对象类型/名称、规则名称、规则类型、规则模板、调度类型、相关知识库文档<br />\n> 列宽比10:10:5:8:12:10,规则类型列最小宽度60px\n\n1. 首先我们列出所有需要定义的列并定义\n```javascript\n// T 为dataSource每一项对应的ts定义,建议设置可以更好得利用ts类型校验避免出现bug\nconst columns = ColumnsProps<T>[] = [\n {\n dataIndex: 'type',\n title: '对象类型/名称',\n },\n {\n dataIndex: 'ruleName',\n title: '规则名称/ID',\n },\n {\n dataIndex: 'runStatus',\n title: '试跑状态',\n },\n {\n dataIndex: 'status',\n title: '生效状态',\n },\n {\n dataIndex: 'ruleType',\n title: '规则类型',\n },\n {\n dataIndex: 'ruleTemplate',\n title: '规则模板',\n },\n {\n dataIndex: 'ruleStrength',\n title: '规则强度',\n },\n {\n dataIndex: 'scheduleType',\n title: '调度类型',\n },\n {\n dataIndex: 'docs',\n title: '相关知识库文档',\n },\n {\n dataIndex: 'action',\n title: '操作',\n },\n]\n```\n2. 然后对照视觉稿中列出的列名将权重填写\n```javascript\n// weights属性用于设置非固宽列,即视觉稿列出的比列\nconst columns = ColumnsProps<T>[] = [\n {\n dataIndex: 'type',\n title: '对象类型/名称',\n weights: 10,\n },\n {\n dataIndex: 'ruleName',\n title: '规则名称/ID',\n weights: 10,\n },\n {\n dataIndex: 'runStatus',\n title: '试跑状态',\n },\n {\n dataIndex: 'status',\n title: '生效状态',\n },\n {\n dataIndex: 'ruleType',\n title: '规则类型',\n weights: 5,\n },\n {\n dataIndex: 'ruleTemplate',\n title: '规则模板',\n weights: 8,\n },\n {\n dataIndex: 'ruleStrength',\n title: '规则强度',\n },\n {\n dataIndex: 'scheduleType',\n title: '调度类型',\n weights: 12,\n },\n {\n dataIndex: 'docs',\n title: '相关知识库文档',\n weights: 10,\n },\n {\n dataIndex: 'action',\n title: '操作',\n },\n]\n```\n3. 再之后对剩余列根据业务含义和实际情况定义固宽列\n```javascript\n// 注意:一定不要遗漏设置某一固宽列,什么都不设置的列会默认是weights: 1,即等分表格的列\nconst columns = ColumnsProps<T>[] = [\n {\n dataIndex: 'type',\n title: '对象类型/名称',\n weights: 10,\n },\n {\n dataIndex: 'ruleName',\n title: '规则名称/ID',\n weights: 10,\n },\n {\n dataIndex: 'runStatus',\n title: '试跑状态',\n // 一个状态icon和一个查看详情icon设置iconNumber为2,中间的文案最长为4个字符,设置length:4\n iconNumber: 2,\n length: 4,\n },\n {\n dataIndex: 'status',\n title: '生效状态',\n // 因为是一个switch组件,以组件的宽度设置即可,注意width属性是包含列左右padding32px的\n width: 80,\n },\n {\n dataIndex: 'ruleType',\n title: '规则类型',\n weights: 5,\n },\n {\n dataIndex: 'ruleTemplate',\n title: '规则模板',\n weights: 8,\n },\n {\n dataIndex: 'ruleStrength',\n title: '规则强度',\n // 此列的值只有强和弱,是在一个固定范围类,使用range属性,当然如果已经定义了map的枚举映射也可直接使用\n range: ['强', '弱']\n },\n {\n dataIndex: 'scheduleType',\n title: '调度类型',\n weights: 12,\n },\n {\n dataIndex: 'docs',\n title: '相关知识库文档',\n weights: 10,\n },\n {\n dataIndex: 'action',\n title: '操作',\n // 最多同时展示4个操作按钮,设置iconNumber为4\n iconNumber: 4,\n },\n]\n```\n4. 如果视觉稿上还标准了某某列最小列宽多少,则在AutoTable上设置<code>colMinWidth</code>属性指定\n``` javascript\n<AutoTable colMinWidth={60} />\n```\n5. 最后根据实际渲染的内容自行定义每列的render即可\n\n## 示例\n\n::: demo :::\n\n## API\n\n### TableProps\n\n::: type.TableProps :::\n\n### ColumnProps\n\n::: type.ColumnProps :::\n\n### SortableOptions\n\n::: type.SortableOptions :::\n\n### AutoTable方法\n\n名称|入参|说明\n--|:--:|--:\n<b>highLightTableRows</b>(highLightRowKeys: string[])|1. highLightRowKeys: 需要高亮的行的rowKey数组|手动设置表格指定行高亮3s\n<b>scrollTo</b>(scrollNumber: number, scrollDirection = 'vertical')|1. scrollNumber: 离顶部滚动的距离,单位px<br />2. scrollDirection: 表格滚动的轴方向,<code>vertical</code>为纵向滚动条, <code>horizontal</code>为横向滚动条, 默认纵向滚动|手动滚动Table横向/纵向滚动条到指定位置\n<b>scrollToItem</b>(index: number, align = 'auto')|1. index: 表格行号,如传入20,指滚动至第20行<br />2. align: 目标行滚动位置的对齐策略,可选入参为<code>auto</code>,<code>smart</code>,<code>start</code>,<code>center</code>,<code>end</code>|按指定策略滚动表格到指定行数(此方法暂不支持根据列数横向滚动)\n\n#### align可选参数说明\n参数|策略说明\n--|--:\nauto|1. 如果目标行已位于表格的可视区域内则不滚动<br />2. 如果目标行不在表格的可视区域内,则滚动至目标行位于表格可视区域底部\nsmart|1. 如果目标行已位于表格的可视区域内则不滚动<br />2. 如果目标行不在表格的可视区域内且距离当前小于一个可视区域,则滚动至目标行位于表格可视区域底部<br />3. 如果目标行不在表格的可视区域内且距离当前大于一个可视区域,则滚动至目标行位于表格可视区域中间\nstart|滚动至目标行位于表格可视区域顶部\ncenter|滚动至目标行位于表格可视区域中间\nend|滚动至目标行位于表格可视区域底部\n\n## FAQ\n\n### Q: 为什么我设置了固宽列,但列的宽度并不固定\n\nA: 在设计中因为屏幕的大小是不确定的,在屏幕宽度足够大时,由于列宽分配规则,非固宽列始终分配多余的宽度,固宽列不变,导致列之间宽度大小差异比较大 \n为了更合理的分配内置了一个``maxRatio``属性,该属性表示**非固宽列宽度总和占表格总宽度的最大百分比**,当分配宽度占总宽度比率超过该值时,宽度将减少至符合该比率,而将多余的宽度按比例分给固宽列,这也是固宽列不固定的原因 \n通常你是无需关心该属性,因为组件自身会为您计算一个合适的值,但如果你需要固宽列始终都是固定的值,则将``maxRatio``设置为100即可\n\n### Q: 为什么设置isFixedHeader为true时不能使用Table的pagination属性\n\nA: 动态固定表头时是需要计算表格高度的,而Table自带的分页器高度是一个不稳定因素,渲染时机也不同,会带来的额外的计算 \n并且通常情况下,固定表头时,分页器也是需要吸底展示的,为此AutoTable提供了配合``isFixedHeader``的内置``Pagination``吸底分页器组件\n\n### Q: 为什么我的表格有时列有略微错位没有对齐\n\nA: 请先检查你的<code>columns</code>定义中是否全部为固宽列,当这这种情况存在时,表格会采取自动按比列分配的方式计算宽度,当因为有纵向滚动条的存在,表头和表体的总宽度会产生计算上的差异导致有错位的情况,需要将重新审视<code>columns</code>中的固宽列的定义是否合理,将其中某些列用<code>weights</code>属性设置为非固宽列即可解决\n\n<br />\n<br />\n<br />\n<br />\n<br />\n<br />", "whenToUse": "基于antd4的Table组件封装的Dataphin表格组件\n\n以往表格的列宽都是设置一个固定的值或者百分比,在表格宽度变化时按比例拉伸 \n但是表格的某些列的宽度往往是固定不变的,屏幕过大,列留白太多;屏幕过小,展示不全 \n为了更好地合理分配列的宽度,建议您使用此组件使Table适应屏幕大小变化", "demos": [ { "name": "CustomTableDemo.tsx", "content": "/**\n * @author 千旌\n * @title AutoTable常见属性配置\n * @description 通过配置Table及columns的属性来使表格更好地展示吧\n * @order 1\n */\nimport React, { memo, useState, useLayoutEffect } from 'react';\nimport { Space, InputNumber } from 'DPAntd';\nimport AutoTable from 'src/components/AutoTable';\n\nconst Demo = () => {\n\tconst tableRef = AutoTable.useTable();\n\tconst [colMinWidth, setColMinWidth] = useState(100);\n\tconst [colConfig, setColConfig] = useState({\n\t\ta: {\n\t\t\tweights: 1,\n\t\t},\n\t\tb: {\n\t\t\tweights: 1,\n\t\t},\n\t\tc: {\n\t\t\tweights: 1,\n\t\t},\n\t\td: {\n\t\t\tweights: 1,\n\t\t},\n\t\te: {\n\t\t\tweights: 1,\n\t\t},\n\t})\n\tconst [colWidths, setColWidths] = useState([]);\n\n const columns = [\n {\n\t\t\tdataIndex: 'a',\n\t\t\ttitle: '列1',\n\t\t\t...colConfig.a,\n\t\t},\n\t\t{\n\t\t\tdataIndex: 'b',\n\t\t\ttitle: '列2',\n\t\t\t...colConfig.b,\n\t\t},\n\t\t{\n\t\t\tdataIndex: 'c',\n\t\t\ttitle: '列3',\n\t\t\t...colConfig.c,\n\t\t},\n\t\t{\n\t\t\tdataIndex: 'd',\n\t\t\ttitle: '列4',\n\t\t\t...colConfig.d,\n\t\t},\n\t\t{\n\t\t\tdataIndex: 'e',\n\t\t\ttitle: '列5',\n\t\t\t...colConfig.e,\n\t\t},\n ];\n\n const data = [\n {\n\t\t\ta: 'A1',\t\t\t\n\t\t\tb: 'B1',\n\t\t\tc: 'C1',\n\t\t\td: 'D1',\n\t\t\te: 'E1',\n\t\t},\n\t\t{\n\t\t\ta: 'A2',\t\t\t\n\t\t\tb: 'B2',\n\t\t\tc: 'C2',\n\t\t\td: 'D2',\n\t\t\te: 'E2',\n\t\t},\n\t\t{\n\t\t\ta: 'A3',\t\t\t\n\t\t\tb: 'B3',\n\t\t\tc: 'C3',\n\t\t\td: 'D3',\n\t\t\te: 'E3',\n\t\t},\n\t\t{\n\t\t\ta: 'A4',\t\t\t\n\t\t\tb: 'B4',\n\t\t\tc: 'C4',\n\t\t\td: 'D4',\n\t\t\te: 'E4',\n\t\t},\n\t\t{\n\t\t\ta: 'A5',\t\t\t\n\t\t\tb: 'B5',\n\t\t\tc: 'C5',\n\t\t\td: 'D5',\n\t\t\te: 'E5',\n\t\t},\n ];\n\n\tuseLayoutEffect(() => {\n\t\tsetTimeout(() => {\n\t\t\tconst container = (tableRef.current as any)?.tableRef;\n\t\t\tconst thDoms = container?.querySelectorAll('tr th') ?? [];\n\t\t\tconst colWidths = [];\n\t\t\tfor (let i = 0; i < thDoms.length; i++) {\n\t\t\t\tcolWidths.push(thDoms[i].getBoundingClientRect().width);\n\t\t\t}\n\t\t\tsetColWidths(colWidths);\n\t\t}, 0)\n\t}, [colConfig, colMinWidth])\n\n return (\n\t\t<Space size={12} direction=\"vertical\" style={{ width: '100%' }}>\n\t\t\t{columns.map((col, index) => {\n\t\t\t\treturn (\n\t\t\t\t\t<Space size={12}>\n\t\t\t\t\t\t<span>{`第${index + 1}列`}</span>\n\t\t\t\t\t\t<span>weights</span>\n\t\t\t\t\t\t<InputNumber min={1} max={1000} step={1} value={colConfig[col.dataIndex]?.weights} onChange={(val) => {\n\t\t\t\t\t\t\tsetColConfig({\n\t\t\t\t\t\t\t\t...colConfig,\n\t\t\t\t\t\t\t\t[col.dataIndex]: {\n\t\t\t\t\t\t\t\t\t...colConfig[col.dataIndex],\n\t\t\t\t\t\t\t\t\tweights: val,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t}} />\n\t\t\t\t\t\t<span>width</span>\n\t\t\t\t\t\t<InputNumber min={10} max={1000} step={1} value={colConfig[col.dataIndex]?.width} onChange={(val) => {\n\t\t\t\t\t\t\tsetColConfig({\n\t\t\t\t\t\t\t\t...colConfig,\n\t\t\t\t\t\t\t\t[col.dataIndex]: {\n\t\t\t\t\t\t\t\t\t...colConfig[col.dataIndex],\n\t\t\t\t\t\t\t\t\twidth: val,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t}} />\n\t\t\t\t\t\t<span>length</span>\n\t\t\t\t\t\t<InputNumber min={1} max={1000} step={1} value={colConfig[col.dataIndex]?.length} onChange={(val) => {\n\t\t\t\t\t\t\tsetColConfig({\n\t\t\t\t\t\t\t\t...colConfig,\n\t\t\t\t\t\t\t\t[col.dataIndex]: {\n\t\t\t\t\t\t\t\t\t...colConfig[col.dataIndex],\n\t\t\t\t\t\t\t\t\tlength: val,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t}} />\n\t\t\t\t\t\t<span>iconNumber</span>\n\t\t\t\t\t\t<InputNumber min={1} max={1000} step={1} value={colConfig[col.dataIndex]?.iconNumber} onChange={(val) => {\n\t\t\t\t\t\t\tsetColConfig({\n\t\t\t\t\t\t\t\t...colConfig,\n\t\t\t\t\t\t\t\t[col.dataIndex]: {\n\t\t\t\t\t\t\t\t\t...colConfig[col.dataIndex],\n\t\t\t\t\t\t\t\t\ticonNumber: val,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t}} />\n\t\t\t\t\t\t<span>当前column宽度</span>\n\t\t\t\t\t\t<span>{colWidths[index]}</span>\n\t\t\t\t\t</Space>\n\t\t\t\t)\n\t\t\t})}\n\t\t\t<Space size={12}>\n\t\t\t\t<span>非固宽列最小展示宽度</span>\n\t\t\t\t<InputNumber min={10} max={1000} step={1} value={colMinWidth} onChange={setColMinWidth} />\n\t\t\t</Space>\n\t\t\t<AutoTable ref={tableRef} columns={columns} dataSource={data} colMinWidth={colMinWidth} />\n\t\t</Space>\n\t);\n};\n\nexport default memo(Demo);\n" }, { "name": "HighLightTableDemo.tsx", "content": "/**\n * @author 千旌\n * @title 新增行/编辑行/呼出抽屉等高亮目标行\n * @description 当表格进行一些操作时,需要高亮目标行3s,使用<code>highLightTableRows</code>方法通过传入rowKeys来高亮目标行\n * @order 8\n */\n\nimport React, { memo, useRef, useState, useEffect } from 'react';\nimport { Button, DatePicker, Form, Input, Modal, Select } from 'DPAntd';\nimport moment from 'moment';\nimport AutoTable, { ActionGroup } from 'src/components/AutoTable';\nimport FormItem from 'src/components/FormItem';\n\nconst getAgeByBirthday = birthday => {\n const ageDifMs = Date.now() - new Date(birthday).getTime();\n const ageDate = new Date(ageDifMs);\n return Math.abs(ageDate.getUTCFullYear() - 1970);\n};\n\nconst data = [\n {\n key: 'xxx',\n name: '张三',\n gender: 0,\n age: getAgeByBirthday('1991-03-04'),\n address: '浙江省杭州市余杭区五常街道xxxxxxxxxxx小区3幢1单元202室',\n birthday: '1991-03-04',\n },\n {\n key: '2',\n name: '李四',\n gender: 1,\n age: getAgeByBirthday('2004-01-26'),\n address: '浙江省杭州市余杭区五常街道xx小区5幢2单元301室',\n birthday: '2004-01-26',\n },\n {\n key: '3',\n name: '王五',\n gender: 0,\n age: getAgeByBirthday('1997-10-17'),\n address: '浙江省杭州市余杭区五常街道xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx小区7幢3单元503室',\n birthday: '1997-10-17',\n },\n];\n\nconst Demo = memo(() => {\n const tableRef = useRef(null);\n const [form] = Form.useForm();\n const [dataSource, setDataSource] = useState(data);\n const [modalVisible, setModalVisible] = useState(false);\n const [currentRecord, setCurrentRecord] = useState(null);\n\n\tuseEffect(() => {\n\t\tform.resetFields();\n\t}, [currentRecord])\n\n const columns = [\n {\n title: '姓名',\n dataIndex: 'name',\n key: 'name',\n weights: 1,\n render: text => <a>{text}</a>,\n },\n {\n title: '性别',\n dataIndex: 'gender',\n key: 'gender',\n range: ['男', '女'],\n render: text => (text === 0 ? '男' : '女'),\n },\n {\n title: '年龄',\n dataIndex: 'age',\n key: 'age',\n length: 5,\n },\n {\n title: '地址',\n dataIndex: 'address',\n key: 'address',\n weights: 2,\n line: 1,\n },\n {\n title: '出生日期',\n key: 'birthday',\n dataIndex: 'birthday',\n time: 'YYYY-MM-DD',\n },\n {\n title: '操作',\n key: 'action',\n iconNumber: 2,\n render: (_, record) => (\n <ActionGroup\n actions={[\n {\n title: '编辑',\n icon: 'icon-edit',\n onClick: () => handleEditRow(record),\n },\n {\n title: '删除',\n icon: 'icon-delete',\n },\n ]}\n />\n ),\n },\n ];\n\n // 新增一行\n const handleAddRow = () => {\n setCurrentRecord(null);\n setModalVisible(true);\n };\n\n // 编辑行\n const handleEditRow = record => {\n setCurrentRecord(record);\n setModalVisible(true);\n };\n\n const handleOk = () => {\n form.validateFields().then(values => {\n let res = [];\n const birthday = moment(values.birthday).format('YYYY-MM-DD');\n if (currentRecord) {\n res = dataSource.map(item => {\n if (item.key === currentRecord.key) {\n return {\n ...item,\n ...values,\n birthday,\n age: getAgeByBirthday(birthday),\n };\n }\n\n return item;\n });\n } else {\n res = dataSource.concat({\n key: String(dataSource.length + 1),\n ...values,\n birthday,\n age: getAgeByBirthday(birthday),\n });\n }\n\n // 模拟接口的异步场景\n setTimeout(() => {\n setDataSource(res);\n setModalVisible(false);\n tableRef.current?.highLightTableRows([currentRecord ? currentRecord.key : String(dataSource.length + 1)]);\n }, 300)\n });\n };\n\n return (\n <div>\n <Button style={{ marginBottom: '10px' }} type=\"primary\" onClick={handleAddRow}>\n 新增一行\n </Button>\n <AutoTable ref={tableRef} rowKey=\"key\" columns={columns} dataSource={dataSource} />\n <Modal\n title={currentRecord ? '编辑一行' : '新增一行'}\n visible={modalVisible}\n onCancel={() => setModalVisible(false)}\n onOk={handleOk}\n >\n <Form\n form={form}\n colon={false}\n initialValues={{\n ...currentRecord,\n birthday: moment(currentRecord?.birthday),\n }}\n >\n <FormItem name=\"name\" label=\"姓名\" labelWidth={80} rules={[{ required: true }]}>\n <Input placeholder=\"请输入姓名\" />\n </FormItem>\n <FormItem name=\"gender\" label=\"性别\" labelWidth={80} rules={[{ required: true }]}>\n <Select placeholder=\"请选择性别\">\n <Select.Option value={0}>男</Select.Option>\n <Select.Option value={1}>女</Select.Option>\n </Select>\n </FormItem>\n <FormItem name=\"birthday\" label=\"生日\" labelWidth={80}>\n <DatePicker placeholder=\"请选择出生日期\" />\n </FormItem>\n <FormItem name=\"address\" label=\"地址\" labelWidth={80}>\n <Input.TextArea placeholder=\"请输入地址\" />\n </FormItem>\n </Form>\n </Modal>\n </div>\n );\n});\n\nexport default Demo;\n" }, { "name": "NewSortableTableDemo.tsx", "content": "/**\n * @author 千旌\n * @title 虚拟列表下拖拽表格,支持树型结构拖拽\n * @description 设置<code>isSortable</code>及<code>isVirtual</code>属性开启此功能,设置<code>sortableOptions</code>进行配置和监听拖拽事件\n * @order 7\n */\n\nimport React, { useState } from 'react';\nimport { InputNumber, Space, Switch } from 'DPAntd';\nimport AutoTable from 'src/components/AutoTable';\n\nconst mockData = [\n {\n id: '1',\n name: '张三',\n desc: '测试测试测试',\n },\n {\n id: '2',\n name: '张三',\n desc: '测试测试测试',\n children: [\n {\n id: '2-1',\n name: '张三',\n desc: '测试测试测试',\n },\n {\n id: '2-2',\n name: '张三',\n desc: '测试测试测试',\n children: [\n {\n id: '2-2-1',\n name: '张三',\n desc: '测试测试测试',\n },\n ],\n },\n {\n id: '2-3',\n name: '张三',\n desc: '测试测试测试',\n },\n {\n id: '2-4',\n name: '张三',\n desc: '测试测试测试',\n },\n {\n id: '2-5',\n name: '张三',\n desc: '测试测试测试',\n },\n {\n id: '2-6',\n name: '张三',\n desc: '测试测试测试',\n },\n {\n id: '2-7',\n name: '张三',\n desc: '测试测试测试',\n },\n {\n id: '2-8',\n name: '张三',\n desc: '测试测试测试',\n },\n {\n id: '2-9',\n name: '张三',\n desc: '测试测试测试',\n },\n ],\n },\n {\n id: '3',\n name: '张三',\n desc: '测试测试测试',\n children: [\n {\n id: '3-1',\n name: '张三',\n desc: '测试测试测试',\n },\n {\n id: '3-2',\n name: '张三',\n desc: '测试测试测试',\n children: [\n {\n id: '3-2-1',\n name: '张三',\n desc: '测试测试测试',\n },\n ],\n },\n ],\n },\n {\n id: '4',\n name: '张三',\n desc: '测试测试测试',\n },\n {\n id: '5',\n name: '张三',\n desc: '测试测试测试',\n },\n {\n id: '6',\n name: '张三',\n desc: '测试测试测试',\n },\n {\n id: '7',\n name: '张三',\n desc: '测试测试测试',\n },\n {\n id: '8',\n name: '张三',\n desc: '测试测试测试',\n },\n {\n id: '9',\n name: '张三',\n desc: '测试测试测试',\n },\n {\n id: '10',\n name: '张三',\n desc: '测试测试测试',\n },\n];\n\nconst TestTable = () => {\n const [dataSource, setDataSource] = useState(mockData);\n const [showHandle, setShowHandle] = useState(true);\n const [hoverTime, setHoverTime] = useState(1000);\n const [allowLeafAsParent, setAllowLeafAsParent] = useState(true);\n const tableRef = AutoTable.useTable();\n\n const columns = [\n {\n dataIndex: 'id',\n title: '序号',\n },\n {\n dataIndex: 'name',\n title: '姓名',\n },\n {\n dataIndex: 'desc',\n title: '描述',\n },\n ];\n\n return (\n <Space size={12} direction=\"vertical\">\n <Space size={12}>\n <span className=\"text-black\">是否展示拖拽手柄</span>\n <Switch checked={showHandle} onChange={setShowHandle} />\n <span className=\"text-black\">允许叶子节点作为父节点</span>\n <Switch checked={allowLeafAsParent} onChange={setAllowLeafAsParent} />\n </Space>\n <Space size={12}>\n <span className=\"text-black\">悬停展开时间设置</span>\n <InputNumber min={0} step={100} value={hoverTime} onChange={setHoverTime} />\n <span className=\"text-black\"> 毫秒</span>\n </Space>\n <AutoTable\n rowKey=\"id\"\n ref={tableRef}\n columns={columns}\n dataSource={dataSource}\n isVirtual={true}\n isSortable={true}\n sortableOptions={{\n showHandle,\n hoverTime,\n allowLeafAsParent,\n onChange: newDataSource => {\n setDataSource(newDataSource);\n },\n }}\n scroll={{\n y: 600,\n }}\n />\n </Space>\n );\n};\n\nexport default TestTable;\n" }, { "name": "ScrollTableDemo.tsx", "content": "/**\n * @author 千旌\n * @title 手动设置表格滚动位置\n * @description AutoTable提供<code>scrollTo</code>和<code>scrollToItem</code>方法,可以手动设置表格滚动位置\n * @order 9\n */\n\nimport React, { memo, useState } from 'react';\nimport { Radio, Space, Button, InputNumber, Divider } from 'DPAntd';\nimport AutoTable, { ActionGroup } from 'src/components/AutoTable';\n\nconst data = [];\nfor (let i = 0; i < 100; i++) {\n data.push({\n key: i,\n name: `张三${i + 1}号`,\n gender: 0,\n age: 32,\n address: `浙江省杭州市余杭区五常街道xx小区3幢1单元${i + 1}室`,\n birthday: '1991-03-04',\n });\n}\n\nconst Demo = memo(() => {\n const tableRef = AutoTable.useTable();\n\tconst [scrollDir, setScrollDir] = useState('vertical');\n\tconst [scrollNumber, setScrollNumber] = useState(0);\n\tconst [scrollIndex, setScrollIndex] = useState(0);\n const [scrollAlign, setScrollAlign] = useState('auto');\n const columns = [\n {\n title: '姓名',\n dataIndex: 'name',\n key: 'name',\n weights: 1,\n render: text => <a>{text}</a>,\n },\n {\n title: '性别',\n dataIndex: 'gender',\n key: 'gender',\n range: ['男', '女'],\n render: text => (text === 0 ? '男' : '女'),\n },\n {\n title: '年龄',\n dataIndex: 'age',\n key: 'age',\n length: 5,\n },\n {\n title: '地址',\n dataIndex: 'address',\n key: 'address',\n weights: 2,\n },\n {\n title: '出生日期',\n key: 'birthday',\n dataIndex: 'birthday',\n time: 'YYYY-MM-DD',\n },\n\t\t{\n title: '列1',\n key: '1',\n dataIndex: '1',\n },\n\t\t{\n title: '列2',\n key: '2',\n dataIndex: '2',\n },\n\t\t{\n title: '列3',\n key: '3',\n dataIndex: '3',\n\t\t\tweights: 2,\n },\n\t\t{\n title: '列4',\n key: '4',\n dataIndex: '4',\n },\n\t\t{\n title: '列5',\n key: '5',\n dataIndex: '5',\n\t\t\tweights: 2,\n },\n\t\t{\n title: '列6',\n key: '6',\n dataIndex: '6',\n },\n\t\t{\n title: '列7',\n key: '7',\n dataIndex: '7',\n\t\t\tweights: 2,\n },\n\t\t{\n title: '列8',\n key: '8',\n dataIndex: '8',\n },\n\t\t{\n title: '列9',\n key: '9',\n dataIndex: '9',\n\t\t\tweights: 2,\n },\n\t\t{\n title: '列10',\n key: '10',\n dataIndex: '10',\n },\n {\n title: '操作',\n key: 'action',\n iconNumber: 3,\n render: (_, record) => (\n <ActionGroup\n tileLimit={2}\n actions={[\n {\n title: '新建',\n icon: 'icon-xinjian2',\n },\n {\n title: '编辑',\n icon: 'icon-edit',\n },\n {\n title: '删除',\n icon: 'icon-delete',\n rules: [\n {\n validate: () => false,\n },\n ],\n },\n {\n title: '查看详情',\n icon: 'icon-chakanxiangqing1',\n },\n ]}\n />\n ),\n },\n ];\n\n\tconst handleScroll = () => {\n\t\ttableRef.current?.scrollTo(scrollNumber, scrollDir as \"vertical\" | \"horizontal\");\n\t}\n\n\tconst handleScrollItem = () => {\n\t\ttableRef.current?.scrollToItem(scrollIndex, scrollAlign as \"center\" | \"auto\" | \"smart\" | \"end\" | \"start\");\n\t}\n\n return (\n <div>\n <Divider orientation=\"left\">滚动到指定距离</Divider>\n\t\t\t<Space style={{ marginBottom: '10px' }}>\n\t\t\t\t<span>轴方向</span>\n <Radio.Group value={scrollDir} onChange={e => setScrollDir(e.target.value)}>\n\t\t\t\t\t<Radio value=\"vertical\">y轴</Radio>\n\t\t\t\t\t<Radio value=\"horizontal\">x轴</Radio>\n\t\t\t\t</Radio.Group>\n </Space>\n <Space style={{ marginBottom: '10px' }}>\n <span>滚动到</span>\n\t\t\t\t<InputNumber value={scrollNumber} onChange={setScrollNumber} />\n\t\t\t\t<Button type=\"primary\" onClick={handleScroll}>确定</Button>\n </Space>\n <Divider orientation=\"left\">滚动到指定行数</Divider>\n <Space style={{ display: 'flex', marginBottom: '10px' }}>\n <span>对齐策略</span>\n <Radio.Group value={scrollAlign} onChange={e => setScrollAlign(e.target.value)}>\n\t\t\t\t\t<Radio value=\"auto\">auto</Radio>\n\t\t\t\t\t<Radio value=\"smart\">smart</Radio>\n <Radio value=\"start\">start</Radio>\n <Radio value=\"center\">center</Radio>\n <Radio value=\"end\">end</Radio>\n\t\t\t\t</Radio.Group>\n </Space>\n <Space style={{ display: 'flex', marginBottom: '10px' }}>\n <span>滚动至第</span>\n\t\t\t\t<InputNumber value={scrollIndex} onChange={setScrollIndex} />\n\t\t\t\t<span>{scrollDir === 'horizontal' ? '列' : '行'}</span>\n\t\t\t\t<Button type=\"primary\" onClick={handleScrollItem}>确定</Button>\n </Space>\n <AutoTable ref={tableRef} rowKey=\"key\" columns={columns} dataSource={data} scroll={{ y: 500 }} />\n </div>\n );\n});\n\nexport default Demo;\n" }, { "name": "SortableTableDemo.tsx", "content": "/**\n * @author 千旌\n * @title 非虚拟列表下拖拽表格,不支持树型结构拖拽\n * @description 设置<code>isSortable</code>属性开启此功能,设置<code>sortableOptions</code>进行配置和监听拖拽事件\n * @order 6\n */\n\nimport React from 'react';\nimport AutoTable, { ActionGroup } from 'src/components/AutoTable';\n\nconst TestTable = () => {\n const columns = [\n {\n title: '序号',\n dataIndex: 'order',\n key: 'order',\n length: 2,\n },\n {\n title: '姓名',\n dataIndex: 'name',\n key: 'name',\n weights: 1,\n render: text => <a>{text}</a>,\n },\n {\n title: '性别',\n dataIndex: 'gender',\n key: 'gender',\n range: ['男', '女'],\n render: text => (text === 0 ? '男' : '女'),\n },\n {\n title: '年龄',\n dataIndex: 'age',\n key: 'age',\n length: 5,\n },\n {\n title: '地址',\n dataIndex: 'address',\n key: 'address',\n weights: 2,\n },\n {\n title: '出生日期',\n key: 'birthday',\n dataIndex: 'birthday',\n time: 'YYYY-MM-DD',\n },\n {\n title: '操作',\n key: 'action',\n iconNumber: 2,\n render: (_, record) => (\n <ActionGroup\n actions={[\n {\n title: '编辑',\n icon: 'icon-edit',\n },\n {\n title: '删除',\n icon: 'icon-delete',\n },\n ]}\n />\n ),\n },\n ];\n\n const data = [];\n for (let i = 0; i < 10; i++) {\n data.push({\n key: i,\n order: i,\n name: `张三${i}号`,\n gender: 0,\n age: 32,\n address: `浙江省杭州市余杭区五常街道xx小区3幢1单元${i}室`,\n birthday: '1991-03-04',\n });\n }\n\n return <AutoTable columns={columns} dataSource={data} isSortable={true} />;\n};\n\nexport default TestTable;\n" }, { "name": "TableColLineDemo.tsx", "content": "/**\n * @author 千旌\n * @title 指定列最大展示行数\n * @description 通过设置columns里的<code>line</code>属性自动为文本使用Abbr组件包裹\n * @order 2\n */\nimport React, { memo } from 'react';\nimport AutoTable, { ActionGroup } from 'src/components/AutoTable';\n\nconst Demo = memo(() => {\n const columns = [\n {\n title: '姓名',\n dataIndex: 'name',\n key: 'name',\n weights: 1,\n render: text => <a>{text}</a>,\n },\n {\n title: '性别',\n dataIndex: 'gender',\n key: 'gender',\n range: ['男', '女'],\n render: text => (text === 0 ? '男' : '女'),\n },\n {\n title: '年龄',\n dataIndex: 'age',\n key: 'age',\n length: 5,\n },\n {\n title: '地址',\n dataIndex: 'address',\n key: 'address',\n weights: 2,\n line: 1,\n },\n {\n title: '出生日期',\n key: 'birthday',\n dataIndex: 'birthday',\n time: 'YYYY-MM-DD',\n },\n {\n title: '操作',\n key: 'action',\n iconNumber: 2,\n render: (_, record) => (\n <ActionGroup\n actions={[\n {\n title: '编辑',\n icon: 'icon-edit',\n },\n {\n title: '删除',\n icon: 'icon-delete',\n },\n ]}\n />\n ),\n },\n ];\n\n const data = [\n {\n key: '1',\n name: '张三',\n gender: 0,\n age: 32,\n address: '浙江省杭州市余杭区五常街道xxxxxxxxxxx小区3幢1单元202室',\n birthday: '1991-03-04',\n },\n {\n key: '2',\n name: '李四',\n gender: 1,\n age: 19,\n address: '浙江省杭州市余杭区五常街道xx小区5幢2单元301室',\n birthday: '2004-01-26',\n },\n {\n key: '3',\n name: '王五',\n gender: 0,\n age: 26,\n address: '浙江省杭州市余杭区五常街道xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx小区7幢3单元503室',\n birthday: '1997-10-17',\n },\n ];\n\n return <AutoTable columns={columns} dataSource={data} />;\n});\n\nexport default Demo;\n" }, { "name": "TableFixedHeaderDemo.tsx", "content": "/**\n * @author 千旌\n * @title 固定表头\n * @description 设置<code>isFixedHeader</code>为true实现固定表头<br />需要Table的父组件是一个高度弹性的盒子\n * @order 3\n */\nimport React, { memo, useCallback, useRef } from 'react';\nimport AutoTable, { ActionGroup } from 'src/components/AutoTable';\nimport './TableFixedHeaderDemo.scss';\n\nconst Demo = memo(() => {\n const ref = useRef(null);\n const lastY = useRef(0);\n\n const columns = [\n {\n title: '姓名',\n dataIndex: 'name',\n key: 'name',\n weights: 1,\n render: text => <a>{text}</a>,\n },\n {\n title: '性别',\n dataIndex: 'gender',\n key: 'gender',\n range: ['男', '女'],\n render: text => (text === 0 ? '男' : '女'),\n },\n {\n title: '年龄',\n dataIndex: 'age',\n key: 'age',\n length: 5,\n },\n {\n title: '地址',\n dataIndex: 'address',\n key: 'address',\n weights: 2,\n line: 1,\n },\n {\n title: '出生日期',\n key: 'birthday',\n dataIndex: 'birthday',\n time: 'YYYY-MM-DD',\n },\n {\n title: '操作',\n key: 'action',\n iconNumber: 2,\n render: (_, record) => (\n <ActionGroup\n actions={[\n {\n title: '编辑',\n icon: 'icon-edit',\n },\n {\n title: '删除',\n icon: 'icon-delete',\n },\n ]}\n />\n ),\n },\n ];\n\n const data = [];\n for (let i = 0; i < 100; i++) {\n data.push({\n key: i,\n name: `张三${i}号`,\n gender: 0,\n age: 32,\n address: `浙江省杭州市余杭区五常街道xx小区3幢1单元${i}室`,\n birthday: '1991-03-04',\n });\n }\n\n const handleMouseDown = e => {\n lastY.current = e.clientY;\n document.addEventListener('mouseup', handleMouseUp);\n };\n\n const handleMouseUp = useCallback(e => {\n const newHeight = ref.current.clientHeight + (e.clientY - lastY.current);\n lastY.current = e.clientY;\n ref.current.style.height = `${newHeight}px`;\n document.removeEventListener('mouseup', handleMouseUp);\n }, []);\n\n return (\n <div className=\"table-fixed-header-demo\" ref={ref}>\n <div className=\"table-box\">\n <h1>表格标题</h1>\n <AutoTable columns={columns} dataSource={data} isFixedHeader={true} />\n </div>\n <div className=\"drag-line\" onMouseDown={handleMouseDown}></div>\n </div>\n );\n});\n\nexport default Demo;\n" }, { "name": "TablePaginationDemo.tsx", "content": "/**\n * @author 千旌\n * @title 分页与批量操作\n * @description AutoTable内置了两个配套组件<b>吸底分页器</b><code>Pagination</code>和<b>表格批量操作</b><code>TableBatchAction</code>, 两个独立组件可单独使用,也可以在<code>isFixedHeader</code>属性为true时,在AutoTable中使用<code>pagination</code>和<code>batchActions</code>两个属性配置\n * @order 4\n */\nimport React, { memo, useState, useEffect } from 'react';\nimport ActionGroup from 'src/components/ActionGroup';\nimport AutoTable from 'src/components/AutoTable';\n\nconst data = new Array(100).fill(0).map((item, index) => ({\n key: String(index),\n name: `张三${index}`,\n gender: 0,\n age: 32,\n address: `浙江省杭州市余杭区五常街道xx小区3幢1单元${index}室`,\n birthday: '1991-03-04',\n}));\n\nconst Demo = memo(() => {\n const [originData, setOriginData] = useState(data);\n const [showData, setShowData] = useState([]);\n const [selectedRowKeys, setSelectedRowKeys] = useState([]);\n const [currentPage, setCurrentPage] = useState(1);\n const [pageSize, setPageSize] = useState(20);\n\n useEffect(() => {\n setShowData(originData.slice((currentPage - 1) * pageSize, currentPage * pageSize));\n }, [originData, currentPage, pageSize]);\n\n const columns = [\n {\n title: '姓名',\n dataIndex: 'name',\n key: 'name',\n weights: 1,\n render: text => <a>{text}</a>,\n },\n {\n title: '性别',\n dataIndex: 'gender',\n key: 'gender',\n range: ['男', '女'],\n render: text => (text === 0 ? '男' : '女'),\n },\n {\n title: '年龄',\n dataIndex: 'age',\n key: 'age',\n length: 5,\n },\n {\n title: '地址',\n dataIndex: 'address',\n key: 'address',\n weights: 2,\n line: 1,\n },\n {\n title: '出生日期',\n key: 'birthday',\n dataIndex: 'birthday',\n time: 'YYYY-MM-DD',\n },\n {\n title: '操作',\n key: 'action',\n iconNumber: 1,\n render: (_, record) => (\n <ActionGroup\n actions={[\n {\n title: '删除',\n icon: 'icon-delete',\n rules: [\n {\n validate: () => Number(record.key) % 13 !== 0,\n message: '13倍数的行禁用',\n },\n ],\n onClick: () => handleDelete(record.key),\n },\n ]}\n />\n ),\n },\n ];\n\n const handleDelete = (key: string) => {\n setOriginData(originData.filter(item => item.key !== key));\n setSelectedRowKeys(selectedRowKeys.filter(item => item !== key));\n };\n\n const handleBatchDelete = () => {\n setOriginData(originData.filter(item => !selectedRowKeys.includes(item.key)));\n setSelectedRowKeys([]);\n };\n\n const handlePageChange = (page: number, pageSize: number) => {\n setCurrentPage(page);\n setPageSize(pageSize);\n };\n\n const handleSelectAll = (checked: boolean, selectedRowKeys: React.Key[]) => {\n setSelectedRowKeys(selectedRowKeys);\n };\n\n return (\n <div style={{ height: '500px', display: 'flex', flexDirection: 'column' }}>\n <AutoTable\n rowKey=\"key\"\n columns={columns}\n dataSource={showData}\n isFixedHeader\n rowSelection={{\n hideSelectAll: true,\n selectedRowKeys: selectedRowKeys,\n // 内置新方法在单个勾选/取消时直接返回当前所有的selectedRowKeys\n onSelectRow: setSelectedRowKeys,\n getCheckboxProps: record => ({\n disabled: Number(record.key) % 13 === 0,\n }),\n }}\n batchActions={{\n showCount: true,\n showTotal: true,\n onSelectAll: handleSelectAll,\n actions: [\n {\n icon: 'icon-delete',\n title: '删除',\n onClick: handleBatchDelete,\n },\n ],\n }}\n pagination={{\n total: originData.length,\n current: currentPage,\n pageSize: pageSize,\n showQuickJumper: true,\n showSizeChanger: true,\n onChange: handlePageChange,\n simpleWidth: 800,\n }}\n />\n </div>\n );\n});\n\nexport default Demo;\n" }, { "name": "VirtualTableDemo.tsx", "content": "/**\n * @author 千旌\n * @title 虚拟滚动\n * @description 设置<code>isVirtual</code>属性开启此功能\n * @order 5\n */\nimport React, { memo } from 'react';\nimport AutoTable, { ActionGroup } from 'src/components/AutoTable';\n\nconst Demo = memo(() => {\n const columns = [\n {\n title: '序号',\n dataIndex: 'order',\n key: 'order',\n length: 2,\n },\n {\n title: '姓名',\n dataIndex: 'name',\n key: 'name',\n weights: 1,\n render: text => <a>{text}</a>,\n },\n {\n title: '性别',\n dataIndex: 'gender',\n key: 'gender',\n range: ['男', '女'],\n render: text => (text === 0 ? '男' : '女'),\n },\n {\n title: '年龄',\n dataIndex: 'age',\n key: 'age',\n length: 5,\n },\n {\n title: '地址',\n dataIndex: 'address',\n key: 'address',\n weights: 2,\n },\n {\n title: '出生日期',\n key: 'birthday',\n dataIndex: 'birthday',\n time: 'YYYY-MM-DD',\n },\n {\n title: '操作',\n key: 'action',\n iconNumber: 2,\n render: (_, record) => (\n <ActionGroup\n actions={[\n {\n title: '编辑',\n icon: 'icon-edit',\n },\n {\n title: '删除',\n icon: 'icon-delete',\n },\n ]}\n />\n ),\n },\n ];\n\n const data = [];\n for (let i = 0; i < 10000; i++) {\n data.push({\n key: i,\n order: i,\n name: `张三${i}号`,\n gender: 0,\n age: 32,\n address: `浙江省杭州市余杭区五常街道xx小区3幢1单元${i}室`,\n birthday: '1991-03-04',\n });\n }\n\n return <AutoTable columns={columns} dataSource={data} isVirtual={true} isFixedHeader={true} />;\n});\n\nexport default Demo;\n" }, { "name": "basic.tsx", "content": "/**\n * @author 千旌\n * @title 基本用法\n * @description 通过columns的属性来设置固宽列及非固宽列,固宽列为性别、年龄、出生日期、操作,非固定列为姓名、地址\n * @order 0\n */\nimport React, { memo } from 'react';\nimport AutoTable, { ActionGroup } from 'src/components/AutoTable';\n\nconst Demo = memo(() => {\n const columns = [\n {\n title: '姓名',\n dataIndex: 'name',\n key: 'name',\n weights: 1,\n render: text => <a>{text}</a>,\n },\n {\n title: '性别',\n dataIndex: 'gender',\n key: 'gender',\n range: ['男', '女'],\n render: text => (text === 0 ? '男' : '女'),\n },\n {\n title: '年龄',\n dataIndex: 'age',\n key: 'age',\n length: 5,\n },\n {\n title: '地址',\n dataIndex: 'address',\n key: 'address',\n weights: 2,\n },\n {\n title: '出生日期',\n key: 'birthday',\n dataIndex: 'birthday',\n time: 'YYYY-MM-DD',\n },\n {\n title: '操作',\n key: 'action',\n iconNumber: 3,\n render: (_, record) => (\n <ActionGroup\n tileLimit={2}\n actions={[\n {\n title: '新建',\n icon: 'icon-xinjian2',\n },\n {\n title: '编辑',\n icon: 'icon-edit',\n },\n {\n title: '删除',\n icon: 'icon-delete',\n rules: [\n {\n validate: () => false,\n },\n ],\n },\n {\n title: '查看详情',\n icon: 'icon-chakanxiangqing1',\n },\n ]}\n />\n ),\n },\n ];\n\n const data = [\n {\n key: '1',\n name: '张三',\n gender: 0,\n age: 32,\n address: '浙江省杭州市余杭区五常街道幸福小区3幢1单元202室',\n birthday: '1991-03-04',\n },\n {\n key: '2',\n name: '李四',\n gender: 1,\n age: 19,\n address: '浙江省杭州市余杭区五常街道幸福小区5幢2单元301室',\n birthday: '2004-01-26',\n },\n {\n key: '3',\n name: '王五',\n gender: 0,\n age: 26,\n address: '浙江省杭州市余杭区五常街道幸福小区7幢3单元503室',\n birthday: '1997-10-17',\n },\n ];\n\n return <AutoTable columns={columns} dataSource={data} />;\n});\n\nexport default Demo;\n" } ] }, { "name": "Abbr", "typeDefinition": "/**\n * @author 无浊\n * @description Abbr 组件的定义文件\n */\n\nimport React from 'react';\nimport { AbstractTooltipProps, TooltipPlacement } from 'antd/lib/tooltip';\n\nexport class AbbrProps {\n /**\n * 额外的 className\n */\n className? = '';\n\n /**\n * 原始文本\n */\n text: number | string = '';\n\n /** 限制长度,以中文字符计算 */\n length?: number;\n\n /** 展示几行,不能和 **length** 同时设置 */\n line?: number;\n\n /**\n * 是否斜体显示,用于 Tab 处于 preview 模式等\n */\n italic? = false;\n\n /** 展现位置,默认为 topLeft */\n placement?: TooltipPlacement = 'topLeft';\n\n /**\n * 高亮关键词\n */\n keyword? = '';\n\n /**\n * Tooltip的overlayClassName\n */\n overlayClassName? = '';\n\n /** 特殊场景,禁用tooltip,只显示... */\n alwaysHidden?: boolean;\n\n [key: string]: any;\n\n /** 配置tooltip的容器 */\n getPopupContainer?: AbstractTooltipProps['getPopupContainer'];\n\n /** 自定义 Tooltip 内容 */\n customTooltipRender?: (finalEl: React.ReactNode, checkOverflow?: () => boolean) => React.ReactNode;\n\n /** 自定义文本渲染,适用于一些需要把文本渲染为不同样式的场景 */\n customTextRender?: () => React.ReactElement;\n\n /** 自定义 Tooltip 文本渲染,适用于一些需要把文本渲染为不同样式的场景 */\n customTooltipTextRender?: (text: AbbrProps['text']) => React.ReactElement;\n\n /*\n * 是否在文字中间展示省略号,默认是在末尾展示省略号,只支持length模式\n * @default false\n */\n ellipsisInMiddle? = false;\n\n /*\n * 是否在文字前面展示省略号,默认是在末尾展示省略号,只支持length模式\n * @default false\n */\n ellipsisInFront? = false;\n\n /** 是否将中文、英文等字符的长度按照相同的长度计算 */\n equalLength? = false;\n\n /** 需要复制 */\n needCopy? = false;\n}\n", "componentCode": null, "documentation": "---\ncategory: 展示组件\ntitle: Abbr\nsubtitle: 在文案超长时,缩略显示,提供完整文案的浮层提示。\norder: 1\nmultiColumn: false\nauthor: 无浊\noverview: https://img.alicdn.com/imgextra/i4/O1CN01UxW0wk1lFs0e2MTJF_!!6000000004790-0-tps-446-306.jpg\n---\n\n# Abbr\n\n## 何时使用\n\n在文案超长时,缩略显示,提供完整文案的浮层提示。\n\n## 示例\n\