@cas-smartdesign/combo-box 7.2.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,130 @@
1
+ import { PropertyValues, TemplateResult } from "lit";
2
+ import SDInput, { CustomEventMap as InputCustomEventMap } from "@cas-smartdesign/lit-input";
3
+ import { ItemGenerator } from "@cas-smartdesign/virtual-list";
4
+ import { ItemData } from "@cas-smartdesign/list-item";
5
+ declare const TAG_NAME = "sd-combo-box";
6
+ declare global {
7
+ interface HTMLElementTagNameMap {
8
+ [TAG_NAME]: ComboBox;
9
+ }
10
+ }
11
+ export type ComboBoxValue = {
12
+ index: number;
13
+ item: ItemData | any;
14
+ };
15
+ export type InMemoryFilter = (filterText: string, item: any) => boolean;
16
+ export type DataResponse = {
17
+ items: any[];
18
+ finalSizeIsKnown: boolean;
19
+ };
20
+ export interface ISelectionEvent {
21
+ selection: ComboBoxValue | string;
22
+ isCustomValue: boolean;
23
+ }
24
+ export interface IFilterChangeEvent {
25
+ value: string;
26
+ }
27
+ export interface CustomEventMap extends InputCustomEventMap {
28
+ "selection-change": CustomEvent<ISelectionEvent>;
29
+ "filter-change": CustomEvent<IFilterChangeEvent>;
30
+ }
31
+ export default interface ComboBox {
32
+ addEventListener<K extends keyof CustomEventMap>(event: K, listener: ((this: this, ev: CustomEventMap[K]) => unknown) | null, options?: AddEventListenerOptions | boolean): void;
33
+ addEventListener(type: string, callback: EventListenerOrEventListenerObject | null, options?: AddEventListenerOptions | boolean): void;
34
+ removeEventListener<K extends keyof CustomEventMap>(type: K, listener: (this: this, ev: CustomEventMap[K]) => unknown, options?: boolean | EventListenerOptions): void;
35
+ removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;
36
+ dispatchEvent<EventType extends CustomEventMap[keyof CustomEventMap]>(event: EventType): boolean;
37
+ }
38
+ export default class ComboBox extends SDInput {
39
+ static readonly ID: string;
40
+ static ensureDefined: () => void;
41
+ static formAssociated: boolean;
42
+ private static readonly DATA_REQUEST_CANCELLED;
43
+ opened: boolean;
44
+ itemHeight: number;
45
+ allowCustomValue: boolean;
46
+ triggerOnly: boolean;
47
+ nullSettingDisallowed: boolean;
48
+ displayValuePath: string;
49
+ filterProperty: string;
50
+ id: string;
51
+ inMemoryFilter: InMemoryFilter;
52
+ filterText: string;
53
+ minimumOverlayWidth: number;
54
+ private _comboBoxValue;
55
+ private _clearButton;
56
+ private _toggleButton;
57
+ private _popper;
58
+ private _list;
59
+ private _dataProvider;
60
+ private _itemGenerator;
61
+ private _itemCache;
62
+ private _declarativeItems;
63
+ private _onDataRequest;
64
+ private _pendingDataRequest;
65
+ private _openedByFilterTextChange;
66
+ private _lastRequestedPage;
67
+ private _lastRequestedFilterText;
68
+ constructor();
69
+ get clearFilterOnLazyLoadedSelection(): boolean;
70
+ /**
71
+ * @deprecated The method should not be used.
72
+ * Use {@link ComboBox#triggerOnly} instead.
73
+ * @param {boolean} value
74
+ */
75
+ set clearFilterOnLazyLoadedSelection(value: boolean);
76
+ get itemGenerator(): ItemGenerator;
77
+ set itemGenerator(value: ItemGenerator);
78
+ get items(): any[];
79
+ set items(items: any[]);
80
+ get finalSizeIsKnown(): boolean;
81
+ set finalSizeIsKnown(value: boolean);
82
+ configureLazyLoad(onDataRequest: (filterText: string, page: number) => Promise<DataResponse>): void;
83
+ get comboBoxValue(): ComboBoxValue | string;
84
+ set comboBoxValue(value: ComboBoxValue | string);
85
+ get selectedIndex(): number;
86
+ get displayValue(): string;
87
+ open(): void;
88
+ static get styles(): import("lit").CSSResult[];
89
+ disconnectedCallback(): void;
90
+ render(): TemplateResult;
91
+ attributeChangedCallback(name: string, oldValue: string, newValue: string): void;
92
+ firstUpdated(changedProperties: PropertyValues): void;
93
+ private updateComboBoxValueFromValue;
94
+ updated(changedProperties: PropertyValues): void;
95
+ private initClearButtton;
96
+ private initToggleButtton;
97
+ private debouncedFilterItemsInMemory;
98
+ private filterItemsInMemory;
99
+ private ensureListAndPopperInitialized;
100
+ private closeIfNotVisible;
101
+ private elementFromMiddleOfComboBox;
102
+ private handleSelection;
103
+ private handleOpenedStateChange;
104
+ private updateValueOnClose;
105
+ private restorePreviousSelection;
106
+ private updateFocusAndSelectedIndexFromValue;
107
+ private handleWindowPointerDown;
108
+ private handleKeyDown;
109
+ private navigateInList;
110
+ private updateActiveDescendant;
111
+ private updateInputValue;
112
+ private convertToDisplayValue;
113
+ protected fireValueChange(immediate?: boolean): void;
114
+ private clearValue;
115
+ private clearFilter;
116
+ private updateDropdownSizes;
117
+ private updateListId;
118
+ private isCustomValue;
119
+ private dispatchSelectionChangeEvent;
120
+ private dispatchFilterChangeEvent;
121
+ private get isLazyLoadConfigured();
122
+ /**
123
+ * Used only when lazy loading is configured.
124
+ */
125
+ private debouncedRequestData;
126
+ private requestData;
127
+ private get defaultSlot();
128
+ private onDefaultSlotChange;
129
+ }
130
+ export {};
@@ -0,0 +1,439 @@
1
+ import { css as g, unsafeCSS as v, html as b } from "lit";
2
+ import { property as r } from "lit/decorators/property.js";
3
+ import { createPopper as x } from "@popperjs/core";
4
+ import _ from "@cas-smartdesign/lit-input";
5
+ import p, { ListDataProvider as y, SelectionType as u } from "@cas-smartdesign/virtual-list";
6
+ import { generator as w } from "@cas-smartdesign/list-item";
7
+ const I = ":host{display:inline-flex;position:relative;cursor:text;font-family:Segoe UI,Lucida Sans,Arial,sans-serif;font-size:16px;color:#111;contain:layout style;flex-direction:column}:host([hidden]),:host([type=hidden]){display:none!important}:host([effective-disabled]){opacity:.6;cursor:default;filter:grayscale(100%)}:host([effective-disabled]) .unfocused-line,:host([effective-disabled]) .focused-line{border-bottom-style:dashed}:host(:not([effective-disabled]):focus) .focused-line,:host(:not([effective-disabled])[focused]) .focused-line{transform:none;transition:transform .25s}:host(:not([effective-disabled]):focus) .label.float,:host(:not([effective-disabled])[focused]) .label.float{color:var(--sd-input-focused-color, #1467ba)}:host([inactive]) .input{pointer-events:none}:host([effective-disabled]:focus),:host([effective-disabled][focused]){box-shadow:0 0 0 1px #111}:host(:not([effective-disabled])[validationlevel]) .focused-line{transform:none;transition:transform .25s}:host([validationlevel=warn i]) .focused-line{border-bottom-color:var(--sd-input-validation-color, #555555)}:host([validationlevel=warn i]) .label,:host([validationlevel=warn i]) .validation-message{color:var(--sd-input-validation-color, #555555)!important}:host([validationlevel=suggest i]) .focused-line{border-bottom-color:var(--sd-input-validation-color, #bf8800)}:host([validationlevel=suggest i]) .label,:host([validationlevel=suggest i]) .validation-message{color:var(--sd-input-validation-color, #bf8800)!important}:host([validationlevel=error i]) .focused-line{border-bottom-color:var(--sd-input-validation-color, #cc0017)}:host([validationlevel=error i]) .label,:host([validationlevel=error i]) .validation-message{color:var(--sd-input-validation-color, #cc0017)!important}:host([validationlevel=warn]) .focused-line{border-bottom-color:var(--sd-input-validation-color, #555555)}:host([validationlevel=warn]) .label,:host([validationlevel=warn]) .validation-message{color:var(--sd-input-validation-color, #555555)!important}:host([validationlevel=suggest]) .focused-line{border-bottom-color:var(--sd-input-validation-color, #bf8800)}:host([validationlevel=suggest]) .label,:host([validationlevel=suggest]) .validation-message{color:var(--sd-input-validation-color, #bf8800)!important}:host([validationlevel=error]) .focused-line{border-bottom-color:var(--sd-input-validation-color, #cc0017)}:host([validationlevel=error]) .label,:host([validationlevel=error]) .validation-message{color:var(--sd-input-validation-color, #cc0017)!important}.validation-message-wrapper{position:relative}.validation-message{position:absolute;left:0;right:0}.label.float{transform:translateY(-75%) scale(.75);width:133%}.label:not(.float){max-width:100%}.floated-label-placeholder{height:20px;width:100%}.label{position:absolute;top:0;left:0;line-height:24px;pointer-events:none;color:var(--sd-input-color, #767676);transition:transform .25s,width .25s;transform-origin:left top}.input-wrapper{position:relative;display:flex;flex-direction:row;align-items:center;background-color:var(--input-wrapper-background-color)}:host([extended-prefix]:focus-within:not([effective-disabled])) .input-wrapper{flex-direction:column;align-items:baseline}:host([extended-prefix]:focus-within:not([effective-disabled])) .input-container{width:100%}:host([extended-prefix]:not(:focus-within)) .input-container,:host([extended-prefix][effective-disabled]) .input-container{width:0px}.input-container{line-height:var(--sd-input-line-height, 24px);flex:1 1 auto}.input{width:100%;background:var(--sd-input-background, transparent);font-family:inherit;font-size:inherit;text-align:inherit;color:inherit;border:none;outline:none;resize:none;padding-left:0;padding-right:0}.input:-webkit-autofill{animation-name:onautofillstart}.input:not(:-webkit-autofill){animation-name:onautofillcancel}@keyframes onautofillstart{0%{outline:none}}@keyframes onautofillcancel{0%{outline:none}}.label,input.input,.validation-message{text-overflow:ellipsis;overflow-x:hidden;white-space:nowrap}.input::-ms-clear{display:none}.input::placeholder{color:var(--sd-input-color, #767676)}.input:-ms-input-placeholder{color:var(--sd-input-color, #767676)}.input::-ms-input-placeholder{color:var(--sd-input-color, #767676)}.underline{height:2px;width:100%;position:relative}.unfocused-line,.focused-line{position:absolute;top:0;right:0;bottom:0;left:0}.unfocused-line{border-bottom:1px solid var(--sd-input-underline-color, #959595)}.focused-line{border-bottom:2px solid var(--sd-input-focused-color, #1467ba);transform-origin:center center;transform:scale3d(0,1,1)}.prefix,.suffix{display:flex;flex-wrap:nowrap}.prefix ::slotted(*),.suffix ::slotted(*){display:flex}:host(:focus){outline:none}.suffix ::slotted(.clear-button),.suffix ::slotted(.toggle-button){cursor:pointer;width:16px;height:32px;padding:0 8px;margin-top:-8px;margin-bottom:-8px;fill:#666;outline:none;flex-shrink:0}.suffix ::slotted(.toggle-button){transition:transform .2s}:host([opened]) .suffix ::slotted(.toggle-button){transform:rotate(180deg)}:host([disabled]) .suffix ::slotted(.clear-button),:host([disabled]) .suffix ::slotted(.toggle-button){display:none!important}:host(:not([has-value])) .suffix ::slotted(.clear-button),:host([null-setting-disallowed]) .suffix ::slotted(.clear-button){display:none!important}:host(:not([allow-custom-value]):not([trigger-only])) .input{caret-color:transparent}:host(:not([allow-custom-value]):not([disabled])) .input{cursor:pointer}#default-slot{display:none}", C = `<svg xmlns="http://www.w3.org/2000/svg" class="toggle-button" slot="suffix" viewBox="0 0 16 16">\r
8
+ <path d="M13 4v2l-5 5-5-5v-2l5 5z"/>\r
9
+ </svg>\r
10
+ `, V = `<svg xmlns="http://www.w3.org/2000/svg" class="clear-button" slot="suffix" viewBox="0 0 16 16">\r
11
+ <path d="M12.96 4.46l-1.42-1.42-3.54 3.55-3.54-3.55-1.42 1.42 3.55 3.54-3.55 3.54 1.42 1.42 3.54-3.55 3.54 3.55 1.42-1.42-3.55-3.54 3.55-3.54z"/>\r
12
+ </svg>\r
13
+ `;
14
+ var B = Object.defineProperty, P = Object.getOwnPropertyDescriptor, d = (h, t, e, i) => {
15
+ for (var s = i > 1 ? void 0 : i ? P(t, e) : t, n = h.length - 1, l; n >= 0; n--)
16
+ (l = h[n]) && (s = (i ? l(t, e, s) : l(s)) || s);
17
+ return i && s && B(t, e, s), s;
18
+ };
19
+ const D = "sd-combo-box";
20
+ function f(h, t) {
21
+ let e;
22
+ return function(...i) {
23
+ e != null && clearTimeout(e), e = window.setTimeout(() => h(...i), t);
24
+ };
25
+ }
26
+ let S = 0;
27
+ var o;
28
+ const a = (o = class extends _ {
29
+ constructor() {
30
+ super(), this.opened = !1, this.itemHeight = 50, this.displayValuePath = "caption", this.id = o.ID + "_" + S++, this.inMemoryFilter = (t, e) => {
31
+ if (!t)
32
+ return !0;
33
+ const i = t.toLowerCase();
34
+ return !!(typeof e.caption == "string" && e.caption.toLowerCase().includes(i) || typeof e.description == "string" && e.description.toLowerCase().includes(i));
35
+ }, this.minimumOverlayWidth = 250, this._itemGenerator = w, this._itemCache = [], this.debouncedFilterItemsInMemory = f(this.filterItemsInMemory.bind(this), 200), this.handleSelection = (t) => {
36
+ const e = this._dataProvider.items[t.detail.index];
37
+ t.detail.selected || (this._list.selectedIndices = [t.detail.index]), this.comboBoxValue = { index: this._itemCache.indexOf(e), item: e }, this.dispatchSelectionChangeEvent(), this.opened = !1;
38
+ }, this.handleWindowPointerDown = (t) => {
39
+ !(t.target instanceof Node && this.contains(t.target)) && this.opened && t.composedPath().indexOf(this._list) === -1 && (this.triggerOnly && (this.value = null), this.opened = !1);
40
+ }, this.handleKeyDown = (t) => {
41
+ switch (t.key) {
42
+ case "Down":
43
+ case "ArrowDown": {
44
+ t.preventDefault(), this.navigateInList(1);
45
+ break;
46
+ }
47
+ case "Up":
48
+ case "ArrowUp": {
49
+ t.preventDefault(), this.navigateInList(-1);
50
+ break;
51
+ }
52
+ case "Enter": {
53
+ this.opened && (t.preventDefault(), t.stopPropagation(), this.opened = !1);
54
+ break;
55
+ }
56
+ case "Escape": {
57
+ this.opened && (t.preventDefault(), t.stopPropagation(), this._list.selectedIndices.indexOf(this._list.focusIndex) > -1 && this._dataProvider.items.length > this._list.focusIndex ? this.opened = !1 : (this.clearFilter(), this.updateInputValue(null), this.updateFocusAndSelectedIndexFromValue(), this._list.selectedIndices.push(this._list.focusIndex)));
58
+ break;
59
+ }
60
+ case "Tab": {
61
+ this.opened && (this.triggerOnly && (this.value = null), this.opened = !1);
62
+ break;
63
+ }
64
+ }
65
+ }, this.debouncedRequestData = f(this.requestData.bind(this), 250), this._dataProvider = new y(), this._dataProvider.finalSizeIsKnown = !0;
66
+ }
67
+ get clearFilterOnLazyLoadedSelection() {
68
+ return this.triggerOnly;
69
+ }
70
+ /**
71
+ * @deprecated The method should not be used.
72
+ * Use {@link ComboBox#triggerOnly} instead.
73
+ * @param {boolean} value
74
+ */
75
+ set clearFilterOnLazyLoadedSelection(t) {
76
+ console.warn(
77
+ "Using clearFilterOnLazyLoadedSelection setting on a combo-box is deprecated. Use triggerOnly instead."
78
+ ), this.triggerOnly = t;
79
+ }
80
+ get itemGenerator() {
81
+ return this._itemGenerator;
82
+ }
83
+ set itemGenerator(t) {
84
+ this._itemGenerator = t, this._list && (this._list.itemGenerator = this._itemGenerator);
85
+ }
86
+ get items() {
87
+ return this._itemCache;
88
+ }
89
+ set items(t) {
90
+ this._itemCache = t, this.value && !this.comboBoxValue && this.updateComboBoxValueFromValue(), this.filterItemsInMemory(), this.opened && this._popper && this._popper.update();
91
+ }
92
+ get finalSizeIsKnown() {
93
+ return this._dataProvider.finalSizeIsKnown;
94
+ }
95
+ set finalSizeIsKnown(t) {
96
+ this._dataProvider.finalSizeIsKnown = t;
97
+ }
98
+ configureLazyLoad(t) {
99
+ if (!t)
100
+ throw new Error("It is not possible to configure lazy load without a given onDataRequest calback.");
101
+ this._dataProvider.finalSizeIsKnown = !1, this._onDataRequest = t, this._dataProvider.onDataRequest = (e) => {
102
+ this.requestData(e, !1);
103
+ };
104
+ }
105
+ get comboBoxValue() {
106
+ return this._comboBoxValue;
107
+ }
108
+ set comboBoxValue(t) {
109
+ this._comboBoxValue = t, this.updateInputValue(null);
110
+ }
111
+ get selectedIndex() {
112
+ return this.isCustomValue(this.comboBoxValue) || !this.comboBoxValue ? -1 : this.comboBoxValue.index;
113
+ }
114
+ get displayValue() {
115
+ return this.value;
116
+ }
117
+ open() {
118
+ this.opened = !0;
119
+ }
120
+ static get styles() {
121
+ return [
122
+ g`
123
+ ${v(I)}
124
+ `
125
+ ];
126
+ }
127
+ disconnectedCallback() {
128
+ super.disconnectedCallback(), this._popper && (this._popper.destroy(), this._popper = null);
129
+ }
130
+ render() {
131
+ return b`
132
+ ${super.render()}
133
+ <slot @slotchange=${this.onDefaultSlotChange} id="default-slot"></slot>
134
+ `;
135
+ }
136
+ attributeChangedCallback(t, e, i) {
137
+ if (super.attributeChangedCallback(t, e, i), e !== i)
138
+ switch (t) {
139
+ case "opened": {
140
+ this.handleOpenedStateChange();
141
+ break;
142
+ }
143
+ case "item-height": {
144
+ this._list && (this._list.itemHeight = this.itemHeight);
145
+ break;
146
+ }
147
+ case "id": {
148
+ this.updateListId();
149
+ break;
150
+ }
151
+ }
152
+ }
153
+ firstUpdated(t) {
154
+ super.firstUpdated(t), this.value && !this.comboBoxValue && this.updateComboBoxValueFromValue(), window.requestAnimationFrame(() => {
155
+ this.initClearButtton(), this.initToggleButtton(), this.addEventListener("click", () => {
156
+ this.disabled || (this.opened = !this.opened);
157
+ }), this.addEventListener("keydown", (e) => {
158
+ this.disabled || this.handleKeyDown(e);
159
+ });
160
+ }), this.inputElement.setAttribute("role", "combobox"), this.inputElement.setAttribute("aria-autocomplete", "list");
161
+ }
162
+ updateComboBoxValueFromValue() {
163
+ if (this.value) {
164
+ const t = this._itemCache.findIndex((e) => e[this.displayValuePath] === this.value);
165
+ t > -1 ? this._comboBoxValue = { index: t, item: this._itemCache[t] } : this.allowCustomValue ? this._comboBoxValue = this.value : this._comboBoxValue = null;
166
+ }
167
+ }
168
+ updated(t) {
169
+ super.updated(t), t.has("currentText") ? this.currentText ? (this.setAttribute("has-value", ""), this._clearButton && (this._clearButton.style.display = "")) : this.removeAttribute("has-value") : t.has("triggerOnly") && this._list && (this._list.selectionType = this.triggerOnly ? u.TriggerOnly : u.Single);
170
+ }
171
+ initClearButtton() {
172
+ const t = document.createElement("template");
173
+ t.innerHTML = V, this._clearButton = t.content.firstChild, this.appendChild(this._clearButton), this._clearButton.addEventListener("click", (e) => {
174
+ e.preventDefault(), e.stopPropagation(), this.opened = !1, this.clearValue();
175
+ });
176
+ }
177
+ initToggleButtton() {
178
+ const t = document.createElement("template");
179
+ t.innerHTML = C, this._toggleButton = t.content.firstChild, this.appendChild(this._toggleButton), this._toggleButton.addEventListener("click", (e) => {
180
+ e.preventDefault(), e.stopPropagation(), this.opened = !this.opened, this.select();
181
+ });
182
+ }
183
+ filterItemsInMemory() {
184
+ if (this.isLazyLoadConfigured)
185
+ return;
186
+ let t = !1;
187
+ this.filterText && (this.filterProperty ? (this._dataProvider.items = this._itemCache.filter((e) => e[this.filterProperty] && String(e[this.filterProperty]).indexOf(this.filterText) > -1), t = !0) : this.inMemoryFilter && (this._dataProvider.items = this._itemCache.filter((e) => this.inMemoryFilter(this.filterText, e)), t = !0)), t ? this._list.focusIndex = null : this._dataProvider.items = this._itemCache, this.opened && this._popper && this._popper.update();
188
+ }
189
+ ensureListAndPopperInitialized() {
190
+ if (this._list || (this._list = document.createElement(p.ID), this.updateListId(), this._list.classList.add("combo-box-dropdown"), this._list.itemHeight = this.itemHeight, this._list.itemGenerator = this.itemGenerator, this._list.selectionType = this.triggerOnly ? u.TriggerOnly : u.Single, this._list.setAttribute("focus-target", ""), Object.assign(this._list.style, {
191
+ zIndex: "21000",
192
+ boxShadow: `rgba(0, 0, 0, 0.14) 0px 2px 2px 0px,
193
+ rgba(0, 0, 0, 0.12) 0px 1px 5px 0px,
194
+ rgba(0, 0, 0, 0.2) 0px 3px 1px -2px`,
195
+ background: "white",
196
+ overflowY: "auto"
197
+ }), this._list.addEventListener("selection", this.handleSelection), this._dataProvider.connectList(this._list)), !this._popper) {
198
+ const t = this;
199
+ this._popper = x(this, this._list, {
200
+ placement: "bottom-start",
201
+ modifiers: [
202
+ {
203
+ name: "computeStyles",
204
+ options: {
205
+ gpuAcceleration: !0
206
+ }
207
+ },
208
+ {
209
+ name: "hide",
210
+ enabled: !1
211
+ },
212
+ {
213
+ name: "closeIfReferenceHidden",
214
+ enabled: !0,
215
+ phase: "afterWrite",
216
+ fn({ state: e }) {
217
+ e.elements.reference.closeIfNotVisible();
218
+ }
219
+ },
220
+ {
221
+ name: "offset",
222
+ options: {
223
+ offset: ({ placement: e }) => e.indexOf("top") > -1 ? [0, -parseInt(getComputedStyle(t).paddingTop, 10)] : e.indexOf("bottom") > -1 ? [0, -parseInt(getComputedStyle(t).paddingBottom, 10)] : [0, 0]
224
+ }
225
+ },
226
+ {
227
+ name: "adjustWidthIfNeeded",
228
+ enabled: !0,
229
+ phase: "read",
230
+ fn({ state: e }) {
231
+ e.elements.popper.increaseWidthOnNextRenderIfNeeded();
232
+ }
233
+ }
234
+ ]
235
+ });
236
+ }
237
+ }
238
+ closeIfNotVisible() {
239
+ const t = this.elementFromMiddleOfComboBox();
240
+ !this.contains(t) && !this.shadowRoot.contains(t) && t !== this._list && (this.triggerOnly && (this.value = null), this.opened = !1);
241
+ }
242
+ elementFromMiddleOfComboBox() {
243
+ const t = this.getBoundingClientRect();
244
+ return document.elementFromPoint(t.left + t.width / 2, t.top + t.height / 2);
245
+ }
246
+ async handleOpenedStateChange() {
247
+ this.inputElement.setAttribute("aria-expanded", String(this.opened)), this.opened ? (this.disabled || (this.ensureListAndPopperInitialized(), this.isLazyLoadConfigured && (this.items.length == 0 || this._lastRequestedFilterText != this.filterText) && this.requestData(0, this._lastRequestedFilterText != this.filterText), this.updateDropdownSizes(), this.ownerDocument.body.appendChild(this._list), this.updateFocusAndSelectedIndexFromValue(), window.requestAnimationFrame(() => {
248
+ this._popper && this._popper.update();
249
+ }), window.addEventListener("pointerdown", this.handleWindowPointerDown), !this.allowCustomValue && !this._openedByFilterTextChange && this.select()), this._openedByFilterTextChange = !1) : (await this._list.updateComplete, this._popper && await this._popper.update, this.ownerDocument.body.removeChild(this._list), window.removeEventListener("pointerdown", this.handleWindowPointerDown), this.updateValueOnClose(), this.clearFilter(), this.setSelectionRange(0, 0), this.inputElement.removeAttribute("aria-activedescendant"), this._popper && (this._popper.destroy(), this._popper = null));
250
+ }
251
+ updateValueOnClose() {
252
+ const t = this.comboBoxValue || "";
253
+ if (this.nullSettingDisallowed && !this.value && this.comboBoxValue)
254
+ this.restorePreviousSelection();
255
+ else if (this.value !== this.convertToDisplayValue(null)) {
256
+ const e = this._dataProvider.items[this._list.focusIndex];
257
+ if (e && e[this.displayValuePath] === this.value) {
258
+ if (e.disabled)
259
+ return;
260
+ this.comboBoxValue = { index: this._itemCache.indexOf(e), item: e };
261
+ } else if (this.allowCustomValue || !this.value)
262
+ this.comboBoxValue = this.value;
263
+ else {
264
+ const i = this._itemCache.findIndex(
265
+ (s) => s[this.displayValuePath] === this.value && !s.disabled
266
+ );
267
+ i > -1 ? this.comboBoxValue = { index: i, item: this._itemCache[i] } : this.restorePreviousSelection();
268
+ }
269
+ }
270
+ t !== (this.comboBoxValue || "") && this.dispatchSelectionChangeEvent();
271
+ }
272
+ restorePreviousSelection() {
273
+ this.updateInputValue(null);
274
+ }
275
+ updateFocusAndSelectedIndexFromValue() {
276
+ if (this.comboBoxValue && !this.isCustomValue(this.comboBoxValue) && !this._openedByFilterTextChange) {
277
+ let t = this.comboBoxValue.index;
278
+ if ((t == -1 || this.isLazyLoadConfigured) && (t = this.items.indexOf(this.comboBoxValue.item), t == -1)) {
279
+ const e = this.comboBoxValue.item.id;
280
+ e != null && (t = this.items.findIndex((i) => i.id == e));
281
+ }
282
+ this._list.focusIndex = t, this._list.selectedIndices = t == -1 ? [] : [t];
283
+ } else
284
+ this._list.focusIndex = -1, this._list.selectedIndices = [];
285
+ this.updateActiveDescendant();
286
+ }
287
+ navigateInList(t) {
288
+ this.opened ? (this._list.focusIndex == null ? t > 0 ? this._list.focusIndex = 0 : this._list.focusIndex = Math.max(0, this._dataProvider.items.length - 1) : this._list.focusIndex = Math.max(
289
+ 0,
290
+ Math.min(this._dataProvider.items.length - 1, this._list.focusIndex + t)
291
+ ), this.updateInputValue(this._dataProvider.items[this._list.focusIndex]), this.updateActiveDescendant(), this.allowCustomValue || this.select()) : this.opened = !0;
292
+ }
293
+ updateActiveDescendant() {
294
+ const t = this._list && this._list.getListItem(this._list.focusIndex);
295
+ t ? this.inputElement.setAttribute("aria-activedescendant", t.id) : this.inputElement.removeAttribute("aria-activedescendant");
296
+ }
297
+ updateInputValue(t) {
298
+ this.updateComplete.then(() => {
299
+ this.value = this.convertToDisplayValue(t);
300
+ });
301
+ }
302
+ convertToDisplayValue(t) {
303
+ return t ? t[this.displayValuePath] : this.comboBoxValue ? this.isCustomValue(this.comboBoxValue) ? this.comboBoxValue : this.comboBoxValue.item[this.displayValuePath] : null;
304
+ }
305
+ fireValueChange(t) {
306
+ t && this.filterText !== this.value && (this.filterText = this.value, this.opened || (this._openedByFilterTextChange = !0, this.opened = !0), this.dispatchFilterChangeEvent(), this.debouncedFilterItemsInMemory());
307
+ }
308
+ clearValue() {
309
+ this.nullSettingDisallowed || (this.value = null, this.inputElement.removeAttribute("aria-activedescendant"), this._list && (this._list.selectedIndices = []), this.clearFilter(), this.comboBoxValue && (this.comboBoxValue = null, this.dispatchSelectionChangeEvent()));
310
+ }
311
+ clearFilter() {
312
+ this.filterText != null && (this.filterText = void 0, this.filterItemsInMemory(), this.dispatchFilterChangeEvent());
313
+ }
314
+ updateDropdownSizes() {
315
+ const e = ((window.innerHeight || document.documentElement.clientHeight) - this.offsetHeight) * 0.5;
316
+ Object.assign(this._list.style, {
317
+ maxHeight: `${e}px`,
318
+ minWidth: `${Math.max(this.offsetWidth, this.minimumOverlayWidth)}px`,
319
+ maxWidth: `max(50vw, ${this.offsetWidth}px)`
320
+ });
321
+ }
322
+ updateListId() {
323
+ this.inputElement && this._list && (this._list.id = this.id + "_list", this.inputElement.setAttribute("aria-controls", this._list.id));
324
+ }
325
+ isCustomValue(t) {
326
+ return typeof t == "string";
327
+ }
328
+ dispatchSelectionChangeEvent() {
329
+ this.updateComplete.then(() => {
330
+ var t;
331
+ if (this.dispatchEvent(
332
+ new CustomEvent("selection-change", {
333
+ detail: {
334
+ selection: this.comboBoxValue,
335
+ isCustomValue: this.isCustomValue(this.comboBoxValue)
336
+ }
337
+ })
338
+ ), this.triggerOnly)
339
+ this.comboBoxValue = null;
340
+ else {
341
+ const e = this.comboBoxValue;
342
+ typeof e == "string" ? this.setFormValue(e) : this.setFormValue((t = e == null ? void 0 : e.item) == null ? void 0 : t.caption);
343
+ }
344
+ }).catch((t) => {
345
+ console.error("Could not dispatch selection change event due to:", t);
346
+ });
347
+ }
348
+ dispatchFilterChangeEvent() {
349
+ this.dispatchEvent(
350
+ new CustomEvent("filter-change", {
351
+ detail: { value: this.filterText },
352
+ composed: !0
353
+ })
354
+ ), this.debouncedRequestData(0, !0);
355
+ }
356
+ get isLazyLoadConfigured() {
357
+ return !!this._onDataRequest;
358
+ }
359
+ requestData(t, e) {
360
+ if (this.isLazyLoadConfigured) {
361
+ if (!this.opened) {
362
+ e && (this._dataProvider.items = [], this._itemCache = []);
363
+ return;
364
+ }
365
+ if (this._lastRequestedPage == t && this._lastRequestedFilterText == this.filterText)
366
+ return;
367
+ this._pendingDataRequest && this._pendingDataRequest.cancel(o.DATA_REQUEST_CANCELLED);
368
+ const i = new Promise((s, n) => {
369
+ this._pendingDataRequest = { cancel: n };
370
+ });
371
+ this._lastRequestedPage = t, this._lastRequestedFilterText = this.filterText, this.setAttribute("loading", ""), Promise.race([i, this._onDataRequest(this._lastRequestedFilterText, t)]).then((s) => {
372
+ if (this.filterText == this._lastRequestedFilterText && this._lastRequestedPage == t && (this._dataProvider.finalSizeIsKnown = s.finalSizeIsKnown, e ? (this._dataProvider.items = s.items, this._itemCache = s.items) : (this._dataProvider.addItems(s.items), this._itemCache = this._dataProvider.items), this._list && (this._list.itemCount = this._dataProvider.items.length), this._popper && this.opened)) {
373
+ if (this.comboBoxValue && !this.isCustomValue(this.comboBoxValue)) {
374
+ const n = this.comboBoxValue.item;
375
+ if (this._list.selectedIndices.length == 0 || this.items[this._list.selectedIndices[0]] != n) {
376
+ let l = this.items.indexOf(n);
377
+ if (l == -1) {
378
+ const c = n.id;
379
+ c != null && (l = this.items.findIndex((m) => m.id == c));
380
+ }
381
+ this.comboBoxValue.index = l, this._list.selectedIndices = l == -1 ? [] : [l];
382
+ }
383
+ }
384
+ this.updateDropdownSizes(), this._popper.update();
385
+ }
386
+ this._pendingDataRequest = null, this.removeAttribute("loading");
387
+ }).catch((s) => {
388
+ s !== o.DATA_REQUEST_CANCELLED && (console.error(
389
+ `Data could not be loaded for filter "${this._lastRequestedFilterText}" and page number "${t}" due to the following error:
390
+ ${s}`
391
+ ), this._dataProvider.finalSizeIsKnown = !0, this.items.length == 0 ? this.opened = !1 : this._list && (this._list.itemCount = this.items.length), this.removeAttribute("loading")), this._pendingDataRequest = null;
392
+ });
393
+ }
394
+ }
395
+ get defaultSlot() {
396
+ return this.shadowRoot.querySelector("#default-slot");
397
+ }
398
+ onDefaultSlotChange() {
399
+ this._declarativeItems = this.defaultSlot.assignedElements(), this._declarativeItems.length > 0 && (this.finalSizeIsKnown = !0, this.itemGenerator = (t, e) => this._declarativeItems[e].cloneNode(!0), this.items = this._declarativeItems.map((t) => {
400
+ const e = {
401
+ caption: t.getAttribute("caption"),
402
+ description: t.getAttribute("description")
403
+ };
404
+ return this.displayValuePath != "caption" && this.displayValuePath != "description" && (e[this.displayValuePath] = t[this.displayValuePath] || t.getAttribute(this.displayValuePath)), e;
405
+ }));
406
+ }
407
+ }, o.ID = D, o.ensureDefined = () => {
408
+ p.ensureDefined(), customElements.get(o.ID) || customElements.define(o.ID, o);
409
+ }, o.formAssociated = !0, o.DATA_REQUEST_CANCELLED = "cancel_data_request", o);
410
+ d([
411
+ r({ type: Boolean, reflect: !0 })
412
+ ], a.prototype, "opened", 2);
413
+ d([
414
+ r({ type: Number, attribute: "item-height" })
415
+ ], a.prototype, "itemHeight", 2);
416
+ d([
417
+ r({ type: Boolean, attribute: "allow-custom-value", reflect: !0 })
418
+ ], a.prototype, "allowCustomValue", 2);
419
+ d([
420
+ r({ type: Boolean, attribute: "trigger-only", reflect: !0 })
421
+ ], a.prototype, "triggerOnly", 2);
422
+ d([
423
+ r({ type: Boolean, attribute: "null-setting-disallowed", reflect: !0 })
424
+ ], a.prototype, "nullSettingDisallowed", 2);
425
+ d([
426
+ r({ type: String, attribute: "display-value-path", noAccessor: !0 })
427
+ ], a.prototype, "displayValuePath", 2);
428
+ d([
429
+ r({ type: String, attribute: "filter-property", noAccessor: !0 })
430
+ ], a.prototype, "filterProperty", 2);
431
+ d([
432
+ r({ type: String, attribute: !0, reflect: !0 })
433
+ ], a.prototype, "id", 2);
434
+ let L = a;
435
+ L.ensureDefined();
436
+ export {
437
+ L as default
438
+ };
439
+ //# sourceMappingURL=combo-box.mjs.map