@lion/ui 0.25.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 (771) 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-suites/LionInputTel.suite.js +9 -4
  81. package/components/input-tel-dropdown/test/LionInputTelDropdown.test.js +6 -4
  82. package/components/input-tel-dropdown/test-suites/LionInputTelDropdown--parentheses.suite.js +10 -13
  83. package/components/input-tel-dropdown/test-suites/LionInputTelDropdown.suite.js +6 -5
  84. package/components/listbox/test-suites/ListboxMixin.suite.js +19 -19
  85. package/components/menu/test-suites/InteractiveListMixin.suite.js +6 -9
  86. package/components/menu/test-suites/LionMenu.suite.js +6 -10
  87. package/components/menu/test-suites/LionMenuInteractions.suite.js +13 -4
  88. package/components/menu/test-suites/MoreButtonMenuMixin.suite.js +6 -9
  89. package/components/menu/test-suites/MultiLevelListMixin.suite.js +15 -11
  90. package/components/overlays/test/OverlayController.test.js +6 -1
  91. package/components/overlays/test-suites/OverlayMixin.suite.js +3 -5
  92. package/components/pagination/test/lion-pagination.test.js +2 -176
  93. package/components/pagination/test-suites/LionPagination.suite.js +201 -0
  94. package/components/progress-indicator/test/lion-progress-indicator.test.js +2 -203
  95. package/components/progress-indicator/test-suites/lion-progress-indicator.suite.js +214 -0
  96. package/components/radio-group/test/lion-radio-group.test.js +2 -162
  97. package/components/radio-group/test/lion-radio.test.js +2 -54
  98. package/components/radio-group/test-suites/lion-radio-group.suite.js +173 -0
  99. package/components/radio-group/test-suites/lion-radio.suite.js +70 -0
  100. package/components/select/test/lion-select.test.js +2 -79
  101. package/components/select/test-suites/LionSelect.suite.js +94 -0
  102. package/components/select-rich/test/lion-select-invoker.test.js +2 -86
  103. package/components/select-rich/test/lion-select-rich-interaction.test.js +2 -430
  104. package/components/select-rich/test/lion-select-rich.test.js +2 -1193
  105. package/components/select-rich/test-suites/lion-select-invoker.suite.js +98 -0
  106. package/components/select-rich/test-suites/lion-select-rich-interaction.suite.js +452 -0
  107. package/components/select-rich/test-suites/lion-select-rich.suite.js +1236 -0
  108. package/components/steps/test/lion-step.test.js +2 -97
  109. package/components/steps/test/lion-steps.test.js +2 -433
  110. package/components/steps/test-suites/lion-step.suite.js +113 -0
  111. package/components/steps/test-suites/lion-steps.suite.js +445 -0
  112. package/components/switch/test/lion-switch.test.js +2 -232
  113. package/components/switch/test-suites/lion-switch.suite.js +450 -0
  114. package/components/tabs/test/lion-tabs.test.js +2 -596
  115. package/components/tabs/test-suites/lion-tabs.suite.js +617 -0
  116. package/components/textarea/src/LionTextarea.js +5 -2
  117. package/components/textarea/test/lion-textarea.test.js +2 -159
  118. package/components/textarea/test-suites/lion-textarea.suite.js +192 -0
  119. package/components/tooltip/test/lion-tooltip.test.js +2 -393
  120. package/components/tooltip/test-suites/lion-tooltip.suite.js +409 -0
  121. package/custom-elements.json +14855 -10161
  122. package/dialog-test-suites.js +2 -0
  123. package/dist-types/components/accordion/test/lion-accordion.test.d.ts +1 -2
  124. package/dist-types/components/accordion/test/lion-accordion.test.d.ts.map +1 -1
  125. package/dist-types/components/accordion/test-suites/lion-accordion.suite.d.ts +18 -0
  126. package/dist-types/components/accordion/test-suites/lion-accordion.suite.d.ts.map +1 -0
  127. package/dist-types/components/button/test-suites/LionButton.suite.d.ts +10 -4
  128. package/dist-types/components/button/test-suites/LionButton.suite.d.ts.map +1 -1
  129. package/dist-types/components/button/test-suites/LionButtonReset.suite.d.ts +10 -4
  130. package/dist-types/components/button/test-suites/LionButtonReset.suite.d.ts.map +1 -1
  131. package/dist-types/components/button/test-suites/LionButtonSubmit.suite.d.ts +10 -4
  132. package/dist-types/components/button/test-suites/LionButtonSubmit.suite.d.ts.map +1 -1
  133. package/dist-types/components/calendar/test/lion-calendar.test.d.ts +1 -3
  134. package/dist-types/components/calendar/test/lion-calendar.test.d.ts.map +1 -1
  135. package/dist-types/components/calendar/test-suites/LionCalendar.suite.d.ts +13 -4
  136. package/dist-types/components/calendar/test-suites/LionCalendar.suite.d.ts.map +1 -1
  137. package/dist-types/components/checkbox-group/test/lion-checkbox-group-integrations.test.d.ts.map +1 -1
  138. package/dist-types/components/checkbox-group/test/lion-checkbox-integrations.test.d.ts.map +1 -1
  139. package/dist-types/components/checkbox-group/test-suites/CheckboxIndeterminate.suite.d.ts +12 -9
  140. package/dist-types/components/checkbox-group/test-suites/CheckboxIndeterminate.suite.d.ts.map +1 -1
  141. package/dist-types/components/collapsible/test/lion-collapsible.test.d.ts +1 -3
  142. package/dist-types/components/collapsible/test/lion-collapsible.test.d.ts.map +1 -1
  143. package/dist-types/components/collapsible/test-suites/LionCollapsible.suite.d.ts +18 -0
  144. package/dist-types/components/collapsible/test-suites/LionCollapsible.suite.d.ts.map +1 -0
  145. package/dist-types/components/combobox/test/lion-combobox.test.d.ts +1 -5
  146. package/dist-types/components/combobox/test/lion-combobox.test.d.ts.map +1 -1
  147. package/dist-types/components/combobox/test-suites/lion-combobox.suite.d.ts +17 -0
  148. package/dist-types/components/combobox/test-suites/lion-combobox.suite.d.ts.map +1 -0
  149. package/dist-types/components/core/src/ScopedElementsMixin.d.ts.map +1 -1
  150. package/dist-types/components/core/test-helpers/isElementVisible.d.ts +12 -0
  151. package/dist-types/components/core/test-helpers/isElementVisible.d.ts.map +1 -0
  152. package/dist-types/components/core/test-helpers/resolveSuiteTag.d.ts +29 -0
  153. package/dist-types/components/core/test-helpers/resolveSuiteTag.d.ts.map +1 -0
  154. package/dist-types/components/core/types/TestSuiteTypes.d.ts +40 -0
  155. package/dist-types/components/core/types/TestSuiteTypes.d.ts.map +1 -0
  156. package/dist-types/components/dialog/test/lion-dialog.integration.test.d.ts.map +1 -1
  157. package/dist-types/components/dialog/test/lion-dialog.test.d.ts +1 -5
  158. package/dist-types/components/dialog/test/lion-dialog.test.d.ts.map +1 -1
  159. package/dist-types/components/dialog/test-suites/lion-dialog.suite.d.ts +19 -0
  160. package/dist-types/components/dialog/test-suites/lion-dialog.suite.d.ts.map +1 -0
  161. package/dist-types/components/drawer/test/lion-drawer.test.d.ts +1 -3
  162. package/dist-types/components/drawer/test/lion-drawer.test.d.ts.map +1 -1
  163. package/dist-types/components/drawer/test-suites/LionDrawer.suite.d.ts +20 -0
  164. package/dist-types/components/drawer/test-suites/LionDrawer.suite.d.ts.map +1 -0
  165. package/dist-types/components/fieldset/test/lion-fieldset.test.d.ts.map +1 -1
  166. package/dist-types/components/form/test/lion-form.test.d.ts +1 -12
  167. package/dist-types/components/form/test/lion-form.test.d.ts.map +1 -1
  168. package/dist-types/components/form/test-suites/lion-form.suite.d.ts +39 -0
  169. package/dist-types/components/form/test-suites/lion-form.suite.d.ts.map +1 -0
  170. package/dist-types/components/form-core/test-suites/FormRegistrationMixins.suite.d.ts +14 -17
  171. package/dist-types/components/form-core/test-suites/FormRegistrationMixins.suite.d.ts.map +1 -1
  172. package/dist-types/components/form-core/test-suites/FormatMixin.suite.d.ts +22 -38
  173. package/dist-types/components/form-core/test-suites/FormatMixin.suite.d.ts.map +1 -1
  174. package/dist-types/components/form-core/test-suites/InteractionStateMixin.suite.d.ts +11 -5
  175. package/dist-types/components/form-core/test-suites/InteractionStateMixin.suite.d.ts.map +1 -1
  176. package/dist-types/components/form-core/test-suites/NativeTextFieldMixin.suite.d.ts +9 -4
  177. package/dist-types/components/form-core/test-suites/NativeTextFieldMixin.suite.d.ts.map +1 -1
  178. package/dist-types/components/form-core/test-suites/ValidateMixin.suite.d.ts +9 -4
  179. package/dist-types/components/form-core/test-suites/ValidateMixin.suite.d.ts.map +1 -1
  180. package/dist-types/components/form-core/test-suites/ValidateMixinFeedbackPart.suite.d.ts +10 -1
  181. package/dist-types/components/form-core/test-suites/ValidateMixinFeedbackPart.suite.d.ts.map +1 -1
  182. package/dist-types/components/form-core/test-suites/choice-group/ChoiceGroupMixin.suite.d.ts +17 -6
  183. package/dist-types/components/form-core/test-suites/choice-group/ChoiceGroupMixin.suite.d.ts.map +1 -1
  184. package/dist-types/components/form-core/test-suites/choice-group/ChoiceInputMixin.suite.d.ts +5 -2
  185. package/dist-types/components/form-core/test-suites/choice-group/ChoiceInputMixin.suite.d.ts.map +1 -1
  186. package/dist-types/components/form-core/test-suites/choice-group/CustomChoiceGroupMixin.suite.d.ts +10 -5
  187. package/dist-types/components/form-core/test-suites/choice-group/CustomChoiceGroupMixin.suite.d.ts.map +1 -1
  188. package/dist-types/components/form-core/test-suites/form-group/FormGroupMixin-input.suite.d.ts +10 -5
  189. package/dist-types/components/form-core/test-suites/form-group/FormGroupMixin-input.suite.d.ts.map +1 -1
  190. package/dist-types/components/form-core/test-suites/form-group/FormGroupMixin.suite.d.ts +10 -5
  191. package/dist-types/components/form-core/test-suites/form-group/FormGroupMixin.suite.d.ts.map +1 -1
  192. package/dist-types/components/icon/test/lion-icon.test.d.ts +1 -4
  193. package/dist-types/components/icon/test/lion-icon.test.d.ts.map +1 -1
  194. package/dist-types/components/icon/test-suites/lion-icon.suite.d.ts +16 -0
  195. package/dist-types/components/icon/test-suites/lion-icon.suite.d.ts.map +1 -0
  196. package/dist-types/components/input/test/lion-input-integrations.test.d.ts.map +1 -1
  197. package/dist-types/components/input/test/lion-input.test.d.ts +1 -2
  198. package/dist-types/components/input/test/lion-input.test.d.ts.map +1 -1
  199. package/dist-types/components/input/test-suites/lion-input.suite.d.ts +17 -0
  200. package/dist-types/components/input/test-suites/lion-input.suite.d.ts.map +1 -0
  201. package/dist-types/components/input-amount/src/parsers.d.ts.map +1 -1
  202. package/dist-types/components/input-amount/test/lion-input-amount-integrations.test.d.ts.map +1 -1
  203. package/dist-types/components/input-amount/test/lion-input-amount.test.d.ts +1 -2
  204. package/dist-types/components/input-amount/test/lion-input-amount.test.d.ts.map +1 -1
  205. package/dist-types/components/input-amount/test-suites/lion-input-amount.suite.d.ts +19 -0
  206. package/dist-types/components/input-amount/test-suites/lion-input-amount.suite.d.ts.map +1 -0
  207. package/dist-types/components/input-amount-dropdown/test/lion-input-amount-dropdown-integrations.test.d.ts.map +1 -1
  208. package/dist-types/components/input-amount-dropdown/test-suites/LionInputAmountDropdown.suite.d.ts +7 -3
  209. package/dist-types/components/input-amount-dropdown/test-suites/LionInputAmountDropdown.suite.d.ts.map +1 -1
  210. package/dist-types/components/input-date/test/lion-input-date-integrations.test.d.ts.map +1 -1
  211. package/dist-types/components/input-date/test/lion-input-date.test.d.ts +1 -3
  212. package/dist-types/components/input-date/test/lion-input-date.test.d.ts.map +1 -1
  213. package/dist-types/components/input-date/test-suites/lion-input-date.suite.d.ts +15 -0
  214. package/dist-types/components/input-date/test-suites/lion-input-date.suite.d.ts.map +1 -0
  215. package/dist-types/components/input-datepicker/test/lion-input-datepicker-integrations.test.d.ts.map +1 -1
  216. package/dist-types/components/input-datepicker/test/lion-input-datepicker.test.d.ts +1 -2
  217. package/dist-types/components/input-datepicker/test/lion-input-datepicker.test.d.ts.map +1 -1
  218. package/dist-types/components/input-datepicker/test-helpers/DatepickerInputObject.d.ts +8 -0
  219. package/dist-types/components/input-datepicker/test-helpers/DatepickerInputObject.d.ts.map +1 -1
  220. package/dist-types/components/input-datepicker/test-suites/LionInputDatepicker.suite.d.ts +15 -5
  221. package/dist-types/components/input-datepicker/test-suites/LionInputDatepicker.suite.d.ts.map +1 -1
  222. package/dist-types/components/input-email/test/lion-input-email-integrations.test.d.ts.map +1 -1
  223. package/dist-types/components/input-email/test/lion-input-email.test.d.ts +1 -3
  224. package/dist-types/components/input-email/test/lion-input-email.test.d.ts.map +1 -1
  225. package/dist-types/components/input-email/test-suites/lion-input-email.suite.d.ts +15 -0
  226. package/dist-types/components/input-email/test-suites/lion-input-email.suite.d.ts.map +1 -0
  227. package/dist-types/components/input-file/test/lion-input-file.test.d.ts +1 -5
  228. package/dist-types/components/input-file/test/lion-input-file.test.d.ts.map +1 -1
  229. package/dist-types/components/input-file/test-suites/lion-input-file.suite.d.ts +19 -0
  230. package/dist-types/components/input-file/test-suites/lion-input-file.suite.d.ts.map +1 -0
  231. package/dist-types/components/input-iban/test/lion-input-iban-integrations.test.d.ts.map +1 -1
  232. package/dist-types/components/input-iban/test/lion-input-iban.test.d.ts +1 -3
  233. package/dist-types/components/input-iban/test/lion-input-iban.test.d.ts.map +1 -1
  234. package/dist-types/components/input-iban/test-suites/lion-input-iban.suite.d.ts +15 -0
  235. package/dist-types/components/input-iban/test-suites/lion-input-iban.suite.d.ts.map +1 -0
  236. package/dist-types/components/input-range/test/lion-input-range.test.d.ts +1 -3
  237. package/dist-types/components/input-range/test/lion-input-range.test.d.ts.map +1 -1
  238. package/dist-types/components/input-range/test-suites/lion-input-range.suite.d.ts +15 -0
  239. package/dist-types/components/input-range/test-suites/lion-input-range.suite.d.ts.map +1 -0
  240. package/dist-types/components/input-stepper/test-suites/lion-input-stepper.integration.suite.d.ts +10 -2
  241. package/dist-types/components/input-stepper/test-suites/lion-input-stepper.integration.suite.d.ts.map +1 -1
  242. package/dist-types/components/input-stepper/test-suites/lion-input-stepper.suite.d.ts +10 -2
  243. package/dist-types/components/input-stepper/test-suites/lion-input-stepper.suite.d.ts.map +1 -1
  244. package/dist-types/components/input-tel/test-suites/LionInputTel.suite.d.ts +6 -4
  245. package/dist-types/components/input-tel/test-suites/LionInputTel.suite.d.ts.map +1 -1
  246. package/dist-types/components/input-tel-dropdown/test-suites/LionInputTelDropdown--parentheses.suite.d.ts +7 -3
  247. package/dist-types/components/input-tel-dropdown/test-suites/LionInputTelDropdown--parentheses.suite.d.ts.map +1 -1
  248. package/dist-types/components/input-tel-dropdown/test-suites/LionInputTelDropdown.suite.d.ts +7 -3
  249. package/dist-types/components/input-tel-dropdown/test-suites/LionInputTelDropdown.suite.d.ts.map +1 -1
  250. package/dist-types/components/listbox/test-suites/ListboxMixin.suite.d.ts +3 -4
  251. package/dist-types/components/listbox/test-suites/ListboxMixin.suite.d.ts.map +1 -1
  252. package/dist-types/components/menu/test-suites/InteractiveListMixin.suite.d.ts +6 -5
  253. package/dist-types/components/menu/test-suites/InteractiveListMixin.suite.d.ts.map +1 -1
  254. package/dist-types/components/menu/test-suites/LionMenu.suite.d.ts +6 -5
  255. package/dist-types/components/menu/test-suites/LionMenu.suite.d.ts.map +1 -1
  256. package/dist-types/components/menu/test-suites/LionMenuInteractions.suite.d.ts +10 -4
  257. package/dist-types/components/menu/test-suites/LionMenuInteractions.suite.d.ts.map +1 -1
  258. package/dist-types/components/menu/test-suites/MoreButtonMenuMixin.suite.d.ts +6 -5
  259. package/dist-types/components/menu/test-suites/MoreButtonMenuMixin.suite.d.ts.map +1 -1
  260. package/dist-types/components/menu/test-suites/MultiLevelListMixin.suite.d.ts +7 -6
  261. package/dist-types/components/menu/test-suites/MultiLevelListMixin.suite.d.ts.map +1 -1
  262. package/dist-types/components/overlays/test-suites/OverlayMixin.suite.d.ts.map +1 -1
  263. package/dist-types/components/pagination/test/lion-pagination.test.d.ts +1 -3
  264. package/dist-types/components/pagination/test/lion-pagination.test.d.ts.map +1 -1
  265. package/dist-types/components/pagination/test-suites/LionPagination.suite.d.ts +18 -0
  266. package/dist-types/components/pagination/test-suites/LionPagination.suite.d.ts.map +1 -0
  267. package/dist-types/components/progress-indicator/test/lion-progress-indicator.test.d.ts +1 -3
  268. package/dist-types/components/progress-indicator/test/lion-progress-indicator.test.d.ts.map +1 -1
  269. package/dist-types/components/progress-indicator/test-suites/lion-progress-indicator.suite.d.ts +15 -0
  270. package/dist-types/components/progress-indicator/test-suites/lion-progress-indicator.suite.d.ts.map +1 -0
  271. package/dist-types/components/radio-group/test/lion-radio-group.test.d.ts +1 -5
  272. package/dist-types/components/radio-group/test/lion-radio-group.test.d.ts.map +1 -1
  273. package/dist-types/components/radio-group/test/lion-radio.test.d.ts +1 -2
  274. package/dist-types/components/radio-group/test/lion-radio.test.d.ts.map +1 -1
  275. package/dist-types/components/radio-group/test-suites/lion-radio-group.suite.d.ts +19 -0
  276. package/dist-types/components/radio-group/test-suites/lion-radio-group.suite.d.ts.map +1 -0
  277. package/dist-types/components/radio-group/test-suites/lion-radio.suite.d.ts +17 -0
  278. package/dist-types/components/radio-group/test-suites/lion-radio.suite.d.ts.map +1 -0
  279. package/dist-types/components/select/test/lion-select.test.d.ts +1 -2
  280. package/dist-types/components/select/test/lion-select.test.d.ts.map +1 -1
  281. package/dist-types/components/select/test-suites/LionSelect.suite.d.ts +16 -0
  282. package/dist-types/components/select/test-suites/LionSelect.suite.d.ts.map +1 -0
  283. package/dist-types/components/select-rich/test/lion-select-invoker.test.d.ts +1 -2
  284. package/dist-types/components/select-rich/test/lion-select-invoker.test.d.ts.map +1 -1
  285. package/dist-types/components/select-rich/test/lion-select-rich-interaction.test.d.ts +1 -5
  286. package/dist-types/components/select-rich/test/lion-select-rich-interaction.test.d.ts.map +1 -1
  287. package/dist-types/components/select-rich/test/lion-select-rich.test.d.ts +1 -8
  288. package/dist-types/components/select-rich/test/lion-select-rich.test.d.ts.map +1 -1
  289. package/dist-types/components/select-rich/test-suites/lion-select-invoker.suite.d.ts +19 -0
  290. package/dist-types/components/select-rich/test-suites/lion-select-invoker.suite.d.ts.map +1 -0
  291. package/dist-types/components/select-rich/test-suites/lion-select-rich-interaction.suite.d.ts +19 -0
  292. package/dist-types/components/select-rich/test-suites/lion-select-rich-interaction.suite.d.ts.map +1 -0
  293. package/dist-types/components/select-rich/test-suites/lion-select-rich.suite.d.ts +21 -0
  294. package/dist-types/components/select-rich/test-suites/lion-select-rich.suite.d.ts.map +1 -0
  295. package/dist-types/components/steps/test/lion-step.test.d.ts +1 -2
  296. package/dist-types/components/steps/test/lion-step.test.d.ts.map +1 -1
  297. package/dist-types/components/steps/test/lion-steps.test.d.ts +1 -8
  298. package/dist-types/components/steps/test/lion-steps.test.d.ts.map +1 -1
  299. package/dist-types/components/steps/test-suites/lion-step.suite.d.ts +17 -0
  300. package/dist-types/components/steps/test-suites/lion-step.suite.d.ts.map +1 -0
  301. package/dist-types/components/steps/test-suites/lion-steps.suite.d.ts +22 -0
  302. package/dist-types/components/steps/test-suites/lion-steps.suite.d.ts.map +1 -0
  303. package/dist-types/components/switch/test/lion-switch.test.d.ts +1 -4
  304. package/dist-types/components/switch/test/lion-switch.test.d.ts.map +1 -1
  305. package/dist-types/components/switch/test-suites/lion-switch.suite.d.ts +17 -0
  306. package/dist-types/components/switch/test-suites/lion-switch.suite.d.ts.map +1 -0
  307. package/dist-types/components/tabs/test/lion-tabs.test.d.ts +1 -5
  308. package/dist-types/components/tabs/test/lion-tabs.test.d.ts.map +1 -1
  309. package/dist-types/components/tabs/test-suites/lion-tabs.suite.d.ts +17 -0
  310. package/dist-types/components/tabs/test-suites/lion-tabs.suite.d.ts.map +1 -0
  311. package/dist-types/components/textarea/src/LionTextarea.d.ts.map +1 -1
  312. package/dist-types/components/textarea/test/lion-textarea.test.d.ts +1 -3
  313. package/dist-types/components/textarea/test/lion-textarea.test.d.ts.map +1 -1
  314. package/dist-types/components/textarea/test-suites/lion-textarea.suite.d.ts +15 -0
  315. package/dist-types/components/textarea/test-suites/lion-textarea.suite.d.ts.map +1 -0
  316. package/dist-types/components/tooltip/test/lion-tooltip.test.d.ts +1 -3
  317. package/dist-types/components/tooltip/test/lion-tooltip.test.d.ts.map +1 -1
  318. package/dist-types/components/tooltip/test-suites/lion-tooltip.suite.d.ts +19 -0
  319. package/dist-types/components/tooltip/test-suites/lion-tooltip.suite.d.ts.map +1 -0
  320. package/dist-types/exports/accordion-test-suites.d.ts +2 -0
  321. package/dist-types/exports/accordion-test-suites.d.ts.map +1 -0
  322. package/dist-types/exports/collapsible-test-suites.d.ts +2 -0
  323. package/dist-types/exports/collapsible-test-suites.d.ts.map +1 -0
  324. package/dist-types/exports/combobox-test-suites.d.ts +2 -0
  325. package/dist-types/exports/combobox-test-suites.d.ts.map +1 -0
  326. package/dist-types/exports/dialog-test-suites.d.ts +2 -0
  327. package/dist-types/exports/dialog-test-suites.d.ts.map +1 -0
  328. package/dist-types/exports/drawer-test-suites.d.ts +2 -0
  329. package/dist-types/exports/drawer-test-suites.d.ts.map +1 -0
  330. package/dist-types/exports/form-test-suites.d.ts +2 -0
  331. package/dist-types/exports/form-test-suites.d.ts.map +1 -0
  332. package/dist-types/exports/icon-test-suites.d.ts +2 -0
  333. package/dist-types/exports/icon-test-suites.d.ts.map +1 -0
  334. package/dist-types/exports/input-amount-test-suites.d.ts +2 -0
  335. package/dist-types/exports/input-amount-test-suites.d.ts.map +1 -0
  336. package/dist-types/exports/input-date-test-suites.d.ts +2 -0
  337. package/dist-types/exports/input-date-test-suites.d.ts.map +1 -0
  338. package/dist-types/exports/input-email-test-suites.d.ts +2 -0
  339. package/dist-types/exports/input-email-test-suites.d.ts.map +1 -0
  340. package/dist-types/exports/input-file-test-suites.d.ts +2 -0
  341. package/dist-types/exports/input-file-test-suites.d.ts.map +1 -0
  342. package/dist-types/exports/input-iban-test-suites.d.ts +2 -0
  343. package/dist-types/exports/input-iban-test-suites.d.ts.map +1 -0
  344. package/dist-types/exports/input-range-test-suites.d.ts +2 -0
  345. package/dist-types/exports/input-range-test-suites.d.ts.map +1 -0
  346. package/dist-types/exports/input-stepper-suites.d.ts +7 -2
  347. package/dist-types/exports/input-stepper-suites.d.ts.map +1 -1
  348. package/dist-types/exports/input-test-suites.d.ts +2 -0
  349. package/dist-types/exports/input-test-suites.d.ts.map +1 -0
  350. package/dist-types/exports/menu-test-suites.d.ts.map +1 -1
  351. package/dist-types/exports/pagination-test-suites.d.ts +2 -0
  352. package/dist-types/exports/pagination-test-suites.d.ts.map +1 -0
  353. package/dist-types/exports/progress-indicator-test-suites.d.ts +2 -0
  354. package/dist-types/exports/progress-indicator-test-suites.d.ts.map +1 -0
  355. package/dist-types/exports/radio-group-test-suites.d.ts +3 -0
  356. package/dist-types/exports/radio-group-test-suites.d.ts.map +1 -0
  357. package/dist-types/exports/select-rich-test-suites.d.ts +4 -0
  358. package/dist-types/exports/select-rich-test-suites.d.ts.map +1 -0
  359. package/dist-types/exports/select-test-suites.d.ts +2 -0
  360. package/dist-types/exports/select-test-suites.d.ts.map +1 -0
  361. package/dist-types/exports/steps-test-suites.d.ts +3 -0
  362. package/dist-types/exports/steps-test-suites.d.ts.map +1 -0
  363. package/dist-types/exports/switch-test-suites.d.ts +2 -0
  364. package/dist-types/exports/switch-test-suites.d.ts.map +1 -0
  365. package/dist-types/exports/tabs-test-suites.d.ts +2 -0
  366. package/dist-types/exports/tabs-test-suites.d.ts.map +1 -0
  367. package/dist-types/exports/textarea-test-suites.d.ts +2 -0
  368. package/dist-types/exports/textarea-test-suites.d.ts.map +1 -0
  369. package/dist-types/exports/tooltip-test-suites.d.ts +2 -0
  370. package/dist-types/exports/tooltip-test-suites.d.ts.map +1 -0
  371. package/dist-types/exports/types/test-suites.d.ts +4 -0
  372. package/dist-types/exports/types/test-suites.d.ts.map +1 -0
  373. package/dist-types/tsconfig.tsbuildinfo +1 -1
  374. package/drawer-test-suites.js +1 -0
  375. package/exports/accordion-test-suites.js +2 -0
  376. package/exports/collapsible-test-suites.js +1 -0
  377. package/exports/combobox-test-suites.js +2 -0
  378. package/exports/dialog-test-suites.js +2 -0
  379. package/exports/drawer-test-suites.js +1 -0
  380. package/exports/form-test-suites.js +2 -0
  381. package/exports/icon-test-suites.js +2 -0
  382. package/exports/input-amount-test-suites.js +2 -0
  383. package/exports/input-date-test-suites.js +2 -0
  384. package/exports/input-email-test-suites.js +2 -0
  385. package/exports/input-file-test-suites.js +2 -0
  386. package/exports/input-iban-test-suites.js +2 -0
  387. package/exports/input-range-test-suites.js +2 -0
  388. package/exports/input-stepper-suites.js +18 -4
  389. package/exports/input-test-suites.js +2 -0
  390. package/exports/menu-test-suites.js +3 -0
  391. package/exports/pagination-test-suites.js +1 -0
  392. package/exports/progress-indicator-test-suites.js +2 -0
  393. package/exports/radio-group-test-suites.js +3 -0
  394. package/exports/select-rich-test-suites.js +4 -0
  395. package/exports/select-test-suites.js +1 -0
  396. package/exports/steps-test-suites.js +3 -0
  397. package/exports/switch-test-suites.js +2 -0
  398. package/exports/tabs-test-suites.js +2 -0
  399. package/exports/textarea-test-suites.js +2 -0
  400. package/exports/tooltip-test-suites.js +2 -0
  401. package/exports/types/test-suites.ts +3 -0
  402. package/form-test-suites.js +2 -0
  403. package/generated/awesome-phonenumber/provenance.json +1 -1
  404. package/icon-test-suites.js +2 -0
  405. package/input-amount-test-suites.js +2 -0
  406. package/input-date-test-suites.js +2 -0
  407. package/input-email-test-suites.js +2 -0
  408. package/input-file-test-suites.js +2 -0
  409. package/input-iban-test-suites.js +2 -0
  410. package/input-range-test-suites.js +2 -0
  411. package/input-stepper-suites.js +18 -4
  412. package/input-test-suites.js +2 -0
  413. package/menu-test-suites.js +3 -0
  414. package/package.json +4 -1
  415. package/pagination-test-suites.js +1 -0
  416. package/progress-indicator-test-suites.js +2 -0
  417. package/radio-group-test-suites.js +3 -0
  418. package/select-rich-test-suites.js +4 -0
  419. package/select-test-suites.js +1 -0
  420. package/steps-test-suites.js +3 -0
  421. package/switch-test-suites.js +2 -0
  422. package/tabs-test-suites.js +2 -0
  423. package/textarea-test-suites.js +2 -0
  424. package/tooltip-test-suites.js +2 -0
  425. package/vscode.html-custom-data.json +55 -0
  426. package/web-types.json +219 -1
  427. package/components/button/test/demos.screenshots-test.js +0 -100
  428. package/components/calendar/test/demos.screenshots-test.js +0 -118
  429. package/components/input-file/test/lion-selected-file-list.test.js +0 -199
  430. package/components/select-rich/test/demos.screenshots-test.js +0 -168
  431. package/components/switch/test/lion-switch-button.test.js +0 -204
  432. package/dist-types/components/button/test/demos.screenshots-test.d.ts +0 -2
  433. package/dist-types/components/button/test/demos.screenshots-test.d.ts.map +0 -1
  434. package/dist-types/components/calendar/test/demos.screenshots-test.d.ts +0 -2
  435. package/dist-types/components/calendar/test/demos.screenshots-test.d.ts.map +0 -1
  436. package/dist-types/components/input-file/test/lion-selected-file-list.test.d.ts +0 -5
  437. package/dist-types/components/input-file/test/lion-selected-file-list.test.d.ts.map +0 -1
  438. package/dist-types/components/select-rich/test/demos.screenshots-test.d.ts +0 -2
  439. package/dist-types/components/select-rich/test/demos.screenshots-test.d.ts.map +0 -1
  440. package/dist-types/components/switch/test/lion-switch-button.test.d.ts +0 -4
  441. package/dist-types/components/switch/test/lion-switch-button.test.d.ts.map +0 -1
  442. package/docs/components/accordion/api-table.md +0 -53
  443. package/docs/components/accordion/index.md +0 -13
  444. package/docs/components/accordion/overview.md +0 -141
  445. package/docs/components/accordion/reference.md +0 -59
  446. package/docs/components/accordion/use-cases.md +0 -303
  447. package/docs/components/button/api-table.md +0 -84
  448. package/docs/components/button/assets/bootstrap-button.js +0 -245
  449. package/docs/components/button/examples.md +0 -42
  450. package/docs/components/button/extensions.md +0 -42
  451. package/docs/components/button/index.md +0 -13
  452. package/docs/components/button/overview.md +0 -42
  453. package/docs/components/button/src/icon.svg.js +0 -5
  454. package/docs/components/button/use-cases.md +0 -121
  455. package/docs/components/calendar/api-table.md +0 -56
  456. package/docs/components/calendar/index.md +0 -13
  457. package/docs/components/calendar/overview.md +0 -61
  458. package/docs/components/calendar/use-cases.md +0 -243
  459. package/docs/components/checkbox-group/api-table.md +0 -117
  460. package/docs/components/checkbox-group/index.md +0 -13
  461. package/docs/components/checkbox-group/overview.md +0 -51
  462. package/docs/components/checkbox-group/use-cases.md +0 -192
  463. package/docs/components/collapsible/api-table.md +0 -55
  464. package/docs/components/collapsible/assets/CustomCollapsible.js +0 -117
  465. package/docs/components/collapsible/assets/applyDemoCollapsibleStyles.js +0 -41
  466. package/docs/components/collapsible/examples.md +0 -95
  467. package/docs/components/collapsible/index.md +0 -13
  468. package/docs/components/collapsible/overview.md +0 -51
  469. package/docs/components/collapsible/use-cases.md +0 -91
  470. package/docs/components/combobox/api-table.md +0 -122
  471. package/docs/components/combobox/extensions.md +0 -174
  472. package/docs/components/combobox/index.md +0 -13
  473. package/docs/components/combobox/overview.md +0 -74
  474. package/docs/components/combobox/src/LinkMixin.js +0 -60
  475. package/docs/components/combobox/src/demo-selection-display.js +0 -164
  476. package/docs/components/combobox/src/gh-combobox/gh-button.js +0 -71
  477. package/docs/components/combobox/src/gh-combobox/gh-combobox.js +0 -515
  478. package/docs/components/combobox/src/google-combobox/assets/google-clear-icon.js +0 -9
  479. package/docs/components/combobox/src/google-combobox/assets/google-search-icon.js +0 -9
  480. package/docs/components/combobox/src/google-combobox/assets/google-voice-search-icon.js +0 -19
  481. package/docs/components/combobox/src/google-combobox/google-combobox.js +0 -461
  482. package/docs/components/combobox/src/lazyRender.js +0 -29
  483. package/docs/components/combobox/src/levenshtein.js +0 -95
  484. package/docs/components/combobox/src/md-combobox/MdFieldMixin.js +0 -345
  485. package/docs/components/combobox/src/md-combobox/md-combobox.js +0 -91
  486. package/docs/components/combobox/src/md-combobox/md-input.js +0 -5
  487. package/docs/components/combobox/src/md-combobox/style/load-roboto.js +0 -6
  488. package/docs/components/combobox/src/md-combobox/style/md-ripple.js +0 -82
  489. package/docs/components/combobox/src/wa-combobox/wa-combobox.js +0 -375
  490. package/docs/components/combobox/use-cases.md +0 -561
  491. package/docs/components/dialog/api-table.md +0 -61
  492. package/docs/components/dialog/index.md +0 -13
  493. package/docs/components/dialog/overview.md +0 -71
  494. package/docs/components/dialog/src/demoStyle.js +0 -57
  495. package/docs/components/dialog/src/external-dialog.js +0 -32
  496. package/docs/components/dialog/src/slots-dialog-content.js +0 -32
  497. package/docs/components/dialog/src/styled-dialog-content.js +0 -38
  498. package/docs/components/dialog/use-cases.md +0 -199
  499. package/docs/components/drawer/api-table.md +0 -64
  500. package/docs/components/drawer/index.md +0 -13
  501. package/docs/components/drawer/overview.md +0 -80
  502. package/docs/components/drawer/src/demoStyle.js +0 -71
  503. package/docs/components/drawer/use-cases.md +0 -206
  504. package/docs/components/fieldset/api-table.md +0 -24
  505. package/docs/components/fieldset/index.md +0 -13
  506. package/docs/components/fieldset/overview.md +0 -61
  507. package/docs/components/fieldset/use-cases.md +0 -203
  508. package/docs/components/form/api-table.md +0 -12
  509. package/docs/components/form/index.md +0 -13
  510. package/docs/components/form/overview.md +0 -66
  511. package/docs/components/form/use-cases.md +0 -230
  512. package/docs/components/icon/api-table.md +0 -41
  513. package/docs/components/icon/assets/bugs/bug01.svg.js +0 -2
  514. package/docs/components/icon/assets/bugs/bug02.svg.js +0 -2
  515. package/docs/components/icon/assets/bugs/bug05.svg.js +0 -2
  516. package/docs/components/icon/assets/bugs/bug06.svg.js +0 -2
  517. package/docs/components/icon/assets/bugs/bug08.svg.js +0 -2
  518. package/docs/components/icon/assets/bugs/bug12.svg.js +0 -2
  519. package/docs/components/icon/assets/bugs/bug19.svg.js +0 -2
  520. package/docs/components/icon/assets/bugs/bug23.svg.js +0 -2
  521. package/docs/components/icon/assets/bugs/bug24.svg.js +0 -2
  522. package/docs/components/icon/assets/iconset-bugs.js +0 -11
  523. package/docs/components/icon/assets/iconset-misc.js +0 -3
  524. package/docs/components/icon/assets/iconset-space.js +0 -31
  525. package/docs/components/icon/assets/misc/arrowLeft.svg.js +0 -6
  526. package/docs/components/icon/assets/space/aliens-spaceship.svg.js +0 -2
  527. package/docs/components/icon/assets/space/meteor.svg.js +0 -2
  528. package/docs/components/icon/assets/space/moon-flag.svg.js +0 -2
  529. package/docs/components/icon/assets/space/moon.svg.js +0 -2
  530. package/docs/components/icon/assets/space/night.svg.js +0 -2
  531. package/docs/components/icon/assets/space/orbit.svg.js +0 -2
  532. package/docs/components/icon/assets/space/planet.svg.js +0 -2
  533. package/docs/components/icon/assets/space/robot.svg.js +0 -2
  534. package/docs/components/icon/assets/space/rocket.svg.js +0 -2
  535. package/docs/components/icon/assets/space/satellite.svg.js +0 -2
  536. package/docs/components/icon/assets/space/signal.svg.js +0 -2
  537. package/docs/components/icon/assets/space/space-helmet.svg.js +0 -2
  538. package/docs/components/icon/assets/space/sun.svg.js +0 -2
  539. package/docs/components/icon/assets/space/telescope.svg.js +0 -2
  540. package/docs/components/icon/index.md +0 -13
  541. package/docs/components/icon/overview.md +0 -52
  542. package/docs/components/icon/use-cases.md +0 -92
  543. package/docs/components/index.md +0 -17
  544. package/docs/components/input/api-table.md +0 -52
  545. package/docs/components/input/index.md +0 -13
  546. package/docs/components/input/overview.md +0 -48
  547. package/docs/components/input/use-cases.md +0 -90
  548. package/docs/components/input-amount/api-table.md +0 -66
  549. package/docs/components/input-amount/index.md +0 -13
  550. package/docs/components/input-amount/overview.md +0 -61
  551. package/docs/components/input-amount/use-cases.md +0 -147
  552. package/docs/components/input-amount-dropdown/api-table.md +0 -87
  553. package/docs/components/input-amount-dropdown/index.md +0 -13
  554. package/docs/components/input-amount-dropdown/use-cases.md +0 -103
  555. package/docs/components/input-date/api-table.md +0 -58
  556. package/docs/components/input-date/index.md +0 -13
  557. package/docs/components/input-date/overview.md +0 -51
  558. package/docs/components/input-date/use-cases.md +0 -96
  559. package/docs/components/input-datepicker/api-table.md +0 -99
  560. package/docs/components/input-datepicker/index.md +0 -13
  561. package/docs/components/input-datepicker/overview.md +0 -54
  562. package/docs/components/input-datepicker/use-cases.md +0 -117
  563. package/docs/components/input-email/api-table.md +0 -53
  564. package/docs/components/input-email/index.md +0 -13
  565. package/docs/components/input-email/overview.md +0 -44
  566. package/docs/components/input-email/use-cases.md +0 -60
  567. package/docs/components/input-file/api-table.md +0 -157
  568. package/docs/components/input-file/index.md +0 -13
  569. package/docs/components/input-file/overview.md +0 -44
  570. package/docs/components/input-file/use-cases.md +0 -454
  571. package/docs/components/input-iban/api-table.md +0 -54
  572. package/docs/components/input-iban/index.md +0 -13
  573. package/docs/components/input-iban/overview.md +0 -49
  574. package/docs/components/input-iban/use-cases.md +0 -114
  575. package/docs/components/input-range/api-table.md +0 -71
  576. package/docs/components/input-range/index.md +0 -13
  577. package/docs/components/input-range/overview.md +0 -44
  578. package/docs/components/input-range/use-cases.md +0 -126
  579. package/docs/components/input-stepper/api-table.md +0 -74
  580. package/docs/components/input-stepper/index.md +0 -13
  581. package/docs/components/input-stepper/overview.md +0 -48
  582. package/docs/components/input-stepper/use-cases.md +0 -155
  583. package/docs/components/input-tel/api-table.md +0 -77
  584. package/docs/components/input-tel/index.md +0 -13
  585. package/docs/components/input-tel/overview.md +0 -74
  586. package/docs/components/input-tel/src/h-region-code-table.js +0 -109
  587. package/docs/components/input-tel/use-cases.md +0 -319
  588. package/docs/components/input-tel-dropdown/api-table.md +0 -85
  589. package/docs/components/input-tel-dropdown/extensions.md +0 -44
  590. package/docs/components/input-tel-dropdown/index.md +0 -13
  591. package/docs/components/input-tel-dropdown/overview.md +0 -50
  592. package/docs/components/input-tel-dropdown/src/intl-input-tel-dropdown.js +0 -138
  593. package/docs/components/input-tel-dropdown/use-cases.md +0 -171
  594. package/docs/components/listbox/api-table.md +0 -65
  595. package/docs/components/listbox/index.md +0 -13
  596. package/docs/components/listbox/overview.md +0 -54
  597. package/docs/components/listbox/src/listboxData.js +0 -131
  598. package/docs/components/listbox/use-cases.md +0 -154
  599. package/docs/components/menu/api-table.md +0 -44
  600. package/docs/components/menu/applyMenuDemoStyles.js +0 -173
  601. package/docs/components/menu/extensions.md +0 -262
  602. package/docs/components/menu/index.md +0 -13
  603. package/docs/components/menu/migration.md +0 -129
  604. package/docs/components/menu/overview.md +0 -448
  605. package/docs/components/menu/src/DemoNavigationBar.js +0 -441
  606. package/docs/components/menu/src/DemoSpinButton.js +0 -215
  607. package/docs/components/menu/src/DemoToolbar.js +0 -101
  608. package/docs/components/menu/src/DemoTree.js +0 -55
  609. package/docs/components/menu/src/navigation-bar-types.js +0 -41
  610. package/docs/components/menu/use-cases.md +0 -74
  611. package/docs/components/pagination/api-table.md +0 -45
  612. package/docs/components/pagination/index.md +0 -13
  613. package/docs/components/pagination/overview.md +0 -41
  614. package/docs/components/pagination/use-cases.md +0 -113
  615. package/docs/components/progress-indicator/api-table.md +0 -48
  616. package/docs/components/progress-indicator/assets/my-determinate-progress-bar.js +0 -30
  617. package/docs/components/progress-indicator/assets/my-indeterminate-progress-spinner.js +0 -55
  618. package/docs/components/progress-indicator/examples.md +0 -137
  619. package/docs/components/progress-indicator/index.md +0 -13
  620. package/docs/components/progress-indicator/overview.md +0 -48
  621. package/docs/components/radio-group/api-table.md +0 -63
  622. package/docs/components/radio-group/index.md +0 -13
  623. package/docs/components/radio-group/overview.md +0 -58
  624. package/docs/components/radio-group/use-cases.md +0 -146
  625. package/docs/components/select/api-table.md +0 -51
  626. package/docs/components/select/index.md +0 -13
  627. package/docs/components/select/overview.md +0 -56
  628. package/docs/components/select/use-cases.md +0 -128
  629. package/docs/components/select-rich/api-table.md +0 -123
  630. package/docs/components/select-rich/examples.md +0 -43
  631. package/docs/components/select-rich/index.md +0 -13
  632. package/docs/components/select-rich/overview.md +0 -55
  633. package/docs/components/select-rich/src/flagStyles.js +0 -1250
  634. package/docs/components/select-rich/src/intl-select-rich.js +0 -194
  635. package/docs/components/select-rich/src/regionMetaList.js +0 -1717
  636. package/docs/components/select-rich/use-cases.md +0 -387
  637. package/docs/components/steps/api-table.md +0 -92
  638. package/docs/components/steps/index.md +0 -13
  639. package/docs/components/steps/overview.md +0 -77
  640. package/docs/components/steps/use-cases.md +0 -181
  641. package/docs/components/switch/api-table.md +0 -82
  642. package/docs/components/switch/index.md +0 -13
  643. package/docs/components/switch/overview.md +0 -87
  644. package/docs/components/switch/reference.md +0 -51
  645. package/docs/components/switch/use-cases.md +0 -88
  646. package/docs/components/tabs/api-table.md +0 -51
  647. package/docs/components/tabs/examples.md +0 -35
  648. package/docs/components/tabs/index.md +0 -13
  649. package/docs/components/tabs/overview.md +0 -60
  650. package/docs/components/tabs/src/lea-tab-panel.js +0 -26
  651. package/docs/components/tabs/src/lea-tab.js +0 -50
  652. package/docs/components/tabs/src/lea-tabs.js +0 -28
  653. package/docs/components/tabs/use-cases.md +0 -231
  654. package/docs/components/textarea/api-table.md +0 -57
  655. package/docs/components/textarea/index.md +0 -13
  656. package/docs/components/textarea/overview.md +0 -47
  657. package/docs/components/textarea/use-cases.md +0 -107
  658. package/docs/components/tooltip/api-table.md +0 -62
  659. package/docs/components/tooltip/examples.md +0 -51
  660. package/docs/components/tooltip/index.md +0 -13
  661. package/docs/components/tooltip/overview.md +0 -56
  662. package/docs/components/tooltip/use-cases.md +0 -275
  663. package/docs/fundamentals/index.md +0 -19
  664. package/docs/fundamentals/node-tools/babel-plugin-extend-docs/index.md +0 -13
  665. package/docs/fundamentals/node-tools/babel-plugin-extend-docs/overview.md +0 -246
  666. package/docs/fundamentals/node-tools/index.md +0 -11
  667. package/docs/fundamentals/node-tools/providence-analytics/index.md +0 -13
  668. package/docs/fundamentals/node-tools/providence-analytics/overview.md +0 -108
  669. package/docs/fundamentals/node-tools/publish-docs/index.md +0 -13
  670. package/docs/fundamentals/node-tools/publish-docs/overview.md +0 -149
  671. package/docs/fundamentals/node-tools/remark-extend/index.md +0 -13
  672. package/docs/fundamentals/node-tools/remark-extend/overview.md +0 -287
  673. package/docs/fundamentals/node-tools/rocket-preset-extend-lion-docs/index.md +0 -13
  674. package/docs/fundamentals/node-tools/rocket-preset-extend-lion-docs/overview.md +0 -298
  675. package/docs/fundamentals/rationales/TypeScript.md +0 -123
  676. package/docs/fundamentals/rationales/accessibility.md +0 -40
  677. package/docs/fundamentals/rationales/index.md +0 -11
  678. package/docs/fundamentals/rationales/side-effects.md +0 -215
  679. package/docs/fundamentals/rationales/versioning.md +0 -47
  680. package/docs/fundamentals/systems/core/SlotMixin.md +0 -168
  681. package/docs/fundamentals/systems/core/api-table.md +0 -43
  682. package/docs/fundamentals/systems/core/index.md +0 -15
  683. package/docs/fundamentals/systems/core/overview.md +0 -98
  684. package/docs/fundamentals/systems/form/api-table.md +0 -40
  685. package/docs/fundamentals/systems/form/assets/h-output.js +0 -156
  686. package/docs/fundamentals/systems/form/formatting-and-parsing.md +0 -258
  687. package/docs/fundamentals/systems/form/index.md +0 -15
  688. package/docs/fundamentals/systems/form/interaction-states.md +0 -195
  689. package/docs/fundamentals/systems/form/model-value.md +0 -57
  690. package/docs/fundamentals/systems/form/overview.md +0 -95
  691. package/docs/fundamentals/systems/form/styling.md +0 -92
  692. package/docs/fundamentals/systems/form/use-cases.md +0 -187
  693. package/docs/fundamentals/systems/form/validate.md +0 -985
  694. package/docs/fundamentals/systems/icon/index.md +0 -15
  695. package/docs/fundamentals/systems/icon/overview.md +0 -137
  696. package/docs/fundamentals/systems/index.md +0 -11
  697. package/docs/fundamentals/systems/localize/api-table.md +0 -72
  698. package/docs/fundamentals/systems/localize/assets/all-locales.js +0 -437
  699. package/docs/fundamentals/systems/localize/assets/en-AU.js +0 -6
  700. package/docs/fundamentals/systems/localize/assets/en-GB.js +0 -6
  701. package/docs/fundamentals/systems/localize/assets/en-US.js +0 -6
  702. package/docs/fundamentals/systems/localize/assets/en.js +0 -4
  703. package/docs/fundamentals/systems/localize/assets/nl-BE.js +0 -6
  704. package/docs/fundamentals/systems/localize/assets/nl-NL.js +0 -6
  705. package/docs/fundamentals/systems/localize/assets/nl.js +0 -4
  706. package/docs/fundamentals/systems/localize/dates.md +0 -208
  707. package/docs/fundamentals/systems/localize/index.md +0 -15
  708. package/docs/fundamentals/systems/localize/numbers.md +0 -230
  709. package/docs/fundamentals/systems/localize/overview.md +0 -61
  710. package/docs/fundamentals/systems/localize/rationale.md +0 -75
  711. package/docs/fundamentals/systems/localize/text.md +0 -139
  712. package/docs/fundamentals/systems/localize/use-cases.md +0 -334
  713. package/docs/fundamentals/systems/overlays/_configuration-positioning.md +0 -118
  714. package/docs/fundamentals/systems/overlays/_edge-cases.md +0 -149
  715. package/docs/fundamentals/systems/overlays/api-table.md +0 -174
  716. package/docs/fundamentals/systems/overlays/assets/applyDemoOverlayStyles.js +0 -23
  717. package/docs/fundamentals/systems/overlays/assets/demo-el-using-overlaymixin.js +0 -104
  718. package/docs/fundamentals/systems/overlays/assets/demo-overlay-backdrop.js +0 -47
  719. package/docs/fundamentals/systems/overlays/assets/demo-overlay-positioning.mjs +0 -537
  720. package/docs/fundamentals/systems/overlays/assets/umbrella-form.js +0 -140
  721. package/docs/fundamentals/systems/overlays/configuration.md +0 -516
  722. package/docs/fundamentals/systems/overlays/index.md +0 -15
  723. package/docs/fundamentals/systems/overlays/overview.md +0 -126
  724. package/docs/fundamentals/systems/overlays/rationale.md +0 -242
  725. package/docs/fundamentals/systems/overlays/use-cases.md +0 -717
  726. package/docs/fundamentals/tools/ajax/index.md +0 -15
  727. package/docs/fundamentals/tools/ajax/overview.md +0 -269
  728. package/docs/fundamentals/tools/ajax/use-cases.md +0 -469
  729. package/docs/fundamentals/tools/helpers/action-logger.md +0 -175
  730. package/docs/fundamentals/tools/helpers/index.md +0 -15
  731. package/docs/fundamentals/tools/helpers/overview.md +0 -43
  732. package/docs/fundamentals/tools/index.md +0 -11
  733. package/docs/fundamentals/tools/singleton-manager/example-complex/demo-app.js +0 -95
  734. package/docs/fundamentals/tools/singleton-manager/example-complex/index.md +0 -34
  735. package/docs/fundamentals/tools/singleton-manager/example-complex/node_modules/overlays/index.js +0 -30
  736. package/docs/fundamentals/tools/singleton-manager/example-complex/node_modules/overlays/instance.js +0 -4
  737. package/docs/fundamentals/tools/singleton-manager/example-complex/node_modules/page-a/page-a.js +0 -35
  738. package/docs/fundamentals/tools/singleton-manager/example-complex/node_modules/page-b/node_modules/overlays/index.js +0 -30
  739. package/docs/fundamentals/tools/singleton-manager/example-complex/node_modules/page-b/node_modules/overlays/instance.js +0 -4
  740. package/docs/fundamentals/tools/singleton-manager/example-complex/node_modules/page-b/page-b.js +0 -49
  741. package/docs/fundamentals/tools/singleton-manager/example-complex/overlayCompatibility.js +0 -69
  742. package/docs/fundamentals/tools/singleton-manager/example-fail/demo-app.js +0 -93
  743. package/docs/fundamentals/tools/singleton-manager/example-fail/index.md +0 -32
  744. package/docs/fundamentals/tools/singleton-manager/example-fail/node_modules/overlays/index.js +0 -30
  745. package/docs/fundamentals/tools/singleton-manager/example-fail/node_modules/overlays/instance.js +0 -3
  746. package/docs/fundamentals/tools/singleton-manager/example-fail/node_modules/page-c/page-c.js +0 -34
  747. package/docs/fundamentals/tools/singleton-manager/example-fail/node_modules/page-d/node_modules/overlays/index.js +0 -30
  748. package/docs/fundamentals/tools/singleton-manager/example-fail/node_modules/page-d/node_modules/overlays/instance.js +0 -3
  749. package/docs/fundamentals/tools/singleton-manager/example-fail/node_modules/page-d/page-d.js +0 -34
  750. package/docs/fundamentals/tools/singleton-manager/example-success/demo-app.js +0 -95
  751. package/docs/fundamentals/tools/singleton-manager/example-success/index.md +0 -31
  752. package/docs/fundamentals/tools/singleton-manager/example-success/node_modules/overlays/index.js +0 -30
  753. package/docs/fundamentals/tools/singleton-manager/example-success/node_modules/overlays/instance.js +0 -4
  754. package/docs/fundamentals/tools/singleton-manager/example-success/node_modules/page-e/page-e.js +0 -33
  755. package/docs/fundamentals/tools/singleton-manager/example-success/node_modules/page-f/node_modules/overlays/index.js +0 -30
  756. package/docs/fundamentals/tools/singleton-manager/example-success/node_modules/page-f/node_modules/overlays/instance.js +0 -4
  757. package/docs/fundamentals/tools/singleton-manager/example-success/node_modules/page-f/page-f.js +0 -34
  758. package/docs/fundamentals/tools/singleton-manager/example-success/overlayCompatibility.js +0 -23
  759. package/docs/fundamentals/tools/singleton-manager/index.md +0 -15
  760. package/docs/fundamentals/tools/singleton-manager/overview.md +0 -317
  761. package/docs/guides/how-to/create-a-custom-field.md +0 -212
  762. package/docs/guides/how-to/create-a-form.md +0 -101
  763. package/docs/guides/how-to/extend-a-native-input.md +0 -78
  764. package/docs/guides/how-to/get-started.md +0 -116
  765. package/docs/guides/how-to/index.md +0 -25
  766. package/docs/guides/index.md +0 -44
  767. package/docs/guides/principles/definitions-and-terms.md +0 -53
  768. package/docs/guides/principles/index.md +0 -36
  769. package/docs/guides/principles/scoped-elements.md +0 -119
  770. package/docs/guides/principles/styling.md +0 -43
  771. package/docs/guides/principles/subclasser-apis.md +0 -40
