weg-shared-layout 0.0.32 → 0.0.34

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/docs/angular.md CHANGED
@@ -1,61 +1,85 @@
1
- # Angular
1
+ # Angular 16 integration
2
2
 
3
- Short quick start for Angular 16+. For the full **step-by-step** guide (HTTP, API mapping, testing, SSR, troubleshooting), see **[angular-integration-guide.md](./angular-integration-guide.md)**.
3
+ Step-by-step guide for **Angular 16** (standalone or NgModule). Uses plain component properties — no signals.
4
4
 
5
- | Demo | When |
6
- | --- | --- |
7
- | **[demo/angular16/README.md](../demo/angular16/README.md)** | Angular **16** — same imports as `npm i` (in-repo: `file:../..`) |
8
- | [weg-angular-demo](https://github.com/jobsac/weg-angular-demo) | Newer Angular (signals) |
5
+ Runnable reference: **[demo/angular16](../demo/angular16/README.md)** (`npm run demo:angular16` from repo root).
9
6
 
10
- ## Integration checklist
7
+ Newer Angular (signals): [weg-angular-demo](https://github.com/jobsac/weg-angular-demo) — same layout ideas, different syntax.
11
8
 
12
- - [ ] `npm i weg-shared-layout`
13
- - [ ] `defineCustomElements()` in `main.ts` **before** bootstrap
14
- - [ ] `skipLibCheck`, `resolveJsonModule`, `moduleResolution: "bundler"` (or `node16`) — see [Step 3 in integration guide](./angular-integration-guide.md#step-3--typescript-import-layout-json)
15
- - [ ] `auth.ts` with `HEADER_SIGN_IN` / `ACCOUNT_LOGIN_HREF` (host app constants)
16
- - [ ] `CUSTOM_ELEMENTS_SCHEMA` on the shell component that uses the tags
17
- - [ ] `[layout]="layoutObject"` on `<weg-header>` and `<weg-footer>`
18
- - [ ] Header: `[signedIn]`, `[userName]`, `(wegAuthClick)` when using auth
9
+ ---
19
10
 
20
- ## Components
11
+ ## Checklist
21
12
 
22
- | Tag | Purpose |
23
- | --- | --- |
24
- | `<weg-header>` | Header — CMS nav (signed out), built-in nav (signed in), auth |
25
- | `<weg-footer>` | Footer — social, menu, credits, copyright |
13
+ Copy this while integrating:
14
+
15
+ - [ ] **Step 1** — `npm i weg-shared-layout`
16
+ - [ ] **Step 2** — `tsconfig`: `skipLibCheck`, `resolveJsonModule`, `moduleResolution`
17
+ - [ ] **Step 3** — `defineCustomElements()` in `main.ts` **before** bootstrap
18
+ - [ ] **Step 4** — `layout.types.ts` from package fixture
19
+ - [ ] **Step 5** — `auth.ts` with sign-in URL constants (your app, not the package)
20
+ - [ ] **Step 6** — `CUSTOM_ELEMENTS_SCHEMA` on the shell component
21
+ - [ ] **Step 7** — Template with **`[layout]`** property binding
22
+ - [ ] **Step 8** — Header: `[signedIn]`, `[userName]`, `(wegAuthClick)`
23
+ - [ ] **Step 9** — Verify in DevTools: `$0.layout` is an object on `<weg-header>`
26
24
 
27
- Both accept the same `layout` payload ([`dummy-data.json`](../src/assets/dummy-data.json) or your API). `<weg-header>` also accepts **`signed-in`**, **`user-name`**, and emits **`wegAuthClick`**.
25
+ ---
28
26
 
29
- ## 1. Install
27
+ ## Step 1 — Install
30
28
 
31
29
  ```bash
32
30
  npm i weg-shared-layout
33
31
  ```
34
32
 
35
- ## 2. Register custom elements (once, before bootstrap)
33
+ ---
34
+
35
+ ## Step 2 — TypeScript config
36
+
37
+ In **`tsconfig.json`** and/or **`tsconfig.app.json`**:
38
+
39
+ ```json
40
+ {
41
+ "compilerOptions": {
42
+ "skipLibCheck": true,
43
+ "resolveJsonModule": true,
44
+ "moduleResolution": "bundler"
45
+ },
46
+ "include": ["src/**/*.ts"]
47
+ }
48
+ ```
49
+
50
+ | Option | Why |
51
+ | --- | --- |
52
+ | `skipLibCheck` | Skips Stencil `stencil-public-runtime.d.ts` (TS 5 syntax) when on TS 4.9 |
53
+ | `resolveJsonModule` | Allows `import … from 'weg-shared-layout/dummy-data.json'` |
54
+ | `moduleResolution: "bundler"` | Resolves package `exports` (`loader`, `dummy-data.json`) |
55
+
56
+ Use **`node16`** instead of **`bundler`** if you must stay on TypeScript 4.9. Classic **`node`** does not resolve subpaths reliably.
57
+
58
+ ---
59
+
60
+ ## Step 3 — Register custom elements
36
61
 
37
- **Recommended** — loader in `src/main.ts`:
62
+ Call the Stencil loader in **`src/main.ts`** once, **before** bootstrap:
38
63
 
39
64
  ```ts
40
65
  import { bootstrapApplication } from '@angular/platform-browser';
41
66
  import { defineCustomElements } from 'weg-shared-layout/loader';
42
67
 
68
+ import { AppComponent } from './app/app.component';
43
69
  import { appConfig } from './app/app.config';
44
- import { App } from './app/app';
45
70
 
46
71
  defineCustomElements();
47
72
 
48
- bootstrapApplication(App, appConfig).catch((err) => console.error(err));
73
+ bootstrapApplication(AppComponent, appConfig).catch((err) => console.error(err));
49
74
  ```
50
75
 
51
- **Alternative** — side-effect imports (one of these approaches, not both; needs `moduleResolution` `bundler` / `node16`):
76
+ If header/footer tags appear but nav is empty, registration did not run or ran too late.
52
77
 
53
- ```ts
54
- import 'weg-shared-layout/weg-header';
55
- import 'weg-shared-layout/weg-footer';
56
- ```
78
+ **NgModule apps:** same `defineCustomElements()` call, then `platformBrowserDynamic().bootstrapModule(AppModule)`.
79
+
80
+ ---
57
81
 
58
- ## 3. Layout types + TypeScript
82
+ ## Step 4 — Layout types
59
83
 
60
84
  ```ts
61
85
  // src/app/layout.types.ts
@@ -64,25 +88,17 @@ import layoutFixture from 'weg-shared-layout/dummy-data.json';
64
88
  export type LayoutData = typeof layoutFixture;
65
89
  ```
66
90
 
67
- ```json
68
- // tsconfig.json (or tsconfig.app.json) — required for JSON + package subpaths
69
- {
70
- "compilerOptions": {
71
- "skipLibCheck": true,
72
- "resolveJsonModule": true,
73
- "moduleResolution": "bundler"
74
- },
75
- "include": ["src/**/*.ts"]
76
- }
77
- ```
91
+ Alternative (types only, no JSON import):
78
92
 
79
- Angular 16 pitfalls (Stencil `.d.ts`, classic `node` resolution): **[angular-16-compatibility.md](./angular-16-compatibility.md)**.
93
+ ```ts
94
+ import type { LayoutData } from 'weg-shared-layout/layout-data';
95
+ ```
80
96
 
81
- ## 4. Allow custom elements in templates
97
+ ---
82
98
 
83
- Add `schemas: [CUSTOM_ELEMENTS_SCHEMA]` to every `@Component` (or `@NgModule`) whose template uses `<weg-header>` or `<weg-footer>`. Does **not** cascade to `router-outlet` children.
99
+ ## Step 5 — Auth URLs
84
100
 
85
- ## 5. Auth constants
101
+ Host apps own sign-in/out URLs — do not import these from the package.
86
102
 
87
103
  ```ts
88
104
  // src/app/auth.ts
@@ -94,35 +110,30 @@ export const HEADER_SIGN_IN = {
94
110
  export const ACCOUNT_LOGIN_HREF = HEADER_SIGN_IN.href;
95
111
  ```
96
112
 
97
- ## 6. Layout shell — pick one
113
+ ---
98
114
 
99
- Use **`[layout]="..."`** so Angular sets the JavaScript `layout` property, not an HTML attribute.
115
+ ## Step 6 — Shell component
100
116
 
101
- | Variant | Angular | Template bindings |
102
- | --- | --- | --- |
103
- | **6A** Plain properties | 16+ | `[layout]="layoutData"` |
104
- | **6B** Signals | 16.1+ | `[layout]="layoutData()"` |
105
-
106
- Full HTTP examples: integration guide **[Step 7A / 7B](./angular-integration-guide.md#step-7--load-layout-from-your-api)**.
107
-
108
- ### 6A — Plain properties (Angular 16+)
117
+ Add `CUSTOM_ELEMENTS_SCHEMA` to the component whose template contains `<weg-header>` / `<weg-footer>`. It does **not** cascade to routed children.
109
118
 
110
119
  ```ts
111
- // src/app/app.ts
120
+ // src/app/app.component.ts
112
121
  import { Component, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
113
122
  import { RouterOutlet } from '@angular/router';
114
123
  import layoutFixture from 'weg-shared-layout/dummy-data.json';
115
124
 
116
125
  import { ACCOUNT_LOGIN_HREF, HEADER_SIGN_IN } from './auth';
126
+ import type { LayoutData } from './layout.types';
117
127
 
118
128
  @Component({
119
129
  selector: 'app-root',
130
+ standalone: true,
120
131
  imports: [RouterOutlet],
121
132
  schemas: [CUSTOM_ELEMENTS_SCHEMA],
122
- templateUrl: './app.html',
133
+ templateUrl: './app.component.html',
123
134
  })
124
- export class App {
125
- layoutData = layoutFixture;
135
+ export class AppComponent {
136
+ layoutData: LayoutData = layoutFixture;
126
137
 
127
138
  signedIn = false;
128
139
  userName?: string;
@@ -142,8 +153,14 @@ export class App {
142
153
  }
143
154
  ```
144
155
 
156
+ ---
157
+
158
+ ## Step 7 — Template
159
+
160
+ Use **`[layout]="..."`** so Angular sets the JavaScript property, not an HTML attribute.
161
+
145
162
  ```html
146
- <!-- src/app/app.html -->
163
+ <!-- src/app/app.component.html -->
147
164
  <weg-header
148
165
  [layout]="layoutData"
149
166
  [signedIn]="signedIn"
@@ -151,43 +168,98 @@ export class App {
151
168
  (wegAuthClick)="onAuthClick($event)"
152
169
  ></weg-header>
153
170
 
154
- <router-outlet />
171
+ <main>
172
+ <router-outlet></router-outlet>
173
+ </main>
155
174
 
156
175
  <weg-footer [layout]="layoutData"></weg-footer>
157
176
  ```
158
177
 
159
- In production, load the same shape from your API — see **[Step 7A](./angular-integration-guide.md#step-7a--http-with-rxjs--async-pipe-pairs-with-6a)**. If your API returns separate arrays, see **[mapping section](./angular-integration-guide.md#optional-api-returns-separate-arrays-not-one-layout-object)**.
178
+ | Binding | Purpose |
179
+ | --- | --- |
180
+ | `[layout]` | CMS nav when signed out; same object for header and footer |
181
+ | `[signedIn]` | `true` → built-in signed-in nav (ignores CMS `header.menu`) |
182
+ | `[userName]` | First name on Manage Account when signed in |
183
+ | `(wegAuthClick)` | `detail.action`: `'sign-in'` \| `'sign-out'` — call `preventDefault()` when you handle navigation |
184
+
185
+ Run the app — you should see header nav and footer.
186
+
187
+ ---
188
+
189
+ ## Step 8 — Load layout from your API (optional)
190
+
191
+ When ready, replace the static fixture with HTTP. Register `provideHttpClient()` in `app.config.ts`.
192
+
193
+ **`src/app/layout.service.ts`:**
160
194
 
161
- ### 6B — Signals (Angular 16.1+)
195
+ ```ts
196
+ import { Injectable } from '@angular/core';
197
+ import { HttpClient } from '@angular/common/http';
198
+ import { map, Observable } from 'rxjs';
199
+
200
+ import { HEADER_SIGN_IN } from './auth';
201
+ import type { LayoutData } from './layout.types';
202
+
203
+ @Injectable({ providedIn: 'root' })
204
+ export class LayoutService {
205
+ constructor(private http: HttpClient) {}
206
+
207
+ loadLayout(): Observable<LayoutData> {
208
+ return this.http.get<LayoutData>('/api/layout').pipe(
209
+ map((data) => this.ensureSignInMenu(data)),
210
+ );
211
+ }
212
+
213
+ private ensureSignInMenu(data: LayoutData): LayoutData {
214
+ const menu = data.header?.menu ?? [];
215
+ const hasSignIn = menu.some(
216
+ (item) =>
217
+ !item.items?.length &&
218
+ item.label?.trim().toLowerCase() === 'sign in',
219
+ );
220
+ if (hasSignIn) return data;
221
+ return {
222
+ ...data,
223
+ header: { ...data.header, menu: [...menu, HEADER_SIGN_IN] },
224
+ };
225
+ }
226
+ }
227
+ ```
228
+
229
+ **`src/app/app.component.ts`** (HTTP variant):
162
230
 
163
231
  ```ts
164
- // src/app/app.ts
165
- import { Component, CUSTOM_ELEMENTS_SCHEMA, signal } from '@angular/core';
232
+ import { AsyncPipe } from '@angular/common';
233
+ import { Component, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
166
234
  import { RouterOutlet } from '@angular/router';
167
- import layoutFixture from 'weg-shared-layout/dummy-data.json';
235
+ import { Observable } from 'rxjs';
168
236
 
169
237
  import { ACCOUNT_LOGIN_HREF, HEADER_SIGN_IN } from './auth';
170
238
  import type { LayoutData } from './layout.types';
239
+ import { LayoutService } from './layout.service';
171
240
 
172
241
  @Component({
173
242
  selector: 'app-root',
174
- imports: [RouterOutlet],
243
+ standalone: true,
244
+ imports: [AsyncPipe, RouterOutlet],
175
245
  schemas: [CUSTOM_ELEMENTS_SCHEMA],
176
- templateUrl: './app.html',
246
+ templateUrl: './app.component.html',
177
247
  })
178
- export class App {
179
- readonly layoutData = signal<LayoutData>(layoutFixture);
248
+ export class AppComponent {
249
+ layout$: Observable<LayoutData>;
250
+ signedIn = false;
251
+ userName?: string;
180
252
 
181
- readonly signedIn = signal(false);
182
- readonly userName = signal<string | undefined>(undefined);
253
+ constructor(layoutService: LayoutService) {
254
+ this.layout$ = layoutService.loadLayout();
255
+ }
183
256
 
184
257
  onAuthClick(event: Event): void {
185
258
  const customEvent = event as CustomEvent<{ action: 'sign-in' | 'sign-out' }>;
186
259
  customEvent.preventDefault();
187
260
 
188
261
  if (customEvent.detail.action === 'sign-out') {
189
- this.signedIn.set(false);
190
- this.userName.set(undefined);
262
+ this.signedIn = false;
191
263
  window.location.href = ACCOUNT_LOGIN_HREF;
192
264
  return;
193
265
  }
@@ -197,62 +269,134 @@ export class App {
197
269
  }
198
270
  ```
199
271
 
272
+ **`src/app/app.component.html`** (Angular 16 — use `*ngIf`, not `@if`):
273
+
200
274
  ```html
201
- <!-- src/app/app.html -->
202
- <weg-header
203
- [layout]="layoutData()"
204
- [signedIn]="signedIn()"
205
- [userName]="userName()"
206
- (wegAuthClick)="onAuthClick($event)"
207
- ></weg-header>
275
+ <ng-container *ngIf="layout$ | async as layout">
276
+ <weg-header
277
+ [layout]="layout"
278
+ [signedIn]="signedIn"
279
+ [userName]="userName"
280
+ (wegAuthClick)="onAuthClick($event)"
281
+ ></weg-header>
282
+
283
+ <main>
284
+ <router-outlet></router-outlet>
285
+ </main>
286
+
287
+ <weg-footer [layout]="layout"></weg-footer>
288
+ </ng-container>
289
+ ```
290
+
291
+ Add `CommonModule` or `NgIf` + `AsyncPipe` to `imports` if not already present.
208
292
 
209
- <router-outlet />
293
+ ---
210
294
 
211
- <weg-footer [layout]="layoutData()"></weg-footer>
295
+ ## Step 9 — Verify
296
+
297
+ 1. Open DevTools → Elements → select `<weg-header>`.
298
+ 2. In the console:
299
+
300
+ ```js
301
+ $0.layout // must be a plain object, not undefined
302
+ $0.signedIn // boolean
303
+ $0.userName // string or undefined
212
304
  ```
213
305
 
214
- HTTP with signals: **[Step 7B](./angular-integration-guide.md#step-7b--http-with-signals--tosignal-pairs-with-6b)** (`toSignal` + same `LayoutService`).
306
+ If `layout` looks like `"[object Object]"`, you used attribute binding instead of `[layout]`.
307
+
308
+ ---
215
309
 
216
- ## Header: `signed-in`, `user-name`, `wegAuthClick`
310
+ ## Layout shape
217
311
 
218
- | Input / output | Binding (6A) | Binding (6B) | Notes |
219
- | --- | --- | --- | --- |
220
- | CMS nav | `[layout]="layoutData"` | `[layout]="layoutData()"` | `header.menu` — groups (`items`) and flat links (`href`) when signed out |
221
- | Session state | `[signedIn]="signedIn"` | `[signedIn]="signedIn()"` | `true` → built-in signed-in nav |
222
- | User name | `[userName]="userName"` | `[userName]="userName()"` | Manage Account label when signed in |
223
- | Auth click | `(wegAuthClick)="onAuthClick($event)"` | `detail.action`: `'sign-in'` \| `'sign-out'` |
224
- | Prevent default | `preventDefault()` in handler | Stops component default navigation |
312
+ Both tags accept one **`layout`** object with `header` and `footer` keys — **not** a bare array at the top level.
313
+
314
+ Full reference: [`dummy-data.json`](../src/assets/dummy-data.json) or [`GET /api/layout`](https://weg-payload-test.vercel.app/api/layout).
315
+
316
+ ```json
317
+ {
318
+ "header": {
319
+ "menu": [
320
+ { "label": "Find a job", "items": [{ "label": "Graduates", "href": "…" }] },
321
+ { "label": "Career advice", "href": "…" },
322
+ { "label": "Sign in", "href": "…" }
323
+ ]
324
+ },
325
+ "footer": {
326
+ "menu": [[{ "label": "About WEG", "href": "…" }]],
327
+ "social": [{ "platform": "LinkedIn", "href": "…" }],
328
+ "credits": "…",
329
+ "copyright": "…"
330
+ }
331
+ }
332
+ ```
225
333
 
226
- **Signed-in nav (built in):** Find a job, Dashboard, Manage Account, Sign out.
334
+ ### API returns separate arrays?
227
335
 
228
- Logo **image** uses `layout.header.logoSrc` (bundled if omitted). Logo **link** always goes to WEG home.
336
+ If your API does not return one `{ header, footer }` object, merge in a service:
229
337
 
230
- ## Footer
338
+ ```ts
339
+ forkJoin({
340
+ menuGroups: this.http.get<LayoutData['header']>('/api/nav/menu'),
341
+ flatLinks: this.http.get<LayoutData['header']>('/api/nav/links'),
342
+ footer: this.http.get<LayoutData['footer']>('/api/footer'),
343
+ }).pipe(
344
+ map(({ menuGroups, flatLinks, footer }) => ({
345
+ header: { menu: [...menuGroups, ...flatLinks, HEADER_SIGN_IN] },
346
+ footer,
347
+ })),
348
+ );
349
+ ```
231
350
 
232
- `<weg-footer>` only needs `[layout]`. See [`dummy-data.json`](../src/assets/dummy-data.json) for `footer` shape.
351
+ ---
233
352
 
234
353
  ## Troubleshooting
235
354
 
236
- | Symptom | Cause / fix |
355
+ | Symptom | Fix |
356
+ | --- | --- |
357
+ | `'weg-header'` is not a known element | `CUSTOM_ELEMENTS_SCHEMA` on the component that owns the template |
358
+ | Header/footer empty | `defineCustomElements()` before bootstrap |
359
+ | Nav empty after passing data | `[layout]` must be `{ header, footer }`, not a bare array |
360
+ | Auth always Sign in | Bind `[signedIn]` from session state |
361
+ | Generic Manage Account | Pass `[userName]` when signed in |
362
+ | `Mixin<const …>` / TS1139 in `stencil-public-runtime.d.ts` | Add `skipLibCheck: true` and/or upgrade to TypeScript 5.0+ |
363
+ | Cannot resolve `weg-shared-layout/loader` | Set `moduleResolution` to `bundler` or `node16` |
364
+ | SSR: `document is not defined` | Guard: `if (typeof window !== 'undefined') defineCustomElements()` |
365
+
366
+ ### TypeScript 4.9 + Stencil errors
367
+
368
+ Stencil ships `.d.ts` files with TypeScript 5 syntax. On Angular 16 with TS 4.9:
369
+
370
+ 1. Add **`skipLibCheck: true`** (recommended), or
371
+ 2. Upgrade to **TypeScript 5.0–5.1** (supported by Angular 16.1+): `npm i -D typescript@~5.1.6`
372
+
373
+ For typing only, avoid pulling Stencil runtime declarations:
374
+
375
+ ```ts
376
+ import type { LayoutData } from 'weg-shared-layout/layout-data';
377
+ // or
378
+ export type LayoutData = typeof layoutFixture; // from dummy-data.json
379
+ ```
380
+
381
+ ---
382
+
383
+ ## File map
384
+
385
+ | File | Role |
237
386
  | --- | --- |
238
- | `'weg-header'` / `'weg-footer'` is not a known element | `CUSTOM_ELEMENTS_SCHEMA` on the template's component |
239
- | Header/footer empty | `defineCustomElements()` before bootstrap, or missing `[layout]` |
240
- | Nav empty after passing an array | `[layout]` must be `{ header, footer }`, not a bare array |
241
- | Auth always Sign in | `[signedIn]` not bound or still `false` |
242
- | Manage Account generic | `[userName]` not set when signed in |
243
- | SSR: `document is not defined` | Guard `defineCustomElements()` with `typeof window !== 'undefined'` |
244
- | `stencil-public-runtime.d.ts` / `Mixin<const …>` errors | TypeScript 4.9 vs Stencil 5 `.d.ts` | **[angular-16-compatibility.md](./angular-16-compatibility.md)** |
245
- | Cannot resolve `weg-shared-layout/weg-header` | Old `moduleResolution` | Loader in `main.ts` or `bundler` / `node16` — **[angular-16-compatibility.md](./angular-16-compatibility.md)** |
387
+ | `src/main.ts` | `defineCustomElements()` then bootstrap |
388
+ | `tsconfig.json` | `skipLibCheck`, `resolveJsonModule`, `moduleResolution` |
389
+ | `src/app/layout.types.ts` | `export type LayoutData = typeof layoutFixture` |
390
+ | `src/app/auth.ts` | `HEADER_SIGN_IN`, `ACCOUNT_LOGIN_HREF` |
391
+ | `src/app/layout.service.ts` | HTTP / API mapping (optional) |
392
+ | `src/app/app.component.ts` | Shell: schema, layout, auth handler |
393
+ | `src/app/app.component.html` | `<weg-header>`, `<router-outlet>`, `<weg-footer>` |
246
394
 
247
- More detail: **[integration guide § Troubleshooting](./angular-integration-guide.md#troubleshooting)**.
395
+ ---
248
396
 
249
397
  ## See also
250
398
 
251
- - **[Documentation index](./README.md)**
252
- - **[In-repo Angular 16 demo](../demo/angular16/README.md)**
253
- - **[Angular 16 / TS 4.9 compatibility](./angular-16-compatibility.md)** — `stencil-public-runtime` errors, subpath imports
254
- - **[Angular integration guide (step-by-step)](./angular-integration-guide.md)**
255
- - **[React SPA](./react.md)**
256
- - **[Next.js App Router](./nextjs.md)**
257
- - **[Plain HTML / vanilla JS](./vanilla.md)**
258
- - **[Package readme](../readme.md)**
399
+ - [Documentation index](./README.md)
400
+ - [In-repo Angular 16 demo](../demo/angular16/README.md)
401
+ - [Package readme](../readme.md)
402
+ - [React SPA](./react.md) · [Next.js](./nextjs.md) · [Vanilla JS](./vanilla.md)
package/docs/nextjs.md CHANGED
@@ -232,6 +232,7 @@ Wire **`signedIn`** and **`userName`** from your auth provider (session hook / c
232
232
  | --- | --- | --- |
233
233
  | `layout.header.menu` | CMS nav rendered (groups + flat links incl. Sign in) | Ignored — built-in nav used |
234
234
  | `layout.header.logoSrc` | Logo image URL (bundled if omitted) | Built-in bundled logo |
235
+ | `layout.header.logoHref` | Logo link URL | WEG homepage |
235
236
  | `signed-in` prop | `false` | `true` — session flag from host app |
236
237
  | `user-name` prop | — | User's first name on Manage Account |
237
238
  | `wegAuthClick` event | `'sign-in'` on Sign in click | `'sign-out'` on Sign out click |
@@ -239,7 +240,7 @@ Wire **`signedIn`** and **`userName`** from your auth provider (session hook / c
239
240
 
240
241
  **Signed-in nav (built into the component):** Find a job, Dashboard, Manage Account, Sign out.
241
242
 
242
- The logo **image** uses `layout.header.logoSrc` when signed out (bundled if omitted). The logo **link** always goes to WEG home.
243
+ The logo **image** uses `layout.header.logoSrc` when signed out (bundled if omitted). The logo **link** uses `layout.header.logoHref` when provided; otherwise it defaults to the WEG homepage.
243
244
 
244
245
  ## Passing `layout` — quick reference
245
246
 
@@ -58,7 +58,7 @@ Use `npm publish --dry-run` if you want to exercise the full pack pipeline witho
58
58
 
59
59
  ## What consumers import
60
60
 
61
- Documented in [docs/README.md](./README.md): `loader`, `dummy-data.json`, `layout-data` (types), and per-tag subpaths. Angular 16 apps need modern `moduleResolution` or the loader-only pattern — [angular-16-compatibility.md](./angular-16-compatibility.md).
61
+ Documented in [docs/README.md](./README.md): `loader`, `dummy-data.json`, `layout-data` (types), and per-tag subpaths. Angular 16 apps need modern `moduleResolution` or the loader-only pattern — [angular.md](./angular.md).
62
62
 
63
63
  ## CI
64
64
 
package/docs/react.md CHANGED
@@ -39,7 +39,7 @@ import { defineCustomElements } from 'weg-shared-layout/loader';
39
39
  defineCustomElements();
40
40
  ```
41
41
 
42
- **Alternative** — side-effect imports per tag (requires modern `moduleResolution`; see [angular-16-compatibility](./angular-16-compatibility.md#error-2-cannot-find-module-weg-shared-layoutweg-header)):
42
+ **Alternative** — side-effect imports per tag (requires modern `moduleResolution`; see [angular.md § Troubleshooting](./angular.md#troubleshooting)):
43
43
 
44
44
  ```ts
45
45
  import 'weg-shared-layout/weg-header';
package/docs/vanilla.md CHANGED
@@ -13,7 +13,7 @@ Payload shape: [`dummy-data.json`](../src/assets/dummy-data.json) (see [readme](
13
13
 
14
14
  ## Install & register
15
15
 
16
- With a bundler that resolves `node_modules` and package **`exports`** (TypeScript: `resolveJsonModule` + `moduleResolution` `bundler` or `node16` — see [angular-16-compatibility](./angular-16-compatibility.md)):
16
+ With a bundler that resolves `node_modules` and package **`exports`** (TypeScript: `resolveJsonModule` + `moduleResolution` `bundler` or `node16` — see [angular.md](./angular.md)):
17
17
 
18
18
  ```html
19
19
  <weg-header id="header"></weg-header>
@@ -61,6 +61,7 @@ Or pass a JSON **string** on the `layout` attribute:
61
61
  | Field | Purpose |
62
62
  | --- | --- |
63
63
  | `header.logoSrc` | Logo image URL (bundled if omitted) |
64
+ | `header.logoHref` | Logo link URL (WEG homepage if omitted) |
64
65
  | `header.menu` | Unified nav — groups with `items[]`, flat links with `href` (incl. Sign in) |
65
66
 
66
67
  See [`dummy-data.json`](../src/assets/dummy-data.json) for production URL examples.
@@ -117,7 +118,7 @@ header.addEventListener('wegAuthClick', (event) => {
117
118
  | `'sign-in'` | Browser follows the Sign in menu entry's `href` |
118
119
  | `'sign-out'` | Redirects to built-in sign-out URL |
119
120
 
120
- Logo **image** uses `header.logoSrc` (bundled if omitted). Logo **link** always goes to WEG home.
121
+ Logo **image** uses `header.logoSrc` (bundled if omitted). Logo **link** uses `header.logoHref` when provided; otherwise it goes to the WEG homepage.
121
122
 
122
123
  ## Without a bundler
123
124
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "weg-shared-layout",
3
- "version": "0.0.32",
3
+ "version": "0.0.34",
4
4
  "description": "Shared layout Web Components built with Stencil",
5
5
  "main": "dist/index.cjs.js",
6
6
  "module": "dist/index.js",
package/readme.md CHANGED
@@ -41,6 +41,7 @@ Full reference: [`src/assets/dummy-data.json`](src/assets/dummy-data.json). Sign
41
41
  | Field | Used when | Notes |
42
42
  | --- | --- | --- |
43
43
  | `header.logoSrc` | Signed out | Optional CMS logo URL; bundled PNG if omitted |
44
+ | `header.logoHref` | Always | Optional logo link URL; WEG homepage if omitted |
44
45
  | `header.menu` | Signed out | Groups use `items`; flat links use `href` |
45
46
  | `footer.menu` | Always | `LayoutLink[][]` — one column per inner array |
46
47
  | `footer.social` | Always | LinkedIn, Instagram, TikTok, or YouTube |
@@ -62,7 +63,7 @@ header.addEventListener('wegAuthClick', (event) => {
62
63
  });
63
64
  ```
64
65
 
65
- - **From npm:** `import layout from 'weg-shared-layout/dummy-data.json'` — in TypeScript set `resolveJsonModule` and `moduleResolution` to `bundler` or `node16` (see [docs/angular-16-compatibility.md](./docs/angular-16-compatibility.md)).
66
+ - **From npm:** `import layout from 'weg-shared-layout/dummy-data.json'` — in TypeScript set `resolveJsonModule` and `moduleResolution` to `bundler` or `node16` (see [docs/angular.md](./docs/angular.md)).
66
67
  - **In this repo:** [`src/assets/dummy-data.json`](src/assets/dummy-data.json)
67
68
 
68
69
  ### Package imports (TypeScript / bundlers)
@@ -81,10 +82,8 @@ Full index: **[docs/README.md](./docs/README.md)**.
81
82
 
82
83
  | Guide | Doc |
83
84
  | --- | --- |
84
- | Angular (quick start) | [docs/angular.md](./docs/angular.md) |
85
- | Angular (step-by-step integration) | [docs/angular-integration-guide.md](./docs/angular-integration-guide.md) |
86
- | Angular 16 / TypeScript 4.9 | [docs/angular-16-compatibility.md](./docs/angular-16-compatibility.md) |
87
- | Angular 16 demo (in-repo, npm-style imports) | [demo/angular16/README.md](./demo/angular16/README.md) |
85
+ | Angular 16 | [docs/angular.md](./docs/angular.md) |
86
+ | Angular 16 demo (runnable) | [demo/angular16/README.md](./demo/angular16/README.md) |
88
87
  | React (SPA, client-only) | [docs/react.md](./docs/react.md) |
89
88
  | Next.js (App Router) | [docs/nextjs.md](./docs/nextjs.md) |
90
89
  | Plain HTML / vanilla JS | [docs/vanilla.md](./docs/vanilla.md) |