@qhealth-design-system/core 1.22.2 → 1.23.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 (78) hide show
  1. package/.storybook/assets/image-position-demo-portrait.svg +54 -0
  2. package/.storybook/assets/image-position-demo.svg +55 -0
  3. package/.storybook/globals.js +9 -0
  4. package/.storybook/preview.js +8 -1
  5. package/CHANGELOG.md +2 -0
  6. package/README.md +0 -6
  7. package/package.json +13 -33
  8. package/src/assets/img/svg-icons.svg +154 -154
  9. package/src/component-loader.js +11 -2
  10. package/src/components/_global/css/admin/component.scss +1 -0
  11. package/src/components/_global/css/btn/component.scss +9 -0
  12. package/src/components/_global/css/img/image-position-utility-classes.scss +30 -0
  13. package/src/components/_global/css/img/image-ratio-utility-classes.scss +41 -0
  14. package/src/components/_global/css/img/images.scss +74 -5
  15. package/src/components/_global/css/modal/component.scss +1 -0
  16. package/src/components/_global/js/animate/global.js +272 -294
  17. package/src/components/_global/js/collapsible.js +3 -3
  18. package/src/components/_global/js/global.js +304 -316
  19. package/src/components/_global/js/legacyGlobal.js +63 -0
  20. package/src/components/_global/js/modal/global.js +218 -223
  21. package/src/components/_global/js/popover/controller.js +4 -4
  22. package/src/components/_global/js/tabs/global.js +264 -276
  23. package/src/components/a-z_listing/js/global.js +106 -92
  24. package/src/components/accordion/css/component.scss +24 -41
  25. package/src/components/accordion/html/component.hbs +23 -5
  26. package/src/components/accordion/js/global.js +5 -10
  27. package/src/components/basic_search/js/global.js +0 -7
  28. package/src/components/code/js/global.js +6 -12
  29. package/src/components/file_upload/js/global.js +1 -5
  30. package/src/components/internal_navigation/css/component.scss +2 -2
  31. package/src/components/internal_navigation/html/component.hbs +16 -1
  32. package/src/components/main_navigation/js/global.js +341 -335
  33. package/src/components/overflow_menu/css/component.scss +1 -0
  34. package/src/components/search_box/css/component.scss +0 -1
  35. package/src/components/tab/js/global.js +5 -10
  36. package/src/components/toggle_tip/js/global.js +0 -6
  37. package/src/components/tool_tip/js/global.js +0 -6
  38. package/src/components/video_player/css/component.scss +27 -9
  39. package/src/components/video_player/html/component.hbs +32 -6
  40. package/src/components/video_player/js/global.js +8 -1
  41. package/src/index.js +4 -0
  42. package/src/stories/Accordion/accordion.stories.js +1 -0
  43. package/src/stories/Banner/bannerContained.stories.js +123 -0
  44. package/src/stories/Flexbox/Flexbox.stories.js +316 -0
  45. package/src/stories/Image/Image.stories.js +182 -0
  46. package/src/stories/Templates/ContentPage.stories.js +101 -0
  47. package/src/stories/Templates/LandingPage.stories.js +193 -0
  48. package/src/stories/Templates/templateHelpers.js +102 -0
  49. package/src/stories/VideoPlayer/VideoPlayer.stories.js +16 -0
  50. package/src/styles/imports/utilities.scss +15 -25
  51. package/src/styles/imports/variables.scss +26 -0
  52. package/src/components/_global/html/head.html +0 -22
  53. package/src/components/_global/html/scripts.html +0 -28
  54. package/src/components/_global/js/_polyfills/global.js +0 -19
  55. package/src/components/_template/html/component-page.html +0 -75
  56. package/src/components/_template/js/global.js +0 -3
  57. package/src/components/accordion/html/accordion-group.html +0 -163
  58. package/src/components/accordion/html/default.html +0 -99
  59. package/src/components/banner_basic/js/global.js +0 -3
  60. package/src/components/loading_spinner/js/global.js +0 -3
  61. package/src/components/pagination/html/default.html +0 -39
  62. package/src/components/search_box/html/component.html +0 -26
  63. package/src/data/current.json +0 -400
  64. package/src/data/current_admin.json +0 -305
  65. package/src/data/model_component.js +0 -14
  66. package/src/data/site.json +0 -977
  67. package/src/externals/tinymce_classes.css +0 -62
  68. package/src/html/component-global-elements.html +0 -2857
  69. package/src/html/component-horizontal_rule.html +0 -647
  70. package/src/html/component-internal_navigation.html +0 -583
  71. package/src/html/component-left_hand_navigation.html +0 -57
  72. package/src/html/component-main_navigation.html +0 -583
  73. package/src/html/component-multi_column.html +0 -582
  74. package/src/html/components.html +0 -354
  75. package/src/html/home.html +0 -1898
  76. package/src/html/index.html +0 -129
  77. package/src/html/inner-with-nav.html +0 -605
  78. package/src/html/inner.html +0 -618