@@ -1,11 +1,54 @@
1
- import { LionCalendar } from '@lion/ui/calendar.js';
2
- import { expect, html, fixture, waitUntil, unsafeStatic, defineCE } from '@open-wc/testing';
3
- import sinon from 'sinon';
1
+ import { html } from 'lit/static-html.js';
2
+ import { LionCalendar, isSameDate } from '@lion/ui/calendar.js';
3
+ import { expect, fixture, fixture as _fixture, unsafeStatic, waitUntil } from '@open-wc/testing';
4
4
  import '@lion/ui/define/lion-calendar.js';
5
5
  import { sendKeys } from '@web/test-runner-commands';
6
- export function runCalendarSuite({ klass = LionCalendar } = {}) {
7
- const tagStringCalendar = defineCE(class extends klass {});
6
+ import { getLocalizeManager } from '@lion/ui/localize-no-side-effects.js';
7
+ import { localizeTearDown } from '@lion/ui/localize-test-helpers.js';
8
+ import {
9
+ CalendarObject as DefaultCalendarObject,
10
+ DayObject,
11
+ } from '@lion/ui/calendar-test-helpers.js';
12
+ import sinon from 'sinon';
13
+ import { resolveSuiteTag } from '../../core/test-helpers/resolveSuiteTag.js';
14
+
15
+ /**
16
+ * Runs the `LionCalendar` behavioural suite. The caller hands the element to run against; anything
17
+ * left out keeps `LionCalendar`.
18
+ * @typedef {import('@lion/ui/types/test-suites.js').SuiteElement} SuiteElement
19
+ * @param {import('@lion/ui/types/test-suites.js').SuiteConfig<{host: SuiteElement}, {CalendarObject?: typeof DefaultCalendarObject}>} [customConfig]
20
+ */
21
+ export function runCalendarSuite({
22
+ classes = {},
23
+ tagString,
24
+ // The tests address the calendar through this page object; an extension layer whose navigation
25
+ // markup differs (ING renders its own button element) passes its own subclass overriding the node
26
+ // getters instead of the suite learning about that markup.
27
+ CalendarObject = DefaultCalendarObject,
28
+ } = {}) {
29
+ const tagStringCalendar = resolveSuiteTag(classes.host, tagString, LionCalendar);
8
30
  const tagCalendar = unsafeStatic(tagStringCalendar);
31
+
32
+ /**
33
+ * The accessible name of a node, whatever mechanism carries it (`title`, `aria-label`, or a
34
+ * `label` on the node itself or a child element).
35
+ * @param {Element|null|undefined} node
36
+ * @returns {string|null}
37
+ */
38
+ function accessibleName(node) {
39
+ return (
40
+ node?.getAttribute('title') ||
41
+ node?.getAttribute('aria-label') ||
42
+ node?.getAttribute('label') ||
43
+ node?.querySelector?.('[label]')?.getAttribute('label') ||
44
+ node?.shadowRoot?.querySelector?.('[label]')?.getAttribute('label') ||
45
+ null
46
+ );
47
+ }
48
+
49
+ // A failing test that never reaches its `clock.restore()` used to leak fake timers into the
50
+ // next test, which then awaited a timer that never fires and wedged the rest of the file.
51
+ afterEach(() => sinon.restore());
9
52
  it('should fire keyboard press events on keyup and not on keydown', async () => {
10
53
  /**
11
54
  * This test covers a corner case where `keydown`, `keyup`, and `focus` events happen across different elements.
@@ -74,4 +117,1573 @@ export function runCalendarSuite({ klass = LionCalendar } = {}) {
74
117
  });
75
118
  expect(keyUpSpy.called).to.equal(false);
76
119
  });
120
+ /**
121
+ * @typedef {import('../src/LionCalendar.js').LionCalendar} LionCalendar
122
+ * @typedef {import('lit').TemplateResult} TemplateResult
123
+ */
124
+
125
+ const fixtureForSuite = /** @type {(arg: TemplateResult) => Promise<LionCalendar>} */ _fixture;
126
+ /**
127
+ * @param {HTMLElement} el
128
+ * @returns {HTMLElement | null | undefined}
129
+ */
130
+ const getSelectedDateEl = (el) =>
131
+ el?.shadowRoot?.querySelector('.calendar__day-button[selected]');
132
+ /**
133
+ * @param {HTMLElement} el
134
+ * @returns {void}
135
+ */
136
+ const focusSelectedDate = (el) => getSelectedDateEl(el)?.focus();
137
+ describe('<lion-calendar>', () => {
138
+ const localizeManager = getLocalizeManager();
139
+ beforeEach(() => {
140
+ localizeTearDown();
141
+ });
142
+ describe('Structure', () => {
143
+ it('implements BEM structure', async () => {
144
+ const el = await fixtureForSuite(html`<${tagCalendar}></${tagCalendar}>`);
145
+ const elObj = new CalendarObject(el);
146
+ expect(elObj.rootEl).to.exist;
147
+ expect(elObj.headerEl).to.exist;
148
+ expect(elObj.previousYearButtonEl).to.exist;
149
+ expect(elObj.nextYearButtonEl).to.exist;
150
+ expect(elObj.yearHeadingEl).to.exist;
151
+ expect(elObj.gridEl).to.exist;
152
+ });
153
+ it('has heading with month and year', async () => {
154
+ const clock = sinon.useFakeTimers({
155
+ now: new Date('2000/12/01').getTime(),
156
+ });
157
+ const el = await fixtureForSuite(html`<${tagCalendar}></${tagCalendar}>`);
158
+ expect(el.shadowRoot?.querySelector('#year')).dom.to.equal(`
159
+ <h2
160
+ id="year"
161
+ class="calendar__navigation-heading"
162
+ aria-atomic="true"
163
+ >
164
+ 2000
165
+ </h2>
166
+ `);
167
+ expect(el.shadowRoot?.querySelector('#month')).dom.to.equal(`
168
+ <h2
169
+ id="month"
170
+ class="calendar__navigation-heading"
171
+ aria-atomic="true"
172
+ >
173
+ December
174
+ </h2>
175
+ `);
176
+ clock.restore();
177
+ });
178
+ it('has previous year button', async () => {
179
+ const el = await fixtureForSuite(
180
+ html`<${tagCalendar} .centralDate=${new Date('2019/11/20')}></${tagCalendar}>`,
181
+ );
182
+ expect(accessibleName(new CalendarObject(el).previousYearButtonEl)).to.equal(
183
+ 'Previous year, November 2018',
184
+ );
185
+ });
186
+ it('has next year button', async () => {
187
+ const el = await fixtureForSuite(
188
+ html`<${tagCalendar} .centralDate=${new Date('2019/11/20')}></${tagCalendar}>`,
189
+ );
190
+ expect(accessibleName(new CalendarObject(el).nextYearButtonEl)).to.equal(
191
+ 'Next year, November 2020',
192
+ );
193
+ });
194
+ it('has previous month button', async () => {
195
+ const el = await fixtureForSuite(
196
+ html`<${tagCalendar} .centralDate=${new Date('2019/11/20')}></${tagCalendar}>`,
197
+ );
198
+ expect(accessibleName(new CalendarObject(el).previousMonthButtonEl)).to.equal(
199
+ 'Previous month, October 2019',
200
+ );
201
+ });
202
+ it('has next month button', async () => {
203
+ const el = await fixtureForSuite(
204
+ html`<${tagCalendar} .centralDate=${new Date('2019/11/20')}></${tagCalendar}>`,
205
+ );
206
+ expect(accessibleName(new CalendarObject(el).nextMonthButtonEl)).to.equal(
207
+ 'Next month, December 2019',
208
+ );
209
+ });
210
+ });
211
+ describe('Public API', () => {
212
+ it('has property "centralDate" that determines currently visible month', async () => {
213
+ const elObj = new CalendarObject(
214
+ await fixtureForSuite(html`
215
+ <${tagCalendar} .centralDate="${new Date('2014/05/15')}"></${tagCalendar}>
216
+ `),
217
+ );
218
+ expect(elObj.activeMonth).to.equal('May');
219
+ expect(elObj.activeYear).to.equal('2014');
220
+ });
221
+ it('sets "centralDate" to today by default', async () => {
222
+ const clock = sinon.useFakeTimers({
223
+ now: new Date('2013/03/15').getTime(),
224
+ });
225
+ const el = await fixtureForSuite(html`<${tagCalendar}></${tagCalendar}>`);
226
+ const elObj = new CalendarObject(el);
227
+ expect(isSameDate(el.centralDate, new Date())).to.be.true;
228
+ expect(elObj.activeMonth).to.equal('March');
229
+ expect(elObj.activeYear).to.equal('2013');
230
+ clock.restore();
231
+ });
232
+ it('determines the date focusable with keyboard from "centralDate"', async () => {
233
+ const elObj = new CalendarObject(
234
+ await fixtureForSuite(html`
235
+ <${tagCalendar} .centralDate="${new Date('2017/07/05')}"></${tagCalendar}>
236
+ `),
237
+ );
238
+ expect(
239
+ elObj.checkForAllDayObjs(
240
+ /** @param {DayObject} o */ (o) => o.buttonEl.getAttribute('tabindex') === '0',
241
+ /** @param {number} n */ (n) => n === 5,
242
+ ),
243
+ ).to.be.true;
244
+ expect(
245
+ elObj.checkForAllDayObjs(
246
+ /** @param {DayObject} o */ (o) => o.buttonEl.getAttribute('tabindex') === '-1',
247
+ /** @param {number} n */ (n) => n !== 5,
248
+ ),
249
+ ).to.be.true;
250
+ });
251
+ it('has property "selectedDate" for the selected date', async () => {
252
+ const el = await fixtureForSuite(html`
253
+ <${tagCalendar} .selectedDate="${new Date('2019/06/15')}"></${tagCalendar}>
254
+ `);
255
+ const elObj = new CalendarObject(el);
256
+ expect(elObj.getDayObj(15).isSelected).to.equal(true);
257
+ expect(elObj.getDayObj(16).isSelected).to.equal(false);
258
+ expect(elObj.getDayObj(14).isSelected).to.equal(false);
259
+ el.selectedDate = new Date('2019/06/16');
260
+ await el.updateComplete;
261
+ expect(elObj.getDayObj(15).isSelected).to.equal(false);
262
+ });
263
+ it('gives priority to "centralDate" to display the month when "selectedDate" is also defined', async () => {
264
+ const elObj = new CalendarObject(
265
+ await fixtureForSuite(html`
266
+ <${tagCalendar}
267
+ .centralDate="${new Date('2018/06/01')}"
268
+ .selectedDate="${new Date('2018/07/15')}"
269
+ ></${tagCalendar}>
270
+ `),
271
+ );
272
+ expect(elObj.activeMonth).to.equal('June');
273
+ expect(elObj.activeYear).to.equal('2018');
274
+ });
275
+ it('changes "centralDate" from default to "selectedDate" on first render if no other custom "centralDate" is provided', async () => {
276
+ const clock = sinon.useFakeTimers({
277
+ now: new Date('2010/01/01').getTime(),
278
+ });
279
+ const el = await fixtureForSuite(html`
280
+ <${tagCalendar} .selectedDate="${new Date('2016/10/20')}"></${tagCalendar}>
281
+ `);
282
+ const elObj = new CalendarObject(el);
283
+ expect(isSameDate(el.centralDate, new Date('2016/10/20'))).to.be.true;
284
+ expect(elObj.activeMonth).to.equal('October');
285
+ expect(elObj.activeYear).to.equal('2016');
286
+ clock.restore();
287
+ });
288
+ it('does not change "centralDate" to "selectedDate" when new date is provided programmatically', async () => {
289
+ const el = await fixtureForSuite(html`
290
+ <${tagCalendar}
291
+ .centralDate="${new Date('2018/06/01')}"
292
+ .selectedDate="${new Date('2018/06/02')}"
293
+ ></${tagCalendar}>
294
+ `);
295
+ expect(isSameDate(el.centralDate, new Date('2018/06/01'))).to.be.true;
296
+ el.selectedDate = new Date('2018/06/03');
297
+ await el.updateComplete;
298
+ expect(isSameDate(el.centralDate, new Date('2018/06/01'))).to.be.true;
299
+ });
300
+ it('does not set "selectedDate" by default', async () => {
301
+ const el = await fixtureForSuite(html`<${tagCalendar}></${tagCalendar}>`);
302
+ const elObj = new CalendarObject(el);
303
+ const today = new Date();
304
+ expect(el.selectedDate).to.equal(undefined);
305
+ expect(elObj.getDayObj(today.getDate()).isSelected).to.equal(false);
306
+ });
307
+ it('allows to reset "selectedDate"', async () => {
308
+ const el = await fixtureForSuite(html`
309
+ <${tagCalendar} .selectedDate="${new Date('2019/06/15')}"></${tagCalendar}>
310
+ `);
311
+ const elObj = new CalendarObject(el);
312
+ el.selectedDate = undefined;
313
+ await el.updateComplete;
314
+ expect(elObj.selectedDayObj).to.be.undefined;
315
+ });
316
+ it('recalculates "centralDate" when "selectedDate" is reset', async () => {
317
+ const el = await fixtureForSuite(html`
318
+ <${tagCalendar} .selectedDate="${new Date('2019/06/15')}"></${tagCalendar}>
319
+ `);
320
+ const elObj = new CalendarObject(el);
321
+ el.selectedDate = undefined;
322
+ await el.updateComplete;
323
+ expect(elObj.selectedDayObj).to.be.undefined;
324
+ expect(isSameDate(el.centralDate, new Date('2019/06/15'))).to.be.true;
325
+ });
326
+ it('sends event "user-selected-date-changed" when user selects a date via mouse', async () => {
327
+ const dateChangedSpy = sinon.spy();
328
+ const el = await fixtureForSuite(html`
329
+ <${tagCalendar}
330
+ .selectedDate="${new Date('2000/12/12')}"
331
+ @user-selected-date-changed="${dateChangedSpy}"
332
+ ></${tagCalendar}>
333
+ `);
334
+ const elObj = new CalendarObject(el);
335
+ expect(dateChangedSpy.called).to.equal(false);
336
+ elObj.getDayEl(15).click();
337
+ await el.updateComplete;
338
+ expect(dateChangedSpy.calledOnce).to.equal(true);
339
+ expect(
340
+ isSameDate(dateChangedSpy.args[0][0].detail.selectedDate, new Date('2000/12/15')),
341
+ ).to.equal(true);
342
+ });
343
+ it('doesn\'t send event "user-selected-date-changed" when user selects a disabled date via mouse', async () => {
344
+ const dateChangedSpy = sinon.spy();
345
+ const disable15th = /** @param {Date} d */ (d) => d.getDate() === 15;
346
+ const el = await fixtureForSuite(html`
347
+ <${tagCalendar}
348
+ .selectedDate="${new Date('2000/12/12')}"
349
+ @user-selected-date-changed="${dateChangedSpy}"
350
+ .disableDates=${disable15th}
351
+ ></${tagCalendar}>
352
+ `);
353
+ const elObj = new CalendarObject(el);
354
+ elObj.getDayEl(15).click();
355
+ await el.updateComplete;
356
+ expect(dateChangedSpy.called).to.equal(false);
357
+ expect(isSameDate(/** @type {Date} */ el.selectedDate, new Date('2000/12/12'))).to.be.true;
358
+ });
359
+ it.skip('sends event "user-selected-date-changed" when user selects a date via [Enter]', async () => {
360
+ /**
361
+ * TODO fix me
362
+ * The dispatchEvent of [Enter] should has to be on contentWrapperElement to be called
363
+ * But to get "selected" a check is done if the action comes from a button.
364
+ */
365
+ const dateChangedSpy = sinon.spy();
366
+ const el = await fixtureForSuite(html`
367
+ <${tagCalendar}
368
+ .selectedDate="${new Date('2000/10/12')}"
369
+ @user-selected-date-changed="${dateChangedSpy}"
370
+ ></${tagCalendar}>
371
+ `);
372
+ const elObj = new CalendarObject(el);
373
+ el.__contentWrapperElement?.dispatchEvent(
374
+ new KeyboardEvent('keydown', {
375
+ key: 'ArrowLeft',
376
+ }),
377
+ );
378
+ await el.updateComplete;
379
+ expect(elObj.activeMonth).to.equal('October');
380
+ expect(elObj.activeYear).to.equal('2000');
381
+ expect(elObj.focusedDayObj?.monthday).to.equal(11);
382
+ el.__contentWrapperElement?.dispatchEvent(
383
+ new KeyboardEvent('keydown', {
384
+ key: 'Enter',
385
+ }),
386
+ );
387
+ await el.updateComplete;
388
+ expect(isSameDate(/** @type {Date} */ el.selectedDate, new Date('2000/10/11'))).to.be.true;
389
+ expect(dateChangedSpy.called).to.equal(true);
390
+ });
391
+ it('doesn\'t send event "user-selected-date-changed" when user selects a disabled date via [Enter]', async () => {
392
+ const dateChangedSpy = sinon.spy();
393
+ const el = await fixtureForSuite(html`
394
+ <${tagCalendar}
395
+ .selectedDate="${new Date('2000/10/12')}"
396
+ .minDate="${new Date('2000/10/12')}"
397
+ @user-selected-date-changed="${dateChangedSpy}"
398
+ ></${tagCalendar}>
399
+ `);
400
+ const elObj = new CalendarObject(el);
401
+ focusSelectedDate(el);
402
+ await sendKeys({
403
+ press: 'ArrowLeft',
404
+ });
405
+ await el.updateComplete;
406
+ expect(elObj.activeMonth).to.equal('October');
407
+ expect(elObj.activeYear).to.equal('2000');
408
+ expect(elObj.focusedDayObj?.monthday).to.equal(11);
409
+ await sendKeys({
410
+ press: 'Enter',
411
+ });
412
+ await el.updateComplete;
413
+ expect(isSameDate(/** @type {Date} */ el.selectedDate, new Date('2000/10/12'))).to.be.true;
414
+ expect(dateChangedSpy.called).to.equal(false);
415
+ });
416
+ it('exposes focusedDate getter', async () => {
417
+ const el = await fixtureForSuite(html`
418
+ <${tagCalendar} .centralDate="${new Date('2019/06/01')}"></${tagCalendar}>
419
+ `);
420
+ const elObj = new CalendarObject(el);
421
+ expect(el.focusedDate).to.be.null;
422
+ elObj.getDayEl(15).click();
423
+ expect(isSameDate(/** @type {Date} */ el.focusedDate, new Date('2019/06/15'))).to.equal(
424
+ true,
425
+ );
426
+ });
427
+ it('has a focusDate() method to focus an arbitrary date', async () => {
428
+ const el = await fixtureForSuite(html`<${tagCalendar}></${tagCalendar}>`);
429
+ const elObj = new CalendarObject(el);
430
+ await el.focusDate(new Date('2016/06/10'));
431
+ expect(isSameDate(/** @type {Date} */ el.focusedDate, new Date('2016/06/10'))).to.be.true;
432
+ expect(elObj.getDayObj(10).isFocused).to.be.true;
433
+ });
434
+ it('has a focusCentralDate() method to focus the central date', async () => {
435
+ const el = await fixtureForSuite(html`
436
+ <${tagCalendar}
437
+ .centralDate="${new Date('2015/12/02')}"
438
+ .selectedDate="${new Date('2015/12/04')}"
439
+ ></${tagCalendar}>
440
+ `);
441
+ const elObj = new CalendarObject(el);
442
+ el.focusCentralDate();
443
+ expect(isSameDate(/** @type {Date} */ el.focusedDate, new Date('2015/12/02'))).to.be.true;
444
+ expect(elObj.getDayObj(2).isFocused).to.be.true;
445
+ });
446
+ it('has a focusSelectedDate() method to focus the selected date', async () => {
447
+ const el = await fixtureForSuite(html`
448
+ <${tagCalendar}
449
+ .centralDate="${new Date('2014/07/05')}"
450
+ .selectedDate="${new Date('2014/07/07')}"
451
+ ></${tagCalendar}>
452
+ `);
453
+ const elObj = new CalendarObject(el);
454
+ await el.focusSelectedDate();
455
+ expect(isSameDate(/** @type {Date} */ el.focusedDate, new Date('2014/07/07'))).to.be.true;
456
+ expect(elObj.getDayObj(7).isFocused).to.be.true;
457
+ });
458
+ it('has a initCentralDate() method for external contexts like datepickers', async () => {
459
+ const initialCentralDate = new Date('2014/07/05');
460
+ const initialSelectedDate = new Date('2014/07/07');
461
+ const el = await fixtureForSuite(html`<${tagCalendar}
462
+ .centralDate="${initialCentralDate}"
463
+ .selectedDate="${initialSelectedDate}"
464
+ ></${tagCalendar}>`);
465
+ expect(el.selectedDate).to.equal(initialSelectedDate);
466
+ expect(el.centralDate).to.equal(initialCentralDate);
467
+ const newSelectedDate = new Date('2015/07/05');
468
+ el.selectedDate = newSelectedDate;
469
+ el.initCentralDate();
470
+ expect(el.centralDate).to.equal(newSelectedDate);
471
+ el.selectedDate = undefined;
472
+ el.initCentralDate();
473
+ expect(el.centralDate).to.equal(initialCentralDate);
474
+ });
475
+ describe('Enabled Dates', () => {
476
+ it('disables all days before "minDate" property', async () => {
477
+ const el = await fixtureForSuite(html`
478
+ <${tagCalendar}
479
+ .selectedDate="${new Date('2000/12/31')}"
480
+ .minDate="${new Date('2000/12/09')}"
481
+ >
482
+ </${tagCalendar}>
483
+ `);
484
+ const elObj = new CalendarObject(el);
485
+ expect(elObj.getDayObj(15).isDisabled).to.equal(false);
486
+ elObj.dayEls.forEach((d, i) => {
487
+ const shouldBeDisabled = i < 8;
488
+ expect(new DayObject(d).isDisabled).to.equal(shouldBeDisabled);
489
+ });
490
+ });
491
+ it('disables all days after "maxDate" property', async () => {
492
+ const el = await fixtureForSuite(html`
493
+ <${tagCalendar}
494
+ .selectedDate="${new Date('2000/12/01')}"
495
+ .maxDate="${new Date('2000/12/09')}"
496
+ >
497
+ </${tagCalendar}>
498
+ `);
499
+ const elObj = new CalendarObject(el);
500
+ expect(elObj.getDayObj(5).isDisabled).to.equal(false);
501
+ elObj.dayEls.forEach((d, i) => {
502
+ const shouldBeDisabled = i > 8;
503
+ expect(new DayObject(d).isDisabled).to.equal(shouldBeDisabled);
504
+ });
505
+ });
506
+ it('disables a date with disableDates function', async () => {
507
+ /** @param {Date} d */
508
+ const disable15th = (d) => d.getDate() === 15;
509
+ const el = await fixtureForSuite(html`
510
+ <${tagCalendar}
511
+ .selectedDate="${new Date('2000/12/01')}"
512
+ .disableDates=${disable15th}
513
+ ></${tagCalendar}>
514
+ `);
515
+ const elObj = new CalendarObject(el);
516
+ elObj.dayEls.forEach((d, i) => {
517
+ const shouldBeDisabled = i === 15 - 1;
518
+ expect(new DayObject(d).isDisabled).to.equal(shouldBeDisabled);
519
+ });
520
+ el.selectedDate = new Date('2000/11/01'); // When month view updates, it should still work
521
+ await el.updateComplete;
522
+ elObj.dayEls.forEach((d, i) => {
523
+ const shouldBeDisabled = i === 15 - 1;
524
+ expect(new DayObject(d).isDisabled).to.equal(shouldBeDisabled);
525
+ });
526
+ });
527
+ it('does not prevent initializing "centralDate" from "selectedDate" when today is disabled', async () => {
528
+ const clock = sinon.useFakeTimers({
529
+ now: new Date('2019/06/03').getTime(),
530
+ });
531
+ const el = await fixtureForSuite(html`
532
+ <${tagCalendar}
533
+ .selectedDate="${new Date('2001/01/08')}"
534
+ .disableDates=${/** @param {Date} date */ (date) => date.getDate() === 3}
535
+ ></${tagCalendar}>
536
+ `);
537
+ const elObj = new CalendarObject(el);
538
+ expect(isSameDate(el.centralDate, new Date('2001/01/08'))).to.be.true;
539
+ expect(elObj.activeMonth).to.equal('January');
540
+ expect(elObj.activeYear).to.equal('2001');
541
+ clock.restore();
542
+ });
543
+ it('requires the user to set an appropriate centralDate even when minDate and maxDate are equal', async () => {
544
+ const clock = sinon.useFakeTimers({
545
+ now: new Date('2019/06/03').getTime(),
546
+ });
547
+ const el = await fixtureForSuite(html`
548
+ <${tagCalendar}
549
+ .minDate="${new Date('2019/07/03')}"
550
+ .maxDate="${new Date('2019/07/03')}"
551
+ ></${tagCalendar}>
552
+ `);
553
+ const elSetting = await fixtureForSuite(html`
554
+ <${tagCalendar}
555
+ .centralDate="${new Date('2019/07/03')}"
556
+ .minDate="${new Date('2019/07/03')}"
557
+ .maxDate="${new Date('2019/07/03')}"
558
+ ></${tagCalendar}>
559
+ `);
560
+ clock.restore();
561
+ expect(isSameDate(el.centralDate, new Date('2019/07/03'))).to.be.true;
562
+ expect(isSameDate(elSetting.centralDate, new Date('2019/07/03'))).to.be.true;
563
+ });
564
+ describe('Normalization', () => {
565
+ it('normalizes all generated dates', async () => {
566
+ /** @param {Date} d */
567
+ function isNormalizedDate(d) {
568
+ return d.getHours() === 0 && d.getMinutes() === 0 && d.getSeconds() === 0;
569
+ }
570
+ const el = await fixtureForSuite(html`<${tagCalendar}></${tagCalendar}>`);
571
+ // The central date will be today's date: it's the date all other
572
+ // dates in the month view will be derived from.
573
+ expect(isNormalizedDate(el.centralDate)).to.be.true;
574
+ });
575
+ it('normalizes dates in date comparisons', async () => {
576
+ const selectedDate = new Date('2000-11-04T03:00:00');
577
+ // without normalization, selectedDate > maxDate would wrongfully be disabled
578
+ const maxDate = new Date('2000-11-29T02:00:00');
579
+ // without normalization, selectedDate < minDate would wrongfully be disabled
580
+ const minDate = new Date('2000-11-02T04:00:00');
581
+ const el = await fixtureForSuite(html`
582
+ <${tagCalendar}
583
+ .selectedDate="${selectedDate}"
584
+ .minDate="${minDate}"
585
+ .maxDate="${maxDate}"
586
+ ></${tagCalendar}>
587
+ `);
588
+ const elObj = new CalendarObject(el);
589
+ expect(elObj.getDayObj(29).isDisabled).to.equal(false);
590
+ expect(elObj.getDayObj(30).isDisabled).to.equal(true);
591
+ expect(elObj.getDayObj(2).isDisabled).to.equal(false);
592
+ expect(elObj.getDayObj(1).isDisabled).to.equal(true);
593
+ });
594
+ });
595
+ });
596
+ });
597
+ describe('Calendar navigation', () => {
598
+ describe('Title', () => {
599
+ it('contains secondary title displaying the current month and year in focus', async () => {
600
+ const el = await fixtureForSuite(html`<${tagCalendar}
601
+
602
+ .selectedDate="${new Date('2000/12/12')}"
603
+ ></${tagCalendar}>`);
604
+ const elObj = new CalendarObject(el);
605
+ expect(elObj.activeMonth).to.equal('December');
606
+ expect(elObj.activeYear).to.equal('2000');
607
+ });
608
+ it('updates the secondary title when the displayed month/year changes', async () => {
609
+ const el = await fixtureForSuite(
610
+ html`<${tagCalendar} .centralDate="${new Date('2000/12/12')}"></${tagCalendar}>`,
611
+ );
612
+ const elObj = new CalendarObject(el);
613
+ el.centralDate = new Date('1999/10/12');
614
+ await el.updateComplete;
615
+ expect(elObj.activeMonth).to.equal('October');
616
+ expect(elObj.activeYear).to.equal('1999');
617
+ });
618
+ describe('Accessibility', () => {
619
+ it('has aria-atomic="true" set on the secondary title', async () => {
620
+ const elObj = new CalendarObject(
621
+ await fixtureForSuite(html`<${tagCalendar}></${tagCalendar}>`),
622
+ );
623
+ expect(elObj.monthHeadingEl?.getAttribute('aria-atomic')).to.equal('true');
624
+ });
625
+ });
626
+ });
627
+ describe('Navigation', () => {
628
+ describe('finding enabled dates', () => {
629
+ it('has helper for `findNextEnabledDate()`, `findPreviousEnabledDate()`, `findNearestEnabledDate()`', async () => {
630
+ const el = await fixtureForSuite(html`
631
+ <${tagCalendar}
632
+ .selectedDate="${new Date('2001/01/02')}"
633
+ .disableDates=${/** @param {Date} date */ (date) => date.getDate() === 3 || date.getDate() === 4}
634
+ ></${tagCalendar}>
635
+ `);
636
+ const elObj = new CalendarObject(el);
637
+ el.focusDate(el.findNextEnabledDate());
638
+ await el.updateComplete;
639
+ expect(elObj.focusedDayObj?.monthday).to.equal(5);
640
+ el.focusDate(el.findPreviousEnabledDate());
641
+ await el.updateComplete;
642
+ expect(elObj.focusedDayObj?.monthday).to.equal(2);
643
+ el.focusDate(el.findNearestEnabledDate());
644
+ await el.updateComplete;
645
+ expect(elObj.focusedDayObj?.monthday).to.equal(1);
646
+ });
647
+ it('future dates take precedence over past dates when "distance" between dates is equal', async () => {
648
+ const clock = sinon.useFakeTimers({
649
+ now: new Date('2000/12/15').getTime(),
650
+ });
651
+ const el = await fixtureForSuite(html`
652
+ <${tagCalendar}
653
+ .disableDates="${/** @param {Date} d */ (d) => d.getDate() === 15}"
654
+ ></${tagCalendar}>
655
+ `);
656
+ el.focusDate(el.findNearestEnabledDate(new Date()));
657
+ await el.updateComplete;
658
+ const elObj = new CalendarObject(el);
659
+ expect(elObj.centralDayObj?.monthday).to.equal(16);
660
+ clock.restore();
661
+ });
662
+ it('will search 750 days in the past', async () => {
663
+ const clock = sinon.useFakeTimers({
664
+ now: new Date('2000/12/15').getTime(),
665
+ });
666
+ const el = await fixtureForSuite(html`
667
+ <${tagCalendar}
668
+ .disableDates="${/** @param {Date} d */ (d) => d.getFullYear() > 1998}"
669
+ ></${tagCalendar}>
670
+ `);
671
+ el.focusDate(el.findNearestEnabledDate(new Date()));
672
+ await el.updateComplete;
673
+ expect(el.centralDate.getFullYear()).to.equal(1998);
674
+ expect(el.centralDate.getMonth()).to.equal(11);
675
+ expect(el.centralDate.getDate()).to.equal(31);
676
+ clock.restore();
677
+ });
678
+ it('will search 750 days in the future', async () => {
679
+ const clock = sinon.useFakeTimers({
680
+ now: new Date('2000/12/15').getTime(),
681
+ });
682
+ const el = await fixtureForSuite(html`
683
+ <${tagCalendar}
684
+ .disableDates="${/** @param {Date} d */ (d) => d.getFullYear() < 2002}"
685
+ ></${tagCalendar}>
686
+ `);
687
+ el.focusDate(el.findNearestEnabledDate(new Date()));
688
+ await el.updateComplete;
689
+ expect(el.centralDate.getFullYear()).to.equal(2002);
690
+ expect(el.centralDate.getMonth()).to.equal(0);
691
+ expect(el.centralDate.getDate()).to.equal(1);
692
+ clock.restore();
693
+ });
694
+ it('throws if no available date can be found within +/- 750 days', async () => {
695
+ const el = await fixtureForSuite(html`
696
+ <${tagCalendar}
697
+ .disableDates="${/** @param {Date} d */ (d) => d.getFullYear() < 2002}"
698
+ ></${tagCalendar}>
699
+ `);
700
+ expect(() => {
701
+ el.findNextEnabledDate(new Date('1900/01/01'));
702
+ }).to.throw(Error, 'Could not find a selectable date within +/- 750 day for 1900/1/1');
703
+ });
704
+ });
705
+ describe('Year', () => {
706
+ it('has a button for navigation to previous year', async () => {
707
+ const el = await fixtureForSuite(
708
+ html`<${tagCalendar} .selectedDate="${new Date('2001/01/01')}"></${tagCalendar}>`,
709
+ );
710
+ const elObj = new CalendarObject(el);
711
+ expect(elObj.previousYearButtonEl).not.to.equal(null);
712
+ expect(elObj.activeMonth).to.equal('January');
713
+ expect(elObj.activeYear).to.equal('2001');
714
+
715
+ /** @type {HTMLElement} */
716
+ elObj.previousYearButtonEl.click();
717
+ await el.updateComplete;
718
+ expect(elObj.activeMonth).to.equal('January');
719
+ expect(elObj.activeYear).to.equal('2000');
720
+
721
+ /** @type {HTMLElement} */
722
+ elObj.previousYearButtonEl.click();
723
+ await el.updateComplete;
724
+ expect(elObj.activeMonth).to.equal('January');
725
+ expect(elObj.activeYear).to.equal('1999');
726
+ });
727
+ it('has a button for navigation to next year', async () => {
728
+ const el = await fixtureForSuite(
729
+ html`<${tagCalendar} .selectedDate="${new Date('2000/12/12')}"></${tagCalendar}>`,
730
+ );
731
+ const elObj = new CalendarObject(el);
732
+ expect(elObj.nextYearButtonEl).not.to.equal(null);
733
+ expect(elObj.activeMonth).to.equal('December');
734
+ expect(elObj.activeYear).to.equal('2000');
735
+
736
+ /** @type {HTMLElement} */
737
+ elObj.nextYearButtonEl.click();
738
+ await el.updateComplete;
739
+ expect(elObj.activeMonth).to.equal('December');
740
+ expect(elObj.activeYear).to.equal('2001');
741
+
742
+ /** @type {HTMLElement} */
743
+ elObj.nextYearButtonEl.click();
744
+ await el.updateComplete;
745
+ expect(elObj.activeMonth).to.equal('December');
746
+ expect(elObj.activeYear).to.equal('2002');
747
+ });
748
+ it('disables previousYearButton and nextYearButton based on disabled days accordingly', async () => {
749
+ const el = await fixtureForSuite(html`
750
+ <${tagCalendar} .selectedDate="${new Date('2000/06/12')}"></${tagCalendar}>
751
+ `);
752
+ const elObj = new CalendarObject(el);
753
+ expect(elObj.activeMonth).to.equal('June');
754
+ expect(elObj.activeYear).to.equal('2000');
755
+ expect(elObj.previousYearButtonEl?.hasAttribute('disabled')).to.equal(false);
756
+ expect(elObj.nextYearButtonEl?.hasAttribute('disabled')).to.equal(false);
757
+ el.minDate = new Date('2000/01/01');
758
+ el.maxDate = new Date('2000/12/31');
759
+ await el.updateComplete;
760
+ expect(elObj.previousYearButtonEl?.hasAttribute('disabled')).to.equal(true);
761
+ expect(elObj.nextYearButtonEl?.hasAttribute('disabled')).to.equal(true);
762
+
763
+ /** @type {HTMLElement} */
764
+ elObj.previousYearButtonEl.click();
765
+ await el.updateComplete;
766
+ expect(elObj.activeMonth).to.equal('June');
767
+ expect(elObj.activeYear).to.equal('2000');
768
+ el.minDate = new Date('1999/12/31');
769
+ el.maxDate = new Date('2001/01/01');
770
+ await el.updateComplete;
771
+ expect(elObj.previousYearButtonEl?.hasAttribute('disabled')).to.equal(false);
772
+ expect(elObj.nextYearButtonEl?.hasAttribute('disabled')).to.equal(false);
773
+ });
774
+ it('sets label to correct month previousYearButton and nextYearButton based on disabled days accordingly', async () => {
775
+ const el = await fixtureForSuite(html`
776
+ <${tagCalendar} .selectedDate="${new Date('2000/06/12')}"></${tagCalendar}>
777
+ `);
778
+ const elObj = new CalendarObject(el);
779
+ el.minDate = new Date('1999/07/12');
780
+ el.maxDate = new Date('2001/05/12');
781
+ await el.updateComplete;
782
+ expect(elObj.previousYearButtonEl?.hasAttribute('disabled')).to.equal(false);
783
+ expect(accessibleName(elObj.previousYearButtonEl)).to.equal('Previous year, July 1999');
784
+ expect(elObj.nextYearButtonEl?.hasAttribute('disabled')).to.equal(false);
785
+ expect(accessibleName(elObj.nextYearButtonEl)).to.equal('Next year, May 2001');
786
+ });
787
+ });
788
+ describe('Month', () => {
789
+ it('has a button for navigation to previous month', async () => {
790
+ const el = await fixtureForSuite(
791
+ html`<${tagCalendar} .selectedDate="${new Date('2001/01/01')}"></${tagCalendar}>`,
792
+ );
793
+ const elObj = new CalendarObject(el);
794
+ expect(elObj.previousMonthButtonEl).not.to.equal(null);
795
+ expect(elObj.activeMonth).to.equal('January');
796
+ expect(elObj.activeYear).to.equal('2001');
797
+
798
+ /** @type {HTMLElement} */
799
+ elObj.previousMonthButtonEl.click();
800
+ await el.updateComplete;
801
+ expect(elObj.activeMonth).to.equal('December');
802
+ expect(elObj.activeYear).to.equal('2000');
803
+
804
+ /** @type {HTMLElement} */
805
+ elObj.previousMonthButtonEl.click();
806
+ await el.updateComplete;
807
+ expect(elObj.activeMonth).to.equal('November');
808
+ expect(elObj.activeYear).to.equal('2000');
809
+ });
810
+ it('has a button for navigation to next month', async () => {
811
+ const el = await fixtureForSuite(
812
+ html`<${tagCalendar} .selectedDate="${new Date('2000/12/12')}"></${tagCalendar}>`,
813
+ );
814
+ const elObj = new CalendarObject(el);
815
+ expect(elObj.nextMonthButtonEl).not.to.equal(null);
816
+ expect(elObj.activeMonth).to.equal('December');
817
+ expect(elObj.activeYear).to.equal('2000');
818
+ /** @type {HTMLElement} */
819
+ elObj.nextMonthButtonEl.click();
820
+ await el.updateComplete;
821
+ expect(elObj.activeMonth).to.equal('January');
822
+ expect(elObj.activeYear).to.equal('2001');
823
+
824
+ /** @type {HTMLElement} */
825
+ elObj.nextMonthButtonEl.click();
826
+ await el.updateComplete;
827
+ expect(elObj.activeMonth).to.equal('February');
828
+ expect(elObj.activeYear).to.equal('2001');
829
+ });
830
+ it('disables previousMonthButton and nextMonthButton based on disabled days accordingly', async () => {
831
+ const el = await fixtureForSuite(html`
832
+ <${tagCalendar} .selectedDate="${new Date('2000/12/12')}"></${tagCalendar}>
833
+ `);
834
+ const elObj = new CalendarObject(el);
835
+ expect(elObj.activeMonth).to.equal('December');
836
+ expect(elObj.activeYear).to.equal('2000');
837
+ expect(elObj.previousMonthButtonEl?.hasAttribute('disabled')).to.equal(false);
838
+ expect(elObj.nextMonthButtonEl?.hasAttribute('disabled')).to.equal(false);
839
+ el.minDate = new Date('2000/12/01');
840
+ el.maxDate = new Date('2000/12/31');
841
+ await el.updateComplete;
842
+ expect(elObj.previousMonthButtonEl?.hasAttribute('disabled')).to.equal(true);
843
+ expect(elObj.nextMonthButtonEl?.hasAttribute('disabled')).to.equal(true);
844
+ /** @type {HTMLElement} */
845
+ elObj.previousMonthButtonEl.click();
846
+ await el.updateComplete;
847
+ expect(elObj.activeMonth).to.equal('December');
848
+ expect(elObj.activeYear).to.equal('2000');
849
+ /** @type {HTMLElement} */
850
+ elObj.previousMonthButtonEl.click();
851
+ await el.updateComplete;
852
+ expect(elObj.activeMonth).to.equal('December');
853
+ expect(elObj.activeYear).to.equal('2000');
854
+ });
855
+ it('handles switch to previous month when dates are disabled', async () => {
856
+ const clock = sinon.useFakeTimers({
857
+ now: new Date('2000/12/15').getTime(),
858
+ });
859
+ const el = await fixtureForSuite(html`<${tagCalendar}></${tagCalendar}>`);
860
+ const elObj = new CalendarObject(el);
861
+ expect(elObj.activeMonth).to.equal('December');
862
+ expect(elObj.activeYear).to.equal('2000');
863
+ el.minDate = new Date('2000/11/20');
864
+ await el.updateComplete;
865
+ expect(elObj.previousMonthButtonEl?.hasAttribute('disabled')).to.equal(false);
866
+ expect(isSameDate(el.centralDate, new Date('2000/12/15'))).to.be.true;
867
+
868
+ /** @type {HTMLElement} */
869
+ elObj.previousMonthButtonEl.click();
870
+ await el.updateComplete;
871
+ expect(elObj.activeMonth).to.equal('November');
872
+ expect(elObj.activeYear).to.equal('2000');
873
+ expect(isSameDate(el.centralDate, new Date('2000/11/15'))).to.be.true;
874
+ clock.restore();
875
+ });
876
+ it('handles switch to next month when dates are disabled', async () => {
877
+ const clock = sinon.useFakeTimers({
878
+ now: new Date('2000/12/15').getTime(),
879
+ });
880
+ const el = await fixtureForSuite(html`<${tagCalendar}></${tagCalendar}>`);
881
+ const elObj = new CalendarObject(el);
882
+ expect(elObj.activeMonth).to.equal('December');
883
+ expect(elObj.activeYear).to.equal('2000');
884
+ el.maxDate = new Date('2001/01/10');
885
+ await el.updateComplete;
886
+ expect(elObj.nextMonthButtonEl?.hasAttribute('disabled')).to.equal(false);
887
+ expect(isSameDate(el.centralDate, new Date('2000/12/15'))).to.be.true;
888
+ /** @type {HTMLElement} */
889
+ elObj.nextMonthButtonEl.click();
890
+ await el.updateComplete;
891
+ expect(elObj.activeMonth).to.equal('January');
892
+ expect(elObj.activeYear).to.equal('2001');
893
+ expect(isSameDate(el.centralDate, new Date('2001/01/15'))).to.be.true;
894
+ clock.restore();
895
+ });
896
+ it('supports navigating from larger months to smaller ones (day counts)', async () => {
897
+ // given
898
+ const inputDate = new Date('2019/08/31');
899
+ const element = await fixtureForSuite(html`
900
+ <${tagCalendar} .centralDate="${inputDate}"> </${tagCalendar}>
901
+ `);
902
+ // when
903
+ const remote = new CalendarObject(element);
904
+ /** @type {HTMLElement} */
905
+ remote.nextMonthButtonEl.click();
906
+ await element.updateComplete;
907
+ // then
908
+ expect(remote.activeMonth).to.equal('September');
909
+ expect(remote.activeYear).to.equal('2019');
910
+ expect(remote.centralDayObj?.el).dom.to.equal(`
911
+ <div
912
+ class="calendar__day-button"
913
+ aria-disabled="false"
914
+ role="button"
915
+ tabindex="0"
916
+ aria-pressed="false"
917
+ past=""
918
+ current-month="">
919
+ <span class="calendar__day-button__text">
920
+ 30
921
+ </span>
922
+ <span class="u-sr-only">
923
+ September 2019 Monday
924
+ </span>
925
+ </div>
926
+ `);
927
+ });
928
+ });
929
+ describe('Accessibility', () => {
930
+ it('navigate buttons have a aria-label and title attribute with accessible label', async () => {
931
+ const el = await fixtureForSuite(html`
932
+ <${tagCalendar} .selectedDate="${new Date('2000/12/12')}"></${tagCalendar}>
933
+ `);
934
+ const elObj = new CalendarObject(el);
935
+ // month
936
+ expect(accessibleName(elObj.previousMonthButtonEl)).to.equal(
937
+ 'Previous month, November 2000',
938
+ );
939
+ expect(accessibleName(elObj.previousMonthButtonEl)).to.equal(
940
+ 'Previous month, November 2000',
941
+ );
942
+ expect(accessibleName(elObj.nextMonthButtonEl)).to.equal('Next month, January 2001');
943
+ expect(accessibleName(elObj.nextMonthButtonEl)).to.equal('Next month, January 2001');
944
+
945
+ // year
946
+ expect(accessibleName(elObj.previousYearButtonEl)).to.equal(
947
+ 'Previous year, December 1999',
948
+ );
949
+ expect(accessibleName(elObj.previousYearButtonEl)).to.equal(
950
+ 'Previous year, December 1999',
951
+ );
952
+ expect(accessibleName(elObj.nextYearButtonEl)).to.equal('Next year, December 2001');
953
+ expect(accessibleName(elObj.nextYearButtonEl)).to.equal('Next year, December 2001');
954
+ });
955
+ it('disables a date with disableDates function provide a correct message', async () => {
956
+ /** @param {Date} d */
957
+ const disable15th = (d) => d.getDate() === 15;
958
+ const el = await fixtureForSuite(html`
959
+ <${tagCalendar}
960
+ .selectedDate="${new Date('2000/12/01')}"
961
+ .disableDates=${disable15th}
962
+ ></${tagCalendar}>
963
+ `);
964
+ const elObj = new CalendarObject(el);
965
+ expect(elObj.getDayObj(15).isDisabled).to.equal(true);
966
+ expect(elObj.getDayObj(15).el).dom.to.equal(`
967
+ <div
968
+ class="calendar__day-button"
969
+ aria-disabled="true"
970
+ role="button"
971
+ tabindex="-1"
972
+ aria-pressed="false"
973
+ past=""
974
+ current-month="">
975
+ <span class="calendar__day-button__text">
976
+ 15
977
+ </span>
978
+ <span class="u-sr-only">
979
+ December 2000 Friday This date is unavailable. Please choose another date.
980
+ </span>
981
+ </div>
982
+ `);
983
+ });
984
+ it('disables days before "minDate" property provide a correct message', async () => {
985
+ const el = await fixtureForSuite(html`
986
+ <${tagCalendar}
987
+ .selectedDate="${new Date('2000/12/31')}"
988
+ .minDate="${new Date('2000/12/09')}"
989
+ >
990
+ </${tagCalendar}>
991
+ `);
992
+ const elObj = new CalendarObject(el);
993
+ expect(elObj.getDayObj(1).isDisabled).to.equal(true);
994
+ expect(elObj.getDayObj(1).el).dom.to.equal(`
995
+ <div
996
+ class="calendar__day-button"
997
+ aria-disabled="true"
998
+ role="button"
999
+ tabindex="-1"
1000
+ aria-pressed="false"
1001
+ past=""
1002
+ current-month="">
1003
+ <span class="calendar__day-button__text">
1004
+ 1
1005
+ </span>
1006
+ <span class="u-sr-only">
1007
+ December 2000 Friday This date is unavailable. Earliest available date is 9 December 2000. Please choose another date.
1008
+ </span>
1009
+ </div>
1010
+ `);
1011
+ });
1012
+ it('disables days after "maxDate" property provide a correct message', async () => {
1013
+ const el = await fixtureForSuite(html`
1014
+ <${tagCalendar}
1015
+ .selectedDate="${new Date('2000/12/31')}"
1016
+ .maxDate="${new Date('2000/12/09')}"
1017
+ >
1018
+ </${tagCalendar}>
1019
+ `);
1020
+ const elObj = new CalendarObject(el);
1021
+ expect(elObj.getDayObj(30).isDisabled).to.equal(true);
1022
+ expect(elObj.getDayObj(30).el).dom.to.equal(`
1023
+ <div
1024
+ class="calendar__day-button"
1025
+ aria-disabled="true"
1026
+ role="button"
1027
+ tabindex="-1"
1028
+ aria-pressed="false"
1029
+ past=""
1030
+ current-month="">
1031
+ <span class="calendar__day-button__text">
1032
+ 30
1033
+ </span>
1034
+ <span class="u-sr-only">
1035
+ December 2000 Saturday This date is unavailable. Latest available date is 9 December 2000. Please choose another date.
1036
+ </span>
1037
+ </div>
1038
+ `);
1039
+ });
1040
+ });
1041
+ });
1042
+ });
1043
+ describe('Calendar body (months view)', () => {
1044
+ it('renders the days of the week as table headers', async () => {
1045
+ const el = await fixtureForSuite(html`<${tagCalendar}
1046
+ .firstDayOfWeek=${0}
1047
+ .selectedDate="${new Date('2000/12/12')}"
1048
+ ></${tagCalendar}>`);
1049
+ const elObj = new CalendarObject(el);
1050
+ expect(elObj.weekdayHeaderEls.map((h) => h.textContent?.trim())).to.deep.equal([
1051
+ 'Sun',
1052
+ 'Mon',
1053
+ 'Tue',
1054
+ 'Wed',
1055
+ 'Thu',
1056
+ 'Fri',
1057
+ 'Sat',
1058
+ ]);
1059
+ });
1060
+ describe('Day view', () => {
1061
+ it('adds "today" attribute if date is today', async () => {
1062
+ const clock = sinon.useFakeTimers({
1063
+ now: new Date('2000/12/15').getTime(),
1064
+ });
1065
+ const el = await fixtureForSuite(html`<${tagCalendar}></${tagCalendar}>`);
1066
+ const elObj = new CalendarObject(el);
1067
+ expect(elObj.getDayEl(15).hasAttribute('today')).to.be.true;
1068
+ expect(
1069
+ elObj.checkForAllDayObjs(/** @param {DayObject} d */ (d) => d.isToday, [15]),
1070
+ ).to.equal(true);
1071
+ clock.restore();
1072
+ });
1073
+ it('adds "selected" attribute to the selected date', async () => {
1074
+ const el = await fixtureForSuite(
1075
+ html`<${tagCalendar} .selectedDate="${new Date('2000/12/12')}"></${tagCalendar}>`,
1076
+ );
1077
+ const elObj = new CalendarObject(el);
1078
+ expect(
1079
+ elObj.checkForAllDayObjs(
1080
+ /** @param {DayObject} obj */ (obj) => obj.el.hasAttribute('selected'),
1081
+ [12],
1082
+ ),
1083
+ ).to.equal(true);
1084
+ el.selectedDate = new Date('2000/12/15');
1085
+ await el.updateComplete;
1086
+ expect(
1087
+ elObj.checkForAllDayObjs(
1088
+ /** @param {DayObject} obj */ (obj) => obj.el.hasAttribute('selected'),
1089
+ [15],
1090
+ ),
1091
+ ).to.equal(true);
1092
+ });
1093
+ it('adds aria-disabled="true" attribute to disabled dates', async () => {
1094
+ const clock = sinon.useFakeTimers({
1095
+ now: new Date('2000/12/15').getTime(),
1096
+ });
1097
+ const el = await fixtureForSuite(html`
1098
+ <${tagCalendar}
1099
+ .selectedDate="${new Date('2000/12/10')}"
1100
+ .minDate="${new Date('2000/12/03')}"
1101
+ .maxDate="${new Date('2000/12/29')}"
1102
+ >
1103
+ </${tagCalendar}>
1104
+ `);
1105
+ const elObj = new CalendarObject(el);
1106
+ expect(
1107
+ elObj.checkForAllDayObjs(
1108
+ /** @param {DayObject} d */ (d) => d.el.getAttribute('aria-disabled') === 'true',
1109
+ [1, 2, 30, 31],
1110
+ ),
1111
+ ).to.equal(true);
1112
+ clock.restore();
1113
+ });
1114
+ });
1115
+ describe('User Interaction', () => {
1116
+ // For implementation, base on: https://www.w3.org/TR/2017/NOTE-wai-aria-practices-1.1-20171214/examples/grid/js/dataGrid.js
1117
+
1118
+ describe('Keyboard Navigation', () => {
1119
+ it('focused day is reachable via tab (tabindex="0")', async () => {
1120
+ const el = await fixtureForSuite(html`
1121
+ <${tagCalendar} .selectedDate="${new Date('2000/12/12')}"></${tagCalendar}>
1122
+ `);
1123
+ const elObj = new CalendarObject(el);
1124
+ expect(
1125
+ elObj.checkForAllDayObjs(
1126
+ /** @param {DayObject} d */ (d) => d.buttonEl.getAttribute('tabindex') === '0',
1127
+ [12],
1128
+ ),
1129
+ ).to.equal(true);
1130
+ });
1131
+ it('non focused days are not reachable via tab (have tabindex="-1")', async () => {
1132
+ const el = await fixtureForSuite(html`
1133
+ <${tagCalendar} .selectedDate="${new Date('2000/12/12')}"></${tagCalendar}>
1134
+ `);
1135
+ const elObj = new CalendarObject(el);
1136
+ expect(
1137
+ elObj.checkForAllDayObjs(
1138
+ /** @param {DayObject} d */ (d) => d.buttonEl.getAttribute('tabindex') === '-1',
1139
+ /** @param {number} dayNumber */ (dayNumber) => dayNumber !== 12,
1140
+ ),
1141
+ ).to.equal(true);
1142
+ });
1143
+ it('blocks navigation to disabled days', async () => {
1144
+ const el = await fixtureForSuite(html`
1145
+ <${tagCalendar}
1146
+ .selectedDate="${new Date('2000/12/31')}"
1147
+ .minDate="${new Date('2000/12/09')}"
1148
+ >
1149
+ </${tagCalendar}>
1150
+ `);
1151
+ const elObj = new CalendarObject(el);
1152
+ expect(
1153
+ elObj.checkForAllDayObjs(
1154
+ /** @param {DayObject} d */ (d) => d.buttonEl.getAttribute('tabindex') === '-1',
1155
+ /** @param {number} dayNumber */ (dayNumber) => dayNumber < 9,
1156
+ ),
1157
+ ).to.equal(true);
1158
+ });
1159
+ it('navigates through months with [pageup] [pagedown] keys', async () => {
1160
+ const el = await fixtureForSuite(html`
1161
+ <${tagCalendar} .selectedDate="${new Date('2001/01/02')}"></${tagCalendar}>
1162
+ `);
1163
+ const elObj = new CalendarObject(el);
1164
+ expect(elObj.activeMonth).to.equal('January');
1165
+ expect(elObj.activeYear).to.equal('2001');
1166
+ focusSelectedDate(el);
1167
+ await sendKeys({
1168
+ press: 'PageUp',
1169
+ });
1170
+ await el.updateComplete;
1171
+ expect(elObj.activeMonth).to.equal('December');
1172
+ expect(elObj.activeYear).to.equal('2000');
1173
+ await sendKeys({
1174
+ press: 'PageDown',
1175
+ });
1176
+ await el.updateComplete;
1177
+ expect(elObj.activeMonth).to.equal('January');
1178
+ expect(elObj.activeYear).to.equal('2001');
1179
+ });
1180
+ it('navigates through years with [alt + pageup] [alt + pagedown] keys', async () => {
1181
+ const el = await fixtureForSuite(html`
1182
+ <${tagCalendar} .selectedDate="${new Date('2001/01/02')}"></${tagCalendar}>
1183
+ `);
1184
+ focusSelectedDate(el);
1185
+ const elObj = new CalendarObject(el);
1186
+ expect(elObj.activeMonth).to.equal('January');
1187
+ expect(elObj.activeYear).to.equal('2001');
1188
+ await sendKeys({
1189
+ down: 'Alt',
1190
+ });
1191
+ await sendKeys({
1192
+ press: 'PageDown',
1193
+ });
1194
+ await sendKeys({
1195
+ up: 'Alt',
1196
+ });
1197
+ await el.updateComplete;
1198
+ focusSelectedDate(el);
1199
+ expect(elObj.activeMonth).to.equal('January');
1200
+ expect(elObj.activeYear).to.equal('2002');
1201
+ await sendKeys({
1202
+ down: 'Alt',
1203
+ });
1204
+ await sendKeys({
1205
+ press: 'PageUp',
1206
+ });
1207
+ await sendKeys({
1208
+ up: 'Alt',
1209
+ });
1210
+ await el.updateComplete;
1211
+ expect(elObj.activeMonth).to.equal('January');
1212
+ expect(elObj.activeYear).to.equal('2001');
1213
+ });
1214
+ describe('Arrow keys', () => {
1215
+ it('navigates (sets focus) to next row item via [arrow down] key', async () => {
1216
+ const el = await fixtureForSuite(html`
1217
+ <${tagCalendar} .selectedDate="${new Date('2001/01/02')}"></${tagCalendar}>
1218
+ `);
1219
+ const elObj = new CalendarObject(el);
1220
+ focusSelectedDate(el);
1221
+ await sendKeys({
1222
+ press: 'ArrowDown',
1223
+ });
1224
+ await el.updateComplete;
1225
+ expect(elObj.focusedDayObj?.monthday).to.equal(2 + 7);
1226
+ });
1227
+ it('navigates (sets focus) to previous row item via [arrow up] key', async () => {
1228
+ const el = await fixtureForSuite(html`
1229
+ <${tagCalendar} .selectedDate="${new Date('2001/01/02')}"></${tagCalendar}>
1230
+ `);
1231
+ const elObj = new CalendarObject(el);
1232
+ focusSelectedDate(el);
1233
+ await sendKeys({
1234
+ press: 'ArrowUp',
1235
+ });
1236
+ await el.updateComplete;
1237
+ expect(elObj.focusedDayObj?.monthday).to.equal(26); // of month before
1238
+ });
1239
+ it('navigates (sets focus) to previous column item via [arrow left] key', async () => {
1240
+ // 2000-12-12 is Tuesday; at 2nd of row
1241
+ const el = await fixtureForSuite(html`
1242
+ <${tagCalendar} .selectedDate="${new Date('2000/12/12')}"></${tagCalendar}>
1243
+ `);
1244
+ const elObj = new CalendarObject(el);
1245
+ focusSelectedDate(el);
1246
+ await sendKeys({
1247
+ press: 'ArrowLeft',
1248
+ });
1249
+ await el.updateComplete;
1250
+ expect(elObj.focusedDayObj?.monthday).to.equal(12 - 1);
1251
+ });
1252
+ it('navigates (sets focus) to next column item via [arrow right] key', async () => {
1253
+ // 2000-12-12 is Tuesday; at 2nd of row
1254
+ const el = await fixtureForSuite(html`
1255
+ <${tagCalendar} .selectedDate="${new Date('2000/12/12')}"></${tagCalendar}>
1256
+ `);
1257
+ const elObj = new CalendarObject(el);
1258
+ focusSelectedDate(el);
1259
+ await sendKeys({
1260
+ press: 'ArrowRight',
1261
+ });
1262
+ await el.updateComplete;
1263
+ expect(elObj.focusedDayObj?.monthday).to.equal(12 + 1);
1264
+ });
1265
+ it('navigates (sets focus) to next column item via [arrow right] key', async () => {
1266
+ const el = await fixtureForSuite(html`
1267
+ <${tagCalendar}
1268
+ .selectedDate="${new Date('2001/01/02')}"
1269
+ .disableDates=${/** @param {Date} date */ (date) => date.getDate() === 3 || date.getDate() === 4}
1270
+ ></${tagCalendar}>
1271
+ `);
1272
+ const elObj = new CalendarObject(el);
1273
+ focusSelectedDate(el);
1274
+ await sendKeys({
1275
+ press: 'ArrowRight',
1276
+ });
1277
+ await el.updateComplete;
1278
+ expect(elObj.focusedDayObj?.monthday).to.equal(3);
1279
+ });
1280
+ it('navigates (sets focus) to next row via [arrow right] key if last item in row', async () => {
1281
+ const el = await fixtureForSuite(html`
1282
+ <${tagCalendar}
1283
+ .firstDayOfWeek=${0}
1284
+ .selectedDate="${new Date('2019/01/05')}"
1285
+ ></${tagCalendar}>
1286
+ `);
1287
+ const elObj = new CalendarObject(el);
1288
+ expect(elObj.centralDayObj?.weekdayNameShort).to.equal('Sat');
1289
+ focusSelectedDate(el);
1290
+ await sendKeys({
1291
+ press: 'ArrowRight',
1292
+ });
1293
+ await el.updateComplete;
1294
+ expect(elObj.focusedDayObj?.monthday).to.equal(6);
1295
+ expect(elObj.focusedDayObj?.weekdayNameShort).to.equal('Sun');
1296
+ });
1297
+ it('navigates (sets focus) to previous row via [arrow left] key if first item in row', async () => {
1298
+ const el = await fixtureForSuite(html`
1299
+ <${tagCalendar}
1300
+ .firstDayOfWeek=${0}
1301
+ .selectedDate="${new Date('2019/01/06')}"
1302
+ ></${tagCalendar}>
1303
+ `);
1304
+ const elObj = new CalendarObject(el);
1305
+ expect(elObj.centralDayObj?.weekdayNameShort).to.equal('Sun');
1306
+ focusSelectedDate(el);
1307
+ await sendKeys({
1308
+ press: 'ArrowLeft',
1309
+ });
1310
+ await el.updateComplete;
1311
+ expect(elObj.focusedDayObj?.monthday).to.equal(5);
1312
+ expect(elObj.focusedDayObj?.weekdayNameShort).to.equal('Sat');
1313
+ });
1314
+ it('navigates to next month via [arrow right] key if last day of month', async () => {
1315
+ const el = await fixtureForSuite(html`
1316
+ <${tagCalendar} .selectedDate="${new Date('2000/12/31')}"></${tagCalendar}>
1317
+ `);
1318
+ const elObj = new CalendarObject(el);
1319
+ expect(elObj.activeMonth).to.equal('December');
1320
+ expect(elObj.activeYear).to.equal('2000');
1321
+ focusSelectedDate(el);
1322
+ await sendKeys({
1323
+ press: 'ArrowRight',
1324
+ });
1325
+ await el.updateComplete;
1326
+ expect(elObj.activeMonth).to.equal('January');
1327
+ expect(elObj.activeYear).to.equal('2001');
1328
+ expect(elObj.focusedDayObj?.monthday).to.equal(1);
1329
+ });
1330
+ it('navigates to previous month via [arrow left] key if first day of month', async () => {
1331
+ const el = await fixtureForSuite(html`
1332
+ <${tagCalendar} .selectedDate="${new Date('2001/01/01')}"></${tagCalendar}>
1333
+ `);
1334
+ const elObj = new CalendarObject(el);
1335
+ expect(elObj.activeMonth).to.equal('January');
1336
+ expect(elObj.activeYear).to.equal('2001');
1337
+ focusSelectedDate(el);
1338
+ await sendKeys({
1339
+ press: 'ArrowLeft',
1340
+ });
1341
+ await el.updateComplete;
1342
+ expect(elObj.activeMonth).to.equal('December');
1343
+ expect(elObj.activeYear).to.equal('2000');
1344
+ expect(elObj.focusedDayObj?.monthday).to.equal(31);
1345
+ });
1346
+ it('navigates to next month via [arrow down] key if last row of month', async () => {
1347
+ const el = await fixtureForSuite(html`
1348
+ <${tagCalendar} .selectedDate="${new Date('2000/12/30')}"></${tagCalendar}>
1349
+ `);
1350
+ const elObj = new CalendarObject(el);
1351
+ expect(elObj.activeMonth).to.equal('December');
1352
+ expect(elObj.activeYear).to.equal('2000');
1353
+ focusSelectedDate(el);
1354
+ await sendKeys({
1355
+ press: 'ArrowDown',
1356
+ });
1357
+ await el.updateComplete;
1358
+ expect(elObj.activeMonth).to.equal('January');
1359
+ expect(elObj.activeYear).to.equal('2001');
1360
+ expect(elObj.focusedDayObj?.monthday).to.equal(6);
1361
+ });
1362
+ it('navigates to previous month via [arrow up] key if first row of month', async () => {
1363
+ const el = await fixtureForSuite(html`
1364
+ <${tagCalendar} .selectedDate="${new Date('2001/01/02')}"></${tagCalendar}>
1365
+ `);
1366
+ const elObj = new CalendarObject(el);
1367
+ expect(elObj.activeMonth).to.equal('January');
1368
+ expect(elObj.activeYear).to.equal('2001');
1369
+ focusSelectedDate(el);
1370
+ await sendKeys({
1371
+ press: 'ArrowUp',
1372
+ });
1373
+ await el.updateComplete;
1374
+ expect(elObj.activeMonth).to.equal('December');
1375
+ expect(elObj.activeYear).to.equal('2000');
1376
+ expect(elObj.focusedDayObj?.monthday).to.equal(26);
1377
+ });
1378
+ });
1379
+ });
1380
+ describe('Initial central', () => {
1381
+ it('is based on "selectedDate"', async () => {
1382
+ const el = await fixtureForSuite(html`
1383
+ <${tagCalendar} .selectedDate=${new Date('2019/06/15')}></${tagCalendar}>
1384
+ `);
1385
+ const elObj = new CalendarObject(el);
1386
+ expect(elObj.centralDayObj?.monthday).to.equal(15);
1387
+ });
1388
+ it('is today if no selected date is available', async () => {
1389
+ const clock = sinon.useFakeTimers({
1390
+ now: new Date('2000/12/15').getTime(),
1391
+ });
1392
+ const el = await fixtureForSuite(html`<${tagCalendar}></${tagCalendar}>`);
1393
+ const elObj = new CalendarObject(el);
1394
+ expect(elObj.centralDayObj?.monthday).to.equal(15);
1395
+ clock.restore();
1396
+ });
1397
+ it('is nearest to today if no selected date is available and today is disabled', async () => {
1398
+ const clock = sinon.useFakeTimers({
1399
+ now: new Date('2000/12/15').getTime(),
1400
+ });
1401
+ const calWithMin = await fixtureForSuite(
1402
+ html`<${tagCalendar} .minDate=${new Date('2000/12/25')}></${tagCalendar}>`,
1403
+ );
1404
+ const calObjWithMin = new CalendarObject(calWithMin);
1405
+ expect(calObjWithMin.centralDayObj?.monthday).to.equal(25);
1406
+ const calWithMax = await fixtureForSuite(
1407
+ html`<${tagCalendar} .maxDate=${new Date('2000/12/05')}></${tagCalendar}>`,
1408
+ );
1409
+ const calObjWithMax = new CalendarObject(calWithMax);
1410
+ expect(calObjWithMax.centralDayObj?.monthday).to.equal(5);
1411
+ const calWithDisabled = await fixtureForSuite(html`<${tagCalendar}
1412
+ .disableDates=${/** @param {Date} date */ (date) => date.getDate() === 15}
1413
+ ></${tagCalendar}>`);
1414
+ await calWithDisabled.updateComplete;
1415
+ const calObjWithDisabled = new CalendarObject(calWithDisabled);
1416
+ expect(calObjWithDisabled.centralDayObj?.monthday).to.equal(16);
1417
+ clock.restore();
1418
+ });
1419
+ });
1420
+
1421
+ /**
1422
+ * Not in scope:
1423
+ * - (virtual) scrolling: still under discussion. Wait for UX
1424
+ */
1425
+ });
1426
+ describe('Accessibility', () => {
1427
+ // Based on:
1428
+ // - https://codepen.io/erikkroes/pen/jJEWpR
1429
+
1430
+ // Navigation and day labels based on:
1431
+ // - https://dequeuniversity.com/library/aria/date-pickers/sf-date-picker
1432
+ // (recommended in W3C Editors Draft)
1433
+
1434
+ // For implementation, base on:
1435
+ // https://www.w3.org/TR/2017/NOTE-wai-aria-practices-1.1-20171214/examples/grid/js/dataGrid.js
1436
+ // As an enhancement, we detect when grid boundaries day are exceeded, so we move to
1437
+ // next/previous month.
1438
+ it('has role="application" to activate keyboard navigation', async () => {
1439
+ const elObj = new CalendarObject(
1440
+ await fixtureForSuite(html`<${tagCalendar}></${tagCalendar}>`),
1441
+ );
1442
+ expect(elObj.rootEl?.getAttribute('role')).to.equal('application');
1443
+ });
1444
+ it(`renders the calendar as a table element with role="grid", aria-readonly="true" and
1445
+ a caption (month + year)`, async () => {
1446
+ const elObj = new CalendarObject(
1447
+ await fixtureForSuite(html`<${tagCalendar}></${tagCalendar}>`),
1448
+ );
1449
+ expect(elObj.gridEl?.getAttribute('role')).to.equal('grid');
1450
+ expect(elObj.gridEl?.getAttribute('aria-readonly')).to.equal('true');
1451
+ });
1452
+ it('adds aria-labels to the weekday table headers', async () => {
1453
+ const elObj = new CalendarObject(
1454
+ await fixtureForSuite(html`<${tagCalendar} .firstDayOfWeek=${0}></${tagCalendar}>`),
1455
+ );
1456
+ expect(elObj.weekdayHeaderEls.map((h) => accessibleName(h))).to.eql([
1457
+ 'Sunday',
1458
+ 'Monday',
1459
+ 'Tuesday',
1460
+ 'Wednesday',
1461
+ 'Thursday',
1462
+ 'Friday',
1463
+ 'Saturday',
1464
+ ]);
1465
+ });
1466
+ it('renders each day as a button inside a table cell', async () => {
1467
+ const elObj = new CalendarObject(
1468
+ await fixtureForSuite(html`<${tagCalendar}></${tagCalendar}>`),
1469
+ );
1470
+ const hasBtn = /** @param {DayObject} d */ (d) =>
1471
+ d.el.tagName === 'DIV' && d.el.getAttribute('role') === 'button';
1472
+ expect(elObj.checkForAllDayObjs(hasBtn)).to.equal(true);
1473
+ });
1474
+ it('renders days for previous and next months', async () => {
1475
+ const elObj = new CalendarObject(
1476
+ await fixtureForSuite(html`
1477
+ <${tagCalendar}
1478
+ .firstDayOfWeek=${0}
1479
+ .selectedDate="${new Date('2000/11/12')}"
1480
+ ></${tagCalendar}>
1481
+ `),
1482
+ );
1483
+ const { previousMonthDayObjs, nextMonthDayObjs } = elObj;
1484
+ expect(previousMonthDayObjs.length).to.equal(3);
1485
+ expect(previousMonthDayObjs[0].cellIndex).to.equal(0);
1486
+ expect(previousMonthDayObjs[0].monthday).to.equal(29);
1487
+ expect(previousMonthDayObjs[1].cellIndex).to.equal(1);
1488
+ expect(previousMonthDayObjs[1].monthday).to.equal(30);
1489
+ expect(previousMonthDayObjs[2].cellIndex).to.equal(2);
1490
+ expect(previousMonthDayObjs[2].monthday).to.equal(31);
1491
+ expect(nextMonthDayObjs.length).to.equal(9);
1492
+ expect(nextMonthDayObjs[0].cellIndex).to.equal(5);
1493
+ expect(nextMonthDayObjs[0].monthday).to.equal(1);
1494
+ expect(nextMonthDayObjs[1].cellIndex).to.equal(6);
1495
+ expect(nextMonthDayObjs[1].monthday).to.equal(2);
1496
+ expect(nextMonthDayObjs[2].cellIndex).to.equal(0);
1497
+ expect(nextMonthDayObjs[2].monthday).to.equal(3);
1498
+ expect(nextMonthDayObjs[3].cellIndex).to.equal(1);
1499
+ expect(nextMonthDayObjs[3].monthday).to.equal(4);
1500
+ expect(nextMonthDayObjs[4].cellIndex).to.equal(2);
1501
+ expect(nextMonthDayObjs[4].monthday).to.equal(5);
1502
+ expect(nextMonthDayObjs[5].cellIndex).to.equal(3);
1503
+ expect(nextMonthDayObjs[5].monthday).to.equal(6);
1504
+ expect(nextMonthDayObjs[6].cellIndex).to.equal(4);
1505
+ expect(nextMonthDayObjs[6].monthday).to.equal(7);
1506
+ expect(nextMonthDayObjs[7].cellIndex).to.equal(5);
1507
+ expect(nextMonthDayObjs[7].monthday).to.equal(8);
1508
+ expect(nextMonthDayObjs[8].cellIndex).to.equal(6);
1509
+ expect(nextMonthDayObjs[8].monthday).to.equal(9);
1510
+ });
1511
+ it('renders days for next months in the last month of the year', async () => {
1512
+ const elObj = new CalendarObject(
1513
+ await fixtureForSuite(html`
1514
+ <${tagCalendar}
1515
+ .firstDayOfWeek=${0}
1516
+ .selectedDate="${new Date('2020/12/12')}"
1517
+ ></${tagCalendar}>
1518
+ `),
1519
+ );
1520
+ const { nextMonthDayObjs } = elObj;
1521
+ expect(nextMonthDayObjs.length).to.equal(9);
1522
+ expect(nextMonthDayObjs[0].cellIndex).to.equal(5);
1523
+ expect(nextMonthDayObjs[0].monthday).to.equal(1);
1524
+ expect(nextMonthDayObjs[1].cellIndex).to.equal(6);
1525
+ expect(nextMonthDayObjs[1].monthday).to.equal(2);
1526
+ expect(nextMonthDayObjs[2].cellIndex).to.equal(0);
1527
+ expect(nextMonthDayObjs[2].monthday).to.equal(3);
1528
+ expect(nextMonthDayObjs[3].cellIndex).to.equal(1);
1529
+ expect(nextMonthDayObjs[3].monthday).to.equal(4);
1530
+ expect(nextMonthDayObjs[4].cellIndex).to.equal(2);
1531
+ expect(nextMonthDayObjs[4].monthday).to.equal(5);
1532
+ expect(nextMonthDayObjs[5].cellIndex).to.equal(3);
1533
+ expect(nextMonthDayObjs[5].monthday).to.equal(6);
1534
+ expect(nextMonthDayObjs[6].cellIndex).to.equal(4);
1535
+ expect(nextMonthDayObjs[6].monthday).to.equal(7);
1536
+ expect(nextMonthDayObjs[7].cellIndex).to.equal(5);
1537
+ expect(nextMonthDayObjs[7].monthday).to.equal(8);
1538
+ expect(nextMonthDayObjs[8].cellIndex).to.equal(6);
1539
+ expect(nextMonthDayObjs[8].monthday).to.equal(9);
1540
+ });
1541
+ it('renders days for previous months in the first month of the year', async () => {
1542
+ const elObj = new CalendarObject(
1543
+ await fixtureForSuite(html`
1544
+ <${tagCalendar}
1545
+ .firstDayOfWeek=${0}
1546
+ .selectedDate="${new Date('2020/01/12')}"
1547
+ ></${tagCalendar}>
1548
+ `),
1549
+ );
1550
+ const { previousMonthDayObjs } = elObj;
1551
+ expect(previousMonthDayObjs.length).to.equal(3);
1552
+ expect(previousMonthDayObjs[0].cellIndex).to.equal(0);
1553
+ expect(previousMonthDayObjs[0].monthday).to.equal(29);
1554
+ expect(previousMonthDayObjs[1].cellIndex).to.equal(1);
1555
+ expect(previousMonthDayObjs[1].monthday).to.equal(30);
1556
+ expect(previousMonthDayObjs[2].cellIndex).to.equal(2);
1557
+ expect(previousMonthDayObjs[2].monthday).to.equal(31);
1558
+ });
1559
+ it('sets aria-current="date" to todays button', async () => {
1560
+ const elObj = new CalendarObject(
1561
+ await fixtureForSuite(html`<${tagCalendar}></${tagCalendar}>`),
1562
+ );
1563
+ const hasAriaCurrent = /** @param {DayObject} d */ (d) =>
1564
+ d.buttonEl.getAttribute('aria-current') === 'date';
1565
+ const monthday = new Date().getDate();
1566
+ expect(elObj.checkForAllDayObjs(hasAriaCurrent, [monthday])).to.equal(true);
1567
+ });
1568
+ it('sets aria-pressed="true" on selected date button', async () => {
1569
+ const elObj = new CalendarObject(
1570
+ await fixtureForSuite(html`
1571
+ <${tagCalendar} .selectedDate="${new Date('2000/11/12')}"></${tagCalendar}>
1572
+ `),
1573
+ );
1574
+ const hasAriaPressed = /** @param {DayObject} d */ (d) =>
1575
+ d.buttonEl.getAttribute('aria-pressed') === 'true';
1576
+ expect(elObj.checkForAllDayObjs(hasAriaPressed, [12])).to.equal(true);
1577
+ });
1578
+
1579
+ /**
1580
+ * Not in scope:
1581
+ * - reads the new focused day on month navigation"
1582
+ */
1583
+ });
1584
+
1585
+ /**
1586
+ * Not in scope:
1587
+ * - show week numbers
1588
+ */
1589
+ });
1590
+ describe('Localization', () => {
1591
+ it('supports custom locale with a fallback to a global locale', async () => {
1592
+ const el = await fixtureForSuite(html`
1593
+ <${tagCalendar} .selectedDate="${new Date('2019/12/20')}"></${tagCalendar}>
1594
+ `);
1595
+ const elObj = new CalendarObject(el);
1596
+ expect(elObj.activeMonth).to.equal('December');
1597
+ el.locale = 'fr-FR';
1598
+ await el.updateComplete;
1599
+ expect(elObj.activeMonth).to.equal('décembre');
1600
+ localizeManager.locale = 'cs-CZ';
1601
+ await el.updateComplete;
1602
+ expect(elObj.activeMonth).to.equal('décembre');
1603
+ el.locale = '';
1604
+ await el.updateComplete;
1605
+ expect(elObj.activeMonth).to.equal('prosinec');
1606
+ });
1607
+ it('displays the right translations according to locale', async () => {
1608
+ const el = await fixtureForSuite(html`
1609
+ <${tagCalendar}
1610
+ .firstDayOfWeek=${0}
1611
+ .centralDate=${new Date('2019/11/20')}
1612
+ ></${tagCalendar}>
1613
+ `);
1614
+ const elObj = new CalendarObject(el);
1615
+ expect(accessibleName(elObj.nextMonthButtonEl)).to.equal('Next month, December 2019');
1616
+ expect(accessibleName(elObj.previousMonthButtonEl)).to.equal(
1617
+ 'Previous month, October 2019',
1618
+ );
1619
+ expect(elObj.weekdayHeaderEls.map((h) => accessibleName(h))).to.eql([
1620
+ 'Sunday',
1621
+ 'Monday',
1622
+ 'Tuesday',
1623
+ 'Wednesday',
1624
+ 'Thursday',
1625
+ 'Friday',
1626
+ 'Saturday',
1627
+ ]);
1628
+ expect(elObj.weekdayHeaderEls.map((h) => h.textContent?.trim())).to.deep.equal([
1629
+ 'Sun',
1630
+ 'Mon',
1631
+ 'Tue',
1632
+ 'Wed',
1633
+ 'Thu',
1634
+ 'Fri',
1635
+ 'Sat',
1636
+ ]);
1637
+ localizeManager.locale = 'nl-NL';
1638
+ await el.localizeNamespacesLoaded;
1639
+ await el.updateComplete;
1640
+ expect(accessibleName(elObj.nextMonthButtonEl)).to.equal('Volgende maand, december 2019');
1641
+ expect(accessibleName(elObj.previousMonthButtonEl)).to.equal('Vorige maand, oktober 2019');
1642
+ expect(elObj.weekdayHeaderEls.map((h) => accessibleName(h))).to.eql([
1643
+ 'zondag',
1644
+ 'maandag',
1645
+ 'dinsdag',
1646
+ 'woensdag',
1647
+ 'donderdag',
1648
+ 'vrijdag',
1649
+ 'zaterdag',
1650
+ ]);
1651
+ expect(elObj.weekdayHeaderEls.map((h) => h.textContent?.trim())).to.deep.equal([
1652
+ 'zo',
1653
+ 'ma',
1654
+ 'di',
1655
+ 'wo',
1656
+ 'do',
1657
+ 'vr',
1658
+ 'za',
1659
+ ]);
1660
+ });
1661
+ });
1662
+ describe('Accessibility', () => {
1663
+ it('is accessible', async () => {
1664
+ const el = await fixtureForSuite(html`<${tagCalendar}></${tagCalendar}>`);
1665
+ await expect(el).to.be.accessible();
1666
+ });
1667
+ it('is accessible with a date selected', async () => {
1668
+ const today = new Date();
1669
+ const selectedDate = new Date(today.getFullYear(), today.getMonth(), today.getDate() + 1);
1670
+ const el = await fixtureForSuite(
1671
+ html`<${tagCalendar} .selectedDate="${selectedDate}"></${tagCalendar}>`,
1672
+ );
1673
+ await expect(el).to.be.accessible();
1674
+ });
1675
+ it('is accessible with disabled dates', async () => {
1676
+ const el = await fixtureForSuite(html`
1677
+ <${tagCalendar}
1678
+ .disableDates=${/** @param {Date} date */ (date) => date.getDay() === 6 || date.getDay() === 0}
1679
+ ></${tagCalendar}>
1680
+ `);
1681
+ await expect(el).to.be.accessible();
1682
+ });
1683
+ it('is hidden when attribute hidden is true', async () => {
1684
+ const el = await fixtureForSuite(html`<${tagCalendar} hidden></${tagCalendar}>`);
1685
+ expect(el).not.to.be.displayed;
1686
+ });
1687
+ });
1688
+ });
77
1689
  }