@qhealth-design-system/core 1.20.2 → 1.21.1

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 (129) hide show
  1. package/.storybook/globals.js +83 -69
  2. package/.storybook/helper-functions.js +0 -4
  3. package/.storybook/main.js +2 -0
  4. package/.storybook/preview-head.html +1 -0
  5. package/.storybook/preview.js +4 -20
  6. package/.storybook/vite-plugin-hbs.js +52 -0
  7. package/.stylelintignore +5 -0
  8. package/.stylelintrc.json +24 -0
  9. package/CHANGELOG.md +4 -0
  10. package/eslint.config.mjs +65 -0
  11. package/package.json +25 -18
  12. package/prettier.config.js +17 -0
  13. package/src/component-loader.js +10 -0
  14. package/src/components/_global/css/cta_links/component.scss +1 -1
  15. package/src/components/_global/css/link_columns/component.scss +8 -0
  16. package/src/components/_global/css/table/component.scss +6 -118
  17. package/src/components/accordion/js/global.js +12 -13
  18. package/src/components/banner/html/component.hbs +31 -3
  19. package/src/components/banner_advanced/css/component.scss +298 -2
  20. package/src/components/basic_search/html/component.hbs +4 -4
  21. package/src/components/global_alert/js/global.js +31 -47
  22. package/src/components/in_page_navigation/html/component.hbs +9 -16
  23. package/src/components/in_page_navigation/js/global.js +25 -3
  24. package/src/components/main_navigation/js/global.js +1 -39
  25. package/src/components/mega_main_navigation/js/global.js +160 -158
  26. package/src/data/current.json +0 -187
  27. package/src/helpers/Handlebars/renderEncoded.js +14 -0
  28. package/src/html/home.html +1 -6
  29. package/src/html/inner-with-nav.html +1 -3
  30. package/src/stories/AZListing/a-z_listing.stories.js +72 -0
  31. package/src/stories/Abstract/abstract.stories.js +68 -0
  32. package/src/stories/BackToTop/BackToTop.stories.js +12 -22
  33. package/src/stories/Banner/banner.stories.js +76 -0
  34. package/src/stories/Banner/bannerAdvanced.stories.js +234 -0
  35. package/src/stories/Banner/bannerBasic.stories.js +105 -0
  36. package/src/stories/Body/body.stories.js +94 -0
  37. package/src/stories/Breadcrumbs/Breadcrumbs.stories.js +16 -21
  38. package/src/stories/Button/Button.stories.js +70 -0
  39. package/src/stories/CTALink/CTALink.stories.js +83 -31
  40. package/src/stories/Callout/Callout.stories.js +25 -35
  41. package/src/stories/Cards/CardFeature.stories.js +164 -0
  42. package/src/stories/Cards/CardMultiAction.stories.js +212 -0
  43. package/src/stories/Cards/CardNoAction.stories.js +201 -0
  44. package/src/stories/Cards/CardSingleAction.stories.js +197 -0
  45. package/src/stories/Cards/Toowoomba-web.jpeg +0 -0
  46. package/src/stories/DirectionLinks/DirectionLinks.stories.js +2 -8
  47. package/src/stories/Footer/Footer.stories.js +7 -13
  48. package/src/stories/{Checkboxes → Forms/Checkboxes}/Checkboxes.js +4 -2
  49. package/src/stories/{Checkboxes → Forms/Checkboxes}/Checkboxes.stories.js +4 -9
  50. package/src/stories/{RadioButtons → Forms/RadioButtons}/RadioButtons.js +4 -2
  51. package/src/stories/{RadioButtons → Forms/RadioButtons}/RadioButtons.stories.js +5 -10
  52. package/src/stories/{SelectBox → Forms/SelectBox}/SelectBox.js +4 -2
  53. package/src/stories/{SelectBox → Forms/SelectBox}/SelectBox.stories.js +5 -10
  54. package/src/stories/Forms/forms.stories.js +188 -0
  55. package/src/stories/Forms/numberInput.stories.js +68 -0
  56. package/src/stories/Forms/textInput.stories.js +147 -0
  57. package/src/stories/Forms/textarea.stories.js +145 -0
  58. package/src/stories/GlobalAlert/GlobalAlert.stories.js +135 -0
  59. package/src/stories/Header/Header.js +2 -4
  60. package/src/stories/Header/Header.stories.js +5 -8
  61. package/src/stories/Iconography/Iconography.stories.js +12 -9
  62. package/src/stories/InPageAlert/InPageAlert.stories.js +27 -31
  63. package/src/stories/InPageNavigation/InPageNavigation.stories.js +89 -0
  64. package/src/stories/Introduction.mdx +3 -36
  65. package/src/stories/LinkColumns/LinkColumns.stories.js +35 -23
  66. package/src/stories/LoadingSpinner/LoadingSpinner.stories.js +11 -25
  67. package/src/stories/MegaMainNavigation/mega_main_navigation.a11y.stories.js +138 -0
  68. package/src/stories/MegaMainNavigation/mega_main_navigation.stories.js +245 -0
  69. package/src/stories/Navbar/Navbar.js +2 -5
  70. package/src/stories/Navbar/Navbar.stories.js +2 -12
  71. package/src/stories/Pagination/Pagination.stories.js +4 -10
  72. package/src/stories/PromoPanel/PromoPanel.stories.js +8 -44
  73. package/src/stories/Table/table.stories.js +112 -0
  74. package/src/stories/Tags/Tags.js +5 -3
  75. package/src/stories/Tags/Tags.stories.js +3 -8
  76. package/src/stories/VideoPlayer/VideoPlayer.stories.js +8 -20
  77. package/src/styles/imports/utilities.scss +80 -0
  78. package/src/components/banner_intermediate/css/component.scss +0 -289
  79. package/src/components/banner_intermediate/html/component.hbs +0 -196
  80. package/src/components/banner_intermediate/js/global.js +0 -6
  81. package/src/components/banner_intermediate/js/manifest.json +0 -249
  82. package/src/components/card_no_action/js/global.js +0 -6
  83. package/src/html/component-a-z_listing.html +0 -57
  84. package/src/html/component-abstract.html +0 -582
  85. package/src/html/component-banner.html +0 -581
  86. package/src/html/component-banner_advanced.html +0 -70
  87. package/src/html/component-banner_basic.html +0 -55
  88. package/src/html/component-banner_intermediate.html +0 -64
  89. package/src/html/component-body.html +0 -605
  90. package/src/html/component-breadcrumbs.html +0 -583
  91. package/src/html/component-btn.html +0 -640
  92. package/src/html/component-callout.html +0 -582
  93. package/src/html/component-card_feature.html +0 -601
  94. package/src/html/component-card_multi_action.html +0 -1227
  95. package/src/html/component-card_no_action.html +0 -395
  96. package/src/html/component-card_single_action.html +0 -602
  97. package/src/html/component-footer.html +0 -583
  98. package/src/html/component-forms.html +0 -1612
  99. package/src/html/component-global_alert.html +0 -582
  100. package/src/html/component-header.html +0 -583
  101. package/src/html/component-in_page_navigation.html +0 -605
  102. package/src/html/component-loading_spinner.html +0 -45
  103. package/src/html/component-overflow_menu.html +0 -62
  104. package/src/html/component-page_alert.html +0 -582
  105. package/src/html/component-page_footer_info.html +0 -583
  106. package/src/html/component-pagination.html +0 -583
  107. package/src/html/component-promo_panel.html +0 -46
  108. package/src/html/component-tag_list.html +0 -1027
  109. package/src/html/component-video_player.html +0 -57
  110. package/src/stories/BackToTop/BackToTop.js +0 -8
  111. package/src/stories/BackToTop/BackToTop.mdx +0 -24
  112. package/src/stories/Breadcrumbs/Breadcrumbs.mdx +0 -30
  113. package/src/stories/CTALink/CTALink.mdx +0 -36
  114. package/src/stories/Callout/Callout.mdx +0 -28
  115. package/src/stories/Checkboxes/Checkboxes.mdx +0 -42
  116. package/src/stories/DirectionLinks/DirectionLinks.mdx +0 -34
  117. package/src/stories/Footer/Footer.mdx +0 -36
  118. package/src/stories/Header/Header.mdx +0 -61
  119. package/src/stories/Iconography/Iconography.mdx +0 -23
  120. package/src/stories/InPageAlert/InPageAlert.mdx +0 -64
  121. package/src/stories/LinkColumns/LinkColumns.mdx +0 -28
  122. package/src/stories/LoadingSpinner/LoadingSpinner.mdx +0 -30
  123. package/src/stories/Navbar/Navbar.mdx +0 -37
  124. package/src/stories/Pagination/Pagination.mdx +0 -26
  125. package/src/stories/PromoPanel/PromoPanel.mdx +0 -26
  126. package/src/stories/RadioButtons/RadioButtons.mdx +0 -42
  127. package/src/stories/SelectBox/SelectBox.mdx +0 -118
  128. package/src/stories/Tags/Tags.mdx +0 -63
  129. package/src/stories/VideoPlayer/VideoPlayer.mdx +0 -26
