mirror of
https://github.com/arc53/DocsGPT.git
synced 2025-11-29 16:43:16 +00:00
chore: TextArea component to replace Div contentEditable for entering prompts
This commit is contained in:
71
frontend/src/components/TextArea.tsx
Normal file
71
frontend/src/components/TextArea.tsx
Normal file
@@ -0,0 +1,71 @@
|
||||
import React, { useEffect, useRef } from 'react';
|
||||
|
||||
type Props = {
|
||||
value: string | string[] | number;
|
||||
isAutoFocused: boolean;
|
||||
id?: string;
|
||||
maxLength?: number;
|
||||
name?: string;
|
||||
placeholder?: string;
|
||||
className?: string;
|
||||
children?: React.ReactElement;
|
||||
onChange: (e: React.ChangeEvent<HTMLTextAreaElement>) => void;
|
||||
onPaste?: (e: React.ClipboardEvent<HTMLTextAreaElement>) => void;
|
||||
onKeyDown?: (e: React.KeyboardEvent<HTMLTextAreaElement>) => void;
|
||||
};
|
||||
|
||||
const TextArea = ({
|
||||
value,
|
||||
isAutoFocused,
|
||||
id,
|
||||
maxLength,
|
||||
name,
|
||||
placeholder,
|
||||
className,
|
||||
children,
|
||||
onChange,
|
||||
onPaste,
|
||||
onKeyDown,
|
||||
}: Props) => {
|
||||
const textAreaRef = useRef<HTMLTextAreaElement>(null);
|
||||
|
||||
useEffect(() => {
|
||||
const autoResizeTextArea = () => {
|
||||
if (textAreaRef.current) {
|
||||
textAreaRef.current.style.height = 'auto';
|
||||
|
||||
const maxHeight = 96;
|
||||
const currentContentHeight = textAreaRef.current.scrollHeight;
|
||||
|
||||
const newHeight = Math.min(maxHeight, currentContentHeight);
|
||||
|
||||
textAreaRef.current.style.height = `${newHeight}px`;
|
||||
}
|
||||
};
|
||||
|
||||
autoResizeTextArea();
|
||||
}, [value]);
|
||||
|
||||
return (
|
||||
<textarea
|
||||
ref={textAreaRef}
|
||||
className={`} w-full resize-none self-stretch overflow-y-auto overflow-x-hidden whitespace-pre-wrap rounded-full bg-white px-9 pt-5 pb-[22px] text-base leading-tight opacity-100 focus:outline-none dark:bg-raisin-black
|
||||
dark:text-bright-gray ${className}`}
|
||||
id={id}
|
||||
rows={1}
|
||||
dir="auto"
|
||||
value={value}
|
||||
name={name}
|
||||
maxLength={maxLength}
|
||||
placeholder={placeholder}
|
||||
autoFocus={isAutoFocused}
|
||||
onChange={onChange}
|
||||
onPaste={onPaste}
|
||||
onKeyDown={onKeyDown}
|
||||
>
|
||||
{children}
|
||||
</textarea>
|
||||
);
|
||||
};
|
||||
|
||||
export default TextArea;
|
||||
@@ -20,7 +20,7 @@ import { sendFeedback } from './conversationApi';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import ArrowDown from './../assets/arrow-down.svg';
|
||||
import RetryIcon from '../components/RetryIcon';
|
||||
import TextInput from '../components/inputs/TextInput';
|
||||
import TextArea from '../components/TextArea';
|
||||
export default function Conversation() {
|
||||
const queries = useSelector(selectQueries);
|
||||
const status = useSelector(selectStatus);
|
||||
@@ -232,9 +232,9 @@ export default function Conversation() {
|
||||
|
||||
<div className="bottom-safe fixed flex w-11/12 flex-col items-end self-center rounded-2xl bg-opacity-0 pb-1 sm:w-6/12">
|
||||
<div className="flex h-full w-full items-center rounded-full border border-silver bg-white dark:bg-raisin-black">
|
||||
<TextInput
|
||||
variant="PROMPT"
|
||||
<TextArea
|
||||
value={prompt}
|
||||
isAutoFocused
|
||||
onChange={(e) => setPrompt(e.target.value)}
|
||||
placeholder={t('inputPlaceholder')}
|
||||
onPaste={handlePaste}
|
||||
@@ -244,7 +244,7 @@ export default function Conversation() {
|
||||
handleQuestionSubmission();
|
||||
}
|
||||
}}
|
||||
></TextInput>
|
||||
></TextArea>{' '}
|
||||
{status === 'loading' ? (
|
||||
<img
|
||||
src={isDarkTheme ? SpinnerDark : Spinner}
|
||||
|
||||
Reference in New Issue
Block a user