fix: prevent scroll jump when editing large messages (#21402)
Save and restore scroll positions around textarea auto-resize to avoid layout shifts. Use preventScroll on focus.
This commit is contained in:
@@ -365,8 +365,13 @@
|
|||||||
|
|
||||||
await tick();
|
await tick();
|
||||||
|
|
||||||
|
const messagesContainer = document.getElementById('messages-container');
|
||||||
|
const savedScrollTop = messagesContainer?.scrollTop;
|
||||||
|
|
||||||
editTextAreaElement.style.height = '';
|
editTextAreaElement.style.height = '';
|
||||||
editTextAreaElement.style.height = `${editTextAreaElement.scrollHeight}px`;
|
editTextAreaElement.style.height = `${editTextAreaElement.scrollHeight}px`;
|
||||||
|
|
||||||
|
if (messagesContainer) messagesContainer.scrollTop = savedScrollTop;
|
||||||
};
|
};
|
||||||
|
|
||||||
const editMessageConfirmHandler = async () => {
|
const editMessageConfirmHandler = async () => {
|
||||||
@@ -697,8 +702,13 @@
|
|||||||
class=" bg-transparent outline-hidden w-full resize-none"
|
class=" bg-transparent outline-hidden w-full resize-none"
|
||||||
bind:value={editedContent}
|
bind:value={editedContent}
|
||||||
on:input={(e) => {
|
on:input={(e) => {
|
||||||
|
const messagesContainer = document.getElementById('messages-container');
|
||||||
|
const savedScrollTop = messagesContainer?.scrollTop;
|
||||||
|
|
||||||
e.target.style.height = '';
|
e.target.style.height = '';
|
||||||
e.target.style.height = `${e.target.scrollHeight}px`;
|
e.target.style.height = `${e.target.scrollHeight}px`;
|
||||||
|
|
||||||
|
if (messagesContainer) messagesContainer.scrollTop = savedScrollTop;
|
||||||
}}
|
}}
|
||||||
on:keydown={(e) => {
|
on:keydown={(e) => {
|
||||||
if (e.key === 'Escape') {
|
if (e.key === 'Escape') {
|
||||||
|
|||||||
@@ -50,6 +50,7 @@
|
|||||||
let editedFiles = [];
|
let editedFiles = [];
|
||||||
|
|
||||||
let messageEditTextAreaElement: HTMLTextAreaElement;
|
let messageEditTextAreaElement: HTMLTextAreaElement;
|
||||||
|
let editScrollContainer: HTMLDivElement;
|
||||||
|
|
||||||
let message = JSON.parse(JSON.stringify(history.messages[messageId]));
|
let message = JSON.parse(JSON.stringify(history.messages[messageId]));
|
||||||
$: if (history.messages) {
|
$: if (history.messages) {
|
||||||
@@ -73,10 +74,14 @@
|
|||||||
await tick();
|
await tick();
|
||||||
|
|
||||||
if (messageEditTextAreaElement) {
|
if (messageEditTextAreaElement) {
|
||||||
|
const messagesContainer = document.getElementById('messages-container');
|
||||||
|
const savedScrollTop = messagesContainer?.scrollTop;
|
||||||
|
|
||||||
messageEditTextAreaElement.style.height = '';
|
messageEditTextAreaElement.style.height = '';
|
||||||
messageEditTextAreaElement.style.height = `${messageEditTextAreaElement.scrollHeight}px`;
|
messageEditTextAreaElement.style.height = `${messageEditTextAreaElement.scrollHeight}px`;
|
||||||
|
|
||||||
messageEditTextAreaElement?.focus();
|
if (messagesContainer) messagesContainer.scrollTop = savedScrollTop;
|
||||||
|
messageEditTextAreaElement?.focus({ preventScroll: true });
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -283,15 +288,22 @@
|
|||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
<div class="max-h-96 overflow-auto">
|
<div class="max-h-96 overflow-auto" bind:this={editScrollContainer}>
|
||||||
<textarea
|
<textarea
|
||||||
id="message-edit-{message.id}"
|
id="message-edit-{message.id}"
|
||||||
bind:this={messageEditTextAreaElement}
|
bind:this={messageEditTextAreaElement}
|
||||||
class=" bg-transparent outline-hidden w-full resize-none"
|
class=" bg-transparent outline-hidden w-full resize-none"
|
||||||
bind:value={editedContent}
|
bind:value={editedContent}
|
||||||
on:input={(e) => {
|
on:input={(e) => {
|
||||||
|
const messagesContainer = document.getElementById('messages-container');
|
||||||
|
const savedScrollTop = messagesContainer?.scrollTop;
|
||||||
|
const savedInnerScroll = editScrollContainer?.scrollTop;
|
||||||
|
|
||||||
e.target.style.height = '';
|
e.target.style.height = '';
|
||||||
e.target.style.height = `${e.target.scrollHeight}px`;
|
e.target.style.height = `${e.target.scrollHeight}px`;
|
||||||
|
|
||||||
|
if (messagesContainer) messagesContainer.scrollTop = savedScrollTop;
|
||||||
|
if (editScrollContainer) editScrollContainer.scrollTop = savedInnerScroll;
|
||||||
}}
|
}}
|
||||||
on:keydown={(e) => {
|
on:keydown={(e) => {
|
||||||
if (e.key === 'Escape') {
|
if (e.key === 'Escape') {
|
||||||
|
|||||||
Reference in New Issue
Block a user