[WEB-1024] fix: textarea component auto-resize (#4221)
* chore: updated resize hook logic * fix: page title overflow issue * chore: add length validation to page title
This commit is contained in:
parent
10ed12e589
commit
f0cb48006f
4 changed files with 74 additions and 36 deletions
|
|
@ -1,6 +1,8 @@
|
|||
import * as React from "react";
|
||||
import React, { useRef } from "react";
|
||||
// helpers
|
||||
import { cn } from "../../helpers";
|
||||
// hooks
|
||||
import { useAutoResizeTextArea } from "../hooks/use-auto-resize-textarea";
|
||||
|
||||
export interface TextAreaProps extends React.TextareaHTMLAttributes<HTMLTextAreaElement> {
|
||||
mode?: "primary" | "transparent";
|
||||
|
|
@ -8,21 +10,6 @@ export interface TextAreaProps extends React.TextareaHTMLAttributes<HTMLTextArea
|
|||
className?: string;
|
||||
}
|
||||
|
||||
// Updates the height of a <textarea> when the value changes.
|
||||
const useAutoSizeTextArea = (textAreaRef: HTMLTextAreaElement | null, value: any) => {
|
||||
React.useEffect(() => {
|
||||
if (textAreaRef) {
|
||||
// We need to reset the height momentarily to get the correct scrollHeight for the textarea
|
||||
textAreaRef.style.height = "0px";
|
||||
const scrollHeight = textAreaRef.scrollHeight;
|
||||
|
||||
// We then set the height directly, outside of the render loop
|
||||
// Trying to set this with state or a ref will product an incorrect value.
|
||||
textAreaRef.style.height = scrollHeight + "px";
|
||||
}
|
||||
}, [textAreaRef, value]);
|
||||
};
|
||||
|
||||
const TextArea = React.forwardRef<HTMLTextAreaElement, TextAreaProps>((props, ref) => {
|
||||
const {
|
||||
id,
|
||||
|
|
@ -35,10 +22,10 @@ const TextArea = React.forwardRef<HTMLTextAreaElement, TextAreaProps>((props, re
|
|||
className = "",
|
||||
...rest
|
||||
} = props;
|
||||
|
||||
const textAreaRef = React.useRef<any>(ref);
|
||||
|
||||
useAutoSizeTextArea(textAreaRef?.current, value);
|
||||
// refs
|
||||
const textAreaRef = useRef<any>(ref);
|
||||
// auto re-size
|
||||
useAutoResizeTextArea(textAreaRef);
|
||||
|
||||
return (
|
||||
<textarea
|
||||
|
|
|
|||
24
packages/ui/src/hooks/use-auto-resize-textarea.ts
Normal file
24
packages/ui/src/hooks/use-auto-resize-textarea.ts
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
import { useEffect } from "react";
|
||||
|
||||
export const useAutoResizeTextArea = (textAreaRef: React.RefObject<HTMLTextAreaElement>) => {
|
||||
useEffect(() => {
|
||||
const textArea = textAreaRef.current;
|
||||
if (!textArea) return;
|
||||
|
||||
const resizeTextArea = () => {
|
||||
textArea.style.height = "auto";
|
||||
const computedHeight = textArea.scrollHeight + "px";
|
||||
textArea.style.height = computedHeight;
|
||||
};
|
||||
|
||||
const handleInput = () => resizeTextArea();
|
||||
|
||||
// resize on mount
|
||||
resizeTextArea();
|
||||
|
||||
textArea.addEventListener("input", handleInput);
|
||||
return () => {
|
||||
textArea.removeEventListener("input", handleInput);
|
||||
};
|
||||
}, [textAreaRef]);
|
||||
};
|
||||
Loading…
Add table
Add a link
Reference in a new issue