@qhealth-design-system/core 1.16.5 → 1.17.0

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 (45) hide show
  1. package/.storybook/assets/storybook.css +1 -1
  2. package/.storybook/globals.js +10 -0
  3. package/CHANGELOG.md +2 -0
  4. package/package.json +1 -1
  5. package/src/components/_global/css/cta_links/component.scss +107 -14
  6. package/src/components/_global/css/forms/control_inputs/component.scss +65 -77
  7. package/src/components/_global/css/link_columns/component.scss +2 -2
  8. package/src/components/_global/html/scripts.html +0 -2
  9. package/src/components/_global/js/cta_links/global.js +33 -0
  10. package/src/components/_global/js/global.js +175 -138
  11. package/src/components/_global/js/tabs/global.js +6 -2
  12. package/src/components/banner_advanced/html/component.hbs +1 -1
  13. package/src/components/breadcrumbs/js/global.js +17 -4
  14. package/src/components/card_feature/html/component.hbs +1 -1
  15. package/src/components/card_multi_action/html/component.hbs +1 -1
  16. package/src/components/card_single_action/css/component.scss +38 -47
  17. package/src/components/card_single_action/html/component.hbs +1 -1
  18. package/src/components/code/css/component.scss +72 -73
  19. package/src/components/code/html/component.hbs +62 -19
  20. package/src/components/code/js/global.js +102 -86
  21. package/src/components/footer/css/component.scss +2 -4
  22. package/src/components/footer/html/component.hbs +11 -8
  23. package/src/components/header/css/component.scss +11 -11
  24. package/src/components/header/html/component.hbs +3 -3
  25. package/src/components/header/js/global.js +58 -65
  26. package/src/components/in_page_navigation/js/global.js +34 -31
  27. package/src/components/internal_navigation/js/global.js +13 -3
  28. package/src/components/main_navigation/css/component.scss +79 -13
  29. package/src/components/main_navigation/html/component.hbs +5 -5
  30. package/src/components/main_navigation/js/global.js +94 -115
  31. package/src/components/mega_main_navigation/css/component.scss +27 -14
  32. package/src/components/mega_main_navigation/html/component.hbs +5 -5
  33. package/src/components/mega_main_navigation/js/global.js +50 -55
  34. package/src/components/page_alert/css/component.scss +141 -179
  35. package/src/data/site.json +3 -3
  36. package/src/html/component-card_feature.html +74 -487
  37. package/src/html/component-card_single_action.html +219 -1175
  38. package/src/html/component-forms.html +202 -67
  39. package/src/stories/Checkboxes/Checkboxes.js +41 -0
  40. package/src/stories/Checkboxes/Checkboxes.mdx +45 -0
  41. package/src/stories/Checkboxes/Checkboxes.stories.js +209 -0
  42. package/src/stories/RadioButtons/RadioButtons.js +41 -0
  43. package/src/stories/RadioButtons/RadioButtons.mdx +45 -0
  44. package/src/stories/RadioButtons/RadioButtons.stories.js +209 -0
  45. package/src/styles/imports/mixins.scss +5 -43
