@angular-mdc/web
Version:
875 lines (870 loc) • 29.3 kB
JavaScript
/**
* @license
* Copyright (c) Dominic Carretto
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://github.com/trimox/angular-mdc-web/blob/master/LICENSE
*/
import { InjectionToken, EventEmitter, Component, ViewEncapsulation, ChangeDetectionStrategy, ChangeDetectorRef, ElementRef, Optional, Inject, Input, Output, ViewChild, forwardRef, ContentChildren, NgModule } from '@angular/core';
import { MdcFormFieldControl, MdcFormField, MdcFormFieldModule } from '@angular-mdc/web/form-field';
import { __extends, __assign } from 'tslib';
import { coerceBooleanProperty } from '@angular/cdk/coercion';
import { UniqueSelectionDispatcher } from '@angular/cdk/collections';
import { supportsPassiveEventListeners } from '@angular/cdk/platform';
import { MDCRippleFoundation } from '@material/ripple';
import { MDCRadioFoundation } from '@material/radio';
import { MdcRipple } from '@angular-mdc/web/ripple';
import { MDCComponent } from '@angular-mdc/web/base';
import { NG_VALUE_ACCESSOR } from '@angular/forms';
/**
* @fileoverview added by tsickle
* Generated from: radio/radio.ts
* @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
/**
* Injection token used to provide the parent MdcRadioGroup component to MdcRadio.
* @type {?}
*/
var MDC_RADIO_GROUP_PARENT_COMPONENT = new InjectionToken('MDC_RADIO_GROUP_PARENT_COMPONENT');
/**
* Change event object emitted by MdcRadio.
*/
var /**
* Change event object emitted by MdcRadio.
*/
MdcRadioChange = /** @class */ (function () {
function MdcRadioChange(source, value) {
this.source = source;
this.value = value;
}
return MdcRadioChange;
}());
/** @type {?} */
var nextUniqueId = 0;
var MdcRadio = /** @class */ (function (_super) {
__extends(MdcRadio, _super);
function MdcRadio(_changeDetectorRef, elementRef, ripple, _radioDispatcher, radioGroup, _parentFormField) {
var _this = _super.call(this, elementRef) || this;
_this._changeDetectorRef = _changeDetectorRef;
_this.elementRef = elementRef;
_this.ripple = ripple;
_this._radioDispatcher = _radioDispatcher;
_this.radioGroup = radioGroup;
_this._parentFormField = _parentFormField;
_this._uniqueId = "mdc-radio-" + ++nextUniqueId;
_this._initialized = false;
/**
* The unique ID for the radio button.
*/
_this.id = _this._uniqueId;
_this.tabIndex = 0;
_this._touch = false;
_this._checked = false;
_this._disabled = false;
_this._required = false;
_this.change = new EventEmitter();
/**
* Unregister function for _radioDispatcher
*/
_this._removeUniqueSelectionListener = (/**
* @return {?}
*/
function () { });
if (_this._parentFormField) {
_parentFormField.elementRef.nativeElement.classList.add('mdc-form-field');
}
_this._root = elementRef.nativeElement;
_this.ripple = _this._createRipple();
_this._removeUniqueSelectionListener =
_radioDispatcher.listen((/**
* @param {?} id
* @param {?} name
* @return {?}
*/
function (id, name) {
if (id !== _this.id && name === _this.name) {
// Get the checked state from native radio button. The native radio buttons with the same
// name have separate unique selection in different form containers.
_this.checked = _this.input.nativeElement.checked;
}
}));
return _this;
}
Object.defineProperty(MdcRadio.prototype, "inputId", {
get: /**
* @return {?}
*/
function () {
return (this.id || this._uniqueId) + "-input";
},
enumerable: true,
configurable: true
});
Object.defineProperty(MdcRadio.prototype, "touch", {
get: /**
* @return {?}
*/
function () {
return this._touch;
},
set: /**
* @param {?} value
* @return {?}
*/
function (value) {
this._touch = coerceBooleanProperty(value);
},
enumerable: true,
configurable: true
});
Object.defineProperty(MdcRadio.prototype, "value", {
get: /**
* @return {?}
*/
function () {
return this._value;
},
set: /**
* @param {?} newValue
* @return {?}
*/
function (newValue) {
this.setValue(newValue);
},
enumerable: true,
configurable: true
});
Object.defineProperty(MdcRadio.prototype, "checked", {
get: /**
* @return {?}
*/
function () {
return this._checked;
},
set: /**
* @param {?} value
* @return {?}
*/
function (value) {
this.setChecked(value);
},
enumerable: true,
configurable: true
});
Object.defineProperty(MdcRadio.prototype, "disabled", {
get: /**
* @return {?}
*/
function () {
return this._disabled || (this.radioGroup !== null && this.radioGroup.disabled);
},
set: /**
* @param {?} value
* @return {?}
*/
function (value) {
/** @type {?} */
var newDisabledState = coerceBooleanProperty(value);
if (this._disabled !== newDisabledState) {
this._disabled = newDisabledState;
this._foundation.setDisabled(this._disabled);
this._changeDetectorRef.markForCheck();
}
},
enumerable: true,
configurable: true
});
Object.defineProperty(MdcRadio.prototype, "required", {
get: /**
* @return {?}
*/
function () {
return this._required || (this.radioGroup && this.radioGroup.required);
},
set: /**
* @param {?} value
* @return {?}
*/
function (value) {
this._required = coerceBooleanProperty(value);
},
enumerable: true,
configurable: true
});
/**
* @return {?}
*/
MdcRadio.prototype.getDefaultFoundation = /**
* @return {?}
*/
function () {
var _this = this;
/** @type {?} */
var adapter = {
addClass: (/**
* @param {?} className
* @return {?}
*/
function (className) { return _this._root.classList.add(className); }),
removeClass: (/**
* @param {?} className
* @return {?}
*/
function (className) { return _this._root.classList.remove(className); }),
setNativeControlDisabled: (/**
* @param {?} disabled
* @return {?}
*/
function (disabled) { return _this.disabled = disabled; })
};
return new MDCRadioFoundation(adapter);
};
/**
* @return {?}
*/
MdcRadio.prototype.ngAfterViewInit = /**
* @return {?}
*/
function () {
var _this = this;
this._initialized = true;
this._foundation.init();
if (this.radioGroup) {
Promise.resolve().then((/**
* @return {?}
*/
function () {
// If the radio is inside a radio group, determine if it should be checked
_this.checked = _this.radioGroup.value === _this._value;
// Copy name from parent radio group
_this.name = _this.radioGroup.name;
_this.setChecked(_this.checked);
_this._changeDetectorRef.markForCheck();
}));
}
};
/**
* @return {?}
*/
MdcRadio.prototype.ngOnDestroy = /**
* @return {?}
*/
function () {
this._removeUniqueSelectionListener();
this.ripple.destroy();
this._foundation.destroy();
};
/**
* @param {?} event
* @return {?}
*/
MdcRadio.prototype.onInputClick = /**
* @param {?} event
* @return {?}
*/
function (event) {
// Preventing bubbling for the second event will solve that issue.
event.stopPropagation();
};
/**
* @param {?} event
* @return {?}
*/
MdcRadio.prototype.onInputChange = /**
* @param {?} event
* @return {?}
*/
function (event) {
this.ripple.init();
event.stopPropagation();
/** @type {?} */
var groupValueChanged = this.radioGroup && this.value !== this.radioGroup.value;
this.checked = true;
this._emitChangeEvent();
if (this.radioGroup) {
this.radioGroup._controlValueAccessorChangeFn(this.value);
if (groupValueChanged) {
this.radioGroup.emitChangeEvent();
}
}
};
/**
* @param {?} checked
* @return {?}
*/
MdcRadio.prototype.setChecked = /**
* @param {?} checked
* @return {?}
*/
function (checked) {
if (!this._initialized) {
return;
}
/** @type {?} */
var newCheckedState = coerceBooleanProperty(checked);
if (this._checked !== newCheckedState) {
this._checked = newCheckedState;
this.input.nativeElement.checked = newCheckedState;
if (newCheckedState && this.radioGroup && this.radioGroup.value !== this.value) {
this.radioGroup.selected = this;
}
else if (!newCheckedState && this.radioGroup && this.radioGroup.value === this.value) {
// When unchecking the selected radio button, update the selected radio
// property on the group.
this.radioGroup.selected = null;
}
this._changeDetectorRef.markForCheck();
if (newCheckedState) {
// Notify all radio buttons with the same name to un-check.
this._radioDispatcher.notify(this.id, this.name);
}
}
};
/**
* @param {?} value
* @return {?}
*/
MdcRadio.prototype.setValue = /**
* @param {?} value
* @return {?}
*/
function (value) {
this._value = value;
this.input.nativeElement.value = this._value;
if (this.radioGroup !== null) {
if (!this.checked) {
// Update checked when the value changed to match the radio group's value
this.checked = this.radioGroup.value === value;
}
if (this.checked) {
this.radioGroup.selected = this;
}
}
};
/**
* @return {?}
*/
MdcRadio.prototype.focus = /**
* @return {?}
*/
function () {
this.input.nativeElement.focus();
};
/**
* @return {?}
*/
MdcRadio.prototype.markForCheck = /**
* @return {?}
*/
function () {
this._changeDetectorRef.markForCheck();
};
/**
* @private
* @return {?}
*/
MdcRadio.prototype._createRipple = /**
* @private
* @return {?}
*/
function () {
var _this = this;
/** @type {?} */
var adapter = __assign(__assign({}, MdcRipple.createAdapter(this)), { isSurfaceActive: (/**
* @return {?}
*/
function () { return false; }), isUnbounded: (/**
* @return {?}
*/
function () { return true; }), deregisterInteractionHandler: (/**
* @param {?} evtType
* @param {?} handler
* @return {?}
*/
function (evtType, handler) {
return _this.input.nativeElement.removeEventListener(evtType, handler, supportsPassiveEventListeners());
}), registerInteractionHandler: (/**
* @param {?} evtType
* @param {?} handler
* @return {?}
*/
function (evtType, handler) {
return _this.input.nativeElement.addEventListener(evtType, handler, supportsPassiveEventListeners());
}) });
return new MdcRipple(this.elementRef, new MDCRippleFoundation(adapter));
};
/** Dispatch change event with current value. */
/**
* Dispatch change event with current value.
* @private
* @return {?}
*/
MdcRadio.prototype._emitChangeEvent = /**
* Dispatch change event with current value.
* @private
* @return {?}
*/
function () {
this.change.emit(new MdcRadioChange(this, this._value));
};
MdcRadio.decorators = [
{ type: Component, args: [{selector: 'mdc-radio',
exportAs: 'mdcRadio',
host: {
'[id]': 'id',
'class': 'mdc-radio',
'(focus)': 'input.nativeElement.focus()',
'[attr.tabindex]': '-1',
'[attr.name]': 'null',
'[class.mdc-radio--touch]': 'touch',
},
template: "\n <input type=\"radio\"\n #input\n class=\"mdc-radio__native-control\"\n [id]=\"inputId\"\n [attr.name]=\"name\"\n [tabIndex]=\"tabIndex\"\n [attr.aria-label]=\"ariaLabel\"\n [attr.aria-labelledby]=\"ariaLabelledby\"\n [attr.aria-describedby]=\"ariaDescribedby\"\n [disabled]=\"disabled\"\n [required]=\"required\"\n [checked]=\"checked\"\n (click)=\"onInputClick($event)\"\n (change)=\"onInputChange($event)\" />\n <div class=\"mdc-radio__background\">\n <div class=\"mdc-radio__outer-circle\"></div>\n <div class=\"mdc-radio__inner-circle\"></div>\n </div>\n <div class=\"mdc-radio__ripple\"></div>\n ",
encapsulation: ViewEncapsulation.None,
changeDetection: ChangeDetectionStrategy.OnPush,
providers: [
MdcRipple,
{ provide: MdcFormFieldControl, useExisting: MdcRadio }
]
},] },
];
/** @nocollapse */
MdcRadio.ctorParameters = function () { return [
{ type: ChangeDetectorRef },
{ type: ElementRef },
{ type: MdcRipple },
{ type: UniqueSelectionDispatcher },
{ type: undefined, decorators: [{ type: Optional }, { type: Inject, args: [MDC_RADIO_GROUP_PARENT_COMPONENT,] }] },
{ type: MdcFormField, decorators: [{ type: Optional }] }
]; };
MdcRadio.propDecorators = {
id: [{ type: Input }],
name: [{ type: Input }],
tabIndex: [{ type: Input }],
ariaLabel: [{ type: Input, args: ['aria-label',] }],
ariaLabelledby: [{ type: Input, args: ['aria-labelledby',] }],
ariaDescribedby: [{ type: Input, args: ['aria-describedby',] }],
touch: [{ type: Input }],
value: [{ type: Input }],
checked: [{ type: Input }],
disabled: [{ type: Input }],
required: [{ type: Input }],
change: [{ type: Output }],
input: [{ type: ViewChild, args: ['input', { static: true },] }]
};
return MdcRadio;
}(MDCComponent));
/**
* @fileoverview added by tsickle
* Generated from: radio/radio-group.ts
* @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
/**
* Provider Expression that allows mdc-radio-group to register as a ControlValueAccessor. This
* allows it to support [(ngModel)] and ngControl.
* @type {?}
*/
var MDC_RADIO_GROUP_CONTROL_VALUE_ACCESSOR = {
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef((/**
* @return {?}
*/
function () { return MdcRadioGroup; })),
multi: true
};
/** @type {?} */
var nextUniqueId$1 = 0;
var MdcRadioGroup = /** @class */ (function () {
function MdcRadioGroup(_changeDetectorRef, elementRef) {
this._changeDetectorRef = _changeDetectorRef;
this.elementRef = elementRef;
this._name = "mdc-radio-group-" + nextUniqueId$1++;
/**
* Selected value for the radio group.
*/
this._value = null;
/**
* Whether the `value` has been set to its initial value.
*/
this._isInitialized = false;
this._selected = null;
this._required = false;
this._disabled = false;
/**
* The method to be called in order to update ngModel
*/
this._controlValueAccessorChangeFn = (/**
* @return {?}
*/
function () { });
/**
* onTouch function registered via registerOnTouch (ControlValueAccessor).
*/
this.onTouched = (/**
* @return {?}
*/
function () { });
this.change = new EventEmitter();
}
Object.defineProperty(MdcRadioGroup.prototype, "name", {
/** Name of the radio button group. All radio buttons inside this group will use this name. */
get: /**
* Name of the radio button group. All radio buttons inside this group will use this name.
* @return {?}
*/
function () { return this._name; },
set: /**
* @param {?} value
* @return {?}
*/
function (value) {
this._name = value;
this._updateRadioButtonNames();
},
enumerable: true,
configurable: true
});
Object.defineProperty(MdcRadioGroup.prototype, "value", {
/**
* Value for the radio-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
* radio button, this value persists to be applied in case a new radio button is added with a
* matching value.
*/
get: /**
* Value for the radio-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
* radio button, this value persists to be applied in case a new radio button is added with a
* matching value.
* @return {?}
*/
function () { return this._value; },
set: /**
* @param {?} newValue
* @return {?}
*/
function (newValue) {
if (this._value !== newValue) {
// Set this before proceeding to ensure no circular loop occurs with selection.
this._value = newValue;
this._updateSelectedRadioFromValue();
this._checkSelectedRadioButton();
}
},
enumerable: true,
configurable: true
});
Object.defineProperty(MdcRadioGroup.prototype, "selected", {
/**
* The currently selected radio button. If set to a new radio button, the radio group value
* will be updated to match the new selected button.
*/
get: /**
* The currently selected radio button. If set to a new radio button, the radio group value
* will be updated to match the new selected button.
* @return {?}
*/
function () { return this._selected; },
set: /**
* @param {?} selected
* @return {?}
*/
function (selected) {
this._selected = selected;
this.value = selected ? selected.value : null;
this._checkSelectedRadioButton();
},
enumerable: true,
configurable: true
});
Object.defineProperty(MdcRadioGroup.prototype, "required", {
get: /**
* @return {?}
*/
function () { return this._required; },
set: /**
* @param {?} value
* @return {?}
*/
function (value) {
this._required = coerceBooleanProperty(value);
this._markRadiosForCheck();
},
enumerable: true,
configurable: true
});
Object.defineProperty(MdcRadioGroup.prototype, "disabled", {
get: /**
* @return {?}
*/
function () { return this._disabled; },
set: /**
* @param {?} value
* @return {?}
*/
function (value) {
this._disabled = coerceBooleanProperty(value);
this._updateDisableRadioState(this._disabled);
this._markRadiosForCheck();
},
enumerable: true,
configurable: true
});
/**
* @return {?}
*/
MdcRadioGroup.prototype._checkSelectedRadioButton = /**
* @return {?}
*/
function () {
if (this._selected && !this._selected.checked) {
this._selected.checked = true;
}
};
/**
* @return {?}
*/
MdcRadioGroup.prototype.ngAfterContentInit = /**
* @return {?}
*/
function () {
this._isInitialized = true;
};
/**
* @return {?}
*/
MdcRadioGroup.prototype._touch = /**
* @return {?}
*/
function () {
if (this.onTouched) {
this.onTouched();
}
};
/**
* @private
* @return {?}
*/
MdcRadioGroup.prototype._updateRadioButtonNames = /**
* @private
* @return {?}
*/
function () {
var _this = this;
if (this._radios) {
this._radios.forEach((/**
* @param {?} radio
* @return {?}
*/
function (radio) {
radio.name = _this.name;
radio.markForCheck();
}));
}
};
/** Updates the `selected` radio button from the internal _value state. */
/**
* Updates the `selected` radio button from the internal _value state.
* @private
* @return {?}
*/
MdcRadioGroup.prototype._updateSelectedRadioFromValue = /**
* Updates the `selected` radio button from the internal _value state.
* @private
* @return {?}
*/
function () {
var _this = this;
// If the value already matches the selected radio, do nothing.
/** @type {?} */
var isAlreadySelected = this._selected !== null && this._selected.value === this._value;
if (this._radios && !isAlreadySelected) {
this._selected = null;
this._radios.forEach((/**
* @param {?} radio
* @return {?}
*/
function (radio) {
radio.checked = _this.value === radio.value;
if (radio.checked) {
_this._selected = radio;
}
}));
}
};
/**
* @private
* @return {?}
*/
MdcRadioGroup.prototype._markRadiosForCheck = /**
* @private
* @return {?}
*/
function () {
if (this._radios) {
this._radios.forEach((/**
* @param {?} radio
* @return {?}
*/
function (radio) { return radio.markForCheck(); }));
}
};
/**
* @private
* @param {?} disabled
* @return {?}
*/
MdcRadioGroup.prototype._updateDisableRadioState = /**
* @private
* @param {?} disabled
* @return {?}
*/
function (disabled) {
if (this._radios) {
this._radios.forEach((/**
* @param {?} radio
* @return {?}
*/
function (radio) { return radio.disabled = disabled; }));
}
};
/** Sets the model value. Implemented as part of ControlValueAccessor. */
/**
* Sets the model value. Implemented as part of ControlValueAccessor.
* @param {?} value
* @return {?}
*/
MdcRadioGroup.prototype.writeValue = /**
* Sets the model value. Implemented as part of ControlValueAccessor.
* @param {?} value
* @return {?}
*/
function (value) {
this.value = value;
this._changeDetectorRef.markForCheck();
};
/**
* Registers a callback to be triggered when the model value changes.
* Implemented as part of ControlValueAccessor.
* @param fn Callback to be registered.
*/
/**
* Registers a callback to be triggered when the model value changes.
* Implemented as part of ControlValueAccessor.
* @param {?} fn Callback to be registered.
* @return {?}
*/
MdcRadioGroup.prototype.registerOnChange = /**
* Registers a callback to be triggered when the model value changes.
* Implemented as part of ControlValueAccessor.
* @param {?} fn Callback to be registered.
* @return {?}
*/
function (fn) {
this._controlValueAccessorChangeFn = fn;
};
/**
* Registers a callback to be triggered when the control is touched.
* Implemented as part of ControlValueAccessor.
* @param fn Callback to be registered.
*/
/**
* Registers a callback to be triggered when the control is touched.
* Implemented as part of ControlValueAccessor.
* @param {?} fn Callback to be registered.
* @return {?}
*/
MdcRadioGroup.prototype.registerOnTouched = /**
* Registers a callback to be triggered when the control is touched.
* Implemented as part of ControlValueAccessor.
* @param {?} fn Callback to be registered.
* @return {?}
*/
function (fn) {
this.onTouched = fn;
};
/**
* Sets the disabled state of the control. Implemented as a part of ControlValueAccessor.
* @param isDisabled Whether the control should be disabled.
*/
/**
* Sets the disabled state of the control. Implemented as a part of ControlValueAccessor.
* @param {?} isDisabled Whether the control should be disabled.
* @return {?}
*/
MdcRadioGroup.prototype.setDisabledState = /**
* Sets the disabled state of the control. Implemented as a part of ControlValueAccessor.
* @param {?} isDisabled Whether the control should be disabled.
* @return {?}
*/
function (isDisabled) {
this.disabled = coerceBooleanProperty(isDisabled);
this._changeDetectorRef.markForCheck();
};
/** Dispatch change event with current selection and group value. */
/**
* Dispatch change event with current selection and group value.
* @return {?}
*/
MdcRadioGroup.prototype.emitChangeEvent = /**
* Dispatch change event with current selection and group value.
* @return {?}
*/
function () {
if (this._isInitialized) {
this.change.emit(new MdcRadioChange((/** @type {?} */ (this._selected)), this._value));
}
};
MdcRadioGroup.decorators = [
{ type: Component, args: [{
selector: 'mdc-radio-group, [mdcRadioGroup]',
exportAs: 'mdcRadioGroup',
host: {
'role': 'radiogroup',
'[attr.name]': 'null'
},
template: '<ng-content></ng-content>',
changeDetection: ChangeDetectionStrategy.OnPush,
encapsulation: ViewEncapsulation.None,
providers: [MDC_RADIO_GROUP_CONTROL_VALUE_ACCESSOR,
{ provide: MDC_RADIO_GROUP_PARENT_COMPONENT, useExisting: MdcRadioGroup }
]
},] },
];
/** @nocollapse */
MdcRadioGroup.ctorParameters = function () { return [
{ type: ChangeDetectorRef },
{ type: ElementRef }
]; };
MdcRadioGroup.propDecorators = {
_radios: [{ type: ContentChildren, args: [forwardRef((/**
* @return {?}
*/
function () { return MdcRadio; })), { descendants: true },] }],
name: [{ type: Input }],
value: [{ type: Input }],
selected: [{ type: Input }],
required: [{ type: Input }],
disabled: [{ type: Input }],
change: [{ type: Output }]
};
return MdcRadioGroup;
}());
/**
* @fileoverview added by tsickle
* Generated from: radio/module.ts
* @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
var MdcRadioModule = /** @class */ (function () {
function MdcRadioModule() {
}
MdcRadioModule.decorators = [
{ type: NgModule, args: [{
imports: [MdcFormFieldModule],
exports: [MdcRadioGroup, MdcRadio],
declarations: [MdcRadioGroup, MdcRadio]
},] },
];
return MdcRadioModule;
}());
export { MDC_RADIO_GROUP_CONTROL_VALUE_ACCESSOR, MDC_RADIO_GROUP_PARENT_COMPONENT, MdcRadio, MdcRadioChange, MdcRadioGroup, MdcRadioModule };
//# sourceMappingURL=radio.es5.js.map