EditableCell.tsx 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. import { Form, FormInstance, Input, InputRef } from "antd";
  2. import React, { useContext, useEffect, useRef, useState } from "react";
  3. import './index.less'
  4. export const EditableContext = React.createContext<FormInstance<any> | null>(null);
  5. interface Item {
  6. key: string;
  7. name: string;
  8. age: string;
  9. address: string;
  10. }
  11. interface EditableCellProps {
  12. title: React.ReactNode;
  13. editable: boolean;
  14. children: React.ReactNode;
  15. dataIndex: keyof Item;
  16. record: Item;
  17. handleSave: (record: Item) => void;
  18. }
  19. const EditableCell: React.FC<EditableCellProps> = ({
  20. title,
  21. editable,
  22. children,
  23. dataIndex,
  24. record,
  25. handleSave,
  26. ...restProps
  27. }) => {
  28. const [editing, setEditing] = useState(false);
  29. const inputRef = useRef<InputRef>(null);
  30. const form = useContext(EditableContext)!;
  31. useEffect(() => {
  32. if (editing) {
  33. inputRef.current!.focus();
  34. }
  35. }, [editing]);
  36. const toggleEdit = () => {
  37. setEditing(!editing);
  38. form.setFieldsValue({ [dataIndex]: record[dataIndex] });
  39. };
  40. const save = async () => {
  41. try {
  42. const values = await form.validateFields();
  43. if (values?.adgroupName !== (record as any)?.adgroupName) {
  44. handleSave({ ...record, ...values });
  45. }
  46. toggleEdit();
  47. } catch (errInfo) {
  48. console.log('Save failed:', errInfo);
  49. }
  50. };
  51. let childNode = children;
  52. if (editable) {
  53. childNode = editing ? (<Form.Item
  54. style={{ margin: 0 }}
  55. name={dataIndex}
  56. rules={[{ required: true, message: `${title} is required.` }]}
  57. >
  58. <Input ref={inputRef} size="small" onPressEnter={save} onBlur={save} bordered/>
  59. </Form.Item>) : (<div className="editable-cell-value-wrap ellipsisText" onClick={toggleEdit}>
  60. {children}
  61. </div>);
  62. }
  63. return <td {...restProps}>{childNode}</td>;
  64. };
  65. export default React.memo(EditableCell)