fragment-headless-sdk 2.1.0 → 2.1.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/components/Announcement/index.js +0 -2
- package/dist/components/Hero/DesktopHero.js +0 -1
- package/dist/components/Hero/MobileHero.js +14 -5
- package/dist/utils/color.d.ts +2 -0
- package/dist/utils/color.js +67 -0
- package/dist/utils/index.d.ts +1 -0
- package/dist/utils/index.js +1 -0
- package/package.json +1 -1
|
@@ -2,7 +2,6 @@ import React, { useEffect, useRef } from "react";
|
|
|
2
2
|
import { AnnouncementType, ButtonType } from "../../constants";
|
|
3
3
|
import { buildClickUrl, fireImpressionWhenVisible, getThemeClasses, mergeSlotAttributes, mergeSlotClasses, mergeSlotStyles, resolveToken, resolveTokenByCategory, } from "../../utils";
|
|
4
4
|
import AnnouncementButton from "./AnnouncementButton";
|
|
5
|
-
import { AnnouncementStyles } from "./AnnouncementStyles";
|
|
6
5
|
import CountdownTimer from "./CountdownTimer";
|
|
7
6
|
export default function Announcement({ content, type, handleClose, }) {
|
|
8
7
|
const ref = useRef(null);
|
|
@@ -55,7 +54,6 @@ export default function Announcement({ content, type, handleClose, }) {
|
|
|
55
54
|
const closeButtonStyle = mergeSlotStyles({ color: closeButtonColor }, styling, "closeButton");
|
|
56
55
|
const closeButtonAttributes = mergeSlotAttributes(styling, "closeButton");
|
|
57
56
|
return (React.createElement("div", { ref: ref, className: rootClass, style: rootStyle, ...(rootAttributes ?? {}) },
|
|
58
|
-
React.createElement(AnnouncementStyles, null),
|
|
59
57
|
React.createElement("div", { className: innerClass, style: innerStyle, ...(innerAttributes ?? {}) },
|
|
60
58
|
type === AnnouncementType.Marquee ? (React.createElement("div", { className: marqueeContainerClass, style: marqueeContainerStyle, ...(marqueeContainerAttributes ?? {}) },
|
|
61
59
|
React.createElement("div", { className: marqueeTextWrapperClass, style: marqueeTextWrapperStyle, ...(marqueeTextWrapperAttributes ?? {}) },
|
|
@@ -22,7 +22,6 @@ export default function DesktopHero({ buttonHref, content, colors, contentWidthC
|
|
|
22
22
|
fontSize: typography.title.fontSize,
|
|
23
23
|
lineHeight: typography.title.lineHeight,
|
|
24
24
|
text: content?.title,
|
|
25
|
-
className: "mt-4",
|
|
26
25
|
color: colors.title,
|
|
27
26
|
font: typography.title.font,
|
|
28
27
|
}),
|
|
@@ -1,13 +1,22 @@
|
|
|
1
1
|
import React from "react";
|
|
2
|
+
import { ensureSafeColor } from "../../utils/color";
|
|
2
3
|
import { renderText, } from "../../utils/hero-resolvers";
|
|
3
4
|
export default function MobileHero({ buttonHref, content, colors, typography, }) {
|
|
5
|
+
const safeTitleColor = ensureSafeColor(colors.title, "#ffffff");
|
|
6
|
+
const safeTextColor = ensureSafeColor(colors.text, "#ffffff");
|
|
7
|
+
const titleFontSize = typography.title.fontSize === "text-5xl"
|
|
8
|
+
? "text-3xl"
|
|
9
|
+
: typography.title.fontSize;
|
|
10
|
+
const descriptionFontSize = typography.description.fontSize === "text-3xl"
|
|
11
|
+
? "text-lg"
|
|
12
|
+
: typography.description.fontSize;
|
|
4
13
|
return (React.createElement("div", { className: "relative z-10 mx-auto gap-4 flex max-w-screen-md flex-col items-center justify-center py-6 text-center", style: { backgroundColor: colors.background } },
|
|
5
14
|
renderText({
|
|
6
|
-
fontSize:
|
|
15
|
+
fontSize: titleFontSize,
|
|
7
16
|
lineHeight: typography.title.lineHeight,
|
|
8
17
|
text: content?.title,
|
|
9
|
-
className: "px-4 drop-shadow-xl text-center",
|
|
10
|
-
color:
|
|
18
|
+
className: "px-4 drop-shadow-xl text-center font-bold",
|
|
19
|
+
color: safeTitleColor,
|
|
11
20
|
font: typography.title.font,
|
|
12
21
|
}),
|
|
13
22
|
content?.videoUrl ? (React.createElement("div", { className: "w-full" },
|
|
@@ -15,11 +24,11 @@ export default function MobileHero({ buttonHref, content, colors, typography, })
|
|
|
15
24
|
React.createElement("img", { src: content.mobileImageUrl, alt: content.title || "Hero", className: "h-full w-full object-cover" }))) : content?.imageUrl ? (React.createElement("div", { className: "w-full" },
|
|
16
25
|
React.createElement("img", { src: content.imageUrl, alt: content.title || "Hero", className: "h-full w-full object-cover" }))) : null,
|
|
17
26
|
renderText({
|
|
18
|
-
fontSize:
|
|
27
|
+
fontSize: descriptionFontSize,
|
|
19
28
|
lineHeight: typography.description.lineHeight,
|
|
20
29
|
text: content?.description,
|
|
21
30
|
className: "px-4 drop-shadow-lg text-center mt-4",
|
|
22
|
-
color:
|
|
31
|
+
color: safeTextColor,
|
|
23
32
|
font: typography.description.font,
|
|
24
33
|
}),
|
|
25
34
|
content?.buttonLink && content?.buttonText && (React.createElement("a", { href: buttonHref, target: "_blank", rel: "noopener noreferrer", className: "no-underline" },
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
const HEX_COLOR_REGEX = /^#([0-9a-f]{3}|[0-9a-f]{6})$/i;
|
|
2
|
+
const RGB_COLOR_REGEX = /^rgba?\s*\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})(?:\s*,\s*(\d*\.?\d+))?\s*\)$/i;
|
|
3
|
+
function hexToRgb(color) {
|
|
4
|
+
if (!HEX_COLOR_REGEX.test(color)) {
|
|
5
|
+
return null;
|
|
6
|
+
}
|
|
7
|
+
let hex = color.slice(1);
|
|
8
|
+
if (hex.length === 3) {
|
|
9
|
+
hex = hex
|
|
10
|
+
.split("")
|
|
11
|
+
.map((char) => char + char)
|
|
12
|
+
.join("");
|
|
13
|
+
}
|
|
14
|
+
const bigint = parseInt(hex, 16);
|
|
15
|
+
return {
|
|
16
|
+
r: (bigint >> 16) & 255,
|
|
17
|
+
g: (bigint >> 8) & 255,
|
|
18
|
+
b: bigint & 255,
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
function rgbStringToRgb(color) {
|
|
22
|
+
const match = color.match(RGB_COLOR_REGEX);
|
|
23
|
+
if (!match) {
|
|
24
|
+
return null;
|
|
25
|
+
}
|
|
26
|
+
const [, r, g, b] = match;
|
|
27
|
+
const red = Number(r);
|
|
28
|
+
const green = Number(g);
|
|
29
|
+
const blue = Number(b);
|
|
30
|
+
if ([red, green, blue].some((value) => Number.isNaN(value))) {
|
|
31
|
+
return null;
|
|
32
|
+
}
|
|
33
|
+
return { r: red, g: green, b: blue };
|
|
34
|
+
}
|
|
35
|
+
function normalizeColor(color) {
|
|
36
|
+
if (!color) {
|
|
37
|
+
return null;
|
|
38
|
+
}
|
|
39
|
+
const trimmed = color.trim();
|
|
40
|
+
return hexToRgb(trimmed) ?? rgbStringToRgb(trimmed);
|
|
41
|
+
}
|
|
42
|
+
function getRelativeLuminance(rgb) {
|
|
43
|
+
const transform = (value) => {
|
|
44
|
+
const channel = value / 255;
|
|
45
|
+
if (channel <= 0.03928) {
|
|
46
|
+
return channel / 12.92;
|
|
47
|
+
}
|
|
48
|
+
return Math.pow((channel + 0.055) / 1.055, 2.4);
|
|
49
|
+
};
|
|
50
|
+
const r = transform(rgb.r);
|
|
51
|
+
const g = transform(rgb.g);
|
|
52
|
+
const b = transform(rgb.b);
|
|
53
|
+
return 0.2126 * r + 0.7152 * g + 0.0722 * b;
|
|
54
|
+
}
|
|
55
|
+
export function isDarkColor(color) {
|
|
56
|
+
const rgb = normalizeColor(color);
|
|
57
|
+
if (!rgb) {
|
|
58
|
+
return false;
|
|
59
|
+
}
|
|
60
|
+
return getRelativeLuminance(rgb) < 0.5;
|
|
61
|
+
}
|
|
62
|
+
export function ensureSafeColor(color, fallback) {
|
|
63
|
+
if (!color) {
|
|
64
|
+
return fallback;
|
|
65
|
+
}
|
|
66
|
+
return isDarkColor(color) ? fallback : color;
|
|
67
|
+
}
|
package/dist/utils/index.d.ts
CHANGED
package/dist/utils/index.js
CHANGED