@qld-gov-au/qgds-bootstrap5 2.0.12 → 2.1.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 (121) hide show
  1. package/.esbuild/plugins/qgds-plugin-generate-icon-assets.js +31 -24
  2. package/.storybook/preview.js +15 -6
  3. package/dist/assets/components/bs5/button/button.hbs +1 -1
  4. package/dist/assets/components/bs5/callToAction/callToAction.hbs +3 -3
  5. package/dist/assets/components/bs5/dateinput/dateinput.hbs +21 -27
  6. package/dist/assets/components/bs5/footer/customLinks.hbs +1 -1
  7. package/dist/assets/components/bs5/footer/followLinks.hbs +1 -1
  8. package/dist/assets/components/bs5/globalAlert/globalAlert.hbs +8 -1
  9. package/dist/assets/components/bs5/head/head.hbs +1 -1
  10. package/dist/assets/components/bs5/inpageAlert/inpageAlert.hbs +10 -2
  11. package/dist/assets/components/bs5/pagination/pagination.hbs +7 -2
  12. package/dist/assets/components/bs5/promotionalPanel/promotionalPanel.hbs +1 -1
  13. package/dist/assets/components/bs5/searchInput/searchInput.hbs +11 -9
  14. package/dist/assets/css/qld.bootstrap.css +2 -2
  15. package/dist/assets/css/qld.bootstrap.css.map +3 -3
  16. package/dist/assets/css/qld.bootstrap.legacy.css +2 -2
  17. package/dist/assets/css/qld.bootstrap.legacy.css.map +3 -3
  18. package/dist/assets/img/icons-sprite.svg +24 -24
  19. package/dist/assets/js/handlebars.helpers.bundle.js +1 -1
  20. package/dist/assets/js/handlebars.init.min.js +80 -64
  21. package/dist/assets/js/handlebars.init.min.js.map +2 -2
  22. package/dist/assets/js/handlebars.partials.js +80 -64
  23. package/dist/assets/js/handlebars.partials.js.map +2 -2
  24. package/dist/assets/js/qld.bootstrap.min.js +6 -6
  25. package/dist/assets/js/qld.bootstrap.min.js.map +4 -4
  26. package/dist/assets/node/handlebars.init.min.js +28 -19
  27. package/dist/assets/node/handlebars.init.min.js.map +2 -2
  28. package/dist/components/bs5/button/button.hbs +1 -1
  29. package/dist/components/bs5/callToAction/callToAction.hbs +3 -3
  30. package/dist/components/bs5/dateinput/dateinput.hbs +21 -27
  31. package/dist/components/bs5/footer/customLinks.hbs +1 -1
  32. package/dist/components/bs5/footer/followLinks.hbs +1 -1
  33. package/dist/components/bs5/globalAlert/globalAlert.hbs +8 -1
  34. package/dist/components/bs5/head/head.hbs +1 -1
  35. package/dist/components/bs5/inpageAlert/inpageAlert.hbs +10 -2
  36. package/dist/components/bs5/pagination/pagination.hbs +7 -2
  37. package/dist/components/bs5/promotionalPanel/promotionalPanel.hbs +1 -1
  38. package/dist/components/bs5/searchInput/searchInput.hbs +11 -9
  39. package/dist/package.json +33 -32
  40. package/dist/sample-data/callToAction/callToAction.data.json +2 -1
  41. package/dist/sample-data/dateinput/dateinput.data.json +3 -1
  42. package/dist/sample-data/footer/footer.data.json +3 -0
  43. package/dist/sample-data/inpageAlert/inpageAlert.data.json +1 -1
  44. package/dist/sample-data/pagination/pagination.data.json +4 -4
  45. package/dist/sample-data/promotionalPanel/promotionalPanel.data.json +45 -47
  46. package/dist/sample-data/searchInput/searchInput.data.json +1 -0
  47. package/package.json +33 -32
  48. package/src/components/bs5/breadcrumbs/breadcrumbs.scss +4 -4
  49. package/src/components/bs5/button/Button.js +32 -6
  50. package/src/components/bs5/button/button.hbs +1 -1
  51. package/src/components/bs5/button/button.scss +1 -5
  52. package/src/components/bs5/button/button.stories.js +16 -4
  53. package/src/components/bs5/callToAction/callToAction.data.json +2 -1
  54. package/src/components/bs5/callToAction/callToAction.hbs +3 -3
  55. package/src/components/bs5/callToAction/callToAction.stories.js +2 -2
  56. package/src/components/bs5/card/card.scss +4 -2
  57. package/src/components/bs5/dateinput/Dateinput.js +1 -38
  58. package/src/components/bs5/dateinput/Dateinput.mdx +27 -0
  59. package/src/components/bs5/dateinput/Dateinput.stories.js +48 -4
  60. package/src/components/bs5/dateinput/dateinput.data.json +3 -1
  61. package/src/components/bs5/dateinput/dateinput.functions.js +91 -0
  62. package/src/components/bs5/dateinput/dateinput.hbs +21 -27
  63. package/src/components/bs5/footer/customLinks.hbs +1 -1
  64. package/src/components/bs5/footer/followLinks.hbs +1 -1
  65. package/src/components/bs5/footer/footer.data.json +3 -0
  66. package/src/components/bs5/formcheck/_form-variables.scss +36 -0
  67. package/src/components/bs5/formcheck/formcheck.scss +59 -14
  68. package/src/components/bs5/globalAlert/globalAlert.hbs +8 -1
  69. package/src/components/bs5/globalAlert/globalAlert.scss +14 -19
  70. package/src/components/bs5/globalAlert/globalAlert.stories.js +1 -0
  71. package/src/components/bs5/globalAlert/globalAlert.test.js +10 -5
  72. package/src/components/bs5/header/header.scss +1 -2
  73. package/src/components/bs5/icons/_icons.list.js +7 -7
  74. package/src/components/bs5/icons/_icons.list.scss +113 -112
  75. package/src/components/bs5/icons/_icons.variables.scss +7 -6
  76. package/src/components/bs5/icons/icons.scss +2 -1
  77. package/src/components/bs5/inpageAlert/inpageAlert.data.json +1 -1
  78. package/src/components/bs5/inpageAlert/inpageAlert.hbs +10 -2
  79. package/src/components/bs5/inpageAlert/inpageAlert.scss +52 -55
  80. package/src/components/bs5/inpageAlert/inpageAlert.stories.js +54 -3
  81. package/src/components/bs5/inpagenav/inpagenav.scss +9 -1
  82. package/src/components/bs5/modal/modal.scss +1 -1
  83. package/src/components/bs5/navbar/navbar.functions.js +39 -28
  84. package/src/components/bs5/navbar/navbar.scss +43 -28
  85. package/src/components/bs5/navbar/navbar.stories.js +4 -3
  86. package/src/components/bs5/pageLayout/PaletteShowcase.stories.js +4 -3
  87. package/src/components/bs5/pagination/pagination.data.json +4 -4
  88. package/src/components/bs5/pagination/pagination.hbs +7 -2
  89. package/src/components/bs5/pagination/pagination.scss +1 -1
  90. package/src/components/bs5/promotionalPanel/promotionalPanel.data.json +45 -47
  91. package/src/components/bs5/promotionalPanel/promotionalPanel.hbs +1 -1
  92. package/src/components/bs5/quickexit/quickexit.scss +1 -1
  93. package/src/components/bs5/searchInput/__snapshots__/searchInput.test.js.snap +16 -16
  94. package/src/components/bs5/searchInput/search.functions.js +70 -71
  95. package/src/components/bs5/searchInput/searchInput.data.json +1 -0
  96. package/src/components/bs5/searchInput/searchInput.hbs +11 -9
  97. package/src/components/bs5/searchInput/searchInput.scss +92 -38
  98. package/src/components/bs5/searchInput/searchInput.test.js +91 -119
  99. package/src/components/bs5/sidenav/sidenav.scss +17 -19
  100. package/src/components/bs5/skiplinks/skipLinks.scss +12 -4
  101. package/src/components/bs5/table/table.scss +93 -83
  102. package/src/components/common/focus-styles/focusStyles.mdx +20 -0
  103. package/src/components/common/focus-styles/focusStyles.stories.js +58 -0
  104. package/src/css/functions/_index.scss +3 -0
  105. package/src/css/functions/color-icon.scss +31 -0
  106. package/src/css/functions/string-replace.scss +49 -0
  107. package/src/css/functions/svg-encode.scss +22 -0
  108. package/src/css/main.scss +3 -0
  109. package/src/css/mixins/focusable.scss +1 -1
  110. package/src/css/mixins/make-icon.scss +1 -1
  111. package/src/css/mixins/make-link.scss +13 -10
  112. package/src/css/qld-palettes.scss +20 -12
  113. package/src/css/qld-reduced-motion.scss +51 -0
  114. package/src/css/qld-tokens.scss +3 -3
  115. package/src/css/qld-type.scss +11 -13
  116. package/src/css/qld-utilities.scss +9 -1
  117. package/src/css/qld-variables.scss +1 -1
  118. package/src/img/icons-sprite.svg +24 -24
  119. package/src/js/constants.js +10 -0
  120. package/src/js/qld.bootstrap.js +99 -151
  121. package/src/js/utils.js +3 -1
