UNPKG

@taiga-ui/kit

Version:
580 lines (571 loc) 26.8 kB
import { __extends, __spread, __decorate, __param, __read } from 'tslib'; import { EventEmitter, Optional, Self, Inject, ChangeDetectorRef, Input, HostBinding, Output, ContentChild, TemplateRef, ViewChild, Component, ChangeDetectionStrategy, forwardRef, Pipe, Directive, ContentChildren, NgModule } from '@angular/core'; import { TUI_DEFAULT_STRINGIFY, TUI_DEFAULT_IDENTITY_MATCHER, ALWAYS_FALSE_HANDLER, EMPTY_ARRAY, isNativeFocused, setNativeFocused, tuiDefaultProp, tuiPure, TUI_FOCUSABLE_ITEM_ACCESSOR, AbstractTuiMultipleControl, EMPTY_QUERY, itemsQueryListObservable, getOriginalArrayFromQueryList, isPresent, tuiReplayedValueChangesFrom, EMPTY_FUNCTION, TuiPreventDefaultModule, TuiActiveZoneModule, TuiLetModule, TuiMapperPipeModule, TuiHoveredModule } from '@taiga-ui/cdk'; import { NgControl, NG_VALUE_ACCESSOR, FormsModule } from '@angular/forms'; import { TuiSvgService, TuiTextfieldLabelOutsideDirective, TUI_TEXTFIELD_LABEL_OUTSIDE, TuiDataListDirective, TUI_DATA_LIST_ACCESSOR, TuiHostedDropdownComponent, TUI_DATA_LIST_HOST, TUI_OPTION_CONTENT, sizeBigger, TuiOptionComponent, TuiSvgModule, TuiHostedDropdownModule, TuiPrimitiveCheckboxModule, TuiDataListModule } from '@taiga-ui/core'; import { TuiStringifiableItem } from '@taiga-ui/kit/classes'; import { TuiInputTagComponent, TuiInputTagModule } from '@taiga-ui/kit/components/input-tag'; import { iconBlank } from '@taiga-ui/kit/constants'; import { FIXED_DROPDOWN_CONTROLLER_PROVIDER } from '@taiga-ui/kit/providers'; import { CommonModule } from '@angular/common'; import { TUI_MULTI_SELECT_OPTION, TuiMultiSelectOptionModule } from '@taiga-ui/kit/components/multi-select-option'; import { PolymorpheusModule } from '@tinkoff/ng-polymorpheus'; import { combineLatest } from 'rxjs'; import { map } from 'rxjs/operators'; var TuiMultiSelectComponent = /** @class */ (function (_super) { __extends(TuiMultiSelectComponent, _super); function TuiMultiSelectComponent(control, changeDetectorRef, svgService, textfieldLabelOutside) { var _this = _super.call(this, control, changeDetectorRef) || this; _this.textfieldLabelOutside = textfieldLabelOutside; _this.stringify = TUI_DEFAULT_STRINGIFY; _this.identityMatcher = TUI_DEFAULT_IDENTITY_MATCHER; _this.expandable = true; _this.search = ''; _this.editable = true; _this.disabledItemHandler = ALWAYS_FALSE_HANDLER; _this.valueContent = ''; _this.searchChange = new EventEmitter(); _this.open = false; _this.valueMapper = function (value, stringify, group) { return group ? EMPTY_ARRAY : value.map(function (item) { return new TuiStringifiableItem(item, stringify); }); }; _this.disabledItemHandlerWrapper = function (handler) { return function (stringifiable) { return typeof stringifiable === 'string' || handler(stringifiable.item); }; }; _this.datalist = ''; svgService.define({ iconBlank: iconBlank }); return _this; } TuiMultiSelectComponent_1 = TuiMultiSelectComponent; Object.defineProperty(TuiMultiSelectComponent.prototype, "nativeFocusableElement", { get: function () { return this.input ? this.input.nativeFocusableElement : null; }, enumerable: true, configurable: true }); Object.defineProperty(TuiMultiSelectComponent.prototype, "focused", { get: function () { return ((!!this.input && this.input.focused) || (!!this.hostedDropdown && this.hostedDropdown.focused)); }, enumerable: true, configurable: true }); Object.defineProperty(TuiMultiSelectComponent.prototype, "computedValue", { get: function () { return this.computedGroup ? EMPTY_ARRAY : this.value; }, enumerable: true, configurable: true }); Object.defineProperty(TuiMultiSelectComponent.prototype, "searchOrSpace", { // @bad TODO: think of a better way get: function () { return this.computedGroup ? ' ' : this.searchString; }, enumerable: true, configurable: true }); Object.defineProperty(TuiMultiSelectComponent.prototype, "searchString", { get: function () { return this.search === null ? '' : this.search; }, enumerable: true, configurable: true }); Object.defineProperty(TuiMultiSelectComponent.prototype, "tagIcon", { get: function () { return this.interactive ? 'iconBlank' : 'tuiIconChevronDownLarge'; }, enumerable: true, configurable: true }); Object.defineProperty(TuiMultiSelectComponent.prototype, "interactive", { get: function () { return !this.disabled && !this.readOnly; }, enumerable: true, configurable: true }); Object.defineProperty(TuiMultiSelectComponent.prototype, "inputHidden", { get: function () { return !this.editable && !this.computedGroup; }, enumerable: true, configurable: true }); Object.defineProperty(TuiMultiSelectComponent.prototype, "computedGroup", { get: function () { return (!!this.valueContent && this.value.length > 0 && (!this.focused || !this.editable)); }, enumerable: true, configurable: true }); Object.defineProperty(TuiMultiSelectComponent.prototype, "context", { get: function () { return this.getContext(this.value); }, enumerable: true, configurable: true }); TuiMultiSelectComponent.prototype.getStringifier = function (stringify) { return function (_a) { var $implicit = _a.$implicit; return stringify($implicit); }; }; TuiMultiSelectComponent.prototype.onHoveredChange = function (hovered) { this.updateHovered(hovered); }; TuiMultiSelectComponent.prototype.onSpace = function (event) { if (!this.editable) { event.preventDefault(); } if (!this.readOnly) { this.open = true; } }; TuiMultiSelectComponent.prototype.handleOption = function (option) { var _a = this, value = _a.value, identityMatcher = _a.identityMatcher; var index = value.findIndex(function (item) { return identityMatcher(item, option); }); this.updateValue(index === -1 ? __spread(value, [option]) : __spread(value.slice(0, index), value.slice(index + 1))); this.updateSearch(null); }; TuiMultiSelectComponent.prototype.onEnter = function (event) { var value = this.value; var options = this.accessor ? this.accessor.getOptions() : []; if (options.length !== 1) { return; } var index = value.indexOf(options[0]); event.preventDefault(); this.updateValue(index === -1 ? __spread(value, [options[0]]) : __spread(value.slice(0, index), value.slice(index + 1))); this.updateSearch(null); }; TuiMultiSelectComponent.prototype.onClick = function (_a) { var nativeFocusableElement = _a.nativeFocusableElement; if (this.interactive && nativeFocusableElement && isNativeFocused(nativeFocusableElement)) { this.open = !this.open; } }; TuiMultiSelectComponent.prototype.onArrowClick = function () { this.open = !this.open; this.focusInput(); }; TuiMultiSelectComponent.prototype.onInput = function (value) { this.updateValue(value.map(function (_a) { var item = _a.item; return item; })); }; TuiMultiSelectComponent.prototype.onSearch = function (search) { this.open = true; this.updateSearch(search); }; TuiMultiSelectComponent.prototype.onActiveZone = function (active) { this.updateFocused(active); }; TuiMultiSelectComponent.prototype.setDisabledState = function () { _super.prototype.setDisabledState.call(this); this.open = false; }; TuiMultiSelectComponent.prototype.updateSearch = function (search) { if (this.search === search) { return; } this.search = search; this.searchChange.emit(search); }; TuiMultiSelectComponent.prototype.focusInput = function (preventScroll) { if (preventScroll === void 0) { preventScroll = false; } if (this.nativeFocusableElement) { setNativeFocused(this.nativeFocusableElement, true, preventScroll); } }; TuiMultiSelectComponent.prototype.getContext = function ($implicit) { return { $implicit: $implicit }; }; var TuiMultiSelectComponent_1; TuiMultiSelectComponent.ctorParameters = function () { return [ { type: NgControl, decorators: [{ type: Optional }, { type: Self }, { type: Inject, args: [NgControl,] }] }, { type: ChangeDetectorRef, decorators: [{ type: Inject, args: [ChangeDetectorRef,] }] }, { type: TuiSvgService, decorators: [{ type: Inject, args: [TuiSvgService,] }] }, { type: TuiTextfieldLabelOutsideDirective, decorators: [{ type: Inject, args: [TUI_TEXTFIELD_LABEL_OUTSIDE,] }] } ]; }; __decorate([ Input(), tuiDefaultProp() ], TuiMultiSelectComponent.prototype, "stringify", void 0); __decorate([ Input(), tuiDefaultProp() ], TuiMultiSelectComponent.prototype, "identityMatcher", void 0); __decorate([ Input(), tuiDefaultProp() ], TuiMultiSelectComponent.prototype, "expandable", void 0); __decorate([ Input(), tuiDefaultProp() ], TuiMultiSelectComponent.prototype, "search", void 0); __decorate([ Input(), HostBinding('class._editable'), tuiDefaultProp() ], TuiMultiSelectComponent.prototype, "editable", void 0); __decorate([ Input(), tuiDefaultProp() ], TuiMultiSelectComponent.prototype, "disabledItemHandler", void 0); __decorate([ Input(), tuiDefaultProp() ], TuiMultiSelectComponent.prototype, "valueContent", void 0); __decorate([ Output() ], TuiMultiSelectComponent.prototype, "searchChange", void 0); __decorate([ ContentChild(TuiDataListDirective, { read: TemplateRef }) ], TuiMultiSelectComponent.prototype, "datalist", void 0); __decorate([ ContentChild(TUI_DATA_LIST_ACCESSOR) ], TuiMultiSelectComponent.prototype, "accessor", void 0); __decorate([ ViewChild(TuiHostedDropdownComponent) ], TuiMultiSelectComponent.prototype, "hostedDropdown", void 0); __decorate([ ViewChild(TuiInputTagComponent) ], TuiMultiSelectComponent.prototype, "input", void 0); __decorate([ tuiPure ], TuiMultiSelectComponent.prototype, "getStringifier", null); __decorate([ tuiPure ], TuiMultiSelectComponent.prototype, "getContext", null); TuiMultiSelectComponent = TuiMultiSelectComponent_1 = __decorate([ Component({ selector: 'tui-multi-select', template: "<tui-hosted-dropdown\n class=\"wrapper\"\n [canOpen]=\"interactive\"\n [content]=\"datalist || ''\"\n [(open)]=\"open\"\n (tuiHoveredChange)=\"onHoveredChange($event)\"\n (tuiActiveZoneChange)=\"onActiveZone($event)\"\n>\n <tui-input-tag\n tuiHostedDropdownHost\n #inputTag\n automation-id=\"tui-multi-select__input\"\n class=\"input\"\n [nativeId]=\"nativeId\"\n [icon]=\"tagIcon\"\n [disabled]=\"disabled\"\n [disabledItemHandler]=\"disabledItemHandler | tuiMapper : disabledItemHandlerWrapper\"\n [readOnly]=\"readOnly\"\n [inputHidden]=\"!editable\"\n [pseudoHovered]=\"hovered\"\n [pseudoFocused]=\"focused\"\n [pseudoInvalid]=\"computedInvalid\"\n [editable]=\"false\"\n [expandable]=\"expandable\"\n [search]=\"searchOrSpace\"\n [ngModel]=\"computedValue | tuiMapper: valueMapper: stringify\"\n (ngModelChange)=\"onInput($event)\"\n (searchChange)=\"onSearch($event)\"\n (keydown.space)=\"onSpace($event)\"\n (keydown.enter)=\"onEnter($event)\"\n (click.stop)=\"onClick(inputTag)\"\n >\n <ng-content></ng-content>\n </tui-input-tag>\n <div\n *ngIf=\"computedGroup\"\n polymorpheus-outlet\n class=\"group\"\n [class.group_fullsize]=\"textfieldLabelOutside.labelOutside\"\n [context]=\"context\"\n [content]=\"valueContent\"\n ></div>\n <tui-svg\n *ngIf=\"interactive\"\n automation-id=\"tui-multi-select__arrow\"\n class=\"arrow\"\n src=\"tuiIconChevronDownLarge\"\n tuiPreventDefault=\"mousedown\"\n [class.arrow_open]=\"open\"\n (click.prevent)=\"onArrowClick()\"\n ></tui-svg>\n</tui-hosted-dropdown>\n", changeDetection: ChangeDetectionStrategy.OnPush, providers: [ { provide: TUI_FOCUSABLE_ITEM_ACCESSOR, useExisting: forwardRef(function () { return TuiMultiSelectComponent_1; }), }, { provide: TUI_DATA_LIST_HOST, useExisting: forwardRef(function () { return TuiMultiSelectComponent_1; }), }, FIXED_DROPDOWN_CONTROLLER_PROVIDER, ], styles: [":host{position:relative;display:block}:host._disabled{pointer-events:none}.wrapper{display:block}:host:not(._editable):not(._readonly) .input{cursor:pointer}.arrow{transition-duration:.3s;transition-timing-function:ease-in-out;display:flex;width:24px;align-items:center;justify-content:center;color:var(--tui-text-03);box-sizing:border-box;transition-property:color,transform;position:absolute;top:50%;transform:translate(0,-50%);right:12px;height:24px;box-sizing:content-box;cursor:pointer}.arrow:hover{color:var(--tui-text-02)}:host._disabled .arrow,:host._readonly .arrow{pointer-events:none}:host[data-mode=onDark] .arrow{color:var(--tui-text-03-night)}:host[data-mode=onDark] .arrow:hover{color:var(--tui-text-01-night)}.arrow_open{transform:rotate(-180deg) translate(0,50%)}.group{position:absolute;top:0;left:0;bottom:0;display:flex;align-items:center;padding:27px 16px 9px;pointer-events:none}.group_fullsize{padding-top:1px;padding-bottom:0}:host[data-tui-host-size='m'] .group_fullsize.group_fullsize{padding-top:0}:host[data-tui-host-size='m'] .group{padding:19px 12px 0;font-size:13px}"] }), __param(0, Optional()), __param(0, Self()), __param(0, Inject(NgControl)), __param(1, Inject(ChangeDetectorRef)), __param(2, Inject(TuiSvgService)), __param(3, Inject(TUI_TEXTFIELD_LABEL_OUTSIDE)) ], TuiMultiSelectComponent); return TuiMultiSelectComponent; }(AbstractTuiMultipleControl)); var TuiHideSelectedPipe = /** @class */ (function () { function TuiHideSelectedPipe(component) { this.component = component; } TuiHideSelectedPipe.prototype.transform = function (items, _a) { var _b = _a === void 0 ? this.component : _a, value = _b.value, identityMatcher = _b.identityMatcher; return items && this.filter(items, value, identityMatcher); }; TuiHideSelectedPipe.prototype.filter = function (items, value, matcher) { return items.filter(function (item) { return value.every(function (selected) { return !matcher(selected, item); }); }); }; TuiHideSelectedPipe.ctorParameters = function () { return [ { type: TuiMultiSelectComponent, decorators: [{ type: Inject, args: [TuiMultiSelectComponent,] }] } ]; }; __decorate([ tuiPure ], TuiHideSelectedPipe.prototype, "filter", null); TuiHideSelectedPipe = __decorate([ Pipe({ name: 'tuiHideSelected', pure: false, }), __param(0, Inject(TuiMultiSelectComponent)) ], TuiHideSelectedPipe); return TuiHideSelectedPipe; }()); // TODO: Remove and switch to viewProviders when Angular is updated to Ivy /** @deprecated */ var TuiMultiSelectGroupResetDirective = /** @class */ (function () { function TuiMultiSelectGroupResetDirective() { } TuiMultiSelectGroupResetDirective = __decorate([ Directive({ selector: '[tuiMultiSelectGroupReset]', providers: [ { provide: TUI_OPTION_CONTENT, useValue: null, }, ], }) ], TuiMultiSelectGroupResetDirective); return TuiMultiSelectGroupResetDirective; }()); var TuiMultiSelectGroupComponent = /** @class */ (function () { function TuiMultiSelectGroupComponent(host, control) { this.host = host; this.control = control; this.label = ''; this.options = EMPTY_QUERY; } Object.defineProperty(TuiMultiSelectGroupComponent.prototype, "size", { get: function () { return (this.options.first && this.options.first.size) || 'm'; }, enumerable: true, configurable: true }); Object.defineProperty(TuiMultiSelectGroupComponent.prototype, "checkboxSize", { get: function () { return this.options.first && sizeBigger(this.options.first.size) ? 'l' : 'm'; }, enumerable: true, configurable: true }); Object.defineProperty(TuiMultiSelectGroupComponent.prototype, "empty$", { get: function () { return itemsQueryListObservable(this.options).pipe(map(function (_a) { var length = _a.length; return !length; })); }, enumerable: true, configurable: true }); Object.defineProperty(TuiMultiSelectGroupComponent.prototype, "disabled$", { get: function () { return itemsQueryListObservable(this.options).pipe(map(function (items) { return items.every(function (_a) { var disabled = _a.disabled; return disabled; }); })); }, enumerable: true, configurable: true }); Object.defineProperty(TuiMultiSelectGroupComponent.prototype, "value$", { get: function () { var _this = this; return combineLatest(this.items$, this.valueChanges$).pipe(map(function (_a) { var _b = __read(_a, 2), items = _b[0], current = _b[1]; var result = false; var _loop_1 = function (i) { var selected = current.some(function (selected) { return _this.matcher(selected, items[i]); }); if ((!selected && result) || (selected && !result && i)) { return { value: null }; } result = selected; }; for (var i = 0; i < items.length; i++) { var state_1 = _loop_1(i); if (typeof state_1 === "object") return state_1.value; } return result; })); }, enumerable: true, configurable: true }); TuiMultiSelectGroupComponent.prototype.onClick = function (checked) { var _this = this; if (!this.control.control) { return; } var controlValue = this.control.value || []; var values = this.values; var filtered = controlValue.filter(function (current) { return values.every(function (item) { return !_this.matcher(current, item); }); }); this.control.control.setValue(checked ? filtered : __spread(filtered, values)); }; Object.defineProperty(TuiMultiSelectGroupComponent.prototype, "values", { get: function () { return this.filter(getOriginalArrayFromQueryList(this.options)); }, enumerable: true, configurable: true }); Object.defineProperty(TuiMultiSelectGroupComponent.prototype, "matcher", { get: function () { return this.host.identityMatcher || TUI_DEFAULT_IDENTITY_MATCHER; }, enumerable: true, configurable: true }); Object.defineProperty(TuiMultiSelectGroupComponent.prototype, "items$", { get: function () { return itemsQueryListObservable(this.options).pipe(map(function (options) { return options.map(function (_a) { var value = _a.value; return value; }).filter(isPresent); })); }, enumerable: true, configurable: true }); Object.defineProperty(TuiMultiSelectGroupComponent.prototype, "valueChanges$", { get: function () { return tuiReplayedValueChangesFrom(this.control).pipe(map(function (value) { return value || []; })); }, enumerable: true, configurable: true }); TuiMultiSelectGroupComponent.prototype.filter = function (items) { return items.map(function (_a) { var value = _a.value; return value; }).filter(isPresent); }; TuiMultiSelectGroupComponent.ctorParameters = function () { return [ { type: undefined, decorators: [{ type: Inject, args: [TUI_DATA_LIST_HOST,] }] }, { type: NgControl, decorators: [{ type: Inject, args: [NgControl,] }] } ]; }; __decorate([ Input(), tuiDefaultProp() ], TuiMultiSelectGroupComponent.prototype, "label", void 0); __decorate([ ContentChildren(TuiOptionComponent) ], TuiMultiSelectGroupComponent.prototype, "options", void 0); __decorate([ tuiPure ], TuiMultiSelectGroupComponent.prototype, "empty$", null); __decorate([ tuiPure ], TuiMultiSelectGroupComponent.prototype, "disabled$", null); __decorate([ tuiPure ], TuiMultiSelectGroupComponent.prototype, "value$", null); __decorate([ tuiPure ], TuiMultiSelectGroupComponent.prototype, "items$", null); __decorate([ tuiPure ], TuiMultiSelectGroupComponent.prototype, "valueChanges$", null); __decorate([ tuiPure ], TuiMultiSelectGroupComponent.prototype, "filter", null); TuiMultiSelectGroupComponent = __decorate([ Component({ selector: 'tui-opt-group[tuiMultiSelectGroup]', template: "<ng-container *tuiLet=\"value$ | async as value\">\n <button\n *ngIf=\"label && !(empty$ | async)\"\n tuiMultiSelectGroupReset\n tuiOption\n [size]=\"size\"\n [disabled]=\"disabled$ | async\"\n (click)=\"onClick(value)\"\n >\n <tui-primitive-checkbox\n class=\"tui-space_right-3\"\n [size]=\"checkboxSize\"\n [value]=\"value\"\n ></tui-primitive-checkbox>\n <span class=\"label\">{{label}}</span>\n </button>\n</ng-container>\n<ng-content></ng-content>\n", changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{display:flex;flex-direction:column}:host:before{content:''}.label{font:var(--tui-font-text-xs);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;flex:1;color:var(--tui-text-02)}"] }), __param(0, Inject(TUI_DATA_LIST_HOST)), __param(1, Inject(NgControl)) ], TuiMultiSelectGroupComponent); return TuiMultiSelectGroupComponent; }()); function hostFallbackFactory(control, host) { return (host || { handleOption: function (option) { if (!control.control) { return; } var value = control.value || []; var index = value.indexOf(option); control.control.setValue(index === -1 ? __spread(value, [option]) : __spread(value.slice(0, index), value.slice(index + 1))); }, }); } var ɵ0 = TUI_MULTI_SELECT_OPTION, ɵ1 = { writeValue: EMPTY_FUNCTION, registerOnChange: EMPTY_FUNCTION, registerOnTouched: EMPTY_FUNCTION, }; var TuiMultiSelectGroupDirective = /** @class */ (function () { function TuiMultiSelectGroupDirective() { } TuiMultiSelectGroupDirective = __decorate([ Directive({ selector: '[tuiMultiSelectGroup]', providers: [ { provide: TUI_OPTION_CONTENT, useValue: ɵ0, }, { provide: TUI_DATA_LIST_HOST, deps: [ NgControl, [new Optional(), forwardRef(function () { return TuiMultiSelectComponent; })], ], useFactory: hostFallbackFactory, }, { provide: NG_VALUE_ACCESSOR, multi: true, useValue: ɵ1, }, ], }) ], TuiMultiSelectGroupDirective); return TuiMultiSelectGroupDirective; }()); var TuiMultiSelectModule = /** @class */ (function () { function TuiMultiSelectModule() { } TuiMultiSelectModule = __decorate([ NgModule({ imports: [ CommonModule, FormsModule, PolymorpheusModule, TuiPreventDefaultModule, TuiActiveZoneModule, TuiLetModule, TuiMapperPipeModule, TuiHoveredModule, TuiSvgModule, TuiHostedDropdownModule, TuiInputTagModule, TuiMultiSelectOptionModule, TuiPrimitiveCheckboxModule, TuiDataListModule, ], declarations: [ TuiMultiSelectComponent, TuiMultiSelectGroupComponent, TuiMultiSelectGroupDirective, TuiMultiSelectGroupResetDirective, TuiHideSelectedPipe, ], exports: [ TuiMultiSelectComponent, TuiMultiSelectGroupComponent, TuiMultiSelectGroupDirective, TuiHideSelectedPipe, ], }) ], TuiMultiSelectModule); return TuiMultiSelectModule; }()); /** * Generated bundle index. Do not edit. */ export { TuiHideSelectedPipe, TuiMultiSelectComponent, TuiMultiSelectGroupComponent, TuiMultiSelectGroupDirective, TuiMultiSelectGroupResetDirective, TuiMultiSelectModule, hostFallbackFactory, ɵ0, ɵ1 }; //# sourceMappingURL=taiga-ui-kit-components-multi-select.js.map