Page Menu
Home
c4science
Search
Configure Global Search
Log In
Files
F102278534
Modal.js
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Subscribers
None
File Metadata
Details
File Info
Storage
Attached
Created
Wed, Feb 19, 01:12
Size
8 KB
Mime Type
text/x-java
Expires
Fri, Feb 21, 01:12 (2 d)
Engine
blob
Format
Raw Data
Handle
24322539
Attached To
rOACCT Open Access Compliance Check Tool (OACCT)
Modal.js
View Options
const
_excluded
=
[
"show"
,
"role"
,
"className"
,
"style"
,
"children"
,
"backdrop"
,
"keyboard"
,
"onBackdropClick"
,
"onEscapeKeyDown"
,
"transition"
,
"backdropTransition"
,
"autoFocus"
,
"enforceFocus"
,
"restoreFocus"
,
"restoreFocusOptions"
,
"renderDialog"
,
"renderBackdrop"
,
"manager"
,
"container"
,
"onShow"
,
"onHide"
,
"onExit"
,
"onExited"
,
"onExiting"
,
"onEnter"
,
"onEntering"
,
"onEntered"
];
function
_objectWithoutPropertiesLoose
(
source
,
excluded
)
{
if
(
source
==
null
)
return
{};
var
target
=
{};
var
sourceKeys
=
Object
.
keys
(
source
);
var
key
,
i
;
for
(
i
=
0
;
i
<
sourceKeys
.
length
;
i
++
)
{
key
=
sourceKeys
[
i
];
if
(
excluded
.
indexOf
(
key
)
>=
0
)
continue
;
target
[
key
]
=
source
[
key
];
}
return
target
;
}
/* eslint-disable @typescript-eslint/no-use-before-define, react/prop-types */
import
activeElement
from
'dom-helpers/activeElement'
;
import
contains
from
'dom-helpers/contains'
;
import
canUseDOM
from
'dom-helpers/canUseDOM'
;
import
listen
from
'dom-helpers/listen'
;
import
{
useState
,
useRef
,
useCallback
,
useImperativeHandle
,
forwardRef
,
useEffect
}
from
'react'
;
import
*
as
React
from
'react'
;
import
ReactDOM
from
'react-dom'
;
import
useMounted
from
'@restart/hooks/useMounted'
;
import
useWillUnmount
from
'@restart/hooks/useWillUnmount'
;
import
usePrevious
from
'@restart/hooks/usePrevious'
;
import
useEventCallback
from
'@restart/hooks/useEventCallback'
;
import
ModalManager
from
'./ModalManager'
;
import
useWaitForDOMRef
from
'./useWaitForDOMRef'
;
import
useWindow
from
'./useWindow'
;
import
{
jsx
as
_jsx
}
from
"react/jsx-runtime"
;
import
{
Fragment
as
_Fragment
}
from
"react/jsx-runtime"
;
import
{
jsxs
as
_jsxs
}
from
"react/jsx-runtime"
;
let
manager
;
function
getManager
(
window
)
{
if
(
!
manager
)
manager
=
new
ModalManager
({
ownerDocument
:
window
==
null
?
void
0
:
window
.
document
});
return
manager
;
}
function
useModalManager
(
provided
)
{
const
window
=
useWindow
();
const
modalManager
=
provided
||
getManager
(
window
);
const
modal
=
useRef
({
dialog
:
null
,
backdrop
:
null
});
return
Object
.
assign
(
modal
.
current
,
{
add
:
()
=>
modalManager
.
add
(
modal
.
current
),
remove
:
()
=>
modalManager
.
remove
(
modal
.
current
),
isTopModal
:
()
=>
modalManager
.
isTopModal
(
modal
.
current
),
setDialogRef
:
useCallback
(
ref
=>
{
modal
.
current
.
dialog
=
ref
;
},
[]),
setBackdropRef
:
useCallback
(
ref
=>
{
modal
.
current
.
backdrop
=
ref
;
},
[])
});
}
const
Modal
=
/*#__PURE__*/
forwardRef
((
_ref
,
ref
)
=>
{
let
{
show
=
false
,
role
=
'dialog'
,
className
,
style
,
children
,
backdrop
=
true
,
keyboard
=
true
,
onBackdropClick
,
onEscapeKeyDown
,
transition
,
backdropTransition
,
autoFocus
=
true
,
enforceFocus
=
true
,
restoreFocus
=
true
,
restoreFocusOptions
,
renderDialog
,
renderBackdrop
=
props
=>
/*#__PURE__*/
_jsx
(
"div"
,
Object
.
assign
({},
props
)),
manager
:
providedManager
,
container
:
containerRef
,
onShow
,
onHide
=
()
=>
{},
onExit
,
onExited
,
onExiting
,
onEnter
,
onEntering
,
onEntered
}
=
_ref
,
rest
=
_objectWithoutPropertiesLoose
(
_ref
,
_excluded
);
const
container
=
useWaitForDOMRef
(
containerRef
);
const
modal
=
useModalManager
(
providedManager
);
const
isMounted
=
useMounted
();
const
prevShow
=
usePrevious
(
show
);
const
[
exited
,
setExited
]
=
useState
(
!
show
);
const
lastFocusRef
=
useRef
(
null
);
useImperativeHandle
(
ref
,
()
=>
modal
,
[
modal
]);
if
(
canUseDOM
&&
!
prevShow
&&
show
)
{
lastFocusRef
.
current
=
activeElement
();
}
if
(
!
transition
&&
!
show
&&
!
exited
)
{
setExited
(
true
);
}
else
if
(
show
&&
exited
)
{
setExited
(
false
);
}
const
handleShow
=
useEventCallback
(()
=>
{
modal
.
add
();
removeKeydownListenerRef
.
current
=
listen
(
document
,
'keydown'
,
handleDocumentKeyDown
);
removeFocusListenerRef
.
current
=
listen
(
document
,
'focus'
,
// the timeout is necessary b/c this will run before the new modal is mounted
// and so steals focus from it
()
=>
setTimeout
(
handleEnforceFocus
),
true
);
if
(
onShow
)
{
onShow
();
}
// autofocus after onShow to not trigger a focus event for previous
// modals before this one is shown.
if
(
autoFocus
)
{
const
currentActiveElement
=
activeElement
(
document
);
if
(
modal
.
dialog
&&
currentActiveElement
&&
!
contains
(
modal
.
dialog
,
currentActiveElement
))
{
lastFocusRef
.
current
=
currentActiveElement
;
modal
.
dialog
.
focus
();
}
}
});
const
handleHide
=
useEventCallback
(()
=>
{
modal
.
remove
();
removeKeydownListenerRef
.
current
==
null
?
void
0
:
removeKeydownListenerRef
.
current
();
removeFocusListenerRef
.
current
==
null
?
void
0
:
removeFocusListenerRef
.
current
();
if
(
restoreFocus
)
{
var
_lastFocusRef$current
;
// Support: <=IE11 doesn't support `focus()` on svg elements (RB: #917)
(
_lastFocusRef$current
=
lastFocusRef
.
current
)
==
null
?
void
0
:
_lastFocusRef$current
.
focus
==
null
?
void
0
:
_lastFocusRef$current
.
focus
(
restoreFocusOptions
);
lastFocusRef
.
current
=
null
;
}
});
// TODO: try and combine these effects: https://github.com/react-bootstrap/react-overlays/pull/794#discussion_r409954120
// Show logic when:
// - show is `true` _and_ `container` has resolved
useEffect
(()
=>
{
if
(
!
show
||
!
container
)
return
;
handleShow
();
},
[
show
,
container
,
/* should never change: */
handleShow
]);
// Hide cleanup logic when:
// - `exited` switches to true
// - component unmounts;
useEffect
(()
=>
{
if
(
!
exited
)
return
;
handleHide
();
},
[
exited
,
handleHide
]);
useWillUnmount
(()
=>
{
handleHide
();
});
// --------------------------------
const
handleEnforceFocus
=
useEventCallback
(()
=>
{
if
(
!
enforceFocus
||
!
isMounted
()
||
!
modal
.
isTopModal
())
{
return
;
}
const
currentActiveElement
=
activeElement
();
if
(
modal
.
dialog
&&
currentActiveElement
&&
!
contains
(
modal
.
dialog
,
currentActiveElement
))
{
modal
.
dialog
.
focus
();
}
});
const
handleBackdropClick
=
useEventCallback
(
e
=>
{
if
(
e
.
target
!==
e
.
currentTarget
)
{
return
;
}
onBackdropClick
==
null
?
void
0
:
onBackdropClick
(
e
);
if
(
backdrop
===
true
)
{
onHide
();
}
});
const
handleDocumentKeyDown
=
useEventCallback
(
e
=>
{
if
(
keyboard
&&
e
.
keyCode
===
27
&&
modal
.
isTopModal
())
{
onEscapeKeyDown
==
null
?
void
0
:
onEscapeKeyDown
(
e
);
if
(
!
e
.
defaultPrevented
)
{
onHide
();
}
}
});
const
removeFocusListenerRef
=
useRef
();
const
removeKeydownListenerRef
=
useRef
();
const
handleHidden
=
(...
args
)
=>
{
setExited
(
true
);
onExited
==
null
?
void
0
:
onExited
(...
args
);
};
const
Transition
=
transition
;
if
(
!
container
||
!
(
show
||
Transition
&&
!
exited
))
{
return
null
;
}
const
dialogProps
=
Object
.
assign
({
role
,
ref
:
modal
.
setDialogRef
,
// apparently only works on the dialog role element
'aria-modal'
:
role
===
'dialog'
?
true
:
undefined
},
rest
,
{
style
,
className
,
tabIndex
:
-
1
});
let
dialog
=
renderDialog
?
renderDialog
(
dialogProps
)
:
/*#__PURE__*/
_jsx
(
"div"
,
Object
.
assign
({},
dialogProps
,
{
children
:
/*#__PURE__*/
React
.
cloneElement
(
children
,
{
role
:
'document'
})
}));
if
(
Transition
)
{
dialog
=
/*#__PURE__*/
_jsx
(
Transition
,
{
appear
:
true
,
unmountOnExit
:
true
,
in
:
!!
show
,
onExit
:
onExit
,
onExiting
:
onExiting
,
onExited
:
handleHidden
,
onEnter
:
onEnter
,
onEntering
:
onEntering
,
onEntered
:
onEntered
,
children
:
dialog
});
}
let
backdropElement
=
null
;
if
(
backdrop
)
{
const
BackdropTransition
=
backdropTransition
;
backdropElement
=
renderBackdrop
({
ref
:
modal
.
setBackdropRef
,
onClick
:
handleBackdropClick
});
if
(
BackdropTransition
)
{
backdropElement
=
/*#__PURE__*/
_jsx
(
BackdropTransition
,
{
appear
:
true
,
in
:
!!
show
,
children
:
backdropElement
});
}
}
return
/*#__PURE__*/
_jsx
(
_Fragment
,
{
children
:
/*#__PURE__*/
ReactDOM
.
createPortal
(
/*#__PURE__*/
_jsxs
(
_Fragment
,
{
children
:
[
backdropElement
,
dialog
]
}),
container
)
});
});
Modal
.
displayName
=
'Modal'
;
export
default
Object
.
assign
(
Modal
,
{
Manager
:
ModalManager
});
Event Timeline
Log In to Comment