fix: refactor GuestRoomsPicker to avoid performance bugs

This commit is contained in:
Arvid Norlin
2024-11-12 13:34:42 +01:00
committed by Christel Westerberg
parent 3e62df27cc
commit 58678244fc
5 changed files with 158 additions and 225 deletions

View File

@@ -1,6 +1,7 @@
"use client"
import { useCallback, useEffect, useRef, useState } from "react"
import { Button, DialogTrigger, Popover } from "react-aria-components"
import { useFormContext } from "react-hook-form"
import { useIntl } from "react-intl"
@@ -9,7 +10,7 @@ import { useGuestsRoomsStore } from "@/stores/guests-rooms"
import { guestRoomsSchema } from "@/components/Forms/BookingWidget/schema"
import Body from "@/components/TempDesignSystem/Text/Body"
import GuestsRoomsPicker from "./GuestsRoomsPicker"
import Dialog from "./Dialog"
import styles from "./guests-rooms-picker.module.css"
@@ -19,47 +20,16 @@ export default function GuestsRoomsPickerForm({
name: string
}) {
const intl = useIntl()
const [isOpen, setIsOpen] = useState(false)
const { setValue } = useFormContext()
const { rooms, adultCount, childCount, setIsValidated } = useGuestsRoomsStore(
(state) => ({
rooms: state.rooms,
adultCount: state.adultCount,
childCount: state.childCount,
setIsValidated: state.setIsValidated,
})
)
const ref = useRef<HTMLDivElement | null>(null)
function handleOnClick() {
setIsOpen((prevIsOpen) => !prevIsOpen)
}
const closePicker = useCallback(() => {
const guestRoomsValidData = guestRoomsSchema.safeParse(rooms)
if (guestRoomsValidData.success) {
setIsOpen(false)
setIsValidated(false)
setValue(name, guestRoomsValidData.data, { shouldValidate: true })
} else {
setIsValidated(true)
}
}, [rooms, name, setValue, setIsValidated, setIsOpen])
useEffect(() => {
function handleClickOutside(evt: Event) {
const target = evt.target as HTMLElement
if (ref.current && target && !ref.current.contains(target)) {
closePicker()
}
}
document.addEventListener("click", handleClickOutside)
return () => {
document.removeEventListener("click", handleClickOutside)
}
}, [closePicker])
const { rooms, adultCount, childCount } = useGuestsRoomsStore((state) => ({
rooms: state.rooms,
adultCount: state.adultCount,
childCount: state.childCount,
}))
return (
<div className={styles.container} data-isopen={isOpen} ref={ref}>
<button className={styles.btn} onClick={handleOnClick} type="button">
<DialogTrigger>
<Button className={styles.btn} type="button">
<Body className={styles.body} asChild>
<span>
{intl.formatMessage(
@@ -80,10 +50,10 @@ export default function GuestsRoomsPickerForm({
: null}
</span>
</Body>
</button>
<div aria-modal className={styles.hideWrapper} role="dialog">
<GuestsRoomsPicker closePicker={closePicker} />
</div>
</div>
</Button>
<Popover>
<Dialog />
</Popover>
</DialogTrigger>
)
}