183 lines
4.3 KiB
JavaScript
183 lines
4.3 KiB
JavaScript
import MaterialPopper from '@mui/material/Popper'
|
|
import Paper from '@mui/material/Paper'
|
|
import { makeStyles } from '@mui/styles'
|
|
import classnames from 'classnames'
|
|
import * as R from 'ramda'
|
|
import React, { useState } from 'react'
|
|
|
|
import { white } from 'src/styling/variables'
|
|
|
|
const Popover = ({
|
|
children,
|
|
bgColor = white,
|
|
arrowSize = 6,
|
|
className,
|
|
...props
|
|
}) => {
|
|
const [arrowRef, setArrowRef] = useState(null)
|
|
|
|
const styles = {
|
|
popover: {
|
|
zIndex: 3000,
|
|
backgroundColor: bgColor,
|
|
borderRadius: 4
|
|
},
|
|
arrow: {
|
|
position: 'absolute',
|
|
fontSize: arrowSize,
|
|
width: '3em',
|
|
height: '3em'
|
|
},
|
|
arrowBottom: {
|
|
top: 0,
|
|
width: 0,
|
|
height: 0,
|
|
borderLeft: [['2em', 'solid', 'transparent']],
|
|
borderRight: [['2em', 'solid', 'transparent']],
|
|
borderBottom: [['2em', 'solid', bgColor]],
|
|
marginTop: '-1.9em',
|
|
'&:after': {
|
|
zIndex: -10,
|
|
content: '""',
|
|
position: 'absolute',
|
|
width: arrowSize * 3,
|
|
height: arrowSize * 3,
|
|
marginLeft: 0,
|
|
bottom: 0,
|
|
top: 'calc(50% - 0px)',
|
|
left: 0,
|
|
border: '5px solid #fff',
|
|
borderColor: 'transparent transparent #fff #fff',
|
|
transformOrigin: '0 0',
|
|
transform: 'rotate(45deg)',
|
|
boxShadow:
|
|
'0px 2px 1px -1px rgba(0,0,0,0.2),0px 1px 1px 0px rgba(0,0,0,0.14),0px 1px 3px 0px rgba(0,0,0,0.12)'
|
|
}
|
|
},
|
|
arrowTop: {
|
|
bottom: 0,
|
|
width: 0,
|
|
height: 0,
|
|
borderLeft: [['2em', 'solid', 'transparent']],
|
|
borderRight: [['2em', 'solid', 'transparent']],
|
|
borderTop: [['2em', 'solid', bgColor]],
|
|
marginBottom: '-1.9em',
|
|
'&:after': {
|
|
zIndex: -10,
|
|
content: '""',
|
|
position: 'absolute',
|
|
width: arrowSize * 3,
|
|
height: arrowSize * 3,
|
|
marginLeft: 0,
|
|
bottom: 0,
|
|
top: -(arrowSize * 4 + 2),
|
|
left: 0,
|
|
border: '5px solid #fff',
|
|
borderColor: 'transparent transparent #fff #fff',
|
|
transformOrigin: '0 0',
|
|
transform: 'rotate(45deg)',
|
|
boxShadow:
|
|
'0px 2px 1px -1px rgba(0,0,0,0.2),0px 1px 1px 0px rgba(0,0,0,0.14),0px 1px 3px 0px rgba(0,0,0,0.12)'
|
|
}
|
|
},
|
|
arrowRight: {
|
|
left: 0,
|
|
width: 0,
|
|
height: 0,
|
|
borderTop: [['2em', 'solid', 'transparent']],
|
|
borderBottom: [['2em', 'solid', 'transparent']],
|
|
borderRight: [['2em', 'solid', bgColor]],
|
|
marginLeft: '-1.9em'
|
|
},
|
|
arrowLeft: {
|
|
right: 0,
|
|
width: 0,
|
|
height: 0,
|
|
borderTop: [['2em', 'solid', 'transparent']],
|
|
borderBottom: [['2em', 'solid', 'transparent']],
|
|
borderLeft: [['2em', 'solid', bgColor]],
|
|
marginRight: '-1.9em'
|
|
},
|
|
root: {
|
|
backgroundColor: bgColor
|
|
}
|
|
}
|
|
|
|
const useStyles = makeStyles(styles)
|
|
|
|
const classes = useStyles()
|
|
|
|
const getArrowClasses = placement => ({
|
|
[classes.arrow]: true,
|
|
[classes.arrowBottom]: placement === 'bottom',
|
|
[classes.arrowTop]: placement === 'top',
|
|
[classes.arrowRight]: placement === 'right',
|
|
[classes.arrowLeft]: placement === 'left'
|
|
})
|
|
|
|
const flipPlacements = {
|
|
top: ['bottom'],
|
|
bottom: ['top'],
|
|
left: ['right'],
|
|
right: ['left']
|
|
}
|
|
|
|
const modifiers = [
|
|
{
|
|
name: 'flip',
|
|
enabled: R.defaultTo(false, props.flip),
|
|
options: {
|
|
allowedAutoPlacements: flipPlacements[props.placement]
|
|
}
|
|
},
|
|
{
|
|
name: 'preventOverflow',
|
|
enabled: true,
|
|
options: {
|
|
rootBoundary: 'scrollParent'
|
|
}
|
|
},
|
|
{
|
|
name: 'offset',
|
|
enabled: true,
|
|
options: {
|
|
offset: [0, 10]
|
|
}
|
|
},
|
|
{
|
|
name: 'arrow',
|
|
enabled: R.defaultTo(true, props.showArrow),
|
|
options: {
|
|
element: arrowRef
|
|
}
|
|
},
|
|
{
|
|
name: 'computeStyles',
|
|
options: {
|
|
gpuAcceleration: false
|
|
}
|
|
}
|
|
]
|
|
|
|
return (
|
|
<>
|
|
<MaterialPopper
|
|
disablePortal={false}
|
|
modifiers={modifiers}
|
|
className={classes.popover}
|
|
{...props}>
|
|
{({ placement }) => (
|
|
<Paper className={classnames(classes.root, className)}>
|
|
<span
|
|
className={classnames(getArrowClasses(placement))}
|
|
ref={setArrowRef}
|
|
/>
|
|
{children}
|
|
</Paper>
|
|
)}
|
|
</MaterialPopper>
|
|
</>
|
|
)
|
|
}
|
|
|
|
export default Popover
|