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.

96 lines
2.0KB

  1. import React, { useMemo, useState } from "react";
  2. import { TextField, TextFieldProps } from "@mui/material";
  3. import { Dictionary } from "@types";
  4. export type TextFieldCustomProps = {
  5. onFix?: () => void;
  6. onChangeValue?: (val: string) => void;
  7. messages?: Dictionary;
  8. readonly?: boolean;
  9. } & TextFieldProps;
  10. export default function TextFieldCustom({
  11. onFix,
  12. onChangeValue,
  13. messages,
  14. readonly,
  15. ...others
  16. }: TextFieldCustomProps) {
  17. const [oldValue, setOldValue] = useState<string | null>(null);
  18. const inputProps = useMemo(() => {
  19. if (readonly) {
  20. return {
  21. style: { color: "rgb(50, 50, 50)" },
  22. disabled: true,
  23. };
  24. } else {
  25. return undefined;
  26. }
  27. }, [readonly]);
  28. const fix = (newValue: string) => {
  29. if (oldValue !== newValue) {
  30. setOldValue(newValue);
  31. if (onFix) {
  32. onFix();
  33. }
  34. }
  35. };
  36. const handleEnter = (e: React.KeyboardEvent<HTMLInputElement>) => {
  37. if (e.key === "Enter") {
  38. if (e.target instanceof HTMLInputElement) {
  39. fix(e.target.value);
  40. }
  41. }
  42. };
  43. const handleBlur = (e: React.FocusEvent<HTMLInputElement>) => {
  44. if (!others.select) {
  45. fix(e.target.value);
  46. }
  47. };
  48. const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
  49. if (onChangeValue) {
  50. onChangeValue(e.target.value);
  51. }
  52. if (others.select) {
  53. fix(e.target.value);
  54. }
  55. };
  56. const message = useMemo(() => {
  57. if (messages && others.name) {
  58. return messages[others.name] ?? "";
  59. } else {
  60. return "";
  61. }
  62. }, [messages]);
  63. const error = useMemo(() => {
  64. if (messages && others.name) {
  65. return (
  66. messages[others.name] !== undefined &&
  67. messages[others.name].length !== 0
  68. );
  69. } else {
  70. return false;
  71. }
  72. }, [messages]);
  73. return (
  74. <TextField
  75. size="small"
  76. onKeyDown={handleEnter}
  77. onBlur={handleBlur}
  78. onChange={handleChange}
  79. helperText={message}
  80. error={error}
  81. inputProps={inputProps}
  82. {...others}
  83. />
  84. );
  85. }