@xapp/chat-widget 1.94.4 → 1.95.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -6,10 +6,6 @@ var reactRedux = require('react-redux');
6
6
 
7
7
  var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
8
8
 
9
- function getDefaultExportFromCjs (x) {
10
- return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;
11
- }
12
-
13
9
  var lib = {};
14
10
 
15
11
  var ActionBar$1 = {};
@@ -397,6 +393,17 @@ var ActionBarCta = function (_a) {
397
393
 
398
394
  var DEFAULT_MOBILE_BREAKPOINT = 768;
399
395
  var RESIZE_DEBOUNCE_MS = 150;
396
+ /**
397
+ * ChatWidget.scss sizes the chat panel against this variable. Nothing used to set it, so it always
398
+ * fell back to the hardcoded 80px in the SCSS - and the real mobile bar is taller than that once
399
+ * env(safe-area-inset-bottom) applies, which pushed the chat input row behind the bar. Measure the
400
+ * bar instead of guessing, so it also stays correct when a customer restyles it.
401
+ *
402
+ * This is written on documentElement, so it assumes one ActionBar per page - the same
403
+ * single-instance assumption the widget already makes for --xapp-widget-z-index and friends.
404
+ * Two concurrent bars would fight over it, and either one unmounting would clear it.
405
+ */
406
+ var ACTION_BAR_HEIGHT_VAR = "--xapp-action-bar-height";
400
407
  var ActionBar = function (_a) {
401
408
  var _b, _c, _d;
402
409
  var config = _a.config, visible = _a.visible, chatDisabled = _a.chatDisabled, _e = _a.hasUserInteracted, hasUserInteracted = _e === void 0 ? false : _e, onChatClick = _a.onChatClick, onChatMinimize = _a.onChatMinimize, onFormClick = _a.onFormClick, onCtaDismiss = _a.onCtaDismiss;
@@ -404,6 +411,7 @@ var ActionBar = function (_a) {
404
411
  var mobileBreakpoint = (_b = config.mobileBreakpoint) !== null && _b !== void 0 ? _b : DEFAULT_MOBILE_BREAKPOINT;
405
412
  var position = (_c = config.position) !== null && _c !== void 0 ? _c : "right";
406
413
  var resizeTimeoutRef = React.useRef(null);
414
+ var barRef = React.useRef(null);
407
415
  // Debounced resize handler
408
416
  var handleResize = React.useCallback(function () {
409
417
  if (resizeTimeoutRef.current) {
@@ -424,6 +432,41 @@ var ActionBar = function (_a) {
424
432
  }
425
433
  };
426
434
  }, [mobileBreakpoint, handleResize]);
435
+ // Publish the bar's real height so the chat panel can size around it.
436
+ //
437
+ // useLayoutEffect, not useEffect: this commits before paint, so the panel never gets a
438
+ // frame laid out against the 80px SCSS fallback. useEffect would run after paint and
439
+ // reintroduce a one-frame version of the very misalignment this is here to remove.
440
+ React.useLayoutEffect(function () {
441
+ var bar = barRef.current;
442
+ if (!bar) {
443
+ return undefined;
444
+ }
445
+ var publishHeight = function () {
446
+ // getBoundingClientRect covers the whole border box, including the safe-area padding
447
+ // the mobile bar adds - which is exactly the space the chat panel has to clear.
448
+ var height = bar.getBoundingClientRect().height;
449
+ // A zero height means the bar is hidden or not laid out yet. Publishing 0px would
450
+ // be worse than the SCSS fallback, so leave whatever is already there alone.
451
+ if (height <= 0) {
452
+ return;
453
+ }
454
+ document.documentElement.style.setProperty(ACTION_BAR_HEIGHT_VAR, "".concat(height, "px"));
455
+ };
456
+ publishHeight();
457
+ // Older browsers without ResizeObserver keep the mount-time measurement above.
458
+ if (typeof ResizeObserver === "undefined") {
459
+ return function () {
460
+ document.documentElement.style.removeProperty(ACTION_BAR_HEIGHT_VAR);
461
+ };
462
+ }
463
+ var observer = new ResizeObserver(publishHeight);
464
+ observer.observe(bar);
465
+ return function () {
466
+ observer.disconnect();
467
+ document.documentElement.style.removeProperty(ACTION_BAR_HEIGHT_VAR);
468
+ };
469
+ }, [isMobile]);
427
470
  // Filter out chat buttons if chat is disabled
428
471
  var filteredButtons = chatDisabled
429
472
  ? config.buttons.filter(function (button) { return !lib.isActionBarChatButton(button); })
@@ -448,7 +491,7 @@ var ActionBar = function (_a) {
448
491
  var handleCtaDismiss = function () {
449
492
  onCtaDismiss === null || onCtaDismiss === void 0 ? void 0 : onCtaDismiss();
450
493
  };
451
- return (require$$0.jsxs("div", { className: classNames, role: "toolbar", "aria-label": "Chat actions", children: [showCta && (require$$0.jsx("div", { className: "xapp-action-bar-cta-wrapper", children: require$$0.jsx(ActionBarCta, { config: config.cta, isMobile: isMobile, onClick: handleCtaClick, onDismiss: handleCtaDismiss, hasUserInteracted: hasUserInteracted }) })), require$$0.jsx("div", { className: "xapp-action-bar__buttons", children: filteredButtons.map(function (button) { return (require$$0.jsx(ActionBarButton, { button: button, chatActive: visible, onChatClick: onChatClick, onChatMinimize: onChatMinimize, onFormClick: onFormClick, isMobile: isMobile }, button.id)); }) })] }));
494
+ return (require$$0.jsxs("div", { ref: barRef, className: classNames, role: "toolbar", "aria-label": "Chat actions", children: [showCta && (require$$0.jsx("div", { className: "xapp-action-bar-cta-wrapper", children: require$$0.jsx(ActionBarCta, { config: config.cta, isMobile: isMobile, onClick: handleCtaClick, onDismiss: handleCtaDismiss, hasUserInteracted: hasUserInteracted }) })), require$$0.jsx("div", { className: "xapp-action-bar__buttons", children: filteredButtons.map(function (button) { return (require$$0.jsx(ActionBarButton, { button: button, chatActive: visible, onChatClick: onChatClick, onChatMinimize: onChatMinimize, onFormClick: onFormClick, isMobile: isMobile }, button.id)); }) })] }));
452
495
  };
453
496
 
454
497
  /**
@@ -2306,8 +2349,9 @@ var RichText = function (props) {
2306
2349
  };
2307
2350
 
2308
2351
  var RichInput = function (props) {
2309
- var id = props.id, value = props.value, type = props.type, autoFocus = props.autoFocus, spellCheck = props.spellCheck, tabIndex = props.tabIndex, maxLength = props.maxLength, onChange = props.onChange, onInput = props.onInput, onKeyDown = props.onKeyDown, onSearch = props.onSearch;
2352
+ var id = props.id, value = props.value, type = props.type, autoFocus = props.autoFocus, spellCheck = props.spellCheck, tabIndex = props.tabIndex, maxLength = props.maxLength, enterKeyHint = props.enterKeyHint, onChange = props.onChange, onInput = props.onInput, onKeyDown = props.onKeyDown, onSearch = props.onSearch;
2310
2353
  var rich = value.formats.some(function (f) { return f.type === "inputText"; });
2354
+ var keyHint = enterKeyHint || (type === "search" ? "search" : "send");
2311
2355
  var handleChange = react.useCallback(function (ev) {
2312
2356
  if (onChange) {
2313
2357
  onChange({
@@ -2359,7 +2403,7 @@ var RichInput = function (props) {
2359
2403
  }
2360
2404
  return undefined;
2361
2405
  }, [inputNode, onSearch]);
2362
- return (jsxRuntime.jsx("div", { className: "xappw-rich-input ".concat(props.className), children: rich ? (jsxRuntime.jsx(RichText, { id: id, value: value, onChange: handleRichChange, onInput: handleRichInput, onKeyDown: handleKeyDown, className: "xappw-rich-input__input ".concat(props.className, "__input") })) : (jsxRuntime.jsx("input", { id: id, ref: inputRef, type: type, value: value.text, autoComplete: "off", autoFocus: autoFocus, placeholder: props.placeholder, spellCheck: spellCheck, tabIndex: tabIndex ? Number(tabIndex) : 0, maxLength: maxLength, className: "xappw-rich-input__input ".concat(props.className, "__input"), onFocus: props.onFocus, onChange: handleChange, onInput: handleInput, onKeyDown: handleKeyDown })) }));
2406
+ return (jsxRuntime.jsx("div", { className: "xappw-rich-input ".concat(props.className), children: rich ? (jsxRuntime.jsx(RichText, { id: id, value: value, onChange: handleRichChange, onInput: handleRichInput, onKeyDown: handleKeyDown, className: "xappw-rich-input__input ".concat(props.className, "__input") })) : (jsxRuntime.jsx("input", { id: id, ref: inputRef, type: type, value: value.text, autoComplete: "off", enterKeyHint: keyHint, autoFocus: autoFocus, placeholder: props.placeholder, spellCheck: spellCheck, tabIndex: tabIndex ? Number(tabIndex) : 0, maxLength: maxLength, className: "xappw-rich-input__input ".concat(props.className, "__input"), onFocus: props.onFocus, onChange: handleChange, onInput: handleInput, onKeyDown: handleKeyDown })) }));
2363
2407
  };
2364
2408
 
2365
2409
  var SuggestionsGroupHeading = function (props) {
@@ -12117,85 +12161,15 @@ var AdminBar = function (_a) {
12117
12161
  return (require$$0.jsx("div", { className: "xappw-admin-input-container visible", children: joined ? renderLeave() : renderJoin() }));
12118
12162
  };
12119
12163
 
12120
- var classnames = {exports: {}};
12121
-
12122
- /*!
12123
- Copyright (c) 2018 Jed Watson.
12124
- Licensed under the MIT License (MIT), see
12125
- http://jedwatson.github.io/classnames
12126
- */
12127
-
12128
- (function (module) {
12129
- /* global define */
12130
-
12131
- (function () {
12132
-
12133
- var hasOwn = {}.hasOwnProperty;
12134
-
12135
- function classNames () {
12136
- var classes = '';
12137
-
12138
- for (var i = 0; i < arguments.length; i++) {
12139
- var arg = arguments[i];
12140
- if (arg) {
12141
- classes = appendClass(classes, parseValue(arg));
12142
- }
12143
- }
12144
-
12145
- return classes;
12146
- }
12147
-
12148
- function parseValue (arg) {
12149
- if (typeof arg === 'string' || typeof arg === 'number') {
12150
- return arg;
12151
- }
12152
-
12153
- if (typeof arg !== 'object') {
12154
- return '';
12155
- }
12156
-
12157
- if (Array.isArray(arg)) {
12158
- return classNames.apply(null, arg);
12159
- }
12160
-
12161
- if (arg.toString !== Object.prototype.toString && !arg.toString.toString().includes('[native code]')) {
12162
- return arg.toString();
12163
- }
12164
-
12165
- var classes = '';
12166
-
12167
- for (var key in arg) {
12168
- if (hasOwn.call(arg, key) && arg[key]) {
12169
- classes = appendClass(classes, key);
12170
- }
12171
- }
12172
-
12173
- return classes;
12174
- }
12175
-
12176
- function appendClass (value, newClass) {
12177
- if (!newClass) {
12178
- return value;
12179
- }
12180
-
12181
- if (value) {
12182
- return value + ' ' + newClass;
12183
- }
12184
-
12185
- return value + newClass;
12186
- }
12187
-
12188
- if (module.exports) {
12189
- classNames.default = classNames;
12190
- module.exports = classNames;
12191
- } else {
12192
- window.classNames = classNames;
12193
- }
12194
- }());
12195
- } (classnames));
12196
-
12197
- var classnamesExports = classnames.exports;
12198
- var classNames = /*@__PURE__*/getDefaultExportFromCjs(classnamesExports);
12164
+ /**
12165
+ * Joins the keys of `classes` whose value is truthy into a single
12166
+ * space-separated string. Local replacement for the `classnames` package.
12167
+ */
12168
+ function classNames(classes) {
12169
+ return Object.keys(classes)
12170
+ .filter(function (key) { return classes[key]; })
12171
+ .join(" ");
12172
+ }
12199
12173
 
12200
12174
  var MarkdownBuilder = function (_a) {
12201
12175
  var text = _a.text, applyBrandingClass = _a.applyBrandingClass, linkColor = _a.linkColor;