@syntrologie/runtime-sdk 2.8.0-canary.5 → 2.8.0-canary.50
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 +214 -111
- package/README.md +2 -0
- package/dist/actions/schema.d.ts +1 -1
- package/dist/actions/schema.js +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-WOSJMR3G.js → chunk-MQ3RNLXB.js} +1519 -606
- package/dist/chunk-MQ3RNLXB.js.map +7 -0
- package/dist/{chunk-R5DNAIRI.js → chunk-TN5BLBPU.js} +1 -1
- package/dist/{chunk-R5DNAIRI.js.map → chunk-TN5BLBPU.js.map} +1 -1
- package/dist/components/TileIcon.d.ts +2 -2
- package/dist/components/emojiToIcon.d.ts +24 -0
- 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 +1525 -210
- 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 +115 -65
- package/dist/smart-canvas.esm.js.map +4 -4
- package/dist/smart-canvas.js +5669 -3002
- package/dist/smart-canvas.js.map +4 -4
- package/dist/smart-canvas.min.js +115 -65
- 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 +100 -2
- package/scripts/syntroReactPlugin.mjs +3 -0
- package/scripts/validate-config.mjs +42 -0
- package/dist/chunk-WOSJMR3G.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,16 +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
|
|
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 |
|
|
236
248
|
|
|
237
249
|
**Positions:**
|
|
238
250
|
|
|
@@ -244,45 +256,66 @@ Inserts HTML content relative to an element.
|
|
|
244
256
|
|
|
245
257
|
```json
|
|
246
258
|
{
|
|
247
|
-
"kind": "
|
|
248
|
-
"anchorId": ".cta-button",
|
|
259
|
+
"kind": "content:insertHtml",
|
|
260
|
+
"anchorId": { "selector": ".cta-button", "route": "/" },
|
|
249
261
|
"html": "<span class=\"badge\">NEW</span>",
|
|
250
262
|
"position": "append"
|
|
251
263
|
}
|
|
252
264
|
```
|
|
253
265
|
|
|
254
|
-
|
|
266
|
+
**Deep-linking to canvas tiles:**
|
|
267
|
+
|
|
268
|
+
Use `deepLink` to make inserted content open the canvas panel and navigate to a specific tile when clicked. This is the correct way to connect inserted buttons/links to canvas tiles — do NOT use `onclick` handlers with `window.SynOS`.
|
|
269
|
+
|
|
270
|
+
| Property | Type | Required | Description |
|
|
271
|
+
| ---------------- | ------ | -------- | ---------------------------------- |
|
|
272
|
+
| `deepLink.tileId` | string | Yes | ID of the tile to open |
|
|
273
|
+
| `deepLink.itemId` | string | No | Specific item within the tile |
|
|
274
|
+
|
|
275
|
+
```json
|
|
276
|
+
{
|
|
277
|
+
"kind": "content:insertHtml",
|
|
278
|
+
"anchorId": { "selector": "[data-id='pricing-heading']", "route": "/" },
|
|
279
|
+
"html": "<button style='background: #4a90e2; color: white; border: none; padding: 8px 16px; border-radius: 20px; cursor: pointer;'>Help Me Choose</button>",
|
|
280
|
+
"position": "after",
|
|
281
|
+
"deepLink": { "tileId": "plan_selector_faq" }
|
|
282
|
+
}
|
|
283
|
+
```
|
|
284
|
+
|
|
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.
|
|
286
|
+
|
|
287
|
+
### content:addClass
|
|
255
288
|
|
|
256
289
|
Adds a CSS class to an element.
|
|
257
290
|
|
|
258
|
-
| Property | Type
|
|
259
|
-
| ----------- |
|
|
260
|
-
| `kind` | `"
|
|
261
|
-
| `anchorId` |
|
|
262
|
-
| `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 |
|
|
263
296
|
|
|
264
297
|
```json
|
|
265
298
|
{
|
|
266
|
-
"kind": "
|
|
267
|
-
"anchorId": ".pricing-card",
|
|
299
|
+
"kind": "content:addClass",
|
|
300
|
+
"anchorId": { "selector": ".pricing-card", "route": "/pricing" },
|
|
268
301
|
"className": "highlighted"
|
|
269
302
|
}
|
|
270
303
|
```
|
|
271
304
|
|
|
272
|
-
###
|
|
305
|
+
### content:removeClass
|
|
273
306
|
|
|
274
307
|
Removes a CSS class from an element.
|
|
275
308
|
|
|
276
|
-
| Property | Type
|
|
277
|
-
| ----------- |
|
|
278
|
-
| `kind` | `"
|
|
279
|
-
| `anchorId` |
|
|
280
|
-
| `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 |
|
|
281
314
|
|
|
282
315
|
```json
|
|
283
316
|
{
|
|
284
|
-
"kind": "
|
|
285
|
-
"anchorId": ".pricing-card",
|
|
317
|
+
"kind": "content:removeClass",
|
|
318
|
+
"anchorId": { "selector": ".pricing-card", "route": "/pricing" },
|
|
286
319
|
"className": "hidden"
|
|
287
320
|
}
|
|
288
321
|
```
|
|
@@ -294,15 +327,24 @@ Removes a CSS class from an element.
|
|
|
294
327
|
|
|
295
328
|
Collapsible Q&A accordion with actions, rich content, feedback, and personalization.
|
|
296
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
|
+
|
|
297
339
|
## Actions
|
|
298
340
|
|
|
299
|
-
###
|
|
341
|
+
### core:mountWidget (FAQ)
|
|
300
342
|
|
|
301
343
|
Mounts an FAQ accordion widget to a surface slot.
|
|
302
344
|
|
|
303
345
|
| Property | Type | Required | Description |
|
|
304
346
|
| ----------------------- | --------------------------------- | -------- | ------------------------------------------------------------------- |
|
|
305
|
-
| `kind` | `"
|
|
347
|
+
| `kind` | `"core:mountWidget"` | Yes | Action type |
|
|
306
348
|
| `slot` | string | Yes | Target slot (e.g., `"drawer_right"`, `"overlay_center"`) |
|
|
307
349
|
| `config.title` | string | No | Widget title |
|
|
308
350
|
| `config.expandBehavior` | `"single"` \| `"multiple"` | No | Whether one or many items can be open at once (default: `"single"`) |
|
|
@@ -326,11 +368,11 @@ Each item in the `items` array:
|
|
|
326
368
|
| `config.category` | string | No | Category for grouping items |
|
|
327
369
|
| `config.priority` | number | No | Priority weight for ordering |
|
|
328
370
|
| `config.answerStrategy` | AnswerStrategy | No | AI-generated answer configuration |
|
|
329
|
-
| `
|
|
371
|
+
| `triggerWhen` | DecisionStrategy \| null | No | Conditional visibility strategy |
|
|
330
372
|
|
|
331
373
|
```json
|
|
332
374
|
{
|
|
333
|
-
"kind": "
|
|
375
|
+
"kind": "core:mountWidget",
|
|
334
376
|
"slot": "drawer_right",
|
|
335
377
|
"config": {
|
|
336
378
|
"title": "Frequently Asked Questions",
|
|
@@ -362,7 +404,7 @@ Each item in the `items` array:
|
|
|
362
404
|
"category": "Billing",
|
|
363
405
|
"priority": 5
|
|
364
406
|
},
|
|
365
|
-
"
|
|
407
|
+
"triggerWhen": {
|
|
366
408
|
"type": "rules",
|
|
367
409
|
"rules": [
|
|
368
410
|
{
|
|
@@ -378,13 +420,13 @@ Each item in the `items` array:
|
|
|
378
420
|
}
|
|
379
421
|
```
|
|
380
422
|
|
|
381
|
-
###
|
|
423
|
+
### faq:scroll_to
|
|
382
424
|
|
|
383
425
|
Scrolls the viewport to a specific FAQ item and optionally expands it.
|
|
384
426
|
|
|
385
427
|
| Property | Type | Required | Default | Description |
|
|
386
428
|
| -------------- | ----------------- | -------- | ---------- | ------------------------------------------ |
|
|
387
|
-
| `kind` | `"
|
|
429
|
+
| `kind` | `"faq:scroll_to"` | Yes | | Action type |
|
|
388
430
|
| `itemId` | string | No\* | | Target item ID |
|
|
389
431
|
| `itemQuestion` | string | No\* | | Target item question text (fuzzy match) |
|
|
390
432
|
| `expand` | boolean | No | `true` | Whether to expand the item after scrolling |
|
|
@@ -394,20 +436,20 @@ Scrolls the viewport to a specific FAQ item and optionally expands it.
|
|
|
394
436
|
|
|
395
437
|
```json
|
|
396
438
|
{
|
|
397
|
-
"kind": "
|
|
439
|
+
"kind": "faq:scroll_to",
|
|
398
440
|
"itemId": "payment-methods",
|
|
399
441
|
"expand": true,
|
|
400
442
|
"behavior": "smooth"
|
|
401
443
|
}
|
|
402
444
|
```
|
|
403
445
|
|
|
404
|
-
###
|
|
446
|
+
### faq:toggle_item
|
|
405
447
|
|
|
406
448
|
Opens, closes, or toggles a FAQ item's expanded state.
|
|
407
449
|
|
|
408
450
|
| Property | Type | Required | Default | Description |
|
|
409
451
|
| -------------- | ------------------- | -------- | ---------- | --------------------------------------- |
|
|
410
|
-
| `kind` | `"
|
|
452
|
+
| `kind` | `"faq:toggle_item"` | Yes | | Action type |
|
|
411
453
|
| `itemId` | string | No\* | | Target item ID |
|
|
412
454
|
| `itemQuestion` | string | No\* | | Target item question text (fuzzy match) |
|
|
413
455
|
| `state` | string | No | `"toggle"` | `"open"`, `"closed"`, `"toggle"` |
|
|
@@ -416,19 +458,19 @@ Opens, closes, or toggles a FAQ item's expanded state.
|
|
|
416
458
|
|
|
417
459
|
```json
|
|
418
460
|
{
|
|
419
|
-
"kind": "
|
|
461
|
+
"kind": "faq:toggle_item",
|
|
420
462
|
"itemId": "getting-started",
|
|
421
463
|
"state": "open"
|
|
422
464
|
}
|
|
423
465
|
```
|
|
424
466
|
|
|
425
|
-
###
|
|
467
|
+
### faq:update
|
|
426
468
|
|
|
427
469
|
Dynamically adds, removes, reorders, or replaces FAQ items at runtime.
|
|
428
470
|
|
|
429
471
|
| Property | Type | Required | Description |
|
|
430
472
|
| ----------- | ------------------- | -------- | ------------------------------------------------------- |
|
|
431
|
-
| `kind` | `"
|
|
473
|
+
| `kind` | `"faq:update"` | Yes | Action type |
|
|
432
474
|
| `operation` | string | Yes | `"add"`, `"remove"`, `"reorder"`, `"replace"` |
|
|
433
475
|
| `items` | FAQQuestionAction[] | No | Items to add or replace with (required for add/replace) |
|
|
434
476
|
| `itemId` | string | No | Item to remove (required for remove) |
|
|
@@ -440,7 +482,7 @@ Dynamically adds, removes, reorders, or replaces FAQ items at runtime.
|
|
|
440
482
|
|
|
441
483
|
```json
|
|
442
484
|
{
|
|
443
|
-
"kind": "
|
|
485
|
+
"kind": "faq:update",
|
|
444
486
|
"operation": "add",
|
|
445
487
|
"position": "append",
|
|
446
488
|
"items": [
|
|
@@ -460,7 +502,7 @@ Dynamically adds, removes, reorders, or replaces FAQ items at runtime.
|
|
|
460
502
|
|
|
461
503
|
```json
|
|
462
504
|
{
|
|
463
|
-
"kind": "
|
|
505
|
+
"kind": "faq:update",
|
|
464
506
|
"operation": "remove",
|
|
465
507
|
"itemId": "outdated-question"
|
|
466
508
|
}
|
|
@@ -470,7 +512,7 @@ Dynamically adds, removes, reorders, or replaces FAQ items at runtime.
|
|
|
470
512
|
|
|
471
513
|
```json
|
|
472
514
|
{
|
|
473
|
-
"kind": "
|
|
515
|
+
"kind": "faq:update",
|
|
474
516
|
"operation": "reorder",
|
|
475
517
|
"order": ["getting-started", "new-feature", "payment-methods"]
|
|
476
518
|
}
|
|
@@ -480,7 +522,7 @@ Dynamically adds, removes, reorders, or replaces FAQ items at runtime.
|
|
|
480
522
|
|
|
481
523
|
```json
|
|
482
524
|
{
|
|
483
|
-
"kind": "
|
|
525
|
+
"kind": "faq:update",
|
|
484
526
|
"operation": "replace",
|
|
485
527
|
"items": [
|
|
486
528
|
{
|
|
@@ -499,12 +541,12 @@ Dynamically adds, removes, reorders, or replaces FAQ items at runtime.
|
|
|
499
541
|
|
|
500
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:
|
|
501
543
|
|
|
502
|
-
- **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
|
|
503
545
|
- **Category grouping** -- items with a `category` field are grouped under collapsible section headers
|
|
504
546
|
- **Dynamic injection** -- `injections` rules can add items when trigger conditions are met, supporting contextual FAQ content
|
|
505
547
|
- **Ordering control** -- the `ordering` strategy determines how items are sorted within categories
|
|
506
548
|
|
|
507
|
-
Items without `
|
|
549
|
+
Items without `triggerWhen` are always visible. Items without `category` appear in an ungrouped section.
|
|
508
550
|
|
|
509
551
|
## Rich Answer Content
|
|
510
552
|
|
|
@@ -650,15 +692,55 @@ Injection rules add contextual FAQ items when conditions are met:
|
|
|
650
692
|
|
|
651
693
|
Gamification capabilities including badges, points, and leaderboards.
|
|
652
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
|
+
|
|
653
703
|
## Actions
|
|
654
704
|
|
|
655
|
-
###
|
|
705
|
+
### gamification:awardBadge
|
|
656
706
|
|
|
657
|
-
|
|
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.
|
|
724
|
+
|
|
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).
|
|
658
740
|
|
|
659
741
|
| Property | Type | Required | Description |
|
|
660
742
|
| -------- | ---------------------- | -------- | -------------------------- |
|
|
661
|
-
| `kind` | `"
|
|
743
|
+
| `kind` | `"core:mountWidget"` | Yes | Action type |
|
|
662
744
|
| `slot` | string | Yes | Target slot |
|
|
663
745
|
| `config` | object | Yes | Gamification configuration |
|
|
664
746
|
|
|
@@ -685,7 +767,7 @@ Mounts gamification UI elements.
|
|
|
685
767
|
|
|
686
768
|
```json
|
|
687
769
|
{
|
|
688
|
-
"kind": "
|
|
770
|
+
"kind": "core:mountWidget",
|
|
689
771
|
"slot": "overlay_corner_br",
|
|
690
772
|
"config": {
|
|
691
773
|
"badges": [
|
|
@@ -697,18 +779,6 @@ Mounts gamification UI elements.
|
|
|
697
779
|
"trigger": {
|
|
698
780
|
"event": "purchase_completed"
|
|
699
781
|
}
|
|
700
|
-
},
|
|
701
|
-
{
|
|
702
|
-
"id": "explorer",
|
|
703
|
-
"name": "Explorer",
|
|
704
|
-
"icon": "compass",
|
|
705
|
-
"description": "Visited 10 different pages",
|
|
706
|
-
"trigger": {
|
|
707
|
-
"event": "page_view",
|
|
708
|
-
"conditions": [
|
|
709
|
-
{ "type": "session_metric", "key": "unique_pages", "operator": ">=", "threshold": 10 }
|
|
710
|
-
]
|
|
711
|
-
}
|
|
712
782
|
}
|
|
713
783
|
],
|
|
714
784
|
"points": {
|
|
@@ -737,6 +807,14 @@ Mounts gamification UI elements.
|
|
|
737
807
|
|
|
738
808
|
Navigation tips accordion widget with conditional item visibility and toast notifications.
|
|
739
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
|
+
|
|
740
818
|
## Widget: `adaptive-nav:tips`
|
|
741
819
|
|
|
742
820
|
Accordion of contextual navigation tips. Each tip has a collapsible header and expanded body with optional CTA link.
|
|
@@ -857,15 +935,26 @@ Navigates to a URL.
|
|
|
857
935
|
|
|
858
936
|
Visual overlay capabilities including highlights, tooltips, badges, pulse animations, and celebrations.
|
|
859
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
|
+
|
|
860
949
|
## Actions
|
|
861
950
|
|
|
862
|
-
### highlight
|
|
951
|
+
### overlays:highlight
|
|
863
952
|
|
|
864
953
|
Creates a spotlight effect around an element with a scrim overlay.
|
|
865
954
|
|
|
866
955
|
| Property | Type | Required | Default | Description |
|
|
867
956
|
| -------------------- | ------------- | -------- | ----------- | --------------------------------------- |
|
|
868
|
-
| `kind` | `"highlight"` | Yes | | Action type |
|
|
957
|
+
| `kind` | `"overlays:highlight"` | Yes | | Action type |
|
|
869
958
|
| `anchorId` | string | Yes | | Element selector |
|
|
870
959
|
| `style.color` | string | No | `"#5b8cff"` | Ring color |
|
|
871
960
|
| `style.scrimOpacity` | number | No | `0.55` | Backdrop opacity 0-1 (set to 0 to hide) |
|
|
@@ -874,7 +963,7 @@ Creates a spotlight effect around an element with a scrim overlay.
|
|
|
874
963
|
|
|
875
964
|
```json
|
|
876
965
|
{
|
|
877
|
-
"kind": "highlight",
|
|
966
|
+
"kind": "overlays:highlight",
|
|
878
967
|
"anchorId": "#signup-button",
|
|
879
968
|
"style": {
|
|
880
969
|
"color": "#22c55e",
|
|
@@ -883,13 +972,13 @@ Creates a spotlight effect around an element with a scrim overlay.
|
|
|
883
972
|
}
|
|
884
973
|
```
|
|
885
974
|
|
|
886
|
-
### tooltip
|
|
975
|
+
### overlays:tooltip
|
|
887
976
|
|
|
888
977
|
Shows a tooltip near an element with optional title, body, and CTA.
|
|
889
978
|
|
|
890
979
|
| Property | Type | Required | Default | Description |
|
|
891
980
|
| -------------------- | ----------- | -------- | ------------- | -------------------------------------- |
|
|
892
|
-
| `kind` | `"tooltip"` | Yes | | Action type |
|
|
981
|
+
| `kind` | `"overlays:tooltip"` | Yes | | Action type |
|
|
893
982
|
| `anchorId` | string | Yes | | Element selector |
|
|
894
983
|
| `content.title` | string | No | | Tooltip heading |
|
|
895
984
|
| `content.body` | string | Yes | | Tooltip text |
|
|
@@ -905,14 +994,14 @@ Shows a tooltip near an element with optional title, body, and CTA.
|
|
|
905
994
|
|
|
906
995
|
```json
|
|
907
996
|
{
|
|
908
|
-
"kind": "tooltip",
|
|
997
|
+
"kind": "overlays:tooltip",
|
|
909
998
|
"anchorId": "#pricing-toggle",
|
|
910
999
|
"content": {
|
|
911
1000
|
"title": "Save 20%",
|
|
912
1001
|
"body": "Switch to annual billing to save on your subscription.",
|
|
913
1002
|
"cta": {
|
|
914
1003
|
"label": "Switch Now",
|
|
915
|
-
"action": { "kind": "navigate", "url": "/billing?annual=true" }
|
|
1004
|
+
"action": { "kind": "navigation:navigate", "url": "/billing?annual=true" }
|
|
916
1005
|
}
|
|
917
1006
|
},
|
|
918
1007
|
"placement": "bottom",
|
|
@@ -951,45 +1040,45 @@ Use `ctaButtons` for tooltips with multiple actions. Each button has:
|
|
|
951
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.
|
|
952
1041
|
- Any other value — Publishes `action.tooltip_cta_clicked` with the `actionId` in event props for custom handling
|
|
953
1042
|
|
|
954
|
-
### badge
|
|
1043
|
+
### overlays:badge
|
|
955
1044
|
|
|
956
1045
|
Adds a small badge indicator near an element.
|
|
957
1046
|
|
|
958
1047
|
| Property | Type | Required | Default | Description |
|
|
959
1048
|
| ---------- | --------- | -------- | ------------- | -------------------------------------------------------------- |
|
|
960
|
-
| `kind` | `"badge"` | Yes | | Action type |
|
|
1049
|
+
| `kind` | `"overlays:badge"` | Yes | | Action type |
|
|
961
1050
|
| `anchorId` | string | Yes | | Element selector |
|
|
962
1051
|
| `text` | string | Yes | | Badge text (e.g., "NEW", "3") |
|
|
963
1052
|
| `position` | string | No | `"top-right"` | `"top-left"`, `"top-right"`, `"bottom-left"`, `"bottom-right"` |
|
|
964
1053
|
|
|
965
1054
|
```json
|
|
966
1055
|
{
|
|
967
|
-
"kind": "badge",
|
|
1056
|
+
"kind": "overlays:badge",
|
|
968
1057
|
"anchorId": "#inbox-icon",
|
|
969
1058
|
"text": "5",
|
|
970
1059
|
"position": "top-right"
|
|
971
1060
|
}
|
|
972
1061
|
```
|
|
973
1062
|
|
|
974
|
-
### pulse
|
|
1063
|
+
### overlays:pulse
|
|
975
1064
|
|
|
976
1065
|
Adds a pulsing animation to draw attention.
|
|
977
1066
|
|
|
978
1067
|
| Property | Type | Required | Default | Description |
|
|
979
1068
|
| ---------- | --------- | -------- | ------- | ------------------------ |
|
|
980
|
-
| `kind` | `"pulse"` | Yes | | Action type |
|
|
1069
|
+
| `kind` | `"overlays:pulse"` | Yes | | Action type |
|
|
981
1070
|
| `anchorId` | string | Yes | | Element selector |
|
|
982
1071
|
| `duration` | number | No | `2000` | Animation duration in ms |
|
|
983
1072
|
|
|
984
1073
|
```json
|
|
985
1074
|
{
|
|
986
|
-
"kind": "pulse",
|
|
1075
|
+
"kind": "overlays:pulse",
|
|
987
1076
|
"anchorId": ".notification-bell",
|
|
988
1077
|
"duration": 3000
|
|
989
1078
|
}
|
|
990
1079
|
```
|
|
991
1080
|
|
|
992
|
-
### modal
|
|
1081
|
+
### overlays:modal
|
|
993
1082
|
|
|
994
1083
|
Shows a centered modal dialog with optional CTA buttons.
|
|
995
1084
|
|
|
@@ -1029,7 +1118,7 @@ Shows a centered modal dialog with optional CTA buttons.
|
|
|
1029
1118
|
}
|
|
1030
1119
|
```
|
|
1031
1120
|
|
|
1032
|
-
### celebrate
|
|
1121
|
+
### overlays:celebrate
|
|
1033
1122
|
|
|
1034
1123
|
Renders a fullscreen Canvas 2D celebration effect. One action kind with a pluggable `effect` parameter supporting multiple visual presets.
|
|
1035
1124
|
|
|
@@ -1251,15 +1340,7 @@ Control when adaptives activate using `DecisionStrategy`:
|
|
|
1251
1340
|
|
|
1252
1341
|
### 1. Choose the Right Action Type
|
|
1253
1342
|
|
|
1254
|
-
|
|
1255
|
-
|------|--------|
|
|
1256
|
-
| Change text | `set_text` |
|
|
1257
|
-
| Add visual indicator | `badge`, `pulse` |
|
|
1258
|
-
| Show help text | `tooltip` |
|
|
1259
|
-
| Draw attention | `highlight` |
|
|
1260
|
-
| Add content | `insert_html` |
|
|
1261
|
-
| Navigate user | `scroll_to`, `navigate` |
|
|
1262
|
-
| 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.
|
|
1263
1344
|
|
|
1264
1345
|
### 2. Anchor Selection
|
|
1265
1346
|
|
|
@@ -1284,3 +1365,25 @@ Control when adaptives activate using `DecisionStrategy`:
|
|
|
1284
1365
|
- Listen for `action.failed` to handle errors
|
|
1285
1366
|
- Track `action.applied` for analytics
|
|
1286
1367
|
- Use EventBus for cross-adaptive coordination
|
|
1368
|
+
|
|
1369
|
+
### 6. Opening the Canvas from Inserted Content
|
|
1370
|
+
|
|
1371
|
+
When `content:insertHtml` needs to open the canvas panel (e.g., a "Help Me Choose" button that opens an FAQ tile), use the `deepLink` property — **never write `onclick` handlers or reference `window.SynOS` in HTML**.
|
|
1372
|
+
|
|
1373
|
+
```json
|
|
1374
|
+
{
|
|
1375
|
+
"kind": "content:insertHtml",
|
|
1376
|
+
"anchorId": { "selector": "[data-id='pricing-heading']", "route": "/" },
|
|
1377
|
+
"html": "<button style='background: #4a90e2; color: white; border: none; padding: 8px 16px; border-radius: 20px; cursor: pointer;'>Help Me Choose</button>",
|
|
1378
|
+
"position": "after",
|
|
1379
|
+
"deepLink": { "tileId": "plan_selector_faq" }
|
|
1380
|
+
}
|
|
1381
|
+
```
|
|
1382
|
+
|
|
1383
|
+
The `deepLink` object:
|
|
1384
|
+
- `tileId` (required) — ID of the canvas tile to navigate to
|
|
1385
|
+
- `itemId` (optional) — specific item within the tile (e.g., a FAQ question ID)
|
|
1386
|
+
|
|
1387
|
+
The SDK automatically opens the canvas, navigates to the tile, sets cursor to pointer, and wires up click/cleanup handlers.
|
|
1388
|
+
|
|
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.
|
package/dist/actions/schema.d.ts
CHANGED
|
@@ -26592,4 +26592,4 @@ export declare const coreActionStepSchemas: ({
|
|
|
26592
26592
|
}>]>>>;
|
|
26593
26593
|
}, z.ZodTypeAny, "passthrough">>;
|
|
26594
26594
|
})[];
|
|
26595
|
-
export {
|
|
26595
|
+
export { AddClassZ, AnchorIdZ, BadgePositionZ, BadgeZ, CtaButtonZ, HighlightStyleZ, HighlightZ, InsertHtmlZ, InsertPositionZ, ModalContentZ, ModalZ, MountWidgetZ, NavigateZ, ParallelZ, PlacementZ, PulseZ, RemoveClassZ, ScrollBehaviorZ, ScrollLogicalPositionZ, ScrollToZ, SequenceZ, SetAttrZ, SetStyleZ, SetTextZ, TooltipContentZ, TooltipTriggerZ, TooltipZ, TourStepForSchemaZ, TourZ, WaitZ, WidgetConfigZ, };
|