@fluid-topics/ftds-combobox 2.0.37

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.
Files changed (33) hide show
  1. package/build/BaseComboboxSuggestionProvider.d.ts +2 -0
  2. package/build/BaseComboboxSuggestionProvider.js +22 -0
  3. package/build/FtdsBaseComboboxMessages.d.ts +10 -0
  4. package/build/FtdsBaseComboboxMessages.js +9 -0
  5. package/build/FtdsComboboxMultiValueMessages.d.ts +10 -0
  6. package/build/FtdsComboboxMultiValueMessages.js +11 -0
  7. package/build/define.d.ts +1 -0
  8. package/build/define.js +3 -0
  9. package/build/definitions.d.ts +7 -0
  10. package/build/definitions.js +6 -0
  11. package/build/ftds-base-combobox.d.ts +71 -0
  12. package/build/ftds-base-combobox.js +540 -0
  13. package/build/ftds-base-combobox.properties.d.ts +39 -0
  14. package/build/ftds-base-combobox.properties.js +14 -0
  15. package/build/ftds-base-combobox.styles.d.ts +1 -0
  16. package/build/ftds-base-combobox.styles.js +111 -0
  17. package/build/ftds-combobox-multi-value.d.ts +30 -0
  18. package/build/ftds-combobox-multi-value.js +218 -0
  19. package/build/ftds-combobox-multi-value.properties.d.ts +14 -0
  20. package/build/ftds-combobox-multi-value.properties.js +5 -0
  21. package/build/ftds-combobox-multi-value.styles.d.ts +1 -0
  22. package/build/ftds-combobox-multi-value.styles.js +58 -0
  23. package/build/ftds-combobox.d.ts +21 -0
  24. package/build/ftds-combobox.js +96 -0
  25. package/build/ftds-combobox.light.js +3486 -0
  26. package/build/ftds-combobox.min.js +3607 -0
  27. package/build/ftds-combobox.properties.d.ts +8 -0
  28. package/build/ftds-combobox.properties.js +5 -0
  29. package/build/ftds-combobox.styles.d.ts +1 -0
  30. package/build/ftds-combobox.styles.js +36 -0
  31. package/build/index.d.ts +11 -0
  32. package/build/index.js +11 -0
  33. package/package.json +36 -0
