@lion/ui 0.24.0 → 0.26.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 (789) hide show
  1. package/README.md +25 -7
  2. package/accordion-test-suites.js +2 -0
  3. package/collapsible-test-suites.js +1 -0
  4. package/combobox-test-suites.js +2 -0
  5. package/components/accordion/test/lion-accordion.test.js +2 -565
  6. package/components/accordion/test-suites/lion-accordion.suite.js +596 -0
  7. package/components/button/test-suites/LionButton.suite.js +13 -11
  8. package/components/button/test-suites/LionButtonReset.suite.js +11 -3
  9. package/components/button/test-suites/LionButtonSubmit.suite.js +11 -3
  10. package/components/calendar/test/lion-calendar.test.js +1 -1570
  11. package/components/calendar/test-suites/LionCalendar.suite.js +1617 -5
  12. package/components/checkbox-group/test/lion-checkbox-group-integrations.test.js +5 -2
  13. package/components/checkbox-group/test/lion-checkbox-indeterminate-integrations.test.js +13 -4
  14. package/components/checkbox-group/test/lion-checkbox-integrations.test.js +4 -1
  15. package/components/checkbox-group/test-suites/CheckboxIndeterminate.suite.js +54 -54
  16. package/components/collapsible/test/lion-collapsible.test.js +2 -126
  17. package/components/collapsible/test-suites/LionCollapsible.suite.js +147 -0
  18. package/components/combobox/test/lion-combobox-integrations.test.js +11 -4
  19. package/components/combobox/test/lion-combobox.test.js +2 -3622
  20. package/components/combobox/test-suites/lion-combobox.suite.js +3665 -0
  21. package/components/core/src/ScopedElementsMixin.js +16 -1
  22. package/components/core/test-helpers/isElementVisible.js +21 -0
  23. package/components/core/test-helpers/resolveSuiteTag.js +97 -0
  24. package/components/core/types/TestSuiteTypes.ts +43 -0
  25. package/components/dialog/test/lion-dialog.integration.test.js +9 -10
  26. package/components/dialog/test/lion-dialog.test.js +2 -399
  27. package/components/dialog/test-suites/lion-dialog.suite.js +412 -0
  28. package/components/drawer/test/lion-drawer.test.js +2 -84
  29. package/components/drawer/test-suites/LionDrawer.suite.js +108 -0
  30. package/components/fieldset/test/lion-fieldset.test.js +7 -2
  31. package/components/form/test/lion-form.test.js +2 -348
  32. package/components/form/test-suites/lion-form.suite.js +398 -0
  33. package/components/form-core/test/FormatMixin.test.js +4 -1
  34. package/components/form-core/test/choice-group/CustomChoiceGroupMixin.integrations.test.js +13 -0
  35. package/components/form-core/test-suites/FormRegistrationMixins.suite.js +21 -26
  36. package/components/form-core/test-suites/FormatMixin.suite.js +45 -43
  37. package/components/form-core/test-suites/InteractionStateMixin.suite.js +19 -15
  38. package/components/form-core/test-suites/NativeTextFieldMixin.suite.js +8 -9
  39. package/components/form-core/test-suites/ValidateMixin.suite.js +14 -10
  40. package/components/form-core/test-suites/ValidateMixinFeedbackPart.suite.js +15 -2
  41. package/components/form-core/test-suites/choice-group/ChoiceGroupMixin.suite.js +55 -33
  42. package/components/form-core/test-suites/choice-group/ChoiceInputMixin.suite.js +7 -6
  43. package/components/form-core/test-suites/choice-group/CustomChoiceGroupMixin.suite.js +19 -22
  44. package/components/form-core/test-suites/form-group/FormGroupMixin-input.suite.js +14 -5
  45. package/components/form-core/test-suites/form-group/FormGroupMixin.suite.js +13 -4
  46. package/components/icon/test/lion-icon.test.js +2 -188
  47. package/components/icon/test-suites/lion-icon.suite.js +206 -0
  48. package/components/input/test/input-integrations.test.js +18 -15
  49. package/components/input/test/lion-input-integrations.test.js +7 -3
  50. package/components/input/test/lion-input.test.js +2 -198
  51. package/components/input/test-suites/lion-input.suite.js +214 -0
  52. package/components/input-amount/src/parsers.js +5 -1
  53. package/components/input-amount/test/lion-input-amount-integrations.test.js +7 -3
  54. package/components/input-amount/test/lion-input-amount.test.js +2 -421
  55. package/components/input-amount/test/parsers.test.js +12 -0
  56. package/components/input-amount/test-suites/lion-input-amount.suite.js +418 -0
  57. package/components/input-amount-dropdown/test/LionInputAmountDropdown.test.js +3 -2
  58. package/components/input-amount-dropdown/test/lion-input-amount-dropdown-integrations.test.js +4 -2
  59. package/components/input-amount-dropdown/test-suites/LionInputAmountDropdown.suite.js +6 -4
  60. package/components/input-date/test/lion-input-date-integrations.test.js +7 -3
  61. package/components/input-date/test/lion-input-date.test.js +2 -177
  62. package/components/input-date/test-suites/lion-input-date.suite.js +195 -0
  63. package/components/input-datepicker/test/lion-input-datepicker-integrations.test.js +7 -3
  64. package/components/input-datepicker/test/lion-input-datepicker.test.js +1 -844
  65. package/components/input-datepicker/test-helpers/DatepickerInputObject.js +26 -0
  66. package/components/input-datepicker/test-suites/LionInputDatepicker.suite.js +899 -14
  67. package/components/input-email/test/lion-input-email-integrations.test.js +4 -2
  68. package/components/input-email/test/lion-input-email.test.js +2 -46
  69. package/components/input-email/test-suites/lion-input-email.suite.js +63 -0
  70. package/components/input-file/test/lion-input-file.test.js +2 -1274
  71. package/components/input-file/test-suites/lion-input-file.suite.js +1505 -0
  72. package/components/input-iban/test/lion-input-iban-integrations.test.js +4 -2
  73. package/components/input-iban/test/lion-input-iban.test.js +2 -73
  74. package/components/input-iban/test-suites/lion-input-iban.suite.js +88 -0
  75. package/components/input-range/test/lion-input-range.test.js +2 -176
  76. package/components/input-range/test-suites/lion-input-range.suite.js +195 -0
  77. package/components/input-stepper/test-suites/lion-input-stepper.integration.suite.js +14 -3
  78. package/components/input-stepper/test-suites/lion-input-stepper.suite.js +14 -10
  79. package/components/input-tel/test/LionInputTel.test.js +3 -1
  80. package/components/input-tel/test/parsers.test.js +87 -0
  81. package/components/input-tel/test-helpers/mockPhoneUtilManager.js +14 -3
  82. package/components/input-tel/test-suites/LionInputTel.suite.js +9 -4
  83. package/components/input-tel-dropdown/test/LionInputTelDropdown.test.js +6 -4
  84. package/components/input-tel-dropdown/test-suites/LionInputTelDropdown--parentheses.suite.js +10 -13
  85. package/components/input-tel-dropdown/test-suites/LionInputTelDropdown.suite.js +6 -5
  86. package/components/listbox/src/LionListbox.js +1 -1
  87. package/components/listbox/test-suites/ListboxMixin.suite.js +19 -19
  88. package/components/menu/test-suites/InteractiveListMixin.suite.js +6 -9
  89. package/components/menu/test-suites/LionMenu.suite.js +6 -10
  90. package/components/menu/test-suites/LionMenuInteractions.suite.js +13 -4
  91. package/components/menu/test-suites/MoreButtonMenuMixin.suite.js +6 -9
  92. package/components/menu/test-suites/MultiLevelListMixin.suite.js +15 -11
  93. package/components/overlays/src/OverlayController.js +7 -2
  94. package/components/overlays/src/OverlayMixin.js +3 -6
  95. package/components/overlays/test/OverlayController.test.js +37 -1
  96. package/components/overlays/test/invoker-compatibility.test.js +37 -0
  97. package/components/overlays/test-suites/OverlayMixin.suite.js +3 -5
  98. package/components/pagination/test/lion-pagination.test.js +2 -176
  99. package/components/pagination/test-suites/LionPagination.suite.js +201 -0
  100. package/components/progress-indicator/test/lion-progress-indicator.test.js +2 -203
  101. package/components/progress-indicator/test-suites/lion-progress-indicator.suite.js +214 -0
  102. package/components/radio-group/test/lion-radio-group.test.js +2 -162
  103. package/components/radio-group/test/lion-radio.test.js +2 -54
  104. package/components/radio-group/test-suites/lion-radio-group.suite.js +173 -0
  105. package/components/radio-group/test-suites/lion-radio.suite.js +70 -0
  106. package/components/select/test/lion-select.test.js +2 -79
  107. package/components/select/test-suites/LionSelect.suite.js +94 -0
  108. package/components/select-rich/src/LionSelectRich.js +2 -1
  109. package/components/select-rich/test/lion-select-invoker.test.js +2 -86
  110. package/components/select-rich/test/lion-select-rich-interaction.test.js +2 -430
  111. package/components/select-rich/test/lion-select-rich.test.js +2 -1193
  112. package/components/select-rich/test-suites/lion-select-invoker.suite.js +98 -0
  113. package/components/select-rich/test-suites/lion-select-rich-interaction.suite.js +452 -0
  114. package/components/select-rich/test-suites/lion-select-rich.suite.js +1236 -0
  115. package/components/steps/test/lion-step.test.js +2 -97
  116. package/components/steps/test/lion-steps.test.js +2 -433
  117. package/components/steps/test-suites/lion-step.suite.js +113 -0
  118. package/components/steps/test-suites/lion-steps.suite.js +445 -0
  119. package/components/switch/test/lion-switch.test.js +2 -232
  120. package/components/switch/test-suites/lion-switch.suite.js +450 -0
  121. package/components/tabs/test/lion-tabs.test.js +2 -596
  122. package/components/tabs/test-suites/lion-tabs.suite.js +617 -0
  123. package/components/textarea/src/LionTextarea.js +5 -2
  124. package/components/textarea/test/lion-textarea.test.js +2 -159
  125. package/components/textarea/test-suites/lion-textarea.suite.js +192 -0
  126. package/components/tooltip/test/lion-tooltip.test.js +2 -393
  127. package/components/tooltip/test-suites/lion-tooltip.suite.js +409 -0
  128. package/custom-elements.json +14890 -10187
  129. package/dialog-test-suites.js +2 -0
  130. package/dist-types/components/accordion/test/lion-accordion.test.d.ts +1 -2
  131. package/dist-types/components/accordion/test/lion-accordion.test.d.ts.map +1 -1
  132. package/dist-types/components/accordion/test-suites/lion-accordion.suite.d.ts +18 -0
  133. package/dist-types/components/accordion/test-suites/lion-accordion.suite.d.ts.map +1 -0
  134. package/dist-types/components/button/test-suites/LionButton.suite.d.ts +10 -4
  135. package/dist-types/components/button/test-suites/LionButton.suite.d.ts.map +1 -1
  136. package/dist-types/components/button/test-suites/LionButtonReset.suite.d.ts +10 -4
  137. package/dist-types/components/button/test-suites/LionButtonReset.suite.d.ts.map +1 -1
  138. package/dist-types/components/button/test-suites/LionButtonSubmit.suite.d.ts +10 -4
  139. package/dist-types/components/button/test-suites/LionButtonSubmit.suite.d.ts.map +1 -1
  140. package/dist-types/components/calendar/test/lion-calendar.test.d.ts +1 -3
  141. package/dist-types/components/calendar/test/lion-calendar.test.d.ts.map +1 -1
  142. package/dist-types/components/calendar/test-suites/LionCalendar.suite.d.ts +13 -4
  143. package/dist-types/components/calendar/test-suites/LionCalendar.suite.d.ts.map +1 -1
  144. package/dist-types/components/checkbox-group/test/lion-checkbox-group-integrations.test.d.ts.map +1 -1
  145. package/dist-types/components/checkbox-group/test/lion-checkbox-integrations.test.d.ts.map +1 -1
  146. package/dist-types/components/checkbox-group/test-suites/CheckboxIndeterminate.suite.d.ts +12 -9
  147. package/dist-types/components/checkbox-group/test-suites/CheckboxIndeterminate.suite.d.ts.map +1 -1
  148. package/dist-types/components/collapsible/test/lion-collapsible.test.d.ts +1 -3
  149. package/dist-types/components/collapsible/test/lion-collapsible.test.d.ts.map +1 -1
  150. package/dist-types/components/collapsible/test-suites/LionCollapsible.suite.d.ts +18 -0
  151. package/dist-types/components/collapsible/test-suites/LionCollapsible.suite.d.ts.map +1 -0
  152. package/dist-types/components/combobox/test/lion-combobox.test.d.ts +1 -5
  153. package/dist-types/components/combobox/test/lion-combobox.test.d.ts.map +1 -1
  154. package/dist-types/components/combobox/test-suites/lion-combobox.suite.d.ts +17 -0
  155. package/dist-types/components/combobox/test-suites/lion-combobox.suite.d.ts.map +1 -0
  156. package/dist-types/components/core/src/ScopedElementsMixin.d.ts.map +1 -1
  157. package/dist-types/components/core/test-helpers/isElementVisible.d.ts +12 -0
  158. package/dist-types/components/core/test-helpers/isElementVisible.d.ts.map +1 -0
  159. package/dist-types/components/core/test-helpers/resolveSuiteTag.d.ts +29 -0
  160. package/dist-types/components/core/test-helpers/resolveSuiteTag.d.ts.map +1 -0
  161. package/dist-types/components/core/types/TestSuiteTypes.d.ts +40 -0
  162. package/dist-types/components/core/types/TestSuiteTypes.d.ts.map +1 -0
  163. package/dist-types/components/dialog/test/lion-dialog.integration.test.d.ts.map +1 -1
  164. package/dist-types/components/dialog/test/lion-dialog.test.d.ts +1 -5
  165. package/dist-types/components/dialog/test/lion-dialog.test.d.ts.map +1 -1
  166. package/dist-types/components/dialog/test-suites/lion-dialog.suite.d.ts +19 -0
  167. package/dist-types/components/dialog/test-suites/lion-dialog.suite.d.ts.map +1 -0
  168. package/dist-types/components/drawer/test/lion-drawer.test.d.ts +1 -3
  169. package/dist-types/components/drawer/test/lion-drawer.test.d.ts.map +1 -1
  170. package/dist-types/components/drawer/test-suites/LionDrawer.suite.d.ts +20 -0
  171. package/dist-types/components/drawer/test-suites/LionDrawer.suite.d.ts.map +1 -0
  172. package/dist-types/components/fieldset/test/lion-fieldset.test.d.ts.map +1 -1
  173. package/dist-types/components/form/test/lion-form.test.d.ts +1 -12
  174. package/dist-types/components/form/test/lion-form.test.d.ts.map +1 -1
  175. package/dist-types/components/form/test-suites/lion-form.suite.d.ts +39 -0
  176. package/dist-types/components/form/test-suites/lion-form.suite.d.ts.map +1 -0
  177. package/dist-types/components/form-core/test-suites/FormRegistrationMixins.suite.d.ts +14 -17
  178. package/dist-types/components/form-core/test-suites/FormRegistrationMixins.suite.d.ts.map +1 -1
  179. package/dist-types/components/form-core/test-suites/FormatMixin.suite.d.ts +22 -38
  180. package/dist-types/components/form-core/test-suites/FormatMixin.suite.d.ts.map +1 -1
  181. package/dist-types/components/form-core/test-suites/InteractionStateMixin.suite.d.ts +11 -5
  182. package/dist-types/components/form-core/test-suites/InteractionStateMixin.suite.d.ts.map +1 -1
  183. package/dist-types/components/form-core/test-suites/NativeTextFieldMixin.suite.d.ts +9 -4
  184. package/dist-types/components/form-core/test-suites/NativeTextFieldMixin.suite.d.ts.map +1 -1
  185. package/dist-types/components/form-core/test-suites/ValidateMixin.suite.d.ts +9 -4
  186. package/dist-types/components/form-core/test-suites/ValidateMixin.suite.d.ts.map +1 -1
  187. package/dist-types/components/form-core/test-suites/ValidateMixinFeedbackPart.suite.d.ts +10 -1
  188. package/dist-types/components/form-core/test-suites/ValidateMixinFeedbackPart.suite.d.ts.map +1 -1
  189. package/dist-types/components/form-core/test-suites/choice-group/ChoiceGroupMixin.suite.d.ts +17 -6
  190. package/dist-types/components/form-core/test-suites/choice-group/ChoiceGroupMixin.suite.d.ts.map +1 -1
  191. package/dist-types/components/form-core/test-suites/choice-group/ChoiceInputMixin.suite.d.ts +5 -2
  192. package/dist-types/components/form-core/test-suites/choice-group/ChoiceInputMixin.suite.d.ts.map +1 -1
  193. package/dist-types/components/form-core/test-suites/choice-group/CustomChoiceGroupMixin.suite.d.ts +10 -5
  194. package/dist-types/components/form-core/test-suites/choice-group/CustomChoiceGroupMixin.suite.d.ts.map +1 -1
  195. package/dist-types/components/form-core/test-suites/form-group/FormGroupMixin-input.suite.d.ts +10 -5
  196. package/dist-types/components/form-core/test-suites/form-group/FormGroupMixin-input.suite.d.ts.map +1 -1
  197. package/dist-types/components/form-core/test-suites/form-group/FormGroupMixin.suite.d.ts +10 -5
  198. package/dist-types/components/form-core/test-suites/form-group/FormGroupMixin.suite.d.ts.map +1 -1
  199. package/dist-types/components/icon/test/lion-icon.test.d.ts +1 -4
  200. package/dist-types/components/icon/test/lion-icon.test.d.ts.map +1 -1
  201. package/dist-types/components/icon/test-suites/lion-icon.suite.d.ts +16 -0
  202. package/dist-types/components/icon/test-suites/lion-icon.suite.d.ts.map +1 -0
  203. package/dist-types/components/input/test/lion-input-integrations.test.d.ts.map +1 -1
  204. package/dist-types/components/input/test/lion-input.test.d.ts +1 -2
  205. package/dist-types/components/input/test/lion-input.test.d.ts.map +1 -1
  206. package/dist-types/components/input/test-suites/lion-input.suite.d.ts +17 -0
  207. package/dist-types/components/input/test-suites/lion-input.suite.d.ts.map +1 -0
  208. package/dist-types/components/input-amount/src/parsers.d.ts.map +1 -1
  209. package/dist-types/components/input-amount/test/lion-input-amount-integrations.test.d.ts.map +1 -1
  210. package/dist-types/components/input-amount/test/lion-input-amount.test.d.ts +1 -2
  211. package/dist-types/components/input-amount/test/lion-input-amount.test.d.ts.map +1 -1
  212. package/dist-types/components/input-amount/test-suites/lion-input-amount.suite.d.ts +19 -0
  213. package/dist-types/components/input-amount/test-suites/lion-input-amount.suite.d.ts.map +1 -0
  214. package/dist-types/components/input-amount-dropdown/test/lion-input-amount-dropdown-integrations.test.d.ts.map +1 -1
  215. package/dist-types/components/input-amount-dropdown/test-suites/LionInputAmountDropdown.suite.d.ts +7 -3
  216. package/dist-types/components/input-amount-dropdown/test-suites/LionInputAmountDropdown.suite.d.ts.map +1 -1
  217. package/dist-types/components/input-date/test/lion-input-date-integrations.test.d.ts.map +1 -1
  218. package/dist-types/components/input-date/test/lion-input-date.test.d.ts +1 -3
  219. package/dist-types/components/input-date/test/lion-input-date.test.d.ts.map +1 -1
  220. package/dist-types/components/input-date/test-suites/lion-input-date.suite.d.ts +15 -0
  221. package/dist-types/components/input-date/test-suites/lion-input-date.suite.d.ts.map +1 -0
  222. package/dist-types/components/input-datepicker/test/lion-input-datepicker-integrations.test.d.ts.map +1 -1
  223. package/dist-types/components/input-datepicker/test/lion-input-datepicker.test.d.ts +1 -2
  224. package/dist-types/components/input-datepicker/test/lion-input-datepicker.test.d.ts.map +1 -1
  225. package/dist-types/components/input-datepicker/test-helpers/DatepickerInputObject.d.ts +8 -0
  226. package/dist-types/components/input-datepicker/test-helpers/DatepickerInputObject.d.ts.map +1 -1
  227. package/dist-types/components/input-datepicker/test-suites/LionInputDatepicker.suite.d.ts +15 -5
  228. package/dist-types/components/input-datepicker/test-suites/LionInputDatepicker.suite.d.ts.map +1 -1
  229. package/dist-types/components/input-email/test/lion-input-email-integrations.test.d.ts.map +1 -1
  230. package/dist-types/components/input-email/test/lion-input-email.test.d.ts +1 -3
  231. package/dist-types/components/input-email/test/lion-input-email.test.d.ts.map +1 -1
  232. package/dist-types/components/input-email/test-suites/lion-input-email.suite.d.ts +15 -0
  233. package/dist-types/components/input-email/test-suites/lion-input-email.suite.d.ts.map +1 -0
  234. package/dist-types/components/input-file/test/lion-input-file.test.d.ts +1 -5
  235. package/dist-types/components/input-file/test/lion-input-file.test.d.ts.map +1 -1
  236. package/dist-types/components/input-file/test-suites/lion-input-file.suite.d.ts +19 -0
  237. package/dist-types/components/input-file/test-suites/lion-input-file.suite.d.ts.map +1 -0
  238. package/dist-types/components/input-iban/test/lion-input-iban-integrations.test.d.ts.map +1 -1
  239. package/dist-types/components/input-iban/test/lion-input-iban.test.d.ts +1 -3
  240. package/dist-types/components/input-iban/test/lion-input-iban.test.d.ts.map +1 -1
  241. package/dist-types/components/input-iban/test-suites/lion-input-iban.suite.d.ts +15 -0
  242. package/dist-types/components/input-iban/test-suites/lion-input-iban.suite.d.ts.map +1 -0
  243. package/dist-types/components/input-range/test/lion-input-range.test.d.ts +1 -3
  244. package/dist-types/components/input-range/test/lion-input-range.test.d.ts.map +1 -1
  245. package/dist-types/components/input-range/test-suites/lion-input-range.suite.d.ts +15 -0
  246. package/dist-types/components/input-range/test-suites/lion-input-range.suite.d.ts.map +1 -0
  247. package/dist-types/components/input-stepper/test-suites/lion-input-stepper.integration.suite.d.ts +10 -2
  248. package/dist-types/components/input-stepper/test-suites/lion-input-stepper.integration.suite.d.ts.map +1 -1
  249. package/dist-types/components/input-stepper/test-suites/lion-input-stepper.suite.d.ts +10 -2
  250. package/dist-types/components/input-stepper/test-suites/lion-input-stepper.suite.d.ts.map +1 -1
  251. package/dist-types/components/input-tel/test-helpers/mockPhoneUtilManager.d.ts +5 -0
  252. package/dist-types/components/input-tel/test-helpers/mockPhoneUtilManager.d.ts.map +1 -1
  253. package/dist-types/components/input-tel/test-suites/LionInputTel.suite.d.ts +6 -4
  254. package/dist-types/components/input-tel/test-suites/LionInputTel.suite.d.ts.map +1 -1
  255. package/dist-types/components/input-tel-dropdown/test-suites/LionInputTelDropdown--parentheses.suite.d.ts +7 -3
  256. package/dist-types/components/input-tel-dropdown/test-suites/LionInputTelDropdown--parentheses.suite.d.ts.map +1 -1
  257. package/dist-types/components/input-tel-dropdown/test-suites/LionInputTelDropdown.suite.d.ts +7 -3
  258. package/dist-types/components/input-tel-dropdown/test-suites/LionInputTelDropdown.suite.d.ts.map +1 -1
  259. package/dist-types/components/listbox/src/LionListbox.d.ts +2 -2
  260. package/dist-types/components/listbox/src/LionListbox.d.ts.map +1 -1
  261. package/dist-types/components/listbox/test-suites/ListboxMixin.suite.d.ts +3 -4
  262. package/dist-types/components/listbox/test-suites/ListboxMixin.suite.d.ts.map +1 -1
  263. package/dist-types/components/menu/test-suites/InteractiveListMixin.suite.d.ts +6 -5
  264. package/dist-types/components/menu/test-suites/InteractiveListMixin.suite.d.ts.map +1 -1
  265. package/dist-types/components/menu/test-suites/LionMenu.suite.d.ts +6 -5
  266. package/dist-types/components/menu/test-suites/LionMenu.suite.d.ts.map +1 -1
  267. package/dist-types/components/menu/test-suites/LionMenuInteractions.suite.d.ts +10 -4
  268. package/dist-types/components/menu/test-suites/LionMenuInteractions.suite.d.ts.map +1 -1
  269. package/dist-types/components/menu/test-suites/MoreButtonMenuMixin.suite.d.ts +6 -5
  270. package/dist-types/components/menu/test-suites/MoreButtonMenuMixin.suite.d.ts.map +1 -1
  271. package/dist-types/components/menu/test-suites/MultiLevelListMixin.suite.d.ts +7 -6
  272. package/dist-types/components/menu/test-suites/MultiLevelListMixin.suite.d.ts.map +1 -1
  273. package/dist-types/components/overlays/src/OverlayController.d.ts +3 -1
  274. package/dist-types/components/overlays/src/OverlayController.d.ts.map +1 -1
  275. package/dist-types/components/overlays/src/OverlayMixin.d.ts.map +1 -1
  276. package/dist-types/components/overlays/test/invoker-compatibility.test.d.ts +3 -0
  277. package/dist-types/components/overlays/test/invoker-compatibility.test.d.ts.map +1 -0
  278. package/dist-types/components/overlays/test-suites/OverlayMixin.suite.d.ts.map +1 -1
  279. package/dist-types/components/pagination/test/lion-pagination.test.d.ts +1 -3
  280. package/dist-types/components/pagination/test/lion-pagination.test.d.ts.map +1 -1
  281. package/dist-types/components/pagination/test-suites/LionPagination.suite.d.ts +18 -0
  282. package/dist-types/components/pagination/test-suites/LionPagination.suite.d.ts.map +1 -0
  283. package/dist-types/components/progress-indicator/test/lion-progress-indicator.test.d.ts +1 -3
  284. package/dist-types/components/progress-indicator/test/lion-progress-indicator.test.d.ts.map +1 -1
  285. package/dist-types/components/progress-indicator/test-suites/lion-progress-indicator.suite.d.ts +15 -0
  286. package/dist-types/components/progress-indicator/test-suites/lion-progress-indicator.suite.d.ts.map +1 -0
  287. package/dist-types/components/radio-group/test/lion-radio-group.test.d.ts +1 -5
  288. package/dist-types/components/radio-group/test/lion-radio-group.test.d.ts.map +1 -1
  289. package/dist-types/components/radio-group/test/lion-radio.test.d.ts +1 -2
  290. package/dist-types/components/radio-group/test/lion-radio.test.d.ts.map +1 -1
  291. package/dist-types/components/radio-group/test-suites/lion-radio-group.suite.d.ts +19 -0
  292. package/dist-types/components/radio-group/test-suites/lion-radio-group.suite.d.ts.map +1 -0
  293. package/dist-types/components/radio-group/test-suites/lion-radio.suite.d.ts +17 -0
  294. package/dist-types/components/radio-group/test-suites/lion-radio.suite.d.ts.map +1 -0
  295. package/dist-types/components/select/test/lion-select.test.d.ts +1 -2
  296. package/dist-types/components/select/test/lion-select.test.d.ts.map +1 -1
  297. package/dist-types/components/select/test-suites/LionSelect.suite.d.ts +16 -0
  298. package/dist-types/components/select/test-suites/LionSelect.suite.d.ts.map +1 -0
  299. package/dist-types/components/select-rich/src/LionSelectRich.d.ts +5 -4
  300. package/dist-types/components/select-rich/src/LionSelectRich.d.ts.map +1 -1
  301. package/dist-types/components/select-rich/test/lion-select-invoker.test.d.ts +1 -2
  302. package/dist-types/components/select-rich/test/lion-select-invoker.test.d.ts.map +1 -1
  303. package/dist-types/components/select-rich/test/lion-select-rich-interaction.test.d.ts +1 -5
  304. package/dist-types/components/select-rich/test/lion-select-rich-interaction.test.d.ts.map +1 -1
  305. package/dist-types/components/select-rich/test/lion-select-rich.test.d.ts +1 -8
  306. package/dist-types/components/select-rich/test/lion-select-rich.test.d.ts.map +1 -1
  307. package/dist-types/components/select-rich/test-suites/lion-select-invoker.suite.d.ts +19 -0
  308. package/dist-types/components/select-rich/test-suites/lion-select-invoker.suite.d.ts.map +1 -0
  309. package/dist-types/components/select-rich/test-suites/lion-select-rich-interaction.suite.d.ts +19 -0
  310. package/dist-types/components/select-rich/test-suites/lion-select-rich-interaction.suite.d.ts.map +1 -0
  311. package/dist-types/components/select-rich/test-suites/lion-select-rich.suite.d.ts +21 -0
  312. package/dist-types/components/select-rich/test-suites/lion-select-rich.suite.d.ts.map +1 -0
  313. package/dist-types/components/steps/test/lion-step.test.d.ts +1 -2
  314. package/dist-types/components/steps/test/lion-step.test.d.ts.map +1 -1
  315. package/dist-types/components/steps/test/lion-steps.test.d.ts +1 -8
  316. package/dist-types/components/steps/test/lion-steps.test.d.ts.map +1 -1
  317. package/dist-types/components/steps/test-suites/lion-step.suite.d.ts +17 -0
  318. package/dist-types/components/steps/test-suites/lion-step.suite.d.ts.map +1 -0
  319. package/dist-types/components/steps/test-suites/lion-steps.suite.d.ts +22 -0
  320. package/dist-types/components/steps/test-suites/lion-steps.suite.d.ts.map +1 -0
  321. package/dist-types/components/switch/test/lion-switch.test.d.ts +1 -4
  322. package/dist-types/components/switch/test/lion-switch.test.d.ts.map +1 -1
  323. package/dist-types/components/switch/test-suites/lion-switch.suite.d.ts +17 -0
  324. package/dist-types/components/switch/test-suites/lion-switch.suite.d.ts.map +1 -0
  325. package/dist-types/components/tabs/test/lion-tabs.test.d.ts +1 -5
  326. package/dist-types/components/tabs/test/lion-tabs.test.d.ts.map +1 -1
  327. package/dist-types/components/tabs/test-suites/lion-tabs.suite.d.ts +17 -0
  328. package/dist-types/components/tabs/test-suites/lion-tabs.suite.d.ts.map +1 -0
  329. package/dist-types/components/textarea/src/LionTextarea.d.ts.map +1 -1
  330. package/dist-types/components/textarea/test/lion-textarea.test.d.ts +1 -3
  331. package/dist-types/components/textarea/test/lion-textarea.test.d.ts.map +1 -1
  332. package/dist-types/components/textarea/test-suites/lion-textarea.suite.d.ts +15 -0
  333. package/dist-types/components/textarea/test-suites/lion-textarea.suite.d.ts.map +1 -0
  334. package/dist-types/components/tooltip/test/lion-tooltip.test.d.ts +1 -3
  335. package/dist-types/components/tooltip/test/lion-tooltip.test.d.ts.map +1 -1
  336. package/dist-types/components/tooltip/test-suites/lion-tooltip.suite.d.ts +19 -0
  337. package/dist-types/components/tooltip/test-suites/lion-tooltip.suite.d.ts.map +1 -0
  338. package/dist-types/exports/accordion-test-suites.d.ts +2 -0
  339. package/dist-types/exports/accordion-test-suites.d.ts.map +1 -0
  340. package/dist-types/exports/collapsible-test-suites.d.ts +2 -0
  341. package/dist-types/exports/collapsible-test-suites.d.ts.map +1 -0
  342. package/dist-types/exports/combobox-test-suites.d.ts +2 -0
  343. package/dist-types/exports/combobox-test-suites.d.ts.map +1 -0
  344. package/dist-types/exports/dialog-test-suites.d.ts +2 -0
  345. package/dist-types/exports/dialog-test-suites.d.ts.map +1 -0
  346. package/dist-types/exports/drawer-test-suites.d.ts +2 -0
  347. package/dist-types/exports/drawer-test-suites.d.ts.map +1 -0
  348. package/dist-types/exports/form-test-suites.d.ts +2 -0
  349. package/dist-types/exports/form-test-suites.d.ts.map +1 -0
  350. package/dist-types/exports/icon-test-suites.d.ts +2 -0
  351. package/dist-types/exports/icon-test-suites.d.ts.map +1 -0
  352. package/dist-types/exports/input-amount-test-suites.d.ts +2 -0
  353. package/dist-types/exports/input-amount-test-suites.d.ts.map +1 -0
  354. package/dist-types/exports/input-date-test-suites.d.ts +2 -0
  355. package/dist-types/exports/input-date-test-suites.d.ts.map +1 -0
  356. package/dist-types/exports/input-email-test-suites.d.ts +2 -0
  357. package/dist-types/exports/input-email-test-suites.d.ts.map +1 -0
  358. package/dist-types/exports/input-file-test-suites.d.ts +2 -0
  359. package/dist-types/exports/input-file-test-suites.d.ts.map +1 -0
  360. package/dist-types/exports/input-iban-test-suites.d.ts +2 -0
  361. package/dist-types/exports/input-iban-test-suites.d.ts.map +1 -0
  362. package/dist-types/exports/input-range-test-suites.d.ts +2 -0
  363. package/dist-types/exports/input-range-test-suites.d.ts.map +1 -0
  364. package/dist-types/exports/input-stepper-suites.d.ts +7 -2
  365. package/dist-types/exports/input-stepper-suites.d.ts.map +1 -1
  366. package/dist-types/exports/input-test-suites.d.ts +2 -0
  367. package/dist-types/exports/input-test-suites.d.ts.map +1 -0
  368. package/dist-types/exports/menu-test-suites.d.ts.map +1 -1
  369. package/dist-types/exports/pagination-test-suites.d.ts +2 -0
  370. package/dist-types/exports/pagination-test-suites.d.ts.map +1 -0
  371. package/dist-types/exports/progress-indicator-test-suites.d.ts +2 -0
  372. package/dist-types/exports/progress-indicator-test-suites.d.ts.map +1 -0
  373. package/dist-types/exports/radio-group-test-suites.d.ts +3 -0
  374. package/dist-types/exports/radio-group-test-suites.d.ts.map +1 -0
  375. package/dist-types/exports/select-rich-test-suites.d.ts +4 -0
  376. package/dist-types/exports/select-rich-test-suites.d.ts.map +1 -0
  377. package/dist-types/exports/select-test-suites.d.ts +2 -0
  378. package/dist-types/exports/select-test-suites.d.ts.map +1 -0
  379. package/dist-types/exports/steps-test-suites.d.ts +3 -0
  380. package/dist-types/exports/steps-test-suites.d.ts.map +1 -0
  381. package/dist-types/exports/switch-test-suites.d.ts +2 -0
  382. package/dist-types/exports/switch-test-suites.d.ts.map +1 -0
  383. package/dist-types/exports/tabs-test-suites.d.ts +2 -0
  384. package/dist-types/exports/tabs-test-suites.d.ts.map +1 -0
  385. package/dist-types/exports/textarea-test-suites.d.ts +2 -0
  386. package/dist-types/exports/textarea-test-suites.d.ts.map +1 -0
  387. package/dist-types/exports/tooltip-test-suites.d.ts +2 -0
  388. package/dist-types/exports/tooltip-test-suites.d.ts.map +1 -0
  389. package/dist-types/exports/types/test-suites.d.ts +4 -0
  390. package/dist-types/exports/types/test-suites.d.ts.map +1 -0
  391. package/dist-types/tsconfig.tsbuildinfo +1 -1
  392. package/drawer-test-suites.js +1 -0
  393. package/exports/accordion-test-suites.js +2 -0
  394. package/exports/collapsible-test-suites.js +1 -0
  395. package/exports/combobox-test-suites.js +2 -0
  396. package/exports/dialog-test-suites.js +2 -0
  397. package/exports/drawer-test-suites.js +1 -0
  398. package/exports/form-test-suites.js +2 -0
  399. package/exports/icon-test-suites.js +2 -0
  400. package/exports/input-amount-test-suites.js +2 -0
  401. package/exports/input-date-test-suites.js +2 -0
  402. package/exports/input-email-test-suites.js +2 -0
  403. package/exports/input-file-test-suites.js +2 -0
  404. package/exports/input-iban-test-suites.js +2 -0
  405. package/exports/input-range-test-suites.js +2 -0
  406. package/exports/input-stepper-suites.js +18 -4
  407. package/exports/input-test-suites.js +2 -0
  408. package/exports/menu-test-suites.js +3 -0
  409. package/exports/pagination-test-suites.js +1 -0
  410. package/exports/progress-indicator-test-suites.js +2 -0
  411. package/exports/radio-group-test-suites.js +3 -0
  412. package/exports/select-rich-test-suites.js +4 -0
  413. package/exports/select-test-suites.js +1 -0
  414. package/exports/steps-test-suites.js +3 -0
  415. package/exports/switch-test-suites.js +2 -0
  416. package/exports/tabs-test-suites.js +2 -0
  417. package/exports/textarea-test-suites.js +2 -0
  418. package/exports/tooltip-test-suites.js +2 -0
  419. package/exports/types/test-suites.ts +3 -0
  420. package/form-test-suites.js +2 -0
  421. package/generated/awesome-phonenumber/provenance.json +1 -1
  422. package/icon-test-suites.js +2 -0
  423. package/input-amount-test-suites.js +2 -0
  424. package/input-date-test-suites.js +2 -0
  425. package/input-email-test-suites.js +2 -0
  426. package/input-file-test-suites.js +2 -0
  427. package/input-iban-test-suites.js +2 -0
  428. package/input-range-test-suites.js +2 -0
  429. package/input-stepper-suites.js +18 -4
  430. package/input-test-suites.js +2 -0
  431. package/menu-test-suites.js +3 -0
  432. package/package.json +11 -7
  433. package/pagination-test-suites.js +1 -0
  434. package/progress-indicator-test-suites.js +2 -0
  435. package/radio-group-test-suites.js +3 -0
  436. package/select-rich-test-suites.js +4 -0
  437. package/select-test-suites.js +1 -0
  438. package/steps-test-suites.js +3 -0
  439. package/switch-test-suites.js +2 -0
  440. package/tabs-test-suites.js +2 -0
  441. package/textarea-test-suites.js +2 -0
  442. package/tooltip-test-suites.js +2 -0
  443. package/vscode.html-custom-data.json +60 -5
  444. package/web-types.json +219 -1
  445. package/components/button/test/demos.screenshots-test.js +0 -100
  446. package/components/calendar/test/demos.screenshots-test.js +0 -118
  447. package/components/input-file/test/lion-selected-file-list.test.js +0 -199
  448. package/components/select-rich/test/demos.screenshots-test.js +0 -168
  449. package/components/switch/test/lion-switch-button.test.js +0 -204
  450. package/dist-types/components/button/test/demos.screenshots-test.d.ts +0 -2
  451. package/dist-types/components/button/test/demos.screenshots-test.d.ts.map +0 -1
  452. package/dist-types/components/calendar/test/demos.screenshots-test.d.ts +0 -2
  453. package/dist-types/components/calendar/test/demos.screenshots-test.d.ts.map +0 -1
  454. package/dist-types/components/input-file/test/lion-selected-file-list.test.d.ts +0 -5
  455. package/dist-types/components/input-file/test/lion-selected-file-list.test.d.ts.map +0 -1
  456. package/dist-types/components/select-rich/test/demos.screenshots-test.d.ts +0 -2
  457. package/dist-types/components/select-rich/test/demos.screenshots-test.d.ts.map +0 -1
  458. package/dist-types/components/switch/test/lion-switch-button.test.d.ts +0 -4
  459. package/dist-types/components/switch/test/lion-switch-button.test.d.ts.map +0 -1
  460. package/docs/components/accordion/api-table.md +0 -53
  461. package/docs/components/accordion/index.md +0 -13
  462. package/docs/components/accordion/overview.md +0 -141
  463. package/docs/components/accordion/reference.md +0 -59
  464. package/docs/components/accordion/use-cases.md +0 -303
  465. package/docs/components/button/api-table.md +0 -84
  466. package/docs/components/button/assets/bootstrap-button.js +0 -245
  467. package/docs/components/button/examples.md +0 -42
  468. package/docs/components/button/extensions.md +0 -42
  469. package/docs/components/button/index.md +0 -13
  470. package/docs/components/button/overview.md +0 -42
  471. package/docs/components/button/src/icon.svg.js +0 -5
  472. package/docs/components/button/use-cases.md +0 -121
  473. package/docs/components/calendar/api-table.md +0 -56
  474. package/docs/components/calendar/index.md +0 -13
  475. package/docs/components/calendar/overview.md +0 -61
  476. package/docs/components/calendar/use-cases.md +0 -243
  477. package/docs/components/checkbox-group/api-table.md +0 -117
  478. package/docs/components/checkbox-group/index.md +0 -13
  479. package/docs/components/checkbox-group/overview.md +0 -51
  480. package/docs/components/checkbox-group/use-cases.md +0 -192
  481. package/docs/components/collapsible/api-table.md +0 -55
  482. package/docs/components/collapsible/assets/CustomCollapsible.js +0 -117
  483. package/docs/components/collapsible/assets/applyDemoCollapsibleStyles.js +0 -41
  484. package/docs/components/collapsible/examples.md +0 -95
  485. package/docs/components/collapsible/index.md +0 -13
  486. package/docs/components/collapsible/overview.md +0 -51
  487. package/docs/components/collapsible/use-cases.md +0 -91
  488. package/docs/components/combobox/api-table.md +0 -122
  489. package/docs/components/combobox/extensions.md +0 -174
  490. package/docs/components/combobox/index.md +0 -13
  491. package/docs/components/combobox/overview.md +0 -74
  492. package/docs/components/combobox/src/LinkMixin.js +0 -60
  493. package/docs/components/combobox/src/demo-selection-display.js +0 -164
  494. package/docs/components/combobox/src/gh-combobox/gh-button.js +0 -71
  495. package/docs/components/combobox/src/gh-combobox/gh-combobox.js +0 -515
  496. package/docs/components/combobox/src/google-combobox/assets/google-clear-icon.js +0 -9
  497. package/docs/components/combobox/src/google-combobox/assets/google-search-icon.js +0 -9
  498. package/docs/components/combobox/src/google-combobox/assets/google-voice-search-icon.js +0 -19
  499. package/docs/components/combobox/src/google-combobox/google-combobox.js +0 -461
  500. package/docs/components/combobox/src/lazyRender.js +0 -29
  501. package/docs/components/combobox/src/levenshtein.js +0 -95
  502. package/docs/components/combobox/src/md-combobox/MdFieldMixin.js +0 -345
  503. package/docs/components/combobox/src/md-combobox/md-combobox.js +0 -91
  504. package/docs/components/combobox/src/md-combobox/md-input.js +0 -5
  505. package/docs/components/combobox/src/md-combobox/style/load-roboto.js +0 -6
  506. package/docs/components/combobox/src/md-combobox/style/md-ripple.js +0 -82
  507. package/docs/components/combobox/src/wa-combobox/wa-combobox.js +0 -375
  508. package/docs/components/combobox/use-cases.md +0 -561
  509. package/docs/components/dialog/api-table.md +0 -61
  510. package/docs/components/dialog/index.md +0 -13
  511. package/docs/components/dialog/overview.md +0 -71
  512. package/docs/components/dialog/src/demoStyle.js +0 -57
  513. package/docs/components/dialog/src/external-dialog.js +0 -32
  514. package/docs/components/dialog/src/slots-dialog-content.js +0 -32
  515. package/docs/components/dialog/src/styled-dialog-content.js +0 -38
  516. package/docs/components/dialog/use-cases.md +0 -199
  517. package/docs/components/drawer/api-table.md +0 -64
  518. package/docs/components/drawer/index.md +0 -13
  519. package/docs/components/drawer/overview.md +0 -80
  520. package/docs/components/drawer/src/demoStyle.js +0 -71
  521. package/docs/components/drawer/use-cases.md +0 -206
  522. package/docs/components/fieldset/api-table.md +0 -24
  523. package/docs/components/fieldset/index.md +0 -13
  524. package/docs/components/fieldset/overview.md +0 -61
  525. package/docs/components/fieldset/use-cases.md +0 -203
  526. package/docs/components/form/api-table.md +0 -12
  527. package/docs/components/form/index.md +0 -13
  528. package/docs/components/form/overview.md +0 -66
  529. package/docs/components/form/use-cases.md +0 -230
  530. package/docs/components/icon/api-table.md +0 -41
  531. package/docs/components/icon/assets/bugs/bug01.svg.js +0 -2
  532. package/docs/components/icon/assets/bugs/bug02.svg.js +0 -2
  533. package/docs/components/icon/assets/bugs/bug05.svg.js +0 -2
  534. package/docs/components/icon/assets/bugs/bug06.svg.js +0 -2
  535. package/docs/components/icon/assets/bugs/bug08.svg.js +0 -2
  536. package/docs/components/icon/assets/bugs/bug12.svg.js +0 -2
  537. package/docs/components/icon/assets/bugs/bug19.svg.js +0 -2
  538. package/docs/components/icon/assets/bugs/bug23.svg.js +0 -2
  539. package/docs/components/icon/assets/bugs/bug24.svg.js +0 -2
  540. package/docs/components/icon/assets/iconset-bugs.js +0 -11
  541. package/docs/components/icon/assets/iconset-misc.js +0 -3
  542. package/docs/components/icon/assets/iconset-space.js +0 -31
  543. package/docs/components/icon/assets/misc/arrowLeft.svg.js +0 -6
  544. package/docs/components/icon/assets/space/aliens-spaceship.svg.js +0 -2
  545. package/docs/components/icon/assets/space/meteor.svg.js +0 -2
  546. package/docs/components/icon/assets/space/moon-flag.svg.js +0 -2
  547. package/docs/components/icon/assets/space/moon.svg.js +0 -2
  548. package/docs/components/icon/assets/space/night.svg.js +0 -2
  549. package/docs/components/icon/assets/space/orbit.svg.js +0 -2
  550. package/docs/components/icon/assets/space/planet.svg.js +0 -2
  551. package/docs/components/icon/assets/space/robot.svg.js +0 -2
  552. package/docs/components/icon/assets/space/rocket.svg.js +0 -2
  553. package/docs/components/icon/assets/space/satellite.svg.js +0 -2
  554. package/docs/components/icon/assets/space/signal.svg.js +0 -2
  555. package/docs/components/icon/assets/space/space-helmet.svg.js +0 -2
  556. package/docs/components/icon/assets/space/sun.svg.js +0 -2
  557. package/docs/components/icon/assets/space/telescope.svg.js +0 -2
  558. package/docs/components/icon/index.md +0 -13
  559. package/docs/components/icon/overview.md +0 -52
  560. package/docs/components/icon/use-cases.md +0 -92
  561. package/docs/components/index.md +0 -17
  562. package/docs/components/input/api-table.md +0 -52
  563. package/docs/components/input/index.md +0 -13
  564. package/docs/components/input/overview.md +0 -48
  565. package/docs/components/input/use-cases.md +0 -90
  566. package/docs/components/input-amount/api-table.md +0 -66
  567. package/docs/components/input-amount/index.md +0 -13
  568. package/docs/components/input-amount/overview.md +0 -61
  569. package/docs/components/input-amount/use-cases.md +0 -147
  570. package/docs/components/input-amount-dropdown/api-table.md +0 -87
  571. package/docs/components/input-amount-dropdown/index.md +0 -13
  572. package/docs/components/input-amount-dropdown/use-cases.md +0 -103
  573. package/docs/components/input-date/api-table.md +0 -58
  574. package/docs/components/input-date/index.md +0 -13
  575. package/docs/components/input-date/overview.md +0 -51
  576. package/docs/components/input-date/use-cases.md +0 -96
  577. package/docs/components/input-datepicker/api-table.md +0 -99
  578. package/docs/components/input-datepicker/index.md +0 -13
  579. package/docs/components/input-datepicker/overview.md +0 -54
  580. package/docs/components/input-datepicker/use-cases.md +0 -117
  581. package/docs/components/input-email/api-table.md +0 -53
  582. package/docs/components/input-email/index.md +0 -13
  583. package/docs/components/input-email/overview.md +0 -44
  584. package/docs/components/input-email/use-cases.md +0 -60
  585. package/docs/components/input-file/api-table.md +0 -157
  586. package/docs/components/input-file/index.md +0 -13
  587. package/docs/components/input-file/overview.md +0 -44
  588. package/docs/components/input-file/use-cases.md +0 -454
  589. package/docs/components/input-iban/api-table.md +0 -54
  590. package/docs/components/input-iban/index.md +0 -13
  591. package/docs/components/input-iban/overview.md +0 -49
  592. package/docs/components/input-iban/use-cases.md +0 -114
  593. package/docs/components/input-range/api-table.md +0 -71
  594. package/docs/components/input-range/index.md +0 -13
  595. package/docs/components/input-range/overview.md +0 -44
  596. package/docs/components/input-range/use-cases.md +0 -126
  597. package/docs/components/input-stepper/api-table.md +0 -74
  598. package/docs/components/input-stepper/index.md +0 -13
  599. package/docs/components/input-stepper/overview.md +0 -48
  600. package/docs/components/input-stepper/use-cases.md +0 -155
  601. package/docs/components/input-tel/api-table.md +0 -77
  602. package/docs/components/input-tel/index.md +0 -13
  603. package/docs/components/input-tel/overview.md +0 -74
  604. package/docs/components/input-tel/src/h-region-code-table.js +0 -109
  605. package/docs/components/input-tel/use-cases.md +0 -319
  606. package/docs/components/input-tel-dropdown/api-table.md +0 -85
  607. package/docs/components/input-tel-dropdown/extensions.md +0 -44
  608. package/docs/components/input-tel-dropdown/index.md +0 -13
  609. package/docs/components/input-tel-dropdown/overview.md +0 -50
  610. package/docs/components/input-tel-dropdown/src/intl-input-tel-dropdown.js +0 -138
  611. package/docs/components/input-tel-dropdown/use-cases.md +0 -171
  612. package/docs/components/listbox/api-table.md +0 -65
  613. package/docs/components/listbox/index.md +0 -13
  614. package/docs/components/listbox/overview.md +0 -54
  615. package/docs/components/listbox/src/listboxData.js +0 -131
  616. package/docs/components/listbox/use-cases.md +0 -154
  617. package/docs/components/menu/api-table.md +0 -44
  618. package/docs/components/menu/applyMenuDemoStyles.js +0 -173
  619. package/docs/components/menu/extensions.md +0 -262
  620. package/docs/components/menu/index.md +0 -13
  621. package/docs/components/menu/migration.md +0 -129
  622. package/docs/components/menu/overview.md +0 -448
  623. package/docs/components/menu/src/DemoNavigationBar.js +0 -441
  624. package/docs/components/menu/src/DemoSpinButton.js +0 -215
  625. package/docs/components/menu/src/DemoToolbar.js +0 -101
  626. package/docs/components/menu/src/DemoTree.js +0 -55
  627. package/docs/components/menu/src/navigation-bar-types.js +0 -41
  628. package/docs/components/menu/use-cases.md +0 -74
  629. package/docs/components/pagination/api-table.md +0 -45
  630. package/docs/components/pagination/index.md +0 -13
  631. package/docs/components/pagination/overview.md +0 -41
  632. package/docs/components/pagination/use-cases.md +0 -113
  633. package/docs/components/progress-indicator/api-table.md +0 -48
  634. package/docs/components/progress-indicator/assets/my-determinate-progress-bar.js +0 -30
  635. package/docs/components/progress-indicator/assets/my-indeterminate-progress-spinner.js +0 -55
  636. package/docs/components/progress-indicator/examples.md +0 -137
  637. package/docs/components/progress-indicator/index.md +0 -13
  638. package/docs/components/progress-indicator/overview.md +0 -48
  639. package/docs/components/radio-group/api-table.md +0 -63
  640. package/docs/components/radio-group/index.md +0 -13
  641. package/docs/components/radio-group/overview.md +0 -58
  642. package/docs/components/radio-group/use-cases.md +0 -146
  643. package/docs/components/select/api-table.md +0 -51
  644. package/docs/components/select/index.md +0 -13
  645. package/docs/components/select/overview.md +0 -56
  646. package/docs/components/select/use-cases.md +0 -128
  647. package/docs/components/select-rich/api-table.md +0 -123
  648. package/docs/components/select-rich/examples.md +0 -43
  649. package/docs/components/select-rich/index.md +0 -13
  650. package/docs/components/select-rich/overview.md +0 -55
  651. package/docs/components/select-rich/src/flagStyles.js +0 -1250
  652. package/docs/components/select-rich/src/intl-select-rich.js +0 -194
  653. package/docs/components/select-rich/src/regionMetaList.js +0 -1717
  654. package/docs/components/select-rich/use-cases.md +0 -387
  655. package/docs/components/steps/api-table.md +0 -92
  656. package/docs/components/steps/index.md +0 -13
  657. package/docs/components/steps/overview.md +0 -77
  658. package/docs/components/steps/use-cases.md +0 -181
  659. package/docs/components/switch/api-table.md +0 -82
  660. package/docs/components/switch/index.md +0 -13
  661. package/docs/components/switch/overview.md +0 -87
  662. package/docs/components/switch/reference.md +0 -51
  663. package/docs/components/switch/use-cases.md +0 -88
  664. package/docs/components/tabs/api-table.md +0 -51
  665. package/docs/components/tabs/examples.md +0 -35
  666. package/docs/components/tabs/index.md +0 -13
  667. package/docs/components/tabs/overview.md +0 -60
  668. package/docs/components/tabs/src/lea-tab-panel.js +0 -26
  669. package/docs/components/tabs/src/lea-tab.js +0 -50
  670. package/docs/components/tabs/src/lea-tabs.js +0 -28
  671. package/docs/components/tabs/use-cases.md +0 -231
  672. package/docs/components/textarea/api-table.md +0 -57
  673. package/docs/components/textarea/index.md +0 -13
  674. package/docs/components/textarea/overview.md +0 -47
  675. package/docs/components/textarea/use-cases.md +0 -107
  676. package/docs/components/tooltip/api-table.md +0 -62
  677. package/docs/components/tooltip/examples.md +0 -51
  678. package/docs/components/tooltip/index.md +0 -13
  679. package/docs/components/tooltip/overview.md +0 -56
  680. package/docs/components/tooltip/use-cases.md +0 -275
  681. package/docs/fundamentals/index.md +0 -19
  682. package/docs/fundamentals/node-tools/babel-plugin-extend-docs/index.md +0 -13
  683. package/docs/fundamentals/node-tools/babel-plugin-extend-docs/overview.md +0 -246
  684. package/docs/fundamentals/node-tools/index.md +0 -11
  685. package/docs/fundamentals/node-tools/providence-analytics/index.md +0 -13
  686. package/docs/fundamentals/node-tools/providence-analytics/overview.md +0 -108
  687. package/docs/fundamentals/node-tools/publish-docs/index.md +0 -13
  688. package/docs/fundamentals/node-tools/publish-docs/overview.md +0 -149
  689. package/docs/fundamentals/node-tools/remark-extend/index.md +0 -13
  690. package/docs/fundamentals/node-tools/remark-extend/overview.md +0 -287
  691. package/docs/fundamentals/node-tools/rocket-preset-extend-lion-docs/index.md +0 -13
  692. package/docs/fundamentals/node-tools/rocket-preset-extend-lion-docs/overview.md +0 -298
  693. package/docs/fundamentals/rationales/TypeScript.md +0 -123
  694. package/docs/fundamentals/rationales/accessibility.md +0 -40
  695. package/docs/fundamentals/rationales/index.md +0 -11
  696. package/docs/fundamentals/rationales/side-effects.md +0 -215
  697. package/docs/fundamentals/rationales/versioning.md +0 -47
  698. package/docs/fundamentals/systems/core/SlotMixin.md +0 -168
  699. package/docs/fundamentals/systems/core/api-table.md +0 -43
  700. package/docs/fundamentals/systems/core/index.md +0 -15
  701. package/docs/fundamentals/systems/core/overview.md +0 -98
  702. package/docs/fundamentals/systems/form/api-table.md +0 -40
  703. package/docs/fundamentals/systems/form/assets/h-output.js +0 -156
  704. package/docs/fundamentals/systems/form/formatting-and-parsing.md +0 -258
  705. package/docs/fundamentals/systems/form/index.md +0 -15
  706. package/docs/fundamentals/systems/form/interaction-states.md +0 -195
  707. package/docs/fundamentals/systems/form/model-value.md +0 -57
  708. package/docs/fundamentals/systems/form/overview.md +0 -95
  709. package/docs/fundamentals/systems/form/styling.md +0 -92
  710. package/docs/fundamentals/systems/form/use-cases.md +0 -187
  711. package/docs/fundamentals/systems/form/validate.md +0 -985
  712. package/docs/fundamentals/systems/icon/index.md +0 -15
  713. package/docs/fundamentals/systems/icon/overview.md +0 -137
  714. package/docs/fundamentals/systems/index.md +0 -11
  715. package/docs/fundamentals/systems/localize/api-table.md +0 -72
  716. package/docs/fundamentals/systems/localize/assets/all-locales.js +0 -437
  717. package/docs/fundamentals/systems/localize/assets/en-AU.js +0 -6
  718. package/docs/fundamentals/systems/localize/assets/en-GB.js +0 -6
  719. package/docs/fundamentals/systems/localize/assets/en-US.js +0 -6
  720. package/docs/fundamentals/systems/localize/assets/en.js +0 -4
  721. package/docs/fundamentals/systems/localize/assets/nl-BE.js +0 -6
  722. package/docs/fundamentals/systems/localize/assets/nl-NL.js +0 -6
  723. package/docs/fundamentals/systems/localize/assets/nl.js +0 -4
  724. package/docs/fundamentals/systems/localize/dates.md +0 -208
  725. package/docs/fundamentals/systems/localize/index.md +0 -15
  726. package/docs/fundamentals/systems/localize/numbers.md +0 -230
  727. package/docs/fundamentals/systems/localize/overview.md +0 -61
  728. package/docs/fundamentals/systems/localize/rationale.md +0 -75
  729. package/docs/fundamentals/systems/localize/text.md +0 -139
  730. package/docs/fundamentals/systems/localize/use-cases.md +0 -334
  731. package/docs/fundamentals/systems/overlays/_configuration-positioning.md +0 -118
  732. package/docs/fundamentals/systems/overlays/_edge-cases.md +0 -149
  733. package/docs/fundamentals/systems/overlays/api-table.md +0 -174
  734. package/docs/fundamentals/systems/overlays/assets/applyDemoOverlayStyles.js +0 -23
  735. package/docs/fundamentals/systems/overlays/assets/demo-el-using-overlaymixin.js +0 -104
  736. package/docs/fundamentals/systems/overlays/assets/demo-overlay-backdrop.js +0 -47
  737. package/docs/fundamentals/systems/overlays/assets/demo-overlay-positioning.mjs +0 -537
  738. package/docs/fundamentals/systems/overlays/assets/umbrella-form.js +0 -140
  739. package/docs/fundamentals/systems/overlays/configuration.md +0 -516
  740. package/docs/fundamentals/systems/overlays/index.md +0 -15
  741. package/docs/fundamentals/systems/overlays/overview.md +0 -126
  742. package/docs/fundamentals/systems/overlays/rationale.md +0 -242
  743. package/docs/fundamentals/systems/overlays/use-cases.md +0 -717
  744. package/docs/fundamentals/tools/ajax/index.md +0 -15
  745. package/docs/fundamentals/tools/ajax/overview.md +0 -269
  746. package/docs/fundamentals/tools/ajax/use-cases.md +0 -469
  747. package/docs/fundamentals/tools/helpers/action-logger.md +0 -175
  748. package/docs/fundamentals/tools/helpers/index.md +0 -15
  749. package/docs/fundamentals/tools/helpers/overview.md +0 -43
  750. package/docs/fundamentals/tools/index.md +0 -11
  751. package/docs/fundamentals/tools/singleton-manager/example-complex/demo-app.js +0 -95
  752. package/docs/fundamentals/tools/singleton-manager/example-complex/index.md +0 -34
  753. package/docs/fundamentals/tools/singleton-manager/example-complex/node_modules/overlays/index.js +0 -30
  754. package/docs/fundamentals/tools/singleton-manager/example-complex/node_modules/overlays/instance.js +0 -4
  755. package/docs/fundamentals/tools/singleton-manager/example-complex/node_modules/page-a/page-a.js +0 -35
  756. package/docs/fundamentals/tools/singleton-manager/example-complex/node_modules/page-b/node_modules/overlays/index.js +0 -30
  757. package/docs/fundamentals/tools/singleton-manager/example-complex/node_modules/page-b/node_modules/overlays/instance.js +0 -4
  758. package/docs/fundamentals/tools/singleton-manager/example-complex/node_modules/page-b/page-b.js +0 -49
  759. package/docs/fundamentals/tools/singleton-manager/example-complex/overlayCompatibility.js +0 -69
  760. package/docs/fundamentals/tools/singleton-manager/example-fail/demo-app.js +0 -93
  761. package/docs/fundamentals/tools/singleton-manager/example-fail/index.md +0 -32
  762. package/docs/fundamentals/tools/singleton-manager/example-fail/node_modules/overlays/index.js +0 -30
  763. package/docs/fundamentals/tools/singleton-manager/example-fail/node_modules/overlays/instance.js +0 -3
  764. package/docs/fundamentals/tools/singleton-manager/example-fail/node_modules/page-c/page-c.js +0 -34
  765. package/docs/fundamentals/tools/singleton-manager/example-fail/node_modules/page-d/node_modules/overlays/index.js +0 -30
  766. package/docs/fundamentals/tools/singleton-manager/example-fail/node_modules/page-d/node_modules/overlays/instance.js +0 -3
  767. package/docs/fundamentals/tools/singleton-manager/example-fail/node_modules/page-d/page-d.js +0 -34
  768. package/docs/fundamentals/tools/singleton-manager/example-success/demo-app.js +0 -95
  769. package/docs/fundamentals/tools/singleton-manager/example-success/index.md +0 -31
  770. package/docs/fundamentals/tools/singleton-manager/example-success/node_modules/overlays/index.js +0 -30
  771. package/docs/fundamentals/tools/singleton-manager/example-success/node_modules/overlays/instance.js +0 -4
  772. package/docs/fundamentals/tools/singleton-manager/example-success/node_modules/page-e/page-e.js +0 -33
  773. package/docs/fundamentals/tools/singleton-manager/example-success/node_modules/page-f/node_modules/overlays/index.js +0 -30
  774. package/docs/fundamentals/tools/singleton-manager/example-success/node_modules/page-f/node_modules/overlays/instance.js +0 -4
  775. package/docs/fundamentals/tools/singleton-manager/example-success/node_modules/page-f/page-f.js +0 -34
  776. package/docs/fundamentals/tools/singleton-manager/example-success/overlayCompatibility.js +0 -23
  777. package/docs/fundamentals/tools/singleton-manager/index.md +0 -15
  778. package/docs/fundamentals/tools/singleton-manager/overview.md +0 -317
  779. package/docs/guides/how-to/create-a-custom-field.md +0 -212
  780. package/docs/guides/how-to/create-a-form.md +0 -101
  781. package/docs/guides/how-to/extend-a-native-input.md +0 -78
  782. package/docs/guides/how-to/get-started.md +0 -116
  783. package/docs/guides/how-to/index.md +0 -25
  784. package/docs/guides/index.md +0 -44
  785. package/docs/guides/principles/definitions-and-terms.md +0 -53
  786. package/docs/guides/principles/index.md +0 -36
  787. package/docs/guides/principles/scoped-elements.md +0 -119
  788. package/docs/guides/principles/styling.md +0 -43
  789. package/docs/guides/principles/subclasser-apis.md +0 -40
