@vonage/vivid 4.18.0 → 4.19.0

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 (90) hide show
  1. package/custom-elements.json +724 -488
  2. package/index.cjs +5 -0
  3. package/index.d.ts +1 -0
  4. package/index.js +2 -2
  5. package/lib/action-group/action-group.d.ts +0 -118
  6. package/lib/banner/banner.d.ts +0 -118
  7. package/lib/breadcrumb-item/breadcrumb-item.d.ts +0 -118
  8. package/lib/checkbox/checkbox.d.ts +0 -118
  9. package/lib/date-picker/date-picker.d.ts +0 -472
  10. package/lib/date-range-picker/date-range-picker.d.ts +0 -236
  11. package/lib/date-time-picker/date-time-picker.d.ts +0 -472
  12. package/lib/date-time-picker/definition.d.ts +2 -0
  13. package/lib/dialog/dialog.d.ts +0 -118
  14. package/lib/divider/divider.d.ts +0 -118
  15. package/lib/menu/menu.d.ts +0 -236
  16. package/lib/nav-disclosure/nav-disclosure.d.ts +0 -118
  17. package/lib/number-field/number-field.d.ts +0 -118
  18. package/lib/option/option.d.ts +2 -0
  19. package/lib/pagination/pagination.d.ts +1 -0
  20. package/lib/progress/progress.d.ts +0 -118
  21. package/lib/progress-ring/progress-ring.d.ts +0 -118
  22. package/lib/rich-text-editor/definition.d.ts +2 -0
  23. package/lib/rich-text-editor/facades/vivid-prose-mirror.facade.d.ts +1 -0
  24. package/lib/rich-text-editor/menubar/definition.d.ts +2 -0
  25. package/lib/rich-text-editor/menubar/menubar.d.ts +4 -0
  26. package/lib/rich-text-editor/menubar/menubar.template.d.ts +4 -0
  27. package/lib/rich-text-editor/rich-text-editor.d.ts +7 -0
  28. package/lib/searchable-select/locale.d.ts +1 -0
  29. package/lib/searchable-select/searchable-select.d.ts +3 -0
  30. package/lib/selectable-box/selectable-box.d.ts +0 -118
  31. package/lib/slider/slider.d.ts +0 -118
  32. package/lib/split-button/split-button.d.ts +0 -118
  33. package/lib/switch/switch.d.ts +0 -118
  34. package/lib/tag-group/tag-group.d.ts +0 -118
  35. package/lib/tag-name-map.d.ts +73 -0
  36. package/lib/text-anchor/text-anchor.d.ts +0 -118
  37. package/lib/text-area/text-area.d.ts +0 -118
  38. package/lib/text-field/text-field.d.ts +0 -118
  39. package/lib/time-picker/time-picker.d.ts +0 -236
  40. package/lib/toggletip/toggletip.d.ts +0 -118
  41. package/lib/tooltip/tooltip.d.ts +0 -118
  42. package/locales/de-DE.cjs +1 -0
  43. package/locales/de-DE.js +1 -0
  44. package/locales/en-GB.cjs +1 -0
  45. package/locales/en-GB.js +1 -0
  46. package/locales/en-US.cjs +1 -0
  47. package/locales/en-US.js +1 -0
  48. package/locales/ja-JP.cjs +1 -0
  49. package/locales/ja-JP.js +1 -0
  50. package/locales/zh-CN.cjs +1 -0
  51. package/locales/zh-CN.js +1 -0
  52. package/package.json +1 -1
  53. package/shared/aria/delegates-aria.d.ts +0 -118
  54. package/shared/definition20.cjs +10 -10
  55. package/shared/definition20.js +1 -1
  56. package/shared/definition30.cjs +1 -1
  57. package/shared/definition30.js +1 -1
  58. package/shared/definition36.cjs +7 -6
  59. package/shared/definition36.js +7 -6
  60. package/shared/definition37.cjs +15 -1
  61. package/shared/definition37.js +15 -1
  62. package/shared/definition4.cjs +13 -12
  63. package/shared/definition4.js +13 -12
  64. package/shared/definition43.cjs +221 -12
  65. package/shared/definition43.js +222 -14
  66. package/shared/definition44.cjs +83 -53
  67. package/shared/definition44.js +80 -50
  68. package/shared/definition63.cjs +232 -157
  69. package/shared/definition63.js +232 -157
  70. package/shared/foundation/button/button.d.ts +0 -118
  71. package/shared/option.cjs +42 -20
  72. package/shared/option.js +43 -21
  73. package/shared/patterns/anchored.d.ts +0 -236
  74. package/shared/picker-field/mixins/calendar-picker.d.ts +0 -118
  75. package/shared/picker-field/mixins/calendar-picker.template.d.ts +0 -118
  76. package/shared/picker-field/mixins/min-max-calendar-picker.d.ts +0 -236
  77. package/shared/picker-field/mixins/single-date-picker.d.ts +0 -354
  78. package/shared/picker-field/mixins/single-value-picker.d.ts +0 -118
  79. package/shared/picker-field/mixins/time-selection-picker.d.ts +0 -236
  80. package/shared/picker-field/mixins/time-selection-picker.template.d.ts +0 -236
  81. package/shared/picker-field.template.js +1 -1
  82. package/shared/vivid-element.cjs +1 -1
  83. package/shared/vivid-element.js +1 -1
  84. package/styles/core/all.css +1 -1
  85. package/styles/core/theme.css +1 -1
  86. package/styles/core/typography.css +1 -1
  87. package/styles/tokens/theme-dark.css +4 -4
  88. package/styles/tokens/theme-light.css +4 -4
  89. package/styles/tokens/vivid-2-compat.css +1 -1
  90. package/vivid.api.json +1339 -446