@@ -38,107 +38,121 @@ export const dummyText =
38
38
 
39
39
  export const dummyLink = "https://www.google.com";
40
40
 
41
- export const figmaLinks = {
42
- masterDoc: {
43
- file: "https://www.figma.com/design/qKsxl3ogIlBp7dafgxXuCA/QGDS-UI-kit?node-id=23529-440999&t=y8LMLpCtTxOgtHpT-0",
44
- },
41
+ // Path to the icon sprite, relative to the Storybook preview iframe. Used for
42
+ // <use href> references and the coreSiteIcons metadata across stories.
43
+ export const iconSpritePath = "QLD-icons.svg";
44
+
45
+ const dsBase = "https://www.designsystem.qld.gov.au";
46
+ const figmaBase = "https://www.figma.com/design/qKsxl3ogIlBp7dafgxXuCA/QGDS-UI-kit";
47
+
48
+ export const componentLinks = {
49
+ accordion: { ds: `${dsBase}/components/accordion` },
45
50
  backToTop: {
46
- design: "https://www.figma.com/design/qKsxl3ogIlBp7dafgxXuCA/QGDS-UI-kit?node-id=11056-321317&p=f&t=A5RGn3vQ6cEyXHw7-0",
47
- ds: "https://www.designsystem.qld.gov.au/components/back-to-top",
51
+ ds: `${dsBase}/patterns/back-to-top`,
52
+ figma: `${figmaBase}?node-id=135268-27564&t=Gk55sISVPoJM2wm4-0`,
48
53
  },
54
+ banner: { ds: `${dsBase}/components/banner`, figma: `${figmaBase}?node-id=120353-65175&t=Lne25vgTT2xUkJcD-0` },
49
55
  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
+ ds: `${dsBase}/components/breadcrumbs`,
57
+ figma: `${figmaBase}?node-id=5990-98076&p=f&t=4xsFBWGSPA5BjG6z-0`,
56
58
  },
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",
59
+ button: { ds: `${dsBase}/components/button`, figma: `${figmaBase}?node-id=5990-98058&p=f&t=pMQreNNlQuuKMxlD-0` },
60
+ callout: { ds: `${dsBase}/components/callout`, figma: `${figmaBase}?node-id=5990-98115&p=f&t=3aGzWYalpb1UXS73-0` },
61
+ card: {
62
+ ds: `${dsBase}/components/card`,
63
+ figma: `${figmaBase}?node-id=120360-98159&t=SzNNrsljtXa1LjkF-0`,
60
64
  },
61
65
  checkboxes: {
62
- design: "https://www.figma.com/design/qKsxl3ogIlBp7dafgxXuCA/QGDS-UI-kit?node-id=11056-321348&p=f&t=WmKMIp3MbkVrYkUf-0",
63
- ds: "https://www.designsystem.qld.gov.au/components/checkboxes",
66
+ ds: `${dsBase}/components/checkbox`,
67
+ figma: `${figmaBase}?node-id=11056-321348&p=f&t=WmKMIp3MbkVrYkUf-0`,
64
68
  },
65
69
  ctaLink: {
66
- design: "https://www.figma.com/design/qKsxl3ogIlBp7dafgxXuCA/QGDS-UI-kit?node-id=11056-321367&p=f&t=WmKMIp3MbkVrYkUf-0",
67
- ds: "https://www.designsystem.qld.gov.au/components/call-to-action-cta",
70
+ ds: `${dsBase}/components/call-to-action-cta`,
71
+ figma: `${figmaBase}?node-id=11056-321367&p=f&t=WmKMIp3MbkVrYkUf-0`,
68
72
  },
69
73
  directionLinks: {
70
- design: "https://www.figma.com/design/qKsxl3ogIlBp7dafgxXuCA/QGDS-UI-kit?node-id=11056-321363&p=f&t=WmKMIp3MbkVrYkUf-0",
71
- ds: "https://www.designsystem.qld.gov.au/components/direction-links",
74
+ ds: `${dsBase}/components/direction-link`,
75
+ figma: `${figmaBase}?node-id=11056-321363&p=f&t=WmKMIp3MbkVrYkUf-0`,
72
76
  },
77
+ footer: { ds: `${dsBase}/components/footer`, figma: `${figmaBase}?node-id=5990-97582&p=f&t=xM7nOPN0NPouiFDO-0` },
78
+ forms: { ds: `${dsBase}/components/forms` },
73
79
  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",
80
+ ds: `${dsBase}/components/global-alert`,
81
+ figma: `${figmaBase}?node-id=5990-97590&p=f&t=DWJ5IM0EPnQV6Sui-0`,
76
82
  },
