@ulu/frontend 0.1.0-beta.6 → 0.1.0-beta.61

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 (290) hide show
  1. package/CHANGELOG.md +428 -0
  2. package/dist/ulu-frontend.min.css +1 -1
  3. package/dist/ulu-frontend.min.js +28 -27
  4. package/docs-dev/assets/main.js +832 -421
  5. package/docs-dev/assets/placeholder/icon-calendar.svg +1 -0
  6. package/docs-dev/assets/placeholder/icon-check.svg +1 -0
  7. package/docs-dev/assets/style.css +629 -233
  8. package/docs-dev/changelog/index.html +6236 -0
  9. package/docs-dev/changelog/updates-and-changes/index.html +5109 -0
  10. package/docs-dev/demos/accordion/index.html +904 -321
  11. package/docs-dev/demos/basic-hero/index.html +111 -0
  12. package/docs-dev/demos/breakpoints-manager/index.html +5246 -0
  13. package/docs-dev/demos/button/index.html +916 -323
  14. package/docs-dev/demos/button-verbose/index.html +5238 -0
  15. package/docs-dev/demos/callout/index.html +951 -328
  16. package/docs-dev/demos/captioned-figure/index.html +904 -321
  17. package/docs-dev/demos/card/index.html +970 -748
  18. package/docs-dev/demos/card-grid/index.html +5357 -0
  19. package/docs-dev/demos/card-new/index.html +5088 -0
  20. package/docs-dev/demos/card-old/index.html +5223 -0
  21. package/docs-dev/demos/card.1/index.html +5223 -0
  22. package/docs-dev/demos/card.TRASH/index.html +5541 -0
  23. package/docs-dev/demos/counter-list/index.html +5224 -0
  24. package/docs-dev/demos/css-icons/index.html +904 -321
  25. package/docs-dev/demos/data-grid/index.html +1014 -511
  26. package/docs-dev/demos/data-table/index.html +1064 -348
  27. package/docs-dev/demos/details-group/index.html +5267 -0
  28. package/docs-dev/demos/file-save/index.html +904 -321
  29. package/docs-dev/demos/flipcard/index.html +904 -321
  30. package/docs-dev/demos/form-theme/index.html +922 -352
  31. package/docs-dev/demos/hero/index.html +12 -4
  32. package/docs-dev/demos/image-grid/index.html +12 -4
  33. package/docs-dev/demos/index.html +905 -322
  34. package/docs-dev/demos/list-inline/index.html +5220 -0
  35. package/docs-dev/demos/list-inline.1/index.html +4727 -0
  36. package/docs-dev/demos/list-lines/index.html +5210 -0
  37. package/docs-dev/demos/menu-stack/index.html +975 -377
  38. package/docs-dev/demos/modals/index.html +1010 -357
  39. package/docs-dev/demos/nav-strip/index.html +904 -321
  40. package/docs-dev/demos/overlay-section/index.html +979 -326
  41. package/docs-dev/demos/popovers/index.html +1152 -327
  42. package/docs-dev/demos/print/index.html +904 -321
  43. package/docs-dev/demos/pull-quote/index.html +904 -321
  44. package/docs-dev/demos/rule/index.html +952 -357
  45. package/docs-dev/demos/scroll-slider/index.html +72 -106
  46. package/docs-dev/demos/scrollpoints/index.html +905 -322
  47. package/docs-dev/demos/slider/index.html +12 -4
  48. package/docs-dev/demos/spoke-spinner/index.html +904 -321
  49. package/docs-dev/demos/sticky-list/index.html +5223 -0
  50. package/docs-dev/demos/tabs/index.html +944 -325
  51. package/docs-dev/demos/tag/index.html +904 -321
  52. package/docs-dev/demos/theme-toggle/index.html +5279 -0
  53. package/docs-dev/demos/tile-grid-overlay/index.html +12 -4
  54. package/docs-dev/demos/tiles/index.html +904 -321
  55. package/docs-dev/demos/tooltip/index.html +904 -321
  56. package/docs-dev/guide/building-stylesheet/index.html +904 -321
  57. package/docs-dev/guide/developing-ulu-scss-module/index.html +904 -321
  58. package/docs-dev/guide/index.html +904 -321
  59. package/docs-dev/guide/updates-and-changes/index.html +5033 -0
  60. package/docs-dev/index.html +904 -321
  61. package/docs-dev/javascript/events/index.html +901 -320
  62. package/docs-dev/javascript/index.html +904 -321
  63. package/docs-dev/javascript/settings/index.html +5400 -0
  64. package/docs-dev/javascript/ui-breakpoints/index.html +916 -335
  65. package/docs-dev/javascript/ui-collapsible/index.html +901 -320
  66. package/docs-dev/javascript/ui-details-group/index.html +5322 -0
  67. package/docs-dev/javascript/ui-dialog/index.html +967 -371
  68. package/docs-dev/javascript/ui-flipcard/index.html +964 -327
  69. package/docs-dev/javascript/ui-grid/index.html +913 -358
  70. package/docs-dev/javascript/ui-modal-builder/index.html +1067 -366
  71. package/docs-dev/javascript/ui-overflow-scroller/index.html +901 -320
  72. package/docs-dev/javascript/ui-overflow-scroller-pager/index.html +901 -320
  73. package/docs-dev/javascript/ui-page/index.html +901 -320
  74. package/docs-dev/javascript/ui-popover/index.html +911 -334
  75. package/docs-dev/javascript/ui-print/index.html +901 -328
  76. package/docs-dev/javascript/ui-print-details/index.html +901 -320
  77. package/docs-dev/javascript/ui-programmatic-modal/index.html +901 -320
  78. package/docs-dev/javascript/ui-proxy-click/index.html +990 -324
  79. package/docs-dev/javascript/ui-resizer/index.html +901 -320
  80. package/docs-dev/javascript/ui-scroll-slider/index.html +941 -328
  81. package/docs-dev/javascript/ui-scrollpoint/index.html +907 -333
  82. package/docs-dev/javascript/ui-slider/index.html +1099 -327
  83. package/docs-dev/javascript/ui-tabs/index.html +914 -370
  84. package/docs-dev/javascript/ui-theme-toggle/index.html +5410 -0
  85. package/docs-dev/javascript/ui-tooltip/index.html +940 -363
  86. package/docs-dev/javascript/utils-class-logger/index.html +901 -320
  87. package/docs-dev/javascript/utils-css/index.html +5224 -0
  88. package/docs-dev/javascript/utils-dom/index.html +1054 -339
  89. package/docs-dev/javascript/utils-file-save/index.html +901 -320
  90. package/docs-dev/javascript/utils-floating-ui/index.html +901 -320
  91. package/docs-dev/javascript/utils-id/index.html +901 -320
  92. package/docs-dev/javascript/utils-pause-youtube-video/index.html +901 -320
  93. package/docs-dev/javascript/utils-system/index.html +5527 -0
  94. package/docs-dev/sass/base/color/index.html +901 -320
  95. package/docs-dev/sass/base/elements/index.html +901 -320
  96. package/docs-dev/sass/base/index/index.html +901 -320
  97. package/docs-dev/sass/base/index.html +904 -321
  98. package/docs-dev/sass/base/keyframes/index.html +901 -320
  99. package/docs-dev/sass/base/layout/index.html +901 -320
  100. package/docs-dev/sass/base/normalize/index.html +901 -320
  101. package/docs-dev/sass/base/print/index.html +901 -320
  102. package/docs-dev/sass/base/root/index.html +901 -320
  103. package/docs-dev/sass/base/typography/index.html +901 -320
  104. package/docs-dev/sass/components/accordion/index.html +908 -327
  105. package/docs-dev/sass/components/adaptive-spacing/index.html +901 -320
  106. package/docs-dev/sass/components/badge/index.html +909 -328
  107. package/docs-dev/sass/components/basic-hero/index.html +5385 -0
  108. package/docs-dev/sass/components/button/index.html +901 -320
  109. package/docs-dev/sass/components/button-verbose/index.html +989 -333
  110. package/docs-dev/sass/components/callout/index.html +1018 -414
  111. package/docs-dev/sass/components/captioned-figure/index.html +1026 -330
  112. package/docs-dev/sass/components/card/index.html +1003 -350
  113. package/docs-dev/sass/components/card-grid/index.html +901 -320
  114. package/docs-dev/sass/components/counter-list/index.html +5458 -0
  115. package/docs-dev/sass/components/css-icon/index.html +918 -330
  116. package/docs-dev/sass/components/data-grid/index.html +922 -334
  117. package/docs-dev/sass/components/data-table/index.html +1106 -333
  118. package/docs-dev/sass/components/fill-context/index.html +901 -320
  119. package/docs-dev/sass/components/flipcard/index.html +939 -327
  120. package/docs-dev/sass/components/flipcard-grid/index.html +901 -320
  121. package/docs-dev/sass/components/form-theme/index.html +1110 -433
  122. package/docs-dev/sass/components/hero/index.html +995 -366
  123. package/docs-dev/sass/components/horizontal-rule/index.html +901 -320
  124. package/docs-dev/sass/components/image-grid/index.html +901 -320
  125. package/docs-dev/sass/components/index/index.html +915 -330
  126. package/docs-dev/sass/components/index.html +904 -321
  127. package/docs-dev/sass/components/links/index.html +901 -320
  128. package/docs-dev/sass/components/list-inline/index.html +5399 -0
  129. package/docs-dev/sass/components/list-lines/index.html +936 -359
  130. package/docs-dev/sass/components/list-ordered/index.html +903 -322
  131. package/docs-dev/sass/components/list-unordered/index.html +901 -320
  132. package/docs-dev/sass/components/menu-stack/index.html +973 -379
  133. package/docs-dev/sass/components/modal/index.html +953 -365
  134. package/docs-dev/sass/components/nav-strip/index.html +909 -328
  135. package/docs-dev/sass/components/overlay-section/index.html +909 -328
  136. package/docs-dev/sass/components/pager/index.html +901 -320
  137. package/docs-dev/sass/components/placeholder-block/index.html +901 -320
  138. package/docs-dev/sass/components/popover/index.html +996 -379
  139. package/docs-dev/sass/components/pull-quote/index.html +913 -332
  140. package/docs-dev/sass/components/ratio-box/index.html +909 -328
  141. package/docs-dev/sass/components/rule/index.html +909 -328
  142. package/docs-dev/sass/components/scroll-slider/index.html +944 -375
  143. package/docs-dev/sass/components/skip-link/index.html +909 -328
  144. package/docs-dev/sass/components/slider/index.html +989 -420
  145. package/docs-dev/sass/components/spoke-spinner/index.html +903 -322
  146. package/docs-dev/sass/components/sticky-list/index.html +5603 -0
  147. package/docs-dev/sass/components/tabs/index.html +910 -329
  148. package/docs-dev/sass/components/tag/index.html +903 -322
  149. package/docs-dev/sass/components/tile-button/index.html +901 -320
  150. package/docs-dev/sass/components/tile-grid/index.html +901 -320
  151. package/docs-dev/sass/components/tile-grid-overlay/index.html +901 -320
  152. package/docs-dev/sass/components/vignette/index.html +915 -328
  153. package/docs-dev/sass/components/wysiwyg/index.html +901 -320
  154. package/docs-dev/sass/core/breakpoint/index.html +947 -352
  155. package/docs-dev/sass/core/button/index.html +901 -320
  156. package/docs-dev/sass/core/color/index.html +1078 -364
  157. package/docs-dev/sass/core/cssvar/index.html +901 -320
  158. package/docs-dev/sass/core/element/index.html +1096 -368
  159. package/docs-dev/sass/core/index.html +901 -320
  160. package/docs-dev/sass/core/layout/index.html +961 -361
  161. package/docs-dev/sass/core/path/index.html +901 -320
  162. package/docs-dev/sass/core/selector/index.html +901 -320
  163. package/docs-dev/sass/core/typography/index.html +901 -320
  164. package/docs-dev/sass/core/units/index.html +911 -324
  165. package/docs-dev/sass/core/utils/index.html +1871 -430
  166. package/docs-dev/sass/helpers/color/index.html +901 -320
  167. package/docs-dev/sass/helpers/display/index.html +902 -321
  168. package/docs-dev/sass/helpers/index/index.html +901 -320
  169. package/docs-dev/sass/helpers/index.html +904 -321
  170. package/docs-dev/sass/helpers/print/index.html +843 -292
  171. package/docs-dev/sass/helpers/typography/index.html +901 -320
  172. package/docs-dev/sass/helpers/units/index.html +901 -320
  173. package/docs-dev/sass/helpers/utilities/index.html +903 -322
  174. package/docs-dev/sass/index.html +904 -321
  175. package/js/index.js +1 -0
  176. package/js/settings.js +95 -0
  177. package/js/ui/breakpoints.js +19 -16
  178. package/js/ui/collapsible.js +8 -1
  179. package/js/ui/details-group.js +112 -0
  180. package/js/ui/dialog.js +90 -42
  181. package/js/ui/dialog.todo +2 -36
  182. package/js/ui/flipcard.js +37 -57
  183. package/js/ui/grid.js +15 -13
  184. package/js/ui/index.js +1 -0
  185. package/js/ui/modal-builder.js +76 -56
  186. package/js/ui/overflow-scroller.js +6 -4
  187. package/js/ui/popover.js +38 -38
  188. package/js/ui/print.js +16 -25
  189. package/js/ui/programmatic-modal.js +9 -3
  190. package/js/ui/proxy-click.js +50 -36
  191. package/js/ui/scroll-slider.js +24 -30
  192. package/js/ui/scrollpoint.js +28 -64
  193. package/js/ui/slider.js +108 -63
  194. package/js/ui/tabs.js +23 -36
  195. package/js/ui/theme-toggle.js +331 -94
  196. package/js/ui/tooltip.js +27 -32
  197. package/js/utils/css.js +13 -0
  198. package/js/utils/dom.js +85 -8
  199. package/js/utils/font-awesome.js +18 -0
  200. package/js/utils/index.js +2 -1
  201. package/js/utils/system.js +154 -0
  202. package/package.json +14 -7
  203. package/scss/_breakpoint.scss +16 -3
  204. package/scss/_color.scss +36 -5
  205. package/scss/_element.scss +94 -2
  206. package/scss/_layout.scss +7 -8
  207. package/scss/_units.scss +3 -2
  208. package/scss/_utils.scss +248 -13
  209. package/scss/components/README.todos +14 -0
  210. package/scss/components/_accordion.scss +5 -7
  211. package/scss/components/_basic-hero.scss +112 -0
  212. package/scss/components/_button-verbose.scss +100 -18
  213. package/scss/components/_callout.scss +125 -78
  214. package/scss/components/_captioned-figure.scss +17 -0
  215. package/scss/components/_card-grid.scss +1 -1
  216. package/scss/components/_card.scss +246 -74
  217. package/scss/components/_counter-list.scss +137 -0
  218. package/scss/components/_css-icon.scss +25 -21
  219. package/scss/components/_data-grid.scss +38 -9
  220. package/scss/components/_data-table.scss +44 -4
  221. package/scss/components/_flipcard.scss +8 -3
  222. package/scss/components/_form-theme.scss +119 -108
  223. package/scss/components/_hero.scss +12 -10
  224. package/scss/components/_index.scss +24 -0
  225. package/scss/components/_list-inline.scss +80 -0
  226. package/scss/components/_list-lines.scss +44 -32
  227. package/scss/components/_menu-stack.scss +42 -26
  228. package/scss/components/_modal.scss +13 -6
  229. package/scss/components/_nav-strip.scss +2 -0
  230. package/scss/components/_overlay-section.scss +2 -5
  231. package/scss/components/_popover.scss +165 -64
  232. package/scss/components/_pull-quote.scss +13 -13
  233. package/scss/components/_ratio-box.scss +2 -5
  234. package/scss/components/_rule.scss +1 -0
  235. package/scss/components/_scroll-slider.scss +1 -5
  236. package/scss/components/_slider.scss +49 -72
  237. package/scss/components/_spoke-spinner.scss +2 -2
  238. package/scss/components/_sticky-list.scss +206 -0
  239. package/scss/components/_tabs.scss +3 -1
  240. package/scss/components/_vignette.scss +3 -5
  241. package/scss/helpers/_display.scss +15 -18
  242. package/scss/helpers/_print.scss +12 -7
  243. package/scss/helpers/_utilities.scss +42 -32
  244. package/types/index.d.ts +1 -0
  245. package/types/settings.d.ts +66 -0
  246. package/types/settings.d.ts.map +1 -0
  247. package/types/ui/breakpoints.d.ts +14 -14
  248. package/types/ui/breakpoints.d.ts.map +1 -1
  249. package/types/ui/collapsible.d.ts.map +1 -1
  250. package/types/ui/details-group.d.ts +38 -0
  251. package/types/ui/details-group.d.ts.map +1 -0
  252. package/types/ui/dialog.d.ts +20 -14
  253. package/types/ui/dialog.d.ts.map +1 -1
  254. package/types/ui/flipcard.d.ts +16 -10
  255. package/types/ui/flipcard.d.ts.map +1 -1
  256. package/types/ui/grid.d.ts +4 -6
  257. package/types/ui/grid.d.ts.map +1 -1
  258. package/types/ui/index.d.ts +1 -0
  259. package/types/ui/modal-builder.d.ts +93 -11
  260. package/types/ui/modal-builder.d.ts.map +1 -1
  261. package/types/ui/overflow-scroller.d.ts +2 -2
  262. package/types/ui/overflow-scroller.d.ts.map +1 -1
  263. package/types/ui/popover.d.ts +6 -7
  264. package/types/ui/popover.d.ts.map +1 -1
  265. package/types/ui/print.d.ts +0 -4
  266. package/types/ui/print.d.ts.map +1 -1
  267. package/types/ui/programmatic-modal.d.ts.map +1 -1
  268. package/types/ui/proxy-click.d.ts +19 -3
  269. package/types/ui/proxy-click.d.ts.map +1 -1
  270. package/types/ui/scroll-slider.d.ts +5 -7
  271. package/types/ui/scroll-slider.d.ts.map +1 -1
  272. package/types/ui/scrollpoint.d.ts +3 -8
  273. package/types/ui/scrollpoint.d.ts.map +1 -1
  274. package/types/ui/slider.d.ts +33 -14
  275. package/types/ui/slider.d.ts.map +1 -1
  276. package/types/ui/tabs.d.ts +6 -8
  277. package/types/ui/tabs.d.ts.map +1 -1
  278. package/types/ui/theme-toggle.d.ts +51 -7
  279. package/types/ui/theme-toggle.d.ts.map +1 -1
  280. package/types/ui/tooltip.d.ts +3 -5
  281. package/types/ui/tooltip.d.ts.map +1 -1
  282. package/types/utils/css.d.ts +11 -0
  283. package/types/utils/css.d.ts.map +1 -0
  284. package/types/utils/dom.d.ts +45 -6
  285. package/types/utils/dom.d.ts.map +1 -1
  286. package/types/utils/font-awesome.d.ts +5 -0
  287. package/types/utils/font-awesome.d.ts.map +1 -0
  288. package/types/utils/index.d.ts +1 -0
  289. package/types/utils/system.d.ts +113 -0
  290. package/types/utils/system.d.ts.map +1 -0