@@ -2,7 +2,8 @@
2
2
 
3
3
  const definition$1 = require('./definition11.cjs');
4
4
  const definition = require('./definition65.cjs');
5
- const definition$2 = require('./definition28.cjs');
5
+ const definition$3 = require('./definition28.cjs');
6
+ const definition$2 = require('./definition38.cjs');
6
7
  const vividElement = require('./vivid-element.cjs');
7
8
  const applyMixinsWithObservables = require('./applyMixinsWithObservables.cjs');
8
9
  const scrollIntoView = require('./scrollIntoView.cjs');
@@ -10,7 +11,7 @@ const formAssociated = require('./form-associated.cjs');
10
11
  const affix = require('./affix.cjs');
11
12
  const localized = require('./localized.cjs');
12
13
  const formElements = require('./form-elements.cjs');
13
- const listbox = require('./listbox.cjs');
14
+ const option = require('./option.cjs');
14
15
  const applyMixins = require('./apply-mixins.cjs');
15
16
  const when = require('./when.cjs');
16
17
  const ref = require('./ref.cjs');
@@ -49,9 +50,8 @@ var __decorateClass$1 = (decorators, target, key, kind) => {
49
50
  var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot " + msg);
50
51
  var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
51
52
  var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
52
- var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "write to private field"), member.set(obj, value), value);
53
53
  var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "access private method"), method);
54
- var _SearchableSelect_instances, updateValuesThroughUserInteraction_fn, updateValuesWhileMaintainingOrder_fn, isValidValue_fn, _slottedOptionsChangeHandler, updateSelectedOnSlottedOptions_fn, handleOptionInteraction_fn, _clonedTagIcons, tagIconOfOption_fn, updateClonedTagIconOfOption_fn, _suppressFilter, updateFilteredOptions_fn, transitionHighlightedOptionTo_fn, selectHighlightedOption_fn, highlightFirstOption_fn, highlightLastOption_fn, highlightPrevPage_fn, highlightNextPage_fn, highlightPreviousOption_fn, highlightNextOption_fn, textForValue_fn, measureTagWidth_fn, updateTagLayout_fn, moveTagFocusTo_fn, nextTagIndexLeft_fn, nextTagIndexRight_fn, nextTagIndexForRemoved_fn, determineInitialValues_fn, updateFormValue_fn, _resizeObserver;
54
+ var _SearchableSelect_instances, updateValuesThroughUserInteraction_fn, updateValuesWhileMaintainingOrder_fn, isValidValue_fn, _slottedOptionsChangeHandler, updateSelectedOnSlottedOptions_fn, handleOptionInteraction_fn, _clonedTagIcons, tagIconOfOption_fn, updateClonedTagIconOfOption_fn, updateFilteredOptions_fn, transitionHighlightedOptionTo_fn, selectHighlightedOption_fn, highlightFirstOption_fn, highlightLastOption_fn, highlightPrevPage_fn, highlightNextPage_fn, highlightPreviousOption_fn, highlightNextOption_fn, textForValue_fn, measureTagWidth_fn, updateTagLayout_fn, moveTagFocusTo_fn, nextTagIndexLeft_fn, nextTagIndexRight_fn, nextTagIndexForRemoved_fn, determineInitialValues_fn, updateFormValue_fn, _resizeObserver;
55
55
  const TagGapPx = 8;
56
56
  const InputMinWidthPx = 100;
57
57
  const PageSize = 10;
@@ -67,7 +67,7 @@ exports.SearchableSelect = class SearchableSelect extends FormAssociatedSearchab
67
67
  this.maxLines = null;
68
68
  this.values = [];
69
69
  this.initialValues = [];
70
- this._inputValue = "";
70
+ this._currentSearchText = null;
71
71
  // --- Slotted options ---
72
72
  /**
73
73
  * @internal
@@ -86,7 +86,7 @@ exports.SearchableSelect = class SearchableSelect extends FormAssociatedSearchab
86
86
  __privateAdd(this, _clonedTagIcons, /* @__PURE__ */ new Map());
87
87
  this._filteredOptions = [];
88
88
  this._filteredEnabledOptions = [];
89
- __privateAdd(this, _suppressFilter, false);
89
+ this.loading = false;
90
90
  this._highlightedOptionIndex = null;
91
91
  this._numElidedTags = 0;
92
92
  this._tagRows = [];
