Skip to content

Commit

Permalink
fix(button-toggle): indirect descendant buttons not picked up… (#17451)
Browse files Browse the repository at this point in the history
Fixes button toggles that aren't direct descendants of the button group not being picked up in some cases.
  • Loading branch information
crisbeto authored and mmalerba committed Oct 21, 2019
1 parent c50aa21 commit 67b009f
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 2 deletions.
1 change: 1 addition & 0 deletions src/material/button-toggle/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ ng_test_library(
deps = [
":button-toggle",
"//src/cdk/testing",
"@npm//@angular/common",
"@npm//@angular/forms",
"@npm//@angular/platform-browser",
],
Expand Down
38 changes: 37 additions & 1 deletion src/material/button-toggle/button-toggle.spec.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import {dispatchMouseEvent} from '@angular/cdk/testing';
import {Component, DebugElement, QueryList, ViewChild, ViewChildren} from '@angular/core';
import {CommonModule} from '@angular/common';
import {ComponentFixture, fakeAsync, flush, TestBed, tick} from '@angular/core/testing';
import {FormControl, FormsModule, NgModel, ReactiveFormsModule} from '@angular/forms';
import {By} from '@angular/platform-browser';
Expand All @@ -15,10 +16,11 @@ describe('MatButtonToggle with forms', () => {

beforeEach(fakeAsync(() => {
TestBed.configureTestingModule({
imports: [MatButtonToggleModule, FormsModule, ReactiveFormsModule],
imports: [MatButtonToggleModule, FormsModule, ReactiveFormsModule, CommonModule],
declarations: [
ButtonToggleGroupWithNgModel,
ButtonToggleGroupWithFormControl,
ButtonToggleGroupWithIndirectDescendantToggles,
],
});

Expand Down Expand Up @@ -232,6 +234,24 @@ describe('MatButtonToggle with forms', () => {
}));

});

it('should be able to pick up toggles that are not direct descendants', fakeAsync(() => {
const fixture = TestBed.createComponent(ButtonToggleGroupWithIndirectDescendantToggles);
fixture.detectChanges();

const button = fixture.nativeElement.querySelector('.mat-button-toggle button');
const groupDebugElement = fixture.debugElement.query(By.directive(MatButtonToggleGroup))!;
const groupInstance =
groupDebugElement.injector.get<MatButtonToggleGroup>(MatButtonToggleGroup);

button.click();
fixture.detectChanges();
tick();

expect(groupInstance.value).toBe('red');
expect(fixture.componentInstance.control.value).toBe('red');
expect(groupInstance._buttonToggles.length).toBe(3);
}));
});

describe('MatButtonToggle without forms', () => {
Expand Down Expand Up @@ -966,6 +986,22 @@ class ButtonToggleGroupWithFormControl {
control = new FormControl();
}

@Component({
// We need the `ngSwitch` so that there's a directive between the group and the toggles.
template: `
<mat-button-toggle-group [formControl]="control">
<ng-container [ngSwitch]="true">
<mat-button-toggle value="red">Value Red</mat-button-toggle>
<mat-button-toggle value="green">Value Green</mat-button-toggle>
<mat-button-toggle value="blue">Value Blue</mat-button-toggle>
</ng-container>
</mat-button-toggle-group>
`
})
class ButtonToggleGroupWithIndirectDescendantToggles {
control = new FormControl();
}

/** Simple test component with an aria-label set. */
@Component({
template: `<mat-button-toggle aria-label="Super effective"></mat-button-toggle>`
Expand Down
6 changes: 5 additions & 1 deletion src/material/button-toggle/button-toggle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,11 @@ export class MatButtonToggleGroup implements ControlValueAccessor, OnInit, After
_onTouched: () => any = () => {};

/** Child button toggle buttons. */
@ContentChildren(forwardRef(() => MatButtonToggle)) _buttonToggles: QueryList<MatButtonToggle>;
@ContentChildren(forwardRef(() => MatButtonToggle), {
// Note that this would technically pick up toggles
// from nested groups, but that's not a case that we support.
descendants: true
}) _buttonToggles: QueryList<MatButtonToggle>;

/** The appearance for all the buttons in the group. */
@Input() appearance: MatButtonToggleAppearance;
Expand Down

0 comments on commit 67b009f

Please sign in to comment.