@@ -1,99 +1,113 @@
1
- (function () {
2
- "use strict";
3
-
4
- window.addEventListener("DOMContentLoaded", function () {
5
- function checkIfAzSelected() {
6
- var hash = window.location.hash;
7
-
8
- if (hash) {
9
- setTimeout(function () {
10
- var servicesAZOptions = document.querySelectorAll(
11
- ".qld__a-z_listing__options__item__link",
12
- );
13
- var servicesAZHeaders = document.querySelectorAll(
14
- ".qld__a-z_listing__list__item__header",
15
- );
16
-
17
- servicesAZOptions.forEach(function (option) {
18
- option.classList.remove("active");
19
- });
20
-
21
- servicesAZHeaders.forEach(function (header) {
22
- header.classList.remove("active");
23
- });
24
-
25
- var activeOption = document.querySelector(
26
- `a[href^="${hash}"].qld__a-z_listing__options__item__link`,
27
- );
28
- if (activeOption) {
29
- activeOption.classList.add("active");
30
- }
31
-
32
- var activeHeader = document.querySelector(
33
- `.qld__a-z_listing__list__item__header ${hash}`,
34
- );
35
- if (activeHeader) {
36
- activeHeader.parentElement.classList.add("active");
37
- }
38
-
39
- var targetElement = document.querySelector(hash);
40
- if (targetElement) {
41
- window.scrollTo({
42
- top:
43
- targetElement.getBoundingClientRect().top + window.scrollY - 20,
44
- behavior: "smooth",
45
- });
46
- }
47
- }, 100);
1
+ /**
2
+ * @module aZListing
3
+ */
4
+
5
+ /**
6
+ * On load, if the URL has a hash, highlight the matching letter option/header
7
+ * and smooth-scroll to the target.
8
+ */
9
+ function checkIfAzSelected() {
10
+ var hash = window.location.hash;
11
+
12
+ if (hash) {
13
+ setTimeout(function () {
14
+ var servicesAZOptions = document.querySelectorAll(
15
+ ".qld__a-z_listing__options__item__link",
16
+ );
17
+ var servicesAZHeaders = document.querySelectorAll(
18
+ ".qld__a-z_listing__list__item__header",
19
+ );
20
+
21
+ servicesAZOptions.forEach(function (option) {
22
+ option.classList.remove("active");
23
+ });
24
+
25
+ servicesAZHeaders.forEach(function (header) {
26
+ header.classList.remove("active");
27
+ });
28
+
29
+ var activeOption = document.querySelector(
30
+ `a[href^="${hash}"].qld__a-z_listing__options__item__link`,
31
+ );
32
+ if (activeOption) {
33
+ activeOption.classList.add("active");
48
34
  }
49
- }
50
-
51
- document.addEventListener("click", function (event) {
52
- var target = event.target;
53
-
54
- if (
55
- target.matches('a[href^="#"].qld__a-z_listing__options__item__link')
56
- ) {
57
- event.preventDefault();
58
-
59
- var servicesAZOptions = document.querySelectorAll(
60
- ".qld__a-z_listing__options__item__link",
61
- );
62
- var servicesAZHeaders = document.querySelectorAll(
63
- ".qld__a-z_listing__list__item__header",
64
- );
65
35
 
66
- servicesAZOptions.forEach(function (option) {
67
- option.classList.remove("active");
68
- });
36
+ var activeHeader = document.querySelector(
37
+ `.qld__a-z_listing__list__item__header ${hash}`,
38
+ );
39
+ if (activeHeader) {
40
+ activeHeader.parentElement.classList.add("active");
41
+ }
69
42
 
70
- servicesAZHeaders.forEach(function (header) {
71
- header.classList.remove("active");
43
+ var targetElement = document.querySelector(hash);
44
+ if (targetElement) {
45
+ window.scrollTo({
46
+ top: targetElement.getBoundingClientRect().top + window.scrollY - 20,
47
+ behavior: "smooth",
72
48
  });
73
-
74
- target.classList.add("active");
75
- var targetHeader = document.querySelector(
76
- `.qld__a-z_listing__list__item__header ${target.getAttribute("href")}`,
77
- );
78
- if (targetHeader) {
79
- targetHeader.parentElement.classList.add("active");
80
- }
81
-
82
- var targetElement = document.querySelector(target.getAttribute("href"));
83
- if (targetElement) {
84
- window.scrollTo({
85
- top:
86
- targetElement.getBoundingClientRect().top + window.scrollY - 20,
87
- behavior: "smooth",
88
- });
89
- }
90
-
91
- setTimeout(() => {
92
- window.location.hash = target.getAttribute("href");
93
- }, 500);
94
49
  }
50
+ }, 100);
51
+ }
52
+ }
53
+
54
+ /**
55
+ * Delegated click handler: when an A-Z letter link is clicked, highlight it,
56
+ * smooth-scroll to its section, and update the URL hash.
57
+ *
58
+ * @param {MouseEvent} event
59
+ */
60
+ function handleAZClick(event) {
61
+ var target = event.target;
62
+
63
+ if (target.matches('a[href^="#"].qld__a-z_listing__options__item__link')) {
64
+ event.preventDefault();
65
+
66
+ var servicesAZOptions = document.querySelectorAll(
67
+ ".qld__a-z_listing__options__item__link",
68
+ );
69
+ var servicesAZHeaders = document.querySelectorAll(
70
+ ".qld__a-z_listing__list__item__header",
71
+ );
72
+
73
+ servicesAZOptions.forEach(function (option) {
74
+ option.classList.remove("active");
95
75
  });
96
76
 
97
- checkIfAzSelected();
98
- });
99
- })();
77
+ servicesAZHeaders.forEach(function (header) {
78
+ header.classList.remove("active");
79
+ });
80
+
81
+ target.classList.add("active");
82
+ var targetHeader = document.querySelector(
83
+ `.qld__a-z_listing__list__item__header ${target.getAttribute("href")}`,
84
+ );
85
+ if (targetHeader) {
86
+ targetHeader.parentElement.classList.add("active");
87
+ }
88
+
89
+ var targetElement = document.querySelector(target.getAttribute("href"));
90
+ if (targetElement) {
91
+ window.scrollTo({
92
+ top: targetElement.getBoundingClientRect().top + window.scrollY - 20,
93
+ behavior: "smooth",
94
+ });
95
+ }
96
+
97
+ setTimeout(() => {
98
+ window.location.hash = target.getAttribute("href");
99
+ }, 500);
100
+ }
101
+ }
102
+
103
+ /**
104
+ * Initialise the A-Z listing behaviour: wire the delegated click handler and
105
+ * apply any hash selection already present in the URL.
106
+ *
107
+ * The click listener is attached to `document` (event delegation), so re-invoking
108
+ * this is a no-op — `addEventListener` dedupes the identical handler reference.
109
+ */
110
+ export default function initAZListing() {
111
+ document.addEventListener("click", handleAZClick);
112
+ checkIfAzSelected();
113
+ }
@@ -46,26 +46,14 @@
46
46
  transition: transform 0.25s ease-in;
47
47
  }
48
48
 
49
- &:after {
50
- content: " ";
51
- position: absolute;
49
+ // the chevron indicator only — other icons (e.g. the video player
50
+ // transcript icon) share .qld__icon but must not centre/rotate
51
+ .qld__accordion__icon {
52
52
  top: 50%;
53
- @include QLD-space(margin-top, -10px); // Pull it up 10px
54
- @include QLD-space(right, 1unit);
55
- @include QLD-space(width, 1.5unit);
56
- @include QLD-space(height, 1.5unit);
57
- // background-image: QLD-svg-with-fill($QLD-icon-chevron-up, var(--QLD-color-light__action--secondary));
58
- // background-repeat: no-repeat;
59
- // background-position: center;
60
- z-index: 1;
61
- transition: transform 0.25s ease-in;
62
- mask-image: QLD-svguri($QLD-icon-chevron-up);
63
- mask-repeat: no-repeat;
64
- mask-position: center;
65
- background-color: var(--QLD-color-light__action--secondary);
53
+ @include QLD-space(margin-top, -0.75unit); // Pull it up half its height
66
54
  }
67
55
 
68
- &.qld__accordion--closed::after {
56
+ &.qld__accordion--closed .qld__accordion__icon {
69
57
  transform: rotate(-180deg);
70
58
  }
71
59
  }
@@ -107,6 +95,7 @@
107
95
  @include QLD-space(font-size, 0.75unit);
108
96
 
109
97
  &-btn {
98
+ display: inline-flex;
110
99
  @include QLD-underline("light");
111
100
  background-color: transparent;
112
101
  color: var(--QLD-color-light__link);
@@ -114,27 +103,15 @@
114
103
  cursor: pointer;
115
104
  position: relative;
116
105
  @include QLD-space(margin-right, 0.5unit);
117
- &::after {
118
- content: " ";
119
- position: absolute;
120
- top: 50%;
121
- @include QLD-space(
122
- margin-top,
123
- -0.5unit
124
- ); // Pull it up half of it's height
125
- @include QLD-space(right, -0.5unit);
126
- @include QLD-space(width, 0.5unit);
127
- @include QLD-space(height, 1unit);
128
- z-index: 101;
106
+ @include QLD-space("gap", 0.5unit);
107
+
108
+ .qld__icon {
109
+ color: var(--QLD-color-light__action--secondary);
129
110
  transition: transform 0.25s ease-in;
130
- mask-image: QLD-svguri($QLD-icon-chevron-up);
131
- mask-repeat: no-repeat;
132
- mask-position: center;
133
- background-color: var(--QLD-color-light__action--secondary);
134
111
  }
135
112
 
136
113
  &--closed {
137
- &::after {
114
+ .qld__icon {
138
115
  transform: rotate(-180deg);
139
116
  }
140
117
  }
@@ -171,6 +148,12 @@
171
148
  padding: 0;
172
149
  @include QLD-space(max-width, 47unit);
173
150
 
151
+ // Accordions stack flush inside a group; the owl spacing on `* + &` only
152
+ // ever hits the first accordion (preceded by the "Open all" toggle row)
153
+ * + .qld__accordion {
154
+ margin-top: 0;
155
+ }
156
+
174
157
  &:last-child {
175
158
  @include QLD-space(margin-bottom, 0unit);
176
159
  }
@@ -187,8 +170,8 @@
187
170
  color: var(--QLD-color-dark__link);
188
171
  @include QLD-underline("dark");
189
172
 
190
- &::after {
191
- background-color: var(--QLD-color-dark__action--secondary);
173
+ .qld__icon {
174
+ color: var(--QLD-color-dark__action--secondary);
192
175
  }
193
176
  }
194
177
  }
@@ -233,8 +216,8 @@
233
216
  background-color: var(--QLD-color-dark__background--shade);
234
217
  color: var(--QLD-color-dark__link);
235
218
 
236
- &::after {
237
- background-color: var(--QLD-color-dark__action--secondary);
219
+ .qld__icon {
220
+ color: var(--QLD-color-dark__action--secondary);
238
221
  }
239
222
  }
240
223
 
@@ -260,8 +243,8 @@
260
243
  background-color: var(--QLD-color-dark__background--alt-shade);
261
244
  color: var(--QLD-color-dark__link);
262
245
 
263
- &::after {
264
- background-color: var(--QLD-color-dark__action--secondary);
246
+ .qld__icon {
247
+ color: var(--QLD-color-dark__action--secondary);
265
248
  }
266
249
  }
267
250
 
@@ -298,7 +281,7 @@ li + li .qld__accordion {
298
281
  color: #000 !important;
299
282
  border: 1px !important;
300
283
 
301
- &:after {
284
+ .qld__accordion__icon {
302
285
  display: none;
303
286
  }
304
287
  }
@@ -22,7 +22,16 @@
22
22
  type="button"
23
23
  aria-expanded="false"
24
24
  >
25
- Open all
25
+ <span>Open all</span>
26
+ <svg
27
+ class="qld__icon qld__icon--xs"
28
+ aria-hidden="true"
29
+ xmlns="http://www.w3.org/2000/svg"
30
+ >
31
+ <use
32
+ href="{{ @root.site.metadata.coreSiteIcons.value }}#chevron-up"
33
+ ></use>
34
+ </svg>
26
35
  </button>
27
36
  </div>
28
37
  {{/ifCond}}
@@ -30,10 +39,19 @@
30
39
  {{#ifCond this.content '!=' ''}}
31
40
  <div class="qld__accordion">
32
41
  <{{../metadata.title_level.value}}>
33
- <button class="qld__accordion__title js-qld__accordion qld__accordion--closed" aria-controls="accordion-group-{{../assetid}}-{{this.fieldid}}" aria-expanded="false" type="button">
34
- {{this.title}}
35
- </button>
36
- </{{../metadata.title_level.value}}>
42
+ <button class="qld__accordion__title js-qld__accordion qld__accordion--closed" aria-controls="accordion-group-{{../assetid}}-{{this.fieldid}}" aria-expanded="false" type="button">
43
+ {{this.title}}
44
+ <svg
45
+ class="qld__icon qld__icon--md qld__accordion__icon"
46
+ aria-hidden="true"
47
+ xmlns="http://www.w3.org/2000/svg"
48
+ >
49
+ <use
50
+ href="{{ @root.site.metadata.coreSiteIcons.value }}#chevron-up"
51
+ ></use>
52
+ </svg>
53
+ </button>
54
+ </{{../metadata.title_level.value}}>
37
55
  <div
38
56
  id="accordion-group-{{ ../assetid }}-{{ this.fieldid }}"
39
57
  class="qld__accordion__body qld__accordion--closed"
@@ -82,7 +82,11 @@ function setToggleAllState(toggleAllBtn, isOpen) {
82
82
  toggleAllBtn.classList.toggle("qld__accordion__toggle-btn--open", isOpen);
83
83
  toggleAllBtn.classList.toggle("qld__accordion__toggle-btn--closed", !isOpen);
84
84
  setExpanded(toggleAllBtn, isOpen);
85
- toggleAllBtn.textContent = isOpen ? "Close all" : "Open all";
85
+
86
+ // Only update the label so the inline chevron svg is preserved; fall back
87
+ // to the whole button for legacy markup without the <span> wrapper
88
+ const labelEl = toggleAllBtn.querySelector("span") ?? toggleAllBtn;
89
+ labelEl.textContent = isOpen ? "Close all" : "Open all";
86
90
  }
87
91
 
88
92
  /**
@@ -182,12 +186,3 @@ export function Open(elements, speed, root = document, callbacks) {
182
186
  export function Close(elements, speed, root = document, callbacks) {
183
187
  collapsible.close(elements, speed, root, callbacks);
184
188
  }
185
-
186
- // Make accordion public for backwards compatibility (window.QLD.accordion.*)
187
- const accordion = { Toggle, ToggleAll, Open, Close, initAccordion };
188
- window.QLD = window.QLD || {};
189
- window.QLD.accordion = accordion;
190
-
191
- // Note: accordion groups are initialised via initAccordion() from component-loader.js.
192
-
193
- export { accordion };
@@ -81,10 +81,3 @@ function checkHoneypot(searchForm, signal) {
81
81
  { signal },
82
82
  );
83
83
  }
84
-
85
- // Make basic search public for backwards compatibility (window.QLD.basicSearch.init)
86
- const basicSearch = { init: initBasicSearch };
87
- window.QLD = window.QLD || {};
88
- window.QLD.basicSearch = basicSearch;
89
-
90
- export { basicSearch };
@@ -6,16 +6,17 @@ import {
6
6
  validateInternalSvgPath,
7
7
  buildIconPath,
8
8
  } from "../../../helpers/global-helpers.js";
9
+ import * as animate from "../../_global/js/animate/global.js";
9
10
 
10
11
  /**
11
12
  * Initialise the code component: syntax-highlight snippets, wire the copy
12
13
  * buttons and the inline-code copy affordance, the "Show more" toggle, and the
13
14
  * preview theme-palette switcher.
14
15
  *
15
- * `Prism` (syntax highlighting) and `QLD.animate` (the toggle animation) are
16
- * provided globally at runtime by `index.js` / the global bundle; both are
17
- * accessed defensively so the component degrades gracefully where they are
18
- * absent (e.g. Storybook).
16
+ * `Prism` (syntax highlighting) is provided globally at runtime by `index.js` /
17
+ * the global bundle and accessed defensively so the component degrades
18
+ * gracefully where it is absent (e.g. Storybook). The toggle animation is
19
+ * imported directly from the `animate` module.
19
20
  *
20
21
  * @param {Document|Element} root - The root element to scope DOM queries to.
21
22
  * @returns {function} Cleanup function that removes the listeners added here.
@@ -128,7 +129,7 @@ export default function initCode(root = document) {
128
129
  svg.appendChild(use);
129
130
  this.appendChild(svg);
130
131
 
131
- window.QLD?.animate?.Toggle?.({
132
+ animate.Toggle({
132
133
  element: target,
133
134
  property: "height",
134
135
  speed: 250,
@@ -240,10 +241,3 @@ function copyTextToClipboard(text) {
240
241
  },
241
242
  );
242
243
  }
243
-
244
- // Make code public for backwards compatibility (window.QLD.code.init)
245
- const code = { init: initCode };
246
- window.QLD = window.QLD || {};
247
- window.QLD.code = code;
248
-
249
- export { code };
@@ -969,9 +969,5 @@ const setFilesDataAttribute = function (
969
969
  input_field_settings.input_element.dataset["files"] = JSON.stringify(files);
970
970
  };
971
971
 
972
- // Store fileUploads object globally for backwards compatibility (window.QLD.fileUploads.*)
973
- window.QLD = window.QLD || {};
974
- window.QLD.fileUploads = fileUploads;
975
-
976
- // Note: file inputs are initialised via initFileUpload() from component-loader.js.
977
972
  export const initFileUpload = fileUploads.init;
973
+ export { fileUploads };
@@ -296,8 +296,8 @@ $QLD-side-nav-breakpoint: lg !default;
296
296
  text-decoration-color: var(--QLD-color-dark__heading);
297
297
  background-color: inherit;
298
298
 
299
- &:after {
300
- background-color: var(--QLD-color-dark__action--secondary);
299
+ .qld__icon {
300
+ color: var(--QLD-color-dark__action--secondary);
301
301
  }
302
302
  }
303
303
 
@@ -2,7 +2,22 @@
2
2
  class="qld__side-nav qld__accordion"
3
3
  data-path="{{ @root.site.metadata.coreSiteIcons.value }}"
4
4
  >
5
- <button class="qld__side-nav__toggle qld__accordion__title qld__accordion--closed" aria-controls="nav-default" aria-expanded="false">In {{{ current.top.asset_name }}}</button>
5
+ <button
6
+ class="qld__side-nav__toggle qld__accordion__title qld__accordion--closed"
7
+ aria-controls="nav-default"
8
+ aria-expanded="false"
9
+ >
10
+ In
11
+ {{{ current.top.asset_name }}}
12
+ <svg
13
+ class="qld__icon qld__icon--md qld__accordion__icon"
14
+ aria-hidden="true"
15
+ xmlns="http://www.w3.org/2000/svg"
16
+ >
17
+ <use href="{{ @root.site.metadata.coreSiteIcons.value }}#chevron-up"
18
+ ></use>
19
+ </svg>
20
+ </button>
6
21
  <nav
7
22
  id="nav-default"
8
23
  class="qld__side-nav__content qld__accordion--closed qld__accordion__body"