127 lines
3.4 KiB
TypeScript
127 lines
3.4 KiB
TypeScript
|
|
import {
|
||
|
|
Avatar,
|
||
|
|
MenuItem,
|
||
|
|
Select,
|
||
|
|
SelectChangeEvent,
|
||
|
|
Typography,
|
||
|
|
useMediaQuery,
|
||
|
|
useTheme,
|
||
|
|
} from "@mui/material";
|
||
|
|
import Box from "@mui/material/Box";
|
||
|
|
import { useCallback, useEffect, useRef, useState } from "react";
|
||
|
|
import "./CustomSelect.css";
|
||
|
|
import arrow_down from "../../assets/icons/arrow_down.svg";
|
||
|
|
|
||
|
|
type CustomSelectProps = {
|
||
|
|
items: string[];
|
||
|
|
selectedItem: number | null;
|
||
|
|
setSelectedItem: (num: number) => void;
|
||
|
|
};
|
||
|
|
|
||
|
|
export const CustomSelect = ({
|
||
|
|
items,
|
||
|
|
selectedItem,
|
||
|
|
setSelectedItem,
|
||
|
|
}: CustomSelectProps) => {
|
||
|
|
const theme = useTheme();
|
||
|
|
const isMobile = useMediaQuery(theme.breakpoints.down(600));
|
||
|
|
const [opened, setOpened] = useState<boolean>(false);
|
||
|
|
const [currentValue, setCurrentValue] = useState<string | null>(null);
|
||
|
|
const [placeholder, setPlaceholder] = useState<string | null>(null);
|
||
|
|
const ref = useRef<HTMLDivElement | null>(null);
|
||
|
|
|
||
|
|
useEffect(() => {
|
||
|
|
setCurrentValue(selectedItem !== null ? items[selectedItem] : null);
|
||
|
|
setPlaceholder(
|
||
|
|
selectedItem === null ? "Выберите ответственного за сделку" : null,
|
||
|
|
);
|
||
|
|
}, [selectedItem, items]);
|
||
|
|
|
||
|
|
const selectItem = useCallback(
|
||
|
|
(event: SelectChangeEvent<HTMLDivElement>) => {
|
||
|
|
setCurrentValue(items[Number(event.target.value)]);
|
||
|
|
setSelectedItem(Number(event.target.value));
|
||
|
|
setPlaceholder(null);
|
||
|
|
},
|
||
|
|
[items, setSelectedItem],
|
||
|
|
);
|
||
|
|
|
||
|
|
const toggleOpened = useCallback(() => {
|
||
|
|
setOpened((isOpened) => !isOpened);
|
||
|
|
}, []);
|
||
|
|
|
||
|
|
return (
|
||
|
|
<Box>
|
||
|
|
<Box
|
||
|
|
sx={{
|
||
|
|
zIndex: 1,
|
||
|
|
position: "relative",
|
||
|
|
width: "100%",
|
||
|
|
height: "56px",
|
||
|
|
padding: "5px",
|
||
|
|
color: selectedItem === null ? "#9A9AAF" : "#7E2AEA",
|
||
|
|
border: "2px solid #ffffff",
|
||
|
|
borderRadius: "30px",
|
||
|
|
background: "#EFF0F5",
|
||
|
|
display: "flex",
|
||
|
|
alignItems: "center",
|
||
|
|
cursor: "pointer",
|
||
|
|
}}
|
||
|
|
onClick={() => ref.current?.click()}
|
||
|
|
>
|
||
|
|
<Avatar sx={{ width: 46, height: 46, marginRight: 1 }} />
|
||
|
|
<Typography
|
||
|
|
sx={{
|
||
|
|
marginLeft: isMobile ? "10px" : "20px",
|
||
|
|
fontWeight: selectedItem === null ? "400" : "500",
|
||
|
|
fontSize: isMobile ? "14px" : "16px",
|
||
|
|
textOverflow: "ellipsis",
|
||
|
|
whiteSpace: "nowrap",
|
||
|
|
overflow: "hidden",
|
||
|
|
flexGrow: 1,
|
||
|
|
}}
|
||
|
|
>
|
||
|
|
{placeholder || currentValue}
|
||
|
|
</Typography>
|
||
|
|
<img
|
||
|
|
src={arrow_down}
|
||
|
|
alt="check"
|
||
|
|
style={{
|
||
|
|
position: "absolute",
|
||
|
|
top: "50%",
|
||
|
|
right: "10px",
|
||
|
|
transform: `translateY(-50%) rotate(${opened ? "180deg" : "0deg"}`,
|
||
|
|
height: "36px",
|
||
|
|
width: "36px",
|
||
|
|
}}
|
||
|
|
className={`select-icon ${opened ? "opened" : ""}`}
|
||
|
|
/>
|
||
|
|
</Box>
|
||
|
|
<Select
|
||
|
|
ref={ref}
|
||
|
|
className="select"
|
||
|
|
value=""
|
||
|
|
open={opened}
|
||
|
|
MenuProps={{
|
||
|
|
disablePortal: true,
|
||
|
|
PaperProps: {
|
||
|
|
style: {
|
||
|
|
maxHeight: "300px",
|
||
|
|
overflow: "auto",
|
||
|
|
},
|
||
|
|
},
|
||
|
|
}}
|
||
|
|
sx={{ width: "100%" }}
|
||
|
|
onChange={selectItem}
|
||
|
|
onClick={toggleOpened}
|
||
|
|
>
|
||
|
|
{items.map((item, index) => (
|
||
|
|
<MenuItem key={item + index} value={index} sx={{ padding: "12px" }}>
|
||
|
|
{item}
|
||
|
|
</MenuItem>
|
||
|
|
))}
|
||
|
|
</Select>
|
||
|
|
</Box>
|
||
|
|
);
|
||
|
|
};
|