(props: {
className: string;
placeholder: string;
value: string;
onChange: (e: React.ChangeEvent<HTMLTextAreaElement>) => void;
onKeyDown?: (e: React.KeyboardEvent<HTMLTextAreaElement>) => void;
minHeight?: number;
maxHeight?: number;
onBlur?: React.FocusEventHandler<HTMLTextAreaElement>;
disabled?: boolean;
ref?: React.RefObject<HTMLTextAreaElement>;
})
| 1 | import React, { useEffect, useRef } from "react"; |
| 2 | |
| 3 | export function AutoGrowingTextArea(props: { |
| 4 | className: string; |
| 5 | placeholder: string; |
| 6 | value: string; |
| 7 | onChange: (e: React.ChangeEvent<HTMLTextAreaElement>) => void; |
| 8 | onKeyDown?: (e: React.KeyboardEvent<HTMLTextAreaElement>) => void; |
| 9 | minHeight?: number; |
| 10 | maxHeight?: number; |
| 11 | onBlur?: React.FocusEventHandler<HTMLTextAreaElement>; |
| 12 | disabled?: boolean; |
| 13 | ref?: React.RefObject<HTMLTextAreaElement>; |
| 14 | }) { |
| 15 | const localRef = useRef(null); |
| 16 | const ref = props.ref ?? localRef; |
| 17 | |
| 18 | useEffect(() => { |
| 19 | if (ref.current === null) return; |
| 20 | // @ts-ignore |
| 21 | ref.current.style.height = "5px"; |
| 22 | |
| 23 | let maxH = props.maxHeight ?? 500; |
| 24 | let minH = props.minHeight ?? 0; |
| 25 | |
| 26 | // @ts-ignore |
| 27 | ref.current.style.height = |
| 28 | // @ts-ignore |
| 29 | Math.max(Math.min(ref.current.scrollHeight, maxH), minH) + "px"; |
| 30 | }, [ref.current, props.value]); |
| 31 | |
| 32 | return ( |
| 33 | <textarea |
| 34 | ref={ref} |
| 35 | className={props.className} |
| 36 | placeholder={props.placeholder} |
| 37 | value={props.value} |
| 38 | onChange={props.onChange} |
| 39 | onKeyDown={props.onKeyDown ?? (() => {})} |
| 40 | onBlur={props.onBlur ?? (() => {})} |
| 41 | disabled={!!props.disabled} |
| 42 | /> |
| 43 | ); |
| 44 | } |
nothing calls this directly
no outgoing calls
no test coverage detected