77
- iconography: {
78
- ds: "https://www.designsystem.qld.gov.au/styles/iconography",
83
+ header: { ds: `${dsBase}/components/header`, figma: `${figmaBase}?node-id=5990-97586&p=f&t=UZuh698yg2zKvMDG-0` },
84
+ horizontalRule: {
85
+ ds: `${dsBase}/components/horizontal-rule`,
86
+ figma: `${figmaBase}?node-id=5990-97954&p=f&t=avPgpU6waAIMt5Tt-0`,
79
87
  },
88
+ iconography: { ds: `${dsBase}/styles/iconography` },
80
89
  inPageAlert: {
81
- design: "https://www.figma.com/design/qKsxl3ogIlBp7dafgxXuCA/QGDS-UI-kit?node-id=5990-98125&p=f&t=WmKMIp3MbkVrYkUf-0",
82
- ds: "https://www.designsystem.qld.gov.au/components/alerts-in-page",
90
+ ds: `${dsBase}/components/alerts-in-page`,
91
+ figma: `${figmaBase}?node-id=5990-98125&p=f&t=WmKMIp3MbkVrYkUf-0`,
83
92
  },
84
93
  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",
94
+ ds: `${dsBase}/components/in-page-navigation`,
95
+ figma: `${figmaBase}?node-id=7905-252906&p=f&t=Tb6VtPPWrZ7Na35f-0`,
87
96
  },
