2020-08-28 16:55:07 +02:00
|
|
|
|
import FocusTrap from 'focus-trap-react'
|
|
|
|
|
import React, { useEffect, useState } from 'react'
|
|
|
|
|
import styled, { css } from 'styled-components'
|
|
|
|
|
|
|
|
|
|
type OverlayProps = React.HTMLAttributes<HTMLDivElement> & {
|
|
|
|
|
onClose?: () => void
|
|
|
|
|
xPosition?: number
|
|
|
|
|
children: React.ReactNode
|
|
|
|
|
}
|
2020-10-12 16:12:29 +02:00
|
|
|
|
declare global {
|
|
|
|
|
interface Window {
|
|
|
|
|
parentIFrame?: any
|
|
|
|
|
}
|
|
|
|
|
}
|
2020-08-28 16:55:07 +02:00
|
|
|
|
|
|
|
|
|
const useIFrameOffset = () => {
|
|
|
|
|
const [offsetTop, setOffset] = useState<number | null>(null)
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
if (!('parentIFrame' in window)) {
|
|
|
|
|
setOffset(0)
|
|
|
|
|
return
|
|
|
|
|
}
|
2021-01-06 11:33:38 +01:00
|
|
|
|
window.parentIFrame.getPageInfo(({ scrollTop, offsetTop }) => {
|
2020-08-28 16:55:07 +02:00
|
|
|
|
setOffset(scrollTop - offsetTop)
|
|
|
|
|
window.parentIFrame.getPageInfo(false)
|
|
|
|
|
})
|
|
|
|
|
}, [])
|
|
|
|
|
return offsetTop
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export default function Overlay({
|
|
|
|
|
onClose,
|
|
|
|
|
children,
|
|
|
|
|
className,
|
|
|
|
|
...otherProps
|
|
|
|
|
}: OverlayProps) {
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
const body = document.getElementsByTagName('body')[0]
|
|
|
|
|
body.classList.add('no-scroll')
|
|
|
|
|
return () => {
|
|
|
|
|
body.classList.remove('no-scroll')
|
|
|
|
|
}
|
|
|
|
|
}, [])
|
|
|
|
|
const offsetTop = useIFrameOffset()
|
2021-01-06 11:20:16 +01:00
|
|
|
|
|
2020-08-28 16:55:07 +02:00
|
|
|
|
if (offsetTop === null) {
|
|
|
|
|
return null
|
|
|
|
|
}
|
|
|
|
|
return (
|
2021-01-06 11:20:16 +01:00
|
|
|
|
<StyledOverlayWrapper offsetTop={Math.max(0, offsetTop)}>
|
2020-08-28 16:55:07 +02:00
|
|
|
|
<div className="overlayContent">
|
|
|
|
|
<FocusTrap
|
|
|
|
|
focusTrapOptions={{
|
|
|
|
|
onDeactivate: onClose,
|
2020-12-01 10:17:27 +01:00
|
|
|
|
clickOutsideDeactivates: !!onClose,
|
2020-08-28 16:55:07 +02:00
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
<div
|
|
|
|
|
aria-modal="true"
|
|
|
|
|
className={'ui__ card ' + className ?? ''}
|
|
|
|
|
{...otherProps}
|
|
|
|
|
>
|
|
|
|
|
{children}
|
|
|
|
|
{onClose && (
|
|
|
|
|
<button
|
|
|
|
|
aria-label="Fermer"
|
|
|
|
|
onClick={onClose}
|
|
|
|
|
className="overlayCloseButton"
|
|
|
|
|
>
|
|
|
|
|
×
|
|
|
|
|
</button>
|
|
|
|
|
)}
|
|
|
|
|
</div>
|
|
|
|
|
</FocusTrap>
|
|
|
|
|
</div>
|
|
|
|
|
</StyledOverlayWrapper>
|
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const StyledOverlayWrapper = styled.div<{ offsetTop: number | null }>`
|
|
|
|
|
position: fixed;
|
|
|
|
|
top: 0;
|
|
|
|
|
left: 0;
|
|
|
|
|
right: 0;
|
|
|
|
|
bottom: 0;
|
|
|
|
|
background: rgba(255, 255, 255, 0.9);
|
2021-01-06 17:35:44 +01:00
|
|
|
|
max-height: 100vh;
|
2020-08-28 16:55:07 +02:00
|
|
|
|
overflow: auto;
|
|
|
|
|
z-index: 2;
|
|
|
|
|
.overlayContent {
|
|
|
|
|
${({ offsetTop }) =>
|
|
|
|
|
offsetTop
|
|
|
|
|
? css`
|
|
|
|
|
transform: translateY(${offsetTop}px);
|
|
|
|
|
`
|
|
|
|
|
: css`
|
|
|
|
|
bottom: 0;
|
|
|
|
|
max-height: 80vh;
|
|
|
|
|
`}
|
|
|
|
|
position: absolute;
|
|
|
|
|
}
|
|
|
|
|
.overlayCloseButton {
|
2021-01-06 11:20:16 +01:00
|
|
|
|
position: fixed;
|
|
|
|
|
background-color: white;
|
|
|
|
|
border-top-left-radius: 100%;
|
2020-08-28 16:55:07 +02:00
|
|
|
|
text-decoration: none;
|
2021-01-06 11:20:16 +01:00
|
|
|
|
font-size: 2.5rem;
|
|
|
|
|
border-top: 0.5rem solid white;
|
|
|
|
|
border-left: 0.5rem solid white;
|
|
|
|
|
bottom: 0;
|
|
|
|
|
right: 0;
|
2020-08-28 16:55:07 +02:00
|
|
|
|
color: var(--lighterTextColor);
|
2021-01-06 11:20:16 +01:00
|
|
|
|
padding: 0 1rem;
|
2021-01-07 17:08:19 +00:00
|
|
|
|
text-decoration: none;
|
2020-08-28 16:55:07 +02:00
|
|
|
|
}
|
2020-10-12 15:04:36 +02:00
|
|
|
|
.ui__.card[aria-modal='true'] {
|
|
|
|
|
padding-bottom: 4rem;
|
|
|
|
|
display: flex;
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
}
|
2021-01-07 17:08:19 +00:00
|
|
|
|
@media (max-width: 600px) {
|
|
|
|
|
.overlayContent {
|
|
|
|
|
width: 100%;
|
|
|
|
|
}
|
|
|
|
|
.overlayCloseButton {
|
|
|
|
|
position: fixed;
|
|
|
|
|
bottom: 0;
|
|
|
|
|
right: 0;
|
|
|
|
|
line-height: 1rem;
|
|
|
|
|
padding: 1.2rem;
|
|
|
|
|
padding-bottom: 1.5rem;
|
|
|
|
|
font-size: 3rem;
|
|
|
|
|
background: var(--lighterColor);
|
|
|
|
|
}
|
|
|
|
|
}
|
2020-10-12 15:04:36 +02:00
|
|
|
|
|
2020-08-28 16:55:07 +02:00
|
|
|
|
@media (min-width: 600px) {
|
|
|
|
|
.overlayCloseButton {
|
2021-01-07 17:08:19 +00:00
|
|
|
|
position: absolute;
|
2020-08-28 16:55:07 +02:00
|
|
|
|
top: 0;
|
|
|
|
|
bottom: auto;
|
2021-01-07 17:08:19 +00:00
|
|
|
|
right: 0;
|
2021-01-06 11:20:16 +01:00
|
|
|
|
padding: 0 0.5rem;
|
2020-08-28 16:55:07 +02:00
|
|
|
|
font-size: 2rem;
|
|
|
|
|
}
|
|
|
|
|
.overlayContent {
|
|
|
|
|
transform: translateX(-50%)
|
2021-01-06 11:20:16 +01:00
|
|
|
|
translateY(calc(${({ offsetTop }) => offsetTop}px + 5rem));
|
2020-08-28 16:55:07 +02:00
|
|
|
|
left: 50%;
|
|
|
|
|
width: 80%;
|
|
|
|
|
bottom: auto;
|
|
|
|
|
height: auto;
|
|
|
|
|
max-width: 40em;
|
|
|
|
|
min-height: 6em;
|
|
|
|
|
}
|
2021-01-06 11:20:16 +01:00
|
|
|
|
.ui__.card[aria-modal='true'] {
|
|
|
|
|
padding-bottom: 2rem;
|
|
|
|
|
margin-bottom: 2rem;
|
|
|
|
|
}
|
2020-08-28 16:55:07 +02:00
|
|
|
|
}
|
|
|
|
|
`
|