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.
- package/dist/cjs/{index-CmiaQ_Dj.js → index-CC8e1qRm.js} +112 -0
- package/dist/cjs/loader.cjs.js +2 -2
- package/dist/cjs/my-component.cjs.entry.js +1 -1
- package/dist/cjs/weg-footer_2.cjs.entry.js +438 -0
- package/dist/cjs/weg-shared-layout.cjs.js +2 -2
- package/dist/collection/collection-manifest.json +2 -1
- package/dist/collection/components/weg-footer/weg-footer.css +1 -24
- package/dist/collection/components/weg-footer/weg-footer.js +5 -40
- package/dist/collection/components/weg-header/logo-data.js +2 -0
- package/dist/collection/components/weg-header/weg-header.cmp.test.js +77 -0
- package/dist/collection/components/weg-header/weg-header.css +327 -0
- package/dist/collection/components/weg-header/weg-header.js +344 -0
- package/dist/collection/styles/shared.css +49 -0
- package/dist/collection/utils/layout.js +33 -0
- package/dist/collection/utils/layout.unit.test.js +36 -0
- package/dist/components/index.js +1 -1
- package/dist/components/my-component.js +1 -1
- package/dist/components/p-CtYuWNO6.js +1 -0
- package/dist/components/p-DbIEJ3IT.js +1 -0
- package/dist/components/weg-footer.js +1 -1
- package/dist/components/weg-header.d.ts +11 -0
- package/dist/components/weg-header.js +1 -0
- package/dist/esm/{index-QiJxC4Ow.js → index-D8pmhPiH.js} +111 -1
- package/dist/esm/loader.js +3 -3
- package/dist/esm/my-component.entry.js +1 -1
- package/dist/esm/weg-footer_2.entry.js +435 -0
- package/dist/esm/weg-shared-layout.js +3 -3
- package/dist/types/components/weg-header/logo-data.d.ts +2 -0
- package/dist/types/components/weg-header/weg-header.cmp.test.d.ts +1 -0
- package/dist/types/components/weg-header/weg-header.d.ts +56 -0
- package/dist/types/components.d.ts +56 -2
- package/dist/types/types/layout-data.d.ts +21 -4
- package/dist/types/utils/layout.d.ts +4 -0
- package/dist/types/utils/layout.unit.test.d.ts +1 -0
- package/dist/weg-shared-layout/p-D8pmhPiH.js +2 -0
- package/dist/weg-shared-layout/{p-d1addb13.entry.js → p-d61033bd.entry.js} +1 -1
- package/dist/weg-shared-layout/p-eaf953a4.entry.js +1 -0
- package/dist/weg-shared-layout/weg-shared-layout.esm.js +1 -1
- package/docs/angular.md +66 -18
- package/docs/nextjs.md +145 -111
- package/docs/react.md +123 -59
- package/docs/vanilla.md +99 -3
- package/package.json +5 -1
- package/readme.md +31 -3
- package/src/assets/dummy-data.json +41 -1
- package/dist/cjs/weg-footer.cjs.entry.js +0 -189
- package/dist/components/p-BTQYW5OR.js +0 -1
- package/dist/esm/weg-footer.entry.js +0 -187
- package/dist/weg-shared-layout/p-0c28f34f.entry.js +0 -1
- 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
|
-
##
|
|
5
|
+
## Components
|
|
6
6
|
|
|
7
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
-
|
|
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
|
|
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.
|
|
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
|
|
62
|
-
return
|
|
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
|
-
|
|
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
|
-
|
|
87
|
+
The WEG logo is bundled inside `<weg-header>` — not configurable via `layout`.
|
|
69
88
|
|
|
70
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
134
|
+
**Ref fallback for the event** (if `onWegAuthClick` does not bind in your React version):
|
|
79
135
|
|
|
80
|
-
|
|
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
|
-
|
|
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
|
|
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;
|
|
191
|
+
if (!layout) return null;
|
|
113
192
|
|
|
114
|
-
return
|
|
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
|
|
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
|
-
|
|
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
|
|
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 —
|
|
156
|
-
| **Attribute** `layout=
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
190
|
-
| Empty
|
|
191
|
-
|
|
|
192
|
-
|
|
|
193
|
-
|
|
|
194
|
-
|
|
|
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)**
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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.
|
|
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>`
|
|
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/" },
|