@ulu/frontend-vue 0.2.0-beta.8 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (174) hide show
  1. package/dist/components/collapsible/UluAccordionGroup.vue.d.ts +2 -2
  2. package/dist/components/collapsible/UluAccordionGroup.vue.d.ts.map +1 -1
  3. package/dist/components/collapsible/UluAccordionGroup.vue.js +22 -19
  4. package/dist/components/collapsible/UluDropdown.vue.d.ts +1 -1
  5. package/dist/components/collapsible/UluDropdown.vue.d.ts.map +1 -1
  6. package/dist/components/collapsible/UluDropdown.vue.js +22 -15
  7. package/dist/components/collapsible/UluModal.vue.d.ts +43 -248
  8. package/dist/components/collapsible/UluModal.vue.d.ts.map +1 -1
  9. package/dist/components/collapsible/UluModal.vue.js +139 -191
  10. package/dist/components/collapsible/UluTabGroup.vue.d.ts +2 -0
  11. package/dist/components/collapsible/UluTabGroup.vue.d.ts.map +1 -1
  12. package/dist/components/collapsible/UluTabGroup.vue.js +23 -14
  13. package/dist/components/elements/UluAlert.vue.d.ts +29 -144
  14. package/dist/components/elements/UluAlert.vue.d.ts.map +1 -1
  15. package/dist/components/elements/UluAlert.vue.js +39 -50
  16. package/dist/components/elements/UluBadge.vue.d.ts +6 -6
  17. package/dist/components/elements/UluBadgeStack.vue.d.ts +1 -1
  18. package/dist/components/elements/UluBadgeStack.vue.d.ts.map +1 -1
  19. package/dist/components/elements/UluBadgeStack.vue.js +12 -9
  20. package/dist/components/elements/UluButton.vue.d.ts +47 -177
  21. package/dist/components/elements/UluButton.vue.d.ts.map +1 -1
  22. package/dist/components/elements/UluButton.vue.js +59 -72
  23. package/dist/components/elements/UluButtonVerbose.vue.d.ts +38 -123
  24. package/dist/components/elements/UluButtonVerbose.vue.d.ts.map +1 -1
  25. package/dist/components/elements/UluButtonVerbose.vue.js +52 -65
  26. package/dist/components/elements/UluCallout.vue.d.ts +20 -25
  27. package/dist/components/elements/UluCallout.vue.d.ts.map +1 -1
  28. package/dist/components/elements/UluCallout.vue.js +11 -16
  29. package/dist/components/elements/UluCaptionedFigure.vue.d.ts +25 -0
  30. package/dist/components/elements/UluCaptionedFigure.vue.d.ts.map +1 -0
  31. package/dist/components/elements/UluCaptionedFigure.vue.js +48 -0
  32. package/dist/components/elements/UluCard.vue.d.ts +2 -2
  33. package/dist/components/elements/UluDefinitionList.vue.d.ts +4 -2
  34. package/dist/components/elements/UluDefinitionList.vue.d.ts.map +1 -1
  35. package/dist/components/elements/UluDefinitionList.vue.js +32 -28
  36. package/dist/components/elements/UluExternalLink.vue.d.ts +2 -2
  37. package/dist/components/elements/UluImage.vue.d.ts +14 -0
  38. package/dist/components/elements/UluImage.vue.d.ts.map +1 -0
  39. package/dist/components/elements/UluImage.vue.js +53 -0
  40. package/dist/components/elements/UluList.vue.d.ts.map +1 -1
  41. package/dist/components/elements/UluList.vue.js +14 -13
  42. package/dist/components/elements/UluOverflowScroller.vue.d.ts +49 -0
  43. package/dist/components/elements/UluOverflowScroller.vue.d.ts.map +1 -0
  44. package/dist/components/elements/UluOverflowScroller.vue.js +138 -0
  45. package/dist/components/elements/UluScrollSlider.vue.d.ts +38 -0
  46. package/dist/components/elements/UluScrollSlider.vue.d.ts.map +1 -0
  47. package/dist/components/elements/UluScrollSlider.vue.js +146 -0
  48. package/dist/components/elements/UluSlider.vue.d.ts +57 -0
  49. package/dist/components/elements/UluSlider.vue.d.ts.map +1 -0
  50. package/dist/components/elements/UluSlider.vue.js +277 -0
  51. package/dist/components/forms/UluFormFile.vue.d.ts +2 -2
  52. package/dist/components/forms/UluFormRadio.vue.d.ts +4 -4
  53. package/dist/components/index.d.ts +6 -0
  54. package/dist/components/layout/UluTitleRail.vue.d.ts +29 -87
  55. package/dist/components/layout/UluTitleRail.vue.d.ts.map +1 -1
  56. package/dist/components/layout/UluTitleRail.vue.js +51 -46
  57. package/dist/components/navigation/UluBreadcrumb.vue.d.ts +27 -68
  58. package/dist/components/navigation/UluBreadcrumb.vue.d.ts.map +1 -1
  59. package/dist/components/navigation/UluBreadcrumb.vue.js +51 -54
  60. package/dist/components/navigation/UluMenu.vue.d.ts +30 -138
  61. package/dist/components/navigation/UluMenu.vue.d.ts.map +1 -1
  62. package/dist/components/navigation/UluMenu.vue.js +85 -84
  63. package/dist/components/navigation/UluMenuStack.vue.d.ts +12 -2
  64. package/dist/components/navigation/UluMenuStack.vue.d.ts.map +1 -1
  65. package/dist/components/navigation/UluMenuStack.vue.js +26 -18
  66. package/dist/components/navigation/UluNavStrip.vue.d.ts +22 -134
  67. package/dist/components/navigation/UluNavStrip.vue.d.ts.map +1 -1
  68. package/dist/components/navigation/UluNavStrip.vue.js +43 -31
  69. package/dist/components/systems/facets/UluFacetsSidebarLayout.vue.js +10 -10
  70. package/dist/components/systems/facets/useFacets.d.ts +3 -0
  71. package/dist/components/systems/facets/useFacets.d.ts.map +1 -1
  72. package/dist/components/systems/facets/useFacets.js +124 -112
  73. package/dist/components/systems/index.d.ts +0 -3
  74. package/dist/components/systems/scroll-anchors/UluScrollAnchors.vue.d.ts +2 -2
  75. package/dist/components/systems/table-sticky/UluTableSticky.vue.d.ts +504 -432
  76. package/dist/components/systems/table-sticky/UluTableSticky.vue.d.ts.map +1 -1
  77. package/dist/components/systems/table-sticky/UluTableSticky.vue.js +313 -456
  78. package/dist/components/systems/table-sticky/UluTableStickyRows.vue.d.ts +40 -31
  79. package/dist/components/systems/table-sticky/UluTableStickyRows.vue.d.ts.map +1 -1
  80. package/dist/components/systems/table-sticky/UluTableStickyRows.vue.js +43 -45
  81. package/dist/components/systems/table-sticky/UluTableStickyTable.vue.d.ts +60 -146
  82. package/dist/components/systems/table-sticky/UluTableStickyTable.vue.d.ts.map +1 -1
  83. package/dist/components/systems/table-sticky/UluTableStickyTable.vue.js +156 -175
  84. package/dist/components/utils/UluAction.vue.d.ts +36 -0
  85. package/dist/components/utils/UluAction.vue.d.ts.map +1 -0
  86. package/dist/components/utils/UluAction.vue.js +59 -0
  87. package/dist/components/utils/UluConditionalText.vue.d.ts +7 -26
  88. package/dist/components/utils/UluConditionalText.vue.d.ts.map +1 -1
  89. package/dist/components/utils/UluConditionalText.vue.js +12 -14
  90. package/dist/components/utils/UluConditionalWrapper.vue.d.ts.map +1 -1
  91. package/dist/components/utils/UluConditionalWrapper.vue.js +11 -9
  92. package/dist/components/utils/UluPlaceholderImage.vue.d.ts +12 -57
  93. package/dist/components/utils/UluPlaceholderImage.vue.d.ts.map +1 -1
  94. package/dist/components/utils/UluPlaceholderImage.vue.js +18 -26
  95. package/dist/components/utils/UluPlaceholderText.vue.d.ts +6 -20
  96. package/dist/components/utils/UluPlaceholderText.vue.js +12 -14
  97. package/dist/components/utils/UluRouteAnnouncer.vue.d.ts +9 -58
  98. package/dist/components/utils/UluRouteAnnouncer.vue.d.ts.map +1 -1
  99. package/dist/components/utils/UluRouteAnnouncer.vue.js +28 -28
  100. package/dist/components/visualizations/UluAnimateNumber.vue.d.ts +20 -14
  101. package/dist/components/visualizations/UluAnimateNumber.vue.d.ts.map +1 -1
  102. package/dist/components/visualizations/UluAnimateNumber.vue.js +18 -26
  103. package/dist/components/visualizations/UluProgressCircle.vue.d.ts +2 -2
  104. package/dist/composables/useModifiers.d.ts +20 -25
  105. package/dist/composables/useModifiers.d.ts.map +1 -1
  106. package/dist/index.js +206 -200
  107. package/dist/plugins/modals/UluModalsDisplay.vue.d.ts +3 -12
  108. package/dist/plugins/modals/UluModalsDisplay.vue.js +24 -45
  109. package/dist/plugins/modals/index.js +6 -6
  110. package/dist/plugins/toast/UluToast.vue.d.ts +24 -49
  111. package/dist/plugins/toast/UluToast.vue.d.ts.map +1 -1
  112. package/dist/plugins/toast/UluToast.vue.js +68 -77
  113. package/dist/plugins/toast/UluToastDisplay.vue.d.ts +1 -9
  114. package/dist/plugins/toast/UluToastDisplay.vue.js +27 -35
  115. package/dist/plugins/toast/defaults.d.ts +40 -35
  116. package/dist/plugins/toast/defaults.js +2 -2
  117. package/dist/plugins/toast/index.js +4 -4
  118. package/dist/plugins/toast/store.d.ts +40 -35
  119. package/dist/plugins/toast/store.d.ts.map +1 -1
  120. package/dist/utils/props.d.ts +7 -0
  121. package/dist/utils/props.d.ts.map +1 -0
  122. package/dist/utils/props.js +6 -0
  123. package/lib/components/collapsible/UluAccordionGroup.vue +4 -1
  124. package/lib/components/collapsible/UluDropdown.vue +5 -1
  125. package/lib/components/collapsible/UluModal.vue +278 -298
  126. package/lib/components/collapsible/UluTabGroup.vue +21 -6
  127. package/lib/components/elements/UluAlert.vue +38 -51
  128. package/lib/components/elements/UluBadgeStack.vue +4 -1
  129. package/lib/components/elements/UluButton.vue +105 -129
  130. package/lib/components/elements/UluButtonVerbose.vue +67 -89
  131. package/lib/components/elements/UluCallout.vue +15 -19
  132. package/lib/components/elements/UluCaptionedFigure.vue +40 -0
  133. package/lib/components/elements/UluDefinitionList.vue +27 -6
  134. package/lib/components/elements/UluImage.vue +56 -0
  135. package/lib/components/elements/UluList.vue +1 -0
  136. package/lib/components/elements/UluOverflowScroller.vue +140 -0
  137. package/lib/components/elements/UluScrollSlider.vue +150 -0
  138. package/lib/components/elements/UluSlider.vue +488 -0
  139. package/lib/components/index.js +10 -0
  140. package/lib/components/layout/UluTitleRail.vue +55 -48
  141. package/lib/components/navigation/UluBreadcrumb.vue +29 -34
  142. package/lib/components/navigation/UluMenu.vue +60 -71
  143. package/lib/components/navigation/UluMenuStack.vue +6 -1
  144. package/lib/components/navigation/UluNavStrip.vue +43 -31
  145. package/lib/components/systems/facets/useFacets.js +33 -17
  146. package/lib/components/systems/index.js +0 -4
  147. package/lib/components/systems/table-sticky/UluTableSticky.vue +602 -576
  148. package/lib/components/systems/table-sticky/UluTableStickyRows.vue +16 -27
  149. package/lib/components/systems/table-sticky/UluTableStickyTable.vue +95 -96
  150. package/lib/components/utils/UluAction.vue +81 -0
  151. package/lib/components/utils/UluConditionalText.vue +13 -16
  152. package/lib/components/utils/UluConditionalWrapper.vue +5 -1
  153. package/lib/components/utils/UluPlaceholderImage.vue +44 -46
  154. package/lib/components/utils/UluPlaceholderText.vue +10 -13
  155. package/lib/components/utils/UluRouteAnnouncer.vue +59 -47
  156. package/lib/components/visualizations/UluAnimateNumber.vue +23 -30
  157. package/lib/composables/useModifiers.js +21 -26
  158. package/lib/plugins/modals/UluModalsDisplay.vue +44 -45
  159. package/lib/plugins/toast/UluToast.vue +28 -34
  160. package/lib/plugins/toast/UluToastDisplay.vue +9 -15
  161. package/lib/utils/props.js +8 -0
  162. package/package.json +9 -5
  163. package/dist/components/systems/slider/UluImageSlideShow.vue.d.ts +0 -130
  164. package/dist/components/systems/slider/UluImageSlideShow.vue.d.ts.map +0 -1
  165. package/dist/components/systems/slider/UluImageSlideShow.vue.js +0 -73
  166. package/dist/components/systems/slider/UluSlideShow.vue.d.ts +0 -205
  167. package/dist/components/systems/slider/UluSlideShow.vue.d.ts.map +0 -1
  168. package/dist/components/systems/slider/UluSlideShow.vue.js +0 -292
  169. package/dist/components/systems/slider/UluSlideShowSlide.vue.d.ts +0 -17
  170. package/dist/components/systems/slider/UluSlideShowSlide.vue.d.ts.map +0 -1
  171. package/dist/components/systems/slider/UluSlideShowSlide.vue.js +0 -26
  172. package/lib/components/systems/slider/UluImageSlideShow.vue +0 -75
  173. package/lib/components/systems/slider/UluSlideShow.vue +0 -336
  174. package/lib/components/systems/slider/UluSlideShowSlide.vue +0 -25
