q2-tecton-elements 1.53.1 → 1.53.3

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 (421) hide show
  1. package/dist/cjs/click-elsewhere_2.cjs.entry.js +73 -69
  2. package/dist/cjs/click-elsewhere_2.cjs.entry.js.map +1 -1
  3. package/dist/cjs/{index-07285783.js → index-7aecfed8.js} +30 -18
  4. package/dist/cjs/index-7aecfed8.js.map +1 -0
  5. package/dist/cjs/loader.cjs.js +1 -1
  6. package/dist/cjs/q2-action-group.cjs.entry.js +2 -2
  7. package/dist/cjs/q2-action-sheet.cjs.entry.js +2 -2
  8. package/dist/cjs/q2-avatar.cjs.entry.js +1 -1
  9. package/dist/cjs/q2-badge_7.cjs.entry.js +4 -4
  10. package/dist/cjs/q2-calendar.cjs.entry.js +1 -1
  11. package/dist/cjs/q2-card.cjs.entry.js +1 -1
  12. package/dist/cjs/q2-carousel-pane.cjs.entry.js +3 -3
  13. package/dist/cjs/q2-carousel.cjs.entry.js +1 -1
  14. package/dist/cjs/q2-chart-area.cjs.entry.js +2 -2
  15. package/dist/cjs/q2-chart-bar.cjs.entry.js +2 -2
  16. package/dist/cjs/q2-chart-donut.cjs.entry.js +2 -2
  17. package/dist/cjs/q2-checkbox-group.cjs.entry.js +1 -1
  18. package/dist/cjs/q2-checkbox.cjs.entry.js +1 -1
  19. package/dist/cjs/q2-currency.cjs.entry.js +1 -1
  20. package/dist/cjs/q2-data-table.cjs.entry.js +1 -1
  21. package/dist/cjs/q2-detail.cjs.entry.js +2 -2
  22. package/dist/cjs/q2-dropdown-item.cjs.entry.js +1 -1
  23. package/dist/cjs/q2-dropdown.cjs.entry.js +4 -2
  24. package/dist/cjs/q2-dropdown.cjs.entry.js.map +1 -1
  25. package/dist/cjs/q2-editable-field.cjs.entry.js +1 -1
  26. package/dist/cjs/q2-example.cjs.entry.js +1 -1
  27. package/dist/cjs/q2-file-picker.cjs.entry.js +1 -1
  28. package/dist/cjs/q2-formatted-text.cjs.entry.js +1 -1
  29. package/dist/cjs/q2-item_3.cjs.entry.js +3 -3
  30. package/dist/cjs/q2-legend.cjs.entry.js +1 -1
  31. package/dist/cjs/q2-loc.cjs.entry.js +2 -2
  32. package/dist/cjs/q2-message.cjs.entry.js +2 -2
  33. package/dist/cjs/q2-month-picker.cjs.entry.js +3 -3
  34. package/dist/cjs/q2-optgroup.cjs.entry.js +2 -2
  35. package/dist/cjs/q2-option-list.cjs.entry.js +1 -1
  36. package/dist/cjs/q2-option.cjs.entry.js +2 -2
  37. package/dist/cjs/q2-pagination.cjs.entry.js +4 -4
  38. package/dist/cjs/q2-pill.cjs.entry.js +2 -2
  39. package/dist/cjs/q2-radio-group.cjs.entry.js +1 -1
  40. package/dist/cjs/q2-radio.cjs.entry.js +1 -1
  41. package/dist/cjs/q2-relative-time.cjs.entry.js +2 -2
  42. package/dist/cjs/q2-resize-observer.cjs.entry.js +1 -1
  43. package/dist/cjs/q2-section.cjs.entry.js +3 -3
  44. package/dist/cjs/q2-select.cjs.entry.js +130 -14
  45. package/dist/cjs/q2-select.cjs.entry.js.map +1 -1
  46. package/dist/cjs/q2-stepper-pane.cjs.entry.js +1 -1
  47. package/dist/cjs/q2-stepper-vertical.cjs.entry.js +2 -2
  48. package/dist/cjs/q2-stepper.cjs.entry.js +2 -2
  49. package/dist/cjs/q2-tag.cjs.entry.js +2 -2
  50. package/dist/cjs/q2-tecton-elements.cjs.js +1 -1
  51. package/dist/cjs/q2-textarea.cjs.entry.js +2 -2
  52. package/dist/cjs/q2-tooltip.cjs.entry.js +1 -1
  53. package/dist/cjs/tecton-tab-pane.cjs.entry.js +2 -2
  54. package/dist/collection/components/click-elsewhere/click-elsewhere.js.map +1 -1
  55. package/dist/collection/components/click-elsewhere/test/click-elsewhere-test.e2e.js.map +1 -1
  56. package/dist/collection/components/q2-action-group/q2-action-group.js +1 -1
  57. package/dist/collection/components/q2-action-group/q2-action-group.js.map +1 -1
  58. package/dist/collection/components/q2-action-group/test/q2-action-group.e2e.js.map +1 -1
  59. package/dist/collection/components/q2-action-group/test/q2-action-group.spec.js.map +1 -1
  60. package/dist/collection/components/q2-action-sheet/q2-action-sheet.js +1 -1
  61. package/dist/collection/components/q2-action-sheet/q2-action-sheet.js.map +1 -1
  62. package/dist/collection/components/q2-action-sheet/test/q2-action-sheet-test.e2e.js.map +1 -1
  63. package/dist/collection/components/q2-avatar/q2-avatar.js +1 -1
  64. package/dist/collection/components/q2-avatar/q2-avatar.js.map +1 -1
  65. package/dist/collection/components/q2-avatar/test/q2-avatar-test.e2e.js.map +1 -1
  66. package/dist/collection/components/q2-badge/q2-badge.js.map +1 -1
  67. package/dist/collection/components/q2-badge/test/q2-badge-test.e2e.js.map +1 -1
  68. package/dist/collection/components/q2-btn/q2-btn.js.map +1 -1
  69. package/dist/collection/components/q2-btn/test/q2-btn-test.e2e.js.map +1 -1
  70. package/dist/collection/components/q2-calendar/q2-calendar-helpers.js.map +1 -1
  71. package/dist/collection/components/q2-calendar/q2-calendar-types.js.map +1 -1
  72. package/dist/collection/components/q2-calendar/q2-calendar-validation.js.map +1 -1
  73. package/dist/collection/components/q2-calendar/q2-calendar.js.map +1 -1
  74. package/dist/collection/components/q2-calendar/q2-month-picker.js +2 -2
  75. package/dist/collection/components/q2-calendar/q2-month-picker.js.map +1 -1
  76. package/dist/collection/components/q2-calendar/test/helpers-test.e2e.js.map +1 -1
  77. package/dist/collection/components/q2-calendar/test/q2-calendar-month-picker-test.e2e.js.map +1 -1
  78. package/dist/collection/components/q2-calendar/test/q2-calendar-test.e2e.js +2 -2
  79. package/dist/collection/components/q2-calendar/test/q2-calendar-test.e2e.js.map +1 -1
  80. package/dist/collection/components/q2-calendar/test/validation-test.e2e.js.map +1 -1
  81. package/dist/collection/components/q2-card/q2-card.js.map +1 -1
  82. package/dist/collection/components/q2-card/test/q2-card-test.e2e.js.map +1 -1
  83. package/dist/collection/components/q2-carousel/q2-carousel.js.map +1 -1
  84. package/dist/collection/components/q2-carousel/test/q2-carousel-test.e2e.js.map +1 -1
  85. package/dist/collection/components/q2-carousel-pane/q2-carousel-pane.js +2 -2
  86. package/dist/collection/components/q2-carousel-pane/q2-carousel-pane.js.map +1 -1
  87. package/dist/collection/components/q2-carousel-pane/test/q2-carousel-pane-test.e2e.js.map +1 -1
  88. package/dist/collection/components/q2-carousel-pane/test/q2-carousel-pane-test.spec.js.map +1 -1
  89. package/dist/collection/components/q2-chart-area/q2-chart-area.js +1 -1
  90. package/dist/collection/components/q2-chart-area/q2-chart-area.js.map +1 -1
  91. package/dist/collection/components/q2-chart-area/test/q2-chart-area-test.e2e.js.map +1 -1
  92. package/dist/collection/components/q2-chart-bar/q2-chart-bar.js +1 -1
  93. package/dist/collection/components/q2-chart-bar/q2-chart-bar.js.map +1 -1
  94. package/dist/collection/components/q2-chart-bar/test/q2-chart-bar-test.e2e.js.map +1 -1
  95. package/dist/collection/components/q2-chart-donut/q2-chart-donut.js +1 -1
  96. package/dist/collection/components/q2-chart-donut/q2-chart-donut.js.map +1 -1
  97. package/dist/collection/components/q2-chart-donut/test/q2-chart-donut-test.e2e.js.map +1 -1
  98. package/dist/collection/components/q2-checkbox/q2-checkbox.js.map +1 -1
  99. package/dist/collection/components/q2-checkbox/test/q2-checkbox-test.e2e.js.map +1 -1
  100. package/dist/collection/components/q2-checkbox-group/q2-checkbox-group.js.map +1 -1
  101. package/dist/collection/components/q2-checkbox-group/test/q2-checkbox-group-test.e2e.js.map +1 -1
  102. package/dist/collection/components/q2-currency/q2-currency.js +1 -1
  103. package/dist/collection/components/q2-currency/q2-currency.js.map +1 -1
  104. package/dist/collection/components/q2-currency/test/q2-currency-test.e2e.js.map +1 -1
  105. package/dist/collection/components/q2-data-table/q2-data-table.js.map +1 -1
  106. package/dist/collection/components/q2-data-table/test/q2-data-table-test.e2e.js.map +1 -1
  107. package/dist/collection/components/q2-detail/q2-detail.js +1 -1
  108. package/dist/collection/components/q2-detail/q2-detail.js.map +1 -1
  109. package/dist/collection/components/q2-detail/test/q2-detail-test.e2e.js.map +1 -1
  110. package/dist/collection/components/q2-dropdown/q2-dropdown.js +3 -1
  111. package/dist/collection/components/q2-dropdown/q2-dropdown.js.map +1 -1
  112. package/dist/collection/components/q2-dropdown/test/q2-dropdown-test.e2e.js +5 -17
  113. package/dist/collection/components/q2-dropdown/test/q2-dropdown-test.e2e.js.map +1 -1
  114. package/dist/collection/components/q2-dropdown-item/q2-dropdown-item.js.map +1 -1
  115. package/dist/collection/components/q2-dropdown-item/test/q2-dropdown-item-test.e2e.js.map +1 -1
  116. package/dist/collection/components/q2-editable-field/q2-editable-field.js.map +1 -1
  117. package/dist/collection/components/q2-editable-field/test/q2-editable-field-test.e2e.js.map +1 -1
  118. package/dist/collection/components/q2-example/q2-example.js +1 -1
  119. package/dist/collection/components/q2-example/q2-example.js.map +1 -1
  120. package/dist/collection/components/q2-example/test/q2-example.e2e.js.map +1 -1
  121. package/dist/collection/components/q2-example/test/q2-example.spec.js.map +1 -1
  122. package/dist/collection/components/q2-file-picker/q2-file-picker.js.map +1 -1
  123. package/dist/collection/components/q2-file-picker/test/q2-file-picker-test.e2e.js.map +1 -1
  124. package/dist/collection/components/q2-file-picker/test/q2-file-picker-test.spec.js.map +1 -1
  125. package/dist/collection/components/q2-formatted-text/q2-formatted-text.js +1 -1
  126. package/dist/collection/components/q2-formatted-text/q2-formatted-text.js.map +1 -1
  127. package/dist/collection/components/q2-formatted-text/test/q2-formatted-text-test.e2e.js.map +1 -1
  128. package/dist/collection/components/q2-icon/q2-icon-types.js.map +1 -1
  129. package/dist/collection/components/q2-icon/q2-icon.js.map +1 -1
  130. package/dist/collection/components/q2-icon/test/q2-icon-test.e2e.js.map +1 -1
  131. package/dist/collection/components/q2-input/formatting/alpha.js.map +1 -1
  132. package/dist/collection/components/q2-input/formatting/alpha.spec.js.map +1 -1
  133. package/dist/collection/components/q2-input/formatting/alphanumeric.js.map +1 -1
  134. package/dist/collection/components/q2-input/formatting/alphanumeric.spec.js.map +1 -1
  135. package/dist/collection/components/q2-input/formatting/credit-card.js.map +1 -1
  136. package/dist/collection/components/q2-input/formatting/credit-card.spec.js.map +1 -1
  137. package/dist/collection/components/q2-input/formatting/currency.js.map +1 -1
  138. package/dist/collection/components/q2-input/formatting/currency.spec.js.map +1 -1
  139. package/dist/collection/components/q2-input/formatting/date.js.map +1 -1
  140. package/dist/collection/components/q2-input/formatting/date.spec.js.map +1 -1
  141. package/dist/collection/components/q2-input/formatting/generic.js.map +1 -1
  142. package/dist/collection/components/q2-input/formatting/number.js.map +1 -1
  143. package/dist/collection/components/q2-input/formatting/numeric.js.map +1 -1
  144. package/dist/collection/components/q2-input/formatting/numeric.spec.js.map +1 -1
  145. package/dist/collection/components/q2-input/formatting/phone.js.map +1 -1
  146. package/dist/collection/components/q2-input/formatting/phone.spec.js.map +1 -1
  147. package/dist/collection/components/q2-input/formatting/postal.js.map +1 -1
  148. package/dist/collection/components/q2-input/formatting/postal.spec.js.map +1 -1
  149. package/dist/collection/components/q2-input/formatting/ssn.js.map +1 -1
  150. package/dist/collection/components/q2-input/formatting/ssn.spec.js.map +1 -1
  151. package/dist/collection/components/q2-input/formatting/tin.js.map +1 -1
  152. package/dist/collection/components/q2-input/formatting/tin.spec.js.map +1 -1
  153. package/dist/collection/components/q2-input/q2-input-types.js.map +1 -1
  154. package/dist/collection/components/q2-input/q2-input.js +1 -1
  155. package/dist/collection/components/q2-input/q2-input.js.map +1 -1
  156. package/dist/collection/components/q2-input/test/q2-input-credit-card-test.e2e.js.map +1 -1
  157. package/dist/collection/components/q2-input/test/q2-input-test.e2e.js.map +1 -1
  158. package/dist/collection/components/q2-input/test/q2-input-test.spec.js.map +1 -1
  159. package/dist/collection/components/q2-item/q2-item.js +1 -1
  160. package/dist/collection/components/q2-item/q2-item.js.map +1 -1
  161. package/dist/collection/components/q2-item/test/q2-item-test.e2e.js.map +1 -1
  162. package/dist/collection/components/q2-item/test/q2-item-test.spec.js.map +1 -1
  163. package/dist/collection/components/q2-legend/q2-legend.js +1 -1
  164. package/dist/collection/components/q2-legend/q2-legend.js.map +1 -1
  165. package/dist/collection/components/q2-legend/test/q2-legend-test.e2e.js.map +1 -1
  166. package/dist/collection/components/q2-legend/test/q2-legend-test.spec.js.map +1 -1
  167. package/dist/collection/components/q2-link/q2-link.js.map +1 -1
  168. package/dist/collection/components/q2-link/test/q2-link-test.e2e.js.map +1 -1
  169. package/dist/collection/components/q2-list/q2-list.js +1 -1
  170. package/dist/collection/components/q2-list/q2-list.js.map +1 -1
  171. package/dist/collection/components/q2-list/test/q2-list-test.e2e.js.map +1 -1
  172. package/dist/collection/components/q2-loading/q2-loading.js.map +1 -1
  173. package/dist/collection/components/q2-loading/skeleton/q2-loading-element/index.js.map +1 -1
  174. package/dist/collection/components/q2-loading/skeleton/shapes.js.map +1 -1
  175. package/dist/collection/components/q2-loading/test/q2-loading-element-test.e2e.js.map +1 -1
  176. package/dist/collection/components/q2-loading/test/q2-loading-test.e2e.js.map +1 -1
  177. package/dist/collection/components/q2-loc/q2-loc.js +1 -1
  178. package/dist/collection/components/q2-loc/q2-loc.js.map +1 -1
  179. package/dist/collection/components/q2-loc/test/q2-loc-test.e2e.js.map +1 -1
  180. package/dist/collection/components/q2-loc/test/q2-loc-test.spec.js.map +1 -1
  181. package/dist/collection/components/q2-message/q2-message.js +1 -1
  182. package/dist/collection/components/q2-message/q2-message.js.map +1 -1
  183. package/dist/collection/components/q2-message/test/q2-message-test.e2e.js.map +1 -1
  184. package/dist/collection/components/q2-optgroup/q2-optgroup.js +1 -1
  185. package/dist/collection/components/q2-optgroup/q2-optgroup.js.map +1 -1
  186. package/dist/collection/components/q2-optgroup/test/q2-optgroup-test.e2e.js.map +1 -1
  187. package/dist/collection/components/q2-option/q2-option.js +1 -1
  188. package/dist/collection/components/q2-option/q2-option.js.map +1 -1
  189. package/dist/collection/components/q2-option/test/q2-option-test.e2e.js.map +1 -1
  190. package/dist/collection/components/q2-option/test/q2-option-test.spec.js.map +1 -1
  191. package/dist/collection/components/q2-option-list/q2-option-list.js.map +1 -1
  192. package/dist/collection/components/q2-option-list/test/q2-option-list-test.e2e.js.map +1 -1
  193. package/dist/collection/components/q2-pagination/q2-pagination.js +3 -3
  194. package/dist/collection/components/q2-pagination/q2-pagination.js.map +1 -1
  195. package/dist/collection/components/q2-pagination/test/q2-pagination-test.e2e.js +1 -0
  196. package/dist/collection/components/q2-pagination/test/q2-pagination-test.e2e.js.map +1 -1
  197. package/dist/collection/components/q2-pill/q2-pill.js +1 -1
  198. package/dist/collection/components/q2-pill/q2-pill.js.map +1 -1
  199. package/dist/collection/components/q2-pill/test/q2-pill-test.e2e.js +2 -2
  200. package/dist/collection/components/q2-pill/test/q2-pill-test.e2e.js.map +1 -1
  201. package/dist/collection/components/q2-popover/q2-popover.css +18 -10
  202. package/dist/collection/components/q2-popover/q2-popover.js +74 -69
  203. package/dist/collection/components/q2-popover/q2-popover.js.map +1 -1
  204. package/dist/collection/components/q2-popover/test/q2-popover-test.e2e.js +1 -34
  205. package/dist/collection/components/q2-popover/test/q2-popover-test.e2e.js.map +1 -1
  206. package/dist/collection/components/q2-popover/test/q2-popover-test.spec.js +902 -511
  207. package/dist/collection/components/q2-popover/test/q2-popover-test.spec.js.map +1 -1
  208. package/dist/collection/components/q2-radio/q2-radio.js.map +1 -1
  209. package/dist/collection/components/q2-radio/test/q2-radio-test.e2e.js.map +1 -1
  210. package/dist/collection/components/q2-radio-group/q2-radio-group.js.map +1 -1
  211. package/dist/collection/components/q2-radio-group/test/q2-radio-group-test.e2e.js.map +1 -1
  212. package/dist/collection/components/q2-relative-time/q2-relative-time.js +1 -1
  213. package/dist/collection/components/q2-relative-time/q2-relative-time.js.map +1 -1
  214. package/dist/collection/components/q2-relative-time/test/q2-relative-time-test.e2e.js.map +1 -1
  215. package/dist/collection/components/q2-resize-observer/q2-resize-observer.js +1 -1
  216. package/dist/collection/components/q2-resize-observer/q2-resize-observer.js.map +1 -1
  217. package/dist/collection/components/q2-resize-observer/test/q2-resize-observer.e2e.js.map +1 -1
  218. package/dist/collection/components/q2-resize-observer/test/q2-resize-observer.spec.js.map +1 -1
  219. package/dist/collection/components/q2-section/q2-section.js +2 -2
  220. package/dist/collection/components/q2-section/q2-section.js.map +1 -1
  221. package/dist/collection/components/q2-section/test/q2-section-test.e2e.js.map +1 -1
  222. package/dist/collection/components/q2-select/q2-select.js +151 -16
  223. package/dist/collection/components/q2-select/q2-select.js.map +1 -1
  224. package/dist/collection/components/q2-select/test/q2-select-test.e2e.js +1 -1
  225. package/dist/collection/components/q2-select/test/q2-select-test.e2e.js.map +1 -1
  226. package/dist/collection/components/q2-select/test/q2-select-test.spec.js +552 -0
  227. package/dist/collection/components/q2-select/test/q2-select-test.spec.js.map +1 -0
  228. package/dist/collection/components/q2-stepper/q2-stepper.js +1 -1
  229. package/dist/collection/components/q2-stepper/q2-stepper.js.map +1 -1
  230. package/dist/collection/components/q2-stepper/test/q2-stepper-test.e2e.js.map +1 -1
  231. package/dist/collection/components/q2-stepper-pane/q2-stepper-pane.js.map +1 -1
  232. package/dist/collection/components/q2-stepper-pane/test/q2-stepper-pane-test.e2e.js.map +1 -1
  233. package/dist/collection/components/q2-stepper-vertical/q2-stepper-vertical.js +1 -1
  234. package/dist/collection/components/q2-stepper-vertical/q2-stepper-vertical.js.map +1 -1
  235. package/dist/collection/components/q2-stepper-vertical/test/q2-stepper-vertical-test.e2e.js.map +1 -1
  236. package/dist/collection/components/q2-tab-container/q2-tab-container.js +1 -1
  237. package/dist/collection/components/q2-tab-container/q2-tab-container.js.map +1 -1
  238. package/dist/collection/components/q2-tab-container/test/q2-tab-container-test.e2e.js.map +1 -1
  239. package/dist/collection/components/q2-tab-container/test/q2-tab-container-test.spec.js.map +1 -1
  240. package/dist/collection/components/q2-tab-pane/q2-tab-pane.js +1 -1
  241. package/dist/collection/components/q2-tab-pane/q2-tab-pane.js.map +1 -1
  242. package/dist/collection/components/q2-tab-pane/test/q2-tab-pane-test.e2e.js.map +1 -1
  243. package/dist/collection/components/q2-tag/q2-tag.js +1 -1
  244. package/dist/collection/components/q2-tag/q2-tag.js.map +1 -1
  245. package/dist/collection/components/q2-tag/test/q2-tag-test.e2e.js +6 -1
  246. package/dist/collection/components/q2-tag/test/q2-tag-test.e2e.js.map +1 -1
  247. package/dist/collection/components/q2-textarea/q2-textarea.js +1 -1
  248. package/dist/collection/components/q2-textarea/q2-textarea.js.map +1 -1
  249. package/dist/collection/components/q2-textarea/test/q2-textarea-test.e2e.js.map +1 -1
  250. package/dist/collection/components/q2-tooltip/q2-tooltip.js.map +1 -1
  251. package/dist/collection/components/q2-tooltip/test/q2-tooltip-test.e2e.js.map +1 -1
  252. package/dist/collection/components/tecton-tab-pane/tecton-tab-pane-types.js.map +1 -1
  253. package/dist/collection/components/tecton-tab-pane/tecton-tab-pane.js +2 -2
  254. package/dist/collection/components/tecton-tab-pane/tecton-tab-pane.js.map +1 -1
  255. package/dist/collection/components/tecton-tab-pane/test/tecton-tab-pane-test.e2e.js.map +1 -1
  256. package/dist/collection/index.js.map +1 -1
  257. package/dist/collection/utils/action-sheet.js.map +1 -1
  258. package/dist/collection/utils/charting.js.map +1 -1
  259. package/dist/collection/utils/helpers.js.map +1 -1
  260. package/dist/collection/utils/index.js +37 -0
  261. package/dist/collection/utils/index.js.map +1 -1
  262. package/dist/collection/utils/sanitize-html-string.js.map +1 -1
  263. package/dist/collection/utils/sanitize-regex-string.js.map +1 -1
  264. package/dist/collection/utils/test/action-sheet-test.e2e.js.map +1 -1
  265. package/dist/collection/utils/test/index.spec.js.map +1 -1
  266. package/dist/components/index2.js +29 -17
  267. package/dist/components/index2.js.map +1 -1
  268. package/dist/components/q2-action-group.js +1 -1
  269. package/dist/components/q2-action-sheet.js +1 -1
  270. package/dist/components/q2-avatar2.js +1 -1
  271. package/dist/components/q2-carousel-pane.js +2 -2
  272. package/dist/components/q2-chart-area.js +1 -1
  273. package/dist/components/q2-chart-bar.js +1 -1
  274. package/dist/components/q2-chart-donut.js +1 -1
  275. package/dist/components/q2-currency.js +1 -1
  276. package/dist/components/q2-detail.js +1 -1
  277. package/dist/components/q2-dropdown.js +3 -1
  278. package/dist/components/q2-dropdown.js.map +1 -1
  279. package/dist/components/q2-example.js +1 -1
  280. package/dist/components/q2-formatted-text.js +1 -1
  281. package/dist/components/q2-input2.js +1 -1
  282. package/dist/components/q2-item2.js +1 -1
  283. package/dist/components/q2-legend2.js +1 -1
  284. package/dist/components/q2-list2.js +1 -1
  285. package/dist/components/q2-loc.js +1 -1
  286. package/dist/components/q2-message2.js +1 -1
  287. package/dist/components/q2-month-picker.js +2 -2
  288. package/dist/components/q2-optgroup2.js +1 -1
  289. package/dist/components/q2-option2.js +1 -1
  290. package/dist/components/q2-pagination.js +3 -3
  291. package/dist/components/q2-pill.js +1 -1
  292. package/dist/components/q2-popover2.js +73 -69
  293. package/dist/components/q2-popover2.js.map +1 -1
  294. package/dist/components/q2-relative-time.js +1 -1
  295. package/dist/components/q2-resize-observer2.js +1 -1
  296. package/dist/components/q2-section.js +2 -2
  297. package/dist/components/q2-select2.js +133 -17
  298. package/dist/components/q2-select2.js.map +1 -1
  299. package/dist/components/q2-stepper-vertical.js +1 -1
  300. package/dist/components/q2-stepper.js +1 -1
  301. package/dist/components/q2-tab-container.js +1 -1
  302. package/dist/components/q2-tab-pane.js +1 -1
  303. package/dist/components/q2-tag.js +1 -1
  304. package/dist/components/q2-textarea.js +1 -1
  305. package/dist/components/tecton-tab-pane.js +2 -2
  306. package/dist/esm/click-elsewhere_2.entry.js +73 -69
  307. package/dist/esm/click-elsewhere_2.entry.js.map +1 -1
  308. package/dist/esm/{index-d18e2a20.js → index-99c46474.js} +30 -18
  309. package/dist/esm/index-99c46474.js.map +1 -0
  310. package/dist/esm/loader.js +1 -1
  311. package/dist/esm/q2-action-group.entry.js +2 -2
  312. package/dist/esm/q2-action-sheet.entry.js +2 -2
  313. package/dist/esm/q2-avatar.entry.js +1 -1
  314. package/dist/esm/q2-badge_7.entry.js +4 -4
  315. package/dist/esm/q2-calendar.entry.js +1 -1
  316. package/dist/esm/q2-card.entry.js +1 -1
  317. package/dist/esm/q2-carousel-pane.entry.js +3 -3
  318. package/dist/esm/q2-carousel.entry.js +1 -1
  319. package/dist/esm/q2-chart-area.entry.js +2 -2
  320. package/dist/esm/q2-chart-bar.entry.js +2 -2
  321. package/dist/esm/q2-chart-donut.entry.js +2 -2
  322. package/dist/esm/q2-checkbox-group.entry.js +1 -1
  323. package/dist/esm/q2-checkbox.entry.js +1 -1
  324. package/dist/esm/q2-currency.entry.js +1 -1
  325. package/dist/esm/q2-data-table.entry.js +1 -1
  326. package/dist/esm/q2-detail.entry.js +2 -2
  327. package/dist/esm/q2-dropdown-item.entry.js +1 -1
  328. package/dist/esm/q2-dropdown.entry.js +4 -2
  329. package/dist/esm/q2-dropdown.entry.js.map +1 -1
  330. package/dist/esm/q2-editable-field.entry.js +1 -1
  331. package/dist/esm/q2-example.entry.js +1 -1
  332. package/dist/esm/q2-file-picker.entry.js +1 -1
  333. package/dist/esm/q2-formatted-text.entry.js +1 -1
  334. package/dist/esm/q2-item_3.entry.js +3 -3
  335. package/dist/esm/q2-legend.entry.js +1 -1
  336. package/dist/esm/q2-loc.entry.js +2 -2
  337. package/dist/esm/q2-message.entry.js +2 -2
  338. package/dist/esm/q2-month-picker.entry.js +3 -3
  339. package/dist/esm/q2-optgroup.entry.js +2 -2
  340. package/dist/esm/q2-option-list.entry.js +1 -1
  341. package/dist/esm/q2-option.entry.js +2 -2
  342. package/dist/esm/q2-pagination.entry.js +4 -4
  343. package/dist/esm/q2-pill.entry.js +2 -2
  344. package/dist/esm/q2-radio-group.entry.js +1 -1
  345. package/dist/esm/q2-radio.entry.js +1 -1
  346. package/dist/esm/q2-relative-time.entry.js +2 -2
  347. package/dist/esm/q2-resize-observer.entry.js +1 -1
  348. package/dist/esm/q2-section.entry.js +3 -3
  349. package/dist/esm/q2-select.entry.js +131 -15
  350. package/dist/esm/q2-select.entry.js.map +1 -1
  351. package/dist/esm/q2-stepper-pane.entry.js +1 -1
  352. package/dist/esm/q2-stepper-vertical.entry.js +2 -2
  353. package/dist/esm/q2-stepper.entry.js +2 -2
  354. package/dist/esm/q2-tag.entry.js +2 -2
  355. package/dist/esm/q2-tecton-elements.js +1 -1
  356. package/dist/esm/q2-textarea.entry.js +2 -2
  357. package/dist/esm/q2-tooltip.entry.js +1 -1
  358. package/dist/esm/tecton-tab-pane.entry.js +2 -2
  359. package/dist/jest.setup.js +33 -0
  360. package/dist/jest.setup.js.map +1 -0
  361. package/dist/q2-tecton-elements/click-elsewhere_2.entry.js +103 -92
  362. package/dist/q2-tecton-elements/click-elsewhere_2.entry.js.map +1 -1
  363. package/dist/q2-tecton-elements/{index-d18e2a20.js → index-99c46474.js} +24 -17
  364. package/dist/q2-tecton-elements/index-99c46474.js.map +1 -0
  365. package/dist/q2-tecton-elements/q2-action-group.entry.js +4 -4
  366. package/dist/q2-tecton-elements/q2-action-sheet.entry.js +34 -34
  367. package/dist/q2-tecton-elements/q2-avatar.entry.js +6 -6
  368. package/dist/q2-tecton-elements/q2-badge_7.entry.js +17 -17
  369. package/dist/q2-tecton-elements/q2-calendar.entry.js +1 -1
  370. package/dist/q2-tecton-elements/q2-card.entry.js +1 -1
  371. package/dist/q2-tecton-elements/q2-carousel-pane.entry.js +21 -21
  372. package/dist/q2-tecton-elements/q2-carousel.entry.js +1 -1
  373. package/dist/q2-tecton-elements/q2-chart-area.entry.js +3 -3
  374. package/dist/q2-tecton-elements/q2-chart-bar.entry.js +80 -80
  375. package/dist/q2-tecton-elements/q2-chart-donut.entry.js +101 -101
  376. package/dist/q2-tecton-elements/q2-checkbox-group.entry.js +1 -1
  377. package/dist/q2-tecton-elements/q2-checkbox.entry.js +1 -1
  378. package/dist/q2-tecton-elements/q2-currency.entry.js +6 -6
  379. package/dist/q2-tecton-elements/q2-data-table.entry.js +1 -1
  380. package/dist/q2-tecton-elements/q2-detail.entry.js +39 -39
  381. package/dist/q2-tecton-elements/q2-dropdown-item.entry.js +1 -1
  382. package/dist/q2-tecton-elements/q2-dropdown.entry.js +13 -11
  383. package/dist/q2-tecton-elements/q2-dropdown.entry.js.map +1 -1
  384. package/dist/q2-tecton-elements/q2-editable-field.entry.js +8 -8
  385. package/dist/q2-tecton-elements/q2-example.entry.js +1 -1
  386. package/dist/q2-tecton-elements/q2-file-picker.entry.js +1 -1
  387. package/dist/q2-tecton-elements/q2-formatted-text.entry.js +2 -2
  388. package/dist/q2-tecton-elements/q2-item_3.entry.js +19 -19
  389. package/dist/q2-tecton-elements/q2-legend.entry.js +2 -2
  390. package/dist/q2-tecton-elements/q2-loc.entry.js +2 -2
  391. package/dist/q2-tecton-elements/q2-message.entry.js +21 -21
  392. package/dist/q2-tecton-elements/q2-month-picker.entry.js +14 -14
  393. package/dist/q2-tecton-elements/q2-optgroup.entry.js +8 -8
  394. package/dist/q2-tecton-elements/q2-option-list.entry.js +1 -1
  395. package/dist/q2-tecton-elements/q2-option.entry.js +14 -14
  396. package/dist/q2-tecton-elements/q2-pagination.entry.js +34 -34
  397. package/dist/q2-tecton-elements/q2-pill.entry.js +14 -14
  398. package/dist/q2-tecton-elements/q2-radio-group.entry.js +5 -5
  399. package/dist/q2-tecton-elements/q2-radio.entry.js +1 -1
  400. package/dist/q2-tecton-elements/q2-relative-time.entry.js +2 -2
  401. package/dist/q2-tecton-elements/q2-resize-observer.entry.js +1 -1
  402. package/dist/q2-tecton-elements/q2-section.entry.js +19 -19
  403. package/dist/q2-tecton-elements/q2-select.entry.js +196 -93
  404. package/dist/q2-tecton-elements/q2-select.entry.js.map +1 -1
  405. package/dist/q2-tecton-elements/q2-stepper-pane.entry.js +1 -1
  406. package/dist/q2-tecton-elements/q2-stepper-vertical.entry.js +37 -37
  407. package/dist/q2-tecton-elements/q2-stepper.entry.js +29 -29
  408. package/dist/q2-tecton-elements/q2-tag.entry.js +25 -25
  409. package/dist/q2-tecton-elements/q2-tecton-elements.esm.js +1 -1
  410. package/dist/q2-tecton-elements/q2-tecton-elements.esm.js.map +1 -1
  411. package/dist/q2-tecton-elements/q2-textarea.entry.js +3 -3
  412. package/dist/q2-tecton-elements/q2-tooltip.entry.js +1 -1
  413. package/dist/q2-tecton-elements/tecton-tab-pane.entry.js +6 -6
  414. package/dist/types/builds/q2e/development/tecton/tecton/packages/q2-tecton-elements/.stencil/jest.setup.d.ts +10 -0
  415. package/dist/types/components/q2-popover/q2-popover.d.ts +4 -4
  416. package/dist/types/components/q2-select/q2-select.d.ts +23 -0
  417. package/dist/types/utils/index.d.ts +3 -0
  418. package/package.json +3 -3
  419. package/dist/cjs/index-07285783.js.map +0 -1
  420. package/dist/esm/index-d18e2a20.js.map +0 -1
  421. package/dist/q2-tecton-elements/index-d18e2a20.js.map +0 -1
