@spectare-personalisation/react 0.2.1 → 0.4.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.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
 
3
- type ComponentName = 'HeroStatement' | 'AtomCard' | 'StatGrid' | 'CodeBlock' | 'ComparisonTable' | 'FeatureList' | 'TestimonialCard' | 'ImageCtaHero' | 'CtaStrip';
4
- type AssemblyZone = 'hero' | 'body' | 'proof' | 'cta';
3
+ type ComponentName = 'AnnouncementBar' | 'HeroStatement' | 'AtomCard' | 'StatGrid' | 'CodeBlock' | 'ComparisonTable' | 'FeatureList' | 'TestimonialCard' | 'ImageCtaHero' | 'CtaStrip';
4
+ type AssemblyZone = 'announce' | 'hero' | 'body' | 'proof' | 'cta';
5
5
  type ComponentAssembly = Array<{
6
6
  component: ComponentName;
7
7
  slots?: Record<string, unknown>;
@@ -25,11 +25,119 @@ interface PersonalisedSectionProps {
25
25
  audience: string;
26
26
  stage: string;
27
27
  };
28
+ /**
29
+ * Seed conversion attribution with a server-rendered arrangement: pass the variantId that
30
+ * /api/assemble/ssr returned alongside initialAssembly. Without it, a visit where the client
31
+ * classification matches the server's (so no client render happens) has no variant for a
32
+ * later conversion to credit.
33
+ */
34
+ initialVariantId?: string;
35
+ /**
36
+ * Explicit visitor-typed context (e.g. a demo input box). Bypasses the session token cache
37
+ * and re-qualifies immediately with the direct flag, which the server cost-caps (cheaper
38
+ * model on a cache miss) and never writes to the shared cache.
39
+ */
40
+ directSummary?: string;
28
41
  /** Render only components assigned to this zone. */
29
42
  zone?: AssemblyZone;
43
+ /** Alignment for statement-style components, to match the host page. */
44
+ align?: 'left' | 'center' | 'right';
45
+ /**
46
+ * Brand accent. Passed through to ComponentRenderer, which emits it into the scoped
47
+ * token set. Defaults to #60a5fa.
48
+ */
49
+ accent?: string;
30
50
  }
31
- declare function PersonalisedSection({ orgSlug, baseUrl, brand, pageHint, className, style, initialAssembly, initialIntent, zone, }: PersonalisedSectionProps): react_jsx_runtime.JSX.Element | null;
51
+ declare function PersonalisedSection({ orgSlug, baseUrl, brand, pageHint, className, style, initialAssembly, initialIntent, initialVariantId, directSummary, zone, align, accent, }: PersonalisedSectionProps): react_jsx_runtime.JSX.Element | null;
32
52
 
