Refactor ProjectSelect and UnitTypeCard components; enhance styling and add new unit types to projects data
This commit is contained in:
@@ -0,0 +1,81 @@
|
||||
/* eslint-disable react-hooks/exhaustive-deps */
|
||||
import { motion } from "motion/react";
|
||||
import { AnimatePresence } from "motion/react";
|
||||
import { useEffect, useState } from "react";
|
||||
import { useClickAway } from "@uidotdev/usehooks";
|
||||
import clsx from "clsx";
|
||||
import ChevronDownIcon from "../icons/ChevronDownIcon";
|
||||
import CheckIcon from "../icons/CheckIcon";
|
||||
function Select({
|
||||
options,
|
||||
onSelect,
|
||||
className = "",
|
||||
}: {
|
||||
options: string[];
|
||||
onSelect: (option: string) => void;
|
||||
className?: string;
|
||||
}) {
|
||||
const [isShow, setIsShow] = useState(false);
|
||||
const [selectedOption, setSelectedOption] = useState(options[0]);
|
||||
const ref = useClickAway<HTMLDivElement>(() => setIsShow(false));
|
||||
|
||||
useEffect(() => {
|
||||
onSelect(selectedOption);
|
||||
}, [selectedOption]);
|
||||
|
||||
return (
|
||||
<div ref={ref} className={clsx("relative", className)}>
|
||||
<button
|
||||
className={clsx(
|
||||
"px-4 py-[14px] rounded-xl ring-1 transition-[box-shadow] w-full text-left flex items-center justify-between group",
|
||||
isShow ? " ring-[#00BED7]" : "ring-[#E2E2DC]"
|
||||
)}
|
||||
onClick={() => setIsShow(!isShow)}
|
||||
>
|
||||
<p className="text-s">{selectedOption}</p>
|
||||
<ChevronDownIcon
|
||||
className={clsx(
|
||||
"w-6 h-6 flex-shrink-0 group-hover:text-[#00BED7] transition-[color,rotate]",
|
||||
isShow && "rotate-180"
|
||||
)}
|
||||
/>
|
||||
</button>
|
||||
<AnimatePresence>
|
||||
{isShow && (
|
||||
<motion.div
|
||||
initial={{ opacity: 0 }}
|
||||
animate={{ opacity: 1 }}
|
||||
exit={{ opacity: 0 }}
|
||||
transition={{ duration: 0.15 }}
|
||||
className="absolute mt-1 p-1 space-y-0.5 shadow-[0px_2px_8px_rgba(0,0,0,0.15)] rounded-xl bg-white w-full z-10"
|
||||
>
|
||||
{options.map((option, index) => (
|
||||
<button
|
||||
key={index}
|
||||
onClick={() => {
|
||||
setSelectedOption(option);
|
||||
setIsShow(false);
|
||||
}}
|
||||
className="px-4 py-[14px] group hover:bg-[#F3F3F2] transition-colors rounded-xl w-full text-left flex items-center justify-between"
|
||||
>
|
||||
<p
|
||||
className={clsx(
|
||||
"text-s group-hover:text-[#0D1922] transition-colors",
|
||||
selectedOption !== option && "text-[#0D1922]/70"
|
||||
)}
|
||||
>
|
||||
{option}
|
||||
</p>
|
||||
{selectedOption === option && (
|
||||
<CheckIcon className="w-6 h-6 flex-shrink-0 text-[#00BED7]" />
|
||||
)}
|
||||
</button>
|
||||
))}
|
||||
</motion.div>
|
||||
)}
|
||||
</AnimatePresence>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default Select;
|
||||
Reference in New Issue
Block a user