@duetds/components 8.5.5 → 8.6.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 (212) hide show
  1. package/hydrate/index.js +289 -113
  2. package/lib/cjs/duet-alert.cjs.entry.js +1 -1
  3. package/lib/cjs/duet-banner.cjs.entry.js +1 -1
  4. package/lib/cjs/duet-callout.cjs.entry.js +1 -1
  5. package/lib/cjs/duet-chip.cjs.entry.js +9 -2
  6. package/lib/cjs/duet-choice_2.cjs.entry.js +1 -1
  7. package/lib/cjs/duet-collapsible.cjs.entry.js +1 -1
  8. package/lib/cjs/duet-combobox.cjs.entry.js +260 -127
  9. package/lib/cjs/duet-date-picker.cjs.entry.js +1 -1
  10. package/lib/cjs/duet-fieldset.cjs.entry.js +1 -1
  11. package/lib/cjs/duet-hero.cjs.entry.js +1 -1
  12. package/lib/cjs/duet-input_2.cjs.entry.js +39 -3
  13. package/lib/cjs/duet-modal.cjs.entry.js +1 -1
  14. package/lib/cjs/duet-multiselect.cjs.entry.js +1 -1
  15. package/lib/cjs/duet-number-input.cjs.entry.js +1 -1
  16. package/lib/cjs/duet-promo-card.cjs.entry.js +1 -1
  17. package/lib/cjs/duet-radio_2.cjs.entry.js +1 -1
  18. package/lib/cjs/duet-scrollable_3.cjs.entry.js +1 -1
  19. package/lib/cjs/duet-select.cjs.entry.js +1 -1
  20. package/lib/cjs/duet-slideout-panel.cjs.entry.js +1 -1
  21. package/lib/cjs/duet-slideout.cjs.entry.js +1 -1
  22. package/lib/cjs/duet-textarea.cjs.entry.js +1 -1
  23. package/lib/cjs/duet.cjs.js +1 -1
  24. package/lib/cjs/loader.cjs.js +1 -1
  25. package/lib/cjs/{slot-utils-f5073417.js → slot-utils-03a40c78.js} +3 -1
  26. package/lib/collection/components/duet-chip/duet-chip.css +7 -0
  27. package/lib/collection/components/duet-chip/duet-chip.js +29 -2
  28. package/lib/collection/components/duet-combobox/duet-combobox-select-single.js +2 -2
  29. package/lib/collection/components/duet-combobox/duet-combobox.css +10 -2
  30. package/lib/collection/components/duet-combobox/duet-combobox.e2e.js +81 -51
  31. package/lib/collection/components/duet-combobox/duet-combobox.js +321 -142
  32. package/lib/collection/components/duet-input/duet-input.css +29 -0
  33. package/lib/collection/components/duet-input/duet-input.js +159 -3
  34. package/lib/collection/utils/slot-utils.js +3 -1
  35. package/lib/dist-custom-elements/duet-action-button.js +1 -1
  36. package/lib/dist-custom-elements/duet-alert.js +1 -1
  37. package/lib/dist-custom-elements/duet-banner.js +1 -1
  38. package/lib/dist-custom-elements/duet-breadcrumb.js +1 -1
  39. package/lib/dist-custom-elements/duet-callout.js +1 -1
  40. package/lib/dist-custom-elements/duet-card.js +1 -1
  41. package/lib/dist-custom-elements/duet-chip.js +1 -273
  42. package/lib/dist-custom-elements/duet-choice-group.js +5 -5
  43. package/lib/dist-custom-elements/duet-choice.js +2 -2
  44. package/lib/dist-custom-elements/duet-collapsible.js +2 -2
  45. package/lib/dist-custom-elements/duet-combobox.js +326 -132
  46. package/lib/dist-custom-elements/duet-cookie-consent.js +1 -1
  47. package/lib/dist-custom-elements/duet-date-picker.js +6 -6
  48. package/lib/dist-custom-elements/duet-editable-table.js +2 -2
  49. package/lib/dist-custom-elements/duet-fieldset.js +1 -1
  50. package/lib/dist-custom-elements/duet-footer.js +1 -1
  51. package/lib/dist-custom-elements/duet-header.js +1 -1
  52. package/lib/dist-custom-elements/duet-hero.js +1 -1
  53. package/lib/dist-custom-elements/duet-input.js +1 -1
  54. package/lib/dist-custom-elements/duet-menu-bar-dropdown-link.js +1 -1
  55. package/lib/dist-custom-elements/duet-menu-bar-dropdown.js +1 -1
  56. package/lib/dist-custom-elements/duet-modal.js +2 -2
  57. package/lib/dist-custom-elements/duet-multiselect.js +5 -5
  58. package/lib/dist-custom-elements/duet-notification-drawer.js +1 -1
  59. package/lib/dist-custom-elements/duet-notification.js +1 -1
  60. package/lib/dist-custom-elements/duet-number-input.js +6 -6
  61. package/lib/dist-custom-elements/duet-pagination.js +6 -6
  62. package/lib/dist-custom-elements/duet-popup-menu.js +1 -1
  63. package/lib/dist-custom-elements/duet-promo-card.js +1 -1
  64. package/lib/dist-custom-elements/duet-radio-group.js +5 -5
  65. package/lib/dist-custom-elements/duet-range-slider.js +1 -1
  66. package/lib/dist-custom-elements/duet-range-stepper.js +2 -2
  67. package/lib/dist-custom-elements/duet-scrollable.js +1 -1
  68. package/lib/dist-custom-elements/duet-select.js +1 -1
  69. package/lib/dist-custom-elements/duet-show-more.js +1 -1
  70. package/lib/dist-custom-elements/duet-slideout-panel.js +1 -1
  71. package/lib/dist-custom-elements/duet-slideout.js +2 -2
  72. package/lib/dist-custom-elements/duet-step.js +1 -1
  73. package/lib/dist-custom-elements/duet-submenu-bar-dropdown-link.js +1 -1
  74. package/lib/dist-custom-elements/duet-submenu-bar-dropdown.js +1 -1
  75. package/lib/dist-custom-elements/duet-submenu-bar-item.js +1 -1
  76. package/lib/dist-custom-elements/duet-submenu-bar-link.js +1 -1
  77. package/lib/dist-custom-elements/duet-tab-group.js +6 -6
  78. package/lib/dist-custom-elements/duet-tab.js +1 -1
  79. package/lib/dist-custom-elements/duet-textarea.js +4 -4
  80. package/lib/dist-custom-elements/duet-toggle.js +1 -1
  81. package/lib/dist-custom-elements/duet-toolbar-dropdown-link.js +1 -1
  82. package/lib/dist-custom-elements/duet-toolbar-dropdown.js +1 -1
  83. package/lib/dist-custom-elements/duet-tooltip-button.js +1 -1
  84. package/lib/dist-custom-elements/duet-tooltip-popup.js +1 -1
  85. package/lib/dist-custom-elements/duet-tooltip.js +1 -1
  86. package/lib/dist-custom-elements/duet-tray.js +1 -1
  87. package/lib/dist-custom-elements/duet-upload-item.js +1 -1
  88. package/lib/dist-custom-elements/duet-upload.js +5 -5
  89. package/lib/dist-custom-elements/{p-cff358b0.js → p-014c1177.js} +49 -8
  90. package/lib/dist-custom-elements/{p-c3d02eb2.js → p-03152b20.js} +1 -1
  91. package/lib/dist-custom-elements/{p-d87f6dd5.js → p-06e608ae.js} +3 -1
  92. package/lib/dist-custom-elements/{p-9cdbc360.js → p-0cee8a12.js} +1 -1
  93. package/lib/dist-custom-elements/{p-12a0876b.js → p-24693e9a.js} +1 -1
  94. package/lib/dist-custom-elements/{p-9a833e56.js → p-28ec3461.js} +1 -1
  95. package/lib/dist-custom-elements/{p-d191ba9e.js → p-45fd4d84.js} +1 -1
  96. package/lib/dist-custom-elements/{p-89d58b60.js → p-6d366100.js} +3 -3
  97. package/lib/dist-custom-elements/p-755dd68f.js +285 -0
  98. package/lib/dist-custom-elements/{p-e44c0eff.js → p-785686e3.js} +1 -1
  99. package/lib/dist-custom-elements/{p-e00d43f3.js → p-92a16064.js} +1 -1
  100. package/lib/dist-custom-elements/{p-f9f9e33d.js → p-a02e62f3.js} +3 -3
  101. package/lib/dist-custom-elements/{p-0d5c0a22.js → p-c8415e2f.js} +1 -1
  102. package/lib/dist-custom-elements/{p-d848b48d.js → p-e702eb52.js} +4 -4
  103. package/lib/duet/duet.esm.js +1 -1
  104. package/lib/duet/{p-88a46585.system.entry.js → p-061f4be0.system.entry.js} +1 -1
  105. package/lib/duet/p-06e608ae.js +4 -0
  106. package/lib/duet/{p-8ca813cb.system.entry.js → p-0778ccde.system.entry.js} +1 -1
  107. package/lib/duet/p-07ac7f3e.system.entry.js +4 -0
  108. package/lib/duet/p-15e24bf0.entry.js +4 -0
  109. package/lib/duet/{p-0dac34a4.system.entry.js → p-1ef0e5ca.system.entry.js} +1 -1
  110. package/lib/duet/{p-c9781f22.entry.js → p-2084a65f.entry.js} +1 -1
  111. package/lib/duet/{p-fd0bb0bf.entry.js → p-23cecf9f.entry.js} +1 -1
  112. package/lib/duet/{p-09e4195f.system.entry.js → p-257800b7.system.entry.js} +1 -1
  113. package/lib/duet/{p-1afd901a.entry.js → p-29491f9f.entry.js} +1 -1
  114. package/lib/duet/{p-3b5ff822.entry.js → p-3302d75d.entry.js} +1 -1
  115. package/lib/duet/{p-7629cd0a.entry.js → p-40375e30.entry.js} +1 -1
  116. package/lib/duet/{p-ba4445cf.system.entry.js → p-45bb3cd0.system.entry.js} +1 -1
  117. package/lib/duet/p-4781cd58.entry.js +4 -0
  118. package/lib/duet/p-4cb5943c.entry.js +4 -0
  119. package/lib/duet/{p-b2f2992f.system.entry.js → p-4de910bd.system.entry.js} +1 -1
  120. package/lib/duet/p-6151635f.system.js +1 -1
  121. package/lib/duet/{p-d349dd93.entry.js → p-67382632.entry.js} +1 -1
  122. package/lib/duet/{p-699a98b4.entry.js → p-76e54ff5.entry.js} +1 -1
  123. package/lib/duet/{p-4d2ef0e2.entry.js → p-7a161455.entry.js} +1 -1
  124. package/lib/duet/{p-3d38079c.entry.js → p-7ca15c93.entry.js} +1 -1
  125. package/lib/duet/{p-bb09fff0.system.entry.js → p-7de614df.system.entry.js} +1 -1
  126. package/lib/duet/{p-480f37b6.entry.js → p-83238fe7.entry.js} +1 -1
  127. package/lib/duet/{p-7c1db591.system.entry.js → p-8a4ba903.system.entry.js} +1 -1
  128. package/lib/duet/{p-4f32a7ee.entry.js → p-8ba91848.entry.js} +1 -1
  129. package/lib/duet/{p-708359ec.system.entry.js → p-999fff8d.system.entry.js} +1 -1
  130. package/lib/duet/{p-9d91a1dd.system.entry.js → p-9e75e5d8.system.entry.js} +1 -1
  131. package/lib/duet/{p-343d037e.entry.js → p-a3afb1af.entry.js} +1 -1
  132. package/lib/duet/{p-2ca6a8a0.system.entry.js → p-a3e90064.system.entry.js} +1 -1
  133. package/lib/duet/{p-892a5644.system.entry.js → p-aba91113.system.entry.js} +1 -1
  134. package/lib/duet/p-ae21ad57.system.js +4 -0
  135. package/lib/duet/{p-ce05fe6d.system.entry.js → p-b2fc4b72.system.entry.js} +1 -1
  136. package/lib/duet/{p-84778369.entry.js → p-b5595969.entry.js} +1 -1
  137. package/lib/duet/{p-bf51f8a5.system.entry.js → p-c68602c9.system.entry.js} +1 -1
  138. package/lib/duet/{p-f6530332.system.entry.js → p-d5721f0d.system.entry.js} +1 -1
  139. package/lib/duet/{p-c00fe4ed.entry.js → p-dc133655.entry.js} +1 -1
  140. package/lib/duet/p-de5054b6.system.entry.js +4 -0
  141. package/lib/duet/{p-61feb701.entry.js → p-df345202.entry.js} +1 -1
  142. package/lib/duet/{p-2628a322.entry.js → p-e0907f29.entry.js} +1 -1
  143. package/lib/duet/p-e333b9fc.system.entry.js +4 -0
  144. package/lib/duet/p-e411627f.entry.js +4 -0
  145. package/lib/duet/{p-da51c71f.system.entry.js → p-eafed149.system.entry.js} +1 -1
  146. package/lib/duet/p-f2279e1e.entry.js +4 -0
  147. package/lib/duet/{p-b1ab1664.system.entry.js → p-fa311641.system.entry.js} +1 -1
  148. package/lib/duet/{p-320318de.system.entry.js → p-fa72c79b.system.entry.js} +1 -1
  149. package/lib/esm/duet-alert.entry.js +1 -1
  150. package/lib/esm/duet-banner.entry.js +1 -1
  151. package/lib/esm/duet-callout.entry.js +1 -1
  152. package/lib/esm/duet-chip.entry.js +9 -2
  153. package/lib/esm/duet-choice_2.entry.js +1 -1
  154. package/lib/esm/duet-collapsible.entry.js +1 -1
  155. package/lib/esm/duet-combobox.entry.js +261 -128
  156. package/lib/esm/duet-date-picker.entry.js +1 -1
  157. package/lib/esm/duet-fieldset.entry.js +1 -1
  158. package/lib/esm/duet-hero.entry.js +1 -1
  159. package/lib/esm/duet-input_2.entry.js +39 -3
  160. package/lib/esm/duet-modal.entry.js +1 -1
  161. package/lib/esm/duet-multiselect.entry.js +1 -1
  162. package/lib/esm/duet-number-input.entry.js +1 -1
  163. package/lib/esm/duet-promo-card.entry.js +1 -1
  164. package/lib/esm/duet-radio_2.entry.js +1 -1
  165. package/lib/esm/duet-scrollable_3.entry.js +1 -1
  166. package/lib/esm/duet-select.entry.js +1 -1
  167. package/lib/esm/duet-slideout-panel.entry.js +1 -1
  168. package/lib/esm/duet-slideout.entry.js +1 -1
  169. package/lib/esm/duet-textarea.entry.js +1 -1
  170. package/lib/esm/duet.js +1 -1
  171. package/lib/esm/loader.js +1 -1
  172. package/lib/esm/{slot-utils-1115a819.js → slot-utils-b50aaef5.js} +3 -1
  173. package/lib/esm-es5/duet-alert.entry.js +1 -1
  174. package/lib/esm-es5/duet-banner.entry.js +1 -1
  175. package/lib/esm-es5/duet-callout.entry.js +1 -1
  176. package/lib/esm-es5/duet-chip.entry.js +1 -1
  177. package/lib/esm-es5/duet-choice_2.entry.js +1 -1
  178. package/lib/esm-es5/duet-collapsible.entry.js +1 -1
  179. package/lib/esm-es5/duet-combobox.entry.js +2 -2
  180. package/lib/esm-es5/duet-date-picker.entry.js +1 -1
  181. package/lib/esm-es5/duet-fieldset.entry.js +1 -1
  182. package/lib/esm-es5/duet-hero.entry.js +1 -1
  183. package/lib/esm-es5/duet-input_2.entry.js +2 -2
  184. package/lib/esm-es5/duet-modal.entry.js +1 -1
  185. package/lib/esm-es5/duet-multiselect.entry.js +1 -1
  186. package/lib/esm-es5/duet-number-input.entry.js +2 -2
  187. package/lib/esm-es5/duet-promo-card.entry.js +2 -2
  188. package/lib/esm-es5/duet-radio_2.entry.js +1 -1
  189. package/lib/esm-es5/duet-scrollable_3.entry.js +1 -1
  190. package/lib/esm-es5/duet-select.entry.js +1 -1
  191. package/lib/esm-es5/duet-slideout-panel.entry.js +1 -1
  192. package/lib/esm-es5/duet-slideout.entry.js +1 -1
  193. package/lib/esm-es5/duet-textarea.entry.js +1 -1
  194. package/lib/esm-es5/duet.js +1 -1
  195. package/lib/esm-es5/loader.js +1 -1
  196. package/lib/esm-es5/slot-utils-b50aaef5.js +4 -0
  197. package/lib/types/components/duet-chip/duet-chip.d.ts +4 -0
  198. package/lib/types/components/duet-combobox/duet-combobox.d.ts +49 -35
  199. package/lib/types/components/duet-input/duet-input.d.ts +30 -0
  200. package/lib/types/components.d.ts +44 -21
  201. package/package.json +2 -2
  202. package/lib/duet/p-7cf03aa8.system.js +0 -4
  203. package/lib/duet/p-92e1181c.entry.js +0 -4
  204. package/lib/duet/p-985c0c67.system.entry.js +0 -4
  205. package/lib/duet/p-9d27bc65.entry.js +0 -4
  206. package/lib/duet/p-afe29a3e.entry.js +0 -4
  207. package/lib/duet/p-cc4a8964.entry.js +0 -4
  208. package/lib/duet/p-d50ad3ed.entry.js +0 -4
  209. package/lib/duet/p-d87f6dd5.js +0 -4
  210. package/lib/duet/p-f1b01db9.system.entry.js +0 -4
  211. package/lib/duet/p-fa21a3b6.system.entry.js +0 -4
  212. package/lib/esm-es5/slot-utils-1115a819.js +0 -4
