From 401c8aeb9d07e77662dd969dc47bbffbbe097dbb Mon Sep 17 00:00:00 2001 From: Cezar Andrew Villegas Santarin Date: Mon, 22 Jul 2019 16:04:43 +0800 Subject: [PATCH] Disable default centering (#47) and improve typings --- README.md | 2 +- package-lock.json | 16 ++--- src/NewWindow.js | 66 ++++++++++--------- stories/default.stories.js | 2 +- stories/features-prop.stories.js | 1 - .../position-centered-to-parent.stories.js | 62 +++++++++++++++++ .../position-centered-to-screen.stories.js | 62 +++++++++++++++++ types/NewWindow.d.ts | 10 ++- 8 files changed, 173 insertions(+), 48 deletions(-) create mode 100644 stories/position-centered-to-parent.stories.js create mode 100644 stories/position-centered-to-screen.stories.js diff --git a/README.md b/README.md index 8a6d00d..528aff3 100644 --- a/README.md +++ b/README.md @@ -45,7 +45,7 @@ The `children` contents is what will be rendered into the new popup window. In t | `features` | `Object` | `{}` | The set of window features ([more details on `windowFeatures`](https://developer.mozilla.org/en-US/docs/Web/API/Window/open#Window_features)). | | `onUnload` | `Function` | `undefined` | A function to be triggered before the new window unload. | | `onBlock` | `Function` | `undefined` | A function to be triggered when the new window could not be opened. | - | `center` | `String` | `parent` | Indicate how to center the new window. Valid values are: `parent` or `screen`. `parent` will center the new window according to its _parent_ window. `screen` will center the new window according to the _screen_. | + | `center` | `String` | `undefined` | Indicate how to center the new window. Valid values are: `parent` or `screen`. `parent` will center the new window according to its _parent_ window. `screen` will center the new window according to the _screen_. | | `copyStyles` | `Boolean` | `true` | If specified, copy styles from parent window's document. | ## Tests diff --git a/package-lock.json b/package-lock.json index b13e088..8efd462 100644 --- a/package-lock.json +++ b/package-lock.json @@ -6645,8 +6645,7 @@ "console-control-strings": { "version": "1.1.0", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "core-util-is": { "version": "1.0.2", @@ -6806,7 +6805,6 @@ "version": "2.3.5", "bundled": true, "dev": true, - "optional": true, "requires": { "safe-buffer": "^5.1.2", "yallist": "^3.0.0" @@ -6825,7 +6823,6 @@ "version": "0.5.1", "bundled": true, "dev": true, - "optional": true, "requires": { "minimist": "0.0.8" } @@ -6919,7 +6916,6 @@ "version": "1.4.0", "bundled": true, "dev": true, - "optional": true, "requires": { "wrappy": "1" } @@ -7005,8 +7001,7 @@ "safe-buffer": { "version": "5.1.2", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "safer-buffer": { "version": "2.1.2", @@ -7042,7 +7037,6 @@ "version": "1.0.2", "bundled": true, "dev": true, - "optional": true, "requires": { "code-point-at": "^1.0.0", "is-fullwidth-code-point": "^1.0.0", @@ -7106,14 +7100,12 @@ "wrappy": { "version": "1.0.2", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "yallist": { "version": "3.0.3", "bundled": true, - "dev": true, - "optional": true + "dev": true } } }, diff --git a/src/NewWindow.js b/src/NewWindow.js index 54a5d5a..ff5b99b 100644 --- a/src/NewWindow.js +++ b/src/NewWindow.js @@ -24,7 +24,6 @@ class NewWindow extends React.PureComponent { onBlock: null, onOpen: null, onUnload: null, - center: 'parent', copyStyles: true } @@ -63,37 +62,40 @@ class NewWindow extends React.PureComponent { const { url, title, name, features, onBlock, onOpen, center } = this.props // Prepare position of the new window to be centered against the 'parent' window or 'screen'. - if ( - typeof center === 'string' && - (features.width === undefined || features.height === undefined) - ) { - console.warn( - 'width and height window features must be present when a center prop is provided' - ) - } else if (center === 'parent') { - features.left = - window.top.outerWidth / 2 + window.top.screenX - features.width / 2 - features.top = - window.top.outerHeight / 2 + window.top.screenY - features.height / 2 - } else if (center === 'screen') { - const screenLeft = - window.screenLeft !== undefined ? window.screenLeft : window.screen.left - const screenTop = - window.screenTop !== undefined ? window.screenTop : window.screen.top - - const width = window.innerWidth - ? window.innerWidth - : document.documentElement.clientWidth - ? document.documentElement.clientWidth - : window.screen.width - const height = window.innerHeight - ? window.innerHeight - : document.documentElement.clientHeight - ? document.documentElement.clientHeight - : window.screen.height - - features.left = width / 2 - features.width / 2 + screenLeft - features.top = height / 2 - features.height / 2 + screenTop + if (typeof center === 'string') { + if (features.width == null || features.height == null) { + console.warn( + 'react-new-window: "width" and "height" window features must be present when a center prop is provided.' + ) + } else if (center === 'parent') { + features.left = + window.top.outerWidth / 2 + window.top.screenX - features.width / 2 + features.top = + window.top.outerHeight / 2 + window.top.screenY - features.height / 2 + } else if (center === 'screen') { + const screenLeft = + window.screenLeft != null ? window.screenLeft : window.screen.left + const screenTop = + window.screenTop != null ? window.screenTop : window.screen.top + + const width = window.innerWidth + ? window.innerWidth + : document.documentElement.clientWidth + ? document.documentElement.clientWidth + : window.screen.width + const height = window.innerHeight + ? window.innerHeight + : document.documentElement.clientHeight + ? document.documentElement.clientHeight + : window.screen.height + + features.left = width / 2 - features.width / 2 + screenLeft + features.top = height / 2 - features.height / 2 + screenTop + } else { + console.warn( + 'react-new-window: Invalid `center` string provided. Only these strings are permitted: "parent", "screen".' + ) + } } // Open a new window. diff --git a/stories/default.stories.js b/stories/default.stories.js index c3d838b..fbeac65 100644 --- a/stories/default.stories.js +++ b/stories/default.stories.js @@ -36,7 +36,7 @@ class DefaultStory extends React.PureComponent { {opened && ( this.newWindowUnloaded()} - features={{ left: 200, top: 200, width: 400, height: 400 }} + features={{ width: 400, height: 400 }} >

Hi 👋

Counting here as well {count}...

diff --git a/stories/features-prop.stories.js b/stories/features-prop.stories.js index f80f313..86fd998 100644 --- a/stories/features-prop.stories.js +++ b/stories/features-prop.stories.js @@ -97,7 +97,6 @@ class FeaturesPropStory extends React.PureComponent { {opened && ( this.newWindowUnloaded()} > diff --git a/stories/position-centered-to-parent.stories.js b/stories/position-centered-to-parent.stories.js new file mode 100644 index 0000000..4b4ab73 --- /dev/null +++ b/stories/position-centered-to-parent.stories.js @@ -0,0 +1,62 @@ +import React from 'react' +import { action } from '@storybook/addon-actions' +import NewWindow from '../src/NewWindow' +import Button from './components/Button' +import Container from './components/Container' +import { storiesOf } from '@storybook/react' + +const stories = storiesOf('react-new-window', module) + +class CenteredToParentStory extends React.PureComponent { + state = { + opened: false, + count: 0 + } + + componentDidMount() { + this.interval = setInterval(() => { + this.setState(prevState => ({ count: prevState.count + 1 })) + }, 1000) + } + + componentWillUnmount() { + clearInterval(this.interval) + } + + render() { + const { opened, count } = this.state + return ( + +

React New Window

+

prop: center: "parent"

+

Counting {count}...

+ + {opened && ( + this.newWindowUnloaded()} + center="parent" + features={{ left: 200, top: 200, width: 400, height: 400 }} + > +

Hi 👋

+

Counting here as well {count}...

+ +
+ )} +
+ ) + } + + toggleOpened() { + action(this.state.opened ? 'Closing the window' : 'Opening the window')() + this.setState(prevState => ({ opened: !prevState.opened })) + } + + newWindowUnloaded() { + action('Window unloaded')() + this.setState({ opened: false }) + } +} + +stories.add('Position: Centered To Parent', () => ) diff --git a/stories/position-centered-to-screen.stories.js b/stories/position-centered-to-screen.stories.js new file mode 100644 index 0000000..7a8e35b --- /dev/null +++ b/stories/position-centered-to-screen.stories.js @@ -0,0 +1,62 @@ +import React from 'react' +import { action } from '@storybook/addon-actions' +import NewWindow from '../src/NewWindow' +import Button from './components/Button' +import Container from './components/Container' +import { storiesOf } from '@storybook/react' + +const stories = storiesOf('react-new-window', module) + +class CenteredToScreenStory extends React.PureComponent { + state = { + opened: false, + count: 0 + } + + componentDidMount() { + this.interval = setInterval(() => { + this.setState(prevState => ({ count: prevState.count + 1 })) + }, 1000) + } + + componentWillUnmount() { + clearInterval(this.interval) + } + + render() { + const { opened, count } = this.state + return ( + +

React New Window

+

prop: center: "screen"

+

Counting {count}...

+ + {opened && ( + this.newWindowUnloaded()} + center="screen" + features={{ left: 200, top: 200, width: 400, height: 400 }} + > +

Hi 👋

+

Counting here as well {count}...

+ +
+ )} +
+ ) + } + + toggleOpened() { + action(this.state.opened ? 'Closing the window' : 'Opening the window')() + this.setState(prevState => ({ opened: !prevState.opened })) + } + + newWindowUnloaded() { + action('Window unloaded')() + this.setState({ opened: false }) + } +} + +stories.add('Position: Centered To Screen', () => ) diff --git a/types/NewWindow.d.ts b/types/NewWindow.d.ts index 0d7563f..e68a548 100644 --- a/types/NewWindow.d.ts +++ b/types/NewWindow.d.ts @@ -13,6 +13,14 @@ declare module 'react-new-window' { export interface IWindowFeatures { height: number width: number + left: number + top: number + menubar: boolean + toolbar: boolean + scrollbars: boolean + location: boolean + status: boolean + resizable: boolean [i: string]: boolean | number | string } @@ -40,7 +48,7 @@ declare module 'react-new-window' { /** * The set of window features. */ - features?: IWindowFeatures + features?: Partial /** * A function to be triggered before the new window unload.