@spectare-personalisation/react 0.4.0 → 0.6.0
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/index.cjs +292 -164
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +98 -55
- package/dist/index.d.ts +98 -55
- package/dist/index.js +213 -115
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
|
-
|
|
2
|
-
import { marked } from 'marked';
|
|
3
|
-
import DOMPurify from 'isomorphic-dompurify';
|
|
4
|
-
import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
|
|
1
|
+
'use client';
|
|
5
2
|
|
|
6
3
|
// src/PersonalisedSection.tsx
|
|
4
|
+
import { useEffect, useRef, useState } from "react";
|
|
5
|
+
|
|
6
|
+
// src/ComponentRenderer.tsx
|
|
7
|
+
import { marked } from "marked";
|
|
8
|
+
import DOMPurify from "isomorphic-dompurify";
|
|
7
9
|
|
|
8
10
|
// src/types.ts
|
|
9
11
|
var COMPONENT_ZONES = {
|
|
@@ -25,15 +27,53 @@ function filterAssemblyByZone(assembly, zone) {
|
|
|
25
27
|
return effectiveZone === zone;
|
|
26
28
|
});
|
|
27
29
|
}
|
|
30
|
+
var COMPONENT_CATEGORIES = {
|
|
31
|
+
AnnouncementBar: "conversion",
|
|
32
|
+
HeroStatement: "hero",
|
|
33
|
+
AtomCard: "content",
|
|
34
|
+
StatGrid: "content",
|
|
35
|
+
CodeBlock: "technical",
|
|
36
|
+
ComparisonTable: "evaluation",
|
|
37
|
+
FeatureList: "content",
|
|
38
|
+
TestimonialCard: "social-proof",
|
|
39
|
+
ImageCtaHero: "hero",
|
|
40
|
+
CtaStrip: "conversion"
|
|
41
|
+
};
|
|
28
42
|
|
|
29
43
|
// src/tokens.ts
|
|
30
44
|
var DEFAULT_ACCENT = "#60a5fa";
|
|
45
|
+
var DEFAULT_ACCENT_LIGHT = "#2563eb";
|
|
31
46
|
var SP_ROOT = "sp-root";
|
|
32
|
-
|
|
33
|
-
|
|
47
|
+
var STYLESHEET_SCOPE = `:where(:root),.${SP_ROOT}`;
|
|
48
|
+
function palette(accent, theme) {
|
|
49
|
+
const shared = {
|
|
34
50
|
"--sp-accent": accent,
|
|
35
51
|
"--sp-accent-bg": `color-mix(in srgb,${accent} 10%,transparent)`,
|
|
36
|
-
"--sp-accent-border": `color-mix(in srgb,${accent} 20%,transparent)
|
|
52
|
+
"--sp-accent-border": `color-mix(in srgb,${accent} 20%,transparent)`
|
|
53
|
+
};
|
|
54
|
+
if (theme === "light") {
|
|
55
|
+
return {
|
|
56
|
+
...shared,
|
|
57
|
+
"--sp-bg": "#ffffff",
|
|
58
|
+
"--sp-surface": "#f4f4f5",
|
|
59
|
+
"--sp-border": "#e4e4e7",
|
|
60
|
+
"--sp-text": "#18181b",
|
|
61
|
+
"--sp-text-sub": "#3f3f46",
|
|
62
|
+
"--sp-text-strong": "#27272a",
|
|
63
|
+
"--sp-text-muted": "#6b6b74",
|
|
64
|
+
"--sp-text-dim": "#82828b",
|
|
65
|
+
"--sp-text-body": "#52525b",
|
|
66
|
+
"--sp-positive": "#047857",
|
|
67
|
+
"--sp-cta-bg": "#18181b",
|
|
68
|
+
"--sp-cta-text": "#ffffff",
|
|
69
|
+
"--sp-divider": "rgba(0,0,0,0.06)",
|
|
70
|
+
"--sp-code-bg": "rgba(0,0,0,0.05)",
|
|
71
|
+
"--sp-code-border": "rgba(0,0,0,0.08)",
|
|
72
|
+
"--sp-pre-bg": "rgba(0,0,0,0.04)"
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
return {
|
|
76
|
+
...shared,
|
|
37
77
|
"--sp-bg": "#18181b",
|
|
38
78
|
"--sp-surface": "#09090b",
|
|
39
79
|
"--sp-border": "#27272a",
|
|
@@ -68,30 +108,37 @@ function rules(unit) {
|
|
|
68
108
|
"@media(max-width:640px){.sp-root .sp-pair{grid-template-columns:1fr}}"
|
|
69
109
|
].join("");
|
|
70
110
|
}
|
|
71
|
-
function buildTokenCss({ accent
|
|
72
|
-
const
|
|
111
|
+
function buildTokenCss({ accent, unit = "px", scope = `.${SP_ROOT}`, theme = "dark" } = {}) {
|
|
112
|
+
const resolved = accent != null ? accent : theme === "light" ? DEFAULT_ACCENT_LIGHT : DEFAULT_ACCENT;
|
|
113
|
+
const decls = Object.entries(palette(resolved, theme)).map(([k, v]) => `${k}:${v}`).join(";");
|
|
73
114
|
return `${scope}{${decls}}${rules(unit)}`;
|
|
74
115
|
}
|
|
116
|
+
|
|
117
|
+
// src/ComponentRenderer.tsx
|
|
118
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
75
119
|
function renderMarkdown(content) {
|
|
76
120
|
const raw = marked.parse(content != null ? content : "", { async: false });
|
|
77
121
|
return DOMPurify.sanitize(raw, { USE_PROFILES: { html: true } });
|
|
78
122
|
}
|
|
123
|
+
var scaler = (unit) => (n) => unit === "rem" ? `${n / 16}rem` : `${n}px`;
|
|
124
|
+
var PX = scaler("px");
|
|
79
125
|
var HALF_COMPONENTS = /* @__PURE__ */ new Set(["TestimonialCard"]);
|
|
80
126
|
var flexItems = (a) => a === "center" ? "center" : a === "right" ? "flex-end" : "flex-start";
|
|
81
|
-
function AnnouncementBar({ text, link }) {
|
|
127
|
+
function AnnouncementBar({ text, link, unit = "px" }) {
|
|
128
|
+
const u = scaler(unit);
|
|
82
129
|
if (!text) return null;
|
|
83
130
|
return /* @__PURE__ */ jsxs("div", { style: {
|
|
84
131
|
display: "flex",
|
|
85
132
|
alignItems: "center",
|
|
86
133
|
justifyContent: "center",
|
|
87
|
-
gap:
|
|
134
|
+
gap: u(10),
|
|
88
135
|
flexWrap: "wrap",
|
|
89
136
|
textAlign: "center",
|
|
90
137
|
background: "var(--sp-accent-bg)",
|
|
91
138
|
border: "1px solid var(--sp-accent-border)",
|
|
92
|
-
borderRadius:
|
|
93
|
-
padding:
|
|
94
|
-
fontSize:
|
|
139
|
+
borderRadius: u(8),
|
|
140
|
+
padding: `${u(8)} ${u(16)}`,
|
|
141
|
+
fontSize: u(14),
|
|
95
142
|
lineHeight: 1.4,
|
|
96
143
|
color: "var(--sp-text-sub)"
|
|
97
144
|
}, children: [
|
|
@@ -102,10 +149,11 @@ function AnnouncementBar({ text, link }) {
|
|
|
102
149
|
] })
|
|
103
150
|
] });
|
|
104
151
|
}
|
|
105
|
-
function HeroStatement({ headline, subheading, align = "left" }) {
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
152
|
+
function HeroStatement({ headline, subheading, align = "left", unit = "px" }) {
|
|
153
|
+
const u = scaler(unit);
|
|
154
|
+
return /* @__PURE__ */ jsxs("div", { style: { display: "flex", flexDirection: "column", alignItems: flexItems(align), textAlign: align, paddingTop: u(24), paddingBottom: u(24) }, children: [
|
|
155
|
+
/* @__PURE__ */ jsx("h2", { style: { fontSize: u(32), fontWeight: 700, letterSpacing: "-0.025em", lineHeight: 1.2, color: "var(--sp-text)", margin: `0 0 ${u(12)}` }, children: headline }),
|
|
156
|
+
subheading && /* @__PURE__ */ jsx("p", { style: { fontSize: u(18), color: "var(--sp-text-sub)", lineHeight: 1.6, maxWidth: u(672), margin: 0 }, children: subheading })
|
|
109
157
|
] });
|
|
110
158
|
}
|
|
111
159
|
var ATOM_LAYOUT_DEFAULT = ["title", "content", "stats", "cta"];
|
|
@@ -116,133 +164,157 @@ var clampStyle = {
|
|
|
116
164
|
WebkitBoxOrient: "vertical",
|
|
117
165
|
overflow: "hidden"
|
|
118
166
|
};
|
|
119
|
-
function AtomCard({ title, content, layout, stats = [], ctaText, ctaUrl, full }) {
|
|
167
|
+
function AtomCard({ title, content, summary, layout, stats = [], ctaText, ctaUrl, full, variant, unit = "px" }) {
|
|
168
|
+
const u = scaler(unit);
|
|
169
|
+
if (variant === "card") {
|
|
170
|
+
const face = (summary == null ? void 0 : summary.trim()) || (content ? `${content.replace(/\s+/g, " ").split(/(?<=[.!?])\s/)[0]}` : "");
|
|
171
|
+
return /* @__PURE__ */ jsxs("div", { style: { background: "var(--sp-bg)", border: "1px solid var(--sp-border)", borderRadius: u(12), padding: u(20) }, children: [
|
|
172
|
+
title && /* @__PURE__ */ jsx("h3", { style: { fontSize: u(16), fontWeight: 600, color: "var(--sp-text)", margin: 0, lineHeight: 1.35 }, children: title }),
|
|
173
|
+
face && /* @__PURE__ */ jsx("p", { style: { fontSize: u(15), color: "var(--sp-text-sub)", lineHeight: 1.6, margin: `${u(8)} 0 0` }, children: face }),
|
|
174
|
+
content && /* @__PURE__ */ jsxs("details", { style: { marginTop: u(10) }, children: [
|
|
175
|
+
/* @__PURE__ */ jsx("summary", { style: { cursor: "pointer", fontSize: u(13), fontWeight: 600, color: "var(--sp-accent)", listStyle: "none" }, children: "Read more" }),
|
|
176
|
+
/* @__PURE__ */ jsx("div", { className: "sp-prose", style: { fontSize: u(15), color: "var(--sp-text-sub)", lineHeight: 1.6, marginTop: u(10) }, dangerouslySetInnerHTML: { __html: renderMarkdown(content) } })
|
|
177
|
+
] }),
|
|
178
|
+
ctaText && ctaUrl && /* @__PURE__ */ jsxs("a", { href: ctaUrl, style: { display: "inline-flex", alignItems: "center", gap: u(4), marginTop: u(10), fontSize: u(13), fontWeight: 600, color: "var(--sp-accent)", textDecoration: "none" }, children: [
|
|
179
|
+
ctaText,
|
|
180
|
+
" \u2192"
|
|
181
|
+
] })
|
|
182
|
+
] });
|
|
183
|
+
}
|
|
120
184
|
const order = layout && layout.length ? layout : ATOM_LAYOUT_DEFAULT;
|
|
121
185
|
const element = (name) => {
|
|
122
|
-
if (name === "title") return title ? /* @__PURE__ */ jsx("h3", { style: { fontSize:
|
|
123
|
-
if (name === "content") return content ? /* @__PURE__ */ jsx("div", { className: "sp-prose", style: { fontSize:
|
|
124
|
-
if (name === "stats") return stats.length ? /* @__PURE__ */ jsx("div", { style: { display: "flex", flexWrap: "wrap", gap:
|
|
125
|
-
/* @__PURE__ */ jsx("span", { style: { fontSize:
|
|
126
|
-
/* @__PURE__ */ jsx("span", { style: { fontSize:
|
|
186
|
+
if (name === "title") return title ? /* @__PURE__ */ jsx("h3", { style: { fontSize: u(16), fontWeight: 600, color: "var(--sp-text)", margin: `0 0 ${u(12)}` }, children: title }, "title") : null;
|
|
187
|
+
if (name === "content") return content ? /* @__PURE__ */ jsx("div", { className: "sp-prose", style: { fontSize: u(15), color: "var(--sp-text-sub)", lineHeight: 1.6, ...full ? {} : clampStyle }, dangerouslySetInnerHTML: { __html: renderMarkdown(content) } }, "content") : null;
|
|
188
|
+
if (name === "stats") return stats.length ? /* @__PURE__ */ jsx("div", { style: { display: "flex", flexWrap: "wrap", gap: u(20), margin: `0 0 ${u(12)}`, paddingBottom: u(12), borderBottom: "1px solid var(--sp-border)" }, children: stats.map((s, i) => /* @__PURE__ */ jsxs("div", { style: { display: "flex", flexDirection: "column", gap: u(2) }, children: [
|
|
189
|
+
/* @__PURE__ */ jsx("span", { style: { fontSize: u(22), fontWeight: 700, color: "var(--sp-text)", lineHeight: 1, fontVariantNumeric: "tabular-nums" }, children: s.value }),
|
|
190
|
+
/* @__PURE__ */ jsx("span", { style: { fontSize: u(11), color: "var(--sp-text-muted)", textTransform: "uppercase", letterSpacing: "0.06em" }, children: s.label })
|
|
127
191
|
] }, i)) }, "stats") : null;
|
|
128
|
-
if (name === "cta") return ctaText && ctaUrl ? /* @__PURE__ */ jsxs("a", { href: ctaUrl, style: { display: "inline-flex", alignItems: "center", gap:
|
|
192
|
+
if (name === "cta") return ctaText && ctaUrl ? /* @__PURE__ */ jsxs("a", { href: ctaUrl, style: { display: "inline-flex", alignItems: "center", gap: u(4), marginTop: u(12), fontSize: u(13), fontWeight: 600, color: "var(--sp-accent)", textDecoration: "none" }, children: [
|
|
129
193
|
ctaText,
|
|
130
194
|
" \u2192"
|
|
131
195
|
] }, "cta") : null;
|
|
132
196
|
return null;
|
|
133
197
|
};
|
|
134
|
-
return /* @__PURE__ */ jsx("div", { style: { background: "var(--sp-bg)", border: "1px solid var(--sp-border)", borderRadius:
|
|
198
|
+
return /* @__PURE__ */ jsx("div", { style: { background: "var(--sp-bg)", border: "1px solid var(--sp-border)", borderRadius: u(12), padding: u(24), height: "100%" }, children: order.map(element) });
|
|
135
199
|
}
|
|
136
|
-
function StatGrid({ stats = [], caption }) {
|
|
200
|
+
function StatGrid({ stats = [], caption, unit = "px" }) {
|
|
201
|
+
const u = scaler(unit);
|
|
137
202
|
const cols = stats.length === 2 ? 2 : stats.length === 3 ? 3 : 4;
|
|
138
203
|
return /* @__PURE__ */ jsxs("div", { children: [
|
|
139
|
-
/* @__PURE__ */ jsx("div", { style: { display: "grid", gridTemplateColumns: `repeat(${cols}, 1fr)`, gap:
|
|
140
|
-
/* @__PURE__ */ jsx("p", { style: { fontSize:
|
|
141
|
-
/* @__PURE__ */ jsx("p", { style: { fontSize:
|
|
204
|
+
/* @__PURE__ */ jsx("div", { style: { display: "grid", gridTemplateColumns: `repeat(${cols}, 1fr)`, gap: u(12) }, children: stats.map(({ value, label }) => /* @__PURE__ */ jsxs("div", { style: { background: "var(--sp-bg)", border: "1px solid var(--sp-border)", borderRadius: u(10), padding: `${u(16)} ${u(20)}`, display: "flex", flexDirection: "column", justifyContent: "space-between", minHeight: u(88) }, children: [
|
|
205
|
+
/* @__PURE__ */ jsx("p", { style: { fontSize: u(11), color: "var(--sp-text-muted)", textTransform: "uppercase", letterSpacing: "0.06em", margin: `0 0 ${u(12)}`, lineHeight: 1.3 }, children: label }),
|
|
206
|
+
/* @__PURE__ */ jsx("p", { style: { fontSize: u(20), fontWeight: 500, color: "var(--sp-text)", fontVariantNumeric: "tabular-nums", lineHeight: 1, margin: 0 }, children: value })
|
|
142
207
|
] }, label)) }),
|
|
143
|
-
caption && /* @__PURE__ */ jsx("p", { style: { fontSize:
|
|
208
|
+
caption && /* @__PURE__ */ jsx("p", { style: { fontSize: u(13), color: "var(--sp-text-muted)", margin: `${u(12)} 0 0` }, children: caption })
|
|
144
209
|
] });
|
|
145
210
|
}
|
|
146
|
-
function CodeBlock({ code, lang = "typescript", caption }) {
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
211
|
+
function CodeBlock({ code, lang = "typescript", caption, unit = "px" }) {
|
|
212
|
+
const u = scaler(unit);
|
|
213
|
+
return /* @__PURE__ */ jsxs("div", { style: { borderRadius: u(12), overflow: "hidden", border: "1px solid var(--sp-border)" }, children: [
|
|
214
|
+
/* @__PURE__ */ jsxs("div", { style: { background: "var(--sp-bg)", padding: `${u(10)} ${u(16)}`, display: "flex", alignItems: "center", justifyContent: "space-between", borderBottom: "1px solid var(--sp-border)" }, children: [
|
|
215
|
+
/* @__PURE__ */ jsx("span", { style: { fontSize: u(12), color: "var(--sp-text-muted)", fontFamily: "monospace" }, children: lang }),
|
|
216
|
+
caption && /* @__PURE__ */ jsx("span", { style: { fontSize: u(12), color: "var(--sp-text-muted)" }, children: caption })
|
|
151
217
|
] }),
|
|
152
|
-
/* @__PURE__ */ jsx("pre", { style: { background: "var(--sp-surface)", padding:
|
|
218
|
+
/* @__PURE__ */ jsx("pre", { style: { background: "var(--sp-surface)", padding: u(20), fontSize: u(13), color: "var(--sp-text-sub)", overflowX: "auto", lineHeight: 1.6, fontFamily: "monospace", whiteSpace: "pre", margin: 0 }, children: code })
|
|
153
219
|
] });
|
|
154
220
|
}
|
|
155
|
-
function ComparisonTable({ brand = "Us", competitor, rows = [] }) {
|
|
156
|
-
|
|
221
|
+
function ComparisonTable({ brand = "Us", competitor, rows = [], unit = "px" }) {
|
|
222
|
+
const u = scaler(unit);
|
|
223
|
+
const cell = { textAlign: "left", padding: `${u(12)} ${u(16)}` };
|
|
224
|
+
return /* @__PURE__ */ jsx("div", { style: { border: "1px solid var(--sp-border)", borderRadius: u(12), overflow: "hidden" }, children: /* @__PURE__ */ jsx("div", { style: { overflowX: "auto" }, children: /* @__PURE__ */ jsxs("table", { style: { width: "100%", fontSize: u(14), borderCollapse: "collapse" }, children: [
|
|
157
225
|
/* @__PURE__ */ jsx("thead", { children: /* @__PURE__ */ jsxs("tr", { style: { borderBottom: "1px solid var(--sp-border)", background: "var(--sp-bg)" }, children: [
|
|
158
|
-
/* @__PURE__ */ jsx("th", { style: {
|
|
159
|
-
/* @__PURE__ */ jsx("th", {
|
|
160
|
-
/* @__PURE__ */ jsx("th", {
|
|
226
|
+
/* @__PURE__ */ jsx("th", { style: { ...cell, color: "var(--sp-text-muted)", fontWeight: 500, fontSize: u(12), width: "33%" } }),
|
|
227
|
+
/* @__PURE__ */ jsx("th", { scope: "col", style: { ...cell, fontWeight: 600, color: "var(--sp-accent)", fontSize: u(12) }, children: brand }),
|
|
228
|
+
/* @__PURE__ */ jsx("th", { scope: "col", style: { ...cell, color: "var(--sp-text-muted)", fontWeight: 500, fontSize: u(12) }, children: competitor })
|
|
161
229
|
] }) }),
|
|
162
230
|
/* @__PURE__ */ jsx("tbody", { children: rows.map(({ label, spectare, them }) => /* @__PURE__ */ jsxs("tr", { style: { borderBottom: "1px solid var(--sp-border)" }, children: [
|
|
163
|
-
/* @__PURE__ */ jsx("
|
|
164
|
-
/* @__PURE__ */ jsx("td", { style: {
|
|
165
|
-
/* @__PURE__ */ jsx("td", { style: {
|
|
231
|
+
/* @__PURE__ */ jsx("th", { scope: "row", style: { ...cell, fontSize: u(13), color: "var(--sp-text-muted)", fontWeight: 500 }, children: label }),
|
|
232
|
+
/* @__PURE__ */ jsx("td", { style: { ...cell, fontSize: u(13), color: "var(--sp-positive)", fontWeight: 500 }, children: spectare }),
|
|
233
|
+
/* @__PURE__ */ jsx("td", { style: { ...cell, fontSize: u(13), color: "var(--sp-text-muted)" }, children: them })
|
|
166
234
|
] }, label)) })
|
|
167
235
|
] }) }) });
|
|
168
236
|
}
|
|
169
|
-
function FeatureList({ items = [] }) {
|
|
170
|
-
|
|
171
|
-
|
|
237
|
+
function FeatureList({ items = [], unit = "px" }) {
|
|
238
|
+
const u = scaler(unit);
|
|
239
|
+
return /* @__PURE__ */ jsx("div", { style: { background: "var(--sp-bg)", border: "1px solid var(--sp-border)", borderRadius: u(12), padding: u(24) }, children: /* @__PURE__ */ jsx("ul", { style: { listStyle: "none", margin: 0, padding: 0, display: "flex", flexDirection: "column", gap: u(16) }, children: items.map(({ text, sub }) => /* @__PURE__ */ jsxs("li", { style: { display: "flex", gap: u(12) }, children: [
|
|
240
|
+
/* @__PURE__ */ jsx("span", { style: { color: "var(--sp-accent)", flexShrink: 0, fontSize: u(15), marginTop: u(2) }, children: "\u2713" }),
|
|
172
241
|
/* @__PURE__ */ jsxs("div", { children: [
|
|
173
|
-
/* @__PURE__ */ jsx("p", { style: { fontSize:
|
|
174
|
-
sub && /* @__PURE__ */ jsx("p", { style: { fontSize:
|
|
242
|
+
/* @__PURE__ */ jsx("p", { style: { fontSize: u(15), fontWeight: 500, color: "var(--sp-text)", lineHeight: 1.4, margin: 0 }, children: text }),
|
|
243
|
+
sub && /* @__PURE__ */ jsx("p", { style: { fontSize: u(13), color: "var(--sp-text-muted)", lineHeight: 1.5, margin: `${u(4)} 0 0` }, children: sub })
|
|
175
244
|
] })
|
|
176
245
|
] }, text)) }) });
|
|
177
246
|
}
|
|
178
|
-
function TestimonialCard({ quote, name, role, company }) {
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
247
|
+
function TestimonialCard({ quote, name, role, company, unit = "px" }) {
|
|
248
|
+
const u = scaler(unit);
|
|
249
|
+
return /* @__PURE__ */ jsxs("div", { style: { background: "var(--sp-bg)", border: "1px solid var(--sp-border)", borderRadius: u(12), padding: u(24), display: "flex", flexDirection: "column", gap: u(20), height: "100%" }, children: [
|
|
250
|
+
/* @__PURE__ */ jsxs("p", { style: { fontSize: u(15), color: "var(--sp-text-sub)", lineHeight: 1.6, flex: 1, margin: 0 }, children: [
|
|
251
|
+
/* @__PURE__ */ jsx("span", { style: { color: "var(--sp-text-dim)", fontSize: u(18), lineHeight: 1, marginRight: u(4) }, children: '"' }),
|
|
182
252
|
quote,
|
|
183
|
-
/* @__PURE__ */ jsx("span", { style: { color: "var(--sp-text-dim)", fontSize:
|
|
253
|
+
/* @__PURE__ */ jsx("span", { style: { color: "var(--sp-text-dim)", fontSize: u(18), lineHeight: 1, marginLeft: u(4) }, children: '"' })
|
|
184
254
|
] }),
|
|
185
|
-
/* @__PURE__ */ jsxs("div", { style: { borderTop: "1px solid var(--sp-border)", paddingTop:
|
|
186
|
-
/* @__PURE__ */ jsx("p", { style: { fontSize:
|
|
187
|
-
/* @__PURE__ */ jsxs("p", { style: { fontSize:
|
|
255
|
+
/* @__PURE__ */ jsxs("div", { style: { borderTop: "1px solid var(--sp-border)", paddingTop: u(16) }, children: [
|
|
256
|
+
/* @__PURE__ */ jsx("p", { style: { fontSize: u(14), fontWeight: 600, color: "var(--sp-text)", margin: 0 }, children: name }),
|
|
257
|
+
/* @__PURE__ */ jsxs("p", { style: { fontSize: u(13), color: "var(--sp-text-muted)", margin: `${u(2)} 0 0` }, children: [
|
|
188
258
|
role,
|
|
189
259
|
company ? `, ${company}` : ""
|
|
190
260
|
] })
|
|
191
261
|
] })
|
|
192
262
|
] });
|
|
193
263
|
}
|
|
194
|
-
function ImageCtaHero({ src, alt = "", headline, subheading, ctaLabel, ctaHref, align = "left" }) {
|
|
264
|
+
function ImageCtaHero({ src, alt = "", headline, subheading, ctaLabel, ctaHref, align = "left", unit = "px" }) {
|
|
265
|
+
const u = scaler(unit);
|
|
195
266
|
if (!src) return null;
|
|
196
|
-
return /* @__PURE__ */ jsxs("div", { style: { borderRadius:
|
|
267
|
+
return /* @__PURE__ */ jsxs("div", { style: { borderRadius: u(12), overflow: "hidden", position: "relative", width: "100%", paddingBottom: "56.25%" }, children: [
|
|
197
268
|
/* @__PURE__ */ jsx("img", { src, alt, style: { position: "absolute", inset: 0, width: "100%", height: "100%", objectFit: "cover" } }),
|
|
198
269
|
/* @__PURE__ */ jsx("div", { style: { position: "absolute", inset: 0, background: "rgba(0,0,0,0.45)" } }),
|
|
199
270
|
/* @__PURE__ */ jsx("div", { style: { position: "absolute", inset: 0, background: "linear-gradient(to top, rgba(0,0,0,0.85) 0%, rgba(0,0,0,0.2) 60%, transparent 100%)" } }),
|
|
200
|
-
/* @__PURE__ */ jsxs("div", { style: { position: "absolute", bottom: 0, left: 0, right: 0, padding:
|
|
201
|
-
headline && /* @__PURE__ */ jsx("h2", { style: { fontSize:
|
|
202
|
-
subheading && /* @__PURE__ */ jsx("p", { style: { fontSize:
|
|
203
|
-
ctaHref && ctaLabel && /* @__PURE__ */ jsx("a", { href: ctaHref, style: { display: "inline-block", background: "#fff", color: "#09090b", padding:
|
|
271
|
+
/* @__PURE__ */ jsxs("div", { style: { position: "absolute", bottom: 0, left: 0, right: 0, padding: u(28), textAlign: align }, children: [
|
|
272
|
+
headline && /* @__PURE__ */ jsx("h2", { style: { fontSize: u(24), fontWeight: 700, color: "#fff", lineHeight: 1.2, margin: `0 0 ${u(8)}`, letterSpacing: "-0.02em" }, children: headline }),
|
|
273
|
+
subheading && /* @__PURE__ */ jsx("p", { style: { fontSize: u(15), color: "rgba(255,255,255,0.75)", lineHeight: 1.5, margin: `0 0 ${u(20)}` }, children: subheading }),
|
|
274
|
+
ctaHref && ctaLabel && /* @__PURE__ */ jsx("a", { href: ctaHref, style: { display: "inline-block", background: "#fff", color: "#09090b", padding: `${u(8)} ${u(20)}`, borderRadius: u(8), fontWeight: 600, fontSize: u(14), textDecoration: "none" }, children: ctaLabel })
|
|
204
275
|
] })
|
|
205
276
|
] });
|
|
206
277
|
}
|
|
207
|
-
function CtaStrip({ headline, primary, secondary, align = "center" }) {
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
/* @__PURE__ */
|
|
211
|
-
|
|
212
|
-
|
|
278
|
+
function CtaStrip({ headline, primary, secondary, align = "center", unit = "px" }) {
|
|
279
|
+
const u = scaler(unit);
|
|
280
|
+
return /* @__PURE__ */ jsxs("div", { style: { border: "1px solid var(--sp-border)", borderRadius: u(12), padding: u(32), textAlign: align, background: "var(--sp-bg)" }, children: [
|
|
281
|
+
/* @__PURE__ */ jsx("h3", { style: { fontSize: u(24), fontWeight: 700, color: "var(--sp-text)", margin: `0 0 ${u(24)}` }, children: headline }),
|
|
282
|
+
/* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "center", justifyContent: flexItems(align), gap: u(16), flexWrap: "wrap" }, children: [
|
|
283
|
+
/* @__PURE__ */ jsx("a", { href: primary.href, style: { background: "var(--sp-cta-bg)", color: "var(--sp-cta-text)", padding: `${u(10)} ${u(24)}`, borderRadius: u(12), fontWeight: 600, fontSize: u(15), textDecoration: "none" }, children: primary.label }),
|
|
284
|
+
secondary && /* @__PURE__ */ jsxs("a", { href: secondary.href, style: { fontSize: u(15), color: "var(--sp-text-sub)", textDecoration: "none" }, children: [
|
|
213
285
|
secondary.label,
|
|
214
286
|
" \u2192"
|
|
215
287
|
] })
|
|
216
288
|
] })
|
|
217
289
|
] });
|
|
218
290
|
}
|
|
219
|
-
function renderSingle(item, brand, align) {
|
|
291
|
+
function renderSingle(item, brand, align, unit = "px") {
|
|
220
292
|
var _a, _b;
|
|
221
293
|
const s = (_a = item.slots) != null ? _a : {};
|
|
222
294
|
switch (item.component) {
|
|
223
295
|
case "AnnouncementBar":
|
|
224
|
-
return /* @__PURE__ */ jsx(AnnouncementBar, { text: s.text, link: s.link });
|
|
296
|
+
return /* @__PURE__ */ jsx(AnnouncementBar, { text: s.text, link: s.link, unit });
|
|
225
297
|
case "HeroStatement":
|
|
226
|
-
return /* @__PURE__ */ jsx(HeroStatement, { headline: s.headline, subheading: s.subheading, align });
|
|
298
|
+
return /* @__PURE__ */ jsx(HeroStatement, { headline: s.headline, subheading: s.subheading, align, unit });
|
|
227
299
|
// A full-width card has nothing beside it, so there is nothing for a clamp to protect.
|
|
228
300
|
case "AtomCard":
|
|
229
|
-
return /* @__PURE__ */ jsx(AtomCard, { title: s.title, content: s.content, layout: s.layout, stats: s.stats, ctaText: s.ctaText, ctaUrl: s.ctaUrl, full: s.full || resolvedSize(item) === "full" });
|
|
301
|
+
return /* @__PURE__ */ jsx(AtomCard, { title: s.title, content: s.content, summary: s.summary, layout: s.layout, stats: s.stats, ctaText: s.ctaText, ctaUrl: s.ctaUrl, full: s.full || resolvedSize(item) === "full", variant: s.variant, unit });
|
|
230
302
|
case "StatGrid":
|
|
231
|
-
return /* @__PURE__ */ jsx(StatGrid, { stats: s.stats, caption: s.caption });
|
|
303
|
+
return /* @__PURE__ */ jsx(StatGrid, { stats: s.stats, caption: s.caption, unit });
|
|
232
304
|
case "CodeBlock":
|
|
233
|
-
return /* @__PURE__ */ jsx(CodeBlock, { code: s.code, lang: s.lang, caption: s.caption });
|
|
305
|
+
return /* @__PURE__ */ jsx(CodeBlock, { code: s.code, lang: s.lang, caption: s.caption, unit });
|
|
234
306
|
case "ComparisonTable":
|
|
235
|
-
return /* @__PURE__ */ jsx(ComparisonTable, { brand: (_b = s.brand) != null ? _b : brand, competitor: s.competitor, rows: s.rows });
|
|
307
|
+
return /* @__PURE__ */ jsx(ComparisonTable, { brand: (_b = s.brand) != null ? _b : brand, competitor: s.competitor, rows: s.rows, unit });
|
|
236
308
|
case "FeatureList":
|
|
237
|
-
return /* @__PURE__ */ jsx(FeatureList, { items: s.items });
|
|
309
|
+
return /* @__PURE__ */ jsx(FeatureList, { items: s.items, unit });
|
|
238
310
|
case "TestimonialCard":
|
|
239
|
-
return /* @__PURE__ */ jsx(TestimonialCard, { quote: s.quote, name: s.name, role: s.role, company: s.company });
|
|
311
|
+
return /* @__PURE__ */ jsx(TestimonialCard, { quote: s.quote, name: s.name, role: s.role, company: s.company, unit });
|
|
240
312
|
case "ImageCtaHero":
|
|
241
|
-
return /* @__PURE__ */ jsx(ImageCtaHero, { src: s.src, alt: s.alt, headline: s.headline, subheading: s.subheading, ctaLabel: s.ctaLabel, ctaHref: s.ctaHref, align });
|
|
313
|
+
return /* @__PURE__ */ jsx(ImageCtaHero, { src: s.src, alt: s.alt, headline: s.headline, subheading: s.subheading, ctaLabel: s.ctaLabel, ctaHref: s.ctaHref, align, unit });
|
|
242
314
|
case "CtaStrip":
|
|
243
|
-
return /* @__PURE__ */ jsx(CtaStrip, { headline: s.headline, primary: s.primary, secondary: s.secondary, align });
|
|
315
|
+
return /* @__PURE__ */ jsx(CtaStrip, { headline: s.headline, primary: s.primary, secondary: s.secondary, align, unit });
|
|
244
316
|
// An unrecognised component name used to render nothing at all. A component needs a
|
|
245
|
-
// renderer
|
|
317
|
+
// renderer here plus spectare.js plus the WordPress plugin, so missing one made its content
|
|
246
318
|
// silently absent on that surface only: no error, no warning, just a shorter page that
|
|
247
319
|
// looks deliberate. That is the failure mode to remove before the registry grows.
|
|
248
320
|
//
|
|
@@ -253,7 +325,7 @@ function renderSingle(item, brand, align) {
|
|
|
253
325
|
default: {
|
|
254
326
|
console.warn(`[spectare] ComponentRenderer: no renderer for "${item.component}", falling back to AtomCard`);
|
|
255
327
|
if (!s.title && !s.content) return null;
|
|
256
|
-
return /* @__PURE__ */ jsx(AtomCard, { title: s.title, content: s.content, stats: s.stats, ctaText: s.ctaText, ctaUrl: s.ctaUrl, full: true });
|
|
328
|
+
return /* @__PURE__ */ jsx(AtomCard, { title: s.title, content: s.content, stats: s.stats, ctaText: s.ctaText, ctaUrl: s.ctaUrl, full: true, unit });
|
|
257
329
|
}
|
|
258
330
|
}
|
|
259
331
|
}
|
|
@@ -261,13 +333,19 @@ function resolvedSize(item) {
|
|
|
261
333
|
if (item.size) return item.size;
|
|
262
334
|
return HALF_COMPONENTS.has(item.component) ? "half" : "full";
|
|
263
335
|
}
|
|
336
|
+
function pairable(a, b) {
|
|
337
|
+
const catOf = (x) => COMPONENT_CATEGORIES[x.component];
|
|
338
|
+
const ca = catOf(a);
|
|
339
|
+
const cb = catOf(b);
|
|
340
|
+
return ca !== void 0 && ca === cb;
|
|
341
|
+
}
|
|
264
342
|
function buildLayout(assembly) {
|
|
265
343
|
const groups = [];
|
|
266
344
|
let i = 0;
|
|
267
345
|
while (i < assembly.length) {
|
|
268
346
|
const cur = assembly[i];
|
|
269
347
|
const next = assembly[i + 1];
|
|
270
|
-
if (resolvedSize(cur) === "half" && next && resolvedSize(next) === "half") {
|
|
348
|
+
if (resolvedSize(cur) === "half" && next && resolvedSize(next) === "half" && pairable(cur, next)) {
|
|
271
349
|
groups.push({ type: "pair", items: [cur, next] });
|
|
272
350
|
i += 2;
|
|
273
351
|
} else if (resolvedSize(cur) === "half") {
|
|
@@ -281,42 +359,46 @@ function buildLayout(assembly) {
|
|
|
281
359
|
return groups;
|
|
282
360
|
}
|
|
283
361
|
function XrayBadge({ name, size }) {
|
|
284
|
-
return /* @__PURE__ */ jsxs("div", { style: { position: "absolute", top:
|
|
285
|
-
/* @__PURE__ */ jsx("span", { style: { fontSize:
|
|
286
|
-
/* @__PURE__ */ jsx("span", { style: { fontSize:
|
|
362
|
+
return /* @__PURE__ */ jsxs("div", { style: { position: "absolute", top: PX(8), left: PX(8), zIndex: 10, display: "flex", alignItems: "center", gap: PX(6), pointerEvents: "none", userSelect: "none" }, children: [
|
|
363
|
+
/* @__PURE__ */ jsx("span", { style: { fontSize: PX(10), fontFamily: "monospace", background: "rgba(59,130,246,0.9)", color: "#fff", padding: `${PX(2)} ${PX(6)}`, borderRadius: PX(4), lineHeight: 1 }, children: name }),
|
|
364
|
+
/* @__PURE__ */ jsx("span", { style: { fontSize: PX(10), fontFamily: "monospace", color: "#71717a", lineHeight: 1 }, children: size })
|
|
287
365
|
] });
|
|
288
366
|
}
|
|
289
|
-
function ComponentRenderer({ assembly, brand, xray = false, zone, align, accent }) {
|
|
367
|
+
function ComponentRenderer({ assembly, brand, xray = false, zone, align, accent, theme, unit = "px", renderOverride, renderItem, rootProps }) {
|
|
368
|
+
const u = scaler(unit);
|
|
290
369
|
const filtered = zone ? filterAssemblyByZone(assembly, zone) : assembly;
|
|
291
370
|
const layout = buildLayout(filtered);
|
|
292
|
-
|
|
293
|
-
|
|
371
|
+
const { className: extraClass, style: extraStyle, ...restRoot } = rootProps != null ? rootProps : {};
|
|
372
|
+
const renderOne = (item) => {
|
|
373
|
+
const override = renderOverride == null ? void 0 : renderOverride(item);
|
|
374
|
+
const node = override === void 0 ? renderSingle(item, brand, align, unit) : override;
|
|
375
|
+
return renderItem ? renderItem(item, node) : node;
|
|
376
|
+
};
|
|
377
|
+
return /* @__PURE__ */ jsxs("div", { className: extraClass ? `${SP_ROOT} ${extraClass}` : SP_ROOT, ...restRoot, style: { ...extraStyle, display: "flex", flexDirection: "column", gap: u(20), ...unit === "px" ? { fontSize: "16px" } : {} }, children: [
|
|
378
|
+
/* @__PURE__ */ jsx("style", { dangerouslySetInnerHTML: { __html: buildTokenCss({ accent, unit, theme }) } }),
|
|
294
379
|
layout.map((group, i) => {
|
|
295
|
-
if (group.type === "full") {
|
|
296
|
-
return /* @__PURE__ */ jsxs("div", { style: xray ? { position: "relative" } : void 0, children: [
|
|
297
|
-
xray && /* @__PURE__ */ jsx(XrayBadge, { name: group.item.component, size: "full" }),
|
|
298
|
-
renderSingle(group.item, brand, align)
|
|
299
|
-
] }, i);
|
|
300
|
-
}
|
|
301
380
|
if (group.type === "pair") {
|
|
302
381
|
return /* @__PURE__ */ jsxs("div", { className: "sp-pair", children: [
|
|
303
382
|
/* @__PURE__ */ jsxs("div", { style: xray ? { position: "relative" } : void 0, children: [
|
|
304
383
|
xray && /* @__PURE__ */ jsx(XrayBadge, { name: group.items[0].component, size: "half" }),
|
|
305
|
-
|
|
384
|
+
renderOne(group.items[0])
|
|
306
385
|
] }),
|
|
307
386
|
/* @__PURE__ */ jsxs("div", { style: xray ? { position: "relative" } : void 0, children: [
|
|
308
387
|
xray && /* @__PURE__ */ jsx(XrayBadge, { name: group.items[1].component, size: "half" }),
|
|
309
|
-
|
|
388
|
+
renderOne(group.items[1])
|
|
310
389
|
] })
|
|
311
390
|
] }, i);
|
|
312
391
|
}
|
|
313
392
|
return /* @__PURE__ */ jsxs("div", { style: xray ? { position: "relative" } : void 0, children: [
|
|
314
|
-
xray && /* @__PURE__ */ jsx(XrayBadge, { name: group.item.component, size: "full" }),
|
|
315
|
-
|
|
393
|
+
xray && /* @__PURE__ */ jsx(XrayBadge, { name: group.item.component, size: group.type === "half-solo" ? "half" : "full" }),
|
|
394
|
+
renderOne(group.item)
|
|
316
395
|
] }, i);
|
|
317
396
|
})
|
|
318
397
|
] });
|
|
319
398
|
}
|
|
399
|
+
|
|
400
|
+
// src/PersonalisedSection.tsx
|
|
401
|
+
import { Fragment, jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
320
402
|
var VARIANT_KEY = (orgSlug) => `_spectare_variant_${orgSlug}`;
|
|
321
403
|
function readVariantId(orgSlug) {
|
|
322
404
|
try {
|
|
@@ -366,11 +448,11 @@ function readVisitPath(orgSlug) {
|
|
|
366
448
|
}
|
|
367
449
|
}
|
|
368
450
|
function Shimmer() {
|
|
369
|
-
return /* @__PURE__ */
|
|
370
|
-
/* @__PURE__ */
|
|
371
|
-
/* @__PURE__ */
|
|
372
|
-
/* @__PURE__ */
|
|
373
|
-
/* @__PURE__ */
|
|
451
|
+
return /* @__PURE__ */ jsxs2("div", { style: { display: "flex", flexDirection: "column", gap: "12px" }, children: [
|
|
452
|
+
/* @__PURE__ */ jsx2("div", { style: { height: "20px", background: "rgba(39,39,42,0.6)", borderRadius: "8px", width: "75%", animation: "sp-pulse 1.5s ease-in-out infinite" } }),
|
|
453
|
+
/* @__PURE__ */ jsx2("div", { style: { height: "14px", background: "rgba(39,39,42,0.4)", borderRadius: "8px", width: "100%", animation: "sp-pulse 1.5s ease-in-out infinite" } }),
|
|
454
|
+
/* @__PURE__ */ jsx2("div", { style: { height: "14px", background: "rgba(39,39,42,0.4)", borderRadius: "8px", width: "83%", animation: "sp-pulse 1.5s ease-in-out infinite" } }),
|
|
455
|
+
/* @__PURE__ */ jsx2("div", { style: { height: "14px", background: "rgba(39,39,42,0.4)", borderRadius: "8px", width: "67%", animation: "sp-pulse 1.5s ease-in-out infinite" } })
|
|
374
456
|
] });
|
|
375
457
|
}
|
|
376
458
|
function PersonalisedSection({
|
|
@@ -386,7 +468,8 @@ function PersonalisedSection({
|
|
|
386
468
|
directSummary,
|
|
387
469
|
zone,
|
|
388
470
|
align,
|
|
389
|
-
accent
|
|
471
|
+
accent,
|
|
472
|
+
theme
|
|
390
473
|
}) {
|
|
391
474
|
const [assembly, setAssembly] = useState(initialAssembly != null ? initialAssembly : []);
|
|
392
475
|
const [loading, setLoading] = useState(!initialAssembly);
|
|
@@ -625,23 +708,38 @@ function PersonalisedSection({
|
|
|
625
708
|
}, [assembly, orgSlug, baseUrl]);
|
|
626
709
|
if (!loading && assembly.length === 0) return null;
|
|
627
710
|
const debugStyle = debugMode ? { outline: "2px solid rgba(96,165,250,0.5)", borderRadius: "0.5rem", position: "relative", padding: "0.5rem", ...style } : style;
|
|
628
|
-
return /* @__PURE__ */
|
|
629
|
-
/* @__PURE__ */
|
|
630
|
-
/* @__PURE__ */
|
|
631
|
-
debugMode && /* @__PURE__ */
|
|
711
|
+
return /* @__PURE__ */ jsxs2(Fragment, { children: [
|
|
712
|
+
/* @__PURE__ */ jsx2("style", { dangerouslySetInnerHTML: { __html: "@keyframes sp-pulse{0%,100%{opacity:1}50%{opacity:0.4}}" } }),
|
|
713
|
+
/* @__PURE__ */ jsxs2("div", { className, style: debugStyle, children: [
|
|
714
|
+
debugMode && /* @__PURE__ */ jsxs2("div", { style: { position: "absolute", top: "-1px", right: "-1px", zIndex: 20, display: "flex", alignItems: "center", gap: "0.375rem", background: "rgba(96,165,250,0.9)", borderRadius: "0 0.5rem 0 0.375rem", padding: "0.25rem 0.625rem", fontSize: "0.625rem", fontFamily: "monospace", color: "#fff", pointerEvents: "none", userSelect: "none" }, children: [
|
|
632
715
|
"Personalised by Spectare",
|
|
633
|
-
debugIntent && /* @__PURE__ */
|
|
716
|
+
debugIntent && /* @__PURE__ */ jsxs2("span", { style: { opacity: 0.75 }, children: [
|
|
634
717
|
" ",
|
|
635
718
|
debugIntent.audience,
|
|
636
719
|
"/",
|
|
637
720
|
debugIntent.stage
|
|
638
721
|
] })
|
|
639
722
|
] }),
|
|
640
|
-
loading && assembly.length === 0 ? /* @__PURE__ */
|
|
723
|
+
loading && assembly.length === 0 ? /* @__PURE__ */ jsx2(Shimmer, {}) : /* @__PURE__ */ jsx2(ComponentRenderer, { assembly: zone ? filterAssemblyByZone(assembly, zone) : assembly, brand: brand != null ? brand : orgName, align, accent, theme })
|
|
641
724
|
] })
|
|
642
725
|
] });
|
|
643
726
|
}
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
727
|
+
export {
|
|
728
|
+
AnnouncementBar,
|
|
729
|
+
AtomCard,
|
|
730
|
+
CodeBlock,
|
|
731
|
+
ComparisonTable,
|
|
732
|
+
ComponentRenderer,
|
|
733
|
+
CtaStrip,
|
|
734
|
+
DEFAULT_ACCENT,
|
|
735
|
+
FeatureList,
|
|
736
|
+
HeroStatement,
|
|
737
|
+
ImageCtaHero,
|
|
738
|
+
PersonalisedSection,
|
|
739
|
+
SP_ROOT,
|
|
740
|
+
StatGrid,
|
|
741
|
+
TestimonialCard,
|
|
742
|
+
buildTokenCss,
|
|
743
|
+
filterAssemblyByZone
|
|
744
|
+
};
|
|
647
745
|
//# sourceMappingURL=index.js.map
|