weg-shared-layout 0.0.22 → 0.0.24

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 (57) hide show
  1. package/LICENSE +21 -21
  2. package/dist/cjs/loader.cjs.js +1 -1
  3. package/dist/cjs/weg-footer_2.cjs.entry.js +121 -58
  4. package/dist/cjs/weg-shared-layout.cjs.js +1 -1
  5. package/dist/collection/collection-manifest.json +0 -1
  6. package/dist/collection/components/weg-footer/icons/instagram.svg +5 -5
  7. package/dist/collection/components/weg-footer/icons/linkedin.svg +3 -3
  8. package/dist/collection/components/weg-footer/icons/tiktok.svg +3 -3
  9. package/dist/collection/components/weg-footer/icons/youtube.svg +4 -4
  10. package/dist/collection/components/weg-footer/weg-footer.css +218 -201
  11. package/dist/collection/components/weg-footer/weg-footer.js +2 -2
  12. package/dist/collection/components/weg-header/weg-header.css +473 -365
  13. package/dist/collection/components/weg-header/weg-header.js +114 -58
  14. package/dist/collection/constants/breakpoints.js +6 -0
  15. package/dist/collection/styles/shared.css +72 -78
  16. package/dist/components/weg-footer.js +1 -1
  17. package/dist/components/weg-header.js +1 -1
  18. package/dist/esm/loader.js +1 -1
  19. package/dist/esm/weg-footer_2.entry.js +121 -58
  20. package/dist/esm/weg-shared-layout.js +1 -1
  21. package/dist/test-utils/axe.js +12 -0
  22. package/dist/test-utils/viewport.js +10 -0
  23. package/dist/types/Users/rakin/Documents/WEG/repos/weg-shared-layout/.stencil/test-utils/axe.d.ts +2 -0
  24. package/dist/types/Users/rakin/Documents/WEG/repos/weg-shared-layout/.stencil/test-utils/viewport.d.ts +10 -0
  25. package/dist/types/components/weg-header/weg-header.d.ts +20 -7
  26. package/dist/types/components.d.ts +0 -42
  27. package/dist/types/constants/breakpoints.d.ts +6 -0
  28. package/dist/weg-shared-layout/p-c6ec3888.entry.js +1 -0
  29. package/dist/weg-shared-layout/weg-shared-layout.esm.js +1 -1
  30. package/docs/angular-integration-guide.md +1026 -0
  31. package/docs/angular.md +247 -138
  32. package/docs/nextjs.md +305 -305
  33. package/docs/publishing.md +48 -48
  34. package/docs/react.md +261 -261
  35. package/docs/vanilla.md +140 -140
  36. package/package.json +11 -6
  37. package/readme.md +108 -107
  38. package/src/assets/dummy-data.json +147 -147
  39. package/src/constants/breakpoints.ts +7 -0
  40. package/src/constants/weg-urls.ts +23 -23
  41. package/dist/cjs/my-component.cjs.entry.js +0 -33
  42. package/dist/collection/components/my-component/my-component.cmp.test.js +0 -27
  43. package/dist/collection/components/my-component/my-component.css +0 -3
  44. package/dist/collection/components/my-component/my-component.js +0 -95
  45. package/dist/collection/components/weg-header/weg-header.cmp.test.js +0 -93
  46. package/dist/collection/utils/layout.unit.test.js +0 -36
  47. package/dist/collection/utils/utils.unit.test.js +0 -16
  48. package/dist/components/my-component.d.ts +0 -11
  49. package/dist/components/my-component.js +0 -1
  50. package/dist/esm/my-component.entry.js +0 -31
  51. package/dist/types/components/my-component/my-component.cmp.test.d.ts +0 -1
  52. package/dist/types/components/my-component/my-component.d.ts +0 -16
  53. package/dist/types/components/weg-header/weg-header.cmp.test.d.ts +0 -1
  54. package/dist/types/utils/layout.unit.test.d.ts +0 -1
  55. package/dist/types/utils/utils.unit.test.d.ts +0 -1
  56. package/dist/weg-shared-layout/p-80fa529c.entry.js +0 -1
  57. package/dist/weg-shared-layout/p-d61033bd.entry.js +0 -1
