onClick events not rendering in NEXTJS - reactjs

I have a contact button in my header I want it to render a modal when clicked. I create state variables for the click event and imported a modal component into my header file. I've tried making a handleClick function for the onClick event as well as don't it without this as you will see. I can't quite see why I can't get it working. I've googled the sh*t out of this with nothing seems to help.
header file:
import React, { useEffect, useState } from "react";
import { Link as LinkScroll } from "react-scroll";
import ButtonOutline from "../misc/ButtonOutline";
import Modal from "../Modal";
const Header = () => {
const [modalOpen, setModalOpen] = useState(false);
const [activeLink, setActiveLink] = useState(null);
const [scrollActive, setScrollActive] = useState(false);
useEffect(() => {
window.addEventListener("scroll", () => {
setScrollActive(window.scrollY > 20);
});
}, []);
return (
<>
<header
className={
"fixed top-0 w-full z-30 bg-white-500 transition-all " +
(scrollActive ? " shadow-md pt-0" : " pt-4")
}
>
<nav className="max-w-screen-xl px-6 sm:px-8 lg:px-16 mx-auto grid grid-flow-col py-3 sm:py-4">
<div className="col-start-1 col-end-2 flex items-center">
<h1 className="h-8 w-auto text-2xl font-Amatic text-black-500 hover:text-green-500 cursor-pointer">
Soul Amiga
</h1>
</div>
<ul className="hidden lg:flex col-start-4 col-end-8 text-black-500 items-center">
<LinkScroll
activeClass="active"
to="home"
spy={true}
smooth={true}
duration={1000}
onSetActive={() => {
setActiveLink("home");
}}
className={
"px-4 py-2 mx-2 cursor-pointer animation-hover inline-block relative" +
(activeLink === "home"
? " text-green-500 animation-active "
: " text-black-500 hover:text-green-500 ")
}
>
Home
</LinkScroll>
<LinkScroll
activeClass="active"
to="about"
spy={true}
smooth={true}
duration={1000}
onSetActive={() => {
setActiveLink("about");
}}
className={
"px-4 py-2 mx-2 cursor-pointer animation-hover inline-block relative" +
(activeLink === "about"
? " text-green-500 animation-active "
: " text-black-500 hover:text-green-500 ")
}
>
About
</LinkScroll>
<LinkScroll
activeClass="active"
to="mywork"
spy={true}
smooth={true}
duration={1000}
onSetActive={() => {
setActiveLink("mywork");
}}
className={
"px-4 py-2 mx-2 cursor-pointer animation-hover inline-block relative" +
(activeLink === "mywork"
? " text-green-500 animation-active "
: " text-black-500 hover:text-green-500 ")
}
>
My Work
</LinkScroll>
<LinkScroll
activeClass="active"
to="blog"
spy={true}
smooth={true}
duration={1000}
onSetActive={() => {
setActiveLink("blog");
}}
className={
"px-4 py-2 mx-2 cursor-pointer animation-hover inline-block relative" +
(activeLink === "blog"
? " text-green-500 animation-active "
: " text-black-500 hover:text-green-500 ")
}
>
Blog
</LinkScroll>
</ul>
<div className="col-start-10 col-end-12 font-medium flex justify-end items-center">
<ButtonOutline
onClick={() => {
setModalOpen(true);
}}
>
Contact
</ButtonOutline>
<Modal open={modalOpen} />
</div>
</nav>
</header>
{/* Mobile Navigation */}
<nav className="fixed lg:hidden bottom-0 left-0 right-0 z-20 px-4 sm:px-8 shadow-t ">
<div className="bg-white-500 sm:px-3">
<ul className="flex w-full justify-between items-center text-black-500">
<LinkScroll
activeClass="active"
to="home"
spy={true}
smooth={true}
duration={1000}
onSetActive={() => {
setActiveLink("home");
}}
className={
"mx-1 sm:mx-2 px-3 sm:px-4 py-2 flex flex-col items-center text-xs border-t-2 transition-all " +
(activeLink === "home"
? " border-green-500 text-green-500"
: " border-transparent")
}
>
<svg
className="w-6 h-6"
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth={2}
d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"
/>
</svg>
Home
</LinkScroll>
<LinkScroll
activeClass="active"
to="about"
spy={true}
smooth={true}
duration={1000}
onSetActive={() => {
setActiveLink("about");
}}
className={
"mx-1 sm:mx-2 px-3 sm:px-4 py-2 flex flex-col items-center text-xs border-t-2 transition-all " +
(activeLink === "about"
? " border-green-500 text-green-500"
: " border-transparent ")
}
>
<svg
className="w-6 h-6"
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth={2}
d="M21 12a9 9 0 01-9 9m9-9a9 9 0 00-9-9m9 9H3m9 9a9 9 0 01-9-9m9 9c1.657 0 3-4.03 3-9s-1.343-9-3-9m0 18c-1.657 0-3-4.03-3-9s1.343-9 3-9m-9 9a9 9 0 019-9"
/>
</svg>
About
</LinkScroll>
<LinkScroll
activeClass="active"
to="mywork"
spy={true}
smooth={true}
duration={1000}
onSetActive={() => {
setActiveLink("mywork");
}}
className={
"mx-1 sm:mx-2 px-3 sm:px-4 py-2 flex flex-col items-center text-xs border-t-2 transition-all " +
(activeLink === "mywork"
? " border-green-500 text-green-500"
: " border-transparent ")
}
>
<svg
className="w-6 h-6"
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth={2}
d="M12 8c-1.657 0-3 .895-3 2s1.343 2 3 2 3 .895 3 2-1.343 2-3 2m0-8c1.11 0 2.08.402 2.599 1M12 8V7m0 1v8m0 0v1m0-1c-1.11 0-2.08-.402-2.599-1M21 12a9 9 0 11-18 0 9 9 0 0118 0z"
/>
</svg>
My Work
</LinkScroll>
<LinkScroll
activeClass="active"
to="blog"
spy={true}
smooth={true}
duration={1000}
onSetActive={() => {
setActiveLink("blog");
}}
className={
"mx-1 sm:mx-2 px-3 sm:px-4 py-2 flex flex-col items-center text-xs border-t-2 transition-all " +
(activeLink === "blog"
? " border-green-500 text-green-500"
: " border-transparent ")
}
>
<svg
className="w-6 h-6"
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth={2}
d="M8 12h.01M12 12h.01M16 12h.01M21 12c0 4.418-4.03 8-9 8a9.863 9.863 0 01-4.255-.949L3 20l1.395-3.72C3.512 15.042 3 13.574 3 12c0-4.418 4.03-8 9-8s9 3.582 9 8z"
/>
</svg>
Blog
</LinkScroll>
</ul>
</div>
</nav>
{/* End Mobile Navigation */}
</>
);
};
export default Header;
modal file:
import React from "react";
import ButtonPrimary from "./misc/ButtonPrimary";
function Modal({ open }) {
if (!open) return null;
return (
<div className="modalBackground">
<div className="modalContainer">
<button> X </button>
<div className="title">
<h1>Soul Amiga</h1>
</div>
<div className="body">
<p>Name</p>
<p>Email</p>
<textarea />
</div>
<div className="footer">
<ButtonPrimary text="Send" />
</div>
</div>
</div>
);
}
export default Modal;

