Styling a “react-mentions” Component With JSS

Implementing the Material-UI look & feel from scratch using the “makeStyles” API

Ron Michaeli
4 min readMar 24, 2021

Intro

Recently we, at SundaySky, wanted to add a new feature with which the user can input text, and when typing a specific character, a list of suggestions pops up. The user can then select an item from the list and have a visual indication of the selected item in the input field.

Figma sketch of the feature. Typing the “{“ character pops up a list of suggestions. When a suggestion is selected, it appears colored in the input

As you can see, this experience is very similar to what we see in platforms like Facebook / Twitter / Medium in which we can mention people using the “@” sign.
This feature is commonly called “mention”.

Research

The first step towards this new feature was research — are there any existing solutions out there that can fit our requirements?

So while searching around the web, I came across this wonderful article which describes how to implement mentions using the react-mentions library.

Nice! What a great start. Thanks Ganesh Ravi Shankar!

So, I made a small POC of a mention component using react-mentions and our product team approved that it met our functional requirements.

The POC. Meets the functional requirements, but ugly

Next up — styling!

Piece of cake, right?
Not quite…

The Challenges

At SundaySky we manage our core UI components in a separate repository, called “Component Library”. In this library we define the look & feel (colors, fonts, animations, dark/light theme support, etc.) of all the components, resulting in reusable components with a consistent streamlined UX across our applications.

Challenge #1

Our design system is based entirely on Material-UI. So the UX guideline was that the new component should have the same look & feel as Material-UI Autocomplete.

See the following GIF for example. Notice how the placeholder text (e.g., “Mui Autocomplete”) decreases in size and moves out of the way when the component gains focus.

The desired look & feel — Material-UI Autocomplete component

This is an example of out-of-the-box Material-UI behavior that needed to be implemented since react-mentions offers zero out-of-the-box styling.

So basically, I had to replicate the Material-UI style from scratch.

Challenge #2

We use theming to style the components in our component library.

Theme is a global object that defines all of the styling properties of the application, such as color palette, transitions, typography, spacing etc.
See this theme object for example.
The main benefit of theming is that all of the styling properties are defined in one place, usually located at the root of the application, and can be used anywhere in the application without having to rewrite “hard-coded” styles all over the place.

In our component library, we use the Material-UI makeStyles API for theming (JSS syntax). As we’ll see in the following chapter, styling a react-mentions component is not trivial and all of the sources I found on the web used CSS for that, while I needed to do it with JSS.

Let’s Get Down to Business

Part 1 — styling the “react-mentions” elements

As Ganesh’s article states, we can apply a custom style to every element within react-mentions by overriding specific className attributes (yeah, it’s weird but it works).

For example, given the following component…

…this is the rendered DOM when the suggestion list is open:

DOM of a “react-mentions” component. Notice the generated classNames (white underline)

We see that we can override the following className attributes to style their matching elements:

  1. ssky-mention-input__control : root control element
  2. ssky-mention-input__highlighter : highlighter element
  3. ssky-mention-input__input : input element
  4. ssky-mention-input__suggestions : suggestion list wrapper
  5. ssky-mention-input__suggestions__list : suggestion list
  6. ssky-mention-input__suggestions__item : suggestion list item
  7. ssky-mention-input__suggestions__item--focused : focused suggestion list item

Since I was adding this component to our component library, it needed to be generic and reusable as possible, and still have a default style. This styling method forced me to have a fixed className for the <MentionsInput /> component, which is not ideal in terms of genericity.

This is how the className override is done using the makeStyles API:

Part 2 — styling the highlighted mentions

Styling the highlighted mention can be done only by passing the style prop to the <Mention /> component. This is my style object:

Part 3 — styling the input placeholder

The placeholder (a.k.a., “floating label”) was tricky because I had to carefully place it inside the input field and understand when to style it as a superscript and when not to. It should be superscript if the input field is focused or if it contains a value.

This is how the placeholder styling is done using the makeStyles API:

Final Result

After days of learning and experimenting with react-mentions, CSS, JSS, Material-UI APIs and all in between… this is the final result:

The final result. Sweet!

And the full code…

defaultStyles.ts :

SskyMentionInput.tsx :

That’s it. Thank you for reading! 🙏

Good luck!

--

--