@moveo-ai/web-client 0.113.0-true.8 → 0.113.0-true.9

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/README.md CHANGED
@@ -230,6 +230,8 @@ a message — never carries the text), `launcher_clicked`,
230
230
  `teaser_quick_reply_clicked` (a teaser reply the visitor tapped, carrying its
231
231
  configured `label`), `teaser_composer_submitted` (the visitor sent their own
232
232
  line from the teaser — carries no properties, because the text is theirs),
233
+ `section_not_found` (a `teaser.pages[].sections[]` entry whose strongest
234
+ selector no longer matches the page — see "A different teaser per section"),
233
235
  `rating_submitted`, and the rest of the `AnalyticsEvent` enum in
234
236
  `src/hooks/useAnalytics.ts`.
235
237
 
@@ -422,6 +424,93 @@ the new URL, and the teaser re-resolves. An integration that configures no
422
424
  `pages[]` is not watched at all, because the watcher patches `history` and never
423
425
  restores it.
424
426
 
427
+ #### A different teaser per section of a page
428
+
429
+ On a long page one teaser is one teaser for fourteen blocks. `sections[]`, nested
430
+ in a `pages[]` entry, gives each part of the page its own, and the teaser
431
+ follows what the visitor is reading.
432
+
433
+ ```javascript
434
+ MoveoAI.init({
435
+ integrationId: 'YOUR_INTEGRATION_ID',
436
+ teaser: {
437
+ quick_replies: ['Compare products', 'Help me choose'],
438
+ pages: [
439
+ {
440
+ url: '/shop',
441
+ id: 'shop',
442
+ quick_replies: ['Which Clover system fits my business?'],
443
+ sections: [
444
+ {
445
+ id: 'station_duo',
446
+ match: [
447
+ '[data-entry-id="3UlHnDQQTGvNwHKQnXgVTz"]',
448
+ 'article > section:nth-of-type(6)',
449
+ ],
450
+ quick_replies: [
451
+ 'Is Station Duo worth $1,899?',
452
+ 'Station Duo or Flex?',
453
+ ],
454
+ },
455
+ {
456
+ id: 'go',
457
+ match: ['[data-entry-id="5oA3X1sZOG6FGGUrk39jiR"]'],
458
+ quick_replies: ['Does Go work without a counter?'],
459
+ },
460
+ { id: 'legal', match: ['#legal'], variant: 'none' },
461
+ ],
462
+ },
463
+ ],
464
+ },
465
+ });
466
+ ```
467
+
468
+ **Resolution is section → page → block.** The section in view wins; no section
469
+ in view falls back to the page's teaser; no page match falls back to the block.
470
+ A section set to `variant: 'none'` goes quiet and does **not** fall back — it is
471
+ an instruction, not an absence.
472
+
473
+ **`match` is an ordered list of CSS selectors, strongest first**, and nothing
474
+ else: the loader runs `querySelector` on each until one matches, and observes
475
+ that element. A selector matching several elements resolves to the first in
476
+ document order. Put a stable `id` or a CMS data attribute first and a positional
477
+ selector like `article > section:nth-of-type(6)` last, so a section survives
478
+ losing its best anchor. Hashed CSS-module class names change on every deploy;
479
+ never use one.
480
+
481
+ **`id` is authored, not derived from position.** It names the section in
482
+ analytics, so an index that shifted whenever someone reordered the list would
483
+ break the history. Unlike `pages[]`, the order of `sections[]` decides nothing:
484
+ sections are chosen at runtime by what is on screen.
485
+
486
+ **The section with the largest visible share of the viewport wins**, not the
487
+ one with the largest visible ratio of itself — a 992px section 40% in view
488
+ fills more screen than a 373px one fully in view. A tie keeps the current
489
+ section, so a slow scroll cannot flap between two sets of chips, and a section
490
+ must hold the viewport for a moment before the teaser follows it, so one flick
491
+ of the wheel does not fire three swaps. The swap lands while the teaser is out
492
+ of the way for the scroll, and the new chips are what fades back in.
493
+
494
+ **`show_after` gates the first show only.** A later swap never waits — a visitor
495
+ scanning a long page would otherwise restart the delay at every block and see
496
+ nothing. **A new section re-arms a teaser that `hide_after` retired**, with a
497
+ fresh budget. **A teaser the visitor closed stays closed** for the visit,
498
+ whatever section they reach.
499
+
500
+ **Sections belong to their page.** A single-page-app navigation rebuilds the
501
+ watch against the new page's sections, and clears the current section so
502
+ nothing from the previous page survives the transition. A page with no
503
+ `sections[]`, or an empty list, is not observed at all, and an integration
504
+ with no sections anywhere registers no observer.
505
+
506
+ **When a selector stops matching**, the widget emits the `section_not_found`
507
+ analytics event once per section per page view, carrying `section_id`,
508
+ `page_id`, `page_url`, `matched_index` and `selector_count`. It fires whenever
509
+ the strongest selector no longer holds: `matched_index` names the fallback that
510
+ still does, so the section can be regenerated before it breaks, and is `null`
511
+ once nothing matches. A section with no match is simply left out of the
512
+ running; the page teaser covers it.
513
+
425
514
  **Chips replace the line, they do not sit under it.** Asking the question and
