Merged in fix/book-149-datepicker-overflowing (pull request #3433)

Fix/optimizations and cleanup of booking widget

* fix(BOOK-149):fixed issue with datepicker overflowing on months spanning more weeks

* fix(BOOK-149): added smooth scroll to age selector to avoid clipping the selector

* cleanup in trigger and css

* update to new Button componenet to fix missing focus indicator

* included color token in triggerbutton class instead


Approved-by: Bianca Widstam
Approved-by: Erik Tiekstra
This commit is contained in:
Matilda Haneling
2026-01-15 11:00:31 +00:00
parent 16fbdb7ae0
commit 4b67ffa7fd
5 changed files with 33 additions and 34 deletions

View File

@@ -58,7 +58,7 @@
box-shadow: var(--popup-box-shadow); box-shadow: var(--popup-box-shadow);
padding: var(--Space-x2) var(--Space-x3); padding: var(--Space-x2) var(--Space-x3);
max-width: calc(100vw - 20px); max-width: calc(100vw - 20px);
max-height: 440px; min-height: 440px;
top: calc(100% + 36px); top: calc(100% + 36px);
left: auto; left: auto;
right: auto; right: auto;

View File

@@ -1,5 +1,6 @@
"use client" "use client"
import { useRef } from "react"
import { useFormContext } from "react-hook-form" import { useFormContext } from "react-hook-form"
import { useIntl } from "react-intl" import { useIntl } from "react-intl"
@@ -30,6 +31,7 @@ export default function ChildSelector({
defaultMessage: "Children (012 years)", defaultMessage: "Children (012 years)",
}) })
const { setValue } = useFormContext() const { setValue } = useFormContext()
const agePickerRef = useRef<HTMLDivElement | null>(null)
function increaseChildrenCount(roomIndex: number) { function increaseChildrenCount(roomIndex: number) {
if (currentChildren.length < 5) { if (currentChildren.length < 5) {
@@ -67,12 +69,19 @@ export default function ChildSelector({
decreaseChildrenCount(roomIndex) decreaseChildrenCount(roomIndex)
}} }}
handleOnIncrease={() => { handleOnIncrease={() => {
requestAnimationFrame(() => {
agePickerRef.current?.scrollIntoView({
behavior: "smooth",
block: "center",
})
})
increaseChildrenCount(roomIndex) increaseChildrenCount(roomIndex)
}} }}
disableDecrease={currentChildren.length == 0} disableDecrease={currentChildren.length == 0}
disableIncrease={currentChildren.length == 5} disableIncrease={currentChildren.length == 5}
/> />
</section> </section>
<span ref={agePickerRef} />
{currentChildren.map((child, index) => ( {currentChildren.map((child, index) => (
<ChildInfoSelector <ChildInfoSelector
roomIndex={roomIndex} roomIndex={roomIndex}

View File

@@ -1,8 +1,8 @@
import { useIntl } from "react-intl" import { useIntl } from "react-intl"
import { Button } from "@scandic-hotels/design-system/Button"
import { Divider } from "@scandic-hotels/design-system/Divider" import { Divider } from "@scandic-hotels/design-system/Divider"
import { MaterialIcon } from "@scandic-hotels/design-system/Icons/MaterialIcon" import { MaterialIcon } from "@scandic-hotels/design-system/Icons/MaterialIcon"
import { OldDSButton as Button } from "@scandic-hotels/design-system/OldDSButton"
import { Typography } from "@scandic-hotels/design-system/Typography" import { Typography } from "@scandic-hotels/design-system/Typography"
import { ChildBedMapEnum } from "@scandic-hotels/trpc/enums/childBedMapEnum" import { ChildBedMapEnum } from "@scandic-hotels/trpc/enums/childBedMapEnum"
@@ -52,13 +52,12 @@ export function GuestsRoom({
/> />
{index !== 0 && ( {index !== 0 && (
<Button <Button
intent="text" variant="Text"
variant="icon"
wrapping
theme="secondaryLight"
onPress={() => onRemove(index)} onPress={() => onRemove(index)}
size="small" size="sm"
color="Primary"
className={styles.roomActionsButton} className={styles.roomActionsButton}
wrapping
> >
<MaterialIcon icon="delete" color="CurrentColor" /> <MaterialIcon icon="delete" color="CurrentColor" />
{intl.formatMessage({ {intl.formatMessage({

View File

@@ -38,7 +38,7 @@
margin-bottom: var(--Space-x1); margin-bottom: var(--Space-x1);
} }
.btn { .triggerButton {
background: none; background: none;
border: none; border: none;
color: var(--Text-Default); color: var(--Text-Default);
@@ -54,9 +54,9 @@
right: 0; right: 0;
padding: 20px var(--Space-x15) 0; padding: 20px var(--Space-x15) 0;
border-radius: var(--Corner-radius-lg); border-radius: var(--Corner-radius-lg);
} display: block;
overflow: hidden;
.guestsAndRooms { text-overflow: ellipsis;
color: var(--Text-Default); color: var(--Text-Default);
} }
@@ -207,12 +207,6 @@
overflow-y: visible; overflow-y: visible;
} }
.trigger > span {
display: block;
overflow: hidden;
text-overflow: ellipsis;
}
.pickerContainer:focus-visible { .pickerContainer:focus-visible {
outline: none; outline: none;
} }

View File

@@ -2,7 +2,7 @@
import { useCallback, useEffect, useRef, useState } from "react" import { useCallback, useEffect, useRef, useState } from "react"
import { FocusScope, useOverlay } from "react-aria" import { FocusScope, useOverlay } from "react-aria"
import { Button } from "react-aria-components" import { Button as ButtonRAC } from "react-aria-components"
import { useFormContext, useWatch } from "react-hook-form" import { useFormContext, useWatch } from "react-hook-form"
import { useIntl } from "react-intl" import { useIntl } from "react-intl"
import { useMediaQuery } from "usehooks-ts" import { useMediaQuery } from "usehooks-ts"
@@ -148,8 +148,7 @@ export default function GuestsRoomsPickerForm({
<div className={styles.container}> <div className={styles.container}>
<Trigger <Trigger
rooms={rooms} rooms={rooms}
className={styles.trigger} onPress={() => {
triggerFn={() => {
setIsOpen((prev) => !prev) setIsOpen((prev) => !prev)
if (!isDesktop && !isOpen) { if (!isDesktop && !isOpen) {
lockScroll() lockScroll()
@@ -197,13 +196,11 @@ export default function GuestsRoomsPickerForm({
function Trigger({ function Trigger({
rooms, rooms,
className, onPress,
triggerFn,
ariaLabelledBy, ariaLabelledBy,
}: { }: {
rooms: GuestsRoom[] rooms: GuestsRoom[]
className: string onPress?: () => void
triggerFn?: () => void
ariaLabelledBy?: string ariaLabelledBy?: string
}) { }) {
const intl = useIntl() const intl = useIntl()
@@ -244,15 +241,15 @@ function Trigger({
} }
return ( return (
<Button <Typography variant="Body/Paragraph/mdRegular">
className={`${className} ${styles.btn}`} <ButtonRAC
className={styles.triggerButton}
type="button" type="button"
onPress={triggerFn} onPress={onPress}
aria-labelledby={ariaLabelledBy} aria-labelledby={ariaLabelledBy}
> >
<Typography variant="Body/Paragraph/mdRegular"> {parts.join(", ")}
<span className={styles.guestsAndRooms}>{parts.join(", ")}</span> </ButtonRAC>
</Typography> </Typography>
</Button>
) )
} }