iMeMPlayZ
iMeMPlayZ

Reputation: 1

How to prevent the overflow hidden in react swiper

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

Answers (0)

Related Questions