I have a cartwidget that i would like to show the items that are already in the cart when I put the mouse on the CartWidget. I do not kow how to implement this code. I just create a CartHover component with function and the Cart.js component inside of it. Then, I added CartHover in the CartWidget. But, nothing happened. Maybe there is someone that can help me and do the hover on the cartWidget in another way. This is the CartHover:
import { useState } from "react";
import CartComponent from "../Cart/Cart";
const CartHover = () => {
const [show, setShow] = useState(false);
const showCart = (e)=>{
setShow(!show);
};
const hideCart = e => {
setShow(false);
};
return (
<>
<div>
<CartComponent
show={show}
onMouseEnter={showCart}
onMouseLeave={hideCart}/>
</div>
</>
)
};
export default CartHover;
This is the Cart.jsx where are all the items in the shopping-cart and I want to be seen in the hover, perhaps it is necessary to do a smaller version of it:
import { Table } from "react-bootstrap";
import { Link } from "react-router-dom";
import { useCartContext } from "../../Context/CartContext";
const CartComponent = () => {
const { list, totalPrice, deleteProd } = useCartContext();
return (
<>
<h1 className="py-4 text-center text-muted">
Cart
</h1>
{list.length > 0 ? (<Table striped hover className="text-muted">
<thead>
<tr>
<th>Product</th>
<th>Title</th>
<th>Quantity</th>
<th>Price</th>
</tr>
</thead>
<tbody>
{list.map((varietal) => (
<tr key={varietal.id}>
<td>
<img
src={varietal.pictureUrl}
alt='img'
style={{ width: "82px" }}
/>
</td>
<td className="align-middle">{varietal.title}</td>
<td className="align-middle">{varietal.count}</td>
<td className="align-middle">${varietal.price}</td>
<td className="align-middle"><button onClick={() => deleteProd(varietal)} className="badge badge-info">Remove</button></td>
</tr>
))}
</tbody>
<thead>
<tr className="font-weight-bold">
<td colSpan="3">Total</td>
<td>${totalPrice()}</td>
</tr>
</thead>
</Table>) : (<div className="py-5">
<h3 className="d-flex justify-content-center pt-5 text-muted">The Cart is empty</h3>
<p className="d-flex justify-content-center text-muted">
Return to home to see our products
</p>
<Link to='/' className="d-flex justify-content-center text-decoration-none"><button className="btn btn-info"> Home </button></Link>
</div>)}
</>
);
};
export default CartComponent;
This is the NavBar:
import React from "react";
import { Navbar as NavbarBootstrap, Nav } from "react-bootstrap";
import { Link, NavLink } from "react-router-dom";
import CartHover from "../CartHover/CartHover";
import CartWidgetComponet from "../CartWidget/CartWidget";
import LogoComponent from "../Logo/LogoComponent";
const NavBar = () => (
<>
<NavbarBootstrap bg="light" variant="light">
<Link to="/" className="text-decoration-none">
<NavbarBootstrap.Brand className="mx-5 px-5"><LogoComponent /> AIMARA</NavbarBootstrap.Brand>
</Link>
<Nav className="ml-auto">
<Link to="/" className="text-decoration-none text-dark">
<Nav className="mx-3">Aimara</Nav>
</Link>
<Link to="/category/red" className="text-decoration-none text-dark">
<Nav className="mx-3">Red Wines</Nav>
</Link>
<Link to="/category/white" className="text-decoration-none text-dark">
<Nav className="mx-3">White Wines</Nav>
</Link>
<Link to="/Contact" className="text-decoration-none text-dark">
<Nav className="mx-3">Contact</Nav>
</Link>
</Nav>
<NavLink to="/Cart" className="pl-3 pr-1 text-muted"><CartWidgetComponet><CartHover /></CartWidgetComponet></NavLink>
</NavbarBootstrap>
</>
);
export default NavBar;
and this is the CartWidgetComponent:
import { useCartContext } from "../../Context/CartContext";
const CartWidgetComponet = () => {
const { list, totalQuantity } = useCartContext();
return (
<>
<svg xmlns="http://www.w3.org/2000/svg" width="25" height="25" fill="currentColor" className="bi bi-cart2" viewBox="0 0 16 16">
<path d="M0 2.5A.5.5 0 0 1 .5 2H2a.5.5 0 0 1 .485.379L2.89 4H14.5a.5.5 0 0 1 .485.621l-1.5 6A.5.5 0 0 1 13 11H4a.5.5 0 0 1-.485-.379L1.61 3H.5a.5.5 0 0 1-.5-.5zM3.14 5l1.25 5h8.22l1.25-5H3.14zM5 13a1 1 0 1 0 0 2 1 1 0 0 0 0-2zm-2 1a2 2 0 1 1 4 0 2 2 0 0 1-4 0zm9-1a1 1 0 1 0 0 2 1 1 0 0 0 0-2zm-2 1a2 2 0 1 1 4 0 2 2 0 0 1-4 0z"/>
</svg>
{list.length > 0 ? (<span className="badge badge-info">{totalQuantity()}</span>) : null}
</>
);
};
export default CartWidgetComponet;
I hope there is someone that could help me. Cheers
I see you're using React Boostrap. It has OverlayTrigger
that you can put to use in this case. The idea is to make your CartHover
element a popover for the OverlayTrigger
so that whatever triggers it (hover in our case) shows your CardHover
elements. So here is some code:
const CartHover = () => {
return (
<>
<div>
You have x number of items in your cart and here they are
<br />
Item 1
<br />
Item 2
</div>
</>
);
};
const CartIcon = () => {
const popover = (
<Popover>
<Popover.Content>
<CartHover />
</Popover.Content>
</Popover>
);
return (
<OverlayTrigger
trigger={["click", "hover"]}
rootClose={true}
placement={"bottom"}
overlay={popover}
>
<div className={"d-inline-block"}>
<svg
xmlns="http://www.w3.org/2000/svg"
width="25"
height="25"
fill="currentColor"
className="bi bi-cart2"
viewBox="0 0 16 16"
>
<path d="M0 2.5A.5.5 0 0 1 .5 2H2a.5.5 0 0 1 .485.379L2.89 4H14.5a.5.5 0 0 1 .485.621l-1.5 6A.5.5 0 0 1 13 11H4a.5.5 0 0 1-.485-.379L1.61 3H.5a.5.5 0 0 1-.5-.5zM3.14 5l1.25 5h8.22l1.25-5H3.14zM5 13a1 1 0 1 0 0 2 1 1 0 0 0 0-2zm-2 1a2 2 0 1 1 4 0 2 2 0 0 1-4 0zm9-1a1 1 0 1 0 0 2 1 1 0 0 0 0-2zm-2 1a2 2 0 1 1 4 0 2 2 0 0 1-4 0z" />
</svg>
<span className="badge badge-info">8</span>
</div>
</OverlayTrigger>
);
};
export default function App() {
return (
<div className="App">
<CartIcon />
</div>
);
}
Sandbox: https://codesandbox.io/s/wizardly-shape-ow5wz?file=/src/App.js