@firstnoodle-ui/bui 0.0.26 → 0.0.28

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 (334) hide show
  1. package/LICENSE +21 -21
  2. package/dist/bui.css +1 -1
  3. package/dist/components/calendar-view/CalendarView.vue.d.ts +21 -0
  4. package/dist/components/calendar-view/components/DateButton.vue.d.ts +10 -0
  5. package/dist/components/calendar-view/components/DecadeView.vue.d.ts +12 -0
  6. package/dist/components/calendar-view/components/MonthView.vue.d.ts +17 -0
  7. package/dist/components/calendar-view/components/YearView.vue.d.ts +13 -0
  8. package/dist/components/calendar-view/composables/useCalendar.d.ts +44 -0
  9. package/dist/components/calendar-view/index.d.ts +1 -0
  10. package/dist/components/calendar-view/utils/enums.d.ts +29 -0
  11. package/dist/components/calendar-view/utils/index.d.ts +23 -0
  12. package/dist/components/calendar-view/utils/types.d.ts +12 -0
  13. package/dist/components/calendar-view/utils/utils/calendar.d.ts +22 -0
  14. package/dist/components/calendar-view/utils/utils/date.d.ts +15 -0
  15. package/dist/components/calendar-view/utils/utils/format.d.ts +18 -0
  16. package/dist/components/calendar-view/utils/utils/time.d.ts +35 -0
  17. package/dist/components/index.d.ts +2 -0
  18. package/dist/components/notification-badge/NotificationBadge.vue.d.ts +5 -0
  19. package/dist/components/notification-badge/index.d.ts +1 -0
  20. package/dist/components/select-list/components/option-group/OptionGroup.vue.d.ts +1 -0
  21. package/dist/components/select-list/components/select-list-option/SelectListOption.vue.d.ts +1 -0
  22. package/dist/components/select-list/types.d.ts +1 -0
  23. package/dist/components/types.d.ts +1 -1
  24. package/dist/index.mjs +7056 -6465
  25. package/dist/utils/capitalizeFirstLetter.d.ts +1 -0
  26. package/package.json +4 -3
  27. package/src/components/application-wrapper/ApplicationWrapper.vue +8 -0
  28. package/src/components/application-wrapper/index.ts +1 -0
  29. package/src/components/aside-section-label/AsideSectionLabel.vue +16 -0
  30. package/src/components/aside-section-label/index.ts +1 -0
  31. package/src/components/button/Button.vue +246 -0
  32. package/src/components/button/NotificationBadge.vue +15 -0
  33. package/src/components/button/components/button-label/ButtonLabel.vue +9 -0
  34. package/src/components/button/components/button-label/index.ts +1 -0
  35. package/src/components/button/components/index.ts +3 -0
  36. package/src/components/button/components/left-group/LeftGroup.vue +5 -0
  37. package/src/components/button/components/left-group/index.ts +1 -0
  38. package/src/components/button/components/notification-badge/NotificationBadge.vue +17 -0
  39. package/src/components/button/components/notification-badge/index.ts +1 -0
  40. package/src/components/button/index.ts +1 -0
  41. package/src/components/button-group/ButtonGroup.vue +97 -0
  42. package/src/components/button-group/index.ts +1 -0
  43. package/src/components/calendar-view/CalendarView.vue +106 -0
  44. package/src/components/calendar-view/components/DateButton.vue +23 -0
  45. package/src/components/calendar-view/components/DecadeView.vue +50 -0
  46. package/src/components/calendar-view/components/MonthView.vue +72 -0
  47. package/src/components/calendar-view/components/NavButton.vue +16 -0
  48. package/src/components/calendar-view/components/YearView.vue +52 -0
  49. package/src/components/calendar-view/composables/useCalendar.ts +138 -0
  50. package/src/components/calendar-view/index.ts +1 -0
  51. package/src/components/calendar-view/utils/enums.ts +31 -0
  52. package/src/components/calendar-view/utils/index.ts +240 -0
  53. package/src/components/calendar-view/utils/types.ts +13 -0
  54. package/src/components/calendar-view/utils/utils/calendar.ts +70 -0
  55. package/src/components/calendar-view/utils/utils/date.ts +130 -0
  56. package/src/components/calendar-view/utils/utils/format.ts +61 -0
  57. package/src/components/calendar-view/utils/utils/time.ts +70 -0
  58. package/src/components/checkbox/Checkbox.vue +51 -0
  59. package/src/components/checkbox/CircleIndicator.vue +26 -0
  60. package/src/components/checkbox/DefaultIndicator.vue +19 -0
  61. package/src/components/checkbox/index.ts +1 -0
  62. package/src/components/collapse/Collapse.vue +114 -0
  63. package/src/components/collapse/index.ts +1 -0
  64. package/src/components/confirm-cancel/ConfirmCancel.vue +66 -0
  65. package/src/components/confirm-cancel/index.ts +1 -0
  66. package/src/components/confirm-cancel/types.ts +18 -0
  67. package/src/components/content-slider/ContentSlider.vue +79 -0
  68. package/src/components/content-slider/index.ts +1 -0
  69. package/src/components/data-point/DataPoint.vue +5 -0
  70. package/src/components/data-point/index.ts +1 -0
  71. package/src/components/delete-button/DeleteButton.vue +19 -0
  72. package/src/components/delete-button/index.ts +1 -0
  73. package/src/components/dialog/Dialog.vue +70 -0
  74. package/src/components/dialog/index.ts +1 -0
  75. package/src/components/fade-in-up/FadeInUp.vue +17 -0
  76. package/src/components/fade-in-up/index.ts +1 -0
  77. package/src/components/filter-chip/FilterChip.vue +28 -0
  78. package/src/components/filter-chip/index.ts +1 -0
  79. package/src/components/first-paint/FirstPaint.vue +21 -0
  80. package/src/components/first-paint/index.ts +1 -0
  81. package/src/components/first-paint/style.scss +23 -0
  82. package/src/components/flexbox/Flexbox.vue +51 -0
  83. package/src/components/flexbox/index.ts +1 -0
  84. package/src/components/horizontal-layout/Aside.vue +114 -0
  85. package/src/components/horizontal-layout/HorizontalLayout.vue +118 -0
  86. package/src/components/horizontal-layout/index.ts +2 -0
  87. package/src/components/icon/Icon.vue +1263 -0
  88. package/src/components/icon/index.ts +1 -0
  89. package/src/components/icon/utils/combine-svgs.cjs +55 -0
  90. package/src/components/icon/utils/combined-svgs.txt +1150 -0
  91. package/src/components/icon/utils/svgs/admin.svg +16 -0
  92. package/src/components/icon/utils/svgs/arrow-deviate.svg +3 -0
  93. package/src/components/icon/utils/svgs/arrow-down-plus.svg +4 -0
  94. package/src/components/icon/utils/svgs/arrow-down.svg +3 -0
  95. package/src/components/icon/utils/svgs/arrow-from.svg +3 -0
  96. package/src/components/icon/utils/svgs/arrow-left.svg +3 -0
  97. package/src/components/icon/utils/svgs/arrow-move.svg +15 -0
  98. package/src/components/icon/utils/svgs/arrow-right.svg +3 -0
  99. package/src/components/icon/utils/svgs/arrow-sub.svg +3 -0
  100. package/src/components/icon/utils/svgs/arrow-trend.svg +15 -0
  101. package/src/components/icon/utils/svgs/arrow-up-plus.svg +4 -0
  102. package/src/components/icon/utils/svgs/arrow-up.svg +3 -0
  103. package/src/components/icon/utils/svgs/authority.svg +5 -0
  104. package/src/components/icon/utils/svgs/beams.svg +5 -0
  105. package/src/components/icon/utils/svgs/bell.svg +15 -0
  106. package/src/components/icon/utils/svgs/bold.svg +3 -0
  107. package/src/components/icon/utils/svgs/box.svg +5 -0
  108. package/src/components/icon/utils/svgs/building.svg +15 -0
  109. package/src/components/icon/utils/svgs/bullet-list.svg +8 -0
  110. package/src/components/icon/utils/svgs/calendar.svg +21 -0
  111. package/src/components/icon/utils/svgs/camera.svg +5 -0
  112. package/src/components/icon/utils/svgs/categories.svg +3 -0
  113. package/src/components/icon/utils/svgs/check-circled.svg +16 -0
  114. package/src/components/icon/utils/svgs/check-outline.svg +15 -0
  115. package/src/components/icon/utils/svgs/check.svg +3 -0
  116. package/src/components/icon/utils/svgs/chevron-down.svg +3 -0
  117. package/src/components/icon/utils/svgs/chevron-left-double.svg +4 -0
  118. package/src/components/icon/utils/svgs/chevron-left.svg +3 -0
  119. package/src/components/icon/utils/svgs/chevron-right-double.svg +4 -0
  120. package/src/components/icon/utils/svgs/chevron-right.svg +3 -0
  121. package/src/components/icon/utils/svgs/chevron-up.svg +3 -0
  122. package/src/components/icon/utils/svgs/clock.svg +4 -0
  123. package/src/components/icon/utils/svgs/close-outline.svg +3 -0
  124. package/src/components/icon/utils/svgs/close.svg +3 -0
  125. package/src/components/icon/utils/svgs/columns.svg +3 -0
  126. package/src/components/icon/utils/svgs/conclusion.svg +17 -0
  127. package/src/components/icon/utils/svgs/copy.svg +16 -0
  128. package/src/components/icon/utils/svgs/crosshair.svg +15 -0
  129. package/src/components/icon/utils/svgs/dash.svg +3 -0
  130. package/src/components/icon/utils/svgs/dashboard.svg +3 -0
  131. package/src/components/icon/utils/svgs/delete.svg +4 -0
  132. package/src/components/icon/utils/svgs/delta.svg +3 -0
  133. package/src/components/icon/utils/svgs/download.svg +3 -0
  134. package/src/components/icon/utils/svgs/drag.svg +8 -0
  135. package/src/components/icon/utils/svgs/drilldown.svg +8 -0
  136. package/src/components/icon/utils/svgs/edit.svg +16 -0
  137. package/src/components/icon/utils/svgs/envelope.svg +3 -0
  138. package/src/components/icon/utils/svgs/error.svg +3 -0
  139. package/src/components/icon/utils/svgs/export-document.svg +16 -0
  140. package/src/components/icon/utils/svgs/filter.svg +6 -0
  141. package/src/components/icon/utils/svgs/filters.svg +4 -0
  142. package/src/components/icon/utils/svgs/flag.svg +3 -0
  143. package/src/components/icon/utils/svgs/folder.svg +15 -0
  144. package/src/components/icon/utils/svgs/frequency.svg +3 -0
  145. package/src/components/icon/utils/svgs/fullscreen-off.svg +3 -0
  146. package/src/components/icon/utils/svgs/fullscreen-on.svg +3 -0
  147. package/src/components/icon/utils/svgs/graduate.svg +3 -0
  148. package/src/components/icon/utils/svgs/hamburger.svg +5 -0
  149. package/src/components/icon/utils/svgs/handshake.svg +15 -0
  150. package/src/components/icon/utils/svgs/heading-1.svg +4 -0
  151. package/src/components/icon/utils/svgs/heading-2.svg +4 -0
  152. package/src/components/icon/utils/svgs/heading.svg +3 -0
  153. package/src/components/icon/utils/svgs/home.svg +3 -0
  154. package/src/components/icon/utils/svgs/id-card.svg +6 -0
  155. package/src/components/icon/utils/svgs/id.svg +4 -0
  156. package/src/components/icon/utils/svgs/indent-left.svg +7 -0
  157. package/src/components/icon/utils/svgs/indent-right.svg +7 -0
  158. package/src/components/icon/utils/svgs/information.svg +17 -0
  159. package/src/components/icon/utils/svgs/italics.svg +3 -0
  160. package/src/components/icon/utils/svgs/itenary.svg +11 -0
  161. package/src/components/icon/utils/svgs/keyboard.svg +11 -0
  162. package/src/components/icon/utils/svgs/lightning.svg +15 -0
  163. package/src/components/icon/utils/svgs/link.svg +4 -0
  164. package/src/components/icon/utils/svgs/list-collapse.svg +6 -0
  165. package/src/components/icon/utils/svgs/list-expand.svg +6 -0
  166. package/src/components/icon/utils/svgs/location.svg +4 -0
  167. package/src/components/icon/utils/svgs/lock-locked.svg +4 -0
  168. package/src/components/icon/utils/svgs/lock-unlocked.svg +4 -0
  169. package/src/components/icon/utils/svgs/magnifying-glass.svg +15 -0
  170. package/src/components/icon/utils/svgs/map.svg +3 -0
  171. package/src/components/icon/utils/svgs/megaphone.svg +3 -0
  172. package/src/components/icon/utils/svgs/message.svg +15 -0
  173. package/src/components/icon/utils/svgs/microscope.svg +3 -0
  174. package/src/components/icon/utils/svgs/moon.svg +3 -0
  175. package/src/components/icon/utils/svgs/new-document.svg +4 -0
  176. package/src/components/icon/utils/svgs/news.svg +15 -0
  177. package/src/components/icon/utils/svgs/numbered-list.svg +7 -0
  178. package/src/components/icon/utils/svgs/open-link.svg +16 -0
  179. package/src/components/icon/utils/svgs/options.svg +5 -0
  180. package/src/components/icon/utils/svgs/page.svg +7 -0
  181. package/src/components/icon/utils/svgs/paper-plane.svg +15 -0
  182. package/src/components/icon/utils/svgs/paper.svg +3 -0
  183. package/src/components/icon/utils/svgs/pen-and-paper.svg +4 -0
  184. package/src/components/icon/utils/svgs/phase.svg +15 -0
  185. package/src/components/icon/utils/svgs/photo.svg +4 -0
  186. package/src/components/icon/utils/svgs/pie-chart.svg +3 -0
  187. package/src/components/icon/utils/svgs/plus.svg +3 -0
  188. package/src/components/icon/utils/svgs/point-left.svg +3 -0
  189. package/src/components/icon/utils/svgs/point-up.svg +3 -0
  190. package/src/components/icon/utils/svgs/popup.svg +16 -0
  191. package/src/components/icon/utils/svgs/question.svg +17 -0
  192. package/src/components/icon/utils/svgs/radio-tower.svg +3 -0
  193. package/src/components/icon/utils/svgs/recycle.svg +3 -0
  194. package/src/components/icon/utils/svgs/redo.svg +3 -0
  195. package/src/components/icon/utils/svgs/refresh.svg +3 -0
  196. package/src/components/icon/utils/svgs/route.svg +3 -0
  197. package/src/components/icon/utils/svgs/rows.svg +3 -0
  198. package/src/components/icon/utils/svgs/scope.svg +7 -0
  199. package/src/components/icon/utils/svgs/settings.svg +16 -0
  200. package/src/components/icon/utils/svgs/share.svg +11 -0
  201. package/src/components/icon/utils/svgs/sign-in.svg +4 -0
  202. package/src/components/icon/utils/svgs/sign-up.svg +3 -0
  203. package/src/components/icon/utils/svgs/sort-down.svg +20 -0
  204. package/src/components/icon/utils/svgs/sort-up.svg +20 -0
  205. package/src/components/icon/utils/svgs/sort.svg +7 -0
  206. package/src/components/icon/utils/svgs/square-solid.svg +3 -0
  207. package/src/components/icon/utils/svgs/star-solid.svg +15 -0
  208. package/src/components/icon/utils/svgs/star.svg +15 -0
  209. package/src/components/icon/utils/svgs/stop-watch.svg +5 -0
  210. package/src/components/icon/utils/svgs/structure.svg +3 -0
  211. package/src/components/icon/utils/svgs/sun.svg +23 -0
  212. package/src/components/icon/utils/svgs/table.svg +3 -0
  213. package/src/components/icon/utils/svgs/tag.svg +15 -0
  214. package/src/components/icon/utils/svgs/team.svg +15 -0
  215. package/src/components/icon/utils/svgs/telescope.svg +15 -0
  216. package/src/components/icon/utils/svgs/trash.svg +6 -0
  217. package/src/components/icon/utils/svgs/triangle-angle.svg +3 -0
  218. package/src/components/icon/utils/svgs/triangle-side.svg +3 -0
  219. package/src/components/icon/utils/svgs/underline.svg +4 -0
  220. package/src/components/icon/utils/svgs/undo.svg +3 -0
  221. package/src/components/icon/utils/svgs/user.svg +16 -0
  222. package/src/components/icon/utils/svgs/venn.svg +3 -0
  223. package/src/components/icon/utils/svgs/video.svg +3 -0
  224. package/src/components/icon/utils/svgs/visibility-off-alt.svg +19 -0
  225. package/src/components/icon/utils/svgs/visibility-off.svg +3 -0
  226. package/src/components/icon/utils/svgs/visibility-on.svg +16 -0
  227. package/src/components/icon/utils/svgs/warning.svg +5 -0
  228. package/src/components/index.ts +45 -0
  229. package/src/components/input/Input.vue +118 -0
  230. package/src/components/input/index.ts +1 -0
  231. package/src/components/input-number/InputNumber.vue +112 -0
  232. package/src/components/input-number/StepButton.vue +23 -0
  233. package/src/components/input-number/index.ts +1 -0
  234. package/src/components/load-spinner/LoadSpinner.vue +13 -0
  235. package/src/components/load-spinner/index.ts +1 -0
  236. package/src/components/modal/Modal.vue +111 -0
  237. package/src/components/modal/index.ts +1 -0
  238. package/src/components/nav-item/NavItem.vue +62 -0
  239. package/src/components/nav-item/index.ts +1 -0
  240. package/src/components/notification/Notification.vue +53 -0
  241. package/src/components/notification/index.ts +1 -0
  242. package/src/components/notification-badge/NotificationBadge.vue +7 -0
  243. package/src/components/notification-badge/index.ts +1 -0
  244. package/src/components/pagination/Pagination.vue +65 -0
  245. package/src/components/pagination/index.ts +1 -0
  246. package/src/components/pop-confirm/PopConfirm.vue +90 -0
  247. package/src/components/pop-confirm/index.ts +1 -0
  248. package/src/components/pop-select/FooterButton.vue +5 -0
  249. package/src/components/pop-select/PopSelect.vue +346 -0
  250. package/src/components/pop-select/ResultFilters.vue +28 -0
  251. package/src/components/pop-select/enums.ts +7 -0
  252. package/src/components/pop-select/index.ts +2 -0
  253. package/src/components/pop-select/option.vue +51 -0
  254. package/src/components/popper/Popper.vue +239 -0
  255. package/src/components/popper/PopperContent.vue +5 -0
  256. package/src/components/popper/index.ts +2 -0
  257. package/src/components/popper/middleware.ts +19 -0
  258. package/src/components/screen-overlay/ScreenOverlay.vue +53 -0
  259. package/src/components/screen-overlay/index.ts +1 -0
  260. package/src/components/scrollbar/Bar.vue +106 -0
  261. package/src/components/scrollbar/ScrollBottomLoader.vue +25 -0
  262. package/src/components/scrollbar/Scrollbar.vue +219 -0
  263. package/src/components/scrollbar/enums.ts +23 -0
  264. package/src/components/scrollbar/index.ts +3 -0
  265. package/src/components/scrollbar/style.scss +77 -0
  266. package/src/components/scrollbar/types.ts +32 -0
  267. package/src/components/select-list/SelectList.vue +476 -0
  268. package/src/components/select-list/components/SelectListFilterChip.vue +34 -0
  269. package/src/components/select-list/components/index.ts +3 -0
  270. package/src/components/select-list/components/option-group/OptionGroup.vue +20 -0
  271. package/src/components/select-list/components/option-group/index.ts +1 -0
  272. package/src/components/select-list/components/select-list-option/SelectListOption.vue +83 -0
  273. package/src/components/select-list/components/select-list-option/index.ts +1 -0
  274. package/src/components/select-list/components/status-cards/error-card/ErrorCard.vue +17 -0
  275. package/src/components/select-list/components/status-cards/error-card/index.ts +1 -0
  276. package/src/components/select-list/components/status-cards/idle-card/IdleCard.vue +11 -0
  277. package/src/components/select-list/components/status-cards/idle-card/index.ts +1 -0
  278. package/src/components/select-list/components/status-cards/index.ts +4 -0
  279. package/src/components/select-list/components/status-cards/loading-card/LoadingCard.vue +10 -0
  280. package/src/components/select-list/components/status-cards/loading-card/index.ts +1 -0
  281. package/src/components/select-list/components/status-cards/no-match-card/NoMatchCard.vue +15 -0
  282. package/src/components/select-list/components/status-cards/no-match-card/index.ts +1 -0
  283. package/src/components/select-list/components/status-cards/status-card/StatusCard.vue +25 -0
  284. package/src/components/select-list/components/status-cards/status-card/index.ts +1 -0
  285. package/src/components/select-list/index.ts +5 -0
  286. package/src/components/select-list/types.ts +49 -0
  287. package/src/components/side-over/SideOver.vue +87 -0
  288. package/src/components/side-over/index.ts +1 -0
  289. package/src/components/status-select/StatusIndicator.vue +78 -0
  290. package/src/components/status-select/StatusSelect.vue +62 -0
  291. package/src/components/status-select/index.ts +1 -0
  292. package/src/components/switch/Switch.vue +52 -0
  293. package/src/components/switch/index.ts +1 -0
  294. package/src/components/tab/Tab.vue +65 -0
  295. package/src/components/tab/index.ts +1 -0
  296. package/src/components/tag/Tag.vue +34 -0
  297. package/src/components/tag/index.ts +1 -0
  298. package/src/components/text-editor/TextEditor.vue +399 -0
  299. package/src/components/text-editor/components/Dialog.vue +11 -0
  300. package/src/components/text-editor/components/FormattingButton.vue +46 -0
  301. package/src/components/text-editor/components/InsertLinkDialog.vue +81 -0
  302. package/src/components/text-editor/components/InsertTextDialog.vue +36 -0
  303. package/src/components/text-editor/components/index.ts +3 -0
  304. package/src/components/text-editor/index.ts +1 -0
  305. package/src/components/text-highlight/TextHighlight.vue +113 -0
  306. package/src/components/text-highlight/index.ts +1 -0
  307. package/src/components/text-viewer/TextViewer.vue +5 -0
  308. package/src/components/text-viewer/index.ts +1 -0
  309. package/src/components/toggle-button/ToggleButton.vue +105 -0
  310. package/src/components/toggle-button/index.ts +1 -0
  311. package/src/components/tooltip/Tooltip.vue +54 -0
  312. package/src/components/tooltip/index.ts +1 -0
  313. package/src/components/types.ts +232 -0
  314. package/src/components/vertical-layout/RunningSection.vue +54 -0
  315. package/src/components/vertical-layout/VerticalLayout.vue +37 -0
  316. package/src/components/vertical-layout/index.ts +3 -0
  317. package/src/components/vertical-layout/types.ts +2 -0
  318. package/src/components/window-frame/WindowFrame.vue +20 -0
  319. package/src/components/window-frame/index.ts +1 -0
  320. package/src/composables/index.ts +5 -0
  321. package/src/composables/useClickOutside.ts +48 -0
  322. package/src/composables/useEscapeKey.ts +12 -0
  323. package/src/composables/useMounted.ts +7 -0
  324. package/src/composables/useNextFrame.ts +10 -0
  325. package/src/composables/useTrapFocus.ts +61 -0
  326. package/src/index.ts +5 -0
  327. package/src/main.css +140 -0
  328. package/src/utils/array.ts +11 -0
  329. package/src/utils/capitalizeFirstLetter.ts +4 -0
  330. package/src/utils/clamp.ts +9 -0
  331. package/src/utils/debounce.ts +8 -0
  332. package/src/utils/index.ts +5 -0
  333. package/src/utils/scrollIntoView.ts +25 -0
  334. package/src/utils/scrollbarWidth.ts +27 -0
