@milaboratories/uikit 2.15.37 → 2.15.38

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 (457) hide show
  1. package/.turbo/turbo-build.log +173 -173
  2. package/.turbo/turbo-formatter$colon$check.log +2 -2
  3. package/.turbo/turbo-linter$colon$check.log +2 -2
  4. package/.turbo/turbo-types$colon$check.log +1 -1
  5. package/CHANGELOG.md +6 -0
  6. package/dist/__tests__/default-testid.test.d.ts +2 -0
  7. package/dist/__tests__/default-testid.test.d.ts.map +1 -0
  8. package/dist/base/BtnBase.js.map +1 -1
  9. package/dist/base/BtnBase.vue.d.ts.map +1 -1
  10. package/dist/base/BtnBase.vue2.js +6 -1
  11. package/dist/base/BtnBase.vue2.js.map +1 -1
  12. package/dist/components/DropdownListItem.js.map +1 -1
  13. package/dist/components/DropdownListItem.vue.d.ts.map +1 -1
  14. package/dist/components/DropdownListItem.vue2.js +13 -4
  15. package/dist/components/DropdownListItem.vue2.js.map +1 -1
  16. package/dist/components/InputRange.js.map +1 -1
  17. package/dist/components/InputRange.vue.d.ts.map +1 -1
  18. package/dist/components/InputRange.vue2.js +10 -2
  19. package/dist/components/InputRange.vue2.js.map +1 -1
  20. package/dist/components/PlAccordion/PlAccordionSection.js.map +1 -1
  21. package/dist/components/PlAccordion/PlAccordionSection.style.js.map +1 -1
  22. package/dist/components/PlAccordion/PlAccordionSection.vue.d.ts.map +1 -1
  23. package/dist/components/PlAccordion/PlAccordionSection.vue2.js +7 -1
  24. package/dist/components/PlAccordion/PlAccordionSection.vue2.js.map +1 -1
  25. package/dist/components/PlAlert/PlAlert.js.map +1 -1
  26. package/dist/components/PlAlert/PlAlert.vue.d.ts.map +1 -1
  27. package/dist/components/PlAlert/PlAlert.vue2.js +10 -1
  28. package/dist/components/PlAlert/PlAlert.vue2.js.map +1 -1
  29. package/dist/components/PlAutocomplete/PlAutocomplete.js.map +1 -1
  30. package/dist/components/PlAutocomplete/PlAutocomplete.vue.d.ts.map +1 -1
  31. package/dist/components/PlAutocomplete/PlAutocomplete.vue2.js +29 -11
  32. package/dist/components/PlAutocomplete/PlAutocomplete.vue2.js.map +1 -1
  33. package/dist/components/PlAutocompleteMulti/PlAutocompleteMulti.js.map +1 -1
  34. package/dist/components/PlAutocompleteMulti/PlAutocompleteMulti.vue.d.ts.map +1 -1
  35. package/dist/components/PlAutocompleteMulti/PlAutocompleteMulti.vue2.js +30 -9
  36. package/dist/components/PlAutocompleteMulti/PlAutocompleteMulti.vue2.js.map +1 -1
  37. package/dist/components/PlBtnAccent/PlBtnAccent.js.map +1 -1
  38. package/dist/components/PlBtnAccent/PlBtnAccent.vue.d.ts.map +1 -1
  39. package/dist/components/PlBtnAccent/PlBtnAccent.vue2.js +4 -1
  40. package/dist/components/PlBtnAccent/PlBtnAccent.vue2.js.map +1 -1
  41. package/dist/components/PlBtnDanger/PlBtnDanger.js.map +1 -1
  42. package/dist/components/PlBtnDanger/PlBtnDanger.vue.d.ts.map +1 -1
  43. package/dist/components/PlBtnDanger/PlBtnDanger.vue2.js +4 -1
  44. package/dist/components/PlBtnDanger/PlBtnDanger.vue2.js.map +1 -1
  45. package/dist/components/PlBtnGhost/PlBtnGhost.js.map +1 -1
  46. package/dist/components/PlBtnGhost/PlBtnGhost.vue.d.ts.map +1 -1
  47. package/dist/components/PlBtnGhost/PlBtnGhost.vue2.js +7 -1
  48. package/dist/components/PlBtnGhost/PlBtnGhost.vue2.js.map +1 -1
  49. package/dist/components/PlBtnGroup/PlBtnGroup.js.map +1 -1
  50. package/dist/components/PlBtnGroup/PlBtnGroup.vue.d.ts.map +1 -1
  51. package/dist/components/PlBtnGroup/PlBtnGroup.vue2.js +19 -6
  52. package/dist/components/PlBtnGroup/PlBtnGroup.vue2.js.map +1 -1
  53. package/dist/components/PlBtnLink/PlBtnLink.js.map +1 -1
  54. package/dist/components/PlBtnLink/PlBtnLink.vue.d.ts.map +1 -1
  55. package/dist/components/PlBtnLink/PlBtnLink.vue2.js +2 -0
  56. package/dist/components/PlBtnLink/PlBtnLink.vue2.js.map +1 -1
  57. package/dist/components/PlBtnPrimary/PlBtnPrimary.js.map +1 -1
  58. package/dist/components/PlBtnPrimary/PlBtnPrimary.vue.d.ts.map +1 -1
  59. package/dist/components/PlBtnPrimary/PlBtnPrimary.vue2.js +4 -1
  60. package/dist/components/PlBtnPrimary/PlBtnPrimary.vue2.js.map +1 -1
  61. package/dist/components/PlBtnSecondary/PlBtnSecondary.js.map +1 -1
  62. package/dist/components/PlBtnSecondary/PlBtnSecondary.vue.d.ts.map +1 -1
  63. package/dist/components/PlBtnSecondary/PlBtnSecondary.vue2.js +1 -1
  64. package/dist/components/PlBtnSecondary/PlBtnSecondary.vue2.js.map +1 -1
  65. package/dist/components/PlBtnSplit/PlBtnSplit.js.map +1 -1
  66. package/dist/components/PlBtnSplit/PlBtnSplit.vue.d.ts.map +1 -1
  67. package/dist/components/PlBtnSplit/PlBtnSplit.vue2.js +6 -0
  68. package/dist/components/PlBtnSplit/PlBtnSplit.vue2.js.map +1 -1
  69. package/dist/components/PlChartHistogram/PlChartHistogram.js.map +1 -1
  70. package/dist/components/PlChartHistogram/PlChartHistogram.style.js.map +1 -1
  71. package/dist/components/PlChartHistogram/PlChartHistogram.vue.d.ts.map +1 -1
  72. package/dist/components/PlChartHistogram/PlChartHistogram.vue2.js +7 -2
  73. package/dist/components/PlChartHistogram/PlChartHistogram.vue2.js.map +1 -1
  74. package/dist/components/PlChartHistogram/createGridlines.d.ts.map +1 -1
  75. package/dist/components/PlChartHistogram/createGridlines.js +1 -1
  76. package/dist/components/PlChartHistogram/createGridlines.js.map +1 -1
  77. package/dist/components/PlChartHistogram/createLabels.d.ts.map +1 -1
  78. package/dist/components/PlChartHistogram/createLabels.js +1 -1
  79. package/dist/components/PlChartHistogram/createLabels.js.map +1 -1
  80. package/dist/components/PlChartHistogram/createSvgContainer.d.ts.map +1 -1
  81. package/dist/components/PlChartHistogram/createSvgContainer.js +1 -1
  82. package/dist/components/PlChartHistogram/createSvgContainer.js.map +1 -1
  83. package/dist/components/PlChartHistogram/drawBins.d.ts.map +1 -1
  84. package/dist/components/PlChartHistogram/drawBins.js +2 -2
  85. package/dist/components/PlChartHistogram/drawBins.js.map +1 -1
  86. package/dist/components/PlChartHistogram/drawThreshold.d.ts.map +1 -1
  87. package/dist/components/PlChartHistogram/drawThreshold.js +1 -1
  88. package/dist/components/PlChartHistogram/drawThreshold.js.map +1 -1
  89. package/dist/components/PlChartHistogram/histogram.d.ts.map +1 -1
  90. package/dist/components/PlChartHistogram/histogram.js +1 -1
  91. package/dist/components/PlChartHistogram/histogram.js.map +1 -1
  92. package/dist/components/PlChartStackedBar/Legends.js.map +1 -1
  93. package/dist/components/PlChartStackedBar/Legends.style.js.map +1 -1
  94. package/dist/components/PlChartStackedBar/Legends.vue.d.ts.map +1 -1
  95. package/dist/components/PlChartStackedBar/Legends.vue2.js +7 -1
  96. package/dist/components/PlChartStackedBar/Legends.vue2.js.map +1 -1
  97. package/dist/components/PlChartStackedBar/PlChartStackedBar.js.map +1 -1
  98. package/dist/components/PlChartStackedBar/PlChartStackedBar.style.js.map +1 -1
  99. package/dist/components/PlChartStackedBar/PlChartStackedBar.vue.d.ts.map +1 -1
  100. package/dist/components/PlChartStackedBar/PlChartStackedBar.vue2.js +5 -1
  101. package/dist/components/PlChartStackedBar/PlChartStackedBar.vue2.js.map +1 -1
  102. package/dist/components/PlChartStackedBar/PlChartStackedBarCompact.js.map +1 -1
  103. package/dist/components/PlChartStackedBar/PlChartStackedBarCompact.style.js.map +1 -1
  104. package/dist/components/PlChartStackedBar/PlChartStackedBarCompact.vue.d.ts.map +1 -1
  105. package/dist/components/PlChartStackedBar/PlChartStackedBarCompact.vue2.js +4 -1
  106. package/dist/components/PlChartStackedBar/PlChartStackedBarCompact.vue2.js.map +1 -1
  107. package/dist/components/PlChartStackedBar/StackedRow.js.map +1 -1
  108. package/dist/components/PlChartStackedBar/StackedRow.style.js.map +1 -1
  109. package/dist/components/PlChartStackedBar/StackedRow.vue.d.ts.map +1 -1
  110. package/dist/components/PlChartStackedBar/StackedRow.vue2.js +13 -3
  111. package/dist/components/PlChartStackedBar/StackedRow.vue2.js.map +1 -1
  112. package/dist/components/PlChartStackedBar/StackedRowCompact.js.map +1 -1
  113. package/dist/components/PlChartStackedBar/StackedRowCompact.style.js.map +1 -1
  114. package/dist/components/PlChartStackedBar/StackedRowCompact.vue.d.ts.map +1 -1
  115. package/dist/components/PlChartStackedBar/StackedRowCompact.vue2.js +8 -2
  116. package/dist/components/PlChartStackedBar/StackedRowCompact.vue2.js.map +1 -1
  117. package/dist/components/PlCheckbox/PlCheckbox.js.map +1 -1
  118. package/dist/components/PlCheckbox/PlCheckbox.vue.d.ts.map +1 -1
  119. package/dist/components/PlCheckbox/PlCheckbox.vue2.js +9 -2
  120. package/dist/components/PlCheckbox/PlCheckbox.vue2.js.map +1 -1
  121. package/dist/components/PlCheckbox/PlCheckboxBase.js.map +1 -1
  122. package/dist/components/PlCheckbox/PlCheckboxBase.vue.d.ts.map +1 -1
  123. package/dist/components/PlCheckbox/PlCheckboxBase.vue2.js +1 -0
  124. package/dist/components/PlCheckbox/PlCheckboxBase.vue2.js.map +1 -1
  125. package/dist/components/PlCheckboxGroup/PlCheckboxGroup.js.map +1 -1
  126. package/dist/components/PlCheckboxGroup/PlCheckboxGroup.vue.d.ts.map +1 -1
  127. package/dist/components/PlCheckboxGroup/PlCheckboxGroup.vue2.js +19 -5
  128. package/dist/components/PlCheckboxGroup/PlCheckboxGroup.vue2.js.map +1 -1
  129. package/dist/components/PlChip/PlChip.js.map +1 -1
  130. package/dist/components/PlChip/PlChip.vue.d.ts.map +1 -1
  131. package/dist/components/PlChip/PlChip.vue2.js +7 -1
  132. package/dist/components/PlChip/PlChip.vue2.js.map +1 -1
  133. package/dist/components/PlClipboard/PlClipboard.js.map +1 -1
  134. package/dist/components/PlClipboard/PlClipboard.style.js.map +1 -1
  135. package/dist/components/PlClipboard/PlClipboard.vue.d.ts.map +1 -1
  136. package/dist/components/PlClipboard/PlClipboard.vue2.js +1 -0
  137. package/dist/components/PlClipboard/PlClipboard.vue2.js.map +1 -1
  138. package/dist/components/PlConfirmDialog.js.map +1 -1
  139. package/dist/components/PlConfirmDialog.vue.d.ts.map +1 -1
  140. package/dist/components/PlConfirmDialog.vue2.js +9 -2
  141. package/dist/components/PlConfirmDialog.vue2.js.map +1 -1
  142. package/dist/components/PlDialogModal/PlDialogModal.js.map +1 -1
  143. package/dist/components/PlDialogModal/PlDialogModal.vue.d.ts.map +1 -1
  144. package/dist/components/PlDialogModal/PlDialogModal.vue2.js +12 -5
  145. package/dist/components/PlDialogModal/PlDialogModal.vue2.js.map +1 -1
  146. package/dist/components/PlDropdown/OptionList.js.map +1 -1
  147. package/dist/components/PlDropdown/OptionList.vue.d.ts.map +1 -1
  148. package/dist/components/PlDropdown/OptionList.vue2.js +11 -5
  149. package/dist/components/PlDropdown/OptionList.vue2.js.map +1 -1
  150. package/dist/components/PlDropdown/PlDropdown.js.map +1 -1
  151. package/dist/components/PlDropdown/PlDropdown.vue.d.ts.map +1 -1
  152. package/dist/components/PlDropdown/PlDropdown.vue2.js +26 -10
  153. package/dist/components/PlDropdown/PlDropdown.vue2.js.map +1 -1
  154. package/dist/components/PlDropdownLegacy/PlDropdownLegacy.js.map +1 -1
  155. package/dist/components/PlDropdownLegacy/PlDropdownLegacy.vue.d.ts.map +1 -1
  156. package/dist/components/PlDropdownLegacy/PlDropdownLegacy.vue2.js +32 -10
  157. package/dist/components/PlDropdownLegacy/PlDropdownLegacy.vue2.js.map +1 -1
  158. package/dist/components/PlDropdownLine/PlDropdownLine.js.map +1 -1
  159. package/dist/components/PlDropdownLine/PlDropdownLine.vue.d.ts.map +1 -1
  160. package/dist/components/PlDropdownLine/PlDropdownLine.vue2.js +17 -3
  161. package/dist/components/PlDropdownLine/PlDropdownLine.vue2.js.map +1 -1
  162. package/dist/components/PlDropdownLine/ResizableInput.js.map +1 -1
  163. package/dist/components/PlDropdownLine/ResizableInput.vue.d.ts.map +1 -1
  164. package/dist/components/PlDropdownLine/ResizableInput.vue2.js +5 -2
  165. package/dist/components/PlDropdownLine/ResizableInput.vue2.js.map +1 -1
  166. package/dist/components/PlDropdownMulti/PlDropdownMulti.js.map +1 -1
  167. package/dist/components/PlDropdownMulti/PlDropdownMulti.vue.d.ts.map +1 -1
  168. package/dist/components/PlDropdownMulti/PlDropdownMulti.vue2.js +31 -10
  169. package/dist/components/PlDropdownMulti/PlDropdownMulti.vue2.js.map +1 -1
  170. package/dist/components/PlDropdownMultiRef/PlDropdownMultiRef.js.map +1 -1
  171. package/dist/components/PlDropdownMultiRef/PlDropdownMultiRef.vue.d.ts.map +1 -1
  172. package/dist/components/PlDropdownMultiRef/PlDropdownMultiRef.vue2.js +1 -1
  173. package/dist/components/PlDropdownMultiRef/PlDropdownMultiRef.vue2.js.map +1 -1
  174. package/dist/components/PlDropdownRef/PlDropdownRef.js.map +1 -1
  175. package/dist/components/PlDropdownRef/PlDropdownRef.vue.d.ts.map +1 -1
  176. package/dist/components/PlDropdownRef/PlDropdownRef.vue2.js +1 -1
  177. package/dist/components/PlDropdownRef/PlDropdownRef.vue2.js.map +1 -1
  178. package/dist/components/PlEditableTitle/PlEditableTitle.js.map +1 -1
  179. package/dist/components/PlEditableTitle/PlEditableTitle.vue.d.ts.map +1 -1
  180. package/dist/components/PlEditableTitle/PlEditableTitle.vue2.js +9 -3
  181. package/dist/components/PlEditableTitle/PlEditableTitle.vue2.js.map +1 -1
  182. package/dist/components/PlElementList/PlElementList.js.map +1 -1
  183. package/dist/components/PlElementList/PlElementList.style.js.map +1 -1
  184. package/dist/components/PlElementList/PlElementList.vue.d.ts.map +1 -1
  185. package/dist/components/PlElementList/PlElementList.vue2.js +6 -1
  186. package/dist/components/PlElementList/PlElementList.vue2.js.map +1 -1
  187. package/dist/components/PlElementList/PlElementListItem.js.map +1 -1
  188. package/dist/components/PlElementList/PlElementListItem.style.js.map +1 -1
  189. package/dist/components/PlElementList/PlElementListItem.vue.d.ts.map +1 -1
  190. package/dist/components/PlElementList/PlElementListItem.vue2.js +34 -13
  191. package/dist/components/PlElementList/PlElementListItem.vue2.js.map +1 -1
  192. package/dist/components/PlErrorAlert/PlErrorAlert.js.map +1 -1
  193. package/dist/components/PlErrorAlert/PlErrorAlert.style.js.map +1 -1
  194. package/dist/components/PlErrorAlert/PlErrorAlert.vue.d.ts.map +1 -1
  195. package/dist/components/PlErrorAlert/PlErrorAlert.vue2.js +15 -3
  196. package/dist/components/PlErrorAlert/PlErrorAlert.vue2.js.map +1 -1
  197. package/dist/components/PlErrorBoundary/PlErrorBoundary.js.map +1 -1
  198. package/dist/components/PlErrorBoundary/PlErrorBoundary.vue.d.ts.map +1 -1
  199. package/dist/components/PlErrorBoundary/PlErrorBoundary.vue2.js +1 -0
  200. package/dist/components/PlErrorBoundary/PlErrorBoundary.vue2.js.map +1 -1
  201. package/dist/components/PlFileDialog/Local.js.map +1 -1
  202. package/dist/components/PlFileDialog/Local.vue.d.ts.map +1 -1
  203. package/dist/components/PlFileDialog/Local.vue2.js +23 -20
  204. package/dist/components/PlFileDialog/Local.vue2.js.map +1 -1
  205. package/dist/components/PlFileDialog/PlFileDialog.js.map +1 -1
  206. package/dist/components/PlFileDialog/PlFileDialog.vue.d.ts.map +1 -1
  207. package/dist/components/PlFileDialog/PlFileDialog.vue2.js +5 -1
  208. package/dist/components/PlFileDialog/PlFileDialog.vue2.js.map +1 -1
  209. package/dist/components/PlFileDialog/Remote.js.map +1 -1
  210. package/dist/components/PlFileDialog/Remote.vue.d.ts.map +1 -1
  211. package/dist/components/PlFileDialog/Remote.vue2.js +108 -94
  212. package/dist/components/PlFileDialog/Remote.vue2.js.map +1 -1
  213. package/dist/components/PlFileDialog/Shortcuts.js.map +1 -1
  214. package/dist/components/PlFileDialog/Shortcuts.style.js.map +1 -1
  215. package/dist/components/PlFileDialog/Shortcuts.vue.d.ts.map +1 -1
  216. package/dist/components/PlFileDialog/Shortcuts.vue2.js +2 -1
  217. package/dist/components/PlFileDialog/Shortcuts.vue2.js.map +1 -1
  218. package/dist/components/PlFileInput/PlFileInput.js.map +1 -1
  219. package/dist/components/PlFileInput/PlFileInput.vue.d.ts.map +1 -1
  220. package/dist/components/PlFileInput/PlFileInput.vue2.js +92 -71
  221. package/dist/components/PlFileInput/PlFileInput.vue2.js.map +1 -1
  222. package/dist/components/PlLoaderCircular/PlLoaderCircular.js.map +1 -1
  223. package/dist/components/PlLoaderCircular/PlLoaderCircular.vue.d.ts.map +1 -1
  224. package/dist/components/PlLoaderCircular/PlLoaderCircular.vue2.js +4 -1
  225. package/dist/components/PlLoaderCircular/PlLoaderCircular.vue2.js.map +1 -1
  226. package/dist/components/PlLoaderLogo.js.map +1 -1
  227. package/dist/components/PlLoaderLogo.style.js.map +1 -1
  228. package/dist/components/PlLoaderLogo.vue.css +1 -1
  229. package/dist/components/PlLoaderLogo.vue.d.ts.map +1 -1
  230. package/dist/components/PlLoaderLogo.vue2.js +4 -3
  231. package/dist/components/PlLoaderLogo.vue2.js.map +1 -1
  232. package/dist/components/PlLogView/PlLogView.js.map +1 -1
  233. package/dist/components/PlLogView/PlLogView.vue.d.ts.map +1 -1
  234. package/dist/components/PlLogView/PlLogView.vue2.js +13 -1
  235. package/dist/components/PlLogView/PlLogView.vue2.js.map +1 -1
  236. package/dist/components/PlNotificationAlert/PlNotificationAlert.js.map +1 -1
  237. package/dist/components/PlNotificationAlert/PlNotificationAlert.vue.d.ts.map +1 -1
  238. package/dist/components/PlNotificationAlert/PlNotificationAlert.vue2.js +8 -2
  239. package/dist/components/PlNotificationAlert/PlNotificationAlert.vue2.js.map +1 -1
  240. package/dist/components/PlNumberField/PlNumberField.js.map +1 -1
  241. package/dist/components/PlNumberField/PlNumberField.vue.d.ts.map +1 -1
  242. package/dist/components/PlNumberField/PlNumberField.vue2.js +12 -3
  243. package/dist/components/PlNumberField/PlNumberField.vue2.js.map +1 -1
  244. package/dist/components/PlProgressBar/PlProgressBar.js.map +1 -1
  245. package/dist/components/PlProgressBar/PlProgressBar.vue.d.ts.map +1 -1
  246. package/dist/components/PlProgressBar/PlProgressBar.vue2.js +9 -1
  247. package/dist/components/PlProgressBar/PlProgressBar.vue2.js.map +1 -1
  248. package/dist/components/PlProgressCell/PlProgressCell.js.map +1 -1
  249. package/dist/components/PlProgressCell/PlProgressCell.vue.d.ts.map +1 -1
  250. package/dist/components/PlProgressCell/PlProgressCell.vue2.js +19 -7
  251. package/dist/components/PlProgressCell/PlProgressCell.vue2.js.map +1 -1
  252. package/dist/components/PlRadio/PlRadio.js.map +1 -1
  253. package/dist/components/PlRadio/PlRadio.style.js.map +1 -1
  254. package/dist/components/PlRadio/PlRadio.vue.d.ts.map +1 -1
  255. package/dist/components/PlRadio/PlRadio.vue2.js +10 -3
  256. package/dist/components/PlRadio/PlRadio.vue2.js.map +1 -1
  257. package/dist/components/PlRadio/PlRadioGroup.js.map +1 -1
  258. package/dist/components/PlRadio/PlRadioGroup.style.js.map +1 -1
  259. package/dist/components/PlRadio/PlRadioGroup.vue.d.ts.map +1 -1
  260. package/dist/components/PlRadio/PlRadioGroup.vue2.js +10 -3
  261. package/dist/components/PlRadio/PlRadioGroup.vue2.js.map +1 -1
  262. package/dist/components/PlSearchField/PlSearchField.js.map +1 -1
  263. package/dist/components/PlSearchField/PlSearchField.style.js.map +1 -1
  264. package/dist/components/PlSearchField/PlSearchField.vue.d.ts.map +1 -1
  265. package/dist/components/PlSearchField/PlSearchField.vue2.js +11 -4
  266. package/dist/components/PlSearchField/PlSearchField.vue2.js.map +1 -1
  267. package/dist/components/PlSectionSeparator/PlSectionSeparator.js.map +1 -1
  268. package/dist/components/PlSectionSeparator/PlSectionSeparator.style.js.map +1 -1
  269. package/dist/components/PlSectionSeparator/PlSectionSeparator.vue.d.ts.map +1 -1
  270. package/dist/components/PlSectionSeparator/PlSectionSeparator.vue2.js +7 -1
  271. package/dist/components/PlSectionSeparator/PlSectionSeparator.vue2.js.map +1 -1
  272. package/dist/components/PlSidebar/PlSidebarGroup.js.map +1 -1
  273. package/dist/components/PlSidebar/PlSidebarGroup.style.js.map +1 -1
  274. package/dist/components/PlSidebar/PlSidebarGroup.vue.d.ts.map +1 -1
  275. package/dist/components/PlSidebar/PlSidebarGroup.vue2.js +5 -1
  276. package/dist/components/PlSidebar/PlSidebarGroup.vue2.js.map +1 -1
  277. package/dist/components/PlSidebar/PlSidebarItem.js.map +1 -1
  278. package/dist/components/PlSidebar/PlSidebarItem.style.js.map +1 -1
  279. package/dist/components/PlSidebar/PlSidebarItem.vue.d.ts.map +1 -1
  280. package/dist/components/PlSidebar/PlSidebarItem.vue2.js +7 -1
  281. package/dist/components/PlSidebar/PlSidebarItem.vue2.js.map +1 -1
  282. package/dist/components/PlSlideModal/PlPureSlideModal.js.map +1 -1
  283. package/dist/components/PlSlideModal/PlPureSlideModal.vue.d.ts.map +1 -1
  284. package/dist/components/PlSlideModal/PlPureSlideModal.vue2.js +4 -1
  285. package/dist/components/PlSlideModal/PlPureSlideModal.vue2.js.map +1 -1
  286. package/dist/components/PlSlideModal/PlSlideModal.js.map +1 -1
  287. package/dist/components/PlSlideModal/PlSlideModal.style.js.map +1 -1
  288. package/dist/components/PlSlideModal/PlSlideModal.vue.d.ts.map +1 -1
  289. package/dist/components/PlSlideModal/PlSlideModal.vue2.js +7 -2
  290. package/dist/components/PlSlideModal/PlSlideModal.vue2.js.map +1 -1
  291. package/dist/components/PlSpacer/PlSpacer.vue.d.ts.map +1 -1
  292. package/dist/components/PlSplash/PlSplash.js.map +1 -1
  293. package/dist/components/PlSplash/PlSplash.vue.d.ts.map +1 -1
  294. package/dist/components/PlSplash/PlSplash.vue2.js +13 -5
  295. package/dist/components/PlSplash/PlSplash.vue2.js.map +1 -1
  296. package/dist/components/PlStatusTag/PlStatusTag.js.map +1 -1
  297. package/dist/components/PlStatusTag/PlStatusTag.vue.d.ts.map +1 -1
  298. package/dist/components/PlStatusTag/PlStatusTag.vue2.js +4 -1
  299. package/dist/components/PlStatusTag/PlStatusTag.vue2.js.map +1 -1
  300. package/dist/components/PlTabs/PlTabs.js.map +1 -1
  301. package/dist/components/PlTabs/PlTabs.vue.d.ts.map +1 -1
  302. package/dist/components/PlTabs/PlTabs.vue2.js +16 -11
  303. package/dist/components/PlTabs/PlTabs.vue2.js.map +1 -1
  304. package/dist/components/PlTextArea/PlTextArea.js.map +1 -1
  305. package/dist/components/PlTextArea/PlTextArea.vue.d.ts.map +1 -1
  306. package/dist/components/PlTextArea/PlTextArea.vue2.js +21 -8
  307. package/dist/components/PlTextArea/PlTextArea.vue2.js.map +1 -1
  308. package/dist/components/PlTextField/PlTextField.js.map +1 -1
  309. package/dist/components/PlTextField/PlTextField.vue.d.ts.map +1 -1
  310. package/dist/components/PlTextField/PlTextField.vue2.js +23 -9
  311. package/dist/components/PlTextField/PlTextField.vue2.js.map +1 -1
  312. package/dist/components/PlToggleSwitch/PlToggleSwitch.js.map +1 -1
  313. package/dist/components/PlToggleSwitch/PlToggleSwitch.vue.d.ts.map +1 -1
  314. package/dist/components/PlToggleSwitch/PlToggleSwitch.vue2.js +10 -2
  315. package/dist/components/PlToggleSwitch/PlToggleSwitch.vue2.js.map +1 -1
  316. package/dist/components/PlTooltip/PlTooltip.js.map +1 -1
  317. package/dist/components/PlTooltip/PlTooltip.style.js.map +1 -1
  318. package/dist/components/PlTooltip/PlTooltip.vue.css +1 -1
  319. package/dist/components/PlTooltip/PlTooltip.vue.d.ts.map +1 -1
  320. package/dist/components/PlTooltip/PlTooltip.vue2.js +7 -2
  321. package/dist/components/PlTooltip/PlTooltip.vue2.js.map +1 -1
  322. package/dist/components/Slider.js.map +1 -1
  323. package/dist/components/Slider.vue.d.ts.map +1 -1
  324. package/dist/components/Slider.vue2.js +13 -1
  325. package/dist/components/Slider.vue2.js.map +1 -1
  326. package/dist/components/SliderRange.js.map +1 -1
  327. package/dist/components/SliderRange.vue.d.ts.map +1 -1
  328. package/dist/components/SliderRange.vue2.js +14 -1
  329. package/dist/components/SliderRange.vue2.js.map +1 -1
  330. package/dist/components/SliderRangeTriple.js.map +1 -1
  331. package/dist/components/SliderRangeTriple.vue.d.ts.map +1 -1
  332. package/dist/components/SliderRangeTriple.vue2.js +13 -1
  333. package/dist/components/SliderRangeTriple.vue2.js.map +1 -1
  334. package/dist/components/TabItem.js.map +1 -1
  335. package/dist/components/TabItem.vue.d.ts.map +1 -1
  336. package/dist/components/TabItem.vue2.js +8 -2
  337. package/dist/components/TabItem.vue2.js.map +1 -1
  338. package/dist/components/contextMenu/Menu.js +1 -1
  339. package/dist/components/contextMenu/Menu.js.map +1 -1
  340. package/dist/components/contextMenu/Menu.style.css +1 -1
  341. package/dist/components/contextMenu/Menu.vue.d.ts.map +1 -1
  342. package/dist/components/contextMenu/Menu.vue2.js +12 -8
  343. package/dist/components/contextMenu/Menu.vue2.js.map +1 -1
  344. package/dist/layout/PlBlockPage/PlBlockPage.js.map +1 -1
  345. package/dist/layout/PlBlockPage/PlBlockPage.style.js.map +1 -1
  346. package/dist/layout/PlBlockPage/PlBlockPage.vue.d.ts.map +1 -1
  347. package/dist/layout/PlBlockPage/PlBlockPage.vue2.js +45 -25
  348. package/dist/layout/PlBlockPage/PlBlockPage.vue2.js.map +1 -1
  349. package/dist/layout/PlContainer/PlContainer.js.map +1 -1
  350. package/dist/layout/PlContainer/PlContainer.vue.d.ts.map +1 -1
  351. package/dist/layout/PlContainer/PlContainer.vue2.js +1 -0
  352. package/dist/layout/PlContainer/PlContainer.vue2.js.map +1 -1
  353. package/dist/layout/PlGrid/PlGrid.js.map +1 -1
  354. package/dist/layout/PlGrid/PlGrid.vue.d.ts.map +1 -1
  355. package/dist/layout/PlGrid/PlGrid.vue2.js +1 -0
  356. package/dist/layout/PlGrid/PlGrid.vue2.js.map +1 -1
  357. package/dist/layout/PlPlaceholder/PlPlaceholder.js.map +1 -1
  358. package/dist/layout/PlPlaceholder/PlPlaceholder.style.js.map +1 -1
  359. package/dist/layout/PlPlaceholder/PlPlaceholder.vue.d.ts.map +1 -1
  360. package/dist/layout/PlPlaceholder/PlPlaceholder.vue2.js +25 -6
  361. package/dist/layout/PlPlaceholder/PlPlaceholder.vue2.js.map +1 -1
  362. package/dist/layout/PlRow/PlRow.js.map +1 -1
  363. package/dist/layout/PlRow/PlRow.vue.d.ts.map +1 -1
  364. package/dist/layout/PlRow/PlRow.vue2.js +7 -4
  365. package/dist/layout/PlRow/PlRow.vue2.js.map +1 -1
  366. package/dist/layout/PlSpacer/PlSpacer.js.map +1 -1
  367. package/dist/layout/PlSpacer/PlSpacer.vue.d.ts.map +1 -1
  368. package/dist/layout/PlSpacer/PlSpacer.vue2.js +1 -0
  369. package/dist/layout/PlSpacer/PlSpacer.vue2.js.map +1 -1
  370. package/package.json +3 -3
  371. package/src/__tests__/default-testid.test.ts +95 -0
  372. package/src/base/BtnBase.vue +3 -3
  373. package/src/components/DropdownListItem.vue +14 -4
  374. package/src/components/InputRange.vue +6 -2
  375. package/src/components/PlAccordion/PlAccordionSection.vue +13 -4
  376. package/src/components/PlAlert/PlAlert.vue +5 -3
  377. package/src/components/PlAutocomplete/PlAutocomplete.vue +47 -11
  378. package/src/components/PlAutocompleteMulti/PlAutocompleteMulti.vue +53 -11
  379. package/src/components/PlBtnAccent/PlBtnAccent.vue +1 -1
  380. package/src/components/PlBtnDanger/PlBtnDanger.vue +1 -1
  381. package/src/components/PlBtnGhost/PlBtnGhost.vue +4 -3
  382. package/src/components/PlBtnGroup/PlBtnGroup.vue +16 -6
  383. package/src/components/PlBtnLink/PlBtnLink.vue +2 -1
  384. package/src/components/PlBtnPrimary/PlBtnPrimary.vue +1 -1
  385. package/src/components/PlBtnSecondary/PlBtnSecondary.vue +1 -1
  386. package/src/components/PlBtnSplit/PlBtnSplit.vue +12 -2
  387. package/src/components/PlChartHistogram/PlChartHistogram.vue +9 -3
  388. package/src/components/PlChartHistogram/createGridlines.ts +2 -0
  389. package/src/components/PlChartHistogram/createLabels.ts +2 -0
  390. package/src/components/PlChartHistogram/createSvgContainer.ts +2 -0
  391. package/src/components/PlChartHistogram/drawBins.ts +2 -0
  392. package/src/components/PlChartHistogram/drawThreshold.ts +1 -0
  393. package/src/components/PlChartHistogram/histogram.ts +6 -1
  394. package/src/components/PlChartStackedBar/Legends.vue +18 -4
  395. package/src/components/PlChartStackedBar/PlChartStackedBar.vue +4 -2
  396. package/src/components/PlChartStackedBar/PlChartStackedBarCompact.vue +1 -1
  397. package/src/components/PlChartStackedBar/StackedRow.vue +12 -4
  398. package/src/components/PlChartStackedBar/StackedRowCompact.vue +10 -3
  399. package/src/components/PlCheckbox/PlCheckbox.vue +15 -4
  400. package/src/components/PlCheckbox/PlCheckboxBase.vue +1 -0
  401. package/src/components/PlCheckboxGroup/PlCheckboxGroup.vue +15 -4
  402. package/src/components/PlChip/PlChip.vue +4 -3
  403. package/src/components/PlClipboard/PlClipboard.vue +7 -1
  404. package/src/components/PlConfirmDialog.vue +8 -3
  405. package/src/components/PlDialogModal/PlDialogModal.vue +15 -2
  406. package/src/components/PlDropdown/OptionList.vue +13 -3
  407. package/src/components/PlDropdown/PlDropdown.vue +35 -11
  408. package/src/components/PlDropdownLegacy/PlDropdownLegacy.vue +51 -12
  409. package/src/components/PlDropdownLine/PlDropdownLine.vue +29 -5
  410. package/src/components/PlDropdownLine/ResizableInput.vue +2 -1
  411. package/src/components/PlDropdownMulti/PlDropdownMulti.vue +47 -11
  412. package/src/components/PlDropdownMultiRef/PlDropdownMultiRef.vue +1 -0
  413. package/src/components/PlDropdownRef/PlDropdownRef.vue +1 -0
  414. package/src/components/PlEditableTitle/PlEditableTitle.vue +11 -3
  415. package/src/components/PlElementList/PlElementList.vue +8 -3
  416. package/src/components/PlElementList/PlElementListItem.vue +16 -5
  417. package/src/components/PlErrorAlert/PlErrorAlert.vue +8 -6
  418. package/src/components/PlErrorBoundary/PlErrorBoundary.vue +7 -1
  419. package/src/components/PlFileDialog/Local.vue +12 -4
  420. package/src/components/PlFileDialog/PlFileDialog.vue +13 -3
  421. package/src/components/PlFileDialog/Remote.vue +39 -11
  422. package/src/components/PlFileDialog/Shortcuts.vue +7 -1
  423. package/src/components/PlFileInput/PlFileInput.vue +44 -19
  424. package/src/components/PlLoaderCircular/PlLoaderCircular.vue +1 -1
  425. package/src/components/PlLoaderLogo.vue +6 -1
  426. package/src/components/PlLogView/PlLogView.vue +30 -8
  427. package/src/components/PlNotificationAlert/PlNotificationAlert.vue +15 -3
  428. package/src/components/PlNumberField/PlNumberField.vue +14 -3
  429. package/src/components/PlProgressBar/PlProgressBar.vue +12 -4
  430. package/src/components/PlProgressCell/PlProgressCell.vue +13 -4
  431. package/src/components/PlRadio/PlRadio.vue +10 -3
  432. package/src/components/PlRadio/PlRadioGroup.vue +3 -2
  433. package/src/components/PlSearchField/PlSearchField.vue +5 -3
  434. package/src/components/PlSectionSeparator/PlSectionSeparator.vue +6 -2
  435. package/src/components/PlSidebar/PlSidebarGroup.vue +2 -2
  436. package/src/components/PlSidebar/PlSidebarItem.vue +12 -4
  437. package/src/components/PlSlideModal/PlPureSlideModal.vue +7 -1
  438. package/src/components/PlSlideModal/PlSlideModal.vue +4 -3
  439. package/src/components/PlSpacer/PlSpacer.vue +1 -1
  440. package/src/components/PlSplash/PlSplash.vue +6 -3
  441. package/src/components/PlStatusTag/PlStatusTag.vue +1 -0
  442. package/src/components/PlTabs/PlTabs.vue +6 -2
  443. package/src/components/PlTextArea/PlTextArea.vue +21 -8
  444. package/src/components/PlTextField/PlTextField.vue +23 -8
  445. package/src/components/PlToggleSwitch/PlToggleSwitch.vue +4 -3
  446. package/src/components/PlTooltip/PlTooltip.vue +3 -0
  447. package/src/components/Slider.vue +27 -7
  448. package/src/components/SliderRange.vue +28 -7
  449. package/src/components/SliderRangeTriple.vue +19 -5
  450. package/src/components/TabItem.vue +2 -2
  451. package/src/components/contextMenu/Menu.vue +8 -3
  452. package/src/layout/PlBlockPage/PlBlockPage.vue +40 -11
  453. package/src/layout/PlContainer/PlContainer.vue +1 -0
  454. package/src/layout/PlGrid/PlGrid.vue +1 -1
  455. package/src/layout/PlPlaceholder/PlPlaceholder.vue +20 -8
  456. package/src/layout/PlRow/PlRow.vue +5 -1
  457. package/src/layout/PlSpacer/PlSpacer.vue +1 -1
