diff --git a/frontend/libs/components/promptbox/src/lib/PromptBox2D.tsx b/frontend/libs/components/promptbox/src/lib/PromptBox2D.tsx index 24e7b87551..5aea264caf 100644 --- a/frontend/libs/components/promptbox/src/lib/PromptBox2D.tsx +++ b/frontend/libs/components/promptbox/src/lib/PromptBox2D.tsx @@ -301,8 +301,16 @@ export const PromptBox2D = ({ const handlePaste = (e: React.ClipboardEvent) => { e.preventDefault(); e.stopPropagation(); - const pastedText = e.clipboardData.getData("text").trim(); - setPrompt(pastedText); + const pastedText = e.clipboardData.getData("text"); + const target = e.currentTarget; + const { selectionStart, selectionEnd, value } = target; + const next = + value.slice(0, selectionStart) + pastedText + value.slice(selectionEnd); + setPrompt(next); + requestAnimationFrame(() => { + const pos = selectionStart + pastedText.length; + textareaRef.current?.setSelectionRange(pos, pos); + }); }; const handleChange = (e: React.ChangeEvent) => { diff --git a/frontend/libs/components/promptbox/src/lib/PromptBox3D.tsx b/frontend/libs/components/promptbox/src/lib/PromptBox3D.tsx index c5e050f0e5..66fb38fca5 100644 --- a/frontend/libs/components/promptbox/src/lib/PromptBox3D.tsx +++ b/frontend/libs/components/promptbox/src/lib/PromptBox3D.tsx @@ -305,8 +305,16 @@ export const PromptBox3D = ({ const handlePaste = (e: React.ClipboardEvent) => { e.preventDefault(); e.stopPropagation(); - const pastedText = e.clipboardData.getData("text").trim(); - setPrompt(pastedText); + const pastedText = e.clipboardData.getData("text"); + const target = e.currentTarget; + const { selectionStart, selectionEnd, value } = target; + const next = + value.slice(0, selectionStart) + pastedText + value.slice(selectionEnd); + setPrompt(next); + requestAnimationFrame(() => { + const pos = selectionStart + pastedText.length; + textareaRef.current?.setSelectionRange(pos, pos); + }); }; const handleChange = (e: React.ChangeEvent) => { diff --git a/frontend/libs/components/promptbox/src/lib/PromptBoxEdit.tsx b/frontend/libs/components/promptbox/src/lib/PromptBoxEdit.tsx index 9e93e7919d..77da0f874a 100644 --- a/frontend/libs/components/promptbox/src/lib/PromptBoxEdit.tsx +++ b/frontend/libs/components/promptbox/src/lib/PromptBoxEdit.tsx @@ -5,7 +5,7 @@ import { faMessageXmark, faMousePointer, faSparkles, - faSpinnerThird + faSpinnerThird, } from "@fortawesome/pro-solid-svg-icons"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { Button, ToggleButton } from "@storyteller/ui-button"; @@ -24,15 +24,13 @@ export const PromptBoxEdit = ({ onModeChange: onModeSelectionChange, selectedMode, onGenerateClick, - isDisabled + isDisabled, }: PromptBoxEditProps) => { - const [prompt, setPrompt] = useState(""); const [useSystemPrompt, setUseSystemPrompt] = useState(true); const textareaRef = useRef(null); - useEffect(() => { if (textareaRef.current) { textareaRef.current.style.height = "auto"; @@ -43,8 +41,17 @@ export const PromptBoxEdit = ({ const handlePaste = (e: React.ClipboardEvent) => { e.preventDefault(); e.stopPropagation(); - const pastedText = e.clipboardData.getData("text").trim(); - setPrompt(pastedText); + const pastedText = e.clipboardData.getData("text"); + const target = e.currentTarget; + const { selectionStart, selectionEnd, value } = target; + const next = + value.slice(0, selectionStart) + pastedText + value.slice(selectionEnd); + setPrompt(next); + // Restore caret after React updates the value + requestAnimationFrame(() => { + const pos = selectionStart + pastedText.length; + textareaRef.current?.setSelectionRange(pos, pos); + }); }; const handleChange = (e: React.ChangeEvent) => { @@ -97,8 +104,8 @@ export const PromptBoxEdit = ({ onChange={handleChange} onPaste={handlePaste} onKeyDown={handleKeyDown} - onFocus={() => { }} - onBlur={() => { }} + onFocus={() => {}} + onBlur={() => {}} />
diff --git a/frontend/libs/components/promptbox/src/lib/PromptBoxImage.tsx b/frontend/libs/components/promptbox/src/lib/PromptBoxImage.tsx index 6c8b5f3fe9..2ebe170a48 100644 --- a/frontend/libs/components/promptbox/src/lib/PromptBoxImage.tsx +++ b/frontend/libs/components/promptbox/src/lib/PromptBoxImage.tsx @@ -243,8 +243,16 @@ export const PromptBoxImage = ({ const handlePaste = (e: React.ClipboardEvent) => { e.preventDefault(); - const pastedText = e.clipboardData.getData("text").trim(); - setPrompt(pastedText); + const pastedText = e.clipboardData.getData("text"); + const target = e.currentTarget; + const { selectionStart, selectionEnd, value } = target; + const next = + value.slice(0, selectionStart) + pastedText + value.slice(selectionEnd); + setPrompt(next); + requestAnimationFrame(() => { + const pos = selectionStart + pastedText.length; + textareaRef.current?.setSelectionRange(pos, pos); + }); }; const handleChange = (e: React.ChangeEvent) => { diff --git a/frontend/libs/components/promptbox/src/lib/PromptBoxVideo.tsx b/frontend/libs/components/promptbox/src/lib/PromptBoxVideo.tsx index 08d28c1519..0b57cde1f9 100644 --- a/frontend/libs/components/promptbox/src/lib/PromptBoxVideo.tsx +++ b/frontend/libs/components/promptbox/src/lib/PromptBoxVideo.tsx @@ -175,8 +175,16 @@ export const PromptBoxVideo = ({ const handlePaste = (e: React.ClipboardEvent) => { e.preventDefault(); - const pastedText = e.clipboardData.getData("text").trim(); - setPrompt(pastedText); + const pastedText = e.clipboardData.getData("text"); + const target = e.currentTarget; + const { selectionStart, selectionEnd, value } = target; + const next = + value.slice(0, selectionStart) + pastedText + value.slice(selectionEnd); + setPrompt(next); + requestAnimationFrame(() => { + const pos = selectionStart + pastedText.length; + textareaRef.current?.setSelectionRange(pos, pos); + }); }; const handleChange = (e: React.ChangeEvent) => {