I have a project on react . In it I make a card, when you hover over it, information about this card should appear next to it. Here is the code:
export const CourseCard: React.FC<CourseCardProps> = () => {
const [isShown, setIsShown] = useState(false)
const [xInfoPos, setXInfoPos] = useState("0")
const [yInfoPos, setYInfoPos] = useState("0")
const cardRef = useRef<HTMLDivElement>(null)
const infoCardRef = useRef<HTMLDivElement>(null)
const formateXCord = (x : Number | undefined) => {
return "left-[" + x + "px]"
}
const formateYCord = (y : Number | undefined ) => {
return "top-[" + y + "px]"
}
const carMouseHandler = () => {
const cardEl = cardRef.current?.getBoundingClientRect()
const infoCardEl = infoCardRef.current?.getBoundingClientRect()
setXInfoPos(formateXCord(cardEl?.right))
setYInfoPos(formateYCord(cardEl?.top))
setIsShown(true)
}
return (
<>
<div ref={cardRef} onMouseEnter={carMouseHandler} onMouseLeave={()=>setIsShown(false)} className="py-0 px-4 relative snap-center flex flex-col w-1/4">
<div className="relative rounded-t-xl rounded-b-none bg-white shrink-0">
<img className="block w-full h-auto rounded-t rounded-b-none" src={cardImage} />
<button className="absolute top-2.5 right-2.5 h-6 w-6 rounded-full bg-gray-700 text-white font-bold text-center">♡</button>
</div>
<div className="py-2.5 px-3.5 bg-white border-[1px] border-solid border-gray-300 rounded-b border-t-0 flex-1 flex flex-col">
<div className="mb-2 flex flex-wrap items-center">
<span className="text-lg leading-4 text-cyan-600 mr-2"></span>
<span className="text-sm leading-4 text-blue-400 line-through"></span>
</div>
<h3 className="text-lg leading-4 mb-2 text-black font-normal h-14 overflow-hidden">TITLE</h3>
<div className="text-sm leading-5 opacity-40 mt-auto">Teacher Name</div>
</div>
{isShown &&
<div ref={infoCardRef} className={`flex flex-col absolute ${xInfoPos} ${yInfoPos} z-20 rounded-t-md w-full py-4 px-4 bg-slate-100`} >
<div className="mb-2 text-sm leading-5 text-black flex items-center">
<img className="block rounded-full w-7 h-7 shrink-0 mr-2" src={cardImage} />
Autor
</div>
<div className="text-lg leading-5 font-light text-black mb-2">
Title
</div>
<ul className="list-none p-0 mb-2 w-full block">
<li className="top-0 left-0 bg-white w-full" >
<img className="block w-full rounded-md top-0 left-0 right-0 bottom-0 h-full object-cover" src={cardImage}></img>
</li>
</ul>
<div className="text-sm leading-5 text-black mb-2">
Description
</div>
<ul className="-mx-2 list-none p-0 flex flex-wrap">
<li className="w-1/2 mb-2.5 text-sm leading-5 text-gray-800 flex items-center">
<img className="block shrink-0 mr-2.5"></img>
file
</li>
<li className="px-2.5 w-1/2 mb-2.5 text-sm leading-5 text-gray-800 flex items-center">
<img className="block shrink-0 mr-2.5"></img>
clock
</li>
<li className="w-1/2 mb-2.5 text-sm leading-5 text-gray-800 flex items-center">
<img className="block shrink-0 mr-2.5"></img>
books
</li>
<li className="px-2.5 w-1/2 mb-2.5 text-sm leading-5 text-gray-800 flex items-center">
<img className="block shrink-0 mr-2.5"></img>
lang
</li>
</ul>
<div className="pt-2 text-base leading-5 font-light text-gray-800 border-t border-solid border-t-black">footer</div>
</div>
}
</div>
</>
);
};
But I ran into a problem , the project uses tailwind and the concatenation doesn't work with it
"left-[" + x + "px]"
I found an article describing it https://v2.tailwindcss.com/docs/just-in-time-mode but if I write like this
"left-[400px]"
it works. The solution suggested in this article does not work because there can be many variants of x and y.
Right now the information is blocking the card which the cursor is pointing at.
Can you tell me how to solve this problem or give me another way to solve it?
Note: Information about the card should appear depending on the location of the card itself. If the card is located at the bottom then the information appears above it, if it is at the top then the information appears below it. Otherwise, on the right or left of the card.
<div style={{ top: yInfoPos, left: xInfoPos }} ...
. Note: value should end with px (eg400px
) - bogdanoff