Skip to content

Instantly share code, notes, and snippets.

@dabbott
Last active February 6, 2019 18:48
Show Gist options
  • Select an option

  • Save dabbott/904dd35b081df8d945d046274b78486a to your computer and use it in GitHub Desktop.

Select an option

Save dabbott/904dd35b081df8d945d046274b78486a to your computer and use it in GitHub Desktop.
import React, { Component } from "react";
import "./App.css";
import ChecklistCombo from "./generated/components/ChecklistCombo";
import ChecklistCard from "./generated/components/ChecklistCard";
import ChecklistItemCard from "./generated/components/ChecklistItemCard";
function compareNodePosition(a, b) {
if (!a || !b) return "implementation_specific";
const documentPosition = a.compareDocumentPosition(b);
if (documentPosition & Node.DOCUMENT_POSITION_CONTAINS) return "contains";
if (documentPosition & Node.DOCUMENT_POSITION_CONTAINED_BY)
return "contained_by";
if (documentPosition & Node.DOCUMENT_POSITION_PRECEDING) return "preceding";
if (documentPosition & Node.DOCUMENT_POSITION_FOLLOWING) return "following";
return "implementation_specific";
}
class App extends Component {
state = {
checked: false,
tabIndex: 0
};
checklistCard = React.createRef();
checklistCombo = React.createRef();
wrapper = React.createRef();
previousActiveElement = null;
handleDocumentFocusChange = e => {
this.previousActiveElement = e.target;
if (this.wrapper.current) {
this.setState({
tabIndex: this.wrapper.current.contains(e.target) ? -1 : 0
});
}
console.log("target", e.target);
};
componentDidMount() {
document.addEventListener("focus", this.handleDocumentFocusChange, true);
}
componentWillUnmount() {
document.removeEventListener("focus", this.handleDocumentFocusChange, true);
}
render() {
return (
<div style={{ padding: 20 }} className="App">
<div style={styles.focusTrap} tabIndex={0} />
<div
ref={this.wrapper}
tabIndex={this.state.tabIndex}
style={{ padding: 20 }}
onFocus={e => {
if (e.target === this.wrapper.current) {
const position = compareNodePosition(
document.activeElement,
this.previousActiveElement
);
switch (position) {
case "preceding":
case "implementation_specific":
this.checklistCard.current.focus();
e.stopPropagation();
e.preventDefault();
break;
case "following":
this.checklistCard.current.focusLast();
e.stopPropagation();
e.preventDefault();
break;
default:
break;
}
}
}}
>
<ChecklistCard ref={this.checklistCard} />
</div>
<div style={styles.focusTrap} tabIndex={0} />
</div>
);
}
}
export default App;
const styles = {
focusTrap: {
height: 10,
background: "lightgrey",
marginTop: 20,
marginBottom: 20
}
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment