@lion/ui 0.2.2 → 0.3.1

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 (304) hide show
  1. package/README.md +23 -72
  2. package/components/button/src/LionButton.js +1 -1
  3. package/components/checkbox-group/src/LionCheckboxIndeterminate.js +2 -2
  4. package/components/checkbox-group/test/lion-checkbox-indeterminate-integrations.test.js +6 -0
  5. package/components/checkbox-group/{test/lion-checkbox-indeterminate.test.js → test-suites/CheckboxIndeterminate.suite.js} +209 -187
  6. package/components/combobox/src/LionCombobox.js +3 -1
  7. package/components/combobox/test/lion-combobox.test.js +52 -0
  8. package/components/core/src/SlotMixin.js +3 -2
  9. package/components/core/test/SlotMixin.test.js +1 -1
  10. package/components/core/types/SlotMixinTypes.ts +4 -1
  11. package/components/dialog/test/lion-dialog.test.js +56 -0
  12. package/components/form-core/src/FocusMixin.js +33 -2
  13. package/components/form-core/src/LionField.js +3 -1
  14. package/components/form-core/src/validate/LionValidationFeedback.js +2 -5
  15. package/components/form-core/src/validate/ResultValidator.js +1 -1
  16. package/components/form-core/test/FocusMixin.test.js +33 -0
  17. package/components/form-core/types/validate/ValidateMixinTypes.ts +2 -2
  18. package/components/form-integrations/test/dialog-integrations.test.js +19 -0
  19. package/components/form-integrations/test/form-group-methods.test.js +11 -37
  20. package/components/form-integrations/test/form-integrations.test.js +4 -0
  21. package/components/form-integrations/test/helpers/umbrella-form.js +21 -18
  22. package/components/input-amount/src/LionInputAmount.js +13 -4
  23. package/components/input-amount/test/lion-input-amount.test.js +19 -20
  24. package/components/input-date/src/LionInputDate.js +2 -11
  25. package/components/input-datepicker/src/LionInputDatepicker.js +5 -2
  26. package/components/input-datepicker/test/lion-input-datepicker.test.js +20 -0
  27. package/components/input-file/src/FileHandle.js +98 -0
  28. package/components/input-file/src/LionInputFile.js +892 -0
  29. package/components/input-file/src/LionSelectedFileList.js +232 -0
  30. package/components/input-file/src/localizeNamespaceLoader.js +75 -0
  31. package/components/input-file/src/validators.js +114 -0
  32. package/components/input-file/test/FileValidators.test.js +170 -0
  33. package/components/input-file/test/lion-input-file.test.js +1168 -0
  34. package/components/input-file/test/lion-selected-file-list.test.js +207 -0
  35. package/components/input-file/translations/bg-BG.js +5 -0
  36. package/components/input-file/translations/bg.js +12 -0
  37. package/components/input-file/translations/cs-CZ.js +5 -0
  38. package/components/input-file/translations/cs.js +13 -0
  39. package/components/input-file/translations/de-DE.js +5 -0
  40. package/components/input-file/translations/de.js +12 -0
  41. package/components/input-file/translations/en-AU.js +5 -0
  42. package/components/input-file/translations/en-GB.js +5 -0
  43. package/components/input-file/translations/en-PH.js +5 -0
  44. package/components/input-file/translations/en-US.js +5 -0
  45. package/components/input-file/translations/en.js +12 -0
  46. package/components/input-file/translations/es-ES.js +5 -0
  47. package/components/input-file/translations/es.js +12 -0
  48. package/components/input-file/translations/fr-BE.js +5 -0
  49. package/components/input-file/translations/fr-FR.js +5 -0
  50. package/components/input-file/translations/fr.js +13 -0
  51. package/components/input-file/translations/hu-HU.js +5 -0
  52. package/components/input-file/translations/hu.js +12 -0
  53. package/components/input-file/translations/it-IT.js +5 -0
  54. package/components/input-file/translations/it.js +12 -0
  55. package/components/input-file/translations/nl-BE.js +5 -0
  56. package/components/input-file/translations/nl-NL.js +5 -0
  57. package/components/input-file/translations/nl.js +12 -0
  58. package/components/input-file/translations/pl-PL.js +5 -0
  59. package/components/input-file/translations/pl.js +12 -0
  60. package/components/input-file/translations/ro-RO.js +5 -0
  61. package/components/input-file/translations/ro.js +12 -0
  62. package/components/input-file/translations/ru-RU.js +5 -0
  63. package/components/input-file/translations/ru.js +12 -0
  64. package/components/input-file/translations/sk-SK.js +5 -0
  65. package/components/input-file/translations/sk.js +12 -0
  66. package/components/input-file/translations/uk-UA.js +5 -0
  67. package/components/input-file/translations/uk.js +12 -0
  68. package/components/input-file/translations/zh-CN.js +5 -0
  69. package/components/input-file/translations/zh.js +12 -0
  70. package/components/input-file/types/input-file.d.ts +32 -0
  71. package/components/input-tel-dropdown/src/LionInputTelDropdown.js +1 -4
  72. package/components/listbox/src/ListboxMixin.js +3 -2
  73. package/components/listbox/test-suites/ListboxMixin.suite.js +31 -1
  74. package/components/localize/src/number/utils/normalize-format-number-to-parts/forceNoSpaceBetweenCurrencySymbolAndNumber.js +22 -0
  75. package/components/localize/src/number/utils/normalize-format-number-to-parts/forceSymbols.js +64 -0
  76. package/components/localize/src/number/utils/normalize-format-number-to-parts/normalizeIntl.js +13 -7
  77. package/components/localize/test/number/formatNumber.test.js +6 -28
  78. package/custom-elements.json +13822 -9246
  79. package/dist-types/components/checkbox-group/test-suites/CheckboxIndeterminate.suite.d.ts +12 -0
  80. package/dist-types/components/checkbox-group/test-suites/CheckboxIndeterminate.suite.d.ts.map +1 -0
  81. package/dist-types/components/combobox/src/LionCombobox.d.ts.map +1 -1
  82. package/dist-types/components/combobox/test/lion-combobox.test.d.ts.map +1 -1
  83. package/dist-types/components/core/src/SlotMixin.d.ts.map +1 -1
  84. package/dist-types/components/core/types/SlotMixinTypes.d.ts +4 -0
  85. package/dist-types/components/core/types/SlotMixinTypes.d.ts.map +1 -1
  86. package/dist-types/components/dialog/test/lion-dialog.test.d.ts.map +1 -1
  87. package/dist-types/components/form-core/src/FocusMixin.d.ts.map +1 -1
  88. package/dist-types/components/form-core/src/LionField.d.ts +2 -1
  89. package/dist-types/components/form-core/src/LionField.d.ts.map +1 -1
  90. package/dist-types/components/form-core/src/validate/LionValidationFeedback.d.ts +4 -11
  91. package/dist-types/components/form-core/src/validate/LionValidationFeedback.d.ts.map +1 -1
  92. package/dist-types/components/form-core/src/validate/ResultValidator.d.ts +1 -1
  93. package/dist-types/components/form-core/types/validate/ValidateMixinTypes.d.ts +5 -0
  94. package/dist-types/components/form-core/types/validate/ValidateMixinTypes.d.ts.map +1 -1
  95. package/dist-types/components/form-integrations/test/dialog-integrations.test.d.ts.map +1 -1
  96. package/dist-types/components/form-integrations/test/form-group-methods.test.d.ts +1 -0
  97. package/dist-types/components/form-integrations/test/form-group-methods.test.d.ts.map +1 -1
  98. package/dist-types/components/form-integrations/test/helpers/umbrella-form.d.ts.map +1 -1
  99. package/dist-types/components/input-amount/src/LionInputAmount.d.ts +2 -4
  100. package/dist-types/components/input-amount/src/LionInputAmount.d.ts.map +1 -1
  101. package/dist-types/components/input-amount/test/lion-input-amount.test.d.ts +0 -1
  102. package/dist-types/components/input-amount/test/lion-input-amount.test.d.ts.map +1 -1
  103. package/dist-types/components/input-date/src/LionInputDate.d.ts.map +1 -1
  104. package/dist-types/components/input-datepicker/src/LionInputDatepicker.d.ts +1 -1
  105. package/dist-types/components/input-datepicker/src/LionInputDatepicker.d.ts.map +1 -1
  106. package/dist-types/components/input-file/src/FileHandle.d.ts +55 -0
  107. package/dist-types/components/input-file/src/FileHandle.d.ts.map +1 -0
  108. package/dist-types/components/input-file/src/LionInputFile.d.ts +230 -0
  109. package/dist-types/components/input-file/src/LionInputFile.d.ts.map +1 -0
  110. package/dist-types/components/input-file/src/LionSelectedFileList.d.ts +69 -0
  111. package/dist-types/components/input-file/src/LionSelectedFileList.d.ts.map +1 -0
  112. package/dist-types/components/input-file/src/localizeNamespaceLoader.d.ts +2 -0
  113. package/dist-types/components/input-file/src/localizeNamespaceLoader.d.ts.map +1 -0
  114. package/dist-types/components/input-file/src/validators.d.ts +58 -0
  115. package/dist-types/components/input-file/src/validators.d.ts.map +1 -0
  116. package/dist-types/components/input-file/test/FileValidators.test.d.ts +2 -0
  117. package/dist-types/components/input-file/test/FileValidators.test.d.ts.map +1 -0
  118. package/dist-types/components/input-file/test/lion-input-file.test.d.ts +5 -0
  119. package/dist-types/components/input-file/test/lion-input-file.test.d.ts.map +1 -0
  120. package/dist-types/components/input-file/test/lion-selected-file-list.test.d.ts +4 -0
  121. package/dist-types/components/input-file/test/lion-selected-file-list.test.d.ts.map +1 -0
  122. package/dist-types/components/input-file/translations/bg-BG.d.ts +13 -0
  123. package/dist-types/components/input-file/translations/bg-BG.d.ts.map +1 -0
  124. package/dist-types/components/input-file/translations/bg.d.ts +13 -0
  125. package/dist-types/components/input-file/translations/bg.d.ts.map +1 -0
  126. package/dist-types/components/input-file/translations/cs-CZ.d.ts +13 -0
  127. package/dist-types/components/input-file/translations/cs-CZ.d.ts.map +1 -0
  128. package/dist-types/components/input-file/translations/cs.d.ts +13 -0
  129. package/dist-types/components/input-file/translations/cs.d.ts.map +1 -0
  130. package/dist-types/components/input-file/translations/de-DE.d.ts +13 -0
  131. package/dist-types/components/input-file/translations/de-DE.d.ts.map +1 -0
  132. package/dist-types/components/input-file/translations/de.d.ts +13 -0
  133. package/dist-types/components/input-file/translations/de.d.ts.map +1 -0
  134. package/dist-types/components/input-file/translations/en-AU.d.ts +13 -0
  135. package/dist-types/components/input-file/translations/en-AU.d.ts.map +1 -0
  136. package/dist-types/components/input-file/translations/en-GB.d.ts +13 -0
  137. package/dist-types/components/input-file/translations/en-GB.d.ts.map +1 -0
  138. package/dist-types/components/input-file/translations/en-PH.d.ts +13 -0
  139. package/dist-types/components/input-file/translations/en-PH.d.ts.map +1 -0
  140. package/dist-types/components/input-file/translations/en-US.d.ts +13 -0
  141. package/dist-types/components/input-file/translations/en-US.d.ts.map +1 -0
  142. package/dist-types/components/input-file/translations/en.d.ts +13 -0
  143. package/dist-types/components/input-file/translations/en.d.ts.map +1 -0
  144. package/dist-types/components/input-file/translations/es-ES.d.ts +13 -0
  145. package/dist-types/components/input-file/translations/es-ES.d.ts.map +1 -0
  146. package/dist-types/components/input-file/translations/es.d.ts +13 -0
  147. package/dist-types/components/input-file/translations/es.d.ts.map +1 -0
  148. package/dist-types/components/input-file/translations/fr-BE.d.ts +13 -0
  149. package/dist-types/components/input-file/translations/fr-BE.d.ts.map +1 -0
  150. package/dist-types/components/input-file/translations/fr-FR.d.ts +13 -0
  151. package/dist-types/components/input-file/translations/fr-FR.d.ts.map +1 -0
  152. package/dist-types/components/input-file/translations/fr.d.ts +13 -0
  153. package/dist-types/components/input-file/translations/fr.d.ts.map +1 -0
  154. package/dist-types/components/input-file/translations/hu-HU.d.ts +13 -0
  155. package/dist-types/components/input-file/translations/hu-HU.d.ts.map +1 -0
  156. package/dist-types/components/input-file/translations/hu.d.ts +13 -0
  157. package/dist-types/components/input-file/translations/hu.d.ts.map +1 -0
  158. package/dist-types/components/input-file/translations/it-IT.d.ts +13 -0
  159. package/dist-types/components/input-file/translations/it-IT.d.ts.map +1 -0
  160. package/dist-types/components/input-file/translations/it.d.ts +13 -0
  161. package/dist-types/components/input-file/translations/it.d.ts.map +1 -0
  162. package/dist-types/components/input-file/translations/nl-BE.d.ts +13 -0
  163. package/dist-types/components/input-file/translations/nl-BE.d.ts.map +1 -0
  164. package/dist-types/components/input-file/translations/nl-NL.d.ts +13 -0
  165. package/dist-types/components/input-file/translations/nl-NL.d.ts.map +1 -0
  166. package/dist-types/components/input-file/translations/nl.d.ts +13 -0
  167. package/dist-types/components/input-file/translations/nl.d.ts.map +1 -0
  168. package/dist-types/components/input-file/translations/pl-PL.d.ts +13 -0
  169. package/dist-types/components/input-file/translations/pl-PL.d.ts.map +1 -0
  170. package/dist-types/components/input-file/translations/pl.d.ts +13 -0
  171. package/dist-types/components/input-file/translations/pl.d.ts.map +1 -0
  172. package/dist-types/components/input-file/translations/ro-RO.d.ts +13 -0
  173. package/dist-types/components/input-file/translations/ro-RO.d.ts.map +1 -0
  174. package/dist-types/components/input-file/translations/ro.d.ts +13 -0
  175. package/dist-types/components/input-file/translations/ro.d.ts.map +1 -0
  176. package/dist-types/components/input-file/translations/ru-RU.d.ts +13 -0
  177. package/dist-types/components/input-file/translations/ru-RU.d.ts.map +1 -0
  178. package/dist-types/components/input-file/translations/ru.d.ts +13 -0
  179. package/dist-types/components/input-file/translations/ru.d.ts.map +1 -0
  180. package/dist-types/components/input-file/translations/sk-SK.d.ts +13 -0
  181. package/dist-types/components/input-file/translations/sk-SK.d.ts.map +1 -0
  182. package/dist-types/components/input-file/translations/sk.d.ts +13 -0
  183. package/dist-types/components/input-file/translations/sk.d.ts.map +1 -0
  184. package/dist-types/components/input-file/translations/uk-UA.d.ts +13 -0
  185. package/dist-types/components/input-file/translations/uk-UA.d.ts.map +1 -0
  186. package/dist-types/components/input-file/translations/uk.d.ts +13 -0
  187. package/dist-types/components/input-file/translations/uk.d.ts.map +1 -0
  188. package/dist-types/components/input-file/translations/zh-CN.d.ts +13 -0
  189. package/dist-types/components/input-file/translations/zh-CN.d.ts.map +1 -0
  190. package/dist-types/components/input-file/translations/zh.d.ts +13 -0
  191. package/dist-types/components/input-file/translations/zh.d.ts.map +1 -0
  192. package/dist-types/components/input-stepper/src/LionInputStepper.d.ts +6 -0
  193. package/dist-types/components/input-stepper/src/LionInputStepper.d.ts.map +1 -1
  194. package/dist-types/components/input-tel-dropdown/src/LionInputTelDropdown.d.ts +0 -1
  195. package/dist-types/components/input-tel-dropdown/src/LionInputTelDropdown.d.ts.map +1 -1
  196. package/dist-types/components/listbox/src/ListboxMixin.d.ts.map +1 -1
  197. package/dist-types/components/listbox/test-suites/ListboxMixin.suite.d.ts.map +1 -1
  198. package/dist-types/components/localize/src/number/utils/normalize-format-number-to-parts/forceNoSpaceBetweenCurrencySymbolAndNumber.d.ts +14 -0
  199. package/dist-types/components/localize/src/number/utils/normalize-format-number-to-parts/forceNoSpaceBetweenCurrencySymbolAndNumber.d.ts.map +1 -0
  200. package/dist-types/components/localize/src/number/utils/normalize-format-number-to-parts/forceSymbols.d.ts +20 -0
  201. package/dist-types/components/localize/src/number/utils/normalize-format-number-to-parts/forceSymbols.d.ts.map +1 -0
  202. package/dist-types/components/localize/src/number/utils/normalize-format-number-to-parts/normalizeIntl.d.ts.map +1 -1
  203. package/dist-types/exports/checkbox-group-test-suites.d.ts +2 -0
  204. package/dist-types/exports/checkbox-group-test-suites.d.ts.map +1 -0
  205. package/dist-types/exports/define/lion-input-file.d.ts +2 -0
  206. package/dist-types/exports/define/lion-input-file.d.ts.map +1 -0
  207. package/dist-types/exports/define/lion-selected-file-list.d.ts +2 -0
  208. package/dist-types/exports/define/lion-selected-file-list.d.ts.map +1 -0
  209. package/dist-types/exports/input-file.d.ts +4 -0
  210. package/dist-types/exports/input-file.d.ts.map +1 -0
  211. package/dist-types/tsconfig.tsbuildinfo +1 -1
  212. package/docs/components/button/extensions/bootstrap-button.mjs +240 -0
  213. package/docs/components/button/extensions.md +30 -0
  214. package/docs/components/checkbox-group/overview.md +9 -10
  215. package/docs/components/checkbox-group/use-cases.md +110 -142
  216. package/docs/components/collapsible/overview.md +1 -1
  217. package/docs/components/combobox/{examples.md → extensions.md} +51 -43
  218. package/docs/components/combobox/overview.md +1 -1
  219. package/docs/components/combobox/src/google-combobox/google-combobox.js +4 -1
  220. package/docs/components/combobox/src/md-combobox/md-combobox.js +40 -38
  221. package/docs/components/combobox/src/wa-combobox/wa-combobox.js +204 -209
  222. package/docs/components/combobox/use-cases.md +1 -1
  223. package/docs/components/dialog/overview.md +1 -1
  224. package/docs/components/fieldset/overview.md +5 -5
  225. package/docs/components/form/overview.md +3 -3
  226. package/docs/components/icon/use-cases.md +1 -1
  227. package/docs/components/input/overview.md +1 -1
  228. package/docs/components/input-amount/overview.md +3 -3
  229. package/docs/components/input-amount/use-cases.md +4 -2
  230. package/docs/components/input-date/overview.md +3 -3
  231. package/docs/components/input-datepicker/overview.md +5 -5
  232. package/docs/components/input-datepicker/use-cases.md +11 -0
  233. package/docs/components/input-email/overview.md +2 -2
  234. package/docs/components/input-file/index.md +3 -0
  235. package/docs/components/input-file/overview.md +32 -0
  236. package/docs/components/input-file/use-cases.md +424 -0
  237. package/docs/components/input-iban/overview.md +2 -2
  238. package/docs/components/input-range/overview.md +2 -2
  239. package/docs/components/input-stepper/overview.md +1 -1
  240. package/docs/components/input-tel/overview.md +1 -1
  241. package/docs/components/input-tel/use-cases.md +6 -6
  242. package/docs/components/input-tel-dropdown/{examples.md → extensions.md} +1 -1
  243. package/docs/components/input-tel-dropdown/overview.md +1 -1
  244. package/docs/components/radio-group/overview.md +3 -3
  245. package/docs/components/select-rich/use-cases.md +1 -1
  246. package/docs/components/tabs/examples.md +1 -1
  247. package/docs/fundamentals/index.md +4 -4
  248. package/docs/fundamentals/node-tools/providence-analytics/LocalConfiguration.md +1 -1
  249. package/docs/fundamentals/node-tools/providence-analytics/QueryResult.md +1 -1
  250. package/docs/fundamentals/node-tools/providence-analytics/analyzer.md +1 -1
  251. package/docs/fundamentals/node-tools/providence-analytics/dashboard.md +1 -1
  252. package/docs/fundamentals/node-tools/providence-analytics/overview.md +3 -3
  253. package/docs/fundamentals/node-tools/publish-docs/overview.md +3 -3
  254. package/docs/fundamentals/node-tools/rocket-preset-extend-lion-docs/overview.md +2 -2
  255. package/docs/fundamentals/rationales/accessibility.md +28 -0
  256. package/docs/fundamentals/systems/core/SlotMixin.md +148 -0
  257. package/docs/fundamentals/systems/core/overview.md +1 -1
  258. package/docs/fundamentals/systems/form/formatting-and-parsing.md +4 -4
  259. package/docs/fundamentals/systems/form/model-value.md +1 -1
  260. package/docs/fundamentals/systems/form/overview.md +28 -28
  261. package/docs/fundamentals/systems/form/use-cases.md +2 -0
  262. package/docs/fundamentals/systems/form/validate.md +1 -1
  263. package/docs/fundamentals/systems/localize/overview.md +4 -4
  264. package/docs/fundamentals/systems/overlays/_configuration-positioning.md +116 -0
  265. package/docs/fundamentals/systems/overlays/_edge-cases.md +145 -0
  266. package/docs/fundamentals/systems/overlays/configuration.md +2 -2
  267. package/docs/fundamentals/systems/overlays/overview.md +5 -5
  268. package/docs/fundamentals/systems/overlays/use-cases.md +2 -2
  269. package/docs/fundamentals/tools/helpers/overview.md +1 -1
  270. package/docs/fundamentals/tools/singleton-manager/example-complex/index.md +21 -0
  271. package/docs/fundamentals/tools/singleton-manager/example-fail/index.md +19 -0
  272. package/docs/fundamentals/tools/singleton-manager/example-success/index.md +18 -0
  273. package/docs/fundamentals/tools/singleton-manager/overview.md +4 -4
  274. package/docs/guides/how-to/create-a-custom-field.md +5 -5
  275. package/docs/guides/how-to/create-a-form.md +88 -0
  276. package/docs/guides/how-to/extend-a-native-input.md +2 -2
  277. package/docs/guides/how-to/get-started.md +28 -1
  278. package/docs/guides/index.md +8 -8
  279. package/docs/guides/principles/index.md +5 -5
  280. package/docs/guides/principles/styling.md +1 -1
  281. package/exports/checkbox-group-test-suites.js +1 -0
  282. package/exports/define/lion-input-file.js +3 -0
  283. package/exports/define/lion-selected-file-list.js +3 -0
  284. package/exports/input-file.js +3 -0
  285. package/package.json +3 -2
  286. package/components/localize/src/number/utils/normalize-format-number-to-parts/forceENAUSymbols.js +0 -25
  287. package/components/localize/src/number/utils/normalize-format-number-to-parts/forceYenSymbol.js +0 -15
  288. package/dist-types/components/checkbox-group/test/lion-checkbox-indeterminate.test.d.ts +0 -4
  289. package/dist-types/components/checkbox-group/test/lion-checkbox-indeterminate.test.d.ts.map +0 -1
  290. package/dist-types/components/localize/src/number/utils/normalize-format-number-to-parts/forceENAUSymbols.d.ts +0 -14
  291. package/dist-types/components/localize/src/number/utils/normalize-format-number-to-parts/forceENAUSymbols.d.ts.map +0 -1
  292. package/dist-types/components/localize/src/number/utils/normalize-format-number-to-parts/forceYenSymbol.d.ts +0 -9
  293. package/dist-types/components/localize/src/number/utils/normalize-format-number-to-parts/forceYenSymbol.d.ts.map +0 -1
  294. package/docs/components/combobox/src/google-combobox/assets/googlelogo_color_272x92dp.png +0 -0
  295. package/docs/components/dialog/src/demo-dialog-style.js +0 -3
  296. package/docs/components/select-rich/src/flags.png +0 -0
  297. package/docs/components/select-rich/src/flags@2x.png +0 -0
  298. package/docs/fundamentals/systems/form/assets/FormatMixinDiagram-1.svg +0 -1
  299. package/docs/fundamentals/systems/form/assets/FormatMixinDiagram-2.svg +0 -1
  300. package/docs/fundamentals/systems/form/assets/FormatMixinDiagram-3.svg +0 -84
  301. package/docs/fundamentals/tools/ajax/assets/naga.json +0 -9
  302. package/docs/fundamentals/tools/ajax/assets/pabu.json +0 -9
  303. package/docs/fundamentals/tools/singleton-manager/.gitignore +0 -1
  304. package/docs/override.js +0 -15
