UNPKG

@angular/cdk

Version:

Angular Material Component Development Kit

151 lines (148 loc) 4.39 kB
import { Subject } from 'rxjs'; class SelectionModel { _multiple; _emitChanges; compareWith; _selection = new Set(); _deselectedToEmit = []; _selectedToEmit = []; _selected; get selected() { if (!this._selected) { this._selected = Array.from(this._selection.values()); } return this._selected; } changed = new Subject(); constructor(_multiple = false, initiallySelectedValues, _emitChanges = true, compareWith) { this._multiple = _multiple; this._emitChanges = _emitChanges; this.compareWith = compareWith; if (initiallySelectedValues && initiallySelectedValues.length) { if (_multiple) { initiallySelectedValues.forEach(value => this._markSelected(value)); } else { this._markSelected(initiallySelectedValues[0]); } this._selectedToEmit.length = 0; } } select(...values) { this._verifyValueAssignment(values); values.forEach(value => this._markSelected(value)); const changed = this._hasQueuedChanges(); this._emitChangeEvent(); return changed; } deselect(...values) { this._verifyValueAssignment(values); values.forEach(value => this._unmarkSelected(value)); const changed = this._hasQueuedChanges(); this._emitChangeEvent(); return changed; } setSelection(...values) { this._verifyValueAssignment(values); const oldValues = this.selected; const newSelectedSet = new Set(values.map(value => this._getConcreteValue(value))); values.forEach(value => this._markSelected(value)); oldValues.filter(value => !newSelectedSet.has(this._getConcreteValue(value, newSelectedSet))).forEach(value => this._unmarkSelected(value)); const changed = this._hasQueuedChanges(); this._emitChangeEvent(); return changed; } toggle(value) { return this.isSelected(value) ? this.deselect(value) : this.select(value); } clear(flushEvent = true) { this._unmarkAll(); const changed = this._hasQueuedChanges(); if (flushEvent) { this._emitChangeEvent(); } return changed; } isSelected(value) { return this._selection.has(this._getConcreteValue(value)); } isEmpty() { return this._selection.size === 0; } hasValue() { return !this.isEmpty(); } sort(predicate) { if (this._multiple && this.selected) { this._selected.sort(predicate); } } isMultipleSelection() { return this._multiple; } _emitChangeEvent() { this._selected = null; if (this._selectedToEmit.length || this._deselectedToEmit.length) { this.changed.next({ source: this, added: this._selectedToEmit, removed: this._deselectedToEmit }); this._deselectedToEmit = []; this._selectedToEmit = []; } } _markSelected(value) { value = this._getConcreteValue(value); if (!this.isSelected(value)) { if (!this._multiple) { this._unmarkAll(); } if (!this.isSelected(value)) { this._selection.add(value); } if (this._emitChanges) { this._selectedToEmit.push(value); } } } _unmarkSelected(value) { value = this._getConcreteValue(value); if (this.isSelected(value)) { this._selection.delete(value); if (this._emitChanges) { this._deselectedToEmit.push(value); } } } _unmarkAll() { if (!this.isEmpty()) { this._selection.forEach(value => this._unmarkSelected(value)); } } _verifyValueAssignment(values) { if (values.length > 1 && !this._multiple && (typeof ngDevMode === 'undefined' || ngDevMode)) { throw getMultipleValuesInSingleSelectionError(); } } _hasQueuedChanges() { return !!(this._deselectedToEmit.length || this._selectedToEmit.length); } _getConcreteValue(inputValue, selection) { if (!this.compareWith) { return inputValue; } else { selection = selection ?? this._selection; for (let selectedValue of selection) { if (this.compareWith(inputValue, selectedValue)) { return selectedValue; } } return inputValue; } } } function getMultipleValuesInSingleSelectionError() { return Error('Cannot pass multiple values into SelectionModel with single-value mode.'); } export { SelectionModel, getMultipleValuesInSingleSelectionError }; //# sourceMappingURL=_selection-model-chunk.mjs.map