Skip to content

Commit

Permalink
fix(material/datepicker): avoid losing focus when re-rendering the cu…
Browse files Browse the repository at this point in the history
…rrent view (#29287)

When some calendar inputs change, we need to re-render the entire view (e.g. `minDate` or `dateFilter`). This can cause the active cell to lose focus since it's being re-rendered.

These changes schedule the active cell to be re-focused in the cases where the view would be re-rendered.

Fixes #29265.

(cherry picked from commit e74065a)
  • Loading branch information
crisbeto committed Jun 25, 2024
1 parent bd4095a commit c1a40a2
Show file tree
Hide file tree
Showing 2 changed files with 8 additions and 2 deletions.
8 changes: 6 additions & 2 deletions src/material/datepicker/calendar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -454,12 +454,16 @@ export class MatCalendar<D> implements AfterContentInit, AfterViewChecked, OnDes
? changes['maxDate']
: undefined;

const change = minDateChange || maxDateChange || changes['dateFilter'];
const changeRequiringRerender = minDateChange || maxDateChange || changes['dateFilter'];

if (change && !change.firstChange) {
if (changeRequiringRerender && !changeRequiringRerender.firstChange) {
const view = this._getCurrentViewComponent();

if (view) {
// Schedule focus to be moved to the active date since re-rendering
// can blur the active cell. See #29265.
this._moveFocusOnNextTick = true;

// We need to `detectChanges` manually here, because the `minDate`, `maxDate` etc. are
// passed down to the view via data bindings which won't be up-to-date when we call `_init`.
this._changeDetectorRef.detectChanges();
Expand Down
2 changes: 2 additions & 0 deletions src/material/datepicker/datepicker.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1726,13 +1726,15 @@ describe('MatDatepicker', () => {
testComponent.minDate = new Date(2020, JAN, 1);
fixture.changeDetectorRef.markForCheck();
fixture.detectChanges();
flush();

expect(getDisabledCells()).not.toBe(disabledCellCount);
disabledCellCount = getDisabledCells();

testComponent.maxDate = new Date(2020, JAN, 10);
fixture.changeDetectorRef.markForCheck();
fixture.detectChanges();
flush();

expect(getDisabledCells()).not.toBe(disabledCellCount);
}));
Expand Down

0 comments on commit c1a40a2

Please sign in to comment.