@duetds/components 4.30.1 → 4.31.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 (312) hide show
  1. package/hydrate/index.js +230 -1038
  2. package/lib/cjs/duet-alert.cjs.entry.js +4 -2
  3. package/lib/cjs/duet-badge.cjs.entry.js +2 -2
  4. package/lib/cjs/duet-button_2.cjs.entry.js +4 -3
  5. package/lib/cjs/duet-caption_4.cjs.entry.js +7 -8
  6. package/lib/cjs/duet-card.cjs.entry.js +4 -4
  7. package/lib/cjs/duet-checkbox.cjs.entry.js +1 -1
  8. package/lib/cjs/duet-choice_2.cjs.entry.js +4 -3
  9. package/lib/cjs/duet-collapsible.cjs.entry.js +2 -2
  10. package/lib/cjs/duet-cookie-consent.cjs.entry.js +1 -1
  11. package/lib/cjs/duet-date-picker.cjs.entry.js +22 -12
  12. package/lib/cjs/duet-divider_2.cjs.entry.js +1 -1
  13. package/lib/cjs/duet-empty-state.cjs.entry.js +1 -1
  14. package/lib/cjs/duet-fieldset.cjs.entry.js +1 -1
  15. package/lib/cjs/duet-footer.cjs.entry.js +4 -4
  16. package/lib/cjs/duet-grid_2.cjs.entry.js +1 -1
  17. package/lib/cjs/duet-header_2.cjs.entry.js +25 -9
  18. package/lib/cjs/duet-hero.cjs.entry.js +6 -6
  19. package/lib/cjs/duet-icon.cjs.entry.js +3 -3
  20. package/lib/cjs/duet-input_2.cjs.entry.js +2 -2
  21. package/lib/cjs/duet-layout.cjs.entry.js +1 -1
  22. package/lib/cjs/duet-list_2.cjs.entry.js +1 -1
  23. package/lib/cjs/duet-modal.cjs.entry.js +8 -7
  24. package/lib/cjs/duet-notification_2.cjs.entry.js +6 -5
  25. package/lib/cjs/duet-number-input.cjs.entry.js +36 -15
  26. package/lib/cjs/duet-radio_2.cjs.entry.js +1 -1
  27. package/lib/cjs/duet-range-slider.cjs.entry.js +1 -1
  28. package/lib/cjs/duet-select.cjs.entry.js +2 -2
  29. package/lib/cjs/duet-step_2.cjs.entry.js +1 -1
  30. package/lib/cjs/duet-tab_2.cjs.entry.js +11 -5
  31. package/lib/cjs/duet-table.cjs.entry.js +1 -1
  32. package/lib/cjs/duet-textarea.cjs.entry.js +1 -1
  33. package/lib/cjs/duet-toggle.cjs.entry.js +1 -1
  34. package/lib/cjs/duet-tooltip.cjs.entry.js +21 -10
  35. package/lib/cjs/duet-tray.cjs.entry.js +20 -9
  36. package/lib/cjs/duet-visually-hidden.cjs.entry.js +1 -1
  37. package/lib/cjs/duet.cjs.js +2 -2
  38. package/lib/cjs/{focus-utils-7605778f.js → focus-utils-bd331feb.js} +1 -1
  39. package/lib/cjs/{index-0c949193.js → index-113c2add.js} +0 -3
  40. package/lib/cjs/{language-utils-70d6a9a4.js → language-utils-48b8860b.js} +23 -8
  41. package/lib/cjs/loader.cjs.js +2 -2
  42. package/lib/cjs/{string-utils-a6de43d8.js → string-utils-267e3dbb.js} +7 -0
  43. package/lib/collection/collection-manifest.json +0 -6
  44. package/lib/collection/components/duet-alert/duet-alert.js +10 -4
  45. package/lib/collection/components/duet-badge/duet-badge.css +1 -0
  46. package/lib/collection/components/duet-button/duet-button.js +7 -5
  47. package/lib/collection/components/duet-card/duet-card.css +10 -7
  48. package/lib/collection/components/duet-card/duet-card.js +3 -5
  49. package/lib/collection/components/duet-choice/duet-choice.js +5 -3
  50. package/lib/collection/components/duet-choice-group/duet-choice-group.css +1 -0
  51. package/lib/collection/components/duet-date-picker/duet-date-picker.css +1 -1
  52. package/lib/collection/components/duet-date-picker/duet-date-picker.js +73 -38
  53. package/lib/collection/components/duet-footer/duet-footer.js +7 -5
  54. package/lib/collection/components/duet-header/duet-header.js +46 -21
  55. package/lib/collection/components/duet-heading/duet-heading.css +1 -0
  56. package/lib/collection/components/duet-hero/duet-hero.js +14 -9
  57. package/lib/collection/components/duet-icon/icon-utils.js +1 -1
  58. package/lib/collection/components/duet-label/duet-label.css +2 -0
  59. package/lib/collection/components/duet-link/duet-link.js +10 -11
  60. package/lib/collection/components/duet-modal/duet-modal.js +16 -11
  61. package/lib/collection/components/duet-notification-drawer/duet-notification-drawer.js +14 -9
  62. package/lib/collection/components/duet-number-input/duet-number-input.js +141 -17
  63. package/lib/collection/components/duet-tab-group/duet-tab-group.js +35 -4
  64. package/lib/collection/components/duet-tooltip/duet-tooltip.js +72 -10
  65. package/lib/collection/components/duet-tray/duet-tray.js +71 -9
  66. package/lib/collection/utils/fixture-utils.js +7 -5
  67. package/lib/collection/utils/language-utils.js +22 -8
  68. package/lib/collection/utils/string-utils.js +6 -0
  69. package/lib/custom-elements-bundle/index.d.ts +0 -6
  70. package/lib/custom-elements-bundle/index.js +224 -995
  71. package/lib/duet/duet.esm.js +1 -1
  72. package/lib/duet/duet.js +1 -1
  73. package/lib/duet/p-0058512b.js +4 -0
  74. package/lib/duet/p-0224db45.entry.js +4 -0
  75. package/lib/duet/{p-345ea4f2.system.entry.js → p-02ad46a0.system.entry.js} +1 -1
  76. package/lib/duet/{p-62806bb6.system.entry.js → p-07263910.system.entry.js} +1 -1
  77. package/lib/duet/{p-f82709ba.entry.js → p-1bfbc988.entry.js} +1 -1
  78. package/lib/duet/p-1cd7177f.entry.js +4 -0
  79. package/lib/duet/p-1cec5a70.system.entry.js +4 -0
  80. package/lib/duet/p-1e7222c2.entry.js +4 -0
  81. package/lib/duet/{p-c0b95b58.entry.js → p-202bbd70.entry.js} +1 -1
  82. package/lib/duet/{p-d1817efe.system.entry.js → p-22f56356.system.entry.js} +1 -1
  83. package/lib/duet/{p-f81d8534.entry.js → p-28b67b94.entry.js} +1 -1
  84. package/lib/duet/{p-b4374f0e.entry.js → p-33426ddc.entry.js} +1 -1
  85. package/lib/duet/p-33cf6ed1.entry.js +4 -0
  86. package/lib/duet/p-3d3f773d.system.entry.js +4 -0
  87. package/lib/duet/p-3e1ef509.system.entry.js +4 -0
  88. package/lib/duet/p-3f78a826.system.js +4 -0
  89. package/lib/duet/{p-2a1a9f9f.entry.js → p-44ffb960.entry.js} +1 -1
  90. package/lib/duet/{p-dee41056.system.entry.js → p-453955cc.system.entry.js} +1 -1
  91. package/lib/duet/{p-66dde4d2.entry.js → p-4670a654.entry.js} +1 -1
  92. package/lib/duet/p-47645ea8.system.entry.js +4 -0
  93. package/lib/duet/p-504dbf8f.system.entry.js +4 -0
  94. package/lib/duet/{p-62c294d6.system.entry.js → p-5230ee3c.system.entry.js} +1 -1
  95. package/lib/duet/{p-bbc229d8.system.entry.js → p-56e172f5.system.entry.js} +1 -1
  96. package/lib/duet/{p-de2be65b.system.js → p-57ea2576.system.js} +1 -1
  97. package/lib/duet/p-5aa0d34d.entry.js +4 -0
  98. package/lib/duet/p-5fc7e1f7.system.entry.js +4 -0
  99. package/lib/duet/{p-3dc9d15d.system.entry.js → p-605bc214.system.entry.js} +1 -1
  100. package/lib/duet/{p-4a7911fd.entry.js → p-60ab57d4.entry.js} +1 -1
  101. package/lib/duet/p-64109493.entry.js +4 -0
  102. package/lib/duet/{p-7e108b7e.entry.js → p-69a5dc6b.entry.js} +1 -1
  103. package/lib/duet/{p-8cfce39e.system.entry.js → p-6a230911.system.entry.js} +1 -1
  104. package/lib/duet/p-6a760b8a.entry.js +4 -0
  105. package/lib/duet/{p-c9303f9a.entry.js → p-6d2da245.entry.js} +1 -1
  106. package/lib/duet/{p-ceb75b35.system.entry.js → p-712e7dde.system.entry.js} +1 -1
  107. package/lib/duet/{p-f71f12ed.entry.js → p-746655ba.entry.js} +1 -1
  108. package/lib/duet/p-7b6db837.system.entry.js +4 -0
  109. package/lib/duet/p-7d080785.system.entry.js +4 -0
  110. package/lib/duet/{p-4095dba5.entry.js → p-82dc2e0b.entry.js} +1 -1
  111. package/lib/duet/p-8c8e82aa.system.js +4 -0
  112. package/lib/duet/{p-fc397e03.system.entry.js → p-8c980350.system.entry.js} +1 -1
  113. package/lib/duet/{p-1cfe38b1.system.entry.js → p-8cb47a70.system.entry.js} +1 -1
  114. package/lib/duet/{p-7ee52f58.entry.js → p-8f03c3eb.entry.js} +1 -1
  115. package/lib/duet/p-91fa68a5.js +4 -0
  116. package/lib/duet/{p-e26116e0.system.entry.js → p-92d38668.system.entry.js} +1 -1
  117. package/lib/duet/p-95626e7e.system.entry.js +4 -0
  118. package/lib/duet/p-96808a2e.system.entry.js +4 -0
  119. package/lib/duet/{p-8ffe1461.system.entry.js → p-96c103b2.system.entry.js} +1 -1
  120. package/lib/duet/p-986779fb.js +4 -0
  121. package/lib/duet/{p-35e45c19.system.js → p-9a945278.system.js} +1 -1
  122. package/lib/duet/{p-2d2c45f9.entry.js → p-9c94be45.entry.js} +1 -1
  123. package/lib/duet/p-9ce1baab.system.entry.js +4 -0
  124. package/lib/duet/p-9ff25646.entry.js +4 -0
  125. package/lib/duet/p-a1d12e94.system.entry.js +4 -0
  126. package/lib/duet/p-b03a46b6.entry.js +4 -0
  127. package/lib/duet/{p-a88df408.entry.js → p-b1b8e510.entry.js} +1 -1
  128. package/lib/duet/p-b694cbf5.system.js +4 -0
  129. package/lib/duet/p-b7e50cfa.entry.js +4 -0
  130. package/lib/duet/p-b82927b0.system.entry.js +4 -0
  131. package/lib/duet/{p-c3688975.entry.js → p-ba205dca.entry.js} +1 -1
  132. package/lib/duet/{p-f71e337e.system.entry.js → p-bcae23fc.system.entry.js} +1 -1
  133. package/lib/duet/{p-5c5bdb06.system.entry.js → p-be19c57b.system.entry.js} +1 -1
  134. package/lib/duet/{p-a321a98c.entry.js → p-c4737f88.entry.js} +1 -1
  135. package/lib/duet/p-c5beceed.js +4 -0
  136. package/lib/duet/{p-27d538f7.system.entry.js → p-c5f10483.system.entry.js} +1 -1
  137. package/lib/duet/{p-a6096b05.system.entry.js → p-d35fd913.system.entry.js} +1 -1
  138. package/lib/duet/p-d4b4bfa6.entry.js +4 -0
  139. package/lib/duet/p-d7623eb8.system.entry.js +4 -0
  140. package/lib/duet/{p-36007600.entry.js → p-dc85d2a4.entry.js} +1 -1
  141. package/lib/duet/p-de093c16.entry.js +4 -0
  142. package/lib/duet/p-de842863.entry.js +4 -0
  143. package/lib/duet/{p-59a07cf9.entry.js → p-e08b8909.entry.js} +1 -1
  144. package/lib/duet/p-e39471b6.entry.js +4 -0
  145. package/lib/duet/p-e834c8d5.system.entry.js +4 -0
  146. package/lib/duet/{p-ce1374a4.system.entry.js → p-ef45cfe9.system.entry.js} +1 -1
  147. package/lib/duet/{p-031c2cd8.system.entry.js → p-f0b1850a.system.entry.js} +1 -1
  148. package/lib/duet/p-f53c8019.entry.js +4 -0
  149. package/lib/duet/{p-4265de16.system.entry.js → p-f96c4093.system.entry.js} +1 -1
  150. package/lib/duet/p-fbd83d67.entry.js +4 -0
  151. package/lib/duet/{p-1c41525a.entry.js → p-fdecaf46.entry.js} +1 -1
  152. package/lib/esm/duet-alert.entry.js +4 -2
  153. package/lib/esm/duet-badge.entry.js +2 -2
  154. package/lib/esm/duet-button_2.entry.js +4 -3
  155. package/lib/esm/duet-caption_4.entry.js +7 -8
  156. package/lib/esm/duet-card.entry.js +4 -4
  157. package/lib/esm/duet-checkbox.entry.js +1 -1
  158. package/lib/esm/duet-choice_2.entry.js +4 -3
  159. package/lib/esm/duet-collapsible.entry.js +2 -2
  160. package/lib/esm/duet-cookie-consent.entry.js +1 -1
  161. package/lib/esm/duet-date-picker.entry.js +22 -12
  162. package/lib/esm/duet-divider_2.entry.js +1 -1
  163. package/lib/esm/duet-empty-state.entry.js +1 -1
  164. package/lib/esm/duet-fieldset.entry.js +1 -1
  165. package/lib/esm/duet-footer.entry.js +4 -4
  166. package/lib/esm/duet-grid_2.entry.js +1 -1
  167. package/lib/esm/duet-header_2.entry.js +25 -9
  168. package/lib/esm/duet-hero.entry.js +6 -6
  169. package/lib/esm/duet-icon.entry.js +3 -3
  170. package/lib/esm/duet-input_2.entry.js +2 -2
  171. package/lib/esm/duet-layout.entry.js +1 -1
  172. package/lib/esm/duet-list_2.entry.js +1 -1
  173. package/lib/esm/duet-modal.entry.js +8 -7
  174. package/lib/esm/duet-notification_2.entry.js +6 -5
  175. package/lib/esm/duet-number-input.entry.js +36 -15
  176. package/lib/esm/duet-radio_2.entry.js +1 -1
  177. package/lib/esm/duet-range-slider.entry.js +1 -1
  178. package/lib/esm/duet-select.entry.js +2 -2
  179. package/lib/esm/duet-step_2.entry.js +1 -1
  180. package/lib/esm/duet-tab_2.entry.js +11 -5
  181. package/lib/esm/duet-table.entry.js +1 -1
  182. package/lib/esm/duet-textarea.entry.js +1 -1
  183. package/lib/esm/duet-toggle.entry.js +1 -1
  184. package/lib/esm/duet-tooltip.entry.js +21 -10
  185. package/lib/esm/duet-tray.entry.js +20 -9
  186. package/lib/esm/duet-visually-hidden.entry.js +1 -1
  187. package/lib/esm/duet.js +2 -2
  188. package/lib/esm/{focus-utils-0b12f0df.js → focus-utils-1995e5a9.js} +1 -1
  189. package/lib/esm/{index-f70ddc7f.js → index-6e246691.js} +0 -3
  190. package/lib/esm/{language-utils-ab9c3afc.js → language-utils-d5c38f65.js} +23 -8
  191. package/lib/esm/loader.js +2 -2
  192. package/lib/esm/{string-utils-69cf0d09.js → string-utils-2f1793b8.js} +7 -1
  193. package/lib/esm-es5/duet-alert.entry.js +1 -1
  194. package/lib/esm-es5/duet-badge.entry.js +1 -1
  195. package/lib/esm-es5/duet-button_2.entry.js +1 -1
  196. package/lib/esm-es5/duet-caption_4.entry.js +1 -1
  197. package/lib/esm-es5/duet-card.entry.js +1 -1
  198. package/lib/esm-es5/duet-checkbox.entry.js +1 -1
  199. package/lib/esm-es5/duet-choice_2.entry.js +1 -1
  200. package/lib/esm-es5/duet-collapsible.entry.js +1 -1
  201. package/lib/esm-es5/duet-cookie-consent.entry.js +1 -1
  202. package/lib/esm-es5/duet-date-picker.entry.js +1 -1
  203. package/lib/esm-es5/duet-divider_2.entry.js +1 -1
  204. package/lib/esm-es5/duet-empty-state.entry.js +1 -1
  205. package/lib/esm-es5/duet-fieldset.entry.js +1 -1
  206. package/lib/esm-es5/duet-footer.entry.js +1 -1
  207. package/lib/esm-es5/duet-grid_2.entry.js +1 -1
  208. package/lib/esm-es5/duet-header_2.entry.js +1 -1
  209. package/lib/esm-es5/duet-hero.entry.js +1 -1
  210. package/lib/esm-es5/duet-icon.entry.js +1 -1
  211. package/lib/esm-es5/duet-input_2.entry.js +1 -1
  212. package/lib/esm-es5/duet-layout.entry.js +1 -1
  213. package/lib/esm-es5/duet-list_2.entry.js +1 -1
  214. package/lib/esm-es5/duet-modal.entry.js +1 -1
  215. package/lib/esm-es5/duet-notification_2.entry.js +1 -1
  216. package/lib/esm-es5/duet-number-input.entry.js +2 -2
  217. package/lib/esm-es5/duet-radio_2.entry.js +1 -1
  218. package/lib/esm-es5/duet-range-slider.entry.js +1 -1
  219. package/lib/esm-es5/duet-select.entry.js +1 -1
  220. package/lib/esm-es5/duet-step_2.entry.js +1 -1
  221. package/lib/esm-es5/duet-tab_2.entry.js +1 -1
  222. package/lib/esm-es5/duet-table.entry.js +1 -1
  223. package/lib/esm-es5/duet-textarea.entry.js +1 -1
  224. package/lib/esm-es5/duet-toggle.entry.js +1 -1
  225. package/lib/esm-es5/duet-tooltip.entry.js +1 -1
  226. package/lib/esm-es5/duet-tray.entry.js +1 -1
  227. package/lib/esm-es5/duet-visually-hidden.entry.js +1 -1
  228. package/lib/esm-es5/duet.js +1 -1
  229. package/lib/esm-es5/focus-utils-1995e5a9.js +4 -0
  230. package/lib/esm-es5/{index-f70ddc7f.js → index-6e246691.js} +1 -1
  231. package/lib/esm-es5/language-utils-d5c38f65.js +4 -0
  232. package/lib/esm-es5/loader.js +1 -1
  233. package/lib/esm-es5/{string-utils-69cf0d09.js → string-utils-2f1793b8.js} +1 -1
  234. package/lib/html.html-data.json +4489 -0
  235. package/lib/types/components/duet-alert/duet-alert.d.ts +2 -1
  236. package/lib/types/components/duet-button/duet-button.d.ts +1 -1
  237. package/lib/types/components/duet-choice/duet-choice.d.ts +1 -1
  238. package/lib/types/components/duet-date-picker/duet-date-picker.d.ts +13 -7
  239. package/lib/types/components/duet-footer/duet-footer.d.ts +1 -1
  240. package/lib/types/components/duet-header/duet-header.d.ts +21 -5
  241. package/lib/types/components/duet-hero/duet-hero.d.ts +3 -3
  242. package/lib/types/components/duet-link/duet-link.d.ts +2 -3
  243. package/lib/types/components/duet-modal/duet-modal.d.ts +3 -3
  244. package/lib/types/components/duet-notification-drawer/duet-notification-drawer.d.ts +3 -3
  245. package/lib/types/components/duet-number-input/duet-number-input.d.ts +21 -0
  246. package/lib/types/components/duet-tab-group/duet-tab-group.d.ts +6 -0
  247. package/lib/types/components/duet-tooltip/duet-tooltip.d.ts +11 -0
  248. package/lib/types/components/duet-tray/duet-tray.d.ts +11 -0
  249. package/lib/types/components.d.ts +146 -384
  250. package/lib/types/utils/language-utils.d.ts +3 -2
  251. package/lib/types/utils/string-utils.d.ts +1 -0
  252. package/package.json +18 -14
  253. package/lib/cjs/duet-upload.cjs.entry.js +0 -866
  254. package/lib/collection/components/duet-upload/duet-upload-file-list.js +0 -49
  255. package/lib/collection/components/duet-upload/duet-upload-validators.js +0 -93
  256. package/lib/collection/components/duet-upload/duet-upload.css +0 -133
  257. package/lib/collection/components/duet-upload/duet-upload.js +0 -1440
  258. package/lib/collection/components/duet-upload/errorcodes.utils.js +0 -20
  259. package/lib/collection/components/duet-upload/mock.helpers.js +0 -91
  260. package/lib/collection/components/duet-upload/upload.helpers.js +0 -13
  261. package/lib/collection/components/duet-upload/xhr.helpers.js +0 -34
  262. package/lib/duet/p-0733c303.system.entry.js +0 -4
  263. package/lib/duet/p-095060cc.js +0 -4
  264. package/lib/duet/p-156864a1.system.entry.js +0 -4
  265. package/lib/duet/p-1911dfe7.system.entry.js +0 -4
  266. package/lib/duet/p-2834a302.entry.js +0 -4
  267. package/lib/duet/p-28a3d38f.system.entry.js +0 -4
  268. package/lib/duet/p-2a4d7c5b.system.entry.js +0 -4
  269. package/lib/duet/p-4289b543.entry.js +0 -4
  270. package/lib/duet/p-46a3ae43.system.js +0 -4
  271. package/lib/duet/p-4a38cf9d.entry.js +0 -4
  272. package/lib/duet/p-4be8e814.entry.js +0 -4
  273. package/lib/duet/p-591b2137.entry.js +0 -4
  274. package/lib/duet/p-5f70e318.entry.js +0 -4
  275. package/lib/duet/p-6c2729da.js +0 -4
  276. package/lib/duet/p-6f107847.system.entry.js +0 -4
  277. package/lib/duet/p-77a5fe4c.system.js +0 -4
  278. package/lib/duet/p-7809e78b.system.entry.js +0 -4
  279. package/lib/duet/p-7a36d76f.system.entry.js +0 -4
  280. package/lib/duet/p-884693f1.entry.js +0 -4
  281. package/lib/duet/p-8977b722.entry.js +0 -4
  282. package/lib/duet/p-89db3b94.entry.js +0 -4
  283. package/lib/duet/p-9381c2d4.entry.js +0 -4
  284. package/lib/duet/p-9a450c9a.entry.js +0 -4
  285. package/lib/duet/p-9bbfe606.system.entry.js +0 -4
  286. package/lib/duet/p-a0a066cb.system.entry.js +0 -4
  287. package/lib/duet/p-a89d5d7c.entry.js +0 -4
  288. package/lib/duet/p-b07055fd.system.entry.js +0 -4
  289. package/lib/duet/p-b456d684.system.entry.js +0 -4
  290. package/lib/duet/p-bd18c93f.js +0 -4
  291. package/lib/duet/p-bddb1c15.system.entry.js +0 -4
  292. package/lib/duet/p-c4d183e6.entry.js +0 -4
  293. package/lib/duet/p-cd4e8ccf.js +0 -4
  294. package/lib/duet/p-cf243bcb.system.entry.js +0 -4
  295. package/lib/duet/p-d37c8a05.system.js +0 -4
  296. package/lib/duet/p-d989af11.entry.js +0 -4
  297. package/lib/duet/p-e6128d82.system.entry.js +0 -4
  298. package/lib/duet/p-e86cdc17.entry.js +0 -4
  299. package/lib/duet/p-eadb29c7.entry.js +0 -4
  300. package/lib/duet/p-f30b14d6.system.entry.js +0 -4
  301. package/lib/duet/p-f79f8da1.entry.js +0 -4
  302. package/lib/esm/duet-upload.entry.js +0 -862
  303. package/lib/esm-es5/duet-upload.entry.js +0 -4
  304. package/lib/esm-es5/focus-utils-0b12f0df.js +0 -4
  305. package/lib/esm-es5/language-utils-ab9c3afc.js +0 -4
  306. package/lib/types/components/duet-upload/duet-upload-file-list.d.ts +0 -9
  307. package/lib/types/components/duet-upload/duet-upload-validators.d.ts +0 -12
  308. package/lib/types/components/duet-upload/duet-upload.d.ts +0 -311
  309. package/lib/types/components/duet-upload/errorcodes.utils.d.ts +0 -7
  310. package/lib/types/components/duet-upload/mock.helpers.d.ts +0 -2
  311. package/lib/types/components/duet-upload/upload.helpers.d.ts +0 -1
  312. package/lib/types/components/duet-upload/xhr.helpers.d.ts +0 -12