@@ -1,5 +1,6 @@
1
1
  import { Navbar } from "./Navbar.js";
2
2
  import defaultdata from "./navbar.data.json";
3
+ import { breakpoints } from "../../../js/constants.js";
3
4
 
4
5
  //Default story
5
6
  export default {
@@ -164,7 +165,7 @@ export default {
164
165
  }
165
166
 
166
167
  /* Mobile-only items - hide on desktop with unique class names */
167
- @media (min-width: 992px) {
168
+ @media (min-width: ${breakpoints.lg}px) {
168
169
  .qgds-mobile-only,
169
170
  .qgds-hide-desktop,
170
171
  .navbar-nav .qgds-mobile-only,
@@ -504,7 +505,7 @@ export const Default = {
504
505
  justify-content: flex-end;
505
506
  align-items: center;
506
507
  }
507
- @media (width <= 992px) {
508
+ @media (width <= ${breakpoints.lg}px) {
508
509
 
509
510
  #burgerBtn {
510
511
  --nav-header-icon-color: #ffe500;
@@ -533,7 +534,7 @@ export const Default = {
533
534
  background-color: var(--nav-header-icon-color, #ffe500);
534
535
  }
535
536
  }
536
- @media (width >= 992px) {
537
+ @media (width >= ${breakpoints.lg}px) {
537
538
  #burgerBtn, #storybook-only-header {
538
539
  display: none !important;
539
540
  }
@@ -231,9 +231,6 @@ export const PaletteComparison = {
231
231
  <div class="col-md-3">
232
232
  <div class="bg-dark p-2 text-center rounded text-white">.bg-dark</div>
233
233
  </div>
234
- <div class="col-md-3">
235
- <div class="bg-dark-alt p-2 text-center rounded text-white">.bg-dark-alt</div>
236
- </div>
237
234
  <div class="col-md-3">
238
235
  <div class="bg-default-shade p-2 text-center rounded">.bg-default-shade</div>
239
236
  </div>
@@ -243,6 +240,10 @@ export const PaletteComparison = {
243
240
  <div class="col-md-3">
244
241
  <div class="bg-light-alt-shade p-2 text-center rounded">.bg-light-alt-shade</div>
245
242
  </div>
243
+ <div class="col-md-3">
244
+ <div class="bg-dark-alt p-2 text-center rounded text-white">.bg-dark-alt</div>
245
+ </div>
246
+
246
247
  </div>
247
248
  </div>
248
249
  `,
@@ -12,10 +12,10 @@
12
12
  },
13
13
 
14
14
  "pages": [
15
- { "href": "#", "linktext": "1", "customClasses": "" },
16
- { "href": "#", "linktext": "2", "customClasses": "active" },
17
- { "href": "#", "linktext": "3", "customClasses": "" },
15
+ { "href": "#", "linktext": "1", "arialabel": "Page 1", "customClasses": "" },
16
+ { "href": "#", "linktext": "2", "arialabel": "Page 2, current page", "customClasses": "active" },
17
+ { "href": "#", "linktext": "3", "arialabel": "Page 3", "customClasses": "" },
18
18
  { "href": "#", "linktext": "", "customClasses": "more", "more": true },
19
- { "href": "#", "linktext": "7", "customClasses": "" }
19
+ { "href": "#", "linktext": "7", "arialabel": "Page 7", "customClasses": "" }
20
20
  ]
21
21
  }
@@ -23,8 +23,13 @@ Reference: https://getbootstrap.com/docs/5.0/components/pagination/
23
23
  {{! More button }}
24
24
  <span></span>
25
25
  {{else}}
26
- {{! Page button }}
27
- <a class="page-link" href="{{href}}" aria-label="{{arialabel}}">{{ linktext }}</a>
26
+ {{#ifCond "active" "in" customClasses}}
27
+ {{! Active page - not a link }}
28
+ <span class="page-link" aria-current="page" aria-label="{{#if arialabel}}{{arialabel}}{{else}}Page {{linktext}}, current page{{/if}}">{{ linktext }}</span>
29
+ {{else}}
30
+ {{! Page button }}
31
+ <a class="page-link" href="{{href}}" aria-label="{{#if arialabel}}{{arialabel}}{{else}}Page {{linktext}}{{/if}}">{{ linktext }}</a>
32
+ {{/ifCond}}
28
33
  {{/if}}
29
34
  </li>
30
35
 
@@ -148,7 +148,7 @@ $pagination-icon-more-dark-hover-color: var(--#{$prefix}dark-action-secondary);
148
148
  .next {
149
149
  margin-left: 0.25rem;
150
150
  }
151
- .active a {
151
+ .active .page-link {
152
152
  font-weight: 700;
153
153
  }
154
154
 
@@ -1,48 +1,46 @@
1
1
  {
2
- "type": "indent-text",
3
- "variantClass": "light",
4
- "promoImage": "./assets/img/banner-example-3-to-2.jpg",
5
- "contentAlignment": "content-left",
6
- "icon": "icon-dot-grid",
7
- "title": "Title goes here and has a maximum of 65 character limit",
8
- "abstract": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed tortor, leo vulputate ut odio mattis.",
9
- "body": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed tortor, leo vulputate ut odio mattis. Vel suspendisse mi quisque consequat aliquet egestas.",
10
- "cta": {
11
- "items": [
12
- {
13
- "url": "#",
14
- "id": "https://www.wired.com",
15
- "value": "Label",
16
- "target": "_blank",
17
- "class": [
18
- {"small": false},
19
- {"view-all": false}
20
- ]
21
- }
22
- ]
23
- },
24
- "btn": {
25
- "items": [
26
- {
27
- "variantClass": "btn-primary",
28
- "islink": true,
29
- "isdisabled": false,
30
- "iconClass": "",
31
- "iconPosition": "",
32
- "label": "Primary",
33
- "href": "https://google.com",
34
- "target": "_self"
35
- },
36
- {
37
- "variantClass": "btn-secondary",
38
- "islink": true,
39
- "isdisabled": false,
40
- "iconClass": "",
41
- "iconPosition": "",
42
- "label": "Secondary",
43
- "href": "https://google.com",
44
- "target": "_self"
45
- }
46
- ]
47
- }
48
- }
2
+ "type": "indent-text",
3
+ "variantClass": "light",
4
+ "promoImage": "./assets/img/banner-example-3-to-2.jpg",
5
+ "promoImageDescription": "Promotional image",
6
+ "contentAlignment": "content-left",
7
+ "icon": "icon-dot-grid",
8
+ "title": "Title goes here and has a maximum of 65 character limit",
9
+ "abstract": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed tortor, leo vulputate ut odio mattis.",
10
+ "body": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed tortor, leo vulputate ut odio mattis. Vel suspendisse mi quisque consequat aliquet egestas.",
11
+ "cta": {
12
+ "items": [
13
+ {
14
+ "url": "#",
15
+ "id": "https://www.wired.com",
16
+ "value": "Label",
17
+ "target": "_blank",
18
+ "class": [{ "small": false }, { "view-all": false }]
19
+ }
20
+ ]
21
+ },
22
+ "btn": {
23
+ "items": [
24
+ {
25
+ "variantClass": "btn-primary",
26
+ "islink": true,
27
+ "isdisabled": false,
28
+ "iconClass": "",
29
+ "iconPosition": "",
30
+ "label": "Primary",
31
+ "href": "https://google.com",
32
+ "target": "_self"
33
+ },
34
+ {
35
+ "variantClass": "btn-secondary",
36
+ "islink": true,
37
+ "isdisabled": false,
38
+ "iconClass": "",
39
+ "iconPosition": "",
40
+ "label": "Secondary",
41
+ "href": "https://google.com",
42
+ "target": "_self"
43
+ }
44
+ ]
45
+ }
46
+ }
@@ -5,7 +5,7 @@
5
5
  {{/ifCond}}>
6
6
  <div class="image-panel">
7
7
  {{#ifCond type '!=' 'promo'}}
8
- <img class="promo-panel-image" src="{{promoImage}}" alt="Promotional Image">
8
+ <img class="promo-panel-image" src="{{promoImage}}" alt="{{isdefined promoImageDescription "Promotional image"}}">
9
9
  {{else}}
10
10
  <div class="promo-panel-image"></div>
11
11
  {{/ifCond}}
@@ -166,7 +166,7 @@
166
166
  position: -webkit-sticky;
167
167
  position: sticky;
168
168
  inset-block-start: 0;
169
- z-index: 999;
169
+ z-index: 500;
170
170
  padding-block: 20px;
171
171
  padding-inline: 40px;
172
172
  .container {
@@ -1,4 +1,4 @@
1
- // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
1
+ // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
2
2
 
3
3
  exports[`SearchInput > Renders as expected 1`] = `
4
4
  "<!--
@@ -6,32 +6,32 @@ exports[`SearchInput > Renders as expected 1`] = `
6
6
  -->
7
7
  <div class="qld-search-input ">
8
8
  <input id="search" name="query" class="form-control" type="text" autocomplete="off"
9
- aria-label="Search website" data-collection="qgov~sp-search" data-profile="qld" data-numranks="10" data-tiers="off" data-suggestions="https://discover.search.qld.gov.au/s/suggest.json" data-results-url="https://discover.search.qld.gov.au/s/search.json" />
10
- <button class="btn btn-primary" type="submit" id="search-button">
11
- <span class="btn-icon"></span>
9
+ aria-label="Search website" data-collection="qgov~sp-search" data-profile="qld" data-numranks="10" data-tiers="off" data-suggestions="https://discover.search.qld.gov.au/s/suggest.json" data-results-url="https://discover.search.qld.gov.au/s/search.json" placeholder="" />
10
+ <button class="btn btn-primary" type="submit" id="search-button" aria-label="Search">
11
+ <span class="btn-icon" aria-hidden="true"></span>
12
12
  <span class="btn-label">Search</span>
13
13
  </button>
14
- <div class="suggestions suggestions__group d-none default">
14
+
15
+ <div class="suggestions suggestions__group default">
15
16
  <div class="default-suggestions">
16
17
  <div class="suggestions-category">
17
18
  <strong class="suggestions-category-label d-block">Popular</strong>
18
19
  <ul>
19
- <li><a href="https://www.forgov.qld.gov.au/pay-benefits-and-policy/leave/submit-a-leave-application">Apply for leave now</a></li>
20
- <li><a href="https://www.forgov.qld.gov.au/recruitment-performance-and-career/starting-a-new-job/apply-for-higher-duties-or-relieving-at-level">Apply for higher duties or relieving at level</a></li>
21
- <li><a href="https://www.forgov.qld.gov.au/recruitment-performance-and-career/recruitment/extending-my-job/extend-a-temporary-or-casual-employee">Extend a temporary or casual employee</a></li>
22
- <li><a href="https://www.forgov.qld.gov.au/recruitment-performance-and-career/recruitment">Hire a staff member (recruitment)</a></li>
23
- <li><a href="/queenslanders" class="view-more">View more</a></li>
20
+ <li><a tabindex="0" href="https://www.forgov.qld.gov.au/pay-benefits-and-policy/leave/submit-a-leave-application">Apply for leave now</a></li>
21
+ <li><a tabindex="0" href="https://www.forgov.qld.gov.au/recruitment-performance-and-career/starting-a-new-job/apply-for-higher-duties-or-relieving-at-level">Apply for higher duties or relieving at level</a></li>
22
+ <li><a tabindex="0" href="https://www.forgov.qld.gov.au/recruitment-performance-and-career/recruitment/extending-my-job/extend-a-temporary-or-casual-employee">Extend a temporary or casual employee</a></li>
23
+ <li><a tabindex="0" href="https://www.forgov.qld.gov.au/recruitment-performance-and-career/recruitment">Hire a staff member (recruitment)</a></li>
24
+ <li><a tabindex="0" href="/queenslanders" class="view-more">View more</a></li>
24
25
  </ul>
25
26
  </div>
26
-
27
27
  <div class="suggestions-category">
28
28
  <strong class="suggestions-category-label d-block">Collection</strong>
29
29
  <ul>
30
- <li><a href="https://www.forgov.qld.gov.au/pay-benefits-and-policy/directives-policies-circulars-and-guidelines">Search for directives, policies, circulars, and guidelines</a></li>
31
- <li><a href="https://www.forgov.qld.gov.au/pay-benefits-and-policy/benefits/employee-pay-and-benefits">Employee pay and benefits</a></li>
32
- <li><a href="https://www.forgov.qld.gov.au/sandbox/archive/queensland-shared-services">Queensland Shared Services</a></li>
33
- <li><a href="https://www.forgov.qld.gov.au/recruitment-performance-and-career/career-development">Career development</a></li>
34
- <li><a href="/queenslanders" class="view-more">View all</a></li>
30
+ <li><a tabindex="0"href="https://www.forgov.qld.gov.au/pay-benefits-and-policy/directives-policies-circulars-and-guidelines">Search for directives, policies, circulars, and guidelines</a></li>
31
+ <li><a tabindex="0"href="https://www.forgov.qld.gov.au/pay-benefits-and-policy/benefits/employee-pay-and-benefits">Employee pay and benefits</a></li>
32
+ <li><a tabindex="0"href="https://www.forgov.qld.gov.au/sandbox/archive/queensland-shared-services">Queensland Shared Services</a></li>
33
+ <li><a tabindex="0"href="https://www.forgov.qld.gov.au/recruitment-performance-and-career/career-development">Career development</a></li>
34
+ <li><a tabindex="0" href="/queenslanders" class="view-more">View all</a></li>
35
35
  </ul>
36
36
  </div>
37
37
  </div>
@@ -1,5 +1,3 @@
1
- import { createPopper } from "@popperjs/core";
2
-
3
1
  /**
4
2
  * Fetches data from the provided URL.
5
3
  *
@@ -28,31 +26,28 @@ async function fetchData(url, type) {
28
26
  * @param {HTMLFormElement} form - The form element.
29
27
  * @returns {void}
30
28
  */
31
- export function selectSuggestion(value, form) {
29
+ export function selectDynamicSuggestion(value, form) {
32
30
  const searchInput = form.querySelector(".qld-search-input input");
33
31
  const suggestions = form.querySelector(".suggestions");
34
32
 
35
33
  if (searchInput && suggestions) {
36
- searchInput.value = value.trim();
37
- // suggestions.classList.add("d-none");
38
-
39
- // Retrieve additional params
40
- const collection =
41
- searchInput.getAttribute("data-collection") || "qgov~sp-search";
42
- const profile = searchInput.getAttribute("data-profile") || "qld";
43
- const numRanks = searchInput.getAttribute("data-numranks") || "10";
44
- const tiers = searchInput.getAttribute("data-tiers") || "off";
34
+ // Assign queryValue, and cleanup string before submission
35
+ let queryValue = value.replace(/\s+/g, " ").trim();
36
+ searchInput.value = queryValue;
45
37
 
46
38
  // Form action
47
39
  const actionUrl = form.getAttribute("action");
48
40
 
41
+ //data-* attributes on search input field
42
+ const atts = searchInput ? searchInput.dataset : null;
43
+
49
44
  // Construct the URL with proper parameters
50
45
  const params = new URLSearchParams({
51
- query: value.trim(),
52
- collection: collection,
53
- profile: profile,
54
- num_ranks: numRanks,
55
- tiers: tiers,
46
+ query: queryValue,
47
+ collection: atts.collection || "qgov~sp-search",
48
+ profile: atts.profile || "qld",
49
+ num_ranks: atts.numRanks || "10",
50
+ tiers: atts.tiers || "off",
56
51
  });
57
52
 
58
53
  const searchUrl = `${actionUrl}?${params.toString()}`;
@@ -81,11 +76,10 @@ export async function showSuggestions(value = "", isDefault = false, form) {
81
76
  );
82
77
 
83
78
  if (!suggestions || !searchInput) {
84
- console.warn("Required suggestions elements not found.");
85
79
  return;
86
80
  }
87
81
 
88
- // Hide/show default suggestions
82
+ // Hide/show default suggestions, and return early
89
83
  if (isDefault) {
90
84
  if (defaultSuggestionsContainer) {
91
85
  defaultSuggestionsContainer.classList.remove("d-none");
@@ -94,13 +88,10 @@ export async function showSuggestions(value = "", isDefault = false, form) {
94
88
  dynamicSuggestionsContainer.innerHTML = "";
95
89
  dynamicSuggestionsContainer.classList.add("d-none");
96
90
  }
97
- createPopper(searchInput, suggestions, {
98
- placement: "bottom-start",
99
- });
100
- suggestions.classList.remove("d-none");
101
91
  return;
102
92
  }
103
93
 
94
+ // If input is empty, hide dynamic suggestions and return early
104
95
  if (dynamicSuggestionsContainer) {
105
96
  if (value.length === 0) {
106
97
  dynamicSuggestionsContainer.innerHTML = "";
@@ -109,22 +100,27 @@ export async function showSuggestions(value = "", isDefault = false, form) {
109
100
  }
110
101
  }
111
102
 
112
- if (defaultSuggestionsContainer) {
113
- defaultSuggestionsContainer.classList.add("d-none");
114
- }
103
+ // Script continues...dynamic suggestions is true and value.length > 0
104
+ defaultSuggestionsContainer?.classList.add("d-none");
105
+
106
+ //data-* attributes on search input field
107
+ const atts = searchInput ? searchInput.dataset : null;
115
108
 
116
109
  // Fetch dynamic suggestions if available
117
110
  if (dynamicSuggestionsContainer) {
118
- const suggestUrl = searchInput.getAttribute("data-suggestions");
111
+ const suggestUrl = atts.suggestions;
112
+
119
113
  if (suggestUrl) {
120
- const collection =
121
- searchInput.getAttribute("data-collection") || "qgov~sp-search";
122
- const profile = searchInput.getAttribute("data-profile") || "qld";
114
+ const collection = atts.collection || "qgov~sp-search";
115
+ const profile = atts.profile || "qld";
116
+
117
+ //Fetch data from suggestions API
123
118
  const fetchedSuggestions = await fetchData(
124
119
  `${suggestUrl}?collection=${collection}&profile=${profile}&fmt=json&alpha=0.5&partial_query=${encodeURIComponent(value)}`,
125
120
  "suggestions",
126
121
  );
127
122
 
123
+ //Rended a suggestions list
128
124
  if (fetchedSuggestions.length > 0) {
129
125
  dynamicSuggestionsContainer.innerHTML = `
130
126
  <div class="suggestions-category">
@@ -135,34 +131,35 @@ export async function showSuggestions(value = "", isDefault = false, form) {
135
131
  new RegExp(`(${value})`, "gi"),
136
132
  "<strong>$1</strong>",
137
133
  );
138
- return `<li><a href="#">${highlightedText}</a></li>`;
134
+ return `<li><a tabindex="0" href="#">${highlightedText}</a></li>`;
139
135
  })
140
136
  .join("")}</ul>
141
137
  </div>`;
138
+
142
139
  dynamicSuggestionsContainer.classList.remove("d-none");
143
- createPopper(searchInput, suggestions, {
144
- placement: "bottom-start",
145
- });
146
- suggestions.classList.remove("d-none");
147
-
148
- // Attach click event listeners to each suggestion item
149
- form.querySelectorAll(".suggestions li").forEach((item) => {
150
- item.addEventListener("click", () =>
151
- selectSuggestion(item.innerText, form),
152
- );
153
- });
140
+
141
+ // Bind an event listener to suggestions container
142
+ form
143
+ .querySelector(".suggestions .dynamic-suggestions")
144
+ .addEventListener("click", (event) => {
145
+ let linkItem = event.target.closest("a");
146
+ if (linkItem) {
147
+ event.preventDefault();
148
+ selectDynamicSuggestion(linkItem.textContent, form);
149
+ }
150
+ });
154
151
  } else {
155
152
  dynamicSuggestionsContainer.innerHTML = "";
156
153
  dynamicSuggestionsContainer.classList.add("d-none");
157
- suggestions.classList.add("d-none");
158
154
  }
159
155
  }
160
156
 
161
- const resultsUrl = searchInput.getAttribute("data-results-url");
157
+ const resultsUrl = atts.resultsUrl; //data-results-url;
162
158
  if (resultsUrl) {
163
- const collection =
164
- searchInput.getAttribute("data-collection") || "qgov~sp-search";
165
- const profile = searchInput.getAttribute("data-profile") || "qld";
159
+ const collection = atts.collection || "qgov~sp-search";
160
+ const profile = atts.profile || "qld";
161
+
162
+ // Fetch related services from services API
166
163
  const fetchedServices = await fetchData(
167
164
  `${resultsUrl}?collection=${collection}&profile=${profile}&smeta_sfinder_sand=yes&query=${encodeURIComponent(value)}`,
168
165
  "services",
@@ -178,11 +175,14 @@ export async function showSuggestions(value = "", isDefault = false, form) {
178
175
  // Build the services HTML safely
179
176
  const servicesItems = fetchedServices.response.resultPacket.results
180
177
  .slice(0, 4)
181
- .map((item) => `<li><a href="${item.liveUrl}">${item.title}</a></li>`)
178
+ .map(
179
+ (item) =>
180
+ `<li><a tabindex="0" href="${item.liveUrl}">${item.title}</a></li>`,
181
+ )
182
182
  .join("");
183
183
 
184
184
  const viewMoreItem = viewMoreUrl
185
- ? `<li><a href="${viewMoreUrl}" class="view-more">View more</a></li>`
185
+ ? `<li><a tabindex="0" href="${viewMoreUrl}" class="view-more">View more</a></li>`
186
186
  : "";
187
187
 
188
188
  dynamicSuggestionsContainer.innerHTML += `
@@ -190,18 +190,19 @@ export async function showSuggestions(value = "", isDefault = false, form) {
190
190
  <strong class="suggestions-category-label d-block">Related services</strong>
191
191
  <ul>${servicesItems}${viewMoreItem}</ul>
192
192
  </div>`;
193
+
193
194
  dynamicSuggestionsContainer.classList.remove("d-none");
194
- createPopper(searchInput, suggestions, {
195
- placement: "bottom-start",
196
- });
197
- suggestions.classList.remove("d-none");
198
-
199
- // Attach click event listeners to each suggestion item
200
- form.querySelectorAll(".suggestions li").forEach((item) => {
201
- item.addEventListener("click", () =>
202
- selectSuggestion(item.innerText, form),
203
- );
204
- });
195
+
196
+ // Attach click event listeners to each SERVICE item in list
197
+ form
198
+ .querySelector(".suggestions .dynamic-suggestions")
199
+ .addEventListener("click", (event) => {
200
+ let linkItem = event.target.closest("a");
201
+ if (linkItem) {
202
+ event.preventDefault();
203
+ selectDynamicSuggestion(linkItem.textContent, form);
204
+ }
205
+ });
205
206
  }
206
207
  }
207
208
  }
@@ -216,19 +217,16 @@ export async function showSuggestions(value = "", isDefault = false, form) {
216
217
  */
217
218
  export function submitSearchForm(query = "", form) {
218
219
  const searchInput = form.querySelector(".qld-search-input input");
220
+ const atts = searchInput ? searchInput.dataset : null;
219
221
 
220
- const collection =
221
- searchInput.getAttribute("data-collection") || "qgov~sp-search";
222
- const profile = searchInput.getAttribute("data-profile") || "qld";
223
- const numRanks = searchInput.getAttribute("data-numranks") || "10";
224
- const tiers = searchInput.getAttribute("data-tiers") || "off";
222
+ const queryValue = query.trim().replace(/\s+/g, " ");
225
223
 
226
224
  const params = new URLSearchParams({
227
- query: query.trim(),
228
- collection: collection,
229
- profile: profile,
230
- num_ranks: numRanks,
231
- tiers: tiers,
225
+ query: queryValue,
226
+ collection: atts.collection || "qgov~sp-search",
227
+ profile: atts.profile || "qld",
228
+ num_ranks: atts.numRanks || "10",
229
+ tiers: atts.tiers || "off",
232
230
  });
233
231
 
234
232
  const searchUrl = `${form.getAttribute("action")}?${params.toString()}`;
@@ -236,4 +234,5 @@ export function submitSearchForm(query = "", form) {
236
234
  }
237
235
 
238
236
  // Attach the function to the window object to make it globally accessible
239
- window.selectSuggestion = (value, form) => selectSuggestion(value, form);
237
+ window.selectDynamicSuggestion = (value, form) =>
238
+ selectDynamicSuggestion(value, form);
@@ -6,6 +6,7 @@
6
6
  "buttonType": "submit",
7
7
  "buttonLabel": "Search",
8
8
  "ariaLabel": "Search website",
9
+ "placeholder": "",
9
10
  "tags": {
10
11
  "collection": "qgov~sp-search",
11
12
  "profile": "qld",
@@ -3,38 +3,40 @@
3
3
  -->
4
4
  <div class="qld-search-input {{customClass}}">
5
5
  <input id="{{ inputID }}" name="{{ inputName }}" class="form-control" type="text" autocomplete="off"
6
- aria-label="{{ ariaLabel }}" {{#each tags}} data-{{@key}}="{{this}}" {{/each}} />
7
- <button class="btn btn-primary" type="{{ buttonType }}" id="{{ buttonID }}">
8
- <span class="btn-icon"></span>
6
+ aria-label="{{ ariaLabel }}" {{#each tags}} data-{{@key}}="{{this}}" {{/each}} placeholder="{{placeholder}}" />
7
+ <button class="btn btn-primary" type="{{ buttonType }}" id="{{ buttonID }}" aria-label="{{ buttonLabel }}">
8
+ <span class="btn-icon" aria-hidden="true"></span>
9
9
  <span class="btn-label">{{ buttonLabel }}</span>
10
10
  </button>
11
11
  {{#ifCond hasDynamicSuggestions '||' hasDefaultSuggestions}}
12
- <div class="suggestions suggestions__group d-none default">
12
+
13
+ <div class="suggestions suggestions__group default">
13
14
  {{#if hasDefaultSuggestions}}
14
15
  <div class="default-suggestions">
15
16
  <div class="suggestions-category">
16
17
  <strong class="suggestions-category-label d-block">{{defaultSuggestions.popularServicesTitle}}</strong>
17
18
  <ul>
18
19
  {{#each defaultSuggestions.popularServices}}
19
- <li><a href="{{link}}">{{title}}</a></li>
20
+ <li><a tabindex="0" href="{{link}}">{{title}}</a></li>
20
21
  {{/each}}
21
22
  {{#if defaultSuggestions.popularServicesLink}}
22
- <li><a href="{{defaultSuggestions.popularServicesLink.href}}" class="view-more">{{#if defaultSuggestions.popularServicesLink.label}}{{defaultSuggestions.popularServicesLink.label}}{{else}}View More{{/if}}</a></li>
23
+ <li><a tabindex="0" href="{{defaultSuggestions.popularServicesLink.href}}" class="view-more">{{#if defaultSuggestions.popularServicesLink.label}}{{defaultSuggestions.popularServicesLink.label}}{{else}}View More{{/if}}</a></li>
23
24
  {{/if}}
24
25
  </ul>
25
26
  </div>
26
-
27
+ {{#if defaultSuggestions.categories}}
27
28
  <div class="suggestions-category">
28
29
  <strong class="suggestions-category-label d-block">{{defaultSuggestions.categoriesTitle}}</strong>
29
30
  <ul>
30
31
  {{#each defaultSuggestions.categories}}
31
- <li><a href="{{link}}">{{title}}</a></li>
32
+ <li><a tabindex="0"href="{{link}}">{{title}}</a></li>
32
33
  {{/each}}
33
34
  {{#if defaultSuggestions.categoriesLink}}
34
- <li><a href="{{defaultSuggestions.categoriesLink.href}}" class="view-more">{{#if defaultSuggestions.categoriesLink.label}}{{defaultSuggestions.categoriesLink.label}}{{else}}View More{{/if}}</a></li>
35
+ <li><a tabindex="0" href="{{defaultSuggestions.categoriesLink.href}}" class="view-more">{{#if defaultSuggestions.categoriesLink.label}}{{defaultSuggestions.categoriesLink.label}}{{else}}View More{{/if}}</a></li>
35
36
  {{/if}}
36
37
  </ul>
37
38
  </div>
39
+ {{/if}}
38
40
  </div>
39
41
  {{/if}}
40
42
  {{#if hasDynamicSuggestions}}