@leadbot/components 2.21.1 → 2.24.1

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.
Files changed (56) hide show
  1. package/README.md +50 -3
  2. package/dist/agentChat-8s9g6Np1.js +379 -0
  3. package/dist/agentChat-DWRE_Le4.cjs +1 -0
  4. package/dist/agentChat.d.ts +2 -0
  5. package/dist/agentChat.d.ts.map +1 -1
  6. package/dist/buttons-ecViBEJ9.js +85 -0
  7. package/dist/buttons-rml8Kh8z.cjs +1 -0
  8. package/dist/buttons.cjs +1 -0
  9. package/dist/buttons.js +3 -0
  10. package/dist/chat.cjs +1 -0
  11. package/dist/chat.js +3 -0
  12. package/dist/entries/_shared.d.ts +5 -0
  13. package/dist/entries/_shared.d.ts.map +1 -0
  14. package/dist/entries/buttons.d.ts +3 -0
  15. package/dist/entries/buttons.d.ts.map +1 -0
  16. package/dist/entries/chat.d.ts +3 -0
  17. package/dist/entries/chat.d.ts.map +1 -0
  18. package/dist/entries/flow.d.ts +3 -0
  19. package/dist/entries/flow.d.ts.map +1 -0
  20. package/dist/entries/form.d.ts +3 -0
  21. package/dist/entries/form.d.ts.map +1 -0
  22. package/dist/entries/whatsapp.d.ts +3 -0
  23. package/dist/entries/whatsapp.d.ts.map +1 -0
  24. package/dist/flow-BZED8XTR.js +5047 -0
  25. package/dist/flow-BpPqOZAo.cjs +82 -0
  26. package/dist/flow.cjs +1 -0
  27. package/dist/flow.d.ts.map +1 -1
  28. package/dist/flow.js +3 -0
  29. package/dist/form-Dc8AaZBV.cjs +1 -0
  30. package/dist/form-Df53ALbk.js +290 -0
  31. package/dist/form.cjs +1 -0
  32. package/dist/form.d.ts +1 -0
  33. package/dist/form.d.ts.map +1 -1
  34. package/dist/form.js +3 -0
  35. package/dist/i18n-DyDsn-Fk.js +93 -0
  36. package/dist/i18n-gV6rxSod.cjs +1 -0
  37. package/dist/i18n.d.ts +25 -0
  38. package/dist/i18n.d.ts.map +1 -0
  39. package/dist/index.cjs +1 -0
  40. package/dist/index.d.ts +1 -0
  41. package/dist/index.d.ts.map +1 -1
  42. package/dist/index.js +9 -6779
  43. package/dist/jsxRuntime.module-CT7yzySL.cjs +1 -0
  44. package/dist/jsxRuntime.module-DsRxbn3o.js +657 -0
  45. package/dist/mount.d.ts +38 -2
  46. package/dist/mount.d.ts.map +1 -1
  47. package/dist/styles.css +93 -4
  48. package/dist/useStep.d.ts +47 -1
  49. package/dist/useStep.d.ts.map +1 -1
  50. package/dist/whatsapp-B3GO1RDT.cjs +1 -0
  51. package/dist/whatsapp-DGnyaume.js +128 -0
  52. package/dist/whatsapp.cjs +1 -0
  53. package/dist/whatsapp.d.ts +1 -0
  54. package/dist/whatsapp.d.ts.map +1 -1
  55. package/dist/whatsapp.js +3 -0
  56. package/package.json +39 -11
package/dist/mount.d.ts CHANGED
@@ -2,7 +2,11 @@ import { type ComponentType } from "preact";
2
2
  import { type LeadbotClient } from "@leadbot/core";
