70 lines
1.7 KiB
JavaScript
70 lines
1.7 KiB
JavaScript
"use client";
|
|
import React, { useState, useRef, useEffect } from "react";
|
|
import styles from "./styles.module.css";
|
|
import ArrowDownIcon from "../icons/arrowDown";
|
|
|
|
const SelectField = ({ label, options, ...props }) => {
|
|
const [showOptions, setShowOptions] = useState(false);
|
|
const [dropUp, setDropUp] = useState(false);
|
|
|
|
const selectRef = useRef(null);
|
|
|
|
const [currentSelected, setCurrentSelected] = useState({
|
|
label: label,
|
|
value: "",
|
|
});
|
|
|
|
useEffect(() => {
|
|
if (!showOptions || !selectRef.current) return;
|
|
|
|
const rect = selectRef.current.getBoundingClientRect();
|
|
|
|
const spaceBelow = window.innerHeight - rect.bottom;
|
|
const spaceAbove = rect.top;
|
|
|
|
const dropdownHeight = 150;
|
|
|
|
setDropUp(spaceBelow < dropdownHeight && spaceAbove > dropdownHeight);
|
|
}, [showOptions]);
|
|
|
|
return (
|
|
<div
|
|
ref={selectRef}
|
|
className={`${styles.select} ${showOptions ? styles.isFocused : ""}`}
|
|
onClick={() => setShowOptions(!showOptions)}
|
|
{...props}
|
|
>
|
|
<label
|
|
className={`${styles.label} ${currentSelected.value ? styles.selected : ""}`}
|
|
>
|
|
{currentSelected.label}
|
|
</label>
|
|
<ArrowDownIcon />
|
|
|
|
{showOptions && (
|
|
<div
|
|
className={`${styles.optionsContainer} ${
|
|
dropUp ? styles.dropUp : ""
|
|
}`}
|
|
>
|
|
{options.map((opt, key) => {
|
|
return (
|
|
<div
|
|
key={key}
|
|
onClick={() => {
|
|
setCurrentSelected(opt);
|
|
setShowOptions(false);
|
|
}}
|
|
>
|
|
<p>{opt.label}</p>
|
|
</div>
|
|
);
|
|
})}
|
|
</div>
|
|
)}
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export default SelectField;
|