@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
@@ -1,5 +1,9 @@
1
1
  <template>
2
- <dl class="definition-list" :class="[resolvedModifiers, classes.list]">
2
+ <dl
3
+ v-if="items?.length"
4
+ class="definition-list"
5
+ :class="[resolvedModifiers, classes.list]"
6
+ >
3
7
  <div
4
8
  v-for="(item, index) in items"
5
9
  :key="index"
@@ -11,9 +15,19 @@
11
15
  </slot>
12
16
  </dt>
13
17
 
14
- <dd :class="classes.description">
15
- <slot name="description" :item="item" :index="index">
16
- {{ item.description }}
18
+ <dd
19
+ v-for="(desc, descIndex) in getDescriptions(item)"
20
+ :key="descIndex"
21
+ :class="classes.description"
22
+ >
23
+ <slot
24
+ name="description"
25
+ :item="item"
26
+ :description="desc"
27
+ :index="index"
28
+ :descriptionIndex="descIndex"
29
+ >
30
+ {{ desc }}
17
31
  </slot>
18
32
  </dd>
19
33
  </div>
@@ -26,7 +40,7 @@
26
40
 
27
41
  const props = defineProps({
28
42
  /**
29
- * Array of term, and description (props in object)
43
+ * Array of objects with term, and description (string or array of strings)
30
44
  * - Can use slots also
31
45
  */
32
46
  items: Array,
@@ -86,4 +100,11 @@
86
100
  internal: internalModifiers,
87
101
  baseClass: "definition-list"
88
102
  });
89
- </script>
103
+
104
+ const getDescriptions = (item) => {
105
+ if (Array.isArray(item.description)) {
106
+ return item.description;
107
+ }
108
+ return [item.description];
109
+ };
110
+ </script>
@@ -0,0 +1,56 @@
1
+ <template>
2
+ <picture v-if="sources?.length" :class="classes?.picture">
3
+ <source
4
+ v-for="(source, index) in sources"
5
+ :key="index"
6
+ v-bind="source"
7
+ />
8
+ <img
9
+ :src="src"
10
+ :alt="alt"
11
+ :class="classes?.img"
12
+ v-bind="$attrs"
13
+ />
14
+ </picture>
15
+
16
+ <img
17
+ v-else
18
+ :src="src"
19
+ :alt="alt"
20
+ :class="classes?.img"
21
+ v-bind="$attrs"
22
+ />
23
+ </template>
24
+
25
+ <script setup>
26
+ defineOptions({
27
+ inheritAttrs: false
28
+ });
29
+
30
+ defineProps({
31
+ src: {
32
+ type: String,
33
+ required: true
34
+ },
35
+ alt: {
36
+ type: String,
37
+ default: ''
38
+ },
39
+ /**
40
+ * Array of source objects for <picture> tag.
41
+ * Example: [{ srcset: '/small.jpg', media: '(max-width: 600px)' }]
42
+ */
43
+ sources: {
44
+ type: Array,
45
+ default: () => []
46
+ },
47
+ /**
48
+ * Granular class targeting for internal elements.
49
+ * Example: { picture: 'my-picture-class', img: 'my-img-class' }
50
+ */
51
+ classes: {
52
+ type: Object,
53
+ default: () => ({})
54
+ }
55
+ });
56
+ </script>
@@ -1,5 +1,6 @@
1
1
  <template>
2
2
  <component
3
+ v-if="items?.length"
3
4
  :is="listElement"
4
5
  :class="[
