weg-shared-layout 0.0.10 → 0.0.12
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/loader.cjs.js +1 -1
- package/dist/cjs/weg-footer.cjs.entry.js +11 -10
- package/dist/cjs/weg-shared-layout.cjs.js +1 -1
- package/dist/collection/components/weg-footer/weg-footer.js +14 -13
- package/dist/components/weg-footer.js +1 -1
- package/dist/esm/loader.js +1 -1
- package/dist/esm/weg-footer.entry.js +11 -10
- package/dist/esm/weg-shared-layout.js +1 -1
- package/dist/types/components/weg-footer/weg-footer.d.ts +6 -5
- package/dist/types/components.d.ts +5 -5
- package/dist/weg-shared-layout/{p-87522053.entry.js → p-99843bbd.entry.js} +1 -1
- package/dist/weg-shared-layout/weg-shared-layout.esm.js +1 -1
- package/docs/angular.md +4 -4
- package/docs/nextjs.md +243 -0
- package/docs/react.md +176 -11
- package/docs/vanilla.md +3 -3
- package/package.json +10 -11
- package/readme.md +3 -2
package/dist/cjs/loader.cjs.js
CHANGED
|
@@ -6,7 +6,7 @@ var appGlobals = require('./app-globals-V2Kpy_OQ.js');
|
|
|
6
6
|
const defineCustomElements = async (win, options) => {
|
|
7
7
|
if (typeof window === 'undefined') return undefined;
|
|
8
8
|
await appGlobals.globalScripts();
|
|
9
|
-
return index.bootstrapLazy([["my-component.cjs",[[513,"my-component",{"first":[1],"middle":[1],"last":[1]}]]],["weg-footer.cjs",[[513,"weg-footer",{"
|
|
9
|
+
return index.bootstrapLazy([["my-component.cjs",[[513,"my-component",{"first":[1],"middle":[1],"last":[1]}]]],["weg-footer.cjs",[[513,"weg-footer",{"layout":[1],"resolved":[32]},null,{"layout":[{"watchLayout":0}]}]]]], options);
|
|
10
10
|
};
|
|
11
11
|
|
|
12
12
|
exports.setNonce = index.setNonce;
|
|
@@ -103,12 +103,13 @@ const WegFooter = class {
|
|
|
103
103
|
index.registerInstance(this, hostRef);
|
|
104
104
|
}
|
|
105
105
|
/**
|
|
106
|
-
* Layout
|
|
106
|
+
* Layout payload, supplied by the host application.
|
|
107
107
|
*
|
|
108
108
|
* In JS / framework templates, pass the object directly (e.g. Angular
|
|
109
|
-
* `[
|
|
109
|
+
* `[layout]="layoutData"`, React `layout={layoutData}`, vanilla
|
|
110
|
+
* `el.layout = layoutData`).
|
|
110
111
|
*
|
|
111
|
-
* In plain HTML, pass the same JSON as a string attribute.
|
|
112
|
+
* In plain HTML, pass the same JSON as a string on the `layout` attribute.
|
|
112
113
|
*
|
|
113
114
|
* Expected shape:
|
|
114
115
|
* ```json
|
|
@@ -122,19 +123,19 @@ const WegFooter = class {
|
|
|
122
123
|
* }
|
|
123
124
|
* ```
|
|
124
125
|
*/
|
|
125
|
-
|
|
126
|
+
layout;
|
|
126
127
|
resolved = EMPTY_FOOTER;
|
|
127
128
|
resolve() {
|
|
128
|
-
if (this.
|
|
129
|
+
if (this.layout === undefined || this.layout === null) {
|
|
129
130
|
this.resolved = EMPTY_FOOTER;
|
|
130
131
|
return;
|
|
131
132
|
}
|
|
132
|
-
this.resolved = normalizeFooterData(parseJsonProp(this.
|
|
133
|
+
this.resolved = normalizeFooterData(parseJsonProp(this.layout));
|
|
133
134
|
}
|
|
134
135
|
componentWillLoad() {
|
|
135
136
|
this.resolve();
|
|
136
137
|
}
|
|
137
|
-
|
|
138
|
+
watchLayout() {
|
|
138
139
|
this.resolve();
|
|
139
140
|
}
|
|
140
141
|
renderLegalText() {
|
|
@@ -156,11 +157,11 @@ const WegFooter = class {
|
|
|
156
157
|
return (index.h("div", { class: "standard__links" }, links.map((l) => (index.h("a", { class: "footer-link", href: l.href }, l.label)))));
|
|
157
158
|
}
|
|
158
159
|
render() {
|
|
159
|
-
return (index.h("footer", { key: '
|
|
160
|
+
return (index.h("footer", { key: 'ba9a2b07235bbad73f4f2aea762af917249f621b', class: "footer" }, index.h("div", { key: '88a8a9de95c09bf4c5524fc942976b7ababe110d', class: "container" }, this.renderSocialLinks(), index.h("div", { key: '2a21b07909bcb975c4bade8a291b050d83d52e8c', class: "standard" }, this.renderStandardLinks(), this.renderLegalText()))));
|
|
160
161
|
}
|
|
161
162
|
static get watchers() { return {
|
|
162
|
-
"
|
|
163
|
-
"
|
|
163
|
+
"layout": [{
|
|
164
|
+
"watchLayout": 0
|
|
164
165
|
}]
|
|
165
166
|
}; }
|
|
166
167
|
};
|
|
@@ -19,7 +19,7 @@ var patchBrowser = () => {
|
|
|
19
19
|
|
|
20
20
|
patchBrowser().then(async (options) => {
|
|
21
21
|
await appGlobals.globalScripts();
|
|
22
|
-
return index.bootstrapLazy([["my-component.cjs",[[513,"my-component",{"first":[1],"middle":[1],"last":[1]}]]],["weg-footer.cjs",[[513,"weg-footer",{"
|
|
22
|
+
return index.bootstrapLazy([["my-component.cjs",[[513,"my-component",{"first":[1],"middle":[1],"last":[1]}]]],["weg-footer.cjs",[[513,"weg-footer",{"layout":[1],"resolved":[32]},null,{"layout":[{"watchLayout":0}]}]]]], options);
|
|
23
23
|
});
|
|
24
24
|
|
|
25
25
|
exports.setNonce = index.setNonce;
|
|
@@ -95,12 +95,13 @@ function SocialIcon({ platform }) {
|
|
|
95
95
|
}
|
|
96
96
|
export class WegFooter {
|
|
97
97
|
/**
|
|
98
|
-
* Layout
|
|
98
|
+
* Layout payload, supplied by the host application.
|
|
99
99
|
*
|
|
100
100
|
* In JS / framework templates, pass the object directly (e.g. Angular
|
|
101
|
-
* `[
|
|
101
|
+
* `[layout]="layoutData"`, React `layout={layoutData}`, vanilla
|
|
102
|
+
* `el.layout = layoutData`).
|
|
102
103
|
*
|
|
103
|
-
* In plain HTML, pass the same JSON as a string attribute.
|
|
104
|
+
* In plain HTML, pass the same JSON as a string on the `layout` attribute.
|
|
104
105
|
*
|
|
105
106
|
* Expected shape:
|
|
106
107
|
* ```json
|
|
@@ -114,19 +115,19 @@ export class WegFooter {
|
|
|
114
115
|
* }
|
|
115
116
|
* ```
|
|
116
117
|
*/
|
|
117
|
-
|
|
118
|
+
layout;
|
|
118
119
|
resolved = EMPTY_FOOTER;
|
|
119
120
|
resolve() {
|
|
120
|
-
if (this.
|
|
121
|
+
if (this.layout === undefined || this.layout === null) {
|
|
121
122
|
this.resolved = EMPTY_FOOTER;
|
|
122
123
|
return;
|
|
123
124
|
}
|
|
124
|
-
this.resolved = normalizeFooterData(parseJsonProp(this.
|
|
125
|
+
this.resolved = normalizeFooterData(parseJsonProp(this.layout));
|
|
125
126
|
}
|
|
126
127
|
componentWillLoad() {
|
|
127
128
|
this.resolve();
|
|
128
129
|
}
|
|
129
|
-
|
|
130
|
+
watchLayout() {
|
|
130
131
|
this.resolve();
|
|
131
132
|
}
|
|
132
133
|
renderLegalText() {
|
|
@@ -148,7 +149,7 @@ export class WegFooter {
|
|
|
148
149
|
return (h("div", { class: "standard__links" }, links.map((l) => (h("a", { class: "footer-link", href: l.href }, l.label)))));
|
|
149
150
|
}
|
|
150
151
|
render() {
|
|
151
|
-
return (h("footer", { key: '
|
|
152
|
+
return (h("footer", { key: 'ba9a2b07235bbad73f4f2aea762af917249f621b', class: "footer" }, h("div", { key: '88a8a9de95c09bf4c5524fc942976b7ababe110d', class: "container" }, this.renderSocialLinks(), h("div", { key: '2a21b07909bcb975c4bade8a291b050d83d52e8c', class: "standard" }, this.renderStandardLinks(), this.renderLegalText()))));
|
|
152
153
|
}
|
|
153
154
|
static get is() { return "weg-footer"; }
|
|
154
155
|
static get encapsulation() { return "shadow"; }
|
|
@@ -164,7 +165,7 @@ export class WegFooter {
|
|
|
164
165
|
}
|
|
165
166
|
static get properties() {
|
|
166
167
|
return {
|
|
167
|
-
"
|
|
168
|
+
"layout": {
|
|
168
169
|
"type": "string",
|
|
169
170
|
"mutable": false,
|
|
170
171
|
"complexType": {
|
|
@@ -181,12 +182,12 @@ export class WegFooter {
|
|
|
181
182
|
"optional": true,
|
|
182
183
|
"docs": {
|
|
183
184
|
"tags": [],
|
|
184
|
-
"text": "Layout
|
|
185
|
+
"text": "Layout payload, supplied by the host application.\n\nIn JS / framework templates, pass the object directly (e.g. Angular\n`[layout]=\"layoutData\"`, React `layout={layoutData}`, vanilla\n`el.layout = layoutData`).\n\nIn plain HTML, pass the same JSON as a string on the `layout` attribute.\n\nExpected shape:\n```json\n{\n \"footer\": {\n \"social\": [{ \"platform\": \"LinkedIn\", \"href\": \"https://...\" }],\n \"standardLinks\": [{ \"label\": \"About Us\", \"href\": \"/about\" }],\n \"credits\": \"...\",\n \"copyright\": \"...\"\n }\n}\n```"
|
|
185
186
|
},
|
|
186
187
|
"getter": false,
|
|
187
188
|
"setter": false,
|
|
188
189
|
"reflect": false,
|
|
189
|
-
"attribute": "
|
|
190
|
+
"attribute": "layout"
|
|
190
191
|
}
|
|
191
192
|
};
|
|
192
193
|
}
|
|
@@ -197,8 +198,8 @@ export class WegFooter {
|
|
|
197
198
|
}
|
|
198
199
|
static get watchers() {
|
|
199
200
|
return [{
|
|
200
|
-
"propName": "
|
|
201
|
-
"methodName": "
|
|
201
|
+
"propName": "layout",
|
|
202
|
+
"methodName": "watchLayout"
|
|
202
203
|
}];
|
|
203
204
|
}
|
|
204
205
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{t,p as e,H as i,h as n}from"./p-BTQYW5OR.js";const o={social:[],standardLinks:[],credits:"",copyright:""};function a(t){return/^https?:\/\//.test(t)}function s(t){return"string"==typeof t&&t.trim().length>0}function r(t){return"LinkedIn"===t||"Instagram"===t||"TikTok"===t||"YouTube"===t}function l(t){if(!Array.isArray(t))return[];const e=[];for(const i of t){if(!i||"object"!=typeof i)continue;const t=i.platform,n=i.href;r(t)&&s(n)&&e.push({platform:t,href:n.trim()})}return e}function c(t){if(!Array.isArray(t))return[];const e=[];for(const i of t){if(!i||"object"!=typeof i)continue;const t=i.label,n=i.href;s(t)&&s(n)&&e.push({label:t.trim(),href:n.trim()})}return e}function f({platform:t}){const e={viewBox:"0 0 48 48",width:48,height:48,fill:"none",xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",focusable:"false"};switch(t){case"LinkedIn":return n("svg",{...e},n("path",{d:"M24 0C37.2548 0 48 10.7452 48 24C48 37.2548 37.2548 48 24 48C10.7452 48 0 37.2548 0 24C0 10.7452 10.7452 0 24 0ZM12.9082 33.4736H17.5889V19.4111H12.9082V33.4736ZM29.0791 19.0811C26.5942 19.0811 25.4815 20.4458 24.8604 21.4033V19.4111H20.1797C20.2412 20.7279 20.1799 33.4203 20.1797 33.4736H24.8604V25.6201C24.8604 25.1998 24.8909 24.7804 25.0146 24.4795C25.3529 23.6399 26.1231 22.7705 27.416 22.7705C29.1103 22.7705 29.7881 24.0605 29.7881 25.9502V33.4736H34.4678V25.4102C34.4677 21.0909 32.1589 19.0811 29.0791 19.0811ZM15.2793 12.6318C13.6783 12.6319 12.6319 13.6818 12.6318 15.0605C12.6318 16.4108 13.6474 17.4912 15.2188 17.4912H15.249C16.8807 17.491 17.8965 16.4107 17.8965 15.0605C17.866 13.6818 16.8804 12.6318 15.2793 12.6318Z",fill:"white"}));case"Instagram":return n("svg",{...e},n("path",{d:"M24 0C37.2548 0 48 10.7452 48 24C48 37.2548 37.2548 48 24 48C10.7452 48 0 37.2548 0 24C0 10.7452 10.7452 0 24 0ZM23.999 11.2002C20.5245 11.2002 20.0877 11.2152 18.7227 11.2773C17.3602 11.3398 16.43 11.5556 15.6162 11.8721C14.7744 12.199 14.06 12.636 13.3486 13.3477C12.6366 14.0591 12.1991 14.7736 11.8711 15.6152C11.5538 16.4293 11.3377 17.3597 11.2764 18.7217C11.2153 20.087 11.2002 20.5238 11.2002 24C11.2002 27.476 11.2155 27.9113 11.2773 29.2764C11.34 30.639 11.5558 31.5699 11.8721 32.3838C12.1993 33.2255 12.636 33.94 13.3477 34.6514C14.0589 35.3634 14.7739 35.801 15.6152 36.1279C16.4295 36.4444 17.3596 36.6602 18.7217 36.7227C20.087 36.7848 20.5233 36.7998 23.999 36.7998C27.4756 36.7998 27.911 36.7848 29.2764 36.7227C30.639 36.6602 31.5704 36.4445 32.3848 36.1279C33.2261 35.801 33.9394 35.3631 34.6504 34.6514C35.3624 33.9399 35.7999 33.2254 36.1279 32.3838C36.4426 31.5697 36.6586 30.6393 36.7227 29.2773C36.784 27.912 36.7998 27.4763 36.7998 24C36.7998 20.5242 36.784 20.0876 36.7227 18.7227C36.6587 17.36 36.4426 16.4291 36.1279 15.6152C35.7999 14.7734 35.3623 14.0591 34.6504 13.3477C33.9385 12.6358 33.2264 12.1987 32.3838 11.8721C31.5678 11.5555 30.6371 11.3397 29.2744 11.2773C27.9093 11.2152 27.4745 11.2002 23.999 11.2002Z",fill:"white"}),n("path",{d:"M22.8525 13.5068C23.1933 13.5063 23.5739 13.5068 24.001 13.5068C27.4186 13.5068 27.8242 13.5197 29.1738 13.5811C30.4214 13.6381 31.0986 13.8463 31.5498 14.0215C32.1471 14.2535 32.5737 14.5305 33.0215 14.9785C33.4695 15.4265 33.746 15.8538 33.9785 16.4512C34.1537 16.9018 34.3631 17.5792 34.4199 18.8271C34.4812 20.1763 34.4941 20.5822 34.4941 23.998C34.4941 27.4134 34.4812 27.819 34.4199 29.168C34.3629 30.4158 34.1537 31.0933 33.9785 31.5439C33.7466 32.1412 33.4693 32.567 33.0215 33.0146C32.5735 33.4627 32.1474 33.7397 31.5498 33.9717C31.0992 34.1477 30.4216 34.356 29.1738 34.4131C27.8245 34.4744 27.4186 34.4883 24.001 34.4883C20.5835 34.4883 20.1783 34.4744 18.8291 34.4131C17.5811 34.3555 16.9036 34.1469 16.4521 33.9717C15.8549 33.7397 15.4284 33.4625 14.9805 33.0146C14.5325 32.5666 14.255 32.1406 14.0225 31.543C13.8473 31.0923 13.6378 30.4148 13.5811 29.167C13.5197 27.8179 13.5078 27.4121 13.5078 23.9941C13.5078 20.5762 13.5197 20.1726 13.5811 18.8232C13.6381 17.5755 13.8473 16.8984 14.0225 16.4473C14.2545 15.8499 14.5325 15.4236 14.9805 14.9756C15.4285 14.5276 15.8549 14.2501 16.4521 14.0176C16.9034 13.8416 17.5811 13.6335 18.8291 13.5762C20.0097 13.5228 20.4674 13.5066 22.8525 13.5039V13.5068ZM24.001 17.4268C20.371 17.427 17.4277 20.3709 17.4277 24.001C17.4279 27.6309 20.3711 30.5721 24.001 30.5723C27.631 30.5723 30.573 27.631 30.5732 24.001C30.5732 20.3708 27.6311 17.4268 24.001 17.4268ZM30.834 15.6318C29.9861 15.632 29.2979 16.3198 29.2979 17.168C29.2979 18.0159 29.9861 18.704 30.834 18.7041C31.682 18.7041 32.3701 18.016 32.3701 17.168C32.37 16.32 31.6819 15.6318 30.834 15.6318Z",fill:"white"}),n("path",{d:"M24.0011 19.7334C26.3574 19.7334 28.2678 21.6436 28.2678 24.0001C28.2678 26.3564 26.3574 28.2668 24.0011 28.2668C21.6445 28.2668 19.7344 26.3564 19.7344 24.0001C19.7344 21.6436 21.6445 19.7334 24.0011 19.7334Z",fill:"white"}));case"TikTok":return n("svg",{...e},n("path",{d:"M24 0C37.2548 0 48 10.7452 48 24C48 37.2548 37.2548 48 24 48C10.7452 48 0 37.2548 0 24C0 10.7452 10.7452 0 24 0ZM25.0273 28.3477C25.0273 30.2955 23.4721 31.8955 21.5361 31.8955C19.6003 31.8954 18.0449 30.2955 18.0449 28.3477C18.045 26.4347 19.5659 24.8693 21.4326 24.7998V20.6953C17.3188 20.7648 14.0001 24.1391 14 28.3477C14 32.5912 17.3883 36 21.5713 36C25.754 35.9998 29.1416 32.5562 29.1416 28.3477V19.9648C30.6627 21.0779 32.5295 21.7396 34.5 21.7744V17.6699C31.4579 17.5656 29.0723 15.0609 29.0723 12H25.0273V28.3477Z",fill:"white"}));case"YouTube":return n("svg",{...e},n("path",{d:"M24 0C37.2548 0 48 10.7452 48 24C48 37.2548 37.2548 48 24 48C10.7452 48 0 37.2548 0 24C0 10.7452 10.7452 0 24 0ZM24 15.2002C24 15.2002 15.9944 15.1997 13.998 15.749C12.8966 16.0513 12.0288 16.9423 11.7344 18.0732C11.1996 20.1231 11.2002 24.4004 11.2002 24.4004C11.2002 24.4472 11.2026 28.6878 11.7344 30.7266C12.0288 31.8575 12.8966 32.7483 13.998 33.0508C15.9944 33.6 24 33.5996 24 33.5996C24 33.5996 32.0057 33.6 34.002 33.0508C35.1033 32.7483 35.9703 31.8575 36.2646 30.7266C36.7966 28.6879 36.7998 24.4472 36.7998 24.4004C36.7998 24.4004 36.7996 20.1231 36.2646 18.0732C35.9703 16.9424 35.1033 16.0513 34.002 15.749C32.0057 15.1997 24 15.2002 24 15.2002Z",fill:"white"}),n("path",{d:"M21.6016 28.7998V20.7998L28.0016 24.8L21.6016 28.7998Z",fill:"white"}))}}const C=e(class extends i{constructor(t){super(),!1!==t&&this.__registerHost(),this.__attachShadow()}data;resolved=o;resolve(){this.resolved=null!=this.data?function(t){const e=t&&"object"==typeof t?t:{},i=e.footer&&"object"==typeof e.footer?e.footer:{};return{social:l(i?.social),standardLinks:c(i?.standardLinks),credits:s(i?.credits)?i.credits.trim():"",copyright:s(i?.copyright)?i.copyright.trim():""}}(function(t){if("string"!=typeof t)return t;const e=t.trim();if(e)try{return JSON.parse(e)}catch{return}}(this.data)):o}componentWillLoad(){this.resolve()}watchData(){this.resolve()}renderLegalText(){const{credits:t,copyright:e}=this.resolved;return t||e?n("div",{class:"legal"},t?n("p",{class:"legal__p"},t):null,t&&e?n("p",{class:"legal__p"},""):null,e?n("p",{class:"legal__p"},e):null):null}renderSocialLinks(){const t=this.resolved.social;return 0===t.length?null:n("div",{class:"social"},t.map((t=>n("a",{class:"social__link",href:t.href,"aria-label":t.platform,target:a(t.href)?"_blank":void 0,rel:a(t.href)?"noreferrer noopener":void 0},n("span",{class:"social__icon","aria-hidden":"true"},n(f,{platform:t.platform}))))))}renderStandardLinks(){const t=this.resolved.standardLinks;return 0===t.length?null:n("div",{class:"standard__links"},t.map((t=>n("a",{class:"footer-link",href:t.href},t.label))))}render(){return n("footer",{key:"b5440fe948f8a4207b20d8e380ab50f559890440",class:"footer"},n("div",{key:"2f4757c3a52203a89b53fa358513d832f153bfa2",class:"container"},this.renderSocialLinks(),n("div",{key:"4ee53f39a16dab3739c70dadcaadb15602f08ce9",class:"standard"},this.renderStandardLinks(),this.renderLegalText())))}static get watchers(){return{data:[{watchData:0}]}}static get style(){return':host{display:block}.footer{background:#030712;color:#ffffff;padding:28px 32px;font-family:ui-sans-serif, system-ui, -apple-system, Segoe UI, Roboto, Helvetica, Arial, "Apple Color Emoji", "Segoe UI Emoji";font-weight:300}.container{max-width:1024px;margin:0 auto;display:flex;flex-direction:column;align-items:center;gap:20px}@media (min-width: 768px){.footer{padding:44px 56px}.container{gap:36px}}.social{display:flex;align-items:center;justify-content:center;gap:16px}@media (min-width: 768px){.social{gap:28px}}.social__link{width:48px;height:48px;display:inline-flex;align-items:center;justify-content:center;border-radius:999px;background:transparent;color:inherit;text-decoration:none;transition:opacity 150ms ease;outline:none}.social__link:hover{opacity:0.9}.social__link:focus-visible{outline:2px solid rgba(255, 255, 255, 0.9);outline-offset:4px}.social__icon{display:inline-flex;width:48px;height:48px}.footer-link{color:#ffffff;text-decoration:underline;text-underline-offset:2px;text-decoration-thickness:1px;outline:none}.footer-link:hover{text-decoration-thickness:2px}.footer-link:focus-visible{outline:2px solid rgba(255, 255, 255, 0.9);outline-offset:4px}.legal{width:100%;max-width:860px;text-align:center;font-size:16px;line-height:24px}@media (min-width: 768px){.legal{font-size:18px;line-height:28px}}.legal__p{margin:0}.standard{width:100%;display:flex;flex-direction:column;align-items:center;gap:36px;text-align:center;font-size:16px;line-height:24px}@media (min-width: 768px){.standard{font-size:18px;line-height:28px}}.standard__links{display:flex;flex-direction:column;align-items:center;gap:16px}@media (min-width: 768px){.standard__links{flex-direction:row;flex-wrap:wrap;justify-content:center;gap:36px}}'}},[513,"weg-footer",{data:[1],resolved:[32]},void 0,{data:[{watchData:0}]}]);function d(){"undefined"!=typeof customElements&&["weg-footer"].forEach((e=>{"weg-footer"===e&&(customElements.get(t(e))||customElements.define(t(e),C))}))}d();const p=C,h=d;export{p as WegFooter,h as defineCustomElement}
|
|
1
|
+
import{t,p as e,H as i,h as n}from"./p-BTQYW5OR.js";const o={social:[],standardLinks:[],credits:"",copyright:""};function a(t){return/^https?:\/\//.test(t)}function s(t){return"string"==typeof t&&t.trim().length>0}function r(t){return"LinkedIn"===t||"Instagram"===t||"TikTok"===t||"YouTube"===t}function l(t){if(!Array.isArray(t))return[];const e=[];for(const i of t){if(!i||"object"!=typeof i)continue;const t=i.platform,n=i.href;r(t)&&s(n)&&e.push({platform:t,href:n.trim()})}return e}function c(t){if(!Array.isArray(t))return[];const e=[];for(const i of t){if(!i||"object"!=typeof i)continue;const t=i.label,n=i.href;s(t)&&s(n)&&e.push({label:t.trim(),href:n.trim()})}return e}function C({platform:t}){const e={viewBox:"0 0 48 48",width:48,height:48,fill:"none",xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",focusable:"false"};switch(t){case"LinkedIn":return n("svg",{...e},n("path",{d:"M24 0C37.2548 0 48 10.7452 48 24C48 37.2548 37.2548 48 24 48C10.7452 48 0 37.2548 0 24C0 10.7452 10.7452 0 24 0ZM12.9082 33.4736H17.5889V19.4111H12.9082V33.4736ZM29.0791 19.0811C26.5942 19.0811 25.4815 20.4458 24.8604 21.4033V19.4111H20.1797C20.2412 20.7279 20.1799 33.4203 20.1797 33.4736H24.8604V25.6201C24.8604 25.1998 24.8909 24.7804 25.0146 24.4795C25.3529 23.6399 26.1231 22.7705 27.416 22.7705C29.1103 22.7705 29.7881 24.0605 29.7881 25.9502V33.4736H34.4678V25.4102C34.4677 21.0909 32.1589 19.0811 29.0791 19.0811ZM15.2793 12.6318C13.6783 12.6319 12.6319 13.6818 12.6318 15.0605C12.6318 16.4108 13.6474 17.4912 15.2188 17.4912H15.249C16.8807 17.491 17.8965 16.4107 17.8965 15.0605C17.866 13.6818 16.8804 12.6318 15.2793 12.6318Z",fill:"white"}));case"Instagram":return n("svg",{...e},n("path",{d:"M24 0C37.2548 0 48 10.7452 48 24C48 37.2548 37.2548 48 24 48C10.7452 48 0 37.2548 0 24C0 10.7452 10.7452 0 24 0ZM23.999 11.2002C20.5245 11.2002 20.0877 11.2152 18.7227 11.2773C17.3602 11.3398 16.43 11.5556 15.6162 11.8721C14.7744 12.199 14.06 12.636 13.3486 13.3477C12.6366 14.0591 12.1991 14.7736 11.8711 15.6152C11.5538 16.4293 11.3377 17.3597 11.2764 18.7217C11.2153 20.087 11.2002 20.5238 11.2002 24C11.2002 27.476 11.2155 27.9113 11.2773 29.2764C11.34 30.639 11.5558 31.5699 11.8721 32.3838C12.1993 33.2255 12.636 33.94 13.3477 34.6514C14.0589 35.3634 14.7739 35.801 15.6152 36.1279C16.4295 36.4444 17.3596 36.6602 18.7217 36.7227C20.087 36.7848 20.5233 36.7998 23.999 36.7998C27.4756 36.7998 27.911 36.7848 29.2764 36.7227C30.639 36.6602 31.5704 36.4445 32.3848 36.1279C33.2261 35.801 33.9394 35.3631 34.6504 34.6514C35.3624 33.9399 35.7999 33.2254 36.1279 32.3838C36.4426 31.5697 36.6586 30.6393 36.7227 29.2773C36.784 27.912 36.7998 27.4763 36.7998 24C36.7998 20.5242 36.784 20.0876 36.7227 18.7227C36.6587 17.36 36.4426 16.4291 36.1279 15.6152C35.7999 14.7734 35.3623 14.0591 34.6504 13.3477C33.9385 12.6358 33.2264 12.1987 32.3838 11.8721C31.5678 11.5555 30.6371 11.3397 29.2744 11.2773C27.9093 11.2152 27.4745 11.2002 23.999 11.2002Z",fill:"white"}),n("path",{d:"M22.8525 13.5068C23.1933 13.5063 23.5739 13.5068 24.001 13.5068C27.4186 13.5068 27.8242 13.5197 29.1738 13.5811C30.4214 13.6381 31.0986 13.8463 31.5498 14.0215C32.1471 14.2535 32.5737 14.5305 33.0215 14.9785C33.4695 15.4265 33.746 15.8538 33.9785 16.4512C34.1537 16.9018 34.3631 17.5792 34.4199 18.8271C34.4812 20.1763 34.4941 20.5822 34.4941 23.998C34.4941 27.4134 34.4812 27.819 34.4199 29.168C34.3629 30.4158 34.1537 31.0933 33.9785 31.5439C33.7466 32.1412 33.4693 32.567 33.0215 33.0146C32.5735 33.4627 32.1474 33.7397 31.5498 33.9717C31.0992 34.1477 30.4216 34.356 29.1738 34.4131C27.8245 34.4744 27.4186 34.4883 24.001 34.4883C20.5835 34.4883 20.1783 34.4744 18.8291 34.4131C17.5811 34.3555 16.9036 34.1469 16.4521 33.9717C15.8549 33.7397 15.4284 33.4625 14.9805 33.0146C14.5325 32.5666 14.255 32.1406 14.0225 31.543C13.8473 31.0923 13.6378 30.4148 13.5811 29.167C13.5197 27.8179 13.5078 27.4121 13.5078 23.9941C13.5078 20.5762 13.5197 20.1726 13.5811 18.8232C13.6381 17.5755 13.8473 16.8984 14.0225 16.4473C14.2545 15.8499 14.5325 15.4236 14.9805 14.9756C15.4285 14.5276 15.8549 14.2501 16.4521 14.0176C16.9034 13.8416 17.5811 13.6335 18.8291 13.5762C20.0097 13.5228 20.4674 13.5066 22.8525 13.5039V13.5068ZM24.001 17.4268C20.371 17.427 17.4277 20.3709 17.4277 24.001C17.4279 27.6309 20.3711 30.5721 24.001 30.5723C27.631 30.5723 30.573 27.631 30.5732 24.001C30.5732 20.3708 27.6311 17.4268 24.001 17.4268ZM30.834 15.6318C29.9861 15.632 29.2979 16.3198 29.2979 17.168C29.2979 18.0159 29.9861 18.704 30.834 18.7041C31.682 18.7041 32.3701 18.016 32.3701 17.168C32.37 16.32 31.6819 15.6318 30.834 15.6318Z",fill:"white"}),n("path",{d:"M24.0011 19.7334C26.3574 19.7334 28.2678 21.6436 28.2678 24.0001C28.2678 26.3564 26.3574 28.2668 24.0011 28.2668C21.6445 28.2668 19.7344 26.3564 19.7344 24.0001C19.7344 21.6436 21.6445 19.7334 24.0011 19.7334Z",fill:"white"}));case"TikTok":return n("svg",{...e},n("path",{d:"M24 0C37.2548 0 48 10.7452 48 24C48 37.2548 37.2548 48 24 48C10.7452 48 0 37.2548 0 24C0 10.7452 10.7452 0 24 0ZM25.0273 28.3477C25.0273 30.2955 23.4721 31.8955 21.5361 31.8955C19.6003 31.8954 18.0449 30.2955 18.0449 28.3477C18.045 26.4347 19.5659 24.8693 21.4326 24.7998V20.6953C17.3188 20.7648 14.0001 24.1391 14 28.3477C14 32.5912 17.3883 36 21.5713 36C25.754 35.9998 29.1416 32.5562 29.1416 28.3477V19.9648C30.6627 21.0779 32.5295 21.7396 34.5 21.7744V17.6699C31.4579 17.5656 29.0723 15.0609 29.0723 12H25.0273V28.3477Z",fill:"white"}));case"YouTube":return n("svg",{...e},n("path",{d:"M24 0C37.2548 0 48 10.7452 48 24C48 37.2548 37.2548 48 24 48C10.7452 48 0 37.2548 0 24C0 10.7452 10.7452 0 24 0ZM24 15.2002C24 15.2002 15.9944 15.1997 13.998 15.749C12.8966 16.0513 12.0288 16.9423 11.7344 18.0732C11.1996 20.1231 11.2002 24.4004 11.2002 24.4004C11.2002 24.4472 11.2026 28.6878 11.7344 30.7266C12.0288 31.8575 12.8966 32.7483 13.998 33.0508C15.9944 33.6 24 33.5996 24 33.5996C24 33.5996 32.0057 33.6 34.002 33.0508C35.1033 32.7483 35.9703 31.8575 36.2646 30.7266C36.7966 28.6879 36.7998 24.4472 36.7998 24.4004C36.7998 24.4004 36.7996 20.1231 36.2646 18.0732C35.9703 16.9424 35.1033 16.0513 34.002 15.749C32.0057 15.1997 24 15.2002 24 15.2002Z",fill:"white"}),n("path",{d:"M21.6016 28.7998V20.7998L28.0016 24.8L21.6016 28.7998Z",fill:"white"}))}}const f=e(class extends i{constructor(t){super(),!1!==t&&this.__registerHost(),this.__attachShadow()}layout;resolved=o;resolve(){this.resolved=null!=this.layout?function(t){const e=t&&"object"==typeof t?t:{},i=e.footer&&"object"==typeof e.footer?e.footer:{};return{social:l(i?.social),standardLinks:c(i?.standardLinks),credits:s(i?.credits)?i.credits.trim():"",copyright:s(i?.copyright)?i.copyright.trim():""}}(function(t){if("string"!=typeof t)return t;const e=t.trim();if(e)try{return JSON.parse(e)}catch{return}}(this.layout)):o}componentWillLoad(){this.resolve()}watchLayout(){this.resolve()}renderLegalText(){const{credits:t,copyright:e}=this.resolved;return t||e?n("div",{class:"legal"},t?n("p",{class:"legal__p"},t):null,t&&e?n("p",{class:"legal__p"},""):null,e?n("p",{class:"legal__p"},e):null):null}renderSocialLinks(){const t=this.resolved.social;return 0===t.length?null:n("div",{class:"social"},t.map((t=>n("a",{class:"social__link",href:t.href,"aria-label":t.platform,target:a(t.href)?"_blank":void 0,rel:a(t.href)?"noreferrer noopener":void 0},n("span",{class:"social__icon","aria-hidden":"true"},n(C,{platform:t.platform}))))))}renderStandardLinks(){const t=this.resolved.standardLinks;return 0===t.length?null:n("div",{class:"standard__links"},t.map((t=>n("a",{class:"footer-link",href:t.href},t.label))))}render(){return n("footer",{key:"ba9a2b07235bbad73f4f2aea762af917249f621b",class:"footer"},n("div",{key:"88a8a9de95c09bf4c5524fc942976b7ababe110d",class:"container"},this.renderSocialLinks(),n("div",{key:"2a21b07909bcb975c4bade8a291b050d83d52e8c",class:"standard"},this.renderStandardLinks(),this.renderLegalText())))}static get watchers(){return{layout:[{watchLayout:0}]}}static get style(){return':host{display:block}.footer{background:#030712;color:#ffffff;padding:28px 32px;font-family:ui-sans-serif, system-ui, -apple-system, Segoe UI, Roboto, Helvetica, Arial, "Apple Color Emoji", "Segoe UI Emoji";font-weight:300}.container{max-width:1024px;margin:0 auto;display:flex;flex-direction:column;align-items:center;gap:20px}@media (min-width: 768px){.footer{padding:44px 56px}.container{gap:36px}}.social{display:flex;align-items:center;justify-content:center;gap:16px}@media (min-width: 768px){.social{gap:28px}}.social__link{width:48px;height:48px;display:inline-flex;align-items:center;justify-content:center;border-radius:999px;background:transparent;color:inherit;text-decoration:none;transition:opacity 150ms ease;outline:none}.social__link:hover{opacity:0.9}.social__link:focus-visible{outline:2px solid rgba(255, 255, 255, 0.9);outline-offset:4px}.social__icon{display:inline-flex;width:48px;height:48px}.footer-link{color:#ffffff;text-decoration:underline;text-underline-offset:2px;text-decoration-thickness:1px;outline:none}.footer-link:hover{text-decoration-thickness:2px}.footer-link:focus-visible{outline:2px solid rgba(255, 255, 255, 0.9);outline-offset:4px}.legal{width:100%;max-width:860px;text-align:center;font-size:16px;line-height:24px}@media (min-width: 768px){.legal{font-size:18px;line-height:28px}}.legal__p{margin:0}.standard{width:100%;display:flex;flex-direction:column;align-items:center;gap:36px;text-align:center;font-size:16px;line-height:24px}@media (min-width: 768px){.standard{font-size:18px;line-height:28px}}.standard__links{display:flex;flex-direction:column;align-items:center;gap:16px}@media (min-width: 768px){.standard__links{flex-direction:row;flex-wrap:wrap;justify-content:center;gap:36px}}'}},[513,"weg-footer",{layout:[1],resolved:[32]},void 0,{layout:[{watchLayout:0}]}]);function d(){"undefined"!=typeof customElements&&["weg-footer"].forEach((e=>{"weg-footer"===e&&(customElements.get(t(e))||customElements.define(t(e),f))}))}d();const p=f,u=d;export{p as WegFooter,u as defineCustomElement}
|
package/dist/esm/loader.js
CHANGED
|
@@ -5,7 +5,7 @@ import { g as globalScripts } from './app-globals-DQuL1Twl.js';
|
|
|
5
5
|
const defineCustomElements = async (win, options) => {
|
|
6
6
|
if (typeof window === 'undefined') return undefined;
|
|
7
7
|
await globalScripts();
|
|
8
|
-
return bootstrapLazy([["my-component",[[513,"my-component",{"first":[1],"middle":[1],"last":[1]}]]],["weg-footer",[[513,"weg-footer",{"
|
|
8
|
+
return bootstrapLazy([["my-component",[[513,"my-component",{"first":[1],"middle":[1],"last":[1]}]]],["weg-footer",[[513,"weg-footer",{"layout":[1],"resolved":[32]},null,{"layout":[{"watchLayout":0}]}]]]], options);
|
|
9
9
|
};
|
|
10
10
|
|
|
11
11
|
export { defineCustomElements };
|
|
@@ -101,12 +101,13 @@ const WegFooter = class {
|
|
|
101
101
|
registerInstance(this, hostRef);
|
|
102
102
|
}
|
|
103
103
|
/**
|
|
104
|
-
* Layout
|
|
104
|
+
* Layout payload, supplied by the host application.
|
|
105
105
|
*
|
|
106
106
|
* In JS / framework templates, pass the object directly (e.g. Angular
|
|
107
|
-
* `[
|
|
107
|
+
* `[layout]="layoutData"`, React `layout={layoutData}`, vanilla
|
|
108
|
+
* `el.layout = layoutData`).
|
|
108
109
|
*
|
|
109
|
-
* In plain HTML, pass the same JSON as a string attribute.
|
|
110
|
+
* In plain HTML, pass the same JSON as a string on the `layout` attribute.
|
|
110
111
|
*
|
|
111
112
|
* Expected shape:
|
|
112
113
|
* ```json
|
|
@@ -120,19 +121,19 @@ const WegFooter = class {
|
|
|
120
121
|
* }
|
|
121
122
|
* ```
|
|
122
123
|
*/
|
|
123
|
-
|
|
124
|
+
layout;
|
|
124
125
|
resolved = EMPTY_FOOTER;
|
|
125
126
|
resolve() {
|
|
126
|
-
if (this.
|
|
127
|
+
if (this.layout === undefined || this.layout === null) {
|
|
127
128
|
this.resolved = EMPTY_FOOTER;
|
|
128
129
|
return;
|
|
129
130
|
}
|
|
130
|
-
this.resolved = normalizeFooterData(parseJsonProp(this.
|
|
131
|
+
this.resolved = normalizeFooterData(parseJsonProp(this.layout));
|
|
131
132
|
}
|
|
132
133
|
componentWillLoad() {
|
|
133
134
|
this.resolve();
|
|
134
135
|
}
|
|
135
|
-
|
|
136
|
+
watchLayout() {
|
|
136
137
|
this.resolve();
|
|
137
138
|
}
|
|
138
139
|
renderLegalText() {
|
|
@@ -154,11 +155,11 @@ const WegFooter = class {
|
|
|
154
155
|
return (h("div", { class: "standard__links" }, links.map((l) => (h("a", { class: "footer-link", href: l.href }, l.label)))));
|
|
155
156
|
}
|
|
156
157
|
render() {
|
|
157
|
-
return (h("footer", { key: '
|
|
158
|
+
return (h("footer", { key: 'ba9a2b07235bbad73f4f2aea762af917249f621b', class: "footer" }, h("div", { key: '88a8a9de95c09bf4c5524fc942976b7ababe110d', class: "container" }, this.renderSocialLinks(), h("div", { key: '2a21b07909bcb975c4bade8a291b050d83d52e8c', class: "standard" }, this.renderStandardLinks(), this.renderLegalText()))));
|
|
158
159
|
}
|
|
159
160
|
static get watchers() { return {
|
|
160
|
-
"
|
|
161
|
-
"
|
|
161
|
+
"layout": [{
|
|
162
|
+
"watchLayout": 0
|
|
162
163
|
}]
|
|
163
164
|
}; }
|
|
164
165
|
};
|
|
@@ -17,5 +17,5 @@ var patchBrowser = () => {
|
|
|
17
17
|
|
|
18
18
|
patchBrowser().then(async (options) => {
|
|
19
19
|
await globalScripts();
|
|
20
|
-
return bootstrapLazy([["my-component",[[513,"my-component",{"first":[1],"middle":[1],"last":[1]}]]],["weg-footer",[[513,"weg-footer",{"
|
|
20
|
+
return bootstrapLazy([["my-component",[[513,"my-component",{"first":[1],"middle":[1],"last":[1]}]]],["weg-footer",[[513,"weg-footer",{"layout":[1],"resolved":[32]},null,{"layout":[{"watchLayout":0}]}]]]], options);
|
|
21
21
|
});
|
|
@@ -9,12 +9,13 @@ type LayoutData = {
|
|
|
9
9
|
};
|
|
10
10
|
export declare class WegFooter {
|
|
11
11
|
/**
|
|
12
|
-
* Layout
|
|
12
|
+
* Layout payload, supplied by the host application.
|
|
13
13
|
*
|
|
14
14
|
* In JS / framework templates, pass the object directly (e.g. Angular
|
|
15
|
-
* `[
|
|
15
|
+
* `[layout]="layoutData"`, React `layout={layoutData}`, vanilla
|
|
16
|
+
* `el.layout = layoutData`).
|
|
16
17
|
*
|
|
17
|
-
* In plain HTML, pass the same JSON as a string attribute.
|
|
18
|
+
* In plain HTML, pass the same JSON as a string on the `layout` attribute.
|
|
18
19
|
*
|
|
19
20
|
* Expected shape:
|
|
20
21
|
* ```json
|
|
@@ -28,11 +29,11 @@ export declare class WegFooter {
|
|
|
28
29
|
* }
|
|
29
30
|
* ```
|
|
30
31
|
*/
|
|
31
|
-
|
|
32
|
+
layout?: LayoutData | string;
|
|
32
33
|
private resolved;
|
|
33
34
|
private resolve;
|
|
34
35
|
componentWillLoad(): void;
|
|
35
|
-
protected
|
|
36
|
+
protected watchLayout(): void;
|
|
36
37
|
private renderLegalText;
|
|
37
38
|
private renderSocialLinks;
|
|
38
39
|
private renderStandardLinks;
|
|
@@ -22,9 +22,9 @@ export namespace Components {
|
|
|
22
22
|
}
|
|
23
23
|
interface WegFooter {
|
|
24
24
|
/**
|
|
25
|
-
* Layout
|
|
25
|
+
* Layout payload, supplied by the host application. In JS / framework templates, pass the object directly (e.g. Angular `[layout]="layoutData"`, React `layout={layoutData}`, vanilla `el.layout = layoutData`). In plain HTML, pass the same JSON as a string on the `layout` attribute. Expected shape: ```json { "footer": { "social": [{ "platform": "LinkedIn", "href": "https://..." }], "standardLinks": [{ "label": "About Us", "href": "/about" }], "credits": "...", "copyright": "..." } } ```
|
|
26
26
|
*/
|
|
27
|
-
"
|
|
27
|
+
"layout"?: LayoutData | string;
|
|
28
28
|
}
|
|
29
29
|
}
|
|
30
30
|
declare global {
|
|
@@ -62,9 +62,9 @@ declare namespace LocalJSX {
|
|
|
62
62
|
}
|
|
63
63
|
interface WegFooter {
|
|
64
64
|
/**
|
|
65
|
-
* Layout
|
|
65
|
+
* Layout payload, supplied by the host application. In JS / framework templates, pass the object directly (e.g. Angular `[layout]="layoutData"`, React `layout={layoutData}`, vanilla `el.layout = layoutData`). In plain HTML, pass the same JSON as a string on the `layout` attribute. Expected shape: ```json { "footer": { "social": [{ "platform": "LinkedIn", "href": "https://..." }], "standardLinks": [{ "label": "About Us", "href": "/about" }], "credits": "...", "copyright": "..." } } ```
|
|
66
66
|
*/
|
|
67
|
-
"
|
|
67
|
+
"layout"?: LayoutData | string;
|
|
68
68
|
}
|
|
69
69
|
|
|
70
70
|
interface MyComponentAttributes {
|
|
@@ -73,7 +73,7 @@ declare namespace LocalJSX {
|
|
|
73
73
|
"last": string;
|
|
74
74
|
}
|
|
75
75
|
interface WegFooterAttributes {
|
|
76
|
-
"
|
|
76
|
+
"layout": LayoutData | string;
|
|
77
77
|
}
|
|
78
78
|
|
|
79
79
|
interface IntrinsicElements {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{r as t,h as e}from"./p-QiJxC4Ow.js";const i={social:[],standardLinks:[],credits:"",copyright:""};function n(t){return/^https?:\/\//.test(t)}function
|
|
1
|
+
import{r as t,h as e}from"./p-QiJxC4Ow.js";const i={social:[],standardLinks:[],credits:"",copyright:""};function n(t){return/^https?:\/\//.test(t)}function o(t){return"string"==typeof t&&t.trim().length>0}function a(t){if(!Array.isArray(t))return[];const e=[];for(const n of t){if(!n||"object"!=typeof n)continue;const t=n.platform,a=n.href;("LinkedIn"===(i=t)||"Instagram"===i||"TikTok"===i||"YouTube"===i)&&o(a)&&e.push({platform:t,href:a.trim()})}var i;return e}function r(t){if(!Array.isArray(t))return[];const e=[];for(const i of t){if(!i||"object"!=typeof i)continue;const t=i.label,n=i.href;o(t)&&o(n)&&e.push({label:t.trim(),href:n.trim()})}return e}function l({platform:t}){const i={viewBox:"0 0 48 48",width:48,height:48,fill:"none",xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",focusable:"false"};switch(t){case"LinkedIn":return e("svg",{...i},e("path",{d:"M24 0C37.2548 0 48 10.7452 48 24C48 37.2548 37.2548 48 24 48C10.7452 48 0 37.2548 0 24C0 10.7452 10.7452 0 24 0ZM12.9082 33.4736H17.5889V19.4111H12.9082V33.4736ZM29.0791 19.0811C26.5942 19.0811 25.4815 20.4458 24.8604 21.4033V19.4111H20.1797C20.2412 20.7279 20.1799 33.4203 20.1797 33.4736H24.8604V25.6201C24.8604 25.1998 24.8909 24.7804 25.0146 24.4795C25.3529 23.6399 26.1231 22.7705 27.416 22.7705C29.1103 22.7705 29.7881 24.0605 29.7881 25.9502V33.4736H34.4678V25.4102C34.4677 21.0909 32.1589 19.0811 29.0791 19.0811ZM15.2793 12.6318C13.6783 12.6319 12.6319 13.6818 12.6318 15.0605C12.6318 16.4108 13.6474 17.4912 15.2188 17.4912H15.249C16.8807 17.491 17.8965 16.4107 17.8965 15.0605C17.866 13.6818 16.8804 12.6318 15.2793 12.6318Z",fill:"white"}));case"Instagram":return e("svg",{...i},e("path",{d:"M24 0C37.2548 0 48 10.7452 48 24C48 37.2548 37.2548 48 24 48C10.7452 48 0 37.2548 0 24C0 10.7452 10.7452 0 24 0ZM23.999 11.2002C20.5245 11.2002 20.0877 11.2152 18.7227 11.2773C17.3602 11.3398 16.43 11.5556 15.6162 11.8721C14.7744 12.199 14.06 12.636 13.3486 13.3477C12.6366 14.0591 12.1991 14.7736 11.8711 15.6152C11.5538 16.4293 11.3377 17.3597 11.2764 18.7217C11.2153 20.087 11.2002 20.5238 11.2002 24C11.2002 27.476 11.2155 27.9113 11.2773 29.2764C11.34 30.639 11.5558 31.5699 11.8721 32.3838C12.1993 33.2255 12.636 33.94 13.3477 34.6514C14.0589 35.3634 14.7739 35.801 15.6152 36.1279C16.4295 36.4444 17.3596 36.6602 18.7217 36.7227C20.087 36.7848 20.5233 36.7998 23.999 36.7998C27.4756 36.7998 27.911 36.7848 29.2764 36.7227C30.639 36.6602 31.5704 36.4445 32.3848 36.1279C33.2261 35.801 33.9394 35.3631 34.6504 34.6514C35.3624 33.9399 35.7999 33.2254 36.1279 32.3838C36.4426 31.5697 36.6586 30.6393 36.7227 29.2773C36.784 27.912 36.7998 27.4763 36.7998 24C36.7998 20.5242 36.784 20.0876 36.7227 18.7227C36.6587 17.36 36.4426 16.4291 36.1279 15.6152C35.7999 14.7734 35.3623 14.0591 34.6504 13.3477C33.9385 12.6358 33.2264 12.1987 32.3838 11.8721C31.5678 11.5555 30.6371 11.3397 29.2744 11.2773C27.9093 11.2152 27.4745 11.2002 23.999 11.2002Z",fill:"white"}),e("path",{d:"M22.8525 13.5068C23.1933 13.5063 23.5739 13.5068 24.001 13.5068C27.4186 13.5068 27.8242 13.5197 29.1738 13.5811C30.4214 13.6381 31.0986 13.8463 31.5498 14.0215C32.1471 14.2535 32.5737 14.5305 33.0215 14.9785C33.4695 15.4265 33.746 15.8538 33.9785 16.4512C34.1537 16.9018 34.3631 17.5792 34.4199 18.8271C34.4812 20.1763 34.4941 20.5822 34.4941 23.998C34.4941 27.4134 34.4812 27.819 34.4199 29.168C34.3629 30.4158 34.1537 31.0933 33.9785 31.5439C33.7466 32.1412 33.4693 32.567 33.0215 33.0146C32.5735 33.4627 32.1474 33.7397 31.5498 33.9717C31.0992 34.1477 30.4216 34.356 29.1738 34.4131C27.8245 34.4744 27.4186 34.4883 24.001 34.4883C20.5835 34.4883 20.1783 34.4744 18.8291 34.4131C17.5811 34.3555 16.9036 34.1469 16.4521 33.9717C15.8549 33.7397 15.4284 33.4625 14.9805 33.0146C14.5325 32.5666 14.255 32.1406 14.0225 31.543C13.8473 31.0923 13.6378 30.4148 13.5811 29.167C13.5197 27.8179 13.5078 27.4121 13.5078 23.9941C13.5078 20.5762 13.5197 20.1726 13.5811 18.8232C13.6381 17.5755 13.8473 16.8984 14.0225 16.4473C14.2545 15.8499 14.5325 15.4236 14.9805 14.9756C15.4285 14.5276 15.8549 14.2501 16.4521 14.0176C16.9034 13.8416 17.5811 13.6335 18.8291 13.5762C20.0097 13.5228 20.4674 13.5066 22.8525 13.5039V13.5068ZM24.001 17.4268C20.371 17.427 17.4277 20.3709 17.4277 24.001C17.4279 27.6309 20.3711 30.5721 24.001 30.5723C27.631 30.5723 30.573 27.631 30.5732 24.001C30.5732 20.3708 27.6311 17.4268 24.001 17.4268ZM30.834 15.6318C29.9861 15.632 29.2979 16.3198 29.2979 17.168C29.2979 18.0159 29.9861 18.704 30.834 18.7041C31.682 18.7041 32.3701 18.016 32.3701 17.168C32.37 16.32 31.6819 15.6318 30.834 15.6318Z",fill:"white"}),e("path",{d:"M24.0011 19.7334C26.3574 19.7334 28.2678 21.6436 28.2678 24.0001C28.2678 26.3564 26.3574 28.2668 24.0011 28.2668C21.6445 28.2668 19.7344 26.3564 19.7344 24.0001C19.7344 21.6436 21.6445 19.7334 24.0011 19.7334Z",fill:"white"}));case"TikTok":return e("svg",{...i},e("path",{d:"M24 0C37.2548 0 48 10.7452 48 24C48 37.2548 37.2548 48 24 48C10.7452 48 0 37.2548 0 24C0 10.7452 10.7452 0 24 0ZM25.0273 28.3477C25.0273 30.2955 23.4721 31.8955 21.5361 31.8955C19.6003 31.8954 18.0449 30.2955 18.0449 28.3477C18.045 26.4347 19.5659 24.8693 21.4326 24.7998V20.6953C17.3188 20.7648 14.0001 24.1391 14 28.3477C14 32.5912 17.3883 36 21.5713 36C25.754 35.9998 29.1416 32.5562 29.1416 28.3477V19.9648C30.6627 21.0779 32.5295 21.7396 34.5 21.7744V17.6699C31.4579 17.5656 29.0723 15.0609 29.0723 12H25.0273V28.3477Z",fill:"white"}));case"YouTube":return e("svg",{...i},e("path",{d:"M24 0C37.2548 0 48 10.7452 48 24C48 37.2548 37.2548 48 24 48C10.7452 48 0 37.2548 0 24C0 10.7452 10.7452 0 24 0ZM24 15.2002C24 15.2002 15.9944 15.1997 13.998 15.749C12.8966 16.0513 12.0288 16.9423 11.7344 18.0732C11.1996 20.1231 11.2002 24.4004 11.2002 24.4004C11.2002 24.4472 11.2026 28.6878 11.7344 30.7266C12.0288 31.8575 12.8966 32.7483 13.998 33.0508C15.9944 33.6 24 33.5996 24 33.5996C24 33.5996 32.0057 33.6 34.002 33.0508C35.1033 32.7483 35.9703 31.8575 36.2646 30.7266C36.7966 28.6879 36.7998 24.4472 36.7998 24.4004C36.7998 24.4004 36.7996 20.1231 36.2646 18.0732C35.9703 16.9424 35.1033 16.0513 34.002 15.749C32.0057 15.1997 24 15.2002 24 15.2002Z",fill:"white"}),e("path",{d:"M21.6016 28.7998V20.7998L28.0016 24.8L21.6016 28.7998Z",fill:"white"}))}}const s=class{constructor(e){t(this,e)}layout;resolved=i;resolve(){this.resolved=null!=this.layout?function(t){const e=t&&"object"==typeof t?t:{},i=e.footer&&"object"==typeof e.footer?e.footer:{};return{social:a(i?.social),standardLinks:r(i?.standardLinks),credits:o(i?.credits)?i.credits.trim():"",copyright:o(i?.copyright)?i.copyright.trim():""}}(function(t){if("string"!=typeof t)return t;const e=t.trim();if(e)try{return JSON.parse(e)}catch{return}}(this.layout)):i}componentWillLoad(){this.resolve()}watchLayout(){this.resolve()}renderLegalText(){const{credits:t,copyright:i}=this.resolved;return t||i?e("div",{class:"legal"},t?e("p",{class:"legal__p"},t):null,t&&i?e("p",{class:"legal__p"},String.fromCharCode(8203)):null,i?e("p",{class:"legal__p"},i):null):null}renderSocialLinks(){const t=this.resolved.social;return 0===t.length?null:e("div",{class:"social"},t.map((t=>e("a",{class:"social__link",href:t.href,"aria-label":t.platform,target:n(t.href)?"_blank":void 0,rel:n(t.href)?"noreferrer noopener":void 0},e("span",{class:"social__icon","aria-hidden":"true"},e(l,{platform:t.platform}))))))}renderStandardLinks(){const t=this.resolved.standardLinks;return 0===t.length?null:e("div",{class:"standard__links"},t.map((t=>e("a",{class:"footer-link",href:t.href},t.label))))}render(){return e("footer",{key:"ba9a2b07235bbad73f4f2aea762af917249f621b",class:"footer"},e("div",{key:"88a8a9de95c09bf4c5524fc942976b7ababe110d",class:"container"},this.renderSocialLinks(),e("div",{key:"2a21b07909bcb975c4bade8a291b050d83d52e8c",class:"standard"},this.renderStandardLinks(),this.renderLegalText())))}static get watchers(){return{layout:[{watchLayout:0}]}}};s.style=':host{display:block}.footer{background:#030712;color:#ffffff;padding:28px 32px;font-family:ui-sans-serif, system-ui, -apple-system, Segoe UI, Roboto, Helvetica, Arial, "Apple Color Emoji", "Segoe UI Emoji";font-weight:300}.container{max-width:1024px;margin:0 auto;display:flex;flex-direction:column;align-items:center;gap:20px}@media (min-width: 768px){.footer{padding:44px 56px}.container{gap:36px}}.social{display:flex;align-items:center;justify-content:center;gap:16px}@media (min-width: 768px){.social{gap:28px}}.social__link{width:48px;height:48px;display:inline-flex;align-items:center;justify-content:center;border-radius:999px;background:transparent;color:inherit;text-decoration:none;transition:opacity 150ms ease;outline:none}.social__link:hover{opacity:0.9}.social__link:focus-visible{outline:2px solid rgba(255, 255, 255, 0.9);outline-offset:4px}.social__icon{display:inline-flex;width:48px;height:48px}.footer-link{color:#ffffff;text-decoration:underline;text-underline-offset:2px;text-decoration-thickness:1px;outline:none}.footer-link:hover{text-decoration-thickness:2px}.footer-link:focus-visible{outline:2px solid rgba(255, 255, 255, 0.9);outline-offset:4px}.legal{width:100%;max-width:860px;text-align:center;font-size:16px;line-height:24px}@media (min-width: 768px){.legal{font-size:18px;line-height:28px}}.legal__p{margin:0}.standard{width:100%;display:flex;flex-direction:column;align-items:center;gap:36px;text-align:center;font-size:16px;line-height:24px}@media (min-width: 768px){.standard{font-size:18px;line-height:28px}}.standard__links{display:flex;flex-direction:column;align-items:center;gap:16px}@media (min-width: 768px){.standard__links{flex-direction:row;flex-wrap:wrap;justify-content:center;gap:36px}}';export{s as weg_footer}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{p as
|
|
1
|
+
import{p as o,b as t}from"./p-QiJxC4Ow.js";export{s as setNonce}from"./p-QiJxC4Ow.js";import{g as a}from"./p-DQuL1Twl.js";(()=>{const t=import.meta.url,a={};return""!==t&&(a.resourcesUrl=new URL(".",t).href),o(a)})().then((async o=>(await a(),t([["p-d1addb13",[[513,"my-component",{first:[1],middle:[1],last:[1]}]]],["p-99843bbd",[[513,"weg-footer",{layout:[1],resolved:[32]},null,{layout:[{watchLayout:0}]}]]]],o))));
|
package/docs/angular.md
CHANGED
|
@@ -30,9 +30,9 @@ If `defineCustomElements` is async in your Stencil build, `await` it (or chain `
|
|
|
30
30
|
|
|
31
31
|
Add `schemas: [CUSTOM_ELEMENTS_SCHEMA]` to every `@Component` whose template uses `<weg-footer>` (it does not cascade from the root through `router-outlet` children).
|
|
32
32
|
|
|
33
|
-
## 4. Pass
|
|
33
|
+
## 4. Pass layout with property binding
|
|
34
34
|
|
|
35
|
-
Use **`[
|
|
35
|
+
Use **`[layout]="..."`** so Angular sets the element’s JavaScript `layout` property (Stencil `@Prop()`), not an HTML attribute.
|
|
36
36
|
|
|
37
37
|
Example with the bundled sample payload:
|
|
38
38
|
|
|
@@ -57,7 +57,7 @@ export class App {
|
|
|
57
57
|
```html
|
|
58
58
|
<!-- src/app/app.html -->
|
|
59
59
|
<router-outlet />
|
|
60
|
-
<weg-footer [
|
|
60
|
+
<weg-footer [layout]="layoutData()"></weg-footer>
|
|
61
61
|
```
|
|
62
62
|
|
|
63
63
|
Enable `resolveJsonModule` in the TypeScript config used by the app (e.g. `tsconfig.app.json`) if you import `dummy-data.json`.
|
|
@@ -79,7 +79,7 @@ Then bootstrap as usual (no `defineCustomElements()` call required for that tag)
|
|
|
79
79
|
| Symptom | Cause / fix |
|
|
80
80
|
| --- | --- |
|
|
81
81
|
| `'weg-footer' is not a known element` | Add `schemas: [CUSTOM_ELEMENTS_SCHEMA]` on the component whose template contains `<weg-footer>`. |
|
|
82
|
-
| Footer missing or empty box | `defineCustomElements()` not called before bootstrap (or footer bundle not imported), or `
|
|
82
|
+
| Footer missing or empty box | `defineCustomElements()` not called before bootstrap (or footer bundle not imported), or `layout` not set / wrong shape — compare with `dummy-data.json`. |
|
|
83
83
|
| SSR: `document is not defined` | Guard `defineCustomElements()` with `typeof window !== 'undefined'` or `isPlatformBrowser`. |
|
|
84
84
|
|
|
85
85
|
## TypeScript typings
|
package/docs/nextjs.md
ADDED
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
# Next.js (App Router)
|
|
2
|
+
|
|
3
|
+
Guide for **Next.js 13+ App Router** (`app/` directory). For Vite/CRA-style client-only React, see **[React SPA](./react.md)**.
|
|
4
|
+
|
|
5
|
+
## Why Next.js is different
|
|
6
|
+
|
|
7
|
+
| Topic | SPA (React 19) | Next.js App Router |
|
|
8
|
+
| --- | --- | --- |
|
|
9
|
+
| **Where `<weg-footer>` runs** | Client only | Must be in a **Client Component** (`"use client"`) |
|
|
10
|
+
| **Server Components** | N/A | Default in `app/` — cannot call `defineCustomElements()` or touch `window` |
|
|
11
|
+
| **SSR output** | N/A | Server HTML is often an **empty** `<weg-footer></weg-footer>` until the client bundle hydrates |
|
|
12
|
+
| **`layout={object}`** | Works on React 19+ | **Does not work reliably** — RSC/SSR serializes props; object props on custom elements become useless attributes |
|
|
13
|
+
| **Recommended `layout` value** | Object (React 19+) or string | **`JSON.stringify(layout)`** always |
|
|
14
|
+
|
|
15
|
+
Stencil custom elements need browser APIs. Registration and rendering belong in a small client wrapper; the root **Server** layout only imports that wrapper.
|
|
16
|
+
|
|
17
|
+
## Requirements
|
|
18
|
+
|
|
19
|
+
| Requirement | Notes |
|
|
20
|
+
| --- | --- |
|
|
21
|
+
| **Next.js 13+** | App Router (`app/layout.tsx`) |
|
|
22
|
+
| **React 19** | Matches current Next defaults; string `layout` still required for custom elements |
|
|
23
|
+
| **`transpilePackages`** | Next must compile `weg-shared-layout` (see below) |
|
|
24
|
+
|
|
25
|
+
## Install
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
npm i weg-shared-layout
|
|
29
|
+
# or
|
|
30
|
+
pnpm add weg-shared-layout
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## 1. Transpile the package
|
|
34
|
+
|
|
35
|
+
In `next.config.ts` / `next.config.js`:
|
|
36
|
+
|
|
37
|
+
```ts
|
|
38
|
+
import type { NextConfig } from 'next';
|
|
39
|
+
|
|
40
|
+
const nextConfig: NextConfig = {
|
|
41
|
+
transpilePackages: ['weg-shared-layout'],
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
export default nextConfig;
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
Without this, you may see build errors or stale/uncompiled Stencil output in the Next bundle.
|
|
48
|
+
|
|
49
|
+
## 2. Client `Footer` component
|
|
50
|
+
|
|
51
|
+
Create a dedicated Client Component (pattern verified in [weg-payload](https://github.com/jobsac/weg-payload)):
|
|
52
|
+
|
|
53
|
+
```tsx
|
|
54
|
+
// src/components/layout/Footer.tsx
|
|
55
|
+
'use client';
|
|
56
|
+
|
|
57
|
+
import layout from 'weg-shared-layout/dummy-data.json';
|
|
58
|
+
import { defineCustomElements } from 'weg-shared-layout/loader';
|
|
59
|
+
import 'weg-shared-layout/weg-footer';
|
|
60
|
+
|
|
61
|
+
defineCustomElements();
|
|
62
|
+
|
|
63
|
+
export function Footer() {
|
|
64
|
+
return (
|
|
65
|
+
<weg-footer layout={JSON.stringify(layout)} suppressHydrationWarning />
|
|
66
|
+
);
|
|
67
|
+
}
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
### Why each line matters
|
|
71
|
+
|
|
72
|
+
| Line | Purpose |
|
|
73
|
+
| --- | --- |
|
|
74
|
+
| `'use client'` | Allows `defineCustomElements`, custom element upgrade, and DOM property updates |
|
|
75
|
+
| `defineCustomElements()` | Registers `<weg-footer>` in the browser (module runs once per client bundle) |
|
|
76
|
+
| `import 'weg-shared-layout/weg-footer'` | Ensures the component definition is bundled |
|
|
77
|
+
| `layout={JSON.stringify(layout)}` | Sets a string attribute/property Next/React can pass through SSR → client; component parses JSON |
|
|
78
|
+
| `suppressHydrationWarning` | Server renders empty tag; client fills content — avoids React hydration mismatch noise |
|
|
79
|
+
|
|
80
|
+
Do **not** pass `layout={layoutObject}` in Next — it will not hydrate correctly.
|
|
81
|
+
|
|
82
|
+
## 3. Server layout: import the client footer
|
|
83
|
+
|
|
84
|
+
```tsx
|
|
85
|
+
// app/layout.tsx (Server Component — no "use client")
|
|
86
|
+
import { Footer } from '@/components/layout/Footer';
|
|
87
|
+
|
|
88
|
+
export default function RootLayout({ children }: { children: React.ReactNode }) {
|
|
89
|
+
return (
|
|
90
|
+
<html lang="en">
|
|
91
|
+
<body>
|
|
92
|
+
{children}
|
|
93
|
+
<Footer />
|
|
94
|
+
</body>
|
|
95
|
+
</html>
|
|
96
|
+
);
|
|
97
|
+
}
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
Fetch layout on the server and pass it into `<Footer layout={...} />` when you wire production data (see below).
|
|
101
|
+
|
|
102
|
+
## 4. Production: fetch on the server, stringify for the client
|
|
103
|
+
|
|
104
|
+
```tsx
|
|
105
|
+
// app/layout.tsx
|
|
106
|
+
import { Footer } from '@/components/layout/Footer';
|
|
107
|
+
|
|
108
|
+
const LAYOUT_URL = 'https://weg-payload-test.vercel.app/api/layout';
|
|
109
|
+
|
|
110
|
+
async function getLayout() {
|
|
111
|
+
const res = await fetch(LAYOUT_URL, { next: { revalidate: 60 } });
|
|
112
|
+
if (!res.ok) throw new Error('Failed to load layout');
|
|
113
|
+
return res.json();
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
export default async function RootLayout({ children }: { children: React.ReactNode }) {
|
|
117
|
+
const layout = await getLayout();
|
|
118
|
+
|
|
119
|
+
return (
|
|
120
|
+
<html lang="en">
|
|
121
|
+
<body>
|
|
122
|
+
{children}
|
|
123
|
+
<Footer layout={layout} />
|
|
124
|
+
</body>
|
|
125
|
+
</html>
|
|
126
|
+
);
|
|
127
|
+
}
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
```tsx
|
|
131
|
+
// src/components/layout/Footer.tsx
|
|
132
|
+
'use client';
|
|
133
|
+
|
|
134
|
+
import { defineCustomElements } from 'weg-shared-layout/loader';
|
|
135
|
+
import 'weg-shared-layout/weg-footer';
|
|
136
|
+
|
|
137
|
+
defineCustomElements();
|
|
138
|
+
|
|
139
|
+
type LayoutData = {
|
|
140
|
+
footer?: {
|
|
141
|
+
social?: { platform: string; href: string }[];
|
|
142
|
+
standardLinks?: { label: string; href: string }[];
|
|
143
|
+
credits?: string;
|
|
144
|
+
copyright?: string;
|
|
145
|
+
};
|
|
146
|
+
};
|
|
147
|
+
|
|
148
|
+
export function Footer({ layout }: { layout: LayoutData }) {
|
|
149
|
+
return (
|
|
150
|
+
<weg-footer layout={JSON.stringify(layout)} suppressHydrationWarning />
|
|
151
|
+
);
|
|
152
|
+
}
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
**Rule:** whatever crosses the Server → Client boundary must be **serializable**. Pass the plain object into the Client Component, then **`JSON.stringify` inside the client** before setting it on `<weg-footer>`.
|
|
156
|
+
|
|
157
|
+
## Passing `layout` — quick reference
|
|
158
|
+
|
|
159
|
+
| Approach | Server Component | Client Component | Works in Next? |
|
|
160
|
+
| --- | --- | --- | --- |
|
|
161
|
+
| `layout={object}` on `<weg-footer>` | No (don’t use CE directly) | Tried often | **No** |
|
|
162
|
+
| `layout={JSON.stringify(obj)}` on `<weg-footer>` | No | Yes | **Yes** (recommended) |
|
|
163
|
+
| Pass `layout` object to `<Footer />`, stringify inside | Fetch/await JSON | `JSON.stringify` in JSX | **Yes** (recommended for CMS) |
|
|
164
|
+
| `ref` + `el.layout = obj` in `useEffect` | No | Yes | Yes (escape hatch) |
|
|
165
|
+
| `prop:layout={obj}` | No | Unreliable | **Avoid** |
|
|
166
|
+
|
|
167
|
+
## TypeScript
|
|
168
|
+
|
|
169
|
+
Use **module augmentation** (not triple-slash references in every file). Example `src/types/weg-shared-layout-jsx.d.ts`:
|
|
170
|
+
|
|
171
|
+
```ts
|
|
172
|
+
import type { JSX as WegSharedLayoutJSX } from 'weg-shared-layout';
|
|
173
|
+
import type { DetailedHTMLProps, HTMLAttributes } from 'react';
|
|
174
|
+
|
|
175
|
+
declare module 'react' {
|
|
176
|
+
namespace JSX {
|
|
177
|
+
interface IntrinsicElements extends WegSharedLayoutJSX.IntrinsicElements {
|
|
178
|
+
'weg-footer': WegSharedLayoutJSX.IntrinsicElements['weg-footer'] &
|
|
179
|
+
DetailedHTMLProps<HTMLAttributes<HTMLWegFooterElement>, HTMLWegFooterElement>;
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
Enable `resolveJsonModule` if you import `weg-shared-layout/dummy-data.json` in the client footer.
|
|
186
|
+
|
|
187
|
+
## Troubleshooting
|
|
188
|
+
|
|
189
|
+
| Symptom | Likely cause | Fix |
|
|
190
|
+
| --- | --- | --- |
|
|
191
|
+
| `document is not defined` | `defineCustomElements()` in a Server Component | Move registration to `"use client"` `Footer.tsx` only. |
|
|
192
|
+
| Empty `<weg-footer>` in Elements panel | SSR placeholder before hydration | Expected until client JS runs; confirm client bundle loads and `defineCustomElements()` ran. |
|
|
193
|
+
| Empty footer after hydration | `layout={object}` or missing stringify | Use `layout={JSON.stringify(layout)}` in the client component. |
|
|
194
|
+
| Hydration warning on `<weg-footer>` | Server HTML ≠ client DOM | Add `suppressHydrationWarning`; ensure `layout` JSON is identical server vs client props. |
|
|
195
|
+
| Build error importing package | Package not transpiled | Add `transpilePackages: ['weg-shared-layout']`. |
|
|
196
|
+
| `'weg-footer' is not a known element` (TS) | Missing JSX types | Add module augmentation file above. |
|
|
197
|
+
| Footer never upgrades | Loader/tag not imported on client | `import 'weg-shared-layout/weg-footer'` + `defineCustomElements()` in client file. |
|
|
198
|
+
|
|
199
|
+
### DevTools tips
|
|
200
|
+
|
|
201
|
+
1. **Elements:** Before hydration, `<weg-footer>` is often empty. After hydration, expand the shadow root — links should appear inside `#shadow-root`.
|
|
202
|
+
2. **Console:** Log `document.querySelector('weg-footer')?.layout` in the browser — should be a **string** (JSON) or object, not `undefined`.
|
|
203
|
+
3. **Network:** Confirm your layout API returns the same shape as [`dummy-data.json`](../src/assets/dummy-data.json).
|
|
204
|
+
4. **React DevTools:** `Footer` should show under a Client Component boundary; parent `layout.tsx` stays a Server Component.
|
|
205
|
+
|
|
206
|
+
### Ref fallback (if stringify still fails)
|
|
207
|
+
|
|
208
|
+
```tsx
|
|
209
|
+
'use client';
|
|
210
|
+
|
|
211
|
+
import { useEffect, useRef } from 'react';
|
|
212
|
+
import { defineCustomElements } from 'weg-shared-layout/loader';
|
|
213
|
+
import 'weg-shared-layout/weg-footer';
|
|
214
|
+
|
|
215
|
+
defineCustomElements();
|
|
216
|
+
|
|
217
|
+
export function Footer({ layout }: { layout: unknown }) {
|
|
218
|
+
const ref = useRef<HTMLWegFooterElement>(null);
|
|
219
|
+
|
|
220
|
+
useEffect(() => {
|
|
221
|
+
if (ref.current) ref.current.layout = layout as object;
|
|
222
|
+
}, [layout]);
|
|
223
|
+
|
|
224
|
+
return <weg-footer ref={ref} suppressHydrationWarning />;
|
|
225
|
+
}
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
## Integration checklist
|
|
229
|
+
|
|
230
|
+
- [ ] `weg-shared-layout` installed
|
|
231
|
+
- [ ] `transpilePackages: ['weg-shared-layout']` in `next.config`
|
|
232
|
+
- [ ] `Footer.tsx` with `'use client'`, loader, tag import, `JSON.stringify`, `suppressHydrationWarning`
|
|
233
|
+
- [ ] Root `app/layout.tsx` imports `<Footer />` (no `defineCustomElements` on server)
|
|
234
|
+
- [ ] Layout data fetched server-side (or static import) and passed as serializable props
|
|
235
|
+
- [ ] TypeScript module augmentation for `'weg-footer'`
|
|
236
|
+
- [ ] Verified in browser after hydration (not only view-source HTML)
|
|
237
|
+
|
|
238
|
+
## See also
|
|
239
|
+
|
|
240
|
+
- **[React SPA](./react.md)** — object `layout={...}` on React 19 without SSR
|
|
241
|
+
- **[Angular](./angular.md)**
|
|
242
|
+
- **[Plain HTML / vanilla JS](./vanilla.md)**
|
|
243
|
+
- **[Package readme](../readme.md)**
|
package/docs/react.md
CHANGED
|
@@ -1,8 +1,34 @@
|
|
|
1
|
-
# React
|
|
1
|
+
# React (SPA)
|
|
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
|
+
## What is `<weg-footer>`?
|
|
6
|
+
|
|
7
|
+
`<weg-footer>` is a **presentational** [Stencil](https://stenciljs.com/) Web Component shipped by `weg-shared-layout`. It renders the site footer (social links, standard links, credits, copyright) from a **layout payload** you provide.
|
|
8
|
+
|
|
9
|
+
The component **does not fetch data**. Your app loads JSON (from an API, CMS, or a static file) and passes it on the `layout` property.
|
|
10
|
+
|
|
11
|
+
Payload shape matches [`dummy-data.json`](../src/assets/dummy-data.json) (see also [readme](../readme.md#how-it-works)).
|
|
12
|
+
|
|
13
|
+
## Requirements
|
|
14
|
+
|
|
15
|
+
| Requirement | Notes |
|
|
16
|
+
| --- | --- |
|
|
17
|
+
| **React 19+** | React 19 maps custom-element props to DOM **properties** when possible. Older React often sets `layout` as a string **attribute**, which breaks object payloads. |
|
|
18
|
+
| **Bundler** | Must resolve `node_modules` ESM/CJS from `weg-shared-layout`. |
|
|
19
|
+
| **TypeScript (optional)** | Module augmentation below; enable `resolveJsonModule` if you import `dummy-data.json`. |
|
|
20
|
+
|
|
21
|
+
## Install
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
npm i weg-shared-layout
|
|
25
|
+
# or
|
|
26
|
+
pnpm add weg-shared-layout
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## 1. Register custom elements (once)
|
|
30
|
+
|
|
31
|
+
Call `defineCustomElements()` **once** before the first `<weg-footer>` render — typically in your app entry (`main.tsx`, `index.tsx`):
|
|
6
32
|
|
|
7
33
|
```ts
|
|
8
34
|
import { defineCustomElements } from 'weg-shared-layout/loader';
|
|
@@ -10,27 +36,166 @@ import { defineCustomElements } from 'weg-shared-layout/loader';
|
|
|
10
36
|
defineCustomElements();
|
|
11
37
|
```
|
|
12
38
|
|
|
13
|
-
|
|
39
|
+
Also side-effect import the tag so your bundler includes the component definition:
|
|
40
|
+
|
|
41
|
+
```ts
|
|
42
|
+
import 'weg-shared-layout/weg-footer';
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
**Alternative:** import only the footer bundle (no loader call):
|
|
46
|
+
|
|
47
|
+
```ts
|
|
48
|
+
import 'weg-shared-layout/weg-footer';
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
Use the loader when you may add more tags from this package later.
|
|
14
52
|
|
|
15
|
-
|
|
53
|
+
## 2. Render the footer
|
|
54
|
+
|
|
55
|
+
### Recommended: pass `layout` as an object (React 19+)
|
|
16
56
|
|
|
17
57
|
```tsx
|
|
18
58
|
import 'weg-shared-layout/weg-footer';
|
|
19
59
|
import layout from 'weg-shared-layout/dummy-data.json';
|
|
20
60
|
|
|
21
61
|
export function SiteFooter() {
|
|
22
|
-
return <weg-footer
|
|
62
|
+
return <weg-footer layout={layout} />;
|
|
23
63
|
}
|
|
24
64
|
```
|
|
25
65
|
|
|
26
|
-
|
|
66
|
+
With React 19+, `layout={layoutObject}` is applied as the custom element’s **`layout` property** (object), which `<weg-footer>` expects.
|
|
67
|
+
|
|
68
|
+
### Fallback: `JSON.stringify` (all React versions)
|
|
69
|
+
|
|
70
|
+
If you are on React 18 or see an empty footer despite correct data, pass a JSON **string**. The component parses string values the same as objects:
|
|
71
|
+
|
|
72
|
+
```tsx
|
|
73
|
+
<weg-footer layout={JSON.stringify(layout)} />
|
|
74
|
+
```
|
|
27
75
|
|
|
28
|
-
|
|
76
|
+
### Plain HTML attribute
|
|
29
77
|
|
|
30
|
-
|
|
78
|
+
Outside React, you can set `layout='{"footer":{...}}'` on the element. Prefer the property in SPA code.
|
|
79
|
+
|
|
80
|
+
## 3. Production: fetch layout from your API
|
|
81
|
+
|
|
82
|
+
Example using the public test API (same shape as `dummy-data.json`):
|
|
83
|
+
|
|
84
|
+
```tsx
|
|
85
|
+
import { useEffect, useState } from 'react';
|
|
86
|
+
import 'weg-shared-layout/weg-footer';
|
|
87
|
+
import layoutFixture from 'weg-shared-layout/dummy-data.json';
|
|
88
|
+
|
|
89
|
+
type LayoutData = typeof layoutFixture;
|
|
90
|
+
|
|
91
|
+
const LAYOUT_URL = 'https://weg-payload-test.vercel.app/api/layout';
|
|
92
|
+
|
|
93
|
+
export function SiteFooter() {
|
|
94
|
+
const [layout, setLayout] = useState<LayoutData | null>(null);
|
|
95
|
+
|
|
96
|
+
useEffect(() => {
|
|
97
|
+
let cancelled = false;
|
|
98
|
+
fetch(LAYOUT_URL)
|
|
99
|
+
.then((res) => {
|
|
100
|
+
if (!res.ok) throw new Error(`layout fetch failed: ${res.status}`);
|
|
101
|
+
return res.json() as Promise<LayoutData>;
|
|
102
|
+
})
|
|
103
|
+
.then((data) => {
|
|
104
|
+
if (!cancelled) setLayout(data);
|
|
105
|
+
})
|
|
106
|
+
.catch(console.error);
|
|
107
|
+
return () => {
|
|
108
|
+
cancelled = true;
|
|
109
|
+
};
|
|
110
|
+
}, []);
|
|
111
|
+
|
|
112
|
+
if (!layout) return null; // or a skeleton
|
|
113
|
+
|
|
114
|
+
return <weg-footer layout={layout} />;
|
|
115
|
+
}
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
Replace the URL with your own CMS/API. Keep the object shape aligned with `dummy-data.json`.
|
|
119
|
+
|
|
120
|
+
## TypeScript: module augmentation
|
|
121
|
+
|
|
122
|
+
Do **not** rely on a triple-slash reference in every file. Augment React’s JSX namespace once (e.g. `src/types/weg-shared-layout-jsx.d.ts`):
|
|
31
123
|
|
|
32
124
|
```ts
|
|
33
|
-
|
|
125
|
+
import type { JSX as WegSharedLayoutJSX } from 'weg-shared-layout';
|
|
126
|
+
import type { DetailedHTMLProps, HTMLAttributes } from 'react';
|
|
127
|
+
|
|
128
|
+
declare module 'react' {
|
|
129
|
+
namespace JSX {
|
|
130
|
+
interface IntrinsicElements extends WegSharedLayoutJSX.IntrinsicElements {
|
|
131
|
+
'weg-footer': WegSharedLayoutJSX.IntrinsicElements['weg-footer'] &
|
|
132
|
+
DetailedHTMLProps<HTMLAttributes<HTMLWegFooterElement>, HTMLWegFooterElement>;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
Ensure that file is included by your `tsconfig.json` `include`/`files`.
|
|
139
|
+
|
|
140
|
+
Enable in `tsconfig.json` when importing JSON fixtures:
|
|
141
|
+
|
|
142
|
+
```json
|
|
143
|
+
{
|
|
144
|
+
"compilerOptions": {
|
|
145
|
+
"resolveJsonModule": true
|
|
146
|
+
}
|
|
147
|
+
}
|
|
34
148
|
```
|
|
35
149
|
|
|
36
|
-
|
|
150
|
+
## `layout` prop vs attribute (why React version matters)
|
|
151
|
+
|
|
152
|
+
| How data is set | Works with object? |
|
|
153
|
+
| --- | --- |
|
|
154
|
+
| **Property** `el.layout = obj` / React 19 `layout={obj}` | Yes |
|
|
155
|
+
| **Attribute** `layout="[object Object]"` / React 18 `layout={obj}` | No — footer stays empty |
|
|
156
|
+
| **Attribute** `layout='{"footer":...}'` / `layout={JSON.stringify(obj)}` | Yes — component parses JSON |
|
|
157
|
+
|
|
158
|
+
`<weg-footer>` accepts `layout` as either an object or a JSON string (see `parseJsonProp` in the component source).
|
|
159
|
+
|
|
160
|
+
## Note: `prop:layout` is unreliable in React
|
|
161
|
+
|
|
162
|
+
Some examples set Stencil props with a `prop:` prefix (e.g. `prop:layout={data}`). In React this is **not dependable** — behavior varies by version and reconciler. Prefer:
|
|
163
|
+
|
|
164
|
+
1. **`layout={object}`** on React 19+, or
|
|
165
|
+
2. **`layout={JSON.stringify(object)}`**, or
|
|
166
|
+
3. **Ref fallback** after mount:
|
|
167
|
+
|
|
168
|
+
```tsx
|
|
169
|
+
import { useEffect, useRef } from 'react';
|
|
170
|
+
import type layoutFixture from 'weg-shared-layout/dummy-data.json';
|
|
171
|
+
|
|
172
|
+
type LayoutData = typeof layoutFixture;
|
|
173
|
+
|
|
174
|
+
export function SiteFooter({ layout }: { layout: LayoutData }) {
|
|
175
|
+
const ref = useRef<HTMLWegFooterElement>(null);
|
|
176
|
+
|
|
177
|
+
useEffect(() => {
|
|
178
|
+
if (ref.current) ref.current.layout = layout;
|
|
179
|
+
}, [layout]);
|
|
180
|
+
|
|
181
|
+
return <weg-footer ref={ref} />;
|
|
182
|
+
}
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
## Troubleshooting
|
|
186
|
+
|
|
187
|
+
| Symptom | Likely cause | Fix |
|
|
188
|
+
| --- | --- | --- |
|
|
189
|
+
| Empty footer, no errors | `defineCustomElements()` not called, or missing `import 'weg-shared-layout/weg-footer'` | Register loader + import tag in entry before render. |
|
|
190
|
+
| Empty footer, data looks correct | React set `layout` as attribute (`[object Object]`) | Upgrade to React 19+, or use `layout={JSON.stringify(layout)}` or ref assignment. |
|
|
191
|
+
| TypeScript: `'weg-footer' does not exist on JSX.IntrinsicElements` | No module augmentation | Add `weg-shared-layout-jsx.d.ts` as above. |
|
|
192
|
+
| Cannot find module `weg-shared-layout/dummy-data.json` | `resolveJsonModule` off | Enable in `tsconfig.json`. |
|
|
193
|
+
| Footer flashes then disappears | Strict Mode double-mount + async layout | Ensure stable `layout` reference; avoid resetting state on remount. |
|
|
194
|
+
| Styles missing | Shadow DOM is encapsulated | Footer ships its own CSS; do not expect global site styles inside the shadow root. |
|
|
195
|
+
|
|
196
|
+
## See also
|
|
197
|
+
|
|
198
|
+
- **[Next.js App Router](./nextjs.md)** — Server Components, `transpilePackages`, hydration
|
|
199
|
+
- **[Angular](./angular.md)**
|
|
200
|
+
- **[Plain HTML / vanilla JS](./vanilla.md)**
|
|
201
|
+
- **[Package readme](../readme.md)**
|
package/docs/vanilla.md
CHANGED
|
@@ -9,10 +9,10 @@ With a bundler that resolves `node_modules` imports:
|
|
|
9
9
|
import layout from 'weg-shared-layout/dummy-data.json';
|
|
10
10
|
|
|
11
11
|
defineCustomElements();
|
|
12
|
-
document.getElementById('footer').
|
|
12
|
+
document.getElementById('footer').layout = layout;
|
|
13
13
|
</script>
|
|
14
14
|
```
|
|
15
15
|
|
|
16
|
-
Otherwise, copy `dummy-data.json` to your static assets, `fetch` it, parse JSON, then assign **`element.
|
|
16
|
+
Otherwise, copy `dummy-data.json` to your static assets, `fetch` it, parse JSON, then assign **`element.layout`**.
|
|
17
17
|
|
|
18
|
-
You can also pass a JSON string on the **`
|
|
18
|
+
You can also pass a JSON string on the **`layout` attribute**; the component parses it the same way as an object `layout` property.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "weg-shared-layout",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.12",
|
|
4
4
|
"description": "Shared layout Web Components built with Stencil",
|
|
5
5
|
"main": "dist/index.cjs.js",
|
|
6
6
|
"module": "dist/index.js",
|
|
@@ -43,14 +43,6 @@
|
|
|
43
43
|
"loader/",
|
|
44
44
|
"src/assets/dummy-data.json"
|
|
45
45
|
],
|
|
46
|
-
"scripts": {
|
|
47
|
-
"prepack": "npm run build",
|
|
48
|
-
"build": "stencil build",
|
|
49
|
-
"start": "stencil build --dev --watch --serve",
|
|
50
|
-
"test": "stencil-test --prod",
|
|
51
|
-
"test:watch": "stencil-test --prod --watch",
|
|
52
|
-
"generate": "stencil generate"
|
|
53
|
-
},
|
|
54
46
|
"devDependencies": {
|
|
55
47
|
"@stencil/core": "^4.27.1 || ^5.0.0-0",
|
|
56
48
|
"@stencil/vitest": "^1.8.3",
|
|
@@ -59,5 +51,12 @@
|
|
|
59
51
|
"playwright": "^1.52.0",
|
|
60
52
|
"vitest": "^4.0.0"
|
|
61
53
|
},
|
|
62
|
-
"license": "MIT"
|
|
63
|
-
|
|
54
|
+
"license": "MIT",
|
|
55
|
+
"scripts": {
|
|
56
|
+
"build": "stencil build",
|
|
57
|
+
"start": "stencil build --dev --watch --serve",
|
|
58
|
+
"test": "stencil-test --prod",
|
|
59
|
+
"test:watch": "stencil-test --prod --watch",
|
|
60
|
+
"generate": "stencil generate"
|
|
61
|
+
}
|
|
62
|
+
}
|
package/readme.md
CHANGED
|
@@ -14,7 +14,7 @@ npm i weg-shared-layout
|
|
|
14
14
|
|
|
15
15
|
`<weg-footer>` is a **presentational** Web Component: it does **not** fetch data.
|
|
16
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 `
|
|
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.
|
|
18
18
|
|
|
19
19
|
The payload shape matches **`dummy-data.json`**:
|
|
20
20
|
|
|
@@ -29,7 +29,8 @@ The payload shape matches **`dummy-data.json`**:
|
|
|
29
29
|
| Guide | Doc |
|
|
30
30
|
| --- | --- |
|
|
31
31
|
| Angular | [docs/angular.md](./docs/angular.md) |
|
|
32
|
-
| React | [docs/react.md](./docs/react.md) |
|
|
32
|
+
| React (SPA, client-only) | [docs/react.md](./docs/react.md) |
|
|
33
|
+
| Next.js (App Router) | [docs/nextjs.md](./docs/nextjs.md) |
|
|
33
34
|
| Plain HTML / vanilla JS | [docs/vanilla.md](./docs/vanilla.md) |
|
|
34
35
|
|
|
35
36
|
## Publishing (maintainers)
|