weg-shared-layout 0.0.17 → 0.0.18
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 +17 -8
- package/dist/collection/components/weg-header/signed-in-layout.js +6 -8
- package/dist/collection/constants/weg-urls.js +18 -0
- package/dist/components/weg-header.js +1 -1
- package/dist/esm/weg-footer_2.entry.js +17 -8
- package/dist/types/components/weg-header/signed-in-layout.d.ts +1 -1
- package/dist/types/constants/weg-urls.d.ts +18 -0
- package/dist/weg-shared-layout/p-82bf5463.entry.js +1 -0
- package/dist/weg-shared-layout/weg-shared-layout.esm.js +1 -1
- package/docs/angular.md +18 -21
- package/docs/nextjs.md +49 -21
- package/docs/react.md +40 -44
- package/docs/vanilla.md +43 -17
- package/package.json +3 -2
- package/readme.md +53 -23
- package/src/constants/weg-urls.ts +23 -0
- package/dist/weg-shared-layout/p-444bffb0.entry.js +0 -1
package/docs/angular.md
CHANGED
|
@@ -9,7 +9,7 @@ Assumes Angular 17+ with **standalone** components (default for `ng new`).
|
|
|
9
9
|
| `<weg-header>` | `import 'weg-shared-layout/weg-header';` |
|
|
10
10
|
| `<weg-footer>` | `import 'weg-shared-layout/weg-footer';` |
|
|
11
11
|
|
|
12
|
-
Both accept the same `layout` payload ([`dummy-data.json`](../src/assets/dummy-data.json)). `<weg-header>` also accepts **`signed-in
|
|
12
|
+
Both accept the same `layout` payload ([`dummy-data.json`](../src/assets/dummy-data.json)). `<weg-header>` also accepts **`signed-in`**, **`user-name`**, and emits **`wegAuthClick`**.
|
|
13
13
|
|
|
14
14
|
## 1. Install
|
|
15
15
|
|
|
@@ -33,8 +33,6 @@ defineCustomElements();
|
|
|
33
33
|
bootstrapApplication(App, appConfig).catch((err) => console.error(err));
|
|
34
34
|
```
|
|
35
35
|
|
|
36
|
-
If `defineCustomElements` is async in your Stencil build, `await` it before bootstrapping.
|
|
37
|
-
|
|
38
36
|
**Alternative:** side-effect import only the tags you need (no loader call):
|
|
39
37
|
|
|
40
38
|
```ts
|
|
@@ -54,6 +52,7 @@ Use **`[layout]="..."`** so Angular sets the JavaScript `layout` property, not a
|
|
|
54
52
|
// src/app/app.ts
|
|
55
53
|
import { Component, CUSTOM_ELEMENTS_SCHEMA, signal } from '@angular/core';
|
|
56
54
|
import { RouterOutlet } from '@angular/router';
|
|
55
|
+
import { ACCOUNT_LOGIN_HREF, HEADER_SIGN_IN } from '../auth';
|
|
57
56
|
import layoutFixture from 'weg-shared-layout/dummy-data.json';
|
|
58
57
|
|
|
59
58
|
@Component({
|
|
@@ -66,19 +65,19 @@ import layoutFixture from 'weg-shared-layout/dummy-data.json';
|
|
|
66
65
|
export class App {
|
|
67
66
|
protected readonly layoutData = signal(layoutFixture);
|
|
68
67
|
protected readonly signedIn = signal(false);
|
|
68
|
+
protected readonly userName = signal<string | undefined>(undefined);
|
|
69
69
|
|
|
70
70
|
protected onAuthClick(event: Event) {
|
|
71
71
|
const customEvent = event as CustomEvent<{ action: 'sign-in' | 'sign-out' }>;
|
|
72
72
|
customEvent.preventDefault();
|
|
73
73
|
|
|
74
74
|
if (customEvent.detail.action === 'sign-out') {
|
|
75
|
-
// call your logout service
|
|
76
75
|
this.signedIn.set(false);
|
|
76
|
+
window.location.href = ACCOUNT_LOGIN_HREF;
|
|
77
77
|
return;
|
|
78
78
|
}
|
|
79
79
|
|
|
80
|
-
|
|
81
|
-
window.location.href = '/account/login';
|
|
80
|
+
window.location.href = layoutFixture.header.signIn?.href ?? HEADER_SIGN_IN.href;
|
|
82
81
|
}
|
|
83
82
|
}
|
|
84
83
|
```
|
|
@@ -88,6 +87,7 @@ export class App {
|
|
|
88
87
|
<weg-header
|
|
89
88
|
[layout]="layoutData()"
|
|
90
89
|
[signedIn]="signedIn()"
|
|
90
|
+
[userName]="userName()"
|
|
91
91
|
(wegAuthClick)="onAuthClick($event)"
|
|
92
92
|
></weg-header>
|
|
93
93
|
|
|
@@ -98,17 +98,23 @@ export class App {
|
|
|
98
98
|
|
|
99
99
|
Enable `resolveJsonModule` in `tsconfig.app.json` if you import `dummy-data.json`.
|
|
100
100
|
|
|
101
|
+
Define auth URLs in `src/app/auth.ts` (same shape as the React/Next examples).
|
|
102
|
+
|
|
101
103
|
In production, replace `layoutFixture` with data from your services; keep the same object shape.
|
|
102
104
|
|
|
103
|
-
## Header: `signed-in` and `wegAuthClick`
|
|
105
|
+
## Header: `signed-in`, `user-name`, and `wegAuthClick`
|
|
104
106
|
|
|
105
107
|
| Input / output | Binding | Notes |
|
|
106
108
|
| --- | --- | --- |
|
|
107
|
-
|
|
|
109
|
+
| CMS nav | `[layout]="layoutData()"` | `dropdowns`, `links`, `signIn` used when signed out |
|
|
110
|
+
| Session state | `[signedIn]="signedIn()"` | When `true`, CMS nav is ignored; built-in signed-in nav is shown |
|
|
111
|
+
| User name | `[userName]="userName()"` | First name on Manage Account (signed in only) |
|
|
108
112
|
| Auth click | `(wegAuthClick)="onAuthClick($event)"` | `event.detail.action` is `'sign-in'` or `'sign-out'` |
|
|
109
|
-
| Prevent default | `event.preventDefault()` in handler | Stops link navigation /
|
|
113
|
+
| Prevent default | `event.preventDefault()` in handler | Stops link navigation / redirect |
|
|
114
|
+
|
|
115
|
+
**Signed-in nav (built into the component):** Find a job, Dashboard, Manage Account, Sign out.
|
|
110
116
|
|
|
111
|
-
Logo is bundled
|
|
117
|
+
Logo **image** is bundled. Logo **link** uses `layout.header.logoHref` when signed out (defaults to WEG home).
|
|
112
118
|
|
|
113
119
|
## Footer
|
|
114
120
|
|
|
@@ -119,20 +125,11 @@ Logo is bundled in the component — not configurable via `layout`.
|
|
|
119
125
|
| Symptom | Cause / fix |
|
|
120
126
|
| --- | --- |
|
|
121
127
|
| `'weg-header'` / `'weg-footer'` is not a known element | Add `CUSTOM_ELEMENTS_SCHEMA` on the component template that uses the tag. |
|
|
122
|
-
| Header/footer empty | `defineCustomElements()` not called before bootstrap, tag bundle not imported, or `layout` not set
|
|
128
|
+
| Header/footer empty | `defineCustomElements()` not called before bootstrap, tag bundle not imported, or `layout` not set. |
|
|
123
129
|
| Auth always shows Sign in | `[signedIn]` not bound or still `false`. |
|
|
130
|
+
| Manage Account shows generic label | `[userName]` not set when signed in. |
|
|
124
131
|
| SSR: `document is not defined` | Guard `defineCustomElements()` with `typeof window !== 'undefined'` or `isPlatformBrowser`. |
|
|
125
132
|
|
|
126
|
-
## TypeScript typings
|
|
127
|
-
|
|
128
|
-
```ts
|
|
129
|
-
/// <reference types="weg-shared-layout/dist/types/components" />
|
|
130
|
-
```
|
|
131
|
-
|
|
132
|
-
## Legacy `NgModule`
|
|
133
|
-
|
|
134
|
-
Add `CUSTOM_ELEMENTS_SCHEMA` on the module that declares components using these tags. `defineCustomElements()` in `main.ts` is still required when using the loader.
|
|
135
|
-
|
|
136
133
|
## See also
|
|
137
134
|
|
|
138
135
|
- **[React SPA](./react.md)**
|
package/docs/nextjs.md
CHANGED
|
@@ -6,10 +6,10 @@ Guide for **Next.js 13+ App Router** (`app/` directory). For Vite/CRA-style clie
|
|
|
6
6
|
|
|
7
7
|
| Tag | Purpose |
|
|
8
8
|
| --- | --- |
|
|
9
|
-
| `<weg-header>` | Site header — logo (
|
|
9
|
+
| `<weg-header>` | Site header — bundled logo, CMS nav (signed out), built-in nav (signed in), Sign in / Manage Account / Sign out |
|
|
10
10
|
| `<weg-footer>` | Site footer — social, columns, legal text |
|
|
11
11
|
|
|
12
|
-
Both accept **`layout`** (JSON string recommended in Next). `<weg-header>` also accepts **`signed-in
|
|
12
|
+
Both accept **`layout`** (JSON string recommended in Next). `<weg-header>` also accepts **`signed-in`**, **`user-name`**, and emits **`wegAuthClick`**.
|
|
13
13
|
|
|
14
14
|
## Why Next.js is different
|
|
15
15
|
|
|
@@ -50,7 +50,21 @@ const nextConfig: NextConfig = {
|
|
|
50
50
|
export default nextConfig;
|
|
51
51
|
```
|
|
52
52
|
|
|
53
|
-
## 2.
|
|
53
|
+
## 2. Auth constants (host app)
|
|
54
|
+
|
|
55
|
+
Keep sign-in/out URLs in your app — not imported from `weg-shared-layout`:
|
|
56
|
+
|
|
57
|
+
```ts
|
|
58
|
+
// src/auth.ts
|
|
59
|
+
export const HEADER_SIGN_IN = {
|
|
60
|
+
label: 'Sign in',
|
|
61
|
+
href: 'https://account.warwickemploymentgroup.com/account/login',
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
export const ACCOUNT_LOGIN_HREF = HEADER_SIGN_IN.href;
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## 3. Client layout components
|
|
54
68
|
|
|
55
69
|
```tsx
|
|
56
70
|
// src/components/layout/Header.tsx
|
|
@@ -58,26 +72,29 @@ export default nextConfig;
|
|
|
58
72
|
|
|
59
73
|
import { useCallback } from 'react';
|
|
60
74
|
import { defineCustomElements } from 'weg-shared-layout/loader';
|
|
75
|
+
import { ACCOUNT_LOGIN_HREF, HEADER_SIGN_IN } from '@/auth';
|
|
61
76
|
import 'weg-shared-layout/weg-header';
|
|
62
77
|
|
|
63
78
|
defineCustomElements();
|
|
64
79
|
|
|
65
80
|
type LayoutData = {
|
|
66
81
|
header?: {
|
|
82
|
+
logoHref?: string;
|
|
67
83
|
dropdowns?: { label: string; items: { label: string; href: string }[] }[];
|
|
68
84
|
links?: { label: string; href: string }[];
|
|
69
85
|
signIn?: { label: string; href: string };
|
|
70
|
-
signOut?: { label: string; href?: string };
|
|
71
86
|
};
|
|
72
87
|
};
|
|
73
88
|
|
|
74
89
|
export function Header({
|
|
75
90
|
layout,
|
|
76
91
|
signedIn,
|
|
92
|
+
userName,
|
|
77
93
|
onSignedInChange,
|
|
78
94
|
}: {
|
|
79
95
|
layout: LayoutData;
|
|
80
96
|
signedIn: boolean;
|
|
97
|
+
userName?: string;
|
|
81
98
|
onSignedInChange?: (signedIn: boolean) => void;
|
|
82
99
|
}) {
|
|
83
100
|
const onAuthClick = useCallback(
|
|
@@ -85,12 +102,12 @@ export function Header({
|
|
|
85
102
|
event.preventDefault();
|
|
86
103
|
|
|
87
104
|
if (event.detail.action === 'sign-out') {
|
|
88
|
-
// your logout(), then:
|
|
89
105
|
onSignedInChange?.(false);
|
|
106
|
+
window.location.href = ACCOUNT_LOGIN_HREF;
|
|
90
107
|
return;
|
|
91
108
|
}
|
|
92
109
|
|
|
93
|
-
window.location.href = layout.header?.signIn?.href ??
|
|
110
|
+
window.location.href = layout.header?.signIn?.href ?? HEADER_SIGN_IN.href;
|
|
94
111
|
},
|
|
95
112
|
[layout, onSignedInChange],
|
|
96
113
|
);
|
|
@@ -98,9 +115,9 @@ export function Header({
|
|
|
98
115
|
return (
|
|
99
116
|
<weg-header
|
|
100
117
|
layout={JSON.stringify(layout)}
|
|
101
|
-
|
|
118
|
+
signedIn={signedIn}
|
|
119
|
+
{...(userName ? { userName } : {})}
|
|
102
120
|
suppressHydrationWarning
|
|
103
|
-
// @ts-expect-error Stencil custom event
|
|
104
121
|
onWegAuthClick={onAuthClick}
|
|
105
122
|
/>
|
|
106
123
|
);
|
|
@@ -137,10 +154,16 @@ export function SiteChrome({
|
|
|
137
154
|
children: React.ReactNode;
|
|
138
155
|
}) {
|
|
139
156
|
const [signedIn, setSignedIn] = useState(false);
|
|
157
|
+
const userName = signedIn ? 'Alex' : undefined; // from your session
|
|
140
158
|
|
|
141
159
|
return (
|
|
142
160
|
<>
|
|
143
|
-
<Header
|
|
161
|
+
<Header
|
|
162
|
+
layout={layout}
|
|
163
|
+
signedIn={signedIn}
|
|
164
|
+
userName={userName}
|
|
165
|
+
onSignedInChange={setSignedIn}
|
|
166
|
+
/>
|
|
144
167
|
{children}
|
|
145
168
|
<Footer layout={layout} />
|
|
146
169
|
</>
|
|
@@ -158,7 +181,7 @@ export function SiteChrome({
|
|
|
158
181
|
|
|
159
182
|
Do **not** pass `layout={layoutObject}` directly on the custom elements in Next.
|
|
160
183
|
|
|
161
|
-
##
|
|
184
|
+
## 4. Server layout
|
|
162
185
|
|
|
163
186
|
```tsx
|
|
164
187
|
// app/layout.tsx (Server Component)
|
|
@@ -176,7 +199,7 @@ export default function RootLayout({ children }: { children: React.ReactNode })
|
|
|
176
199
|
}
|
|
177
200
|
```
|
|
178
201
|
|
|
179
|
-
##
|
|
202
|
+
## 5. Production: fetch layout on the server
|
|
180
203
|
|
|
181
204
|
```tsx
|
|
182
205
|
// app/layout.tsx
|
|
@@ -205,19 +228,23 @@ export default async function RootLayout({ children }: { children: React.ReactNo
|
|
|
205
228
|
|
|
206
229
|
Pass the plain object into the Client Component; **stringify inside** the header/footer wrappers.
|
|
207
230
|
|
|
208
|
-
Wire **`signedIn`** from your auth provider (
|
|
231
|
+
Wire **`signedIn`** and **`userName`** from your auth provider (session hook / context in a client wrapper).
|
|
209
232
|
|
|
210
233
|
## Header auth reference
|
|
211
234
|
|
|
212
|
-
| API |
|
|
213
|
-
| --- | --- |
|
|
214
|
-
| `layout.header.
|
|
215
|
-
| `layout.header.
|
|
216
|
-
| `
|
|
217
|
-
| `
|
|
218
|
-
| `
|
|
235
|
+
| API | Signed out | Signed in |
|
|
236
|
+
| --- | --- | --- |
|
|
237
|
+
| `layout.header.dropdowns` / `links` | CMS nav rendered | Ignored — built-in nav used |
|
|
238
|
+
| `layout.header.signIn` | Sign in button | Not shown |
|
|
239
|
+
| `layout.header.logoHref` | Logo link target | Built-in WEG home URL |
|
|
240
|
+
| `signed-in` prop | `false` | `true` — session flag from host app |
|
|
241
|
+
| `user-name` prop | — | User's first name on Manage Account |
|
|
242
|
+
| `wegAuthClick` event | `'sign-in'` on Sign in click | `'sign-out'` on Sign out click |
|
|
243
|
+
| `event.preventDefault()` | Skip default navigation | Skip default redirect |
|
|
244
|
+
|
|
245
|
+
**Signed-in nav (built into the component):** Find a job, Dashboard, Manage Account, Sign out.
|
|
219
246
|
|
|
220
|
-
|
|
247
|
+
The logo **image** is bundled. The logo **link** uses `layout.header.logoHref` when signed out.
|
|
221
248
|
|
|
222
249
|
## Passing `layout` — quick reference
|
|
223
250
|
|
|
@@ -254,6 +281,7 @@ declare module 'react' {
|
|
|
254
281
|
| `document is not defined` | Loader in Server Component | Keep registration in `"use client"` files only. |
|
|
255
282
|
| Empty after hydration | Object passed to CE without stringify | `JSON.stringify` in client wrapper. |
|
|
256
283
|
| Logo missing | Stale package | Logo is inlined in `logo-data.ts`; rebuild / upgrade. |
|
|
284
|
+
| Header not clickable | Overlapping page content | `:host` uses `z-index: 20`; upgrade package if missing. |
|
|
257
285
|
| Auth not updating | `signed-in` only on server | Manage session in client state / context. |
|
|
258
286
|
| Hydration warning | Shadow DOM mismatch | `suppressHydrationWarning` on both tags. |
|
|
259
287
|
| Build error | Package not transpiled | `transpilePackages: ['weg-shared-layout']`. |
|
|
@@ -263,7 +291,7 @@ declare module 'react' {
|
|
|
263
291
|
- [ ] `weg-shared-layout` installed
|
|
264
292
|
- [ ] `transpilePackages` in `next.config`
|
|
265
293
|
- [ ] Client `Header.tsx` / `Footer.tsx` with loader, tag imports, `JSON.stringify`, `suppressHydrationWarning`
|
|
266
|
-
- [ ] Auth: `signed-in`
|
|
294
|
+
- [ ] Auth: `signed-in`, `user-name`, and `wegAuthClick` handler on header
|
|
267
295
|
- [ ] Server `layout.tsx` imports client chrome only (no `defineCustomElements` on server)
|
|
268
296
|
- [ ] Layout fetched or imported server-side, passed as serializable props
|
|
269
297
|
- [ ] TypeScript augmentation for `'weg-header'` and `'weg-footer'`
|
package/docs/react.md
CHANGED
|
@@ -6,12 +6,12 @@ Guide for **client-rendered** React apps (Vite, Create React App, etc.). If you
|
|
|
6
6
|
|
|
7
7
|
| Tag | Purpose |
|
|
8
8
|
| --- | --- |
|
|
9
|
-
| `<weg-header>` | Site header — logo (
|
|
9
|
+
| `<weg-header>` | Site header — bundled logo, CMS nav (signed out), built-in nav (signed in), Sign in / Manage Account / Sign out |
|
|
10
10
|
| `<weg-footer>` | Site footer — social links, columns, credits, copyright |
|
|
11
11
|
|
|
12
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)).
|
|
13
13
|
|
|
14
|
-
`<weg-header>` additionally accepts **`signed-in
|
|
14
|
+
`<weg-header>` additionally accepts **`signed-in`**, **`user-name`**, and emits **`wegAuthClick`**.
|
|
15
15
|
|
|
16
16
|
## Requirements
|
|
17
17
|
|
|
@@ -46,15 +46,6 @@ import 'weg-shared-layout/weg-header';
|
|
|
46
46
|
import 'weg-shared-layout/weg-footer';
|
|
47
47
|
```
|
|
48
48
|
|
|
49
|
-
**Alternative:** import individual tag bundles only (no loader):
|
|
50
|
-
|
|
51
|
-
```ts
|
|
52
|
-
import 'weg-shared-layout/weg-header';
|
|
53
|
-
import 'weg-shared-layout/weg-footer';
|
|
54
|
-
```
|
|
55
|
-
|
|
56
|
-
Use the loader when you may add more tags from this package later.
|
|
57
|
-
|
|
58
49
|
## 2. Layout shell
|
|
59
50
|
|
|
60
51
|
### Recommended: pass `layout` as an object (React 19+)
|
|
@@ -84,42 +75,63 @@ export function SiteLayout({ children }: { children: React.ReactNode }) {
|
|
|
84
75
|
|
|
85
76
|
## 3. Header auth
|
|
86
77
|
|
|
87
|
-
|
|
78
|
+
Define auth URLs once in your app:
|
|
79
|
+
|
|
80
|
+
```ts
|
|
81
|
+
// auth.ts
|
|
82
|
+
export const HEADER_SIGN_IN = {
|
|
83
|
+
label: 'Sign in',
|
|
84
|
+
href: 'https://account.warwickemploymentgroup.com/account/login',
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
export const ACCOUNT_LOGIN_HREF = HEADER_SIGN_IN.href;
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
### Signed out
|
|
88
91
|
|
|
89
|
-
|
|
92
|
+
Pass CMS/API layout with `dropdowns`, `links`, and `signIn`. Use [`dummy-data.json`](../src/assets/dummy-data.json) for the full shape. Keep auth URLs in a local file:
|
|
90
93
|
|
|
91
|
-
```
|
|
92
|
-
|
|
93
|
-
|
|
94
|
+
```ts
|
|
95
|
+
// auth.ts (host app)
|
|
96
|
+
export const HEADER_SIGN_IN = {
|
|
97
|
+
label: 'Sign in',
|
|
98
|
+
href: 'https://account.warwickemploymentgroup.com/account/login',
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
export const ACCOUNT_LOGIN_HREF = HEADER_SIGN_IN.href;
|
|
94
102
|
```
|
|
95
103
|
|
|
96
|
-
|
|
104
|
+
### Signed in
|
|
105
|
+
|
|
106
|
+
Set **`signed-in`** and optionally **`user-name`**. The component **ignores CMS nav** and shows built-in links: Find a job, Dashboard, Manage Account, Sign out.
|
|
97
107
|
|
|
98
108
|
```tsx
|
|
99
109
|
import { useCallback, useState } from 'react';
|
|
110
|
+
import { ACCOUNT_LOGIN_HREF, HEADER_SIGN_IN } from './auth';
|
|
100
111
|
import 'weg-shared-layout/weg-header';
|
|
101
112
|
import layout from 'weg-shared-layout/dummy-data.json';
|
|
102
113
|
|
|
103
114
|
export function SiteHeader() {
|
|
104
115
|
const [signedIn, setSignedIn] = useState(false);
|
|
116
|
+
const userName = signedIn ? 'Alex' : undefined;
|
|
105
117
|
|
|
106
118
|
const onAuthClick = useCallback((event: CustomEvent<{ action: 'sign-in' | 'sign-out' }>) => {
|
|
107
119
|
event.preventDefault();
|
|
108
120
|
|
|
109
121
|
if (event.detail.action === 'sign-out') {
|
|
110
|
-
// your logout(), then:
|
|
111
122
|
setSignedIn(false);
|
|
123
|
+
window.location.href = ACCOUNT_LOGIN_HREF;
|
|
112
124
|
return;
|
|
113
125
|
}
|
|
114
126
|
|
|
115
|
-
window.location.href =
|
|
127
|
+
window.location.href = layout.header.signIn?.href ?? HEADER_SIGN_IN.href;
|
|
116
128
|
}, []);
|
|
117
129
|
|
|
118
130
|
return (
|
|
119
131
|
<weg-header
|
|
120
132
|
layout={layout}
|
|
121
|
-
|
|
122
|
-
|
|
133
|
+
signedIn={signedIn}
|
|
134
|
+
{...(userName ? { userName } : {})}
|
|
123
135
|
onWegAuthClick={onAuthClick}
|
|
124
136
|
/>
|
|
125
137
|
);
|
|
@@ -128,7 +140,8 @@ export function SiteHeader() {
|
|
|
128
140
|
|
|
129
141
|
| Prop / event | Purpose |
|
|
130
142
|
| --- | --- |
|
|
131
|
-
| `
|
|
143
|
+
| `signedIn={boolean}` | Switches to signed-in nav when `true` |
|
|
144
|
+
| `userName={string}` | First name beside profile icon on Manage Account |
|
|
132
145
|
| `onWegAuthClick` | Host handles routing / logout; call `event.preventDefault()` to override defaults |
|
|
133
146
|
|
|
134
147
|
**Ref fallback for the event** (if `onWegAuthClick` does not bind in your React version):
|
|
@@ -152,11 +165,9 @@ useEffect(() => {
|
|
|
152
165
|
return () => el.removeEventListener('wegAuthClick', handler);
|
|
153
166
|
}, []);
|
|
154
167
|
|
|
155
|
-
return <weg-header ref={ref} layout={layout}
|
|
168
|
+
return <weg-header ref={ref} layout={layout} signedIn={signedIn} userName="Alex" />;
|
|
156
169
|
```
|
|
157
170
|
|
|
158
|
-
Update `signedIn` via `ref.current.signedIn = true` if property binding is unreliable.
|
|
159
|
-
|
|
160
171
|
## 4. Production: fetch layout from your API
|
|
161
172
|
|
|
162
173
|
```tsx
|
|
@@ -222,16 +233,6 @@ declare module 'react' {
|
|
|
222
233
|
}
|
|
223
234
|
```
|
|
224
235
|
|
|
225
|
-
Enable in `tsconfig.json` when importing JSON fixtures:
|
|
226
|
-
|
|
227
|
-
```json
|
|
228
|
-
{
|
|
229
|
-
"compilerOptions": {
|
|
230
|
-
"resolveJsonModule": true
|
|
231
|
-
}
|
|
232
|
-
}
|
|
233
|
-
```
|
|
234
|
-
|
|
235
236
|
## `layout` prop vs attribute
|
|
236
237
|
|
|
237
238
|
| How data is set | Works with object? |
|
|
@@ -240,21 +241,16 @@ Enable in `tsconfig.json` when importing JSON fixtures:
|
|
|
240
241
|
| **Attribute** `layout="[object Object]"` / React 18 `layout={obj}` | No — components stay empty |
|
|
241
242
|
| **Attribute** `layout={JSON.stringify(obj)}` | Yes — component parses JSON |
|
|
242
243
|
|
|
243
|
-
Both components accept `layout` as an object or JSON string.
|
|
244
|
-
|
|
245
|
-
## Note: `prop:layout` is unreliable in React
|
|
246
|
-
|
|
247
|
-
Prefer `layout={object}`, `layout={JSON.stringify(object)}`, or ref assignment — not `prop:layout`.
|
|
248
|
-
|
|
249
244
|
## Troubleshooting
|
|
250
245
|
|
|
251
246
|
| Symptom | Likely cause | Fix |
|
|
252
247
|
| --- | --- | --- |
|
|
253
|
-
| Empty header/footer | Loader/tag import missing | `defineCustomElements()` +
|
|
248
|
+
| Empty header/footer | Loader/tag import missing | `defineCustomElements()` + tag imports. |
|
|
254
249
|
| Empty despite correct data | React set `layout` as attribute | React 19+, or `JSON.stringify`, or ref assignment. |
|
|
255
250
|
| 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 `
|
|
257
|
-
|
|
|
251
|
+
| Auth always Sign in | `signed-in` not set | Bind `signedIn={!!session}`. |
|
|
252
|
+
| Manage Account shows label not name | `user-name` not set | Pass `userName` when signed in. |
|
|
253
|
+
| `onWegAuthClick` not firing | React CE event binding | Use `addEventListener` on a ref. |
|
|
258
254
|
| TS: unknown element | No augmentation | Add `weg-shared-layout-jsx.d.ts`. |
|
|
259
255
|
|
|
260
256
|
## See also
|
package/docs/vanilla.md
CHANGED
|
@@ -4,10 +4,10 @@
|
|
|
4
4
|
|
|
5
5
|
| Tag | Purpose |
|
|
6
6
|
| --- | --- |
|
|
7
|
-
| `<weg-header>` | Site header — logo (
|
|
7
|
+
| `<weg-header>` | Site header — bundled logo, CMS nav (signed out), built-in nav (signed in), Sign in / Manage Account / Sign out |
|
|
8
8
|
| `<weg-footer>` | Site footer — social links, columns, credits, copyright |
|
|
9
9
|
|
|
10
|
-
Both components are **presentational**: they do **not** fetch data. Pass the same `layout` payload to each
|
|
10
|
+
Both components are **presentational**: they do **not** fetch data. Pass the same `layout` payload to each.
|
|
11
11
|
|
|
12
12
|
Payload shape: [`dummy-data.json`](../src/assets/dummy-data.json) (see [readme](../readme.md#how-it-works)).
|
|
13
13
|
|
|
@@ -23,6 +23,7 @@ With a bundler that resolves `node_modules` imports:
|
|
|
23
23
|
<script type="module">
|
|
24
24
|
import { defineCustomElements } from 'weg-shared-layout/loader';
|
|
25
25
|
import layout from 'weg-shared-layout/dummy-data.json';
|
|
26
|
+
import { ACCOUNT_LOGIN_HREF, HEADER_SIGN_IN } from './auth.js';
|
|
26
27
|
|
|
27
28
|
defineCustomElements();
|
|
28
29
|
|
|
@@ -49,51 +50,76 @@ Assign the **`layout` JavaScript property** (recommended):
|
|
|
49
50
|
element.layout = layoutObject;
|
|
50
51
|
```
|
|
51
52
|
|
|
52
|
-
Or pass a JSON **string** on the `layout` attribute
|
|
53
|
+
Or pass a JSON **string** on the `layout` attribute:
|
|
53
54
|
|
|
54
55
|
```html
|
|
55
56
|
<weg-header layout='{"header":{"links":[]}}'></weg-header>
|
|
56
57
|
```
|
|
57
58
|
|
|
59
|
+
## Header layout fields (signed out)
|
|
60
|
+
|
|
61
|
+
| Field | Purpose |
|
|
62
|
+
| --- | --- |
|
|
63
|
+
| `header.logoHref` | Logo link target (defaults to WEG home) |
|
|
64
|
+
| `header.dropdowns` | Dropdown menus from CMS |
|
|
65
|
+
| `header.links` | Flat nav links from CMS |
|
|
66
|
+
| `header.signIn` | Sign in button `{ label, href }` |
|
|
67
|
+
|
|
68
|
+
See [`dummy-data.json`](../src/assets/dummy-data.json) for production URL examples.
|
|
69
|
+
|
|
58
70
|
## Header auth (Sign in / Sign out)
|
|
59
71
|
|
|
60
|
-
|
|
72
|
+
Define auth URLs in `./auth.js`:
|
|
73
|
+
|
|
74
|
+
```js
|
|
75
|
+
export const HEADER_SIGN_IN = {
|
|
76
|
+
label: 'Sign in',
|
|
77
|
+
href: 'https://account.warwickemploymentgroup.com/account/login',
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
export const ACCOUNT_LOGIN_HREF = HEADER_SIGN_IN.href;
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
### Signed out
|
|
84
|
+
|
|
85
|
+
Renders `dropdowns`, `links`, and `signIn` from `layout`.
|
|
61
86
|
|
|
62
|
-
|
|
87
|
+
### Signed in
|
|
88
|
+
|
|
89
|
+
Set **`signedIn`** and optionally **`userName`**. CMS nav is ignored; built-in links are shown (Find a job, Dashboard, Manage Account, Sign out).
|
|
63
90
|
|
|
64
91
|
```js
|
|
65
92
|
header.signedIn = true;
|
|
93
|
+
header.userName = 'Alex';
|
|
66
94
|
// or
|
|
67
95
|
header.setAttribute('signed-in', '');
|
|
96
|
+
header.setAttribute('user-name', 'Alex');
|
|
68
97
|
```
|
|
69
98
|
|
|
70
|
-
|
|
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:
|
|
99
|
+
Listen for **`wegAuthClick`**:
|
|
78
100
|
|
|
79
101
|
```js
|
|
102
|
+
import { ACCOUNT_LOGIN_HREF, HEADER_SIGN_IN } from './auth.js';
|
|
103
|
+
|
|
80
104
|
header.addEventListener('wegAuthClick', (event) => {
|
|
81
|
-
event.preventDefault();
|
|
105
|
+
event.preventDefault();
|
|
82
106
|
|
|
83
107
|
if (event.detail.action === 'sign-out') {
|
|
84
|
-
// your logout()
|
|
85
108
|
header.signedIn = false;
|
|
109
|
+
window.location.href = ACCOUNT_LOGIN_HREF;
|
|
86
110
|
return;
|
|
87
111
|
}
|
|
88
112
|
|
|
89
|
-
window.location.href =
|
|
113
|
+
window.location.href = layout.header.signIn?.href ?? HEADER_SIGN_IN.href;
|
|
90
114
|
});
|
|
91
115
|
```
|
|
92
116
|
|
|
93
117
|
| `event.detail.action` | Default behaviour if not prevented |
|
|
94
118
|
| --- | --- |
|
|
95
119
|
| `'sign-in'` | Browser follows `signIn.href` |
|
|
96
|
-
| `'sign-out'` |
|
|
120
|
+
| `'sign-out'` | Redirects to built-in sign-out URL |
|
|
121
|
+
|
|
122
|
+
Logo **image** is bundled. Logo **link** uses `layout.header.logoHref` when signed out.
|
|
97
123
|
|
|
98
124
|
## Without a bundler
|
|
99
125
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "weg-shared-layout",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.18",
|
|
4
4
|
"description": "Shared layout Web Components built with Stencil",
|
|
5
5
|
"main": "dist/index.cjs.js",
|
|
6
6
|
"module": "dist/index.js",
|
|
@@ -45,7 +45,8 @@
|
|
|
45
45
|
"dist/",
|
|
46
46
|
"docs/",
|
|
47
47
|
"loader/",
|
|
48
|
-
"src/assets/dummy-data.json"
|
|
48
|
+
"src/assets/dummy-data.json",
|
|
49
|
+
"src/constants/"
|
|
49
50
|
],
|
|
50
51
|
"devDependencies": {
|
|
51
52
|
"@stencil/core": "^4.27.1 || ^5.0.0-0",
|