I’m working on an input field that combines user input (userText
) and AI-generated suggestions (aiText
). The goal is to make them appear as part of the same sentence, even when the user hasn’t accepted the AI’s suggestions yet.
Currently, the input field is single-line, and when aiText
is longer, it breaks awkwardly in the middle of the input field, making it look disjointed. Ideally, if aiText
needs to wrap to a new line, it should start from the very left of the input component, not from the middle where userText
ends.
Here’s the current implementation:
<div
onClick={focusContentEditable}
className="relative flex justify-start items-start p-3 border border-border
bg-[#FFFFFF] text-[#1F1F1F] dark:bg-[#2A2A40] dark:text-[#EAEAEA]
focus-within:outline focus-within:outline-[#9462fd]
cursor-text rounded-2xl text-left w-full h-20 mx-auto
overflow-hidden"
>
{/* Placeholder */}
{userText.trim() === "" && !isFocused && (
<span className="text-gray-400 text-xs">Ask me anything...</span>
)}
<div className="inline-flex items-baseline">
<span
ref={contentEditableRef}
className="text-xs border-0 outline-none whitespace-nowrap break-words inline-flex min-h-[20px] w-full"
contentEditable={true}
suppressContentEditableWarning={true}
onInput={handleInput}
onKeyDown={handleKeyDown}
>
{/* {userText} */}
</span>
<span
className={`text-xs text-gray-400 dark:text-gray-600 transition-opacity whitespace-normal inline-flex duration-500 ${
aiText ? "opacity-100" : "opacity-0"
}`}
contentEditable={false}
>
{aiText.length > 0 && userText.trim() !== "" && <>{aiText}</>}
</span>
</div>
</div>
Problem:
- The input field is single-line, and I’m not enforcing line breaks.
- When
aiText
is present and long, it breaks mid-line, which disrupts the flow of the text. - I want the input field to expand in height to accommodate a second line if needed, so
aiText
can wrap cleanly to the next line starting from the left edge.
What I’ve Tried:
- Using
contentEditable
for dynamic text input. - Combining
userText
andaiText
in a single container withinline-flex
to keep them aligned.
Desired Behavior:
- The input field should expand in height to allow multi-line text.
aiText
should wrap to the next line starting from the left edge if it doesn’t fit in the current line.userText
andaiText
should appear as part of the same sentence.
Any suggestions on how to achieve this? Thanks in advance!
I’m working on an input field that combines user input (userText
) and AI-generated suggestions (aiText
). The goal is to make them appear as part of the same sentence, even when the user hasn’t accepted the AI’s suggestions yet.
Currently, the input field is single-line, and when aiText
is longer, it breaks awkwardly in the middle of the input field, making it look disjointed. Ideally, if aiText
needs to wrap to a new line, it should start from the very left of the input component, not from the middle where userText
ends.
Here’s the current implementation:
<div
onClick={focusContentEditable}
className="relative flex justify-start items-start p-3 border border-border
bg-[#FFFFFF] text-[#1F1F1F] dark:bg-[#2A2A40] dark:text-[#EAEAEA]
focus-within:outline focus-within:outline-[#9462fd]
cursor-text rounded-2xl text-left w-full h-20 mx-auto
overflow-hidden"
>
{/* Placeholder */}
{userText.trim() === "" && !isFocused && (
<span className="text-gray-400 text-xs">Ask me anything...</span>
)}
<div className="inline-flex items-baseline">
<span
ref={contentEditableRef}
className="text-xs border-0 outline-none whitespace-nowrap break-words inline-flex min-h-[20px] w-full"
contentEditable={true}
suppressContentEditableWarning={true}
onInput={handleInput}
onKeyDown={handleKeyDown}
>
{/* {userText} */}
</span>
<span
className={`text-xs text-gray-400 dark:text-gray-600 transition-opacity whitespace-normal inline-flex duration-500 ${
aiText ? "opacity-100" : "opacity-0"
}`}
contentEditable={false}
>
{aiText.length > 0 && userText.trim() !== "" && <>{aiText}</>}
</span>
</div>
</div>
Problem:
- The input field is single-line, and I’m not enforcing line breaks.
- When
aiText
is present and long, it breaks mid-line, which disrupts the flow of the text. - I want the input field to expand in height to accommodate a second line if needed, so
aiText
can wrap cleanly to the next line starting from the left edge.
What I’ve Tried:
- Using
contentEditable
for dynamic text input. - Combining
userText
andaiText
in a single container withinline-flex
to keep them aligned.
Desired Behavior:
- The input field should expand in height to allow multi-line text.
aiText
should wrap to the next line starting from the left edge if it doesn’t fit in the current line.userText
andaiText
should appear as part of the same sentence.
Any suggestions on how to achieve this? Thanks in advance!
Share Improve this question edited Feb 5 at 22:21 isherwood 61.1k16 gold badges120 silver badges168 bronze badges asked Feb 5 at 17:47 ZethystZethyst 1531 silver badge8 bronze badges 1- 1 This is really an HTML/CSS question. I suggest extracting that from the React code and presenting it here as a demo snippet. Once you have a solution you can migrated it into your app. – isherwood Commented Feb 5 at 22:22
1 Answer
Reset to default 2I could definitely be missing something here, but I believe a <span contentEditable={false}>
tag inside of a <p contentEditable={true}>
tag should suffice to achieve your desired behavior.
<p className="whitespace-pre-wrap" contentEditable={true}>
This is some user input text
<span contentEditable={false} className="text-xs text-gray-400">
Here is some extremely looooooong looong looong looooong AI text
</span>
</p>
We use the Tailwind class whitespace-pre-wrap
to automatically wrap the aiText
to the next line, should it overflow.