From d41f2afd8182cfc39c62817dbf207a8f99e21133 Mon Sep 17 00:00:00 2001 From: Jeremy Elbourn Date: Thu, 6 Apr 2017 16:25:28 -0600 Subject: [PATCH] chore: add a mixin for disabled and apply it to md-button --- src/lib/button/button.ts | 21 ++++++++++-------- .../core/common-behaviors/disabled.spec.ts | 18 +++++++++++++++ src/lib/core/common-behaviors/disabled.ts | 22 +++++++++++++++++++ src/lib/core/common-behaviors/index.ts | 1 + 4 files changed, 53 insertions(+), 9 deletions(-) create mode 100644 src/lib/core/common-behaviors/disabled.spec.ts create mode 100644 src/lib/core/common-behaviors/disabled.ts create mode 100644 src/lib/core/common-behaviors/index.ts diff --git a/src/lib/button/button.ts b/src/lib/button/button.ts index 9a96d5750993..9f37877dfcd5 100644 --- a/src/lib/button/button.ts +++ b/src/lib/button/button.ts @@ -10,6 +10,7 @@ import { ViewEncapsulation } from '@angular/core'; import {coerceBooleanProperty, FocusOriginMonitor} from '../core'; +import {mixinDisabled, CanDisable} from '../core/common-behaviors/disabled'; // TODO(kara): Convert attribute selectors to classes when attr maps become available @@ -79,6 +80,11 @@ export class MdFabCssMatStyler {} export class MdMiniFabCssMatStyler {} +// Boilerplate for applying mixins to MdButton. +export class MdButtonBase { } +export const _MdButtonMixinBase = mixinDisabled(MdButtonBase); + + /** * Material design button. */ @@ -89,14 +95,15 @@ export class MdMiniFabCssMatStyler {} 'button[mat-button], button[mat-raised-button], button[mat-icon-button],' + 'button[mat-fab], button[mat-mini-fab]', host: { - '[disabled]': 'disabled', + '[disabled]': 'disabled || null', }, + inputs: ['disabled'], templateUrl: 'button.html', styleUrls: ['button.css'], encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, }) -export class MdButton implements OnDestroy { +export class MdButton extends _MdButtonMixinBase implements OnDestroy, CanDisable { private _color: string; /** Whether the button is round. */ @@ -107,20 +114,15 @@ export class MdButton implements OnDestroy { /** Whether the ripple effect on click should be disabled. */ private _disableRipple: boolean = false; - private _disabled: boolean = null; /** Whether the ripple effect for this button is disabled. */ @Input() get disableRipple() { return this._disableRipple; } set disableRipple(v) { this._disableRipple = coerceBooleanProperty(v); } - /** Whether the button is disabled. */ - @Input() - get disabled() { return this._disabled; } - set disabled(value: boolean) { this._disabled = coerceBooleanProperty(value) ? true : null; } - constructor(private _elementRef: ElementRef, private _renderer: Renderer, private _focusOriginMonitor: FocusOriginMonitor) { + super(); this._focusOriginMonitor.monitor(this._elementRef.nativeElement, this._renderer, true); } @@ -179,10 +181,11 @@ export class MdButton implements OnDestroy { selector: `a[md-button], a[md-raised-button], a[md-icon-button], a[md-fab], a[md-mini-fab], a[mat-button], a[mat-raised-button], a[mat-icon-button], a[mat-fab], a[mat-mini-fab]`, host: { - '[attr.disabled]': 'disabled', + '[attr.disabled]': 'disabled || null', '[attr.aria-disabled]': '_isAriaDisabled', '(click)': '_haltDisabledEvents($event)', }, + inputs: ['disabled'], templateUrl: 'button.html', styleUrls: ['button.css'], encapsulation: ViewEncapsulation.None diff --git a/src/lib/core/common-behaviors/disabled.spec.ts b/src/lib/core/common-behaviors/disabled.spec.ts new file mode 100644 index 000000000000..0e28f3177b1f --- /dev/null +++ b/src/lib/core/common-behaviors/disabled.spec.ts @@ -0,0 +1,18 @@ +import {mixinDisabled} from './disabled'; + + +describe('MixinDisabled', () => { + it('should augment an existing class with a disabled property', () => { + class EmptyClass { } + + let classWithDisabled = mixinDisabled(EmptyClass); + let instance = new classWithDisabled(); + + expect(instance.disabled) + .toBe(false, 'Expected the mixed-into class to have a disabled property'); + + instance.disabled = true; + expect(instance.disabled) + .toBe(true, 'Expected the mixed-into class to have an updated disabled property'); + }); +}); diff --git a/src/lib/core/common-behaviors/disabled.ts b/src/lib/core/common-behaviors/disabled.ts new file mode 100644 index 000000000000..8c290d1e8fdd --- /dev/null +++ b/src/lib/core/common-behaviors/disabled.ts @@ -0,0 +1,22 @@ +import {coerceBooleanProperty} from '../coercion/boolean-property'; + + +/** @docs-private */ +export type Constructor = new(...args: any[]) => T; + +/** @docs-private */ +export interface CanDisable { + disabled: boolean; +} + +/** Mixin to augment a directive with a `disabled` property. */ +export function mixinDisabled>(base: T): Constructor & T { + return class extends base { + private _disabled: boolean = false; + + get disabled() { return this._disabled; } + set disabled(value: any) { this._disabled = coerceBooleanProperty(value); } + + constructor(...args: any[]) { super(...args); } + }; +} diff --git a/src/lib/core/common-behaviors/index.ts b/src/lib/core/common-behaviors/index.ts new file mode 100644 index 000000000000..5aaccb7b57d7 --- /dev/null +++ b/src/lib/core/common-behaviors/index.ts @@ -0,0 +1 @@ +export {CanDisable, mixinDisabled} from './disabled';