88
97
  linkColumns: {
89
- design: "https://www.figma.com/design/qKsxl3ogIlBp7dafgxXuCA/QGDS-UI-kit?node-id=11056-321574&p=f&t=WmKMIp3MbkVrYkUf-0",
90
- ds: "https://www.designsystem.qld.gov.au/components/link-columns-link-list",
98
+ ds: `${dsBase}/components/link-columns-link-list`,
99
+ figma: `${figmaBase}?node-id=11056-321574&p=f&t=WmKMIp3MbkVrYkUf-0`,
91
100
  },
92
101
  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",
102
+ ds: `${dsBase}/components/loading-spinner`,
103
+ figma: `${figmaBase}?node-id=49314-16705&p=f&t=N6vEZVb73vuDEtRO-0`,
104
+ },
105
+ navbar: {
106
+ ds: `${dsBase}/components/navigation-horizontal`,
107
+ figma: `${figmaBase}?node-id=5990-97586&p=f&t=UZuh698yg2zKvMDG-0`,
95
108
  },
96
109
  pagination: {
97
- design: "https://www.figma.com/design/qKsxl3ogIlBp7dafgxXuCA/QGDS-UI-kit?node-id=11056-321779&p=f&t=wdrRF6qJa1fuzxWP-0",
98
- ds: "https://www.designsystem.qld.gov.au/components/pagination",
110
+ ds: `${dsBase}/components/pagination`,
111
+ figma: `${figmaBase}?node-id=11056-321779&p=f&t=wdrRF6qJa1fuzxWP-0`,
99
112
  },
100
113
  promoPanel: {
101
- design: "https://www.figma.com/design/qKsxl3ogIlBp7dafgxXuCA/QGDS-UI-kit?node-id=23269-286312&p=f&t=ub7vIB4rUQNZ6zzo-0",
102
- ds: "https://www.designsystem.qld.gov.au/components/promotional-panel",
114
+ ds: `${dsBase}/components/promotional-panel`,
115
+ figma: `${figmaBase}?node-id=23269-286312&p=f&t=ub7vIB4rUQNZ6zzo-0`,
103
116
  },
104
117
  radioButtons: {
105
- design: "https://www.figma.com/design/qKsxl3ogIlBp7dafgxXuCA/QGDS-UI-kit?node-id=11056-321347&p=f&t=kHfUZsyKYuDkprji-0",
106
- ds: "https://www.designsystem.qld.gov.au/components/radio-buttons",
118
+ ds: `${dsBase}/components/radio-buttons`,
119
+ figma: `${figmaBase}?node-id=11056-321347&p=f&t=kHfUZsyKYuDkprji-0`,
107
120
  },
108
121
  selectBox: {
109
- design: "https://www.figma.com/design/qKsxl3ogIlBp7dafgxXuCA/QGDS-UI-kit?node-id=11056-321345&p=f&t=WmKMIp3MbkVrYkUf-0",
110
- ds: "https://www.designsystem.qld.gov.au/components/input-fields-select-box",
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
- },
116
- tags: {
117
- design: "https://www.figma.com/design/qKsxl3ogIlBp7dafgxXuCA/QGDS-UI-kit?node-id=5990-97596&p=f&t=WmKMIp3MbkVrYkUf-0",
118
- ds: "https://www.designsystem.qld.gov.au/components/tags",
122
+ ds: `${dsBase}/components/input-fields-select-box`,
123
+ figma: `${figmaBase}?node-id=11056-321345&p=f&t=WmKMIp3MbkVrYkUf-0`,
119
124
  },
125
+ table: { ds: `${dsBase}/components/table`, figma: `${figmaBase}?node-id=120418-57729&t=VPLTzrxLs85peK9J-0` },
126
+ tabs: { ds: `${dsBase}/components/tabs`, figma: `${figmaBase}?node-id=25951-236134&p=f&t=pMQreNNlQuuKMxlD-0` },
127
+ tags: { ds: `${dsBase}/components/tags`, figma: `${figmaBase}?node-id=5990-97596&p=f&t=WmKMIp3MbkVrYkUf-0` },
120
128
  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",
