react-textarea-autosize icon indicating copy to clipboard operation
react-textarea-autosize copied to clipboard

Placeholder text makes TextArea autosize incorrectly

Open abelmark opened this issue 5 years ago • 9 comments

The text area is not autosizing correctly. When I implement placeholder text the TextArea gets an extra line of height too tall, but when I start filling in the field it sizes correctly. I have attached images below for reference.

NotRightSize _Placeholder text = not correct size_ RightSize _With actual text = correct size_ NoPlaceholderRightSize _With no placeholder and empty = correct size_

SASS for reference

`.TextArea { width: 90%; height: auto; background: #EDEEFF; font-size: 0.875rem; padding: 1rem; margin: 1rem; border-radius: 1.25rem 1.25rem 0.2rem 1.25rem; border: none; resize: none; text-decoration: underline;

&::placeholder { text-decoration: underline; font-size: 0.7rem; } }`

abelmark avatar Jun 28 '19 16:06 abelmark

Please provide a codesandbox with the issue reproduced with exact instructions how to reproduce it.

Andarist avatar Jun 29 '19 08:06 Andarist

@Andarist I have the same issue. Here's a reproduction with in codesandbox.

Notice the following things (tested in chrome): The input has two rows even though there is no text, because the placeholder is too long. Also, when you start typing you will notice the textarea going back to one row, and when you empty it - it goes back to 2 rows. If you put a shorter placeholder, the textarea becomes one row.

I added a fairly common css thingy that makes the placeholder ellipsize but that only made it look weirder that there's an extra row.

motiazu avatar Jul 31 '19 12:07 motiazu

Thanks for doing that. I went on vacation for a few weeks without a laptop. Any word on this?

abelmark avatar Aug 05 '19 19:08 abelmark

Thanks for repro case! I've researched a little bit and it seems it's not possible to reliably getComputedStyle of a placeholder right now, even though it's been added to the spec last year. Without that, I'm not sure how to fix this issue in the core. You could use a workaround for this - https://codesandbox.io/embed/nostalgic-dew-d8kf1 , but this might not cover all use cases.

Andarist avatar Aug 06 '19 09:08 Andarist

@motiazu, you should probably include the additional placeholder styling in your original post: .text-style::placeholder { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }. It looks to me like the library is calculating the height of the placeholder without taking white-space: nowrap; into account (as if it were actually wrapping).

Separately, I came across this, because I want to see how to get the textarea to have a height of Math.max(placeholderHeight, valueHeight), so it doesn’t jump back (like you’re seeing when you enter text).

mrcoles avatar Jan 13 '20 19:01 mrcoles

I have similar problem. Would be one solution not to put placeholder text in value of hiddenTextarea on demand? Obviously the Browser (especially Chrome) does not provide correct values for placeholder pseudo-element computed styles. Thus you may not copy this to hiddenTextarea.

kuhmuh avatar Feb 03 '20 11:02 kuhmuh

That would most likely lead to unexpected results because you would have to be really aware about your width and text length, which is super error-prone (even if that behavior would be put behind a flag).

Andarist avatar Feb 04 '20 10:02 Andarist

Ok. I agree with you. This is quite error prune, because of implicit dependencies of style and flag. But because I use your component in a table with many other components this is very annoying behaviour. For those reading this thread: I solved this by just switching from <input /> to <TextareaAutosize /> when user changes empty text input field.

kuhmuh avatar Feb 05 '20 13:02 kuhmuh

Hi,

On my side I did something like that :

<div className="flex-1 relative flex my-3">
    <TextareaAutosize
        className="w-full resize-none outline-none min-h-6 h-6 border rounded-xl py-5 px-3 box-content"
        onChange={handleTyping}
        onKeyDown={handleKeyDown}
        ref={messageInputRef}
        disabled={recordingStatus != "closed"}
    />
    {!isSendable && (
        <span
            className="absolute top-1/2 -translate-y-1/2 left-3 opacity-50"
            onClick={() => messageInputRef.current?.focus()}
        >
            {recordingStatus != "closed"
                ? "Recording..."
                : "Message"}
        </span>
    )}
</div>

y4nn0ff avatar Jan 29 '24 21:01 y4nn0ff