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

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>

Related

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:

Display image after a condition in JSX

I am trying to display an image once the user clicks on Chicken category, I was able to change the colour only.
{categories && categories.map(category => (
<motion.div
whileTap={{scale:0.75}}
key={categories.id} className={`group ${
filter === category.urlParamName}group ${ filter === "chicken"?
'bg-red-500': 'bg-card'} }
w-24 min-w-[94px] h-28 cursor-pointer rounded-lg drop-shadow-xl flex flex-col
gap-3 items-center justify-center hover:bg-cartNumBg`}
onClick={()=> setFilter(category.urlParamName)
} >
You are closing the className's closing bracket before the w-24.
<motion.div
whileTap={{ scale: 0.75 }}
key={categories.id}
className={`group ${filter === category.urlParamName}group ${
filter === "chicken" ? "bg-red-500" : "bg-card"
} w-24 min-w-[94px] h-28 cursor-pointer rounded-lg drop-shadow-xl flex
flex-col gap-3 items-center justify-center hover:bg-cartNumBg`}
onClick={() => setFilter(category.urlParamName)}
/>

Reactjs, tailwind css : Overflow and padding getting automatically added causing scroll lock

So My page looks like below
I have written a logic to open a modal using headlessui on clicking one of the sub hoodie images.
This works perfectly , but after I close it, the scrolling of the page disables and an extra
style="overflow: hidden; padding-right: 16px;"
is getting added to my main html tag.
Below is the reference
How do i stop the modal to automatically apply padding and overflow.
A lot of people have had this problem with bootstrap but i am not able to find this issue resolved in tailwind. Please help
below is the code for my modal
import React from 'react'
import { Dialog, Transition } from '#headlessui/react'
import { Fragment } from 'react'
import {XIcon} from '#heroicons/react/solid'
import {useRecoilState} from 'recoil'
import {openState} from '../../../atoms/modalAtom'
const product = {
name: "Women's Basic Tee",
price: '$32',
rating: 3.9,
reviewCount: 512,
href: '#',
imageSrc: 'https://tailwindui.com/img/ecommerce-images/product-page-01-featured-product-shot.jpg',
imageAlt: "Back of women's Basic Tee in black.",
colors: [
{ name: 'Black', bgColor: 'bg-gray-900', selectedColor: 'ring-gray-900' },
{ name: 'Heather Grey', bgColor: 'bg-gray-400', selectedColor: 'ring-gray-400' },
],
sizes: [
{ name: 'XXS', inStock: true },
{ name: 'XS', inStock: true },
{ name: 'S', inStock: true },
{ name: 'M', inStock: true },
{ name: 'L', inStock: true },
{ name: 'XL', inStock: true },
{ name: 'XXL', inStock: false },
],
}
export function DesignQuickView ({design}) {
const [open, setOpen] = useRecoilState(openState)
return (
<Transition.Root show={open} as={Fragment}>
<Dialog as="div" className="relative z-10" onClose={() => setOpen(false)}>
<Transition.Child
as={Fragment}
enter="ease-out duration-300"
enterFrom="opacity-0"
enterTo="opacity-100"
leave="ease-in duration-200"
leaveFrom="opacity-100"
leaveTo="opacity-0"
>
<div className="hidden fixed inset-0 bg-gray-500 bg-opacity-75 transition-opacity md:block" />
</Transition.Child>
<div className="fixed z-10 inset-0 overflow-y-auto">
<div className="flex items-stretch md:items-center justify-center min-h-full text-center md:px-2 lg:px-4">
{/* This element is to trick the browser into centering the modal contents. */}
<span className="hidden md:inline-block md:align-middle md:h-screen" aria-hidden="true">
​
</span>
<Transition.Child
as={Fragment}
enter="ease-out duration-300"
enterFrom="opacity-0 translate-y-4 md:translate-y-0 md:scale-95"
enterTo="opacity-100 translate-y-0 md:scale-100"
leave="ease-in duration-200"
leaveFrom="opacity-100 translate-y-0 md:scale-100"
leaveTo="opacity-0 translate-y-4 md:translate-y-0 md:scale-95"
>
<Dialog.Panel className="flex text-base text-left transform transition w-full md:max-w-2xl md:px-4 md:my-8 lg:max-w-4xl">
<div className="w-full relative flex items-center bg-white px-4 pt-14 pb-8 overflow-hidden shadow-2xl sm:px-6 sm:pt-8 md:p-6 lg:p-8">
<button
type="button"
className="absolute top-4 right-4 text-gray-400 hover:text-gray-500 sm:top-8 sm:right-6 md:top-6 md:right-6 lg:top-8 lg:right-8"
onClick={() => setOpen(false)}
>
<span className="sr-only">Close</span>
<XIcon className="h-6 w-6" aria-hidden="true" />
</button>
<div className="w-full grid grid-cols-1 gap-y-8 gap-x-6 items-start sm:grid-cols-12 lg:items-center lg:gap-x-8">
<div className="aspect-w-3 aspect-h-4 rounded-lg bg-gray-100 overflow-hidden sm:col-span-4 lg:col-span-5">
<img src={design.url} alt={design.name} className="object-center object-cover" />
</div>
<div className="sm:col-span-8 lg:col-span-7">
<h2 className="text-xl font-medium text-gray-900 sm:pr-12">Hoodie</h2>
<section aria-labelledby="information-heading" className="mt-1">
<h3 id="information-heading" className="sr-only">
Product information
</h3>
<p className="font-medium text-gray-900">{product.price}</p>
</section>
<section aria-labelledby="options-heading" className="mt-8">
<h3 id="options-heading" className="sr-only">
Product options
</h3>
<form>
{/* Color picker */}
<div>
<h4 className="text-sm font-medium text-gray-900">Color</h4>
{/* <RadioGroup value={selectedColor} onChange={setSelectedColor} className="mt-2">
<RadioGroup.Label className="sr-only">Choose a color</RadioGroup.Label>
<div className="flex items-center space-x-3">
{product.colors.map((color) => (
<RadioGroup.Option
key={color.name}
value={color}
className={({ active, checked }) =>
classNames(
color.selectedColor,
active && checked ? 'ring ring-offset-1' : '',
!active && checked ? 'ring-2' : '',
'-m-0.5 relative p-0.5 rounded-full flex items-center justify-center cursor-pointer focus:outline-none'
)
}
>
<RadioGroup.Label as="span" className="sr-only">
{color.name}
</RadioGroup.Label>
<span
aria-hidden="true"
className={classNames(
color.bgColor,
'h-8 w-8 border border-black border-opacity-10 rounded-full'
)}
/>
</RadioGroup.Option>
))}
</div>
</RadioGroup> */}
</div>
{/* Size picker */}
<div className="mt-8">
<div className="flex items-center justify-between">
<h4 className="text-sm font-medium text-gray-900">Size</h4>
<a href="#" className="text-sm font-medium text-indigo-600 hover:text-indigo-500">
Size guide
</a>
</div>
{/* <RadioGroup value={selectedSize} onChange={setSelectedSize} className="mt-2">
<RadioGroup.Label className="sr-only">Choose a size</RadioGroup.Label>
<div className="grid grid-cols-7 gap-2">
{product.sizes.map((size) => (
<RadioGroup.Option
key={size.name}
value={size}
className={({ active, checked }) =>
classNames(
size.inStock
? 'cursor-pointer focus:outline-none'
: 'opacity-25 cursor-not-allowed',
active ? 'ring-2 ring-offset-2 ring-indigo-500' : '',
checked
? 'bg-indigo-600 border-transparent text-white hover:bg-indigo-700'
: 'bg-white border-gray-200 text-gray-900 hover:bg-gray-50',
'border rounded-md py-3 px-3 flex items-center justify-center text-sm font-medium uppercase sm:flex-1'
)
}
disabled={!size.inStock}
>
<RadioGroup.Label as="span">{size.name}</RadioGroup.Label>
</RadioGroup.Option>
))}
</div>
</RadioGroup> */}
</div>
</form>
</section>
</div>
</div>
</div>
</Dialog.Panel>
</Transition.Child>
</div>
</div>
</Dialog>
</Transition.Root>
)
}
export default DesignQuickView
In the closeModal function, you can override the style of the html tag:
function closeModal() {
setOpen(false);
setTimeout(() => {
const html = document.body.parentNode as HTMLElement | null;
html.classList.add('modal_close');
}, 50);
}
function openModal() {
setOpen(true);
const html = document.body.parentNode as HTMLElement | null;
html.classList.remove('modal_close');
}
<Dialog as="div" className="relative z-10" onClose={closeModal}><
<button
type="button"
className="absolute top-4 right-4 text-gray-400 hover:text-gray-500 sm:top-8 sm:right-6 md:top-6 md:right-6 lg:top-8 lg:right-8"
onClick={closeModal}
>
style.css
.modal_close {
overflow: auto !important;
padding-right: 0px !important;
}

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