BetterDiscordApp-rauenzi/renderer/src/ui/settings/components/dropdown.jsx

47 lines
1.6 KiB
React
Raw Normal View History

2019-06-29 06:47:56 +02:00
import {React} from "modules";
import Arrow from "../../icons/downarrow";
2023-03-07 01:17:28 +01:00
const {useState, useCallback} = React;
2023-03-07 01:17:28 +01:00
export default function Select({value: initialValue, options, style, onChange}) {
const [value, setValue] = useState(initialValue ?? options[0].value);
const change = useCallback((val) => {
onChange?.(val);
setValue(val);
2023-03-20 03:23:11 +01:00
}, [onChange]);
2019-06-29 06:47:56 +02:00
2023-03-07 01:17:28 +01:00
const hideMenu = useCallback(() => {
setOpen(false);
document.removeEventListener("click", hideMenu);
}, []);
2019-06-29 06:47:56 +02:00
2023-03-07 01:17:28 +01:00
const [open, setOpen] = useState(false);
const showMenu = useCallback((event) => {
event.preventDefault();
event.stopPropagation();
2019-06-29 06:47:56 +02:00
2023-03-07 01:17:28 +01:00
const next = !open;
setOpen(next);
if (!next) return;
document.addEventListener("click", hideMenu);
2023-03-20 03:23:11 +01:00
}, [hideMenu, open]);
2023-03-07 01:17:28 +01:00
2023-03-13 21:32:51 +01:00
// ?? options[0] provides a double failsafe
const selected = options.find(o => o.value == value) ?? options[0];
2023-03-07 01:17:28 +01:00
const optionComponents = <div className="bd-select-options">
{options.map(opt =>
<div className={`bd-select-option${selected.value == opt.value ? " selected" : ""}`} onClick={() => change(opt.value)}>{opt.label}</div>
2019-06-29 06:47:56 +02:00
)}
</div>;
2023-03-07 01:17:28 +01:00
const styleClass = style == "transparent" ? " bd-select-transparent" : "";
const isOpen = open ? " menu-open" : "";
return <div className={`bd-select${styleClass}${isOpen}`} onClick={showMenu}>
<div className="bd-select-value">{selected.label}</div>
<Arrow className="bd-select-arrow" />
{open && optionComponents}
</div>;
}