Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to compose react-textarea-autosize with react-mentions

It's now clear to me that mixins and inheritance are generally considered bad and composition is the way to go, this from:

https://medium.com/@dan_abramov/mixins-are-dead-long-live-higher-order-components-94a0d2f9e750

https://facebook.github.io/react/blog/2016/07/13/mixins-considered-harmful.html


Now, what to do when you find two components that specialize in different things and you want a component that is the result of both behaviors mixed? For instance, I want a textarea that both grows automatically when text goes beyond initial rows, and allow mentions inside (aka. mix react-mentions with react-textarea-autosize)

  • How am I supposed to compose both in a way that works?
  • Am I supposed to code a brand new component copying/merging the inner code from both components?
  • What's the ReactJs way to compose in such scenarios?
like image 955
Lorenzo Peña Avatar asked Oct 18 '22 10:10

Lorenzo Peña


1 Answers

I came across the same issue. With react-mention you don't have to use the react-text-autosize as you can achieve the same behavior with css which can auto grow the textarea generated. Consider following example

<MentionsInput
   value={content}
   placeholder="Add a comment"
   onChange={this.onChange}
   className="mentionWrapper">
        <Mention
          trigger="@"
          data={users}
          className="mentionedFriend"
          displayTransform={(id, display) => `@${display}`}
        />
</MentionsInput>

For this i've used the following styles

.mentionWrapper {
  width: 100%;
  background: transparent;
  font-size: 0.9rem;
  color: #a9b5c4;
 }
 .mentionWrapper .mentionWrapper__control {
   border-radius: 25px;
   border: 1px solid #3a546f;
   min-height: 45px;
  }

 .mentionWrapper .mentionWrapper__control .mentionWrapper__highlighter {
  padding: 0.7rem 1rem;
 }

 .mentionWrapper .mentionWrapper__control .mentionWrapper__input {
  padding: 0.7rem 1rem;
  outline: 0;
  border: 0;
  resize: none;
  outline: none;
  font-size: 0.9rem;
  color: #7288a3;
  border-color: #3a546f;
  overflow: hidden;
 }

.mentionWrapper .mentionWrapper__control .mentionWrapper__input::placeholder {
  color: #7288a3;
 }

.mentionWrapper__suggestions {
  background-color: rgba(0, 0, 0, 0.6) !important;
  padding: 10px;
  -webkit-box-shadow: 0px 0px 11px 0px rgba(0, 0, 0, 0.75);
 -moz-box-shadow: 0px 0px 11px 0px rgba(0, 0, 0, 0.75);
 box-shadow: 0px 0px 11px 0px rgba(0, 0, 0, 0.75);
 border-radius: 0.8rem;
 }

.mentionWrapper__suggestions .mentionWrapper__suggestions__list {
  font-size: 14px;
 }

.mentionWrapper
.mentionWrapper__suggestions
.mentionWrapper__suggestions__item--focused {
 color: #ffffff;
 border-bottom: 1px solid #3a546f;
 font-weight: 600;
}

.mentionedFriend {
  color: #7288a3;
  text-decoration: underline;
 }

Key point here is that i've applied a min-height of 45px to "control" div which is append by react-mention package. By doing so you will get the attached result. enter image description here

like image 151
Fakhir Shad Avatar answered Oct 21 '22 08:10

Fakhir Shad