@xapp/chat-widget 1.96.2 → 1.96.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.
- package/dist/index.css +1 -1
- package/dist/index.es.js +518 -0
- package/dist/index.es.js.map +1 -1
- package/dist/index.js +518 -0
- package/dist/index.js.map +1 -1
- package/dist/xapp-chat-widget.css +1 -1
- package/dist/xapp-chat-widget.js +6 -4
- package/dist/xapp-chat-widget.js.map +1 -1
- package/package.json +3 -3
package/dist/index.es.js
CHANGED
|
@@ -67,6 +67,522 @@ function isActionBarPaymentButton(button) {
|
|
|
67
67
|
return button.type === "payment";
|
|
68
68
|
}
|
|
69
69
|
|
|
70
|
+
var buildChatWidgetChannel$1 = {};
|
|
71
|
+
|
|
72
|
+
var color = {};
|
|
73
|
+
|
|
74
|
+
/*! Copyright (c) 2026, XAPP AI */
|
|
75
|
+
Object.defineProperty(color, "__esModule", { value: true });
|
|
76
|
+
color.parseRgb = parseRgb;
|
|
77
|
+
color.invertColorHEX = invertColorHEX;
|
|
78
|
+
color.invertColorRgb = invertColorRgb;
|
|
79
|
+
color.invertColor = invertColor;
|
|
80
|
+
color.isSupportedColor = isSupportedColor;
|
|
81
|
+
color.usableColorOr = usableColorOr;
|
|
82
|
+
color.readableTextOn = readableTextOn;
|
|
83
|
+
color.darkenColor = darkenColor;
|
|
84
|
+
/**
|
|
85
|
+
* Colour maths for building a widget theme from a business's own branding.
|
|
86
|
+
*
|
|
87
|
+
* These lived in stentor-client, which meant the only way to work out a
|
|
88
|
+
* readable text colour was to be running in a browser. Studio needs the same
|
|
89
|
+
* answers when it builds an app server-side for a get.xapp.ai signup, and two
|
|
90
|
+
* implementations of "which colour reads on this background" would drift into
|
|
91
|
+
* two different-looking widgets.
|
|
92
|
+
*
|
|
93
|
+
* The inputs are colours scraped off a customer's website, so they are whatever
|
|
94
|
+
* their designer chose — any hex length, rgb or rgba, or nothing at all.
|
|
95
|
+
*/
|
|
96
|
+
/** Left-pads a hex component so "f" becomes "0f". */
|
|
97
|
+
function padZero(value, length = 2) {
|
|
98
|
+
const zeros = new Array(length).join("0");
|
|
99
|
+
return (zeros + value).slice(-length);
|
|
100
|
+
}
|
|
101
|
+
function parseRgb(colorString) {
|
|
102
|
+
const rgba = /^rgba?\((\d+),\s*(\d+),\s*(\d+),\s*([\d.]+)\)$/;
|
|
103
|
+
const rgb = /^rgb?\((\d+),\s*(\d+),\s*(\d+)\)$/;
|
|
104
|
+
const withAlpha = colorString === null || colorString === void 0 ? void 0 : colorString.match(rgba);
|
|
105
|
+
if (withAlpha) {
|
|
106
|
+
return {
|
|
107
|
+
r: parseInt(withAlpha[1], 10),
|
|
108
|
+
g: parseInt(withAlpha[2], 10),
|
|
109
|
+
b: parseInt(withAlpha[3], 10),
|
|
110
|
+
a: parseFloat(withAlpha[4])
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
const plain = colorString === null || colorString === void 0 ? void 0 : colorString.match(rgb);
|
|
114
|
+
if (plain) {
|
|
115
|
+
return { r: parseInt(plain[1], 10), g: parseInt(plain[2], 10), b: parseInt(plain[3], 10) };
|
|
116
|
+
}
|
|
117
|
+
return null;
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Whether text should be black or white to read on this background.
|
|
121
|
+
*
|
|
122
|
+
* The weighting is perceived brightness, not an average: the eye is far more
|
|
123
|
+
* sensitive to green than to blue, so a pure blue is dark to us even though its
|
|
124
|
+
* numeric average is mid-range.
|
|
125
|
+
*
|
|
126
|
+
* @see http://stackoverflow.com/a/3943023/112731
|
|
127
|
+
*/
|
|
128
|
+
function isLight(r, g, b) {
|
|
129
|
+
return r * 0.299 + g * 0.587 + b * 0.114 > 186;
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Inverts a hex colour, or returns black/white for contrast when `bw` is set.
|
|
133
|
+
*
|
|
134
|
+
* Inverting is rarely what you want behind text — a mid-tone inverts to another
|
|
135
|
+
* mid-tone and neither reads. `bw` is the contrast answer.
|
|
136
|
+
*/
|
|
137
|
+
function invertColorHEX(hex, bw) {
|
|
138
|
+
if (!hex) {
|
|
139
|
+
return undefined;
|
|
140
|
+
}
|
|
141
|
+
let value = hex.indexOf("#") === 0 ? hex.slice(1) : hex;
|
|
142
|
+
if (value.length === 3) {
|
|
143
|
+
value = value[0] + value[0] + value[1] + value[1] + value[2] + value[2];
|
|
144
|
+
}
|
|
145
|
+
if (value.length !== 6) {
|
|
146
|
+
throw new Error("Invalid HEX color.");
|
|
147
|
+
}
|
|
148
|
+
const r = parseInt(value.slice(0, 2), 16);
|
|
149
|
+
const g = parseInt(value.slice(2, 4), 16);
|
|
150
|
+
const b = parseInt(value.slice(4, 6), 16);
|
|
151
|
+
if (bw) {
|
|
152
|
+
return isLight(r, g, b) ? "#000000" : "#FFFFFF";
|
|
153
|
+
}
|
|
154
|
+
return `#${padZero((255 - r).toString(16))}${padZero((255 - g).toString(16))}${padZero((255 - b).toString(16))}`;
|
|
155
|
+
}
|
|
156
|
+
/** As invertColorHEX, for rgb/rgba input. */
|
|
157
|
+
function invertColorRgb(rgb, bw) {
|
|
158
|
+
const parsed = parseRgb(rgb);
|
|
159
|
+
if (!parsed) {
|
|
160
|
+
return rgb;
|
|
161
|
+
}
|
|
162
|
+
const { r, g, b } = parsed;
|
|
163
|
+
if (bw) {
|
|
164
|
+
return isLight(r, g, b) ? "rgba(0, 0, 0, 1)" : "rgba(255, 255, 255, 1)";
|
|
165
|
+
}
|
|
166
|
+
return `rgba(${255 - r}, ${255 - g}, ${255 - b}, 1)`;
|
|
167
|
+
}
|
|
168
|
+
/** Inverts whichever colour notation was given. */
|
|
169
|
+
function invertColor(color, bw) {
|
|
170
|
+
if (!color) {
|
|
171
|
+
return undefined;
|
|
172
|
+
}
|
|
173
|
+
return color.startsWith("#") ? invertColorHEX(color, bw) : invertColorRgb(color, bw);
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* Whether we can work out what text reads on this colour.
|
|
177
|
+
*
|
|
178
|
+
* Hex and rgb/rgba only. A CSS named colour like `orange`, or `hsl(...)`, is
|
|
179
|
+
* perfectly valid CSS — we simply cannot compute its brightness, and a
|
|
180
|
+
* background whose contrast we cannot compute is one we must not use.
|
|
181
|
+
*/
|
|
182
|
+
function isSupportedColor(color) {
|
|
183
|
+
if (!color) {
|
|
184
|
+
return false;
|
|
185
|
+
}
|
|
186
|
+
if (color.startsWith("#")) {
|
|
187
|
+
const value = color.slice(1);
|
|
188
|
+
return (value.length === 3 || value.length === 6) && /^[0-9a-f]+$/i.test(value);
|
|
189
|
+
}
|
|
190
|
+
return parseRgb(color) !== null;
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* The colour to theme with: the one given, or the fallback when we cannot work
|
|
194
|
+
* out what text reads on it.
|
|
195
|
+
*
|
|
196
|
+
* Every builder needs this and each was doing it by hand, which is how the
|
|
197
|
+
* chat widget ended up guarded and the other two not. A background whose
|
|
198
|
+
* contrast cannot be computed is one we must not use — the foreground would be
|
|
199
|
+
* a guess paired with an unknown, and on a dark unparseable colour that is
|
|
200
|
+
* invisible text.
|
|
201
|
+
*/
|
|
202
|
+
function usableColorOr(color, fallback) {
|
|
203
|
+
return isSupportedColor(color) ? color : fallback;
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* The text colour that will read on this background: black or white, never
|
|
207
|
+
* anything else.
|
|
208
|
+
*
|
|
209
|
+
* That guarantee is the whole point. An earlier version leaned on invertColor,
|
|
210
|
+
* whose rgb path returns its input unchanged when it cannot parse it — so
|
|
211
|
+
* `readableTextOn("orange")` answered `"orange"`, and a header themed from a
|
|
212
|
+
* scraped named colour got text in exactly the background colour. Invisible,
|
|
213
|
+
* and by the one function meant to prevent it.
|
|
214
|
+
*
|
|
215
|
+
* Unparseable input falls back to black. That is a guess, so callers who
|
|
216
|
+
* control the background should check `isSupportedColor` first and use a
|
|
217
|
+
* colour whose contrast can actually be computed, rather than pairing a
|
|
218
|
+
* guessed foreground with an unknown background.
|
|
219
|
+
*/
|
|
220
|
+
function readableTextOn(background) {
|
|
221
|
+
if (!isSupportedColor(background)) {
|
|
222
|
+
return "#000000";
|
|
223
|
+
}
|
|
224
|
+
const rgb = background.startsWith("#") ? hexToRgb(background) : parseRgb(background);
|
|
225
|
+
if (!rgb) {
|
|
226
|
+
return "#000000";
|
|
227
|
+
}
|
|
228
|
+
return isLight(rgb.r, rgb.g, rgb.b) ? "#000000" : "#FFFFFF";
|
|
229
|
+
}
|
|
230
|
+
function hexToRgb(hex) {
|
|
231
|
+
let value = hex.slice(1);
|
|
232
|
+
if (value.length === 3) {
|
|
233
|
+
value = value[0] + value[0] + value[1] + value[1] + value[2] + value[2];
|
|
234
|
+
}
|
|
235
|
+
if (value.length !== 6) {
|
|
236
|
+
return null;
|
|
237
|
+
}
|
|
238
|
+
return {
|
|
239
|
+
r: parseInt(value.slice(0, 2), 16),
|
|
240
|
+
g: parseInt(value.slice(2, 4), 16),
|
|
241
|
+
b: parseInt(value.slice(4, 6), 16)
|
|
242
|
+
};
|
|
243
|
+
}
|
|
244
|
+
/**
|
|
245
|
+
* A shade of the input colour, darkened by `amount` percent (negative
|
|
246
|
+
* lightens). Ported alongside the rest so the form widget's theme does not
|
|
247
|
+
* need its own copy of it.
|
|
248
|
+
*/
|
|
249
|
+
function darkenColor(colorIn, amount) {
|
|
250
|
+
if (!colorIn) {
|
|
251
|
+
return colorIn;
|
|
252
|
+
}
|
|
253
|
+
let r, g, b, a;
|
|
254
|
+
let colorOut;
|
|
255
|
+
try {
|
|
256
|
+
// Parse the color format
|
|
257
|
+
if (colorIn.startsWith('#')) {
|
|
258
|
+
// Hex format
|
|
259
|
+
const hexMatch = colorIn.match(/\w\w/g);
|
|
260
|
+
if (hexMatch) {
|
|
261
|
+
[r, g, b] = hexMatch.map(x => parseInt(x, 16));
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
else if (colorIn.startsWith('rgb')) {
|
|
265
|
+
// RGB or RGBA format
|
|
266
|
+
const rgba = parseRgb(colorIn);
|
|
267
|
+
if (rgba) {
|
|
268
|
+
({ r, g, b, a } = rgba);
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
if (r === undefined || g === undefined || b === undefined) {
|
|
272
|
+
console.error(`Unsupported color format: ${colorIn}`);
|
|
273
|
+
return colorIn;
|
|
274
|
+
}
|
|
275
|
+
if (a !== undefined) {
|
|
276
|
+
// Adjust luminance for RGBA
|
|
277
|
+
// Luminance is on the 0-255 scale the channels are, so the clamp
|
|
278
|
+
// has to be too. Bounding it to 0-1 collapsed it to 1 for every
|
|
279
|
+
// real colour, which made the ratio tiny and crushed the result to
|
|
280
|
+
// near-black instead of darkening it: rgba(20, 52, 204, 0.8) at 20%
|
|
281
|
+
// came back rgba(0, 1, 3, 1).
|
|
282
|
+
const luminance = 0.3 * r + 0.59 * g + 0.11 * b;
|
|
283
|
+
let newLuminance = luminance * (1 - amount / 100);
|
|
284
|
+
newLuminance = Math.max(0, Math.min(255, newLuminance));
|
|
285
|
+
const ratio = newLuminance / (luminance || 1); // no division by zero
|
|
286
|
+
r = Math.round(r * ratio);
|
|
287
|
+
g = Math.round(g * ratio);
|
|
288
|
+
b = Math.round(b * ratio);
|
|
289
|
+
// Adjust alpha
|
|
290
|
+
a = a + amount / 100;
|
|
291
|
+
a = Math.max(0, Math.min(1, a)); // within 0 and 1
|
|
292
|
+
colorOut = `rgba(${r}, ${g}, ${b}, ${a})`;
|
|
293
|
+
}
|
|
294
|
+
else {
|
|
295
|
+
// Adjust the color for RGB or Hex
|
|
296
|
+
if (amount > 0) {
|
|
297
|
+
r = Math.max(0, r - amount);
|
|
298
|
+
g = Math.max(0, g - amount);
|
|
299
|
+
b = Math.max(0, b - amount);
|
|
300
|
+
}
|
|
301
|
+
else {
|
|
302
|
+
amount = Math.abs(amount); // positive for lightening
|
|
303
|
+
r = Math.min(255, r + amount);
|
|
304
|
+
g = Math.min(255, g + amount);
|
|
305
|
+
b = Math.min(255, b + amount);
|
|
306
|
+
}
|
|
307
|
+
colorOut = `#${r.toString(16).padStart(2, '0')}${g.toString(16).padStart(2, '0')}${b.toString(16).padStart(2, '0')}`;
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
catch (e) {
|
|
311
|
+
console.error(`Unsupported color format: ${colorIn} - Error: ${e}`);
|
|
312
|
+
}
|
|
313
|
+
return colorOut;
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
Object.defineProperty(buildChatWidgetChannel$1, "__esModule", { value: true });
|
|
317
|
+
buildChatWidgetChannel$1.buildChatWidgetChannel = buildChatWidgetChannel;
|
|
318
|
+
buildChatWidgetChannel$1.buildChatTheme = buildChatTheme;
|
|
319
|
+
const color_1 = color;
|
|
320
|
+
/** Fallback when a crawl found no branding. Deliberately neutral. */
|
|
321
|
+
const DEFAULT_PRIMARY = "#1AA7DC";
|
|
322
|
+
function buildChatWidgetChannel(props) {
|
|
323
|
+
const { appId, apiUrl, mcpUrl, formWidgetKey, phoneNumber } = props;
|
|
324
|
+
// Only a colour whose contrast can actually be computed, so the background
|
|
325
|
+
// and the text on it are always a matched pair rather than one scraped
|
|
326
|
+
// value and one guess.
|
|
327
|
+
const primaryColor = (0, color_1.usableColorOr)(props.primaryColor, DEFAULT_PRIMARY);
|
|
328
|
+
return {
|
|
329
|
+
type: "chat-widget",
|
|
330
|
+
// MCP by default. The widget runs on a public page, so homeowner mode
|
|
331
|
+
// — which is unauthenticated and carries the appId in the url — is the
|
|
332
|
+
// only one that can work there; business_owner needs a token, and a
|
|
333
|
+
// token on a public page is not a token.
|
|
334
|
+
connection: {
|
|
335
|
+
type: "mcp",
|
|
336
|
+
serverUrl: `${mcpUrl}/${appId}`,
|
|
337
|
+
mcp: {
|
|
338
|
+
mode: "homeowner"
|
|
339
|
+
}
|
|
340
|
+
},
|
|
341
|
+
theme: buildChatTheme(primaryColor, props.secondaryColor),
|
|
342
|
+
actionBar: buildActionBar({ apiUrl, formWidgetKey, phoneNumber })
|
|
343
|
+
};
|
|
344
|
+
}
|
|
345
|
+
/**
|
|
346
|
+
* The dock of buttons that replaces the plain chat bubble.
|
|
347
|
+
*
|
|
348
|
+
* On by default, which is the part worth explaining: chat is not on the default
|
|
349
|
+
* tier, but the action bar is how someone reaches booking and the phone, and
|
|
350
|
+
* those are what the business is paying for.
|
|
351
|
+
*
|
|
352
|
+
* Order is deliberate. Booking is the thing we are selling, so it comes first;
|
|
353
|
+
* calling is the fallback for people who will not use a form; chat is last
|
|
354
|
+
* because it is the least likely to be enabled.
|
|
355
|
+
*/
|
|
356
|
+
function buildActionBar(props) {
|
|
357
|
+
const { apiUrl, formWidgetKey, phoneNumber } = props;
|
|
358
|
+
const buttons = [];
|
|
359
|
+
if (formWidgetKey) {
|
|
360
|
+
buttons.push({
|
|
361
|
+
id: "book",
|
|
362
|
+
type: "schedule",
|
|
363
|
+
label: "Book",
|
|
364
|
+
formConfig: {
|
|
365
|
+
api: {
|
|
366
|
+
url: apiUrl,
|
|
367
|
+
key: formWidgetKey
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
});
|
|
371
|
+
}
|
|
372
|
+
if (phoneNumber) {
|
|
373
|
+
buttons.push({
|
|
374
|
+
id: "call",
|
|
375
|
+
type: "phone",
|
|
376
|
+
label: "Call",
|
|
377
|
+
phoneNumber
|
|
378
|
+
});
|
|
379
|
+
}
|
|
380
|
+
buttons.push({
|
|
381
|
+
id: "chat",
|
|
382
|
+
type: "chat",
|
|
383
|
+
label: "Chat"
|
|
384
|
+
});
|
|
385
|
+
return {
|
|
386
|
+
enabled: true,
|
|
387
|
+
position: "right",
|
|
388
|
+
buttons
|
|
389
|
+
};
|
|
390
|
+
}
|
|
391
|
+
/**
|
|
392
|
+
* The theme a new chat widget starts with, from the business's own colour.
|
|
393
|
+
*
|
|
394
|
+
* A faithful port of stentor-client's buildDefaultChatTheme, deliberately: the
|
|
395
|
+
* point of moving it is that onboarding can call this instead of its own copy,
|
|
396
|
+
* and that migration should not restyle every widget created afterwards. A
|
|
397
|
+
* thinner theme would have quietly dropped the CTA, message, input, footer and
|
|
398
|
+
* button styling that new widgets have today.
|
|
399
|
+
*
|
|
400
|
+
* The one change is how the contrast colour is derived — see below.
|
|
401
|
+
*/
|
|
402
|
+
function buildChatTheme(primaryColor, secondaryColor) {
|
|
403
|
+
const fontFamily = "RobotoRegular";
|
|
404
|
+
// secondaryColor is the colour of text sitting ON primaryColor — header
|
|
405
|
+
// title, subtitle, footer branding. Left unset it is computed, which is
|
|
406
|
+
// what makes the theme readable against whatever colour was scraped off
|
|
407
|
+
// the business's own site.
|
|
408
|
+
if (!secondaryColor) {
|
|
409
|
+
secondaryColor = (0, color_1.readableTextOn)(primaryColor);
|
|
410
|
+
}
|
|
411
|
+
return {
|
|
412
|
+
zIndex: "10000",
|
|
413
|
+
border: {
|
|
414
|
+
color: primaryColor,
|
|
415
|
+
radius: "10px",
|
|
416
|
+
},
|
|
417
|
+
carousel: {
|
|
418
|
+
button: {
|
|
419
|
+
color: primaryColor,
|
|
420
|
+
},
|
|
421
|
+
subtitle: {
|
|
422
|
+
color: "#979797",
|
|
423
|
+
fontFamily,
|
|
424
|
+
fontSize: "12px",
|
|
425
|
+
fontStyle: "normal",
|
|
426
|
+
fontWeight: "normal",
|
|
427
|
+
},
|
|
428
|
+
title: {
|
|
429
|
+
color: "#000",
|
|
430
|
+
fontFamily,
|
|
431
|
+
fontSize: "14px",
|
|
432
|
+
fontStyle: "normal",
|
|
433
|
+
fontWeight: "bold",
|
|
434
|
+
},
|
|
435
|
+
},
|
|
436
|
+
chatButton: {
|
|
437
|
+
background: primaryColor,
|
|
438
|
+
margin: {
|
|
439
|
+
bottom: "10px",
|
|
440
|
+
left: "10px",
|
|
441
|
+
right: "10px",
|
|
442
|
+
top: "10px",
|
|
443
|
+
},
|
|
444
|
+
},
|
|
445
|
+
content: {
|
|
446
|
+
background: "#ffffff",
|
|
447
|
+
},
|
|
448
|
+
cta: {
|
|
449
|
+
background: "#e1e2e1",
|
|
450
|
+
text: {
|
|
451
|
+
// Use a dark color that contrasts well with the light grey background
|
|
452
|
+
// instead of primaryColor which may not have sufficient contrast
|
|
453
|
+
color: "#333333",
|
|
454
|
+
fontFamily,
|
|
455
|
+
fontSize: "14px",
|
|
456
|
+
},
|
|
457
|
+
},
|
|
458
|
+
footer: {
|
|
459
|
+
background: primaryColor,
|
|
460
|
+
border: {
|
|
461
|
+
color: primaryColor,
|
|
462
|
+
radius: "0px",
|
|
463
|
+
width: "0px",
|
|
464
|
+
},
|
|
465
|
+
branding: {
|
|
466
|
+
text: {
|
|
467
|
+
color: "#ffffff",
|
|
468
|
+
fontFamily,
|
|
469
|
+
fontSize: "14px",
|
|
470
|
+
fontWeight: "normal",
|
|
471
|
+
fontStyle: "normal",
|
|
472
|
+
},
|
|
473
|
+
},
|
|
474
|
+
},
|
|
475
|
+
header: {
|
|
476
|
+
background: primaryColor,
|
|
477
|
+
avatarBackground: "transparent",
|
|
478
|
+
border: {
|
|
479
|
+
color: primaryColor,
|
|
480
|
+
radius: "0px",
|
|
481
|
+
width: "0px",
|
|
482
|
+
},
|
|
483
|
+
text: {
|
|
484
|
+
color: secondaryColor,
|
|
485
|
+
fontFamily,
|
|
486
|
+
fontSize: "16px",
|
|
487
|
+
fontWeight: "normal",
|
|
488
|
+
fontStyle: "normal",
|
|
489
|
+
},
|
|
490
|
+
subtitle: {
|
|
491
|
+
color: secondaryColor,
|
|
492
|
+
fontFamily,
|
|
493
|
+
fontSize: "10px",
|
|
494
|
+
fontWeight: "normal",
|
|
495
|
+
fontStyle: "normal",
|
|
496
|
+
},
|
|
497
|
+
},
|
|
498
|
+
input: {
|
|
499
|
+
background: "#ffffff",
|
|
500
|
+
border: {
|
|
501
|
+
radius: "20px",
|
|
502
|
+
},
|
|
503
|
+
text: {
|
|
504
|
+
color: "#000000",
|
|
505
|
+
fontFamily,
|
|
506
|
+
fontSize: "14px",
|
|
507
|
+
},
|
|
508
|
+
placeholder: {
|
|
509
|
+
color: "#e1e2e1",
|
|
510
|
+
fontFamily,
|
|
511
|
+
fontSize: "14px",
|
|
512
|
+
fontWeight: "normal",
|
|
513
|
+
fontStyle: "normal",
|
|
514
|
+
},
|
|
515
|
+
},
|
|
516
|
+
textTypingStatus: {
|
|
517
|
+
text: {
|
|
518
|
+
color: "#bfbfbf",
|
|
519
|
+
fontFamily,
|
|
520
|
+
fontSize: "14px",
|
|
521
|
+
fontWeight: "normal",
|
|
522
|
+
fontStyle: "normal",
|
|
523
|
+
},
|
|
524
|
+
},
|
|
525
|
+
menu: {
|
|
526
|
+
item: {
|
|
527
|
+
height: "24px",
|
|
528
|
+
text: {
|
|
529
|
+
fontSize: "14px",
|
|
530
|
+
},
|
|
531
|
+
},
|
|
532
|
+
},
|
|
533
|
+
menuButton: {
|
|
534
|
+
color: "#ffffff",
|
|
535
|
+
},
|
|
536
|
+
messages: {
|
|
537
|
+
maxWidth: "400px",
|
|
538
|
+
mine: {
|
|
539
|
+
bubbleColor: "#f2f2f2",
|
|
540
|
+
text: {
|
|
541
|
+
color: "#454545",
|
|
542
|
+
fontFamily,
|
|
543
|
+
fontSize: "18px",
|
|
544
|
+
fontStyle: "normal",
|
|
545
|
+
fontWeight: "normal",
|
|
546
|
+
},
|
|
547
|
+
},
|
|
548
|
+
others: {
|
|
549
|
+
bubbleColor: "#e1e2e1",
|
|
550
|
+
text: {
|
|
551
|
+
color: "#262726",
|
|
552
|
+
fontFamily,
|
|
553
|
+
fontSize: "18px",
|
|
554
|
+
fontStyle: "normal",
|
|
555
|
+
fontWeight: "normal",
|
|
556
|
+
},
|
|
557
|
+
},
|
|
558
|
+
padding: {
|
|
559
|
+
bottom: "0px",
|
|
560
|
+
left: "20px",
|
|
561
|
+
right: "16px",
|
|
562
|
+
top: "16px",
|
|
563
|
+
},
|
|
564
|
+
},
|
|
565
|
+
refreshButton: {
|
|
566
|
+
color: secondaryColor,
|
|
567
|
+
},
|
|
568
|
+
minimizeButton: {
|
|
569
|
+
color: secondaryColor,
|
|
570
|
+
},
|
|
571
|
+
cancelButton: {
|
|
572
|
+
color: secondaryColor,
|
|
573
|
+
},
|
|
574
|
+
primaryColor: primaryColor,
|
|
575
|
+
sendButton: {
|
|
576
|
+
color: "#505050",
|
|
577
|
+
width: "20px",
|
|
578
|
+
},
|
|
579
|
+
size: {
|
|
580
|
+
width: "500px",
|
|
581
|
+
height: "700px",
|
|
582
|
+
},
|
|
583
|
+
};
|
|
584
|
+
}
|
|
585
|
+
|
|
70
586
|
var ChannelData = {};
|
|
71
587
|
|
|
72
588
|
Object.defineProperty(ChannelData, "__esModule", { value: true });
|
|
@@ -132,7 +648,9 @@ function isOpenURLMenuItem(item) {
|
|
|
132
648
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
133
649
|
/*! Copyright (c) 2021, XAPPmedia */
|
|
134
650
|
__exportStar(ActionBar$1, exports);
|
|
651
|
+
__exportStar(buildChatWidgetChannel$1, exports);
|
|
135
652
|
__exportStar(ChannelData, exports);
|
|
653
|
+
__exportStar(color, exports);
|
|
136
654
|
__exportStar(Constants, exports);
|
|
137
655
|
__exportStar(Types, exports);
|
|
138
656
|
__exportStar(UserInfo, exports);
|