2023-09-29 16:01:27 +02:00
|
|
|
// __SDEFILE__ - This file is a dependency for the stand-alone environment
|
2023-04-25 17:33:34 +02:00
|
|
|
import { useState, useEffect, useContext } from 'react'
|
2023-04-22 14:34:16 +02:00
|
|
|
import { useSwipeable } from 'react-swipeable'
|
2023-04-25 17:33:34 +02:00
|
|
|
import { ModalContext } from 'shared/context/modal-context.mjs'
|
2023-11-26 11:42:50 +01:00
|
|
|
import { CloseIcon } from 'shared/components/icons.mjs'
|
2023-04-22 14:34:16 +02:00
|
|
|
|
|
|
|
const slideClasses = {
|
|
|
|
left: '-translate-x-full',
|
|
|
|
right: 'translate-x-full',
|
|
|
|
top: '-translate-y-full',
|
|
|
|
bottom: 'translate-y-full',
|
|
|
|
}
|
2023-04-19 20:56:15 +02:00
|
|
|
|
2023-04-16 10:45:36 +02:00
|
|
|
export const ModalWrapper = ({
|
2023-04-19 20:56:15 +02:00
|
|
|
children = null,
|
2023-04-16 10:45:36 +02:00
|
|
|
flex = 'row',
|
|
|
|
justify = 'center',
|
|
|
|
items = 'center',
|
|
|
|
bg = 'base-100 lg:bg-base-300',
|
|
|
|
bgOpacity = '100 lg:bg-opacity-95',
|
|
|
|
bare = false,
|
|
|
|
keepOpenOnClick = false,
|
2023-04-22 14:34:16 +02:00
|
|
|
slideFrom = 'left',
|
2023-06-23 14:29:09 -05:00
|
|
|
keepOpenOnSwipe = false,
|
2023-08-30 10:44:35 +02:00
|
|
|
fullWidth = false,
|
2023-04-19 20:56:15 +02:00
|
|
|
}) => {
|
2023-04-25 17:33:34 +02:00
|
|
|
const { clearModal } = useContext(ModalContext)
|
2023-06-29 16:41:11 +00:00
|
|
|
const [animate, setAnimate] = useState('in')
|
2023-04-19 20:56:15 +02:00
|
|
|
|
2023-04-22 14:34:16 +02:00
|
|
|
const close = (evt) => {
|
|
|
|
// Only process the first swipe event
|
|
|
|
if (evt?.event) evt.event.stopPropagation()
|
2023-06-29 16:41:11 +00:00
|
|
|
setAnimate('out')
|
|
|
|
window.setTimeout(clearModal, 150)
|
2023-04-22 14:34:16 +02:00
|
|
|
}
|
2023-06-23 14:29:09 -05:00
|
|
|
|
|
|
|
const swipeActions = {}
|
|
|
|
if (!keepOpenOnSwipe) {
|
|
|
|
if (slideFrom === 'left') swipeActions.onSwipedLeft = close
|
|
|
|
else if (slideFrom === 'right') swipeActions.onSwipedRight = close
|
|
|
|
else if (slideFrom === 'top') swipeActions.onSwipedUp = close
|
|
|
|
else if (slideFrom === 'bottom') swipeActions.onSwipedDown = close
|
|
|
|
}
|
2023-04-22 14:34:16 +02:00
|
|
|
|
|
|
|
const swipeHandlers = useSwipeable({
|
|
|
|
...swipeActions,
|
|
|
|
trackMouse: true,
|
|
|
|
})
|
|
|
|
|
2023-04-19 20:56:15 +02:00
|
|
|
useEffect(() => {
|
2023-06-29 16:41:11 +00:00
|
|
|
// only turn off animation if it's animating in
|
|
|
|
if (animate === 'in') setAnimate(false)
|
|
|
|
}, [animate])
|
2023-04-22 14:34:16 +02:00
|
|
|
|
|
|
|
// CSS classes for animation
|
|
|
|
const animation = animate
|
|
|
|
? `lg:opacity-0 ${slideClasses[slideFrom]} lg:translate-x-0 lg:translate-y-0`
|
|
|
|
: 'opacity-100 translate-none'
|
2023-04-19 20:56:15 +02:00
|
|
|
|
2023-11-26 11:42:50 +01:00
|
|
|
const stopClick = (evt) => evt.stopPropagation()
|
|
|
|
|
2023-04-19 20:56:15 +02:00
|
|
|
return (
|
|
|
|
<div
|
2023-04-22 14:34:16 +02:00
|
|
|
ref={swipeHandlers.ref}
|
|
|
|
onMouseDown={swipeHandlers.onMouseDown}
|
2023-04-19 20:56:15 +02:00
|
|
|
className={`fixed top-0 left-0 m-0 p-0 shadow w-full h-screen
|
2023-04-22 14:34:16 +02:00
|
|
|
transform-all duration-150 ${animation}
|
2023-04-16 10:45:36 +02:00
|
|
|
bg-${bg} bg-opacity-${bgOpacity} z-50 hover:cursor-pointer
|
2023-05-24 08:37:29 -05:00
|
|
|
flex flex-${flex} justify-${justify} items-${items} lg:p-12`}
|
2023-04-22 14:34:16 +02:00
|
|
|
onClick={keepOpenOnClick ? null : close}
|
2023-04-19 20:56:15 +02:00
|
|
|
>
|
|
|
|
{bare ? (
|
|
|
|
children
|
|
|
|
) : (
|
2023-05-24 08:37:29 -05:00
|
|
|
<div
|
2023-11-26 11:42:50 +01:00
|
|
|
onClick={stopClick}
|
|
|
|
className={`z-30 bg-base-100 p-4 lg:px-8 lg:rounded-lg lg:shadow-lg max-h-full overflow-auto hover:cursor-default ${
|
2023-08-30 10:44:35 +02:00
|
|
|
fullWidth ? 'w-full' : ''
|
|
|
|
}`}
|
2023-05-24 08:37:29 -05:00
|
|
|
>
|
|
|
|
{children}
|
2023-11-26 11:42:50 +01:00
|
|
|
{!keepOpenOnClick && (
|
|
|
|
<button
|
|
|
|
className="fixed bottom-2 right-2 btn btn-neutral btn-circle lg:hidden"
|
2023-11-26 14:42:02 +01:00
|
|
|
onClick={close}
|
2023-11-26 11:42:50 +01:00
|
|
|
>
|
|
|
|
<CloseIcon className="w-8 h-8" />
|
|
|
|
</button>
|
|
|
|
)}
|
2023-05-24 08:37:29 -05:00
|
|
|
</div>
|
2023-04-19 20:56:15 +02:00
|
|
|
)}
|
|
|
|
</div>
|
|
|
|
)
|
|
|
|
}
|