fix: added event listener to scroll when transition ends
This commit is contained in:
@@ -35,9 +35,6 @@ export default function SectionAccordion({
|
|||||||
const noBreakfastTitle = intl.formatMessage({ id: "No breakfast" })
|
const noBreakfastTitle = intl.formatMessage({ id: "No breakfast" })
|
||||||
const breakfastTitle = intl.formatMessage({ id: "Breakfast buffet" })
|
const breakfastTitle = intl.formatMessage({ id: "Breakfast buffet" })
|
||||||
|
|
||||||
const accordionRef = useRef<HTMLDivElement>(null)
|
|
||||||
const [scope, animate] = useAnimate()
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (step === StepEnum.selectBed && bedType) {
|
if (step === StepEnum.selectBed && bedType) {
|
||||||
setTitle(bedType.description)
|
setTitle(bedType.description)
|
||||||
@@ -60,49 +57,6 @@ export default function SectionAccordion({
|
|||||||
setIsOpen(currentStep === step)
|
setIsOpen(currentStep === step)
|
||||||
}, [currentStep, setIsOpen, step])
|
}, [currentStep, setIsOpen, step])
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (!accordionRef.current) return
|
|
||||||
|
|
||||||
const animateAccordion = async () => {
|
|
||||||
// Measure the initial position of the accordion
|
|
||||||
const initialOffset = accordionRef.current?.offsetTop || 0
|
|
||||||
|
|
||||||
// Start the accordion expansion animation
|
|
||||||
const accordionAnimation = animate(
|
|
||||||
scope.current,
|
|
||||||
{
|
|
||||||
gridTemplateRows: isOpen
|
|
||||||
? "var(--header-height) 1fr"
|
|
||||||
: "var(--header-height) 0fr",
|
|
||||||
},
|
|
||||||
{ duration: 0.3, ease: "easeInOut" }
|
|
||||||
)
|
|
||||||
|
|
||||||
if (isOpen) {
|
|
||||||
// Start scrolling immediately
|
|
||||||
const scrollAnimation = animate(
|
|
||||||
window.scrollY,
|
|
||||||
initialOffset - 100, // 100px offset from top
|
|
||||||
{
|
|
||||||
duration: 0.3,
|
|
||||||
ease: "easeInOut",
|
|
||||||
onUpdate: (latest) => {
|
|
||||||
window.scrollTo(0, latest)
|
|
||||||
},
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
// Wait for both animations to complete
|
|
||||||
await Promise.all([accordionAnimation, scrollAnimation])
|
|
||||||
} else {
|
|
||||||
// If closing, just wait for the accordion animation
|
|
||||||
await accordionAnimation
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
animateAccordion()
|
|
||||||
}, [isOpen, scope, animate])
|
|
||||||
|
|
||||||
function onModify() {
|
function onModify() {
|
||||||
navigate(step)
|
navigate(step)
|
||||||
}
|
}
|
||||||
@@ -110,13 +64,7 @@ export default function SectionAccordion({
|
|||||||
const textColor =
|
const textColor =
|
||||||
isComplete || isOpen ? "uiTextHighContrast" : "baseTextDisabled"
|
isComplete || isOpen ? "uiTextHighContrast" : "baseTextDisabled"
|
||||||
return (
|
return (
|
||||||
<motion.div
|
<div className={styles.accordion} data-open={isOpen} data-step={step}>
|
||||||
className={styles.accordion}
|
|
||||||
data-open={isOpen}
|
|
||||||
data-step={step}
|
|
||||||
ref={scope}
|
|
||||||
transition={{ duration: 0.3, ease: "easeOut" }}
|
|
||||||
>
|
|
||||||
<div className={styles.iconWrapper}>
|
<div className={styles.iconWrapper}>
|
||||||
<div className={styles.circle} data-checked={isComplete}>
|
<div className={styles.circle} data-checked={isComplete}>
|
||||||
{isComplete ? (
|
{isComplete ? (
|
||||||
@@ -124,7 +72,7 @@ export default function SectionAccordion({
|
|||||||
) : null}
|
) : null}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<header className={styles.header} ref={accordionRef}>
|
<header className={styles.header}>
|
||||||
<button
|
<button
|
||||||
onClick={onModify}
|
onClick={onModify}
|
||||||
disabled={!isComplete}
|
disabled={!isComplete}
|
||||||
@@ -151,6 +99,6 @@ export default function SectionAccordion({
|
|||||||
<div className={styles.content}>
|
<div className={styles.content}>
|
||||||
<div className={styles.contentWrapper}>{children}</div>
|
<div className={styles.contentWrapper}>{children}</div>
|
||||||
</div>
|
</div>
|
||||||
</motion.div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
gap: var(--Spacing-x3);
|
gap: var(--Spacing-x3);
|
||||||
width: 100%;
|
width: 100%;
|
||||||
padding-top: var(--Spacing-x3);
|
padding-top: var(--Spacing-x3);
|
||||||
/* transition: 0.4s ease-out; */
|
transition: 0.4s ease-out;
|
||||||
|
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-areas: "circle header" "content content";
|
grid-template-areas: "circle header" "content content";
|
||||||
@@ -15,6 +15,7 @@
|
|||||||
column-gap: var(--Spacing-x-one-and-half);
|
column-gap: var(--Spacing-x-one-and-half);
|
||||||
|
|
||||||
transform-origin: top;
|
transform-origin: top;
|
||||||
|
scroll-margin-top: 71px; /* booking widget height */
|
||||||
}
|
}
|
||||||
|
|
||||||
.accordion:last-child {
|
.accordion:last-child {
|
||||||
@@ -81,9 +82,9 @@
|
|||||||
background-color: var(--Base-Surface-Subtle-Hover);
|
background-color: var(--Base-Surface-Subtle-Hover);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* .accordion[data-open="true"] {
|
.accordion[data-open="true"] {
|
||||||
grid-template-rows: var(--header-height) 1fr;
|
grid-template-rows: var(--header-height) 1fr;
|
||||||
} */
|
}
|
||||||
|
|
||||||
.contentWrapper {
|
.contentWrapper {
|
||||||
padding-bottom: var(--Spacing-x3);
|
padding-bottom: var(--Spacing-x3);
|
||||||
|
|||||||
@@ -42,6 +42,16 @@ export function extractGuestFromUser(user: NonNullable<SafeUser>) {
|
|||||||
|
|
||||||
export function navigate(step: StepEnum, searchParams: string) {
|
export function navigate(step: StepEnum, searchParams: string) {
|
||||||
window.history.pushState({ step }, "", `${step}?${searchParams}`)
|
window.history.pushState({ step }, "", `${step}?${searchParams}`)
|
||||||
|
|
||||||
|
const element = document.querySelector(`[data-step='${step}']`)
|
||||||
|
const isMobile = window.matchMedia("(max-width: 768px)").matches
|
||||||
|
if (element && isMobile) {
|
||||||
|
element.addEventListener(
|
||||||
|
"transitionend",
|
||||||
|
() => element?.scrollIntoView({ behavior: "smooth" }),
|
||||||
|
{ once: true }
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function checkIsSameBooking(prev: BookingData, next: BookingData) {
|
export function checkIsSameBooking(prev: BookingData, next: BookingData) {
|
||||||
|
|||||||
Reference in New Issue
Block a user