mirror of
https://github.com/angular/angular.git
synced 2026-09-14 13:54:52 +08:00
feat(select): add option to disable option-based alignment (#9885)
This commit is contained in:
@@ -2704,6 +2704,41 @@ describe('MatSelect', () => {
|
||||
|
||||
});
|
||||
|
||||
describe('with option centering disabled', () => {
|
||||
beforeEach(async(() => configureMatSelectTestingModule([
|
||||
SelectWithoutOptionCentering,
|
||||
])));
|
||||
|
||||
let fixture: ComponentFixture<SelectWithoutOptionCentering>;
|
||||
let trigger: HTMLElement;
|
||||
let select: HTMLElement;
|
||||
let formField: HTMLElement;
|
||||
|
||||
beforeEach(fakeAsync(() => {
|
||||
fixture = TestBed.createComponent(SelectWithoutOptionCentering);
|
||||
fixture.detectChanges();
|
||||
trigger = fixture.debugElement.query(By.css('.mat-select-trigger')).nativeElement;
|
||||
select = fixture.debugElement.query(By.css('mat-select')).nativeElement;
|
||||
formField = fixture.debugElement.query(By.css('mat-form-field')).nativeElement;
|
||||
}));
|
||||
|
||||
it('should not align the active option with the trigger if centering is disabled',
|
||||
fakeAsync(() => {
|
||||
trigger.click();
|
||||
fixture.detectChanges();
|
||||
flush();
|
||||
|
||||
const scrollContainer = document.querySelector('.cdk-overlay-pane .mat-select-panel')!;
|
||||
|
||||
// The panel should be scrolled to 0 because centering the option disabled.
|
||||
expect(scrollContainer.scrollTop).toEqual(0, `Expected panel not to be scrolled.`);
|
||||
// The trigger should contain 'Pizza' because it was preselected
|
||||
expect(trigger.textContent).toContain('Pizza');
|
||||
// The selected index should be 1 because it was preselected
|
||||
expect(fixture.componentInstance.options.toArray()[1].selected).toBe(true);
|
||||
}));
|
||||
});
|
||||
|
||||
describe('positioning', () => {
|
||||
beforeEach(async(() => configureMatSelectTestingModule([
|
||||
BasicSelect,
|
||||
@@ -4445,3 +4480,32 @@ class SingleSelectWithPreselectedArrayValues {
|
||||
@ViewChild(MatSelect) select: MatSelect;
|
||||
@ViewChildren(MatOption) options: QueryList<MatOption>;
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'select-without-option-centering',
|
||||
template: `
|
||||
<mat-form-field>
|
||||
<mat-select placeholder="Food" [formControl]="control" disableOptionCentering>
|
||||
<mat-option *ngFor="let food of foods" [value]="food.value">
|
||||
{{ food.viewValue }}
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
`
|
||||
})
|
||||
class SelectWithoutOptionCentering {
|
||||
foods: any[] = [
|
||||
{ value: 'steak-0', viewValue: 'Steak' },
|
||||
{ value: 'pizza-1', viewValue: 'Pizza' },
|
||||
{ value: 'tacos-2', viewValue: 'Tacos'},
|
||||
{ value: 'sandwich-3', viewValue: 'Sandwich' },
|
||||
{ value: 'chips-4', viewValue: 'Chips' },
|
||||
{ value: 'eggs-5', viewValue: 'Eggs' },
|
||||
{ value: 'pasta-6', viewValue: 'Pasta' },
|
||||
{ value: 'sushi-7', viewValue: 'Sushi' },
|
||||
];
|
||||
control = new FormControl('pizza-1');
|
||||
|
||||
@ViewChild(MatSelect) select: MatSelect;
|
||||
@ViewChildren(MatOption) options: QueryList<MatOption>;
|
||||
}
|
||||
|
||||
@@ -308,6 +308,9 @@ export class MatSelect extends _MatSelectMixinBase implements AfterContentInit,
|
||||
},
|
||||
];
|
||||
|
||||
/** Whether the component is disabling centering of the active option over the trigger. */
|
||||
private _disableOptionCentering: boolean = false;
|
||||
|
||||
/** Whether the select is focused. */
|
||||
focused: boolean = false;
|
||||
|
||||
@@ -362,6 +365,13 @@ export class MatSelect extends _MatSelectMixinBase implements AfterContentInit,
|
||||
this._multiple = coerceBooleanProperty(value);
|
||||
}
|
||||
|
||||
/** Whether to center the active option over the trigger. */
|
||||
@Input()
|
||||
get disableOptionCentering(): boolean { return this._disableOptionCentering; }
|
||||
set disableOptionCentering(value: boolean) {
|
||||
this._disableOptionCentering = coerceBooleanProperty(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* A function to compare the option values with the selected values. The first argument
|
||||
* is a value from an option. The second is a value from the selection. A boolean
|
||||
@@ -1118,6 +1128,11 @@ export class MatSelect extends _MatSelectMixinBase implements AfterContentInit,
|
||||
const maxOptionsDisplayed = Math.floor(SELECT_PANEL_MAX_HEIGHT / itemHeight);
|
||||
let optionOffsetFromPanelTop: number;
|
||||
|
||||
// Disable offset if requested by user by returning 0 as value to offset
|
||||
if (this._disableOptionCentering) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (this._scrollTop === 0) {
|
||||
optionOffsetFromPanelTop = selectedIndex * itemHeight;
|
||||
} else if (this._scrollTop === maxScroll) {
|
||||
|
||||
Reference in New Issue
Block a user