-
Notifications
You must be signed in to change notification settings - Fork 66
/
Lock.js
94 lines (81 loc) 路 2.16 KB
/
Lock.js
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
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import FocusTrap from './Trap';
const hidden = {
width: '1px',
height: '0px',
padding: 0,
overflow: 'hidden',
};
class FocusLock extends Component {
state = {
observed: undefined,
};
componentDidUpdate(prevProps) {
if (prevProps.disabled && !this.props.disabled) {
this.originalFocusedElement = null;
}
}
componentWillUnmount() {
if (
this.props.returnFocus &&
this.originalFocusedElement &&
this.originalFocusedElement.focus
) {
this.originalFocusedElement.focus();
}
}
onActivation = () => {
this.originalFocusedElement = this.originalFocusedElement || document.activeElement;
};
setObserveNode = observed =>
this.setState({
observed,
});
update = () =>
this.setState(prevState => ({
escapeAttempts: prevState.escapeAttempts + 1,
}));
originalFocusedElement = null;
render() {
const { children, disabled, noFocusGuards, allowTextSelection } = this.props;
const { observed } = this.state;
return (
<div>
{!noFocusGuards && [
<div key="guard-first" tabIndex={disabled ? -1 : 0} style={hidden} />, // nearest focus guard
<div key="guard-nearest" tabIndex={disabled ? -1 : 1} style={hidden} />, // first tabbed element guard
]}
<div
ref={this.setObserveNode}
onBlur={this.onTrapBlur}
>
<FocusTrap
observed={observed}
disabled={disabled}
allowTextSelection={allowTextSelection}
onActivation={this.onActivation}
>
{children}
</FocusTrap>
</div>
{!noFocusGuards && <div tabIndex={disabled ? -1 : 0} style={hidden} />}
</div>
);
}
}
FocusLock.propTypes = {
children: PropTypes.node.isRequired,
disabled: PropTypes.bool,
returnFocus: PropTypes.bool,
noFocusGuards: PropTypes.bool,
allowTextSelection: PropTypes.bool,
};
FocusLock.defaultProps = {
disabled: false,
returnFocus: false,
sandboxed: false,
noFocusGuards: false,
allowTextSelection: false,
};
export default FocusLock;