@@ -11,14 +11,15 @@ const createId = require('./create-id-1f8c438f.js');
11
11
  const jsUtils = require('./js-utils-92e24ba1.js');
12
12
  const keyboardUtils = require('./keyboard-utils-681e11ec.js');
13
13
  const languageUtils = require('./language-utils-e8a527e5.js');
14
+ const slotUtils = require('./slot-utils-03a40c78.js');
14
15
  const stringUtils = require('./string-utils-053749ff.js');
15
16
 
16
17
  const SelectSingle = ({ item, search = "", selected }) => {
17
- const regEx = search !== "" ? new RegExp("(" + search.split(" ").join("|") + ")", "gi") : undefined;
18
+ const regEx = search !== "" ? new RegExp("(" + search.split(" ").join("|") + ")", "i") : undefined;
18
19
  return (index.h(index.Fragment, null,
19
20
  selected && index.h("duet-icon", { class: "option-icon", name: "messaging-checked", size: "xx-small", margin: "none" }),
20
21
  regEx ? (index.h("span", { class: "option-container", "aria-hidden": "true" },
21
- index.h("span", { innerHTML: item.name.replace(regEx, '<span class="highlight">$&</span>') }))) : (item.name),
22
+ index.h("span", { innerHTML: item.name.replace(regEx, '<span class="highlight sc-duet-combobox">$&</span>') }))) : (item.name),
22
23
  item.tags && index.h("span", { class: "option-tags" }, item.tags.join(", "))));
