@syntrologie/runtime-sdk 2.1.0-canary.8 → 2.1.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 +415 -115
- package/dist/SmartCanvasApp.d.ts +1 -3
- package/dist/SmartCanvasApp.js +16 -10
- package/dist/SmartCanvasApp.js.map +1 -1
- package/dist/SmartCanvasElement.d.ts +0 -2
- package/dist/SmartCanvasElement.js +3 -8
- package/dist/SmartCanvasElement.js.map +1 -1
- package/dist/actions/executors/index.js +4 -1
- package/dist/actions/executors/index.js.map +1 -1
- package/dist/actions/executors/tour.js +2 -2
- package/dist/actions/executors/tour.js.map +1 -1
- package/dist/actions/validation.js +5 -30
- package/dist/actions/validation.js.map +1 -1
- package/dist/adaptives/adaptive-chatbot/index.js +7 -5
- package/dist/adaptives/adaptive-chatbot/index.js.map +4 -4
- package/dist/adaptives/adaptive-content/index.js +22 -0
- package/dist/adaptives/adaptive-content/index.js.map +7 -0
- package/dist/adaptives/adaptive-faq/index.js +11 -0
- package/dist/adaptives/adaptive-faq/index.js.map +7 -0
- package/dist/adaptives/adaptive-gamification/index.js +2 -0
- package/dist/adaptives/adaptive-gamification/index.js.map +7 -0
- package/dist/adaptives/adaptive-nav/index.js +12 -0
- package/dist/adaptives/adaptive-nav/index.js.map +7 -0
- package/dist/adaptives/adaptive-overlays/index.js +94 -0
- package/dist/adaptives/adaptive-overlays/index.js.map +7 -0
- package/dist/api.d.ts +1 -9
- package/dist/api.js +5 -5
- package/dist/api.js.map +1 -1
- package/dist/apps/AppLoader.d.ts +5 -0
- package/dist/apps/AppLoader.js +28 -3
- package/dist/apps/AppLoader.js.map +1 -1
- package/dist/apps/index.d.ts +1 -1
- package/dist/apps/types.d.ts +26 -0
- package/dist/blocks/data/ComparisonBlock.js +12 -9
- package/dist/blocks/data/ComparisonBlock.js.map +1 -1
- package/dist/blocks/data/StatsBlock.js +11 -10
- package/dist/blocks/data/StatsBlock.js.map +1 -1
- package/dist/blocks/index.d.ts +9 -5
- package/dist/blocks/index.js +2 -2
- package/dist/blocks/index.js.map +1 -1
- package/dist/blocks/interactive/ChecklistBlock.js +13 -12
- package/dist/blocks/interactive/ChecklistBlock.js.map +1 -1
- package/dist/blocks/interactive/RatingBlock.js +18 -12
- package/dist/blocks/interactive/RatingBlock.js.map +1 -1
- package/dist/blocks/notification/NotificationBlock.js +24 -23
- package/dist/blocks/notification/NotificationBlock.js.map +1 -1
- package/dist/blocks/theme-tokens.d.ts +23 -0
- package/dist/blocks/theme-tokens.js +25 -0
- package/dist/blocks/theme-tokens.js.map +1 -0
- package/dist/bootstrap.js +21 -24
- package/dist/bootstrap.js.map +1 -1
- package/dist/components/ShadowCanvasOverlay.d.ts +6 -3
- package/dist/components/ShadowCanvasOverlay.js +191 -115
- package/dist/components/ShadowCanvasOverlay.js.map +1 -1
- package/dist/components/TileCard.d.ts +1 -5
- package/dist/components/TileCard.js +62 -286
- package/dist/components/TileCard.js.map +1 -1
- package/dist/components/TileWheel.js +24 -4
- package/dist/components/TileWheel.js.map +1 -1
- package/dist/configFetcher.d.ts +5 -1
- package/dist/configFetcher.js +33 -2
- package/dist/configFetcher.js.map +1 -1
- package/dist/context/ContextManager.js +3 -2
- package/dist/context/ContextManager.js.map +1 -1
- package/dist/decisions/engine.d.ts +4 -0
- package/dist/decisions/engine.js +6 -1
- package/dist/decisions/engine.js.map +1 -1
- package/dist/decisions/schema.d.ts +241 -0
- package/dist/decisions/schema.js +8 -0
- package/dist/decisions/schema.js.map +1 -1
- package/dist/decisions/strategies/rules.js +14 -0
- package/dist/decisions/strategies/rules.js.map +1 -1
- package/dist/decisions/types.d.ts +21 -1
- package/dist/editorLoader.d.ts +19 -9
- package/dist/editorLoader.js +112 -94
- package/dist/editorLoader.js.map +1 -1
- package/dist/events/EventAccumulator.d.ts +29 -0
- package/dist/events/EventAccumulator.js +101 -0
- package/dist/events/EventAccumulator.js.map +1 -0
- package/dist/events/index.d.ts +2 -0
- package/dist/events/index.js +1 -0
- package/dist/events/index.js.map +1 -1
- package/dist/events/normalizers/posthog.js +12 -4
- package/dist/events/normalizers/posthog.js.map +1 -1
- package/dist/events/types.d.ts +4 -0
- package/dist/events/types.js +5 -0
- package/dist/events/types.js.map +1 -1
- package/dist/experiments/adapters/growthbook.d.ts +2 -1
- package/dist/experiments/adapters/growthbook.js +11 -23
- package/dist/experiments/adapters/growthbook.js.map +1 -1
- package/dist/experiments/types.d.ts +5 -0
- package/dist/fetchers/experimentsFetcher.d.ts +23 -1
- package/dist/fetchers/experimentsFetcher.js +48 -1
- package/dist/fetchers/experimentsFetcher.js.map +1 -1
- package/dist/fetchers/mergeConfigs.d.ts +29 -0
- package/dist/fetchers/mergeConfigs.js +38 -0
- package/dist/fetchers/mergeConfigs.js.map +1 -0
- package/dist/hooks/useShadowCanvasConfig.js +1 -1
- package/dist/hooks/useShadowCanvasConfig.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +28 -0
- package/dist/index.js.map +1 -1
- package/dist/notifications/NotificationToastStack.d.ts +8 -0
- package/dist/notifications/NotificationToastStack.js +118 -0
- package/dist/notifications/NotificationToastStack.js.map +1 -0
- package/dist/notifications/index.d.ts +9 -0
- package/dist/notifications/index.js +6 -0
- package/dist/notifications/index.js.map +1 -0
- package/dist/notifications/matcher.d.ts +25 -0
- package/dist/notifications/matcher.js +66 -0
- package/dist/notifications/matcher.js.map +1 -0
- package/dist/notifications/types.d.ts +64 -0
- package/dist/notifications/types.js +13 -0
- package/dist/notifications/types.js.map +1 -0
- package/dist/notifications/useNotifications.d.ts +19 -0
- package/dist/notifications/useNotifications.js +104 -0
- package/dist/notifications/useNotifications.js.map +1 -0
- package/dist/notifications/useNotifyWatcher.d.ts +15 -0
- package/dist/notifications/useNotifyWatcher.js +62 -0
- package/dist/notifications/useNotifyWatcher.js.map +1 -0
- package/dist/overlays/runtime/overlay/runner.js +2 -2
- package/dist/overlays/runtime/overlay/runner.js.map +1 -1
- package/dist/render/RenderContext.js +5 -3
- package/dist/render/RenderContext.js.map +1 -1
- package/dist/render/types.d.ts +2 -3
- package/dist/runtime.d.ts +3 -0
- package/dist/runtime.js +28 -12
- package/dist/runtime.js.map +1 -1
- package/dist/smart-canvas.esm.js +131 -102
- package/dist/smart-canvas.esm.js.map +4 -4
- package/dist/smart-canvas.js +40870 -43700
- package/dist/smart-canvas.js.map +4 -4
- package/dist/smart-canvas.min.js +131 -102
- package/dist/smart-canvas.min.js.map +4 -4
- package/dist/theme/defaultTheme.d.ts +7 -3
- package/dist/theme/defaultTheme.js +78 -51
- package/dist/theme/defaultTheme.js.map +1 -1
- package/dist/theme/index.d.ts +1 -1
- package/dist/theme/index.js +1 -1
- package/dist/theme/index.js.map +1 -1
- package/dist/theme/types.d.ts +7 -0
- package/dist/types.d.ts +13 -100
- package/dist/types.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/dist/version.js.map +1 -1
- package/dist/widgets/WidgetRegistry.d.ts +6 -1
- package/dist/widgets/WidgetRegistry.js +12 -4
- package/dist/widgets/WidgetRegistry.js.map +1 -1
- package/package.json +18 -12
- package/schema/canvas-config.schema.json +34 -69
- package/schema/event-catalog.schema.json +157 -0
- package/scripts/validate-config.mjs +20 -13
- package/dist/adaptives/faq/index.js +0 -11
- package/dist/adaptives/faq/index.js.map +0 -7
- package/dist/adaptives/gamification/index.js +0 -2
- package/dist/adaptives/gamification/index.js.map +0 -7
- package/dist/adaptives/nav/index.js +0 -11
- package/dist/adaptives/nav/index.js.map +0 -7
package/CAPABILITIES.md
CHANGED
|
@@ -291,7 +291,7 @@ Removes a CSS class from an element.
|
|
|
291
291
|
|
|
292
292
|
# @syntrologie/adapt-faq
|
|
293
293
|
|
|
294
|
-
|
|
294
|
+
Collapsible Q&A accordion with actions, rich content, feedback, and personalization. Supports mounting a full FAQ widget, scrolling to specific items, toggling item state, and dynamically updating the item list at runtime.
|
|
295
295
|
|
|
296
296
|
## Actions
|
|
297
297
|
|
|
@@ -299,22 +299,33 @@ FAQ accordion widget with conditional item visibility.
|
|
|
299
299
|
|
|
300
300
|
Mounts an FAQ accordion widget to a surface slot.
|
|
301
301
|
|
|
302
|
-
| Property
|
|
303
|
-
|
|
|
304
|
-
| `kind`
|
|
305
|
-
| `slot`
|
|
306
|
-
| `config.title`
|
|
307
|
-
| `config.
|
|
302
|
+
| Property | Type | Required | Description |
|
|
303
|
+
| ----------------------- | --------------------------------- | -------- | ------------------------------------------------------------------- |
|
|
304
|
+
| `kind` | `"mount_faq"` | Yes | Action type |
|
|
305
|
+
| `slot` | string | Yes | Target slot (e.g., `"drawer_right"`, `"overlay_center"`) |
|
|
306
|
+
| `config.title` | string | No | Widget title |
|
|
307
|
+
| `config.expandBehavior` | `"single"` \| `"multiple"` | No | Whether one or many items can be open at once (default: `"single"`) |
|
|
308
|
+
| `config.searchable` | boolean | No | Show a search/filter input (default: `false`) |
|
|
309
|
+
| `config.theme` | `"light"` \| `"dark"` \| `"auto"` | No | Color theme (default: `"auto"`) |
|
|
310
|
+
| `config.items` | array | Yes | FAQ items (see below) |
|
|
311
|
+
| `config.feedback` | boolean \| FeedbackConfig | No | Enable per-item feedback widget |
|
|
312
|
+
| `config.ordering` | OrderingStrategy | No | Item ordering strategy (default: `"static"`) |
|
|
313
|
+
| `config.injections` | InjectionRule[] | No | Dynamic item injection rules |
|
|
308
314
|
|
|
309
315
|
### FAQ Item Schema
|
|
310
316
|
|
|
311
317
|
Each item in the `items` array:
|
|
312
318
|
|
|
313
|
-
| Property
|
|
314
|
-
|
|
|
315
|
-
| `
|
|
316
|
-
| `
|
|
317
|
-
| `
|
|
319
|
+
| Property | Type | Required | Description |
|
|
320
|
+
| ----------------------- | ------------------------ | -------- | ----------------------------------------------- |
|
|
321
|
+
| `kind` | `"faq:question"` | Yes | Compositional action type |
|
|
322
|
+
| `config.id` | string | Yes | Unique identifier for this question |
|
|
323
|
+
| `config.question` | string | Yes | The question text |
|
|
324
|
+
| `config.answer` | FAQAnswer | Yes | Answer content (string, rich HTML, or markdown) |
|
|
325
|
+
| `config.category` | string | No | Category for grouping items |
|
|
326
|
+
| `config.priority` | number | No | Priority weight for ordering |
|
|
327
|
+
| `config.answerStrategy` | AnswerStrategy | No | AI-generated answer configuration |
|
|
328
|
+
| `showWhen` | DecisionStrategy \| null | No | Conditional visibility strategy |
|
|
318
329
|
|
|
319
330
|
```json
|
|
320
331
|
{
|
|
@@ -322,14 +333,34 @@ Each item in the `items` array:
|
|
|
322
333
|
"slot": "drawer_right",
|
|
323
334
|
"config": {
|
|
324
335
|
"title": "Frequently Asked Questions",
|
|
336
|
+
"expandBehavior": "single",
|
|
337
|
+
"searchable": true,
|
|
338
|
+
"theme": "auto",
|
|
339
|
+
"feedback": {
|
|
340
|
+
"style": "thumbs",
|
|
341
|
+
"prompt": "Was this helpful?"
|
|
342
|
+
},
|
|
343
|
+
"ordering": "priority",
|
|
325
344
|
"items": [
|
|
326
345
|
{
|
|
327
|
-
"
|
|
328
|
-
"
|
|
346
|
+
"kind": "faq:question",
|
|
347
|
+
"config": {
|
|
348
|
+
"id": "getting-started",
|
|
349
|
+
"question": "How do I get started?",
|
|
350
|
+
"answer": "Sign up for a free account and follow our quickstart guide.",
|
|
351
|
+
"category": "General",
|
|
352
|
+
"priority": 10
|
|
353
|
+
}
|
|
329
354
|
},
|
|
330
355
|
{
|
|
331
|
-
"
|
|
332
|
-
"
|
|
356
|
+
"kind": "faq:question",
|
|
357
|
+
"config": {
|
|
358
|
+
"id": "payment-methods",
|
|
359
|
+
"question": "What payment methods do you accept?",
|
|
360
|
+
"answer": "We accept all major credit cards and PayPal.",
|
|
361
|
+
"category": "Billing",
|
|
362
|
+
"priority": 5
|
|
363
|
+
},
|
|
333
364
|
"showWhen": {
|
|
334
365
|
"type": "rules",
|
|
335
366
|
"rules": [
|
|
@@ -346,16 +377,270 @@ Each item in the `items` array:
|
|
|
346
377
|
}
|
|
347
378
|
```
|
|
348
379
|
|
|
380
|
+
### scroll_to_faq
|
|
381
|
+
|
|
382
|
+
Scrolls the viewport to a specific FAQ item and optionally expands it.
|
|
383
|
+
|
|
384
|
+
| Property | Type | Required | Default | Description |
|
|
385
|
+
| -------------- | ----------------- | -------- | ---------- | ------------------------------------------ |
|
|
386
|
+
| `kind` | `"scroll_to_faq"` | Yes | | Action type |
|
|
387
|
+
| `itemId` | string | No\* | | Target item ID |
|
|
388
|
+
| `itemQuestion` | string | No\* | | Target item question text (fuzzy match) |
|
|
389
|
+
| `expand` | boolean | No | `true` | Whether to expand the item after scrolling |
|
|
390
|
+
| `behavior` | string | No | `"smooth"` | `"smooth"`, `"instant"`, `"auto"` |
|
|
391
|
+
|
|
392
|
+
\* Either `itemId` or `itemQuestion` is required.
|
|
393
|
+
|
|
394
|
+
```json
|
|
395
|
+
{
|
|
396
|
+
"kind": "scroll_to_faq",
|
|
397
|
+
"itemId": "payment-methods",
|
|
398
|
+
"expand": true,
|
|
399
|
+
"behavior": "smooth"
|
|
400
|
+
}
|
|
401
|
+
```
|
|
402
|
+
|
|
403
|
+
### toggle_faq_item
|
|
404
|
+
|
|
405
|
+
Opens, closes, or toggles a FAQ item's expanded state.
|
|
406
|
+
|
|
407
|
+
| Property | Type | Required | Default | Description |
|
|
408
|
+
| -------------- | ------------------- | -------- | ---------- | --------------------------------------- |
|
|
409
|
+
| `kind` | `"toggle_faq_item"` | Yes | | Action type |
|
|
410
|
+
| `itemId` | string | No\* | | Target item ID |
|
|
411
|
+
| `itemQuestion` | string | No\* | | Target item question text (fuzzy match) |
|
|
412
|
+
| `state` | string | No | `"toggle"` | `"open"`, `"closed"`, `"toggle"` |
|
|
413
|
+
|
|
414
|
+
\* Either `itemId` or `itemQuestion` is required.
|
|
415
|
+
|
|
416
|
+
```json
|
|
417
|
+
{
|
|
418
|
+
"kind": "toggle_faq_item",
|
|
419
|
+
"itemId": "getting-started",
|
|
420
|
+
"state": "open"
|
|
421
|
+
}
|
|
422
|
+
```
|
|
423
|
+
|
|
424
|
+
### update_faq
|
|
425
|
+
|
|
426
|
+
Dynamically adds, removes, reorders, or replaces FAQ items at runtime.
|
|
427
|
+
|
|
428
|
+
| Property | Type | Required | Description |
|
|
429
|
+
| ----------- | ------------------- | -------- | ------------------------------------------------------- |
|
|
430
|
+
| `kind` | `"update_faq"` | Yes | Action type |
|
|
431
|
+
| `operation` | string | Yes | `"add"`, `"remove"`, `"reorder"`, `"replace"` |
|
|
432
|
+
| `items` | FAQQuestionAction[] | No | Items to add or replace with (required for add/replace) |
|
|
433
|
+
| `itemId` | string | No | Item to remove (required for remove) |
|
|
434
|
+
| `order` | string[] | No | Ordered list of item IDs (required for reorder) |
|
|
435
|
+
| `position` | string | No | `"prepend"`, `"append"`, `"before"`, `"after"` |
|
|
436
|
+
| `anchorId` | string | No | Reference item for before/after positioning |
|
|
437
|
+
|
|
438
|
+
**Add items:**
|
|
439
|
+
|
|
440
|
+
```json
|
|
441
|
+
{
|
|
442
|
+
"kind": "update_faq",
|
|
443
|
+
"operation": "add",
|
|
444
|
+
"position": "append",
|
|
445
|
+
"items": [
|
|
446
|
+
{
|
|
447
|
+
"kind": "faq:question",
|
|
448
|
+
"config": {
|
|
449
|
+
"id": "new-feature",
|
|
450
|
+
"question": "What is the new feature?",
|
|
451
|
+
"answer": "Our latest release includes AI-powered recommendations."
|
|
452
|
+
}
|
|
453
|
+
}
|
|
454
|
+
]
|
|
455
|
+
}
|
|
456
|
+
```
|
|
457
|
+
|
|
458
|
+
**Remove an item:**
|
|
459
|
+
|
|
460
|
+
```json
|
|
461
|
+
{
|
|
462
|
+
"kind": "update_faq",
|
|
463
|
+
"operation": "remove",
|
|
464
|
+
"itemId": "outdated-question"
|
|
465
|
+
}
|
|
466
|
+
```
|
|
467
|
+
|
|
468
|
+
**Reorder items:**
|
|
469
|
+
|
|
470
|
+
```json
|
|
471
|
+
{
|
|
472
|
+
"kind": "update_faq",
|
|
473
|
+
"operation": "reorder",
|
|
474
|
+
"order": ["getting-started", "new-feature", "payment-methods"]
|
|
475
|
+
}
|
|
476
|
+
```
|
|
477
|
+
|
|
478
|
+
**Replace all items:**
|
|
479
|
+
|
|
480
|
+
```json
|
|
481
|
+
{
|
|
482
|
+
"kind": "update_faq",
|
|
483
|
+
"operation": "replace",
|
|
484
|
+
"items": [
|
|
485
|
+
{
|
|
486
|
+
"kind": "faq:question",
|
|
487
|
+
"config": {
|
|
488
|
+
"id": "only-question",
|
|
489
|
+
"question": "Is this the only question?",
|
|
490
|
+
"answer": "Yes, after replacing all items."
|
|
491
|
+
}
|
|
492
|
+
}
|
|
493
|
+
]
|
|
494
|
+
}
|
|
495
|
+
```
|
|
496
|
+
|
|
349
497
|
## Compositional Pattern
|
|
350
498
|
|
|
351
|
-
The FAQ widget
|
|
499
|
+
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:
|
|
352
500
|
|
|
353
|
-
-
|
|
354
|
-
-
|
|
355
|
-
-
|
|
356
|
-
-
|
|
501
|
+
- **Per-item conditional visibility** via `showWhen` strategies -- items can appear or hide based on page URL, user segment, viewport, or any DecisionStrategy condition
|
|
502
|
+
- **Category grouping** -- items with a `category` field are grouped under collapsible section headers
|
|
503
|
+
- **Dynamic injection** -- `injections` rules can add items when trigger conditions are met, supporting contextual FAQ content
|
|
504
|
+
- **Ordering control** -- the `ordering` strategy determines how items are sorted within categories
|
|
357
505
|
|
|
358
|
-
Items without `showWhen` are always visible.
|
|
506
|
+
Items without `showWhen` are always visible. Items without `category` appear in an ungrouped section.
|
|
507
|
+
|
|
508
|
+
## Rich Answer Content
|
|
509
|
+
|
|
510
|
+
FAQ answers support three content formats via the `FAQAnswer` union type:
|
|
511
|
+
|
|
512
|
+
- **Plain string** -- simple text, supports basic markdown
|
|
513
|
+
- **Rich HTML** (`{ "type": "rich", "html": "<p>...</p>" }`) -- pre-rendered HTML content
|
|
514
|
+
- **Enhanced markdown** (`{ "type": "markdown", "content": "...", "assets": [...] }`) -- markdown with embedded media assets (images, videos)
|
|
515
|
+
|
|
516
|
+
```json
|
|
517
|
+
{
|
|
518
|
+
"config": {
|
|
519
|
+
"id": "rich-example",
|
|
520
|
+
"question": "How does the visual editor work?",
|
|
521
|
+
"answer": {
|
|
522
|
+
"type": "markdown",
|
|
523
|
+
"content": "The visual editor lets you create experiments with a point-and-click interface.\n\n",
|
|
524
|
+
"assets": [
|
|
525
|
+
{
|
|
526
|
+
"id": "editor-screenshot",
|
|
527
|
+
"type": "image",
|
|
528
|
+
"src": "https://cdn.example.com/editor.png",
|
|
529
|
+
"alt": "Visual editor interface",
|
|
530
|
+
"width": 800,
|
|
531
|
+
"height": 450
|
|
532
|
+
}
|
|
533
|
+
]
|
|
534
|
+
}
|
|
535
|
+
}
|
|
536
|
+
}
|
|
537
|
+
```
|
|
538
|
+
|
|
539
|
+
## Feedback
|
|
540
|
+
|
|
541
|
+
Per-item feedback allows users to rate answer helpfulness. Enable with a boolean or detailed config:
|
|
542
|
+
|
|
543
|
+
- `"feedback": true` -- enables thumbs up/down with default prompt
|
|
544
|
+
- `"feedback": { "style": "thumbs", "prompt": "Was this helpful?" }` -- thumbs with custom prompt
|
|
545
|
+
- `"feedback": { "style": "rating" }` -- numeric rating scale
|
|
546
|
+
|
|
547
|
+
Feedback events are published via `context.publishEvent` for analytics integration.
|
|
548
|
+
|
|
549
|
+
## Personalization
|
|
550
|
+
|
|
551
|
+
### Ordering Strategies
|
|
552
|
+
|
|
553
|
+
The `ordering` field controls how FAQ items are sorted:
|
|
554
|
+
|
|
555
|
+
- **`"static"`** (default) -- items appear in the order defined in the config
|
|
556
|
+
- **`"priority"`** -- items are sorted by their `priority` field (higher values first)
|
|
557
|
+
- **Segment-based** -- items are ordered differently per user segment:
|
|
558
|
+
|
|
559
|
+
```json
|
|
560
|
+
{
|
|
561
|
+
"ordering": {
|
|
562
|
+
"type": "segment",
|
|
563
|
+
"segmentWeights": {
|
|
564
|
+
"new_user": ["getting-started", "pricing", "support"],
|
|
565
|
+
"power_user": ["api-docs", "advanced-config", "integrations"]
|
|
566
|
+
}
|
|
567
|
+
}
|
|
568
|
+
}
|
|
569
|
+
```
|
|
570
|
+
|
|
571
|
+
### Contextual Hints (Companion Tooltips)
|
|
572
|
+
|
|
573
|
+
FAQ questions can be surfaced proactively on the page using companion overlay tooltips. When a tooltip CTA has an `actionId` matching `faq:open:<questionId>`, clicking it expands the corresponding question in the FAQ widget and scrolls it into view.
|
|
574
|
+
|
|
575
|
+
This is a convention-based integration — no special FAQ action is needed. Use a standard `overlays:tooltip` action with `ctaButtons`:
|
|
576
|
+
|
|
577
|
+
```json
|
|
578
|
+
{
|
|
579
|
+
"kind": "overlays:tooltip",
|
|
580
|
+
"anchorId": "#complex-feature",
|
|
581
|
+
"content": {
|
|
582
|
+
"title": "Need help?",
|
|
583
|
+
"body": "Check our FAQ for details.",
|
|
584
|
+
"ctaButtons": [
|
|
585
|
+
{ "label": "View Answer", "actionId": "faq:open:getting-started", "primary": true },
|
|
586
|
+
{ "label": "Dismiss", "actionId": "dismiss" }
|
|
587
|
+
]
|
|
588
|
+
},
|
|
589
|
+
"trigger": "immediate",
|
|
590
|
+
"placement": "bottom"
|
|
591
|
+
}
|
|
592
|
+
```
|
|
593
|
+
|
|
594
|
+
**How it works:**
|
|
595
|
+
|
|
596
|
+
1. The tooltip CTA click publishes an `action.tooltip_cta_clicked` event via the EventBus
|
|
597
|
+
2. The FAQ widget subscribes to these events and filters for `faq:open:*` actionIds
|
|
598
|
+
3. The matching question expands and scrolls into view
|
|
599
|
+
4. The widget also publishes `canvas.requestOpen` to open the canvas panel if needed
|
|
600
|
+
|
|
601
|
+
**Late-mount support:** If the FAQ widget mounts after the CTA click (e.g., canvas was closed), it checks the EventBus history for recent `faq:open:*` events (within 10 seconds) and auto-expands the target question on mount.
|
|
602
|
+
|
|
603
|
+
**`dismiss` actionId:** Destroys the tooltip without publishing an event. Use this for a "close" or "not now" button.
|
|
604
|
+
|
|
605
|
+
### Dynamic Injection
|
|
606
|
+
|
|
607
|
+
Injection rules add contextual FAQ items when conditions are met:
|
|
608
|
+
|
|
609
|
+
```json
|
|
610
|
+
{
|
|
611
|
+
"injections": [
|
|
612
|
+
{
|
|
613
|
+
"trigger": {
|
|
614
|
+
"type": "rules",
|
|
615
|
+
"rules": [
|
|
616
|
+
{
|
|
617
|
+
"conditions": [{ "type": "page_url", "pattern": "/checkout*" }],
|
|
618
|
+
"value": true
|
|
619
|
+
}
|
|
620
|
+
],
|
|
621
|
+
"default": false
|
|
622
|
+
},
|
|
623
|
+
"items": [
|
|
624
|
+
{
|
|
625
|
+
"kind": "faq:question",
|
|
626
|
+
"config": {
|
|
627
|
+
"id": "checkout-help",
|
|
628
|
+
"question": "Having trouble with checkout?",
|
|
629
|
+
"answer": "Contact support at help@example.com for immediate assistance."
|
|
630
|
+
}
|
|
631
|
+
}
|
|
632
|
+
],
|
|
633
|
+
"position": "prepend",
|
|
634
|
+
"once": true
|
|
635
|
+
}
|
|
636
|
+
]
|
|
637
|
+
}
|
|
638
|
+
```
|
|
639
|
+
|
|
640
|
+
- `trigger` -- a DecisionStrategy that evaluates to `true` when injection should occur
|
|
641
|
+
- `items` -- FAQ items to inject
|
|
642
|
+
- `position` -- `"prepend"` or `"append"` relative to existing items
|
|
643
|
+
- `once` -- if `true`, items are injected only on the first trigger match
|
|
359
644
|
|
|
360
645
|
|
|
361
646
|
---
|
|
@@ -449,71 +734,81 @@ Mounts gamification UI elements.
|
|
|
449
734
|
|
|
450
735
|
# @syntrologie/adapt-nav
|
|
451
736
|
|
|
452
|
-
Navigation
|
|
737
|
+
Navigation tips accordion widget with conditional item visibility and toast notifications.
|
|
453
738
|
|
|
454
|
-
##
|
|
739
|
+
## Widget: `adaptive-nav:tips`
|
|
455
740
|
|
|
456
|
-
|
|
741
|
+
Accordion of contextual navigation tips. Each tip has a collapsible header and expanded body with optional CTA link.
|
|
457
742
|
|
|
458
|
-
|
|
743
|
+
### Tile Config
|
|
459
744
|
|
|
460
|
-
| Property
|
|
461
|
-
|
|
|
462
|
-
| `
|
|
463
|
-
| `
|
|
464
|
-
| `
|
|
465
|
-
| `
|
|
745
|
+
| Property | Type | Required | Default | Description |
|
|
746
|
+
| ------------------------ | -------------------------- | -------- | ---------- | ------------------------------- |
|
|
747
|
+
| `widget` | `"adaptive-nav:tips"` | Yes | | Widget identifier |
|
|
748
|
+
| `props.expandBehavior` | `"single"` \| `"multiple"` | No | `"single"` | Accordion expand mode |
|
|
749
|
+
| `props.theme` | `"light"` \| `"dark"` \| `"auto"` | No | `"auto"` | Color theme |
|
|
750
|
+
| `props.actions` | `NavTipAction[]` | Yes | | Navigation tip items |
|
|
466
751
|
|
|
467
|
-
### Nav
|
|
752
|
+
### Nav Tip Action (`nav:tip`)
|
|
468
753
|
|
|
469
|
-
|
|
754
|
+
Compositional action — rendered as an accordion item by the parent widget.
|
|
470
755
|
|
|
471
|
-
| Property
|
|
472
|
-
|
|
|
473
|
-
| `
|
|
474
|
-
| `
|
|
475
|
-
| `
|
|
476
|
-
| `
|
|
756
|
+
| Property | Type | Required | Description |
|
|
757
|
+
| ---------------------- | ---------------------------- | -------- | ------------------------------------ |
|
|
758
|
+
| `kind` | `"nav:tip"` | Yes | Action type |
|
|
759
|
+
| `config.id` | string | Yes | Unique tip identifier |
|
|
760
|
+
| `config.title` | string | Yes | Accordion header text |
|
|
761
|
+
| `config.description` | string | Yes | Expanded body text |
|
|
762
|
+
| `config.href` | string | No | Optional CTA link URL |
|
|
763
|
+
| `config.icon` | string | No | Icon (emoji or icon key) |
|
|
764
|
+
| `config.external` | boolean | No | Open link in new tab |
|
|
765
|
+
| `config.category` | string | No | Category for grouping |
|
|
766
|
+
| `showWhen` | `DecisionStrategy<boolean>` | No | Conditional visibility |
|
|
767
|
+
| `notify` | `{ title?, body?, icon? }` | No | Toast config for showWhen transition |
|
|
768
|
+
| `rationale` | `{ why, confidence? }` | No | AI reasoning for recommendation |
|
|
769
|
+
|
|
770
|
+
### Events Published
|
|
771
|
+
|
|
772
|
+
| Event | When | Props |
|
|
773
|
+
| ------------------ | ------------------------------------- | ------------------------------------ |
|
|
774
|
+
| `nav:toggled` | User expands/collapses a tip | `{ instanceId, tipId, expanded }` |
|
|
775
|
+
| `nav:tip_clicked` | User clicks a tip's CTA link | `{ instanceId, href, external }` |
|
|
776
|
+
| `nav:tip_revealed` | `showWhen` transitions false → true | `{ tipId, title, body, icon }` |
|
|
777
|
+
|
|
778
|
+
### Notify Watchers
|
|
779
|
+
|
|
780
|
+
Tips with both `showWhen` and `notify` are registered as notify watchers. The runtime evaluates these continuously (even when drawer is closed). When `showWhen` transitions false → true, publishes `nav:tip_revealed` which can trigger toast notifications via tile-level `notifications` rules.
|
|
477
781
|
|
|
478
782
|
```json
|
|
479
783
|
{
|
|
480
|
-
"
|
|
481
|
-
"
|
|
482
|
-
"
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
{
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
"showWhen": {
|
|
495
|
-
"type": "rules",
|
|
496
|
-
"rules": [
|
|
497
|
-
{
|
|
498
|
-
"conditions": [{ "type": "state_equals", "key": "user.role", "value": "admin" }],
|
|
499
|
-
"value": true
|
|
500
|
-
}
|
|
501
|
-
],
|
|
502
|
-
"default": false
|
|
503
|
-
}
|
|
504
|
-
},
|
|
784
|
+
"id": "nav",
|
|
785
|
+
"widget": "adaptive-nav:tips",
|
|
786
|
+
"notifications": [
|
|
787
|
+
{
|
|
788
|
+
"on": "nav:tip_revealed",
|
|
789
|
+
"title": "{{props.title}}",
|
|
790
|
+
"body": "{{props.body}}",
|
|
791
|
+
"icon": "🧭"
|
|
792
|
+
}
|
|
793
|
+
],
|
|
794
|
+
"props": {
|
|
795
|
+
"expandBehavior": "single",
|
|
796
|
+
"theme": "dark",
|
|
797
|
+
"actions": [
|
|
505
798
|
{
|
|
506
|
-
"
|
|
507
|
-
"
|
|
508
|
-
|
|
799
|
+
"kind": "nav:tip",
|
|
800
|
+
"config": {
|
|
801
|
+
"id": "tip-analytics",
|
|
802
|
+
"title": "Advanced Analytics",
|
|
803
|
+
"description": "Unlock deeper insights with our analytics suite.",
|
|
804
|
+
"href": "/analytics",
|
|
805
|
+
"icon": "📊",
|
|
806
|
+
"category": "Power User"
|
|
807
|
+
},
|
|
808
|
+
"notify": { "title": "New Tip", "body": "Advanced Analytics", "icon": "📊" },
|
|
509
809
|
"showWhen": {
|
|
510
810
|
"type": "rules",
|
|
511
|
-
"rules": [
|
|
512
|
-
{
|
|
513
|
-
"conditions": [{ "type": "state_equals", "key": "user.plan", "value": "free" }],
|
|
514
|
-
"value": true
|
|
515
|
-
}
|
|
516
|
-
],
|
|
811
|
+
"rules": [{ "conditions": [{ "type": "event_count", "key": "link-clicks", "operator": "gte", "count": 3 }], "value": true }],
|
|
517
812
|
"default": false
|
|
518
813
|
}
|
|
519
814
|
}
|
|
@@ -522,57 +817,28 @@ Each item in the `items` array:
|
|
|
522
817
|
}
|
|
523
818
|
```
|
|
524
819
|
|
|
525
|
-
## Compositional Pattern
|
|
526
|
-
|
|
527
|
-
The nav widget supports **per-item conditional visibility** using `showWhen` strategies. This allows different navigation items to appear based on:
|
|
528
|
-
|
|
529
|
-
- User role or permissions
|
|
530
|
-
- Subscription tier
|
|
531
|
-
- Feature flags
|
|
532
|
-
- Any other DecisionStrategy condition
|
|
533
|
-
|
|
534
|
-
Items without `showWhen` are always visible.
|
|
535
|
-
|
|
536
820
|
## Navigation Actions
|
|
537
821
|
|
|
538
|
-
###
|
|
822
|
+
### `navigation:scrollTo`
|
|
539
823
|
|
|
540
824
|
Scrolls the viewport to bring an element into view.
|
|
541
825
|
|
|
542
826
|
| Property | Type | Required | Default | Description |
|
|
543
827
|
| ---------- | ------------- | -------- | ----------- | ------------------------------------------- |
|
|
544
|
-
| `kind` | `"
|
|
828
|
+
| `kind` | `"navigation:scrollTo"` | Yes | | Action type |
|
|
545
829
|
| `anchorId` | string | Yes | | Element selector |
|
|
546
830
|
| `behavior` | string | No | `"smooth"` | `"smooth"`, `"instant"`, `"auto"` |
|
|
547
831
|
| `block` | string | No | `"center"` | `"start"`, `"center"`, `"end"`, `"nearest"` |
|
|
548
|
-
| `inline` | string | No | `"nearest"` | `"start"`, `"center"`, `"end"`, `"nearest"` |
|
|
549
|
-
|
|
550
|
-
```json
|
|
551
|
-
{
|
|
552
|
-
"kind": "scroll_to",
|
|
553
|
-
"anchorId": "#pricing-section",
|
|
554
|
-
"behavior": "smooth",
|
|
555
|
-
"block": "start"
|
|
556
|
-
}
|
|
557
|
-
```
|
|
558
832
|
|
|
559
|
-
### navigate
|
|
833
|
+
### `navigation:navigate`
|
|
560
834
|
|
|
561
835
|
Navigates to a URL.
|
|
562
836
|
|
|
563
|
-
| Property | Type
|
|
564
|
-
| -------- |
|
|
565
|
-
| `kind` | `"navigate"` | Yes
|
|
566
|
-
| `url` | string
|
|
567
|
-
| `target` | string
|
|
568
|
-
|
|
569
|
-
```json
|
|
570
|
-
{
|
|
571
|
-
"kind": "navigate",
|
|
572
|
-
"url": "/signup?ref=banner",
|
|
573
|
-
"target": "_self"
|
|
574
|
-
}
|
|
575
|
-
```
|
|
837
|
+
| Property | Type | Required | Default | Description |
|
|
838
|
+
| -------- | ----------------------- | -------- | --------- | ----------------------- |
|
|
839
|
+
| `kind` | `"navigation:navigate"` | Yes | | Action type |
|
|
840
|
+
| `url` | string | Yes | | Destination URL |
|
|
841
|
+
| `target` | string | No | `"_self"` | `"_self"` or `"_blank"` |
|
|
576
842
|
|
|
577
843
|
**Note:** `javascript:` URLs are blocked for security.
|
|
578
844
|
|
|
@@ -619,13 +885,16 @@ Shows a tooltip near an element with optional title, body, and CTA.
|
|
|
619
885
|
| `anchorId` | string | Yes | | Element selector |
|
|
620
886
|
| `content.title` | string | No | | Tooltip heading |
|
|
621
887
|
| `content.body` | string | Yes | | Tooltip text |
|
|
622
|
-
| `content.cta.label` | string | No | | CTA button text
|
|
623
|
-
| `content.cta.action` | Action | No | | Action to execute on CTA click
|
|
624
|
-
| `
|
|
625
|
-
| `
|
|
888
|
+
| `content.cta.label` | string | No | | CTA button text (single-CTA shorthand) |
|
|
889
|
+
| `content.cta.action` | Action | No | | Action to execute on CTA click |
|
|
890
|
+
| `content.ctaButtons` | array | No | | Multiple CTA buttons (see below) |
|
|
891
|
+
| `trigger` | string | No | `"immediate"` | `"immediate"`, `"hover"`, `"click"` |
|
|
892
|
+
| `placement` | string | No | `"top"` | See placement options below |
|
|
626
893
|
|
|
627
894
|
**Placement options:** `top`, `top-start`, `top-end`, `bottom`, `bottom-start`, `bottom-end`, `left`, `left-start`, `left-end`, `right`, `right-start`, `right-end`
|
|
628
895
|
|
|
896
|
+
**Single CTA (shorthand):**
|
|
897
|
+
|
|
629
898
|
```json
|
|
630
899
|
{
|
|
631
900
|
"kind": "tooltip",
|
|
@@ -643,6 +912,37 @@ Shows a tooltip near an element with optional title, body, and CTA.
|
|
|
643
912
|
}
|
|
644
913
|
```
|
|
645
914
|
|
|
915
|
+
**Multiple CTAs (`ctaButtons`):**
|
|
916
|
+
|
|
917
|
+
Use `ctaButtons` for tooltips with multiple actions. Each button has:
|
|
918
|
+
|
|
919
|
+
- `label`: Button text
|
|
920
|
+
- `actionId`: Identifier published with the `action.tooltip_cta_clicked` event
|
|
921
|
+
- `primary`: Whether this is a primary button (default: false)
|
|
922
|
+
|
|
923
|
+
```json
|
|
924
|
+
{
|
|
925
|
+
"kind": "overlays:tooltip",
|
|
926
|
+
"anchorId": "[data-nav=\"features\"]",
|
|
927
|
+
"content": {
|
|
928
|
+
"title": "Learn About Features",
|
|
929
|
+
"body": "We have answers about our feature set.",
|
|
930
|
+
"ctaButtons": [
|
|
931
|
+
{ "label": "View Answer", "actionId": "faq:open:q-features", "primary": true },
|
|
932
|
+
{ "label": "Dismiss", "actionId": "dismiss" }
|
|
933
|
+
]
|
|
934
|
+
},
|
|
935
|
+
"trigger": "immediate",
|
|
936
|
+
"placement": "bottom"
|
|
937
|
+
}
|
|
938
|
+
```
|
|
939
|
+
|
|
940
|
+
**Special actionId values:**
|
|
941
|
+
|
|
942
|
+
- `"dismiss"` — Destroys the tooltip immediately without publishing an event
|
|
943
|
+
- `"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.
|
|
944
|
+
- Any other value — Publishes `action.tooltip_cta_clicked` with the `actionId` in event props for custom handling
|
|
945
|
+
|
|
646
946
|
### badge
|
|
647
947
|
|
|
648
948
|
Adds a small badge indicator near an element.
|
package/dist/SmartCanvasApp.d.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { ReactNode } from 'react';
|
|
2
|
-
import { MountableComponent } from './api';
|
|
3
2
|
import { CanvasTheme } from './components/ShadowCanvasOverlay';
|
|
4
3
|
import { SmartCanvasController } from './controller';
|
|
5
4
|
import type { ExperimentClient } from './experiments/types';
|
|
@@ -29,7 +28,6 @@ export interface SmartCanvasAppProps {
|
|
|
29
28
|
footerSlot?: ReactNode;
|
|
30
29
|
launcherLabel?: string;
|
|
31
30
|
canvasHost?: HTMLElement | null;
|
|
32
|
-
customRenderers?: Record<string, MountableComponent>;
|
|
33
31
|
theme?: Partial<CanvasTheme>;
|
|
34
32
|
}
|
|
35
|
-
export declare function SmartCanvasApp({ controller, fetcher, configUri, configUriFeatureKey, configFeatureKey, fetchCredentials, pollIntervalMs, experiments, telemetry, runtime, overlayFetcher, overlayConfigUri, overlayConfigFeatureKey, overlayFetchCredentials, footerSlot, launcherLabel, canvasHost,
|
|
33
|
+
export declare function SmartCanvasApp({ controller, fetcher, configUri, configUriFeatureKey, configFeatureKey, fetchCredentials, pollIntervalMs, experiments, telemetry, runtime, overlayFetcher, overlayConfigUri, overlayConfigFeatureKey, overlayFetchCredentials, footerSlot, launcherLabel, canvasHost, theme, }: SmartCanvasAppProps): import("react/jsx-runtime").JSX.Element;
|