Skip to content

Commit bab3124

Browse files
committed
fix(app): prompt input quirks
1 parent 7a66ec6 commit bab3124

1 file changed

Lines changed: 47 additions & 38 deletions

File tree

packages/app/src/components/prompt-input.tsx

Lines changed: 47 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,7 @@ export const PromptInput: Component<PromptInputProps> = (props) => {
108108
let slashPopoverRef!: HTMLDivElement
109109

110110
const mirror = { input: false }
111+
const inset = 44
111112

112113
const scrollCursorIntoView = () => {
113114
const container = scrollRef
@@ -117,7 +118,14 @@ export const PromptInput: Component<PromptInputProps> = (props) => {
117118
const range = selection.getRangeAt(0)
118119
if (!editorRef.contains(range.startContainer)) return
119120

120-
const rect = range.getBoundingClientRect()
121+
const cursor = getCursorPosition(editorRef)
122+
const length = promptLength(prompt.current().filter((part) => part.type !== "image"))
123+
if (cursor >= length) {
124+
container.scrollTop = container.scrollHeight
125+
return
126+
}
127+
128+
const rect = range.getClientRects().item(0) ?? range.getBoundingClientRect()
121129
if (!rect.height) return
122130

123131
const containerRect = container.getBoundingClientRect()
@@ -130,8 +138,8 @@ export const PromptInput: Component<PromptInputProps> = (props) => {
130138
return
131139
}
132140

133-
if (bottom > container.scrollTop + container.clientHeight - padding) {
134-
container.scrollTop = bottom - container.clientHeight + padding
141+
if (bottom > container.scrollTop + container.clientHeight - inset) {
142+
container.scrollTop = bottom - container.clientHeight + inset
135143
}
136144
}
137145

@@ -1059,8 +1067,7 @@ export const PromptInput: Component<PromptInputProps> = (props) => {
10591067
removeLabel={language.t("prompt.attachment.remove")}
10601068
/>
10611069
<div
1062-
class="relative max-h-[240px] overflow-y-auto"
1063-
ref={(el) => (scrollRef = el)}
1070+
class="relative"
10641071
onMouseDown={(e) => {
10651072
const target = e.target
10661073
if (!(target instanceof HTMLElement)) return
@@ -1074,40 +1081,42 @@ export const PromptInput: Component<PromptInputProps> = (props) => {
10741081
editorRef?.focus()
10751082
}}
10761083
>
1077-
<div
1078-
data-component="prompt-input"
1079-
ref={(el) => {
1080-
editorRef = el
1081-
props.ref?.(el)
1082-
}}
1083-
role="textbox"
1084-
aria-multiline="true"
1085-
aria-label={placeholder()}
1086-
contenteditable="true"
1087-
autocapitalize="off"
1088-
autocorrect="off"
1089-
spellcheck={false}
1090-
onInput={handleInput}
1091-
onPaste={handlePaste}
1092-
onCompositionStart={() => setComposing(true)}
1093-
onCompositionEnd={() => setComposing(false)}
1094-
onKeyDown={handleKeyDown}
1095-
classList={{
1096-
"select-text": true,
1097-
"w-full pl-3 pr-2 pt-2 pb-12 text-14-regular text-text-strong focus:outline-none whitespace-pre-wrap": true,
1098-
"[&_[data-type=file]]:text-syntax-property": true,
1099-
"[&_[data-type=agent]]:text-syntax-type": true,
1100-
"font-mono!": store.mode === "shell",
1101-
}}
1102-
/>
1103-
<Show when={!prompt.dirty()}>
1084+
<div class="relative max-h-[240px] overflow-y-auto no-scrollbar" ref={(el) => (scrollRef = el)}>
11041085
<div
1105-
class="absolute top-0 inset-x-0 pl-3 pr-2 pt-2 pb-12 text-14-regular text-text-weak pointer-events-none whitespace-nowrap truncate"
1106-
classList={{ "font-mono!": store.mode === "shell" }}
1107-
>
1108-
{placeholder()}
1109-
</div>
1110-
</Show>
1086+
data-component="prompt-input"
1087+
ref={(el) => {
1088+
editorRef = el
1089+
props.ref?.(el)
1090+
}}
1091+
role="textbox"
1092+
aria-multiline="true"
1093+
aria-label={placeholder()}
1094+
contenteditable="true"
1095+
autocapitalize="off"
1096+
autocorrect="off"
1097+
spellcheck={false}
1098+
onInput={handleInput}
1099+
onPaste={handlePaste}
1100+
onCompositionStart={() => setComposing(true)}
1101+
onCompositionEnd={() => setComposing(false)}
1102+
onKeyDown={handleKeyDown}
1103+
classList={{
1104+
"select-text": true,
1105+
"w-full pl-3 pr-2 pt-2 pb-11 text-14-regular text-text-strong focus:outline-none whitespace-pre-wrap": true,
1106+
"[&_[data-type=file]]:text-syntax-property": true,
1107+
"[&_[data-type=agent]]:text-syntax-type": true,
1108+
"font-mono!": store.mode === "shell",
1109+
}}
1110+
/>
1111+
<Show when={!prompt.dirty()}>
1112+
<div
1113+
class="absolute top-0 inset-x-0 pl-3 pr-2 pt-2 pb-11 text-14-regular text-text-weak pointer-events-none whitespace-nowrap truncate"
1114+
classList={{ "font-mono!": store.mode === "shell" }}
1115+
>
1116+
{placeholder()}
1117+
</div>
1118+
</Show>
1119+
</div>
11111120

11121121
<div class="pointer-events-none absolute bottom-2 right-2 flex items-center gap-2">
11131122
<input

0 commit comments

Comments
 (0)