@@ -1,6 +1,6 @@
1
- (function(QLD) {
1
+ (function (QLD) {
2
2
  "use strict";
3
-
3
+
4
4
  /**
5
5
  * The main namespace for all QLDDS functions and variables
6
6
  * @module _global
@@ -9,30 +9,30 @@
9
9
  QLD.utils = {
10
10
  /**
11
11
  * Add 'js' body class if JS is enabled on the page
12
- *
12
+ *
13
13
  * @memberof module:_global
14
14
  */
15
- 'browserJS': function() {
15
+ browserJS: function () {
16
16
  document.querySelector("html").classList.remove("no-js");
17
17
  document.querySelector("html").classList.add("js");
18
18
  },
19
-
19
+
20
20
  /**
21
- * Returns a function, that, as long as it continues to be invoked, will not
22
- * be triggered. The function will be called after it stops being called for
23
- * N milliseconds. If `immediate` is passed, trigger the function on the
24
- * leading edge, instead of the trailing.
25
- * https://davidwalsh.name/javascript-debounce-function
26
- *
27
- * @memberof module:_global
28
- *
29
- * @param {function} func
30
- * @param {number} wait
31
- * @param {boolean} immediate
32
- *
33
- * @returns {function}
34
- */
35
- 'debounce': function (func, wait, immediate) {
21
+ * Returns a function, that, as long as it continues to be invoked, will not
22
+ * be triggered. The function will be called after it stops being called for
23
+ * N milliseconds. If `immediate` is passed, trigger the function on the
24
+ * leading edge, instead of the trailing.
25
+ * https://davidwalsh.name/javascript-debounce-function
26
+ *
27
+ * @memberof module:_global
28
+ *
29
+ * @param {function} func
30
+ * @param {number} wait
31
+ * @param {boolean} immediate
32
+ *
33
+ * @returns {function}
34
+ */
35
+ debounce: function (func, wait, immediate) {
36
36
  var timeout;
37
37
  return function () {
38
38
  var context = this,
@@ -50,158 +50,161 @@
50
50
 
51
51
  /**
52
52
  * Convert nodeList to Array (for IE11)
53
- *
53
+ *
54
54
  * @memberof module:_global
55
- *
56
- * @param {*} node_list
57
- *
55
+ *
56
+ * @param {*} node_list
57
+ *
58
58
  * @returns {Node[]}
59
59
  */
60
- 'listToArray': function(node_list) {
60
+ listToArray: function (node_list) {
61
61
  return Array.prototype.slice.call(node_list);
62
62
  },
63
63
 
64
64
  /**
65
65
  * Set browser cookie
66
- *
66
+ *
67
67
  * @memberof module:_global
68
- *
69
- * @param {string} cookie_name
70
- * @param {string} cookie_value
68
+ *
69
+ * @param {string} cookie_name
70
+ * @param {string} cookie_value
71
71
  */
72
- 'setCookie': function(cookie_name, cookie_value) {
73
- var cookie_entry = cookie_name + '=' + encodeURIComponent(cookie_value) + ';';
74
- document.cookie = cookie_entry + '; path=/;';
72
+ setCookie: function (cookie_name, cookie_value) {
73
+ var cookie_entry = cookie_name + "=" + encodeURIComponent(cookie_value) + ";";
74
+ document.cookie = cookie_entry + "; path=/;";
75
75
  },
76
76
  /**
77
77
  * Get browser cookie
78
- *
78
+ *
79
79
  * @memberof module:_global
80
- *
81
- * @param {string} cookie_name
82
- *
80
+ *
81
+ * @param {string} cookie_name
82
+ *
83
83
  * @returns {c_value}
84
84
  */
85
- 'getCookie': function(cookie_name) {
85
+ getCookie: function (cookie_name) {
86
86
  var c_value = " " + document.cookie;
87
87
  var c_start = c_value.indexOf(" " + cookie_name + "=");
88
88
  if (c_start == -1) {
89
89
  c_value = null;
90
- }
91
- else {
90
+ } else {
92
91
  c_start = c_value.indexOf("=", c_start) + 1;
93
92
  var c_end = c_value.indexOf(";", c_start);
94
93
  if (c_end == -1) {
95
94
  c_end = c_value.length;
96
95
  }
97
- c_value = unescape(c_value.substring(c_start,c_end));
96
+ c_value = unescape(c_value.substring(c_start, c_end));
98
97
  }
99
98
  return c_value;
100
99
  },
101
100
  /**
102
101
  * Set browser local storage
103
- *
102
+ *
104
103
  * @memberof module:_global
105
- *
104
+ *
106
105
  * @param {string} storage_key
107
- * @param {string} storage_value
106
+ * @param {string} storage_value
108
107
  */
109
- 'setLocalStorage': function(storage_key, storage_value) {
110
- if (typeof(storage_value) !== 'string') {
108
+ setLocalStorage: function (storage_key, storage_value) {
109
+ if (typeof storage_value !== "string") {
111
110
  storage_value = JSON.stringify(storage_value);
112
111
  }
113
-
112
+
114
113
  localStorage.setItem(storage_key, storage_value);
115
114
  },
116
115
  /**
117
116
  * Get browser local storage from key
118
- *
117
+ *
119
118
  * @memberof module:_global
120
- *
121
- * @param {string} storage_key
122
- *
119
+ *
120
+ * @param {string} storage_key
121
+ *
123
122
  * @returns {localStorage.getItem(storage_key)}
124
123
  */
125
- 'getLocalStorage': function(storage_key) {
124
+ getLocalStorage: function (storage_key) {
126
125
  return localStorage.getItem(storage_key);
127
126
  },
128
127
  /**
129
128
  * Remove browser local storage item by key
130
- *
129
+ *
131
130
  * @memberof module:_global
132
- *
133
- * @param {string} storage_key
131
+ *
132
+ * @param {string} storage_key
134
133
  */
135
- 'removeLocalStorage': function(storage_key) {
134
+ removeLocalStorage: function (storage_key) {
136
135
  localStorage.removeItem(storage_key);
137
136
  },
138
137
  /**
139
138
  * Determine the location of the user using HTML5 geolocation
140
- *
139
+ *
141
140
  * @memberof module:_global
142
- *
141
+ *
143
142
  * @param {Boolean} override
144
143
  * @param {function} errorCallback
145
144
  */
146
- 'geolocateUser': function(override, errorCallback) {
147
-
148
- var userLocationStorage = QLD.utils.getLocalStorage('qld_user_location');
149
- if(userLocationStorage !== null && !override) {
145
+ geolocateUser: function (override, errorCallback) {
146
+ var userLocationStorage = QLD.utils.getLocalStorage("qld_user_location");
147
+ if (userLocationStorage !== null && !override) {
150
148
  return JSON.parse(userLocationStorage);
151
149
  }
152
150
 
153
151
  if (navigator.geolocation) {
154
-
155
152
  QLD.utils.setLoadingState(true);
156
- navigator.geolocation.getCurrentPosition(function(position) {
157
- var location = {
158
- "latitude": position.coords.latitude,
159
- "longitude": position.coords.longitude,
160
- "isGeolocated": true,
161
- "location": ''
162
- };
163
-
164
- QLD.utils.setUserLocation(location);
165
- QLD.utils.removeLocalStorage('deny-location');
166
- return `${position.coords.latitude},${position.coords.longitude}`;
167
- }, function(error) {
168
- console.log(error);
169
- QLD.utils.setLoadingState(false);
170
- if (errorCallback) {
171
- errorCallback();
172
- }
173
- return false;
174
- }, { timeout: 10000 });
153
+ navigator.geolocation.getCurrentPosition(
154
+ function (position) {
155
+ var location = {
156
+ latitude: position.coords.latitude,
157
+ longitude: position.coords.longitude,
158
+ isGeolocated: true,
159
+ location: "",
160
+ };
175
161
 
162
+ QLD.utils.setUserLocation(location);
163
+ QLD.utils.removeLocalStorage("deny-location");
164
+ return `${position.coords.latitude},${position.coords.longitude}`;
165
+ },
166
+ function (error) {
167
+ console.log(error);
168
+ QLD.utils.setLoadingState(false);
169
+ if (errorCallback) {
170
+ errorCallback();
171
+ }
172
+ return false;
173
+ },
174
+ { timeout: 10000 },
175
+ );
176
176
  } else {
177
- console.log('Unable to locate');
177
+ console.log("Unable to locate");
178
178
  if (errorCallback) {
179
- errorCallback();
180
- }
179
+ errorCallback();
180
+ }
181
181
  return false;
182
182
  }
183
183
  },
184
184
 
185
185
  /**
186
186
  * Set the user location, including the HHS
187
- *
187
+ *
188
188
  * @memberof module:_global
189
- *
190
- * @param {object} location
189
+ *
190
+ * @param {object} location
191
191
  */
192
- 'setUserLocation': function(location, refresh = true) {
192
+ setUserLocation: function (location, refresh = true) {
193
193
  // If there is a site-wide HHS configured
194
- var hhsDiv = document.getElementById('qld__hhs');
194
+ var hhsDiv = document.getElementById("qld__hhs");
195
195
 
196
- if (hhsDiv !== null && typeof(serviceFinderData) !== 'undefined') {
197
- var hhsId = hhsDiv.getAttribute('data-hhs');
198
- serviceFinderData.collection('hhs').doc(hhsId).get().then((response) => {
199
- location.hhs_id = hhsId;
200
- location.hhs_name = response.name;
196
+ if (hhsDiv !== null && typeof serviceFinderData !== "undefined") {
197
+ var hhsId = hhsDiv.getAttribute("data-hhs");
198
+ serviceFinderData
199
+ .collection("hhs")
200
+ .doc(hhsId)
201
+ .get()
202
+ .then((response) => {
203
+ location.hhs_id = hhsId;
204
+ location.hhs_name = response.name;
201
205
 
202
- QLD.utils.setUserLocationInStorage(location, refresh);
203
- });
204
-
206
+ QLD.utils.setUserLocationInStorage(location, refresh);
207
+ });
205
208
  } else {
206
209
  QLD.utils.setUserLocationInStorage(location, refresh);
207
210
  }
@@ -209,17 +212,17 @@
209
212
 
210
213
  /**
211
214
  * Set the 'qld_user_location' cookie based on a provided location object
212
- *
215
+ *
213
216
  * @memberof module:_global
214
- *
217
+ *
215
218
  */
216
- 'setUserLocationInStorage': function(newLocation, refresh) {
217
- QLD.utils.setLocalStorage('qld_user_location', JSON.stringify(newLocation));
219
+ setUserLocationInStorage: function (newLocation, refresh) {
220
+ QLD.utils.setLocalStorage("qld_user_location", JSON.stringify(newLocation));
218
221
 
219
- if(refresh) {
222
+ if (refresh) {
220
223
  QLD.utils.setLoadingState(true);
221
-
222
- setTimeout(function() {
224
+
225
+ setTimeout(function () {
223
226
  window.location.reload(false);
224
227
  }, 300);
225
228
  }
@@ -227,22 +230,21 @@
227
230
  /**
228
231
  * Check the 'qld_user_location' cookie to determine
229
232
  * whether the user is geolocated
230
- *
233
+ *
231
234
  * @memberof module:_global
232
- *
235
+ *
233
236
  * @return {boolean}
234
- *
237
+ *
235
238
  */
236
- 'isGeolocated': function() {
237
- var userLocationStorage = QLD.utils.getLocalStorage('qld_user_location');
239
+ isGeolocated: function () {
240
+ var userLocationStorage = QLD.utils.getLocalStorage("qld_user_location");
238
241
  var userLocationData = {};
239
242
 
240
- if(userLocationStorage !== null) {
243
+ if (userLocationStorage !== null) {
241
244
  userLocationData = JSON.parse(userLocationStorage);
242
245
  }
243
246
 
244
- if(Object.keys(userLocationData).length > 0) {
245
-
247
+ if (Object.keys(userLocationData).length > 0) {
246
248
  return userLocationData.isGeolocated;
247
249
  }
248
250
 
@@ -253,50 +255,85 @@
253
255
  * this will show a loader animation overlay over
254
256
  * the entire page. Use 'false' to remove this
255
257
  * same animation
256
- *
258
+ *
257
259
  * @memberof module:_global
258
- *
259
- * @param {Boolean} isLoading
260
+ *
261
+ * @param {Boolean} isLoading
260
262
  */
261
- 'setLoadingState': function(isLoading) {
262
- var loader = document.querySelector('.loader');
263
-
263
+ setLoadingState: function (isLoading) {
264
+ var loader = document.querySelector(".loader");
265
+
264
266
  if (loader === null) {
265
- loader = document.createElement('div');
266
- loader.classList.add('loader');
267
- var parentNode = document.querySelector('.main');
267
+ loader = document.createElement("div");
268
+ loader.classList.add("loader");
269
+ var parentNode = document.querySelector(".main");
268
270
  parentNode.insertBefore(loader, parentNode.firstChild);
269
271
  }
270
272
 
271
273
  if (isLoading) {
272
- loader.parentNode.classList.add('loading');
274
+ loader.parentNode.classList.add("loading");
273
275
  } else {
274
- document.querySelector('.loading').classList.remove('loading');
276
+ document.querySelector(".loading").classList.remove("loading");
275
277
  }
276
278
  },
277
279
  /**
278
280
  * Get Paramater from URL by name
279
- *
281
+ *
280
282
  * @memberof module:_global
281
- *
283
+ *
282
284
  * @param {*} name
283
285
  */
284
- 'getParamaterByName': function(name){
285
- name = name.replace(/[\[]/,"\\\[").replace(/[\]]/,"\\\]");
286
- var regexS = "[\\?&]"+name+"=([^&#]*)";
287
- var regex = new RegExp( regexS );
288
- var results = regex.exec( window.location.href );
289
- if( results == null )
290
- return "";
291
- else
292
- return decodeURIComponent(results[1].replace(/\+/g, " "));
293
- }
286
+ getParamaterByName: function (name) {
287
+ name = name.replace(/[\[]/, "\\[").replace(/[\]]/, "\\]");
288
+ var regexS = "[\\?&]" + name + "=([^&#]*)";
289
+ var regex = new RegExp(regexS);
290
+ var results = regex.exec(window.location.href);
291
+ if (results == null) return "";
292
+ else return decodeURIComponent(results[1].replace(/\+/g, " "));
293
+ },
294
+ /**
295
+ * Update the href path for SVG icons, depending on the spritesheeet source (core vs health)
296
+ *
297
+ * @memberof module:_global
298
+ *
299
+ * String selector to that targets the "use" element within the SVG icon
300
+ * @param {string} selector
301
+ */
302
+ updateSvgIconPath: function (selector) {
303
+ const ctaNavIcons = document.querySelectorAll(selector);
304
+ if (ctaNavIcons.length > 0) {
305
+ // Check each icon found
306
+ ctaNavIcons.forEach((icon) => {
307
+ const href = icon.getAttribute("href");
308
+
309
+ if (href) {
310
+ const splitArray = href.split("#");
311
+ let iconName = splitArray.pop();
312
+ let isHealthIcon = iconName.startsWith("extended_");
313
+
314
+ // Remove the "extended_" prefix from the iconName if it's a health icon
315
+ if (isHealthIcon) {
316
+ iconName = iconName.replace(/extended_/gi, "");
317
+ }
318
+
319
+ // Recreate the href path for the SVG
320
+ splitArray.push(iconName);
321
+ let updatedHref = splitArray.join("#");
322
+
323
+ // Update the path to the health spreadsheet if required
324
+ if (isHealthIcon) {
325
+ updatedHref = updatedHref.replace("QLD-icons", "QLD-Health-icons");
326
+ }
327
+
328
+ icon.setAttribute("href", updatedHref);
329
+ }
330
+ });
331
+ }
332
+ },
294
333
  };
295
334
 
296
335
  // Make QLD variable available to the console for debugging
297
336
  window.QLD = QLD;
298
337
 
299
338
  QLD.utils.browserJS();
300
-
301
-
302
- })(window.QLD);
339
+ })(window.QLD);
@@ -65,7 +65,10 @@
65
65
  };
66
66
 
67
67
  /**
68
- * When a tab is clicked, activateTab is fired to activate it
68
+ * When a tab is clicked, activateTab is fired to activate it.
69
+ * Always retrieve the closest tab button to ensure the event is
70
+ * triggered on the correct element as we reference specific data
71
+ * attributes on the button.
69
72
  *
70
73
  * @memberof module:tabs
71
74
  * @instance
@@ -74,7 +77,7 @@
74
77
  * @param {Document.event} event
75
78
  */
76
79
  function clickEventListener(event) {
77
- var tab = event.target;
80
+ var tab = event.target.closest('[role="tab"]');
78
81
  activateTab(tab, false);
79
82
  };
80
83
 
@@ -217,6 +220,7 @@
217
220
  */
218
221
  function activateTab(tab, setFocus) {
219
222
  setFocus = setFocus || true;
223
+
220
224
  // Deactivate all other tabs
221
225
  deactivatetabs(tab);
222
226
 
@@ -221,7 +221,7 @@
221
221
  {{/if}}
222
222
  </h2>
223
223
  </div>
224
- <div class="qld__card__arrow"></div>
224
+ <svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" class="qld__card--arrow-icon qld__icon qld__icon--md"><use href="{{@root.site.metadata.coreSiteIcons.value}}#arrow-right"></use></svg>
225
225
  </div>
226
226
  </div>
227
227
  </div>
@@ -24,7 +24,8 @@
24
24
  }
25
25
 
26
26
  if (resized) {
27
- bannerBreadCrumb.querySelector("ol.qld__link-list").innerHTML = originalBreadCrumbUl.innerHTML;
27
+ const originalList = originalBreadCrumbUl.cloneNode(true);
28
+ bannerBreadCrumb.querySelector("ol.qld__link-list").replaceChildren(...originalList.children);
28
29
  }
29
30
 
30
31
  const breadCrumbsUl = bannerBreadCrumb.querySelector("ol.qld__link-list");
@@ -65,7 +66,19 @@
65
66
  button.setAttribute("aria-expanded", "false");
66
67
 
67
68
  if (svgPath) {
68
- button.innerHTML = `<svg class="qld__icon qld__icon--lg" aria-hidden="true" xmlns="http://www.w3.org/2000/svg"><use href="${svgPath}#more-horizontal"></use></svg>`;
69
+ // Create <svg>
70
+ const svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
71
+ svg.setAttribute("class", "qld__icon qld__icon--lg");
72
+ svg.setAttribute("aria-hidden", "true");
73
+ svg.setAttribute("xmlns", "http://www.w3.org/2000/svg");
74
+
75
+ // Create <use>
76
+ const use = document.createElementNS("http://www.w3.org/2000/svg", "use");
77
+ use.setAttributeNS(null, "href", `${svgPath}#more-horizontal`);
78
+
79
+ // Append <use> to <svg>
80
+ svg.appendChild(use);
81
+ button.appendChild(svg);
69
82
  }
70
83
 
71
84
  overFlowWrapper.appendChild(button);
@@ -106,8 +119,8 @@
106
119
  breadCrumbsUlLis[breadCrumbsUlLis.length - 1].style.overflow = "hidden";
107
120
  }
108
121
 
109
- function appendOverflow(breadCrumbsUlLis, overflowMenu, breadcrumbUL) {
110
- breadCrumbsUlLis[1].innerHTML = "";
122
+ function appendOverflow(breadCrumbsUlLis, overflowMenu) {
123
+ breadCrumbsUlLis[1].replaceChildren();
111
124
  breadCrumbsUlLis[1].className = "qld__overflow_menu--breadcrumbs";
112
125
  breadCrumbsUlLis[1].appendChild(overflowMenu);
113
126
  breadCrumbsUlLis[1].style.display = "flex";
@@ -62,7 +62,7 @@
62
62
  {{/if}}
63
63
  </div>
64
64
  {{#ifCond metadata.show_arrow.value '==' 'true'}}
65
- <div class="qld__card__arrow"></div>
65
+ <svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" class="qld__card--arrow-icon qld__icon qld__icon--md"><use href="{{@root.site.metadata.coreSiteIcons.value}}#arrow-right"></use></svg>
66
66
  {{/ifCond}}
67
67
  </div>
68
68
  {{#ifCond metadata.show_card_footer.value '==' 'true'}}
@@ -126,7 +126,7 @@
126
126
  {{/if}}
127
127
  </div>
128
128
  {{#ifCond ../component.data.metadata.show_arrow.value '==' 'true'}}
129
- <div class="qld__card__arrow"></div>
129
+ <svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" class="qld__card--arrow-icon qld__icon qld__icon--md"><use href="{{@root.site.metadata.coreSiteIcons.value}}#arrow-right"></use></svg>
130
130
  {{/ifCond}}
131
131
  </div>
132
132
  {{#ifCond metadata.cardDisplayFooter.value '==' 'true'}}