index.tsx 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. import { View, Textarea, InputProps } from "@tarojs/components";
  2. import styleIndex from "./index.module.less";
  3. import { useState, useRef, useEffect } from "react";
  4. import { countCharacters, getStrByMaxLength } from "@/utils/index";
  5. interface Props {
  6. placeholder?: string;
  7. value: string;
  8. cursorSpacing?: number;
  9. maxlength?: number;
  10. autoHeight?: boolean;
  11. disabled?: boolean;
  12. confirmType?: keyof InputProps.ConfirmType;
  13. extra?: () => JSX.Element | JSX.Element[] | undefined;
  14. prefix?: () => JSX.Element | JSX.Element[] | undefined;
  15. style?: React.CSSProperties;
  16. onInput?: (value: string) => void;
  17. onBlur?: (value: string) => void;
  18. bgColor?: string;
  19. autoFocus?: boolean;
  20. extraClass?: string;
  21. onConfirm?: (value: string) => void;
  22. placeholderStyle?: string;
  23. }
  24. let isInbox = false;
  25. const index = ({
  26. value,
  27. bgColor,
  28. extraClass,
  29. style,
  30. disabled,
  31. confirmType,
  32. prefix,
  33. autoHeight,
  34. autoFocus = false,
  35. placeholder = "请输入...",
  36. onInput,
  37. onBlur,
  38. cursorSpacing,
  39. maxlength,
  40. extra,
  41. onConfirm,
  42. placeholderStyle,
  43. }: Props) => {
  44. const [focus, setFocus] = useState(false);
  45. const inputRef = useRef<HTMLInputElement>(null); // 创建一个 ref
  46. const handleFocus = () => {
  47. isInbox = false;
  48. setFocus(true);
  49. };
  50. const handleBlur = () => {
  51. // console.log("textarea blur");
  52. if (!isInbox) {
  53. setFocus(false);
  54. if (onBlur && inputRef.current) {
  55. onBlur(inputRef.current.value);
  56. }
  57. }
  58. };
  59. const handleInput = (value: string) => {
  60. const len = countCharacters(value);
  61. if (maxlength && len > maxlength) {
  62. const r = getStrByMaxLength(value, maxlength);
  63. onInput && onInput(r);
  64. return;
  65. }
  66. onInput && onInput(value);
  67. };
  68. return (
  69. <View
  70. className={`${
  71. focus ? styleIndex.inputContainerFocused : styleIndex.inputContainer
  72. } p-12`}
  73. style={bgColor ? { backgroundColor: bgColor } : {}}
  74. >
  75. {prefix && prefix()}
  76. <View className={styleIndex.textareaContainer}>
  77. <Textarea
  78. ref={inputRef}
  79. value={value}
  80. disabled={disabled}
  81. confirmType={confirmType}
  82. style={style}
  83. onInput={(e: any) => handleInput(e.target.value)}
  84. placeholder={placeholder}
  85. placeholderStyle={placeholderStyle ?? 'color: rgba(17,17,17,.25)'}
  86. className={`${styleIndex.textInput} ${extraClass}`}
  87. onFocus={handleFocus}
  88. onBlur={handleBlur}
  89. autoHeight={autoHeight}
  90. autoFocus={autoFocus}
  91. cursorSpacing={cursorSpacing}
  92. maxlength={10000}
  93. onConfirm={(e: any) => {
  94. onConfirm && onConfirm(e.detail.value);
  95. }}
  96. />
  97. <View className={`${styleIndex.textareaButtons} justify-end gap-8`}>
  98. {extra && extra()}
  99. {/* <View className={`button-rounded-mini ${!value.length ? 'disabled' :''}`} onClick={handleClear}>清除</View> */}
  100. {maxlength && (
  101. <View className="text-gray-4">
  102. {maxlength}/{countCharacters(value)}
  103. </View>
  104. )}
  105. </View>
  106. </View>
  107. </View>
  108. );
  109. };
  110. export default index;