@firstnoodle-ui/bui 0.0.13 → 0.0.14

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 (272) hide show
  1. package/dist/bui.css +1 -1
  2. package/dist/components/checkbox/Checkbox.vue.d.ts +5 -9
  3. package/dist/components/checkbox/CircleIndicator.vue.d.ts +3 -2
  4. package/dist/components/checkbox/DefaultIndicator.vue.d.ts +3 -2
  5. package/dist/components/collapse/Collapse.vue.d.ts +0 -2
  6. package/dist/components/input/Input.vue.d.ts +3 -1
  7. package/dist/components/pagination/Pagination.vue.d.ts +4 -4
  8. package/dist/components/text-editor/components/InsertLinkDialog.vue.d.ts +5 -2
  9. package/dist/components/text-editor/components/InsertTextDialog.vue.d.ts +5 -2
  10. package/dist/components/types.d.ts +2 -0
  11. package/dist/index.mjs +4391 -4425
  12. package/package.json +8 -3
  13. package/dist/components/scrollbar/scrollbarWidth.d.ts +0 -1
  14. package/src/components/application-wrapper/ApplicationWrapper.vue +0 -8
  15. package/src/components/application-wrapper/index.ts +0 -1
  16. package/src/components/aside-section-label/AsideSectionLabel.vue +0 -16
  17. package/src/components/aside-section-label/index.ts +0 -1
  18. package/src/components/button/Button.vue +0 -245
  19. package/src/components/button/NotificationBadge.vue +0 -15
  20. package/src/components/button/index.ts +0 -1
  21. package/src/components/button-group/ButtonGroup.vue +0 -97
  22. package/src/components/button-group/index.ts +0 -1
  23. package/src/components/checkbox/Checkbox.vue +0 -52
  24. package/src/components/checkbox/CircleIndicator.vue +0 -27
  25. package/src/components/checkbox/DefaultIndicator.vue +0 -22
  26. package/src/components/checkbox/index.ts +0 -1
  27. package/src/components/collapse/Collapse.vue +0 -120
  28. package/src/components/collapse/index.ts +0 -1
  29. package/src/components/confirm-cancel/ConfirmCancel.vue +0 -79
  30. package/src/components/confirm-cancel/index.ts +0 -1
  31. package/src/components/data-point/DataPoint.vue +0 -5
  32. package/src/components/data-point/index.ts +0 -1
  33. package/src/components/dialog/Dialog.vue +0 -70
  34. package/src/components/dialog/index.ts +0 -1
  35. package/src/components/fade-in-up/FadeInUp.vue +0 -17
  36. package/src/components/fade-in-up/index.ts +0 -1
  37. package/src/components/first-paint/FirstPaint.vue +0 -21
  38. package/src/components/first-paint/index.ts +0 -1
  39. package/src/components/first-paint/style.scss +0 -23
  40. package/src/components/flexbox/Flexbox.vue +0 -50
  41. package/src/components/flexbox/index.ts +0 -1
  42. package/src/components/horizontal-layout/Aside.vue +0 -113
  43. package/src/components/horizontal-layout/HorizontalLayout.vue +0 -118
  44. package/src/components/horizontal-layout/index.ts +0 -2
  45. package/src/components/icon/Icon.vue +0 -1159
  46. package/src/components/icon/index.ts +0 -1
  47. package/src/components/icon/utils/combine-svgs.cjs +0 -55
  48. package/src/components/icon/utils/combined-svgs.txt +0 -1150
  49. package/src/components/icon/utils/svgs/admin.svg +0 -16
  50. package/src/components/icon/utils/svgs/arrow-deviate.svg +0 -3
  51. package/src/components/icon/utils/svgs/arrow-down-plus.svg +0 -4
  52. package/src/components/icon/utils/svgs/arrow-down.svg +0 -3
  53. package/src/components/icon/utils/svgs/arrow-from.svg +0 -3
  54. package/src/components/icon/utils/svgs/arrow-left.svg +0 -3
  55. package/src/components/icon/utils/svgs/arrow-move.svg +0 -15
  56. package/src/components/icon/utils/svgs/arrow-right.svg +0 -3
  57. package/src/components/icon/utils/svgs/arrow-sub.svg +0 -3
  58. package/src/components/icon/utils/svgs/arrow-trend.svg +0 -15
  59. package/src/components/icon/utils/svgs/arrow-up-plus.svg +0 -4
  60. package/src/components/icon/utils/svgs/arrow-up.svg +0 -3
  61. package/src/components/icon/utils/svgs/authority.svg +0 -5
  62. package/src/components/icon/utils/svgs/beams.svg +0 -5
  63. package/src/components/icon/utils/svgs/bell.svg +0 -15
  64. package/src/components/icon/utils/svgs/bold.svg +0 -3
  65. package/src/components/icon/utils/svgs/box.svg +0 -5
  66. package/src/components/icon/utils/svgs/building.svg +0 -15
  67. package/src/components/icon/utils/svgs/bullet-list.svg +0 -8
  68. package/src/components/icon/utils/svgs/calendar.svg +0 -21
  69. package/src/components/icon/utils/svgs/camera.svg +0 -5
  70. package/src/components/icon/utils/svgs/categories.svg +0 -3
  71. package/src/components/icon/utils/svgs/check-circled.svg +0 -16
  72. package/src/components/icon/utils/svgs/check-outline.svg +0 -15
  73. package/src/components/icon/utils/svgs/check.svg +0 -3
  74. package/src/components/icon/utils/svgs/chevron-down.svg +0 -3
  75. package/src/components/icon/utils/svgs/chevron-left-double.svg +0 -4
  76. package/src/components/icon/utils/svgs/chevron-left.svg +0 -3
  77. package/src/components/icon/utils/svgs/chevron-right-double.svg +0 -4
  78. package/src/components/icon/utils/svgs/chevron-right.svg +0 -3
  79. package/src/components/icon/utils/svgs/chevron-up.svg +0 -3
  80. package/src/components/icon/utils/svgs/clock.svg +0 -4
  81. package/src/components/icon/utils/svgs/close-outline.svg +0 -3
  82. package/src/components/icon/utils/svgs/close.svg +0 -3
  83. package/src/components/icon/utils/svgs/columns.svg +0 -3
  84. package/src/components/icon/utils/svgs/conclusion.svg +0 -17
  85. package/src/components/icon/utils/svgs/copy.svg +0 -16
  86. package/src/components/icon/utils/svgs/crosshair.svg +0 -15
  87. package/src/components/icon/utils/svgs/dash.svg +0 -3
  88. package/src/components/icon/utils/svgs/dashboard.svg +0 -3
  89. package/src/components/icon/utils/svgs/delete.svg +0 -4
  90. package/src/components/icon/utils/svgs/delta.svg +0 -3
  91. package/src/components/icon/utils/svgs/download.svg +0 -3
  92. package/src/components/icon/utils/svgs/drag.svg +0 -8
  93. package/src/components/icon/utils/svgs/drilldown.svg +0 -8
  94. package/src/components/icon/utils/svgs/edit.svg +0 -16
  95. package/src/components/icon/utils/svgs/envelope.svg +0 -3
  96. package/src/components/icon/utils/svgs/error.svg +0 -3
  97. package/src/components/icon/utils/svgs/export-document.svg +0 -16
  98. package/src/components/icon/utils/svgs/filter.svg +0 -6
  99. package/src/components/icon/utils/svgs/filters.svg +0 -4
  100. package/src/components/icon/utils/svgs/flag.svg +0 -3
  101. package/src/components/icon/utils/svgs/folder.svg +0 -15
  102. package/src/components/icon/utils/svgs/frequency.svg +0 -3
  103. package/src/components/icon/utils/svgs/fullscreen-off.svg +0 -3
  104. package/src/components/icon/utils/svgs/fullscreen-on.svg +0 -3
  105. package/src/components/icon/utils/svgs/graduate.svg +0 -3
  106. package/src/components/icon/utils/svgs/hamburger.svg +0 -5
  107. package/src/components/icon/utils/svgs/handshake.svg +0 -15
  108. package/src/components/icon/utils/svgs/heading-1.svg +0 -4
  109. package/src/components/icon/utils/svgs/heading-2.svg +0 -4
  110. package/src/components/icon/utils/svgs/heading.svg +0 -3
  111. package/src/components/icon/utils/svgs/home.svg +0 -3
  112. package/src/components/icon/utils/svgs/id-card.svg +0 -6
  113. package/src/components/icon/utils/svgs/id.svg +0 -4
  114. package/src/components/icon/utils/svgs/indent-left.svg +0 -7
  115. package/src/components/icon/utils/svgs/indent-right.svg +0 -7
  116. package/src/components/icon/utils/svgs/information.svg +0 -17
  117. package/src/components/icon/utils/svgs/italics.svg +0 -3
  118. package/src/components/icon/utils/svgs/itenary.svg +0 -11
  119. package/src/components/icon/utils/svgs/keyboard.svg +0 -11
  120. package/src/components/icon/utils/svgs/lightning.svg +0 -15
  121. package/src/components/icon/utils/svgs/link.svg +0 -4
  122. package/src/components/icon/utils/svgs/list-collapse.svg +0 -6
  123. package/src/components/icon/utils/svgs/list-expand.svg +0 -6
  124. package/src/components/icon/utils/svgs/location.svg +0 -4
  125. package/src/components/icon/utils/svgs/lock-locked.svg +0 -4
  126. package/src/components/icon/utils/svgs/lock-unlocked.svg +0 -4
  127. package/src/components/icon/utils/svgs/magnifying-glass.svg +0 -15
  128. package/src/components/icon/utils/svgs/map.svg +0 -3
  129. package/src/components/icon/utils/svgs/megaphone.svg +0 -3
  130. package/src/components/icon/utils/svgs/message.svg +0 -15
  131. package/src/components/icon/utils/svgs/microscope.svg +0 -3
  132. package/src/components/icon/utils/svgs/moon.svg +0 -3
  133. package/src/components/icon/utils/svgs/new-document.svg +0 -4
  134. package/src/components/icon/utils/svgs/news.svg +0 -15
  135. package/src/components/icon/utils/svgs/numbered-list.svg +0 -7
  136. package/src/components/icon/utils/svgs/open-link.svg +0 -16
  137. package/src/components/icon/utils/svgs/options.svg +0 -5
  138. package/src/components/icon/utils/svgs/page.svg +0 -7
  139. package/src/components/icon/utils/svgs/paper-plane.svg +0 -15
  140. package/src/components/icon/utils/svgs/paper.svg +0 -3
  141. package/src/components/icon/utils/svgs/pen-and-paper.svg +0 -4
  142. package/src/components/icon/utils/svgs/phase.svg +0 -15
  143. package/src/components/icon/utils/svgs/photo.svg +0 -4
  144. package/src/components/icon/utils/svgs/pie-chart.svg +0 -3
  145. package/src/components/icon/utils/svgs/plus.svg +0 -3
  146. package/src/components/icon/utils/svgs/point-left.svg +0 -3
  147. package/src/components/icon/utils/svgs/point-up.svg +0 -3
  148. package/src/components/icon/utils/svgs/popup.svg +0 -16
  149. package/src/components/icon/utils/svgs/question.svg +0 -17
  150. package/src/components/icon/utils/svgs/radio-tower.svg +0 -3
  151. package/src/components/icon/utils/svgs/recycle.svg +0 -3
  152. package/src/components/icon/utils/svgs/redo.svg +0 -3
  153. package/src/components/icon/utils/svgs/refresh.svg +0 -3
  154. package/src/components/icon/utils/svgs/route.svg +0 -3
  155. package/src/components/icon/utils/svgs/rows.svg +0 -3
  156. package/src/components/icon/utils/svgs/scope.svg +0 -7
  157. package/src/components/icon/utils/svgs/settings.svg +0 -16
  158. package/src/components/icon/utils/svgs/share.svg +0 -11
  159. package/src/components/icon/utils/svgs/sign-in.svg +0 -4
  160. package/src/components/icon/utils/svgs/sign-up.svg +0 -3
  161. package/src/components/icon/utils/svgs/sort-down.svg +0 -20
  162. package/src/components/icon/utils/svgs/sort-up.svg +0 -20
  163. package/src/components/icon/utils/svgs/sort.svg +0 -7
  164. package/src/components/icon/utils/svgs/square-solid.svg +0 -3
  165. package/src/components/icon/utils/svgs/star-solid.svg +0 -15
  166. package/src/components/icon/utils/svgs/star.svg +0 -15
  167. package/src/components/icon/utils/svgs/stop-watch.svg +0 -5
  168. package/src/components/icon/utils/svgs/structure.svg +0 -3
  169. package/src/components/icon/utils/svgs/sun.svg +0 -23
  170. package/src/components/icon/utils/svgs/table.svg +0 -3
  171. package/src/components/icon/utils/svgs/tag.svg +0 -15
  172. package/src/components/icon/utils/svgs/team.svg +0 -15
  173. package/src/components/icon/utils/svgs/telescope.svg +0 -15
  174. package/src/components/icon/utils/svgs/trash.svg +0 -6
  175. package/src/components/icon/utils/svgs/triangle-angle.svg +0 -3
  176. package/src/components/icon/utils/svgs/triangle-side.svg +0 -3
  177. package/src/components/icon/utils/svgs/underline.svg +0 -4
  178. package/src/components/icon/utils/svgs/undo.svg +0 -3
  179. package/src/components/icon/utils/svgs/user.svg +0 -16
  180. package/src/components/icon/utils/svgs/venn.svg +0 -3
  181. package/src/components/icon/utils/svgs/video.svg +0 -3
  182. package/src/components/icon/utils/svgs/visibility-off-alt.svg +0 -19
  183. package/src/components/icon/utils/svgs/visibility-off.svg +0 -3
  184. package/src/components/icon/utils/svgs/visibility-on.svg +0 -16
  185. package/src/components/icon/utils/svgs/warning.svg +0 -5
  186. package/src/components/index.ts +0 -38
  187. package/src/components/input/Input.vue +0 -87
  188. package/src/components/input/index.ts +0 -1
  189. package/src/components/load-spinner/LoadSpinner.vue +0 -13
  190. package/src/components/load-spinner/index.ts +0 -1
  191. package/src/components/modal/Modal.vue +0 -111
  192. package/src/components/modal/index.ts +0 -1
  193. package/src/components/nav-item/NavItem.vue +0 -62
  194. package/src/components/nav-item/index.ts +0 -1
  195. package/src/components/notification/Notification.vue +0 -34
  196. package/src/components/notification/index.ts +0 -1
  197. package/src/components/pagination/Pagination.vue +0 -72
  198. package/src/components/pagination/index.ts +0 -1
  199. package/src/components/pill/Pill.vue +0 -52
  200. package/src/components/pill/index.ts +0 -2
  201. package/src/components/pill/pill-types.ts +0 -2
  202. package/src/components/pop-confirm/PopConfirm.vue +0 -69
  203. package/src/components/pop-confirm/index.ts +0 -1
  204. package/src/components/pop-select/FooterButton.vue +0 -5
  205. package/src/components/pop-select/PopSelect.vue +0 -346
  206. package/src/components/pop-select/ResultFilters.vue +0 -31
  207. package/src/components/pop-select/enums.ts +0 -7
  208. package/src/components/pop-select/index.ts +0 -2
  209. package/src/components/pop-select/option.vue +0 -51
  210. package/src/components/popper/Popper.vue +0 -239
  211. package/src/components/popper/PopperContent.vue +0 -5
  212. package/src/components/popper/index.ts +0 -2
  213. package/src/components/popper/middleware.ts +0 -19
  214. package/src/components/screen-overlay/ScreenOverlay.vue +0 -53
  215. package/src/components/screen-overlay/index.ts +0 -1
  216. package/src/components/scrollbar/Bar.vue +0 -106
  217. package/src/components/scrollbar/ScrollBottomLoader.vue +0 -25
  218. package/src/components/scrollbar/Scrollbar.vue +0 -220
  219. package/src/components/scrollbar/enums.ts +0 -23
  220. package/src/components/scrollbar/index.ts +0 -2
  221. package/src/components/scrollbar/scrollbarWidth.ts +0 -26
  222. package/src/components/scrollbar/style.scss +0 -75
  223. package/src/components/scrollbar/types.ts +0 -32
  224. package/src/components/side-over/SideOver.vue +0 -87
  225. package/src/components/side-over/index.ts +0 -1
  226. package/src/components/status-select/StatusIndicator.vue +0 -78
  227. package/src/components/status-select/StatusSelect.vue +0 -62
  228. package/src/components/status-select/index.ts +0 -1
  229. package/src/components/switch/Switch.vue +0 -52
  230. package/src/components/switch/index.ts +0 -1
  231. package/src/components/tab/Tab.vue +0 -59
  232. package/src/components/tab/index.ts +0 -1
  233. package/src/components/tag/Tag.vue +0 -34
  234. package/src/components/tag/index.ts +0 -1
  235. package/src/components/text-editor/TextEditor.vue +0 -399
  236. package/src/components/text-editor/components/Dialog.vue +0 -11
  237. package/src/components/text-editor/components/FormattingButton.vue +0 -46
  238. package/src/components/text-editor/components/InsertLinkDialog.vue +0 -81
  239. package/src/components/text-editor/components/InsertTextDialog.vue +0 -36
  240. package/src/components/text-editor/components/index.ts +0 -3
  241. package/src/components/text-editor/index.ts +0 -1
  242. package/src/components/text-highlight/TextHighlight.vue +0 -113
  243. package/src/components/text-highlight/index.ts +0 -1
  244. package/src/components/text-viewer/TextViewer.vue +0 -5
  245. package/src/components/text-viewer/index.ts +0 -1
  246. package/src/components/tooltip/Tooltip.vue +0 -54
  247. package/src/components/tooltip/index.ts +0 -1
  248. package/src/components/types.ts +0 -221
  249. package/src/components/vertical-layout/RunningSection.vue +0 -54
  250. package/src/components/vertical-layout/VerticalLayout.vue +0 -37
  251. package/src/components/vertical-layout/index.ts +0 -3
  252. package/src/components/vertical-layout/types.ts +0 -2
  253. package/src/components/window-frame/WindowFrame.vue +0 -20
  254. package/src/components/window-frame/index.ts +0 -1
  255. package/src/composables/index.ts +0 -5
  256. package/src/composables/useClickOutside.ts +0 -48
  257. package/src/composables/useEscapeKey.ts +0 -12
  258. package/src/composables/useMounted.ts +0 -7
  259. package/src/composables/useNextFrame.ts +0 -10
  260. package/src/composables/useTrapFocus.ts +0 -61
  261. package/src/index.ts +0 -5
  262. package/src/main.css +0 -116
  263. package/src/utils/array.ts +0 -11
  264. package/src/utils/clamp.ts +0 -1
  265. package/src/utils/debounce.ts +0 -8
  266. package/src/utils/index.ts +0 -5
  267. package/src/utils/scrollIntoView.ts +0 -25
  268. package/src/utils/scrollbarWidth.ts +0 -27
  269. package/tsconfig.app.json +0 -4
  270. package/tsconfig.json +0 -11
  271. package/tsconfig.node.json +0 -21
  272. package/vite.config.ts +0 -27
