@coreui/react-pro 5.24.1 → 5.26.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (416) hide show
  1. package/README.md +1 -1
  2. package/dist/cjs/components/card/CCardImage.js.map +1 -1
  3. package/dist/cjs/components/carousel/CCarousel.js +44 -33
  4. package/dist/cjs/components/carousel/CCarousel.js.map +1 -1
  5. package/dist/cjs/components/carousel/CCarouselItem.js +19 -28
  6. package/dist/cjs/components/carousel/CCarouselItem.js.map +1 -1
  7. package/dist/cjs/components/chip/CChip.d.ts +12 -0
  8. package/dist/cjs/components/chip/CChip.js +16 -63
  9. package/dist/cjs/components/chip/CChip.js.map +1 -1
  10. package/dist/cjs/components/chip/const.d.ts +1 -0
  11. package/dist/cjs/components/chip/const.js +8 -0
  12. package/dist/cjs/components/chip/const.js.map +1 -0
  13. package/dist/cjs/components/chip-set/CChipSet.d.ts +73 -0
  14. package/dist/cjs/components/chip-set/CChipSet.js +66 -0
  15. package/dist/cjs/components/chip-set/CChipSet.js.map +1 -0
  16. package/dist/cjs/components/chip-set/index.d.ts +2 -0
  17. package/dist/cjs/components/chip-set/useChipSet.d.ts +48 -0
  18. package/dist/cjs/components/chip-set/useChipSet.js +163 -0
  19. package/dist/cjs/components/chip-set/useChipSet.js.map +1 -0
  20. package/dist/cjs/components/chip-set/utils.d.ts +7 -0
  21. package/dist/cjs/components/chip-set/utils.js +18 -0
  22. package/dist/cjs/components/chip-set/utils.js.map +1 -0
  23. package/dist/cjs/components/collapse/CCollapse.js +14 -6
  24. package/dist/cjs/components/collapse/CCollapse.js.map +1 -1
  25. package/dist/cjs/components/conditional-portal/CConditionalPortal.js +3 -1
  26. package/dist/cjs/components/conditional-portal/CConditionalPortal.js.map +1 -1
  27. package/dist/cjs/components/date-picker/CDatePicker.d.ts +1 -1
  28. package/dist/cjs/components/date-picker/CDatePicker.js.map +1 -1
  29. package/dist/cjs/components/date-range-picker/CDateRangePicker.js +2 -0
  30. package/dist/cjs/components/date-range-picker/CDateRangePicker.js.map +1 -1
  31. package/dist/cjs/components/dropdown/CDropdown.js +23 -30
  32. package/dist/cjs/components/dropdown/CDropdown.js.map +1 -1
  33. package/dist/cjs/components/dropdown/CDropdownToggle.js.map +1 -1
  34. package/dist/cjs/components/form/CChipInput.d.ts +14 -2
  35. package/dist/cjs/components/form/CChipInput.js +77 -49
  36. package/dist/cjs/components/form/CChipInput.js.map +1 -1
  37. package/dist/cjs/components/form/CFormCheck.js.map +1 -1
  38. package/dist/cjs/components/form/CFormInput.js.map +1 -1
  39. package/dist/cjs/components/form/CFormSelect.js.map +1 -1
  40. package/dist/cjs/components/form/CFormTextarea.js.map +1 -1
  41. package/dist/cjs/components/form/CInputGroupText.js.map +1 -1
  42. package/dist/cjs/components/grid/CContainer.js +3 -1
  43. package/dist/cjs/components/grid/CContainer.js.map +1 -1
  44. package/dist/cjs/components/header/CHeaderBrand.js.map +1 -1
  45. package/dist/cjs/components/index.d.ts +2 -0
  46. package/dist/cjs/components/link/CLink.js +4 -2
  47. package/dist/cjs/components/link/CLink.js.map +1 -1
  48. package/dist/cjs/components/list-group/CListGroupItem.js.map +1 -1
  49. package/dist/cjs/components/modal/CModal.js +14 -2
  50. package/dist/cjs/components/modal/CModal.js.map +1 -1
  51. package/dist/cjs/components/multi-select/CMultiSelect.d.ts +73 -1
  52. package/dist/cjs/components/multi-select/CMultiSelect.js +157 -18
  53. package/dist/cjs/components/multi-select/CMultiSelect.js.map +1 -1
  54. package/dist/cjs/components/multi-select/CMultiSelectNativeSelect.js +1 -1
  55. package/dist/cjs/components/multi-select/CMultiSelectNativeSelect.js.map +1 -1
  56. package/dist/cjs/components/multi-select/CMultiSelectOptions.d.ts +3 -0
  57. package/dist/cjs/components/multi-select/CMultiSelectOptions.js +45 -2
  58. package/dist/cjs/components/multi-select/CMultiSelectOptions.js.map +1 -1
  59. package/dist/cjs/components/multi-select/CMultiSelectSelection.d.ts +1 -0
  60. package/dist/cjs/components/multi-select/CMultiSelectSelection.js +4 -3
  61. package/dist/cjs/components/multi-select/CMultiSelectSelection.js.map +1 -1
  62. package/dist/cjs/components/multi-select/types.d.ts +12 -0
  63. package/dist/cjs/components/multi-select/utils.js +1 -4
  64. package/dist/cjs/components/multi-select/utils.js.map +1 -1
  65. package/dist/cjs/components/nav/CNav.js.map +1 -1
  66. package/dist/cjs/components/nav/CNavGroup.d.ts +13 -6
  67. package/dist/cjs/components/nav/CNavGroup.js +86 -23
  68. package/dist/cjs/components/nav/CNavGroup.js.map +1 -1
  69. package/dist/cjs/components/nav/CNavGroupContext.d.ts +25 -0
  70. package/dist/cjs/components/nav/CNavGroupContext.js +13 -0
  71. package/dist/cjs/components/nav/CNavGroupContext.js.map +1 -0
  72. package/dist/cjs/components/nav/CNavLink.d.ts +1 -5
  73. package/dist/cjs/components/nav/CNavLink.js +21 -8
  74. package/dist/cjs/components/nav/CNavLink.js.map +1 -1
  75. package/dist/cjs/components/one-time-password-input/COneTimePassword.js +3 -3
  76. package/dist/cjs/components/one-time-password-input/COneTimePassword.js.map +1 -1
  77. package/dist/cjs/components/popover/CPopover.js +69 -24
  78. package/dist/cjs/components/popover/CPopover.js.map +1 -1
  79. package/dist/cjs/components/progress/CProgress.js.map +1 -1
  80. package/dist/cjs/components/rating/CRating.d.ts +1 -1
  81. package/dist/cjs/components/rating/CRating.js.map +1 -1
  82. package/dist/cjs/components/search-button/CSearchButton.d.ts +32 -0
  83. package/dist/cjs/components/search-button/CSearchButton.js +77 -0
  84. package/dist/cjs/components/search-button/CSearchButton.js.map +1 -0
  85. package/dist/cjs/components/search-button/index.d.ts +2 -0
  86. package/dist/cjs/components/search-button/types.d.ts +10 -0
  87. package/dist/cjs/components/search-button/utils.d.ts +11 -0
  88. package/dist/cjs/components/search-button/utils.js +115 -0
  89. package/dist/cjs/components/search-button/utils.js.map +1 -0
  90. package/dist/cjs/components/sidebar/CSidebar.js +40 -23
  91. package/dist/cjs/components/sidebar/CSidebar.js.map +1 -1
  92. package/dist/cjs/components/sidebar/CSidebarNav.d.ts +12 -0
  93. package/dist/cjs/components/sidebar/CSidebarNav.js +12 -36
  94. package/dist/cjs/components/sidebar/CSidebarNav.js.map +1 -1
  95. package/dist/cjs/components/smart-table/CSmartTable.js +2 -2
  96. package/dist/cjs/components/smart-table/CSmartTable.js.map +1 -1
  97. package/dist/cjs/components/smart-table/CSmartTableInterface.d.ts +2 -2
  98. package/dist/cjs/components/table/CTableDataCell.js.map +1 -1
  99. package/dist/cjs/components/table/types.d.ts +2 -1
  100. package/dist/cjs/components/table/utils.js +4 -4
  101. package/dist/cjs/components/table/utils.js.map +1 -1
  102. package/dist/cjs/components/tabs/CTabPanel.js +3 -1
  103. package/dist/cjs/components/tabs/CTabPanel.js.map +1 -1
  104. package/dist/cjs/components/time-picker/CTimePicker.d.ts +1 -1
  105. package/dist/cjs/components/time-picker/CTimePicker.js +1 -1
  106. package/dist/cjs/components/time-picker/CTimePicker.js.map +1 -1
  107. package/dist/cjs/components/tooltip/CTooltip.js +69 -24
  108. package/dist/cjs/components/tooltip/CTooltip.js.map +1 -1
  109. package/dist/cjs/components/virtual-scroller/CVirtualScroller.js +11 -8
  110. package/dist/cjs/components/virtual-scroller/CVirtualScroller.js.map +1 -1
  111. package/dist/cjs/helpers/polymorphicComponent.d.ts +1 -2
  112. package/dist/cjs/hooks/useDebouncedCallback.d.ts +1 -1
  113. package/dist/cjs/hooks/useDebouncedCallback.js +1 -1
  114. package/dist/cjs/hooks/useDebouncedCallback.js.map +1 -1
  115. package/dist/cjs/hooks/useForkedRef.d.ts +1 -1
  116. package/dist/cjs/hooks/useForkedRef.js +6 -3
  117. package/dist/cjs/hooks/useForkedRef.js.map +1 -1
  118. package/dist/cjs/hooks/usePopper.js +8 -6
  119. package/dist/cjs/hooks/usePopper.js.map +1 -1
  120. package/dist/cjs/index.js +4 -0
  121. package/dist/cjs/index.js.map +1 -1
  122. package/dist/cjs/node_modules/@babel/runtime/helpers/esm/objectWithoutPropertiesLoose.js +1 -1
  123. package/dist/cjs/node_modules/@babel/runtime/helpers/esm/objectWithoutPropertiesLoose.js.map +1 -1
  124. package/dist/cjs/node_modules/@coreui/icons/dist/esm/free/cil-arrow-bottom.js +1 -1
  125. package/dist/cjs/node_modules/@coreui/icons/dist/esm/free/cil-arrow-bottom.js.map +1 -1
  126. package/dist/cjs/node_modules/@coreui/icons/dist/esm/free/cil-arrow-top.js +1 -1
  127. package/dist/cjs/node_modules/@coreui/icons/dist/esm/free/cil-arrow-top.js.map +1 -1
  128. package/dist/cjs/node_modules/@coreui/icons/dist/esm/free/cil-filter-x.js +1 -1
  129. package/dist/cjs/node_modules/@coreui/icons/dist/esm/free/cil-filter-x.js.map +1 -1
  130. package/dist/cjs/node_modules/@coreui/icons/dist/esm/free/cil-swap-vertical.js +1 -1
  131. package/dist/cjs/node_modules/@coreui/icons/dist/esm/free/cil-swap-vertical.js.map +1 -1
  132. package/dist/cjs/node_modules/ua-parser-js/dist/ua-parser.min.js +4 -4
  133. package/dist/cjs/node_modules/ua-parser-js/dist/ua-parser.min.js.map +1 -1
  134. package/dist/cjs/utils/executeAfterTransition.js.map +1 -1
  135. package/dist/cjs/utils/index.d.ts +2 -1
  136. package/dist/cjs/utils/swipe.d.ts +26 -0
  137. package/dist/cjs/utils/swipe.js +94 -0
  138. package/dist/cjs/utils/swipe.js.map +1 -0
  139. package/dist/esm/components/card/CCardImage.js.map +1 -1
  140. package/dist/esm/components/carousel/CCarousel.js +44 -33
  141. package/dist/esm/components/carousel/CCarousel.js.map +1 -1
  142. package/dist/esm/components/carousel/CCarouselItem.js +19 -28
  143. package/dist/esm/components/carousel/CCarouselItem.js.map +1 -1
  144. package/dist/esm/components/chip/CChip.d.ts +12 -0
  145. package/dist/esm/components/chip/CChip.js +16 -63
  146. package/dist/esm/components/chip/CChip.js.map +1 -1
  147. package/dist/esm/components/chip/const.d.ts +1 -0
  148. package/dist/esm/components/chip/const.js +6 -0
  149. package/dist/esm/components/chip/const.js.map +1 -0
  150. package/dist/esm/components/chip-set/CChipSet.d.ts +73 -0
  151. package/dist/esm/components/chip-set/CChipSet.js +64 -0
  152. package/dist/esm/components/chip-set/CChipSet.js.map +1 -0
  153. package/dist/esm/components/chip-set/index.d.ts +2 -0
  154. package/dist/esm/components/chip-set/useChipSet.d.ts +48 -0
  155. package/dist/esm/components/chip-set/useChipSet.js +161 -0
  156. package/dist/esm/components/chip-set/useChipSet.js.map +1 -0
  157. package/dist/esm/components/chip-set/utils.d.ts +7 -0
  158. package/dist/esm/components/chip-set/utils.js +16 -0
  159. package/dist/esm/components/chip-set/utils.js.map +1 -0
  160. package/dist/esm/components/collapse/CCollapse.js +14 -6
  161. package/dist/esm/components/collapse/CCollapse.js.map +1 -1
  162. package/dist/esm/components/conditional-portal/CConditionalPortal.js +3 -1
  163. package/dist/esm/components/conditional-portal/CConditionalPortal.js.map +1 -1
  164. package/dist/esm/components/date-picker/CDatePicker.d.ts +1 -1
  165. package/dist/esm/components/date-picker/CDatePicker.js.map +1 -1
  166. package/dist/esm/components/date-range-picker/CDateRangePicker.js +2 -0
  167. package/dist/esm/components/date-range-picker/CDateRangePicker.js.map +1 -1
  168. package/dist/esm/components/dropdown/CDropdown.js +23 -30
  169. package/dist/esm/components/dropdown/CDropdown.js.map +1 -1
  170. package/dist/esm/components/dropdown/CDropdownToggle.js.map +1 -1
  171. package/dist/esm/components/form/CChipInput.d.ts +14 -2
  172. package/dist/esm/components/form/CChipInput.js +78 -50
  173. package/dist/esm/components/form/CChipInput.js.map +1 -1
  174. package/dist/esm/components/form/CFormCheck.js.map +1 -1
  175. package/dist/esm/components/form/CFormInput.js.map +1 -1
  176. package/dist/esm/components/form/CFormSelect.js.map +1 -1
  177. package/dist/esm/components/form/CFormTextarea.js.map +1 -1
  178. package/dist/esm/components/form/CInputGroupText.js.map +1 -1
  179. package/dist/esm/components/grid/CContainer.js +3 -1
  180. package/dist/esm/components/grid/CContainer.js.map +1 -1
  181. package/dist/esm/components/header/CHeaderBrand.js.map +1 -1
  182. package/dist/esm/components/index.d.ts +2 -0
  183. package/dist/esm/components/link/CLink.js +4 -2
  184. package/dist/esm/components/link/CLink.js.map +1 -1
  185. package/dist/esm/components/list-group/CListGroupItem.js.map +1 -1
  186. package/dist/esm/components/modal/CModal.js +14 -2
  187. package/dist/esm/components/modal/CModal.js.map +1 -1
  188. package/dist/esm/components/multi-select/CMultiSelect.d.ts +73 -1
  189. package/dist/esm/components/multi-select/CMultiSelect.js +158 -19
  190. package/dist/esm/components/multi-select/CMultiSelect.js.map +1 -1
  191. package/dist/esm/components/multi-select/CMultiSelectNativeSelect.js +1 -1
  192. package/dist/esm/components/multi-select/CMultiSelectNativeSelect.js.map +1 -1
  193. package/dist/esm/components/multi-select/CMultiSelectOptions.d.ts +3 -0
  194. package/dist/esm/components/multi-select/CMultiSelectOptions.js +45 -2
  195. package/dist/esm/components/multi-select/CMultiSelectOptions.js.map +1 -1
  196. package/dist/esm/components/multi-select/CMultiSelectSelection.d.ts +1 -0
  197. package/dist/esm/components/multi-select/CMultiSelectSelection.js +4 -3
  198. package/dist/esm/components/multi-select/CMultiSelectSelection.js.map +1 -1
  199. package/dist/esm/components/multi-select/types.d.ts +12 -0
  200. package/dist/esm/components/multi-select/utils.js +1 -4
  201. package/dist/esm/components/multi-select/utils.js.map +1 -1
  202. package/dist/esm/components/nav/CNav.js.map +1 -1
  203. package/dist/esm/components/nav/CNavGroup.d.ts +13 -6
  204. package/dist/esm/components/nav/CNavGroup.js +87 -24
  205. package/dist/esm/components/nav/CNavGroup.js.map +1 -1
  206. package/dist/esm/components/nav/CNavGroupContext.d.ts +25 -0
  207. package/dist/esm/components/nav/CNavGroupContext.js +11 -0
  208. package/dist/esm/components/nav/CNavGroupContext.js.map +1 -0
  209. package/dist/esm/components/nav/CNavLink.d.ts +1 -5
  210. package/dist/esm/components/nav/CNavLink.js +21 -8
  211. package/dist/esm/components/nav/CNavLink.js.map +1 -1
  212. package/dist/esm/components/one-time-password-input/COneTimePassword.js +3 -3
  213. package/dist/esm/components/one-time-password-input/COneTimePassword.js.map +1 -1
  214. package/dist/esm/components/popover/CPopover.js +69 -24
  215. package/dist/esm/components/popover/CPopover.js.map +1 -1
  216. package/dist/esm/components/progress/CProgress.js.map +1 -1
  217. package/dist/esm/components/rating/CRating.d.ts +1 -1
  218. package/dist/esm/components/rating/CRating.js.map +1 -1
  219. package/dist/esm/components/search-button/CSearchButton.d.ts +32 -0
  220. package/dist/esm/components/search-button/CSearchButton.js +75 -0
  221. package/dist/esm/components/search-button/CSearchButton.js.map +1 -0
  222. package/dist/esm/components/search-button/index.d.ts +2 -0
  223. package/dist/esm/components/search-button/types.d.ts +10 -0
  224. package/dist/esm/components/search-button/utils.d.ts +11 -0
  225. package/dist/esm/components/search-button/utils.js +104 -0
  226. package/dist/esm/components/search-button/utils.js.map +1 -0
  227. package/dist/esm/components/sidebar/CSidebar.js +40 -23
  228. package/dist/esm/components/sidebar/CSidebar.js.map +1 -1
  229. package/dist/esm/components/sidebar/CSidebarNav.d.ts +12 -0
  230. package/dist/esm/components/sidebar/CSidebarNav.js +13 -37
  231. package/dist/esm/components/sidebar/CSidebarNav.js.map +1 -1
  232. package/dist/esm/components/smart-table/CSmartTable.js +2 -2
  233. package/dist/esm/components/smart-table/CSmartTable.js.map +1 -1
  234. package/dist/esm/components/smart-table/CSmartTableInterface.d.ts +2 -2
  235. package/dist/esm/components/table/CTableDataCell.js.map +1 -1
  236. package/dist/esm/components/table/types.d.ts +2 -1
  237. package/dist/esm/components/table/utils.js +4 -4
  238. package/dist/esm/components/table/utils.js.map +1 -1
  239. package/dist/esm/components/tabs/CTabPanel.js +3 -1
  240. package/dist/esm/components/tabs/CTabPanel.js.map +1 -1
  241. package/dist/esm/components/time-picker/CTimePicker.d.ts +1 -1
  242. package/dist/esm/components/time-picker/CTimePicker.js +1 -1
  243. package/dist/esm/components/time-picker/CTimePicker.js.map +1 -1
  244. package/dist/esm/components/tooltip/CTooltip.js +69 -24
  245. package/dist/esm/components/tooltip/CTooltip.js.map +1 -1
  246. package/dist/esm/components/virtual-scroller/CVirtualScroller.js +11 -8
  247. package/dist/esm/components/virtual-scroller/CVirtualScroller.js.map +1 -1
  248. package/dist/esm/helpers/polymorphicComponent.d.ts +1 -2
  249. package/dist/esm/hooks/useDebouncedCallback.d.ts +1 -1
  250. package/dist/esm/hooks/useDebouncedCallback.js +1 -1
  251. package/dist/esm/hooks/useDebouncedCallback.js.map +1 -1
  252. package/dist/esm/hooks/useForkedRef.d.ts +1 -1
  253. package/dist/esm/hooks/useForkedRef.js +6 -3
  254. package/dist/esm/hooks/useForkedRef.js.map +1 -1
  255. package/dist/esm/hooks/usePopper.js +9 -7
  256. package/dist/esm/hooks/usePopper.js.map +1 -1
  257. package/dist/esm/index.js +2 -0
  258. package/dist/esm/index.js.map +1 -1
  259. package/dist/esm/node_modules/@babel/runtime/helpers/esm/objectWithoutPropertiesLoose.js +1 -1
  260. package/dist/esm/node_modules/@babel/runtime/helpers/esm/objectWithoutPropertiesLoose.js.map +1 -1
  261. package/dist/esm/node_modules/@coreui/icons/dist/esm/free/cil-arrow-bottom.js +1 -1
  262. package/dist/esm/node_modules/@coreui/icons/dist/esm/free/cil-arrow-bottom.js.map +1 -1
  263. package/dist/esm/node_modules/@coreui/icons/dist/esm/free/cil-arrow-top.js +1 -1
  264. package/dist/esm/node_modules/@coreui/icons/dist/esm/free/cil-arrow-top.js.map +1 -1
  265. package/dist/esm/node_modules/@coreui/icons/dist/esm/free/cil-filter-x.js +1 -1
  266. package/dist/esm/node_modules/@coreui/icons/dist/esm/free/cil-filter-x.js.map +1 -1
  267. package/dist/esm/node_modules/@coreui/icons/dist/esm/free/cil-swap-vertical.js +1 -1
  268. package/dist/esm/node_modules/@coreui/icons/dist/esm/free/cil-swap-vertical.js.map +1 -1
  269. package/dist/esm/node_modules/ua-parser-js/dist/ua-parser.min.js +4 -4
  270. package/dist/esm/node_modules/ua-parser-js/dist/ua-parser.min.js.map +1 -1
  271. package/dist/esm/utils/executeAfterTransition.js.map +1 -1
  272. package/dist/esm/utils/index.d.ts +2 -1
  273. package/dist/esm/utils/swipe.d.ts +26 -0
  274. package/dist/esm/utils/swipe.js +90 -0
  275. package/dist/esm/utils/swipe.js.map +1 -0
  276. package/package.json +8 -6
  277. package/src/components/autocomplete/CAutocompleteOptions.tsx +1 -1
  278. package/src/components/autocomplete/__tests__/CAutocomplete.spec.tsx +18 -16
  279. package/src/components/autocomplete/__tests__/CAutocompleteOptions.spec.tsx +37 -28
  280. package/src/components/autocomplete/__tests__/__snapshots__/CAutocomplete.spec.tsx.snap +129 -0
  281. package/src/components/autocomplete/__tests__/__snapshots__/CAutocompleteOptions.spec.tsx.snap +36 -0
  282. package/src/components/calendar/__tests__/CCalendar.spec.tsx +40 -45
  283. package/src/components/calendar/__tests__/__snapshots__/CCalendar.spec.tsx.snap +99 -75
  284. package/src/components/calendar/__tests__/utils.spec.tsx +8 -18
  285. package/src/components/card/CCardImage.tsx +3 -2
  286. package/src/components/carousel/CCarousel.tsx +48 -51
  287. package/src/components/carousel/CCarouselContext.ts +1 -1
  288. package/src/components/carousel/CCarouselItem.tsx +25 -26
  289. package/src/components/carousel/__tests__/CCarousel.spec.tsx +47 -4
  290. package/src/components/carousel/__tests__/CCarouselItem.spec.tsx +37 -0
  291. package/src/components/chip/CChip.tsx +45 -78
  292. package/src/components/chip/__tests__/CChip.spec.tsx +26 -19
  293. package/src/components/chip/const.ts +3 -0
  294. package/src/components/chip-set/CChipSet.tsx +183 -0
  295. package/src/components/chip-set/__tests__/CChipSet.spec.tsx +215 -0
  296. package/src/components/chip-set/__tests__/__snapshots__/CChipSet.spec.tsx.snap +22 -0
  297. package/src/components/chip-set/index.ts +3 -0
  298. package/src/components/chip-set/useChipSet.ts +243 -0
  299. package/src/components/chip-set/utils.ts +19 -0
  300. package/src/components/collapse/CCollapse.tsx +18 -6
  301. package/src/components/conditional-portal/CConditionalPortal.tsx +4 -2
  302. package/src/components/date-picker/CDatePicker.tsx +12 -13
  303. package/src/components/date-picker/__tests__/CDatePicker.spec.tsx +1 -1
  304. package/src/components/date-picker/__tests__/__snapshots__/CDatePicker.spec.tsx.snap +12 -640
  305. package/src/components/date-range-picker/CDateRangePicker.tsx +2 -0
  306. package/src/components/date-range-picker/__tests__/CDateRangePicker.spec.tsx +1 -1
  307. package/src/components/date-range-picker/__tests__/__snapshots__/CDateRangePicker.spec.tsx.snap +21 -1259
  308. package/src/components/dropdown/CDropdown.tsx +29 -34
  309. package/src/components/dropdown/CDropdownToggle.tsx +1 -1
  310. package/src/components/dropdown/__tests__/CDropdown.spec.tsx +56 -1
  311. package/src/components/dropdown/__tests__/__snapshots__/CDropdown.spec.tsx.snap +2 -2
  312. package/src/components/dropdown/__tests__/__snapshots__/CDropdownMenu.spec.tsx.snap +1 -1
  313. package/src/components/focus-trap/__tests__/CFocusTrap.spec.tsx +1 -1
  314. package/src/components/form/CChipInput.tsx +105 -67
  315. package/src/components/form/CFormCheck.tsx +1 -2
  316. package/src/components/form/CFormInput.tsx +1 -2
  317. package/src/components/form/CFormSelect.tsx +1 -2
  318. package/src/components/form/CFormTextarea.tsx +1 -2
  319. package/src/components/form/CInputGroupText.tsx +3 -2
  320. package/src/components/form/__tests__/CChipInput.spec.tsx +67 -1
  321. package/src/components/form/__tests__/CFormInput.spec.tsx +17 -20
  322. package/src/components/form/__tests__/__snapshots__/CChipInput.spec.tsx.snap +7 -0
  323. package/src/components/form/__tests__/__snapshots__/CFormInput.spec.tsx.snap +12 -3
  324. package/src/components/grid/CContainer.tsx +3 -1
  325. package/src/components/header/CHeaderBrand.tsx +3 -2
  326. package/src/components/index.ts +2 -0
  327. package/src/components/link/CLink.tsx +7 -4
  328. package/src/components/list-group/CListGroupItem.tsx +3 -2
  329. package/src/components/loading-button/__tests__/CLoadingButton.spec.tsx +1 -1
  330. package/src/components/loading-button/__tests__/__snapshots__/CLoadingButton.spec.tsx.snap +4 -4
  331. package/src/components/modal/CModal.tsx +19 -2
  332. package/src/components/modal/__tests__/CModal.spec.tsx +43 -0
  333. package/src/components/multi-select/CMultiSelect.tsx +341 -46
  334. package/src/components/multi-select/CMultiSelectNativeSelect.tsx +1 -1
  335. package/src/components/multi-select/CMultiSelectOptions.tsx +74 -3
  336. package/src/components/multi-select/CMultiSelectSelection.tsx +5 -1
  337. package/src/components/multi-select/__tests__/CMultiSelect.spec.tsx +27 -69
  338. package/src/components/multi-select/__tests__/CMultiSelectNativeSelect.spec.tsx +4 -5
  339. package/src/components/multi-select/__tests__/CMultiSelectOptions.spec.tsx +4 -4
  340. package/src/components/multi-select/__tests__/CMultiSelectSelection.spec.tsx +7 -24
  341. package/src/components/multi-select/__tests__/__snapshots__/CMultiSelect.spec.tsx.snap +108 -61
  342. package/src/components/multi-select/__tests__/__snapshots__/CMultiSelectNativeSelect.spec.tsx.snap +2 -4
  343. package/src/components/multi-select/__tests__/__snapshots__/CMultiSelectOptions.spec.tsx.snap +7 -0
  344. package/src/components/multi-select/__tests__/__snapshots__/CMultiSelectSelection.spec.tsx.snap +16 -9
  345. package/src/components/multi-select/types.ts +14 -0
  346. package/src/components/nav/CNav.tsx +3 -2
  347. package/src/components/nav/CNavGroup.tsx +196 -105
  348. package/src/components/nav/CNavGroupContext.ts +27 -0
  349. package/src/components/nav/CNavLink.tsx +26 -12
  350. package/src/components/nav/__tests__/CNavGroup.spec.tsx +207 -4
  351. package/src/components/nav/__tests__/__snapshots__/CNavGroup.spec.tsx.snap +3 -1
  352. package/src/components/offcanvas/__tests__/COffcanvas.spec.tsx +1 -0
  353. package/src/components/one-time-password-input/COneTimePassword.tsx +10 -11
  354. package/src/components/picker/__tests__/CPicker.spec.tsx +1 -1
  355. package/src/components/picker/__tests__/__snapshots__/CPicker.spec.tsx.snap +2 -16
  356. package/src/components/popover/CPopover.tsx +71 -26
  357. package/src/components/popover/__tests__/CPopover.spec.tsx +85 -4
  358. package/src/components/progress/CProgress.tsx +1 -2
  359. package/src/components/rating/CRating.tsx +1 -0
  360. package/src/components/search-button/CSearchButton.tsx +195 -0
  361. package/src/components/search-button/__tests__/CSearchButton.spec.tsx +95 -0
  362. package/src/components/search-button/__tests__/__snapshots__/CSearchButton.spec.tsx.snap +87 -0
  363. package/src/components/search-button/index.ts +3 -0
  364. package/src/components/search-button/types.ts +10 -0
  365. package/src/components/search-button/utils.ts +140 -0
  366. package/src/components/sidebar/CSidebar.tsx +51 -26
  367. package/src/components/sidebar/CSidebarNav.tsx +39 -53
  368. package/src/components/sidebar/__tests__/CSidebar.spec.tsx +26 -0
  369. package/src/components/smart-table/CSmartTable.tsx +5 -4
  370. package/src/components/smart-table/CSmartTableInterface.tsx +2 -2
  371. package/src/components/smart-table/__tests__/CSmartTable.spec.tsx +3 -2
  372. package/src/components/smart-table/__tests__/__snapshots__/CSmartTable.spec.tsx.snap +7 -15
  373. package/src/components/stepper/__tests__/CStepper.spec.tsx +24 -21
  374. package/src/components/stepper/__tests__/__snapshots__/CStepper.spec.tsx.snap +295 -0
  375. package/src/components/table/CTableDataCell.tsx +2 -1
  376. package/src/components/table/types.ts +3 -1
  377. package/src/components/table/utils.ts +4 -4
  378. package/src/components/tabs/CTabPanel.tsx +3 -1
  379. package/src/components/tabs/CTabsContext.ts +1 -1
  380. package/src/components/tabs/__tests__/CTabContent.spec.tsx +1 -0
  381. package/src/components/tabs/__tests__/CTabPane.spec.tsx +1 -0
  382. package/src/components/time-picker/CTimePicker.tsx +6 -7
  383. package/src/components/time-picker/__tests__/CTimePicker.spec.tsx +10 -1
  384. package/src/components/time-picker/__tests__/__snapshots__/CTimePicker.spec.tsx.snap +599 -315
  385. package/src/components/tooltip/CTooltip.tsx +72 -27
  386. package/src/components/tooltip/__tests__/CTooltip.spec.tsx +102 -1
  387. package/src/components/virtual-scroller/CVirtualScroller.tsx +13 -14
  388. package/src/helpers/polymorphicComponent.ts +1 -1
  389. package/src/hooks/useColorModes.ts +2 -2
  390. package/src/hooks/useDebouncedCallback.ts +7 -4
  391. package/src/hooks/useForkedRef.ts +20 -15
  392. package/src/hooks/usePopper.ts +13 -9
  393. package/src/utils/__tests__/swipe.spec.ts +82 -0
  394. package/src/utils/executeAfterTransition.ts +1 -1
  395. package/src/utils/index.ts +2 -0
  396. package/src/utils/mergeClassNames.ts +1 -1
  397. package/src/utils/swipe.ts +114 -0
  398. package/dist/cjs/components/accordion/CAccordionCollapse.d.ts +0 -3
  399. package/dist/cjs/components/sidebar/CSidebarNavContext.d.ts +0 -5
  400. package/dist/cjs/components/sidebar/CSidebarNavContext.js +0 -8
  401. package/dist/cjs/components/sidebar/CSidebarNavContext.js.map +0 -1
  402. package/dist/esm/components/accordion/CAccordionCollapse.d.ts +0 -3
  403. package/dist/esm/components/sidebar/CSidebarNavContext.d.ts +0 -5
  404. package/dist/esm/components/sidebar/CSidebarNavContext.js +0 -6
  405. package/dist/esm/components/sidebar/CSidebarNavContext.js.map +0 -1
  406. package/src/components/accordion/CAccordionCollapse.tsx +0 -20
  407. package/src/components/accordion/__tests__/CAccordionCollapse.spec.tsx +0 -10
  408. package/src/components/accordion/__tests__/__snapshots__/CAccordionCollapse.spec.tsx.snap +0 -11
  409. package/src/components/button/__tests__/__snapshots__/CButtonClose.spec.tsx.snap +0 -26
  410. package/src/components/calendar/__tests__/CCalendar.accessibility.spec.tsx +0 -595
  411. package/src/components/calendar/__tests__/CCalendar.comprehensive.spec.tsx +0 -402
  412. package/src/components/calendar/__tests__/CCalendar.edge-cases.spec.tsx +0 -416
  413. package/src/components/calendar/__tests__/CCalendar.interactions.spec.tsx +0 -593
  414. package/src/components/header/CHeaderBrand.tsx~HEAD +0 -36
  415. package/src/components/sidebar/CSidebarNavContext.ts +0 -8
  416. /package/src/components/calendar/__tests__/{test-setup.ts → setup.ts} +0 -0