@@ -12,6 +12,7 @@ import '@lion/ui/define/lion-listbox.js';
12
12
  import '@lion/ui/define/lion-option.js';
13
13
  import { Required, Unparseable } from '@lion/ui/form-core.js';
14
14
  import { defineCE, expect, fixture, html, unsafeStatic } from '@open-wc/testing';
15
+ import { sendKeys } from '@web/test-runner-commands';
15
16
  import { LitElement } from 'lit';
16
17
  import sinon from 'sinon';
17
18
 
@@ -2678,6 +2679,57 @@ describe('lion-combobox', () => {
2678
2679
  mimicKeyPress(visibleOptions[1], 'Enter');
2679
2680
  expect(el.opened).to.equal(true);
2680
2681
  });
2682
+
2683
+ it('submits form on [Enter] when listbox is closed', async () => {
2684
+ const submitSpy = sinon.spy(e => e.preventDefault());
2685
+ const el = /** @type {HTMLFormElement} */ (
2686
+ await fixture(html`
2687
+ <form @submit=${submitSpy}>
2688
+ <lion-combobox name="foo" multiple-choice>
2689
+ <lion-option .choiceValue="${'Artichoke'}">Artichoke</lion-option>
2690
+ <lion-option .choiceValue="${'Chard'}">Chard</lion-option>
2691
+ <lion-option .choiceValue="${'Chicory'}">Chicory</lion-option>
2692
+ <lion-option .choiceValue="${'Victoria Plum'}">Victoria Plum</lion-option>
2693
+ </lion-combobox>
2694
+ <button type="submit">submit</button>
2695
+ </form>
2696
+ `)
2697
+ );
2698
+ const combobox = /** @type {LionCombobox} */ (el.querySelector('[name="foo"]'));
2699
+ const { _inputNode } = getComboboxMembers(combobox);
2700
+ await combobox.updateComplete;
2701
+ _inputNode.focus();
2702
+ await sendKeys({
2703
+ press: 'Enter',
2704
+ });
2705
+ expect(submitSpy.callCount).to.equal(1);
2706
+ });
2707
+
2708
+ it('does not submit form on [Enter] when listbox is opened', async () => {
2709
+ const submitSpy = sinon.spy(e => e.preventDefault());
2710
+ const el = /** @type {HTMLFormElement} */ (
2711
+ await fixture(html`
2712
+ <form @submit=${submitSpy}>
2713
+ <lion-combobox name="foo" multiple-choice>
2714
+ <lion-option .choiceValue="${'Artichoke'}">Artichoke</lion-option>
2715
+ <lion-option .choiceValue="${'Chard'}">Chard</lion-option>
2716
+ <lion-option .choiceValue="${'Chicory'}">Chicory</lion-option>
2717
+ <lion-option .choiceValue="${'Victoria Plum'}">Victoria Plum</lion-option>
2718
+ </lion-combobox>
2719
+ <button type="submit">submit</button>
2720
+ </form>
2721
+ `)
2722
+ );
2723
+ const combobox = /** @type {LionCombobox} */ (el.querySelector('[name="foo"]'));
2724
+ const { _inputNode } = getComboboxMembers(combobox);
2725
+ combobox.opened = true;
2726
+ await combobox.updateComplete;
2727
+ _inputNode.focus();
2728
+ await sendKeys({
2729
+ press: 'Enter',
2730
+ });
2731
+ expect(submitSpy.callCount).to.equal(0);
2732
+ });
2681
2733
  });
