@@ -9,8 +9,12 @@ import {
99 ElementRef ,
1010 ViewChild ,
1111 SimpleChanges ,
12- OnChanges
12+ OnChanges ,
13+ Renderer2 ,
14+ Inject ,
15+ OnDestroy
1316} from "@angular/core" ;
17+ import { DOCUMENT } from "@angular/common" ;
1418import { cycleTabs , getFocusElementList } from "carbon-components-angular/common" ;
1519
1620/**
@@ -101,15 +105,7 @@ export class ModalDemo {
101105 </ibm-overlay>
102106 `
103107} )
104- export class Modal implements AfterViewInit , OnChanges {
105- /**
106- * Size of the modal to display.
107- */
108- @Input ( ) size : "xs" | "sm" | "lg" ;
109- /**
110- * Classification of the modal.
111- */
112- @Input ( ) theme : "default" | "danger" = "default" ;
108+ export class Modal implements AfterViewInit , OnChanges , OnDestroy {
113109
114110 /**
115111 * Label for the modal.
@@ -124,6 +120,33 @@ export class Modal implements AfterViewInit, OnChanges {
124120 return this . ariaLabel ;
125121 }
126122
123+ /**
124+ * This detects whether or not the modal contains scrolling content.
125+ *
126+ * To force trigger a detection (ie. on window resize), change or reset the value of the modal content.
127+ *
128+ * Use the `hasScrollingContent` input to manually override the overflow indicator.
129+ */
130+ get shouldShowScrollbar ( ) {
131+ const modalContent = this . modal ? this . modal . nativeElement . querySelector ( ".bx--modal-content" ) : null ;
132+ if ( ! modalContent ) {
133+ return false ;
134+ }
135+
136+ // get rounded value from height to match integer returned from scrollHeight
137+ const modalContentHeight = Math . ceil ( modalContent . getBoundingClientRect ( ) . height ) ;
138+ const modalContentScrollHeight = modalContent . scrollHeight ;
139+ return modalContentScrollHeight > modalContentHeight ;
140+ }
141+ /**
142+ * Size of the modal to display.
143+ */
144+ @Input ( ) size : "xs" | "sm" | "lg" ;
145+ /**
146+ * Classification of the modal.
147+ */
148+ @Input ( ) theme : "default" | "danger" = "default" ;
149+
127150 @Input ( ) ariaLabel = "default" ;
128151
129152 /**
@@ -166,14 +189,23 @@ export class Modal implements AfterViewInit, OnChanges {
166189 /**
167190 * Creates an instance of `Modal`.
168191 */
169- constructor ( public modalService : ModalService ) { }
192+ constructor (
193+ public modalService : ModalService ,
194+ @Inject ( DOCUMENT ) private document : Document ,
195+ private renderer : Renderer2
196+ ) { }
170197
171198 ngOnChanges ( { open } : SimpleChanges ) {
172199 if ( open ) {
173200 if ( open . currentValue ) {
174201 // `100` is just enough time to allow the modal
175202 // to become visible, so that we can set focus
176203 setTimeout ( ( ) => this . focusInitialElement ( ) , 100 ) ;
204+ // Prevent scrolling on open
205+ this . renderer . addClass ( this . document . body , "bx--body--with-modal-open" ) ;
206+ } else if ( ! open . currentValue ) {
207+ // Enable scrolling on close
208+ this . renderer . removeClass ( this . document . body , "bx--body--with-modal-open" ) ;
177209 } else if ( this . trigger ) {
178210 this . trigger . focus ( ) ;
179211 }
@@ -207,23 +239,9 @@ export class Modal implements AfterViewInit, OnChanges {
207239 }
208240 }
209241
210- /**
211- * This detects whether or not the modal contains scrolling content.
212- *
213- * To force trigger a detection (ie. on window resize), change or reset the value of the modal content.
214- *
215- * Use the `hasScrollingContent` input to manually override the overflow indicator.
216- */
217- get shouldShowScrollbar ( ) {
218- const modalContent = this . modal ? this . modal . nativeElement . querySelector ( ".bx--modal-content" ) : null ;
219- if ( modalContent ) {
220- // get rounded value from height to match integer returned from scrollHeight
221- const modalContentHeight = Math . ceil ( modalContent . getBoundingClientRect ( ) . height ) ;
222- const modalContentScrollHeight = modalContent . scrollHeight ;
223- return modalContentScrollHeight > modalContentHeight ;
224- } else {
225- return false ;
226- }
242+ // Remove class preventing scrolling
243+ ngOnDestroy ( ) {
244+ this . renderer . removeClass ( this . document . body , "bx--body--with-modal-open" ) ;
227245 }
228246
229247 protected focusInitialElement ( ) {
0 commit comments