@@ -127,14 +127,6 @@ exports.SearchableSelect = class SearchableSelect extends FormAssociatedSearchab
127
127
  this.values = this.values.filter((value) => __privateMethod(this, _SearchableSelect_instances, isValidValue_fn).call(this, value));
128
128
  return;
129
129
  }
130
- if (!this.multiple) {
131
- if (this.values.length) {
132
- __privateSet(this, _suppressFilter, true);
133
- this._inputValue = __privateMethod(this, _SearchableSelect_instances, textForValue_fn).call(this, this.values[0]);
134
- } else {
135
- this._inputValue = "";
136
- }
137
- }
138
130
  this.value = this.values.length ? this.values[0] : "";
139
131
  __privateMethod(this, _SearchableSelect_instances, updateSelectedOnSlottedOptions_fn).call(this);
140
132
  if (this.$fastController.isConnected) {
@@ -189,21 +181,35 @@ exports.SearchableSelect = class SearchableSelect extends FormAssociatedSearchab
189
181
  /**
190
182
  * @internal
191
183
  */
192
- _inputValueChanged() {
184
+ _currentSearchTextChanged() {
193
185
  __privateMethod(this, _SearchableSelect_instances, updateFilteredOptions_fn).call(this);
186
+ this.$emit("search-text-change", void 0, {
187
+ bubbles: false,
188
+ composed: false
189
+ });
190
+ }
191
+ /**
192
+ * The current search text of the component.
193
+ */
194
+ get searchText() {
195
+ return this._currentSearchText ?? "";
196
+ }
197
+ /**
198
+ * @internal
199
+ */
200
+ get _inputValue() {
201
+ return this._currentSearchText ?? (!this.multiple && this.value !== "" ? __privateMethod(this, _SearchableSelect_instances, textForValue_fn).call(this, this.value) ?? "" : "");
194
202
  }
195
203
  /**
196
204
  * @internal
197
205
  */
198
206
  _onInputInput(event) {
199
- __privateSet(this, _suppressFilter, false);
200
- this._inputValue = event.target.value;
207
+ this._currentSearchText = event.target.value;
201
208
  }
202
209
  /**
203
210
  * @internal
204
211
  */
205
212
  _onInputFocus(_) {
206
- __privateSet(this, _suppressFilter, true);
207
213
  __privateMethod(this, _SearchableSelect_instances, updateFilteredOptions_fn).call(this);
208
214
  this.open = true;
209
215
  }
@@ -212,15 +218,7 @@ exports.SearchableSelect = class SearchableSelect extends FormAssociatedSearchab
212
218
  */
213
219
  _onInputBlur(_) {
214
220
  this.open = false;
215
- if (this.multiple) {
216
- this._inputValue = "";
217
- } else {
218
- if (this.values.length === 0) {
219
- this._inputValue = "";
220
- } else {
221
- this._inputValue = __privateMethod(this, _SearchableSelect_instances, textForValue_fn).call(this, this.values[0]);
222
- }
223
- }
221
+ this._currentSearchText = null;
224
222
  this._changeDescription = "";
225
223
  }
226
224
  /**
@@ -338,6 +336,12 @@ exports.SearchableSelect = class SearchableSelect extends FormAssociatedSearchab
338
336
  _tagIconSlotName(value) {
339
337
  return `_tag-icon-${this.values.indexOf(value)}`;
340
338
  }
339
+ /**
340
+ * @internal
341
+ */
342
+ optionFilterChanged() {
343
+ __privateMethod(this, _SearchableSelect_instances, updateFilteredOptions_fn).call(this);
344
+ }
341
345
  // --- Tags ---
342
346
  /**
343
347
  * @internal
@@ -512,6 +516,7 @@ updateSelectedOnSlottedOptions_fn = function() {
512
516
  handleOptionInteraction_fn = function(option) {
513
517
  const value = option.value;
514
518
  let newValues;
519
+ let shouldClearSearchText = false;
515
520
  const isSelection = !this.values.includes(value);
516
521
  if (this.multiple) {
517
522
  if (isSelection) {
@@ -519,11 +524,11 @@ handleOptionInteraction_fn = function(option) {
519
524
  } else {
520
525
  newValues = this.values.filter((option2) => option2 !== value);
521
526
  }
522
- this._inputValue = "";
527
+ shouldClearSearchText = true;
523
528
  } else {
524
529
  if (isSelection) {
525
530
  newValues = [value];
526
- this._inputValue = option.text;
531
+ shouldClearSearchText = true;
527
532
  } else {
528
533
  newValues = [];
529
534
  }
@@ -531,6 +536,9 @@ handleOptionInteraction_fn = function(option) {
531
536
  }
532
537
  this._changeDescription = isSelection ? this.locale.searchableSelect.optionSelectedMessage(option.text) : this.locale.searchableSelect.optionDeselectedMessage(option.text);
533
538
  __privateMethod(this, _SearchableSelect_instances, updateValuesThroughUserInteraction_fn).call(this, newValues);
539
+ if (shouldClearSearchText) {
540
+ this._currentSearchText = null;
541
+ }
534
542
  };
535
543
  _clonedTagIcons = new WeakMap();
536
544
  tagIconOfOption_fn = function(option) {
@@ -553,20 +561,14 @@ updateClonedTagIconOfOption_fn = function(option) {
553
561
  }
554
562
  }
555
563
  };
556
- _suppressFilter = new WeakMap();
557
564
  updateFilteredOptions_fn = function() {
558
565
  const newFilteredOptions = [];
566
+ const optionFilter = this.optionFilter ?? ((option, searchText) => option.text.toLowerCase().includes(searchText.toLowerCase()));
559
567
  for (const option of this._slottedOptions ?? []) {
560
- if (__privateGet(this, _suppressFilter) || this._inputValue === "") {
561
- option.hidden = false;
562
- option._matchedRange = null;
563
- } else {
564
- const matchIndex = option.text.toLowerCase().indexOf(this._inputValue.toLowerCase());
565
- const matchedRange = matchIndex === -1 ? null : { from: matchIndex, to: matchIndex + this._inputValue.length };
566
- option.hidden = !matchedRange;
567
- option._matchedRange = matchedRange;
568
- }
569
- if (!option.hidden) {
568
+ option._vvdSearchText = this.searchText;
569
+ const matches = !this.searchText || optionFilter(option, this.searchText);
570
+ option._isNotMatching = !matches;
571
+ if (!option.hidden && matches) {
570
572
  newFilteredOptions.push(option);
571
573
  }
572
574
  }
@@ -627,10 +629,7 @@ highlightNextOption_fn = function() {
627
629
  __privateMethod(this, _SearchableSelect_instances, transitionHighlightedOptionTo_fn).call(this, (this._highlightedOptionIndex ?? -1) + 1);
628
630
  };
629
631
  textForValue_fn = function(value) {
630
- const option = this._slottedOptions.find(
631
- (option2) => option2.value === value
632
- );
633
- return option.text;
632
+ return this._slottedOptions?.find((option) => option.value === value)?.text;
634
633
  };
635
634
  /**
636
635
  * @internal
@@ -798,16 +797,24 @@ __decorateClass$1([
798
797
  ], exports.SearchableSelect.prototype, "_input", 2);
799
798
  __decorateClass$1([
800
799
  vividElement.observable
801
- ], exports.SearchableSelect.prototype, "_inputValue", 2);
800
+ ], exports.SearchableSelect.prototype, "_currentSearchText", 2);
802
801
  __decorateClass$1([
803
802
  vividElement.observable
804
803
  ], exports.SearchableSelect.prototype, "_slottedOptions", 2);
804
+ __decorateClass$1([
805
+ vividElement.observable
806
+ ], exports.SearchableSelect.prototype, "optionFilter", 2);
805
807
  __decorateClass$1([
806
808
  vividElement.observable
807
809
  ], exports.SearchableSelect.prototype, "_filteredOptions", 2);
808
810
  __decorateClass$1([
809
811
  vividElement.observable
810
812
  ], exports.SearchableSelect.prototype, "_filteredEnabledOptions", 2);
813
+ __decorateClass$1([
814
+ vividElement.attr({
815
+ mode: "boolean"
816
+ })
817
+ ], exports.SearchableSelect.prototype, "loading", 2);
811
818
  __decorateClass$1([
812
819
  vividElement.observable
813
820
  ], exports.SearchableSelect.prototype, "_highlightedOptionIndex", 2);
@@ -933,6 +940,7 @@ const elidedTagTemplateFactory = (context, getComponent) => {
933
940
  };
934
941
  function renderFieldset(context) {
935
942
  const buttonTag = context.tagFor(definition$1.Button);
943
+ const progressRingTag = context.tagFor(definition$2.ProgressRing);
936
944
  const affixIconTemplate = affix.affixIconTemplateFactory(context);
937
945
  const chevronTemplate = definition$1.chevronTemplateFactory(context);
938
946
  const tagTemplate = tagTemplateFactory(context, (c) => c.parent);
@@ -990,7 +998,13 @@ function renderFieldset(context) {
990
998
  type="text"
991
999
  ?disabled="${(x) => x.disabled}"
992
1000
  :value="${(x) => x._inputValue}"
993
- @input="${(x, c) => x._onInputInput(c.event)}"
1001
+ @input="${(x, c) => {
1002
+ x._onInputInput(c.event);
1003
+ c.event.stopPropagation();
1004
+ }}"
1005
+ @change="${(_, c) => {
1006
+ c.event.stopPropagation();
1007
+ }}"
994
1008
  @focus="${(x, c) => x._onInputFocus(c.event)}"
995
1009
  @blur="${(x, c) => x._onInputBlur(c.event)}"
996
1010
  @keydown="${(x, c) => x._onInputKeydown(c.event)}"
@@ -1014,7 +1028,11 @@ function renderFieldset(context) {
1014
1028
  ></${buttonTag}>`
1015
1029
  )}
1016
1030
  <div @mousedown="${() => false}" @click="${(x) => x._onChevronClick()}">
1017
- ${chevronTemplate}
1031
+ ${when.when(
1032
+ (x) => x.loading,
1033
+ vividElement.html`<${progressRingTag} indeterminate size="-6"></${progressRingTag}>`
1034
+ )}
1035
+ ${when.when((x) => !x.loading, chevronTemplate)}
1018
1036
  </div>
1019
1037
  </div>
1020
1038
  `;
@@ -1052,7 +1070,7 @@ function renderControl(context) {
1052
1070
  >
1053
1071
  <slot
1054
1072
  ${slotted.slotted({
1055
- filter: listbox.Listbox.slottedOptionFilter,
1073
+ filter: option.isListboxOption,
1056
1074
  flatten: true,
1057
1075
  property: "_slottedOptions"
1058
1076
  })}>
@@ -1061,13 +1079,19 @@ function renderControl(context) {
1061
1079
  (x) => x._filteredOptions.length === 0,
1062
1080
  vividElement.html`<div class="empty-message">
1063
1081
  ${when.when(
1064
- (x) => x._inputValue === "",
1082
+ (x) => x.loading,
1083
+ vividElement.html`<slot name="loading-options">
1084
+ ${(x) => x.locale.searchableSelect.loadingOptionsMessage}
1085
+ </slot>`
1086
+ )}
1087
+ ${when.when(
1088
+ (x) => !x.loading && x.searchText === "",
1065
1089
  vividElement.html`<slot name="no-options">
1066
1090
  ${(x) => x.locale.searchableSelect.noOptionsMessage}
1067
1091
  </slot>`
1068
1092
  )}
1069
1093
  ${when.when(
1070
- (x) => x._inputValue !== "",
1094
+ (x) => !x.loading && x.searchText !== "",
1071
1095
  vividElement.html`<slot name="no-matches">
1072
1096
  ${(x) => x.locale.searchableSelect.noMatchesMessage}
1073
1097
  </slot>`
@@ -1114,7 +1138,7 @@ function renderRemoveButton(iconTag) {
1114
1138
  `;
1115
1139
  }
1116
1140
  const optionTagTemplate = (context) => {
1117
- const iconTag = context.tagFor(definition$2.Icon);
1141
+ const iconTag = context.tagFor(definition$3.Icon);
1118
1142
  return vividElement.html`<span class="${getClasses}" aria-disabled="${(x) => x.disabled}">
1119
1143
  <slot name="icon" aria-hidden="true">
1120
1144
  ${when.when(
@@ -1134,7 +1158,7 @@ const optionTagDefinition = vividElement.defineVividComponent(
1134
1158
  "option-tag",
1135
1159
  OptionTag,
1136
1160
  optionTagTemplate,
1137
- [definition$2.iconDefinition],
1161
+ [definition$3.iconDefinition],
1138
1162
  {
1139
1163
  styles: [optionTagStyles],
1140
1164
  shadowOptions: {
@@ -1146,7 +1170,13 @@ const searchableSelectDefinition = vividElement.defineVividComponent(
1146
1170
  "searchable-select",
1147
1171
  exports.SearchableSelect,
1148
1172
  SearchableSelectTemplate,
1149
- [definition$1.buttonDefinition, definition.popupDefinition, definition$2.iconDefinition, optionTagDefinition],
1173
+ [
1174
+ definition$1.buttonDefinition,
1175
+ definition.popupDefinition,
1176
+ definition$3.iconDefinition,
1177
+ optionTagDefinition,
1178
+ definition$2.progressRingDefinition
1179
+ ],
1150
1180
  {
1151
1181
  styles
1152
1182
  }
@@ -1,6 +1,7 @@
1
1
  import { B as Button, c as chevronTemplateFactory, b as buttonDefinition } from './definition11.js';
2
2
  import { P as Popup, p as popupDefinition } from './definition65.js';
3
3
  import { I as Icon, i as iconDefinition } from './definition28.js';
4
+ import { P as ProgressRing, p as progressRingDefinition } from './definition38.js';
4
5
  import { V as VividElement, O as Observable, D as DOM, a as attr, n as nullableNumberConverter, o as observable, h as html, d as createRegisterFunction, f as defineVividComponent } from './vivid-element.js';
5
6
  import { a as applyMixinsWithObservables } from './applyMixinsWithObservables.js';
6
7
  import { s as scrollIntoView } from './scrollIntoView.js';
@@ -8,7 +9,7 @@ import { F as FormAssociated } from './form-associated.js';
8
9
  import { A as AffixIconWithTrailing, a as affixIconTemplateFactory, I as IconWrapper } from './affix.js';
9
10
  import { L as Localized } from './localized.js';
10
11
  import { F as FormElementSuccessText, a as FormElementHelperText, e as errorText, f as formElements, g as getFeedbackTemplate } from './form-elements.js';
11
- import { L as Listbox } from './listbox.js';
12
+ import { i as isListboxOption } from './option.js';
12
13
  import { a as applyMixins } from './apply-mixins.js';
13
14
  import { w as when } from './when.js';
14
15
  import { r as ref } from './ref.js';
@@ -47,9 +48,8 @@ var __decorateClass$1 = (decorators, target, key, kind) => {
47
48
  var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot " + msg);
48
49
  var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
49
50
  var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
50
- var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "write to private field"), member.set(obj, value), value);
51
51
  var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "access private method"), method);
52
- var _SearchableSelect_instances, updateValuesThroughUserInteraction_fn, updateValuesWhileMaintainingOrder_fn, isValidValue_fn, _slottedOptionsChangeHandler, updateSelectedOnSlottedOptions_fn, handleOptionInteraction_fn, _clonedTagIcons, tagIconOfOption_fn, updateClonedTagIconOfOption_fn, _suppressFilter, updateFilteredOptions_fn, transitionHighlightedOptionTo_fn, selectHighlightedOption_fn, highlightFirstOption_fn, highlightLastOption_fn, highlightPrevPage_fn, highlightNextPage_fn, highlightPreviousOption_fn, highlightNextOption_fn, textForValue_fn, measureTagWidth_fn, updateTagLayout_fn, moveTagFocusTo_fn, nextTagIndexLeft_fn, nextTagIndexRight_fn, nextTagIndexForRemoved_fn, determineInitialValues_fn, updateFormValue_fn, _resizeObserver;
52
+ var _SearchableSelect_instances, updateValuesThroughUserInteraction_fn, updateValuesWhileMaintainingOrder_fn, isValidValue_fn, _slottedOptionsChangeHandler, updateSelectedOnSlottedOptions_fn, handleOptionInteraction_fn, _clonedTagIcons, tagIconOfOption_fn, updateClonedTagIconOfOption_fn, updateFilteredOptions_fn, transitionHighlightedOptionTo_fn, selectHighlightedOption_fn, highlightFirstOption_fn, highlightLastOption_fn, highlightPrevPage_fn, highlightNextPage_fn, highlightPreviousOption_fn, highlightNextOption_fn, textForValue_fn, measureTagWidth_fn, updateTagLayout_fn, moveTagFocusTo_fn, nextTagIndexLeft_fn, nextTagIndexRight_fn, nextTagIndexForRemoved_fn, determineInitialValues_fn, updateFormValue_fn, _resizeObserver;
53
53
  const TagGapPx = 8;
54
54
  const InputMinWidthPx = 100;
55
55
  const PageSize = 10;
@@ -65,7 +65,7 @@ let SearchableSelect = class extends FormAssociatedSearchableSelect {
65
65
  this.maxLines = null;
66
66
  this.values = [];
67
67
  this.initialValues = [];
68
- this._inputValue = "";
68
+ this._currentSearchText = null;
69
69
  // --- Slotted options ---
70
70
  /**
71
71
  * @internal
@@ -84,7 +84,7 @@ let SearchableSelect = class extends FormAssociatedSearchableSelect {
84
84
  __privateAdd(this, _clonedTagIcons, /* @__PURE__ */ new Map());
85
85
  this._filteredOptions = [];
86
86
  this._filteredEnabledOptions = [];
87
- __privateAdd(this, _suppressFilter, false);
87
+ this.loading = false;
88
88
  this._highlightedOptionIndex = null;
89
89
  this._numElidedTags = 0;
90
90
  this._tagRows = [];
@@ -125,14 +125,6 @@ let SearchableSelect = class extends FormAssociatedSearchableSelect {
125
125
  this.values = this.values.filter((value) => __privateMethod(this, _SearchableSelect_instances, isValidValue_fn).call(this, value));
126
126
  return;
127
127
  }
128
- if (!this.multiple) {
129
- if (this.values.length) {
130
- __privateSet(this, _suppressFilter, true);
131
- this._inputValue = __privateMethod(this, _SearchableSelect_instances, textForValue_fn).call(this, this.values[0]);
132
- } else {
133
- this._inputValue = "";
134
- }
135
- }
136
128
  this.value = this.values.length ? this.values[0] : "";
137
129
  __privateMethod(this, _SearchableSelect_instances, updateSelectedOnSlottedOptions_fn).call(this);
138
130
  if (this.$fastController.isConnected) {
@@ -187,21 +179,35 @@ let SearchableSelect = class extends FormAssociatedSearchableSelect {
187
179
  /**
188
180
  * @internal
189
181
  */
190
- _inputValueChanged() {
182
+ _currentSearchTextChanged() {
191
183
  __privateMethod(this, _SearchableSelect_instances, updateFilteredOptions_fn).call(this);
184
+ this.$emit("search-text-change", void 0, {
185
+ bubbles: false,
186
+ composed: false
187
+ });
188
+ }
189
+ /**
190
+ * The current search text of the component.
191
+ */
192
+ get searchText() {
193
+ return this._currentSearchText ?? "";
194
+ }
195
+ /**
196
+ * @internal
197
+ */
198
+ get _inputValue() {
199
+ return this._currentSearchText ?? (!this.multiple && this.value !== "" ? __privateMethod(this, _SearchableSelect_instances, textForValue_fn).call(this, this.value) ?? "" : "");
192
200
  }
193
201
  /**
194
202
  * @internal
195
203
  */
196
204
  _onInputInput(event) {
197
- __privateSet(this, _suppressFilter, false);
198
- this._inputValue = event.target.value;
205
+ this._currentSearchText = event.target.value;
199
206
  }
200
207
  /**
201
208
  * @internal
202
209
  */
203
210
  _onInputFocus(_) {
204
- __privateSet(this, _suppressFilter, true);
205
211
  __privateMethod(this, _SearchableSelect_instances, updateFilteredOptions_fn).call(this);
206
212
  this.open = true;
207
213
  }
@@ -210,15 +216,7 @@ let SearchableSelect = class extends FormAssociatedSearchableSelect {
210
216
  */
211
217
  _onInputBlur(_) {
212
218
  this.open = false;
213
- if (this.multiple) {
214
- this._inputValue = "";
215
- } else {
216
- if (this.values.length === 0) {
217
- this._inputValue = "";
218
- } else {
219
- this._inputValue = __privateMethod(this, _SearchableSelect_instances, textForValue_fn).call(this, this.values[0]);
220
- }
221
- }
219
+ this._currentSearchText = null;
222
220
  this._changeDescription = "";
223
221
  }
224
222
  /**
@@ -336,6 +334,12 @@ let SearchableSelect = class extends FormAssociatedSearchableSelect {
336
334
  _tagIconSlotName(value) {
337
335
  return `_tag-icon-${this.values.indexOf(value)}`;
338
336
  }
337
+ /**
338
+ * @internal
339
+ */
340
+ optionFilterChanged() {
341
+ __privateMethod(this, _SearchableSelect_instances, updateFilteredOptions_fn).call(this);
342
+ }
339
343
  // --- Tags ---
340
344
  /**
341
345
  * @internal
@@ -510,6 +514,7 @@ updateSelectedOnSlottedOptions_fn = function() {
510
514
  handleOptionInteraction_fn = function(option) {
511
515
  const value = option.value;
512
516
  let newValues;
517
+ let shouldClearSearchText = false;
513
518
  const isSelection = !this.values.includes(value);
514
519
  if (this.multiple) {
515
520
  if (isSelection) {
@@ -517,11 +522,11 @@ handleOptionInteraction_fn = function(option) {
517
522
  } else {
518
523
  newValues = this.values.filter((option2) => option2 !== value);
519
524
  }
520
- this._inputValue = "";
525
+ shouldClearSearchText = true;
521
526
  } else {
522
527
  if (isSelection) {
523
528
  newValues = [value];
524
- this._inputValue = option.text;
529
+ shouldClearSearchText = true;
525
530
  } else {
526
531
  newValues = [];
527
532
  }
@@ -529,6 +534,9 @@ handleOptionInteraction_fn = function(option) {
529
534
  }
530
535
  this._changeDescription = isSelection ? this.locale.searchableSelect.optionSelectedMessage(option.text) : this.locale.searchableSelect.optionDeselectedMessage(option.text);
531
536
  __privateMethod(this, _SearchableSelect_instances, updateValuesThroughUserInteraction_fn).call(this, newValues);
537
+ if (shouldClearSearchText) {
538
+ this._currentSearchText = null;
539
+ }
532
540
  };
533
541
  _clonedTagIcons = new WeakMap();
534
542
  tagIconOfOption_fn = function(option) {
@@ -551,20 +559,14 @@ updateClonedTagIconOfOption_fn = function(option) {
551
559
  }
552
560
  }
553
561
  };
554
- _suppressFilter = new WeakMap();
555
562
  updateFilteredOptions_fn = function() {
556
563
  const newFilteredOptions = [];
564
+ const optionFilter = this.optionFilter ?? ((option, searchText) => option.text.toLowerCase().includes(searchText.toLowerCase()));
557
565
  for (const option of this._slottedOptions ?? []) {
558
- if (__privateGet(this, _suppressFilter) || this._inputValue === "") {
559
- option.hidden = false;
560
- option._matchedRange = null;
561
- } else {
562
- const matchIndex = option.text.toLowerCase().indexOf(this._inputValue.toLowerCase());
563
- const matchedRange = matchIndex === -1 ? null : { from: matchIndex, to: matchIndex + this._inputValue.length };
564
- option.hidden = !matchedRange;
565
- option._matchedRange = matchedRange;
566
- }
567
- if (!option.hidden) {
566
+ option._vvdSearchText = this.searchText;
567
+ const matches = !this.searchText || optionFilter(option, this.searchText);
568
+ option._isNotMatching = !matches;
569
+ if (!option.hidden && matches) {
568
570
  newFilteredOptions.push(option);
569
571
  }
570
572
  }
@@ -625,10 +627,7 @@ highlightNextOption_fn = function() {
625
627
  __privateMethod(this, _SearchableSelect_instances, transitionHighlightedOptionTo_fn).call(this, (this._highlightedOptionIndex ?? -1) + 1);
626
628
  };
627
629
  textForValue_fn = function(value) {
628
- const option = this._slottedOptions.find(
629
- (option2) => option2.value === value
630
- );
631
- return option.text;
630
+ return this._slottedOptions?.find((option) => option.value === value)?.text;
632
631
  };
633
632
  /**
634
633
  * @internal
@@ -796,16 +795,24 @@ __decorateClass$1([
796
795
  ], SearchableSelect.prototype, "_input", 2);
797
796
  __decorateClass$1([
798
797
  observable
799
- ], SearchableSelect.prototype, "_inputValue", 2);
798
+ ], SearchableSelect.prototype, "_currentSearchText", 2);
800
799
  __decorateClass$1([
801
800
  observable
802
801
  ], SearchableSelect.prototype, "_slottedOptions", 2);
802
+ __decorateClass$1([
803
+ observable
804
+ ], SearchableSelect.prototype, "optionFilter", 2);
803
805
  __decorateClass$1([
804
806
  observable
805
807
  ], SearchableSelect.prototype, "_filteredOptions", 2);
806
808
  __decorateClass$1([
807
809
  observable
808
810
  ], SearchableSelect.prototype, "_filteredEnabledOptions", 2);
811
+ __decorateClass$1([
812
+ attr({
813
+ mode: "boolean"
814
+ })
815
+ ], SearchableSelect.prototype, "loading", 2);
809
816
  __decorateClass$1([
810
817
  observable
811
818
  ], SearchableSelect.prototype, "_highlightedOptionIndex", 2);
@@ -931,6 +938,7 @@ const elidedTagTemplateFactory = (context, getComponent) => {
931
938
  };
932
939
  function renderFieldset(context) {
933
940
  const buttonTag = context.tagFor(Button);
941
+ const progressRingTag = context.tagFor(ProgressRing);
934
942
  const affixIconTemplate = affixIconTemplateFactory(context);
935
943
  const chevronTemplate = chevronTemplateFactory(context);
936
944
  const tagTemplate = tagTemplateFactory(context, (c) => c.parent);
@@ -988,7 +996,13 @@ function renderFieldset(context) {
988
996
  type="text"
989
997
  ?disabled="${(x) => x.disabled}"
990
998
  :value="${(x) => x._inputValue}"
991
- @input="${(x, c) => x._onInputInput(c.event)}"
999
+ @input="${(x, c) => {
1000
+ x._onInputInput(c.event);
1001
+ c.event.stopPropagation();
1002
+ }}"
1003
+ @change="${(_, c) => {
1004
+ c.event.stopPropagation();
1005
+ }}"
992
1006
  @focus="${(x, c) => x._onInputFocus(c.event)}"
993
1007
  @blur="${(x, c) => x._onInputBlur(c.event)}"
994
1008
  @keydown="${(x, c) => x._onInputKeydown(c.event)}"
@@ -1012,7 +1026,11 @@ function renderFieldset(context) {
1012
1026
  ></${buttonTag}>`
1013
1027
  )}
1014
1028
  <div @mousedown="${() => false}" @click="${(x) => x._onChevronClick()}">
1015
- ${chevronTemplate}
1029
+ ${when(
1030
+ (x) => x.loading,
1031
+ html`<${progressRingTag} indeterminate size="-6"></${progressRingTag}>`
1032
+ )}
1033
+ ${when((x) => !x.loading, chevronTemplate)}
1016
1034
  </div>
1017
1035
  </div>
1018
1036
  `;
@@ -1050,7 +1068,7 @@ function renderControl(context) {
1050
1068
  >
1051
1069
  <slot
1052
1070
  ${slotted({
1053
- filter: Listbox.slottedOptionFilter,
1071
+ filter: isListboxOption,
1054
1072
  flatten: true,
1055
1073
  property: "_slottedOptions"
1056
1074
  })}>
@@ -1059,13 +1077,19 @@ function renderControl(context) {
1059
1077
  (x) => x._filteredOptions.length === 0,
1060
1078
  html`<div class="empty-message">
1061
1079
  ${when(
1062
- (x) => x._inputValue === "",
1080
+ (x) => x.loading,
1081
+ html`<slot name="loading-options">
1082
+ ${(x) => x.locale.searchableSelect.loadingOptionsMessage}
1083
+ </slot>`
1084
+ )}
1085
+ ${when(
1086
+ (x) => !x.loading && x.searchText === "",
1063
1087
  html`<slot name="no-options">
1064
1088
  ${(x) => x.locale.searchableSelect.noOptionsMessage}
1065
1089
  </slot>`
1066
1090
  )}
1067
1091
  ${when(
1068
- (x) => x._inputValue !== "",
1092
+ (x) => !x.loading && x.searchText !== "",
1069
1093
  html`<slot name="no-matches">
1070
1094
  ${(x) => x.locale.searchableSelect.noMatchesMessage}
1071
1095
  </slot>`
@@ -1144,7 +1168,13 @@ const searchableSelectDefinition = defineVividComponent(
1144
1168
  "searchable-select",
1145
1169
  SearchableSelect,
1146
1170
  SearchableSelectTemplate,
1147
- [buttonDefinition, popupDefinition, iconDefinition, optionTagDefinition],
1171
+ [
1172
+ buttonDefinition,
1173
+ popupDefinition,
1174
+ iconDefinition,
1175
+ optionTagDefinition,
1176
+ progressRingDefinition
1177
+ ],
1148
1178
  {
1149
1179
  styles
1150
1180
  }