@@ -34,45 +34,40 @@
34
34
  </nav>
35
35
  </template>
36
36
 
37
- <script>
37
+ <script setup>
38
38
  import UluIcon from '../elements/UluIcon.vue';
39
+
39
40
  /**
40
41
  * Breadcrumb trail component
41
42
  * - Is now agnostic of router, pass precomputed breadcrumb trail via items prop
42
43
  */
43
- export default {
44
- name: 'UluBreadcrumb',
45
- components: {
46
- UluIcon
44
+ const props = defineProps({
45
+ /**
46
+ * Array of breadcrumb items.
47
+ * Each item is an object: { title: String, to: [String, Object], current: Boolean }
48
+ */
49
+ items: {
50
+ type: Array,
51
+ default: () => []
47
52
  },
48
- props: {
49
- /**
50
- * Array of breadcrumb items.
51
- * Each item is an object: { title: String, to: [String, Object], current: Boolean }
52
- */
53
- items: {
54
- type: Array,
55
- default: () => []
56
- },
57
- /**
58
- * Icon to use as a separator.
59
- */
60
- separatorIcon: String,
61
- /**
62
- * Classes object to be applied to elements.
63
- * Keys: nav, list, item, link, icon
64
- */
65
- classes: {
66
- type: Object,
67
- default: () => ({
68
- nav: "breadcrumb",
69
- list: "breadcrumb__list",
70
- item: "breadcrumb__item",
71
- link: "breadcrumb__link",
72
- current: "breadcrumb__current",
73
- separator: "breadcrumb__separator"
74
- })
75
- }
53
+ /**
54
+ * Icon to use as a separator.
55
+ */
56
+ separatorIcon: String,
57
+ /**
58
+ * Classes object to be applied to elements.
59
+ * Keys: nav, list, item, link, icon
60
+ */
61
+ classes: {
62
+ type: Object,
63
+ default: () => ({
64
+ nav: "breadcrumb",
65
+ list: "breadcrumb__list",
66
+ item: "breadcrumb__item",
67
+ link: "breadcrumb__link",
68
+ current: "breadcrumb__current",
69
+ separator: "breadcrumb__separator"
70
+ })
76
71
  }
77
- }
72
+ });
78
73
  </script>
@@ -1,5 +1,8 @@
1
1
  <template>
2
- <ul v-if="items?.length" :class="classes.list">
2
+ <ul
3
+ v-if="items?.length"
4
+ :class="classes.list"
5
+ >
3
6
  <li
4
7
  v-for="(item, index) in items"
5
8
  :key="index"
@@ -10,20 +13,10 @@
10
13
  item.separatorAfter ? classes.itemSeparatorAfter : ''
11
14
  ]"
12
15
  >
13
- <!--
14
- Note: The ternary spread method below is conditionally adding certain
15
- props/handlers for each of the different element types.
16
- -->
17
- <component
18
- :is="item.to || item.path ? 'router-link' : item.click ? 'button' : 'a'"
19
- v-bind="{
20
- ...(item.to || item.path ? {
21
- to: item.to || item.path,
22
- activeClass: classes.linkActive || null,
23
- exactActiveClass: classes.linkExactActive || null
24
- } : {}),
25
- ...(item.href ? { 'href' : item.href || '#' } : {}),
26
- }"
16
+ <UluAction
17
+ v-bind="item"
18
+ :activeClass="classes.linkActive"
19
+ :exactActiveClass="classes.linkExactActive"
27
20
  @click="(event) => { handleItemClick(event, item) }"