2682
2734
 
2683
2735
  describe('Match Mode', () => {
@@ -83,6 +83,7 @@ const SlotMixinImplementation = superclass =>
83
83
  slotName,
84
84
  shouldRerender: true,
85
85
  });
86
+ // TODO: this is deprecated, remove later
86
87
  slotFunctionResult.afterRender?.();
87
88
  }
88
89
 
@@ -90,8 +91,8 @@ const SlotMixinImplementation = superclass =>
90
91
  * Here we rerender slots defined with a `SlotRerenderObject`
91
92
  * @param {import('lit-element').PropertyValues } changedProperties
92
93
  */
93
- updated(changedProperties) {
94
- super.updated(changedProperties);
94
+ update(changedProperties) {
95
+ super.update(changedProperties);
95
96
 
96
97
  if (this.__slotsThatNeedRerender.size) {
97
98
  for (const slotName of Array.from(this.__slotsThatNeedRerender)) {
@@ -383,7 +383,7 @@ describe('SlotMixin', () => {
383
383
  expect(slot.tagName).to.equal('SPAN');
384
384
  });
385
385
 
386
- it('supports afterRender logic (type "{ template:TemplateResults; afterRender: Function}" )', async () => {
386
+ it('supports (deprecated) afterRender logic (type "{ template:TemplateResults; afterRender: Function}" )', async () => {
387
387
  let varThatProvesAfterRenderIsCalled = 'not called';
388
388
 
389
389
  const tag = defineCE(
@@ -6,7 +6,10 @@ import { TemplateResult, LitElement } from 'lit';
6
6
  */
7
7
  export type SlotRerenderObject = {
8
8
  template: TemplateResult;
9
- /* Add logic that will be performed after the render */
9
+ /**
10
+ * Add logic that will be performed after the render
11
+ * @deprecated
12
+ */
10
13
  afterRender?: Function;
11
14
  };
12
15
 
@@ -1,3 +1,4 @@
1
+ /* eslint-disable lit-a11y/no-autofocus */
1
2
  import { expect, fixture as _fixture, html, unsafeStatic } from '@open-wc/testing';
2
3
  import { runOverlayMixinSuite } from '../../overlays/test-suites/OverlayMixin.suite.js';
3
4
  import '@lion/ui/define/lion-dialog.js';
@@ -72,4 +73,59 @@ describe('lion-dialog', () => {
72
73
  expect(nestedDialogEl.opened).to.be.true;
73
74
  });
74
75
  });
76
+
77
+ describe('focus', () => {
78
+ it('sets focus on contentSlot by default', async () => {
79
+ const el = await fixture(html`
80
+ <lion-dialog>
81
+ <button slot="invoker">invoker button</button>
82
+ <div slot="content">
83
+ <label for="myInput">Label</label>
84
+ <input id="myInput" />
85
+ </div>
86
+ </lion-dialog>
87
+ `);
88
+ // @ts-expect-error [allow-protected-in-tests]
89
+ const invokerNode = el._overlayInvokerNode;
90
+ invokerNode.focus();
91
+ invokerNode.click();
92
+ const contentNode = el.querySelector('[slot="content"]');
93
+ expect(document.activeElement).to.equal(contentNode);
94
+ });
95
+
96
+ it('sets focus on autofocused element', async () => {
97
+ const el = await fixture(html`
98
+ <lion-dialog>
99
+ <button slot="invoker">invoker button</button>
100
+ <div slot="content">
101
+ <label for="myInput">Label</label>
102
+ <input id="myInput" autofocus />
103
+ </div>
104
+ </lion-dialog>
105
+ `);
106
+ // @ts-expect-error [allow-protected-in-tests]
107
+ const invokerNode = el._overlayInvokerNode;
108
+ invokerNode.focus();
109
+ invokerNode.click();
110
+ const input = el.querySelector('input');
111
+ expect(document.activeElement).to.equal(input);
112
+ });
113
+
114
+ it('with trapsKeyboardFocus set to false the focus stays on the invoker', async () => {
115
+ const el = /** @type {LionDialog} */ await fixture(html`
116
+ <lion-dialog .config=${{ trapsKeyboardFocus: false }}>
117
+ <button slot="invoker">invoker button</button>
118
+ <div slot="content">
119
+ <label for="myInput">Label</label>
120
+ <input id="myInput" autofocus />
121
+ </div>
122
+ </lion-dialog>
123
+ `);
124
+ // @ts-expect-error [allow-protected-in-tests]
125
+ const invokerNode = el._overlayInvokerNode;
126
+ invokerNode.focus();
127
+ invokerNode.click();
128
+ expect(document.activeElement).to.equal(invokerNode);
129
+ });
130
+ });
75
131
  });
@@ -27,6 +27,7 @@ const FocusMixinImplementation = superclass =>
27
27
  return {
28
28
  focused: { type: Boolean, reflect: true },
29
29
  focusedVisible: { type: Boolean, reflect: true, attribute: 'focused-visible' },
30
+ autofocus: { type: Boolean, reflect: true }, // Required in Lit to observe autofocus
30
31
  };
31
32
  }
32
33
 
@@ -47,11 +48,16 @@ const FocusMixinImplementation = superclass =>
47
48
  * @type {boolean}
48
49
  */
49
50
  this.focusedVisible = false;
51
+ this.autofocus = false;
50
52
  }
51
53
 
52
- connectedCallback() {
53
- super.connectedCallback();
54
+ /**
55
+ * @param {import('lit').PropertyValues } changedProperties
56
+ */
57
+ firstUpdated(changedProperties) {
58
+ super.firstUpdated(changedProperties);
54
59
  this.__registerEventsForFocusMixin();
60
+ this.__syncAutofocusToFocusableElement();
55
61
  }
56
62
 
57
63
  disconnectedCallback() {
@@ -59,6 +65,31 @@ const FocusMixinImplementation = superclass =>
59
65
  this.__teardownEventsForFocusMixin();
60
66
  }
61
67
 
68
+ /**
69
+ * @param {import('lit').PropertyValues } changedProperties
70
+ */
71
+ updated(changedProperties) {
72
+ super.updated(changedProperties);
73
+ if (changedProperties.has('autofocus')) {
74
+ this.__syncAutofocusToFocusableElement();
75
+ }
76
+ }
77
+
78
+ /**
79
+ * @private
80
+ */
81
+ __syncAutofocusToFocusableElement() {
82
+ if (!this._focusableNode) {
83
+ return;
84
+ }
85
+
86
+ if (this.hasAttribute('autofocus')) {
87
+ this._focusableNode.setAttribute('autofocus', '');
88
+ } else {
89
+ this._focusableNode.removeAttribute('autofocus');
90
+ }
91
+ }
92
+
62
93
  /**
63
94
  * Calls `focus()` on focusable element within
64
95
  */
@@ -72,9 +72,11 @@ export class LionField extends FormControlMixin(
72
72
 
73
73
  /**
74
74
  * Dispatches custom bubble event
75
+ * @param {Event=} ev
75
76
  * @protected
76
77
  */
77
- _onChange() {
78
+ // eslint-disable-next-line no-unused-vars
79
+ _onChange(ev) {
78
80
  /** @protectedEvent user-input-changed */
79
81
  this.dispatchEvent(new Event('user-input-changed', { bubbles: true }));
80
82
  }
@@ -3,10 +3,7 @@ import { html, LitElement } from 'lit';
3
3
  /**
4
4
  * @typedef {import('./Validator.js').Validator} Validator
5
5
  * @typedef {import('lit').TemplateResult} TemplateResult
6
- * @typedef {Object} messageMap
7
- * @property {string | Node} message
8
- * @property {string} type
9
- * @property {Validator} [validator]
6
+ * @typedef {import('../../types/validate/ValidateMixinTypes.js').FeedbackMessage} FeedbackMessage
10
7
  */
11
8
 
12
9
  /**
@@ -47,7 +44,7 @@ export class LionValidationFeedback extends LitElement {
47
44
  if (this.currentType === 'success') {
48
45
  this.removeMessage = window.setTimeout(() => {
49
46
  this.removeAttribute('type');
50
- /** @type {messageMap[]} */
47
+ /** @type {FeedbackMessage[]} */
51
48
  this.feedbackData = [];
52
49
  }, 3000);
53
50
  }
@@ -1,7 +1,7 @@
1
1
  import { Validator } from './Validator.js';
2
2
 
3
3
  /**
4
- * @desc Instead of evaluating the result of a regular validator, a ResultValidator looks
4
+ * Instead of evaluating the result of a regular Validator, a ResultValidator looks
5
5
  * at the total result of regular Validators. Instead of an execute function, it uses a
6
6
  * 'executeOnResults' Validator.
7
7
  * ResultValidators cannot be async, and should not contain an execute method.
@@ -323,6 +323,39 @@ describe('FocusMixin', () => {
323
323
  spy4.restore();
324
324
  restoreMock4();
325
325
  });
326
+
327
+ it('has mirrors syncs autofocus on the focusable element when autofocus changes', async () => {
328
+ const el = /** @type {Focusable} */ (
329
+ await fixture(html`
330
+ <${tag}><input slot="input"></${tag}>
331
+ `)
332
+ );
333
+
334
+ // @ts-ignore [allow-protected] in test
335
+ const { _focusableNode } = el;
336
+
337
+ el.setAttribute('autofocus', '');
338
+ await el.updateComplete;
339
+ expect(_focusableNode.hasAttribute('autofocus')).to.be.true;
340
+
341
+ el.removeAttribute('autofocus');
342
+ await el.updateComplete;
343
+ expect(_focusableNode.hasAttribute('autofocus')).not.to.be.true;
344
+ });
345
+
346
+ it('has mirrors syncs autofocus on the focusable element when autofocus was set on render', async () => {
347
+ const el = /** @type {Focusable} */ (
348
+ await fixture(html`
349
+ <${tag} autofocus><input slot="input"></${tag}>
350
+ `)
351
+ );
352
+
353
+ // @ts-ignore [allow-protected] in test
354
+ const { _focusableNode } = el;
355
+
356
+ expect(el.hasAttribute('autofocus')).to.be.true;
357
+ expect(_focusableNode.hasAttribute('autofocus')).to.be.true;
358
+ });
326
359
  });