Related

HeadlessUI's select keeps invisible but opened, how to fix it?

I'm using the headless UI's select to choose a dev name, when I open it and I choose the option sometimes he keeps opened but insivible, then I need to click again in some option to actually close the select.
Here's the code:
<div>
<Listbox value={selected} onChange={setSelected}>
<div className=" mt-1 z-40">
<Listbox.Button className="relative w-full cursor-pointer rounded-lg bg-base-200 border-none text-left sm:text-sm">
<span className="block truncate">{selected}</span>
</Listbox.Button>
<Transition
as={Fragment}
leave="transition ease-in duration-100"
leaveFrom="opacity-100"
leaveTo="opacity-0"
>
<Listbox.Options className="mt-1 z-40 max-h-60 absolute px-4 box-border w-1/6 overflow-auto rounded-md bg-base-300 py-1 text-base shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none sm:text-sm">
{arrayDevs?.map((newDev: string) => (
<Listbox.Option
onClick={() => updateTaskDev(newDev)}
key={newDev}
className={({ active }) =>
`relative cursor-default select-none py-2 pl-2 pr-4 rounded-lg list-none ${
active ? "bg-primary text-white" : "text-base-content"
}`
}
value={newDev}
>
{({ selected }) => (
<>
<span
className={`block truncate ${
selected ? "font-medium" : "font-normal"
}`}
>
{newDev}
</span>
</>
)}
</Listbox.Option>
))}
</Listbox.Options>
</Transition>
</div>
</Listbox>
</div>

