Removing old implementation of attachment

Tiny refactor

Merge branch 'next' of github.com:coralproject/talk into permalink

* 'next' of github.com:coralproject/talk:
  [next] ClickOutside Component (#1757)

Support for ClickOutside
This commit is contained in:
Belén Curcio
2018-07-25 19:44:25 -03:00
parent 906940f152
commit 8b56e408f8
19 changed files with 195 additions and 117 deletions
@@ -0,0 +1,27 @@
---
name: ClickOutside
menu: UI Kit
---
import { Playground, PropsTable } from 'docz'
import ClickOutside from './ClickOutside'
import Button from '../Button/Button'
# ClickOutside
A Component to handle click events outside the children components.
## Basic usage
Wrap a Component with `<ClickOutside>` and pass a function to `onClickOutside`. This function will trigger when the user
clicks outside the component.
### Test
Click the blue background. It should trigger an alert. Nothing should happen if you click the button.
<Playground>
<div style={{background: 'blue', padding: '10px'}}>
<ClickOutside onClickOutside={() => alert('You clicked outside!')}>
<Button variant="filled">Push Me</Button>
</ClickOutside>
</div>
</Playground>
@@ -0,0 +1,62 @@
import { mount } from "enzyme";
import React from "react";
import simulant from "simulant";
import sinon from "sinon";
import ClickOutside from "./ClickOutside";
let container: HTMLElement;
beforeAll(() => {
container = document.createElement("div");
document.body.appendChild(container);
});
afterAll(() => {
document.body.removeChild(container);
});
it("should render correctly", () => {
const noop = () => null;
const wrapper = mount(
<ClickOutside onClickOutside={noop}>
<span>Hello World!</span>
</ClickOutside>
);
expect(wrapper.html()).toMatchSnapshot();
wrapper.unmount();
});
it("should detect click outside", () => {
const onClickOutside = sinon.spy();
const wrapper = mount(
<ClickOutside onClickOutside={onClickOutside}>
<span>Hello World!</span>
</ClickOutside>,
{
attachTo: container,
}
);
simulant.fire(container, "click");
expect(onClickOutside.calledOnce).toEqual(true);
wrapper.unmount();
});
it("should ignore click inside", () => {
const onClickOutside = sinon.spy();
const wrapper = mount(
<ClickOutside onClickOutside={onClickOutside}>
<button id="click-outside-test-button">Push Me</button>
</ClickOutside>,
{
attachTo: container,
}
);
const target = document.getElementById("click-outside-test-button")!;
simulant.fire(target, "click");
expect(onClickOutside.calledOnce).toEqual(false);
wrapper.unmount();
});
@@ -0,0 +1,34 @@
import React from "react";
import { findDOMNode } from "react-dom";
export interface ClickOutsideProps {
onClickOutside: () => void;
children: React.ReactNode;
}
export class ClickOutside extends React.Component<ClickOutsideProps> {
public domNode: Element | null = null;
public handleClick = (e: MouseEvent) => {
const { onClickOutside } = this.props;
if (!e || !this.domNode!.contains(e.target as HTMLInputElement)) {
// tslint:disable-next-line:no-unused-expression
onClickOutside && onClickOutside();
}
};
public componentDidMount() {
this.domNode = findDOMNode(this) as Element;
document.addEventListener("click", this.handleClick, true);
}
public componentWillUnmount() {
document.removeEventListener("click", this.handleClick, true);
}
public render() {
return this.props.children;
}
}
export default ClickOutside;
@@ -0,0 +1,3 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`should render correctly 1`] = `"<span>Hello World!</span>"`;
@@ -0,0 +1 @@
export { default, ClickOutside } from "./ClickOutside";