@adatechnology/conversations-ui 0.1.0-rc.3 → 0.1.0-rc.4

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.
@@ -18,7 +18,14 @@ var DEFAULT_LOCALES = {
18
18
  viewImage: "Ver imagem",
19
19
  listenAudio: "Ouvir \xE1udio",
20
20
  viewVideo: "Ver v\xEDdeo",
21
- moderationFlagged: "Linguagem ofensiva"
21
+ moderationFlagged: "Linguagem ofensiva",
22
+ mediaLoading: "Carregando...",
23
+ mediaRetry: "Erro \u2014 tentar novamente",
24
+ mediaError: "Erro",
25
+ mediaUnavailable: "M\xEDdia indispon\xEDvel",
26
+ imageAlt: "Imagem",
27
+ untitledDocument: "Documento",
28
+ downloadFile: "Baixar"
22
29
  },
23
30
  selection: {
24
31
  select: "Selecionar"
@@ -254,9 +261,9 @@ function MediaRenderer({ message, onLightbox, onResolveUrl }) {
254
261
  case "image":
255
262
  case "sticker": {
256
263
  if (!src && canLazyLoad) {
257
- return /* @__PURE__ */ jsx5("button", { onClick: lazy.load, className: lazyButtonClass, children: lazy.loading ? "Carregando..." : lazy.error ? "Erro \u2014 tentar novamente" : bubble.viewImage });
264
+ return /* @__PURE__ */ jsx5("button", { onClick: lazy.load, className: lazyButtonClass, children: lazy.loading ? bubble.mediaLoading : lazy.error ? bubble.mediaRetry : bubble.viewImage });
258
265
  }
259
- return /* @__PURE__ */ jsx5("div", { className: "min-w-[200px]", children: src ? /* @__PURE__ */ jsx5("img", { src, alt: message.caption ?? "Image", className: "w-full max-h-80 object-cover cursor-pointer hover:opacity-90 transition-opacity", onClick: () => onLightbox(src), loading: "lazy" }) : /* @__PURE__ */ jsx5("div", { className: "w-full h-40 bg-gray-200 flex items-center justify-center text-gray-400", children: /* @__PURE__ */ jsxs3("svg", { width: "32", height: "32", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "1.5", children: [
266
+ return /* @__PURE__ */ jsx5("div", { className: "min-w-[200px]", children: src ? /* @__PURE__ */ jsx5("img", { src, alt: message.caption ?? bubble.imageAlt, className: "w-full max-h-80 object-cover cursor-pointer hover:opacity-90 transition-opacity", onClick: () => onLightbox(src), loading: "lazy" }) : /* @__PURE__ */ jsx5("div", { className: "w-full h-40 bg-gray-200 flex items-center justify-center text-gray-400", children: /* @__PURE__ */ jsxs3("svg", { width: "32", height: "32", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "1.5", children: [
260
267
  /* @__PURE__ */ jsx5("rect", { x: "3", y: "3", width: "18", height: "18", rx: "2", ry: "2" }),
261
268
  /* @__PURE__ */ jsx5("circle", { cx: "8.5", cy: "8.5", r: "1.5" }),
262
269
  /* @__PURE__ */ jsx5("polyline", { points: "21 15 16 10 5 21" })
@@ -264,7 +271,7 @@ function MediaRenderer({ message, onLightbox, onResolveUrl }) {
264
271
  }
265
272
  case "video": {
266
273
  if (!src && canLazyLoad) {
267
- return /* @__PURE__ */ jsx5("button", { onClick: lazy.load, className: lazyButtonClass, children: lazy.loading ? "Carregando..." : lazy.error ? "Erro \u2014 tentar novamente" : bubble.viewVideo });
274
+ return /* @__PURE__ */ jsx5("button", { onClick: lazy.load, className: lazyButtonClass, children: lazy.loading ? bubble.mediaLoading : lazy.error ? bubble.mediaRetry : bubble.viewVideo });
268
275
  }
269
276
  return /* @__PURE__ */ jsx5("div", { className: "min-w-[200px]", children: src ? /* @__PURE__ */ jsx5("video", { src, className: "w-full max-h-80 rounded-lg", controls: true, preload: "metadata", children: /* @__PURE__ */ jsx5("track", { kind: "captions" }) }) : /* @__PURE__ */ jsx5("div", { className: "w-full h-32 bg-gray-200 rounded-lg flex items-center justify-center text-gray-400", children: /* @__PURE__ */ jsxs3("svg", { width: "32", height: "32", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "1.5", children: [
270
277
  /* @__PURE__ */ jsx5("polygon", { points: "23 7 16 12 23 17 23 7" }),
@@ -273,9 +280,9 @@ function MediaRenderer({ message, onLightbox, onResolveUrl }) {
273
280
  }
274
281
  case "audio": {
275
282
  if (!src && canLazyLoad) {
276
- return /* @__PURE__ */ jsx5("button", { onClick: lazy.load, className: lazyButtonClass, children: lazy.loading ? "Carregando..." : lazy.error ? "Erro \u2014 tentar novamente" : bubble.listenAudio });
283
+ return /* @__PURE__ */ jsx5("button", { onClick: lazy.load, className: lazyButtonClass, children: lazy.loading ? bubble.mediaLoading : lazy.error ? bubble.mediaRetry : bubble.listenAudio });
277
284
  }
278
- return /* @__PURE__ */ jsx5("div", { className: "min-w-[200px]", children: src ? /* @__PURE__ */ jsx5(AudioPlayer, { src, isMine: message.direction === "outbound" }) : /* @__PURE__ */ jsx5("div", { className: "h-12 bg-gray-200 rounded-lg flex items-center justify-center text-gray-400 text-xs", children: "Audio unavailable" }) });
285
+ return /* @__PURE__ */ jsx5("div", { className: "min-w-[200px]", children: src ? /* @__PURE__ */ jsx5(AudioPlayer, { src, isMine: message.direction === "outbound" }) : /* @__PURE__ */ jsx5("div", { className: "h-12 bg-gray-200 rounded-lg flex items-center justify-center text-gray-400 text-xs", children: bubble.mediaUnavailable }) });
279
286
  }
280
287
  case "document": {
281
288
  const typeLabel = message.mimeType?.split("/")[1]?.toUpperCase() ?? "FILE";
@@ -283,10 +290,10 @@ function MediaRenderer({ message, onLightbox, onResolveUrl }) {
283
290
  return /* @__PURE__ */ jsxs3("div", { className: "flex items-center gap-3 min-w-[200px]", children: [
284
291
  /* @__PURE__ */ jsx5("div", { className: "w-10 h-10 bg-gray-200 rounded-lg flex items-center justify-center flex-shrink-0", children: /* @__PURE__ */ jsx5(FileIcon, { filename: message.filename, mimeType: message.mimeType }) }),
285
292
  /* @__PURE__ */ jsxs3("div", { className: "flex-1 min-w-0", children: [
286
- /* @__PURE__ */ jsx5("p", { className: "text-sm font-medium truncate", children: message.filename ?? "Document" }),
293
+ /* @__PURE__ */ jsx5("p", { className: "text-sm font-medium truncate", children: message.filename ?? bubble.untitledDocument }),
287
294
  /* @__PURE__ */ jsx5("p", { className: "text-xs text-gray-500", children: sizeLabel ? `${typeLabel} \xB7 ${sizeLabel}` : typeLabel })
288
295
  ] }),
289
- src ? /* @__PURE__ */ jsx5("a", { href: src, download: message.filename, className: "w-8 h-8 flex items-center justify-center rounded-full bg-gray-200 hover:bg-gray-300 flex-shrink-0 transition-colors", "aria-label": "Download", children: /* @__PURE__ */ jsxs3("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", className: "text-gray-600", children: [
296
+ src ? /* @__PURE__ */ jsx5("a", { href: src, download: message.filename, className: "w-8 h-8 flex items-center justify-center rounded-full bg-gray-200 hover:bg-gray-300 flex-shrink-0 transition-colors", "aria-label": bubble.downloadFile, children: /* @__PURE__ */ jsxs3("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", className: "text-gray-600", children: [
290
297
  /* @__PURE__ */ jsx5("path", { d: "M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4" }),
291
298
  /* @__PURE__ */ jsx5("polyline", { points: "7 10 12 15 17 10" }),
292
299
  /* @__PURE__ */ jsx5("line", { x1: "12", y1: "15", x2: "12", y2: "3" })
@@ -296,7 +303,7 @@ function MediaRenderer({ message, onLightbox, onResolveUrl }) {
296
303
  onClick: lazy.load,
297
304
  disabled: lazy.loading,
298
305
  className: "w-8 h-8 flex items-center justify-center rounded-full bg-gray-200 hover:bg-gray-300 flex-shrink-0 transition-colors disabled:opacity-50",
299
- "aria-label": "Download",
306
+ "aria-label": bubble.downloadFile,
300
307
  children: /* @__PURE__ */ jsxs3("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", className: "text-gray-600", children: [
301
308
  /* @__PURE__ */ jsx5("path", { d: "M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4" }),
302
309
  /* @__PURE__ */ jsx5("polyline", { points: "7 10 12 15 17 10" }),
@@ -304,7 +311,7 @@ function MediaRenderer({ message, onLightbox, onResolveUrl }) {
304
311
  ] })
305
312
  }
306
313
  ) : null,
307
- lazy.error && /* @__PURE__ */ jsx5("span", { className: "text-xs text-red-500 flex-shrink-0", children: "Erro" })
314
+ lazy.error && /* @__PURE__ */ jsx5("span", { className: "text-xs text-red-500 flex-shrink-0", children: bubble.mediaError })
308
315
  ] });
309
316
  }
310
317
  default:
package/dist/index.d.ts CHANGED
@@ -44,6 +44,13 @@ interface ConversationLocales {
44
44
  listenAudio: string;
45
45
  viewVideo: string;
46
46
  moderationFlagged: string;
47
+ mediaLoading: string;
48
+ mediaRetry: string;
49
+ mediaError: string;
50
+ mediaUnavailable: string;
51
+ imageAlt: string;
52
+ untitledDocument: string;
53
+ downloadFile: string;
47
54
  };
48
55
  selection: {
49
56
  select: string;
package/dist/index.js CHANGED
@@ -18,7 +18,7 @@ import {
18
18
  formatFileSize,
19
19
  formatTimestamp,
20
20
  useConversationLocales
21
- } from "./chunk-N7B24WYD.js";
21
+ } from "./chunk-4R6Y43DQ.js";
22
22
  import {
23
23
  htmlToWA,
24
24
  parseWhatsAppFormatting,
@@ -3,7 +3,7 @@ import {
3
3
  DateDivider,
4
4
  MessageBubble,
5
5
  MessageComposer
6
- } from "../chunk-N7B24WYD.js";
6
+ } from "../chunk-4R6Y43DQ.js";
7
7
  import "../chunk-OGRRHQQW.js";
8
8
 
9
9
  // src/preview/previewStore.ts
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adatechnology/conversations-ui",
3
- "version": "0.1.0-rc.3",
3
+ "version": "0.1.0-rc.4",
4
4
  "description": "WhatsApp conversation UI components — parametrizável por endpoint, tema e feature flags",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -31,7 +31,7 @@
31
31
  "clsx": "^2.1.1",
32
32
  "lucide-react": "^1.21.0",
33
33
  "tailwind-merge": "^3.6.0",
34
- "@adatechnology/meta-whatsapp-contracts": "0.2.0-rc.3"
34
+ "@adatechnology/meta-whatsapp-contracts": "0.2.0-rc.4"
35
35
  },
36
36
  "peerDependencies": {
37
37
  "react": "^18 || ^19",
@@ -14,6 +14,13 @@ export interface ConversationLocales {
14
14
  listenAudio: string
15
15
  viewVideo: string
16
16
  moderationFlagged: string
17
+ mediaLoading: string
18
+ mediaRetry: string
19
+ mediaError: string
20
+ mediaUnavailable: string
21
+ imageAlt: string
22
+ untitledDocument: string
23
+ downloadFile: string
17
24
  }
18
25
  selection: {
19
26
  select: string
@@ -38,6 +45,13 @@ const DEFAULT_LOCALES: ConversationLocales = {
38
45
  listenAudio: 'Ouvir áudio',
39
46
  viewVideo: 'Ver vídeo',
40
47
  moderationFlagged: 'Linguagem ofensiva',
48
+ mediaLoading: 'Carregando...',
49
+ mediaRetry: 'Erro — tentar novamente',
50
+ mediaError: 'Erro',
51
+ mediaUnavailable: 'Mídia indisponível',
52
+ imageAlt: 'Imagem',
53
+ untitledDocument: 'Documento',
54
+ downloadFile: 'Baixar',
41
55
  },
42
56
  selection: {
43
57
  select: 'Selecionar',
@@ -70,14 +70,14 @@ export function MediaRenderer({ message, onLightbox, onResolveUrl }: MediaRender
70
70
  if (!src && canLazyLoad) {
71
71
  return (
72
72
  <button onClick={lazy.load} className={lazyButtonClass}>
73
- {lazy.loading ? 'Carregando...' : lazy.error ? 'Erro — tentar novamente' : bubble.viewImage}
73
+ {lazy.loading ? bubble.mediaLoading : lazy.error ? bubble.mediaRetry : bubble.viewImage}
74
74
  </button>
75
75
  )
76
76
  }
77
77
  return (
78
78
  <div className="min-w-[200px]">
79
79
  {src ? (
80
- <img src={src} alt={message.caption ?? 'Image'} className="w-full max-h-80 object-cover cursor-pointer hover:opacity-90 transition-opacity" onClick={() => onLightbox(src)} loading="lazy" />
80
+ <img src={src} alt={message.caption ?? bubble.imageAlt} className="w-full max-h-80 object-cover cursor-pointer hover:opacity-90 transition-opacity" onClick={() => onLightbox(src)} loading="lazy" />
81
81
  ) : (
82
82
  <div className="w-full h-40 bg-gray-200 flex items-center justify-center text-gray-400">
83
83
  <svg width="32" height="32" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5"><rect x="3" y="3" width="18" height="18" rx="2" ry="2" /><circle cx="8.5" cy="8.5" r="1.5" /><polyline points="21 15 16 10 5 21" /></svg>
@@ -90,7 +90,7 @@ export function MediaRenderer({ message, onLightbox, onResolveUrl }: MediaRender
90
90
  if (!src && canLazyLoad) {
91
91
  return (
92
92
  <button onClick={lazy.load} className={lazyButtonClass}>
93
- {lazy.loading ? 'Carregando...' : lazy.error ? 'Erro — tentar novamente' : bubble.viewVideo}
93
+ {lazy.loading ? bubble.mediaLoading : lazy.error ? bubble.mediaRetry : bubble.viewVideo}
94
94
  </button>
95
95
  )
96
96
  }
@@ -110,14 +110,14 @@ export function MediaRenderer({ message, onLightbox, onResolveUrl }: MediaRender
110
110
  if (!src && canLazyLoad) {
111
111
  return (
112
112
  <button onClick={lazy.load} className={lazyButtonClass}>
113
- {lazy.loading ? 'Carregando...' : lazy.error ? 'Erro — tentar novamente' : bubble.listenAudio}
113
+ {lazy.loading ? bubble.mediaLoading : lazy.error ? bubble.mediaRetry : bubble.listenAudio}
114
114
  </button>
115
115
  )
116
116
  }
117
117
  return (
118
118
  <div className="min-w-[200px]">
119
119
  {src ? <AudioPlayer src={src} isMine={message.direction === 'outbound'} /> : (
120
- <div className="h-12 bg-gray-200 rounded-lg flex items-center justify-center text-gray-400 text-xs">Audio unavailable</div>
120
+ <div className="h-12 bg-gray-200 rounded-lg flex items-center justify-center text-gray-400 text-xs">{bubble.mediaUnavailable}</div>
121
121
  )}
122
122
  </div>
123
123
  )
@@ -131,11 +131,11 @@ export function MediaRenderer({ message, onLightbox, onResolveUrl }: MediaRender
131
131
  <FileIcon filename={message.filename} mimeType={message.mimeType} />
132
132
  </div>
133
133
  <div className="flex-1 min-w-0">
134
- <p className="text-sm font-medium truncate">{message.filename ?? 'Document'}</p>
134
+ <p className="text-sm font-medium truncate">{message.filename ?? bubble.untitledDocument}</p>
135
135
  <p className="text-xs text-gray-500">{sizeLabel ? `${typeLabel} · ${sizeLabel}` : typeLabel}</p>
136
136
  </div>
137
137
  {src ? (
138
- <a href={src} download={message.filename} className="w-8 h-8 flex items-center justify-center rounded-full bg-gray-200 hover:bg-gray-300 flex-shrink-0 transition-colors" aria-label="Download">
138
+ <a href={src} download={message.filename} className="w-8 h-8 flex items-center justify-center rounded-full bg-gray-200 hover:bg-gray-300 flex-shrink-0 transition-colors" aria-label={bubble.downloadFile}>
139
139
  <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" className="text-gray-600"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4" /><polyline points="7 10 12 15 17 10" /><line x1="12" y1="15" x2="12" y2="3" /></svg>
140
140
  </a>
141
141
  ) : canLazyLoad ? (
@@ -143,12 +143,12 @@ export function MediaRenderer({ message, onLightbox, onResolveUrl }: MediaRender
143
143
  onClick={lazy.load}
144
144
  disabled={lazy.loading}
145
145
  className="w-8 h-8 flex items-center justify-center rounded-full bg-gray-200 hover:bg-gray-300 flex-shrink-0 transition-colors disabled:opacity-50"
146
- aria-label="Download"
146
+ aria-label={bubble.downloadFile}
147
147
  >
148
148
  <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" className="text-gray-600"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4" /><polyline points="7 10 12 15 17 10" /><line x1="12" y1="15" x2="12" y2="3" /></svg>
149
149
  </button>
150
150
  ) : null}
151
- {lazy.error && <span className="text-xs text-red-500 flex-shrink-0">Erro</span>}
151
+ {lazy.error && <span className="text-xs text-red-500 flex-shrink-0">{bubble.mediaError}</span>}
152
152
  </div>
153
153
  )
154
154
  }