@iamproperty/components 7.8.2--beta3 → 7.8.2--beta4
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/assets/css/components/actionbar.component.css +1 -1
- package/assets/css/components/actionbar.component.css.map +1 -1
- package/assets/css/components/address-lookup.component.css +1 -1
- package/assets/css/components/address-lookup.component.css.map +1 -1
- package/assets/css/components/advanced-select.component.css +1 -1
- package/assets/css/components/advanced-select.component.css.map +1 -1
- package/assets/css/components/banner.preload.css +1 -0
- package/assets/css/components/banner.preload.css.map +1 -0
- package/assets/css/components/calendar.component.css +1 -1
- package/assets/css/components/calendar.component.css.map +1 -1
- package/assets/css/components/card.component.css +1 -1
- package/assets/css/components/card.component.css.map +1 -1
- package/assets/css/components/card.module.css +1 -1
- package/assets/css/components/card.module.css.map +1 -1
- package/assets/css/components/card.preload.css +1 -0
- package/assets/css/components/card.preload.css.map +1 -0
- package/assets/css/components/carousel.component.css +1 -1
- package/assets/css/components/carousel.component.css.map +1 -1
- package/assets/css/components/carousel.config.css +1 -1
- package/assets/css/components/carousel.config.css.map +1 -1
- package/assets/css/components/config.component.css +1 -1
- package/assets/css/components/config.component.css.map +1 -1
- package/assets/css/components/content.component.css +1 -1
- package/assets/css/components/content.component.css.map +1 -1
- package/assets/css/components/fileupload.css +1 -1
- package/assets/css/components/fileupload.css.map +1 -1
- package/assets/css/components/filter-card.component.css +1 -1
- package/assets/css/components/filter-card.component.css.map +1 -1
- package/assets/css/components/multiselect.css +1 -1
- package/assets/css/components/multiselect.css.map +1 -1
- package/assets/css/components/nav.component.css +1 -1
- package/assets/css/components/nav.component.css.map +1 -1
- package/assets/css/components/pagination.css +1 -1
- package/assets/css/components/pagination.css.map +1 -1
- package/assets/css/components/record-card.component.css +1 -1
- package/assets/css/components/record-card.component.css.map +1 -1
- package/assets/css/components/search.component.css +1 -1
- package/assets/css/components/search.component.css.map +1 -1
- package/assets/css/components/skeleton.global.css +1 -1
- package/assets/css/components/skeleton.global.css.map +1 -1
- package/assets/css/components/slider.css +1 -1
- package/assets/css/components/slider.css.map +1 -1
- package/assets/css/components/split-button.component.css +1 -1
- package/assets/css/components/split-button.component.css.map +1 -1
- package/assets/css/components/std-nav-standalone.component.css +1 -1
- package/assets/css/components/std-nav-standalone.component.css.map +1 -1
- package/assets/css/components/tabs.component.css +1 -1
- package/assets/css/components/tabs.component.css.map +1 -1
- package/assets/css/components/tag.component.css +1 -1
- package/assets/css/components/tag.component.css.map +1 -1
- package/assets/css/components/video-card.component.css +1 -1
- package/assets/css/components/video-card.component.css.map +1 -1
- package/assets/css/core.min.css +1 -1
- package/assets/css/core.min.css.map +1 -1
- package/assets/css/elements/dropdown.css +1 -1
- package/assets/css/elements/dropdown.css.map +1 -1
- package/assets/css/elements/forms.css +1 -1
- package/assets/css/elements/forms.css.map +1 -1
- package/assets/css/elements/links--global.css +1 -1
- package/assets/css/elements/links--global.css.map +1 -1
- package/assets/css/elements/links.css +1 -1
- package/assets/css/elements/links.css.map +1 -1
- package/assets/css/style.min.css +1 -1
- package/assets/css/style.min.css.map +1 -1
- package/assets/js/components/accordion/accordion.component.min.js +1 -1
- package/assets/js/components/actionbar/actionbar.component.min.js +2 -2
- package/assets/js/components/address-lookup/address-lookup.component.min.js +4 -4
- package/assets/js/components/address-lookup/address-lookup.component.min.js.map +1 -1
- package/assets/js/components/advanced-select/advanced-select.component.min.js +2 -2
- package/assets/js/components/applied-filters/applied-filters.component.min.js +1 -1
- package/assets/js/components/banner/banner.component.min.js +1 -1
- package/assets/js/components/barchart/barchart.component.min.js +1 -1
- package/assets/js/components/bento-grid/bento-grid.component.min.js +1 -1
- package/assets/js/components/bone/bone.component.min.js +1 -1
- package/assets/js/components/button/button.component.min.js +1 -1
- package/assets/js/components/calendar/calendar.component.min.js +2 -2
- package/assets/js/components/card/card.component.js +114 -125
- package/assets/js/components/card/card.component.min.js +7 -7
- package/assets/js/components/card/card.component.min.js.map +1 -1
- package/assets/js/components/carousel/carousel.component.js +83 -29
- package/assets/js/components/carousel/carousel.component.min.js +16 -11
- package/assets/js/components/carousel/carousel.component.min.js.map +1 -1
- package/assets/js/components/collapsible-side/collapsible-side.component.min.js +1 -1
- package/assets/js/components/config/config.component.min.js +7 -7
- package/assets/js/components/config/config.component.min.js.map +1 -1
- package/assets/js/components/content/content.component.js +28 -69
- package/assets/js/components/content/content.component.min.js +4 -4
- package/assets/js/components/content/content.component.min.js.map +1 -1
- package/assets/js/components/darkmode/darkmode.component.min.js +1 -1
- package/assets/js/components/doughnutchart/doughnutchart.component.min.js +1 -1
- package/assets/js/components/fileupload/fileupload.component.min.js +2 -2
- package/assets/js/components/filter-card/filter-card.component.min.js +5 -5
- package/assets/js/components/filter-card/filter-card.component.min.js.map +1 -1
- package/assets/js/components/filterlist/filterlist.component.min.js +1 -1
- package/assets/js/components/form/form.component.min.js +1 -1
- package/assets/js/components/header/header.component.min.js +1 -1
- package/assets/js/components/inline-edit/inline-edit.component.min.js +1 -1
- package/assets/js/components/input/input.component.min.js +1 -1
- package/assets/js/components/input-range/input-range.component.min.js +1 -1
- package/assets/js/components/marketing/marketing.component.min.js +1 -1
- package/assets/js/components/menu/menu.component.min.js +1 -1
- package/assets/js/components/milestone/milestone.component.min.js +1 -1
- package/assets/js/components/milestone-group/milestone-group.component.min.js +1 -1
- package/assets/js/components/modal/modal.component.min.js +1 -1
- package/assets/js/components/multi-step/multi-step.component.min.js +1 -1
- package/assets/js/components/multi-step-modal/multi-step-modal.component.min.js +1 -1
- package/assets/js/components/multiselect/multiselect.component.min.js +4 -4
- package/assets/js/components/multiselect/multiselect.component.min.js.map +1 -1
- package/assets/js/components/nav/nav.component.min.js +2 -2
- package/assets/js/components/notification/notification.component.min.js +1 -1
- package/assets/js/components/pagination/pagination.component.min.js +5 -5
- package/assets/js/components/password/password.component.min.js +1 -1
- package/assets/js/components/popover/popover.component.min.js +1 -1
- package/assets/js/components/rank/rank.component.min.js +1 -1
- package/assets/js/components/rankings/rankings.component.min.js +1 -1
- package/assets/js/components/rating/rating.component.min.js +1 -1
- package/assets/js/components/record-card/record-card.component.min.js +6 -6
- package/assets/js/components/record-card/record-card.component.min.js.map +1 -1
- package/assets/js/components/search/search.component.js +234 -186
- package/assets/js/components/search/search.component.min.js +12 -7
- package/assets/js/components/search/search.component.min.js.map +1 -1
- package/assets/js/components/skeleton/skeleton.component.min.js +1 -1
- package/assets/js/components/slider/slider.component.min.js +2 -2
- package/assets/js/components/split-button/split-button.component.min.js +2 -2
- package/assets/js/components/std-address-lookup/std-address-lookup.component.min.js +5 -5
- package/assets/js/components/std-address-lookup/std-address-lookup.component.min.js.map +1 -1
- package/assets/js/components/std-nav/std-nav.component.js +10 -9
- package/assets/js/components/std-nav/std-nav.component.min.js +9 -12
- package/assets/js/components/std-nav/std-nav.component.min.js.map +1 -1
- package/assets/js/components/std-nav-standalone/std-nav-standalone.component.min.js +5 -5
- package/assets/js/components/std-nav-standalone/std-nav-standalone.component.min.js.map +1 -1
- package/assets/js/components/table/table.component.min.js +1 -1
- package/assets/js/components/table-ajax/table-ajax.component.min.js +1 -1
- package/assets/js/components/table-basic/table-basic.component.min.js +1 -1
- package/assets/js/components/table-no-submit/table-no-submit.component.min.js +1 -1
- package/assets/js/components/table-submit/table-submit.component.min.js +1 -1
- package/assets/js/components/tabs/tabs.component.min.js +4 -4
- package/assets/js/components/tag/tag.component.min.js +3 -3
- package/assets/js/components/tag/tag.component.min.js.map +1 -1
- package/assets/js/components/tooltip/tooltip.component.min.js +1 -1
- package/assets/js/components/video/video.component.min.js +1 -1
- package/assets/js/components/video-card/video-card.component.min.js +9 -9
- package/assets/js/components/video-card/video-card.component.min.js.map +1 -1
- package/assets/js/components/video-modal/video-modal.component.min.js +1 -1
- package/assets/js/components/word-count/word-count.component.min.js +1 -1
- package/assets/js/modules/card.module.js +12 -11
- package/assets/js/modules/content.js +40 -8
- package/assets/js/modules/content.test.js +62 -12
- package/assets/js/modules/data-layer.js +7 -6
- package/assets/js/modules/dropdown.js +0 -1
- package/assets/js/modules/nav.js +10 -3
- package/assets/js/modules/search.js +153 -0
- package/assets/js/modules/search.test.js +125 -0
- package/assets/js/modules/tabs.test.js +64 -12
- package/assets/js/modules/testimonial.test.js +44 -6
- package/assets/js/modules/videos.test.js +61 -13
- package/assets/js/scripts.bundle.js +3 -3
- package/assets/js/scripts.bundle.js.map +1 -1
- package/assets/js/scripts.bundle.min.js +2 -2
- package/assets/js/scripts.bundle.min.js.map +1 -1
- package/assets/sass/_components.scss +2 -63
- package/assets/sass/components/banner.preload.scss +26 -0
- package/assets/sass/components/card.component.scss +1 -7
- package/assets/sass/components/card.module.scss +6 -6
- package/assets/sass/components/card.preload.scss +80 -0
- package/assets/sass/components/carousel.component.scss +165 -0
- package/assets/sass/components/carousel.config.scss +85 -249
- package/assets/sass/components/content.component.scss +0 -7
- package/assets/sass/components/nav.component.scss +2 -1
- package/assets/sass/components/search.component.scss +89 -7
- package/assets/sass/components/skeleton.global.scss +4 -0
- package/assets/sass/elements/dropdown.css +2 -0
- package/assets/sass/elements/forms.scss +0 -27
- package/assets/sass/elements/links--global.scss +40 -2
- package/assets/sass/foundations/root.scss +0 -1
- package/assets/sass/utilities/js-display.css +2 -3
- package/assets/ts/components/card/card.component.ts +72 -62
- package/assets/ts/components/carousel/carousel.component.ts +84 -19
- package/assets/ts/components/content/content.component.ts +36 -100
- package/assets/ts/components/search/search.component.ts +257 -185
- package/assets/ts/components/std-nav/std-nav.component.ts +17 -16
- package/assets/ts/html.d.ts +6 -0
- package/assets/ts/modules/card.module.ts +20 -12
- package/assets/ts/modules/content.test.ts +84 -12
- package/assets/ts/modules/content.ts +56 -9
- package/assets/ts/modules/data-layer.ts +7 -11
- package/assets/ts/modules/dropdown.ts +0 -2
- package/assets/ts/modules/nav.ts +12 -3
- package/assets/ts/modules/search.test.ts +142 -0
- package/assets/ts/modules/search.ts +206 -0
- package/assets/ts/modules/tabs.test.ts +79 -12
- package/assets/ts/modules/testimonial.test.ts +45 -6
- package/assets/ts/modules/videos.test.ts +74 -14
- package/dist/components.es.js +25 -25
- package/dist/components.umd.js +163 -156
- package/package.json +1 -1
- package/assets/js/modules/carousel.js +0 -214
- package/assets/js/modules/carousel.test.js +0 -18
- package/assets/ts/modules/carousel.test.ts +0 -27
- package/assets/ts/modules/carousel.ts +0 -301
package/package.json
CHANGED
|
@@ -1,214 +0,0 @@
|
|
|
1
|
-
export const generateThumbnailList = function (carouselComponent) {
|
|
2
|
-
const thumbnailImages = [];
|
|
3
|
-
Array.from(carouselComponent.querySelectorAll(':scope > :is(div,iam-card)')).forEach((slide, index) => {
|
|
4
|
-
if (slide.hasAttribute('data-thumbnail')) {
|
|
5
|
-
thumbnailImages[index] = slide.getAttribute('data-thumbnail');
|
|
6
|
-
}
|
|
7
|
-
});
|
|
8
|
-
return thumbnailImages;
|
|
9
|
-
};
|
|
10
|
-
export const generatePipsHTML = function (carouselComponent, thumbnailImages) {
|
|
11
|
-
const itemCount = carouselComponent.querySelectorAll(':scope > :is(div,iam-card)').length;
|
|
12
|
-
let pips = '';
|
|
13
|
-
for (let i = 1; i <= itemCount; i++) {
|
|
14
|
-
let pipContent = null;
|
|
15
|
-
let pipClass = '';
|
|
16
|
-
if (thumbnailImages.length && thumbnailImages[i - 1]) {
|
|
17
|
-
pipClass = 'has-thumbnail';
|
|
18
|
-
pipContent = `<img src="${thumbnailImages[i - 1]}" alt="Slide ${i}" height="148"/>`;
|
|
19
|
-
}
|
|
20
|
-
else {
|
|
21
|
-
pipContent = `Slide ${i}`;
|
|
22
|
-
}
|
|
23
|
-
pips += `<button class="control-${i} ${pipClass}" data-slide="${i}" ${i == 1 ? 'aria-current' : ''}>${pipContent}</button>`;
|
|
24
|
-
}
|
|
25
|
-
return pips;
|
|
26
|
-
};
|
|
27
|
-
export const getProgressMax = function (itemCount, visibleItems) {
|
|
28
|
-
if (visibleItems == 1) {
|
|
29
|
-
return itemCount;
|
|
30
|
-
}
|
|
31
|
-
const max = Math.ceil(itemCount / visibleItems) * visibleItems - visibleItems;
|
|
32
|
-
return max + 1;
|
|
33
|
-
};
|
|
34
|
-
const getProgressPercent = function (value, max) {
|
|
35
|
-
return ((value - 1) / (max - 1)) * 100;
|
|
36
|
-
};
|
|
37
|
-
export const carousel = function (carouselComponent) {
|
|
38
|
-
let scrollTimeout;
|
|
39
|
-
const carouselElement = carouselComponent.shadowRoot.querySelector('.carousel');
|
|
40
|
-
const carouselInner = carouselElement.querySelector('.carousel__inner');
|
|
41
|
-
const carouselControls = carouselElement.querySelector('.carousel__controls');
|
|
42
|
-
const carouselProgress = carouselElement.querySelector('.carousel__progress [type="range"]');
|
|
43
|
-
const itemCount = carouselComponent.querySelectorAll(':scope > :is(div,iam-card)').length;
|
|
44
|
-
let scrollArea = carouselInner.clientWidth;
|
|
45
|
-
let itemWidth = carouselComponent.querySelector(':scope > :is(div,iam-card)').scrollWidth;
|
|
46
|
-
let visibleItems = Math.round(scrollArea / itemWidth);
|
|
47
|
-
carouselProgress.setAttribute('min', 1);
|
|
48
|
-
carouselProgress.setAttribute('step', visibleItems);
|
|
49
|
-
let progressMax = getProgressMax(itemCount, visibleItems);
|
|
50
|
-
carouselProgress.setAttribute('max', progressMax);
|
|
51
|
-
carouselProgress.value = 1;
|
|
52
|
-
let percent = getProgressPercent(1, progressMax);
|
|
53
|
-
carouselProgress.style.setProperty('--percent', percent + '%');
|
|
54
|
-
let stepperInterval, stepperEvent = 'mouseup', stepperStart = 'mousedown';
|
|
55
|
-
if ('ontouchstart' in document.documentElement) {
|
|
56
|
-
stepperEvent = 'touchend';
|
|
57
|
-
stepperStart = 'touchstart';
|
|
58
|
-
}
|
|
59
|
-
// On scroll we need to make sure the buttons get corrected and the next testimonial is shown
|
|
60
|
-
carouselInner.addEventListener('scroll', function () {
|
|
61
|
-
clearTimeout(scrollTimeout);
|
|
62
|
-
scrollTimeout = setTimeout(function () {
|
|
63
|
-
const scrollArea = carouselInner.clientWidth;
|
|
64
|
-
const scrollWidth = carouselInner.scrollWidth;
|
|
65
|
-
const scrollLeft = carouselInner.scrollLeft;
|
|
66
|
-
let targetSlide = Math.round((scrollLeft / scrollWidth) * itemCount) + 1;
|
|
67
|
-
const itemWidth = carouselComponent.querySelector(':scope > :is(div,iam-card)').scrollWidth;
|
|
68
|
-
const lastItemOffset = carouselComponent.querySelector(':scope > :is(div,iam-card):last-child').offsetLeft;
|
|
69
|
-
//+60px here is to account for when the next offscreen slide is visible beneath the next arrow
|
|
70
|
-
const lastItemInView = carouselInner.scrollLeft + scrollArea + carouselInner.getBoundingClientRect().left >= lastItemOffset + 60;
|
|
71
|
-
const visibleItems = Math.round(scrollArea / itemWidth);
|
|
72
|
-
//Check if theres room for more slides than we have
|
|
73
|
-
const leftOverSpace = Math.ceil(itemCount / visibleItems) * visibleItems - itemCount;
|
|
74
|
-
carouselProgress.setAttribute('step', visibleItems);
|
|
75
|
-
if (leftOverSpace > 0 && lastItemInView) {
|
|
76
|
-
targetSlide = Math.floor(itemCount / visibleItems) * visibleItems + 1;
|
|
77
|
-
}
|
|
78
|
-
Array.from(carouselElement.querySelectorAll('.carousel__controls button')).forEach((button) => {
|
|
79
|
-
button.removeAttribute('aria-current');
|
|
80
|
-
});
|
|
81
|
-
carouselElement.querySelector('.control-' + targetSlide).setAttribute('aria-current', true);
|
|
82
|
-
// Disable the previous button
|
|
83
|
-
if (targetSlide == 1)
|
|
84
|
-
carouselElement.querySelector('.btn-prev').setAttribute('disabled', 'disabled');
|
|
85
|
-
else
|
|
86
|
-
carouselElement.querySelector('.btn-prev').removeAttribute('disabled');
|
|
87
|
-
// Disable the next button if the last item is in view
|
|
88
|
-
if (targetSlide > itemCount - visibleItems)
|
|
89
|
-
carouselElement.querySelector('.btn-next').setAttribute('disabled', 'disabled');
|
|
90
|
-
else
|
|
91
|
-
carouselElement.querySelector('.btn-next').removeAttribute('disabled');
|
|
92
|
-
carouselProgress.value = targetSlide;
|
|
93
|
-
progressMax = getProgressMax(itemCount, visibleItems);
|
|
94
|
-
carouselProgress.setAttribute('max', progressMax);
|
|
95
|
-
percent = (targetSlide / progressMax) * 100;
|
|
96
|
-
percent = getProgressPercent(targetSlide, progressMax);
|
|
97
|
-
carouselProgress.style.setProperty('--percent', percent + '%');
|
|
98
|
-
}, 100);
|
|
99
|
-
}, false);
|
|
100
|
-
// when the buttons are used we need to make sure the carousel scrolls to the correct place
|
|
101
|
-
carouselControls.addEventListener('click', function (e) {
|
|
102
|
-
for (let target = e.target; target && target != this; target = target.parentNode) {
|
|
103
|
-
if (typeof target.matches == 'function' && target.matches('button')) {
|
|
104
|
-
e.preventDefault();
|
|
105
|
-
Array.from(carouselControls.querySelectorAll('button')).forEach((button) => {
|
|
106
|
-
button.removeAttribute('aria-current');
|
|
107
|
-
});
|
|
108
|
-
target.setAttribute('aria-current', true);
|
|
109
|
-
const customEvent = new CustomEvent('pip-clicked', {
|
|
110
|
-
detail: {
|
|
111
|
-
slide: target.getAttribute('data-slide'),
|
|
112
|
-
},
|
|
113
|
-
});
|
|
114
|
-
carouselComponent.dispatchEvent(customEvent);
|
|
115
|
-
const el = carouselComponent.querySelector(`:scope > *:nth-child(${target.getAttribute('data-slide')})`);
|
|
116
|
-
carouselInner.scroll({
|
|
117
|
-
top: 0,
|
|
118
|
-
left: el.offsetLeft - carouselInner.getBoundingClientRect().left,
|
|
119
|
-
behavior: 'smooth',
|
|
120
|
-
});
|
|
121
|
-
break;
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
}, false);
|
|
125
|
-
carouselElement.addEventListener('click', function (e) {
|
|
126
|
-
const scrollArea = carouselInner.clientWidth;
|
|
127
|
-
//const scrollWidth = carouselInner.scrollWidth;
|
|
128
|
-
const itemWidth = carouselComponent.querySelector(':scope > :is(div,iam-card)').scrollWidth;
|
|
129
|
-
const visibleItems = Math.round(scrollArea / itemWidth);
|
|
130
|
-
const lastItemOffset = carouselComponent.querySelector(':scope > :is(div,iam-card):last-child').offsetLeft;
|
|
131
|
-
const lastItemInView = carouselInner.scrollLeft + scrollArea + carouselInner.getBoundingClientRect().left >= lastItemOffset + 60;
|
|
132
|
-
//Check if theres room for more slides than we have
|
|
133
|
-
const leftOverSpace = Math.ceil(itemCount / visibleItems) * visibleItems - itemCount;
|
|
134
|
-
/*
|
|
135
|
-
When the last slide isn't filled with items, we only want to move back the number of items on the slide,
|
|
136
|
-
rather than the total number of possible visible items
|
|
137
|
-
*/
|
|
138
|
-
const spacesToMove = visibleItems - leftOverSpace;
|
|
139
|
-
//Only want to change the amount of movement if the last item is visible
|
|
140
|
-
const movement = lastItemInView && leftOverSpace > 0 ? spacesToMove * itemWidth : carouselInner.clientWidth;
|
|
141
|
-
for (let target = e.target; target && target != this; target = target.parentNode) {
|
|
142
|
-
if (typeof target.matches == 'function' && target.matches('.btn-next, .btn-prev')) {
|
|
143
|
-
const direction = target.matches('.btn-next') ? 'next' : 'prev';
|
|
144
|
-
const customEvent = new CustomEvent(`${direction}-clicked`, {
|
|
145
|
-
detail: {
|
|
146
|
-
slide: target.getAttribute('data-go'),
|
|
147
|
-
},
|
|
148
|
-
});
|
|
149
|
-
carouselComponent.dispatchEvent(customEvent);
|
|
150
|
-
e.preventDefault();
|
|
151
|
-
const scrollTo = target.classList.contains('btn-prev')
|
|
152
|
-
? carouselInner.scrollLeft - movement
|
|
153
|
-
: carouselInner.scrollLeft + carouselInner.clientWidth;
|
|
154
|
-
carouselInner.scroll({
|
|
155
|
-
top: 0,
|
|
156
|
-
left: scrollTo,
|
|
157
|
-
behavior: 'smooth',
|
|
158
|
-
});
|
|
159
|
-
break;
|
|
160
|
-
}
|
|
161
|
-
}
|
|
162
|
-
}, false);
|
|
163
|
-
carouselProgress.addEventListener(stepperStart, function () {
|
|
164
|
-
clearInterval(stepperInterval);
|
|
165
|
-
stepperInterval = setInterval(function () {
|
|
166
|
-
scrollArea = carouselInner.clientWidth;
|
|
167
|
-
itemWidth = carouselComponent.querySelector(':scope > :is(div,iam-card)').scrollWidth;
|
|
168
|
-
visibleItems = Math.round(scrollArea / itemWidth);
|
|
169
|
-
carouselProgress.setAttribute('step', visibleItems);
|
|
170
|
-
progressMax = getProgressMax(itemCount, visibleItems);
|
|
171
|
-
carouselProgress.setAttribute('max', progressMax);
|
|
172
|
-
percent = getProgressPercent(carouselProgress.value, progressMax);
|
|
173
|
-
carouselProgress.style.setProperty('--percent', percent + '%');
|
|
174
|
-
}, 10);
|
|
175
|
-
});
|
|
176
|
-
carouselProgress.addEventListener(stepperEvent, function () {
|
|
177
|
-
clearInterval(stepperInterval);
|
|
178
|
-
});
|
|
179
|
-
carouselProgress.addEventListener('change', function () {
|
|
180
|
-
clearInterval(stepperInterval);
|
|
181
|
-
const target = carouselComponent.querySelector(`:scope > *:nth-child(${carouselProgress.value})`);
|
|
182
|
-
carouselInner.scroll({
|
|
183
|
-
top: 0,
|
|
184
|
-
left: target ? target.offsetLeft - carouselInner.getBoundingClientRect().left : 0,
|
|
185
|
-
behavior: 'smooth',
|
|
186
|
-
});
|
|
187
|
-
//const direction = target.matches('.btn-next') ? 'next' : 'prev';
|
|
188
|
-
const customEvent = new CustomEvent(`slider-changed`, {
|
|
189
|
-
detail: {
|
|
190
|
-
slide: carouselProgress.value,
|
|
191
|
-
},
|
|
192
|
-
});
|
|
193
|
-
carouselComponent.dispatchEvent(customEvent);
|
|
194
|
-
}, false);
|
|
195
|
-
};
|
|
196
|
-
export const updateCarousel = function (carouselComponent) {
|
|
197
|
-
const carouselElement = carouselComponent.shadowRoot.querySelector('.carousel');
|
|
198
|
-
const carouselInner = carouselElement.querySelector('.carousel__inner');
|
|
199
|
-
const carouselControls = carouselElement.querySelector('.carousel__controls');
|
|
200
|
-
const carouselProgress = carouselElement.querySelector('.carousel__progress [type="range"]');
|
|
201
|
-
const itemCount = carouselComponent.querySelectorAll(':scope > :is(div,iam-card)').length;
|
|
202
|
-
let scrollArea = carouselInner.clientWidth;
|
|
203
|
-
let itemWidth = carouselComponent.querySelector(':scope > :is(div,iam-card)').scrollWidth;
|
|
204
|
-
let visibleItems = Math.round(scrollArea / itemWidth);
|
|
205
|
-
carouselProgress.setAttribute('min', 1);
|
|
206
|
-
carouselProgress.setAttribute('step', visibleItems);
|
|
207
|
-
let progressMax = getProgressMax(itemCount, visibleItems);
|
|
208
|
-
carouselProgress.setAttribute('max', progressMax);
|
|
209
|
-
carouselProgress.value = 1;
|
|
210
|
-
let percent = getProgressPercent(1, progressMax);
|
|
211
|
-
carouselProgress.style.setProperty('--percent', percent + '%');
|
|
212
|
-
carouselControls.innerHTML = generatePipsHTML(carouselComponent, []);
|
|
213
|
-
};
|
|
214
|
-
export default carousel;
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from './test.ts';
|
|
2
|
-
import { createElement, installTestDom } from './test-dom.ts';
|
|
3
|
-
import { append } from './test-utils.ts';
|
|
4
|
-
import { generatePipsHTML, generateThumbnailList, getProgressMax } from './carousel.ts';
|
|
5
|
-
installTestDom();
|
|
6
|
-
describe('Carousel module', () => {
|
|
7
|
-
it('builds thumbnail-aware pips and progress max values', () => {
|
|
8
|
-
const carousel = createElement('iam-carousel');
|
|
9
|
-
append(carousel, createElement('div', { dataThumbnail: '/one.jpg' }), createElement('iam-card'), createElement('div', { dataThumbnail: '/three.jpg' }));
|
|
10
|
-
const thumbnails = generateThumbnailList(carousel);
|
|
11
|
-
const html = generatePipsHTML(carousel, thumbnails);
|
|
12
|
-
expect(thumbnails[0] === '/one.jpg');
|
|
13
|
-
expect(thumbnails[2] === '/three.jpg');
|
|
14
|
-
expect(html.includes('control-1 has-thumbnail'));
|
|
15
|
-
expect(html.includes('Slide 2'));
|
|
16
|
-
expect(getProgressMax(7, 3) === 7);
|
|
17
|
-
});
|
|
18
|
-
});
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from './test.ts';
|
|
2
|
-
import { createElement, installTestDom } from './test-dom.ts';
|
|
3
|
-
import { append } from './test-utils.ts';
|
|
4
|
-
import { generatePipsHTML, generateThumbnailList, getProgressMax } from './carousel.ts';
|
|
5
|
-
|
|
6
|
-
installTestDom();
|
|
7
|
-
|
|
8
|
-
describe('Carousel module', () => {
|
|
9
|
-
it('builds thumbnail-aware pips and progress max values', () => {
|
|
10
|
-
const carousel = createElement('iam-carousel');
|
|
11
|
-
append(
|
|
12
|
-
carousel,
|
|
13
|
-
createElement('div', { dataThumbnail: '/one.jpg' }),
|
|
14
|
-
createElement('iam-card'),
|
|
15
|
-
createElement('div', { dataThumbnail: '/three.jpg' })
|
|
16
|
-
);
|
|
17
|
-
|
|
18
|
-
const thumbnails = generateThumbnailList(carousel);
|
|
19
|
-
const html = generatePipsHTML(carousel, thumbnails);
|
|
20
|
-
|
|
21
|
-
expect(thumbnails[0] === '/one.jpg');
|
|
22
|
-
expect(thumbnails[2] === '/three.jpg');
|
|
23
|
-
expect(html.includes('control-1 has-thumbnail'));
|
|
24
|
-
expect(html.includes('Slide 2'));
|
|
25
|
-
expect(getProgressMax(7, 3) === 7);
|
|
26
|
-
});
|
|
27
|
-
});
|
|
@@ -1,301 +0,0 @@
|
|
|
1
|
-
export const generateThumbnailList = function (carouselComponent): any {
|
|
2
|
-
const thumbnailImages = [];
|
|
3
|
-
|
|
4
|
-
Array.from(carouselComponent.querySelectorAll(':scope > :is(div,iam-card)')).forEach((slide, index) => {
|
|
5
|
-
if (slide.hasAttribute('data-thumbnail')) {
|
|
6
|
-
thumbnailImages[index] = slide.getAttribute('data-thumbnail');
|
|
7
|
-
}
|
|
8
|
-
});
|
|
9
|
-
|
|
10
|
-
return thumbnailImages;
|
|
11
|
-
};
|
|
12
|
-
|
|
13
|
-
export const generatePipsHTML = function (carouselComponent, thumbnailImages): string {
|
|
14
|
-
const itemCount = carouselComponent.querySelectorAll(':scope > :is(div,iam-card)').length;
|
|
15
|
-
|
|
16
|
-
let pips = '';
|
|
17
|
-
for (let i = 1; i <= itemCount; i++) {
|
|
18
|
-
let pipContent = null;
|
|
19
|
-
let pipClass = '';
|
|
20
|
-
|
|
21
|
-
if (thumbnailImages.length && thumbnailImages[i - 1]) {
|
|
22
|
-
pipClass = 'has-thumbnail';
|
|
23
|
-
pipContent = `<img src="${thumbnailImages[i - 1]}" alt="Slide ${i}" height="148"/>`;
|
|
24
|
-
} else {
|
|
25
|
-
pipContent = `Slide ${i}`;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
pips += `<button class="control-${i} ${pipClass}" data-slide="${i}" ${i == 1 ? 'aria-current' : ''}>${pipContent}</button>`;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
return pips;
|
|
32
|
-
};
|
|
33
|
-
|
|
34
|
-
export const getProgressMax = function (itemCount, visibleItems): number {
|
|
35
|
-
if (visibleItems == 1) {
|
|
36
|
-
return itemCount;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
const max = Math.ceil(itemCount / visibleItems) * visibleItems - visibleItems;
|
|
40
|
-
|
|
41
|
-
return max + 1;
|
|
42
|
-
};
|
|
43
|
-
|
|
44
|
-
const getProgressPercent = function (value, max): number {
|
|
45
|
-
return ((value - 1) / (max - 1)) * 100;
|
|
46
|
-
};
|
|
47
|
-
|
|
48
|
-
export const carousel = function (carouselComponent): void {
|
|
49
|
-
let scrollTimeout;
|
|
50
|
-
|
|
51
|
-
const carouselElement = carouselComponent.shadowRoot.querySelector('.carousel');
|
|
52
|
-
|
|
53
|
-
const carouselInner = carouselElement.querySelector('.carousel__inner');
|
|
54
|
-
const carouselControls = carouselElement.querySelector('.carousel__controls');
|
|
55
|
-
const carouselProgress = carouselElement.querySelector('.carousel__progress [type="range"]');
|
|
56
|
-
const itemCount = carouselComponent.querySelectorAll(':scope > :is(div,iam-card)').length;
|
|
57
|
-
let scrollArea = carouselInner.clientWidth;
|
|
58
|
-
let itemWidth = carouselComponent.querySelector(':scope > :is(div,iam-card)').scrollWidth;
|
|
59
|
-
let visibleItems = Math.round(scrollArea / itemWidth);
|
|
60
|
-
|
|
61
|
-
carouselProgress.setAttribute('min', 1);
|
|
62
|
-
carouselProgress.setAttribute('step', visibleItems);
|
|
63
|
-
|
|
64
|
-
let progressMax = getProgressMax(itemCount, visibleItems);
|
|
65
|
-
|
|
66
|
-
carouselProgress.setAttribute('max', progressMax);
|
|
67
|
-
carouselProgress.value = 1;
|
|
68
|
-
|
|
69
|
-
let percent = getProgressPercent(1, progressMax);
|
|
70
|
-
|
|
71
|
-
carouselProgress.style.setProperty('--percent', percent + '%');
|
|
72
|
-
|
|
73
|
-
let stepperInterval,
|
|
74
|
-
stepperEvent = 'mouseup',
|
|
75
|
-
stepperStart = 'mousedown';
|
|
76
|
-
|
|
77
|
-
if ('ontouchstart' in document.documentElement) {
|
|
78
|
-
stepperEvent = 'touchend';
|
|
79
|
-
stepperStart = 'touchstart';
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
// On scroll we need to make sure the buttons get corrected and the next testimonial is shown
|
|
83
|
-
carouselInner.addEventListener(
|
|
84
|
-
'scroll',
|
|
85
|
-
function () {
|
|
86
|
-
clearTimeout(scrollTimeout);
|
|
87
|
-
scrollTimeout = setTimeout(function () {
|
|
88
|
-
const scrollArea = carouselInner.clientWidth;
|
|
89
|
-
const scrollWidth = carouselInner.scrollWidth;
|
|
90
|
-
const scrollLeft = carouselInner.scrollLeft;
|
|
91
|
-
let targetSlide = Math.round((scrollLeft / scrollWidth) * itemCount) + 1;
|
|
92
|
-
|
|
93
|
-
const itemWidth = carouselComponent.querySelector(':scope > :is(div,iam-card)').scrollWidth;
|
|
94
|
-
const lastItemOffset = carouselComponent.querySelector(':scope > :is(div,iam-card):last-child').offsetLeft;
|
|
95
|
-
//+60px here is to account for when the next offscreen slide is visible beneath the next arrow
|
|
96
|
-
const lastItemInView =
|
|
97
|
-
carouselInner.scrollLeft + scrollArea + carouselInner.getBoundingClientRect().left >= lastItemOffset + 60;
|
|
98
|
-
|
|
99
|
-
const visibleItems = Math.round(scrollArea / itemWidth);
|
|
100
|
-
|
|
101
|
-
//Check if theres room for more slides than we have
|
|
102
|
-
const leftOverSpace = Math.ceil(itemCount / visibleItems) * visibleItems - itemCount;
|
|
103
|
-
|
|
104
|
-
carouselProgress.setAttribute('step', visibleItems);
|
|
105
|
-
|
|
106
|
-
if (leftOverSpace > 0 && lastItemInView) {
|
|
107
|
-
targetSlide = Math.floor(itemCount / visibleItems) * visibleItems + 1;
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
Array.from(carouselElement.querySelectorAll('.carousel__controls button')).forEach((button) => {
|
|
111
|
-
button.removeAttribute('aria-current');
|
|
112
|
-
});
|
|
113
|
-
|
|
114
|
-
carouselElement.querySelector('.control-' + targetSlide).setAttribute('aria-current', true);
|
|
115
|
-
|
|
116
|
-
// Disable the previous button
|
|
117
|
-
if (targetSlide == 1) carouselElement.querySelector('.btn-prev').setAttribute('disabled', 'disabled');
|
|
118
|
-
else carouselElement.querySelector('.btn-prev').removeAttribute('disabled');
|
|
119
|
-
|
|
120
|
-
// Disable the next button if the last item is in view
|
|
121
|
-
if (targetSlide > itemCount - visibleItems)
|
|
122
|
-
carouselElement.querySelector('.btn-next').setAttribute('disabled', 'disabled');
|
|
123
|
-
else carouselElement.querySelector('.btn-next').removeAttribute('disabled');
|
|
124
|
-
|
|
125
|
-
carouselProgress.value = targetSlide;
|
|
126
|
-
|
|
127
|
-
progressMax = getProgressMax(itemCount, visibleItems);
|
|
128
|
-
|
|
129
|
-
carouselProgress.setAttribute('max', progressMax);
|
|
130
|
-
percent = (targetSlide / progressMax) * 100;
|
|
131
|
-
percent = getProgressPercent(targetSlide, progressMax);
|
|
132
|
-
carouselProgress.style.setProperty('--percent', percent + '%');
|
|
133
|
-
}, 100);
|
|
134
|
-
},
|
|
135
|
-
false
|
|
136
|
-
);
|
|
137
|
-
|
|
138
|
-
// when the buttons are used we need to make sure the carousel scrolls to the correct place
|
|
139
|
-
carouselControls.addEventListener(
|
|
140
|
-
'click',
|
|
141
|
-
function (e) {
|
|
142
|
-
for (let target = e.target; target && target != this; target = target.parentNode) {
|
|
143
|
-
if (typeof target.matches == 'function' && target.matches('button')) {
|
|
144
|
-
e.preventDefault();
|
|
145
|
-
|
|
146
|
-
Array.from(carouselControls.querySelectorAll('button')).forEach((button) => {
|
|
147
|
-
button.removeAttribute('aria-current');
|
|
148
|
-
});
|
|
149
|
-
target.setAttribute('aria-current', true);
|
|
150
|
-
|
|
151
|
-
const customEvent = new CustomEvent('pip-clicked', {
|
|
152
|
-
detail: {
|
|
153
|
-
slide: target.getAttribute('data-slide'),
|
|
154
|
-
},
|
|
155
|
-
});
|
|
156
|
-
|
|
157
|
-
carouselComponent.dispatchEvent(customEvent);
|
|
158
|
-
|
|
159
|
-
const el = carouselComponent.querySelector(`:scope > *:nth-child(${target.getAttribute('data-slide')})`);
|
|
160
|
-
|
|
161
|
-
carouselInner.scroll({
|
|
162
|
-
top: 0,
|
|
163
|
-
left: el.offsetLeft - carouselInner.getBoundingClientRect().left,
|
|
164
|
-
behavior: 'smooth',
|
|
165
|
-
});
|
|
166
|
-
|
|
167
|
-
break;
|
|
168
|
-
}
|
|
169
|
-
}
|
|
170
|
-
},
|
|
171
|
-
false
|
|
172
|
-
);
|
|
173
|
-
|
|
174
|
-
carouselElement.addEventListener(
|
|
175
|
-
'click',
|
|
176
|
-
function (e) {
|
|
177
|
-
const scrollArea = carouselInner.clientWidth;
|
|
178
|
-
//const scrollWidth = carouselInner.scrollWidth;
|
|
179
|
-
const itemWidth = carouselComponent.querySelector(':scope > :is(div,iam-card)').scrollWidth;
|
|
180
|
-
|
|
181
|
-
const visibleItems = Math.round(scrollArea / itemWidth);
|
|
182
|
-
|
|
183
|
-
const lastItemOffset = carouselComponent.querySelector(':scope > :is(div,iam-card):last-child').offsetLeft;
|
|
184
|
-
const lastItemInView =
|
|
185
|
-
carouselInner.scrollLeft + scrollArea + carouselInner.getBoundingClientRect().left >= lastItemOffset + 60;
|
|
186
|
-
|
|
187
|
-
//Check if theres room for more slides than we have
|
|
188
|
-
const leftOverSpace = Math.ceil(itemCount / visibleItems) * visibleItems - itemCount;
|
|
189
|
-
|
|
190
|
-
/*
|
|
191
|
-
When the last slide isn't filled with items, we only want to move back the number of items on the slide,
|
|
192
|
-
rather than the total number of possible visible items
|
|
193
|
-
*/
|
|
194
|
-
const spacesToMove = visibleItems - leftOverSpace;
|
|
195
|
-
|
|
196
|
-
//Only want to change the amount of movement if the last item is visible
|
|
197
|
-
const movement = lastItemInView && leftOverSpace > 0 ? spacesToMove * itemWidth : carouselInner.clientWidth;
|
|
198
|
-
|
|
199
|
-
for (let target = e.target; target && target != this; target = target.parentNode) {
|
|
200
|
-
if (typeof target.matches == 'function' && target.matches('.btn-next, .btn-prev')) {
|
|
201
|
-
const direction = target.matches('.btn-next') ? 'next' : 'prev';
|
|
202
|
-
|
|
203
|
-
const customEvent = new CustomEvent(`${direction}-clicked`, {
|
|
204
|
-
detail: {
|
|
205
|
-
slide: target.getAttribute('data-go'),
|
|
206
|
-
},
|
|
207
|
-
});
|
|
208
|
-
|
|
209
|
-
carouselComponent.dispatchEvent(customEvent);
|
|
210
|
-
|
|
211
|
-
e.preventDefault();
|
|
212
|
-
const scrollTo = target.classList.contains('btn-prev')
|
|
213
|
-
? carouselInner.scrollLeft - movement
|
|
214
|
-
: carouselInner.scrollLeft + carouselInner.clientWidth;
|
|
215
|
-
|
|
216
|
-
carouselInner.scroll({
|
|
217
|
-
top: 0,
|
|
218
|
-
left: scrollTo,
|
|
219
|
-
behavior: 'smooth',
|
|
220
|
-
});
|
|
221
|
-
break;
|
|
222
|
-
}
|
|
223
|
-
}
|
|
224
|
-
},
|
|
225
|
-
false
|
|
226
|
-
);
|
|
227
|
-
|
|
228
|
-
carouselProgress.addEventListener(stepperStart, function () {
|
|
229
|
-
clearInterval(stepperInterval);
|
|
230
|
-
stepperInterval = setInterval(function () {
|
|
231
|
-
scrollArea = carouselInner.clientWidth;
|
|
232
|
-
itemWidth = carouselComponent.querySelector(':scope > :is(div,iam-card)').scrollWidth;
|
|
233
|
-
visibleItems = Math.round(scrollArea / itemWidth);
|
|
234
|
-
carouselProgress.setAttribute('step', visibleItems);
|
|
235
|
-
progressMax = getProgressMax(itemCount, visibleItems);
|
|
236
|
-
carouselProgress.setAttribute('max', progressMax);
|
|
237
|
-
percent = getProgressPercent(carouselProgress.value, progressMax);
|
|
238
|
-
|
|
239
|
-
carouselProgress.style.setProperty('--percent', percent + '%');
|
|
240
|
-
}, 10);
|
|
241
|
-
});
|
|
242
|
-
|
|
243
|
-
carouselProgress.addEventListener(stepperEvent, function () {
|
|
244
|
-
clearInterval(stepperInterval);
|
|
245
|
-
});
|
|
246
|
-
|
|
247
|
-
carouselProgress.addEventListener(
|
|
248
|
-
'change',
|
|
249
|
-
function () {
|
|
250
|
-
clearInterval(stepperInterval);
|
|
251
|
-
const target = carouselComponent.querySelector(`:scope > *:nth-child(${carouselProgress.value})`);
|
|
252
|
-
|
|
253
|
-
carouselInner.scroll({
|
|
254
|
-
top: 0,
|
|
255
|
-
left: target ? target.offsetLeft - carouselInner.getBoundingClientRect().left : 0,
|
|
256
|
-
behavior: 'smooth',
|
|
257
|
-
});
|
|
258
|
-
|
|
259
|
-
//const direction = target.matches('.btn-next') ? 'next' : 'prev';
|
|
260
|
-
|
|
261
|
-
const customEvent = new CustomEvent(`slider-changed`, {
|
|
262
|
-
detail: {
|
|
263
|
-
slide: carouselProgress.value,
|
|
264
|
-
},
|
|
265
|
-
});
|
|
266
|
-
|
|
267
|
-
carouselComponent.dispatchEvent(customEvent);
|
|
268
|
-
},
|
|
269
|
-
false
|
|
270
|
-
);
|
|
271
|
-
};
|
|
272
|
-
|
|
273
|
-
export const updateCarousel = function (carouselComponent): void {
|
|
274
|
-
|
|
275
|
-
const carouselElement = carouselComponent.shadowRoot.querySelector('.carousel');
|
|
276
|
-
const carouselInner = carouselElement.querySelector('.carousel__inner');
|
|
277
|
-
const carouselControls = carouselElement.querySelector('.carousel__controls');
|
|
278
|
-
const carouselProgress = carouselElement.querySelector('.carousel__progress [type="range"]');
|
|
279
|
-
const itemCount = carouselComponent.querySelectorAll(':scope > :is(div,iam-card)').length;
|
|
280
|
-
|
|
281
|
-
let scrollArea = carouselInner.clientWidth;
|
|
282
|
-
let itemWidth = carouselComponent.querySelector(':scope > :is(div,iam-card)').scrollWidth;
|
|
283
|
-
let visibleItems = Math.round(scrollArea / itemWidth);
|
|
284
|
-
|
|
285
|
-
carouselProgress.setAttribute('min', 1);
|
|
286
|
-
carouselProgress.setAttribute('step', visibleItems);
|
|
287
|
-
|
|
288
|
-
let progressMax = getProgressMax(itemCount, visibleItems);
|
|
289
|
-
|
|
290
|
-
carouselProgress.setAttribute('max', progressMax);
|
|
291
|
-
carouselProgress.value = 1;
|
|
292
|
-
|
|
293
|
-
let percent = getProgressPercent(1, progressMax);
|
|
294
|
-
|
|
295
|
-
carouselProgress.style.setProperty('--percent', percent + '%');
|
|
296
|
-
|
|
297
|
-
carouselControls.innerHTML = generatePipsHTML(carouselComponent, []);
|
|
298
|
-
|
|
299
|
-
}
|
|
300
|
-
|
|
301
|
-
export default carousel;
|