129
+ ds: `${dsBase}/components/text-input`,
130
+ figma: `${figmaBase}?node-id=5990-97997&p=f&t=yRd2EKrtkEkPbBDT-0`,
123
131
  },
124
132
  videoPlayer: {
125
- design: "https://www.figma.com/design/qKsxl3ogIlBp7dafgxXuCA/QGDS-UI-kit?node-id=13297-214065&p=f&t=WmKMIp3MbkVrYkUf-0",
126
- ds: "https://www.designsystem.qld.gov.au/components",
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",
133
+ figma: `${figmaBase}?node-id=13297-214065&p=f&t=WmKMIp3MbkVrYkUf-0`,
143
134
  },
144
135
  };
136
+
137
+ /**
138
+ * Standard docs parameters for a story.
139
+ * Renders a Resources line at the top of autodocs with links to the QLD Design System
140
+ * and Figma (when available). Both are looked up automatically from the component key.
141
+ *
142
+ * @param {keyof typeof componentLinks} componentKey
143
+ */
144
+ export function storyParams(componentKey) {
145
+ const { ds, figma } = componentLinks[componentKey] ?? {};
146
+ const links = ds ? [`[QLD Design System ↗](${ds})`] : [];
147
+ if (figma) links.push(`[Figma UI Kit ↗](${figma})`);
148
+ return {
149
+ docs: {
150
+ toc: true,
151
+ codePanel: true,
152
+ description: {
153
+ component: `**Resources:** ${links.join(" · ")}`,
154
+ },
155
+ },
156
+ ...(figma && { design: { type: "figma", url: figma } }),
157
+ };
158
+ }
@@ -15,7 +15,3 @@ export const cleanStorybookUrls = (html) => {
15
15
  export const themeWrapper = (theme, content) => {
16
16
  return `<div class="${theme}" style="padding: 2rem;">${content}</div>`;
17
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,5 +1,6 @@
1
1
  /** @type { import('@storybook/html-vite').StorybookConfig } */
2
2
  import sassGlobImports from "vite-plugin-sass-glob-import";
3
+ import hbsPlugin from "./vite-plugin-hbs.js"
3
4
 
4
5
  const config = {
5
6
  stories: ["../src/**/*.mdx", "../src/**/*.stories.@(js|jsx|mjs|ts|tsx)"],
@@ -10,6 +11,7 @@ const config = {
10
11
  },
11
12
  async viteFinal(config) {
12
13
  config.plugins.push(sassGlobImports());
14
+ config.plugins.push(hbsPlugin())
13
15
  return config;
14
16
  },
15
17
  staticDirs: ["../dist/mysource_files/img", "./core-assets", "./assets"],
@@ -1 +1,2 @@
1
1
  <!-- Add external links here, such as cdn scripts -->
2
+ <script src="https://kit.fontawesome.com/66722b4f34.js" crossorigin="anonymous"></script>
@@ -2,25 +2,11 @@ import "./assets/index.js"; // Storybook JS import
2
2
  import "./assets/index.scss"; // Storybook styles import from core
3
3
  import "./assets/storybook.scss"; // Storybook specific styles
4
4
  import { INITIAL_VIEWPORTS } from "storybook/viewport";
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
- });
5
+ import { viewports, themes, themeColours, iconSpritePath } from "./globals.js";
21
6
 
22
7
  /** @type { import('@storybook/html-vite').Preview } */
23
8
  const preview = {
9
+ tags: ["autodocs"],
24
10
  parameters: {
25
11
  controls: {
26
12
  matchers: {
@@ -82,13 +68,11 @@ const preview = {
82
68
  },
83
69
  args: {
84
70
  // Ensure GitHub hosted page uses correct icon path
85
- site: { metadata: { coreSiteIcons: { value: getSvgPath() } } },
86
- iconIDs: await iconsIds,
71
+ site: { metadata: { coreSiteIcons: { value: iconSpritePath } } },
87
72
  },
88
73
  argTypes: {
89
74
  // Remove the site metadata from the controls
90
75
  site: { table: { disable: true } },
91
- iconIDs: { table: { disable: true } },
92
76
  },
93
77
  decorators: [
94
78
  (storyFn, context) => {
@@ -97,7 +81,7 @@ const preview = {
97
81
  return storyFn();
98
82
  }
99
83
  // Get the theme key from the background, to use within the decorator
100
- const themeKey = Object.keys(themeColours).find((key) => themeColours[key] === context.globals.backgrounds?.value);
84
+ const themeKey = Object.keys(themeColours).find((key) => key === context.globals.backgrounds?.value);
101
85
  const wrapper = document.createElement("div");
102
86
  wrapper.className = themes[themeKey] || themes["white"];
103
87
  const story = storyFn();
@@ -0,0 +1,52 @@
1
+ import Handlebars from 'handlebars';
2
+
3
+ /**
4
+ * Vite plugin that transforms Handlebars component templates (.hbs)
5
+ * into pre-compiled JavaScript modules for use in Storybook.
6
+ *
7
+ * Without this plugin, Vite cannot handle .hbs files. Stories would need to import
8
+ * templates as raw strings (?raw) and call Handlebars.compile() at runtime in the
9
+ * browser on every render. This plugin moves compilation to build time instead.
10
+ *
11
+ * How it works:
12
+ * 1. Vite intercepts any import ending in .hbs
13
+ * 2. Handlebars.precompile() converts the template source into a serialisable
14
+ * template spec (a plain JS object) at build time in Node
15
+ * 3. The plugin emits a JS module that calls Handlebars.template(spec) to wrap
16
+ * the spec in a callable function — no parsing or compilation in the browser
17
+ *
18
+ * The emitted module imports the full 'handlebars' package (not 'handlebars/runtime')
19
+ * so that custom helpers registered in .storybook/core-assets/handlebar-helpers.js
20
+ * are available on the same Handlebars instance at runtime.
21
+ *
22
+ * Usage in a story:
23
+ * import Template from './html/component.hbs';
24
+ * Template({ component: { data: { metadata: { ... } } } }); // → HTML string
25
+ *
26
+ * Note: Files imported with the ?raw suffix bypass this plugin entirely — Vite's
27
+ * built-in raw loader handles those and returns the template source as a string.
28
+ *
29
+ * @returns {import('vite').Plugin}
30
+ */
31
+ export default function hbsPlugin() {
32
+ return {
33
+ name: 'vite-plugin-hbs',
34
+
35
+ transform(src, id) {
36
+ if (!id.endsWith('.hbs')) return;
37
+
38
+ const templateSpec = Handlebars.precompile(src);
39
+
40
+ const code = `
41
+ import Handlebars from 'handlebars';
42
+ const template = Handlebars.template(${templateSpec});
43
+ export default template;
44
+ `;
45
+
46
+ return {
47
+ code,
48
+ map: null,
49
+ };
50
+ },
51
+ };
52
+ }
@@ -0,0 +1,5 @@
1
+ src/externals/
2
+ src/styles/imports/cssbackup.css
3
+ **/*.hbs
4
+ storybook-static
5
+ dist
@@ -0,0 +1,24 @@
1
+ {
2
+ "extends": ["stylelint-config-standard"],
3
+ "plugins": ["stylelint-scss"],
4
+ "rules": {
5
+ "selector-class-pattern": [
6
+ "^[a-z][a-z0-9-]*(__[a-z0-9][a-z0-9_-]*)*(--[a-z0-9][a-z0-9-]*)?$",
7
+ { "message": "Expected class selector to use BEM naming convention" }
8
+ ],
9
+ "custom-property-pattern": null
10
+ },
11
+ "overrides": [
12
+ {
13
+ "files": ["**/*.scss"],
14
+ "customSyntax": "postcss-scss",
15
+ "rules": {
16
+ "at-rule-no-unknown": null,
17
+ "scss/at-rule-no-unknown": true,
18
+ "function-no-unknown": null,
19
+ "no-descending-specificity": null,
20
+ "annotation-no-unknown": null
21
+ }
22
+ }
23
+ ]
24
+ }
package/CHANGELOG.md CHANGED
@@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## Unreleased
9
9
 
10
+ ## 1.21.1 - 2026-06-10
11
+
12
+ ## 1.21.0 - 2026-06-09
13
+
10
14
  ## 1.20.2 - 2026-03-12
11
15
 
12
16
  ## 1.20.1 - 2026-02-25
@@ -0,0 +1,65 @@
1
+ import js from "@eslint/js";
2
+ import globals from "globals";
3
+ import json from "@eslint/json";
4
+ import markdown from "@eslint/markdown";
5
+ import css from "@eslint/css";
6
+ import { defineConfig, globalIgnores } from "eslint/config";
7
+ import eslintConfigPrettier from "eslint-config-prettier/flat";
8
+ import storybook from "eslint-plugin-storybook";
9
+
10
+ export default defineConfig([
11
+ globalIgnores(["!.storybook"], "Include Storybook Directory"),
12
+ globalIgnores(["storybook-static", "*.min.js", "src/externals", "dist"]),
13
+ {
14
+ files: ["src/**/*.js", ".storybook/**/*.js"],
15
+ plugins: { js },
16
+ extends: ["js/recommended"],
17
+ languageOptions: {
18
+ sourceType: "module",
19
+ globals: globals.browser,
20
+ parserOptions: {
21
+ allowImportExportEverywhere: true,
22
+ },
23
+ },
24
+ rules: {
25
+ "no-const-assign": "warn",
26
+ "no-this-before-super": "warn",
27
+ "no-undef": "warn",
28
+ "no-unreachable": "warn",
29
+ "no-unused-vars": "warn",
30
+ "constructor-super": "warn",
31
+ "valid-typeof": "warn",
32
+ },
33
+ },
34
+ {
35
+ files: ["webpack/**/*.js", "scripts/**/*.js", "*.config.js", "postcss.config.js"],
36
+ plugins: { js },
37
+ extends: ["js/recommended"],
38
+ languageOptions: {
39
+ sourceType: "commonjs",
40
+ globals: globals.node,
41
+ parserOptions: {
42
+ allowImportExportEverywhere: true,
43
+ },
44
+ },
45
+ rules: {
46
+ "no-const-assign": "warn",
47
+ "no-this-before-super": "warn",
48
+ "no-undef": "warn",
49
+ "no-unreachable": "warn",
50
+ "no-unused-vars": "warn",
51
+ "constructor-super": "warn",
52
+ "valid-typeof": "warn",
53
+ },
54
+ },
55
+ {
56
+ // Storybook config files (main.js, prepare-storybook.js, etc.) run in Node.
57
+ files: [".storybook/**/*.js"],
58
+ languageOptions: { globals: globals.node },
59
+ },
60
+ { files: ["**/*.json"], plugins: { json }, language: "json/json", extends: ["json/recommended"] },
61
+ { files: ["**/*.md"], plugins: { markdown }, language: "markdown/gfm", extends: ["markdown/recommended"] },
62
+ { files: ["**/*.css"], plugins: { css }, language: "css/css", extends: ["css/recommended"] },
63
+ eslintConfigPrettier,
64
+ ...storybook.configs["flat/recommended"],
65
+ ]);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@qhealth-design-system/core",
3
- "version": "1.20.2",
3
+ "version": "1.21.1",
4
4
  "description": "",
5
5
  "repository": {
6
6
  "type": "git",
@@ -14,8 +14,8 @@
14
14
  "serve": "webpack-dev-server --open --config webpack/webpack.dev.js",
15
15
  "add-component": "bash scripts/add_component.sh",
16
16
  "jsdoc": "./node_modules/jsdoc/jsdoc.js -a all -c jsdoc.json -r -R README.md ./src/components/ -d ./documentation/jsdoc",
17
- "lint:js": "eslint \"./src/**/*.js\"",
18
- "lint:styles": "stylelint \"./src/**/*.css\" \"./src/**/*.scss\" \"!./src/**/*.min.css\"",
17
+ "lint:js": "eslint .",
18
+ "lint:styles": "stylelint \"**/*.{css,scss}\"",
19
19
  "lint": "npm run lint:js && npm run lint:styles",
20
20
  "build-storybook": "node .storybook/prepare-storybook.js && storybook build",
21
21
  "storybook": "storybook dev -p 6006",
@@ -26,24 +26,30 @@
26
26
  "license": "ISC",
27
27
  "devDependencies": {
28
28
  "@babel/core": "^7.22.5",
29
- "@babel/eslint-parser": "^7.22.9",
30
29
  "@babel/plugin-syntax-dynamic-import": "^7.8.3",
31
30
  "@babel/preset-env": "^7.22.5",
32
31
  "@babel/preset-react": "^7.22.5",
33
- "@storybook/addon-a11y": "^10.1.10",
34
- "@storybook/addon-designs": "^11.1.0",
35
- "@storybook/addon-docs": "^10.1.10",
36
- "@storybook/addon-themes": "^10.1.10",
37
- "@storybook/html-vite": "^10.1.10",
32
+ "@eslint/css": "^1.3.0",
33
+ "@eslint/js": "^10.0.1",
34
+ "@eslint/json": "^2.0.0",
35
+ "@eslint/markdown": "^8.0.2",
36
+ "@poliklot/prettier-plugin-handlebars": "^0.2.12",
37
+ "@storybook/addon-a11y": "^10.4.0",
38
+ "@storybook/addon-designs": "^11.1.3",
39
+ "@storybook/addon-docs": "^10.4.0",
40
+ "@storybook/addon-themes": "^10.4.0",
41
+ "@storybook/html-vite": "^10.4.0",
38
42
  "autoprefixer": "^10.4.14",
39
- "chromatic": "^13.3.4",
43
+ "chromatic": "^17.0.0",
40
44
  "copy-webpack-plugin": "^11.0.0",
41
45
  "core-js": "^3.31.0",
42
46
  "css-loader": "^5.2.6",
43
- "eslint": "^8.43.0",
44
- "eslint-plugin-storybook": "^10.1.10",
45
- "eslint-webpack-plugin": "^4.0.1",
47
+ "eslint": "^10.4.1",
48
+ "eslint-config-prettier": "^10.1.8",
49
+ "eslint-plugin-storybook": "^10.4.0",
50
+ "eslint-webpack-plugin": "^6.0.0",
46
51
  "glob": "^7.2.0",
52
+ "globals": "^17.6.0",
47
53
  "handlebars": "^4.7.8",
48
54
  "html-loader": "^0.5.5",
49
55
  "html-webpack-plugin": "^5.5.3",
@@ -52,15 +58,16 @@
52
58
  "jsdoc": "^4.0.2",
53
59
  "mini-css-extract-plugin": "^2.7.6",
54
60
  "postcss-loader": "^7.3.3",
61
+ "postcss-scss": "^4.0.9",
62
+ "prettier": "3.8.3",
55
63
  "sass": "^1.63.6",
56
64
  "sass-loader": "^13.3.2",
57
- "storybook": "^10.1.10",
65
+ "storybook": "^10.4.0",
58
66
  "string-replace-loader": "^3.1.0",
59
67
  "style-loader": "^3.3.3",
60
- "stylelint": "^15.9.0",
61
- "stylelint-config-standard": "^33.0.0",
62
- "stylelint-scss": "^5.0.1",
63
- "stylelint-webpack-plugin": "^4.1.1",
68
+ "stylelint": "^17.12.0",
69
+ "stylelint-config-standard": "^40.0.0",
70
+ "stylelint-scss": "^7.1.0",
64
71
  "terser-webpack-plugin": "^5.3.9",
65
72
  "url-loader": "^4.1.1",
66
73
  "vite": "^7.2.6",
@@ -0,0 +1,17 @@
1
+ /** @type {import("prettier").Config} */
2
+ module.exports = {
3
+ printWidth: 240,
4
+ semi: true,
5
+ tabWidth: 4,
6
+ singleQuote: false,
7
+ trailingComma: "all",
8
+ plugins: ["@poliklot/prettier-plugin-handlebars"],
9
+ overrides: [
10
+ {
11
+ files: ["*.hbs", "*.handlebars"],
12
+ options: {
13
+ parser: "handlebars",
14
+ },
15
+ },
16
+ ],
17
+ };
@@ -1,3 +1,6 @@
1
+ // Global utilities (sets up window.QLD / QLD.utils) — must load before any init runs
2
+ import "./components/_global/js/global.js";
3
+
1
4
  // Standard components
2
5
  import initHeader from "./components/header/js/global.js";
3
6
  import initInPageNavigation from "./components/in_page_navigation/js/global.js";
@@ -5,6 +8,8 @@ import initInternalNavigation from "./components/internal_navigation/js/global.j
5
8
  import initLeftHandNav from "./components/left_hand_navigation/js/global.js";
6
9
  import initPromoPanel from "./components/promo_panel/js/global.js";
7
10
  import initVideoPlayer from "./components/video_player/js/global.js";
11
+ import { initMegaMenu } from "./components/mega_main_navigation/js/global";
12
+ import { initGlobalAlert } from "./components/global_alert/js/global.js";
8
13
 
9
14
  // Global components
10
15
  import initCtaLinks from "./components/_global/js/cta_links/global.js";
@@ -12,12 +17,17 @@ import initSelectBoxes from "./components/_global/js/select_boxes/global.js";
12
17
 
13
18
  // Adding ES module initialisation for components
14
19
  export default function initComponents() {
20
+ // Call initGlobalAlert outside the DOMContentLoaded callback so it executes immediately. There is a noticeable
21
+ // delay before the DOMContentLoaded event fires, which can cause dismissed global alerts to stay visible for a few
22
+ // seconds before they are removed. Likely to remove DOMContentLoaded event listener in the future.
23
+ initGlobalAlert();
15
24
  document.addEventListener("DOMContentLoaded", () => {
16
25
  initCtaLinks(document);
17
26
  initHeader(document);
18
27
  initInPageNavigation(document);
19
28
  initInternalNavigation(document);
20
29
  initLeftHandNav(document);
30
+ initMegaMenu();
21
31
  initPromoPanel(document);
22
32
  initSelectBoxes(document);
23
33
  initVideoPlayer(document);
@@ -14,7 +14,7 @@ a.qld__cta-link {
14
14
 
15
15
  &::before {
16
16
  @include QLD-space(width, 1unit);
17
- top: 50%;
17
+ top: 1rem;
18
18
  right: 0.3rem;
19
19
  }
20
20
 
@@ -43,6 +43,14 @@
43
43
  padding-right: 2rem;
44
44
  }
45
45
 
46
+ // Rule that ensures that if a cta-link is used in the link columns, the correct arrow is displayed
47
+ a.qld__cta-link:not(.qld__cta-link--view-all) {
48
+ &::before,
49
+ &::after {
50
+ display: none;
51
+ }
52
+ }
53
+
46
54
  &::before {
47
55
  @include QLD-space(margin, 0 0.5unit 0 0.5unit);
48
56
  flex: 0 0 auto;