From 0206d6fca2aef0501deee1cd636a05576043af7d Mon Sep 17 00:00:00 2001 From: Paul Gschwendtner Date: Fri, 16 Jun 2017 21:28:23 +0200 Subject: [PATCH] refactor: replace disabled getters/setters with mixin (#5137) --- src/lib/button-toggle/button-toggle.ts | 40 +++++++------------------- src/lib/menu/menu-item.ts | 28 +++++++++--------- src/lib/select/select.ts | 21 ++++---------- src/lib/tabs/tab-label-wrapper.ts | 22 +++++++------- src/lib/tabs/tab.ts | 21 +++++++------- 5 files changed, 49 insertions(+), 83 deletions(-) diff --git a/src/lib/button-toggle/button-toggle.ts b/src/lib/button-toggle/button-toggle.ts index efdf17e6a34..4475dec407d 100644 --- a/src/lib/button-toggle/button-toggle.ts +++ b/src/lib/button-toggle/button-toggle.ts @@ -25,13 +25,15 @@ import { AfterViewInit, } from '@angular/core'; import {NG_VALUE_ACCESSOR, ControlValueAccessor} from '@angular/forms'; -import {Observable} from 'rxjs/Observable'; import {UniqueSelectionDispatcher, coerceBooleanProperty, FocusOriginMonitor} from '../core'; +import {CanDisable, mixinDisabled} from '../core/common-behaviors/disabled'; /** Acceptable types for a button toggle. */ export type ToggleType = 'checkbox' | 'radio'; - +// Boilerplate for applying mixins to MdButtonToggleGroup and MdButtonToggleGroupMultiple +export class MdButtonToggleGroupBase {} +export const _MdButtonToggleGroupMixinBase = mixinDisabled(MdButtonToggleGroupBase); /** * Provider Expression that allows md-button-toggle-group to register as a ControlValueAccessor. @@ -58,6 +60,7 @@ export class MdButtonToggleChange { @Directive({ selector: 'md-button-toggle-group:not([multiple]), mat-button-toggle-group:not([multiple])', providers: [MD_BUTTON_TOGGLE_GROUP_VALUE_ACCESSOR], + inputs: ['disabled'], host: { 'role': 'radiogroup', 'class': 'mat-button-toggle-group', @@ -65,16 +68,15 @@ export class MdButtonToggleChange { }, exportAs: 'mdButtonToggleGroup', }) -export class MdButtonToggleGroup implements AfterViewInit, ControlValueAccessor { +export class MdButtonToggleGroup extends _MdButtonToggleGroupMixinBase implements AfterViewInit, + ControlValueAccessor, CanDisable { + /** The value for the button toggle group. Should match currently selected button toggle. */ private _value: any = null; /** The HTML name attribute applied to toggles in this group. */ private _name: string = `md-button-toggle-group-${_uniqueIdCounter++}`; - /** Disables all toggles in the group. */ - private _disabled: boolean = null; - /** Whether the button toggle group should be vertical. */ private _vertical: boolean = false; @@ -112,16 +114,6 @@ export class MdButtonToggleGroup implements AfterViewInit, ControlValueAccessor this._updateButtonToggleNames(); } - /** Whether the toggle group is disabled. */ - @Input() - get disabled(): boolean { - return this._disabled; - } - - set disabled(value) { - this._disabled = coerceBooleanProperty(value); - } - /** Whether the toggle group is vertical. */ @Input() get vertical(): boolean { @@ -245,28 +237,18 @@ export class MdButtonToggleGroup implements AfterViewInit, ControlValueAccessor @Directive({ selector: 'md-button-toggle-group[multiple], mat-button-toggle-group[multiple]', exportAs: 'mdButtonToggleGroup', + inputs: ['disabled'], host: { 'class': 'mat-button-toggle-group', '[class.mat-button-toggle-vertical]': 'vertical' } }) -export class MdButtonToggleGroupMultiple { - /** Disables all toggles in the group. */ - private _disabled: boolean = null; +export class MdButtonToggleGroupMultiple extends _MdButtonToggleGroupMixinBase + implements CanDisable { /** Whether the button toggle group should be vertical. */ private _vertical: boolean = false; - /** Whether the toggle group is disabled. */ - @Input() - get disabled(): boolean { - return this._disabled; - } - - set disabled(value) { - this._disabled = (value != null && value !== false) ? true : null; - } - /** Whether the toggle group is vertical. */ @Input() get vertical(): boolean { diff --git a/src/lib/menu/menu-item.ts b/src/lib/menu/menu-item.ts index 491a6099691..ff5d8fbd09f 100644 --- a/src/lib/menu/menu-item.ts +++ b/src/lib/menu/menu-item.ts @@ -6,9 +6,13 @@ * found in the LICENSE file at https://angular.io/license */ -import {Component, ElementRef, Input} from '@angular/core'; +import {Component, ElementRef} from '@angular/core'; import {Focusable} from '../core/a11y/focus-key-manager'; -import {coerceBooleanProperty} from '../core/coercion/boolean-property'; +import {CanDisable, mixinDisabled} from '../core/common-behaviors/disabled'; + +// Boilerplate for applying mixins to MdMenuItem. +export class MdMenuItemBase {} +export const _MdMenuItemMixinBase = mixinDisabled(MdMenuItemBase); /** * This directive is intended to be used inside an md-menu tag. @@ -17,6 +21,7 @@ import {coerceBooleanProperty} from '../core/coercion/boolean-property'; @Component({ moduleId: module.id, selector: '[md-menu-item], [mat-menu-item]', + inputs: ['disabled'], host: { 'role': 'menuitem', 'class': 'mat-menu-item', @@ -28,32 +33,25 @@ import {coerceBooleanProperty} from '../core/coercion/boolean-property'; templateUrl: 'menu-item.html', exportAs: 'mdMenuItem' }) -export class MdMenuItem implements Focusable { - /** Whether the menu item is disabled */ - private _disabled: boolean = false; +export class MdMenuItem extends _MdMenuItemMixinBase implements Focusable, CanDisable { - constructor(private _elementRef: ElementRef) {} + constructor(private _elementRef: ElementRef) { + super(); + } /** Focuses the menu item. */ focus(): void { this._getHostElement().focus(); } - /** Whether the menu item is disabled. */ - @Input() - get disabled() { return this._disabled; } - set disabled(value: any) { - this._disabled = coerceBooleanProperty(value); - } - /** Used to set the `tabindex`. */ _getTabIndex(): string { - return this._disabled ? '-1' : '0'; + return this.disabled ? '-1' : '0'; } /** Used to set the HTML `disabled` attribute. Necessary for links to be disabled properly. */ _getDisabledAttr(): boolean { - return this._disabled ? true : null; + return this.disabled ? true : null; } /** Returns the host DOM element. */ diff --git a/src/lib/select/select.ts b/src/lib/select/select.ts index 7be1cf9f60e..e0cc93ee342 100644 --- a/src/lib/select/select.ts +++ b/src/lib/select/select.ts @@ -38,13 +38,12 @@ import {coerceBooleanProperty} from '../core/coercion/boolean-property'; import {ConnectedOverlayDirective} from '../core/overlay/overlay-directives'; import {ViewportRuler} from '../core/overlay/position/viewport-ruler'; import {SelectionModel} from '../core/selection/selection'; -import {ScrollDispatcher} from '../core/overlay/scroll/scroll-dispatcher'; import {getMdSelectDynamicMultipleError, getMdSelectNonArrayValueError} from './select-errors'; import 'rxjs/add/observable/merge'; import 'rxjs/add/operator/startWith'; import 'rxjs/add/operator/filter'; import {CanColor, mixinColor} from '../core/common-behaviors/color'; -import {CanDisable} from '../core/common-behaviors/disabled'; +import {CanDisable, mixinDisabled} from '../core/common-behaviors/disabled'; import { FloatPlaceholderType, PlaceholderOptions, @@ -114,14 +113,14 @@ export class MdSelectChange { export class MdSelectBase { constructor(public _renderer: Renderer2, public _elementRef: ElementRef) {} } -export const _MdSelectMixinBase = mixinColor(MdSelectBase, 'primary'); +export const _MdSelectMixinBase = mixinColor(mixinDisabled(MdSelectBase), 'primary'); @Component({ moduleId: module.id, selector: 'md-select, mat-select', templateUrl: 'select.html', styleUrls: ['select.css'], - inputs: ['color'], + inputs: ['color', 'disabled'], encapsulation: ViewEncapsulation.None, host: { 'role': 'listbox', @@ -145,7 +144,7 @@ export const _MdSelectMixinBase = mixinColor(MdSelectBase, 'primary'); exportAs: 'mdSelect', }) export class MdSelect extends _MdSelectMixinBase implements AfterContentInit, OnDestroy, OnInit, - ControlValueAccessor, CanColor { + ControlValueAccessor, CanColor, CanDisable { /** Whether or not the overlay panel is open. */ private _panelOpen = false; @@ -161,9 +160,6 @@ export class MdSelect extends _MdSelectMixinBase implements AfterContentInit, On /** Whether filling out the select is required in the form. */ private _required: boolean = false; - /** Whether the select is disabled. */ - private _disabled: boolean = false; - /** The scroll position of the overlay panel, calculated to center the selected option. */ private _scrollTop = 0; @@ -268,13 +264,6 @@ export class MdSelect extends _MdSelectMixinBase implements AfterContentInit, On Promise.resolve(null).then(() => this._setTriggerWidth()); } - /** Whether the component is disabled. */ - @Input() - get disabled() { return this._disabled; } - set disabled(value: any) { - this._disabled = coerceBooleanProperty(value); - } - /** Whether the component is required. */ @Input() get required() { return this._required; } @@ -301,7 +290,7 @@ export class MdSelect extends _MdSelectMixinBase implements AfterContentInit, On /** Tab index for the select element. */ @Input() - get tabIndex(): number { return this._disabled ? -1 : this._tabIndex; } + get tabIndex(): number { return this.disabled ? -1 : this._tabIndex; } set tabIndex(value: number) { if (typeof value !== 'undefined') { this._tabIndex = value; diff --git a/src/lib/tabs/tab-label-wrapper.ts b/src/lib/tabs/tab-label-wrapper.ts index f458e4a85b6..bf3dafbc4c0 100644 --- a/src/lib/tabs/tab-label-wrapper.ts +++ b/src/lib/tabs/tab-label-wrapper.ts @@ -6,9 +6,12 @@ * found in the LICENSE file at https://angular.io/license */ -import {Directive, ElementRef, Input} from '@angular/core'; -import {coerceBooleanProperty} from '../core/coercion/boolean-property'; +import {Directive, ElementRef} from '@angular/core'; +import {CanDisable, mixinDisabled} from '../core/common-behaviors/disabled'; +// Boilerplate for applying mixins to MdTabLabelWrapper. +export class MdTabLabelWrapperBase {} +export const _MdTabLabelWrapperMixinBase = mixinDisabled(MdTabLabelWrapperBase); /** * Used in the `md-tab-group` view to display tab labels. @@ -16,20 +19,15 @@ import {coerceBooleanProperty} from '../core/coercion/boolean-property'; */ @Directive({ selector: '[md-tab-label-wrapper], [mat-tab-label-wrapper]', + inputs: ['disabled'], host: { '[class.mat-tab-disabled]': 'disabled' } }) -export class MdTabLabelWrapper { - constructor(public elementRef: ElementRef) {} - - /** Whether the tab label is disabled. */ - private _disabled: boolean = false; - - /** Whether the element is disabled. */ - @Input() - get disabled() { return this._disabled; } - set disabled(value: any) { this._disabled = coerceBooleanProperty(value); } +export class MdTabLabelWrapper extends _MdTabLabelWrapperMixinBase implements CanDisable { + constructor(public elementRef: ElementRef) { + super(); + } /** Sets focus on the wrapper element */ focus(): void { diff --git a/src/lib/tabs/tab.ts b/src/lib/tabs/tab.ts index b8265e25fb5..b5aeaf14464 100644 --- a/src/lib/tabs/tab.ts +++ b/src/lib/tabs/tab.ts @@ -11,16 +11,20 @@ import { ViewContainerRef, Input, TemplateRef, ViewChild, OnInit, ContentChild, Component } from '@angular/core'; -import {coerceBooleanProperty} from '../core/coercion/boolean-property'; - +import {CanDisable, mixinDisabled} from '../core/common-behaviors/disabled'; import {MdTabLabel} from './tab-label'; +// Boilerplate for applying mixins to MdTab. +export class MdTabBase {} +export const _MdTabMixinBase = mixinDisabled(MdTabBase); + @Component({ moduleId: module.id, selector: 'md-tab, mat-tab', templateUrl: 'tab.html', + inputs: ['disabled'] }) -export class MdTab implements OnInit { +export class MdTab extends _MdTabMixinBase implements OnInit, CanDisable { /** Content for the tab label given by . */ @ContentChild(MdTabLabel) templateLabel: MdTabLabel; @@ -46,14 +50,9 @@ export class MdTab implements OnInit { */ origin: number = null; - private _disabled = false; - - /** Whether the tab is disabled */ - @Input() - set disabled(value: boolean) { this._disabled = coerceBooleanProperty(value); } - get disabled(): boolean { return this._disabled; } - - constructor(private _viewContainerRef: ViewContainerRef) { } + constructor(private _viewContainerRef: ViewContainerRef) { + super(); + } ngOnInit() { this._contentPortal = new TemplatePortal(this._content, this._viewContainerRef);