how to add react responsive carousel swipe animation

I'm using next JS with tailwind css and using react-responsive-carousel package.the issue that i'm having is that when i start to swipe the images they're next to each other horizontally. they have no effect (like fade or ease in out) to them while swiping. and i wanted to make animation transition with ease-in-out or fade to it. how can i add fade in out animation instead of its default slide?
<Carousel
swipeScrollTolerance={100}
preventMovementUntilSwipeScrollTolerance
key={house.id}
axis="horizontal"
showStatus={false}
showThumbs={false}
swipeable={true}
className="group "
renderIndicator={(onClickHandler, isSelected, index, label) => {
const defStyle = {
marginLeft: 6,
color: "#b9b9b9",
cursor: "pointer",
};
const style = isSelected
? { ...defStyle, color: "#dcdcdc" }
: { ...defStyle };
return (
<span
style={style}
onClick={onClickHandler}
onKeyDown={onClickHandler}
value={index}
key={index}
role="button"
tabIndex={0}
aria-label={`${label} ${index + 1}`}
>
<FontAwesomeIcon
icon={faCircle}
className="sm:h-[0.35rem] sm:w-[0.35rem] h-2 w-2 font-thin"
/>
</span>
);
}}
renderArrowPrev={(clickHandler, hasPrev) => {
return (
<div
className={`${
hasPrev && !toggle ? "absolute" : "hidden"
} top-0 bottom-0 left-0 flex justify-center items-center p-3 opacity-0 group-hover:opacity-70 cursor-pointer z-10 text-white`}
onClick={clickHandler}
>
<FontAwesomeIcon
icon={faChevronCircleLeft}
className="h-8 w-8 font-thin"
/>
</div>
);
}}
renderArrowNext={(clickHandler, hasNext) => {
return (
<div
className={`${
hasNext && !toggle ? "absolute" : "hidden"
} top-0 bottom-0 right-0 flex justify-center items-center p-3 opacity-0 group-hover:opacity-70 cursor-pointerz-10 text-white`}
onClick={clickHandler}
>
<FontAwesomeIcon
icon={faChevronCircleRight}
className="h-8 w-8 font-thin"
/>
</div>
);
}}
>
{house.img.map((img, index) => {
return (
<Link href={`/living/${house.id}`} key={img.id}>
<div
key={img.id}
className=" w-full relative -z-10 pt-[100%] cursor-pointer"
>
<Image
src={img.img}
alt="profile"
fill
className="w-full h-full top-0 left-0 -z-10 object-cover rounded-2xl ease-in-out duration-200"
/>
</div>
</Link>
);
})}
</Carousel>

Child Dropdown component Value to Parent Form