327
360
  });
328
361
  });
@@ -9,9 +9,9 @@ import { FormControlHost } from '../FormControlMixinTypes.js';
9
9
  import { SyncUpdatableHost } from '../utils/SyncUpdatableMixinTypes.js';
10
10
  import { Validator } from '../../src/validate/Validator.js';
11
11
 
12
- type FeedbackMessage = {
12
+ export type FeedbackMessage = {
13
13
  message: string | Node;
14
- type: string;
14
+ type: ValidationType | string;
15
15
  validator?: Validator;
16
16
  };
17
17
 
@@ -1,3 +1,4 @@
1
+ /* eslint-disable lit-a11y/no-autofocus */
1
2
  import { expect, fixture } from '@open-wc/testing';
2
3
  import { html } from 'lit';
3
4
  import { getAllTagNames } from './helpers/helpers.js';
@@ -36,6 +37,7 @@ describe('Form inside dialog Integrations', () => {
36
37
  'lion-input-amount',
37
38
  'lion-input-iban',
38
39
  'lion-input-email',
40
+ 'lion-input-file',
39
41
  'lion-input-tel',
40
42
  'lion-input-tel-dropdown',
41
43
  'lion-checkbox-group',
@@ -70,4 +72,21 @@ describe('Form inside dialog Integrations', () => {
70
72
  'lion-textarea',
71
73
  ]);
72
74
  });
75
+
76
+ it('sets focus on first focusable element with autofocus', async () => {
77
+ const el = /** @type {LionDialog} */ await fixture(html`
78
+ <lion-dialog>
79
+ <button slot="invoker">invoker button</button>
80
+ <div slot="content">
81
+ <lion-input label="label" name="input" autofocus></lion-input>
82
+ <lion-textarea label="label" name="textarea" autofocus></lion-textarea>
83
+ </div>
84
+ </lion-dialog>
85
+ `);
86
+ // @ts-expect-error [allow-protected-in-tests]
87
+ el._overlayInvokerNode.click();
88
+ const lionInput = el.querySelector('[name="input"]');
89
+ // @ts-expect-error [allow-protected-in-tests]
90
+ expect(document.activeElement).to.equal(lionInput._focusableNode);
91
+ });
73
92
  });
