* feat(BOOK-293): Adjusted padding of the buttons to match Figma design * feat(BOOK-293): Updated variants for IconButton * feat(BOOK-113): Updated focus indicators on buttons and added default focus ring color * feat(BOOK-293): Replaced buttons inside booking widget Approved-by: Christel Westerberg
95 lines
2.6 KiB
TypeScript
95 lines
2.6 KiB
TypeScript
'use client'
|
|
|
|
import { useEffect } from 'react'
|
|
import { Dialog, Modal, ModalOverlay } from 'react-aria-components'
|
|
import { useIntl } from 'react-intl'
|
|
|
|
import usePopStateHandler from '@scandic-hotels/common/hooks/usePopStateHandler'
|
|
|
|
import { IconButton } from '../IconButton'
|
|
import { MaterialIcon } from '../Icons/MaterialIcon'
|
|
import { Typography } from '../Typography'
|
|
|
|
import SidePeekSEO from './SidePeekSEO'
|
|
|
|
import { KeepBodyVisible } from './KeepBodyVisible'
|
|
import styles from './sidePeek.module.css'
|
|
|
|
interface SidePeekSelfControlledProps extends React.PropsWithChildren {
|
|
title: string
|
|
isOpen: boolean
|
|
onClose: () => void
|
|
}
|
|
|
|
export default function SidePeekSelfControlled({
|
|
children,
|
|
isOpen,
|
|
onClose,
|
|
title,
|
|
}: SidePeekSelfControlledProps) {
|
|
const intl = useIntl()
|
|
|
|
function handleClose(moveBack = false) {
|
|
if (moveBack) {
|
|
window.history.back()
|
|
} else {
|
|
onClose()
|
|
}
|
|
}
|
|
|
|
// Only register popstate handler when open
|
|
usePopStateHandler(() => handleClose(), isOpen)
|
|
|
|
useEffect(() => {
|
|
if (isOpen) {
|
|
window.history.pushState(null, '', window.location.href)
|
|
}
|
|
}, [isOpen])
|
|
|
|
return (
|
|
<>
|
|
<ModalOverlay
|
|
className={styles.overlay}
|
|
isDismissable
|
|
onOpenChange={() => handleClose(true)}
|
|
isOpen={isOpen}
|
|
>
|
|
<Modal className={styles.modal}>
|
|
<Dialog className={styles.dialog} aria-label={title}>
|
|
<aside className={styles.aside}>
|
|
<header className={styles.header}>
|
|
<div className={styles.headerContent}>
|
|
{title ? (
|
|
<Typography variant="Title/md" className={styles.heading}>
|
|
<h2>{title}</h2>
|
|
</Typography>
|
|
) : null}
|
|
<IconButton
|
|
variant="Muted"
|
|
emphasis
|
|
onPress={() => handleClose(true)}
|
|
aria-label={intl.formatMessage({
|
|
id: 'common.close',
|
|
defaultMessage: 'Close',
|
|
})}
|
|
>
|
|
<MaterialIcon
|
|
icon="close"
|
|
size={24}
|
|
color="Icon/Interactive/Default"
|
|
/>
|
|
</IconButton>
|
|
</div>
|
|
</header>
|
|
<div className={styles.sidePeekContent}>{children}</div>
|
|
<KeepBodyVisible />
|
|
</aside>
|
|
</Dialog>
|
|
</Modal>
|
|
</ModalOverlay>
|
|
|
|
<SidePeekSEO title={title}>{children}</SidePeekSEO>
|
|
</>
|
|
)
|
|
}
|