EditableLabel.tsx 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. import { useEffect, useRef, useState } from "react";
  2. import "./style.css";
  3. interface IWidget {
  4. defaultValue?: string;
  5. value?: string;
  6. placeholder?: string;
  7. style?: React.CSSProperties;
  8. onChange?: Function;
  9. onKeyDown?: Function;
  10. onBlur?: Function;
  11. onPressEnter?: Function;
  12. }
  13. const EditableLabelWidget = ({
  14. defaultValue,
  15. value,
  16. placeholder,
  17. style,
  18. onChange,
  19. onKeyDown,
  20. onBlur,
  21. onPressEnter,
  22. }: IWidget) => {
  23. const [textAreaValue, setTextAreaValue] = useState(defaultValue);
  24. const [shadowText, setShadowText] = useState(defaultValue);
  25. const [textAreaHeight, setTextAreaHeight] = useState<number | undefined>(31);
  26. const [shadowHeight, _setShadowHeight] = useState<number | undefined>(31);
  27. const refTextArea = useRef<HTMLTextAreaElement>(null);
  28. const refShadow = useRef<HTMLDivElement>(null);
  29. useEffect(() => {
  30. setTextAreaValue(value);
  31. setShadowText(value);
  32. }, [value]);
  33. useEffect(() => {
  34. setTextAreaHeight(refShadow.current?.clientHeight);
  35. }, []);
  36. return (
  37. <div className="text_input" style={style}>
  38. <div
  39. ref={refShadow}
  40. className="textarea text_shadow"
  41. style={{
  42. height: shadowHeight,
  43. display: "inline-block",
  44. minHeight: "1em",
  45. minWidth: "15em",
  46. }}
  47. onResize={(_event: React.SyntheticEvent<HTMLDivElement, Event>) => {
  48. setTextAreaHeight(refShadow.current?.clientHeight);
  49. }}
  50. >
  51. {shadowText}
  52. </div>
  53. <textarea
  54. className="textarea tran_sent_textarea"
  55. ref={refTextArea}
  56. style={{
  57. height: textAreaHeight,
  58. display: "inline-block",
  59. minHeight: "1em",
  60. minWidth: "15em",
  61. resize: "none",
  62. overflow: "hidden",
  63. borderBottom: "1px solid",
  64. borderRadius: 0,
  65. }}
  66. placeholder={placeholder}
  67. value={textAreaValue}
  68. onBlur={(event: React.FocusEvent<HTMLTextAreaElement, Element>) => {
  69. if (typeof onBlur !== "undefined") {
  70. onBlur(event);
  71. }
  72. }}
  73. onChange={(event: React.ChangeEvent<HTMLTextAreaElement>) => {
  74. setTextAreaValue(event.target.value);
  75. setShadowText(event.target.value);
  76. if (typeof onChange !== "undefined") {
  77. onChange(event);
  78. }
  79. }}
  80. onResize={(_event: unknown) => {
  81. //setShadowHeight(refTextArea.current?.clientHeight);
  82. }}
  83. onKeyDown={(event: React.KeyboardEvent<HTMLTextAreaElement>) => {
  84. if (typeof onKeyDown !== "undefined") {
  85. onKeyDown(event);
  86. }
  87. if (event.key === "Enter" && typeof onPressEnter !== "undefined") {
  88. onPressEnter(event, textAreaValue);
  89. }
  90. }}
  91. onKeyUp={(_event) => {
  92. //自适应高度
  93. if (
  94. refShadow.current === null ||
  95. refTextArea.current === null ||
  96. refTextArea.current.parentElement === null
  97. ) {
  98. return;
  99. }
  100. setTextAreaHeight(refShadow.current.scrollHeight);
  101. }}
  102. />
  103. </div>
  104. );
  105. };
  106. export default EditableLabelWidget;