@adatechnology/conversations-ui 0.4.2 → 0.5.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 (93) hide show
  1. package/README.md +169 -0
  2. package/dist/{ConversationSimulatorPanel-DnXElfY8.d.ts → ConversationSimulatorPanel-CrfFjiWh.d.ts} +2 -268
  3. package/dist/{chunk-PJNR6UMN.js → chunk-CBYEHPX6.js} +1 -63
  4. package/dist/{chunk-HMCOTZAX.js → chunk-HOKNKXIT.js} +1 -1
  5. package/dist/{chunk-4P5KMWOI.js → chunk-JXJCPN34.js} +327 -522
  6. package/dist/chunk-MRVFFJEH.js +64 -0
  7. package/dist/chunk-RJMSM3YA.js +249 -0
  8. package/dist/chunk-WSFGNR5R.js +55 -0
  9. package/dist/flows/index.js +5 -3
  10. package/dist/index.d.ts +9 -3
  11. package/dist/index.js +783 -807
  12. package/dist/participant/index.d.ts +162 -0
  13. package/dist/participant/index.js +1448 -0
  14. package/dist/preview/index.d.ts +4 -2
  15. package/dist/preview/index.js +4 -2
  16. package/dist/quickReply.types-B4gmZsSr.d.ts +274 -0
  17. package/dist/styles.css +591 -0
  18. package/package.json +8 -4
  19. package/src/ChannelIcon.tsx +2 -0
  20. package/src/MessageBubble.test.tsx +2 -2
  21. package/src/MessageText.test.tsx +59 -0
  22. package/src/MessageText.tsx +20 -12
  23. package/src/MessageTextCopiedBadge.tsx +7 -0
  24. package/src/StatusTicks.test.tsx +30 -0
  25. package/src/StatusTicks.tsx +24 -9
  26. package/src/buildOutput.test.ts +41 -0
  27. package/src/channelCapability.test.ts +17 -0
  28. package/src/conversationChannel.test.ts +30 -1
  29. package/src/conversationChannel.ts +19 -1
  30. package/src/participant/ParticipantAttachmentItem.tsx +77 -0
  31. package/src/participant/ParticipantComposer.test.tsx +97 -0
  32. package/src/participant/ParticipantComposer.tsx +167 -0
  33. package/src/participant/ParticipantConversations.test.tsx +90 -0
  34. package/src/participant/ParticipantConversations.tsx +42 -0
  35. package/src/participant/ParticipantConversationsScreen.tsx +67 -0
  36. package/src/participant/ParticipantInbox.test.tsx +147 -0
  37. package/src/participant/ParticipantInbox.tsx +168 -0
  38. package/src/participant/ParticipantLoadState.tsx +27 -0
  39. package/src/participant/ParticipantMessageBubble.test.tsx +165 -0
  40. package/src/participant/ParticipantMessageBubble.tsx +185 -0
  41. package/src/participant/ParticipantThread.test.tsx +132 -0
  42. package/src/participant/ParticipantThread.tsx +174 -0
  43. package/src/participant/ParticipantThreadScreen.tsx +135 -0
  44. package/src/participant/bindAttachmentUrlResolver.test.ts +25 -0
  45. package/src/participant/bindAttachmentUrlResolver.ts +7 -0
  46. package/src/participant/index.ts +25 -0
  47. package/src/participant/participant.types.ts +43 -0
  48. package/src/participant/participantApi.types.ts +59 -0
  49. package/src/participant/participantAttachmentUrl.test.ts +32 -0
  50. package/src/participant/participantAttachmentUrl.ts +10 -0
  51. package/src/participant/participantBubbleActions.test.ts +44 -0
  52. package/src/participant/participantBubbleActions.ts +40 -0
  53. package/src/participant/participantDrafts.test.ts +65 -0
  54. package/src/participant/participantDrafts.ts +50 -0
  55. package/src/participant/participantFileValidation.test.ts +86 -0
  56. package/src/participant/participantFileValidation.ts +72 -0
  57. package/src/participant/participantFixtures.test-helper.ts +41 -0
  58. package/src/participant/participantGrouping.test.ts +138 -0
  59. package/src/participant/participantGrouping.ts +77 -0
  60. package/src/participant/participantInboxState.test.ts +69 -0
  61. package/src/participant/participantInboxState.ts +74 -0
  62. package/src/participant/participantLabels.ts +86 -0
  63. package/src/participant/participantLoadView.test.ts +23 -0
  64. package/src/participant/participantLoadView.ts +21 -0
  65. package/src/participant/participantMessages.test.ts +128 -0
  66. package/src/participant/participantMessages.ts +73 -0
  67. package/src/participant/participantNewMessages.test.ts +54 -0
  68. package/src/participant/participantNewMessages.ts +29 -0
  69. package/src/participant/participantQuickReply.test.ts +23 -0
  70. package/src/participant/participantQuickReply.ts +6 -0
  71. package/src/participant/participantScroll.test.ts +69 -0
  72. package/src/participant/participantScroll.ts +43 -0
  73. package/src/participant/participantSendController.test.ts +201 -0
  74. package/src/participant/participantSendController.ts +134 -0
  75. package/src/participant/participantSendStates.ts +31 -0
  76. package/src/participant/participantTheme.ts +20 -0
  77. package/src/participant/participantThreadState.test.ts +75 -0
  78. package/src/participant/participantThreadState.ts +59 -0
  79. package/src/participant/shouldMarkRead.test.ts +24 -0
  80. package/src/participant/shouldMarkRead.ts +16 -0
  81. package/src/participant/useDocumentVisibility.ts +18 -0
  82. package/src/participant/useParticipantConversationView.ts +60 -0
  83. package/src/participant/useParticipantDraft.ts +45 -0
  84. package/src/participant/useParticipantInbox.ts +57 -0
  85. package/src/participant/useParticipantMarkRead.ts +26 -0
  86. package/src/participant/useParticipantRevalidation.ts +36 -0
  87. package/src/participant/useParticipantSend.ts +84 -0
  88. package/src/participant/useParticipantThread.ts +116 -0
  89. package/src/participant/useParticipantThreadScroll.ts +26 -0
  90. package/src/participant/useStickToBottom.ts +77 -0
  91. package/src/preview/ConversationSimulatorPanel.tsx +8 -0
  92. package/src/styles.css +160 -0
  93. package/src/types.ts +3 -1
