From 94270d8b127ae7fef17af6b275fd2ed3bc78f0e0 Mon Sep 17 00:00:00 2001 From: Robert Hjalmers Date: Tue, 9 Mar 2021 12:28:57 +0100 Subject: [PATCH 1/7] fix(modal): empty space for scrollable modal fixes #596 --- package-lock.json | 8 +- scss/styles/_modal.scss | 249 +++++++++++++++++++++++++++++++++++++++- 2 files changed, 251 insertions(+), 6 deletions(-) diff --git a/package-lock.json b/package-lock.json index 3f6d985..1eefab6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "bootstrap-demo", - "version": "1.0.1", + "version": "2.0.0-rc.1", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -8242,9 +8242,9 @@ } }, "body-scroll-lock": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/body-scroll-lock/-/body-scroll-lock-2.7.1.tgz", - "integrity": "sha512-hS53SQ8RhM0e4DsQ3PKz6Gr2O7Kpdh59TWU98GHjaQznL7y4dFycEPk7pFQAikqBaUSCArkc5E3pe7CWIt2fZA==", + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/body-scroll-lock/-/body-scroll-lock-3.1.5.tgz", + "integrity": "sha512-Yi1Xaml0EvNA0OYWxXiYNqY24AfWkbA6w5vxE7GWxtKfzIbZM+Qw+aSmkgsbWzbHiy/RCSkUZBplVxTA+E4jJg==", "dev": true }, "bonjour": { diff --git a/scss/styles/_modal.scss b/scss/styles/_modal.scss index 4964d20..733614d 100644 --- a/scss/styles/_modal.scss +++ b/scss/styles/_modal.scss @@ -1,4 +1,246 @@ -@import "../bootstrap-core/modal"; +//@import "../bootstrap-core/modal"; +// .modal-open - body class for killing the scroll +// .modal - container to scroll within +// .modal-dialog - positioning shell for the actual modal +// .modal-content - actual modal w/ bg and corners and stuff + + +.modal-open { + // Kill the scroll on the body + overflow: hidden; + + .modal { + overflow-x: hidden; + overflow-y: auto; + } +} + +// Container that the modal scrolls within +.modal { + position: fixed; + top: 0; + left: 0; + z-index: $zindex-modal; + display: none; + width: 100%; + height: 100%; + overflow: hidden; + // Prevent Chrome on Windows from adding a focus outline. For details, see + // https://github.com/twbs/bootstrap/pull/10951. + outline: 0; + // We deliberately don't use `-webkit-overflow-scrolling: touch;` due to a + // gnarly iOS Safari bug: https://bugs.webkit.org/show_bug.cgi?id=158342 + // See also https://github.com/twbs/bootstrap/issues/17695 +} + +// Shell div to position the modal with bottom padding +.modal-dialog { + position: relative; + width: auto; + margin: $modal-dialog-margin; + // allow clicks to pass through for custom click handling to close modal + pointer-events: none; + + // When fading in the modal, animate it to slide down + .modal.fade & { + @include transition($modal-transition); + transform: $modal-fade-transform; + } + .modal.show & { + transform: $modal-show-transform; + } + + // When trying to close, animate focus to scale + .modal.modal-static & { + transform: $modal-scale-transform; + } +} + +.modal-dialog-scrollable { + display: flex; // IE10/11 + //max-height: subtract(100%, $modal-dialog-margin * 2); + + .modal-content { + //max-height: subtract(100vh, $modal-dialog-margin * 2); // IE10/11 + max-height: 100vh; + overflow: hidden; + } + + .modal-header, + .modal-footer { + flex-shrink: 0; + } + + .modal-body { + overflow-y: auto; + } +} + +.modal-dialog-centered { + display: flex; + align-items: center; + min-height: subtract(100%, $modal-dialog-margin * 2); + + // Ensure `modal-dialog-centered` extends the full height of the view (IE10/11) + &::before { + display: block; // IE10 + height: subtract(100vh, $modal-dialog-margin * 2); + height: min-content; // Reset height to 0 except on IE + content: ""; + } + + // Ensure `.modal-body` shows scrollbar (IE10/11) + &.modal-dialog-scrollable { + flex-direction: column; + justify-content: center; + height: 100%; + + .modal-content { + max-height: none; + } + + &::before { + content: none; + } + } +} + +// Actual modal +.modal-content { + position: relative; + display: flex; + flex-direction: column; + width: 100%; // Ensure `.modal-content` extends the full width of the parent `.modal-dialog` + // counteract the pointer-events: none; in the .modal-dialog + color: $modal-content-color; + pointer-events: auto; + background-color: $modal-content-bg; + background-clip: padding-box; + border: $modal-content-border-width solid $modal-content-border-color; + @include border-radius($modal-content-border-radius); + @include box-shadow($modal-content-box-shadow-xs); + // Remove focus outline from opened modal + outline: 0; +} + +// Modal background +.modal-backdrop { + position: fixed; + top: 0; + left: 0; + z-index: $zindex-modal-backdrop; + width: 100vw; + height: 100vh; + background-color: $modal-backdrop-bg; + + // Fade for backdrop + &.fade { opacity: 0; } + &.show { opacity: $modal-backdrop-opacity; } +} + +// Modal header +// Top section of the modal w/ title and dismiss +.modal-header { + display: flex; + align-items: flex-start; // so the close btn always stays on the upper right corner + justify-content: space-between; // Put modal header elements (title and dismiss) on opposite ends + padding: $modal-header-padding; + border-bottom: $modal-header-border-width solid $modal-header-border-color; + @include border-top-radius($modal-content-inner-border-radius); + + .close { + padding: $modal-header-padding; + // auto on the left force icon to the right even when there is no .modal-title + margin: (-$modal-header-padding-y) (-$modal-header-padding-x) (-$modal-header-padding-y) auto; + } +} + +// Title text within header +.modal-title { + margin-bottom: 0; + line-height: $modal-title-line-height; +} + +// Modal body +// Where all modal content resides (sibling of .modal-header and .modal-footer) +.modal-body { + position: relative; + // Enable `flex-grow: 1` so that the body take up as much space as possible + // when there should be a fixed height on `.modal-dialog`. + flex: 1 1 auto; + padding: $modal-inner-padding; +} + +// Footer (for actions) +.modal-footer { + display: flex; + flex-wrap: wrap; + align-items: center; // vertically center + justify-content: flex-end; // Right align buttons with flex property because text-align doesn't work on flex items + padding: $modal-inner-padding - $modal-footer-margin-between / 2; + border-top: $modal-footer-border-width solid $modal-footer-border-color; + @include border-bottom-radius($modal-content-inner-border-radius); + + // Place margin between footer elements + // This solution is far from ideal because of the universal selector usage, + // but is needed to fix https://github.com/twbs/bootstrap/issues/24800 + > * { + margin: $modal-footer-margin-between / 2; + } +} + +// Measure scrollbar width for padding body during modal show/hide +.modal-scrollbar-measure { + position: absolute; + top: -9999px; + width: 50px; + height: 50px; + overflow: scroll; +} + +// Scale up the modal +@include media-breakpoint-up(sm) { + // Automatically set modal's width for larger viewports + .modal-dialog { + max-width: $modal-md; + margin: $modal-dialog-margin-y-sm-up auto; + } + + .modal-dialog-scrollable { + max-height: subtract(100%, $modal-dialog-margin-y-sm-up * 2); + + .modal-content { + max-height: subtract(100vh, $modal-dialog-margin-y-sm-up * 2); + } + } + + .modal-dialog-centered { + min-height: subtract(100%, $modal-dialog-margin-y-sm-up * 2); + + &::before { + height: subtract(100vh, $modal-dialog-margin-y-sm-up * 2); + height: min-content; + } + } + + .modal-content { + @include box-shadow($modal-content-box-shadow-sm-up); + } + + .modal-sm { max-width: $modal-sm; } +} + +@include media-breakpoint-up(lg) { + .modal-lg, + .modal-xl { + max-width: $modal-lg; + } +} + +@include media-breakpoint-up(xl) { + .modal-xl { max-width: $modal-xl; } +} + // SEB Specific style for aside modal and fullscreen @@ -100,12 +342,15 @@ @supports (-webkit-overflow-scrolling: touch) { .modal.modal-aside, .modal.modal-fullscreen { .modal-dialog, .modal-content { - max-height: 100%; + height: 100%; } } .modal-body { -webkit-overflow-scrolling: touch; } + .modal > .modal-dialog-scrollable > .modal-content { + max-height: -webkit-fill-available; + } } From 83bce723dcc161d8af7ac36251b02276015c76e6 Mon Sep 17 00:00:00 2001 From: Robert Hjalmers Date: Tue, 9 Mar 2021 12:30:53 +0100 Subject: [PATCH 2/7] docs(modal): update demo and docs for scrollable version --- src/example/modals/modals.component.html | 57 +++++++++++++++++++++--- src/example/modals/modals.component.ts | 7 ++- 2 files changed, 58 insertions(+), 6 deletions(-) diff --git a/src/example/modals/modals.component.html b/src/example/modals/modals.component.html index bdcb54c..f6d0fc0 100644 --- a/src/example/modals/modals.component.html +++ b/src/example/modals/modals.component.html @@ -29,7 +29,7 @@
- + @@ -40,6 +40,11 @@

