@duetds/components 4.32.0 → 4.33.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 (350) hide show
  1. package/hydrate/index.js +1933 -87
  2. package/lib/cjs/{dom-a28e5c5f.js → dom-c850c8d7.js} +1 -1
  3. package/lib/cjs/duet-alert.cjs.entry.js +2 -2
  4. package/lib/cjs/duet-badge.cjs.entry.js +1 -1
  5. package/lib/cjs/duet-button_2.cjs.entry.js +4 -4
  6. package/lib/cjs/duet-caption_4.cjs.entry.js +17 -10
  7. package/lib/cjs/duet-card.cjs.entry.js +3 -3
  8. package/lib/cjs/duet-checkbox.cjs.entry.js +2 -2
  9. package/lib/cjs/duet-choice_2.cjs.entry.js +40 -18
  10. package/lib/cjs/duet-collapsible.cjs.entry.js +4 -1
  11. package/lib/cjs/duet-cookie-consent.cjs.entry.js +1 -1
  12. package/lib/cjs/duet-date-picker.cjs.entry.js +7 -7
  13. package/lib/cjs/duet-divider_2.cjs.entry.js +1 -1
  14. package/lib/cjs/duet-editable-table-button_3.cjs.entry.js +232 -0
  15. package/lib/cjs/{duet-table.cjs.entry.js → duet-editable-table_3.cjs.entry.js} +206 -2
  16. package/lib/cjs/duet-empty-state.cjs.entry.js +1 -1
  17. package/lib/cjs/duet-footer.cjs.entry.js +2 -2
  18. package/lib/cjs/duet-grid_2.cjs.entry.js +52 -4
  19. package/lib/cjs/duet-header_2.cjs.entry.js +3 -3
  20. package/lib/cjs/duet-hero.cjs.entry.js +2 -2
  21. package/lib/cjs/duet-icon.cjs.entry.js +4 -4
  22. package/lib/cjs/duet-input_2.cjs.entry.js +6 -6
  23. package/lib/cjs/duet-layout.cjs.entry.js +1 -1
  24. package/lib/cjs/duet-list_2.cjs.entry.js +2 -2
  25. package/lib/cjs/duet-modal.cjs.entry.js +3 -3
  26. package/lib/cjs/duet-notification_2.cjs.entry.js +2 -2
  27. package/lib/cjs/duet-number-input.cjs.entry.js +2 -2
  28. package/lib/cjs/duet-progress.cjs.entry.js +75 -0
  29. package/lib/cjs/duet-radio_2.cjs.entry.js +2 -2
  30. package/lib/cjs/duet-range-slider.cjs.entry.js +2 -2
  31. package/lib/cjs/duet-select.cjs.entry.js +5 -5
  32. package/lib/cjs/duet-step_2.cjs.entry.js +1 -1
  33. package/lib/cjs/duet-tab_2.cjs.entry.js +3 -3
  34. package/lib/cjs/duet-textarea.cjs.entry.js +5 -5
  35. package/lib/cjs/duet-toggle.cjs.entry.js +1 -1
  36. package/lib/cjs/duet-tooltip.cjs.entry.js +2 -2
  37. package/lib/cjs/duet-tray.cjs.entry.js +3 -3
  38. package/lib/cjs/duet-upload.cjs.entry.js +1089 -0
  39. package/lib/cjs/duet-visually-hidden.cjs.entry.js +1 -1
  40. package/lib/cjs/duet.cjs.js +4 -4
  41. package/lib/cjs/{focus-utils-55b5a616.js → focus-utils-a7a1fb8b.js} +1 -1
  42. package/lib/cjs/{index-03ed1f55.js → index-b724d698.js} +5 -2
  43. package/lib/cjs/js-utils-33a9dbe3.js +16 -0
  44. package/lib/cjs/{language-utils-48b8860b.js → language-utils-aa282901.js} +6 -2
  45. package/lib/cjs/loader.cjs.js +3 -3
  46. package/lib/cjs/{shadow-css-6560c90c.js → shadow-css-e3edeed1.js} +9 -10
  47. package/lib/cjs/{token-utils-13e5d13e.js → token-utils-63a9c8dc.js} +1 -1
  48. package/lib/cjs/{tokens.module-53b3bd92.js → tokens.module-6b2df1c2.js} +2 -0
  49. package/lib/cjs/{watch-options-3877c082.js → watch-options-d88afac0.js} +29 -6
  50. package/lib/collection/collection-manifest.json +15 -2
  51. package/lib/collection/components/duet-checkbox/duet-checkbox.css +1 -1
  52. package/lib/collection/components/duet-choice/duet-choice.js +95 -21
  53. package/lib/collection/components/duet-date-picker/duet-date-picker.js +9 -9
  54. package/lib/collection/components/duet-editable-table/duet-editable-table-button.css +32 -0
  55. package/lib/collection/components/duet-editable-table/duet-editable-table-button.js +218 -0
  56. package/lib/collection/components/duet-editable-table/duet-editable-table-item.css +36 -0
  57. package/lib/collection/components/duet-editable-table/duet-editable-table-item.js +203 -0
  58. package/lib/collection/components/duet-editable-table/duet-editable-table-tabledata.js +13 -0
  59. package/lib/collection/components/duet-editable-table/duet-editable-table.css +16 -0
  60. package/lib/collection/components/duet-editable-table/duet-editable-table.js +348 -0
  61. package/lib/collection/components/duet-grid/duet-grid.js +57 -6
  62. package/lib/collection/components/duet-heading/duet-heading.css +3 -0
  63. package/lib/collection/components/duet-heading/duet-heading.js +7 -6
  64. package/lib/collection/components/duet-icon/duet-icon.js +2 -6
  65. package/lib/collection/components/duet-input/duet-input.css +15 -0
  66. package/lib/collection/components/duet-input/duet-input.js +4 -4
  67. package/lib/collection/components/duet-paragraph/duet-paragraph.css +6 -0
  68. package/lib/collection/components/duet-paragraph/duet-paragraph.js +34 -3
  69. package/lib/collection/components/duet-progress/duet-progress.css +103 -0
  70. package/lib/collection/components/duet-progress/duet-progress.js +240 -0
  71. package/lib/collection/components/duet-select/duet-select.css +15 -0
  72. package/lib/collection/components/duet-select/duet-select.js +3 -3
  73. package/lib/collection/components/duet-tab-group/duet-tab-group.css +2 -2
  74. package/lib/collection/components/duet-textarea/duet-textarea.css +19 -0
  75. package/lib/collection/components/duet-textarea/duet-textarea.js +5 -4
  76. package/lib/collection/components/duet-upload/duet-upload-aria-status.js +217 -0
  77. package/lib/collection/components/duet-upload/duet-upload-editable-item-error.js +16 -0
  78. package/lib/collection/components/duet-upload/duet-upload-editable-item-inprogres.js +8 -0
  79. package/lib/collection/components/duet-upload/duet-upload-editable-item-success.js +30 -0
  80. package/lib/collection/components/duet-upload/duet-upload-validators.js +93 -0
  81. package/lib/collection/components/duet-upload/duet-upload.css +64 -0
  82. package/lib/collection/components/duet-upload/duet-upload.js +1838 -0
  83. package/lib/collection/components/duet-upload/errorcodes.utils.js +32 -0
  84. package/lib/collection/components/duet-upload/mock.helpers.js +91 -0
  85. package/lib/collection/components/duet-upload/upload.helpers.js +13 -0
  86. package/lib/collection/components/duet-upload/xhr.helpers.js +30 -0
  87. package/lib/collection/utils/js-utils.js +12 -0
  88. package/lib/collection/utils/language-utils.js +6 -3
  89. package/lib/collection/utils/watch-options.js +35 -6
  90. package/lib/custom-elements-bundle/index.d.ts +36 -0
  91. package/lib/custom-elements-bundle/index.js +1917 -277
  92. package/lib/duet/duet.esm.js +1 -1
  93. package/lib/duet/duet.js +1 -1
  94. package/lib/duet/{p-1391ec53.entry.js → p-00735436.entry.js} +1 -1
  95. package/lib/duet/p-060d79be.entry.js +4 -0
  96. package/lib/duet/p-0d22396e.system.js +16 -0
  97. package/lib/duet/p-10deead0.system.js +4 -0
  98. package/lib/duet/{p-72fd384a.entry.js → p-1208c84f.entry.js} +1 -1
  99. package/lib/duet/p-12721178.js +4 -0
  100. package/lib/duet/p-155ef581.system.entry.js +4 -0
  101. package/lib/duet/{p-08729381.entry.js → p-16c48c5d.entry.js} +1 -1
  102. package/lib/duet/p-1797df7b.system.entry.js +4 -0
  103. package/lib/duet/p-1a08fc22.system.entry.js +4 -0
  104. package/lib/duet/{p-b6a0caf8.system.entry.js → p-237e47b4.system.entry.js} +1 -1
  105. package/lib/duet/{p-4fcbcecd.system.entry.js → p-2443bdca.system.entry.js} +1 -1
  106. package/lib/duet/{p-432ba72e.system.entry.js → p-263bc9cd.system.entry.js} +1 -1
  107. package/lib/duet/p-2764f081.js +4 -0
  108. package/lib/duet/{p-b0bbbdba.system.entry.js → p-27d80cef.system.entry.js} +1 -1
  109. package/lib/duet/p-28e02c08.entry.js +4 -0
  110. package/lib/duet/{p-8740fa38.entry.js → p-2bb1460c.entry.js} +1 -1
  111. package/lib/duet/p-33c58756.entry.js +4 -0
  112. package/lib/duet/{p-9cdd361e.js → p-35a3794e.js} +0 -0
  113. package/lib/duet/{p-8c511832.system.entry.js → p-374fb7e6.system.entry.js} +1 -1
  114. package/lib/duet/{p-5a817929.system.entry.js → p-387823af.system.entry.js} +1 -1
  115. package/lib/duet/{p-a678da8c.entry.js → p-3af5d66f.entry.js} +1 -1
  116. package/lib/duet/{p-322d1c38.js → p-3c1971d8.js} +1 -1
  117. package/lib/duet/{p-d13874cb.entry.js → p-4607af59.entry.js} +1 -1
  118. package/lib/duet/{p-2c0dd9ba.system.entry.js → p-48d1eb1f.system.entry.js} +1 -1
  119. package/lib/duet/p-4a87e9ab.system.entry.js +4 -0
  120. package/lib/duet/{p-92103298.system.entry.js → p-4b6ebe40.system.entry.js} +1 -1
  121. package/lib/duet/{p-6cf41bfe.system.entry.js → p-4e28da18.system.entry.js} +1 -1
  122. package/lib/duet/p-548d484e.js +4 -0
  123. package/lib/duet/{p-2c679963.entry.js → p-5826523b.entry.js} +1 -1
  124. package/lib/duet/{p-7331f2fe.system.entry.js → p-58750bae.system.entry.js} +1 -1
  125. package/lib/duet/{p-7a868085.entry.js → p-597d99c7.entry.js} +1 -1
  126. package/lib/duet/p-5ea0cd19.entry.js +4 -0
  127. package/lib/duet/p-63d5bf73.system.entry.js +4 -0
  128. package/lib/duet/{p-68d09837.system.entry.js → p-67d9a9a9.system.entry.js} +1 -1
  129. package/lib/duet/{p-9542c540.entry.js → p-6a19b5ec.entry.js} +1 -1
  130. package/lib/duet/p-6cc3be76.system.entry.js +4 -0
  131. package/lib/duet/p-6e363557.system.js +4 -0
  132. package/lib/duet/{p-3b3bac3f.system.entry.js → p-6e6e76db.system.entry.js} +1 -1
  133. package/lib/duet/p-70fafc98.system.js +4 -0
  134. package/lib/duet/{p-2d1e2b23.system.entry.js → p-7368b14e.system.entry.js} +1 -1
  135. package/lib/duet/{p-2a3411b5.system.entry.js → p-751542a0.system.entry.js} +1 -1
  136. package/lib/duet/{p-b75c5f13.entry.js → p-794659ac.entry.js} +1 -1
  137. package/lib/duet/{p-b04d738f.system.entry.js → p-7e8d5bb9.system.entry.js} +1 -1
  138. package/lib/duet/p-7fee0d23.system.entry.js +4 -0
  139. package/lib/duet/p-81867417.system.js +4 -0
  140. package/lib/duet/{p-84ece735.entry.js → p-86daec1c.entry.js} +1 -1
  141. package/lib/duet/{p-94a5fd74.system.entry.js → p-8b5ca0e7.system.entry.js} +1 -1
  142. package/lib/duet/{p-ffc2ffff.entry.js → p-8cb7416d.entry.js} +1 -1
  143. package/lib/duet/p-8f826843.system.entry.js +4 -0
  144. package/lib/duet/p-94169303.entry.js +4 -0
  145. package/lib/duet/{p-807b2087.entry.js → p-9481e312.entry.js} +1 -1
  146. package/lib/duet/{p-977f2826.entry.js → p-984576c9.entry.js} +1 -1
  147. package/lib/duet/p-987edcd0.js +15 -0
  148. package/lib/duet/p-9d73343a.entry.js +4 -0
  149. package/lib/duet/{p-8652a7ab.system.entry.js → p-9dca5c22.system.entry.js} +1 -1
  150. package/lib/duet/p-a207b008.entry.js +4 -0
  151. package/lib/duet/p-a5b9c192.system.entry.js +4 -0
  152. package/lib/duet/p-a6a84ec6.entry.js +4 -0
  153. package/lib/duet/{p-9f0f5674.entry.js → p-a890da72.entry.js} +1 -1
  154. package/lib/duet/{p-0f2a478e.entry.js → p-a9859a82.entry.js} +1 -1
  155. package/lib/duet/{p-3040debf.entry.js → p-aba68b7b.entry.js} +1 -1
  156. package/lib/duet/p-acc57c77.entry.js +4 -0
  157. package/lib/duet/{p-2826f987.js → p-ad07f399.js} +1 -1
  158. package/lib/duet/{p-fb898d94.system.entry.js → p-aee24388.system.entry.js} +1 -1
  159. package/lib/duet/p-aef1b720.system.entry.js +4 -0
  160. package/lib/duet/{p-00eac879.system.entry.js → p-af41d894.system.entry.js} +1 -1
  161. package/lib/duet/p-b25d3769.js +4 -0
  162. package/lib/duet/{p-43dde575.system.entry.js → p-b32224fe.system.entry.js} +1 -1
  163. package/lib/duet/{p-f13a0883.entry.js → p-b3744481.entry.js} +1 -1
  164. package/lib/duet/{p-b374d7c2.system.js → p-b42d81c3.system.js} +1 -1
  165. package/lib/duet/{p-ed479d09.system.entry.js → p-b4e87f02.system.entry.js} +1 -1
  166. package/lib/duet/{p-b9683731.entry.js → p-bf93a991.entry.js} +1 -1
  167. package/lib/duet/{p-a962c8c1.system.js → p-c18a599e.system.js} +0 -0
  168. package/lib/duet/p-c2e77278.entry.js +4 -0
  169. package/lib/duet/p-c34329f3.entry.js +4 -0
  170. package/lib/duet/{p-c19094dd.entry.js → p-c36b4da0.entry.js} +1 -1
  171. package/lib/duet/{p-8002a095.entry.js → p-cdd70b93.entry.js} +1 -1
  172. package/lib/duet/p-d1c19f04.system.entry.js +4 -0
  173. package/lib/duet/{p-cc0bd28f.system.entry.js → p-d3a3c3c7.system.entry.js} +1 -1
  174. package/lib/duet/{p-19c28d99.system.entry.js → p-d4118b6e.system.entry.js} +1 -1
  175. package/lib/duet/{p-abd3bfb4.system.entry.js → p-d744d188.system.entry.js} +1 -1
  176. package/lib/duet/p-ddb6344c.system.js +4 -0
  177. package/lib/duet/p-de07c7d7.entry.js +4 -0
  178. package/lib/duet/{p-57cb58d4.system.entry.js → p-dfe79666.system.entry.js} +1 -1
  179. package/lib/duet/{p-c723d36e.system.js → p-e12f2b8b.system.js} +1 -1
  180. package/lib/duet/p-e2a44156.js +4 -0
  181. package/lib/duet/p-e76b722f.entry.js +4 -0
  182. package/lib/duet/{p-0b9b6393.entry.js → p-e964d062.entry.js} +1 -1
  183. package/lib/duet/p-eb55ccd2.system.js +4 -0
  184. package/lib/duet/p-f0a4b68d.system.entry.js +4 -0
  185. package/lib/duet/p-f364eb96.entry.js +4 -0
  186. package/lib/duet/{p-fbb7d194.entry.js → p-f8ce39fb.entry.js} +1 -1
  187. package/lib/esm/{dom-8516b24e.js → dom-58cd15f6.js} +1 -1
  188. package/lib/esm/duet-alert.entry.js +2 -2
  189. package/lib/esm/duet-badge.entry.js +1 -1
  190. package/lib/esm/duet-button_2.entry.js +4 -4
  191. package/lib/esm/duet-caption_4.entry.js +17 -10
  192. package/lib/esm/duet-card.entry.js +3 -3
  193. package/lib/esm/duet-checkbox.entry.js +2 -2
  194. package/lib/esm/duet-choice_2.entry.js +41 -19
  195. package/lib/esm/duet-collapsible.entry.js +4 -1
  196. package/lib/esm/duet-cookie-consent.entry.js +1 -1
  197. package/lib/esm/duet-date-picker.entry.js +7 -7
  198. package/lib/esm/duet-divider_2.entry.js +1 -1
  199. package/lib/esm/duet-editable-table-button_3.entry.js +226 -0
  200. package/lib/esm/{duet-table.entry.js → duet-editable-table_3.entry.js} +205 -3
  201. package/lib/esm/duet-empty-state.entry.js +1 -1
  202. package/lib/esm/duet-footer.entry.js +2 -2
  203. package/lib/esm/duet-grid_2.entry.js +52 -4
  204. package/lib/esm/duet-header_2.entry.js +3 -3
  205. package/lib/esm/duet-hero.entry.js +2 -2
  206. package/lib/esm/duet-icon.entry.js +4 -4
  207. package/lib/esm/duet-input_2.entry.js +6 -6
  208. package/lib/esm/duet-layout.entry.js +1 -1
  209. package/lib/esm/duet-list_2.entry.js +2 -2
  210. package/lib/esm/duet-modal.entry.js +3 -3
  211. package/lib/esm/duet-notification_2.entry.js +2 -2
  212. package/lib/esm/duet-number-input.entry.js +2 -2
  213. package/lib/esm/duet-progress.entry.js +71 -0
  214. package/lib/esm/duet-radio_2.entry.js +2 -2
  215. package/lib/esm/duet-range-slider.entry.js +2 -2
  216. package/lib/esm/duet-select.entry.js +5 -5
  217. package/lib/esm/duet-step_2.entry.js +1 -1
  218. package/lib/esm/duet-tab_2.entry.js +3 -3
  219. package/lib/esm/duet-textarea.entry.js +5 -5
  220. package/lib/esm/duet-toggle.entry.js +1 -1
  221. package/lib/esm/duet-tooltip.entry.js +2 -2
  222. package/lib/esm/duet-tray.entry.js +3 -3
  223. package/lib/esm/duet-upload.entry.js +1085 -0
  224. package/lib/esm/duet-visually-hidden.entry.js +1 -1
  225. package/lib/esm/duet.js +4 -4
  226. package/lib/esm/{focus-utils-6a282066.js → focus-utils-1fe0dcd0.js} +1 -1
  227. package/lib/esm/{index-3a265449.js → index-84d97bd1.js} +5 -2
  228. package/lib/esm/js-utils-b69f17df.js +14 -0
  229. package/lib/esm/{language-utils-d5c38f65.js → language-utils-344d894c.js} +6 -3
  230. package/lib/esm/loader.js +3 -3
  231. package/lib/esm/{shadow-css-9178c864.js → shadow-css-7c726abb.js} +9 -10
  232. package/lib/esm/{token-utils-5a35377f.js → token-utils-590d9413.js} +1 -1
  233. package/lib/esm/{tokens.module-edb66c04.js → tokens.module-49cbf963.js} +3 -1
  234. package/lib/esm/watch-options-dd55bce8.js +57 -0
  235. package/lib/esm-es5/{dom-8516b24e.js → dom-58cd15f6.js} +0 -0
  236. package/lib/esm-es5/duet-alert.entry.js +1 -1
  237. package/lib/esm-es5/duet-badge.entry.js +1 -1
  238. package/lib/esm-es5/duet-button_2.entry.js +1 -1
  239. package/lib/esm-es5/duet-caption_4.entry.js +2 -2
  240. package/lib/esm-es5/duet-card.entry.js +1 -1
  241. package/lib/esm-es5/duet-checkbox.entry.js +1 -1
  242. package/lib/esm-es5/duet-choice_2.entry.js +2 -2
  243. package/lib/esm-es5/duet-collapsible.entry.js +1 -1
  244. package/lib/esm-es5/duet-cookie-consent.entry.js +1 -1
  245. package/lib/esm-es5/duet-date-picker.entry.js +1 -1
  246. package/lib/esm-es5/duet-divider_2.entry.js +1 -1
  247. package/lib/esm-es5/duet-editable-table-button_3.entry.js +4 -0
  248. package/lib/esm-es5/duet-editable-table_3.entry.js +4 -0
  249. package/lib/esm-es5/duet-empty-state.entry.js +1 -1
  250. package/lib/esm-es5/duet-footer.entry.js +1 -1
  251. package/lib/esm-es5/duet-grid_2.entry.js +2 -2
  252. package/lib/esm-es5/duet-header_2.entry.js +1 -1
  253. package/lib/esm-es5/duet-hero.entry.js +1 -1
  254. package/lib/esm-es5/duet-icon.entry.js +1 -1
  255. package/lib/esm-es5/duet-input_2.entry.js +1 -1
  256. package/lib/esm-es5/duet-layout.entry.js +1 -1
  257. package/lib/esm-es5/duet-list_2.entry.js +1 -1
  258. package/lib/esm-es5/duet-modal.entry.js +1 -1
  259. package/lib/esm-es5/duet-notification_2.entry.js +1 -1
  260. package/lib/esm-es5/duet-number-input.entry.js +1 -1
  261. package/lib/esm-es5/duet-progress.entry.js +4 -0
  262. package/lib/esm-es5/duet-radio_2.entry.js +1 -1
  263. package/lib/esm-es5/duet-range-slider.entry.js +1 -1
  264. package/lib/esm-es5/duet-select.entry.js +1 -1
  265. package/lib/esm-es5/duet-step_2.entry.js +1 -1
  266. package/lib/esm-es5/duet-tab_2.entry.js +2 -2
  267. package/lib/esm-es5/duet-textarea.entry.js +1 -1
  268. package/lib/esm-es5/duet-toggle.entry.js +1 -1
  269. package/lib/esm-es5/duet-tooltip.entry.js +1 -1
  270. package/lib/esm-es5/duet-tray.entry.js +1 -1
  271. package/lib/esm-es5/duet-upload.entry.js +4 -0
  272. package/lib/esm-es5/duet-visually-hidden.entry.js +1 -1
  273. package/lib/esm-es5/duet.js +1 -1
  274. package/lib/esm-es5/{focus-utils-6a282066.js → focus-utils-1fe0dcd0.js} +1 -1
  275. package/lib/esm-es5/index-84d97bd1.js +4 -0
  276. package/lib/esm-es5/js-utils-b69f17df.js +4 -0
  277. package/lib/esm-es5/{language-utils-d5c38f65.js → language-utils-344d894c.js} +1 -1
  278. package/lib/esm-es5/loader.js +1 -1
  279. package/lib/esm-es5/shadow-css-7c726abb.js +15 -0
  280. package/lib/esm-es5/{token-utils-5a35377f.js → token-utils-590d9413.js} +1 -1
  281. package/lib/esm-es5/tokens.module-49cbf963.js +4 -0
  282. package/lib/esm-es5/watch-options-dd55bce8.js +4 -0
  283. package/lib/types/components/duet-choice/duet-choice.d.ts +20 -1
  284. package/lib/types/components/duet-date-picker/duet-date-picker.d.ts +5 -5
  285. package/lib/types/components/duet-editable-table/duet-editable-table-button.d.ts +72 -0
  286. package/lib/types/components/duet-editable-table/duet-editable-table-item.d.ts +72 -0
  287. package/lib/types/components/duet-editable-table/duet-editable-table-tabledata.d.ts +7 -0
  288. package/lib/types/components/duet-editable-table/duet-editable-table.d.ts +84 -0
  289. package/lib/types/components/duet-grid/duet-grid.d.ts +16 -2
  290. package/lib/types/components/duet-heading/duet-heading.d.ts +2 -2
  291. package/lib/types/components/duet-icon/duet-icon.d.ts +1 -1
  292. package/lib/types/components/duet-paragraph/duet-paragraph.d.ts +9 -1
  293. package/lib/types/components/duet-progress/duet-progress.d.ts +64 -0
  294. package/lib/types/components/duet-upload/duet-upload-aria-status.d.ts +49 -0
  295. package/lib/types/components/duet-upload/duet-upload-editable-item-error.d.ts +7 -0
  296. package/lib/types/components/duet-upload/duet-upload-editable-item-inprogres.d.ts +7 -0
  297. package/lib/types/components/duet-upload/duet-upload-editable-item-success.d.ts +8 -0
  298. package/lib/types/components/duet-upload/duet-upload-validators.d.ts +12 -0
  299. package/lib/types/components/duet-upload/duet-upload.d.ts +380 -0
  300. package/lib/types/components/duet-upload/errorcodes.utils.d.ts +8 -0
  301. package/lib/types/components/duet-upload/mock.helpers.d.ts +2 -0
  302. package/lib/types/components/duet-upload/upload.helpers.d.ts +1 -0
  303. package/lib/types/components/duet-upload/xhr.helpers.d.ts +18 -0
  304. package/lib/types/components.d.ts +789 -19
  305. package/lib/types/utils/js-utils.d.ts +1 -0
  306. package/lib/types/utils/language-utils.d.ts +5 -1
  307. package/lib/types/utils/watch-options.d.ts +2 -0
  308. package/package.json +6 -6
  309. package/lib/cjs/duet-fieldset.cjs.entry.js +0 -62
  310. package/lib/duet/p-0058512b.js +0 -4
  311. package/lib/duet/p-0b00e8d6.system.js +0 -16
  312. package/lib/duet/p-15922601.system.js +0 -4
  313. package/lib/duet/p-194e25ce.system.entry.js +0 -4
  314. package/lib/duet/p-1d87ea02.system.entry.js +0 -4
  315. package/lib/duet/p-3618aaee.entry.js +0 -4
  316. package/lib/duet/p-40d68321.entry.js +0 -4
  317. package/lib/duet/p-418b2ce7.system.js +0 -4
  318. package/lib/duet/p-43e39d98.system.js +0 -4
  319. package/lib/duet/p-4603830b.entry.js +0 -4
  320. package/lib/duet/p-52d7fbec.entry.js +0 -4
  321. package/lib/duet/p-60478325.system.entry.js +0 -4
  322. package/lib/duet/p-64ed7add.entry.js +0 -4
  323. package/lib/duet/p-6a356ab1.system.js +0 -4
  324. package/lib/duet/p-753b406c.entry.js +0 -4
  325. package/lib/duet/p-76c00d0c.entry.js +0 -4
  326. package/lib/duet/p-85fe1132.js +0 -4
  327. package/lib/duet/p-8c8e82aa.system.js +0 -4
  328. package/lib/duet/p-9a89ec39.js +0 -4
  329. package/lib/duet/p-a11df1b6.js +0 -15
  330. package/lib/duet/p-a1eccee1.system.entry.js +0 -4
  331. package/lib/duet/p-a89e88a3.js +0 -4
  332. package/lib/duet/p-ade33230.entry.js +0 -4
  333. package/lib/duet/p-cb827bb7.entry.js +0 -4
  334. package/lib/duet/p-d85fba2c.system.entry.js +0 -4
  335. package/lib/duet/p-dfa90f8a.system.entry.js +0 -4
  336. package/lib/duet/p-e6b9bd1d.entry.js +0 -4
  337. package/lib/duet/p-ec3eef3a.entry.js +0 -4
  338. package/lib/duet/p-ee64d6be.system.entry.js +0 -4
  339. package/lib/duet/p-f113671b.system.entry.js +0 -4
  340. package/lib/duet/p-f2f04396.entry.js +0 -4
  341. package/lib/duet/p-f364ce8b.system.entry.js +0 -4
  342. package/lib/duet/p-fc6624fe.system.entry.js +0 -4
  343. package/lib/esm/duet-fieldset.entry.js +0 -58
  344. package/lib/esm/watch-options-de55ea78.js +0 -35
  345. package/lib/esm-es5/duet-fieldset.entry.js +0 -4
  346. package/lib/esm-es5/duet-table.entry.js +0 -4
  347. package/lib/esm-es5/index-3a265449.js +0 -4
  348. package/lib/esm-es5/shadow-css-9178c864.js +0 -15
  349. package/lib/esm-es5/tokens.module-edb66c04.js +0 -4
  350. package/lib/esm-es5/watch-options-de55ea78.js +0 -4
package/hydrate/index.js CHANGED
@@ -6,7 +6,7 @@
6
6
  Object.defineProperty(exports, '__esModule', { value: true });
7
7
 
8
8
  /*!
9
- Stencil Mock Doc v2.10.0 | MIT Licensed | https://stenciljs.com
9
+ Stencil Mock Doc v2.11.0 | MIT Licensed | https://stenciljs.com
10
10
  */
11
11
  const CONTENT_REF_ID = 'r';
12
12
  const ORG_LOCATION_ID = 'o';
@@ -4701,7 +4701,8 @@ function hydrateFactory($stencilWindow, $stencilHydrateOpts, $stencilHydrateResu
4701
4701
 
4702
4702
 
4703
4703
  const NAMESPACE = 'duet';
4704
- const BUILD = /* duet */ { allRenderFn: true, appendChildSlotFix: false, asyncLoading: true, attachStyles: true, cloneNodeFix: false, cmpDidLoad: true, cmpDidRender: false, cmpDidUnload: false, cmpDidUpdate: true, cmpShouldUpdate: false, cmpWillLoad: true, cmpWillRender: false, cmpWillUpdate: false, connectedCallback: true, constructableCSS: false, cssAnnotations: true, cssVarShim: false, devTools: false, disconnectedCallback: true, dynamicImportShim: false, element: false, event: true, hasRenderFn: true, hostListener: true, hostListenerTarget: true, hostListenerTargetBody: true, hostListenerTargetDocument: true, hostListenerTargetParent: false, hostListenerTargetWindow: true, hotModuleReplacement: false, hydrateClientSide: true, hydrateServerSide: true, hydratedAttribute: false, hydratedClass: true, isDebug: false, isDev: false, isTesting: false, lazyLoad: true, lifecycle: true, lifecycleDOMEvents: false, member: true, method: true, mode: false, observeAttribute: true, profile: false, prop: true, propBoolean: true, propMutable: true, propNumber: true, propString: true, reflect: true, safari10: false, scoped: true, scriptDataOpts: false, shadowDelegatesFocus: true, shadowDom: true, shadowDomShim: true, slot: true, slotChildNodesFix: false, slotRelocation: true, state: true, style: true, svg: true, taskQueue: true, updatable: true, vdomAttribute: true, vdomClass: true, vdomFunctional: true, vdomKey: true, vdomListener: true, vdomPropOrAttr: true, vdomRef: true, vdomRender: true, vdomStyle: true, vdomText: true, vdomXlink: true, watchCallback: true };
4704
+ const BUILD = /* duet */ { allRenderFn: true, appendChildSlotFix: false, asyncLoading: true, attachStyles: true, cloneNodeFix: false, cmpDidLoad: true, cmpDidRender: false, cmpDidUnload: false, cmpDidUpdate: true, cmpShouldUpdate: false, cmpWillLoad: true, cmpWillRender: true, cmpWillUpdate: false, connectedCallback: true, constructableCSS: false, cssAnnotations: true, cssVarShim: false, devTools: false, disconnectedCallback: true, dynamicImportShim: false, element: false, event: true, hasRenderFn: true, hostListener: true, hostListenerTarget: true, hostListenerTargetBody: true, hostListenerTargetDocument: true, hostListenerTargetParent: false, hostListenerTargetWindow: true, hotModuleReplacement: false, hydrateClientSide: true, hydrateServerSide: true, hydratedAttribute: false, hydratedClass: true, isDebug: false, isDev: false, isTesting: false, lazyLoad: true, lifecycle: true, lifecycleDOMEvents: false, member: true, method: true, mode: false, observeAttribute: true, profile: false, prop: true, propBoolean: true, propMutable: true, propNumber: true, propString: true, reflect: true, safari10: false, scoped: true, scriptDataOpts: false, shadowDelegatesFocus: true, shadowDom: true, shadowDomShim: true, slot: true, slotChildNodesFix: false, slotRelocation: true, state: true, style: true, svg: true, taskQueue: true, updatable: true, vdomAttribute: true, vdomClass: true, vdomFunctional: true, vdomKey: true, vdomListener: true, vdomPropOrAttr: true, vdomRef: true, vdomRender: true, vdomStyle: true, vdomText: true, vdomXlink: true, watchCallback: true };
4705
+ const Env = /* duet */ {"cdnURILocal":"http://0.0.0.0:3334","cdnURIProd":"https://cdn.duetds.com/api","duetIconVersion":"2.2.3"};
4705
4706
 
4706
4707
  const TAB_KEY = 9;
4707
4708
  var appGlobalScript = () => {
@@ -5170,7 +5171,8 @@ const createElm = (e, t, o, n) => {
5170
5171
  const n = createTime("scheduleUpdate", e.$cmpMeta$.$tagName$), s = e.$lazyInstance$ ;
5171
5172
  let l;
5172
5173
  return t ? ((e.$flags$ |= 256, e.$queuedListeners$ && (e.$queuedListeners$.map((([e, t]) => safeCall(s, e, t))),
5173
- e.$queuedListeners$ = null)), (l = safeCall(s, "componentWillLoad"))) : (BUILD.cmpWillUpdate ), n(), then(l, (() => updateComponent(e, s, t)));
5174
+ e.$queuedListeners$ = null)), (l = safeCall(s, "componentWillLoad"))) : (BUILD.cmpWillUpdate ), (l = then(l, (() => safeCall(s, "componentWillRender")))),
5175
+ n(), then(l, (() => updateComponent(e, s, t)));
5174
5176
  }, updateComponent = async (e, t, o) => {
5175
5177
  const n = e.$hostElement$, s = createTime("update", e.$cmpMeta$.$tagName$), l = n["s-rc"];
5176
5178
  o && attachStyles(e);
@@ -5635,6 +5637,9 @@ const getLocale = (lang) => {
5635
5637
  }
5636
5638
  throw new Error(`Locale for "${lang}" not found`);
5637
5639
  };
