@progress/kendo-react-conversational-ui
Version:
React Chat component allows the user to participate in chat sessions with users or chat bots. KendoReact Conversational UI components
209 lines (208 loc) • 7.59 kB
JavaScript
/**
* @license
*-------------------------------------------------------------------------------------------
* Copyright © 2025 Progress Software Corporation. All rights reserved.
* Licensed under commercial license. See LICENSE.md in the package root for more information
*-------------------------------------------------------------------------------------------
*/
import { Keys as n, dispatchEvent as l, validatePackage as p, WatermarkOverlay as h, classNames as u } from "@progress/kendo-react-common";
import o from "prop-types";
import * as i from "react";
import { convertMsgsToViewItems as d } from "../ViewItem.mjs";
import g from "./ActionGroup.mjs";
import f from "./AttachmentGroup.mjs";
import I from "./DateMarker.mjs";
import T from "./MessageGroup.mjs";
import w from "./NewMessage.mjs";
import { ChatMessage as k } from "./ChatMessage.mjs";
import { packageMetadata as y } from "../package-metadata.mjs";
import { ariaLabelMessageList as c, messages as S } from "../messages/index.mjs";
import { provideLocalizationService as x } from "@progress/kendo-react-intl";
const a = class a extends i.Component {
constructor(s) {
super(s), this.viewItems = [], this.isDirectionRightToLeft = !1, this.scrollToBottomOnLoadingData = !0, this.showLicenseWatermark = !1, this.onFocus = () => {
clearTimeout(this.timeoutIdForChatLosingFocus);
}, this.onBlur = () => {
this.timeoutIdForChatLosingFocus = window.setTimeout(() => {
this.setState({ selectedItemIndex: null });
}, 0);
}, this.onSelectionRequested = (e) => {
this.setState({ selectedItemIndex: e });
}, this.onKeyDown = (e) => {
let t = null;
const r = this.state.selectedItemIndex !== null ? this.state.selectedItemIndex : this.viewItems.lastSelectionIndex;
e.keyCode === n.up ? r === null ? t = 0 : r > 0 && (t = r - 1) : e.keyCode === n.down && (r === null ? t = 0 : r < this.viewItems.lastSelectionIndex && (t = r + 1)), t !== null && (this.setState({ selectedItemIndex: t }), e.preventDefault());
}, this.onMessageSend = (e, t) => {
l(this.props.onMessageSend, t, this, { message: e });
}, this.onActionExecute = (e, t) => {
if (l(this.props.onActionExecute, t, this, { action: e }), !t.isDefaultPrevented()) {
switch (e.type) {
case "reply":
this.onMessageSend(
{
author: this.props.user,
text: e.value,
timestamp: /* @__PURE__ */ new Date()
},
t
);
break;
case "call":
window.open("tel:" + e.value);
break;
case "openUrl":
window.open(e.value);
break;
}
this.newMsgComp.focusInput();
}
}, this.showLicenseWatermark = !p(y, { component: "Chat" }), this.state = { selectedItemIndex: null, isFirstRender: !0 };
}
/**
* @hidden
*/
render() {
this.viewItems = this.getViewItemsFromMsgs(this.props.messages), this.isDirectionRightToLeft = this.checkIsDirectionRightToLeft(this.props);
const s = x(this);
return /* @__PURE__ */ i.createElement(
"div",
{
style: { width: this.props.width, position: "relative" },
onKeyDown: this.onKeyDown,
className: this.getClassNames(),
ref: (e) => this.chatWrapperEl = e
},
/* @__PURE__ */ i.createElement(
"div",
{
className: "k-message-list k-avatars",
onBlur: this.onBlur,
onFocus: this.onFocus,
role: "log",
"aria-label": s.toLanguageString(
c,
S[c]
),
"aria-live": "polite",
onScroll: (e) => {
this.scrollToBottomOnLoadingData = e.currentTarget.scrollTop === e.currentTarget.scrollHeight - e.currentTarget.clientHeight;
},
ref: (e) => this.viewItemsWrapperEl = e
},
/* @__PURE__ */ i.createElement("div", { className: "k-message-list-content" }, this.renderViewItems())
),
/* @__PURE__ */ i.createElement(
w,
{
user: this.props.user,
onMessageSend: this.onMessageSend,
isDirectionRightToLeft: this.isDirectionRightToLeft,
ref: (e) => this.newMsgComp = e,
placeholder: this.props.placeholder,
MessageBox: this.props.messageBox,
toolbar: this.props.toolbar,
onToolbarActionButtonClick: this.props.onToolbarActionExecute,
showToolbar: this.props.showToolbar
}
),
this.showLicenseWatermark && /* @__PURE__ */ i.createElement(h, null)
);
}
/**
* @hidden
*/
componentDidMount() {
this.setState({ isFirstRender: !1 }, () => {
this.nextTickId = window.setTimeout(() => this.scrollViewItemsToBottom(), 250);
});
}
/**
* @hidden
*/
componentWillUnmount() {
clearTimeout(this.nextTickId);
}
/**
* @hidden
*/
componentDidUpdate(s) {
s.messages.length !== this.props.messages.length && this.scrollToBottomOnLoadingData && this.scrollViewItemsToBottom();
}
getClassNames() {
return u("k-chat", this.props.className, { "k-rtl": this.isDirectionRightToLeft });
}
checkIsDirectionRightToLeft(s) {
return !!(s.dir !== void 0 ? s.dir === "rtl" : this.chatWrapperEl && getComputedStyle(this.chatWrapperEl).direction === "rtl");
}
renderViewItems() {
const s = this.viewItems.length - 1;
return this.viewItems.map((e, t) => {
if (e.type === "date-marker")
return /* @__PURE__ */ i.createElement(I, { item: e, key: t });
if (e.type === "message-group")
return /* @__PURE__ */ i.createElement(
T,
{
group: e,
itemTemplate: this.props.messageTemplate,
attachmentTemplate: this.props.attachmentTemplate,
user: this.props.user,
selectedItemIndex: this.state.selectedItemIndex,
onRequestSelection: this.onSelectionRequested,
isLastGroup: t === s,
key: t,
message: this.props.message || a.defaultProps.message
}
);
if (e.type === "attachment-group")
return /* @__PURE__ */ i.createElement(
f,
{
group: e,
itemTemplate: this.props.attachmentTemplate,
onRequestSelection: this.onSelectionRequested,
selected: e.selectionIndex === this.state.selectedItemIndex,
isLastGroup: t === s,
key: t
}
);
if (e.type === "action-group")
return /* @__PURE__ */ i.createElement(
g,
{
group: e,
onActionExecute: this.onActionExecute,
onRequestSelection: this.onSelectionRequested,
selected: e.selectionIndex === this.state.selectedItemIndex,
isLastGroup: t === s,
key: t
}
);
});
}
scrollViewItemsToBottom() {
this.viewItemsWrapperEl && (this.viewItemsWrapperEl.scrollTop = this.viewItemsWrapperEl.scrollHeight - this.viewItemsWrapperEl.clientHeight);
}
getViewItemsFromMsgs(s) {
return s.length > 0 ? d(s) : [];
}
};
a.propTypes = {
messages: o.arrayOf(o.object),
user: o.object,
messageTemplate: o.any,
attachmentTemplate: o.any,
width: o.oneOfType([o.string, o.number]),
onMessageSend: o.func,
onActionExecute: o.func,
dir: o.string,
messageBox: o.any
}, a.defaultProps = {
messages: [],
dateFormat: "g",
message: k
};
let m = a;
export {
m as Chat
};