Reputation: 1
using the swiper library for a react web app, inside of it i got custom dropdown, the swiper seems to have overflow hidden property and its cutting the dropdownmenu out i don't know if there is a configuration in the swiper to prevent the cutting of the overflow, or changing the styling would do the job
the swiper:
<Swiper
spaceBetween={50}
slidesPerView={1}
onSwiper={(swiper) => {
setSwiperRef(swiper);
}
}
>
<AnimatePresence>
{activeTab === 'information' ? (
<motion.div
initial={{ x: 300, opacity: 0 }}
animate={{ x: 0, opacity: 1 }}
exit={{ x: -300, opacity: 0 }}
transition={{ duration: 0.2 }}
layoutId="information"
className='grid grid-cols-2 gap-5'>
<SwiperSlide>
<div>
<label htmlFor='title' className='block text-sm font-medium text-gray-700'>Title</label>
<input
type='text'
name='title'
id='title'
placeholder='Title...'
value={offer.title ? offer.title : ''}
className='mt-1 p-3 outline-none border border-gray-300 focus:border-primary block w-full bg-gray-100 rounded-lg'
onChange={(e) => setOffer({ ...offer, title: e.target.value })}
/>
</div>
</SwiperSlide>
<SwiperSlide>
<div>
<label htmlFor='description' className='block text-sm font-medium text-gray-700'>Description</label>
<textarea
name='description'
id='description'
placeholder='Description...'
value={offer.description ? offer.description : ''}
className='mt-1 p-3 outline-none border border-gray-300 focus:border-primary block w-full bg-gray-100 rounded-lg'
onChange={(e) => setOffer({ ...offer, description: e.target.value })} />
</div>
</SwiperSlide>
<SwiperSlide>
<div>
<label htmlFor='tags' className='block mb-1 text-sm font-medium text-gray-700'>Tags</label>
<MultiOptionsSelect placeholder='Tags... (search)' value={offer.tags} options={tags} onSelect={handleSelectedOptionsChange} />
</div>
</SwiperSlide>
<SwiperSlide>
<div>
<label htmlFor='location' className='block text-sm font-medium text-gray-700'>Location</label>
<input
type='text'
name='location'
id='location'
placeholder='Location... (e.g. Tunis, la Marsa)'
value={offer.location ? offer.location : ''}
className='mt-1 p-3 outline-none border border-gray-300 focus:border-primary block w-full bg-gray-100 rounded-lg'
onChange={(e) => setOffer({ ...offer, location: e.target.value })}
/>
</div>
</SwiperSlide>
<SwiperSlide>
<div className='space-y-2'>
<div>
<label htmlFor='duration' className='block text-sm font-medium text-gray-700'>Duration</label>
<input
type='string'
name='duration'
id='duration'
placeholder='Duration... (e.g. 3 months)'
value={offer.duration ? offer.duration : ''}
className='mt-1 p-3 outline-none border border-gray-300 focus:border-primary block w-full bg-gray-100 rounded-lg'
onChange={(e) => setOffer({ ...offer, duration: e.target.value })} />
</div>
<div className="flex gap-2">
<div>
<label htmlFor='startdate' className='block text-sm font-medium text-gray-700 mb-1'>Start Date <span className='text-xs text-[#FF7A50]'>(optional)</span></label>
<CustomDateInput placeholder={'Start Date...'} value={offer.startDate} onSelect={handleStartDateSelect} />
</div>
<div>
<label htmlFor='enddate' className='block text-sm font-medium text-gray-700 mb-1'>End Date <span className='text-xs text-[#FF7A50]'>(optional)</span></label>
<CustomDateInput placeholder={'End Date...'} value={offer.endDate} onSelect={handleEndDateSelect} />
</div>
</div>
</div>
</SwiperSlide>
<SwiperSlide>
<div className='flex gap-5'>
<div>
<label htmlFor='spots' className='block text-sm font-medium text-gray-700'>Spots</label>
<input
type='number'
name='spots'
id='spots'
placeholder='Spots...'
value={offer.spots ? offer.spots : null}
className='mt-1 p-3 outline-none border border-gray-300 focus:border-primary block w-full bg-gray-100 rounded-lg'
onChange={(e) => setOffer({ ...offer, spots: Number(e.target.value) })} />
</div>
<div>
<label htmlFor='category' className='block text-sm font-medium text-gray-700 mb-1'>Category</label>
<CustomDropdownMenu placeholder={"Category..."} value={offer.category} options={categories} onSelect={handleCategorySelect} />
</div>
<div>
<label htmlFor='type' className='block text-sm font-medium text-gray-700 mb-1'>Type</label>
<CustomDropdownMenu placeholder={"Type..."} value={offer.type} options={typeOptions} onSelect={handleTypeSelect} />
</div>
<div>
<label htmlFor='payment' className='block text-sm font-medium text-gray-700 mb-1'>Payment</label>
<CustomDropdownMenu placeholder={"Payment..."} value={offer.payment} options={paymentOptions} onSelect={handlePaymentSelect} />
</div>
</div>
</SwiperSlide>
</motion.div>
) : (
<motion.div
initial={{ x: 300, opacity: 0 }}
animate={{ x: 0, opacity: 1 }}
exit={{ x: -300, opacity: 0 }}
transition={{ duration: 0.2 }}
layoutId="options"
className='space-y-5'
>
<div>
<label htmlFor='gender' className='block text-sm font-medium text-gray-700 mb-1'>Gender</label>
<CustomDropdownMenu placeholder={'Eligible Gender for Application'} value={offer.options.gender} options={genderOptions} onSelect={(option) => setOffer({ ...offer, options: { ...offer.options, gender: option } })} />
</div>
<div>
<label htmlFor='states' className='block text-sm font-medium text-gray-700 mb-1'>States</label>
<MultiOptionsSelect
placeholder={'Eligible States for Application'}
value={offer.options.states}
options={statesOptions}
onSelect={(options) => setOffer(prevOffer => {
const newStates = options.filter(option => !prevOffer.options.states.includes(option));
if (newStates.length === 0) {
return prevOffer;
}
return {
...prevOffer,
options: {
...prevOffer.options,
states: [...prevOffer.options.states, ...newStates]
}
};
})}
/>
</div>
<div>
<label htmlFor='expire' className='block text-sm font-medium text-gray-700'>Expires After</label>
<input
type='number'
name='expire'
id='expire'
placeholder='Expires After (hours)... (e.g. 5)'
value={offer.options.expire ? offer.options.expire : null}
className='mt-1 p-3 outline-none border border-gray-300 focus:border-primary block w-full bg-gray-100 rounded-lg'
onChange={(e) => setOffer({ ...offer, options: { ...offer.options, expires: Number(e.target.value) } })}
/>
</div>
</motion.div>
)}
</AnimatePresence>
<div className='flex items-center gap-2 justify-end mt-2'>
<button
onClick={() => swiperRef.slidePrev()}
className='bg-gray-200 p-3 rounded-lg text-[#333333]'>Previous</button>
<button
onClick={() => swiperRef.slideNext()}
className='bg-gray-200 p-3 rounded-lg text-[#333333]'>Next</button>
</div>
</Swiper>
CustomDateInput.js:
import React, { useState, useRef, useEffect } from 'react';
import { motion, AnimatePresence } from 'framer-motion';
import { FiCalendar } from 'react-icons/fi';
import CustomCalendar from '../widgets/CustomCalendar'; // Import the CustomCalendar component
function CustomDateInput({ placeholder, value, onSelect, error }) {
const [isOpen, setIsOpen] = useState(false);
const [selectedDate, setSelectedDate] = useState(value ? value : null);
const dropdownRef = useRef(null);
const toggleDropdown = () => {
setIsOpen(!isOpen);
};
const handleDateChange = (date) => {
setSelectedDate(date);
onSelect(date);
setIsOpen(false);
};
const handleClickOutside = (event) => {
if (dropdownRef.current && !dropdownRef.current.contains(event.target)) {
setIsOpen(false);
}
};
useEffect(() => {
document.addEventListener('mousedown', handleClickOutside);
return () => {
document.removeEventListener('mousedown', handleClickOutside);
};
}, []);
const dropdownVariants = {
hidden: { opacity: 0, y: -20 },
visible: { opacity: 1, y: 0 },
};
return (
<div className="dropdown relative flex items-center w-full gap-2" ref={dropdownRef}>
<input
type="text"
placeholder={placeholder}
value={selectedDate ? selectedDate.toLocaleDateString() : ''}
readOnly
className={`w-full p-3 bg-gray-300/25 border-[1.5px] rounded-lg outline-none focus:border-primary border-gray-300 ${error ? 'border-red-500 bg-red-500/25 text-red-500 placeholder-red-500 animate-shake' : ''}`}
/>
<div>
<div
className="dropdown-toggle bg-primary text-white p-[17px] rounded-lg relative cursor-pointer"
onClick={toggleDropdown}
>
<FiCalendar className={`w-5 transition-all duration-150 ease-in-out`} />
</div>
<AnimatePresence>
{isOpen && (
<motion.div
className="dropdown-menu absolute w-full z-10 mt-2 left-0 max-h-64 overflow-y-auto bg-gray-200 border-[1.5px] rounded-lg outline-none p-1 space-y-2 scrollbar scrollbar-track-slate-300 scrollbar-thumb-slate-600"
variants={dropdownVariants}
initial="hidden"
animate="visible"
exit="hidden"
>
<CustomCalendar onDateChange={handleDateChange} />
</motion.div>
)}
</AnimatePresence>
</div>
</div>
);
}
export default CustomDateInput;
i tried changing the swiper styles but got nowhere, i also tried putting the dropown inside a portal but that only messed up the dropdown
Upvotes: 0
Views: 47