Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(sort): be able to disable sort header #7786

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/demo-app/table/table-demo.html
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ <h3>CdkTable Example</h3>
<!-- Column Definition: ID -->
<ng-container cdkColumnDef="userId">
<cdk-header-cell *cdkHeaderCellDef
mat-sort-header arrowPosition="before">
mat-sort-header arrowPosition="before" disabled>
ID
</cdk-header-cell>
<cdk-cell *cdkCellDef="let row"> {{row.id}} </cdk-cell>
Expand Down Expand Up @@ -228,7 +228,7 @@ <h3>MatTable With MatTableDataSource Example</h3>

<!-- Column Definition: ID -->
<ng-container cdkColumnDef="userId">
<mat-header-cell *matHeaderCellDef mat-sort-header> ID </mat-header-cell>
<mat-header-cell *matHeaderCellDef mat-sort-header disabled> ID </mat-header-cell>
<mat-cell *matCellDef="let row"> {{row.id}} </mat-cell>
</ng-container>

Expand Down
3 changes: 3 additions & 0 deletions src/lib/sort/sort-header.html
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
<div class="mat-sort-header-container"
[class.mat-sort-header-disabled]="disabled"
[class.mat-sort-header-position-before]="arrowPosition == 'before'">

<button class="mat-sort-header-button" type="button"
[disabled]="disabled"
[attr.aria-label]="_intl.sortButtonLabel(id)">
<ng-content></ng-content>
</button>
Expand Down
5 changes: 5 additions & 0 deletions src/lib/sort/sort-header.scss
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,11 @@ $mat-sort-header-arrow-transition: 225ms cubic-bezier(0.4, 0, 0.2, 1);
color: currentColor;
}

.mat-sort-header-disabled,
.mat-sort-header-button[disabled] {
cursor: default;
}