28
21
  :class="[classes.link, item?.classes?.link]"
29
22
  :aria-label="iconOnly ? item.title : null"
@@ -39,74 +32,70 @@
39
32
  <span :class="[classes.linkText, item?.classes?.linkText]">{{ item.title }}</span>
40
33
  <UluTag v-if="item.tag" v-bind="item.tag"/>
41
34
  </slot>
42
- </component>
35
+ </UluAction>
36
+ <slot name="item" :item="item" :index="index" />
43
37
  <!-- Component calls itself recursively for children if allowed (noChildren) -->
44
38
  <UluMenu v-if="!noChildren && item?.children?.length"
45
39
  :iconOnly="iconOnly"
46
40
  :classes="classes"
47
41
  :items="item.children"
48
- />
42
+ >
43
+ <template v-for="(_, name) in $slots" #[name]="slotData">
44
+ <slot :name="name" v-bind="slotData" />
45
+ </template>
46
+ </UluMenu>
49
47
  </li>
50
48
  </ul>
51
49
  </template>
52
50
 
53
- <script>
51
+ <script setup>
52
+ import UluAction from "../utils/UluAction.vue";
54
53
  import UluIcon from "../elements/UluIcon.vue";
55
54
  import UluTag from "../elements/UluTag.vue";
56
- /**
57
- * Reusable menu component (ul > li > [a/button/router-link])
58
- * - Requires ulu tooltip plugin (as items themselves can have tooltips)
59
- */
60
- export default {
61
- name: "UluMenu",
62
- components: {
63
- UluIcon,
64
- UluTag
65
- },
66
- emits: [
67
- /**
68
- * Fired anytime a item is clicked
69
- */
70
- "item-click"
71
- ],
72
- props: {
73
- /**
74
- * Items Array of Objects for each link
75
- * [{
76
- * title: String (title of link)
77
- * icon: Icon definition passed to UluIcon
78
- * tag: Tag appearing after link text (count/etc), pass props you want bound to tag
79
- * tooltip: Add tooltip to menu item (pass options for tooltip), unless iconOnly than the title is presented in the tooltip
80
- * href: Will result in <a>
81
- * click: Will be called on click and result in <button>
82
- * to: Will result in <a> and use vue-router router-link component
83
- * }]
84
- */
85
- items: Array,
86
- /**
87
- * Classes object to add class bindings to the different elements
88
- * - { list, item, link, linkActive, linkExactActive, linkIcon, linkText }
89
- */
90
- classes: {
91
- type: Object,
92
- default: () => ({})
93
- },
94
- /**
95
- * Use icon only version of menu
96
- */
97
- iconOnly: Boolean,
98
- /**
99
- * Do not print menu items children recursively
100
- */
101
- noChildren: Boolean
55
+
56
+ const props = defineProps({
57
+ /**
58
+ * Items Array of Objects for each link
59
+ * [{
60
+ * title: String (title of link)
61
+ * icon: Icon definition passed to UluIcon
62
+ * tag: Tag appearing after link text (count/etc), pass props you want bound to tag
63
+ * tooltip: Add tooltip to menu item (pass options for tooltip), unless iconOnly than the title is presented in the tooltip
64
+ * href: Will result in <a>
65
+ * click: Will be called on click and result in <button>
66
+ * to: Will result in <a> and use vue-router router-link component
67
+ * }]
68
+ */
69
+ items: Array,
70
+ /**
71
+ * Classes object to add class bindings to the different elements
72
+ * - { list, item, link, linkActive, linkExactActive, linkIcon, linkText }
73
+ */
74
+ classes: {
75
+ type: Object,
76
+ default: () => ({})
102
77
  },
103
- methods: {
104
- handleItemClick(event, item) {
105
- if (item.click) {
106
- item.click(event);
107
- }
108
- this.$emit("item-click", { item, event });
109
- }
78
+ /**
79
+ * Use icon only version of menu
80
+ */
81
+ iconOnly: Boolean,
82
+ /**
83
+ * Do not print menu items children recursively
84
+ */
85
+ noChildren: Boolean
86
+ });
87
+
88
+ const emit = defineEmits([
89
+ /**
90
+ * Fired anytime a item is clicked
91
+ */
92
+ "item-click"
93
+ ]);
94
+
95
+ const handleItemClick = (event, item) => {
96
+ if (item.click) {
97
+ item.click(event);
110
98
  }
99
+ emit("item-click", { item, event });
111
100
  };
112
101
  </script>
@@ -1,5 +1,6 @@
1
1
  <template>
2
2
  <component
3
+ v-if="items?.length"
3
4
  class="menu-stack"
4
5
  :is="containerElement"
5
6
  :class="resolvedModifiers"
@@ -16,7 +17,11 @@
16
17
  itemSeparatorAfter: 'menu-stack__item--separator-after'
17
18
  }"
18
19
  :noChildren="noChildren"
19
- />
20
+ >
21
+ <template v-for="(_, name) in $slots" #[name]="slotData">
22
+ <slot :name="name" v-bind="slotData" />
23
+ </template>
24
+ </UluMenu>
20
25
  </component>
21
26
  </template>
22
27
 
@@ -1,11 +1,8 @@
1
1
  <template>
2
2
  <nav
3
+ v-if="items?.length"
3
4
  class="nav-strip"
4
- :class="{
5
- 'nav-strip--rule' : rule,
6
- 'nav-strip--center' : center,
7
- 'nav-strip--right' : right
8
- }"
5
+ :class="resolvedModifiers"
9
6
  >
10
7
  <UluMenu
11
8
  :items="items"
@@ -15,34 +12,49 @@
15
12
  link: 'nav-strip__link',
16
13
  linkExactActive: 'is-active'
17
14
  }"
