mirror of
https://github.com/wassname/talk.git
synced 2026-07-02 03:00:45 +08:00
Merge branch 'next' into permalink
This commit is contained in:
Generated
+102
@@ -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",
|
||||
|
||||
@@ -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";
|
||||
@@ -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";
|
||||
|
||||
Reference in New Issue
Block a user