@yext/chat-ui-react 0.8.1-alpha.53.2 → 0.8.1

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.
Files changed (88) hide show
  1. package/lib/commonjs/package.json.js +1 -1
  2. package/lib/commonjs/src/components/ChatInput.js +1 -1
  3. package/lib/commonjs/src/components/ChatPanel.d.ts +1 -3
  4. package/lib/commonjs/src/components/ChatPanel.d.ts.map +1 -1
  5. package/lib/commonjs/src/components/ChatPanel.js +30 -7
  6. package/lib/commonjs/src/components/ChatPanel.js.map +1 -1
  7. package/lib/commonjs/src/components/ChatPopUp.d.ts +1 -1
  8. package/lib/commonjs/src/components/ChatPopUp.d.ts.map +1 -1
  9. package/lib/commonjs/src/components/ChatPopUp.js +2 -2
  10. package/lib/commonjs/src/components/ChatPopUp.js.map +1 -1
  11. package/lib/commonjs/src/components/FeedbackButtons.d.ts +4 -3
  12. package/lib/commonjs/src/components/FeedbackButtons.d.ts.map +1 -1
  13. package/lib/commonjs/src/components/FeedbackButtons.js +1 -2
  14. package/lib/commonjs/src/components/FeedbackButtons.js.map +1 -1
  15. package/lib/commonjs/src/components/Markdown.d.ts +3 -7
  16. package/lib/commonjs/src/components/Markdown.d.ts.map +1 -1
  17. package/lib/commonjs/src/components/Markdown.js +1 -1
  18. package/lib/commonjs/src/components/Markdown.js.map +1 -1
  19. package/lib/commonjs/src/components/index.d.ts +1 -4
  20. package/lib/commonjs/src/components/index.d.ts.map +1 -1
  21. package/lib/commonjs/src/hooks/index.d.ts +0 -3
  22. package/lib/commonjs/src/hooks/index.d.ts.map +1 -1
  23. package/lib/commonjs/src/hooks/useDefaultHandleApiError.d.ts +1 -1
  24. package/lib/commonjs/src/hooks/useDefaultHandleApiError.js +1 -1
  25. package/lib/commonjs/src/hooks/useDefaultHandleApiError.js.map +1 -1
  26. package/lib/commonjs/src/hooks/useFetchInitialMessage.d.ts +1 -1
  27. package/lib/commonjs/src/hooks/useFetchInitialMessage.js +1 -1
  28. package/lib/commonjs/src/hooks/useFetchInitialMessage.js.map +1 -1
  29. package/lib/commonjs/src/hooks/useReportAnalyticsEvent.d.ts +0 -2
  30. package/lib/commonjs/src/hooks/useReportAnalyticsEvent.d.ts.map +1 -1
  31. package/lib/commonjs/src/hooks/useReportAnalyticsEvent.js +0 -2
  32. package/lib/commonjs/src/hooks/useReportAnalyticsEvent.js.map +1 -1
  33. package/lib/commonjs/src/index.js +0 -10
  34. package/lib/commonjs/src/index.js.map +1 -1
  35. package/lib/esm/index.d.ts +2 -86
  36. package/lib/esm/package.json.mjs +1 -1
  37. package/lib/esm/src/components/ChatInput.mjs +1 -1
  38. package/lib/esm/src/components/ChatPanel.d.ts +1 -3
  39. package/lib/esm/src/components/ChatPanel.d.ts.map +1 -1
  40. package/lib/esm/src/components/ChatPanel.mjs +31 -8
  41. package/lib/esm/src/components/ChatPanel.mjs.map +1 -1
  42. package/lib/esm/src/components/ChatPopUp.d.ts +1 -1
  43. package/lib/esm/src/components/ChatPopUp.d.ts.map +1 -1
  44. package/lib/esm/src/components/ChatPopUp.mjs +2 -2
  45. package/lib/esm/src/components/ChatPopUp.mjs.map +1 -1
  46. package/lib/esm/src/components/FeedbackButtons.d.ts +4 -3
  47. package/lib/esm/src/components/FeedbackButtons.d.ts.map +1 -1
  48. package/lib/esm/src/components/FeedbackButtons.mjs +1 -2
  49. package/lib/esm/src/components/FeedbackButtons.mjs.map +1 -1
  50. package/lib/esm/src/components/Markdown.d.ts +3 -7
  51. package/lib/esm/src/components/Markdown.d.ts.map +1 -1
  52. package/lib/esm/src/components/Markdown.mjs +1 -1
  53. package/lib/esm/src/components/Markdown.mjs.map +1 -1
  54. package/lib/esm/src/components/index.d.ts +1 -4
  55. package/lib/esm/src/components/index.d.ts.map +1 -1
  56. package/lib/esm/src/hooks/index.d.ts +0 -3
  57. package/lib/esm/src/hooks/index.d.ts.map +1 -1
  58. package/lib/esm/src/hooks/useDefaultHandleApiError.d.ts +1 -1
  59. package/lib/esm/src/hooks/useDefaultHandleApiError.mjs +1 -1
  60. package/lib/esm/src/hooks/useDefaultHandleApiError.mjs.map +1 -1
  61. package/lib/esm/src/hooks/useFetchInitialMessage.d.ts +1 -1
  62. package/lib/esm/src/hooks/useFetchInitialMessage.mjs +1 -1
  63. package/lib/esm/src/hooks/useFetchInitialMessage.mjs.map +1 -1
  64. package/lib/esm/src/hooks/useReportAnalyticsEvent.d.ts +0 -2
  65. package/lib/esm/src/hooks/useReportAnalyticsEvent.d.ts.map +1 -1
  66. package/lib/esm/src/hooks/useReportAnalyticsEvent.mjs +0 -2
  67. package/lib/esm/src/hooks/useReportAnalyticsEvent.mjs.map +1 -1
  68. package/lib/esm/src/index.mjs +0 -5
  69. package/lib/esm/src/index.mjs.map +1 -1
  70. package/package.json +1 -1
  71. package/src/components/ChatPanel.tsx +37 -15
  72. package/src/components/ChatPopUp.tsx +1 -1
  73. package/src/components/FeedbackButtons.tsx +3 -3
  74. package/src/components/Markdown.tsx +2 -7
  75. package/src/components/index.ts +1 -6
  76. package/src/hooks/index.ts +1 -4
  77. package/src/hooks/useDefaultHandleApiError.ts +1 -1
  78. package/src/hooks/useFetchInitialMessage.ts +1 -1
  79. package/src/hooks/useReportAnalyticsEvent.ts +0 -2
  80. package/lib/commonjs/src/hooks/useScrollToLastMessage.d.ts +0 -15
  81. package/lib/commonjs/src/hooks/useScrollToLastMessage.d.ts.map +0 -1
  82. package/lib/commonjs/src/hooks/useScrollToLastMessage.js +0 -45
  83. package/lib/commonjs/src/hooks/useScrollToLastMessage.js.map +0 -1
  84. package/lib/esm/src/hooks/useScrollToLastMessage.d.ts +0 -15
  85. package/lib/esm/src/hooks/useScrollToLastMessage.d.ts.map +0 -1
  86. package/lib/esm/src/hooks/useScrollToLastMessage.mjs +0 -43
  87. package/lib/esm/src/hooks/useScrollToLastMessage.mjs.map +0 -1
  88. package/src/hooks/useScrollToLastMessage.ts +0 -47