23
24
  };
24
25
 
@@ -37,7 +38,7 @@ const DuetComboBoxSelect = ({ item, active, total, selected, label = undefined,
37
38
  index.h(SelectSingle, { item: item, search: search, selected: selected }))));
38
39
  };
39
40
 
40
- const duetComboboxCss = ".sc-duet-combobox-h{box-sizing:border-box;padding:0;margin:0;background:transparent;border:0;-moz-appearance:none;-webkit-appearance:none;appearance:none;position:relative;display:inline-block;width:100%;font-family:\"localtapiola-sans\", -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\";color:rgb(0, 41, 77)}.sc-duet-combobox-h a.sc-duet-combobox{color:rgb(0, 41, 77);transition:none}.duet-theme-turva.sc-duet-combobox-h{font-family:\"turva-sans\", -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\";color:rgb(23, 28, 58)}.duet-theme-turva.sc-duet-combobox-h a.sc-duet-combobox{color:rgb(23, 28, 58)}.duet-theme-turva.sc-duet-combobox-h .duet-combobox-list.sc-duet-combobox .duet-combobox-listbox.sc-duet-combobox .list-item.option.sc-duet-combobox .option-tags.sc-duet-combobox{color:rgb(116, 116, 117)}.duet-theme-turva.sc-duet-combobox-h .duet-combobox-list.sc-duet-combobox .duet-combobox-listbox.sc-duet-combobox .list-item.option.selected.sc-duet-combobox{background:rgb(244, 207, 214)}.duet-theme-turva.sc-duet-combobox-h .duet-combobox-list.sc-duet-combobox .duet-combobox-listbox.sc-duet-combobox .list-item.active.sc-duet-combobox,.duet-theme-turva.sc-duet-combobox-h .duet-combobox-list.sc-duet-combobox .duet-combobox-listbox.sc-duet-combobox .list-item.sc-duet-combobox:focus,.duet-theme-turva.sc-duet-combobox-h .duet-combobox-list.sc-duet-combobox .duet-combobox-listbox.sc-duet-combobox .list-item.sc-duet-combobox:hover{color:rgb(255, 255, 255);background:rgb(198, 12, 48)}.duet-theme-turva.sc-duet-combobox-h .duet-combobox-list.sc-duet-combobox .duet-combobox-listbox.sc-duet-combobox .list-item.active.sc-duet-combobox .option-tags.sc-duet-combobox,.duet-theme-turva.sc-duet-combobox-h .duet-combobox-list.sc-duet-combobox .duet-combobox-listbox.sc-duet-combobox .list-item.sc-duet-combobox:focus .option-tags.sc-duet-combobox,.duet-theme-turva.sc-duet-combobox-h .duet-combobox-list.sc-duet-combobox .duet-combobox-listbox.sc-duet-combobox .list-item.sc-duet-combobox:hover .option-tags.sc-duet-combobox{color:rgb(255, 255, 255)}.duet-theme-turva.sc-duet-combobox-h .duet-combobox-list.sc-duet-combobox .duet-combobox-listbox.sc-duet-combobox .list-item.active.sc-duet-combobox a.sc-duet-combobox,.duet-theme-turva.sc-duet-combobox-h .duet-combobox-list.sc-duet-combobox .duet-combobox-listbox.sc-duet-combobox .list-item.sc-duet-combobox:focus a.sc-duet-combobox,.duet-theme-turva.sc-duet-combobox-h .duet-combobox-list.sc-duet-combobox .duet-combobox-listbox.sc-duet-combobox .list-item.sc-duet-combobox:hover a.sc-duet-combobox{color:rgb(255, 255, 255)}.duet-combobox-list.sc-duet-combobox{position:absolute;top:calc(100% - 12px);z-index:700;display:none;background:rgb(255, 255, 255);border-radius:0 4px;box-shadow:0 2px 10px 0 rgba(0, 41, 77, 0.1)}.duet-combobox-list.open.sc-duet-combobox{display:block}.duet-combobox-list.sc-duet-combobox .duet-combobox-listbox.sc-duet-combobox{max-height:200px;padding:0.75rem 0;margin:0;overflow-y:scroll;font-weight:600;list-style:none;cursor:pointer;scroll-behavior:smooth}.duet-combobox-list.sc-duet-combobox .duet-combobox-listbox.sc-duet-combobox .list-item.sc-duet-combobox{padding:4px 0}.duet-combobox-list.sc-duet-combobox .duet-combobox-listbox.sc-duet-combobox .list-item.sc-duet-combobox:not(.selected){padding-left:16px}.duet-combobox-list.sc-duet-combobox .duet-combobox-listbox.sc-duet-combobox .list-item.sc-duet-combobox:not(.selected) .highlight.sc-duet-combobox{text-decoration:underline}.duet-combobox-list.sc-duet-combobox .duet-combobox-listbox.sc-duet-combobox .list-item.option.sc-duet-combobox .option-link.sc-duet-combobox{display:block;width:100%}.duet-combobox-list.sc-duet-combobox .duet-combobox-listbox.sc-duet-combobox .list-item.option.sc-duet-combobox .option-tags.sc-duet-combobox{float:right;padding-right:0.875rem;font-weight:400;color:rgb(144, 149, 153)}.duet-combobox-list.sc-duet-combobox .duet-combobox-listbox.sc-duet-combobox .list-item.option-link.sc-duet-combobox{display:block;width:100%}.duet-combobox-list.sc-duet-combobox .duet-combobox-listbox.sc-duet-combobox .list-item.selected.sc-duet-combobox{padding-left:0;background:rgb(205, 229, 241)}.duet-combobox-list.sc-duet-combobox .duet-combobox-listbox.sc-duet-combobox .list-item.selected.option.sc-duet-combobox .option-icon.sc-duet-combobox{padding:0 8px 0 8px}.duet-combobox-list.sc-duet-combobox .duet-combobox-listbox.sc-duet-combobox .list-item.selected.option.sc-duet-combobox .option-tags.sc-duet-combobox{color:rgb(144, 149, 153)}.duet-combobox-list.sc-duet-combobox .duet-combobox-listbox.sc-duet-combobox .list-item.active.sc-duet-combobox,.duet-combobox-list.sc-duet-combobox .duet-combobox-listbox.sc-duet-combobox .list-item.sc-duet-combobox:focus,.duet-combobox-list.sc-duet-combobox .duet-combobox-listbox.sc-duet-combobox .list-item.sc-duet-combobox:hover{color:rgb(255, 255, 255);background:rgb(0, 119, 179)}.duet-combobox-list.sc-duet-combobox .duet-combobox-listbox.sc-duet-combobox .list-item.active.sc-duet-combobox .option-tags.sc-duet-combobox,.duet-combobox-list.sc-duet-combobox .duet-combobox-listbox.sc-duet-combobox .list-item.sc-duet-combobox:focus .option-tags.sc-duet-combobox,.duet-combobox-list.sc-duet-combobox .duet-combobox-listbox.sc-duet-combobox .list-item.sc-duet-combobox:hover .option-tags.sc-duet-combobox{color:rgb(255, 255, 255)}.duet-combobox-list.sc-duet-combobox .duet-combobox-listbox.sc-duet-combobox .list-item.active.sc-duet-combobox a.sc-duet-combobox,.duet-combobox-list.sc-duet-combobox .duet-combobox-listbox.sc-duet-combobox .list-item.sc-duet-combobox:focus a.sc-duet-combobox,.duet-combobox-list.sc-duet-combobox .duet-combobox-listbox.sc-duet-combobox .list-item.sc-duet-combobox:hover a.sc-duet-combobox{color:rgb(255, 255, 255)}";
41
+ const duetComboboxCss = ".sc-duet-combobox-h{box-sizing:border-box;padding:0;margin:0;background:transparent;border:0;-moz-appearance:none;-webkit-appearance:none;appearance:none;position:relative;display:inline-block;width:100%;font-family:\"localtapiola-sans\", -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\";color:rgb(0, 41, 77)}.sc-duet-combobox-h a.sc-duet-combobox{color:rgb(0, 41, 77);transition:none}.duet-theme-turva.sc-duet-combobox-h{font-family:\"turva-sans\", -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\";color:rgb(23, 28, 58)}.duet-theme-turva.sc-duet-combobox-h a.sc-duet-combobox{color:rgb(23, 28, 58)}.duet-theme-turva.sc-duet-combobox-h .duet-combobox-list.sc-duet-combobox .duet-combobox-listbox.sc-duet-combobox .list-item.option.sc-duet-combobox .option-tags.sc-duet-combobox{color:rgb(116, 116, 117)}.duet-theme-turva.sc-duet-combobox-h .duet-combobox-list.sc-duet-combobox .duet-combobox-listbox.sc-duet-combobox .list-item.option.selected.sc-duet-combobox{background:rgb(244, 207, 214)}.duet-theme-turva.sc-duet-combobox-h .duet-combobox-list.sc-duet-combobox .duet-combobox-listbox.sc-duet-combobox .list-item.active.sc-duet-combobox,.duet-theme-turva.sc-duet-combobox-h .duet-combobox-list.sc-duet-combobox .duet-combobox-listbox.sc-duet-combobox .list-item.sc-duet-combobox:focus,.duet-theme-turva.sc-duet-combobox-h .duet-combobox-list.sc-duet-combobox .duet-combobox-listbox.sc-duet-combobox .list-item.sc-duet-combobox:hover{color:rgb(255, 255, 255);background:rgb(198, 12, 48)}.duet-theme-turva.sc-duet-combobox-h .duet-combobox-list.sc-duet-combobox .duet-combobox-listbox.sc-duet-combobox .list-item.active.sc-duet-combobox .option-tags.sc-duet-combobox,.duet-theme-turva.sc-duet-combobox-h .duet-combobox-list.sc-duet-combobox .duet-combobox-listbox.sc-duet-combobox .list-item.sc-duet-combobox:focus .option-tags.sc-duet-combobox,.duet-theme-turva.sc-duet-combobox-h .duet-combobox-list.sc-duet-combobox .duet-combobox-listbox.sc-duet-combobox .list-item.sc-duet-combobox:hover .option-tags.sc-duet-combobox{color:rgb(255, 255, 255)}.duet-theme-turva.sc-duet-combobox-h .duet-combobox-list.sc-duet-combobox .duet-combobox-listbox.sc-duet-combobox .list-item.active.sc-duet-combobox a.sc-duet-combobox,.duet-theme-turva.sc-duet-combobox-h .duet-combobox-list.sc-duet-combobox .duet-combobox-listbox.sc-duet-combobox .list-item.sc-duet-combobox:focus a.sc-duet-combobox,.duet-theme-turva.sc-duet-combobox-h .duet-combobox-list.sc-duet-combobox .duet-combobox-listbox.sc-duet-combobox .list-item.sc-duet-combobox:hover a.sc-duet-combobox{color:rgb(255, 255, 255)}.duet-combobox-list.sc-duet-combobox{position:absolute;top:calc(100% - 12px);z-index:700;margin:8px 0 0;visibility:hidden;background:rgb(255, 255, 255);border-radius:0 4px;box-shadow:0 2px 10px 0 rgba(0, 41, 77, 0.1);opacity:0;transition:transform 300ms ease, opacity 300ms ease, visibility 300ms ease;transform:scale(0.96) translateZ(0) translateY(-20px);transform-origin:top right}.duet-combobox-list.open.sc-duet-combobox{visibility:visible;opacity:1;transition-property:transform, opacity;transform:scale(1.0001) translateZ(0) translateY(0)}.duet-combobox-list.sc-duet-combobox .duet-combobox-listbox.sc-duet-combobox{max-height:200px;padding:0.75rem 0;margin:0;overflow-y:scroll;font-weight:600;list-style:none;cursor:pointer;scroll-behavior:smooth}.duet-combobox-list.sc-duet-combobox .duet-combobox-listbox.sc-duet-combobox .list-item.sc-duet-combobox{padding:4px 0}.duet-combobox-list.sc-duet-combobox .duet-combobox-listbox.sc-duet-combobox .list-item.sc-duet-combobox:not(.selected){padding-left:16px}.duet-combobox-list.sc-duet-combobox .duet-combobox-listbox.sc-duet-combobox .list-item.sc-duet-combobox:not(.selected) .highlight.sc-duet-combobox{text-decoration:underline}.duet-combobox-list.sc-duet-combobox .duet-combobox-listbox.sc-duet-combobox .list-item.option.sc-duet-combobox .option-link.sc-duet-combobox{display:block;width:100%}.duet-combobox-list.sc-duet-combobox .duet-combobox-listbox.sc-duet-combobox .list-item.option.sc-duet-combobox .option-tags.sc-duet-combobox{float:right;padding-right:0.875rem;font-weight:400;color:rgb(144, 149, 153)}.duet-combobox-list.sc-duet-combobox .duet-combobox-listbox.sc-duet-combobox .list-item.option-link.sc-duet-combobox{display:block;width:100%}.duet-combobox-list.sc-duet-combobox .duet-combobox-listbox.sc-duet-combobox .list-item.selected.sc-duet-combobox{padding-left:0;background:rgb(205, 229, 241)}.duet-combobox-list.sc-duet-combobox .duet-combobox-listbox.sc-duet-combobox .list-item.selected.option.sc-duet-combobox .option-icon.sc-duet-combobox{padding:0 8px 0 8px}.duet-combobox-list.sc-duet-combobox .duet-combobox-listbox.sc-duet-combobox .list-item.selected.option.sc-duet-combobox .option-tags.sc-duet-combobox{color:rgb(144, 149, 153)}.duet-combobox-list.sc-duet-combobox .duet-combobox-listbox.sc-duet-combobox .list-item.active.sc-duet-combobox,.duet-combobox-list.sc-duet-combobox .duet-combobox-listbox.sc-duet-combobox .list-item.sc-duet-combobox:focus,.duet-combobox-list.sc-duet-combobox .duet-combobox-listbox.sc-duet-combobox .list-item.sc-duet-combobox:hover{color:rgb(255, 255, 255);background:rgb(0, 119, 179)}.duet-combobox-list.sc-duet-combobox .duet-combobox-listbox.sc-duet-combobox .list-item.active.sc-duet-combobox .option-tags.sc-duet-combobox,.duet-combobox-list.sc-duet-combobox .duet-combobox-listbox.sc-duet-combobox .list-item.sc-duet-combobox:focus .option-tags.sc-duet-combobox,.duet-combobox-list.sc-duet-combobox .duet-combobox-listbox.sc-duet-combobox .list-item.sc-duet-combobox:hover .option-tags.sc-duet-combobox{color:rgb(255, 255, 255)}.duet-combobox-list.sc-duet-combobox .duet-combobox-listbox.sc-duet-combobox .list-item.active.sc-duet-combobox a.sc-duet-combobox,.duet-combobox-list.sc-duet-combobox .duet-combobox-listbox.sc-duet-combobox .list-item.sc-duet-combobox:focus a.sc-duet-combobox,.duet-combobox-list.sc-duet-combobox .duet-combobox-listbox.sc-duet-combobox .list-item.sc-duet-combobox:hover a.sc-duet-combobox{color:rgb(255, 255, 255)}";
41
42
 
