Custom select/dropdown in React

John Kagga
The Andela Way
Published in
5 min readApr 27, 2020

--

Photo by Jerin J on Unsplash

I was tasked to create a custom select in ReactJs so that when it is used on a website it all looks the same in all browser. It is important to note that the in-built browser select element design defers from one browser to another.

Below I am going to take you through how I developed a simple custom select element using ReactJs and Styled components. Enjoy!

First things first, we need a development environment. I normally use codesand box for such jobs. Feel free to create a ReactJs environment there or you can directly use create-react-app on your local machine.

Let's get into it right away.

We are going to write our CSS rules/styles using styled-components. You can install it using the command below.

npm install --save styled-components

or

yarn add styled-components

Structure

Now that we are done installing our own dependency, let's look at the structure of our select/dropdown custom element below.

Using the styled import from styled-components we are going to style the different jsx elements such as the div ul and li elements. They will in turn be returned as React elements.

The DropDownContainer is the umbrella div container for the entire select, DropDownHeader is the element that is going to show the currently selected option from the select, DropDownListContainer is the div containing the unordered list DropDownList which has unordered elements ListItemas its children. Then the mangoes, Apples and Oranges are currently our select options. Below is the visual representation of the above structure in Chrome.

Styles/Design

Now that we are done with the structure, let's add a few styles to our elements. Below is the image of the custom select after applying these styles.

Below is the code with styles and the corresponding explanation for each element.

We have changed <div className=”App”> to <Main> and added a background and height as shown in the GitHub gist above. Since our list has a background of white we changed the Main background so that we could clearly see our selection.

We have styled the DropDownContainer to have a width, which is the width of the custom select and a margin which just centres the custom select for the purposes of this tutorial.

The DropDownContainer styles are kinda self-explanatory but it's important to note that we added a box shadow in order to add a shadow and a bottom margin so that there is a separation between the header and the list of items.

In the DropDownList styles I would like to highlight this section below.

&:first-child {  padding-top: 0.8em;}

It essentially adds a padding-top to the first child of the DropDownList(ul) which is the first ListItem(li) Mangoes in this case.

Behaviour

We now have a base design for our custom selects, let us now move on to adding the desired behaviour where when clicked on the header it shows or hides the list as shown below.

We are using React Hooks to create an isOpen boolean that we are going to use to toggle the list’s visibility as shown below.

const [isOpen, setIsOpen] = useState(false);

Then add a click handler that will be responsible for toggling the boolean to either true or false as shown below.

const toggling = () => setIsOpen(!isOpen);

The click listener is then attached to the DropDownHeader so that when a user clicks the isOpen state variable is toggled to either false or true.

<DropDownHeader onClick={toggling}>Mangoes</DropDownHeader>

Finally, the isOpen state variable is used to either show or hide the DropDownListContainer as shown in the code snippet below.

{isOpen && (  <DropDownListContainer>     <DropDownList>         <ListItem>Mangoes</ListItem>         <ListItem>Apples</ListItem>         <ListItem>Oranges</ListItem>    </DropDownList></DropDownListContainer>)}

Here is all the code up to this point.

Selected option

In order to get and store the selected option from the custom select, we add a new state variable using a React hook as shown below.

const [selectedOption, setSelectedOption] = useState(null);

When an option is clicked we need a click handler that will be called with the selected options so that we can add it to the selectedOption state variable and also probably log it to the console for the purposes of this tutorial. Below is the click handler code snippet.

const onOptionClicked = value => () => {    setSelectedOption(value);    setIsOpen(false);    console.log(selectedOption);};

The value parameter is the selected option, it is important to note that we also have to hide the list when an item is clicked and that's why we set the setIsOpen to false and finally log out the selected option/value.

The list item values have also been moved into an array so that we just map over them and create their respective ListItem as shown below.

const options = ["Mangoes", "Apples", "Oranges"];

Below is mapping of the options:

<DropDownList> {options.map(option => (  <ListItem onClick={onOptionClicked(option)} key={Math.random()}>      {option}  </ListItem>))}</DropDownList>

A click handler is added to each ListItem so that its value is passed over to the function whenever a user clicks on an item. A unique key is also added so that React is able to keep track of each ListItem

Below is the Github gist for the code up until this point:

Great!, you have come to the end of this tutorial, though there a few things you can add like the hover and focus text color for the ListItem and also ensuring that the list of items does not move the other content below it by making the DropDownListContainer position absoluteFinally, feel free to add the up or down arrows when the list visibility changes.

Check out the code on Github.

Thank you for reading, in case you have a question or feedback feel free to add it in the comments below.

--

--

John Kagga
The Andela Way

Andela |The Andela Way Editor | Arvana |Facebook Dev Circles| Long-life Learner