feat: enhance NewSelect component with reset functionality and improved styling

This commit is contained in:
2025-06-16 15:21:03 +05:00
parent e11bcb13f3
commit 1ae87e954b
2 changed files with 39 additions and 22 deletions
+38 -22
View File
@@ -3,18 +3,26 @@ import ChevronDownIcon from "./icons/ChevronDownIcon";
import ChevronUpIcon from "./icons/ChevronUpIcon";
import clsx from "clsx";
import CloseIcon from "./icons/CloseIcon";
import Button from "./Button";
import CheckIcon from "./icons/CheckIcon";
import { useClickAway } from "@uidotdev/usehooks";
function NewSelect<T extends { name: string }>({
data,
isGrid,
placeholder,
resetTitle,
}: {
data: T[];
isGrid: boolean;
placeholder: string;
resetTitle: string;
}) {
const [selectedValues, setSelectedValues] = useState<T[]>([]);
const [isSelectVisible, setIsSelectVisible] = useState(false);
const selectRef = useClickAway<HTMLDivElement>(() => {
setIsSelectVisible(false);
});
const handleSelectClick = (item: T) => {
const isItemSelected = selectedValues.some((val) => val.name === item.name);
@@ -41,7 +49,10 @@ function NewSelect<T extends { name: string }>({
</div>
</div>
) : (
<div className="relative w-[19.583vw] bg-white rounded-[0.833vw] select-none">
<div
className="relative w-[19.583vw] bg-white rounded-[0.833vw] select-none"
ref={selectRef}
>
<div
className={clsx(
"flex items-center justify-between px-[1.111vw] py-[1.285vw] hover:bg-[#F0F0F0] rounded-[0.833vw] cursor-pointer",
@@ -51,21 +62,14 @@ function NewSelect<T extends { name: string }>({
)}
onClick={() => setIsSelectVisible(!isSelectVisible)}
>
<div className="button-m font-medium flex gap-[0.278vw] text-ellipsis overflow-hidden">
<div className="button-m font-medium text-ellipsis line-clamp-1 flex-1">
{selectedValues.length > 0
? selectedValues.map((value, index) => {
return (
<div key={value.name} className="">
{value.name +
(index !== selectedValues.length - 1 ? ", " : "")}
</div>
);
})
? selectedValues.map(({ name }) => name).join(", ")
: placeholder}
</div>
<span
className={clsx(
"w-[1.389vw] h-[1.389vw] flex items-center justify-center ",
"w-[1.389vw] h-[1.389vw] flex items-center justify-center",
isSelectVisible ? "text-[#7B60F3]" : "text-[#7D7D7D]"
)}
>
@@ -79,27 +83,39 @@ function NewSelect<T extends { name: string }>({
)}
>
<div
className="flex flex-col gap-[0.278vw] p-[0.833vw] w-full bg-white rounded-[0.833vw]"
className="flex flex-col gap-[0.278vw] px-[0.833vw] pb-[0.833vw] w-full bg-white rounded-[0.833vw] max-h-[13.889vw] overflow-auto"
style={{
boxShadow: "0px 4px 40px 0px #0000000D, 0px 2px 2px 0px #0000000D",
}}
>
<div
className="text-s font-medium p-[0.833vw] text-[#7D7D7D] flex items-center gap-[0.278vw] cursor-pointer rounded-[0.278vw] hover:bg-[#F6F6F6]"
onClick={() => setSelectedValues([])}
>
<span className="size-[1.111vw] flex items-center justify-center">
<CloseIcon />
</span>
Выбрать всё
<div className="bg-white sticky top-0 pt-[0.833vw]">
<Button
variant="secondary"
className="!justify-start w-full text-s font-medium p-[0.833vw] text-[#7D7D7D] flex items-center gap-[0.278vw] cursor-pointer rounded-[0.278vw] hover:bg-[#F6F6F6]"
onClick={() => setSelectedValues([])}
>
<span className="size-[1.111vw] flex items-center justify-center">
<CloseIcon />
</span>
{resetTitle}
</Button>
</div>
<div className="h-[1px] w-full bg-[#F6F6F6]" />
<div className="min-h-[1px] w-full bg-[#F6F6F6]" />
{data.map((item, index) => (
<div
key={index}
className="w-full p-[0.833vw] text-s rounded-[0.278vw] hover:bg-[#F6F6F6] cursor-pointer"
className="flex gap-[0.278vw] w-full p-[0.833vw] text-s rounded-[0.278vw] hover:bg-[#F6F6F6] cursor-pointer"
onClick={() => handleSelectClick(item)}
>
<div className="size-[1.111vw]">
{selectedValues
.map((value) => value.name)
.includes(item.name) && (
<span className="text-[#7B60F3]">
<CheckIcon />
</span>
)}
</div>
{item.name}
</div>
))}
+1
View File
@@ -76,6 +76,7 @@ function DashboardPage() {
]}
isGrid={false}
placeholder="Выберите сервер"
resetTitle="Все сервера"
/>
<div className="w-full">
<div className="flex flex-col gap-[1.667vw]">