3
3
  export interface LeadbotComponentsConfig {
4
4
  domainKey?: string;
5
- /** API server origin, e.g. "https://collector.example.com" — "/api" is appended. */
5
+ /**
6
+ * API server origin, e.g. "https://collector.example.com" — "/api" is
7
+ * appended. Optional: the build bakes the collector origin in, so only
8
+ * preview/staging overrides need to pass it.
9
+ */
6
10
  apiHost?: string;
7
11
  /** Id of the component leadbot these components belong to (dashboard → Settings → Components). */
8
12
  leadbotId?: number;
@@ -21,7 +25,11 @@ export interface LeadbotComponentsConfig {
21
25
  * to anyone reading the shipped JS.
22
26
  */
23
27
  previewToken?: string;
24
- /** Base/primary color for buttons etc. — sets --leadbot-primary on the mount. */
28
+ /**
29
+ * Base/primary color for buttons etc. — sets --leadbot-primary on the
30
+ * mount. Optional: the colour configured in the dashboard arrives with the
31
+ * boot fetch and is used by default; this prop overrides it.
32
+ */
25
33
  baseColor?: string;
26
34
  /**
27
35
  * Test/preview mode. Submissions and chat turns run end-to-end (AI still
@@ -29,6 +37,12 @@ export interface LeadbotComponentsConfig {
29
37
  * the dashboard preview so test interactions never create real leads.
30
38
  */
31
39
  preview?: boolean;
40
+ /**
41
+ * Render a visible placeholder instead of nothing when an `id` resolves to
42
+ * no published step. On by default on localhost and in the dashboard
43
+ * preview; set it to force the placeholder on (or off) elsewhere.
44
+ */
45
+ debug?: boolean;
32
46
  }
33
47
  /**
34
48
  * Set module-level defaults; every mount accepts the same keys as overrides.
@@ -40,9 +54,31 @@ export interface LeadbotComponentsConfig {
40
54
  * fire. Pass the leadbot id to get the same tracking as the classic widget.
41
55
  */
42
56
  export declare function init(config: LeadbotComponentsConfig): void;
57
+ /**
58
+ * What the boot fetch answered about the bot itself: the language its copy is
59
+ * written in and the colour configured in the dashboard. Mounts read these as
60
+ * defaults, so a Dutch bot on a `lang="en"` page speaks Dutch and a snippet
61
+ * that passes no `baseColor` still renders in the bot's colour.
62
+ *
63
+ * Only ever set from a flow response, so a mount that never loads a flow (an
64
+ * explicit `fields` list, no `id`) costs no extra request.
65
+ */
66
+ export interface FlowSnapshot {
67
+ language?: string;
68
+ baseColor?: string;
69
+ }
70
+ export declare function getFlowSnapshot(leadbotId?: number): FlowSnapshot;
71
+ /** Re-render on the next flow response; returns the unsubscribe. */
72
+ export declare function subscribeFlowSnapshot(listener: () => void): () => void;
43
73
  /** Merge the `init()` defaults under explicitly-set option keys. */
44
74
  export declare function withDefaults(options: LeadbotComponentsConfig): LeadbotComponentsConfig;
45
75
  export declare function resolveClient(options: LeadbotComponentsConfig): LeadbotClient;
76
+ /**
77
+ * Whether this mount's own boot fetch was refused with a 403 — a broken
78
+ * install rather than an unpublished bot. Only meaningful once that fetch has
79
+ * resolved.
80
+ */
81
+ export declare function wasFlowForbidden(options: LeadbotComponentsConfig): boolean;
46
82
  /**
47
83
  * Boot fetch of the published flow: delivers the steps and bills the pageview.
48
84
  * Bumps the generation, so a response for a route the caller has already left
@@ -1 +1 @@
1
- {"version":3,"file":"mount.d.ts","sourceRoot":"","sources":["../src/mount.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,aAAa,EAAa,MAAM,QAAQ,CAAC;AACvD,OAAO,EAKN,KAAK,aAAa,EAIlB,MAAM,eAAe,CAAC;AAEvB,MAAM,WAAW,uBAAuB;IACvC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,oFAAoF;IACpF,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,kGAAkG;IAClG,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;;OAIG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,oFAAoF;IACpF,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;;;OAKG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,iFAAiF;IACjF,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;;OAIG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;CAClB;AAKD;;;;;;;;GAQG;AACH,wBAAgB,IAAI,CAAC,MAAM,EAAE,uBAAuB,GAAG,IAAI,CA2B1D;AAID,oEAAoE;AACpE,wBAAgB,YAAY,CAC3B,OAAO,EAAE,uBAAuB,GAC9B,uBAAuB,CAMzB;AAED,wBAAgB,aAAa,CAAC,OAAO,EAAE,uBAAuB,GAAG,aAAa,CAK7E;AA2BD;;;;GAIG;AACH,wBAAgB,QAAQ,CAAC,OAAO,EAAE,uBAAuB,yDAExD;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAC7B,OAAO,EAAE,uBAAuB,GAC9B,IAAI,CAAC,uBAAuB,EAAE,SAAS,GAAG,cAAc,CAAC,CAQ3D;AAED,MAAM,WAAW,gBAAiB,SAAQ,uBAAuB;IAChE,wDAAwD;IACxD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;;OAIG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;CACjB;AAED,MAAM,WAAW,WAAW,CAAC,CAAC;IAC7B,MAAM,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC;IAClC,OAAO,IAAI,IAAI,CAAC;CAChB;AAED,oFAAoF;AACpF,eAAO,MAAM,UAAU,uBAAuB,CAAC;AAE/C,2EAA2E;AAC3E,eAAO,MAAM,UAAU,iBAAiB,CAAC;AAMzC;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,CAAC,SAAS,gBAAgB,EACrD,SAAS,EAAE,aAAa,CAAC,CAAC,CAAC,EAC3B,EAAE,EAAE,WAAW,EACf,OAAO,EAAE,CAAC,GACR,WAAW,CAAC,CAAC,CAAC,CA+BhB;AAED;;;GAGG;AACH,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC"}
1
+ {"version":3,"file":"mount.d.ts","sourceRoot":"","sources":["../src/mount.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,aAAa,EAAa,MAAM,QAAQ,CAAC;AACvD,OAAO,EAON,KAAK,aAAa,EAIlB,MAAM,eAAe,CAAC;AAEvB,MAAM,WAAW,uBAAuB;IACvC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;;OAIG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,kGAAkG;IAClG,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;;OAIG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,oFAAoF;IACpF,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;;;OAKG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;;;;OAIG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;;OAIG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB;;;;OAIG;IACH,KAAK,CAAC,EAAE,OAAO,CAAC;CAChB;AAaD;;;;;;;;GAQG;AACH,wBAAgB,IAAI,CAAC,MAAM,EAAE,uBAAuB,GAAG,IAAI,CA8B1D;AAID;;;;;;;;GAQG;AACH,MAAM,WAAW,YAAY;IAC5B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;CACnB;AAkBD,wBAAgB,eAAe,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,YAAY,CAEhE;AAED,oEAAoE;AACpE,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,MAAM,IAAI,GAAG,MAAM,IAAI,CAKtE;AAsBD,oEAAoE;AACpE,wBAAgB,YAAY,CAC3B,OAAO,EAAE,uBAAuB,GAC9B,uBAAuB,CAMzB;AAED,wBAAgB,aAAa,CAAC,OAAO,EAAE,uBAAuB,GAAG,aAAa,CAK7E;AAqBD;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,uBAAuB,GAAG,OAAO,CAG1E;AA8BD;;;;GAIG;AACH,wBAAgB,QAAQ,CAAC,OAAO,EAAE,uBAAuB,yDAExD;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAC7B,OAAO,EAAE,uBAAuB,GAC9B,IAAI,CAAC,uBAAuB,EAAE,SAAS,GAAG,cAAc,CAAC,CAQ3D;AAED,MAAM,WAAW,gBAAiB,SAAQ,uBAAuB;IAChE,wDAAwD;IACxD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;;OAIG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;CACjB;AAED,MAAM,WAAW,WAAW,CAAC,CAAC;IAC7B,MAAM,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC;IAClC,OAAO,IAAI,IAAI,CAAC;CAChB;AAED,oFAAoF;AACpF,eAAO,MAAM,UAAU,uBAAuB,CAAC;AAE/C,2EAA2E;AAC3E,eAAO,MAAM,UAAU,iBAAiB,CAAC;AAMzC;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,CAAC,SAAS,gBAAgB,EACrD,SAAS,EAAE,aAAa,CAAC,CAAC,CAAC,EAC3B,EAAE,EAAE,WAAW,EACf,OAAO,EAAE,CAAC,GACR,WAAW,CAAC,CAAC,CAAC,CAqChB;AAED;;;GAGG;AACH,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC"}
package/dist/styles.css CHANGED
@@ -18,6 +18,9 @@
18
18
  built around 320px; an embedded flow (@leadbot/components) can widen or
19
19
  narrow the whole conversation by overriding this one token. */
20
20
  --leadbot-flow-max-width: 320px;
21
+ /* Chat panel height. Fixed by design: the panel must not grow or shrink with
22
+ message count or starter count. Clamped by the viewport at render time. */
23
+ --leadbot-chat-height: 520px;
21
24
  /* Border radius */
22
25
  --leadbot-radius-sm: 6px;
23
26
  --leadbot-radius-md: 8px;
@@ -523,7 +526,7 @@
523
526
  border-radius: var(--leadbot-radius-card);
524
527
  box-shadow: 0 4px 24px rgba(0, 0, 0, 0.12), 0 0 0 1px rgba(0, 0, 0, 0.04);
525
528
  max-width: 360px;
526
- max-height: max(0px, var(--leadbot-available-height));
529
+ height: min(var(--leadbot-chat-height), max(0px, var(--leadbot-available-height)));
527
530
  min-width: 360px;
528
531
  min-height: 0;
529
532
  overflow: hidden;
@@ -603,7 +606,9 @@
603
606
  display: flex;
604
607
  flex-direction: column;
605
608
  gap: 10px;
606
- flex: 1 1 360px;
609
+ /* Fills whatever the fixed-height panel leaves over; never sets the panel's
610
+ own height, so starters appearing or unmounting can't resize the card. */
611
+ flex: 1 1 auto;
607
612
  }
