weg-shared-layout 0.0.14 → 0.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.
Files changed (50) hide show
  1. package/dist/cjs/{index-CmiaQ_Dj.js → index-CC8e1qRm.js} +112 -0
  2. package/dist/cjs/loader.cjs.js +2 -2
  3. package/dist/cjs/my-component.cjs.entry.js +1 -1
  4. package/dist/cjs/weg-footer_2.cjs.entry.js +438 -0
  5. package/dist/cjs/weg-shared-layout.cjs.js +2 -2
  6. package/dist/collection/collection-manifest.json +2 -1
  7. package/dist/collection/components/weg-footer/weg-footer.css +1 -24
  8. package/dist/collection/components/weg-footer/weg-footer.js +5 -40
  9. package/dist/collection/components/weg-header/logo-data.js +2 -0
  10. package/dist/collection/components/weg-header/weg-header.cmp.test.js +77 -0
  11. package/dist/collection/components/weg-header/weg-header.css +327 -0
  12. package/dist/collection/components/weg-header/weg-header.js +344 -0
  13. package/dist/collection/styles/shared.css +49 -0
  14. package/dist/collection/utils/layout.js +33 -0
  15. package/dist/collection/utils/layout.unit.test.js +36 -0
  16. package/dist/components/index.js +1 -1
  17. package/dist/components/my-component.js +1 -1
  18. package/dist/components/p-CtYuWNO6.js +1 -0
  19. package/dist/components/p-DbIEJ3IT.js +1 -0
  20. package/dist/components/weg-footer.js +1 -1
  21. package/dist/components/weg-header.d.ts +11 -0
  22. package/dist/components/weg-header.js +1 -0
  23. package/dist/esm/{index-QiJxC4Ow.js → index-D8pmhPiH.js} +111 -1
  24. package/dist/esm/loader.js +3 -3
  25. package/dist/esm/my-component.entry.js +1 -1
  26. package/dist/esm/weg-footer_2.entry.js +435 -0
  27. package/dist/esm/weg-shared-layout.js +3 -3
  28. package/dist/types/components/weg-header/logo-data.d.ts +2 -0
  29. package/dist/types/components/weg-header/weg-header.cmp.test.d.ts +1 -0
  30. package/dist/types/components/weg-header/weg-header.d.ts +56 -0
  31. package/dist/types/components.d.ts +56 -2
  32. package/dist/types/types/layout-data.d.ts +21 -4
  33. package/dist/types/utils/layout.d.ts +4 -0
  34. package/dist/types/utils/layout.unit.test.d.ts +1 -0
  35. package/dist/weg-shared-layout/p-D8pmhPiH.js +2 -0
  36. package/dist/weg-shared-layout/{p-d1addb13.entry.js → p-d61033bd.entry.js} +1 -1
  37. package/dist/weg-shared-layout/p-eaf953a4.entry.js +1 -0
  38. package/dist/weg-shared-layout/weg-shared-layout.esm.js +1 -1
  39. package/docs/angular.md +66 -18
  40. package/docs/nextjs.md +145 -111
  41. package/docs/react.md +123 -59
  42. package/docs/vanilla.md +99 -3
  43. package/package.json +5 -1
  44. package/readme.md +31 -3
  45. package/src/assets/dummy-data.json +41 -1
  46. package/dist/cjs/weg-footer.cjs.entry.js +0 -189
  47. package/dist/components/p-BTQYW5OR.js +0 -1
  48. package/dist/esm/weg-footer.entry.js +0 -187
  49. package/dist/weg-shared-layout/p-0c28f34f.entry.js +0 -1
  50. package/dist/weg-shared-layout/p-QiJxC4Ow.js +0 -2
package/docs/react.md CHANGED
@@ -2,19 +2,22 @@
2
2
 
3
3
  Guide for **client-rendered** React apps (Vite, Create React App, etc.). If you use **Next.js App Router**, see **[Next.js](./nextjs.md)** — SSR and Server Components require a different integration.
4
4
 
5
- ## What is `<weg-footer>`?
5
+ ## Components
6
6
 
