@spectare-personalisation/react 0.5.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 +53 -11
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +59 -46
- package/dist/index.d.ts +59 -46
- package/dist/index.js +53 -11
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -44,11 +44,57 @@ interface PersonalisedSectionProps {
|
|
|
44
44
|
align?: 'left' | 'center' | 'right';
|
|
45
45
|
/**
|
|
46
46
|
* Brand accent. Passed through to ComponentRenderer, which emits it into the scoped
|
|
47
|
-
* token set. Defaults to #60a5fa.
|
|
47
|
+
* token set. Defaults to #60a5fa (dark) or #2563eb (light).
|
|
48
48
|
*/
|
|
49
49
|
accent?: string;
|
|
50
|
+
/** dark (default) or light, matching your page's ground. See ComponentRenderer. */
|
|
51
|
+
theme?: 'dark' | 'light';
|
|
50
52
|
}
|
|
51
|
-
declare function PersonalisedSection({ orgSlug, baseUrl, brand, pageHint, className, style, initialAssembly, initialIntent, initialVariantId, directSummary, zone, align, accent, }: PersonalisedSectionProps): react_jsx_runtime.JSX.Element | null;
|
|
53
|
+
declare function PersonalisedSection({ orgSlug, baseUrl, brand, pageHint, className, style, initialAssembly, initialIntent, initialVariantId, directSummary, zone, align, accent, theme, }: PersonalisedSectionProps): react_jsx_runtime.JSX.Element | null;
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* The one place this package's design tokens are defined.
|
|
57
|
+
*
|
|
58
|
+
* Two things that are easy to get wrong here:
|
|
59
|
+
*
|
|
60
|
+
* 1. Tokens are declared on `.sp-root`, not `:root`. Declaring them at `:root` writes into
|
|
61
|
+
* the host's document, allows only one theme per page, and means a customer overriding
|
|
62
|
+
* `--sp-accent` competes with us at equal specificity so tag order decides the winner.
|
|
63
|
+
* Scoping also lets two differently themed sections sit on one page.
|
|
64
|
+
*
|
|
65
|
+
* 2. `tokens.css` must stay byte-identical to `buildTokenCss({ scope: STYLESHEET_SCOPE })`,
|
|
66
|
+
* which differs from the injected CSS in its selector and in nothing else.
|
|
67
|
+
* tests/unit/react-tokens.test.ts enforces both halves, because a customer who imports the
|
|
68
|
+
* stylesheet and a customer who renders the component must get the same page.
|
|
69
|
+
*
|
|
70
|
+
* components/ServerAssemblyRenderer.tsx in the Spectare app is a deliberate mirror of the
|
|
71
|
+
* values below. It is not the same file: that renderer uses rem, this one uses px.
|
|
72
|
+
*/
|
|
73
|
+
/** The package default. `spectare.js` and the WordPress plugin default to #2563eb, which is
|
|
74
|
+
* a live inconsistency and a brand decision rather than a technical one, so it is left alone
|
|
75
|
+
* here. Pass `accent` to override on either path. */
|
|
76
|
+
declare const DEFAULT_ACCENT = "#60a5fa";
|
|
77
|
+
type SpTheme = 'dark' | 'light';
|
|
78
|
+
/** Class the tokens are scoped to. Applied by ComponentRenderer to its own wrapper. */
|
|
79
|
+
declare const SP_ROOT = "sp-root";
|
|
80
|
+
/**
|
|
81
|
+
* Returns the stylesheet a renderer injects.
|
|
82
|
+
*
|
|
83
|
+
* @param accent brand colour. Accepts anything CSS does; `--sp-accent-bg` and
|
|
84
|
+
* `--sp-accent-border` are derived from it so a customer sets one value
|
|
85
|
+
* rather than three. Defaults to DEFAULT_ACCENT.
|
|
86
|
+
* @param unit length unit for layout rules. 'px' for this package, 'rem' for the app's
|
|
87
|
+
* server renderer, which sizes in rem throughout.
|
|
88
|
+
* @param scope selector the custom properties are declared on. Defaults to `.sp-root`, which is
|
|
89
|
+
* what a renderer injecting this at runtime wants. `tokens.css` is generated with
|
|
90
|
+
* STYLESHEET_SCOPE instead, so importing it works without a wrapper.
|
|
91
|
+
*/
|
|
92
|
+
declare function buildTokenCss({ accent, unit, scope, theme }?: {
|
|
93
|
+
accent?: string;
|
|
94
|
+
unit?: 'px' | 'rem';
|
|
95
|
+
scope?: string;
|
|
96
|
+
theme?: SpTheme;
|
|
97
|
+
}): string;
|
|
52
98
|
|
|
53
99
|
type Unit = 'px' | 'rem';
|
|
54
100
|
type Align = 'left' | 'center' | 'right';
|
|
@@ -75,9 +121,10 @@ declare function HeroStatement({ headline, subheading, align, unit }: {
|
|
|
75
121
|
align?: Align;
|
|
76
122
|
unit?: Unit;
|
|
77
123
|
}): react_jsx_runtime.JSX.Element;
|
|
78
|
-
declare function AtomCard({ title, content, layout, stats, ctaText, ctaUrl, full, unit }: {
|
|
124
|
+
declare function AtomCard({ title, content, summary, layout, stats, ctaText, ctaUrl, full, variant, unit }: {
|
|
79
125
|
title?: string;
|
|
80
126
|
content?: string;
|
|
127
|
+
summary?: string;
|
|
81
128
|
layout?: string[];
|
|
82
129
|
stats?: {
|
|
83
130
|
value: string;
|
|
@@ -86,6 +133,7 @@ declare function AtomCard({ title, content, layout, stats, ctaText, ctaUrl, full
|
|
|
86
133
|
ctaText?: string;
|
|
87
134
|
ctaUrl?: string;
|
|
88
135
|
full?: boolean;
|
|
136
|
+
variant?: string;
|
|
89
137
|
unit?: Unit;
|
|
90
138
|
}): react_jsx_runtime.JSX.Element;
|
|
91
139
|
declare function StatGrid({ stats, caption, unit }: {
|
|
@@ -169,6 +217,13 @@ interface ComponentRendererProps {
|
|
|
169
217
|
* from it, so one value covers all three. Defaults to #60a5fa.
|
|
170
218
|
*/
|
|
171
219
|
accent?: string;
|
|
220
|
+
/**
|
|
221
|
+
* dark (default) is the package's original near-black card set. light renders white cards
|
|
222
|
+
* with a dark text ramp for light host pages; without it the components paint near-white
|
|
223
|
+
* text and near-black slabs onto a light ground. Both palettes hold the same contrast
|
|
224
|
+
* floors (see tests/unit/token-contrast.test.ts).
|
|
225
|
+
*/
|
|
226
|
+
theme?: SpTheme;
|
|
172
227
|
/**
|
|
173
228
|
* px (default) sizes components absolutely, predictable inside arbitrary host pages.
|
|
174
229
|
* rem tracks the reader's font-size preference; the root then also inherits the host's
|
|
@@ -189,48 +244,6 @@ interface ComponentRendererProps {
|
|
|
189
244
|
/** Extra attributes for the root element (e.g. a data marker a host overlay targets). */
|
|
190
245
|
rootProps?: Record<string, unknown>;
|
|
191
246
|
}
|
|
192
|
-
declare function ComponentRenderer({ assembly, brand, xray, zone, align, accent, unit, renderOverride, renderItem, rootProps }: ComponentRendererProps): react_jsx_runtime.JSX.Element;
|
|
193
|
-
|
|
194
|
-
/**
|
|
195
|
-
* The one place this package's design tokens are defined.
|
|
196
|
-
*
|
|
197
|
-
* Two things that are easy to get wrong here:
|
|
198
|
-
*
|
|
199
|
-
* 1. Tokens are declared on `.sp-root`, not `:root`. Declaring them at `:root` writes into
|
|
200
|
-
* the host's document, allows only one theme per page, and means a customer overriding
|
|
201
|
-
* `--sp-accent` competes with us at equal specificity so tag order decides the winner.
|
|
202
|
-
* Scoping also lets two differently themed sections sit on one page.
|
|
203
|
-
*
|
|
204
|
-
* 2. `tokens.css` must stay byte-identical to `buildTokenCss({ scope: STYLESHEET_SCOPE })`,
|
|
205
|
-
* which differs from the injected CSS in its selector and in nothing else.
|
|
206
|
-
* tests/unit/react-tokens.test.ts enforces both halves, because a customer who imports the
|
|
207
|
-
* stylesheet and a customer who renders the component must get the same page.
|
|
208
|
-
*
|
|
209
|
-
* components/ServerAssemblyRenderer.tsx in the Spectare app is a deliberate mirror of the
|
|
210
|
-
* values below. It is not the same file: that renderer uses rem, this one uses px.
|
|
211
|
-
*/
|
|
212
|
-
/** The package default. `spectare.js` and the WordPress plugin default to #2563eb, which is
|
|
213
|
-
* a live inconsistency and a brand decision rather than a technical one, so it is left alone
|
|
214
|
-
* here. Pass `accent` to override on either path. */
|
|
215
|
-
declare const DEFAULT_ACCENT = "#60a5fa";
|
|
216
|
-
/** Class the tokens are scoped to. Applied by ComponentRenderer to its own wrapper. */
|
|
217
|
-
declare const SP_ROOT = "sp-root";
|
|
218
|
-
/**
|
|
219
|
-
* Returns the stylesheet a renderer injects.
|
|
220
|
-
*
|
|
221
|
-
* @param accent brand colour. Accepts anything CSS does; `--sp-accent-bg` and
|
|
222
|
-
* `--sp-accent-border` are derived from it so a customer sets one value
|
|
223
|
-
* rather than three. Defaults to DEFAULT_ACCENT.
|
|
224
|
-
* @param unit length unit for layout rules. 'px' for this package, 'rem' for the app's
|
|
225
|
-
* server renderer, which sizes in rem throughout.
|
|
226
|
-
* @param scope selector the custom properties are declared on. Defaults to `.sp-root`, which is
|
|
227
|
-
* what a renderer injecting this at runtime wants. `tokens.css` is generated with
|
|
228
|
-
* STYLESHEET_SCOPE instead, so importing it works without a wrapper.
|
|
229
|
-
*/
|
|
230
|
-
declare function buildTokenCss({ accent, unit, scope }?: {
|
|
231
|
-
accent?: string;
|
|
232
|
-
unit?: 'px' | 'rem';
|
|
233
|
-
scope?: string;
|
|
234
|
-
}): string;
|
|
247
|
+
declare function ComponentRenderer({ assembly, brand, xray, zone, align, accent, theme, unit, renderOverride, renderItem, rootProps }: ComponentRendererProps): react_jsx_runtime.JSX.Element;
|
|
235
248
|
|
|
236
249
|
export { AnnouncementBar, type AssemblyZone, AtomCard, CodeBlock, ComparisonTable, type ComponentAssembly, type ComponentName, ComponentRenderer, type ComponentRendererProps, CtaStrip, DEFAULT_ACCENT, FeatureList, HeroStatement, ImageCtaHero, PersonalisedSection, type PersonalisedSectionProps, SP_ROOT, StatGrid, TestimonialCard, buildTokenCss, filterAssemblyByZone };
|
package/dist/index.d.ts
CHANGED
|
@@ -44,11 +44,57 @@ interface PersonalisedSectionProps {
|
|
|
44
44
|
align?: 'left' | 'center' | 'right';
|
|
45
45
|
/**
|
|
46
46
|
* Brand accent. Passed through to ComponentRenderer, which emits it into the scoped
|
|
47
|
-
* token set. Defaults to #60a5fa.
|
|
47
|
+
* token set. Defaults to #60a5fa (dark) or #2563eb (light).
|
|
48
48
|
*/
|
|
49
49
|
accent?: string;
|
|
50
|
+
/** dark (default) or light, matching your page's ground. See ComponentRenderer. */
|
|
51
|
+
theme?: 'dark' | 'light';
|
|
50
52
|
}
|
|
51
|
-
declare function PersonalisedSection({ orgSlug, baseUrl, brand, pageHint, className, style, initialAssembly, initialIntent, initialVariantId, directSummary, zone, align, accent, }: PersonalisedSectionProps): react_jsx_runtime.JSX.Element | null;
|
|
53
|
+
declare function PersonalisedSection({ orgSlug, baseUrl, brand, pageHint, className, style, initialAssembly, initialIntent, initialVariantId, directSummary, zone, align, accent, theme, }: PersonalisedSectionProps): react_jsx_runtime.JSX.Element | null;
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* The one place this package's design tokens are defined.
|
|
57
|
+
*
|
|
58
|
+
* Two things that are easy to get wrong here:
|
|
59
|
+
*
|
|
60
|
+
* 1. Tokens are declared on `.sp-root`, not `:root`. Declaring them at `:root` writes into
|
|
61
|
+
* the host's document, allows only one theme per page, and means a customer overriding
|
|
62
|
+
* `--sp-accent` competes with us at equal specificity so tag order decides the winner.
|
|
63
|
+
* Scoping also lets two differently themed sections sit on one page.
|
|
64
|
+
*
|
|
65
|
+
* 2. `tokens.css` must stay byte-identical to `buildTokenCss({ scope: STYLESHEET_SCOPE })`,
|
|
66
|
+
* which differs from the injected CSS in its selector and in nothing else.
|
|
67
|
+
* tests/unit/react-tokens.test.ts enforces both halves, because a customer who imports the
|
|
68
|
+
* stylesheet and a customer who renders the component must get the same page.
|
|
69
|
+
*
|
|
70
|
+
* components/ServerAssemblyRenderer.tsx in the Spectare app is a deliberate mirror of the
|
|
71
|
+
* values below. It is not the same file: that renderer uses rem, this one uses px.
|
|
72
|
+
*/
|
|
73
|
+
/** The package default. `spectare.js` and the WordPress plugin default to #2563eb, which is
|
|
74
|
+
* a live inconsistency and a brand decision rather than a technical one, so it is left alone
|
|
75
|
+
* here. Pass `accent` to override on either path. */
|
|
76
|
+
declare const DEFAULT_ACCENT = "#60a5fa";
|
|
77
|
+
type SpTheme = 'dark' | 'light';
|
|
78
|
+
/** Class the tokens are scoped to. Applied by ComponentRenderer to its own wrapper. */
|
|
79
|
+
declare const SP_ROOT = "sp-root";
|
|
80
|
+
/**
|
|
81
|
+
* Returns the stylesheet a renderer injects.
|
|
82
|
+
*
|
|
83
|
+
* @param accent brand colour. Accepts anything CSS does; `--sp-accent-bg` and
|
|
84
|
+
* `--sp-accent-border` are derived from it so a customer sets one value
|
|
85
|
+
* rather than three. Defaults to DEFAULT_ACCENT.
|
|
86
|
+
* @param unit length unit for layout rules. 'px' for this package, 'rem' for the app's
|
|
87
|
+
* server renderer, which sizes in rem throughout.
|
|
88
|
+
* @param scope selector the custom properties are declared on. Defaults to `.sp-root`, which is
|
|
89
|
+
* what a renderer injecting this at runtime wants. `tokens.css` is generated with
|
|
90
|
+
* STYLESHEET_SCOPE instead, so importing it works without a wrapper.
|
|
91
|
+
*/
|
|
92
|
+
declare function buildTokenCss({ accent, unit, scope, theme }?: {
|
|
93
|
+
accent?: string;
|
|
94
|
+
unit?: 'px' | 'rem';
|
|
95
|
+
scope?: string;
|
|
96
|
+
theme?: SpTheme;
|
|
97
|
+
}): string;
|
|
52
98
|
|
|
53
99
|
type Unit = 'px' | 'rem';
|
|
54
100
|
type Align = 'left' | 'center' | 'right';
|
|
@@ -75,9 +121,10 @@ declare function HeroStatement({ headline, subheading, align, unit }: {
|
|
|
75
121
|
align?: Align;
|
|
76
122
|
unit?: Unit;
|
|
77
123
|
}): react_jsx_runtime.JSX.Element;
|
|
78
|
-
declare function AtomCard({ title, content, layout, stats, ctaText, ctaUrl, full, unit }: {
|
|
124
|
+
declare function AtomCard({ title, content, summary, layout, stats, ctaText, ctaUrl, full, variant, unit }: {
|
|
79
125
|
title?: string;
|
|
80
126
|
content?: string;
|
|
127
|
+
summary?: string;
|
|
81
128
|
layout?: string[];
|
|
82
129
|
stats?: {
|
|
83
130
|
value: string;
|
|
@@ -86,6 +133,7 @@ declare function AtomCard({ title, content, layout, stats, ctaText, ctaUrl, full
|
|
|
86
133
|
ctaText?: string;
|
|
87
134
|
ctaUrl?: string;
|
|
88
135
|
full?: boolean;
|
|
136
|
+
variant?: string;
|
|
89
137
|
unit?: Unit;
|
|
90
138
|
}): react_jsx_runtime.JSX.Element;
|
|
91
139
|
declare function StatGrid({ stats, caption, unit }: {
|
|
@@ -169,6 +217,13 @@ interface ComponentRendererProps {
|
|
|
169
217
|
* from it, so one value covers all three. Defaults to #60a5fa.
|
|
170
218
|
*/
|
|
171
219
|
accent?: string;
|
|
220
|
+
/**
|
|
221
|
+
* dark (default) is the package's original near-black card set. light renders white cards
|
|
222
|
+
* with a dark text ramp for light host pages; without it the components paint near-white
|
|
223
|
+
* text and near-black slabs onto a light ground. Both palettes hold the same contrast
|
|
224
|
+
* floors (see tests/unit/token-contrast.test.ts).
|
|
225
|
+
*/
|
|
226
|
+
theme?: SpTheme;
|
|
172
227
|
/**
|
|
173
228
|
* px (default) sizes components absolutely, predictable inside arbitrary host pages.
|
|
174
229
|
* rem tracks the reader's font-size preference; the root then also inherits the host's
|
|
@@ -189,48 +244,6 @@ interface ComponentRendererProps {
|
|
|
189
244
|
/** Extra attributes for the root element (e.g. a data marker a host overlay targets). */
|
|
190
245
|
rootProps?: Record<string, unknown>;
|
|
191
246
|
}
|
|
192
|
-
declare function ComponentRenderer({ assembly, brand, xray, zone, align, accent, unit, renderOverride, renderItem, rootProps }: ComponentRendererProps): react_jsx_runtime.JSX.Element;
|
|
193
|
-
|
|
194
|
-
/**
|
|
195
|
-
* The one place this package's design tokens are defined.
|
|
196
|
-
*
|
|
197
|
-
* Two things that are easy to get wrong here:
|
|
198
|
-
*
|
|
199
|
-
* 1. Tokens are declared on `.sp-root`, not `:root`. Declaring them at `:root` writes into
|
|
200
|
-
* the host's document, allows only one theme per page, and means a customer overriding
|
|
201
|
-
* `--sp-accent` competes with us at equal specificity so tag order decides the winner.
|
|
202
|
-
* Scoping also lets two differently themed sections sit on one page.
|
|
203
|
-
*
|
|
204
|
-
* 2. `tokens.css` must stay byte-identical to `buildTokenCss({ scope: STYLESHEET_SCOPE })`,
|
|
205
|
-
* which differs from the injected CSS in its selector and in nothing else.
|
|
206
|
-
* tests/unit/react-tokens.test.ts enforces both halves, because a customer who imports the
|
|
207
|
-
* stylesheet and a customer who renders the component must get the same page.
|
|
208
|
-
*
|
|
209
|
-
* components/ServerAssemblyRenderer.tsx in the Spectare app is a deliberate mirror of the
|
|
210
|
-
* values below. It is not the same file: that renderer uses rem, this one uses px.
|
|
211
|
-
*/
|
|
212
|
-
/** The package default. `spectare.js` and the WordPress plugin default to #2563eb, which is
|
|
213
|
-
* a live inconsistency and a brand decision rather than a technical one, so it is left alone
|
|
214
|
-
* here. Pass `accent` to override on either path. */
|
|
215
|
-
declare const DEFAULT_ACCENT = "#60a5fa";
|
|
216
|
-
/** Class the tokens are scoped to. Applied by ComponentRenderer to its own wrapper. */
|
|
217
|
-
declare const SP_ROOT = "sp-root";
|
|
218
|
-
/**
|
|
219
|
-
* Returns the stylesheet a renderer injects.
|
|
220
|
-
*
|
|
221
|
-
* @param accent brand colour. Accepts anything CSS does; `--sp-accent-bg` and
|
|
222
|
-
* `--sp-accent-border` are derived from it so a customer sets one value
|
|
223
|
-
* rather than three. Defaults to DEFAULT_ACCENT.
|
|
224
|
-
* @param unit length unit for layout rules. 'px' for this package, 'rem' for the app's
|
|
225
|
-
* server renderer, which sizes in rem throughout.
|
|
226
|
-
* @param scope selector the custom properties are declared on. Defaults to `.sp-root`, which is
|
|
227
|
-
* what a renderer injecting this at runtime wants. `tokens.css` is generated with
|
|
228
|
-
* STYLESHEET_SCOPE instead, so importing it works without a wrapper.
|
|
229
|
-
*/
|
|
230
|
-
declare function buildTokenCss({ accent, unit, scope }?: {
|
|
231
|
-
accent?: string;
|
|
232
|
-
unit?: 'px' | 'rem';
|
|
233
|
-
scope?: string;
|
|
234
|
-
}): string;
|
|
247
|
+
declare function ComponentRenderer({ assembly, brand, xray, zone, align, accent, theme, unit, renderOverride, renderItem, rootProps }: ComponentRendererProps): react_jsx_runtime.JSX.Element;
|
|
235
248
|
|
|
236
249
|
export { AnnouncementBar, type AssemblyZone, AtomCard, CodeBlock, ComparisonTable, type ComponentAssembly, type ComponentName, ComponentRenderer, type ComponentRendererProps, CtaStrip, DEFAULT_ACCENT, FeatureList, HeroStatement, ImageCtaHero, PersonalisedSection, type PersonalisedSectionProps, SP_ROOT, StatGrid, TestimonialCard, buildTokenCss, filterAssemblyByZone };
|
package/dist/index.js
CHANGED
|
@@ -42,13 +42,38 @@ var COMPONENT_CATEGORIES = {
|
|
|
42
42
|
|
|
43
43
|
// src/tokens.ts
|
|
44
44
|
var DEFAULT_ACCENT = "#60a5fa";
|
|
45
|
+
var DEFAULT_ACCENT_LIGHT = "#2563eb";
|
|
45
46
|
var SP_ROOT = "sp-root";
|
|
46
47
|
var STYLESHEET_SCOPE = `:where(:root),.${SP_ROOT}`;
|
|
47
|
-
function palette(accent) {
|
|
48
|
-
|
|
48
|
+
function palette(accent, theme) {
|
|
49
|
+
const shared = {
|
|
49
50
|
"--sp-accent": accent,
|
|
50
51
|
"--sp-accent-bg": `color-mix(in srgb,${accent} 10%,transparent)`,
|
|
51
|
-
"--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,
|
|
52
77
|
"--sp-bg": "#18181b",
|
|
53
78
|
"--sp-surface": "#09090b",
|
|
54
79
|
"--sp-border": "#27272a",
|
|
@@ -83,8 +108,9 @@ function rules(unit) {
|
|
|
83
108
|
"@media(max-width:640px){.sp-root .sp-pair{grid-template-columns:1fr}}"
|
|
84
109
|
].join("");
|
|
85
110
|
}
|
|
86
|
-
function buildTokenCss({ accent
|
|
87
|
-
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(";");
|
|
88
114
|
return `${scope}{${decls}}${rules(unit)}`;
|
|
89
115
|
}
|
|
90
116
|
|
|
@@ -138,8 +164,23 @@ var clampStyle = {
|
|
|
138
164
|
WebkitBoxOrient: "vertical",
|
|
139
165
|
overflow: "hidden"
|
|
140
166
|
};
|
|
141
|
-
function AtomCard({ title, content, layout, stats = [], ctaText, ctaUrl, full, unit = "px" }) {
|
|
167
|
+
function AtomCard({ title, content, summary, layout, stats = [], ctaText, ctaUrl, full, variant, unit = "px" }) {
|
|
142
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
|
+
}
|
|
143
184
|
const order = layout && layout.length ? layout : ATOM_LAYOUT_DEFAULT;
|
|
144
185
|
const element = (name) => {
|
|
145
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;
|
|
@@ -257,7 +298,7 @@ function renderSingle(item, brand, align, unit = "px") {
|
|
|
257
298
|
return /* @__PURE__ */ jsx(HeroStatement, { headline: s.headline, subheading: s.subheading, align, unit });
|
|
258
299
|
// A full-width card has nothing beside it, so there is nothing for a clamp to protect.
|
|
259
300
|
case "AtomCard":
|
|
260
|
-
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", unit });
|
|
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 });
|
|
261
302
|
case "StatGrid":
|
|
262
303
|
return /* @__PURE__ */ jsx(StatGrid, { stats: s.stats, caption: s.caption, unit });
|
|
263
304
|
case "CodeBlock":
|
|
@@ -323,7 +364,7 @@ function XrayBadge({ name, size }) {
|
|
|
323
364
|
/* @__PURE__ */ jsx("span", { style: { fontSize: PX(10), fontFamily: "monospace", color: "#71717a", lineHeight: 1 }, children: size })
|
|
324
365
|
] });
|
|
325
366
|
}
|
|
326
|
-
function ComponentRenderer({ assembly, brand, xray = false, zone, align, accent, unit = "px", renderOverride, renderItem, rootProps }) {
|
|
367
|
+
function ComponentRenderer({ assembly, brand, xray = false, zone, align, accent, theme, unit = "px", renderOverride, renderItem, rootProps }) {
|
|
327
368
|
const u = scaler(unit);
|
|
328
369
|
const filtered = zone ? filterAssemblyByZone(assembly, zone) : assembly;
|
|
329
370
|
const layout = buildLayout(filtered);
|
|
@@ -334,7 +375,7 @@ function ComponentRenderer({ assembly, brand, xray = false, zone, align, accent,
|
|
|
334
375
|
return renderItem ? renderItem(item, node) : node;
|
|
335
376
|
};
|
|
336
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: [
|
|
337
|
-
/* @__PURE__ */ jsx("style", { dangerouslySetInnerHTML: { __html: buildTokenCss({ accent, unit }) } }),
|
|
378
|
+
/* @__PURE__ */ jsx("style", { dangerouslySetInnerHTML: { __html: buildTokenCss({ accent, unit, theme }) } }),
|
|
338
379
|
layout.map((group, i) => {
|
|
339
380
|
if (group.type === "pair") {
|
|
340
381
|
return /* @__PURE__ */ jsxs("div", { className: "sp-pair", children: [
|
|
@@ -427,7 +468,8 @@ function PersonalisedSection({
|
|
|
427
468
|
directSummary,
|
|
428
469
|
zone,
|
|
429
470
|
align,
|
|
430
|
-
accent
|
|
471
|
+
accent,
|
|
472
|
+
theme
|
|
431
473
|
}) {
|
|
432
474
|
const [assembly, setAssembly] = useState(initialAssembly != null ? initialAssembly : []);
|
|
433
475
|
const [loading, setLoading] = useState(!initialAssembly);
|
|
@@ -678,7 +720,7 @@ function PersonalisedSection({
|
|
|
678
720
|
debugIntent.stage
|
|
679
721
|
] })
|
|
680
722
|
] }),
|
|
681
|
-
loading && assembly.length === 0 ? /* @__PURE__ */ jsx2(Shimmer, {}) : /* @__PURE__ */ jsx2(ComponentRenderer, { assembly: zone ? filterAssemblyByZone(assembly, zone) : assembly, brand: brand != null ? brand : orgName, align, accent })
|
|
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 })
|
|
682
724
|
] })
|
|
683
725
|
] });
|
|
684
726
|
}
|