Shreyas094's picture
Upload 528 files
372531f verified
import Image from "next/image";
import { FC, useRef } from "react";
import TypeAnimation from "../../TypeAnimation";
type TInputAreaProps = {
promptValue: string;
setPromptValue: React.Dispatch<React.SetStateAction<string>>;
handleSubmit: (query: string) => void;
handleSecondary?: (query: string) => void;
disabled?: boolean;
reset?: () => void;
isStopped?: boolean;
};
// Debounce function to limit the rate at which a function can fire
function debounce(func: Function, wait: number) {
let timeout: NodeJS.Timeout | undefined;
return function executedFunction(...args: any[]) {
const later = () => {
clearTimeout(timeout);
func(...args);
};
clearTimeout(timeout);
timeout = setTimeout(later, wait);
};
}
const InputArea: FC<TInputAreaProps> = ({
promptValue,
setPromptValue,
handleSubmit,
handleSecondary,
disabled,
reset,
isStopped,
}) => {
// Only show input if not stopped
if (isStopped) {
return null;
}
const placeholder = handleSecondary
? "Any questions about this report?"
: "What would you like to research next?";
const textareaRef = useRef<HTMLTextAreaElement>(null);
const resetHeight = () => {
if (textareaRef.current) {
textareaRef.current.style.height = '3em'; // Reset to base height
}
};
const handleKeyDown = (e: React.KeyboardEvent<HTMLTextAreaElement>) => {
if (e.key === 'Enter') {
if (e.shiftKey) {
return; // Allow new line on Shift+Enter
} else {
e.preventDefault();
if (!disabled) {
if (reset) reset();
handleSubmit(promptValue);
setPromptValue(''); // Clear prompt value
resetHeight(); // Reset height after submit
}
}
}
};
// Debounced version of the height adjustment function
const adjustHeight = debounce((target: HTMLTextAreaElement) => {
target.style.height = 'auto'; // Reset height to auto to allow shrinking
target.style.height = `${target.scrollHeight}px`; // Adjust height
}, 100); // Adjust the delay as needed
const handleTextareaChange = (e: React.ChangeEvent<HTMLTextAreaElement>) => {
const target = e.target;
adjustHeight(target); // Use debounced function
setPromptValue(target.value);
};
return (
<form
className="mx-auto flex pt-2 pb-2 w-full items-center justify-between rounded-lg border bg-white px-3 shadow-[2px_2px_38px_0px_rgba(0,0,0,0.25),0px_-2px_4px_0px_rgba(0,0,0,0.25)_inset,1px_2px_4px_0px_rgba(0,0,0,0.25)_inset]"
onSubmit={(e) => {
e.preventDefault();
if (reset) reset();
handleSubmit(promptValue);
setPromptValue(''); // Clear prompt value
resetHeight();
}}
>
<textarea
placeholder={placeholder}
ref={textareaRef}
className="focus-visible::outline-0 my-1 w-full pl-5 font-light not-italic leading-[normal]
text-[#1B1B16]/30 text-black outline-none focus-visible:ring-0 focus-visible:ring-offset-0
sm:text-xl min-h-[3em] resize-none"
disabled={disabled}
value={promptValue}
required
rows={2}
onKeyDown={handleKeyDown}
onChange={handleTextareaChange}
/>
<button
disabled={disabled}
type="submit"
className="relative flex h-[50px] w-[50px] shrink-0 items-center justify-center rounded-[3px] bg-[linear-gradient(154deg,#1B1B16_23.37%,#565646_91.91%)] disabled:pointer-events-none disabled:opacity-75"
>
{disabled && (
<div className="absolute inset-0 flex items-center justify-center">
<TypeAnimation />
</div>
)}
<Image
unoptimized
src={"/img/arrow-narrow-right.svg"}
alt="search"
width={24}
height={24}
className={disabled ? "invisible" : ""}
/>
</button>
</form>
);
};
export default InputArea;