99import {
1010 afterNextRender ,
1111 AfterRenderRef ,
12+ ANIMATION_MODULE_TYPE ,
1213 booleanAttribute ,
1314 ChangeDetectionStrategy ,
1415 Component ,
@@ -32,7 +33,6 @@ import {
3233 ViewContainerRef ,
3334 ViewEncapsulation ,
3435} from '@angular/core' ;
35- import { animate , group , state , style , transition , trigger } from '@angular/animations' ;
3636import {
3737 DateAdapter ,
3838 MAT_DATE_FORMATS ,
@@ -80,18 +80,6 @@ export interface MatTimepickerSelected<D> {
8080 useExisting : MatTimepicker ,
8181 } ,
8282 ] ,
83- animations : [
84- trigger ( 'panel' , [
85- state ( 'void' , style ( { opacity : 0 , transform : 'scaleY(0.8)' } ) ) ,
86- transition ( ':enter' , [
87- group ( [
88- animate ( '0.03s linear' , style ( { opacity : 1 } ) ) ,
89- animate ( '0.12s cubic-bezier(0, 0, 0.2, 1)' , style ( { transform : 'scaleY(1)' } ) ) ,
90- ] ) ,
91- ] ) ,
92- transition ( ':leave' , [ animate ( '0.075s linear' , style ( { opacity : 0 } ) ) ] ) ,
93- ] ) ,
94- ] ,
9583} )
9684export class MatTimepicker < D > implements OnDestroy , MatOptionParentComponent {
9785 private _overlay = inject ( Overlay ) ;
@@ -101,6 +89,8 @@ export class MatTimepicker<D> implements OnDestroy, MatOptionParentComponent {
10189 private _defaultConfig = inject ( MAT_TIMEPICKER_CONFIG , { optional : true } ) ;
10290 private _dateAdapter = inject < DateAdapter < D > > ( DateAdapter , { optional : true } ) ! ;
10391 private _dateFormats = inject ( MAT_DATE_FORMATS , { optional : true } ) ! ;
92+ protected _animationsDisabled =
93+ inject ( ANIMATION_MODULE_TYPE , { optional : true } ) === 'NoopAnimations' ;
10494
10595 private _isOpen = signal ( false ) ;
10696 private _activeDescendant = signal < string | null > ( null ) ;
@@ -246,8 +236,11 @@ export class MatTimepicker<D> implements OnDestroy, MatOptionParentComponent {
246236 close ( ) : void {
247237 if ( this . _isOpen ( ) ) {
248238 this . _isOpen . set ( false ) ;
249- this . _overlayRef ?. detach ( ) ;
250239 this . closed . emit ( ) ;
240+
241+ if ( this . _animationsDisabled ) {
242+ this . _overlayRef ?. detach ( ) ;
243+ }
251244 }
252245 }
253246
@@ -270,9 +263,16 @@ export class MatTimepicker<D> implements OnDestroy, MatOptionParentComponent {
270263 }
271264
272265 /** Selects a specific time value. */
273- protected _selectValue ( value : D ) {
266+ protected _selectValue ( option : MatOption < D > ) {
274267 this . close ( ) ;
275- this . selected . emit ( { value, source : this } ) ;
268+ this . _keyManager . setActiveItem ( option ) ;
269+ this . _options ( ) . forEach ( current => {
270+ // This is primarily here so we don't show two selected options while animating away.
271+ if ( current !== option ) {
272+ current . deselect ( false ) ;
273+ }
274+ } ) ;
275+ this . selected . emit ( { value : option . value , source : this } ) ;
276276 this . _input ( ) ?. focus ( ) ;
277277 }
278278
@@ -284,6 +284,13 @@ export class MatTimepicker<D> implements OnDestroy, MatOptionParentComponent {
284284 return this . ariaLabelledby ( ) || this . _input ( ) ?. _getLabelId ( ) || null ;
285285 }
286286
287+ /** Handles animation events coming from the panel. */
288+ protected _handleAnimationEnd ( event : AnimationEvent ) {
289+ if ( event . animationName === '_mat-timepicker-exit' ) {
290+ this . _overlayRef ?. detach ( ) ;
291+ }
292+ }
293+
287294 /** Creates an overlay reference for the timepicker panel. */
288295 private _getOverlayRef ( ) : OverlayRef {
289296 if ( this . _overlayRef ) {
@@ -409,7 +416,7 @@ export class MatTimepicker<D> implements OnDestroy, MatOptionParentComponent {
409416 event . preventDefault ( ) ;
410417
411418 if ( this . _keyManager . activeItem ) {
412- this . _selectValue ( this . _keyManager . activeItem . value ) ;
419+ this . _selectValue ( this . _keyManager . activeItem ) ;
413420 } else {
414421 this . close ( ) ;
415422 }
0 commit comments