mirror of
https://github.com/wassname/talk.git
synced 2026-07-20 12:40:47 +08:00
[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:
committed by
Wyatt Johnson
parent
acb86f4b44
commit
e0a8f2e067
Generated
+5
@@ -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",
|
||||
|
||||
@@ -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>"`;
|
||||
Vendored
+16
@@ -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;
|
||||
}
|
||||
Reference in New Issue
Block a user