18
- />
15
+ >
16
+ <template v-for="(_, name) in $slots" #[name]="slotData">
17
+ <slot :name="name" v-bind="slotData" />
18
+ </template>
19
+ </UluMenu>
19
20
  </nav>
20
21
  </template>
21
22
 
22
- <script>
23
+ <script setup>
24
+ import { computed } from "vue";
23
25
  import UluMenu from "./UluMenu.vue";
24
- export default {
25
- name: "UluNavStrip",
26
- components: {
27
- UluMenu
28
- },
29
- props: {
30
- /**
31
- * Array of items for list (uses UluMenu, see structure there)
32
- */
33
- items: Array,
34
- /**
35
- * Center aligned
36
- */
37
- center: Boolean,
38
- /**
39
- * Right aligned
40
- */
41
- right: Boolean,
42
- /**
43
- * Rule nav strip style
44
- */
45
- rule: Boolean
46
- },
47
- };
26
+ import { useModifiers } from "../../composables/useModifiers.js";
27
+
28
+ const props = defineProps({
29
+ /**
30
+ * Array of items for list (uses UluMenu, see structure there)
31
+ */
32
+ items: Array,
33
+ /**
34
+ * Center aligned
35
+ */
36
+ center: Boolean,
37
+ /**
38
+ * Right aligned
39
+ */
40
+ right: Boolean,
41
+ /**
42
+ * Rule nav strip style
43
+ */
44
+ rule: Boolean,
45
+ /**
46
+ * Modifiers (to add any modifier classes based on base class)
47
+ */
48
+ modifiers: [String, Array]
49
+ });
50
+
51
+ const { resolvedModifiers } = useModifiers({
52
+ props,
53
+ baseClass: "nav-strip",
54
+ internal: computed(() => ({
55
+ "center": props.center,
56
+ "right": props.right,
57
+ "rule": props.rule
58
+ }))
59
+ });
48
60
  </script>
