Merged in fix/book-149-ui-fixes (pull request #3463)

Fix/book 149 ui fixes

* fixed text-overflow issue in datepicker trigger

* fixed X missing in booking code text field

* fixed toDate not setting properly

* fixed spacing issues and placeholder text not fitting

* added error message to child age if none is added

* spacing fixes

* Revert "map link alignment fix"

This reverts commit d38cc5b007bc05a1d48ce6661b1052fe714961c3.

* fixed EB points padding issue on SAS tablet

* maxWidth on BookingCode/voucher

* spacing fixes

* fixed icons in error message

* spacing fixes

* scroll to child age picker updates

* feat(SW-3706): fix heatmap issue for langswitcher and booking widget

* fixed tablet lineup issue


Approved-by: Linus Flood
This commit is contained in:
Matilda Haneling
2026-01-22 12:50:24 +00:00
parent f79ff9b570
commit 665ca210c0
19 changed files with 129 additions and 41 deletions

View File

@@ -30,6 +30,7 @@ type ChildInfoSelectorProps = {
index: number
roomIndex: number
childrenInAdultsBed: number
scrollToRef?: React.Ref<HTMLDivElement>
}
export default function ChildInfoSelector({
@@ -38,6 +39,7 @@ export default function ChildInfoSelector({
adults,
index = 0,
roomIndex = 0,
scrollToRef,
}: ChildInfoSelectorProps) {
const ageSelectRef = useRef<HTMLDivElement>(null)
const bedPrefSelectRef = useRef<HTMLDivElement>(null)
@@ -84,8 +86,11 @@ export default function ChildInfoSelector({
defaultMessage: "Child age is required",
})
const { setValue, formState } = useFormContext()
const { setValue, formState, watch } = useFormContext()
const selectedAgeValue = watch(
`rooms.${roomIndex}.childrenInRoom.${index}.age`
)
function updateSelectedBed(bed: number) {
setValue(`rooms.${roomIndex}.childrenInRoom.${index}.bed`, bed)
}
@@ -140,10 +145,16 @@ export default function ChildInfoSelector({
const ageError = roomErrors?.age
const bedError = roomErrors?.bed
const isInvalid =
!!ageError ||
!!bedError ||
selectedAgeValue === undefined ||
selectedAgeValue === null ||
selectedAgeValue === -1
return (
<>
<div key={index} className={styles.childInfoContainer}>
<div key={index} ref={scrollToRef} className={styles.childInfoContainer}>
<div ref={ageSelectRef}>
<Select
items={ageList}
@@ -152,9 +163,13 @@ export default function ChildInfoSelector({
onSelectionChange={(key) => {
updateSelectedAge(key as number)
}}
isRequired
popoverWidth={`${ageWidth}px`}
value={child.age ?? childDefaultValues.age}
isInvalid={!!ageError}
isInvalid={
(!!ageError || selectedAgeValue === undefined) ??
childDefaultValues.age === -1
}
/>
</div>
<div ref={bedPrefSelectRef}>
@@ -186,7 +201,7 @@ export default function ChildInfoSelector({
</Typography>
) : null}
{ageError || bedError ? (
{isInvalid ? (
<>
<Typography
variant="Body/Supporting text (caption)/smRegular"

View File

@@ -1,6 +1,6 @@
"use client"
import { useRef } from "react"
import { useCallback, useEffect, useRef } from "react"
import { useFormContext } from "react-hook-form"
import { useIntl } from "react-intl"
@@ -18,20 +18,25 @@ type ChildSelectorProps = {
currentAdults: number
currentChildren: Child[]
childrenInAdultsBed: number
containerRef?: React.RefObject<HTMLDivElement | null>
roomsDividerRef?: React.RefObject<HTMLDivElement | null>
}
export default function ChildSelector({
roomIndex = 0,
currentAdults,
childrenInAdultsBed,
currentChildren,
containerRef,
}: ChildSelectorProps) {
const intl = useIntl()
const childRefs = useRef<(HTMLDivElement | null)[]>([])
const previousChildCount = useRef(currentChildren.length)
const childrenLabel = intl.formatMessage({
id: "bookingwidget.dropdown.children",
defaultMessage: "Children (012 years)",
})
const { setValue } = useFormContext()
const agePickerRef = useRef<HTMLDivElement | null>(null)
function increaseChildrenCount(roomIndex: number) {
if (currentChildren.length < 5) {
@@ -53,6 +58,35 @@ export default function ChildSelector({
})
}
}
const scrollToAgePicker = useCallback(() => {
if (!containerRef?.current) return
const lastChildIndex = currentChildren.length - 1
const lastChild = childRefs.current[lastChildIndex]
if (!lastChild) return
const container = containerRef.current
const containerRect = container.getBoundingClientRect()
const targetRect = lastChild.getBoundingClientRect()
const targetOffset =
targetRect.top - containerRect.top + container.scrollTop
const centerOffset = containerRect.height / 2 - targetRect.height / 2
container.scrollTo({
top: targetOffset - centerOffset,
behavior: "smooth",
})
}, [containerRef, currentChildren.length])
useEffect(() => {
// Only scroll when a child was added
if (currentChildren.length > previousChildCount.current) {
scrollToAgePicker()
}
previousChildCount.current = currentChildren.length
}, [currentChildren.length, scrollToAgePicker])
return (
<>
@@ -71,19 +105,13 @@ export default function ChildSelector({
decreaseChildrenCount(roomIndex)
}}
handleOnIncrease={() => {
requestAnimationFrame(() => {
agePickerRef.current?.scrollIntoView({
behavior: "smooth",
block: "center",
})
})
increaseChildrenCount(roomIndex)
}}
disableDecrease={currentChildren.length == 0}
disableIncrease={currentChildren.length == 5}
/>
</section>
<span ref={agePickerRef} />
{currentChildren.map((child, index) => (
<ChildInfoSelector
roomIndex={roomIndex}
@@ -92,6 +120,9 @@ export default function ChildSelector({
adults={currentAdults}
key={"child_" + index}
childrenInAdultsBed={childrenInAdultsBed}
scrollToRef={(el) => {
childRefs.current[index] = el
}}
/>
))}
</>