@@ -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 * @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;;;;"}
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 * @internal\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;;;;"}
@@ -1,8 +1,6 @@
1
1
  import { ChatHeadless } from "@yext/chat-headless-react";
2
2
  /**
3
3
  * Returns a function to send requests to Yext Analytics API.
4
- * The payload will automatically includes chat-ui-react's
5
- * package version for "clientSdk" field.
6
4
  *
7
5
  * @public
8
6
  */
@@ -1 +1 @@
1
- {"version":3,"file":"useReportAnalyticsEvent.d.ts","sourceRoot":"","sources":["../../../../src/hooks/useReportAnalyticsEvent.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAkB,MAAM,2BAA2B,CAAC;AAIzE;;;;;;GAMG;AACH,wBAAgB,uBAAuB,IAAI,YAAY,CAAC,QAAQ,CAAC,CAMhE"}
1
+ {"version":3,"file":"useReportAnalyticsEvent.d.ts","sourceRoot":"","sources":["../../../../src/hooks/useReportAnalyticsEvent.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAkB,MAAM,2BAA2B,CAAC;AAIzE;;;;GAIG;AACH,wBAAgB,uBAAuB,IAAI,YAAY,CAAC,QAAQ,CAAC,CAMhE"}
@@ -4,8 +4,6 @@ import { useCallback } from 'react';
4
4
 
5
5
  /**
6
6
  * Returns a function to send requests to Yext Analytics API.
7
- * The payload will automatically includes chat-ui-react's
8
- * package version for "clientSdk" field.
9
7
  *
10
8
  * @public
11
9
  */
@@ -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 * @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;;;;"}
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 *\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;;;;AAIG;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;;;;"}
@@ -3,11 +3,6 @@ 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';
8
6
  export { useComposedCssClasses } from './hooks/useComposedCssClasses.mjs';
9
- export { useDefaultHandleApiError } from './hooks/useDefaultHandleApiError.mjs';
10
- export { useFetchInitialMessage } from './hooks/useFetchInitialMessage.mjs';
11
7
  export { useReportAnalyticsEvent } from './hooks/useReportAnalyticsEvent.mjs';
12
- export { useScrollToLastMessage } from './hooks/useScrollToLastMessage.mjs';
13
8
  //# 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,6 +1,6 @@
1
1
  {
2
2
  "name": "@yext/chat-ui-react",
3
- "version": "0.8.1-alpha.53.2",
3
+ "version": "0.8.1",
4
4
  "description": "A library of React Components for powering Yext Chat integrations.",
5
5
  "author": "clippy@yext.com",
6
6
  "main": "./lib/commonjs/src/index.js",
@@ -1,4 +1,4 @@
1
- import React, { useEffect } from "react";
1
+ import React, { useCallback, useEffect, useRef } from "react";
2
2
  import { useChatState } from "@yext/chat-headless-react";
3
3
  import {
4
4
  MessageBubble,
@@ -7,13 +7,10 @@ import {
7
7
  } from "./MessageBubble";
8
8
  import { ChatInput, ChatInputCssClasses, ChatInputProps } from "./ChatInput";
9
9
  import { LoadingDots } from "./LoadingDots";
10
- import {
11
- useComposedCssClasses,
12
- useReportAnalyticsEvent,
13
- useFetchInitialMessage,
14
- useScrollToLastMessage,
15
- } from "../hooks";
10
+ import { useComposedCssClasses } from "../hooks";
16
11
  import { withStylelessCssClasses } from "../utils/withStylelessCssClasses";
12
+ import { useReportAnalyticsEvent } from "../hooks/useReportAnalyticsEvent";
13
+ import { useFetchInitialMessage } from "../hooks/useFetchInitialMessage";
17
14
 
18
15
  /**
19
16
  * The CSS class interface for the {@link ChatPanel} component.
@@ -50,10 +47,8 @@ const builtInCssClasses: ChatPanelCssClasses = withStylelessCssClasses(
50
47
  export interface ChatPanelProps
51
48
  extends Omit<MessageBubbleProps, "customCssClasses" | "message">,
52
49
  Omit<ChatInputProps, "customCssClasses"> {
53
- /** A custom header component to render at the top of the panel. */
50
+ /** A header to render at the top of the panel. */
54
51
  header?: JSX.Element;
55
- /** A custom input component to render at the bottom of the panel. */
56
- input?: JSX.Element;
57
52
  /**
58
53
  * CSS classes for customizing the component styling.
59
54
  */
@@ -70,13 +65,12 @@ export interface ChatPanelProps
70
65
  * @param props - {@link ChatPanelProps}
71
66
  */
72
67
  export function ChatPanel(props: ChatPanelProps) {
73
- const { header, input, customCssClasses, stream, handleError } = props;
68
+ const { header, customCssClasses, stream, handleError } = props;
74
69
  const messages = useChatState((state) => state.conversation.messages);
75
70
  const loading = useChatState((state) => state.conversation.isLoading);
76
71
  const cssClasses = useComposedCssClasses(builtInCssClasses, customCssClasses);
77
72
  const reportAnalyticsEvent = useReportAnalyticsEvent();
78
73
  useFetchInitialMessage(handleError, stream);
79
- const [messagesContainerRef, setMessageRef] = useScrollToLastMessage();
80
74
 
81
75
  useEffect(() => {
82
76
  reportAnalyticsEvent({
@@ -84,14 +78,42 @@ export function ChatPanel(props: ChatPanelProps) {
84
78
  });
85
79
  }, [reportAnalyticsEvent]);
86
80
 
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
+
87
109
  return (
88
110
  <div className="yext-chat w-full h-full">
89
111
  <div className={cssClasses.container}>
90
112
  {header}
91
113
  <div className={cssClasses.messagesScrollContainer}>
92
- <div ref={messagesContainerRef} className={cssClasses.messagesContainer}>
114
+ <div ref={messagesContainer} className={cssClasses.messagesContainer}>
93
115
  {messages.map((message, index) => (
94
- <div key={index} ref={setMessageRef(index)}>
116
+ <div key={index} ref={setMessagesRef(index)}>
95
117
  <MessageBubble
96
118
  {...props}
97
119
  customCssClasses={cssClasses.messageBubbleCssClasses}
@@ -103,7 +125,7 @@ export function ChatPanel(props: ChatPanelProps) {
103
125
  </div>
104
126
  </div>
105
127
  <div className={cssClasses.inputContainer}>
106
- {input ?? <ChatInput {...props} customCssClasses={cssClasses.inputCssClasses} />}
128
+ <ChatInput {...props} customCssClasses={cssClasses.inputCssClasses} />
107
129
  </div>
108
130
  </div>
109
131
  </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" | "input" | "customCssClasses"> {
85
+ Omit<ChatPanelProps, "header" | "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
- * @public
42
+ * @internal
43
43
  */
44
- export interface FeedbackButtonsProps {
44
+ 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 @@ export 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
- * @public
55
+ * @internal
56
56
  */
57
57
  export function FeedbackButtons({
58
58
  customCssClasses,
@@ -19,12 +19,7 @@ const unifiedPlugins: { remark?: PluggableList; rehype: PluggableList } = {
19
19
  ],
20
20
  };
21
21
 
22
- /**
23
- * The props for the {@link Markdown} component.
24
- *
25
- * @public
26
- */
27
- export interface MarkdownProps {
22
+ interface MarkdownProps {
28
23
  /** Stringified markdown. */
29
24
  content: string;
30
25
  /** The response ID correlates to the current message. */
@@ -40,7 +35,7 @@ export interface MarkdownProps {
40
35
  * @remarks
41
36
  * A link click will send a CHAT_LINK_CLICK analytics event
42
37
  *
43
- * @public
38
+ * @internal
44
39
  */
45
40
  export function Markdown({ content, responseId, className }: MarkdownProps) {
46
41
  const reportAnalyticsEvent = useReportAnalyticsEvent();
@@ -16,10 +16,5 @@ export type { ChatPanelCssClasses, ChatPanelProps } from "./ChatPanel";
16
16
  export { ChatPopUp } from "./ChatPopUp";
17
17
  export type { ChatPopUpCssClasses, ChatPopUpProps } from "./ChatPopUp";
18
18
 
19
- export { FeedbackButtons } from "./FeedbackButtons";
20
- export type { FeedbackButtonsCssClasses, FeedbackButtonsProps } from "./FeedbackButtons";
21
-
22
- export { Markdown } from "./Markdown";
23
- export { MarkdownProps } from "./Markdown";
24
-
19
+ export type { FeedbackButtonsCssClasses } from "./FeedbackButtons";
25
20
  export type { InitialMessagePopUpCssClasses } from "./InitialMessagePopUp";
@@ -1,5 +1,2 @@
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
+ export { useReportAnalyticsEvent } from "./useReportAnalyticsEvent";
@@ -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
- * @public
8
+ * @internal
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
- * @public
9
+ * @internal
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.
@@ -4,8 +4,6 @@ import { useCallback } from "react";
4
4
 
5
5
  /**
6
6
  * Returns a function to send requests to Yext Analytics API.
7
- * The payload will automatically includes chat-ui-react's
8
- * package version for "clientSdk" field.
9
7
  *
10
8
  * @public
11
9
  */
@@ -1,15 +0,0 @@
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
@@ -1 +0,0 @@
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"}
@@ -1,45 +0,0 @@
1
- 'use strict';
2
-
3
- var chatHeadlessReact = require('@yext/chat-headless-react');
4
- var React = require('react');
5
-
6
- /**
7
- * Scroll the messsages container to the top of the last message whenever there's
8
- * an update to the messages state.
9
- *
10
- * @public
11
- *
12
- * @returns a ref to set on the messages container element and
13
- * a function to set ref on individual message element
14
- */
15
- function useScrollToLastMessage() {
16
- const messagesRef = React.useRef([]);
17
- const messagesContainerRef = React.useRef(null);
18
- const messages = chatHeadlessReact.useChatState((state) => state.conversation.messages);
19
- // Handle scrolling when messages change
20
- React.useEffect(() => {
21
- let scrollTop = 0;
22
- messagesRef.current = messagesRef.current.slice(0, messages.length);
23
- // Sums up scroll heights of all messages except the last one
24
- if (messagesRef?.current.length > 1) {
25
- scrollTop = messagesRef.current
26
- .slice(0, -1)
27
- .map((elem, _) => elem?.scrollHeight ?? 0)
28
- .reduce((total, height) => total + height);
29
- }
30
- // Scroll to the top of the last message
31
- messagesContainerRef.current?.scroll({
32
- top: scrollTop,
33
- behavior: "smooth",
34
- });
35
- }, [messages]);
36
- const setMessageRef = React.useCallback((index) => {
37
- if (!messagesRef?.current)
38
- return undefined;
39
- return (message) => (messagesRef.current[index] = message);
40
- }, []);
41
- return [messagesContainerRef, setMessageRef];
42
- }
43
-
44
- exports.useScrollToLastMessage = useScrollToLastMessage;
45
- //# sourceMappingURL=useScrollToLastMessage.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"useScrollToLastMessage.js","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":["useRef","useChatState","useEffect","useCallback"],"mappings":";;;;;AAGA;;;;;;;;AAQG;SACa,sBAAsB,GAAA;AAIpC,IAAA,MAAM,WAAW,GAAGA,YAAM,CAA+B,EAAE,CAAC,CAAC;AAC7D,IAAA,MAAM,oBAAoB,GAAGA,YAAM,CAAiB,IAAI,CAAC,CAAC;AAC1D,IAAA,MAAM,QAAQ,GAAGC,8BAAY,CAAC,CAAC,KAAK,KAAK,KAAK,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC;;IAGtEC,eAAS,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,GAAGC,iBAAW,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;;;;"}
@@ -1,15 +0,0 @@
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
@@ -1 +0,0 @@
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"}
@@ -1,43 +0,0 @@
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
@@ -1 +0,0 @@
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;;;;"}
@@ -1,47 +0,0 @@
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
- }