weg-shared-layout 0.0.23 → 0.0.25
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/LICENSE +21 -21
- package/dist/cjs/loader.cjs.js +1 -1
- package/dist/cjs/weg-footer_2.cjs.entry.js +307 -219
- package/dist/cjs/weg-shared-layout.cjs.js +1 -1
- package/dist/collection/collection-manifest.json +0 -1
- package/dist/collection/components/weg-footer/icons/instagram.svg +5 -5
- package/dist/collection/components/weg-footer/icons/linkedin.svg +3 -3
- package/dist/collection/components/weg-footer/icons/tiktok.svg +3 -3
- package/dist/collection/components/weg-footer/icons/youtube.svg +4 -4
- package/dist/collection/components/weg-footer/weg-footer.css +270 -201
- package/dist/collection/components/weg-footer/weg-footer.js +22 -26
- package/dist/collection/components/weg-header/weg-header.css +474 -365
- package/dist/collection/components/weg-header/weg-header.js +226 -166
- package/dist/collection/constants/breakpoints.js +6 -0
- package/dist/collection/styles/shared.css +72 -78
- package/dist/collection/utils/layout.js +57 -9
- package/dist/components/p-BnMIy-A5.js +1 -0
- package/dist/components/weg-footer.js +1 -1
- package/dist/components/weg-header.js +1 -1
- package/dist/esm/loader.js +1 -1
- package/dist/esm/weg-footer_2.entry.js +307 -219
- package/dist/esm/weg-shared-layout.js +1 -1
- package/dist/types/components/weg-footer/weg-footer.d.ts +2 -2
- package/dist/types/components/weg-header/weg-header.d.ts +32 -16
- package/dist/types/components.d.ts +6 -48
- package/dist/types/constants/breakpoints.d.ts +6 -0
- package/dist/types/types/layout-data.d.ts +13 -27
- package/dist/types/utils/layout.d.ts +9 -1
- package/dist/weg-shared-layout/p-d74a58cf.entry.js +1 -0
- package/dist/weg-shared-layout/weg-shared-layout.esm.js +1 -1
- package/docs/angular-integration-guide.md +1004 -0
- package/docs/angular.md +229 -138
- package/docs/nextjs.md +306 -305
- package/docs/publishing.md +48 -48
- package/docs/react.md +261 -261
- package/docs/vanilla.md +138 -140
- package/package.json +12 -8
- package/readme.md +82 -107
- package/src/assets/dummy-data.json +137 -63
- package/src/constants/breakpoints.ts +7 -0
- package/dist/cjs/my-component.cjs.entry.js +0 -33
- package/dist/collection/components/my-component/my-component.css +0 -3
- package/dist/collection/components/my-component/my-component.js +0 -95
- package/dist/collection/components/weg-header/signed-in-layout.js +0 -13
- package/dist/collection/constants/weg-urls.js +0 -18
- package/dist/components/my-component.d.ts +0 -11
- package/dist/components/my-component.js +0 -1
- package/dist/components/p-DbIEJ3IT.js +0 -1
- package/dist/esm/my-component.entry.js +0 -31
- package/dist/types/components/my-component/my-component.d.ts +0 -16
- package/dist/types/components/weg-header/signed-in-layout.d.ts +0 -18
- package/dist/types/constants/weg-urls.d.ts +0 -18
- package/dist/weg-shared-layout/p-80fa529c.entry.js +0 -1
- package/dist/weg-shared-layout/p-d61033bd.entry.js +0 -1
- package/src/constants/weg-urls.ts +0 -23
- /package/dist/types/Users/{tan/Documents/code → rakin/Documents/WEG/repos}/weg-shared-layout/.stencil/test-utils/axe.d.ts +0 -0
- /package/dist/types/Users/{tan/Documents/code → rakin/Documents/WEG/repos}/weg-shared-layout/.stencil/test-utils/viewport.d.ts +0 -0
|
@@ -1,64 +1,54 @@
|
|
|
1
1
|
import { h } from "@stencil/core";
|
|
2
|
-
import {
|
|
2
|
+
import { isMenuGroup, isNonEmptyString, normalizeHeaderMenu, parseJsonProp, } from "../../utils/layout";
|
|
3
|
+
import { WEG_HOVER_CAPABLE_MEDIA_QUERY, WEG_MD_MEDIA_QUERY } from "../../constants/breakpoints";
|
|
3
4
|
import { LOGO_SRC } from "./logo-data";
|
|
4
|
-
|
|
5
|
+
const WEG_HOME = 'https://www.warwickemploymentgroup.com';
|
|
6
|
+
const ACCOUNT_HOME = 'https://account.warwickemploymentgroup.com';
|
|
7
|
+
const DEFAULT_LOGO_HREF = `${WEG_HOME}/`;
|
|
8
|
+
const ACCOUNT_LOGIN_HREF = `${ACCOUNT_HOME}/account/login`;
|
|
9
|
+
const ACCOUNT_MANAGE_HREF = `${ACCOUNT_HOME}/account/manage`;
|
|
10
|
+
const SIGNED_IN_MENU = [
|
|
11
|
+
{ label: 'Find a job', href: `${WEG_HOME}/find-a-job` },
|
|
12
|
+
{ label: 'Dashboard', href: `${ACCOUNT_HOME}/dashboard` },
|
|
13
|
+
{ label: 'Manage Account', href: `${ACCOUNT_HOME}/account/manage` },
|
|
14
|
+
{ label: 'Sign out', href: `${ACCOUNT_HOME}/account/login` },
|
|
15
|
+
];
|
|
5
16
|
const EMPTY_HEADER = {
|
|
6
|
-
|
|
7
|
-
dropdowns: [],
|
|
8
|
-
links: [],
|
|
9
|
-
signIn: null,
|
|
10
|
-
signOut: null,
|
|
17
|
+
menu: [],
|
|
11
18
|
};
|
|
12
|
-
function
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
const label = item.label;
|
|
20
|
-
const items = normalizeLinks(item.items);
|
|
21
|
-
if (!isNonEmptyString(label))
|
|
22
|
-
continue;
|
|
23
|
-
if (items.length === 0)
|
|
24
|
-
continue;
|
|
25
|
-
result.push({ label: label.trim(), items });
|
|
26
|
-
}
|
|
27
|
-
return result;
|
|
19
|
+
function isSignInLink(link) {
|
|
20
|
+
const label = link.label.trim().toLowerCase();
|
|
21
|
+
if (label === 'sign out')
|
|
22
|
+
return false;
|
|
23
|
+
if (label === 'sign in')
|
|
24
|
+
return true;
|
|
25
|
+
return link.href === ACCOUNT_LOGIN_HREF;
|
|
28
26
|
}
|
|
29
|
-
function
|
|
30
|
-
|
|
31
|
-
return null;
|
|
32
|
-
const label = input.label;
|
|
33
|
-
const href = input.href;
|
|
34
|
-
if (!isNonEmptyString(label))
|
|
35
|
-
return null;
|
|
36
|
-
if (!isNonEmptyString(href))
|
|
37
|
-
return null;
|
|
38
|
-
return { label: label.trim(), href: href.trim() };
|
|
27
|
+
function isSignOutLink(link) {
|
|
28
|
+
return link.label.trim().toLowerCase() === 'sign out';
|
|
39
29
|
}
|
|
40
|
-
function
|
|
41
|
-
if (
|
|
42
|
-
return
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
30
|
+
function isManageAccountLink(link) {
|
|
31
|
+
if (link.label.trim().toLowerCase() === 'manage account')
|
|
32
|
+
return true;
|
|
33
|
+
return link.href === ACCOUNT_MANAGE_HREF;
|
|
34
|
+
}
|
|
35
|
+
function isFindJobLink(link) {
|
|
36
|
+
if (link.label.trim().toLowerCase() === 'find a job')
|
|
37
|
+
return true;
|
|
38
|
+
return link.href === `${WEG_HOME}/find-a-job`;
|
|
39
|
+
}
|
|
40
|
+
function isDashboardLink(link) {
|
|
41
|
+
if (link.label.trim().toLowerCase() === 'dashboard')
|
|
42
|
+
return true;
|
|
43
|
+
return link.href === `${ACCOUNT_HOME}/dashboard`;
|
|
51
44
|
}
|
|
52
45
|
function normalizeHeaderData(input) {
|
|
53
46
|
const root = (input && typeof input === 'object' ? input : {});
|
|
54
47
|
const header = root.header && typeof root.header === 'object' ? root.header : {};
|
|
55
|
-
const
|
|
48
|
+
const logoSrc = isNonEmptyString(header.logoSrc) ? header.logoSrc.trim() : undefined;
|
|
56
49
|
return {
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
links: normalizeLinks(header.links),
|
|
60
|
-
signIn: normalizeSignIn(header.signIn),
|
|
61
|
-
signOut: normalizeSignOut(header.signOut),
|
|
50
|
+
logoSrc,
|
|
51
|
+
menu: normalizeHeaderMenu(header.menu),
|
|
62
52
|
};
|
|
63
53
|
}
|
|
64
54
|
function SignInIcon() {
|
|
@@ -67,6 +57,12 @@ function SignInIcon() {
|
|
|
67
57
|
function SignOutIcon() {
|
|
68
58
|
return (h("svg", { viewBox: "0 0 26 24", width: "26", height: "24", "aria-hidden": "true", focusable: "false", fill: "none" }, h("path", { d: "M19.6667 6.33333L25 11.6667L19.6667 17M25 11.6667H6.33333M14.3333 17V18.3333C14.3333 19.3942 13.9119 20.4116 13.1618 21.1618C12.4116 21.9119 11.3942 22.3333 10.3333 22.3333H5C3.93913 22.3333 2.92172 21.9119 2.17157 21.1618C1.42143 20.4116 1 19.3942 1 18.3333V5C1 3.93913 1.42143 2.92172 2.17157 2.17157C2.92172 1.42143 3.93913 1 5 1H10.3333C11.3942 1 12.4116 1.42143 13.1618 2.17157C13.9119 2.92172 14.3333 3.93913 14.3333 5V6.33333", stroke: "currentColor", "stroke-width": "2", "stroke-linecap": "round", "stroke-linejoin": "round" })));
|
|
69
59
|
}
|
|
60
|
+
function FindJobIcon() {
|
|
61
|
+
return (h("svg", { viewBox: "0 0 24 24", width: "20", height: "20", "aria-hidden": "true", focusable: "false", fill: "none" }, h("path", { d: "M16 20V4a2 2 0 0 0-2-2h-4a2 2 0 0 0-2 2v16", stroke: "currentColor", "stroke-width": "2", "stroke-linecap": "round", "stroke-linejoin": "round" }), h("rect", { x: "2", y: "6", width: "20", height: "14", rx: "2", stroke: "currentColor", "stroke-width": "2", "stroke-linecap": "round", "stroke-linejoin": "round" })));
|
|
62
|
+
}
|
|
63
|
+
function DashboardIcon() {
|
|
64
|
+
return (h("svg", { viewBox: "0 0 24 24", width: "20", height: "20", "aria-hidden": "true", focusable: "false", fill: "none" }, h("rect", { x: "3", y: "3", width: "7", height: "9", rx: "1", stroke: "currentColor", "stroke-width": "2", "stroke-linecap": "round", "stroke-linejoin": "round" }), h("rect", { x: "14", y: "3", width: "7", height: "5", rx: "1", stroke: "currentColor", "stroke-width": "2", "stroke-linecap": "round", "stroke-linejoin": "round" }), h("rect", { x: "14", y: "12", width: "7", height: "9", rx: "1", stroke: "currentColor", "stroke-width": "2", "stroke-linecap": "round", "stroke-linejoin": "round" }), h("rect", { x: "3", y: "16", width: "7", height: "5", rx: "1", stroke: "currentColor", "stroke-width": "2", "stroke-linecap": "round", "stroke-linejoin": "round" })));
|
|
65
|
+
}
|
|
70
66
|
function HamburgerIcon() {
|
|
71
67
|
return (h("svg", { viewBox: "0 0 24 24", width: "28", height: "28", "aria-hidden": "true", focusable: "false", fill: "none" }, h("path", { d: "M4 7h16M4 12h16M4 17h16", stroke: "currentColor", "stroke-width": "2", "stroke-linecap": "round" })));
|
|
72
68
|
}
|
|
@@ -76,8 +72,8 @@ function CloseIcon() {
|
|
|
76
72
|
function ToggleIcon({ expanded }) {
|
|
77
73
|
return (h("span", { class: "toggle-icon", "aria-hidden": "true" }, expanded ? (h("svg", { viewBox: "0 0 24 24", width: "14", height: "14", fill: "none" }, h("path", { d: "M6 12h12", stroke: "currentColor", "stroke-width": "2.5", "stroke-linecap": "round" }))) : (h("svg", { viewBox: "0 0 24 24", width: "14", height: "14", fill: "none" }, h("path", { d: "M12 6v12M6 12h12", stroke: "currentColor", "stroke-width": "2.5", "stroke-linecap": "round" })))));
|
|
78
74
|
}
|
|
79
|
-
function Logo({ href }) {
|
|
80
|
-
return (h("a", { class: "logo-link", href: href, "aria-label": "Home" }, h("img", { class: "logo", src:
|
|
75
|
+
function Logo({ href, src }) {
|
|
76
|
+
return (h("a", { class: "logo-link", href: href, "aria-label": "Home" }, h("img", { class: "logo", src: src, alt: "WEG", width: "225", height: "83" })));
|
|
81
77
|
}
|
|
82
78
|
export class WegHeader {
|
|
83
79
|
/**
|
|
@@ -87,19 +83,18 @@ export class WegHeader {
|
|
|
87
83
|
* ```json
|
|
88
84
|
* {
|
|
89
85
|
* "header": {
|
|
90
|
-
* "
|
|
91
|
-
*
|
|
92
|
-
*
|
|
93
|
-
*
|
|
94
|
-
*
|
|
86
|
+
* "menu": [
|
|
87
|
+
* { "label": "Find a job", "items": [{ "label": "Graduates", "href": "..." }] },
|
|
88
|
+
* { "label": "Career advice", "href": "/career-advice" },
|
|
89
|
+
* { "label": "Sign in", "href": "/account/login" }
|
|
90
|
+
* ]
|
|
95
91
|
* }
|
|
96
92
|
* }
|
|
97
93
|
* ```
|
|
98
94
|
*/
|
|
99
95
|
layout;
|
|
100
96
|
/**
|
|
101
|
-
* When true, the header
|
|
102
|
-
* Manage Account, Sign out) instead of the CMS layout.
|
|
97
|
+
* When true, the header uses the built-in signed-in menu instead of the CMS layout.
|
|
103
98
|
*/
|
|
104
99
|
signedIn = false;
|
|
105
100
|
/**
|
|
@@ -115,10 +110,13 @@ export class WegHeader {
|
|
|
115
110
|
resolved = EMPTY_HEADER;
|
|
116
111
|
menuOpen = false;
|
|
117
112
|
openDropdown = null;
|
|
118
|
-
expandedSection = null;
|
|
119
113
|
boundHandleDocumentClick = this.handleDocumentClick.bind(this);
|
|
114
|
+
boundHandleViewportChange = this.handleViewportChange.bind(this);
|
|
115
|
+
boundHandleHoverCapabilityChange = this.handleHoverCapabilityChange.bind(this);
|
|
120
116
|
hoverCloseTimer = null;
|
|
121
117
|
hoverOpenEnabled = false;
|
|
118
|
+
desktopMediaQuery;
|
|
119
|
+
hoverCapableMediaQuery;
|
|
122
120
|
resolve() {
|
|
123
121
|
if (this.layout === undefined || this.layout === null) {
|
|
124
122
|
this.resolved = EMPTY_HEADER;
|
|
@@ -128,15 +126,46 @@ export class WegHeader {
|
|
|
128
126
|
}
|
|
129
127
|
componentWillLoad() {
|
|
130
128
|
this.resolve();
|
|
131
|
-
this.
|
|
129
|
+
this.hoverCapableMediaQuery = window.matchMedia(WEG_HOVER_CAPABLE_MEDIA_QUERY);
|
|
130
|
+
this.hoverCapableMediaQuery.addEventListener('change', this.boundHandleHoverCapabilityChange);
|
|
131
|
+
this.desktopMediaQuery = window.matchMedia(WEG_MD_MEDIA_QUERY);
|
|
132
|
+
this.desktopMediaQuery.addEventListener('change', this.boundHandleViewportChange);
|
|
133
|
+
this.updateHoverDropdownEnabled();
|
|
134
|
+
this.handleViewportChange();
|
|
132
135
|
}
|
|
133
136
|
connectedCallback() {
|
|
134
137
|
document.addEventListener('click', this.boundHandleDocumentClick);
|
|
135
138
|
}
|
|
136
139
|
disconnectedCallback() {
|
|
137
140
|
document.removeEventListener('click', this.boundHandleDocumentClick);
|
|
141
|
+
this.desktopMediaQuery?.removeEventListener('change', this.boundHandleViewportChange);
|
|
142
|
+
this.hoverCapableMediaQuery?.removeEventListener('change', this.boundHandleHoverCapabilityChange);
|
|
138
143
|
this.cancelScheduledDropdownClose();
|
|
139
144
|
}
|
|
145
|
+
/**
|
|
146
|
+
* Desktop dropdowns open on hover when viewport is md+ and the device reports hover support.
|
|
147
|
+
* Uses (hover: hover) only — not (pointer: fine), which breaks in DevTools and hybrid devices.
|
|
148
|
+
*/
|
|
149
|
+
updateHoverDropdownEnabled() {
|
|
150
|
+
const enabled = Boolean(this.desktopMediaQuery?.matches && this.hoverCapableMediaQuery?.matches);
|
|
151
|
+
if (this.hoverOpenEnabled && !enabled) {
|
|
152
|
+
this.cancelScheduledDropdownClose();
|
|
153
|
+
this.closeDropdown();
|
|
154
|
+
}
|
|
155
|
+
this.hoverOpenEnabled = enabled;
|
|
156
|
+
}
|
|
157
|
+
handleHoverCapabilityChange() {
|
|
158
|
+
this.updateHoverDropdownEnabled();
|
|
159
|
+
}
|
|
160
|
+
handleViewportChange() {
|
|
161
|
+
if (this.desktopMediaQuery?.matches) {
|
|
162
|
+
this.closeMenu();
|
|
163
|
+
}
|
|
164
|
+
this.updateHoverDropdownEnabled();
|
|
165
|
+
}
|
|
166
|
+
isMobileMenuActive() {
|
|
167
|
+
return this.menuOpen && !this.desktopMediaQuery?.matches;
|
|
168
|
+
}
|
|
140
169
|
watchLayout() {
|
|
141
170
|
this.resolve();
|
|
142
171
|
}
|
|
@@ -188,18 +217,40 @@ export class WegHeader {
|
|
|
188
217
|
return;
|
|
189
218
|
this.openDropdownMenu(label);
|
|
190
219
|
}
|
|
191
|
-
handleDropdownPointerLeave() {
|
|
220
|
+
handleDropdownPointerLeave(event) {
|
|
192
221
|
if (!this.hoverOpenEnabled)
|
|
193
222
|
return;
|
|
223
|
+
const related = event.relatedTarget;
|
|
224
|
+
const container = event.currentTarget;
|
|
225
|
+
if (related && container.contains(related))
|
|
226
|
+
return;
|
|
194
227
|
this.scheduleDropdownClose();
|
|
195
228
|
}
|
|
196
|
-
|
|
229
|
+
handleDropdownPanelPointerEnter(label) {
|
|
230
|
+
if (!this.hoverOpenEnabled)
|
|
231
|
+
return;
|
|
232
|
+
this.cancelScheduledDropdownClose();
|
|
197
233
|
this.openDropdownMenu(label);
|
|
198
234
|
}
|
|
235
|
+
handleDropdownPanelPointerLeave(event) {
|
|
236
|
+
if (!this.hoverOpenEnabled)
|
|
237
|
+
return;
|
|
238
|
+
const related = event.relatedTarget;
|
|
239
|
+
const panel = event.currentTarget;
|
|
240
|
+
const container = panel.closest('.nav-dropdown');
|
|
241
|
+
if (related && container?.contains(related))
|
|
242
|
+
return;
|
|
243
|
+
this.scheduleDropdownClose();
|
|
244
|
+
}
|
|
245
|
+
handleDropdownTriggerClick(event, label) {
|
|
246
|
+
event.stopPropagation();
|
|
247
|
+
this.cancelScheduledDropdownClose();
|
|
248
|
+
this.toggleDropdown(label);
|
|
249
|
+
}
|
|
199
250
|
handleDropdownFocusOut(event, label) {
|
|
200
251
|
const related = event.relatedTarget;
|
|
201
|
-
const
|
|
202
|
-
if (related &&
|
|
252
|
+
const container = event.currentTarget;
|
|
253
|
+
if (related && container.contains(related))
|
|
203
254
|
return;
|
|
204
255
|
if (this.openDropdown === label) {
|
|
205
256
|
this.closeDropdown();
|
|
@@ -214,63 +265,74 @@ export class WegHeader {
|
|
|
214
265
|
}
|
|
215
266
|
focusFirstDropdownLink(itemEl) {
|
|
216
267
|
setTimeout(() => {
|
|
217
|
-
const firstLink = itemEl.querySelector('.
|
|
268
|
+
const firstLink = itemEl.querySelector('.nav-dropdown__link');
|
|
218
269
|
firstLink?.focus();
|
|
219
270
|
}, 0);
|
|
220
271
|
}
|
|
221
|
-
|
|
222
|
-
|
|
272
|
+
toggleMenu() {
|
|
273
|
+
if (this.menuOpen) {
|
|
274
|
+
this.closeMenu();
|
|
275
|
+
return;
|
|
276
|
+
}
|
|
277
|
+
this.openMenu();
|
|
223
278
|
}
|
|
224
279
|
openMenu() {
|
|
225
280
|
this.menuOpen = true;
|
|
226
|
-
this.
|
|
281
|
+
this.closeDropdown();
|
|
227
282
|
}
|
|
228
283
|
closeMenu() {
|
|
229
284
|
this.menuOpen = false;
|
|
230
|
-
this.
|
|
285
|
+
this.closeDropdown();
|
|
231
286
|
}
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
dropdowns: [],
|
|
238
|
-
links: [...SIGNED_IN_HEADER.links],
|
|
239
|
-
signIn: null,
|
|
240
|
-
signOut: SIGNED_IN_HEADER.signOut,
|
|
241
|
-
};
|
|
287
|
+
getActiveMenu() {
|
|
288
|
+
return this.signedIn ? SIGNED_IN_MENU : this.resolved.menu;
|
|
289
|
+
}
|
|
290
|
+
getLogoSrc() {
|
|
291
|
+
return this.resolved.logoSrc ?? LOGO_SRC;
|
|
242
292
|
}
|
|
243
293
|
getLogoHref() {
|
|
244
|
-
return
|
|
294
|
+
return DEFAULT_LOGO_HREF;
|
|
295
|
+
}
|
|
296
|
+
findSignInLink(menu) {
|
|
297
|
+
for (const item of menu) {
|
|
298
|
+
if (!isMenuGroup(item) && isSignInLink(item))
|
|
299
|
+
return item;
|
|
300
|
+
}
|
|
301
|
+
return null;
|
|
245
302
|
}
|
|
246
303
|
getManageAccountLabel() {
|
|
247
304
|
const name = this.userName?.trim();
|
|
248
305
|
return name || 'Manage Account';
|
|
249
306
|
}
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
const
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
307
|
+
renderIconNavLink(link, Icon, className, onNavigate) {
|
|
308
|
+
return (h("li", { class: "main-nav__item main-nav__item--auth", key: link.label }, h("a", { class: { 'sign-in-link': true, [className]: true }, href: link.href, onClick: () => onNavigate?.() }, h(Icon, null), link.label)));
|
|
309
|
+
}
|
|
310
|
+
renderFlatNavLink(link, onNavigate) {
|
|
311
|
+
return (h("li", { class: "main-nav__item", key: link.label }, h("a", { class: "nav-link", href: link.href, onClick: () => onNavigate?.() }, link.label)));
|
|
312
|
+
}
|
|
313
|
+
renderMenuGroup(item, onNavigate) {
|
|
314
|
+
const items = item.items ?? [];
|
|
315
|
+
const isOpen = this.openDropdown === item.label;
|
|
316
|
+
const panelId = this.getDropdownPanelId(item.label);
|
|
317
|
+
return (h("li", { class: "main-nav__item main-nav__item--dropdown", key: item.label }, h("div", { class: "nav-dropdown", onMouseEnter: () => this.handleDropdownPointerEnter(item.label), onMouseLeave: (event) => this.handleDropdownPointerLeave(event), onFocusout: (event) => this.handleDropdownFocusOut(event, item.label) }, h("button", { type: "button", class: {
|
|
318
|
+
'nav-dropdown__trigger': true,
|
|
319
|
+
'nav-dropdown__trigger--open': isOpen,
|
|
320
|
+
}, "aria-expanded": isOpen ? 'true' : 'false', "aria-haspopup": "true", "aria-controls": panelId, id: `${panelId}-trigger`, onClick: (event) => this.handleDropdownTriggerClick(event, item.label), onKeyDown: (event) => {
|
|
321
|
+
const container = event.currentTarget.closest('.nav-dropdown');
|
|
322
|
+
this.handleDropdownTriggerKeyDown(event, item.label, container);
|
|
323
|
+
} }, h("span", { class: "nav-dropdown__label" }, item.label), h(ToggleIcon, { expanded: isOpen })), isOpen ? (h("div", { class: "nav-dropdown__panel", id: panelId, role: "region", "aria-labelledby": `${panelId}-trigger`, onMouseEnter: () => this.handleDropdownPanelPointerEnter(item.label), onMouseLeave: (event) => this.handleDropdownPanelPointerLeave(event) }, h("div", { class: "nav-dropdown__accent" }, h("div", { class: "nav-dropdown__links" }, items.map((child) => (h("a", { class: "nav-dropdown__link", href: child.href, key: `${item.label}:${child.label}`, onClick: () => onNavigate?.() }, child.label))))))) : null)));
|
|
324
|
+
}
|
|
325
|
+
handleAuthClick(event, action, href, onNavigate) {
|
|
326
|
+
const emitted = this.wegAuthClick.emit({ action });
|
|
265
327
|
if (emitted.defaultPrevented) {
|
|
266
328
|
event.preventDefault();
|
|
267
329
|
onNavigate?.();
|
|
268
330
|
return;
|
|
269
331
|
}
|
|
270
|
-
if (
|
|
332
|
+
if (action === 'sign-out') {
|
|
271
333
|
event.preventDefault();
|
|
272
|
-
if (
|
|
273
|
-
window.location.assign(
|
|
334
|
+
if (href) {
|
|
335
|
+
window.location.assign(href);
|
|
274
336
|
}
|
|
275
337
|
onNavigate?.();
|
|
276
338
|
return;
|
|
@@ -278,71 +340,70 @@ export class WegHeader {
|
|
|
278
340
|
onNavigate?.();
|
|
279
341
|
}
|
|
280
342
|
renderAuthControl(options) {
|
|
281
|
-
const
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
if (
|
|
300
|
-
return (
|
|
343
|
+
const { link, action, iconOnly, onNavigate } = options;
|
|
344
|
+
const Icon = action === 'sign-out' ? SignOutIcon : SignInIcon;
|
|
345
|
+
const classSuffix = action === 'sign-out' ? 'sign-out-link' : 'sign-in-link';
|
|
346
|
+
return (h("a", { class: {
|
|
347
|
+
[classSuffix]: !iconOnly,
|
|
348
|
+
'icon-button': !!iconOnly,
|
|
349
|
+
[options.className || '']: !!options.className,
|
|
350
|
+
}, href: link.href, "aria-label": link.label, onClick: (event) => this.handleAuthClick(event, action, link.href, onNavigate) }, h(Icon, null), !iconOnly ? link.label : null, iconOnly ? h("span", { class: "sr-only" }, link.label) : null));
|
|
351
|
+
}
|
|
352
|
+
renderManageAccountAnchor(onNavigate, iconOnly = false) {
|
|
353
|
+
const label = this.getManageAccountLabel();
|
|
354
|
+
return (h("a", { class: {
|
|
355
|
+
'sign-in-link': !iconOnly,
|
|
356
|
+
'manage-account-link': true,
|
|
357
|
+
'icon-button': iconOnly,
|
|
358
|
+
}, href: ACCOUNT_MANAGE_HREF, "aria-label": label, onClick: () => onNavigate?.() }, h(SignInIcon, null), !iconOnly ? label : null, iconOnly ? h("span", { class: "sr-only" }, label) : null));
|
|
359
|
+
}
|
|
360
|
+
renderNavItem(item, onNavigate) {
|
|
361
|
+
if (isMenuGroup(item)) {
|
|
362
|
+
return this.renderMenuGroup(item, onNavigate);
|
|
363
|
+
}
|
|
364
|
+
if (isSignOutLink(item)) {
|
|
365
|
+
return (h("li", { class: "main-nav__item main-nav__item--auth", key: "sign-out" }, this.renderAuthControl({ link: item, action: 'sign-out', onNavigate })));
|
|
366
|
+
}
|
|
367
|
+
if (isSignInLink(item)) {
|
|
368
|
+
return (h("li", { class: "main-nav__item main-nav__item--auth", key: "sign-in" }, this.renderAuthControl({ link: item, action: 'sign-in', onNavigate })));
|
|
369
|
+
}
|
|
370
|
+
if (isManageAccountLink(item)) {
|
|
371
|
+
return (h("li", { class: "main-nav__item main-nav__item--auth", key: "manage-account" }, this.renderManageAccountAnchor(onNavigate)));
|
|
372
|
+
}
|
|
373
|
+
if (this.signedIn && isFindJobLink(item)) {
|
|
374
|
+
return this.renderIconNavLink(item, FindJobIcon, 'find-a-job-link', onNavigate);
|
|
375
|
+
}
|
|
376
|
+
if (this.signedIn && isDashboardLink(item)) {
|
|
377
|
+
return this.renderIconNavLink(item, DashboardIcon, 'dashboard-link', onNavigate);
|
|
378
|
+
}
|
|
379
|
+
return this.renderFlatNavLink(item, onNavigate);
|
|
380
|
+
}
|
|
381
|
+
renderNav(onNavigate) {
|
|
382
|
+
return (h("nav", { class: "main-nav", "aria-label": "Main" }, h("ul", { class: "main-nav__list" }, this.getActiveMenu().map((item) => this.renderNavItem(item, onNavigate)))));
|
|
383
|
+
}
|
|
384
|
+
renderCompactAuth(onNavigate) {
|
|
385
|
+
if (this.signedIn) {
|
|
386
|
+
return this.renderManageAccountAnchor(onNavigate, true);
|
|
301
387
|
}
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
h("li", { class: "desktop-nav__item", key: "sign-out" }, h("a", { class: "sign-in-link sign-out-link", href: signOut.href, "aria-label": signOut.label, onClick: (event) => this.handleAuthClick(event, options.onNavigate) }, h(SignOutIcon, null), signOut.label)),
|
|
305
|
-
];
|
|
306
|
-
}
|
|
307
|
-
renderDesktop() {
|
|
308
|
-
const { dropdowns, links } = this.getActiveHeaderData();
|
|
309
|
-
return (h("div", { class: "desktop" }, h(Logo, { href: this.getLogoHref() }), h("nav", { class: "desktop-nav", "aria-label": "Main" }, h("ul", { class: "desktop-nav__list" }, dropdowns.map((dropdown) => {
|
|
310
|
-
const isOpen = this.openDropdown === dropdown.label;
|
|
311
|
-
const panelId = this.getDropdownPanelId(dropdown.label);
|
|
312
|
-
return (h("li", { class: "desktop-nav__item desktop-nav__item--dropdown", key: dropdown.label, onMouseEnter: () => this.handleDropdownPointerEnter(dropdown.label), onMouseLeave: () => this.handleDropdownPointerLeave(), onFocusin: () => this.handleDropdownFocusIn(dropdown.label), onFocusout: (event) => this.handleDropdownFocusOut(event, dropdown.label) }, h("button", { type: "button", class: {
|
|
313
|
-
'dropdown-trigger': true,
|
|
314
|
-
'dropdown-trigger--open': isOpen,
|
|
315
|
-
}, "aria-expanded": isOpen ? 'true' : 'false', "aria-haspopup": "true", "aria-controls": panelId, id: `${panelId}-trigger`, onClick: (event) => {
|
|
316
|
-
event.stopPropagation();
|
|
317
|
-
this.toggleDropdown(dropdown.label);
|
|
318
|
-
}, onKeyDown: (event) => {
|
|
319
|
-
const itemEl = event.currentTarget.closest('.desktop-nav__item--dropdown');
|
|
320
|
-
this.handleDropdownTriggerKeyDown(event, dropdown.label, itemEl);
|
|
321
|
-
} }, dropdown.label, h(ToggleIcon, { expanded: isOpen })), isOpen ? (h("div", { class: "dropdown-panel", id: panelId, role: "region", "aria-labelledby": `${panelId}-trigger` }, h("div", { class: "dropdown-panel__accent" }, h("div", { class: "dropdown-panel__links" }, dropdown.items.map((item) => (h("a", { class: "dropdown-panel__link", href: item.href, key: `${dropdown.label}:${item.label}` }, item.label))))))) : null));
|
|
322
|
-
}), links.map((link) => (h("li", { class: "desktop-nav__item", key: link.label }, h("a", { class: "nav-link", href: link.href }, link.label)))), this.signedIn
|
|
323
|
-
? this.renderSignedInAuthControls({})
|
|
324
|
-
: this.getAuthControl()
|
|
325
|
-
? h("li", { class: "desktop-nav__item" }, this.renderAuthControl({}))
|
|
326
|
-
: null))));
|
|
327
|
-
}
|
|
328
|
-
renderMobileBar() {
|
|
329
|
-
return (h("div", { class: "mobile" }, h("button", { type: "button", class: "icon-button", "aria-label": "Open menu", onClick: () => this.openMenu() }, h(HamburgerIcon, null)), h(Logo, { href: this.getLogoHref() }), this.signedIn
|
|
330
|
-
? this.renderSignedInAuthControls({ iconOnly: true })
|
|
331
|
-
: this.renderAuthControl({ iconOnly: true })));
|
|
332
|
-
}
|
|
333
|
-
renderMobileOverlay() {
|
|
334
|
-
if (!this.menuOpen)
|
|
388
|
+
const signIn = this.findSignInLink(this.resolved.menu);
|
|
389
|
+
if (!signIn?.href)
|
|
335
390
|
return null;
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
}), links.map((link) => (h("div", { class: "mobile-nav__section", key: link.label }, h("a", { class: "mobile-nav__row", href: link.href, onClick: () => this.closeMenu() }, link.label)))), this.signedIn ? (h("div", { class: "mobile-nav__section" }, h("a", { class: "mobile-nav__row manage-account-link", href: SIGNED_IN_HEADER.manageAccount.href, onClick: () => this.closeMenu() }, this.getManageAccountLabel()), h("a", { class: "mobile-nav__row sign-out-link", href: SIGNED_IN_HEADER.signOut.href, onClick: (event) => this.handleAuthClick(event, () => this.closeMenu()) }, h(SignOutIcon, null), SIGNED_IN_HEADER.signOut.label))) : null)));
|
|
391
|
+
return this.renderAuthControl({
|
|
392
|
+
link: signIn,
|
|
393
|
+
action: 'sign-in',
|
|
394
|
+
iconOnly: true,
|
|
395
|
+
onNavigate,
|
|
396
|
+
});
|
|
343
397
|
}
|
|
344
398
|
render() {
|
|
345
|
-
|
|
399
|
+
const logoHref = this.getLogoHref();
|
|
400
|
+
const logoSrc = this.getLogoSrc();
|
|
401
|
+
const closeMenu = () => this.closeMenu();
|
|
402
|
+
const mobileMenuActive = this.isMobileMenuActive();
|
|
403
|
+
return (h("header", { key: 'ce1a217dd1eda9bb72b506c187a5c6a0848de3a6', class: {
|
|
404
|
+
header: true,
|
|
405
|
+
'header--menu-open': mobileMenuActive,
|
|
406
|
+
} }, h("div", { key: '535d54f8eb512158c6048d748fccce4feb097cc0', class: "container header-inner" }, h("button", { key: '51a0fead049fadcbee17c8e622a35b1d2d8be99c', type: "button", class: "menu-toggle icon-button", "aria-label": mobileMenuActive ? 'Close menu' : 'Open menu', "aria-expanded": mobileMenuActive ? 'true' : 'false', "aria-controls": "weg-header-main-nav", onClick: () => this.toggleMenu() }, mobileMenuActive ? h(CloseIcon, null) : h(HamburgerIcon, null)), h(Logo, { key: '6f5693bfec5d8fe196ca3e4ff565506b6c3d3421', href: logoHref, src: logoSrc }), h("div", { key: '9f846e47cb68b6158e832fdffda5973e5e1554f4', class: "header-actions" }, this.renderCompactAuth(mobileMenuActive ? closeMenu : undefined)), h("div", { key: 'e18db3c24e934200595a1216dc74f3dcb8ad0e67', class: "main-nav-panel", id: "weg-header-main-nav", role: mobileMenuActive ? 'dialog' : undefined, "aria-modal": mobileMenuActive ? 'true' : undefined, "aria-label": mobileMenuActive ? 'Menu' : undefined }, this.renderNav(mobileMenuActive ? closeMenu : undefined)))));
|
|
346
407
|
}
|
|
347
408
|
static get is() { return "weg-header"; }
|
|
348
409
|
static get encapsulation() { return "shadow"; }
|
|
@@ -363,7 +424,7 @@ export class WegHeader {
|
|
|
363
424
|
"mutable": false,
|
|
364
425
|
"complexType": {
|
|
365
426
|
"original": "LayoutData | string",
|
|
366
|
-
"resolved": "string | { header?: Partial<LayoutHeaderData>; footer?: Partial<
|
|
427
|
+
"resolved": "string | { header?: Partial<LayoutHeaderData>; footer?: Partial<LayoutFooterData>; }",
|
|
367
428
|
"references": {
|
|
368
429
|
"LayoutData": {
|
|
369
430
|
"location": "import",
|
|
@@ -377,7 +438,7 @@ export class WegHeader {
|
|
|
377
438
|
"optional": true,
|
|
378
439
|
"docs": {
|
|
379
440
|
"tags": [],
|
|
380
|
-
"text": "Layout payload, supplied by the host application.\n\nExpected shape:\n```json\n{\n \"header\": {\n \"
|
|
441
|
+
"text": "Layout payload, supplied by the host application.\r\n\r\nExpected shape:\r\n```json\r\n{\r\n \"header\": {\r\n \"menu\": [\r\n { \"label\": \"Find a job\", \"items\": [{ \"label\": \"Graduates\", \"href\": \"...\" }] },\r\n { \"label\": \"Career advice\", \"href\": \"/career-advice\" },\r\n { \"label\": \"Sign in\", \"href\": \"/account/login\" }\r\n ]\r\n }\r\n}\r\n```"
|
|
381
442
|
},
|
|
382
443
|
"getter": false,
|
|
383
444
|
"setter": false,
|
|
@@ -396,7 +457,7 @@ export class WegHeader {
|
|
|
396
457
|
"optional": false,
|
|
397
458
|
"docs": {
|
|
398
459
|
"tags": [],
|
|
399
|
-
"text": "When true, the header
|
|
460
|
+
"text": "When true, the header uses the built-in signed-in menu instead of the CMS layout."
|
|
400
461
|
},
|
|
401
462
|
"getter": false,
|
|
402
463
|
"setter": false,
|
|
@@ -429,8 +490,7 @@ export class WegHeader {
|
|
|
429
490
|
return {
|
|
430
491
|
"resolved": {},
|
|
431
492
|
"menuOpen": {},
|
|
432
|
-
"openDropdown": {}
|
|
433
|
-
"expandedSection": {}
|
|
493
|
+
"openDropdown": {}
|
|
434
494
|
};
|
|
435
495
|
}
|
|
436
496
|
static get events() {
|
|
@@ -442,7 +502,7 @@ export class WegHeader {
|
|
|
442
502
|
"composed": true,
|
|
443
503
|
"docs": {
|
|
444
504
|
"tags": [],
|
|
445
|
-
"text": "Fired when the user clicks Sign in or Sign out.\nCall `event.preventDefault()` in the host to handle navigation/logout yourself."
|
|
505
|
+
"text": "Fired when the user clicks Sign in or Sign out.\r\nCall `event.preventDefault()` in the host to handle navigation/logout yourself."
|
|
446
506
|
},
|
|
447
507
|
"complexType": {
|
|
448
508
|
"original": "{ action: LayoutHeaderAuthAction }",
|