You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

87 rivejä
2.0 KiB

  1. import React, {
  2. ChangeEventHandler,
  3. useCallback,
  4. useEffect,
  5. useRef,
  6. useState,
  7. } from "react";
  8. import { Box, Input, SxProps, TableCell } from "@mui/material";
  9. interface Props<T> {
  10. value: T;
  11. onChange: (newValue?: T) => void;
  12. renderValue?: (value: T) => string;
  13. convertValue: (inputValue?: string) => T;
  14. cellSx?: SxProps;
  15. inputSx?: SxProps;
  16. }
  17. const TableCellEdit = <T,>({
  18. value,
  19. renderValue = (val) => `${val}`,
  20. convertValue,
  21. onChange,
  22. cellSx,
  23. inputSx,
  24. }: Props<T>) => {
  25. const [editMode, setEditMode] = useState(false);
  26. const [input, setInput] = useState<string>();
  27. const inputRef = useRef<HTMLInputElement>(null);
  28. const onClick = useCallback(() => {
  29. setEditMode(true);
  30. setInput(`${value}`);
  31. }, [value]);
  32. const onInputChange = useCallback<ChangeEventHandler<HTMLInputElement>>(
  33. (e) => setInput(e.target.value),
  34. [],
  35. );
  36. const onBlur = useCallback(() => {
  37. setEditMode(false);
  38. onChange(convertValue(input));
  39. setInput(undefined);
  40. }, [convertValue, input, onChange]);
  41. useEffect(() => {
  42. if (editMode && inputRef.current) {
  43. inputRef.current?.focus();
  44. }
  45. }, [editMode]);
  46. return (
  47. <TableCell
  48. sx={{
  49. outline: editMode ? "1px solid" : undefined,
  50. outlineColor: editMode ? "primary.main" : undefined,
  51. ...cellSx,
  52. }}
  53. >
  54. <Input
  55. sx={{
  56. display: editMode ? "block" : "none",
  57. "::after": { display: "none " },
  58. "::before": { display: "none " },
  59. height: "inherit",
  60. width: "inherit",
  61. padding: 0,
  62. fontWeight: "inherit",
  63. lineHeight: "inherit",
  64. ...inputSx,
  65. }}
  66. inputRef={inputRef}
  67. value={input}
  68. onChange={onInputChange}
  69. onBlur={onBlur}
  70. type={typeof value === "number" ? "number" : "text"}
  71. />
  72. <Box sx={{ display: editMode ? "none" : "block" }} onClick={onClick}>
  73. {renderValue(value)}
  74. </Box>
  75. </TableCell>
  76. );
  77. };
  78. export default TableCellEdit;