Conversation
The content size was read from the textarea's own scrollHeight, which is never less than the height the textarea has been given. So once an auto-growing input has grown, deleting lines never reports a smaller size and the input can't shrink back. Measure a zero-height, hidden copy of the textarea instead, which reports the height of the content alone and leaves the textarea's box and the page's scroll position untouched. Close necolas#2160
|
This pull request is automatically built and testable in CodeSandbox. To see build info of the built libraries, click here or the icon next to each commit SHA. Latest deployment of this branch, based on commit edde968:
|
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
onContentSizeChangeon a multilineTextInputreads the textarea's ownscrollHeight, which is never less than the height the textarea currently has. Once an auto-growing input has grown (the app setsheightfrom the reported size), deleting lines keeps reporting the old, larger size, so the input can never shrink back. This is #2160 (and the earlier #1339/#1399).The fix measures a zero-height, hidden copy of the textarea instead of the textarea itself. The copy is a
cloneNode()(so it keeps the same classes and inline styles, and inherits from the same parent), gets the textarea's computed width so wrapping matches, and isposition: fixed/visibility: hidden/overflow: hiddenso it neither moves anything nor grows a scrollbar that would change wrapping. It is inserted and removed synchronously, so nothing is painted. This is the same techniquereact-textarea-autosizeuses. Temporarily setting the real textarea's height to0would be simpler, but the forced layout clamps the scroll position of any container the textarea sits at the bottom of (a chat composer being the typical case), and restoring the height does not restore the scroll offset.Reported size is still
scrollHeight/scrollWidthof a textarea (content plus padding), so values for content that fits are unchanged; only content smaller than the box now reports its real height.Tested with a jest test that mocks
scrollHeight(jsdom has no layout) and checks the reported height goes 10 → 30 → 10 as lines are added and removed, that the real textarea's height is untouched and that no clone is left in the DOM. Also checked in Chrome on a page scrolled to the bottom: a 100px-high textarea with one line reports 40px (line + padding) instead of 98px, eight lines report 180px as before, long lines wrap to the same height as in the textarea, andwindow.scrollYis unchanged after measuring.npm run unit,lintandformatpass for the package;flowcould not be run locally (flow-bin has no arm64 build), so relying on CI for it.