@@ -0,0 +1,64 @@
1
+ // src/useDarkMode.ts
2
+ import { useState, useEffect, useCallback } from "react";
3
+ var STORAGE_KEY = "conversations-ui-dark-mode";
4
+ function getInitialDark() {
5
+ if (typeof window === "undefined") return false;
6
+ const stored = localStorage.getItem(STORAGE_KEY);
7
+ if (stored !== null) {
8
+ return stored === "true";
9
+ }
10
+ return window.matchMedia("(prefers-color-scheme: dark)").matches;
11
+ }
12
+ function useIsDarkTheme() {
13
+ const [isDark, setIsDark] = useState(
14
+ () => typeof document !== "undefined" && document.documentElement.classList.contains("dark")
15
+ );
16
+ useEffect(() => {
17
+ const root = document.documentElement;
18
+ const observer = new MutationObserver(() => setIsDark(root.classList.contains("dark")));
19
+ observer.observe(root, { attributes: true, attributeFilter: ["class"] });
20
+ setIsDark(root.classList.contains("dark"));
21
+ return () => observer.disconnect();
22
+ }, []);
23
+ return isDark;
24
+ }
25
+ function useDarkMode() {
26
+ const [isDark, setIsDark] = useState(getInitialDark);
27
+ useEffect(() => {
28
+ const root = document.documentElement;
29
+ if (isDark) {
30
+ root.classList.add("dark");
31
+ } else {
32
+ root.classList.remove("dark");
33
+ }
34
+ localStorage.setItem(STORAGE_KEY, String(isDark));
35
+ }, [isDark]);
36
+ useEffect(() => {
37
+ const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)");
38
+ const handleChange = (event) => {
39
+ const stored = localStorage.getItem(STORAGE_KEY);
40
+ if (stored === null) {
41
+ setIsDark(event.matches);
42
+ }
43
+ };
44
+ mediaQuery.addEventListener("change", handleChange);
45
+ return () => mediaQuery.removeEventListener("change", handleChange);
46
+ }, []);
47
+ const toggle = useCallback(() => {
48
+ setIsDark((prev) => !prev);
49
+ }, []);
50
+ return { isDark, toggle };
51
+ }
52
+
53
+ // src/lib/cn.ts
54
+ import { clsx } from "clsx";
55
+ import { twMerge } from "tailwind-merge";
56
+ function cn(...inputs) {
57
+ return twMerge(clsx(inputs));
58
+ }
59
+
60
+ export {
61
+ cn,
62
+ useIsDarkTheme,
63
+ useDarkMode
64
+ };
@@ -0,0 +1,249 @@
1
+ // src/lib/phone.ts
2
+ function formatPhone(number) {
3
+ const digits = number.replace(/\D/g, "");
4
+ if (digits.length === 13) {
5
+ return `+${digits.slice(0, 2)} (${digits.slice(2, 4)}) ${digits.slice(4, 9)}-${digits.slice(9, 13)}`;
6
+ }
7
+ if (digits.length === 12) {
8
+ return `+${digits.slice(0, 2)} (${digits.slice(2, 4)}) ${digits.slice(4, 8)}-${digits.slice(8, 12)}`;
9
+ }
10
+ if (digits.length === 11) {
11
+ return `(${digits.slice(0, 2)}) ${digits.slice(2, 7)}-${digits.slice(7, 11)}`;
12
+ }
13
+ if (digits.length === 10) {
14
+ return `(${digits.slice(0, 2)}) ${digits.slice(2, 6)}-${digits.slice(6, 10)}`;
15
+ }
16
+ return number;
17
+ }
18
+ var COUNTRY_FLAG_BY_DIAL_CODE = {
19
+ "55": "\u{1F1E7}\u{1F1F7}",
20
+ "351": "\u{1F1F5}\u{1F1F9}",
21
+ "34": "\u{1F1EA}\u{1F1F8}",
22
+ "54": "\u{1F1E6}\u{1F1F7}",
23
+ "56": "\u{1F1E8}\u{1F1F1}",
24
+ "57": "\u{1F1E8}\u{1F1F4}",
25
+ "52": "\u{1F1F2}\u{1F1FD}",
26
+ "598": "\u{1F1FA}\u{1F1FE}",
27
+ "595": "\u{1F1F5}\u{1F1FE}",
28
+ "44": "\u{1F1EC}\u{1F1E7}",
29
+ "49": "\u{1F1E9}\u{1F1EA}",
30
+ "39": "\u{1F1EE}\u{1F1F9}",
31
+ "33": "\u{1F1EB}\u{1F1F7}"
32
+ };
33
+ function phoneCountryFlag(number) {
34
+ const digits = number.replace(/\D/g, "");
35
+ for (const length of [3, 2, 1]) {
36
+ const flag = COUNTRY_FLAG_BY_DIAL_CODE[digits.slice(0, length)];
37
+ if (flag) return flag;
38
+ }
39
+ return "";
40
+ }
41
+ function phoneInitials(number) {
42
+ const digits = number.replace(/\D/g, "");
43
+ return digits.slice(-2);
44
+ }
45
+
46
+ // src/conversationChannel.ts
47
+ var CONVERSATION_CHANNEL = {
48
+ WHATSAPP: "whatsapp",
49
+ MESSENGER: "messenger",
50
+ INSTAGRAM: "instagram",
51
+ APP: "app",
52
+ PORTAL: "portal",
53
+ WEBCHAT: "webchat",
54
+ EMAIL: "email"
55
+ };
56
+ var DEFAULT_CONVERSATION_CHANNEL = CONVERSATION_CHANNEL.WHATSAPP;
57
+ var REOPEN_MECHANISM = {
58
+ TEMPLATE: "template",
59
+ TAG: "tag",
60
+ NONE: "none"
61
+ };
62
+ var HANDLE_KIND = {
63
+ PHONE: "phone",
64
+ USERNAME: "username",
65
+ SESSION: "session",
66
+ EMAIL: "email"
67
+ };
68
+ var CHANNEL_CAPABILITIES = {
69
+ [CONVERSATION_CHANNEL.WHATSAPP]: {
70
+ label: "WhatsApp",
71
+ icon: "\u{1F4AC}",
72
+ reopenMechanism: REOPEN_MECHANISM.TEMPLATE,
73
+ handleKind: HANDLE_KIND.PHONE
74
+ },
75
+ [CONVERSATION_CHANNEL.MESSENGER]: {
76
+ // Messenger também tem 24h, mas reabre com message tag — não com template aprovado.
77
+ label: "Messenger",
78
+ icon: "\u{1F4E8}",
79
+ reopenMechanism: REOPEN_MECHANISM.TAG,
80
+ handleKind: HANDLE_KIND.USERNAME
81
+ },
82
+ [CONVERSATION_CHANNEL.INSTAGRAM]: {
83
+ label: "Instagram",
84
+ icon: "\u{1F4F7}",
85
+ reopenMechanism: REOPEN_MECHANISM.TAG,
86
+ handleKind: HANDLE_KIND.USERNAME
87
+ },
88
+ [CONVERSATION_CHANNEL.APP]: {
89
+ label: "App",
90
+ icon: "\u{1F4F1}",
91
+ reopenMechanism: REOPEN_MECHANISM.NONE,
92
+ handleKind: HANDLE_KIND.SESSION
93
+ },
94
+ [CONVERSATION_CHANNEL.PORTAL]: {
95
+ label: "Portal",
96
+ icon: "\u{1F517}",
97
+ reopenMechanism: REOPEN_MECHANISM.NONE,
98
+ handleKind: HANDLE_KIND.SESSION
99
+ },
100
+ [CONVERSATION_CHANNEL.WEBCHAT]: {
101
+ // Chat próprio: sem intermediário, sem janela. Bloquear o composer aqui seria inventar limite.
102
+ label: "Chat do site",
103
+ icon: "\u{1F310}",
104
+ reopenMechanism: REOPEN_MECHANISM.NONE,
105
+ handleKind: HANDLE_KIND.SESSION
106
+ },
107
+ [CONVERSATION_CHANNEL.EMAIL]: {
108
+ // RF10: e-mail entra no vocabulário; ele não reabre por template nem por tag — é só resposta.
109
+ label: "E-mail",
110
+ icon: "\u2709\uFE0F",
111
+ reopenMechanism: REOPEN_MECHANISM.NONE,
112
+ handleKind: HANDLE_KIND.EMAIL
113
+ }
114
+ };
115
+ function capabilitiesOf(channel) {
116
+ return CHANNEL_CAPABILITIES[channel ?? DEFAULT_CONVERSATION_CHANNEL];
117
+ }
118
+ var CHANNEL_FILTER_ALL = "all";
119
+ function channelFiltersFor(conversations) {
120
+ const present = new Set(
121
+ conversations.map((conversation) => conversation.channel ?? DEFAULT_CONVERSATION_CHANNEL)
122
+ );
123
+ if (present.size < 2) return [];
124
+ const ordered = Object.keys(CHANNEL_CAPABILITIES).filter((channel) => present.has(channel));
125
+ return [
126
+ { value: CHANNEL_FILTER_ALL, label: "Todos" },
127
+ ...ordered.map((channel) => ({ value: channel, label: CHANNEL_CAPABILITIES[channel].label }))
128
+ ];
129
+ }
130
+ function formatContactHandle(params) {
131
+ const { handleKind } = capabilitiesOf(params.channel);
132
+ if (handleKind === HANDLE_KIND.PHONE) return formatPhone(params.handle);
133
+ if (handleKind === HANDLE_KIND.USERNAME) return params.handle.startsWith("@") ? params.handle : `@${params.handle}`;
134
+ if (handleKind === HANDLE_KIND.EMAIL) return params.handle;
135
+ return `Visitante ${params.handle.slice(-6)}`;
136
+ }
137
+ function contactFlag(params) {
138
+ return capabilitiesOf(params.channel).handleKind === HANDLE_KIND.PHONE ? phoneCountryFlag(params.handle) : "";
139
+ }
140
+
141
+ // src/channelCapability.ts
142
+ import {
143
+ CHANNEL_CAPABILITIES as CORE_CHANNEL_CAPABILITIES,
144
+ CONVERSATION_CHANNEL as CORE_CONVERSATION_CHANNEL
145
+ } from "@adatechnology/conversation-contracts";
146
+ var CORE_CHANNELS = CORE_CONVERSATION_CHANNEL;
147
+ function isCoreChannel(channel) {
148
+ return CORE_CHANNELS.includes(channel);
149
+ }
150
+ var META_ONLY_CHANNEL_CAPABILITY = CORE_CHANNEL_CAPABILITIES.whatsapp;
151
+ function channelCapabilityFor(channel) {
152
+ const resolved = channel ?? DEFAULT_CONVERSATION_CHANNEL;
153
+ return isCoreChannel(resolved) ? CORE_CHANNEL_CAPABILITIES[resolved] : META_ONLY_CHANNEL_CAPABILITY;
154
+ }
155
+
156
+ // src/StatusTicks.tsx
157
+ import { AlertTriangle, Clock } from "lucide-react";
158
+ import { jsx, jsxs } from "react/jsx-runtime";
159
+ var STATUS_MODIFIER = {
160
+ queued: "queued",
161
+ sent: "sent",
162
+ delivered: "delivered",
163
+ read: "read",
164
+ failed: "failed",
165
+ bounced: "failed"
166
+ };
167
+ var QUEUED_LABEL = "Queued";
168
+ function Ticks({ double }) {
169
+ return /* @__PURE__ */ jsxs("svg", { viewBox: "0 0 20 12", width: "15", height: "9", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: [
170
+ double && /* @__PURE__ */ jsx("path", { d: "M1 6.5L4.5 10L11 2", stroke: "currentColor", strokeWidth: "1.6", strokeLinecap: "round", strokeLinejoin: "round" }),
171
+ /* @__PURE__ */ jsx(
172
+ "path",
173
+ {
174
+ d: double ? "M6 6.5L9.5 10L19 1" : "M1 6.5L5 10.5L14.5 1",
175
+ stroke: "currentColor",
176
+ strokeWidth: "1.6",
177
+ strokeLinecap: "round",
178
+ strokeLinejoin: "round"
179
+ }
180
+ )
181
+ ] });
182
+ }
183
+ function StatusIcon({ modifier }) {
184
+ if (modifier === "failed") return /* @__PURE__ */ jsx(AlertTriangle, { size: 11 });
185
+ if (modifier === "queued") return /* @__PURE__ */ jsx(Clock, { size: 11 });
186
+ return /* @__PURE__ */ jsx(Ticks, { double: modifier !== "sent" });
187
+ }
188
+ function StatusTicks({ status, title }) {
189
+ const modifier = STATUS_MODIFIER[status] ?? "sent";
190
+ const ariaLabel = modifier === "queued" ? QUEUED_LABEL : void 0;
191
+ return /* @__PURE__ */ jsx(
192
+ "span",
193
+ {
194
+ className: `cv-status-ticks cv-status-ticks--${modifier}`,
195
+ "data-cv-tooltip": title ?? ariaLabel,
196
+ "aria-label": ariaLabel,
197
+ children: /* @__PURE__ */ jsx(StatusIcon, { modifier })
198
+ }
199
+ );
200
+ }
201
+
202
+ // src/lib/format.ts
203
+ function formatTimestamp(timestamp) {
204
+ try {
205
+ const date = new Date(timestamp);
206
+ const hours = date.getHours().toString().padStart(2, "0");
207
+ const minutes = date.getMinutes().toString().padStart(2, "0");
208
+ return `${hours}:${minutes}`;
209
+ } catch {
210
+ return timestamp;
211
+ }
212
+ }
213
+ function formatDateTime(iso) {
214
+ const d = new Date(iso);
215
+ return d.toLocaleString("pt-BR", { day: "2-digit", month: "2-digit", hour: "2-digit", minute: "2-digit" });
216
+ }
217
+ function isSameDay(a, b) {
218
+ return a.getFullYear() === b.getFullYear() && a.getMonth() === b.getMonth() && a.getDate() === b.getDate();
219
+ }
220
+ var FILE_SIZE_UNITS = ["B", "KB", "MB", "GB"];
221
+ function formatFileSize(bytes) {
222
+ if (!isFinite(bytes) || bytes < 0) return "";
223
+ if (bytes < 1) return "0 B";
224
+ const exponent = Math.min(Math.floor(Math.log(bytes) / Math.log(1024)), FILE_SIZE_UNITS.length - 1);
225
+ const value = bytes / 1024 ** exponent;
226
+ const formatted = exponent === 0 ? value.toString() : value.toFixed(value < 10 ? 1 : 0);
227
+ return `${formatted} ${FILE_SIZE_UNITS[exponent]}`;
228
+ }
229
+
230
+ export {
231
+ formatPhone,
232
+ phoneInitials,
233
+ CONVERSATION_CHANNEL,
234
+ DEFAULT_CONVERSATION_CHANNEL,
235
+ REOPEN_MECHANISM,
236
+ HANDLE_KIND,
237
+ CHANNEL_CAPABILITIES,
238
+ capabilitiesOf,
239
+ CHANNEL_FILTER_ALL,
240
+ channelFiltersFor,
241
+ formatContactHandle,
242
+ contactFlag,
243
+ channelCapabilityFor,
244
+ StatusTicks,
245
+ formatTimestamp,
246
+ formatDateTime,
247
+ isSameDay,
248
+ formatFileSize
249
+ };
@@ -0,0 +1,55 @@
1
+ import {
2
+ parseWhatsAppFormatting
3
+ } from "./chunk-CBYEHPX6.js";
4
+
5
+ // src/MessageText.tsx
6
+ import { useCallback, useState } from "react";
7
+
8
+ // src/theme.ts
9
+ var CHAT_TEXT_PRIMARY_CLASS = "text-[#111b21] dark:text-[#e9edef]";
10
+ var CHAT_TEXT_SECONDARY_CLASS = "text-[#667781] dark:text-[#8696a0]";
11
+
12
+ // src/MessageTextCopiedBadge.tsx
13
+ import { jsx } from "react/jsx-runtime";
14
+ function MessageTextCopiedBadge({ label = "Copied" }) {
15
+ return /* @__PURE__ */ jsx("span", { className: "cv-message-text__copied", children: label });
16
+ }
17
+
18
+ // src/MessageText.tsx
19
+ import { jsx as jsx2, jsxs } from "react/jsx-runtime";
20
+ function MessageText({ message, copyOnClick = true, copiedLabel }) {
21
+ const [copied, setCopied] = useState(false);
22
+ const handleCopy = useCallback(async () => {
23
+ if (!copyOnClick || !message.content) return;
24
+ try {
25
+ await navigator.clipboard.writeText(message.content);
26
+ setCopied(true);
27
+ setTimeout(() => setCopied(false), 2e3);
28
+ } catch {
29
+ }
30
+ }, [copyOnClick, message.content]);
31
+ const handleKeyDown = (event) => {
32
+ if (event.key !== "Enter" && event.key !== " ") return;
33
+ event.preventDefault();
34
+ void handleCopy();
35
+ };
36
+ if (message.type === "template")
37
+ return /* @__PURE__ */ jsx2("p", { className: `text-sm italic ${CHAT_TEXT_SECONDARY_CLASS}`, children: message.content ?? "Template message" });
38
+ return /* @__PURE__ */ jsxs(
39
+ "div",
40
+ {
41
+ className: copyOnClick ? "cv-message-text cv-message-text--copyable" : "cv-message-text",
42
+ ...copyOnClick ? { role: "button", tabIndex: 0, onClick: handleCopy, onKeyDown: handleKeyDown } : {},
43
+ children: [
44
+ /* @__PURE__ */ jsx2("div", { children: parseWhatsAppFormatting(message.content ?? "") }),
45
+ copied && /* @__PURE__ */ jsx2(MessageTextCopiedBadge, { label: copiedLabel })
46
+ ]
47
+ }
48
+ );
49
+ }
50
+
51
+ export {
52
+ CHAT_TEXT_PRIMARY_CLASS,
53
+ CHAT_TEXT_SECONDARY_CLASS,
54
+ MessageText
55
+ };
@@ -1,11 +1,13 @@
1
1
  import {
2
2
  TooltipLayer,
3
3
  WhatsAppMessagePreview
4
- } from "../chunk-HMCOTZAX.js";
4
+ } from "../chunk-HOKNKXIT.js";
5
5
  import {
6
- parseWhatsAppFormatting,
7
6
  useIsDarkTheme
8
- } from "../chunk-PJNR6UMN.js";
7
+ } from "../chunk-MRVFFJEH.js";
8
+ import {
9
+ parseWhatsAppFormatting
10
+ } from "../chunk-CBYEHPX6.js";
9
11
 
