@adatechnology/conversations-ui 0.1.0-rc.26 → 0.1.0-rc.27

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 (75) hide show
  1. package/dist/chunk-DXPSPUWF.js +110 -0
  2. package/dist/{chunk-TV4OQRGH.js → chunk-UZJBYD5O.js} +123 -45
  3. package/dist/{chunk-2AYDBWNE.js → chunk-WCBDXZ3X.js} +13 -3
  4. package/dist/flows/index.d.ts +2 -0
  5. package/dist/flows/index.js +61 -18
  6. package/dist/index.d.ts +37 -10
  7. package/dist/index.js +694 -297
  8. package/dist/preview/index.js +3 -3
  9. package/dist/styles.css +119 -6
  10. package/package.json +1 -1
  11. package/src/AudioPlayer.tsx +8 -0
  12. package/src/AudioRecorderButton.test.tsx +3 -3
  13. package/src/AudioRecorderButton.tsx +3 -3
  14. package/src/AudioTranscription.tsx +4 -1
  15. package/src/Avatar.tsx +1 -1
  16. package/src/ConversationContextPanel.tsx +2 -2
  17. package/src/ConversationDocumentsPanel.tsx +11 -6
  18. package/src/ConversationHeader.test.tsx +66 -0
  19. package/src/ConversationHeader.tsx +147 -47
  20. package/src/ConversationListItem.tsx +3 -2
  21. package/src/ConversationRow.tsx +31 -7
  22. package/src/DocumentsLibrary.tsx +9 -4
  23. package/src/EmojiPicker.tsx +2 -1
  24. package/src/InteractiveMessage.tsx +3 -0
  25. package/src/Lightbox.tsx +1 -1
  26. package/src/MediaRenderer.tsx +2 -0
  27. package/src/MessageBubble.test.tsx +41 -0
  28. package/src/MessageBubble.tsx +27 -8
  29. package/src/MessageComposer.tsx +11 -8
  30. package/src/RichMessageComposer.test.tsx +42 -12
  31. package/src/RichMessageComposer.tsx +216 -45
  32. package/src/SimpleEmojiPicker.tsx +5 -3
  33. package/src/StatusTicks.tsx +1 -1
  34. package/src/Toast.tsx +4 -0
  35. package/src/Tooltip.test.ts +42 -0
  36. package/src/Tooltip.tsx +164 -0
  37. package/src/WhatsAppMessageEditor.tsx +4 -4
  38. package/src/WindowExpiredNotice.tsx +12 -4
  39. package/src/composer.constant.ts +33 -0
  40. package/src/conversationWindow.ts +7 -5
  41. package/src/documents/DocumentsWorkspace.tsx +10 -6
  42. package/src/flows/FlowGroupHeader.tsx +2 -2
  43. package/src/flows/FlowMapNode.tsx +2 -1
  44. package/src/flows/FlowNodeCard.tsx +3 -3
  45. package/src/flows/FlowNodePanel.tsx +6 -5
  46. package/src/flows/FlowPalette.tsx +7 -1
  47. package/src/flows/FlowPortalNode.tsx +1 -1
  48. package/src/flows/FlowsWorkspace.tsx +13 -4
  49. package/src/flows/labels.ts +4 -0
  50. package/src/hooks/useContainerWidth.ts +35 -0
  51. package/src/hooks/useConversationRealtime.ts +10 -8
  52. package/src/icon.constant.ts +12 -0
  53. package/src/index.ts +1 -0
  54. package/src/lib/composer-formatting.test.ts +78 -0
  55. package/src/lib/composer-formatting.ts +145 -0
  56. package/src/lib/whatsapp-formatting.test.tsx +37 -0
  57. package/src/lib/whatsapp-formatting.tsx +28 -3
  58. package/src/listing/index.tsx +5 -1
  59. package/src/pagination.constant.ts +10 -0
  60. package/src/preview/ConversationSimulatorPanel.tsx +1 -1
  61. package/src/providers/ConversationsProvider.tsx +8 -6
  62. package/src/settings/MessagesWorkspace.tsx +3 -0
  63. package/src/settings/TopicsForm.tsx +2 -0
  64. package/src/settings/TranscriptionSettingsForm.test.tsx +1 -1
  65. package/src/settings/TranscriptionSettingsForm.tsx +1 -0
  66. package/src/settings/WelcomeFarewellForm.tsx +1 -0
  67. package/src/settings/WhatsAppCreateTemplateForm.tsx +1 -0
  68. package/src/settings/WhatsAppTemplateSettingsForm.tsx +5 -2
  69. package/src/settings/WhatsAppTemplatesSettings.tsx +2 -0
  70. package/src/styles.css +100 -4
  71. package/src/workspace/BulkTemplateModal.tsx +4 -2
  72. package/src/workspace/ConversationPane.tsx +49 -19
  73. package/src/workspace/ConversationsInboxList.tsx +17 -8
  74. package/src/workspace/ConversationsWorkspace.tsx +24 -16
  75. package/src/workspace/useConversationsInbox.ts +5 -2
@@ -1,7 +1,10 @@
1
+ import {
2
+ TooltipLayer
3
+ } from "../chunk-DXPSPUWF.js";
1
4
  import {
2
5
  parseWhatsAppFormatting,
3
6
  useIsDarkTheme
4
- } from "../chunk-2AYDBWNE.js";
7
+ } from "../chunk-WCBDXZ3X.js";
5
8
 
6
9
  // src/flows/FlowNodeCard.tsx
7
10
  import { Handle, Position } from "@xyflow/react";
