@ulu/frontend 0.1.0-beta.32 → 0.1.0-beta.34

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 (214) hide show
  1. package/CHANGELOG.md +53 -0
  2. package/dist/ulu-frontend.min.css +1 -1
  3. package/dist/ulu-frontend.min.js +23 -23
  4. package/docs-dev/changelog/index.html +161 -8
  5. package/docs-dev/demos/accordion/index.html +38 -8
  6. package/docs-dev/demos/button/index.html +38 -8
  7. package/docs-dev/demos/button-verbose/index.html +38 -8
  8. package/docs-dev/demos/callout/index.html +65 -8
  9. package/docs-dev/demos/captioned-figure/index.html +38 -8
  10. package/docs-dev/demos/card/index.html +59 -33
  11. package/docs-dev/demos/card-grid/index.html +42 -12
  12. package/docs-dev/demos/css-icons/index.html +38 -8
  13. package/docs-dev/demos/data-grid/index.html +38 -8
  14. package/docs-dev/demos/data-table/index.html +63 -33
  15. package/docs-dev/demos/details-group/index.html +71 -8
  16. package/docs-dev/demos/file-save/index.html +38 -8
  17. package/docs-dev/demos/flipcard/index.html +38 -8
  18. package/docs-dev/demos/form-theme/index.html +38 -8
  19. package/docs-dev/demos/index.html +38 -8
  20. package/docs-dev/demos/list-inline/index.html +38 -8
  21. package/docs-dev/demos/list-lines/index.html +38 -8
  22. package/docs-dev/demos/menu-stack/index.html +38 -8
  23. package/docs-dev/demos/modals/index.html +51 -10
  24. package/docs-dev/demos/nav-strip/index.html +38 -8
  25. package/docs-dev/demos/overlay-section/index.html +38 -8
  26. package/docs-dev/demos/popovers/index.html +38 -8
  27. package/docs-dev/demos/print/index.html +38 -8
  28. package/docs-dev/demos/pull-quote/index.html +38 -8
  29. package/docs-dev/demos/rule/index.html +38 -8
  30. package/docs-dev/demos/scrollpoints/index.html +39 -9
  31. package/docs-dev/demos/spoke-spinner/index.html +38 -8
  32. package/docs-dev/demos/sticky-list/index.html +38 -8
  33. package/docs-dev/demos/tabs/index.html +74 -8
  34. package/docs-dev/demos/tag/index.html +38 -8
  35. package/docs-dev/demos/theme-toggle/index.html +38 -8
  36. package/docs-dev/demos/tiles/index.html +38 -8
  37. package/docs-dev/demos/tooltip/index.html +38 -8
  38. package/docs-dev/guide/building-stylesheet/index.html +38 -8
  39. package/docs-dev/guide/developing-ulu-scss-module/index.html +38 -8
  40. package/docs-dev/guide/index.html +38 -8
  41. package/docs-dev/index.html +38 -8
  42. package/docs-dev/javascript/events/index.html +38 -8
  43. package/docs-dev/javascript/index.html +38 -8
  44. package/docs-dev/javascript/settings/index.html +38 -8
  45. package/docs-dev/javascript/ui-breakpoints/index.html +38 -8
  46. package/docs-dev/javascript/ui-collapsible/index.html +38 -8
  47. package/docs-dev/javascript/ui-details-group/index.html +56 -38
  48. package/docs-dev/javascript/ui-dialog/index.html +70 -25
  49. package/docs-dev/javascript/ui-flipcard/index.html +99 -13
  50. package/docs-dev/javascript/ui-grid/index.html +48 -44
  51. package/docs-dev/javascript/ui-modal-builder/index.html +49 -40
  52. package/docs-dev/javascript/ui-overflow-scroller/index.html +38 -8
  53. package/docs-dev/javascript/ui-overflow-scroller-pager/index.html +38 -8
  54. package/docs-dev/javascript/ui-page/index.html +38 -8
  55. package/docs-dev/javascript/ui-popover/index.html +46 -20
  56. package/docs-dev/javascript/ui-print/index.html +38 -16
  57. package/docs-dev/javascript/ui-print-details/index.html +38 -8
  58. package/docs-dev/javascript/ui-programmatic-modal/index.html +38 -8
  59. package/docs-dev/javascript/ui-proxy-click/index.html +125 -10
  60. package/docs-dev/javascript/ui-resizer/index.html +38 -8
  61. package/docs-dev/javascript/ui-scroll-slider/index.html +76 -14
  62. package/docs-dev/javascript/ui-scrollpoint/index.html +44 -21
  63. package/docs-dev/javascript/ui-slider/index.html +234 -13
  64. package/docs-dev/javascript/ui-tabs/index.html +49 -56
  65. package/docs-dev/javascript/ui-theme-toggle/index.html +43 -21
  66. package/docs-dev/javascript/ui-tooltip/index.html +45 -19
  67. package/docs-dev/javascript/utils-class-logger/index.html +38 -8
  68. package/docs-dev/javascript/utils-dom/index.html +63 -8
  69. package/docs-dev/javascript/utils-file-save/index.html +38 -8
  70. package/docs-dev/javascript/utils-floating-ui/index.html +38 -8
  71. package/docs-dev/javascript/utils-id/index.html +38 -8
  72. package/docs-dev/javascript/utils-pause-youtube-video/index.html +38 -8
  73. package/docs-dev/javascript/utils-system/index.html +5437 -0
  74. package/docs-dev/sass/base/color/index.html +38 -8
  75. package/docs-dev/sass/base/elements/index.html +38 -8
  76. package/docs-dev/sass/base/index/index.html +38 -8
  77. package/docs-dev/sass/base/index.html +38 -8
  78. package/docs-dev/sass/base/keyframes/index.html +38 -8
  79. package/docs-dev/sass/base/layout/index.html +38 -8
  80. package/docs-dev/sass/base/normalize/index.html +38 -8
  81. package/docs-dev/sass/base/print/index.html +38 -8
  82. package/docs-dev/sass/base/root/index.html +38 -8
  83. package/docs-dev/sass/base/typography/index.html +38 -8
  84. package/docs-dev/sass/components/accordion/index.html +39 -9
  85. package/docs-dev/sass/components/adaptive-spacing/index.html +38 -8
  86. package/docs-dev/sass/components/badge/index.html +38 -8
  87. package/docs-dev/sass/components/basic-hero/index.html +38 -8
  88. package/docs-dev/sass/components/button/index.html +38 -8
  89. package/docs-dev/sass/components/button-verbose/index.html +72 -37
  90. package/docs-dev/sass/components/callout/index.html +124 -35
  91. package/docs-dev/sass/components/captioned-figure/index.html +38 -8
  92. package/docs-dev/sass/components/card/index.html +38 -8
  93. package/docs-dev/sass/components/card-grid/index.html +38 -8
  94. package/docs-dev/sass/components/css-icon/index.html +38 -8
  95. package/docs-dev/sass/components/data-grid/index.html +38 -8
  96. package/docs-dev/sass/components/data-table/index.html +53 -16
  97. package/docs-dev/sass/components/fill-context/index.html +38 -8
  98. package/docs-dev/sass/components/flipcard/index.html +38 -8
  99. package/docs-dev/sass/components/flipcard-grid/index.html +38 -8
  100. package/docs-dev/sass/components/form-theme/index.html +84 -60
  101. package/docs-dev/sass/components/hero/index.html +38 -8
  102. package/docs-dev/sass/components/horizontal-rule/index.html +38 -8
  103. package/docs-dev/sass/components/image-grid/index.html +38 -8
  104. package/docs-dev/sass/components/index/index.html +38 -8
  105. package/docs-dev/sass/components/index.html +38 -8
  106. package/docs-dev/sass/components/links/index.html +38 -8
  107. package/docs-dev/sass/components/list-inline/index.html +38 -8
  108. package/docs-dev/sass/components/list-lines/index.html +38 -8
  109. package/docs-dev/sass/components/list-ordered/index.html +38 -8
  110. package/docs-dev/sass/components/list-unordered/index.html +38 -8
  111. package/docs-dev/sass/components/menu-stack/index.html +38 -8
  112. package/docs-dev/sass/components/modal/index.html +38 -8
  113. package/docs-dev/sass/components/nav-strip/index.html +38 -8
  114. package/docs-dev/sass/components/overlay-section/index.html +38 -8
  115. package/docs-dev/sass/components/pager/index.html +38 -8
  116. package/docs-dev/sass/components/placeholder-block/index.html +38 -8
  117. package/docs-dev/sass/components/popover/index.html +38 -8
  118. package/docs-dev/sass/components/pull-quote/index.html +38 -8
  119. package/docs-dev/sass/components/ratio-box/index.html +38 -8
  120. package/docs-dev/sass/components/rule/index.html +38 -8
  121. package/docs-dev/sass/components/scroll-slider/index.html +46 -28
  122. package/docs-dev/sass/components/skip-link/index.html +38 -8
  123. package/docs-dev/sass/components/slider/index.html +38 -8
  124. package/docs-dev/sass/components/spoke-spinner/index.html +40 -10
  125. package/docs-dev/sass/components/sticky-list/index.html +38 -8
  126. package/docs-dev/sass/components/tabs/index.html +38 -8
  127. package/docs-dev/sass/components/tag/index.html +40 -10
  128. package/docs-dev/sass/components/tile-button/index.html +38 -8
  129. package/docs-dev/sass/components/tile-grid/index.html +38 -8
  130. package/docs-dev/sass/components/tile-grid-overlay/index.html +38 -8
  131. package/docs-dev/sass/components/vignette/index.html +38 -8
  132. package/docs-dev/sass/components/wysiwyg/index.html +38 -8
  133. package/docs-dev/sass/core/breakpoint/index.html +38 -8
  134. package/docs-dev/sass/core/button/index.html +38 -8
  135. package/docs-dev/sass/core/color/index.html +38 -8
  136. package/docs-dev/sass/core/cssvar/index.html +38 -8
  137. package/docs-dev/sass/core/element/index.html +218 -47
  138. package/docs-dev/sass/core/index.html +38 -8
  139. package/docs-dev/sass/core/layout/index.html +94 -45
  140. package/docs-dev/sass/core/path/index.html +38 -8
  141. package/docs-dev/sass/core/selector/index.html +38 -8
  142. package/docs-dev/sass/core/typography/index.html +38 -8
  143. package/docs-dev/sass/core/units/index.html +38 -8
  144. package/docs-dev/sass/core/utils/index.html +302 -68
  145. package/docs-dev/sass/helpers/color/index.html +38 -8
  146. package/docs-dev/sass/helpers/display/index.html +38 -8
  147. package/docs-dev/sass/helpers/index/index.html +38 -8
  148. package/docs-dev/sass/helpers/index.html +38 -8
  149. package/docs-dev/sass/helpers/print/index.html +38 -8
  150. package/docs-dev/sass/helpers/typography/index.html +38 -8
  151. package/docs-dev/sass/helpers/units/index.html +38 -8
  152. package/docs-dev/sass/helpers/utilities/index.html +38 -8
  153. package/docs-dev/sass/index.html +38 -8
  154. package/js/ui/breakpoints.js +1 -2
  155. package/js/ui/details-group.js +33 -42
  156. package/js/ui/dialog.js +64 -41
  157. package/js/ui/dialog.todo +2 -36
  158. package/js/ui/flipcard.js +37 -57
  159. package/js/ui/grid.js +15 -13
  160. package/js/ui/modal-builder.js +24 -38
  161. package/js/ui/popover.js +38 -39
  162. package/js/ui/print.js +16 -25
  163. package/js/ui/proxy-click.js +50 -36
  164. package/js/ui/scroll-slider.js +24 -30
  165. package/js/ui/scrollpoint.js +27 -63
  166. package/js/ui/slider.js +53 -55
  167. package/js/ui/tabs.js +23 -36
  168. package/js/ui/theme-toggle.js +37 -41
  169. package/js/ui/tooltip.js +27 -32
  170. package/js/utils/dom.js +12 -0
  171. package/js/utils/system.js +154 -0
  172. package/package.json +1 -1
  173. package/scss/_element.scss +91 -0
  174. package/scss/_layout.scss +3 -1
  175. package/scss/_utils.scss +42 -0
  176. package/scss/components/_accordion.scss +1 -2
  177. package/scss/components/_button-verbose.scss +41 -36
  178. package/scss/components/_callout.scss +113 -53
  179. package/scss/components/_data-table.scss +3 -0
  180. package/scss/components/_form-theme.scss +24 -25
  181. package/scss/components/_scroll-slider.scss +0 -4
  182. package/types/ui/breakpoints.d.ts.map +1 -1
  183. package/types/ui/details-group.d.ts +7 -12
  184. package/types/ui/details-group.d.ts.map +1 -1
  185. package/types/ui/dialog.d.ts +19 -14
  186. package/types/ui/dialog.d.ts.map +1 -1
  187. package/types/ui/flipcard.d.ts +16 -10
  188. package/types/ui/flipcard.d.ts.map +1 -1
  189. package/types/ui/grid.d.ts +4 -6
  190. package/types/ui/grid.d.ts.map +1 -1
  191. package/types/ui/modal-builder.d.ts +5 -9
  192. package/types/ui/modal-builder.d.ts.map +1 -1
  193. package/types/ui/popover.d.ts +6 -7
  194. package/types/ui/popover.d.ts.map +1 -1
  195. package/types/ui/print.d.ts +0 -4
  196. package/types/ui/print.d.ts.map +1 -1
  197. package/types/ui/proxy-click.d.ts +19 -3
  198. package/types/ui/proxy-click.d.ts.map +1 -1
  199. package/types/ui/scroll-slider.d.ts +5 -7
  200. package/types/ui/scroll-slider.d.ts.map +1 -1
  201. package/types/ui/scrollpoint.d.ts +3 -8
  202. package/types/ui/scrollpoint.d.ts.map +1 -1
  203. package/types/ui/slider.d.ts +22 -12
  204. package/types/ui/slider.d.ts.map +1 -1
  205. package/types/ui/tabs.d.ts +6 -8
  206. package/types/ui/tabs.d.ts.map +1 -1
  207. package/types/ui/theme-toggle.d.ts +6 -13
  208. package/types/ui/theme-toggle.d.ts.map +1 -1
  209. package/types/ui/tooltip.d.ts +3 -5
  210. package/types/ui/tooltip.d.ts.map +1 -1
  211. package/types/utils/dom.d.ts +6 -0
  212. package/types/utils/dom.d.ts.map +1 -1
  213. package/types/utils/system.d.ts +113 -0
  214. package/types/utils/system.d.ts.map +1 -0
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
  }