5
6
  {
@@ -0,0 +1,140 @@
1
+ <template>
2
+ <component :is="element">
3
+ <slot :setTrackRef="setTrackRef" :onScroll="onScroll" :canScrollLeft="canScrollLeft" :canScrollRight="canScrollRight"></slot>
4
+
5
+ <ul v-if="controls" :class="[`${namespace}__controls`, controlsClass]">
6
+ <li :class="[`${namespace}__controls-item`, `${namespace}__controls-item--previous`, { [`${namespace}__controls-item--disabled`]: !canScrollLeft }]">
7
+ <button
8
+ :class="[`${namespace}__control-button`, `${namespace}__control-button--previous`, ...buttonClasses]"
9
+ aria-label="Scroll Left"
10
+ :aria-controls="trackId"
11
+ @click="scrollLeft"
12
+ :disabled="!canScrollLeft"
13
+ >
14
+ <slot name="previous">
15
+ <span class="hidden-visually">Previous</span>
16
+ <UluIcon :icon="iconClassPrevious" :class="`${namespace}__control-icon`" />
17
+ </slot>
18
+ </button>
19
+ </li>
20
+ <li :class="[`${namespace}__controls-item`, `${namespace}__controls-item--next`, { [`${namespace}__controls-item--disabled`]: !canScrollRight }]">
21
+ <button
22
+ :class="[`${namespace}__control-button`, `${namespace}__control-button--next`, ...buttonClasses]"
23
+ aria-label="Scroll Right"
24
+ :aria-controls="trackId"
25
+ @click="scrollRight"
26
+ :disabled="!canScrollRight"
27
+ >
28
+ <slot name="next">
29
+ <span class="hidden-visually">Next</span>
30
+ <UluIcon :icon="iconClassNext" :class="`${namespace}__control-icon`" />
31
+ </slot>
32
+ </button>
33
+ </li>
34
+ </ul>
35
+ </component>
36
+ </template>
37
+
38
+ <script setup>
39
+ import { ref, onMounted, onBeforeUnmount, nextTick } from 'vue';
40
+ import UluIcon from './UluIcon.vue';
41
+
42
+ const props = defineProps({
43
+ /**
44
+ * The HTML element to use as the root wrapper.
45
+ */
46
+ element: { type: String, default: 'div' },
47
+ /**
48
+ * Show previous/next controls.
49
+ */
50
+ controls: { type: Boolean, default: true },
51
+ /**
52
+ * The ID of the track element, used for aria-controls.
53
+ */
54
+ trackId: { type: String, default: null },
55
+ /**
56
+ * Scroll amount (in pixels) for the next/prev buttons.
57
+ * If 'auto', it scrolls by the visible width of the track.
58
+ */
59
+ scrollAmount: { type: [Number, String], default: 'auto' },
60
+ /**
61
+ * Scroll behavior ('smooth' or 'auto').
62
+ */
63
+ scrollBehavior: { type: String, default: 'smooth' },
64
+ /**
65
+ * CSS class namespace for controls.
66
+ */
67
+ namespace: { type: String, default: 'OverflowScroller' },
68
+ /**
69
+ * Additional class to apply to the controls container.
70
+ */
71
+ controlsClass: { type: String, default: '' },
72
+ /**
73
+ * Button classes to apply.
74
+ */
75
+ buttonClasses: { type: Array, default: () => ['button', 'button--icon'] },
76
+ /**
77
+ * Icon definition for previous button.
78
+ */
79
+ iconClassPrevious: { type: String, default: 'type:previous' },
80
+ /**
81
+ * Icon definition for next button.
82
+ */
83
+ iconClassNext: { type: String, default: 'type:next' },
84
+ /**
85
+ * Offset threshold to consider "at start" (disables previous button).
86
+ */
87
+ offsetStart: { type: Number, default: 10 },
88
+ /**
89
+ * Offset threshold to consider "at end" (disables next button).
90
+ */
91
+ offsetEnd: { type: Number, default: 10 }
92
+ });
93
+
94
+ const trackRef = ref(null);
95
+ const canScrollLeft = ref(false);
96
+ const canScrollRight = ref(false);
97
+
98
+ const setTrackRef = (el) => {
99
+ trackRef.value = el;
100
+ };
101
+
102
+ const checkScrollability = () => {
103
+ if (!trackRef.value) return;
104
+ const { scrollLeft, scrollWidth, clientWidth } = trackRef.value;
105
+ canScrollLeft.value = scrollLeft > props.offsetStart;
106
+ canScrollRight.value = Math.ceil(scrollLeft + clientWidth) < (scrollWidth - props.offsetEnd);
107
+ };
108
+
109
+ const onScroll = () => {
110
+ checkScrollability();
111
+ };
112
+
113
+ const scrollByAmount = (direction) => {
114
+ if (!trackRef.value) return;
115
+ const { clientWidth } = trackRef.value;
116
+ let amount = props.scrollAmount;
117
+ if (amount === 'auto') {
118
+ amount = clientWidth;
119
+ }
120
+
121
+ trackRef.value.scrollBy({
122
+ left: direction === 'right' ? amount : -amount,
123
+ behavior: props.scrollBehavior
124
+ });
125
+ };
126
+
127
+ const scrollLeft = () => scrollByAmount('left');
128
+ const scrollRight = () => scrollByAmount('right');
129
+
130
+ onMounted(() => {
131
+ nextTick(() => {
132
+ checkScrollability();
133
+ });
134
+ window.addEventListener('resize', checkScrollability);
135
+ });
136
+
137
+ onBeforeUnmount(() => {
138
+ window.removeEventListener('resize', checkScrollability);
139
+ });
140
+ </script>
@@ -0,0 +1,150 @@
1
+ <template>
2
+ <div class="scroll-slider" :class="resolvedModifiers">
3
+ <UluOverflowScroller
4
+ class="scroll-slider__control-context"
5
+ controlsClass="scroll-slider__controls"
6
+ :controls="controls"
7
+ :scrollAmount="scrollAmount"
8
+ :scrollBehavior="scrollBehavior"
9
+ :trackId="trackId"
10
+ >
11
+ <template #default="{ setTrackRef, onScroll }">
12
+ <div class="scroll-slider__track-crop">
13
+ <ul
14
+ class="scroll-slider__track"
15
+ :id="trackId"
16
+ :ref="el => { trackRef = el; setTrackRef(el); }"
17
+ @scroll="onScroll"
18
+ >
19
+ <li v-if="emptySlides" class="scroll-slider__slide scroll-slider__slide--empty" role="presentation">&nbsp;</li>
20
+ <li
21
+ v-for="(item, index) in items"
22
+ :key="index"
23
+ class="scroll-slider__slide"
24
+ :ref="el => setSlideRef(el, index)"
25
+ >
26
+ <slot
27
+ name="slide"
28
+ :item="item"
29
+ :index="index"
30
+ :isIntersecting="intersectingIndexes.includes(index)"
31
+ ></slot>
32
+ </li>
33
+ <li v-if="emptySlides" class="scroll-slider__slide scroll-slider__slide--empty" role="presentation">&nbsp;</li>
34
+ </ul>
35
+ </div>
36
+ </template>
37
+ <template v-if="$slots.previous" #previous>
38
+ <slot name="previous"></slot>
39
+ </template>
40
+ <template v-if="$slots.next" #next>
41
+ <slot name="next"></slot>
42
+ </template>
43
+ </UluOverflowScroller>
44
+ </div>
45
+ </template>
46
+
47
+ <script setup>
48
+ import { ref, onMounted, onBeforeUnmount, nextTick } from 'vue';
49
+ import { useModifiers } from '../../composables/useModifiers.js';
50
+ import { newId } from '../../utils/dom.js';
51
+ import UluOverflowScroller from './UluOverflowScroller.vue';
52
+
53
+ const props = defineProps({
54
+ /**
55
+ * Array of items to render.
56
+ */
57
+ items: {
58
+ type: Array,
59
+ required: true,
60
+ },
61
+ /**
62
+ * Show previous/next controls.
63
+ */
64
+ controls: {
65
+ type: Boolean,
66
+ default: true,
67
+ },
68
+ /**
69
+ * Scroll amount (in pixels) for the next/prev buttons.
70
+ * If not provided, it defaults to the visible width of the track.
71
+ */
72
+ scrollAmount: {
73
+ type: [Number, String],
74
+ default: 'auto',
75
+ },
76
+ /**
77
+ * Scroll behavior ('smooth' or 'auto').
78
+ */
79
+ scrollBehavior: {
80
+ type: String,
81
+ default: 'smooth',
82
+ },
83
+ /**
84
+ * Include empty start and end slides (needed for correct margin collapsing with some styles).
85
+ */
86
+ emptySlides: {
87
+ type: Boolean,
88
+ default: true,
89
+ },
90
+ /**
91
+ * Options passed to the IntersectionObserver (determines when a slide is considered "intersecting").
92
+ */
93
+ observerOptions: {
94
+ type: Object,
95
+ default: () => ({ threshold: 0.1 })
96
+ },
97
+ /**
98
+ * Base class modifiers.
99
+ */
100
+ modifiers: [String, Array],
101
+ });
102
+
103
+ const { resolvedModifiers } = useModifiers({ props, baseClass: 'scroll-slider' });
104
+
105
+ const trackId = newId('ulu-scroll-slider-track');
106
+ const trackRef = ref(null);
107
+ const slideRefs = ref([]);
108
+ const intersectingIndexes = ref([]);
109
+
110
+ let observer = null;
111
+
112
+ const setSlideRef = (el, index) => {
113
+ if (el) {
114
+ slideRefs.value[index] = el;
115
+ }
116
+ };
117
+
118
+ onMounted(() => {
119
+ nextTick(() => {
120
+ // Setup IntersectionObserver to track visible slides
121
+ observer = new IntersectionObserver((entries) => {
122
+ entries.forEach(entry => {
123
+ const index = slideRefs.value.findIndex(el => el === entry.target);
124
+ if (index > -1) {
125
+ if (entry.isIntersecting) {
126
+ if (!intersectingIndexes.value.includes(index)) {
127
+ intersectingIndexes.value.push(index);
128
+ }
129
+ } else {
130
+ intersectingIndexes.value = intersectingIndexes.value.filter(i => i !== index);
131
+ }
132
+ }
133
+ });
134
+ }, {
135
+ ...props.observerOptions,
136
+ root: trackRef.value
137
+ });
138
+
139
+ slideRefs.value.forEach(el => {
140
+ if (el) observer.observe(el);
141
+ });
142
+ });
143
+ });
144
+
145
+ onBeforeUnmount(() => {
146
+ if (observer) {
147
+ observer.disconnect();
148
+ }
149
+ });
150
+ </script>