Merge branch 'next' into permalink

This commit is contained in:
Kiwi
2018-08-06 20:02:57 +02:00
committed by GitHub
6 changed files with 323 additions and 0 deletions
+102
View File
@@ -1925,6 +1925,15 @@
"@types/passport": "*"
}
},
"@types/prop-types": {
"version": "15.5.4",
"resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.5.4.tgz",
"integrity": "sha512-RnC6YeQDmDas7DToCbRWNntB9XpIR+sqg1zUqcCUxOJTBwGeSAPfTQaXqzyNND82FIBNY67r17FedDyaKRcHBQ==",
"dev": true,
"requires": {
"@types/react": "*"
}
},
"@types/query-string": {
"version": "6.1.0",
"resolved": "https://registry.npmjs.org/@types/query-string/-/query-string-6.1.0.tgz",
@@ -3001,6 +3010,41 @@
}
}
},
"awesome-typescript-loader": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/awesome-typescript-loader/-/awesome-typescript-loader-4.0.1.tgz",
"integrity": "sha512-lx6JJXtuNXyrK1DBx/+w6fbnbcfavMz0a2zszZ89yQ/NAAUE6GzIAtfQ2mkD96piClCoxLpbNpTkVi/H8FJn7w==",
"dev": true,
"requires": {
"chalk": "^2.3.1",
"enhanced-resolve": "3.3.0",
"loader-utils": "^1.1.0",
"lodash": "^4.17.4",
"micromatch": "^3.0.3",
"mkdirp": "^0.5.1",
"source-map-support": "^0.5.3"
},
"dependencies": {
"enhanced-resolve": {
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-3.3.0.tgz",
"integrity": "sha512-2qbxE7ek3YxPJ1ML6V+satHkzHpJQKWkRHmRx6mfAoW59yP8YH8BFplbegSP+u2hBd6B6KCOpvJQ3dZAP+hkpg==",
"dev": true,
"requires": {
"graceful-fs": "^4.1.2",
"memory-fs": "^0.4.0",
"object-assign": "^4.0.1",
"tapable": "^0.2.5"
}
},
"tapable": {
"version": "0.2.8",
"resolved": "https://registry.npmjs.org/tapable/-/tapable-0.2.8.tgz",
"integrity": "sha1-mTcqXJmb8t8WCvwNdL7U9HlIzSI=",
"dev": true
}
}
},
"aws-sign2": {
"version": "0.7.0",
"resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz",
@@ -18994,6 +19038,12 @@
"integrity": "sha1-635iZ1SN3t+4mcG5Dlc3RVnN234=",
"dev": true
},
"ramda": {
"version": "0.25.0",
"resolved": "https://registry.npmjs.org/ramda/-/ramda-0.25.0.tgz",
"integrity": "sha512-GXpfrYVPwx3K7RQ6aYT8KPS8XViSXUVJT1ONhoKPE9VAleW42YE+U+8VEyGWt41EnEQW7gwecYJriTI0pKoecQ==",
"dev": true
},
"randexp": {
"version": "0.4.6",
"resolved": "https://registry.npmjs.org/randexp/-/randexp-0.4.6.tgz",
@@ -19626,6 +19676,21 @@
"integrity": "sha512-MKucv9nU65BOPqIrClAFxqvpGCC4RdRpqp0P1YIb7C3yT6TQVdcoOlr0k4TDHvLQhbkwd3nbTxiDQMa3iDlZxg==",
"dev": true
},
"react-with-state-props": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/react-with-state-props/-/react-with-state-props-2.0.4.tgz",
"integrity": "sha512-tG2Rn/KXPXKy6RBhPeGMgR3JeSd11feNvQMR9ri2V6s8Tu8Q6Yz3pRD8xTOB+IzkEM2Vhf+iau7w2lki7hyHOQ==",
"dev": true,
"requires": {
"@types/prop-types": "^15.5.2",
"@types/react": "^16.0.40",
"awesome-typescript-loader": "^4.0.1",
"prop-types": "^15.6.1",
"ramda": "^0.25.0",
"source-map-loader": "^0.2.3",
"typescript": "^2.7.2"
}
},
"read-cache": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz",
@@ -21176,6 +21241,43 @@
"integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
"dev": true
},
"source-map-loader": {
"version": "0.2.3",
"resolved": "https://registry.npmjs.org/source-map-loader/-/source-map-loader-0.2.3.tgz",
"integrity": "sha512-MYbFX9DYxmTQFfy2v8FC1XZwpwHKYxg3SK8Wb7VPBKuhDjz8gi9re2819MsG4p49HDyiOSUKlmZ+nQBArW5CGw==",
"dev": true,
"requires": {
"async": "^2.5.0",
"loader-utils": "~0.2.2",
"source-map": "~0.6.1"
},
"dependencies": {
"json5": {
"version": "0.5.1",
"resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz",
"integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=",
"dev": true
},
"loader-utils": {
"version": "0.2.17",
"resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-0.2.17.tgz",
"integrity": "sha1-+G5jdNQyBabmxg6RlvF8Apm/s0g=",
"dev": true,
"requires": {
"big.js": "^3.1.3",
"emojis-list": "^2.0.0",
"json5": "^0.5.0",
"object-assign": "^4.0.1"
}
},
"source-map": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
"dev": true
}
}
},
"source-map-resolve": {
"version": "0.5.2",
"resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.2.tgz",
+1
View File
@@ -179,6 +179,7 @@
"react-responsive": "^4.1.0",
"react-test-renderer": "^16.4.1",
"react-timeago": "^4.1.9",
"react-with-state-props": "^2.0.4",
"recompose": "^0.27.1",
"relay-compiler": "github:coralproject/patched#relay-compiler",
"relay-compiler-language-typescript": "github:coralproject/patched#relay-compiler-language-typescript",
@@ -0,0 +1,44 @@
---
name: Popup
menu: UI Kit
---
import { Playground } from "docz"
import Popup from "./Popup"
import Button from "../Button"
import Flex from "../Flex"
import Container from "react-with-state-props"
# Popup
Declaratively control a popup.
## Basic usage
<Playground>
<Container
state={{ open: false, focus: false }}
render={props => (
<Flex itemGutter>
<Popup
href={"/static/js/src-core-client-ui-components-popup-popup.js"}
title="Coral Project"
features="menubar=0,resizable=0,width=500,height=550,top=200,left=500"
open={props.open}
focus={props.focus}
onFocus={() => props.setFocus(true)}
onBlur={() => props.setFocus(false)}
onClose={() => props.setOpen(false)}
/>
<Button onClick={() => props.setOpen(true)} variant="filled" color="primary" disabled={props.open}>
Open Popup
</Button>
<Button onClick={() => props.setOpen(false)} variant="outlined" disabled={!props.open}>
Close Popup
</Button>
<Button onClick={() => props.setFocus(true)} variant="outlined" disabled={!props.open}>
Focus Popup
</Button>
</Flex>
)}/>
</Playground>
@@ -0,0 +1,174 @@
import { Component } from "react";
interface PopupProps {
open?: boolean;
focus?: boolean;
onFocus?: (e: FocusEvent) => void;
onBlur?: (e: FocusEvent) => void;
onLoad?: (e: Event) => void;
onUnload?: (e: Event) => void;
onClose?: () => void;
href: string;
features?: string;
title?: string;
}
export default class Popup extends Component<PopupProps> {
private ref: Window | null = null;
private detectCloseInterval: any = null;
private resetCallbackInterval: any = null;
constructor(props: PopupProps) {
super(props);
if (props.open) {
this.openWindow(props);
}
}
private openWindow(props = this.props) {
this.ref = window.open(props.href, props.title, props.features);
this.setCallbacks();
// For some reasons IE needs a timeout before setting the callbacks...
setTimeout(() => this.setCallbacks(), 1000);
}
private setCallbacks() {
this.ref!.onload = e => {
if (this.detectCloseInterval) {
clearInterval(this.detectCloseInterval);
}
this.onLoad(e);
};
this.ref!.onfocus = e => {
this.onFocus(e);
};
this.ref!.onblur = e => {
this.onBlur(e);
};
// Use `onunload` instead of `onbeforeunload` which is not supported in iOS
// Safari.
this.ref!.onunload = e => {
this.onUnload(e);
if (this.resetCallbackInterval) {
clearInterval(this.resetCallbackInterval);
}
this.resetCallbackInterval = setInterval(() => {
try {
if (this.ref && this.ref.onload === null) {
if (this.resetCallbackInterval) {
clearInterval(this.resetCallbackInterval);
}
this.resetCallbackInterval = null;
this.setCallbacks();
}
} catch (err) {
// We could be getting a security exception here if the login page
// gets redirected to another domain to authenticate.
}
}, 50);
if (this.detectCloseInterval) {
clearInterval(this.detectCloseInterval);
}
this.detectCloseInterval = setInterval(() => {
if (!this.ref || this.ref.closed) {
if (this.detectCloseInterval) {
clearInterval(this.detectCloseInterval);
}
this.detectCloseInterval = null;
this.onClose();
}
}, 50);
};
}
private closeWindow() {
if (this.ref) {
if (!this.ref.closed) {
this.ref.close();
}
this.ref = null;
}
}
private focusWindow() {
if (this.ref && !this.ref.closed) {
this.ref.focus();
}
}
private blurWindow() {
if (this.ref && !this.ref.closed) {
this.ref.blur();
}
}
private onLoad = (e: Event) => {
if (this.props.onLoad) {
this.props.onLoad(e);
}
};
private onUnload = (e: Event) => {
if (this.props.onUnload) {
this.props.onUnload(e);
}
};
private onClose = () => {
if (this.props.onClose) {
this.props.onClose();
}
};
private onFocus = (e: FocusEvent) => {
if (this.props.onFocus) {
this.props.onFocus(e);
}
};
private onBlur = (e: FocusEvent) => {
if (this.props.onBlur) {
this.props.onBlur(e);
}
};
public componentWillReceiveProps(nextProps: PopupProps) {
if (nextProps.open && !this.ref) {
this.openWindow(nextProps);
}
if (this.props.open && !nextProps.open) {
this.closeWindow();
}
if (!this.props.focus && nextProps.focus) {
this.focusWindow();
}
if (this.props.focus && !nextProps.focus) {
this.blurWindow();
}
if (this.props.href !== nextProps.href) {
this.ref!.location.href = nextProps.href;
}
}
public componentWillUnmount() {
this.closeWindow();
}
public render() {
return null;
}
}
@@ -0,0 +1 @@
export { default } from "./Popup";
+1
View File
@@ -10,3 +10,4 @@ export { default as Flex } from "./Flex";
export { default as MatchMedia } from "./MatchMedia";
export { default as TrapFocus } from "./TrapFocus";
export { default as ClickOutside } from "./ClickOutside";
export { default as Popup } from "./Popup";