mirror of
https://github.com/movie-web/movie-web.git
synced 2024-12-29 16:06:07 +00:00
Being to create select box
This commit is contained in:
parent
9448b990e3
commit
f3a7b0823c
112
src/components/SelectBox.css
Normal file
112
src/components/SelectBox.css
Normal file
|
@ -0,0 +1,112 @@
|
||||||
|
@import url('https://fonts.googleapis.com/css?family=Open+Sans:300,300i,400,400i,600,600i,700,700i,800,800i&display=swap');
|
||||||
|
body {
|
||||||
|
background-color: #1B1F3B;
|
||||||
|
font-family: 'Open Sans', Arial, sans-serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* select box styling */
|
||||||
|
.select-box {
|
||||||
|
display: flex;
|
||||||
|
width: 200px;
|
||||||
|
flex-direction: column;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.select-box > * {
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
.select-box .options-container {
|
||||||
|
max-height: 0;
|
||||||
|
width: calc( 100% - 12px);
|
||||||
|
opacity: 0;
|
||||||
|
transition: all 0.2s ease-in-out;
|
||||||
|
overflow: hidden;
|
||||||
|
border-radius: 5px;
|
||||||
|
background-color: #272C4F;
|
||||||
|
order: 1;
|
||||||
|
position: absolute;
|
||||||
|
top: 50px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.select-box .selected {
|
||||||
|
margin-bottom: 8px;
|
||||||
|
position: relative;
|
||||||
|
width: 188px;
|
||||||
|
height: 45px;
|
||||||
|
border-radius: 5px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
background-color: #272C4F;
|
||||||
|
color: white;
|
||||||
|
order: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.selected::after {
|
||||||
|
/* Font Awesome */
|
||||||
|
content: "\f078";
|
||||||
|
font-family: "Font Awesome 5 Free";
|
||||||
|
font-weight: 900;
|
||||||
|
-webkit-font-smoothing: antialiased;
|
||||||
|
display: inline-block;
|
||||||
|
font-style: normal;
|
||||||
|
font-variant: normal;
|
||||||
|
text-rendering: auto;
|
||||||
|
line-height: 1;
|
||||||
|
/* BG Img */
|
||||||
|
/* content: url("img/arrow-down.svg"); */
|
||||||
|
position: absolute;
|
||||||
|
right: 15px;
|
||||||
|
top: 50%;
|
||||||
|
transition: transform 150ms;
|
||||||
|
transform: translateY(-50%);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.select-box .option .item {
|
||||||
|
color: #AFB5DD;
|
||||||
|
}
|
||||||
|
|
||||||
|
.select-box .options-container.active {
|
||||||
|
max-height: 240px;
|
||||||
|
opacity: 1;
|
||||||
|
overflow-y: scroll;
|
||||||
|
}
|
||||||
|
|
||||||
|
.select-box .options-container.active + .selected::after {
|
||||||
|
transform: translateY(-50%) rotateX(180deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.select-box .options-container::-webkit-scrollbar {
|
||||||
|
width: 8px;
|
||||||
|
background: #0d141f;
|
||||||
|
background: #81878f;
|
||||||
|
background: #f1f2f3;
|
||||||
|
border-radius: 0 5px 5px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.select-box .options-container::-webkit-scrollbar-thumb {
|
||||||
|
background: #525861;
|
||||||
|
background: #81878f;
|
||||||
|
border-radius: 0 5px 5px 0;
|
||||||
|
}
|
||||||
|
.select-box .option,
|
||||||
|
.selected {
|
||||||
|
padding: 12px 15px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.select-box .option:hover {
|
||||||
|
background: #2F345B;
|
||||||
|
}
|
||||||
|
.select-box .option:hover .item {
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.select-box label {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.select-box .option .radio {
|
||||||
|
display: none;
|
||||||
|
}
|
71
src/components/SelectBox.js
Normal file
71
src/components/SelectBox.js
Normal file
|
@ -0,0 +1,71 @@
|
||||||
|
import { useRef, useState, useEffect } from "react"
|
||||||
|
import "./SelectBox.css"
|
||||||
|
|
||||||
|
function Option({ option, onClick }) {
|
||||||
|
return (
|
||||||
|
<div className="option" onClick={onClick}>
|
||||||
|
<input
|
||||||
|
type="radio"
|
||||||
|
className="radio"
|
||||||
|
id={option.id} />
|
||||||
|
<label htmlFor={option.id}>
|
||||||
|
<div className="item">{option.name}</div>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export function SelectBox({ options }) {
|
||||||
|
if (!Array.isArray(options)) {
|
||||||
|
throw "Items must be an array!"
|
||||||
|
}
|
||||||
|
|
||||||
|
const [selectedItem, setSelectedItem] = useState(0)
|
||||||
|
const [active, setActive] = useState(false)
|
||||||
|
|
||||||
|
const containerRef = useRef();
|
||||||
|
|
||||||
|
const handleClick = e => {
|
||||||
|
if (containerRef.current.contains(e.target)) {
|
||||||
|
// inside click
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// outside click
|
||||||
|
closeDropdown()
|
||||||
|
};
|
||||||
|
|
||||||
|
const closeDropdown = () => {
|
||||||
|
setActive(false)
|
||||||
|
}
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
// add when mounted
|
||||||
|
document.addEventListener("mousedown", handleClick);
|
||||||
|
document.addEventListener("scroll", closeDropdown);
|
||||||
|
// return function to be called when unmounted
|
||||||
|
return () => {
|
||||||
|
document.removeEventListener("mousedown", handleClick);
|
||||||
|
document.removeEventListener("scroll", closeDropdown)
|
||||||
|
};
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const onOptionClick = (option, i) => {
|
||||||
|
setSelectedItem(i)
|
||||||
|
closeDropdown()
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="select-box" ref={containerRef}>
|
||||||
|
<div className={"options-container" + (active ? " active" : "")}>
|
||||||
|
{options.map((opt, i) => (
|
||||||
|
<Option option={opt} key={i} onClick={() => onOptionClick(opt, i)} />
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
<div className="selected" onClick={() => setActive(a => !a)}>
|
||||||
|
{options ? (
|
||||||
|
<Option option={options[selectedItem]} />
|
||||||
|
) : null}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
Loading…
Reference in a new issue