@@ -99,7 +102,7 @@ function FlowNodeCard({ data }) {
99
102
  return /* @__PURE__ */ jsxs(
100
103
  "div",
101
104
  {
102
- title: isDetached ? labels.detachedNodeTooltip : label,
105
+ "data-cv-tooltip": isDetached ? labels.detachedNodeTooltip : label,
103
106
  className: `relative rounded-lg border-2 px-3 py-2 w-60 cursor-pointer shadow-sm hover:shadow-md transition-shadow ${NODE_TYPE_COLOR[node.type]} ${isSelected ? "ring-2 ring-blue-500 ring-offset-2 dark:ring-offset-gray-900" : ""} ${isDetached ? "border-dashed !border-amber-400 animate-pulse" : ""}`,
104
107
  onClick: () => onSelect(node.id),
105
108
  children: [
@@ -107,7 +110,7 @@ function FlowNodeCard({ data }) {
107
110
  /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-2", children: [
108
111
  /* @__PURE__ */ jsxs("span", { className: "flex items-center gap-1.5 uppercase tracking-wide font-semibold text-gray-500 dark:text-gray-400 text-xs", children: [
109
112
  /* @__PURE__ */ jsx(Icon, { size: 12, strokeWidth: 2.5 }),
110
- isStart && /* @__PURE__ */ jsx("span", { className: "h-1.5 w-1.5 rounded-full bg-emerald-500", title: labels.startNodeTooltip }),
113
+ isStart && /* @__PURE__ */ jsx("span", { className: "h-1.5 w-1.5 rounded-full bg-emerald-500", "data-cv-tooltip": labels.startNodeTooltip }),
111
114
  labels.legend[node.type]
112
115
  ] }),
113
116
  /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1", children: [
@@ -116,7 +119,7 @@ function FlowNodeCard({ data }) {
116
119
  liveCount > 0 && /* @__PURE__ */ jsx(
117
120
  "span",
118
121
  {
119
- title: labels.liveCountTooltip(liveCount),
122
+ "data-cv-tooltip": labels.liveCountTooltip(liveCount),
120
123
  className: "font-bold bg-blue-600 text-white rounded-full px-1.5 py-0.5 text-xs",
121
124
  children: liveCount
122
125
  }
@@ -181,6 +184,8 @@ var DEFAULT_FLOW_EDITOR_LABELS = {
181
184
  question: "Texto da pergunta",
182
185
  options: "Op\xE7\xF5es (choice)",
183
186
  addOption: "Adicionar op\xE7\xE3o",
187
+ removeOption: "Remover op\xE7\xE3o",
188
+ close: "Fechar painel",
184
189
  optionId: "Valor",
185
190
  optionLabel: "Texto exibido",
186
191
  next: "Pr\xF3ximo n\xF3",
@@ -323,12 +328,14 @@ function FlowMapNode({ data }) {
323
328
  /* @__PURE__ */ jsxs2("div", { className: "flex items-center gap-1.5 text-emerald-700 dark:text-emerald-300", children: [
324
329
  /* @__PURE__ */ jsx2(GitBranch2, { size: 14 }),
325
330
  /* @__PURE__ */ jsx2("span", { className: "text-sm font-semibold truncate", children: label }),
326
- isRoot && /* @__PURE__ */ jsx2("span", { className: "h-1.5 w-1.5 rounded-full bg-emerald-500 shrink-0", title: labels.startNodeTooltip })
331
+ isRoot && /* @__PURE__ */ jsx2("span", { className: "h-1.5 w-1.5 rounded-full bg-emerald-500 shrink-0", "data-cv-tooltip": labels.startNodeTooltip })
327
332
  ] }),
328
333
  /* @__PURE__ */ jsx2("p", { className: "text-xs text-gray-500 dark:text-gray-400 mt-1", children: labels.flowMap.nodeCount(nodeCount) }),
329
334
  /* @__PURE__ */ jsxs2(
330
335
  "button",
331
336
  {
337
+ "data-cv-tooltip": labels.flowMap.openFlow,
338
+ "aria-label": labels.flowMap.openFlow,
332
339
  type: "button",
333
340
  onClick: onOpen,
334
341
  className: "mt-2 inline-flex items-center gap-1 text-xs font-medium text-blue-600 dark:text-blue-400 hover:underline",
@@ -678,7 +685,8 @@ function FlowGroupHeader({ data }) {
678
685
  {
679
686
  type: "button",
680
687
  onClick: onFocus,
681
- title: labels.flowGroup.focus,
688
+ "data-cv-tooltip": labels.flowGroup.focus,
689
+ "aria-label": labels.flowGroup.focus,
682
690
  className: "hover:text-blue-600 dark:hover:text-blue-400",
683
691
  children: /* @__PURE__ */ jsx5(Maximize22, { size: 12 })
684
692
  }
@@ -688,7 +696,8 @@ function FlowGroupHeader({ data }) {
688
696
  {
689
697
  type: "button",
690
698
  onClick: onClose,
691
- title: labels.flowGroup.close,
699
+ "data-cv-tooltip": labels.flowGroup.close,
700
+ "aria-label": labels.flowGroup.close,
692
701
  className: "hover:text-red-600 dark:hover:text-red-400",
693
702
  children: /* @__PURE__ */ jsx5(X, { size: 12 })
694
703
  }
@@ -707,7 +716,8 @@ function FlowPortalNode({ data }) {
707
716
  "button",
708
717
  {
709
718
  type: "button",
710
- title: labels.crossFlowPortal.tooltip,
719
+ "data-cv-tooltip": labels.crossFlowPortal.tooltip,
720
+ "aria-label": labels.crossFlowPortal.tooltip,
711
721
  onClick: onNavigate,
712
722
  className: "relative flex items-center gap-1.5 rounded-full border-2 border-dashed border-cyan-400 dark:border-cyan-600 bg-cyan-50 dark:bg-cyan-950/40 px-3 py-1.5 text-xs font-medium text-cyan-700 dark:text-cyan-300 hover:bg-cyan-100 dark:hover:bg-cyan-950/70 transition-colors cursor-pointer",
713
723
  children: [
@@ -752,6 +762,8 @@ function FlowPalette({ onAdd, labels: labelsOverride, actionOptions }) {
752
762
  /* @__PURE__ */ jsxs6(
753
763
  "button",
754
764
  {
765
+ "data-cv-tooltip": labels.palette.title,
766
+ "aria-label": labels.palette.title,
755
767
  onClick: () => setOpen((v) => !v),
756
768
  className: "inline-flex items-center gap-1.5 rounded-lg bg-blue-600 px-3 py-1.5 text-xs font-medium text-white hover:bg-blue-700",
757
769
  children: [
@@ -766,6 +778,8 @@ function FlowPalette({ onAdd, labels: labelsOverride, actionOptions }) {
766
778
  /* @__PURE__ */ jsxs6(
767
779
  "button",
768
780
  {
781
+ "data-cv-tooltip": labels.palette.question,
782
+ "aria-label": labels.palette.question,
769
783
  onMouseEnter: () => setSubmenu("question"),
770
784
  onClick: () => setSubmenu(submenu === "question" ? null : "question"),
771
785
  className: "w-full flex items-center justify-between gap-2 px-3 py-2 text-sm text-gray-700 dark:text-gray-200 hover:bg-gray-50 dark:hover:bg-gray-700",
@@ -782,6 +796,8 @@ function FlowPalette({ onAdd, labels: labelsOverride, actionOptions }) {
782
796
  submenu === "question" && /* @__PURE__ */ jsx7("div", { className: "absolute left-full top-0 ml-1 w-56 rounded-xl border border-gray-200 dark:border-gray-700 bg-white dark:bg-gray-800 shadow-lg py-1", children: QUESTION_TYPES.map((qt) => /* @__PURE__ */ jsx7(
783
797
  "button",
784
798
  {
799
+ "data-cv-tooltip": labels.questionTypeLabels[qt],
800
+ "aria-label": labels.questionTypeLabels[qt],
785
801
  onClick: () => select({ kind: "question", questionType: qt }),
786
802
  className: "w-full text-left px-3 py-2 text-sm text-gray-700 dark:text-gray-200 hover:bg-gray-50 dark:hover:bg-gray-700",
787
803
  children: labels.questionTypeLabels[qt]
@@ -792,6 +808,8 @@ function FlowPalette({ onAdd, labels: labelsOverride, actionOptions }) {
792
808
  /* @__PURE__ */ jsxs6(
793
809
  "button",
794
810
  {
811
+ "data-cv-tooltip": labels.palette.decision,
812
+ "aria-label": labels.palette.decision,
795
813
  onMouseEnter: () => setSubmenu(null),
796
814
  onClick: () => select({ kind: "decision" }),
797
815
  className: "w-full flex items-center gap-2 px-3 py-2 text-sm text-gray-700 dark:text-gray-200 hover:bg-gray-50 dark:hover:bg-gray-700",
@@ -808,7 +826,8 @@ function FlowPalette({ onAdd, labels: labelsOverride, actionOptions }) {
808
826
  onMouseEnter: () => setSubmenu(null),
809
827
  onClick: () => select({ kind: "condition" }),
810
828
  className: "w-full flex items-center gap-2 px-3 py-2 text-sm text-gray-700 dark:text-gray-200 hover:bg-gray-50 dark:hover:bg-gray-700",
811
- title: labels.palette.conditionHint,
829
+ "data-cv-tooltip": labels.palette.conditionHint,
830
+ "aria-label": labels.palette.conditionHint,
812
831
  children: [
813
832
  /* @__PURE__ */ jsx7(Diamond2, { size: 15, className: "text-cyan-500" }),
814
833
  " ",
@@ -820,6 +839,8 @@ function FlowPalette({ onAdd, labels: labelsOverride, actionOptions }) {
820
839
  /* @__PURE__ */ jsxs6(
821
840
  "button",
822
841
  {
842
+ "data-cv-tooltip": labels.palette.action,
843
+ "aria-label": labels.palette.action,
823
844
  onMouseEnter: () => setSubmenu("action"),
824
845
  onClick: () => setSubmenu(submenu === "action" ? null : "action"),
825
846
  className: "w-full flex items-center justify-between gap-2 px-3 py-2 text-sm text-gray-700 dark:text-gray-200 hover:bg-gray-50 dark:hover:bg-gray-700",
@@ -836,6 +857,8 @@ function FlowPalette({ onAdd, labels: labelsOverride, actionOptions }) {
836
857
  submenu === "action" && /* @__PURE__ */ jsx7("div", { className: "absolute left-full top-0 ml-1 w-64 rounded-xl border border-gray-200 dark:border-gray-700 bg-white dark:bg-gray-800 shadow-lg py-1", children: resolvedActionOptions.map((option) => /* @__PURE__ */ jsx7(
837
858
  "button",
838
859
  {
860
+ "data-cv-tooltip": option.label,
861
+ "aria-label": option.label,
839
862
  onClick: () => select({ kind: "action", actionKind: option.actionKind }),
840
863
  className: "w-full text-left px-3 py-2 text-sm text-gray-700 dark:text-gray-200 hover:bg-gray-50 dark:hover:bg-gray-700",
841
864
  children: option.label
@@ -1003,7 +1026,7 @@ function FlowNodePanel({
1003
1026
  return /* @__PURE__ */ jsxs8("div", { className: "fixed inset-y-0 right-0 w-96 bg-white dark:bg-gray-800 border-l border-gray-200 dark:border-gray-700 shadow-xl z-50 flex flex-col", children: [
1004
1027
  /* @__PURE__ */ jsxs8("div", { className: "flex items-center justify-between px-4 py-3 border-b border-gray-100 dark:border-gray-700", children: [
1005
1028
  /* @__PURE__ */ jsx9("h3", { className: "text-sm font-semibold text-gray-900 dark:text-gray-100", children: labels.nodePanel.title }),
1006
- /* @__PURE__ */ jsx9("button", { onClick: onClose, className: "text-gray-400 hover:text-gray-600", children: /* @__PURE__ */ jsx9(X2, { size: 18 }) })
1029
+ /* @__PURE__ */ jsx9("button", { "data-cv-tooltip": labels.nodePanel.close, "aria-label": labels.nodePanel.close, onClick: onClose, className: "text-gray-400 hover:text-gray-600", children: /* @__PURE__ */ jsx9(X2, { size: 18 }) })
1007
1030
  ] }),
1008
1031
  /* @__PURE__ */ jsxs8("div", { className: "flex-1 overflow-y-auto p-4 space-y-4", children: [
1009
1032
  nodeIssues.length > 0 && /* @__PURE__ */ jsx9("div", { className: "rounded-lg border border-gray-100 dark:border-gray-700 bg-gray-50 dark:bg-gray-900/40 p-2.5 space-y-1.5", children: nodeIssues.map((issue, i) => /* @__PURE__ */ jsx9(IssueRow, { issue }, i)) }),
@@ -1124,7 +1147,7 @@ function FlowNodePanel({
1124
1147
  (draft.questionType === "choice" || draft.type === "menu") && /* @__PURE__ */ jsxs8("div", { children: [
1125
1148
  /* @__PURE__ */ jsxs8("div", { className: "flex items-center justify-between mb-1.5", children: [
1126
1149
  /* @__PURE__ */ jsx9("label", { className: "text-xs font-medium text-gray-500 dark:text-gray-400", children: labels.nodePanel.options }),
1127
- /* @__PURE__ */ jsxs8("button", { onClick: addOption, className: "text-xs text-blue-600 hover:underline flex items-center gap-1", children: [
1150
+ /* @__PURE__ */ jsxs8("button", { "data-cv-tooltip": labels.nodePanel.addOption, "aria-label": labels.nodePanel.addOption, onClick: addOption, className: "text-xs text-blue-600 hover:underline flex items-center gap-1", children: [
1128
1151
  /* @__PURE__ */ jsx9(Plus2, { size: 12 }),
1129
1152
  " ",
1130
1153
  labels.nodePanel.addOption
@@ -1149,7 +1172,7 @@ function FlowNodePanel({
1149
1172
  className: `flex-1 ${INPUT_CLASSNAME}`
1150
1173
  }
1151
1174
  ),
1152
- /* @__PURE__ */ jsx9("button", { onClick: () => removeOption(i), className: "text-gray-400 hover:text-red-600", children: /* @__PURE__ */ jsx9(Trash2, { size: 14 }) })
1175
+ /* @__PURE__ */ jsx9("button", { "data-cv-tooltip": labels.nodePanel.removeOption, "aria-label": labels.nodePanel.removeOption, onClick: () => removeOption(i), className: "text-gray-400 hover:text-red-600", children: /* @__PURE__ */ jsx9(Trash2, { size: 14 }) })
1153
1176
  ] }, i)) })
1154
1177
  ] }),
1155
1178
  !isAction && /* @__PURE__ */ jsxs8("div", { className: "pt-2 border-t border-gray-100 dark:border-gray-700", children: [
@@ -1204,6 +1227,8 @@ function FlowNodePanel({
1204
1227
  /* @__PURE__ */ jsxs8(
1205
1228
  "button",
1206
1229
  {
1230
+ "data-cv-tooltip": labels.nodePanel.save,
1231
+ "aria-label": labels.nodePanel.save,
1207
1232
  onClick: () => onChange(draft),
1208
1233
  className: "flex-1 inline-flex items-center justify-center gap-2 rounded-lg bg-blue-600 px-4 py-2 text-sm font-medium text-white hover:bg-blue-700",
1209
1234
  children: [
@@ -1219,12 +1244,13 @@ function FlowNodePanel({
1219
1244
  onClick: () => {
1220
1245
  if (window.confirm(labels.nodePanel.deleteConfirm)) onDelete(node.id);
1221
1246
  },
1222
- title: labels.nodePanel.delete,
1247
+ "data-cv-tooltip": labels.nodePanel.delete,
1248
+ "aria-label": labels.nodePanel.delete,
1223
1249
  className: "px-3 py-2 text-sm text-red-600 dark:text-red-400 hover:bg-red-50 dark:hover:bg-red-950/30 rounded-lg",
1224
1250
  children: /* @__PURE__ */ jsx9(Trash2, { size: 14 })
1225
1251
  }
1226
1252
  ),
1227
- /* @__PURE__ */ jsx9("button", { onClick: onClose, className: "px-4 py-2 text-sm text-gray-600 dark:text-gray-300 hover:underline", children: labels.nodePanel.cancel })
1253
+ /* @__PURE__ */ jsx9("button", { "data-cv-tooltip": labels.nodePanel.cancel, "aria-label": labels.nodePanel.cancel, onClick: onClose, className: "px-4 py-2 text-sm text-gray-600 dark:text-gray-300 hover:underline", children: labels.nodePanel.cancel })
1228
1254
  ] })
1229
1255
  ] });
1230
1256
  }
@@ -1930,6 +1956,7 @@ function FlowsWorkspace({
1930
1956
  const canCreateFlow = Boolean(api.createFlow);
1931
1957
  const canDeleteFlow = Boolean(api.deleteFlow) && primaryFlowKey !== rootFlowKey;
1932
1958
  return /* @__PURE__ */ jsxs9("div", { className: `space-y-4 h-full flex flex-col ${className ?? ""}`, children: [
1959
+ /* @__PURE__ */ jsx10(TooltipLayer, {}),
1933
1960
  /* @__PURE__ */ jsxs9("div", { className: "flex items-center justify-between flex-wrap gap-3", children: [
1934
1961
  /* @__PURE__ */ jsxs9("div", { children: [
1935
1962
  /* @__PURE__ */ jsx10("h2", { className: "text-2xl font-bold text-gray-900 dark:text-gray-100", children: labels.workspace.title }),
@@ -1941,6 +1968,8 @@ function FlowsWorkspace({
1941
1968
  /* @__PURE__ */ jsxs9(
1942
1969
  "button",
1943
1970
  {
1971
+ "data-cv-tooltip": viewMode === "map" ? labels.flowMap.toggleToDetail : labels.flowMap.toggleToMap,
1972
+ "aria-label": viewMode === "map" ? labels.flowMap.toggleToDetail : labels.flowMap.toggleToMap,
1944
1973
  type: "button",
1945
1974
  onClick: () => setViewMode((mode) => mode === "map" ? "detail" : "map"),
1946
1975
  className: OUTLINE_BUTTON,
@@ -1957,7 +1986,8 @@ function FlowsWorkspace({
1957
1986
  type: "button",
1958
1987
  onClick: handleOrganize,
1959
1988
  className: OUTLINE_BUTTON,
1960
- title: labels.workspace.organizeTooltip,
1989
+ "data-cv-tooltip": labels.workspace.organizeTooltip,
1990
+ "aria-label": labels.workspace.organizeTooltip,
1961
1991
  disabled: !primaryGraph,
1962
1992
  children: [
1963
1993
  /* @__PURE__ */ jsx10(LayoutGrid, { size: 14, "aria-hidden": "true" }),
@@ -1972,7 +2002,8 @@ function FlowsWorkspace({
1972
2002
  type: "button",
1973
2003
  onClick: handleDiscardChanges,
1974
2004
  className: OUTLINE_BUTTON,
1975
- title: labels.workspace.discardTooltip,
2005
+ "data-cv-tooltip": labels.workspace.discardTooltip,
2006
+ "aria-label": labels.workspace.discardTooltip,
1976
2007
  disabled: !isDirty || saveState === "saving",
1977
2008
  children: [
1978
2009
  /* @__PURE__ */ jsx10(Undo2, { size: 14, "aria-hidden": "true" }),
@@ -1984,6 +2015,8 @@ function FlowsWorkspace({
1984
2015
  /* @__PURE__ */ jsxs9(
1985
2016
  "button",
1986
2017
  {
2018
+ "data-cv-tooltip": labels.workspace.saveGraph,
2019
+ "aria-label": labels.workspace.saveGraph,
1987
2020
  type: "button",
1988
2021
  onClick: () => void handlePublish(),
1989
2022
  className: PRIMARY_BUTTON,
@@ -2002,6 +2035,8 @@ function FlowsWorkspace({
2002
2035
  graphs && Object.values(graphs).map((graph) => /* @__PURE__ */ jsx10(
2003
2036
  "button",
2004
2037
  {
2038
+ "data-cv-tooltip": graph.label,
2039
+ "aria-label": graph.label,
2005
2040
  type: "button",
2006
2041
  onClick: () => focusFlow(graph.key),
2007
2042
  className: `px-3 py-1.5 rounded-full text-xs font-medium border transition-colors ${primaryFlowKey === graph.key ? "bg-blue-600 text-white border-blue-600" : "bg-white dark:bg-gray-800 text-gray-600 dark:text-gray-300 border-gray-200 dark:border-gray-700 hover:border-blue-300"}`,
@@ -2012,6 +2047,8 @@ function FlowsWorkspace({
2012
2047
  canCreateFlow && /* @__PURE__ */ jsxs9(
2013
2048
  "button",
2014
2049
  {
2050
+ "data-cv-tooltip": labels.flowManager.newFlow,
2051
+ "aria-label": labels.flowManager.newFlow,
2015
2052
  type: "button",
2016
2053
  onClick: () => {
2017
2054
  setFlowMutationState({ pending: false });
@@ -2038,6 +2075,8 @@ function FlowsWorkspace({
2038
2075
  primaryGraph && canDeleteFlow && /* @__PURE__ */ jsxs9(
2039
2076
  "button",
2040
2077
  {
2078
+ "data-cv-tooltip": labels.flowManager.deleteFlow,
2079
+ "aria-label": labels.flowManager.deleteFlow,
2041
2080
  type: "button",
2042
2081
  onClick: () => {
2043
2082
  setFlowMutationState({ pending: false });
@@ -2171,10 +2210,12 @@ function FlowsWorkspace({
2171
2210
  flowMutationState.error && /* @__PURE__ */ jsx10("p", { className: "text-xs text-red-600", children: flowMutationState.error })
2172
2211
  ] }),
2173
2212
  /* @__PURE__ */ jsxs9("div", { className: "flex justify-end gap-2 mt-4", children: [
2174
- /* @__PURE__ */ jsx10("button", { type: "button", className: OUTLINE_BUTTON, onClick: () => setShowCreateDialog(false), children: labels.nodePanel.cancel }),
2213
+ /* @__PURE__ */ jsx10("button", { "data-cv-tooltip": labels.nodePanel.cancel, "aria-label": labels.nodePanel.cancel, type: "button", className: OUTLINE_BUTTON, onClick: () => setShowCreateDialog(false), children: labels.nodePanel.cancel }),
2175
2214
  /* @__PURE__ */ jsx10(
2176
2215
  "button",
2177
2216
  {
2217
+ "data-cv-tooltip": labels.flowManager.create,
2218
+ "aria-label": labels.flowManager.create,
2178
2219
  type: "button",
2179
2220
  className: PRIMARY_BUTTON,
2180
2221
  onClick: () => void handleCreateFlow(),
@@ -2188,10 +2229,12 @@ function FlowsWorkspace({
2188
2229
  /* @__PURE__ */ jsx10("p", { className: "text-sm text-gray-600 dark:text-gray-300", children: primaryGraph ? labels.flowManager.deleteConfirm(primaryGraph.label) : "" }),
2189
2230
  flowMutationState.error && /* @__PURE__ */ jsx10("p", { className: "text-xs text-red-600 mt-2", children: flowMutationState.error }),
2190
2231
  /* @__PURE__ */ jsxs9("div", { className: "flex justify-end gap-2 mt-4", children: [
2191
- /* @__PURE__ */ jsx10("button", { type: "button", className: OUTLINE_BUTTON, onClick: () => setShowDeleteDialog(false), children: labels.nodePanel.cancel }),
2232
+ /* @__PURE__ */ jsx10("button", { "data-cv-tooltip": labels.nodePanel.cancel, "aria-label": labels.nodePanel.cancel, type: "button", className: OUTLINE_BUTTON, onClick: () => setShowDeleteDialog(false), children: labels.nodePanel.cancel }),
2192
2233
  /* @__PURE__ */ jsxs9(
2193
2234
  "button",
2194
2235
  {
2236
+ "data-cv-tooltip": labels.flowManager.deleteFlow,
2237
+ "aria-label": labels.flowManager.deleteFlow,
2195
2238
  type: "button",
2196
2239
  className: "inline-flex items-center gap-1.5 rounded-lg bg-red-600 px-3 py-1.5 text-xs font-medium text-white hover:bg-red-700 disabled:opacity-40",
2197
2240
  onClick: () => void handleDeleteFlow(),
package/dist/index.d.ts CHANGED
@@ -208,6 +208,7 @@ interface MessageComposerLabels {
208
208
  emoji: string;
209
209
  attach: string;
210
210
  send: string;
211
+ removeAttachment: string;
211
212
  }
212
213
  declare const DEFAULT_MESSAGE_COMPOSER_LABELS: MessageComposerLabels;
213
214
  interface MessageComposerProps {
@@ -269,6 +270,8 @@ interface RichComposerTooltips {
269
270
  attach: string;
270
271
  send: string;
271
272
  variables: string;
273
+ /** Botão que abre a formatação recolhida, quando a barra está estreita demais para os quatro. */
274
+ formatting: string;
272
275
  }
273
276
  declare const DEFAULT_RICH_COMPOSER_TOOLTIPS: RichComposerTooltips;
274
277
  /**
@@ -319,6 +322,12 @@ interface RichMessageComposerProps {
319
322
  idleAction?: ReactNode;
320
323
  /** Prévia dos anexos já escolhidos, desenhada pelo host acima da barra. */
321
324
  attachmentsPreview?: ReactNode;
325
+ /**
326
+ * Há anexo na fila esperando envio. O campo não conhece a fila — é do host — e sem essa dica ele
327
+ * concluía que não havia nada a enviar: com uma imagem anexada e nenhum texto, o botão de enviar
328
+ * dava lugar ao `idleAction` e a imagem ficava presa.
329
+ */
330
+ hasQueuedAttachments?: boolean;
322
331
  acceptedFileTypes?: string;
323
332
  className?: string;
324
333
  }
@@ -420,6 +429,22 @@ declare function ToastProvider({ children }: {
420
429
  }): react.JSX.Element;
421
430
  declare function useToast(): ToastContextValue;
422
431
 
432
+ /**
433
+ * Camada única de dicas do pacote.
434
+ *
435
+ * O `title` nativo existia em todos os botões e mesmo assim a dica "não aparecia": o navegador
436
+ * espera de 1 a 2 segundos antes de desenhar, o balão sai fora do tema e some ao menor movimento do
437
+ * mouse. Aqui a dica é do produto — aparece em 120ms, com o mesmo contraste do resto da interface.
438
+ *
439
+ * Um só ouvinte no documento atende a interface inteira: cada botão declara `data-cv-tooltip` e não
440
+ * precisa de estado, ref ou wrapper próprio. O balão é impresso em `document.body` via portal
441
+ * porque `overflow` de container (a régua de respostas rápidas rola na horizontal) recortaria um
442
+ * balão desenhado dentro do próprio botão.
443
+ */
444
+ /** Atributo que marca um elemento como portador de dica. */
445
+ declare const TOOLTIP_ATTRIBUTE = "data-cv-tooltip";
446
+ declare function TooltipLayer(): react.ReactPortal | null;
447
+
423
448
  interface StatusTicksProps {
424
449
  status: string;
425
450
  title?: string;
@@ -485,23 +510,23 @@ type ConversationWindow = (typeof CONVERSATION_WINDOW)[keyof typeof CONVERSATION
485
510
  declare const WINDOW_FILTERS: readonly [{
486
511
  readonly value: "all";
487
512
  readonly label: "Todas";
488
- readonly dotClass: "";
513
+ readonly tone: "";
489
514
  }, {
490
515
  readonly value: "fresh";
491
516
  readonly label: "<12h";
492
- readonly dotClass: "bg-green-500";
517
+ readonly tone: "fresh";
493
518
  }, {
494
519
  readonly value: "warning";
495
520
  readonly label: "12-21h";
496
- readonly dotClass: "bg-yellow-500";
521
+ readonly tone: "warning";
497
522
  }, {
498
523
  readonly value: "critical";
499
524
  readonly label: "21-24h";
500
- readonly dotClass: "bg-red-500";
525
+ readonly tone: "critical";
501
526
  }, {
502
527
  readonly value: "expired";
503
528
  readonly label: ">24h";
504
- readonly dotClass: "bg-gray-400";
529
+ readonly tone: "expired";
505
530
  }];
506
531
  type WindowOfParams = {
507
532
  readonly lastInboundAt: string | null;
@@ -577,8 +602,8 @@ interface ConversationHeaderClassNames {
577
602
  */
578
603
  interface ConversationHeaderUtility {
579
604
  key: string;
580
- /** Emoji, para casar com os utilitários nativos do cabeçalho. */
581
- icon: string;
605
+ /** Ícone da biblioteca (lucide), no tamanho dos utilitários nativos: `<Play size={16} />`. */
606
+ icon: ReactNode;
582
607
  label: string;
583
608
  run: () => void;
584
609
  active?: boolean;
@@ -1620,7 +1645,8 @@ interface ConversationsWorkspaceSimulator {
1620
1645
  }): ReactNode;
1621
1646
  /** Ausente = ligado. Serve para esconder fora de desenvolvimento sem condicionar o JSX. */
1622
1647
  readonly enabled?: boolean;
1623
- readonly icon?: string;
1648
+ /** Ícone da biblioteca (lucide) no utilitário do cabeçalho. Ausente, entra o frasco de teste. */
1649
+ readonly icon?: ReactNode;
1624
1650
  readonly label?: string;
1625
1651
  }
1626
1652
  interface ConversationsWorkspaceProps {
@@ -1675,7 +1701,8 @@ interface ConversationPaneProps {
1675
1701
  readonly now: number;
1676
1702
  readonly busy: boolean;
1677
1703
  readonly labels: ConversationsWorkspaceLabels;
1678
- readonly onTakeover?: (() => void) | undefined;
1704
+ /** Devolve a promessa quando o host a tem: o envio de template espera a tomada antes de sair. */
1705
+ readonly onTakeover?: (() => void | Promise<void>) | undefined;
1679
1706
  readonly onReturnToBot?: (() => void) | undefined;
1680
1707
  readonly onFinish?: (() => void) | undefined;
1681
1708
  readonly onBack: () => void;
@@ -1745,4 +1772,4 @@ interface ConversationsInboxListProps {
1745
1772
  }
1746
1773
  declare function ConversationsInboxList({ inbox, labels, className, renderFilters, renderBulkActions, renderRow, onSendTemplateToSelected, }: ConversationsInboxListProps): react.JSX.Element;
1747
1774
 
1748
- export { type AsyncResourceState, AudioPlayer, type AudioPlayerProps, AudioTranscription, type AudioTranscriptionProps, Avatar, type AvatarLabels, type AvatarProps, type BotMessages, type BuildTranscriptTextParams, BulkActionBar, type BulkActionBarProps, CHANNEL_BRAND_COLOR, CONVERSATIONS_PER_PAGE, CONVERSATION_WINDOW, ChannelFilter, ChannelFilterOption, ChannelIcon, type ChannelIconProps, ConversationChannel, type ConversationContextEntry, ConversationContextPanel, type ConversationContextPanelClassNames, type ConversationContextPanelLabels, type ConversationContextPanelProps, type ConversationContextStatus, ConversationDocument, ConversationDocumentsPanel, type ConversationDocumentsPanelClassNames, type ConversationDocumentsPanelLabels, type ConversationDocumentsPanelProps, ConversationHeader, type ConversationHeaderClassNames, type ConversationHeaderLabels, type ConversationHeaderProps, type ConversationHeaderUtility, ConversationListItem, type ConversationListItemLabels, type ConversationListItemProps, type ConversationLocales, ConversationLocalesProvider, type ConversationLocalesProviderProps, ConversationPane, type ConversationPaneProps, type ConversationRealtimeHandler, ConversationRow, type ConversationRowClassNames, type ConversationRowProps, ConversationSummary, ConversationTemplate, ConversationWallpaper, type ConversationWallpaperProps, type ConversationWindow, ConversationsApi, ConversationsFeatures, ConversationsInboxList, type ConversationsInboxListProps, ConversationsProvider, ConversationsWorkspace, type ConversationsWorkspaceLabels, type ConversationsWorkspaceProps, type ConversationsWorkspaceSimulator, DEFAULT_ACCEPTED_FILE_TYPES, DEFAULT_AVATAR_LABELS, DEFAULT_CONVERSATIONS_WORKSPACE_LABELS, DEFAULT_CONVERSATION_CONTEXT_LABELS, DEFAULT_CONVERSATION_DOCUMENTS_LABELS, DEFAULT_CONVERSATION_HEADER_LABELS, DEFAULT_CONVERSATION_LIST_ITEM_LABELS, DEFAULT_DOCUMENTS_LIBRARY_LABELS, DEFAULT_DOCUMENTS_WORKSPACE_LABELS, DEFAULT_EMOJI_PICKER_LABELS, DEFAULT_INTERACTIVE_MESSAGE_LABELS, DEFAULT_LIGHTBOX_LABELS, DEFAULT_MESSAGE_COMPOSER_LABELS, DEFAULT_RICH_COMPOSER_TOOLTIPS, DEFAULT_TEMPLATES_SETTINGS_LABELS, DEFAULT_WHATSAPP_MESSAGE_EDITOR_LABELS, DEFAULT_WINDOW_EXPIRED_LABELS, DOCUMENT_SOURCE_FILTER, DateDivider, type DateDividerClassNames, type DateDividerProps, type DocumentSourceFilter, type DocumentsFiltersContext, DocumentsLibrary, type DocumentsLibraryClassNames, type DocumentsLibraryLabels, type DocumentsLibraryProps, DocumentsWorkspace, type DocumentsWorkspaceClassNames, type DocumentsWorkspaceLabels, type DocumentsWorkspaceProps, EMOJI_CATEGORIES, type EmojiCategory, type EmojiEntry, EmojiPicker, type EmojiPickerLabels, type EmojiPickerProps, FileIcon, type FileIconProps, type FilterOption, InteractiveMessage, type InteractiveMessageLabels, type InteractiveMessageProps, InteractivePayload, InteractiveSelection, Lightbox, type LightboxLabels, type LightboxProps, ListConversationsParams, ListDocumentsParams, ListingPagination, type ListingPaginationProps, MessageBubble, type MessageBubbleProps, MessageComposer, type MessageComposerClassNames, type MessageComposerLabels, type MessageComposerProps, MessagePayload, MessageTail, MessageText, type MessageTextProps, MessageTimestamp, MessageTranscription, MessagesWorkspace, type MessagesWorkspaceApi, type MessagesWorkspaceLabels, type MessagesWorkspaceProps, MultiSelectFilter, type MultiSelectFilterProps, NARROW_MAX_WIDTH_PX, type QuickReply, RICH_COMPOSER_ACTION, ResolveMediaUrl, type RichComposerAction, type RichComposerQuickReply, type RichComposerTooltips, type RichComposerVariable, RichMessageComposer, type RichMessageComposerHandle, type RichMessageComposerProps, SSEProvider, SimpleEmojiPicker, type SimpleEmojiPickerProps, type SortDirection, SortableHead, type SortableHeadProps, StatusTicks, type StatusTicksProps, TEMPLATE_SETTINGS_TAB, type TemplateSettings, type TemplateSettingsTab, ToastProvider, type TopicItem, TopicsForm, type TopicsFormLabels, type TopicsFormProps, TranscriptionMode, type TranscriptionSettings, TranscriptionSettingsForm, type TranscriptionSettingsFormLabels, type TranscriptionSettingsFormProps, type UrlStateOptions, type UseConversationActionsResult, type UseConversationContextResult, type UseConversationDocumentsParams, type UseConversationDocumentsResult, type UseConversationListParams, type UseConversationListResult, type UseConversationMessagesResult, type UseConversationsInboxParams, type UseConversationsInboxResult, type UseInboxActionsResult, type UseScrollToLatestMessageParams, type UseScrollToLatestMessageResult, type UseWaitingNotificationsLabels, type UseWaitingNotificationsParams, type UseWaitingNotificationsResult, WINDOW_FILTERS, WelcomeFarewellForm, type WelcomeFarewellFormLabels, type WelcomeFarewellFormProps, WhatsAppCreateTemplateForm, type WhatsAppCreateTemplateFormLabels, type WhatsAppCreateTemplateFormProps, type WhatsAppCreateTemplateResult, type WhatsAppCreateTemplateState, WhatsAppMessageEditor, type WhatsAppMessageEditorLabels, type WhatsAppMessageEditorProps, type WhatsAppTemplateHeaderType, WhatsAppTemplateSettingsForm, type WhatsAppTemplateSettingsFormLabels, type WhatsAppTemplateSettingsFormProps, type WhatsAppTemplateSummary, type WhatsAppTemplateVariableSuggestion, WhatsAppTemplatesSettings, type WhatsAppTemplatesSettingsLabels, type WhatsAppTemplatesSettingsProps, WindowExpiredNotice, type WindowExpiredNoticeLabels, type WindowExpiredNoticeProps, type WindowOfParams, applyQuickReplyVariables, buildTranscriptFilename, buildTranscriptText, createMediaUrlResolver, downloadTextFile, formatDateTime, formatFileSize, formatPhone, formatStalledFor, formatTimestamp, htmlToWA, isSameDay, isWindowBlocking, parseWhatsAppFormatting, phoneInitials, resolveQuickReply, searchEmojis, toast, useConversationActions, useConversationContext, useConversationDocuments, useConversationList, useConversationLocales, useConversationMessages, useConversationRealtime, useConversations, useConversationsInbox, useDarkMode, useDebouncedValue, useGlobalRealtime, useInboxActions, useIsDarkTheme, useIsNarrow, useScrollToLatestMessage, useToast, useUrlArrayState, useUrlNumberState, useUrlStringState, useWaitingNotifications, waToHTML, waToHTMLInline, windowOf };
1775
+ export { type AsyncResourceState, AudioPlayer, type AudioPlayerProps, AudioTranscription, type AudioTranscriptionProps, Avatar, type AvatarLabels, type AvatarProps, type BotMessages, type BuildTranscriptTextParams, BulkActionBar, type BulkActionBarProps, CHANNEL_BRAND_COLOR, CONVERSATIONS_PER_PAGE, CONVERSATION_WINDOW, ChannelFilter, ChannelFilterOption, ChannelIcon, type ChannelIconProps, ConversationChannel, type ConversationContextEntry, ConversationContextPanel, type ConversationContextPanelClassNames, type ConversationContextPanelLabels, type ConversationContextPanelProps, type ConversationContextStatus, ConversationDocument, ConversationDocumentsPanel, type ConversationDocumentsPanelClassNames, type ConversationDocumentsPanelLabels, type ConversationDocumentsPanelProps, ConversationHeader, type ConversationHeaderClassNames, type ConversationHeaderLabels, type ConversationHeaderProps, type ConversationHeaderUtility, ConversationListItem, type ConversationListItemLabels, type ConversationListItemProps, type ConversationLocales, ConversationLocalesProvider, type ConversationLocalesProviderProps, ConversationPane, type ConversationPaneProps, type ConversationRealtimeHandler, ConversationRow, type ConversationRowClassNames, type ConversationRowProps, ConversationSummary, ConversationTemplate, ConversationWallpaper, type ConversationWallpaperProps, type ConversationWindow, ConversationsApi, ConversationsFeatures, ConversationsInboxList, type ConversationsInboxListProps, ConversationsProvider, ConversationsWorkspace, type ConversationsWorkspaceLabels, type ConversationsWorkspaceProps, type ConversationsWorkspaceSimulator, DEFAULT_ACCEPTED_FILE_TYPES, DEFAULT_AVATAR_LABELS, DEFAULT_CONVERSATIONS_WORKSPACE_LABELS, DEFAULT_CONVERSATION_CONTEXT_LABELS, DEFAULT_CONVERSATION_DOCUMENTS_LABELS, DEFAULT_CONVERSATION_HEADER_LABELS, DEFAULT_CONVERSATION_LIST_ITEM_LABELS, DEFAULT_DOCUMENTS_LIBRARY_LABELS, DEFAULT_DOCUMENTS_WORKSPACE_LABELS, DEFAULT_EMOJI_PICKER_LABELS, DEFAULT_INTERACTIVE_MESSAGE_LABELS, DEFAULT_LIGHTBOX_LABELS, DEFAULT_MESSAGE_COMPOSER_LABELS, DEFAULT_RICH_COMPOSER_TOOLTIPS, DEFAULT_TEMPLATES_SETTINGS_LABELS, DEFAULT_WHATSAPP_MESSAGE_EDITOR_LABELS, DEFAULT_WINDOW_EXPIRED_LABELS, DOCUMENT_SOURCE_FILTER, DateDivider, type DateDividerClassNames, type DateDividerProps, type DocumentSourceFilter, type DocumentsFiltersContext, DocumentsLibrary, type DocumentsLibraryClassNames, type DocumentsLibraryLabels, type DocumentsLibraryProps, DocumentsWorkspace, type DocumentsWorkspaceClassNames, type DocumentsWorkspaceLabels, type DocumentsWorkspaceProps, EMOJI_CATEGORIES, type EmojiCategory, type EmojiEntry, EmojiPicker, type EmojiPickerLabels, type EmojiPickerProps, FileIcon, type FileIconProps, type FilterOption, InteractiveMessage, type InteractiveMessageLabels, type InteractiveMessageProps, InteractivePayload, InteractiveSelection, Lightbox, type LightboxLabels, type LightboxProps, ListConversationsParams, ListDocumentsParams, ListingPagination, type ListingPaginationProps, MessageBubble, type MessageBubbleProps, MessageComposer, type MessageComposerClassNames, type MessageComposerLabels, type MessageComposerProps, MessagePayload, MessageTail, MessageText, type MessageTextProps, MessageTimestamp, MessageTranscription, MessagesWorkspace, type MessagesWorkspaceApi, type MessagesWorkspaceLabels, type MessagesWorkspaceProps, MultiSelectFilter, type MultiSelectFilterProps, NARROW_MAX_WIDTH_PX, type QuickReply, RICH_COMPOSER_ACTION, ResolveMediaUrl, type RichComposerAction, type RichComposerQuickReply, type RichComposerTooltips, type RichComposerVariable, RichMessageComposer, type RichMessageComposerHandle, type RichMessageComposerProps, SSEProvider, SimpleEmojiPicker, type SimpleEmojiPickerProps, type SortDirection, SortableHead, type SortableHeadProps, StatusTicks, type StatusTicksProps, TEMPLATE_SETTINGS_TAB, TOOLTIP_ATTRIBUTE, type TemplateSettings, type TemplateSettingsTab, ToastProvider, TooltipLayer, type TopicItem, TopicsForm, type TopicsFormLabels, type TopicsFormProps, TranscriptionMode, type TranscriptionSettings, TranscriptionSettingsForm, type TranscriptionSettingsFormLabels, type TranscriptionSettingsFormProps, type UrlStateOptions, type UseConversationActionsResult, type UseConversationContextResult, type UseConversationDocumentsParams, type UseConversationDocumentsResult, type UseConversationListParams, type UseConversationListResult, type UseConversationMessagesResult, type UseConversationsInboxParams, type UseConversationsInboxResult, type UseInboxActionsResult, type UseScrollToLatestMessageParams, type UseScrollToLatestMessageResult, type UseWaitingNotificationsLabels, type UseWaitingNotificationsParams, type UseWaitingNotificationsResult, WINDOW_FILTERS, WelcomeFarewellForm, type WelcomeFarewellFormLabels, type WelcomeFarewellFormProps, WhatsAppCreateTemplateForm, type WhatsAppCreateTemplateFormLabels, type WhatsAppCreateTemplateFormProps, type WhatsAppCreateTemplateResult, type WhatsAppCreateTemplateState, WhatsAppMessageEditor, type WhatsAppMessageEditorLabels, type WhatsAppMessageEditorProps, type WhatsAppTemplateHeaderType, WhatsAppTemplateSettingsForm, type WhatsAppTemplateSettingsFormLabels, type WhatsAppTemplateSettingsFormProps, type WhatsAppTemplateSummary, type WhatsAppTemplateVariableSuggestion, WhatsAppTemplatesSettings, type WhatsAppTemplatesSettingsLabels, type WhatsAppTemplatesSettingsProps, WindowExpiredNotice, type WindowExpiredNoticeLabels, type WindowExpiredNoticeProps, type WindowOfParams, applyQuickReplyVariables, buildTranscriptFilename, buildTranscriptText, createMediaUrlResolver, downloadTextFile, formatDateTime, formatFileSize, formatPhone, formatStalledFor, formatTimestamp, htmlToWA, isSameDay, isWindowBlocking, parseWhatsAppFormatting, phoneInitials, resolveQuickReply, searchEmojis, toast, useConversationActions, useConversationContext, useConversationDocuments, useConversationList, useConversationLocales, useConversationMessages, useConversationRealtime, useConversations, useConversationsInbox, useDarkMode, useDebouncedValue, useGlobalRealtime, useInboxActions, useIsDarkTheme, useIsNarrow, useScrollToLatestMessage, useToast, useUrlArrayState, useUrlNumberState, useUrlStringState, useWaitingNotifications, waToHTML, waToHTMLInline, windowOf };