53
+ type Align = 'left' | 'center' | 'right';
54
+ /**
55
+ * A single line above everything else. Deliberately the plainest component in the set: no
56
+ * heading, no image, no padding to speak of. A bar that draws attention to itself competes with
57
+ * the page it is announcing something about.
58
+ *
59
+ * Uses the accent rather than a red or amber alert colour. This is a fact worth knowing, not a
60
+ * warning, and a venue putting "members book from Thursday" in an alarm colour reads as a problem
61
+ * rather than an offer.
62
+ */
63
+ declare function AnnouncementBar({ text, link }: {
64
+ text?: string;
65
+ link?: {
66
+ label: string;
67
+ href: string;
68
+ };
69
+ }): react_jsx_runtime.JSX.Element | null;
70
+ declare function HeroStatement({ headline, subheading, align }: {
71
+ headline: string;
72
+ subheading?: string;
73
+ align?: Align;
74
+ }): react_jsx_runtime.JSX.Element;
75
+ declare function AtomCard({ title, content, layout, stats, ctaText, ctaUrl, full }: {
76
+ title?: string;
77
+ content?: string;
78
+ layout?: string[];
79
+ stats?: {
80
+ value: string;
81
+ label: string;
82
+ }[];
83
+ ctaText?: string;
84
+ ctaUrl?: string;
85
+ full?: boolean;
86
+ }): react_jsx_runtime.JSX.Element;
87
+ declare function StatGrid({ stats, caption }: {
88
+ stats?: {
89
+ value: string;
90
+ label: string;
91
+ }[];
92
+ caption?: string;
93
+ }): react_jsx_runtime.JSX.Element;
94
+ declare function CodeBlock({ code, lang, caption }: {
95
+ code: string;
96
+ lang?: string;
97
+ caption?: string;
98
+ }): react_jsx_runtime.JSX.Element;
99
+ declare function ComparisonTable({ brand, competitor, rows }: {
100
+ brand?: string;
101
+ competitor: string;
102
+ rows?: {
103
+ label: string;
104
+ spectare: string;
105
+ them: string;
106
+ }[];
107
+ }): react_jsx_runtime.JSX.Element;
108
+ declare function FeatureList({ items }: {
109
+ items?: {
110
+ text: string;
111
+ sub?: string;
112
+ }[];
113
+ }): react_jsx_runtime.JSX.Element;
114
+ declare function TestimonialCard({ quote, name, role, company }: {
115
+ quote: string;
116
+ name: string;
117
+ role: string;
118
+ company?: string;
119
+ }): react_jsx_runtime.JSX.Element;
120
+ declare function ImageCtaHero({ src, alt, headline, subheading, ctaLabel, ctaHref, align }: {
121
+ src?: string;
122
+ alt?: string;
123
+ headline?: string;
124
+ subheading?: string;
125
+ ctaLabel?: string;
126
+ ctaHref?: string;
127
+ align?: Align;
128
+ }): react_jsx_runtime.JSX.Element | null;
129
+ declare function CtaStrip({ headline, primary, secondary, align }: {
130
+ headline: string;
131
+ primary: {
132
+ label: string;
133
+ href: string;
134
+ };
135
+ secondary?: {
136
+ label: string;
137
+ href: string;
138
+ };
139
+ align?: Align;
140
+ }): react_jsx_runtime.JSX.Element;
33
141
  interface ComponentRendererProps {
34
142
  assembly: ComponentAssembly;
35
143
  /** Your brand name, used as the left column header in ComparisonTable. Defaults to "Us". */
@@ -38,7 +146,61 @@ interface ComponentRendererProps {
38
146
  xray?: boolean;
39
147
  /** Render only components assigned to this zone. */
40
148
  zone?: AssemblyZone;
149
+ /**
150
+ * Alignment for statement-style components (HeroStatement, CtaStrip, ImageCtaHero),
151
+ * so assembled content can match the host page. Omit to use each component's natural
152
+ * default (HeroStatement left, CtaStrip centered).
153
+ */
154
+ align?: 'left' | 'center' | 'right';
155
+ /**
156
+ * Brand accent, as an explicit input rather than a custom property you override and hope
157
+ * wins on tag order. Any CSS colour. `--sp-accent-bg` and `--sp-accent-border` are derived
158
+ * from it, so one value covers all three. Defaults to #60a5fa.
159
+ */
160
+ accent?: string;
41
161
  }
42
- declare function ComponentRenderer({ assembly, brand, xray, zone }: ComponentRendererProps): react_jsx_runtime.JSX.Element;
162
+ declare function ComponentRenderer({ assembly, brand, xray, zone, align, accent }: ComponentRendererProps): react_jsx_runtime.JSX.Element;
163
+
164
+ /**
165
+ * The one place this package's design tokens are defined.
166
+ *
167
+ * Two things that are easy to get wrong here:
168
+ *
169
+ * 1. Tokens are declared on `.sp-root`, not `:root`. Declaring them at `:root` writes into
170
+ * the host's document, allows only one theme per page, and means a customer overriding
171
+ * `--sp-accent` competes with us at equal specificity so tag order decides the winner.
172
+ * Scoping also lets two differently themed sections sit on one page.
173
+ *
174
+ * 2. `tokens.css` must stay byte-identical to `buildTokenCss({ scope: STYLESHEET_SCOPE })`,
175
+ * which differs from the injected CSS in its selector and in nothing else.
176
+ * tests/unit/react-tokens.test.ts enforces both halves, because a customer who imports the
177
+ * stylesheet and a customer who renders the component must get the same page.
178
+ *
179
+ * components/ServerAssemblyRenderer.tsx in the Spectare app is a deliberate mirror of the
180
+ * values below. It is not the same file: that renderer uses rem, this one uses px.
181
+ */
182
+ /** The package default. `spectare.js` and the WordPress plugin default to #2563eb, which is
183
+ * a live inconsistency and a brand decision rather than a technical one, so it is left alone
184
+ * here. Pass `accent` to override on either path. */
185
+ declare const DEFAULT_ACCENT = "#60a5fa";
186
+ /** Class the tokens are scoped to. Applied by ComponentRenderer to its own wrapper. */
187
+ declare const SP_ROOT = "sp-root";
188
+ /**
189
+ * Returns the stylesheet a renderer injects.
190
+ *
191
+ * @param accent brand colour. Accepts anything CSS does; `--sp-accent-bg` and
192
+ * `--sp-accent-border` are derived from it so a customer sets one value
193
+ * rather than three. Defaults to DEFAULT_ACCENT.
194
+ * @param unit length unit for layout rules. 'px' for this package, 'rem' for the app's
195
+ * server renderer, which sizes in rem throughout.
196
+ * @param scope selector the custom properties are declared on. Defaults to `.sp-root`, which is
197
+ * what a renderer injecting this at runtime wants. `tokens.css` is generated with
198
+ * STYLESHEET_SCOPE instead, so importing it works without a wrapper.
199
+ */
200
+ declare function buildTokenCss({ accent, unit, scope }?: {
201
+ accent?: string;
202
+ unit?: 'px' | 'rem';
203
+ scope?: string;
204
+ }): string;
43
205
 
44
- export { type AssemblyZone, type ComponentAssembly, type ComponentName, ComponentRenderer, type ComponentRendererProps, PersonalisedSection, type PersonalisedSectionProps, filterAssemblyByZone };
206
+ 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 };