@adatechnology/conversations-ui 0.1.0-rc.8 → 0.1.0-rc.9
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.
- package/dist/{chunk-OGRRHQQW.js → chunk-2AYDBWNE.js} +55 -1
- package/dist/{chunk-73MW5HNT.js → chunk-G5BM3VBP.js} +29 -4
- package/dist/flows/index.js +2 -4
- package/dist/index.d.ts +4 -2
- package/dist/index.js +4 -6
- package/dist/preview/index.js +2 -2
- package/package.json +1 -1
- package/src/Wallpaper.test.tsx +21 -0
- package/src/Wallpaper.tsx +52 -6
- package/dist/chunk-NV2RZ5KT.js +0 -56
|
@@ -151,9 +151,63 @@ function waToHTMLInline(text) {
|
|
|
151
151
|
return escapeHtml(text).replace(/\*([^*\n]+)\*/g, "<strong>$1</strong>").replace(/_([^_\n]+)_/g, "<em>$1</em>").replace(/~([^~\n]+)~/g, "<del>$1</del>").replace(/`([^`\n]+)`/g, "<code>$1</code>");
|
|
152
152
|
}
|
|
153
153
|
|
|
154
|
+
// src/useDarkMode.ts
|
|
155
|
+
import { useState, useEffect, useCallback } from "react";
|
|
156
|
+
var STORAGE_KEY = "conversations-ui-dark-mode";
|
|
157
|
+
function getInitialDark() {
|
|
158
|
+
if (typeof window === "undefined") return false;
|
|
159
|
+
const stored = localStorage.getItem(STORAGE_KEY);
|
|
160
|
+
if (stored !== null) {
|
|
161
|
+
return stored === "true";
|
|
162
|
+
}
|
|
163
|
+
return window.matchMedia("(prefers-color-scheme: dark)").matches;
|
|
164
|
+
}
|
|
165
|
+
function useIsDarkTheme() {
|
|
166
|
+
const [isDark, setIsDark] = useState(
|
|
167
|
+
() => typeof document !== "undefined" && document.documentElement.classList.contains("dark")
|
|
168
|
+
);
|
|
169
|
+
useEffect(() => {
|
|
170
|
+
const root = document.documentElement;
|
|
171
|
+
const observer = new MutationObserver(() => setIsDark(root.classList.contains("dark")));
|
|
172
|
+
observer.observe(root, { attributes: true, attributeFilter: ["class"] });
|
|
173
|
+
setIsDark(root.classList.contains("dark"));
|
|
174
|
+
return () => observer.disconnect();
|
|
175
|
+
}, []);
|
|
176
|
+
return isDark;
|
|
177
|
+
}
|
|
178
|
+
function useDarkMode() {
|
|
179
|
+
const [isDark, setIsDark] = useState(getInitialDark);
|
|
180
|
+
useEffect(() => {
|
|
181
|
+
const root = document.documentElement;
|
|
182
|
+
if (isDark) {
|
|
183
|
+
root.classList.add("dark");
|
|
184
|
+
} else {
|
|
185
|
+
root.classList.remove("dark");
|
|
186
|
+
}
|
|
187
|
+
localStorage.setItem(STORAGE_KEY, String(isDark));
|
|
188
|
+
}, [isDark]);
|
|
189
|
+
useEffect(() => {
|
|
190
|
+
const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)");
|
|
191
|
+
const handleChange = (event) => {
|
|
192
|
+
const stored = localStorage.getItem(STORAGE_KEY);
|
|
193
|
+
if (stored === null) {
|
|
194
|
+
setIsDark(event.matches);
|
|
195
|
+
}
|
|
196
|
+
};
|
|
197
|
+
mediaQuery.addEventListener("change", handleChange);
|
|
198
|
+
return () => mediaQuery.removeEventListener("change", handleChange);
|
|
199
|
+
}, []);
|
|
200
|
+
const toggle = useCallback(() => {
|
|
201
|
+
setIsDark((prev) => !prev);
|
|
202
|
+
}, []);
|
|
203
|
+
return { isDark, toggle };
|
|
204
|
+
}
|
|
205
|
+
|
|
154
206
|
export {
|
|
155
207
|
parseWhatsAppFormatting,
|
|
156
208
|
waToHTML,
|
|
157
209
|
htmlToWA,
|
|
158
|
-
waToHTMLInline
|
|
210
|
+
waToHTMLInline,
|
|
211
|
+
useIsDarkTheme,
|
|
212
|
+
useDarkMode
|
|
159
213
|
};
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
|
-
parseWhatsAppFormatting
|
|
3
|
-
|
|
2
|
+
parseWhatsAppFormatting,
|
|
3
|
+
useIsDarkTheme
|
|
4
|
+
} from "./chunk-2AYDBWNE.js";
|
|
4
5
|
|
|
5
6
|
// src/ConversationLocalesProvider.tsx
|
|
6
7
|
import { createContext, useContext } from "react";
|
|
@@ -616,8 +617,32 @@ function MessageBubble({
|
|
|
616
617
|
|
|
617
618
|
// src/Wallpaper.tsx
|
|
618
619
|
import { jsx as jsx10 } from "react/jsx-runtime";
|
|
619
|
-
function
|
|
620
|
-
|
|
620
|
+
function doodlePattern(strokeColor, opacity) {
|
|
621
|
+
const svg = `<svg xmlns='http://www.w3.org/2000/svg' width='100' height='100' viewBox='0 0 100 100'><g fill='none' stroke='${strokeColor}' stroke-width='1.2' opacity='${opacity}'><circle cx='15' cy='15' r='3'/><path d='M40 10 q5 8 0 16 q-5 -8 0 -16z'/><circle cx='70' cy='28' r='2'/><path d='M18 55 l6 6 m-6 0 l6 -6'/><circle cx='55' cy='68' r='2.5'/><path d='M85 58 q6 6 0 12 q-6 -6 0 -12z'/><circle cx='8' cy='85' r='2'/><path d='M65 90 l5 5 m-5 0 l5 -5'/></g></svg>`;
|
|
622
|
+
return `url("data:image/svg+xml,${encodeURIComponent(svg)}")`;
|
|
623
|
+
}
|
|
624
|
+
var LIGHT_WALLPAPER = {
|
|
625
|
+
backgroundColor: "#efeae2",
|
|
626
|
+
backgroundImage: doodlePattern("#d7cfc0", 0.7),
|
|
627
|
+
backgroundRepeat: "repeat",
|
|
628
|
+
backgroundSize: "100px 100px"
|
|
629
|
+
};
|
|
630
|
+
var DARK_WALLPAPER = {
|
|
631
|
+
backgroundColor: "#0b141a",
|
|
632
|
+
backgroundImage: doodlePattern("#19232a", 0.9),
|
|
633
|
+
backgroundRepeat: "repeat",
|
|
634
|
+
backgroundSize: "100px 100px"
|
|
635
|
+
};
|
|
636
|
+
function ConversationWallpaper({ children, className, style }) {
|
|
637
|
+
const isDark = useIsDarkTheme();
|
|
638
|
+
return /* @__PURE__ */ jsx10(
|
|
639
|
+
"div",
|
|
640
|
+
{
|
|
641
|
+
className: cn("cv-wallpaper", className),
|
|
642
|
+
style: { ...isDark ? DARK_WALLPAPER : LIGHT_WALLPAPER, ...style },
|
|
643
|
+
children
|
|
644
|
+
}
|
|
645
|
+
);
|
|
621
646
|
}
|
|
622
647
|
|
|
623
648
|
// src/emojiCatalog.ts
|
package/dist/flows/index.js
CHANGED
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
|
+
parseWhatsAppFormatting,
|
|
2
3
|
useIsDarkTheme
|
|
3
|
-
} from "../chunk-
|
|
4
|
-
import {
|
|
5
|
-
parseWhatsAppFormatting
|
|
6
|
-
} from "../chunk-OGRRHQQW.js";
|
|
4
|
+
} from "../chunk-2AYDBWNE.js";
|
|
7
5
|
|
|
8
6
|
// src/flows/FlowNodeCard.tsx
|
|
9
7
|
import { Handle, Position } from "@xyflow/react";
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as react from 'react';
|
|
2
|
-
import react__default, { ReactNode, FormEvent } from 'react';
|
|
2
|
+
import react__default, { ReactNode, CSSProperties, FormEvent } from 'react';
|
|
3
3
|
import { y as MessagePayload, A as ResolveMediaUrl, v as InteractiveSelection, t as InteractivePayload, p as ConversationsFeatures, m as ConversationSummary, h as ConversationChannel, L as ListConversationsParams, o as ConversationsApi, S as SSEProvider, w as ListDocumentsParams, i as ConversationDocument, n as ConversationTemplate } from './types-B5C1DLu1.js';
|
|
4
4
|
export { C as CHANNEL_CAPABILITIES, a as CHANNEL_FILTER_ALL, b as CONVERSATION_CHANNEL, c as ChannelCapabilities, d as ChannelFilter, e as ChannelFilterOption, f as CompanyDocument, g as CompanyDocumentPage, j as ConversationDocumentPage, k as ConversationEventSource, l as ConversationPage, q as ConversationsTheme, r as ConversationsUIConfig, D as DEFAULT_CONVERSATION_CHANNEL, F as FormatContactHandleParams, H as HANDLE_KIND, s as HandleKind, I as InteractiveOption, u as InteractiveSection, M as MediaRenderer, x as MediaRendererProps, R as REOPEN_MECHANISM, z as ReopenMechanism, B as capabilitiesOf, E as channelFiltersFor, G as contactFlag, J as formatContactHandle } from './types-B5C1DLu1.js';
|
|
5
5
|
|
|
@@ -41,8 +41,10 @@ declare function InteractiveMessage({ payload, onSelect, labels, className }: In
|
|
|
41
41
|
interface ConversationWallpaperProps {
|
|
42
42
|
children?: ReactNode;
|
|
43
43
|
className?: string;
|
|
44
|
+
/** Ajusta ou substitui o fundo padrão — para produto com identidade visual própria. */
|
|
45
|
+
style?: CSSProperties;
|
|
44
46
|
}
|
|
45
|
-
declare function ConversationWallpaper({ children, className }: ConversationWallpaperProps): react.JSX.Element;
|
|
47
|
+
declare function ConversationWallpaper({ children, className, style }: ConversationWallpaperProps): react.JSX.Element;
|
|
46
48
|
|
|
47
49
|
interface ConversationLocales {
|
|
48
50
|
bubble: {
|
package/dist/index.js
CHANGED
|
@@ -1,7 +1,3 @@
|
|
|
1
|
-
import {
|
|
2
|
-
useDarkMode,
|
|
3
|
-
useIsDarkTheme
|
|
4
|
-
} from "./chunk-NV2RZ5KT.js";
|
|
5
1
|
import {
|
|
6
2
|
AudioPlayer,
|
|
7
3
|
ConversationDocumentsPanel,
|
|
@@ -43,13 +39,15 @@ import {
|
|
|
43
39
|
useConversationDocuments,
|
|
44
40
|
useConversationLocales,
|
|
45
41
|
useConversations
|
|
46
|
-
} from "./chunk-
|
|
42
|
+
} from "./chunk-G5BM3VBP.js";
|
|
47
43
|
import {
|
|
48
44
|
htmlToWA,
|
|
49
45
|
parseWhatsAppFormatting,
|
|
46
|
+
useDarkMode,
|
|
47
|
+
useIsDarkTheme,
|
|
50
48
|
waToHTML,
|
|
51
49
|
waToHTMLInline
|
|
52
|
-
} from "./chunk-
|
|
50
|
+
} from "./chunk-2AYDBWNE.js";
|
|
53
51
|
|
|
54
52
|
// src/WhatsAppMessageEditor.tsx
|
|
55
53
|
import { useRef } from "react";
|
package/dist/preview/index.js
CHANGED
|
@@ -6,8 +6,8 @@ import {
|
|
|
6
6
|
DocumentsLibrary,
|
|
7
7
|
MessageBubble,
|
|
8
8
|
MessageComposer
|
|
9
|
-
} from "../chunk-
|
|
10
|
-
import "../chunk-
|
|
9
|
+
} from "../chunk-G5BM3VBP.js";
|
|
10
|
+
import "../chunk-2AYDBWNE.js";
|
|
11
11
|
|
|
12
12
|
// src/preview/previewStore.ts
|
|
13
13
|
var GLOBAL_CHANNEL = "global";
|
package/package.json
CHANGED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { describe, expect, it } from 'bun:test'
|
|
2
|
+
import { renderToStaticMarkup } from 'react-dom/server'
|
|
3
|
+
|
|
4
|
+
import { ConversationWallpaper } from './Wallpaper'
|
|
5
|
+
|
|
6
|
+
describe('ConversationWallpaper', () => {
|
|
7
|
+
it('desenha o fundo sozinho, sem depender do styles.css do host', () => {
|
|
8
|
+
const markup = renderToStaticMarkup(<ConversationWallpaper />)
|
|
9
|
+
|
|
10
|
+
expect(markup).toContain('background-color:#efeae2')
|
|
11
|
+
expect(markup).toContain('background-image:url("data:image/svg+xml,')
|
|
12
|
+
expect(markup).toContain('cv-wallpaper')
|
|
13
|
+
})
|
|
14
|
+
|
|
15
|
+
it('deixa o produto sobrescrever o fundo por style', () => {
|
|
16
|
+
const markup = renderToStaticMarkup(<ConversationWallpaper style={{ backgroundColor: '#123456' }} />)
|
|
17
|
+
|
|
18
|
+
expect(markup).toContain('background-color:#123456')
|
|
19
|
+
expect(markup).not.toContain('background-color:#efeae2')
|
|
20
|
+
})
|
|
21
|
+
})
|
package/src/Wallpaper.tsx
CHANGED
|
@@ -1,15 +1,61 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Fundo da conversa — a textura clara/escura do WhatsApp.
|
|
3
|
+
*
|
|
4
|
+
* O fundo vem embutido, e não da folha de estilo do pacote: `styles.css` é um import opcional que o
|
|
5
|
+
* host precisa lembrar de fazer, e esquecê-lo deixava a conversa sobre branco liso, sem erro nenhum
|
|
6
|
+
* para denunciar o problema. Fundo é identidade do componente, não tema do host.
|
|
7
|
+
*
|
|
8
|
+
* A classe `cv-wallpaper` continua no elemento para quem já sobrescreve por CSS.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import type { CSSProperties, ReactNode } from 'react'
|
|
2
12
|
|
|
3
13
|
import { cn } from './lib/cn'
|
|
14
|
+
import { useIsDarkTheme } from './useDarkMode'
|
|
15
|
+
|
|
16
|
+
/** Textura do WhatsApp: rabiscos esparsos que se repetem a cada 100px. */
|
|
17
|
+
function doodlePattern(strokeColor: string, opacity: number): string {
|
|
18
|
+
const svg =
|
|
19
|
+
`<svg xmlns='http://www.w3.org/2000/svg' width='100' height='100' viewBox='0 0 100 100'>` +
|
|
20
|
+
`<g fill='none' stroke='${strokeColor}' stroke-width='1.2' opacity='${opacity}'>` +
|
|
21
|
+
`<circle cx='15' cy='15' r='3'/><path d='M40 10 q5 8 0 16 q-5 -8 0 -16z'/>` +
|
|
22
|
+
`<circle cx='70' cy='28' r='2'/><path d='M18 55 l6 6 m-6 0 l6 -6'/>` +
|
|
23
|
+
`<circle cx='55' cy='68' r='2.5'/><path d='M85 58 q6 6 0 12 q-6 -6 0 -12z'/>` +
|
|
24
|
+
`<circle cx='8' cy='85' r='2'/><path d='M65 90 l5 5 m-5 0 l5 -5'/>` +
|
|
25
|
+
`</g></svg>`
|
|
26
|
+
return `url("data:image/svg+xml,${encodeURIComponent(svg)}")`
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const LIGHT_WALLPAPER: CSSProperties = {
|
|
30
|
+
backgroundColor: '#efeae2',
|
|
31
|
+
backgroundImage: doodlePattern('#d7cfc0', 0.7),
|
|
32
|
+
backgroundRepeat: 'repeat',
|
|
33
|
+
backgroundSize: '100px 100px',
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const DARK_WALLPAPER: CSSProperties = {
|
|
37
|
+
backgroundColor: '#0b141a',
|
|
38
|
+
backgroundImage: doodlePattern('#19232a', 0.9),
|
|
39
|
+
backgroundRepeat: 'repeat',
|
|
40
|
+
backgroundSize: '100px 100px',
|
|
41
|
+
}
|
|
4
42
|
|
|
5
43
|
export interface ConversationWallpaperProps {
|
|
6
44
|
children?: ReactNode
|
|
7
45
|
className?: string
|
|
46
|
+
/** Ajusta ou substitui o fundo padrão — para produto com identidade visual própria. */
|
|
47
|
+
style?: CSSProperties
|
|
8
48
|
}
|
|
9
49
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
50
|
+
export function ConversationWallpaper({ children, className, style }: ConversationWallpaperProps) {
|
|
51
|
+
const isDark = useIsDarkTheme()
|
|
52
|
+
|
|
53
|
+
return (
|
|
54
|
+
<div
|
|
55
|
+
className={cn('cv-wallpaper', className)}
|
|
56
|
+
style={{ ...(isDark ? DARK_WALLPAPER : LIGHT_WALLPAPER), ...style }}
|
|
57
|
+
>
|
|
58
|
+
{children}
|
|
59
|
+
</div>
|
|
60
|
+
)
|
|
15
61
|
}
|
package/dist/chunk-NV2RZ5KT.js
DELETED
|
@@ -1,56 +0,0 @@
|
|
|
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
|
-
export {
|
|
54
|
-
useIsDarkTheme,
|
|
55
|
-
useDarkMode
|
|
56
|
-
};
|