@qhealth-design-system/core 1.19.2 → 1.20.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 (69) hide show
  1. package/.storybook/assets/breadcrumbs-js.js +216 -0
  2. package/.storybook/assets/index.js +9 -1
  3. package/.storybook/assets/index.scss +9 -0
  4. package/.storybook/assets/{storybook.css → storybook.scss} +23 -0
  5. package/.storybook/globals.js +56 -0
  6. package/.storybook/helper-functions.js +21 -0
  7. package/.storybook/main.js +5 -0
  8. package/.storybook/prepare-storybook.js +1 -1
  9. package/.storybook/preview-head.html +1 -2
  10. package/.storybook/preview.js +32 -2
  11. package/CHANGELOG.md +2 -0
  12. package/package.json +6 -1
  13. package/src/component-loader.js +2 -0
  14. package/src/components/_global/css/cta_links/component.scss +55 -40
  15. package/src/components/_global/css/tags/component.scss +2 -4
  16. package/src/components/_global/js/animate/global.js +83 -64
  17. package/src/components/_global/js/cta_links/global.js +15 -28
  18. package/src/components/banner/html/component.hbs +8 -2
  19. package/src/components/banner_advanced/html/component.hbs +6 -1
  20. package/src/components/banner_basic/html/component.hbs +6 -1
  21. package/src/components/banner_intermediate/html/component.hbs +6 -1
  22. package/src/components/basic_search/html/component.hbs +11 -4
  23. package/src/components/breadcrumbs/css/component.scss +18 -99
  24. package/src/components/breadcrumbs/html/component.hbs +17 -9
  25. package/src/components/breadcrumbs/js/global.js +18 -0
  26. package/src/components/callout/html/component.hbs +1 -1
  27. package/src/components/internal_navigation/html/component.hbs +1 -1
  28. package/src/components/left_hand_navigation/html/component.hbs +2 -2
  29. package/src/components/main_navigation/css/component.scss +4 -2
  30. package/src/components/main_navigation/js/global.js +126 -48
  31. package/src/components/mega_main_navigation/html/component.hbs +1 -1
  32. package/src/components/overflow_menu/css/component.scss +4 -4
  33. package/src/data/current.json +24 -0
  34. package/src/helpers/Handlebars/withinObject.js +4 -11
  35. package/src/helpers/global-helpers.js +3 -0
  36. package/src/html/component-tag_list.html +89 -0
  37. package/src/stories/BackToTop/BackToTop.stories.js +1 -1
  38. package/src/stories/Breadcrumbs/Breadcrumbs.mdx +30 -0
  39. package/src/stories/Breadcrumbs/Breadcrumbs.stories.js +133 -0
  40. package/src/stories/CTALink/CTALink.mdx +1 -1
  41. package/src/stories/CTALink/CTALink.stories.js +22 -33
  42. package/src/stories/Callout/Callout.mdx +28 -0
  43. package/src/stories/Callout/Callout.stories.js +172 -0
  44. package/src/stories/Checkboxes/Checkboxes.stories.js +35 -45
  45. package/src/stories/DirectionLinks/DirectionLinks.stories.js +28 -38
  46. package/src/stories/Footer/Footer.mdx +36 -0
  47. package/src/stories/Footer/Footer.stories.js +204 -0
  48. package/src/stories/Header/Header.js +99 -0
  49. package/src/stories/Header/Header.mdx +61 -0
  50. package/src/stories/Header/Header.stories.js +392 -0
  51. package/src/stories/Iconography/Iconography.js +3 -0
  52. package/src/stories/Iconography/Iconography.mdx +23 -0
  53. package/src/stories/Iconography/Iconography.stories.js +118 -0
  54. package/src/stories/InPageAlert/InPageAlert.stories.js +1 -1
  55. package/src/stories/LinkColumns/LinkColumns.stories.js +38 -48
  56. package/src/stories/LoadingSpinner/LoadingSpinner.mdx +30 -0
  57. package/src/stories/LoadingSpinner/LoadingSpinner.stories.js +81 -0
  58. package/src/stories/Navbar/Navbar.js +122 -0
  59. package/src/stories/Navbar/Navbar.mdx +37 -0
  60. package/src/stories/Navbar/Navbar.stories.js +79 -0
  61. package/src/stories/Pagination/Pagination.stories.js +35 -42
  62. package/src/stories/PromoPanel/PromoPanel.stories.js +15 -9
  63. package/src/stories/RadioButtons/RadioButtons.stories.js +35 -45
  64. package/src/stories/SelectBox/SelectBox.stories.js +81 -91
  65. package/src/stories/Tags/Tags.stories.js +32 -42
  66. package/src/stories/VideoPlayer/VideoPlayer.stories.js +2 -6
  67. package/src/styles/core-styles.scss +113 -0
  68. package/src/styles/global.scss +3 -121
  69. package/src/styles/imports/variables.scss +1 -1