42
43
  const DuetCombobox = class {
43
44
  constructor(hostRef) {
@@ -53,24 +54,63 @@ const DuetCombobox = class {
53
54
  // this.listElement.style.width = `${currentWidth + 1}px`
54
55
  }
55
56
  }, 100));
56
- this.handleInputKeyDownEvent = (e) => {
57
+ this.onInputChange = async (e) => {
58
+ const newValue = e.detail.value;
59
+ this.inputValue = newValue;
60
+ };
61
+ this.onInputClick = () => {
62
+ var _a, _b;
63
+ if (this.openListOnClick) {
64
+ this.listOpen = !this.listOpen;
65
+ }
66
+ else {
67
+ this.listOpen = ((_a = this.inputValue) === null || _a === void 0 ? void 0 : _a.length) >= this.minCharacters;
68
+ }
69
+ if (!((_b = this.getFilteredItems()) === null || _b === void 0 ? void 0 : _b.length)) {
70
+ this.listOpen = false;
71
+ }
72
+ };
73
+ this.onInputTyping = async (e) => {
74
+ var _a;
75
+ const newValue = e.detail.value;
76
+ if (!this.force && !this.multiple && this.selectedItems.size > 0 && newValue !== this.getSelectedItemLabel()) {
77
+ this.selectedItems.clear();
78
+ }
79
+ this.listOpen = String(newValue).length >= this.minCharacters && ((_a = this.getFilteredItems()) === null || _a === void 0 ? void 0 : _a.length) > 0;
80
+ };
81
+ this.onKeyDown = (e) => {
57
82
  //if selection is made, close the list and update internal and external values
83
+ const listItems = this.returnFilteredOrNonFiltered();
58
84
  // this should be set to undefined on everything BUT up/down arrow according to the aria 1.1 specs
59
85
  // https://www.w3.org/TR/wai-aria-practices-1.1/#combobox
60
86
  this.input.accessibleActiveDescendant = undefined;
61
87
  if (keyboardUtils.isEnterKey(e)) {
62
88
  e.preventDefault();
63
- this.selectActiveItem();
64
- this.updateInputText(false);
89
+ if (this.listOpen && this.activeItem !== undefined && listItems[this.activeItem]) {
90
+ if (this.multiple) {
91
+ this.addSelectedItem(listItems[this.activeItem].id, true);
92
+ }
93
+ else {
94
+ this.updateSelectedItem(listItems[this.activeItem].id, true);
95
+ }
96
+ }
97
+ this.activeItem = undefined;
65
98
  this.listOpen = false;
66
99
  return;
67
100
  }
68
- //tabbing out or escaping, restore initial state
69
101
  if (keyboardUtils.isEscapeKey(e) || keyboardUtils.isTabKey(e)) {
70
102
  this.updateInputText(true);
103
+ this.activeItem = undefined;
71
104
  this.listOpen = false;
72
105
  return;
73
106
  }
107
+ if (keyboardUtils.isBackspaceKey(e) && this.inputValue === "") {
108
+ if (this.multiple && this.selectedItems.size > 0) {
109
+ const lastItem = Array.from(this.selectedItems).pop();
110
+ this.removeSelectedItem(lastItem, true);
111
+ }
112
+ return;
113
+ }
74
114
  //handle arrow up/down navigation
75
115
  let nextActiveItem = this.activeItem;
76
116
  if (keyboardUtils.isArrowUpKey(e)) {
@@ -83,7 +123,6 @@ const DuetCombobox = class {
83
123
  this.listOpen = true;
84
124
  }
85
125
  if (keyboardUtils.isArrowDownKey(e) || keyboardUtils.isArrowUpKey(e)) {
86
- const listItems = this.shouldListBeFiltered() ? this.getFilteredItems() : this.processedItems;
87
126
  if (nextActiveItem < 0 || !nextActiveItem) {
88
127
  nextActiveItem = 0;
89
128
  }
@@ -96,13 +135,10 @@ const DuetCombobox = class {
96
135
  this.activeItem = nextActiveItem;
97
136
  this.scrollToActive();
98
137
  }
99
- this.announceActive();
100
138
  return;
101
139
  };
102
140
  this.processedItems = null;
103
- this.inputWidth = 0;
104
141
  this.inputValue = "";
105
- this.selectionMsg = "";
106
142
  this.listOpen = false;
107
143
  this.selectedItems = new Set();
108
144
  this.activeItem = undefined;
@@ -124,8 +160,11 @@ const DuetCombobox = class {
124
160
  },
125
161
  };
126
162
  this.accessibleLabels = languageUtils.getLocaleString(this.accessibleLabelDefaults, languageUtils.getLanguage());
163
+ this.label = "";
164
+ this.caption = "";
127
165
  this.theme = "";
128
166
  this.force = false;
167
+ this.multiple = false;
129
168
  this.items = undefined;
130
169
  this.formatter = (item) => item && item.name ? item.name : "";
131
170
  this.value = undefined;
@@ -141,7 +180,7 @@ const DuetCombobox = class {
141
180
  const path = e.composedPath();
142
181
  const isClickOutside = path.every(el => el !== this.element);
143
182
  if (isClickOutside) {
144
- this.updateInputText(true, true);
183
+ this.updateInputText(true);
145
184
  this.listOpen = false;
146
185
  }
147
186
  }
@@ -152,17 +191,67 @@ const DuetCombobox = class {
152
191
  async formatItem(item) {
153
192
  return this.formatter(item);
154
193
  }
155
- async processItems() {
156
- this.items = this.processedItems = stringUtils.parsePossibleJSON(this.items);
157
- await this.updateInputText();
194
+ processItems() {
195
+ const ids = [];
196
+ this.processedItems = stringUtils.parsePossibleJSON(this.items);
197
+ if (!Array.isArray(this.processedItems)) {
198
+ console.error("DuetCombobox: Items should be an array");
199
+ return;
200
+ }
201
+ if (this.processedItems.length !== new Set([...this.processedItems]).size) {
202
+ console.warn("DuetCombobox: Duplicate item values found in the list");
203
+ }
204
+ this.processedItems = this.processedItems.map((item, index) => {
205
+ if (typeof item === "string") {
206
+ item = { name: item, value: item };
207
+ }
208
+ if (item.id !== undefined) {
209
+ item.id = String(item.id);
210
+ }
211
+ else {
212
+ item.id = `${JSON.stringify(item.value)}-${item.name}`;
213
+ }
214
+ if (ids.includes(item.id)) {
215
+ console.warn("DuetCombobox: Duplicate item id found in the list, postfixed with index");
216
+ item.id = `${item.id}-${index}`;
217
+ }
218
+ ids.push(item.id);
219
+ return item;
220
+ });
221
+ // remove any item selections that are no longer in the items list
222
+ const selectionsMissing = Array.from(this.selectedItems).filter(id => !this.processedItems.find(item => item.id === id));
223
+ if (selectionsMissing.length) {
224
+ if (this.multiple) {
225
+ selectionsMissing.forEach(id => this.removeSelectedItem(id));
226
+ }
227
+ else {
228
+ this.updateSelectedItem(selectionsMissing[0], true);
229
+ }
230
+ }
158
231
  }
159
- async processValue() {
160
- if (this.value) {
161
- const selectedItem = this.items.find(item => item.value === this.value);
162
- this.updateSelectedItems(selectedItem.id);
232
+ processValue() {
233
+ // empty string may be valid item value
234
+ if (this.value !== "" && !this.value) {
235
+ this.selectedItems.clear();
236
+ return;
237
+ }
238
+ const values = Array.isArray(this.value) ? this.value : [this.value];
239
+ const ids = this.processedItems.filter(item => values.includes(item.value)).map(item => item.id);
240
+ // if value corresponds to the selectedItems, do nothing
241
+ if (ids.length === this.selectedItems.size && ids.every(id => this.selectedItems.has(id))) {
242
+ return;
243
+ }
244
+ if (this.multiple) {
245
+ this.selectedItems.clear();
246
+ this.input.clearChips();
247
+ ids.forEach(id => this.addSelectedItem(id));
248
+ }
249
+ else {
250
+ const selectedItem = this.processedItems.find(item => item.value === this.value);
251
+ this.updateSelectedItem(selectedItem.id);
163
252
  }
164
253
  }
165
- async processListOpenChange() {
254
+ processListOpenChange() {
166
255
  if (this.openListOnClick) {
167
256
  this.input.icon = this.listOpen ? "action-arrow-up" : "action-arrow-down";
168
257
  }
@@ -175,63 +264,51 @@ const DuetCombobox = class {
175
264
  themeableComponent.inheritGlobalTheme(this);
176
265
  }
177
266
  connectedCallback() {
178
- this.items = this.processedItems = stringUtils.parsePossibleJSON(this.items);
179
- this.input = this.element.querySelector("duet-input");
180
- this.input.addEventListener("duetChange", this.updateInputValue.bind(this));
181
- this.input.addEventListener("click", () => {
182
- if (!this.openListOnClick) {
183
- this.inputValue.length >= this.minCharacters ? (this.listOpen = true) : (this.listOpen = false);
184
- }
185
- else {
186
- this.listOpen = !this.listOpen;
187
- }
188
- });
189
- this.element.addEventListener("keydown", this.handleInputKeyDownEvent);
190
- languageUtils.connectLanguageChangeObserver(this, { prop: "accessibleLabels", defaults: "accessibleLabelDefaults" });
267
+ if (this.items) {
268
+ this.processItems();
269
+ }
270
+ const slottedElements = slotUtils.getElementsFromDefaultSlot(this.element);
271
+ if (slottedElements.length) {
272
+ this.input = slottedElements[0];
273
+ }
274
+ else {
275
+ this.input = document.createElement("duet-input");
276
+ this.input.label = this.label;
277
+ this.input.caption = this.caption;
278
+ this.input.expand = true;
279
+ this.element.prepend(this.input);
280
+ }
281
+ this.input.chips = this.multiple;
282
+ this.input.addEventListener("duetChange", this.onInputChange);
283
+ this.input.addEventListener("duetInput", this.onInputTyping);
284
+ this.input.addEventListener("click", this.onInputClick);
191
285
  //add correct aria attributes to the input element
192
286
  this.input.role = "combobox";
193
287
  this.input.accessibleExpanded = this.listOpen ? "true" : "false";
194
288
  this.input.accessibleAutocomplete = "list";
195
289
  this.input.accessibleControls = this.listBoxId;
290
+ this.element.addEventListener("keydown", this.onKeyDown);
291
+ languageUtils.connectLanguageChangeObserver(this, { prop: "accessibleLabels", defaults: "accessibleLabelDefaults" });
196
292
  this.processListOpenChange();
197
293
  }
198
294
  disconnectedCallback() {
199
- this.input.removeEventListener("duetChange", this.updateInputValue.bind(this));
200
- this.input.removeEventListener("click", () => this.inputValue.length ? (this.listOpen = true) : (this.listOpen = false));
201
- this.element.removeEventListener("keydown", this.handleInputKeyDownEvent);
202
- this.listElement.removeEventListener("click", e => {
203
- e.stopPropagation();
204
- });
295
+ this.input.removeEventListener("duetChange", this.onInputChange);
296
+ this.input.removeEventListener("click", this.onInputClick);
297
+ this.element.removeEventListener("keydown", this.onKeyDown);
205
298
  this.resizeObserver.disconnect();
206
299
  languageUtils.disconnectLanguageChangeObserver(this);
207
300
  }
208
301
  componentDidLoad() {
209
302
  // observe resize events to dynamically adjust size of dropdown area
210
303
  this.resizeObserver.observe(this.input);
211
- this.listElement.addEventListener("click", e => {
212
- e.stopPropagation();
213
- });
214
304
  this.processValue();
215
305
  }
216
- /**
217
- * Updates the input text based on the selected/clicked items.
218
- * @param event - event
219
- *'param item: DuetComboboxItem - the item that was selected
220
- */
221
- onListClick(e, item) {
222
- e.preventDefault();
223
- // update selected item with id
224
- this.updateSelectedItems(item.id, true);
225
- this.listOpen = false;
226
- return this.listOpen;
227
- }
228
306
  /**
229
307
  * Helper function that checks inputs in the field, compares it with the item list and returns true when inputvalue matches selectedItem id
230
- * TODO: this should be disabled in multiple mode
231
308
  */
232
309
  shouldListBeFiltered() {
233
- if (this.selectedItems.size && this.input.value === this.inputValue) {
234
- const item = this.items.filter(item => this.selectedItems.has(item.id));
310
+ if (!this.multiple && this.selectedItems.size && this.input.value === this.inputValue) {
311
+ const item = this.processedItems.find(item => this.selectedItems.has(item.id));
235
312
  return !(this.formatter(item).toLowerCase() === this.input.value.toLowerCase());
236
313
  }
237
314
  return true;
@@ -246,91 +323,135 @@ const DuetCombobox = class {
246
323
  : this.sortFilteredItems(this.processedItems)
247
324
  : [];
248
325
  }
326
+ emitChangeEvent(id) {
327
+ const item = this.processedItems.find(item => item.id === id);
328
+ this.duetChange.emit({
329
+ item,
330
+ value: this.value,
331
+ component: "duet-combobox",
332
+ });
333
+ }
249
334
  /**
250
- * Updates the selected items based on the item id.
251
- * @param id
252
- * @private
335
+ * Updates the value after selected items have changed for multiple selection.
253
336
  */
254
- async updateSelectedItems(id, emitEvent) {
255
- // for a multiple scenario wrap this in an if/else and just don't clear here
256
- this.selectedItems.clear();
257
- if (this.selectedItems) {
258
- if (this.selectedItems.has(id)) {
259
- this.selectedItems.delete(id);
260
- }
261
- else {
262
- this.selectedItems.add(id);
263
- }
337
+ updateMultipleValue() {
338
+ this.value = this.processedItems.filter(item => this.selectedItems.has(item.id)).map(item => item.value);
339
+ this.input.value = "";
340
+ this.updateChips();
341
+ }
342
+ /**
343
+ * Add item with id to the selectedItems set. Used only when multiple is true.
344
+ */
345
+ addSelectedItem(id, emitEvent) {
346
+ if (this.selectedItems.has(id)) {
347
+ return;
264
348
  }
349
+ this.selectedItems.add(id);
350
+ this.updateMultipleValue();
265
351
  if (emitEvent) {
266
- const item = this.selectedItems.size === 0 ? [] : this.items.filter(item => this.selectedItems.has(item.id));
267
- this.duetChange.emit({
268
- value: item[0].value,
269
- item: item[0],
270
- component: "duet-combobox",
271
- });
352
+ this.emitChangeEvent(id);
272
353
  }
273
- await this.updateInputText();
274
354
  }
275
355
  /**
276
- * Updates the input text based on the selected/clicked items.
277
- * @param bool -override to clear if invoked by "click outside"
356
+ * Remove item with id from the selectedItems set. Used only when multiple is true.
278
357
  */
279
- async updateInputText(isBlurred = false, isClickOutside = false) {
280
- const item = this.selectedItems.size === 0 ? [] : this.items.filter(item => this.selectedItems.has(item.id));
281
- //if items changed and given id no longer exists
282
- if (item.length === 0 && this.selectedItems.size > 0) {
283
- this.selectedItems.clear();
284
- this.input.value = "";
358
+ removeSelectedItem(id, emitEvent) {
359
+ if (!this.selectedItems.has(id)) {
360
+ return;
361
+ }
362
+ this.selectedItems.delete(id);
363
+ this.updateMultipleValue();
364
+ if (emitEvent) {
365
+ this.emitChangeEvent(id);
366
+ }
367
+ }
368
+ /**
369
+ * Updates the selected item based on the item id. Used only when multiple is false.
370
+ */
371
+ async updateSelectedItem(id, emitEvent) {
372
+ if (this.selectedItems.has(id)) {
373
+ this.selectedItems.delete(id);
285
374
  this.value = undefined;
286
- this.activeItem = undefined;
287
375
  }
288
- if (!isClickOutside && this.selectedItems.size === 1) {
289
- this.input.value = ""; // set value to empty so that cursor position follows accordingly
290
- this.input.value = await this.formatItem(item[0]);
291
- this.input.scrollLeft = this.input.scrollWidth;
292
- this.activeItem = undefined;
293
- this.value = item[0].value;
376
+ else {
377
+ this.selectedItems.clear();
378
+ this.selectedItems.add(id);
379
+ this.value = this.processedItems.find(item => item.id === id).value;
294
380
  }
295
- if (isBlurred) {
296
- if (this.selectedItems.size === 0) {
297
- this.activeItem = undefined;
298
- if (this.force) {
299
- this.inputValue = "";
300
- this.input.value = "";
301
- }
381
+ if (emitEvent) {
382
+ this.emitChangeEvent(id);
383
+ }
384
+ await this.updateInputText();
385
+ }
386
+ /**
387
+ * Add or remove chips of the input based on the selectedItems Set.
388
+ */
389
+ async updateChips() {
390
+ const ids = Array.from(this.selectedItems);
391
+ const chips = await this.input.getChips();
392
+ ids.forEach(async (id) => {
393
+ const item = this.processedItems.find(i => i.id === id);
394
+ const text = await this.formatItem(item);
395
+ const chipExists = await this.input.hasChip({ value: `${id}`, text });
396
+ if (!chipExists) {
397
+ const chip = document.createElement("duet-chip");
398
+ chip.variation = "input";
399
+ chip.value = `${id}`;
400
+ chip.textContent = text;
401
+ chip.addEventListener("duetRemove", evt => {
402
+ const id = evt.detail.value;
403
+ this.removeSelectedItem(id, true);
404
+ });
405
+ this.input.addChip(chip);
302
406
  }
303
- else if (this.force) {
304
- const selectedValueIndex = [...this.selectedItems][0];
305
- const selectedValueLabel = await this.formatItem(this.items[selectedValueIndex]);
306
- this.inputValue = selectedValueLabel;
307
- this.input.value = selectedValueLabel;
407
+ });
408
+ chips.forEach(chip => {
409
+ if (!ids.includes(chip.value)) {
410
+ chip.remove();
308
411
  }
309
- }
310
- this.listOpen = false;
412
+ });
311
413
  }
312
- updateInputValue(e) {
313
- var _a;
314
- this.inputValue = e.detail.value;
315
- this.listOpen = String(this.inputValue).length >= this.minCharacters && ((_a = this.getFilteredItems()) === null || _a === void 0 ? void 0 : _a.length) > 0;
414
+ async getSelectedItemLabel() {
415
+ const item = this.processedItems.find(item => this.selectedItems.has(item.id));
416
+ const label = item ? await this.formatItem(item) : "";
417
+ return label;
316
418
  }
317
- selectActiveItem() {
318
- if (this.activeItem === undefined) {
419
+ /**
420
+ * Updates the input text when the combobox loses focus or when a selection is made.
421
+ */
422
+ async updateInputText(isBlurred = false) {
423
+ if (isBlurred && this.multiple) {
424
+ this.input.value = "";
319
425
  return;
320
426
  }
321
- const filteredItem = this.returnFilteredOrNonFiltered();
322
- const item = filteredItem[this.activeItem];
323
- this.updateSelectedItems(item.id, true);
427
+ if (isBlurred && this.force) {
428
+ if (this.selectedItems.size === 0) {
429
+ this.input.value = "";
430
+ }
431
+ else {
432
+ this.input.value = await this.getSelectedItemLabel();
433
+ }
434
+ }
435
+ if (!isBlurred && this.selectedItems.size > 0) {
436
+ this.input.value = ""; // set value to empty so that cursor position follows accordingly
437
+ this.input.value = await this.getSelectedItemLabel();
438
+ this.input.scrollLeft = this.input.scrollWidth;
439
+ }
324
440
  }
325
- announceActive(items) {
326
- if (!items) {
327
- items = this.returnFilteredOrNonFiltered();
441
+ // Event handlers
442
+ onListClick(e, item) {
443
+ e.preventDefault();
444
+ e.stopPropagation();
445
+ // update selected item with id
446
+ if (this.multiple) {
447
+ this.addSelectedItem(item.id, true);
328
448
  }
329
- if (this.activeItem === undefined || this.activeItem === -1) {
330
- return;
449
+ else {
450
+ this.updateSelectedItem(item.id, true);
331
451
  }
332
- const item = items[this.activeItem];
333
- this.selectionMsg = structuredClone(this.formatLabel(item, items.length, this.items.length));
452
+ this.activeItem = undefined;
453
+ this.listOpen = false;
454
+ return this.listOpen;
334
455
  }
335
456
  //function that scrolls to the li element with the class "active"
336
457
  scrollToActive() {
@@ -358,16 +479,27 @@ const DuetCombobox = class {
358
479
  */
359
480
  getFilteredItems() {
360
481
  // filter items based on user inputs
361
- const filteredItems = this.processedItems.filter(item => {
362
- var _a, _b, _c, _d;
482
+ const filteredItems = this.processedItems
483
+ .filter(item => {
484
+ var _a, _b, _c, _d, _e;
363
485
  // filter by name and value
364
486
  // if value contains inputvalue
365
487
  return ((_a = String(item.value)) === null || _a === void 0 ? void 0 : _a.toLowerCase()[this.filterType]((_b = this.inputValue) === null || _b === void 0 ? void 0 : _b.toLowerCase())) ||
366
488
  (
367
489
  // if name contains input value
368
490
  (_c = String(item.name)) === null || _c === void 0 ? void 0 : _c.toLowerCase()[this.filterType]((_d = this.inputValue) === null || _d === void 0 ? void 0 : _d.toLowerCase())) ||
491
+ // if name contains input value
492
+ this.formatter(item).toLowerCase()[this.filterType]((_e = this.inputValue) === null || _e === void 0 ? void 0 : _e.toLowerCase()) ||
369
493
  // if the item is selected
370
494
  this.selectedItems.has(item.id);
495
+ })
496
+ // if multiple, filter out the selected items
497
+ .filter(item => {
498
+ let include = true;
499
+ if (this.multiple && this.selectedItems.has(item.id)) {
500
+ include = false;
501
+ }
502
+ return include;
371
503
  });
372
504
  return this.sortFilteredItems(filteredItems);
373
505
  }
@@ -401,9 +533,10 @@ const DuetCombobox = class {
401
533
  }, ref: el => (this.listContainer = el) }, index.h("ul", { class: {
402
534
  "duet-combobox-listbox-open": this.listOpen,
403
535
  "duet-combobox-listbox": true,
404
- }, role: "listbox", ref: el => (this.listElement = el), id: this.listBoxId }, selectElements.map((item, index$1) => {
405
- return (index.h(DuetComboBoxSelect, { item: item, active: index$1 === this.activeItem, selected: this.selectedItems.has(item.id), search: this.inputValue, total: selectElements.length, clickHandler: e => this.onListClick(e, item), label: this.formatLabel(item, selectElements.length, this.items.length) }));
406
- })))));
536
+ }, role: "listbox", ref: el => (this.listElement = el), id: this.listBoxId }, this.listOpen &&
537
+ selectElements.map((item, index$1) => {
538
+ return (index.h(DuetComboBoxSelect, { item: item, active: index$1 === this.activeItem, selected: this.selectedItems.has(item.id), search: this.inputValue, total: selectElements.length, clickHandler: e => this.onListClick(e, item), label: this.formatLabel(item, selectElements.length, this.processedItems.length) }));
539
+ })))));
407
540
  }
408
541
  get element() { return index.getElement(this); }
409
542
  static get watchers() { return {
@@ -10,7 +10,7 @@ const themeableComponent = require('./themeable-component-83a2a0d4.js');
10
10
  const createId = require('./create-id-1f8c438f.js');
11
11
  const focusUtils = require('./focus-utils-56f2d983.js');
12
12
  const languageUtils = require('./language-utils-e8a527e5.js');
13
- const slotUtils = require('./slot-utils-f5073417.js');
13
+ const slotUtils = require('./slot-utils-03a40c78.js');
14
14
  require('./string-utils-053749ff.js');
15
15
 
16
16
  const formatOptionsShort = { day: "numeric", month: "long" };
@@ -8,7 +8,7 @@ Object.defineProperty(exports, '__esModule', { value: true });
8
8
  const index = require('./index-b77ebc31.js');
9
9
  const themeableComponent = require('./themeable-component-83a2a0d4.js');
10
10
  const createId = require('./create-id-1f8c438f.js');
11
- const slotUtils = require('./slot-utils-f5073417.js');
11
+ const slotUtils = require('./slot-utils-03a40c78.js');
12
12
 
13
13
  const duetFieldsetCss = "*,*::after,*::before{box-sizing:border-box;padding:0;margin:0;background:transparent;border:0;-moz-appearance:none;-webkit-appearance:none;appearance:none}:host{box-sizing:border-box;padding:0;margin:0;background:transparent;border:0;-moz-appearance:none;-webkit-appearance:none;appearance:none;margin-bottom:12px !important;display:block;width:100%}:host(.duet-m-0){margin:0 !important}fieldset{position:relative;width:100%;min-width:0;border:0}fieldset legend{position:absolute !important;top:0;width:1px !important;height:1px !important;padding:0 !important;overflow:hidden !important;clip:rect(1px, 1px, 1px, 1px) !important;border:0 !important}.duet-legend-wrapper{position:relative;display:block;width:100%;font-family:\"localtapiola-sans\", -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\";font-size:1rem;font-weight:600;line-height:1.5;color:rgb(0, 41, 77);text-align:left;background:transparent}.duet-legend-wrapper.duet-legend-compact:not(.duet-legend-has-caption){line-height:1.25}.duet-theme-turva .duet-legend-wrapper{font-family:\"turva-sans\", -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\";color:rgb(23, 28, 58)}.duet-fieldset-label{margin-bottom:12px !important;margin-top:8px}.duet-legend-has-caption .duet-fieldset-label{margin-bottom:6px !important}.duet-legend-has-tooltip .duet-fieldset-label{padding-right:36px}@media (min-width: 48em){.duet-legend-has-tooltip .duet-fieldset-label{margin-bottom:3px !important;padding-right:0}}@media (min-width: 48em){.duet-legend-has-tooltip.duet-legend-has-caption .duet-fieldset-label{margin-bottom:-3px !important}}.duet-fieldset-caption{margin-bottom:12px !important}.duet-fieldset-help{display:block;font-family:\"localtapiola-sans\", -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\";font-size:0.875rem;font-weight:400;line-height:1.25;color:rgb(222, 35, 98);border-radius:4px}.duet-fieldset-help span{display:block;margin-top:12px}.duet-theme-turva .duet-fieldset-help{font-family:\"turva-sans\", -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\";color:rgb(224, 42, 13)}::slotted(duet-tooltip){position:absolute;top:4px;right:0}@media (min-width: 48em){::slotted(duet-tooltip){position:relative;right:auto}}.duet-legend-hidden{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0 0 0 0);border:0}";
14
14