@syntrologie/runtime-sdk 2.10.0 → 2.12.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/CAPABILITIES.md +176 -117
- package/README.md +2 -0
- package/dist/actions/schema.d.ts +7 -7
- package/dist/actions/schema.js +1 -1
- package/dist/actions/types.d.ts +1 -1
- package/dist/actions/validation-core.d.ts +24 -0
- package/dist/actions/validation-rules.d.ts +74 -0
- package/dist/actions/validation.d.ts +5 -11
- package/dist/bootstrap-init.d.ts +33 -0
- package/dist/bootstrap-runtime.d.ts +7 -0
- package/dist/bootstrap-types.d.ts +90 -0
- package/dist/bootstrap.d.ts +17 -83
- package/dist/{chunk-OIDBMIRB.js → chunk-J2LGX2PV.js} +1282 -488
- package/dist/chunk-J2LGX2PV.js.map +7 -0
- package/dist/{chunk-R5DNAIRI.js → chunk-L6RJMBR2.js} +2 -2
- package/dist/{chunk-R5DNAIRI.js.map → chunk-L6RJMBR2.js.map} +2 -2
- package/dist/events/EventBus.d.ts +27 -1
- package/dist/events/history.d.ts +9 -0
- package/dist/events/index.d.ts +3 -0
- package/dist/events/normalizers/posthog.d.ts +4 -50
- package/dist/events/types.d.ts +30 -23
- package/dist/events/validation.d.ts +7 -0
- package/dist/index.d.ts +0 -2
- package/dist/index.js +1125 -2027
- package/dist/index.js.map +4 -4
- package/dist/overlays/runtime/overlay/overlay-runner.d.ts +4 -0
- package/dist/overlays/runtime/overlay/overlay-state.d.ts +21 -0
- package/dist/overlays/types.d.ts +3 -1
- package/dist/react.js +4 -2
- package/dist/react.js.map +2 -2
- package/dist/smart-canvas.esm.js +92 -108
- package/dist/smart-canvas.esm.js.map +4 -4
- package/dist/smart-canvas.js +5225 -5012
- package/dist/smart-canvas.js.map +4 -4
- package/dist/smart-canvas.min.js +92 -108
- package/dist/smart-canvas.min.js.map +4 -4
- package/dist/telemetry/adapters/posthog.d.ts +30 -4
- package/dist/test/setup.d.ts +1 -0
- package/dist/token.d.ts +2 -0
- package/dist/version.d.ts +1 -1
- package/package.json +23 -28
- package/schema/canvas-config.schema.json +1 -1
- package/scripts/syntroReactPlugin.mjs +3 -0
- package/scripts/validate-config.mjs +42 -0
- package/dist/chunk-OIDBMIRB.js.map +0 -7
package/CAPABILITIES.md
CHANGED
|
@@ -54,8 +54,8 @@ Change a page header when the element is visible:
|
|
|
54
54
|
},
|
|
55
55
|
"actions": [
|
|
56
56
|
{
|
|
57
|
-
"kind": "
|
|
58
|
-
"anchorId": "h1.hero-title",
|
|
57
|
+
"kind": "content:setText",
|
|
58
|
+
"anchorId": { "selector": "h1.hero-title", "route": "/" },
|
|
59
59
|
"text": "Welcome to Our New Experience"
|
|
60
60
|
}
|
|
61
61
|
]
|
|
@@ -160,62 +160,73 @@ The widget reads auth credentials from the browser:
|
|
|
160
160
|
|
|
161
161
|
DOM content modification capabilities for text, attributes, styles, HTML, and classes.
|
|
162
162
|
|
|
163
|
+
## When to use
|
|
164
|
+
|
|
165
|
+
| Goal | Action |
|
|
166
|
+
|------|--------|
|
|
167
|
+
| Replace an element's text | `content:setText` |
|
|
168
|
+
| Change an HTML attribute (href, src, data-*) | `content:setAttr` |
|
|
169
|
+
| Modify inline styles (color, size, spacing) | `content:setStyle` |
|
|
170
|
+
| Inject new HTML before/after/inside an element | `content:insertHtml` |
|
|
171
|
+
| Add a CSS class (show/hide, animate) | `content:addClass` |
|
|
172
|
+
| Remove a CSS class | `content:removeClass` |
|
|
173
|
+
|
|
163
174
|
## Actions
|
|
164
175
|
|
|
165
|
-
###
|
|
176
|
+
### content:setText
|
|
166
177
|
|
|
167
178
|
Replaces the text content of an element.
|
|
168
179
|
|
|
169
|
-
| Property | Type
|
|
170
|
-
| ---------- |
|
|
171
|
-
| `kind` | `"
|
|
172
|
-
| `anchorId` |
|
|
173
|
-
| `text` | string
|
|
180
|
+
| Property | Type | Required | Description |
|
|
181
|
+
| ---------- | ------------------- | -------- | ---------------- |
|
|
182
|
+
| `kind` | `"content:setText"` | Yes | Action type |
|
|
183
|
+
| `anchorId` | object | Yes | `{ selector, route }` |
|
|
184
|
+
| `text` | string | Yes | New text content |
|
|
174
185
|
|
|
175
186
|
```json
|
|
176
187
|
{
|
|
177
|
-
"kind": "
|
|
178
|
-
"anchorId": "h1.hero-title",
|
|
188
|
+
"kind": "content:setText",
|
|
189
|
+
"anchorId": { "selector": "h1.hero-title", "route": "/" },
|
|
179
190
|
"text": "Start Your Free Trial Today"
|
|
180
191
|
}
|
|
181
192
|
```
|
|
182
193
|
|
|
183
|
-
###
|
|
194
|
+
### content:setAttr
|
|
184
195
|
|
|
185
196
|
Sets an HTML attribute on an element.
|
|
186
197
|
|
|
187
|
-
| Property | Type
|
|
188
|
-
| ---------- |
|
|
189
|
-
| `kind` | `"
|
|
190
|
-
| `anchorId` |
|
|
191
|
-
| `attr` | string
|
|
192
|
-
| `value` | string
|
|
198
|
+
| Property | Type | Required | Description |
|
|
199
|
+
| ---------- | ------------------- | -------- | ---------------- |
|
|
200
|
+
| `kind` | `"content:setAttr"` | Yes | Action type |
|
|
201
|
+
| `anchorId` | object | Yes | `{ selector, route }` |
|
|
202
|
+
| `attr` | string | Yes | Attribute name |
|
|
203
|
+
| `value` | string | Yes | Attribute value |
|
|
193
204
|
|
|
194
205
|
**Blocked attributes:** Event handlers (`onclick`, `onerror`, etc.) are not allowed.
|
|
195
206
|
|
|
196
207
|
```json
|
|
197
208
|
{
|
|
198
|
-
"kind": "
|
|
199
|
-
"anchorId": "#signup-form",
|
|
209
|
+
"kind": "content:setAttr",
|
|
210
|
+
"anchorId": { "selector": "#signup-form", "route": "/" },
|
|
200
211
|
"attr": "data-experiment",
|
|
201
212
|
"value": "signup-v2"
|
|
202
213
|
}
|
|
203
214
|
```
|
|
204
215
|
|
|
205
|
-
###
|
|
216
|
+
### content:setStyle
|
|
206
217
|
|
|
207
218
|
Sets inline CSS styles on an element.
|
|
208
219
|
|
|
209
|
-
| Property | Type
|
|
210
|
-
| ---------- |
|
|
211
|
-
| `kind` | `"
|
|
212
|
-
| `anchorId` |
|
|
213
|
-
| `styles` | object
|
|
220
|
+
| Property | Type | Required | Description |
|
|
221
|
+
| ---------- | -------------------- | -------- | ------------------------ |
|
|
222
|
+
| `kind` | `"content:setStyle"` | Yes | Action type |
|
|
223
|
+
| `anchorId` | object | Yes | `{ selector, route }` |
|
|
224
|
+
| `styles` | object | Yes | CSS property/value pairs |
|
|
214
225
|
|
|
215
226
|
```json
|
|
216
227
|
{
|
|
217
|
-
"kind": "
|
|
218
|
-
"anchorId": ".hero-section",
|
|
228
|
+
"kind": "content:setStyle",
|
|
229
|
+
"anchorId": { "selector": ".hero-section", "route": "/" },
|
|
219
230
|
"styles": {
|
|
220
231
|
"background-color": "#1e40af",
|
|
221
232
|
"padding": "2rem"
|
|
@@ -223,17 +234,17 @@ Sets inline CSS styles on an element.
|
|
|
223
234
|
}
|
|
224
235
|
```
|
|
225
236
|
|
|
226
|
-
###
|
|
237
|
+
### content:insertHtml
|
|
227
238
|
|
|
228
239
|
Inserts HTML content relative to an element.
|
|
229
240
|
|
|
230
|
-
| Property | Type
|
|
231
|
-
| ---------- |
|
|
232
|
-
| `kind` | `"
|
|
233
|
-
| `anchorId` |
|
|
234
|
-
| `html` | string
|
|
235
|
-
| `position` | string
|
|
236
|
-
| `deepLink` | object
|
|
241
|
+
| Property | Type | Required | Description |
|
|
242
|
+
| ---------- | --------------------- | -------- | ----------------------------------------------------------- |
|
|
243
|
+
| `kind` | `"content:insertHtml"` | Yes | Action type |
|
|
244
|
+
| `anchorId` | object | Yes | `{ selector, route }` |
|
|
245
|
+
| `html` | string | Yes | HTML content (sanitized) |
|
|
246
|
+
| `position` | string | Yes | `"before"`, `"after"`, `"prepend"`, `"append"`, `"replace"` |
|
|
247
|
+
| `deepLink` | object | No | Makes the entire inserted element clickable to open the canvas panel and navigate to a specific tile |
|
|
237
248
|
|
|
238
249
|
**Positions:**
|
|
239
250
|
|
|
@@ -245,8 +256,8 @@ Inserts HTML content relative to an element.
|
|
|
245
256
|
|
|
246
257
|
```json
|
|
247
258
|
{
|
|
248
|
-
"kind": "
|
|
249
|
-
"anchorId": ".cta-button",
|
|
259
|
+
"kind": "content:insertHtml",
|
|
260
|
+
"anchorId": { "selector": ".cta-button", "route": "/" },
|
|
250
261
|
"html": "<span class=\"badge\">NEW</span>",
|
|
251
262
|
"position": "append"
|
|
252
263
|
}
|
|
@@ -263,8 +274,8 @@ Use `deepLink` to make inserted content open the canvas panel and navigate to a
|
|
|
263
274
|
|
|
264
275
|
```json
|
|
265
276
|
{
|
|
266
|
-
"kind": "
|
|
267
|
-
"anchorId": "[data-id='pricing-heading']",
|
|
277
|
+
"kind": "content:insertHtml",
|
|
278
|
+
"anchorId": { "selector": "[data-id='pricing-heading']", "route": "/" },
|
|
268
279
|
"html": "<button style='background: #4a90e2; color: white; border: none; padding: 8px 16px; border-radius: 20px; cursor: pointer;'>Help Me Choose</button>",
|
|
269
280
|
"position": "after",
|
|
270
281
|
"deepLink": { "tileId": "plan_selector_faq" }
|
|
@@ -273,38 +284,38 @@ Use `deepLink` to make inserted content open the canvas panel and navigate to a
|
|
|
273
284
|
|
|
274
285
|
The SDK automatically handles opening the canvas, setting the cursor to pointer, and publishing a `notification.deep_link` event. The click handler is wired up and cleaned up by the SDK — no JavaScript in the HTML is needed.
|
|
275
286
|
|
|
276
|
-
###
|
|
287
|
+
### content:addClass
|
|
277
288
|
|
|
278
289
|
Adds a CSS class to an element.
|
|
279
290
|
|
|
280
|
-
| Property | Type
|
|
281
|
-
| ----------- |
|
|
282
|
-
| `kind` | `"
|
|
283
|
-
| `anchorId` |
|
|
284
|
-
| `className` | string
|
|
291
|
+
| Property | Type | Required | Description |
|
|
292
|
+
| ----------- | -------------------- | -------- | ----------------- |
|
|
293
|
+
| `kind` | `"content:addClass"` | Yes | Action type |
|
|
294
|
+
| `anchorId` | object | Yes | `{ selector, route }` |
|
|
295
|
+
| `className` | string | Yes | Class name to add |
|
|
285
296
|
|
|
286
297
|
```json
|
|
287
298
|
{
|
|
288
|
-
"kind": "
|
|
289
|
-
"anchorId": ".pricing-card",
|
|
299
|
+
"kind": "content:addClass",
|
|
300
|
+
"anchorId": { "selector": ".pricing-card", "route": "/pricing" },
|
|
290
301
|
"className": "highlighted"
|
|
291
302
|
}
|
|
292
303
|
```
|
|
293
304
|
|
|
294
|
-
###
|
|
305
|
+
### content:removeClass
|
|
295
306
|
|
|
296
307
|
Removes a CSS class from an element.
|
|
297
308
|
|
|
298
|
-
| Property | Type
|
|
299
|
-
| ----------- |
|
|
300
|
-
| `kind` | `"
|
|
301
|
-
| `anchorId` |
|
|
302
|
-
| `className` | string
|
|
309
|
+
| Property | Type | Required | Description |
|
|
310
|
+
| ----------- | ----------------------- | -------- | -------------------- |
|
|
311
|
+
| `kind` | `"content:removeClass"` | Yes | Action type |
|
|
312
|
+
| `anchorId` | object | Yes | `{ selector, route }` |
|
|
313
|
+
| `className` | string | Yes | Class name to remove |
|
|
303
314
|
|
|
304
315
|
```json
|
|
305
316
|
{
|
|
306
|
-
"kind": "
|
|
307
|
-
"anchorId": ".pricing-card",
|
|
317
|
+
"kind": "content:removeClass",
|
|
318
|
+
"anchorId": { "selector": ".pricing-card", "route": "/pricing" },
|
|
308
319
|
"className": "hidden"
|
|
309
320
|
}
|
|
310
321
|
```
|
|
@@ -316,15 +327,24 @@ Removes a CSS class from an element.
|
|
|
316
327
|
|
|
317
328
|
Collapsible Q&A accordion with actions, rich content, feedback, and personalization.
|
|
318
329
|
|
|
330
|
+
## When to use
|
|
331
|
+
|
|
332
|
+
| Goal | Action |
|
|
333
|
+
|------|--------|
|
|
334
|
+
| Mount an FAQ accordion widget | `core:mountWidget` with `widget: "adaptive-faq:accordion"` |
|
|
335
|
+
| Scroll to and expand a specific FAQ item | `faq:scroll_to` |
|
|
336
|
+
| Open, close, or toggle a FAQ item | `faq:toggle_item` |
|
|
337
|
+
| Add, remove, reorder, or replace FAQ items | `faq:update` |
|
|
338
|
+
|
|
319
339
|
## Actions
|
|
320
340
|
|
|
321
|
-
###
|
|
341
|
+
### core:mountWidget (FAQ)
|
|
322
342
|
|
|
323
343
|
Mounts an FAQ accordion widget to a surface slot.
|
|
324
344
|
|
|
325
345
|
| Property | Type | Required | Description |
|
|
326
346
|
| ----------------------- | --------------------------------- | -------- | ------------------------------------------------------------------- |
|
|
327
|
-
| `kind` | `"
|
|
347
|
+
| `kind` | `"core:mountWidget"` | Yes | Action type |
|
|
328
348
|
| `slot` | string | Yes | Target slot (e.g., `"drawer_right"`, `"overlay_center"`) |
|
|
329
349
|
| `config.title` | string | No | Widget title |
|
|
330
350
|
| `config.expandBehavior` | `"single"` \| `"multiple"` | No | Whether one or many items can be open at once (default: `"single"`) |
|
|
@@ -348,11 +368,11 @@ Each item in the `items` array:
|
|
|
348
368
|
| `config.category` | string | No | Category for grouping items |
|
|
349
369
|
| `config.priority` | number | No | Priority weight for ordering |
|
|
350
370
|
| `config.answerStrategy` | AnswerStrategy | No | AI-generated answer configuration |
|
|
351
|
-
| `
|
|
371
|
+
| `triggerWhen` | DecisionStrategy \| null | No | Conditional visibility strategy |
|
|
352
372
|
|
|
353
373
|
```json
|
|
354
374
|
{
|
|
355
|
-
"kind": "
|
|
375
|
+
"kind": "core:mountWidget",
|
|
356
376
|
"slot": "drawer_right",
|
|
357
377
|
"config": {
|
|
358
378
|
"title": "Frequently Asked Questions",
|
|
@@ -384,7 +404,7 @@ Each item in the `items` array:
|
|
|
384
404
|
"category": "Billing",
|
|
385
405
|
"priority": 5
|
|
386
406
|
},
|
|
387
|
-
"
|
|
407
|
+
"triggerWhen": {
|
|
388
408
|
"type": "rules",
|
|
389
409
|
"rules": [
|
|
390
410
|
{
|
|
@@ -400,13 +420,13 @@ Each item in the `items` array:
|
|
|
400
420
|
}
|
|
401
421
|
```
|
|
402
422
|
|
|
403
|
-
###
|
|
423
|
+
### faq:scroll_to
|
|
404
424
|
|
|
405
425
|
Scrolls the viewport to a specific FAQ item and optionally expands it.
|
|
406
426
|
|
|
407
427
|
| Property | Type | Required | Default | Description |
|
|
408
428
|
| -------------- | ----------------- | -------- | ---------- | ------------------------------------------ |
|
|
409
|
-
| `kind` | `"
|
|
429
|
+
| `kind` | `"faq:scroll_to"` | Yes | | Action type |
|
|
410
430
|
| `itemId` | string | No\* | | Target item ID |
|
|
411
431
|
| `itemQuestion` | string | No\* | | Target item question text (fuzzy match) |
|
|
412
432
|
| `expand` | boolean | No | `true` | Whether to expand the item after scrolling |
|
|
@@ -416,20 +436,20 @@ Scrolls the viewport to a specific FAQ item and optionally expands it.
|
|
|
416
436
|
|
|
417
437
|
```json
|
|
418
438
|
{
|
|
419
|
-
"kind": "
|
|
439
|
+
"kind": "faq:scroll_to",
|
|
420
440
|
"itemId": "payment-methods",
|
|
421
441
|
"expand": true,
|
|
422
442
|
"behavior": "smooth"
|
|
423
443
|
}
|
|
424
444
|
```
|
|
425
445
|
|
|
426
|
-
###
|
|
446
|
+
### faq:toggle_item
|
|
427
447
|
|
|
428
448
|
Opens, closes, or toggles a FAQ item's expanded state.
|
|
429
449
|
|
|
430
450
|
| Property | Type | Required | Default | Description |
|
|
431
451
|
| -------------- | ------------------- | -------- | ---------- | --------------------------------------- |
|
|
432
|
-
| `kind` | `"
|
|
452
|
+
| `kind` | `"faq:toggle_item"` | Yes | | Action type |
|
|
433
453
|
| `itemId` | string | No\* | | Target item ID |
|
|
434
454
|
| `itemQuestion` | string | No\* | | Target item question text (fuzzy match) |
|
|
435
455
|
| `state` | string | No | `"toggle"` | `"open"`, `"closed"`, `"toggle"` |
|
|
@@ -438,19 +458,19 @@ Opens, closes, or toggles a FAQ item's expanded state.
|
|
|
438
458
|
|
|
439
459
|
```json
|
|
440
460
|
{
|
|
441
|
-
"kind": "
|
|
461
|
+
"kind": "faq:toggle_item",
|
|
442
462
|
"itemId": "getting-started",
|
|
443
463
|
"state": "open"
|
|
444
464
|
}
|
|
445
465
|
```
|
|
446
466
|
|
|
447
|
-
###
|
|
467
|
+
### faq:update
|
|
448
468
|
|
|
449
469
|
Dynamically adds, removes, reorders, or replaces FAQ items at runtime.
|
|
450
470
|
|
|
451
471
|
| Property | Type | Required | Description |
|
|
452
472
|
| ----------- | ------------------- | -------- | ------------------------------------------------------- |
|
|
453
|
-
| `kind` | `"
|
|
473
|
+
| `kind` | `"faq:update"` | Yes | Action type |
|
|
454
474
|
| `operation` | string | Yes | `"add"`, `"remove"`, `"reorder"`, `"replace"` |
|
|
455
475
|
| `items` | FAQQuestionAction[] | No | Items to add or replace with (required for add/replace) |
|
|
456
476
|
| `itemId` | string | No | Item to remove (required for remove) |
|
|
@@ -462,7 +482,7 @@ Dynamically adds, removes, reorders, or replaces FAQ items at runtime.
|
|
|
462
482
|
|
|
463
483
|
```json
|
|
464
484
|
{
|
|
465
|
-
"kind": "
|
|
485
|
+
"kind": "faq:update",
|
|
466
486
|
"operation": "add",
|
|
467
487
|
"position": "append",
|
|
468
488
|
"items": [
|
|
@@ -482,7 +502,7 @@ Dynamically adds, removes, reorders, or replaces FAQ items at runtime.
|
|
|
482
502
|
|
|
483
503
|
```json
|
|
484
504
|
{
|
|
485
|
-
"kind": "
|
|
505
|
+
"kind": "faq:update",
|
|
486
506
|
"operation": "remove",
|
|
487
507
|
"itemId": "outdated-question"
|
|
488
508
|
}
|
|
@@ -492,7 +512,7 @@ Dynamically adds, removes, reorders, or replaces FAQ items at runtime.
|
|
|
492
512
|
|
|
493
513
|
```json
|
|
494
514
|
{
|
|
495
|
-
"kind": "
|
|
515
|
+
"kind": "faq:update",
|
|
496
516
|
"operation": "reorder",
|
|
497
517
|
"order": ["getting-started", "new-feature", "payment-methods"]
|
|
498
518
|
}
|
|
@@ -502,7 +522,7 @@ Dynamically adds, removes, reorders, or replaces FAQ items at runtime.
|
|
|
502
522
|
|
|
503
523
|
```json
|
|
504
524
|
{
|
|
505
|
-
"kind": "
|
|
525
|
+
"kind": "faq:update",
|
|
506
526
|
"operation": "replace",
|
|
507
527
|
"items": [
|
|
508
528
|
{
|
|
@@ -521,12 +541,12 @@ Dynamically adds, removes, reorders, or replaces FAQ items at runtime.
|
|
|
521
541
|
|
|
522
542
|
The FAQ widget uses a **compositional action pattern** where `faq:question` actions serve as configuration data rendered by the widget, rather than being executed by the runtime. This allows:
|
|
523
543
|
|
|
524
|
-
- **Per-item conditional visibility** via `
|
|
544
|
+
- **Per-item conditional visibility** via `triggerWhen` strategies -- items can appear or hide based on page URL, user segment, viewport, or any DecisionStrategy condition
|
|
525
545
|
- **Category grouping** -- items with a `category` field are grouped under collapsible section headers
|
|
526
546
|
- **Dynamic injection** -- `injections` rules can add items when trigger conditions are met, supporting contextual FAQ content
|
|
527
547
|
- **Ordering control** -- the `ordering` strategy determines how items are sorted within categories
|
|
528
548
|
|
|
529
|
-
Items without `
|
|
549
|
+
Items without `triggerWhen` are always visible. Items without `category` appear in an ungrouped section.
|
|
530
550
|
|
|
531
551
|
## Rich Answer Content
|
|
532
552
|
|
|
@@ -672,15 +692,55 @@ Injection rules add contextual FAQ items when conditions are met:
|
|
|
672
692
|
|
|
673
693
|
Gamification capabilities including badges, points, and leaderboards.
|
|
674
694
|
|
|
695
|
+
## When to use
|
|
696
|
+
|
|
697
|
+
| Goal | Action |
|
|
698
|
+
|------|--------|
|
|
699
|
+
| Award a badge to a user | `gamification:awardBadge` |
|
|
700
|
+
| Add points to a user's score | `gamification:addPoints` |
|
|
701
|
+
| Mount a gamification widget (leaderboard, progress) | `core:mountWidget` |
|
|
702
|
+
|
|
675
703
|
## Actions
|
|
676
704
|
|
|
677
|
-
###
|
|
705
|
+
### gamification:awardBadge
|
|
706
|
+
|
|
707
|
+
Awards a badge to the current user.
|
|
708
|
+
|
|
709
|
+
| Property | Type | Required | Description |
|
|
710
|
+
| -------- | -------------------------- | -------- | ---------------- |
|
|
711
|
+
| `kind` | `"gamification:awardBadge"` | Yes | Action type |
|
|
712
|
+
| `badgeId` | string | Yes | Badge identifier |
|
|
713
|
+
|
|
714
|
+
```json
|
|
715
|
+
{
|
|
716
|
+
"kind": "gamification:awardBadge",
|
|
717
|
+
"badgeId": "first-purchase"
|
|
718
|
+
}
|
|
719
|
+
```
|
|
720
|
+
|
|
721
|
+
### gamification:addPoints
|
|
722
|
+
|
|
723
|
+
Adds points to the current user's score.
|
|
678
724
|
|
|
679
|
-
|
|
725
|
+
| Property | Type | Required | Description |
|
|
726
|
+
| -------- | -------------------------- | -------- | ---------------- |
|
|
727
|
+
| `kind` | `"gamification:addPoints"` | Yes | Action type |
|
|
728
|
+
| `points` | number | Yes | Points to add |
|
|
729
|
+
|
|
730
|
+
```json
|
|
731
|
+
{
|
|
732
|
+
"kind": "gamification:addPoints",
|
|
733
|
+
"points": 50
|
|
734
|
+
}
|
|
735
|
+
```
|
|
736
|
+
|
|
737
|
+
### core:mountWidget (Gamification)
|
|
738
|
+
|
|
739
|
+
Mounts gamification UI elements (leaderboard, badge display, progress tracker).
|
|
680
740
|
|
|
681
741
|
| Property | Type | Required | Description |
|
|
682
742
|
| -------- | ---------------------- | -------- | -------------------------- |
|
|
683
|
-
| `kind` | `"
|
|
743
|
+
| `kind` | `"core:mountWidget"` | Yes | Action type |
|
|
684
744
|
| `slot` | string | Yes | Target slot |
|
|
685
745
|
| `config` | object | Yes | Gamification configuration |
|
|
686
746
|
|
|
@@ -707,7 +767,7 @@ Mounts gamification UI elements.
|
|
|
707
767
|
|
|
708
768
|
```json
|
|
709
769
|
{
|
|
710
|
-
"kind": "
|
|
770
|
+
"kind": "core:mountWidget",
|
|
711
771
|
"slot": "overlay_corner_br",
|
|
712
772
|
"config": {
|
|
713
773
|
"badges": [
|
|
@@ -719,18 +779,6 @@ Mounts gamification UI elements.
|
|
|
719
779
|
"trigger": {
|
|
720
780
|
"event": "purchase_completed"
|
|
721
781
|
}
|
|
722
|
-
},
|
|
723
|
-
{
|
|
724
|
-
"id": "explorer",
|
|
725
|
-
"name": "Explorer",
|
|
726
|
-
"icon": "compass",
|
|
727
|
-
"description": "Visited 10 different pages",
|
|
728
|
-
"trigger": {
|
|
729
|
-
"event": "page_view",
|
|
730
|
-
"conditions": [
|
|
731
|
-
{ "type": "session_metric", "key": "unique_pages", "operator": ">=", "threshold": 10 }
|
|
732
|
-
]
|
|
733
|
-
}
|
|
734
782
|
}
|
|
735
783
|
],
|
|
736
784
|
"points": {
|
|
@@ -759,6 +807,14 @@ Mounts gamification UI elements.
|
|
|
759
807
|
|
|
760
808
|
Navigation tips accordion widget with conditional item visibility and toast notifications.
|
|
761
809
|
|
|
810
|
+
## When to use
|
|
811
|
+
|
|
812
|
+
| Goal | Action |
|
|
813
|
+
|------|--------|
|
|
814
|
+
| Scroll to an element on the page | `navigation:scrollTo` |
|
|
815
|
+
| Navigate to a different URL | `navigation:navigate` |
|
|
816
|
+
| Show contextual navigation tips widget | `core:mountWidget` with `widget: "adaptive-nav:tips"` |
|
|
817
|
+
|
|
762
818
|
## Widget: `adaptive-nav:tips`
|
|
763
819
|
|
|
764
820
|
Accordion of contextual navigation tips. Each tip has a collapsible header and expanded body with optional CTA link.
|
|
@@ -879,15 +935,26 @@ Navigates to a URL.
|
|
|
879
935
|
|
|
880
936
|
Visual overlay capabilities including highlights, tooltips, badges, pulse animations, and celebrations.
|
|
881
937
|
|
|
938
|
+
## When to use
|
|
939
|
+
|
|
940
|
+
| Goal | Action |
|
|
941
|
+
|------|--------|
|
|
942
|
+
| Draw attention to an element (spotlight) | `overlays:highlight` |
|
|
943
|
+
| Show contextual help or guidance near an element | `overlays:tooltip` |
|
|
944
|
+
| Add a notification indicator (count, "NEW") | `overlays:badge` |
|
|
945
|
+
| Subtle attention-grab animation | `overlays:pulse` |
|
|
946
|
+
| Show a blocking or non-blocking dialog | `overlays:modal` |
|
|
947
|
+
| Celebrate a user achievement | `overlays:celebrate` |
|
|
948
|
+
|
|
882
949
|
## Actions
|
|
883
950
|
|
|
884
|
-
### highlight
|
|
951
|
+
### overlays:highlight
|
|
885
952
|
|
|
886
953
|
Creates a spotlight effect around an element with a scrim overlay.
|
|
887
954
|
|
|
888
955
|
| Property | Type | Required | Default | Description |
|
|
889
956
|
| -------------------- | ------------- | -------- | ----------- | --------------------------------------- |
|
|
890
|
-
| `kind` | `"highlight"` | Yes | | Action type |
|
|
957
|
+
| `kind` | `"overlays:highlight"` | Yes | | Action type |
|
|
891
958
|
| `anchorId` | string | Yes | | Element selector |
|
|
892
959
|
| `style.color` | string | No | `"#5b8cff"` | Ring color |
|
|
893
960
|
| `style.scrimOpacity` | number | No | `0.55` | Backdrop opacity 0-1 (set to 0 to hide) |
|
|
@@ -896,7 +963,7 @@ Creates a spotlight effect around an element with a scrim overlay.
|
|
|
896
963
|
|
|
897
964
|
```json
|
|
898
965
|
{
|
|
899
|
-
"kind": "highlight",
|
|
966
|
+
"kind": "overlays:highlight",
|
|
900
967
|
"anchorId": "#signup-button",
|
|
901
968
|
"style": {
|
|
902
969
|
"color": "#22c55e",
|
|
@@ -905,13 +972,13 @@ Creates a spotlight effect around an element with a scrim overlay.
|
|
|
905
972
|
}
|
|
906
973
|
```
|
|
907
974
|
|
|
908
|
-
### tooltip
|
|
975
|
+
### overlays:tooltip
|
|
909
976
|
|
|
910
977
|
Shows a tooltip near an element with optional title, body, and CTA.
|
|
911
978
|
|
|
912
979
|
| Property | Type | Required | Default | Description |
|
|
913
980
|
| -------------------- | ----------- | -------- | ------------- | -------------------------------------- |
|
|
914
|
-
| `kind` | `"tooltip"` | Yes | | Action type |
|
|
981
|
+
| `kind` | `"overlays:tooltip"` | Yes | | Action type |
|
|
915
982
|
| `anchorId` | string | Yes | | Element selector |
|
|
916
983
|
| `content.title` | string | No | | Tooltip heading |
|
|
917
984
|
| `content.body` | string | Yes | | Tooltip text |
|
|
@@ -927,14 +994,14 @@ Shows a tooltip near an element with optional title, body, and CTA.
|
|
|
927
994
|
|
|
928
995
|
```json
|
|
929
996
|
{
|
|
930
|
-
"kind": "tooltip",
|
|
997
|
+
"kind": "overlays:tooltip",
|
|
931
998
|
"anchorId": "#pricing-toggle",
|
|
932
999
|
"content": {
|
|
933
1000
|
"title": "Save 20%",
|
|
934
1001
|
"body": "Switch to annual billing to save on your subscription.",
|
|
935
1002
|
"cta": {
|
|
936
1003
|
"label": "Switch Now",
|
|
937
|
-
"action": { "kind": "navigate", "url": "/billing?annual=true" }
|
|
1004
|
+
"action": { "kind": "navigation:navigate", "url": "/billing?annual=true" }
|
|
938
1005
|
}
|
|
939
1006
|
},
|
|
940
1007
|
"placement": "bottom",
|
|
@@ -973,45 +1040,45 @@ Use `ctaButtons` for tooltips with multiple actions. Each button has:
|
|
|
973
1040
|
- `"faq:open:<questionId>"` — Convention for companion FAQ tooltips (see adaptive-faq CAPABILITIES for details). Publishes `action.tooltip_cta_clicked` which the FAQ widget listens for.
|
|
974
1041
|
- Any other value — Publishes `action.tooltip_cta_clicked` with the `actionId` in event props for custom handling
|
|
975
1042
|
|
|
976
|
-
### badge
|
|
1043
|
+
### overlays:badge
|
|
977
1044
|
|
|
978
1045
|
Adds a small badge indicator near an element.
|
|
979
1046
|
|
|
980
1047
|
| Property | Type | Required | Default | Description |
|
|
981
1048
|
| ---------- | --------- | -------- | ------------- | -------------------------------------------------------------- |
|
|
982
|
-
| `kind` | `"badge"` | Yes | | Action type |
|
|
1049
|
+
| `kind` | `"overlays:badge"` | Yes | | Action type |
|
|
983
1050
|
| `anchorId` | string | Yes | | Element selector |
|
|
984
1051
|
| `text` | string | Yes | | Badge text (e.g., "NEW", "3") |
|
|
985
1052
|
| `position` | string | No | `"top-right"` | `"top-left"`, `"top-right"`, `"bottom-left"`, `"bottom-right"` |
|
|
986
1053
|
|
|
987
1054
|
```json
|
|
988
1055
|
{
|
|
989
|
-
"kind": "badge",
|
|
1056
|
+
"kind": "overlays:badge",
|
|
990
1057
|
"anchorId": "#inbox-icon",
|
|
991
1058
|
"text": "5",
|
|
992
1059
|
"position": "top-right"
|
|
993
1060
|
}
|
|
994
1061
|
```
|
|
995
1062
|
|
|
996
|
-
### pulse
|
|
1063
|
+
### overlays:pulse
|
|
997
1064
|
|
|
998
1065
|
Adds a pulsing animation to draw attention.
|
|
999
1066
|
|
|
1000
1067
|
| Property | Type | Required | Default | Description |
|
|
1001
1068
|
| ---------- | --------- | -------- | ------- | ------------------------ |
|
|
1002
|
-
| `kind` | `"pulse"` | Yes | | Action type |
|
|
1069
|
+
| `kind` | `"overlays:pulse"` | Yes | | Action type |
|
|
1003
1070
|
| `anchorId` | string | Yes | | Element selector |
|
|
1004
1071
|
| `duration` | number | No | `2000` | Animation duration in ms |
|
|
1005
1072
|
|
|
1006
1073
|
```json
|
|
1007
1074
|
{
|
|
1008
|
-
"kind": "pulse",
|
|
1075
|
+
"kind": "overlays:pulse",
|
|
1009
1076
|
"anchorId": ".notification-bell",
|
|
1010
1077
|
"duration": 3000
|
|
1011
1078
|
}
|
|
1012
1079
|
```
|
|
1013
1080
|
|
|
1014
|
-
### modal
|
|
1081
|
+
### overlays:modal
|
|
1015
1082
|
|
|
1016
1083
|
Shows a centered modal dialog with optional CTA buttons.
|
|
1017
1084
|
|
|
@@ -1051,7 +1118,7 @@ Shows a centered modal dialog with optional CTA buttons.
|
|
|
1051
1118
|
}
|
|
1052
1119
|
```
|
|
1053
1120
|
|
|
1054
|
-
### celebrate
|
|
1121
|
+
### overlays:celebrate
|
|
1055
1122
|
|
|
1056
1123
|
Renders a fullscreen Canvas 2D celebration effect. One action kind with a pluggable `effect` parameter supporting multiple visual presets.
|
|
1057
1124
|
|
|
@@ -1273,15 +1340,7 @@ Control when adaptives activate using `DecisionStrategy`:
|
|
|
1273
1340
|
|
|
1274
1341
|
### 1. Choose the Right Action Type
|
|
1275
1342
|
|
|
1276
|
-
|
|
1277
|
-
|------|--------|
|
|
1278
|
-
| Change text | `set_text` |
|
|
1279
|
-
| Add visual indicator | `badge`, `pulse` |
|
|
1280
|
-
| Show help text | `tooltip` |
|
|
1281
|
-
| Draw attention | `highlight` |
|
|
1282
|
-
| Add content | `insert_html` |
|
|
1283
|
-
| Navigate user | `scroll_to`, `navigate` |
|
|
1284
|
-
| Show UI panel | `mount_widget` + Surfaces |
|
|
1343
|
+
Each adaptive package has a "When to use" guide at the top of its capabilities section above. Refer to those for action selection guidance.
|
|
1285
1344
|
|
|
1286
1345
|
### 2. Anchor Selection
|
|
1287
1346
|
|
|
@@ -1313,8 +1372,8 @@ When `content:insertHtml` needs to open the canvas panel (e.g., a "Help Me Choos
|
|
|
1313
1372
|
|
|
1314
1373
|
```json
|
|
1315
1374
|
{
|
|
1316
|
-
"kind": "
|
|
1317
|
-
"anchorId": "[data-id='pricing-heading']",
|
|
1375
|
+
"kind": "content:insertHtml",
|
|
1376
|
+
"anchorId": { "selector": "[data-id='pricing-heading']", "route": "/" },
|
|
1318
1377
|
"html": "<button style='background: #4a90e2; color: white; border: none; padding: 8px 16px; border-radius: 20px; cursor: pointer;'>Help Me Choose</button>",
|
|
1319
1378
|
"position": "after",
|
|
1320
1379
|
"deepLink": { "tileId": "plan_selector_faq" }
|
|
@@ -1327,4 +1386,4 @@ The `deepLink` object:
|
|
|
1327
1386
|
|
|
1328
1387
|
The SDK automatically opens the canvas, navigates to the tile, sets cursor to pointer, and wires up click/cleanup handlers.
|
|
1329
1388
|
|
|
1330
|
-
**NEVER use `onclick`, `window.SynOS`, or any JavaScript in `
|
|
1389
|
+
**NEVER use `onclick`, `window.SynOS`, or any JavaScript in `content:insertHtml` HTML strings.** The HTML is sanitized and event handlers are stripped. Use `deepLink` instead.
|
package/README.md
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# Smart Canvas Runtime SDK
|
|
2
2
|
|
|
3
|
+
> Config is delivered via GrowthBook feature flags — discovered automatically, no hardcoded keys.
|
|
4
|
+
|
|
3
5
|
## Runtime SDK (React + Shadow DOM)
|
|
4
6
|
|
|
5
7
|
The SDK ships a framework-agnostic `<smart-canvas>` custom element with an **open shadow root**. We render everything with React, but the canvas is encapsulated so host Tailwind configs, resets, or stacking contexts can't break the UI.
|