@leadbot/components 2.21.1 → 2.24.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.
Files changed (56) hide show
  1. package/README.md +49 -3
  2. package/dist/agentChat-0mQZrzM9.js +366 -0
  3. package/dist/agentChat-C1wUvNcg.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-BY5oslmc.js +5006 -0
  25. package/dist/flow-CNUyZA89.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 +79 -1
  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
@@ -1498,6 +1498,10 @@
1498
1498
  .leadbot-components .leadbot-whatsapp-chat {
1499
1499
  padding: 16px;
1500
1500
  min-height: 80px;
1501
+ display: flex;
1502
+ flex-direction: column;
1503
+ gap: 8px;
1504
+ align-items: flex-start;
1501
1505
  background: linear-gradient(to bottom, var(--leadbot-whatsapp-wallpaper) 0%, var(--leadbot-whatsapp-wallpaper-end) 100%);
1502
1506
  }
1503
1507
  .leadbot-components .leadbot-whatsapp-message {
@@ -1507,18 +1511,74 @@
1507
1511
  max-width: 100%;
1508
1512
  position: relative;
1509
1513
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
1514
+ --leadbot-whatsapp-bubble-from: -24px;
1515
+ animation: leadbot-whatsapp-bubble-in 0.28s var(--leadbot-ease-appear) backwards;
1510
1516
  }
1511
1517
  .leadbot-components .leadbot-whatsapp-message::before {
1512
1518
  content: "";
1513
1519
  position: absolute;
1514
1520
  left: -8px;
1515
- top: 16px;
1521
+ top: 6px; /* ponytail: hugs the rounded corner and still fits short bubbles (typing dots) */
1516
1522
  width: 0;
1517
1523
  height: 0;
1518
1524
  border: 8px solid transparent;
1519
1525
  border-right-color: var(--leadbot-whatsapp-bubble);
1520
1526
  border-left: none;
1521
1527
  }
1528
+ .leadbot-components {
1529
+ /* Visitor's own message, echoed back while we ask for the phone number. */
1530
+ }
1531
+ .leadbot-components .leadbot-whatsapp-message-outgoing {
1532
+ align-self: flex-end;
1533
+ background: var(--leadbot-whatsapp-green);
1534
+ --leadbot-whatsapp-bubble-from: 24px;
1535
+ }
1536
+ .leadbot-components .leadbot-whatsapp-message-outgoing::before {
1537
+ left: auto;
1538
+ right: -8px;
1539
+ border-right: none;
1540
+ border-left: 8px solid var(--leadbot-whatsapp-green);
1541
+ }
1542
+ .leadbot-components .leadbot-whatsapp-message-outgoing .leadbot-whatsapp-message-content {
1543
+ color: var(--leadbot-whatsapp-on-green);
1544
+ }
1545
+ .leadbot-components {
1546
+ /* Bubbles slide in from their own side, the way WhatsApp lands a message;
1547
+ the side comes from --leadbot-whatsapp-bubble-from. */
1548
+ }
1549
+ @keyframes leadbot-whatsapp-bubble-in {
1550
+ from {
1551
+ opacity: 0;
1552
+ transform: translateX(var(--leadbot-whatsapp-bubble-from));
1553
+ }
1554
+ to {
1555
+ opacity: 1;
1556
+ transform: none;
1557
+ }
1558
+ }
1559
+ .leadbot-components {
1560
+ /* Reply-is-coming indicator, same bubble shape as a real message. */
1561
+ }
1562
+ .leadbot-components .leadbot-whatsapp-typing {
1563
+ padding: 12px;
1564
+ }
1565
+ .leadbot-components .leadbot-whatsapp-typing-dots {
1566
+ display: flex;
1567
+ gap: 4px;
1568
+ }
1569
+ .leadbot-components .leadbot-whatsapp-typing-dots span {
1570
+ width: 6px;
1571
+ height: 6px;
1572
+ border-radius: 50%;
1573
+ background: var(--leadbot-color-text-subtle);
1574
+ animation: leadbot-typing-bounce 1.4s infinite var(--leadbot-ease-loop);
1575
+ }
1576
+ .leadbot-components .leadbot-whatsapp-typing-dots span:nth-child(1) {
1577
+ animation-delay: -0.32s;
1578
+ }
1579
+ .leadbot-components .leadbot-whatsapp-typing-dots span:nth-child(2) {
1580
+ animation-delay: -0.16s;
1581
+ }
1522
1582
  .leadbot-components .leadbot-whatsapp-message-content {
1523
1583
  color: var(--leadbot-whatsapp-bubble-text);
1524
1584
  font-size: var(--leadbot-font-size);
@@ -1895,6 +1955,24 @@
1895
1955
  background: color-mix(in srgb, var(--leadbot-primary) 8%, var(--leadbot-color-surface));
1896
1956
  border-color: var(--leadbot-primary);
1897
1957
  }
1958
+ .leadbot-step-stub {
1959
+ display: flex;
1960
+ flex-direction: column;
1961
+ gap: 4px;
1962
+ padding: 12px 14px;
1963
+ border: 1px dashed #d97706;
1964
+ border-radius: var(--leadbot-radius-md, 8px);
1965
+ background: #fffbeb;
1966
+ color: #7c2d12;
1967
+ font-family: inherit;
1968
+ font-size: var(--leadbot-font-size-sm);
1969
+ line-height: 1.4;
1970
+ }
1971
+ .leadbot-step-stub--quiet {
1972
+ border-color: var(--leadbot-color-border, #e5e7eb);
1973
+ background: transparent;
1974
+ color: var(--leadbot-color-text-muted, #6b7280);
1975
+ }
1898
1976
  @keyframes fadeSlide {
1899
1977
  from {
1900
1978
  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.0",
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.0"
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
  }