@yext/chat-ui-react 0.8.0 → 0.8.1-alpha.53.2
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/lib/commonjs/package.json.js +1 -1
- package/lib/commonjs/src/components/ChatInput.js +1 -1
- package/lib/commonjs/src/components/ChatPanel.d.ts +3 -1
- package/lib/commonjs/src/components/ChatPanel.d.ts.map +1 -1
- package/lib/commonjs/src/components/ChatPanel.js +8 -31
- package/lib/commonjs/src/components/ChatPanel.js.map +1 -1
- package/lib/commonjs/src/components/ChatPopUp.d.ts +1 -1
- package/lib/commonjs/src/components/ChatPopUp.d.ts.map +1 -1
- package/lib/commonjs/src/components/ChatPopUp.js +3 -3
- package/lib/commonjs/src/components/ChatPopUp.js.map +1 -1
- package/lib/commonjs/src/components/FeedbackButtons.d.ts +3 -4
- package/lib/commonjs/src/components/FeedbackButtons.d.ts.map +1 -1
- package/lib/commonjs/src/components/FeedbackButtons.js +2 -1
- package/lib/commonjs/src/components/FeedbackButtons.js.map +1 -1
- package/lib/commonjs/src/components/InitialMessagePopUp.js +1 -1
- package/lib/commonjs/src/components/Markdown.d.ts +7 -3
- package/lib/commonjs/src/components/Markdown.d.ts.map +1 -1
- package/lib/commonjs/src/components/Markdown.js +1 -1
- package/lib/commonjs/src/components/Markdown.js.map +1 -1
- package/lib/commonjs/src/components/index.d.ts +4 -1
- package/lib/commonjs/src/components/index.d.ts.map +1 -1
- package/lib/commonjs/src/hooks/index.d.ts +4 -0
- package/lib/commonjs/src/hooks/index.d.ts.map +1 -1
- package/lib/commonjs/src/hooks/useDefaultHandleApiError.d.ts +1 -1
- package/lib/commonjs/src/hooks/useDefaultHandleApiError.js +1 -1
- package/lib/commonjs/src/hooks/useDefaultHandleApiError.js.map +1 -1
- package/lib/commonjs/src/hooks/useFetchInitialMessage.d.ts +1 -1
- package/lib/commonjs/src/hooks/useFetchInitialMessage.js +1 -1
- package/lib/commonjs/src/hooks/useFetchInitialMessage.js.map +1 -1
- package/lib/commonjs/src/hooks/useReportAnalyticsEvent.d.ts +1 -1
- package/lib/commonjs/src/hooks/useReportAnalyticsEvent.js +1 -1
- package/lib/commonjs/src/hooks/useReportAnalyticsEvent.js.map +1 -1
- package/lib/commonjs/src/hooks/useScrollToLastMessage.d.ts +15 -0
- package/lib/commonjs/src/hooks/useScrollToLastMessage.d.ts.map +1 -0
- package/lib/commonjs/src/hooks/useScrollToLastMessage.js +45 -0
- package/lib/commonjs/src/hooks/useScrollToLastMessage.js.map +1 -0
- package/lib/commonjs/src/index.js +12 -0
- package/lib/commonjs/src/index.js.map +1 -1
- package/lib/esm/index.d.ts +94 -2
- package/lib/esm/package.json.mjs +1 -1
- package/lib/esm/src/components/ChatInput.mjs +1 -1
- package/lib/esm/src/components/ChatPanel.d.ts +3 -1
- package/lib/esm/src/components/ChatPanel.d.ts.map +1 -1
- package/lib/esm/src/components/ChatPanel.mjs +9 -32
- package/lib/esm/src/components/ChatPanel.mjs.map +1 -1
- package/lib/esm/src/components/ChatPopUp.d.ts +1 -1
- package/lib/esm/src/components/ChatPopUp.d.ts.map +1 -1
- package/lib/esm/src/components/ChatPopUp.mjs +3 -3
- package/lib/esm/src/components/ChatPopUp.mjs.map +1 -1
- package/lib/esm/src/components/FeedbackButtons.d.ts +3 -4
- package/lib/esm/src/components/FeedbackButtons.d.ts.map +1 -1
- package/lib/esm/src/components/FeedbackButtons.mjs +2 -1
- package/lib/esm/src/components/FeedbackButtons.mjs.map +1 -1
- package/lib/esm/src/components/InitialMessagePopUp.mjs +1 -1
- package/lib/esm/src/components/Markdown.d.ts +7 -3
- package/lib/esm/src/components/Markdown.d.ts.map +1 -1
- package/lib/esm/src/components/Markdown.mjs +1 -1
- package/lib/esm/src/components/Markdown.mjs.map +1 -1
- package/lib/esm/src/components/index.d.ts +4 -1
- package/lib/esm/src/components/index.d.ts.map +1 -1
- package/lib/esm/src/hooks/index.d.ts +4 -0
- package/lib/esm/src/hooks/index.d.ts.map +1 -1
- package/lib/esm/src/hooks/useDefaultHandleApiError.d.ts +1 -1
- package/lib/esm/src/hooks/useDefaultHandleApiError.mjs +1 -1
- package/lib/esm/src/hooks/useDefaultHandleApiError.mjs.map +1 -1
- package/lib/esm/src/hooks/useFetchInitialMessage.d.ts +1 -1
- package/lib/esm/src/hooks/useFetchInitialMessage.mjs +1 -1
- package/lib/esm/src/hooks/useFetchInitialMessage.mjs.map +1 -1
- package/lib/esm/src/hooks/useReportAnalyticsEvent.d.ts +1 -1
- package/lib/esm/src/hooks/useReportAnalyticsEvent.mjs +1 -1
- package/lib/esm/src/hooks/useReportAnalyticsEvent.mjs.map +1 -1
- package/lib/esm/src/hooks/useScrollToLastMessage.d.ts +15 -0
- package/lib/esm/src/hooks/useScrollToLastMessage.d.ts.map +1 -0
- package/lib/esm/src/hooks/useScrollToLastMessage.mjs +43 -0
- package/lib/esm/src/hooks/useScrollToLastMessage.mjs.map +1 -0
- package/lib/esm/src/index.mjs +6 -0
- package/lib/esm/src/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/components/ChatPanel.tsx +15 -37
- package/src/components/ChatPopUp.tsx +1 -1
- package/src/components/FeedbackButtons.tsx +3 -3
- package/src/components/Markdown.tsx +7 -2
- package/src/components/index.ts +6 -1
- package/src/hooks/index.ts +4 -0
- package/src/hooks/useDefaultHandleApiError.ts +1 -1
- package/src/hooks/useFetchInitialMessage.ts +1 -1
- package/src/hooks/useReportAnalyticsEvent.ts +1 -1
- package/src/hooks/useScrollToLastMessage.ts +47 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Markdown.mjs","sources":["../../../../src/components/Markdown.tsx"],"sourcesContent":["import ReactMarkdown, {\n PluggableList,\n ReactMarkdownOptions,\n} from \"react-markdown\";\nimport remarkGfm from \"remark-gfm\";\nimport rehypeRaw from \"rehype-raw\";\nimport rehypeSanitize from \"rehype-sanitize\";\nimport React, { useMemo } from \"react\";\nimport { useReportAnalyticsEvent } from \"../hooks/useReportAnalyticsEvent\";\n\n// The Remark and Rehype plugins to use in conjunction with ReactMarkdown.\nconst unifiedPlugins: { remark?: PluggableList; rehype: PluggableList } = {\n remark: [\n remarkGfm, //renders Github-Flavored Markdown\n ],\n rehype: [\n rehypeRaw, //to support HTML embedded in markdown\n rehypeSanitize, //to sanitize HTML content\n ],\n};\n\
|
|
1
|
+
{"version":3,"file":"Markdown.mjs","sources":["../../../../src/components/Markdown.tsx"],"sourcesContent":["import ReactMarkdown, {\n PluggableList,\n ReactMarkdownOptions,\n} from \"react-markdown\";\nimport remarkGfm from \"remark-gfm\";\nimport rehypeRaw from \"rehype-raw\";\nimport rehypeSanitize from \"rehype-sanitize\";\nimport React, { useMemo } from \"react\";\nimport { useReportAnalyticsEvent } from \"../hooks/useReportAnalyticsEvent\";\n\n// The Remark and Rehype plugins to use in conjunction with ReactMarkdown.\nconst unifiedPlugins: { remark?: PluggableList; rehype: PluggableList } = {\n remark: [\n remarkGfm, //renders Github-Flavored Markdown\n ],\n rehype: [\n rehypeRaw, //to support HTML embedded in markdown\n rehypeSanitize, //to sanitize HTML content\n ],\n};\n\n/**\n * The props for the {@link Markdown} component.\n * \n * @public\n */\nexport interface MarkdownProps {\n /** Stringified markdown. */\n content: string;\n /** The response ID correlates to the current message. */\n responseId?: string;\n /** Classnames for the container. */\n className?: string;\n}\n\n/**\n * Renders Github-Flavored Markdown from the Knowledge Graph. This Markdown can include\n * arbitrary HTML. Any HTML will be sanitized according to Rehype's default Schema.\n *\n * @remarks\n * A link click will send a CHAT_LINK_CLICK analytics event\n *\n * @public\n */\nexport function Markdown({ content, responseId, className }: MarkdownProps) {\n const reportAnalyticsEvent = useReportAnalyticsEvent();\n\n const components: ReactMarkdownOptions[\"components\"] = useMemo(() => {\n const createClickHandlerFn = (href?: string) => () => {\n reportAnalyticsEvent({\n action: \"CHAT_LINK_CLICK\",\n destinationUrl: href,\n chat: {\n responseId,\n },\n });\n };\n return {\n a: ({ node: _, children, ...props }) => {\n return (\n <a\n {...props}\n onClick={createClickHandlerFn(props.href)}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"cursor-pointer\"\n >\n {children}\n </a>\n );\n },\n };\n }, [reportAnalyticsEvent, responseId]);\n\n return (\n <ReactMarkdown\n className={className}\n children={content}\n remarkPlugins={unifiedPlugins.remark}\n rehypePlugins={unifiedPlugins.rehype}\n components={components}\n />\n );\n}\n"],"names":[],"mappings":";;;;;;;AAUA;AACA,MAAM,cAAc,GAAsD;AACxE,IAAA,MAAM,EAAE;AACN,QAAA,SAAS;AACV,KAAA;AACD,IAAA,MAAM,EAAE;QACN,SAAS;AACT,QAAA,cAAc;AACf,KAAA;CACF,CAAC;AAgBF;;;;;;;;AAQG;AACG,SAAU,QAAQ,CAAC,EAAE,OAAO,EAAE,UAAU,EAAE,SAAS,EAAiB,EAAA;AACxE,IAAA,MAAM,oBAAoB,GAAG,uBAAuB,EAAE,CAAC;AAEvD,IAAA,MAAM,UAAU,GAAuC,OAAO,CAAC,MAAK;QAClE,MAAM,oBAAoB,GAAG,CAAC,IAAa,KAAK,MAAK;AACnD,YAAA,oBAAoB,CAAC;AACnB,gBAAA,MAAM,EAAE,iBAAiB;AACzB,gBAAA,cAAc,EAAE,IAAI;AACpB,gBAAA,IAAI,EAAE;oBACJ,UAAU;AACX,iBAAA;AACF,aAAA,CAAC,CAAC;AACL,SAAC,CAAC;QACF,OAAO;AACL,YAAA,CAAC,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,QAAQ,EAAE,GAAG,KAAK,EAAE,KAAI;AACrC,gBAAA,QACE,KAAA,CAAA,aAAA,CAAA,GAAA,EAAA,EAAA,GACM,KAAK,EACT,OAAO,EAAE,oBAAoB,CAAC,KAAK,CAAC,IAAI,CAAC,EACzC,MAAM,EAAC,QAAQ,EACf,GAAG,EAAC,qBAAqB,EACzB,SAAS,EAAC,gBAAgB,EAEzB,EAAA,QAAQ,CACP,EACJ;aACH;SACF,CAAC;AACJ,KAAC,EAAE,CAAC,oBAAoB,EAAE,UAAU,CAAC,CAAC,CAAC;AAEvC,IAAA,QACE,KAAA,CAAA,aAAA,CAAC,aAAa,EAAA,EACZ,SAAS,EAAE,SAAS,EACpB,QAAQ,EAAE,OAAO,EACjB,aAAa,EAAE,cAAc,CAAC,MAAM,EACpC,aAAa,EAAE,cAAc,CAAC,MAAM,EACpC,UAAU,EAAE,UAAU,EAAA,CACtB,EACF;AACJ;;;;"}
|
|
@@ -8,6 +8,9 @@ export { ChatPanel } from "./ChatPanel";
|
|
|
8
8
|
export type { ChatPanelCssClasses, ChatPanelProps } from "./ChatPanel";
|
|
9
9
|
export { ChatPopUp } from "./ChatPopUp";
|
|
10
10
|
export type { ChatPopUpCssClasses, ChatPopUpProps } from "./ChatPopUp";
|
|
11
|
-
export
|
|
11
|
+
export { FeedbackButtons } from "./FeedbackButtons";
|
|
12
|
+
export type { FeedbackButtonsCssClasses, FeedbackButtonsProps } from "./FeedbackButtons";
|
|
13
|
+
export { Markdown } from "./Markdown";
|
|
14
|
+
export { MarkdownProps } from "./Markdown";
|
|
12
15
|
export type { InitialMessagePopUpCssClasses } from "./InitialMessagePopUp";
|
|
13
16
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,YAAY,EAAE,mBAAmB,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAEvE,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,YAAY,EAAE,oBAAoB,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAE1E,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,YAAY,EACV,uBAAuB,EACvB,kBAAkB,GACnB,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,YAAY,EAAE,mBAAmB,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAEvE,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,YAAY,EAAE,mBAAmB,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAEvE,YAAY,EAAE,yBAAyB,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,YAAY,EAAE,mBAAmB,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAEvE,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,YAAY,EAAE,oBAAoB,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAE1E,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,YAAY,EACV,uBAAuB,EACvB,kBAAkB,GACnB,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,YAAY,EAAE,mBAAmB,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAEvE,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,YAAY,EAAE,mBAAmB,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAEvE,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,YAAY,EAAE,yBAAyB,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AAEzF,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAE3C,YAAY,EAAE,6BAA6B,EAAE,MAAM,uBAAuB,CAAC"}
|
|
@@ -1,2 +1,6 @@
|
|
|
1
1
|
export { useComposedCssClasses } from "./useComposedCssClasses";
|
|
2
|
+
export { useDefaultHandleApiError } from "./useDefaultHandleApiError";
|
|
3
|
+
export { useFetchInitialMessage } from "./useFetchInitialMessage";
|
|
4
|
+
export { useReportAnalyticsEvent } from "./useReportAnalyticsEvent";
|
|
5
|
+
export { useScrollToLastMessage } from "./useScrollToLastMessage";
|
|
2
6
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/hooks/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/hooks/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAChE,OAAO,EAAE,wBAAwB,EAAE,MAAM,4BAA4B,CAAC;AACtE,OAAO,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AAClE,OAAO,EAAE,uBAAuB,EAAE,MAAM,2BAA2B,CAAC;AACpE,OAAO,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC"}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Returns a default handler function for API errors. It will log the error and
|
|
3
3
|
* add a default error message to state.
|
|
4
4
|
*
|
|
5
|
-
* @
|
|
5
|
+
* @public
|
|
6
6
|
*/
|
|
7
7
|
export declare function useDefaultHandleApiError(): (e: unknown) => void;
|
|
8
8
|
//# sourceMappingURL=useDefaultHandleApiError.d.ts.map
|
|
@@ -5,7 +5,7 @@ import { useCallback } from 'react';
|
|
|
5
5
|
* Returns a default handler function for API errors. It will log the error and
|
|
6
6
|
* add a default error message to state.
|
|
7
7
|
*
|
|
8
|
-
* @
|
|
8
|
+
* @public
|
|
9
9
|
*/
|
|
10
10
|
function useDefaultHandleApiError() {
|
|
11
11
|
const chat = useChatActions();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useDefaultHandleApiError.mjs","sources":["../../../../src/hooks/useDefaultHandleApiError.ts"],"sourcesContent":["import { MessageSource, useChatActions } from \"@yext/chat-headless-react\";\nimport { useCallback } from \"react\";\n\n/**\n * Returns a default handler function for API errors. It will log the error and\n * add a default error message to state.\n *\n * @
|
|
1
|
+
{"version":3,"file":"useDefaultHandleApiError.mjs","sources":["../../../../src/hooks/useDefaultHandleApiError.ts"],"sourcesContent":["import { MessageSource, useChatActions } from \"@yext/chat-headless-react\";\nimport { useCallback } from \"react\";\n\n/**\n * Returns a default handler function for API errors. It will log the error and\n * add a default error message to state.\n *\n * @public\n */\nexport function useDefaultHandleApiError() {\n const chat = useChatActions();\n\n return useCallback(\n (e: unknown) => {\n console.error(e);\n chat.addMessage({\n text: \"Sorry, I'm unable to respond at the moment. Please try again later!\",\n source: MessageSource.BOT,\n timestamp: new Date().toISOString(),\n });\n },\n [chat]\n );\n}\n"],"names":[],"mappings":";;;AAGA;;;;;AAKG;SACa,wBAAwB,GAAA;AACtC,IAAA,MAAM,IAAI,GAAG,cAAc,EAAE,CAAC;AAE9B,IAAA,OAAO,WAAW,CAChB,CAAC,CAAU,KAAI;AACb,QAAA,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QACjB,IAAI,CAAC,UAAU,CAAC;AACd,YAAA,IAAI,EAAE,qEAAqE;YAC3E,MAAM,EAAE,aAAa,CAAC,GAAG;AACzB,YAAA,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;AACpC,SAAA,CAAC,CAAC;AACL,KAAC,EACD,CAAC,IAAI,CAAC,CACP,CAAC;AACJ;;;;"}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Sends a request to Chat API to fetch the initial message when the
|
|
3
3
|
* conversation first start or when the message history is reset.
|
|
4
4
|
*
|
|
5
|
-
* @
|
|
5
|
+
* @public
|
|
6
6
|
*
|
|
7
7
|
* @param handleError - A function which is called when an error occurs while fetching for initial message.
|
|
8
8
|
* By default, the error is logged to the console and an error message is added to state.
|
|
@@ -6,7 +6,7 @@ import { useDefaultHandleApiError } from './useDefaultHandleApiError.mjs';
|
|
|
6
6
|
* Sends a request to Chat API to fetch the initial message when the
|
|
7
7
|
* conversation first start or when the message history is reset.
|
|
8
8
|
*
|
|
9
|
-
* @
|
|
9
|
+
* @public
|
|
10
10
|
*
|
|
11
11
|
* @param handleError - A function which is called when an error occurs while fetching for initial message.
|
|
12
12
|
* By default, the error is logged to the console and an error message is added to state.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useFetchInitialMessage.mjs","sources":["../../../../src/hooks/useFetchInitialMessage.ts"],"sourcesContent":["import { useEffect, useState } from \"react\";\nimport { useChatState, useChatActions } from \"@yext/chat-headless-react\";\nimport { useDefaultHandleApiError } from \"../hooks/useDefaultHandleApiError\";\n\n/**\n * Sends a request to Chat API to fetch the initial message when the\n * conversation first start or when the message history is reset.\n *\n * @
|
|
1
|
+
{"version":3,"file":"useFetchInitialMessage.mjs","sources":["../../../../src/hooks/useFetchInitialMessage.ts"],"sourcesContent":["import { useEffect, useState } from \"react\";\nimport { useChatState, useChatActions } from \"@yext/chat-headless-react\";\nimport { useDefaultHandleApiError } from \"../hooks/useDefaultHandleApiError\";\n\n/**\n * Sends a request to Chat API to fetch the initial message when the\n * conversation first start or when the message history is reset.\n *\n * @public\n *\n * @param handleError - A function which is called when an error occurs while fetching for initial message.\n * By default, the error is logged to the console and an error message is added to state.\n * @param stream - Enable streaming behavior by making a request to Chat Streaming API. Defaults to false.\n * @param customCondition - additional condition for when to fetch initial message\n */\nexport function useFetchInitialMessage(\n handleError?: (e: unknown) => void,\n stream = false,\n customCondition = true\n) {\n const chat = useChatActions();\n const defaultHandleApiError = useDefaultHandleApiError();\n const messages = useChatState((state) => state.conversation.messages);\n const [fetchInitialMessage, setFetchInitialMessage] = useState(\n messages.length === 0\n );\n const [messagesLength, setMessagesLength] = useState(messages.length);\n const canSendMessage = useChatState(\n (state) => state.conversation.canSendMessage\n );\n\n //handle message history resets\n useEffect(() => {\n const newMessagesLength = messages.length;\n // Fetch data only when the conversation messages changes from non-zero to zero\n if (messagesLength > 0 && newMessagesLength === 0) {\n setFetchInitialMessage(true);\n }\n setMessagesLength(newMessagesLength);\n }, [messages.length, messagesLength]);\n\n useEffect(() => {\n if (!fetchInitialMessage || !canSendMessage || !customCondition) {\n return;\n }\n setFetchInitialMessage(false);\n const res = stream ? chat.streamNextMessage() : chat.getNextMessage();\n res.catch((e) => (handleError ? handleError(e) : defaultHandleApiError(e)));\n }, [\n chat,\n stream,\n handleError,\n defaultHandleApiError,\n fetchInitialMessage,\n canSendMessage,\n customCondition,\n ]);\n}\n"],"names":[],"mappings":";;;;AAIA;;;;;;;;;;AAUG;AACG,SAAU,sBAAsB,CACpC,WAAkC,EAClC,MAAM,GAAG,KAAK,EACd,eAAe,GAAG,IAAI,EAAA;AAEtB,IAAA,MAAM,IAAI,GAAG,cAAc,EAAE,CAAC;AAC9B,IAAA,MAAM,qBAAqB,GAAG,wBAAwB,EAAE,CAAC;AACzD,IAAA,MAAM,QAAQ,GAAG,YAAY,CAAC,CAAC,KAAK,KAAK,KAAK,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC;AACtE,IAAA,MAAM,CAAC,mBAAmB,EAAE,sBAAsB,CAAC,GAAG,QAAQ,CAC5D,QAAQ,CAAC,MAAM,KAAK,CAAC,CACtB,CAAC;AACF,IAAA,MAAM,CAAC,cAAc,EAAE,iBAAiB,CAAC,GAAG,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;AACtE,IAAA,MAAM,cAAc,GAAG,YAAY,CACjC,CAAC,KAAK,KAAK,KAAK,CAAC,YAAY,CAAC,cAAc,CAC7C,CAAC;;IAGF,SAAS,CAAC,MAAK;AACb,QAAA,MAAM,iBAAiB,GAAG,QAAQ,CAAC,MAAM,CAAC;;AAE1C,QAAA,IAAI,cAAc,GAAG,CAAC,IAAI,iBAAiB,KAAK,CAAC,EAAE;YACjD,sBAAsB,CAAC,IAAI,CAAC,CAAC;AAC9B,SAAA;QACD,iBAAiB,CAAC,iBAAiB,CAAC,CAAC;KACtC,EAAE,CAAC,QAAQ,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC,CAAC;IAEtC,SAAS,CAAC,MAAK;QACb,IAAI,CAAC,mBAAmB,IAAI,CAAC,cAAc,IAAI,CAAC,eAAe,EAAE;YAC/D,OAAO;AACR,SAAA;QACD,sBAAsB,CAAC,KAAK,CAAC,CAAC;AAC9B,QAAA,MAAM,GAAG,GAAG,MAAM,GAAG,IAAI,CAAC,iBAAiB,EAAE,GAAG,IAAI,CAAC,cAAc,EAAE,CAAC;QACtE,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,WAAW,GAAG,WAAW,CAAC,CAAC,CAAC,GAAG,qBAAqB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAC9E,KAAC,EAAE;QACD,IAAI;QACJ,MAAM;QACN,WAAW;QACX,qBAAqB;QACrB,mBAAmB;QACnB,cAAc;QACd,eAAe;AAChB,KAAA,CAAC,CAAC;AACL;;;;"}
|
|
@@ -4,7 +4,7 @@ import { ChatHeadless } from "@yext/chat-headless-react";
|
|
|
4
4
|
* The payload will automatically includes chat-ui-react's
|
|
5
5
|
* package version for "clientSdk" field.
|
|
6
6
|
*
|
|
7
|
-
* @
|
|
7
|
+
* @public
|
|
8
8
|
*/
|
|
9
9
|
export declare function useReportAnalyticsEvent(): ChatHeadless["report"];
|
|
10
10
|
//# sourceMappingURL=useReportAnalyticsEvent.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useReportAnalyticsEvent.mjs","sources":["../../../../src/hooks/useReportAnalyticsEvent.ts"],"sourcesContent":["import { ChatHeadless, useChatActions } from \"@yext/chat-headless-react\";\nimport { version } from \"../../package.json\";\nimport { useCallback } from \"react\";\n\n/**\n * Returns a function to send requests to Yext Analytics API.\n * The payload will automatically includes chat-ui-react's\n * package version for \"clientSdk\" field.\n *\n * @
|
|
1
|
+
{"version":3,"file":"useReportAnalyticsEvent.mjs","sources":["../../../../src/hooks/useReportAnalyticsEvent.ts"],"sourcesContent":["import { ChatHeadless, useChatActions } from \"@yext/chat-headless-react\";\nimport { version } from \"../../package.json\";\nimport { useCallback } from \"react\";\n\n/**\n * Returns a function to send requests to Yext Analytics API.\n * The payload will automatically includes chat-ui-react's\n * package version for \"clientSdk\" field.\n *\n * @public\n */\nexport function useReportAnalyticsEvent(): ChatHeadless[\"report\"] {\n const chat = useChatActions();\n chat.addClientSdk({\n CHAT_UI_REACT: version,\n });\n return useCallback((payload) => chat.report(payload), [chat]);\n}\n"],"names":[],"mappings":";;;;AAIA;;;;;;AAMG;SACa,uBAAuB,GAAA;AACrC,IAAA,MAAM,IAAI,GAAG,cAAc,EAAE,CAAC;IAC9B,IAAI,CAAC,YAAY,CAAC;AAChB,QAAA,aAAa,EAAE,OAAO;AACvB,KAAA,CAAC,CAAC;AACH,IAAA,OAAO,WAAW,CAAC,CAAC,OAAO,KAAK,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC;AAChE;;;;"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
/**
|
|
3
|
+
* Scroll the messsages container to the top of the last message whenever there's
|
|
4
|
+
* an update to the messages state.
|
|
5
|
+
*
|
|
6
|
+
* @public
|
|
7
|
+
*
|
|
8
|
+
* @returns a ref to set on the messages container element and
|
|
9
|
+
* a function to set ref on individual message element
|
|
10
|
+
*/
|
|
11
|
+
export declare function useScrollToLastMessage(): [
|
|
12
|
+
React.RefObject<HTMLDivElement>,
|
|
13
|
+
(index: number) => ((message: HTMLDivElement) => void) | undefined
|
|
14
|
+
];
|
|
15
|
+
//# sourceMappingURL=useScrollToLastMessage.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useScrollToLastMessage.d.ts","sourceRoot":"","sources":["../../../../src/hooks/useScrollToLastMessage.ts"],"names":[],"mappings":"AACA,OAAO,KAAyC,MAAM,OAAO,CAAC;AAE9D;;;;;;;;GAQG;AACH,wBAAgB,sBAAsB,IAAI;IACxC,KAAK,CAAC,SAAS,CAAC,cAAc,CAAC;IAC/B,CAAC,KAAK,EAAE,MAAM,KAAK,CAAC,CAAC,OAAO,EAAE,cAAc,KAAK,IAAI,CAAC,GAAG,SAAS;CACnE,CA+BA"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { useChatState } from '@yext/chat-headless-react';
|
|
2
|
+
import { useRef, useEffect, useCallback } from 'react';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Scroll the messsages container to the top of the last message whenever there's
|
|
6
|
+
* an update to the messages state.
|
|
7
|
+
*
|
|
8
|
+
* @public
|
|
9
|
+
*
|
|
10
|
+
* @returns a ref to set on the messages container element and
|
|
11
|
+
* a function to set ref on individual message element
|
|
12
|
+
*/
|
|
13
|
+
function useScrollToLastMessage() {
|
|
14
|
+
const messagesRef = useRef([]);
|
|
15
|
+
const messagesContainerRef = useRef(null);
|
|
16
|
+
const messages = useChatState((state) => state.conversation.messages);
|
|
17
|
+
// Handle scrolling when messages change
|
|
18
|
+
useEffect(() => {
|
|
19
|
+
let scrollTop = 0;
|
|
20
|
+
messagesRef.current = messagesRef.current.slice(0, messages.length);
|
|
21
|
+
// Sums up scroll heights of all messages except the last one
|
|
22
|
+
if (messagesRef?.current.length > 1) {
|
|
23
|
+
scrollTop = messagesRef.current
|
|
24
|
+
.slice(0, -1)
|
|
25
|
+
.map((elem, _) => elem?.scrollHeight ?? 0)
|
|
26
|
+
.reduce((total, height) => total + height);
|
|
27
|
+
}
|
|
28
|
+
// Scroll to the top of the last message
|
|
29
|
+
messagesContainerRef.current?.scroll({
|
|
30
|
+
top: scrollTop,
|
|
31
|
+
behavior: "smooth",
|
|
32
|
+
});
|
|
33
|
+
}, [messages]);
|
|
34
|
+
const setMessageRef = useCallback((index) => {
|
|
35
|
+
if (!messagesRef?.current)
|
|
36
|
+
return undefined;
|
|
37
|
+
return (message) => (messagesRef.current[index] = message);
|
|
38
|
+
}, []);
|
|
39
|
+
return [messagesContainerRef, setMessageRef];
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export { useScrollToLastMessage };
|
|
43
|
+
//# sourceMappingURL=useScrollToLastMessage.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useScrollToLastMessage.mjs","sources":["../../../../src/hooks/useScrollToLastMessage.ts"],"sourcesContent":["import { useChatState } from \"@yext/chat-headless-react\";\nimport React, { useCallback, useEffect, useRef } from \"react\";\n\n/**\n * Scroll the messsages container to the top of the last message whenever there's\n * an update to the messages state.\n * \n * @public\n * \n * @returns a ref to set on the messages container element and\n * a function to set ref on individual message element\n */\nexport function useScrollToLastMessage(): [\n React.RefObject<HTMLDivElement>,\n (index: number) => ((message: HTMLDivElement) => void) | undefined\n] {\n const messagesRef = useRef<Array<HTMLDivElement | null>>([]);\n const messagesContainerRef = useRef<HTMLDivElement>(null);\n const messages = useChatState((state) => state.conversation.messages);\n\n // Handle scrolling when messages change\n useEffect(() => {\n let scrollTop = 0;\n messagesRef.current = messagesRef.current.slice(0, messages.length);\n\n // Sums up scroll heights of all messages except the last one\n if (messagesRef?.current.length > 1) {\n scrollTop = messagesRef.current\n .slice(0, -1)\n .map((elem, _) => elem?.scrollHeight ?? 0)\n .reduce((total, height) => total + height);\n }\n\n // Scroll to the top of the last message\n messagesContainerRef.current?.scroll({\n top: scrollTop,\n behavior: \"smooth\",\n });\n }, [messages]);\n\n const setMessageRef = useCallback((index) => {\n if (!messagesRef?.current) return undefined;\n return (message: HTMLDivElement) => (messagesRef.current[index] = message);\n }, []);\n\n return [messagesContainerRef, setMessageRef]\n}"],"names":[],"mappings":";;;AAGA;;;;;;;;AAQG;SACa,sBAAsB,GAAA;AAIpC,IAAA,MAAM,WAAW,GAAG,MAAM,CAA+B,EAAE,CAAC,CAAC;AAC7D,IAAA,MAAM,oBAAoB,GAAG,MAAM,CAAiB,IAAI,CAAC,CAAC;AAC1D,IAAA,MAAM,QAAQ,GAAG,YAAY,CAAC,CAAC,KAAK,KAAK,KAAK,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC;;IAGtE,SAAS,CAAC,MAAK;QACb,IAAI,SAAS,GAAG,CAAC,CAAC;AAClB,QAAA,WAAW,CAAC,OAAO,GAAG,WAAW,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC;;AAGpE,QAAA,IAAI,WAAW,EAAE,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE;YACnC,SAAS,GAAG,WAAW,CAAC,OAAO;AAC5B,iBAAA,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;AACZ,iBAAA,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,KAAK,IAAI,EAAE,YAAY,IAAI,CAAC,CAAC;AACzC,iBAAA,MAAM,CAAC,CAAC,KAAK,EAAE,MAAM,KAAK,KAAK,GAAG,MAAM,CAAC,CAAC;AAC9C,SAAA;;AAGD,QAAA,oBAAoB,CAAC,OAAO,EAAE,MAAM,CAAC;AACnC,YAAA,GAAG,EAAE,SAAS;AACd,YAAA,QAAQ,EAAE,QAAQ;AACnB,SAAA,CAAC,CAAC;AACL,KAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC;AAEf,IAAA,MAAM,aAAa,GAAG,WAAW,CAAC,CAAC,KAAK,KAAI;QAC1C,IAAI,CAAC,WAAW,EAAE,OAAO;AAAE,YAAA,OAAO,SAAS,CAAC;AAC5C,QAAA,OAAO,CAAC,OAAuB,MAAM,WAAW,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,OAAO,CAAC,CAAC;KAC5E,EAAE,EAAE,CAAC,CAAC;AAEP,IAAA,OAAO,CAAC,oBAAoB,EAAE,aAAa,CAAC,CAAA;AAC9C;;;;"}
|
package/lib/esm/src/index.mjs
CHANGED
|
@@ -3,5 +3,11 @@ export { ChatHeader } from './components/ChatHeader.mjs';
|
|
|
3
3
|
export { MessageBubble } from './components/MessageBubble.mjs';
|
|
4
4
|
export { ChatPanel } from './components/ChatPanel.mjs';
|
|
5
5
|
export { ChatPopUp } from './components/ChatPopUp.mjs';
|
|
6
|
+
export { FeedbackButtons } from './components/FeedbackButtons.mjs';
|
|
7
|
+
export { Markdown } from './components/Markdown.mjs';
|
|
6
8
|
export { useComposedCssClasses } from './hooks/useComposedCssClasses.mjs';
|
|
9
|
+
export { useDefaultHandleApiError } from './hooks/useDefaultHandleApiError.mjs';
|
|
10
|
+
export { useFetchInitialMessage } from './hooks/useFetchInitialMessage.mjs';
|
|
11
|
+
export { useReportAnalyticsEvent } from './hooks/useReportAnalyticsEvent.mjs';
|
|
12
|
+
export { useScrollToLastMessage } from './hooks/useScrollToLastMessage.mjs';
|
|
7
13
|
//# sourceMappingURL=index.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.mjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;"}
|
package/package.json
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React, {
|
|
1
|
+
import React, { useEffect } from "react";
|
|
2
2
|
import { useChatState } from "@yext/chat-headless-react";
|
|
3
3
|
import {
|
|
4
4
|
MessageBubble,
|
|
@@ -7,10 +7,13 @@ import {
|
|
|
7
7
|
} from "./MessageBubble";
|
|
8
8
|
import { ChatInput, ChatInputCssClasses, ChatInputProps } from "./ChatInput";
|
|
9
9
|
import { LoadingDots } from "./LoadingDots";
|
|
10
|
-
import {
|
|
10
|
+
import {
|
|
11
|
+
useComposedCssClasses,
|
|
12
|
+
useReportAnalyticsEvent,
|
|
13
|
+
useFetchInitialMessage,
|
|
14
|
+
useScrollToLastMessage,
|
|
15
|
+
} from "../hooks";
|
|
11
16
|
import { withStylelessCssClasses } from "../utils/withStylelessCssClasses";
|
|
12
|
-
import { useReportAnalyticsEvent } from "../hooks/useReportAnalyticsEvent";
|
|
13
|
-
import { useFetchInitialMessage } from "../hooks/useFetchInitialMessage";
|
|
14
17
|
|
|
15
18
|
/**
|
|
16
19
|
* The CSS class interface for the {@link ChatPanel} component.
|
|
@@ -47,8 +50,10 @@ const builtInCssClasses: ChatPanelCssClasses = withStylelessCssClasses(
|
|
|
47
50
|
export interface ChatPanelProps
|
|
48
51
|
extends Omit<MessageBubbleProps, "customCssClasses" | "message">,
|
|
49
52
|
Omit<ChatInputProps, "customCssClasses"> {
|
|
50
|
-
/** A header to render at the top of the panel. */
|
|
53
|
+
/** A custom header component to render at the top of the panel. */
|
|
51
54
|
header?: JSX.Element;
|
|
55
|
+
/** A custom input component to render at the bottom of the panel. */
|
|
56
|
+
input?: JSX.Element;
|
|
52
57
|
/**
|
|
53
58
|
* CSS classes for customizing the component styling.
|
|
54
59
|
*/
|
|
@@ -65,12 +70,13 @@ export interface ChatPanelProps
|
|
|
65
70
|
* @param props - {@link ChatPanelProps}
|
|
66
71
|
*/
|
|
67
72
|
export function ChatPanel(props: ChatPanelProps) {
|
|
68
|
-
const { header, customCssClasses, stream, handleError } = props;
|
|
73
|
+
const { header, input, customCssClasses, stream, handleError } = props;
|
|
69
74
|
const messages = useChatState((state) => state.conversation.messages);
|
|
70
75
|
const loading = useChatState((state) => state.conversation.isLoading);
|
|
71
76
|
const cssClasses = useComposedCssClasses(builtInCssClasses, customCssClasses);
|
|
72
77
|
const reportAnalyticsEvent = useReportAnalyticsEvent();
|
|
73
78
|
useFetchInitialMessage(handleError, stream);
|
|
79
|
+
const [messagesContainerRef, setMessageRef] = useScrollToLastMessage();
|
|
74
80
|
|
|
75
81
|
useEffect(() => {
|
|
76
82
|
reportAnalyticsEvent({
|
|
@@ -78,42 +84,14 @@ export function ChatPanel(props: ChatPanelProps) {
|
|
|
78
84
|
});
|
|
79
85
|
}, [reportAnalyticsEvent]);
|
|
80
86
|
|
|
81
|
-
const messagesRef = useRef<Array<HTMLDivElement | null>>([]);
|
|
82
|
-
const messagesContainer = useRef<HTMLDivElement>(null);
|
|
83
|
-
|
|
84
|
-
// Handle scrolling when messages change
|
|
85
|
-
useEffect(() => {
|
|
86
|
-
let scrollTop = 0;
|
|
87
|
-
messagesRef.current = messagesRef.current.slice(0, messages.length);
|
|
88
|
-
|
|
89
|
-
// Sums up scroll heights of all messages except the last one
|
|
90
|
-
if (messagesRef?.current.length > 1) {
|
|
91
|
-
scrollTop = messagesRef.current
|
|
92
|
-
.slice(0, -1)
|
|
93
|
-
.map((elem, _) => elem?.scrollHeight ?? 0)
|
|
94
|
-
.reduce((total, height) => total + height);
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
// Scroll to the top of the last message
|
|
98
|
-
messagesContainer.current?.scroll({
|
|
99
|
-
top: scrollTop,
|
|
100
|
-
behavior: "smooth",
|
|
101
|
-
});
|
|
102
|
-
}, [messages]);
|
|
103
|
-
|
|
104
|
-
const setMessagesRef = useCallback((index) => {
|
|
105
|
-
if (!messagesRef?.current) return null;
|
|
106
|
-
return (message) => (messagesRef.current[index] = message);
|
|
107
|
-
}, []);
|
|
108
|
-
|
|
109
87
|
return (
|
|
110
88
|
<div className="yext-chat w-full h-full">
|
|
111
89
|
<div className={cssClasses.container}>
|
|
112
90
|
{header}
|
|
113
91
|
<div className={cssClasses.messagesScrollContainer}>
|
|
114
|
-
<div ref={
|
|
92
|
+
<div ref={messagesContainerRef} className={cssClasses.messagesContainer}>
|
|
115
93
|
{messages.map((message, index) => (
|
|
116
|
-
<div key={index} ref={
|
|
94
|
+
<div key={index} ref={setMessageRef(index)}>
|
|
117
95
|
<MessageBubble
|
|
118
96
|
{...props}
|
|
119
97
|
customCssClasses={cssClasses.messageBubbleCssClasses}
|
|
@@ -125,7 +103,7 @@ export function ChatPanel(props: ChatPanelProps) {
|
|
|
125
103
|
</div>
|
|
126
104
|
</div>
|
|
127
105
|
<div className={cssClasses.inputContainer}>
|
|
128
|
-
<ChatInput {...props} customCssClasses={cssClasses.inputCssClasses} />
|
|
106
|
+
{input ?? <ChatInput {...props} customCssClasses={cssClasses.inputCssClasses} />}
|
|
129
107
|
</div>
|
|
130
108
|
</div>
|
|
131
109
|
</div>
|
|
@@ -82,7 +82,7 @@ const builtInCssClasses: ChatPopUpCssClasses = withStylelessCssClasses(
|
|
|
82
82
|
*/
|
|
83
83
|
export interface ChatPopUpProps
|
|
84
84
|
extends Omit<ChatHeaderProps, "showCloseButton" | "customCssClasses">,
|
|
85
|
-
Omit<ChatPanelProps, "header" | "customCssClasses"> {
|
|
85
|
+
Omit<ChatPanelProps, "header" | "input" | "customCssClasses"> {
|
|
86
86
|
/** Custom icon for the popup button to open the panel. */
|
|
87
87
|
openPanelButtonIcon?: JSX.Element;
|
|
88
88
|
/** CSS classes for customizing the component styling. */
|
|
@@ -39,9 +39,9 @@ const builtInCssClasses: FeedbackButtonsCssClasses =
|
|
|
39
39
|
/**
|
|
40
40
|
* The props for the FeedbackButtons component.
|
|
41
41
|
*
|
|
42
|
-
* @
|
|
42
|
+
* @public
|
|
43
43
|
*/
|
|
44
|
-
interface FeedbackButtonsProps {
|
|
44
|
+
export interface FeedbackButtonsProps {
|
|
45
45
|
/** The response ID correlates to the current message to give feedback on. */
|
|
46
46
|
responseId?: string;
|
|
47
47
|
/** CSS classes for customizing the component styling. */
|
|
@@ -52,7 +52,7 @@ interface FeedbackButtonsProps {
|
|
|
52
52
|
* Displays feedback buttons (e.g. thumbs up and thumbs down) that will
|
|
53
53
|
* report analytic events on click.
|
|
54
54
|
*
|
|
55
|
-
* @
|
|
55
|
+
* @public
|
|
56
56
|
*/
|
|
57
57
|
export function FeedbackButtons({
|
|
58
58
|
customCssClasses,
|
|
@@ -19,7 +19,12 @@ const unifiedPlugins: { remark?: PluggableList; rehype: PluggableList } = {
|
|
|
19
19
|
],
|
|
20
20
|
};
|
|
21
21
|
|
|
22
|
-
|
|
22
|
+
/**
|
|
23
|
+
* The props for the {@link Markdown} component.
|
|
24
|
+
*
|
|
25
|
+
* @public
|
|
26
|
+
*/
|
|
27
|
+
export interface MarkdownProps {
|
|
23
28
|
/** Stringified markdown. */
|
|
24
29
|
content: string;
|
|
25
30
|
/** The response ID correlates to the current message. */
|
|
@@ -35,7 +40,7 @@ interface MarkdownProps {
|
|
|
35
40
|
* @remarks
|
|
36
41
|
* A link click will send a CHAT_LINK_CLICK analytics event
|
|
37
42
|
*
|
|
38
|
-
* @
|
|
43
|
+
* @public
|
|
39
44
|
*/
|
|
40
45
|
export function Markdown({ content, responseId, className }: MarkdownProps) {
|
|
41
46
|
const reportAnalyticsEvent = useReportAnalyticsEvent();
|
package/src/components/index.ts
CHANGED
|
@@ -16,5 +16,10 @@ export type { ChatPanelCssClasses, ChatPanelProps } from "./ChatPanel";
|
|
|
16
16
|
export { ChatPopUp } from "./ChatPopUp";
|
|
17
17
|
export type { ChatPopUpCssClasses, ChatPopUpProps } from "./ChatPopUp";
|
|
18
18
|
|
|
19
|
-
export
|
|
19
|
+
export { FeedbackButtons } from "./FeedbackButtons";
|
|
20
|
+
export type { FeedbackButtonsCssClasses, FeedbackButtonsProps } from "./FeedbackButtons";
|
|
21
|
+
|
|
22
|
+
export { Markdown } from "./Markdown";
|
|
23
|
+
export { MarkdownProps } from "./Markdown";
|
|
24
|
+
|
|
20
25
|
export type { InitialMessagePopUpCssClasses } from "./InitialMessagePopUp";
|
package/src/hooks/index.ts
CHANGED
|
@@ -1 +1,5 @@
|
|
|
1
1
|
export { useComposedCssClasses } from "./useComposedCssClasses";
|
|
2
|
+
export { useDefaultHandleApiError } from "./useDefaultHandleApiError";
|
|
3
|
+
export { useFetchInitialMessage } from "./useFetchInitialMessage";
|
|
4
|
+
export { useReportAnalyticsEvent } from "./useReportAnalyticsEvent";
|
|
5
|
+
export { useScrollToLastMessage } from "./useScrollToLastMessage";
|
|
@@ -5,7 +5,7 @@ import { useCallback } from "react";
|
|
|
5
5
|
* Returns a default handler function for API errors. It will log the error and
|
|
6
6
|
* add a default error message to state.
|
|
7
7
|
*
|
|
8
|
-
* @
|
|
8
|
+
* @public
|
|
9
9
|
*/
|
|
10
10
|
export function useDefaultHandleApiError() {
|
|
11
11
|
const chat = useChatActions();
|
|
@@ -6,7 +6,7 @@ import { useDefaultHandleApiError } from "../hooks/useDefaultHandleApiError";
|
|
|
6
6
|
* Sends a request to Chat API to fetch the initial message when the
|
|
7
7
|
* conversation first start or when the message history is reset.
|
|
8
8
|
*
|
|
9
|
-
* @
|
|
9
|
+
* @public
|
|
10
10
|
*
|
|
11
11
|
* @param handleError - A function which is called when an error occurs while fetching for initial message.
|
|
12
12
|
* By default, the error is logged to the console and an error message is added to state.
|
|
@@ -7,7 +7,7 @@ import { useCallback } from "react";
|
|
|
7
7
|
* The payload will automatically includes chat-ui-react's
|
|
8
8
|
* package version for "clientSdk" field.
|
|
9
9
|
*
|
|
10
|
-
* @
|
|
10
|
+
* @public
|
|
11
11
|
*/
|
|
12
12
|
export function useReportAnalyticsEvent(): ChatHeadless["report"] {
|
|
13
13
|
const chat = useChatActions();
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { useChatState } from "@yext/chat-headless-react";
|
|
2
|
+
import React, { useCallback, useEffect, useRef } from "react";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Scroll the messsages container to the top of the last message whenever there's
|
|
6
|
+
* an update to the messages state.
|
|
7
|
+
*
|
|
8
|
+
* @public
|
|
9
|
+
*
|
|
10
|
+
* @returns a ref to set on the messages container element and
|
|
11
|
+
* a function to set ref on individual message element
|
|
12
|
+
*/
|
|
13
|
+
export function useScrollToLastMessage(): [
|
|
14
|
+
React.RefObject<HTMLDivElement>,
|
|
15
|
+
(index: number) => ((message: HTMLDivElement) => void) | undefined
|
|
16
|
+
] {
|
|
17
|
+
const messagesRef = useRef<Array<HTMLDivElement | null>>([]);
|
|
18
|
+
const messagesContainerRef = useRef<HTMLDivElement>(null);
|
|
19
|
+
const messages = useChatState((state) => state.conversation.messages);
|
|
20
|
+
|
|
21
|
+
// Handle scrolling when messages change
|
|
22
|
+
useEffect(() => {
|
|
23
|
+
let scrollTop = 0;
|
|
24
|
+
messagesRef.current = messagesRef.current.slice(0, messages.length);
|
|
25
|
+
|
|
26
|
+
// Sums up scroll heights of all messages except the last one
|
|
27
|
+
if (messagesRef?.current.length > 1) {
|
|
28
|
+
scrollTop = messagesRef.current
|
|
29
|
+
.slice(0, -1)
|
|
30
|
+
.map((elem, _) => elem?.scrollHeight ?? 0)
|
|
31
|
+
.reduce((total, height) => total + height);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// Scroll to the top of the last message
|
|
35
|
+
messagesContainerRef.current?.scroll({
|
|
36
|
+
top: scrollTop,
|
|
37
|
+
behavior: "smooth",
|
|
38
|
+
});
|
|
39
|
+
}, [messages]);
|
|
40
|
+
|
|
41
|
+
const setMessageRef = useCallback((index) => {
|
|
42
|
+
if (!messagesRef?.current) return undefined;
|
|
43
|
+
return (message: HTMLDivElement) => (messagesRef.current[index] = message);
|
|
44
|
+
}, []);
|
|
45
|
+
|
|
46
|
+
return [messagesContainerRef, setMessageRef]
|
|
47
|
+
}
|