import React, { useState, useRef, useEffect, useContext, useCallback } from 'react'; import { Button, Table, Input, Select, Form, FormInstance, Switch, DatePicker } from '@arco-design/web-react'; const FormItem = Form.Item; const EditableContext = React.createContext<{ getForm?: () => FormInstance }>({}); interface EditableTableProps { columns: ColumnProps[]; data: any[]; onDataChange?: (data: any[]) => void; showAddButton?: boolean; addButtonText?: string; onAdd?: () => void; showDeleteButton?: boolean; deleteButtonText?: string; onDelete?: (key: string) => void; // Table组件的其他配置属性 tableProps?: any; // 添加空数据的配置 emptyItem?: any; } interface ColumnProps { title: string; dataIndex: string; editable?: boolean; render?: (text: any, record: any, index: number) => React.ReactNode; // 用于指定编辑时使用的组件类型 editComponent?: 'input' | 'select' | 'switch' | 'date' | 'custom'; // 用于select组件的选项 options?: { label: string; value: any }[]; // 用于自定义渲染编辑组件 renderEdit?: (props: EditComponentProps) => React.ReactNode; // 其他列配置属性 [key: string]: any; } interface EditComponentProps { value: any; onChange: (value: any) => void; rowData: any; column: ColumnProps; } interface EditableRowProps { children: React.ReactNode; record: any; className: string; [key: string]: any; } interface EditableCellProps { children: React.ReactNode; className: string; rowData: any; column: ColumnProps; onHandleSave: (row: any) => void; } function EditableRow(props: EditableRowProps) { const { children, record, className, ...rest } = props; const refForm = useRef(null); const getForm = () => refForm.current; return (
{children}
); } function EditableCell(props: EditableCellProps) { const { children, className, rowData, column, onHandleSave } = props; const { getForm } = useContext(EditableContext); const cellValueChangeHandler = (value: any) => { const values = { [column.dataIndex]: value }; onHandleSave && onHandleSave({ ...rowData, ...values }); }; // 渲染编辑组件 const renderEditComponent = () => { // 如果有自定义渲染函数,使用它 if (column.renderEdit) { return column.renderEdit({ value: rowData[column.dataIndex], onChange: cellValueChangeHandler, rowData, column }); } // 根据editComponent类型渲染不同的组件 switch (column.editComponent) { case 'select': return ( cellValueChangeHandler(value)} style={{ width: '100%' }} /> ); } }; // 如果列是可编辑的,直接渲染编辑组件 if (column.editable) { return (
{renderEditComponent()}
); } // 非编辑状态直接显示文本 return (
{children}
); } const EditableTable: React.FC = ({ columns, data, onDataChange, showAddButton = true, addButtonText = 'Add', onAdd, showDeleteButton = true, deleteButtonText = 'Delete', onDelete, tableProps = {}, emptyItem = {} }) => { const [tableData, setTableData] = useState(data); useEffect(() => { setTableData(data); }, [data]); const handleSave = (row: any) => { const newData = [...tableData]; const index = newData.findIndex((item) => row.key === item.key); if (index !== -1) { newData.splice(index, 1, { ...newData[index], ...row }); setTableData(newData); onDataChange && onDataChange(newData); } }; const removeRow = (key: string) => { const newData = tableData.filter((item) => item.key !== key); setTableData(newData); onDataChange && onDataChange(newData); onDelete && onDelete(key); }; const addRow = () => { if (onAdd) { onAdd(); } else { // 添加一条空数据 const newKey = `${Date.now()}`; const newRow = { key: newKey, ...emptyItem }; const newData = [...tableData, newRow]; setTableData(newData); onDataChange && onDataChange(newData); } }; // 处理列配置,添加删除按钮 const processedColumns = [...columns]; if (showDeleteButton && !columns.some(col => col.dataIndex === 'op')) { processedColumns.push({ title: 'Operation', dataIndex: 'op', render: (_: any, record: any) => ( ) }); } return ( <> {showAddButton && ( )} column.editable ? { ...column, onCell: () => ({ onHandleSave: handleSave }) } : column )} className="table-demo-editable-cell" {...tableProps} /> ); }; export default EditableTable;