@@ -1,5 +1,7 @@
1
- import { ref, computed, watch, nextTick, watchPostEffect } from 'vue';
2
- import Fuse from 'fuse.js';
1
+ import { ref, computed, watch, watchPostEffect } from "vue";
2
+ import Fuse from "fuse.js";
3
+
4
+ const isFunction = v => typeof v === "function";
3
5
 
4
6
  /**
5
7
  * Helper function to create a union of multiple Sets.
@@ -58,7 +60,7 @@ function getFilteredSetFromIndex(selected, index, allItemsSet) {
58
60
  });
59
61
 
60
62
  // For 'all' (AND), intersect the sets within the group.
61
- if (group.match === 'all') {
63
+ if (group.match === "all") {
62
64
  return intersectSets(childSets);
63
65
  }
64
66
  // For 'some' (OR), union the sets within the group.
@@ -125,19 +127,21 @@ function generateInitialFacets(allItems, facetFields) {
125
127
  * @param {Object} [options.urlSync] - Optional configuration to sync state with URL.
126
128
  * @param {import('vue-router').Router} [options.urlSync.router] - The Vue Router instance.
127
129
  * @param {import('vue-router').RouteLocationNormalizedLoaded} [options.urlSync.route] - The current route instance.
130
+ * @param {Function} [options.isPinned] - A function that receives an item and returns true if it should be pinned to the top of the results.
128
131
  */
