How to open Popover manually (Headless UI) - reactjs

Hi im currently running an e-commerce site where i need to open the cart (popover component) manually whenever a person adds something to their cart.
This is the code i have at the moment, but it's not finished. Im using Headless UI from Tailwind.
export default function Cart() {
const {isCartOpen, openCart, closeCart} = useCartUI();
const {lines, totalQuantity} = useCart();
return (
<Popover className="ml-4 flow-root text-sm lg:relative lg:ml-8">
{({open}: {open: boolean}) => {
if(!open) closeCart();
return (
<>
<Popover.Button
className={clsx(
'flex h-[2.4rem] items-center rounded-sm bg-darkGray px-3 py-2 text-sm font-bold duration-150',
open ? "bg-opacity-20" : "bg-opacity-0 hover:bg-opacity-10",
)}
>
<span className="mr-2">Kurv</span>
<ChevronDownIcon className={clsx(open && 'rotate-180')} />
</Popover.Button>
{isCartOpen && (
<Popover.Panel static className="absolute inset-x-0 top-16 mt-px bg-white pb-6 shadow-lg sm:px-2 lg:top-full lg:left-auto lg:right-0 lg:mt-3 lg:-mr-1.5 lg:w-80 lg:rounded-lg lg:ring-1 lg:ring-black lg:ring-opacity-5">
<CartHeader numLines={lines.length} />
{totalQuantity === 0 ? (
<CartEmpty />
) : (
<>
<CartItems />
<CartFooter />
</>
)}
</Popover.Panel>
)}
</>
)
}}
</Popover>
);
}

I was just looking for a similar answer. If you haven't solved it, and are still interested, I found a solution.
You can use the static prop on the popover to always display it and use your own state, or the popover's internal state, to conditionally display its contents.
Here's an example https://codesandbox.io/s/d8llw?file=/src/App.js:600-609. You can find information on the static prop here: https://headlessui.com/react/popover#showing-hiding-the-popover

Related

Netflix clone, mapping different trailers

