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, 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()

View File

@@ -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"
} }

View File

@@ -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 }) => (