diff --git a/packages/components/src/modal/index.js b/packages/components/src/modal/index.js index 940a715afec3aa..861fe289d727f0 100644 --- a/packages/components/src/modal/index.js +++ b/packages/components/src/modal/index.js @@ -36,7 +36,7 @@ class Modal extends Component { openModalCount++; if ( openModalCount === 1 ) { - this.openFirstModal(); + this.openFirstModal( this.props.isFullscreen ); } } @@ -48,7 +48,7 @@ class Modal extends Component { openModalCount--; if ( openModalCount === 0 ) { - this.closeLastModal(); + this.closeLastModal( this.props.isFullscreen ); } this.cleanDOM(); @@ -66,6 +66,7 @@ class Modal extends Component { prepareDOM() { if ( ! parentElement ) { parentElement = document.createElement( 'div' ); + parentElement.className = 'components-modal__portal'; document.body.appendChild( parentElement ); } this.node = document.createElement( 'div' ); @@ -85,19 +86,29 @@ class Modal extends Component { * It appends an additional div to the body for the modals to be rendered in, * it hides any other elements from screen-readers and adds an additional class * to the body to prevent scrolling while the modal is open. + * + * @param {boolean} isFullscreen */ - openFirstModal() { + openFirstModal( isFullscreen ) { ariaHelper.hideApp( parentElement ); document.body.classList.add( this.props.bodyOpenClassName ); + if ( isFullscreen ) { + document.body.classList.add( 'is-fullscreen-modal' ); + } } /** * Cleans up the DOM after the last modal is closed and makes the app available * for screen-readers again. + * + * @param {boolean} isFullscreen */ - closeLastModal() { + closeLastModal( isFullscreen ) { document.body.classList.remove( this.props.bodyOpenClassName ); ariaHelper.showApp(); + if ( isFullscreen ) { + document.body.classList.remove( 'is-fullscreen-modal' ); + } } /** diff --git a/packages/components/src/modal/style.scss b/packages/components/src/modal/style.scss index 7e7a8449d039ec..d9614598a25102 100644 --- a/packages/components/src/modal/style.scss +++ b/packages/components/src/modal/style.scss @@ -6,48 +6,12 @@ bottom: 0; left: 0; z-index: z-index(".components-modal__screen-overlay"); - - &.is-full-screen { - padding: 20px; - background: $white; - overflow: auto; - - @include break-small() { - padding: 100px; - } - - // These are two divs rendered by Higher-order components - // We need their height to be 100% for the verticalcentering - // of the modal. - & > div, - & > div > div { - height: 100%; - } - } - - &.is-dialog { - // This animates the appearance of the background. - @include edit-post__fade-in-animation(); - - background-color: rgba($black, 0.7); - } -} - -// The modal window element. -.components-modal__screen-overlay.is-full-screen .components-modal__frame { - max-width: 800px; - min-height: 100%; - margin: auto; - display: grid; - align-items: center; - - // Animate the modal frame/contents appearing on the page. - transform-origin: top center; - animation: components-modal__appear-scale-animation 0.2s forwards; - @include reduce-motion("animation"); + background-color: rgba($black, 0.7); + // This animates the appearance of the background. + @include edit-post__fade-in-animation(); } -.components-modal__screen-overlay.is-dialog .components-modal__frame { +.components-modal__frame { // On small screens the content needs to be full width because of limited // space. position: absolute; @@ -60,21 +24,29 @@ border: $border-width solid $gray-300; background: $white; box-shadow: $shadow-modal; - overflow: auto; - - // Show a centered modal on bigger screens. - @include break-small() { - top: 50%; - right: auto; - bottom: auto; - left: 50%; - min-width: $modal-min-width; - max-width: calc(100% - #{ $grid-unit-20 } - #{ $grid-unit-20 }); - max-height: 90%; - transform: translate(-50%, -50%); - // Animate the modal frame/contents appearing on the page. - animation: components-modal__appear-slide-animation 0.1s ease-out; - animation-fill-mode: forwards; + + .components-modal__screen-overlay.is-dialog & { + // Show a centered modal on bigger screens. + @include break-small() { + top: 50%; + right: auto; + bottom: auto; + left: 50%; + min-width: $modal-min-width; + max-width: calc(100% - #{ $grid-unit-20 } - #{ $grid-unit-20 }); + max-height: 90%; + transform: translate(-50%, -50%); + // Animate the modal frame/contents appearing on the page. + animation: components-modal__appear-slide-animation 0.1s ease-out; + animation-fill-mode: forwards; + @include reduce-motion("animation"); + } + } + + .components-modal__screen-overlay.is-full-screen & { + top: 100%; + transform-origin: top center; + animation: components-modal__appear-slide-from-bottom 0.3s forwards; @include reduce-motion("animation"); } } @@ -92,23 +64,21 @@ height: $header-height; margin-bottom: 2 * $grid-unit-30; - .components-modal__screen-overlay.is-dialog & { - border-bottom: $border-width solid $gray-300; - padding: 0 $grid-unit-30; - - position: relative; - position: sticky; - top: 0; - z-index: z-index(".components-modal__header"); - margin: 0 -#{$grid-unit-30} $grid-unit-30; + border-bottom: $border-width solid $gray-300; + padding: 0 $grid-unit-30; - // Rules inside this query are only run by Microsoft Edge. - // Edge has bugs around position: sticky;, so it needs a separate top rule. - // See also https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/17555420/. - @supports (-ms-ime-align:auto) { - position: fixed; - width: 100%; - } + position: relative; + position: sticky; + top: 0; + z-index: z-index(".components-modal__header"); + margin: 0 -#{$grid-unit-30} $grid-unit-30; + + // Rules inside this query are only run by Microsoft Edge. + // Edge has bugs around position: sticky;, so it needs a separate top rule. + // See also https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/17555420/. + @supports (-ms-ime-align:auto) { + position: fixed; + width: 100%; } h1 { @@ -122,16 +92,11 @@ } } -.components-modal__screen-overlay.is-dialog .components-modal__header-heading { +.components-modal__screen-overlay .components-modal__header-heading { font-size: 1rem; font-weight: 600; } -.components-modal__screen-overlay.is-full-screen .components-modal__header-heading { - font-size: 2rem; - font-weight: 300; -} - .components-modal__header-heading-container { align-items: center; flex-grow: 1; @@ -155,8 +120,9 @@ box-sizing: border-box; padding: 0 $grid-unit-30 $grid-unit-30; - .components-modal__screen-overlay.is-dialog & { + .components-modal__screen-overlay & { height: 100%; + overflow: auto; // Rules inside this query are only run by Microsoft Edge. // This is a companion top padding to the fixed rule in line 77. @@ -164,18 +130,21 @@ padding-top: $header-height; } } + } -.components-modal__screen-overlay.is-full-screen .components-modal-header__close svg { - transform: scale(1.5); +// Scale down the content of the page. +body.modal-open.is-fullscreen-modal > *:not(.components-modal__portal) { + transition: transform 0.5s; + transform: scale(0.9); } -@keyframes components-modal__appear-scale-animation { +@keyframes components-modal__appear-slide-from-bottom { from { - transform: scale(0.1); + top: 100%; } to { - transform: scale(1); + top: 100px; } } diff --git a/packages/edit-post/src/components/keyboard-shortcut-help-modal/index.js b/packages/edit-post/src/components/keyboard-shortcut-help-modal/index.js index a05e3f20ba4a3d..0513aeb7cd7069 100644 --- a/packages/edit-post/src/components/keyboard-shortcut-help-modal/index.js +++ b/packages/edit-post/src/components/keyboard-shortcut-help-modal/index.js @@ -105,6 +105,7 @@ export function KeyboardShortcutHelpModal( { isModalActive, toggleModal } ) { title={ __( 'Keyboard shortcuts' ) } closeLabel={ __( 'Close' ) } onRequestClose={ toggleModal } + isFullscreen >