Open robrez opened 1 month ago
Potential general solutions:
_onResize() {
const width = this.getBoundingClientRect()?.width;
const value = this.value;
if (width === this.__prevWidth && value === this.__prevValue) {
return;
}
this.__prevWidth = width;
this.__prevValue = value;
this._updateHeight();
this.__scrollPositionUpdated();
}
Memoize width and value onResize. Don't re-try resize whenever width and value match the previous effort. This would misbehave in a lot of circumstances, some examples:
After typing that, I realize checking the width of the input element would be better versus "this". The only other idea I have for a solution involves some sort of debouncing of resize observers or maybe saying, "ignore the next one" whenever we cause the resize ourselves
I think that doing some sort of "skipNextResize" is the better strategy.. probably still not perfect:
_onResize() {
if (this.__resizing) {
return;
}
if (this.__skipNextResize) {
this.__skipNextResize = false;
return;
}
this.__resizing = true;
this._updateHeight();
this.__resizing = false;
this.__scrollPositionUpdated();
}
_updateHeight() {
// ...
const inputHeight = input.scrollHeight;
if (inputHeight > input.clientHeight) {
// add these 3 lines.. not sure it really makes sense to have an "if"... we'd probably
// want to just _always_ skip the next resize observer when we are the ones who caused it
if (this.__resizing) {
this.__skipNextResize = true;
}
input.style.height = `${inputHeight}px`;
}
// ...
}
Description
In certain situations, text-area's resize observer causes an infinite loop
Expected outcome
Loop should be terminated
Minimal reproducible example
I've had some difficultly creating a very minimalist reproduction. Here is a gif and stackblitz
https://stackblitz.com/edit/vitejs-vite-wmooik?file=main.js
Steps to reproduce
Place text-area(s) in the dom, provide values, and slowly make the window / dom parent narrower until you see "jittery" behavior
Environment
Vaadin version(s): 23, 24 OS: windows
Browsers
Chrome