7
- `<weg-footer>` is a **presentational** [Stencil](https://stenciljs.com/) Web Component shipped by `weg-shared-layout`. It renders the site footer (social links, link columns, credits, copyright) from a **layout payload** you provide.
7
+ | Tag | Purpose |
8
+ | --- | --- |
9
+ | `<weg-header>` | Site header — logo (bundled), nav dropdowns, flat links, Sign in / Sign out |
10
+ | `<weg-footer>` | Site footer — social links, columns, credits, copyright |
8
11
 
9
- The component **does not fetch data**. Your app loads JSON (from an API, CMS, or a static file) and passes it on the `layout` property.
12
+ Both are **presentational** [Stencil](https://stenciljs.com/) Web Components. They **do not fetch data** your app passes a **`layout`** payload (API, CMS, or [`dummy-data.json`](../src/assets/dummy-data.json)).
10
13
 
11
- Payload shape matches [`dummy-data.json`](../src/assets/dummy-data.json) (see also [readme](../readme.md#how-it-works)).
14
+ `<weg-header>` additionally accepts **`signed-in`** and emits **`wegAuthClick`** for auth handling.
12
15
 
13
16
  ## Requirements
14
17
 
15
18
  | Requirement | Notes |
16
19
  | --- | --- |
17
- | **React 19+** | React 19 maps custom-element props to DOM **properties** when possible. Older React often sets `layout` as a string **attribute**, which breaks object payloads. |
20
+ | **React 19+** | React 19 maps custom-element props to DOM **properties** when possible. Older React often sets props as string **attributes**, which breaks object payloads. |
18
21
  | **Bundler** | Must resolve `node_modules` ESM/CJS from `weg-shared-layout`. |
19
22
  | **TypeScript (optional)** | Module augmentation below; enable `resolveJsonModule` if you import `dummy-data.json`. |
20
23
 
@@ -28,7 +31,7 @@ pnpm add weg-shared-layout
28
31
 
29
32
  ## 1. Register custom elements (once)
30
33
 
31
- Call `defineCustomElements()` **once** before the first `<weg-footer>` render — typically in your app entry (`main.tsx`, `index.tsx`):
34
+ Call `defineCustomElements()` **once** before the first render — typically in `main.tsx` / `index.tsx`:
32
35
 
33
36
  ```ts
34
37
  import { defineCustomElements } from 'weg-shared-layout/loader';
@@ -36,53 +39,129 @@ import { defineCustomElements } from 'weg-shared-layout/loader';
36
39
  defineCustomElements();
37
40
  ```
38
41
 
39
- Also side-effect import the tag so your bundler includes the component definition:
42
+ Side-effect import the tags your app uses:
40
43
 
41
44
  ```ts
45
+ import 'weg-shared-layout/weg-header';
42
46
  import 'weg-shared-layout/weg-footer';
43
47
  ```
44
48
 
45
- **Alternative:** import only the footer bundle (no loader call):
49
+ **Alternative:** import individual tag bundles only (no loader):
46
50
 
47
51
  ```ts
52
+ import 'weg-shared-layout/weg-header';
48
53
  import 'weg-shared-layout/weg-footer';
49
54
  ```
50
55
 
51
56
  Use the loader when you may add more tags from this package later.
52
57
 
53
- ## 2. Render the footer
58
+ ## 2. Layout shell
54
59
 
55
60
  ### Recommended: pass `layout` as an object (React 19+)
56
61
 
57
62
  ```tsx
63
+ import 'weg-shared-layout/weg-header';
58
64
  import 'weg-shared-layout/weg-footer';
59
65
  import layout from 'weg-shared-layout/dummy-data.json';
60
66
 
61
- export function SiteFooter() {
62
- return <weg-footer layout={layout} />;
67
+ export function SiteLayout({ children }: { children: React.ReactNode }) {
68
+ return (
69
+ <>
70
+ <weg-header layout={layout} />
71
+ {children}
72
+ <weg-footer layout={layout} />
73
+ </>
74
+ );
63
75
  }
64
76
  ```
65
77
 
66
- With React 19+, `layout={layoutObject}` is applied as the custom element’s **`layout` property** (object), which `<weg-footer>` expects.
78
+ ### Fallback: `JSON.stringify` (React 18 or empty components)
79
+
80
+ ```tsx
81
+ <weg-header layout={JSON.stringify(layout)} />
82
+ <weg-footer layout={JSON.stringify(layout)} />
83
+ ```
84
+
85
+ ## 3. Header auth
67
86
 
68
- ### Fallback: `JSON.stringify` (all React versions)
87
+ The WEG logo is bundled inside `<weg-header>` — not configurable via `layout`.
69
88
 
70
- If you are on React 18 or see an empty footer despite correct data, pass a JSON **string**. The component parses string values the same as objects:
89
+ Configure labels in `layout.header`:
90
+
91
+ ```json
92
+ "signIn": { "label": "Sign in", "href": "/account/login" },
93
+ "signOut": { "label": "Sign out" }
94
+ ```
95
+
96
+ Set **`signed-in`** from your session state and listen for **`wegAuthClick`**:
71
97
 
72
98
  ```tsx
73
- <weg-footer layout={JSON.stringify(layout)} />
99
+ import { useCallback, useState } from 'react';
100
+ import 'weg-shared-layout/weg-header';
101
+ import layout from 'weg-shared-layout/dummy-data.json';
102
+
103
+ export function SiteHeader() {
104
+ const [signedIn, setSignedIn] = useState(false);
105
+
106
+ const onAuthClick = useCallback((event: CustomEvent<{ action: 'sign-in' | 'sign-out' }>) => {
107
+ event.preventDefault();
108
+
109
+ if (event.detail.action === 'sign-out') {
110
+ // your logout(), then:
111
+ setSignedIn(false);
112
+ return;
113
+ }
114
+
115
+ window.location.href = '/account/login';
116
+ }, []);
117
+
118
+ return (
119
+ <weg-header
120
+ layout={layout}
121
+ signed-in={signedIn}
122
+ // @ts-expect-error Stencil custom event
123
+ onWegAuthClick={onAuthClick}
124
+ />
125
+ );
126
+ }
74
127
  ```
75
128
 
76
- ### Plain HTML attribute
129
+ | Prop / event | Purpose |
130
+ | --- | --- |
131
+ | `signed-in={boolean}` | Shows Sign out when `true` |
132
+ | `onWegAuthClick` | Host handles routing / logout; call `event.preventDefault()` to override defaults |
77
133
 
78
- Outside React, you can set `layout='{"footer":{...}}'` on the element. Prefer the property in SPA code.
134
+ **Ref fallback for the event** (if `onWegAuthClick` does not bind in your React version):
79
135
 
80
- ## 3. Production: fetch layout from your API
136
+ ```tsx
137
+ import { useEffect, useRef } from 'react';
138
+
139
+ const ref = useRef<HTMLWegHeaderElement>(null);
140
+
141
+ useEffect(() => {
142
+ const el = ref.current;
143
+ if (!el) return;
81
144
 
82
- Example using the public test API (same shape as `dummy-data.json`):
145
+ const handler = (event: Event) => {
146
+ const e = event as CustomEvent<{ action: 'sign-in' | 'sign-out' }>;
147
+ e.preventDefault();
148
+ // ...
149
+ };
150
+
151
+ el.addEventListener('wegAuthClick', handler);
152
+ return () => el.removeEventListener('wegAuthClick', handler);
153
+ }, []);
154
+
155
+ return <weg-header ref={ref} layout={layout} signed-in={signedIn} />;
156
+ ```
157
+
158
+ Update `signedIn` via `ref.current.signedIn = true` if property binding is unreliable.
159
+
160
+ ## 4. Production: fetch layout from your API
83
161
 
84
162
  ```tsx
85
163
  import { useEffect, useState } from 'react';
164
+ import 'weg-shared-layout/weg-header';
86
165
  import 'weg-shared-layout/weg-footer';
87
166
  import layoutFixture from 'weg-shared-layout/dummy-data.json';
88
167
 
@@ -90,7 +169,7 @@ type LayoutData = typeof layoutFixture;
90
169
 
91
170
  const LAYOUT_URL = 'https://weg-payload-test.vercel.app/api/layout';
92
171
 
93
- export function SiteFooter() {
172
+ export function SiteLayout({ children }: { children: React.ReactNode }) {
94
173
  const [layout, setLayout] = useState<LayoutData | null>(null);
95
174
 
96
175
  useEffect(() => {
@@ -109,17 +188,23 @@ export function SiteFooter() {
109
188
  };
110
189
  }, []);
111
190
 
112
- if (!layout) return null; // or a skeleton
191
+ if (!layout) return null;
113
192
 
114
- return <weg-footer layout={layout} />;
193
+ return (
194
+ <>
195
+ <weg-header layout={layout} />
196
+ {children}
197
+ <weg-footer layout={layout} />
198
+ </>
199
+ );
115
200
  }
116
201
  ```
117
202
 
118
- Replace the URL with your own CMS/API. Keep the object shape aligned with `dummy-data.json`.
203
+ Replace the URL with your CMS/API. Keep the object shape aligned with `dummy-data.json`.
119
204
 
120
205
  ## TypeScript: module augmentation
121
206
 
122
- Do **not** rely on a triple-slash reference in every file. Augment React’s JSX namespace once (e.g. `src/types/weg-shared-layout-jsx.d.ts`):
207
+ Add once (e.g. `src/types/weg-shared-layout-jsx.d.ts`):
123
208
 
124
209
  ```ts
125
210
  import type { JSX as WegSharedLayoutJSX } from 'weg-shared-layout';
@@ -128,6 +213,8 @@ import type { DetailedHTMLProps, HTMLAttributes } from 'react';
128
213
  declare module 'react' {
129
214
  namespace JSX {
130
215
  interface IntrinsicElements extends WegSharedLayoutJSX.IntrinsicElements {
216
+ 'weg-header': WegSharedLayoutJSX.IntrinsicElements['weg-header'] &
217
+ DetailedHTMLProps<HTMLAttributes<HTMLWegHeaderElement>, HTMLWegHeaderElement>;
131
218
  'weg-footer': WegSharedLayoutJSX.IntrinsicElements['weg-footer'] &
132
219
  DetailedHTMLProps<HTMLAttributes<HTMLWegFooterElement>, HTMLWegFooterElement>;
133
220
  }
@@ -135,8 +222,6 @@ declare module 'react' {
135
222
  }
136
223
  ```
137
224
 
138
- Ensure that file is included by your `tsconfig.json` `include`/`files`.
139
-
140
225
  Enable in `tsconfig.json` when importing JSON fixtures:
141
226
 
142
227
  ```json
@@ -147,55 +232,34 @@ Enable in `tsconfig.json` when importing JSON fixtures:
147
232
  }
148
233
  ```
149
234
 
150
- ## `layout` prop vs attribute (why React version matters)
235
+ ## `layout` prop vs attribute
151
236
 
152
237
  | How data is set | Works with object? |
153
238
  | --- | --- |
154
239
  | **Property** `el.layout = obj` / React 19 `layout={obj}` | Yes |
155
- | **Attribute** `layout="[object Object]"` / React 18 `layout={obj}` | No — footer stays empty |
156
- | **Attribute** `layout='{"footer":...}'` / `layout={JSON.stringify(obj)}` | Yes — component parses JSON |
240
+ | **Attribute** `layout="[object Object]"` / React 18 `layout={obj}` | No — components stay empty |
241
+ | **Attribute** `layout={JSON.stringify(obj)}` | Yes — component parses JSON |
157
242
 
158
- `<weg-footer>` accepts `layout` as either an object or a JSON string (see `parseJsonProp` in the component source).
243
+ Both components accept `layout` as an object or JSON string.
159
244
 
160
245
  ## Note: `prop:layout` is unreliable in React
161
246
 
162
- Some examples set Stencil props with a `prop:` prefix (e.g. `prop:layout={data}`). In React this is **not dependable** — behavior varies by version and reconciler. Prefer:
163
-
164
- 1. **`layout={object}`** on React 19+, or
165
- 2. **`layout={JSON.stringify(object)}`**, or
166
- 3. **Ref fallback** after mount:
167
-
168
- ```tsx
169
- import { useEffect, useRef } from 'react';
170
- import type layoutFixture from 'weg-shared-layout/dummy-data.json';
171
-
172
- type LayoutData = typeof layoutFixture;
173
-
174
- export function SiteFooter({ layout }: { layout: LayoutData }) {
175
- const ref = useRef<HTMLWegFooterElement>(null);
176
-
177
- useEffect(() => {
178
- if (ref.current) ref.current.layout = layout;
179
- }, [layout]);
180
-
181
- return <weg-footer ref={ref} />;
182
- }
183
- ```
247
+ Prefer `layout={object}`, `layout={JSON.stringify(object)}`, or ref assignment not `prop:layout`.
184
248
 
185
249
  ## Troubleshooting
186
250
 
187
251
  | Symptom | Likely cause | Fix |
188
252
  | --- | --- | --- |
189
- | Empty footer, no errors | `defineCustomElements()` not called, or missing `import 'weg-shared-layout/weg-footer'` | Register loader + import tag in entry before render. |
190
- | Empty footer, data looks correct | React set `layout` as attribute (`[object Object]`) | Upgrade to React 19+, or use `layout={JSON.stringify(layout)}` or ref assignment. |
191
- | TypeScript: `'weg-footer' does not exist on JSX.IntrinsicElements` | No module augmentation | Add `weg-shared-layout-jsx.d.ts` as above. |
192
- | Cannot find module `weg-shared-layout/dummy-data.json` | `resolveJsonModule` off | Enable in `tsconfig.json`. |
193
- | Footer flashes then disappears | Strict Mode double-mount + async layout | Ensure stable `layout` reference; avoid resetting state on remount. |
194
- | Styles missing | Shadow DOM is encapsulated | Footer ships its own CSS; do not expect global site styles inside the shadow root. |
253
+ | Empty header/footer | Loader/tag import missing | `defineCustomElements()` + `import 'weg-shared-layout/weg-header'` (and footer). |
254
+ | Empty despite correct data | React set `layout` as attribute | React 19+, or `JSON.stringify`, or ref assignment. |
255
+ | Logo missing on header | Old build without inlined logo | Upgrade package; logo is bundled in `logo-data.ts`. |
256
+ | Auth always Sign in | `signed-in` not set | Bind `signed-in={!!session}`. |
257
+ | `onWegAuthClick` not firing | React CE event binding | Use `addEventListener` on a ref (see above). |
258
+ | TS: unknown element | No augmentation | Add `weg-shared-layout-jsx.d.ts`. |
195
259
 
196
260
  ## See also
197
261
 
198
- - **[Next.js App Router](./nextjs.md)** — Server Components, `transpilePackages`, hydration
262
+ - **[Next.js App Router](./nextjs.md)**
199
263
  - **[Angular](./angular.md)**
200
264
  - **[Plain HTML / vanilla JS](./vanilla.md)**
201
265
  - **[Package readme](../readme.md)**
package/docs/vanilla.md CHANGED
@@ -1,18 +1,114 @@
1
1
  # Plain HTML / vanilla JS
2
2
 
3
+ ## What you get
4
+
5
+ | Tag | Purpose |
6
+ | --- | --- |
7
+ | `<weg-header>` | Site header — logo (bundled), nav dropdowns, flat links, Sign in / Sign out |
8
+ | `<weg-footer>` | Site footer — social links, columns, credits, copyright |
9
+
10
+ Both components are **presentational**: they do **not** fetch data. Pass the same `layout` payload to each (or one shared object on both).
11
+
12
+ Payload shape: [`dummy-data.json`](../src/assets/dummy-data.json) (see [readme](../readme.md#how-it-works)).
13
+
14
+ ## Install & register
15
+
3
16
  With a bundler that resolves `node_modules` imports:
4
17
 
5
18
  ```html
19
+ <weg-header id="header"></weg-header>
20
+ <main><!-- your content --></main>
6
21
  <weg-footer id="footer"></weg-footer>
22
+
7
23
  <script type="module">
8
24
  import { defineCustomElements } from 'weg-shared-layout/loader';
9
25
  import layout from 'weg-shared-layout/dummy-data.json';
10
26
 
11
27
  defineCustomElements();
12
- document.getElementById('footer').layout = layout;
28
+
29
+ const header = document.getElementById('header');
30
+ const footer = document.getElementById('footer');
31
+
32
+ header.layout = layout;
33
+ footer.layout = layout;
13
34
  </script>
14
35
  ```
15
36
 
16
- Otherwise, copy `dummy-data.json` to your static assets, `fetch` it, parse JSON, then assign **`element.layout`**.
37
+ Side-effect imports (no loader) if you only need specific tags:
38
+
39
+ ```js
40
+ import 'weg-shared-layout/weg-header';
41
+ import 'weg-shared-layout/weg-footer';
42
+ ```
43
+
44
+ ## `layout` property vs attribute
45
+
46
+ Assign the **`layout` JavaScript property** (recommended):
47
+
48
+ ```js
49
+ element.layout = layoutObject;
50
+ ```
51
+
52
+ Or pass a JSON **string** on the `layout` attribute — the component parses it the same way:
53
+
54
+ ```html
55
+ <weg-header layout='{"header":{"links":[]}}'></weg-header>
56
+ ```
57
+
58
+ ## Header auth (Sign in / Sign out)
59
+
60
+ The logo is bundled inside `<weg-header>` and cannot be changed via `layout`.
61
+
62
+ Set **`signedIn`** when the user has a session (maps to the `signed-in` attribute):
63
+
64
+ ```js
65
+ header.signedIn = true;
66
+ // or
67
+ header.setAttribute('signed-in', '');
68
+ ```
69
+
70
+ Labels come from `layout.header.signIn` and `layout.header.signOut`:
71
+
72
+ ```json
73
+ "signIn": { "label": "Sign in", "href": "/account/login" },
74
+ "signOut": { "label": "Sign out" }
75
+ ```
76
+
77
+ Listen for **`wegAuthClick`** to handle sign-in routing or sign-out logic:
78
+
79
+ ```js
80
+ header.addEventListener('wegAuthClick', (event) => {
81
+ event.preventDefault(); // stop default navigation / redirect
82
+
83
+ if (event.detail.action === 'sign-out') {
84
+ // your logout()
85
+ header.signedIn = false;
86
+ return;
87
+ }
88
+
89
+ window.location.href = '/account/login';
90
+ });
91
+ ```
92
+
93
+ | `event.detail.action` | Default behaviour if not prevented |
94
+ | --- | --- |
95
+ | `'sign-in'` | Browser follows `signIn.href` |
96
+ | `'sign-out'` | Navigates to `signOut.href` if set; otherwise event only |
97
+
98
+ ## Without a bundler
99
+
100
+ Copy `dummy-data.json` to your static assets, `fetch` it, parse JSON, then assign properties:
101
+
102
+ ```js
103
+ const res = await fetch('/assets/dummy-data.json');
104
+ const layout = await res.json();
105
+ document.getElementById('header').layout = layout;
106
+ document.getElementById('footer').layout = layout;
107
+ ```
108
+
109
+ ## See also
17
110
 
18
- You can also pass a JSON string on the **`layout` attribute**; the component parses it the same way as an object `layout` property.
111
+ - **[React SPA](./react.md)**
112
+ - **[Next.js App Router](./nextjs.md)**
113
+ - **[Angular](./angular.md)**
114
+ - **[Package readme](../readme.md)**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "weg-shared-layout",
3
- "version": "0.0.14",
3
+ "version": "0.0.15",
4
4
  "description": "Shared layout Web Components built with Stencil",
5
5
  "main": "dist/index.cjs.js",
6
6
  "module": "dist/index.js",
@@ -22,6 +22,10 @@
22
22
  "types": "./dist/components/weg-footer.d.ts",
23
23
  "import": "./dist/components/weg-footer.js"
24
24
  },
25
+ "./weg-header": {
26
+ "types": "./dist/components/weg-header.d.ts",
27
+ "import": "./dist/components/weg-header.js"
28
+ },
25
29
  "./loader": {
26
30
  "types": "./loader/index.d.ts",
27
31
  "import": "./loader/index.js",
package/readme.md CHANGED
@@ -12,14 +12,25 @@ npm i weg-shared-layout
12
12
 
13
13
  ## How it works
14
14
 
15
- `<weg-footer>` is a **presentational** Web Component: it does **not** fetch data.
16
-
17
- You **can** load that object however you normally fetch JSON in your app. For example, [https://weg-payload-test.vercel.app/api/layout](https://weg-payload-test.vercel.app/api/layout) returns the same shape as **`dummy-data.json`**; pass the response into `layout` on `<weg-footer>` (or your framework wrapper) like any other prop.
15
+ `<weg-header>` and `<weg-footer>` are **presentational** Web Components: they do **not** fetch data.
16
+
17
+ You **can** load that object however you normally fetch JSON in your app. For example, [https://weg-payload-test.vercel.app/api/layout](https://weg-payload-test.vercel.app/api/layout) returns the same shape as **`dummy-data.json`**; pass the response into `layout` on `<weg-header>` / `<weg-footer>` (or your framework wrapper) like any other prop.
18
18
 
19
19
  The payload shape matches **`dummy-data.json`** (and `GET /api/layout` from the WEG CMS):
20
20
 
21
21
  ```json
22
22
  {
23
+ "header": {
24
+ "dropdowns": [
25
+ {
26
+ "label": "Find a job",
27
+ "items": [{ "label": "Graduates", "href": "/search?category=graduates" }]
28
+ }
29
+ ],
30
+ "links": [{ "label": "Career advice", "href": "/career-advice" }],
31
+ "signIn": { "label": "Sign in", "href": "/account/login" },
32
+ "signOut": { "label": "Sign out" }
33
+ },
23
34
  "footer": {
24
35
  "social": [{ "platform": "LinkedIn", "href": "https://..." }],
25
36
  "columns": [{ "links": [{ "label": "About Us", "href": "/about" }] }],
@@ -29,6 +40,23 @@ The payload shape matches **`dummy-data.json`** (and `GET /api/layout` from the
29
40
  }
30
41
  ```
31
42
 
43
+ The WEG logo is bundled inside `<weg-header>` (`logo-data.ts`) and is not configurable via `layout`.
44
+
45
+ ### Auth (Sign in / Sign out)
46
+
47
+ Set **`signed-in`** on `<weg-header>` from your app when the user has a session. Labels come from `layout.header.signIn` / `layout.header.signOut`.
48
+
49
+ Listen for **`wegAuthClick`** to run sign-in routing or sign-out logic. Call `event.preventDefault()` to stop default navigation (sign-in link follow or sign-out `href` redirect).
50
+
51
+ ```js
52
+ header.signedIn = true;
53
+ header.addEventListener('wegAuthClick', (event) => {
54
+ event.preventDefault();
55
+ if (event.detail.action === 'sign-out') logout();
56
+ else window.location.href = '/account/login';
57
+ });
58
+ ```
59
+
32
60
  - **From npm:** `import layout from 'weg-shared-layout/dummy-data.json'` (enable `resolveJsonModule` in TypeScript if needed).
33
61
 
34
62
  - **In this repo:** [`src/assets/dummy-data.json`](src/assets/dummy-data.json)
@@ -1,5 +1,45 @@
1
1
  {
2
- "header": {},
2
+ "header": {
3
+ "dropdowns": [
4
+ {
5
+ "label": "Find a job",
6
+ "items": [
7
+ { "label": "Professional & operational services", "href": "/search?category=professional" },
8
+ { "label": "Engineering & technology", "href": "/search?category=engineering" },
9
+ { "label": "Graduates", "href": "/search?category=graduates" },
10
+ { "label": "Senior & leadership", "href": "/search?category=senior" }
11
+ ]
12
+ },
13
+ {
14
+ "label": "Hire talent",
15
+ "items": [
16
+ { "label": "Professional & operational services", "href": "/hire/professional" },
17
+ { "label": "Engineering & technology", "href": "/hire/engineering" },
18
+ { "label": "Graduates", "href": "/hire/graduates" },
19
+ { "label": "Executive search & selection", "href": "/hire/executive" }
20
+ ]
21
+ },
22
+ {
23
+ "label": "HE solutions",
24
+ "items": [
25
+ { "label": "Franchise solution", "href": "/franchise" },
26
+ { "label": "Payroll bureau", "href": "/payroll" },
27
+ { "label": "Disability support", "href": "/disability-support" }
28
+ ]
29
+ }
30
+ ],
31
+ "links": [
32
+ { "label": "Career advice", "href": "/career-advice" },
33
+ { "label": "Register", "href": "/register" }
34
+ ],
35
+ "signIn": {
36
+ "label": "Sign in",
37
+ "href": "/account/login"
38
+ },
39
+ "signOut": {
40
+ "label": "Sign out"
41
+ }
42
+ },
3
43
  "footer": {
4
44
  "social": [
5
45
  { "platform": "LinkedIn", "href": "https://www.linkedin.com/company/warwickemploymentgroup/" },