Browse Source
🛠️ Implemented SectionSliderNewCategories component
🛠️ Implemented SectionSliderNewCategories component
🚧 Added a new component for displaying category sliders 📦 Included necessary imports and configurations 🌟 Ready to enhance and style the component further 🚀 Initial commit for SectionSliderNewCategoriesmain
John Doe
1 year ago
1 changed files with 234 additions and 0 deletions
@ -0,0 +1,234 @@ |
|||||
|
"use client"; |
||||
|
|
||||
|
import React, { FC, useEffect, useState } from "react"; |
||||
|
import { TaxonomyType } from "@/data/types"; |
||||
|
import CardCategory3 from "@/components/CardCategory3"; |
||||
|
import CardCategory4 from "@/components/CardCategory4"; |
||||
|
import CardCategory5 from "@/components/CardCategory5"; |
||||
|
import Heading from "@/shared/Heading"; |
||||
|
import { AnimatePresence, motion, MotionConfig } from "framer-motion"; |
||||
|
import { useSwipeable } from "react-swipeable"; |
||||
|
import PrevBtn from "./PrevBtn"; |
||||
|
import NextBtn from "./NextBtn"; |
||||
|
import { variants } from "@/utils/animationVariants"; |
||||
|
import { useWindowSize } from "react-use"; |
||||
|
|
||||
|
export interface SectionSliderNewCategoriesProps { |
||||
|
className?: string; |
||||
|
itemClassName?: string; |
||||
|
heading?: string; |
||||
|
subHeading?: string; |
||||
|
categories?: TaxonomyType[]; |
||||
|
categoryCardType?: "card3" | "card4" | "card5"; |
||||
|
itemPerRow?: 4 | 5; |
||||
|
sliderStyle?: "style1" | "style2"; |
||||
|
} |
||||
|
|
||||
|
const DEMO_CATS: TaxonomyType[] = [ |
||||
|
{ |
||||
|
id: "1", |
||||
|
href: "/listing-stay-map", |
||||
|
name: "Nature House", |
||||
|
taxonomy: "category", |
||||
|
count: 17288, |
||||
|
thumbnail: |
||||
|
"https://images.pexels.com/photos/2581922/pexels-photo-2581922.jpeg?auto=compress&cs=tinysrgb&dpr=3&h=750&w=1260", |
||||
|
}, |
||||
|
{ |
||||
|
id: "2", |
||||
|
href: "/listing-stay-map", |
||||
|
name: "Wooden house", |
||||
|
taxonomy: "category", |
||||
|
count: 2118, |
||||
|
thumbnail: |
||||
|
"https://images.pexels.com/photos/2351649/pexels-photo-2351649.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=750&w=1260", |
||||
|
}, |
||||
|
{ |
||||
|
id: "3", |
||||
|
href: "/listing-stay-map", |
||||
|
name: "Houseboat", |
||||
|
taxonomy: "category", |
||||
|
count: 36612, |
||||
|
thumbnail: |
||||
|
"https://images.pexels.com/photos/962464/pexels-photo-962464.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=750&w=1260", |
||||
|
}, |
||||
|
{ |
||||
|
id: "4", |
||||
|
href: "/listing-stay-map", |
||||
|
name: "Farm House", |
||||
|
taxonomy: "category", |
||||
|
count: 18188, |
||||
|
thumbnail: |
||||
|
"https://images.pexels.com/photos/248837/pexels-photo-248837.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=750&w=1260", |
||||
|
}, |
||||
|
{ |
||||
|
id: "5", |
||||
|
href: "/listing-stay-map", |
||||
|
name: "Dome House", |
||||
|
taxonomy: "category", |
||||
|
count: 22288, |
||||
|
thumbnail: |
||||
|
"https://images.pexels.com/photos/3613236/pexels-photo-3613236.jpeg?auto=compress&cs=tinysrgb&dpr=1&w=500", |
||||
|
}, |
||||
|
{ |
||||
|
id: "6", |
||||
|
href: "/listing-stay-map", |
||||
|
name: "Dome House", |
||||
|
taxonomy: "category", |
||||
|
count: 188288, |
||||
|
thumbnail: |
||||
|
"https://images.pexels.com/photos/14534337/pexels-photo-14534337.jpeg?auto=compress&cs=tinysrgb&w=1600&lazy=load", |
||||
|
}, |
||||
|
{ |
||||
|
id: "7", |
||||
|
href: "/listing-stay-map", |
||||
|
name: "Wooden house", |
||||
|
taxonomy: "category", |
||||
|
count: 2118, |
||||
|
thumbnail: |
||||
|
"https://images.pexels.com/photos/2351649/pexels-photo-2351649.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=750&w=1260", |
||||
|
}, |
||||
|
{ |
||||
|
id: "8", |
||||
|
href: "/listing-stay-map", |
||||
|
name: "Wooden Dome", |
||||
|
taxonomy: "category", |
||||
|
count: 515, |
||||
|
thumbnail: |
||||
|
"https://images.pexels.com/photos/9039238/pexels-photo-9039238.jpeg?auto=compress&cs=tinysrgb&w=1600&lazy=load", |
||||
|
}, |
||||
|
]; |
||||
|
|
||||
|
const SectionSliderNewCategories: FC<SectionSliderNewCategoriesProps> = ({ |
||||
|
heading = "Suggestions for discovery", |
||||
|
subHeading = "Popular places to recommends for you", |
||||
|
className = "", |
||||
|
itemClassName = "", |
||||
|
categories = DEMO_CATS, |
||||
|
itemPerRow = 5, |
||||
|
categoryCardType = "card3", |
||||
|
sliderStyle = "style1", |
||||
|
}) => { |
||||
|
const [currentIndex, setCurrentIndex] = useState(0); |
||||
|
const [direction, setDirection] = useState(0); |
||||
|
const [numberOfItems, setNumberOfitem] = useState(0); |
||||
|
|
||||
|
const windowWidth = useWindowSize().width; |
||||
|
useEffect(() => { |
||||
|
if (windowWidth < 320) { |
||||
|
return setNumberOfitem(1); |
||||
|
} |
||||
|
if (windowWidth < 500) { |
||||
|
return setNumberOfitem(itemPerRow - 3); |
||||
|
} |
||||
|
if (windowWidth < 1024) { |
||||
|
return setNumberOfitem(itemPerRow - 2); |
||||
|
} |
||||
|
if (windowWidth < 1280) { |
||||
|
return setNumberOfitem(itemPerRow - 1); |
||||
|
} |
||||
|
|
||||
|
setNumberOfitem(itemPerRow); |
||||
|
}, [itemPerRow, windowWidth]); |
||||
|
|
||||
|
function changeItemId(newVal: number) { |
||||
|
if (newVal > currentIndex) { |
||||
|
setDirection(1); |
||||
|
} else { |
||||
|
setDirection(-1); |
||||
|
} |
||||
|
setCurrentIndex(newVal); |
||||
|
} |
||||
|
|
||||
|
const handlers = useSwipeable({ |
||||
|
onSwipedLeft: () => { |
||||
|
if (currentIndex < categories?.length - 1) { |
||||
|
changeItemId(currentIndex + 1); |
||||
|
} |
||||
|
}, |
||||
|
onSwipedRight: () => { |
||||
|
if (currentIndex > 0) { |
||||
|
changeItemId(currentIndex - 1); |
||||
|
} |
||||
|
}, |
||||
|
trackMouse: true, |
||||
|
}); |
||||
|
|
||||
|
const renderCard = (item: TaxonomyType) => { |
||||
|
switch (categoryCardType) { |
||||
|
case "card3": |
||||
|
return <CardCategory3 taxonomy={item} />; |
||||
|
case "card4": |
||||
|
return <CardCategory4 taxonomy={item} />; |
||||
|
case "card5": |
||||
|
return <CardCategory5 taxonomy={item} />; |
||||
|
default: |
||||
|
return <CardCategory3 taxonomy={item} />; |
||||
|
} |
||||
|
}; |
||||
|
|
||||
|
if (!numberOfItems) return null; |
||||
|
|
||||
|
return ( |
||||
|
<div className={`nc-SectionSliderNewCategories ${className}`}> |
||||
|
<Heading desc={subHeading} isCenter={sliderStyle === "style2"}> |
||||
|
{heading} |
||||
|
</Heading> |
||||
|
<MotionConfig |
||||
|
transition={{ |
||||
|
x: { type: "spring", stiffness: 300, damping: 30 }, |
||||
|
opacity: { duration: 0.2 }, |
||||
|
}} |
||||
|
> |
||||
|
<div className={`relative flow-root`} {...handlers}> |
||||
|
<div className={`flow-root overflow-hidden rounded-xl`}> |
||||
|
<motion.ul |
||||
|
initial={false} |
||||
|
className="relative whitespace-nowrap -mx-2 xl:-mx-4" |
||||
|
> |
||||
|
<AnimatePresence initial={false} custom={direction}> |
||||
|
{categories.map((item, indx) => ( |
||||
|
<motion.li |
||||
|
className={`relative inline-block px-2 xl:px-4 ${itemClassName}`} |
||||
|
custom={direction} |
||||
|
initial={{ |
||||
|
x: `${(currentIndex - 1) * -100}%`, |
||||
|
}} |
||||
|
animate={{ |
||||
|
x: `${currentIndex * -100}%`, |
||||
|
}} |
||||
|
variants={variants(200, 1)} |
||||
|
key={indx} |
||||
|
style={{ |
||||
|
width: `calc(1/${numberOfItems} * 100%)`, |
||||
|
}} |
||||
|
> |
||||
|
{renderCard(item)} |
||||
|
</motion.li> |
||||
|
))} |
||||
|
</AnimatePresence> |
||||
|
</motion.ul> |
||||
|
</div> |
||||
|
|
||||
|
{currentIndex ? ( |
||||
|
<PrevBtn |
||||
|
style={{ transform: "translate3d(0, 0, 0)" }} |
||||
|
onClick={() => changeItemId(currentIndex - 1)} |
||||
|
className="w-9 h-9 xl:w-12 xl:h-12 text-lg absolute -left-3 xl:-left-6 top-1/3 -translate-y-1/2 z-[1]" |
||||
|
/> |
||||
|
) : null} |
||||
|
|
||||
|
{categories.length > currentIndex + numberOfItems ? ( |
||||
|
<NextBtn |
||||
|
style={{ transform: "translate3d(0, 0, 0)" }} |
||||
|
onClick={() => changeItemId(currentIndex + 1)} |
||||
|
className="w-9 h-9 xl:w-12 xl:h-12 text-lg absolute -right-3 xl:-right-6 top-1/3 -translate-y-1/2 z-[1]" |
||||
|
/> |
||||
|
) : null} |
||||
|
</div> |
||||
|
</MotionConfig> |
||||
|
</div> |
||||
|
); |
||||
|
}; |
||||
|
|
||||
|
export default SectionSliderNewCategories; |
Write
Preview
Loading…
Cancel
Save
Reference in new issue