1- import { animate , AnimationEvent , state , style , transition , trigger } from '@angular/animations' ;
21import { A11yModule , FocusMonitor } from '@angular/cdk/a11y' ;
32import { BooleanInput } from '@angular/cdk/coercion' ;
43import {
@@ -30,37 +29,18 @@ import { ModalDialogComponent } from '../modal-dialog/modal-dialog.component';
3029
3130@Component ( {
3231 selector : 'c-modal' ,
33- animations : [
34- trigger ( 'showHide' , [
35- state (
36- 'visible' ,
37- style ( {
38- // display: 'block'
39- } )
40- ) ,
41- state (
42- 'hidden' ,
43- style ( {
44- // display: 'none'
45- } )
46- ) ,
47- transition ( 'visible <=> *' , [ animate ( '150ms' ) ] )
48- ] )
49- ] ,
5032 templateUrl : './modal.component.html' ,
5133 exportAs : 'cModal' ,
5234 imports : [ ModalDialogComponent , ModalContentComponent , A11yModule ] ,
5335 host : {
5436 class : 'modal' ,
5537 '[class]' : 'hostClasses()' ,
56- '[attr.role]' : 'role()' ,
57- '[attr.inert]' : 'ariaHidden' ,
38+ '[attr.role]' : 'visible() ? role() : null ' ,
39+ '[attr.inert]' : 'ariaHidden() ' ,
5840 '[attr.id]' : 'id' ,
5941 '[attr.aria-modal]' : 'ariaModal()' ,
42+ '[attr.aria-hidden]' : 'ariaHidden()' ,
6043 '[attr.tabindex]' : '-1' ,
61- '[@showHide]' : 'animateTrigger()' ,
62- '(@showHide.start)' : 'animateStart($event)' ,
63- '(@showHide.done)' : 'animateDone($event)' ,
6444 '(mousedown)' : 'onMouseDownHandler($event)' ,
6545 '(click)' : 'onClickHandler($event)' ,
6646 '(document:keyup)' : 'onKeyUpHandler($event)'
@@ -163,6 +143,7 @@ export class ModalComponent implements OnInit, OnDestroy, AfterViewInit {
163143 readonly #visibleInputEffect = effect ( ( ) => {
164144 const visible = this . visible ( ) ;
165145 untracked ( ( ) => {
146+ this . animateStart ( ) ;
166147 this . setBodyStyles ( visible ) ;
167148 this . setBackdrop ( this . backdrop ( ) !== false && visible ) ;
168149 this . visibleChange ?. emit ( visible ) ;
@@ -209,6 +190,28 @@ export class ModalComponent implements OnInit, OnDestroy, AfterViewInit {
209190 // @ViewChild ('modalContentRef', { read: ElementRef }) modalContentRef!: ElementRef;
210191 // readonly modalContentRef = viewChild(ModalContentComponent, { read: ElementRef });
211192 readonly modalContentRef = viewChild ( 'modalContentRef' , { read : ElementRef } ) ;
193+ readonly modalDialogRef = viewChild . required ( ModalDialogComponent , { read : ElementRef } ) ;
194+
195+ readonly #modalDialogEffect = effect ( ( OnCleanup ) => {
196+ const modalDialogElement = this . modalDialogRef ( ) . nativeElement ;
197+
198+ const removeEventListeners = ( ) => {
199+ modalDialogElement ?. removeEventListener ( 'transitionend' , this . #handleTransitionEnd) ;
200+ } ;
201+
202+ OnCleanup ( removeEventListeners ) ;
203+
204+ modalDialogElement ?. addEventListener ( 'transitionend' , this . #handleTransitionEnd) ;
205+ } ) ;
206+
207+ readonly #handleTransitionEnd = ( event : TransitionEvent ) => {
208+ const modalDialogElement = this . modalDialogRef ( ) . nativeElement ;
209+ if ( event . target === modalDialogElement && event . propertyName === 'transform' ) {
210+ if ( ! this . visible ( ) ) {
211+ this . #renderer. setStyle ( this . #hostElement. nativeElement , 'display' , 'none' ) ;
212+ }
213+ }
214+ } ;
212215
213216 #activeBackdrop! : any ;
214217
@@ -218,30 +221,16 @@ export class ModalComponent implements OnInit, OnDestroy, AfterViewInit {
218221 return {
219222 modal : true ,
220223 fade : this . transition ( ) ,
221- show : this . show
224+ show : this . visible ( )
222225 } as Record < string , boolean > ;
223226 } ) ;
224227
225- get ariaHidden ( ) : boolean | null {
228+ readonly ariaHidden = computed ( ( ) => {
226229 return this . visible ( ) ? null : true ;
227- }
228-
229- readonly animateTrigger = computed ( ( ) => {
230- return this . visible ( ) ? 'visible' : 'hidden' ;
231230 } ) ;
232231
233- get show ( ) : boolean {
234- return this . visible ( ) && this . #show( ) ;
235- }
236-
237- set show ( value : boolean ) {
238- this . #show. set ( value ) ;
239- }
240-
241- readonly #show = signal ( true ) ;
242-
243- animateStart ( event : AnimationEvent ) {
244- if ( event . toState === 'visible' ) {
232+ animateStart ( ) {
233+ if ( this . visible ( ) ) {
245234 this . #backdropService. hideScrollbar ( ) ;
246235 this . #renderer. setStyle ( this . #hostElement. nativeElement , 'display' , 'block' ) ;
247236 } else {
@@ -251,16 +240,6 @@ export class ModalComponent implements OnInit, OnDestroy, AfterViewInit {
251240 }
252241 }
253242
254- animateDone ( event : AnimationEvent ) {
255- setTimeout ( ( ) => {
256- if ( event . toState === 'hidden' ) {
257- this . #renderer. setStyle ( this . #hostElement. nativeElement , 'display' , 'none' ) ;
258- this . #backdropService. resetScrollbar ( ) ;
259- }
260- } ) ;
261- this . show = this . visible ( ) ;
262- }
263-
264243 onKeyUpHandler ( event : KeyboardEvent ) : void {
265244 if ( event . key === 'Escape' && this . keyboard ( ) && this . visible ( ) ) {
266245 if ( this . backdrop ( ) === 'static' ) {
@@ -332,7 +311,7 @@ export class ModalComponent implements OnInit, OnDestroy, AfterViewInit {
332311
333312 private setBodyStyles ( open : boolean ) : void {
334313 if ( open ) {
335- if ( this . backdrop ( ) === true || this . backdrop ( ) === 'static' ) {
314+ if ( ! ! this . backdrop ( ) ) {
336315 this . #renderer. addClass ( this . #document. body , 'modal-open' ) ;
337316 }
338317 } else {
0 commit comments