@@ -5,6 +5,7 @@ import Button from './Button'
55import classNames from 'classnames'
66import usePortal from '../utils/usePortal'
77import { createPortal } from 'react-dom'
8+ import FocusLock from 'react-focus-lock'
89
910const Modal = ( props ) => {
1011 const [ , setOpen ] = props . modalState
@@ -24,27 +25,36 @@ const Modal = (props) => {
2425 const target = usePortal ( props . id )
2526
2627 return createPortal (
27- < div className = 'fixed w-screen md:p-4 bg-gray-900 bg-opacity-60 flex items-start md:items-center justify-center inset-0 z-50 text-black transition-colors' >
28- < dialog className = 'overflow-scroll block w-full h-full md:h-auto md:w-[600px] bg-white md:rounded p-0' aria-modal = 'true' aria-labelledby = { `modal-${ props . id } -label` } >
29- < div className = 'p-4 border-b border-gray-200 flex items-center justify-between' >
30- < h2
31- id = { `modal-${ props . id } -label` }
32- className = { classNames ( 'text-xl font-semibold' , { 'hidden' : props . hideTitle } ) }
33- >
34- { props . title }
35- </ h2 >
36-
37- < Button
38- variant = 'icon'
39- onClick = { ( ) => setOpen ( false ) }
40- icon = { < IconX /> }
41- extra = { { 'aria-label' : 'Close modal' } }
42- />
43- </ div >
44-
45- { props . children }
46- </ dialog >
47- </ div > ,
28+ < FocusLock >
29+ < div className = 'fixed w-screen md:p-4 bg-gray-900 bg-opacity-60 flex items-start md:items-center justify-center inset-0 z-50 text-black transition-colors' >
30+ < dialog
31+ className = { classNames ( 'block w-full h-full md:h-auto md:w-[600px] bg-white md:rounded p-0' , {
32+ 'overflow-scroll' : props . scroll ,
33+ 'overflow-visible' : ! props . scroll
34+ } ) }
35+ aria-modal = 'true'
36+ aria-labelledby = { `modal-${ props . id } -label` }
37+ >
38+ < div className = 'p-4 border-b border-gray-200 flex items-center justify-between' >
39+ < h2
40+ id = { `modal-${ props . id } -label` }
41+ className = { classNames ( 'text-xl font-semibold' , { 'hidden' : props . hideTitle } ) }
42+ >
43+ { props . title }
44+ </ h2 >
45+
46+ < Button
47+ variant = 'icon'
48+ onClick = { ( ) => setOpen ( false ) }
49+ icon = { < IconX /> }
50+ extra = { { 'aria-label' : 'Close modal' } }
51+ />
52+ </ div >
53+
54+ { props . children }
55+ </ dialog >
56+ </ div >
57+ </ FocusLock > ,
4858 target
4959 )
5060}
@@ -54,7 +64,12 @@ Modal.propTypes = {
5464 title : PropTypes . string . isRequired ,
5565 hideTitle : PropTypes . bool ,
5666 children : PropTypes . any . isRequired ,
57- modalState : PropTypes . array . isRequired
67+ modalState : PropTypes . array . isRequired ,
68+ scroll : PropTypes . bool
69+ }
70+
71+ Modal . defaultProps = {
72+ scroll : true
5873}
5974
6075export default Modal
0 commit comments