Skip to content

feat(material/select): add a global option to specify overlay panel class #20702

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

Merged
merged 2 commits into from
Oct 7, 2020
Merged
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
1 change: 1 addition & 0 deletions src/material-experimental/mdc-select/select.html
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
cdkConnectedOverlayLockPosition
cdkConnectedOverlayHasBackdrop
cdkConnectedOverlayBackdropClass="cdk-overlay-transparent-backdrop"
[cdkConnectedOverlayPanelClass]="_overlayPanelClass"
[cdkConnectedOverlayScrollStrategy]="_scrollStrategy"
[cdkConnectedOverlayOrigin]="_preferredOverlayOrigin || fallbackOverlayOrigin"
[cdkConnectedOverlayOpen]="panelOpen"
Expand Down
11 changes: 8 additions & 3 deletions src/material-experimental/mdc-select/select.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3732,21 +3732,26 @@ describe('MDC-based MatSelect', () => {

});

it('should be able to provide default values through an injection token', () => {
it('should be able to provide default values through an injection token', fakeAsync(() => {
configureMatSelectTestingModule([NgModelSelect], [{
provide: MAT_SELECT_CONFIG,
useValue: {
disableOptionCentering: true,
typeaheadDebounceInterval: 1337
typeaheadDebounceInterval: 1337,
overlayPanelClass: 'test-panel-class',
} as MatSelectConfig
}]);
const fixture = TestBed.createComponent(NgModelSelect);
fixture.detectChanges();
const select = fixture.componentInstance.select;
select.open();
fixture.detectChanges();
flush();

expect(select.disableOptionCentering).toBe(true);
expect(select.typeaheadDebounceInterval).toBe(1337);
});
expect(document.querySelector('.cdk-overlay-pane')?.classList).toContain('test-panel-class');
}));

