Fix user resize on textarea

When user resize the textarea, the ResizeObserver will trigger a height reset on textarea, causing height flashing.
pull/2465/head
giaphat71 2025-06-16 21:14:07 +07:00 zatwierdzone przez GitHub
rodzic fb59fda70e
commit 0f1e1f91dd
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: B5690EEEBB952194
1 zmienionych plików z 5 dodań i 4 usunięć

Wyświetl plik

@ -153,7 +153,7 @@ export default class SlTextarea extends ShoelaceElement implements ShoelaceFormC
this.resizeObserver = new ResizeObserver(() => this.setTextareaHeight()); this.resizeObserver = new ResizeObserver(() => this.setTextareaHeight());
this.updateComplete.then(() => { this.updateComplete.then(() => {
this.setTextareaHeight(); this.setTextareaHeight(true);
this.resizeObserver.observe(this.input); this.resizeObserver.observe(this.input);
}); });
} }
@ -195,13 +195,14 @@ export default class SlTextarea extends ShoelaceElement implements ShoelaceFormC
this.formControlController.emitInvalidEvent(event); this.formControlController.emitInvalidEvent(event);
} }
private setTextareaHeight() { private setTextareaHeight(isProgrammatic?: boolean) {
if (this.resize === 'auto') { if (this.resize === 'auto') {
// This prevents layout shifts. We use `clientHeight` instead of `scrollHeight` to account for if the `<textarea>` has a max-height set on it. In my tests, this has worked fine. Im not aware of any edge cases. [Konnor] // This prevents layout shifts. We use `clientHeight` instead of `scrollHeight` to account for if the `<textarea>` has a max-height set on it. In my tests, this has worked fine. Im not aware of any edge cases. [Konnor]
this.sizeAdjuster.style.height = `${this.input.clientHeight}px`; this.sizeAdjuster.style.height = `${this.input.clientHeight}px`;
this.input.style.height = 'auto'; this.input.style.height = 'auto';
this.input.style.height = `${this.input.scrollHeight}px`; this.input.style.height = `${this.input.scrollHeight}px`;
} else { } else if(isProgrammatic){
// The height only be changed by user resize, so no need to reset the value.
this.input.style.height = ''; this.input.style.height = '';
} }
} }
@ -214,7 +215,7 @@ export default class SlTextarea extends ShoelaceElement implements ShoelaceFormC
@watch('rows', { waitUntilFirstUpdate: true }) @watch('rows', { waitUntilFirstUpdate: true })
handleRowsChange() { handleRowsChange() {
this.setTextareaHeight(); this.setTextareaHeight(true);
} }
@watch('value', { waitUntilFirstUpdate: true }) @watch('value', { waitUntilFirstUpdate: true })