UNPKG

@angular-mdc/web

Version:
875 lines (870 loc) 29.3 kB
/** * @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