@@ -1,862 +0,0 @@
1
- /*!
2
- * Built with Duet Design System
3
- */
4
- import { h, r as registerInstance, c as createEvent, H as Host, g as getElement } from './index-f70ddc7f.js';
5
- import { c as createID } from './create-id-981107da.js';
6
- import { g as getLocaleString } from './language-utils-ab9c3afc.js';
7
- import { i as inheritGlobalTheme } from './themeable-component-572685dd.js';
8
-
9
- const formatBytes = (bytes, decimals = 2) => {
10
- if (bytes === 0) {
11
- return "0 Bytes";
12
- }
13
- const k = 1024;
14
- const dm = decimals < 0 ? 0 : decimals;
15
- const sizes = ["Bytes", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"];
16
- const i = Math.floor(Math.log(bytes) / Math.log(k));
17
- return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + " " + sizes[i];
18
- };
19
-
20
- const DuetUploadFileList = ({ data, onDelete, onCancel, getError }) => {
21
- if (data.invalid.length === 0 && data.valid.length === 0) {
22
- return;
23
- }
24
- return (h("ol", { class: "duet-upload-filelist" },
25
- data.valid.length !== 0 && (h("li", null,
26
- h("duet-visually-hidden", null, "Files"),
27
- h("ul", null, data.valid.length !== 0 &&
28
- data.valid.map(e => (h("li", { class: "duet-upload-file" },
29
- h("div", { class: "duet-upload-file-container" },
30
- h("div", { class: "duet-upload-file-link" }, e.url ? (h("duet-button", { variation: "plain", icon: "messaging-attachment", url: e.url },
31
- e.item.name,
32
- " (",
33
- formatBytes(e.item.size),
34
- ")")) : (`${e.item.name} (${formatBytes(e.item.size)})`)),
35
- h("ul", { class: "duet-upload-file-actions", role: "menubar", "aria-label": "file actions" },
36
- e.progress < 100 && (h("li", { role: "none" },
37
- h("duet-button", { role: "menuitem", variation: "plain", icon: "messaging-declined", "icon-only": true, "icon-size": "large", margin: "none", onClick: ev => onCancel(e.item.name, ev) }))),
38
- e.progress === 100 && (h("li", { role: "none" },
39
- h("duet-button", { role: "menuitem", variation: "destructive", icon: "action-delete", "icon-only": true, "icon-size": "large", margin: "none", onClick: ev => onDelete(e.item.name, ev) }))))),
40
- e.progress < 100 && (h("div", { class: "duet-upload-file-progress" },
41
- h("progress", { value: e.progress, max: "100" },
42
- h("div", { class: "progress-bar" },
43
- h("span", { style: { width: `${e.progress}%;` } },
44
- "Progress: ",
45
- e.progress,
46
- "%"))))))))))),
47
- data.invalid.length !== 0 && (h("li", null,
48
- h("duet-visually-hidden", null, "Files with Errors"),
49
- h("ul", null, data.invalid.map(e => {
50
- return (h("li", { class: "duet-upload-file duet-upload-file-errors" },
51
- h("div", { class: "duet-upload-file-container" },
52
- h("div", { class: "duet-upload-file-link duet-upload-file-link-error" },
53
- h("div", null,
54
- e.item.name,
55
- " (",
56
- formatBytes(e.item.size),
57
- ")"),
58
- h("div", { "data-error-type": e.error.type, "data-error-message": e.error.system_message }, getError(e.error.type))),
59
- h("ul", { class: "duet-upload-file-actions", role: "menubar", "aria-label": "file actions" },
60
- h("li", { role: "none" },
61
- h("duet-button", { role: "menuitem", variation: "destructive", icon: "action-delete", "icon-only": true, "icon-size": "large", margin: "none", onClick: ev => onDelete(e.item.name, ev) }))))));
62
- }))))));
63
- };
64
-
65
- const errorcodes = [
66
- {
67
- type: "default",
68
- system_message: "unknown error",
69
- message: {
70
- fi: "",
71
- sv: "",
72
- en: "An unknown error occured, please try again"
73
- }
74
- },
75
- {
76
- type: "400",
77
- system_message: "Bad Request: The server could not understand the request due to invalid syntax.",
78
- message: {
79
- fi: "",
80
- sv: "",
81
- en: "The server rejected your file"
82
- }
83
- },
84
- {
85
- type: "401",
86
- system_message: "Not Authenticated: The client must authenticate itself to get the requested response..",
87
- message: {
88
- fi: "",
89
- sv: "",
90
- en: "You need to be logged in to upload files"
91
- }
92
- },
93
- {
94
- type: "403",
95
- system_message: "No Access: The client does not have access rights to the content;",
96
- message: {
97
- fi: "",
98
- sv: "",
99
- en: "You do not have the correct access rights to upload files"
100
- }
101
- },
102
- {
103
- type: "413",
104
- system_message: "Payload too large",
105
- message: {
106
- fi: "",
107
- sv: "",
108
- en: "The file was to large for the server to handle"
109
- }
110
- },
111
- {
112
- type: "415",
113
- system_message: "Unsupported media type",
114
- message: {
115
- fi: "",
116
- sv: "",
117
- en: "The server rejected the file because it had the wrong type"
118
- }
119
- },
120
- {
121
- type: "429",
122
- system_message: "Too many request from same address",
123
- message: {
124
- fi: "",
125
- sv: "",
126
- en: "The server has received to many request from you, please try again later"
127
- }
128
- },
129
- {
130
- type: "500",
131
- system_message: "Internal Server Error",
132
- message: {
133
- fi: "",
134
- sv: "",
135
- en: "The server reported an unknown error and the upload failed"
136
- }
137
- },
138
- {
139
- type: "duet-upload-100",
140
- system_message: "File extension not allowed",
141
- message: {
142
- fi: "",
143
- sv: "",
144
- en: "You cannot upload files with that extension"
145
- }
146
- },
147
- {
148
- type: "duet-upload-001",
149
- system_message: "File transfer failed",
150
- message: {
151
- fi: "",
152
- sv: "",
153
- en: "Your connection to the server was interrupted, try again"
154
- }
155
- },
156
- {
157
- type: "duet-upload-101",
158
- system_message: "File mimetype not allowed",
159
- message: {
160
- fi: "",
161
- sv: "",
162
- en: "You cannot upload files of that type"
163
- }
164
- },
165
- {
166
- type: "duet-upload-201",
167
- system_message: "File is too large",
168
- message: {
169
- fi: "",
170
- sv: "",
171
- en: "The file is larger than permitted"
172
- }
173
- },
174
- {
175
- type: "duet-upload-202",
176
- system_message: "The combined size of all files is too large",
177
- message: {
178
- fi: "",
179
- sv: "",
180
- en: "You have reached the maximum combined filesize"
181
- }
182
- },
183
- {
184
- type: "duet-upload-301",
185
- system_message: "The maximum file limit has been reached",
186
- message: {
187
- fi: "Liitteiden maksimimäärä saavutettu.",
188
- sv: "",
189
- en: "Maximum number of attachments reached."
190
- }
191
- }
192
- ];
193
-
194
- const getError = (code) => {
195
- let error = {
196
- type: undefined,
197
- system_message: undefined,
198
- message: undefined,
199
- };
200
- error = errorcodes.filter(errorItem => {
201
- return errorItem.type === code;
202
- })[0];
203
- if (!error) {
204
- error = errorcodes.filter(errorItem => {
205
- return errorItem.type === "default";
206
- })[0];
207
- }
208
- return error;
209
- };
210
-
211
- const validateFileExtension = (name, allowedExtensions) => {
212
- if (!allowedExtensions) {
213
- return true;
214
- }
215
- const ext = name.split(".");
216
- const validExtension = allowedExtensions.split(",");
217
- const extension = ext[ext.length - 1];
218
- return validExtension.includes(extension);
219
- };
220
- const validateFileMime = (type, allowedMimetypes) => {
221
- if (!allowedMimetypes || !type) {
222
- return true;
223
- }
224
- const validMimeTypes = allowedMimetypes.split(",");
225
- let valid = false;
226
- validMimeTypes.forEach(mimeType => {
227
- const allowedTypes = mimeType.split("/");
228
- const fileType = type.split("/");
229
- if (allowedTypes[0] === fileType[0] && (allowedTypes[1] === fileType[1] || allowedTypes[1] === "*")) {
230
- valid = true;
231
- }
232
- });
233
- return valid;
234
- };
235
- const validateFileSize = (size, maxBytes) => {
236
- if (!maxBytes || !size) {
237
- return true;
238
- }
239
- return maxBytes >= size;
240
- };
241
- const validateFile = (item, validators) => {
242
- const { allowedMimetypes, allowedExtensions, maxBytes } = validators;
243
- let valid = false;
244
- let errorMessage = getError("default");
245
- if (item) {
246
- const { name, type, size } = item;
247
- const mime = validateFileMime(type, allowedMimetypes);
248
- const ext = validateFileExtension(name, allowedExtensions);
249
- const bytes = validateFileSize(size, maxBytes);
250
- if (!mime) {
251
- errorMessage = getError("duet-upload-101");
252
- }
253
- if (!ext) {
254
- errorMessage = getError("duet-upload-100");
255
- }
256
- if (!bytes) {
257
- errorMessage = getError("duet-upload-201");
258
- }
259
- valid = mime && ext && bytes;
260
- }
261
- else {
262
- valid = false;
263
- }
264
- return {
265
- valid,
266
- errorMessage: valid ? undefined : getLocaleString(errorMessage.message),
267
- errorSystem: valid ? undefined : errorMessage.system_message,
268
- errorType: valid ? undefined : errorMessage.type,
269
- };
270
- };
271
- const validateTotalSizeIsAboveMax = (filelist, maxTotalBytes) => {
272
- let total = 0;
273
- if (maxTotalBytes) {
274
- filelist.forEach(item => {
275
- if (item.valid && item.size) {
276
- total += item.size;
277
- }
278
- });
279
- if (total < maxTotalBytes) {
280
- return true;
281
- }
282
- }
283
- return false;
284
- };
285
- const validateTotalAmountIsAboveMax = (filelist, maxFiles) => {
286
- let total = 0;
287
- if (maxFiles) {
288
- filelist.forEach(item => {
289
- if (item.valid) {
290
- total++;
291
- }
292
- });
293
- if (total > maxFiles) {
294
- return true;
295
- }
296
- }
297
- return false;
298
- };
299
-
300
- const makeXhrRequest = (payload, options, onFailure, onSuccess, onProgress) => {
301
- const { type, xhr, uri, argument, headers } = Object.assign({
302
- type: "POST",
303
- argument: null,
304
- headers: null,
305
- }, options);
306
- xhr.open(type, `${uri}${argument || ""}`, true);
307
- const { data, name } = payload;
308
- // headers must be added after open
309
- if (headers) {
310
- Object.keys(headers).forEach(key => {
311
- xhr.setRequestHeader(key, headers[key]);
312
- });
313
- }
314
- if (type === "POST") {
315
- xhr.onreadystatechange = () => {
316
- // Call a function when the state changes.
317
- if (xhr.readyState === XMLHttpRequest.DONE && xhr.status >= 200 && xhr.status < 300) {
318
- // Request finished without errors
319
- onSuccess(xhr, name, xhr.status);
320
- }
321
- if (xhr.readyState === XMLHttpRequest.DONE && xhr.status >= 300 && xhr.status < 999) {
322
- // Request finished with errors
323
- onFailure(xhr, name, xhr.status);
324
- }
325
- };
326
- onProgress(name);
327
- }
328
- xhr.send(data);
329
- return xhr;
330
- };
331
-
332
- const duetUploadCss = "*,*::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}:host li{list-style:none}.duet-upload{box-sizing:border-box;padding:0;margin:0;background:transparent;border:0;-moz-appearance:none;-webkit-appearance:none;appearance:none}.duet-upload li{list-style:none}.duet-upload-file-errors{padding:20px 0;color:#de2362}.duet-upload-filelist{margin-bottom:25px}.duet-upload-filelist-empty{display:flex;align-items:center;justify-content:center;width:100%;height:75px;margin:0 auto;background-color:#f3f9fc}.duet-upload-file{display:flex;flex-flow:column;justify-content:center;min-height:50px;border-bottom:1px solid #e1e3e6}.duet-upload-file:first-of-type:not(.duet-upload-file-errors){border-top:1px solid #e1e3e6}.duet-upload-file-container{display:flex;place-items:center;width:100%}.duet-upload-file-link{display:flex;flex-grow:2;place-items:center}.duet-upload-file-link-error{flex-direction:column;place-items:flex-start}.duet-upload-file-link duet-button{position:relative;top:6px}.duet-upload-file-actions{display:flex;transform:scale(0.8)}.duet-upload-file-progress{}.duet-upload-file-progress .progress-bar{position:relative;display:block;width:100%;height:15px;background-color:#f3f9fc;border-radius:0;box-shadow:none}.duet-upload-file-progress .progress-bar>span{display:block;text-indent:-9999px;background-color:#0077b3;border-radius:0}.duet-upload-file-progress progress[value]{display:flex;width:100%;height:15px;color:#0077b3;border:0 none;-webkit-appearance:none;-moz-appearance:none;appearance:none}.duet-upload-file-progress progress[value]::-webkit-progress-bar{background-color:#f3f9fc;border-radius:0}.duet-upload-file-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-upload-file-progress progress[value] ::-moz-progress-bar{background-color:#f3f9fc}";
333
-
334
- let DuetUpload = class {
335
- constructor(hostRef) {
336
- registerInstance(this, hostRef);
337
- this.duetChange = createEvent(this, "duetChange", 3);
338
- this.duetBlur = createEvent(this, "duetBlur", 7);
339
- this.duetFocus = createEvent(this, "duetFocus", 7);
340
- this.duetDone = createEvent(this, "duetDone", 3);
341
- this.duetState = createEvent(this, "duetState", 3);
342
- this.duetDelete = createEvent(this, "duetDelete", 3);
343
- this.duetCancel = createEvent(this, "duetCancel", 3);
344
- this.duetProgress = createEvent(this, "duetProgress", 3);
345
- this.duetUpload = createEvent(this, "duetUpload", 3);
346
- /**
347
- * Own Properties
348
- */
349
- this.buttonId = createID("DuetButton");
350
- this.labelId = createID("DuetLabel");
351
- this.uploadId = createID("DuetUpload");
352
- this.filesInProgress = new Map();
353
- this.fileMaxReached = false;
354
- this.bytesMaxReached = false;
355
- /**
356
- * State() variables
357
- */
358
- this.tick = Date.now();
359
- /**
360
- * If external is set to true, the upload component will not actually upload the files, but only keep states
361
- * it will be up to you to handle the upload and return progress information to the upload-component
362
- */
363
- this.external = false;
364
- /**
365
- * Property to change descriptionDefaults defaults on the component.
366
- * normally you would handle these strings on an application level and override @label when needed
367
- */
368
- this.buttonLabelDefaults = {
369
- fi: "Lisää liite",
370
- sv: "Lägg till en bilaga",
371
- en: "Add an attachment",
372
- };
373
- /**
374
- * Label of button
375
- * @default { fi: "Lisää liite", sv: "Lägg till en bilaga", en: "Add an attachment" }
376
- */
377
- this.buttonLabel = getLocaleString(this.buttonLabelDefaults);
378
- /**
379
- * accessible Label of button
380
- */
381
- this.accessibleButtonLabel = undefined;
382
- /**
383
- * Theme of the input.
384
- */
385
- this.theme = "";
386
- /**
387
- * Makes the input component disabled. This prevents users from being able to
388
- * interact with the upload component, and conveys its inactive state to assistive technologies.
389
- */
390
- this.disabled = false;
391
- /**
392
- * Controls the margin of the component.
393
- */
394
- this.margin = "auto";
395
- /**
396
- * Set whether the input is required or not. Please note that this is necessary for
397
- * accessible inputs when the user is required to fill them. When using this property
398
- * you need to also set “novalidate” attribute to your form element to prevent
399
- * browser from displaying its own validation errors.
400
- */
401
- this.required = false;
402
- /**
403
- * Map of string that contain list of uploaded files.
404
- */
405
- this.files = new Map();
406
- /**
407
- * Property to read if filelist contains errors or not
408
- */
409
- this.valid = !this.required;
410
- /**
411
- * Property to change labelDefaults defaults on the component.
412
- * normally you would handle these strings on an application level and override @label when needed
413
- */
414
- this.labelDefaults = {
415
- fi: "Lisää liite",
416
- sv: "Lägg till en bilaga",
417
- en: "Add attachments",
418
- };
419
- /**
420
- * Label for the input.
421
- * @default { fi: "Lisää liite",sv: "Lägg till en bilaga",en: "Add attachments"}
422
- */
423
- this.label = getLocaleString(this.labelDefaults);
424
- /**
425
- * Property to change descriptionDefaults defaults on the component.
426
- * normally you would handle these strings on an application level and override @label when needed
427
- */
428
- this.descriptionDefaults = {
429
- 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.",
430
- 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.",
431
- 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.",
432
- };
433
- /**
434
- * Description for the upload component.
435
- * @default ...
436
- */
437
- this.description = getLocaleString(this.descriptionDefaults);
438
- /**
439
- * Defaults for the filelist's empty state.
440
- * @default { fi: "Lisää liite",sv: "Lägg till en bilaga",en: "Add attachments"}
441
- */
442
- this.fileListEmptyDefaults = {
443
- fi: "Ei vielä lisättyjä tiedostoja.",
444
- sv: "Inga filer har lagts till ännu.",
445
- en: "No files added yet.",
446
- };
447
- /**
448
- * Label for the filelist's empty state.
449
- * @default { fi: "Ei vielä lisättyjä tiedostoja.",sv: "Inga filer har lagts till ännu.",en: "No files added yet."}
450
- */
451
- this.fileListEmpty = getLocaleString(this.fileListEmptyDefaults);
452
- /**
453
- * Display the input in error state along with an error message.
454
- */
455
- this.error = "";
456
- /**
457
- * Visually hide the label, but still show it to screen readers.
458
- */
459
- this.labelHidden = false;
460
- /**
461
- * if set, allows capture of media from user camera / microphone
462
- * The capture attribute value is a string that specifies which camera to use for capture
463
- * of image or video data, if the accept attribute indicates that the input should be of
464
- * one of those types. A value of user indicates that the user-facing camera and/or
465
- * microphone should be used. A value of environment specifies that the outward-facing
466
- * camera and/or microphone should be used. If this attribute is missing, the user agent
467
- * is free to decide on its own what to do. If the requested facing mode isn't available,
468
- * the user agent may fall back to its preferred default mode.
469
- */
470
- this.capture = undefined;
471
- /**
472
- * Use maxBytes to specify the maximum size in Bytes of a file that can be uploaded.
473
- */
474
- this.maxBytes = 200000000;
475
- /**
476
- * Use maxBytesTotal to specify the maximum size in Bytes of All files combined that can be uploaded.
477
- */
478
- this.maxBytesTotal = undefined;
479
- /**
480
- * Use maxFiles to specify the maximum amount of files that can be uploaded
481
- */
482
- this.maxFiles = 99;
483
- /**
484
- * A string of commaseperated file type values that are allowed
485
- * @example: .pdf,.doc,.docx
486
- */
487
- this.allowedExtensions = "all";
488
- /**
489
- * A string of commaseperated mime type values that are allowed
490
- * @example: image/*,application/msword,
491
- */
492
- this.allowedMimetypes = "*";
493
- /**
494
- * Use multiple to allow the user to select multiple files when uploading
495
- */
496
- this.multiple = true;
497
- /**
498
- * Use limitSelection to enforce the value in allowedExtension & allowedMimetypes when selecting files,
499
- * by default this is off, setting this to true will limit the users choices to what has been explicitly set
500
- */
501
- this.limitSelection = false;
502
- /**
503
- * Private functions
504
- */
505
- this.kick = () => (this.tick = Date.now()); // will trigger re-render
506
- this.genHashName = () => Date.now().toString(36) + Math.random();
507
- this.updateValueInMap = (item, key, value, kick = true) => {
508
- const fileItem = this.files.get(item);
509
- fileItem[key] = value;
510
- this.files.set(item, fileItem);
511
- if (kick) {
512
- this.kick();
513
- }
514
- };
515
- this.updateProgress = (ev, name) => {
516
- if (ev.lengthComputable) {
517
- const percentComplete = (ev.loaded / ev.total) * 100;
518
- this.updateValueInMap(name, "progress", percentComplete);
519
- this.onProgress(name, percentComplete, ev);
520
- }
521
- else {
522
- console.log("cant read progress");
523
- }
524
- };
525
- this.trackProgress = (name, remove = false) => {
526
- if (remove) {
527
- this.filesInProgress.delete(name);
528
- }
529
- else {
530
- this.filesInProgress.set(name, "inprogress");
531
- }
532
- if (this.filesInProgress.size === 0) {
533
- this.onDone();
534
- }
535
- };
536
- this.getFilesAsArray = () => {
537
- const filesInQueue = [];
538
- const filesInError = [];
539
- this.files.forEach(value => {
540
- if (value.valid && !value.deleted) {
541
- filesInQueue.push(value);
542
- }
543
- else if (!value.valid && !value.deleted) {
544
- filesInError.push(value);
545
- }
546
- });
547
- return { valid: filesInQueue, invalid: filesInError };
548
- };
549
- this.resetFormFields = () => {
550
- /**
551
- * You cannot modify a FileList, nor remove single items from it
552
- * This completely removes all items in the FileList
553
- * We reset the form fields to always be able to re-upload files
554
- * and because we handle all uploads and states internally in the component (not relying on native form elements)
555
- */
556
- this.nativeInput.value = "";
557
- };
558
- this.getI18nError = (errorCode) => {
559
- const errorFromJson = getError(errorCode);
560
- const i18String = getLocaleString(errorFromJson.message);
561
- if (i18String === "" || !i18String) {
562
- return errorFromJson.system_message;
563
- }
564
- else {
565
- return i18String;
566
- }
567
- };
568
- /**
569
- * Eventlisteners for the XHR requests
570
- */
571
- this.transferComplete = name => {
572
- this.updateValueInMap(name, "progress", 100, false);
573
- this.trackProgress(name, true);
574
- };
575
- this.transferDone = (xhr, name, status) => {
576
- this.updateValueInMap(name, "status", status, false);
577
- try {
578
- const response = JSON.parse(xhr.response);
579
- this.updateValueInMap(name, "url", response.url);
580
- }
581
- catch (e) {
582
- this.updateValueInMap(name, "url", null);
583
- console.error("Server did not respond with expected response {url: string}");
584
- }
585
- return;
586
- };
587
- this.transferDoneWithFailure = (xhr, name, status) => {
588
- try {
589
- const { error } = JSON.parse(xhr.response);
590
- this.updateValueInMap(name, "error", { message: error.message, type: error.type });
591
- }
592
- catch (e) {
593
- console.error("Server did not respond with expected response error:{message: string, type: int}");
594
- this.updateValueInMap(name, "error", { type: status });
595
- }
596
- };
597
- this.transferFailed = name => {
598
- this.updateValueInMap(name, "error", getError("duet-upload-001"));
599
- };
600
- this.transferCanceled = name => {
601
- this.files.delete(name);
602
- this.validateTotals(name);
603
- this.kick();
604
- };
605
- this.validateTotals = (name) => {
606
- const isTotalSizeOverMaxSize = validateTotalSizeIsAboveMax(this.files, this.maxBytesTotal);
607
- const isTotalFileAmountAboveMax = validateTotalAmountIsAboveMax(this.files, this.maxFiles);
608
- if (isTotalSizeOverMaxSize && name) {
609
- this.updateValueInMap(name, "error", getError("duet-upload-202"), false);
610
- }
611
- if (isTotalFileAmountAboveMax && name) {
612
- this.updateValueInMap(name, "error", getError("duet-upload-301"), false);
613
- }
614
- this.bytesMaxReached = isTotalSizeOverMaxSize;
615
- this.fileMaxReached = isTotalFileAmountAboveMax;
616
- return {
617
- bytesMaxReached: isTotalSizeOverMaxSize,
618
- fileMaxReached: isTotalFileAmountAboveMax,
619
- };
620
- };
621
- this.onDelete = (key, ev) => {
622
- const deletedItem = this.files.get(key);
623
- this.files.delete(key);
624
- this.validateTotals();
625
- this.kick();
626
- if (!this.external) {
627
- this.makeXHRDeleteRequest(deletedItem);
628
- }
629
- this.resetFormFields();
630
- this.duetDelete.emit({
631
- originalEvent: ev,
632
- data: { deletion: deletedItem },
633
- component: "duet-upload",
634
- });
635
- };
636
- this.onCancel = (key, ev) => {
637
- const cancelledItem = this.files.get(key);
638
- this.files.delete(key);
639
- if (!this.external) {
640
- const { xhr } = cancelledItem;
641
- xhr.abort();
642
- }
643
- else {
644
- this.kick();
645
- }
646
- this.resetFormFields();
647
- this.duetCancel.emit({
648
- originalEvent: ev,
649
- data: { cancelled: cancelledItem },
650
- component: "duet-upload",
651
- });
652
- };
653
- this.onUpload = (ev) => {
654
- this.duetUpload.emit({
655
- originalEvent: ev,
656
- component: "duet-upload",
657
- });
658
- };
659
- this.onBlur = (ev) => {
660
- this.duetBlur.emit({
661
- originalEvent: ev,
662
- component: "duet-upload",
663
- });
664
- };
665
- this.onProgress = (key, percentComplete, ev) => {
666
- this.duetChange.emit({
667
- originalEvent: ev,
668
- data: {
669
- key,
670
- percentComplete,
671
- },
672
- component: "duet-upload",
673
- });
674
- };
675
- this.onFocus = (ev) => {
676
- this.duetFocus.emit({
677
- originalEvent: ev,
678
- component: "duet-upload",
679
- });
680
- };
681
- this.onDone = () => {
682
- this.duetDone.emit({
683
- component: "duet-upload",
684
- data: { files: this.files },
685
- });
686
- };
687
- this.startUpload = async (ev) => {
688
- await this.setFocus();
689
- this.nativeInput.click();
690
- this.onUpload(ev);
691
- ev.stopPropagation();
692
- ev.preventDefault();
693
- };
694
- }
695
- watchValidHandler(newValue, oldValue) {
696
- if (newValue !== oldValue) {
697
- this.kick();
698
- }
699
- }
700
- /**
701
- * Component lifecycle events.
702
- */
703
- componentWillLoad() {
704
- inheritGlobalTheme(this);
705
- }
706
- componentWillRender() {
707
- const { invalid, valid } = this.getFilesAsArray();
708
- const oldValid = this.valid;
709
- this.valid = invalid.length === 0 && valid.length !== 0;
710
- if (this.valid !== oldValid) {
711
- this.duetState.emit({
712
- originalEvent: undefined,
713
- data: { valid: this.valid, from: "componentWillRender" },
714
- component: "duet-upload",
715
- });
716
- }
717
- }
718
- /**
719
- * XHR request utilities
720
- */
721
- makeXHRPostRequest(data) {
722
- const xhr = new XMLHttpRequest();
723
- const name = data.get("name");
724
- xhr.upload.addEventListener("progress", ev => {
725
- this.updateProgress(ev, name);
726
- });
727
- xhr.upload.addEventListener("load", () => {
728
- this.transferComplete(name);
729
- });
730
- xhr.upload.addEventListener("error", () => {
731
- this.transferFailed(name);
732
- });
733
- xhr.upload.addEventListener("abort", () => {
734
- this.transferCanceled(name);
735
- });
736
- return makeXhrRequest({ data, name }, { type: "POST", uri: this.uri, xhr, argument: null, headers: null }, this.transferDoneWithFailure, this.transferDone, this.trackProgress);
737
- }
738
- makeXHRDeleteRequest(data) {
739
- const { uid, item } = data;
740
- const xhr = new XMLHttpRequest();
741
- // don't present server issues to user on deletes, just remove them from the visible list
742
- return makeXhrRequest({ data: null, name }, {
743
- type: "DELETE",
744
- xhr,
745
- uri: this.uri,
746
- arguments: `?key=${uid}&name=${item.name}`,
747
- headers: {
748
- "x-fileuid": uid,
749
- "x-filename": item.name,
750
- },
751
- }, this.transferDoneWithFailure, this.transferDone, this.trackProgress);
752
- }
753
- /**
754
- * Component event handling.
755
- */
756
- async onChange(ev) {
757
- var _a;
758
- const selectedFiles = Array.from((_a = this.nativeInput) === null || _a === void 0 ? void 0 : _a.files);
759
- // FileList is a nice array like structure but
760
- // to ensure uniqueness of files we use a mapping structure and
761
- // key to the name (makes it easier to delete)
762
- if (selectedFiles) {
763
- for (const item of selectedFiles) {
764
- const { valid, errorMessage, errorType, errorSystem } = validateFile(item, {
765
- maxBytes: this.maxBytes,
766
- allowedExtensions: this.allowedExtensions,
767
- allowedMimetypes: this.allowedMimetypes,
768
- });
769
- const uid = this.genHashName();
770
- const fileListItem = {
771
- uid,
772
- item: item,
773
- size: item.size,
774
- valid,
775
- error: {
776
- type: valid ? undefined : errorType,
777
- message: valid ? undefined : errorMessage,
778
- system_message: valid ? undefined : errorSystem,
779
- },
780
- progress: 0,
781
- deleted: false,
782
- xhr: false,
783
- url: false,
784
- };
785
- this.files.set(item.name, fileListItem);
786
- // validate that we haven't hit any maxfiles or maxbytes limits before we upload
787
- const { bytesMaxReached, fileMaxReached } = this.validateTotals(item.name);
788
- if (bytesMaxReached) {
789
- // in case one of the global maxes have been reached, invalidate the file
790
- this.updateValueInMap(item.name, "valid", false, false);
791
- }
792
- else if (fileMaxReached) {
793
- // in case one of the global maxes have been reached, invalidate the file
794
- this.updateValueInMap(item.name, "valid", false, false);
795
- }
796
- else if (valid && !this.external) {
797
- // if all is well AND external file upload handling has not been set, start upload
798
- const data = new FormData();
799
- data.append("file", item);
800
- data.append("uid", uid);
801
- data.append("name", item.name);
802
- data.append("metadata", JSON.stringify({ uid, url: this.uri, size: item.size }));
803
- fileListItem.xhr = await this.makeXHRPostRequest(data);
804
- }
805
- // kick the stat to force update
806
- this.kick();
807
- }
808
- }
809
- // reset the form, so that a user may upload a file again (with the same name)
810
- this.resetFormFields();
811
- this.duetChange.emit({
812
- originalEvent: ev,
813
- data: { files: this.files },
814
- component: "duet-upload",
815
- });
816
- }
817
- /**
818
- * Sets focus on the specified `duet-input`. Use this method instead of the global
819
- * `input.focus()`.
820
- */
821
- async setFocus(options) {
822
- if (this.nativeInput) {
823
- this.nativeInput.focus(options);
824
- }
825
- return;
826
- }
827
- /**
828
- * Get list of files, divided in errors and valid sections
829
- */
830
- async getFiles() {
831
- if (!this.files || this.files.size === 0) {
832
- return false;
833
- }
834
- return this.getFilesAsArray();
835
- }
836
- /**
837
- * render() function
838
- * Always the last one in the class.
839
- */
840
- render() {
841
- const identifier = this.identifier || this.uploadId;
842
- let caption = this.description.replace(/{maxfiles}/g, this.maxFiles.toString());
843
- caption = caption.replace(/{maxbytes}/g, `${Math.floor(this.maxBytes / 1024 / 1024)} MB`);
844
- caption = caption.replace(/{filetypes}/g, this.allowedExtensions.split(",").join(", "));
845
- return (h(Host, { class: { "duet-m-0": this.margin === "none" } }, h("duet-fieldset", { label: this.label, caption: caption }, h("slot", { name: "header" }), h("duet-label", { theme: this.theme === "turva" ? "turva" : "default", size: "small", class: {
846
- "duet-upload-filelist-empty": !this.files.size,
847
- "duet-upload-filelist": true,
848
- "duet-upload-filelist-filled": this.files.size,
849
- }, id: this.labelId, for: identifier }, !this.files.size && this.fileListEmpty), !!this.files.size && h("slot", { name: "fileheader" }), h(DuetUploadFileList, { data: this.getFilesAsArray(), onDelete: this.onDelete, onCancel: this.onCancel, getError: this.getI18nError }, h("li", null, "testing something")), !!this.files.size && h("slot", { name: "filefooter" }), h("duet-spacer", { size: "large" }), h("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), h("duet-spacer", { size: "medium" }), (this.fileMaxReached || this.bytesMaxReached) && (h("duet-alert", null, this.fileMaxReached && this.getI18nError("duet-upload-301"), this.bytesMaxReached && this.getI18nError("duet-upload-202"))), h("duet-spacer", { size: "medium" }), h("duet-visually-hidden", null, h("input", { ref: input => {
850
- this.nativeInput = input;
851
- }, accept: this.limitSelection ? undefined : `${this.allowedMimetypes},${this.allowedExtensions}`, onBlur: this.onBlur, onFocus: this.onFocus, onChange: e => this.onChange(e), type: "file", class: {
852
- "duet-upload": true,
853
- }, disabled: this.disabled, "aria-hidden": "true", required: this.required, name: this.name, id: this.identifier, multiple: this.multiple, capture: "user" })))));
854
- }
855
- get element() { return getElement(this); }
856
- static get watchers() { return {
857
- "valid": ["watchValidHandler"]
858
- }; }
859
- };
860
- DuetUpload.style = duetUploadCss;
861
-
862
- export { DuetUpload as duet_upload };