Merged in feat/SW-1899-destination-city-mobile-map-active-pins (pull request #1557)
feat(SW-1899): active hotel pin on carousel scroll * feat(SW-1899): active hotel pin on carousel scroll Approved-by: Erik Tiekstra
This commit is contained in:
@@ -22,6 +22,7 @@ function Carousel({
|
|||||||
children,
|
children,
|
||||||
scrollToIdx = 0,
|
scrollToIdx = 0,
|
||||||
align = "start",
|
align = "start",
|
||||||
|
onScrollSelect,
|
||||||
}: CarouselProps) {
|
}: CarouselProps) {
|
||||||
const [carouselRef, api] = useEmblaCarousel(
|
const [carouselRef, api] = useEmblaCarousel(
|
||||||
{
|
{
|
||||||
@@ -34,10 +35,14 @@ function Carousel({
|
|||||||
)
|
)
|
||||||
const [selectedIndex, setSelectedIndex] = useState(scrollToIdx)
|
const [selectedIndex, setSelectedIndex] = useState(scrollToIdx)
|
||||||
|
|
||||||
const onSelect = useCallback((api: CarouselApi) => {
|
const onSelect = useCallback(
|
||||||
if (!api) return
|
(api: CarouselApi) => {
|
||||||
setSelectedIndex(api.selectedScrollSnap())
|
if (!api) return
|
||||||
}, [])
|
setSelectedIndex(api.selectedScrollSnap())
|
||||||
|
onScrollSelect?.(api.selectedScrollSnap())
|
||||||
|
},
|
||||||
|
[onScrollSelect]
|
||||||
|
)
|
||||||
|
|
||||||
function scrollPrev() {
|
function scrollPrev() {
|
||||||
api?.scrollPrev()
|
api?.scrollPrev()
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ export interface CarouselProps extends PropsWithChildren {
|
|||||||
plugins?: CarouselPlugin
|
plugins?: CarouselPlugin
|
||||||
setApi?: (api: CarouselApi) => void
|
setApi?: (api: CarouselApi) => void
|
||||||
className?: string
|
className?: string
|
||||||
handleScrollSelected?: (idx: number) => void
|
onScrollSelect?: (idx: number) => void
|
||||||
scrollToIdx?: number
|
scrollToIdx?: number
|
||||||
align?: "start" | "center"
|
align?: "start" | "center"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
"use client"
|
"use client"
|
||||||
|
|
||||||
import { cx } from "class-variance-authority"
|
import { cx } from "class-variance-authority"
|
||||||
|
import { useCallback } from "react"
|
||||||
|
|
||||||
import { useDestinationPageHotelsMapStore } from "@/stores/destination-page-hotels-map"
|
import { useDestinationPageHotelsMapStore } from "@/stores/destination-page-hotels-map"
|
||||||
|
|
||||||
@@ -18,18 +19,28 @@ interface MapCardCarouselProps {
|
|||||||
export default function HotelCardCarousel({
|
export default function HotelCardCarousel({
|
||||||
visibleHotels,
|
visibleHotels,
|
||||||
}: MapCardCarouselProps) {
|
}: MapCardCarouselProps) {
|
||||||
const { activeHotel } = useDestinationPageHotelsMapStore()
|
const { activeHotel, setActiveHotel } = useDestinationPageHotelsMapStore()
|
||||||
|
|
||||||
const selectedHotelIdx = visibleHotels.findIndex(
|
const selectedHotelIdx = visibleHotels.findIndex(
|
||||||
({ hotel }) => hotel.operaId === activeHotel
|
({ hotel }) => hotel.operaId === activeHotel
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const handleScrollSelect = useCallback(
|
||||||
|
(idx: number) => {
|
||||||
|
if (selectedHotelIdx !== -1) {
|
||||||
|
setActiveHotel(visibleHotels[idx]?.hotel.operaId)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[setActiveHotel, visibleHotels, selectedHotelIdx]
|
||||||
|
)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Carousel
|
<Carousel
|
||||||
className={styles.carousel}
|
className={styles.carousel}
|
||||||
scrollToIdx={selectedHotelIdx}
|
scrollToIdx={selectedHotelIdx}
|
||||||
align="center"
|
align="center"
|
||||||
opts={{ containScroll: false }}
|
opts={{ containScroll: false }}
|
||||||
|
onScrollSelect={handleScrollSelect}
|
||||||
>
|
>
|
||||||
<Carousel.Content className={styles.carouselContent}>
|
<Carousel.Content className={styles.carouselContent}>
|
||||||
{visibleHotels.map(({ hotel, url }) => (
|
{visibleHotels.map(({ hotel, url }) => (
|
||||||
|
|||||||
Reference in New Issue
Block a user