import React from "react"; import classNames from "classnames"; import { TableAddon } from "../../TableProps"; import { noop } from "../../../_util/noop"; import { RowsDraggableTable, RowsDraggableTableBody, DraggableTableRow, } from "./RowsDraggableTable"; import { CheckTreeRelation } from "../../../checktree"; import { getRowKeyFromRecordKey } from "../../util/get-row-key-from-record-key"; import { injectPropsIfTargetNotExisted } from "../../util/inject-props-if-target-not-existed"; import { Icon } from "../../../icon"; /** * `RowsDraggable` 插件用于支持表格行拖拽排序操作。 */ export interface RowsDraggableOptions { /** * 提供 `relations` 属性,结合 expandable 插件 */ relations?: CheckTreeRelation; /** * 用户进行展开/收起操作的时候,知会最新的键值,结合 expandable 插件 */ onExpandedKeysChange?: ( value: string[], context?: { event: React.SyntheticEvent; operateType: "expand" | "collapse"; operateKey: string; operateRecord: Record; } ) => void; /** * 展开行的键值,结合 expandable 插件 */ expandedKeys?: string[]; /** * 子级相对父级缩进量,结合 expandable 插件 * @default 20 */ indent?: number; /** * 拖拽完成回调 */ onDragEnd: ( records: Record[], dragContext?: { dragKey?: string; dragRecordIndex?: number; dragRecord?: Record; dropKey?: string; dropDepth?: number; } ) => void; /** * 拖拽开始时回调 */ onDragStart?: (context: any) => void; /** * 拖拽类型,树拖拽排序或者仅行拖拽 * @default "row" */ dragType?: "tree" | "row"; /** * 可拖拽的行, 默认所有行 * @default "all" */ draggableRowKeys?: string[] | "all"; /** * 子树列表字段名,树形拖拽需传该参数 */ childrenColName?: string; /** * 隐藏拖拽手柄图标 * * *默认值:* * * - *内置拖拽 `"unhover"`* * - *第三方库拖拽 `false`* */ hideHandler?: boolean | "unhover"; /** * 拖拽手柄列宽度,可以指定 CSS 属性或数字 (单位:px) * @default 46 */ width?: string | number; /** * 拖拽手柄图标 * * *参考 Icon 组件[图标类型](/component/icon)* * * @default "drop" */ icon?: string; /** * 提供一个列的 `key`,将icon插入到一个目标列 * * 默认在最前新建一列插入 */ targetColumnKey?: string; } const fallbackColumnKey = "__row_draggable_addon__"; export function rowsDraggable({ onDragEnd = noop, onDragStart = noop, draggableRowKeys = "all", childrenColName = "childrenList", dragType = "row", relations, onExpandedKeysChange, expandedKeys, indent = 20, hideHandler = "unhover", icon, width = 26, targetColumnKey, ...options }: RowsDraggableOptions): TableAddon { const iconColumnWidth = (options as any).iconColumnWidth || (typeof width === "number" ? width : 26); let getRowKey: ReturnType; let recordsData = []; return { getInfo: () => ({ name: "draggable" }), onInjectProps: props => { const { recordKey, records } = props; recordsData = records; getRowKey = getRowKeyFromRecordKey(recordKey); const columns = hideHandler !== true ? injectPropsIfTargetNotExisted(props.columns, targetColumnKey, { key: fallbackColumnKey, width: iconColumnWidth, header: null, render: () => null, }) : props.columns; return { ...props, rowsDraggable: true, draggableRowKeys, columns, }; }, onInjectTable: render => props => { const table = render(props); return ( ); }, onInjectBody: render => (records, rows, topTip, bottomTip) => { const body = render(records, rows, topTip, bottomTip); return ; }, onInjectRow: renderRow => (record, rowKey, recordIndex, columns) => { const key = getRowKey(record, recordIndex); const { prepends, row, appends } = renderRow( record, rowKey, recordIndex, columns ); // 表头跳过 if (recordIndex === -1) { return { prepends, row, appends }; } return { prepends, row: ( ), appends, }; }, onInjectColumn: previous => ( record, rowKey, recordIndex, column, columnIndex ) => { // 不是目标列 if (column.key !== targetColumnKey && column.key !== fallbackColumnKey) { return previous(record, rowKey, recordIndex, column, columnIndex); } const { children, props, ...result } = previous( record, rowKey, recordIndex, column, columnIndex ); let childrenWrap = children; // 非表头 if (recordIndex !== -1 && hideHandler !== true) { childrenWrap = (
{children}
); } return { ...result, props, children: childrenWrap }; }, }; }