@@ -25,22 +25,30 @@ import { refDebounced as he } from "@vueuse/core";
25
25
  //#region src/components/PlAutocomplete/PlAutocomplete.vue?vue&type=script&setup=true&lang.ts
26
26
  var ge = ["tabindex"], _e = { class: "pl-autocomplete__container" }, ve = ["title"], O = ["disabled", "placeholder"], k = {
27
27
  key: 0,
28
- class: "input-value"
28
+ class: "input-value",
29
+ "data-testid": "pl-autocomplete-value"
29
30
  }, A = { class: "pl-autocomplete__controls" }, j = {
30
31
  key: 2,
31
32
  class: "arrow-icon arrow-icon-default"
32
- }, M = { key: 0 }, N = {
33
+ }, M = {
33
34
  key: 0,
34
- class: "nothing-found"
35
+ "data-testid": "pl-autocomplete-label"
36
+ }, N = {
37
+ key: 0,
38
+ class: "nothing-found",
39
+ "data-testid": "pl-autocomplete-options-empty"
35
40
  }, P = {
36
41
  key: 0,
37
- class: "pl-autocomplete__error"
42
+ class: "pl-autocomplete__error",
43
+ "data-testid": "pl-autocomplete-error"
38
44
  }, F = {
39
45
  key: 1,
40
- class: "pl-autocomplete__helper"
46
+ class: "pl-autocomplete__helper",
47
+ "data-testid": "pl-autocomplete-helper"
41
48
  }, ye = {
42
49
  key: 2,
43
- class: "pl-autocomplete__helper"
50
+ class: "pl-autocomplete__helper",
51
+ "data-testid": "pl-autocomplete-helper"
44
52
  }, I = /* @__PURE__ */ g({
45
53
  name: "PlAutocomplete",
46
54
  props: /* @__PURE__ */ _({
@@ -141,7 +149,8 @@ var ge = ["tabindex"], _e = { class: "pl-autocomplete__container" }, ve = ["titl
141
149
  G.value = e;
142
150
  }), (t, n) => (y(), p("div", {
143
151
  class: "pl-autocomplete__envelope",
144
- onClick: E(ke, ["stop"])
152
+ onClick: E(ke, ["stop"]),
153
+ "data-testid": "pl-autocomplete"
145
154
  }, [m("div", {
146
155
  ref_key: "rootRef",
147
156
  ref: L,
@@ -151,6 +160,7 @@ var ge = ["tabindex"], _e = { class: "pl-autocomplete__container" }, ve = ["titl
151
160
  error: !!J.value,
152
161
  disabled: q.value
153
162
  }]),
163
+ "data-testid": "pl-autocomplete-control",
154
164
  onKeydown: Me,
155
165
  onFocusout: je
156
166
  }, [m("div", _e, [
@@ -168,6 +178,7 @@ var ge = ["tabindex"], _e = { class: "pl-autocomplete__container" }, ve = ["titl
168
178
  placeholder: Te.value,
169
179
  spellcheck: "false",
170
180
  autocomplete: "chrome-off",
181
+ "data-testid": "pl-autocomplete-input",
171
182
  onFocus: Ae
172
183
  }, null, 40, O), [[fe, B.value]]),
173
184
  V.open ? f("", !0) : (y(), p("div", k, [h(a, null, {
@@ -177,17 +188,20 @@ var ge = ["tabindex"], _e = { class: "pl-autocomplete__container" }, ve = ["titl
177
188
  m("div", A, [
178
189
  G.value ? (y(), d(C(s), {
179
190
  key: 0,
180
- name: "loading"
191
+ name: "loading",
192
+ "data-testid": "pl-autocomplete-loading"
181
193
  })) : f("", !0),
182
194
  g.clearable && Ee.value ? (y(), d(C(ee), {
183
195
  key: 1,
184
196
  class: "clear",
197
+ "data-testid": "pl-autocomplete-clear",
185
198
  name: "delete-clear",
186
199
  onClick: E(Oe, ["stop"])
187
200
  })) : f("", !0),
188
201
  x(t.$slots, "append"),
189
202
  m("div", {
190
203
  class: "pl-autocomplete__arrow-wrapper",
204
+ "data-testid": "pl-autocomplete-arrow",
191
205
  onClick: E(Z, ["stop"])
192
206
  }, [g.arrowIconLarge ? (y(), p("div", {
193
207
  key: 0,
@@ -201,13 +215,15 @@ var ge = ["tabindex"], _e = { class: "pl-autocomplete__container" }, ve = ["titl
201
215
  g.label ? (y(), p("label", M, [
202
216
  g.required ? (y(), d(C(o), {
203
217
  key: 0,
204
- uri: C(ie)
218
+ uri: C(ie),
219
+ "data-testid": "pl-autocomplete-required"
205
220
  }, null, 8, ["uri"])) : f("", !0),
206
221
  m("span", null, S(g.label), 1),
207
222
  be.tooltip ? (y(), d(C(r), {
208
223
  key: 1,
209
224
  class: "info",
210
- position: "top"
225
+ position: "top",
226
+ "data-testid": "pl-autocomplete-tooltip"
211
227
  }, {
212
228
  tooltip: T(() => [x(t.$slots, "tooltip")]),
213
229
  _: 3
@@ -218,6 +234,7 @@ var ge = ["tabindex"], _e = { class: "pl-autocomplete__container" }, ve = ["titl
218
234
  ref: "overlay",
219
235
  root: L.value,
220
236
  class: "pl-autocomplete__options",
237
+ "data-testid": "pl-autocomplete-options",
221
238
  tabindex: "-1",
222
239
  gap: 3
223
240
  }, {
@@ -227,6 +244,7 @@ var ge = ["tabindex"], _e = { class: "pl-autocomplete__container" }, ve = ["titl
227
244
  "is-selected": t.isSelected,
228
245
  "is-hovered": t.isActive,
229
246
  size: g.optionSize,
247
+ "data-testid": "pl-autocomplete-option",
230
248
  onClick: E((e) => X(t), ["stop"])
231
249
  }, null, 8, [
232
250
  "option",
@@ -234,7 +252,7 @@ var ge = ["tabindex"], _e = { class: "pl-autocomplete__container" }, ve = ["titl
234
252
  "is-hovered",
235
253
  "size",
236
254
  "onClick"
237
- ]))), 128)), W.value.length ? f("", !0) : (y(), p("div", N, "Nothing found"))]),
255
+ ]))), 128)), W.value.length ? f("", !0) : (y(), p("div", N, " Nothing found "))]),
238
256
  _: 1
239
257
  }, 8, ["root"])) : f("", !0),
240
258
  h(te, {
@@ -1 +1 @@
1
- {"version":3,"file":"PlAutocomplete.vue_vue_type_script_setup_true_lang.js","names":[],"sources":["../../../src/components/PlAutocomplete/PlAutocomplete.vue"],"sourcesContent":["<script lang=\"ts\">\n/**\n * A component for selecting one value from a big list of options using string search request\n */\nexport default {\n name: \"PlAutocomplete\",\n};\n</script>\n\n<script\n lang=\"ts\"\n setup\n generic=\"M extends null | undefined | string | number = null | undefined | string\"\n>\nimport \"./pl-autocomplete.scss\";\nimport { computed, reactive, ref, unref, useTemplateRef, watch, watchPostEffect } from \"vue\";\nimport { tap } from \"../../helpers/functions\";\nimport { PlTooltip } from \"../PlTooltip\";\nimport DoubleContour from \"../../utils/DoubleContour.vue\";\nimport { useLabelNotch } from \"../../utils/useLabelNotch\";\nimport type { ListOption, ListOptionNormalized } from \"../../types\";\nimport { deepEqual } from \"../../helpers/objects\";\nimport DropdownListItem from \"../DropdownListItem.vue\";\nimport LongText from \"../LongText.vue\";\nimport { normalizeListOptions } from \"../../helpers/utils\";\nimport { PlIcon16 } from \"../PlIcon16\";\nimport { PlMaskIcon24 } from \"../PlMaskIcon24\";\nimport { DropdownOverlay } from \"../../utils/DropdownOverlay\";\nimport { refDebounced } from \"@vueuse/core\";\nimport { useWatchFetch } from \"../../composition/useWatchFetch.ts\";\nimport { getErrorMessage } from \"../../helpers/error.ts\";\nimport type { ListOptionBase } from \"@platforma-sdk/model\";\nimport { PlSvg } from \"../PlSvg\";\nimport SvgRequired from \"../../assets/images/required.svg?raw\";\nimport { isNil } from \"@milaboratories/helpers\";\n\n/**\n * The current selected value.\n */\nconst model = defineModel<M>({ required: true });\n\nconst props = withDefaults(\n defineProps<{\n /**\n * Lambda for requesting of available options for the dropdown by search string.\n */\n optionsSearch: (string: string, type: \"value\" | \"label\") => Promise<ListOption<M>[]>;\n /**\n * The label text for the dropdown field (optional)\n */\n label?: string;\n /**\n * A helper text displayed below the dropdown when there are no errors (optional).\n */\n helper?: string;\n /**\n * A helper text displayed below the dropdown when there are no options yet or options is undefined (optional).\n */\n loadingOptionsHelper?: string;\n /**\n * Error message displayed below the dropdown (optional)\n */\n error?: unknown;\n /**\n * Placeholder text shown when no value is selected.\n */\n placeholder?: string;\n /**\n * Enables a button to clear the selected value (default: false)\n */\n clearable?: boolean;\n /**\n * If `true`, the dropdown component is marked as required.\n */\n required?: boolean;\n /**\n * If `true`, the dropdown component is disabled and cannot be interacted with.\n */\n disabled?: boolean;\n /**\n * Custom icon (16px) class for the dropdown arrow (optional)\n */\n arrowIcon?: string;\n /**\n * Custom icon (24px) class for the dropdown arrow (optional)\n */\n arrowIconLarge?: string;\n /**\n * Option list item size\n */\n optionSize?: \"small\" | \"medium\";\n /**\n * Formatter for the selected value if its label is absent\n */\n formatValue?: (value: M) => string;\n /**\n * Makes some of corners not rounded\n * */\n groupPosition?:\n | \"top\"\n | \"bottom\"\n | \"left\"\n | \"right\"\n | \"top-left\"\n | \"top-right\"\n | \"bottom-left\"\n | \"bottom-right\"\n | \"middle\";\n }>(),\n {\n modelSearch: undefined,\n label: \"\",\n helper: undefined,\n loadingOptionsHelper: undefined,\n error: undefined,\n placeholder: \"...\",\n clearable: false,\n required: false,\n disabled: false,\n arrowIcon: undefined,\n arrowIconLarge: undefined,\n optionSize: \"small\",\n formatValue: (v: M) => String(v),\n groupPosition: undefined,\n },\n);\n\nconst slots = defineSlots<{\n [key: string]: unknown;\n}>();\n\nconst rootRef = ref<HTMLElement | undefined>();\nconst input = ref<HTMLInputElement | undefined>();\n\nconst overlayRef = useTemplateRef(\"overlay\");\n\nconst search = ref<string | null>(null);\nconst data = reactive({\n activeIndex: -1,\n open: false,\n});\n\nconst findActiveIndex = () =>\n tap(\n renderedOptionsRef.value.findIndex((o) => deepEqual(o.value, model.value)),\n (v) => (v < 0 ? 0 : v),\n );\n\nconst updateActive = () => (data.activeIndex = findActiveIndex());\n\nconst loadedOptionsRef = ref<ListOption<M>[]>([]);\nconst modelOptionRef = ref<ListOptionNormalized<M> | undefined>(); // list of 1 option that is selected or empty, to keep selected label\n\nconst renderedOptionsRef = computed(() => {\n return normalizeListOptions(loadedOptionsRef.value).map((opt, index) => ({\n ...opt,\n index,\n isSelected: index === selectedIndex.value,\n isActive: index === data.activeIndex,\n })) as (ListOptionBase<M> & { index: number; isSelected: boolean; isActive: boolean })[];\n});\nconst isLoadingOptions = ref<boolean>(true);\nconst isLoadingError = ref<boolean>(false);\n\nconst isDisabled = computed(() => {\n return props.disabled;\n});\n\nconst selectedIndex = computed(() => {\n return loadedOptionsRef.value.findIndex((o) => deepEqual(o.value, model.value));\n});\n\nconst computedError = computed(() => {\n if (isLoadingOptions.value) {\n return undefined;\n }\n\n if (props.error) {\n return getErrorMessage(props.error);\n }\n\n if (isLoadingError.value) {\n return \"Data loading error\";\n }\n\n return undefined;\n});\n\nconst textValue = computed(() => {\n const modelOption = unref(modelOptionRef);\n const options = unref(renderedOptionsRef);\n\n const item: ListOptionNormalized | undefined =\n modelOption ??\n options.find((o) => deepEqual(o.value, model.value)) ??\n options.find((o) => deepEqual(o.value, model.value));\n\n return item?.label || (model.value ? props.formatValue(model.value) : \"\");\n});\n\n// Native tooltip with the full selected value; the value layer itself has\n// `pointer-events: none`, so the title goes on the field wrapper.\nconst fieldTitle = computed(() => (!data.open && textValue.value ? textValue.value : undefined));\n\nconst computedPlaceholder = computed(() => {\n if (!data.open && model.value) {\n return \"\";\n }\n\n return model.value ? String(textValue.value) : props.placeholder;\n});\n\nconst hasValue = computed(() => {\n return model.value !== undefined && model.value !== null;\n});\n\nconst tabindex = computed(() => (isDisabled.value ? undefined : \"0\"));\n\nconst selectOption = (v: (ListOptionBase<M> & { index: number }) | undefined) => {\n model.value = v?.value as M;\n modelOptionRef.value = v;\n search.value = null;\n data.open = false;\n rootRef?.value?.focus();\n};\n\nconst clear = () => {\n model.value = undefined as M;\n modelOptionRef.value = undefined;\n};\n\nconst setFocusOnInput = () => input.value?.focus();\n\nconst toggleOpen = () => {\n data.open = !data.open;\n};\n\nwatch(\n () => data.open,\n (v) => {\n search.value = v ? \"\" : null;\n },\n);\n\nconst onInputFocus = () => {\n data.open = true;\n};\n\nconst onFocusOut = (event: FocusEvent) => {\n const relatedTarget = event.relatedTarget as Node | null;\n\n if (\n !rootRef.value?.contains(relatedTarget) &&\n !overlayRef.value?.listRef?.contains(relatedTarget)\n ) {\n search.value = null;\n data.open = false;\n }\n};\n\nconst handleKeydown = (e: { code: string; preventDefault(): void }) => {\n if (![\"ArrowDown\", \"ArrowUp\", \"Enter\", \"Escape\"].includes(e.code)) {\n return;\n } else {\n e.preventDefault();\n }\n\n const { open, activeIndex } = data;\n\n if (!open) {\n if (e.code === \"Enter\") {\n data.open = true;\n search.value = \"\";\n }\n return;\n }\n\n if (e.code === \"Escape\") {\n data.open = false;\n search.value = null;\n rootRef.value?.focus();\n }\n\n const options = unref(renderedOptionsRef);\n\n const { length } = options;\n\n if (!length) {\n return;\n }\n\n if (e.code === \"Enter\") {\n selectOption(options.find((it) => it.index === activeIndex));\n }\n\n const localIndex = options.findIndex((it) => it.index === activeIndex) ?? -1;\n\n const delta = e.code === \"ArrowDown\" ? 1 : e.code === \"ArrowUp\" ? -1 : 0;\n\n const newIndex = Math.abs(localIndex + delta + length) % length;\n\n data.activeIndex = renderedOptionsRef.value[newIndex].index ?? -1;\n};\n\nuseLabelNotch(rootRef);\n\nwatch(() => model.value, updateActive, { immediate: true });\n\nwatch(\n () => data.open,\n (open) => (open ? input.value?.focus() : \"\"),\n);\n\nwatchPostEffect(() => {\n // eslint-disable-next-line @typescript-eslint/no-unused-expressions\n search.value; // to watch\n\n if (data.activeIndex >= 0 && data.open) {\n overlayRef.value?.scrollIntoActive();\n }\n});\n\nconst searchDebounced = refDebounced(search, 300, { maxWait: 1000 });\n\nconst optionsRequest = useWatchFetch(\n () => searchDebounced.value,\n async (v) => (isNil(v) ? undefined : props.optionsSearch(v, \"label\")),\n);\n\nconst modelOptionRequest = useWatchFetch(\n () => model.value,\n async (v) => {\n if (isNil(v) || deepEqual(modelOptionRef.value?.value, v)) {\n return modelOptionRef.value;\n }\n\n const options = await props.optionsSearch(String(v), \"value\");\n return options.find((o) => String(o.value) === String(v));\n },\n);\n\nwatch(\n () => optionsRequest.value,\n (result) => {\n if (result) {\n loadedOptionsRef.value = result;\n if (search.value !== null) {\n isLoadingError.value = false;\n }\n }\n },\n);\n\nwatch(\n () => modelOptionRequest.value,\n (result) => {\n if (result) {\n modelOptionRef.value = normalizeListOptions([result])[0];\n }\n },\n);\n\nwatch(\n () => optionsRequest.error,\n (err) => {\n if (err) {\n isLoadingError.value = Boolean(err);\n }\n },\n);\n\nwatch(\n () => optionsRequest.loading || modelOptionRequest.loading,\n (loading) => {\n isLoadingOptions.value = loading;\n },\n);\n</script>\n\n<template>\n <div class=\"pl-autocomplete__envelope\" @click.stop=\"setFocusOnInput\">\n <div\n ref=\"rootRef\"\n :tabindex=\"tabindex\"\n class=\"pl-autocomplete\"\n :class=\"{ open: data.open, error: Boolean(computedError), disabled: isDisabled }\"\n @keydown=\"handleKeydown\"\n @focusout=\"onFocusOut\"\n >\n <div class=\"pl-autocomplete__container\">\n <div class=\"pl-autocomplete__field\" :title=\"fieldTitle\">\n <input\n ref=\"input\"\n v-model=\"search\"\n type=\"text\"\n tabindex=\"-1\"\n :disabled=\"isDisabled\"\n :placeholder=\"computedPlaceholder\"\n spellcheck=\"false\"\n autocomplete=\"chrome-off\"\n @focus=\"onInputFocus\"\n />\n\n <div v-if=\"!data.open\" class=\"input-value\">\n <LongText> {{ textValue }} </LongText>\n </div>\n\n <div class=\"pl-autocomplete__controls\">\n <PlMaskIcon24 v-if=\"isLoadingOptions\" name=\"loading\" />\n <PlIcon16\n v-if=\"clearable && hasValue\"\n class=\"clear\"\n name=\"delete-clear\"\n @click.stop=\"clear\"\n />\n <slot name=\"append\" />\n <div class=\"pl-autocomplete__arrow-wrapper\" @click.stop=\"toggleOpen\">\n <div\n v-if=\"arrowIconLarge\"\n class=\"arrow-icon\"\n :class=\"[`icon-24 ${arrowIconLarge}`]\"\n />\n <div v-else-if=\"arrowIcon\" class=\"arrow-icon\" :class=\"[`icon-16 ${arrowIcon}`]\" />\n <div v-else class=\"arrow-icon arrow-icon-default\" />\n </div>\n </div>\n </div>\n <label v-if=\"label\">\n <PlSvg v-if=\"required\" :uri=\"SvgRequired\" />\n <span>{{ label }}</span>\n <PlTooltip v-if=\"slots.tooltip\" class=\"info\" position=\"top\">\n <template #tooltip>\n <slot name=\"tooltip\" />\n </template>\n </PlTooltip>\n </label>\n <DropdownOverlay\n v-if=\"data.open\"\n ref=\"overlay\"\n :root=\"rootRef\"\n class=\"pl-autocomplete__options\"\n tabindex=\"-1\"\n :gap=\"3\"\n >\n <DropdownListItem\n v-for=\"(item, index) in renderedOptionsRef\"\n :key=\"index\"\n :option=\"item\"\n :is-selected=\"item.isSelected\"\n :is-hovered=\"item.isActive\"\n :size=\"optionSize\"\n @click.stop=\"selectOption(item)\"\n />\n <div v-if=\"!renderedOptionsRef.length\" class=\"nothing-found\">Nothing found</div>\n </DropdownOverlay>\n <DoubleContour class=\"pl-autocomplete__contour\" :group-position=\"groupPosition\" />\n </div>\n </div>\n <div v-if=\"computedError\" class=\"pl-autocomplete__error\">{{ computedError }}</div>\n <div v-else-if=\"isLoadingOptions && loadingOptionsHelper\" class=\"pl-autocomplete__helper\">\n {{ loadingOptionsHelper }}\n </div>\n <div v-else-if=\"helper\" class=\"pl-autocomplete__helper\">{{ helper }}</div>\n </div>\n</template>\n"],"mappings":"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"}
1
+ {"version":3,"file":"PlAutocomplete.vue_vue_type_script_setup_true_lang.js","names":[],"sources":["../../../src/components/PlAutocomplete/PlAutocomplete.vue"],"sourcesContent":["<script lang=\"ts\">\n/**\n * A component for selecting one value from a big list of options using string search request\n */\nexport default {\n name: \"PlAutocomplete\",\n};\n</script>\n\n<script\n lang=\"ts\"\n setup\n generic=\"M extends null | undefined | string | number = null | undefined | string\"\n>\nimport \"./pl-autocomplete.scss\";\nimport { computed, reactive, ref, unref, useTemplateRef, watch, watchPostEffect } from \"vue\";\nimport { tap } from \"../../helpers/functions\";\nimport { PlTooltip } from \"../PlTooltip\";\nimport DoubleContour from \"../../utils/DoubleContour.vue\";\nimport { useLabelNotch } from \"../../utils/useLabelNotch\";\nimport type { ListOption, ListOptionNormalized } from \"../../types\";\nimport { deepEqual } from \"../../helpers/objects\";\nimport DropdownListItem from \"../DropdownListItem.vue\";\nimport LongText from \"../LongText.vue\";\nimport { normalizeListOptions } from \"../../helpers/utils\";\nimport { PlIcon16 } from \"../PlIcon16\";\nimport { PlMaskIcon24 } from \"../PlMaskIcon24\";\nimport { DropdownOverlay } from \"../../utils/DropdownOverlay\";\nimport { refDebounced } from \"@vueuse/core\";\nimport { useWatchFetch } from \"../../composition/useWatchFetch.ts\";\nimport { getErrorMessage } from \"../../helpers/error.ts\";\nimport type { ListOptionBase } from \"@platforma-sdk/model\";\nimport { PlSvg } from \"../PlSvg\";\nimport SvgRequired from \"../../assets/images/required.svg?raw\";\nimport { isNil } from \"@milaboratories/helpers\";\n\n/**\n * The current selected value.\n */\nconst model = defineModel<M>({ required: true });\n\nconst props = withDefaults(\n defineProps<{\n /**\n * Lambda for requesting of available options for the dropdown by search string.\n */\n optionsSearch: (string: string, type: \"value\" | \"label\") => Promise<ListOption<M>[]>;\n /**\n * The label text for the dropdown field (optional)\n */\n label?: string;\n /**\n * A helper text displayed below the dropdown when there are no errors (optional).\n */\n helper?: string;\n /**\n * A helper text displayed below the dropdown when there are no options yet or options is undefined (optional).\n */\n loadingOptionsHelper?: string;\n /**\n * Error message displayed below the dropdown (optional)\n */\n error?: unknown;\n /**\n * Placeholder text shown when no value is selected.\n */\n placeholder?: string;\n /**\n * Enables a button to clear the selected value (default: false)\n */\n clearable?: boolean;\n /**\n * If `true`, the dropdown component is marked as required.\n */\n required?: boolean;\n /**\n * If `true`, the dropdown component is disabled and cannot be interacted with.\n */\n disabled?: boolean;\n /**\n * Custom icon (16px) class for the dropdown arrow (optional)\n */\n arrowIcon?: string;\n /**\n * Custom icon (24px) class for the dropdown arrow (optional)\n */\n arrowIconLarge?: string;\n /**\n * Option list item size\n */\n optionSize?: \"small\" | \"medium\";\n /**\n * Formatter for the selected value if its label is absent\n */\n formatValue?: (value: M) => string;\n /**\n * Makes some of corners not rounded\n * */\n groupPosition?:\n | \"top\"\n | \"bottom\"\n | \"left\"\n | \"right\"\n | \"top-left\"\n | \"top-right\"\n | \"bottom-left\"\n | \"bottom-right\"\n | \"middle\";\n }>(),\n {\n modelSearch: undefined,\n label: \"\",\n helper: undefined,\n loadingOptionsHelper: undefined,\n error: undefined,\n placeholder: \"...\",\n clearable: false,\n required: false,\n disabled: false,\n arrowIcon: undefined,\n arrowIconLarge: undefined,\n optionSize: \"small\",\n formatValue: (v: M) => String(v),\n groupPosition: undefined,\n },\n);\n\nconst slots = defineSlots<{\n [key: string]: unknown;\n}>();\n\nconst rootRef = ref<HTMLElement | undefined>();\nconst input = ref<HTMLInputElement | undefined>();\n\nconst overlayRef = useTemplateRef(\"overlay\");\n\nconst search = ref<string | null>(null);\nconst data = reactive({\n activeIndex: -1,\n open: false,\n});\n\nconst findActiveIndex = () =>\n tap(\n renderedOptionsRef.value.findIndex((o) => deepEqual(o.value, model.value)),\n (v) => (v < 0 ? 0 : v),\n );\n\nconst updateActive = () => (data.activeIndex = findActiveIndex());\n\nconst loadedOptionsRef = ref<ListOption<M>[]>([]);\nconst modelOptionRef = ref<ListOptionNormalized<M> | undefined>(); // list of 1 option that is selected or empty, to keep selected label\n\nconst renderedOptionsRef = computed(() => {\n return normalizeListOptions(loadedOptionsRef.value).map((opt, index) => ({\n ...opt,\n index,\n isSelected: index === selectedIndex.value,\n isActive: index === data.activeIndex,\n })) as (ListOptionBase<M> & { index: number; isSelected: boolean; isActive: boolean })[];\n});\nconst isLoadingOptions = ref<boolean>(true);\nconst isLoadingError = ref<boolean>(false);\n\nconst isDisabled = computed(() => {\n return props.disabled;\n});\n\nconst selectedIndex = computed(() => {\n return loadedOptionsRef.value.findIndex((o) => deepEqual(o.value, model.value));\n});\n\nconst computedError = computed(() => {\n if (isLoadingOptions.value) {\n return undefined;\n }\n\n if (props.error) {\n return getErrorMessage(props.error);\n }\n\n if (isLoadingError.value) {\n return \"Data loading error\";\n }\n\n return undefined;\n});\n\nconst textValue = computed(() => {\n const modelOption = unref(modelOptionRef);\n const options = unref(renderedOptionsRef);\n\n const item: ListOptionNormalized | undefined =\n modelOption ??\n options.find((o) => deepEqual(o.value, model.value)) ??\n options.find((o) => deepEqual(o.value, model.value));\n\n return item?.label || (model.value ? props.formatValue(model.value) : \"\");\n});\n\n// Native tooltip with the full selected value; the value layer itself has\n// `pointer-events: none`, so the title goes on the field wrapper.\nconst fieldTitle = computed(() => (!data.open && textValue.value ? textValue.value : undefined));\n\nconst computedPlaceholder = computed(() => {\n if (!data.open && model.value) {\n return \"\";\n }\n\n return model.value ? String(textValue.value) : props.placeholder;\n});\n\nconst hasValue = computed(() => {\n return model.value !== undefined && model.value !== null;\n});\n\nconst tabindex = computed(() => (isDisabled.value ? undefined : \"0\"));\n\nconst selectOption = (v: (ListOptionBase<M> & { index: number }) | undefined) => {\n model.value = v?.value as M;\n modelOptionRef.value = v;\n search.value = null;\n data.open = false;\n rootRef?.value?.focus();\n};\n\nconst clear = () => {\n model.value = undefined as M;\n modelOptionRef.value = undefined;\n};\n\nconst setFocusOnInput = () => input.value?.focus();\n\nconst toggleOpen = () => {\n data.open = !data.open;\n};\n\nwatch(\n () => data.open,\n (v) => {\n search.value = v ? \"\" : null;\n },\n);\n\nconst onInputFocus = () => {\n data.open = true;\n};\n\nconst onFocusOut = (event: FocusEvent) => {\n const relatedTarget = event.relatedTarget as Node | null;\n\n if (\n !rootRef.value?.contains(relatedTarget) &&\n !overlayRef.value?.listRef?.contains(relatedTarget)\n ) {\n search.value = null;\n data.open = false;\n }\n};\n\nconst handleKeydown = (e: { code: string; preventDefault(): void }) => {\n if (![\"ArrowDown\", \"ArrowUp\", \"Enter\", \"Escape\"].includes(e.code)) {\n return;\n } else {\n e.preventDefault();\n }\n\n const { open, activeIndex } = data;\n\n if (!open) {\n if (e.code === \"Enter\") {\n data.open = true;\n search.value = \"\";\n }\n return;\n }\n\n if (e.code === \"Escape\") {\n data.open = false;\n search.value = null;\n rootRef.value?.focus();\n }\n\n const options = unref(renderedOptionsRef);\n\n const { length } = options;\n\n if (!length) {\n return;\n }\n\n if (e.code === \"Enter\") {\n selectOption(options.find((it) => it.index === activeIndex));\n }\n\n const localIndex = options.findIndex((it) => it.index === activeIndex) ?? -1;\n\n const delta = e.code === \"ArrowDown\" ? 1 : e.code === \"ArrowUp\" ? -1 : 0;\n\n const newIndex = Math.abs(localIndex + delta + length) % length;\n\n data.activeIndex = renderedOptionsRef.value[newIndex].index ?? -1;\n};\n\nuseLabelNotch(rootRef);\n\nwatch(() => model.value, updateActive, { immediate: true });\n\nwatch(\n () => data.open,\n (open) => (open ? input.value?.focus() : \"\"),\n);\n\nwatchPostEffect(() => {\n // eslint-disable-next-line @typescript-eslint/no-unused-expressions\n search.value; // to watch\n\n if (data.activeIndex >= 0 && data.open) {\n overlayRef.value?.scrollIntoActive();\n }\n});\n\nconst searchDebounced = refDebounced(search, 300, { maxWait: 1000 });\n\nconst optionsRequest = useWatchFetch(\n () => searchDebounced.value,\n async (v) => (isNil(v) ? undefined : props.optionsSearch(v, \"label\")),\n);\n\nconst modelOptionRequest = useWatchFetch(\n () => model.value,\n async (v) => {\n if (isNil(v) || deepEqual(modelOptionRef.value?.value, v)) {\n return modelOptionRef.value;\n }\n\n const options = await props.optionsSearch(String(v), \"value\");\n return options.find((o) => String(o.value) === String(v));\n },\n);\n\nwatch(\n () => optionsRequest.value,\n (result) => {\n if (result) {\n loadedOptionsRef.value = result;\n if (search.value !== null) {\n isLoadingError.value = false;\n }\n }\n },\n);\n\nwatch(\n () => modelOptionRequest.value,\n (result) => {\n if (result) {\n modelOptionRef.value = normalizeListOptions([result])[0];\n }\n },\n);\n\nwatch(\n () => optionsRequest.error,\n (err) => {\n if (err) {\n isLoadingError.value = Boolean(err);\n }\n },\n);\n\nwatch(\n () => optionsRequest.loading || modelOptionRequest.loading,\n (loading) => {\n isLoadingOptions.value = loading;\n },\n);\n</script>\n\n<template>\n <div\n class=\"pl-autocomplete__envelope\"\n @click.stop=\"setFocusOnInput\"\n data-testid=\"pl-autocomplete\"\n >\n <div\n ref=\"rootRef\"\n :tabindex=\"tabindex\"\n class=\"pl-autocomplete\"\n data-testid=\"pl-autocomplete-control\"\n :class=\"{ open: data.open, error: Boolean(computedError), disabled: isDisabled }\"\n @keydown=\"handleKeydown\"\n @focusout=\"onFocusOut\"\n >\n <div class=\"pl-autocomplete__container\">\n <div class=\"pl-autocomplete__field\" :title=\"fieldTitle\">\n <input\n ref=\"input\"\n v-model=\"search\"\n type=\"text\"\n tabindex=\"-1\"\n :disabled=\"isDisabled\"\n :placeholder=\"computedPlaceholder\"\n spellcheck=\"false\"\n autocomplete=\"chrome-off\"\n data-testid=\"pl-autocomplete-input\"\n @focus=\"onInputFocus\"\n />\n\n <div v-if=\"!data.open\" class=\"input-value\" data-testid=\"pl-autocomplete-value\">\n <LongText> {{ textValue }} </LongText>\n </div>\n\n <div class=\"pl-autocomplete__controls\">\n <PlMaskIcon24\n v-if=\"isLoadingOptions\"\n name=\"loading\"\n data-testid=\"pl-autocomplete-loading\"\n />\n <PlIcon16\n v-if=\"clearable && hasValue\"\n class=\"clear\"\n data-testid=\"pl-autocomplete-clear\"\n name=\"delete-clear\"\n @click.stop=\"clear\"\n />\n <slot name=\"append\" />\n <div\n class=\"pl-autocomplete__arrow-wrapper\"\n data-testid=\"pl-autocomplete-arrow\"\n @click.stop=\"toggleOpen\"\n >\n <div\n v-if=\"arrowIconLarge\"\n class=\"arrow-icon\"\n :class=\"[`icon-24 ${arrowIconLarge}`]\"\n />\n <div v-else-if=\"arrowIcon\" class=\"arrow-icon\" :class=\"[`icon-16 ${arrowIcon}`]\" />\n <div v-else class=\"arrow-icon arrow-icon-default\" />\n </div>\n </div>\n </div>\n <label v-if=\"label\" data-testid=\"pl-autocomplete-label\">\n <PlSvg v-if=\"required\" :uri=\"SvgRequired\" data-testid=\"pl-autocomplete-required\" />\n <span>{{ label }}</span>\n <PlTooltip\n v-if=\"slots.tooltip\"\n class=\"info\"\n position=\"top\"\n data-testid=\"pl-autocomplete-tooltip\"\n >\n <template #tooltip>\n <slot name=\"tooltip\" />\n </template>\n </PlTooltip>\n </label>\n <DropdownOverlay\n v-if=\"data.open\"\n ref=\"overlay\"\n :root=\"rootRef\"\n class=\"pl-autocomplete__options\"\n data-testid=\"pl-autocomplete-options\"\n tabindex=\"-1\"\n :gap=\"3\"\n >\n <DropdownListItem\n v-for=\"(item, index) in renderedOptionsRef\"\n :key=\"index\"\n :option=\"item\"\n :is-selected=\"item.isSelected\"\n :is-hovered=\"item.isActive\"\n :size=\"optionSize\"\n data-testid=\"pl-autocomplete-option\"\n @click.stop=\"selectOption(item)\"\n />\n <div\n v-if=\"!renderedOptionsRef.length\"\n class=\"nothing-found\"\n data-testid=\"pl-autocomplete-options-empty\"\n >\n Nothing found\n </div>\n </DropdownOverlay>\n <DoubleContour class=\"pl-autocomplete__contour\" :group-position=\"groupPosition\" />\n </div>\n </div>\n <div v-if=\"computedError\" class=\"pl-autocomplete__error\" data-testid=\"pl-autocomplete-error\">\n {{ computedError }}\n </div>\n <div\n v-else-if=\"isLoadingOptions && loadingOptionsHelper\"\n class=\"pl-autocomplete__helper\"\n data-testid=\"pl-autocomplete-helper\"\n >\n {{ loadingOptionsHelper }}\n </div>\n <div v-else-if=\"helper\" class=\"pl-autocomplete__helper\" data-testid=\"pl-autocomplete-helper\">\n {{ helper }}\n </div>\n </div>\n</template>\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"PlAutocompleteMulti.js","names":[],"sources":["../../../src/components/PlAutocompleteMulti/PlAutocompleteMulti.vue"],"sourcesContent":["<script lang=\"ts\">\n/**\n * A multi-select autocomplete component that allows users to search and select multiple values from a list of options.\n * Supports async data fetching, keyboard navigation, and displays selected items as removable chips.\n *\n * @example\n * Basic usage:\n * <PlAutocompleteMulti\n * v-model=\"selectedUsers\"\n * :options-search=\"searchUsers\"\n * :model-search=\"getUsersByIds\"\n * label=\"Select Users\"\n * placeholder=\"Search for users...\"\n * required\n * :debounce=\"300\"\n * helper=\"Choose one or more users from the list\"\n * />\n *\n * With async functions:\n * const selectedUsers = ref([])\n *\n * const searchUsers = async (searchTerm) => {\n * const response = await fetch('/api/users/search?q=' + searchTerm)\n * const users = await response.json()\n * return users.map(user => ({ value: user.id, label: user.name }))\n * }\n *\n * const getUsersByIds = async (userIds) => {\n * if (!userIds.length) return []\n * const response = await fetch('/api/users?ids=' + userIds.join(','))\n * const users = await response.json()\n * return users.map(user => ({ value: user.id, label: user.name }))\n * }\n */\nexport default {\n name: \"PlAutocompleteMulti\",\n};\n\nexport interface OptionsSearch<T> {\n (s: string, type: \"label\"): Promise<Readonly<ListOptionBase<T>[]>>;\n (s: T[], type: \"value\"): Promise<Readonly<ListOptionBase<T>[]>>;\n}\n</script>\n\n<script lang=\"ts\" setup generic=\"M extends string | number = string\">\nimport \"./pl-autocomplete-multi.scss\";\n\nimport type { ListOptionBase } from \"@platforma-sdk/model\";\nimport canonicalize from \"canonicalize\";\nimport { computed, reactive, ref, toRef, unref, useSlots, useTemplateRef, watch } from \"vue\";\nimport { useWatchFetch } from \"../../composition/useWatchFetch.ts\";\nimport { getErrorMessage } from \"../../helpers/error.ts\";\nimport { deepEqual, deepIncludes } from \"../../helpers/objects\";\nimport DoubleContour from \"../../utils/DoubleContour.vue\";\nimport DropdownOverlay from \"../../utils/DropdownOverlay/DropdownOverlay.vue\";\nimport { useLabelNotch } from \"../../utils/useLabelNotch\";\nimport DropdownListItem from \"../DropdownListItem.vue\";\nimport { PlChip } from \"../PlChip\";\nimport { PlMaskIcon24 } from \"../PlMaskIcon24\";\nimport { PlTooltip } from \"../PlTooltip\";\n\nimport SvgRequired from \"../../assets/images/required.svg?raw\";\nimport { PlSvg } from \"../PlSvg\";\n\nconst emit = defineEmits<{\n (e: \"update:modelValue\", v: M[]): void;\n}>();\n\nconst emitModel = (v: M[]) => emit(\"update:modelValue\", v);\n\nconst slots = useSlots();\n\nconst props = withDefaults(\n defineProps<{\n /**\n * The current selected values.\n */\n modelValue: M[];\n /**\n * Lambda for requesting of available options for the dropdown by search string.\n */\n optionsSearch: OptionsSearch<M>;\n /**\n * Unique identifier for the source of the options, changing it will invalidate the options cache.\n */\n sourceId?: string;\n /**\n * The label text for the dropdown field (optional)\n */\n label?: string;\n /**\n * A helper text displayed below the dropdown when there are no errors (optional).\n */\n helper?: string;\n /**\n * Error message displayed below the dropdown (optional)\n */\n error?: unknown;\n /**\n * Placeholder text shown when no value is selected.\n */\n placeholder?: string;\n /**\n * If `true`, the dropdown component is marked as required.\n */\n required?: boolean;\n /**\n * If `true`, the dropdown component is disabled and cannot be interacted with.\n */\n disabled?: boolean;\n /**\n * Debounce time in ms for the options search.\n */\n debounce?: number;\n /**\n * If `true`, the search input is reset and focus is set on it when the new option is selected.\n */\n resetSearchOnSelect?: boolean;\n /**\n * The text to display when no options are found.\n */\n emptyOptionsText?: string;\n /**\n * Makes some of corners not rounded\n * */\n groupPosition?:\n | \"top\"\n | \"bottom\"\n | \"left\"\n | \"right\"\n | \"top-left\"\n | \"top-right\"\n | \"bottom-left\"\n | \"bottom-right\"\n | \"middle\";\n }>(),\n {\n modelValue: () => [],\n label: undefined,\n helper: undefined,\n error: undefined,\n placeholder: \"...\",\n required: false,\n disabled: false,\n debounce: 300,\n emptyOptionsText: \"Nothing found\",\n sourceId: undefined,\n groupPosition: undefined,\n },\n);\n\nconst rootRef = ref<HTMLElement | undefined>();\nconst inputRef = ref<HTMLInputElement | undefined>();\n\nconst overlay = useTemplateRef(\"overlay\");\n\nconst data = reactive({\n search: \"\",\n activeOption: -1,\n open: false,\n optionsHeight: 0,\n});\n\nwatch(\n () => data.open,\n (v) => {\n if (!v) {\n data.search = \"\";\n }\n },\n { flush: \"sync\" },\n);\n\nconst selectedValuesRef = computed(() => (Array.isArray(props.modelValue) ? props.modelValue : []));\n\nconst placeholderRef = computed(() => {\n if (data.open && props.modelValue.length > 0) {\n return props.placeholder;\n }\n\n return props.modelValue.length > 0 ? \"\" : props.placeholder;\n});\n\nconst debounce = toRef(props, \"debounce\");\n\nconst searchOptionsRef = useWatchFetch(\n () => [data.search, data.open, props.sourceId] as const,\n async ([search, _open]) => {\n return props.optionsSearch(search, \"label\");\n },\n {\n filterWatchResult: ([_search, open]) => open,\n debounce,\n },\n);\n\nconst modelOptionsRef = useWatchFetch(\n () => [props.modelValue, props.sourceId] as const,\n async ([v]) => {\n return props.optionsSearch(v, \"value\");\n },\n {\n debounce,\n },\n);\n\nconst allOptionsRef = computed(() => {\n const modelOptions = modelOptionsRef.value ?? [];\n const searchOptions = searchOptionsRef.value ?? [];\n\n const seenValues = new Set<string | undefined>();\n const result = [] as ListOptionBase<M>[];\n\n const addOptions = (options: Readonly<ListOptionBase<M>[]>) => {\n for (const option of options) {\n const canonicalValue = canonicalize(option.value);\n if (!seenValues.has(canonicalValue)) {\n seenValues.add(canonicalValue);\n result.push(option);\n }\n }\n };\n\n addOptions(modelOptions);\n addOptions(searchOptions);\n\n return result;\n});\n\nconst selectedOptionsRef = computed(() => {\n return selectedValuesRef.value\n .map((v) => allOptionsRef.value.find((opt) => deepEqual(opt.value, v)))\n .filter((v) => v !== undefined);\n});\n\nconst filteredOptionsRef = computed(() => {\n const selectedValues = unref(selectedValuesRef);\n\n const options = searchOptionsRef.value ?? [];\n\n return [...options].map((opt) => ({\n ...opt,\n selected: deepIncludes(selectedValues, opt.value),\n }));\n});\n\nconst isOptionsLoading = computed(() => searchOptionsRef.loading || modelOptionsRef.loading);\n\nconst isDisabled = computed(() => {\n if (modelOptionsRef.value === undefined) {\n return true;\n }\n\n return props.disabled;\n});\n\nconst tabindex = computed(() => (isDisabled.value ? undefined : \"0\"));\n\nconst updateActiveOption = () => {\n data.activeOption = 0;\n};\n\nconst selectOption = (v: M) => {\n const values = unref(selectedValuesRef);\n emitModel(deepIncludes(values, v) ? values.filter((it) => !deepEqual(it, v)) : [...values, v]);\n if (props.resetSearchOnSelect) {\n data.search = \"\";\n }\n inputRef.value?.focus();\n};\n\nconst unselectOption = (d: M) =>\n emitModel(unref(selectedValuesRef).filter((v) => !deepEqual(v, d)));\n\nconst setFocusOnInput = () => inputRef.value?.focus();\n\nconst toggleOpen = () => (data.open = !data.open);\n\nconst onFocusOut = (event: FocusEvent) => {\n const relatedTarget = event.relatedTarget as Node | null;\n\n if (!rootRef.value?.contains(relatedTarget) && !overlay.value?.listRef?.contains(relatedTarget)) {\n data.open = false;\n }\n};\n\nconst handleKeydown = (e: { code: string; preventDefault(): void }) => {\n const { open, activeOption } = data;\n\n if (!open) {\n if (e.code === \"Enter\") {\n data.open = true;\n }\n return;\n }\n\n if (e.code === \"Escape\") {\n data.open = false;\n inputRef.value?.focus();\n }\n\n const filteredOptions = unref(filteredOptionsRef);\n\n const { length } = filteredOptions;\n\n if (!length) {\n return;\n }\n\n if ([\"ArrowDown\", \"ArrowUp\", \"Enter\"].includes(e.code)) {\n e.preventDefault();\n }\n\n if (e.code === \"Enter\") {\n selectOption(filteredOptions[activeOption].value);\n }\n\n const d = e.code === \"ArrowDown\" ? 1 : e.code === \"ArrowUp\" ? -1 : 0;\n\n data.activeOption = Math.abs(activeOption + d + length) % length;\n\n requestAnimationFrame(() => overlay.value?.scrollIntoActive());\n};\n\nuseLabelNotch(rootRef);\n\nwatch(\n () => props.modelValue,\n () => updateActiveOption(),\n { immediate: true },\n);\n\nconst computedError = computed(() => {\n if (isOptionsLoading.value) {\n return undefined;\n }\n\n if (searchOptionsRef.error) {\n return getErrorMessage(searchOptionsRef.error);\n }\n\n if (modelOptionsRef.error) {\n return getErrorMessage(modelOptionsRef.error);\n }\n\n if (props.error) {\n return getErrorMessage(props.error);\n }\n\n if (props.modelValue.length && selectedOptionsRef.value.length !== props.modelValue.length) {\n return \"The selected values are not one of the options\";\n }\n\n return undefined;\n});\n</script>\n\n<template>\n <div class=\"pl-autocomplete-multi__envelope\" @click=\"setFocusOnInput\">\n <div\n ref=\"rootRef\"\n :tabindex=\"tabindex\"\n class=\"pl-autocomplete-multi\"\n :class=\"{ open: data.open, error: Boolean(computedError), disabled: isDisabled }\"\n @keydown=\"handleKeydown\"\n @focusout=\"onFocusOut\"\n >\n <div class=\"pl-autocomplete-multi__container\">\n <div class=\"pl-autocomplete-multi__field\">\n <input\n ref=\"inputRef\"\n v-model=\"data.search\"\n type=\"text\"\n tabindex=\"-1\"\n :disabled=\"isDisabled\"\n :placeholder=\"placeholderRef\"\n spellcheck=\"false\"\n autocomplete=\"chrome-off\"\n @focus=\"data.open = true\"\n />\n <div v-if=\"!data.open\" class=\"chips-container\">\n <PlChip\n v-for=\"(opt, i) in selectedOptionsRef\"\n :key=\"i\"\n closeable\n small\n @click.stop=\"data.open = true\"\n @close=\"unselectOption(opt.value)\"\n >\n {{ opt.label || opt.value }}\n </PlChip>\n </div>\n\n <div class=\"pl-autocomplete-multi__controls\">\n <PlMaskIcon24 v-if=\"isOptionsLoading\" name=\"loading\" />\n <slot name=\"append\" />\n <div class=\"pl-autocomplete-multi__arrow-wrapper\" @click.stop=\"toggleOpen\">\n <div class=\"arrow-icon arrow-icon-default\" />\n </div>\n </div>\n </div>\n <label v-if=\"label\">\n <PlSvg v-if=\"required\" :uri=\"SvgRequired\" />\n <span>{{ label }}</span>\n <PlTooltip v-if=\"slots.tooltip\" class=\"info\" position=\"top\">\n <template #tooltip>\n <slot name=\"tooltip\" />\n </template>\n </PlTooltip>\n </label>\n <DropdownOverlay\n v-if=\"data.open\"\n ref=\"overlay\"\n :root=\"rootRef\"\n class=\"pl-autocomplete-multi__options\"\n :gap=\"5\"\n tabindex=\"-1\"\n @focusout=\"onFocusOut\"\n >\n <div class=\"pl-autocomplete-multi__open-chips-container\">\n <PlChip\n v-for=\"(opt, i) in selectedOptionsRef\"\n :key=\"i\"\n closeable\n small\n @close=\"unselectOption(opt.value)\"\n >\n {{ opt.label || opt.value }}\n </PlChip>\n </div>\n <DropdownListItem\n v-for=\"(item, index) in filteredOptionsRef\"\n :key=\"index\"\n :option=\"item\"\n :text-item=\"'text'\"\n :is-selected=\"item.selected\"\n :is-hovered=\"data.activeOption == index\"\n size=\"medium\"\n use-checkbox\n @click.stop=\"selectOption(item.value)\"\n />\n <div v-if=\"!filteredOptionsRef.length && !isOptionsLoading\" class=\"nothing-found\">\n {{ emptyOptionsText }}\n </div>\n </DropdownOverlay>\n <DoubleContour class=\"pl-autocomplete-multi__contour\" :group-position=\"groupPosition\" />\n </div>\n </div>\n <div v-if=\"computedError\" class=\"pl-autocomplete-multi__error\">{{ computedError }}</div>\n <div v-else-if=\"helper\" class=\"pl-autocomplete-multi__helper\">{{ helper }}</div>\n </div>\n</template>\n"],"mappings":""}
1
+ {"version":3,"file":"PlAutocompleteMulti.js","names":[],"sources":["../../../src/components/PlAutocompleteMulti/PlAutocompleteMulti.vue"],"sourcesContent":["<script lang=\"ts\">\n/**\n * A multi-select autocomplete component that allows users to search and select multiple values from a list of options.\n * Supports async data fetching, keyboard navigation, and displays selected items as removable chips.\n *\n * @example\n * Basic usage:\n * <PlAutocompleteMulti\n * v-model=\"selectedUsers\"\n * :options-search=\"searchUsers\"\n * :model-search=\"getUsersByIds\"\n * label=\"Select Users\"\n * placeholder=\"Search for users...\"\n * required\n * :debounce=\"300\"\n * helper=\"Choose one or more users from the list\"\n * />\n *\n * With async functions:\n * const selectedUsers = ref([])\n *\n * const searchUsers = async (searchTerm) => {\n * const response = await fetch('/api/users/search?q=' + searchTerm)\n * const users = await response.json()\n * return users.map(user => ({ value: user.id, label: user.name }))\n * }\n *\n * const getUsersByIds = async (userIds) => {\n * if (!userIds.length) return []\n * const response = await fetch('/api/users?ids=' + userIds.join(','))\n * const users = await response.json()\n * return users.map(user => ({ value: user.id, label: user.name }))\n * }\n */\nexport default {\n name: \"PlAutocompleteMulti\",\n};\n\nexport interface OptionsSearch<T> {\n (s: string, type: \"label\"): Promise<Readonly<ListOptionBase<T>[]>>;\n (s: T[], type: \"value\"): Promise<Readonly<ListOptionBase<T>[]>>;\n}\n</script>\n\n<script lang=\"ts\" setup generic=\"M extends string | number = string\">\nimport \"./pl-autocomplete-multi.scss\";\n\nimport type { ListOptionBase } from \"@platforma-sdk/model\";\nimport canonicalize from \"canonicalize\";\nimport { computed, reactive, ref, toRef, unref, useSlots, useTemplateRef, watch } from \"vue\";\nimport { useWatchFetch } from \"../../composition/useWatchFetch.ts\";\nimport { getErrorMessage } from \"../../helpers/error.ts\";\nimport { deepEqual, deepIncludes } from \"../../helpers/objects\";\nimport DoubleContour from \"../../utils/DoubleContour.vue\";\nimport DropdownOverlay from \"../../utils/DropdownOverlay/DropdownOverlay.vue\";\nimport { useLabelNotch } from \"../../utils/useLabelNotch\";\nimport DropdownListItem from \"../DropdownListItem.vue\";\nimport { PlChip } from \"../PlChip\";\nimport { PlMaskIcon24 } from \"../PlMaskIcon24\";\nimport { PlTooltip } from \"../PlTooltip\";\n\nimport SvgRequired from \"../../assets/images/required.svg?raw\";\nimport { PlSvg } from \"../PlSvg\";\n\nconst emit = defineEmits<{\n (e: \"update:modelValue\", v: M[]): void;\n}>();\n\nconst emitModel = (v: M[]) => emit(\"update:modelValue\", v);\n\nconst slots = useSlots();\n\nconst props = withDefaults(\n defineProps<{\n /**\n * The current selected values.\n */\n modelValue: M[];\n /**\n * Lambda for requesting of available options for the dropdown by search string.\n */\n optionsSearch: OptionsSearch<M>;\n /**\n * Unique identifier for the source of the options, changing it will invalidate the options cache.\n */\n sourceId?: string;\n /**\n * The label text for the dropdown field (optional)\n */\n label?: string;\n /**\n * A helper text displayed below the dropdown when there are no errors (optional).\n */\n helper?: string;\n /**\n * Error message displayed below the dropdown (optional)\n */\n error?: unknown;\n /**\n * Placeholder text shown when no value is selected.\n */\n placeholder?: string;\n /**\n * If `true`, the dropdown component is marked as required.\n */\n required?: boolean;\n /**\n * If `true`, the dropdown component is disabled and cannot be interacted with.\n */\n disabled?: boolean;\n /**\n * Debounce time in ms for the options search.\n */\n debounce?: number;\n /**\n * If `true`, the search input is reset and focus is set on it when the new option is selected.\n */\n resetSearchOnSelect?: boolean;\n /**\n * The text to display when no options are found.\n */\n emptyOptionsText?: string;\n /**\n * Makes some of corners not rounded\n * */\n groupPosition?:\n | \"top\"\n | \"bottom\"\n | \"left\"\n | \"right\"\n | \"top-left\"\n | \"top-right\"\n | \"bottom-left\"\n | \"bottom-right\"\n | \"middle\";\n }>(),\n {\n modelValue: () => [],\n label: undefined,\n helper: undefined,\n error: undefined,\n placeholder: \"...\",\n required: false,\n disabled: false,\n debounce: 300,\n emptyOptionsText: \"Nothing found\",\n sourceId: undefined,\n groupPosition: undefined,\n },\n);\n\nconst rootRef = ref<HTMLElement | undefined>();\nconst inputRef = ref<HTMLInputElement | undefined>();\n\nconst overlay = useTemplateRef(\"overlay\");\n\nconst data = reactive({\n search: \"\",\n activeOption: -1,\n open: false,\n optionsHeight: 0,\n});\n\nwatch(\n () => data.open,\n (v) => {\n if (!v) {\n data.search = \"\";\n }\n },\n { flush: \"sync\" },\n);\n\nconst selectedValuesRef = computed(() => (Array.isArray(props.modelValue) ? props.modelValue : []));\n\nconst placeholderRef = computed(() => {\n if (data.open && props.modelValue.length > 0) {\n return props.placeholder;\n }\n\n return props.modelValue.length > 0 ? \"\" : props.placeholder;\n});\n\nconst debounce = toRef(props, \"debounce\");\n\nconst searchOptionsRef = useWatchFetch(\n () => [data.search, data.open, props.sourceId] as const,\n async ([search, _open]) => {\n return props.optionsSearch(search, \"label\");\n },\n {\n filterWatchResult: ([_search, open]) => open,\n debounce,\n },\n);\n\nconst modelOptionsRef = useWatchFetch(\n () => [props.modelValue, props.sourceId] as const,\n async ([v]) => {\n return props.optionsSearch(v, \"value\");\n },\n {\n debounce,\n },\n);\n\nconst allOptionsRef = computed(() => {\n const modelOptions = modelOptionsRef.value ?? [];\n const searchOptions = searchOptionsRef.value ?? [];\n\n const seenValues = new Set<string | undefined>();\n const result = [] as ListOptionBase<M>[];\n\n const addOptions = (options: Readonly<ListOptionBase<M>[]>) => {\n for (const option of options) {\n const canonicalValue = canonicalize(option.value);\n if (!seenValues.has(canonicalValue)) {\n seenValues.add(canonicalValue);\n result.push(option);\n }\n }\n };\n\n addOptions(modelOptions);\n addOptions(searchOptions);\n\n return result;\n});\n\nconst selectedOptionsRef = computed(() => {\n return selectedValuesRef.value\n .map((v) => allOptionsRef.value.find((opt) => deepEqual(opt.value, v)))\n .filter((v) => v !== undefined);\n});\n\nconst filteredOptionsRef = computed(() => {\n const selectedValues = unref(selectedValuesRef);\n\n const options = searchOptionsRef.value ?? [];\n\n return [...options].map((opt) => ({\n ...opt,\n selected: deepIncludes(selectedValues, opt.value),\n }));\n});\n\nconst isOptionsLoading = computed(() => searchOptionsRef.loading || modelOptionsRef.loading);\n\nconst isDisabled = computed(() => {\n if (modelOptionsRef.value === undefined) {\n return true;\n }\n\n return props.disabled;\n});\n\nconst tabindex = computed(() => (isDisabled.value ? undefined : \"0\"));\n\nconst updateActiveOption = () => {\n data.activeOption = 0;\n};\n\nconst selectOption = (v: M) => {\n const values = unref(selectedValuesRef);\n emitModel(deepIncludes(values, v) ? values.filter((it) => !deepEqual(it, v)) : [...values, v]);\n if (props.resetSearchOnSelect) {\n data.search = \"\";\n }\n inputRef.value?.focus();\n};\n\nconst unselectOption = (d: M) =>\n emitModel(unref(selectedValuesRef).filter((v) => !deepEqual(v, d)));\n\nconst setFocusOnInput = () => inputRef.value?.focus();\n\nconst toggleOpen = () => (data.open = !data.open);\n\nconst onFocusOut = (event: FocusEvent) => {\n const relatedTarget = event.relatedTarget as Node | null;\n\n if (!rootRef.value?.contains(relatedTarget) && !overlay.value?.listRef?.contains(relatedTarget)) {\n data.open = false;\n }\n};\n\nconst handleKeydown = (e: { code: string; preventDefault(): void }) => {\n const { open, activeOption } = data;\n\n if (!open) {\n if (e.code === \"Enter\") {\n data.open = true;\n }\n return;\n }\n\n if (e.code === \"Escape\") {\n data.open = false;\n inputRef.value?.focus();\n }\n\n const filteredOptions = unref(filteredOptionsRef);\n\n const { length } = filteredOptions;\n\n if (!length) {\n return;\n }\n\n if ([\"ArrowDown\", \"ArrowUp\", \"Enter\"].includes(e.code)) {\n e.preventDefault();\n }\n\n if (e.code === \"Enter\") {\n selectOption(filteredOptions[activeOption].value);\n }\n\n const d = e.code === \"ArrowDown\" ? 1 : e.code === \"ArrowUp\" ? -1 : 0;\n\n data.activeOption = Math.abs(activeOption + d + length) % length;\n\n requestAnimationFrame(() => overlay.value?.scrollIntoActive());\n};\n\nuseLabelNotch(rootRef);\n\nwatch(\n () => props.modelValue,\n () => updateActiveOption(),\n { immediate: true },\n);\n\nconst computedError = computed(() => {\n if (isOptionsLoading.value) {\n return undefined;\n }\n\n if (searchOptionsRef.error) {\n return getErrorMessage(searchOptionsRef.error);\n }\n\n if (modelOptionsRef.error) {\n return getErrorMessage(modelOptionsRef.error);\n }\n\n if (props.error) {\n return getErrorMessage(props.error);\n }\n\n if (props.modelValue.length && selectedOptionsRef.value.length !== props.modelValue.length) {\n return \"The selected values are not one of the options\";\n }\n\n return undefined;\n});\n</script>\n\n<template>\n <div\n class=\"pl-autocomplete-multi__envelope\"\n @click=\"setFocusOnInput\"\n data-testid=\"pl-autocomplete-multi\"\n >\n <div\n ref=\"rootRef\"\n :tabindex=\"tabindex\"\n class=\"pl-autocomplete-multi\"\n data-testid=\"pl-autocomplete-multi-control\"\n :class=\"{ open: data.open, error: Boolean(computedError), disabled: isDisabled }\"\n @keydown=\"handleKeydown\"\n @focusout=\"onFocusOut\"\n >\n <div class=\"pl-autocomplete-multi__container\">\n <div class=\"pl-autocomplete-multi__field\">\n <input\n ref=\"inputRef\"\n v-model=\"data.search\"\n type=\"text\"\n tabindex=\"-1\"\n :disabled=\"isDisabled\"\n :placeholder=\"placeholderRef\"\n spellcheck=\"false\"\n autocomplete=\"chrome-off\"\n data-testid=\"pl-autocomplete-multi-input\"\n @focus=\"data.open = true\"\n />\n <div v-if=\"!data.open\" class=\"chips-container\" data-testid=\"pl-autocomplete-multi-chips\">\n <PlChip\n v-for=\"(opt, i) in selectedOptionsRef\"\n :key=\"i\"\n closeable\n data-testid=\"pl-autocomplete-multi-chip\"\n small\n @click.stop=\"data.open = true\"\n @close=\"unselectOption(opt.value)\"\n >\n {{ opt.label || opt.value }}\n </PlChip>\n </div>\n\n <div class=\"pl-autocomplete-multi__controls\">\n <PlMaskIcon24\n v-if=\"isOptionsLoading\"\n name=\"loading\"\n data-testid=\"pl-autocomplete-multi-loading\"\n />\n <slot name=\"append\" />\n <div\n class=\"pl-autocomplete-multi__arrow-wrapper\"\n data-testid=\"pl-autocomplete-multi-arrow\"\n @click.stop=\"toggleOpen\"\n >\n <div class=\"arrow-icon arrow-icon-default\" />\n </div>\n </div>\n </div>\n <label v-if=\"label\" data-testid=\"pl-autocomplete-multi-label\">\n <PlSvg v-if=\"required\" :uri=\"SvgRequired\" data-testid=\"pl-autocomplete-multi-required\" />\n <span>{{ label }}</span>\n <PlTooltip\n v-if=\"slots.tooltip\"\n class=\"info\"\n position=\"top\"\n data-testid=\"pl-autocomplete-multi-tooltip\"\n >\n <template #tooltip>\n <slot name=\"tooltip\" />\n </template>\n </PlTooltip>\n </label>\n <DropdownOverlay\n v-if=\"data.open\"\n ref=\"overlay\"\n :root=\"rootRef\"\n class=\"pl-autocomplete-multi__options\"\n data-testid=\"pl-autocomplete-multi-options\"\n :gap=\"5\"\n tabindex=\"-1\"\n @focusout=\"onFocusOut\"\n >\n <div\n class=\"pl-autocomplete-multi__open-chips-container\"\n data-testid=\"pl-autocomplete-multi-chips\"\n >\n <PlChip\n v-for=\"(opt, i) in selectedOptionsRef\"\n :key=\"i\"\n closeable\n data-testid=\"pl-autocomplete-multi-chip\"\n small\n @close=\"unselectOption(opt.value)\"\n >\n {{ opt.label || opt.value }}\n </PlChip>\n </div>\n <DropdownListItem\n v-for=\"(item, index) in filteredOptionsRef\"\n :key=\"index\"\n :option=\"item\"\n :text-item=\"'text'\"\n :is-selected=\"item.selected\"\n :is-hovered=\"data.activeOption == index\"\n size=\"medium\"\n use-checkbox\n data-testid=\"pl-autocomplete-multi-option\"\n @click.stop=\"selectOption(item.value)\"\n />\n <div\n v-if=\"!filteredOptionsRef.length && !isOptionsLoading\"\n class=\"nothing-found\"\n data-testid=\"pl-autocomplete-multi-options-empty\"\n >\n {{ emptyOptionsText }}\n </div>\n </DropdownOverlay>\n <DoubleContour class=\"pl-autocomplete-multi__contour\" :group-position=\"groupPosition\" />\n </div>\n </div>\n <div\n v-if=\"computedError\"\n class=\"pl-autocomplete-multi__error\"\n data-testid=\"pl-autocomplete-multi-error\"\n >\n {{ computedError }}\n </div>\n <div\n v-else-if=\"helper\"\n class=\"pl-autocomplete-multi__helper\"\n data-testid=\"pl-autocomplete-multi-helper\"\n >\n {{ helper }}\n </div>\n </div>\n</template>\n"],"mappings":""}
@@ -1 +1 @@
1
- {"version":3,"file":"PlAutocompleteMulti.vue.d.ts","sourceRoot":"","sources":["../../../src/components/PlAutocompleteMulti/PlAutocompleteMulti.vue"],"names":[],"mappings":"AAucA,OAAO,8BAA8B,CAAC;AAEtC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAkB3D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;wBACkB,OAAO,YAAY;AAAxC,wBAAyC;AAMzC,MAAM,WAAW,aAAa,CAAC,CAAC;IAC9B,CAAC,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IACnE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;CACjE;AACD,QAAA,MAAM,YAAY,GAAK,CAAC,SAAS,MAAM,GAAG,MAAM,GAAG,MAAM,EACxD,aAAa,WAAW,CAAC,OAAO,CAAC,OAAO,WAAW,CAAC,CAAC,CAAC,OAAO,CAAC,EAC9D,YAAY,mBAAmB,CAAC,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,OAAO,WAAW,CAAC,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,OAAO,CAAC,CAAC,EAC3G,gBAAgB,WAAW,CAAC,OAAO,CAAC,OAAO,WAAW,CAAC,CAAC,CAAC,QAAQ,CAAC,EAClE;WA6pBO,OAAO,KAAK,EAAE,WAAW,GAAG,mBAAmB,CAAC;QAlpBpD;;WAEG;oBACS,CAAC,EAAE;QACf;;WAEG;uBACY,aAAa,CAAC,CAAC,CAAC;QAC/B;;WAEG;mBACQ,MAAM;QACjB;;WAEG;gBACK,MAAM;QACd;;WAEG;iBACM,MAAM;QACf;;WAEG;gBACK,OAAO;QACf;;WAEG;sBACW,MAAM;QACpB;;WAEG;mBACQ,OAAO;QAClB;;WAEG;mBACQ,OAAO;QAClB;;WAEG;mBACQ,MAAM;QACjB;;WAEG;8BACmB,OAAO;QAC7B;;WAEG;2BACgB,MAAM;QACzB;;aAEK;wBAED,KAAK,GACL,QAAQ,GACR,MAAM,GACN,OAAO,GACP,UAAU,GACV,WAAW,GACX,aAAa,GACb,cAAc,GACd,QAAQ;;;KAslB2E,CAAC,GAAG,CAAC,OAAO,UAAU,SAAS;QAAE,oBAAoB,EAAE,MAAM,CAAC,CAAA;KAAE,GAAG,CAAC,GAAG,EAAE,CAAC;YAC5J,CAAC,OAAO,EAAE,EAAE,KAAK,IAAI;WACtB,GAAG;;iBAbE,CAAC,KAAK,IAAiB,KAAK,GAAG;;kBAC9B,CAAC,KAAK,IAAiB,KAAK,GAAG;;cAjpBvC,mBAAmB,KAAK,CAAC,EAAE,KAAG,IAAI;EAiqBpC,KACQ,OAAO,KAAK,EAAE,KAAK,GAAG;IAAE,KAAK,CAAC,EAAE,WAAW,CAAC,OAAO,CAAC,OAAO,WAAW,CAAC,CAAC,CAAA;CAAI,CAAC;AACzF,KAAK,mBAAmB,CAAC,CAAC,IAAI,CAAC,CAAC,SAAS,GAAG,GAAG;KAAG,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;CAAG,GAAG;KAAG,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;CAAG,CAAC,GAAG,EAAE,CAAC"}
1
+ {"version":3,"file":"PlAutocompleteMulti.vue.d.ts","sourceRoot":"","sources":["../../../src/components/PlAutocompleteMulti/PlAutocompleteMulti.vue"],"names":[],"mappings":"AAifA,OAAO,8BAA8B,CAAC;AAEtC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAkB3D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;wBACkB,OAAO,YAAY;AAAxC,wBAAyC;AAMzC,MAAM,WAAW,aAAa,CAAC,CAAC;IAC9B,CAAC,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IACnE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;CACjE;AACD,QAAA,MAAM,YAAY,GAAK,CAAC,SAAS,MAAM,GAAG,MAAM,GAAG,MAAM,EACxD,aAAa,WAAW,CAAC,OAAO,CAAC,OAAO,WAAW,CAAC,CAAC,CAAC,OAAO,CAAC,EAC9D,YAAY,mBAAmB,CAAC,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,OAAO,WAAW,CAAC,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,OAAO,CAAC,CAAC,EAC3G,gBAAgB,WAAW,CAAC,OAAO,CAAC,OAAO,WAAW,CAAC,CAAC,CAAC,QAAQ,CAAC,EAClE;WAqrBO,OAAO,KAAK,EAAE,WAAW,GAAG,mBAAmB,CAAC;QA1qBpD;;WAEG;oBACS,CAAC,EAAE;QACf;;WAEG;uBACY,aAAa,CAAC,CAAC,CAAC;QAC/B;;WAEG;mBACQ,MAAM;QACjB;;WAEG;gBACK,MAAM;QACd;;WAEG;iBACM,MAAM;QACf;;WAEG;gBACK,OAAO;QACf;;WAEG;sBACW,MAAM;QACpB;;WAEG;mBACQ,OAAO;QAClB;;WAEG;mBACQ,OAAO;QAClB;;WAEG;mBACQ,MAAM;QACjB;;WAEG;8BACmB,OAAO;QAC7B;;WAEG;2BACgB,MAAM;QACzB;;aAEK;wBAED,KAAK,GACL,QAAQ,GACR,MAAM,GACN,OAAO,GACP,UAAU,GACV,WAAW,GACX,aAAa,GACb,cAAc,GACd,QAAQ;;;KA8mB2E,CAAC,GAAG,CAAC,OAAO,UAAU,SAAS;QAAE,oBAAoB,EAAE,MAAM,CAAC,CAAA;KAAE,GAAG,CAAC,GAAG,EAAE,CAAC;YAC5J,CAAC,OAAO,EAAE,EAAE,KAAK,IAAI;WACtB,GAAG;;iBAbE,CAAC,KAAK,IAAiB,KAAK,GAAG;;kBAC9B,CAAC,KAAK,IAAiB,KAAK,GAAG;;cAzqBvC,mBAAmB,KAAK,CAAC,EAAE,KAAG,IAAI;EAyrBpC,KACQ,OAAO,KAAK,EAAE,KAAK,GAAG;IAAE,KAAK,CAAC,EAAE,WAAW,CAAC,OAAO,CAAC,OAAO,WAAW,CAAC,CAAC,CAAA;CAAI,CAAC;AACzF,KAAK,mBAAmB,CAAC,CAAC,IAAI,CAAC,CAAC,SAAS,GAAG,GAAG;KAAG,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;CAAG,GAAG;KAAG,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;CAAG,CAAC,GAAG,EAAE,CAAC"}
@@ -20,16 +20,26 @@ import se from "canonicalize";
20
20
  //#region src/components/PlAutocompleteMulti/PlAutocompleteMulti.vue?vue&type=script&setup=true&lang.ts
21
21
  var ce = ["tabindex"], le = { class: "pl-autocomplete-multi__container" }, ue = { class: "pl-autocomplete-multi__field" }, de = ["disabled", "placeholder"], fe = {
22
22
  key: 0,
23
- class: "chips-container"
24
- }, pe = { class: "pl-autocomplete-multi__controls" }, me = { key: 0 }, he = { class: "pl-autocomplete-multi__open-chips-container" }, ge = {
23
+ class: "chips-container",
24
+ "data-testid": "pl-autocomplete-multi-chips"
25
+ }, pe = { class: "pl-autocomplete-multi__controls" }, me = {
25
26
  key: 0,
26
- class: "nothing-found"
27
+ "data-testid": "pl-autocomplete-multi-label"
28
+ }, he = {
29
+ class: "pl-autocomplete-multi__open-chips-container",
30
+ "data-testid": "pl-autocomplete-multi-chips"
31
+ }, ge = {
32
+ key: 0,
33
+ class: "nothing-found",
34
+ "data-testid": "pl-autocomplete-multi-options-empty"
27
35
  }, j = {
28
36
  key: 0,
29
- class: "pl-autocomplete-multi__error"
37
+ class: "pl-autocomplete-multi__error",
38
+ "data-testid": "pl-autocomplete-multi-error"
30
39
  }, M = {
31
40
  key: 1,
32
- class: "pl-autocomplete-multi__helper"
41
+ class: "pl-autocomplete-multi__helper",
42
+ "data-testid": "pl-autocomplete-multi-helper"
33
43
  }, N = /* @__PURE__ */ v({
34
44
  name: "PlAutocompleteMulti",
35
45
  props: {
@@ -121,7 +131,8 @@ var ce = ["tabindex"], le = { class: "pl-autocomplete-multi__container" }, ue =
121
131
  });
122
132
  return (n, o) => (y(), h("div", {
123
133
  class: "pl-autocomplete-multi__envelope",
124
- onClick: xe
134
+ onClick: xe,
135
+ "data-testid": "pl-autocomplete-multi"
125
136
  }, [g("div", {
126
137
  ref_key: "rootRef",
127
138
  ref: R,
@@ -131,6 +142,7 @@ var ce = ["tabindex"], le = { class: "pl-autocomplete-multi__container" }, ue =
131
142
  error: !!$.value,
132
143
  disabled: Y.value
133
144
  }]),
145
+ "data-testid": "pl-autocomplete-multi-control",
134
146
  onKeydown: Ce,
135
147
  onFocusout: Q
136
148
  }, [g("div", le, [
@@ -145,11 +157,13 @@ var ce = ["tabindex"], le = { class: "pl-autocomplete-multi__container" }, ue =
145
157
  placeholder: _e.value,
146
158
  spellcheck: "false",
147
159
  autocomplete: "chrome-off",
160
+ "data-testid": "pl-autocomplete-multi-input",
148
161
  onFocus: o[1] ||= (e) => V.open = !0
149
162
  }, null, 40, de), [[D, V.search]]),
150
163
  V.open ? m("", !0) : (y(), h("div", fe, [(y(!0), h(d, null, S(K.value, (e, t) => (y(), p(E(u), {
151
164
  key: t,
152
165
  closeable: "",
166
+ "data-testid": "pl-autocomplete-multi-chip",
153
167
  small: "",
154
168
  onClick: o[2] ||= A((e) => V.open = !0, ["stop"]),
155
169
  onClose: (t) => Z(e.value)
@@ -160,11 +174,13 @@ var ce = ["tabindex"], le = { class: "pl-autocomplete-multi__container" }, ue =
160
174
  g("div", pe, [
161
175
  J.value ? (y(), p(E(i), {
162
176
  key: 0,
163
- name: "loading"
177
+ name: "loading",
178
+ "data-testid": "pl-autocomplete-multi-loading"
164
179
  })) : m("", !0),
165
180
  C(n.$slots, "append"),
166
181
  g("div", {
167
182
  class: "pl-autocomplete-multi__arrow-wrapper",
183
+ "data-testid": "pl-autocomplete-multi-arrow",
168
184
  onClick: A(Se, ["stop"])
169
185
  }, [...o[3] ||= [g("div", { class: "arrow-icon arrow-icon-default" }, null, -1)]])
170
186
  ])
@@ -172,13 +188,15 @@ var ce = ["tabindex"], le = { class: "pl-autocomplete-multi__container" }, ue =
172
188
  v.label ? (y(), h("label", me, [
173
189
  v.required ? (y(), p(E(r), {
174
190
  key: 0,
175
- uri: E(te)
191
+ uri: E(te),
192
+ "data-testid": "pl-autocomplete-multi-required"
176
193
  }, null, 8, ["uri"])) : m("", !0),
177
194
  g("span", null, w(v.label), 1),
178
195
  E(I).tooltip ? (y(), p(E(t), {
179
196
  key: 1,
180
197
  class: "info",
181
- position: "top"
198
+ position: "top",
199
+ "data-testid": "pl-autocomplete-multi-tooltip"
182
200
  }, {
183
201
  tooltip: k(() => [C(n.$slots, "tooltip")]),
184
202
  _: 3
@@ -190,6 +208,7 @@ var ce = ["tabindex"], le = { class: "pl-autocomplete-multi__container" }, ue =
190
208
  ref: B,
191
209
  root: R.value,
192
210
  class: "pl-autocomplete-multi__options",
211
+ "data-testid": "pl-autocomplete-multi-options",
193
212
  gap: 5,
194
213
  tabindex: "-1",
195
214
  onFocusout: Q
@@ -198,6 +217,7 @@ var ce = ["tabindex"], le = { class: "pl-autocomplete-multi__container" }, ue =
198
217
  g("div", he, [(y(!0), h(d, null, S(K.value, (e, t) => (y(), p(E(u), {
199
218
  key: t,
200
219
  closeable: "",
220
+ "data-testid": "pl-autocomplete-multi-chip",
201
221
  small: "",
202
222
  onClose: (t) => Z(e.value)
203
223
  }, {
@@ -212,6 +232,7 @@ var ce = ["tabindex"], le = { class: "pl-autocomplete-multi__container" }, ue =
212
232
  "is-hovered": V.activeOption == n,
213
233
  size: "medium",
214
234
  "use-checkbox": "",
235
+ "data-testid": "pl-autocomplete-multi-option",
215
236
  onClick: A((e) => X(t.value), ["stop"])
216
237
  }, null, 8, [
217
238
  "option",
@@ -1 +1 @@
1
- {"version":3,"file":"PlAutocompleteMulti.vue_vue_type_script_setup_true_lang.js","names":[],"sources":["../../../src/components/PlAutocompleteMulti/PlAutocompleteMulti.vue"],"sourcesContent":["<script lang=\"ts\">\n/**\n * A multi-select autocomplete component that allows users to search and select multiple values from a list of options.\n * Supports async data fetching, keyboard navigation, and displays selected items as removable chips.\n *\n * @example\n * Basic usage:\n * <PlAutocompleteMulti\n * v-model=\"selectedUsers\"\n * :options-search=\"searchUsers\"\n * :model-search=\"getUsersByIds\"\n * label=\"Select Users\"\n * placeholder=\"Search for users...\"\n * required\n * :debounce=\"300\"\n * helper=\"Choose one or more users from the list\"\n * />\n *\n * With async functions:\n * const selectedUsers = ref([])\n *\n * const searchUsers = async (searchTerm) => {\n * const response = await fetch('/api/users/search?q=' + searchTerm)\n * const users = await response.json()\n * return users.map(user => ({ value: user.id, label: user.name }))\n * }\n *\n * const getUsersByIds = async (userIds) => {\n * if (!userIds.length) return []\n * const response = await fetch('/api/users?ids=' + userIds.join(','))\n * const users = await response.json()\n * return users.map(user => ({ value: user.id, label: user.name }))\n * }\n */\nexport default {\n name: \"PlAutocompleteMulti\",\n};\n\nexport interface OptionsSearch<T> {\n (s: string, type: \"label\"): Promise<Readonly<ListOptionBase<T>[]>>;\n (s: T[], type: \"value\"): Promise<Readonly<ListOptionBase<T>[]>>;\n}\n</script>\n\n<script lang=\"ts\" setup generic=\"M extends string | number = string\">\nimport \"./pl-autocomplete-multi.scss\";\n\nimport type { ListOptionBase } from \"@platforma-sdk/model\";\nimport canonicalize from \"canonicalize\";\nimport { computed, reactive, ref, toRef, unref, useSlots, useTemplateRef, watch } from \"vue\";\nimport { useWatchFetch } from \"../../composition/useWatchFetch.ts\";\nimport { getErrorMessage } from \"../../helpers/error.ts\";\nimport { deepEqual, deepIncludes } from \"../../helpers/objects\";\nimport DoubleContour from \"../../utils/DoubleContour.vue\";\nimport DropdownOverlay from \"../../utils/DropdownOverlay/DropdownOverlay.vue\";\nimport { useLabelNotch } from \"../../utils/useLabelNotch\";\nimport DropdownListItem from \"../DropdownListItem.vue\";\nimport { PlChip } from \"../PlChip\";\nimport { PlMaskIcon24 } from \"../PlMaskIcon24\";\nimport { PlTooltip } from \"../PlTooltip\";\n\nimport SvgRequired from \"../../assets/images/required.svg?raw\";\nimport { PlSvg } from \"../PlSvg\";\n\nconst emit = defineEmits<{\n (e: \"update:modelValue\", v: M[]): void;\n}>();\n\nconst emitModel = (v: M[]) => emit(\"update:modelValue\", v);\n\nconst slots = useSlots();\n\nconst props = withDefaults(\n defineProps<{\n /**\n * The current selected values.\n */\n modelValue: M[];\n /**\n * Lambda for requesting of available options for the dropdown by search string.\n */\n optionsSearch: OptionsSearch<M>;\n /**\n * Unique identifier for the source of the options, changing it will invalidate the options cache.\n */\n sourceId?: string;\n /**\n * The label text for the dropdown field (optional)\n */\n label?: string;\n /**\n * A helper text displayed below the dropdown when there are no errors (optional).\n */\n helper?: string;\n /**\n * Error message displayed below the dropdown (optional)\n */\n error?: unknown;\n /**\n * Placeholder text shown when no value is selected.\n */\n placeholder?: string;\n /**\n * If `true`, the dropdown component is marked as required.\n */\n required?: boolean;\n /**\n * If `true`, the dropdown component is disabled and cannot be interacted with.\n */\n disabled?: boolean;\n /**\n * Debounce time in ms for the options search.\n */\n debounce?: number;\n /**\n * If `true`, the search input is reset and focus is set on it when the new option is selected.\n */\n resetSearchOnSelect?: boolean;\n /**\n * The text to display when no options are found.\n */\n emptyOptionsText?: string;\n /**\n * Makes some of corners not rounded\n * */\n groupPosition?:\n | \"top\"\n | \"bottom\"\n | \"left\"\n | \"right\"\n | \"top-left\"\n | \"top-right\"\n | \"bottom-left\"\n | \"bottom-right\"\n | \"middle\";\n }>(),\n {\n modelValue: () => [],\n label: undefined,\n helper: undefined,\n error: undefined,\n placeholder: \"...\",\n required: false,\n disabled: false,\n debounce: 300,\n emptyOptionsText: \"Nothing found\",\n sourceId: undefined,\n groupPosition: undefined,\n },\n);\n\nconst rootRef = ref<HTMLElement | undefined>();\nconst inputRef = ref<HTMLInputElement | undefined>();\n\nconst overlay = useTemplateRef(\"overlay\");\n\nconst data = reactive({\n search: \"\",\n activeOption: -1,\n open: false,\n optionsHeight: 0,\n});\n\nwatch(\n () => data.open,\n (v) => {\n if (!v) {\n data.search = \"\";\n }\n },\n { flush: \"sync\" },\n);\n\nconst selectedValuesRef = computed(() => (Array.isArray(props.modelValue) ? props.modelValue : []));\n\nconst placeholderRef = computed(() => {\n if (data.open && props.modelValue.length > 0) {\n return props.placeholder;\n }\n\n return props.modelValue.length > 0 ? \"\" : props.placeholder;\n});\n\nconst debounce = toRef(props, \"debounce\");\n\nconst searchOptionsRef = useWatchFetch(\n () => [data.search, data.open, props.sourceId] as const,\n async ([search, _open]) => {\n return props.optionsSearch(search, \"label\");\n },\n {\n filterWatchResult: ([_search, open]) => open,\n debounce,\n },\n);\n\nconst modelOptionsRef = useWatchFetch(\n () => [props.modelValue, props.sourceId] as const,\n async ([v]) => {\n return props.optionsSearch(v, \"value\");\n },\n {\n debounce,\n },\n);\n\nconst allOptionsRef = computed(() => {\n const modelOptions = modelOptionsRef.value ?? [];\n const searchOptions = searchOptionsRef.value ?? [];\n\n const seenValues = new Set<string | undefined>();\n const result = [] as ListOptionBase<M>[];\n\n const addOptions = (options: Readonly<ListOptionBase<M>[]>) => {\n for (const option of options) {\n const canonicalValue = canonicalize(option.value);\n if (!seenValues.has(canonicalValue)) {\n seenValues.add(canonicalValue);\n result.push(option);\n }\n }\n };\n\n addOptions(modelOptions);\n addOptions(searchOptions);\n\n return result;\n});\n\nconst selectedOptionsRef = computed(() => {\n return selectedValuesRef.value\n .map((v) => allOptionsRef.value.find((opt) => deepEqual(opt.value, v)))\n .filter((v) => v !== undefined);\n});\n\nconst filteredOptionsRef = computed(() => {\n const selectedValues = unref(selectedValuesRef);\n\n const options = searchOptionsRef.value ?? [];\n\n return [...options].map((opt) => ({\n ...opt,\n selected: deepIncludes(selectedValues, opt.value),\n }));\n});\n\nconst isOptionsLoading = computed(() => searchOptionsRef.loading || modelOptionsRef.loading);\n\nconst isDisabled = computed(() => {\n if (modelOptionsRef.value === undefined) {\n return true;\n }\n\n return props.disabled;\n});\n\nconst tabindex = computed(() => (isDisabled.value ? undefined : \"0\"));\n\nconst updateActiveOption = () => {\n data.activeOption = 0;\n};\n\nconst selectOption = (v: M) => {\n const values = unref(selectedValuesRef);\n emitModel(deepIncludes(values, v) ? values.filter((it) => !deepEqual(it, v)) : [...values, v]);\n if (props.resetSearchOnSelect) {\n data.search = \"\";\n }\n inputRef.value?.focus();\n};\n\nconst unselectOption = (d: M) =>\n emitModel(unref(selectedValuesRef).filter((v) => !deepEqual(v, d)));\n\nconst setFocusOnInput = () => inputRef.value?.focus();\n\nconst toggleOpen = () => (data.open = !data.open);\n\nconst onFocusOut = (event: FocusEvent) => {\n const relatedTarget = event.relatedTarget as Node | null;\n\n if (!rootRef.value?.contains(relatedTarget) && !overlay.value?.listRef?.contains(relatedTarget)) {\n data.open = false;\n }\n};\n\nconst handleKeydown = (e: { code: string; preventDefault(): void }) => {\n const { open, activeOption } = data;\n\n if (!open) {\n if (e.code === \"Enter\") {\n data.open = true;\n }\n return;\n }\n\n if (e.code === \"Escape\") {\n data.open = false;\n inputRef.value?.focus();\n }\n\n const filteredOptions = unref(filteredOptionsRef);\n\n const { length } = filteredOptions;\n\n if (!length) {\n return;\n }\n\n if ([\"ArrowDown\", \"ArrowUp\", \"Enter\"].includes(e.code)) {\n e.preventDefault();\n }\n\n if (e.code === \"Enter\") {\n selectOption(filteredOptions[activeOption].value);\n }\n\n const d = e.code === \"ArrowDown\" ? 1 : e.code === \"ArrowUp\" ? -1 : 0;\n\n data.activeOption = Math.abs(activeOption + d + length) % length;\n\n requestAnimationFrame(() => overlay.value?.scrollIntoActive());\n};\n\nuseLabelNotch(rootRef);\n\nwatch(\n () => props.modelValue,\n () => updateActiveOption(),\n { immediate: true },\n);\n\nconst computedError = computed(() => {\n if (isOptionsLoading.value) {\n return undefined;\n }\n\n if (searchOptionsRef.error) {\n return getErrorMessage(searchOptionsRef.error);\n }\n\n if (modelOptionsRef.error) {\n return getErrorMessage(modelOptionsRef.error);\n }\n\n if (props.error) {\n return getErrorMessage(props.error);\n }\n\n if (props.modelValue.length && selectedOptionsRef.value.length !== props.modelValue.length) {\n return \"The selected values are not one of the options\";\n }\n\n return undefined;\n});\n</script>\n\n<template>\n <div class=\"pl-autocomplete-multi__envelope\" @click=\"setFocusOnInput\">\n <div\n ref=\"rootRef\"\n :tabindex=\"tabindex\"\n class=\"pl-autocomplete-multi\"\n :class=\"{ open: data.open, error: Boolean(computedError), disabled: isDisabled }\"\n @keydown=\"handleKeydown\"\n @focusout=\"onFocusOut\"\n >\n <div class=\"pl-autocomplete-multi__container\">\n <div class=\"pl-autocomplete-multi__field\">\n <input\n ref=\"inputRef\"\n v-model=\"data.search\"\n type=\"text\"\n tabindex=\"-1\"\n :disabled=\"isDisabled\"\n :placeholder=\"placeholderRef\"\n spellcheck=\"false\"\n autocomplete=\"chrome-off\"\n @focus=\"data.open = true\"\n />\n <div v-if=\"!data.open\" class=\"chips-container\">\n <PlChip\n v-for=\"(opt, i) in selectedOptionsRef\"\n :key=\"i\"\n closeable\n small\n @click.stop=\"data.open = true\"\n @close=\"unselectOption(opt.value)\"\n >\n {{ opt.label || opt.value }}\n </PlChip>\n </div>\n\n <div class=\"pl-autocomplete-multi__controls\">\n <PlMaskIcon24 v-if=\"isOptionsLoading\" name=\"loading\" />\n <slot name=\"append\" />\n <div class=\"pl-autocomplete-multi__arrow-wrapper\" @click.stop=\"toggleOpen\">\n <div class=\"arrow-icon arrow-icon-default\" />\n </div>\n </div>\n </div>\n <label v-if=\"label\">\n <PlSvg v-if=\"required\" :uri=\"SvgRequired\" />\n <span>{{ label }}</span>\n <PlTooltip v-if=\"slots.tooltip\" class=\"info\" position=\"top\">\n <template #tooltip>\n <slot name=\"tooltip\" />\n </template>\n </PlTooltip>\n </label>\n <DropdownOverlay\n v-if=\"data.open\"\n ref=\"overlay\"\n :root=\"rootRef\"\n class=\"pl-autocomplete-multi__options\"\n :gap=\"5\"\n tabindex=\"-1\"\n @focusout=\"onFocusOut\"\n >\n <div class=\"pl-autocomplete-multi__open-chips-container\">\n <PlChip\n v-for=\"(opt, i) in selectedOptionsRef\"\n :key=\"i\"\n closeable\n small\n @close=\"unselectOption(opt.value)\"\n >\n {{ opt.label || opt.value }}\n </PlChip>\n </div>\n <DropdownListItem\n v-for=\"(item, index) in filteredOptionsRef\"\n :key=\"index\"\n :option=\"item\"\n :text-item=\"'text'\"\n :is-selected=\"item.selected\"\n :is-hovered=\"data.activeOption == index\"\n size=\"medium\"\n use-checkbox\n @click.stop=\"selectOption(item.value)\"\n />\n <div v-if=\"!filteredOptionsRef.length && !isOptionsLoading\" class=\"nothing-found\">\n {{ emptyOptionsText }}\n </div>\n </DropdownOverlay>\n <DoubleContour class=\"pl-autocomplete-multi__contour\" :group-position=\"groupPosition\" />\n </div>\n </div>\n <div v-if=\"computedError\" class=\"pl-autocomplete-multi__error\">{{ computedError }}</div>\n <div v-else-if=\"helper\" class=\"pl-autocomplete-multi__helper\">{{ helper }}</div>\n </div>\n</template>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAmCE,MAAM;;;;;;;;;;;;;;;;;;;;;;;;EA6BR,IAAM,IAAO,GAIP,KAAa,MAAW,EAAK,qBAAqB,EAAE,EAEpD,IAAQ,IAAU,EAElB,IAAQ,GA+ER,IAAU,GAA8B,EACxC,IAAW,GAAmC,EAE9C,IAAU,GAAe,UAAU,EAEnC,IAAO,EAAS;GACpB,QAAQ;GACR,cAAc;GACd,MAAM;GACN,eAAe;GAChB,CAAC;AAEF,UACQ,EAAK,OACV,MAAM;AACL,GAAK,MACH,EAAK,SAAS;KAGlB,EAAE,OAAO,QAAQ,CAClB;EAED,IAAM,IAAoB,QAAgB,MAAM,QAAQ,EAAM,WAAW,GAAG,EAAM,aAAa,EAAE,CAAE,EAE7F,KAAiB,QACjB,EAAK,QAAQ,EAAM,WAAW,SAAS,IAClC,EAAM,cAGR,EAAM,WAAW,SAAS,IAAI,KAAK,EAAM,YAChD,EAEI,IAAW,EAAM,GAAO,WAAW,EAEnC,IAAmB,QACjB;GAAC,EAAK;GAAQ,EAAK;GAAM,EAAM;GAAS,EAC9C,OAAO,CAAC,GAAQ,OACP,EAAM,cAAc,GAAQ,QAAQ,EAE7C;GACE,oBAAoB,CAAC,GAAS,OAAU;GACxC;GACD,CACF,EAEK,IAAkB,QAChB,CAAC,EAAM,YAAY,EAAM,SAAS,EACxC,OAAO,CAAC,OACC,EAAM,cAAc,GAAG,QAAQ,EAExC,EACE,aACD,CACF,EAEK,KAAgB,QAAe;GACnC,IAAM,IAAe,EAAgB,SAAS,EAAE,EAC1C,IAAgB,EAAiB,SAAS,EAAE,EAE5C,oBAAa,IAAI,KAAyB,EAC1C,IAAS,EAAE,EAEX,KAAc,MAA2C;AAC7D,SAAK,IAAM,KAAU,GAAS;KAC5B,IAAM,IAAiB,GAAa,EAAO,MAAM;AACjD,KAAK,EAAW,IAAI,EAAe,KACjC,EAAW,IAAI,EAAe,EAC9B,EAAO,KAAK,EAAO;;;AAQzB,UAHA,EAAW,EAAa,EACxB,EAAW,EAAc,EAElB;IACP,EAEI,IAAqB,QAClB,EAAkB,MACtB,KAAK,MAAM,GAAc,MAAM,MAAM,MAAQ,EAAU,EAAI,OAAO,EAAE,CAAC,CAAA,CACrE,QAAQ,MAAM,MAAM,KAAA,EAAU,CACjC,EAEI,IAAqB,QAAe;GACxC,IAAM,IAAiB,EAAM,EAAkB;AAI/C,UAAO,CAAC,GAFQ,EAAiB,SAAS,EAAE,CAEzB,CAAC,KAAK,OAAS;IAChC,GAAG;IACH,UAAU,EAAa,GAAgB,EAAI,MAAM;IAClD,EAAE;IACH,EAEI,IAAmB,QAAe,EAAiB,WAAW,EAAgB,QAAQ,EAEtF,IAAa,QACb,EAAgB,UAAU,KAAA,IACrB,KAGF,EAAM,SACb,EAEI,KAAW,QAAgB,EAAW,QAAQ,KAAA,IAAY,IAAK,EAE/D,WAA2B;AAC/B,KAAK,eAAe;KAGhB,KAAgB,MAAS;GAC7B,IAAM,IAAS,EAAM,EAAkB;AAKvC,GAJA,EAAU,EAAa,GAAQ,EAAE,GAAG,EAAO,QAAQ,MAAO,CAAC,EAAU,GAAI,EAAE,CAAC,GAAG,CAAC,GAAG,GAAQ,EAAE,CAAC,EAC1F,EAAM,wBACR,EAAK,SAAS,KAEhB,EAAS,OAAO,OAAO;KAGnB,KAAkB,MACtB,EAAU,EAAM,EAAkB,CAAC,QAAQ,MAAM,CAAC,EAAU,GAAG,EAAE,CAAC,CAAC,EAE/D,WAAwB,EAAS,OAAO,OAAO,EAE/C,WAAoB,EAAK,OAAO,CAAC,EAAK,MAEtC,KAAc,MAAsB;GACxC,IAAM,IAAgB,EAAM;AAE5B,GAAI,CAAC,EAAQ,OAAO,SAAS,EAAc,IAAI,CAAC,EAAQ,OAAO,SAAS,SAAS,EAAc,KAC7F,EAAK,OAAO;KAIV,MAAiB,MAAgD;GACrE,IAAM,EAAE,SAAM,oBAAiB;AAE/B,OAAI,CAAC,GAAM;AACT,IAAI,EAAE,SAAS,YACb,EAAK,OAAO;AAEd;;AAGF,GAAI,EAAE,SAAS,aACb,EAAK,OAAO,IACZ,EAAS,OAAO,OAAO;GAGzB,IAAM,IAAkB,EAAM,EAAmB,EAE3C,EAAE,cAAW;AAEnB,OAAI,CAAC,EACH;AAOF,GAJI;IAAC;IAAa;IAAW;IAAQ,CAAC,SAAS,EAAE,KAAK,IACpD,EAAE,gBAAgB,EAGhB,EAAE,SAAS,WACb,EAAa,EAAgB,GAAc,MAAM;GAGnD,IAAM,IAAI,EAAE,SAAS,cAAc,IAAI,EAAE,SAAS,YAAY,KAAK;AAInE,GAFA,EAAK,eAAe,KAAK,IAAI,IAAe,IAAI,EAAO,GAAG,GAE1D,4BAA4B,EAAQ,OAAO,kBAAkB,CAAC;;AAKhE,EAFA,EAAc,EAAQ,EAEtB,QACQ,EAAM,kBACN,IAAoB,EAC1B,EAAE,WAAW,IAAM,CACpB;EAED,IAAM,IAAgB,QAAe;AAC/B,UAAiB,OAIrB;QAAI,EAAiB,MACnB,QAAO,EAAgB,EAAiB,MAAM;AAGhD,QAAI,EAAgB,MAClB,QAAO,EAAgB,EAAgB,MAAM;AAG/C,QAAI,EAAM,MACR,QAAO,EAAgB,EAAM,MAAM;AAGrC,QAAI,EAAM,WAAW,UAAU,EAAmB,MAAM,WAAW,EAAM,WAAW,OAClF,QAAO;;IAIT;yBAIA,EA4FM,OAAA;GA5FD,OAAM;GAAmC,SAAO;MACnD,EAwFM,OAAA;YAvFA;GAAJ,KAAI;GACH,UAAU,GAAA;GACX,OAAK,GAAA,CAAC,yBAAuB;IAAA,MACb,EAAK;IAAI,OAAS,EAAQ,EAAA;IAAa,UAAa,EAAA;IAAU,CAAA,CAAA;GAC7E,WAAS;GACT,YAAU;MAEX,EA+EM,OA/EN,IA+EM;GA9EJ,EAgCM,OAhCN,IAgCM;OA/BJ,EAUE,SAAA;cATI;KAAJ,KAAI;8CACU,SAAM;KACpB,MAAK;KACL,UAAS;KACR,UAAU,EAAA;KACV,aAAa,GAAA;KACd,YAAW;KACX,cAAa;KACZ,SAAK,AAAA,EAAA,QAAA,MAAE,EAAK,OAAI;2BAPR,EAAK,OAAM,CAAA,CAAA;IASV,EAAK,oBAAA,GAAA,EAAjB,EAWM,OAXN,IAWM,EAAA,EAAA,GAAA,EAVJ,EASS,GAAA,MAAA,EARY,EAAA,QAAX,GAAK,YADf,EASS,EAAA,EAAA,EAAA;KAPN,KAAK;KACN,WAAA;KACA,OAAA;KACC,SAAK,AAAA,EAAA,OAAA,GAAA,MAAO,EAAK,OAAI,IAAA,CAAA,OAAA,CAAA;KACrB,UAAK,MAAE,EAAe,EAAI,MAAK;;sBAEJ,CAAA,EAAA,EAAzB,EAAI,SAAS,EAAI,MAAK,EAAA,EAAA,CAAA,CAAA;;;IAI7B,EAMM,OANN,IAMM;KALgB,EAAA,SAAA,GAAA,EAApB,EAAuD,EAAA,EAAA,EAAA;;MAAjB,MAAK;;KAC3C,EAAsB,EAAA,QAAA,SAAA;KACtB,EAEM,OAAA;MAFD,OAAM;MAAwC,SAAK,EAAO,IAAU,CAAA,OAAA,CAAA;sBACvE,EAA6C,OAAA,EAAxC,OAAM,iCAA+B,EAAA,MAAA,GAAA,CAAA,CAAA,CAAA;;;GAInC,EAAA,SAAA,GAAA,EAAb,EAQQ,SAAA,IAAA;IAPO,EAAA,YAAA,GAAA,EAAb,EAA4C,EAAA,EAAA,EAAA;;KAApB,KAAK,EAAA,GAAW;;IACxC,EAAwB,QAAA,MAAA,EAAf,EAAA,MAAK,EAAA,EAAA;IACG,EAAA,EAAK,CAAC,WAAA,GAAA,EAAvB,EAIY,EAAA,EAAA,EAAA;;KAJoB,OAAM;KAAO,UAAS;;KACzC,SAAO,QACO,CAAvB,EAAuB,EAAA,QAAA,UAAA,CAAA,CAAA;;;;GAKrB,EAAK,QAAA,GAAA,EADb,EAkCkB,IAAA;;aAhCZ;IAAJ,KAAI;IACH,MAAM,EAAA;IACP,OAAM;IACL,KAAK;IACN,UAAS;IACR,YAAU;;qBAYL;KAVN,EAUM,OAVN,IAUM,EAAA,EAAA,GAAA,EATJ,EAQS,GAAA,MAAA,EAPY,EAAA,QAAX,GAAK,YADf,EAQS,EAAA,EAAA,EAAA;MANN,KAAK;MACN,WAAA;MACA,OAAA;MACC,UAAK,MAAE,EAAe,EAAI,MAAK;;uBAEJ,CAAA,EAAA,EAAzB,EAAI,SAAS,EAAI,MAAK,EAAA,EAAA,CAAA,CAAA;;;aAG7B,EAUE,GAAA,MAAA,EATwB,EAAA,QAAhB,GAAM,YADhB,EAUE,GAAA;MARC,KAAK;MACL,QAAQ;MACR,aAAW;MACX,eAAa,EAAK;MAClB,cAAY,EAAK,gBAAgB;MAClC,MAAK;MACL,gBAAA;MACC,SAAK,GAAA,MAAO,EAAa,EAAK,MAAK,EAAA,CAAA,OAAA,CAAA;;;;;;;MAE1B,EAAA,MAAmB,UAAM,CAAK,EAAA,SAAA,GAAA,EAA1C,EAEM,OAFN,IAEM,EADD,EAAA,iBAAgB,EAAA,EAAA,IAAA,EAAA,IAAA,GAAA;;;;GAGvB,GAAwF,GAAA;IAAzE,OAAM;IAAkC,kBAAgB,EAAA;;gBAGhE,EAAA,SAAA,GAAA,EAAX,EAAwF,OAAxF,GAAwF,EAAtB,EAAA,MAAa,EAAA,EAAA,IAC/D,EAAA,UAAA,GAAA,EAAhB,EAAgF,OAAhF,GAAgF,EAAf,EAAA,OAAM,EAAA,EAAA,IAAA,EAAA,IAAA,GAAA,CAAA,CAAA"}
1
+ {"version":3,"file":"PlAutocompleteMulti.vue_vue_type_script_setup_true_lang.js","names":[],"sources":["../../../src/components/PlAutocompleteMulti/PlAutocompleteMulti.vue"],"sourcesContent":["<script lang=\"ts\">\n/**\n * A multi-select autocomplete component that allows users to search and select multiple values from a list of options.\n * Supports async data fetching, keyboard navigation, and displays selected items as removable chips.\n *\n * @example\n * Basic usage:\n * <PlAutocompleteMulti\n * v-model=\"selectedUsers\"\n * :options-search=\"searchUsers\"\n * :model-search=\"getUsersByIds\"\n * label=\"Select Users\"\n * placeholder=\"Search for users...\"\n * required\n * :debounce=\"300\"\n * helper=\"Choose one or more users from the list\"\n * />\n *\n * With async functions:\n * const selectedUsers = ref([])\n *\n * const searchUsers = async (searchTerm) => {\n * const response = await fetch('/api/users/search?q=' + searchTerm)\n * const users = await response.json()\n * return users.map(user => ({ value: user.id, label: user.name }))\n * }\n *\n * const getUsersByIds = async (userIds) => {\n * if (!userIds.length) return []\n * const response = await fetch('/api/users?ids=' + userIds.join(','))\n * const users = await response.json()\n * return users.map(user => ({ value: user.id, label: user.name }))\n * }\n */\nexport default {\n name: \"PlAutocompleteMulti\",\n};\n\nexport interface OptionsSearch<T> {\n (s: string, type: \"label\"): Promise<Readonly<ListOptionBase<T>[]>>;\n (s: T[], type: \"value\"): Promise<Readonly<ListOptionBase<T>[]>>;\n}\n</script>\n\n<script lang=\"ts\" setup generic=\"M extends string | number = string\">\nimport \"./pl-autocomplete-multi.scss\";\n\nimport type { ListOptionBase } from \"@platforma-sdk/model\";\nimport canonicalize from \"canonicalize\";\nimport { computed, reactive, ref, toRef, unref, useSlots, useTemplateRef, watch } from \"vue\";\nimport { useWatchFetch } from \"../../composition/useWatchFetch.ts\";\nimport { getErrorMessage } from \"../../helpers/error.ts\";\nimport { deepEqual, deepIncludes } from \"../../helpers/objects\";\nimport DoubleContour from \"../../utils/DoubleContour.vue\";\nimport DropdownOverlay from \"../../utils/DropdownOverlay/DropdownOverlay.vue\";\nimport { useLabelNotch } from \"../../utils/useLabelNotch\";\nimport DropdownListItem from \"../DropdownListItem.vue\";\nimport { PlChip } from \"../PlChip\";\nimport { PlMaskIcon24 } from \"../PlMaskIcon24\";\nimport { PlTooltip } from \"../PlTooltip\";\n\nimport SvgRequired from \"../../assets/images/required.svg?raw\";\nimport { PlSvg } from \"../PlSvg\";\n\nconst emit = defineEmits<{\n (e: \"update:modelValue\", v: M[]): void;\n}>();\n\nconst emitModel = (v: M[]) => emit(\"update:modelValue\", v);\n\nconst slots = useSlots();\n\nconst props = withDefaults(\n defineProps<{\n /**\n * The current selected values.\n */\n modelValue: M[];\n /**\n * Lambda for requesting of available options for the dropdown by search string.\n */\n optionsSearch: OptionsSearch<M>;\n /**\n * Unique identifier for the source of the options, changing it will invalidate the options cache.\n */\n sourceId?: string;\n /**\n * The label text for the dropdown field (optional)\n */\n label?: string;\n /**\n * A helper text displayed below the dropdown when there are no errors (optional).\n */\n helper?: string;\n /**\n * Error message displayed below the dropdown (optional)\n */\n error?: unknown;\n /**\n * Placeholder text shown when no value is selected.\n */\n placeholder?: string;\n /**\n * If `true`, the dropdown component is marked as required.\n */\n required?: boolean;\n /**\n * If `true`, the dropdown component is disabled and cannot be interacted with.\n */\n disabled?: boolean;\n /**\n * Debounce time in ms for the options search.\n */\n debounce?: number;\n /**\n * If `true`, the search input is reset and focus is set on it when the new option is selected.\n */\n resetSearchOnSelect?: boolean;\n /**\n * The text to display when no options are found.\n */\n emptyOptionsText?: string;\n /**\n * Makes some of corners not rounded\n * */\n groupPosition?:\n | \"top\"\n | \"bottom\"\n | \"left\"\n | \"right\"\n | \"top-left\"\n | \"top-right\"\n | \"bottom-left\"\n | \"bottom-right\"\n | \"middle\";\n }>(),\n {\n modelValue: () => [],\n label: undefined,\n helper: undefined,\n error: undefined,\n placeholder: \"...\",\n required: false,\n disabled: false,\n debounce: 300,\n emptyOptionsText: \"Nothing found\",\n sourceId: undefined,\n groupPosition: undefined,\n },\n);\n\nconst rootRef = ref<HTMLElement | undefined>();\nconst inputRef = ref<HTMLInputElement | undefined>();\n\nconst overlay = useTemplateRef(\"overlay\");\n\nconst data = reactive({\n search: \"\",\n activeOption: -1,\n open: false,\n optionsHeight: 0,\n});\n\nwatch(\n () => data.open,\n (v) => {\n if (!v) {\n data.search = \"\";\n }\n },\n { flush: \"sync\" },\n);\n\nconst selectedValuesRef = computed(() => (Array.isArray(props.modelValue) ? props.modelValue : []));\n\nconst placeholderRef = computed(() => {\n if (data.open && props.modelValue.length > 0) {\n return props.placeholder;\n }\n\n return props.modelValue.length > 0 ? \"\" : props.placeholder;\n});\n\nconst debounce = toRef(props, \"debounce\");\n\nconst searchOptionsRef = useWatchFetch(\n () => [data.search, data.open, props.sourceId] as const,\n async ([search, _open]) => {\n return props.optionsSearch(search, \"label\");\n },\n {\n filterWatchResult: ([_search, open]) => open,\n debounce,\n },\n);\n\nconst modelOptionsRef = useWatchFetch(\n () => [props.modelValue, props.sourceId] as const,\n async ([v]) => {\n return props.optionsSearch(v, \"value\");\n },\n {\n debounce,\n },\n);\n\nconst allOptionsRef = computed(() => {\n const modelOptions = modelOptionsRef.value ?? [];\n const searchOptions = searchOptionsRef.value ?? [];\n\n const seenValues = new Set<string | undefined>();\n const result = [] as ListOptionBase<M>[];\n\n const addOptions = (options: Readonly<ListOptionBase<M>[]>) => {\n for (const option of options) {\n const canonicalValue = canonicalize(option.value);\n if (!seenValues.has(canonicalValue)) {\n seenValues.add(canonicalValue);\n result.push(option);\n }\n }\n };\n\n addOptions(modelOptions);\n addOptions(searchOptions);\n\n return result;\n});\n\nconst selectedOptionsRef = computed(() => {\n return selectedValuesRef.value\n .map((v) => allOptionsRef.value.find((opt) => deepEqual(opt.value, v)))\n .filter((v) => v !== undefined);\n});\n\nconst filteredOptionsRef = computed(() => {\n const selectedValues = unref(selectedValuesRef);\n\n const options = searchOptionsRef.value ?? [];\n\n return [...options].map((opt) => ({\n ...opt,\n selected: deepIncludes(selectedValues, opt.value),\n }));\n});\n\nconst isOptionsLoading = computed(() => searchOptionsRef.loading || modelOptionsRef.loading);\n\nconst isDisabled = computed(() => {\n if (modelOptionsRef.value === undefined) {\n return true;\n }\n\n return props.disabled;\n});\n\nconst tabindex = computed(() => (isDisabled.value ? undefined : \"0\"));\n\nconst updateActiveOption = () => {\n data.activeOption = 0;\n};\n\nconst selectOption = (v: M) => {\n const values = unref(selectedValuesRef);\n emitModel(deepIncludes(values, v) ? values.filter((it) => !deepEqual(it, v)) : [...values, v]);\n if (props.resetSearchOnSelect) {\n data.search = \"\";\n }\n inputRef.value?.focus();\n};\n\nconst unselectOption = (d: M) =>\n emitModel(unref(selectedValuesRef).filter((v) => !deepEqual(v, d)));\n\nconst setFocusOnInput = () => inputRef.value?.focus();\n\nconst toggleOpen = () => (data.open = !data.open);\n\nconst onFocusOut = (event: FocusEvent) => {\n const relatedTarget = event.relatedTarget as Node | null;\n\n if (!rootRef.value?.contains(relatedTarget) && !overlay.value?.listRef?.contains(relatedTarget)) {\n data.open = false;\n }\n};\n\nconst handleKeydown = (e: { code: string; preventDefault(): void }) => {\n const { open, activeOption } = data;\n\n if (!open) {\n if (e.code === \"Enter\") {\n data.open = true;\n }\n return;\n }\n\n if (e.code === \"Escape\") {\n data.open = false;\n inputRef.value?.focus();\n }\n\n const filteredOptions = unref(filteredOptionsRef);\n\n const { length } = filteredOptions;\n\n if (!length) {\n return;\n }\n\n if ([\"ArrowDown\", \"ArrowUp\", \"Enter\"].includes(e.code)) {\n e.preventDefault();\n }\n\n if (e.code === \"Enter\") {\n selectOption(filteredOptions[activeOption].value);\n }\n\n const d = e.code === \"ArrowDown\" ? 1 : e.code === \"ArrowUp\" ? -1 : 0;\n\n data.activeOption = Math.abs(activeOption + d + length) % length;\n\n requestAnimationFrame(() => overlay.value?.scrollIntoActive());\n};\n\nuseLabelNotch(rootRef);\n\nwatch(\n () => props.modelValue,\n () => updateActiveOption(),\n { immediate: true },\n);\n\nconst computedError = computed(() => {\n if (isOptionsLoading.value) {\n return undefined;\n }\n\n if (searchOptionsRef.error) {\n return getErrorMessage(searchOptionsRef.error);\n }\n\n if (modelOptionsRef.error) {\n return getErrorMessage(modelOptionsRef.error);\n }\n\n if (props.error) {\n return getErrorMessage(props.error);\n }\n\n if (props.modelValue.length && selectedOptionsRef.value.length !== props.modelValue.length) {\n return \"The selected values are not one of the options\";\n }\n\n return undefined;\n});\n</script>\n\n<template>\n <div\n class=\"pl-autocomplete-multi__envelope\"\n @click=\"setFocusOnInput\"\n data-testid=\"pl-autocomplete-multi\"\n >\n <div\n ref=\"rootRef\"\n :tabindex=\"tabindex\"\n class=\"pl-autocomplete-multi\"\n data-testid=\"pl-autocomplete-multi-control\"\n :class=\"{ open: data.open, error: Boolean(computedError), disabled: isDisabled }\"\n @keydown=\"handleKeydown\"\n @focusout=\"onFocusOut\"\n >\n <div class=\"pl-autocomplete-multi__container\">\n <div class=\"pl-autocomplete-multi__field\">\n <input\n ref=\"inputRef\"\n v-model=\"data.search\"\n type=\"text\"\n tabindex=\"-1\"\n :disabled=\"isDisabled\"\n :placeholder=\"placeholderRef\"\n spellcheck=\"false\"\n autocomplete=\"chrome-off\"\n data-testid=\"pl-autocomplete-multi-input\"\n @focus=\"data.open = true\"\n />\n <div v-if=\"!data.open\" class=\"chips-container\" data-testid=\"pl-autocomplete-multi-chips\">\n <PlChip\n v-for=\"(opt, i) in selectedOptionsRef\"\n :key=\"i\"\n closeable\n data-testid=\"pl-autocomplete-multi-chip\"\n small\n @click.stop=\"data.open = true\"\n @close=\"unselectOption(opt.value)\"\n >\n {{ opt.label || opt.value }}\n </PlChip>\n </div>\n\n <div class=\"pl-autocomplete-multi__controls\">\n <PlMaskIcon24\n v-if=\"isOptionsLoading\"\n name=\"loading\"\n data-testid=\"pl-autocomplete-multi-loading\"\n />\n <slot name=\"append\" />\n <div\n class=\"pl-autocomplete-multi__arrow-wrapper\"\n data-testid=\"pl-autocomplete-multi-arrow\"\n @click.stop=\"toggleOpen\"\n >\n <div class=\"arrow-icon arrow-icon-default\" />\n </div>\n </div>\n </div>\n <label v-if=\"label\" data-testid=\"pl-autocomplete-multi-label\">\n <PlSvg v-if=\"required\" :uri=\"SvgRequired\" data-testid=\"pl-autocomplete-multi-required\" />\n <span>{{ label }}</span>\n <PlTooltip\n v-if=\"slots.tooltip\"\n class=\"info\"\n position=\"top\"\n data-testid=\"pl-autocomplete-multi-tooltip\"\n >\n <template #tooltip>\n <slot name=\"tooltip\" />\n </template>\n </PlTooltip>\n </label>\n <DropdownOverlay\n v-if=\"data.open\"\n ref=\"overlay\"\n :root=\"rootRef\"\n class=\"pl-autocomplete-multi__options\"\n data-testid=\"pl-autocomplete-multi-options\"\n :gap=\"5\"\n tabindex=\"-1\"\n @focusout=\"onFocusOut\"\n >\n <div\n class=\"pl-autocomplete-multi__open-chips-container\"\n data-testid=\"pl-autocomplete-multi-chips\"\n >\n <PlChip\n v-for=\"(opt, i) in selectedOptionsRef\"\n :key=\"i\"\n closeable\n data-testid=\"pl-autocomplete-multi-chip\"\n small\n @close=\"unselectOption(opt.value)\"\n >\n {{ opt.label || opt.value }}\n </PlChip>\n </div>\n <DropdownListItem\n v-for=\"(item, index) in filteredOptionsRef\"\n :key=\"index\"\n :option=\"item\"\n :text-item=\"'text'\"\n :is-selected=\"item.selected\"\n :is-hovered=\"data.activeOption == index\"\n size=\"medium\"\n use-checkbox\n data-testid=\"pl-autocomplete-multi-option\"\n @click.stop=\"selectOption(item.value)\"\n />\n <div\n v-if=\"!filteredOptionsRef.length && !isOptionsLoading\"\n class=\"nothing-found\"\n data-testid=\"pl-autocomplete-multi-options-empty\"\n >\n {{ emptyOptionsText }}\n </div>\n </DropdownOverlay>\n <DoubleContour class=\"pl-autocomplete-multi__contour\" :group-position=\"groupPosition\" />\n </div>\n </div>\n <div\n v-if=\"computedError\"\n class=\"pl-autocomplete-multi__error\"\n data-testid=\"pl-autocomplete-multi-error\"\n >\n {{ computedError }}\n </div>\n <div\n v-else-if=\"helper\"\n class=\"pl-autocomplete-multi__helper\"\n data-testid=\"pl-autocomplete-multi-helper\"\n >\n {{ helper }}\n </div>\n </div>\n</template>\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"PlBtnAccent.js","names":[],"sources":["../../../src/components/PlBtnAccent/PlBtnAccent.vue"],"sourcesContent":["<script lang=\"ts\">\n/**\n * Accent button\n */\nexport default {\n name: \"PlBtnAccent\",\n};\n</script>\n\n<script lang=\"ts\" setup>\nimport \"./pl-btn-accent.scss\";\nimport type { MaskIconName16, Size } from \"../../types\";\nimport BtnBase from \"../../base/BtnBase.vue\";\n\nconst props = defineProps<{\n /**\n * If `true,` the button is disabled, cannot be interacted with, and shows a special 'loading' icon.\n */\n loading?: boolean;\n /**\n * Size of the button, the default value is 'medium'\n */\n size?: Size;\n /**\n * If `true` the shape is round.\n */\n round?: boolean;\n /**\n * Icon to display\n */\n icon?: MaskIconName16;\n /**\n * If `true`, an icon is displayed before the text.\n */\n reverse?: boolean;\n /**\n * Justify text at the center\n */\n justifyCenter?: boolean;\n}>();\n</script>\n\n<template>\n <BtnBase class=\"pl-btn-accent\" v-bind=\"props\">\n <slot />\n </BtnBase>\n</template>\n"],"mappings":""}
1
+ {"version":3,"file":"PlBtnAccent.js","names":[],"sources":["../../../src/components/PlBtnAccent/PlBtnAccent.vue"],"sourcesContent":["<script lang=\"ts\">\n/**\n * Accent button\n */\nexport default {\n name: \"PlBtnAccent\",\n};\n</script>\n\n<script lang=\"ts\" setup>\nimport \"./pl-btn-accent.scss\";\nimport type { MaskIconName16, Size } from \"../../types\";\nimport BtnBase from \"../../base/BtnBase.vue\";\n\nconst props = defineProps<{\n /**\n * If `true,` the button is disabled, cannot be interacted with, and shows a special 'loading' icon.\n */\n loading?: boolean;\n /**\n * Size of the button, the default value is 'medium'\n */\n size?: Size;\n /**\n * If `true` the shape is round.\n */\n round?: boolean;\n /**\n * Icon to display\n */\n icon?: MaskIconName16;\n /**\n * If `true`, an icon is displayed before the text.\n */\n reverse?: boolean;\n /**\n * Justify text at the center\n */\n justifyCenter?: boolean;\n}>();\n</script>\n\n<template>\n <BtnBase data-testid=\"pl-btn-accent\" class=\"pl-btn-accent\" v-bind=\"props\">\n <slot />\n </BtnBase>\n</template>\n"],"mappings":""}
@@ -1 +1 @@
1
- {"version":3,"file":"PlBtnAccent.vue.d.ts","sourceRoot":"","sources":["../../../src/components/PlBtnAccent/PlBtnAccent.vue"],"names":[],"mappings":"AAkDA,OAAO,sBAAsB,CAAC;AAC9B,OAAO,KAAK,EAAE,cAAc,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AAIxD;;GAEG;wBACkB,OAAO,YAAY;AAAxC,wBAAyC;AAKzC,QAAA,MAAM,YAAY;IAEhB;;OAEG;cACO,OAAO;IACjB;;OAEG;WACI,IAAI;IACX;;OAEG;YACK,OAAO;IACf;;OAEG;WACI,cAAc;IACrB;;OAEG;cACO,OAAO;IACjB;;OAEG;oBACa,OAAO;;IAvBvB;;OAEG;cACO,OAAO;IACjB;;OAEG;WACI,IAAI;IACX;;OAEG;YACK,OAAO;IACf;;OAEG;WACI,cAAc;IACrB;;OAEG;cACO,OAAO;IACjB;;OAEG;oBACa,OAAO;;cAoCX,CAAC,KAAK,IAAgB,KAAK,GAAG;EAOxC,CAAC;AACL,KAAK,eAAe,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG;IAChC,QAAO;QACN,MAAM,EAAE,CAAC,CAAC;KACV,CAAA;CACD,CAAC"}
1
+ {"version":3,"file":"PlBtnAccent.vue.d.ts","sourceRoot":"","sources":["../../../src/components/PlBtnAccent/PlBtnAccent.vue"],"names":[],"mappings":"AAkDA,OAAO,sBAAsB,CAAC;AAC9B,OAAO,KAAK,EAAE,cAAc,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AAIxD;;GAEG;wBACkB,OAAO,YAAY;AAAxC,wBAAyC;AAKzC,QAAA,MAAM,YAAY;IAEhB;;OAEG;cACO,OAAO;IACjB;;OAEG;WACI,IAAI;IACX;;OAEG;YACK,OAAO;IACf;;OAEG;WACI,cAAc;IACrB;;OAEG;cACO,OAAO;IACjB;;OAEG;oBACa,OAAO;;IAvBvB;;OAEG;cACO,OAAO;IACjB;;OAEG;WACI,IAAI;IACX;;OAEG;YACK,OAAO;IACf;;OAEG;WACI,cAAc;IACrB;;OAEG;cACO,OAAO;IACjB;;OAEG;oBACa,OAAO;;cAsCX,CAAC,KAAK,IAAgB,KAAK,GAAG;EAOxC,CAAC;AACL,KAAK,eAAe,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG;IAChC,QAAO;QACN,MAAM,EAAE,CAAC,CAAC;KACV,CAAA;CACD,CAAC"}
@@ -13,7 +13,10 @@ var s = /* @__PURE__ */ n({
13
13
  },
14
14
  setup(n) {
15
15
  let s = n;
16
- return (n, c) => (i(), t(e, r({ class: "pl-btn-accent" }, s), {
16
+ return (n, c) => (i(), t(e, r({
17
+ "data-testid": "pl-btn-accent",
18
+ class: "pl-btn-accent"
19
+ }, s), {
17
20
  default: o(() => [a(n.$slots, "default")]),
18
21
  _: 3
19
22
  }, 16));
@@ -1 +1 @@
1
- {"version":3,"file":"PlBtnAccent.vue_vue_type_script_setup_true_lang.js","names":[],"sources":["../../../src/components/PlBtnAccent/PlBtnAccent.vue"],"sourcesContent":["<script lang=\"ts\">\n/**\n * Accent button\n */\nexport default {\n name: \"PlBtnAccent\",\n};\n</script>\n\n<script lang=\"ts\" setup>\nimport \"./pl-btn-accent.scss\";\nimport type { MaskIconName16, Size } from \"../../types\";\nimport BtnBase from \"../../base/BtnBase.vue\";\n\nconst props = defineProps<{\n /**\n * If `true,` the button is disabled, cannot be interacted with, and shows a special 'loading' icon.\n */\n loading?: boolean;\n /**\n * Size of the button, the default value is 'medium'\n */\n size?: Size;\n /**\n * If `true` the shape is round.\n */\n round?: boolean;\n /**\n * Icon to display\n */\n icon?: MaskIconName16;\n /**\n * If `true`, an icon is displayed before the text.\n */\n reverse?: boolean;\n /**\n * Justify text at the center\n */\n justifyCenter?: boolean;\n}>();\n</script>\n\n<template>\n <BtnBase class=\"pl-btn-accent\" v-bind=\"props\">\n <slot />\n </BtnBase>\n</template>\n"],"mappings":";;;;CAKE,MAAM;;;;;;;;;;EASR,IAAM,IAAQ;yBA6BZ,EAEU,GAFV,EAEU,EAFD,OAAM,iBAAe,EAAS,EAAK,EAAA;oBAClC,CAAR,EAAQ,EAAA,QAAA,UAAA,CAAA,CAAA"}
1
+ {"version":3,"file":"PlBtnAccent.vue_vue_type_script_setup_true_lang.js","names":[],"sources":["../../../src/components/PlBtnAccent/PlBtnAccent.vue"],"sourcesContent":["<script lang=\"ts\">\n/**\n * Accent button\n */\nexport default {\n name: \"PlBtnAccent\",\n};\n</script>\n\n<script lang=\"ts\" setup>\nimport \"./pl-btn-accent.scss\";\nimport type { MaskIconName16, Size } from \"../../types\";\nimport BtnBase from \"../../base/BtnBase.vue\";\n\nconst props = defineProps<{\n /**\n * If `true,` the button is disabled, cannot be interacted with, and shows a special 'loading' icon.\n */\n loading?: boolean;\n /**\n * Size of the button, the default value is 'medium'\n */\n size?: Size;\n /**\n * If `true` the shape is round.\n */\n round?: boolean;\n /**\n * Icon to display\n */\n icon?: MaskIconName16;\n /**\n * If `true`, an icon is displayed before the text.\n */\n reverse?: boolean;\n /**\n * Justify text at the center\n */\n justifyCenter?: boolean;\n}>();\n</script>\n\n<template>\n <BtnBase data-testid=\"pl-btn-accent\" class=\"pl-btn-accent\" v-bind=\"props\">\n <slot />\n </BtnBase>\n</template>\n"],"mappings":";;;;CAKE,MAAM;;;;;;;;;;EASR,IAAM,IAAQ;yBA6BZ,EAEU,GAFV,EAEU;GAFD,eAAY;GAAgB,OAAM;KAAwB,EAAK,EAAA;oBAC9D,CAAR,EAAQ,EAAA,QAAA,UAAA,CAAA,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"PlBtnDanger.js","names":[],"sources":["../../../src/components/PlBtnDanger/PlBtnDanger.vue"],"sourcesContent":["<script lang=\"ts\">\n/**\n * Danger button\n */\nexport default {\n name: \"PlBtnDanger\",\n};\n</script>\n\n<script lang=\"ts\" setup>\nimport \"./pl-btn-danger.scss\";\nimport type { MaskIconName16, Size } from \"../../types\";\nimport BtnBase from \"../../base/BtnBase.vue\";\n\nconst props = defineProps<{\n /**\n * If `true,` the button is disabled, cannot be interacted with, and shows a special 'loading' icon.\n */\n loading?: boolean;\n /**\n * Size of the button, the default value is 'medium'\n */\n size?: Size;\n /**\n * If `true` the shape is round.\n */\n round?: boolean;\n /**\n * Icon to display\n */\n icon?: MaskIconName16;\n /**\n * If `true`, an icon is displayed before the text.\n */\n reverse?: boolean;\n /**\n * Justify text at the center\n */\n justifyCenter?: boolean;\n}>();\n</script>\n\n<template>\n <BtnBase class=\"pl-btn-danger\" v-bind=\"props\">\n <slot />\n </BtnBase>\n</template>\n"],"mappings":""}
1
+ {"version":3,"file":"PlBtnDanger.js","names":[],"sources":["../../../src/components/PlBtnDanger/PlBtnDanger.vue"],"sourcesContent":["<script lang=\"ts\">\n/**\n * Danger button\n */\nexport default {\n name: \"PlBtnDanger\",\n};\n</script>\n\n<script lang=\"ts\" setup>\nimport \"./pl-btn-danger.scss\";\nimport type { MaskIconName16, Size } from \"../../types\";\nimport BtnBase from \"../../base/BtnBase.vue\";\n\nconst props = defineProps<{\n /**\n * If `true,` the button is disabled, cannot be interacted with, and shows a special 'loading' icon.\n */\n loading?: boolean;\n /**\n * Size of the button, the default value is 'medium'\n */\n size?: Size;\n /**\n * If `true` the shape is round.\n */\n round?: boolean;\n /**\n * Icon to display\n */\n icon?: MaskIconName16;\n /**\n * If `true`, an icon is displayed before the text.\n */\n reverse?: boolean;\n /**\n * Justify text at the center\n */\n justifyCenter?: boolean;\n}>();\n</script>\n\n<template>\n <BtnBase data-testid=\"pl-btn-danger\" class=\"pl-btn-danger\" v-bind=\"props\">\n <slot />\n </BtnBase>\n</template>\n"],"mappings":""}
@@ -1 +1 @@
1
- {"version":3,"file":"PlBtnDanger.vue.d.ts","sourceRoot":"","sources":["../../../src/components/PlBtnDanger/PlBtnDanger.vue"],"names":[],"mappings":"AAkDA,OAAO,sBAAsB,CAAC;AAC9B,OAAO,KAAK,EAAE,cAAc,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AAIxD;;GAEG;wBACkB,OAAO,YAAY;AAAxC,wBAAyC;AAKzC,QAAA,MAAM,YAAY;IAEhB;;OAEG;cACO,OAAO;IACjB;;OAEG;WACI,IAAI;IACX;;OAEG;YACK,OAAO;IACf;;OAEG;WACI,cAAc;IACrB;;OAEG;cACO,OAAO;IACjB;;OAEG;oBACa,OAAO;;IAvBvB;;OAEG;cACO,OAAO;IACjB;;OAEG;WACI,IAAI;IACX;;OAEG;YACK,OAAO;IACf;;OAEG;WACI,cAAc;IACrB;;OAEG;cACO,OAAO;IACjB;;OAEG;oBACa,OAAO;;cAoCX,CAAC,KAAK,IAAgB,KAAK,GAAG;EAOxC,CAAC;AACL,KAAK,eAAe,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG;IAChC,QAAO;QACN,MAAM,EAAE,CAAC,CAAC;KACV,CAAA;CACD,CAAC"}
1
+ {"version":3,"file":"PlBtnDanger.vue.d.ts","sourceRoot":"","sources":["../../../src/components/PlBtnDanger/PlBtnDanger.vue"],"names":[],"mappings":"AAkDA,OAAO,sBAAsB,CAAC;AAC9B,OAAO,KAAK,EAAE,cAAc,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AAIxD;;GAEG;wBACkB,OAAO,YAAY;AAAxC,wBAAyC;AAKzC,QAAA,MAAM,YAAY;IAEhB;;OAEG;cACO,OAAO;IACjB;;OAEG;WACI,IAAI;IACX;;OAEG;YACK,OAAO;IACf;;OAEG;WACI,cAAc;IACrB;;OAEG;cACO,OAAO;IACjB;;OAEG;oBACa,OAAO;;IAvBvB;;OAEG;cACO,OAAO;IACjB;;OAEG;WACI,IAAI;IACX;;OAEG;YACK,OAAO;IACf;;OAEG;WACI,cAAc;IACrB;;OAEG;cACO,OAAO;IACjB;;OAEG;oBACa,OAAO;;cAsCX,CAAC,KAAK,IAAgB,KAAK,GAAG;EAOxC,CAAC;AACL,KAAK,eAAe,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG;IAChC,QAAO;QACN,MAAM,EAAE,CAAC,CAAC;KACV,CAAA;CACD,CAAC"}
@@ -13,7 +13,10 @@ var s = /* @__PURE__ */ n({
13
13
  },
14
14
  setup(n) {
15
15
  let s = n;
16
- return (n, c) => (i(), t(e, r({ class: "pl-btn-danger" }, s), {
16
+ return (n, c) => (i(), t(e, r({
17
+ "data-testid": "pl-btn-danger",
18
+ class: "pl-btn-danger"
19
+ }, s), {
17
20
  default: o(() => [a(n.$slots, "default")]),
18
21
  _: 3
19
22
  }, 16));