@@ -0,0 +1,216 @@
1
+ // This file is temporarily added to Storybook to allow testing of the breadcrumbs, while the main breadcrumbs js file is being refactored into a module.
2
+
3
+ import { validateInternalSvgPath, buildIconPath } from "../../src/helpers/global-helpers.js";
4
+
5
+ /**
6
+ * @module breadcrumb
7
+ */
8
+
9
+ var originalBreadCrumbUl = null;
10
+
11
+ export const getTheElements = (resized = false) => {
12
+ const bannerBreadCrumbsAll = document.querySelectorAll("nav.qld__banner__breadcrumbs--desktop");
13
+
14
+ const bodyBreadCrumbsAll = document.querySelectorAll("section.qld__body--breadcrumb nav.qld__breadcrumbs");
15
+
16
+ const bannerBreadCrumbArray = [...bannerBreadCrumbsAll, ...bodyBreadCrumbsAll];
17
+ const bannerBreadCrumb = bannerBreadCrumbArray.find((breadcrumb) => {
18
+ return breadcrumb.offsetWidth > 0;
19
+ });
20
+
21
+ if (bannerBreadCrumb) {
22
+ if (!originalBreadCrumbUl) {
23
+ originalBreadCrumbUl = bannerBreadCrumb.querySelector("ol.qld__link-list").cloneNode(true);
24
+ }
25
+
26
+ if (resized) {
27
+ const originalList = originalBreadCrumbUl.cloneNode(true);
28
+ bannerBreadCrumb.querySelector("ol.qld__link-list").replaceChildren(...originalList.children);
29
+ }
30
+
31
+ const breadCrumbsUl = bannerBreadCrumb.querySelector("ol.qld__link-list");
32
+ if (bannerBreadCrumb.parentElement && bannerBreadCrumb.parentElement.classList.contains("qld__banner__content")) {
33
+ const contentBanner = bannerBreadCrumb.closest(".qld__banner__content");
34
+ const contentBannerStyle = window.getComputedStyle(contentBanner);
35
+
36
+ const contentPaddings = parseFloat(contentBannerStyle.getPropertyValue("padding-right").replace(/[^\d.]/g, "")) + parseFloat(contentBannerStyle.getPropertyValue("padding-left").replace(/[^\d.]/g, ""));
37
+
38
+ bannerBreadCrumb.style.maxWidth = contentBanner.offsetWidth - contentPaddings + "px";
39
+
40
+ breadCrumbsUl.style.maxWidth = contentBanner.offsetWidth - contentPaddings + "px";
41
+ } else {
42
+ const containerFluid = bannerBreadCrumb.closest(".container-fluid");
43
+ const containerFluidStyle = window.getComputedStyle(containerFluid);
44
+ if (containerFluid) {
45
+ const paddings = parseFloat(containerFluidStyle.getPropertyValue("padding-right").replace(/[^\d.]/g, "")) + parseFloat(containerFluidStyle.getPropertyValue("padding-left").replace(/[^\d.]/g, ""));
46
+
47
+ bannerBreadCrumb.style.maxWidth = containerFluid.offsetWidth - paddings + "px";
48
+ breadCrumbsUl.style.maxWidth = containerFluid.offsetWidth - paddings + "px";
49
+ }
50
+ }
51
+ return {
52
+ bannerBreadCrumb,
53
+ breadCrumbsUl,
54
+ };
55
+ }
56
+ };
57
+
58
+ function createOverFlow(svgPath) {
59
+ const overFlowWrapper = document.createElement("div");
60
+ overFlowWrapper.className = "qld__overflow_menu_wrapper";
61
+
62
+ const button = document.createElement("button");
63
+ button.className = "qld__btn qld__btn--toggle qld__overflow_menu__btn qld__accordion--closed";
64
+ button.setAttribute("href", "#");
65
+ button.setAttribute("aria-controls", "overflow-menu--");
66
+ button.setAttribute("aria-expanded", "false");
67
+
68
+ if (svgPath) {
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
+ // Attempt to validate SVG path before using it
78
+ if (validateInternalSvgPath(svgPath)) {
79
+ use.setAttributeNS(null, "href", buildIconPath(svgPath, "more-horizontal").toString());
80
+ }
81
+
82
+ // Append <use> to <svg>
83
+ svg.appendChild(use);
84
+ button.appendChild(svg);
85
+ }
86
+
87
+ overFlowWrapper.appendChild(button);
88
+
89
+ const div = document.createElement("div");
90
+ div.className = "qld__overflow_menu qld__accordion--closed";
91
+ div.setAttribute("id", "overflow-menu--");
92
+
93
+ const ul = document.createElement("ul");
94
+ ul.className = "qld__overflow_menu_list";
95
+ ul.setAttribute("aria-label", "qld__overflow_menu qld__link-columns");
96
+
97
+ div.appendChild(ul);
98
+
99
+ overFlowWrapper.appendChild(div);
100
+
101
+ return overFlowWrapper;
102
+ }
103
+
104
+ function insertOverFlowButton(overFlowWrapper, element) {
105
+ const newElement = document.createElement("div");
106
+ newElement.className = "qld__overflow_menu_list-item";
107
+
108
+ const link = element.querySelector("a");
109
+ link.classList.add("qld__overflow_menu_list-item-link");
110
+ link.setAttribute("tabindex", "0");
111
+
112
+ newElement.appendChild(link);
113
+
114
+ const ul = overFlowWrapper.querySelector("ul");
115
+
116
+ ul.appendChild(newElement);
117
+
118
+ return overFlowWrapper;
119
+ }
120
+
121
+ function truncateLastLi(breadCrumbsUlLis) {
122
+ breadCrumbsUlLis[breadCrumbsUlLis.length - 1].style.overflow = "hidden";
123
+ }
124
+
125
+ function appendOverflow(breadCrumbsUlLis, overflowMenu) {
126
+ breadCrumbsUlLis[1].replaceChildren();
127
+ breadCrumbsUlLis[1].className = "qld__overflow_menu--breadcrumbs";
128
+ breadCrumbsUlLis[1].appendChild(overflowMenu);
129
+ breadCrumbsUlLis[1].style.display = "flex";
130
+ }
131
+
132
+ // Function to remove excess breadcrumb chevrons in situations where breadcrumbs are hidden using JS
133
+ function checkChevrons() {
134
+ const component = document.querySelector(".qld__breadcrumbs .qld__link-list.qld__breadcrumbs__list--desktop");
135
+ // Find the visible breadcrumb children
136
+ const children = Array.from(component.children).filter((child) => getComputedStyle(child).display !== "none");
137
+
138
+ // Remove excess breadcrumb chevrons
139
+ let wasPreviouslySVG = false;
140
+ children.forEach((child) => {
141
+ if (child.tagName === "svg") {
142
+ if (wasPreviouslySVG) child.remove();
143
+ else wasPreviouslySVG = true;
144
+ } else wasPreviouslySVG = false;
145
+ });
146
+ }
147
+
148
+ export const initBreadcrumbs = (document = document) => {
149
+ if (getTheElements()) {
150
+ const { breadCrumbsUl } = getTheElements();
151
+
152
+ const breadCrumbsUlLis = breadCrumbsUl.querySelectorAll("li");
153
+ if (breadCrumbsUlLis.length > 2 && breadCrumbsUlLis[0].offsetHeight > 0) {
154
+ const parent = breadCrumbsUl.parentElement;
155
+ const svgPath = parent.getAttribute("data-path");
156
+ const overflowMenu = createOverFlow(svgPath);
157
+
158
+ let breadcrumbLisLength = breadCrumbsUlLis.length;
159
+ let i = 1;
160
+
161
+ let totalLisOffsetWidth = 0;
162
+
163
+ for (let i = 0; i < breadCrumbsUlLis.length; i++) {
164
+ totalLisOffsetWidth += breadCrumbsUlLis[i].offsetWidth;
165
+ }
166
+
167
+ if (breadcrumbLisLength > 5) {
168
+ insertOverFlowButton(overflowMenu, breadCrumbsUlLis[1]);
169
+ breadCrumbsUlLis[1].style.display = "none";
170
+ appendOverflow(breadCrumbsUlLis, overflowMenu, breadCrumbsUl);
171
+ i = 2;
172
+
173
+ while (i < breadCrumbsUlLis.length - 2) {
174
+ insertOverFlowButton(overflowMenu, breadCrumbsUlLis[i]);
175
+ breadCrumbsUlLis[i].style.display = "none";
176
+ i++;
177
+ }
178
+ } else if (breadCrumbsUl.offsetHeight > breadCrumbsUlLis[0].offsetHeight * 1.9) {
179
+ if (breadcrumbLisLength > 3) {
180
+ insertOverFlowButton(overflowMenu, breadCrumbsUlLis[1]);
181
+ breadCrumbsUlLis[1].style.display = "none";
182
+ appendOverflow(breadCrumbsUlLis, overflowMenu, breadCrumbsUl);
183
+ }
184
+
185
+ i = 2;
186
+
187
+ while (breadCrumbsUl.offsetHeight > breadCrumbsUlLis[0].offsetHeight * 1.9 && i < breadcrumbLisLength - 2) {
188
+ insertOverFlowButton(overflowMenu, breadCrumbsUlLis[i]);
189
+ breadCrumbsUlLis[i].style.display = "none";
190
+
191
+ i++;
192
+ }
193
+ } else if (parseFloat(breadCrumbsUl.style.maxWidth.replace(/[^\d.]/g, "")) < totalLisOffsetWidth) {
194
+ if (breadcrumbLisLength > 3) {
195
+ insertOverFlowButton(overflowMenu, breadCrumbsUlLis[1]);
196
+ breadCrumbsUlLis[1].style.display = "none";
197
+ appendOverflow(breadCrumbsUlLis, overflowMenu, breadCrumbsUl);
198
+ totalLisOffsetWidth -= breadCrumbsUlLis[1].offsetWidth;
199
+ }
200
+
201
+ i = 2;
202
+
203
+ while (parseFloat(breadCrumbsUl.style.maxWidth.replace(/[^\d.]/g, "")) < totalLisOffsetWidth && i < breadcrumbLisLength - 2) {
204
+ insertOverFlowButton(overflowMenu, breadCrumbsUlLis[i]);
205
+ totalLisOffsetWidth -= breadCrumbsUlLis[1].offsetWidth;
206
+ breadCrumbsUlLis[i].style.display = "none";
207
+ i++;
208
+ }
209
+ }
210
+
211
+ truncateLastLi(breadCrumbsUlLis, breadCrumbsUl);
212
+ }
213
+
214
+ checkChevrons();
215
+ }
216
+ };
@@ -1,8 +1,8 @@
1
1
  // Storybook index file to import storybook related assets
