Add phantom overlay to Selects to prevent background touches
https://github.com/radix-ui/primitives/issues/1658
This commit is contained in:
parent
2c2a9dd65d
commit
84aa355ad8
6 changed files with 86 additions and 23 deletions
|
|
@ -11,6 +11,7 @@
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
max-width: 761px;
|
max-width: 761px;
|
||||||
|
isolation: isolate;
|
||||||
|
|
||||||
@include breakpoint(tablet) {
|
@include breakpoint(tablet) {
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
|
|
|
||||||
|
|
@ -45,6 +45,7 @@
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.2);
|
box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.2);
|
||||||
display: block;
|
display: block;
|
||||||
|
isolation: isolate;
|
||||||
flex-grow: 2;
|
flex-grow: 2;
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
height: $height;
|
height: $height;
|
||||||
|
|
|
||||||
13
components/Overlay/index.scss
Normal file
13
components/Overlay/index.scss
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
.Overlay {
|
||||||
|
isolation: isolate;
|
||||||
|
position: fixed;
|
||||||
|
z-index: 30;
|
||||||
|
top: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
|
||||||
|
&.Visible {
|
||||||
|
background: rgba(0, 0, 0, 0.6);
|
||||||
|
}
|
||||||
|
}
|
||||||
52
components/Overlay/index.tsx
Normal file
52
components/Overlay/index.tsx
Normal file
|
|
@ -0,0 +1,52 @@
|
||||||
|
import React, { useEffect, useState } from 'react'
|
||||||
|
import classNames from 'classnames'
|
||||||
|
import './index.scss'
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
visible: boolean
|
||||||
|
open: boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
const defaultProps = {
|
||||||
|
visible: true,
|
||||||
|
}
|
||||||
|
|
||||||
|
const Overlay = ({
|
||||||
|
visible: displayed,
|
||||||
|
open,
|
||||||
|
}: {
|
||||||
|
visible: boolean
|
||||||
|
open: boolean
|
||||||
|
}) => {
|
||||||
|
const [visible, setVisible] = useState(open)
|
||||||
|
|
||||||
|
const classes = classNames({
|
||||||
|
Overlay: true,
|
||||||
|
Visible: displayed,
|
||||||
|
})
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!open) {
|
||||||
|
console.log('No longer open, setting timeout...')
|
||||||
|
const timer = setTimeout(() => {
|
||||||
|
console.log('Timeout cleared!')
|
||||||
|
setVisible(false)
|
||||||
|
}, 200)
|
||||||
|
return () => {
|
||||||
|
clearTimeout(timer)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
setVisible(true)
|
||||||
|
return () => {}
|
||||||
|
}, [open])
|
||||||
|
|
||||||
|
function handleClick(event: React.MouseEvent<HTMLDivElement, MouseEvent>) {
|
||||||
|
event.stopPropagation()
|
||||||
|
}
|
||||||
|
|
||||||
|
return visible ? <div className={classes} onClick={handleClick} /> : null
|
||||||
|
}
|
||||||
|
|
||||||
|
Overlay.defaultProps = defaultProps
|
||||||
|
|
||||||
|
export default Overlay
|
||||||
|
|
@ -5,6 +5,7 @@ import classNames from 'classnames'
|
||||||
import ArrowIcon from '~public/icons/Arrow.svg'
|
import ArrowIcon from '~public/icons/Arrow.svg'
|
||||||
|
|
||||||
import './index.scss'
|
import './index.scss'
|
||||||
|
import Overlay from '~components/Overlay'
|
||||||
|
|
||||||
// Props
|
// Props
|
||||||
interface Props
|
interface Props
|
||||||
|
|
@ -76,19 +77,24 @@ const Select = React.forwardRef<HTMLButtonElement, Props>(function Select(
|
||||||
</RadixSelect.Trigger>
|
</RadixSelect.Trigger>
|
||||||
|
|
||||||
<RadixSelect.Portal className="Select">
|
<RadixSelect.Portal className="Select">
|
||||||
<RadixSelect.Content
|
<>
|
||||||
onCloseAutoFocus={onCloseAutoFocus}
|
<Overlay open={open} visible={false} />
|
||||||
onEscapeKeyDown={onEscapeKeyDown}
|
|
||||||
onPointerDownOutside={onPointerDownOutside}
|
<RadixSelect.Content
|
||||||
>
|
className="Select"
|
||||||
<RadixSelect.ScrollUpButton className="Scroll Up">
|
onCloseAutoFocus={onCloseAutoFocus}
|
||||||
<ArrowIcon />
|
onEscapeKeyDown={onEscapeKeyDown}
|
||||||
</RadixSelect.ScrollUpButton>
|
onPointerDownOutside={onPointerDownOutside}
|
||||||
<RadixSelect.Viewport>{props.children}</RadixSelect.Viewport>
|
>
|
||||||
<RadixSelect.ScrollDownButton className="Scroll Down">
|
<RadixSelect.ScrollUpButton className="Scroll Up">
|
||||||
<ArrowIcon />
|
<ArrowIcon />
|
||||||
</RadixSelect.ScrollDownButton>
|
</RadixSelect.ScrollUpButton>
|
||||||
</RadixSelect.Content>
|
<RadixSelect.Viewport>{props.children}</RadixSelect.Viewport>
|
||||||
|
<RadixSelect.ScrollDownButton className="Scroll Down">
|
||||||
|
<ArrowIcon />
|
||||||
|
</RadixSelect.ScrollDownButton>
|
||||||
|
</RadixSelect.Content>
|
||||||
|
</>
|
||||||
</RadixSelect.Portal>
|
</RadixSelect.Portal>
|
||||||
</RadixSelect.Root>
|
</RadixSelect.Root>
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -119,16 +119,6 @@ select {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.Overlay {
|
|
||||||
background: rgba(0, 0, 0, 0.6);
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
z-index: 20;
|
|
||||||
}
|
|
||||||
|
|
||||||
.Hovercard {
|
.Hovercard {
|
||||||
background: #222;
|
background: #222;
|
||||||
border-radius: $unit;
|
border-radius: $unit;
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue