@coreui/vue-pro 5.18.0 → 5.19.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 (422) hide show
  1. package/README.md +1 -1
  2. package/dist/cjs/components/carousel/CCarousel.d.ts +24 -2
  3. package/dist/cjs/components/carousel/CCarousel.js +51 -14
  4. package/dist/cjs/components/carousel/CCarousel.js.map +1 -1
  5. package/dist/cjs/components/carousel/CCarouselItem.js +3 -3
  6. package/dist/cjs/components/carousel/CCarouselItem.js.map +1 -1
  7. package/dist/cjs/components/chip/CChip.d.ts +97 -11
  8. package/dist/cjs/components/chip/CChip.js +107 -79
  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-input/CChipInput.d.ts +30 -2
  14. package/dist/cjs/components/chip-input/CChipInput.js +108 -66
  15. package/dist/cjs/components/chip-input/CChipInput.js.map +1 -1
  16. package/dist/cjs/components/chip-set/CChipSet.d.ts +145 -0
  17. package/dist/cjs/components/chip-set/CChipSet.js +127 -0
  18. package/dist/cjs/components/chip-set/CChipSet.js.map +1 -0
  19. package/dist/cjs/components/chip-set/buildChips.d.ts +13 -0
  20. package/dist/cjs/components/chip-set/buildChips.js +19 -0
  21. package/dist/cjs/components/chip-set/buildChips.js.map +1 -0
  22. package/dist/cjs/components/chip-set/index.d.ts +2 -0
  23. package/dist/cjs/components/chip-set/useChipSet.d.ts +42 -0
  24. package/dist/cjs/components/chip-set/useChipSet.js +115 -0
  25. package/dist/cjs/components/chip-set/useChipSet.js.map +1 -0
  26. package/dist/cjs/components/collapse/CCollapse.js +2 -2
  27. package/dist/cjs/components/collapse/CCollapse.js.map +1 -1
  28. package/dist/cjs/components/dropdown/CDropdown.d.ts +24 -1
  29. package/dist/cjs/components/dropdown/CDropdown.js +34 -17
  30. package/dist/cjs/components/dropdown/CDropdown.js.map +1 -1
  31. package/dist/cjs/components/dropdown/CDropdownToggle.js +1 -1
  32. package/dist/cjs/components/dropdown/CDropdownToggle.js.map +1 -1
  33. package/dist/cjs/components/focus-trap/CFocusTrap.js +4 -1
  34. package/dist/cjs/components/focus-trap/CFocusTrap.js.map +1 -1
  35. package/dist/cjs/components/form/CFormInput.d.ts +3 -0
  36. package/dist/cjs/components/form/CFormRange.d.ts +2 -2
  37. package/dist/cjs/components/form/CFormRange.js +2 -2
  38. package/dist/cjs/components/form/CFormRange.js.map +1 -1
  39. package/dist/cjs/components/grid/CContainer.js +3 -1
  40. package/dist/cjs/components/grid/CContainer.js.map +1 -1
  41. package/dist/cjs/components/index.d.ts +2 -0
  42. package/dist/cjs/components/index.js +30 -24
  43. package/dist/cjs/components/index.js.map +1 -1
  44. package/dist/cjs/components/modal/CModal.js +3 -2
  45. package/dist/cjs/components/modal/CModal.js.map +1 -1
  46. package/dist/cjs/components/modal/CModalHeader.js +6 -3
  47. package/dist/cjs/components/modal/CModalHeader.js.map +1 -1
  48. package/dist/cjs/components/multi-select/CMultiSelect.d.ts +206 -3
  49. package/dist/cjs/components/multi-select/CMultiSelect.js +304 -28
  50. package/dist/cjs/components/multi-select/CMultiSelect.js.map +1 -1
  51. package/dist/cjs/components/multi-select/CMultiSelectNativeSelect.js +1 -2
  52. package/dist/cjs/components/multi-select/CMultiSelectNativeSelect.js.map +1 -1
  53. package/dist/cjs/components/multi-select/CMultiSelectOptions.d.ts +16 -1
  54. package/dist/cjs/components/multi-select/CMultiSelectOptions.js +59 -3
  55. package/dist/cjs/components/multi-select/CMultiSelectOptions.js.map +1 -1
  56. package/dist/cjs/components/multi-select/CMultiSelectSelection.d.ts +9 -0
  57. package/dist/cjs/components/multi-select/CMultiSelectSelection.js +6 -1
  58. package/dist/cjs/components/multi-select/CMultiSelectSelection.js.map +1 -1
  59. package/dist/cjs/components/multi-select/utils.js +0 -3
  60. package/dist/cjs/components/multi-select/utils.js.map +1 -1
  61. package/dist/cjs/components/nav/CNav.js +8 -1
  62. package/dist/cjs/components/nav/CNav.js.map +1 -1
  63. package/dist/cjs/components/nav/CNavGroup.d.ts +15 -7
  64. package/dist/cjs/components/nav/CNavGroup.js +113 -88
  65. package/dist/cjs/components/nav/CNavGroup.js.map +1 -1
  66. package/dist/cjs/components/nav/CNavLink.js +11 -0
  67. package/dist/cjs/components/nav/CNavLink.js.map +1 -1
  68. package/dist/cjs/components/popover/CPopover.d.ts +24 -1
  69. package/dist/cjs/components/popover/CPopover.js +18 -1
  70. package/dist/cjs/components/popover/CPopover.js.map +1 -1
  71. package/dist/cjs/components/range-slider/CRangeSlider.d.ts +1 -1
  72. package/dist/cjs/components/search-button/CSearchButton.d.ts +63 -0
  73. package/dist/cjs/components/search-button/CSearchButton.js +125 -0
  74. package/dist/cjs/components/search-button/CSearchButton.js.map +1 -0
  75. package/dist/cjs/components/search-button/index.d.ts +6 -0
  76. package/dist/cjs/components/search-button/index.js +13 -0
  77. package/dist/cjs/components/search-button/index.js.map +1 -0
  78. package/dist/cjs/components/search-button/types.d.ts +10 -0
  79. package/dist/cjs/components/search-button/utils.d.ts +11 -0
  80. package/dist/cjs/components/search-button/utils.js +114 -0
  81. package/dist/cjs/components/search-button/utils.js.map +1 -0
  82. package/dist/cjs/components/sidebar/CSidebar.js +4 -3
  83. package/dist/cjs/components/sidebar/CSidebar.js.map +1 -1
  84. package/dist/cjs/components/sidebar/CSidebarNav.d.ts +32 -0
  85. package/dist/cjs/components/sidebar/CSidebarNav.js +28 -24
  86. package/dist/cjs/components/sidebar/CSidebarNav.js.map +1 -1
  87. package/dist/cjs/components/spinner/CSpinner.d.ts +4 -4
  88. package/dist/cjs/components/spinner/CSpinner.js +2 -2
  89. package/dist/cjs/components/spinner/CSpinner.js.map +1 -1
  90. package/dist/cjs/components/table/utils.js +4 -4
  91. package/dist/cjs/components/table/utils.js.map +1 -1
  92. package/dist/cjs/components/tabs/CTabList.js +8 -2
  93. package/dist/cjs/components/tabs/CTabList.js.map +1 -1
  94. package/dist/cjs/components/tabs/CTabs.js +1 -1
  95. package/dist/cjs/components/tabs/CTabs.js.map +1 -1
  96. package/dist/cjs/components/toast/CToast.js +12 -2
  97. package/dist/cjs/components/toast/CToast.js.map +1 -1
  98. package/dist/cjs/components/toast/CToastClose.d.ts +3 -2
  99. package/dist/cjs/components/toast/CToastClose.js +2 -3
  100. package/dist/cjs/components/toast/CToastClose.js.map +1 -1
  101. package/dist/cjs/components/tooltip/CTooltip.d.ts +24 -1
  102. package/dist/cjs/components/tooltip/CTooltip.js +18 -1
  103. package/dist/cjs/components/tooltip/CTooltip.js.map +1 -1
  104. package/dist/cjs/directives/v-c-popover.js +6 -3
  105. package/dist/cjs/directives/v-c-popover.js.map +1 -1
  106. package/dist/cjs/directives/v-c-tooltip.js +6 -3
  107. package/dist/cjs/directives/v-c-tooltip.js.map +1 -1
  108. package/dist/cjs/directives/v-c-visible.js +1 -1
  109. package/dist/cjs/directives/v-c-visible.js.map +1 -1
  110. package/dist/cjs/index.js +36 -30
  111. package/dist/cjs/index.js.map +1 -1
  112. package/dist/cjs/node_modules/@coreui/icons/dist/esm/free/cil-arrow-bottom.js +1 -1
  113. package/dist/cjs/node_modules/@coreui/icons/dist/esm/free/cil-arrow-bottom.js.map +1 -1
  114. package/dist/cjs/node_modules/@coreui/icons/dist/esm/free/cil-arrow-top.js +1 -1
  115. package/dist/cjs/node_modules/@coreui/icons/dist/esm/free/cil-arrow-top.js.map +1 -1
  116. package/dist/cjs/node_modules/@coreui/icons/dist/esm/free/cil-filter-x.js +1 -1
  117. package/dist/cjs/node_modules/@coreui/icons/dist/esm/free/cil-filter-x.js.map +1 -1
  118. package/dist/cjs/node_modules/@coreui/icons/dist/esm/free/cil-swap-vertical.js +1 -1
  119. package/dist/cjs/node_modules/@coreui/icons/dist/esm/free/cil-swap-vertical.js.map +1 -1
  120. package/dist/cjs/utils/index.d.ts +2 -1
  121. package/dist/cjs/utils/swipe.d.ts +26 -0
  122. package/dist/cjs/utils/swipe.js +94 -0
  123. package/dist/cjs/utils/swipe.js.map +1 -0
  124. package/dist/cjs/utils/transition.js.map +1 -1
  125. package/dist/esm/components/carousel/CCarousel.d.ts +24 -2
  126. package/dist/esm/components/carousel/CCarousel.js +52 -15
  127. package/dist/esm/components/carousel/CCarousel.js.map +1 -1
  128. package/dist/esm/components/carousel/CCarouselItem.js +3 -3
  129. package/dist/esm/components/carousel/CCarouselItem.js.map +1 -1
  130. package/dist/esm/components/chip/CChip.d.ts +97 -11
  131. package/dist/esm/components/chip/CChip.js +108 -80
  132. package/dist/esm/components/chip/CChip.js.map +1 -1
  133. package/dist/esm/components/chip/const.d.ts +1 -0
  134. package/dist/esm/components/chip/const.js +6 -0
  135. package/dist/esm/components/chip/const.js.map +1 -0
  136. package/dist/esm/components/chip-input/CChipInput.d.ts +30 -2
  137. package/dist/esm/components/chip-input/CChipInput.js +109 -67
  138. package/dist/esm/components/chip-input/CChipInput.js.map +1 -1
  139. package/dist/esm/components/chip-set/CChipSet.d.ts +145 -0
  140. package/dist/esm/components/chip-set/CChipSet.js +125 -0
  141. package/dist/esm/components/chip-set/CChipSet.js.map +1 -0
  142. package/dist/esm/components/chip-set/buildChips.d.ts +13 -0
  143. package/dist/esm/components/chip-set/buildChips.js +17 -0
  144. package/dist/esm/components/chip-set/buildChips.js.map +1 -0
  145. package/dist/esm/components/chip-set/index.d.ts +2 -0
  146. package/dist/esm/components/chip-set/useChipSet.d.ts +42 -0
  147. package/dist/esm/components/chip-set/useChipSet.js +112 -0
  148. package/dist/esm/components/chip-set/useChipSet.js.map +1 -0
  149. package/dist/esm/components/collapse/CCollapse.js +2 -2
  150. package/dist/esm/components/collapse/CCollapse.js.map +1 -1
  151. package/dist/esm/components/dropdown/CDropdown.d.ts +24 -1
  152. package/dist/esm/components/dropdown/CDropdown.js +34 -17
  153. package/dist/esm/components/dropdown/CDropdown.js.map +1 -1
  154. package/dist/esm/components/dropdown/CDropdownToggle.js +1 -1
  155. package/dist/esm/components/dropdown/CDropdownToggle.js.map +1 -1
  156. package/dist/esm/components/focus-trap/CFocusTrap.js +4 -1
  157. package/dist/esm/components/focus-trap/CFocusTrap.js.map +1 -1
  158. package/dist/esm/components/form/CFormInput.d.ts +3 -0
  159. package/dist/esm/components/form/CFormRange.d.ts +2 -2
  160. package/dist/esm/components/form/CFormRange.js +2 -2
  161. package/dist/esm/components/form/CFormRange.js.map +1 -1
  162. package/dist/esm/components/grid/CContainer.js +3 -1
  163. package/dist/esm/components/grid/CContainer.js.map +1 -1
  164. package/dist/esm/components/index.d.ts +2 -0
  165. package/dist/esm/components/index.js +3 -0
  166. package/dist/esm/components/index.js.map +1 -1
  167. package/dist/esm/components/modal/CModal.js +3 -2
  168. package/dist/esm/components/modal/CModal.js.map +1 -1
  169. package/dist/esm/components/modal/CModalHeader.js +6 -3
  170. package/dist/esm/components/modal/CModalHeader.js.map +1 -1
  171. package/dist/esm/components/multi-select/CMultiSelect.d.ts +206 -3
  172. package/dist/esm/components/multi-select/CMultiSelect.js +305 -29
  173. package/dist/esm/components/multi-select/CMultiSelect.js.map +1 -1
  174. package/dist/esm/components/multi-select/CMultiSelectNativeSelect.js +1 -2
  175. package/dist/esm/components/multi-select/CMultiSelectNativeSelect.js.map +1 -1
  176. package/dist/esm/components/multi-select/CMultiSelectOptions.d.ts +16 -1
  177. package/dist/esm/components/multi-select/CMultiSelectOptions.js +59 -3
  178. package/dist/esm/components/multi-select/CMultiSelectOptions.js.map +1 -1
  179. package/dist/esm/components/multi-select/CMultiSelectSelection.d.ts +9 -0
  180. package/dist/esm/components/multi-select/CMultiSelectSelection.js +6 -1
  181. package/dist/esm/components/multi-select/CMultiSelectSelection.js.map +1 -1
  182. package/dist/esm/components/multi-select/utils.js +0 -3
  183. package/dist/esm/components/multi-select/utils.js.map +1 -1
  184. package/dist/esm/components/nav/CNav.js +8 -1
  185. package/dist/esm/components/nav/CNav.js.map +1 -1
  186. package/dist/esm/components/nav/CNavGroup.d.ts +15 -7
  187. package/dist/esm/components/nav/CNavGroup.js +114 -89
  188. package/dist/esm/components/nav/CNavGroup.js.map +1 -1
  189. package/dist/esm/components/nav/CNavLink.js +12 -1
  190. package/dist/esm/components/nav/CNavLink.js.map +1 -1
  191. package/dist/esm/components/popover/CPopover.d.ts +24 -1
  192. package/dist/esm/components/popover/CPopover.js +18 -1
  193. package/dist/esm/components/popover/CPopover.js.map +1 -1
  194. package/dist/esm/components/range-slider/CRangeSlider.d.ts +1 -1
  195. package/dist/esm/components/search-button/CSearchButton.d.ts +63 -0
  196. package/dist/esm/components/search-button/CSearchButton.js +123 -0
  197. package/dist/esm/components/search-button/CSearchButton.js.map +1 -0
  198. package/dist/esm/components/search-button/index.d.ts +6 -0
  199. package/dist/esm/components/search-button/index.js +10 -0
  200. package/dist/esm/components/search-button/index.js.map +1 -0
  201. package/dist/esm/components/search-button/types.d.ts +10 -0
  202. package/dist/esm/components/search-button/utils.d.ts +11 -0
  203. package/dist/esm/components/search-button/utils.js +103 -0
  204. package/dist/esm/components/search-button/utils.js.map +1 -0
  205. package/dist/esm/components/sidebar/CSidebar.js +4 -3
  206. package/dist/esm/components/sidebar/CSidebar.js.map +1 -1
  207. package/dist/esm/components/sidebar/CSidebarNav.d.ts +32 -0
  208. package/dist/esm/components/sidebar/CSidebarNav.js +29 -25
  209. package/dist/esm/components/sidebar/CSidebarNav.js.map +1 -1
  210. package/dist/esm/components/spinner/CSpinner.d.ts +4 -4
  211. package/dist/esm/components/spinner/CSpinner.js +2 -2
  212. package/dist/esm/components/spinner/CSpinner.js.map +1 -1
  213. package/dist/esm/components/table/utils.js +4 -4
  214. package/dist/esm/components/table/utils.js.map +1 -1
  215. package/dist/esm/components/tabs/CTabList.js +8 -2
  216. package/dist/esm/components/tabs/CTabList.js.map +1 -1
  217. package/dist/esm/components/tabs/CTabs.js +1 -1
  218. package/dist/esm/components/tabs/CTabs.js.map +1 -1
  219. package/dist/esm/components/toast/CToast.js +12 -2
  220. package/dist/esm/components/toast/CToast.js.map +1 -1
  221. package/dist/esm/components/toast/CToastClose.d.ts +3 -2
  222. package/dist/esm/components/toast/CToastClose.js +2 -3
  223. package/dist/esm/components/toast/CToastClose.js.map +1 -1
  224. package/dist/esm/components/tooltip/CTooltip.d.ts +24 -1
  225. package/dist/esm/components/tooltip/CTooltip.js +18 -1
  226. package/dist/esm/components/tooltip/CTooltip.js.map +1 -1
  227. package/dist/esm/directives/v-c-popover.js +6 -3
  228. package/dist/esm/directives/v-c-popover.js.map +1 -1
  229. package/dist/esm/directives/v-c-tooltip.js +6 -3
  230. package/dist/esm/directives/v-c-tooltip.js.map +1 -1
  231. package/dist/esm/directives/v-c-visible.js +1 -1
  232. package/dist/esm/directives/v-c-visible.js.map +1 -1
  233. package/dist/esm/index.js +3 -0
  234. package/dist/esm/index.js.map +1 -1
  235. package/dist/esm/node_modules/@coreui/icons/dist/esm/free/cil-arrow-bottom.js +1 -1
  236. package/dist/esm/node_modules/@coreui/icons/dist/esm/free/cil-arrow-bottom.js.map +1 -1
  237. package/dist/esm/node_modules/@coreui/icons/dist/esm/free/cil-arrow-top.js +1 -1
  238. package/dist/esm/node_modules/@coreui/icons/dist/esm/free/cil-arrow-top.js.map +1 -1
  239. package/dist/esm/node_modules/@coreui/icons/dist/esm/free/cil-filter-x.js +1 -1
  240. package/dist/esm/node_modules/@coreui/icons/dist/esm/free/cil-filter-x.js.map +1 -1
  241. package/dist/esm/node_modules/@coreui/icons/dist/esm/free/cil-swap-vertical.js +1 -1
  242. package/dist/esm/node_modules/@coreui/icons/dist/esm/free/cil-swap-vertical.js.map +1 -1
  243. package/dist/esm/utils/index.d.ts +2 -1
  244. package/dist/esm/utils/swipe.d.ts +26 -0
  245. package/dist/esm/utils/swipe.js +90 -0
  246. package/dist/esm/utils/swipe.js.map +1 -0
  247. package/dist/esm/utils/transition.js.map +1 -1
  248. package/package.json +6 -6
  249. package/src/components/accordion/CAccordion.ts +2 -2
  250. package/src/components/accordion/CAccordionBody.ts +1 -1
  251. package/src/components/accordion/CAccordionButton.ts +1 -1
  252. package/src/components/accordion/CAccordionHeader.ts +2 -2
  253. package/src/components/accordion/__tests__/__snapshots__/CAccordionButton.spec.ts.snap +1 -1
  254. package/src/components/accordion/__tests__/__snapshots__/CAccordionHeader.spec.ts.snap +1 -1
  255. package/src/components/alert/CAlert.ts +3 -3
  256. package/src/components/alert/CAlertHeading.ts +1 -1
  257. package/src/components/alert/CAlertLink.ts +1 -1
  258. package/src/components/autocomplete/__tests__/CAutocomplete.spec.ts +5 -1
  259. package/src/components/autocomplete/__tests__/CAutocompleteOptions.spec.ts +8 -5
  260. package/src/components/avatar/CAvatar.ts +1 -1
  261. package/src/components/backdrop/CBackdrop.ts +1 -1
  262. package/src/components/badge/CBadge.ts +1 -1
  263. package/src/components/breadcrumb/CBreadcrumb.ts +1 -1
  264. package/src/components/breadcrumb/CBreadcrumbItem.ts +1 -1
  265. package/src/components/button/CButton.ts +1 -1
  266. package/src/components/button/__tests__/CButton.spec.ts +0 -1
  267. package/src/components/button/__tests__/__snapshots__/CButton.spec.ts.snap +1 -1
  268. package/src/components/button-group/CButtonGroup.ts +1 -1
  269. package/src/components/callout/CCallout.ts +1 -1
  270. package/src/components/card/CCard.ts +1 -1
  271. package/src/components/card/CCardImage.ts +1 -1
  272. package/src/components/card/CCardLink.ts +1 -1
  273. package/src/components/carousel/CCarousel.ts +61 -22
  274. package/src/components/carousel/CCarouselCaption.ts +1 -1
  275. package/src/components/carousel/CCarouselItem.ts +5 -4
  276. package/src/components/carousel/__tests__/CCarousel.spec.ts +1 -1
  277. package/src/components/chip/CChip.ts +123 -101
  278. package/src/components/chip/__tests__/CChip.spec.ts +26 -0
  279. package/src/components/chip/const.ts +3 -0
  280. package/src/components/chip-input/CChipInput.ts +134 -82
  281. package/src/components/chip-input/__tests__/CChipInput.spec.ts +80 -4
  282. package/src/components/chip-input/__tests__/__snapshots__/CChipInput.spec.ts.snap +1 -1
  283. package/src/components/chip-set/CChipSet.ts +140 -0
  284. package/src/components/chip-set/__tests__/CChipSet.spec.ts +174 -0
  285. package/src/components/chip-set/buildChips.ts +29 -0
  286. package/src/components/chip-set/index.ts +3 -0
  287. package/src/components/chip-set/useChipSet.ts +168 -0
  288. package/src/components/collapse/CCollapse.ts +5 -5
  289. package/src/components/collapse/__tests__/CCollapse.spec.ts +48 -0
  290. package/src/components/collapse/__tests__/__snapshots__/CCollapse.spec.ts.snap +7 -0
  291. package/src/components/conditional-teleport/CConditionalTeleport.ts +3 -3
  292. package/src/components/conditional-teleport/__tests__/CConditionalTeleport.spec.ts +28 -0
  293. package/src/components/dropdown/CDropdown.ts +43 -23
  294. package/src/components/dropdown/CDropdownHeader.ts +1 -1
  295. package/src/components/dropdown/CDropdownItem.ts +1 -1
  296. package/src/components/dropdown/CDropdownMenu.ts +2 -2
  297. package/src/components/dropdown/CDropdownToggle.ts +4 -4
  298. package/src/components/dropdown/__tests__/CDropdown.spec.ts +1 -1
  299. package/src/components/dropdown/__tests__/CDropdownMenu.spec.ts +11 -7
  300. package/src/components/dropdown/__tests__/CDropdownPopperConfig.spec.ts +63 -0
  301. package/src/components/dropdown/__tests__/CDropdownToggle.spec.ts +0 -2
  302. package/src/components/dropdown/__tests__/__snapshots__/CDropdown.spec.ts.snap +1 -1
  303. package/src/components/dropdown/__tests__/__snapshots__/CDropdownMenu.spec.ts.snap +4 -0
  304. package/src/components/dropdown/utils.ts +2 -2
  305. package/src/components/focus-trap/CFocusTrap.ts +9 -6
  306. package/src/components/focus-trap/__tests__/CFocusTrap.spec.ts +42 -0
  307. package/src/components/footer/CFooter.ts +1 -1
  308. package/src/components/form/CForm.ts +1 -1
  309. package/src/components/form/CFormCheck.ts +5 -5
  310. package/src/components/form/CFormControlValidation.ts +3 -3
  311. package/src/components/form/CFormFeedback.ts +1 -1
  312. package/src/components/form/CFormFloating.ts +1 -1
  313. package/src/components/form/CFormInput.ts +2 -2
  314. package/src/components/form/CFormLabel.ts +1 -1
  315. package/src/components/form/CFormRange.ts +4 -4
  316. package/src/components/form/CFormSelect.ts +3 -3
  317. package/src/components/form/CFormSwitch.ts +2 -2
  318. package/src/components/form/CFormTextarea.ts +2 -2
  319. package/src/components/form/CInputGroup.ts +1 -1
  320. package/src/components/form/__tests__/CFormRange.spec.ts +2 -2
  321. package/src/components/form/__tests__/CFormText.spec.ts +1 -1
  322. package/src/components/form/__tests__/__snapshots__/CFormRange.spec.ts.snap +1 -1
  323. package/src/components/grid/CCol.ts +1 -1
  324. package/src/components/grid/CContainer.ts +4 -2
  325. package/src/components/grid/CRow.ts +1 -1
  326. package/src/components/header/CHeader.ts +2 -2
  327. package/src/components/header/CHeaderNav.ts +1 -1
  328. package/src/components/header/CHeaderToggler.ts +1 -1
  329. package/src/components/header/__tests__/CHeader.spec.ts +1 -2
  330. package/src/components/index.ts +2 -0
  331. package/src/components/link/CLink.ts +1 -1
  332. package/src/components/list-group/CListGroup.ts +1 -1
  333. package/src/components/list-group/CListGroupItem.ts +1 -1
  334. package/src/components/modal/CModal.ts +3 -2
  335. package/src/components/modal/CModalHeader.ts +10 -3
  336. package/src/components/modal/__tests__/__snapshots__/CModal.spec.ts.snap +9 -4
  337. package/src/components/multi-select/CMultiSelect.ts +380 -41
  338. package/src/components/multi-select/CMultiSelectNativeSelect.ts +1 -2
  339. package/src/components/multi-select/CMultiSelectOptions.ts +77 -3
  340. package/src/components/multi-select/CMultiSelectSelection.ts +6 -1
  341. package/src/components/nav/CNav.ts +9 -2
  342. package/src/components/nav/CNavGroup.ts +147 -99
  343. package/src/components/nav/CNavItem.ts +2 -2
  344. package/src/components/nav/CNavLink.ts +19 -2
  345. package/src/components/nav/__tests__/CNavGroup.spec.ts +188 -6
  346. package/src/components/nav/__tests__/CNavItem.spec.ts +6 -6
  347. package/src/components/nav/__tests__/__snapshots__/CNavGroup.spec.ts.snap +3 -7
  348. package/src/components/nav/__tests__/__snapshots__/CNavItem.spec.ts.snap +1 -5
  349. package/src/components/navbar/CNavbar.ts +2 -2
  350. package/src/components/navbar/CNavbarBrand.ts +1 -1
  351. package/src/components/navbar/CNavbarNav.ts +1 -1
  352. package/src/components/navbar/CNavbarToggler.ts +1 -1
  353. package/src/components/navbar/__tests__/CNavbar.spec.ts +1 -1
  354. package/src/components/pagination/CPagination.ts +2 -2
  355. package/src/components/pagination/CPaginationItem.ts +2 -2
  356. package/src/components/placeholder/CPlaceholder.ts +1 -1
  357. package/src/components/popover/CPopover.ts +27 -7
  358. package/src/components/popover/__tests__/CPopover.spec.ts +43 -0
  359. package/src/components/progress/CProgress.ts +2 -2
  360. package/src/components/progress/CProgressBar.ts +1 -1
  361. package/src/components/progress/CProgressStacked.ts +1 -1
  362. package/src/components/progress/__tests__/CProgressBar.spec.ts +0 -4
  363. package/src/components/search-button/CSearchButton.ts +163 -0
  364. package/src/components/search-button/__tests__/CSearchButton.spec.ts +128 -0
  365. package/src/components/search-button/__tests__/__snapshots__/CSearchButton.spec.ts.snap +13 -0
  366. package/src/components/search-button/index.ts +10 -0
  367. package/src/components/search-button/types.ts +10 -0
  368. package/src/components/search-button/utils.ts +140 -0
  369. package/src/components/sidebar/CSidebar.ts +9 -6
  370. package/src/components/sidebar/CSidebarBrand.ts +1 -1
  371. package/src/components/sidebar/CSidebarNav.ts +30 -28
  372. package/src/components/sidebar/__tests__/CSidebar.spec.ts +1 -1
  373. package/src/components/spinner/CSpinner.ts +6 -6
  374. package/src/components/spinner/__tests__/CSpinner.spec.ts +0 -1
  375. package/src/components/stepper/__tests__/CStepper.spec.ts +13 -8
  376. package/src/components/table/CTable.ts +16 -16
  377. package/src/components/table/CTableBody.ts +1 -1
  378. package/src/components/table/CTableDataCell.ts +1 -1
  379. package/src/components/table/CTableFoot.ts +1 -1
  380. package/src/components/table/CTableHead.ts +1 -1
  381. package/src/components/table/CTableHeaderCell.ts +1 -1
  382. package/src/components/table/CTableRow.ts +1 -1
  383. package/src/components/table/types.ts +1 -0
  384. package/src/components/table/utils.ts +4 -4
  385. package/src/components/tabs/CTab.ts +1 -1
  386. package/src/components/tabs/CTabList.ts +12 -5
  387. package/src/components/tabs/CTabPane.ts +3 -3
  388. package/src/components/tabs/CTabPanel.ts +5 -5
  389. package/src/components/tabs/CTabs.ts +2 -2
  390. package/src/components/tabs/__tests__/__snapshots__/CTabPane.spec.ts.snap +1 -1
  391. package/src/components/toast/CToast.ts +12 -4
  392. package/src/components/toast/CToastClose.ts +5 -6
  393. package/src/components/toast/CToaster.ts +1 -1
  394. package/src/components/toast/__tests__/CToaster.spec.ts +0 -2
  395. package/src/components/toast/__tests__/__snapshots__/CToastClose.spec.ts.snap +1 -1
  396. package/src/components/tooltip/CTooltip.ts +26 -6
  397. package/src/components/tooltip/__tests__/CTooltip.spec.ts +43 -0
  398. package/src/components/widgets/CWidgetStatsA.ts +4 -4
  399. package/src/components/widgets/CWidgetStatsB.ts +5 -5
  400. package/src/components/widgets/CWidgetStatsC.ts +5 -5
  401. package/src/components/widgets/CWidgetStatsD.ts +5 -5
  402. package/src/components/widgets/CWidgetStatsE.ts +4 -4
  403. package/src/components/widgets/CWidgetStatsF.ts +5 -5
  404. package/src/directives/__tests__/v-c-placeholder.spec.ts +33 -0
  405. package/src/directives/__tests__/v-c-popover.spec.ts +67 -0
  406. package/src/directives/__tests__/v-c-tooltip.spec.ts +66 -0
  407. package/src/directives/v-c-popover.ts +8 -5
  408. package/src/directives/v-c-tooltip.ts +8 -5
  409. package/src/directives/v-c-visible.ts +1 -1
  410. package/src/index.ts +1 -1
  411. package/src/utils/ComponentProps.ts +1 -0
  412. package/src/utils/__tests__/swipe.spec.ts +82 -0
  413. package/src/utils/getNextActiveElement.ts +1 -1
  414. package/src/utils/index.ts +2 -0
  415. package/src/utils/swipe.ts +114 -0
  416. package/src/utils/transition.ts +2 -2
  417. package/dist/cjs/components/collapse/__test__/CCollapse.spec.d.ts +0 -1
  418. package/dist/esm/components/collapse/__test__/CCollapse.spec.d.ts +0 -1
  419. package/src/components/accordion/__tests__/CAccordionCollapse.spec.ts +0 -28
  420. package/src/components/accordion/__tests__/__snapshots__/CAccordionCollapse.spec.ts.snap +0 -7
  421. package/src/components/collapse/__test__/CCollapse.spec.ts +0 -44
  422. package/src/components/collapse/__test__/__snapshots__/CCollapse.spec.ts.snap +0 -13
@@ -1,16 +1,53 @@
1
- import { computed, defineComponent, h, ref, watch, PropType } from 'vue'
1
+ import { computed, defineComponent, h, ref, useId, PropType, type VNode } from 'vue'
2
2
 
3
- import { CChip } from '../chip/CChip'
3
+ import { chipsFromData } from '../chip-set/buildChips'
4
+ import { useChipSet, type ChipSetConfig } from '../chip-set/useChipSet'
5
+ import { isRTL } from '../../utils'
4
6
 
5
7
  type ChipClassName = string | ((value: string) => string)
6
8
 
9
+ // Initial chip values can be supplied declaratively as CChip slot content
10
+ // (parity with the vanilla ChipInput, which reads existing .chip elements).
11
+ const slotText = (slot: unknown): string | undefined => {
12
+ if (typeof slot !== 'function') {
13
+ return undefined
14
+ }
15
+
16
+ const rendered = slot()
17
+ const first = Array.isArray(rendered) ? rendered[0] : rendered
18
+ if (typeof first === 'string') {
19
+ return first
20
+ }
21
+
22
+ return typeof first?.children === 'string' ? first.children : undefined
23
+ }
24
+
25
+ const valuesFromSlot = (nodes: VNode[] = []): string[] => {
26
+ const values: string[] = []
27
+ for (const node of nodes) {
28
+ if (Array.isArray(node.children)) {
29
+ values.push(...valuesFromSlot(node.children as VNode[]))
30
+ continue
31
+ }
32
+
33
+ const value =
34
+ (node.props?.value as string | undefined) ??
35
+ slotText((node.children as { default?: unknown } | null)?.default)
36
+ if (value) {
37
+ values.push(value)
38
+ }
39
+ }
40
+
41
+ return values
42
+ }
43
+
7
44
  const uniqueValues = (values: string[]): string[] => [
8
45
  ...new Set(values.map((value) => value.trim()).filter(Boolean)),
9
46
  ]
10
47
 
11
48
  const resolveChipClassName = (
12
49
  chipClassName: ChipClassName | undefined,
13
- value: string,
50
+ value: string
14
51
  ): string | undefined => {
15
52
  if (!chipClassName) {
16
53
  return undefined
@@ -52,6 +89,10 @@ const CChipInput = defineComponent({
52
89
  * Toggle the disabled state for the component.
53
90
  */
54
91
  disabled: Boolean,
92
+ /**
93
+ * Renders the chips as filter chips, each showing a leading check icon while selected. Implies `selectable`.
94
+ */
95
+ filter: Boolean,
55
96
  /**
56
97
  * Sets the `id` of the internal text input rendered by the component.
57
98
  */
@@ -100,6 +141,15 @@ const CChipInput = defineComponent({
100
141
  * Enables chip selection behavior in the component.
101
142
  */
102
143
  selectable: Boolean,
144
+ /**
145
+ * Sets how many chips can be selected at once.
146
+ *
147
+ * @values 'single', 'multiple'
148
+ */
149
+ selectionMode: {
150
+ type: String as PropType<'single' | 'multiple'>,
151
+ default: 'multiple',
152
+ },
103
153
  /**
104
154
  * Sets the separator character used to create chips while typing or pasting in the component.
105
155
  */
@@ -145,21 +195,39 @@ const CChipInput = defineComponent({
145
195
  */
146
196
  'update:modelValue',
147
197
  ],
148
- setup(props, { attrs, emit, expose }) {
149
- const internalValues = ref<string[]>(uniqueValues(props.defaultValue))
198
+ setup(props, { attrs, emit, expose, slots }) {
199
+ const internalValues = ref<string[]>(
200
+ uniqueValues(
201
+ props.defaultValue.length > 0 ? props.defaultValue : valuesFromSlot(slots.default?.())
202
+ )
203
+ )
150
204
  const inputValue = ref('')
151
- const selectedValues = ref<string[]>([])
152
- const rootRef = ref<HTMLDivElement>()
153
205
  const inputRef = ref<HTMLInputElement>()
206
+ const generatedName = useId()
154
207
 
155
208
  const values = computed(() =>
156
- props.modelValue !== undefined
157
- ? uniqueValues(props.modelValue as string[])
158
- : uniqueValues(internalValues.value)
209
+ props.modelValue === undefined
210
+ ? uniqueValues(internalValues.value)
211
+ : uniqueValues(props.modelValue as string[])
159
212
  )
160
213
 
161
- watch(values, (newValues) => {
162
- selectedValues.value = selectedValues.value.filter((item) => newValues.includes(item))
214
+ // CChipInput builds on the same engine as CChipSet: useChipSet owns selection
215
+ // coordination, roving focus, and chip prop forwarding (provided to the chips
216
+ // below). CChipInput owns the chip list and adds the text-input layer.
217
+ const config = computed<ChipSetConfig>(() => ({
218
+ disabled: props.disabled,
219
+ filter: props.filter,
220
+ removable: Boolean(props.removable && !props.disabled && !props.readOnly),
221
+ selectable: props.selectable,
222
+ }))
223
+
224
+ const { rootRef, clearSelection, getFocusableChips, handleKeydown } = useChipSet({
225
+ config,
226
+ selectionMode: () => props.selectionMode,
227
+ selected: () => undefined,
228
+ restoreFocusOnRemove: false,
229
+ onSelectionChange: (selected) => emit('select', selected),
230
+ onRemove: (value) => remove(value),
163
231
  })
164
232
 
165
233
  const emitValuesChange = (nextValues: string[]): void => {
@@ -172,7 +240,7 @@ const CChipInput = defineComponent({
172
240
  }
173
241
 
174
242
  const canAddMore = computed(
175
- () => props.maxChips === null || values.value.length < props.maxChips,
243
+ () => props.maxChips === null || values.value.length < props.maxChips
176
244
  )
177
245
 
178
246
  const add = (rawValue: string): boolean => {
@@ -200,16 +268,10 @@ const CChipInput = defineComponent({
200
268
  return false
201
269
  }
202
270
 
203
- const nextValues = values.value.filter((item) => item !== valueToRemove)
204
- emitValuesChange(nextValues)
205
- selectedValues.value = selectedValues.value.filter((item) => {
206
- const wasSelected = item === valueToRemove
207
- if (wasSelected && selectedValues.value.length !== nextValues.length) {
208
- emit('select', selectedValues.value.filter((v) => v !== valueToRemove))
209
- }
210
- return item !== valueToRemove
211
- })
271
+ // Selection is cleaned up by useChipSet; here we just drop the value.
272
+ emitValuesChange(values.value.filter((item) => item !== valueToRemove))
212
273
  emit('remove', valueToRemove)
274
+ inputRef.value?.focus()
213
275
  return true
214
276
  }
215
277
 
@@ -220,19 +282,8 @@ const CChipInput = defineComponent({
220
282
  }
221
283
 
222
284
  const focusLastChip = (): void => {
223
- if (!rootRef.value) {
224
- return
225
- }
226
-
227
- const focusableChips = [
228
- ...rootRef.value.querySelectorAll<HTMLElement>(
229
- '[data-coreui-chip-focusable="true"]:not(.disabled)',
230
- ),
231
- ]
232
- if (focusableChips.length === 0) {
233
- return
234
- }
235
- focusableChips[focusableChips.length - 1].focus()
285
+ const chips = getFocusableChips()
286
+ chips[chips.length - 1]?.focus()
236
287
  }
237
288
 
238
289
  const handleInputKeydown = (event: KeyboardEvent): void => {
@@ -252,9 +303,17 @@ const CChipInput = defineComponent({
252
303
  break
253
304
  }
254
305
 
255
- case 'ArrowLeft': {
306
+ case 'ArrowLeft':
307
+ case 'ArrowRight': {
308
+ // The arrow pointing toward the chips (left in LTR, right in RTL) jumps
309
+ // to the last chip when the caret is at the start of the input.
310
+ const towardChipsKey = isRTL(rootRef.value) ? 'ArrowRight' : 'ArrowLeft'
256
311
  const target = event.currentTarget as HTMLInputElement
257
- if (target.selectionStart === 0 && target.selectionEnd === 0) {
312
+ if (
313
+ event.key === towardChipsKey &&
314
+ target.selectionStart === 0 &&
315
+ target.selectionEnd === 0
316
+ ) {
258
317
  event.preventDefault()
259
318
  focusLastChip()
260
319
  }
@@ -280,13 +339,14 @@ const CChipInput = defineComponent({
280
339
  const parts = value.split(props.separator)
281
340
  const chipsToAdd = uniqueValues(parts.slice(0, -1))
282
341
 
283
- const newChips = chipsToAdd.filter(chip => !values.value.includes(chip))
284
- const availableSlots = props.maxChips !== null ? props.maxChips - values.value.length : Infinity
342
+ const newChips = chipsToAdd.filter((chip) => !values.value.includes(chip))
343
+ const availableSlots =
344
+ props.maxChips === null ? Infinity : props.maxChips - values.value.length
285
345
  const chipsToEmit = newChips.slice(0, availableSlots)
286
346
 
287
347
  if (chipsToEmit.length > 0) {
288
348
  const nextValues = [...values.value, ...chipsToEmit]
289
- chipsToEmit.forEach(chip => emit('add', chip))
349
+ chipsToEmit.forEach((chip) => emit('add', chip))
290
350
  emitValuesChange(nextValues)
291
351
  }
292
352
 
@@ -313,13 +373,14 @@ const CChipInput = defineComponent({
313
373
  event.preventDefault()
314
374
  const chipsToAdd = uniqueValues(pastedData.split(props.separator))
315
375
 
316
- const newChips = chipsToAdd.filter(chip => !values.value.includes(chip))
317
- const availableSlots = props.maxChips !== null ? props.maxChips - values.value.length : Infinity
376
+ const newChips = chipsToAdd.filter((chip) => !values.value.includes(chip))
377
+ const availableSlots =
378
+ props.maxChips === null ? Infinity : props.maxChips - values.value.length
318
379
  const chipsToEmit = newChips.slice(0, availableSlots)
319
380
 
320
381
  if (chipsToEmit.length > 0) {
321
382
  const nextValues = [...values.value, ...chipsToEmit]
322
- chipsToEmit.forEach(chip => emit('add', chip))
383
+ chipsToEmit.forEach((chip) => emit('add', chip))
323
384
  emitValuesChange(nextValues)
324
385
  }
325
386
 
@@ -344,6 +405,21 @@ const CChipInput = defineComponent({
344
405
  return
345
406
  }
346
407
 
408
+ // The arrow past the last chip moves focus into the text field (mirrored in RTL).
409
+ if (event.key === (isRTL(rootRef.value) ? 'ArrowLeft' : 'ArrowRight')) {
410
+ const chips = getFocusableChips()
411
+ const lastChip = chips[chips.length - 1]
412
+ if (lastChip?.contains(event.target as Node)) {
413
+ event.preventDefault()
414
+ inputRef.value?.focus()
415
+ return
416
+ }
417
+ }
418
+
419
+ if (handleKeydown(event)) {
420
+ return
421
+ }
422
+
347
423
  if (event.key.length === 1) {
348
424
  inputRef.value?.focus()
349
425
  }
@@ -355,13 +431,6 @@ const CChipInput = defineComponent({
355
431
  }
356
432
  }
357
433
 
358
- const handleSelectedChange = (chipValue: string, selected: boolean): void => {
359
- selectedValues.value = selected
360
- ? uniqueValues([...selectedValues.value, chipValue])
361
- : selectedValues.value.filter((value) => value !== chipValue)
362
- emit('select', selectedValues.value)
363
- }
364
-
365
434
  expose({ rootRef, inputRef })
366
435
 
367
436
  return () => {
@@ -375,26 +444,15 @@ const CChipInput = defineComponent({
375
444
  class: 'chip-input-label',
376
445
  for: props.id,
377
446
  },
378
- props.label,
379
- ),
380
- ...values.value.map((chipValue) =>
381
- h(
382
- CChip,
383
- {
384
- ariaRemoveLabel: `Remove ${chipValue}`,
385
- class: resolveChipClassName(props.chipClassName, chipValue),
386
- disabled: props.disabled,
387
- key: chipValue,
388
- onRemove: () => remove(chipValue),
389
- onSelectedChange: (selected: boolean) => handleSelectedChange(chipValue, selected),
390
- removable: Boolean(props.removable && !props.disabled && !props.readOnly),
391
- selectable: props.selectable,
392
- selected: selectedValues.value.includes(chipValue),
393
- },
394
- {
395
- default: () => chipValue,
396
- },
447
+ props.label
397
448
  ),
449
+ ...chipsFromData(
450
+ values.value.map((chipValue) => ({
451
+ value: chipValue,
452
+ label: chipValue,
453
+ ariaRemoveLabel: `Remove ${chipValue}`,
454
+ class: resolveChipClassName(props.chipClassName, chipValue),
455
+ }))
398
456
  ),
399
457
  h('input', {
400
458
  ref: inputRef,
@@ -410,19 +468,13 @@ const CChipInput = defineComponent({
410
468
  onInput: (event: Event) => handleInputChange((event.target as HTMLInputElement).value),
411
469
  onKeydown: handleInputKeydown,
412
470
  onPaste: handlePaste,
413
- onFocus: () => {
414
- if (selectedValues.value.length > 0) {
415
- selectedValues.value = []
416
- emit('select', [])
417
- }
418
- },
471
+ onFocus: clearSelection,
472
+ }),
473
+ h('input', {
474
+ type: 'hidden',
475
+ name: props.name ?? generatedName,
476
+ value: values.value.join(','),
419
477
  }),
420
- props.name &&
421
- h('input', {
422
- type: 'hidden',
423
- name: props.name,
424
- value: values.value.join(','),
425
- }),
426
478
  ].filter(Boolean)
427
479
 
428
480
  return h(
@@ -442,7 +494,7 @@ const CChipInput = defineComponent({
442
494
  onClick: handleContainerClick,
443
495
  onKeydown: handleContainerKeydown,
444
496
  },
445
- children,
497
+ children
446
498
  )
447
499
  }
448
500
  },
@@ -1,5 +1,6 @@
1
1
  import { mount } from '@vue/test-utils'
2
- import { CChipInput } from '../../../index'
2
+ import { h } from 'vue'
3
+ import { CChip, CChipInput } from '../../../index'
3
4
 
4
5
  describe('CChipInput', () => {
5
6
  it('has correct name', () => {
@@ -185,6 +186,18 @@ describe('CChipInput', () => {
185
186
  expect(hiddenInput.attributes('value')).toBe('tag1,tag2')
186
187
  })
187
188
 
189
+ it('always renders a hidden input even without a name', () => {
190
+ const wrapper = mount(CChipInput, {
191
+ props: {
192
+ modelValue: ['tag1'],
193
+ },
194
+ })
195
+ const hiddenInput = wrapper.find('input[type="hidden"]')
196
+ expect(hiddenInput.exists()).toBe(true)
197
+ expect(hiddenInput.attributes('name')).toBeTruthy()
198
+ expect(hiddenInput.attributes('value')).toBe('tag1')
199
+ })
200
+
188
201
  it('applies size classes', () => {
189
202
  const wrapperSm = mount(CChipInput, {
190
203
  props: {
@@ -268,7 +281,26 @@ describe('CChipInput', () => {
268
281
  })
269
282
 
270
283
  const chips = wrapper.findAllComponents({ name: 'CChip' })
271
- expect(chips[0].props('selectable')).toBe(true)
284
+ // CChipInput forwards `selectable` to chips through the shared set config, not as a prop, so
285
+ // the chips are selectable in effect—`aria-selected` is only rendered for a selectable chip.
286
+ expect(chips[0].attributes('aria-selected')).toBe('false')
287
+ })
288
+
289
+ it('single selection deselects siblings', async () => {
290
+ const wrapper = mount(CChipInput, {
291
+ props: {
292
+ selectable: true,
293
+ selectionMode: 'single',
294
+ modelValue: ['a', 'b'],
295
+ },
296
+ })
297
+
298
+ const chips = wrapper.findAll('.chip')
299
+ await chips[0].trigger('click')
300
+ await chips[1].trigger('click')
301
+
302
+ expect(chips[0].classes()).not.toContain('active')
303
+ expect(chips[1].classes()).toContain('active')
272
304
  })
273
305
 
274
306
  it('handles paste with separator', async () => {
@@ -307,10 +339,9 @@ describe('CChipInput', () => {
307
339
  })
308
340
 
309
341
  it('applies chipClassName as function', async () => {
310
- const classNameFn = (value: string) => `chip-${value}`
311
342
  const wrapper = mount(CChipInput, {
312
343
  props: {
313
- chipClassName: classNameFn,
344
+ chipClassName: (value: string) => `chip-${value}`,
314
345
  modelValue: ['primary', 'secondary'],
315
346
  },
316
347
  })
@@ -364,4 +395,49 @@ describe('CChipInput', () => {
364
395
  const removeBtn = wrapper.find('.chip-remove')
365
396
  expect(removeBtn.exists()).toBe(false)
366
397
  })
398
+
399
+ it('moves focus to the input on ArrowRight from the last chip', async () => {
400
+ const wrapper = mount(CChipInput, {
401
+ attachTo: document.body,
402
+ props: { defaultValue: ['React', 'Vue'] },
403
+ })
404
+ const chips = wrapper.findAll('.chip')
405
+ const lastChip = chips[chips.length - 1]
406
+ const input = wrapper.find('input.chip-input-field').element as HTMLInputElement
407
+ ;(lastChip.element as HTMLElement).focus()
408
+ await lastChip.trigger('keydown', { key: 'ArrowRight' })
409
+ expect(document.activeElement).toBe(input)
410
+ wrapper.unmount()
411
+ })
412
+
413
+ it('moves focus to the input on ArrowLeft from the last chip in RTL', async () => {
414
+ document.documentElement.dir = 'rtl'
415
+ const wrapper = mount(CChipInput, {
416
+ attachTo: document.body,
417
+ props: { defaultValue: ['React', 'Vue'] },
418
+ })
419
+ const chips = wrapper.findAll('.chip')
420
+ const lastChip = chips[chips.length - 1]
421
+ const input = wrapper.find('input.chip-input-field').element as HTMLInputElement
422
+ ;(lastChip.element as HTMLElement).focus()
423
+ await lastChip.trigger('keydown', { key: 'ArrowLeft' })
424
+ expect(document.activeElement).toBe(input)
425
+ wrapper.unmount()
426
+ document.documentElement.dir = ''
427
+ })
428
+
429
+ it('seeds initial chips from CChip slot content', () => {
430
+ const wrapper = mount(CChipInput, {
431
+ slots: {
432
+ default: () => [
433
+ h(CChip, { value: 'React' }, { default: () => 'React' }),
434
+ h(CChip, { value: 'Vue' }, { default: () => 'Vue' }),
435
+ ],
436
+ },
437
+ })
438
+ const chips = wrapper.findAll('.chip')
439
+ expect(chips).toHaveLength(2)
440
+ expect(wrapper.text()).toContain('React')
441
+ expect(wrapper.text()).toContain('Vue')
442
+ })
367
443
  })
@@ -1,3 +1,3 @@
1
1
  // Jest Snapshot v1, https://goo.gl/fbAQLP
2
2
 
3
- exports[`CChipInput renders correctly 1`] = `"<div class="chip-input"><input type="text" class="chip-input-field" placeholder="" size="1" value=""></div>"`;
3
+ exports[`CChipInput renders correctly 1`] = `"<div class="chip-input"><input type="text" class="chip-input-field" placeholder="" size="1" value=""><input type="hidden" name="v-0" value=""></div>"`;
@@ -0,0 +1,140 @@
1
+ import { computed, defineComponent, h, PropType } from 'vue'
2
+
3
+ import { chipsFromData, type CChipSetItem } from './buildChips'
4
+ import { useChipSet, type ChipSetConfig } from './useChipSet'
5
+
6
+ export type { CChipSetItem }
7
+
8
+ const itemValue = (item: string | CChipSetItem): string =>
9
+ typeof item === 'string' ? item : item.value
10
+
11
+ const CChipSet = defineComponent({
12
+ name: 'CChipSet',
13
+ props: {
14
+ /**
15
+ * Component used for the root node. Either a string to use a HTML element or a component.
16
+ */
17
+ as: {
18
+ type: String,
19
+ default: 'div',
20
+ },
21
+ /**
22
+ * Renders chips from data instead of the default slot. Each item is a string or an object with a `value`, an optional `label`, and any `CChip` props. The slot is used when this is omitted.
23
+ */
24
+ chips: {
25
+ type: Array as PropType<(string | CChipSetItem)[]>,
26
+ default: undefined,
27
+ },
28
+ /**
29
+ * Disables every chip rendered by the component.
30
+ */
31
+ disabled: Boolean,
32
+ /**
33
+ * Turns the chips into filter chips, each showing a leading check icon while selected.
34
+ */
35
+ filter: Boolean,
36
+ /**
37
+ * Displays a remove button on every chip rendered by the component.
38
+ */
39
+ removable: Boolean,
40
+ /**
41
+ * Replaces the default remove icon on every chip with a custom icon node.
42
+ */
43
+ removeIcon: {
44
+ type: [String, Object],
45
+ default: undefined,
46
+ },
47
+ /**
48
+ * Enables selection behavior for the chips rendered by the component.
49
+ */
50
+ selectable: Boolean,
51
+ /**
52
+ * The selected chip values passed using `v-model:selected`.
53
+ */
54
+ selected: {
55
+ type: Array as PropType<string[]>,
56
+ default: undefined,
57
+ },
58
+ /**
59
+ * Replaces the default selected icon shown by filter chips with a custom icon node.
60
+ */
61
+ selectedIcon: {
62
+ type: [String, Object],
63
+ default: undefined,
64
+ },
65
+ /**
66
+ * Sets how many chips can be selected at once.
67
+ *
68
+ * @values 'single', 'multiple'
69
+ */
70
+ selectionMode: {
71
+ type: String as PropType<'single' | 'multiple'>,
72
+ default: 'multiple',
73
+ },
74
+ },
75
+ emits: [
76
+ /**
77
+ * Event occurs when a chip requests removal, with its value.
78
+ */
79
+ 'remove',
80
+ /**
81
+ * Event occurs when the selected chip values change.
82
+ */
83
+ 'select',
84
+ /**
85
+ * Emit the chips without the removed one (for `v-model:chips`).
86
+ */
87
+ 'update:chips',
88
+ /**
89
+ * Emit the new selected values whenever the selection changes (for `v-model:selected`).
90
+ */
91
+ 'update:selected',
92
+ ],
93
+ setup(props, { attrs, emit, slots, expose }) {
94
+ const config = computed<ChipSetConfig>(() => ({
95
+ disabled: props.disabled,
96
+ filter: props.filter,
97
+ removable: props.removable,
98
+ removeIcon: props.removeIcon,
99
+ selectable: props.selectable,
100
+ selectedIcon: props.selectedIcon,
101
+ }))
102
+
103
+ const { rootRef, handleKeydown } = useChipSet({
104
+ config,
105
+ selectionMode: () => props.selectionMode,
106
+ selected: () => props.selected,
107
+ onSelectionChange: (selected) => {
108
+ emit('update:selected', selected)
109
+ emit('select', selected)
110
+ },
111
+ onRemove: (value) => {
112
+ // With `v-model:chips` the parent stays in sync automatically; a one-way
113
+ // `:chips` binding ignores the update and handles removal via `@remove`.
114
+ if (props.chips) {
115
+ emit(
116
+ 'update:chips',
117
+ props.chips.filter((item) => itemValue(item) !== value)
118
+ )
119
+ }
120
+ emit('remove', value)
121
+ },
122
+ })
123
+
124
+ expose({ rootRef })
125
+
126
+ return () =>
127
+ h(
128
+ props.as,
129
+ {
130
+ ref: rootRef,
131
+ class: ['chip-set', { disabled: props.disabled }, attrs.class],
132
+ ...(props.disabled && { 'aria-disabled': true }),
133
+ onKeydown: handleKeydown,
134
+ },
135
+ props.chips ? chipsFromData(props.chips) : slots.default && slots.default()
136
+ )
137
+ },
138
+ })
139
+
140
+ export { CChipSet }