@@ -1,12 +1,18 @@
1
1
  import { newSpecPage } from "@stencil/core/testing";
2
2
  import { Q2Popover } from "../q2-popover";
3
+ import * as utils from "../../../utils/index";
3
4
  describe('popover', () => {
4
5
  let specPopover;
6
+ afterEach(() => {
7
+ jest.restoreAllMocks();
8
+ });
5
9
  const samplePlatformDimensions = {
6
10
  scrollY: 0,
7
11
  innerHeight: 800,
8
12
  innerWidth: 600,
9
13
  outletOffset: 20,
14
+ top: 0,
15
+ bottom: 0,
10
16
  };
11
17
  const sampleTectonWindow = {
12
18
  inMobileApp: false,
@@ -14,15 +20,78 @@ describe('popover', () => {
14
20
  platformUrl: '',
15
21
  platformDimensions: samplePlatformDimensions,
16
22
  };
23
+ const enablePopoverAPI = () => {
24
+ Object.defineProperty(HTMLElement.prototype, 'popover', { value: true, configurable: true });
25
+ };
17
26
  describe('Props', () => {
18
- describe('mode', () => {
19
- it('does not add the legacy class on the container (default)', async () => {
27
+ describe('align', () => {
28
+ it('adds the left class on the container by default', async () => {
20
29
  const page = await newSpecPage({
21
30
  components: [Q2Popover],
22
31
  html: `<q2-popover></q2-popover>`,
23
32
  });
24
- expect(page.root.shadowRoot.firstElementChild.classList.contains('legacy')).toBeFalsy();
33
+ expect(page.root.shadowRoot.firstElementChild.classList.contains('left')).toBeTruthy();
34
+ });
35
+ it('adds the left class on the container when align is "left"', async () => {
36
+ const page = await newSpecPage({
37
+ components: [Q2Popover],
38
+ html: `<q2-popover align="left"></q2-popover>`,
39
+ });
40
+ expect(page.root.shadowRoot.firstElementChild.classList.contains('left')).toBeTruthy();
41
+ });
42
+ it('adds the right class on the container when align is "right"', async () => {
43
+ const page = await newSpecPage({
44
+ components: [Q2Popover],
45
+ html: `<q2-popover align="right"></q2-popover>`,
46
+ });
47
+ expect(page.root.shadowRoot.firstElementChild.classList.contains('right')).toBeTruthy();
48
+ });
49
+ });
50
+ describe('block', () => {
51
+ it('adds the block class on the container when block is true', async () => {
52
+ const page = await newSpecPage({
53
+ components: [Q2Popover],
54
+ html: `<q2-popover block="true"></q2-popover>`,
55
+ });
56
+ expect(page.root.shadowRoot.firstElementChild.classList.contains('block')).toBeTruthy();
57
+ });
58
+ it('does not add the block class when block is false', async () => {
59
+ const page = await newSpecPage({
60
+ components: [Q2Popover],
61
+ html: `<q2-popover block="false"></q2-popover>`,
62
+ });
63
+ expect(page.root.shadowRoot.firstElementChild.classList.contains('block')).toBeFalsy();
64
+ });
65
+ });
66
+ describe('direction', () => {
67
+ const setupPopoverWithDirection = async (direction) => {
68
+ const page = await newSpecPage({
69
+ components: [Q2Popover],
70
+ html: `<q2-popover direction="${direction}"></q2-popover>`,
71
+ });
72
+ // Mock essential dependencies
73
+ window.visualViewport = { width: 800, height: 600 };
74
+ page.rootInstance.addViewportListeners = jest.fn();
75
+ page.rootInstance.controlElement = document.createElement('div');
76
+ // Simulate opening the popover and setting the direction
77
+ page.rootInstance.open = true;
78
+ page.rootInstance.currentDirection = direction;
79
+ page.rootInstance.show = true;
80
+ await page.waitForChanges();
81
+ return page;
82
+ };
83
+ it('adds the up class on the container when direction is "up" and popover is open', async () => {
84
+ const page = await setupPopoverWithDirection('up');
85
+ expect(page.rootInstance.currentDirection).toBe('up');
86
+ expect(page.root.shadowRoot.firstElementChild.classList.contains('up')).toBeTruthy();
87
+ });
88
+ it('adds the down class on the container when direction is "down" and popover is open', async () => {
89
+ const page = await setupPopoverWithDirection('down');
90
+ expect(page.rootInstance.currentDirection).toBe('down');
91
+ expect(page.root.shadowRoot.firstElementChild.classList.contains('down')).toBeTruthy();
25
92
  });
93
+ });
94
+ describe('mode', () => {
26
95
  it('adds the legacy class on the container when mode is "legacy"', async () => {
27
96
  const page = await newSpecPage({
28
97
  components: [Q2Popover],
@@ -30,9 +99,175 @@ describe('popover', () => {
30
99
  });
31
100
  expect(page.root.shadowRoot.firstElementChild.classList.contains('legacy')).toBeTruthy();
32
101
  });
102
+ it('sets mode to legacy and adds the legacy class when Popover API is NOT supported at runtime', async () => {
103
+ const page = await newSpecPage({
104
+ components: [Q2Popover],
105
+ html: `<q2-popover></q2-popover>`,
106
+ });
107
+ expect(page.rootInstance.mode).toBe('legacy');
108
+ expect(page.root.shadowRoot.firstElementChild.classList.contains('legacy')).toBeTruthy();
109
+ });
110
+ it('does not add the legacy class when Popover API is supported at runtime', async () => {
111
+ const page = await newSpecPage({
112
+ components: [Q2Popover],
113
+ html: `<q2-popover></q2-popover>`,
114
+ });
115
+ enablePopoverAPI();
116
+ page.rootInstance.mode = null;
117
+ page.rootInstance.componentWillLoad();
118
+ await page.waitForChanges();
119
+ expect(page.rootInstance.mode).not.toBe('legacy');
120
+ expect(page.root.shadowRoot.firstElementChild.classList.contains('legacy')).toBeFalsy();
121
+ });
122
+ });
123
+ describe('open', () => {
124
+ it('sets the open attribute on the hostElement when open is true', async () => {
125
+ const page = await newSpecPage({
126
+ components: [Q2Popover],
127
+ html: `<q2-popover></q2-popover>`,
128
+ });
129
+ page.rootInstance.addViewportListeners = jest.fn();
130
+ page.rootInstance.removeViewportListeners = jest.fn();
131
+ page.rootInstance.open = true;
132
+ await page.waitForChanges();
133
+ expect(page.rootInstance.hostElement.hasAttribute('open')).toBe(true);
134
+ });
135
+ it('removes the open attribute on the hostElement when open is false', async () => {
136
+ const page = await newSpecPage({
137
+ components: [Q2Popover],
138
+ html: `<q2-popover></q2-popover>`,
139
+ });
140
+ page.rootInstance.addViewportListeners = jest.fn();
141
+ page.rootInstance.removeViewportListeners = jest.fn();
142
+ page.rootInstance.open = false;
143
+ await page.waitForChanges();
144
+ expect(page.rootInstance.hostElement.hasAttribute('open')).toBe(false);
145
+ });
146
+ });
147
+ });
148
+ describe('Events', () => {
149
+ describe('popoverStateChanged', () => {
150
+ let specPopover;
151
+ let page;
152
+ beforeEach(async () => {
153
+ page = await newSpecPage({
154
+ components: [Q2Popover],
155
+ html: `<q2-popover></q2-popover>`,
156
+ });
157
+ specPopover = page.rootInstance;
158
+ specPopover.addViewportListeners = jest.fn();
159
+ specPopover.removeViewportListeners = jest.fn();
160
+ });
161
+ it('emits popoverStateChanged when open changes to true', async () => {
162
+ const popoverStateChangedSpy = jest.spyOn(specPopover.popoverStateChanged, 'emit');
163
+ specPopover.open = true;
164
+ await page.waitForChanges();
165
+ expect(popoverStateChangedSpy).toHaveBeenCalledWith({ open: true });
166
+ });
167
+ it('emits popoverStateChanged when open changes to false', async () => {
168
+ const popoverStateChangedSpy = jest.spyOn(specPopover.popoverStateChanged, 'emit');
169
+ specPopover.open = false;
170
+ await page.waitForChanges();
171
+ expect(popoverStateChangedSpy).toHaveBeenCalledWith({ open: false });
172
+ });
33
173
  });
34
174
  });
35
- describe('Methods', () => {
175
+ describe('Lifecycle Events', () => {
176
+ describe('disconnectedCallback', () => {
177
+ beforeEach(async () => {
178
+ specPopover = new Q2Popover();
179
+ specPopover.addViewportListeners = jest.fn();
180
+ specPopover.removeViewportListeners = jest.fn();
181
+ specPopover.containerElement = document.createElement('div');
182
+ specPopover.contentElement = document.createElement('div');
183
+ specPopover.controlElement = document.createElement('div');
184
+ });
185
+ it('calls removeViewportListeners', async () => {
186
+ specPopover.disconnectedCallback();
187
+ expect(specPopover.removeViewportListeners).toHaveBeenCalled();
188
+ });
189
+ it('removes the toggle event listener from containerElement', async () => {
190
+ const removeEventListenerSpy = jest.spyOn(specPopover.containerElement, 'removeEventListener');
191
+ specPopover.disconnectedCallback();
192
+ expect(removeEventListenerSpy).toHaveBeenCalledWith('toggle', specPopover.handlePopoverToggleEvent);
193
+ });
194
+ it('sets containerElement to null', async () => {
195
+ expect(specPopover.containerElement).not.toBeNull();
196
+ specPopover.disconnectedCallback();
197
+ expect(specPopover.containerElement).toBeNull();
198
+ });
199
+ it('sets contentElement to null', async () => {
200
+ expect(specPopover.contentElement).not.toBeNull();
201
+ specPopover.disconnectedCallback();
202
+ expect(specPopover.contentElement).toBeNull();
203
+ });
204
+ it('sets controlElement to null', async () => {
205
+ expect(specPopover.controlElement).not.toBeNull();
206
+ specPopover.disconnectedCallback();
207
+ expect(specPopover.controlElement).toBeNull();
208
+ });
209
+ });
210
+ describe('componentDidLoad', () => {
211
+ it('calls handleMinHeight', async () => {
212
+ specPopover = new Q2Popover();
213
+ specPopover.handleMinHeight = jest.fn();
214
+ specPopover.componentDidLoad();
215
+ expect(specPopover.handleMinHeight).toHaveBeenCalled();
216
+ });
217
+ it('when Popover API is supported, it sets up the "toggle" Popover API event listener on container element', async () => {
218
+ specPopover = new Q2Popover();
219
+ enablePopoverAPI();
220
+ specPopover.containerElement = document.createElement('div');
221
+ specPopover.containerElement.addEventListener = jest.fn();
222
+ specPopover.componentDidLoad();
223
+ expect(specPopover.containerElement.addEventListener).toHaveBeenCalledWith('toggle', specPopover.handlePopoverToggleEvent);
224
+ });
225
+ it('when open is true it calls determinePopDirection', async () => {
226
+ specPopover = new Q2Popover();
227
+ specPopover.open = true;
228
+ specPopover.determinePopDirection = jest.fn();
229
+ specPopover.componentDidLoad();
230
+ expect(specPopover.determinePopDirection).toHaveBeenCalled();
231
+ });
232
+ });
233
+ describe('componentWillLoad', () => {
234
+ it('if supportsPopoverAPI is false it sets mode to "legacy"', async () => {
235
+ specPopover = new Q2Popover();
236
+ specPopover.componentWillLoad();
237
+ expect(specPopover.mode).toBe('legacy');
238
+ });
239
+ it('if supportsPopoverAPI is true it does NOT set mode to "legacy"', async () => {
240
+ specPopover = new Q2Popover();
241
+ enablePopoverAPI();
242
+ specPopover.componentWillLoad();
243
+ expect(specPopover.mode).toBeNull();
244
+ });
245
+ });
246
+ });
247
+ describe('Listeners', () => {
248
+ describe('popoverState', () => {
249
+ it('updates open property when event detail and attribute do not match', async () => {
250
+ specPopover = new Q2Popover();
251
+ specPopover.open = false;
252
+ specPopover.popoverStateHandler(new CustomEvent('popoverState', { detail: { open: true } }));
253
+ expect(specPopover.open).toBe(true);
254
+ });
255
+ it('does not update the open property if detail and attribute match', async () => {
256
+ specPopover = new Q2Popover();
257
+ specPopover.open = true;
258
+ specPopover.popoverStateHandler(new CustomEvent('popoverState', { detail: { open: true } }));
259
+ expect(specPopover.open).toBe(true);
260
+ });
261
+ it('calls stopPropogation on the event', async () => {
262
+ specPopover = new Q2Popover();
263
+ const event = new CustomEvent('popoverState', { detail: { open: true } });
264
+ const stopSpy = jest.spyOn(event, 'stopPropagation');
265
+ specPopover.popoverStateHandler(event);
266
+ expect(stopSpy).toHaveBeenCalled();
267
+ });
268
+ });
269
+ });
270
+ describe('Public Methods API', () => {
36
271
  beforeEach(() => {
37
272
  specPopover = new Q2Popover();
38
273
  });
@@ -58,538 +293,694 @@ describe('popover', () => {
58
293
  });
59
294
  });
60
295
  });
61
- describe('Getters', () => {
62
- beforeEach(() => {
63
- specPopover = new Q2Popover();
64
- });
65
- describe('actualDirection', () => {
66
- it('returns direction when "up"', async () => {
67
- specPopover.direction = 'up';
68
- expect(specPopover.providedDirection).toBe('up');
69
- });
70
- it('returns direction when "down"', async () => {
71
- specPopover.direction = 'down';
72
- expect(specPopover.providedDirection).toBe('down');
73
- });
74
- it('returns undefined when not "up" or "down"', async () => {
75
- specPopover.direction = 'bottom';
76
- expect(specPopover.providedDirection).toBeUndefined();
296
+ describe('Watchers', () => {
297
+ describe('minHeightProvided', () => {
298
+ it('calls handleMinHeight', async () => {
299
+ specPopover = new Q2Popover();
300
+ specPopover.handleMinHeight = jest.fn();
301
+ specPopover.minHeight = 100;
302
+ specPopover.minHeightProvided();
303
+ expect(specPopover.handleMinHeight).toHaveBeenCalled();
304
+ });
305
+ });
306
+ describe('openChanged', () => {
307
+ beforeEach(async () => {
308
+ specPopover = new Q2Popover();
309
+ specPopover.addViewportListeners = jest.fn();
310
+ specPopover.removeViewportListeners = jest.fn();
311
+ specPopover.determinePopDirection = jest.fn();
312
+ specPopover.clearCSSProperties = jest.fn();
313
+ });
314
+ it('calls popoverStateChanged with the new open value', async () => {
315
+ specPopover.popoverStateChanged = { emit: jest.fn() };
316
+ await specPopover.openChanged(true);
317
+ expect(specPopover.popoverStateChanged.emit).toHaveBeenCalledWith({ open: true });
318
+ });
319
+ describe('when open is true', () => {
320
+ it('calls addViewportListeners', async () => {
321
+ await specPopover.openChanged(true);
322
+ expect(specPopover.addViewportListeners).toHaveBeenCalled();
323
+ });
324
+ it('calls determinePopDirection', async () => {
325
+ await specPopover.openChanged(true);
326
+ expect(specPopover.determinePopDirection).toHaveBeenCalled();
327
+ });
77
328
  });
78
- });
79
- describe('isModule', () => {
80
- it('returns false when window top matches window and platformDimensions is not defined', async () => {
81
- expect(window.top).toBe(window);
82
- expect(window.Tecton).toBeUndefined();
83
- expect(specPopover.isModule).toBe(false);
84
- });
85
- it('returns false when window top does not match window and platformDimensions is not defined', async () => {
86
- const windowSpy = jest.spyOn(window, 'top', 'get').mockReturnValue({});
87
- expect(window.top).not.toEqual(window);
88
- expect(window.Tecton).toBeUndefined();
89
- expect(specPopover.isModule).toBe(false);
90
- windowSpy.mockRestore();
91
- });
92
- it('returns false when window top matches window and platformDimensions is defined', async () => {
93
- window.Tecton = sampleTectonWindow;
94
- expect(window.top).toBe(window);
95
- expect(window.Tecton.platformDimensions).toBeTruthy();
96
- expect(specPopover.isModule).toBe(false);
97
- });
98
- it('returns true when window top does not match window and platformDimensions is defined', async () => {
99
- const windowSpy = jest.spyOn(window, 'top', 'get').mockReturnValue({});
100
- window.Tecton = sampleTectonWindow;
101
- expect(specPopover.isModule).toBe(true);
102
- windowSpy.mockRestore();
329
+ describe('when open is false', () => {
330
+ it('calls removeViewportListeners', async () => {
331
+ await specPopover.openChanged(false);
332
+ expect(specPopover.removeViewportListeners).toHaveBeenCalled();
333
+ });
334
+ it('sets currentDirection to undefined', async () => {
335
+ specPopover.currentDirection = 'up';
336
+ expect(specPopover.currentDirection).toBe('up');
337
+ await specPopover.openChanged(false);
338
+ expect(specPopover.currentDirection).toBeUndefined();
339
+ });
340
+ it('sets show to false if mode is legacy', async () => {
341
+ specPopover.mode = 'legacy';
342
+ specPopover.show = true;
343
+ expect(specPopover.show).toBe(true);
344
+ await specPopover.openChanged(false);
345
+ expect(specPopover.show).toBe(false);
346
+ });
347
+ it('sets show to false if Popover API is not supported', async () => {
348
+ specPopover.show = true;
349
+ expect(specPopover.show).toBe(true);
350
+ await specPopover.openChanged(false);
351
+ expect(specPopover.show).toBe(false);
352
+ });
353
+ it('calls hidePopover if Popover API is supported', async () => {
354
+ enablePopoverAPI();
355
+ specPopover.containerElement = document.createElement('div');
356
+ specPopover.containerElement.hidePopover = jest.fn();
357
+ await specPopover.openChanged(false);
358
+ expect(specPopover.containerElement.hidePopover).toHaveBeenCalled();
359
+ });
360
+ it('calls clearCSSProperties', async () => {
361
+ await specPopover.openChanged(false);
362
+ expect(specPopover.clearCSSProperties).toHaveBeenCalled();
363
+ });
103
364
  });
104
365
  });
105
366
  });
106
- describe('when in a module', () => {
107
- let specPopover;
108
- let windowSpy;
109
- let controlElement;
110
- let containerElement;
111
- beforeEach(async () => {
112
- specPopover = new Q2Popover();
113
- windowSpy = jest.spyOn(window, 'top', 'get').mockReturnValue({});
114
- window.Tecton = sampleTectonWindow;
115
- expect(specPopover.isModule).toBe(true);
116
- controlElement = document.createElement('div');
117
- specPopover.controlElement = controlElement;
118
- containerElement = document.createElement('div');
119
- specPopover.containerElement = containerElement;
120
- });
121
- afterEach(() => {
122
- windowSpy.mockRestore();
123
- });
124
- describe("when the module is taller than the window's viewport", () => {
367
+ describe('Local Methods', () => {
368
+ describe('Getters', () => {
125
369
  beforeEach(() => {
126
- specPopover.open = true;
127
- window.visualViewport = { height: 1200 };
370
+ specPopover = new Q2Popover();
371
+ });
372
+ describe('isModule', () => {
373
+ it('returns false when window top matches window and platformDimensions is not defined', async () => {
374
+ expect(window.top).toBe(window);
375
+ expect(window.Tecton).toBeUndefined();
376
+ expect(specPopover.isModule).toBe(false);
377
+ });
378
+ it('returns false when window top does not match window and platformDimensions is not defined', async () => {
379
+ const windowSpy = jest.spyOn(window, 'top', 'get').mockReturnValue({});
380
+ expect(window.top).not.toEqual(window);
381
+ expect(window.Tecton).toBeUndefined();
382
+ expect(specPopover.isModule).toBe(false);
383
+ windowSpy.mockRestore();
384
+ });
385
+ it('returns false when window top matches window and platformDimensions is defined', async () => {
386
+ window.Tecton = sampleTectonWindow;
387
+ expect(window.top).toBe(window);
388
+ expect(window.Tecton.platformDimensions).toBeTruthy();
389
+ expect(specPopover.isModule).toBe(false);
390
+ });
391
+ it('returns true when window top does not match window and platformDimensions is defined', async () => {
392
+ const windowSpy = jest.spyOn(window, 'top', 'get').mockReturnValue({});
393
+ window.Tecton = sampleTectonWindow;
394
+ expect(specPopover.isModule).toBe(true);
395
+ windowSpy.mockRestore();
396
+ });
128
397
  });
129
- it('sets the direction to down when control element has more space below it', async () => {
130
- const controlSpy = jest.spyOn(controlElement, 'getBoundingClientRect').mockReturnValue({
131
- top: 20,
132
- bottom: 70,
398
+ describe('providedDirection', () => {
399
+ it('returns direction when "up"', async () => {
400
+ specPopover.direction = 'up';
401
+ expect(specPopover.providedDirection).toBe('up');
402
+ });
403
+ it('returns direction when "down"', async () => {
404
+ specPopover.direction = 'down';
405
+ expect(specPopover.providedDirection).toBe('down');
406
+ });
407
+ it('returns undefined when not "up" or "down"', async () => {
408
+ specPopover.direction = 'bottom';
409
+ expect(specPopover.providedDirection).toBeUndefined();
133
410
  });
134
- await specPopover.determinePopDirection();
135
- expect(containerElement.style.getPropertyValue('--comp-pop-max-height')).toBe('700px');
136
- expect(specPopover.currentDirection).toBe('down');
137
- controlSpy.mockRestore();
138
411
  });
139
- it('sets the direction to up when control element has more space above it', async () => {
140
- const controlSpy = jest.spyOn(controlElement, 'getBoundingClientRect').mockReturnValue({
141
- top: 600,
142
- bottom: 650,
412
+ describe('supportsPopoverAPI', () => {
413
+ it('returns false when Popover API is not supported', async () => {
414
+ specPopover = new Q2Popover();
415
+ expect(specPopover.supportsPopoverAPI).toBe(false);
416
+ });
417
+ it('returns true when Popover API is supported', async () => {
418
+ enablePopoverAPI();
419
+ specPopover = new Q2Popover();
420
+ expect(specPopover.supportsPopoverAPI).toBe(true);
143
421
  });
144
- await specPopover.determinePopDirection();
145
- expect(containerElement.style.getPropertyValue('--comp-pop-max-height')).toBe('590px');
146
- expect(specPopover.currentDirection).toBe('up');
147
- controlSpy.mockRestore();
148
422
  });
149
- describe('when the outletOffset is less than 0', () => {
423
+ });
424
+ describe('Methods', () => {
425
+ describe('addViewPortListeners', () => {
426
+ let specPopover;
427
+ let windowAddEventListenerSpy;
428
+ let visualViewportAddEventListenerSpy;
429
+ let screenOrientationAddEventListenerSpy;
150
430
  beforeEach(() => {
151
- window.Tecton = Object.assign(Object.assign({}, sampleTectonWindow), { platformDimensions: Object.assign(Object.assign({}, samplePlatformDimensions), { outletOffset: -50 }) });
431
+ windowAddEventListenerSpy = jest.spyOn(window, 'addEventListener');
432
+ // Mock visualViewport
433
+ const mockVisualViewport = {
434
+ addEventListener: jest.fn(),
435
+ removeEventListener: jest.fn(),
436
+ width: 800,
437
+ height: 600,
438
+ };
439
+ Object.defineProperty(window, 'visualViewport', {
440
+ value: mockVisualViewport,
441
+ configurable: true,
442
+ });
443
+ global.visualViewport = mockVisualViewport;
444
+ visualViewportAddEventListenerSpy = jest.spyOn(mockVisualViewport, 'addEventListener');
445
+ // Mock screen.orientation
446
+ const mockScreenOrientation = {
447
+ addEventListener: jest.fn(),
448
+ removeEventListener: jest.fn(),
449
+ };
450
+ const mockScreen = { orientation: mockScreenOrientation };
451
+ Object.defineProperty(window, 'screen', {
452
+ value: mockScreen,
453
+ configurable: true,
454
+ });
455
+ global.screen = mockScreen;
456
+ screenOrientationAddEventListenerSpy = jest.spyOn(mockScreenOrientation, 'addEventListener');
457
+ specPopover = new Q2Popover();
152
458
  });
153
- it('sets the direction to down when control element has more space below it', async () => {
154
- const controlSpy = jest.spyOn(controlElement, 'getBoundingClientRect').mockReturnValue({
155
- top: 20,
156
- bottom: 70,
459
+ afterEach(() => {
460
+ windowAddEventListenerSpy.mockRestore();
461
+ visualViewportAddEventListenerSpy.mockRestore();
462
+ screenOrientationAddEventListenerSpy.mockRestore();
463
+ delete global.visualViewport;
464
+ delete global.screen;
465
+ delete window.visualViewport;
466
+ delete window.screen;
467
+ });
468
+ describe('resize', () => {
469
+ it('adds resize listener to window with viewPortOrientationChanged handler', async () => {
470
+ specPopover.addViewportListeners();
471
+ expect(windowAddEventListenerSpy).toHaveBeenCalledWith('resize', specPopover.viewPortOrientationChanged);
157
472
  });
158
- await specPopover.determinePopDirection();
159
- expect(containerElement.style.getPropertyValue('--comp-pop-max-height')).toBe('770px');
160
- expect(specPopover.currentDirection).toBe('down');
161
- controlSpy.mockRestore();
162
- });
163
- it('sets the direction to up when control element has more space above it', async () => {
164
- const controlSpy = jest.spyOn(controlElement, 'getBoundingClientRect').mockReturnValue({
165
- top: 600,
166
- bottom: 650,
473
+ it('adds resize listener to visualViewport with viewPortChanged handler', async () => {
474
+ specPopover.addViewportListeners();
475
+ expect(visualViewportAddEventListenerSpy).toHaveBeenCalledWith('resize', specPopover.viewPortChanged);
476
+ });
477
+ });
478
+ describe('scroll', () => {
479
+ it('adds scroll listener to window when in scrollable container on desktop only', async () => {
480
+ jest.spyOn(utils, 'isInScrollableContainer').mockReturnValue(true);
481
+ jest.spyOn(utils, 'isMobile').mockReturnValue(false);
482
+ specPopover.addViewportListeners();
483
+ expect(windowAddEventListenerSpy).toHaveBeenCalledWith('scroll', specPopover.viewPortChanged, {
484
+ passive: true,
485
+ capture: true,
486
+ });
487
+ });
488
+ it('does not add scroll listener on mobile', async () => {
489
+ jest.spyOn(utils, 'isInScrollableContainer').mockReturnValue(true);
490
+ jest.spyOn(utils, 'isMobile').mockReturnValue(true);
491
+ specPopover.addViewportListeners();
492
+ expect(windowAddEventListenerSpy).not.toHaveBeenCalledWith('scroll', specPopover.viewPortChanged, {
493
+ passive: true,
494
+ capture: true,
495
+ });
496
+ });
497
+ it('does not add scroll listener in non-scrollable container', async () => {
498
+ jest.spyOn(utils, 'isInScrollableContainer').mockReturnValue(false);
499
+ jest.spyOn(utils, 'isMobile').mockReturnValue(false);
500
+ specPopover.addViewportListeners();
501
+ expect(windowAddEventListenerSpy).not.toHaveBeenCalledWith('scroll', specPopover.viewPortChanged, {
502
+ passive: true,
503
+ capture: true,
504
+ });
167
505
  });
168
- await specPopover.determinePopDirection();
169
- expect(containerElement.style.getPropertyValue('--comp-pop-max-height')).toBe('540px');
170
- expect(specPopover.currentDirection).toBe('up');
171
- controlSpy.mockRestore();
506
+ });
507
+ describe('orientationchange', () => {
508
+ it('adds orientationchange listener to screen.orientation with viewPortOrientationChanged handler', async () => {
509
+ specPopover.addViewportListeners();
510
+ expect(screenOrientationAddEventListenerSpy).toHaveBeenCalledWith('orientationchange', specPopover.viewPortOrientationChanged);
511
+ });
512
+ it('adds orientationchange listener to window with viewPortOrientationChanged handler', async () => {
513
+ specPopover.addViewportListeners();
514
+ expect(windowAddEventListenerSpy).toHaveBeenCalledWith('orientationchange', specPopover.viewPortOrientationChanged);
515
+ });
516
+ });
517
+ it('adds all expected listeners when called', async () => {
518
+ specPopover.addViewportListeners();
519
+ expect(windowAddEventListenerSpy).toHaveBeenCalled();
520
+ expect(visualViewportAddEventListenerSpy).toHaveBeenCalled();
521
+ expect(screenOrientationAddEventListenerSpy).toHaveBeenCalled();
172
522
  });
173
523
  });
174
- });
175
- describe("when the module is shorter than the window's viewport", () => {
176
- beforeEach(() => {
177
- specPopover.open = true;
178
- window.visualViewport = { height: 600 };
524
+ describe('clearCSSProperties', () => {
525
+ let specPopover;
526
+ let containerElement;
527
+ beforeEach(() => {
528
+ specPopover = new Q2Popover();
529
+ containerElement = document.createElement('div');
530
+ containerElement.style.setProperty('--comp-pop-max-height', '100px');
531
+ containerElement.style.setProperty('--comp-pop-top', '20px');
532
+ containerElement.style.setProperty('--comp-pop-bottom', '25px');
533
+ containerElement.style.setProperty('--comp-pop-left', '30px');
534
+ containerElement.style.setProperty('--comp-pop-right', '35px');
535
+ containerElement.style.setProperty('--comp-pop-width', '200px');
536
+ containerElement.style.setProperty('--comp-pop-opacity', '1');
537
+ specPopover.containerElement = containerElement;
538
+ });
539
+ it('clears the necessary CSS properties', async () => {
540
+ await specPopover.clearCSSProperties();
541
+ expect(containerElement.style.getPropertyValue('--comp-pop-max-height')).toBeFalsy();
542
+ expect(containerElement.style.getPropertyValue('--comp-pop-top')).toBeFalsy();
543
+ expect(containerElement.style.getPropertyValue('--comp-pop-bottom')).toBeFalsy();
544
+ expect(containerElement.style.getPropertyValue('--comp-pop-left')).toBeFalsy();
545
+ expect(containerElement.style.getPropertyValue('--comp-pop-right')).toBeFalsy();
546
+ expect(containerElement.style.getPropertyValue('--comp-pop-width')).toBeFalsy();
547
+ expect(containerElement.style.getPropertyValue('--comp-pop-opacity')).toBeFalsy();
548
+ });
179
549
  });
180
- it('sets the direction to down when control element has more space below it', async () => {
181
- const controlSpy = jest.spyOn(controlElement, 'getBoundingClientRect').mockReturnValue({
182
- top: 20,
183
- bottom: 70,
550
+ describe('determinePopDirection', () => {
551
+ let specPopover;
552
+ let controlElement;
553
+ let containerElement;
554
+ beforeEach(async () => {
555
+ specPopover = new Q2Popover();
556
+ specPopover.setDirectionAndShow = jest.fn();
557
+ controlElement = document.createElement('div');
558
+ specPopover.controlElement = controlElement;
559
+ containerElement = document.createElement('div');
560
+ specPopover.containerElement = containerElement;
561
+ });
562
+ afterEach(() => {
563
+ delete window.visualViewport;
564
+ delete window.Tecton;
565
+ delete window.innerHeight;
566
+ });
567
+ describe('when in a module', () => {
568
+ beforeEach(async () => {
569
+ window.Tecton = sampleTectonWindow;
570
+ jest.spyOn(window, 'top', 'get').mockReturnValue({});
571
+ specPopover.open = true;
572
+ expect(specPopover.isModule).toBe(true);
573
+ });
574
+ describe("when the module is taller than the window's viewport", () => {
575
+ beforeEach(() => {
576
+ window.innerHeight = 1200;
577
+ });
578
+ it('sets the direction to down when control element has more space below it', async () => {
579
+ jest.spyOn(controlElement, 'getBoundingClientRect').mockReturnValue({
580
+ top: 20,
581
+ bottom: 70,
582
+ });
583
+ await specPopover.determinePopDirection();
584
+ expect(containerElement.style.getPropertyValue('--comp-pop-max-height')).toBe('700px');
585
+ expect(specPopover.setDirectionAndShow).toHaveBeenCalledWith('down');
586
+ });
587
+ it('sets the direction to up when control element has more space above it', async () => {
588
+ jest.spyOn(controlElement, 'getBoundingClientRect').mockReturnValue({
589
+ top: 600,
590
+ bottom: 650,
591
+ });
592
+ await specPopover.determinePopDirection();
593
+ expect(containerElement.style.getPropertyValue('--comp-pop-max-height')).toBe('590px');
594
+ expect(specPopover.setDirectionAndShow).toHaveBeenCalledWith('up');
595
+ });
596
+ describe('when the outletOffset is 0 or less', () => {
597
+ beforeEach(() => {
598
+ window.Tecton = Object.assign(Object.assign({}, sampleTectonWindow), { platformDimensions: Object.assign(Object.assign({}, samplePlatformDimensions), { outletOffset: -50 }) });
599
+ });
600
+ it('sets the direction to down when control element has more space below it', async () => {
601
+ jest.spyOn(controlElement, 'getBoundingClientRect').mockReturnValue({
602
+ top: 20,
603
+ bottom: 70,
604
+ });
605
+ await specPopover.determinePopDirection();
606
+ expect(containerElement.style.getPropertyValue('--comp-pop-max-height')).toBe('770px');
607
+ expect(specPopover.setDirectionAndShow).toHaveBeenCalledWith('down');
608
+ });
609
+ it('sets the direction to up when control element has more space above it', async () => {
610
+ jest.spyOn(controlElement, 'getBoundingClientRect').mockReturnValue({
611
+ top: 600,
612
+ bottom: 650,
613
+ });
614
+ await specPopover.determinePopDirection();
615
+ expect(containerElement.style.getPropertyValue('--comp-pop-max-height')).toBe('540px');
616
+ expect(specPopover.setDirectionAndShow).toHaveBeenCalledWith('up');
617
+ });
618
+ });
619
+ describe('when the "top" platformDimension has a value', () => {
620
+ beforeEach(() => {
621
+ window.Tecton = Object.assign(Object.assign({}, sampleTectonWindow), { platformDimensions: Object.assign(Object.assign({}, samplePlatformDimensions), { outletOffset: 0, top: 50 }) });
622
+ });
623
+ it('takes the "top" into account when opening up', async () => {
624
+ jest.spyOn(controlElement, 'getBoundingClientRect').mockReturnValue({
625
+ top: 600,
626
+ bottom: 650,
627
+ });
628
+ await specPopover.determinePopDirection();
629
+ expect(containerElement.style.getPropertyValue('--comp-pop-max-height')).toBe('540px');
630
+ expect(specPopover.setDirectionAndShow).toHaveBeenCalledWith('up');
631
+ });
632
+ it('ignores "top" when outletOffset is positive', async () => {
633
+ window.Tecton = Object.assign(Object.assign({}, sampleTectonWindow), { platformDimensions: Object.assign(Object.assign({}, samplePlatformDimensions), { outletOffset: 20 }) });
634
+ jest.spyOn(controlElement, 'getBoundingClientRect').mockReturnValue({
635
+ top: 600,
636
+ bottom: 650,
637
+ });
638
+ await specPopover.determinePopDirection();
639
+ expect(containerElement.style.getPropertyValue('--comp-pop-max-height')).toBe('590px');
640
+ expect(specPopover.setDirectionAndShow).toHaveBeenCalledWith('up');
641
+ });
642
+ });
643
+ describe('when the "bottom" platformDimension has a value', () => {
644
+ it('takes "bottom" into account when calculating space below', async () => {
645
+ window.Tecton = Object.assign(Object.assign({}, sampleTectonWindow), { platformDimensions: Object.assign(Object.assign({}, samplePlatformDimensions), { bottom: 50 }) });
646
+ jest.spyOn(controlElement, 'getBoundingClientRect').mockReturnValue({
647
+ top: 20,
648
+ bottom: 70,
649
+ });
650
+ await specPopover.determinePopDirection();
651
+ expect(containerElement.style.getPropertyValue('--comp-pop-max-height')).toBe('650px');
652
+ expect(specPopover.setDirectionAndShow).toHaveBeenCalledWith('down');
653
+ });
654
+ });
655
+ });
656
+ describe("when the module is shorter than the window's viewport", () => {
657
+ beforeEach(() => {
658
+ window.innerHeight = 600;
659
+ });
660
+ it('sets the direction to down when control element has more space below it', async () => {
661
+ jest.spyOn(controlElement, 'getBoundingClientRect').mockReturnValue({
662
+ top: 20,
663
+ bottom: 70,
664
+ });
665
+ await specPopover.determinePopDirection();
666
+ expect(containerElement.style.getPropertyValue('--comp-pop-max-height')).toBe('520px');
667
+ expect(specPopover.setDirectionAndShow).toHaveBeenCalledWith('down');
668
+ });
669
+ it('sets the direction to up when control element has more space above it', async () => {
670
+ jest.spyOn(controlElement, 'getBoundingClientRect').mockReturnValue({
671
+ top: 500,
672
+ bottom: 550,
673
+ });
674
+ await specPopover.determinePopDirection();
675
+ expect(containerElement.style.getPropertyValue('--comp-pop-max-height')).toBe('490px');
676
+ expect(specPopover.setDirectionAndShow).toHaveBeenCalledWith('up');
677
+ });
678
+ });
679
+ });
680
+ describe('when at the platform level', () => {
681
+ beforeEach(async () => {
682
+ window.innerHeight = 600;
683
+ expect(specPopover.isModule).toBe(false);
684
+ });
685
+ it('sets the direction to up when control element has more space above it', async () => {
686
+ const controlSpy = jest.spyOn(controlElement, 'getBoundingClientRect').mockReturnValue({
687
+ top: 500,
688
+ bottom: 550,
689
+ });
690
+ await specPopover.determinePopDirection();
691
+ expect(containerElement.style.getPropertyValue('--comp-pop-max-height')).toBe('490px');
692
+ expect(specPopover.setDirectionAndShow).toHaveBeenCalledWith('up');
693
+ controlSpy.mockRestore();
694
+ });
695
+ it('sets the direction to down when control element has more space below it', async () => {
696
+ const controlSpy = jest.spyOn(controlElement, 'getBoundingClientRect').mockReturnValue({
697
+ top: 100,
698
+ bottom: 150,
699
+ });
700
+ await specPopover.determinePopDirection();
701
+ expect(containerElement.style.getPropertyValue('--comp-pop-max-height')).toBe('440px');
702
+ expect(specPopover.setDirectionAndShow).toHaveBeenCalledWith('down');
703
+ controlSpy.mockRestore();
704
+ });
184
705
  });
185
- await specPopover.determinePopDirection();
186
- expect(containerElement.style.getPropertyValue('--comp-pop-max-height')).toBe('520px');
187
- expect(specPopover.currentDirection).toBe('down');
188
- controlSpy.mockRestore();
189
706
  });
190
- it('sets the direction to up when control element has more space above it', async () => {
191
- const controlSpy = jest.spyOn(controlElement, 'getBoundingClientRect').mockReturnValue({
192
- top: 500,
193
- bottom: 550,
707
+ describe('handleMinHeight', () => {
708
+ it('calls handleDeprecationWarning for minHeight', async () => {
709
+ specPopover = new Q2Popover();
710
+ const mockHandleDeprecation = jest
711
+ .spyOn(utils, 'handleDeprecationWarning')
712
+ .mockImplementation(() => { });
713
+ specPopover.minHeight = 100;
714
+ specPopover.handleMinHeight();
715
+ expect(mockHandleDeprecation).toHaveBeenCalled();
194
716
  });
195
- await specPopover.determinePopDirection();
196
- expect(containerElement.style.getPropertyValue('--comp-pop-max-height')).toBe('490px');
197
- expect(specPopover.currentDirection).toBe('up');
198
- controlSpy.mockRestore();
199
717
  });
200
- });
201
- });
202
- describe('viewPortChanged', () => {
203
- let specPopover;
204
- let windowSpy;
205
- beforeEach(() => {
206
- specPopover = new Q2Popover();
207
- windowSpy = jest.spyOn(window, 'top', 'get').mockReturnValue({});
208
- window.Tecton = sampleTectonWindow;
209
- expect(specPopover.isModule).toBe(true);
210
- specPopover.determinePopDirection = jest.fn();
211
- });
212
- afterEach(() => {
213
- windowSpy.mockRestore();
214
- });
215
- it('calls determinePopDirection when open is true', async () => {
216
- specPopover.open = true;
217
- await specPopover.viewPortChanged();
218
- expect(specPopover.determinePopDirection).toHaveBeenCalled();
219
- });
220
- it('does nothing when open is false', async () => {
221
- specPopover.open = false;
222
- await specPopover.viewPortChanged();
223
- expect(specPopover.determinePopDirection).not.toHaveBeenCalled();
224
- });
225
- });
226
- describe('viewPortOrientationChanged', () => {
227
- let specPopover;
228
- beforeEach(() => {
229
- specPopover = new Q2Popover();
230
- specPopover.viewPortChanged = jest.fn();
231
- });
232
- it('sets orientationChanged to true and calls viewportChanged', async () => {
233
- await specPopover.viewPortOrientationChanged();
234
- expect(specPopover.orientationChanged).toBe(true);
235
- expect(specPopover.viewPortChanged).toHaveBeenCalled();
236
- });
237
- });
238
- describe('setFixedCSSProperties', () => {
239
- let specPopover;
240
- let containerElement;
241
- beforeEach(() => {
242
- window.visualViewport = { width: 800, height: 600 };
243
- specPopover = new Q2Popover();
244
- containerElement = document.createElement('div');
245
- specPopover.containerElement = containerElement;
246
- specPopover.rootElementRect = {
247
- top: 0,
248
- bottom: 0,
249
- left: 0,
250
- right: 0,
251
- height: window.visualViewport.height,
252
- width: window.visualViewport.width,
253
- };
254
- const controlElement = document.createElement('div');
255
- controlElement.getBoundingClientRect = jest.fn().mockReturnValue({
256
- top: 20,
257
- bottom: 70,
258
- left: 30,
259
- right: 80,
260
- });
261
- specPopover.controlElement = controlElement;
262
- });
263
- it('sets the necessary CSS properties', async () => {
264
- await specPopover.setFixedCSSProperties();
265
- expect(containerElement.style.getPropertyValue('--comp-pop-max-height')).toBeFalsy();
266
- expect(containerElement.style.getPropertyValue('--comp-pop-top')).toBeFalsy();
267
- expect(containerElement.style.getPropertyValue('--comp-pop-bottom')).toBeFalsy();
268
- expect(containerElement.style.getPropertyValue('--comp-pop-left')).toBe('30px');
269
- expect(containerElement.style.getPropertyValue('--comp-pop-right')).toBe('720px');
270
- expect(containerElement.style.getPropertyValue('--comp-pop-width')).toBeFalsy();
271
- expect(containerElement.style.getPropertyValue('--comp-pop-opacity')).toBe('1');
272
- });
273
- it('sets --comp-pop-bottom when direction is up', async () => {
274
- specPopover.currentDirection = 'up';
275
- await specPopover.setFixedCSSProperties();
276
- expect(containerElement.style.getPropertyValue('--comp-pop-top')).toBeFalsy();
277
- expect(containerElement.style.getPropertyValue('--comp-pop-bottom')).toBe('580px');
278
- });
279
- it('sets --comp-pop-top when direction is down', async () => {
280
- specPopover.currentDirection = 'down';
281
- await specPopover.setFixedCSSProperties();
282
- expect(containerElement.style.getPropertyValue('--comp-pop-top')).toBe('70px');
283
- expect(containerElement.style.getPropertyValue('--comp-pop-bottom')).toBeFalsy();
284
- });
285
- it('sets --comp-pop-width when block is true', async () => {
286
- specPopover.block = true;
287
- await specPopover.setFixedCSSProperties();
288
- expect(containerElement.style.getPropertyValue('--comp-pop-width')).toBe('0px');
289
- });
290
- describe('when rootElementRect is bonkers', () => {
291
- beforeEach(() => {
292
- specPopover.rootElementRect = {
293
- top: 50,
294
- bottom: 650,
295
- left: 50,
296
- right: 750,
297
- height: 600,
298
- width: 700,
299
- };
300
- const controlElement = document.createElement('div');
301
- controlElement.getBoundingClientRect = jest.fn().mockReturnValue({
302
- top: 70,
303
- bottom: 120,
304
- left: 80,
305
- right: 130,
306
- });
307
- specPopover.controlElement = controlElement;
308
- });
309
- it('sets the necessary CSS properties', async () => {
310
- await specPopover.setFixedCSSProperties();
311
- expect(containerElement.style.getPropertyValue('--comp-pop-max-height')).toBeFalsy();
312
- expect(containerElement.style.getPropertyValue('--comp-pop-top')).toBeFalsy();
313
- expect(containerElement.style.getPropertyValue('--comp-pop-bottom')).toBeFalsy();
314
- expect(containerElement.style.getPropertyValue('--comp-pop-left')).toBe('30px');
315
- expect(containerElement.style.getPropertyValue('--comp-pop-right')).toBe('620px');
316
- expect(containerElement.style.getPropertyValue('--comp-pop-width')).toBeFalsy();
317
- expect(containerElement.style.getPropertyValue('--comp-pop-opacity')).toBe('1');
318
- });
319
- it('sets --comp-pop-bottom when direction is up', async () => {
320
- specPopover.currentDirection = 'up';
321
- await specPopover.setFixedCSSProperties();
322
- expect(containerElement.style.getPropertyValue('--comp-pop-top')).toBeFalsy();
323
- expect(containerElement.style.getPropertyValue('--comp-pop-bottom')).toBe('580px');
324
- });
325
- it('sets --comp-pop-top when direction is down', async () => {
326
- specPopover.currentDirection = 'down';
327
- await specPopover.setFixedCSSProperties();
328
- expect(containerElement.style.getPropertyValue('--comp-pop-top')).toBe('70px');
329
- expect(containerElement.style.getPropertyValue('--comp-pop-bottom')).toBeFalsy();
330
- });
331
- it('sets --comp-pop-width when block is true', async () => {
332
- specPopover.block = true;
333
- await specPopover.setFixedCSSProperties();
334
- expect(containerElement.style.getPropertyValue('--comp-pop-width')).toBe('0px');
718
+ describe('handlePopoverToggleEvent', () => {
719
+ it('emits the popoverStateChanged event', async () => {
720
+ specPopover = new Q2Popover();
721
+ const mockEmit = jest.spyOn(specPopover.popoverStateChanged, 'emit');
722
+ specPopover.handlePopoverToggleEvent({});
723
+ expect(mockEmit).toHaveBeenCalled();
724
+ });
725
+ describe('when the newState from the ToggleEvent is "open"', () => {
726
+ it('emits the popoverStateChanged event open as true', async () => {
727
+ specPopover = new Q2Popover();
728
+ const mockEmit = jest.spyOn(specPopover.popoverStateChanged, 'emit');
729
+ specPopover.handlePopoverToggleEvent({ newState: 'open' });
730
+ expect(mockEmit).toHaveBeenCalledWith({ open: true });
731
+ });
732
+ });
733
+ describe('when the newState from the ToggleEvent is "closed"', () => {
734
+ it('emits the popoverStateChanged event open as false', async () => {
735
+ specPopover = new Q2Popover();
736
+ const mockEmit = jest.spyOn(specPopover.popoverStateChanged, 'emit');
737
+ specPopover.handlePopoverToggleEvent({ newState: 'closed' });
738
+ expect(mockEmit).toHaveBeenCalledWith({ open: false });
739
+ });
740
+ });
335
741
  });
336
- });
337
- });
338
- describe('setAbsoluteCSSProperties', () => {
339
- let specPopover;
340
- let containerElement;
341
- beforeEach(() => {
342
- specPopover = new Q2Popover();
343
- containerElement = document.createElement('div');
344
- specPopover.mode = 'legacy';
345
- specPopover.containerElement = containerElement;
346
- const controlElement = document.createElement('div');
347
- controlElement.getBoundingClientRect = jest.fn().mockReturnValue({
348
- top: 20,
349
- bottom: 70,
350
- left: 30,
351
- right: 80,
352
- });
353
- specPopover.controlElement = controlElement;
354
- window.visualViewport = { width: 800, height: 600 };
355
- });
356
- it('sets the necessary CSS properties', async () => {
357
- await specPopover.setAbsoluteCSSProperties();
358
- expect(containerElement.style.getPropertyValue('--comp-pop-max-height')).toBeFalsy();
359
- expect(containerElement.style.getPropertyValue('--comp-pop-top')).toBeFalsy();
360
- expect(containerElement.style.getPropertyValue('--comp-pop-bottom')).toBeFalsy();
361
- expect(containerElement.style.getPropertyValue('--comp-pop-left')).toBe('0');
362
- expect(containerElement.style.getPropertyValue('--comp-pop-right')).toBe('unset');
363
- expect(containerElement.style.getPropertyValue('--comp-pop-width')).toBe('');
364
- expect(containerElement.style.getPropertyValue('--comp-pop-opacity')).toBe('1');
365
- });
366
- it('sets the necessary CSS properties when align is right', async () => {
367
- specPopover.align = 'right';
368
- await specPopover.setAbsoluteCSSProperties();
369
- expect(containerElement.style.getPropertyValue('--comp-pop-left')).toBe('unset');
370
- expect(containerElement.style.getPropertyValue('--comp-pop-right')).toBe('0');
371
- });
372
- it('sets --comp-pop-bottom when direction is up', async () => {
373
- specPopover.currentDirection = 'up';
374
- await specPopover.setAbsoluteCSSProperties();
375
- expect(containerElement.style.getPropertyValue('--comp-pop-top')).toBeFalsy();
376
- expect(containerElement.style.getPropertyValue('--comp-pop-bottom')).toBe('0px');
377
- });
378
- it('does not set --comp-pop-top when direction is down', async () => {
379
- specPopover.currentDirection = 'down';
380
- await specPopover.setAbsoluteCSSProperties();
381
- expect(containerElement.style.getPropertyValue('--comp-pop-top')).toBe('');
382
- expect(containerElement.style.getPropertyValue('--comp-pop-bottom')).toBe('');
383
- });
384
- it('sets --comp-pop-width when block is true', async () => {
385
- specPopover.block = true;
386
- await specPopover.setAbsoluteCSSProperties();
387
- expect(containerElement.style.getPropertyValue('--comp-pop-width')).toBe('100%');
388
- });
389
- });
390
- describe('clearCSSProperties', () => {
391
- let specPopover;
392
- let containerElement;
393
- beforeEach(() => {
394
- specPopover = new Q2Popover();
395
- containerElement = document.createElement('div');
396
- containerElement.style.setProperty('--comp-pop-max-height', '100px');
397
- containerElement.style.setProperty('--comp-pop-top', '20px');
398
- containerElement.style.setProperty('--comp-pop-bottom', '25px');
399
- containerElement.style.setProperty('--comp-pop-left', '30px');
400
- containerElement.style.setProperty('--comp-pop-right', '35px');
401
- containerElement.style.setProperty('--comp-pop-width', '200px');
402
- containerElement.style.setProperty('--comp-pop-opacity', '1');
403
- specPopover.containerElement = containerElement;
404
- });
405
- it('clears the necessary CSS properties', async () => {
406
- await specPopover.clearCSSProperties();
407
- expect(containerElement.style.getPropertyValue('--comp-pop-max-height')).toBeFalsy();
408
- expect(containerElement.style.getPropertyValue('--comp-pop-top')).toBeFalsy();
409
- expect(containerElement.style.getPropertyValue('--comp-pop-bottom')).toBeFalsy();
410
- expect(containerElement.style.getPropertyValue('--comp-pop-left')).toBeFalsy();
411
- expect(containerElement.style.getPropertyValue('--comp-pop-right')).toBeFalsy();
412
- expect(containerElement.style.getPropertyValue('--comp-pop-width')).toBeFalsy();
413
- expect(containerElement.style.getPropertyValue('--comp-pop-opacity')).toBeFalsy();
414
- });
415
- });
416
- describe('setDirectionAndShow', () => {
417
- let specPopover;
418
- let containerElement;
419
- beforeEach(() => {
420
- specPopover = new Q2Popover();
421
- containerElement = document.createElement('div');
422
- specPopover.containerElement = containerElement;
423
- specPopover.setRootElement = jest.fn();
424
- specPopover.setFixedCSSProperties = jest.fn();
425
- specPopover.setAbsoluteCSSProperties = jest.fn();
426
- specPopover.scrollContainerTo = jest.fn();
427
- });
428
- it('does nothing when open is false', async () => {
429
- specPopover.open = false;
430
- await specPopover.setDirectionAndShow('up');
431
- expect(specPopover.currentDirection).toBeUndefined();
432
- expect(specPopover.show).toBe(false);
433
- expect(specPopover.setRootElement).toHaveBeenCalled();
434
- expect(specPopover.setFixedCSSProperties).not.toHaveBeenCalled();
435
- expect(specPopover.setAbsoluteCSSProperties).not.toHaveBeenCalled();
436
- });
437
- describe('when open is true', () => {
438
- beforeEach(() => {
439
- specPopover.open = true;
742
+ describe('removeViewportListeners', () => {
743
+ let specPopover;
744
+ let windowRemoveEventListenerSpy;
745
+ let visualViewportRemoveEventListenerSpy;
746
+ let screenOrientationRemoveEventListenerSpy;
747
+ beforeEach(() => {
748
+ specPopover = new Q2Popover();
749
+ windowRemoveEventListenerSpy = jest.spyOn(window, 'removeEventListener');
750
+ // Mock visualViewport
751
+ const mockVisualViewport = {
752
+ removeEventListener: jest.fn(),
753
+ };
754
+ Object.defineProperty(window, 'visualViewport', {
755
+ value: mockVisualViewport,
756
+ configurable: true,
757
+ });
758
+ global.visualViewport = mockVisualViewport;
759
+ visualViewportRemoveEventListenerSpy = jest.spyOn(mockVisualViewport, 'removeEventListener');
760
+ // Mock screen.orientation
761
+ const mockScreenOrientation = {
762
+ removeEventListener: jest.fn(),
763
+ };
764
+ const mockScreen = { orientation: mockScreenOrientation };
765
+ Object.defineProperty(window, 'screen', {
766
+ value: mockScreen,
767
+ configurable: true,
768
+ });
769
+ global.screen = mockScreen;
770
+ screenOrientationRemoveEventListenerSpy = jest.spyOn(mockScreenOrientation, 'removeEventListener');
771
+ });
772
+ afterEach(() => {
773
+ windowRemoveEventListenerSpy.mockRestore();
774
+ visualViewportRemoveEventListenerSpy.mockRestore();
775
+ screenOrientationRemoveEventListenerSpy.mockRestore();
776
+ delete global.visualViewport;
777
+ delete global.screen;
778
+ delete window.visualViewport;
779
+ delete window.screen;
780
+ });
781
+ it('removes resize listener from window with viewPortOrientationChanged handler', async () => {
782
+ specPopover.removeViewportListeners();
783
+ expect(windowRemoveEventListenerSpy).toHaveBeenCalledWith('resize', specPopover.viewPortOrientationChanged);
784
+ });
785
+ it('removes resize listener from visualViewport with viewPortChanged handler', async () => {
786
+ specPopover.removeViewportListeners();
787
+ expect(visualViewportRemoveEventListenerSpy).toHaveBeenCalledWith('resize', specPopover.viewPortChanged);
788
+ });
789
+ it('removes scroll listener from window with viewPortChanged handler and proper options', async () => {
790
+ specPopover.removeViewportListeners();
791
+ expect(windowRemoveEventListenerSpy).toHaveBeenNthCalledWith(2, 'scroll', specPopover.viewPortChanged, { capture: true });
792
+ });
793
+ it('removes orientationchange listener from screen.orientation with viewPortOrientationChanged handler', async () => {
794
+ specPopover.removeViewportListeners();
795
+ expect(screenOrientationRemoveEventListenerSpy).toHaveBeenCalledWith('orientationchange', specPopover.viewPortOrientationChanged);
796
+ });
797
+ it('removes orientationchange listener from window with viewPortOrientationChanged handler', async () => {
798
+ specPopover.removeViewportListeners();
799
+ expect(windowRemoveEventListenerSpy).toHaveBeenCalledWith('orientationchange', specPopover.viewPortOrientationChanged);
800
+ });
440
801
  });
441
- it('sets the direction, shows the popover, and sets fixed position properties', async () => {
442
- await specPopover.setDirectionAndShow('up');
443
- expect(specPopover.currentDirection).toBe('up');
444
- expect(specPopover.show).toBe(true);
445
- expect(specPopover.setRootElement).toHaveBeenCalled();
446
- expect(specPopover.setFixedCSSProperties).toHaveBeenCalled();
447
- expect(specPopover.setAbsoluteCSSProperties).not.toHaveBeenCalled();
448
- });
449
- it('sets the direction, shows the popover, and sets absolute position properties when mode is "legacy"', async () => {
450
- specPopover.mode = 'legacy';
451
- await specPopover.setDirectionAndShow('up');
452
- expect(specPopover.currentDirection).toBe('up');
453
- expect(specPopover.show).toBe(true);
454
- expect(specPopover.setRootElement).toHaveBeenCalled();
455
- expect(specPopover.setFixedCSSProperties).not.toHaveBeenCalled();
456
- expect(specPopover.setAbsoluteCSSProperties).toHaveBeenCalled();
802
+ describe('setAbsoluteCSSProperties', () => {
803
+ let specPopover;
804
+ let containerElement;
805
+ beforeEach(() => {
806
+ specPopover = new Q2Popover();
807
+ containerElement = document.createElement('div');
808
+ specPopover.mode = 'legacy';
809
+ specPopover.containerElement = containerElement;
810
+ const controlElement = document.createElement('div');
811
+ controlElement.getBoundingClientRect = jest.fn().mockReturnValue({
812
+ top: 20,
813
+ bottom: 70,
814
+ left: 30,
815
+ right: 80,
816
+ });
817
+ specPopover.controlElement = controlElement;
818
+ window.visualViewport = { width: 800, height: 600 };
819
+ });
820
+ it('sets the necessary CSS properties', async () => {
821
+ await specPopover.setAbsoluteCSSProperties();
822
+ expect(containerElement.style.getPropertyValue('--comp-pop-max-height')).toBeFalsy();
823
+ expect(containerElement.style.getPropertyValue('--comp-pop-top')).toBeFalsy();
824
+ expect(containerElement.style.getPropertyValue('--comp-pop-bottom')).toBeFalsy();
825
+ expect(containerElement.style.getPropertyValue('--comp-pop-left')).toBe('0');
826
+ expect(containerElement.style.getPropertyValue('--comp-pop-right')).toBe('unset');
827
+ expect(containerElement.style.getPropertyValue('--comp-pop-width')).toBe('');
828
+ expect(containerElement.style.getPropertyValue('--comp-pop-opacity')).toBe('1');
829
+ });
830
+ it('sets the necessary CSS properties when align is right', async () => {
831
+ specPopover.align = 'right';
832
+ await specPopover.setAbsoluteCSSProperties();
833
+ expect(containerElement.style.getPropertyValue('--comp-pop-left')).toBe('unset');
834
+ expect(containerElement.style.getPropertyValue('--comp-pop-right')).toBe('0');
835
+ });
836
+ it('sets --comp-pop-bottom when direction is up', async () => {
837
+ specPopover.currentDirection = 'up';
838
+ await specPopover.setAbsoluteCSSProperties();
839
+ expect(containerElement.style.getPropertyValue('--comp-pop-top')).toBeFalsy();
840
+ expect(containerElement.style.getPropertyValue('--comp-pop-bottom')).toBe('0px');
841
+ });
842
+ it('does not set --comp-pop-top when direction is down', async () => {
843
+ specPopover.currentDirection = 'down';
844
+ await specPopover.setAbsoluteCSSProperties();
845
+ expect(containerElement.style.getPropertyValue('--comp-pop-top')).toBe('');
846
+ expect(containerElement.style.getPropertyValue('--comp-pop-bottom')).toBe('');
847
+ });
848
+ it('sets --comp-pop-width when block is true', async () => {
849
+ specPopover.block = true;
850
+ await specPopover.setAbsoluteCSSProperties();
851
+ expect(containerElement.style.getPropertyValue('--comp-pop-width')).toBe('100%');
852
+ });
457
853
  });
458
- });
459
- });
460
- describe('determinePopDirection', () => {
461
- let specPopover;
462
- let controlElement;
463
- let containerElement;
464
- beforeEach(() => {
465
- specPopover = new Q2Popover();
466
- controlElement = document.createElement('div');
467
- containerElement = document.createElement('div');
468
- specPopover.controlElement = controlElement;
469
- specPopover.containerElement = containerElement;
470
- window.visualViewport = { width: 800, height: 600 };
471
- specPopover.setDirectionAndShow = jest.fn();
472
- });
473
- it('sets the direction to up when control element has more space above it', async () => {
474
- const controlSpy = jest.spyOn(controlElement, 'getBoundingClientRect').mockReturnValue({
475
- top: 500,
476
- bottom: 550,
477
- });
478
- await specPopover.determinePopDirection();
479
- expect(containerElement.style.getPropertyValue('--comp-pop-max-height')).toBe('490px');
480
- expect(specPopover.setDirectionAndShow).toHaveBeenCalledWith('up');
481
- controlSpy.mockRestore();
482
- });
483
- it('sets the direction to down when control element has more space below it', async () => {
484
- const controlSpy = jest.spyOn(controlElement, 'getBoundingClientRect').mockReturnValue({
485
- top: 100,
486
- bottom: 150,
487
- });
488
- await specPopover.determinePopDirection();
489
- expect(containerElement.style.getPropertyValue('--comp-pop-max-height')).toBe('440px');
490
- expect(specPopover.setDirectionAndShow).toHaveBeenCalledWith('down');
491
- controlSpy.mockRestore();
492
- });
493
- });
494
- describe('openChanged', () => {
495
- beforeEach(() => {
496
- specPopover = new Q2Popover();
497
- specPopover.setRootElement = jest.fn();
498
- specPopover.addViewportListeners = jest.fn();
499
- specPopover.determinePopDirection = jest.fn();
500
- specPopover.removeViewportListeners = jest.fn();
501
- specPopover.clearCSSProperties = jest.fn();
502
- });
503
- it('sets open to true when open is false', async () => {
504
- specPopover.currentDirection = 'down';
505
- specPopover.show = true;
506
- await specPopover.openChanged(true);
507
- expect(specPopover.currentDirection).toBe('down');
508
- expect(specPopover.show).toBeTruthy();
509
- expect(specPopover.setRootElement).toHaveBeenCalled();
510
- expect(specPopover.addViewportListeners).toHaveBeenCalled();
511
- expect(specPopover.determinePopDirection).toHaveBeenCalled();
512
- expect(specPopover.removeViewportListeners).not.toHaveBeenCalled();
513
- expect(specPopover.clearCSSProperties).not.toHaveBeenCalled();
514
- });
515
- it('sets open to false when open is true', async () => {
516
- specPopover.currentDirection = 'down';
517
- specPopover.show = true;
518
- await specPopover.openChanged(false);
519
- expect(specPopover.currentDirection).toBeUndefined();
520
- expect(specPopover.show).toBeFalsy();
521
- expect(specPopover.setRootElement).toHaveBeenCalled();
522
- expect(specPopover.addViewportListeners).not.toHaveBeenCalled();
523
- expect(specPopover.determinePopDirection).not.toHaveBeenCalled();
524
- expect(specPopover.clearCSSProperties).toHaveBeenCalled();
525
- expect(specPopover.clearCSSProperties).toHaveBeenCalled();
526
- });
527
- });
528
- describe('setRootElement', () => {
529
- let computedStyleStub = {};
530
- const popoverDOMRect = {
531
- top: 50,
532
- bottom: 125,
533
- left: 50,
534
- right: 50,
535
- height: 75,
536
- width: 700,
537
- };
538
- beforeEach(() => {
539
- computedStyleStub = {
540
- transform: 'none',
541
- filter: 'none',
542
- perspective: 'none',
543
- contain: 'none',
544
- containerType: 'normal',
545
- willChange: 'auto',
546
- };
547
- window.visualViewport = { width: 800, height: 600 };
548
- specPopover = new Q2Popover();
549
- window.getComputedStyle = jest.fn().mockReturnValue(computedStyleStub);
550
- specPopover.hostElement.getBoundingClientRect = jest.fn().mockReturnValue(popoverDOMRect);
551
- });
552
- it('sets the rootElementRect by default', async () => {
553
- await specPopover.setRootElement();
554
- expect(specPopover.rootElementRect).toEqual({
555
- top: 0,
556
- bottom: 0,
557
- left: 0,
558
- right: 0,
559
- height: 600,
560
- width: 800,
854
+ describe('setDirectionAndShow', () => {
855
+ let specPopover;
856
+ let containerElement;
857
+ beforeEach(() => {
858
+ specPopover = new Q2Popover();
859
+ containerElement = document.createElement('div');
860
+ specPopover.containerElement = containerElement;
861
+ specPopover.setPopoverAPICSSProperties = jest.fn();
862
+ specPopover.setAbsoluteCSSProperties = jest.fn();
863
+ specPopover.scrollContainerTo = jest.fn();
864
+ });
865
+ it('does nothing when open is false', async () => {
866
+ specPopover.open = false;
867
+ specPopover.setDirectionAndShow('up');
868
+ expect(specPopover.currentDirection).toBeUndefined();
869
+ expect(specPopover.show).toBe(false);
870
+ expect(specPopover.setPopoverAPICSSProperties).not.toHaveBeenCalled();
871
+ expect(specPopover.setAbsoluteCSSProperties).not.toHaveBeenCalled();
872
+ });
873
+ describe('when open is true', () => {
874
+ beforeEach(() => {
875
+ specPopover.open = true;
876
+ });
877
+ it('sets the direction, shows the popover, and sets fixed position properties', async () => {
878
+ enablePopoverAPI();
879
+ containerElement.showPopover = jest.fn();
880
+ specPopover.setDirectionAndShow('up');
881
+ expect(specPopover.currentDirection).toBe('up');
882
+ expect(specPopover.setPopoverAPICSSProperties).toHaveBeenCalled();
883
+ expect(specPopover.setAbsoluteCSSProperties).not.toHaveBeenCalled();
884
+ expect(containerElement.showPopover).toHaveBeenCalled();
885
+ });
886
+ it('sets the direction, shows the popover, and sets absolute position properties when mode is "legacy"', async () => {
887
+ specPopover.mode = 'legacy';
888
+ specPopover.setDirectionAndShow('up');
889
+ expect(specPopover.currentDirection).toBe('up');
890
+ expect(specPopover.show).toBe(true);
891
+ expect(specPopover.setPopoverAPICSSProperties).not.toHaveBeenCalled();
892
+ expect(specPopover.setAbsoluteCSSProperties).toHaveBeenCalled();
893
+ });
894
+ });
561
895
  });
562
- });
563
- describe('when a containing block is created by applying CSS properties', () => {
564
- it('returns the currentElementRect when transform is applied', async () => {
565
- computedStyleStub.transform = 'translate(10px, 20px)';
566
- await specPopover.setRootElement();
567
- expect(specPopover.rootElementRect).toEqual(popoverDOMRect);
568
- });
569
- it('returns the currentElementRect when filter is applied', async () => {
570
- computedStyleStub.filter = 'blur(5px)';
571
- await specPopover.setRootElement();
572
- expect(specPopover.rootElementRect).toEqual(popoverDOMRect);
573
- });
574
- it('returns the currentElementRect when perspective is applied', async () => {
575
- computedStyleStub.perspective = '100px';
576
- await specPopover.setRootElement();
577
- expect(specPopover.rootElementRect).toEqual(popoverDOMRect);
578
- });
579
- it('returns the currentElementRect when contain is applied', async () => {
580
- computedStyleStub.contain = 'layout';
581
- await specPopover.setRootElement();
582
- expect(specPopover.rootElementRect).toEqual(popoverDOMRect);
583
- });
584
- it('returns the currentElementRect when containerType is applied', async () => {
585
- computedStyleStub.containerType = 'none';
586
- await specPopover.setRootElement();
587
- expect(specPopover.rootElementRect).toEqual(popoverDOMRect);
588
- });
589
- it('returns the currentElementRect when willChange is applied', async () => {
590
- computedStyleStub.willChange = 'transform';
591
- await specPopover.setRootElement();
592
- expect(specPopover.rootElementRect).toEqual(popoverDOMRect);
896
+ describe('setPopoverAPICSSProperties', () => {
897
+ let specPopover;
898
+ let containerElement;
899
+ beforeEach(() => {
900
+ window.visualViewport = { width: 800, height: 600, offsetTop: 0 };
901
+ window.innerHeight = 600;
902
+ window.scrollY = 0;
903
+ specPopover = new Q2Popover();
904
+ containerElement = document.createElement('div');
905
+ specPopover.containerElement = containerElement;
906
+ const controlElement = document.createElement('div');
907
+ controlElement.getBoundingClientRect = jest.fn().mockReturnValue({
908
+ top: 20,
909
+ bottom: 70,
910
+ left: 30,
911
+ right: 80,
912
+ });
913
+ specPopover.controlElement = controlElement;
914
+ });
915
+ it('sets the necessary CSS properties', async () => {
916
+ await specPopover.setPopoverAPICSSProperties();
917
+ expect(containerElement.style.getPropertyValue('--comp-pop-max-height')).toBeFalsy();
918
+ expect(containerElement.style.getPropertyValue('--comp-pop-top')).toBeFalsy();
919
+ expect(containerElement.style.getPropertyValue('--comp-pop-bottom')).toBeFalsy();
920
+ expect(containerElement.style.getPropertyValue('--comp-pop-left')).toBe('30px');
921
+ expect(containerElement.style.getPropertyValue('--comp-pop-right')).toBe('unset');
922
+ expect(containerElement.style.getPropertyValue('--comp-pop-width')).toBeFalsy();
923
+ expect(containerElement.style.getPropertyValue('--comp-pop-opacity')).toBe('1');
924
+ });
925
+ it('sets --comp-pop-right when align is right', async () => {
926
+ specPopover.align = 'right';
927
+ await specPopover.setPopoverAPICSSProperties();
928
+ expect(containerElement.style.getPropertyValue('--comp-pop-left')).toBe('unset');
929
+ expect(containerElement.style.getPropertyValue('--comp-pop-right')).toBe('720px');
930
+ });
931
+ it('sets --comp-pop-bottom when direction is up', async () => {
932
+ specPopover.currentDirection = 'up';
933
+ await specPopover.setPopoverAPICSSProperties();
934
+ expect(containerElement.style.getPropertyValue('--comp-pop-top')).toBeFalsy();
935
+ expect(containerElement.style.getPropertyValue('--comp-pop-bottom')).toBe('580px');
936
+ });
937
+ it('sets --comp-pop-top when direction is down', async () => {
938
+ specPopover.currentDirection = 'down';
939
+ await specPopover.setPopoverAPICSSProperties();
940
+ expect(containerElement.style.getPropertyValue('--comp-pop-top')).toBe('70px');
941
+ expect(containerElement.style.getPropertyValue('--comp-pop-bottom')).toBeFalsy();
942
+ });
943
+ it('sets --comp-pop-width when block is true', async () => {
944
+ specPopover.block = true;
945
+ await specPopover.setPopoverAPICSSProperties();
946
+ expect(containerElement.style.getPropertyValue('--comp-pop-width')).toBe('0px');
947
+ });
948
+ });
949
+ describe('viewPortChanged', () => {
950
+ let specPopover;
951
+ let windowSpy;
952
+ beforeEach(() => {
953
+ specPopover = new Q2Popover();
954
+ windowSpy = jest.spyOn(window, 'top', 'get').mockReturnValue({});
955
+ window.Tecton = sampleTectonWindow;
956
+ expect(specPopover.isModule).toBe(true);
957
+ specPopover.determinePopDirection = jest.fn();
958
+ });
959
+ afterEach(() => {
960
+ windowSpy.mockRestore();
961
+ });
962
+ it('calls determinePopDirection when open is true', async () => {
963
+ specPopover.open = true;
964
+ specPopover.viewPortChanged();
965
+ expect(specPopover.determinePopDirection).toHaveBeenCalled();
966
+ });
967
+ it('does nothing when open is false', async () => {
968
+ specPopover.open = false;
969
+ specPopover.viewPortChanged();
970
+ expect(specPopover.determinePopDirection).not.toHaveBeenCalled();
971
+ });
972
+ });
973
+ describe('viewPortOrientationChanged', () => {
974
+ let specPopover;
975
+ beforeEach(() => {
976
+ specPopover = new Q2Popover();
977
+ specPopover.viewPortChanged = jest.fn();
978
+ });
979
+ it('sets orientationChanged to true and calls viewportChanged', async () => {
980
+ specPopover.viewPortOrientationChanged();
981
+ expect(specPopover.orientationChanged).toBe(true);
982
+ expect(specPopover.viewPortChanged).toHaveBeenCalled();
983
+ });
593
984
  });
594
985
  });
595
986
  });