I'm making a Netflix clone site. I want the trailers of the movies to play when the mouse is hovered over the movie posters. I did this for the big trailer section at the top. But when you hover over any of the posters arranged side by side at the bottom, all the movies in that series play the same trailer instead of a single movie. The reason is because I made that array with the map method. How can I do this like on Netflix? Code and pictures are below.
this row
{movies.map((movie) => (
<>
{trailerUrl && (
<div className="trailer-content">
<Youtube
className="trailer"
videoId={trailerUrl}
opts={opts}
/>
</div>
)}
{!trailerUrl && (
<div key={movie.id} className="all-hover">
{
<img
onMouseLeave={() => setTrailerUrl("")}
onMouseEnter={() => handleEnter(movie)}
className={`row-poster ${
isLargeRow && "row-poster-large"
}`}
src={`${photo_base_URL}${
isLargeRow ? movie.poster_path : movie.backdrop_path
}`}
alt={movie.name}
/>
}......
this picture
issue

How to fix unexpected behavior of Next/Link when it is a child of a button?

I am experiencing some issues with next/link when I use it in my app.
I have a reusable component that renders a button. This component is used twice on the page with different urls each time.
When the page is in desktop view, the button works perfectly. I can navigate from one page to another. When I reduce the size of the screen to either tablet or mobile one redirects correctly and the other one does not respond as expected.
To work around the issue I have enclosed the area inside a link so the user can click outside the button area and still be directed to the page but it is not really the experience I want to offer to the user.
I never had this before. Can someone tell me how to fix this or why is it behaving this way, please? thanks.
const Banner = ({
purpose,
imageUrl,
title1,
title2,
desc1,
linkName,
buttonText,
}) => {
return (
<div className="row flex-lg-row-reverse align-items-center g-5 justify-content-center">
<div className=" col-10 col-sm-8 col-lg-6">
<Image
className="d-block img-fluid mx-lg-auto"
src={imageUrl}
width={700}
height={500}
alt="banner"
loader={myLoader}
/>
</div>
<Link href={linkName} passHref>
<div className="col-lg-4 p-3 text-center text-lg-start border-0">
<h1 className="display-6 fw-bold lh-1 mb-3">{purpose}</h1>
<p className="lead">
{title1}
<br /> {title2}
</p>
<p className="lead">{desc1}</p>
<button className="btn link btn-primary btn-xl w-100">
<Link href={linkName} passHref>
<a> {buttonText}</a>
</Link>
</button>
</div>
</Link>
</div>
);
};
export default function Home({ data }) {
const {
results: {
client: { secondhandListing },
},
} = data;
//console.log('index page results',secondhandListing);
return (
<>
<div
data-spy="scroll"
data-bs-target="main-nav"
data-offset="0"
className="scrollspy-example"
tabIndex="0"
>
<Services />
<div className="section d-flex justify-content-center my-5">
<h1 className="my-5" id="#scrollspyHeading2">
Properties
</h1>
</div>
<div className="container-fluid d-flex justify-content-xxl-between align-items-center flex-wrap flex-lg-nowrap">
<div className="section d-flex">
<Banner
purpose="Rent a Home"
title1="Rental Homes for"
title2="Everyone"
desc1="Explore Apartments, Villas, Homes"
desc2="and more"
buttonText="Explore Renting"
linkName="/search?operationType=rent"
imageUrl="https://bayut-production.s3.eu-central-1.amazonaws.com/image/145426814/33973352624c48628e41f2ec460faba4"
/>
</div>
<div className="section d-flex">
<Banner
purpose="Buy a Home"
title1="Find, Buy & Own"
title2="Your Dream Home"
desc1="Explore Apartments, Villas, Homes"
desc2="and more"
buttonText="Explore Buying"
linkName="/search?operationType=sale"
imageUrl="https://bayut-production.s3.eu-central-1.amazonaws.com/image/145426814/33973352624c48628e41f2ec460faba4"
/>
</div>
</div>
<Team />
<Contact />
</div>
</>
);
}
Run the new-link codemod to automatically upgrade previous versions of Next.js to the new <Link> usage:
npx #next/codemod new-link .
This will change <Link><a id="link">Home<a></Link> to <Link id="link">Home</Link>.
Alternatively, you can add the legacyBehavior prop <Link legacyBehavior><a id="link">Home<a></Link>.
<button> and <a> do not allow interactive content to be their content.
That said, you're passing invalid children to your <Link> component and to the <button> element:
<Link href={linkName} passHref>
<div className="col-lg-4 p-3 text-center text-lg-start border-0">
<h1 className="display-6 fw-bold lh-1 mb-3">{purpose}</h1>
<p className="lead">{title1}<br /> {title2}</p>
<p className="lead">{desc1}</p>
{/* Invalid child */}
<button className="btn link btn-primary btn-xl w-100">
{/* Invalid child */}
<Link href={linkName} passHref>
<a> {buttonText}</a>
</Link>
</button>
</div>
</Link>
That may be the reason of why your component is behaving oddly.
PS. Formatting your code helps by making it more readable. :). You can do that by setting ESLint and Prettier up.
You maybe need to add the legacyBehavior as props in the next/link component.
import Link from 'next/link'
function Legacy() {
return (
<Link href="/about" legacyBehavior>
<a>About Us</a>
</Link>
)
}
export default Legacy
docs: https://nextjs.org/docs/api-reference/next/link#if-the-child-is-a-tag

Is there any way to center this element to screen?

I am starting out using Tailwind with React and I am stuck on this. I tried various methods but still I am stuck. Here is the code and view snippet.
import { Navbar, Welcome, Footer, Services, Transactions } from "./components";
const App = () => {
return (
<div className="min-h-screen">
<div className="h-14 bg-gradient-to-r from-purple-500 to-red-500 border-double rounded-b-3xl border-b-8 w-5/6">
<Welcome />
</div>
<div className="h-14 bg-gradient-to-b from-blue-500 to-green-500 rounded-lg w-1/2 flex justify-center ">
<Services />
</div>
<Transactions />
<Footer />
</div>
);
}
export default App;
Have you try adding mx-auto class to your gradient divs? If that doesn't work you could also try text-center in your main div.

Popup component renders but positioned off-page

I've created a popup element using Tailwindcss.
Functionality-wise the popup renders and is removed totally fine but the problem is that the Popup component's properties are set to h-screen (height: 100%;) and if I'm scrolled down, the pop-up looks off.
For functionality, I've added a class to the body that prevents scrolling but the component is still rendered weirdly.
Image for Example
Popup component code:
interface OrderSummaryProps {
renderOrderSummary: () => void;
OrderSummaryPopupState: boolean;
}
// { cartList, renderPopUp }: OrderSummaryProps
function OrderSummary({ renderOrderSummary, OrderSummaryPopupState }: OrderSummaryProps) {
const getBody = document.querySelector('body')
if (OrderSummaryPopupState) getBody?.classList.add('overflow-hidden')
else getBody?.classList.remove('overflow-hidden')
return (
<>
<div className='absolute top-0 bg-black z-10 w-full backdrop-filter backdrop-blur-sm bg-opacity-25 flex justify-center items-center' style={{ height: '100%' }}>
<div className='bg-white shadow-xl w-max h-max border border-neutral-200 rounded-xl flex items-center justify-between flex-col px-20 py-10'>
<div className='flex flex-col justify-center my-10'>
<button onClick={() => renderOrderSummary()} className='rounded-full py-2 px-6 border-2 border-red-200 bg-red-500 font-bold text-white'>סגור חלון</button>
</div>
</div>
</div>
</>
);
}
export default OrderSummary;
The answer to that challenge was using wisely the 'fixed' and 'inset-0' tailwind properties. this has fixed the popup to the screen no matter where you're located in the page.
Just a tip for newbies like me - Codepen for front-end can be your best friend.
Check out also Tailwind CSS Docs

Cannot center section within the image in next.js

I'm new to Next.js. I have the HomePage within the pages folder, and I'm trying to center the <h1></h1> in the middle of the picture but instead, it pushes it down. Here is my code...
import image from '../public/images/background.jpg'
import Image from "next/image";
import Layout from "../components/Layout";
export default function HomePage() {
return (
<Layout>
<main>
<Image
src={image}
alt="Programming"
className="absolute object-cover w-full h-full"
/>
<section className="relative flex justify-center min-h-screen pt-12 lg:pt-64 px-8">
<h1 className="text-6xl text-green-100 font-bold cursive leading-none lg:leading-snug home-name">Hi. I'm
Shloimi</h1>
</section>
</main>
</Layout>
)
}
Can someone help me, please. And I'm using Tailwind.css
Try this,
<main className="relative">
<Image
src={image}
alt="Programming"
className="w-full h-full bg-cover"
/>
<h1 className="absolute w-full text-6xl font-bold leading-none text-center text-green-100 top-1/2 transform translate-y-1/2 cursive lg:leading-snug home-name ">
asdf
</h1>
</main>
I deleted pt-12 lg:pt-64 to make your goal and inserted items-center, but if you want to use pt, then you can customise with that values.
Happy coding :)

Resources