how to show a hidden element on hover on tailwind - reactjs

how would it be possible to display a hidden menu through a hover. im getting confused as to how a hidden element can be connected to a visible element. this example is on the headlessui website. however instead of clicking on it, would it be possible to hover to show the popover?
return (
<div className='fixed w-full max-w-sm px-4 top-16'>
<Popover className='relative'>
{({ open }) => (
<>
<Popover.Button></Popover.Button>
<Transition>
<Popover.Panel className='absolute z-10 w-screen max-w-sm px-4 mt-3 transform -translate-x-1/2 left-1/2 sm:px-0 lg:max-w-3xl'></Popover.Panel>
</Transition>
</>
)}
</Popover>
</div>
);

Try using the onMouse in Events
return (
<div onMouseEnter={() => setOpen(true)}
onMouseLeave={() => setOpen(false)}
className='fixed w-full max-w-sm px-4 top-16'>
<Popover className='relative'>
{({ open }) => (
<>
<Popover.Button></Popover.Button>
<Transition>
<Popover.Panel className='absolute z-10 w-screen max-w-sm px-4 mt-3 transform -translate-x-1/2 left-1/2 sm:px-0 lg:max-w-3xl'></Popover.Panel>
</Transition>
</>
)}
</Popover>
</div>
);

Related

Add/delete draggable item in beautiful drag and drop (dnd)

