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/dist/cjs/weg-footer_2.cjs.entry.js +5 -3
- package/dist/collection/components/weg-header/weg-header.js +5 -3
- package/dist/components/weg-header.js +1 -1
- package/dist/esm/weg-footer_2.entry.js +5 -3
- package/dist/types/types/layout-data.d.ts +1 -0
- package/dist/weg-shared-layout/p-910c4f50.entry.js +1 -0
- package/dist/weg-shared-layout/weg-shared-layout.esm.js +1 -1
- package/docs/README.md +4 -6
- package/docs/angular.md +259 -115
- package/docs/nextjs.md +2 -1
- package/docs/publishing.md +1 -1
- package/docs/react.md +1 -1
- package/docs/vanilla.md +3 -2
- package/package.json +1 -1
- package/readme.md +4 -5
- package/dist/weg-shared-layout/p-674d7d98.entry.js +0 -1
- package/docs/angular-16-compatibility.md +0 -250
- package/docs/angular-integration-guide.md +0 -1035
package/docs/angular.md
CHANGED
|
@@ -1,61 +1,85 @@
|
|
|
1
|
-
# Angular
|
|
1
|
+
# Angular 16 integration
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Step-by-step guide for **Angular 16** (standalone or NgModule). Uses plain component properties — no signals.
|
|
4
4
|
|
|
5
|
-
|
|
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
|
-
|
|
7
|
+
Newer Angular (signals): [weg-angular-demo](https://github.com/jobsac/weg-angular-demo) — same layout ideas, different syntax.
|
|
11
8
|
|
|
12
|
-
|
|
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
|
-
##
|
|
11
|
+
## Checklist
|
|
21
12
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
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
|
-
|
|
25
|
+
---
|
|
28
26
|
|
|
29
|
-
## 1
|
|
27
|
+
## Step 1 — Install
|
|
30
28
|
|
|
31
29
|
```bash
|
|
32
30
|
npm i weg-shared-layout
|
|
33
31
|
```
|
|
34
32
|
|
|
35
|
-
|
|
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
|
-
|
|
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(
|
|
73
|
+
bootstrapApplication(AppComponent, appConfig).catch((err) => console.error(err));
|
|
49
74
|
```
|
|
50
75
|
|
|
51
|
-
|
|
76
|
+
If header/footer tags appear but nav is empty, registration did not run or ran too late.
|
|
52
77
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
```
|
|
78
|
+
**NgModule apps:** same `defineCustomElements()` call, then `platformBrowserDynamic().bootstrapModule(AppModule)`.
|
|
79
|
+
|
|
80
|
+
---
|
|
57
81
|
|
|
58
|
-
##
|
|
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
|
-
|
|
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
|
-
|
|
93
|
+
```ts
|
|
94
|
+
import type { LayoutData } from 'weg-shared-layout/layout-data';
|
|
95
|
+
```
|
|
80
96
|
|
|
81
|
-
|
|
97
|
+
---
|
|
82
98
|
|
|
83
|
-
|
|
99
|
+
## Step 5 — Auth URLs
|
|
84
100
|
|
|
85
|
-
|
|
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
|
-
|
|
113
|
+
---
|
|
98
114
|
|
|
99
|
-
|
|
115
|
+
## Step 6 — Shell component
|
|
100
116
|
|
|
101
|
-
|
|
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
|
|
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
|
-
<
|
|
171
|
+
<main>
|
|
172
|
+
<router-outlet></router-outlet>
|
|
173
|
+
</main>
|
|
155
174
|
|
|
156
175
|
<weg-footer [layout]="layoutData"></weg-footer>
|
|
157
176
|
```
|
|
158
177
|
|
|
159
|
-
|
|
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
|
-
|
|
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
|
-
|
|
165
|
-
import { Component, CUSTOM_ELEMENTS_SCHEMA
|
|
232
|
+
import { AsyncPipe } from '@angular/common';
|
|
233
|
+
import { Component, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
|
|
166
234
|
import { RouterOutlet } from '@angular/router';
|
|
167
|
-
import
|
|
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
|
-
|
|
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
|
|
179
|
-
|
|
248
|
+
export class AppComponent {
|
|
249
|
+
layout$: Observable<LayoutData>;
|
|
250
|
+
signedIn = false;
|
|
251
|
+
userName?: string;
|
|
180
252
|
|
|
181
|
-
|
|
182
|
-
|
|
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
|
|
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
|
-
|
|
202
|
-
<weg-header
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
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
|
-
|
|
293
|
+
---
|
|
210
294
|
|
|
211
|
-
|
|
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
|
-
|
|
306
|
+
If `layout` looks like `"[object Object]"`, you used attribute binding instead of `[layout]`.
|
|
307
|
+
|
|
308
|
+
---
|
|
215
309
|
|
|
216
|
-
##
|
|
310
|
+
## Layout shape
|
|
217
311
|
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
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
|
-
|
|
334
|
+
### API returns separate arrays?
|
|
227
335
|
|
|
228
|
-
|
|
336
|
+
If your API does not return one `{ header, footer }` object, merge in a service:
|
|
229
337
|
|
|
230
|
-
|
|
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
|
-
|
|
351
|
+
---
|
|
233
352
|
|
|
234
353
|
## Troubleshooting
|
|
235
354
|
|
|
236
|
-
| Symptom |
|
|
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
|
-
| `
|
|
239
|
-
|
|
|
240
|
-
|
|
|
241
|
-
|
|
|
242
|
-
|
|
|
243
|
-
|
|
|
244
|
-
| `
|
|
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
|
-
|
|
395
|
+
---
|
|
248
396
|
|
|
249
397
|
## See also
|
|
250
398
|
|
|
251
|
-
-
|
|
252
|
-
-
|
|
253
|
-
-
|
|
254
|
-
-
|
|
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**
|
|
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
|
|
package/docs/publishing.md
CHANGED
|
@@ -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
|
|
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
|
|
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
|
+
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**
|
|
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
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
|
|
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
|
|
85
|
-
| Angular (
|
|
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) |
|