I have a page /enroll where there is a select dropdown menu, which is another component:
const roles = [
{ id: 1, name: 'Business Analyst' },
{ id: 2, name: 'Data Analyst' },
{ id: 3, name: 'Quality Assurance Analyst' },
{ id: 4, name: 'UI/UX Designer' },
]
const Dropdown = () => {
const [selected, setSelected] = useState(people[0])
return (
<Listbox value={selected} onChange={setSelected}>
{({ open }) => (
<>
<Listbox.Label className="block text-sm font-medium text-gray-700">Interested Role</Listbox.Label>
<div className="relative mt-1">
<Listbox.Button className="relative w-full cursor-default rounded-md border border-gray-300 bg-white py-2 pl-3 pr-10 text-left shadow-sm focus:border-indigo-500 focus:outline-none focus:ring-1 focus:ring-indigo-500 sm:text-sm">
<span className="block truncate">{selected.name}</span>
<span className="pointer-events-none absolute inset-y-0 right-0 flex items-center pr-2">
<ChevronUpDownIcon className="h-5 w-5 text-gray-400" aria-hidden="true" />
</span>
</Listbox.Button>
<Transition
show={open}
as={Fragment}
leave="transition ease-in duration-100"
leaveFrom="opacity-100"
leaveTo="opacity-0"
>
<Listbox.Options className="absolute z-10 mt-1 max-h-60 w-full overflow-auto rounded-md bg-white py-1 text-base shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none sm:text-sm">
{people.map((person) => (
<Listbox.Option
key={person.id}
className={({ active }) =>
classNames(
active ? 'text-white bg-indigo-600' : 'text-gray-900',
'relative cursor-default select-none py-2 pl-3 pr-9'
)
}
value={person}
>
{({ selected, active }) => (
<>
<span className={classNames(selected ? 'font-semibold' : 'font-normal', 'block truncate')}>
{person.name}
</span>
{selected ? (
<span
className={classNames(
active ? 'text-white' : 'text-indigo-600',
'absolute inset-y-0 right-0 flex items-center pr-4'
)}
>
<CheckIcon className="h-5 w-5" aria-hidden="true" />
</span>
) : null}
</>
)}
</Listbox.Option>
))}
</Listbox.Options>
</Transition>
</div>
</>
)}
</Listbox>
)
}
export default Dropdown
I need the value of the selected option on the enroll page. This is how the component is being called on the /enroll page:
<div className="">
<Dropdown />
</div>
How do I know what value was selected in the dropdown?
P.S. Next.js is used here.
This is what the /enroll page form looks like:

NextJS Image component is overlapping other components regardless of z-index

