chore: add CanDisable mixin to checkbox, radio-group, slide-toggle, and (#4209)

slider
This commit is contained in:
Jeremy Elbourn
2017-04-27 11:08:30 -07:00
committed by mmalerba
parent bd48f39b6c
commit 6a34f6fa40
5 changed files with 66 additions and 67 deletions
+1 -1
View File
@@ -97,9 +97,9 @@ export const _MdButtonMixinBase = mixinDisabled(MdButtonBase);
host: {
'[disabled]': 'disabled || null',
},
inputs: ['disabled'],
templateUrl: 'button.html',
styleUrls: ['button.css'],
inputs: ['disabled'],
encapsulation: ViewEncapsulation.None,
changeDetection: ChangeDetectionStrategy.OnPush,
})
+18 -21
View File
@@ -1,26 +1,22 @@
import {
ChangeDetectorRef,
AfterViewInit,
ChangeDetectionStrategy,
ChangeDetectorRef,
Component,
ElementRef,
EventEmitter,
forwardRef,
Input,
OnDestroy,
Output,
Renderer,
ViewEncapsulation,
forwardRef,
ViewChild,
AfterViewInit,
OnDestroy,
ViewEncapsulation,
} from '@angular/core';
import {NG_VALUE_ACCESSOR, ControlValueAccessor} from '@angular/forms';
import {ControlValueAccessor, NG_VALUE_ACCESSOR} from '@angular/forms';
import {coerceBooleanProperty} from '../core/coercion/boolean-property';
import {
MdRipple,
RippleRef,
FocusOriginMonitor,
FocusOrigin,
} from '../core';
import {FocusOrigin, FocusOriginMonitor, MdRipple, RippleRef} from '../core';
import {mixinDisabled, CanDisable} from '../core/common-behaviors/disabled';
/** Monotonically increasing integer used to auto-generate unique ids for checkbox components. */
@@ -60,6 +56,11 @@ export class MdCheckboxChange {
checked: boolean;
}
// Boilerplate for applying mixins to MdCheckbox.
export class MdCheckboxBase { }
export const _MdCheckboxMixinBase = mixinDisabled(MdCheckboxBase);
/**
* A material design checkbox component. Supports all of the functionality of an HTML5 checkbox,
* and exposes a similar API. A MdCheckbox can be either checked, unchecked, indeterminate, or
@@ -74,17 +75,19 @@ export class MdCheckboxChange {
templateUrl: 'checkbox.html',
styleUrls: ['checkbox.css'],
host: {
'[class.mat-checkbox]': 'true',
'class': 'mat-checkbox',
'[class.mat-checkbox-indeterminate]': 'indeterminate',
'[class.mat-checkbox-checked]': 'checked',
'[class.mat-checkbox-disabled]': 'disabled',
'[class.mat-checkbox-label-before]': 'labelPosition == "before"',
},
providers: [MD_CHECKBOX_CONTROL_VALUE_ACCESSOR],
inputs: ['disabled'],
encapsulation: ViewEncapsulation.None,
changeDetection: ChangeDetectionStrategy.OnPush
})
export class MdCheckbox implements ControlValueAccessor, AfterViewInit, OnDestroy {
export class MdCheckbox extends _MdCheckboxMixinBase
implements ControlValueAccessor, AfterViewInit, OnDestroy, CanDisable {
/**
* Attached to the aria-label attribute of the host element. In most cases, arial-labelledby will
* take precedence so this may be omitted.
@@ -137,13 +140,6 @@ export class MdCheckbox implements ControlValueAccessor, AfterViewInit, OnDestro
/** Whether the label should appear after or before the checkbox. Defaults to 'after' */
@Input() labelPosition: 'before' | 'after' = 'after';
private _disabled: boolean = false;
/** Whether the checkbox is disabled. */
@Input()
get disabled(): boolean { return this._disabled; }
set disabled(value) { this._disabled = coerceBooleanProperty(value); }
/** Tabindex value that is passed to the underlying input element. */
@Input() tabIndex: number = 0;
@@ -189,6 +185,7 @@ export class MdCheckbox implements ControlValueAccessor, AfterViewInit, OnDestro
private _elementRef: ElementRef,
private _changeDetectorRef: ChangeDetectorRef,
private _focusOriginMonitor: FocusOriginMonitor) {
super();
this.color = 'accent';
}
+10 -14
View File
@@ -26,6 +26,7 @@ import {
FocusOrigin,
} from '../core';
import {coerceBooleanProperty} from '../core/coercion/boolean-property';
import {mixinDisabled, CanDisable} from '../core/common-behaviors/disabled';
/**
@@ -49,6 +50,11 @@ export class MdRadioChange {
value: any;
}
// Boilerplate for applying mixins to MdRadioGroup.
export class MdRadioGroupBase { }
export const _MdRadioGroupMixinBase = mixinDisabled(MdRadioGroupBase);
/**
* A group of radio buttons. May contain one or more `<md-radio-button>` elements.
*/
@@ -59,8 +65,10 @@ export class MdRadioChange {
'role': 'radiogroup',
'[class.mat-radio-group]': 'true',
},
inputs: ['disabled'],
})
export class MdRadioGroup implements AfterContentInit, ControlValueAccessor {
export class MdRadioGroup extends _MdRadioGroupMixinBase
implements AfterContentInit, ControlValueAccessor, CanDisable {
/**
* Selected value for group. Should equal the value of the selected radio button if there *is*
* a corresponding radio button with a matching value. If there is *not* such a corresponding
@@ -72,9 +80,6 @@ export class MdRadioGroup implements AfterContentInit, ControlValueAccessor {
/** The HTML name attribute applied to radio buttons in this group. */
private _name: string = `md-radio-group-${_uniqueIdCounter++}`;
/** Disables all individual radio buttons assigned to this group. */
private _disabled: boolean = false;
/** The currently selected radio button. Should match value. */
private _selected: MdRadioButton = null;
@@ -127,14 +132,6 @@ export class MdRadioGroup implements AfterContentInit, ControlValueAccessor {
/** Whether the labels should appear after or before the radio-buttons. Defaults to 'after' */
@Input() labelPosition: 'before' | 'after' = 'after';
/** Whether the radio button is disabled. */
@Input()
get disabled(): boolean { return this._disabled; }
set disabled(value) {
// The presence of *any* disabled value makes the component disabled, *except* for false.
this._disabled = (value != null && value !== false) ? true : null;
}
/** Value of the radio button. */
@Input()
get value(): any { return this._value; }
@@ -369,8 +366,7 @@ export class MdRadioButton implements OnInit, AfterViewInit, OnDestroy {
}
set disabled(value: boolean) {
// The presence of *any* disabled value makes the component disabled, *except* for false.
this._disabled = (value != null && value !== false) ? true : null;
this._disabled = coerceBooleanProperty(value);
}
/**
+25 -23
View File
@@ -1,28 +1,29 @@
import {
AfterContentInit,
ChangeDetectionStrategy,
Component,
ElementRef,
Renderer,
forwardRef,
ChangeDetectionStrategy,
Input,
Output,
EventEmitter,
AfterContentInit,
ViewChild,
ViewEncapsulation,
forwardRef,
Input,
OnDestroy,
Output,
Renderer,
ViewChild,
ViewEncapsulation
} from '@angular/core';
import {
applyCssTransform,
coerceBooleanProperty,
HammerInput,
FocusOriginMonitor,
FocusOrigin,
FocusOriginMonitor,
HammerInput,
MdRipple,
RippleRef
} from '../core';
import {ControlValueAccessor, NG_VALUE_ACCESSOR} from '@angular/forms';
import {Observable} from 'rxjs/Observable';
import {mixinDisabled, CanDisable} from '../core/common-behaviors/disabled';
export const MD_SLIDE_TOGGLE_VALUE_ACCESSOR: any = {
provide: NG_VALUE_ACCESSOR,
@@ -39,9 +40,13 @@ export class MdSlideToggleChange {
// Increasing integer for generating unique ids for slide-toggle components.
let nextId = 0;
/**
* Two-state control, which can be also called `switch`.
*/
// Boilerplate for applying mixins to MdSlideToggle.
export class MdSlideToggleBase { }
export const _MdSlideToggleMixinBase = mixinDisabled(MdSlideToggleBase);
/** Represents a slidable "switch" toggle that can be moved between on and off. */
@Component({
moduleId: module.id,
selector: 'md-slide-toggle, mat-slide-toggle',
@@ -54,11 +59,12 @@ let nextId = 0;
templateUrl: 'slide-toggle.html',
styleUrls: ['slide-toggle.css'],
providers: [MD_SLIDE_TOGGLE_VALUE_ACCESSOR],
inputs: ['disabled'],
encapsulation: ViewEncapsulation.None,
changeDetection: ChangeDetectionStrategy.OnPush
})
export class MdSlideToggle implements OnDestroy, AfterContentInit, ControlValueAccessor {
export class MdSlideToggle extends _MdSlideToggleMixinBase
implements OnDestroy, AfterContentInit, ControlValueAccessor, CanDisable {
private onChange = (_: any) => {};
private onTouched = () => {};
@@ -67,7 +73,6 @@ export class MdSlideToggle implements OnDestroy, AfterContentInit, ControlValueA
private _checked: boolean = false;
private _color: string;
private _slideRenderer: SlideToggleRenderer = null;
private _disabled: boolean = false;
private _required: boolean = false;
private _disableRipple: boolean = false;
@@ -92,11 +97,6 @@ export class MdSlideToggle implements OnDestroy, AfterContentInit, ControlValueA
/** Used to set the aria-labelledby attribute on the underlying input element. */
@Input('aria-labelledby') ariaLabelledby: string = null;
/** Whether the slide-toggle is disabled. */
@Input()
get disabled(): boolean { return this._disabled; }
set disabled(value) { this._disabled = coerceBooleanProperty(value); }
/** Whether the slide-toggle is required. */
@Input()
get required(): boolean { return this._required; }
@@ -121,7 +121,9 @@ export class MdSlideToggle implements OnDestroy, AfterContentInit, ControlValueA
constructor(private _elementRef: ElementRef,
private _renderer: Renderer,
private _focusOriginMonitor: FocusOriginMonitor) {}
private _focusOriginMonitor: FocusOriginMonitor) {
super();
}
ngAfterContentInit() {
this._slideRenderer = new SlideToggleRenderer(this._elementRef);
+12 -8
View File
@@ -24,6 +24,8 @@ import {
UP_ARROW
} from '../core/keyboard/keycodes';
import {FocusOrigin, FocusOriginMonitor} from '../core/style/focus-origin-monitor';
import {mixinDisabled, CanDisable} from '../core/common-behaviors/disabled';
/**
* Visually, a 30px separation between tick marks looks best. This is very subjective but it is
@@ -59,6 +61,11 @@ export class MdSliderChange {
value: number;
}
// Boilerplate for applying mixins to MdSlider.
export class MdSliderBase { }
export const _MdSliderMixinBase = mixinDisabled(MdSliderBase);
/**
* Allows users to select from a range of values by moving the slider thumb. It is similar in
* behavior to the native `<input type="range">` element.
@@ -68,7 +75,6 @@ export class MdSliderChange {
selector: 'md-slider, mat-slider',
providers: [MD_SLIDER_VALUE_ACCESSOR],
host: {
'[class.mat-slider]': 'true',
'(focus)': '_onFocus()',
'(blur)': '_onBlur()',
'(click)': '_onClick($event)',
@@ -78,6 +84,7 @@ export class MdSliderChange {
'(slide)': '_onSlide($event)',
'(slideend)': '_onSlideEnd()',
'(slidestart)': '_onSlideStart($event)',
'class': 'mat-slider',
'role': 'slider',
'tabindex': '0',
'[attr.aria-disabled]': 'disabled',
@@ -99,15 +106,11 @@ export class MdSliderChange {
},
templateUrl: 'slider.html',
styleUrls: ['slider.css'],
inputs: ['disabled'],
encapsulation: ViewEncapsulation.None,
})
export class MdSlider implements ControlValueAccessor, OnDestroy {
/** Whether or not the slider is disabled. */
@Input()
get disabled(): boolean { return this._disabled; }
set disabled(value) { this._disabled = coerceBooleanProperty(value); }
private _disabled: boolean = false;
export class MdSlider extends _MdSliderMixinBase
implements ControlValueAccessor, OnDestroy, CanDisable {
/** Whether the slider is inverted. */
@Input()
get invert() { return this._invert; }
@@ -379,6 +382,7 @@ export class MdSlider implements ControlValueAccessor, OnDestroy {
constructor(renderer: Renderer, private _elementRef: ElementRef,
private _focusOriginMonitor: FocusOriginMonitor, @Optional() private _dir: Dir) {
super();
this._focusOriginMonitor.monitor(this._elementRef.nativeElement, renderer, true)
.subscribe((origin: FocusOrigin) => this._isActive = !!origin && origin !== 'keyboard');
this._renderer = new SliderRenderer(this._elementRef);