@@ -1,49 +1,20 @@
1
1
  import { elementUpdated, expect, fixture } from '@open-wc/testing';
2
2
  import { html } from 'lit';
3
- import './helpers/umbrella-form.js';
4
3
  import { getAllFieldsAndFormGroups } from './helpers/helpers.js';
5
-
6
- import '@lion/ui/define/lion-button.js';
7
- import '@lion/ui/define/lion-button-submit.js';
8
- import '@lion/ui/define/lion-button-reset.js';
9
-
10
- import '@lion/ui/define/lion-checkbox.js';
11
- import '@lion/ui/define/lion-checkbox-group.js';
12
- import '@lion/ui/define/lion-combobox.js';
13
-
14
- import '@lion/ui/define/lion-dialog.js';
15
-
16
- import '@lion/ui/define/lion-form.js';
17
- import '@lion/ui/define/lion-fieldset.js';
18
- import '@lion/ui/define/lion-select-rich.js';
19
- import '@lion/ui/define/lion-select.js';
20
-
21
- import '@lion/ui/define/lion-input-stepper.js';
22
- import '@lion/ui/define/lion-input-range.js';
23
- import '@lion/ui/define/lion-input-amount.js';
24
- import '@lion/ui/define/lion-input.js';
25
- import '@lion/ui/define/lion-input-date.js';
26
- import '@lion/ui/define/lion-input-iban.js';
27
- import '@lion/ui/define/lion-input-email.js';
28
- import '@lion/ui/define/lion-input-tel-dropdown.js';
29
- import '@lion/ui/define/lion-input-datepicker.js';
30
-
31
- import '@lion/ui/define/lion-textarea.js';
32
-
33
- import '@lion/ui/define/lion-radio.js';
34
- import '@lion/ui/define/lion-radio-group.js';
35
-
36
- import '@lion/ui/define/lion-listbox.js';
37
- import '@lion/ui/define/lion-option.js';
38
- import '@lion/ui/define/lion-options.js';
39
-
40
- import '@lion/ui/define/lion-validation-feedback.js';
4
+ import './helpers/umbrella-form.js';
41
5
  /**
42
6
  * @typedef {import('../../form-core/src/LionField.js').LionField} LionField
7
+ * @typedef {import('../../input-file/types/input-file.js').InputFile} InputFile
43
8
  * @typedef {import('../../button/src/LionButton.js').LionButton} LionButton
44
9
  * @typedef {import('./helpers/umbrella-form.js').UmbrellaForm} UmbrellaForm
45
10
  */