@@ -0,0 +1,1505 @@
1
+ import { html } from 'lit/static-html.js';
2
+ import { LionInputFile, LionSelectedFileList } from '@lion/ui/input-file.js';
3
+ import '@lion/ui/define/lion-input-file.js';
4
+ import '@lion/ui/define/lion-selected-file-list.js';
5
+ import { Required } from '@lion/ui/form-core.js';
6
+ import { getInputMembers } from '@lion/ui/input-test-helpers.js';
7
+ import { getLocalizeManager } from '@lion/ui/localize-no-side-effects.js';
8
+ import { localizeTearDown } from '@lion/ui/localize-test-helpers.js';
9
+ import {
10
+ unsafeStatic,
11
+ expect,
12
+ fixture as _fixture,
13
+ oneEvent,
14
+ elementUpdated,
15
+ } from '@open-wc/testing';
16
+ import sinon from 'sinon';
17
+ import { resolveSuiteTag } from '../../core/test-helpers/resolveSuiteTag.js';
18
+
19
+ /**
20
+ * @typedef {import('../types/input-file.js').InputFile} InputFile
21
+ * @typedef {import('../types/input-file.js').SystemFile} SystemFile
22
+ * @typedef {import('lit').TemplateResult} TemplateResult
23
+ */
24
+ const fixture = /** @type {(arg: TemplateResult|string) => Promise<LionInputFile>} */ _fixture;
25
+ const filesListChanged = (/** @type {LionInputFile} */ el, /** @type { CustomEvent } */ ev) => {
26
+ // eslint-disable-next-line no-param-reassign
27
+ el.uploadResponse = [...ev.detail.newFiles];
28
+ };
29
+ function mimicSelectFile(
30
+ /** @type {LionInputFile} */ formControl,
31
+ /** @type {InputFile[]} */ mockFiles,
32
+ ) {
33
+ // @ts-expect-error [allow-protected-in-tests]
34
+ formControl._processFiles(mockFiles);
35
+ // TODO: doesn't this set latest file.name only to formControl._inputNode.value?
36
+ mockFiles.forEach((file) => {
37
+ // @ts-expect-error [allow-protected-in-tests]
38
+ Object.defineProperty(formControl._inputNode, 'value', {
39
+ value: `C:\\fakepath\\${file.name}`,
40
+ writable: true,
41
+ });
42
+ });
43
+ // @ts-expect-error [allow-protected-in-tests]
44
+ Object.defineProperty(formControl._inputNode, 'files', {
45
+ value: mockFiles,
46
+ writable: true,
47
+ });
48
+ // @ts-expect-error [allow-protected-in-tests]
49
+ formControl._inputNode.dispatchEvent(
50
+ new Event('input', {
51
+ bubbles: true,
52
+ }),
53
+ );
54
+ }
55
+ const file =
56
+ /** @type {InputFile} */
57
+ new File(['foo'], 'foo.txt', {
58
+ type: 'text/plain',
59
+ });
60
+ const file2 =
61
+ /** @type {InputFile} */
62
+ new File(['bar'], 'bar.txt', {
63
+ type: 'text/plain',
64
+ });
65
+ const file3 =
66
+ /** @type {InputFile} */
67
+ new File(['foo3'], 'foo3.txt', {
68
+ type: 'text/plain',
69
+ });
70
+ const file4 =
71
+ /** @type {InputFile} */
72
+ new File(['foo4'], 'foo4.txt', {
73
+ type: 'text/plain',
74
+ });
75
+
76
+ /**
77
+ * Runs the `lion-input-file` behavioural suite, moved out of `test/lion-input-file.test.js` so a Subclasser can run
78
+ * the same guarantees against its own element. Pass `tagString` to point it at your
79
+ * registered tag; see docs/guides/principles/test-suites.md.
80
+ * `tagString`, `klass` and the older role tag keys are deprecated: pass `classes` instead (Lion
81
+ * itself uses `classes` everywhere).
82
+ * @param {{ classes?: Record<string, CustomElementConstructor>, tagString?: string, selectedFileListTagString?: string }} [customConfig]
83
+ */
84
+ export function runInputFileSuite({
85
+ classes: {
86
+ host = LionInputFile,
87
+ 'selected-file-list': selectedFileListEl = LionSelectedFileList,
88
+ } = {},
89
+ tagString: legacyTagString,
90
+ selectedFileListTagString: legacySelectedFileListTagString,
91
+ } = {}) {
92
+ const hostTagString = resolveSuiteTag(host, legacyTagString);
93
+ const tag = unsafeStatic(hostTagString);
94
+ const selectedFileListTagString = resolveSuiteTag(
95
+ selectedFileListEl,
96
+ legacySelectedFileListTagString,
97
+ );
98
+ describe('lion-input-file', () => {
99
+ const localizeManager = getLocalizeManager();
100
+ afterEach(localizeTearDown);
101
+ it('has a type of "file"', async () => {
102
+ const el = await fixture(html`<${tag}></${tag}>`);
103
+ // @ts-expect-error [allow-protected-in-tests]
104
+ const { _inputNode } = getInputMembers(el);
105
+ expect(_inputNode.type).to.equal('file');
106
+ });
107
+ it('should add single file and dispatch "file-list-changed" event with newly added file', async () => {
108
+ const el = await fixture(html`<${tag}></${tag}>`);
109
+ const fileListChangedEventPromise = oneEvent(el, 'file-list-changed');
110
+ mimicSelectFile(el, [file]);
111
+ const fileListChangedEvent = await fileListChangedEventPromise;
112
+ // @ts-expect-error [allow-protected-in-tests]
113
+ expect(el._selectedFilesMetaData.length).to.equal(1);
114
+ expect(el.uploadResponse.length).to.equal(1);
115
+ expect(fileListChangedEvent).to.exist;
116
+ expect(fileListChangedEvent.detail.newFiles.length).to.equal(1);
117
+ expect(fileListChangedEvent.detail.newFiles[0].name).to.equal('foo.txt');
118
+ });
119
+ it('should select 1 file', async () => {
120
+ const el = await fixture(html`<${tag}></${tag}>`);
121
+ // @ts-expect-error [allow-protected-in-test]
122
+ const processedFilesSpy = sinon.spy(el, '_processFiles');
123
+
124
+ // @ts-expect-error [allow-protected-in-test]
125
+ await el._onChange({
126
+ target: {
127
+ files: [file],
128
+ },
129
+ });
130
+ expect(processedFilesSpy).have.been.calledOnce;
131
+ processedFilesSpy.restore();
132
+ });
133
+ it('should retain selected file when "Cancel" button is clicked in system file explorer dialog', async () => {
134
+ const el = await fixture(html`<${tag}></${tag}>`);
135
+ mimicSelectFile(el, [file]);
136
+ await el.updateComplete;
137
+ // @ts-expect-error [allow-protected-in-test]
138
+ expect(el._selectedFilesMetaData.length).to.equal(1);
139
+ expect(el.uploadResponse.length).to.equal(1);
140
+
141
+ // when cancel is clicked, native input value is blank which means modelValue is blank
142
+ el.modelValue = [];
143
+ await el.updateComplete;
144
+ // @ts-expect-error [allow-protected-in-test]
145
+ expect(el._selectedFilesMetaData.length).to.equal(1);
146
+ });
147
+ it('has an attribute focused when focused', async () => {
148
+ const el = await fixture(html` <${tag} label="Select"></${tag}> `);
149
+
150
+ // @ts-expect-error [allow-protected-in-test]
151
+ el._buttonNode.focus();
152
+ await el.updateComplete;
153
+ expect(el.hasAttribute('focused')).to.be.true;
154
+
155
+ // @ts-expect-error [allow-protected-in-test]
156
+ el._buttonNode.blur();
157
+ await el.updateComplete;
158
+ expect(el.hasAttribute('focused')).to.be.false;
159
+ });
160
+ it('should set touched property true on change', async () => {
161
+ const el = await fixture(html` <${tag} label="Select"></${tag}> `);
162
+ expect(el.touched).to.be.false;
163
+
164
+ // @ts-expect-error [allow-protected-in-test]
165
+ await el._onChange({
166
+ target: {
167
+ files: [file],
168
+ },
169
+ });
170
+ expect(el.touched).to.be.true;
171
+ });
172
+ it('should replace previous file when new file is selected', async () => {
173
+ const el = await fixture(html`<${tag}></${tag}>`);
174
+ mimicSelectFile(el, [file]);
175
+ await el.updateComplete;
176
+ // @ts-expect-error [allow-protected-in-test]
177
+ expect(el._selectedFilesMetaData.length).to.equal(1);
178
+ // @ts-expect-error [allow-protected-in-test]
179
+ expect(el._selectedFilesMetaData[0].systemFile.name).to.equal('foo.txt');
180
+ mimicSelectFile(el, [file2]);
181
+ await el.updateComplete;
182
+ // @ts-expect-error [allow-protected-in-test]
183
+ expect(el._selectedFilesMetaData.length).to.equal(1);
184
+ // @ts-expect-error [allow-protected-in-test]
185
+ expect(el._selectedFilesMetaData[0].systemFile.name).to.equal('bar.txt');
186
+ });
187
+ describe('structure', async () => {
188
+ it('can has a button label by default', async () => {
189
+ const el = await fixture(html`<${tag}></${tag}>`);
190
+ // @ts-expect-error [allow-protected-in-test]
191
+ expect(el._buttonNode.textContent).to.equal('Select file');
192
+ });
193
+ it('can has a button label by default when multiple', async () => {
194
+ const el = await fixture(html`<${tag} multiple></${tag}>`);
195
+ // @ts-expect-error [allow-protected-in-test]
196
+ expect(el._buttonNode.textContent).to.equal('Select files');
197
+ });
198
+ it('will update the button label on locale change', async () => {
199
+ const el = await fixture(html`<${tag}></${tag}>`);
200
+ // @ts-expect-error [allow-protected-in-test]
201
+ expect(el._buttonNode.textContent).to.equal('Select file');
202
+ localizeManager.locale = 'nl-NL';
203
+ await localizeManager.loadingComplete;
204
+ await el.updateComplete;
205
+ // @ts-expect-error [allow-protected-in-test]
206
+ expect(el._buttonNode.textContent).to.equal('Selecteer bestand');
207
+ });
208
+ it('can overwrite the button label', async () => {
209
+ const el = await fixture(html`<${tag} .buttonLabel="${'Foo'}"></${tag}>`);
210
+ // @ts-expect-error [allow-protected-in-test]
211
+ expect(el._buttonNode.textContent).to.equal('Foo');
212
+ el.buttonLabel = 'Bar';
213
+ await el.updateComplete;
214
+ // @ts-expect-error [allow-protected-in-test]
215
+ expect(el._buttonNode.textContent).to.equal('Bar');
216
+ });
217
+ });
218
+ describe('invalid file types', async () => {
219
+ const fileWrongType =
220
+ /** @type {InputFile} */
221
+ new File(['foobar'], 'foobar.txt', {
222
+ type: 'xxxxx',
223
+ });
224
+ it('error should not be there when the file extensions are accepted', async () => {
225
+ const el = await fixture(html`
226
+ <${tag} label="Select" accept=".txt"></${tag}>
227
+ `);
228
+ mimicSelectFile(el, [fileWrongType]);
229
+ await el.updateComplete;
230
+ expect(el.hasFeedbackFor.length).to.equal(0);
231
+ });
232
+ it('should not be added to the selected list', async () => {
233
+ const el = await fixture(html`
234
+ <${tag} label="Select" accept="text/plain"></${tag}>
235
+ `);
236
+ mimicSelectFile(el, [fileWrongType]);
237
+ await el.updateComplete;
238
+
239
+ // @ts-expect-error [allow-protected-in-test]
240
+ expect(el._selectedFilesMetaData.length).to.equal(1);
241
+ // @ts-expect-error [allow-protected-in-test]
242
+ expect(el._selectedFilesMetaData[0].failedProp?.length).to.equal(1);
243
+ // @ts-expect-error [allow-protected-in-test]
244
+ expect(el._selectedFilesMetaData[0].validationFeedback).to.exist;
245
+ // @ts-expect-error [allow-protected-in-test]
246
+ expect(el._selectedFilesMetaData[0].status).to.equal('FAIL');
247
+ expect(el.uploadResponse[0].status).to.equal('FAIL');
248
+ });
249
+ it('error message should use main type when "/*" is used', async () => {
250
+ const el = await fixture(html`
251
+ <${tag} label="Select" accept="text/*"></${tag}>
252
+ `);
253
+ mimicSelectFile(el, [fileWrongType]);
254
+ await el.updateComplete;
255
+
256
+ // @ts-expect-error [allow-protected-in-test]
257
+ el._selectedFilesMetaData[0].validationFeedback?.forEach((error) => {
258
+ expect(error.message).to.deep.equal('Please select a(n) text file with max 500MB.');
259
+ });
260
+ });
261
+ it('error message should use main type when "text/plain" is used', async () => {
262
+ const el = await fixture(html`
263
+ <${tag} label="Select" accept="text/plain"></${tag}>
264
+ `);
265
+ mimicSelectFile(el, [fileWrongType]);
266
+ await el.updateComplete;
267
+
268
+ // @ts-expect-error [allow-protected-in-test]
269
+ el._selectedFilesMetaData[0].validationFeedback?.forEach((error) => {
270
+ expect(error.message).to.deep.equal('Please select a(n) text file with max 500MB.');
271
+ });
272
+ });
273
+ it('error message should use sub type when e.g. "text/html" is used', async () => {
274
+ const el = await fixture(html`
275
+ <${tag} label="Select" accept="text/html"></${tag}>
276
+ `);
277
+ mimicSelectFile(el, [fileWrongType]);
278
+ await el.updateComplete;
279
+
280
+ // @ts-expect-error [allow-protected-in-test]
281
+ el._selectedFilesMetaData[0].validationFeedback?.forEach((error) => {
282
+ expect(error.message).to.deep.equal('Please select a(n) .html file with max 500MB.');
283
+ });
284
+ });
285
+ it('error message should use the first sub type when e.g. "image/svg+xml" is used', async () => {
286
+ const el = await fixture(html`
287
+ <${tag} label="Select" accept="image/svg+xml"></${tag}>
288
+ `);
289
+ mimicSelectFile(el, [fileWrongType]);
290
+ await el.updateComplete;
291
+
292
+ // @ts-expect-error [allow-protected-in-test]
293
+ el._selectedFilesMetaData[0].validationFeedback?.forEach((error) => {
294
+ expect(error.message).to.deep.equal('Please select a(n) .svg file with max 500MB.');
295
+ });
296
+ });
297
+ it('can reflect multiple types in the error message', async () => {
298
+ const el = await fixture(html`
299
+ <${tag} label="Select" accept="text/html, text/csv"></${tag}>
300
+ `);
301
+ mimicSelectFile(el, [fileWrongType]);
302
+ await el.updateComplete;
303
+
304
+ // @ts-expect-error [allow-protected-in-test]
305
+ el._selectedFilesMetaData[0].validationFeedback?.forEach((error) => {
306
+ expect(error.message).to.deep.equal('Please select a .html or .csv file with max 500MB.');
307
+ });
308
+ });
309
+ it('can reflect multiple types in the error message also with a space " "', async () => {
310
+ const el = await fixture(html`
311
+ <${tag} label="Select" accept="text/html,text/csv"></${tag}>
312
+ `);
313
+ mimicSelectFile(el, [fileWrongType]);
314
+ await el.updateComplete;
315
+
316
+ // @ts-expect-error [allow-protected-in-test]
317
+ el._selectedFilesMetaData[0].validationFeedback?.forEach((error) => {
318
+ expect(error.message).to.deep.equal('Please select a .html or .csv file with max 500MB.');
319
+ });
320
+ });
321
+ it('can reflect multiple types in the error message with preference to extensions', async () => {
322
+ const el = await fixture(html`
323
+ <${tag} label="Select" accept=".jpg,image/svg+xml"></${tag}>
324
+ `);
325
+ mimicSelectFile(el, [fileWrongType]);
326
+ await el.updateComplete;
327
+
328
+ // @ts-expect-error [allow-protected-in-test]
329
+ el._selectedFilesMetaData[0].validationFeedback?.forEach((error) => {
330
+ expect(error.message).to.deep.equal('Please select a(n) .jpg file with max 500MB.');
331
+ });
332
+ });
333
+ });
334
+ describe('invalid file extensions', async () => {
335
+ const fileWrongType =
336
+ /** @type {InputFile} */
337
+ new File(['foobar'], 'foobar.txt', {
338
+ type: 'xxxxx',
339
+ });
340
+ it('should not be added to the selected list', async () => {
341
+ const el = await fixture(html`
342
+ <${tag} label="Select" accept=".jpg, .png, .pdf"></${tag}>
343
+ `);
344
+ mimicSelectFile(el, [fileWrongType]);
345
+ await el.updateComplete;
346
+
347
+ // @ts-expect-error [allow-protected-in-test]
348
+ expect(el._selectedFilesMetaData.length).to.equal(1);
349
+ // @ts-expect-error [allow-protected-in-test]
350
+ expect(el._selectedFilesMetaData[0].failedProp?.length).to.equal(1);
351
+ // @ts-expect-error [allow-protected-in-test]
352
+ expect(el._selectedFilesMetaData[0].validationFeedback).to.exist;
353
+ // @ts-expect-error [allow-protected-in-test]
354
+ expect(el._selectedFilesMetaData[0].status).to.equal('FAIL');
355
+ expect(el.uploadResponse[0].status).to.equal('FAIL');
356
+ });
357
+ it('error message should add the file extension to the validator message', async () => {
358
+ const el = await fixture(html`
359
+ <${tag} label="Select" accept=".jpg"></${tag}>
360
+ `);
361
+ mimicSelectFile(el, [fileWrongType]);
362
+ await el.updateComplete;
363
+
364
+ // @ts-expect-error [allow-protected-in-test]
365
+ el._selectedFilesMetaData[0].validationFeedback?.forEach((error) => {
366
+ expect(error.message).to.equal('Please select a(n) .jpg file with max 500MB.');
367
+ });
368
+ });
369
+ it('error message should add all file extensions to the validator message', async () => {
370
+ const el = await fixture(html`
371
+ <${tag} label="Select" accept=".jpg, .png, .pdf"></${tag}>
372
+ `);
373
+ mimicSelectFile(el, [fileWrongType]);
374
+ await el.updateComplete;
375
+
376
+ // @ts-expect-error [allow-protected-in-test]
377
+ el._selectedFilesMetaData[0].validationFeedback?.forEach((error) => {
378
+ expect(error.message).to.equal('Please select a .jpg, .png or .pdf file with max 500MB.');
379
+ });
380
+ });
381
+ it('error message should add all file extensions to the validator message also works without spaces " "', async () => {
382
+ const el = await fixture(html`
383
+ <${tag} label="Select" accept=".jpg,.png,.pdf"></${tag}>
384
+ `);
385
+ mimicSelectFile(el, [fileWrongType]);
386
+ await el.updateComplete;
387
+
388
+ // @ts-expect-error [allow-protected-in-test]
389
+ el._selectedFilesMetaData[0].validationFeedback?.forEach((error) => {
390
+ expect(error.message).to.equal('Please select a .jpg, .png or .pdf file with max 500MB.');
391
+ });
392
+ });
393
+ });
394
+ describe('invalid file sizes', async () => {
395
+ // Size of this file is 4 bytes
396
+ const fileWrongSize = /** @type {InputFile} */ new File(['foobar'], 'foobar.txt');
397
+ it('should not be added to the selected list', async () => {
398
+ const el = await fixture(html` <${tag} max-file-size="2"></${tag}> `);
399
+ mimicSelectFile(el, [fileWrongSize]);
400
+ await el.updateComplete;
401
+
402
+ // @ts-expect-error [allow-protected-in-test]
403
+ expect(el._selectedFilesMetaData.length).to.equal(1);
404
+ // @ts-expect-error [allow-protected-in-test]
405
+ expect(el._selectedFilesMetaData[0].failedProp?.length).to.equal(1);
406
+ // @ts-expect-error [allow-protected-in-test]
407
+ expect(el._selectedFilesMetaData[0].validationFeedback).to.exist;
408
+ // @ts-expect-error [allow-protected-in-test]
409
+ expect(el._selectedFilesMetaData[0].status).to.equal('FAIL');
410
+ expect(el.uploadResponse[0].status).to.equal('FAIL');
411
+ });
412
+ it('error message should show only the max file size if no type/extension restrictions are defined', async () => {
413
+ const el = await fixture(html`
414
+ <${tag} label="Select" max-file-size="2"></${tag}>
415
+ `);
416
+ mimicSelectFile(el, [fileWrongSize]);
417
+ await el.updateComplete;
418
+
419
+ // @ts-expect-error [allow-protected-in-test]
420
+ el._selectedFilesMetaData[0].validationFeedback?.forEach((error) => {
421
+ expect(error.message).to.equal('Please select a file with max 2 bytes.');
422
+ });
423
+ });
424
+ it('error message should show the correct max file size if type/extension restrictions are defined', async () => {
425
+ const el = await fixture(html`
426
+ <${tag}
427
+ label="Select"
428
+ max-file-size="2"
429
+ accept=".jpg, .png, .pdf"
430
+ ></${tag}>
431
+ `);
432
+ mimicSelectFile(el, [fileWrongSize]);
433
+ await el.updateComplete;
434
+
435
+ // @ts-expect-error [allow-protected-in-test]
436
+ el._selectedFilesMetaData[0].validationFeedback?.forEach((error) => {
437
+ expect(error.message).to.equal(
438
+ 'Please select a .jpg, .png or .pdf file with max 2 bytes.',
439
+ );
440
+ });
441
+ });
442
+ });
443
+ it('should send "file-list-changed" event if selecting files succeeded partially', async () => {
444
+ const el = await fixture(html`<${tag} multiple max-file-size="3"></${tag}>`);
445
+
446
+ // Size of this file is 4 bytes
447
+ const fileWrongSize = /** @type {InputFile} */ new File(['foobar'], 'foobar.txt');
448
+ setTimeout(() => {
449
+ mimicSelectFile(el, [fileWrongSize, file2]);
450
+ });
451
+ const fileListChangedEvent = await oneEvent(el, 'file-list-changed');
452
+
453
+ // @ts-expect-error [allow-protected-in-test]
454
+ expect(el._selectedFilesMetaData.length).to.equal(2);
455
+ // @ts-expect-error [allow-protected-in-test]
456
+ expect(el._selectedFilesMetaData[0].status).to.equal('FAIL');
457
+ expect(el.uploadResponse[0].status).to.equal('FAIL');
458
+ expect(fileListChangedEvent.detail.newFiles.length).to.equal(1);
459
+ });
460
+ it('should update downloadurl for successful files', async () => {
461
+ const el = await fixture(html`<${tag}></${tag}>`);
462
+ setTimeout(() => {
463
+ mimicSelectFile(el, [file]);
464
+ });
465
+ const fileListChangedEvent = await oneEvent(el, 'file-list-changed');
466
+ filesListChanged(el, fileListChangedEvent);
467
+
468
+ // @ts-expect-error [allow-protected-in-test]
469
+ expect(el._selectedFilesMetaData[0].downloadUrl).to.exist;
470
+ });
471
+ describe('format', () => {
472
+ it('modelValue is an array of files', async () => {
473
+ const el = await fixture(html` <${tag} name="select"></${tag}> `);
474
+ mimicSelectFile(el, [file]);
475
+ await el.updateComplete;
476
+ expect(el.modelValue).to.deep.equal([file]);
477
+ });
478
+ it('view value is a string', async () => {
479
+ const el = await fixture(html` <${tag} name="select"></${tag}> `);
480
+ mimicSelectFile(el, [file]);
481
+ await el.updateComplete;
482
+ expect(el.value).to.equal('C:\\fakepath\\foo.txt');
483
+ // @ts-expect-error [allow-protected-in-tests]
484
+ expect(el._inputNode.value).to.equal('C:\\fakepath\\foo.txt');
485
+ });
486
+ it('formattedValue is a string', async () => {
487
+ const el = await fixture(html` <${tag} name="select"></${tag}> `);
488
+ mimicSelectFile(el, [file]);
489
+ await el.updateComplete;
490
+ expect(el.formattedValue).to.equal('C:\\fakepath\\foo.txt');
491
+ });
492
+ it('serializedValue is an array of files', async () => {
493
+ const el = await fixture(html` <${tag} name="select"></${tag}> `);
494
+ mimicSelectFile(el, [file]);
495
+ await el.updateComplete;
496
+ expect(el.serializedValue).to.deep.equal([file]);
497
+ });
498
+ it('fires `model-value-changed` for every programmatic modelValue change', async () => {
499
+ const el = await fixture(html` <${tag} name="select"></${tag}> `);
500
+ let counter = 0;
501
+ let isTriggeredByUser = false;
502
+ el.addEventListener('model-value-changed', (event) => {
503
+ counter += 1;
504
+ isTriggeredByUser = /** @type {CustomEvent} */ event.detail.isTriggeredByUser;
505
+ });
506
+ el.modelValue = [file];
507
+ expect(counter).to.equal(1);
508
+ expect(isTriggeredByUser).to.be.false;
509
+
510
+ // TODO: should no change mean no event?
511
+ // el.modelValue = [file];
512
+ // expect(counter).to.equal(1);
513
+
514
+ el.modelValue = [file, file2];
515
+ expect(counter).to.equal(2);
516
+ });
517
+ it('fires `model-value-changed` for every user input, adding `isTriggeredByUser` in event detail', async () => {
518
+ const el = await fixture(html` <${tag} name="select"></${tag}> `);
519
+ let counter = 0;
520
+ let isTriggeredByUser = false;
521
+ el.addEventListener('model-value-changed', (event) => {
522
+ counter += 1;
523
+ isTriggeredByUser = /** @type {CustomEvent} */ event.detail.isTriggeredByUser;
524
+ });
525
+ mimicSelectFile(el, [file]);
526
+ await el.updateComplete;
527
+ expect(counter).to.equal(1);
528
+ expect(isTriggeredByUser).to.be.true;
529
+ mimicSelectFile(el, [file, file2]);
530
+ await el.updateComplete;
531
+ expect(counter).to.equal(2);
532
+ });
533
+ });
534
+ describe('multiple file select', () => {
535
+ it('should add multiple files', async () => {
536
+ const el = await fixture(html`
537
+ <${tag} label="Select" .multiple="${true}"> </${tag}>
538
+ `);
539
+ mimicSelectFile(el, [file, file2]);
540
+ await el.updateComplete;
541
+ // @ts-expect-error [allow-protected-in-test]
542
+ expect(el._selectedFilesMetaData.length).to.equal(2);
543
+ // @ts-expect-error [allow-protected-in-test]
544
+ expect(el._selectedFilesMetaData[0].systemFile.name).to.equal('foo.txt');
545
+ // @ts-expect-error [allow-protected-in-test]
546
+ expect(el._selectedFilesMetaData[1].systemFile.name).to.equal('bar.txt');
547
+ expect(el.uploadResponse.length).to.equal(2);
548
+ expect(el.uploadResponse[0].name).to.equal('foo.txt');
549
+ expect(el.uploadResponse[1].name).to.equal('bar.txt');
550
+ });
551
+ it('should add new files and retain previous files', async () => {
552
+ const el = await fixture(html` <${tag} .multiple="${true}"></${tag}> `);
553
+ setTimeout(() => {
554
+ mimicSelectFile(el, [file, file2]);
555
+ });
556
+ const fileListChangedEvent = await oneEvent(el, 'file-list-changed');
557
+ filesListChanged(el, fileListChangedEvent);
558
+ await elementUpdated(el);
559
+
560
+ // @ts-expect-error [allow-protected-in-test]
561
+ expect(el._selectedFilesMetaData.length).to.equal(2);
562
+ expect(el.modelValue.length).to.equal(2);
563
+ setTimeout(() => {
564
+ mimicSelectFile(el, [file3, file4]);
565
+ });
566
+ const fileListChangedEvent1 = await oneEvent(el, 'file-list-changed');
567
+ filesListChanged(el, fileListChangedEvent1);
568
+ await elementUpdated(el);
569
+
570
+ // @ts-expect-error [allow-protected-in-test]
571
+ expect(el._selectedFilesMetaData.length).to.equal(4);
572
+ expect(el.modelValue.length).to.equal(4);
573
+ });
574
+ it('should add multiple files and dispatch file-list-changed event ONLY with newly added file', async () => {
575
+ const el = await fixture(html` <${tag} .multiple="${true}"></${tag}> `);
576
+ setTimeout(() => {
577
+ mimicSelectFile(el, [file, file2]);
578
+ });
579
+ const fileListChangedEvent = await oneEvent(el, 'file-list-changed');
580
+ filesListChanged(el, fileListChangedEvent);
581
+ setTimeout(() => {
582
+ mimicSelectFile(el, [file3, file4]);
583
+ });
584
+ const fileListChangedEvent1 = await oneEvent(el, 'file-list-changed');
585
+ filesListChanged(el, fileListChangedEvent1);
586
+ expect(fileListChangedEvent1).to.exist;
587
+ // @ts-expect-error [allow-protected-in-test]
588
+ expect(el._selectedFilesMetaData.length).to.equal(4);
589
+ expect(fileListChangedEvent1.detail.newFiles.length).to.equal(2);
590
+ expect(fileListChangedEvent1.detail.newFiles[0].name).to.equal('foo3.txt');
591
+ expect(fileListChangedEvent1.detail.newFiles[1].name).to.equal('foo4.txt');
592
+ });
593
+ it('should not allow duplicate files to be selected and show notification message', async () => {
594
+ const el = await fixture(html` <${tag} .multiple="${true}"></${tag}> `);
595
+ setTimeout(() => {
596
+ mimicSelectFile(el, [file]);
597
+ });
598
+
599
+ // create condition to also show the feedback
600
+ el.prefilled = true;
601
+ const fileListChangedEvent = await oneEvent(el, 'file-list-changed');
602
+
603
+ // @ts-expect-error [allow-protected-in-test]
604
+ expect(el._selectedFilesMetaData.length).to.equal(1);
605
+ // @ts-expect-error [allow-protected-in-test]
606
+ expect(el._selectedFilesMetaData[0].systemFile.name).to.equal('foo.txt');
607
+ expect(fileListChangedEvent).to.exist;
608
+ expect(fileListChangedEvent.detail.newFiles.length).to.equal(1);
609
+ expect(fileListChangedEvent.detail.newFiles[0].name).to.equal('foo.txt');
610
+ const fileDuplicate =
611
+ /** @type {InputFile} */
612
+ new File(['foo'], 'foo.txt', {
613
+ type: 'text/plain',
614
+ });
615
+ mimicSelectFile(el, [fileDuplicate]);
616
+ await el.updateComplete;
617
+ // @ts-expect-error [allow-protected-in-test]
618
+ expect(el._selectedFilesMetaData.length).to.equal(1);
619
+ expect(el.hasFeedbackFor).to.deep.equals(['info'], 'hasFeedbackFor');
620
+ expect(el.showsFeedbackFor).to.deep.equals(['info'], 'showsFeedbackFor');
621
+ });
622
+ it('should add valid files and skip invalid ones', async () => {
623
+ const fileWrongSize = /** @type {InputFile} */ new File(['foobar'], 'foobar.txt');
624
+ const fileWrongType =
625
+ /** @type {InputFile} */
626
+ new File(['foobar'], 'foobar.txt', {
627
+ type: 'xxxxx',
628
+ });
629
+ const el = await fixture(html`
630
+ <${tag} multiple max-file-size="3" accept=".txt"></${tag}>
631
+ `);
632
+ setTimeout(() => {
633
+ mimicSelectFile(el, [file, fileWrongSize, file2, fileWrongType]);
634
+ });
635
+ const fileListChangedEvent = await oneEvent(el, 'file-list-changed');
636
+ // @ts-expect-error [allow-protected-in-test]
637
+ expect(el._selectedFilesMetaData.length).to.equal(4);
638
+ expect(fileListChangedEvent).to.exist;
639
+ expect(fileListChangedEvent.detail.newFiles.length).to.equal(2);
640
+ expect(fileListChangedEvent.detail.newFiles[0].name).to.equal('foo.txt');
641
+ expect(fileListChangedEvent.detail.newFiles[1].name).to.equal('bar.txt');
642
+ });
643
+ });
644
+ describe('status and error', () => {
645
+ /**
646
+ * @type {LionInputFile}
647
+ */
648
+ let el;
649
+ beforeEach(async () => {
650
+ el = await fixture(html`<${tag} accept="text/plain"></${tag}>`);
651
+ });
652
+ it('should set uploadResponse data to _selectedFilesMetaData for rendering error and status', async () => {
653
+ mimicSelectFile(el, [file]);
654
+ el.uploadResponse = [
655
+ {
656
+ name: 'foo.txt',
657
+ status: 'LOADING',
658
+ errorMessage: '500',
659
+ },
660
+ ];
661
+ await el.updateComplete;
662
+
663
+ // @ts-expect-error [allow-protected-in-test]
664
+ expect(el._selectedFilesMetaData[0].status).to.equal('LOADING');
665
+ // @ts-ignore
666
+ expect(el._selectedFilesMetaData[0].validationFeedback[0].message).to.equal('500');
667
+ });
668
+ it('should not fire file-list-changed event if invalid file is selected', async () => {
669
+ const filePdf =
670
+ /** @type {InputFile} */
671
+ new File(['foo'], 'foo.pdf', {
672
+ type: 'application/pdf',
673
+ });
674
+ // @ts-ignore
675
+ const fileListChangedSpy = sinon.spy(el, '_dispatchFileListChangeEvent');
676
+ mimicSelectFile(el, [filePdf]);
677
+ expect(fileListChangedSpy).have.not.been.called;
678
+ fileListChangedSpy.restore();
679
+ });
680
+ it('updates showFeedbackFor when a wrong file has been added/removed', async () => {
681
+ const fileWrongType =
682
+ /** @type {InputFile} */
683
+ new File(['foobar'], 'foobar.txt', {
684
+ type: 'xxxxx',
685
+ });
686
+
687
+ // create condition to also show the feedback
688
+ el.prefilled = true;
689
+ mimicSelectFile(el, [fileWrongType]);
690
+ await el.updateComplete;
691
+ expect(el.hasFeedbackFor).to.deep.equals(['error'], 'hasFeedbackFor');
692
+ expect(el.showsFeedbackFor).to.deep.equals(['error'], 'showsFeedbackFor');
693
+
694
+ // on change the showsFeedbackFor should be empty again
695
+ mimicSelectFile(el, [file]);
696
+ await el.updateComplete;
697
+ expect(el.hasFeedbackFor).to.deep.equals([]);
698
+ expect(el.showsFeedbackFor).to.deep.equals([]);
699
+ });
700
+ });
701
+ describe('validations when used with lion-form', () => {
702
+ it('should throw error with Required validator', async () => {
703
+ const el = await fixture(html`
704
+ <${tag}
705
+ name="myFileInput"
706
+ .validators="${[
707
+ new Required(
708
+ {},
709
+ {
710
+ getMessage: () => 'FooBar',
711
+ },
712
+ ),
713
+ ]}"
714
+ >
715
+ </${tag}>
716
+ `);
717
+ el.touched = true;
718
+ el.dirty = true;
719
+ await el.updateComplete;
720
+ await el.feedbackComplete;
721
+ // @ts-ignore input type="file" is a specific input member
722
+ const { _feedbackNode } = getInputMembers(el);
723
+ expect(_feedbackNode.feedbackData?.[0].message).to.equal('FooBar');
724
+ expect(el.hasFeedbackFor.includes('error')).to.be.true;
725
+ });
726
+ it('reset method should remove File from modelValue but keep uploadResponse', async () => {
727
+ const uploadResponse = [
728
+ {
729
+ name: 'file1.txt',
730
+ status: 'SUCCESS',
731
+ errorMessage: '',
732
+ downloadUrl: '/downloadFile',
733
+ },
734
+ ];
735
+ const el = await fixture(html`
736
+ <${tag} label="Select" .uploadResponse="${uploadResponse}"></${tag}>
737
+ `);
738
+
739
+ // @ts-expect-error [allow-protected-in-test]
740
+ el.uploadResponse = uploadResponse;
741
+ await el.updateComplete;
742
+ mimicSelectFile(el, [file]);
743
+ await el.updateComplete;
744
+ await el.reset();
745
+ expect(el.modelValue).to.deep.equal([]);
746
+ // @ts-expect-error [allow-protected-in-test]
747
+ expect(el._selectedFilesMetaData).to.deep.equal([]);
748
+ expect(el.uploadResponse).to.deep.equal(uploadResponse);
749
+ });
750
+ it('clear method should remove File from modelValue and uploadResponse', async () => {
751
+ const uploadResponse = [
752
+ {
753
+ name: 'file1.txt',
754
+ status: 'SUCCESS',
755
+ errorMessage: '',
756
+ downloadUrl: '/downloadFile',
757
+ },
758
+ ];
759
+ const el = await fixture(html` <${tag} label="Select"></${tag}> `);
760
+
761
+ // @ts-expect-error [allow-protected-in-test]
762
+ el.uploadResponse = uploadResponse;
763
+ setTimeout(() => {
764
+ mimicSelectFile(el, [file]);
765
+ });
766
+ await oneEvent(el, 'file-list-changed');
767
+ await el.clear();
768
+ expect(el.modelValue).to.deep.equal([]);
769
+ expect(el.uploadResponse).to.deep.equal([]);
770
+ // @ts-expect-error [allow-protected-in-test]
771
+ expect(el._selectedFilesMetaData).to.deep.equal([]);
772
+ });
773
+ });
774
+ describe('file select component with prefilled state', () => {
775
+ /**
776
+ * @type {LionInputFile}
777
+ */
778
+ let el;
779
+ const uploadResponse = [
780
+ {
781
+ name: 'file1.txt',
782
+ status: 'SUCCESS',
783
+ errorMessage: '',
784
+ downloadUrl: '/downloadFile',
785
+ },
786
+ {
787
+ name: 'file2.txt',
788
+ status: 'FAIL',
789
+ errorMessage: 'something went wrong',
790
+ },
791
+ ];
792
+ beforeEach(async () => {
793
+ el = await fixture(html`
794
+ <${tag} name="myFiles" multiple="${true}"> </${tag}>
795
+ `);
796
+
797
+ // @ts-expect-error [allow-protected-in-test]
798
+ el.uploadResponse = uploadResponse;
799
+ await el.updateComplete;
800
+ });
801
+ it('should update the _selectedFilesMetaData according to uploadResponse', () => {
802
+ // @ts-expect-error [allow-protected-in-test]
803
+ expect(el._selectedFilesMetaData.length).to.equal(2);
804
+ // @ts-expect-error [allow-protected-in-test]
805
+ expect(el._selectedFilesMetaData[0].systemFile.name).to.equal('file1.txt');
806
+ // @ts-expect-error [allow-protected-in-test]
807
+ expect(el._selectedFilesMetaData[0].status).to.equal('SUCCESS');
808
+ // @ts-expect-error [allow-protected-in-test]
809
+ expect(el._selectedFilesMetaData[0].downloadUrl).to.equal('/downloadFile');
810
+ // @ts-expect-error [allow-protected-in-test]
811
+ expect(el._selectedFilesMetaData[1].validationFeedback[0].message).to.equal(
812
+ 'something went wrong',
813
+ );
814
+ });
815
+ it('should remove file on click of cross button', async () => {
816
+ /**
817
+ * @type {Partial<InputFile>}
818
+ */
819
+ const removedFile = {
820
+ name: 'file2.txt',
821
+ status: 'FAIL',
822
+ systemFile: {
823
+ name: 'file2.txt',
824
+ },
825
+ response: {
826
+ name: 'file2.txt',
827
+ status: 'FAIL',
828
+ },
829
+ };
830
+ // @ts-expect-error [allow-protected-in-test]
831
+ const removeFileSpy = sinon.spy(el, '_removeFile');
832
+
833
+ // assertion for displayed file list to be same
834
+ // @ts-expect-error [allow-protected-in-test]
835
+ expect(el._selectedFilesMetaData.length).to.equal(2);
836
+ // @ts-expect-error [allow-protected-in-test]
837
+ expect(el._selectedFilesMetaData[1].systemFile.name).to.equal('file2.txt');
838
+
839
+ // @ts-expect-error [allow-protected-in-test]
840
+ el._fileListNode.dispatchEvent(
841
+ new CustomEvent('file-remove-requested', {
842
+ detail: {
843
+ removedFile,
844
+ status: removedFile.status,
845
+ uploadResponse: removedFile.response,
846
+ },
847
+ }),
848
+ );
849
+ await el.updateComplete;
850
+ expect(removeFileSpy).have.been.calledOnce;
851
+ // @ts-expect-error [allow-protected-in-test]
852
+ expect(el._selectedFilesMetaData.length).to.equal(1);
853
+ removeFileSpy.restore();
854
+ });
855
+ it('should fire file-removed event with uploadResponse in the details', async () => {
856
+ /**
857
+ * @type {Partial<InputFile>}
858
+ */
859
+ const removedFile = {
860
+ name: 'file2.txt',
861
+ status: 'FAIL',
862
+ systemFile: {
863
+ name: 'file2.txt',
864
+ },
865
+ response: {
866
+ name: 'file2.txt',
867
+ status: 'FAIL',
868
+ },
869
+ };
870
+ setTimeout(() => {
871
+ // @ts-ignore ignore file typing
872
+ el._removeFile(removedFile);
873
+ });
874
+ await el.updateComplete;
875
+ const removeFileEvent = await oneEvent(el, 'file-removed');
876
+
877
+ // assertion for event data
878
+ expect(removeFileEvent).to.exist;
879
+ expect(removeFileEvent.detail.removedFile).to.deep.equal({
880
+ name: 'file2.txt',
881
+ status: 'FAIL',
882
+ systemFile: {
883
+ name: 'file2.txt',
884
+ },
885
+ response: {
886
+ name: 'file2.txt',
887
+ status: 'FAIL',
888
+ },
889
+ });
890
+ expect(removeFileEvent.detail.status).to.deep.equal('FAIL');
891
+ expect(removeFileEvent.detail.uploadResponse).to.deep.equal({
892
+ name: 'file2.txt',
893
+ status: 'FAIL',
894
+ });
895
+ });
896
+ });
897
+ describe('drag and drop', () => {
898
+ /**
899
+ * @type {LionInputFile}
900
+ */
901
+ let el;
902
+ beforeEach(async () => {
903
+ el = await fixture(html`
904
+ <${tag} name="myFiles" multiple enable-drop-zone></${tag}>
905
+ `);
906
+ await el.updateComplete;
907
+ });
908
+ it('should set "is-dragging" on dragenter', async () => {
909
+ const dropzone = el.shadowRoot?.querySelector('.input-file__drop-zone');
910
+ dropzone?.dispatchEvent(
911
+ new Event('dragenter', {
912
+ bubbles: true,
913
+ }),
914
+ );
915
+ await el.updateComplete;
916
+ expect(el.hasAttribute('is-dragging')).to.equal(true);
917
+ });
918
+ it('should set "is-dragging" on dragover', async () => {
919
+ const dropzone = el.shadowRoot?.querySelector('.input-file__drop-zone');
920
+ dropzone?.dispatchEvent(
921
+ new Event('dragover', {
922
+ bubbles: true,
923
+ }),
924
+ );
925
+ await el.updateComplete;
926
+ expect(el.hasAttribute('is-dragging')).to.equal(true);
927
+ });
928
+ it('should remove "is-dragging" on dragleave', async () => {
929
+ const dropzone = el.shadowRoot?.querySelector('.input-file__drop-zone');
930
+ dropzone?.dispatchEvent(
931
+ new Event('dragenter', {
932
+ bubbles: true,
933
+ }),
934
+ );
935
+ await el.updateComplete;
936
+ dropzone?.dispatchEvent(
937
+ new Event('dragleave', {
938
+ bubbles: true,
939
+ }),
940
+ );
941
+ await el.updateComplete;
942
+ expect(el.hasAttribute('is-dragging')).to.equal(false);
943
+ });
944
+ it('should remove "is-dragging" on drop', async () => {
945
+ const dropzone = el.shadowRoot?.querySelector('.input-file__drop-zone');
946
+ dropzone?.dispatchEvent(
947
+ new Event('dragenter', {
948
+ bubbles: true,
949
+ }),
950
+ );
951
+ await el.updateComplete;
952
+ window.dispatchEvent(
953
+ new Event('drop', {
954
+ bubbles: true,
955
+ }),
956
+ );
957
+ await el.updateComplete;
958
+ expect(el.hasAttribute('is-dragging')).to.equal(false);
959
+ });
960
+ it('should update modelValue on drop', async () => {
961
+ const list = new DataTransfer();
962
+ // @ts-ignore
963
+ list.items.add(file);
964
+ const droppedFiles = list.files;
965
+
966
+ // @ts-expect-error [allow-protected-in-test]
967
+ await el._processDroppedFiles({
968
+ // @ts-ignore
969
+ dataTransfer: {
970
+ files: droppedFiles,
971
+ items: [
972
+ {
973
+ name: 'test.txt',
974
+ },
975
+ ],
976
+ },
977
+ preventDefault: () => {},
978
+ });
979
+ await el.updateComplete;
980
+ expect(el.modelValue.length).to.equal(1);
981
+ const list2 = new DataTransfer();
982
+ // @ts-ignore
983
+ list2.items.add(file2);
984
+
985
+ // @ts-expect-error [allow-protected-in-test]
986
+ await el._processDroppedFiles({
987
+ // @ts-ignore
988
+ dataTransfer: {
989
+ files: list2.files,
990
+ items: [
991
+ {
992
+ name: 'test2.txt',
993
+ },
994
+ ],
995
+ },
996
+ preventDefault: () => {},
997
+ });
998
+ await el.updateComplete;
999
+ expect(el.modelValue.length).to.equal(2);
1000
+ });
1001
+ it('should call _processFiles method', async () => {
1002
+ const list = new DataTransfer();
1003
+ // @ts-ignore
1004
+ list.items.add(file);
1005
+ const droppedFiles = list.files;
1006
+ // @ts-ignore
1007
+ const _processFilesSpy = sinon.spy(el, '_processFiles');
1008
+
1009
+ // @ts-expect-error [allow-protected-in-test]
1010
+ await el._processDroppedFiles({
1011
+ // @ts-ignore
1012
+ dataTransfer: {
1013
+ files: droppedFiles,
1014
+ items: [
1015
+ {
1016
+ name: 'test.txt',
1017
+ },
1018
+ ],
1019
+ },
1020
+ preventDefault: () => {},
1021
+ });
1022
+ expect(_processFilesSpy).have.been.calledOnce;
1023
+ _processFilesSpy.restore();
1024
+ });
1025
+ });
1026
+ describe('uploadOnSelect as true', () => {
1027
+ it('should not remove file on click of cross button and fire file-removed event', async () => {
1028
+ /**
1029
+ * @type {Partial<InputFile>}
1030
+ */
1031
+ const removeFile = {
1032
+ name: 'foo.txt',
1033
+ status: 'SUCCESS',
1034
+ systemFile: {
1035
+ name: 'foo.txt',
1036
+ },
1037
+ response: {
1038
+ name: 'foo.txt',
1039
+ status: 'SUCCESS',
1040
+ },
1041
+ };
1042
+ const el = await fixture(html`
1043
+ <${tag} .uploadOnSelect="${true}"> </${tag}>
1044
+ `);
1045
+ el.modelValue = [file];
1046
+ mimicSelectFile(el, [file]);
1047
+ await el.updateComplete;
1048
+ setTimeout(() => {
1049
+ // @ts-ignore ignore file typing
1050
+ el._removeFile(removeFile);
1051
+ });
1052
+ const removeFileEvent = await oneEvent(el, 'file-removed');
1053
+
1054
+ // assertion for displayed file list to be same
1055
+ // @ts-expect-error [allow-protected-in-test]
1056
+ expect(el._selectedFilesMetaData.length).to.equal(1);
1057
+ // @ts-expect-error [allow-protected-in-test]
1058
+ expect(el._selectedFilesMetaData[0].systemFile.name).to.equal('foo.txt');
1059
+
1060
+ // assertion for event data
1061
+ expect(removeFileEvent).to.exist;
1062
+ expect(removeFileEvent.detail.removedFile).to.deep.equal({
1063
+ name: 'foo.txt',
1064
+ status: 'SUCCESS',
1065
+ systemFile: {
1066
+ name: 'foo.txt',
1067
+ },
1068
+ response: {
1069
+ name: 'foo.txt',
1070
+ status: 'SUCCESS',
1071
+ },
1072
+ });
1073
+ expect(removeFileEvent.detail.status).to.deep.equal('SUCCESS');
1074
+ expect(removeFileEvent.detail.uploadResponse).to.deep.equal({
1075
+ name: 'foo.txt',
1076
+ status: 'SUCCESS',
1077
+ });
1078
+ });
1079
+ it('should remove file from displayed list if not available in uploadResponse array', async () => {
1080
+ const uploadResponse = [
1081
+ {
1082
+ name: 'file1.txt',
1083
+ status: 'SUCCESS',
1084
+ errorMessage: '',
1085
+ downloadUrl: '/downloadFile',
1086
+ },
1087
+ {
1088
+ name: 'file2.txt',
1089
+ status: 'FAIL',
1090
+ errorMessage: 'something went wrong',
1091
+ },
1092
+ ];
1093
+ const el = await fixture(html`
1094
+ <${tag} label="Select" .uploadOnSelect="${true}"> </${tag}>
1095
+ `);
1096
+
1097
+ // @ts-expect-error [allow-protected-in-test]
1098
+ el.uploadResponse = uploadResponse;
1099
+ await el.updateComplete;
1100
+ // assertion for displayed file list to be same
1101
+ // @ts-expect-error [allow-protected-in-test]
1102
+ expect(el._selectedFilesMetaData.length).to.equal(2);
1103
+ el.uploadResponse = [
1104
+ {
1105
+ name: 'file1.txt',
1106
+ status: 'SUCCESS',
1107
+ errorMessage: '',
1108
+ downloadUrl: '/downloadFile',
1109
+ },
1110
+ ];
1111
+ await el.updateComplete;
1112
+ // assertion for displayed file list to be same
1113
+ // @ts-expect-error [allow-protected-in-test]
1114
+ expect(el._selectedFilesMetaData.length).to.equal(1);
1115
+ // @ts-expect-error [allow-protected-in-test]
1116
+ expect(el._selectedFilesMetaData[0].systemFile.name).to.equal('file1.txt');
1117
+ // @ts-expect-error [allow-protected-in-tests]
1118
+ expect(el._inputNode.value).to.equal('');
1119
+ });
1120
+ });
1121
+ describe('Accessibility', async () => {
1122
+ it('is accessible', async () => {
1123
+ const el = await fixture(html`<${tag} label="Select"></${tag}>`);
1124
+ await expect(el).to.be.accessible();
1125
+ });
1126
+ it('is accessible when a file is selected', async () => {
1127
+ const uploadResponse = [
1128
+ {
1129
+ name: 'file1.txt',
1130
+ status: 'SUCCESS',
1131
+ errorMessage: '',
1132
+ downloadUrl: '/downloadFile',
1133
+ },
1134
+ ];
1135
+ const el = await fixture(html` <${tag} label="Select"></${tag}>`);
1136
+
1137
+ // @ts-expect-error [allow-protected-in-test]
1138
+ el.uploadResponse = uploadResponse;
1139
+ await expect(el).to.be.accessible();
1140
+ });
1141
+ it('is accessible with an selected file and disabled', async () => {
1142
+ const uploadResponse = [
1143
+ {
1144
+ name: 'file1.txt',
1145
+ status: 'SUCCESS',
1146
+ errorMessage: '',
1147
+ downloadUrl: '/downloadFile',
1148
+ },
1149
+ ];
1150
+ const el = await fixture(html` <${tag} label="Select" disabled></${tag}> `);
1151
+
1152
+ // @ts-expect-error [allow-protected-in-test]
1153
+ el.uploadResponse = uploadResponse;
1154
+ await expect(el).to.be.accessible();
1155
+ });
1156
+ describe('has correct aria-roles', async () => {
1157
+ it('select-button has aria-labelledby set to itself and the label', async () => {
1158
+ const el = await fixture(html` <${tag} label="Select"></${tag}> `);
1159
+ // @ts-expect-error [allow-protected-in-test]
1160
+ expect(el._buttonNode?.getAttribute('aria-labelledby')).to.contain(
1161
+ // @ts-expect-error [allow-protected-in-test]
1162
+ `select-button-${el._inputId}`,
1163
+ );
1164
+ // @ts-expect-error [allow-protected-in-test]
1165
+ expect(el._buttonNode?.getAttribute('aria-labelledby')).to.contain(
1166
+ // @ts-expect-error [allow-protected-in-test]
1167
+ `label-${el._inputId}`,
1168
+ );
1169
+ });
1170
+ it('select-button has aria-describedby set to the help-text, after and the feedback message', async () => {
1171
+ const uploadResponse = [
1172
+ {
1173
+ name: 'file1.txt',
1174
+ status: 'SUCCESS',
1175
+ errorMessage: '',
1176
+ downloadUrl: '/downloadFile',
1177
+ },
1178
+ ];
1179
+ const el = await fixture(html`
1180
+ <${tag} label="Select" help-text="foo"></${tag}>
1181
+ `);
1182
+
1183
+ // @ts-expect-error [allow-protected-in-test]
1184
+ el.uploadResponse = uploadResponse;
1185
+
1186
+ // @ts-expect-error [allow-protected-in-test]
1187
+ expect(el._buttonNode?.getAttribute('aria-describedby')).to.contain(
1188
+ // @ts-expect-error [allow-protected-in-test]
1189
+ `help-text-${el._inputId}`,
1190
+ );
1191
+ // @ts-expect-error [allow-protected-in-test]
1192
+ expect(el._buttonNode?.getAttribute('aria-describedby')).to.contain(
1193
+ // @ts-expect-error [allow-protected-in-test]
1194
+ `feedback-${el._inputId}`,
1195
+ );
1196
+ // @ts-expect-error [allow-protected-in-test]
1197
+ expect(el._buttonNode?.getAttribute('aria-describedby')).to.contain(
1198
+ // @ts-expect-error [allow-protected-in-test]
1199
+ `after-${el._inputId}`,
1200
+ );
1201
+ });
1202
+ it('after contains upload name of file when uploadOnSelect is true and status is SUCCESS', async () => {
1203
+ const uploadResponse = [
1204
+ {
1205
+ name: 'file1.txt',
1206
+ status: 'SUCCESS',
1207
+ errorMessage: '',
1208
+ downloadUrl: '/downloadFile',
1209
+ },
1210
+ ];
1211
+ const el = await fixture(html`
1212
+ <${tag} label="Select" upload-on-select></${tag}>
1213
+ `);
1214
+ expect(el.querySelector('[slot="after"]')?.textContent).to.equal('No files uploaded.');
1215
+ // @ts-expect-error
1216
+ el.uploadResponse = uploadResponse;
1217
+ await el.updateComplete;
1218
+ expect(el.querySelector('[slot="after"]')?.textContent).to.equal(
1219
+ 'Uploaded file: file1.txt',
1220
+ );
1221
+ });
1222
+ it('after contains upload name of file when uploadOnSelect is false and status is SUCCESS', async () => {
1223
+ const uploadResponse = [
1224
+ {
1225
+ name: 'file1.txt',
1226
+ status: 'SUCCESS',
1227
+ errorMessage: '',
1228
+ downloadUrl: '/downloadFile',
1229
+ },
1230
+ ];
1231
+ const el = await fixture(html` <${tag} label="Select"></${tag}> `);
1232
+ expect(el.querySelector('[slot="after"]')?.textContent).to.equal('No files selected.');
1233
+ // @ts-expect-error
1234
+ el.uploadResponse = uploadResponse;
1235
+ await el.updateComplete;
1236
+ expect(el.querySelector('[slot="after"]')?.textContent).to.equal(
1237
+ 'Selected file: file1.txt',
1238
+ );
1239
+ });
1240
+ it('after contains upload validator message of file when FAIL', async () => {
1241
+ const uploadResponse = [
1242
+ {
1243
+ name: 'file1.txt',
1244
+ status: 'FAIL',
1245
+ errorMessage: 'something went wrong',
1246
+ downloadUrl: '/downloadFile',
1247
+ },
1248
+ ];
1249
+ const el = await fixture(html` <${tag} label="Select"></${tag}> `);
1250
+ expect(el.querySelector('[slot="after"]')?.textContent).to.equal('No files selected.');
1251
+ // @ts-expect-error
1252
+ el.uploadResponse = uploadResponse;
1253
+ await el.updateComplete;
1254
+ expect(el.querySelector('[slot="after"]')?.textContent).to.equal('something went wrong');
1255
+ });
1256
+ it('after contains upload status of files when uploadOnSelect is true and multiple files have been selected', async () => {
1257
+ const uploadResponse = [
1258
+ {
1259
+ name: 'file1.txt',
1260
+ status: 'SUCCESS',
1261
+ errorMessage: '',
1262
+ downloadUrl: '/downloadFile',
1263
+ },
1264
+ {
1265
+ name: 'file2.txt',
1266
+ status: 'FAIL',
1267
+ errorMessage: 'something went wrong',
1268
+ downloadUrl: '/downloadFile',
1269
+ },
1270
+ ];
1271
+ const el = await fixture(html`
1272
+ <${tag} label="Select" multiple upload-on-select></${tag}>
1273
+ `);
1274
+ // @ts-expect-error
1275
+ el.uploadResponse = uploadResponse;
1276
+ await el.updateComplete;
1277
+ expect(el.querySelector('[slot="after"]')?.textContent?.trim()).to.equal(
1278
+ 'Uploaded files: 2 files. "something went wrong", for file2.txt.',
1279
+ );
1280
+ });
1281
+ it('after contains upload status of files when uploadOnSelect is false and multiple files have been selected', async () => {
1282
+ const uploadResponse = [
1283
+ {
1284
+ name: 'file1.txt',
1285
+ status: 'SUCCESS',
1286
+ errorMessage: '',
1287
+ downloadUrl: '/downloadFile',
1288
+ },
1289
+ {
1290
+ name: 'file2.txt',
1291
+ status: 'FAIL',
1292
+ errorMessage: 'something went wrong',
1293
+ downloadUrl: '/downloadFile',
1294
+ },
1295
+ ];
1296
+ const el = await fixture(html`
1297
+ <${tag} label="Select" multiple></${tag}>
1298
+ `);
1299
+ // @ts-expect-error
1300
+ el.uploadResponse = uploadResponse;
1301
+ await el.updateComplete;
1302
+ expect(el.querySelector('[slot="after"]')?.textContent?.trim()).to.equal(
1303
+ 'Selected files: 2 files. "something went wrong", for file2.txt.',
1304
+ );
1305
+ });
1306
+ });
1307
+ });
1308
+ });
1309
+ describe('lion-selected-file-list, the file list lion-input-file renders', () => {
1310
+ // The list is its own element with its own type: cast the shared fixture for these tests.
1311
+ const listFixture =
1312
+ /** @type {(arg: TemplateResult) => Promise<LionSelectedFileList>} */
1313
+ _fixture;
1314
+ // The list is a separate element the input renders and a subclasser may replace, so it keeps its
1315
+ // own role key here instead of a suite and an entry point of its own.
1316
+ const listTagString = selectedFileListTagString;
1317
+ const listTag = unsafeStatic(listTagString);
1318
+
1319
+ /**
1320
+ * @type {Partial<InputFile>}
1321
+ */
1322
+ const fileSuccess = {
1323
+ name: 'foo.txt',
1324
+ status: 'SUCCESS',
1325
+ downloadUrl: '#foo',
1326
+ systemFile: {
1327
+ name: 'foo.txt',
1328
+ type: 'text/plain',
1329
+ size: 1000,
1330
+ status: 'SUCCESS',
1331
+ },
1332
+ response: {
1333
+ name: 'foo',
1334
+ type: 'text/plain',
1335
+ size: 1000,
1336
+ status: 'SUCCESS',
1337
+ },
1338
+ };
1339
+
1340
+ /**
1341
+ * @type {Partial<InputFile>}
1342
+ */
1343
+ const fileLoading = {
1344
+ status: 'LOADING',
1345
+ systemFile: {
1346
+ name: 'bar.txt',
1347
+ type: 'text/plain',
1348
+ size: 100,
1349
+ status: 'LOADING',
1350
+ },
1351
+ };
1352
+
1353
+ /**
1354
+ * @type {Partial<InputFile>}
1355
+ */
1356
+ const fileFail = {
1357
+ systemFile: {
1358
+ name: 'foobar.txt',
1359
+ type: 'text/plain',
1360
+ size: 1000,
1361
+ status: 'FAIL',
1362
+ },
1363
+ status: 'FAIL',
1364
+ validationFeedback: [
1365
+ {
1366
+ message: 'foobar',
1367
+ type: 'error',
1368
+ },
1369
+ ],
1370
+ };
1371
+ it('when empty show nothing', async () => {
1372
+ const el = await listFixture(html`<${listTag}></${listTag}>`);
1373
+ expect(el.children.length).to.equal(0);
1374
+ });
1375
+ it('can have 1 item', async () => {
1376
+ const el = await listFixture(html`
1377
+ <${listTag} .fileList="${[fileSuccess]}"></${listTag}>
1378
+ `);
1379
+ const fileItems = el.shadowRoot?.querySelectorAll('.selected__list__item');
1380
+ expect(fileItems?.length).to.equal(1);
1381
+ });
1382
+ it('shows a list when multiple', async () => {
1383
+ const el = await listFixture(html`
1384
+ <${listTag}
1385
+ .fileList="${[fileSuccess, fileLoading]}"
1386
+ .multiple="${true}"
1387
+ ></${listTag}>
1388
+ `);
1389
+ const fileItems = el.shadowRoot?.querySelectorAll('.selected__list__item');
1390
+ expect(fileItems?.length).to.equal(2);
1391
+ const fileList = el.shadowRoot?.querySelector('.selected__list');
1392
+ expect(fileList?.tagName).to.equal('UL');
1393
+ });
1394
+ it('displays an anchor when status="SUCCESS" and a downloadUrl is available', async () => {
1395
+ const el = await listFixture(html`
1396
+ <${listTag}
1397
+ .fileList="${[fileSuccess, fileLoading, fileFail]}"
1398
+ .multiple="${true}"
1399
+ ></${listTag}>
1400
+ `);
1401
+ const fileItems = el.shadowRoot?.querySelectorAll('.selected__list__item');
1402
+ // @ts-ignore
1403
+ expect(fileItems[0].querySelector('.selected__list__item__label__link')).to.exist;
1404
+ // @ts-ignore
1405
+ expect(fileItems[1].querySelector('.selected__list__item__label__link')).to.not.exist;
1406
+ // @ts-ignore
1407
+ expect(fileItems[2].querySelector('.selected__list__item__label__link')).to.not.exist;
1408
+ });
1409
+ it('displays a feedback message when status="FAIL"', async () => {
1410
+ const el = await listFixture(html`
1411
+ <${listTag} .fileList="${[fileFail]}"></${listTag}>
1412
+ `);
1413
+ const fileItems = el.shadowRoot?.querySelectorAll('.selected__list__item');
1414
+ const feedback = fileItems
1415
+ ? fileItems[0].querySelector('lion-validation-feedback')
1416
+ : undefined;
1417
+
1418
+ // @ts-ignore
1419
+ expect(feedback).to.exist;
1420
+ expect(el.shadowRoot?.textContent).to.include('foobar');
1421
+ });
1422
+ it('should call removeFile method on click of remove button', async () => {
1423
+ const el = await listFixture(html`
1424
+ <${listTag} .fileList="${[fileSuccess, fileLoading]}"></${listTag}>
1425
+ `);
1426
+
1427
+ /**
1428
+ * @type {HTMLButtonElement | null | undefined}
1429
+ */
1430
+ const removeButton = el.shadowRoot?.querySelector('.selected__list__item__remove-button');
1431
+ const removeFileSpy = sinon.spy(el, /** @type {keyof LionSelectedFileList} */ '_removeFile');
1432
+ removeButton?.click();
1433
+ expect(removeFileSpy).have.been.calledOnce;
1434
+ removeFileSpy.restore();
1435
+ });
1436
+ it('should fire file-remove-requested event with removed file data', async () => {
1437
+ const el = await listFixture(html`
1438
+ <${listTag} .fileList="${[fileSuccess, fileLoading]}"></${listTag}>
1439
+ `);
1440
+
1441
+ /**
1442
+ * @type {Partial<InputFile>}
1443
+ */
1444
+ const removedFile = {
1445
+ name: el.fileList[0].name,
1446
+ status: el.fileList[0].status,
1447
+ systemFile: {
1448
+ name: el.fileList[0].name,
1449
+ },
1450
+ response: {
1451
+ name: el.fileList[0].name,
1452
+ status: el.fileList[0].status,
1453
+ },
1454
+ };
1455
+ setTimeout(() => {
1456
+ // @ts-ignore ignore file typing
1457
+ el._removeFile(removedFile);
1458
+ });
1459
+ const removeFileEvent = await oneEvent(el, 'file-remove-requested');
1460
+ expect(removeFileEvent).to.exist;
1461
+ expect(removeFileEvent.detail.removedFile).to.deep.equal({
1462
+ name: 'foo.txt',
1463
+ status: 'SUCCESS',
1464
+ systemFile: {
1465
+ name: 'foo.txt',
1466
+ },
1467
+ response: {
1468
+ name: 'foo.txt',
1469
+ status: 'SUCCESS',
1470
+ },
1471
+ });
1472
+ expect(removeFileEvent.detail.status).to.deep.equal('SUCCESS');
1473
+ expect(removeFileEvent.detail.uploadResponse).to.deep.equal({
1474
+ name: 'foo.txt',
1475
+ status: 'SUCCESS',
1476
+ });
1477
+ });
1478
+ describe('Accessibility', async () => {
1479
+ it('is accessible', async () => {
1480
+ const el = await listFixture(html`<${listTag}
1481
+ .fileList="${[fileSuccess, fileLoading, fileFail]}"
1482
+ ></${listTag}>`);
1483
+ await expect(el).to.be.accessible();
1484
+ });
1485
+ it(`adds aria-live="polite" to the feedback slot on focus, aria-live="assertive" to the feedback slot on blur,
1486
+ so error messages appearing on blur will be read before those of the next input`, async () => {
1487
+ const el = await listFixture(html`
1488
+ <${listTag} .fileList="${[fileFail]}"></${listTag}>
1489
+ `);
1490
+ const fileFeedback = el?.shadowRoot?.querySelectorAll('[id^="file-feedback"]')[0];
1491
+ const removeButton =
1492
+ /** @type {HTMLButtonElement} */
1493
+ el.shadowRoot?.querySelector('.selected__list__item__remove-button');
1494
+ // @ts-ignore
1495
+ expect(fileFeedback.getAttribute('aria-live')).to.equal('assertive');
1496
+ removeButton?.focus();
1497
+ // @ts-ignore
1498
+ expect(fileFeedback.getAttribute('aria-live')).to.equal('polite');
1499
+ removeButton?.blur();
1500
+ // @ts-ignore
1501
+ expect(fileFeedback.getAttribute('aria-live')).to.equal('assertive');
1502
+ });
1503
+ });
1504
+ });
1505
+ }