@@ -173,6 +173,14 @@ export const CTooltip = forwardRef<HTMLDivElement, CTooltipProps>(
173
173
  const { initPopper, destroyPopper, updatePopper } = usePopper()
174
174
 
175
175
  const _delay = typeof delay === 'number' ? { show: delay, hide: delay } : delay
176
+ const timer = useRef<ReturnType<typeof setTimeout>>(undefined)
177
+
178
+ const clearTimer = () => {
179
+ if (timer.current) {
180
+ clearTimeout(timer.current)
181
+ timer.current = undefined
182
+ }
183
+ }
176
184
 
177
185
  const defaultPopperConfig: Partial<Options> = {
178
186
  modifiers: [
@@ -188,19 +196,41 @@ export const CTooltip = forwardRef<HTMLDivElement, CTooltipProps>(
188
196
  ...(typeof popperConfig === 'function' ? popperConfig(defaultPopperConfig) : popperConfig),
189
197
  }
190
198
 
199
+ const handleShow = () => {
200
+ clearTimer()
201
+
202
+ if (mounted) {
203
+ timer.current = setTimeout(() => {
204
+ setVisible(true)
205
+ }, _delay.show)
206
+ } else {
207
+ setMounted(true)
208
+ }
209
+
210
+ onShow?.()
211
+ }
212
+
213
+ const handleHide = () => {
214
+ clearTimer()
215
+
216
+ timer.current = setTimeout(() => {
217
+ setVisible(false)
218
+ onHide?.()
219
+ }, _delay.hide)
220
+ }
221
+
191
222
  useEffect(() => {
192
- if (visible) {
223
+ if (visible === true) {
193
224
  handleShow()
194
- return
225
+ } else if (visible === false) {
226
+ handleHide()
195
227
  }
196
-
197
- handleHide()
198
228
  }, [visible])
199
229
 
200
230
  useEffect(() => {
201
231
  if (mounted && togglerRef.current && tooltipRef.current) {
202
232
  initPopper(togglerRef.current, tooltipRef.current, computedPopperConfig)
203
- setTimeout(() => {
233
+ timer.current = setTimeout(() => {
204
234
  setVisible(true)
205
235
  }, _delay.show)
206
236
 
@@ -212,6 +242,13 @@ export const CTooltip = forwardRef<HTMLDivElement, CTooltipProps>(
212
242
  }
213
243
  }, [mounted])
214
244
 
245
+ useEffect(() => {
246
+ return () => {
247
+ clearTimer()
248
+ destroyPopper()
249
+ }
250
+ }, [])
251
+
215
252
  useEffect(() => {
216
253
  if (!_visible && togglerRef.current && tooltipRef.current) {
217
254
  executeAfterTransition(() => {
@@ -220,43 +257,51 @@ export const CTooltip = forwardRef<HTMLDivElement, CTooltipProps>(
220
257
  }
221
258
  }, [_visible])
222
259
 
223
- const handleShow = () => {
224
- setMounted(true)
225
- if (onShow) {
226
- onShow()
227
- }
228
- }
229
-
230
- const handleHide = () => {
231
- setTimeout(() => {
232
- setVisible(false)
233
- if (onHide) {
234
- onHide()
235
- }
236
- }, _delay.hide)
237
- }
238
-
239
260
  useEffect(() => {
240
261
  updatePopper()
241
262
  }, [content])
242
263
 
264
+ const child = children as React.ReactElement<
265
+ React.HTMLAttributes<HTMLElement> & { ref?: React.Ref<HTMLElement> }
266
+ >
267
+
243
268
  return (
244
269
  <>
245
- {React.cloneElement(children as React.ReactElement<any>, {
270
+ {React.cloneElement(child, {
246
271
  ...(_visible && {
247
272
  'aria-describedby': id,
248
273
  }),
249
274
  ref: togglerRef,
250
275
  ...((trigger === 'click' || trigger.includes('click')) && {
251
- onClick: () => (_visible ? handleHide() : handleShow()),
276
+ onClick: (event: React.MouseEvent<HTMLElement>) => {
277
+ child.props.onClick?.(event)
278
+
279
+ if (_visible) {
280
+ handleHide()
281
+ } else {
282
+ handleShow()
283
+ }
284
+ },
252
285
  }),
253
286
  ...((trigger === 'focus' || trigger.includes('focus')) && {
254
- onFocus: () => handleShow(),
255
- onBlur: () => handleHide(),
287
+ onFocus: (event: React.FocusEvent<HTMLElement>) => {
288
+ child.props.onFocus?.(event)
289
+ handleShow()
290
+ },
291
+ onBlur: (event: React.FocusEvent<HTMLElement>) => {
292
+ child.props.onBlur?.(event)
293
+ handleHide()
294
+ },
256
295
  }),
257
296
  ...((trigger === 'hover' || trigger.includes('hover')) && {
258
- onMouseEnter: () => handleShow(),
259
- onMouseLeave: () => handleHide(),
297
+ onMouseEnter: (event: React.MouseEvent<HTMLElement>) => {
298
+ child.props.onMouseEnter?.(event)
299
+ handleShow()
300
+ },
301
+ onMouseLeave: (event: React.MouseEvent<HTMLElement>) => {
302
+ child.props.onMouseLeave?.(event)
303
+ handleHide()
304
+ },
260
305
  }),
261
306
  })}
262
307
  <CConditionalPortal container={container} portal={true}>
@@ -13,7 +13,7 @@ beforeEach(() => {
13
13
  })
14
14
 
15
15
  afterEach(() => {
16
- container && container.remove()
16
+ container?.remove()
17
17
  container = null
18
18
  })
19
19
 
@@ -47,6 +47,101 @@ test('CTooltip customize', async () => {
47
47
  jest.useRealTimers()
48
48
  })
49
49
 
50
+ test('CTooltip stays visible when re-hovered during the hide delay', async () => {
51
+ jest.useFakeTimers()
52
+
53
+ render(
54
+ <CTooltip trigger="hover" delay={{ show: 0, hide: 300 }} content="content">
55
+ <CLink>Test</CLink>
56
+ </CTooltip>
57
+ )
58
+
59
+ const link = screen.getByText('Test')
60
+
61
+ act(() => {
62
+ fireEvent.mouseOver(link)
63
+ })
64
+
65
+ act(() => {
66
+ jest.runAllTimers()
67
+ })
68
+
69
+ expect(document.querySelector('.tooltip')).toHaveClass('show')
70
+
71
+ act(() => {
72
+ fireEvent.mouseOut(link)
73
+ jest.advanceTimersByTime(100)
74
+ })
75
+
76
+ act(() => {
77
+ fireEvent.mouseOver(link)
78
+ jest.advanceTimersByTime(1000)
79
+ })
80
+
81
+ expect(document.querySelector('.tooltip')).toHaveClass('show')
82
+
83
+ jest.useRealTimers()
84
+ })
85
+
86
+ test('CTooltip cancels the pending show timer when pointer leaves before the show delay', async () => {
87
+ jest.useFakeTimers()
88
+
89
+ render(
90
+ <CTooltip trigger="hover" delay={{ show: 300, hide: 0 }} content="content">
91
+ <CLink>Test</CLink>
92
+ </CTooltip>
93
+ )
94
+
95
+ const link = screen.getByText('Test')
96
+
97
+ act(() => {
98
+ fireEvent.mouseOver(link)
99
+ jest.advanceTimersByTime(100)
100
+ })
101
+
102
+ act(() => {
103
+ fireEvent.mouseOut(link)
104
+ jest.advanceTimersByTime(1000)
105
+ })
106
+
107
+ expect(document.querySelector('.tooltip.show')).toBeNull()
108
+ expect(link).not.toHaveAttribute('aria-describedby')
109
+
110
+ jest.useRealTimers()
111
+ })
112
+
113
+ test('CTooltip preserves event handlers of the child element', async () => {
114
+ jest.useFakeTimers()
115
+
116
+ const onClick = jest.fn()
117
+ const onMouseEnter = jest.fn()
118
+
119
+ render(
120
+ <CTooltip trigger={['hover', 'click']} content="content">
121
+ <CButton onClick={onClick} onMouseEnter={onMouseEnter}>
122
+ Test
123
+ </CButton>
124
+ </CTooltip>
125
+ )
126
+
127
+ const btn = screen.getByRole('button', { name: /test/i })
128
+
129
+ act(() => {
130
+ fireEvent.mouseOver(btn)
131
+ jest.runAllTimers()
132
+ })
133
+
134
+ act(() => {
135
+ fireEvent.click(btn)
136
+ jest.runAllTimers()
137
+ })
138
+
139
+ expect(onMouseEnter).toHaveBeenCalledTimes(1)
140
+ expect(onClick).toHaveBeenCalledTimes(1)
141
+
142
+ jest.useRealTimers()
143
+ })
144
+
50
145
  test('CTooltip onShow and onHide', async () => {
51
146
  jest.useFakeTimers()
52
147
 
@@ -66,6 +161,9 @@ test('CTooltip onShow and onHide', async () => {
66
161
 
67
162
  act(() => {
68
163
  fireEvent.click(btn)
164
+ })
165
+
166
+ act(() => {
69
167
  jest.runAllTimers()
70
168
  })
71
169
 
@@ -74,6 +172,9 @@ test('CTooltip onShow and onHide', async () => {
74
172
 
75
173
  act(() => {
76
174
  fireEvent.click(btn)
175
+ })
176
+
177
+ act(() => {
77
178
  jest.runAllTimers()
78
179
  })
79
180
 
@@ -31,15 +31,15 @@ export const CVirtualScroller = forwardRef<HTMLDivElement, CVirtualScrollerProps
31
31
  const [itemsNumber, setItemsNumber] = useState(React.Children.count(children))
32
32
  const [viewportPadding, setViewportPadding] = useState(0)
33
33
  const [viewportHeight, setViewportHeight] = useState(
34
- visibleItems * itemHeight + 2 * viewportPadding,
34
+ visibleItems * itemHeight + 2 * viewportPadding
35
35
  )
36
36
  const [maxHeight, setMaxHeight] = useState(itemsNumber * itemHeight + 2 * viewportPadding)
37
37
 
38
38
  useEffect(() => {
39
- virtualScrollRef.current && virtualScrollRef.current.scrollTop
40
-
41
- virtualScrollRef.current &&
39
+ if (virtualScrollRef.current) {
40
+ void virtualScrollRef.current.scrollTop // force reflow
42
41
  setViewportPadding(Number.parseFloat(getComputedStyle(virtualScrollRef.current).paddingTop))
42
+ }
43
43
  })
44
44
 
45
45
  useEffect(() => {
@@ -52,7 +52,7 @@ export const CVirtualScroller = forwardRef<HTMLDivElement, CVirtualScrollerProps
52
52
 
53
53
  useEffect(() => {
54
54
  setMaxHeight(itemsNumber * itemHeight)
55
- virtualScrollRef.current && virtualScrollRef.current.scrollTop
55
+ void virtualScrollRef.current?.scrollTop // force reflow
56
56
  }, [itemHeight, itemsNumber])
57
57
 
58
58
  useEffect(() => {
@@ -60,17 +60,15 @@ export const CVirtualScroller = forwardRef<HTMLDivElement, CVirtualScrollerProps
60
60
  }, [visibleItems])
61
61
 
62
62
  const handleScroll = (scrollTop: number) => {
63
- const _currentItemIndex = itemHeight && Math.max(Math.ceil(scrollTop / itemHeight), 1)
63
+ const _currentItemIndex = itemHeight ? Math.max(Math.ceil(scrollTop / itemHeight), 1) : 0
64
64
  setCurrentItemIndex(_currentItemIndex)
65
- onScroll && onScroll(_currentItemIndex)
65
+ onScroll?.(_currentItemIndex)
66
66
  }
67
67
 
68
68
  return (
69
69
  <div
70
70
  className={classNames('virtual-scroller', className)}
71
- onScroll={(event: UIEvent<HTMLDivElement>) =>
72
- handleScroll((event.target as HTMLDivElement).scrollTop)
73
- }
71
+ onScroll={(event: UIEvent<HTMLDivElement>) => handleScroll(event.currentTarget.scrollTop)}
74
72
  style={{
75
73
  height: viewportHeight,
76
74
  overflowY: 'auto',
@@ -91,8 +89,9 @@ export const CVirtualScroller = forwardRef<HTMLDivElement, CVirtualScrollerProps
91
89
  index + 1 > Math.max(currentItemIndex - buffer, 0) &&
92
90
  index + 1 <= currentItemIndex + visibleItems + buffer
93
91
  ) {
94
- return React.cloneElement(child as React.ReactElement<any>, {
95
- className: classNames(child.props.className, {
92
+ const childElement = child as React.ReactElement<Record<string, unknown>>
93
+ return React.cloneElement(childElement, {
94
+ className: classNames(childElement.props.className as string, {
96
95
  'virtual-scroller-item-preload':
97
96
  index + 1 > currentItemIndex + visibleItems || index + 1 < currentItemIndex,
98
97
  }),
@@ -108,7 +107,7 @@ export const CVirtualScroller = forwardRef<HTMLDivElement, CVirtualScrollerProps
108
107
  setItemHeight(
109
108
  node.offsetHeight +
110
109
  Number.parseFloat(getComputedStyle(node).marginTop) +
111
- Number.parseFloat(getComputedStyle(node).marginBottom),
110
+ Number.parseFloat(getComputedStyle(node).marginBottom)
112
111
  ),
113
112
  })
114
113
  }
@@ -117,7 +116,7 @@ export const CVirtualScroller = forwardRef<HTMLDivElement, CVirtualScrollerProps
117
116
  </div>
118
117
  </div>
119
118
  )
120
- },
119
+ }
121
120
  )
122
121
 
123
122
  CVirtualScroller.propTypes = {
@@ -8,7 +8,7 @@ export interface AsProp<As extends ElementType = ElementType> {
8
8
  as?: As
9
9
  }
10
10
 
11
- export interface Props<As extends ElementType = ElementType> extends AsProp<As> {}
11
+ export type Props<As extends ElementType = ElementType> = AsProp<As>
12
12
 
13
13
  export interface PolymorphicRefForwardingComponent<TInitial extends ElementType, P = unknown> {
14
14
  <As extends ElementType = TInitial>(
@@ -37,10 +37,10 @@ const setTheme = (colorMode: string) => {
37
37
  }
38
38
 
39
39
  export const useColorModes = (
40
- localStorageItemName = 'coreui-react-color-scheme',
40
+ localStorageItemName = 'coreui-react-color-scheme'
41
41
  ): UseColorModesOutput => {
42
42
  const [colorMode, setColorMode] = useState<string | undefined>(
43
- getPreferredColorScheme(localStorageItemName),
43
+ getPreferredColorScheme(localStorageItemName)
44
44
  )
45
45
 
46
46
  useEffect(() => {
@@ -1,10 +1,13 @@
1
1
  import { useRef, useCallback } from 'react'
2
2
 
3
- export const useDebouncedCallback = <F extends Function>(callback: F, delay: number) => {
4
- const timeout = useRef<ReturnType<typeof setTimeout>>()
3
+ export const useDebouncedCallback = <A extends unknown[]>(
4
+ callback: (...args: A) => void,
5
+ delay: number
6
+ ) => {
7
+ const timeout = useRef<ReturnType<typeof setTimeout> | undefined>(undefined)
5
8
 
6
9
  return useCallback(
7
- (...args: any[]) => {
10
+ (...args: A) => {
8
11
  const handler = () => {
9
12
  clearTimeout(timeout.current)
10
13
  callback(...args)
@@ -13,6 +16,6 @@ export const useDebouncedCallback = <F extends Function>(callback: F, delay: num
13
16
  clearTimeout(timeout.current)
14
17
  timeout.current = setTimeout(handler, delay)
15
18
  },
16
- [callback, delay],
19
+ [callback, delay]
17
20
  )
18
21
  }
@@ -13,24 +13,30 @@ export type AssignableRef<ValueType> =
13
13
  export function useForkedRef<RefValueType = any>(
14
14
  ...refs: (AssignableRef<RefValueType> | null | undefined)[]
15
15
  ) {
16
- return useMemo(() => {
17
- if (refs.every((ref) => ref == null)) {
18
- return null
19
- }
20
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
21
- return (node: any) => {
22
- refs.forEach((ref) => {
23
- assignRef(ref, node)
24
- })
25
- }
26
- }, refs)
16
+ return useMemo(
17
+ () => {
18
+ if (refs.every((ref) => ref == null)) {
19
+ return null
20
+ }
21
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
22
+ return (node: any) => {
23
+ refs.forEach((ref) => {
24
+ assignRef(ref, node)
25
+ })
26
+ }
27
+ },
28
+ // useForkedRef accepts a variable number of refs, so the dependency list
29
+ // cannot be a static array literal; the refs are compared element-wise.
30
+ // eslint-disable-next-line react-hooks/use-memo, react-hooks/exhaustive-deps
31
+ refs
32
+ )
27
33
  }
28
34
 
29
35
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
30
36
  export function assignRef<RefValueType = any>(
31
37
  ref: AssignableRef<RefValueType> | null | undefined,
32
38
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
33
- value: any,
39
+ value: any
34
40
  ) {
35
41
  if (ref == null) return
36
42
  if (isFunction(ref)) {
@@ -44,7 +50,6 @@ export function assignRef<RefValueType = any>(
44
50
  }
45
51
  }
46
52
 
47
- // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/ban-types
48
- export function isFunction(value: any): value is Function {
49
- return !!(value && {}.toString.call(value) == '[object Function]')
53
+ export function isFunction(value: unknown): value is (...args: unknown[]) => unknown {
54
+ return typeof value === 'function'
50
55
  }
@@ -1,4 +1,4 @@
1
- import { useRef } from 'react'
1
+ import { useCallback, useRef } from 'react'
2
2
  import { createPopper } from '@popperjs/core'
3
3
  import type { Instance, Options } from '@popperjs/core'
4
4
 
@@ -13,12 +13,16 @@ export const usePopper = (): UsePopperOutput => {
13
13
  const _popper = useRef<Instance>(undefined)
14
14
  const el = useRef<HTMLElement>(null)
15
15
 
16
- const initPopper = (reference: HTMLElement, popper: HTMLElement, options: Partial<Options>) => {
17
- _popper.current = createPopper(reference, popper, options)
18
- el.current = popper
19
- }
16
+ const initPopper = useCallback(
17
+ (reference: HTMLElement, popper: HTMLElement, options: Partial<Options>) => {
18
+ _popper.current?.destroy()
19
+ _popper.current = createPopper(reference, popper, options)
20
+ el.current = popper
21
+ },
22
+ []
23
+ )
20
24
 
21
- const destroyPopper = () => {
25
+ const destroyPopper = useCallback(() => {
22
26
  const popperInstance = _popper.current
23
27
 
24
28
  if (popperInstance && el.current) {
@@ -26,9 +30,9 @@ export const usePopper = (): UsePopperOutput => {
26
30
  }
27
31
 
28
32
  _popper.current = undefined
29
- }
33
+ }, [])
30
34
 
31
- const updatePopper = (options?: Partial<Options>) => {
35
+ const updatePopper = useCallback((options?: Partial<Options>) => {
32
36
  const popperInstance = _popper.current
33
37
 
34
38
  if (popperInstance && options) {
@@ -38,7 +42,7 @@ export const usePopper = (): UsePopperOutput => {
38
42
  if (popperInstance) {
39
43
  popperInstance.update()
40
44
  }
41
- }
45
+ }, [])
42
46
 
43
47
  return {
44
48
  popper: _popper.current,
@@ -0,0 +1,82 @@
1
+ import Swipe from '../swipe'
2
+
3
+ const touchEvent = (type: string, clientX: number): Event => {
4
+ const event = new Event(type) as Event & { touches: { clientX: number }[] }
5
+ event.touches = [{ clientX }]
6
+ return event
7
+ }
8
+
9
+ describe('Swipe', () => {
10
+ let element: HTMLElement
11
+ const originalPointerEvent = window.PointerEvent
12
+
13
+ beforeEach(() => {
14
+ element = document.createElement('div')
15
+ document.body.appendChild(element)
16
+ // Force the touch-event path and make the helper consider touch supported.
17
+ ;(window as unknown as { PointerEvent?: unknown }).PointerEvent = undefined
18
+ Object.defineProperty(navigator, 'maxTouchPoints', { value: 1, configurable: true })
19
+ })
20
+
21
+ afterEach(() => {
22
+ element.remove()
23
+ ;(window as unknown as { PointerEvent?: unknown }).PointerEvent = originalPointerEvent
24
+ })
25
+
26
+ it('reports support when touch points are available', () => {
27
+ expect(Swipe.isSupported()).toBe(true)
28
+ })
29
+
30
+ it('calls onLeft when swiping left past the threshold', () => {
31
+ const onLeft = jest.fn()
32
+ const onRight = jest.fn()
33
+ const onEnd = jest.fn()
34
+ new Swipe(element, { onLeft, onRight, onEnd })
35
+
36
+ element.dispatchEvent(touchEvent('touchstart', 200))
37
+ element.dispatchEvent(touchEvent('touchmove', 100))
38
+ element.dispatchEvent(touchEvent('touchend', 100))
39
+
40
+ expect(onLeft).toHaveBeenCalledTimes(1)
41
+ expect(onRight).not.toHaveBeenCalled()
42
+ expect(onEnd).toHaveBeenCalledTimes(1)
43
+ })
44
+
45
+ it('calls onRight when swiping right past the threshold', () => {
46
+ const onLeft = jest.fn()
47
+ const onRight = jest.fn()
48
+ new Swipe(element, { onLeft, onRight })
49
+
50
+ element.dispatchEvent(touchEvent('touchstart', 100))
51
+ element.dispatchEvent(touchEvent('touchmove', 200))
52
+ element.dispatchEvent(touchEvent('touchend', 200))
53
+
54
+ expect(onRight).toHaveBeenCalledTimes(1)
55
+ expect(onLeft).not.toHaveBeenCalled()
56
+ })
57
+
58
+ it('ignores swipes below the threshold', () => {
59
+ const onLeft = jest.fn()
60
+ const onRight = jest.fn()
61
+ new Swipe(element, { onLeft, onRight })
62
+
63
+ element.dispatchEvent(touchEvent('touchstart', 200))
64
+ element.dispatchEvent(touchEvent('touchmove', 180))
65
+ element.dispatchEvent(touchEvent('touchend', 180))
66
+
67
+ expect(onLeft).not.toHaveBeenCalled()
68
+ expect(onRight).not.toHaveBeenCalled()
69
+ })
70
+
71
+ it('stops detecting swipes after dispose', () => {
72
+ const onLeft = jest.fn()
73
+ const swipe = new Swipe(element, { onLeft })
74
+ swipe.dispose()
75
+
76
+ element.dispatchEvent(touchEvent('touchstart', 200))
77
+ element.dispatchEvent(touchEvent('touchmove', 100))
78
+ element.dispatchEvent(touchEvent('touchend', 100))
79
+
80
+ expect(onLeft).not.toHaveBeenCalled()
81
+ })
82
+ })
@@ -25,7 +25,7 @@ const executeAfterTransition = (
25
25
 
26
26
  let called = false
27
27
 
28
- const handler = ({ target }: { target: any }) => {
28
+ const handler = ({ target }: Event) => {
29
29
  if (target !== transitionElement) {
30
30
  return
31
31
  }
@@ -8,6 +8,7 @@ import isInViewport from './isInViewport'
8
8
  import isObjectInArray from './isObjectInArray'
9
9
  import isRTL from './isRTL'
10
10
  import mergeClassNames from './mergeClassNames'
11
+ import Swipe from './swipe'
11
12
 
12
13
  export {
13
14
  executeAfterTransition,
@@ -20,4 +21,5 @@ export {
20
21
  isObjectInArray,
21
22
  isRTL,
22
23
  mergeClassNames,
24
+ Swipe,
23
25
  }
@@ -9,7 +9,7 @@ const mergeClassNames = <T extends object>(
9
9
  const classNames: T = { ...defaultClassNames }
10
10
 
11
11
  for (const key in customClassNames) {
12
- if (customClassNames.hasOwnProperty(key)) {
12
+ if (Object.hasOwn(customClassNames, key)) {
13
13
  const typedKey = key as keyof T
14
14
  const customClassName = customClassNames[typedKey]?.toString()
15
15