115 lines
3.2 KiB
TypeScript
115 lines
3.2 KiB
TypeScript
"use client"
|
|
import { useEffect, useRef, useState } from "react"
|
|
import { useIntl } from "react-intl"
|
|
|
|
import { useEnterDetailsStore } from "@/stores/enter-details"
|
|
|
|
import { CheckIcon, ChevronDownIcon } from "@/components/Icons"
|
|
import Button from "@/components/TempDesignSystem/Button"
|
|
import Footnote from "@/components/TempDesignSystem/Text/Footnote"
|
|
import Subtitle from "@/components/TempDesignSystem/Text/Subtitle"
|
|
|
|
import styles from "./sectionAccordion.module.css"
|
|
|
|
import { SectionAccordionProps } from "@/types/components/hotelReservation/selectRate/sectionAccordion"
|
|
|
|
export default function SectionAccordion({
|
|
header,
|
|
label,
|
|
step,
|
|
children,
|
|
}: React.PropsWithChildren<SectionAccordionProps>) {
|
|
const intl = useIntl()
|
|
const [isComplete, setIsComplete] = useState(false)
|
|
const currentStep = useEnterDetailsStore((state) => state.currentStep)
|
|
const isValid = useEnterDetailsStore((state) => state.isValid[step])
|
|
|
|
const navigate = useEnterDetailsStore((state) => state.navigate)
|
|
|
|
const contentRef = useRef<HTMLDivElement>(null)
|
|
const circleRef = useRef<HTMLDivElement>(null)
|
|
|
|
const isOpen = currentStep === step
|
|
|
|
useEffect(() => {
|
|
const content = contentRef.current
|
|
const circle = circleRef.current
|
|
if (content) {
|
|
if (isOpen) {
|
|
content.style.maxHeight = `${content.scrollHeight}px`
|
|
} else {
|
|
content.style.maxHeight = "0"
|
|
}
|
|
}
|
|
|
|
if (circle) {
|
|
if (isOpen) {
|
|
circle.style.backgroundColor = `var(--UI-Text-Placeholder);`
|
|
} else {
|
|
circle.style.backgroundColor = `var(--Base-Surface-Subtle-Hover);`
|
|
}
|
|
}
|
|
}, [isOpen])
|
|
|
|
useEffect(() => {
|
|
// We need to set the state on mount because of hydration errors
|
|
setIsComplete(isValid)
|
|
}, [isValid])
|
|
|
|
function onModify() {
|
|
navigate(step)
|
|
}
|
|
|
|
return (
|
|
<section className={styles.wrapper} data-open={isOpen}>
|
|
<div className={styles.iconWrapper}>
|
|
<div
|
|
className={styles.circle}
|
|
data-checked={isComplete}
|
|
ref={circleRef}
|
|
>
|
|
{isComplete ? (
|
|
<CheckIcon color="white" height="16" width="16" />
|
|
) : null}
|
|
</div>
|
|
</div>
|
|
<div className={styles.main}>
|
|
<header className={styles.headerContainer}>
|
|
<div>
|
|
<Footnote
|
|
asChild
|
|
textTransform="uppercase"
|
|
color="uiTextPlaceholder"
|
|
>
|
|
<h2>{header}</h2>
|
|
</Footnote>
|
|
<Subtitle
|
|
type="two"
|
|
className={styles.selection}
|
|
color="uiTextHighContrast"
|
|
>
|
|
{label}
|
|
</Subtitle>
|
|
</div>
|
|
{isComplete && !isOpen && (
|
|
<Button
|
|
onClick={onModify}
|
|
theme="base"
|
|
size="small"
|
|
variant="icon"
|
|
intent="text"
|
|
wrapping
|
|
>
|
|
{intl.formatMessage({ id: "Modify" })}{" "}
|
|
<ChevronDownIcon color="burgundy" />
|
|
</Button>
|
|
)}
|
|
</header>
|
|
<div className={styles.content} ref={contentRef}>
|
|
{children}
|
|
</div>
|
|
</div>
|
|
</section>
|
|
)
|
|
}
|