2
2
  import "../core-assets/handlebar-helpers.js";
3
- import "../core-assets/main.js";
4
3
  import initAnimate from "./animate-js.js";
5
4
  import initAccordion from "./accordion-js.js";
5
+ import { initBreadcrumbs, getTheElements } from "./breadcrumbs-js.js";
6
6
  import initComponents from "../../src/component-loader.js";
7
7
 
8
8
  // ES module initialisation for Core components
@@ -12,4 +12,12 @@ initComponents();
12
12
  document.addEventListener("DOMContentLoaded", () => {
13
13
  initAnimate(document);
14
14
  initAccordion(document);
15
+ initBreadcrumbs(document);
16
+ initAccordion(document, "overflow"); // Needed specifically for the breadcrumbs overflow functionality
17
+ });
18
+
19
+ window.addEventListener("resize", function () {
20
+ getTheElements(true);
21
+ initBreadcrumbs(document);
22
+ initAccordion(document, "overflow");
15
23
  });
@@ -0,0 +1,9 @@
1
+ // Global SCSS imports
2
+ @import "../../src/styles/core-styles.scss";
3
+
4
+ // Global shared imports
5
+ @import "../../src/components/_global/css/*.scss";
6
+ @import "../../src/components/_global/css/**/*.scss";
7
+
8
+ // Component SCSS imports
9
+ @import "../../src/components/**/css/component.scss";
@@ -24,3 +24,26 @@
24
24
  }
