@ulu/frontend 0.0.3
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/LICENSE +21 -0
- package/README.md +9 -0
- package/dist/ulu-frontend.min.css +1 -0
- package/dist/ulu-frontend.min.js +1 -0
- package/index.js +2 -0
- package/js/deprecated/doc-ready.js +28 -0
- package/js/deprecated/jquery-prototypes.js +309 -0
- package/js/deprecated/mini-collapsible-popper-positioning.js +126 -0
- package/js/deprecated/mini-collapsible.js +607 -0
- package/js/deprecated/script-loader.js +60 -0
- package/js/events/index.js +42 -0
- package/js/helpers/css-breakpoint.js +247 -0
- package/js/helpers/file-save.js +48 -0
- package/js/helpers/node-data-manager.js +74 -0
- package/js/helpers/pause-youtube-video.js +42 -0
- package/js/helpers/scrollbar-width-property.js +10 -0
- package/js/index.js +15 -0
- package/js/polyfills/element-closest.js +17 -0
- package/js/ui/flipcard.js +202 -0
- package/js/ui/grid.js +67 -0
- package/js/ui/modals.js +219 -0
- package/js/ui/overflow-scroller-pager.js +58 -0
- package/js/ui/overflow-scroller.js +160 -0
- package/js/ui/programmatic-modal.js +91 -0
- package/js/ui/resizer.js +60 -0
- package/js/ui/slider.js +468 -0
- package/js/ui/tabs.js +109 -0
- package/js/ui/tooltip.js +82 -0
- package/js/utils/array.js +28 -0
- package/js/utils/dom.js +122 -0
- package/js/utils/logger.js +69 -0
- package/js/utils/object.js +22 -0
- package/js/utils/performance.js +43 -0
- package/js/utils/regex.js +10 -0
- package/js/utils/string.js +107 -0
- package/js/waypoints/README.md +3 -0
- package/js/waypoints/anchor-menu.js +76 -0
- package/js/waypoints/element-waypoint.js +75 -0
- package/js/waypoints/examples/page-link-menu.md +106 -0
- package/js/waypoints/state-in-attribute.js +32 -0
- package/package.json +38 -0
- package/scss/README.md +58 -0
- package/scss/_breakpoint.scss +190 -0
- package/scss/_button.scss +241 -0
- package/scss/_calculate.scss +64 -0
- package/scss/_color.scss +211 -0
- package/scss/_cssvar.scss +116 -0
- package/scss/_element.scss +276 -0
- package/scss/_grid.scss +699 -0
- package/scss/_index.scss +29 -0
- package/scss/_layout.scss +202 -0
- package/scss/_path.scss +58 -0
- package/scss/_selector.scss +81 -0
- package/scss/_typography.scss +320 -0
- package/scss/_units.scss +47 -0
- package/scss/_utility.scss +12 -0
- package/scss/_utils.scss +209 -0
- package/scss/base/_color.scss +13 -0
- package/scss/base/_elements.scss +188 -0
- package/scss/base/_index.scss +62 -0
- package/scss/base/_keyframes.scss +78 -0
- package/scss/base/_layout.scss +100 -0
- package/scss/base/_normalize.scss +315 -0
- package/scss/base/_typography.scss +41 -0
- package/scss/components/README.md +5 -0
- package/scss/components/README.todos +15 -0
- package/scss/components/_button.scss +95 -0
- package/scss/components/_index.scss +63 -0
- package/scss/components/_links.scss +34 -0
- package/scss/components/_list-lines.scss +73 -0
- package/scss/components/_list-ordered.scss +16 -0
- package/scss/components/_list-unordered.scss +21 -0
- package/scss/components/_rule.scss +93 -0
- package/scss/helpers/_color.scss +14 -0
- package/scss/helpers/_display.scss +73 -0
- package/scss/helpers/_index.scss +67 -0
- package/scss/helpers/_print.scss +58 -0
- package/scss/helpers/_typography.scss +80 -0
- package/scss/helpers/_units.scss +79 -0
- package/scss/helpers/_utilities.scss +102 -0
- package/scss/stylesheets/README.md +3 -0
- package/scss/stylesheets/full.scss +17 -0
- package/trash/js-old/deprecated/doc-ready.js +28 -0
- package/trash/js-old/deprecated/jquery-prototypes.js +309 -0
- package/trash/js-old/deprecated/mini-collapsible-popper-positioning.js +126 -0
- package/trash/js-old/deprecated/mini-collapsible.js +607 -0
- package/trash/js-old/deprecated/script-loader.js +60 -0
- package/trash/js-old/events/index.js +42 -0
- package/trash/js-old/helpers/css-breakpoint.js +247 -0
- package/trash/js-old/helpers/file-save.js +48 -0
- package/trash/js-old/helpers/node-data-manager.js +74 -0
- package/trash/js-old/helpers/pause-youtube-video.js +42 -0
- package/trash/js-old/index.js +15 -0
- package/trash/js-old/polyfills/element-closest.js +17 -0
- package/trash/js-old/ui/flipcard.js +202 -0
- package/trash/js-old/ui/grid.js +67 -0
- package/trash/js-old/ui/modals.js +219 -0
- package/trash/js-old/ui/programmatic-modal.js +91 -0
- package/trash/js-old/ui/resizer.js +60 -0
- package/trash/js-old/ui/slider.js +469 -0
- package/trash/js-old/ui/tabs.js +109 -0
- package/trash/js-old/ui/tooltip.js +82 -0
- package/trash/js-old/utils/array.js +28 -0
- package/trash/js-old/utils/dom.js +122 -0
- package/trash/js-old/utils/logger.js +69 -0
- package/trash/js-old/utils/object.js +22 -0
- package/trash/js-old/utils/performance.js +43 -0
- package/trash/js-old/utils/regex.js +10 -0
- package/trash/js-old/utils/string.js +107 -0
- package/trash/js-old/waypoints/README.md +3 -0
- package/trash/js-old/waypoints/anchor-menu.js +76 -0
- package/trash/js-old/waypoints/element-waypoint.js +75 -0
- package/trash/js-old/waypoints/examples/page-link-menu.md +106 -0
- package/trash/js-old/waypoints/state-in-attribute.js +32 -0
- package/trash/js-old-230729/deprecated/doc-ready.js +28 -0
- package/trash/js-old-230729/deprecated/jquery-prototypes.js +309 -0
- package/trash/js-old-230729/deprecated/mini-collapsible-popper-positioning.js +126 -0
- package/trash/js-old-230729/deprecated/mini-collapsible.js +607 -0
- package/trash/js-old-230729/deprecated/script-loader.js +60 -0
- package/trash/js-old-230729/events/index.js +42 -0
- package/trash/js-old-230729/helpers/css-breakpoint.js +247 -0
- package/trash/js-old-230729/helpers/file-save.js +48 -0
- package/trash/js-old-230729/helpers/node-data-manager.js +74 -0
- package/trash/js-old-230729/helpers/pause-youtube-video.js +42 -0
- package/trash/js-old-230729/helpers/scrollbar-width-property.js +10 -0
- package/trash/js-old-230729/index.js +15 -0
- package/trash/js-old-230729/polyfills/element-closest.js +17 -0
- package/trash/js-old-230729/ui/flipcard.js +202 -0
- package/trash/js-old-230729/ui/grid.js +67 -0
- package/trash/js-old-230729/ui/modals.js +219 -0
- package/trash/js-old-230729/ui/overflow-scroller-pager.js +58 -0
- package/trash/js-old-230729/ui/overflow-scroller.js +160 -0
- package/trash/js-old-230729/ui/programmatic-modal.js +91 -0
- package/trash/js-old-230729/ui/resizer.js +60 -0
- package/trash/js-old-230729/ui/slider.js +468 -0
- package/trash/js-old-230729/ui/tabs.js +109 -0
- package/trash/js-old-230729/ui/tooltip.js +82 -0
- package/trash/js-old-230729/utils/array.js +28 -0
- package/trash/js-old-230729/utils/dom.js +122 -0
- package/trash/js-old-230729/utils/logger.js +69 -0
- package/trash/js-old-230729/utils/object.js +22 -0
- package/trash/js-old-230729/utils/performance.js +43 -0
- package/trash/js-old-230729/utils/regex.js +10 -0
- package/trash/js-old-230729/utils/string.js +107 -0
- package/trash/js-old-230729/waypoints/README.md +3 -0
- package/trash/js-old-230729/waypoints/anchor-menu.js +76 -0
- package/trash/js-old-230729/waypoints/element-waypoint.js +75 -0
- package/trash/js-old-230729/waypoints/examples/page-link-menu.md +106 -0
- package/trash/js-old-230729/waypoints/state-in-attribute.js +32 -0
- package/trash/logo-1.svg +13 -0
- package/trash/logo.svg +16 -0
- package/trash/scss-before-cqc-update/README.md +58 -0
- package/trash/scss-before-cqc-update/_breakpoint.scss +190 -0
- package/trash/scss-before-cqc-update/_button.scss +229 -0
- package/trash/scss-before-cqc-update/_calculate.scss +65 -0
- package/trash/scss-before-cqc-update/_color.scss +211 -0
- package/trash/scss-before-cqc-update/_cssvar.scss +116 -0
- package/trash/scss-before-cqc-update/_element.scss +275 -0
- package/trash/scss-before-cqc-update/_index.scss +29 -0
- package/trash/scss-before-cqc-update/_layout.scss +247 -0
- package/trash/scss-before-cqc-update/_path.scss +59 -0
- package/trash/scss-before-cqc-update/_selector.scss +82 -0
- package/trash/scss-before-cqc-update/_typography.scss +322 -0
- package/trash/scss-before-cqc-update/_units.scss +48 -0
- package/trash/scss-before-cqc-update/_utility.scss +13 -0
- package/trash/scss-before-cqc-update/_utils.scss +211 -0
- package/trash/scss-before-cqc-update/base/_color.scss +14 -0
- package/trash/scss-before-cqc-update/base/_elements.scss +189 -0
- package/trash/scss-before-cqc-update/base/_index.scss +63 -0
- package/trash/scss-before-cqc-update/base/_keyframes.scss +74 -0
- package/trash/scss-before-cqc-update/base/_layout.scss +88 -0
- package/trash/scss-before-cqc-update/base/_normalize.scss +316 -0
- package/trash/scss-before-cqc-update/base/_typography.scss +42 -0
- package/trash/scss-before-cqc-update/components/README.md +5 -0
- package/trash/scss-before-cqc-update/components/README.todos +15 -0
- package/trash/scss-before-cqc-update/components/_button.scss +96 -0
- package/trash/scss-before-cqc-update/components/_grid.scss +671 -0
- package/trash/scss-before-cqc-update/components/_index.scss +70 -0
- package/trash/scss-before-cqc-update/components/_links.scss +35 -0
- package/trash/scss-before-cqc-update/components/_list-lines.scss +74 -0
- package/trash/scss-before-cqc-update/components/_list-ordered.scss +17 -0
- package/trash/scss-before-cqc-update/components/_list-unordered.scss +22 -0
- package/trash/scss-before-cqc-update/components/_rule.scss +94 -0
- package/trash/scss-before-cqc-update/helpers/_color.scss +15 -0
- package/trash/scss-before-cqc-update/helpers/_display.scss +73 -0
- package/trash/scss-before-cqc-update/helpers/_index.scss +68 -0
- package/trash/scss-before-cqc-update/helpers/_print.scss +59 -0
- package/trash/scss-before-cqc-update/helpers/_typography.scss +73 -0
- package/trash/scss-before-cqc-update/helpers/_units.scss +79 -0
- package/trash/scss-before-cqc-update/helpers/_utilities.scss +88 -0
- package/trash/scss-before-cqc-update/stylesheets/README.md +3 -0
- package/trash/scss-before-cqc-update/stylesheets/full.scss +17 -0
- package/trash/scss-old/README.md +58 -0
- package/trash/scss-old/_breakpoint.scss +140 -0
- package/trash/scss-old/_button.scss +223 -0
- package/trash/scss-old/_calculate.scss +64 -0
- package/trash/scss-old/_color.scss +200 -0
- package/trash/scss-old/_element.scss +262 -0
- package/trash/scss-old/_grid.scss +558 -0
- package/trash/scss-old/_index.scss +25 -0
- package/trash/scss-old/_layout.scss +170 -0
- package/trash/scss-old/_path.scss +58 -0
- package/trash/scss-old/_selector.scss +81 -0
- package/trash/scss-old/_typography.scss +320 -0
- package/trash/scss-old/_units.scss +47 -0
- package/trash/scss-old/_utility.scss +12 -0
- package/trash/scss-old/_utils.scss +186 -0
- package/trash/scss-old/base/_color.scss +13 -0
- package/trash/scss-old/base/_elements.scss +183 -0
- package/trash/scss-old/base/_index.scss +62 -0
- package/trash/scss-old/base/_keyframes.scss +74 -0
- package/trash/scss-old/base/_layout.scss +81 -0
- package/trash/scss-old/base/_normalize.scss +316 -0
- package/trash/scss-old/base/_typography.scss +42 -0
- package/trash/scss-old/components/README.md +5 -0
- package/trash/scss-old/components/README.todos +15 -0
- package/trash/scss-old/components/_button.scss +74 -0
- package/trash/scss-old/components/_index.scss +63 -0
- package/trash/scss-old/components/_links.scss +34 -0
- package/trash/scss-old/components/_list-lines.scss +73 -0
- package/trash/scss-old/components/_list-ordered.scss +16 -0
- package/trash/scss-old/components/_list-unordered.scss +21 -0
- package/trash/scss-old/components/_rule.scss +84 -0
- package/trash/scss-old/helpers/_color.scss +14 -0
- package/trash/scss-old/helpers/_display.scss +68 -0
- package/trash/scss-old/helpers/_index.scss +67 -0
- package/trash/scss-old/helpers/_print.scss +59 -0
- package/trash/scss-old/helpers/_typography.scss +73 -0
- package/trash/scss-old/helpers/_units.scss +68 -0
- package/trash/scss-old/helpers/_utilities.scss +82 -0
- package/trash/scss-old/packages/README.md +3 -0
- package/trash/scss-old/packages/everything.scss +17 -0
- package/trash/scss-old-2/README.md +58 -0
- package/trash/scss-old-2/_breakpoint.scss +139 -0
- package/trash/scss-old-2/_button.scss +223 -0
- package/trash/scss-old-2/_calculate.scss +64 -0
- package/trash/scss-old-2/_color.scss +202 -0
- package/trash/scss-old-2/_element.scss +263 -0
- package/trash/scss-old-2/_grid.scss +558 -0
- package/trash/scss-old-2/_index.scss +25 -0
- package/trash/scss-old-2/_layout.scss +170 -0
- package/trash/scss-old-2/_path.scss +58 -0
- package/trash/scss-old-2/_selector.scss +81 -0
- package/trash/scss-old-2/_typography.scss +320 -0
- package/trash/scss-old-2/_units.scss +47 -0
- package/trash/scss-old-2/_utility.scss +12 -0
- package/trash/scss-old-2/_utils.scss +186 -0
- package/trash/scss-old-2/base/_color.scss +13 -0
- package/trash/scss-old-2/base/_elements.scss +182 -0
- package/trash/scss-old-2/base/_index.scss +62 -0
- package/trash/scss-old-2/base/_keyframes.scss +73 -0
- package/trash/scss-old-2/base/_layout.scss +83 -0
- package/trash/scss-old-2/base/_normalize.scss +315 -0
- package/trash/scss-old-2/base/_typography.scss +41 -0
- package/trash/scss-old-2/components/README.md +5 -0
- package/trash/scss-old-2/components/README.todos +15 -0
- package/trash/scss-old-2/components/_button.scss +95 -0
- package/trash/scss-old-2/components/_index.scss +63 -0
- package/trash/scss-old-2/components/_links.scss +33 -0
- package/trash/scss-old-2/components/_list-lines.scss +73 -0
- package/trash/scss-old-2/components/_list-ordered.scss +16 -0
- package/trash/scss-old-2/components/_list-unordered.scss +21 -0
- package/trash/scss-old-2/components/_rule.scss +84 -0
- package/trash/scss-old-2/helpers/_color.scss +14 -0
- package/trash/scss-old-2/helpers/_display.scss +67 -0
- package/trash/scss-old-2/helpers/_index.scss +67 -0
- package/trash/scss-old-2/helpers/_print.scss +58 -0
- package/trash/scss-old-2/helpers/_typography.scss +72 -0
- package/trash/scss-old-2/helpers/_units.scss +68 -0
- package/trash/scss-old-2/helpers/_utilities.scss +81 -0
- package/trash/scss-old-2/packages/README.md +3 -0
- package/trash/scss-old-2/packages/everything.scss +17 -0
- package/trash/scss-old-230729/README.md +58 -0
- package/trash/scss-old-230729/_breakpoint.scss +139 -0
- package/trash/scss-old-230729/_button.scss +223 -0
- package/trash/scss-old-230729/_calculate.scss +64 -0
- package/trash/scss-old-230729/_color.scss +202 -0
- package/trash/scss-old-230729/_element.scss +273 -0
- package/trash/scss-old-230729/_grid.scss +694 -0
- package/trash/scss-old-230729/_index.scss +25 -0
- package/trash/scss-old-230729/_layout.scss +193 -0
- package/trash/scss-old-230729/_path.scss +58 -0
- package/trash/scss-old-230729/_selector.scss +81 -0
- package/trash/scss-old-230729/_typography.scss +320 -0
- package/trash/scss-old-230729/_units.scss +47 -0
- package/trash/scss-old-230729/_utility.scss +12 -0
- package/trash/scss-old-230729/_utils.scss +186 -0
- package/trash/scss-old-230729/base/_color.scss +13 -0
- package/trash/scss-old-230729/base/_elements.scss +188 -0
- package/trash/scss-old-230729/base/_index.scss +62 -0
- package/trash/scss-old-230729/base/_keyframes.scss +73 -0
- package/trash/scss-old-230729/base/_layout.scss +83 -0
- package/trash/scss-old-230729/base/_normalize.scss +315 -0
- package/trash/scss-old-230729/base/_typography.scss +41 -0
- package/trash/scss-old-230729/components/README.md +5 -0
- package/trash/scss-old-230729/components/README.todos +15 -0
- package/trash/scss-old-230729/components/_button.scss +95 -0
- package/trash/scss-old-230729/components/_index.scss +63 -0
- package/trash/scss-old-230729/components/_links.scss +34 -0
- package/trash/scss-old-230729/components/_list-lines.scss +73 -0
- package/trash/scss-old-230729/components/_list-ordered.scss +16 -0
- package/trash/scss-old-230729/components/_list-unordered.scss +21 -0
- package/trash/scss-old-230729/components/_rule.scss +93 -0
- package/trash/scss-old-230729/helpers/_color.scss +14 -0
- package/trash/scss-old-230729/helpers/_display.scss +73 -0
- package/trash/scss-old-230729/helpers/_index.scss +67 -0
- package/trash/scss-old-230729/helpers/_print.scss +58 -0
- package/trash/scss-old-230729/helpers/_typography.scss +72 -0
- package/trash/scss-old-230729/helpers/_units.scss +68 -0
- package/trash/scss-old-230729/helpers/_utilities.scss +87 -0
- package/trash/scss-old-230729/packages/README.md +3 -0
- package/trash/scss-old-230729/packages/everything.scss +17 -0
- package/trash/vue/directives/background-image-url.js +12 -0
- package/trash/vue/helpers/add-required-components.js +14 -0
- package/trash/vue/ui/CollapsibleRegion/CollapsibleRegion.vue +277 -0
- package/trash/vue/ui/CollapsibleRegion/Demo.vue +101 -0
- package/trash/vue/ui/Dropdown/Dropdown.vue +184 -0
- package/trash/vue/ui/Modals/components/Modal.vue +49 -0
- package/trash/vue/ui/Modals/components/Modals.vue +103 -0
- package/trash/vue/ui/Modals/plugin.js +215 -0
- package/trash/vue/ui/Modals/readme.note +10 -0
- package/trash/vue/ui/Modals/reference/example-usage.vue +27 -0
- package/trash/vue/ui/Modals/reference/wcag-example/dialog.js +324 -0
package/js/ui/slider.js
ADDED
|
@@ -0,0 +1,468 @@
|
|
|
1
|
+
// =============================================================================
|
|
2
|
+
// Slider
|
|
3
|
+
// =============================================================================
|
|
4
|
+
|
|
5
|
+
// Version: 1.0.10
|
|
6
|
+
|
|
7
|
+
// Changes:
|
|
8
|
+
// 1.0.10 | Fix bug when two and going in reverse
|
|
9
|
+
// 1.0.9 | Fix bug when there are only 2 slides (not sliding correctly [revesers because of switchSlide])
|
|
10
|
+
// this is addressed now and should slide infinitly between two slides
|
|
11
|
+
// 1.0.8 | Change API, to elements object (from individaul arguments),
|
|
12
|
+
// Add the ability to specify the element to append controls within
|
|
13
|
+
// 1.0.6 | Add transition class for changes during transition,
|
|
14
|
+
// add will-change to the transition
|
|
15
|
+
// 1.0.5 | Fix transtion event difference on windows, convert all
|
|
16
|
+
// async stuff to promises and simplify
|
|
17
|
+
// 1.0.4 | Remove live region annoucement (only used if auto rotate)
|
|
18
|
+
|
|
19
|
+
// Reference: https://www.w3.org/WAI/tutorials/carousels/working-example/
|
|
20
|
+
// https://www.w3.org/TR/wai-aria-practices/examples/carousel/carousel-1.html#
|
|
21
|
+
// https://www.w3.org/TR/wai-aria-practices-1.1/examples/carousel/carousel-1.html
|
|
22
|
+
// https://www.accessibilityoz.com/
|
|
23
|
+
// https://www.sitepoint.com/unbearable-accessible-slideshow/
|
|
24
|
+
// https://dev.opera.com/articles/css-will-change-property/
|
|
25
|
+
// * Will Change use
|
|
26
|
+
|
|
27
|
+
import maintain from 'ally.js/maintain/_maintain';
|
|
28
|
+
import { log, logError, logWarning } from "../utils/logger.js";
|
|
29
|
+
import { hasRequiredProps } from '../utils/object.js';
|
|
30
|
+
import { trimWhitespace } from "../utils/string.js";
|
|
31
|
+
import { debounce } from "../utils/performance.js";
|
|
32
|
+
const debugMode = false; // Global dev debug
|
|
33
|
+
const reduceMotion = matchMedia('(prefers-reduced-motion: reduce)').matches;
|
|
34
|
+
const eventOnce = { once: true };
|
|
35
|
+
const cssDuration = d => `${ d }ms`;
|
|
36
|
+
|
|
37
|
+
// Resize handlers for all slider instances, Load event to avoid triggering
|
|
38
|
+
addEventListener('load', () => {
|
|
39
|
+
addEventListener('resize', debounce(() => {
|
|
40
|
+
Slider.instances.forEach(i => i.handleResize());
|
|
41
|
+
}, 250));
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
const requiredElements = [
|
|
45
|
+
"container",
|
|
46
|
+
"trackContainer",
|
|
47
|
+
"track",
|
|
48
|
+
"slides"
|
|
49
|
+
];
|
|
50
|
+
export class Slider {
|
|
51
|
+
static instances = [];
|
|
52
|
+
static defaults = {
|
|
53
|
+
classAccessiblyHidden: "hidden-visually",
|
|
54
|
+
namespace: "Slider",
|
|
55
|
+
events: {},
|
|
56
|
+
transition: true,
|
|
57
|
+
transitionFade: false,
|
|
58
|
+
transitionDuration: 700,
|
|
59
|
+
transitionDurationExit: 400,
|
|
60
|
+
transitionTimingFunction: "ease-in-out",
|
|
61
|
+
|
|
62
|
+
// transition: true
|
|
63
|
+
}
|
|
64
|
+
// constructor(container, title, trackContainer, track, slides, config, debug = false) {
|
|
65
|
+
constructor(elements, config, debug = false) {
|
|
66
|
+
const options = Object.assign({}, Slider.defaults, config);
|
|
67
|
+
this.debug = debugMode || debug;
|
|
68
|
+
this.options = options;
|
|
69
|
+
this.slide = null;
|
|
70
|
+
this.index = null;
|
|
71
|
+
this.transitioning = false;
|
|
72
|
+
|
|
73
|
+
if (!hasRequiredProps(requiredElements)) {
|
|
74
|
+
logError(this, 'Missing a required Element');
|
|
75
|
+
}
|
|
76
|
+
if (!elements.slides.length) {
|
|
77
|
+
logError(this, "Missing slides");
|
|
78
|
+
}
|
|
79
|
+
this.slides = [ ...elements.slides ].map((element, index) => {
|
|
80
|
+
return {
|
|
81
|
+
element,
|
|
82
|
+
index,
|
|
83
|
+
number: index + 1
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
this.elements = {
|
|
87
|
+
...elements,
|
|
88
|
+
...this.createControls(elements.controlContext || elements.container),
|
|
89
|
+
...this.createNav(elements.navContext || elements.container)
|
|
90
|
+
};
|
|
91
|
+
// Choose the appropriate transition method
|
|
92
|
+
this.transition = options.transition ? options.transitionFade || reduceMotion
|
|
93
|
+
? this.fadeTransition : this.slideTransition : this.noTransition;
|
|
94
|
+
this.setup();
|
|
95
|
+
this.goto(0, null, "init");
|
|
96
|
+
log(this, "Slider Instance Created", this);
|
|
97
|
+
Slider.instances.push(this);
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Sliding mechanism needs translate updated on resize
|
|
101
|
+
*/
|
|
102
|
+
handleResize() {
|
|
103
|
+
const { slide, transition, slideTransition} = this;
|
|
104
|
+
if (transition === slideTransition && slide) {
|
|
105
|
+
this.translateTo(slide.element.offsetLeft, 0);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Goto to the previous slide
|
|
110
|
+
*/
|
|
111
|
+
previous(event) {
|
|
112
|
+
const { index: lastIndex, slides } = this;
|
|
113
|
+
const last = slides.length - 1;
|
|
114
|
+
const prev = lastIndex - 1;
|
|
115
|
+
const index = prev < 0 ? last : prev;
|
|
116
|
+
this.emit("previous", [event, index]);
|
|
117
|
+
this.goto(index, event, "previous");
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Goto to the next slide
|
|
121
|
+
*/
|
|
122
|
+
next(event) {
|
|
123
|
+
const { index: lastIndex, slides } = this;
|
|
124
|
+
const next = lastIndex + 1;
|
|
125
|
+
const index = next > slides.length - 1 ? 0 : next;
|
|
126
|
+
this.emit("next", [event, index]);
|
|
127
|
+
this.goto(index, event, "next");
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Makes sure that no matter what the callback is called if transition event
|
|
131
|
+
* doesn't start or fails to finish/cancel
|
|
132
|
+
* @param {number} element
|
|
133
|
+
* @param {number} duration Duration to wait for complete
|
|
134
|
+
* @param {Function} beginTransition Css changes to begin/start transtion
|
|
135
|
+
*/
|
|
136
|
+
ensureTranstionEnds(element, duration, beginTransition) {
|
|
137
|
+
return new Promise(resolve => {
|
|
138
|
+
const tid = {};
|
|
139
|
+
// If the transition has started remove the fallback for start
|
|
140
|
+
// and set one for the end
|
|
141
|
+
const onStart = () => {
|
|
142
|
+
clearTimeout(tid.start);
|
|
143
|
+
tid.end = setTimeout(onComplete, duration + 500);
|
|
144
|
+
};
|
|
145
|
+
// The transition has completed, cleanup and resolve
|
|
146
|
+
const onComplete = () => {
|
|
147
|
+
clearTimeout(tid.start);
|
|
148
|
+
clearTimeout(tid.end);
|
|
149
|
+
element.removeEventListener("transitionrun", onStart, eventOnce);
|
|
150
|
+
element.removeEventListener('transitionend', onComplete, eventOnce);
|
|
151
|
+
element.removeEventListener('transitioncancel', onComplete, eventOnce);
|
|
152
|
+
resolve();
|
|
153
|
+
};
|
|
154
|
+
// Wait for animation to start, also set a timer to ensure that
|
|
155
|
+
// if this event never fires for any reason, the promise will resolve
|
|
156
|
+
element.addEventListener("transitionrun", onStart, eventOnce);
|
|
157
|
+
// If it has started it will be waiting for the end
|
|
158
|
+
// If it never ends for any reason, the promise will resolve
|
|
159
|
+
element.addEventListener('transitionend', onComplete, eventOnce);
|
|
160
|
+
element.addEventListener('transitioncancel', onComplete, eventOnce);
|
|
161
|
+
tid.start = setTimeout(onComplete, duration + 500);
|
|
162
|
+
// Apply users css changes
|
|
163
|
+
element.style.transitionDuration = cssDuration(duration);
|
|
164
|
+
beginTransition();
|
|
165
|
+
// Bypass events if no duration or 0
|
|
166
|
+
if (!duration) {
|
|
167
|
+
onComplete();
|
|
168
|
+
}
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* Translate the track to X
|
|
173
|
+
*/
|
|
174
|
+
translateTo(x, duration) {
|
|
175
|
+
const { track } = this.elements;
|
|
176
|
+
const set = () => track.style.transform = `translateX(-${ x }px)`;
|
|
177
|
+
// tell brwoser we're about to animate
|
|
178
|
+
track.style.willChange = "transform";
|
|
179
|
+
return this.ensureTranstionEnds(track, duration, set).then(() => {
|
|
180
|
+
// Remove to avoid any issues with optimization
|
|
181
|
+
track.style.willChange = "auto";
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* Show's a specifc slide and hides others, except when passing true to show all
|
|
186
|
+
* then all slides will visible
|
|
187
|
+
*/
|
|
188
|
+
setVisibility(activeSlide, showAll) {
|
|
189
|
+
if (!showAll) {
|
|
190
|
+
activeSlide.element.style.visibility = "visible";
|
|
191
|
+
}
|
|
192
|
+
this.slides.forEach(slide => {
|
|
193
|
+
if (slide !== activeSlide) {
|
|
194
|
+
slide.element.style.visibility = showAll ? "visible" : "hidden";
|
|
195
|
+
}
|
|
196
|
+
});
|
|
197
|
+
}
|
|
198
|
+
/**
|
|
199
|
+
* Perform a fade on a single slide
|
|
200
|
+
*/
|
|
201
|
+
fadeSlide(slide, visible) {
|
|
202
|
+
const { options } = this;
|
|
203
|
+
const { element } = slide;
|
|
204
|
+
const duration = visible ? options.transitionDuration : options.transitionDurationExit;
|
|
205
|
+
return this.ensureTranstionEnds(element, duration, () => {
|
|
206
|
+
element.style.opacity = visible ? "1" : "0";
|
|
207
|
+
});
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* Handler for the entire slide transtion
|
|
211
|
+
*/
|
|
212
|
+
async slideTransition({ slide, index, old, oldIndex, triggerType }) {
|
|
213
|
+
const count = this.slides.length;
|
|
214
|
+
const reverse = triggerType === "previous";
|
|
215
|
+
const lastIndex = count - 1;
|
|
216
|
+
const lastToFirst = index === 0 && oldIndex === lastIndex;
|
|
217
|
+
const firstToLast = index === lastIndex && oldIndex === 0;
|
|
218
|
+
let switchSlide;
|
|
219
|
+
let duration = this.options.transitionDuration;
|
|
220
|
+
|
|
221
|
+
// Set duration based on how many slides to traverse
|
|
222
|
+
// First to last or the opposite are single slide animations
|
|
223
|
+
if (oldIndex && !lastToFirst && !firstToLast) {
|
|
224
|
+
duration = duration * Math.abs(oldIndex - index);
|
|
225
|
+
}
|
|
226
|
+
// If first to last or last to first we switch the order of the slides so that
|
|
227
|
+
// They are right next to each other at the front of the list
|
|
228
|
+
// Then perform the animation, Then put them back in their natural place without transitioning
|
|
229
|
+
// so it doesn't move for the user. Note count affects this differently
|
|
230
|
+
|
|
231
|
+
if (count < 3) {
|
|
232
|
+
if (lastToFirst && !reverse) {
|
|
233
|
+
switchSlide = old;
|
|
234
|
+
} else if (firstToLast) {
|
|
235
|
+
switchSlide = reverse ? slide : old;
|
|
236
|
+
}
|
|
237
|
+
} else {
|
|
238
|
+
if (lastToFirst) {
|
|
239
|
+
switchSlide = old;
|
|
240
|
+
} else if (firstToLast) {
|
|
241
|
+
switchSlide = slide;
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
// Set all slides to visible during the animation
|
|
246
|
+
this.setVisibility(null, true);
|
|
247
|
+
|
|
248
|
+
// Put the last item at the front of the list and reset the
|
|
249
|
+
// tracks (or the opposite for first to last)
|
|
250
|
+
if (switchSlide) {
|
|
251
|
+
switchSlide.element.style.order = "-1";
|
|
252
|
+
await this.translateTo(lastToFirst ? 0 : old.element.offsetLeft, 0);
|
|
253
|
+
}
|
|
254
|
+
// Perform the main sliding animation
|
|
255
|
+
await this.translateTo(slide.element.offsetLeft, duration);
|
|
256
|
+
// Set the order back to normal in the end
|
|
257
|
+
// Don't transtion so the slider seems like it doesn't jump/move
|
|
258
|
+
if (switchSlide) {
|
|
259
|
+
switchSlide.element.style.order = "0";
|
|
260
|
+
await this.translateTo(slide.element.offsetLeft, 0);
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
this.setVisibility(slide, false);
|
|
264
|
+
}
|
|
265
|
+
/**
|
|
266
|
+
* Handler for the entire fade transtion
|
|
267
|
+
*/
|
|
268
|
+
async fadeTransition({ slide, old }) {
|
|
269
|
+
this.setVisibility(null, true);
|
|
270
|
+
// Uses order trick to move the current slide
|
|
271
|
+
if (old) {
|
|
272
|
+
await this.fadeSlide(old, false);
|
|
273
|
+
old.element.style.order = "0";
|
|
274
|
+
}
|
|
275
|
+
slide.element.style.order = "-1";
|
|
276
|
+
await this.fadeSlide(slide, true);
|
|
277
|
+
this.setVisibility(slide, false);
|
|
278
|
+
}
|
|
279
|
+
/**
|
|
280
|
+
* Handler for the entire NO transtion
|
|
281
|
+
*/
|
|
282
|
+
noTransition({ slide, old }) {
|
|
283
|
+
this.setVisibility(slide, false);
|
|
284
|
+
if (old) {
|
|
285
|
+
old.element.style.order = "0";
|
|
286
|
+
}
|
|
287
|
+
slide.element.style.order = "-1";
|
|
288
|
+
return Promise.resolve();
|
|
289
|
+
}
|
|
290
|
+
goto(index, event, triggerType) {
|
|
291
|
+
const {
|
|
292
|
+
slide: old,
|
|
293
|
+
index:
|
|
294
|
+
oldIndex,
|
|
295
|
+
slides,
|
|
296
|
+
elements
|
|
297
|
+
} = this;
|
|
298
|
+
const isInit = triggerType === "init";
|
|
299
|
+
const slide = slides[index];
|
|
300
|
+
const activeClass = this.getClass("nav-button--active");
|
|
301
|
+
const transitionClass = this.getClass("transition", true);
|
|
302
|
+
const to = { slide, index, old, oldIndex, triggerType };
|
|
303
|
+
|
|
304
|
+
if (index === oldIndex) {
|
|
305
|
+
logWarning(this, "Could not goto slide, still performing transition");
|
|
306
|
+
return;
|
|
307
|
+
}
|
|
308
|
+
if (this.transitioning) {
|
|
309
|
+
logWarning(this, "Cancel goto(), same slide index as current slide");
|
|
310
|
+
return;
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
// Make all slide interactive elements inert
|
|
314
|
+
const lockInteractives = maintain.disabled({ context: this.elements.track });
|
|
315
|
+
this.transitioning = true;
|
|
316
|
+
// Set classes first just feels better
|
|
317
|
+
if (old) old.navButton.classList.remove(activeClass);
|
|
318
|
+
slide.navButton.classList.add(activeClass);
|
|
319
|
+
elements.container.classList.add(transitionClass);
|
|
320
|
+
// Perform transition and then set state
|
|
321
|
+
this.transition(to).then(() => {
|
|
322
|
+
this.index = index;
|
|
323
|
+
this.slide = slide;
|
|
324
|
+
this.transitioning = false;
|
|
325
|
+
elements.container.classList.remove(transitionClass);
|
|
326
|
+
lockInteractives.disengage();
|
|
327
|
+
if (!isInit) {
|
|
328
|
+
slide.element.focus();
|
|
329
|
+
this.emit("goto", [event, index, slide]);
|
|
330
|
+
}
|
|
331
|
+
});
|
|
332
|
+
}
|
|
333
|
+
setup() {
|
|
334
|
+
const { container, track, trackContainer } = this.elements;
|
|
335
|
+
const trackCss = trimWhitespace(this.trackCss());
|
|
336
|
+
const trackContainerStyles = trimWhitespace(this.trackContainerStyles());
|
|
337
|
+
const slideCss = trimWhitespace(this.slideCss());
|
|
338
|
+
track.setAttribute("style", trackCss);
|
|
339
|
+
trackContainer.setAttribute("style", trackContainerStyles);
|
|
340
|
+
this.slides.forEach(slide => {
|
|
341
|
+
slide.element.setAttribute("style", slideCss);
|
|
342
|
+
slide.element.setAttribute('tabindex', '-1');
|
|
343
|
+
});
|
|
344
|
+
container.classList.add(this.getClass());
|
|
345
|
+
}
|
|
346
|
+
trackContainerStyles() {
|
|
347
|
+
// Crop translated track
|
|
348
|
+
return `
|
|
349
|
+
overflow: hidden;
|
|
350
|
+
`;
|
|
351
|
+
}
|
|
352
|
+
transitionCss(property) {
|
|
353
|
+
const { transitionTimingFunction, transitionDuration } = this.options;
|
|
354
|
+
return `
|
|
355
|
+
transition-property: ${ property };
|
|
356
|
+
transition-duration: ${ cssDuration(transitionDuration) };
|
|
357
|
+
transition-timing-function: ${ transitionTimingFunction };
|
|
358
|
+
`;
|
|
359
|
+
}
|
|
360
|
+
trackCss() {
|
|
361
|
+
// Add in sliding transtion properties when not fade
|
|
362
|
+
return `
|
|
363
|
+
display: flex;
|
|
364
|
+
position: relative;
|
|
365
|
+
list-style: none;
|
|
366
|
+
${ this.transition === this.slideTransition ? this.transitionCss("transform") : "" }
|
|
367
|
+
`;
|
|
368
|
+
}
|
|
369
|
+
slideCss() {
|
|
370
|
+
const fadingTransition = this.transition === this.fadeTransition;
|
|
371
|
+
// Add in fading transtion properties when not slide (which is on the track)
|
|
372
|
+
return `
|
|
373
|
+
width: 100%;
|
|
374
|
+
flex: 0 0 100%;
|
|
375
|
+
${ fadingTransition ? this.transitionCss("opacity") : "" }
|
|
376
|
+
opacity: ${ fadingTransition ? "0" : "1" }
|
|
377
|
+
`;
|
|
378
|
+
}
|
|
379
|
+
getClass(child, modifier) {
|
|
380
|
+
const { namespace } = this.options;
|
|
381
|
+
if (modifier) {
|
|
382
|
+
return `${ namespace }--${ child }`;
|
|
383
|
+
} else if (child) {
|
|
384
|
+
return `${ namespace }__${ child }`;
|
|
385
|
+
} else {
|
|
386
|
+
return namespace;
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
createControlButton(action) {
|
|
390
|
+
const button = document.createElement("button");
|
|
391
|
+
button.classList.add(this.getClass("control-button"));
|
|
392
|
+
button.classList.add(this.getClass(`control-button--${ action }`));
|
|
393
|
+
button.setAttribute("data-slider-control", action);
|
|
394
|
+
button.setAttribute("type", "button");
|
|
395
|
+
button.innerHTML = this.getControlContent(action);
|
|
396
|
+
return button;
|
|
397
|
+
}
|
|
398
|
+
createControls(context) {
|
|
399
|
+
const controls = document.createElement('ul');
|
|
400
|
+
const previousItem = document.createElement("li");
|
|
401
|
+
const nextItem = document.createElement("li");
|
|
402
|
+
const previous = this.createControlButton("previous");
|
|
403
|
+
const next = this.createControlButton("next");
|
|
404
|
+
|
|
405
|
+
controls.classList.add(this.getClass("controls"));
|
|
406
|
+
|
|
407
|
+
previousItem.appendChild(previous);
|
|
408
|
+
nextItem.appendChild(next);
|
|
409
|
+
controls.appendChild(previousItem);
|
|
410
|
+
controls.appendChild(nextItem);
|
|
411
|
+
previous.addEventListener('click', this.previous.bind(this));
|
|
412
|
+
next.addEventListener('click', this.next.bind(this));
|
|
413
|
+
context.appendChild(controls);
|
|
414
|
+
|
|
415
|
+
return {
|
|
416
|
+
controls,
|
|
417
|
+
previousItem,
|
|
418
|
+
nextItem,
|
|
419
|
+
previous,
|
|
420
|
+
next
|
|
421
|
+
};
|
|
422
|
+
}
|
|
423
|
+
createNav(container) {
|
|
424
|
+
const nav = document.createElement("ul");
|
|
425
|
+
const navButtons = this.slides.map(this.createNavButton.bind(this));
|
|
426
|
+
const navItems = navButtons.map(button => {
|
|
427
|
+
const item = document.createElement("li");
|
|
428
|
+
item.appendChild(button);
|
|
429
|
+
// item.setAttribute('tabindex', "-1"); // WHY?
|
|
430
|
+
nav.appendChild(item);
|
|
431
|
+
return item;
|
|
432
|
+
});
|
|
433
|
+
|
|
434
|
+
nav.classList.add(this.getClass("nav"));
|
|
435
|
+
container.appendChild(nav);
|
|
436
|
+
|
|
437
|
+
return {
|
|
438
|
+
nav,
|
|
439
|
+
navButtons,
|
|
440
|
+
navItems
|
|
441
|
+
};
|
|
442
|
+
}
|
|
443
|
+
createNavButton(slide, index) {
|
|
444
|
+
const button = document.createElement("button");
|
|
445
|
+
button.classList.add(this.getClass("nav-button"));
|
|
446
|
+
button.setAttribute("type", "button");
|
|
447
|
+
button.innerHTML = this.getNavContent(slide.number);
|
|
448
|
+
slide.navButton = button; // Add reference to slide object
|
|
449
|
+
button.addEventListener("click", this.goto.bind(this, index));
|
|
450
|
+
return button;
|
|
451
|
+
}
|
|
452
|
+
getControlContent(action) {
|
|
453
|
+
return `
|
|
454
|
+
<span class="hidden-visually">${ action }</span>
|
|
455
|
+
<span aria-hidden="true">${ action === 'next' ? '→' : '←' }</span>
|
|
456
|
+
`;
|
|
457
|
+
}
|
|
458
|
+
getNavContent(number) {
|
|
459
|
+
return `<span class="hidden-visually">Item</span> <span>${ number }</span>`;
|
|
460
|
+
}
|
|
461
|
+
emit(name, args) {
|
|
462
|
+
if (this.options.events[name]) {
|
|
463
|
+
this.options.events[name].apply(this, args);
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
export default Slider;
|
package/js/ui/tabs.js
ADDED
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
// =============================================================================
|
|
2
|
+
// Tabs
|
|
3
|
+
// =============================================================================
|
|
4
|
+
//
|
|
5
|
+
// Version: 1.0.1
|
|
6
|
+
//
|
|
7
|
+
// Selected by: [data-site-tablist]
|
|
8
|
+
//
|
|
9
|
+
// Possible options (passed in attribute JSON)
|
|
10
|
+
// - openByUrlHash | Optionally add "openByUrlHash" to
|
|
11
|
+
// have the scriptopen a tab and focus it on page load
|
|
12
|
+
// (and set it in history as they navigate)
|
|
13
|
+
|
|
14
|
+
import AriaTablist from 'aria-tablist';
|
|
15
|
+
|
|
16
|
+
const errorHeader = "Site Tablist [data-site-tablist] error:";
|
|
17
|
+
const instances = [];
|
|
18
|
+
// Init all instances currently in page
|
|
19
|
+
window.addEventListener("load", () => {
|
|
20
|
+
initWithin(document);
|
|
21
|
+
// Run this on page load, optionally exported for use when page is running
|
|
22
|
+
instances.forEach(openByCurrentHash);
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
// Initialize when page updates/changes
|
|
26
|
+
document.addEventListener('pageModified', e => initWithin(e.target));
|
|
27
|
+
|
|
28
|
+
function initWithin(context) {
|
|
29
|
+
if (!context) return;
|
|
30
|
+
const tablists = context.querySelectorAll('[data-site-tablist]');
|
|
31
|
+
tablists.forEach(init);
|
|
32
|
+
}
|
|
33
|
+
function openByCurrentHash({ options, ariaTablist }) {
|
|
34
|
+
if (options.openByUrlHash) {
|
|
35
|
+
const { hash } = window.location;
|
|
36
|
+
if (hash && hash.length > 1) {
|
|
37
|
+
const possibleId = hash.substring(1);
|
|
38
|
+
ariaTablist.tabs.forEach(tab => {
|
|
39
|
+
if (possibleId === tab.id) {
|
|
40
|
+
ariaTablist.open(tab);
|
|
41
|
+
}
|
|
42
|
+
})
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
function init(element) {
|
|
47
|
+
let options = {};
|
|
48
|
+
const config = {};
|
|
49
|
+
|
|
50
|
+
if (element.dataset.siteTablist) {
|
|
51
|
+
try {
|
|
52
|
+
options = JSON.parse(element.dataset.siteTablist);
|
|
53
|
+
} catch(e) {
|
|
54
|
+
console.error(errorHeader, "(JSON Parse for options)", element);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
if (options.vertical) {
|
|
58
|
+
config.allArrows = true;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// Need to render the markup before checking height
|
|
62
|
+
// - used to wait until images had loaded
|
|
63
|
+
ready();
|
|
64
|
+
|
|
65
|
+
if (options.equalHeights) {
|
|
66
|
+
setHeights(element);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
function ready() {
|
|
70
|
+
const instance = { element, options };
|
|
71
|
+
instance.ariaTablist = AriaTablist(element, {
|
|
72
|
+
onOpen(...args) {
|
|
73
|
+
args.unshift(instance);
|
|
74
|
+
handleOpen.apply(null, args);
|
|
75
|
+
},
|
|
76
|
+
...config
|
|
77
|
+
});
|
|
78
|
+
instances.push(instance);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
function handleOpen({ options }, panel, tab) {
|
|
82
|
+
if (options.openByUrlHash && window.history) {
|
|
83
|
+
window.history.replaceState(null, "", `#${ tab.id }`);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
function setHeights(element) {
|
|
87
|
+
const tabs = [ ...element.children];
|
|
88
|
+
const panels = tabs.map(n => document.querySelector(`[aria-labelledby="${ n.id }"]`));
|
|
89
|
+
const parent = panels[0].parentElement;
|
|
90
|
+
const images = [ ...parent.querySelectorAll('img') ];
|
|
91
|
+
const imagePromises = images.map(image => imagePromise(image));
|
|
92
|
+
function imagePromise(image) {
|
|
93
|
+
return new Promise((resolve, reject) => {
|
|
94
|
+
image.onload = () => resolve(image);
|
|
95
|
+
image.onerror = reject;
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
Promise.all(imagePromises).then(() => {
|
|
99
|
+
const heights = panels.map(panel => panel.offsetHeight);
|
|
100
|
+
const max = Math.max(...heights);
|
|
101
|
+
panels.forEach(panel => panel.style.minHeight = `${ max }px`);
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
export { instances };
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
|
package/js/ui/tooltip.js
ADDED
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
// =============================================================================
|
|
2
|
+
// Tooltip
|
|
3
|
+
// =============================================================================
|
|
4
|
+
|
|
5
|
+
// Version: 1.0.1
|
|
6
|
+
|
|
7
|
+
// Description: Adds a single tooltip div to bottom of document to be used to
|
|
8
|
+
// show text/simple markup of mouse hover or focus
|
|
9
|
+
|
|
10
|
+
import { logError } from "../utils/logger.js";
|
|
11
|
+
import { createPopper } from '@popperjs/core';
|
|
12
|
+
|
|
13
|
+
const ATTR_DESC = "aria-describedby";
|
|
14
|
+
const popperOptions = {
|
|
15
|
+
placement: "auto",
|
|
16
|
+
strategy: 'fixed',
|
|
17
|
+
modifiers: [
|
|
18
|
+
{
|
|
19
|
+
name: 'eventListeners',
|
|
20
|
+
enabled: false
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
name: 'preventOverflow',
|
|
24
|
+
enabled: true,
|
|
25
|
+
options: {
|
|
26
|
+
mainAxis: true
|
|
27
|
+
}
|
|
28
|
+
},
|
|
29
|
+
// Arrow
|
|
30
|
+
{
|
|
31
|
+
name: 'offset',
|
|
32
|
+
options: {
|
|
33
|
+
offset: [ 0, 10 ],
|
|
34
|
+
},
|
|
35
|
+
}
|
|
36
|
+
]
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
export default class Tooltip {
|
|
40
|
+
static defaults = {
|
|
41
|
+
namespace: "Tooltip",
|
|
42
|
+
describedBy: false,
|
|
43
|
+
arrowSize: 10,
|
|
44
|
+
classes: []
|
|
45
|
+
}
|
|
46
|
+
constructor(context, markup, config) {
|
|
47
|
+
if (!context) {
|
|
48
|
+
logError(this, 'Missing context element');
|
|
49
|
+
}
|
|
50
|
+
this.options = Object.assign({}, Tooltip.defaults, config);
|
|
51
|
+
this.context = context;
|
|
52
|
+
this.element = this.create(markup);
|
|
53
|
+
createPopper(context, this.element, popperOptions);
|
|
54
|
+
}
|
|
55
|
+
create(markup) {
|
|
56
|
+
const { namespace } = this.options;
|
|
57
|
+
const element = document.createElement("div");
|
|
58
|
+
|
|
59
|
+
element.id = namespace + "--" + Date.now();
|
|
60
|
+
element.innerHTML = markup;
|
|
61
|
+
element.classList.add(namespace);
|
|
62
|
+
element.classList.add(...this.options.classes);
|
|
63
|
+
|
|
64
|
+
const arrow = document.createElement("div");
|
|
65
|
+
arrow.setAttribute("data-popper-arrow", "");
|
|
66
|
+
|
|
67
|
+
if (this.options.describedBy) {
|
|
68
|
+
this.context.setAttribute(ATTR_DESC, element.id);
|
|
69
|
+
}
|
|
70
|
+
this.inPage = true;
|
|
71
|
+
element.appendChild(arrow);
|
|
72
|
+
return document.body.appendChild(element);
|
|
73
|
+
}
|
|
74
|
+
destroy() {
|
|
75
|
+
if (this.inPage) {
|
|
76
|
+
document.body.removeChild(this.element);
|
|
77
|
+
}
|
|
78
|
+
if (this.options.describedBy) {
|
|
79
|
+
this.context.removeAttribute(ATTR_DESC);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Removes an array element (modifies array)
|
|
3
|
+
* @param {Array} array Array to remove element from
|
|
4
|
+
* @param {Element} element Array element to remove
|
|
5
|
+
*/
|
|
6
|
+
export function removeArrayElement(array, element) {
|
|
7
|
+
var index = array.indexOf(element);
|
|
8
|
+
if (index > -1) {
|
|
9
|
+
array.splice(index, 1);
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Searches array for first item matching test, beginning at a start index but searching the entire array
|
|
15
|
+
* @param {Array} array Array to search
|
|
16
|
+
* @param {Number} start The index in the array to start the search from
|
|
17
|
+
* @param {Function} callback A test function that is passed array item and index
|
|
18
|
+
* - Credit: (James Waddington) https://stackoverflow.com/questions/28430348/how-to-loop-through-arrays-starting-at-different-index-while-still-looping-throu
|
|
19
|
+
*/
|
|
20
|
+
export function offsetFindIndexOf(array, start = 0, callback) {
|
|
21
|
+
let found, offset;
|
|
22
|
+
for (var i = 0; i < array.length; i++) {
|
|
23
|
+
offset = (i + start) % array.length;
|
|
24
|
+
found = callback(array[offset], offset);
|
|
25
|
+
if (found) return offset;
|
|
26
|
+
}
|
|
27
|
+
return -1;
|
|
28
|
+
}
|