@@ -1,23 +1,22 @@
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
7
  import { wrapSettingString } from "../settings.js";
8
8
  import { getName } from "../events/index.js";
9
9
  import { createElementFromHtml } from "@ulu/utils/browser/dom.js";
10
10
  import { Resizer } from "./resizer.js";
11
- import { getDatasetJson } from "../utils/dom.js";
12
- import { defaults as dialogDefaults, attrs as dialogAttrs } from "./dialog.js";
13
-
14
- const attrs = {
15
- builder: "data-ulu-modal-builder",
16
- body: "data-ulu-modal-builder-body",
17
- resizer: "data-ulu-modal-builder-resizer"
18
- };
11
+ import { baseAttribute, closeAttribute, defaults as dialogDefaults } from "./dialog.js";
19
12
 
20
- 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
+ });
21
20
 
22
21
  /**
23
22
  * Default builder options (extends dialog defaults, watch name collisions)
@@ -75,14 +74,14 @@ export const defaults = {
75
74
  }
76
75
  <span class="modal__title-text">${ config.title }</span>
77
76
  </h2>
78
- <button class="modal__close" aria-label="Close modal" ${ dialogAttrs.close } autofocus>
77
+ <button class="modal__close" aria-label="Close modal" ${ closeAttribute } autofocus>
79
78
  ${ config.templateCloseIcon(config) }
80
79
  </button>
81
80
  </header>
82
81
  ` : "" }
83
- <div class="modal__body" ${ attrs.body }></div>
82
+ <div class="modal__body" ${ initializer.getAttribute("body") }></div>
84
83
  ${ config.hasResizer ?
85
- `<div class="modal__resizer" ${ attrs.resizer }>
84
+ `<div class="modal__resizer" ${ initializer.getAttribute("resizer") }>
86
85
  ${ config.templateResizerIcon(config) }
87
86
  </div>` : ""
88
87
  }
@@ -106,26 +105,13 @@ export function setDefaults(options) {
106
105
  * - This will only initialize elements once, it is safe to call on page changes
107
106
  */
