frontPanel/src/components/CustomSelect/CustomSelect.tsx

197 lines
5.1 KiB
TypeScript
Raw Normal View History

import * as React from "react";
import { FC, useCallback, useMemo, useRef, useState } from "react";
2024-04-08 14:05:38 +00:00
import {
Avatar,
MenuItem,
Select,
SelectChangeEvent,
Typography,
useMediaQuery,
useTheme,
Box,
2024-04-08 14:05:38 +00:00
} from "@mui/material";
import "./CustomSelect.css";
import arrow_down from "../../assets/icons/arrow_down.svg";
type Items = {
id: string;
title: string;
subTitle: string;
}
2024-04-08 14:05:38 +00:00
type CustomSelectProps = {
items: Items[] | [];
selectedItemId: string | null;
2024-04-09 13:07:42 +00:00
setSelectedItem: (value: string | null) => void;
handleScroll: () => void;
2024-04-08 14:05:38 +00:00
};
2024-06-01 22:42:52 +00:00
2024-04-09 13:07:42 +00:00
export const CustomSelect: FC<CustomSelectProps> = ({
items,
selectedItemId,
2024-04-08 14:05:38 +00:00
setSelectedItem,
handleScroll,
2024-04-09 13:07:42 +00:00
}) => {
2024-04-08 14:05:38 +00:00
const theme = useTheme();
const isMobile = useMediaQuery(theme.breakpoints.down(600));
const ref = useRef<HTMLDivElement | null>(null);
2024-04-08 14:05:38 +00:00
const [opened, setOpened] = useState<boolean>(false);
2024-04-08 14:05:38 +00:00
const toggleOpened = useCallback(() => {
setOpened((isOpened) => !isOpened);
}, []);
const onScroll = useCallback((e: React.UIEvent<HTMLDivElement>) => {
2024-05-20 18:15:36 +00:00
const scrollHeight = e.currentTarget.scrollHeight;
const scrollTop = e.currentTarget.scrollTop;
const clientHeight = e.currentTarget.clientHeight;
const scrolledToBottom = scrollTop / (scrollHeight - clientHeight) > 0.9;
if (scrolledToBottom) {
handleScroll();
2024-05-20 18:15:36 +00:00
}
}, []);
2024-05-20 18:15:36 +00:00
const currentItem = useMemo(() => (
items.find(item => item.id === selectedItemId) || null
), [selectedItemId, items])
2024-05-20 18:15:36 +00:00
const menuItems = useMemo(() => {
if (items.length !== 0) {
return items.map((item) => (
2024-05-20 18:15:36 +00:00
<MenuItem
key={item.id}
value={item.id}
sx={{
padding: "6px 0",
zIndex: 2,
borderTop: "1px solid rgba(154, 154, 175, 0.1)",
width: "auto",
}}
2024-05-20 18:15:36 +00:00
>
<Box
sx={{
fontSize: "16px",
color: "#4D4D4D",
display: "flex",
flexDirection: isMobile ? "column" : "row",
justifyContent: "space-evenly",
width: "100%",
}}
>
<Typography
sx={{
width: "33%",
borderRight: isMobile
? "none"
: "1px solid rgba(154, 154, 175, 0.1)",
padding: isMobile ? "5px 0 5px 20px" : "10px 0 10px 20px",
}}
>
{item.title}
</Typography>
<Typography
sx={{
width: "33%",
borderRight: isMobile
? "none"
: "1px solid rgba(154, 154, 175, 0.1)",
padding: isMobile ? "5px 0 5px 20px" : "10px 0 10px 20px",
color: isMobile ? "#9A9AAF" : "#4D4D4D",
}}
>
{item.subTitle}
</Typography>
</Box>
2024-05-20 18:15:36 +00:00
</MenuItem>
));
}
return (
<MenuItem key={"-1"} disabled sx={{ padding: "12px", zIndex: 2 }}>
нет данных
</MenuItem>
);
}, [items]);
2024-05-20 18:15:36 +00:00
2024-04-08 14:05:38 +00:00
return (
<Box>
<Box
sx={{
2024-04-09 13:07:42 +00:00
zIndex: 3,
2024-04-08 14:05:38 +00:00
position: "relative",
width: "100%",
height: "56px",
padding: "5px",
2024-04-12 09:05:33 +00:00
color:
currentItem === null
2024-04-12 09:05:33 +00:00
? theme.palette.grey2.main
: theme.palette.brightPurple.main,
border: `2px solid ${theme.palette.common.white}`,
2024-04-08 14:05:38 +00:00
borderRadius: "30px",
background: "#EFF0F5",
display: "flex",
alignItems: "center",
cursor: "pointer",
}}
onClick={() => {if (ref.current !== null) ref.current?.click()}}
2024-04-08 14:05:38 +00:00
>
<Avatar sx={{ width: 46, height: 46, marginRight: 1 }} />
<Typography
sx={{
marginLeft: isMobile ? "10px" : "20px",
fontWeight: currentItem === null ? "400" : "500",
2024-04-08 14:05:38 +00:00
fontSize: isMobile ? "14px" : "16px",
textOverflow: "ellipsis",
whiteSpace: "nowrap",
overflow: "hidden",
flexGrow: 1,
}}
>
{currentItem?.title || "Выберите ответственного за сделку"}
2024-04-08 14:05:38 +00:00
</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"
2024-04-09 13:07:42 +00:00
value={""}
2024-04-08 14:05:38 +00:00
open={opened}
MenuProps={{
disablePortal: true,
PaperProps: {
onScroll: onScroll,
2024-04-08 14:05:38 +00:00
style: {
2024-04-09 13:07:42 +00:00
zIndex: 2,
2024-04-08 14:05:38 +00:00
maxHeight: "300px",
overflow: "auto",
overflowX: "auto",
2024-04-08 14:05:38 +00:00
},
},
}}
sx={{}}
onChange={({ target }: SelectChangeEvent<string>) => setSelectedItem(target.value)}
2024-04-08 14:05:38 +00:00
onClick={toggleOpened}
>
2024-05-20 18:15:36 +00:00
{menuItems}
2024-04-08 14:05:38 +00:00
</Select>
</Box>
);
};