@taiga-ui/kit
Version:
Taiga UI Angular main components kit
139 lines (135 loc) • 6.47 kB
JavaScript
import * as i0 from '@angular/core';
import { inject, signal, isSignal, computed, effect, untracked, Directive, Input } from '@angular/core';
import { TuiControl, tuiAsControl } from '@taiga-ui/cdk/classes';
import { TUI_STRICT_MATCHER, TUI_ALLOW_SIGNAL_WRITES } from '@taiga-ui/cdk/constants';
import { tuiInjectElement } from '@taiga-ui/cdk/utils/dom';
import { tuiAsOptionContent } from '@taiga-ui/core/components/data-list';
import * as i1 from '@taiga-ui/core/components/textfield';
import { TuiTextfieldComponent, TuiTextfieldDirective, tuiInjectAuxiliary, tuiAsTextfieldAccessor, TuiWithTextfield } from '@taiga-ui/core/components/textfield';
import { tuiDropdownOpen, tuiDropdownEnabled, TuiDropdownDirective } from '@taiga-ui/core/directives/dropdown';
import { TUI_ITEMS_HANDLERS } from '@taiga-ui/core/directives/items-handlers';
import { TuiSelectOption } from '@taiga-ui/kit/components/select';
class TuiComboBox extends TuiControl {
constructor() {
super(...arguments);
this.el = tuiInjectElement();
this.host = inject(TuiTextfieldComponent);
this.textfield = inject(TuiTextfieldDirective);
this.open = tuiDropdownOpen();
this.dropdownEnabled = tuiDropdownEnabled(this.interactive);
this.dropdown = inject(TuiDropdownDirective);
this.itemsHandlers = inject(TUI_ITEMS_HANDLERS);
this.matcher = signal(TUI_STRICT_MATCHER);
this.strict = signal(true);
this.datalist = tuiInjectAuxiliary((x) => x !== this && 'options' in x && isSignal(x.options));
this.options = computed(() => this.datalist()
?.options?.() // TODO(v5): remove optional call `?.()`
.filter((x) => !this.itemsHandlers.disabledItemHandler()(x)) ?? []);
this.nonStrictValueEffect = effect(() => {
if (!this.options().length &&
!this.strict() &&
this.stringify(this.value()) !== this.textfield.value()) {
this.onChange(this.textfield.value() || null);
}
}, TUI_ALLOW_SIGNAL_WRITES);
this.matchingEffect = effect(() => {
const options = this.options();
const matcher = this.matcher();
if (!options.length || !matcher) {
return;
}
const textfieldValue = this.textfield.value();
const selectedOption = options.find((x) => matcher(x, textfieldValue, this.itemsHandlers.stringify())) ?? null;
const stringified = this.stringify(selectedOption);
const fallback = this.strict() || !textfieldValue ? null : textfieldValue;
this.onChange(selectedOption ?? fallback);
if (stringified && stringified !== textfieldValue) {
this.textfield.value.set(stringified);
}
}, TUI_ALLOW_SIGNAL_WRITES);
this.blurEffect = effect(() => {
const incomplete = untracked(() => this.strict() && !this.value());
if (!this.host.focused() && incomplete) {
this.textfield.value.set('');
}
}, TUI_ALLOW_SIGNAL_WRITES);
}
// TODO(v5): use signal input
set strictSetter(x) {
this.strict.set(x);
}
// TODO(v5): use signal input
set matcherSetter(x) {
this.matcher.set(x);
}
setValue(value) {
const stringified = this.stringify(value);
if (stringified !== this.textfield.value()) {
this.textfield.value.set(stringified);
setTimeout((end = stringified.length) => this.el.setSelectionRange(end, end));
}
this.onChange(value);
if (!value) {
this.toggleDropdown(true);
}
}
writeValue(value) {
super.writeValue(value);
this.textfield.value.set(this.stringify(value));
}
toggleDropdown(open = !this.open()) {
if (this.dropdownEnabled() && this.dropdown._content()) {
this.open.set(open);
}
}
keydownEnter(event) {
if (!this.open()) {
return;
}
event.preventDefault();
const options = this.options();
if (options.length === 1 && options[0]) {
this.setValue(options[0]);
this.toggleDropdown(false);
}
}
stringify(value) {
return value ? this.itemsHandlers.stringify()(value) : '';
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: TuiComboBox, deps: null, target: i0.ɵɵFactoryTarget.Directive }); }
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.12", type: TuiComboBox, isStandalone: true, selector: "input[tuiComboBox]", inputs: { strictSetter: ["strict", "strictSetter"], matcherSetter: ["matcher", "matcherSetter"] }, host: { listeners: { "click": "toggleDropdown()", "input": "toggleDropdown(true)", "keydown.enter": "keydownEnter($event)" }, properties: { "disabled": "disabled()" } }, providers: [
tuiAsOptionContent(TuiSelectOption),
tuiAsTextfieldAccessor(TuiComboBox),
tuiAsControl(TuiComboBox),
], usesInheritance: true, hostDirectives: [{ directive: i1.TuiWithTextfield }], ngImport: i0 }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: TuiComboBox, decorators: [{
type: Directive,
args: [{
standalone: true,
selector: 'input[tuiComboBox]',
providers: [
tuiAsOptionContent(TuiSelectOption),
tuiAsTextfieldAccessor(TuiComboBox),
tuiAsControl(TuiComboBox),
],
hostDirectives: [TuiWithTextfield],
host: {
'[disabled]': 'disabled()',
'(click)': 'toggleDropdown()',
'(input)': 'toggleDropdown(true)',
'(keydown.enter)': 'keydownEnter($event)',
},
}]
}], propDecorators: { strictSetter: [{
type: Input,
args: ['strict']
}], matcherSetter: [{
type: Input,
args: ['matcher']
}] } });
/**
* Generated bundle index. Do not edit.
*/
export { TuiComboBox };
//# sourceMappingURL=taiga-ui-kit-components-combo-box.mjs.map