108
107
  export function init() {
109
- document.addEventListener(getName("pageModified"), setup);
110
- setup();
111
- }
112
-
113
- /**
114
- * Query and setup all builder
115
- */
116
- export function setup() {
117
- const builders = document.querySelectorAll(attrSelector("builder"));
118
- builders.forEach(setupBuilder);
119
- }
120
-
121
- /**
122
- * Build a dialog for the given content
123
- * @param {Node} element
124
- */
125
- export function setupBuilder(element) {
126
- const options = getDatasetJson(element, "uluModalBuilder");
127
- element.removeAttribute(attrs.builder);
128
- buildModal(element, options);
108
+ initializer.init({
109
+ withData: true,
110
+ events: ["pageModified"],
111
+ setup({ element, data }) {
112
+ buildModal(element, data);
113
+ }
114
+ });
129
115
  }
130
116
 
131
117
  /**
@@ -141,7 +127,7 @@ export function buildModal(content, options) {
141
127
  config.hasResizer = true;
142
128
  }
143
129
  if (config.debug) {
144
- console.log(config, content);
130
+ initializer.log(config, content);
145
131
  }
146
132
  if (!content.id) {
147
133
  throw new Error("Missing ID on modal");
@@ -149,7 +135,7 @@ export function buildModal(content, options) {
149
135
 
150
136
  const markup = config.template(content.id, config);
151
137
  const modal = createElementFromHtml(markup.trim());
152
- const selectChild = key => modal.querySelector(attrSelector(key));
138
+ const selectChild = key => modal.querySelector(initializer.attributeSelector(key));
153
139
  const body = selectChild("body");
154
140
  const resizer = selectChild("resizer");
155
141
  const dialogOptions = separateDialogOptions(config);
@@ -157,12 +143,12 @@ export function buildModal(content, options) {
157
143
  // Replace content with new dialog, and then insert the content into the new dialogs body
158
144
  content.removeAttribute("id");
159
145
  content.removeAttribute("hidden");
160
- content.removeAttribute(attrs.builder);
146
+ content.removeAttribute(initializer.getAttribute());
161
147
  content.parentNode.replaceChild(modal, content);
162
148
  body.appendChild(content);
163
149
 
164
150
  // Add dialog options for other scripts
165
- modal.setAttribute(dialogAttrs.dialog, JSON.stringify(dialogOptions));
151
+ modal.setAttribute(baseAttribute, JSON.stringify(dialogOptions));
166
152
 
167
153
  if (config.hasResizer) {
168
154
  new Resizer(modal, resizer, {
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,8 +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 };
127
- console.log("this.floatingOptions:\n", this.floatingOptions);
126
+ const floatingElements = { trigger: anchor, contentArrow, content };
128
127
  this.floatingCleanup = createFloatingUi(floatingElements, this.floatingOptions);
129
128
  }
130
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);
@@ -1,26 +1,27 @@
1
1
  /**
2
2
  * @module ui/proxy-click
3
+ * @description Used for cards and things that look like they should be clickable
4
+ * even though the link in their content is the only clickable element. This way
5
+ * the entire cards content doesn't need to be in a link (which isn't accessible).
6
+ *
7
+ * The script allows only for clicks with a duration of 250ms to avoid conflict
8
+ * with a user selecting text. Works with either links or buttons because it just
9
+ * uses the elements .click(). Uses data-attributes for selection by default.
3
10
  */