@@ -1,147 +1,147 @@
1
- {
2
- "header": {
3
- "logoHref": "https://www.warwickemploymentgroup.com/",
4
- "dropdowns": [
5
- {
6
- "label": "Find a job",
7
- "items": [
8
- {
9
- "label": "Professional & operational services",
10
- "href": "https://www.warwickemploymentgroup.com/find-a-job/professional-and-operational-services"
11
- },
12
- {
13
- "label": "Engineering & technology",
14
- "href": "https://www.warwickemploymentgroup.com/find-a-job/engineering-and-technology"
15
- },
16
- {
17
- "label": "Graduates",
18
- "href": "https://www.warwickemploymentgroup.com/find-a-job/graduates"
19
- },
20
- {
21
- "label": "Senior & leadership",
22
- "href": "https://www.warwickemploymentgroup.com/find-a-job/senior-and-leadership"
23
- }
24
- ]
25
- },
26
- {
27
- "label": "Hire talent",
28
- "items": [
29
- {
30
- "label": "Professional & operational services",
31
- "href": "https://www.warwickemploymentgroup.com/hire-talent/professional-and-operational-services"
32
- },
33
- {
34
- "label": "Engineering & technology",
35
- "href": "https://www.warwickemploymentgroup.com/hire-talent/engineering-and-technology"
36
- },
37
- {
38
- "label": "Graduates",
39
- "href": "https://www.warwickemploymentgroup.com/hire-talent/graduates"
40
- },
41
- {
42
- "label": "Executive search & selection",
43
- "href": "https://www.warwickemploymentgroup.com/hire-talent/executive-search-and-selection"
44
- }
45
- ]
46
- },
47
- {
48
- "label": "HE solutions",
49
- "items": [
50
- {
51
- "label": "Franchise solution",
52
- "href": "https://www.warwickemploymentgroup.com/he-solutions/unitemps-franchise"
53
- },
54
- {
55
- "label": "Disability support solution",
56
- "href": "https://www.warwickemploymentgroup.com/he-solutions/disabillity-support"
57
- },
58
- {
59
- "label": "Payroll bureau",
60
- "href": "https://www.warwickemploymentgroup.com/he-solutions/payroll-bureau"
61
- }
62
- ]
63
- }
64
- ],
65
- "links": [
66
- {
67
- "label": "Career advice",
68
- "href": "https://www.warwickemploymentgroup.com/career-advice"
69
- },
70
- {
71
- "label": "Register",
72
- "href": "https://account.warwickemploymentgroup.com/account/register"
73
- }
74
- ],
75
- "signIn": {
76
- "label": "Sign in",
77
- "href": "https://account.warwickemploymentgroup.com/account/login"
78
- },
79
- "signOut": {
80
- "label": "Sign out",
81
- "href": "https://account.warwickemploymentgroup.com/account/login"
82
- }
83
- },
84
- "footer": {
85
- "social": [
86
- { "platform": "LinkedIn", "href": "https://www.linkedin.com/company/warwickemploymentgroup/" },
87
- { "platform": "TikTok", "href": "https://www.tiktok.com/@weg_updates" },
88
- { "platform": "Instagram", "href": "https://www.instagram.com/warwickemploymentgroup/" },
89
- { "platform": "YouTube", "href": "https://www.youtube.com/@WarwickEmploymentGroup" }
90
- ],
91
- "columns": [
92
- {
93
- "links": [
94
- { "label": "Find a job", "href": "/jobs" },
95
- { "label": "Professional & operational", "href": "/jobs/professional" },
96
- { "label": "Engineering & technology", "href": "/jobs/engineering" },
97
- { "label": "Graduates", "href": "/jobs/graduates" },
98
- { "label": "Senior & leadership", "href": "/jobs/senior" }
99
- ]
100
- },
101
- {
102
- "links": [
103
- { "label": "Hire talent", "href": "/hire" },
104
- { "label": "Professional & operational", "href": "/hire/professional" },
105
- { "label": "Engineering & technology", "href": "/hire/engineering" },
106
- { "label": "Graduates", "href": "/hire/graduates" },
107
- { "label": "Executive search & selection", "href": "/hire/executive" }
108
- ]
109
- },
110
- {
111
- "links": [
112
- { "label": "HE solutions", "href": "/he-solutions" },
113
- { "label": "Franchise solution", "href": "/franchise" },
114
- { "label": "Payroll bureau", "href": "/payroll" },
115
- { "label": "Disability support", "href": "/disability-support" }
116
- ]
117
- },
118
- {
119
- "links": [
120
- { "label": "Career advice", "href": "/career-advice" },
121
- { "label": "News & events", "href": "/news" },
122
- { "label": "Insights", "href": "/insights" }
123
- ]
124
- },
125
- {
126
- "links": [
127
- { "label": "About WEG", "href": "/about" },
128
- { "label": "Our brands", "href": "/brands" },
129
- { "label": "Careers at WEG", "href": "/careers" },
130
- { "label": "Contact us", "href": "/contact" }
131
- ]
132
- },
133
- {
134
- "links": [
135
- { "label": "Privacy policy", "href": "/privacy" },
136
- { "label": "Terms of use", "href": "/terms" },
137
- { "label": "Cookie policy", "href": "/cookies" },
138
- { "label": "Accessibility statement", "href": "/accessibility" },
139
- { "label": "Diversity & inclusion", "href": "/diversity" },
140
- { "label": "Modern slavery", "href": "/modern-slavery" }
141
- ]
142
- }
143
- ],
144
- "credits": "Warwick Employment Group is a department of the Campus and Commercial Services Group at the University of Warwick.",
145
- "copyright": "Copyright © Warwick Employment Group."
146
- }
147
- }
1
+ {
2
+ "header": {
3
+ "logoHref": "https://www.warwickemploymentgroup.com/",
4
+ "dropdowns": [
5
+ {
6
+ "label": "Find a job",
7
+ "items": [
8
+ {
9
+ "label": "Professional & operational services",
10
+ "href": "https://www.warwickemploymentgroup.com/find-a-job/professional-and-operational-services"
11
+ },
12
+ {
13
+ "label": "Engineering & technology",
14
+ "href": "https://www.warwickemploymentgroup.com/find-a-job/engineering-and-technology"
15
+ },
16
+ {
17
+ "label": "Graduates",
18
+ "href": "https://www.warwickemploymentgroup.com/find-a-job/graduates"
19
+ },
20
+ {
21
+ "label": "Senior & leadership",
22
+ "href": "https://www.warwickemploymentgroup.com/find-a-job/senior-and-leadership"
23
+ }
24
+ ]
25
+ },
26
+ {
27
+ "label": "Hire talent",
28
+ "items": [
29
+ {
30
+ "label": "Professional & operational services",
31
+ "href": "https://www.warwickemploymentgroup.com/hire-talent/professional-and-operational-services"
32
+ },
33
+ {
34
+ "label": "Engineering & technology",
35
+ "href": "https://www.warwickemploymentgroup.com/hire-talent/engineering-and-technology"
36
+ },
37
+ {
38
+ "label": "Graduates",
39
+ "href": "https://www.warwickemploymentgroup.com/hire-talent/graduates"
40
+ },
41
+ {
42
+ "label": "Executive search & selection",
43
+ "href": "https://www.warwickemploymentgroup.com/hire-talent/executive-search-and-selection"
44
+ }
45
+ ]
46
+ },
47
+ {
48
+ "label": "HE solutions",
49
+ "items": [
50
+ {
51
+ "label": "Franchise solution",
52
+ "href": "https://www.warwickemploymentgroup.com/he-solutions/unitemps-franchise"
53
+ },
54
+ {
55
+ "label": "Disability support solution",
56
+ "href": "https://www.warwickemploymentgroup.com/he-solutions/disabillity-support"
57
+ },
58
+ {
59
+ "label": "Payroll bureau",
60
+ "href": "https://www.warwickemploymentgroup.com/he-solutions/payroll-bureau"
61
+ }
62
+ ]
63
+ }
64
+ ],
65
+ "links": [
66
+ {
67
+ "label": "Career advice",
68
+ "href": "https://www.warwickemploymentgroup.com/career-advice"
69
+ },
70
+ {
71
+ "label": "Register",
72
+ "href": "https://account.warwickemploymentgroup.com/account/register"
73
+ }
74
+ ],
75
+ "signIn": {
76
+ "label": "Sign in",
77
+ "href": "https://account.warwickemploymentgroup.com/account/login"
78
+ },
79
+ "signOut": {
80
+ "label": "Sign out",
81
+ "href": "https://account.warwickemploymentgroup.com/account/login"
82
+ }
83
+ },
84
+ "footer": {
85
+ "social": [
86
+ { "platform": "LinkedIn", "href": "https://www.linkedin.com/company/warwickemploymentgroup/" },
87
+ { "platform": "TikTok", "href": "https://www.tiktok.com/@weg_updates" },
88
+ { "platform": "Instagram", "href": "https://www.instagram.com/warwickemploymentgroup/" },
89
+ { "platform": "YouTube", "href": "https://www.youtube.com/@WarwickEmploymentGroup" }
90
+ ],
91
+ "columns": [
92
+ {
93
+ "links": [
94
+ { "label": "Find a job", "href": "/jobs" },
95
+ { "label": "Professional & operational", "href": "/jobs/professional" },
96
+ { "label": "Engineering & technology", "href": "/jobs/engineering" },
97
+ { "label": "Graduates", "href": "/jobs/graduates" },
98
+ { "label": "Senior & leadership", "href": "/jobs/senior" }
99
+ ]
100
+ },
101
+ {
102
+ "links": [
103
+ { "label": "Hire talent", "href": "/hire" },
104
+ { "label": "Professional & operational", "href": "/hire/professional" },
105
+ { "label": "Engineering & technology", "href": "/hire/engineering" },
106
+ { "label": "Graduates", "href": "/hire/graduates" },
107
+ { "label": "Executive search & selection", "href": "/hire/executive" }
108
+ ]
109
+ },
110
+ {
111
+ "links": [
112
+ { "label": "HE solutions", "href": "/he-solutions" },
113
+ { "label": "Franchise solution", "href": "/franchise" },
114
+ { "label": "Payroll bureau", "href": "/payroll" },
115
+ { "label": "Disability support", "href": "/disability-support" }
116
+ ]
117
+ },
118
+ {
119
+ "links": [
120
+ { "label": "Career advice", "href": "/career-advice" },
121
+ { "label": "News & events", "href": "/news" },
122
+ { "label": "Insights", "href": "/insights" }
123
+ ]
124
+ },
125
+ {
126
+ "links": [
127
+ { "label": "About WEG", "href": "/about" },
128
+ { "label": "Our brands", "href": "/brands" },
129
+ { "label": "Careers at WEG", "href": "/careers" },
130
+ { "label": "Contact us", "href": "/contact" }
131
+ ]
132
+ },
133
+ {
134
+ "links": [
135
+ { "label": "Privacy policy", "href": "/privacy" },
136
+ { "label": "Terms of use", "href": "/terms" },
137
+ { "label": "Cookie policy", "href": "/cookies" },
138
+ { "label": "Accessibility statement", "href": "/accessibility" },
139
+ { "label": "Diversity & inclusion", "href": "/diversity" },
140
+ { "label": "Modern slavery", "href": "/modern-slavery" }
141
+ ]
142
+ }
143
+ ],
144
+ "credits": "Warwick Employment Group is a department of the Campus and Commercial Services Group at the University of Warwick.",
145
+ "copyright": "Copyright © Warwick Employment Group."
146
+ }
147
+ }
@@ -0,0 +1,7 @@
1
+ /**
2
+ * JS media-query strings aligned with `src/styles/breakpoints.css`.
3
+ */
4
+ export const WEG_MD_MEDIA_QUERY = '(width >= 960px)' as const;
5
+
6
+ /** Primary input can hover (excludes most touch-only profiles). */
7
+ export const WEG_HOVER_CAPABLE_MEDIA_QUERY = '(hover: hover)' as const;
@@ -1,23 +1,23 @@
1
- /** Canonical WEG site and account URLs — single source of truth for components, docs, and host apps. */
2
-
3
- export const WEG_SITE_ORIGIN = 'https://www.warwickemploymentgroup.com';
4
- export const ACCOUNT_ORIGIN = 'https://account.warwickemploymentgroup.com';
5
-
6
- export const DEFAULT_LOGO_HREF = `${WEG_SITE_ORIGIN}/`;
7
- export const FIND_A_JOB_HREF = `${WEG_SITE_ORIGIN}/find-a-job`;
8
- export const CAREER_ADVICE_HREF = `${WEG_SITE_ORIGIN}/career-advice`;
9
-
10
- export const ACCOUNT_LOGIN_HREF = `${ACCOUNT_ORIGIN}/account/login`;
11
- export const ACCOUNT_REGISTER_HREF = `${ACCOUNT_ORIGIN}/account/register`;
12
- export const ACCOUNT_DASHBOARD_HREF = `${ACCOUNT_ORIGIN}/dashboard`;
13
- export const ACCOUNT_MANAGE_HREF = `${ACCOUNT_ORIGIN}/account/manage`;
14
-
15
- export const HEADER_SIGN_IN = {
16
- label: 'Sign in',
17
- href: ACCOUNT_LOGIN_HREF,
18
- } as const;
19
-
20
- export const HEADER_SIGN_OUT = {
21
- label: 'Sign out',
22
- href: ACCOUNT_LOGIN_HREF,
23
- } as const;
1
+ /** Canonical WEG site and account URLs — single source of truth for components, docs, and host apps. */
2
+
3
+ export const WEG_SITE_ORIGIN = 'https://www.warwickemploymentgroup.com';
4
+ export const ACCOUNT_ORIGIN = 'https://account.warwickemploymentgroup.com';
5
+
6
+ export const DEFAULT_LOGO_HREF = `${WEG_SITE_ORIGIN}/`;
7
+ export const FIND_A_JOB_HREF = `${WEG_SITE_ORIGIN}/find-a-job`;
8
+ export const CAREER_ADVICE_HREF = `${WEG_SITE_ORIGIN}/career-advice`;
9
+
10
+ export const ACCOUNT_LOGIN_HREF = `${ACCOUNT_ORIGIN}/account/login`;
11
+ export const ACCOUNT_REGISTER_HREF = `${ACCOUNT_ORIGIN}/account/register`;
12
+ export const ACCOUNT_DASHBOARD_HREF = `${ACCOUNT_ORIGIN}/dashboard`;
13
+ export const ACCOUNT_MANAGE_HREF = `${ACCOUNT_ORIGIN}/account/manage`;
14
+
15
+ export const HEADER_SIGN_IN = {
16
+ label: 'Sign in',
17
+ href: ACCOUNT_LOGIN_HREF,
18
+ } as const;
19
+
20
+ export const HEADER_SIGN_OUT = {
21
+ label: 'Sign out',
22
+ href: ACCOUNT_LOGIN_HREF,
23
+ } as const;
@@ -1,33 +0,0 @@
1
- 'use strict';
2
-
3
- var index = require('./index-CC8e1qRm.js');
4
- var index$1 = require('./index.cjs.js');
5
-
6
- const myComponentCss = () => `:host{display:block}`;
7
-
8
- const MyComponent = class {
9
- constructor(hostRef) {
10
- index.registerInstance(this, hostRef);
11
- }
12
- /**
13
- * The first name
14
- */
15
- first;
16
- /**
17
- * The middle name
18
- */
19
- middle;
20
- /**
21
- * The last name
22
- */
23
- last;
24
- getText() {
25
- return index$1.format(this.first, this.middle, this.last);
26
- }
27
- render() {
28
- return index.h("div", { key: '5452c3b9c97f8879dbc26b788d1fa79409846ff0' }, "Hello, world! I'm ", this.getText());
29
- }
30
- };
31
- MyComponent.style = myComponentCss();
32
-
33
- exports.my_component = MyComponent;
@@ -1,27 +0,0 @@
1
- import { render, h, describe, it, expect } from "@stencil/vitest";
2
- describe('my-component', () => {
3
- it('renders', async () => {
4
- const { root } = await render(h("my-component", null));
5
- await expect(root).toEqualHtml(`
6
- <my-component class="hydrated">
7
- <mock:shadow-root>
8
- <div>
9
- Hello, World! I'm
10
- </div>
11
- </mock:shadow-root>
12
- </my-component>
13
- `);
14
- });
15
- it('renders with values', async () => {
16
- const { root } = await render(h("my-component", { first: "Stencil", middle: "'Don't call me a framework'", last: "JS" }));
17
- await expect(root).toEqualHtml(`
18
- <my-component class="hydrated">
19
- <mock:shadow-root>
20
- <div>
21
- Hello, World! I'm Stencil 'Don't call me a framework' JS
22
- </div>
23
- </mock:shadow-root>
24
- </my-component>
25
- `);
26
- });
27
- });
@@ -1,3 +0,0 @@
1
- :host {
2
- display: block;
3
- }
@@ -1,95 +0,0 @@
1
- import { h } from "@stencil/core";
2
- import { format } from "../../utils/utils";
3
- export class MyComponent {
4
- /**
5
- * The first name
6
- */
7
- first;
8
- /**
9
- * The middle name
10
- */
11
- middle;
12
- /**
13
- * The last name
14
- */
15
- last;
16
- getText() {
17
- return format(this.first, this.middle, this.last);
18
- }
19
- render() {
20
- return h("div", { key: '5452c3b9c97f8879dbc26b788d1fa79409846ff0' }, "Hello, world! I'm ", this.getText());
21
- }
22
- static get is() { return "my-component"; }
23
- static get encapsulation() { return "shadow"; }
24
- static get originalStyleUrls() {
25
- return {
26
- "$": ["my-component.css"]
27
- };
28
- }
29
- static get styleUrls() {
30
- return {
31
- "$": ["my-component.css"]
32
- };
33
- }
34
- static get properties() {
35
- return {
36
- "first": {
37
- "type": "string",
38
- "mutable": false,
39
- "complexType": {
40
- "original": "string",
41
- "resolved": "string",
42
- "references": {}
43
- },
44
- "required": false,
45
- "optional": true,
46
- "docs": {
47
- "tags": [],
48
- "text": "The first name"
49
- },
50
- "getter": false,
51
- "setter": false,
52
- "reflect": false,
53
- "attribute": "first"
54
- },
55
- "middle": {
56
- "type": "string",
57
- "mutable": false,
58
- "complexType": {
59
- "original": "string",
60
- "resolved": "string",
61
- "references": {}
62
- },
63
- "required": false,
64
- "optional": true,
65
- "docs": {
66
- "tags": [],
67
- "text": "The middle name"
68
- },
69
- "getter": false,
70
- "setter": false,
71
- "reflect": false,
72
- "attribute": "middle"
73
- },
74
- "last": {
75
- "type": "string",
76
- "mutable": false,
77
- "complexType": {
78
- "original": "string",
79
- "resolved": "string",
80
- "references": {}
81
- },
82
- "required": false,
83
- "optional": true,
84
- "docs": {
85
- "tags": [],
86
- "text": "The last name"
87
- },
88
- "getter": false,
89
- "setter": false,
90
- "reflect": false,
91
- "attribute": "last"
92
- }
93
- };
94
- }
95
- }
@@ -1,93 +0,0 @@
1
- import { render, h, describe, it, expect } from "@stencil/vitest";
2
- const SAMPLE_HEADER_LAYOUT = {
3
- header: {
4
- dropdowns: [
5
- {
6
- label: 'Find a job',
7
- items: [{ label: 'Graduates', href: '/search?category=graduates' }],
8
- },
9
- ],
10
- links: [{ label: 'Career advice', href: '/career-advice' }],
11
- signIn: { label: 'Sign in', href: '/account/login' },
12
- signOut: { label: 'Sign out' },
13
- },
14
- };
15
- describe('weg-header', () => {
16
- it('renders safely when layout is undefined', async () => {
17
- const { root } = await render(h("weg-header", null));
18
- expect(root).toBeTruthy();
19
- const header = root.shadowRoot?.querySelector('.header');
20
- expect(header).toBeTruthy();
21
- });
22
- it('parses JSON string layout prop', async () => {
23
- const { root } = await render(h("weg-header", { layout: JSON.stringify(SAMPLE_HEADER_LAYOUT) }));
24
- const text = root.shadowRoot?.textContent ?? '';
25
- expect(text).toContain('Find a job');
26
- expect(text).toContain('Career advice');
27
- expect(text).toContain('Sign in');
28
- });
29
- it('renders dropdown labels and flat links from layout object', async () => {
30
- const { root } = await render(h("weg-header", { layout: SAMPLE_HEADER_LAYOUT }));
31
- const text = root.shadowRoot?.textContent ?? '';
32
- expect(text).toContain('Find a job');
33
- expect(text).toContain('Career advice');
34
- });
35
- it('shows signed-in navigation when signed-in is true', async () => {
36
- const { root } = await render(h("weg-header", { layout: SAMPLE_HEADER_LAYOUT, "signed-in": true, "user-name": "Alex" }));
37
- const text = root.shadowRoot?.textContent ?? '';
38
- expect(text).toContain('Find a job');
39
- expect(text).toContain('Dashboard');
40
- expect(text).toContain('Alex');
41
- expect(text).toContain('Sign out');
42
- expect(text).not.toContain('Sign in');
43
- expect(text).not.toContain('Career advice');
44
- });
45
- it('emits wegAuthClick when auth control is clicked', async () => {
46
- const { root } = await render(h("weg-header", { layout: SAMPLE_HEADER_LAYOUT }));
47
- let detail;
48
- root.addEventListener('wegAuthClick', ((event) => {
49
- detail = event.detail;
50
- event.preventDefault();
51
- }));
52
- const authLink = root.shadowRoot?.querySelector('.desktop .sign-in-link');
53
- expect(authLink).toBeTruthy();
54
- authLink?.click();
55
- expect(detail).toEqual({ action: 'sign-in' });
56
- });
57
- it('emits sign-out action when signed in', async () => {
58
- const { root } = await render(h("weg-header", { layout: SAMPLE_HEADER_LAYOUT, "signed-in": true }));
59
- let detail;
60
- root.addEventListener('wegAuthClick', ((event) => {
61
- detail = event.detail;
62
- event.preventDefault();
63
- }));
64
- const signOutLink = root.shadowRoot?.querySelector('.desktop .sign-out-link');
65
- expect(signOutLink).toBeTruthy();
66
- signOutLink?.click();
67
- expect(detail).toEqual({ action: 'sign-out' });
68
- });
69
- it('opens desktop dropdown on trigger focus with accessible wiring', async () => {
70
- const { root } = await render(h("weg-header", { layout: SAMPLE_HEADER_LAYOUT }));
71
- const trigger = root.shadowRoot?.querySelector('.dropdown-trigger');
72
- expect(trigger).toBeTruthy();
73
- expect(trigger?.getAttribute('aria-haspopup')).toBe('true');
74
- expect(trigger?.getAttribute('aria-expanded')).toBe('false');
75
- expect(trigger?.getAttribute('aria-controls')).toBeTruthy();
76
- trigger?.focus();
77
- await new Promise((r) => setTimeout(r, 0));
78
- expect(trigger?.getAttribute('aria-expanded')).toBe('true');
79
- expect(root.shadowRoot?.querySelector('.dropdown-panel')).toBeTruthy();
80
- });
81
- it('toggles mobile accordion aria-expanded', async () => {
82
- const { root } = await render(h("weg-header", { layout: SAMPLE_HEADER_LAYOUT }));
83
- const openButton = root.shadowRoot?.querySelector('.mobile .icon-button');
84
- expect(openButton).toBeTruthy();
85
- openButton?.click();
86
- await new Promise((r) => setTimeout(r, 0));
87
- const accordionButton = root.shadowRoot?.querySelector('.mobile-nav__row');
88
- expect(accordionButton?.getAttribute('aria-expanded')).toBe('false');
89
- accordionButton?.click();
90
- await new Promise((r) => setTimeout(r, 0));
91
- expect(accordionButton?.getAttribute('aria-expanded')).toBe('true');
92
- });
93
- });
@@ -1,36 +0,0 @@
1
- import { describe, it, expect } from "vitest";
2
- import { parseJsonProp, isNonEmptyString, normalizeLinks } from "./layout";
3
- describe('parseJsonProp', () => {
4
- it('returns non-string values unchanged', () => {
5
- expect(parseJsonProp({ header: {} })).toEqual({ header: {} });
6
- });
7
- it('parses JSON strings', () => {
8
- expect(parseJsonProp('{"footer":{}}')).toEqual({ footer: {} });
9
- });
10
- it('returns undefined for invalid or empty strings', () => {
11
- expect(parseJsonProp('')).toBeUndefined();
12
- expect(parseJsonProp('not json')).toBeUndefined();
13
- });
14
- });
15
- describe('isNonEmptyString', () => {
16
- it('accepts trimmed non-empty strings', () => {
17
- expect(isNonEmptyString(' hello ')).toBe(true);
18
- });
19
- it('rejects empty or non-string values', () => {
20
- expect(isNonEmptyString(' ')).toBe(false);
21
- expect(isNonEmptyString(null)).toBe(false);
22
- });
23
- });
24
- describe('normalizeLinks', () => {
25
- it('filters invalid entries and trims valid links', () => {
26
- expect(normalizeLinks([
27
- { label: ' About ', href: ' /about ' },
28
- { label: '', href: '/x' },
29
- { label: 'Missing href' },
30
- null,
31
- ])).toEqual([{ label: 'About', href: '/about' }]);
32
- });
33
- it('returns an empty array for non-arrays', () => {
34
- expect(normalizeLinks(undefined)).toEqual([]);
35
- });
36
- });