@blox/material
Version:
Material Components for Angular
671 lines • 91.3 kB
JavaScript
import { Directive, ElementRef, forwardRef, HostBinding, Input, Renderer2, Self, ContentChildren, Host, SkipSelf, HostListener, Inject, Output, EventEmitter } from '@angular/core';
import { DOCUMENT } from '@angular/common';
import { MDCLineRippleFoundation } from '@material/line-ripple';
import { MDCSelectFoundation, cssClasses, strings } from '@material/select';
import { Subject, merge } from 'rxjs';
import { takeUntil, debounceTime } from 'rxjs/operators';
import { MdcFloatingLabelDirective } from '../floating-label/mdc.floating-label.directive';
import { AbstractMdcRipple } from '../ripple/abstract.mdc.ripple';
import { MdcEventRegistry } from '../../utils/mdc.event.registry';
import { MdcNotchedOutlineDirective } from '../notched-outline/mdc.notched-outline.directive';
import { MdcMenuDirective } from '../menu/mdc.menu.directive';
import { MdcMenuSurfaceDirective } from '../menu-surface/mdc.menu-surface.directive';
import { MdcListFunction, MdcListDirective } from '../list/mdc.list.directive';
import { HasId } from '../abstract/mixin.mdc.hasid';
import { applyMixins } from '../../utils/mixins';
import { NG_VALUE_ACCESSOR } from '@angular/forms';
import { asBoolean } from '../../utils/value.utils';
class MdcSelectTextDirectiveBase {
}
MdcSelectTextDirectiveBase.decorators = [
{ type: Directive }
];
applyMixins(MdcSelectTextDirectiveBase, [HasId]);
/**
* Directive for showing the text of the currently selected `mdcSelect` item. It is the responsibility
* of the host component to set the actual text (see examples). This makes the `mdcSelect` more flexible,
* so that e.g. the text of options can also contain markup to style parts of it differently.
* When no value is selected, the embedded text must be empty.
*
* # Accessibility
* * When no `id` is assigned, the component will generate a unique `id`, so that the `mdcSelectAnchor`
* and `mdcList` for this select can be labelled (with `aria-labelledBy`) appropriately.
* * The element will be made focusable and tabbable (with `tabindex=0`), unless disabled.
* * The `aria-disabled` will get a value based on the `disabled` property of the `mdcSelect`.
* * The `aria-required` will get a value based on the `required` property of the `mdcSelect`.
* * The `role` attribute will be set to `button`.
* * The `aria-haspopup` attribute will be set to `listbox`.
* * The `aria-labelledBy` attribute will list the ids of the `mdcFloatinglabel` and the `mdcSelectText` self.
* * The `aria-expanded` attribute will reflect whether this element is focused (the menu-surface is open).
*/
export class MdcSelectTextDirective extends MdcSelectTextDirectiveBase {
constructor(_elm, select) {
super();
this._elm = _elm;
this.select = select;
/** @internal */
this._cls = true;
/** @internal */
this._role = 'button';
/** @internal */
this._haspop = 'listbox';
/** @internal */
this._labelledBy = null;
}
ngOnInit() {
this.initId();
}
/** @internal */
_onFocus() {
var _a;
(_a = this.select.foundation) === null || _a === void 0 ? void 0 : _a.handleFocus();
}
/** @internal */
_onBlur() {
this.select.onBlur();
}
/** @internal */
_onKeydown(event) {
var _a;
(_a = this.select.foundation) === null || _a === void 0 ? void 0 : _a.handleKeydown(event);
}
/** @internal */
_onClick(event) {
var _a;
(_a = this.select.foundation) === null || _a === void 0 ? void 0 : _a.handleClick(this.getNormalizedXCoordinate(event));
}
getNormalizedXCoordinate(event) {
const targetClientRect = event.target.getBoundingClientRect();
const xCoordinate = !!(event.touches) ? event.touches[0].clientX : event.clientX;
return xCoordinate - targetClientRect.left;
}
}
MdcSelectTextDirective.decorators = [
{ type: Directive, args: [{
selector: '[mdcSelectText]'
},] }
];
MdcSelectTextDirective.ctorParameters = () => [
{ type: ElementRef },
{ type: MdcSelectDirective, decorators: [{ type: Host }, { type: SkipSelf }, { type: Inject, args: [forwardRef(() => MdcSelectDirective),] }] }
];
MdcSelectTextDirective.propDecorators = {
_cls: [{ type: HostBinding, args: ['class.mdc-select__selected-text',] }],
_role: [{ type: HostBinding, args: ['attr.role',] }],
_haspop: [{ type: HostBinding, args: ['attr.aria-haspopup',] }],
_labelledBy: [{ type: HostBinding, args: ['attr.aria-labelledby',] }],
_onFocus: [{ type: HostListener, args: ['focus',] }],
_onBlur: [{ type: HostListener, args: ['blur',] }],
_onKeydown: [{ type: HostListener, args: ['keydown', ['$event'],] }],
_onClick: [{ type: HostListener, args: ['click', ['$event'],] }]
};
/**
* The `mdcSelectAnchor` should be the first child of an `mdcSelect`. It contains the dropdown-icon,
* `mdcSelectText`, `mdcFloatingLabel`, ripples, and may contain an optional `mdcNotchedOutline`.
* See the examples for the required structure of these directives.
*/
export class MdcSelectAnchorDirective extends AbstractMdcRipple {
constructor(_elm, rndr, registry, select, doc) {
super(_elm, rndr, registry, doc);
this._elm = _elm;
this.rndr = rndr;
this.select = select;
this.onDestroy$ = new Subject();
this.onLabelsChange$ = new Subject();
/** @internal */
this._cls = true;
this._bottomLineElm = null;
/** @internal */
this.bottomLineFoundation = null;
this.mdcLineRippleAdapter = {
addClass: (className) => this.rndr.addClass(this._bottomLineElm, className),
removeClass: (className) => this.rndr.removeClass(this._bottomLineElm, className),
hasClass: (className) => this._bottomLineElm.classList.contains(className),
setStyle: (name, value) => this.rndr.setStyle(this._bottomLineElm, name, value),
registerEventHandler: (evtType, handler) => this._registry.listenElm(this.rndr, evtType, handler, this._bottomLineElm),
deregisterEventHandler: (evtType, handler) => this._registry.unlisten(evtType, handler)
};
}
ngAfterContentInit() {
merge(this._floatingLabels.changes, this._outlines.changes).pipe(takeUntil(this.onDestroy$), debounceTime(1)).subscribe(() => {
this.reconstructComponent();
});
merge(this._floatingLabels.changes, this._texts.changes).pipe(takeUntil(this.onDestroy$)).subscribe(() => {
var _a, _b;
this.onLabelsChange$.next();
(_a = this._label) === null || _a === void 0 ? void 0 : _a.idChange().pipe(takeUntil(this.onLabelsChange$)).subscribe(() => {
this.computeLabelledBy();
});
(_b = this._text) === null || _b === void 0 ? void 0 : _b.idChange().pipe(takeUntil(this.onLabelsChange$)).subscribe(() => {
this.computeLabelledBy();
});
this.computeLabelledBy();
});
this.addIcon();
this.initComponent();
this.computeLabelledBy();
}
ngOnDestroy() {
this.onLabelsChange$.next();
this.onLabelsChange$.complete();
this.onDestroy$.next();
this.onDestroy$.complete();
this.destroyRipple();
this.destroyLineRipple();
}
initComponent() {
if (!this._outline) {
this.initLineRipple();
this.initRipple();
}
}
destroyComponent() {
this.destroyRipple();
this.destroyLineRipple();
}
reconstructComponent() {
this.destroyComponent();
this.initComponent();
}
addIcon() {
const icon = this.rndr.createElement('i');
this.rndr.addClass(icon, 'mdc-select__dropdown-icon');
if (this._elm.nativeElement.children.length > 0)
this.rndr.insertBefore(this._elm.nativeElement, icon, this._elm.nativeElement.children.item(0));
else
this.rndr.appendChild(this._elm.nativeElement, icon);
}
initLineRipple() {
if (!this._bottomLineElm) {
this._bottomLineElm = this.rndr.createElement('div');
this.rndr.addClass(this._bottomLineElm, 'mdc-line-ripple');
this.rndr.appendChild(this._elm.nativeElement, this._bottomLineElm);
this.bottomLineFoundation = new MDCLineRippleFoundation(this.mdcLineRippleAdapter);
this.bottomLineFoundation.init();
}
}
destroyLineRipple() {
if (this._bottomLineElm) {
this.bottomLineFoundation.destroy();
this.bottomLineFoundation = null;
this.rndr.removeChild(this._elm.nativeElement, this._bottomLineElm);
this._bottomLineElm = null;
}
}
computeLabelledBy() {
var _a, _b;
let ids = [];
const labelId = (_a = this._label) === null || _a === void 0 ? void 0 : _a.id;
if (labelId)
ids.push(labelId);
const textId = (_b = this._text) === null || _b === void 0 ? void 0 : _b.id;
if (textId)
ids.push(textId);
if (this._text)
this._text._labelledBy = ids.join(' ');
this.select.setListLabelledBy(labelId || null); // the list should only use the id of the label
}
/** @internal */
get _outline() {
var _a;
return (_a = this._outlines) === null || _a === void 0 ? void 0 : _a.first;
}
/** @internal */
get _label() {
var _a;
return (_a = this._floatingLabels) === null || _a === void 0 ? void 0 : _a.first;
}
/** @internal */
get _text() {
var _a;
return (_a = this._texts) === null || _a === void 0 ? void 0 : _a.first;
}
}
MdcSelectAnchorDirective.decorators = [
{ type: Directive, args: [{
selector: '[mdcSelectAnchor]'
},] }
];
MdcSelectAnchorDirective.ctorParameters = () => [
{ type: ElementRef },
{ type: Renderer2 },
{ type: MdcEventRegistry },
{ type: MdcSelectDirective, decorators: [{ type: Host }, { type: SkipSelf }, { type: Inject, args: [forwardRef(() => MdcSelectDirective),] }] },
{ type: undefined, decorators: [{ type: Inject, args: [DOCUMENT,] }] }
];
MdcSelectAnchorDirective.propDecorators = {
_cls: [{ type: HostBinding, args: ['class.mdc-select__anchor',] }],
_floatingLabels: [{ type: ContentChildren, args: [MdcFloatingLabelDirective, { descendants: true },] }],
_outlines: [{ type: ContentChildren, args: [MdcNotchedOutlineDirective,] }],
_texts: [{ type: ContentChildren, args: [MdcSelectTextDirective,] }]
};
/**
* Directive for the options list of an `mdcSelect`. This directive should be the second (last) child
* of an `mdcSelect`, and should wrap an `mdcList` with all selection options.
* See the examples for the required structure of these directives.
*
* An `mdcSelectMenu` element will also match with the selector of the menu surface directive, documented
* <a href="/components/menu-surface#mdcMenuSurface">here: mdcMenuSurface API</a>.
*/
export class MdcSelectMenuDirective {
constructor(_menu, _surface) {
this._menu = _menu;
this._surface = _surface;
/** @internal */
this._cls = true;
}
}
MdcSelectMenuDirective.decorators = [
{ type: Directive, args: [{
selector: '[mdcSelectMenu]'
},] }
];
MdcSelectMenuDirective.ctorParameters = () => [
{ type: MdcMenuDirective, decorators: [{ type: Self }] },
{ type: MdcMenuSurfaceDirective, decorators: [{ type: Self }] }
];
MdcSelectMenuDirective.propDecorators = {
_cls: [{ type: HostBinding, args: ['class.mdc-select__menu',] }]
};
/** @docs-private */
var ValueSource;
(function (ValueSource) {
ValueSource[ValueSource["control"] = 0] = "control";
ValueSource[ValueSource["foundation"] = 1] = "foundation";
ValueSource[ValueSource["program"] = 2] = "program";
})(ValueSource || (ValueSource = {}));
;
/**
* Directive for a spec aligned material design 'Select Control'. This directive should contain
* and `mdcSelectAnchor` and an `mdcSelectMenu`. See the examples for the required structure of
* these directives.
*
* If leaving the select empty should be a valid option, include an `mdcListItem` as first element in the list,
* with an ampty string as `value`.
*
* # Accessibility
* * This directive implements the aria practices recommendations for a
* [listbox](https://www.w3.org/TR/wai-aria-practices/examples/listbox/listbox-collapsible.html).
* Most `aria-*` and `role` attributes affect the embedded `mdcSelectAnchor`, and `mdcList`, and are
* explained in the documentation for these directives.
*/
export class MdcSelectDirective {
constructor(elm, rndr, doc) {
this.elm = elm;
this.rndr = rndr;
/** @internal */
this._cls = true;
this.onDestroy$ = new Subject();
this.onMenuChange$ = new Subject();
this.onItemsChange$ = new Subject();
this._onChange = () => { };
this._onTouched = () => { };
this._lastMenu = null;
this._value = null;
this._valueSource = null;
this._disabled = false;
this._required = false;
this._listLabelledBy = null;
/**
* emits the value of the item when the selected item changes
*/
this.valueChange = new EventEmitter();
this.mdcAdapter = {
addClass: (className) => this.rndr.addClass(this.elm.nativeElement, className),
removeClass: (className) => this.rndr.removeClass(this.elm.nativeElement, className),
hasClass: (className) => this.elm.nativeElement.classList.contains(className),
activateBottomLine: () => { var _a, _b; return (_b = (_a = this.anchor) === null || _a === void 0 ? void 0 : _a.bottomLineFoundation) === null || _b === void 0 ? void 0 : _b.activate(); },
deactivateBottomLine: () => { var _a, _b; return (_b = (_a = this.anchor) === null || _a === void 0 ? void 0 : _a.bottomLineFoundation) === null || _b === void 0 ? void 0 : _b.deactivate(); },
getSelectedMenuItem: () => { var _a; return (_a = this.getSelectedItem()) === null || _a === void 0 ? void 0 : _a._elm.nativeElement; },
hasLabel: () => !!this.label,
floatLabel: (shouldFloat) => { var _a; return (_a = this.label) === null || _a === void 0 ? void 0 : _a.float(shouldFloat); },
getLabelWidth: () => { var _a; return ((_a = this.label) === null || _a === void 0 ? void 0 : _a.getWidth()) || 0; },
hasOutline: () => { var _a; return !!((_a = this.anchor) === null || _a === void 0 ? void 0 : _a._outline); },
notchOutline: (labelWidth) => { var _a; return (_a = this.anchor) === null || _a === void 0 ? void 0 : _a._outline.open(labelWidth); },
closeOutline: () => { var _a; return (_a = this.anchor) === null || _a === void 0 ? void 0 : _a._outline.close(); },
setRippleCenter: (normalizedX) => { var _a, _b; return (_b = (_a = this.anchor) === null || _a === void 0 ? void 0 : _a.bottomLineFoundation) === null || _b === void 0 ? void 0 : _b.setRippleCenter(normalizedX); },
notifyChange: (value) => this.updateValue(value, ValueSource.foundation),
// setSelectedText does nothing, library consumer should set the text; gives them more freedom to e.g. also use markup:
setSelectedText: () => undefined,
isSelectedTextFocused: () => { var _a; return !!(this.document.activeElement && this.document.activeElement === ((_a = this.text) === null || _a === void 0 ? void 0 : _a._elm.nativeElement)); },
getSelectedTextAttr: (attr) => { var _a; return (_a = this.text) === null || _a === void 0 ? void 0 : _a._elm.nativeElement.getAttribute(attr); },
setSelectedTextAttr: (attr, value) => this.text ? this.rndr.setAttribute(this.text._elm.nativeElement, attr, value) : undefined,
openMenu: () => this.menu.openAndFocus(null),
closeMenu: () => this.menu.doClose(),
getAnchorElement: () => this.anchor._elm.nativeElement,
setMenuAnchorElement: (anchorEl) => this.surface.menuAnchor = anchorEl,
setMenuAnchorCorner: (anchorCorner) => this.surface.setFoundationAnchorCorner(anchorCorner),
setMenuWrapFocus: () => undefined,
setAttributeAtIndex: (index, name, value) => {
var _a, _b, _c;
if (name != strings.ARIA_SELECTED_ATTR) {
const item = (_c = (_b = (_a = this.menu) === null || _a === void 0 ? void 0 : _a._list) === null || _b === void 0 ? void 0 : _b.getItem(index)) === null || _c === void 0 ? void 0 : _c._elm.nativeElement;
if (item)
this.rndr.setAttribute(item, name, value);
}
},
removeAttributeAtIndex: (index, name) => {
var _a, _b, _c;
if (name !== strings.ARIA_SELECTED_ATTR) {
const item = (_c = (_b = (_a = this.menu) === null || _a === void 0 ? void 0 : _a._list) === null || _b === void 0 ? void 0 : _b.getItem(index)) === null || _c === void 0 ? void 0 : _c._elm.nativeElement;
if (item)
this.rndr.removeAttribute(item, name);
}
},
focusMenuItemAtIndex: (index) => {
var _a, _b, _c;
const item = (_c = (_b = (_a = this.menu) === null || _a === void 0 ? void 0 : _a._list) === null || _b === void 0 ? void 0 : _b.getItem(index)) === null || _c === void 0 ? void 0 : _c._elm.nativeElement;
if (item)
item.focus();
},
getMenuItemCount: () => { var _a, _b; return ((_b = (_a = this.menu) === null || _a === void 0 ? void 0 : _a._list) === null || _b === void 0 ? void 0 : _b.getItems().length) || 0; },
getMenuItemValues: () => { var _a, _b; return ((_b = (_a = this.menu) === null || _a === void 0 ? void 0 : _a._list) === null || _b === void 0 ? void 0 : _b.getItems().map(item => item.value || '')) || []; },
// foundation uses this to 'setSelectedText', but that's ignored in our implementation (see remark on setSelectedText):
getMenuItemTextAtIndex: () => '',
getMenuItemAttr: (menuItem, attr) => {
var _a, _b, _c;
if (attr === strings.VALUE_ATTR)
return ((_c = (_b = (_a = this.menu) === null || _a === void 0 ? void 0 : _a._list) === null || _b === void 0 ? void 0 : _b.getItemByElement(menuItem)) === null || _c === void 0 ? void 0 : _c.value) || null;
return menuItem.getAttribute(attr);
},
addClassAtIndex: (index, className) => {
var _a, _b;
const item = (_b = (_a = this.menu) === null || _a === void 0 ? void 0 : _a._list) === null || _b === void 0 ? void 0 : _b.getItem(index);
if (item && className === cssClasses.SELECTED_ITEM_CLASS) {
item.active = true;
}
else if (item)
this.rndr.addClass(item._elm.nativeElement, className);
},
removeClassAtIndex: (index, className) => {
var _a, _b;
const item = (_b = (_a = this.menu) === null || _a === void 0 ? void 0 : _a._list) === null || _b === void 0 ? void 0 : _b.getItem(index);
if (item && className === cssClasses.SELECTED_ITEM_CLASS) {
item.active = false;
}
else if (item)
this.rndr.removeClass(this.menu._list.getItem(index)._elm.nativeElement, className);
}
};
/** @internal */
this.foundation = null;
this.document = doc;
}
ngAfterContentInit() {
this._lastMenu = this._menus.first;
this._menus.changes.subscribe(() => {
var _a;
if (this._lastMenu !== this._menus.first) {
this.onMenuChange$.next();
(_a = this._lastMenu) === null || _a === void 0 ? void 0 : _a._menu.itemValuesChanged.pipe(takeUntil(this.onMenuChange$)).subscribe(() => this.onItemsChange$.next());
this._lastMenu = this._menus.first;
this.setupMenuHandlers();
}
});
this._lists.changes.subscribe(() => this.initListLabel());
merge(this.onMenuChange$,
// the foundation initializes with the values of the items, so if they change, the foundation must be reconstructed:
this.onItemsChange$,
// mdcSelectText change needs a complete re-init as well:
this._texts.changes,
// when an outline is added/removed, a re-init is needed as well:
this._outlines.changes).pipe(takeUntil(this.onDestroy$), debounceTime(1)).subscribe(() => {
this.reconstructComponent();
});
this.initComponent();
this.setupMenuHandlers();
this.initListLabel();
}
ngOnDestroy() {
this.onMenuChange$.next();
this.onMenuChange$.complete();
this.onDestroy$.next();
this.onDestroy$.complete();
this.onItemsChange$.complete();
this.destroyComponent();
}
initComponent() {
this.foundation = new class extends MDCSelectFoundation {
isValid() {
//TODO: required effect on validity in combination with @angular/forms
//TODO: setValid/aria-invalid/helpertext validity
return super.isValid();
}
}(this.mdcAdapter, {
helperText: undefined,
leadingIcon: undefined
});
this.foundation.init();
// foundation needs a call to setDisabled (even when false), because otherwise
// tabindex will not be set correctly:
this.foundation.setDisabled(this._disabled);
this.foundation.setRequired(this._required);
// foundation only updates aria-expanded on open/close, not on initialization:
this.mdcAdapter.setSelectedTextAttr('aria-expanded', `${this.surface.open}`);
// TODO: it looks like the foundation doesn't update aria-expanded when the surface is
// opened programmatically.
}
destroyComponent() {
var _a;
(_a = this.foundation) === null || _a === void 0 ? void 0 : _a.destroy();
this.foundation = null;
}
reconstructComponent() {
this.destroyComponent();
this.initComponent();
}
setupMenuHandlers() {
if (this.menu) {
this.menu._listFunction = MdcListFunction.select;
this.menu.pick.pipe(takeUntil(this.onMenuChange$)).subscribe((evt) => {
var _a;
(_a = this.foundation) === null || _a === void 0 ? void 0 : _a.handleMenuItemAction(evt.index);
});
this.surface.afterOpened.pipe(takeUntil(this.onMenuChange$)).subscribe(() => {
var _a;
(_a = this.foundation) === null || _a === void 0 ? void 0 : _a.handleMenuOpened();
});
this.surface.afterClosed.pipe(takeUntil(this.onMenuChange$)).subscribe(() => {
var _a;
(_a = this.foundation) === null || _a === void 0 ? void 0 : _a.handleMenuClosed();
});
}
}
initListLabel() {
this._lists.forEach(list => {
list.labelledBy = this._listLabelledBy;
});
}
/**
* The value of the selected item.
*/
get value() {
return this._value;
}
set value(value) {
this.updateValue(value, ValueSource.program);
}
/** @internal */
updateValue(value, source) {
const oldSource = this._valueSource;
try {
if (!this._valueSource)
this._valueSource = source;
if (source === ValueSource.foundation) {
this._value = value;
Promise.resolve().then(() => {
this.valueChange.emit(value);
if (this._valueSource !== ValueSource.control)
this._onChange(value);
});
}
else if (value !== this.value) {
if (this.foundation) {
this.foundation.setValue(value); // foundation should also accept null value
// foundation will do a nested call for this function with source===foundation
// there we will handle the value change and emit to observers (see the if block preceding this)
}
else {
this._value = value;
Promise.resolve().then(() => {
this.valueChange.emit(value);
if (this._valueSource !== ValueSource.control)
this._onChange(value);
});
}
}
}
finally {
this._valueSource = oldSource;
}
}
/**
* To disable the select, set this input to a value other then false.
*/
get disabled() {
return this._disabled;
}
set disabled(value) {
var _a;
this._disabled = asBoolean(value);
(_a = this.foundation) === null || _a === void 0 ? void 0 : _a.setDisabled(this._disabled);
}
/**
* To make the select a required input, set this input to a value other then false.
*/
get required() {
return this._required;
}
set required(value) {
var _a;
this._required = asBoolean(value);
(_a = this.foundation) === null || _a === void 0 ? void 0 : _a.setRequired(this._required);
}
/** @internal */
get outlined() {
var _a;
return !!((_a = this.anchor) === null || _a === void 0 ? void 0 : _a._outline);
}
/** @internal */
get labeled() {
var _a;
return !((_a = this.anchor) === null || _a === void 0 ? void 0 : _a._label);
}
/** @internal */
setListLabelledBy(id) {
this._listLabelledBy = id;
this.initListLabel();
}
/** @internal */
get expanded() {
var _a;
return !!((_a = this.surface) === null || _a === void 0 ? void 0 : _a.open);
}
get menu() {
var _a, _b;
return (_b = (_a = this._menus) === null || _a === void 0 ? void 0 : _a.first) === null || _b === void 0 ? void 0 : _b._menu;
}
get surface() {
var _a, _b;
return (_b = (_a = this._menus) === null || _a === void 0 ? void 0 : _a.first) === null || _b === void 0 ? void 0 : _b._surface;
}
get anchor() {
var _a;
return (_a = this._anchors) === null || _a === void 0 ? void 0 : _a.first;
}
get label() {
var _a;
return (_a = this.anchor) === null || _a === void 0 ? void 0 : _a._label;
}
get text() {
var _a;
return (_a = this._texts) === null || _a === void 0 ? void 0 : _a.first;
}
getSelectedItem() {
var _a, _b;
return (_b = (_a = this.menu) === null || _a === void 0 ? void 0 : _a._list) === null || _b === void 0 ? void 0 : _b.getSelectedItem();
}
/** @internal */
registerOnChange(onChange) {
this._onChange = onChange;
}
/** @internal */
registerOnTouched(onTouched) {
this._onTouched = onTouched;
}
/** @internal */
onBlur() {
var _a;
(_a = this.foundation) === null || _a === void 0 ? void 0 : _a.handleBlur();
this._onTouched();
}
}
MdcSelectDirective.decorators = [
{ type: Directive, args: [{
selector: '[mdcSelect]'
},] }
];
MdcSelectDirective.ctorParameters = () => [
{ type: ElementRef },
{ type: Renderer2 },
{ type: undefined, decorators: [{ type: Inject, args: [DOCUMENT,] }] }
];
MdcSelectDirective.propDecorators = {
_cls: [{ type: HostBinding, args: ['class.mdc-select',] }],
valueChange: [{ type: Output }],
_anchors: [{ type: ContentChildren, args: [MdcSelectAnchorDirective,] }],
_outlines: [{ type: ContentChildren, args: [MdcNotchedOutlineDirective, { descendants: true },] }],
_menus: [{ type: ContentChildren, args: [MdcSelectMenuDirective,] }],
_lists: [{ type: ContentChildren, args: [MdcListDirective, { descendants: true },] }],
_texts: [{ type: ContentChildren, args: [MdcSelectTextDirective, { descendants: true },] }],
value: [{ type: Input }],
disabled: [{ type: Input }],
required: [{ type: Input }],
outlined: [{ type: HostBinding, args: ['class.mdc-select--outlined',] }],
labeled: [{ type: HostBinding, args: ['class.mdc-select--no-label',] }]
};
/**
* Directive for adding Angular Forms (<code>ControlValueAccessor</code>) behavior to an
* `mdcSelect`. Allows the use of the Angular Forms API with select inputs,
* e.g. binding to <code>[(ngModel)]</code>, form validation, etc.
*/
export class MdcFormsSelectDirective {
constructor(mdcSelect) {
this.mdcSelect = mdcSelect;
}
/** @docs-private */
writeValue(obj) {
this.mdcSelect.updateValue(obj, ValueSource.control);
}
/** @docs-private */
registerOnChange(onChange) {
this.mdcSelect.registerOnChange(onChange);
}
/** @docs-private */
registerOnTouched(onTouched) {
this.mdcSelect.registerOnTouched(onTouched);
}
/** @docs-private */
setDisabledState(disabled) {
this.mdcSelect.disabled = disabled;
}
}
MdcFormsSelectDirective.decorators = [
{ type: Directive, args: [{
selector: '[mdcSelect][formControlName],[mdcSelect][formControl],[mdcSelect][ngModel]',
providers: [
{ provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => MdcFormsSelectDirective), multi: true }
]
},] }
];
MdcFormsSelectDirective.ctorParameters = () => [
{ type: MdcSelectDirective, decorators: [{ type: Self }] }
];
export const SELECT_DIRECTIVES = [
MdcSelectTextDirective,
MdcSelectAnchorDirective,
MdcSelectMenuDirective,
MdcSelectDirective,
MdcFormsSelectDirective
];
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWRjLnNlbGVjdC5kaXJlY3RpdmUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvY29tcG9uZW50cy9zZWxlY3QvbWRjLnNlbGVjdC5kaXJlY3RpdmUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFvQixTQUFTLEVBQUUsVUFBVSxFQUFFLFVBQVUsRUFBRSxXQUFXLEVBQ3ZFLEtBQUssRUFBcUIsU0FBUyxFQUFFLElBQUksRUFBRSxlQUFlLEVBQWEsSUFBSSxFQUFFLFFBQVEsRUFDckYsWUFBWSxFQUFFLE1BQU0sRUFBRSxNQUFNLEVBQUUsWUFBWSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ3BFLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUMzQyxPQUFPLEVBQUUsdUJBQXVCLEVBQXdCLE1BQU0sdUJBQXVCLENBQUM7QUFDdEYsT0FBTyxFQUFFLG1CQUFtQixFQUFvQixVQUFVLEVBQUUsT0FBTyxFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFDOUYsT0FBTyxFQUFFLE9BQU8sRUFBRSxLQUFLLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDdEMsT0FBTyxFQUFFLFNBQVMsRUFBRSxZQUFZLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUN6RCxPQUFPLEVBQUUseUJBQXlCLEVBQUUsTUFBTSxnREFBZ0QsQ0FBQztBQUMzRixPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSwrQkFBK0IsQ0FBQztBQUNsRSxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxnQ0FBZ0MsQ0FBQztBQUNsRSxPQUFPLEVBQUUsMEJBQTBCLEVBQUUsTUFBTSxrREFBa0QsQ0FBQztBQUM5RixPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQUM5RCxPQUFPLEVBQUUsdUJBQXVCLEVBQUUsTUFBTSw0Q0FBNEMsQ0FBQztBQUNyRixPQUFPLEVBQUUsZUFBZSxFQUFFLGdCQUFnQixFQUFFLE1B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