Stack: NextJS, JavaScript, React, Tailwind, Framer Motion
I've scoured the web for answers to this but mostly the answers were saying that the <div> that wraps the image must have a position of relative. I tried this and it didn't change anything.
Code for the text and images:
import React from "react";
import { motion } from "framer-motion";
import Image from "next/image";
export default function Card({ image, name, description }) {
return (
<motion.div
className="flex justify-center mt-5"
initial="hidden"
animate="visible"
variants={{
hidden: { scale: 0.9, opacity: 0 },
visible: {
scale: 1,
opacity: 1,
transition: { delay: 0.3, ease: [0.17, 0.67, 0.83, 0.67] },
},
}}
>
<div className="relative">
<Image
className="rounded-full absolute"
src={image}
width={100}
height={100}
alt="Leader profile picture"
/>
</div>
<div>
<motion.h1
className="text-xl pl-1 font-bourton"
initial="hidden"
animate="visible"
variants={{
hidden: { scale: 0.9, opacity: 0 },
visible: {
scale: 1,
opacity: 1,
transition: { delay: 0.35, ease: [0.17, 0.67, 0.83, 0.67] },
},
}}
>
{name}
</motion.h1>
<motion.p className="text-sm p-3 text-wrap w-48 text-slate-600 font-bourton">
{description}
</motion.p>
</div>
</motion.div>
);
}
The code for the sidebar:
import { useState } from "react";
import { motion } from "framer-motion";
import classnames from "classnames";
import { useRouter } from "next/router";
const path01Variants = {
open: { d: "M3.06061 2.99999L21.0606 21" },
closed: { d: "M0 9.5L24 9.5" },
};
const path02Variants = {
open: { d: "M3.00006 21.0607L21 3.06064" },
moving: { d: "M0 14.5L24 14.5" },
closed: { d: "M0 14.5L15 14.5" },
};
const Sidebar = () => {
const [showSidebar, setShowSidebar] = useState(false);
const [animation, setAnimation] = useState("closed");
const router = useRouter();
const onClick = () => {
setAnimation("moving");
setTimeout(() => {
setAnimation(animation === "closed" ? "open" : "closed");
}, 200);
setShowSidebar(!showSidebar);
};
return (
<>
{showSidebar ? (
<button
className="flex justify-center relative z-100 items-center w-12 h-12 border border-black rounded-full"
onClick={onClick}
>
<svg width="24" height="24" viewBox="0 0 24 24">
<motion.path
stroke="#fff"
animate={animation}
variants={path01Variants}
/>
<motion.path
stroke="#fff"
animate={animation}
variants={path02Variants}
/>
</svg>
</button>
) : (
<button
className="flex justify-center top-12 right-12 items-center w-12 h-12 border border-black rounded-full"
onClick={onClick}
>
<svg width="24" height="24" viewBox="0 0 24 24">
<motion.path
stroke="#000"
animate={animation}
variants={path01Variants}
/>
<motion.path
stroke="#000"
animate={animation}
variants={path02Variants}
/>
</svg>
</button>
)}
<div
className={` bg-unionred border-black opacity-90 top-0 right-0 lg:w-[35vw] sm:w-[50vw] p-10 pl-20 fixed text-white h-full ease-in-out duration-300 ${
showSidebar ? "translate-x-0" : "translate-x-full"
}`}
>
<button
className="flex justify-center absolute top-8 right-8 items-center w-12 h-12 border border-white rounded-full"
onClick={onClick}
>
<svg width="24" height="24" viewBox="0 0 24 24">
<motion.path
stroke="#fff"
animate={animation}
variants={path01Variants}
/>
<motion.path
stroke="#fff"
animate={animation}
variants={path02Variants}
/>
</svg>
</button>
<h3 className="mt-20 text-4xl underline font-bourton text-white">
<button className="underline" onClick={() => router.push("whoweare")}>
Who We Are
</button>
</h3>
<h3 className="mt-20 text-4xl font-bourton text-white">
<button
className="underline"
onClick={() => router.push("ourleaders")}
>
Our Leaders
</button>
</h3>
<h3 className="mt-20 text-4xl font-bourton text-white">
<button className="underline">News</button>
</h3>
</div>
</>
);
};
export default Sidebar;
Before opening sidebar
After opening sidebar
Any help would be appreciated! Thank you.
It looks like you're not applying a z-index to the sidebar itself. That <div> is the container that needs to overlap the main content, so that is where you need to add the utility class.
Additionally, it looks like you're trying to use z-100 which is not one of the Tailwind defaults (see: https://tailwindcss.com/docs/z-index). You can either add that new value to your tailwind.config.js or try z-50, which is the highest default.
For example:
<div className={`z-50 bg-unionred border-black opacity-90 top-0 right-0 lg:w-[35vw] sm:w-[50vw] p-10 pl-20 fixed text-white h-full ease-in-out duration-300 ${showSidebar ? "translate-x-0" : "translate-x-full"}`}>

Navbar conditional rendering

