Repository navigation
Expand file tree
/
Copy pathindex.js
More file actions
124 lines (113 loc) · 2.83 KB
/
Copy pathindex.js
File metadata and controls
124 lines (113 loc) · 2.83 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
import React, {
createContext,
createPortal,
useEffect,
useRef,
Children,
Component
} from 'react'
const Context = createContext('Modals')
const isOverlay = (el) =>
(el.classList && el.classList.contains('ae-modal-container'))
class Portal extends Component {
constructor (props) {
super(props)
this.el = document.createElement('div')
this.modalRoot = document.getElementById('modals')
}
componentDidMount () {
// The portal element is inserted in the DOM tree after
// the Modal's children are mounted, meaning that children
// will be mounted on a detached DOM node. If a child
// component requires to be attached to the DOM tree
// immediately when mounted, for example to measure a
// DOM node, or uses 'autoFocus' in a descendant, add
// state to Modal and only render the children when Modal
// is inserted in the DOM tree.
this.modalRoot.appendChild(this.el)
}
componentWillUnmount () {
this.modalRoot.removeChild(this.el)
}
render () {
return createPortal(
this.props.children,
this.el
)
}
}
export function Modal ({
className = '',
hideClose = false,
shouldCloseOnEsc = true,
children
}) {
const focusRef = useRef()
useEffect(() => {
if (focusRef.current) {
focusRef.current.focus()
}
}, [])
return (
<Context.Consumer>
{([_, setModal]) => {
const closeModal = () => setModal(null)
const onContainerClick = (event) => {
if (isOverlay(event.target)) {
closeModal()
}
}
const handleKeyDown = (event) => {
const pressedEsc = event.keyCode === 27
if (pressedEsc) {
event.stopPropagation()
closeModal()
}
}
return (
<div
className={'ae-modal-container ' + className}
onClick={onContainerClick}
>
<div
class='ae-modal-content'
ref={focusRef}
tabIndex='-1'
onKeyDown={shouldCloseOnEsc && handleKeyDown}
>
{!hideClose &&
<div className='close' onClick={closeModal}>
close
</div>}
{children}
</div>
</div>
)
}}
</Context.Consumer>
)
}
export function Modals ({ value, syncState, children }) {
const setModalMaybe = (uid) => {
if (uid !== value) {
syncState && syncState(uid)
}
}
if (value == null) {
return null
}
let child
Children.forEach(children, c => {
if (c.type.name === value) {
child = c
}
})
if (value != null && child == null) {
console.warn('No modal found for: ' + value)
}
return (
<Context.Provider value={[value, setModalMaybe]}>
<Portal>{child}</Portal>
</Context.Provider>
)
}