129
132
  export function useFacets(allItems, options = {}) {
130
133
  const {
131
134
  initialFacets,
132
135
  facetFields,
133
- initialSearchValue = '',
134
- initialSortType = 'az',
136
+ initialSearchValue = "",
137
+ initialSortType = "az",
135
138
  noDefaultSorts = false,
136
139
  extraSortTypes = {},
137
140
  searchOptions: initialSearchOptions = {},
138
141
  getSortValue = item => (item.title || item.label || ""),
139
- countMode = 'none', // 'none', 'simple', 'intuitive'
140
- urlSync: urlSyncOptions
142
+ countMode = "none", // 'none', 'simple', 'intuitive'
143
+ urlSync: urlSyncOptions,
144
+ isPinned
141
145
  } = options;
142
146
 
143
147
  const sortAlpha = items => {
@@ -261,14 +265,22 @@ export function useFacets(allItems, options = {}) {
261
265
  return result;
262
266
  });
263
267
 
264
- const displayItems = computed(() => {
268
+ const displayItemsGrouped = computed(() => {
265
269
  const sortFn = sortTypes.value[selectedSort.value]?.sort;
266
- if (typeof sortFn !== 'function') {
267
- return filteredItems.value;
270
+ let sorted = isFunction(sortFn) ? sortFn([...filteredItems.value]) : [...filteredItems.value];
271
+
272
+ if (isFunction(isPinned)) {
273
+ const pinned = [];
274
+ const unpinned = [];
275
+ sorted.forEach(item => isPinned(item) ? pinned.push(item) : unpinned.push(item));
276
+ return { pinned, unpinned, all: [...pinned, ...unpinned] };
268
277
  }
269
- return sortFn([...filteredItems.value]);
278
+ return { pinned: [], unpinned: sorted, all: sorted };
270
279
  });
271
280
 
281
+ const displayItems = computed(() => displayItemsGrouped.value.all);
282
+ const pinnedItems = computed(() => displayItemsGrouped.value.pinned);
283
+
272
284
  // --- Methods ---
273
285
  function clearFilters() {
274
286
  facets.value.forEach(group => {
@@ -309,12 +321,12 @@ export function useFacets(allItems, options = {}) {
309
321
  }, { immediate: true });
310
322
 
311
323
  watch([selectedFacets, searchedItems], ([currentSelected, currentSearchedItems], [prevSelected, prevSearchedItems]) => {
312
- if (countMode === 'none' || !facets.value.length) return;
324
+ if (countMode === "none" || !facets.value.length) return;
313
325
 
314
326
  // A simple optimization to prevent re-calculating counts if the actual data hasn't changed.
315
327
  if (currentSelected === prevSelected && currentSearchedItems === prevSearchedItems) return;
316
328
 
317
- if (countMode === 'simple') {
329
+ if (countMode === "simple") {
318
330
  const index = facetIndex.value;
319
331
  if (index.size === 0 && searchedItems.value.length > 0 && facetFields?.length > 0) {
320
332
  return; // Index not ready
@@ -337,7 +349,7 @@ export function useFacets(allItems, options = {}) {
337
349
  child.count = intersection.size;
338
350
  });
339
351
  });
340
- } else if (countMode === 'intuitive') {
352
+ } else if (countMode === "intuitive") {
341
353
  const index = facetIndex.value;
342
354
  if (index.size === 0 && searchedItems.value.length > 0 && facetFields?.length > 0) {
343
355
  // Index might not be ready yet.
@@ -348,7 +360,7 @@ export function useFacets(allItems, options = {}) {
348
360
 
349
361
  facets.value.forEach(group => {
350
362
  group.children.forEach(child => {
351
- const key = `${group.uid}:${child.uid}`;
363
+ const key = `${ group.uid }:${ child.uid }`;
352
364
  const childSet = index.get(key) || new Set();
353
365
 
354
366
  if (child.selected) {
@@ -438,7 +450,7 @@ export function useFacets(allItems, options = {}) {
438
450
 
439
451
  const selectionsFromUrl = new Map();
440
452
  facets.value.forEach(group => {
441
- const selectedUids = query[group.uid] ? query[group.uid].split(',') : [];
453
+ const selectedUids = query[group.uid] ? query[group.uid].split(",") : [];
442
454
  selectionsFromUrl.set(group.uid, new Set(selectedUids));
443
455
  });
444
456
 
@@ -463,7 +475,10 @@ export function useFacets(allItems, options = {}) {
463
475
  });
464
476
 
465
477
  // Sync state changes TO the URL
466
- watch([selectedSort, searchValue, selectedFacets], updateUrlFromState, { deep: true });
478
+ watch(
479
+ [selectedSort, searchValue, selectedFacets], updateUrlFromState,
480
+ { deep: true }
481
+ );
467
482
 
468
483
  // Sync URL changes TO the state
469
484
  watch(() => route.query, updateStateFromUrl);
@@ -475,6 +490,7 @@ export function useFacets(allItems, options = {}) {
475
490
  selectedSort,
476
491
  sortTypes,
477
492
  displayItems,
493
+ pinnedItems,
478
494
  selectedFacets,
479
495
  clearFilters,
480
496
  handleFacetChange
@@ -25,10 +25,6 @@ export { default as UluSkeletonContent } from './skeleton/UluSkeletonContent.vue
25
25
  export { default as UluSkeletonMedia } from './skeleton/UluSkeletonMedia.vue';
26
26
  export { default as UluSkeletonText } from './skeleton/UluSkeletonText.vue';
27
27
 
28
- export { default as UluImageSlideShow } from './slider/UluImageSlideShow.vue';
29
- export { default as UluSlideShow } from './slider/UluSlideShow.vue';
30
- export { default as UluSlideShowSlide } from './slider/UluSlideShowSlide.vue';
31
-
32
28
  export { default as UluTableSticky } from './table-sticky/UluTableSticky.vue';
33
29
  export { default as UluTableStickyRows } from './table-sticky/UluTableStickyRows.vue';
34
30
  export { default as UluTableStickyTable } from './table-sticky/UluTableStickyTable.vue';