25
25
  }
26
26
  }
27
+
28
+ .iconography-container {
29
+ display: flex;
30
+ flex-direction: row;
31
+ flex-wrap: wrap;
32
+
33
+ .iconography-item {
34
+ display: flex;
35
+ flex-direction: column;
36
+ align-items: center;
37
+ border: 1px solid var(--QLD-color-light__heading);
38
+ border-radius: 8px;
39
+ gap: 1rem;
40
+ margin: 1rem;
41
+ padding: 2rem 1rem;
42
+ width: 12rem;
43
+
44
+ .qld__dark &,
45
+ .qld__dark-alt & {
46
+ border-color: white;
47
+ }
48
+ }
49
+ }
@@ -33,6 +33,11 @@ export const themeColours = {
33
33
  "dark alt": "var(--QLD-color-dark__background--alt)",
34
34
  };
35
35
 
36
+ export const dummyText =
37
+ "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.";
38
+
39
+ export const dummyLink = "https://www.google.com";
40
+
36
41
  export const figmaLinks = {
37
42
  masterDoc: {
38
43
  file: "https://www.figma.com/design/qKsxl3ogIlBp7dafgxXuCA/QGDS-UI-kit?node-id=23529-440999&t=y8LMLpCtTxOgtHpT-0",
@@ -41,6 +46,18 @@ export const figmaLinks = {
41
46
  design: "https://www.figma.com/design/qKsxl3ogIlBp7dafgxXuCA/QGDS-UI-kit?node-id=11056-321317&p=f&t=A5RGn3vQ6cEyXHw7-0",
42
47
  ds: "https://www.designsystem.qld.gov.au/components/back-to-top",
43
48
  },
49
+ breadcrumbs: {
50
+ design: "https://www.figma.com/design/qKsxl3ogIlBp7dafgxXuCA/QGDS-UI-kit?node-id=5990-98076&p=f&t=4xsFBWGSPA5BjG6z-0",
51
+ ds: "https://www.designsystem.qld.gov.au/components/breadcrumbs",
52
+ },
53
+ button: {
54
+ design: "https://www.figma.com/design/qKsxl3ogIlBp7dafgxXuCA/QGDS-UI-kit?node-id=5990-98058&p=f&t=pMQreNNlQuuKMxlD-0",
55
+ ds: "https://www.designsystem.qld.gov.au/components/button",
56
+ },
57
+ callout: {
58
+ design: "https://www.figma.com/design/qKsxl3ogIlBp7dafgxXuCA/QGDS-UI-kit?node-id=5990-98115&p=f&t=3aGzWYalpb1UXS73-0",
59
+ ds: "https://www.designsystem.qld.gov.au/components/callout",
60
+ },
44
61
  checkboxes: {
45
62
  design: "https://www.figma.com/design/qKsxl3ogIlBp7dafgxXuCA/QGDS-UI-kit?node-id=11056-321348&p=f&t=WmKMIp3MbkVrYkUf-0",
46
63
  ds: "https://www.designsystem.qld.gov.au/components/checkboxes",
@@ -53,14 +70,29 @@ export const figmaLinks = {
53
70
  design: "https://www.figma.com/design/qKsxl3ogIlBp7dafgxXuCA/QGDS-UI-kit?node-id=11056-321363&p=f&t=WmKMIp3MbkVrYkUf-0",
54
71
  ds: "https://www.designsystem.qld.gov.au/components/direction-links",
55
72
  },
73
+ globalAlert: {
74
+ design: "https://www.figma.com/design/qKsxl3ogIlBp7dafgxXuCA/QGDS-UI-kit?node-id=5990-97590&p=f&t=DWJ5IM0EPnQV6Sui-0",
75
+ ds: "https://www.designsystem.qld.gov.au/components/global-alert",
76
+ },
77
+ iconography: {
78
+ ds: "https://www.designsystem.qld.gov.au/styles/iconography",
79
+ },
56
80
  inPageAlert: {
57
81
  design: "https://www.figma.com/design/qKsxl3ogIlBp7dafgxXuCA/QGDS-UI-kit?node-id=5990-98125&p=f&t=WmKMIp3MbkVrYkUf-0",
58
82
  ds: "https://www.designsystem.qld.gov.au/components/alerts-in-page",
59
83
  },
84
+ inPageNavigation: {
85
+ design: "https://www.figma.com/design/qKsxl3ogIlBp7dafgxXuCA/QGDS-UI-kit?node-id=7905-252906&p=f&t=HnUAp2BI742820Qk-0",
86
+ ds: "https://www.designsystem.qld.gov.au/components/in-page-navigation",
87
+ },
60
88
  linkColumns: {
61
89
  design: "https://www.figma.com/design/qKsxl3ogIlBp7dafgxXuCA/QGDS-UI-kit?node-id=11056-321574&p=f&t=WmKMIp3MbkVrYkUf-0",
62
90
  ds: "https://www.designsystem.qld.gov.au/components/link-columns-link-list",
63
91
  },
92
+ loadingSpinner: {
93
+ design: "https://www.figma.com/design/qKsxl3ogIlBp7dafgxXuCA/QGDS-UI-kit?node-id=49314-16705&p=f&t=N6vEZVb73vuDEtRO-0",
94
+ ds: "https://www.designsystem.qld.gov.au/components/loading-spinner",
95
+ },
64
96
  pagination: {
65
97
  design: "https://www.figma.com/design/qKsxl3ogIlBp7dafgxXuCA/QGDS-UI-kit?node-id=11056-321779&p=f&t=wdrRF6qJa1fuzxWP-0",
66
98
  ds: "https://www.designsystem.qld.gov.au/components/pagination",
@@ -77,12 +109,36 @@ export const figmaLinks = {
77
109
  design: "https://www.figma.com/design/qKsxl3ogIlBp7dafgxXuCA/QGDS-UI-kit?node-id=11056-321345&p=f&t=WmKMIp3MbkVrYkUf-0",
78
110
  ds: "https://www.designsystem.qld.gov.au/components/input-fields-select-box",
79
111
  },
112
+ tabs: {
113
+ design: "https://www.figma.com/design/qKsxl3ogIlBp7dafgxXuCA/QGDS-UI-kit?node-id=25951-236134&p=f&t=pMQreNNlQuuKMxlD-0",
114
+ ds: "https://www.designsystem.qld.gov.au/components/tabs",
115
+ },
80
116
  tags: {
81
117
  design: "https://www.figma.com/design/qKsxl3ogIlBp7dafgxXuCA/QGDS-UI-kit?node-id=5990-97596&p=f&t=WmKMIp3MbkVrYkUf-0",
82
118
  ds: "https://www.designsystem.qld.gov.au/components/tags",
83
119
  },
120
+ textInput: {
121
+ design: "https://www.figma.com/design/qKsxl3ogIlBp7dafgxXuCA/QGDS-UI-kit?node-id=5990-97997&p=f&t=yRd2EKrtkEkPbBDT-0",
122
+ ds: "https://www.designsystem.qld.gov.au/components/text-input",
123
+ },
84
124
  videoPlayer: {
85
125
  design: "https://www.figma.com/design/qKsxl3ogIlBp7dafgxXuCA/QGDS-UI-kit?node-id=13297-214065&p=f&t=WmKMIp3MbkVrYkUf-0",
86
126
  ds: "https://www.designsystem.qld.gov.au/components",
87
127
  },
128
+ header: {
129
+ design: "https://www.figma.com/design/qKsxl3ogIlBp7dafgxXuCA/QGDS-UI-kit?node-id=5990-97586&p=f&t=UZuh698yg2zKvMDG-0",
130
+ ds: "https://www.designsystem.qld.gov.au/components/header",
131
+ },
132
+ horizontalRule: {
133
+ design: "https://www.figma.com/design/qKsxl3ogIlBp7dafgxXuCA/QGDS-UI-kit?node-id=5990-97954&p=f&t=avPgpU6waAIMt5Tt-0",
134
+ ds: "https://www.designsystem.qld.gov.au/components/horizontal-rule",
135
+ },
136
+ navbar: {
137
+ design: "https://www.figma.com/design/qKsxl3ogIlBp7dafgxXuCA/QGDS-UI-kit?node-id=5990-97586&p=f&t=UZuh698yg2zKvMDG-0",
138
+ ds: "https://www.designsystem.qld.gov.au/components/navigation-horizontal",
139
+ },
140
+ footer: {
141
+ design: "https://www.figma.com/design/qKsxl3ogIlBp7dafgxXuCA/QGDS-UI-kit?node-id=5990-97582&p=f&t=xM7nOPN0NPouiFDO-0",
142
+ ds: "https://www.designsystem.qld.gov.au/components/footer",
143
+ },
88
144
  };
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Remove the ./?a= prefix from all href, src, and srcset in rendered HTML
3
+ * @param {string} html - the HTML string to clean
4
+ * @returns {string} - cleaned HTML
5
+ */
6
+ export const cleanStorybookUrls = (html) => {
7
+ return (
8
+ html
9
+ .replace(/(\b(?:href|src|srcset)=["'])\.\/\?a=/g, "$1")
10
+ // CSS url(./?a=...)
11
+ .replace(/url\(\s*\.\/\?a=/g, "url(")
12
+ );
13
+ };
14
+
15
+ export const themeWrapper = (theme, content) => {
16
+ return `<div class="${theme}" style="padding: 2rem;">${content}</div>`;
17
+ };
18
+
19
+ export const getSvgPath = () => {
20
+ return window.location.origin === "https://qld-health-online-team.github.io" ? "/design-system/QLD-icons.svg" : "/QLD-icons.svg";
21
+ };
@@ -1,4 +1,5 @@
1
1
  /** @type { import('@storybook/html-vite').StorybookConfig } */
2
+ import sassGlobImports from "vite-plugin-sass-glob-import";
2
3
 
3
4
  const config = {
4
5
  stories: ["../src/**/*.mdx", "../src/**/*.stories.@(js|jsx|mjs|ts|tsx)"],
@@ -7,6 +8,10 @@ const config = {
7
8
  name: "@storybook/html-vite",
8
9
  options: {},
9
10
  },
11
+ async viteFinal(config) {
12
+ config.plugins.push(sassGlobImports());
13
+ return config;
14
+ },
10
15
  staticDirs: ["../dist/mysource_files/img", "./core-assets", "./assets"],
11
16
  };
12
17
  export default config;
@@ -1,7 +1,7 @@
1
1
  const fs = require("fs");
2
2
  const path = require("path");
3
3
 
4
- const filesToCopy = ["main.css", "main.css.map", "js/main.js", "js/main.js.map", "js/helpers.js"];
4
+ const filesToCopy = ["js/helpers.js"];
5
5
  const srcDir = path.resolve("dist");
6
6
  const destDir = path.resolve(".storybook/core-assets");
7
7
 
@@ -1,2 +1 @@
1
- <link href="main.css" rel="stylesheet" />
2
- <link href="storybook.css" rel="stylesheet" />
1
+ <!-- Add external links here, such as cdn scripts -->
@@ -1,6 +1,23 @@
1
- import "./assets/index.js"; // Storybook assets import
1
+ import "./assets/index.js"; // Storybook JS import
2
+ import "./assets/index.scss"; // Storybook styles import from core
3
+ import "./assets/storybook.scss"; // Storybook specific styles
2
4
  import { INITIAL_VIEWPORTS } from "storybook/viewport";
3
5
  import { viewports, themes, themeColours } from "./globals.js";
6
+ import { getSvgPath } from "./helper-functions.js";
7
+
8
+ const iconsIds = fetch(getSvgPath())
9
+ .then((res) => res.text())
10
+ .then((svgText) => {
11
+ // Parse the text as XML
12
+ const parser = new DOMParser();
13
+ const svgDoc = parser.parseFromString(svgText, "image/svg+xml");
14
+
15
+ // Select all <symbol> elements
16
+ const symbols = svgDoc.querySelectorAll("symbol");
17
+
18
+ // Map their IDs
19
+ return Array.from(symbols).map((sym) => sym.id);
20
+ });
4
21
 
5
22
  /** @type { import('@storybook/html-vite').Preview } */
6
23
  const preview = {
@@ -56,16 +73,29 @@ const preview = {
56
73
  },
57
74
  },
58
75
  },
76
+ options: {
77
+ storySort: {
78
+ // Force SB to load Introduction page first
79
+ order: ["Introduction", "1. Core Styles", "2. Layout", "3. Components"],
80
+ },
81
+ },
59
82
  },
60
83
  args: {
61
- site: { metadata: { coreSiteIcons: { value: "/QLD-icons.svg" } } },
84
+ // Ensure GitHub hosted page uses correct icon path
85
+ site: { metadata: { coreSiteIcons: { value: getSvgPath() } } },
86
+ iconIDs: await iconsIds,
62
87
  },
63
88
  argTypes: {
64
89
  // Remove the site metadata from the controls
65
90
  site: { table: { disable: true } },
91
+ iconIDs: { table: { disable: true } },
66
92
  },
67
93
  decorators: [
68
94
  (storyFn, context) => {
95
+ // Skip wrapper for Navbar story
96
+ if (context.kind === "Components/Navbar") {
97
+ return storyFn();
98
+ }
69
99
  // Get the theme key from the background, to use within the decorator
70
100
  const themeKey = Object.keys(themeColours).find((key) => themeColours[key] === context.globals.backgrounds?.value);
71
101
  const wrapper = document.createElement("div");
package/CHANGELOG.md CHANGED
@@ -7,6 +7,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## Unreleased
9
9
 
10
+ ## 1.20.0 - 2026-02-25
11
+
10
12
  ## 1.19.2 - 2026-02-04
11
13
 
12
14
  ## 1.19.1 - 2026-02-02
package/package.json CHANGED
@@ -1,7 +1,11 @@
1
1
  {
2
2
  "name": "@qhealth-design-system/core",
3
- "version": "1.19.2",
3
+ "version": "1.20.0",
4
4
  "description": "",
5
+ "repository": {
6
+ "type": "git",
7
+ "url": "https://github.com/Qld-Health-Online-Team/design-system"
8
+ },
5
9
  "licence": "MIT",
6
10
  "main": "index.js",
7
11
  "scripts": {
@@ -60,6 +64,7 @@
60
64
  "terser-webpack-plugin": "^5.3.9",
61
65
  "url-loader": "^4.1.1",
62
66
  "vite": "^7.2.6",
67
+ "vite-plugin-sass-glob-import": "^6.0.2",
63
68
  "webpack": "^5.88.0",
64
69
  "webpack-cli": "^5.1.4",
65
70
  "webpack-dev-server": "^4.15.1"
@@ -7,11 +7,13 @@ import initPromoPanel from "./components/promo_panel/js/global.js";
7
7
  import initVideoPlayer from "./components/video_player/js/global.js";
8
8
 
9
9
  // Global components
10
+ import initCtaLinks from "./components/_global/js/cta_links/global.js";
10
11
  import initSelectBoxes from "./components/_global/js/select_boxes/global.js";
11
12
 
12
13
  // Adding ES module initialisation for components
13
14
  export default function initComponents() {
14
15
  document.addEventListener("DOMContentLoaded", () => {
16
+ initCtaLinks(document);
15
17
  initHeader(document);
16
18
  initInPageNavigation(document);
17
19
  initInternalNavigation(document);