@uniweb/runtime 1.2.0 → 1.2.1
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/ssr.js +81 -105
- package/dist/ssr.js.map +1 -1
- package/package.json +3 -3
- package/src/background-shared.js +16 -10
- package/src/background.js +182 -0
- package/src/components/Background.jsx +19 -294
- package/src/components/PageRenderer.jsx +4 -2
- package/src/setup.js +2 -1
- package/src/ssr-renderer.js +26 -122
package/dist/ssr.js
CHANGED
|
@@ -222,9 +222,12 @@ function siteUrl(url) {
|
|
|
222
222
|
function withOpacity(color, opacity) {
|
|
223
223
|
if (typeof color !== "string" || !color) return color;
|
|
224
224
|
if (color.startsWith("#")) {
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
225
|
+
let hex = color.slice(1);
|
|
226
|
+
if (hex.length === 3 || hex.length === 4) hex = [...hex].map((c) => c + c).join("");
|
|
227
|
+
if (!/^[0-9a-f]{6}([0-9a-f]{2})?$/i.test(hex)) return color;
|
|
228
|
+
const r = parseInt(hex.slice(0, 2), 16);
|
|
229
|
+
const g = parseInt(hex.slice(2, 4), 16);
|
|
230
|
+
const b = parseInt(hex.slice(4, 6), 16);
|
|
228
231
|
return `rgba(${r}, ${g}, ${b}, ${opacity})`;
|
|
229
232
|
}
|
|
230
233
|
if (color.startsWith("rgb")) {
|
|
@@ -233,6 +236,76 @@ function withOpacity(color, opacity) {
|
|
|
233
236
|
}
|
|
234
237
|
return color;
|
|
235
238
|
}
|
|
239
|
+
const h = React.createElement;
|
|
240
|
+
const FILL = { position: "absolute", inset: 0 };
|
|
241
|
+
function ColorLayer({ color }) {
|
|
242
|
+
if (!color) return null;
|
|
243
|
+
return h("div", { className: "background-color", style: { ...FILL, backgroundColor: color }, "aria-hidden": "true" });
|
|
244
|
+
}
|
|
245
|
+
function GradientLayer({ gradient }) {
|
|
246
|
+
if (!gradient) return null;
|
|
247
|
+
if (typeof gradient === "string") {
|
|
248
|
+
return h("div", { className: "background-gradient", style: { ...FILL, background: gradient }, "aria-hidden": "true" });
|
|
249
|
+
}
|
|
250
|
+
const start = gradient.start ?? "transparent";
|
|
251
|
+
const end = gradient.end ?? "transparent";
|
|
252
|
+
const startOpacity = gradient.startOpacity ?? 1;
|
|
253
|
+
const endOpacity = gradient.endOpacity ?? 1;
|
|
254
|
+
const startColor = startOpacity < 1 ? withOpacity(start, startOpacity) : start;
|
|
255
|
+
const endColor = endOpacity < 1 ? withOpacity(end, endOpacity) : end;
|
|
256
|
+
const background = `linear-gradient(${gradient.angle ?? 0}deg, ${startColor} ${gradient.startPosition ?? 0}%, ${endColor} ${gradient.endPosition ?? 100}%)`;
|
|
257
|
+
return h("div", { className: "background-gradient", style: { ...FILL, background }, "aria-hidden": "true" });
|
|
258
|
+
}
|
|
259
|
+
function ImageLayer({ image }) {
|
|
260
|
+
if (!image?.src) return null;
|
|
261
|
+
const style = {
|
|
262
|
+
...FILL,
|
|
263
|
+
backgroundImage: `url(${siteUrl(image.src)})`,
|
|
264
|
+
backgroundPosition: image.position ?? "center",
|
|
265
|
+
backgroundSize: image.size ?? "cover",
|
|
266
|
+
backgroundRepeat: "no-repeat"
|
|
267
|
+
};
|
|
268
|
+
return h("div", { className: "background-image", style, "aria-hidden": "true" });
|
|
269
|
+
}
|
|
270
|
+
function VideoPoster({ video }) {
|
|
271
|
+
if (!video?.src || !video.poster) return null;
|
|
272
|
+
return h(ImageLayer, { image: { src: video.poster, size: "cover", position: "center" } });
|
|
273
|
+
}
|
|
274
|
+
function Overlay({ overlay }) {
|
|
275
|
+
if (!overlay?.enabled) return null;
|
|
276
|
+
const opacity = overlay.opacity ?? 0.5;
|
|
277
|
+
if (overlay.gradient) {
|
|
278
|
+
const g = overlay.gradient;
|
|
279
|
+
const background = `linear-gradient(${g.angle ?? 180}deg, ${g.start ?? "rgba(0,0,0,0.7)"} ${g.startPosition ?? 0}%, ${g.end ?? "rgba(0,0,0,0)"} ${g.endPosition ?? 100}%)`;
|
|
280
|
+
return h("div", {
|
|
281
|
+
className: "background-overlay background-overlay--gradient",
|
|
282
|
+
style: { ...FILL, background, opacity, pointerEvents: "none" },
|
|
283
|
+
"aria-hidden": "true"
|
|
284
|
+
});
|
|
285
|
+
}
|
|
286
|
+
const base = overlay.type === "light" ? "255, 255, 255" : "0, 0, 0";
|
|
287
|
+
return h("div", {
|
|
288
|
+
className: "background-overlay background-overlay--solid",
|
|
289
|
+
style: { ...FILL, backgroundColor: `rgba(${base}, ${opacity})`, pointerEvents: "none" },
|
|
290
|
+
"aria-hidden": "true"
|
|
291
|
+
});
|
|
292
|
+
}
|
|
293
|
+
function Background({ mode, color, gradient, image, video, overlay, className = "", Video = VideoPoster }) {
|
|
294
|
+
if (!mode) return null;
|
|
295
|
+
return h(
|
|
296
|
+
"div",
|
|
297
|
+
{
|
|
298
|
+
className: `background background--${mode} ${className}`.trim(),
|
|
299
|
+
style: { ...FILL, overflow: "hidden", zIndex: 0 },
|
|
300
|
+
"aria-hidden": "true"
|
|
301
|
+
},
|
|
302
|
+
mode === "color" ? h(ColorLayer, { color }) : null,
|
|
303
|
+
mode === "gradient" ? h(GradientLayer, { gradient }) : null,
|
|
304
|
+
mode === "image" ? h(ImageLayer, { image }) : null,
|
|
305
|
+
mode === "video" ? h(Video, { video }) : null,
|
|
306
|
+
h(Overlay, { overlay })
|
|
307
|
+
);
|
|
308
|
+
}
|
|
236
309
|
function default404Html(basePath = "") {
|
|
237
310
|
const homeHref = basePath ? `${basePath}/` : "/";
|
|
238
311
|
return `<div class="page-not-found" style="min-height:80vh;display:flex;flex-direction:column;align-items:center;justify-content:center;padding:2rem;text-align:center"><h1 style="font-size:3rem;font-weight:bold;color:#1f2937;margin-bottom:1rem">404</h1><p style="color:#64748b;margin-bottom:2rem">Page not found</p><a href="${homeHref}" style="color:#3b82f6;text-decoration:underline">Go to homepage</a></div>`;
|
|
@@ -452,105 +525,7 @@ function getWrapperProps(block) {
|
|
|
452
525
|
}
|
|
453
526
|
function renderBackground(background) {
|
|
454
527
|
if (!background?.mode) return null;
|
|
455
|
-
|
|
456
|
-
position: "absolute",
|
|
457
|
-
inset: "0",
|
|
458
|
-
overflow: "hidden",
|
|
459
|
-
zIndex: 0
|
|
460
|
-
};
|
|
461
|
-
const children = [];
|
|
462
|
-
if (background.mode === "color" && background.color) {
|
|
463
|
-
children.push(
|
|
464
|
-
React.createElement("div", {
|
|
465
|
-
key: "bg-color",
|
|
466
|
-
className: "background-color",
|
|
467
|
-
style: { position: "absolute", inset: "0", backgroundColor: background.color },
|
|
468
|
-
"aria-hidden": "true"
|
|
469
|
-
})
|
|
470
|
-
);
|
|
471
|
-
}
|
|
472
|
-
if (background.mode === "gradient" && background.gradient) {
|
|
473
|
-
const g = background.gradient;
|
|
474
|
-
let bgValue;
|
|
475
|
-
if (typeof g === "string") {
|
|
476
|
-
bgValue = g;
|
|
477
|
-
} else {
|
|
478
|
-
const {
|
|
479
|
-
start = "transparent",
|
|
480
|
-
end = "transparent",
|
|
481
|
-
angle = 0,
|
|
482
|
-
startPosition = 0,
|
|
483
|
-
endPosition = 100,
|
|
484
|
-
startOpacity = 1,
|
|
485
|
-
endOpacity = 1
|
|
486
|
-
} = g;
|
|
487
|
-
const startColor = startOpacity < 1 ? withOpacity(start, startOpacity) : start;
|
|
488
|
-
const endColor = endOpacity < 1 ? withOpacity(end, endOpacity) : end;
|
|
489
|
-
bgValue = `linear-gradient(${angle}deg, ${startColor} ${startPosition}%, ${endColor} ${endPosition}%)`;
|
|
490
|
-
}
|
|
491
|
-
children.push(
|
|
492
|
-
React.createElement("div", {
|
|
493
|
-
key: "bg-gradient",
|
|
494
|
-
className: "background-gradient",
|
|
495
|
-
style: { position: "absolute", inset: "0", background: bgValue },
|
|
496
|
-
"aria-hidden": "true"
|
|
497
|
-
})
|
|
498
|
-
);
|
|
499
|
-
}
|
|
500
|
-
if (background.mode === "image" && background.image?.src) {
|
|
501
|
-
const img = background.image;
|
|
502
|
-
children.push(
|
|
503
|
-
React.createElement("div", {
|
|
504
|
-
key: "bg-image",
|
|
505
|
-
className: "background-image",
|
|
506
|
-
style: {
|
|
507
|
-
position: "absolute",
|
|
508
|
-
inset: "0",
|
|
509
|
-
backgroundImage: `url(${siteUrl(img.src)})`,
|
|
510
|
-
backgroundPosition: img.position || "center",
|
|
511
|
-
backgroundSize: img.size || "cover",
|
|
512
|
-
backgroundRepeat: "no-repeat"
|
|
513
|
-
},
|
|
514
|
-
"aria-hidden": "true"
|
|
515
|
-
})
|
|
516
|
-
);
|
|
517
|
-
}
|
|
518
|
-
if (background.overlay?.enabled) {
|
|
519
|
-
const ov = background.overlay;
|
|
520
|
-
let overlayStyle;
|
|
521
|
-
if (ov.gradient) {
|
|
522
|
-
const g = ov.gradient;
|
|
523
|
-
overlayStyle = {
|
|
524
|
-
position: "absolute",
|
|
525
|
-
inset: "0",
|
|
526
|
-
pointerEvents: "none",
|
|
527
|
-
background: `linear-gradient(${g.angle || 180}deg, ${g.start || "rgba(0,0,0,0.7)"} ${g.startPosition || 0}%, ${g.end || "rgba(0,0,0,0)"} ${g.endPosition || 100}%)`,
|
|
528
|
-
opacity: ov.opacity ?? 0.5
|
|
529
|
-
};
|
|
530
|
-
} else {
|
|
531
|
-
const baseColor = ov.type === "light" ? "255, 255, 255" : "0, 0, 0";
|
|
532
|
-
overlayStyle = {
|
|
533
|
-
position: "absolute",
|
|
534
|
-
inset: "0",
|
|
535
|
-
pointerEvents: "none",
|
|
536
|
-
backgroundColor: `rgba(${baseColor}, ${ov.opacity ?? 0.5})`
|
|
537
|
-
};
|
|
538
|
-
}
|
|
539
|
-
children.push(
|
|
540
|
-
React.createElement("div", {
|
|
541
|
-
key: "bg-overlay",
|
|
542
|
-
className: ov.gradient ? "background-overlay background-overlay--gradient" : "background-overlay background-overlay--solid",
|
|
543
|
-
style: overlayStyle,
|
|
544
|
-
"aria-hidden": "true"
|
|
545
|
-
})
|
|
546
|
-
);
|
|
547
|
-
}
|
|
548
|
-
if (children.length === 0) return null;
|
|
549
|
-
return React.createElement("div", {
|
|
550
|
-
className: `background background--${background.mode}`,
|
|
551
|
-
style: containerStyle,
|
|
552
|
-
"aria-hidden": "true"
|
|
553
|
-
}, ...children);
|
|
528
|
+
return React.createElement(Background, background);
|
|
554
529
|
}
|
|
555
530
|
function renderBlock(block, { as = "section", stickySelf = false } = {}) {
|
|
556
531
|
const Component = block.initComponent();
|
|
@@ -563,10 +538,13 @@ function renderBlock(block, { as = "section", stickySelf = false } = {}) {
|
|
|
563
538
|
const meta = getComponentMeta(block.type);
|
|
564
539
|
const entityStore = block.website?.entityStore;
|
|
565
540
|
let entityData = null;
|
|
541
|
+
let pending = false;
|
|
566
542
|
if (entityStore) {
|
|
567
543
|
const resolved = entityStore.resolve(block, meta);
|
|
568
544
|
if (resolved.status === "ready") entityData = resolved.data;
|
|
545
|
+
pending = resolved.status === "pending";
|
|
569
546
|
}
|
|
547
|
+
block.dataLoading = pending;
|
|
570
548
|
const prepared = prepareProps(block, meta, entityData);
|
|
571
549
|
const params = prepared.params;
|
|
572
550
|
const content = { ...prepared.content, ...block.properties };
|
|
@@ -691,9 +669,7 @@ function initPrerender(content, foundation, extensionsOrOptions, maybeOptions) {
|
|
|
691
669
|
)
|
|
692
670
|
);
|
|
693
671
|
};
|
|
694
|
-
uniweb.backgroundRenderer =
|
|
695
|
-
return renderBackground(background);
|
|
696
|
-
};
|
|
672
|
+
uniweb.backgroundRenderer = Background;
|
|
697
673
|
wireFoundationCapabilities(uniweb, foundation);
|
|
698
674
|
ensureThemeCss(uniweb, foundation);
|
|
699
675
|
const website = uniweb.activeWebsite;
|