mirror of
https://github.com/wassname/talk.git
synced 2026-07-15 11:26:58 +08:00
Merge branch 'permalink' of https://github.com/coralproject/talk into permalink
This commit is contained in:
@@ -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