4
11
 
12
+ import { ComponentInitializer } from "../utils/system.js";
5
13
 
6
- // Used for cards and things that look like they should be clickable even
7
- // though the link in their content is the only clickable element. This way the
8
- // entire cards content doesn't need to be in a link (which isn't accessible)
9
- // - The script allows only for clicks with a duration of 250ms to avoid
10
- // conflict with a user selecting text.
11
- // - Works with either links or buttons because it just uses the elements .click()
12
- // - Uses data-attributes for selection
13
- import { getName } from "../events/index.js";
14
- import { getDatasetOptionalJson } from "../utils/dom.js";
15
-
16
- const attrs = {
17
- trigger: "data-ulu-proxy-click",
18
- init: "data-ulu-proxy-click-init",
19
- };
20
-
21
- const attrSelector = key => `[${ attrs[key] }]`;
22
- const attrSelectorInitial = key => `${ attrSelector(key) }:not([${ attrs.init }])`;
14
+ /**
15
+ * Proxy Click Component Initializer
16
+ */
17
+ export const initializer = new ComponentInitializer({
18
+ type: "proxy-click",
19
+ baseAttribute: "data-ulu-proxy-click"
20
+ });
23
21
 
22
+ /**
23
+ * Default options
24
+ */
24
25
  export const defaults = {
25
26
  selector: "[data-ulu-proxy-click-source]",
26
27
  selectorPreventBase: "input, select, textarea, button, a, [tabindex='-1']",
@@ -32,7 +33,7 @@ export const defaults = {
32
33
  let currentDefaults = { ...defaults };
33
34
 
34
35
  /**
35
- * @param {Object} options Change options used as default for dialogs, can then be overriden by data attribute settings on element
36
+ * @param {Object} options Change options used as default for dialogs, can then be overridden by data attribute settings on element
36
37
  */
37
38
  export function setDefaults(options) {
38
39
  currentDefaults = Object.assign({}, currentDefaults, options);
@@ -42,26 +43,39 @@ export function setDefaults(options) {
42
43
  * - This will only initialize elements once, it is safe to call on page changes
43
44
  */
44
45
  export function init() {
45
- document.addEventListener(getName("pageModified"), () => setup());
46
- setup();
47
- }
48
-
49
- export function setup(context = document) {
50
- const proxies = context.querySelectorAll(attrSelectorInitial("trigger"));
51
- proxies.forEach(proxy => {
52
- const elOptions = getDatasetOptionalJson(proxy, "siteProxyClick");
53
- const options = Object.assign({}, currentDefaults, elOptions);
54
- const child = proxy.querySelector(options.selector);
55
- if (child) {
56
- attachHandlers(proxy, child, options);
57
- proxy.setAttribute(attrs.init, "");
58
- } else {
59
- console.error("Unable to locate proxy click source", options.selector);
46
+ initializer.init({
47
+ withData: true,
48
+ events: ["pageModified"],
49
+ setup({ element, data, initialize }) {
50
+ setupProxy(element, data);
51
+ initialize();
60
52
  }
61
53
  });
62
54
  }
63
- export function attachHandlers(proxy, child, options) {
64
- const { selectorPreventBase: spb, selectorPrevent: sp } = options;
55
+
56
+ /**
57
+ * Setup a single proxy click
58
+ * @param {Node} proxy The container who's click should proxy the click of inner element with options.selector (defaults to [data-ulu-proxy-click-source])
59
+ * @param {Object} userOptions Options to override defaults
60
+ */
61
+ export function setupProxy(proxy, userOptions) {
62
+ const options = Object.assign({}, currentDefaults, userOptions);
63
+ const child = proxy.querySelector(options.selector);
64
+ if (child) {
65
+ attachHandlers(proxy, child, options);
66
+ } else {
67
+ console.error("Unable to locate proxy click source", options.selector);
68
+ }
69
+ }
70
+
71
+ /**
72
+ * Main function for attaching behaviors that enable proxy click
73
+ * @param {Node} proxy The container who's click should proxy the click of inner element with options.selector (defaults to [data-ulu-proxy-click-source])
74
+ * @param {Node} child The element who is being proxied and will get clicked if the proxy is clicked (as long as not an interactive element within proxy)
75
+ * @param {Object} config Merged/final options object
76
+ */
77
+ export function attachHandlers(proxy, child, config) {
78
+ const { selectorPreventBase: spb, selectorPrevent: sp } = config;
65
79
  const selectorPrevent = `${ spb }${ sp ? `, ${ sp }` : "" }`;
66
80
  let start, shouldProxy;
67
81
  proxy.addEventListener("mousedown", ({ target, timeStamp }) => {
@@ -72,7 +86,7 @@ export function attachHandlers(proxy, child, options) {
72
86
  }
73
87
  });
74
88
  proxy.addEventListener("mouseup", ({ timeStamp }) => {
75
- if (shouldProxy && timeStamp - start < options.mousedownDurationPrevent) {
89
+ if (shouldProxy && timeStamp - start < config.mousedownDurationPrevent) {
76
90
  child.click();
77
91
  }
78
92
  });
@@ -2,29 +2,21 @@
2
2
  * @module ui/scroll-slider
3
3
  */
4
4
 
5
+ import { ComponentInitializer } from "../utils/system.js";
5
6
  import { OverflowScroller } from "./overflow-scroller.js";
6
7
  import { createPager } from "./overflow-scroller-pager.js";
7
- import { getName } from "../events/index.js";
8
- import { getDatasetOptionalJson } from "../utils/dom.js";
9
-
10
8
 
11
9
  /**
12
- * Default data attributes
10
+ * Scroll Slider Component Initializer
13
11
  */
14
- export const attrs = {
15
- init: "data-ulu-scroll-slider-init",
16
- slider: "data-ulu-scroll-slider",
17
- track: "data-ulu-scroll-slider-track",
18
- controls: "data-ulu-scroll-slider-control-context"
19
- };
20
-
21
- // Utils for selecting things based on attributes
22
- const attrSelector = key => `[${ attrs[key] }]`;
23
- const attrSelectorInitial = key => `${ attrSelector(key) }:not([${ attrs.init }])`;
24
-
12
+ export const initializer = new ComponentInitializer({
13
+ type: "scroll-slider",
14
+ baseAttribute: "data-ulu-scroll-slider"
15
+ });
25
16
 
17
+ const attrSelectorTrack = initializer.attributeSelector("track");
18
+ const attrSelectorControls = initializer.attributeSelector("controls");
26
19
  const instances = [];
27
-
28
20
  const defaults = {
29
21
  amount: createPager()
30
22
  };
@@ -34,23 +26,25 @@ const defaults = {
34
26
  * - This will only initialize elements once, it is safe to call on page changes
35
27
  */
36
28
  export function init() {
37
- document.addEventListener(getName("pageModified"), setup);
38
- setup();
29
+ initializer.init({
30
+ withData: true,
31
+ events: ["pageModified"],
32
+ setup({ element, data, initialize }) {
33
+ setupSlider(element, data);
34
+ initialize();
35
+ }
36
+ });
39
37
  }
40
38
 
41
- export function setup() {
42
- const builders = document.querySelectorAll(attrSelectorInitial("slider"));
43
- builders.forEach(setupSlider);
44
- }
45
-
46
- // getDatasetOptionalJson
47
- function setupSlider(container) {
48
- container.setAttribute(attrs.init, "");
49
- const options = getDatasetOptionalJson(container, "uluScrollSlider");
50
- const config = Object.assign({}, defaults, options);
39
+ /**
40
+ * Setup instance of scroll slider based on data-attributes
41
+ * @param {Node} container The scroll slider container
42
+ */
43
+ function setupSlider(container, userOptions) {
44
+ const config = Object.assign({}, defaults, userOptions);
51
45
  const elements = {
52
- track: container.querySelector(attrSelector("track")),
53
- controls: container.querySelector(attrSelector("controls"))
46
+ track: container.querySelector(attrSelectorTrack),
47
+ controls: container.querySelector(attrSelectorControls)
54
48
  };
55
49
  instances.push(new OverflowScroller(elements, config));
56
50
  }