10
12
  // src/flows/FlowNodeCard.tsx
11
13
  import { useState } from "react";
package/dist/index.d.ts CHANGED
@@ -1,7 +1,9 @@
1
1
  import * as react from 'react';
2
2
  import react__default, { ReactNode, CSSProperties, UIEvent, FormEvent, RefObject, KeyboardEvent } from 'react';
3
- import { M as MessagePayload, R as ResolveMediaUrl, U as InteractiveSelection, V as MessageTranscription, W as ConversationChannel, X as InteractivePayload, Y as ConversationsFeatures, Z as QuickReply$1, C as ConversationSummary, L as ListConversationsParams, b as ConversationsApi, S as SSEProvider, _ as TranscriptionMode, $ as ListDocumentsParams, d as ConversationDocument, a0 as ConversationTemplate, a1 as QueuedAttachment, a2 as QuickReplyInput, a3 as QuickReplyAttachment, a4 as ConversationVariable, a5 as ChannelFilter, a6 as ChannelFilterOption, k as ConversationSimulatorClient, m as ConversationSimulatorPanelLabels, P as PreviewUploadedMedia } from './ConversationSimulatorPanel-DnXElfY8.js';
4
- export { A as AudioRecorderButton, g as AudioRecorderButtonLabels, h as AudioRecorderButtonProps, a7 as CHANNEL_CAPABILITIES, a8 as CHANNEL_FILTER_ALL, a9 as CONVERSATION_CHANNEL, aa as ChannelCapabilities, ab as CompanyDocument, ac as CompanyDocumentPage, ad as ConversationDocumentPage, a as ConversationEventSource, c as ConversationPage, ae as ConversationsTheme, af as ConversationsUIConfig, D as DEFAULT_AUDIO_RECORDER_BUTTON_LABELS, ag as DEFAULT_CONVERSATION_CHANNEL, ah as DEFAULT_MAX_RECORDING_MILLISECONDS, ai as FormatContactHandleParams, aj as HANDLE_KIND, ak as HandleKind, al as InteractiveOption, am as InteractiveSection, an as MediaRenderer, ao as MediaRendererProps, ap as QUICK_REPLY_ATTACHMENT_LIMIT, aq as REOPEN_MECHANISM, ar as ReopenMechanism, y as SendSimulatorMediaParams, z as SimulatorMediaKind, as as StoredAttachmentSendResult, at as TranscriptionStatus, au as capabilitiesOf, av as channelFiltersFor, aw as contactFlag, ax as formatContactHandle } from './ConversationSimulatorPanel-DnXElfY8.js';
3
+ import { M as MessagePayload, I as InteractiveSelection, b as MessageTranscription, C as ConversationChannel, e as InteractivePayload, f as ConversationsFeatures, Q as QuickReply$1, T as TranscriptionMode, g as QueuedAttachment, c as QuickReplyInput, d as QuickReplyAttachment, h as ConversationVariable, i as ChannelFilter, j as ChannelFilterOption } from './quickReply.types-B4gmZsSr.js';
4
+ export { k as CHANNEL_CAPABILITIES, l as CHANNEL_FILTER_ALL, m as CONVERSATION_CHANNEL, n as ChannelCapabilities, a as ConversationsTheme, o as ConversationsUIConfig, D as DEFAULT_CONVERSATION_CHANNEL, F as FormatContactHandleParams, H as HANDLE_KIND, p as HandleKind, q as InteractiveOption, r as InteractiveSection, s as QUICK_REPLY_ATTACHMENT_LIMIT, R as REOPEN_MECHANISM, t as ReopenMechanism, S as StoredAttachmentSendResult, u as TranscriptionStatus, v as capabilitiesOf, w as channelFiltersFor, x as contactFlag, y as formatContactHandle } from './quickReply.types-B4gmZsSr.js';
5
+ import { R as ResolveMediaUrl, C as ConversationSummary, L as ListConversationsParams, b as ConversationsApi, S as SSEProvider, Q as ListDocumentsParams, d as ConversationDocument, U as ConversationTemplate, k as ConversationSimulatorClient, m as ConversationSimulatorPanelLabels, P as PreviewUploadedMedia } from './ConversationSimulatorPanel-CrfFjiWh.js';
6
+ export { A as AudioRecorderButton, g as AudioRecorderButtonLabels, h as AudioRecorderButtonProps, V as CompanyDocument, W as CompanyDocumentPage, X as ConversationDocumentPage, a as ConversationEventSource, c as ConversationPage, D as DEFAULT_AUDIO_RECORDER_BUTTON_LABELS, Y as DEFAULT_MAX_RECORDING_MILLISECONDS, Z as MediaRenderer, _ as MediaRendererProps, y as SendSimulatorMediaParams, z as SimulatorMediaKind } from './ConversationSimulatorPanel-CrfFjiWh.js';
5
7
  import { ChannelCapability } from '@adatechnology/conversation-contracts';
6
8
  export { ChannelCapability } from '@adatechnology/conversation-contracts';
7
9
  import '@adatechnology/meta-whatsapp-contracts/testing';
@@ -627,8 +629,12 @@ declare function FileIcon({ filename, mimeType, size, className }: FileIconProps
627
629
 
628
630
  interface MessageTextProps {
629
631
  message: MessagePayload;
632
+ /** Defaults to true (tap copies the text, as in 0.3.1); false disables copying and its button semantics. */
633
+ copyOnClick?: boolean;
634
+ /** Text of the badge shown after copying; absent means the package default ("Copied"). */
635
+ copiedLabel?: string;
630
636
  }
631
- declare function MessageText({ message }: MessageTextProps): react.JSX.Element;
637
+ declare function MessageText({ message, copyOnClick, copiedLabel }: MessageTextProps): react.JSX.Element;
632
638
 
633
639
  interface MessageTimestampProps {
634
640
  timestamp: string;