From b41aab56a684b668ec22655d487d628a532928bd Mon Sep 17 00:00:00 2001 From: Erik Tiekstra Date: Wed, 26 Nov 2025 07:40:12 +0000 Subject: [PATCH] feat(BOOK-101): Added functionality to show active map card when focus is within the hotel card Approved-by: Bianca Widstam --- .../lib/components/HotelCardListing/index.tsx | 2 ++ .../HotelCard/HotelCard.stories.tsx | 2 ++ .../lib/components/HotelCard/index.tsx | 32 +++++++++++++++++-- packages/design-system/package.json | 1 + yarn.lock | 1 + 5 files changed, 35 insertions(+), 3 deletions(-) diff --git a/packages/booking-flow/lib/components/HotelCardListing/index.tsx b/packages/booking-flow/lib/components/HotelCardListing/index.tsx index 1a2842c12..affa384ce 100644 --- a/packages/booking-flow/lib/components/HotelCardListing/index.tsx +++ b/packages/booking-flow/lib/components/HotelCardListing/index.tsx @@ -221,6 +221,8 @@ export default function HotelCardListing({ ), } } + onFocusIn={() => engage(hotel.hotel.name)} + onFocusOut={() => disengage()} onHover={() => engage(hotel.hotel.name)} onHoverEnd={() => disengage()} onAddressClick={() => { diff --git a/packages/design-system/lib/components/HotelCard/HotelCard.stories.tsx b/packages/design-system/lib/components/HotelCard/HotelCard.stories.tsx index ec8a15fa6..d6db9656f 100644 --- a/packages/design-system/lib/components/HotelCard/HotelCard.stories.tsx +++ b/packages/design-system/lib/components/HotelCard/HotelCard.stories.tsx @@ -88,6 +88,8 @@ export const Default: Story = { onAddressClick: fn, onHover: fn, onHoverEnd: fn, + onFocusIn: fn, + onFocusOut: fn, }, } diff --git a/packages/design-system/lib/components/HotelCard/index.tsx b/packages/design-system/lib/components/HotelCard/index.tsx index 0255947ff..7fbe10fb3 100644 --- a/packages/design-system/lib/components/HotelCard/index.tsx +++ b/packages/design-system/lib/components/HotelCard/index.tsx @@ -2,7 +2,8 @@ import { cx } from 'class-variance-authority' import { type ReadonlyURLSearchParams, useSearchParams } from 'next/navigation' -import { memo } from 'react' +import { memo, useState } from 'react' +import { useFocusWithin } from 'react-aria' import { useIntl } from 'react-intl' import { @@ -116,6 +117,8 @@ export type HotelCardProps = { onHover: () => void onHoverEnd: () => void + onFocusIn: () => void + onFocusOut: () => void onAddressClick: () => void } @@ -139,8 +142,18 @@ export const HotelCard = memo( onAddressClick, onHover, onHoverEnd, + onFocusIn, + onFocusOut, }: HotelCardProps) => { const searchParams = useSearchParams() + const [isFocusWithin, setIsFocusWithin] = useState(false) + const { focusWithinProps } = useFocusWithin({ + onFocusWithin: onFocusIn, + onBlurWithin: onFocusOut, + onFocusWithinChange: (isFocusWithin) => { + setIsFocusWithin(isFocusWithin) + }, + }) const intl = useIntl() @@ -174,11 +187,24 @@ export const HotelCard = memo( prices?.member?.rateType === RateTypeEnum.PublicPromotion const showBookingCodeChip = bookingCode || isCampaign + function onMouseEnter() { + if (!isFocusWithin) { + onHover() + } + } + + function onMouseLeave() { + if (!isFocusWithin) { + onHoverEnd() + } + } + return (
onHover()} - onMouseLeave={() => onHoverEnd()} + onMouseEnter={onMouseEnter} + onMouseLeave={onMouseLeave} >
diff --git a/packages/design-system/package.json b/packages/design-system/package.json index 8d4d6d74c..1570a69dc 100644 --- a/packages/design-system/package.json +++ b/packages/design-system/package.json @@ -234,6 +234,7 @@ "@vis.gl/react-google-maps": "^1.5.2", "next": "^15", "react": "^19.1.0", + "react-aria": "^3.39.0", "react-aria-components": "^1.8.0", "react-dom": "^19.1.0", "react-hook-form": "^7.56.2", diff --git a/yarn.lock b/yarn.lock index 233f1c6a4..83982f76e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5169,6 +5169,7 @@ __metadata: "@vis.gl/react-google-maps": ^1.5.2 next: ^15 react: ^19.1.0 + react-aria: ^3.39.0 react-aria-components: ^1.8.0 react-dom: ^19.1.0 react-hook-form: ^7.56.2