First, I'm new to React.
So, I've been making some drag and drop feature while there are also add and delete item feature on it. There are only 2 jsx file that I use, first is DragDropContext and the second is Column (Column with draggable item on it).
Here some code for your better understanding
<DragDropContext onDragEnd={onDragEnd}>
<div className="w-full md:w-[80vw] h-screen p-5 lg:p-20 overflow-y-scroll text-gray-800 bg-slate-100">
<h3 className='text-2xl font-bold'>Favorite Page</h3>
<div className='flex justify-between items-center mt-8'>
<div>
<input type="text" placeholder='type something...' className='p-2 rounded' />
<input type="button" value="Add" className='p-2 rounded bg-indigo-300 ml-4' />
</div>
<div>
<button onClick={onOff}
className={`px-4 py-2 rounded-full text-white ${isToggled ? 'bg-indigo-500': 'bg-slate-400'}`}>{`${isToggled ? 'Edit Page' : 'Save Page'}`}</button>
</div>
</div>
{isToggled ?
<div className='flex mt-5 w-full gap-5 h-fit'>
{state.columnOrder.map((columnId) => {
const column = state.columns[columnId];
const tasks = column.taskIds.map(taskId => state.tasks[taskId]);
// console.log(tasks);
return <Column key={column.id} column={column} tasks={tasks} dataPost={dataPost} enable={true} color={'bg-slate-100'} toggle={isToggled}/>
})}
</div>
:
<div className='flex mt-5 w-full gap-5 h-fit'>
{state.columnOrder.map((columnId) => {
const column = state.columns[columnId];
const tasks = column.taskIds.map(taskId => state.tasks[taskId]);
// console.log(tasks);
return <Column key={column.id} column={column} tasks={tasks} dataPost={dataPost} enable={false} color={'bg-white'} deleteItem={deleteItem}/>
})}
</div>
}
</div>
</DragDropContext>
and this one is for Column
const Column = ( {column, tasks, enable, color, deleteItem, toggle}) => {
return(
<div className={`${column.colorBody} w-full rounded-xl overflow-hidden`}>
<p className={` ${column.colorHead} w-full p-4 text-center text-lg font-light text-white`}>{column.title}</p>
<Droppable droppableId={column.id}>
{(droppableProvided, droppableSnapshot) => (
<div key={column.id} className='w-full h-fit p-5 flex flex-col gap-4' ref={droppableProvided.innerRef} {...droppableProvided.droppableProps}>
{tasks.map((task, index) =>(
<Draggable key={task.id} draggableId={`${task.id}`} index={index} isDragDisabled={enable}>
{(draggableProvided, draggableSnapshot) => (
<div className={`${color} w-full flex justify-between rounded h-fit overflow-hidden ${draggableSnapshot.isDragging? 'border-4 border-indigo-400' : ''}`} id={task.id}
ref={draggableProvided.innerRef}
{...draggableProvided.draggableProps}
{...draggableProvided.dragHandleProps}
>
<div className="flex">
<img className="w-[25%] object-cover" src={`http://127.0.0.1:8000/storage/${task.image}`} alt="" />
<p className='p-4 w-[75%]'>{task.title}</p>
</div>
<button onClick={() => {deleteItem(task.id, column.id)}} className={`button-x ${toggle? 'hidden' : 'block'} h-full bg-red-400 text-white flex items-center justify-center pt-2 pr-2 pb-4 pl-4 rounded-bl-full`}><i className="bi bi-x-lg"></i></button>
</div>
)}
</Draggable>
))}
{droppableProvided.placeholder}
</div>
)}
</Droppable>
</div>
Actually, I'm successful at deleting the item. Still, it throws errors in console and when I drop item on the place that I delete the item before, it'll go to the top left corner and back to the deleted position (place that I drop earlier, like a boomerang). The way I deleted the item is only with deleting the div (draggable item), and when i tried to update the state, it completely not rendering on browser.
The error that throws by console are
Unable to find drag handle with id "1" as no handle with a matching id was found -> in yellow
and
`A setup problem was encountered.
Invariant failed: Draggable[id: 1]: Unable to find drag handle` -> in red
Probably if PublicDraggable key="xx" component is deleted, the error would be gone, but it can't be done that way, right?
So, maybe I need some enlightenment, which function or where is the thing that needs and store Draggable Id except on the div.

Portfolio react js mapping error for project cards

import React from 'react'
import net from '../assets/netflix.png'
const Porfolio = () => {
const Projects = [
{
id:1,
title:"Netflix Clone",
desc:"Netflix Landing Page Clone using React JS and Tailwind CSS with Authentication Feature using Firebase",
imgLink:net,
codeLink:"https://github.com/codegoggins/netflix-clone",
projectLink:"https://netflix-clone-13127.firebaseapp.com/"
}
]
return (
<div
className='px-20 py-4'>
<p
className='text-white text-4xl'
>Projects</p>
{/* PROJECT CARDS */}
<div
className='mt-8 flex flex-col justify-center items-center md:flex md:items-start'
>
{
Projects.map(({id,title,desc,imgLink,codeLink,projectLink})=>(
<>
{/* SINGLE CARD */}
<div className='w-[340px] h-auto relative group md:w-[500px]'>
{/* OVERLAY */}
<div
className='bg-black/80 text-sm md:text-lg absolute flex top-0 bottom-0 h-full w-full rounded-lg overflow-hidden opacity-0 group-hover:opacity-100 transition-all duration-300'>
{/* PROJECT DETAILS */}
<div
className='text-white text-sm md:text-lg flex flex-col p-4 gap-3 md:gap-2 items-center justify-center'>
{/* TITLE */}
<p>{title}</p>
{/* DETAIL */}
<p>{desc}</p>
{/* BUTTONS */}
<div
className='flex gap-3 text-sm md:text-lg'>
<button
className='cursor-pointer font-semibold p-1.5 px-4 rounded-md bg-white text-black transition ease-linear duration-300'
>
Code
</button>
<button
className='cursor-pointer font-semibold p-1.5 px-2 rounded-md bg-white text-black transition ease-linear duration-300'>
See Project
</button>
</div>
</div>
</div>
{/* Image */}
<div className='rounded-lg overflow-hidden'>
<img src={imgLink} alt="" className='h-full w-full object-cover'/>
</div>
</div>
</>
))
}
</div>
</div>
)
}
export default Porfolio
I am getting error to add key , for that instead of react fragments, I
replace it with a div and give key to it but I am getting error. With
react fragments I don't get any error but I can't add key to it for
mapping.
I want the card details to be mapped on all the cards.
enter image description here
You should return inside mapping and provide a key for the root element.
for example,
{
products?.map(({ id, title, desc, imgLink, codeLink, projectLink }) => {
return (
<div key={id} className='w-[340px] h-auto relative group md:w-[500px]'>
//Your code here
</div>
)
})}
You can add:
<React.Fragment key={id}>
some code
</React.Fragment>
or remove the fragment and add the key to the first div inside the map

How do I use like & unlike functionality on every element while using map to render those elements?

I have social media posts stored in firebase and each post has a like button. I am using map() function to render those posts but I have declared a single state for like button using useState().
When I click on like button in any of the posts, the state is getting changed for all the posts and same is happening when I dislike.
How do I change the state for that particular post on which like is cliked??
function Feed(){
const [like, setLike] = useState(false);
const [heart, setHeart] = useState(false);
{posts.map((item) => (
<div
key={item.id}
className=" flex flex-col gap-2 bg-white rounded-xl p-3 border border-gray-300 shadow-
lg mb-2"
>
<div className=" flex gap-2 items-center">
<img
src={userImage}
className=" w-[48px] h-[48px] rounded-full "
alt=""
/>
<span className=" text-black font-semibold text-sm">
{userName}
</span>
</div>
<hr />
{item.body && <p>{item.body}</p>}
{item.imageUrl && <img src={item.imageUrl} alt="" />}
{item.videoUrl && (
<iframe
src={item.videoUrl}
title={item.id}
frameBorder="0"
className=" w-full h-[20rem] "
></iframe>
)}
<hr />
<div className=" flex gap-2">
{like ? (
<ThumbUpIcon
className=" cursor-pointer text-blue-600 hover:bg-gray-100 px-2 py-2
hover:rounded-md"
fontSize="large"
onClick={() => setLike(!like)}
/>
) : (
<ThumbUpOutlinedIcon
className=" cursor-pointer text-gary-500 hover:bg-gray-100 px-2 py-2
hover:rounded-md"
fontSize="large"
onClick={() => setLike(!like)}
/>
)}
{heart ? (
<FavoriteOutlinedIcon
className=" cursor-pointer text-red-500 hover:bg-gray-100 px-2 py-2
hover:rounded-md"
fontSize="large"
onClick={() => setHeart(!heart)}
/>
) : (
<FavoriteBorderOutlinedIcon
className=" cursor-pointer text-gary-500 hover:bg-gray-100 px-2 py-2
hover:rounded-md"
fontSize="large"
onClick={() => setHeart(!heart)}
/>
)}
</div>
</div>
))}
}
I suggest instead of a boolean variable for keeping like for posts, define an array and add the id of each element that liked
const [likes, setLikes] = useState([]);
And
likes.findIndex(x=>x===item.id)<0 ?
onClick={() => {likes.add(item.id);setLikse(...likes)}}
Sandbox: Simple Sample is here

How to style a icon inside an input using tailwind and styled-components

const StyledInput = styled.input`w-full focus:ring-indigo-500 focus:border-indigo-500 block p-2 border-gray-300 border-2 rounded-md`;
export const Input = (props: StyledInputProps) => {
return props.iconPosition === 'trailing' ? (
<div>
{props.label && <div tw="text-coolGray-800">{props.label}</div>}
<div tw="w-full relative rounded-md shadow-sm flex">
<StyledInput {...props} />
<div tw="absolute inset-y-0 right-0 pr-3 flex items-center pointer-events-none">
{props.icon}
</div>
</div>
</div>
) : (
<div>
{props.label && <div tw="text-coolGray-800">{props.label}</div>}
<div tw="w-full relative rounded-md flex bg-white">
{props.icon && (
<div tw="z-10 h-full leading-snug font-normal absolute text-center rounded text-base items-center justify-center w-8 pl-3 py-3">
{props.icon}
</div>
)}
<StyledInput {...props} />
</div>
</div>
);
};
No Matter how I try to style the leading input Icon, I always get this:
I'm trying to get the icon to go inside the input element, like Put icon inside input element in a form
But Even trying all the normal answers, I can't figure it out, is there something really dumb I'm missing?

Headless UI "leave" transition not working in React

My navbar is setup such that on state change the hamburger menu opens and closes. While the enter animation works perfectly, the leave doesn't. My animation is a smooth slide in and slide out, but only the slide in works whereas on leave it just closes normally.
const NavbarMenu = ({ isOpen, menuClick }) => {
return (
<Transition appear={true} show={isOpen}>
<Transition.Child
class="flex flex-col bg-yellow-700 fixed top-0 right-0 p-5 z-20 w-1/2 h-full transition ease-in-out duration-300"
enter="transition-opacity ease-in-out duration-700"
enterFrom="translate-x-full"
enterTo="translate-x-0"
leave="transition-opacity ease-out duration-700"
leaveFrom="opacity-100"
leaveTo="opacity-0"
>
<Exit className="text-yellow-100 w-1/6" onClick={() => menuClick()} />
<div className="flex flex-col gap-y-4 mt-10 font-poppins font-bold text-xl text-yellow-100">
<span>About</span>
<span>About</span>
<span>About</span>
</div>
</Transition.Child>
</Transition>
);
};
Your leave transition is missing the translate-x classes.
You probably also want to add the opacity transition to the enter animation.
This should work:
const NavbarMenu = ({ isOpen, menuClick }) => {
return (
<Transition appear={true} show={isOpen}>
<Transition.Child
class="flex flex-col bg-yellow-700 fixed top-0 right-0 p-5 z-20 w-1/2 h-full transition duration-700"
enter="ease-in-out"
enterFrom="translate-x-full opacity-0"
enterTo="translate-x-0 opacity-100"
leave="ease-out"
leaveFrom="translate-x-0 opacity-100"
leaveTo="translate-x-full opacity-0"
>
<Exit className="text-yellow-100 w-1/6" onClick={() => menuClick()} />
<div className="flex flex-col gap-y-4 mt-10 font-poppins font-bold text-xl text-yellow-100">
<span>About</span>
<span>About</span>
<span>About</span>
</div>
</Transition.Child>
</Transition>
);
};
Most often when "leave transitions" doesn't work it's because it unmounts before the transition ends. To work around that you need a "between state" that is triggered when the Transition is in show mode. Then create a useEffect that listens to this state, and set a setTimeout that does the actual unmount of the element.
I found a solution, just delay the execution of set state to 0ms so the transition can trigger the leave property. I don't have a logical explanation but this worked smoothly.
const NavbarMenu = ({ isOpen, menuClick }) => {
return (
<Transition appear={true} show={isOpen}>
<Transition.Child
class="flex flex-col bg-yellow-700 fixed top-0 right-0 p-5 z-20 w-1/2 h-full transition ease-in-out duration-300"
enter="transition-opacity ease-in-out duration-700"
enterFrom="translate-x-full"
enterTo="translate-x-0"
leave="transition-opacity ease-out duration-700"
leaveFrom="opacity-100"
leaveTo="opacity-0"
>
<Exit className="text-yellow-100 w-1/6"
onClick={() =>
setTimeout(() => {
menuClick();
}, 0);
} />
<div className="flex flex-col gap-y-4 mt-10 font-poppins font-bold text-xl text-yellow-100">
<span>About</span>
<span>About</span>
<span>About</span>
</div>
</Transition.Child>
</Transition>
);
};

Resources