.mat-sort-header-arrow {
height: $mat-sort-header-arrow-container-size;
width: $mat-sort-header-arrow-container-size;
Expand Down
35 changes: 24 additions & 11 deletions src/lib/sort/sort-header.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,25 +15,28 @@ import {
ViewEncapsulation
} from '@angular/core';
import {coerceBooleanProperty} from '@angular/cdk/coercion';
import {
trigger,
state,
style,
animate,
transition,
keyframes,
} from '@angular/animations';
import {animate, keyframes, state, style, transition, trigger} from '@angular/animations';
import {CdkColumnDef} from '@angular/cdk/table';
import {Subscription} from 'rxjs/Subscription';
import {merge} from 'rxjs/observable/merge';
import {MatSort, MatSortable} from './sort';
import {MatSortHeaderIntl} from './sort-header-intl';
import {getSortHeaderNotContainedWithinSortError} from './sort-errors';
import {AnimationCurves, AnimationDurations} from '@angular/material/core';
import {
AnimationCurves,
AnimationDurations,
CanDisable,
mixinDisabled
} from '@angular/material/core';

const SORT_ANIMATION_TRANSITION =
AnimationDurations.ENTERING + ' ' + AnimationCurves.STANDARD_CURVE;

// Boilerplate for applying mixins to MatSortHeader.
/** @docs-private */
export class MatSortHeaderBase { }
export const _MatSortHeaderMixinBase = mixinDisabled(MatSortHeaderBase);

/**
* Applies sorting behavior (click to change sort) and styles to an element, including an
* arrow to display the current sort direction.
Expand All @@ -49,8 +52,9 @@ const SORT_ANIMATION_TRANSITION =
exportAs: 'matSortHeader',
templateUrl: 'sort-header.html',
styleUrls: ['sort-header.css'],
inputs: ['disabled'],
host: {
'(click)': '_sort.sort(this)',
'(click)': '_handleClick()',
'[class.mat-sort-header-sorted]': '_isSorted()',
},
encapsulation: ViewEncapsulation.None,
Expand Down Expand Up @@ -93,7 +97,7 @@ const SORT_ANIMATION_TRANSITION =
])
]
})
export class MatSortHeader implements MatSortable {
export class MatSortHeader extends _MatSortHeaderMixinBase implements MatSortable, CanDisable {
private _rerenderSubscription: Subscription;

/**
Expand All @@ -118,6 +122,8 @@ export class MatSortHeader implements MatSortable {
changeDetectorRef: ChangeDetectorRef,
@Optional() public _sort: MatSort,
@Optional() public _cdkColumnDef: CdkColumnDef) {
super();

if (!_sort) {
throw getSortHeaderNotContainedWithinSortError();
}
Expand All @@ -140,6 +146,13 @@ export class MatSortHeader implements MatSortable {
this._rerenderSubscription.unsubscribe();
}

/** Triggers the sort on this sort header if it is not disabled. */
_handleClick() {
if (!this.disabled) {
this._sort.sort(this);
}
}

/** Whether this MatSortHeader is currently sorted in either ascending or descending order. */
_isSorted() {
return this._sort.active == this.id &&
Expand Down
23 changes: 19 additions & 4 deletions src/lib/sort/sort.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,19 +52,34 @@ describe('MatSort', () => {

it('should have the sort headers register and deregister themselves', () => {
const sortables = component.matSort.sortables;
expect(sortables.size).toBe(4);
expect(sortables.size).toBe(5);
expect(sortables.get('defaultSortHeaderA')).toBe(component.matSortHeaderDefaultA);
expect(sortables.get('defaultSortHeaderB')).toBe(component.matSortHeaderDefaultB);

fixture.destroy();
expect(sortables.size).toBe(0);
});

it('should be able to disable a sort header', () => {
// With it disabled, it should not set to active
fixture.componentInstance.sort('sortF');
fixture.detectChanges();
expect(component.matSort.active).toBe(undefined);

// Set disabled to false
fixture.componentInstance.disableSortF = false;
fixture.detectChanges();

// Sort should work
fixture.componentInstance.sort('sortF');
fixture.detectChanges();
expect(component.matSort.active).toBe('sortF');
});

it('should use the column definition if used within a cdk table', () => {
let cdkTableMatSortAppFixture = TestBed.createComponent(CdkTableMatSortApp);
let cdkTableMatSortAppComponent = cdkTableMatSortAppFixture.componentInstance;

cdkTableMatSortAppFixture.detectChanges();
cdkTableMatSortAppFixture.detectChanges();

const sortables = cdkTableMatSortAppComponent.matSort.sortables;
Expand All @@ -78,7 +93,6 @@ describe('MatSort', () => {
let matTableMatSortAppFixture = TestBed.createComponent(MatTableMatSortApp);
let matTableMatSortAppComponent = matTableMatSortAppFixture.componentInstance;

matTableMatSortAppFixture.detectChanges();
matTableMatSortAppFixture.detectChanges();

const sortables = matTableMatSortAppComponent.matSort.sortables;
Expand Down Expand Up @@ -223,6 +237,7 @@ function testSingleColumnSortDirectionSequence(fixture: ComponentFixture<SimpleM
</div>
<div id="overrideStart" mat-sort-header="overrideStart" start="desc"> D </div>
<div id="overrideDisableClear" mat-sort-header="overrideDisableClear" disableClear> E </div>
<div id="sortF" mat-sort-header="sortF" [disabled]="disableSortF"> F </div>
</div>
`
})
Expand All @@ -232,6 +247,7 @@ class SimpleMatSortApp {
active: string;
start: SortDirection = 'asc';
direction: SortDirection = '';
disableSortF = true;
disableClear: boolean;

@ViewChild(MatSort) matSort: MatSort;
Expand All @@ -246,7 +262,6 @@ class SimpleMatSortApp {
}
}


class FakeDataSource extends DataSource<any> {
connect(collectionViewer: CollectionViewer): Observable<any[]> {
return map.call(collectionViewer.viewChange, () => []);
Expand Down