1- import { Component , Provider , signal , ViewChild } from '@angular/core' ;
1+ import { Component , inject , Provider , signal , ViewChild } from '@angular/core' ;
22import { ComponentFixture , fakeAsync , flush , TestBed } from '@angular/core/testing' ;
33import { NoopAnimationsModule } from '@angular/platform-browser/animations' ;
44import { DateAdapter , provideNativeDateAdapter } from '@angular/material/core' ;
@@ -24,10 +24,13 @@ import {
2424import { MatInput } from '@angular/material/input' ;
2525import { MatFormField , MatLabel , MatSuffix } from '@angular/material/form-field' ;
2626import { MatTimepickerInput } from './timepicker-input' ;
27- import { MatTimepicker } from './timepicker' ;
27+ import { MAT_TIMEPICKER_SCROLL_STRATEGY , MatTimepicker } from './timepicker' ;
2828import { MatTimepickerToggle } from './timepicker-toggle' ;
2929import { MAT_TIMEPICKER_CONFIG , MatTimepickerOption } from './util' ;
3030import { FormControl , ReactiveFormsModule , Validators } from '@angular/forms' ;
31+ import { ScrollDispatcher } from '@angular/cdk/scrolling' ;
32+ import { Overlay } from '@angular/cdk/overlay' ;
33+ import { Subject } from 'rxjs' ;
3134
3235describe ( 'MatTimepicker' , ( ) => {
3336 let adapter : DateAdapter < Date > ;
@@ -440,6 +443,38 @@ describe('MatTimepicker', () => {
440443 flush ( ) ;
441444 } ) . not . toThrow ( ) ;
442445 } ) ) ;
446+
447+ it ( 'should be able to reopen the panel when closed by a scroll strategy' , fakeAsync ( ( ) => {
448+ const scrolledSubject = new Subject ( ) ;
449+
450+ TestBed . resetTestingModule ( ) ;
451+ configureTestingModule ( [
452+ {
453+ provide : ScrollDispatcher ,
454+ useValue : { scrolled : ( ) => scrolledSubject } ,
455+ } ,
456+ {
457+ provide : MAT_TIMEPICKER_SCROLL_STRATEGY ,
458+ useFactory : ( ) => {
459+ const overlay = inject ( Overlay ) ;
460+ return ( ) => overlay . scrollStrategies . close ( ) ;
461+ } ,
462+ } ,
463+ ] ) ;
464+
465+ const fixture = TestBed . createComponent ( StandaloneTimepicker ) ;
466+ fixture . detectChanges ( ) ;
467+ fixture . componentInstance . timepicker . open ( ) ;
468+ fixture . detectChanges ( ) ;
469+ expect ( getPanel ( ) ) . toBeTruthy ( ) ;
470+ scrolledSubject . next ( ) ;
471+ fixture . detectChanges ( ) ;
472+ flush ( ) ;
473+ expect ( getPanel ( ) ) . toBeFalsy ( ) ;
474+ fixture . componentInstance . timepicker . open ( ) ;
475+ fixture . detectChanges ( ) ;
476+ expect ( getPanel ( ) ) . toBeTruthy ( ) ;
477+ } ) ) ;
443478 } ) ;
444479
445480 // Note: these tests intentionally don't cover the full option generation logic
0 commit comments