Skip to content
This repository has been archived by the owner on Mar 1, 2024. It is now read-only.

Provide an instance method to update size #114

Closed
olavim opened this issue Nov 23, 2018 · 3 comments
Closed

Provide an instance method to update size #114

olavim opened this issue Nov 23, 2018 · 3 comments
Labels

Comments

@olavim
Copy link

olavim commented Nov 23, 2018

In my app I have a need to update the textarea's width without changing its props. Currently the textarea only resizes when its props change (or more specifically, when the value or rows change).

Basically, in my app, the textarea is inside a container, and users can indent this container. Since the container's position is constrained from one side, it has no option but to make the underlying text take more vertical space to fit. The textarea doesn't detect this change though.

My current workaround is to call textareaRef.dispatchEvent('autosize:update'). My suggestion is to add an updateSize (or something) instance method that does this for me, because my current solution is a bit cumbersome since it relies on underlying technicalities.

@FrancescoCioria
Copy link
Contributor

this is weird, the textarea should detect it.
what you're describing is the same behaviour as resizing the browser window and in that case it works correctly:

Image from Gyazo

It also works if you update the width of a container without resizing the browser window:

Image from Gyazo

@olavim how does your code differ from those two examples? can you help me reproduce it?

@olavim
Copy link
Author

olavim commented Nov 30, 2018

@FrancescoCioria the following snippet, when pasted to https://react-components.buildo.io/#textareaautosize, works as I described:

initialState = {indent: 0, value: ''};

<div style={{width: '600px'}}>
  <div style={{paddingLeft: `${state.indent * 40}px`}}>
    <TextareaAutosize
      style={{width: '100%'}}
      value={state.value}
      onChange={evt => setState({value: evt.target.value})}
    />
  </div>

  <button onClick={() => setState({indent: state.indent - 1})}>{'<- indent'}</button>
  <button onClick={() => setState({indent: state.indent + 1})}>{'indent ->'}</button>
</div>

It's worth to note that the snippet worked correctly when I used an uncontrolled textarea, and when I set the initial value (in initialState) to the text I wanted to test in a controlled one.

So to get what I'm getting, do the following:

  1. paste the following text to the textarea:
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam dignissim nunc metus, vel congue purus 
fermentum volutpat. Sed at dolor lacus. Donec laoreet lorem ut turpis sagittis sagittis. Ut vel ligula sit 
amet felis efficitur egestas. Phasellus congue id est vitae ultricies. Ut facilisis turpis et 
  1. press the indent -> button until you see that the text wraps, but the textarea doesn't resize.

@FrancescoCioria
Copy link
Contributor

@olavim thanks for the snippet

the issue is in the componentDidUpdate logic:
image

as we can see we are updating the textarea only if props.rows has changed or if props.value is different from the cached value currentValue (which explains why it does not happen when uncontrolled)

that logic was meant to improve performance, but I can see that it can easily cause bugs...
also, if someone wants to limit the number of times that update is called, they can easily wrap this component in another one and implement a custom shouldComponentUpdate which makes that logic in my opinion risky and not worth it

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

No branches or pull requests

3 participants