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:
Fredrik Thorsson
2025-03-18 09:44:17 +00:00
parent f096b70c45
commit d4fe8baa49
3 changed files with 22 additions and 6 deletions

View File

@@ -22,6 +22,7 @@ function Carousel({
children,
scrollToIdx = 0,
align = "start",
onScrollSelect,
}: CarouselProps) {
const [carouselRef, api] = useEmblaCarousel(
{
@@ -34,10 +35,14 @@ function Carousel({
)
const [selectedIndex, setSelectedIndex] = useState(scrollToIdx)
const onSelect = useCallback((api: CarouselApi) => {
if (!api) return
setSelectedIndex(api.selectedScrollSnap())
}, [])
const onSelect = useCallback(
(api: CarouselApi) => {
if (!api) return
setSelectedIndex(api.selectedScrollSnap())
onScrollSelect?.(api.selectedScrollSnap())
},
[onScrollSelect]
)
function scrollPrev() {
api?.scrollPrev()

View File

@@ -16,7 +16,7 @@ export interface CarouselProps extends PropsWithChildren {
plugins?: CarouselPlugin
setApi?: (api: CarouselApi) => void
className?: string
handleScrollSelected?: (idx: number) => void
onScrollSelect?: (idx: number) => void
scrollToIdx?: number
align?: "start" | "center"
}

View File

@@ -1,6 +1,7 @@
"use client"
import { cx } from "class-variance-authority"
import { useCallback } from "react"
import { useDestinationPageHotelsMapStore } from "@/stores/destination-page-hotels-map"
@@ -18,18 +19,28 @@ interface MapCardCarouselProps {
export default function HotelCardCarousel({
visibleHotels,
}: MapCardCarouselProps) {
const { activeHotel } = useDestinationPageHotelsMapStore()
const { activeHotel, setActiveHotel } = useDestinationPageHotelsMapStore()
const selectedHotelIdx = visibleHotels.findIndex(
({ hotel }) => hotel.operaId === activeHotel
)
const handleScrollSelect = useCallback(
(idx: number) => {
if (selectedHotelIdx !== -1) {
setActiveHotel(visibleHotels[idx]?.hotel.operaId)
}
},
[setActiveHotel, visibleHotels, selectedHotelIdx]
)
return (
<Carousel
className={styles.carousel}
scrollToIdx={selectedHotelIdx}
align="center"
opts={{ containScroll: false }}
onScrollSelect={handleScrollSelect}
>
<Carousel.Content className={styles.carouselContent}>
{visibleHotels.map(({ hotel, url }) => (