feat: implement auto-resizing textarea in ChatInput component
This commit is contained in:
@@ -6,20 +6,55 @@ interface ChatInputProps
|
|||||||
extends React.TextareaHTMLAttributes<HTMLTextAreaElement> {}
|
extends React.TextareaHTMLAttributes<HTMLTextAreaElement> {}
|
||||||
|
|
||||||
const ChatInput = React.forwardRef<HTMLTextAreaElement, ChatInputProps>(
|
const ChatInput = React.forwardRef<HTMLTextAreaElement, ChatInputProps>(
|
||||||
({ className, ...props }, ref) => (
|
({ className, onChange, ...props }, ref) => {
|
||||||
|
const internalRef = React.useRef<HTMLTextAreaElement>(null);
|
||||||
|
|
||||||
|
// Combine the forwarded ref with the internal ref
|
||||||
|
React.useImperativeHandle(
|
||||||
|
ref,
|
||||||
|
() => internalRef.current as HTMLTextAreaElement
|
||||||
|
);
|
||||||
|
|
||||||
|
// Function to adjust the height of the textarea
|
||||||
|
const adjustHeight = () => {
|
||||||
|
if (internalRef.current) {
|
||||||
|
// Reset the height to auto to calculate the new height
|
||||||
|
internalRef.current.style.height = "auto";
|
||||||
|
// Set the height to the scrollHeight (content height)
|
||||||
|
internalRef.current.style.height = `${internalRef.current.scrollHeight}px`;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Adjust height whenever the content changes
|
||||||
|
React.useEffect(() => {
|
||||||
|
adjustHeight();
|
||||||
|
}, [props.value]); // Run whenever the value changes
|
||||||
|
|
||||||
|
// Handle input changes
|
||||||
|
const handleInput = (e: React.ChangeEvent<HTMLTextAreaElement>) => {
|
||||||
|
adjustHeight();
|
||||||
|
if (onChange) {
|
||||||
|
onChange(e); // Call the passed onChange handler
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
<Textarea
|
<Textarea
|
||||||
mockOnChange={false}
|
mockOnChange={false}
|
||||||
autoComplete="off"
|
autoComplete="off"
|
||||||
ref={ref}
|
ref={internalRef}
|
||||||
name="message"
|
name="message"
|
||||||
className={cn(
|
className={cn(
|
||||||
"max-h-12 px-4 py-3 bg-background text-sm placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50 w-full rounded-md flex items-center h-16 resize-none",
|
"max-h-48 px-4 py-3 bg-background text-sm placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50 w-full rounded-md flex items-center resize-none",
|
||||||
className
|
className
|
||||||
)}
|
)}
|
||||||
|
onChange={handleInput}
|
||||||
{...props}
|
{...props}
|
||||||
/>
|
/>
|
||||||
)
|
);
|
||||||
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
ChatInput.displayName = "ChatInput";
|
ChatInput.displayName = "ChatInput";
|
||||||
|
|
||||||
export { ChatInput };
|
export { ChatInput };
|
||||||
|
|||||||
Reference in New Issue
Block a user