5640
+ /**
5641
+ * Takes any json object that is passed and/or htmlencoded and converts it to proper json
5642
+ */
5638
5643
  const sanitizeString = (string) => {
5639
5644
  const argIsString = typeof string === "string";
5640
5645
  if (argIsString) {
@@ -5642,7 +5647,7 @@ const sanitizeString = (string) => {
5642
5647
  return JSON.parse(convertHtmlQuotes(string));
5643
5648
  }
5644
5649
  catch (e) {
5645
- console.log("getLocaleString received a string, that didnt parse to json object", string, e);
5650
+ console.log("sanitizeString received a string, that didnt parse to json object", string, e);
5646
5651
  }
5647
5652
  }
5648
5653
  return string;
@@ -5654,7 +5659,7 @@ const sanitizeString = (string) => {
5654
5659
  * @param {object} langObject - {fi: "finnish", sv: "swedish", en: "english"} | string will get JSON.parsed
5655
5660
  * @param {boolean} languageOverride = false - in case you want to override the actual language set in html tag
5656
5661
  * @default {object} {locale: "fi-FI", money: "€"}
5657
- * @returns {(string|Object)} given example contains {fi:"something"} and langua===fi this will return "something"
5662
+ * @returns {(string|Object)} given example contains {fi:"something"} and language===fi this will return "something"
5658
5663
  */
5659
5664
  const getLocaleString = (langObject, languageOverride) => {
5660
5665
  const obj = sanitizeString(langObject);
@@ -5962,6 +5967,7 @@ const sizeTappableSquare = "48px";
5962
5967
  const sizeIconXSmall = "16px";
5963
5968
  const sizeIconXxxSmall = "7px";
5964
5969
  const sizeButtonBorder = "2px";
5970
+ const sizeButtonTinyBorder = "1px";
5965
5971
  const sizeIconMedium = "24px";
5966
5972
  const sizeIconSmall = "20px";
5967
5973
  const opacity85 = "0.85";
@@ -6111,6 +6117,7 @@ var tokens$2 = /*#__PURE__*/Object.freeze({
6111
6117
  sizeIconXSmall: sizeIconXSmall,
6112
6118
  sizeIconXxxSmall: sizeIconXxxSmall,
6113
6119
  sizeButtonBorder: sizeButtonBorder,
6120
+ sizeButtonTinyBorder: sizeButtonTinyBorder,
6114
6121
  sizeIconMedium: sizeIconMedium,
6115
6122
  sizeIconSmall: sizeIconSmall,
6116
6123
  opacity85: opacity85,
@@ -6676,7 +6683,7 @@ class DuetCard {
6676
6683
  }; }
6677
6684
  }
6678
6685
 
6679
- const duetCheckboxCss = "*.sc-duet-checkbox,*.sc-duet-checkbox::after,*.sc-duet-checkbox::before{box-sizing:border-box;padding:0;margin:0;background:transparent;border:0;-moz-appearance:none;-webkit-appearance:none;appearance:none}.sc-duet-checkbox-h{box-sizing:border-box;padding:0;margin:0;background:transparent;border:0;-moz-appearance:none;-webkit-appearance:none;appearance:none;margin-right:8px !important;margin-bottom:12px !important;display:inline-flex;width:100%;vertical-align:bottom;-webkit-tap-highlight-color:transparent}.sc-duet-checkbox-h:last-child,.sc-duet-checkbox-h:last-of-type{margin-right:0 !important}.sc-duet-checkbox-h:last-of-type:not(:only-child){margin-bottom:0 !important}.duet-m-0.sc-duet-checkbox-h{margin:0 !important}.duet-label.sc-duet-checkbox{position:relative;z-index:100;display:inline;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:400;line-height:1.5;color:#00294d;vertical-align:top;cursor:pointer;background:transparent;transition:300ms ease}.duet-theme-turva.sc-duet-checkbox .duet-label.sc-duet-checkbox{font-family:\"turva-sans\", -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\";color:#171c3a}.duet-label.sc-duet-checkbox span.sc-duet-checkbox{display:inline-block;width:calc(100% - 32px);font-size:1rem;font-weight:400;vertical-align:top}.duet-checkbox-container.sc-duet-checkbox{position:relative;width:100%;height:100%}.duet-checkbox.sc-duet-checkbox{padding:14px !important;position:absolute;top:0;left:0;z-index:2;width:100%;height:100%;cursor:pointer;opacity:0}.duet-checkbox.sc-duet-checkbox+label.sc-duet-checkbox::before{z-index:100;display:inline-block;width:20px;height:20px;margin:2px 10px 1px 1px;vertical-align:top;content:\"\";background:white;border:1px solid #00294d;border-radius:4px}.duet-theme-turva.sc-duet-checkbox .duet-checkbox.sc-duet-checkbox+label.sc-duet-checkbox::before{border-color:#171c3a}.duet-checkbox.sc-duet-checkbox:checked+label.sc-duet-checkbox::before{background:#00294d;border:1px solid #00294d}.duet-theme-turva.sc-duet-checkbox .duet-checkbox.sc-duet-checkbox:checked+label.sc-duet-checkbox::before{background:#171c3a;border-color:#171c3a}.duet-checkbox.sc-duet-checkbox:focus+label.sc-duet-checkbox::before{box-shadow:0 0 0 4px rgba(0, 119, 179, 0.3), 0 0 0 1px #0077b3}.duet-theme-turva.sc-duet-checkbox .duet-checkbox.sc-duet-checkbox:focus+label.sc-duet-checkbox::before{box-shadow:0 0 0 4px rgba(23, 28, 58, 0.2), 0 0 0 1px #171c3a}.duet-checkbox.sc-duet-checkbox+label.sc-duet-checkbox{position:static}.duet-checkbox.sc-duet-checkbox:checked+label.sc-duet-checkbox::after{position:absolute;top:6px;left:5px;z-index:200;width:12px;height:12px;pointer-events:none;content:\"\";background:transparent url(\"data:image/svg+xml,%3Csvg%20fill%3D%27white%27%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%20width%3D%2724%27%20height%3D%2724%27%20viewBox%3D%270%200%2024%2024%27%3E%3Cpath%20d%3D%27M23.374.287a1.5%2C1.5%2C0%2C0%2C0-2.093.345L7.246%2C20.2%2C2.561%2C15.511A1.5%2C1.5%2C0%2C1%2C0%2C.439%2C17.632l5.935%2C5.934a1.525%2C1.525%2C0%2C0%2C0%2C2.279-.186l15.066-21A1.5%2C1.5%2C0%2C0%2C0%2C23.374.287Z%27%20%2F%3E%3C%2Fsvg%3E\") no-repeat 0 0;background-size:100% auto}.duet-checkbox[disabled].sc-duet-checkbox{cursor:default}.duet-checkbox[disabled].sc-duet-checkbox+label.sc-duet-checkbox{color:#657787}.duet-theme-turva.sc-duet-checkbox .duet-checkbox[disabled].sc-duet-checkbox+label.sc-duet-checkbox{color:#747475}.duet-checkbox[disabled].sc-duet-checkbox+label.sc-duet-checkbox::before{border-color:#cfd2d4}.duet-theme-turva.sc-duet-checkbox .duet-checkbox[disabled].sc-duet-checkbox+label.sc-duet-checkbox::before{border-color:#cfcfd1}.duet-checkbox[disabled].sc-duet-checkbox:checked+label.sc-duet-checkbox::before{background:#657787;border:1px solid #657787}.duet-theme-turva.sc-duet-checkbox .duet-checkbox[disabled].sc-duet-checkbox:checked+label.sc-duet-checkbox::before{background:#747475;border-color:#747475}.duet-label-hidden.sc-duet-checkbox .duet-label.sc-duet-checkbox span.sc-duet-checkbox{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0 0 0 0);border:0}";
6686
+ const duetCheckboxCss = "*.sc-duet-checkbox,*.sc-duet-checkbox::after,*.sc-duet-checkbox::before{box-sizing:border-box;padding:0;margin:0;background:transparent;border:0;-moz-appearance:none;-webkit-appearance:none;appearance:none}.sc-duet-checkbox-h{box-sizing:border-box;padding:0;margin:0;background:transparent;border:0;-moz-appearance:none;-webkit-appearance:none;appearance:none;margin-right:8px !important;margin-bottom:12px !important;display:inline-flex;width:100%;vertical-align:bottom;-webkit-tap-highlight-color:transparent}.sc-duet-checkbox-h:last-child,.sc-duet-checkbox-h:last-of-type{margin-right:0 !important}.sc-duet-checkbox-h:last-child:not(:only-child){margin-bottom:0 !important}.duet-m-0.sc-duet-checkbox-h{margin:0 !important}.duet-label.sc-duet-checkbox{position:relative;z-index:100;display:inline;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:400;line-height:1.5;color:#00294d;vertical-align:top;cursor:pointer;background:transparent;transition:300ms ease}.duet-theme-turva.sc-duet-checkbox .duet-label.sc-duet-checkbox{font-family:\"turva-sans\", -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\";color:#171c3a}.duet-label.sc-duet-checkbox span.sc-duet-checkbox{display:inline-block;width:calc(100% - 32px);font-size:1rem;font-weight:400;vertical-align:top}.duet-checkbox-container.sc-duet-checkbox{position:relative;width:100%;height:100%}.duet-checkbox.sc-duet-checkbox{padding:14px !important;position:absolute;top:0;left:0;z-index:2;width:100%;height:100%;cursor:pointer;opacity:0}.duet-checkbox.sc-duet-checkbox+label.sc-duet-checkbox::before{z-index:100;display:inline-block;width:20px;height:20px;margin:2px 10px 1px 1px;vertical-align:top;content:\"\";background:white;border:1px solid #00294d;border-radius:4px}.duet-theme-turva.sc-duet-checkbox .duet-checkbox.sc-duet-checkbox+label.sc-duet-checkbox::before{border-color:#171c3a}.duet-checkbox.sc-duet-checkbox:checked+label.sc-duet-checkbox::before{background:#00294d;border:1px solid #00294d}.duet-theme-turva.sc-duet-checkbox .duet-checkbox.sc-duet-checkbox:checked+label.sc-duet-checkbox::before{background:#171c3a;border-color:#171c3a}.duet-checkbox.sc-duet-checkbox:focus+label.sc-duet-checkbox::before{box-shadow:0 0 0 4px rgba(0, 119, 179, 0.3), 0 0 0 1px #0077b3}.duet-theme-turva.sc-duet-checkbox .duet-checkbox.sc-duet-checkbox:focus+label.sc-duet-checkbox::before{box-shadow:0 0 0 4px rgba(23, 28, 58, 0.2), 0 0 0 1px #171c3a}.duet-checkbox.sc-duet-checkbox+label.sc-duet-checkbox{position:static}.duet-checkbox.sc-duet-checkbox:checked+label.sc-duet-checkbox::after{position:absolute;top:6px;left:5px;z-index:200;width:12px;height:12px;pointer-events:none;content:\"\";background:transparent url(\"data:image/svg+xml,%3Csvg%20fill%3D%27white%27%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%20width%3D%2724%27%20height%3D%2724%27%20viewBox%3D%270%200%2024%2024%27%3E%3Cpath%20d%3D%27M23.374.287a1.5%2C1.5%2C0%2C0%2C0-2.093.345L7.246%2C20.2%2C2.561%2C15.511A1.5%2C1.5%2C0%2C1%2C0%2C.439%2C17.632l5.935%2C5.934a1.525%2C1.525%2C0%2C0%2C0%2C2.279-.186l15.066-21A1.5%2C1.5%2C0%2C0%2C0%2C23.374.287Z%27%20%2F%3E%3C%2Fsvg%3E\") no-repeat 0 0;background-size:100% auto}.duet-checkbox[disabled].sc-duet-checkbox{cursor:default}.duet-checkbox[disabled].sc-duet-checkbox+label.sc-duet-checkbox{color:#657787}.duet-theme-turva.sc-duet-checkbox .duet-checkbox[disabled].sc-duet-checkbox+label.sc-duet-checkbox{color:#747475}.duet-checkbox[disabled].sc-duet-checkbox+label.sc-duet-checkbox::before{border-color:#cfd2d4}.duet-theme-turva.sc-duet-checkbox .duet-checkbox[disabled].sc-duet-checkbox+label.sc-duet-checkbox::before{border-color:#cfcfd1}.duet-checkbox[disabled].sc-duet-checkbox:checked+label.sc-duet-checkbox::before{background:#657787;border:1px solid #657787}.duet-theme-turva.sc-duet-checkbox .duet-checkbox[disabled].sc-duet-checkbox:checked+label.sc-duet-checkbox::before{background:#747475;border-color:#747475}.duet-label-hidden.sc-duet-checkbox .duet-label.sc-duet-checkbox span.sc-duet-checkbox{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0 0 0 0);border:0}";
6680
6687
 
6681
6688
  class DuetCheckbox {
6682
6689
  constructor(hostRef) {
@@ -6809,11 +6816,24 @@ class DuetCheckbox {
6809
6816
 
6810
6817
  var messagingInfo={"title":"messaging-info","tags":"messaging info information circle","svg":"<svg fill=\"currentColor\" viewBox=\"0 0 24 24\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\"><path d=\"M13.5 17.25A2.252 2.252 0 0 1 11.25 15v-3.75h-.75a.75.75 0 0 1 0-1.5h.75c.827 0 1.5.673 1.5 1.5V15c0 .414.336.75.75.75h.75a.75.75 0 0 1 0 1.5z\"/><circle cx=\"11.625\" cy=\"7.125\" r=\"1.125\"/><path d=\"M12 24C5.383 24 0 18.617 0 12S5.383 0 12 0s12 5.383 12 12-5.383 12-12 12zm0-22.5C6.21 1.5 1.5 6.21 1.5 12S6.21 22.5 12 22.5 22.5 17.79 22.5 12 17.79 1.5 12 1.5z\"/></svg>"};
6811
6818
 
6819
+ const focusElement = (element) => {
6820
+ if ("setFocus" in element) {
6821
+ element.setFocus();
6822
+ }
6823
+ else {
6824
+ element.focus();
6825
+ }
6826
+ };
6827
+ const FocusGuard = ({ moveFocusTo }) => {
6828
+ return hAsync("div", { class: "duet-focus-guard", "aria-hidden": "true", tabIndex: 0, onFocus: () => focusElement(moveFocusTo) });
6829
+ };
6830
+
6812
6831
  const duetChoiceCss = "*.sc-duet-choice,*.sc-duet-choice::after,*.sc-duet-choice::before{box-sizing:border-box;padding:0;margin:0;background:transparent;border:0;-moz-appearance:none;-webkit-appearance:none;appearance:none}.sc-duet-choice-h{box-sizing:border-box;padding:0;margin:0;background:transparent;border:0;-moz-appearance:none;-webkit-appearance:none;appearance:none;margin-right:16px !important;margin-bottom:12px !important;display:inline-flex;flex-direction:column;width:auto;max-width:100%;vertical-align:bottom;-webkit-tap-highlight-color:transparent}.sc-duet-choice-h:last-child,.sc-duet-choice-h:last-of-type{margin-right:0 !important}@media (max-width: 35.9375em){.sc-duet-choice-h{width:100%}}.duet-expand.sc-duet-choice-h{width:100% !important}.duet-m-0.sc-duet-choice-h{margin:0 !important}.duet-fixed.sc-duet-choice-h{width:auto !important}.vertical.sc-duet-choice-h{margin-right:0 !important}.horizontal.sc-duet-choice-h{margin-bottom:0 !important}@media (min-width: 48em){.horizontal-responsive.sc-duet-choice-h{margin-bottom:0 !important;margin-right:16px !important}.horizontal-responsive.sc-duet-choice-h:last-child,.horizontal-responsive.sc-duet-choice-h:last-of-type{margin-right:0 !important}}.sc-duet-choice-h:last-child:not(:only-child){margin-right:0 !important}.duet-choice-card.sc-duet-choice{position:relative;display:block;width:100%;min-width:8rem;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:400;-webkit-hyphens:auto;hyphens:auto;line-height:1.1;color:#00294d !important;text-align:left;background:white;border-width:2px}.duet-choice-card.duet-p-0.sc-duet-choice{padding:0 !important}.duet-choice-card.duet-m-0.sc-duet-choice{margin:0 !important}.duet-theme-turva.sc-duet-choice .duet-choice-card.sc-duet-choice{font-family:\"turva-sans\", -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\";color:#171c3a !important}.duet-choice-card-flextainer.sc-duet-choice{display:flex}.duet-choice-label.sc-duet-choice{-webkit-user-select:none;user-select:none;position:relative;z-index:100;display:block;width:100%;padding:20px 48px 20px 16px;font-size:1rem;font-weight:600;text-decoration:none;cursor:pointer;border:2px solid #e1e3e6;border-radius:4px;transition:background-color 150ms ease}.has-info.sc-duet-choice .duet-choice-label.sc-duet-choice{padding-right:110px;border-top-right-radius:0;border-bottom-right-radius:0}.info.sc-duet-choice .duet-choice-label.sc-duet-choice{border-bottom-right-radius:0;border-bottom-left-radius:0}.duet-theme-turva.sc-duet-choice .duet-choice-label.sc-duet-choice{border-color:#e4e4e6}.duet-theme-turva.sc-duet-choice .info.sc-duet-choice .duet-choice-label.sc-duet-choice{border-color:#e4e4e6}.duet-choice-label.sc-duet-choice:not(.no-hover):hover{border-color:#909599}.duet-choice-label.sc-duet-choice:not(.no-hover):hover .duet-checkmark-container.sc-duet-choice{border-color:#909599}.duet-theme-turva.sc-duet-choice .duet-choice-label.sc-duet-choice:not(.no-hover):hover{border-color:#747475}.duet-theme-turva.sc-duet-choice .duet-choice-label.sc-duet-choice:not(.no-hover):hover .duet-checkmark-container.sc-duet-choice{border-color:#747475}.duet-theme-turva.sc-duet-choice .info.sc-duet-choice .duet-choice-label.sc-duet-choice:not(.no-hover):hover{border-color:#747475}.duet-choice-label.sc-duet-choice:active{opacity:0.75;transition:none !important}.has-icon.sc-duet-choice .duet-choice-label.sc-duet-choice{padding-left:48px}.checked.sc-duet-choice .duet-choice-label.sc-duet-choice{color:#0077b3 !important;background:#f3f9fc;border-color:#0077b3 !important}.checked.sc-duet-choice .duet-choice-label.sc-duet-choice .duet-checkmark-container.sc-duet-choice{border-color:#0077b3}.duet-theme-turva.sc-duet-choice .checked.sc-duet-choice .duet-choice-label.sc-duet-choice{color:#171c3a !important;background:#f5f5f7;border-color:#171c3a !important}.duet-theme-turva.sc-duet-choice .checked.sc-duet-choice .duet-choice-label.sc-duet-choice .duet-checkmark-container.sc-duet-choice{border-color:#c60c30}.checked.collapsible.sc-duet-choice .duet-choice-label.sc-duet-choice{border-bottom:0 !important;border-bottom-right-radius:0;border-bottom-left-radius:0}input.sc-duet-choice:focus{outline:0}.user-is-tabbing.sc-duet-choice-h input.sc-duet-choice:checked:focus+.duet-choice-label.sc-duet-choice{box-shadow:0 0 0 4px rgba(0, 119, 179, 0.3)}.user-is-tabbing.sc-duet-choice-h input.sc-duet-choice:not(:checked):focus+.duet-choice-label.sc-duet-choice{box-shadow:0 0 0 4px rgba(0, 119, 179, 0.3), 0 0 0 1px #0077b3}.user-is-tabbing.duet-theme-turva.sc-duet-choice-h input.sc-duet-choice:checked:focus+.duet-choice-label.sc-duet-choice{box-shadow:0 0 0 4px rgba(23, 28, 58, 0.2)}.user-is-tabbing.duet-theme-turva.sc-duet-choice-h input.sc-duet-choice:not(:checked):focus+.duet-choice-label.sc-duet-choice{box-shadow:0 0 0 4px rgba(23, 28, 58, 0.2), 0 0 0 1px #171c3a}input[disabled].sc-duet-choice+.duet-choice-label.sc-duet-choice{color:#657787 !important;cursor:default !important;background:#f5f8fa !important;border-color:#e1e3e6 !important}input[disabled].sc-duet-choice+.duet-choice-label.sc-duet-choice .duet-checkmark.sc-duet-choice{border-color:#657787 !important}.duet-theme-turva.sc-duet-choice input[disabled].sc-duet-choice+.duet-choice-label.sc-duet-choice{color:#747475 !important;background:#f5f5f7 !important;border-color:#e4e4e6 !important}.duet-theme-turva.sc-duet-choice input[disabled].sc-duet-choice+.duet-choice-label.sc-duet-choice .duet-checkmark.sc-duet-choice{border-color:#747475 !important}.checked.sc-duet-choice input[disabled].sc-duet-choice+.duet-choice-label.sc-duet-choice{background:#e1e3e6 !important;border-color:#e1e3e6 !important}.duet-theme-turva.sc-duet-choice .checked.sc-duet-choice input[disabled].sc-duet-choice+.duet-choice-label.sc-duet-choice{background:#e4e4e6 !important;border-color:#e4e4e6 !important}.duet-checkmark-container.sc-duet-choice{position:absolute;top:17.7777777778px;right:16px;width:20px;height:20px;border:1px solid #909599;border-radius:4px;transition:border 300ms ease}.duet-theme-turva.sc-duet-choice .duet-checkmark-container.sc-duet-choice{border-color:#747475}.checked.sc-duet-choice .duet-checkmark-container.sc-duet-choice{background:#0077b3;border-color:#0077b3;transition:none}.duet-theme-turva.sc-duet-choice .checked.sc-duet-choice .duet-checkmark-container.sc-duet-choice{background:#171c3a;border-color:#171c3a !important}.duet-checkmark-container.duet-checkmark-radio.sc-duet-choice{border-radius:50%}[disabled].sc-duet-choice+label.sc-duet-choice .duet-checkmark-container.sc-duet-choice{border-color:#cfd2d4 !important}.duet-theme-turva.sc-duet-choice [disabled].sc-duet-choice+label.sc-duet-choice .duet-checkmark-container.sc-duet-choice{border-color:#cfcfd1 !important}.checked.sc-duet-choice [disabled].sc-duet-choice+label.sc-duet-choice .duet-checkmark-container.sc-duet-choice{background:#cfd2d4 !important}.duet-theme-turva.sc-duet-choice .checked.sc-duet-choice [disabled].sc-duet-choice+label.sc-duet-choice .duet-checkmark-container.sc-duet-choice{background:#cfcfd1 !important}.duet-checkmark.sc-duet-choice{position:absolute;top:10px;left:3px;width:5.3333333333px;height:11.8518518519px;border-top:2px solid white;border-right:2px solid white;opacity:1;transform:scaleX(-1) rotate(135deg) translateZ(0);transform-origin:left top;animation-name:duet-checkmark;animation-duration:600ms;animation-timing-function:ease-out;animation-fill-mode:forwards}@keyframes duet-checkmark{0%{width:0;height:0;opacity:1}20%{width:5.3333333333px;height:0;opacity:1}40%,100%{width:5.3333333333px;height:11.8518518519px;opacity:1}}.duet-choice-card-icon.sc-duet-choice{position:absolute;top:50%;left:16px;transform:translateY(-50%)}.duet-choice-card-icon.sc-duet-choice duet-icon.sc-duet-choice{display:block}.duet-choice-section-hidden.sc-duet-choice{display:none}.duet-choice-card-info.duet-choice-card-collapsed.sc-duet-choice,.duet-choice-card-collapsed.duet-choice-card-collapsible.sc-duet-choice{position:relative;width:auto;padding:0 !important;background:unset !important;border:0;border-radius:0}.duet-choice-card-info.sc-duet-choice,.duet-choice-card-collapsible.sc-duet-choice{padding:28px !important;position:relative;z-index:200;width:100%;font-weight:400;color:#00294d;border:2px solid #e1e3e6;border-top:0;border-radius:0 0 4px 4px}.duet-theme-turva.sc-duet-choice .duet-choice-card-info.sc-duet-choice,.duet-theme-turva.sc-duet-choice .duet-choice-card-collapsible.sc-duet-choice{color:#171c3a;border-color:#171c3a}.checked.sc-duet-choice .duet-choice-card-info.sc-duet-choice,.checked.sc-duet-choice .duet-choice-card-collapsible.sc-duet-choice{display:block}.duet-choice-card-info-expanded.sc-duet-choice,.duet-choice-card-collapsible-expanded.sc-duet-choice{display:block}.duet-choice-card-collapsible.sc-duet-choice{background:white;border:2px solid #0077b3;border-top:0}.duet-choice-card-collapsible.duet-theme-turva.sc-duet-choice{background:white;border-color:#171c3a}.duet-choice-card-collapsible-disabled.sc-duet-choice{background:#f5f8fa;border-color:#e1e3e6}.duet-choice-card-collapsible-disabled.duet-theme-turva.sc-duet-choice{background:#f5f5f7;border-color:#e4e4e6}.duet-choice-card-info.sc-duet-choice{font-size:0.875rem;line-height:1.5;background:#f5f8fa;transition:150ms ease-out}.duet-choice-card-info.duet-theme-turva.sc-duet-choice{background:#f5f5f7;border-color:#e4e4e6}.duet-choice-info-toggle.sc-duet-choice{display:flex;flex-shrink:0;justify-content:center;width:57.6px;padding-top:18px;cursor:pointer;background:white;border:2px solid #e1e3e6;border-left:0 none;border-top-right-radius:4px;border-bottom-right-radius:4px;-webkit-appearance:none;appearance:none}.duet-choice-info-toggle[aria-expanded=true].sc-duet-choice{background:#f5f8fa;border-bottom:0;border-bottom-right-radius:0}.duet-choice-info-toggle[disabled].sc-duet-choice{pointer-events:none;background:#f5f8fa !important;border-color:#e1e3e6 !important}.duet-choice-info-toggle[disabled].sc-duet-choice .duet-choice-info-icon.sc-duet-choice{color:#909599 !important}.duet-choice-info-toggle[disabled].duet-theme-turva.sc-duet-choice{background:#f5f5f7 !important;border-color:#e4e4e6 !important}.duet-choice-info-toggle[disabled].duet-theme-turva.sc-duet-choice .duet-choice-info-icon.sc-duet-choice{color:#747475 !important}.duet-choice-info-toggle.sc-duet-choice:focus{outline:none}.user-is-tabbing.sc-duet-choice-h .duet-choice-info-toggle.sc-duet-choice:focus{box-shadow:0 0 0 4px rgba(0, 119, 179, 0.3), 0 0 0 1px #0077b3}.duet-choice-label.sc-duet-choice:not(.no-hover):hover .duet-choice-info-toggle.sc-duet-choice{border-left-color:#909599}.checked.sc-duet-choice .duet-choice-info-toggle.sc-duet-choice{border-left-color:#0077b3 !important}.duet-choice-info-toggle.sc-duet-choice duet-icon.sc-duet-choice{display:block}.duet-choice-info-toggle.sc-duet-choice .duet-choice-info-icon.sc-duet-choice{color:#0077b3}.duet-theme-turva.sc-duet-choice .duet-choice-info-toggle.sc-duet-choice .duet-choice-info-icon.sc-duet-choice{color:#c60c30}.duet-choice-input.sc-duet-choice{position:absolute !important;width:auto;height:auto;overflow:hidden;clip:rect(1px, 1px, 1px, 1px);color:transparent}";
6813
6832
 
6814
6833
  /**
6815
6834
  * @slot unnamed default slot - The component’s primary content. All child nodes that do not have a slot attribute defined are inserted into this primary slot.
6816
6835
  * @slot info - Info content. Anything inserted into this slot is displayed in a collapsible info box.
6836
+ * @slot collapsible_header - header that is only added to collapsible element, this header should be used when the components collapsible area contains additional interactive elements (such as form items) and should be user for a short description of the content below it, it is mandatory for good accessibility to use this - and aria-decribe-by will point to it. If you use the collapsible area with simple text - describe-by will point to this area
6817
6837
  * @slot additional - Additional content. Anything inserted into this slot is displayed as additional content under the label and caption
6818
6838
  */
6819
6839
  class DuetChoice {
@@ -6822,8 +6842,11 @@ class DuetChoice {
6822
6842
  this.duetChange = createEvent$2(this, "duetChange", 7);
6823
6843
  this.duetFocus = createEvent$2(this, "duetFocus", 7);
6824
6844
  this.duetBlur = createEvent$2(this, "duetBlur", 7);
6845
+ this.hasHeader = false;
6825
6846
  this.choiceId = createID("DuetChoice");
6826
6847
  this.expandId = createID("DuetChoiceExpand");
6848
+ this.headerId = createID("DuetChoiceHeader");
6849
+ this.infoButtonId = createID("DuetChoiceInfoButton");
6827
6850
  /**
6828
6851
  * State() variables
6829
6852
  * Inlined decorator, alphabetical order.
@@ -6901,6 +6924,24 @@ class DuetChoice {
6901
6924
  * browser from displaying its own validation errors.
6902
6925
  */
6903
6926
  this.required = false;
6927
+ /**
6928
+ * Placeholder defaults
6929
+ * @default { fi: "pp.kk.vvvv", en: "dd.mm.yyyy", sv: "dd.mm.åååå" }
6930
+ */
6931
+ this.infoLabelDefaults = {
6932
+ fi: "Lisätietoja",
6933
+ en: "More information about",
6934
+ sv: "Mera information om",
6935
+ };
6936
+ /**
6937
+ * Hint text to display before the user types into the date picker input.
6938
+ * @default {
6939
+ * fi: "Lisätietoja",
6940
+ * en: "More information about",
6941
+ * sv: "Mera information om",
6942
+ * }
6943
+ */
6944
+ this.infoLabel = getLocaleString(this.infoLabelDefaults, getLanguage());
6904
6945
  this.onMouseEnter = () => {
6905
6946
  this.isHovering = true;
6906
6947
  };
@@ -6975,6 +7016,7 @@ class DuetChoice {
6975
7016
  componentWillLoad() {
6976
7017
  inheritGlobalTheme(this);
6977
7018
  this.hasInfo = !!this.element.querySelector("[slot='info']");
7019
+ this.hasHeader = !!this.element.querySelector('[slot="header"]');
6978
7020
  this.hasAdditional = !!this.element.querySelector("[slot='additional']");
6979
7021
  }
6980
7022
  /**
@@ -6995,8 +7037,11 @@ class DuetChoice {
6995
7037
  handleHostKeyDown() {
6996
7038
  this.isKeyDown = true;
6997
7039
  }
6998
- handleHostKeyUp() {
7040
+ handleHostKeyUp(ev) {
6999
7041
  this.isKeyDown = false;
7042
+ if (isEscapeKey(ev) && this.isInfoOpen) {
7043
+ this.toggleInfo();
7044
+ }
7000
7045
  }
7001
7046
  /**
7002
7047
  * Sets focus on the specified `duet-choice`. Use this method instead of the global
@@ -7010,7 +7055,12 @@ class DuetChoice {
7010
7055
  return this.accessibleDescribedBy;
7011
7056
  }
7012
7057
  if (this.collapsible || this.hasInfo) {
7013
- return this.expandId;
7058
+ if (this.hasHeader) {
7059
+ return this.headerId;
7060
+ }
7061
+ else {
7062
+ return this.expandId;
7063
+ }
7014
7064
  }
7015
7065
  return null;
7016
7066
  }
@@ -7042,6 +7092,7 @@ class DuetChoice {
7042
7092
  */
7043
7093
  render() {
7044
7094
  const identifier = this.identifier || this.choiceId;
7095
+ console.log(this.element);
7045
7096
  return (hAsync(Host, { class: {
7046
7097
  horizontal: this.groupDirection === "horizontal" && !this.groupResponsive,
7047
7098
  "horizontal-responsive": this.groupDirection === "horizontal" && this.groupResponsive,
@@ -7059,23 +7110,13 @@ class DuetChoice {
7059
7110
  info: this.isInfoOpen,
7060
7111
  collapsible: this.collapsible,
7061
7112
  "duet-p-0": this.padding === "none",
7062
- } }, hAsync("input", { class: "duet-choice-input", type: this.type, onFocus: this.onFocus, onBlur: this.onBlur, onChange: this.onChange, disabled: this.disabled || this.groupDisabled, required: this.required, id: identifier, name: this.name, value: this.value, checked: this.checked, "aria-controls": this.accessibleControls, "aria-activedescendant": this.accessibleActiveDescendant, "aria-owns": this.accessibleOwns, "aria-describedby": this.getAriaDescribedby(), onKeyDown: this.handleKeyDown, ref: input => (this.nativeInput = input) }), hAsync("label", { htmlFor: identifier, class: { "duet-choice-label": true, "no-hover": this.isHovering }, onClick: this.onClick }, this.icon && (hAsync("div", { class: "duet-choice-card-icon" }, hAsync("duet-icon", { margin: "none", size: "small", name: this.icon, color: "currentColor" }))), this.label, this.hasInfo ||
7063
- // this is an incredibly dirty way of both hiding the expanded / collapsed state text
7064
- // and an extremely bad way of notifying any screenreaders about state - unfortunately
7065
- // this is extremely difficult to do consistently across browsers so this hack is the best way todo it
7066
- (this.collapsible && (hAsync("span", { lang: "en", style: { opacity: "0", pointerEvents: "none", fontSize: "0", lineHeight: "0" } }, this.collapsible
7067
- ? this.checked
7068
- ? ", Expanded"
7069
- : ", Collapsed"
7070
- : this.isInfoOpen
7071
- ? ", Expanded"
7072
- : ", Collapsed"))), this.caption && (hAsync("div", null, hAsync("duet-spacer", { size: "xx-small" }), hAsync("duet-caption", { margin: "none", selected: this.checked }, this.caption))), this.hasAdditional && (hAsync("div", null, hAsync("duet-spacer", { size: "xx-small" }), hAsync("slot", { name: "additional" }))), hAsync("div", { class: { "duet-checkmark-container": true, "duet-checkmark-radio": this.type === "radio" } }, this.checked && hAsync("div", { class: "duet-checkmark" })))), this.hasInfo && !this.collapsible && (hAsync("button", { class: {
7113
+ } }, hAsync("input", { class: "duet-choice-input", type: this.type, onFocus: this.onFocus, onBlur: this.onBlur, onChange: this.onChange, disabled: this.disabled || this.groupDisabled, required: this.required, id: identifier, name: this.name, value: this.value, checked: this.checked, "aria-controls": this.accessibleControls, "aria-activedescendant": this.accessibleActiveDescendant, "aria-owns": this.accessibleOwns, "aria-describedby": this.getAriaDescribedby(), onKeyDown: this.handleKeyDown, ref: input => (this.nativeInput = input) }), hAsync("label", { htmlFor: identifier, class: { "duet-choice-label": true, "no-hover": this.isHovering }, onClick: this.onClick }, this.icon && (hAsync("div", { class: "duet-choice-card-icon" }, hAsync("duet-icon", { margin: "none", size: "small", name: this.icon, color: "currentColor" }))), this.label, this.caption && (hAsync("div", null, hAsync("duet-spacer", { size: "xx-small" }), hAsync("duet-caption", { margin: "none", selected: this.checked }, this.caption))), this.hasAdditional && (hAsync("div", null, hAsync("duet-spacer", { size: "xx-small" }), hAsync("slot", { name: "additional" }))), hAsync("div", { class: { "duet-checkmark-container": true, "duet-checkmark-radio": this.type === "radio" } }, this.checked && hAsync("div", { class: "duet-checkmark" })))), this.hasInfo && !this.collapsible && (hAsync("button", { ref: button => (this.infoButtonEl = button), id: this.infoButtonId, class: {
7073
7114
  "duet-choice-info-toggle": true,
7074
7115
  "duet-theme-turva": this.theme === "turva",
7075
- }, onMouseEnter: this.onMouseEnter, onMouseLeave: this.onMouseLeave, onClick: this.toggleInfo, disabled: this.disabled || this.groupDisabled, "aria-expanded": this.isInfoOpen ? "true" : "false", "aria-controls": this.expandId, "aria-flowto": this.expandId, tabindex: this.type === "radio" && !this.checked ? "-1" : "0", type: "button" }, hAsync("duet-visually-hidden", { "aria-hidden": !this.isBlurred ? "true" : "false" }, this.accessibleLabelInfoButton), hAsync("div", { class: "duet-choice-info-icon" }, hAsync("duet-icon", { icon: messagingInfo.svg, margin: "none", size: "small", color: "currentColor" }))))), this.collapsible || this.hasInfo ? (hAsync("div", { class: this.getClassNames(), id: this.expandId }, hAsync("span", { class: {
7116
+ }, onMouseEnter: this.onMouseEnter, onMouseLeave: this.onMouseLeave, onClick: this.toggleInfo, disabled: this.disabled || this.groupDisabled, "aria-expanded": this.isInfoOpen ? "true" : "false", "aria-label": `${this.infoLabel} ${this.label}`, "aria-controls": this.expandId, "aria-flowto": this.expandId, tabindex: this.type === "radio" && !this.checked ? "-1" : "0", type: "button" }, hAsync("duet-visually-hidden", { "aria-hidden": !this.isBlurred ? "true" : "false" }, this.accessibleLabelInfoButton), hAsync("div", { class: "duet-choice-info-icon" }, hAsync("duet-icon", { icon: messagingInfo.svg, margin: "none", size: "small", color: "currentColor" }))))), this.collapsible || this.hasInfo ? (hAsync("div", { class: this.getClassNames(), id: this.expandId }, hAsync("span", { class: {
7076
7117
  "duet-choice-section-visible": this.collapsible ? this.checked : this.isInfoOpen,
7077
7118
  "duet-choice-section-hidden": this.collapsible ? !this.checked : !this.isInfoOpen,
7078
- } }, this.hasInfo ? (hAsync("span", null, hAsync("slot", { name: "info" }), hAsync("slot", null))) : (hAsync("span", null, hAsync("slot", null)))))) : null));
7119
+ } }, hAsync("span", { id: this.headerId }, hAsync("slot", { name: "header" })), this.hasInfo ? (hAsync("span", null, hAsync("span", { "aria-relevant": "all", "aria-atomic": "true", "aria-live": this.isInfoOpen ? "polite" : "off" }, hAsync("slot", { name: "info" })), hAsync("slot", null))) : (hAsync("span", null, hAsync("slot", null)))), this.isInfoOpen && hAsync(FocusGuard, { moveFocusTo: this.infoButtonEl }))) : null));
7079
7120
  }
7080
7121
  get element() { return getElement(this); }
7081
7122
  static get style() { return duetChoiceCss; }
@@ -7107,6 +7148,8 @@ class DuetChoice {
7107
7148
  "groupResponsive": [4, "group-responsive"],
7108
7149
  "disabled": [516],
7109
7150
  "required": [4],
7151
+ "infoLabelDefaults": [1, "accessible-label-info-default"],
7152
+ "infoLabel": [1, "info-label"],
7110
7153
  "isHovering": [32],
7111
7154
  "isInfoOpen": [32],
7112
7155
  "isBlurred": [32],
@@ -7118,19 +7161,41 @@ class DuetChoice {
7118
7161
  }; }
7119
7162
  }
7120
7163
 
7121
- const watchForOptions = (containerEl, tagName, onChange) => {
7164
+ const watchFor = (containerEl, tagName, onChange, changeHandler, options = {
7165
+ childList: true,
7166
+ subtree: true,
7167
+ }) => {
7122
7168
  let mutation;
7123
7169
  if (typeof MutationObserver !== "undefined") {
7124
7170
  mutation = new MutationObserver(mutationList => {
7125
- onChange(getSelectedOption(mutationList, tagName));
7126
- });
7127
- mutation.observe(containerEl, {
7128
- childList: true,
7129
- subtree: true,
7171
+ onChange(changeHandler(mutationList, tagName));
7130
7172
  });
7173
+ mutation.observe(containerEl, options);
7131
7174
  }
7132
7175
  return mutation;
7133
7176
  };
7177
+ const watchForOptions = (containerEl, tagName, onChange) => {
7178
+ return watchFor(containerEl, tagName, onChange, getSelectedOption);
7179
+ };
7180
+ const watchForElement = (containerEl, tagName, onChange) => {
7181
+ return watchFor(containerEl, tagName, onChange, getElementItem, {
7182
+ childList: true,
7183
+ subtree: true,
7184
+ });
7185
+ };
7186
+ const getElementItem = (mutationList) => {
7187
+ let addedNode = false;
7188
+ let removedNode = false;
7189
+ mutationList.forEach(mut => {
7190
+ if (mut.addedNodes.length) {
7191
+ addedNode = true;
7192
+ }
7193
+ if (mut.removedNodes.length) {
7194
+ removedNode = true;
7195
+ }
7196
+ });
7197
+ return { addedNode, removedNode, mutationList };
7198
+ };
7134
7199
  const getSelectedOption = (mutationList, tagName) => {
7135
7200
  let newOption;
7136
7201
  mutationList.forEach(mut => {
@@ -7438,6 +7503,7 @@ const size_tappable_square = "48px";
7438
7503
  const size_icon_x_small = "16px";
7439
7504
  const size_icon_xxx_small = "7px";
7440
7505
  const size_button_border = "2px";
7506
+ const size_button_tiny_border = "1px";
7441
7507
  const size_icon_medium = "24px";
7442
7508
  const size_icon_small = "20px";
7443
7509
  const opacity_85 = "0.85";
@@ -7585,6 +7651,7 @@ var tokens = {
7585
7651
  size_icon_x_small: size_icon_x_small,
7586
7652
  size_icon_xxx_small: size_icon_xxx_small,
7587
7653
  size_button_border: size_button_border,
7654
+ size_button_tiny_border: size_button_tiny_border,
7588
7655
  size_icon_medium: size_icon_medium,
7589
7656
  size_icon_small: size_icon_small,
7590
7657
  opacity_85: opacity_85,
@@ -7735,6 +7802,7 @@ var tokens$1 = /*#__PURE__*/Object.freeze({
7735
7802
  size_icon_x_small: size_icon_x_small,
7736
7803
  size_icon_xxx_small: size_icon_xxx_small,
7737
7804
  size_button_border: size_button_border,
7805
+ size_button_tiny_border: size_button_tiny_border,
7738
7806
  size_icon_medium: size_icon_medium,
7739
7807
  size_icon_small: size_icon_small,
7740
7808
  opacity_85: opacity_85,
@@ -7959,18 +8027,6 @@ class DuetCookieConsent {
7959
8027
  }; }
7960
8028
  }
7961
8029
 
7962
- const focusElement = (element) => {
7963
- if ("setFocus" in element) {
7964
- element.setFocus();
7965
- }
7966
- else {
7967
- element.focus();
7968
- }
7969
- };
7970
- const FocusGuard = ({ moveFocusTo }) => {
7971
- return hAsync("div", { class: "duet-focus-guard", "aria-hidden": "true", tabIndex: 0, onFocus: () => focusElement(moveFocusTo) });
7972
- };
7973
-
7974
8030
  const formatOptionsShort = { day: "numeric", month: "long" };
7975
8031
  const formatOptionsLong = { day: "numeric", month: "long", year: "numeric" };
7976
8032
  const i18n$2 = {
@@ -8403,14 +8459,14 @@ class DuetDatePicker {
8403
8459
  */
8404
8460
  this.margin = "auto";
8405
8461
  /**
8406
- * The currently active language. This setting changes the month/year/day
8462
+ * The currently active language. This setting changes the month/year/day.
8407
8463
  * names and button labels as well as all screen reader labels.
8408
- * @deprecated this is now handled via the html lang tag, and is no longer used - kept to avoid breaking changes and ease unit testing
8464
+ * @deprecated this is now handled via the html lang tag, and is no longer used - kept to avoid breaking changes and ease unit testing.
8409
8465
  * @default "fi"
8410
8466
  */
8411
8467
  this.language = getLanguage();
8412
8468
  /**
8413
- * Placeholder defaults
8469
+ * Placeholder defaults.
8414
8470
  * @default { fi: "pp.kk.vvvv", en: "dd.mm.yyyy", sv: "dd.mm.åååå" }
8415
8471
  */
8416
8472
  this.placeholderDefaults = {
@@ -8473,7 +8529,7 @@ class DuetDatePicker {
8473
8529
  */
8474
8530
  this.min = "";
8475
8531
  /**
8476
- * Minimum date allowed to be picked. Must be in IS0-8601 format: YYYY-MM-DD
8532
+ * Minimum date allowed to be picked. Must be in IS0-8601 format: YYYY-MM-DD.
8477
8533
  * This setting can be used alone or together with the min property.
8478
8534
  */
8479
8535
  this.max = "";
@@ -8857,6 +8913,338 @@ class DuetDivider {
8857
8913
  }; }
8858
8914
  }
8859
8915
 
8916
+ const debounce = (func, timeout = 50) => {
8917
+ let timer;
8918
+ return (...args) => {
8919
+ clearTimeout(timer);
8920
+ timer = setTimeout(() => {
8921
+ func.apply(undefined, args);
8922
+ }, timeout);
8923
+ };
8924
+ };
8925
+
8926
+ const duetEditableTableCss = "/*!@duet-editable-table*/duet-editable-table.sc-duet-editable-table{box-sizing:border-box;padding:0;margin:0;background:transparent;border:0;-moz-appearance:none;-webkit-appearance:none;appearance:none}/*!@.duet-editable-table-header tr .duet-editable-table-header-hidden*/.duet-editable-table-header.sc-duet-editable-table tr.sc-duet-editable-table .duet-editable-table-header-hidden.sc-duet-editable-table{padding:0 !important;font-size:0;border-bottom:0}";
8927
+
8928
+ class DuetEditableTable {
8929
+ constructor(hostRef) {
8930
+ registerInstance(this, hostRef);
8931
+ /**
8932
+ * State() variables
8933
+ * @internal
8934
+ */
8935
+ this.tick = Date.now();
8936
+ /**
8937
+ * Map of items that contain list of things.
8938
+ */
8939
+ this.items = new Map();
8940
+ /**
8941
+ * Array of internationalized defaults for the default groups labels.
8942
+ */
8943
+ this.groupsLabelDefaults = {
8944
+ fi: "Kaikki",
8945
+ en: "All items",
8946
+ sv: "Alla objekt",
8947
+ };
8948
+ /**
8949
+ * Array of internationalized defaults for the default action labels.
8950
+ */
8951
+ this.actionLabelDefaults = {
8952
+ fi: "Toiminnot",
8953
+ en: "Actions",
8954
+ sv: "Handlingar",
8955
+ };
8956
+ /**
8957
+ * Array of group names that you want the editable table to display (can be used to hide or show groups depending on conditions).
8958
+ * @default { id: "all", label: this.groupsLabelDefaults, actionLabel: this.actionLabelDefaults }.
8959
+ * @example [{ id: "success", label: {fi: "Onnistunut", en: "Success", sv: "Alt klart", }}].
8960
+ */
8961
+ this.groups = [
8962
+ { id: "all", label: this.groupsLabelDefaults, actionLabel: this.actionLabelDefaults },
8963
+ ];
8964
+ /**
8965
+ * Array of actions that are mapped via the map variable to the various groups defined in group.
8966
+ * @default undefined
8967
+ * @example [{
8968
+ variation: "default",
8969
+ icon: "action-edit-2",
8970
+ id: "edit",
8971
+ map: ["success"],
8972
+ label: {
8973
+ fi: " Label",
8974
+ en: " Label",
8975
+ sv: " Label",
8976
+ }
8977
+ }]
8978
+ */
8979
+ this.actions = undefined;
8980
+ /**
8981
+ * Shows or hides the table labels.
8982
+ */
8983
+ this.hideGroups = false;
8984
+ /**
8985
+ * Exposes the aria role for optimizing accessibility.
8986
+ */
8987
+ this.accessibleRole = undefined;
8988
+ /**
8989
+ * Private methods.
8990
+ */
8991
+ this.kick = debounce(() => {
8992
+ this.tick = Date.now();
8993
+ }, 100); // will trigger re-render
8994
+ this.filterMap = needle => {
8995
+ if (needle === "all") {
8996
+ return Array.from(this.items);
8997
+ }
8998
+ return Array.from(this.items).filter(item => needle === item[1].group);
8999
+ };
9000
+ }
9001
+ /**
9002
+ * Component lifecycle events.
9003
+ */
9004
+ componentWillLoad() {
9005
+ if (typeof this.groups === "string") {
9006
+ this.internalGroupArray = sanitizeString(this.groups);
9007
+ }
9008
+ else {
9009
+ this.internalGroupArray = this.groups;
9010
+ }
9011
+ if (typeof this.actions === "string") {
9012
+ this.internalActionsArray = sanitizeString(this.actions);
9013
+ }
9014
+ else {
9015
+ this.internalActionsArray = this.actions;
9016
+ }
9017
+ inheritGlobalTheme(this);
9018
+ }
9019
+ /**
9020
+ * Method to force an update of a tabular data array.
9021
+ * when called the method will rerender the entire tabular structure.
9022
+ */
9023
+ async updateTable(passedItems = undefined) {
9024
+ this.items = new Map(passedItems || this.items);
9025
+ this.kick();
9026
+ }
9027
+ render() {
9028
+ return (hAsync(Host, { class: {
9029
+ "duet-theme-turva": this.theme === "turva",
9030
+ } }, this.internalGroupArray.map(group => {
9031
+ const currentGroup = this.filterMap(group.id);
9032
+ if (!currentGroup.length) {
9033
+ return;
9034
+ }
9035
+ return (hAsync("duet-table", { variation: "plain", breakpoint: "none", role: "", margin: this.hideGroups ? "none" : "auto" }, hAsync("table", { class: "duet-editable-table", "aria-role": this.accessibleRole }, hAsync("thead", { class: "duet-editable-table-header" }, hAsync("tr", null, hAsync("th", { class: {
9036
+ "duet-editable-table-header-hidden": this.hideGroups,
9037
+ } }, !this.hideGroups ? (getLocaleString(group.label)) : (hAsync("duet-visually-hidden", null, getLocaleString(group.label)))), hAsync("th", { class: {
9038
+ "duet-editable-table-header-hidden": this.hideGroups,
9039
+ } }, hAsync("duet-visually-hidden", null, group.actionLabel
9040
+ ? getLocaleString(group.actionLabel)
9041
+ : getLocaleString(this.actionLabelDefaults))))), hAsync("tbody", null, currentGroup.map(dataAsArray => {
9042
+ const [key, value] = dataAsArray;
9043
+ return (hAsync("duet-editable-table-item", { keyName: key, data: Object.assign({}, value), groupId: group.id, part: group.id, actions: this.internalActionsArray }));
9044
+ })))));
9045
+ })));
9046
+ }
9047
+ get element() { return getElement(this); }
9048
+ static get style() { return duetEditableTableCss; }
9049
+ static get cmpMeta() { return {
9050
+ "$flags$": 9,
9051
+ "$tagName$": "duet-editable-table",
9052
+ "$members$": {
9053
+ "items": [1040],
9054
+ "groupsLabelDefaults": [16],
9055
+ "actionLabelDefaults": [16],
9056
+ "groups": [1],
9057
+ "actions": [1],
9058
+ "hideGroups": [4, "hide-table-labels"],
9059
+ "accessibleRole": [1, "accessible-role"],
9060
+ "theme": [1025],
9061
+ "tick": [32],
9062
+ "updateTable": [64]
9063
+ },
9064
+ "$listeners$": undefined,
9065
+ "$lazyBundleId$": "-",
9066
+ "$attrsToReflect$": []
9067
+ }; }
9068
+ }
9069
+
9070
+ const duetEditableTableButtonCss = "*.sc-duet-editable-table-button,*.sc-duet-editable-table-button::after,*.sc-duet-editable-table-button::before{box-sizing:border-box;padding:0;margin:0;background:transparent;border:0;-moz-appearance:none;-webkit-appearance:none;appearance:none}.sc-duet-editable-table-button-h button.sc-duet-editable-table-button{display:flex;align-content:space-between;justify-content:center;min-width:32px;max-width:32px;height:100%;min-height:32px;max-height:32px;padding:0;margin:0;cursor:pointer !important;background-color:transparent;border:1px solid;border-radius:50%}.sc-duet-editable-table-button-h button.sc-duet-editable-table-button duet-icon.sc-duet-editable-table-button{align-self:center}";
9071
+
9072
+ class DuetEditableTableButton {
9073
+ constructor(hostRef) {
9074
+ registerInstance(this, hostRef);
9075
+ this.duetEditableItemAction = createEvent$2(this, "duetEditableItemAction", 7);
9076
+ this.isHovering = false;
9077
+ /**
9078
+ * Theme of the empty state component.
9079
+ */
9080
+ this.theme = "";
9081
+ /**
9082
+ * action items passed from host component
9083
+ * @internal
9084
+ */
9085
+ this.actions = undefined;
9086
+ /**
9087
+ * uid that gets passed along when the action is emitted
9088
+ * @internal
9089
+ */
9090
+ this.uid = "";
9091
+ /**
9092
+ * group associated with action
9093
+ * @internal
9094
+ */
9095
+ this.group = "";
9096
+ /**
9097
+ * key of the item in the map
9098
+ * @internal
9099
+ */
9100
+ this.keyName = "";
9101
+ this.onMouseEnter = () => {
9102
+ this.isHovering = true;
9103
+ };
9104
+ this.onMouseLeave = () => {
9105
+ this.isHovering = false;
9106
+ };
9107
+ }
9108
+ /**
9109
+ /**
9110
+ * Component lifecycle events.
9111
+ */
9112
+ componentWillLoad() {
9113
+ inheritGlobalTheme(this);
9114
+ }
9115
+ /**
9116
+ /**
9117
+ * private functions
9118
+ */
9119
+ emitActionEvent(ev) {
9120
+ this.duetEditableItemAction.emit({
9121
+ originalEvent: ev,
9122
+ uid: this.uid,
9123
+ group: this.group,
9124
+ action: this.actions.id,
9125
+ keyName: this.keyName,
9126
+ component: "duet-editable-table-item",
9127
+ });
9128
+ }
9129
+ /**
9130
+ * render() function
9131
+ * Always the last one in the class.
9132
+ */
9133
+ render() {
9134
+ return (hAsync("button", { style: {
9135
+ "border-color": this.isHovering
9136
+ ? getColorByName(this.actions.color_hover)
9137
+ : getColorByName(this.actions.color),
9138
+ }, onMouseEnter: this.onMouseEnter, onMouseLeave: this.onMouseLeave, role: "menuitem", class: "duet-editable-table-actions-items-button", "aria-label": this.actions.label ? getLocaleString(this.actions.label) : undefined, onClick: ev => this.emitActionEvent(ev) }, hAsync("duet-icon", { class: "duet-editable-table-actions-items-icon", size: "x-small", name: this.actions.icon, color: this.isHovering ? this.actions.color_hover : this.actions.color, margin: "none" })));
9139
+ }
9140
+ get el() { return getElement(this); }
9141
+ static get style() { return duetEditableTableButtonCss; }
9142
+ static get cmpMeta() { return {
9143
+ "$flags$": 2,
9144
+ "$tagName$": "duet-editable-table-button",
9145
+ "$members$": {
9146
+ "theme": [1025],
9147
+ "actions": [16],
9148
+ "uid": [1],
9149
+ "group": [1],
9150
+ "keyName": [1, "key-name"],
9151
+ "isHovering": [32]
9152
+ },
9153
+ "$listeners$": undefined,
9154
+ "$lazyBundleId$": "-",
9155
+ "$attrsToReflect$": []
9156
+ }; }
9157
+ }
9158
+
9159
+ //simple functional component that renders the data in the table
9160
+ const TableData = ({ data, groupId }, _children) => {
9161
+ if (typeof data === "string") {
9162
+ return hAsync("td", { innerHTML: data, class: "duet-editable-table-content", part: `${groupId}content` });
9163
+ }
9164
+ else {
9165
+ return (hAsync("td", { class: "duet-editable-table-content", part: `${groupId}content` }, data));
9166
+ }
9167
+ };
9168
+
9169
+ const duetEditableTableItemCss = "/*!@*,\n*::after,\n*::before*/*.sc-duet-editable-table-item,*.sc-duet-editable-table-item::after,*.sc-duet-editable-table-item::before{box-sizing:border-box;padding:0;margin:0;background:transparent;border:0;-moz-appearance:none;-webkit-appearance:none;appearance:none}/*!@:host*/.sc-duet-editable-table-item-h{display:table-row;height:32px}/*!@.duet-editable-table-content, .duet-editable-table-actions*/.duet-editable-table-content.sc-duet-editable-table-item,.duet-editable-table-actions.sc-duet-editable-table-item{height:32px;padding:12px 0;vertical-align:middle;break-word:break-all;border-bottom:1px solid #e1e3e6}/*!@.duet-editable-table-actions-items*/.duet-editable-table-actions-items.sc-duet-editable-table-item{display:flex;justify-content:flex-end}/*!@.duet-editable-table-actions-items duet-editable-table-button*/.duet-editable-table-actions-items.sc-duet-editable-table-item duet-editable-table-button.sc-duet-editable-table-item{padding-left:8px}/*!@.duet-editable-table .editable-item-small*/.duet-editable-table.sc-duet-editable-table-item .editable-item-small.sc-duet-editable-table-item{font-size:0.75rem;font-weight:400}";
9170
+
9171
+ class DuetEditableTableItem {
9172
+ constructor(hostRef) {
9173
+ registerInstance(this, hostRef);
9174
+ this.duetEditableItemAction = createEvent$2(this, "duetEditableItemAction", 7);
9175
+ this.isHovering = false;
9176
+ /**
9177
+ * Theme of the empty state component.
9178
+ */
9179
+ this.theme = "";
9180
+ /**
9181
+ * Actions that can be performed on the element
9182
+ */
9183
+ this.actions = undefined;
9184
+ /**
9185
+ * GroupId used to pierce the shadowdom - gets concatenated with "content & actions" and used as part="groupIDcontent/actions" to pierce the content/Action item
9186
+ * @internal
9187
+ */
9188
+ this.groupId = "";
9189
+ /**
9190
+ * Key used to identify item, when running actions
9191
+ */
9192
+ this.keyName = "";
9193
+ /**
9194
+ * Object of data itemsused to render the entire row
9195
+ */
9196
+ this.data = undefined;
9197
+ }
9198
+ watchPropHandler(_newValue, _oldValue) {
9199
+ // console.log("The new value of activated is: ", _newValue)
9200
+ }
9201
+ /**
9202
+ /**
9203
+ * Component lifecycle events.
9204
+ */
9205
+ componentWillLoad() {
9206
+ inheritGlobalTheme(this);
9207
+ }
9208
+ /**
9209
+ /**
9210
+ * private functions
9211
+ */
9212
+ /**
9213
+ * render() function
9214
+ * Always the last one in the class.
9215
+ */
9216
+ render() {
9217
+ return (hAsync(Host, { role: "row" }, hAsync(TableData, { data: this.data.item, groupId: this.groupId }), hAsync("td", { class: "duet-editable-table-actions" }, hAsync("div", { class: "duet-editable-table-actions-items", part: `${this.groupId}actions` }, this.actions.map(result => {
9218
+ const { map = undefined } = result;
9219
+ // if map has been specified, only show the current action if groupID matches the map array
9220
+ if (map && !map.includes(this.groupId)) {
9221
+ return;
9222
+ }
9223
+ return (hAsync("duet-editable-table-button", { keyName: this.keyName, group: this.data.group, uid: this.data.uid, actions: result, theme: this.theme }));
9224
+ })))));
9225
+ }
9226
+ get el() { return getElement(this); }
9227
+ static get watchers() { return {
9228
+ "data": ["watchPropHandler"]
9229
+ }; }
9230
+ static get style() { return duetEditableTableItemCss; }
9231
+ static get cmpMeta() { return {
9232
+ "$flags$": 9,
9233
+ "$tagName$": "duet-editable-table-item",
9234
+ "$members$": {
9235
+ "theme": [1025],
9236
+ "actions": [16],
9237
+ "groupId": [1, "group-id"],
9238
+ "keyName": [1, "key-name"],
9239
+ "data": [1040],
9240
+ "isHovering": [32]
9241
+ },
9242
+ "$listeners$": undefined,
9243
+ "$lazyBundleId$": "-",
9244
+ "$attrsToReflect$": []
9245
+ }; }
9246
+ }
9247
+
8860
9248
  const duetEmptyStateCss = "/*!@*,\n*::after,\n*::before*/*.sc-duet-empty-state,*.sc-duet-empty-state::after,*.sc-duet-empty-state::before{box-sizing:border-box;padding:0;margin:0;background:transparent;border:0;-moz-appearance:none;-webkit-appearance:none;appearance:none}/*!@:host*/.sc-duet-empty-state-h{box-sizing:border-box;padding:0;margin:0;background:transparent;border:0;-moz-appearance:none;-webkit-appearance:none;appearance:none;display:block;width:100%;height:100%}/*!@.duet-empty-state*/.duet-empty-state.sc-duet-empty-state{box-sizing:border-box;padding:0;margin:0;background:transparent;border:0;-moz-appearance:none;-webkit-appearance:none;appearance:none;width:100%;height:100%;padding:48px;color:#00294d;text-align:center;background:#f5f8fa;border-radius:4px}/*!@.duet-empty-state.duet-theme-turva*/.duet-empty-state.duet-theme-turva.sc-duet-empty-state{color:#171c3a;background:#f5f5f7}";
8861
9249
 
8862
9250
  class DuetEmptyState {
@@ -9137,6 +9525,7 @@ function isGridItem(element) {
9137
9525
  class DuetGrid {
9138
9526
  constructor(hostRef) {
9139
9527
  registerInstance(this, hostRef);
9528
+ this.distributeFormElement = false;
9140
9529
  /**
9141
9530
  * Enable or disable the automatic responsive behaviour of the grid component.
9142
9531
  * Setting this option to "true" makes sure that contents are stacked vertically
@@ -9153,7 +9542,9 @@ class DuetGrid {
9153
9542
  */
9154
9543
  this.direction = "horizontal";
9155
9544
  /**
9156
- * Adjusts the vertical alignment of the grid items.
9545
+ * Adjusts the vertical alignment of the grid items, if set to "form_distribute"
9546
+ * the grid will try to calculate correct paddings for any duet-input fields inside duet-grid-items,
9547
+ * so that they align even when displaying errors.
9157
9548
  */
9158
9549
  this.alignment = "top";
9159
9550
  /**
@@ -9165,14 +9556,34 @@ class DuetGrid {
9165
9556
  */
9166
9557
  this.mobile = "";
9167
9558
  }
9559
+ /**
9560
+ * Private functions
9561
+ */
9562
+ /**
9563
+ * Returns the element height including margins
9564
+ * @param element - element
9565
+ * @returns {number}
9566
+ */
9567
+ outerHeight(element) {
9568
+ const height = element.offsetHeight, style = window.getComputedStyle(element);
9569
+ return ["top", "bottom"]
9570
+ .map(side => parseInt(style[`margin-${side}`]))
9571
+ .reduce((total, side) => total + side, height);
9572
+ }
9168
9573
  /**
9169
9574
  * Component lifecycle events.
9170
9575
  */
9171
9576
  async connectedCallback() {
9172
9577
  const el = this.element;
9578
+ this.distributeFormElement = this.alignment === "form_distribute";
9173
9579
  this.mutationO = watchForOptions(el, "duet-grid-item", () => {
9174
9580
  this.updateGridItems();
9175
9581
  });
9582
+ if (this.distributeFormElement) {
9583
+ this.mutation1 = watchForElement(el, "duet-input", () => {
9584
+ this.updateGridItemsWithInputFields();
9585
+ });
9586
+ }
9176
9587
  this.updateGridItems();
9177
9588
  }
9178
9589
  disconnectedCallback() {
@@ -9180,6 +9591,10 @@ class DuetGrid {
9180
9591
  this.mutationO.disconnect();
9181
9592
  this.mutationO = undefined;
9182
9593
  }
9594
+ if (this.mutation1) {
9595
+ this.mutation1.disconnect();
9596
+ this.mutation1 = undefined;
9597
+ }
9183
9598
  }
9184
9599
  /**
9185
9600
  * Local methods
@@ -9191,6 +9606,27 @@ class DuetGrid {
9191
9606
  item.breakpoint = this.breakpoint;
9192
9607
  });
9193
9608
  }
9609
+ async updateGridItemsWithInputFields() {
9610
+ const items = Array.from(this.element.children).filter(isGridItem);
9611
+ let maxHeight = 0;
9612
+ const sizes = [];
9613
+ items.forEach(item => {
9614
+ const inputErrorDom = item.querySelector("span.duet-input-error");
9615
+ const height = inputErrorDom ? this.outerHeight(inputErrorDom) : 0;
9616
+ sizes.push(height);
9617
+ });
9618
+ maxHeight = Math.max(...sizes);
9619
+ items.forEach(item => {
9620
+ const inputErrorDom = item.querySelector("span.duet-input-error");
9621
+ const height = inputErrorDom ? this.outerHeight(inputErrorDom) : 0;
9622
+ if (height < maxHeight) {
9623
+ item.setAttribute("style", `padding-bottom: ${maxHeight - height}px;`);
9624
+ }
9625
+ else if (height === maxHeight) {
9626
+ item.setAttribute("style", `padding-bottom: 0px;`);
9627
+ }
9628
+ });
9629
+ }
9194
9630
  /**
9195
9631
  * render() function
9196
9632
  * Always the last one in the class.
@@ -9200,7 +9636,7 @@ class DuetGrid {
9200
9636
  "duet-grid": true,
9201
9637
  "duet-no-stacking": !this.responsive,
9202
9638
  "duet-grid-align-top": this.alignment === "top",
9203
- "duet-grid-align-bottom": this.alignment === "bottom",
9639
+ "duet-grid-align-bottom": this.alignment === "bottom" || this.alignment === "form_distribute",
9204
9640
  "duet-grid-align-center": this.alignment === "center",
9205
9641
  "duet-grid-align-stretch": this.alignment === "stretch",
9206
9642
  "duet-grid-align-baseline": this.alignment === "baseline",
@@ -9235,7 +9671,8 @@ class DuetGrid {
9235
9671
  "direction": [1],
9236
9672
  "alignment": [1],
9237
9673
  "distribution": [1],
9238
- "mobile": [1]
9674
+ "mobile": [1],
9675
+ "distributeFormElement": [32]
9239
9676
  },
9240
9677
  "$listeners$": undefined,
9241
9678
  "$lazyBundleId$": "-",
@@ -9960,7 +10397,7 @@ class DuetHeader {
9960
10397
  }; }
9961
10398
  }
9962
10399
 
9963
- const duetHeadingCss = "/*!@*,\n*::after,\n*::before*/*.sc-duet-heading,*.sc-duet-heading::after,*.sc-duet-heading::before{box-sizing:border-box;padding:0;margin:0;background:transparent;border:0;-moz-appearance:none;-webkit-appearance:none;appearance:none}/*!@:host*/.sc-duet-heading-h{box-sizing:border-box;padding:0;margin:0;background:transparent;border:0;-moz-appearance:none;-webkit-appearance:none;appearance:none;position:relative;display:block;width:100%}/*!@.duet-heading*/.duet-heading.sc-duet-heading{margin-bottom:16px !important;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-style:normal;font-weight:800;font-variant-numeric:tabular-nums;line-height:1.25;color:#00294d;text-decoration:none;letter-spacing:-0.01rem;word-break:break-word}@media (min-width: 36em){/*!@.duet-heading*/.duet-heading.sc-duet-heading{margin-bottom:20px !important}}/*!@.duet-heading.duet-theme-turva*/.duet-heading.duet-theme-turva.sc-duet-heading{font-family:\"turva-sans\", -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\";font-style:italic;font-weight:700;color:#171c3a}/*!@.duet-heading.duet-heading-border*/.duet-heading.duet-heading-border.sc-duet-heading{padding-bottom:20px;border-bottom:1px solid #e1e3e6}/*!@.duet-heading.duet-heading-hyphenate*/.duet-heading.duet-heading-hyphenate.sc-duet-heading{-webkit-hyphens:auto;hyphens:auto}/*!@.duet-heading.h0*/.duet-heading.h0.sc-duet-heading{font-size:9.4vw}/*!@.duet-heading.h0.duet-p-0*/.duet-heading.h0.duet-p-0.sc-duet-heading{padding:0 !important}/*!@.duet-heading.h0.duet-m-0*/.duet-heading.h0.duet-m-0.sc-duet-heading{margin:0 !important}@media (max-width: 31.914893617rem){/*!@.duet-heading.h0*/.duet-heading.h0.sc-duet-heading{font-size:3rem}}@media (min-width: 47.8723404255rem){/*!@.duet-heading.h0*/.duet-heading.h0.sc-duet-heading{font-size:4.5rem}}@media (max-width: 22.5em){/*!@.duet-heading.h0*/.duet-heading.h0.sc-duet-heading{font-size:2.25rem}}/*!@.duet-heading.h1*/.duet-heading.h1.sc-duet-heading{font-size:7vw}/*!@.duet-heading.h1.duet-p-0*/.duet-heading.h1.duet-p-0.sc-duet-heading{padding:0 !important}/*!@.duet-heading.h1.duet-m-0*/.duet-heading.h1.duet-m-0.sc-duet-heading{margin:0 !important}@media (max-width: 32.1428571429rem){/*!@.duet-heading.h1*/.duet-heading.h1.sc-duet-heading{font-size:2.25rem}}@media (min-width: 42.8571428571rem){/*!@.duet-heading.h1*/.duet-heading.h1.sc-duet-heading{font-size:3rem}}@media (max-width: 22.5em){/*!@.duet-heading.h1*/.duet-heading.h1.sc-duet-heading{font-size:1.5rem}}/*!@.duet-heading.h2*/.duet-heading.h2.sc-duet-heading{font-size:5.8vw}/*!@.duet-heading.h2.duet-p-0*/.duet-heading.h2.duet-p-0.sc-duet-heading{padding:0 !important}/*!@.duet-heading.h2.duet-m-0*/.duet-heading.h2.duet-m-0.sc-duet-heading{margin:0 !important}@media (max-width: 25.8620689655rem){/*!@.duet-heading.h2*/.duet-heading.h2.sc-duet-heading{font-size:1.5rem}}@media (min-width: 38.7931034483rem){/*!@.duet-heading.h2*/.duet-heading.h2.sc-duet-heading{font-size:2.25rem}}@media (max-width: 22.5em){/*!@.duet-heading.h2*/.duet-heading.h2.sc-duet-heading{font-size:1.375rem}}/*!@.duet-heading.h3*/.duet-heading.h3.sc-duet-heading{margin-bottom:12px !important;font-size:4.2vw}/*!@.duet-heading.h3.duet-p-0*/.duet-heading.h3.duet-p-0.sc-duet-heading{padding:0 !important}/*!@.duet-heading.h3.duet-m-0*/.duet-heading.h3.duet-m-0.sc-duet-heading{margin:0 !important}@media (max-width: 29.7619047619rem){/*!@.duet-heading.h3*/.duet-heading.h3.sc-duet-heading{font-size:1.25rem}}@media (min-width: 35.7142857143rem){/*!@.duet-heading.h3*/.duet-heading.h3.sc-duet-heading{font-size:1.5rem}}/*!@.duet-heading.h3.duet-theme-turva*/.duet-heading.h3.duet-theme-turva.sc-duet-heading{font-style:normal}/*!@.duet-heading.h3.duet-heading-border*/.duet-heading.h3.duet-heading-border.sc-duet-heading{padding-bottom:20px}/*!@.duet-heading.h4*/.duet-heading.h4.sc-duet-heading{margin-bottom:8px !important;font-size:4vw;letter-spacing:0}/*!@.duet-heading.h4.duet-p-0*/.duet-heading.h4.duet-p-0.sc-duet-heading{padding:0 !important}/*!@.duet-heading.h4.duet-m-0*/.duet-heading.h4.duet-m-0.sc-duet-heading{margin:0 !important}@media (max-width: 27.5rem){/*!@.duet-heading.h4*/.duet-heading.h4.sc-duet-heading{font-size:1.1rem}}@media (min-width: 31.25rem){/*!@.duet-heading.h4*/.duet-heading.h4.sc-duet-heading{font-size:1.25rem}}/*!@.duet-heading.h4.duet-theme-turva*/.duet-heading.h4.duet-theme-turva.sc-duet-heading{font-style:normal;font-weight:700}/*!@.duet-heading.h4.duet-heading-border*/.duet-heading.h4.duet-heading-border.sc-duet-heading{padding-bottom:20px}/*!@.duet-heading.h5*/.duet-heading.h5.sc-duet-heading{margin-bottom:8px !important;font-size:4vw;font-weight:600;letter-spacing:0}/*!@.duet-heading.h5.duet-p-0*/.duet-heading.h5.duet-p-0.sc-duet-heading{padding:0 !important}/*!@.duet-heading.h5.duet-m-0*/.duet-heading.h5.duet-m-0.sc-duet-heading{margin:0 !important}@media (max-width: 27.5rem){/*!@.duet-heading.h5*/.duet-heading.h5.sc-duet-heading{font-size:1.1rem}}@media (min-width: 28.4090909091rem){/*!@.duet-heading.h5*/.duet-heading.h5.sc-duet-heading{font-size:1.1363636364rem}}/*!@.duet-heading.h5.duet-theme-turva*/.duet-heading.h5.duet-theme-turva.sc-duet-heading{font-style:normal;font-weight:700}/*!@.duet-heading.h5.duet-heading-border*/.duet-heading.h5.duet-heading-border.sc-duet-heading{padding-bottom:16px}/*!@.duet-heading.h6*/.duet-heading.h6.sc-duet-heading{margin-bottom:8px !important;font-size:1rem;font-weight:600;letter-spacing:0}/*!@.duet-heading.h6.duet-p-0*/.duet-heading.h6.duet-p-0.sc-duet-heading{padding:0 !important}/*!@.duet-heading.h6.duet-m-0*/.duet-heading.h6.duet-m-0.sc-duet-heading{margin:0 !important}/*!@.duet-heading.h6.duet-theme-turva*/.duet-heading.h6.duet-theme-turva.sc-duet-heading{font-style:normal;font-weight:700}/*!@.duet-heading.h6.duet-heading-border*/.duet-heading.h6.duet-heading-border.sc-duet-heading{padding-bottom:16px}/*!@.duet-heading.duet-semibold, .duet-heading.duet-theme-turva.duet-semibold*/.duet-heading.duet-semibold.sc-duet-heading,.duet-heading.duet-theme-turva.duet-semibold.sc-duet-heading{font-style:normal !important;font-weight:600 !important}";
10400
+ const duetHeadingCss = "/*!@*,\n*::after,\n*::before*/*.sc-duet-heading,*.sc-duet-heading::after,*.sc-duet-heading::before{box-sizing:border-box;padding:0;margin:0;background:transparent;border:0;-moz-appearance:none;-webkit-appearance:none;appearance:none}/*!@:host*/.sc-duet-heading-h{box-sizing:border-box;padding:0;margin:0;background:transparent;border:0;-moz-appearance:none;-webkit-appearance:none;appearance:none;position:relative;display:block;width:100%}/*!@.duet-heading*/.duet-heading.sc-duet-heading{margin-bottom:16px !important;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-style:normal;font-weight:800;font-variant-numeric:tabular-nums;line-height:1.25;color:#00294d;text-decoration:none;letter-spacing:-0.01rem;word-break:break-word}@media (min-width: 36em){/*!@.duet-heading*/.duet-heading.sc-duet-heading{margin-bottom:20px !important}}/*!@.duet-heading.duet-theme-turva*/.duet-heading.duet-theme-turva.sc-duet-heading{font-family:\"turva-sans\", -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\";font-style:italic;font-weight:700;color:#171c3a}/*!@.duet-heading.duet-heading-border*/.duet-heading.duet-heading-border.sc-duet-heading{padding-bottom:20px;border-bottom:1px solid #e1e3e6}/*!@.duet-heading.duet-heading-border.duet-heading-border-solid*/.duet-heading.duet-heading-border.duet-heading-border-solid.sc-duet-heading{border-bottom-color:#657787}/*!@.duet-heading.duet-heading-hyphenate*/.duet-heading.duet-heading-hyphenate.sc-duet-heading{-webkit-hyphens:auto;hyphens:auto}/*!@.duet-heading.h0*/.duet-heading.h0.sc-duet-heading{font-size:9.4vw}/*!@.duet-heading.h0.duet-p-0*/.duet-heading.h0.duet-p-0.sc-duet-heading{padding:0 !important}/*!@.duet-heading.h0.duet-m-0*/.duet-heading.h0.duet-m-0.sc-duet-heading{margin:0 !important}@media (max-width: 31.914893617rem){/*!@.duet-heading.h0*/.duet-heading.h0.sc-duet-heading{font-size:3rem}}@media (min-width: 47.8723404255rem){/*!@.duet-heading.h0*/.duet-heading.h0.sc-duet-heading{font-size:4.5rem}}@media (max-width: 22.5em){/*!@.duet-heading.h0*/.duet-heading.h0.sc-duet-heading{font-size:2.25rem}}/*!@.duet-heading.h1*/.duet-heading.h1.sc-duet-heading{font-size:7vw}/*!@.duet-heading.h1.duet-p-0*/.duet-heading.h1.duet-p-0.sc-duet-heading{padding:0 !important}/*!@.duet-heading.h1.duet-m-0*/.duet-heading.h1.duet-m-0.sc-duet-heading{margin:0 !important}@media (max-width: 32.1428571429rem){/*!@.duet-heading.h1*/.duet-heading.h1.sc-duet-heading{font-size:2.25rem}}@media (min-width: 42.8571428571rem){/*!@.duet-heading.h1*/.duet-heading.h1.sc-duet-heading{font-size:3rem}}@media (max-width: 22.5em){/*!@.duet-heading.h1*/.duet-heading.h1.sc-duet-heading{font-size:1.5rem}}/*!@.duet-heading.h2*/.duet-heading.h2.sc-duet-heading{font-size:5.8vw}/*!@.duet-heading.h2.duet-p-0*/.duet-heading.h2.duet-p-0.sc-duet-heading{padding:0 !important}/*!@.duet-heading.h2.duet-m-0*/.duet-heading.h2.duet-m-0.sc-duet-heading{margin:0 !important}@media (max-width: 25.8620689655rem){/*!@.duet-heading.h2*/.duet-heading.h2.sc-duet-heading{font-size:1.5rem}}@media (min-width: 38.7931034483rem){/*!@.duet-heading.h2*/.duet-heading.h2.sc-duet-heading{font-size:2.25rem}}@media (max-width: 22.5em){/*!@.duet-heading.h2*/.duet-heading.h2.sc-duet-heading{font-size:1.375rem}}/*!@.duet-heading.h3*/.duet-heading.h3.sc-duet-heading{margin-bottom:12px !important;font-size:4.2vw}/*!@.duet-heading.h3.duet-p-0*/.duet-heading.h3.duet-p-0.sc-duet-heading{padding:0 !important}/*!@.duet-heading.h3.duet-m-0*/.duet-heading.h3.duet-m-0.sc-duet-heading{margin:0 !important}@media (max-width: 29.7619047619rem){/*!@.duet-heading.h3*/.duet-heading.h3.sc-duet-heading{font-size:1.25rem}}@media (min-width: 35.7142857143rem){/*!@.duet-heading.h3*/.duet-heading.h3.sc-duet-heading{font-size:1.5rem}}/*!@.duet-heading.h3.duet-theme-turva*/.duet-heading.h3.duet-theme-turva.sc-duet-heading{font-style:normal}/*!@.duet-heading.h3.duet-heading-border*/.duet-heading.h3.duet-heading-border.sc-duet-heading{padding-bottom:20px}/*!@.duet-heading.h4*/.duet-heading.h4.sc-duet-heading{margin-bottom:8px !important;font-size:4vw;letter-spacing:0}/*!@.duet-heading.h4.duet-p-0*/.duet-heading.h4.duet-p-0.sc-duet-heading{padding:0 !important}/*!@.duet-heading.h4.duet-m-0*/.duet-heading.h4.duet-m-0.sc-duet-heading{margin:0 !important}@media (max-width: 27.5rem){/*!@.duet-heading.h4*/.duet-heading.h4.sc-duet-heading{font-size:1.1rem}}@media (min-width: 31.25rem){/*!@.duet-heading.h4*/.duet-heading.h4.sc-duet-heading{font-size:1.25rem}}/*!@.duet-heading.h4.duet-theme-turva*/.duet-heading.h4.duet-theme-turva.sc-duet-heading{font-style:normal;font-weight:700}/*!@.duet-heading.h4.duet-heading-border*/.duet-heading.h4.duet-heading-border.sc-duet-heading{padding-bottom:20px}/*!@.duet-heading.h5*/.duet-heading.h5.sc-duet-heading{margin-bottom:8px !important;font-size:4vw;font-weight:600;letter-spacing:0}/*!@.duet-heading.h5.duet-p-0*/.duet-heading.h5.duet-p-0.sc-duet-heading{padding:0 !important}/*!@.duet-heading.h5.duet-m-0*/.duet-heading.h5.duet-m-0.sc-duet-heading{margin:0 !important}@media (max-width: 27.5rem){/*!@.duet-heading.h5*/.duet-heading.h5.sc-duet-heading{font-size:1.1rem}}@media (min-width: 28.4090909091rem){/*!@.duet-heading.h5*/.duet-heading.h5.sc-duet-heading{font-size:1.1363636364rem}}/*!@.duet-heading.h5.duet-theme-turva*/.duet-heading.h5.duet-theme-turva.sc-duet-heading{font-style:normal;font-weight:700}/*!@.duet-heading.h5.duet-heading-border*/.duet-heading.h5.duet-heading-border.sc-duet-heading{padding-bottom:16px}/*!@.duet-heading.h6*/.duet-heading.h6.sc-duet-heading{margin-bottom:8px !important;font-size:1rem;font-weight:600;letter-spacing:0}/*!@.duet-heading.h6.duet-p-0*/.duet-heading.h6.duet-p-0.sc-duet-heading{padding:0 !important}/*!@.duet-heading.h6.duet-m-0*/.duet-heading.h6.duet-m-0.sc-duet-heading{margin:0 !important}/*!@.duet-heading.h6.duet-theme-turva*/.duet-heading.h6.duet-theme-turva.sc-duet-heading{font-style:normal;font-weight:700}/*!@.duet-heading.h6.duet-heading-border*/.duet-heading.h6.duet-heading-border.sc-duet-heading{padding-bottom:16px}/*!@.duet-heading.duet-semibold, .duet-heading.duet-theme-turva.duet-semibold*/.duet-heading.duet-semibold.sc-duet-heading,.duet-heading.duet-theme-turva.duet-semibold.sc-duet-heading{font-style:normal !important;font-weight:600 !important}";
9964
10401
 
9965
10402
  class DuetHeading {
9966
10403
  constructor(hostRef) {
@@ -9974,7 +10411,7 @@ class DuetHeading {
9974
10411
  */
9975
10412
  this.margin = "auto";
9976
10413
  /**
9977
- * Enable or disable the border underneath the heading.
10414
+ * Enable or disable the border underneath the heading, solid will darken the border
9978
10415
  */
9979
10416
  this.border = false;
9980
10417
  /**
@@ -10011,7 +10448,8 @@ class DuetHeading {
10011
10448
  const color = getColorByName(this.color);
10012
10449
  return (hAsync(TagName, { class: {
10013
10450
  "duet-heading": true,
10014
- "duet-heading-border": this.border,
10451
+ "duet-heading-border": this.border !== false,
10452
+ "duet-heading-border-solid": this.border === "solid",
10015
10453
  "duet-semibold": this.weight === "semibold",
10016
10454
  "duet-heading-hyphenate": this.hyphenate,
10017
10455
  "duet-m-0": this.margin === "none",
@@ -10028,7 +10466,7 @@ class DuetHeading {
10028
10466
  "level": [513],
10029
10467
  "margin": [1],
10030
10468
  "visualLevel": [1, "visual-level"],
10031
- "border": [4],
10469
+ "border": [8],
10032
10470
  "weight": [1],
10033
10471
  "color": [1],
10034
10472
  "theme": [1025],
@@ -10287,22 +10725,92 @@ class DuetHero {
10287
10725
  }; }
10288
10726
  }
10289
10727
 
10290
- const duetIconCss = "/*!@*,\n*::after,\n*::before*/*.sc-duet-icon,*.sc-duet-icon::after,*.sc-duet-icon::before{box-sizing:border-box;padding:0;margin:0;background:transparent;border:0;-moz-appearance:none;-webkit-appearance:none;appearance:none}/*!@:host*/.sc-duet-icon-h{box-sizing:border-box;padding:0;margin:0;background:transparent;border:0;-moz-appearance:none;-webkit-appearance:none;appearance:none;margin-bottom:16px !important;display:inline-block;width:auto;max-width:100%;color:inherit;-webkit-tap-highlight-color:transparent}@media (max-width: 35.9375em){/*!@:host(.duet-icon-has-outline)*/.duet-icon-has-outline.sc-duet-icon-h{margin-bottom:0 !important}}@media (max-width: 35.9375em){/*!@:host(.duet-icon-has-background)*/.duet-icon-has-background.sc-duet-icon-h{margin-bottom:0 !important}}/*!@:host(.duet-m-0)*/.duet-m-0.sc-duet-icon-h{margin:0 !important}@media (max-width: 35.9375em){/*!@:host(.duet-m-0)*/.duet-m-0.sc-duet-icon-h{margin:0 !important}}/*!@.duet-icon*/.duet-icon.sc-duet-icon{-webkit-user-select:none;user-select:none;width:100%;height:100%;transform-origin:top center}/*!@.duet-icon.duet-icon-has-outline*/.duet-icon.duet-icon-has-outline.sc-duet-icon{padding:12px;border-style:solid;border-width:1px;border-radius:50%}@media (max-width: 35.9375em){/*!@.duet-icon.duet-icon-has-outline*/.duet-icon.duet-icon-has-outline.sc-duet-icon{outline:1px solid transparent;transform:scale(0.8)}}/*!@.duet-icon.duet-icon-has-background*/.duet-icon.duet-icon-has-background.sc-duet-icon{padding:16px;color:white;border-radius:50%}@media (max-width: 35.9375em){/*!@.duet-icon.duet-icon-has-background*/.duet-icon.duet-icon-has-background.sc-duet-icon{outline:1px solid transparent;transform:scale(0.8)}}/*!@.duet-icon.duet-icon-has-background.duet-theme-turva, .duet-icon.duet-icon-has-background.duet-theme-default*/.duet-icon.duet-icon-has-background.duet-theme-turva.sc-duet-icon,.duet-icon.duet-icon-has-background.duet-theme-default.sc-duet-icon{color:white}/*!@.duet-icon.duet-icon-has-background.xxx-small .duet-icon-svg, .duet-icon.duet-icon-has-outline.xxx-small .duet-icon-svg*/.duet-icon.duet-icon-has-background.xxx-small.sc-duet-icon .duet-icon-svg.sc-duet-icon,.duet-icon.duet-icon-has-outline.xxx-small.sc-duet-icon .duet-icon-svg.sc-duet-icon{width:10px;height:10px}/*!@.duet-icon.duet-icon-has-background.xx-small .duet-icon-svg, .duet-icon.duet-icon-has-outline.xx-small .duet-icon-svg*/.duet-icon.duet-icon-has-background.xx-small.sc-duet-icon .duet-icon-svg.sc-duet-icon,.duet-icon.duet-icon-has-outline.xx-small.sc-duet-icon .duet-icon-svg.sc-duet-icon{width:16px;height:16px}@media (max-width: 35.9375em){/*!@.duet-icon.duet-icon-not-responsive*/.duet-icon.duet-icon-not-responsive.sc-duet-icon{transform:scale(1) !important}}/*!@.duet-icon.duet-theme-default*/.duet-icon.duet-theme-default.sc-duet-icon{color:#0077b3}/*!@.duet-icon.duet-theme-turva*/.duet-icon.duet-theme-turva.sc-duet-icon{color:#c60c30}/*!@.duet-icon.auto .duet-icon-svg*/.duet-icon.auto.sc-duet-icon .duet-icon-svg.sc-duet-icon{width:100%;height:100%}/*!@.duet-icon.xxx-small .duet-icon-svg*/.duet-icon.xxx-small.sc-duet-icon .duet-icon-svg.sc-duet-icon{width:7px;height:7px}/*!@.duet-icon.duet-icon-has-background.xxx-small*/.duet-icon.duet-icon-has-background.xxx-small.sc-duet-icon{padding:6px}/*!@.duet-icon.duet-icon-has-outline.xxx-small*/.duet-icon.duet-icon-has-outline.xxx-small.sc-duet-icon{padding:4px}/*!@.duet-icon.xx-small .duet-icon-svg*/.duet-icon.xx-small.sc-duet-icon .duet-icon-svg.sc-duet-icon{width:10px;height:10px}/*!@.duet-icon.duet-icon-has-background.xx-small*/.duet-icon.duet-icon-has-background.xx-small.sc-duet-icon{padding:8px}/*!@.duet-icon.duet-icon-has-outline.xx-small*/.duet-icon.duet-icon-has-outline.xx-small.sc-duet-icon{padding:7px}/*!@.duet-icon.x-small .duet-icon-svg*/.duet-icon.x-small.sc-duet-icon .duet-icon-svg.sc-duet-icon{width:16px;height:16px}/*!@.duet-icon.duet-icon-has-outline.x-small*/.duet-icon.duet-icon-has-outline.x-small.sc-duet-icon{padding:10px}/*!@.duet-icon.duet-icon-has-background.x-small*/.duet-icon.duet-icon-has-background.x-small.sc-duet-icon{padding:12px}/*!@.duet-icon.small .duet-icon-svg*/.duet-icon.small.sc-duet-icon .duet-icon-svg.sc-duet-icon{width:20px;height:20px}/*!@.duet-icon.duet-icon-has-background.small*/.duet-icon.duet-icon-has-background.small.sc-duet-icon{padding:14px}/*!@.duet-icon.large .duet-icon-svg*/.duet-icon.large.sc-duet-icon .duet-icon-svg.sc-duet-icon{width:30px;height:30px}/*!@.duet-icon.x-large .duet-icon-svg*/.duet-icon.x-large.sc-duet-icon .duet-icon-svg.sc-duet-icon{width:36px;height:36px}/*!@.duet-icon.xx-large .duet-icon-svg*/.duet-icon.xx-large.sc-duet-icon .duet-icon-svg.sc-duet-icon{width:48px;height:48px}/*!@.duet-icon.xxx-large .duet-icon-svg*/.duet-icon.xxx-large.sc-duet-icon .duet-icon-svg.sc-duet-icon{width:48px;height:48px}@media (min-width: 48em){/*!@.duet-icon.xxx-large .duet-icon-svg*/.duet-icon.xxx-large.sc-duet-icon .duet-icon-svg.sc-duet-icon{width:72px;height:72px}}/*!@.duet-icon .duet-icon-svg*/.duet-icon.sc-duet-icon .duet-icon-svg.sc-duet-icon{display:block;width:24px;min-width:100%;height:24px;font-size:0}/*!@.duet-icon svg*/.duet-icon.sc-duet-icon svg.sc-duet-icon{width:100%;min-width:100%;fill:currentColor}";
10291
-
10292
- class DuetIcon {
10293
- constructor(hostRef) {
10294
- registerInstance(this, hostRef);
10295
- /**
10296
- * Theme of the icon. This setting will be overridden when you set the color
10297
- * property
10298
- */
10299
- this.theme = "";
10300
- /**
10301
- * Icon name from Duet to display.
10302
- */
10303
- this.name = "action-add";
10304
- /**
10305
- * Controls the margin of the component.
10728
+ const cleanupSvg = (svgContent) => {
10729
+ if (typeof document === "undefined" || !svgContent) {
10730
+ return;
10731
+ }
10732
+ const div = document.createElement("div");
10733
+ div.innerHTML = svgContent;
10734
+ // setup this way to ensure it works on our buddy IE
10735
+ for (let i = div.childNodes.length - 1; i >= 0; i--) {
10736
+ const child = div.childNodes[i];
10737
+ if (child.nodeName.toLowerCase() !== "svg") {
10738
+ div.removeChild(div.childNodes[i]);
10739
+ }
10740
+ }
10741
+ return div.firstElementChild;
10742
+ };
10743
+ const isValid = (elm) => {
10744
+ if (elm.nodeName.toLowerCase() === "script") {
10745
+ return false;
10746
+ }
10747
+ for (let i = 0; i < elm.attributes.length; i++) {
10748
+ const attribute = elm.attributes[i];
10749
+ if (attribute.name.toLowerCase().indexOf("on") === 0) {
10750
+ return false;
10751
+ }
10752
+ }
10753
+ if (elm.children) {
10754
+ for (let i = 0; i < elm.children.length; i++) {
10755
+ if (!isValid(elm.children[i])) {
10756
+ return false;
10757
+ }
10758
+ }
10759
+ }
10760
+ return true;
10761
+ };
10762
+ const buildIconUrl = (iconName) => {
10763
+ // under normal operations the Icons should always be loaded from the CDN
10764
+ {
10765
+ return `${Env.cdnURIProd}/icons/${Env.duetIconVersion}/lib/assets/${iconName}.svg`;
10766
+ }
10767
+ };
10768
+ const iconCache = {};
10769
+ function fetchIconByUrl(url) {
10770
+ if (iconCache[url]) {
10771
+ return iconCache[url];
10772
+ }
10773
+ // we create a function that covers all the fetching, cleanup, validation etc,
10774
+ // this way we can perform that work just once, and then return the same promise in future.
10775
+ async function doFetch() {
10776
+ const res = await fetch(url);
10777
+ if (!res.ok) {
10778
+ throw new Error(`SVG request failed: ${res.status} ${res.statusText}`);
10779
+ }
10780
+ const responseText = await res.text();
10781
+ const svgElement = cleanupSvg(responseText);
10782
+ if (!isValid(svgElement)) {
10783
+ throw new Error("SVG validation failed");
10784
+ }
10785
+ // OuterHTML does not unfortunately work here with IE11
10786
+ // was previously: resolve(svgElement.outerHTML)
10787
+ const div = document.createElement("div");
10788
+ div.appendChild(svgElement);
10789
+ return div.innerHTML;
10790
+ }
10791
+ // we do not `await` the fetch, as we only care about initiating the work,
10792
+ // it's the responsibility of the calling code to wait for the response.
10793
+ const req = doFetch();
10794
+ // cache for the repeat requests
10795
+ return (iconCache[url] = req);
10796
+ }
10797
+
10798
+ const duetIconCss = "/*!@*,\n*::after,\n*::before*/*.sc-duet-icon,*.sc-duet-icon::after,*.sc-duet-icon::before{box-sizing:border-box;padding:0;margin:0;background:transparent;border:0;-moz-appearance:none;-webkit-appearance:none;appearance:none}/*!@:host*/.sc-duet-icon-h{box-sizing:border-box;padding:0;margin:0;background:transparent;border:0;-moz-appearance:none;-webkit-appearance:none;appearance:none;margin-bottom:16px !important;display:inline-block;width:auto;max-width:100%;color:inherit;-webkit-tap-highlight-color:transparent}@media (max-width: 35.9375em){/*!@:host(.duet-icon-has-outline)*/.duet-icon-has-outline.sc-duet-icon-h{margin-bottom:0 !important}}@media (max-width: 35.9375em){/*!@:host(.duet-icon-has-background)*/.duet-icon-has-background.sc-duet-icon-h{margin-bottom:0 !important}}/*!@:host(.duet-m-0)*/.duet-m-0.sc-duet-icon-h{margin:0 !important}@media (max-width: 35.9375em){/*!@:host(.duet-m-0)*/.duet-m-0.sc-duet-icon-h{margin:0 !important}}/*!@.duet-icon*/.duet-icon.sc-duet-icon{-webkit-user-select:none;user-select:none;width:100%;height:100%;transform-origin:top center}/*!@.duet-icon.duet-icon-has-outline*/.duet-icon.duet-icon-has-outline.sc-duet-icon{padding:12px;border-style:solid;border-width:1px;border-radius:50%}@media (max-width: 35.9375em){/*!@.duet-icon.duet-icon-has-outline*/.duet-icon.duet-icon-has-outline.sc-duet-icon{outline:1px solid transparent;transform:scale(0.8)}}/*!@.duet-icon.duet-icon-has-background*/.duet-icon.duet-icon-has-background.sc-duet-icon{padding:16px;color:white;border-radius:50%}@media (max-width: 35.9375em){/*!@.duet-icon.duet-icon-has-background*/.duet-icon.duet-icon-has-background.sc-duet-icon{outline:1px solid transparent;transform:scale(0.8)}}/*!@.duet-icon.duet-icon-has-background.duet-theme-turva, .duet-icon.duet-icon-has-background.duet-theme-default*/.duet-icon.duet-icon-has-background.duet-theme-turva.sc-duet-icon,.duet-icon.duet-icon-has-background.duet-theme-default.sc-duet-icon{color:white}/*!@.duet-icon.duet-icon-has-background.xxx-small .duet-icon-svg, .duet-icon.duet-icon-has-outline.xxx-small .duet-icon-svg*/.duet-icon.duet-icon-has-background.xxx-small.sc-duet-icon .duet-icon-svg.sc-duet-icon,.duet-icon.duet-icon-has-outline.xxx-small.sc-duet-icon .duet-icon-svg.sc-duet-icon{width:10px;height:10px}/*!@.duet-icon.duet-icon-has-background.xx-small .duet-icon-svg, .duet-icon.duet-icon-has-outline.xx-small .duet-icon-svg*/.duet-icon.duet-icon-has-background.xx-small.sc-duet-icon .duet-icon-svg.sc-duet-icon,.duet-icon.duet-icon-has-outline.xx-small.sc-duet-icon .duet-icon-svg.sc-duet-icon{width:16px;height:16px}@media (max-width: 35.9375em){/*!@.duet-icon.duet-icon-not-responsive*/.duet-icon.duet-icon-not-responsive.sc-duet-icon{transform:scale(1) !important}}/*!@.duet-icon.duet-theme-default*/.duet-icon.duet-theme-default.sc-duet-icon{color:#0077b3}/*!@.duet-icon.duet-theme-turva*/.duet-icon.duet-theme-turva.sc-duet-icon{color:#c60c30}/*!@.duet-icon.auto .duet-icon-svg*/.duet-icon.auto.sc-duet-icon .duet-icon-svg.sc-duet-icon{width:100%;height:100%}/*!@.duet-icon.xxx-small .duet-icon-svg*/.duet-icon.xxx-small.sc-duet-icon .duet-icon-svg.sc-duet-icon{width:7px;height:7px}/*!@.duet-icon.duet-icon-has-background.xxx-small*/.duet-icon.duet-icon-has-background.xxx-small.sc-duet-icon{padding:6px}/*!@.duet-icon.duet-icon-has-outline.xxx-small*/.duet-icon.duet-icon-has-outline.xxx-small.sc-duet-icon{padding:4px}/*!@.duet-icon.xx-small .duet-icon-svg*/.duet-icon.xx-small.sc-duet-icon .duet-icon-svg.sc-duet-icon{width:10px;height:10px}/*!@.duet-icon.duet-icon-has-background.xx-small*/.duet-icon.duet-icon-has-background.xx-small.sc-duet-icon{padding:8px}/*!@.duet-icon.duet-icon-has-outline.xx-small*/.duet-icon.duet-icon-has-outline.xx-small.sc-duet-icon{padding:7px}/*!@.duet-icon.x-small .duet-icon-svg*/.duet-icon.x-small.sc-duet-icon .duet-icon-svg.sc-duet-icon{width:16px;height:16px}/*!@.duet-icon.duet-icon-has-outline.x-small*/.duet-icon.duet-icon-has-outline.x-small.sc-duet-icon{padding:10px}/*!@.duet-icon.duet-icon-has-background.x-small*/.duet-icon.duet-icon-has-background.x-small.sc-duet-icon{padding:12px}/*!@.duet-icon.small .duet-icon-svg*/.duet-icon.small.sc-duet-icon .duet-icon-svg.sc-duet-icon{width:20px;height:20px}/*!@.duet-icon.duet-icon-has-background.small*/.duet-icon.duet-icon-has-background.small.sc-duet-icon{padding:14px}/*!@.duet-icon.large .duet-icon-svg*/.duet-icon.large.sc-duet-icon .duet-icon-svg.sc-duet-icon{width:30px;height:30px}/*!@.duet-icon.x-large .duet-icon-svg*/.duet-icon.x-large.sc-duet-icon .duet-icon-svg.sc-duet-icon{width:36px;height:36px}/*!@.duet-icon.xx-large .duet-icon-svg*/.duet-icon.xx-large.sc-duet-icon .duet-icon-svg.sc-duet-icon{width:48px;height:48px}/*!@.duet-icon.xxx-large .duet-icon-svg*/.duet-icon.xxx-large.sc-duet-icon .duet-icon-svg.sc-duet-icon{width:48px;height:48px}@media (min-width: 48em){/*!@.duet-icon.xxx-large .duet-icon-svg*/.duet-icon.xxx-large.sc-duet-icon .duet-icon-svg.sc-duet-icon{width:72px;height:72px}}/*!@.duet-icon .duet-icon-svg*/.duet-icon.sc-duet-icon .duet-icon-svg.sc-duet-icon{display:block;width:24px;min-width:100%;height:24px;font-size:0}/*!@.duet-icon svg*/.duet-icon.sc-duet-icon svg.sc-duet-icon{width:100%;min-width:100%;fill:currentColor}";
10799
+
10800
+ class DuetIcon {
10801
+ constructor(hostRef) {
10802
+ registerInstance(this, hostRef);
10803
+ /**
10804
+ * Theme of the icon. This setting will be overridden when you set the color
10805
+ * property
10806
+ */
10807
+ this.theme = "";
10808
+ /**
10809
+ * Icon name from Duet to display.
10810
+ */
10811
+ this.name = "action-add";
10812
+ /**
10813
+ * Controls the margin of the component.
10306
10814
  */
10307
10815
  this.margin = "auto";
10308
10816
  /**
@@ -10343,7 +10851,7 @@ class DuetIcon {
10343
10851
  if (this.src && this.icon) {
10344
10852
  console.warn("[DUET COMPONENTS]: <duet-icon> should have either have src or icon attributes, but not both. icon attribute will take precedence", "icon:", this.icon, "src:", this.src);
10345
10853
  }
10346
- this.loadIcon();
10854
+ return this.loadIcon();
10347
10855
  }
10348
10856
  async loadIcon() {
10349
10857
  // static icon known at build-time, so we can set it synchronously
@@ -10351,9 +10859,13 @@ class DuetIcon {
10351
10859
  this.svgContent = this.icon;
10352
10860
  return;
10353
10861
  }
10354
- // on server, don't make requests
10355
- {
10356
- return;
10862
+ // dynamically load icon from url
10863
+ const src = this.src ? this.src : buildIconUrl(this.name);
10864
+ try {
10865
+ this.svgContent = await fetchIconByUrl(src);
10866
+ }
10867
+ catch (e) {
10868
+ console.warn(`[DUET COMPONENTS]: <duet-icon> could not load SVG from URL: ${src}.`, e);
10357
10869
  }
10358
10870
  }
10359
10871
  /**
@@ -10463,7 +10975,7 @@ function cleanValue(input, regex) {
10463
10975
  return newValue;
10464
10976
  }
10465
10977
 
10466
- const duetInputCss = "*.sc-duet-input,*.sc-duet-input::after,*.sc-duet-input::before{box-sizing:border-box;padding:0;margin:0;background:transparent;border:0;-moz-appearance:none;-webkit-appearance:none;appearance:none}.sc-duet-input-h{box-sizing:border-box;padding:0;margin:0;background:transparent;border:0;-moz-appearance:none;-webkit-appearance:none;appearance:none;margin-right:16px !important;margin-bottom:12px !important;display:inline-flex;width:100%;min-width:calc(33.333% - 8px);max-width:100%;text-align:left;vertical-align:bottom}.sc-duet-input-h:last-child,.sc-duet-input-h:last-of-type{margin-right:0 !important}@media (min-width: 36em){.sc-duet-input-h{width:calc(50% - 16px - 3px)}}.duet-expand.sc-duet-input-h{width:100% !important}.duet-m-0.sc-duet-input-h{margin:0 !important}duet-tooltip.sc-duet-input{position:absolute;top:12px;right:0}@media (min-width: 48em){duet-tooltip.sc-duet-input{position:relative;top:4px;right:auto}}duet-caption.sc-duet-input:not(:last-of-type){margin-bottom:0}.duet-input-icon.sc-duet-input{position:absolute;top:50%;right:16px;z-index:200;width:20px;height:20px;font-size:0;line-height:normal;color:#00294d;pointer-events:none;transform:translateY(-50%)}.duet-theme-turva.sc-duet-input .duet-input-icon.sc-duet-input{color:#171c3a}.duet-input-container.sc-duet-input{position:relative;width:100%;height:100%}.duet-input.sc-duet-input{position:relative;z-index:100;display:block !important;width:100% !important;min-width:8rem;max-width:initial !important;height:auto !important;padding:12px 14px !important;margin:initial !important;margin-bottom:initial !important;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:400 !important;font-variant-numeric:tabular-nums;line-height:1.5 !important;color:#00294d !important;cursor:initial !important;background:white !important;background-clip:initial !important;border:1px solid #909599 !important;border-radius:4px !important;box-shadow:initial !important;transition:box-shadow 150ms ease, border 150ms ease !important}.duet-input.is-number.sc-duet-input{padding-right:112px !important}.duet-input.is-date.sc-duet-input{padding-right:64px !important}.has-error.sc-duet-input .duet-input.sc-duet-input{border-color:#de2362 !important}.has-error.sc-duet-input .duet-input.sc-duet-input+.duet-input-icon.sc-duet-input{color:#de2362 !important}.duet-theme-turva.has-error.sc-duet-input .duet-input.sc-duet-input{border-color:#e02a0d !important}.duet-theme-turva.has-error.sc-duet-input .duet-input.sc-duet-input+.duet-input-icon.sc-duet-input{color:#e02a0d !important}.has-icon.sc-duet-input .duet-input.sc-duet-input{padding-right:48px !important}.duet-theme-turva.sc-duet-input .duet-input.sc-duet-input{font-family:\"turva-sans\", -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\";color:#171c3a !important;border-color:#747475 !important}.duet-input.sc-duet-input::-ms-clear{display:none}.duet-input.sc-duet-input::-webkit-contacts-auto-fill-button{display:none !important}.duet-input.sc-duet-input::-webkit-input-placeholder{color:#657787;opacity:1 !important;transition:color 300ms ease}.duet-theme-turva.sc-duet-input .duet-input.sc-duet-input::-webkit-input-placeholder{color:#747475}.duet-input.sc-duet-input:focus::-webkit-input-placeholder{color:#cfd2d4}.duet-theme-turva.sc-duet-input .duet-input.sc-duet-input:focus::-webkit-input-placeholder{color:#cfcfd1}.duet-input.sc-duet-input::-moz-placeholder{color:#657787;opacity:1 !important}.duet-theme-turva.sc-duet-input .duet-input.sc-duet-input::-moz-placeholder{color:#747475}.duet-input.sc-duet-input:focus::-moz-placeholder{color:#cfd2d4}.duet-theme-turva.sc-duet-input .duet-input.sc-duet-input:focus::-moz-placeholder{color:#cfcfd1}.duet-input.sc-duet-input:-ms-input-placeholder{color:#657787}.duet-theme-turva.sc-duet-input .duet-input.sc-duet-input:-ms-input-placeholder{color:#747475}.duet-input.sc-duet-input:focus:-ms-input-placeholder{color:#cfd2d4}.duet-theme-turva.sc-duet-input .duet-input.sc-duet-input:focus:-ms-input-placeholder{color:#cfcfd1}.duet-input[disabled].sc-duet-input{color:#00294d !important;cursor:text !important;background:#f5f8fa !important;border-color:#f5f8fa !important;box-shadow:none !important;opacity:1 !important;-webkit-text-fill-color:#00294d !important}.duet-theme-turva.sc-duet-input .duet-input[disabled].sc-duet-input{color:#171c3a !important;background:#f5f5f7 !important;border-color:#f5f5f7 !important;-webkit-text-fill-color:#171c3a !important}.duet-input.sc-duet-input:hover:not(:disabled){box-shadow:0 0 0 1px #909599 !important}.duet-theme-turva.sc-duet-input .duet-input.sc-duet-input:hover:not(:disabled){box-shadow:0 0 0 1px #747475 !important}.has-error.sc-duet-input .duet-input.sc-duet-input:hover:not(:disabled){box-shadow:0 0 0 1px #de2362}.duet-theme-turva.has-error.sc-duet-input .duet-input.sc-duet-input:hover:not(:disabled){box-shadow:0 0 0 1px #e02a0d}.duet-input.sc-duet-input:focus{border-color:#0077b3 !important;outline:0;box-shadow:0 0 0 1px #0077b3 !important;transition:none}.duet-theme-turva.sc-duet-input .duet-input.sc-duet-input:focus{border-color:#171c3a !important;box-shadow:0 0 0 1px #171c3a !important}.duet-theme-turva.sc-duet-input .duet-input.sc-duet-input:focus+.duet-input-icon.sc-duet-input{color:#171c3a}.has-error.sc-duet-input .duet-input.sc-duet-input:focus{box-shadow:0 0 0 1px #de2362}.duet-theme-turva.has-error.sc-duet-input .duet-input.sc-duet-input:focus{box-shadow:0 0 0 1px #e02a0d}.duet-input.sc-duet-input:focus+.duet-input-icon.sc-duet-input{color:#0077b3}.duet-input[type=search].sc-duet-input:not(:placeholder-shown):focus+.duet-input-icon.sc-duet-input{display:none}.duet-input.sc-duet-input:not(:focus):not(:hover):invalid{box-shadow:none !important}.duet-input[type=number].sc-duet-input::-webkit-inner-spin-button,.duet-input[type=number].sc-duet-input::-webkit-outer-spin-button,.duet-input[type=time].sc-duet-input::-webkit-inner-spin-button,.duet-input[type=time].sc-duet-input::-webkit-outer-spin-button{display:none;margin:0;-webkit-appearance:none}.duet-input.sc-duet-input::-webkit-search-cancel-button{margin-right:-28px}.duet-input-help.sc-duet-input{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:#657787;border-radius:4px}.duet-input-help.sc-duet-input span.sc-duet-input{display:block;margin-top:8px}.duet-theme-turva.sc-duet-input .duet-input-help.sc-duet-input{font-family:\"turva-sans\", -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\";color:#747475}.has-error.sc-duet-input .duet-input-help.sc-duet-input{color:#de2362}.duet-theme-turva.has-error.sc-duet-input .duet-input-help.sc-duet-input{color:#e02a0d}.duet-label-hidden.sc-duet-input duet-label.sc-duet-input{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0 0 0 0);border:0}.duet-input-relative.sc-duet-input{position:relative;width:100%}";
10978
+ const duetInputCss = "*.sc-duet-input,*.sc-duet-input::after,*.sc-duet-input::before{box-sizing:border-box;padding:0;margin:0;background:transparent;border:0;-moz-appearance:none;-webkit-appearance:none;appearance:none}.sc-duet-input-h{box-sizing:border-box;padding:0;margin:0;background:transparent;border:0;-moz-appearance:none;-webkit-appearance:none;appearance:none;margin-right:16px !important;margin-bottom:12px !important;display:inline-flex;width:100%;min-width:calc(33.333% - 8px);max-width:100%;text-align:left;vertical-align:bottom}.sc-duet-input-h:last-child,.sc-duet-input-h:last-of-type{margin-right:0 !important}@media (min-width: 36em){.sc-duet-input-h{width:calc(50% - 16px - 3px)}}.duet-expand.sc-duet-input-h{width:100% !important}.duet-m-0.sc-duet-input-h{margin:0 !important}duet-tooltip.sc-duet-input{position:absolute;top:12px;right:0}@media (min-width: 48em){duet-tooltip.sc-duet-input{position:relative;top:4px;right:auto}}duet-caption.sc-duet-input:not(:last-of-type){margin-bottom:0}.duet-input-placeholder.sc-duet-input{position:absolute;top:-9px;left:9px;z-index:200;display:block;width:auto;max-width:60%;padding:0 0.25rem;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;background:white}.duet-input-icon.sc-duet-input{position:absolute;top:50%;right:16px;z-index:200;width:20px;height:20px;font-size:0;line-height:normal;color:#00294d;pointer-events:none;transform:translateY(-50%)}.duet-theme-turva.sc-duet-input .duet-input-icon.sc-duet-input{color:#171c3a}.duet-input-container.sc-duet-input{position:relative;width:100%;height:100%}.duet-input.sc-duet-input{position:relative;z-index:100;display:block !important;width:100% !important;min-width:8rem;max-width:initial !important;height:auto !important;padding:12px 14px !important;margin:initial !important;margin-bottom:initial !important;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:400 !important;font-variant-numeric:tabular-nums;line-height:1.5 !important;color:#00294d !important;cursor:initial !important;background:white !important;background-clip:initial !important;border:1px solid #909599 !important;border-radius:4px !important;box-shadow:initial !important;transition:box-shadow 150ms ease, border 150ms ease !important}.duet-input.is-number.sc-duet-input{padding-right:112px !important}.duet-input.is-date.sc-duet-input{padding-right:64px !important}.has-error.sc-duet-input .duet-input.sc-duet-input{border-color:#de2362 !important}.has-error.sc-duet-input .duet-input.sc-duet-input+.duet-input-icon.sc-duet-input{color:#de2362 !important}.duet-theme-turva.has-error.sc-duet-input .duet-input.sc-duet-input{border-color:#e02a0d !important}.duet-theme-turva.has-error.sc-duet-input .duet-input.sc-duet-input+.duet-input-icon.sc-duet-input{color:#e02a0d !important}.has-icon.sc-duet-input .duet-input.sc-duet-input{padding-right:48px !important}.duet-theme-turva.sc-duet-input .duet-input.sc-duet-input{font-family:\"turva-sans\", -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\";color:#171c3a !important;border-color:#747475 !important}.duet-input.sc-duet-input::-ms-clear{display:none}.duet-input.sc-duet-input::-webkit-contacts-auto-fill-button{display:none !important}.duet-input.sc-duet-input::-webkit-input-placeholder{color:#657787;opacity:1 !important;transition:color 300ms ease}.duet-theme-turva.sc-duet-input .duet-input.sc-duet-input::-webkit-input-placeholder{color:#747475}.duet-input.sc-duet-input:focus::-webkit-input-placeholder{color:#cfd2d4}.duet-theme-turva.sc-duet-input .duet-input.sc-duet-input:focus::-webkit-input-placeholder{color:#cfcfd1}.duet-input.sc-duet-input::-moz-placeholder{color:#657787;opacity:1 !important}.duet-theme-turva.sc-duet-input .duet-input.sc-duet-input::-moz-placeholder{color:#747475}.duet-input.sc-duet-input:focus::-moz-placeholder{color:#cfd2d4}.duet-theme-turva.sc-duet-input .duet-input.sc-duet-input:focus::-moz-placeholder{color:#cfcfd1}.duet-input.sc-duet-input:-ms-input-placeholder{color:#657787}.duet-theme-turva.sc-duet-input .duet-input.sc-duet-input:-ms-input-placeholder{color:#747475}.duet-input.sc-duet-input:focus:-ms-input-placeholder{color:#cfd2d4}.duet-theme-turva.sc-duet-input .duet-input.sc-duet-input:focus:-ms-input-placeholder{color:#cfcfd1}.duet-input[disabled].sc-duet-input{color:#00294d !important;cursor:text !important;background:#f5f8fa !important;border-color:#f5f8fa !important;box-shadow:none !important;opacity:1 !important;-webkit-text-fill-color:#00294d !important}.duet-theme-turva.sc-duet-input .duet-input[disabled].sc-duet-input{color:#171c3a !important;background:#f5f5f7 !important;border-color:#f5f5f7 !important;-webkit-text-fill-color:#171c3a !important}.duet-input.sc-duet-input:hover:not(:disabled){box-shadow:0 0 0 1px #909599 !important}.duet-theme-turva.sc-duet-input .duet-input.sc-duet-input:hover:not(:disabled){box-shadow:0 0 0 1px #747475 !important}.has-error.sc-duet-input .duet-input.sc-duet-input:hover:not(:disabled){box-shadow:0 0 0 1px #de2362}.duet-theme-turva.has-error.sc-duet-input .duet-input.sc-duet-input:hover:not(:disabled){box-shadow:0 0 0 1px #e02a0d}.duet-input.sc-duet-input:focus{border-color:#0077b3 !important;outline:0;box-shadow:0 0 0 1px #0077b3 !important;transition:none}.duet-theme-turva.sc-duet-input .duet-input.sc-duet-input:focus{border-color:#171c3a !important;box-shadow:0 0 0 1px #171c3a !important}.duet-theme-turva.sc-duet-input .duet-input.sc-duet-input:focus+.duet-input-icon.sc-duet-input{color:#171c3a}.has-error.sc-duet-input .duet-input.sc-duet-input:focus{box-shadow:0 0 0 1px #de2362}.duet-theme-turva.has-error.sc-duet-input .duet-input.sc-duet-input:focus{box-shadow:0 0 0 1px #e02a0d}.duet-input.sc-duet-input:focus+.duet-input-icon.sc-duet-input{color:#0077b3}.duet-input[type=search].sc-duet-input:not(:placeholder-shown):focus+.duet-input-icon.sc-duet-input{display:none}.duet-input.sc-duet-input:not(:focus):not(:hover):invalid{box-shadow:none !important}.duet-input[type=number].sc-duet-input::-webkit-inner-spin-button,.duet-input[type=number].sc-duet-input::-webkit-outer-spin-button,.duet-input[type=time].sc-duet-input::-webkit-inner-spin-button,.duet-input[type=time].sc-duet-input::-webkit-outer-spin-button{display:none;margin:0;-webkit-appearance:none}.duet-input.sc-duet-input::-webkit-search-cancel-button{margin-right:-28px}.duet-input-help.sc-duet-input{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:#657787;border-radius:4px}.duet-input-help.sc-duet-input span.sc-duet-input{display:block;margin-top:8px}.duet-theme-turva.sc-duet-input .duet-input-help.sc-duet-input{font-family:\"turva-sans\", -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\";color:#747475}.has-error.sc-duet-input .duet-input-help.sc-duet-input{color:#de2362}.duet-theme-turva.has-error.sc-duet-input .duet-input-help.sc-duet-input{color:#e02a0d}.duet-label-hidden.sc-duet-input duet-label.sc-duet-input{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0 0 0 0);border:0}.duet-input-relative.sc-duet-input{position:relative;width:100%}";
10467
10979
 
10468
10980
  const icons = {
10469
10981
  search: formSearch,
@@ -10603,7 +11115,7 @@ class DuetInput {
10603
11115
  // (in webkit based browsers settings value trigger cursor position and will set it to EndOfText)
10604
11116
  restoreCursor();
10605
11117
  }
10606
- this.isCaptionVisible = !!(this.caption || (this.placeholder && this.echoPlaceholder && this.value));
11118
+ this.isCaptionVisible = !!this.caption;
10607
11119
  const emitEvent = () => this.duetChange.emit({
10608
11120
  value: this.value,
10609
11121
  component: "duet-input",
@@ -10622,7 +11134,7 @@ class DuetInput {
10622
11134
  componentWillLoad() {
10623
11135
  inheritGlobalTheme(this);
10624
11136
  this.disallowedPatternChange();
10625
- this.isCaptionVisible = !!(this.caption || (this.placeholder && this.echoPlaceholder && this.value));
11137
+ this.isCaptionVisible = !!this.caption;
10626
11138
  }
10627
11139
  /**
10628
11140
  * Sets focus on the specified `duet-input`. Use this method instead of the global
@@ -10657,12 +11169,12 @@ class DuetInput {
10657
11169
  "duet-input-top-caption-shown": this.isCaptionVisible,
10658
11170
  "has-icon": !!this.icon || (this.type !== "text" && this.type !== "tel" && this.type !== "password"),
10659
11171
  "has-error": !!this.error,
10660
- } }, hAsync("duet-label", { theme: this.theme === "turva" ? "turva" : "default", class: { "duet-has-tooltip": !!this.tooltip }, margin: this.isCaptionVisible ? "small" : "auto", id: this.labelId, for: identifier }, this.label), this.tooltip && (hAsync("duet-tooltip", { direction: this.tooltipDirection, accessibleInputLabel: this.label }, this.tooltip)), this.caption && (hAsync("duet-caption", { id: this.topCaptionId, size: "medium" }, this.caption)), this.placeholder && this.echoPlaceholder && this.value && (hAsync("duet-caption", { id: this.topCaptionPlaceholderId, size: "small" }, this.placeholder)), hAsync("div", { class: "duet-input-relative" }, hAsync("input", Object.assign({ ref: input => (this.nativeInput = input), onInput: this.onInput, onBlur: this.onBlur, onFocus: this.onFocus, type: this.type, class: {
11172
+ } }, hAsync("duet-label", { theme: this.theme === "turva" ? "turva" : "default", class: { "duet-has-tooltip": !!this.tooltip }, margin: this.isCaptionVisible ? "small" : "auto", id: this.labelId, for: identifier }, this.label), this.tooltip && (hAsync("duet-tooltip", { direction: this.tooltipDirection, accessibleInputLabel: this.label }, this.tooltip)), this.caption && (hAsync("duet-caption", { id: this.topCaptionId, size: "medium" }, this.caption)), hAsync("div", { class: "duet-input-relative" }, this.placeholder && this.echoPlaceholder && this.value && (hAsync("duet-caption", { id: this.topCaptionPlaceholderId, class: "duet-input-placeholder", margin: "none", size: "small" }, this.placeholder)), hAsync("input", Object.assign({ ref: input => (this.nativeInput = input), onInput: this.onInput, onBlur: this.onBlur, onFocus: this.onFocus, type: this.type, class: {
10661
11173
  "duet-input": true,
10662
11174
  disabled: this.disabled,
10663
11175
  "is-number": this.component === "number",
10664
11176
  "is-date": this.component === "date",
10665
- }, value: this.value, disabled: this.disabled, "aria-invalid": this.error ? "true" : "false", "aria-labelledby": `${this.labelId} ${this.errorId}`, "aria-controls": this.accessibleControls, "aria-autocomplete": this.accessibleAutocomplete, "aria-activedescendant": this.accessibleActiveDescendant, "aria-owns": this.accessibleOwns, "aria-describedby": `${this.isCaptionVisible ? this.topCaptionId : ""} ${this.accessibleDescribedBy}`, placeholder: this.placeholder, spellcheck: "false", minlength: this.minlength, maxlength: this.maxlength, autocomplete: this.autoComplete, required: this.required, role: this.role, name: this.name, id: identifier }, inputProps)), !this.icon && this.type !== "text" && this.type !== "tel" && this.type !== "password" && (hAsync("div", { class: "duet-input-icon" }, hAsync("duet-icon", { margin: "none", size: "small", icon: icons[this.type].svg, color: "currentColor" }))), this.icon && (hAsync("div", { class: "duet-input-icon" }, hAsync("duet-icon", { margin: "none", size: "small", name: this.icon, color: "currentColor" }))), hAsync("slot", null)), hAsync("span", { class: "duet-input-help", id: this.errorId, "aria-live": "assertive", "aria-relevant": "additions removals" }, this.error && hAsync("span", null, this.error)))));
11177
+ }, value: this.value, disabled: this.disabled, "aria-invalid": this.error ? "true" : "false", "aria-labelledby": `${this.labelId} ${this.errorId}`, "aria-controls": this.accessibleControls, "aria-autocomplete": this.accessibleAutocomplete, "aria-activedescendant": this.accessibleActiveDescendant, "aria-owns": this.accessibleOwns, "aria-describedby": `${this.isCaptionVisible ? this.topCaptionId : ""} ${this.accessibleDescribedBy}`, placeholder: this.placeholder, spellcheck: "false", minlength: this.minlength, maxlength: this.maxlength, autocomplete: this.autoComplete, required: this.required, role: this.role, name: this.name, id: identifier }, inputProps)), !this.icon && this.type !== "text" && this.type !== "tel" && this.type !== "password" && (hAsync("div", { class: "duet-input-icon" }, hAsync("duet-icon", { margin: "none", size: "small", icon: icons[this.type].svg, color: "currentColor" }))), this.icon && (hAsync("div", { class: "duet-input-icon" }, hAsync("duet-icon", { margin: "none", size: "small", name: this.icon, color: "currentColor" }))), hAsync("slot", null)), hAsync("span", { class: "duet-input-help", id: this.errorId, "aria-live": "assertive", "aria-relevant": "additions removals" }, this.error && hAsync("span", { class: "duet-input-error" }, this.error)))));
10666
11178
  }
10667
11179
  get element() { return getElement(this); }
10668
11180
  static get watchers() { return {
@@ -12105,13 +12617,16 @@ class DuetNumberInput {
12105
12617
  }; }
12106
12618
  }
12107
12619
 
12108
- const duetParagraphCss = "/*!@*,\n*::after,\n*::before*/*.sc-duet-paragraph,*.sc-duet-paragraph::after,*.sc-duet-paragraph::before{box-sizing:border-box;padding:0;margin:0;background:transparent;border:0;-moz-appearance:none;-webkit-appearance:none;appearance:none}/*!@:host*/.sc-duet-paragraph-h{box-sizing:border-box;padding:0;margin:0;background:transparent;border:0;-moz-appearance:none;-webkit-appearance:none;appearance:none;position:relative;display:block;width:100%}/*!@.duet-paragraph*/.duet-paragraph.sc-duet-paragraph{margin-bottom:16px !important;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-style:normal;font-weight:400;font-variant-numeric:tabular-nums;-webkit-hyphens:auto;hyphens:auto;line-height:1.5;color:#00294d}/*!@.duet-paragraph.duet-p-0*/.duet-paragraph.duet-p-0.sc-duet-paragraph{padding:0 !important}/*!@.duet-paragraph.duet-m-0*/.duet-paragraph.duet-m-0.sc-duet-paragraph{margin:0 !important}/*!@.duet-paragraph.duet-theme-turva*/.duet-paragraph.duet-theme-turva.sc-duet-paragraph{font-family:\"turva-sans\", -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\";color:#171c3a}/*!@.duet-paragraph.duet-paragraph-small*/.duet-paragraph.duet-paragraph-small.sc-duet-paragraph{font-size:0.875rem}/*!@.duet-paragraph.duet-m-0*/.duet-paragraph.duet-m-0.sc-duet-paragraph{margin:0 !important}/*!@.duet-paragraph.intro*/.duet-paragraph.intro.sc-duet-paragraph{font-size:2.7vw;margin-bottom:28px !important;-webkit-hyphens:inherit;hyphens:inherit}@media (max-width: 37.037037037rem){/*!@.duet-paragraph.intro*/.duet-paragraph.intro.sc-duet-paragraph{font-size:1rem}}@media (min-width: 46.2962962963rem){/*!@.duet-paragraph.intro*/.duet-paragraph.intro.sc-duet-paragraph{font-size:1.25rem}}/*!@.duet-paragraph.intro.duet-m-0*/.duet-paragraph.intro.duet-m-0.sc-duet-paragraph{margin:0 !important}/*!@::slotted(a)*/.sc-duet-paragraph-s>a{font-family:\"localtapiola-sans\", -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\";font-style:normal;font-weight:400;color:#0077b3;text-decoration:underline;transition:300ms ease}/*!@::slotted(a).duet-theme-turva*/.sc-duet-paragraph-s>a.duet-theme-turva{font-family:\"turva-sans\", -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\";color:#c60c30}/*!@::slotted(a):hover*/.sc-duet-paragraph-s>a:hover{color:#004d80;text-decoration:none}/*!@::slotted(a):hover.duet-theme-turva*/.sc-duet-paragraph-s>a:hover.duet-theme-turva{color:#940925}/*!@::slotted(a):active*/.sc-duet-paragraph-s>a:active{opacity:0.75;transition:none}";
12620
+ const duetParagraphCss = "/*!@*,\n*::after,\n*::before*/*.sc-duet-paragraph,*.sc-duet-paragraph::after,*.sc-duet-paragraph::before{box-sizing:border-box;padding:0;margin:0;background:transparent;border:0;-moz-appearance:none;-webkit-appearance:none;appearance:none}/*!@:host*/.sc-duet-paragraph-h{box-sizing:border-box;padding:0;margin:0;background:transparent;border:0;-moz-appearance:none;-webkit-appearance:none;appearance:none;position:relative;display:block;width:100%}/*!@.duet-paragraph*/.duet-paragraph.sc-duet-paragraph{margin-bottom:16px !important;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-style:normal;font-weight:400;font-variant-numeric:tabular-nums;-webkit-hyphens:auto;hyphens:auto;line-height:1.5;color:#00294d}/*!@.duet-paragraph.duet-p-0*/.duet-paragraph.duet-p-0.sc-duet-paragraph{padding:0 !important}/*!@.duet-paragraph.duet-m-0*/.duet-paragraph.duet-m-0.sc-duet-paragraph{margin:0 !important}/*!@.duet-paragraph.duet-theme-turva*/.duet-paragraph.duet-theme-turva.sc-duet-paragraph{font-family:\"turva-sans\", -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\";color:#171c3a}/*!@.duet-paragraph.duet-paragraph-small*/.duet-paragraph.duet-paragraph-small.sc-duet-paragraph{font-size:0.875rem}/*!@.duet-paragraph.duet-paragraph-semi-bold*/.duet-paragraph.duet-paragraph-semi-bold.sc-duet-paragraph{font-weight:600}/*!@.duet-paragraph.duet-paragraph-bold*/.duet-paragraph.duet-paragraph-bold.sc-duet-paragraph{font-weight:700}/*!@.duet-paragraph.duet-m-0*/.duet-paragraph.duet-m-0.sc-duet-paragraph{margin:0 !important}/*!@.duet-paragraph.intro*/.duet-paragraph.intro.sc-duet-paragraph{font-size:2.7vw;margin-bottom:28px !important;-webkit-hyphens:inherit;hyphens:inherit}@media (max-width: 37.037037037rem){/*!@.duet-paragraph.intro*/.duet-paragraph.intro.sc-duet-paragraph{font-size:1rem}}@media (min-width: 46.2962962963rem){/*!@.duet-paragraph.intro*/.duet-paragraph.intro.sc-duet-paragraph{font-size:1.25rem}}/*!@.duet-paragraph.intro.duet-m-0*/.duet-paragraph.intro.duet-m-0.sc-duet-paragraph{margin:0 !important}/*!@::slotted(a)*/.sc-duet-paragraph-s>a{font-family:\"localtapiola-sans\", -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\";font-style:normal;font-weight:400;color:#0077b3;text-decoration:underline;transition:300ms ease}/*!@::slotted(a).duet-theme-turva*/.sc-duet-paragraph-s>a.duet-theme-turva{font-family:\"turva-sans\", -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\";color:#c60c30}/*!@::slotted(a):hover*/.sc-duet-paragraph-s>a:hover{color:#004d80;text-decoration:none}/*!@::slotted(a):hover.duet-theme-turva*/.sc-duet-paragraph-s>a:hover.duet-theme-turva{color:#940925}/*!@::slotted(a):active*/.sc-duet-paragraph-s>a:active{opacity:0.75;transition:none}";
12109
12621
 
12622
+ /**
12623
+ * @part duet-paragraph - piercing selector for styling the paragraph
12624
+ */
12110
12625
  class DuetParagraph {
12111
12626
  constructor(hostRef) {
12112
12627
  registerInstance(this, hostRef);
12113
12628
  /**
12114
- * Theme of the card.
12629
+ * Theme of the paragraph.
12115
12630
  */
12116
12631
  this.theme = "";
12117
12632
  /**
@@ -12122,6 +12637,10 @@ class DuetParagraph {
12122
12637
  * Controls the size of the paragraph.
12123
12638
  */
12124
12639
  this.size = "medium";
12640
+ /**
12641
+ * Controls the Font-Weight of the paragraph.
12642
+ */
12643
+ this.weight = undefined;
12125
12644
  /**
12126
12645
  * Style variation of the paragraph.
12127
12646
  */
@@ -12147,10 +12666,12 @@ class DuetParagraph {
12147
12666
  return (hAsync("p", { class: {
12148
12667
  "duet-paragraph": true,
12149
12668
  "duet-paragraph-small": this.size === "small",
12669
+ "duet-paragraph-semi-bold": this.weight === "semi-bold",
12670
+ "duet-paragraph-bold": this.weight === "bold",
12150
12671
  "duet-m-0": this.margin === "none",
12151
12672
  [this.variation]: true,
12152
12673
  "duet-theme-turva": this.theme === "turva",
12153
- }, style: { color } }, hAsync("slot", null)));
12674
+ }, style: { color }, part: "duet-paragraph" }, hAsync("slot", null)));
12154
12675
  }
12155
12676
  get element() { return getElement(this); }
12156
12677
  static get style() { return duetParagraphCss; }
@@ -12161,6 +12682,7 @@ class DuetParagraph {
12161
12682
  "theme": [1025],
12162
12683
  "margin": [1],
12163
12684
  "size": [1],
12685
+ "weight": [1],
12164
12686
  "variation": [1],
12165
12687
  "color": [1]
12166
12688
  },
@@ -12170,6 +12692,84 @@ class DuetParagraph {
12170
12692
  }; }
12171
12693
  }
12172
12694
 
12695
+ const duetProgressCss = "*,*::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;width:100%;height:inherit}.duet-progress{box-sizing:border-box;padding:0;margin:0;background:transparent;border:0;-moz-appearance:none;-webkit-appearance:none;appearance:none;display:block;width:100%;min-height:1px;}.duet-progress .progress-bar{position:relative;display:block;width:100%;height:inherit;min-height:1px;background-color:#f3f9fc;border-radius:0;box-shadow:none}.duet-theme-turva .duet-progress .progress-bar{background-color:#fcf3f4}.duet-progress .progress-bar>span{display:block;height:inherit;text-indent:-9999px;background-color:#0077b3;border-radius:0}.duet-theme-turva .duet-progress .progress-bar>span{background-color:#c60c30}.duet-progress progress[value]{display:flex;width:100%;height:inherit;min-height:1px;color:#0077b3;border:0 none;-webkit-appearance:none;-moz-appearance:none;appearance:none}.duet-theme-turva .duet-progress progress[value]{color:#c60c30}.duet-progress progress[value]::-webkit-progress-bar{background-color:#f3f9fc;border-radius:0}.duet-theme-turva .duet-progress progress[value]::-webkit-progress-bar{background-color:#fcf3f4}.duet-progress progress[value]::-webkit-progress-value{background-color:#0077b3;background-size:35px 20px, 100% 100%, 100% 100%;border-radius:0;-webkit-animation:animate-stripes 5s linear infinite;animation:animate-stripes 5s linear infinite}.duet-theme-turva .duet-progress progress[value]::-webkit-progress-value{background-color:#c60c30}.duet-progress progress[value] ::-moz-progress-bar{background-color:#f3f9fc}.duet-theme-turva .duet-progress progress[value] ::-moz-progress-bar{background-color:#fcf3f4}";
12696
+
12697
+ class DuetProgress {
12698
+ constructor(hostRef) {
12699
+ registerInstance(this, hostRef);
12700
+ /**
12701
+ * Own Properties
12702
+ */
12703
+ this.progressId = createID("DuetProgress");
12704
+ this.progressLabelId = createID("DuetProgressLabel");
12705
+ /**
12706
+ * Defaults for accessibleLabel
12707
+ */
12708
+ this.accessibleLabelUploadDefaults = {
12709
+ fi: ["lähetys valmis", "lähetys käynnissä"],
12710
+ sv: ["Uppladdningen är klar", "Uppladdning pågår"],
12711
+ en: ["upload completed", "upload in progress"],
12712
+ };
12713
+ /**
12714
+ * Adds accessible label for upload in progress and upload complete states
12715
+ * @default {fi: ["lähetys valmis", "lähetys käynnissä"],sv: ["Uppladdningen är klar", "Uppladdning pågår"], en: ["completed", "in progress"]}
12716
+ */
12717
+ this.accessibleLabelUpload = getLocaleString(this.accessibleLabelUploadDefaults);
12718
+ /**
12719
+ * Progress of the bar, a value from 0-100
12720
+ */
12721
+ this.progress = 0;
12722
+ /**
12723
+ * Height of progressbar
12724
+ */
12725
+ this.height = "10px";
12726
+ /**
12727
+ * Theme of the input.
12728
+ */
12729
+ this.theme = "";
12730
+ }
12731
+ /**
12732
+ * Component lifecycle events.
12733
+ */
12734
+ componentWillLoad() {
12735
+ inheritGlobalTheme(this);
12736
+ }
12737
+ /**
12738
+ * render() function
12739
+ * Always the last one in the class.
12740
+ */
12741
+ render() {
12742
+ return (hAsync(Host, null, hAsync("div", { "aria-live": this.accessibleLabel ? "polite" : "off", "aria-hidden": this.accessibleLabel ? "false" : "true", "aria-atomic": "true", style: {
12743
+ height: this.height,
12744
+ }, id: this.progressId, class: {
12745
+ "duet-progress": true,
12746
+ "duet-progress-done": this.progress === 100,
12747
+ "duet-progress-start": this.progress === 0,
12748
+ "duet-progress-inprogress": this.progress < 99 && this.progress !== 0,
12749
+ "duet-theme-turva": this.theme === "turva",
12750
+ } }, hAsync("duet-visually-hidden", null, hAsync("label", { htmlFor: this.progressLabelId }, this.progress !== 0 && (hAsync("span", null, this.accessibleLabel, ", ", this.accessibleLabelUpload[this.progress < 99 ? 1 : 0])))), this.caption && (hAsync("div", { class: "duet-progress-caption" }, hAsync("span", null, this.caption))), hAsync("progress", { id: this.progressLabelId, "aria-describedby": this.accessibleDescribedBy, role: "progressbar", value: this.progress, max: "100", "aria-valuemin": "0", "aria-valuemax": "100" }, hAsync("div", { class: "progress-bar" }, hAsync("span", { style: { width: `${this.progress}%;` } }, "Progress: ", this.progress, "%"))))));
12751
+ }
12752
+ get element() { return getElement(this); }
12753
+ static get style() { return duetProgressCss; }
12754
+ static get cmpMeta() { return {
12755
+ "$flags$": 0,
12756
+ "$tagName$": "duet-progress",
12757
+ "$members$": {
12758
+ "accessibleDescribedBy": [1, "accessible-described-by"],
12759
+ "accessibleLabel": [1, "accessible-label"],
12760
+ "accessibleLabelUploadDefaults": [1, "accessible-label-upload-defaults"],
12761
+ "accessibleLabelUpload": [1, "accessible-label-upload"],
12762
+ "progress": [1538],
12763
+ "caption": [1],
12764
+ "height": [1],
12765
+ "theme": [1025]
12766
+ },
12767
+ "$listeners$": undefined,
12768
+ "$lazyBundleId$": "-",
12769
+ "$attrsToReflect$": [["progress", "progress"]]
12770
+ }; }
12771
+ }
12772
+
12173
12773
  const duetRadioCss = "*.sc-duet-radio,*.sc-duet-radio::after,*.sc-duet-radio::before{box-sizing:border-box;padding:0;margin:0;background:transparent;border:0;-moz-appearance:none;-webkit-appearance:none;appearance:none}.sc-duet-radio-h{box-sizing:border-box;padding:0;margin:0;background:transparent;border:0;-moz-appearance:none;-webkit-appearance:none;appearance:none;margin-right:28px !important;margin-bottom:12px !important;display:inline-flex;width:100%;vertical-align:bottom;-webkit-tap-highlight-color:transparent}.sc-duet-radio-h:last-child,.sc-duet-radio-h:last-of-type{margin-right:0 !important}.vertical.sc-duet-radio-h{margin-right:0 !important}.horizontal.sc-duet-radio-h{margin-bottom:0 !important;width:auto}.horizontal.sc-duet-radio-h .duet-label.sc-duet-radio span.sc-duet-radio{max-width:100%}@media (min-width: 48em){.horizontal-responsive.sc-duet-radio-h{margin-right:28px !important;margin-bottom:0 !important;width:auto}.horizontal-responsive.sc-duet-radio-h:last-child,.horizontal-responsive.sc-duet-radio-h:last-of-type{margin-right:0 !important}.horizontal-responsive.sc-duet-radio-h .duet-label.sc-duet-radio span.sc-duet-radio{max-width:100%}}.duet-m-0.sc-duet-radio-h{margin:0 !important}.sc-duet-radio-h:last-child:not(:only-child){margin-right:0 !important;margin-bottom:0 !important}.duet-label.sc-duet-radio{position:relative;z-index:100;display:flex;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:400;line-height:1.5;color:#00294d;cursor:pointer;background:transparent}.duet-theme-turva.sc-duet-radio .duet-label.sc-duet-radio{font-family:\"turva-sans\", -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\";color:#171c3a}.duet-label.sc-duet-radio span.sc-duet-radio{flex-grow:1;font-size:1rem}.duet-label-hidden.sc-duet-radio .duet-label.sc-duet-radio{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0 0 0 0);border:0}.duet-radio-container.sc-duet-radio{position:relative;width:100%;height:100%}.duet-radio.sc-duet-radio{padding:14px !important;position:absolute;top:0;left:0;z-index:200;width:100%;height:100%;cursor:pointer;opacity:0}.duet-radio.sc-duet-radio+label.sc-duet-radio::before{z-index:100;flex-shrink:0;width:20px;height:20px;margin:2px 10px 1px 1px;content:\"\";background:white;border:1px solid #00294d;border-radius:50%}.duet-theme-turva.sc-duet-radio .duet-radio.sc-duet-radio+label.sc-duet-radio::before{border-color:#171c3a}.duet-radio.sc-duet-radio:focus+label.sc-duet-radio::before{box-shadow:0 0 0 4px rgba(0, 119, 179, 0.3), 0 0 0 1px #0077b3}.duet-theme-turva.sc-duet-radio .duet-radio.sc-duet-radio:focus+label.sc-duet-radio::before{box-shadow:0 0 0 4px rgba(23, 28, 58, 0.2), 0 0 0 1px #171c3a}.duet-radio.sc-duet-radio:checked+label.sc-duet-radio::after{position:absolute;top:6px;left:5px;z-index:200;flex-shrink:0;width:12px;height:12px;content:\"\";background:#00294d;border-radius:50%}.duet-theme-turva.sc-duet-radio .duet-radio.sc-duet-radio:checked+label.sc-duet-radio::after{background:#171c3a}.duet-radio[disabled].sc-duet-radio{cursor:default}.duet-radio[disabled].sc-duet-radio+label.sc-duet-radio{color:#657787}.duet-theme-turva.sc-duet-radio .duet-radio[disabled].sc-duet-radio+label.sc-duet-radio{color:#747475}.duet-radio[disabled].sc-duet-radio+label.sc-duet-radio::before{border-color:#cfd2d4}.duet-theme-turva.sc-duet-radio .duet-radio[disabled].sc-duet-radio+label.sc-duet-radio::before{border-color:#cfcfd1}.duet-radio[disabled].sc-duet-radio:checked+label.sc-duet-radio::before{border:1px solid #657787}.duet-radio[disabled].sc-duet-radio:checked+label.sc-duet-radio::after{background:#657787}.duet-theme-turva.sc-duet-radio .duet-radio[disabled].sc-duet-radio:checked+label.sc-duet-radio::after{background:#747475;border-color:#747475}";
12174
12774
 
12175
12775
  class DuetRadio {
@@ -12658,7 +13258,7 @@ class DuetRangeSlider {
12658
13258
  }; }
12659
13259
  }
12660
13260
 
12661
- const duetSelectCss = "@charset \"UTF-8\";*.sc-duet-select,*.sc-duet-select::after,*.sc-duet-select::before{box-sizing:border-box;padding:0;margin:0;background:transparent;border:0;-moz-appearance:none;-webkit-appearance:none;appearance:none}.sc-duet-select-h{box-sizing:border-box;padding:0;margin:0;background:transparent;border:0;-moz-appearance:none;-webkit-appearance:none;appearance:none;margin-right:16px !important;margin-bottom:12px !important;display:inline-flex;width:100%;max-width:100%;vertical-align:bottom}.sc-duet-select-h:last-child,.sc-duet-select-h:last-of-type{margin-right:0 !important}@media (min-width: 36em){.sc-duet-select-h{width:calc(50% - 16px - 3px)}.duet-expand.sc-duet-select-h{width:100% !important}}.duet-m-0.sc-duet-select-h{margin:0 !important}duet-tooltip.sc-duet-select{position:absolute;top:12px;right:0}@media (min-width: 48em){duet-tooltip.sc-duet-select{position:relative;top:4px;right:auto}}.duet-select-container.sc-duet-select{position:relative;width:100%}.duet-select-wrapper.sc-duet-select{position:relative;width:100%;padding:15px 14px !important;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:400;line-height:1.25}.duet-theme-turva.sc-duet-select .duet-select-wrapper.sc-duet-select{font-family:\"turva-sans\", -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\"}.duet-select-wrapper.sc-duet-select::after{content:\"  \"}.duet-select-wrapper.sc-duet-select select.sc-duet-select{position:absolute;top:0;right:0;bottom:0;left:0;z-index:200;width:100%;height:100%;padding:0;margin:0;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;cursor:pointer;border:0;outline:none;opacity:0}.duet-theme-turva.sc-duet-select .duet-select-wrapper.sc-duet-select select.sc-duet-select{font-family:\"turva-sans\", -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\"}.duet-select-wrapper.sc-duet-select select.sc-duet-select:hover+.duet-select.sc-duet-select{border-color:#909599;box-shadow:0 0 0 1px #909599}.duet-theme-turva.sc-duet-select .duet-select-wrapper.sc-duet-select select.sc-duet-select:hover+.duet-select.sc-duet-select{border-color:#747475;box-shadow:0 0 0 1px #747475}.has-error.sc-duet-select .duet-select-wrapper.sc-duet-select select.sc-duet-select:hover+.duet-select.sc-duet-select{box-shadow:0 0 0 1px #de2362}.duet-theme-turva.has-error.sc-duet-select .duet-select-wrapper.sc-duet-select select.sc-duet-select:hover+.duet-select.sc-duet-select{box-shadow:0 0 0 1px #e02a0d}.duet-select-wrapper.sc-duet-select select.sc-duet-select:focus+.duet-select.sc-duet-select{border-color:#0077b3;outline:0;box-shadow:0 0 0 1px #0077b3;transition:none}.duet-theme-turva.sc-duet-select .duet-select-wrapper.sc-duet-select select.sc-duet-select:focus+.duet-select.sc-duet-select{border-color:#171c3a;box-shadow:0 0 0 1px #171c3a}.duet-theme-turva.sc-duet-select .duet-select-wrapper.sc-duet-select select.sc-duet-select:focus+.duet-select.sc-duet-select .duet-select-icon.sc-duet-select{color:#171c3a}.duet-select-wrapper.sc-duet-select select.sc-duet-select:focus+.duet-select.sc-duet-select .duet-select-icon.sc-duet-select{color:#0077b3}.has-error.sc-duet-select .duet-select-wrapper.sc-duet-select select.sc-duet-select:focus+.duet-select.sc-duet-select{box-shadow:0 0 0 1px #de2362}.duet-theme-turva.has-error.sc-duet-select .duet-select-wrapper.sc-duet-select select.sc-duet-select:focus+.duet-select.sc-duet-select{box-shadow:0 0 0 1px #e02a0d}.duet-select-wrapper.sc-duet-select select[disabled].sc-duet-select{cursor:default !important}.duet-select-wrapper.sc-duet-select select[disabled].sc-duet-select+.duet-select.sc-duet-select{color:#00294d !important;cursor:default !important;background:#f5f8fa !important;border-color:#f5f8fa !important;box-shadow:none !important;opacity:1 !important;-webkit-text-fill-color:#00294d !important}.duet-theme-turva.sc-duet-select .duet-select-wrapper.sc-duet-select select[disabled].sc-duet-select+.duet-select.sc-duet-select{color:#171c3a !important;background:#f5f5f7 !important;border-color:#f5f5f7 !important;-webkit-text-fill-color:#171c3a !important}.duet-select.sc-duet-select{position:absolute;top:0;right:0;bottom:0;left:0;z-index:100;display:block;width:100%;min-width:8rem;padding:12px 14px !important;padding-right:48px !important;overflow:hidden;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:400;font-variant-numeric:tabular-nums;line-height:1.5;color:#00294d;text-align:left;text-overflow:ellipsis;white-space:nowrap;background:white;border:1px solid #909599;border-radius:4px;transition:150ms ease}.has-error.sc-duet-select .duet-select.sc-duet-select{border-color:#de2362 !important}.has-error.sc-duet-select .duet-select.sc-duet-select .duet-select-icon.sc-duet-select{color:#de2362 !important}.duet-theme-turva.has-error.sc-duet-select .duet-select.sc-duet-select{border-color:#e02a0d !important}.duet-theme-turva.has-error.sc-duet-select .duet-select.sc-duet-select .duet-select-icon.sc-duet-select{color:#e02a0d !important}.duet-theme-turva.sc-duet-select .duet-select.sc-duet-select{font-family:\"turva-sans\", -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\";color:#171c3a;border-color:#747475}.duet-select.sc-duet-select svg.sc-duet-select{position:absolute;top:50%;right:16px;z-index:200;width:20px;height:20px;color:#00294d;pointer-events:none;transform:translateY(-50%)}.duet-theme-turva.sc-duet-select .duet-select.sc-duet-select svg.sc-duet-select{color:#171c3a}.duet-select-help.sc-duet-select{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:#657787;border-radius:4px}.duet-select-help.sc-duet-select span.sc-duet-select{display:block;margin-top:8px}.duet-theme-turva.sc-duet-select .duet-select-help.sc-duet-select{color:#747475}.has-error.sc-duet-select .duet-select-help.sc-duet-select{color:#de2362}.duet-theme-turva.has-error.sc-duet-select .duet-select-help.sc-duet-select{color:#e02a0d}.duet-label-hidden.sc-duet-select duet-label.sc-duet-select{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0 0 0 0);border:0}";
13261
+ const duetSelectCss = "@charset \"UTF-8\";*.sc-duet-select,*.sc-duet-select::after,*.sc-duet-select::before{box-sizing:border-box;padding:0;margin:0;background:transparent;border:0;-moz-appearance:none;-webkit-appearance:none;appearance:none}.sc-duet-select-h{box-sizing:border-box;padding:0;margin:0;background:transparent;border:0;-moz-appearance:none;-webkit-appearance:none;appearance:none;margin-right:16px !important;margin-bottom:12px !important;display:inline-flex;width:100%;max-width:100%;vertical-align:bottom}.sc-duet-select-h:last-child,.sc-duet-select-h:last-of-type{margin-right:0 !important}@media (min-width: 36em){.sc-duet-select-h{width:calc(50% - 16px - 3px)}.duet-expand.sc-duet-select-h{width:100% !important}}.duet-m-0.sc-duet-select-h{margin:0 !important}duet-tooltip.sc-duet-select{position:absolute;top:12px;right:0}@media (min-width: 48em){duet-tooltip.sc-duet-select{position:relative;top:4px;right:auto}}.duet-select-placeholder.sc-duet-select{position:absolute;top:-9px;left:9px;z-index:200;display:block;width:auto;max-width:60%;padding:0 0.25rem;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;background:white}.duet-select-container.sc-duet-select{position:relative;width:100%}.duet-select-wrapper.sc-duet-select{position:relative;width:100%;padding:15px 14px !important;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:400;line-height:1.25}.duet-theme-turva.sc-duet-select .duet-select-wrapper.sc-duet-select{font-family:\"turva-sans\", -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\"}.duet-select-wrapper.sc-duet-select::after{content:\"  \"}.duet-select-wrapper.sc-duet-select select.sc-duet-select{position:absolute;top:0;right:0;bottom:0;left:0;z-index:200;width:100%;height:100%;padding:0;margin:0;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;cursor:pointer;border:0;outline:none;opacity:0}.duet-theme-turva.sc-duet-select .duet-select-wrapper.sc-duet-select select.sc-duet-select{font-family:\"turva-sans\", -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\"}.duet-select-wrapper.sc-duet-select select.sc-duet-select:hover+.duet-select.sc-duet-select{border-color:#909599;box-shadow:0 0 0 1px #909599}.duet-theme-turva.sc-duet-select .duet-select-wrapper.sc-duet-select select.sc-duet-select:hover+.duet-select.sc-duet-select{border-color:#747475;box-shadow:0 0 0 1px #747475}.has-error.sc-duet-select .duet-select-wrapper.sc-duet-select select.sc-duet-select:hover+.duet-select.sc-duet-select{box-shadow:0 0 0 1px #de2362}.duet-theme-turva.has-error.sc-duet-select .duet-select-wrapper.sc-duet-select select.sc-duet-select:hover+.duet-select.sc-duet-select{box-shadow:0 0 0 1px #e02a0d}.duet-select-wrapper.sc-duet-select select.sc-duet-select:focus+.duet-select.sc-duet-select{border-color:#0077b3;outline:0;box-shadow:0 0 0 1px #0077b3;transition:none}.duet-theme-turva.sc-duet-select .duet-select-wrapper.sc-duet-select select.sc-duet-select:focus+.duet-select.sc-duet-select{border-color:#171c3a;box-shadow:0 0 0 1px #171c3a}.duet-theme-turva.sc-duet-select .duet-select-wrapper.sc-duet-select select.sc-duet-select:focus+.duet-select.sc-duet-select .duet-select-icon.sc-duet-select{color:#171c3a}.duet-select-wrapper.sc-duet-select select.sc-duet-select:focus+.duet-select.sc-duet-select .duet-select-icon.sc-duet-select{color:#0077b3}.has-error.sc-duet-select .duet-select-wrapper.sc-duet-select select.sc-duet-select:focus+.duet-select.sc-duet-select{box-shadow:0 0 0 1px #de2362}.duet-theme-turva.has-error.sc-duet-select .duet-select-wrapper.sc-duet-select select.sc-duet-select:focus+.duet-select.sc-duet-select{box-shadow:0 0 0 1px #e02a0d}.duet-select-wrapper.sc-duet-select select[disabled].sc-duet-select{cursor:default !important}.duet-select-wrapper.sc-duet-select select[disabled].sc-duet-select+.duet-select.sc-duet-select{color:#00294d !important;cursor:default !important;background:#f5f8fa !important;border-color:#f5f8fa !important;box-shadow:none !important;opacity:1 !important;-webkit-text-fill-color:#00294d !important}.duet-theme-turva.sc-duet-select .duet-select-wrapper.sc-duet-select select[disabled].sc-duet-select+.duet-select.sc-duet-select{color:#171c3a !important;background:#f5f5f7 !important;border-color:#f5f5f7 !important;-webkit-text-fill-color:#171c3a !important}.duet-select.sc-duet-select{position:absolute;top:0;right:0;bottom:0;left:0;z-index:100;display:block;width:100%;min-width:8rem;padding:12px 14px !important;padding-right:48px !important;overflow:hidden;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:400;font-variant-numeric:tabular-nums;line-height:1.5;color:#00294d;text-align:left;text-overflow:ellipsis;white-space:nowrap;background:white;border:1px solid #909599;border-radius:4px;transition:150ms ease}.has-error.sc-duet-select .duet-select.sc-duet-select{border-color:#de2362 !important}.has-error.sc-duet-select .duet-select.sc-duet-select .duet-select-icon.sc-duet-select{color:#de2362 !important}.duet-theme-turva.has-error.sc-duet-select .duet-select.sc-duet-select{border-color:#e02a0d !important}.duet-theme-turva.has-error.sc-duet-select .duet-select.sc-duet-select .duet-select-icon.sc-duet-select{color:#e02a0d !important}.duet-theme-turva.sc-duet-select .duet-select.sc-duet-select{font-family:\"turva-sans\", -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\";color:#171c3a;border-color:#747475}.duet-select.sc-duet-select svg.sc-duet-select{position:absolute;top:50%;right:16px;z-index:200;width:20px;height:20px;color:#00294d;pointer-events:none;transform:translateY(-50%)}.duet-theme-turva.sc-duet-select .duet-select.sc-duet-select svg.sc-duet-select{color:#171c3a}.duet-select-help.sc-duet-select{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:#657787;border-radius:4px}.duet-select-help.sc-duet-select span.sc-duet-select{display:block;margin-top:8px}.duet-theme-turva.sc-duet-select .duet-select-help.sc-duet-select{color:#747475}.has-error.sc-duet-select .duet-select-help.sc-duet-select{color:#de2362}.duet-theme-turva.has-error.sc-duet-select .duet-select-help.sc-duet-select{color:#e02a0d}.duet-label-hidden.sc-duet-select duet-label.sc-duet-select{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0 0 0 0);border:0}";
12662
13262
 
12663
13263
  function isOptionGroup(item) {
12664
13264
  return "options" in item;
@@ -12780,14 +13380,14 @@ class DuetSelect {
12780
13380
  if (this.nativeSelect) {
12781
13381
  this.nativeSelect.value = this.value;
12782
13382
  }
12783
- this.isCaptionVisible = !!(this.caption || (this.placeholder && this.echoPlaceholder && this.value));
13383
+ this.isCaptionVisible = !!this.caption;
12784
13384
  }
12785
13385
  /**
12786
13386
  * Component lifecycle events.
12787
13387
  */
12788
13388
  componentWillLoad() {
12789
13389
  inheritGlobalTheme(this);
12790
- this.isCaptionVisible = !!(this.caption || (this.placeholder && this.echoPlaceholder && this.value));
13390
+ this.isCaptionVisible = !!this.caption;
12791
13391
  this.refresh();
12792
13392
  }
12793
13393
  /**
@@ -12830,7 +13430,7 @@ class DuetSelect {
12830
13430
  "duet-theme-turva": this.theme === "turva",
12831
13431
  "duet-input-top-caption-shown": this.isCaptionVisible,
12832
13432
  "has-error": !!this.error,
12833
- } }, hAsync("duet-label", { theme: this.theme === "turva" ? "turva" : "default", class: { "duet-has-tooltip": !!this.tooltip }, id: this.labelId, for: identifier }, this.label), this.tooltip && (hAsync("duet-tooltip", { direction: this.tooltipDirection, accessibleInputLabel: this.label }, this.tooltip)), this.caption && (hAsync("duet-caption", { id: this.topCaptionId, size: "medium" }, this.caption)), this.placeholder && this.echoPlaceholder && this.value && (hAsync("duet-caption", { id: this.topCaptionPlaceholderId, size: "small" }, this.placeholder)), hAsync("div", { class: "duet-select-wrapper" }, hAsync("select", { ref: select => (this.nativeSelect = select), disabled: this.disabled, name: this.name, id: identifier, role: this.role, "aria-labelledby": `${this.labelId} ${this.errorId}`, "aria-controls": this.accessibleControls, "aria-activedescendant": this.accessibleActiveDescendant, "aria-owns": this.accessibleOwns, onFocus: this.onFocus, onBlur: this.onBlur, onChange: this.onChange, required: this.required, "aria-describedby": this.accessibleDescribedBy }, this.placeholder && (hAsync("option", { disabled: true, selected: true, value: "" }, this.placeholder)), !this.processedItems ? (hAsync("option", null, "Virhe valintoja ladattaessa. P\u00E4ivit\u00E4 sivu ja kokeile uusiksi.")) : (this.processedItems.map(item => {
13433
+ } }, hAsync("duet-label", { theme: this.theme === "turva" ? "turva" : "default", class: { "duet-has-tooltip": !!this.tooltip }, id: this.labelId, for: identifier }, this.label), this.tooltip && (hAsync("duet-tooltip", { direction: this.tooltipDirection, accessibleInputLabel: this.label }, this.tooltip)), this.caption && (hAsync("duet-caption", { id: this.topCaptionId, size: "medium" }, this.caption)), hAsync("div", { class: "duet-select-wrapper" }, this.placeholder && this.echoPlaceholder && this.value && (hAsync("duet-caption", { id: this.topCaptionPlaceholderId, class: "duet-select-placeholder", size: "small" }, this.placeholder)), hAsync("select", { ref: select => (this.nativeSelect = select), disabled: this.disabled, name: this.name, id: identifier, role: this.role, "aria-labelledby": `${this.labelId} ${this.errorId}`, "aria-controls": this.accessibleControls, "aria-activedescendant": this.accessibleActiveDescendant, "aria-owns": this.accessibleOwns, onFocus: this.onFocus, onBlur: this.onBlur, onChange: this.onChange, required: this.required, "aria-describedby": this.accessibleDescribedBy }, this.placeholder && (hAsync("option", { disabled: true, selected: true, value: "" }, this.placeholder)), !this.processedItems ? (hAsync("option", null, "Virhe valintoja ladattaessa. P\u00E4ivit\u00E4 sivu ja kokeile uusiksi.")) : (this.processedItems.map(item => {
12834
13434
  return isOptionGroup(item) ? this.renderOptionGroup(item) : this.renderOption(item);
12835
13435
  }))), hAsync("div", { class: "duet-select", "aria-hidden": "true" }, hAsync("span", { key: this.value }, this.getSelectedItemLabel()), hAsync("svg", { role: "img", class: "duet-select-icon", fill: "currentColor", viewBox: "0 0 24 24", xmlns: "http://www.w3.org/2000/svg" }, hAsync("path", { d: "m12 18.999c-.4 0-.776-.156-1.059-.438l-10.721-10.72c-.142-.142-.22-.33-.22-.531 0-.2.078-.389.22-.53.142-.142.33-.22.53-.22s.389.078.53.22l10.72 10.719 10.72-10.719c.142-.142.33-.22.53-.22s.389.078.53.22c.142.142.22.33.22.53s-.078.389-.22.53l-10.72 10.72c-.282.283-.659.439-1.06.439z" })))), hAsync("span", { class: "duet-select-help", id: this.errorId, "aria-live": "assertive", "aria-relevant": "additions removals" }, this.error && hAsync("span", null, this.error)))));
12836
13436
  }
@@ -13263,7 +13863,7 @@ class DuetTab {
13263
13863
  }; }
13264
13864
  }
13265
13865
 
13266
- const duetTabGroupCss = "*.sc-duet-tab-group,*.sc-duet-tab-group::after,*.sc-duet-tab-group::before{box-sizing:border-box;padding:0;margin:0;background:transparent;border:0;-moz-appearance:none;-webkit-appearance:none;appearance:none}.sc-duet-tab-group-h{box-sizing:border-box;padding:0;margin:0;background:transparent;border:0;-moz-appearance:none;-webkit-appearance:none;appearance:none;-webkit-tap-highlight-color:transparent;display:block;width:100%}.duet-tab-group-tabs.sc-duet-tab-group{margin-bottom:28px !important;display:block;width:100%;max-width:100%;padding-top:2px;list-style:none}.duet-tab-group-tabs.duet-m-0.sc-duet-tab-group{margin:0 !important}.duet-tab-group-tabs.duet-tab-group-hidden.sc-duet-tab-group{display:none}@media (min-width: 36em){.duet-tab-group-tabs.duet-tab-group-hidden.sc-duet-tab-group{display:block}}.duet-tab-variation-plain.sc-duet-tab-group .duet-tab-group-tabs.sc-duet-tab-group{border-bottom:1px solid #e1e3e6}.duet-theme-turva.duet-tab-variation-plain.sc-duet-tab-group .duet-tab-group-tabs.sc-duet-tab-group{border-bottom-color:#e4e4e6 !important}@media (min-width: 36em){duet-select.sc-duet-tab-group{display:none !important}}.duet-tab-button.sc-duet-tab-group{-webkit-user-select:none;user-select:none;position:relative;z-index:100;display:block;width:100%;padding:20px;margin-top:-2px;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.1;color:#00294d !important;text-align:left;text-decoration:none;cursor:pointer;background:white;border:2px solid #e1e3e6;border-style:solid;border-radius:0;transition:150ms ease}.duet-tab-button.duet-p-0.sc-duet-tab-group{padding:0 !important}.duet-tab-button.duet-m-0.sc-duet-tab-group{margin:0 !important}.duet-theme-turva.sc-duet-tab-group .duet-tab-button.sc-duet-tab-group{font-family:\"turva-sans\", -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\";color:#171c3a !important;border-color:#e4e4e6}.duet-tab-button.duet-p-0.sc-duet-tab-group{padding:0 !important}@media (min-width: 36em){.duet-tab-button.sc-duet-tab-group{display:inline-block;width:auto;margin-left:-2px;border-right:2px solid #e1e3e6;border-radius:0}}.duet-tab-button.sc-duet-tab-group:hover{z-index:200;border-color:#909599}.duet-theme-turva.sc-duet-tab-group .duet-tab-button.sc-duet-tab-group:hover{border-color:#747475 !important}.duet-tab-button.sc-duet-tab-group:active{opacity:0.75;transition:none}.duet-tab-button.selected.sc-duet-tab-group{z-index:201;color:white !important;background:#00294d;border-color:#00294d;outline:0;box-shadow:none !important}.duet-theme-turva.sc-duet-tab-group .duet-tab-button.selected.sc-duet-tab-group{color:white !important;background-color:#444445;border-color:#444445 !important}.duet-tab-button.sc-duet-tab-group:focus{z-index:200;outline:0}.user-is-tabbing.sc-duet-tab-group-h .duet-tab-button.sc-duet-tab-group:focus{box-shadow:0 0 0 4px rgba(0, 119, 179, 0.3), 0 0 0 1px #0077b3 !important}.user-is-tabbing.sc-duet-tab-group-h .duet-theme-turva.sc-duet-tab-group .duet-tab-button.sc-duet-tab-group:focus{box-shadow:0 0 0 4px rgba(23, 28, 58, 0.2), 0 0 0 1px #171c3a !important}.duet-tab-button.sc-duet-tab-group:first-child{border-top-left-radius:4px;border-top-right-radius:4px}@media (min-width: 36em){.duet-tab-button.sc-duet-tab-group:first-child{border-top-right-radius:0;border-bottom-left-radius:4px}}.duet-tab-button.sc-duet-tab-group:last-child{border-bottom-right-radius:4px;border-bottom-left-radius:4px}@media (min-width: 36em){.duet-tab-button.sc-duet-tab-group:last-child{border-radius:0;border-top-right-radius:4px;border-bottom-right-radius:4px}}.duet-tab-variation-plain.sc-duet-tab-group .duet-tab-button.sc-duet-tab-group{display:inline-block;width:auto;padding-right:0;padding-left:0;border:0;border-radius:0;transition:none}.duet-tab-variation-plain.sc-duet-tab-group .duet-tab-button.sc-duet-tab-group+.duet-tab-button.sc-duet-tab-group{margin-left:36px}.duet-tab-variation-plain.sc-duet-tab-group .duet-tab-button.selected.sc-duet-tab-group{color:#0077b3 !important;background:white;border-bottom:3px solid #0077b3}.duet-theme-turva.duet-tab-variation-plain.sc-duet-tab-group .duet-tab-button.selected.sc-duet-tab-group{color:#c60c30 !important;border-bottom-color:#c60c30 !important}.duet-tab-group-content.sc-duet-tab-group{position:relative;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:400;line-height:1.5;color:#00294d;text-align:left}.duet-theme-turva.sc-duet-tab-group .duet-tab-group-content.sc-duet-tab-group{font-family:\"turva-sans\", -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\";color:#171c3a}";
13866
+ const duetTabGroupCss = "*.sc-duet-tab-group,*.sc-duet-tab-group::after,*.sc-duet-tab-group::before{box-sizing:border-box;padding:0;margin:0;background:transparent;border:0;-moz-appearance:none;-webkit-appearance:none;appearance:none}.sc-duet-tab-group-h{box-sizing:border-box;padding:0;margin:0;background:transparent;border:0;-moz-appearance:none;-webkit-appearance:none;appearance:none;-webkit-tap-highlight-color:transparent;display:block;width:100%}.duet-tab-group-tabs.sc-duet-tab-group{margin-bottom:28px !important;display:block;width:100%;max-width:100%;padding-top:2px;list-style:none}.duet-tab-group-tabs.duet-m-0.sc-duet-tab-group{margin:0 !important}.duet-tab-group-tabs.duet-tab-group-hidden.sc-duet-tab-group{display:none}@media (min-width: 36em){.duet-tab-group-tabs.duet-tab-group-hidden.sc-duet-tab-group{display:block}}.duet-tab-variation-plain.sc-duet-tab-group .duet-tab-group-tabs.sc-duet-tab-group{border-bottom:1px solid #e1e3e6}.duet-theme-turva.duet-tab-variation-plain.sc-duet-tab-group .duet-tab-group-tabs.sc-duet-tab-group{border-bottom-color:#e4e4e6 !important}@media (min-width: 36em){duet-select.sc-duet-tab-group{display:none !important}}.duet-tab-button.sc-duet-tab-group{-webkit-user-select:none;user-select:none;position:relative;z-index:100;display:block;width:100%;padding:20px;margin-top:-2px;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.1;color:#00294d !important;text-align:left;text-decoration:none;cursor:pointer;background:white;border:2px solid #e1e3e6;border-style:solid;border-radius:0;transition:150ms ease}.duet-tab-button.duet-p-0.sc-duet-tab-group{padding:0 !important}.duet-tab-button.duet-m-0.sc-duet-tab-group{margin:0 !important}.duet-theme-turva.sc-duet-tab-group .duet-tab-button.sc-duet-tab-group{font-family:\"turva-sans\", -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\";color:#171c3a !important;border-color:#e4e4e6}.duet-tab-button.duet-p-0.sc-duet-tab-group{padding:0 !important}@media (min-width: 36em){.duet-tab-button.sc-duet-tab-group{display:inline-block;width:auto;margin-left:-2px;border-right:2px solid #e1e3e6;border-radius:0}}.duet-tab-button.sc-duet-tab-group:hover{z-index:200;border-color:#909599}.duet-theme-turva.sc-duet-tab-group .duet-tab-button.sc-duet-tab-group:hover{border-color:#747475 !important}.duet-tab-button.sc-duet-tab-group:active{opacity:0.75;transition:none}.duet-tab-button.selected.sc-duet-tab-group{z-index:201;color:white !important;background:#00294d;border-color:#00294d;outline:0;box-shadow:none !important}.duet-theme-turva.sc-duet-tab-group .duet-tab-button.selected.sc-duet-tab-group{color:white !important;background-color:#171c3a;border-color:#171c3a !important}.duet-tab-button.sc-duet-tab-group:focus{z-index:200;outline:0}.user-is-tabbing.sc-duet-tab-group-h .duet-tab-button.sc-duet-tab-group:focus{box-shadow:0 0 0 4px rgba(0, 119, 179, 0.3), 0 0 0 1px #0077b3 !important}.user-is-tabbing.sc-duet-tab-group-h .duet-theme-turva.sc-duet-tab-group .duet-tab-button.sc-duet-tab-group:focus{box-shadow:0 0 0 4px rgba(23, 28, 58, 0.2), 0 0 0 1px #171c3a !important}.duet-tab-button.sc-duet-tab-group:first-child{border-top-left-radius:4px;border-top-right-radius:4px}@media (min-width: 36em){.duet-tab-button.sc-duet-tab-group:first-child{border-top-right-radius:0;border-bottom-left-radius:4px}}.duet-tab-button.sc-duet-tab-group:last-child{border-bottom-right-radius:4px;border-bottom-left-radius:4px}@media (min-width: 36em){.duet-tab-button.sc-duet-tab-group:last-child{border-radius:0;border-top-right-radius:4px;border-bottom-right-radius:4px}}.duet-tab-variation-plain.sc-duet-tab-group .duet-tab-button.sc-duet-tab-group{display:inline-block;width:auto;padding-right:0;padding-left:0;border:0;border-radius:0;transition:none}.duet-tab-variation-plain.sc-duet-tab-group .duet-tab-button.sc-duet-tab-group+.duet-tab-button.sc-duet-tab-group{margin-left:36px}.duet-tab-variation-plain.sc-duet-tab-group .duet-tab-button.selected.sc-duet-tab-group{color:#0077b3 !important;background:white;border-bottom:3px solid #0077b3}.duet-theme-turva.duet-tab-variation-plain.sc-duet-tab-group .duet-tab-button.selected.sc-duet-tab-group{color:#c60c30 !important;border-bottom-color:#c60c30 !important}.duet-tab-group-content.sc-duet-tab-group{position:relative;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:400;line-height:1.5;color:#00294d;text-align:left}.duet-theme-turva.sc-duet-tab-group .duet-tab-group-content.sc-duet-tab-group{font-family:\"turva-sans\", -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\";color:#171c3a}";
13267
13867
 
13268
13868
  class DuetTabGroup {
13269
13869
  constructor(hostRef) {
@@ -13591,7 +14191,7 @@ class DuetTable {
13591
14191
  }; }
13592
14192
  }
13593
14193
 
13594
- const duetTextareaCss = "*.sc-duet-textarea,*.sc-duet-textarea::after,*.sc-duet-textarea::before{box-sizing:border-box;padding:0;margin:0;background:transparent;border:0;-moz-appearance:none;-webkit-appearance:none;appearance:none}.sc-duet-textarea-h{box-sizing:border-box;padding:0;margin:0;background:transparent;border:0;-moz-appearance:none;-webkit-appearance:none;appearance:none;margin-right:16px !important;margin-bottom:12px !important;display:block;width:100%;max-width:100%;text-align:left}.sc-duet-textarea-h:last-child,.sc-duet-textarea-h:last-of-type{margin-right:0 !important}@media (min-width: 36em){.sc-duet-textarea-h{width:calc(50% - 16px - 3px)}.duet-expand.sc-duet-textarea-h{width:100% !important}}.duet-m-0.sc-duet-textarea-h{margin:0 !important}duet-tooltip.sc-duet-textarea{position:absolute;top:12px;right:0}@media (min-width: 48em){duet-tooltip.sc-duet-textarea{position:relative;top:4px;right:auto}}.duet-textarea-container.sc-duet-textarea{position:relative;width:100%;height:100%}.duet-textarea-container.sc-duet-textarea .duet-input-top-caption.sc-duet-textarea{display:none}.duet-textarea-container.duet-input-top-caption-shown.sc-duet-textarea .duet-input-top-caption.sc-duet-textarea{display:flex !important}.duet-textarea.sc-duet-textarea{padding:15px !important;position:relative;z-index:100;display:block;width:100%;min-width:8rem;min-height:160px;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:400;font-variant-numeric:tabular-nums;line-height:1.25;color:#00294d;resize:vertical;background:white;border:1px solid #909599;border-radius:4px;transition:150ms ease}.duet-theme-turva.sc-duet-textarea .duet-textarea.sc-duet-textarea{font-family:\"turva-sans\", -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\";color:#171c3a;border-color:#747475}.has-error.sc-duet-textarea .duet-textarea.sc-duet-textarea{border-color:#de2362 !important}.duet-theme-turva.has-error.sc-duet-textarea .duet-textarea.sc-duet-textarea{border-color:#e02a0d !important}.duet-textarea.sc-duet-textarea::-webkit-input-placeholder{color:#657787;opacity:1 !important;transition:color 300ms ease}.duet-theme-turva.sc-duet-textarea .duet-textarea.sc-duet-textarea::-webkit-input-placeholder{color:#747475}.duet-textarea.sc-duet-textarea:focus::-webkit-input-placeholder{color:#cfd2d4}.duet-theme-turva.sc-duet-textarea .duet-textarea.sc-duet-textarea:focus::-webkit-input-placeholder{color:#cfcfd1}.duet-textarea.sc-duet-textarea::-moz-placeholder{color:#657787;opacity:1 !important}.duet-theme-turva.sc-duet-textarea .duet-textarea.sc-duet-textarea::-moz-placeholder{color:#747475}.duet-textarea.sc-duet-textarea:focus::-moz-placeholder{color:#cfd2d4}.duet-theme-turva.sc-duet-textarea .duet-textarea.sc-duet-textarea:focus::-moz-placeholder{color:#cfcfd1}.duet-textarea.sc-duet-textarea:-ms-input-placeholder{color:#657787}.duet-theme-turva.sc-duet-textarea .duet-textarea.sc-duet-textarea:-ms-input-placeholder{color:#747475}.duet-textarea.sc-duet-textarea:focus:-ms-input-placeholder{color:#cfd2d4}.duet-theme-turva.sc-duet-textarea .duet-textarea.sc-duet-textarea:focus:-ms-input-placeholder{color:#cfcfd1}.duet-textarea[disabled].sc-duet-textarea{color:#657787 !important;cursor:default !important;background:#f5f8fa !important;border-color:#f5f8fa !important}.duet-theme-turva.sc-duet-textarea .duet-textarea[disabled].sc-duet-textarea{color:#747475 !important;background:#f5f5f7 !important;border-color:#f5f5f7 !important}.duet-textarea.sc-duet-textarea:hover:not(:disabled){box-shadow:0 0 0 1px #909599}.duet-theme-turva.sc-duet-textarea .duet-textarea.sc-duet-textarea:hover:not(:disabled){box-shadow:0 0 0 1px #747475}.has-error.sc-duet-textarea .duet-textarea.sc-duet-textarea:hover:not(:disabled){box-shadow:0 0 0 1px #de2362}.duet-theme-turva.has-error.sc-duet-textarea .duet-textarea.sc-duet-textarea:hover:not(:disabled){box-shadow:0 0 0 1px #e02a0d}.duet-textarea.sc-duet-textarea:focus{border-color:#0077b3;outline:0;box-shadow:0 0 0 1px #0077b3;transition:none}.duet-theme-turva.sc-duet-textarea .duet-textarea.sc-duet-textarea:focus{border-color:#171c3a;box-shadow:0 0 0 1px #171c3a}.has-error.sc-duet-textarea .duet-textarea.sc-duet-textarea:focus{box-shadow:0 0 0 1px #de2362}.duet-theme-turva.has-error.sc-duet-textarea .duet-textarea.sc-duet-textarea:focus{box-shadow:0 0 0 1px #e02a0d}.duet-textarea.sc-duet-textarea:not(:focus):not(:hover):invalid{box-shadow:none}.duet-textarea-help.sc-duet-textarea{font-size:0.875rem;line-height:1.25}.duet-textarea-help.sc-duet-textarea span.sc-duet-textarea{display:block;margin-top:8px}.has-error.sc-duet-textarea .duet-textarea-help.sc-duet-textarea{color:#de2362}.duet-theme-turva.has-error.sc-duet-textarea .duet-textarea-help.sc-duet-textarea{color:#e02a0d}.duet-label-hidden.sc-duet-textarea duet-label.sc-duet-textarea{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0 0 0 0);border:0}.duet-character-count.sc-duet-textarea{display:block;margin:8px 0 0 auto}";
14194
+ const duetTextareaCss = "*.sc-duet-textarea,*.sc-duet-textarea::after,*.sc-duet-textarea::before{box-sizing:border-box;padding:0;margin:0;background:transparent;border:0;-moz-appearance:none;-webkit-appearance:none;appearance:none}.sc-duet-textarea-h{box-sizing:border-box;padding:0;margin:0;background:transparent;border:0;-moz-appearance:none;-webkit-appearance:none;appearance:none;margin-right:16px !important;margin-bottom:12px !important;display:block;width:100%;max-width:100%;text-align:left}.sc-duet-textarea-h:last-child,.sc-duet-textarea-h:last-of-type{margin-right:0 !important}@media (min-width: 36em){.sc-duet-textarea-h{width:calc(50% - 16px - 3px)}.duet-expand.sc-duet-textarea-h{width:100% !important}}.duet-m-0.sc-duet-textarea-h{margin:0 !important}duet-tooltip.sc-duet-textarea{position:absolute;top:12px;right:0}@media (min-width: 48em){duet-tooltip.sc-duet-textarea{position:relative;top:4px;right:auto}}.duet-textarea-container.sc-duet-textarea{position:relative;width:100%;height:100%}.duet-textarea-container.sc-duet-textarea .duet-input-top-caption.sc-duet-textarea{display:none}.duet-textarea-container.duet-input-top-caption-shown.sc-duet-textarea .duet-input-top-caption.sc-duet-textarea{display:flex !important}.duet-textarea-wrapper.sc-duet-textarea{position:relative}.duet-textarea-placeholder.sc-duet-textarea{position:absolute;top:-9px;left:9px;z-index:200;display:block;width:auto;max-width:60%;padding:0 0.25rem;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;background:white}.duet-textarea.sc-duet-textarea{padding:15px !important;position:relative;z-index:100;display:block;width:100%;min-width:8rem;min-height:160px;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:400;font-variant-numeric:tabular-nums;line-height:1.25;color:#00294d;resize:vertical;background:white;border:1px solid #909599;border-radius:4px;transition:150ms ease}.duet-theme-turva.sc-duet-textarea .duet-textarea.sc-duet-textarea{font-family:\"turva-sans\", -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\";color:#171c3a;border-color:#747475}.has-error.sc-duet-textarea .duet-textarea.sc-duet-textarea{border-color:#de2362 !important}.duet-theme-turva.has-error.sc-duet-textarea .duet-textarea.sc-duet-textarea{border-color:#e02a0d !important}.duet-textarea.sc-duet-textarea::-webkit-input-placeholder{color:#657787;opacity:1 !important;transition:color 300ms ease}.duet-theme-turva.sc-duet-textarea .duet-textarea.sc-duet-textarea::-webkit-input-placeholder{color:#747475}.duet-textarea.sc-duet-textarea:focus::-webkit-input-placeholder{color:#cfd2d4}.duet-theme-turva.sc-duet-textarea .duet-textarea.sc-duet-textarea:focus::-webkit-input-placeholder{color:#cfcfd1}.duet-textarea.sc-duet-textarea::-moz-placeholder{color:#657787;opacity:1 !important}.duet-theme-turva.sc-duet-textarea .duet-textarea.sc-duet-textarea::-moz-placeholder{color:#747475}.duet-textarea.sc-duet-textarea:focus::-moz-placeholder{color:#cfd2d4}.duet-theme-turva.sc-duet-textarea .duet-textarea.sc-duet-textarea:focus::-moz-placeholder{color:#cfcfd1}.duet-textarea.sc-duet-textarea:-ms-input-placeholder{color:#657787}.duet-theme-turva.sc-duet-textarea .duet-textarea.sc-duet-textarea:-ms-input-placeholder{color:#747475}.duet-textarea.sc-duet-textarea:focus:-ms-input-placeholder{color:#cfd2d4}.duet-theme-turva.sc-duet-textarea .duet-textarea.sc-duet-textarea:focus:-ms-input-placeholder{color:#cfcfd1}.duet-textarea[disabled].sc-duet-textarea{color:#657787 !important;cursor:default !important;background:#f5f8fa !important;border-color:#f5f8fa !important}.duet-theme-turva.sc-duet-textarea .duet-textarea[disabled].sc-duet-textarea{color:#747475 !important;background:#f5f5f7 !important;border-color:#f5f5f7 !important}.duet-textarea.sc-duet-textarea:hover:not(:disabled){box-shadow:0 0 0 1px #909599}.duet-theme-turva.sc-duet-textarea .duet-textarea.sc-duet-textarea:hover:not(:disabled){box-shadow:0 0 0 1px #747475}.has-error.sc-duet-textarea .duet-textarea.sc-duet-textarea:hover:not(:disabled){box-shadow:0 0 0 1px #de2362}.duet-theme-turva.has-error.sc-duet-textarea .duet-textarea.sc-duet-textarea:hover:not(:disabled){box-shadow:0 0 0 1px #e02a0d}.duet-textarea.sc-duet-textarea:focus{border-color:#0077b3;outline:0;box-shadow:0 0 0 1px #0077b3;transition:none}.duet-theme-turva.sc-duet-textarea .duet-textarea.sc-duet-textarea:focus{border-color:#171c3a;box-shadow:0 0 0 1px #171c3a}.has-error.sc-duet-textarea .duet-textarea.sc-duet-textarea:focus{box-shadow:0 0 0 1px #de2362}.duet-theme-turva.has-error.sc-duet-textarea .duet-textarea.sc-duet-textarea:focus{box-shadow:0 0 0 1px #e02a0d}.duet-textarea.sc-duet-textarea:not(:focus):not(:hover):invalid{box-shadow:none}.duet-textarea-help.sc-duet-textarea{font-size:0.875rem;line-height:1.25}.duet-textarea-help.sc-duet-textarea span.sc-duet-textarea{display:block;margin-top:8px}.has-error.sc-duet-textarea .duet-textarea-help.sc-duet-textarea{color:#de2362}.duet-theme-turva.has-error.sc-duet-textarea .duet-textarea-help.sc-duet-textarea{color:#e02a0d}.duet-label-hidden.sc-duet-textarea duet-label.sc-duet-textarea{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0 0 0 0);border:0}.duet-character-count.sc-duet-textarea{display:block;margin:8px 0 0 auto}";
13595
14195
 
13596
14196
  const CharacterCount = ({ value, maxlength, label, theme }) => {
13597
14197
  if (maxlength == null) {
@@ -13692,7 +14292,7 @@ class DuetTextarea {
13692
14292
  cleanValue(this.nativeInput, this.disallowPatternRegex);
13693
14293
  }
13694
14294
  this.value = this.nativeInput.value;
13695
- this.isCaptionVisible = !!(this.caption || (this.placeholder && this.echoPlaceholder && this.value));
14295
+ this.isCaptionVisible = !!this.caption;
13696
14296
  this.duetInput.emit({
13697
14297
  originalEvent: ev,
13698
14298
  value: this.value,
@@ -13731,7 +14331,7 @@ class DuetTextarea {
13731
14331
  componentWillLoad() {
13732
14332
  inheritGlobalTheme(this);
13733
14333
  this.disallowedPatternChange();
13734
- this.isCaptionVisible = !!(this.caption || (this.placeholder && this.echoPlaceholder && this.value));
14334
+ this.isCaptionVisible = !!this.caption;
13735
14335
  if (this.counter && this.maxlength == null) {
13736
14336
  console.warn("[DUET WARNING]: counter will only take effect if maxlength is set");
13737
14337
  }
@@ -13765,7 +14365,7 @@ class DuetTextarea {
13765
14365
  "duet-label-hidden": this.labelHidden,
13766
14366
  "duet-input-top-caption-shown": this.isCaptionVisible,
13767
14367
  "has-error": !!this.error,
13768
- } }, hAsync("duet-label", { theme: this.theme === "turva" ? "turva" : "default", class: { "duet-has-tooltip": !!this.tooltip }, margin: this.isCaptionVisible ? "small" : "auto", id: this.labelId, for: identifier }, this.label), this.tooltip && (hAsync("duet-tooltip", { direction: this.tooltipDirection, accessibleInputLabel: this.label }, this.tooltip)), this.caption && (hAsync("duet-caption", { id: this.topCaptionId, size: "medium" }, this.caption)), this.placeholder && this.echoPlaceholder && this.value && (hAsync("duet-caption", { id: this.topCaptionPlaceholderId, size: "small" }, this.placeholder)), hAsync("textarea", { onInput: this.handleInput, onChange: this.handleChange, onBlur: this.handleBlur, onFocus: this.handleFocus, ref: input => (this.nativeInput = input), class: { "duet-textarea": true, disabled: this.disabled }, value: this.value, disabled: this.disabled, "aria-labelledby": `${this.labelId} ${this.errorId}`, "aria-controls": this.accessibleControls, "aria-autocomplete": this.accessibleAutocomplete, "aria-activedescendant": this.accessibleActiveDescendant, "aria-owns": this.accessibleOwns, "aria-describedby": `${this.isCaptionVisible ? this.topCaptionId : ""} ${this.accessibleDescribedBy}`, placeholder: this.placeholder, spellcheck: "false", required: this.required, minlength: this.minlength, maxlength: this.maxlength, role: this.role, name: this.name, id: identifier }), hAsync("duet-grid", { alignment: "stretch" }, hAsync("duet-grid-item", { margin: "none", fill: true }, hAsync("div", { class: "duet-textarea-help", id: this.errorId, "aria-live": "assertive", "aria-relevant": "additions removals" }, this.error && hAsync("span", null, this.error))), hAsync("duet-grid-item", { margin: "none", class: "duet-character-count-caption" }, this.counter && (hAsync(CharacterCount, { theme: this.theme, value: this.value, maxlength: this.maxlength, label: this.counterLabel })))))));
14368
+ } }, hAsync("duet-label", { theme: this.theme === "turva" ? "turva" : "default", class: { "duet-has-tooltip": !!this.tooltip }, margin: this.isCaptionVisible ? "small" : "auto", id: this.labelId, for: identifier }, this.label), this.tooltip && (hAsync("duet-tooltip", { direction: this.tooltipDirection, accessibleInputLabel: this.label }, this.tooltip)), this.caption && (hAsync("duet-caption", { id: this.topCaptionId, size: "medium" }, this.caption)), hAsync("div", { class: "duet-textarea-wrapper" }, this.placeholder && this.echoPlaceholder && this.value && (hAsync("duet-caption", { id: this.topCaptionPlaceholderId, class: "duet-textarea-placeholder", size: "small" }, this.placeholder)), hAsync("textarea", { onInput: this.handleInput, onChange: this.handleChange, onBlur: this.handleBlur, onFocus: this.handleFocus, ref: input => (this.nativeInput = input), class: { "duet-textarea": true, disabled: this.disabled }, value: this.value, disabled: this.disabled, "aria-labelledby": `${this.labelId} ${this.errorId}`, "aria-controls": this.accessibleControls, "aria-autocomplete": this.accessibleAutocomplete, "aria-activedescendant": this.accessibleActiveDescendant, "aria-owns": this.accessibleOwns, "aria-describedby": `${this.isCaptionVisible ? this.topCaptionId : ""} ${this.accessibleDescribedBy}`, placeholder: this.placeholder, spellcheck: "false", required: this.required, minlength: this.minlength, maxlength: this.maxlength, role: this.role, name: this.name, id: identifier })), hAsync("duet-grid", { alignment: "stretch" }, hAsync("duet-grid-item", { margin: "none", fill: true }, hAsync("div", { class: "duet-textarea-help", id: this.errorId, "aria-live": "assertive", "aria-relevant": "additions removals" }, this.error && hAsync("span", null, this.error))), hAsync("duet-grid-item", { margin: "none", class: "duet-character-count-caption" }, this.counter && (hAsync(CharacterCount, { theme: this.theme, value: this.value, maxlength: this.maxlength, label: this.counterLabel })))))));
13769
14369
  }
13770
14370
  get element() { return getElement(this); }
13771
14371
  static get watchers() { return {
@@ -14317,6 +14917,1246 @@ class DuetTray {
14317
14917
  }; }
14318
14918
  }
14319
14919
 
14920
+ var errorCodes = [
14921
+ {
14922
+ type: "default",
14923
+ system_message: "unknown error",
14924
+ message: {
14925
+ fi: "Tapahtui tuntematon virhe, ole hyvä ja yritä uudelleen.",
14926
+ sv: "Ett okänt fel uppstod, försök igen.",
14927
+ en: "An unknown error occured, please try again."
14928
+ }
14929
+ },
14930
+ {
14931
+ type: "400",
14932
+ system_message: "Bad Request: The server could not understand the request due to invalid syntax.",
14933
+ message: {
14934
+ fi: "Tiedostoa ei hyväksytty.",
14935
+ sv: "Servern avvisade din fil.",
14936
+ en: "The server rejected your file."
14937
+ }
14938
+ },
14939
+ {
14940
+ type: "401",
14941
+ system_message: "Not Authenticated: The client must authenticate itself to get the requested response...",
14942
+ message: {
14943
+ fi: "Vain kirjautunut käyttäjä voi lähettää tiedostoja.",
14944
+ sv: "Du måste vara inloggad för att ladda upp filer.",
14945
+ en: "You need to be logged in to upload files."
14946
+ }
14947
+ },
14948
+ {
14949
+ type: "403",
14950
+ system_message: "No Access: The client does not have access rights to the content.",
14951
+ message: {
14952
+ fi: "Ei oikeuksia lähettää tiedostoja.",
14953
+ sv: "Du har inte rätt åtkomsträttigheter för att ladda upp filer.",
14954
+ en: "You do not have the correct access rights to upload files."
14955
+ }
14956
+ },
14957
+ {
14958
+ type: "413",
14959
+ system_message: "Payload too large",
14960
+ message: {
14961
+ fi: "Tiedosto oli liian vastaanotettavaksi.",
14962
+ sv: "Filen var för stor för servern att hantera.",
14963
+ en: "The file was to large for the server to handle."
14964
+ }
14965
+ },
14966
+ {
14967
+ type: "415",
14968
+ system_message: "Unsupported media type",
14969
+ message: {
14970
+ fi: "Tiedoston tyyppi oli väärä.",
14971
+ sv: "Servern avvisade filen eftersom den hade fel typ.",
14972
+ en: "The server rejected the file because it had the wrong type."
14973
+ }
14974
+ },
14975
+ {
14976
+ type: "429",
14977
+ system_message: "Too many request from same address",
14978
+ message: {
14979
+ fi: "Liian monta yritystä, ole hyvä ja yritä myöhemmin uudelleen.",
14980
+ sv: "Servern har fått många förfrågningar från dig, försök igen senare.",
14981
+ en: "The server has received to many request from you, please try again later."
14982
+ }
14983
+ },
14984
+ {
14985
+ type: "500",
14986
+ system_message: "Internal Server Error",
14987
+ message: {
14988
+ fi: "Palvelin ilmoitti tuntemattomasta virheestä ja lataus epäonnistui.",
14989
+ sv: "Servern rapporterade ett okänt fel och uppladdningen misslyckades.",
14990
+ en: "The server reported an unknown error and the upload failed."
14991
+ }
14992
+ },
14993
+ {
14994
+ type: "duet-upload-100",
14995
+ system_message: "File extension not allowed",
14996
+ message: {
14997
+ fi: "Tiedoston tyyppi ei ole sallittu.",
14998
+ sv: "Du kan inte ladda upp filer av den type.",
14999
+ en: "You cannot upload files with that extension."
15000
+ }
15001
+ },
15002
+ {
15003
+ type: "duet-upload-001",
15004
+ system_message: "File transfer failed",
15005
+ message: {
15006
+ fi: "Tiedoston lähetys keskeytyi, ole hyvä ja yritä uudelleen.",
15007
+ sv: "Din anslutning till servern avbröts, försök igen.",
15008
+ en: "Your connection to the server was interrupted, try again."
15009
+ }
15010
+ },
15011
+ {
15012
+ type: "duet-upload-101",
15013
+ system_message: "File mimetype not allowed",
15014
+ message: {
15015
+ fi: "Tiedoston tyyppi ei ole sallittu.",
15016
+ sv: "Du kan inte ladda upp filer av den typ.",
15017
+ en: "You cannot upload files of that type."
15018
+ }
15019
+ },
15020
+ {
15021
+ type: "duet-upload-201",
15022
+ system_message: "File is too large",
15023
+ message: {
15024
+ fi: "Tiedosto on liian iso.",
15025
+ sv: "Filen är större än tillåtet.",
15026
+ en: "The file is larger than permitted."
15027
+ }
15028
+ },
15029
+ {
15030
+ type: "duet-upload-202",
15031
+ system_message: "The combined size of all files is too large",
15032
+ message: {
15033
+ fi: "Tiedostojen yhteenlaskettu koko on liian iso.",
15034
+ sv: "Du har nått den maximala kombinerade filstorleken.",
15035
+ en: "You have reached the maximum combined filesize."
15036
+ }
15037
+ },
15038
+ {
15039
+ type: "duet-upload-301",
15040
+ system_message: "The maximum file limit has been reached",
15041
+ message: {
15042
+ fi: "Liitteiden maksimimäärä saavutettu.",
15043
+ sv: "Maximalt antal bilagor har uppnåtts.",
15044
+ en: "Maximum number of attachments reached."
15045
+ }
15046
+ }
15047
+ ];
15048
+
15049
+ const getError = (code) => {
15050
+ let error = {
15051
+ type: undefined,
15052
+ system_message: undefined,
15053
+ message: undefined,
15054
+ };
15055
+ error = errorCodes.filter(errorItem => {
15056
+ // the == is intentional we may be comparing numbers to strings - and that is ok here
15057
+ return errorItem.type == code;
15058
+ })[0];
15059
+ if (!error) {
15060
+ error = errorCodes.filter(errorItem => {
15061
+ return errorItem.type === "default";
15062
+ })[0];
15063
+ }
15064
+ return error;
15065
+ };
15066
+ const getI18nError = (errorCode) => {
15067
+ const errorFromJson = getError(errorCode);
15068
+ const i18String = getLocaleString(errorFromJson.message);
15069
+ if (i18String === "" || !i18String) {
15070
+ return errorFromJson.system_message;
15071
+ }
15072
+ else {
15073
+ return i18String;
15074
+ }
15075
+ };
15076
+
15077
+ const ErrorItem = ({ data }) => {
15078
+ const { item, error } = data;
15079
+ const { name } = item;
15080
+ const { type } = error;
15081
+ return (hAsync("span", { class: "duet-upload-item-error", role: "status" },
15082
+ hAsync("duet-paragraph", { class: "duet-upload-item-name", color: "danger", margin: "none", weight: "semi-bold" },
15083
+ hAsync("duet-icon", { margin: "none", size: "xx-small", name: "messaging-attachment" }),
15084
+ " ",
15085
+ name),
15086
+ hAsync("duet-paragraph", { class: "duet-upload-item-error-label", size: "small", margin: "none", color: "danger" }, getI18nError(type))));
15087
+ };
15088
+
15089
+ const ProgressItem = ({ progress, name }) => (hAsync("span", null,
15090
+ hAsync("duet-paragraph", { color: "secondary", margin: "none", size: "small" }, name),
15091
+ hAsync("duet-spacer", { size: "xx-small" }),
15092
+ hAsync("duet-progress", { progress: Math.ceil(progress), "aria-hidden": true })));
15093
+
15094
+ const formatBytes = (bytes, decimals = 2) => {
15095
+ if (bytes === 0) {
15096
+ return "0 Bytes";
15097
+ }
15098
+ const k = 1024;
15099
+ const dm = decimals < 0 ? 0 : decimals;
15100
+ const sizes = ["Bytes", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"];
15101
+ const i = Math.floor(Math.log(bytes) / Math.log(k));
15102
+ return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + " " + sizes[i];
15103
+ };
15104
+
15105
+ const SuccessItem = ({ data, showLinks }) => {
15106
+ const { item, size, uploaded, url, meta } = data;
15107
+ const { name } = item;
15108
+ const ContentName = (hAsync("span", { class: "duet-upload-item-name" },
15109
+ hAsync("duet-icon", { margin: "none", size: "xx-small", name: "messaging-attachment" }),
15110
+ hAsync("duet-spacer", { size: "xx-small", direction: "horizontal" }),
15111
+ name));
15112
+ const SizeText = (hAsync("span", { class: "duet-upload-item-size", style: { fontSize: "14px", fontWeight: "400" } },
15113
+ "(",
15114
+ formatBytes(size),
15115
+ ")"));
15116
+ const FilenameLine = uploaded && url && showLinks ? (hAsync("duet-paragraph", { color: "secondary", margin: "none", weight: "semi-bold" },
15117
+ hAsync("duet-link", { url: url, external: true }, ContentName),
15118
+ hAsync("duet-spacer", { size: "xx-small", direction: "horizontal" }),
15119
+ SizeText)) : (hAsync("duet-paragraph", { color: "secondary", margin: "none", weight: "semi-bold" },
15120
+ ContentName,
15121
+ hAsync("duet-spacer", { size: "xx-small", direction: "horizontal" }),
15122
+ SizeText));
15123
+ const Badges = meta && meta.badges ? (hAsync("span", null,
15124
+ hAsync("duet-spacer", { size: "xx-small" }),
15125
+ meta.badges.map(badgeText => (hAsync("duet-badge", { color: "primary" }, badgeText))))) : undefined;
15126
+ return (hAsync("span", { class: "duet-upload-item-success" },
15127
+ hAsync("div", null, FilenameLine),
15128
+ Badges));
15129
+ };
15130
+
15131
+ const validateFileExtension = (name, allowedExtensions) => {
15132
+ if (!allowedExtensions) {
15133
+ return true;
15134
+ }
15135
+ const ext = name.split(".");
15136
+ const validExtension = allowedExtensions.split(",");
15137
+ const extension = ext[ext.length - 1];
15138
+ return validExtension.includes(extension);
15139
+ };
15140
+ const validateFileMime = (type, allowedMimetypes) => {
15141
+ if (!allowedMimetypes || !type) {
15142
+ return true;
15143
+ }
15144
+ const validMimeTypes = allowedMimetypes.split(",");
15145
+ let valid = false;
15146
+ validMimeTypes.forEach(mimeType => {
15147
+ const allowedTypes = mimeType.split("/");
15148
+ const fileType = type.split("/");
15149
+ if (allowedTypes[0] === fileType[0] && (allowedTypes[1] === fileType[1] || allowedTypes[1] === "*")) {
15150
+ valid = true;
15151
+ }
15152
+ });
15153
+ return valid;
15154
+ };
15155
+ const validateFileSize = (size, maxBytes) => {
15156
+ if (!maxBytes || !size) {
15157
+ return true;
15158
+ }
15159
+ return maxBytes >= size;
15160
+ };
15161
+ const validateFile = (item, validators) => {
15162
+ const { allowedMimetypes, allowedExtensions, maxBytes } = validators;
15163
+ let valid = false;
15164
+ let errorMessage = getError("default");
15165
+ if (item) {
15166
+ const { name, type, size } = item;
15167
+ const mime = validateFileMime(type, allowedMimetypes);
15168
+ const ext = validateFileExtension(name, allowedExtensions);
15169
+ const bytes = validateFileSize(size, maxBytes);
15170
+ if (!mime) {
15171
+ errorMessage = getError("duet-upload-101");
15172
+ }
15173
+ if (!ext) {
15174
+ errorMessage = getError("duet-upload-100");
15175
+ }
15176
+ if (!bytes) {
15177
+ errorMessage = getError("duet-upload-201");
15178
+ }
15179
+ valid = mime && ext && bytes;
15180
+ }
15181
+ else {
15182
+ valid = false;
15183
+ }
15184
+ return {
15185
+ valid,
15186
+ errorMessage: valid ? undefined : getLocaleString(errorMessage.message),
15187
+ errorSystem: valid ? undefined : errorMessage.system_message,
15188
+ errorType: valid ? undefined : errorMessage.type,
15189
+ };
15190
+ };
15191
+ const validateTotalSizeIsAboveMax = (filelist, maxTotalBytes) => {
15192
+ let total = 0;
15193
+ if (maxTotalBytes) {
15194
+ filelist.forEach(item => {
15195
+ if (item.valid && item.size) {
15196
+ total += item.size;
15197
+ }
15198
+ });
15199
+ if (total < maxTotalBytes) {
15200
+ return true;
15201
+ }
15202
+ }
15203
+ return false;
15204
+ };
15205
+ const validateTotalAmountIsAboveMax = (filelist, maxFiles) => {
15206
+ let total = 0;
15207
+ if (maxFiles) {
15208
+ filelist.forEach(item => {
15209
+ if (item.valid) {
15210
+ total++;
15211
+ }
15212
+ });
15213
+ if (total > maxFiles) {
15214
+ return true;
15215
+ }
15216
+ }
15217
+ return false;
15218
+ };
15219
+
15220
+ const makeXhrRequest = ({ payload, options, onFailure, onSuccess, onProgress }) => {
15221
+ const { type = "POST", xhr, uri, argument = null, headers = null } = options;
15222
+ xhr.open(type, `${uri}${argument || ""}`, true);
15223
+ const { data, name } = payload;
15224
+ // headers must be added after open
15225
+ if (headers) {
15226
+ Object.keys(headers).forEach(key => {
15227
+ xhr.setRequestHeader(key, headers[key]);
15228
+ });
15229
+ }
15230
+ if (type === "POST") {
15231
+ xhr.onreadystatechange = () => {
15232
+ // Call a function when the state changes.
15233
+ if (xhr.readyState === XMLHttpRequest.DONE && xhr.status >= 200 && xhr.status < 300) {
15234
+ // Request finished without errors
15235
+ onSuccess(xhr, name, xhr.status);
15236
+ }
15237
+ if (xhr.readyState === XMLHttpRequest.DONE && xhr.status >= 300 && xhr.status < 999) {
15238
+ // Request finished with errors
15239
+ onFailure(xhr, name, xhr.status);
15240
+ }
15241
+ };
15242
+ onProgress(name);
15243
+ }
15244
+ xhr.send(data);
15245
+ return xhr;
15246
+ };
15247
+
15248
+ const duetUploadCss = "/*!@*,\n*::after,\n*::before*/*.sc-duet-upload,*.sc-duet-upload::after,*.sc-duet-upload::before{box-sizing:border-box;padding:0;margin:0;background:transparent;border:0;-moz-appearance:none;-webkit-appearance:none;appearance:none}/*!@:host*/.sc-duet-upload-h{box-sizing:border-box;padding:0;margin:0;background:transparent;border:0;-moz-appearance:none;-webkit-appearance:none;appearance:none}/*!@::slotted([slot=header])*/.sc-duet-upload-s>[slot=header]{margin-bottom:16px}/*!@::slotted([slot=fileheader])*/.sc-duet-upload-s>[slot=fileheader]{margin:16px 0 0 0}/*!@::slotted([slot=filefooter])*/.sc-duet-upload-s>[slot=filefooter]{margin-top:16px}/*!@.duet-upload*/.duet-upload.sc-duet-upload{box-sizing:border-box;padding:0;margin:0;background:transparent;border:0;-moz-appearance:none;-webkit-appearance:none;appearance:none}/*!@.duet-upload-item-size*/.duet-upload-item-size.sc-duet-upload{font-size:0.75rem;font-weight:400}/*!@.duet-upload-filelist*/.duet-upload-filelist.sc-duet-upload{margin-bottom:25px}/*!@.duet-upload-filelist-empty*/.duet-upload-filelist-empty.sc-duet-upload{display:flex;align-items:center;justify-content:center;width:100%;height:75px;margin:0 auto;font-size:1rem;font-weight:400;background-color:#f5f8fa}";
15249
+
15250
+ /**
15251
+ * @slot header - named slot - to place content after description / caption
15252
+ * @slot fileheader - named slot - to place content above "filelist" (only displayed when "filelist" contains items)
15253
+ * @slot filelist - named slot - should always contain a configurable duet-editable-table or a component that exposes the same functionality
15254
+ * @slot filefooter - named slot - to place content below "filelist" (only displayed when "filelist" contains items)
15255
+ */
15256
+ class DuetUpload {
15257
+ constructor(hostRef) {
15258
+ registerInstance(this, hostRef);
15259
+ this.duetChange = createEvent$2(this, "duetChange", 3);
15260
+ this.duetBlur = createEvent$2(this, "duetBlur", 7);
15261
+ this.duetFocus = createEvent$2(this, "duetFocus", 7);
15262
+ this.duetDone = createEvent$2(this, "duetDone", 3);
15263
+ this.duetState = createEvent$2(this, "duetState", 3);
15264
+ this.duetDelete = createEvent$2(this, "duetDelete", 3);
15265
+ this.duetCancel = createEvent$2(this, "duetCancel", 3);
15266
+ this.duetProgress = createEvent$2(this, "duetProgress", 3);
15267
+ this.duetUpload = createEvent$2(this, "duetUpload", 3);
15268
+ /**
15269
+ * Own Properties
15270
+ */
15271
+ this.buttonId = createID("DuetButton");
15272
+ this.labelId = createID("DuetLabel");
15273
+ this.uploadId = createID("DuetUpload");
15274
+ this.editableTableId = createID("DuetEditableTable");
15275
+ this.filesInProgress = new Map();
15276
+ this.fileMaxReached = false;
15277
+ this.bytesMaxReached = false;
15278
+ //region Internally exposed properties
15279
+ /**
15280
+ * Properties
15281
+ */
15282
+ this.DefaultGroups = {
15283
+ inprogress: "inprogress",
15284
+ success: "success",
15285
+ failure: "failure",
15286
+ };
15287
+ /**
15288
+ * State() variables
15289
+ */
15290
+ this.tick = Date.now();
15291
+ /**
15292
+ * If external is set to true, the upload component will not actually upload the files, but only keep states
15293
+ * it will be up to you to handle the upload and return progress information to the upload-component
15294
+ */
15295
+ this.external = false;
15296
+ /**
15297
+ * If set the upload component will not display an upload button, you will have to create on yourself
15298
+ * and call the exposed methods startUpload
15299
+ */
15300
+ this.hideButton = false;
15301
+ /**
15302
+ * Default actions added to all files
15303
+ */
15304
+ this.actions = [
15305
+ {
15306
+ icon: "action-delete",
15307
+ color: "color-danger",
15308
+ color_hover: "category-home",
15309
+ id: "delete",
15310
+ map: ["success", "failure"],
15311
+ label: {
15312
+ fi: "Poista tiedosto",
15313
+ en: "Poista tiedosto",
15314
+ sv: "Ta bort filen",
15315
+ },
15316
+ },
15317
+ {
15318
+ icon: "navigation-close",
15319
+ color: "primary",
15320
+ color_hover: "category-home",
15321
+ id: "cancel",
15322
+ map: ["inprogress"],
15323
+ label: {
15324
+ fi: "Keskeytä lähetys",
15325
+ en: "Cancel the upload",
15326
+ sv: "Stop överföringen",
15327
+ },
15328
+ },
15329
+ ];
15330
+ /**
15331
+ * If enabled the filelist will create links on successfully uploaded items,
15332
+ * this requires the server can respond with link URIs in the correct format
15333
+ */
15334
+ this.showLinks = false;
15335
+ /**
15336
+ * Property to change the aria upload progress text read aloud by screenreaders
15337
+ * @default {
15338
+ fi: "Lisää liite",
15339
+ sv: "Lägg till en bilaga",
15340
+ en: "Choose files",
15341
+ }
15342
+ */
15343
+ this.statusLabelDefaults = {
15344
+ fi: {
15345
+ inProgress: "Lähetetään {filesUploaded} lähetettävästä {filesTotal} tiedostosta",
15346
+ inProgressWithErrors: "Lähetetään {filesInProgress} tiedostoa, lähetetty {filesUploaded} lähetettävästä {filesTotal} tiedostosta, {filesWithErrors} tiedostossa on virheitä",
15347
+ done: "Kaikki {filesTotal} tiedostoa lähetetty onnistuneesti",
15348
+ doneWithErrors: "Lähetys valmis, {filesUploaded} tiedostoa on lähetetty onnistuneesti, {filesWithErrors} tiedostossa oli virheitä",
15349
+ files: "tiedostot",
15350
+ file: "tiedosto",
15351
+ },
15352
+ sv: {
15353
+ inProgress: "Adding {filesUploaded} of {filesTotal}",
15354
+ inProgressWithErrors: "Laddar upp {filesInProgress}, {filesUploaded} uppladdad av {filesTotal}, {filesWithErrors} misslyckades",
15355
+ done: "Alla {filesTotal} har lagts till",
15356
+ doneWithErrors: "Handling slutförd, {filesUploaded} har lagts till, {filesWithErrors} misslyckades",
15357
+ files: "filer",
15358
+ file: "fil",
15359
+ },
15360
+ en: {
15361
+ inProgress: "Adding {filesUploaded} of {filesTotal}",
15362
+ inProgressWithErrors: "Uploading {filesInProgress}, {filesUploaded} uploaded of {filesTotal}, {filesWithErrors} failed",
15363
+ done: "All {filesTotal} added successfully",
15364
+ doneWithErrors: "Action completed, {filesUploaded} has been added successfully, {filesWithErrors} had errors",
15365
+ files: "tiedostoa",
15366
+ file: "tiedosto",
15367
+ },
15368
+ };
15369
+ /**
15370
+ * Strings used for the status aria-label
15371
+ */
15372
+ this.statusMessageLabel = getLocaleString(this.statusLabelDefaults);
15373
+ /**
15374
+ * Property to change descriptionDefaults defaults on the component.
15375
+ * normally you would handle these strings on an application level and override @label when needed
15376
+ * @default {
15377
+ fi: "Lisää liite",
15378
+ sv: "Lägg till en bilaga",
15379
+ en: "Add an attachment",
15380
+ }
15381
+ */
15382
+ this.buttonLabelDefaults = {
15383
+ fi: "Lisää liite",
15384
+ sv: "Lägg till en bilaga",
15385
+ en: "Add an attachment",
15386
+ };
15387
+ /**
15388
+ * Label of button
15389
+ * @default { fi: "Lisää liite", sv: "Lägg till en bilaga", en: "Add an attachment" }
15390
+ */
15391
+ this.buttonLabel = getLocaleString(this.buttonLabelDefaults);
15392
+ /**
15393
+ * accessible Label of button
15394
+ */
15395
+ this.accessibleButtonLabel = undefined;
15396
+ /**
15397
+ * Theme of the input.
15398
+ */
15399
+ this.theme = "";
15400
+ /**
15401
+ * Makes the input component disabled. This prevents users from being able to
15402
+ * interact with the upload component, and conveys its inactive state to assistive technologies.
15403
+ */
15404
+ this.disabled = false;
15405
+ /**
15406
+ * Controls the margin of the component.
15407
+ */
15408
+ this.margin = "auto";
15409
+ /**
15410
+ * Set whether the input is required or not. Please note that this is necessary for
15411
+ * accessible inputs when the user is required to fill them. When using this property
15412
+ * you need to also set “novalidate” attribute to your form element to prevent
15413
+ * browser from displaying its own validation errors.
15414
+ */
15415
+ this.required = false;
15416
+ /**
15417
+ * Visually hides the groups labels in the editable table list used to display the list of files
15418
+ */
15419
+ this.hideGroups = false;
15420
+ /**
15421
+ * Map of string that contain list of uploaded files.
15422
+ */
15423
+ this.files = new Map();
15424
+ /**
15425
+ * Property to read if filelist contains errors or not
15426
+ */
15427
+ this.valid = !this.required;
15428
+ /**
15429
+ * Property to change labelDefaults defaults on the component.
15430
+ * normally you would handle these strings on an application level and override @label when needed
15431
+ * @default { fi: "Lisää liite",sv: "Lägg till en bilaga",en: "Add attachments"}
15432
+ */
15433
+ this.labelDefaults = {
15434
+ fi: "Lisää liite",
15435
+ sv: "Lägg till en bilaga",
15436
+ en: "Add attachments",
15437
+ };
15438
+ /**
15439
+ * Label for the input.
15440
+ * @default { fi: "Lisää liite",sv: "Lägg till en bilaga",en: "Add attachments"}
15441
+ */
15442
+ this.label = getLocaleString(this.labelDefaults);
15443
+ /**
15444
+ * Property to change descriptionDefaults defaults on the component.
15445
+ * normally you would handle these strings on an application level and override @label when needed
15446
+ * @default {
15447
+ fi: "Voit liittää {filetypes}-muotoisia tiedostoja sekä yleisimpiä videotiedostoja. Voit lähettää {maxbytes} verran tiedostoja yhdellä kertaa, ja lisätä enintään {maxfiles} liitettä kerrallaan.",
15448
+ sv: "Du kan bifoga filer i flg. formater {filetypes} samt de vanligaste videofilerna. Du kan ladda upp {maxbytes} filer åt gången och lägga till upp till {maxfiles} bilagor åt gången.",
15449
+ en: "You may attach the following filetypes: {filetypes} - as well as the most common video files. You can upload {maxbytes} of files at a time, and add up to {maxfiles} attachments at a time.",
15450
+ }
15451
+ */
15452
+ this.descriptionDefaults = {
15453
+ fi: "Voit liittää {filetypes}-muotoisia tiedostoja sekä yleisimpiä videotiedostoja. Voit lähettää {maxbytes} verran tiedostoja yhdellä kertaa, ja lisätä enintään {maxfiles} liitettä kerrallaan.",
15454
+ sv: "Du kan bifoga filer i flg. formater {filetypes} samt de vanligaste videofilerna. Du kan ladda upp {maxbytes} filer åt gången och lägga till upp till {maxfiles} bilagor åt gången.",
15455
+ en: "You may attach the following filetypes: {filetypes} - as well as the most common video files. You can upload {maxbytes} of files at a time, and add up to {maxfiles} attachments at a time.",
15456
+ };
15457
+ /**
15458
+ * Description for the upload component.
15459
+ * @default {
15460
+ fi: "Voit liittää {filetypes}-muotoisia tiedostoja sekä yleisimpiä videotiedostoja. Voit lähettää {maxbytes} verran tiedostoja yhdellä kertaa, ja lisätä enintään {maxfiles} liitettä kerrallaan.",
15461
+ sv: "Du kan bifoga filer i flg. formater {filetypes} samt de vanligaste videofilerna. Du kan ladda upp {maxbytes} filer åt gången och lägga till upp till {maxfiles} bilagor åt gången.",
15462
+ en: "You may attach the following filetypes: {filetypes} - as well as the most common video files. You can upload {maxbytes} of files at a time, and add up to {maxfiles} attachments at a time.",
15463
+ }
15464
+ */
15465
+ this.description = getLocaleString(this.descriptionDefaults);
15466
+ /**
15467
+ * Defaults for the filelist's empty state.
15468
+ * @default {
15469
+ fi: "Ei vielä lisättyjä tiedostoja.",
15470
+ sv: "Inga filer har lagts till ännu.",
15471
+ en: "No files added yet.",
15472
+ }
15473
+ */
15474
+ this.fileListEmptyDefaults = {
15475
+ fi: "Ei vielä lisättyjä tiedostoja.",
15476
+ sv: "Inga filer har lagts till ännu.",
15477
+ en: "No files added yet.",
15478
+ };
15479
+ /**
15480
+ * Label for the filelist's empty state.
15481
+ * @default { fi: "Ei vielä lisättyjä tiedostoja.",sv: "Inga filer har lagts till ännu.",en: "No files added yet."}
15482
+ */
15483
+ this.fileListEmpty = getLocaleString(this.fileListEmptyDefaults);
15484
+ /**
15485
+ * Display the input in error state along with an error message.
15486
+ */
15487
+ this.error = "";
15488
+ /**
15489
+ * Use maxBytes to specify the maximum size in Bytes of a file that can be uploaded.
15490
+ */
15491
+ this.maxBytes = 200000000;
15492
+ /**
15493
+ * Use maxBytesTotal to specify the maximum size in Bytes of All files combined that can be uploaded.
15494
+ */
15495
+ this.maxBytesTotal = undefined;
15496
+ /**
15497
+ * Use maxFiles to specify the maximum amount of files that can be uploaded
15498
+ */
15499
+ this.maxFiles = 99;
15500
+ /**
15501
+ * A string of commaseperated file type values that are allowed
15502
+ * @example: .pdf,.doc,.docx
15503
+ */
15504
+ this.allowedExtensions = "all";
15505
+ /**
15506
+ * A string of commaseperated mime type values that are allowed
15507
+ * @example: image/*,application/msword,
15508
+ */
15509
+ this.allowedMimetypes = "*";
15510
+ /**
15511
+ * Use multiple to allow the user to select multiple files when uploading
15512
+ */
15513
+ this.multiple = true;
15514
+ /**
15515
+ * Use limitSelection to enforce the value in allowedExtension & allowedMimetypes when selecting files,
15516
+ * by default this is off, setting this to true will limit the users choices to what has been explicitly set
15517
+ */
15518
+ this.limitSelection = false;
15519
+ //region Private functions
15520
+ /**
15521
+ * Private functions
15522
+ */
15523
+ this.listenForActionEvents = () => {
15524
+ this.element.addEventListener("duetEditableItemAction", (e) => {
15525
+ const detail = e.detail;
15526
+ const { action, keyName, originalEvent } = detail;
15527
+ switch (action) {
15528
+ case "delete":
15529
+ this.onDelete(keyName, originalEvent);
15530
+ break;
15531
+ case "cancel":
15532
+ this.onCancel(keyName, originalEvent);
15533
+ break;
15534
+ // code block
15535
+ }
15536
+ });
15537
+ };
15538
+ this.verifyValidity = () => {
15539
+ const { invalid, valid } = this.getFilesAsArray();
15540
+ const oldValid = this.valid;
15541
+ this.valid = invalid.length === 0 && valid.length !== 0;
15542
+ if (this.valid !== oldValid) {
15543
+ this.duetState.emit({
15544
+ originalEvent: undefined,
15545
+ data: { valid: this.valid, from: "componentWillRender" },
15546
+ component: "duet-upload",
15547
+ });
15548
+ }
15549
+ };
15550
+ this.getGroupFromItemData = (item) => {
15551
+ if (item.valid && item.progress === 100) {
15552
+ // if the item has a group, move the file to that group instead
15553
+ // of into the standard success group
15554
+ if (item.group) {
15555
+ return item.group;
15556
+ }
15557
+ return this.DefaultGroups.success;
15558
+ }
15559
+ else if (item.progress > 0 && item.progress !== 100) {
15560
+ return this.DefaultGroups.inprogress;
15561
+ }
15562
+ else if (!item.valid) {
15563
+ return this.DefaultGroups.failure;
15564
+ }
15565
+ else if (item.group) {
15566
+ return item.group;
15567
+ }
15568
+ else {
15569
+ return "none";
15570
+ }
15571
+ };
15572
+ this.getItemHTMLFromItemData = (data, group) => {
15573
+ if (group === this.DefaultGroups.success) {
15574
+ return hAsync(SuccessItem, { data: data, showLinks: this.showLinks });
15575
+ }
15576
+ else if (group === this.DefaultGroups.inprogress) {
15577
+ return hAsync(ProgressItem, { progress: data.progress, name: data.item.name });
15578
+ }
15579
+ else if (group === this.DefaultGroups.failure) {
15580
+ return hAsync(ErrorItem, { data: data });
15581
+ }
15582
+ else if (data.group) {
15583
+ return data.html;
15584
+ }
15585
+ else {
15586
+ return "none";
15587
+ }
15588
+ };
15589
+ this.convertToDuetEditableTableItems = () => {
15590
+ // we're always recreating the map - in order to force an update down stream.
15591
+ const itemData = new Map();
15592
+ //walk the files Map and convert to DuetEditableTableItemData
15593
+ this.files.forEach((data, key, _originalMap) => {
15594
+ const group = this.getGroupFromItemData(data);
15595
+ const item = this.getItemHTMLFromItemData(data, group);
15596
+ itemData.set(key, {
15597
+ uid: data.uid,
15598
+ item,
15599
+ group,
15600
+ });
15601
+ });
15602
+ return itemData;
15603
+ };
15604
+ this.kick = debounce(() => {
15605
+ this.tick = Date.now();
15606
+ }, 30); // will trigger re-render
15607
+ this.genHashName = () => Date.now().toString(36) + Math.random();
15608
+ this.updateValueInMap = (item, key, value, kick = true) => {
15609
+ const fileItem = this.files.get(item);
15610
+ fileItem[key] = value;
15611
+ this.files.set(item, fileItem);
15612
+ if (kick) {
15613
+ this.kick();
15614
+ }
15615
+ };
15616
+ this.updateProgress = (ev, name) => {
15617
+ console.log(this.filesInProgress.size);
15618
+ const updateProgressHelper = percentComplete => {
15619
+ this.updateValueInMap(name, "progress", percentComplete);
15620
+ this.onProgress(name, percentComplete, ev);
15621
+ };
15622
+ if (ev.lengthComputable) {
15623
+ const percentComplete = (ev.loaded / ev.total) * 100;
15624
+ updateProgressHelper(percentComplete);
15625
+ }
15626
+ else {
15627
+ console.log("cant read progress");
15628
+ }
15629
+ };
15630
+ this.trackProgress = (name, remove = false) => {
15631
+ if (remove) {
15632
+ this.filesInProgress.delete(name);
15633
+ }
15634
+ else {
15635
+ this.filesInProgress.set(name, "inprogress");
15636
+ }
15637
+ if (this.filesInProgress.size === 0) {
15638
+ this.onDone();
15639
+ }
15640
+ };
15641
+ this.getFilesAsArray = () => {
15642
+ const filesInQueue = [];
15643
+ const filesInError = [];
15644
+ this.files.forEach(value => {
15645
+ if (value.valid && !value.deleted) {
15646
+ filesInQueue.push(value);
15647
+ }
15648
+ else if (!value.valid && !value.deleted) {
15649
+ filesInError.push(value);
15650
+ }
15651
+ });
15652
+ return { valid: filesInQueue, invalid: filesInError };
15653
+ };
15654
+ this.resetFormFields = () => {
15655
+ /**
15656
+ * You cannot modify a FileList, nor remove single items from it
15657
+ * This completely removes all items in the FileList
15658
+ * We reset the form fields to always be able to re-upload files
15659
+ * and because we handle all uploads and states internally in the component (not relying on native form elements)
15660
+ */
15661
+ this.nativeInput.value = "";
15662
+ };
15663
+ this.startUpload = async (ev, metaData = undefined) => {
15664
+ await this.setFocus();
15665
+ this.metaData = metaData;
15666
+ this.nativeInput.click();
15667
+ this.onUpload(ev, metaData);
15668
+ ev.stopPropagation();
15669
+ ev.preventDefault();
15670
+ return;
15671
+ };
15672
+ //endregion
15673
+ //region Eventlisteners for the XHR requests
15674
+ /**
15675
+ * Eventlisteners for the XHR requests
15676
+ */
15677
+ this.transferComplete = name => {
15678
+ this.updateValueInMap(name, "progress", 100, false);
15679
+ this.trackProgress(name, true);
15680
+ };
15681
+ this.transferDone = (xhr, name, status) => {
15682
+ this.updateValueInMap(name, "status", status, false);
15683
+ this.updateValueInMap(name, "uploaded", true, false);
15684
+ try {
15685
+ const response = JSON.parse(xhr.response);
15686
+ this.updateValueInMap(name, "url", response.url);
15687
+ }
15688
+ catch (e) {
15689
+ this.updateValueInMap(name, "url", null);
15690
+ console.error("Server did not respond with expected response {url: string}");
15691
+ }
15692
+ return;
15693
+ };
15694
+ this.transferDoneWithFailure = (xhr, name, status) => {
15695
+ try {
15696
+ const { error } = JSON.parse(xhr.response);
15697
+ this.updateValueInMap(name, "error", { message: error.message, type: error.type }, false);
15698
+ }
15699
+ catch (e) {
15700
+ console.error("Server did not respond with expected response error:{message: string, type: int}");
15701
+ this.updateValueInMap(name, "error", { type: status }, false);
15702
+ }
15703
+ this.updateValueInMap(name, "valid", false, true);
15704
+ };
15705
+ this.transferFailed = name => {
15706
+ this.updateValueInMap(name, "error", getError("duet-upload-001"));
15707
+ };
15708
+ this.transferCanceled = name => {
15709
+ this.files.delete(name);
15710
+ this.validateTotals(name);
15711
+ this.kick();
15712
+ };
15713
+ this.validateTotals = (name) => {
15714
+ const isTotalSizeOverMaxSize = validateTotalSizeIsAboveMax(this.files, this.maxBytesTotal);
15715
+ const isTotalFileAmountAboveMax = validateTotalAmountIsAboveMax(this.files, this.maxFiles);
15716
+ if (isTotalSizeOverMaxSize && name) {
15717
+ this.updateValueInMap(name, "error", getError("duet-upload-202"), false);
15718
+ }
15719
+ if (isTotalFileAmountAboveMax && name) {
15720
+ this.updateValueInMap(name, "error", getError("duet-upload-301"), false);
15721
+ }
15722
+ this.bytesMaxReached = isTotalSizeOverMaxSize;
15723
+ this.fileMaxReached = isTotalFileAmountAboveMax;
15724
+ return {
15725
+ bytesMaxReached: isTotalSizeOverMaxSize,
15726
+ fileMaxReached: isTotalFileAmountAboveMax,
15727
+ };
15728
+ };
15729
+ this.onDelete = (key, ev) => {
15730
+ const deletedItem = this.files.get(key);
15731
+ this.files.delete(key);
15732
+ this.validateTotals();
15733
+ this.kick();
15734
+ this.duetDelete.emit({
15735
+ originalEvent: ev,
15736
+ data: { deletion: deletedItem },
15737
+ component: "duet-upload",
15738
+ });
15739
+ if (!this.external) {
15740
+ this.makeXHRDeleteRequest(deletedItem);
15741
+ }
15742
+ this.resetFormFields();
15743
+ };
15744
+ this.onCancel = (key, ev) => {
15745
+ const cancelledItem = this.files.get(key);
15746
+ this.files.delete(key);
15747
+ if (!this.external) {
15748
+ const { xhr } = cancelledItem;
15749
+ xhr.abort();
15750
+ }
15751
+ else {
15752
+ this.kick();
15753
+ }
15754
+ this.resetFormFields();
15755
+ this.duetCancel.emit({
15756
+ originalEvent: ev,
15757
+ data: { cancelled: cancelledItem },
15758
+ component: "duet-upload",
15759
+ });
15760
+ };
15761
+ this.onUpload = (ev, metaData) => {
15762
+ this.duetUpload.emit({
15763
+ originalEvent: ev,
15764
+ metaData,
15765
+ component: "duet-upload",
15766
+ });
15767
+ };
15768
+ this.onBlur = (ev) => {
15769
+ this.duetBlur.emit({
15770
+ originalEvent: ev,
15771
+ component: "duet-upload",
15772
+ });
15773
+ };
15774
+ this.onProgress = (key, percentComplete, ev) => {
15775
+ this.duetChange.emit({
15776
+ originalEvent: ev,
15777
+ data: {
15778
+ key,
15779
+ percentComplete,
15780
+ },
15781
+ component: "duet-upload",
15782
+ });
15783
+ };
15784
+ this.onFocus = (ev) => {
15785
+ this.duetFocus.emit({
15786
+ originalEvent: ev,
15787
+ component: "duet-upload",
15788
+ });
15789
+ };
15790
+ this.onDone = () => {
15791
+ this.duetDone.emit({
15792
+ component: "duet-upload",
15793
+ data: { files: this.files },
15794
+ });
15795
+ };
15796
+ }
15797
+ watchValidHandler(newValue, oldValue) {
15798
+ if (newValue !== oldValue) {
15799
+ this.kick();
15800
+ }
15801
+ }
15802
+ //endregion
15803
+ /**
15804
+ * Component lifecycle events.
15805
+ */
15806
+ componentWillLoad() {
15807
+ inheritGlobalTheme(this);
15808
+ this.listenForActionEvents();
15809
+ }
15810
+ componentWillRender() {
15811
+ // listen to the events from the component
15812
+ this.verifyValidity();
15813
+ }
15814
+ //endregion
15815
+ //region XHR requests
15816
+ /**
15817
+ * XHR request utilities
15818
+ */
15819
+ makeXHRPostRequest(data) {
15820
+ const xhr = new XMLHttpRequest();
15821
+ const name = data.get("name");
15822
+ xhr.upload.addEventListener("progress", ev => {
15823
+ this.updateProgress(ev, name);
15824
+ });
15825
+ xhr.upload.addEventListener("load", () => {
15826
+ this.transferComplete(name);
15827
+ });
15828
+ xhr.upload.addEventListener("error", () => {
15829
+ this.transferFailed(name);
15830
+ });
15831
+ xhr.upload.addEventListener("abort", () => {
15832
+ this.transferCanceled(name);
15833
+ });
15834
+ return makeXhrRequest({
15835
+ payload: { data, name },
15836
+ options: { type: "POST", uri: this.uri, xhr, argument: null, headers: null },
15837
+ onFailure: this.transferDoneWithFailure,
15838
+ onSuccess: this.transferDone,
15839
+ onProgress: this.trackProgress,
15840
+ });
15841
+ }
15842
+ makeXHRDeleteRequest(data) {
15843
+ const { uid, item } = data;
15844
+ const xhr = new XMLHttpRequest();
15845
+ // don't present server issues to user on deletes, just remove them from the visible list
15846
+ return makeXhrRequest({
15847
+ payload: { data: null, name },
15848
+ options: {
15849
+ type: "DELETE",
15850
+ xhr,
15851
+ uri: this.uri,
15852
+ arguments: `?key=${uid}&name=${item.name}`,
15853
+ headers: {
15854
+ "x-fileuid": uid,
15855
+ "x-filename": item.name,
15856
+ },
15857
+ },
15858
+ onFailure: this.transferDoneWithFailure,
15859
+ onSuccess: this.transferDone,
15860
+ onProgress: this.trackProgress,
15861
+ });
15862
+ }
15863
+ //endregion
15864
+ //region EventHandlers
15865
+ /**
15866
+ * Component event handling.
15867
+ */
15868
+ async onChange(ev) {
15869
+ var _a;
15870
+ const selectedFiles = Array.from((_a = this.nativeInput) === null || _a === void 0 ? void 0 : _a.files);
15871
+ // FileList is a nice array like structure but
15872
+ // to ensure uniqueness of files we use a mapping structure and
15873
+ // key to the name (makes it easier to delete as well)
15874
+ if (selectedFiles) {
15875
+ for (const item of selectedFiles) {
15876
+ const { valid, errorMessage, errorType, errorSystem } = validateFile(item, {
15877
+ maxBytes: this.maxBytes,
15878
+ allowedExtensions: this.allowedExtensions,
15879
+ allowedMimetypes: this.allowedMimetypes,
15880
+ });
15881
+ const uid = this.genHashName();
15882
+ const fileListItem = {
15883
+ uid,
15884
+ item: item,
15885
+ size: item.size,
15886
+ meta: this.metaData,
15887
+ uploaded: false,
15888
+ valid,
15889
+ error: {
15890
+ type: valid ? undefined : errorType,
15891
+ message: valid ? undefined : errorMessage,
15892
+ system_message: valid ? undefined : errorSystem,
15893
+ },
15894
+ progress: 0,
15895
+ deleted: false,
15896
+ xhr: false,
15897
+ url: false,
15898
+ };
15899
+ this.files.set(item.name, fileListItem);
15900
+ // validate that we haven't hit any maxfiles or maxbytes limits before we upload
15901
+ const { bytesMaxReached, fileMaxReached } = this.validateTotals(item.name);
15902
+ if (bytesMaxReached) {
15903
+ // in case one of the global maxes have been reached, invalidate the file
15904
+ this.updateValueInMap(item.name, "valid", false, false);
15905
+ }
15906
+ else if (fileMaxReached) {
15907
+ // in case one of the global maxes have been reached, invalidate the file
15908
+ this.updateValueInMap(item.name, "valid", false, false);
15909
+ }
15910
+ else if (valid && !this.external) {
15911
+ // if all is well AND external file upload handling has not been set, start upload
15912
+ const data = new FormData();
15913
+ data.append("file", item);
15914
+ data.append("uid", uid);
15915
+ data.append("name", item.name);
15916
+ data.append("metadata", JSON.stringify({ uid, url: this.uri, size: item.size, meta: fileListItem.meta }));
15917
+ try {
15918
+ fileListItem.xhr = await this.makeXHRPostRequest(data);
15919
+ }
15920
+ catch (e) {
15921
+ // in case one of the global maxes have been reached, invalidate the file
15922
+ this.updateValueInMap(item.name, "valid", false, false);
15923
+ }
15924
+ }
15925
+ // kick the stat to force update
15926
+ this.kick();
15927
+ }
15928
+ }
15929
+ // reset the form, so that a user may upload a file again (with the same name)
15930
+ this.resetFormFields();
15931
+ // reset the internal metaData state
15932
+ this.metaData = undefined;
15933
+ this.duetChange.emit({
15934
+ originalEvent: ev,
15935
+ data: { files: this.files },
15936
+ component: "duet-upload",
15937
+ });
15938
+ }
15939
+ //endregion
15940
+ /**
15941
+ * Sets focus on the specified `duet-input`. Use this method instead of the global
15942
+ * `input.focus()`.
15943
+ */
15944
+ async setFocus(options) {
15945
+ if (this.nativeInput) {
15946
+ this.nativeInput.focus(options);
15947
+ }
15948
+ return;
15949
+ }
15950
+ /**
15951
+ * Method for invoking the upload sequence
15952
+ */
15953
+ async upload(metaData = undefined) {
15954
+ await this.setFocus();
15955
+ this.metaData = metaData;
15956
+ this.nativeInput.click();
15957
+ return;
15958
+ }
15959
+ /**
15960
+ * Get list of files, divided in errors and valid sections
15961
+ */
15962
+ async getFiles() {
15963
+ if (!this.files || this.files.size === 0) {
15964
+ return false;
15965
+ }
15966
+ return this.getFilesAsArray();
15967
+ }
15968
+ /**
15969
+ * Convenience method for updating a of an item in the files attribute
15970
+ */
15971
+ async updateValue(item, key, value) {
15972
+ this.updateValueInMap(item, key, value);
15973
+ }
15974
+ /**
15975
+ * render() function
15976
+ * Always the last one in the class.
15977
+ */
15978
+ render() {
15979
+ const identifier = this.identifier || this.uploadId;
15980
+ let caption = this.description.replace(/{maxfiles}/g, this.maxFiles.toString());
15981
+ caption = caption.replace(/{maxbytes}/g, `${Math.floor(this.maxBytes / 1024 / 1024)} MB`);
15982
+ caption = caption.replace(/{filetypes}/g, this.allowedExtensions.split(",").join(", "));
15983
+ return (hAsync(Host, { class: { "duet-m-0": this.margin === "none" } }, hAsync("duet-fieldset", { label: this.label, caption: caption }, hAsync("slot", { name: "header" }), !this.files.size && (hAsync("duet-label", { theme: this.theme === "turva" ? "turva" : "default", size: "small", class: {
15984
+ "duet-upload-filelist-empty": !this.files.size,
15985
+ "duet-upload-filelist": true,
15986
+ "duet-upload-filelist-filled": this.files.size,
15987
+ }, id: this.labelId, for: identifier }, this.fileListEmpty)), !!this.files.size && hAsync("slot", { name: "fileheader" }), !!this.files.size && (hAsync("duet-upload-aria-status", { invalid: this.getFilesAsArray().invalid.length, valid: this.getFilesAsArray().valid.length, inprogress: this.filesInProgress.size, total: this.files.size, statusMessageLabel: this.statusMessageLabel })), !!this.files.size && (hAsync("duet-editable-table", { "aria-live": "polite", "aria-relevant": "removals", accessibleRole: "log", id: this.editableTableId, groups: this.groups, actions: this.actions, hideGroups: this.hideGroups, items: this.convertToDuetEditableTableItems() })), !!this.files.size && hAsync("slot", { name: "filefooter" }), hAsync("duet-spacer", { size: "large" }), !this.hideButton && (hAsync("duet-button", { id: this.buttonId, onClick: this.startUpload, "accessible-controls": identifier, disabled: this.fileMaxReached, "accessible-label": this.accessibleButtonLabel, "accessible-owns": identifier, size: "small", variation: "secondary", fixed: true, icon: "action-add-circle" }, this.buttonLabel)), hAsync("duet-spacer", { size: "medium" }), (this.fileMaxReached || this.bytesMaxReached) && (hAsync("duet-alert", null, this.fileMaxReached && getI18nError("duet-upload-301"), this.bytesMaxReached && getI18nError("duet-upload-202"))), hAsync("duet-spacer", { size: "medium" }), hAsync("duet-visually-hidden", null, hAsync("input", { ref: input => {
15988
+ this.nativeInput = input;
15989
+ }, accept: !this.limitSelection ? undefined : `${this.allowedMimetypes},${this.allowedExtensions}`, onBlur: this.onBlur, onFocus: this.onFocus, onChange: e => this.onChange(e), type: "file", class: {
15990
+ "duet-upload": true,
15991
+ }, disabled: this.disabled, "aria-hidden": "true", required: this.required, name: this.name, id: this.identifier, multiple: this.multiple, capture: "user" })))));
15992
+ }
15993
+ get element() { return getElement(this); }
15994
+ static get watchers() { return {
15995
+ "valid": ["watchValidHandler"]
15996
+ }; }
15997
+ static get style() { return duetUploadCss; }
15998
+ static get cmpMeta() { return {
15999
+ "$flags$": 9,
16000
+ "$tagName$": "duet-upload",
16001
+ "$members$": {
16002
+ "accessibleActiveDescendant": [1, "accessible-active-descendant"],
16003
+ "accessibleDescribedBy": [1, "accessible-described-by"],
16004
+ "accessibleControls": [1, "accessible-controls"],
16005
+ "accessibleOwns": [1, "accessible-owns"],
16006
+ "external": [4],
16007
+ "hideButton": [4, "hide-upload-button"],
16008
+ "actions": [1],
16009
+ "uri": [1],
16010
+ "showLinks": [4, "show-links"],
16011
+ "caption": [1],
16012
+ "statusLabelDefaults": [1, "status-label-default"],
16013
+ "statusMessageLabel": [16],
16014
+ "buttonLabelDefaults": [1, "button-label-default"],
16015
+ "buttonLabel": [1, "button-label"],
16016
+ "accessibleButtonLabel": [1, "accessible-button-label"],
16017
+ "theme": [1025],
16018
+ "disabled": [516],
16019
+ "identifier": [1],
16020
+ "margin": [1],
16021
+ "required": [4],
16022
+ "groups": [1],
16023
+ "hideGroups": [4, "hide-table-labels"],
16024
+ "files": [1040],
16025
+ "valid": [1540],
16026
+ "labelDefaults": [1, "label-default"],
16027
+ "label": [1],
16028
+ "descriptionDefaults": [1, "description-default"],
16029
+ "description": [1],
16030
+ "fileListEmptyDefaults": [1, "list-empty-default"],
16031
+ "fileListEmpty": [1, "file-list-empty"],
16032
+ "error": [1],
16033
+ "name": [1],
16034
+ "maxBytes": [2, "max-bytes"],
16035
+ "maxBytesTotal": [2, "max-bytes-total"],
16036
+ "maxFiles": [2, "max-files"],
16037
+ "allowedExtensions": [1, "allowed-extensions"],
16038
+ "allowedMimetypes": [1, "allowed-mimetypes"],
16039
+ "multiple": [4],
16040
+ "limitSelection": [4, "limit-selection"],
16041
+ "value": [1025],
16042
+ "tick": [32],
16043
+ "setFocus": [64],
16044
+ "upload": [64],
16045
+ "getFiles": [64],
16046
+ "updateValue": [64]
16047
+ },
16048
+ "$listeners$": undefined,
16049
+ "$lazyBundleId$": "-",
16050
+ "$attrsToReflect$": [["disabled", "disabled"], ["valid", "valid"]]
16051
+ }; }
16052
+ }
16053
+
16054
+ class DuetUploadAriaStatus {
16055
+ constructor(hostRef) {
16056
+ registerInstance(this, hostRef);
16057
+ /**
16058
+ * State() variables
16059
+ */
16060
+ this.statusMessage = null;
16061
+ /**
16062
+ * State() variables
16063
+ */
16064
+ this.statusMessageLabel = null;
16065
+ /**
16066
+ * Adds accessible label that is read aloud
16067
+ */
16068
+ this.accessibleAriaLive = "polite";
16069
+ /**
16070
+ * valid file amount
16071
+ */
16072
+ this.valid = undefined;
16073
+ /**
16074
+ * total files
16075
+ */
16076
+ this.total = undefined;
16077
+ /**
16078
+ * invalid file amount
16079
+ */
16080
+ this.invalid = undefined;
16081
+ /**
16082
+ * valid file amount
16083
+ */
16084
+ this.inprogress = undefined;
16085
+ /**
16086
+ * Component lifecycle events.
16087
+ */
16088
+ this.replacePlaceHolders = (statusString) => {
16089
+ const addFiles = (amount) => {
16090
+ return amount > 1 ? `${amount} ${this.statusMessageLabel.files}` : `${amount} ${this.statusMessageLabel.file}`;
16091
+ };
16092
+ return statusString
16093
+ .replace("{filesUploaded}", addFiles(this.valid))
16094
+ .replace("{filesInProgress}", addFiles(this.inprogress))
16095
+ .replace("{filesTotal}", addFiles(this.total))
16096
+ .replace("{filesWithErrors}", addFiles(this.invalid));
16097
+ };
16098
+ this.getStatusMessage = () => {
16099
+ const { done, inProgress, doneWithErrors, inProgressWithErrors } = this.statusMessageLabel;
16100
+ const hasErrors = this.invalid > 0;
16101
+ const isInProgress = this.inprogress > 0;
16102
+ const isInProgressWithErrors = this.inprogress > 0 && hasErrors;
16103
+ const isDone = this.valid === this.total && !isInProgress && !hasErrors;
16104
+ const isDoneWithErrors = this.valid + this.invalid === this.total && !isInProgress;
16105
+ if (isDone) {
16106
+ this.statusMessage = this.replacePlaceHolders(done);
16107
+ return;
16108
+ }
16109
+ else if (isInProgressWithErrors) {
16110
+ this.statusMessage = this.replacePlaceHolders(inProgressWithErrors);
16111
+ return;
16112
+ }
16113
+ else if (isInProgress) {
16114
+ this.statusMessage = this.replacePlaceHolders(inProgress);
16115
+ return;
16116
+ }
16117
+ else if (isDoneWithErrors) {
16118
+ this.statusMessage = this.replacePlaceHolders(doneWithErrors);
16119
+ return;
16120
+ }
16121
+ return;
16122
+ };
16123
+ }
16124
+ watchHandler(newValue, oldValue) {
16125
+ if (newValue !== oldValue) {
16126
+ this.getStatusMessage();
16127
+ }
16128
+ }
16129
+ /**
16130
+ * render() function
16131
+ * Always the last one in the class.
16132
+ */
16133
+ render() {
16134
+ return (hAsync(Host, { role: "status", "aria-live": "assertive", "aria-atomic": "true", "aria-relevant": "all" }, hAsync("duet-visually-hidden", null, this.statusMessage)));
16135
+ }
16136
+ static get watchers() { return {
16137
+ "valid": ["watchHandler"],
16138
+ "invalid": ["watchHandler"],
16139
+ "inprogress": ["watchHandler"],
16140
+ "total": ["watchHandler"]
16141
+ }; }
16142
+ static get cmpMeta() { return {
16143
+ "$flags$": 9,
16144
+ "$tagName$": "duet-upload-aria-status",
16145
+ "$members$": {
16146
+ "statusMessageLabel": [16],
16147
+ "accessibleAriaLive": [1, "accessible-aria-live"],
16148
+ "valid": [2],
16149
+ "total": [2],
16150
+ "invalid": [2],
16151
+ "inprogress": [2],
16152
+ "statusMessage": [32]
16153
+ },
16154
+ "$listeners$": undefined,
16155
+ "$lazyBundleId$": "-",
16156
+ "$attrsToReflect$": []
16157
+ }; }
16158
+ }
16159
+
14320
16160
  const duetVisuallyHiddenCss = "/*!@:host*/.sc-duet-visually-hidden-h{box-sizing:border-box;padding:0;margin:0;background:transparent;border:0;-moz-appearance:none;-webkit-appearance:none;appearance:none;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}";
14321
16161
 
14322
16162
  class DuetVisuallyHidden {
@@ -14354,6 +16194,9 @@ registerComponents([
14354
16194
  DuetCookieConsent,
14355
16195
  DuetDatePicker,
14356
16196
  DuetDivider,
16197
+ DuetEditableTable,
16198
+ DuetEditableTableButton,
16199
+ DuetEditableTableItem,
14357
16200
  DuetEmptyState,
14358
16201
  DuetFieldset,
14359
16202
  DuetFooter,
@@ -14375,6 +16218,7 @@ registerComponents([
14375
16218
  DuetNotificationDrawer,
14376
16219
  DuetNumberInput,
14377
16220
  DuetParagraph,
16221
+ DuetProgress,
14378
16222
  DuetRadio,
14379
16223
  DuetRadioGroup,
14380
16224
  DuetRangeSlider,
@@ -14390,6 +16234,8 @@ registerComponents([
14390
16234
  DuetToggle,
14391
16235
  DuetTooltip,
14392
16236
  DuetTray,
16237
+ DuetUpload,
16238
+ DuetUploadAriaStatus,
14393
16239
  DuetVisuallyHidden,
14394
16240
  ]);
14395
16241