Skip to content

Commit 60bf81b

Browse files
committed
fix(sort): display mat-sort-header arrow when sorting programmatically
Fix mat-sort-header arrow not displaying after sorting programmatically (eg. `matSort.sort()`) Related to #10242, #12754
1 parent 917a52e commit 60bf81b

File tree

2 files changed

+36
-25
lines changed

2 files changed

+36
-25
lines changed

src/material/sort/sort-header.ts

Lines changed: 23 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import {
2020
} from '@angular/core';
2121
import {CanDisable, CanDisableCtor, mixinDisabled} from '@angular/material/core';
2222
import {merge, Subscription} from 'rxjs';
23+
import {filter} from 'rxjs/operators';
2324
import {MatSort, MatSortable} from './sort';
2425
import {matSortAnimations} from './sort-animations';
2526
import {SortDirection} from './sort-direction';
@@ -152,19 +153,28 @@ export class MatSortHeader extends _MatSortHeaderMixinBase
152153
}
153154

154155
this._rerenderSubscription = merge(_sort.sortChange, _sort._stateChanges, _intl.changes)
155-
.subscribe(() => {
156-
if (this._isSorted()) {
157-
this._updateArrowDirection();
158-
}
159-
160-
// If this header was recently active and now no longer sorted, animate away the arrow.
161-
if (!this._isSorted() && this._viewState && this._viewState.toState === 'active') {
162-
this._disableViewStateAnimation = false;
163-
this._setAnimationTransitionState({fromState: 'active', toState: this._arrowDirection});
164-
}
165-
166-
changeDetectorRef.markForCheck();
167-
});
156+
.pipe(filter(() => !!this.id))
157+
.subscribe(() => {
158+
const viewState = this._viewState;
159+
160+
// Do not show the animation if the header was already shown in the right position.
161+
if (viewState && viewState.toState === 'hint' || viewState.toState === 'active') {
162+
this._disableViewStateAnimation = true;
163+
}
164+
165+
if (this._isSorted()) {
166+
this._updateArrowDirection();
167+
168+
this._setAnimationTransitionState({fromState: this._arrowDirection, toState: 'active'});
169+
} else if (viewState && viewState.toState === 'active') {
170+
// This header was recently active and now no longer sorted, animate away the arrow.
171+
this._disableViewStateAnimation = false;
172+
173+
this._setAnimationTransitionState({fromState: 'active', toState: this._arrowDirection});
174+
}
175+
176+
changeDetectorRef.markForCheck();
177+
});
168178
}
169179

170180
ngOnInit() {
@@ -226,18 +236,6 @@ export class MatSortHeader extends _MatSortHeaderMixinBase
226236

227237
this._sort.sort(this);
228238

229-
// Do not show the animation if the header was already shown in the right position.
230-
if (this._viewState.toState === 'hint' || this._viewState.toState === 'active') {
231-
this._disableViewStateAnimation = true;
232-
}
233-
234-
// If the arrow is now sorted, animate the arrow into place. Otherwise, animate it away into
235-
// the direction it is facing.
236-
const viewState: ArrowViewStateTransition = this._isSorted() ?
237-
{fromState: this._arrowDirection, toState: 'active'} :
238-
{fromState: 'active', toState: this._arrowDirection};
239-
this._setAnimationTransitionState(viewState);
240-
241239
this._showIndicatorHint = false;
242240
}
243241

src/material/sort/sort.spec.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,19 @@ describe('MatSort', () => {
188188
component.expectViewAndDirectionStates(expectedStates);
189189
});
190190

191+
it('should be correct when sort has changed programmatically while a header is active', () => {
192+
// Sort the first header to set up
193+
component.sort('defaultA');
194+
expectedStates.set('defaultA', {viewState: 'asc-to-active', arrowDirection: 'active-asc'});
195+
component.expectViewAndDirectionStates(expectedStates);
196+
197+
// Sort the second header programmatically and verify that the first header animated away
198+
component.matSort.sort({id: 'defaultB', start: 'asc', disableClear: false});
199+
expectedStates.set('defaultA', {viewState: 'active-to-asc', arrowDirection: 'asc'});
200+
expectedStates.set('defaultB', {viewState: 'asc-to-active', arrowDirection: 'active-asc'});
201+
component.expectViewAndDirectionStates(expectedStates);
202+
});
203+
191204
it('should be correct when sort has been disabled', () => {
192205
// Mousing over the first sort should set the view state to hint
193206
component.disabledColumnSort = true;

0 commit comments

Comments
 (0)