@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.
Files changed (323) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +9 -0
  3. package/dist/ulu-frontend.min.css +1 -0
  4. package/dist/ulu-frontend.min.js +1 -0
  5. package/index.js +2 -0
  6. package/js/deprecated/doc-ready.js +28 -0
  7. package/js/deprecated/jquery-prototypes.js +309 -0
  8. package/js/deprecated/mini-collapsible-popper-positioning.js +126 -0
  9. package/js/deprecated/mini-collapsible.js +607 -0
  10. package/js/deprecated/script-loader.js +60 -0
  11. package/js/events/index.js +42 -0
  12. package/js/helpers/css-breakpoint.js +247 -0
  13. package/js/helpers/file-save.js +48 -0
  14. package/js/helpers/node-data-manager.js +74 -0
  15. package/js/helpers/pause-youtube-video.js +42 -0
  16. package/js/helpers/scrollbar-width-property.js +10 -0
  17. package/js/index.js +15 -0
  18. package/js/polyfills/element-closest.js +17 -0
  19. package/js/ui/flipcard.js +202 -0
  20. package/js/ui/grid.js +67 -0
  21. package/js/ui/modals.js +219 -0
  22. package/js/ui/overflow-scroller-pager.js +58 -0
  23. package/js/ui/overflow-scroller.js +160 -0
  24. package/js/ui/programmatic-modal.js +91 -0
  25. package/js/ui/resizer.js +60 -0
  26. package/js/ui/slider.js +468 -0
  27. package/js/ui/tabs.js +109 -0
  28. package/js/ui/tooltip.js +82 -0
  29. package/js/utils/array.js +28 -0
  30. package/js/utils/dom.js +122 -0
  31. package/js/utils/logger.js +69 -0
  32. package/js/utils/object.js +22 -0
  33. package/js/utils/performance.js +43 -0
  34. package/js/utils/regex.js +10 -0
  35. package/js/utils/string.js +107 -0
  36. package/js/waypoints/README.md +3 -0
  37. package/js/waypoints/anchor-menu.js +76 -0
  38. package/js/waypoints/element-waypoint.js +75 -0
  39. package/js/waypoints/examples/page-link-menu.md +106 -0
  40. package/js/waypoints/state-in-attribute.js +32 -0
  41. package/package.json +38 -0
  42. package/scss/README.md +58 -0
  43. package/scss/_breakpoint.scss +190 -0
  44. package/scss/_button.scss +241 -0
  45. package/scss/_calculate.scss +64 -0
  46. package/scss/_color.scss +211 -0
  47. package/scss/_cssvar.scss +116 -0
  48. package/scss/_element.scss +276 -0
  49. package/scss/_grid.scss +699 -0
  50. package/scss/_index.scss +29 -0
  51. package/scss/_layout.scss +202 -0
  52. package/scss/_path.scss +58 -0
  53. package/scss/_selector.scss +81 -0
  54. package/scss/_typography.scss +320 -0
  55. package/scss/_units.scss +47 -0
  56. package/scss/_utility.scss +12 -0
  57. package/scss/_utils.scss +209 -0
  58. package/scss/base/_color.scss +13 -0
  59. package/scss/base/_elements.scss +188 -0
  60. package/scss/base/_index.scss +62 -0
  61. package/scss/base/_keyframes.scss +78 -0
  62. package/scss/base/_layout.scss +100 -0
  63. package/scss/base/_normalize.scss +315 -0
  64. package/scss/base/_typography.scss +41 -0
  65. package/scss/components/README.md +5 -0
  66. package/scss/components/README.todos +15 -0
  67. package/scss/components/_button.scss +95 -0
  68. package/scss/components/_index.scss +63 -0
  69. package/scss/components/_links.scss +34 -0
  70. package/scss/components/_list-lines.scss +73 -0
  71. package/scss/components/_list-ordered.scss +16 -0
  72. package/scss/components/_list-unordered.scss +21 -0
  73. package/scss/components/_rule.scss +93 -0
  74. package/scss/helpers/_color.scss +14 -0
  75. package/scss/helpers/_display.scss +73 -0
  76. package/scss/helpers/_index.scss +67 -0
  77. package/scss/helpers/_print.scss +58 -0
  78. package/scss/helpers/_typography.scss +80 -0
  79. package/scss/helpers/_units.scss +79 -0
  80. package/scss/helpers/_utilities.scss +102 -0
  81. package/scss/stylesheets/README.md +3 -0
  82. package/scss/stylesheets/full.scss +17 -0
  83. package/trash/js-old/deprecated/doc-ready.js +28 -0
  84. package/trash/js-old/deprecated/jquery-prototypes.js +309 -0
  85. package/trash/js-old/deprecated/mini-collapsible-popper-positioning.js +126 -0
  86. package/trash/js-old/deprecated/mini-collapsible.js +607 -0
  87. package/trash/js-old/deprecated/script-loader.js +60 -0
  88. package/trash/js-old/events/index.js +42 -0
  89. package/trash/js-old/helpers/css-breakpoint.js +247 -0
  90. package/trash/js-old/helpers/file-save.js +48 -0
  91. package/trash/js-old/helpers/node-data-manager.js +74 -0
  92. package/trash/js-old/helpers/pause-youtube-video.js +42 -0
  93. package/trash/js-old/index.js +15 -0
  94. package/trash/js-old/polyfills/element-closest.js +17 -0
  95. package/trash/js-old/ui/flipcard.js +202 -0
  96. package/trash/js-old/ui/grid.js +67 -0
  97. package/trash/js-old/ui/modals.js +219 -0
  98. package/trash/js-old/ui/programmatic-modal.js +91 -0
  99. package/trash/js-old/ui/resizer.js +60 -0
  100. package/trash/js-old/ui/slider.js +469 -0
  101. package/trash/js-old/ui/tabs.js +109 -0
  102. package/trash/js-old/ui/tooltip.js +82 -0
  103. package/trash/js-old/utils/array.js +28 -0
  104. package/trash/js-old/utils/dom.js +122 -0
  105. package/trash/js-old/utils/logger.js +69 -0
  106. package/trash/js-old/utils/object.js +22 -0
  107. package/trash/js-old/utils/performance.js +43 -0
  108. package/trash/js-old/utils/regex.js +10 -0
  109. package/trash/js-old/utils/string.js +107 -0
  110. package/trash/js-old/waypoints/README.md +3 -0
  111. package/trash/js-old/waypoints/anchor-menu.js +76 -0
  112. package/trash/js-old/waypoints/element-waypoint.js +75 -0
  113. package/trash/js-old/waypoints/examples/page-link-menu.md +106 -0
  114. package/trash/js-old/waypoints/state-in-attribute.js +32 -0
  115. package/trash/js-old-230729/deprecated/doc-ready.js +28 -0
  116. package/trash/js-old-230729/deprecated/jquery-prototypes.js +309 -0
  117. package/trash/js-old-230729/deprecated/mini-collapsible-popper-positioning.js +126 -0
  118. package/trash/js-old-230729/deprecated/mini-collapsible.js +607 -0
  119. package/trash/js-old-230729/deprecated/script-loader.js +60 -0
  120. package/trash/js-old-230729/events/index.js +42 -0
  121. package/trash/js-old-230729/helpers/css-breakpoint.js +247 -0
  122. package/trash/js-old-230729/helpers/file-save.js +48 -0
  123. package/trash/js-old-230729/helpers/node-data-manager.js +74 -0
  124. package/trash/js-old-230729/helpers/pause-youtube-video.js +42 -0
  125. package/trash/js-old-230729/helpers/scrollbar-width-property.js +10 -0
  126. package/trash/js-old-230729/index.js +15 -0
  127. package/trash/js-old-230729/polyfills/element-closest.js +17 -0
  128. package/trash/js-old-230729/ui/flipcard.js +202 -0
  129. package/trash/js-old-230729/ui/grid.js +67 -0
  130. package/trash/js-old-230729/ui/modals.js +219 -0
  131. package/trash/js-old-230729/ui/overflow-scroller-pager.js +58 -0
  132. package/trash/js-old-230729/ui/overflow-scroller.js +160 -0
  133. package/trash/js-old-230729/ui/programmatic-modal.js +91 -0
  134. package/trash/js-old-230729/ui/resizer.js +60 -0
  135. package/trash/js-old-230729/ui/slider.js +468 -0
  136. package/trash/js-old-230729/ui/tabs.js +109 -0
  137. package/trash/js-old-230729/ui/tooltip.js +82 -0
  138. package/trash/js-old-230729/utils/array.js +28 -0
  139. package/trash/js-old-230729/utils/dom.js +122 -0
  140. package/trash/js-old-230729/utils/logger.js +69 -0
  141. package/trash/js-old-230729/utils/object.js +22 -0
  142. package/trash/js-old-230729/utils/performance.js +43 -0
  143. package/trash/js-old-230729/utils/regex.js +10 -0
  144. package/trash/js-old-230729/utils/string.js +107 -0
  145. package/trash/js-old-230729/waypoints/README.md +3 -0
  146. package/trash/js-old-230729/waypoints/anchor-menu.js +76 -0
  147. package/trash/js-old-230729/waypoints/element-waypoint.js +75 -0
  148. package/trash/js-old-230729/waypoints/examples/page-link-menu.md +106 -0
  149. package/trash/js-old-230729/waypoints/state-in-attribute.js +32 -0
  150. package/trash/logo-1.svg +13 -0
  151. package/trash/logo.svg +16 -0
  152. package/trash/scss-before-cqc-update/README.md +58 -0
  153. package/trash/scss-before-cqc-update/_breakpoint.scss +190 -0
  154. package/trash/scss-before-cqc-update/_button.scss +229 -0
  155. package/trash/scss-before-cqc-update/_calculate.scss +65 -0
  156. package/trash/scss-before-cqc-update/_color.scss +211 -0
  157. package/trash/scss-before-cqc-update/_cssvar.scss +116 -0
  158. package/trash/scss-before-cqc-update/_element.scss +275 -0
  159. package/trash/scss-before-cqc-update/_index.scss +29 -0
  160. package/trash/scss-before-cqc-update/_layout.scss +247 -0
  161. package/trash/scss-before-cqc-update/_path.scss +59 -0
  162. package/trash/scss-before-cqc-update/_selector.scss +82 -0
  163. package/trash/scss-before-cqc-update/_typography.scss +322 -0
  164. package/trash/scss-before-cqc-update/_units.scss +48 -0
  165. package/trash/scss-before-cqc-update/_utility.scss +13 -0
  166. package/trash/scss-before-cqc-update/_utils.scss +211 -0
  167. package/trash/scss-before-cqc-update/base/_color.scss +14 -0
  168. package/trash/scss-before-cqc-update/base/_elements.scss +189 -0
  169. package/trash/scss-before-cqc-update/base/_index.scss +63 -0
  170. package/trash/scss-before-cqc-update/base/_keyframes.scss +74 -0
  171. package/trash/scss-before-cqc-update/base/_layout.scss +88 -0
  172. package/trash/scss-before-cqc-update/base/_normalize.scss +316 -0
  173. package/trash/scss-before-cqc-update/base/_typography.scss +42 -0
  174. package/trash/scss-before-cqc-update/components/README.md +5 -0
  175. package/trash/scss-before-cqc-update/components/README.todos +15 -0
  176. package/trash/scss-before-cqc-update/components/_button.scss +96 -0
  177. package/trash/scss-before-cqc-update/components/_grid.scss +671 -0
  178. package/trash/scss-before-cqc-update/components/_index.scss +70 -0
  179. package/trash/scss-before-cqc-update/components/_links.scss +35 -0
  180. package/trash/scss-before-cqc-update/components/_list-lines.scss +74 -0
  181. package/trash/scss-before-cqc-update/components/_list-ordered.scss +17 -0
  182. package/trash/scss-before-cqc-update/components/_list-unordered.scss +22 -0
  183. package/trash/scss-before-cqc-update/components/_rule.scss +94 -0
  184. package/trash/scss-before-cqc-update/helpers/_color.scss +15 -0
  185. package/trash/scss-before-cqc-update/helpers/_display.scss +73 -0
  186. package/trash/scss-before-cqc-update/helpers/_index.scss +68 -0
  187. package/trash/scss-before-cqc-update/helpers/_print.scss +59 -0
  188. package/trash/scss-before-cqc-update/helpers/_typography.scss +73 -0
  189. package/trash/scss-before-cqc-update/helpers/_units.scss +79 -0
  190. package/trash/scss-before-cqc-update/helpers/_utilities.scss +88 -0
  191. package/trash/scss-before-cqc-update/stylesheets/README.md +3 -0
  192. package/trash/scss-before-cqc-update/stylesheets/full.scss +17 -0
  193. package/trash/scss-old/README.md +58 -0
  194. package/trash/scss-old/_breakpoint.scss +140 -0
  195. package/trash/scss-old/_button.scss +223 -0
  196. package/trash/scss-old/_calculate.scss +64 -0
  197. package/trash/scss-old/_color.scss +200 -0
  198. package/trash/scss-old/_element.scss +262 -0
  199. package/trash/scss-old/_grid.scss +558 -0
  200. package/trash/scss-old/_index.scss +25 -0
  201. package/trash/scss-old/_layout.scss +170 -0
  202. package/trash/scss-old/_path.scss +58 -0
  203. package/trash/scss-old/_selector.scss +81 -0
  204. package/trash/scss-old/_typography.scss +320 -0
  205. package/trash/scss-old/_units.scss +47 -0
  206. package/trash/scss-old/_utility.scss +12 -0
  207. package/trash/scss-old/_utils.scss +186 -0
  208. package/trash/scss-old/base/_color.scss +13 -0
  209. package/trash/scss-old/base/_elements.scss +183 -0
  210. package/trash/scss-old/base/_index.scss +62 -0
  211. package/trash/scss-old/base/_keyframes.scss +74 -0
  212. package/trash/scss-old/base/_layout.scss +81 -0
  213. package/trash/scss-old/base/_normalize.scss +316 -0
  214. package/trash/scss-old/base/_typography.scss +42 -0
  215. package/trash/scss-old/components/README.md +5 -0
  216. package/trash/scss-old/components/README.todos +15 -0
  217. package/trash/scss-old/components/_button.scss +74 -0
  218. package/trash/scss-old/components/_index.scss +63 -0
  219. package/trash/scss-old/components/_links.scss +34 -0
  220. package/trash/scss-old/components/_list-lines.scss +73 -0
  221. package/trash/scss-old/components/_list-ordered.scss +16 -0
  222. package/trash/scss-old/components/_list-unordered.scss +21 -0
  223. package/trash/scss-old/components/_rule.scss +84 -0
  224. package/trash/scss-old/helpers/_color.scss +14 -0
  225. package/trash/scss-old/helpers/_display.scss +68 -0
  226. package/trash/scss-old/helpers/_index.scss +67 -0
  227. package/trash/scss-old/helpers/_print.scss +59 -0
  228. package/trash/scss-old/helpers/_typography.scss +73 -0
  229. package/trash/scss-old/helpers/_units.scss +68 -0
  230. package/trash/scss-old/helpers/_utilities.scss +82 -0
  231. package/trash/scss-old/packages/README.md +3 -0
  232. package/trash/scss-old/packages/everything.scss +17 -0
  233. package/trash/scss-old-2/README.md +58 -0
  234. package/trash/scss-old-2/_breakpoint.scss +139 -0
  235. package/trash/scss-old-2/_button.scss +223 -0
  236. package/trash/scss-old-2/_calculate.scss +64 -0
  237. package/trash/scss-old-2/_color.scss +202 -0
  238. package/trash/scss-old-2/_element.scss +263 -0
  239. package/trash/scss-old-2/_grid.scss +558 -0
  240. package/trash/scss-old-2/_index.scss +25 -0
  241. package/trash/scss-old-2/_layout.scss +170 -0
  242. package/trash/scss-old-2/_path.scss +58 -0
  243. package/trash/scss-old-2/_selector.scss +81 -0
  244. package/trash/scss-old-2/_typography.scss +320 -0
  245. package/trash/scss-old-2/_units.scss +47 -0
  246. package/trash/scss-old-2/_utility.scss +12 -0
  247. package/trash/scss-old-2/_utils.scss +186 -0
  248. package/trash/scss-old-2/base/_color.scss +13 -0
  249. package/trash/scss-old-2/base/_elements.scss +182 -0
  250. package/trash/scss-old-2/base/_index.scss +62 -0
  251. package/trash/scss-old-2/base/_keyframes.scss +73 -0
  252. package/trash/scss-old-2/base/_layout.scss +83 -0
  253. package/trash/scss-old-2/base/_normalize.scss +315 -0
  254. package/trash/scss-old-2/base/_typography.scss +41 -0
  255. package/trash/scss-old-2/components/README.md +5 -0
  256. package/trash/scss-old-2/components/README.todos +15 -0
  257. package/trash/scss-old-2/components/_button.scss +95 -0
  258. package/trash/scss-old-2/components/_index.scss +63 -0
  259. package/trash/scss-old-2/components/_links.scss +33 -0
  260. package/trash/scss-old-2/components/_list-lines.scss +73 -0
  261. package/trash/scss-old-2/components/_list-ordered.scss +16 -0
  262. package/trash/scss-old-2/components/_list-unordered.scss +21 -0
  263. package/trash/scss-old-2/components/_rule.scss +84 -0
  264. package/trash/scss-old-2/helpers/_color.scss +14 -0
  265. package/trash/scss-old-2/helpers/_display.scss +67 -0
  266. package/trash/scss-old-2/helpers/_index.scss +67 -0
  267. package/trash/scss-old-2/helpers/_print.scss +58 -0
  268. package/trash/scss-old-2/helpers/_typography.scss +72 -0
  269. package/trash/scss-old-2/helpers/_units.scss +68 -0
  270. package/trash/scss-old-2/helpers/_utilities.scss +81 -0
  271. package/trash/scss-old-2/packages/README.md +3 -0
  272. package/trash/scss-old-2/packages/everything.scss +17 -0
  273. package/trash/scss-old-230729/README.md +58 -0
  274. package/trash/scss-old-230729/_breakpoint.scss +139 -0
  275. package/trash/scss-old-230729/_button.scss +223 -0
  276. package/trash/scss-old-230729/_calculate.scss +64 -0
  277. package/trash/scss-old-230729/_color.scss +202 -0
  278. package/trash/scss-old-230729/_element.scss +273 -0
  279. package/trash/scss-old-230729/_grid.scss +694 -0
  280. package/trash/scss-old-230729/_index.scss +25 -0
  281. package/trash/scss-old-230729/_layout.scss +193 -0
  282. package/trash/scss-old-230729/_path.scss +58 -0
  283. package/trash/scss-old-230729/_selector.scss +81 -0
  284. package/trash/scss-old-230729/_typography.scss +320 -0
  285. package/trash/scss-old-230729/_units.scss +47 -0
  286. package/trash/scss-old-230729/_utility.scss +12 -0
  287. package/trash/scss-old-230729/_utils.scss +186 -0
  288. package/trash/scss-old-230729/base/_color.scss +13 -0
  289. package/trash/scss-old-230729/base/_elements.scss +188 -0
  290. package/trash/scss-old-230729/base/_index.scss +62 -0
  291. package/trash/scss-old-230729/base/_keyframes.scss +73 -0
  292. package/trash/scss-old-230729/base/_layout.scss +83 -0
  293. package/trash/scss-old-230729/base/_normalize.scss +315 -0
  294. package/trash/scss-old-230729/base/_typography.scss +41 -0
  295. package/trash/scss-old-230729/components/README.md +5 -0
  296. package/trash/scss-old-230729/components/README.todos +15 -0
  297. package/trash/scss-old-230729/components/_button.scss +95 -0
  298. package/trash/scss-old-230729/components/_index.scss +63 -0
  299. package/trash/scss-old-230729/components/_links.scss +34 -0
  300. package/trash/scss-old-230729/components/_list-lines.scss +73 -0
  301. package/trash/scss-old-230729/components/_list-ordered.scss +16 -0
  302. package/trash/scss-old-230729/components/_list-unordered.scss +21 -0
  303. package/trash/scss-old-230729/components/_rule.scss +93 -0
  304. package/trash/scss-old-230729/helpers/_color.scss +14 -0
  305. package/trash/scss-old-230729/helpers/_display.scss +73 -0
  306. package/trash/scss-old-230729/helpers/_index.scss +67 -0
  307. package/trash/scss-old-230729/helpers/_print.scss +58 -0
  308. package/trash/scss-old-230729/helpers/_typography.scss +72 -0
  309. package/trash/scss-old-230729/helpers/_units.scss +68 -0
  310. package/trash/scss-old-230729/helpers/_utilities.scss +87 -0
  311. package/trash/scss-old-230729/packages/README.md +3 -0
  312. package/trash/scss-old-230729/packages/everything.scss +17 -0
  313. package/trash/vue/directives/background-image-url.js +12 -0
  314. package/trash/vue/helpers/add-required-components.js +14 -0
  315. package/trash/vue/ui/CollapsibleRegion/CollapsibleRegion.vue +277 -0
  316. package/trash/vue/ui/CollapsibleRegion/Demo.vue +101 -0
  317. package/trash/vue/ui/Dropdown/Dropdown.vue +184 -0
  318. package/trash/vue/ui/Modals/components/Modal.vue +49 -0
  319. package/trash/vue/ui/Modals/components/Modals.vue +103 -0
  320. package/trash/vue/ui/Modals/plugin.js +215 -0
  321. package/trash/vue/ui/Modals/readme.note +10 -0
  322. package/trash/vue/ui/Modals/reference/example-usage.vue +27 -0
  323. package/trash/vue/ui/Modals/reference/wcag-example/dialog.js +324 -0
@@ -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
+
@@ -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
+ }