@@ -0,0 +1,111 @@
1
+ import { css } from "lit";
2
+ import { combobox, floatingMenu, } from "@fluid-topics/design-system-variables";
3
+ import { foundation } from "@fluid-topics/ft-wc-utils";
4
+ import { FtdsBaseInputCssVariables } from "@fluid-topics/ft-base-input";
5
+ // language=css
6
+ export const baseComboboxStyles = css `
7
+ :host {
8
+ display: block;
9
+ position: relative;
10
+ width: 100%;
11
+ }
12
+
13
+ input {
14
+ background-color: transparent;
15
+ outline: none;
16
+ border: none;
17
+ width: 100%;
18
+ cursor: text;
19
+ text-overflow: ellipsis;
20
+ }
21
+
22
+ .listbox {
23
+ position: absolute;
24
+ left: 0;
25
+ right: 0;
26
+ margin: ${combobox.menuVerticalGap} 0 0;
27
+ padding: 0;
28
+ list-style: none;
29
+ z-index: 100;
30
+ box-shadow: ${floatingMenu.shadow};
31
+ max-height: 240px;
32
+ overflow-y: auto;
33
+ overflow-x: hidden;
34
+ background-color: ${floatingMenu.backgroundColor};
35
+ }
36
+
37
+ .listbox.ftds--size-large {
38
+ top: ${FtdsBaseInputCssVariables.largeFieldHeight};
39
+ }
40
+
41
+ .listbox.ftds--size-medium {
42
+ top: ${FtdsBaseInputCssVariables.mediumFieldHeight};
43
+ }
44
+
45
+ .listbox[hidden] {
46
+ display: none;
47
+ }
48
+
49
+ .listbox-option {
50
+ display: flex;
51
+ align-items: center;
52
+ padding: ${floatingMenu.verticalPadding} ${floatingMenu.horizontalPadding};
53
+ min-height: ${floatingMenu.height};
54
+ box-sizing: border-box;
55
+ cursor: pointer;
56
+ gap: ${floatingMenu.gap};
57
+ }
58
+
59
+ .listbox-option--label {
60
+ word-break: break-word;
61
+ }
62
+
63
+ .listbox-option[aria-disabled="true"] {
64
+ opacity: ${floatingMenu.disabledComponentOpacity};
65
+ }
66
+
67
+ .listbox-option--new-value {
68
+ display: flex;
69
+ flex-direction: column;
70
+ align-items: flex-start;
71
+ gap: 0;
72
+ }
73
+
74
+ .listbox-option--new-value .listbox-option--label {
75
+ display: flex;
76
+ align-items: center;
77
+ }
78
+
79
+ .listbox-option--new-value:not(:first-child) {
80
+ border-top: ${combobox.menuNewValueBorderWidth} solid ${combobox.menuNewValueBorderColor};
81
+ }
82
+
83
+ .listbox-option--new-value.listbox-option--new-value--error {
84
+ background-color: ${combobox.menuNewValueErrorBackgroundColor};
85
+ }
86
+
87
+ .listbox-option--new-value.listbox-option--new-value--error:hover {
88
+ background-color: color-mix(in srgb, ${combobox.menuNewValueErrorStateLayerColor} calc(${combobox.menuNewValueErrorHoverStateLayerOpacity} * 100%), transparent);
89
+ }
90
+
91
+ .listbox-option--new-value.listbox-option--new-value--error[data-active="true"] {
92
+ background-color: color-mix(in srgb, ${combobox.menuNewValueErrorStateLayerColor} calc(${combobox.menuNewValueErrorActiveStateLayerOpacity} * 100%), transparent);
93
+ }
94
+
95
+ .listbox-option--new-value--error:not(:first-child) {
96
+ border-color: ${combobox.menuNewValueErrorBorderColor};
97
+ }
98
+
99
+ .listbox-option--helper {
100
+ margin-bottom: ${foundation.spacing1};
101
+ color: ${combobox.menuNewValueLabelColor};
102
+ }
103
+
104
+ .listbox-option--message--no-option,
105
+ .listbox-option--message--max {
106
+ display: flex;
107
+ flex-direction: column;
108
+ color: ${combobox.menuMessageLabelColor};
109
+ padding: ${combobox.menuMessagePaddingTop} ${combobox.menuMessageHorizontalPadding} ${combobox.menuMessagePaddingBottom};
110
+ }
111
+ `;
@@ -0,0 +1,30 @@
1
+ import { TemplateResult } from "lit";
2
+ import { ElementDefinitionsMap } from "@fluid-topics/ft-wc-utils";
3
+ import { ActionableListboxItem, ListboxItem, SuggestionListboxItem } from "./ftds-base-combobox.properties";
4
+ import { ComboboxValue, FtdsComboboxMultiValueProperties } from "./ftds-combobox-multi-value.properties";
5
+ import { FtdsBaseCombobox } from "./ftds-base-combobox";
6
+ export declare class FtdsComboboxMultiValue extends FtdsBaseCombobox<ComboboxValue[]> implements FtdsComboboxMultiValueProperties {
7
+ static elementDefinitions: ElementDefinitionsMap;
8
+ static styles: import("lit").CSSResult[];
9
+ canSelectAll: boolean;
10
+ maxNumberOfChips: number;
11
+ constructor();
12
+ handleBlurStrategy(): void;
13
+ computeListboxItems(): Promise<void>;
14
+ commitSelection(suggestion: ActionableListboxItem): void;
15
+ commitTypedText(): void;
16
+ resetCombobox(): void;
17
+ private resetInputValue;
18
+ isSuggestionSelected(value: string): boolean;
19
+ private notifySelectionChange;
20
+ private toggleSelectAll;
21
+ renderListboxItem(listboxItem: ListboxItem, index: number): TemplateResult | typeof import("lit-html").nothing;
22
+ private renderSelectAll;
23
+ private isValueSelected;
24
+ private areAllSuggestionsChecked;
25
+ private areAllSuggestionsUnchecked;
26
+ render(): TemplateResult;
27
+ renderSuggestionItem(suggestion: SuggestionListboxItem, isSelected: boolean): TemplateResult;
28
+ protected renderChips(): TemplateResult;
29
+ private removeChipValueFromSelection;
30
+ }
@@ -0,0 +1,218 @@
1
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ };
7
+ import { html, } from "lit";
8
+ import { property } from "lit/decorators.js";
9
+ import { classMap } from "lit/directives/class-map.js";
10
+ import { numberProperty, processValidationRules, screenReaderStyles, } from "@fluid-topics/ft-wc-utils";
11
+ import { FtdsIcon } from "@fluid-topics/ft-icon";
12
+ import { ListboxItemType, } from "./ftds-base-combobox.properties";
13
+ import { FtdsComboboxMultiValueChangeEvent, } from "./ftds-combobox-multi-value.properties";
14
+ import { comboboxMultiValueStyles } from "./ftds-combobox-multi-value.styles";
15
+ import { FtdsTypographyVariants } from "@fluid-topics/ft-typography";
16
+ import { FtdsChipGroup, } from "@fluid-topics/ft-chip-group";
17
+ import { comboboxMultiValueContext, defaultComboboxMultiValueMessages, } from "./FtdsComboboxMultiValueMessages";
18
+ import { FtdsBaseCombobox } from "./ftds-base-combobox";
19
+ import { baseComboboxStyles } from "./ftds-base-combobox.styles";
20
+ export class FtdsComboboxMultiValue extends FtdsBaseCombobox {
21
+ constructor() {
22
+ var _a;
23
+ super();
24
+ this.canSelectAll = false;
25
+ this.maxNumberOfChips = 10;
26
+ this.value = (_a = this.value) !== null && _a !== void 0 ? _a : [];
27
+ this.addI18nContext(comboboxMultiValueContext, defaultComboboxMultiValueMessages);
28
+ }
29
+ handleBlurStrategy() {
30
+ this.resetCombobox();
31
+ }
32
+ async computeListboxItems() {
33
+ await super.computeListboxItems();
34
+ const showSelectAll = this.canSelectAll && this.filteredSuggestionsWithLimit.length > 0;
35
+ if (showSelectAll) {
36
+ this.listboxItems = [
37
+ { type: ListboxItemType.all },
38
+ ...this.listboxItems,
39
+ ];
40
+ }
41
+ }
42
+ commitSelection(suggestion) {
43
+ if (suggestion.type === ListboxItemType.all) {
44
+ this.toggleSelectAll();
45
+ return;
46
+ }
47
+ if (suggestion.type === ListboxItemType.newValue && processValidationRules(suggestion.value, this.newValueValidationRules).length > 0) {
48
+ return;
49
+ }
50
+ const shouldBeAdded = !this.value.some((selectedValue) => selectedValue.value === suggestion.value);
51
+ if (shouldBeAdded) {
52
+ this.value = [
53
+ ...this.value,
54
+ { value: suggestion.value, label: suggestion.label },
55
+ ];
56
+ }
57
+ else {
58
+ this.value = this.value.filter((valueInSelection) => valueInSelection.value !== suggestion.value);
59
+ }
60
+ this.closeMenu();
61
+ this.resetInputValue();
62
+ this.notifySelectionChange([suggestion.label], shouldBeAdded);
63
+ }
64
+ commitTypedText() {
65
+ // We never commit input on blur for multi-value
66
+ this.resetInputValue();
67
+ }
68
+ resetCombobox() {
69
+ this.resetInputValue();
70
+ }
71
+ resetInputValue() {
72
+ if (this.input) {
73
+ this.input.value = "";
74
+ }
75
+ this.inputValue = "";
76
+ }
77
+ isSuggestionSelected(value) {
78
+ return this.value.some((selectedSuggestion) => selectedSuggestion.value === value);
79
+ }
80
+ notifySelectionChange(suggestionsLabels, isAdded) {
81
+ this.dispatchEvent(new FtdsComboboxMultiValueChangeEvent(this.value));
82
+ this.ariaDescribedBy = comboboxMultiValueContext.messages.numberOfSelectedValuesAriaLabel(this.value.length);
83
+ const concatenatedSuggestions = suggestionsLabels.join();
84
+ const message = isAdded
85
+ ? comboboxMultiValueContext.messages.valueAdded(concatenatedSuggestions)
86
+ : comboboxMultiValueContext.messages.valueRemoved(concatenatedSuggestions);
87
+ // Delay so VoiceOver finishes announcing the menu collapse before reading this message
88
+ setTimeout(() => {
89
+ this.ariaLiveMessage = message;
90
+ }, 800);
91
+ }
92
+ toggleSelectAll() {
93
+ const currentSuggestions = this.listboxItems
94
+ .filter((item) => item.type === ListboxItemType.suggestion)
95
+ .map((item) => ({
96
+ value: item.value,
97
+ label: item.label,
98
+ }));
99
+ const areAllSuggestionsChecked = this.areAllSuggestionsChecked();
100
+ let diff;
101
+ if (areAllSuggestionsChecked) {
102
+ diff = this.value.filter((selectedValue) => currentSuggestions.some((s) => selectedValue.value === s.value));
103
+ this.value = this.value.filter((selectedValue) => !currentSuggestions.some((s) => selectedValue.value === s.value));
104
+ }
105
+ else {
106
+ diff = currentSuggestions.filter((s) => !this.value.some((selectedValue) => selectedValue.value === s.value));
107
+ this.value = this.value.concat(diff);
108
+ }
109
+ this.closeMenu();
110
+ this.resetInputValue();
111
+ this.notifySelectionChange(diff.map((value) => value.label), !areAllSuggestionsChecked);
112
+ }
113
+ renderListboxItem(listboxItem, index) {
114
+ if (listboxItem.type === ListboxItemType.all) {
115
+ return this.renderSelectAll(index);
116
+ }
117
+ return super.renderListboxItem(listboxItem, index);
118
+ }
119
+ renderSelectAll(index) {
120
+ const areAllSuggestionsUnchecked = this.areAllSuggestionsUnchecked();
121
+ const areAllSuggestionsChecked = this.areAllSuggestionsChecked();
122
+ const shouldBeIntermediate = !areAllSuggestionsUnchecked && !areAllSuggestionsChecked;
123
+ let icon = "square";
124
+ if (shouldBeIntermediate) {
125
+ icon = "square-minus";
126
+ }
127
+ if (areAllSuggestionsChecked) {
128
+ icon = "square-check";
129
+ }
130
+ const checkboxClasses = {
131
+ "listbox-option--checkbox": true,
132
+ "checked": areAllSuggestionsChecked,
133
+ "intermediate": shouldBeIntermediate,
134
+ "unchecked": areAllSuggestionsUnchecked,
135
+ };
136
+ const isActive = this.activeIndex === index;
137
+ return html `
138
+ <li class="listbox-option--select-all listbox-option"
139
+ id="${this.suggestionId(index)}"
140
+ role="option"
141
+ aria-selected="${areAllSuggestionsChecked}"
142
+ data-active="${isActive}"
143
+ @mousedown=${(e) => e.preventDefault()}
144
+ @click=${() => this.toggleSelectAll()}
145
+ >
146
+ <ftds-icon class="${classMap(checkboxClasses)}" icon="${icon}"></ftds-icon>
147
+ <ftds-typography variant="${FtdsTypographyVariants.body2medium}" class="listbox-option--label">
148
+ ${comboboxMultiValueContext.messages.selectAll()}
149
+ </ftds-typography>
150
+ </li>
151
+ `;
152
+ }
153
+ isValueSelected(value) {
154
+ return this.value.some((v) => v.value === value);
155
+ }
156
+ areAllSuggestionsChecked() {
157
+ if (this.filteredSuggestionsWithLimit.length === 0) {
158
+ return false;
159
+ }
160
+ return this.filteredSuggestionsWithLimit.every((suggestion) => this.isValueSelected(suggestion.value));
161
+ }
162
+ areAllSuggestionsUnchecked() {
163
+ return this.filteredSuggestionsWithLimit.every((suggestion) => !this.isValueSelected(suggestion.value));
164
+ }
165
+ render() {
166
+ return html `
167
+ ${this.renderField()}
168
+ ${this.renderListboxContainer(true)}
169
+ ${this.renderChips()}
170
+ `;
171
+ }
172
+ renderSuggestionItem(suggestion, isSelected) {
173
+ return html `
174
+ <ftds-icon class="listbox-option--checkbox" icon="${isSelected ? "square-check" : "square"}"></ftds-icon>
175
+ <ftds-typography variant="${FtdsTypographyVariants.body2medium}" class="listbox-option--label">
176
+ ${suggestion.label}
177
+ </ftds-typography>
178
+ `;
179
+ }
180
+ renderChips() {
181
+ const chipsList = this.value.map((value) => ({
182
+ value: value.value,
183
+ label: value.label,
184
+ family: value.status,
185
+ removeLabel: comboboxMultiValueContext.messages.removeValueLabel(value.label),
186
+ }));
187
+ return html `
188
+ <ftds-chip-group
189
+ .chips=${chipsList}
190
+ @remove-chip=${(e) => this.removeChipValueFromSelection(e.detail.value)}
191
+ ?removable=${!this.disabled}
192
+ .maxNumberOfChips=${this.maxNumberOfChips}
193
+ ></ftds-chip-group>
194
+ `;
195
+ }
196
+ removeChipValueFromSelection(value) {
197
+ var _a, _b;
198
+ const removed = this.value.find((sv) => sv.value === value);
199
+ this.value = this.value.filter((selectedValue) => selectedValue.value !== value);
200
+ this.notifySelectionChange([(_a = removed === null || removed === void 0 ? void 0 : removed.label) !== null && _a !== void 0 ? _a : value], false);
201
+ // When the last chip is removed we focus the input
202
+ if (this.value.length === 0) {
203
+ (_b = this.input) === null || _b === void 0 ? void 0 : _b.focus();
204
+ }
205
+ }
206
+ }
207
+ FtdsComboboxMultiValue.elementDefinitions = {
208
+ ...FtdsBaseCombobox.baseComboboxElementDefinitions,
209
+ "ftds-icon": FtdsIcon,
210
+ "ftds-chip-group": FtdsChipGroup,
211
+ };
212
+ FtdsComboboxMultiValue.styles = [baseComboboxStyles, comboboxMultiValueStyles, screenReaderStyles];
213
+ __decorate([
214
+ property({ type: Boolean })
215
+ ], FtdsComboboxMultiValue.prototype, "canSelectAll", void 0);
216
+ __decorate([
217
+ numberProperty()
218
+ ], FtdsComboboxMultiValue.prototype, "maxNumberOfChips", void 0);
@@ -0,0 +1,14 @@
1
+ import { DesignSystemFamily } from "@fluid-topics/design-system-variables";
2
+ import { ComboboxSuggestion, FtdsBaseComboboxProperties } from "./ftds-base-combobox.properties";
3
+ export interface FtdsComboboxMultiValueProperties extends FtdsBaseComboboxProperties {
4
+ canSelectAll: boolean;
5
+ maxNumberOfChips: number;
6
+ }
7
+ export interface ComboboxValue extends ComboboxSuggestion {
8
+ status?: DesignSystemFamily;
9
+ }
10
+ export declare class FtdsComboboxMultiValueChangeEvent extends CustomEvent<{
11
+ values: ComboboxValue[];
12
+ }> {
13
+ constructor(values: ComboboxValue[]);
14
+ }
@@ -0,0 +1,5 @@
1
+ export class FtdsComboboxMultiValueChangeEvent extends CustomEvent {
2
+ constructor(values) {
3
+ super("change", { detail: { values } });
4
+ }
5
+ }
@@ -0,0 +1 @@
1
+ export declare const comboboxMultiValueStyles: import("lit").CSSResult;
@@ -0,0 +1,58 @@
1
+ import { css } from "lit";
2
+ import { combobox, floatingMenu, } from "@fluid-topics/design-system-variables";
3
+ // language=css
4
+ export const comboboxMultiValueStyles = css `
5
+ :host {
6
+ display: block;
7
+ position: relative;
8
+ width: 100%;
9
+ }
10
+
11
+ .listbox-option--label {
12
+ display: flex;
13
+ gap: ${floatingMenu.gap};
14
+ align-items: center;
15
+ }
16
+
17
+ .listbox-option {
18
+ background-color: color-mix(in srgb, ${floatingMenu.multiselectUncheckedStateLayerColor} calc(${floatingMenu.multiselectUncheckedDefaultStateLayerOpacity} * 100%), transparent);
19
+ color: ${floatingMenu.multiselectUncheckedColor};
20
+
21
+ .listbox-option--checkbox {
22
+ color: ${floatingMenu.multiselectUncheckedIconColor}
23
+ }
24
+ }
25
+
26
+ .listbox-option:hover {
27
+ background-color: color-mix(in srgb, ${floatingMenu.multiselectUncheckedStateLayerColor} calc(${floatingMenu.multiselectUncheckedHoverStateLayerOpacity} * 100%), transparent);
28
+ }
29
+
30
+ .listbox-option[data-active="true"] {
31
+ background-color: color-mix(in srgb, ${floatingMenu.multiselectUncheckedStateLayerColor} calc(${floatingMenu.multiselectUncheckedFocusStateLayerOpacity} * 100%), transparent);
32
+ }
33
+
34
+ .listbox-option[aria-selected="true"] {
35
+ background-color: color-mix(in srgb, ${floatingMenu.multiselectCheckedStateLayerColor} calc(${floatingMenu.multiselectCheckedDefaultStateLayerOpacity} * 100%), transparent);
36
+ color: ${floatingMenu.multiselectCheckedColor};
37
+
38
+ .listbox-option--checkbox {
39
+ color: ${floatingMenu.multiselectCheckedIconColor}
40
+ }
41
+ }
42
+
43
+ .listbox-option[aria-selected="true"]:hover {
44
+ background-color: color-mix(in srgb, ${floatingMenu.multiselectCheckedStateLayerColor} calc(${floatingMenu.multiselectCheckedHoverStateLayerOpacity} * 100%), transparent);
45
+ }
46
+
47
+ .listbox-option[aria-selected="true"][data-active="true"] {
48
+ background-color: color-mix(in srgb, ${floatingMenu.multiselectCheckedStateLayerColor} calc(${floatingMenu.multiselectCheckedFocusStateLayerOpacity} * 100%), transparent);
49
+ }
50
+
51
+ .listbox-option--select-all[aria-selected="false"] .listbox-option--checkbox.intermediate {
52
+ color: ${floatingMenu.multiselectCheckedIconColor}
53
+ }
54
+
55
+ ::part(chip) {
56
+ border-color: ${combobox.valuesChipBorderColor}
57
+ }
58
+ `;
@@ -0,0 +1,21 @@
1
+ import { PropertyValues, TemplateResult } from "lit";
2
+ import { ElementDefinitionsMap } from "@fluid-topics/ft-wc-utils";
3
+ import { ActionableListboxItem, SuggestionListboxItem } from "./ftds-base-combobox.properties";
4
+ import { FtdsComboboxProperties } from "./ftds-combobox.properties";
5
+ import { FtdsBaseCombobox } from "./ftds-base-combobox";
6
+ export declare class FtdsCombobox extends FtdsBaseCombobox<string> implements FtdsComboboxProperties {
7
+ static elementDefinitions: ElementDefinitionsMap;
8
+ static styles: import("lit").CSSResult[];
9
+ private previousCommittedLabel;
10
+ constructor();
11
+ handleBlurStrategy(): void;
12
+ commitSelection(suggestion: ActionableListboxItem): void;
13
+ commitTypedText(typedText: string): void;
14
+ private commit;
15
+ resetCombobox(): void;
16
+ protected updated(changedProperties: PropertyValues): void;
17
+ isSuggestionSelected(value: string): boolean;
18
+ onType(e: Event): Promise<void>;
19
+ render(): TemplateResult;
20
+ renderSuggestionItem(suggestion: SuggestionListboxItem): TemplateResult;
21
+ }
@@ -0,0 +1,96 @@
1
+ import { html, } from "lit";
2
+ import { processValidationRules, screenReaderStyles, } from "@fluid-topics/ft-wc-utils";
3
+ import { isSelectableListboxItem, ListboxItemType, } from "./ftds-base-combobox.properties";
4
+ import { FtdsComboboxChangeEvent, } from "./ftds-combobox.properties";
5
+ import { comboboxStyles } from "./ftds-combobox.styles";
6
+ import { FtdsTypographyVariants } from "@fluid-topics/ft-typography";
7
+ import { FtdsBaseCombobox } from "./ftds-base-combobox";
8
+ import { baseComboboxStyles } from "./ftds-base-combobox.styles";
9
+ export class FtdsCombobox extends FtdsBaseCombobox {
10
+ constructor() {
11
+ var _a;
12
+ super();
13
+ this.previousCommittedLabel = "";
14
+ this.value = (_a = this.value) !== null && _a !== void 0 ? _a : "";
15
+ }
16
+ handleBlurStrategy() {
17
+ if (this.inputValue === "") {
18
+ return;
19
+ }
20
+ const matchedSuggestion = this.filteredSuggestions.find((s) => s.label.toLowerCase() === this.inputValue.toLowerCase());
21
+ if (matchedSuggestion) {
22
+ this.commitSelection(matchedSuggestion);
23
+ }
24
+ else if (this.canOfferNewValue) {
25
+ this.commitTypedText(this.inputValue);
26
+ }
27
+ else {
28
+ this.resetCombobox();
29
+ }
30
+ }
31
+ commitSelection(suggestion) {
32
+ if (!isSelectableListboxItem(suggestion)) {
33
+ return;
34
+ }
35
+ if (suggestion.type === ListboxItemType.newValue && processValidationRules(suggestion.value, this.newValueValidationRules).length > 0) {
36
+ return;
37
+ }
38
+ this.commit(suggestion.value, suggestion.label);
39
+ this.closeMenu();
40
+ }
41
+ commitTypedText(typedText) {
42
+ if (processValidationRules(typedText, this.newValueValidationRules).length > 0) {
43
+ return;
44
+ }
45
+ this.commit(typedText, typedText);
46
+ }
47
+ commit(value, label) {
48
+ this.value = value;
49
+ this.inputValue = label;
50
+ this.previousCommittedLabel = label;
51
+ this.dispatchEvent(new FtdsComboboxChangeEvent(value));
52
+ }
53
+ resetCombobox() {
54
+ this.inputValue = this.previousCommittedLabel;
55
+ }
56
+ updated(changedProperties) {
57
+ var _a;
58
+ super.updated(changedProperties);
59
+ if (changedProperties.has("value")) {
60
+ const previous = (_a = (changedProperties.get("value"))) !== null && _a !== void 0 ? _a : "";
61
+ const hasValueChanged = this.value !== previous && !this.isOpen && this.inputValue === previous;
62
+ if (hasValueChanged) {
63
+ this.inputValue = this.value;
64
+ }
65
+ }
66
+ }
67
+ isSuggestionSelected(value) {
68
+ return value === this.value;
69
+ }
70
+ async onType(e) {
71
+ await super.onType(e);
72
+ if (this.inputValue === "" && this.value !== "") {
73
+ this.previousCommittedLabel = "";
74
+ this.value = "";
75
+ this.dispatchEvent(new FtdsComboboxChangeEvent(""));
76
+ }
77
+ }
78
+ render() {
79
+ return html `
80
+ ${this.renderField()}
81
+ ${this.renderListboxContainer(false)}
82
+ `;
83
+ }
84
+ renderSuggestionItem(suggestion) {
85
+ return html `
86
+ <ftds-typography
87
+ variant="${this.isSuggestionSelected(suggestion.value) ? FtdsTypographyVariants.body2semibold : FtdsTypographyVariants.body2medium}"
88
+ class="listbox-option--label"
89
+ >
90
+ ${suggestion.label}
91
+ </ftds-typography>
92
+ `;
93
+ }
94
+ }
95
+ FtdsCombobox.elementDefinitions = FtdsBaseCombobox.baseComboboxElementDefinitions;
96
+ FtdsCombobox.styles = [baseComboboxStyles, comboboxStyles, screenReaderStyles];