608
613
  .leadbot-components {
609
614
  /* ---- Message bubbles ---- */
@@ -641,7 +646,12 @@
641
646
  justify-content: flex-end;
642
647
  gap: 6px;
643
648
  padding: 4px 16px 8px;
644
- flex-shrink: 0;
649
+ /* The starters are the only footer row that may give up space: on a short
650
+ viewport (landscape phone) the panel can't fit header + starters + composer,
651
+ and a clipped composer would make the chat unusable. They scroll instead. */
652
+ flex-shrink: 1;
653
+ min-height: 0;
654
+ overflow-y: auto;
645
655
  }
646
656
  .leadbot-components .leadbot-chatbot-starter-btn {
647
657
  background: var(--leadbot-color-surface);
@@ -1498,6 +1508,10 @@
1498
1508
  .leadbot-components .leadbot-whatsapp-chat {
1499
1509
  padding: 16px;
1500
1510
  min-height: 80px;
1511
+ display: flex;
1512
+ flex-direction: column;
1513
+ gap: 8px;
1514
+ align-items: flex-start;
1501
1515
  background: linear-gradient(to bottom, var(--leadbot-whatsapp-wallpaper) 0%, var(--leadbot-whatsapp-wallpaper-end) 100%);
1502
1516
  }
1503
1517
  .leadbot-components .leadbot-whatsapp-message {
@@ -1507,18 +1521,74 @@
1507
1521
  max-width: 100%;
1508
1522
  position: relative;
1509
1523
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
1524
+ --leadbot-whatsapp-bubble-from: -24px;
1525
+ animation: leadbot-whatsapp-bubble-in 0.28s var(--leadbot-ease-appear) backwards;
1510
1526
  }
1511
1527
  .leadbot-components .leadbot-whatsapp-message::before {
1512
1528
  content: "";
1513
1529
  position: absolute;
1514
1530
  left: -8px;
1515
- top: 16px;
1531
+ top: 6px; /* ponytail: hugs the rounded corner and still fits short bubbles (typing dots) */
1516
1532
  width: 0;
1517
1533
  height: 0;
1518
1534
  border: 8px solid transparent;
1519
1535
  border-right-color: var(--leadbot-whatsapp-bubble);
1520
1536
  border-left: none;
1521
1537
  }
1538
+ .leadbot-components {
1539
+ /* Visitor's own message, echoed back while we ask for the phone number. */
1540
+ }
1541
+ .leadbot-components .leadbot-whatsapp-message-outgoing {
1542
+ align-self: flex-end;
1543
+ background: var(--leadbot-whatsapp-green);
1544
+ --leadbot-whatsapp-bubble-from: 24px;
1545
+ }
1546
+ .leadbot-components .leadbot-whatsapp-message-outgoing::before {
1547
+ left: auto;
1548
+ right: -8px;
1549
+ border-right: none;
1550
+ border-left: 8px solid var(--leadbot-whatsapp-green);
1551
+ }
1552
+ .leadbot-components .leadbot-whatsapp-message-outgoing .leadbot-whatsapp-message-content {
1553
+ color: var(--leadbot-whatsapp-on-green);
1554
+ }
1555
+ .leadbot-components {
1556
+ /* Bubbles slide in from their own side, the way WhatsApp lands a message;
1557
+ the side comes from --leadbot-whatsapp-bubble-from. */
1558
+ }
1559
+ @keyframes leadbot-whatsapp-bubble-in {
1560
+ from {
1561
+ opacity: 0;
1562
+ transform: translateX(var(--leadbot-whatsapp-bubble-from));
1563
+ }
1564
+ to {
1565
+ opacity: 1;
1566
+ transform: none;
1567
+ }
1568
+ }
1569
+ .leadbot-components {
1570
+ /* Reply-is-coming indicator, same bubble shape as a real message. */
1571
+ }
1572
+ .leadbot-components .leadbot-whatsapp-typing {
1573
+ padding: 12px;
1574
+ }
1575
+ .leadbot-components .leadbot-whatsapp-typing-dots {
1576
+ display: flex;
1577
+ gap: 4px;
1578
+ }
1579
+ .leadbot-components .leadbot-whatsapp-typing-dots span {
1580
+ width: 6px;
1581
+ height: 6px;
1582
+ border-radius: 50%;
1583
+ background: var(--leadbot-color-text-subtle);
1584
+ animation: leadbot-typing-bounce 1.4s infinite var(--leadbot-ease-loop);
1585
+ }
1586
+ .leadbot-components .leadbot-whatsapp-typing-dots span:nth-child(1) {
1587
+ animation-delay: -0.32s;
1588
+ }
1589
+ .leadbot-components .leadbot-whatsapp-typing-dots span:nth-child(2) {
1590
+ animation-delay: -0.16s;
1591
+ }
1522
1592
  .leadbot-components .leadbot-whatsapp-message-content {
1523
1593
  color: var(--leadbot-whatsapp-bubble-text);
1524
1594
  font-size: var(--leadbot-font-size);
@@ -1838,6 +1908,7 @@
1838
1908
  border: 0;
1839
1909
  border-radius: 0;
1840
1910
  box-shadow: none;
1911
+ height: auto;
1841
1912
  max-height: none;
1842
1913
  max-width: none;
1843
1914
  overflow: visible;
@@ -1895,6 +1966,24 @@
1895
1966
  background: color-mix(in srgb, var(--leadbot-primary) 8%, var(--leadbot-color-surface));
1896
1967
  border-color: var(--leadbot-primary);
1897
1968
  }
1969
+ .leadbot-step-stub {
1970
+ display: flex;
1971
+ flex-direction: column;
1972
+ gap: 4px;
1973
+ padding: 12px 14px;
1974
+ border: 1px dashed #d97706;
1975
+ border-radius: var(--leadbot-radius-md, 8px);
1976
+ background: #fffbeb;
1977
+ color: #7c2d12;
1978
+ font-family: inherit;
1979
+ font-size: var(--leadbot-font-size-sm);
1980
+ line-height: 1.4;
1981
+ }
1982
+ .leadbot-step-stub--quiet {
1983
+ border-color: var(--leadbot-color-border, #e5e7eb);
1984
+ background: transparent;
1985
+ color: var(--leadbot-color-text-muted, #6b7280);
1986
+ }
1898
1987
  @keyframes fadeSlide {
1899
1988
  from {
1900
1989
  opacity: 0;
package/dist/useStep.d.ts CHANGED
@@ -1,4 +1,5 @@
1
- import { type Step, type StepAttributes } from "@leadbot/core";
1
+ import { type VNode } from "preact";
2
+ import { type Lang, type Step, type StepAttributes } from "@leadbot/core";
2
3
  import { type LeadbotComponentsConfig } from "./mount";
3
4
  export interface StepOptions extends LeadbotComponentsConfig {
4
5
  /**
@@ -9,6 +10,51 @@ export interface StepOptions extends LeadbotComponentsConfig {
9
10
  id: string;
10
11
  }
11
12
  export type PublishedStep = Step<Partial<StepAttributes>>;
13
+ /**
14
+ * A resolved mount: the published step, plus whether the flow has come back
15
+ * without it. `missing` is what turns a typo'd id from "renders nothing" into
16
+ * something a developer can see — see {@link StepStub}.
17
+ */
18
+ export interface StepResolution {
19
+ step: PublishedStep | null;
20
+ missing: boolean;
21
+ /** The flow was refused with a 403 — a broken install, not a paused bot. */
22
+ forbidden: boolean;
23
+ }
24
+ /**
25
+ * Placeholder for a mount whose `id` resolved to nothing. Two different
26
+ * placeholders, for two different audiences:
27
+ *
28
+ * - The developer one, naming the ids that resolved to nothing, on a dev host,
29
+ * in the dashboard preview or with `debug: true` — never on a plain
30
+ * production page, where an unpublished bot legitimately renders nothing.
31
+ * - The visitor one (`forbidden`), when the collector refused this install with
32
+ * a 403. That is a broken install rather than an expected state, so it does
33
+ * render in production — quietly, localized, and naming nothing.
34
+ */
35
+ export declare function StepStub(options: {
36
+ id?: string;
37
+ leadbotId?: number;
38
+ preview?: boolean;
39
+ debug?: boolean;
40
+ forbidden?: boolean;
41
+ /** Language for the visitor-facing `forbidden` copy. */
42
+ lang?: Lang;
43
+ }): VNode | null;
44
+ /** The subset of a mount's options {@link StepStub} renders from, with the
45
+ * `init()` defaults merged in. */
46
+ export declare function stubProps(options: {
47
+ id?: string;
48
+ } & LeadbotComponentsConfig): {
49
+ id: string | undefined;
50
+ leadbotId: number | undefined;
51
+ preview: boolean | undefined;
52
+ debug: boolean | undefined;
53
+ };
54
+ /** {@link useStep} plus the "flow came back without it" flag. */
55
+ export declare function usePublishedStep(options: Omit<StepOptions, "id"> & {
56
+ id?: string;
57
+ }): StepResolution;
12
58
  /**
13
59
  * Resolves the published step behind `id` from the page's boot fetch. Null
14
60
  * while the fetch is pending, when no id is given, or when the flow has no
@@ -1 +1 @@
1
- {"version":3,"file":"useStep.d.ts","sourceRoot":"","sources":["../src/useStep.ts"],"names":[],"mappings":"AACA,OAAO,EAAe,KAAK,IAAI,EAAE,KAAK,cAAc,EAAE,MAAM,eAAe,CAAC;AAC5E,OAAO,EAAE,KAAK,uBAAuB,EAAY,MAAM,SAAS,CAAC;AAEjE,MAAM,WAAW,WAAY,SAAQ,uBAAuB;IAC3D;;;;OAIG;IACH,EAAE,EAAE,MAAM,CAAC;CACX;AAED,MAAM,MAAM,aAAa,GAAG,IAAI,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC,CAAC;AAE1D;;;;GAIG;AACH,wBAAgB,OAAO,CAEtB,OAAO,EAAE,IAAI,CAAC,WAAW,EAAE,IAAI,CAAC,GAAG;IAAE,EAAE,CAAC,EAAE,MAAM,CAAA;CAAE,GAChD,aAAa,GAAG,IAAI,CAkEtB"}
1
+ {"version":3,"file":"useStep.d.ts","sourceRoot":"","sources":["../src/useStep.ts"],"names":[],"mappings":"AAAA,OAAO,EAAK,KAAK,KAAK,EAAE,MAAM,QAAQ,CAAC;AAEvC,OAAO,EAEN,KAAK,IAAI,EAET,KAAK,IAAI,EACT,KAAK,cAAc,EACnB,MAAM,eAAe,CAAC;AACvB,OAAO,EACN,KAAK,uBAAuB,EAI5B,MAAM,SAAS,CAAC;AAEjB,MAAM,WAAW,WAAY,SAAQ,uBAAuB;IAC3D;;;;OAIG;IACH,EAAE,EAAE,MAAM,CAAC;CACX;AAED,MAAM,MAAM,aAAa,GAAG,IAAI,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC,CAAC;AAE1D;;;;GAIG;AACH,MAAM,WAAW,cAAc;IAC9B,IAAI,EAAE,aAAa,GAAG,IAAI,CAAC;IAC3B,OAAO,EAAE,OAAO,CAAC;IACjB,4EAA4E;IAC5E,SAAS,EAAE,OAAO,CAAC;CACnB;AAkBD;;;;;;;;;;GAUG;AACH,wBAAgB,QAAQ,CAAC,OAAO,EAAE;IACjC,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,wDAAwD;IACxD,IAAI,CAAC,EAAE,IAAI,CAAC;CACZ,GAAG,KAAK,GAAG,IAAI,CAoCf;AAED;kCACkC;AAClC,wBAAgB,SAAS,CAAC,OAAO,EAAE;IAAE,EAAE,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,uBAAuB;;;;;EAQ3E;AAED,iEAAiE;AACjE,wBAAgB,gBAAgB,CAC/B,OAAO,EAAE,IAAI,CAAC,WAAW,EAAE,IAAI,CAAC,GAAG;IAAE,EAAE,CAAC,EAAE,MAAM,CAAA;CAAE,GAChD,cAAc,CA4EhB;AAED;;;;GAIG;AACH,wBAAgB,OAAO,CAEtB,OAAO,EAAE,IAAI,CAAC,WAAW,EAAE,IAAI,CAAC,GAAG;IAAE,EAAE,CAAC,EAAE,MAAM,CAAA;CAAE,GAChD,aAAa,GAAG,IAAI,CAEtB"}
@@ -0,0 +1 @@
1
+ const e=require("./jsxRuntime.module-CT7yzySL.cjs"),t=require("./i18n-gV6rxSod.cjs");let n=require("@leadbot/core");var r=t.a(`en`);function i(r){let i=t.i(r),{step:a,missing:o,forbidden:s}=e.i(r),c=a?.attributes??{},l=r.phoneNumber??c.sender_number??c.phone_number??``,u=c.text,d=r.eventLabel??a?.event_label??void 0,f=(0,n.formSchemaToFields)(c.form_schema)[0],p=t.a(i),m={...p,contactName:c.sender_name??p.contactName,...r.labels},[h,g]=e.l(r.prefilledMessage??``),[_,v]=e.l(null),[y,b]=e.l(!1);return l?e.t(`div`,{className:`leadbot-whatsapp-interface`,children:[e.t(`div`,{className:`leadbot-whatsapp-header`,children:e.t(`div`,{className:`leadbot-whatsapp-contact-info`,children:e.t(`div`,{className:`leadbot-whatsapp-contact-details`,children:[e.t(`div`,{className:`leadbot-whatsapp-name`,children:m.contactName}),e.t(`div`,{className:`leadbot-whatsapp-status`,children:m.status})]})})}),u&&e.t(`div`,{className:`leadbot-whatsapp-chat`,children:e.t(`div`,{className:`leadbot-whatsapp-message`,children:e.t(`div`,{className:`leadbot-whatsapp-message-content`,children:u})})}),e.t(`div`,{className:`leadbot-whatsapp-input-container`,children:[_&&e.t(`div`,{className:`leadbot-form-error`,children:_}),e.t(`form`,{onSubmit:async t=>{t.preventDefault();let i=h.trim();if(!i||y)return;v(null);let o={message:i};if(r.onSubmit&&await r.onSubmit(o)===!1)return;b(!0);let s=!0;try{let t=e.b(r),o=await t.postJson(`/client/submit`,(0,n.buildSubmitPayload)({domainKey:t.domainKey,leadbotId:r.leadbotId,stepUuid:r.id,stepType:`whatsapp`,visitorId:(0,n.getOrCreateVisitorId)(),userData:{[f?.uuid??`message`]:{value:i,type:`text`,label:f?.label??m.messageLabel,required:!0}},analytics:(0,n.buildAnalytics)(),components:!0,event_label:d,marks_as_qualified:r.marksAsQualified??a?.marks_as_qualified??void 0,chat_session_id:(0,n.getActiveChatSession)(),...e.y(r)}));if(!o.ok)throw Error(`Server error: ${o.status}`)}catch(e){s=!1,v(m.submitError),r.onError?.(e)}let c=(0,n.createWhatsAppUrl)(l,i);if(!c){v(m.redirectError),b(!1);return}s&&(0,n.getTracker)().trackWhatsAppRedirect({event_label:d}),window.open(c,`_blank`,`noopener,noreferrer`),r.onSuccess?.(o),g(``),b(!1)},children:e.t(`div`,{className:`leadbot-whatsapp-input-bar`,children:[e.t(`input`,{type:`text`,className:`leadbot-whatsapp-message-field`,placeholder:m.placeholder,value:h,disabled:y,onInput:e=>g(e.currentTarget.value)}),e.t(`button`,{type:`submit`,className:`leadbot-whatsapp-send-btn${y?` leadbot-whatsapp-send-disabled`:``}`,disabled:y,children:e.t(`svg`,{width:`20`,height:`20`,viewBox:`0 0 20 20`,fill:`none`,children:e.t(`path`,{d:`M2.5 10L17.5 3.5L12.5 17L9.5 11L2.5 10Z`,stroke:`currentColor`,strokeWidth:`1.6`,strokeLinecap:`round`,strokeLinejoin:`round`})})})]})})]})]}):o?e.t(e.n,{...e.r(r),forbidden:s,lang:i}):null}function a(t,n){return e.h(i,t,n)}Object.defineProperty(exports,"n",{enumerable:!0,get:function(){return r}}),Object.defineProperty(exports,"r",{enumerable:!0,get:function(){return a}}),Object.defineProperty(exports,"t",{enumerable:!0,get:function(){return i}});
@@ -0,0 +1,128 @@
1
+ import { b as e, g as t, h as n, i as r, l as i, n as a, r as o, t as s, x as c } from "./jsxRuntime.module-DsRxbn3o.js";
2
+ import { a as l, i as u } from "./i18n-DyDsn-Fk.js";
3
+ import { buildSubmitPayload as d, createWhatsAppUrl as f, formSchemaToFields as p, getActiveChatSession as m, getOrCreateVisitorId as h, getTracker as g } from "@leadbot/core";
4
+ //#region src/whatsapp.tsx
5
+ var _ = l("en");
6
+ function v(t) {
7
+ let _ = u(t), { step: v, missing: y, forbidden: b } = r(t), x = v?.attributes ?? {}, S = t.phoneNumber ?? x.sender_number ?? x.phone_number ?? "", C = x.text, w = t.eventLabel ?? v?.event_label ?? void 0, T = p(x.form_schema)[0], E = l(_), D = {
8
+ ...E,
9
+ contactName: x.sender_name ?? E.contactName,
10
+ ...t.labels
11
+ }, [O, k] = i(t.prefilledMessage ?? ""), [A, j] = i(null), [M, N] = i(!1);
12
+ return S ? /* @__PURE__ */ s("div", {
13
+ className: "leadbot-whatsapp-interface",
14
+ children: [
15
+ /* @__PURE__ */ s("div", {
16
+ className: "leadbot-whatsapp-header",
17
+ children: /* @__PURE__ */ s("div", {
18
+ className: "leadbot-whatsapp-contact-info",
19
+ children: /* @__PURE__ */ s("div", {
20
+ className: "leadbot-whatsapp-contact-details",
21
+ children: [/* @__PURE__ */ s("div", {
22
+ className: "leadbot-whatsapp-name",
23
+ children: D.contactName
24
+ }), /* @__PURE__ */ s("div", {
25
+ className: "leadbot-whatsapp-status",
26
+ children: D.status
27
+ })]
28
+ })
29
+ })
30
+ }),
31
+ C && /* @__PURE__ */ s("div", {
32
+ className: "leadbot-whatsapp-chat",
33
+ children: /* @__PURE__ */ s("div", {
34
+ className: "leadbot-whatsapp-message",
35
+ children: /* @__PURE__ */ s("div", {
36
+ className: "leadbot-whatsapp-message-content",
37
+ children: C
38
+ })
39
+ })
40
+ }),
41
+ /* @__PURE__ */ s("div", {
42
+ className: "leadbot-whatsapp-input-container",
43
+ children: [A && /* @__PURE__ */ s("div", {
44
+ className: "leadbot-form-error",
45
+ children: A
46
+ }), /* @__PURE__ */ s("form", {
47
+ onSubmit: async (r) => {
48
+ r.preventDefault();
49
+ let i = O.trim();
50
+ if (!i || M) return;
51
+ j(null);
52
+ let a = { message: i };
53
+ if (t.onSubmit && await t.onSubmit(a) === !1) return;
54
+ N(!0);
55
+ let o = !0;
56
+ try {
57
+ let r = c(t), a = await r.postJson("/client/submit", d({
58
+ domainKey: r.domainKey,
59
+ leadbotId: t.leadbotId,
60
+ stepUuid: t.id,
61
+ stepType: "whatsapp",
62
+ visitorId: h(),
63
+ userData: { [T?.uuid ?? "message"]: {
64
+ value: i,
65
+ type: "text",
66
+ label: T?.label ?? D.messageLabel,
67
+ required: !0
68
+ } },
69
+ analytics: n(),
70
+ components: !0,
71
+ event_label: w,
72
+ marks_as_qualified: t.marksAsQualified ?? v?.marks_as_qualified ?? void 0,
73
+ chat_session_id: m(),
74
+ ...e(t)
75
+ }));
76
+ if (!a.ok) throw Error(`Server error: ${a.status}`);
77
+ } catch (e) {
78
+ o = !1, j(D.submitError), t.onError?.(e);
79
+ }
80
+ let s = f(S, i);
81
+ if (!s) {
82
+ j(D.redirectError), N(!1);
83
+ return;
84
+ }
85
+ o && g().trackWhatsAppRedirect({ event_label: w }), window.open(s, "_blank", "noopener,noreferrer"), t.onSuccess?.(a), k(""), N(!1);
86
+ },
87
+ children: /* @__PURE__ */ s("div", {
88
+ className: "leadbot-whatsapp-input-bar",
89
+ children: [/* @__PURE__ */ s("input", {
90
+ type: "text",
91
+ className: "leadbot-whatsapp-message-field",
92
+ placeholder: D.placeholder,
93
+ value: O,
94
+ disabled: M,
95
+ onInput: (e) => k(e.currentTarget.value)
96
+ }), /* @__PURE__ */ s("button", {
97
+ type: "submit",
98
+ className: `leadbot-whatsapp-send-btn${M ? " leadbot-whatsapp-send-disabled" : ""}`,
99
+ disabled: M,
100
+ children: /* @__PURE__ */ s("svg", {
101
+ width: "20",
102
+ height: "20",
103
+ viewBox: "0 0 20 20",
104
+ fill: "none",
105
+ children: /* @__PURE__ */ s("path", {
106
+ d: "M2.5 10L17.5 3.5L12.5 17L9.5 11L2.5 10Z",
107
+ stroke: "currentColor",
108
+ strokeWidth: "1.6",
109
+ strokeLinecap: "round",
110
+ strokeLinejoin: "round"
111
+ })
112
+ })
113
+ })]
114
+ })
115
+ })]
116
+ })
117
+ ]
118
+ }) : y ? /* @__PURE__ */ s(a, {
119
+ ...o(t),
120
+ forbidden: b,
121
+ lang: _
122
+ }) : null;
123
+ }
124
+ function y(e, n) {
125
+ return t(v, e, n);
126
+ }
127
+ //#endregion
128
+ export { _ as n, y as r, v as t };
@@ -0,0 +1 @@
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./jsxRuntime.module-CT7yzySL.cjs"),t=require("./whatsapp-B3GO1RDT.cjs");let n=require("@leadbot/core");exports.ComponentsWhatsApp=t.t,exports.DEFAULT_WHATSAPP_LABELS=t.n,exports.ROOT_CLASS=e.m,Object.defineProperty(exports,"buildAnalytics",{enumerable:!0,get:function(){return n.buildAnalytics}}),exports.init=e._,exports.loadFlow=e.v,exports.mountWhatsApp=t.r,exports.useStep=e.a;
@@ -8,6 +8,7 @@ export interface WhatsAppLabels {
8
8
  submitError: string;
9
9
  redirectError: string;
10
10
  }
11
+ /** English label set; every other language comes from the same table. */
11
12
  export declare const DEFAULT_WHATSAPP_LABELS: WhatsAppLabels;
12
13
  export interface WhatsAppOptions extends BaseMountOptions, StepOptions {
13
14
  /** Id of the component leadbot this component belongs to (dashboard → Settings → Components). */
@@ -1 +1 @@
1
- {"version":3,"file":"whatsapp.d.ts","sourceRoot":"","sources":["../src/whatsapp.tsx"],"names":[],"mappings":"AAUA,OAAO,EACN,KAAK,gBAAgB,EAGrB,KAAK,WAAW,EAGhB,MAAM,SAAS,CAAC;AACjB,OAAO,EAAE,KAAK,WAAW,EAAW,MAAM,WAAW,CAAC;AAEtD,MAAM,WAAW,cAAc;IAC9B,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;CACtB;AAED,eAAO,MAAM,uBAAuB,EAAE,cASrC,CAAC;AAOF,MAAM,WAAW,eAAgB,SAAQ,gBAAgB,EAAE,WAAW;IACrE,iGAAiG;IACjG,SAAS,EAAE,MAAM,CAAC;IAClB,iGAAiG;IACjG,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,sDAAsD;IACtD,QAAQ,CAAC,EAAE,CACV,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KACzB,OAAO,GAAG,IAAI,GAAG,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,CAAC;IAC9C,SAAS,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,CAAC;IACpD,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;IACnC,MAAM,CAAC,EAAE,OAAO,CAAC,cAAc,CAAC,CAAC;CACjC;AAED,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,eAAe,uCAwIxD;AAED,wBAAgB,aAAa,CAC5B,EAAE,EAAE,WAAW,EACf,OAAO,EAAE,eAAe,GACtB,WAAW,CAAC,eAAe,CAAC,CAE9B"}
1
+ {"version":3,"file":"whatsapp.d.ts","sourceRoot":"","sources":["../src/whatsapp.tsx"],"names":[],"mappings":"AAUA,OAAO,EACN,KAAK,gBAAgB,EAGrB,KAAK,WAAW,EAGhB,MAAM,SAAS,CAAC;AAEjB,OAAO,EACN,KAAK,WAAW,EAIhB,MAAM,WAAW,CAAC;AAEnB,MAAM,WAAW,cAAc;IAC9B,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;CACtB;AAED,yEAAyE;AACzE,eAAO,MAAM,uBAAuB,EAAE,cAAqC,CAAC;AAO5E,MAAM,WAAW,eAAgB,SAAQ,gBAAgB,EAAE,WAAW;IACrE,iGAAiG;IACjG,SAAS,EAAE,MAAM,CAAC;IAClB,iGAAiG;IACjG,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,sDAAsD;IACtD,QAAQ,CAAC,EAAE,CACV,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KACzB,OAAO,GAAG,IAAI,GAAG,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,CAAC;IAC9C,SAAS,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,CAAC;IACpD,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;IACnC,MAAM,CAAC,EAAE,OAAO,CAAC,cAAc,CAAC,CAAC;CACjC;AAED,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,eAAe,uCA8IxD;AAED,wBAAgB,aAAa,CAC5B,EAAE,EAAE,WAAW,EACf,OAAO,EAAE,eAAe,GACtB,WAAW,CAAC,eAAe,CAAC,CAE9B"}
@@ -0,0 +1,3 @@
1
+ import { a as e, h as t, m as n, v as r, y as i } from "./jsxRuntime.module-DsRxbn3o.js";
2
+ import { n as a, r as o, t as s } from "./whatsapp-DGnyaume.js";
3
+ export { s as ComponentsWhatsApp, a as DEFAULT_WHATSAPP_LABELS, n as ROOT_CLASS, t as buildAnalytics, r as init, i as loadFlow, o as mountWhatsApp, e as useStep };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@leadbot/components",
3
- "version": "2.21.1",
3
+ "version": "2.24.1",
4
4
  "description": "LeadBot Components: mount agent chat, forms, callback/email requests and WhatsApp handoff into your own DOM.",
5
5
  "license": "MIT",
6
6
  "publishConfig": {
@@ -11,31 +11,59 @@
11
11
  "sideEffects": [
12
12
  "*.css"
13
13
  ],
14
- "main": "./dist/index.js",
14
+ "main": "./dist/index.cjs",
15
15
  "types": "./dist/index.d.ts",
16
16
  "exports": {
17
17
  ".": {
18
18
  "types": "./dist/index.d.ts",
19
- "import": "./dist/index.js"
19
+ "import": "./dist/index.js",
20
+ "require": "./dist/index.cjs"
21
+ },
22
+ "./form": {
23
+ "types": "./dist/entries/form.d.ts",
24
+ "import": "./dist/form.js",
25
+ "require": "./dist/form.cjs"
26
+ },
27
+ "./chat": {
28
+ "types": "./dist/entries/chat.d.ts",
29
+ "import": "./dist/chat.js",
30
+ "require": "./dist/chat.cjs"
31
+ },
32
+ "./whatsapp": {
33
+ "types": "./dist/entries/whatsapp.d.ts",
34
+ "import": "./dist/whatsapp.js",
35
+ "require": "./dist/whatsapp.cjs"
36
+ },
37
+ "./buttons": {
38
+ "types": "./dist/entries/buttons.d.ts",
39
+ "import": "./dist/buttons.js",
40
+ "require": "./dist/buttons.cjs"
41
+ },
42
+ "./flow": {
43
+ "types": "./dist/entries/flow.d.ts",
44
+ "import": "./dist/flow.js",
45
+ "require": "./dist/flow.cjs"
20
46
  },
21
47
  "./styles.css": "./dist/styles.css"
22
48
  },
23
49
  "files": [
24
- "dist"
50
+ "dist",
51
+ "README.md"
25
52
  ],
26
53
  "dependencies": {
27
- "@leadbot/core": "2.21.1"
54
+ "@leadbot/core": "2.24.1"
28
55
  },
29
56
  "devDependencies": {
30
- "happy-dom": "^20.8.9",
31
- "preact": "^10.29.1",
32
- "sass-embedded": "^1.99.0",
57
+ "happy-dom": "^20.11.6",
58
+ "preact": "^10.29.8",
59
+ "sass-embedded": "^1.103.1",
33
60
  "typescript": "^5.9.3",
34
- "vite": "^8.0.8",
35
- "vitest": "^4.1.4"
61
+ "vite": "^8.2.2",
62
+ "vitest": "^4.1.11"
36
63
  },
37
64
  "scripts": {
38
- "build": "vite build && tsc -p tsconfig.json && sass --no-source-map src/styles/index.scss dist/styles.css",
65
+ "build": "vite build && tsc -p tsconfig.json && rm -f dist/global.d.ts dist/global.d.ts.map && sass --no-source-map src/styles/index.scss dist/styles.css",
66
+ "build:cdn": "vite build --config vite.cdn.config.ts",
39
67
  "test": "vitest run"
40
68
  }
41
69
  }