@qld-gov-au/qgds-bootstrap5 1.0.13 → 1.0.15
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.
- package/.storybook/main.js +1 -1
- package/.storybook/preview.js +8 -0
- package/README.md +96 -46
- package/dist/assets/css/qld.bootstrap.css +1 -1
- package/dist/assets/css/qld.bootstrap.css.map +3 -3
- package/dist/assets/js/handlebars.helpers.bundle.js +1 -1
- package/dist/assets/js/handlebars.helpers.bundle.js.map +3 -3
- package/dist/assets/js/handlebars.helpers.js +4 -8
- package/dist/assets/js/qld.bootstrap.min.js +9 -9
- package/dist/assets/js/qld.bootstrap.min.js.map +4 -4
- package/dist/components/bs5/breadcrumbs/breadcrumbs.hbs +1 -1
- package/dist/components/bs5/button/button.hbs +30 -9
- package/dist/components/bs5/footer/footer.hbs +98 -112
- package/dist/components/bs5/footer/footerForgov.hbs +86 -59
- package/dist/components/bs5/header/header.hbs +15 -17
- package/dist/components/bs5/navbar/navbar.hbs +1 -1
- package/dist/components/bs5/quickexit/quickexit.hbs +28 -20
- package/dist/components/bs5/searchInput/searchInput.hbs +9 -3
- package/dist/components/handlebars.helpers.js +4 -8
- package/dist/components/handlebars.init.bundle.js +1 -1
- package/dist/components/handlebars.init.bundle.js.map +3 -3
- package/dist/index.html +2 -1
- package/dist/sample-data/button/button.data.json +2 -1
- package/dist/sample-data/footer/footer.data.json +93 -45
- package/dist/sample-data/header/header.data.json +134 -75
- package/dist/sample-data/navbar/navbar.data.json +8 -8
- package/dist/sample-data/quickexit/quickexit.data.json +8 -1
- package/dist/sample-data/searchInput/searchInput.data.json +10 -1
- package/package.json +20 -19
- package/src/components/bs5/breadcrumbs/breadcrumb.functions.js +71 -32
- package/src/components/bs5/breadcrumbs/breadcrumbs.hbs +1 -1
- package/src/components/bs5/button/button.data.json +2 -1
- package/src/components/bs5/button/button.hbs +30 -9
- package/src/components/bs5/button/button.scss +87 -44
- package/src/components/bs5/button/button.stories.js +121 -27
- package/src/components/bs5/callout/callout.scss +1 -1
- package/src/components/bs5/footer/_colours.scss +74 -0
- package/src/components/bs5/footer/_measurements.scss +30 -0
- package/src/components/bs5/footer/footer.data.json +93 -45
- package/src/components/bs5/footer/footer.functions.js +36 -0
- package/src/components/bs5/footer/footer.hbs +98 -112
- package/src/components/bs5/footer/footer.scss +445 -199
- package/src/components/bs5/footer/footer.stories.js +17 -6
- package/src/components/bs5/footer/footerForgov.hbs +86 -59
- package/src/components/bs5/header/_colours.scss +0 -52
- package/src/components/bs5/header/header.data.json +134 -75
- package/src/components/bs5/header/header.functions.js +1 -180
- package/src/components/bs5/header/header.hbs +15 -17
- package/src/components/bs5/header/header.scss +7 -156
- package/src/components/bs5/header/header.stories.js +10 -50
- package/src/components/bs5/modal/modal.scss +54 -35
- package/src/components/bs5/modal/modal.stories.js +2 -2
- package/src/components/bs5/navbar/_colours.scss +46 -82
- package/src/components/bs5/navbar/navbar.data.json +8 -8
- package/src/components/bs5/navbar/navbar.hbs +1 -1
- package/src/components/bs5/navbar/navbar.scss +15 -6
- package/src/components/bs5/quickexit/_colours.scss +28 -0
- package/src/components/bs5/quickexit/quickexit.data.json +8 -1
- package/src/components/bs5/quickexit/quickexit.hbs +28 -20
- package/src/components/bs5/quickexit/quickexit.scss +236 -156
- package/src/components/bs5/quickexit/quickexit.stories.js +35 -13
- package/src/components/bs5/searchInput/_colours.scss +63 -0
- package/src/components/bs5/searchInput/search.functions.js +170 -0
- package/src/components/bs5/searchInput/searchInput.data.json +10 -1
- package/src/components/bs5/searchInput/searchInput.hbs +9 -3
- package/src/components/bs5/searchInput/searchInput.scss +122 -21
- package/src/components/bs5/searchInput/searchInput.stories.js +1 -1
- package/src/components/bs5/tag/tag.scss +4 -2
- package/src/js/handlebars.helpers.js +4 -8
- package/src/main.js +63 -39
- package/src/main.scss +6 -3
- package/src/scss/qld-print.scss +365 -0
- package/src/scss/qld-type.scss +94 -85
- package/src/scss/qld-variables.scss +87 -101
- package/src/templates/compiled/index.html +2 -1
- package/src/templates/index.html +31 -46
- package/src/components/common/header/Header.js +0 -11
- package/src/components/common/header/header.html +0 -259
- package/src/components/common/header/header.scss +0 -118
- /package/src/components/bs5/{header/_search.json → searchInput/search.json} +0 -0
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
import { createPopper } from '@popperjs/core';
|
|
2
|
+
import { defaultSuggestions } from './search.json';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Fetches data from the provided URL.
|
|
6
|
+
*
|
|
7
|
+
* @param {string} url - The URL to fetch data from.
|
|
8
|
+
* @param {string} type - The type of data to fetch (suggestions or services).
|
|
9
|
+
* @returns {Promise<Object>} - A promise that resolves to the fetched data.
|
|
10
|
+
*/
|
|
11
|
+
async function fetchData(url, type) {
|
|
12
|
+
try {
|
|
13
|
+
const response = await fetch(url);
|
|
14
|
+
if (!response.ok) {
|
|
15
|
+
throw new Error('Network response was not ok');
|
|
16
|
+
}
|
|
17
|
+
const data = await response.json();
|
|
18
|
+
return data;
|
|
19
|
+
} catch (error) {
|
|
20
|
+
console.error(`Error fetching ${type}:`, error);
|
|
21
|
+
return {};
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Sets the selected suggestion into the input field and submits the form.
|
|
27
|
+
*
|
|
28
|
+
* @param {string} value - The selected suggestion.
|
|
29
|
+
* @returns {void}
|
|
30
|
+
*/
|
|
31
|
+
export function selectSuggestion(value) {
|
|
32
|
+
const form = document.querySelector('.site-search');
|
|
33
|
+
const searchInput = form.querySelector('.qld-search-input input');
|
|
34
|
+
const suggestions = form.querySelector('.suggestions');
|
|
35
|
+
|
|
36
|
+
if (searchInput && suggestions && form) {
|
|
37
|
+
searchInput.value = value.trim();
|
|
38
|
+
suggestions.style.display = 'none';
|
|
39
|
+
|
|
40
|
+
// Retrieve additional params
|
|
41
|
+
const collection = 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';
|
|
45
|
+
|
|
46
|
+
// Form action
|
|
47
|
+
const actionUrl = form.getAttribute('action');
|
|
48
|
+
|
|
49
|
+
// Construct the URL with proper parameters
|
|
50
|
+
const params = new URLSearchParams({
|
|
51
|
+
query: value.trim(),
|
|
52
|
+
collection: collection,
|
|
53
|
+
profile: profile,
|
|
54
|
+
num_ranks: numRanks,
|
|
55
|
+
tiers: tiers
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
const searchUrl = `${actionUrl}?${params.toString()}`;
|
|
59
|
+
|
|
60
|
+
// Manually set the window location to the constructed URL
|
|
61
|
+
window.location.href = searchUrl;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Shows suggestions based on the user's input.
|
|
67
|
+
*
|
|
68
|
+
* @param {string} value - The current input value.
|
|
69
|
+
* @param {boolean} isDefault - Whether to show default suggestions or not.
|
|
70
|
+
* @returns {void}
|
|
71
|
+
**/
|
|
72
|
+
export async function showSuggestions(value = '', isDefault = false) {
|
|
73
|
+
const form = document.querySelector('.site-search');
|
|
74
|
+
const searchInput = form.querySelector('.qld-search-input input');
|
|
75
|
+
const suggestions = form.querySelector('.suggestions');
|
|
76
|
+
|
|
77
|
+
// Search input attributes
|
|
78
|
+
const collection = searchInput.getAttribute('data-collection') || 'qgov~sp-search';
|
|
79
|
+
const profile = searchInput.getAttribute('data-profile') || 'qld';
|
|
80
|
+
const suggestUrl = searchInput.getAttribute('data-suggestions') || '10';
|
|
81
|
+
const resultsUrl = searchInput.getAttribute('data-results-url') || 'off';
|
|
82
|
+
|
|
83
|
+
if (!suggestions || !searchInput) {
|
|
84
|
+
console.error("Required elements not found.");
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// Clear previous suggestions and services
|
|
89
|
+
suggestions.innerHTML = '';
|
|
90
|
+
const loadedSuggestions = defaultSuggestions;
|
|
91
|
+
|
|
92
|
+
if (isDefault) {
|
|
93
|
+
suggestions.innerHTML = `
|
|
94
|
+
<div class="suggestions-category mt-2">
|
|
95
|
+
<strong>Popular services</strong>
|
|
96
|
+
<ul class="mt-2">${loadedSuggestions.popular_services.slice(0, 4).map(item => `<li onclick="window.selectSuggestion('${item.title}')"><a href="${item.href}">${item.title}</a></li>`).join('')}</ul>
|
|
97
|
+
</div>
|
|
98
|
+
<hr>
|
|
99
|
+
<div class="suggestions-category mt-2">
|
|
100
|
+
<strong>Browse by category</strong>
|
|
101
|
+
<ul class="mt-2">${loadedSuggestions.categories.slice(0, 4).map(item => `<li onclick="window.selectSuggestion('${item.title}')"><a href="${item.href}">${item.title}</a></li>`).join('')}</ul>
|
|
102
|
+
</div>
|
|
103
|
+
<!--${loadedSuggestions.options.view_more ? `<div class="suggestions-category mt-4 mb-4"><a href="${loadedSuggestions.options.href}">${loadedSuggestions.options.label}</a></div>-->` : ''}
|
|
104
|
+
`;
|
|
105
|
+
suggestions.classList.add('show');
|
|
106
|
+
createPopper(searchInput, suggestions, {
|
|
107
|
+
placement: 'bottom-start',
|
|
108
|
+
});
|
|
109
|
+
suggestions.style.display = 'block';
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
if (value.length === 0) {
|
|
114
|
+
suggestions.innerHTML = '';
|
|
115
|
+
suggestions.style.display = 'none';
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
if (suggestUrl) {
|
|
120
|
+
|
|
121
|
+
const fetchedSuggestions = await fetchData(`${suggestUrl}?collection=${collection}&profile=${profile}&fmt=json&alpha=0.5&partial_query=${encodeURIComponent(value)}`, 'suggestions');
|
|
122
|
+
|
|
123
|
+
// Use the fetched suggestions to populate the suggestions dropdown
|
|
124
|
+
if (fetchedSuggestions.length > 0) {
|
|
125
|
+
suggestions.innerHTML = `
|
|
126
|
+
<div class="suggestions-category mt-2">
|
|
127
|
+
<strong>Suggestions</strong>
|
|
128
|
+
<ul class="mt-2">${fetchedSuggestions.slice(0, 4).map(item => {
|
|
129
|
+
const highlightedText = item.replace(new RegExp(`(${value})`, 'gi'), '<strong>$1</strong>');
|
|
130
|
+
return `<li onclick="window.selectSuggestion('${item}')"><a href="#">${highlightedText}</a></li>`;
|
|
131
|
+
}).join('')}</ul>
|
|
132
|
+
</div>
|
|
133
|
+
`;
|
|
134
|
+
suggestions.classList.add('show');
|
|
135
|
+
|
|
136
|
+
// Initialize Popper.js to manage the dropdown position
|
|
137
|
+
createPopper(searchInput, suggestions, {
|
|
138
|
+
placement: 'bottom-start',
|
|
139
|
+
});
|
|
140
|
+
suggestions.style.display = 'block';
|
|
141
|
+
} else {
|
|
142
|
+
suggestions.innerHTML = '';
|
|
143
|
+
suggestions.style.display = 'none';
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
if (resultsUrl) {
|
|
148
|
+
const fetchedServices = await fetchData(`${resultsUrl}?collection=${collection}&profile=${profile}&smeta_sfinder_sand=yes&query=${encodeURIComponent(value)}`, 'services');
|
|
149
|
+
|
|
150
|
+
// Use the fetched services to populate the services dropdown
|
|
151
|
+
if (fetchedServices.response.resultPacket && fetchedServices.response.resultPacket.results.length > 0) {
|
|
152
|
+
suggestions.innerHTML += `
|
|
153
|
+
<div class="suggestions-category feature pt-2">
|
|
154
|
+
<strong>Services</strong>
|
|
155
|
+
<ul class="mt-2">${fetchedServices.response.resultPacket.results.slice(0, 4).map(item => `<li class="pb-2" onclick="window.selectSuggestion('${item.title}')"><a href="${item.liveUrl}">${item.title}</a></li>`).join('')}</ul>
|
|
156
|
+
</div>
|
|
157
|
+
`;
|
|
158
|
+
suggestions.classList.add('show');
|
|
159
|
+
|
|
160
|
+
// Initialize Popper.js to manage the dropdown position
|
|
161
|
+
createPopper(searchInput, suggestions, {
|
|
162
|
+
placement: 'bottom-start',
|
|
163
|
+
});
|
|
164
|
+
suggestions.style.display = 'block';
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
// Attach the function to the window object to make it globally accessible
|
|
170
|
+
window.selectSuggestion = selectSuggestion;
|
|
@@ -7,5 +7,14 @@
|
|
|
7
7
|
"buttonID": "search-button",
|
|
8
8
|
"buttonType": "submit",
|
|
9
9
|
"buttonLabel": "Search",
|
|
10
|
-
"ariaLabel": "Search website"
|
|
10
|
+
"ariaLabel": "Search website",
|
|
11
|
+
"suggestions": true,
|
|
12
|
+
"tags": {
|
|
13
|
+
"collection": "qgov~sp-search",
|
|
14
|
+
"profile": "qld",
|
|
15
|
+
"numranks": "10",
|
|
16
|
+
"tiers": "off",
|
|
17
|
+
"suggestions": "https://discover.search.qld.gov.au/s/suggest.json",
|
|
18
|
+
"results-url": "https://discover.search.qld.gov.au/s/search.json"
|
|
19
|
+
}
|
|
11
20
|
}
|
|
@@ -2,15 +2,21 @@
|
|
|
2
2
|
QGDS Component: Search input
|
|
3
3
|
-->
|
|
4
4
|
<div class="container {{variantClass}}">
|
|
5
|
-
|
|
5
|
+
|
|
6
6
|
<div class="qld-search-input {{customClass}}">
|
|
7
7
|
|
|
8
|
-
<input id="{{ inputID }}" name=" {{ inputName }}" class="form-control" type="text" placeholder="{{placeholder}}"
|
|
9
|
-
|
|
8
|
+
<input id="{{ inputID }}" name=" {{ inputName }}" class="form-control" type="text" placeholder="{{placeholder}}"
|
|
9
|
+
aria-label="{{ ariaLabel }}" {{#each tags}} data-{{@key}}="{{this}}" {{/each}} />
|
|
10
|
+
|
|
10
11
|
<button class="btn btn-primary" type="{{ buttonType }}" id="{{ buttonID }}">
|
|
11
12
|
<span class="btn-icon"></span>
|
|
12
13
|
<span class="btn-label">{{ buttonLabel }}</span>
|
|
13
14
|
</button>
|
|
14
15
|
|
|
16
|
+
{{#if suggestions}}
|
|
17
|
+
<ul class="suggestions suggestions__group"></ul>
|
|
18
|
+
{{/if}}
|
|
19
|
+
|
|
15
20
|
</div>
|
|
21
|
+
|
|
16
22
|
</div>
|
|
@@ -1,5 +1,9 @@
|
|
|
1
|
-
|
|
1
|
+
// ----------------------------------------------------------------------------------------------------------------------
|
|
2
|
+
// Header - palettes and second hand variables:
|
|
3
|
+
@import './colours';
|
|
4
|
+
// ----------------------------------------------------------------------------------------------------------------------
|
|
2
5
|
|
|
6
|
+
.qld-search-input {
|
|
3
7
|
//Default state - unfocused, unhovered
|
|
4
8
|
--text-color: var(--qld-dark-grey-muted);
|
|
5
9
|
--placeholder-color: var(--qld-dark-grey-muted);
|
|
@@ -11,8 +15,101 @@
|
|
|
11
15
|
--icon: url("data:image/svg+xml,%3Csvg width='17' height='17' viewBox='0 0 17 17' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M11.5 6.5C11.5 4.71875 10.5312 3.09375 9 2.1875C7.4375 1.28125 5.53125 1.28125 4 2.1875C2.4375 3.09375 1.5 4.71875 1.5 6.5C1.5 8.3125 2.4375 9.9375 4 10.8438C5.53125 11.75 7.4375 11.75 9 10.8438C10.5312 9.9375 11.5 8.3125 11.5 6.5ZM10.5312 11.625C9.40625 12.5 8 13 6.5 13C2.90625 13 0 10.0938 0 6.5C0 2.9375 2.90625 0 6.5 0C10.0625 0 13 2.9375 13 6.5C13 8.03125 12.4688 9.4375 11.5938 10.5625L15.7812 14.7188C16.0625 15.0312 16.0625 15.5 15.7812 15.7812C15.4688 16.0938 15 16.0938 14.7188 15.7812L10.5312 11.625Z' fill='%23414141'/%3E%3C/svg%3E%0A");
|
|
12
16
|
|
|
13
17
|
position: relative;
|
|
14
|
-
min-width:
|
|
15
|
-
|
|
18
|
+
min-width: 22.5rem;
|
|
19
|
+
|
|
20
|
+
//Search dropdown
|
|
21
|
+
.suggestions {
|
|
22
|
+
position: absolute;
|
|
23
|
+
display: none;
|
|
24
|
+
left: 0;
|
|
25
|
+
top: 100%;
|
|
26
|
+
width: 100%;
|
|
27
|
+
z-index: 1;
|
|
28
|
+
border-radius: .5rem;
|
|
29
|
+
background: var(--#{$prefix}site-search-suggestions-bg);
|
|
30
|
+
box-shadow: var(--#{$prefix}site-search_boxshadow);
|
|
31
|
+
border-bottom: solid .25rem var(--#{$prefix}site-search-suggestions-hover__border_color);
|
|
32
|
+
|
|
33
|
+
.suggestions-category {
|
|
34
|
+
padding: 0 1rem;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
hr {
|
|
38
|
+
margin: 0;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// Featured search result styles
|
|
42
|
+
.feature {
|
|
43
|
+
background-color: var(--#{$prefix}site-search-suggestions-feature_bg);
|
|
44
|
+
|
|
45
|
+
strong {
|
|
46
|
+
color: var(--#{$prefix}site-search-suggestions-feature_text-color);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
ul {
|
|
50
|
+
li {
|
|
51
|
+
&:hover {
|
|
52
|
+
background-color: var(--#{$prefix}site-search-suggestions-feature_hover);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
a {
|
|
56
|
+
color: var(--#{$prefix}site-search-suggestions-feature_text-color);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// Show when active
|
|
63
|
+
&.show {
|
|
64
|
+
display: block;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
&__group {
|
|
68
|
+
padding: 0;
|
|
69
|
+
|
|
70
|
+
a,
|
|
71
|
+
strong {
|
|
72
|
+
color: var(--site-search-input-color);
|
|
73
|
+
font-weight: 400;
|
|
74
|
+
font-size: 1rem;
|
|
75
|
+
text-decoration: none;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
strong {
|
|
79
|
+
font-weight: 600;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
ul {
|
|
83
|
+
padding: 0;
|
|
84
|
+
|
|
85
|
+
li {
|
|
86
|
+
min-height: 3rem;
|
|
87
|
+
list-style: none;
|
|
88
|
+
cursor: pointer;
|
|
89
|
+
|
|
90
|
+
a {
|
|
91
|
+
vertical-align: middle;
|
|
92
|
+
vertical-align: -webkit-baseline-middle;
|
|
93
|
+
|
|
94
|
+
&:hover {
|
|
95
|
+
text-decoration: underline;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
&:hover {
|
|
100
|
+
background-color: var(--#{$prefix}site-search-suggestions-hover);
|
|
101
|
+
margin: 0 -1rem;
|
|
102
|
+
padding: 0 1rem;
|
|
103
|
+
|
|
104
|
+
a {
|
|
105
|
+
text-decoration: underline;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
16
113
|
|
|
17
114
|
&.full-width {
|
|
18
115
|
max-width: 100%;
|
|
@@ -27,20 +124,24 @@
|
|
|
27
124
|
left: calc(1rem - 2px);
|
|
28
125
|
width: 1.5rem;
|
|
29
126
|
height: 1.5rem;
|
|
30
|
-
background-color: var(--icon-color);
|
|
127
|
+
background-color: var(--icon-color);
|
|
31
128
|
mask: var(--icon) center center / 1.25rem no-repeat;
|
|
32
129
|
}
|
|
33
130
|
|
|
34
131
|
//Icon color is scoped against the parent container, not the input :(
|
|
35
|
-
&:has(.form-control:hover) {
|
|
36
|
-
|
|
132
|
+
&:has(.form-control:hover) {
|
|
133
|
+
--icon-color: var(--qld-dark-grey-muted);
|
|
134
|
+
}
|
|
37
135
|
|
|
38
|
-
.form-control {
|
|
136
|
+
&:has(.form-control:focus) {
|
|
137
|
+
--icon-color: var(--qld-text-grey);
|
|
138
|
+
}
|
|
39
139
|
|
|
140
|
+
.form-control {
|
|
40
141
|
padding: 0.75rem 1rem 0.75rem 3rem;
|
|
41
142
|
border-radius: 0.25rem;
|
|
42
143
|
border: 2px solid var(--border-color);
|
|
43
|
-
background: var(--background-color);
|
|
144
|
+
background: var(--background-color);
|
|
44
145
|
padding-right: 6rem;
|
|
45
146
|
color: var(--text-color);
|
|
46
147
|
|
|
@@ -64,19 +165,18 @@
|
|
|
64
165
|
--placeholder-color: var(--qld-text-grey);
|
|
65
166
|
--border-color: var(--qld-soft-grey);
|
|
66
167
|
--background-color: var(--qld-white);
|
|
67
|
-
|
|
168
|
+
|
|
68
169
|
outline: 3px solid var(--outline-color);
|
|
69
170
|
outline-offset: 2px;
|
|
70
171
|
}
|
|
71
172
|
|
|
72
|
-
+
|
|
173
|
+
+button {
|
|
73
174
|
position: absolute;
|
|
74
175
|
top: 0;
|
|
75
176
|
bottom: 0;
|
|
76
177
|
right: 0;
|
|
77
|
-
z-index: 10;
|
|
78
178
|
border-radius: 0 0.25rem 0.25rem 0;
|
|
79
|
-
|
|
179
|
+
|
|
80
180
|
// Adjust button padding to allow for input borders of 2px top and bottom
|
|
81
181
|
padding-top: calc(0.75rem - 2px);
|
|
82
182
|
padding-bottom: calc(0.75rem - 2px);
|
|
@@ -88,7 +188,7 @@
|
|
|
88
188
|
height: 1.5rem;
|
|
89
189
|
height: 1.5rem;
|
|
90
190
|
margin-right: 0;
|
|
91
|
-
background-color: var(--icon-color-on-btn);
|
|
191
|
+
background-color: var(--icon-color-on-btn);
|
|
92
192
|
mask: var(--icon) center center / 1.25rem no-repeat;
|
|
93
193
|
}
|
|
94
194
|
}
|
|
@@ -102,10 +202,11 @@
|
|
|
102
202
|
.form-control {
|
|
103
203
|
padding-left: 1rem;
|
|
104
204
|
|
|
105
|
-
+
|
|
205
|
+
+button {
|
|
106
206
|
span.btn-label {
|
|
107
207
|
display: none;
|
|
108
208
|
}
|
|
209
|
+
|
|
109
210
|
//Show the search icon (on button) on small screens
|
|
110
211
|
span.btn-icon {
|
|
111
212
|
display: block;
|
|
@@ -127,7 +228,7 @@
|
|
|
127
228
|
.qld-search-input {
|
|
128
229
|
|
|
129
230
|
// Rescope colours inside a dark container
|
|
130
|
-
|
|
231
|
+
|
|
131
232
|
// Default state - unfocused, unhovered
|
|
132
233
|
--icon-color: #DEEBF9;
|
|
133
234
|
--icon-color-on-btn: var(--qld-dark-action-text);
|
|
@@ -136,13 +237,13 @@
|
|
|
136
237
|
--placeholder-color: #DEEBF9;
|
|
137
238
|
--border-color: var(--qld-dark-alt-border);
|
|
138
239
|
--background-color: var(--qld-dark-background);
|
|
139
|
-
|
|
240
|
+
|
|
140
241
|
//Icon color is scoped against the parent container, not the input :(
|
|
141
|
-
&:has(.form-control:hover) {
|
|
242
|
+
&:has(.form-control:hover) {
|
|
142
243
|
--icon-color: var(--qld-white);
|
|
143
244
|
}
|
|
144
|
-
|
|
145
|
-
&:has(.form-control:focus) {
|
|
245
|
+
|
|
246
|
+
&:has(.form-control:focus) {
|
|
146
247
|
--icon-color: var(--qld-text-grey);
|
|
147
248
|
--text-color: var(--qld-text-grey);
|
|
148
249
|
}
|
|
@@ -163,7 +264,7 @@
|
|
|
163
264
|
--border-color: var(--qld-light-grey);
|
|
164
265
|
--background-color: var(--qld-white);
|
|
165
266
|
}
|
|
166
|
-
|
|
267
|
+
|
|
167
268
|
}
|
|
168
269
|
}
|
|
169
|
-
}
|
|
270
|
+
}
|
|
@@ -54,10 +54,12 @@
|
|
|
54
54
|
&:active,
|
|
55
55
|
&:focus {
|
|
56
56
|
background-color: $qld-textbox-border-color;
|
|
57
|
+
color: $qld-white;
|
|
58
|
+
text-decoration: underline;
|
|
59
|
+
text-underline-offset: var(--qld-link-underline-offset);
|
|
57
60
|
|
|
58
61
|
a {
|
|
59
|
-
color: white;
|
|
60
|
-
text-decoration: underline;
|
|
62
|
+
color: $qld-white;
|
|
61
63
|
}
|
|
62
64
|
}
|
|
63
65
|
}
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
/* global Handlebars */
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
|
-
* Registers Handlebars
|
|
4
|
+
* Registers Handlebars Helpers
|
|
5
5
|
* @param {module} Handlebars Templating engine
|
|
6
6
|
* @returns {void} Result of the helper operation
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
9
|
export default function handlebarsHelpers(Handlebars) {
|
|
10
|
-
|
|
10
|
+
// Contains -
|
|
11
11
|
Handlebars.registerHelper("contains", function (needle, haystack, options) {
|
|
12
12
|
needle = Handlebars.escapeExpression(needle);
|
|
13
13
|
haystack = Handlebars.escapeExpression(haystack);
|
|
@@ -15,6 +15,7 @@ export default function handlebarsHelpers(Handlebars) {
|
|
|
15
15
|
? options.fn(this)
|
|
16
16
|
: options.inverse(this);
|
|
17
17
|
});
|
|
18
|
+
// ifCond - checks conditions
|
|
18
19
|
Handlebars.registerHelper("ifCond", function (v1, operator, v2, options) {
|
|
19
20
|
switch (operator) {
|
|
20
21
|
case "==":
|
|
@@ -47,12 +48,7 @@ export default function handlebarsHelpers(Handlebars) {
|
|
|
47
48
|
return options.inverse(this);
|
|
48
49
|
}
|
|
49
50
|
});
|
|
50
|
-
|
|
51
|
-
return (index % 3 === 0); // This will check if the index of the current item in the iteration is a multiple of three (nav dropdown)
|
|
52
|
-
});
|
|
53
|
-
Handlebars.registerHelper('isEndOfRow', function(index) {
|
|
54
|
-
return ((index + 1) % 3 === 0); // Since index is zero-based, add 1 to check if it's the end of a row.
|
|
55
|
-
});
|
|
51
|
+
// Checks is expected type
|
|
56
52
|
Handlebars.registerHelper('isType', function (value, expected, options) {
|
|
57
53
|
if (value === expected) {
|
|
58
54
|
return options.fn(this); // Render the block if condition is true
|
package/src/main.js
CHANGED
|
@@ -1,58 +1,90 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
accordionToggleAll,
|
|
3
|
+
accordionToggleAllButtonState,
|
|
4
|
+
accordionHashLinks,
|
|
5
|
+
} from "./components/bs5/accordion/accordion.functions";
|
|
2
6
|
import { videoEmbedPlay, videoTranscriptTitle } from "./components/bs5/video/video.functions";
|
|
3
|
-
import { initializeNavbar } from
|
|
4
|
-
import {
|
|
5
|
-
import { positionQuickExit, initQuickexit } from
|
|
6
|
-
import {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
window.addEventListener(
|
|
11
|
-
window.addEventListener(
|
|
7
|
+
import { initializeNavbar } from "./components/bs5/navbar/navbar.functions";
|
|
8
|
+
import { initBreadcrumb } from "./components/bs5/breadcrumbs/breadcrumb.functions";
|
|
9
|
+
import { positionQuickExit, initQuickexit } from "./components/bs5/quickexit/quickexit.functions";
|
|
10
|
+
import { displayFeedbackForm } from "./components/bs5/footer/footer.functions";
|
|
11
|
+
import { toggleSearch } from "./components/bs5/header/header.functions";
|
|
12
|
+
import { showSuggestions } from "./components/bs5/searchInput/search.functions";
|
|
13
|
+
|
|
14
|
+
window.addEventListener("scroll", positionQuickExit, true);
|
|
15
|
+
window.addEventListener("resize", positionQuickExit, true);
|
|
16
|
+
window.addEventListener("click", initQuickexit, true);
|
|
17
|
+
window.addEventListener("keydown", initQuickexit, true);
|
|
12
18
|
|
|
13
19
|
window.addEventListener("DOMContentLoaded", () => {
|
|
14
20
|
(() => {
|
|
21
|
+
// Footer FormIO Action
|
|
22
|
+
// Note: This is added here, as there is an issue with breadcrumbShorten() function.
|
|
23
|
+
// Will move this once that issue is fixed.
|
|
24
|
+
const footerFormio = document.getElementById("qg-feedback-toggle");
|
|
25
|
+
if (footerFormio) {
|
|
26
|
+
displayFeedbackForm();
|
|
27
|
+
}
|
|
15
28
|
|
|
16
29
|
//Header search
|
|
17
|
-
let headerSearchButton = document.querySelector(
|
|
18
|
-
|
|
19
|
-
|
|
30
|
+
let headerSearchButton = document.querySelector(".qld__main-nav__toggle-search");
|
|
31
|
+
|
|
32
|
+
if (headerSearchButton) {
|
|
33
|
+
document.querySelector(".qld__main-nav__toggle-search").addEventListener("click", toggleSearch);
|
|
20
34
|
}
|
|
21
|
-
|
|
35
|
+
|
|
36
|
+
const form = document.querySelector(".site-search");
|
|
37
|
+
const searchInput = form.querySelector(".qld-search-input input");
|
|
38
|
+
|
|
22
39
|
if (searchInput) {
|
|
23
40
|
let timeout;
|
|
24
41
|
|
|
25
|
-
searchInput.addEventListener(
|
|
42
|
+
searchInput.addEventListener("keyup", function () {
|
|
26
43
|
clearTimeout(timeout);
|
|
27
44
|
timeout = setTimeout(() => {
|
|
28
45
|
showSuggestions(this.value);
|
|
29
46
|
}, 300);
|
|
30
47
|
});
|
|
31
48
|
|
|
32
|
-
searchInput.addEventListener(
|
|
33
|
-
showSuggestions(
|
|
49
|
+
searchInput.addEventListener("focus", function () {
|
|
50
|
+
showSuggestions("", true);
|
|
34
51
|
});
|
|
35
52
|
|
|
36
|
-
searchInput.addEventListener(
|
|
37
|
-
if (this.value ===
|
|
38
|
-
showSuggestions(
|
|
53
|
+
searchInput.addEventListener("click", function () {
|
|
54
|
+
if (this.value === "") {
|
|
55
|
+
showSuggestions("", true);
|
|
39
56
|
}
|
|
40
57
|
});
|
|
58
|
+
|
|
41
59
|
// Close suggestions when clicking outside
|
|
42
|
-
document.addEventListener(
|
|
43
|
-
if (!searchInput.contains(event.target) && !document.
|
|
44
|
-
document.
|
|
60
|
+
document.addEventListener("click", function (event) {
|
|
61
|
+
if (!searchInput.contains(event.target) && !document.querySelector(".suggestions").contains(event.target)) {
|
|
62
|
+
document.querySelector(".suggestions").style.display = "none";
|
|
45
63
|
}
|
|
46
64
|
});
|
|
47
65
|
}
|
|
48
66
|
|
|
67
|
+
//Header
|
|
68
|
+
// Get the <header> element
|
|
69
|
+
var header = document.querySelector("header");
|
|
70
|
+
if (header) {
|
|
71
|
+
// Get the current page URL without query string parameters
|
|
72
|
+
var url = window.location.origin + window.location.pathname;
|
|
73
|
+
// Set the data-page-url attribute on the <header> element
|
|
74
|
+
header.setAttribute("data-page-url", url);
|
|
75
|
+
}
|
|
76
|
+
|
|
49
77
|
// Navbar
|
|
50
78
|
initializeNavbar();
|
|
51
79
|
|
|
52
80
|
// Breadcrumb
|
|
53
|
-
|
|
81
|
+
initBreadcrumb();
|
|
54
82
|
|
|
55
83
|
// Quick exit
|
|
84
|
+
window.addEventListener("scroll", positionQuickExit, true);
|
|
85
|
+
window.addEventListener("resize", positionQuickExit, true);
|
|
86
|
+
window.addEventListener("click", initQuickexit, true);
|
|
87
|
+
window.addEventListener("keydown", initQuickexit, true);
|
|
56
88
|
initQuickexit();
|
|
57
89
|
positionQuickExit();
|
|
58
90
|
|
|
@@ -62,9 +94,7 @@ window.addEventListener("DOMContentLoaded", () => {
|
|
|
62
94
|
accordionToggleButton.forEach(function (toggleButton) {
|
|
63
95
|
toggleButton.addEventListener("click", accordionToggleAll);
|
|
64
96
|
|
|
65
|
-
let accordionButtons = toggleButton
|
|
66
|
-
.closest(".accordion-group")
|
|
67
|
-
.querySelectorAll(".accordion-button");
|
|
97
|
+
let accordionButtons = toggleButton.closest(".accordion-group").querySelectorAll(".accordion-button");
|
|
68
98
|
|
|
69
99
|
accordionButtons.forEach(function (button) {
|
|
70
100
|
button.addEventListener("click", accordionToggleAllButtonState);
|
|
@@ -79,23 +109,17 @@ window.addEventListener("DOMContentLoaded", () => {
|
|
|
79
109
|
link.addEventListener("click", accordionHashLinks);
|
|
80
110
|
});
|
|
81
111
|
|
|
82
|
-
|
|
83
112
|
// Video
|
|
84
|
-
let videoThumbnails = document.querySelectorAll(
|
|
113
|
+
let videoThumbnails = document.querySelectorAll(".video-thumbnail");
|
|
85
114
|
|
|
86
115
|
videoThumbnails.forEach(function (thumbnail) {
|
|
87
|
-
thumbnail.addEventListener("click", videoEmbedPlay)
|
|
88
|
-
})
|
|
116
|
+
thumbnail.addEventListener("click", videoEmbedPlay);
|
|
117
|
+
});
|
|
89
118
|
|
|
90
|
-
let videoTranscripts = document.querySelectorAll(
|
|
119
|
+
let videoTranscripts = document.querySelectorAll(".video .accordion .accordion-button");
|
|
91
120
|
|
|
92
121
|
videoTranscripts.forEach(function (transcript) {
|
|
93
|
-
transcript.addEventListener("click", videoTranscriptTitle)
|
|
94
|
-
})
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
//Modal
|
|
98
|
-
|
|
99
|
-
|
|
122
|
+
transcript.addEventListener("click", videoTranscriptTitle);
|
|
123
|
+
});
|
|
100
124
|
})();
|
|
101
125
|
});
|
package/src/main.scss
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
// Guidelines for this setup: https://getbootstrap.com/docs/5.3/customize/sass/
|
|
6
6
|
|
|
7
7
|
// External fonts
|
|
8
|
-
@import url('https://fonts.googleapis.com/css2?family=Fira+Sans:wght@400;700&family=Noto+Sans:wght@400;600&display=swap');
|
|
8
|
+
@import url('https://fonts.googleapis.com/css2?family=Fira+Sans:wght@400;700&family=Noto+Sans:wght@400;600;900&display=swap');
|
|
9
9
|
$font-family-sans-serif: "Noto Sans", system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", "Noto Sans", "Liberation Sans", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji" !default;
|
|
10
10
|
$font-family-sitename: "Fira Sans";
|
|
11
11
|
|
|
@@ -113,5 +113,8 @@ $enable-dark-mode: true;
|
|
|
113
113
|
// Common Layout Blocks, under review
|
|
114
114
|
@import "./components/common/layout/content.scss";
|
|
115
115
|
|
|
116
|
-
// Themes
|
|
117
|
-
@import "./scss/qld-theme.scss";
|
|
116
|
+
// Themes
|
|
117
|
+
@import "./scss/qld-theme.scss";
|
|
118
|
+
|
|
119
|
+
// Print
|
|
120
|
+
@import "./scss/qld-print.scss";
|