package/js/ui/flipcard.js CHANGED
@@ -2,14 +2,43 @@
2
2
  * @module ui/flipcard
3
3
  */
4
4
 
5
+ import { ComponentInitializer } from "../utils/system.js";
5
6
  import { trimWhitespace } from "@ulu/utils/string.js";
6
7
  import { log, logError } from "../utils/class-logger.js";
7
- import { getName } from "../events/index.js";
8
- import { getDatasetOptionalJson } from "../utils/dom.js";
9
- const debugMode = false; // Global dev debug
10
8
 
9
+ /**
10
+ * Flipcard Component Initializer
11
+ */
12
+ export const initializer = new ComponentInitializer({
13
+ type: "flipcard",
14
+ baseAttribute: "data-ulu-flipcard"
15
+ });
16
+
17
+ /**
18
+ * Initialize flipcards using data-ulu-flipcard attribute
19
+ */
20
+ export function init() {
21
+ initializer.init({
22
+ withData: true,
23
+ events: ["pageModified"],
24
+ setup({ element, data, initialize }) {
25
+ const options = Object.assign({}, data);
26
+ const front = element.querySelector(initializer.attributeSelector("front"));
27
+ const back = element.querySelector(initializer.attributeSelector("back"));
28
+ (new Flipcard(element, front, back, options));
29
+ initialize();
30
+ }
31
+ });
32
+ }
33
+
34
+ /**
35
+ * Flipcard class (creates flipcard instance and behaviors)
36
+ */
11
37
  export class Flipcard {
12
38
  static instances = [];
39
+ /**
40
+ * Default options for Flipcard
41
+ */
13
42
  static defaults = {
14
43
  namespace: "Flipcard",
15
44
  proxyClick: {
@@ -18,25 +47,25 @@ export class Flipcard {
18
47
  exclude: "a, input, textarea, button" // Selectors to avoid closing a flipcard onProxyclick
19
48
  },
20
49
  };
21
- constructor(container, front, back, config, debug = false) {
50
+ constructor(container, front, back, config) {
22
51
  if (!container, !front, !back) {
23
52
  logError(this, 'Missing an element (container, front, back)');
24
53
  }
25
54
  this.options = Object.assign({}, Flipcard.defaults, config);
26
55
  const { namespace } = this.options;
56
+
27
57
  Flipcard.instances.push(this);
28
58
 
29
- this.debug = debugMode || debug;
30
59
  this.elements = { container, front, back };
31
60
  this.isOpen = false;
32
61
  this.uid = `${ namespace }-id-${ Flipcard.instances.length }`;
33
62
  this.stateAttr = `data-${ namespace }-state`.toLowerCase();
34
63
  this.setup();
35
- this.setVisiblity(false);
64
+ this.setVisibility(false);
36
65
  log(this, this);
37
66
  }
38
67
  toggle() {
39
- this.setVisiblity(!this.isOpen);
68
+ this.setVisibility(!this.isOpen);
40
69
  }
41
70
  setup() {
42
71
  const { uid } = this;
@@ -98,7 +127,7 @@ export class Flipcard {
98
127
  <span class="hidden-visually">Show More Information</span>
99
128
  `;
100
129
  }
101
- setVisiblity(visible) {
130
+ setVisibility(visible) {
102
131
  const { back, container, control } = this.elements;
103
132
  const state = visible ? "open" : "closed";
104
133
  back.style.zIndex = visible ? "10" : "1";
@@ -128,56 +157,7 @@ export class Flipcard {
128
157
  }
129
158
  }
130
159
 
131
- /**
132
- * Default data attributes
133
- */
134
- export const attrs = {
135
- init: "data-ulu-flipcard-init",
136
- flipcard: "data-ulu-flipcard",
137
- front: "data-ulu-flipcard-front",
138
- back: "data-ulu-flipcard-back",
139
- };
140
-
141
- // Utils for selecting things based on attributes
142
- const attrSelector = key => `[${ attrs[key] }]`;
143
- const attrSelectorInitial = key => `${ attrSelector(key) }:not([${ attrs.init }])`;
144
-
145
- // const containers = document.querySelectorAll('[data-ulu-flipcard]');
146
- const instances = [];
147
-
148
- export function init() {
149
- document.addEventListener(getName("pageModified"), setup);
150
- setup();
151
- }
152
160
 
153
- export function setup() {
154
- const builders = document.querySelectorAll(attrSelectorInitial("flipcard"));
155
- builders.forEach(setupFlipcard);
156
- }
157
-
158
- // containers.forEach(init);
159
-
160
- function setupFlipcard(container) {
161
- container.setAttribute(attrs.init, "");
162
- const options = getDatasetOptionalJson(container, "uluFlipcard");
163
- const config = Object.assign({}, options);
164
- const front = container.querySelector(attrSelectorInitial("front"));
165
- const back = container.querySelector(attrSelectorInitial("back"));
166
- instances.push(new Flipcard(container, front, back, config));
167
- }
168
-
169
- // getDatasetOptionalJson
170
- function setupSlider(container) {
171
- container.setAttribute(attrs.init, "");
172
- const options = getDatasetOptionalJson(container, "uluFlipcard");
173
- const config = Object.assign({}, options);
174
- const elements = {
175
- track: container.querySelector(attrSelector("track")),
176
- controls: container.querySelector(attrSelector("controls"))
177
- };
178
- // replace with OverflowScroller when finished removing sitescrollslider
179
- instances.push(new SiteScrollSlider(elements, config));
180
- }
181
161
 
182
162
  /**
183
163
  * Preliminary Notes:
package/js/ui/grid.js CHANGED
@@ -2,25 +2,27 @@
2
2
  * @module ui/grid
3
3
  */
4
4
 
5
+ import { ComponentInitializer } from "../utils/system.js";
5
6
  import { setPositionClasses } from "../utils/dom.js";
6
- import { getName } from "../events/index.js";
7
7
 
8
8
  /**
9
- * Sets up document for grid position classes
10
- * @param {String} selector The selector for the parent element
11
- * @param {Object} classes Classes (optional) @see setPositionClasses
9
+ * Dialog Component Initializer
12
10
  */
13
- export function init(selector = "[data-grid]", classes) {
14
- document.addEventListener(getName("pageModified"), () => setup(selector, classes));
15
- document.addEventListener(getName("pageResized"), () => setup(selector, classes));
16
- setup(selector, classes);
17
- }
11
+ export const initializer = new ComponentInitializer({
12
+ type: "grid",
13
+ baseAttribute: "data-grid"
14
+ });
18
15
 
19
16
  /**
20
- * Goes through document and finds elements that need to have positioning classes
21
- * @param {String} selector The selector for the parent element
17
+ * Sets up document for grid position classes
22
18
  * @param {Object} classes Classes (optional) @see setPositionClasses
23
19
  */
24
- export function setup(selector, classes) {
25
- document.querySelectorAll(selector).forEach(element => setPositionClasses(element, classes || undefined));
20
+ export function init(classes) {
21
+ initializer.init({
22
+ events: ["pageModified", "pageResized"],
23
+ setup({ element, initialize }) {
24
+ setPositionClasses(element, classes);
25
+ initialize();
26
+ }
27
+ });
26
28
  }
package/js/ui/index.js CHANGED
@@ -19,3 +19,4 @@ export * as print from "./print.js";
19
19
  export * as printDetails from "./print-details.js";
20
20
  export * as scrollSlider from "./scroll-slider.js";
21
21
  export * as themeToggle from "./theme-toggle.js";
22
+ export * as detailsGroup from "./details-group.js";
@@ -1,32 +1,61 @@
1
1
  /**
2
2
  * @module ui/modal-builder
3
+ * @description Note this module needs to be initialized before dialogs!
3
4
  */
4
5
 
5
- // Note this needs to be run before dialogs are initialized!
6
-
6
+ import { ComponentInitializer } from "../utils/system.js";
7
+ import { wrapSettingString } from "../settings.js";
7
8
  import { getName } from "../events/index.js";
8
9
  import { createElementFromHtml } from "@ulu/utils/browser/dom.js";
9
10
  import { Resizer } from "./resizer.js";
10
- import { getDatasetJson } from "../utils/dom.js";
11
- import { defaults as dialogDefaults, attrs as dialogAttrs } from "./dialog.js";
12
-
13
- const attrs = {
14
- builder: "data-ulu-modal-builder",
15
- body: "data-ulu-modal-builder-body",
16
- resizer: "data-ulu-modal-builder-resizer"
17
- };
11
+ import { baseAttribute, closeAttribute, defaults as dialogDefaults } from "./dialog.js";
18
12
 
19
- const attrSelector = key => `[${ attrs[key] }]`;
13
+ /**
14
+ * Modal Builder Component Initializer
15
+ */
16
+ export const initializer = new ComponentInitializer({
17
+ type: "modal-builder",
18
+ baseAttribute: "data-ulu-modal-builder"
19
+ });
20
20
 
21
21
  /**
22
22
  * Default builder options (extends dialog defaults, watch name collisions)
23
23
  * - Decided to extend defaults so the interface in HTML is singular
24
- * - This is sometimes easier to template (merging and serializing options
25
- * in twig for example)
24
+ * - This is sometimes easier to template (merging and serializing options
25
+ * in twig for example)
26
+ * @typedef {object} DefaultModalOptions
27
+ * @property {string|null} title - The title of the modal. Defaults to `null`.
28
+ * @property {string|null} titleIcon - The class name for an icon to display in the title. Defaults to `null`.
29
+ * @property {string} titleClass - Extra class/classes to add to title
30
+ * @property {boolean} nonModal - If `true`, the modal will not prevent interaction with elements behind it. Defaults to `false`.
31
+ * @property {boolean} documentEnd - If `true`, the modal will be appended to the end of the `document.body`. Defaults to `true`.
32
+ * @property {boolean} allowResize - If `true`, the modal will be resizable. Defaults to `false`.
33
+ * @property {"center"|"top-left"|"top-center"|"top-right"|"bottom-left"|"bottom-center"|"bottom-right"} position - The initial position of the modal. Defaults to `"center"`.
34
+ * @property {boolean} bodyFills - If `true`, the modal body will fill the available space. Defaults to `false`.
35
+ * @property {boolean} noBackdrop - If `true`, no backdrop will be displayed behind the modal. Defaults to `false`.
36
+ * @property {"default"|"small"|"large"|"fullscreen"} size - The size of the modal. Defaults to `"default"`.
37
+ * @property {boolean} print - If `true`, the modal content will be optimized for printing. Defaults to `false`.
38
+ * @property {boolean} noMinHeight - If `true`, the modal will not have a minimum height. Defaults to `false`.
39
+ * @property {string} class - Additional CSS class(es) to add to the modal. Defaults to `""`.
40
+ * @property {string} baseClass - The base CSS class for the modal elements. Defaults to `"modal"`.
41
+ * @property {string} classCloseIcon - The class name for the close icon. Uses the wrapped setting string.
42
+ * @property {string} classResizerIcon - The class name for the resizer icon. Uses the wrapped setting string.
43
+ * @property {boolean} debug - Enables debug logging. Defaults to `false`.
44
+ * @property {function(object): string} templateCloseIcon - A function that returns the HTML for the close icon.
45
+ * @property {function(object): string} templateCloseIcon.config - The resolved modal configuration object.
46
+ * @returns {string} The HTML string for the close icon.
47
+ * @property {function(object): string} templateResizerIcon - A function that returns the HTML for the resizer icon.
48
+ * @property {function(object): string} templateResizerIcon.config - The resolved modal configuration object.
49
+ * @returns {string} The HTML string for the resizer icon.
50
+ * @property {function(string, DefaultModalOptions): string} template - The default modal template function.
51
+ * @param {string} template.id - The ID for the new modal.
52
+ * @param {DefaultModalOptions} template.config - The resolved modal options.
53
+ * @returns {string} Markup for the modal.
26
54
  */
27
55
  export const defaults = {
28
56
  title: null,
29
57
  titleIcon: null,
58
+ titleClass: "",
30
59
  nonModal: false,
31
60
  documentEnd: true,
32
61
  allowResize: false,
@@ -37,14 +66,17 @@ export const defaults = {
37
66
  print: false,
38
67
  noMinHeight: false,
39
68
  class: "",
40
- classCloseIcon: "css-icon css-icon--close",
41
- classResizerIcon: "css-icon css-icon--drag",
69
+ baseClass: "modal",
70
+ classCloseIcon: wrapSettingString("iconClassClose"),
71
+ classResizerIcon: wrapSettingString("iconClassDragX"),
42
72
  debug: false,
43
73
  templateCloseIcon(config) {
44
- return `<span class="modal__close-icon ${ config.classCloseIcon }" aria-hidden="true"></span>`;
74
+ const { baseClass, classCloseIcon } = config;
75
+ return `<span class="${ baseClass }__close-icon ${ classCloseIcon }" aria-hidden="true"></span>`;
45
76
  },
46
77
  templateResizerIcon(config) {
47
- return `<span class="modal__resizer-icon ${ config.classResizerIcon }" aria-hidden="true"></span>`;
78
+ const { baseClass, classResizerIcon } = config;
79
+ return `<span class="${ baseClass }__resizer-icon ${ classResizerIcon }" aria-hidden="true"></span>`;
48
80
  },
49
81
  /**
50
82
  * Default modal template
@@ -53,35 +85,36 @@ export const defaults = {
53
85
  * @returns {String} Markup for modal
54
86
  */
55
87
  template(id, config) {
88
+ const { baseClass } = config;
56
89
  const classes = [
57
- "modal",
58
- `modal--${ config.position }`,
59
- `modal--${ config.size }`,
60
- `modal--${ config.allowResize ? "resize" : "no-resize" }`,
61
- ...(!config.title ? ["modal--no-header"] : []),
62
- ...(config.bodyFills ? ["modal--body-fills"] : []),
63
- ...(config.noBackdrop ? ["modal--no-backdrop"] : []),
64
- ...(config.noMinHeight ? ["modal--no-min-height"] : [] ),
90
+ baseClass,
91
+ `${ baseClass }--${ config.position }`,
92
+ `${ baseClass }--${ config.size }`,
93
+ `${ baseClass }--${ config.allowResize ? "resize" : "no-resize" }`,
94
+ ...(!config.title ? [`${ baseClass }--no-header`] : []),
95
+ ...(config.bodyFills ? [`${ baseClass }--body-fills`] : []),
96
+ ...(config.noBackdrop ? [`${ baseClass }--no-backdrop`] : []),
97
+ ...(config.noMinHeight ? [`${ baseClass }--no-min-height`] : [] ),
65
98
  ...(config.class ? [config.class] : []),
66
99
  ];
67
100
  return `
68
101
  <dialog id="${ id }" class="${ classes.join(" ") }">
69
102
  ${ config.title ? `
70
- <header class="modal__header">
71
- <h2 class="modal__title">
103
+ <header class="${ baseClass }__header">
104
+ <h2 class="${ baseClass }__title ${ config.titleClass }">
72
105
  ${ config.titleIcon ?
73
- `<span class="modal__title-icon ${ config.titleIcon }" aria-hidden="true"></span>` : ""
106
+ `<span class="${ baseClass }__title-icon ${ config.titleIcon }" aria-hidden="true"></span>` : ""
74
107
  }
75
- <span class="modal__title-text">${ config.title }</span>
108
+ <span class="${ baseClass }__title-text">${ config.title }</span>
76
109
  </h2>
77
- <button class="modal__close" aria-label="Close modal" ${ dialogAttrs.close } autofocus>
110
+ <button class="${ baseClass }__close" aria-label="Close modal" ${ closeAttribute } autofocus>
78
111
  ${ config.templateCloseIcon(config) }
79
112
  </button>
80
113
  </header>
81
114
  ` : "" }
82
- <div class="modal__body" ${ attrs.body }></div>
115
+ <div class="${ baseClass }__body" ${ initializer.getAttribute("body") }></div>
83
116
  ${ config.hasResizer ?
84
- `<div class="modal__resizer" ${ attrs.resizer }>
117
+ `<div class="${ baseClass }__resizer" ${ initializer.getAttribute("resizer") }>
85
118
  ${ config.templateResizerIcon(config) }
86
119
  </div>` : ""
87
120
  }
@@ -105,26 +138,13 @@ export function setDefaults(options) {
105
138
  * - This will only initialize elements once, it is safe to call on page changes
106
139
  */
107
140
  export function init() {
108
- document.addEventListener(getName("pageModified"), setup);
109
- setup();
110
- }
111
-
112
- /**
113
- * Query and setup all builder
114
- */
115
- export function setup() {
116
- const builders = document.querySelectorAll(attrSelector("builder"));
117
- builders.forEach(setupBuilder);
118
- }
119
-
120
- /**
121
- * Build a dialog for the given content
122
- * @param {Node} element
123
- */
124
- export function setupBuilder(element) {
125
- const options = getDatasetJson(element, "uluModalBuilder");
126
- element.removeAttribute(attrs.builder);
127
- buildModal(element, options);
141
+ initializer.init({
142
+ withData: true,
143
+ events: ["pageModified"],
144
+ setup({ element, data }) {
145
+ buildModal(element, data);
146
+ }
147
+ });
128
148
  }
129
149
 
130
150
  /**
@@ -140,7 +160,7 @@ export function buildModal(content, options) {
140
160
  config.hasResizer = true;
141
161
  }
142
162
  if (config.debug) {
143
- console.log(config, content);
163
+ initializer.log(config, content);
144
164
  }
145
165
  if (!content.id) {
146
166
  throw new Error("Missing ID on modal");
@@ -148,7 +168,7 @@ export function buildModal(content, options) {
148
168
 
149
169
  const markup = config.template(content.id, config);
150
170
  const modal = createElementFromHtml(markup.trim());
151
- const selectChild = key => modal.querySelector(attrSelector(key));
171
+ const selectChild = key => modal.querySelector(initializer.attributeSelector(key));
152
172
  const body = selectChild("body");
153
173
  const resizer = selectChild("resizer");
154
174
  const dialogOptions = separateDialogOptions(config);
@@ -156,12 +176,12 @@ export function buildModal(content, options) {
156
176
  // Replace content with new dialog, and then insert the content into the new dialogs body
157
177
  content.removeAttribute("id");
158
178
  content.removeAttribute("hidden");
159
- content.removeAttribute(attrs.builder);
179
+ content.removeAttribute(initializer.getAttribute());
160
180
  content.parentNode.replaceChild(modal, content);
161
181
  body.appendChild(content);
162
182
 
163
183
  // Add dialog options for other scripts
164
- modal.setAttribute(dialogAttrs.dialog, JSON.stringify(dialogOptions));
184
+ modal.setAttribute(baseAttribute, JSON.stringify(dialogOptions));
165
185
 
166
186
  if (config.hasResizer) {
167
187
  new Resizer(modal, resizer, {
@@ -10,6 +10,7 @@
10
10
  * @todo - Document that user could use something like [https://github.com/LachlanArthur/scroll-snap-api/tree/master/src] to have it go between items
11
11
  *
12
12
  */
13
+ import { wrapSettingString } from "../settings.js";
13
14
  import { hasRequiredProps } from '@ulu/utils/object.js';
14
15
  import { logError } from "../utils/class-logger.js";
15
16
  const requiredElements = [
@@ -26,14 +27,15 @@ export class OverflowScroller {
26
27
  offsetEnd: 100,
27
28
  amount: "auto",
28
29
  buttonClasses: ["button", "button--icon"],
29
- iconClassesPrevious: ["css-icon", "css-icon--angle-left"],
30
- iconClassesNext: ["css-icon", "css-icon--angle-right"]
30
+ iconClassPrevious: wrapSettingString("iconClassPrevious"),
31
+ iconClassNext: wrapSettingString("iconClassNext"),
31
32
  }
32
33
  constructor(elements, config) {
33
34
  this.options = Object.assign({}, OverflowScroller.defaults, config);
34
35
  if (!hasRequiredProps(requiredElements)) {
35
36
  logError(this, 'Missing a required Element');
36
37
  }
38
+ console.log(elements)
37
39
  this.elements = {
38
40
  ...elements,
39
41
  ...this.createControls(elements.controls)
@@ -87,10 +89,10 @@ export class OverflowScroller {
87
89
  return button;
88
90
  }
89
91
  getControlContent(action) {
90
- const classes = this.options[action === "next" ? "iconClassesNext" : "iconClassesPrevious"];
92
+ const classes = this.options[action === "next" ? "iconClassNext" : "iconClassPrevious"];
91
93
  return `
92
94
  <span class="hidden-visually">${ action }</span>
93
- <span class="${ classes.join(' ') }" aria-hidden="true"></span>
95
+ <span class="${ classes }" aria-hidden="true"></span>
94
96
  `;
95
97
  }
96
98
  onScroll(event) {
package/js/ui/popover.js CHANGED
@@ -2,24 +2,27 @@
2
2
  * @module ui/popover
3
3
  */
4
4
 
5
- import { getName } from "../events/index.js";
5
+ import { ComponentInitializer } from "../utils/system.js";
6
6
  import { createFloatingUi } from "../utils/floating-ui.js";
7
7
  import { Collapsible } from "./collapsible.js";
8
8
 
9
9
  /**
10
- * Array of current instances
10
+ * Popover Component Initializer
11
11
  */
12
- export const instances = new WeakMap;
12
+ export const initializer = new ComponentInitializer({
13
+ type: "popover",
14
+ baseAttribute: "data-ulu-popover"
15
+ });
13
16
 
14
- const logError = (...msgs) => console.error("@ulu (popovers):", ...msgs);
17
+ const attrSelectorAnchor = initializer.attributeSelector("trigger-anchor");
18
+ const attrSelectorArrow = initializer.attributeSelector("arrow");
19
+ const attrContent = initializer.getAttribute("content");
20
+ const attrSelectorContent = initializer.attributeSelector("content");
15
21
 
16
- const attrs = {
17
- trigger: "data-ulu-popover-trigger",
18
- content: "data-ulu-popover-content",
19
- arrow: "data-ulu-popover-arrow",
20
- anchor: "data-ulu-popover-trigger-anchor",
21
- };
22
- const attrSelector = key => `[${ attrs[key] }]`;
22
+ /**
23
+ * Array of current instances
24
+ */
25
+ export const instances = new WeakMap;
23
26
 
24
27
  // This modules collapsible defaults
25
28
  const collapsibleDefaults = {
@@ -31,47 +34,44 @@ const collapsibleDefaults = {
31
34
  * Initialize default popover
32
35
  */
33
36
  export function init() {
34
- document.addEventListener(getName("pageModified"), setup);
35
- setup();
36
- }
37
+ initializer.init({
38
+ key: "trigger",
39
+ withData: true,
40
+ events: ["pageModified"],
41
+ setup({ element, data, initialize }) {
42
+ if (instances.has(element)) return;
43
+ const resolved = resolve(element, data);
37
44
 
38
- /**
39
- * Query all popovers on current page and set them up
40
- * - Use this manually if needed
41
- * - Won't setup a popover more than once
42
- */
43
- export function setup() {
44
- const triggers = document.querySelectorAll(attrSelector("trigger"));
45
- // Only triggers we don't have instances for
46
- const resolved = Array.from(triggers)
47
- .filter(trigger => !instances.has(trigger))
48
- .map(resolve)
49
- .filter(v => v);
45
+ if (!resolved) {
46
+ initializer.warn("Unable to resolve popover elements for trigger.", element);
47
+ return;
48
+ }
50
49
 
51
- resolved.forEach(({ elements, options, floatingOptions }) => {
52
- instances.set(elements.trigger, new Popover(elements, options, floatingOptions));
50
+ const { elements, options, floatingOptions } = resolved;
51
+ instances.set(elements, new Popover(elements, options, floatingOptions));
52
+ initialize();
53
+ }
53
54
  });
54
55
  }
55
56
 
56
57
  /**
57
58
  * Find the popover's elements
58
59
  */
59
- export function resolve(trigger) {
60
- const raw = trigger.dataset.uluPopoverTrigger;
61
- const options = raw?.length ? JSON.parse(raw) : {};
60
+ export function resolve(trigger, userOptions) {
61
+ const options = Object.assign({}, userOptions);
62
62
  const content = getContentByTrigger(trigger);
63
63
  const elements = {
64
64
  trigger,
65
65
  content,
66
- anchor: trigger.querySelector(attrSelector("anchor")) || trigger,
67
- contentArrow: content.querySelector(attrSelector("arrow"))
66
+ anchor: trigger.querySelector(attrSelectorAnchor) || trigger,
67
+ contentArrow: content.querySelector(attrSelectorArrow)
68
68
  };
69
69
  const floatingOptions = options.floating || {};
70
70
  delete options.floating;
71
71
  if (content) {
72
72
  return { elements, options, floatingOptions };
73
73
  } else {
74
- logError("Unable to make popover for", trigger);
74
+ initializer.logError("Unable to make popover for", trigger);
75
75
  return false;
76
76
  }
77
77
  }
@@ -85,17 +85,17 @@ export function getContentByTrigger(trigger) {
85
85
 
86
86
  if (ariaControls) {
87
87
  content = document.getElementById(ariaControls);
88
- } else if (trigger?.nextElementSibling?.hasAttribute(attrs.content)) {
88
+ } else if (trigger?.nextElementSibling?.hasAttribute(attrContent)) {
89
89
  content = trigger.nextElementSibling;
90
90
  // @todo - Consider removing this (non standard, users like this should be using aria-controls)
91
91
  } else {
92
92
  const children = Array.from(trigger.parentNode.children);
93
93
  const triggerIndex = children.findIndex(c => c === trigger);
94
94
  const childrenAfter = children.slice(triggerIndex);
95
- content = childrenAfter.find(child => child.matches(attrSelector("content")));
95
+ content = childrenAfter.find(child => child.matches(attrSelectorContent));
96
96
  }
97
97
  if (!content) {
98
- logError("Unable to resolve 'content' element for popover", trigger);
98
+ initializer.logError("Unable to resolve 'content' element for popover", trigger);
99
99
  }
100
100
  return content;
101
101
  }
@@ -123,7 +123,7 @@ export class Popover extends Collapsible {
123
123
  }
124
124
  createFloatingInstance() {
125
125
  const { content, anchor, contentArrow } = this.elements;
126
- const floatingElements = { trigger: anchor, contentArrow, content };
126
+ const floatingElements = { trigger: anchor, contentArrow, content };
127
127
  this.floatingCleanup = createFloatingUi(floatingElements, this.floatingOptions);
128
128
  }
129
129
  destroyFloatingInstance() {
package/js/ui/print.js CHANGED
@@ -2,18 +2,14 @@
2
2
  * @module ui/print
3
3
  */
4
4
 
5
- import { getName } from "../events/index.js";
6
- import { getDatasetOptionalJson, getElement } from "../utils/dom.js";
5
+ import { ComponentInitializer } from "../utils/system.js";
6
+ import { getElement } from "../utils/dom.js";
7
7
  import { printElement } from "@ulu/utils/browser/print.js";
8
8
 
9
- export const attrs = {
10
- trigger: "data-ulu-print",
11
- init: "data-ulu-print-init",
12
- };
13
-
14
- const attrSelector = key => `[${ attrs[key] }]`;
15
- const attrSelectorInitial = key => `${ attrSelector(key) }:not([${ attrs.init }])`;
16
- const queryAllInitial = key => document.querySelectorAll(attrSelectorInitial(key));
9
+ const initializer = new ComponentInitializer({
10
+ type: "print",
11
+ baseAttribute: "data-ulu-print"
12
+ });
17
13
 
18
14
  /**
19
15
  * Default options
@@ -30,27 +26,22 @@ const defaults = {
30
26
  * - This will only initialize elements once, it is safe to call on page changes
31
27
  */
32
28
  export function init() {
33
- document.addEventListener(getName("pageModified"), setup);
34
- setup();
35
- }
36
-
37
- /**
38
- * Setup all triggers currently on the page
39
- */
40
- function setup() {
41
- const triggers = queryAllInitial("trigger");
42
- triggers.forEach(trigger => {
43
- const options = getDatasetOptionalJson(trigger, "uluPrint");
44
- setupTrigger(trigger, options);
29
+ initializer.init({
30
+ withData: true,
31
+ events: ["pageModified"],
32
+ setup({ element, data, initialize }) {
33
+ setupTrigger(element, data);
34
+ initialize();
35
+ }
45
36
  });
46
37
  }
47
38
 
48
39
  /**
49
40
  * Setup a single trigger (can be used manually without attr if needed)
50
41
  */
51
- function setupTrigger(trigger, options) {
52
- const config = Object.assign({}, defaults, options);
53
- trigger.addEventListener("click", (event) => {
42
+ function setupTrigger(trigger, userOptions) {
43
+ const config = Object.assign({}, defaults, userOptions);
44
+ trigger.addEventListener("click", () => {
54
45
  // Option to print a specific element
55
46
  if (config.element) {
56
47
  const element = getElement(config.element);