@@ -1,72 +0,0 @@
1
- <script setup lang="ts">
2
- import type { TPopSelectOption } from "../types";
3
- import { computed } from "vue";
4
- import { BIcon, BPopSelect, BTooltip } from "../";
5
- import { range } from "../../utils";
6
-
7
- const props = withDefaults(
8
- defineProps<{
9
- noBorders?: boolean;
10
- currentPage: number;
11
- lastPage: number;
12
- }>(),
13
- {
14
- noBorders: false,
15
- },
16
- );
17
-
18
- const emit = defineEmits(["change"]);
19
-
20
- const pageOptions = computed((): TPopSelectOption[] => {
21
- return range(0, props.lastPage).map((num: number) => ({ label: `${num + 1}` }));
22
- });
23
-
24
- const shared
25
- = "relative inline-flex items-center h-8 bg-primary text-sm text-primary hover:bg-sand-grey-15 focus:z-10 focus:outline-hidden focus-visible:bg-sand-grey-40 active:scale-[0.98]";
26
-
27
- const arrowClasses = computed(() => {
28
- return props.noBorders
29
- ? `${shared} px-2 rounded-lg border border-transparent focus-visible:border-true-blue`
30
- : `${shared} px-2 border border-default focus-visible:border-true-blue`;
31
- });
32
- const triggerClasses = computed(() => {
33
- return props.noBorders ? `${shared} px-3 rounded-lg` : `${shared} -ml-px px-3 border border-default focus-visible:border-true-blue`;
34
- });
35
-
36
- const onChange = (direction: -1 | 1) => {
37
- let targetPage = props.currentPage + direction;
38
- if (targetPage > props.lastPage) targetPage = 1;
39
- if (targetPage < 1) targetPage = props.lastPage;
40
- emit("change", targetPage);
41
- };
42
-
43
- const onPageSelect = (pageOption: TPopSelectOption) => {
44
- emit("change", pageOption.label);
45
- };
46
- </script>
47
-
48
- <template>
49
- <nav class="relative z-0 inline-flex">
50
- <BTooltip text="Previous page" :delay="500">
51
- <button rel="prev" aria-label="previous page" class="rounded-l-lg" :class="[arrowClasses]" @click="onChange(-1)">
52
- <BIcon name="chevron-left" />
53
- </button>
54
- </BTooltip>
55
- <BPopSelect same-width-as-trigger :value="currentPage" :options="pageOptions" @select="onPageSelect">
56
- <template #trigger>
57
- <BTooltip text="current / total" :delay="500">
58
- <button :class="triggerClasses">
59
- <span class="">{{ currentPage }}</span>
60
- <span class="px-2">/</span>
61
- <span class="">{{ lastPage }}</span>
62
- </button>
63
- </BTooltip>
64
- </template>
65
- </BPopSelect>
66
- <BTooltip text="Next page" :delay="500">
67
- <button rel="next" aria-label="next page" class="-ml-px rounded-r-lg" :class="[arrowClasses]" @click="onChange(1)">
68
- <BIcon name="chevron-right" />
69
- </button>
70
- </BTooltip>
71
- </nav>
72
- </template>
@@ -1 +0,0 @@
1
- export { default as BPagination } from "./Pagination.vue";
@@ -1,52 +0,0 @@
1
- <script setup lang="ts">
2
- import { BIcon } from "../";
3
-
4
- const props = withDefaults(
5
- defineProps<{
6
- deletable?: boolean;
7
- selected?: boolean;
8
- stopPropagation?: boolean;
9
- }>(),
10
- {
11
- deletable: false,
12
- selected: false,
13
- stopPropagation: false,
14
- },
15
- );
16
-
17
- const emit = defineEmits(["click", "delete"]);
18
-
19
- const onClick = (event: Event) => {
20
- if (props.stopPropagation) {
21
- event.stopPropagation();
22
- event.preventDefault();
23
- }
24
- emit("click");
25
- };
26
-
27
- // TODO key.enter event stopPropagation
28
- </script>
29
-
30
- <template>
31
- <button
32
- class="h-7 px-2 inline-flex items-center space-x-1 rounded-lg focus:outline-hidden border border-transparent focus-visible:border-true-blue"
33
- :class="{
34
- 'bg-light-blue text-white hover:bg-light-blue-darker': selected,
35
- 'bg-light-blue-40 text-light-blue hover:bg-light-blue-15 hover:text-light-blue-darker': !selected,
36
- }"
37
- @click="onClick"
38
- >
39
- <span class="truncate"><slot /></span>
40
- <button
41
- v-if="deletable"
42
- class="w-4 h-4 flex items-center justify-center rounded-md focus:outline-hidden border border-transparent focus-visible:border-true-blue opacity-75 hover:opacity-100"
43
- :class="{
44
- 'hover:bg-black/20 hover:bg-opacity-20': selected,
45
- 'hover:bg-light-blue hover:text-light-blue-15': !selected,
46
- }"
47
- @click.stop.prevent="emit('delete')"
48
- >
49
- <BIcon name="close" />
50
- </button>
51
- </button>
52
- </template>
@@ -1,2 +0,0 @@
1
- export * from "./pill-types";
2
- export { default as BPill } from "./Pill.vue";
@@ -1,2 +0,0 @@
1
- export const LogicOperator = ["=", "!=", "<=", ">="] as const;
2
- export type TLogicOperator = (typeof LogicOperator)[number];
@@ -1,69 +0,0 @@
1
- <script setup lang="ts">
2
- import type { Placement } from "@floating-ui/dom";
3
- import type { TButtonType } from "../types";
4
- import { nextTick, ref } from "vue";
5
- import { BButton, BPopper, BPopperContent } from "../";
6
- import { useTrapFocus } from "../../";
7
-
8
- withDefaults(
9
- defineProps<{
10
- cancelLabel?: string;
11
- cancelType?: TButtonType;
12
- confirmLabel?: string;
13
- confirmType?: TButtonType;
14
- disabled?: boolean;
15
- placement?: Placement;
16
- tagName?: string;
17
- }>(),
18
- {
19
- cancelLabel: "Cancel",
20
- cancelType: "primary",
21
- confirmLabel: "Confirm",
22
- confirmType: "error",
23
- disabled: false,
24
- placement: "bottom",
25
- tagName: "span",
26
- },
27
- );
28
-
29
- const emit = defineEmits(["cancel", "close", "confirm"]);
30
-
31
- const popperRef = ref<typeof BPopper>();
32
- const contentRef = ref<HTMLDivElement>();
33
- const { trapFocus } = useTrapFocus(contentRef);
34
-
35
- const close = () => {
36
- emit("close");
37
- popperRef.value && popperRef.value.close();
38
- };
39
-
40
- const onOpen = () => nextTick(trapFocus);
41
-
42
- const onCancel = () => {
43
- close();
44
- emit("cancel");
45
- };
46
-
47
- const onConfirm = () => {
48
- close();
49
- emit("confirm");
50
- };
51
- </script>
52
-
53
- <template>
54
- <BPopper ref="popperRef" trigger="click" :placement="placement" @open="onOpen" @close="close">
55
- <template #default="slotProps">
56
- <div class="inline-flex">
57
- <slot name="reference" :visible="slotProps && slotProps.visible" />
58
- </div>
59
- </template>
60
- <template #content>
61
- <BPopperContent>
62
- <div ref="contentRef" class="flex flex-col px-2 py-2 space-y-2">
63
- <BButton bordered :type="cancelType" :label="cancelLabel" @click="onCancel" />
64
- <BButton bordered :label="confirmLabel" :type="confirmType" @click="onConfirm" />
65
- </div>
66
- </BPopperContent>
67
- </template>
68
- </BPopper>
69
- </template>
@@ -1 +0,0 @@
1
- export { default as BPopConfirm } from "./PopConfirm.vue";
@@ -1,5 +0,0 @@
1
- <script setup lang="ts"></script>
2
-
3
- <template>
4
- To be implemented
5
- </template>
@@ -1,346 +0,0 @@
1
- <script setup lang="ts" generic="T extends TPopSelectOption">
2
- import type { Placement } from "@floating-ui/dom";
3
- import type { TIcon, TPopSelectOption, TPopSelectResultFilter } from "../types";
4
- import { computed, nextTick, onBeforeMount, ref, useSlots, watch, withDefaults } from "vue";
5
- import { BIcon, BLoadSpinner, BPopper, BPopperContent, BScrollbar, BTextHighlight } from "../";
6
- import { useNextFrame } from "../../composables";
7
- import { debounce, scrollIntoView } from "../../utils";
8
- import { State } from "./enums.ts";
9
- import PopSelectOption from "./option.vue";
10
- import ResultFilters from "./ResultFilters.vue";
11
-
12
- const props = withDefaults(
13
- defineProps<{
14
- resetOnClose?: boolean;
15
- debounceMs?: number;
16
- disabled?: boolean;
17
- emptyStateIcon?: TIcon;
18
- emptyStateText?: string;
19
- filterable?: boolean;
20
- fixedHeight?: boolean;
21
- keepOpen?: boolean;
22
- loading?: boolean;
23
- loadingText?: string;
24
- options: T[];
25
- placeholder?: string;
26
- placement?: Placement;
27
- popperWidthClass?: string;
28
- // eslint-disable-next-line ts/no-unsafe-function-type
29
- remoteMethod?: Function | null;
30
- resultFilters?: TPopSelectResultFilter<T>[];
31
- rootClass?: string;
32
- sameWidthAsElement?: HTMLElement;
33
- sameWidthAsTrigger?: boolean;
34
- selected?: TPopSelectOption | TPopSelectOption[];
35
- triggerClass?: string;
36
- }>(),
37
- {
38
- resetOnClose: false,
39
- debounceMs: 300,
40
- disabled: false,
41
- emptyStateIcon: "keyboard",
42
- emptyStateText: "Type to search",
43
- filterable: false,
44
- fixedHeight: false,
45
- keepOpen: false,
46
- loading: false,
47
- loadingText: "Loading...",
48
- placeholder: "Search",
49
- placement: "bottom-start",
50
- remoteMethod: null,
51
- sameWidthAsTrigger: false,
52
- },
53
- );
54
- const emit = defineEmits(["close", "save-custom", "select"]);
55
- const slots = useSlots() as ReturnType<typeof useSlots>;
56
-
57
- const hoveredOption = ref<TPopSelectOption | null>(null);
58
- const localOptions = ref<TPopSelectOption[]>([]);
59
- const currentQuery = ref("");
60
-
61
- const contentRef = ref<typeof BPopperContent>();
62
- const errorRef = ref<HTMLElement>();
63
- const inputRef = ref<HTMLInputElement>();
64
- const optionsRef = ref();
65
- const popperRef = ref<typeof BPopper>();
66
- const scrollbarRef = ref<typeof BScrollbar>();
67
-
68
- const localResultFilters = ref<TPopSelectResultFilter<T>[]>(props.resultFilters || []);
69
- const selectedResultFilter = ref<TPopSelectResultFilter<T> | null>(props.resultFilters ? props.resultFilters[0] : null);
70
-
71
- const { nextFrame } = useNextFrame();
72
-
73
- const selectedOptions = computed(() => {
74
- if (!props.selected) return [];
75
- return Array.isArray(props.selected) ? props.selected : [props.selected];
76
- });
77
-
78
- const allOptionsDisabled = computed(() => {
79
- return localOptions.value.every((option: TPopSelectOption) => option.disabled as boolean);
80
- });
81
-
82
- const emptyState = computed(() => {
83
- return !currentQuery.value.length && !localOptions.value.length;
84
- });
85
-
86
- const noSearchResults = computed(() => {
87
- return currentQuery.value.length && !localOptions.value.length;
88
- });
89
-
90
- const state = computed(() => {
91
- if (errorRef.value) return State.ERROR;
92
- if (props.loading) return State.LOADING;
93
- if (noSearchResults.value && !props.loading) return State.NO_MATCH;
94
- if (emptyState.value && !props.loading) return State.IDLE;
95
- if (localOptions.value.length && !props.loading) return State.MATCH;
96
- return undefined;
97
- });
98
-
99
- const updateLocalOptions = (options: T[]) => {
100
- localOptions.value = selectedResultFilter.value ? options.filter(selectedResultFilter.value.execute) : options;
101
-
102
- // update counts
103
- if (props.resultFilters) {
104
- localResultFilters.value.forEach((filter) => {
105
- filter.count = options.filter(filter.execute).length;
106
- });
107
- }
108
- };
109
-
110
- watch(
111
- () => props.options,
112
- (newValue: T[]) => {
113
- updateLocalOptions(newValue);
114
- hoveredOption.value = null;
115
- },
116
- );
117
-
118
- onBeforeMount(() => {
119
- if (props.filterable && props.remoteMethod) {
120
- console.warn("[PopSelect] should not have both \"filterable\" and \"remoteMethod\" props at the same time");
121
- }
122
- updateLocalOptions(props.options);
123
- });
124
-
125
- // triggers onClose event when popper is closed
126
- const close = () => popperRef.value!.close();
127
- const focus = () => popperRef.value!.open();
128
-
129
- const onOpen = async () => {
130
- nextFrame(() => {
131
- if (scrollbarRef.value) {
132
- nextFrame(() => scrollbarRef.value!.update());
133
- }
134
- if (inputRef.value) {
135
- nextFrame(() => inputRef.value!.focus());
136
- }
137
- });
138
- };
139
-
140
- const onClose = () => {
141
- if (props.keepOpen) return;
142
-
143
- hoveredOption.value = null;
144
-
145
- if (props.resetOnClose) {
146
- currentQuery.value = "";
147
- props.remoteMethod ? props.remoteMethod("") : updateLocalOptions([]);
148
- selectedResultFilter.value = props.resultFilters ? props.resultFilters[0] : null;
149
- }
150
-
151
- emit("close");
152
- };
153
-
154
- const onSelect = (option: TPopSelectOption) => {
155
- emit("select", option);
156
- if (!props.keepOpen) close();
157
- };
158
-
159
- const filterOptions = (query: string) => (localOptions.value = props.options.filter(o => o.label.toLowerCase().includes(query.toLowerCase())));
160
-
161
- const onQuery = async (event: Event) => {
162
- const query = (event.target as HTMLInputElement).value;
163
-
164
- hoveredOption.value = null;
165
-
166
- if (props.filterable) {
167
- filterOptions(query);
168
- }
169
- else if (props.remoteMethod) {
170
- await props.remoteMethod(query);
171
- }
172
- };
173
-
174
- const debounceOnQuery = debounce(onQuery, props.debounceMs);
175
-
176
- const onOptionHover = (label: string) => {
177
- hoveredOption.value = localOptions.value.find(o => o.label === label) || null;
178
- };
179
-
180
- const scrollToOption = (option: TPopSelectOption) => {
181
- if (!optionsRef.value.length) return;
182
-
183
- const target = optionsRef.value[localOptions.value.findIndex(o => o.label === option.label)].$el;
184
-
185
- if (scrollbarRef.value && target) {
186
- const menu: HTMLElement | null = scrollbarRef.value.$el.querySelector(".scrollbar__wrap");
187
- if (menu) {
188
- scrollIntoView(menu, target);
189
- scrollbarRef.value.handleScroll();
190
- }
191
- }
192
- };
193
-
194
- const navigateOptions = async (direction: "next" | "prev") => {
195
- if (localOptions.value.length === 0) return;
196
-
197
- let hoverIndex = localOptions.value.findIndex(o => o.label === hoveredOption.value?.label);
198
-
199
- if (!allOptionsDisabled.value) {
200
- if (direction === "next") {
201
- hoverIndex++;
202
- if (hoverIndex === localOptions.value.length) {
203
- hoverIndex = 0;
204
- }
205
- }
206
- else if (direction === "prev") {
207
- hoverIndex--;
208
- if (hoverIndex < 0) {
209
- hoverIndex = localOptions.value.length - 1;
210
- }
211
- }
212
- hoveredOption.value = localOptions.value[hoverIndex];
213
-
214
- if (hoveredOption.value.disabled === true) {
215
- navigateOptions(direction);
216
- }
217
-
218
- await nextTick();
219
-
220
- if (hoveredOption.value) {
221
- scrollToOption(hoveredOption.value);
222
- }
223
- }
224
- };
225
-
226
- const selectOption = () => {
227
- if (hoveredOption.value) {
228
- onSelect(hoveredOption.value);
229
- }
230
- else if (currentQuery.value.length) {
231
- emit("save-custom", currentQuery.value);
232
- }
233
- };
234
-
235
- const onResultFilterChange = (filter: TPopSelectResultFilter<T>) => {
236
- selectedResultFilter.value = filter;
237
- updateLocalOptions(props.options);
238
- inputRef.value!.focus();
239
- };
240
-
241
- defineExpose({ close, focus });
242
- </script>
243
-
244
- <template>
245
- <BPopper
246
- ref="popperRef"
247
- trigger="click"
248
- :placement="placement"
249
- :disabled="disabled"
250
- :popper-width-class="popperWidthClass"
251
- :same-width-as-element="sameWidthAsElement"
252
- :same-width-as-trigger="sameWidthAsTrigger"
253
- :root-class="rootClass"
254
- :trigger-class="triggerClass"
255
- @close="onClose"
256
- @open="onOpen"
257
- >
258
- <template #default="slotProps">
259
- <slot name="trigger" :disabled="disabled" :visible="slotProps && slotProps.visible" />
260
- </template>
261
-
262
- <template #content>
263
- <BPopperContent ref="contentRef" class="flex flex-col" :class="{ 'h-72': fixedHeight }">
264
- <header v-if="filterable || remoteMethod || resultFilters" class="border-b border-default">
265
- <header v-if="filterable || remoteMethod" class="flex items-center w-full px-3 space-x-2 bg-light overflow-hidden">
266
- <BIcon name="magnifying-glass" class="text-light-blue" />
267
- <input
268
- ref="inputRef"
269
- v-model="currentQuery"
270
- type="text"
271
- class="w-full h-8 text-sm leading-none bg-light rounded-tr-lg focus:outline-hidden"
272
- :placeholder="placeholder"
273
- @click.stop.prevent
274
- @input="debounceOnQuery"
275
- @keydown.down.prevent="navigateOptions('next')"
276
- @keydown.up.prevent="navigateOptions('prev')"
277
- @keydown.enter.prevent="selectOption"
278
- @keydown.esc.stop.prevent="onClose"
279
- >
280
- </header>
281
- <ResultFilters
282
- v-if="resultFilters"
283
- show-counts
284
- :filters="localResultFilters"
285
- :selected="selectedResultFilter"
286
- @change="onResultFilterChange"
287
- />
288
- </header>
289
-
290
- <div v-if="$slots.error" ref="errorRef" class="flex-1 bg-light h-full">
291
- <slot name="error" />
292
- </div>
293
- <div v-else-if="state === State.LOADING" class="flex-1">
294
- <div class="flex items-center space-x-2 bg-light text-tertiary py-3 px-3">
295
- <BLoadSpinner class="w-4 h-4 text-granite-grey" />
296
- <span class="italic leading-none text-sm">{{ loadingText }}</span>
297
- </div>
298
- </div>
299
- <div v-else-if="state === State.NO_MATCH" class="flex-1">
300
- <div class="flex space-x-2 bg-light text-tertiary py-3 px-3">
301
- <div class="w-4 h-4 text-center leading-none">
302
- ...
303
- </div>
304
- <span class="italic leading-none text-sm">Nothing matches your input</span>
305
- </div>
306
- </div>
307
- <div v-else-if="state === State.IDLE" class="flex-1">
308
- <div class="flex items-center space-x-2 bg-light text-tertiary py-3 px-3">
309
- <BIcon :name="emptyStateIcon" />
310
- <span class="italic leading-none text-sm">{{ emptyStateText }}</span>
311
- </div>
312
- <div class="h-8 w-full bg-light" />
313
- </div>
314
-
315
- <BScrollbar v-else-if="state === State.MATCH" ref="scrollbarRef">
316
- <div class="max-h-60 bg-light">
317
- <PopSelectOption
318
- v-for="option in localOptions"
319
- ref="optionsRef"
320
- :key="option.id || option.label"
321
- :disabled="option.disabled"
322
- :label="option.label"
323
- :hovered-option="hoveredOption"
324
- :selected="selectedOptions.includes(option)"
325
- @focus="onOptionHover"
326
- @hover="onOptionHover"
327
- @click="onSelect(option)"
328
- >
329
- <div class="flex items-center space-x-2">
330
- <BIcon v-if="option.icon" :name="option.icon" />
331
- <BTextHighlight bold underline :value="option.label" :highlight="currentQuery" />
332
- </div>
333
- <div v-if="option.meta" class="text-secondary">
334
- {{ option.meta }}
335
- </div>
336
- </PopSelectOption>
337
- </div>
338
- </BScrollbar>
339
-
340
- <footer v-if="slots.footer" class="flex-none border-t border-default bg-light">
341
- <slot name="footer" />
342
- </footer>
343
- </BPopperContent>
344
- </template>
345
- </BPopper>
346
- </template>
@@ -1,31 +0,0 @@
1
- <script setup lang="ts" generic="T extends TPopSelectOption">
2
- import type { TPopSelectOption, TPopSelectResultFilter } from "../types";
3
- import { BPill } from "../";
4
-
5
- withDefaults(defineProps<{
6
- selected: TPopSelectResultFilter<T> | null;
7
- showCounts?: boolean;
8
- filters: TPopSelectResultFilter<T>[];
9
- }>(), {
10
- showCounts: false,
11
- });
12
-
13
- const emit = defineEmits(["change"]);
14
- </script>
15
-
16
- <template>
17
- <section class="flex items-center px-2 pb-2 space-x-2">
18
- <BPill
19
- v-for="filter in filters"
20
- :key="filter.name"
21
- :selected="Boolean(selected && selected.name === filter.name)"
22
- stop-propagation
23
- @click="emit('change', filter)"
24
- >
25
- <span class="flex items-center space-x-1">
26
- <span>{{ filter.name }}</span>
27
- <span v-if="showCounts && filter.count" class="text-xs opacity-75">{{ `(${filter.count})` }}</span>
28
- </span>
29
- </BPill>
30
- </section>
31
- </template>
@@ -1,7 +0,0 @@
1
- export enum State {
2
- ERROR = "error",
3
- IDLE = "idle",
4
- LOADING = "loading",
5
- MATCH = "match",
6
- NO_MATCH = "no match",
7
- }
@@ -1,2 +0,0 @@
1
- export { default as BPopSelectFooterButton } from "./FooterButton.vue";
2
- export { default as BPopSelect } from "./PopSelect.vue";
@@ -1,51 +0,0 @@
1
- <script setup lang="ts">
2
- import type { TPopSelectOption } from "../types";
3
- import { computed, ref } from "vue";
4
-
5
- const props = withDefaults(
6
- defineProps<{
7
- label: string;
8
- disabled?: boolean;
9
- hoveredOption: TPopSelectOption | null;
10
- selected?: boolean;
11
- }>(),
12
- {
13
- disabled: false,
14
- selected: false,
15
- },
16
- );
17
-
18
- const emit = defineEmits(["click", "focus", "hover"]);
19
-
20
- const root = ref();
21
-
22
- const highlighted = computed(() => {
23
- return props.hoveredOption && props.hoveredOption.label === props.label;
24
- });
25
-
26
- const onOptionClick = () => {
27
- if (props.disabled) return;
28
- emit("click");
29
- };
30
- </script>
31
-
32
- <template>
33
- <div
34
- ref="root"
35
- tabindex="0"
36
- class="flex items-center justify-between w-full h-8 px-3 space-x-2 text-sm focus:outline-hidden"
37
- :class="{
38
- 'cursor-not-allowed text-muted ': disabled,
39
- 'cursor-pointer text-primary hover:bg-blue-100 focus:bg-blue-100': !disabled && !selected,
40
- 'cursor-pointer text-light-blue font-medium hover:bg-blue-100 focus:bg-blue-100': selected,
41
- 'bg-blue-100': highlighted,
42
- 'bg-light': !highlighted,
43
- }"
44
- @click="onOptionClick"
45
- @keydown.enter.prevent="onOptionClick"
46
- @mouseover="emit('hover', label)"
47
- @focus="emit('focus', label)"
48
- >
49
- <slot />
50
- </div>
51
- </template>