Tech @ Upshotly
Published in

Tech @ Upshotly

How Upshotly implemented user mentions in comments using the react-mentions library

Implementing Comment with Mentions

  1. react-mentions
  2. DraftJs mentions

Comparing react-mentions with DraftJS mentions plugin

  1. Implementation
  2. UI

Comparing in terms of implementation:

  1. It is configurable

Comparison in terms of UI

  1. User Image
  2. User Link
  3. User Name
  1. User Name
  2. User Id

Implementing mentions with react-mentions

npm install react-mentions — save
yarn add react-mentions
import { MentionsInput, Mention } from ‘react-mentions’
<MentionsInput value={this.state.comment} onChange={event => this.setState({comment: event.target.value})}>
<Mention
trigger=”@”
data={this.props.users}
/>
</MentionsInput>
MentionInput TextArea
users =[
{
id: user_id
display: user_name
}
]

Saving comments along with mentions to database

<MentionsInput value={this.state.comment} onChange={event =>   this.setState({comment: event.target.value})}>
<Mention
trigger=”@”
data={this.props.users}
markup=‘@@@____id__^^____display__@@@^^^’
/>
</MentionsInput>
<Button className=”btn btn-us” onClick={() => this.saveComment()}>
Submit
</Button>
saveComment = () => {
let newComment = this.state.comment;
newComment = newComment.split(‘@@@__’).join(“<a href=\”/user/”)
newComment = newComment.split(‘^^^__’).join(“\”>”)
newComment = newComment.split(‘@@@^^^’).join(“</a>”);
if (newComment != ‘’) {
let comment = newComment.trim();
//Call to your DataBase like backendModule.saveComment(comment, along_with_other_params);
this.setState({
comment: ‘’,
})
}
}

How to display a saved comment from the database in UI

Comments {
id: Int
comment_text: varchar
.
.
.
other_fields
}
<p dangerouslySetInnerHTML={{ __html: comment.comment.comment_text.replace(/\n\r?/g, ‘<br />’) }}/>dangerouslySetInnerHTML - There are so many alternative to avoid using this :) See this.

Why I have used comment_text.replace(/\n\r?/g, ‘<br/>)

Changing the UGLY UI to look sharp and fresh:

.comments-textarea{
background-color: #fff;
border-radius: 3px;
transition: 0.3s ease-in-out;
padding: 9px;
font-size: 14px;
line-height: 1.42857143;
color: #333;
border: 1px solid #dedede;
&:focus,&:active{
outline: none;
border: 1px solid #3fb9de;
}
}
<MentionsInput className=“comments-textarea” value={this.state.comment} onChange={event => this.setState({comment: event.target.value})}>
<Mention
trigger=”@”
data={this.props.users}
markup=‘@@@____id__^^____display__@@@^^^’
/>
</MentionsInput>
  1. For MentionInput input it appends __input at the end of our className (comments-textarea)
  2. For Suggestions list, it appends __suggestions__list at the end of our className (comments-textarea)
  3. For Suggestion Items, it appends __suggestions_item at the end of our className (comments-textarea)
  4. For Suggestion item when focused it appends __suggestions__item — focused at the end of our className (comments-textarea)
  5. For the Input Control, it appends __control at the end of our className (comments-textarea)
  6. For the Highlighter, it appends __highlighter at the end of our className (comments-textarea).
.comments-textarea__control{
margin-top: 10px;
margin-bottom: 20px;
}
.comments-textarea__input{
background-color: #fff;
border-radius: 3px;
transition: 0.3s ease-in-out;
padding: 9px;
font-size: 14px;
line-height: 1.42857143;
color: #333;
border: 1px solid #dedede;
&:focus,&:active{
outline: none;
border: 1px solid #3fb9de;
}
&::placeholder {
color: #a4b0be;
font-size: 14px;
}
}
.comments-textarea__highlighter{
padding: 10px;
}
.comments-textarea__suggestions__list {
background-color: #fff;
border: 1px solid rgba(0, 0, 0, 0.15);
font-size: 14px;
max-height: 200px;
overflow: auto;
}
.comments-textarea__suggestions__item {
padding: 5px 15px;
border-bottom: 1px solid rgba(0, 0, 0, 0.15);
}
.comments-textarea__suggestions__item — focused {
background-color: #daf4fa;
}

How to change the color of your mentions highlighter

<MentionsInput className=’comments-textarea’ placeholder=”Add Comment” value={this.state.comment} onChange={(event) => this.setState({ comment: event.target.value })}>
<Mention
trigger=”@”
markup=’@@@____id__^^^____display__@@@^^^’
displayTransform={this.handleDisplayTextForMention}
data={this.props.users}
style={{
backgroundColor: ‘#daf4fa’
}}

/>
</MentionsInput>

--

--

The technical problems that we overcome every day, shared here as your learning experience.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Ganesh Ravi Shankar

Co-Founder @Upshotly | www.upshotly.com | Tech Enthusiast | Performance and Scalability Enthusiast | Polyglot