Skip to content

Instantly share code, notes, and snippets.

@zachj0hnston
Created August 23, 2018 15:11
Show Gist options
  • Save zachj0hnston/370aa6dfa7f16a4682d39fd656ca0508 to your computer and use it in GitHub Desktop.
Save zachj0hnston/370aa6dfa7f16a4682d39fd656ca0508 to your computer and use it in GitHub Desktop.
import * as React from "react";
import { PropertyControls, ControlType } from "framer";
export class ClickOutside extends React.Component<Props> {
static defaultProps = {
width: 100,
height: 100,
}
static propertyControls: PropertyControls = {
}
state = {
isSelected: false,
}
componentWillMount() {
document.addEventListener('mousedown', this.handleClick, false);
}
componentWillUnmount() {
document.removeEventListener('mousedown', this.handleClick, false);
}
componentWillReceiveProps(nextProps) {
this.setState({isSelected: nextProps.isSelected});
}
handleClick = (e) => {
if (this.node.contains(e.target)) {
this.setState({isSelected: true);
return;
}
this.setState({isSelected: false);
}
render() {
return (
<div ref={node => this.node = node}>
{this.state.isSelected? "Yay! : "Click me!" }
</div>
);
}
}
@zachj0hnston
Copy link
Author

How does this work??

  1. We set ref={node => this.node = node} on the element we want to target.
  2. When the component mounts, we bind an event listener for mousedown
  3. When the component unmounts, we remove that listener
  4. That listener fires handleClick which checks where the click happens and if it's inside does one thing and if it's outside does another.

That's it! The componentWillReceiveProps method is there to turn a prop into a state but you don't need it if you don't want a user-facing controller.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment