[next] ClickOutside Component (#1757)

* working on the tests

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

* 'next' of github.com:coralproject/talk: (36 commits)
  [next] Implement AriaInfo (#1756)
  e render props for TrapFocus (#1755)
  [ToggleShow] Fix typo and better description (#1753)
  Fix wrong hour pluralization
  Implement button active state
  Styling fixes
  Fix Playground
  Commit snapshots
  Harmonize typography
  Fix Flex margin bug and add examples
  Update package-lock.json
  Use explicit export
  Implement ButtonIcon component
  Remove wrong ref prop
  Implement new button api
  Read env in watchers.ts
  updated tests
  Update ToggleShow.spec.tsx
  ToggleShow Component
  Fix CI thanks to wyatt
  ...

docz added

Added simulant

Added simulant

unnused

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

* 'clickoutside' of github.com:coralproject/talk: (40 commits)
  Added simulant
  Added simulant
  docz added
  [next] Implement AriaInfo (#1756)
  e render props for TrapFocus (#1755)
  [ToggleShow] Fix typo and better description (#1753)
  Fix wrong hour pluralization
  Implement button active state
  Styling fixes
  Fix Playground
  Commit snapshots
  Harmonize typography
  Fix Flex margin bug and add examples
  Update package-lock.json
  Use explicit export
  Implement ButtonIcon component
  Remove wrong ref prop
  Implement new button api
  Read env in watchers.ts
  working on the tests
  ...

unnused

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

* 'clickoutside' of github.com:coralproject/talk: (42 commits)
  unnused
  working on the tests
  Added simulant
  Added simulant
  docz added
  [next] Implement AriaInfo (#1756)
  e render props for TrapFocus (#1755)
  [ToggleShow] Fix typo and better description (#1753)
  Fix wrong hour pluralization
  Implement button active state
  Styling fixes
  Fix Playground
  Commit snapshots
  Harmonize typography
  Fix Flex margin bug and add examples
  Update package-lock.json
  Use explicit export
  Implement ButtonIcon component
  Remove wrong ref prop
  Implement new button api
  ...

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

* 'clickoutside' of github.com:coralproject/talk: (42 commits)
  unnused
  working on the tests
  Added simulant
  Added simulant
  docz added
  [next] Implement AriaInfo (#1756)
  e render props for TrapFocus (#1755)
  [ToggleShow] Fix typo and better description (#1753)
  Fix wrong hour pluralization
  Implement button active state
  Styling fixes
  Fix Playground
  Commit snapshots
  Harmonize typography
  Fix Flex margin bug and add examples
  Update package-lock.json
  Use explicit export
  Implement ButtonIcon component
  Remove wrong ref prop
  Implement new button api
  ...

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

* 'clickoutside' of github.com:coralproject/talk: (43 commits)
  working on the tests
  unnused
  working on the tests
  Added simulant
  Added simulant
  docz added
  [next] Implement AriaInfo (#1756)
  e render props for TrapFocus (#1755)
  [ToggleShow] Fix typo and better description (#1753)
  Fix wrong hour pluralization
  Implement button active state
  Styling fixes
  Fix Playground
  Commit snapshots
  Harmonize typography
  Fix Flex margin bug and add examples
  Update package-lock.json
  Use explicit export
  Implement ButtonIcon component
  Remove wrong ref prop
  ...

* Implement passing tests

* Use html as snapshot

* Refactor and simplify test

* Remove unused import

* ts

* simulant moved to devdeps
This commit is contained in:
Belén Curcio
2018-07-25 20:33:29 +00:00
committed by Wyatt Johnson
parent acb86f4b44
commit e0a8f2e067
7 changed files with 147 additions and 0 deletions
+5
View File
@@ -20221,6 +20221,11 @@
}
}
},
"simulant": {
"version": "0.2.2",
"resolved": "https://registry.npmjs.org/simulant/-/simulant-0.2.2.tgz",
"integrity": "sha1-8bzlJxK2p6DaON392n6DsgsdoB4="
},
"sinon": {
"version": "6.1.3",
"resolved": "https://registry.npmjs.org/sinon/-/sinon-6.1.3.tgz",
+1
View File
@@ -146,6 +146,7 @@
"relay-runtime": "github:coralproject/patched#relay-runtime",
"relay-test-utils": "github:coralproject/patched#relay-test-utils",
"sane": "^2.5.2",
"simulant": "^0.2.2",
"sinon": "^6.1.3",
"style-loader": "^0.21.0",
"ts-jest": "^23.0.0",
@@ -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,33 @@
import React from "react";
import { findDOMNode } from "react-dom";
interface Props {
onClickOutside: () => void;
children: React.ReactNode;
}
class ClickOutside extends React.Component<Props> {
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>"`;
+16
View File
@@ -0,0 +1,16 @@
declare module "simulant" {
type SimulantEvent = {};
interface Simulant {
(event: string, extendedParams: Record<string, any>): SimulantEvent;
fire(
target: HTMLElement,
event: string | SimulantEvent,
extendedParams?: Record<string, any>
): void;
polyfill(): void;
}
const simulant: Simulant;
export default simulant;
}