Skip to content

Instantly share code, notes, and snippets.

@omargfh
Created August 13, 2022 20:36
Show Gist options
  • Save omargfh/49705a76c8a2b18882a9d698c0bcfab6 to your computer and use it in GitHub Desktop.
Save omargfh/49705a76c8a2b18882a9d698c0bcfab6 to your computer and use it in GitHub Desktop.
React Custom Select Dropdown
import {useState} from 'react';
import Select from 'select';
export default function index() {
const options = ['Option A', 'Option B', 'Option C'];
const [activeOption, setActiveOption] = useState('Option A');
return (
<>
<Select options={options} setSelected={setActiveOption} />
</>
)
}
import React, { useEffect, useState } from 'react';
export default function Select({options, setSelected}) {
const [activeIndex, setActiveIndex] = useState(0);
const handleClick = (i, event) => {
setActiveIndex(i);
setSelected(options[i]);
setToggled(false);
}
const [toggled, setToggled] = useState(false);
const handleToggle = (event) => {
event.preventDefault();
event.stopPropagation();
setToggled(!toggled);
}
useEffect(() => {
// Check null collection
if (options == null) {
options = [];
}
// Check null function
if (setSelected == null) {
setSelected = () => {};
}
// check document click
document.addEventListener('click', () => setToggled(false));
return () => {
document.removeEventListener('click', () => setToggled(false));
}
}, []);
return(
<ul className={"selector" + (toggled ? " toggled" : "")} onBlur={() => setToggled(false)}>
<li key="selector-main" className="selector-main" onClick={handleToggle}>{options[activeIndex]}</li>
<div className="options">
{options.map((e, i) => <li key={i} className={"option" + (activeIndex == i ? " active" : "")} onClick={(e) => handleClick(i, e)}>{e}</li>)}
</div>
</ul>
);
}
.selector {
color: #65676b;
font-family: arial;
font-weight: 800;
font-size: 16px;
position: relative;
.selector-main {
padding: 0.5em 2em;
background-color: #f0f2f5;
width: 180px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
text-align: left;
border-radius: 25px;
position: relative;
user-select: none;
cursor: pointer;
&::after {
content: '▼';
display: block;
position: absolute;
font-size: 12px;
right: 1.5em;
top: 50%;
transform: translateY(-50%);
}
&:hover {
background-color: #e4e6ea;
}
}
.option {
display: none;
}
&.toggled {
.options {
position: absolute;
z-index: 10;
}
.option {
display: block;
padding: 0.5em 2em;
background-color: #f0f2f5;
width: calc(180px);
cursor: pointer;
&:last-child {
border-bottom-left-radius: 10px;
border-bottom-right-radius: 10px;
}
&:hover {
background-color: #e4e6ea;
}
}
.selector-main {
border-radius: 20px;
border-bottom-left-radius: 0;
border-bottom-right-radius: 0;
&::after {
content: '▲';
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment