From a726cb38998e1000ba527d5827323e9fb6715009 Mon Sep 17 00:00:00 2001 From: Max Novich Date: Wed, 27 Nov 2024 10:40:15 -0800 Subject: [PATCH] [feat]: Made input resizable + newline support (#359) --- ui/desktop/src/components/Input.tsx | 67 +++++++++++++++++++---- ui/desktop/src/components/UserMessage.tsx | 2 +- 2 files changed, 56 insertions(+), 13 deletions(-) diff --git a/ui/desktop/src/components/Input.tsx b/ui/desktop/src/components/Input.tsx index 3efe57254..598767a92 100644 --- a/ui/desktop/src/components/Input.tsx +++ b/ui/desktop/src/components/Input.tsx @@ -1,27 +1,70 @@ -import React from 'react'; -import { Button } from './ui/button' -import Send from './ui/Send' +import React, { useRef, useState, useEffect } from 'react'; +import { Button } from './ui/button'; +import Send from './ui/Send'; interface InputProps { handleSubmit: (e: React.FormEvent) => void; - handleInputChange: (e: React.ChangeEvent) => void; + handleInputChange: (e: React.ChangeEvent) => void; input: string; disabled?: boolean; } export default function Input({ handleSubmit, handleInputChange, input, disabled = false }: InputProps) { + const [value, setValue] = useState(input); + const textAreaRef = useRef(null); + + const useAutosizeTextArea = (textAreaRef: HTMLTextAreaElement | null, value: string) => { + useEffect(() => { + if (textAreaRef) { + textAreaRef.style.height = "0px"; // Reset height + const scrollHeight = textAreaRef.scrollHeight; + textAreaRef.style.height = Math.min(scrollHeight, maxHeight) + "px"; + } + }, [textAreaRef, value]); + }; + + const minHeight = "1rem"; + const maxHeight = 10 * 24; + + useAutosizeTextArea(textAreaRef.current, value); + + const handleChange = (evt: React.ChangeEvent) => { + const val = evt.target?.value; + setValue(val); + handleInputChange(evt); + }; + + const handleKeyDown = (evt: React.KeyboardEvent) => { + if (evt.key === 'Enter' && !evt.shiftKey) { + evt.preventDefault(); + handleSubmit(new CustomEvent('submit', { detail: { value } })); // Trigger custom form submit + setValue(''); // Clear textarea + } + }; + return ( -
- { + handleSubmit(e); + setValue(''); + }} className="flex relative bg-white h-auto px-[16px] pr-[38px] py-[1rem] rounded-b-2xl"> +