@doku-dev/doku-fragment
Version:
A new Angular UI library that moving away from Bootstrap and built from scratch.
610 lines • 94.6 kB
JavaScript
import { CommonModule, DOCUMENT } from '@angular/common';
import { ChangeDetectionStrategy, Component, ContentChild, EventEmitter, HostBinding, Inject, Input, Optional, Output, Self, ViewChild, ViewEncapsulation, } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { BehaviorSubject, ReplaySubject, Subject, delay, distinctUntilChanged, filter, fromEvent, map, skip, startWith, switchMap, takeUntil, tap, } from 'rxjs';
import { getClickType } from '../../utils/get-click-type';
import { updateFloatingPosition } from '../../utils/update-floating-position';
import { DOKU_FORM_FIELD_ACCESSOR, DokuFormField, } from '../form-field';
import { DokuTypographyModule } from '../typography';
import { DokuSelectLabelTemplate } from './directives/select-label-template.directive';
import { DokuSelectLoadingTemplate } from './directives/select-loading-template.directive';
import { DokuSelectNoItemTemplate } from './directives/select-no-item-template.directive';
import { DokuSelectOptionTemplate } from './directives/select-option-template.directive';
import { ItemInjectionUtil } from './utils/item-injection.util';
import { SearchUtil } from './utils/search.util';
import { StyleUtil } from './utils/style.util';
import { ValueUtil } from './utils/value.util';
import { ViewElementUtil } from './utils/view-element.util';
import * as i0 from "@angular/core";
import * as i1 from "@angular/forms";
import * as i2 from "@angular/common";
import * as i3 from "../typography/typography.component";
import * as i4 from "../form-field";
export class DokuSelect {
/**
* List of options that will be shown on the dropdown.
*
* Supported values:
* - array of string or number
* - array of object (nested object is not supported)
*
* @default []
*/
get items() {
return this._items;
}
set items(value) {
this._items = this.normalizeInputItems(value);
this._notifyOnChange$.next({ type: 'item' });
}
/**
* Value of the selected options.
*
* @default undefined
*/
get value() {
return this._value;
}
set value(value) {
this._value = ValueUtil.normalizeValue('', value, { multiple: this.multiple });
this._notifyOnChange$.next({ type: 'value' });
}
/**
* Whether the select should allow multiple options selected simultaneously.
*
* @default false
*/
get multiple() {
return this._multiple;
}
set multiple(value) {
this._multiple = value;
this._notifyOnChange$.next({ type: 'multiple' });
}
/**
* Whether to truncate the label when the width is reached.
*
* Does not truncate the label if `multiple` is true.
*
* @default false
*/
get truncateLabel() {
return this._truncateLabel;
}
set truncateLabel(value) {
this._truncateLabel = this.multiple ? false : value;
}
/**
* The placement of the arrow icon.
*
* @default 'right'
*/
get arrowPlacement() {
return this._arrowPlacement;
}
set arrowPlacement(value) {
this._arrowPlacement = value;
this._notifyOnChange$.next({ type: 'arrowPlacement' });
}
/**
* Whether the select input should be disabled.
*
* @default false;
*/
get disabled() {
return this._disabled;
}
set disabled(value) {
this._disabled = value;
this._notifyOnChange$.next({ type: 'disabled' });
}
/**
* Whether the select input is readonly.
*
* @default false
*/
get readonly() {
return this._readonly;
}
set readonly(value) {
this._readonly = value;
this._notifyOnChange$.next({ type: 'readonly' });
}
/**
* Whether to provide async data fetching when searching data.
* It will display a loading state in the select options.
*
* Only works when `searchable` is true.
*
* @default false
*/
get isAsync() {
return this._isAsync;
}
set isAsync(value) {
this._isAsync = value;
}
/**
* Whether options dropdown state is opened.
*/
get isOpen() {
return this._isOpen;
}
set isOpen(value) {
this._isOpen = value;
this.cdr.detectChanges();
}
/**
* Loading state used when `isAsync` is true.
*/
get loading() {
return this._loading;
}
set loading(value) {
this._loading = this.isAsync ? value : false;
this._notifyOnChange$.next({ type: 'loading' });
}
constructor(envInjector, appRef, ngZone, injector, cdr, renderer, document, ngControl, formField) {
this.envInjector = envInjector;
this.appRef = appRef;
this.ngZone = ngZone;
this.injector = injector;
this.cdr = cdr;
this.renderer = renderer;
this.document = document;
this.ngControl = ngControl;
this.formField = formField;
this._items = [];
/**
* Bind property key of the label from the item if `items` value is an array of object.
*
* @default 'label'
*/
this.bindLabel = 'label';
/**
* Bind property key of the value from the item if `items` value is an array of object.
*
* @default 'value'
*/
this.bindValue = 'value';
this._value = '';
/**
* Placeholder of the field.
*
* @default ''
*/
this.placeholder = '';
this._multiple = false;
this._truncateLabel = false;
this._arrowPlacement = 'right';
this._disabled = false;
this._readonly = false;
/**
* Whether the select options are searchable.
*
* @default false
*/
this.searchable = false;
this._isAsync = false;
/**
* Whether the selected item can be cleared by clicking an icon.
*
* For `multiple`, it will remove all selected items.
*
* @default false
*/
this.clearable = false;
/**
* An event emitted when value changes.
*/
this.valueChange = new EventEmitter();
/**
* An event emitted if `searchable` is `true`.
*/
this.search = new EventEmitter();
this._notifyOnChange$ = new Subject();
this._isOpen = false;
this._loading = false;
this.search$ = new BehaviorSubject('');
this.filteredItems = [];
this.valueDetails = [];
this.destroy$ = new ReplaySubject();
if (this.ngControl) {
this.ngControl.valueAccessor = this;
}
this.handleCloseOptionsClickOutside();
}
get classes() {
return ['d-select', `d-select-arrow-${this.arrowPlacement}`];
}
get hasValue() {
if (this.multiple)
return !!this.value?.length;
return !!this.value;
}
get shouldShowPlaceholder() {
return !this.hasValue && !this.search$.value;
}
get shouldShowValueSingleSelect() {
return !!this.hasValue && !this.multiple && !this.search$.value;
}
get shouldShowValueMultipleSelect() {
return !!this.hasValue && this.multiple;
}
get inputWrapperElement() {
return this.formField?.['inputWrapperElement'];
}
ngOnInit() {
// Handle value details
this._notifyOnChange$
.pipe(filter(({ type }) => type === 'item' || type === 'value'), startWith({ value: this.value, items: this.items }), map(() => ({ value: this.value, items: this.items })), distinctUntilChanged((prev, current) => JSON.stringify(prev) === JSON.stringify(current)), tap(({ value, items }) => {
this.valueDetails = ValueUtil.convertValueToFullDetails(value, items, {
bindValue: this.bindValue,
multiple: this.multiple,
prevValueDetails: this.valueDetails,
});
this.cdr.detectChanges();
}), distinctUntilChanged((prev, current) => JSON.stringify(prev.value) === JSON.stringify(current.value)),
// Do skip first change because we want to avoid triggering onChange on initial value.
skip(1), takeUntil(this.destroy$))
.subscribe(({ value }) => {
this.onChange?.(value);
this.valueChange.emit(value);
});
// Handle filtered items
this._notifyOnChange$
.pipe(filter(({ type }) => type === 'item' || type === 'loading'), tap(({ type }) => {
if (type === 'item' && this.loading)
this.loading = false;
}), startWith(this.items), switchMap(() => SearchUtil.useSearchMatcher(this.items, {
bindLabel: this.bindLabel,
search$: this.search$,
searchable: this.searchable,
customSearchMatcherFn: this.searchMatcherFn,
})), takeUntil(this.destroy$))
.subscribe((items) => {
this.filteredItems = items;
if (!this.isOpen)
return;
// Handle on demand select options.
this.injectSelectOptions();
});
this.search$
.pipe(skip(1), filter(() => this.searchable), distinctUntilChanged(), takeUntil(this.destroy$))
.subscribe((value) => {
if (!this.loading)
this.loading = true;
this.search.emit(value);
this.cdr.detectChanges();
});
}
ngAfterContentInit() {
this.cdr.detectChanges();
}
ngAfterViewInit() {
this._notifyOnChange$
.pipe(filter(({ type }) => type === 'arrowPlacement' || type === 'multiple'), startWith({ arrowPlacement: this.arrowPlacement, multiple: this.multiple }), map(() => ({ arrowPlacement: this.arrowPlacement, multiple: this.multiple })), distinctUntilChanged((prev, current) => JSON.stringify(prev) === JSON.stringify(current)), delay(0), takeUntil(this.destroy$))
.subscribe(({ arrowPlacement, multiple }) => {
StyleUtil.handleInputWrapperStyle({
inputWrapperElement: this.inputWrapperElement,
arrowPlacement: arrowPlacement,
multiple: multiple,
});
});
this._notifyOnChange$
.pipe(filter(({ type }) => type === 'disabled' || type === 'readonly'), startWith({ disabled: this.disabled, readonly: this.readonly }), map(() => ({ disabled: this.disabled, readonly: this.readonly })), distinctUntilChanged((prev, current) => JSON.stringify(prev) === JSON.stringify(current)), delay(0), takeUntil(this.destroy$))
.subscribe(({ disabled, readonly }) => {
if (typeof disabled === 'boolean')
this.onDisable?.(disabled);
if (typeof readonly === 'boolean')
this.onReadonly?.(readonly);
StyleUtil.setInputWrapperCursorState({ readonly, disabled }, { inputWrapperElement: this.inputWrapperElement, searchable: this.searchable });
});
this.ngControl?.statusChanges
?.pipe(map((status) => ({
status: status,
state: {
pristine: this.ngControl?.control?.pristine,
untouched: this.ngControl?.control?.untouched,
},
})), distinctUntilChanged((prev, curr) => JSON.stringify(prev) === JSON.stringify(curr)), delay(0), takeUntil(this.destroy$))
.subscribe(({ status, state }) => {
if (status === 'VALID') {
this.onValidate?.('valid', state);
}
else if (status === 'INVALID') {
this.onValidate?.('invalid', state);
}
else {
this.onValidate?.(undefined, state);
}
});
}
ngOnDestroy() {
this.close();
this.destroy$.next(1);
this.destroy$.complete();
}
writeValue(value) {
this.value = value;
}
registerOnChange(fn) {
this.onChange = fn;
}
registerOnTouched(fn) {
this.onTouched = fn;
}
setDisabledState(isDisabled) {
this.disabled = isDisabled;
}
onClickWrapperElement() {
this.searchable ? this.open() : this.toggle();
}
registerOnDisable(fn) {
this.onDisable = fn;
}
registerOnReadonly(fn) {
this.onReadonly = fn;
}
registerOnValidate(fn) {
this.onValidate = fn;
}
/**
* Open select dropdown programmatically.
*/
open() {
if (this.disabled || this.readonly || this.isOpen)
return;
this.isOpen = true;
this.openSelectDropdownPortal();
this.injectSelectOptions();
this.scrollToActiveOption();
this.doAutoUpdateDropdownPosition();
this.cdr.detectChanges();
// If searchable, focus to text input
// and select options
if (this.searchable) {
this.searchInput?.nativeElement.focus();
}
}
/**
* Close select dropdown programmatically.
*/
close() {
if (this.disabled || this.readonly || !this.isOpen)
return;
this.isOpen = false;
this.closeSelectDropdownPortal();
this.cleanup?.();
this.onTouched?.();
this.cdr.detectChanges();
// Clear search if searchable is allowed
if (this.searchable)
this.search$.next('');
// Reset loading state
this.loading = false;
}
/**
* Toggle select dropdown programmatically.
*/
toggle() {
if (this.disabled || this.readonly)
return;
this.isOpen ? this.close() : this.open();
}
clearValue(event) {
if (!this.clearable || this.disabled)
return;
event.preventDefault();
event.stopPropagation();
this.value = '';
if (this.searchable)
this.search$.next('');
this.cdr.markForCheck();
this.onTouched?.();
}
removeItem(item) {
if (!this.multiple)
return;
this.patchNextValue(item[this.bindValue]);
}
onSearchValueChange(event) {
const value = event.target.value;
this.search$.next(value);
this.onTouched?.();
}
/**
* Update value from upcoming.
*
* If `multiple` is true, it will add/push value if not exist
* or will remove value when already exist.
*/
patchNextValue(value) {
this.value = ValueUtil.normalizeValue(this.value, value, { multiple: this.multiple });
}
/**
* Normalize input items to object where the value will be converted to string.
* @param items Input items.
* @returns Normalized items to object key-value pairs.
*/
normalizeInputItems(items) {
return items
.map((item) => {
if (typeof item === 'string') {
return { [this.bindLabel]: item, [this.bindValue]: item };
}
if (typeof item === 'number') {
return { [this.bindLabel]: item.toString(), [this.bindValue]: item.toString() };
}
if (item && typeof item === 'object' && !!Object.keys(item).length) {
let value = item[this.bindValue];
if (!['string', 'number'].includes(typeof value))
return null;
if (typeof value === 'number')
value = value.toString();
return { ...item, [this.bindValue]: value };
}
return null;
})
.filter(Boolean);
}
openSelectDropdownPortal() {
this.portalRef = ViewElementUtil.createSelectDropdownPortal({
applicationRef: this.appRef,
environmentInjector: this.envInjector,
parentElementInjector: this.injector,
renderer: this.renderer,
inputWrapperElement: this.inputWrapperElement,
portalClass: this.portalClass,
});
this.renderer.appendChild(this.document.body, this.portalRef.location.nativeElement);
}
closeSelectDropdownPortal() {
this.portalRef?.destroy();
this.portalRef = undefined;
}
injectSelectOptions() {
if (!this.portalRef)
return;
ItemInjectionUtil.injectSelectOptions(this.filteredItems, {
appRef: this.appRef,
bindLabel: this.bindLabel,
bindValue: this.bindValue,
envInjector: this.envInjector,
portalRef: this.portalRef,
renderer: this.renderer,
clickFn: this.handleOnClickSelectOption.bind(this),
loading: this.loading,
}, { loading: this.loadingTemplate, noItem: this.noItemTemplate, option: this.optionTemplate });
}
handleOnClickSelectOption(item) {
return () => {
if (item.disabled)
return;
this.patchNextValue(item[this.bindValue]);
this.onTouched?.();
// Clear searchable value if searchable.
if (this.searchable)
this.search$.next('');
// Don't close the dropdown if selection is multiple.
if (!this.multiple)
this.close();
// Re-focus to search input on multiple selection and searchable.
if (this.multiple && this.searchable) {
this.searchInput?.nativeElement.focus();
}
};
}
handleCloseOptionsClickOutside() {
this.ngZone.runOutsideAngular(() => {
fromEvent(this.document, 'click')
.pipe(filter(() => this.isOpen), takeUntil(this.destroy$))
.subscribe((event) => {
const { clickOutside, clickTrigger } = getClickType(event, [this.inputWrapperElement], [this.portalRef?.location.nativeElement]);
if (clickOutside && !clickTrigger)
this.close();
});
});
}
scrollToActiveOption() {
setTimeout(() => {
const selectedElement = this.portalRef?.location.nativeElement.querySelector('.d-select-option-selected');
if (selectedElement && this.portalRef) {
this.portalRef.location.nativeElement.scrollTop = selectedElement.offsetTop;
}
}, 0);
}
doAutoUpdateDropdownPosition() {
this.ngZone.runOutsideAngular(() => {
if (!this.inputWrapperElement || !this.portalRef?.location.nativeElement)
return;
this.cleanup = updateFloatingPosition({
triggerElement: this.inputWrapperElement,
floatingElement: this.portalRef?.location.nativeElement,
placement: 'bottom-start',
autoUpdate: true,
middleware: {
flip: true,
shift: true,
},
});
});
}
}
DokuSelect.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: DokuSelect, deps: [{ token: i0.EnvironmentInjector }, { token: i0.ApplicationRef }, { token: i0.NgZone }, { token: i0.Injector }, { token: i0.ChangeDetectorRef }, { token: i0.Renderer2 }, { token: DOCUMENT }, { token: i1.NgControl, optional: true, self: true }, { token: DokuFormField, optional: true }], target: i0.ɵɵFactoryTarget.Component });
DokuSelect.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.9", type: DokuSelect, isStandalone: true, selector: "doku-select", inputs: { items: "items", bindLabel: "bindLabel", bindValue: "bindValue", value: "value", placeholder: "placeholder", portalClass: "portalClass", multiple: "multiple", truncateLabel: "truncateLabel", arrowPlacement: "arrowPlacement", disabled: "disabled", readonly: "readonly", searchable: "searchable", isAsync: "isAsync", searchMatcherFn: "searchMatcherFn", clearable: "clearable" }, outputs: { valueChange: "valueChange", search: "search" }, host: { properties: { "class.d-select-multiple": "this.multiple", "class.d-select-truncated-label": "this.truncateLabel", "class": "this.classes" } }, providers: [{ provide: DOKU_FORM_FIELD_ACCESSOR, useExisting: DokuSelect }], queries: [{ propertyName: "labelTemplate", first: true, predicate: DokuSelectLabelTemplate, descendants: true }, { propertyName: "optionTemplate", first: true, predicate: DokuSelectOptionTemplate, descendants: true }, { propertyName: "noItemTemplate", first: true, predicate: DokuSelectNoItemTemplate, descendants: true }, { propertyName: "loadingTemplate", first: true, predicate: DokuSelectLoadingTemplate, descendants: true }], viewQueries: [{ propertyName: "searchInput", first: true, predicate: ["searchInput"], descendants: true }], exportAs: ["dokuSelect"], ngImport: i0, template: "<div class=\"d-select-value-container\">\n <div *ngIf=\"shouldShowPlaceholder\" class=\"d-select-placeholder\" doku-typography variant=\"body-m\">\n <ng-container>{{ placeholder || \" \" }}</ng-container>\n </div>\n\n <ng-container *ngIf=\"shouldShowValueSingleSelect || shouldShowValueMultipleSelect\">\n <ng-container\n *ngIf=\"labelTemplate && !multiple\"\n [ngTemplateOutlet]=\"labelTemplate.templateRef\"\n [ngTemplateOutletContext]=\"{ $implicit: valueDetails[0] }\"\n ></ng-container>\n\n <ng-container *ngIf=\"labelTemplate && multiple\">\n <ng-container *ngFor=\"let item of valueDetails\">\n <ng-container\n [ngTemplateOutlet]=\"labelTemplate.templateRef\"\n [ngTemplateOutletContext]=\"{ $implicit: item, removeItem: removeItem.bind(this) }\"\n ></ng-container>\n </ng-container>\n </ng-container>\n\n <ng-container *ngIf=\"!labelTemplate\">\n <div *ngFor=\"let item of valueDetails\" class=\"d-select-value\">\n <ng-container *ngIf=\"!multiple\">{{ item[bindLabel] }}</ng-container>\n <ng-container *ngIf=\"multiple\">\n <div (click)=\"removeItem(item)\">\n <ng-container *ngTemplateOutlet=\"iconClose\"></ng-container>\n </div>\n <span> </span>\n <div doku-typography variant=\"label\">{{ item[bindLabel] }}</div>\n </ng-container>\n </div>\n </ng-container>\n </ng-container>\n\n <input\n #searchInput\n *ngIf=\"searchable && !disabled && !readonly\"\n type=\"text\"\n class=\"d-select-searchable-input\"\n [class.relative]=\"hasValue\"\n [class.opened]=\"isOpen\"\n [value]=\"search$.value\"\n (input)=\"onSearchValueChange($event)\"\n />\n</div>\n\n<div\n *ngIf=\"clearable && hasValue && !disabled\"\n class=\"d-select-clearable\"\n (click)=\"clearValue($event)\"\n>\n <ng-container *ngTemplateOutlet=\"iconClose\"></ng-container>\n</div>\n\n<div class=\"d-select-arrow\" [ngClass]=\"arrowPlacement\">\n <ng-template *ngTemplateOutlet=\"iconArrow\"></ng-template>\n</div>\n\n<ng-template #iconArrow>\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\">\n <path\n d=\"M7.56745 14.4236L4.80999 10.5154C4.48457 10.0556 4.74905 9.33337 5.24293 9.33337H10.7578C10.8684 9.33326 10.9766 9.37265 11.0695 9.44683C11.1625 9.52101 11.2362 9.62684 11.2819 9.75164C11.3276 9.87644 11.3433 10.0149 11.3271 10.1505C11.311 10.2861 11.2636 10.413 11.1908 10.5161L8.43333 14.4229C8.37936 14.4995 8.31281 14.5609 8.23814 14.6029C8.16346 14.645 8.0824 14.6667 8.00039 14.6667C7.91838 14.6667 7.83731 14.645 7.76264 14.6029C7.68797 14.5609 7.62142 14.4995 7.56745 14.4229V14.4236Z\"\n fill=\"currentColor\"\n />\n <path\n d=\"M7.56745 1.57638L4.80999 5.48461C4.48457 5.94444 4.74905 6.66663 5.24293 6.66663H10.7578C10.8684 6.66674 10.9766 6.62735 11.0695 6.55317C11.1625 6.47899 11.2362 6.37316 11.2819 6.24836C11.3276 6.12356 11.3433 5.98508 11.3271 5.84949C11.311 5.71391 11.2636 5.58698 11.1908 5.48389L8.43333 1.5771C8.37936 1.50052 8.31281 1.43915 8.23814 1.3971C8.16346 1.35505 8.0824 1.33329 8.00039 1.33329C7.91838 1.33329 7.83731 1.35505 7.76264 1.3971C7.68797 1.43915 7.62142 1.50052 7.56745 1.5771V1.57638Z\"\n fill=\"currentColor\"\n />\n </svg>\n</ng-template>\n\n<ng-template #iconClose>\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"17\" height=\"16\" viewBox=\"0 0 17 16\" fill=\"none\">\n <path\n fill-rule=\"evenodd\"\n clip-rule=\"evenodd\"\n d=\"M12.2544 4.14598C12.301 4.19242 12.3379 4.2476 12.3631 4.30834C12.3883 4.36909 12.4013 4.43421 12.4013 4.49998C12.4013 4.56575 12.3883 4.63087 12.3631 4.69161C12.3379 4.75236 12.301 4.80753 12.2544 4.85398L5.25441 11.854C5.16053 11.9479 5.03319 12.0006 4.90041 12.0006C4.76764 12.0006 4.6403 11.9479 4.54641 11.854C4.45253 11.7601 4.39978 11.6328 4.39978 11.5C4.39978 11.3672 4.45253 11.2399 4.54641 11.146L11.5464 4.14598C11.5929 4.09941 11.648 4.06247 11.7088 4.03727C11.7695 4.01206 11.8346 3.99908 11.9004 3.99908C11.9662 3.99908 12.0313 4.01206 12.092 4.03727C12.1528 4.06247 12.208 4.09941 12.2544 4.14598Z\"\n fill=\"currentColor\"\n stroke=\"currentColor\"\n />\n <path\n fill-rule=\"evenodd\"\n clip-rule=\"evenodd\"\n d=\"M4.54643 4.14598C4.49987 4.19242 4.46292 4.2476 4.43772 4.30834C4.41251 4.36909 4.39954 4.43421 4.39954 4.49998C4.39954 4.56575 4.41251 4.63087 4.43772 4.69161C4.46292 4.75236 4.49987 4.80753 4.54643 4.85398L11.5464 11.854C11.6403 11.9479 11.7677 12.0006 11.9004 12.0006C12.0332 12.0006 12.1605 11.9479 12.2544 11.854C12.3483 11.7601 12.4011 11.6328 12.4011 11.5C12.4011 11.3672 12.3483 11.2399 12.2544 11.146L5.25443 4.14598C5.20798 4.09941 5.15281 4.06247 5.09206 4.03727C5.03132 4.01206 4.9662 3.99908 4.90043 3.99908C4.83466 3.99908 4.76954 4.01206 4.7088 4.03727C4.64805 4.06247 4.59288 4.09941 4.54643 4.14598Z\"\n fill=\"currentColor\"\n stroke=\"currentColor\"\n />\n </svg>\n</ng-template>\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: DokuTypographyModule }, { kind: "component", type: i3.DokuTypography, selector: "[doku-typography]", inputs: ["variant"], exportAs: ["dokuTypography"] }, { kind: "ngmodule", type: FormsModule }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: DokuSelect, decorators: [{
type: Component,
args: [{ selector: 'doku-select', exportAs: 'dokuSelect', standalone: true, imports: [CommonModule, DokuTypographyModule, FormsModule], encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, providers: [{ provide: DOKU_FORM_FIELD_ACCESSOR, useExisting: DokuSelect }], template: "<div class=\"d-select-value-container\">\n <div *ngIf=\"shouldShowPlaceholder\" class=\"d-select-placeholder\" doku-typography variant=\"body-m\">\n <ng-container>{{ placeholder || \" \" }}</ng-container>\n </div>\n\n <ng-container *ngIf=\"shouldShowValueSingleSelect || shouldShowValueMultipleSelect\">\n <ng-container\n *ngIf=\"labelTemplate && !multiple\"\n [ngTemplateOutlet]=\"labelTemplate.templateRef\"\n [ngTemplateOutletContext]=\"{ $implicit: valueDetails[0] }\"\n ></ng-container>\n\n <ng-container *ngIf=\"labelTemplate && multiple\">\n <ng-container *ngFor=\"let item of valueDetails\">\n <ng-container\n [ngTemplateOutlet]=\"labelTemplate.templateRef\"\n [ngTemplateOutletContext]=\"{ $implicit: item, removeItem: removeItem.bind(this) }\"\n ></ng-container>\n </ng-container>\n </ng-container>\n\n <ng-container *ngIf=\"!labelTemplate\">\n <div *ngFor=\"let item of valueDetails\" class=\"d-select-value\">\n <ng-container *ngIf=\"!multiple\">{{ item[bindLabel] }}</ng-container>\n <ng-container *ngIf=\"multiple\">\n <div (click)=\"removeItem(item)\">\n <ng-container *ngTemplateOutlet=\"iconClose\"></ng-container>\n </div>\n <span> </span>\n <div doku-typography variant=\"label\">{{ item[bindLabel] }}</div>\n </ng-container>\n </div>\n </ng-container>\n </ng-container>\n\n <input\n #searchInput\n *ngIf=\"searchable && !disabled && !readonly\"\n type=\"text\"\n class=\"d-select-searchable-input\"\n [class.relative]=\"hasValue\"\n [class.opened]=\"isOpen\"\n [value]=\"search$.value\"\n (input)=\"onSearchValueChange($event)\"\n />\n</div>\n\n<div\n *ngIf=\"clearable && hasValue && !disabled\"\n class=\"d-select-clearable\"\n (click)=\"clearValue($event)\"\n>\n <ng-container *ngTemplateOutlet=\"iconClose\"></ng-container>\n</div>\n\n<div class=\"d-select-arrow\" [ngClass]=\"arrowPlacement\">\n <ng-template *ngTemplateOutlet=\"iconArrow\"></ng-template>\n</div>\n\n<ng-template #iconArrow>\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\">\n <path\n d=\"M7.56745 14.4236L4.80999 10.5154C4.48457 10.0556 4.74905 9.33337 5.24293 9.33337H10.7578C10.8684 9.33326 10.9766 9.37265 11.0695 9.44683C11.1625 9.52101 11.2362 9.62684 11.2819 9.75164C11.3276 9.87644 11.3433 10.0149 11.3271 10.1505C11.311 10.2861 11.2636 10.413 11.1908 10.5161L8.43333 14.4229C8.37936 14.4995 8.31281 14.5609 8.23814 14.6029C8.16346 14.645 8.0824 14.6667 8.00039 14.6667C7.91838 14.6667 7.83731 14.645 7.76264 14.6029C7.68797 14.5609 7.62142 14.4995 7.56745 14.4229V14.4236Z\"\n fill=\"currentColor\"\n />\n <path\n d=\"M7.56745 1.57638L4.80999 5.48461C4.48457 5.94444 4.74905 6.66663 5.24293 6.66663H10.7578C10.8684 6.66674 10.9766 6.62735 11.0695 6.55317C11.1625 6.47899 11.2362 6.37316 11.2819 6.24836C11.3276 6.12356 11.3433 5.98508 11.3271 5.84949C11.311 5.71391 11.2636 5.58698 11.1908 5.48389L8.43333 1.5771C8.37936 1.50052 8.31281 1.43915 8.23814 1.3971C8.16346 1.35505 8.0824 1.33329 8.00039 1.33329C7.91838 1.33329 7.83731 1.35505 7.76264 1.3971C7.68797 1.43915 7.62142 1.50052 7.56745 1.5771V1.57638Z\"\n fill=\"currentColor\"\n />\n </svg>\n</ng-template>\n\n<ng-template #iconClose>\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"17\" height=\"16\" viewBox=\"0 0 17 16\" fill=\"none\">\n <path\n fill-rule=\"evenodd\"\n clip-rule=\"evenodd\"\n d=\"M12.2544 4.14598C12.301 4.19242 12.3379 4.2476 12.3631 4.30834C12.3883 4.36909 12.4013 4.43421 12.4013 4.49998C12.4013 4.56575 12.3883 4.63087 12.3631 4.69161C12.3379 4.75236 12.301 4.80753 12.2544 4.85398L5.25441 11.854C5.16053 11.9479 5.03319 12.0006 4.90041 12.0006C4.76764 12.0006 4.6403 11.9479 4.54641 11.854C4.45253 11.7601 4.39978 11.6328 4.39978 11.5C4.39978 11.3672 4.45253 11.2399 4.54641 11.146L11.5464 4.14598C11.5929 4.09941 11.648 4.06247 11.7088 4.03727C11.7695 4.01206 11.8346 3.99908 11.9004 3.99908C11.9662 3.99908 12.0313 4.01206 12.092 4.03727C12.1528 4.06247 12.208 4.09941 12.2544 4.14598Z\"\n fill=\"currentColor\"\n stroke=\"currentColor\"\n />\n <path\n fill-rule=\"evenodd\"\n clip-rule=\"evenodd\"\n d=\"M4.54643 4.14598C4.49987 4.19242 4.46292 4.2476 4.43772 4.30834C4.41251 4.36909 4.39954 4.43421 4.39954 4.49998C4.39954 4.56575 4.41251 4.63087 4.43772 4.69161C4.46292 4.75236 4.49987 4.80753 4.54643 4.85398L11.5464 11.854C11.6403 11.9479 11.7677 12.0006 11.9004 12.0006C12.0332 12.0006 12.1605 11.9479 12.2544 11.854C12.3483 11.7601 12.4011 11.6328 12.4011 11.5C12.4011 11.3672 12.3483 11.2399 12.2544 11.146L5.25443 4.14598C5.20798 4.09941 5.15281 4.06247 5.09206 4.03727C5.03132 4.01206 4.9662 3.99908 4.90043 3.99908C4.83466 3.99908 4.76954 4.01206 4.7088 4.03727C4.64805 4.06247 4.59288 4.09941 4.54643 4.14598Z\"\n fill=\"currentColor\"\n stroke=\"currentColor\"\n />\n </svg>\n</ng-template>\n" }]
}], ctorParameters: function () { return [{ type: i0.EnvironmentInjector }, { type: i0.ApplicationRef }, { type: i0.NgZone }, { type: i0.Injector }, { type: i0.ChangeDetectorRef }, { type: i0.Renderer2 }, { type: Document, decorators: [{
type: Inject,
args: [DOCUMENT]
}] }, { type: i1.NgControl, decorators: [{
type: Optional
}, {
type: Self
}] }, { type: i4.DokuFormField, decorators: [{
type: Optional
}, {
type: Inject,
args: [DokuFormField]
}] }]; }, propDecorators: { items: [{
type: Input
}], bindLabel: [{
type: Input
}], bindValue: [{
type: Input
}], value: [{
type: Input
}], placeholder: [{
type: Input
}], portalClass: [{
type: Input
}], multiple: [{
type: HostBinding,
args: ['class.d-select-multiple']
}, {
type: Input
}], truncateLabel: [{
type: HostBinding,
args: ['class.d-select-truncated-label']
}, {
type: Input
}], arrowPlacement: [{
type: Input
}], disabled: [{
type: Input
}], readonly: [{
type: Input
}], searchable: [{
type: Input
}], isAsync: [{
type: Input
}], searchMatcherFn: [{
type: Input
}], clearable: [{
type: Input
}], valueChange: [{
type: Output
}], search: [{
type: Output
}], labelTemplate: [{
type: ContentChild,
args: [DokuSelectLabelTemplate]
}], optionTemplate: [{
type: ContentChild,
args: [DokuSelectOptionTemplate]
}], noItemTemplate: [{
type: ContentChild,
args: [DokuSelectNoItemTemplate]
}], loadingTemplate: [{
type: ContentChild,
args: [DokuSelectLoadingTemplate]
}], searchInput: [{
type: ViewChild,
args: ['searchInput']
}], classes: [{
type: HostBinding,
args: ['class']
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VsZWN0LmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2Rva3UtZnJhZ21lbnQvc3JjL2xpYi9zZWxlY3Qvc2VsZWN0LmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2Rva3UtZnJhZ21lbnQvc3JjL2xpYi9zZWxlY3Qvc2VsZWN0LmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxZQUFZLEVBQUUsUUFBUSxFQUFXLE1BQU0saUJBQWlCLENBQUM7QUFDbEUsT0FBTyxFQUlMLHVCQUF1QixFQUV2QixTQUFTLEVBRVQsWUFBWSxFQUdaLFlBQVksRUFDWixXQUFXLEVBQ1gsTUFBTSxFQUVOLEtBQUssRUFJTCxRQUFRLEVBQ1IsTUFBTSxFQUVOLElBQUksRUFDSixTQUFTLEVBQ1QsaUJBQWlCLEdBQ2xCLE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sRUFBd0IsV0FBVyxFQUFhLE1BQU0sZ0JBQWdCLENBQUM7QUFDOUUsT0FBTyxFQUNMLGVBQWUsRUFDZixhQUFhLEVBQ2IsT0FBTyxFQUNQLEtBQUssRUFDTCxvQkFBb0IsRUFDcEIsTUFBTSxFQUNOLFNBQVMsRUFDVCxHQUFHLEVBQ0gsSUFBSSxFQUNKLFNBQVMsRUFDVCxTQUFTLEVBQ1QsU0FBUyxFQUNULEdBQUcsR0FDSixNQUFNLE1BQU0sQ0FBQztBQUNkLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQUMxRCxPQUFPLEVBQUUsc0JBQXNCLEVBQUUsTUFBTSxzQ0FBc0MsQ0FBQztBQUM5RSxPQUFPLEVBQ0wsd0JBQXdCLEVBQ3hCLGFBQWEsR0FJZCxNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDckQsT0FBTyxFQUFFLHVCQUF1QixFQUFFLE1BQU0sOENBQThDLENBQUM7QUFD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