46
11
 
12
+ const file = /** @type {InputFile} */ (
13
+ new File(['foo'], 'foo.txt', {
14
+ type: 'text/plain',
15
+ })
16
+ );
17
+
47
18
  const fullyPrefilledSerializedValue = {
48
19
  fullName: { firstName: 'Lorem', lastName: 'Ipsum' },
49
20
  date: '2000-12-12',
@@ -57,6 +28,7 @@ const fullyPrefilledSerializedValue = {
57
28
  favoriteFruit: 'Banana',
58
29
  favoriteMovie: 'Rocky',
59
30
  favoriteColor: 'hotpink',
31
+ file: [],
60
32
  lyrics: '1',
61
33
  notifications: {
62
34
  checked: true,
@@ -81,6 +53,7 @@ const fullyChangedSerializedValue = {
81
53
  favoriteFruit: '',
82
54
  favoriteMovie: '',
83
55
  favoriteColor: '',
56
+ file: [file],
84
57
  lyrics: '2',
85
58
  notifications: {
86
59
  checked: false,
@@ -189,6 +162,7 @@ describe(`Submitting/Resetting/Clearing Form`, async () => {
189
162
  favoriteFruit: '',
190
163
  favoriteMovie: '',
191
164
  favoriteColor: '',
165
+ file: [],
192
166
  lyrics: '',
193
167
  notifications: {
194
168
  checked: false,
@@ -41,6 +41,7 @@ describe('Form Integrations', () => {
41
41
  favoriteFruit: 'Banana',
42
42
  favoriteMovie: 'Rocky',
43
43
  favoriteColor: 'hotpink',
44
+ file: [],
44
45
  lyrics: '1',
45
46
  range: 2.3,
46
47
  terms: [],
@@ -74,6 +75,7 @@ describe('Form Integrations', () => {
74
75
  favoriteFruit: 'Banana',
75
76
  favoriteMovie: 'Rocky',
76
77
  favoriteColor: 'hotpink',
78
+ file: '',
77
79
  lyrics: 'Fire up that loud',
78
80
  range: 2.3,
79
81
  terms: [],
@@ -98,6 +100,7 @@ describe('Form Integrations', () => {
98
100
  money: '',
99
101
  iban: '',
100
102
  email: '',
103
+ file: [],
101
104
  checkers: ['foo', 'bar'],
102
105
  dinosaurs: 'brontosaurus',
103
106
  favoriteFruit: 'Banana',
@@ -129,6 +132,7 @@ describe('Form Integrations', () => {
129
132
  'lion-input-amount',
130
133
  'lion-input-iban',
131
134
  'lion-input-email',
135
+ 'lion-input-file',
132
136
  'lion-input-tel',
133
137
  'lion-input-tel-dropdown',
134
138
  'lion-checkbox-group',
@@ -1,29 +1,31 @@
1
- import { LitElement, html } from 'lit';
2
- import { Required, MinLength } from '@lion/ui/form-core.js';
3
- import '@lion/ui/define/lion-form.js';
1
+ import '@lion/ui/define/lion-button-reset.js';
2
+ import '@lion/ui/define/lion-button-submit.js';
3
+ import '@lion/ui/define/lion-checkbox-group.js';
4
+ import '@lion/ui/define/lion-checkbox.js';
5
+ import '@lion/ui/define/lion-combobox.js';
4
6
  import '@lion/ui/define/lion-fieldset.js';
5
- import '@lion/ui/define/lion-input.js';
7
+ import '@lion/ui/define/lion-form.js';
8
+ import '@lion/ui/define/lion-input-amount.js';
6
9
  import '@lion/ui/define/lion-input-date.js';
7
10
  import '@lion/ui/define/lion-input-datepicker.js';
8
- import '@lion/ui/define/lion-input-amount.js';
9
- import '@lion/ui/define/lion-input-iban.js';
10
11
  import '@lion/ui/define/lion-input-email.js';
11
- import '@lion/ui/define/lion-input-tel.js';
12
+ import '@lion/ui/define/lion-input-file.js';
13
+ import '@lion/ui/define/lion-input-iban.js';
14
+ import '@lion/ui/define/lion-input-range.js';
15
+ import '@lion/ui/define/lion-input-stepper.js';
12
16
  import '@lion/ui/define/lion-input-tel-dropdown.js';
13
- import '@lion/ui/define/lion-checkbox-group.js';
14
- import '@lion/ui/define/lion-checkbox.js';
17
+ import '@lion/ui/define/lion-input-tel.js';
18
+ import '@lion/ui/define/lion-input.js';
19
+ import '@lion/ui/define/lion-listbox.js';
20
+ import '@lion/ui/define/lion-option.js';
15
21
  import '@lion/ui/define/lion-radio-group.js';
16
22
  import '@lion/ui/define/lion-radio.js';
17
- import '@lion/ui/define/lion-select.js';
18
23
  import '@lion/ui/define/lion-select-rich.js';
19
- import '@lion/ui/define/lion-listbox.js';
20
- import '@lion/ui/define/lion-option.js';
21
- import '@lion/ui/define/lion-combobox.js';
22
- import '@lion/ui/define/lion-input-range.js';
23
- import '@lion/ui/define/lion-textarea.js';
24
- import '@lion/ui/define/lion-button.js';
24
+ import '@lion/ui/define/lion-select.js';
25
25
  import '@lion/ui/define/lion-switch.js';
26
- import '@lion/ui/define/lion-input-stepper.js';
26
+ import '@lion/ui/define/lion-textarea.js';
27
+ import { MinLength, Required } from '@lion/ui/form-core.js';
28
+ import { html, LitElement } from 'lit';
27
29
 
28
30
  export class UmbrellaForm extends LitElement {
29
31
  get _lionFormNode() {
@@ -83,6 +85,7 @@ export class UmbrellaForm extends LitElement {
83
85
  <lion-input-amount name="money" label="Money"></lion-input-amount>
84
86
  <lion-input-iban name="iban" label="Iban"></lion-input-iban>
85
87
  <lion-input-email name="email" label="Email"></lion-input-email>
88
+ <lion-input-file name="file" label="File"></lion-input-file>
86
89
  <lion-input-tel name="tel" label="Telephone Number"></lion-input-tel>
87
90
  <lion-input-tel-dropdown
88
91
  name="tel-dropdown"
@@ -151,7 +154,7 @@ export class UmbrellaForm extends LitElement {
151
154
  .validators="${[new Required()]}"
152
155
  >
153
156
  <lion-checkbox
154
- .choiceValue="agreed"
157
+ .choiceValue="${'agreed'}"
155
158
  label="I blindly accept all terms and conditions"
156
159
  ></lion-checkbox>
157
160
  </lion-checkbox-group>
@@ -31,6 +31,11 @@ export class LionInputAmount extends LocalizeMixin(LionInput) {
31
31
  * validators.
32
32
  */
33
33
  modelValue: Number,
34
+ /**
35
+ * The slot to put the currency display node in. Can be 'prefix', 'suffix', 'before' and 'after'.
36
+ * Default will be 'after'.
37
+ */
38
+ _currencyDisplayNodeSlot: { attribute: false },
34
39
  locale: { attribute: false },
35
40
  };
36
41
  }
@@ -38,7 +43,7 @@ export class LionInputAmount extends LocalizeMixin(LionInput) {
38
43
  get slots() {
39
44
  return {
40
45
  ...super.slots,
41
- after: () => {
46
+ [this._currencyDisplayNodeSlot]: () => {
42
47
  const el = document.createElement('span');
43
48
  // The data-label attribute will make sure that FormControl adds this to
44
49
  // input[aria-labelledby]
@@ -70,6 +75,8 @@ export class LionInputAmount extends LocalizeMixin(LionInput) {
70
75
  this.locale = undefined;
71
76
  this.__currencyDisplayNodeIsConnected = true;
72
77
  this.defaultValidators.push(new IsNumber());
78
+ /** @protected */
79
+ this._currencyDisplayNodeSlot = 'after';
73
80
  }
74
81
 
75
82
  connectedCallback() {
@@ -103,14 +110,14 @@ export class LionInputAmount extends LocalizeMixin(LionInput) {
103
110
 
104
111
  /**
105
112
  * Upon connecting slot mixin, we should check if
106
- * the after slot was created by the slot mixin,
113
+ * the required slot was created by the slot mixin,
107
114
  * and if so, we should execute the currency changed flow
108
115
  * which evaluates whether the slot node should be
109
116
  * removed for invalid currencies
110
117
  */
111
118
  _connectSlotMixin() {
112
119
  super._connectSlotMixin();
113
- if (this._isPrivateSlot('after')) {
120
+ if (this._isPrivateSlot(this._currencyDisplayNodeSlot)) {
114
121
  this._onCurrencyChanged({ currency: this.currency || null });
115
122
  }
116
123
  }
@@ -179,7 +186,9 @@ export class LionInputAmount extends LocalizeMixin(LionInput) {
179
186
  * @private
180
187
  */
181
188
  get __currencyDisplayNode() {
182
- const node = Array.from(this.children).find(child => child.slot === 'after');
189
+ const node = Array.from(this.children).find(
190
+ child => child.slot === this._currencyDisplayNodeSlot,
191
+ );
183
192
  if (node) {
184
193
  this.__storedCurrencyDisplayNode = node;
185
194
  }
@@ -3,13 +3,12 @@ import { html } from 'lit';
3
3
  import { localize } from '@lion/ui/localize.js';
4
4
  import { localizeTearDown } from '@lion/ui/localize-test-helpers.js';
5
5
  import { getInputMembers } from '@lion/ui/input-test-helpers.js';
6
- import { formatAmount, parseAmount } from '@lion/ui/input-amount.js';
6
+ import { LionInputAmount, formatAmount, parseAmount } from '@lion/ui/input-amount.js';
7
7
 
8
8
  import '@lion/ui/define/lion-input-amount.js';
9
9
 
10
10
  /**
11
11
  * @typedef {import('../../input/src/LionInput.js').LionInput} LionInput
12
- * @typedef {import('../src/LionInputAmount.js').LionInputAmount} LionInputAmount
13
12
  */
14
13
 
15
14
  describe('<lion-input-amount>', () => {
@@ -187,24 +186,6 @@ describe('<lion-input-amount>', () => {
187
186
  ).to.equal('USD');
188
187
  });
189
188
 
190
- it('ignores currency if a suffix is already present', async () => {
191
- const el = /** @type {LionInputAmount} */ (
192
- await fixture(
193
- `<lion-input-amount currency="EUR"><span slot="suffix">my-currency</span></lion-input-amount>`,
194
- )
195
- );
196
- expect(
197
- /** @type {HTMLElement[]} */ (Array.from(el.children)).find(child => child.slot === 'suffix')
198
- ?.innerText,
199
- ).to.equal('my-currency');
200
- el.currency = 'EUR';
201
- await el.updateComplete;
202
- expect(
203
- /** @type {HTMLElement[]} */ (Array.from(el.children)).find(child => child.slot === 'suffix')
204
- ?.innerText,
205
- ).to.equal('my-currency');
206
- });
207
-
208
189
  it('reformats on locale changes', async () => {
209
190
  const el = /** @type {LionInputAmount} */ (
210
191
  await fixture(
@@ -275,6 +256,24 @@ describe('<lion-input-amount>', () => {
275
256
  expect(currLabel?.innerText).to.equal('EUR');
276
257
  });
277
258
 
259
+ it('can override the currency label slot', async () => {
260
+ customElements.define(
261
+ 'my-input-amount',
262
+ class extends LionInputAmount {
263
+ constructor() {
264
+ super();
265
+ // Put the currency label in the suffix slot
266
+ this._currencyDisplayNodeSlot = 'suffix';
267
+ }
268
+ },
269
+ );
270
+ const el = await fixture(html`<my-input-amount currency="EUR"></my-input-amount>`);
271
+ expect(
272
+ /** @type {HTMLElement[]} */ (Array.from(el.children)).find(child => child.slot === 'suffix')
273
+ ?.innerText,
274
+ ).to.equal('EUR');
275
+ });
276
+
278
277
  describe('Accessibility', () => {
279
278
  it('is accessible', async () => {
280
279
  const el = await fixture(