Add the class .modal-dialog-scrollable to the modal element to allow the body content to overflow i.e. scroll. If you want the buttons or modal actions to align nicely at the bottom put them inside a modal footer with the class .border-top to get a border against the scrolling content body. This goes for aside and fullscreen modals too!

+
+
+ +
+
@@ -50,10 +55,14 @@

Add .modal-aside class to the modal element together with either .modal-aside-right or .modal-aside-left to get a modal that will slide in from the side.

+

Aside modals will by default scroll content if it overflows the modal body size, note that you need to add .border-top to the footer to get the top border.

+
+ +
@@ -65,10 +74,14 @@

Add .modal-fullscreen class to the modal element to get a fullscreen modal.

+

Fullscreen modals will by default scroll content if it overflows the modal body size, note that you need to add .border-top to the footer to get the top border.

+
+ +
@@ -79,7 +92,7 @@ @@ -87,14 +100,33 @@

Modal body text goes here.

+ + + + + @@ -108,7 +140,22 @@
+ + + + + diff --git a/src/example/modals/modals.component.ts b/src/example/modals/modals.component.ts index b1f1049..672fc82 100644 --- a/src/example/modals/modals.component.ts +++ b/src/example/modals/modals.component.ts @@ -39,7 +39,12 @@ export class ModalsComponent implements OnInit { this.closeResult = `Dismissed ${this.getDismissReason(reason)}`; }); - disableBodyScroll(contentBody); + disableBodyScroll(contentBody, { + allowTouchMove: el => { + // only allow scroll if parent to touched element contains modal-content or modal-body class + return el.parentElement.classList.contains('modal-content') || el.parentElement.classList.contains('modal-body') + }, + }); } private getDismissReason(reason: any): string { From 0e0d9bad867377c30326fe4b604f5673a36aa133 Mon Sep 17 00:00:00 2001 From: Robert Hjalmers Date: Tue, 9 Mar 2021 12:43:22 +0100 Subject: [PATCH 3/7] fix(modal): min width for large aside modal with iframe content --- scss/styles/_modal.scss | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/scss/styles/_modal.scss b/scss/styles/_modal.scss index 733614d..e57db1d 100644 --- a/scss/styles/_modal.scss +++ b/scss/styles/_modal.scss @@ -287,10 +287,16 @@ max-width: 100vw; .modal-content { width: 100vw; + iframe { + min-width: 100%; + } @include media-breakpoint-up(md) { max-width: $modal-aside-lg-width; width: auto; min-width: $modal-aside-width; + iframe { + min-width: $modal-aside-lg-width; + } } } } From 28bc9147993664d4477fd238a4e0048c1c3c0373 Mon Sep 17 00:00:00 2001 From: Robert Hjalmers Date: Tue, 9 Mar 2021 12:44:37 +0100 Subject: [PATCH 4/7] docs(modal): update demo and docs for large aside modal with iframe --- src/example/modals/modals.component.html | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/example/modals/modals.component.html b/src/example/modals/modals.component.html index f6d0fc0..8fc295a 100644 --- a/src/example/modals/modals.component.html +++ b/src/example/modals/modals.component.html @@ -22,6 +22,7 @@

Add .modal-lg class to the modal dialog to get a larger modal, works with normal modals and aside modals.

+

The width of large aside modals will grow and assume the size of the content (if width is set) and the max width is currently set to 768px (the breakpoint for medium sized screens). Note that if you use an iframe inside a large aside modal it's width will be set to 100% and fixed to 768px on md screens and up.

@@ -29,7 +30,10 @@
+
+
+
From 21dceec40cd82ce30516d22367be00459c0ee735 Mon Sep 17 00:00:00 2001 From: Robert Hjalmers Date: Tue, 9 Mar 2021 12:45:21 +0100 Subject: [PATCH 5/7] chore(deps): bump body scroll lock version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index d7b8e03..99d41f3 100644 --- a/package.json +++ b/package.json @@ -110,7 +110,7 @@ "@types/node": "^12.19.7", "autoprefixer": "^9.8.6", "backstopjs": "^5.0.6", - "body-scroll-lock": "^2.7.1", + "body-scroll-lock": "^3.1.5", "bootstrap": "^4.5.3", "clean-css-cli": "^4.2.1", "codelyzer": "^6.0.0", From b1857315bc8aa2f28d4167f3d2e065218351b4b8 Mon Sep 17 00:00:00 2001 From: Robert Hjalmers Date: Tue, 9 Mar 2021 12:46:40 +0100 Subject: [PATCH 6/7] chore(local-dev): update npm start script to allow other hosts --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 99d41f3..011d1b9 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,7 @@ "homepage": "https://sebgroup.github.io/bootstrap/", "scripts": { "ng": "ng", - "start": "ng serve", + "start": "ng serve --host 0.0.0.0", "build:demo": "ng build --prod --base-href https://sebgroup.github.io/bootstrap/ && copyfiles -f src/404.html dist/bootstrap", "prebuild:demo": "rimraf dist/bootstrap && replace __TRAVIS_BUILD_NUMBER__ $TRAVIS_BUILD_NUMBER src/environments/environment.ts && replace __TRAVIS_BUILD_NUMBER__ $TRAVIS_BUILD_NUMBER src/environments/environment.prod.ts", "build-dev": "ng build --source-map false --base-href https://sebgroup.github.io/bootstrap/dev/ --output-path dist/bootstrap/dev && copyfiles -f src/dev/404.html dist/bootstrap/dev", From 05c15b331a19b38d1f03678eb52019282a6fa1c4 Mon Sep 17 00:00:00 2001 From: Robert Hjalmers Date: Tue, 9 Mar 2021 13:02:24 +0100 Subject: [PATCH 7/7] fix(close): update focus state --- scss/styles/_close.scss | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/scss/styles/_close.scss b/scss/styles/_close.scss index 91ffac9..4c16071 100644 --- a/scss/styles/_close.scss +++ b/scss/styles/_close.scss @@ -56,6 +56,13 @@ opacity: 1; } } + &:focus { + outline: none; + &::after { + outline: none; + box-shadow: 0 0 4px 1px $blue; + } + } &:active::after { content: ''; background: $close-icon-active-bg;