426
515
  offering the answers says the same thing twice, and a bubble above
427
516
  content-width chips leaves a ragged edge.
@@ -659,14 +748,14 @@ icon and the launcher, and `--color-chat-background` follows the background.
659
748
  Six more colours have no `theme_colors` key, so they are set through
660
749
  `setCSSVariables()` only:
661
750
 
662
- | Variable | Controls |
663
- | ------------------------------------ | ------------------------------------------------------------------- |
664
- | `--color-chat-background` | The area behind the messages; follows the background |
665
- | `--color-options-background` | Quick reply buttons, and the teaser chips and composer field |
666
- | `--color-options-foreground` | Quick reply labels, the teaser composer text, and a chip under the pointer or the focus ring; defaults to the accent |
751
+ | Variable | Controls |
752
+ | ------------------------------------ | ---------------------------------------------------------------------------------------------------------------------- |
753
+ | `--color-chat-background` | The area behind the messages; follows the background |
754
+ | `--color-options-background` | Quick reply buttons, and the teaser chips and composer field |
755
+ | `--color-options-foreground` | Quick reply labels, the teaser composer text, and a chip under the pointer or the focus ring; defaults to the accent |
667
756
  | `--color-options-border` | Quick reply borders, the teaser composer field, and a chip under the pointer or the focus ring; defaults to the accent |
668
- | `--color-opening-message-background` | The teaser bubble, on `callout` and `composer`; defaults to the accent |
669
- | `--color-opening-message-foreground` | The teaser bubble text; defaults to the visitor's own bubble text colour |
757
+ | `--color-opening-message-background` | The teaser bubble, on `callout` and `composer`; defaults to the accent |
758
+ | `--color-opening-message-foreground` | The teaser bubble text; defaults to the visitor's own bubble text colour |
670
759
 
671
760
  The two `opening-message` names are the teaser's, from before it was called
672
761
  one. They are the only lever that moves the bubble off the accent, so an
@@ -1,6 +1,6 @@
1
1
  /*!
2
2
  *
3
- * @moveo-ai/web-client v0.113.0-true.8
3
+ * @moveo-ai/web-client v0.113.0-true.9
4
4
  * Copyright (c) Moveo.ai (TM)
5
5
  *
6
6
  */
@@ -1,6 +1,6 @@
1
1
  /*!
2
2
  *
3
- * @moveo-ai/web-client v0.113.0-true.8
3
+ * @moveo-ai/web-client v0.113.0-true.9
4
4
  * Copyright (c) Moveo.ai (TM)
5
5
  *
6
6
  */
@@ -1,6 +1,6 @@
1
1
  /*!
2
2
  *
3
- * @moveo-ai/web-client v0.113.0-true.8
3
+ * @moveo-ai/web-client v0.113.0-true.9
4
4
  * Copyright (c) Moveo.ai (TM)
5
5
  *
6
6
  */
@@ -1,6 +1,6 @@
1
1
  /*!
2
2
  *
3
- * @moveo-ai/web-client v0.113.0-true.8
3
+ * @moveo-ai/web-client v0.113.0-true.9
4
4
  * Copyright (c) Moveo.ai (TM)
5
5
  *
6
6
  */
@@ -1,6 +1,6 @@
1
1
  /*!
2
2
  *
3
- * @moveo-ai/web-client v0.113.0-true.8
3
+ * @moveo-ai/web-client v0.113.0-true.9
4
4
  * Copyright (c) Moveo.ai (TM)
5
5
  *
6
6
  */