So im currently trying to figure out how I can change the state of a button depending on wether I'm on the page or not.
I have this navbar:
import { Fragment } from 'react'
import { Disclosure, Menu, Transition } from '#headlessui/react'
import { BellIcon, MenuIcon, XIcon } from '#heroicons/react/outline'
import { PlusSmIcon } from '#heroicons/react/solid'
const user = {
name: 'Tom Cook',
email: 'tom#example.com',
imageUrl:
'https://images.unsplash.com/photo-1472099645785-5658abf4ff4e?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=facearea&facepad=2&w=256&h=256&q=80',
}
const navigation = [
{ name: 'Home', href: '/', current: true },
{ name: 'Dashboard', href: '/dashboard', current: false },
{ name: 'Price', href: '/price', current: false },
]
const userNavigation = [
{ name: 'Your Profile', href: '/profile' },
{ name: 'Settings', href: '#' },
{ name: 'Sign out', href: '#' },
]
function classNames(...classes) {
return classes.filter(Boolean).join(' ')
}
export default function Navbar() {
return (
<Disclosure as="nav" className="bg-gray-800">
{({ open }) => (
<>
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div className="flex justify-between h-16">
<div className="flex">
<div className="-ml-2 mr-2 flex items-center md:hidden">
{/* Mobile menu button */}
<Disclosure.Button className="inline-flex items-center justify-center p-2 rounded-md text-gray-400 hover:text-white hover:bg-gray-700 focus:outline-none focus:ring-2 focus:ring-inset focus:ring-white">
<span className="sr-only">Open main menu</span>
{open ? (
<XIcon className="block h-6 w-6" aria-hidden="true" />
) : (
<MenuIcon className="block h-6 w-6" aria-hidden="true" />
)}
</Disclosure.Button>
</div>
<div className="flex-shrink-0 flex items-center">
<img
className="block lg:hidden h-8 w-auto"
src="Assets/img/logo-light.png"
alt="Nemondo"
/>
<img
className="hidden lg:block h-8 w-auto"
src="Assets/img/logo-light.png"
alt="Nemondo"
/>
</div>
<div className="hidden md:ml-6 md:flex md:items-center md:space-x-4">
{navigation.map((item) => (
<a
key={item.name}
href={item.href}
className={classNames(
item.current ? 'bg-gray-900 text-white' : 'text-gray-300 hover:bg-gray-700 hover:text-white',
'px-3 py-2 rounded-md text-sm font-medium'
)}
aria-current={item.current ? 'page' : undefined}
>
{item.name}
</a>
))}
</div>
</div>
<div className="flex items-center">
<div className="flex-shrink-0">
<button
type="button"
className="relative inline-flex items-center px-4 py-2 border border-transparent shadow-sm text-sm font-medium rounded-md text-white bg-indigo-500 hover:bg-indigo-600 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-offset-gray-800 focus:ring-indigo-500"
>
<PlusSmIcon className="-ml-1 mr-2 h-5 w-5" aria-hidden="true" />
<span>New Job</span>
</button>
</div>
<div className="hidden md:ml-4 md:flex-shrink-0 md:flex md:items-center">
<button
type="button"
className="bg-gray-800 p-1 rounded-full text-gray-400 hover:text-white focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-offset-gray-800 focus:ring-white"
>
<span className="sr-only">View notifications</span>
<BellIcon className="h-6 w-6" aria-hidden="true" />
</button>
{/* Profile dropdown */}
<Menu as="div" className="ml-3 relative">
<div>
<Menu.Button className="bg-gray-800 flex text-sm rounded-full focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-offset-gray-800 focus:ring-white">
<span className="sr-only">Open user menu</span>
<img className="h-8 w-8 rounded-full" src={user.imageUrl} alt="" />
</Menu.Button>
</div>
<Transition
as={Fragment}
enter="transition ease-out duration-200"
enterFrom="transform opacity-0 scale-95"
enterTo="transform opacity-100 scale-100"
leave="transition ease-in duration-75"
leaveFrom="transform opacity-100 scale-100"
leaveTo="transform opacity-0 scale-95"
>
<Menu.Items className="origin-top-right absolute right-0 mt-2 w-48 rounded-md shadow-lg py-1 bg-white ring-1 ring-black ring-opacity-5 focus:outline-none z-10">
{userNavigation.map((item) => (
<Menu.Item key={item.name}>
{({ active }) => (
<a
href={item.href}
className={classNames(
active ? 'bg-gray-100' : '',
'block px-4 py-2 text-sm text-gray-700'
)}
>
{item.name}
</a>
)}
</Menu.Item>
))}
</Menu.Items>
</Transition>
</Menu>
</div>
</div>
</div>
</div>
<Disclosure.Panel className="md:hidden">
<div className="px-2 pt-2 pb-3 space-y-1 sm:px-3">
{navigation.map((item) => (
<Disclosure.Button
key={item.name}
as="a"
href={item.href}
className={classNames(
item.current ? 'bg-gray-900 text-white' : 'text-gray-300 hover:bg-gray-700 hover:text-white',
'block px-3 py-2 rounded-md text-base font-medium'
)}
aria-current={item.current ? 'page' : undefined}
>
{item.name}
</Disclosure.Button>
))}
</div>
<div className="pt-4 pb-3 border-t border-gray-700">
<div className="flex items-center px-5 sm:px-6">
<div className="flex-shrink-0">
<img className="h-10 w-10 rounded-full" src={user.imageUrl} alt="" />
</div>
<div className="ml-3">
<div className="text-base font-medium text-white">{user.name}</div>
<div className="text-sm font-medium text-gray-400">{user.email}</div>
</div>
<button
type="button"
className="ml-auto flex-shrink-0 bg-gray-800 p-1 rounded-full text-gray-400 hover:text-white focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-offset-gray-800 focus:ring-white"
>
<span className="sr-only">View notifications</span>
<BellIcon className="h-6 w-6" aria-hidden="true" />
</button>
</div>
<div className="mt-3 px-2 space-y-1 sm:px-3">
{userNavigation.map((item) => (
<Disclosure.Button
key={item.name}
as="a"
href={item.href}
className="block px-3 py-2 rounded-md text-base font-medium text-gray-400 hover:text-white hover:bg-gray-700"
>
{item.name}
</Disclosure.Button>
))}
</div>
</div>
</Disclosure.Panel>
</>
)}
</Disclosure>
)
}
It seems that when I change the current:
const navigation = [
{ name: 'Home', href: '/', current: true },
{ name: 'Dashboard', href: '/dashboard', current: false },
{ name: 'Price', href: '/price', current: false },
From true to false and vice versa it does exactly what I need, but how can I make it so it changes depending on whether I'm on the page or not?
Thanks in advance.
codesandbox: https://codesandbox.io/s/navbar-react-router-dom-v6-p8vy4b
It is not styled very good. The conditional check of current route look like this:
import { useLocation } from "react-router-dom";
const Navbar = () => {
const location = useLocation();
const navigation = [
{
name: "Root",
href: "/"
},
{
name: "Home",
href: "/home"
},
{
name: "About",
href: "/about"
}
];
return (
<navbar
style={{
display: "flex",
height: "50px",
backgroundColor: "red",
width: "100vw"
}}
>
{navigation.map((nav, idx) => {
const isActiveRoute = location.pathname === nav.href;
// const isActiveRoute = location.pathname.startsWith(nav.href) // or if you want a prefix instead
return (
<a
key={idx}
href={nav.href}
style={{ padding: "0 25px", color: isActiveRoute && "black" }}
>
<h3>{nav.name}</h3>
</a>
);
})}
</navbar>
);
};
export default Navbar;
and the routing :
import "./styles.css";
import { BrowserRouter, Routes, Route } from "react-router-dom";
import Navbar from "./Navbar";
export default function App() {
const wrapNavbar = (item) => {
return (
<>
<Navbar />
{item}
<p>note: black navbar color is the active item</p>
</>
);
};
return (
<BrowserRouter>
<Routes>
<Route path="/" element={wrapNavbar(<h1>this is root </h1>)} />
<Route path="/home" element={wrapNavbar(<h1>this is home </h1>)} />
<Route path="/about" element={wrapNavbar(<h1>this is about </h1>)} />
</Routes>
</BrowserRouter>
);
}

Resources