@@ -0,0 +1,476 @@
1
+ <script setup lang="ts" generic="T extends SelectListOption">
2
+ import type { ScrollIntersectionEvent } from "../../components";
3
+ import type { SelectListFilter, SelectListOption, SelectListOptionGroup, SelectListProps, SelectListState } from "./types.ts";
4
+ import debounce from "debounce";
5
+ import { computed, nextTick, onBeforeMount, onBeforeUnmount, onMounted, ref, watch } from "vue";
6
+ import { BButton, BCheckbox, BInput, BScrollbar } from "../..";
7
+ import { useNextFrame } from "../../composables";
8
+ import { scrollIntoView } from "../../utils";
9
+
10
+ import { BErrorCard, BIdleCard, BLoadingCard, BNoMatchCard } from "./components/status-cards";
11
+
12
+ const props = withDefaults(defineProps<SelectListProps>(), {
13
+ identifier: "label",
14
+ loading: false,
15
+ placeholder: "Search",
16
+ small: false,
17
+ remoteMethod: null,
18
+ });
19
+
20
+ // TODO:
21
+ // Control fixed height via props. See style attribute in root <div/>
22
+
23
+ const emit = defineEmits(["escape", "selectQuery", "select"]);
24
+
25
+ const { nextFrame } = useNextFrame();
26
+
27
+ const hoveredOption = ref<SelectListOption | null>(null);
28
+ const localOptions = ref<SelectListOption[] | SelectListOptionGroup[]>([]);
29
+ const searchQuery = ref("");
30
+
31
+ const selectListRef = ref<HTMLDivElement>();
32
+ const optionsRef = ref();
33
+ const scrollbarRef = ref<typeof BScrollbar>();
34
+ const selectedOptionsRef = ref();
35
+ const selectionScrollbarRef = ref<typeof BScrollbar>();
36
+
37
+ const selectedOptionFilter = ref<SelectListFilter | null>(props.filters ? props.filters[0] : null);
38
+ const selectionOpen = ref(false);
39
+ const selectionOverflow = ref(false);
40
+ const selectionScrollClasses = ref("");
41
+
42
+ // we need to know if the options passed is an array of options or option groups
43
+ const isOptionGroup = (obj: unknown): obj is SelectListOptionGroup => {
44
+ if (!Array.isArray(obj)) throw new Error("Item passed must be an Array");
45
+ if (obj.length === 0) return false;
46
+ return "options" in obj[0];
47
+ };
48
+ const isGrouped = computed(() => isOptionGroup(props.options));
49
+ const flattenedOptions = computed((): SelectListOption[] => {
50
+ if (!isGrouped.value) return props.options as SelectListOption[];
51
+ return (props.options as SelectListOptionGroup[]).flatMap((group: SelectListOptionGroup) => group.options);
52
+ });
53
+
54
+ const state = computed((): SelectListState => {
55
+ if (props.loading) return "loading";
56
+ if (props.errorMessage) return "error";
57
+ if (searchQuery.value.length && !localOptions.value.length) return "no match";
58
+ if (localOptions.value.length) return "match";
59
+ return "idle";
60
+ });
61
+
62
+ const isMultiselect = computed(() => props.selected && "length" in props.selected);
63
+
64
+ const selectedCount = computed(() => {
65
+ if (!props.selected) return 0;
66
+ return isMultiselect.value ? (props.selected as T[]).length : 1;
67
+ });
68
+
69
+ const allOptionsSelected = computed(() => {
70
+ if (!props.selected) return false;
71
+ // TODO - consider whether or not we should show "all selected" when a filter is applied and all the filtered items has been selected
72
+ // introduces complexity, as we need to check if exactely the same options are selected and not just the count
73
+ // plus what if more items are selected than the filtered... this is why I will currently abandon this idea
74
+
75
+ if (selectedOptionFilter.value) {
76
+ return (props.selected as T[]).length >= flattenedOptions.value.filter(selectedOptionFilter.value.execute).length;
77
+ }
78
+
79
+ return isMultiselect.value ? (props.selected as T[]).length === flattenedOptions.value.length : false;
80
+ });
81
+
82
+ const noSelection = computed(() => {
83
+ if (!props.selected) return true;
84
+ return isMultiselect.value ? !(props.selected as T[]).length : !props.selected;
85
+ });
86
+
87
+ watch(() => props.selected, (newValue: SelectListOption | SelectListOption[] | null) => {
88
+ if (newValue && selectionOpen.value) {
89
+ nextFrame(() => {
90
+ scrollbarRef.value!.update();
91
+
92
+ if (isMultiselect.value && selectedCount.value) {
93
+ const target = selectedOptionsRef.value[selectedOptionsRef.value.length - 1].$el;
94
+ const scrollView: HTMLElement | null = selectionScrollbarRef.value!.$el.querySelector(".scrollbar__wrap");
95
+ if (scrollView) {
96
+ scrollIntoView(scrollView, target);
97
+ selectionScrollbarRef.value!.handleScroll();
98
+ }
99
+ }
100
+ });
101
+ }
102
+ });
103
+
104
+ watch(() => props.options, (newValue: SelectListOption[] | SelectListOptionGroup[]) => {
105
+ // eslint-disable-next-line ts/no-use-before-define
106
+ updateLocalOptions(newValue);
107
+ hoveredOption.value = null;
108
+ });
109
+
110
+ // eslint-disable-next-line ts/no-use-before-define
111
+ onBeforeMount(() => updateLocalOptions(props.options));
112
+ onMounted(() => {
113
+ if (!isMultiselect.value && props.selectAll) {
114
+ console.warn("[SelectList] selectAll prop not allowed when SelectList is not isMultiselect. You need to pass an Array of selected options (or empty) if you want it to be isMultiselect.");
115
+ }
116
+
117
+ nextFrame(() => {
118
+ if (scrollbarRef.value) scrollbarRef.value!.update();
119
+ // eslint-disable-next-line ts/no-use-before-define
120
+ selectListRef.value!.addEventListener("keydown", onKeydown);
121
+ });
122
+ // focusSearch();
123
+ });
124
+
125
+ // eslint-disable-next-line ts/no-use-before-define
126
+ onBeforeUnmount(() => selectListRef.value!.removeEventListener("keydown", onKeydown));
127
+
128
+ const onKeydown = (event: KeyboardEvent) => {
129
+ if (event.key === "Enter") {
130
+ // eslint-disable-next-line ts/no-use-before-define
131
+ selectOption();
132
+ }
133
+ else if (event.key === "Escape") {
134
+ emit("escape");
135
+ }
136
+ else if (event.key === "ArrowDown") {
137
+ // eslint-disable-next-line ts/no-use-before-define
138
+ navigateOptions("next");
139
+ }
140
+ else if (event.key === "ArrowUp") {
141
+ // eslint-disable-next-line ts/no-use-before-define
142
+ navigateOptions("prev");
143
+ }
144
+ };
145
+
146
+ const onSelect = (option: SelectListOption) => {
147
+ if (isMultiselect.value) {
148
+ const newSelection = (props.selected as T[]).map(i => i.label).includes(option.label)
149
+ ? [...(props.selected as T[]).filter(i => i.label !== option.label)]
150
+ : [...(props.selected as T[]), option];
151
+ emit("select", newSelection);
152
+ }
153
+ else {
154
+ emit("select", option);
155
+ }
156
+ };
157
+
158
+ const selectOption = () => {
159
+ if (hoveredOption.value) {
160
+ onSelect(hoveredOption.value);
161
+ }
162
+ else if (searchQuery.value.length) {
163
+ emit("selectQuery", searchQuery.value);
164
+ }
165
+ };
166
+
167
+ const optionIsSelected = (option: SelectListOption) => {
168
+ if (!props.selected) return false;
169
+
170
+ if (isMultiselect.value) {
171
+ return (props.selected as T[]).some(o => o[props.identifier] === (option as T)[props.identifier]);
172
+ }
173
+
174
+ return (option as T)[props.identifier] === (props.selected as T)[props.identifier];
175
+ };
176
+
177
+ const onSearch = async (value: string) => {
178
+ searchQuery.value = value;
179
+ hoveredOption.value = null;
180
+
181
+ if (props.searchFunction) {
182
+ await props.searchFunction(value);
183
+ }
184
+ };
185
+ const debounceOnSearch = props.searchDebounce ? debounce(onSearch, props.searchDebounce) : onSearch;
186
+
187
+ const updateLocalOptions = (options: SelectListOption[] | SelectListOptionGroup[]) => {
188
+ if (isGrouped.value) {
189
+ const groups = options as SelectListOptionGroup[];
190
+ localOptions.value = groups.map(group => ({
191
+ ...group,
192
+ options: selectedOptionFilter.value ? group.options.filter(selectedOptionFilter.value?.execute) : group.options,
193
+ }));
194
+ }
195
+ else {
196
+ const flatOptions = options as SelectListOption[];
197
+ localOptions.value = selectedOptionFilter.value ? flatOptions.filter(selectedOptionFilter.value?.execute) : flatOptions;
198
+ }
199
+
200
+ // Update option filter counts
201
+ // if (props.filters) {
202
+ // localOptionFilters.value.forEach((filter) => {
203
+ // filter.count = isGrouped.value
204
+ // ? options.reduce((acc: number, group: SelectListOptionGroup): number => {
205
+ // acc += group.options.filter(filter.execute).length;
206
+ // return acc;
207
+ // }, 0)
208
+ // : options.filter(filter.execute).length;
209
+ // });
210
+ // }
211
+ // nextFrame(() => scrollbarRef.value!.update());
212
+ };
213
+
214
+ const onOptionFilterChange = (filter: SelectListFilter) => {
215
+ selectedOptionFilter.value = filter;
216
+ updateLocalOptions(props.options);
217
+ // focusSearch();
218
+ };
219
+
220
+ const onToggleAll = () => {
221
+ if (!isMultiselect.value) throw new Error("[SelectList@onToggleAll] method should not be called when \"isMultiselect=false\"");
222
+
223
+ // need to do a different check if selectedOptionFilter has a value
224
+ // then check if "allFilteredOptionsSelected"
225
+ if (selectedCount.value === 0 || Boolean(selectedCount.value && !allOptionsSelected.value)) {
226
+ emit("select", selectedOptionFilter.value ? flattenedOptions.value.filter(selectedOptionFilter.value.execute) : flattenedOptions.value);
227
+ }
228
+ else {
229
+ emit("select", []);
230
+ }
231
+ };
232
+
233
+ /**
234
+ * Navigating and highlighting
235
+ */
236
+ const onOptionHover = (option: T) => hoveredOption.value = flattenedOptions.value.find(o => (o as T)[props.identifier] === option[props.identifier]) || null;
237
+ const allOptionsDisabled = computed(() => {
238
+ // If options are grouped, flatten them before checking
239
+ const options = Array.isArray(localOptions.value) && localOptions.value.length > 0 && "options" in localOptions.value[0]
240
+ ? (localOptions.value as SelectListOptionGroup[]).flatMap(group => group.options)
241
+ : (localOptions.value as SelectListOption[]);
242
+ return options.length > 0 && options.every((option: any) => !!option.disabled);
243
+ });
244
+
245
+ const navigateOptions = async (direction: "next" | "prev") => {
246
+ if (localOptions.value.length === 0) return;
247
+
248
+ let hoverIndex = flattenedOptions.value.findIndex(o => o.label === hoveredOption.value?.label);
249
+
250
+ if (!allOptionsDisabled.value) {
251
+ if (direction === "next") {
252
+ hoverIndex++;
253
+ if (hoverIndex === localOptions.value.length) {
254
+ hoverIndex = 0;
255
+ }
256
+ }
257
+ else if (direction === "prev") {
258
+ hoverIndex--;
259
+ if (hoverIndex < 0) {
260
+ hoverIndex = localOptions.value.length - 1;
261
+ }
262
+ }
263
+ hoveredOption.value = flattenedOptions.value[hoverIndex];
264
+
265
+ if (hoveredOption.value.disabled === true) {
266
+ navigateOptions(direction);
267
+ }
268
+
269
+ await nextTick();
270
+
271
+ if (hoveredOption.value) {
272
+ // eslint-disable-next-line ts/no-use-before-define
273
+ scrollToOption(hoveredOption.value);
274
+ }
275
+ }
276
+ };
277
+
278
+ const scrollToOption = (_option: SelectListOption) => {
279
+ if (!optionsRef.value.children.length) return;
280
+
281
+ // TODO add data attribute to options and query those within the optionsRef
282
+
283
+ const target = null; // optionsRef.value.children[localOptions.value.findIndex(o => o.label === option.label)].$el;
284
+
285
+ if (scrollbarRef.value && target) {
286
+ const scrollView: HTMLElement | null = scrollbarRef.value.$el.querySelector(".scrollbar__wrap");
287
+ if (scrollView) {
288
+ scrollIntoView(scrollView, target);
289
+ scrollbarRef.value.handleScroll();
290
+ }
291
+ }
292
+ };
293
+
294
+ const onToggleSelectionFooter = () => {
295
+ selectionOpen.value = !selectionOpen.value;
296
+ selectionScrollbarRef.value!.update();
297
+ };
298
+ const selectionClassesComputed = computed(() => {
299
+ return selectionOpen.value && selectionOverflow.value ? selectionScrollClasses.value : "border-transparent";
300
+ });
301
+ const onSelectionFooterIntersect = (payload: ScrollIntersectionEvent) => {
302
+ if (!payload.hit) {
303
+ selectionScrollClasses.value = "border-y-outline-subtle shadow-scroll-y";
304
+ }
305
+ else if (payload.edge === "bottom" && payload.hit) {
306
+ selectionScrollClasses.value = "border-b-transparent border-t-outline-subtle shadow-scroll-top";
307
+ }
308
+ else if (payload.edge === "top" && payload.hit) {
309
+ selectionScrollClasses.value = "border-t-transparent border-b-outline-subtle shadow-scroll-bottom";
310
+ }
311
+ };
312
+ const onScrollYActive = (active: boolean) => {
313
+ selectionOverflow.value = active;
314
+ };
315
+
316
+ const reset = () => {
317
+ searchQuery.value = "";
318
+ props.searchFunction ? props.searchFunction("") : updateLocalOptions([]);
319
+ selectedOptionFilter.value = props.filters ? props.filters[0] : null;
320
+ };
321
+
322
+ defineExpose({
323
+ // focusSearch,
324
+ isMultiselect,
325
+ reset,
326
+ scrollbarRef,
327
+ });
328
+ </script>
329
+
330
+ <template>
331
+ <div
332
+ ref="selectListRef"
333
+ tabindex="0"
334
+ class="relative flex flex-col focus:outline-none w-full h-full overflow-hidden"
335
+ :style="{
336
+ height: searchFunction ? '640px' : undefined,
337
+ maxHeight: searchFunction ? undefined : '100%',
338
+ }"
339
+ >
340
+ <header
341
+ v-if="$slots.header || searchFunction || filters || selectAll"
342
+ class="flex-0 flex flex-col gap-2 p-2 border-b border-default"
343
+ >
344
+ <slot name="header" />
345
+
346
+ <section v-if="searchFunction" class="">
347
+ <BInput
348
+ class="w-full"
349
+ clearable
350
+ :value="searchQuery"
351
+ :placeholder="placeholder"
352
+ @change="debounceOnSearch"
353
+ @clear="onSearch('')"
354
+ />
355
+ </section>
356
+
357
+ <section v-if="filters" class="flex items-center gap-1">
358
+ <BButton
359
+ v-for="filter in filters"
360
+ :key="filter.name"
361
+ small
362
+ variant="textSubtle"
363
+ :focus="Boolean(selectedOptionFilter && selectedOptionFilter.name === filter.name)"
364
+ :label="filter.name"
365
+ @click="onOptionFilterChange(filter)"
366
+ />
367
+ </section>
368
+
369
+ <button
370
+ v-if="selectAll"
371
+ class="cursor-pointer flex items-center gap-2 px-2 py-1 rounded-lg hover:bg-secondary active:bg-tertiary"
372
+ @click="onToggleAll"
373
+ >
374
+ <BCheckbox
375
+ :indeterminate="Boolean(selectedCount && !allOptionsSelected)"
376
+ :checked="allOptionsSelected"
377
+ @click="onToggleAll"
378
+ />
379
+ <span class="text-sm text-muted italic">Select/deselect all</span>
380
+ </button>
381
+ </header>
382
+
383
+ <main class="flex-1 h-full overflow-hidden flex flex-col">
384
+ <BErrorCard v-if="state === 'error'" :message="errorMessage as string" />
385
+ <BLoadingCard v-else-if="state === 'loading'" />
386
+ <BNoMatchCard v-else-if="state === 'no match'" />
387
+ <BIdleCard v-else-if="state === 'idle'" />
388
+ <BScrollbar
389
+ v-else-if="state === 'match'"
390
+ ref="scrollbarRef"
391
+ class="flex-1"
392
+ show
393
+ >
394
+ <ul
395
+ ref="optionsRef"
396
+ class="px-1"
397
+ :class="{
398
+ 'py-2': small && isGrouped || !small && !isGrouped,
399
+ 'py-1': small && !isGrouped,
400
+ 'py-4': !small && isGrouped,
401
+ }"
402
+ >
403
+ <slot
404
+ name="options"
405
+ :options="localOptions"
406
+ :hover="onOptionHover"
407
+ :hovered-option="hoveredOption"
408
+ :select="onSelect"
409
+ :get-is-selected="optionIsSelected"
410
+ />
411
+ </ul>
412
+ </BScrollbar>
413
+ </main>
414
+
415
+ <template v-if="$slots.footer">
416
+ <footer class="flex-initial max-h-72 flex flex-col border-t-1 border-default">
417
+ <template v-if="showSelection">
418
+ <header class="flex-none flex items-center justify-between gap-1 px-4 py-1">
419
+ <BButton
420
+ square
421
+ size="tiny"
422
+ variant="text"
423
+ class="-ml-4"
424
+ :label="`${selectionOpen ? 'Hide' : 'Show'} selected items (${selectedCount})`"
425
+ :trailing-icon="selectionOpen ? 'chevron-down' : 'chevron-up'"
426
+ @click="onToggleSelectionFooter"
427
+ />
428
+ </header>
429
+ <BScrollbar
430
+ ref="selectionScrollbarRef"
431
+ show
432
+ tag="ul"
433
+ class="border-y-1"
434
+ :class="selectionClassesComputed"
435
+ :view-height-class="selectionOpen ? 'flex-1 max-h-72' : 'flex-none h-0'"
436
+ @scroll-y-active="onScrollYActive"
437
+ @intersect="onSelectionFooterIntersect"
438
+ >
439
+ <template v-if="selectionOpen">
440
+ <span v-if="noSelection" class="px-4 h-8 flex items-center text-ui-label-14-regular text-disabled-font">Nothing selected</span>
441
+ <section class="w-full px-4 flex flex-wrap items-center gap-2">
442
+ <!-- <NInputChip
443
+ ref="selectedOptionsRef"
444
+ v-if="selected && isMultiselect"
445
+ v-for="option in selected"
446
+ :key="(option as T).id || (option as T).label"
447
+ :selected="optionIsSelected(option as T)"
448
+ :label="(option as T).label"
449
+ shape="squared"
450
+ variant="outline"
451
+ emphasis="strong"
452
+ closable
453
+ @close="onSelect(option as T)"
454
+ />
455
+ <NInputChip
456
+ ref="selectedOptionsRef"
457
+ v-else-if="selected"
458
+ :selected="true"
459
+ :label="(selected as T).label"
460
+ shape="squared"
461
+ variant="outline"
462
+ emphasis="strong"
463
+ closable
464
+ @close="onSelect(selected as T)"
465
+ /> -->
466
+ </section>
467
+ </template>
468
+ </BScrollbar>
469
+ </template>
470
+ <footer class="flex-0 px-6 py-4">
471
+ <slot name="footer" />
472
+ </footer>
473
+ </footer>
474
+ </template>
475
+ </div>
476
+ </template>
@@ -0,0 +1,34 @@
1
+ <script setup lang="ts">
2
+ const { filterCount, label } = defineProps<{
3
+ filterCount?: number;
4
+ label: string;
5
+ selected: boolean;
6
+ }>();
7
+ </script>
8
+
9
+ <template>
10
+ <button
11
+ class="
12
+ group
13
+ flex flex-shrink-0 items-center justify-center gap-1 w-fit h-8 py-2 rounded-x-large
14
+ text-ui-button-12
15
+ focus-visible:outline-focus focus-visible:outline focus-visible:outline-offset-[1px]
16
+ "
17
+ :class="{
18
+ 'bg-primary hover:bg-primary-hover active:bg-primary-active text-white': selected,
19
+ 'bg-base-light hover:bg-base-medium active:bg-base-heavy text-primary hover:text-primary-hover active:text-primary-active': !selected,
20
+ 'pl-3 pr-1.5': filterCount,
21
+ 'px-3': !filterCount,
22
+ }"
23
+ >
24
+ {{ label }}
25
+
26
+ <template v-if="filterCount">
27
+ <div
28
+ class="pointer-events-none select-none flex items-center h-5 px-2 rounded-full text-ui-label-12-bold text-white bg-primary-hover group-hover:bg-primary-active"
29
+ >
30
+ {{ filterCount }}
31
+ </div>
32
+ </template>
33
+ </button>
34
+ </template>
@@ -0,0 +1,3 @@
1
+ export * from "./option-group";
2
+ export * from "./select-list-option";
3
+ export * from "./status-cards";
@@ -0,0 +1,20 @@
1
+ <script setup lang="ts">
2
+ const { small = false } = defineProps<{ label?: string; small?: boolean }>();
3
+ </script>
4
+
5
+ <template>
6
+ <section
7
+ class="relative w-full border-t border-default"
8
+ :class="{ 'first:border-t-0 first:pt-0': !label, 'py-2': small, 'py-4': !small }"
9
+ >
10
+ <div
11
+ v-if="label"
12
+ :style="{ top: small ? '-0.55rem' : '-0.63rem' }"
13
+ class="absolute bg-primary px-2 font-medium text-tertiary"
14
+ :class="{ 'text-[10px]': small, 'text-xs': !small }"
15
+ >
16
+ {{ label }}
17
+ </div>
18
+ <slot />
19
+ </section>
20
+ </template>
@@ -0,0 +1 @@
1
+ export { default as BSelectListOptionGroup } from "./OptionGroup.vue";
@@ -0,0 +1,83 @@
1
+ <script setup lang="ts">
2
+ import type { SelectListOption, SelectOptionVariant } from "../../types";
3
+ import { computed } from "vue";
4
+ import { BButton, BCheckbox, BIcon, BTextHighlight } from "../../../";
5
+
6
+ const { hoveredOption, selected, option, variant = "checkbox", small = false } = defineProps<{
7
+ hoveredOption?: SelectListOption | null;
8
+ option: SelectListOption;
9
+ selected: boolean;
10
+ search?: string;
11
+ small?: boolean;
12
+ variant?: SelectOptionVariant;
13
+ }>();
14
+
15
+ const emit = defineEmits(["click", "delete", "focus", "hover"]);
16
+
17
+ const isButton = computed(() => variant === "checkbox" || variant === "single");
18
+ const highlighted = computed(() => {
19
+ if (hoveredOption) {
20
+ if ("id" in hoveredOption && "id" in option) {
21
+ return hoveredOption.id === option.id;
22
+ }
23
+ return hoveredOption && hoveredOption.label === option.label;
24
+ }
25
+ return false;
26
+ });
27
+
28
+ const onToggle = () => emit("click");
29
+ </script>
30
+
31
+ <template>
32
+ <li class="list-none flex items-center w-full overflow-hidden bg-primary">
33
+ <component
34
+ :is="isButton ? 'button' : 'div'"
35
+ class="cursor-pointer w-full overflow-hidden rounded-lg flex items-center px-2 py-1 gap-2 hover:bg-secondary active:bg-tertiary"
36
+ :class="{
37
+ '': variant === 'checkbox',
38
+ 'bg-secondary': highlighted,
39
+ 'h-6 text-xs': small,
40
+ 'h-9 text-sm': !small,
41
+ }"
42
+ @click="onToggle"
43
+ @mouseover="emit('hover', option)"
44
+ @focus="emit('focus', option)"
45
+ >
46
+ <main class="flex-1 w-full overflow-hidden flex items-center gap-2">
47
+ <BCheckbox
48
+ v-if="variant === 'checkbox'"
49
+ :checked="selected"
50
+ class="flex-0"
51
+ @click="onToggle"
52
+ />
53
+ <BIcon
54
+ v-if="option.icon"
55
+ :name="option.icon"
56
+ class="w-4 h-4 flex-0"
57
+ :class="{
58
+ 'text-action': selected && variant === 'single',
59
+ }"
60
+ />
61
+ <BTextHighlight
62
+ background-color="yellow"
63
+ :value="option.label"
64
+ :highlight="search"
65
+ class="flex-1 pl-1 -ml-1 text-left min-w-0 truncate"
66
+ :class="{
67
+ 'text-action': selected && variant === 'single',
68
+ 'text-xs': small,
69
+ 'text-sm': !small,
70
+ }"
71
+ />
72
+ </main>
73
+ <span v-if="option.suffix" class="flex-0 text-sm text-secondary" :class="{ 'text-xs': small, 'text-sm': !small }">{{ option.suffix }}</span>
74
+ <BButton
75
+ v-if="variant === 'deletable'"
76
+ small
77
+ icon="close"
78
+ variant="text"
79
+ @click="emit('delete')"
80
+ />
81
+ </component>
82
+ </li>
83
+ </template>
@@ -0,0 +1 @@
1
+ export { default as BSelectListOption } from "./SelectListOption.vue";
@@ -0,0 +1,17 @@
1
+ <script setup lang="ts">
2
+ import { StatusCard } from "../status-card";
3
+
4
+ defineProps<{ message: string }>();
5
+ </script>
6
+
7
+ <template>
8
+ <StatusCard :status="message" variant="error">
9
+ <svg width="37" height="50" viewBox="0 0 37 50" fill="none" xmlns="http://www.w3.org/2000/svg">
10
+ <path d="M15.5369 1.94446C15.5369 1.94446 5.52391 3.36996 1.83341 15.1295C-1.27759 25.042 3.94441 41.9445 23.2614 46.1665" stroke="#C44836" stroke-width="2" stroke-miterlimit="10" stroke-linecap="round" />
11
+ <path d="M25.9997 48.1889C27.5125 48.1889 28.7387 46.9626 28.7387 45.4499C28.7387 43.9372 27.5125 42.7109 25.9997 42.7109C24.487 42.7109 23.2607 43.9372 23.2607 45.4499C23.2607 46.9626 24.487 48.1889 25.9997 48.1889Z" stroke="#C44836" stroke-width="2" stroke-miterlimit="10" stroke-linecap="round" />
12
+ <path d="M14.6998 23.153C17.4629 23.153 19.7028 20.9131 19.7028 18.15C19.7028 15.3869 17.4629 13.147 14.6998 13.147C11.9367 13.147 9.69678 15.3869 9.69678 18.15C9.69678 20.9131 11.9367 23.153 14.6998 23.153Z" stroke="#C44836" stroke-width="2" stroke-miterlimit="10" stroke-linecap="round" />
13
+ <path d="M21.7593 25.4259C21.7593 25.4259 23.8148 28.5369 27.7498 27.7224" stroke="#C44836" stroke-width="2" stroke-miterlimit="10" stroke-linecap="round" />
14
+ <path d="M22.7901 34.6389C29.0291 33.0074 31.2711 28.0774 31.7481 24.8944C31.7841 24.6529 31.9971 24.4779 32.2406 24.4779H34.6821C35.3996 24.4779 35.9811 23.8964 35.9811 23.1789C35.5506 19.5239 32.4851 5.23991 23.6876 2.17041C23.3106 2.03891 22.9346 2.38891 23.0396 2.77441C26.3746 15.0469 19.7031 18.1499 19.7031 18.1499" stroke="#C44836" stroke-width="2" stroke-miterlimit="10" stroke-linecap="round" />
15
+ </svg>
16
+ </StatusCard>
17
+ </template>
@@ -0,0 +1 @@
1
+ export { default as BErrorCard } from "./ErrorCard.vue";
@@ -0,0 +1,11 @@
1
+ <script setup lang="ts">
2
+ import { StatusCard } from "../status-card";
3
+ </script>
4
+
5
+ <template>
6
+ <StatusCard status="Type to search" variant="idle">
7
+ <svg width="44" height="36" viewBox="0 0 44 36" fill="none" xmlns="http://www.w3.org/2000/svg">
8
+ <path fill-rule="evenodd" clip-rule="evenodd" d="M15 1C15 0.447715 14.5523 0 14 0C13.4477 0 13 0.447715 13 1L12.9999 1.09744C12.9991 2.0294 12.9979 3.38692 13.6318 4.49614C14.3697 5.78762 15.781 6.5 18 6.5C18.878 6.5 19.4498 6.66469 19.8269 6.87416C20.1933 7.07776 20.435 7.35604 20.6056 7.69721C20.8594 8.2049 20.9503 8.82576 20.9826 9.5H3C1.34315 9.5 0 10.8431 0 12.5V32.5C0 34.1569 1.34315 35.5 3 35.5H41C42.6569 35.5 44 34.1569 44 32.5V12.5C44 10.8431 42.6569 9.5 41 9.5H22.9864C22.9515 8.65934 22.8281 7.67021 22.3944 6.80279C22.065 6.14396 21.5567 5.54724 20.7981 5.12584C20.0502 4.71031 19.122 4.5 18 4.5C16.219 4.5 15.6303 3.96238 15.3682 3.50386C15.0245 2.90238 15 2.06711 15 1ZM22 11.5H3C2.44772 11.5 2 11.9477 2 12.5V15.5H4H5H9H10H36H39H42V12.5C42 11.9477 41.5523 11.5 41 11.5H22ZM8 17.5H9H10H12V21.5H8V17.5ZM2 21.5V17.5H4H5H6V21.5H2ZM32 17.5H36V21.5H32V17.5ZM38 17.5H39H42V21.5H38V17.5ZM2 27.5V23.5H9V27.5H2ZM11 27.5V23.5H15V27.5H11ZM17 27.5H21V23.5H17V27.5ZM27 27.5H23V23.5H27V27.5ZM29 27.5H33V23.5H29V27.5ZM42 27.5H35V23.5H42V27.5ZM14 21.5H18V17.5H14V21.5ZM26 21.5H30V17.5H26V21.5ZM20 21.5H24V17.5H20V21.5ZM2 29.5V32.5C2 33.0523 2.44772 33.5 3 33.5H6V29.5H2ZM8 29.5V33.5H12V29.5H8ZM30 33.5H14V29.5H30V33.5ZM32 33.5H36V29.5H32V33.5ZM41 33.5H38V29.5H42V32.5C42 33.0523 41.5523 33.5 41 33.5ZM39 14.5C39.5523 14.5 40 14.0523 40 13.5C40 12.9477 39.5523 12.5 39 12.5H36C35.4477 12.5 35 12.9477 35 13.5C35 14.0523 35.4477 14.5 36 14.5H39ZM5 14.5C5.55228 14.5 6 14.0523 6 13.5C6 12.9477 5.55228 12.5 5 12.5H4C3.44772 12.5 3 12.9477 3 13.5C3 14.0523 3.44772 14.5 4 14.5H5ZM10 14.5C10.5523 14.5 11 14.0523 11 13.5C11 12.9477 10.5523 12.5 10 12.5H9C8.44771 12.5 8 12.9477 8 13.5C8 14.0523 8.44771 14.5 9 14.5H10Z" fill="#ADA7A1" />
9
+ </svg>
10
+ </StatusCard>
11
+ </template>
@@ -0,0 +1 @@
1
+ export { default as BIdleCard } from "./IdleCard.vue";
@@ -0,0 +1,4 @@
1
+ export * from "./error-card";
2
+ export * from "./idle-card";
3
+ export * from "./loading-card";
4
+ export * from "./no-match-card";