@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.
- package/dist/components/collapsible/UluAccordionGroup.vue.d.ts +2 -2
- package/dist/components/collapsible/UluAccordionGroup.vue.d.ts.map +1 -1
- package/dist/components/collapsible/UluAccordionGroup.vue.js +22 -19
- package/dist/components/collapsible/UluDropdown.vue.d.ts +1 -1
- package/dist/components/collapsible/UluDropdown.vue.d.ts.map +1 -1
- package/dist/components/collapsible/UluDropdown.vue.js +22 -15
- package/dist/components/collapsible/UluModal.vue.d.ts +43 -248
- package/dist/components/collapsible/UluModal.vue.d.ts.map +1 -1
- package/dist/components/collapsible/UluModal.vue.js +139 -191
- package/dist/components/collapsible/UluTabGroup.vue.d.ts +2 -0
- package/dist/components/collapsible/UluTabGroup.vue.d.ts.map +1 -1
- package/dist/components/collapsible/UluTabGroup.vue.js +23 -14
- package/dist/components/elements/UluAlert.vue.d.ts +29 -144
- package/dist/components/elements/UluAlert.vue.d.ts.map +1 -1
- package/dist/components/elements/UluAlert.vue.js +39 -50
- package/dist/components/elements/UluBadge.vue.d.ts +6 -6
- package/dist/components/elements/UluBadgeStack.vue.d.ts +1 -1
- package/dist/components/elements/UluBadgeStack.vue.d.ts.map +1 -1
- package/dist/components/elements/UluBadgeStack.vue.js +12 -9
- package/dist/components/elements/UluButton.vue.d.ts +47 -177
- package/dist/components/elements/UluButton.vue.d.ts.map +1 -1
- package/dist/components/elements/UluButton.vue.js +59 -72
- package/dist/components/elements/UluButtonVerbose.vue.d.ts +38 -123
- package/dist/components/elements/UluButtonVerbose.vue.d.ts.map +1 -1
- package/dist/components/elements/UluButtonVerbose.vue.js +52 -65
- package/dist/components/elements/UluCallout.vue.d.ts +20 -25
- package/dist/components/elements/UluCallout.vue.d.ts.map +1 -1
- package/dist/components/elements/UluCallout.vue.js +11 -16
- package/dist/components/elements/UluCaptionedFigure.vue.d.ts +25 -0
- package/dist/components/elements/UluCaptionedFigure.vue.d.ts.map +1 -0
- package/dist/components/elements/UluCaptionedFigure.vue.js +48 -0
- package/dist/components/elements/UluCard.vue.d.ts +2 -2
- package/dist/components/elements/UluDefinitionList.vue.d.ts +4 -2
- package/dist/components/elements/UluDefinitionList.vue.d.ts.map +1 -1
- package/dist/components/elements/UluDefinitionList.vue.js +32 -28
- package/dist/components/elements/UluExternalLink.vue.d.ts +2 -2
- package/dist/components/elements/UluImage.vue.d.ts +14 -0
- package/dist/components/elements/UluImage.vue.d.ts.map +1 -0
- package/dist/components/elements/UluImage.vue.js +53 -0
- package/dist/components/elements/UluList.vue.d.ts.map +1 -1
- package/dist/components/elements/UluList.vue.js +14 -13
- package/dist/components/elements/UluOverflowScroller.vue.d.ts +49 -0
- package/dist/components/elements/UluOverflowScroller.vue.d.ts.map +1 -0
- package/dist/components/elements/UluOverflowScroller.vue.js +138 -0
- package/dist/components/elements/UluScrollSlider.vue.d.ts +38 -0
- package/dist/components/elements/UluScrollSlider.vue.d.ts.map +1 -0
- package/dist/components/elements/UluScrollSlider.vue.js +146 -0
- package/dist/components/elements/UluSlider.vue.d.ts +57 -0
- package/dist/components/elements/UluSlider.vue.d.ts.map +1 -0
- package/dist/components/elements/UluSlider.vue.js +277 -0
- package/dist/components/forms/UluFormFile.vue.d.ts +2 -2
- package/dist/components/forms/UluFormRadio.vue.d.ts +4 -4
- package/dist/components/index.d.ts +6 -0
- package/dist/components/layout/UluTitleRail.vue.d.ts +29 -87
- package/dist/components/layout/UluTitleRail.vue.d.ts.map +1 -1
- package/dist/components/layout/UluTitleRail.vue.js +51 -46
- package/dist/components/navigation/UluBreadcrumb.vue.d.ts +27 -68
- package/dist/components/navigation/UluBreadcrumb.vue.d.ts.map +1 -1
- package/dist/components/navigation/UluBreadcrumb.vue.js +51 -54
- package/dist/components/navigation/UluMenu.vue.d.ts +30 -138
- package/dist/components/navigation/UluMenu.vue.d.ts.map +1 -1
- package/dist/components/navigation/UluMenu.vue.js +85 -84
- package/dist/components/navigation/UluMenuStack.vue.d.ts +12 -2
- package/dist/components/navigation/UluMenuStack.vue.d.ts.map +1 -1
- package/dist/components/navigation/UluMenuStack.vue.js +26 -18
- package/dist/components/navigation/UluNavStrip.vue.d.ts +22 -134
- package/dist/components/navigation/UluNavStrip.vue.d.ts.map +1 -1
- package/dist/components/navigation/UluNavStrip.vue.js +43 -31
- package/dist/components/systems/facets/UluFacetsSidebarLayout.vue.js +10 -10
- package/dist/components/systems/facets/useFacets.d.ts +3 -0
- package/dist/components/systems/facets/useFacets.d.ts.map +1 -1
- package/dist/components/systems/facets/useFacets.js +124 -112
- package/dist/components/systems/index.d.ts +0 -3
- package/dist/components/systems/scroll-anchors/UluScrollAnchors.vue.d.ts +2 -2
- package/dist/components/systems/table-sticky/UluTableSticky.vue.d.ts +504 -432
- package/dist/components/systems/table-sticky/UluTableSticky.vue.d.ts.map +1 -1
- package/dist/components/systems/table-sticky/UluTableSticky.vue.js +313 -456
- package/dist/components/systems/table-sticky/UluTableStickyRows.vue.d.ts +40 -31
- package/dist/components/systems/table-sticky/UluTableStickyRows.vue.d.ts.map +1 -1
- package/dist/components/systems/table-sticky/UluTableStickyRows.vue.js +43 -45
- package/dist/components/systems/table-sticky/UluTableStickyTable.vue.d.ts +60 -146
- package/dist/components/systems/table-sticky/UluTableStickyTable.vue.d.ts.map +1 -1
- package/dist/components/systems/table-sticky/UluTableStickyTable.vue.js +156 -175
- package/dist/components/utils/UluAction.vue.d.ts +36 -0
- package/dist/components/utils/UluAction.vue.d.ts.map +1 -0
- package/dist/components/utils/UluAction.vue.js +59 -0
- package/dist/components/utils/UluConditionalText.vue.d.ts +7 -26
- package/dist/components/utils/UluConditionalText.vue.d.ts.map +1 -1
- package/dist/components/utils/UluConditionalText.vue.js +12 -14
- package/dist/components/utils/UluConditionalWrapper.vue.d.ts.map +1 -1
- package/dist/components/utils/UluConditionalWrapper.vue.js +11 -9
- package/dist/components/utils/UluPlaceholderImage.vue.d.ts +12 -57
- package/dist/components/utils/UluPlaceholderImage.vue.d.ts.map +1 -1
- package/dist/components/utils/UluPlaceholderImage.vue.js +18 -26
- package/dist/components/utils/UluPlaceholderText.vue.d.ts +6 -20
- package/dist/components/utils/UluPlaceholderText.vue.js +12 -14
- package/dist/components/utils/UluRouteAnnouncer.vue.d.ts +9 -58
- package/dist/components/utils/UluRouteAnnouncer.vue.d.ts.map +1 -1
- package/dist/components/utils/UluRouteAnnouncer.vue.js +28 -28
- package/dist/components/visualizations/UluAnimateNumber.vue.d.ts +20 -14
- package/dist/components/visualizations/UluAnimateNumber.vue.d.ts.map +1 -1
- package/dist/components/visualizations/UluAnimateNumber.vue.js +18 -26
- package/dist/components/visualizations/UluProgressCircle.vue.d.ts +2 -2
- package/dist/composables/useModifiers.d.ts +20 -25
- package/dist/composables/useModifiers.d.ts.map +1 -1
- package/dist/index.js +206 -200
- package/dist/plugins/modals/UluModalsDisplay.vue.d.ts +3 -12
- package/dist/plugins/modals/UluModalsDisplay.vue.js +24 -45
- package/dist/plugins/modals/index.js +6 -6
- package/dist/plugins/toast/UluToast.vue.d.ts +24 -49
- package/dist/plugins/toast/UluToast.vue.d.ts.map +1 -1
- package/dist/plugins/toast/UluToast.vue.js +68 -77
- package/dist/plugins/toast/UluToastDisplay.vue.d.ts +1 -9
- package/dist/plugins/toast/UluToastDisplay.vue.js +27 -35
- package/dist/plugins/toast/defaults.d.ts +40 -35
- package/dist/plugins/toast/defaults.js +2 -2
- package/dist/plugins/toast/index.js +4 -4
- package/dist/plugins/toast/store.d.ts +40 -35
- package/dist/plugins/toast/store.d.ts.map +1 -1
- package/dist/utils/props.d.ts +7 -0
- package/dist/utils/props.d.ts.map +1 -0
- package/dist/utils/props.js +6 -0
- package/lib/components/collapsible/UluAccordionGroup.vue +4 -1
- package/lib/components/collapsible/UluDropdown.vue +5 -1
- package/lib/components/collapsible/UluModal.vue +278 -298
- package/lib/components/collapsible/UluTabGroup.vue +21 -6
- package/lib/components/elements/UluAlert.vue +38 -51
- package/lib/components/elements/UluBadgeStack.vue +4 -1
- package/lib/components/elements/UluButton.vue +105 -129
- package/lib/components/elements/UluButtonVerbose.vue +67 -89
- package/lib/components/elements/UluCallout.vue +15 -19
- package/lib/components/elements/UluCaptionedFigure.vue +40 -0
- package/lib/components/elements/UluDefinitionList.vue +27 -6
- package/lib/components/elements/UluImage.vue +56 -0
- package/lib/components/elements/UluList.vue +1 -0
- package/lib/components/elements/UluOverflowScroller.vue +140 -0
- package/lib/components/elements/UluScrollSlider.vue +150 -0
- package/lib/components/elements/UluSlider.vue +488 -0
- package/lib/components/index.js +10 -0
- package/lib/components/layout/UluTitleRail.vue +55 -48
- package/lib/components/navigation/UluBreadcrumb.vue +29 -34
- package/lib/components/navigation/UluMenu.vue +60 -71
- package/lib/components/navigation/UluMenuStack.vue +6 -1
- package/lib/components/navigation/UluNavStrip.vue +43 -31
- package/lib/components/systems/facets/useFacets.js +33 -17
- package/lib/components/systems/index.js +0 -4
- package/lib/components/systems/table-sticky/UluTableSticky.vue +602 -576
- package/lib/components/systems/table-sticky/UluTableStickyRows.vue +16 -27
- package/lib/components/systems/table-sticky/UluTableStickyTable.vue +95 -96
- package/lib/components/utils/UluAction.vue +81 -0
- package/lib/components/utils/UluConditionalText.vue +13 -16
- package/lib/components/utils/UluConditionalWrapper.vue +5 -1
- package/lib/components/utils/UluPlaceholderImage.vue +44 -46
- package/lib/components/utils/UluPlaceholderText.vue +10 -13
- package/lib/components/utils/UluRouteAnnouncer.vue +59 -47
- package/lib/components/visualizations/UluAnimateNumber.vue +23 -30
- package/lib/composables/useModifiers.js +21 -26
- package/lib/plugins/modals/UluModalsDisplay.vue +44 -45
- package/lib/plugins/toast/UluToast.vue +28 -34
- package/lib/plugins/toast/UluToastDisplay.vue +9 -15
- package/lib/utils/props.js +8 -0
- package/package.json +9 -5
- package/dist/components/systems/slider/UluImageSlideShow.vue.d.ts +0 -130
- package/dist/components/systems/slider/UluImageSlideShow.vue.d.ts.map +0 -1
- package/dist/components/systems/slider/UluImageSlideShow.vue.js +0 -73
- package/dist/components/systems/slider/UluSlideShow.vue.d.ts +0 -205
- package/dist/components/systems/slider/UluSlideShow.vue.d.ts.map +0 -1
- package/dist/components/systems/slider/UluSlideShow.vue.js +0 -292
- package/dist/components/systems/slider/UluSlideShowSlide.vue.d.ts +0 -17
- package/dist/components/systems/slider/UluSlideShowSlide.vue.d.ts.map +0 -1
- package/dist/components/systems/slider/UluSlideShowSlide.vue.js +0 -26
- package/lib/components/systems/slider/UluImageSlideShow.vue +0 -75
- package/lib/components/systems/slider/UluSlideShow.vue +0 -336
- package/lib/components/systems/slider/UluSlideShowSlide.vue +0 -25
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<dl
|
|
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
|
|
15
|
-
|
|
16
|
-
|
|
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 (
|
|
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
|
-
|
|
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>
|
|
@@ -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"> </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"> </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>
|