From 8acd0ae29fbec16a1d80aa164a5c0f1ae9a7a267 Mon Sep 17 00:00:00 2001 From: boblinthorst Date: Mon, 23 Apr 2018 14:51:26 +0200 Subject: [PATCH 01/16] working version of a basic react modal --- components/index.js | 1 + components/modal/ModalHeader.js | 30 +++++++++ components/modal/index.js | 58 ++++++++++++++++++ components/modal/style.scss | 105 ++++++++++++++++++++++++++++++++ package.json | 1 + 5 files changed, 195 insertions(+) create mode 100644 components/modal/ModalHeader.js create mode 100644 components/modal/index.js create mode 100644 components/modal/style.scss diff --git a/components/index.js b/components/index.js index 38731f65401287..1933ec52135ddf 100644 --- a/components/index.js +++ b/components/index.js @@ -25,6 +25,7 @@ export { default as KeyboardShortcuts } from './keyboard-shortcuts'; export { default as MenuGroup } from './menu-group'; export { default as MenuItem } from './menu-item'; export { default as MenuItemsChoice } from './menu-items-choice'; +export { default as Modal } from './modal'; export { default as ScrollLock } from './scroll-lock'; export { NavigableMenu, TabbableContainer } from './navigable-container'; export { default as Notice } from './notice'; diff --git a/components/modal/ModalHeader.js b/components/modal/ModalHeader.js new file mode 100644 index 00000000000000..7e4167d85ceb88 --- /dev/null +++ b/components/modal/ModalHeader.js @@ -0,0 +1,30 @@ +import { NavigableToolbar } from '../../editor/components'; +import { IconButton } from '@wordpress/components'; +import { __ } from '@wordpress/i18n'; +import './style.scss'; + +const ModalHeader = ( { icon, title, onClose, closeLabel } ) => { + const label = closeLabel ? closeLabel : __( 'Close window' ); + + return ( + +
+ +

+ { title } +

+
+ +
+ ); +}; + +export default ModalHeader; \ No newline at end of file diff --git a/components/modal/index.js b/components/modal/index.js new file mode 100644 index 00000000000000..27dbd67e822a29 --- /dev/null +++ b/components/modal/index.js @@ -0,0 +1,58 @@ +/** + * WordPress dependencies + */ +import { Component } from '@wordpress/element'; + +/** + * Internal dependencies + */ +import './style.scss'; + +/** + * External dependencies + */ +import ReactModal from 'react-modal'; + +ReactModal.setAppElement( document.getElementById( 'wpwrap' ) ); + +export default class Modal extends Component { + constructor( props ) { + super( props ); + + this.state = { + isOpen: true, + height: window.innerHeight - 32, + }; + + this.updateWindowHeight = this.updateWindowHeight.bind( this ); + this.onClose = this.onClose.bind( this ); + } + + componentDidMount() { + window.addEventListener( 'resize', this.updateWindowHeight ); + } + + componentWillUnmount() { + window.removeEventListener( 'resize', this.updateWindowHeight ); + } + + updateWindowHeight() { + this.setState( { + height: window.innerHeight - 32, + } ); + } + + onClose() { + this.setState( { + isOpen: false, + } ); + } + + render() { + const { children } = this.props; + return + { children } + ; + } +} \ No newline at end of file diff --git a/components/modal/style.scss b/components/modal/style.scss new file mode 100644 index 00000000000000..9eb66df01946bc --- /dev/null +++ b/components/modal/style.scss @@ -0,0 +1,105 @@ +.edit-post-plugin-screen-takeover__editor-screen-takeover { + position: absolute; + top: 50%; + left: 50%; + right: auto; + bottom: auto; + width: auto; + max-width: 90%; + max-height: 90%; + min-width: 75%; + min-height: 75%; + border: 0; + border-radius: 0; + margin-right: -50%; + transform: translate(-50%, -50%); + background-color: #fff; + outline: none; + box-shadow: 0 3px 25px #000; + + // In small screens the content needs to be full width. + @media ( max-width: #{ ( $break-small ) } ) { + position: fixed; + top: 0; + bottom: 0; + right: 0; + left: 0; + margin: 0; + transform: initial; + max-width: none; + max-height: none; + } +} + +.edit-post-plugin-screen-takeover__editor-screen-takeover-overlay { + position: fixed; + top: 0; + left: 0; + right: 0; + bottom: 0; + background-color: rgba(0, 0, 0, 0.6); + z-index: 999999; + // on mobile the main content area has to scroll + // otherwise you can invoke the overscroll bounce on the non-scrolling container, causing (ノಠ益ಠ)ノ彡┻━┻ + @include break-small { + position: fixed; + top: $admin-bar-height-big; + } + + @include break-medium() { + top: $admin-bar-height; + } +} + +@include editor-left('.edit-post-plugin-screen-takeover__editor-screen-takeover-overlay'); + +// We prevent scrolling of the body when the React Modal screen takeover is opened. +body.ReactModal__Body--open { + overflow-y: hidden; +} + +// The modal needs a separate header that needs its own styling. +.edit-post-plugin-screen-takeover__editor-screen-takeover-header { + height: $header-height; + border-bottom: 1px solid $light-gray-500; + padding: 10px; + display: flex; + flex-direction: row; + align-items: stretch; + justify-content: space-between; + z-index: z-index( '.edit-post-header' ); + left: 0; + right: 0; + + div { + align-items: center; + flex-grow: 1; + display: flex; + flex-direction: row; + justify-content: left; + + h1 { + font-size: 1em; + font-weight: normal; + padding-left: 5px; + } + + span { + display: inline-block; + } + + svg { + max-width: $icon-button-size; + max-height: $icon-button-size; + padding: 8px; + } + } +} + +// The modal needs a separate header that needs its own styling. +.edit-post-plugin-screen-takeover__editor-screen-takeover-content { + height: calc( 100% - #{ $header-height } ); + overflow: auto; + padding: 10px 20px 5px 20px; + position: absolute; +} \ No newline at end of file diff --git a/package.json b/package.json index e23656843c165f..305f7bfdc03608 100644 --- a/package.json +++ b/package.json @@ -44,6 +44,7 @@ "react-color": "2.13.4", "react-datepicker": "0.61.0", "react-dom": "16.3.0", + "react-modal": "3.4.2", "redux": "3.7.2", "redux-multi": "0.1.12", "redux-optimist": "1.0.0", From 7aa0da0b3dc90d46740af022448c033163f1ae35 Mon Sep 17 00:00:00 2001 From: boblinthorst Date: Mon, 23 Apr 2018 15:09:49 +0200 Subject: [PATCH 02/16] switched export to bottom --- components/modal/index.js | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/components/modal/index.js b/components/modal/index.js index 27dbd67e822a29..afcb56d530899f 100644 --- a/components/modal/index.js +++ b/components/modal/index.js @@ -15,7 +15,7 @@ import ReactModal from 'react-modal'; ReactModal.setAppElement( document.getElementById( 'wpwrap' ) ); -export default class Modal extends Component { +class Modal extends Component { constructor( props ) { super( props ); @@ -50,9 +50,15 @@ export default class Modal extends Component { render() { const { children } = this.props; - return { children } ; } -} \ No newline at end of file +} + +export default Modal; From 354537eb1670fc42df5c3b0bfa51598aa7b02d97 Mon Sep 17 00:00:00 2001 From: boblinthorst Date: Mon, 23 Apr 2018 15:32:35 +0200 Subject: [PATCH 03/16] Added part of the props --- components/modal/index.js | 29 ++++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/components/modal/index.js b/components/modal/index.js index afcb56d530899f..8b0f688ec76923 100644 --- a/components/modal/index.js +++ b/components/modal/index.js @@ -49,16 +49,31 @@ class Modal extends Component { } render() { - const { children } = this.props; + const { + isOpen, + render, + className, + overlayClassName, + ariaLabelledBy, + children } = this.props; + return + isOpen={ isOpen } + render={ render } + className={ className } + overlayClassName={ overlayClassName } + aria-labelledby={ ariaLabelledBy }> { children } ; } } -export default Modal; +Modal.defaultProps = { + isOpen: true, + render: true, + className: 'edit-post-plugin-screen-takeover__editor-screen-takeover', + overlayClassName: 'edit-post-plugin-screen-takeover__editor-screen-takeover-overlay', + ariaLabelledBy: 'modalID', +}; + +export default Modal; \ No newline at end of file From b39d4d8ad1adf11c80c5b2b91960676e3c014fcc Mon Sep 17 00:00:00 2001 From: boblinthorst Date: Tue, 24 Apr 2018 09:06:10 +0200 Subject: [PATCH 04/16] removed navigableToolbar --- components/modal/index.js | 13 +++++++++++-- components/modal/{ModalHeader.js => modalHeader.js} | 9 ++++----- 2 files changed, 15 insertions(+), 7 deletions(-) rename components/modal/{ModalHeader.js => modalHeader.js} (81%) diff --git a/components/modal/index.js b/components/modal/index.js index 8b0f688ec76923..8397f7374276a0 100644 --- a/components/modal/index.js +++ b/components/modal/index.js @@ -12,6 +12,7 @@ import './style.scss'; * External dependencies */ import ReactModal from 'react-modal'; +import ModalHeader from './modalHeader'; ReactModal.setAppElement( document.getElementById( 'wpwrap' ) ); @@ -55,6 +56,8 @@ class Modal extends Component { className, overlayClassName, ariaLabelledBy, + icon, + title, children } = this.props; return - { children } + aria-labelledby={ ariaLabelledBy } + onRequestClose={ this.onClose }> + +
+ { children } +
; } } @@ -74,6 +81,8 @@ Modal.defaultProps = { className: 'edit-post-plugin-screen-takeover__editor-screen-takeover', overlayClassName: 'edit-post-plugin-screen-takeover__editor-screen-takeover-overlay', ariaLabelledBy: 'modalID', + icon: null, + title: 'modal', }; export default Modal; \ No newline at end of file diff --git a/components/modal/ModalHeader.js b/components/modal/modalHeader.js similarity index 81% rename from components/modal/ModalHeader.js rename to components/modal/modalHeader.js index 7e4167d85ceb88..f75831581bf408 100644 --- a/components/modal/ModalHeader.js +++ b/components/modal/modalHeader.js @@ -1,13 +1,12 @@ -import { NavigableToolbar } from '../../editor/components'; import { IconButton } from '@wordpress/components'; -import { __ } from '@wordpress/i18n'; import './style.scss'; +import { __ } from '@wordpress/i18n'; const ModalHeader = ( { icon, title, onClose, closeLabel } ) => { const label = closeLabel ? closeLabel : __( 'Close window' ); return ( -
@@ -23,8 +22,8 @@ const ModalHeader = ( { icon, title, onClose, closeLabel } ) => { icon="no-alt" label={ label } /> - +
); }; -export default ModalHeader; \ No newline at end of file +export default ModalHeader; From 09f81c764deba7d4df287411305cab544d5f4df9 Mon Sep 17 00:00:00 2001 From: boblinthorst Date: Tue, 24 Apr 2018 09:59:52 +0200 Subject: [PATCH 05/16] Renamed css classes --- components/modal/index.js | 24 ++++++++++-------------- components/modal/modalHeader.js | 2 +- components/modal/style.scss | 10 +++++----- 3 files changed, 16 insertions(+), 20 deletions(-) diff --git a/components/modal/index.js b/components/modal/index.js index 8397f7374276a0..08999a8bcb3ce3 100644 --- a/components/modal/index.js +++ b/components/modal/index.js @@ -21,12 +21,10 @@ class Modal extends Component { super( props ); this.state = { - isOpen: true, height: window.innerHeight - 32, }; this.updateWindowHeight = this.updateWindowHeight.bind( this ); - this.onClose = this.onClose.bind( this ); } componentDidMount() { @@ -43,21 +41,17 @@ class Modal extends Component { } ); } - onClose() { - this.setState( { - isOpen: false, - } ); - } - render() { const { isOpen, render, className, overlayClassName, + contentClassName, ariaLabelledBy, icon, title, + onRequestClose, children } = this.props; return - -
+ onRequestClose={ onRequestClose }> + +
{ children }
; @@ -78,11 +72,13 @@ class Modal extends Component { Modal.defaultProps = { isOpen: true, render: true, - className: 'edit-post-plugin-screen-takeover__editor-screen-takeover', - overlayClassName: 'edit-post-plugin-screen-takeover__editor-screen-takeover-overlay', + className: 'edit-post-plugin-modal__editor-modal', + overlayClassName: 'edit-post-plugin-modal__editor-modal-overlay', + contentClassName: 'edit-post-plugin-modal__editor-modal-content', ariaLabelledBy: 'modalID', icon: null, - title: 'modal', + title: 'Plugin screen', + onRequestClose: null, }; export default Modal; \ No newline at end of file diff --git a/components/modal/modalHeader.js b/components/modal/modalHeader.js index f75831581bf408..767ee8c4b80d66 100644 --- a/components/modal/modalHeader.js +++ b/components/modal/modalHeader.js @@ -7,7 +7,7 @@ const ModalHeader = ( { icon, title, onClose, closeLabel } ) => { return (