it('should not not throw if the select is inside an ng-container with ngIf', fakeAsync(() => {
configureMatSelectTestingModule([SelectInNgContainer]);
Expand Down
1 change: 1 addition & 0 deletions src/material/select/select.html
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
cdkConnectedOverlayLockPosition
cdkConnectedOverlayHasBackdrop
cdkConnectedOverlayBackdropClass="cdk-overlay-transparent-backdrop"
[cdkConnectedOverlayPanelClass]="_overlayPanelClass"
[cdkConnectedOverlayScrollStrategy]="_scrollStrategy"
[cdkConnectedOverlayOrigin]="origin"
[cdkConnectedOverlayOpen]="panelOpen"
Expand Down
11 changes: 8 additions & 3 deletions src/material/select/select.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4583,21 +4583,26 @@ describe('MatSelect', () => {

});

it('should be able to provide default values through an injection token', () => {
it('should be able to provide default values through an injection token', fakeAsync(() => {
configureMatSelectTestingModule([NgModelSelect], [{
provide: MAT_SELECT_CONFIG,
useValue: {
disableOptionCentering: true,
typeaheadDebounceInterval: 1337
typeaheadDebounceInterval: 1337,
overlayPanelClass: 'test-panel-class',
} as MatSelectConfig
}]);
const fixture = TestBed.createComponent(NgModelSelect);
fixture.detectChanges();
const select = fixture.componentInstance.select;
select.open();
fixture.detectChanges();
flush();

expect(select.disableOptionCentering).toBe(true);
expect(select.typeaheadDebounceInterval).toBe(1337);
});
expect(document.querySelector('.cdk-overlay-pane')?.classList).toContain('test-panel-class');
}));

it('should not not throw if the select is inside an ng-container with ngIf', fakeAsync(() => {
configureMatSelectTestingModule([SelectInNgContainer]);
Expand Down
21 changes: 8 additions & 13 deletions src/material/select/select.ts
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,9 @@ export interface MatSelectConfig {

/** Time to wait in milliseconds after the last keystroke before moving focus to an item. */
typeaheadDebounceInterval?: number;

/** Class or list of classes to be applied to the menu's overlay panel. */
overlayPanelClass?: string | string[];
}

/** Injection token that can be used to provide the default options the select module. */
Expand Down Expand Up @@ -311,6 +314,8 @@ export abstract class _MatSelectBase<C> extends _MatSelectMixinBase implements A
/** Strategy that will be used to handle scrolling while the select panel is open. */
_scrollStrategy: ScrollStrategy;

_overlayPanelClass: string | string[] = this._defaultOptions?.overlayPanelClass || '';

/** Whether the select is focused. */
get focused(): boolean {
return this._focused || this._panelOpen;
Expand Down Expand Up @@ -373,7 +378,7 @@ export abstract class _MatSelectBase<C> extends _MatSelectMixinBase implements A
set disableOptionCentering(value: boolean) {
this._disableOptionCentering = coerceBooleanProperty(value);
}
private _disableOptionCentering: boolean = false;
private _disableOptionCentering = this._defaultOptions?.disableOptionCentering ?? false;

/**
* Function to compare the option values with the selected values. The first argument
Expand Down Expand Up @@ -422,7 +427,7 @@ export abstract class _MatSelectBase<C> extends _MatSelectMixinBase implements A
set typeaheadDebounceInterval(value: number) {
this._typeaheadDebounceInterval = coerceNumberProperty(value);
}
private _typeaheadDebounceInterval: number;
private _typeaheadDebounceInterval = this._defaultOptions?.typeaheadDebounceInterval ?? 0;

/**
* Function used to sort the values in a select in multiple mode.
Expand Down Expand Up @@ -489,7 +494,7 @@ export abstract class _MatSelectBase<C> extends _MatSelectMixinBase implements A
@Attribute('tabindex') tabIndex: string,
@Inject(MAT_SELECT_SCROLL_STRATEGY) scrollStrategyFactory: any,
private _liveAnnouncer: LiveAnnouncer,
@Optional() @Inject(MAT_SELECT_CONFIG) defaults?: MatSelectConfig) {
@Optional() @Inject(MAT_SELECT_CONFIG) private _defaultOptions?: MatSelectConfig) {
super(elementRef, _defaultErrorStateMatcher, _parentForm,
_parentFormGroup, ngControl);

Expand All @@ -505,16 +510,6 @@ export abstract class _MatSelectBase<C> extends _MatSelectMixinBase implements A

// Force setter to be called in case id was not specified.
this.id = this.id;

if (defaults) {
if (defaults.disableOptionCentering != null) {
this.disableOptionCentering = defaults.disableOptionCentering;
}

if (defaults.typeaheadDebounceInterval != null) {
this.typeaheadDebounceInterval = defaults.typeaheadDebounceInterval;
}
}
}

ngOnInit() {
Expand Down
4 changes: 3 additions & 1 deletion tools/public_api_guard/material/select.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ export declare abstract class _MatSelectBase<C> extends _MatSelectMixinBase impl
_onChange: (value: any) => void;
_onTouched: () => void;
readonly _openedStream: Observable<void>;
_overlayPanelClass: string | string[];
_panelDoneAnimatingStream: Subject<string>;
protected _parentFormField: MatFormField;
abstract _positions: ConnectedPosition[];
Expand Down Expand Up @@ -56,7 +57,7 @@ export declare abstract class _MatSelectBase<C> extends _MatSelectMixinBase impl
get value(): any;
set value(newValue: any);
readonly valueChange: EventEmitter<any>;
constructor(_viewportRuler: ViewportRuler, _changeDetectorRef: ChangeDetectorRef, _ngZone: NgZone, _defaultErrorStateMatcher: ErrorStateMatcher, elementRef: ElementRef, _dir: Directionality, _parentForm: NgForm, _parentFormGroup: FormGroupDirective, _parentFormField: MatFormField, ngControl: NgControl, tabIndex: string, scrollStrategyFactory: any, _liveAnnouncer: LiveAnnouncer, defaults?: MatSelectConfig);
constructor(_viewportRuler: ViewportRuler, _changeDetectorRef: ChangeDetectorRef, _ngZone: NgZone, _defaultErrorStateMatcher: ErrorStateMatcher, elementRef: ElementRef, _dir: Directionality, _parentForm: NgForm, _parentFormGroup: FormGroupDirective, _parentFormField: MatFormField, ngControl: NgControl, tabIndex: string, scrollStrategyFactory: any, _liveAnnouncer: LiveAnnouncer, _defaultOptions?: MatSelectConfig | undefined);
protected _canOpen(): boolean;
_getAriaActiveDescendant(): string | null;
protected abstract _getChangeEvent(value: any): C;
Expand Down Expand Up @@ -145,6 +146,7 @@ export declare class MatSelectChange {

export interface MatSelectConfig {
disableOptionCentering?: boolean;
overlayPanelClass?: string | string[];
typeaheadDebounceInterval?: number;
}

Expand Down