@patternfly/chatbot 2.1.0 → 2.2.0-prerelease.10

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 (177) hide show
  1. package/dist/cjs/Chatbot/Chatbot.js +0 -9
  2. package/dist/cjs/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.d.ts +5 -1
  3. package/dist/cjs/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.js +4 -4
  4. package/dist/cjs/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.test.js +3 -3
  5. package/dist/cjs/ChatbotHeader/ChatbotHeaderCloseButton.d.ts +17 -0
  6. package/dist/cjs/ChatbotHeader/ChatbotHeaderCloseButton.js +14 -0
  7. package/dist/cjs/ChatbotHeader/ChatbotHeaderMenu.d.ts +2 -0
  8. package/dist/cjs/ChatbotHeader/ChatbotHeaderMenu.js +2 -2
  9. package/dist/cjs/ChatbotHeader/index.d.ts +1 -0
  10. package/dist/cjs/ChatbotHeader/index.js +1 -0
  11. package/dist/cjs/CodeModal/CodeModal.js +2 -12
  12. package/dist/cjs/Message/ListMessage/OrderedListMessage.d.ts +1 -1
  13. package/dist/cjs/Message/ListMessage/OrderedListMessage.js +2 -2
  14. package/dist/cjs/Message/Message.d.ts +16 -6
  15. package/dist/cjs/Message/Message.js +6 -6
  16. package/dist/cjs/Message/Message.test.js +51 -0
  17. package/dist/cjs/Message/QuickResponse/QuickResponse.d.ts +15 -0
  18. package/dist/cjs/Message/QuickResponse/QuickResponse.js +33 -0
  19. package/dist/cjs/Message/QuickStarts/FallbackImg.d.ts +13 -0
  20. package/dist/cjs/Message/QuickStarts/FallbackImg.js +34 -0
  21. package/dist/cjs/Message/QuickStarts/QuickStartTile.d.ts +27 -0
  22. package/dist/cjs/Message/QuickStarts/QuickStartTile.js +82 -0
  23. package/dist/cjs/Message/QuickStarts/QuickStartTileDescription.d.ts +23 -0
  24. package/dist/cjs/Message/QuickStarts/QuickStartTileDescription.js +64 -0
  25. package/dist/cjs/Message/QuickStarts/QuickStartTileDescription.test.d.ts +1 -0
  26. package/dist/cjs/Message/QuickStarts/QuickStartTileDescription.test.js +76 -0
  27. package/dist/cjs/Message/QuickStarts/QuickStartTileHeader.d.ts +11 -0
  28. package/dist/cjs/Message/QuickStarts/QuickStartTileHeader.js +30 -0
  29. package/dist/cjs/Message/QuickStarts/monitor-sampleapp-quickstart-with-image.d.ts +30 -0
  30. package/dist/cjs/Message/QuickStarts/monitor-sampleapp-quickstart-with-image.js +77 -0
  31. package/dist/cjs/Message/QuickStarts/monitor-sampleapp-quickstart.d.ts +30 -0
  32. package/dist/cjs/Message/QuickStarts/monitor-sampleapp-quickstart.js +77 -0
  33. package/dist/cjs/Message/QuickStarts/types.d.ts +132 -0
  34. package/dist/cjs/Message/QuickStarts/types.js +17 -0
  35. package/dist/cjs/MessageBar/SendButton.js +1 -1
  36. package/dist/cjs/ResponseActions/ResponseActionButton.d.ts +6 -0
  37. package/dist/cjs/ResponseActions/ResponseActionButton.js +10 -2
  38. package/dist/cjs/ResponseActions/ResponseActionButton.test.d.ts +1 -0
  39. package/dist/cjs/ResponseActions/ResponseActionButton.test.js +54 -0
  40. package/dist/cjs/ResponseActions/ResponseActions.d.ts +4 -0
  41. package/dist/cjs/ResponseActions/ResponseActions.js +26 -9
  42. package/dist/cjs/ResponseActions/ResponseActions.test.js +79 -5
  43. package/dist/cjs/Settings/SettingsForm.d.ts +13 -0
  44. package/dist/cjs/Settings/SettingsForm.js +27 -0
  45. package/dist/cjs/Settings/index.d.ts +2 -0
  46. package/dist/cjs/Settings/index.js +23 -0
  47. package/dist/cjs/TermsOfUse/TermsOfUse.d.ts +34 -0
  48. package/dist/cjs/TermsOfUse/TermsOfUse.js +49 -0
  49. package/dist/cjs/TermsOfUse/TermsOfUse.test.d.ts +1 -0
  50. package/dist/cjs/TermsOfUse/TermsOfUse.test.js +79 -0
  51. package/dist/cjs/TermsOfUse/index.d.ts +2 -0
  52. package/dist/cjs/TermsOfUse/index.js +23 -0
  53. package/dist/cjs/index.d.ts +4 -0
  54. package/dist/cjs/index.js +7 -1
  55. package/dist/css/main.css +191 -30
  56. package/dist/css/main.css.map +1 -1
  57. package/dist/dynamic/Settings/package.json +1 -0
  58. package/dist/dynamic/TermsOfUse/package.json +1 -0
  59. package/dist/esm/Chatbot/Chatbot.js +0 -9
  60. package/dist/esm/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.d.ts +5 -1
  61. package/dist/esm/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.js +4 -4
  62. package/dist/esm/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.test.js +3 -3
  63. package/dist/esm/ChatbotHeader/ChatbotHeaderCloseButton.d.ts +17 -0
  64. package/dist/esm/ChatbotHeader/ChatbotHeaderCloseButton.js +8 -0
  65. package/dist/esm/ChatbotHeader/ChatbotHeaderMenu.d.ts +2 -0
  66. package/dist/esm/ChatbotHeader/ChatbotHeaderMenu.js +2 -2
  67. package/dist/esm/ChatbotHeader/index.d.ts +1 -0
  68. package/dist/esm/ChatbotHeader/index.js +1 -0
  69. package/dist/esm/CodeModal/CodeModal.js +2 -12
  70. package/dist/esm/Message/ListMessage/OrderedListMessage.d.ts +1 -1
  71. package/dist/esm/Message/ListMessage/OrderedListMessage.js +2 -2
  72. package/dist/esm/Message/Message.d.ts +16 -6
  73. package/dist/esm/Message/Message.js +7 -7
  74. package/dist/esm/Message/Message.test.js +51 -0
  75. package/dist/esm/Message/QuickResponse/QuickResponse.d.ts +15 -0
  76. package/dist/esm/Message/QuickResponse/QuickResponse.js +26 -0
  77. package/dist/esm/Message/QuickStarts/FallbackImg.d.ts +13 -0
  78. package/dist/esm/Message/QuickStarts/FallbackImg.js +9 -0
  79. package/dist/esm/Message/QuickStarts/QuickStartTile.d.ts +27 -0
  80. package/dist/esm/Message/QuickStarts/QuickStartTile.js +52 -0
  81. package/dist/esm/Message/QuickStarts/QuickStartTileDescription.d.ts +23 -0
  82. package/dist/esm/Message/QuickStarts/QuickStartTileDescription.js +35 -0
  83. package/dist/esm/Message/QuickStarts/QuickStartTileDescription.test.d.ts +1 -0
  84. package/dist/esm/Message/QuickStarts/QuickStartTileDescription.test.js +48 -0
  85. package/dist/esm/Message/QuickStarts/QuickStartTileHeader.d.ts +11 -0
  86. package/dist/esm/Message/QuickStarts/QuickStartTileHeader.js +5 -0
  87. package/dist/esm/Message/QuickStarts/monitor-sampleapp-quickstart-with-image.d.ts +30 -0
  88. package/dist/esm/Message/QuickStarts/monitor-sampleapp-quickstart-with-image.js +74 -0
  89. package/dist/esm/Message/QuickStarts/monitor-sampleapp-quickstart.d.ts +30 -0
  90. package/dist/esm/Message/QuickStarts/monitor-sampleapp-quickstart.js +74 -0
  91. package/dist/esm/Message/QuickStarts/types.d.ts +132 -0
  92. package/dist/esm/Message/QuickStarts/types.js +14 -0
  93. package/dist/esm/MessageBar/SendButton.js +1 -1
  94. package/dist/esm/ResponseActions/ResponseActionButton.d.ts +6 -0
  95. package/dist/esm/ResponseActions/ResponseActionButton.js +10 -2
  96. package/dist/esm/ResponseActions/ResponseActionButton.test.d.ts +1 -0
  97. package/dist/esm/ResponseActions/ResponseActionButton.test.js +49 -0
  98. package/dist/esm/ResponseActions/ResponseActions.d.ts +4 -0
  99. package/dist/esm/ResponseActions/ResponseActions.js +26 -9
  100. package/dist/esm/ResponseActions/ResponseActions.test.js +79 -5
  101. package/dist/esm/Settings/SettingsForm.d.ts +13 -0
  102. package/dist/esm/Settings/SettingsForm.js +20 -0
  103. package/dist/esm/Settings/index.d.ts +2 -0
  104. package/dist/esm/Settings/index.js +2 -0
  105. package/dist/esm/TermsOfUse/TermsOfUse.d.ts +34 -0
  106. package/dist/esm/TermsOfUse/TermsOfUse.js +42 -0
  107. package/dist/esm/TermsOfUse/TermsOfUse.test.d.ts +1 -0
  108. package/dist/esm/TermsOfUse/TermsOfUse.test.js +74 -0
  109. package/dist/esm/TermsOfUse/index.d.ts +2 -0
  110. package/dist/esm/TermsOfUse/index.js +2 -0
  111. package/dist/esm/index.d.ts +4 -0
  112. package/dist/esm/index.js +4 -0
  113. package/dist/tsconfig.tsbuildinfo +1 -1
  114. package/package.json +7 -13
  115. package/patternfly-docs/content/extensions/chatbot/examples/Messages/MessageWithCustomResponseActions.tsx +4 -0
  116. package/patternfly-docs/content/extensions/chatbot/examples/Messages/MessageWithQuickStart.tsx +31 -0
  117. package/patternfly-docs/content/extensions/chatbot/examples/Messages/Messages.md +26 -4
  118. package/patternfly-docs/content/extensions/chatbot/examples/Messages/explore-pipeline-quickstart.ts +65 -0
  119. package/patternfly-docs/content/extensions/chatbot/examples/UI/ChatbotFooter.tsx +1 -1
  120. package/patternfly-docs/content/extensions/chatbot/examples/UI/ChatbotFootnote.tsx +2 -2
  121. package/patternfly-docs/content/extensions/chatbot/examples/UI/ChatbotHeaderDrawer.tsx +2 -2
  122. package/patternfly-docs/content/extensions/chatbot/examples/UI/ChatbotHeaderDrawerNavigation.tsx +67 -0
  123. package/patternfly-docs/content/extensions/chatbot/examples/UI/ChatbotHeaderDrawerWithSelection.tsx +78 -0
  124. package/patternfly-docs/content/extensions/chatbot/examples/UI/ChatbotMessageBarDisabled.tsx +26 -0
  125. package/patternfly-docs/content/extensions/chatbot/examples/UI/PF-TermsAndConditionsHeader.svg +148 -0
  126. package/patternfly-docs/content/extensions/chatbot/examples/UI/Settings.tsx +289 -0
  127. package/patternfly-docs/content/extensions/chatbot/examples/UI/SquareChatbotToggle.tsx +1 -1
  128. package/patternfly-docs/content/extensions/chatbot/examples/UI/TermsOfUse.tsx +147 -0
  129. package/patternfly-docs/content/extensions/chatbot/examples/UI/UI.md +56 -0
  130. package/patternfly-docs/content/extensions/chatbot/examples/demos/Chatbot.md +2 -2
  131. package/patternfly-docs/content/extensions/chatbot/examples/demos/Chatbot.tsx +2 -2
  132. package/patternfly-docs/content/extensions/chatbot/examples/demos/ChatbotAttachment.tsx +20 -19
  133. package/patternfly-docs/content/extensions/chatbot/examples/demos/ChatbotAttachmentMenu.tsx +1 -1
  134. package/patternfly-docs/content/extensions/chatbot/examples/demos/EmbeddedChatbot.tsx +2 -2
  135. package/src/Chatbot/Chatbot.scss +0 -10
  136. package/src/Chatbot/Chatbot.tsx +0 -9
  137. package/src/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.scss +14 -0
  138. package/src/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.test.tsx +3 -3
  139. package/src/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.tsx +11 -3
  140. package/src/ChatbotFooter/ChatbotFooter.scss +2 -1
  141. package/src/ChatbotHeader/ChatbotHeaderCloseButton.tsx +51 -0
  142. package/src/ChatbotHeader/ChatbotHeaderMenu.tsx +5 -2
  143. package/src/ChatbotHeader/index.ts +1 -0
  144. package/src/CodeModal/CodeModal.scss +8 -0
  145. package/src/CodeModal/CodeModal.tsx +2 -13
  146. package/src/FileDropZone/__snapshots__/FileDropZone.test.tsx.snap +1 -1
  147. package/src/Message/ListMessage/OrderedListMessage.tsx +2 -2
  148. package/src/Message/Message.scss +0 -14
  149. package/src/Message/Message.test.tsx +76 -0
  150. package/src/Message/Message.tsx +35 -26
  151. package/src/Message/QuickResponse/QuickResponse.scss +33 -0
  152. package/src/Message/QuickResponse/QuickResponse.tsx +50 -0
  153. package/src/Message/QuickStarts/FallbackImg.tsx +24 -0
  154. package/src/Message/QuickStarts/QuickStartTile.scss +25 -0
  155. package/src/Message/QuickStarts/QuickStartTile.tsx +147 -0
  156. package/src/Message/QuickStarts/QuickStartTileDescription.test.tsx +57 -0
  157. package/src/Message/QuickStarts/QuickStartTileDescription.tsx +81 -0
  158. package/src/Message/QuickStarts/QuickStartTileHeader.tsx +21 -0
  159. package/src/Message/QuickStarts/monitor-sampleapp-quickstart-with-image.ts +75 -0
  160. package/src/Message/QuickStarts/monitor-sampleapp-quickstart.ts +75 -0
  161. package/src/Message/QuickStarts/types.ts +154 -0
  162. package/src/MessageBar/SendButton.scss +24 -0
  163. package/src/MessageBar/SendButton.tsx +1 -1
  164. package/src/ResponseActions/ResponseActionButton.test.tsx +52 -0
  165. package/src/ResponseActions/ResponseActionButton.tsx +46 -27
  166. package/src/ResponseActions/ResponseActions.scss +10 -8
  167. package/src/ResponseActions/ResponseActions.test.tsx +103 -5
  168. package/src/ResponseActions/ResponseActions.tsx +54 -7
  169. package/src/Settings/Settings.scss +34 -0
  170. package/src/Settings/SettingsForm.tsx +25 -0
  171. package/src/Settings/index.ts +3 -0
  172. package/src/TermsOfUse/TermsOfUse.scss +66 -0
  173. package/src/TermsOfUse/TermsOfUse.test.tsx +138 -0
  174. package/src/TermsOfUse/TermsOfUse.tsx +117 -0
  175. package/src/TermsOfUse/index.ts +3 -0
  176. package/src/index.ts +6 -0
  177. package/src/main.scss +7 -3
@@ -52,8 +52,10 @@ import FileDetailsLabel from '@patternfly/chatbot/dist/dynamic/FileDetailsLabel'
52
52
  import FileDropZone from '@patternfly/chatbot/dist/dynamic/FileDropZone';
53
53
  import { PreviewAttachment } from '@patternfly/chatbot/dist/dynamic/PreviewAttachment';
54
54
  import ChatbotAlert from '@patternfly/chatbot/dist/dynamic/ChatbotAlert';
55
+ import TermsOfUse from '@patternfly/chatbot/dist/dynamic/TermsOfUse';
55
56
  import {
56
57
  ChatbotHeader,
58
+ ChatbotHeaderCloseButton,
57
59
  ChatbotHeaderMain,
58
60
  ChatbotHeaderMenu,
59
61
  ChatbotHeaderActions,
@@ -65,6 +67,7 @@ import { ChatbotFooter, ChatbotFootnote } from '@patternfly/chatbot/dist/dynamic
65
67
  import { MessageBar } from '@patternfly/chatbot/dist/dynamic/MessageBar';
66
68
  import SourceDetailsMenuItem from '@patternfly/chatbot/dist/dynamic/SourceDetailsMenuItem';
67
69
  import { ChatbotModal } from '@patternfly/chatbot/dist/dynamic/ChatbotModal';
70
+ import SettingsForm from '@patternfly/chatbot/dist/dynamic/Settings';
68
71
  import { BellIcon, CalendarAltIcon, ClipboardIcon, CodeIcon, UploadIcon } from '@patternfly/react-icons';
69
72
  import { useDropzone } from 'react-dropzone';
70
73
 
@@ -74,10 +77,13 @@ import { DropdownItem, DropdownList, Checkbox } from '@patternfly/react-core';
74
77
  import OutlinedWindowRestoreIcon from '@patternfly/react-icons/dist/esm/icons/outlined-window-restore-icon';
75
78
  import ExpandIcon from '@patternfly/react-icons/dist/esm/icons/expand-icon';
76
79
  import OpenDrawerRightIcon from '@patternfly/react-icons/dist/esm/icons/open-drawer-right-icon';
80
+ import CogIcon from '@patternfly/react-icons/dist/esm/icons/cog-icon';
77
81
  import PFHorizontalLogoColor from './PF-HorizontalLogo-Color.svg';
78
82
  import PFHorizontalLogoReverse from './PF-HorizontalLogo-Reverse.svg';
79
83
  import userAvatar from '../Messages/user_avatar.svg';
80
84
  import patternflyAvatar from '../Messages/patternfly_avatar.jpg';
85
+ import termsAndConditionsHeader from './PF-TermsAndConditionsHeader.svg';
86
+ import { CloseIcon } from '@patternfly/react-icons';
81
87
 
82
88
  ## Structure
83
89
 
@@ -257,6 +263,18 @@ In this example, the locale is set to to ja-JP. You can try it out by saying "ha
257
263
 
258
264
  ```
259
265
 
266
+ ### Message bar with always-shown send button
267
+
268
+ By default, the send button is only shown once a user has entered a valid message. If you choose to keep the send button visible at all times, disable the button when there is no valid message to send.
269
+
270
+ To always show the send button in the message bar, use the `alwaysShowSendButton` prop. Use the `isSendButtonDisabled` prop to disable the button as needed. If you want to enable or disable the send button based on the presence of text in the message bar, you can detect text via the `onChange` prop for `<MessageBar>`.
271
+
272
+ To disable the send button in the following example, select the "Disable send button" checkbox. When the button is disabled, you also cannot send via the enter key.
273
+
274
+ ```js file="./ChatbotMessageBarDisabled.tsx"
275
+
276
+ ```
277
+
260
278
  ### Message bar with attach menu appended to attach button
261
279
 
262
280
  You can change the behavior of the attach button to open a menu, rather than the default file viewer for your operating system. This menu can display different actions related to attachments.
@@ -345,6 +363,44 @@ Actions can be added to conversations with `menuItems`. Optionally, you can also
345
363
 
346
364
  ```
347
365
 
366
+ ### Drawer with active conversation
367
+
368
+ If you're showing a conversation that is already active, you can set the `activeItemId` prop on your `<ChatbotConversationHistoryNav>` to apply an active visual state.
369
+
370
+ ```js file="./ChatbotHeaderDrawerWithSelection.tsx"
371
+
372
+ ```
373
+
374
+ ### Drawer with simple menu
375
+
376
+ The drawer can also be used to display a list of basic menu items.
377
+
378
+ ```js file="./ChatbotHeaderDrawerNavigation.tsx"
379
+
380
+ ```
381
+
382
+ ### Terms of use
383
+
384
+ Based on the [PatternFly modal](/components/modal), this modal adapts to the ChatBot display mode and is meant to display terms and conditions for using a ChatBot in your project. The image in the header can be toggled on or off depending on whether the `image` and `altText` props are provided.
385
+
386
+ This example also includes an example of how to use [skip to content](/patternfly-ai/chatbot/ui#skip-to-content). When the terms of use modal is open, focus is placed on the terms of use container. When it is closed, focus is placed on the ChatBot. In a real example with a functioning ChatBot toggle, you would also want to place focus on the toggle when appropriate.
387
+
388
+ ```js file="./TermsOfUse.tsx" isFullscreen
389
+
390
+ ```
391
+
392
+ ### Settings
393
+
394
+ To contain user preference controls and other ChatBot setting options, you can create a separate settings page that can accept any number of buttons, dropdown menus, toggles, labels, and so on. This settings page will render all components appropriately within all 4 display modes.
395
+
396
+ In this demo, you can toggle the settings page by clicking the "Settings" button in the display mode menu.
397
+
398
+ ```js file="./Settings.tsx" isFullscreen
399
+
400
+ ```
401
+
402
+ ## Modals
403
+
348
404
  ### Modal
349
405
 
350
406
  Based on the [PatternFly modal](/components/modal), this modal adapts to the ChatBot display mode and accepts components typically used in a modal. It is primarily used and tested in the context of the attachment modals, but you can customize this modal to adapt it to other use cases as needed. The modal will overlay the ChatBot in default and docked modes, and will behave more like a traditional PatternFly modal in fullscreen and embedded modes.
@@ -66,7 +66,7 @@ This demo displays a basic ChatBot, which includes:
66
66
  4. [`<ChatbotContent>` and `<MessageBox>`](/patternfly-ai/chatbot/ui#content-and-message-box) with:
67
67
 
68
68
  - A `<ChatbotWelcomePrompt>`
69
- - An initial [user `<Message>`](/patternfly-ai/chatbot/messages#user-messages) and an initial bot message with [message actions.](/patternfly-ai/chatbot/messages#messages-actions)
69
+ - An initial [user `<Message>`](/patternfly-ai/chatbot/messages#user-messages) and an initial bot message with [message actions.](/patternfly-ai/chatbot/messages#message-actions)
70
70
  - Logic for enabling auto-scrolling to the most recent message whenever a new message is sent or received using a `scrollToBottomRef`
71
71
 
72
72
  5. A [`<ChatbotFooter>`](/patternfly-ai/chatbot/ui#footer) with a [`<ChatbotFootNote>`](/patternfly-ai/chatbot/ui#footnote-with-popover) and a `<MessageBar>` that contains the abilities of:
@@ -92,7 +92,7 @@ This demo displays an embedded ChatBot. Embedded ChatBots are meant to be placed
92
92
  3. A [`<ChatbotHeader>`](/patternfly-ai/chatbot/ui#header) with all built sub-components laid out, including a `<ChatbotHeaderTitle>`
93
93
  4. [`<ChatbotContent>` and `<MessageBox>`](/patternfly-ai/chatbot/ui#content-and-message-box) with:
94
94
  - A `<ChatbotWelcomePrompt>`
95
- - An initial [user `<Message>`](/patternfly-ai/chatbot/messages#user-messages) and an initial bot message with [message actions.](/patternfly-ai/chatbot/messages/#messages-actions)
95
+ - An initial [user `<Message>`](/patternfly-ai/chatbot/messages#user-messages) and an initial bot message with [message actions.](/patternfly-ai/chatbot/messages/#message-actions)
96
96
  - Logic for enabling auto-scrolling to the most recent message whenever a new message is sent or received using a `scrollToBottomRef`
97
97
  5. A [`<ChatbotFooter>`](/patternfly-ai/chatbot/ui#footer) with a [`<ChatbotFootNote>`](/patternfly-ai/chatbot/ui#footnote-with-popover) and a `<MessageBar>` that contains the abilities of:
98
98
  - [Speech to text.](/patternfly-ai/chatbot/ui#message-bar-with-speech-recognition-and-file-attachment)
@@ -34,10 +34,10 @@ import userAvatar from '../Messages/user_avatar.svg';
34
34
  import patternflyAvatar from '../Messages/patternfly_avatar.jpg';
35
35
 
36
36
  const footnoteProps = {
37
- label: 'Lightspeed uses AI. Check for mistakes.',
37
+ label: 'ChatBot uses AI. Check for mistakes.',
38
38
  popover: {
39
39
  title: 'Verify accuracy',
40
- description: `While Lightspeed strives for accuracy, there's always a possibility of errors. It's a good practice to verify critical information from reliable sources, especially if it's crucial for decision-making or actions.`,
40
+ description: `While ChatBot strives for accuracy, there's always a possibility of errors. It's a good practice to verify critical information from reliable sources, especially if it's crucial for decision-making or actions.`,
41
41
  bannerImage: {
42
42
  src: 'https://cdn.dribbble.com/userupload/10651749/file/original-8a07b8e39d9e8bf002358c66fce1223e.gif',
43
43
  alt: 'Example image for footnote popover'
@@ -36,18 +36,26 @@ interface ModalData {
36
36
  }
37
37
 
38
38
  export const BasicDemo: React.FunctionComponent = () => {
39
- const onAttachmentClose = (attachmentId: string) => {
40
- const index = messages.findIndex((message) => message.attachmentId === attachmentId);
39
+ const onAttachmentClose = (event, name, id) => {
41
40
  const updatedMessages: MessageProps[] = [];
42
- if (index >= 0) {
43
- messages.forEach((message) => updatedMessages.push(message));
44
- delete updatedMessages[index].attachmentName;
45
- delete updatedMessages[index].attachmentId;
46
- delete updatedMessages[index].onAttachmentClick;
47
- delete updatedMessages[index].onAttachmentClose;
48
- setMessages(updatedMessages);
49
- }
41
+ messages.map((message) => {
42
+ if (message.attachments) {
43
+ const filteredAttachments = message.attachments.filter((attachment) => attachment.id !== id);
44
+ message.attachments = filteredAttachments;
45
+ updatedMessages.push(message);
46
+ } else {
47
+ updatedMessages.push(message);
48
+ }
49
+ });
50
+ setMessages(updatedMessages);
50
51
  };
52
+
53
+ const onAttachmentClick = () => {
54
+ setCurrentModalData({ fileName: 'auth-operator.yml', code: 'test' });
55
+ setIsEditModalOpen(false);
56
+ setIsPreviewModalOpen(true);
57
+ };
58
+
51
59
  const initialMessages: MessageProps[] = [
52
60
  {
53
61
  role: 'user',
@@ -55,14 +63,7 @@ export const BasicDemo: React.FunctionComponent = () => {
55
63
  name: 'User',
56
64
  avatar: userAvatar,
57
65
  avatarProps: { isBordered: true },
58
- attachmentName: 'auth-operator.yml',
59
- attachmentId: '1',
60
- onAttachmentClose,
61
- onAttachmentClick: () => {
62
- setCurrentModalData({ fileName: 'auth-operator.yml', code: 'test' });
63
- setIsEditModalOpen(false);
64
- setIsPreviewModalOpen(true);
65
- }
66
+ attachments: [{ name: 'auth-operator.yml', id: '1', onClick: onAttachmentClick, onClose: onAttachmentClose }]
66
67
  },
67
68
  {
68
69
  role: 'bot',
@@ -243,7 +244,7 @@ export const BasicDemo: React.FunctionComponent = () => {
243
244
  </div>
244
245
  )}
245
246
  <MessageBar onSendMessage={handleSend} hasAttachButton handleAttach={handleAttach} />
246
- <ChatbotFootnote label="Lightspeed uses AI. Check for mistakes." />
247
+ <ChatbotFootnote label="ChatBot uses AI. Check for mistakes." />
247
248
  </ChatbotFooter>
248
249
  </FileDropZone>
249
250
  </Chatbot>
@@ -259,7 +259,7 @@ export const AttachmentMenuDemo: React.FunctionComponent = () => {
259
259
  onAttachMenuToggleClick: onToggleClick
260
260
  }}
261
261
  />
262
- <ChatbotFootnote label="Lightspeed uses AI. Check for mistakes." />
262
+ <ChatbotFootnote label="ChatBot uses AI. Check for mistakes." />
263
263
  </ChatbotFooter>
264
264
  </>
265
265
  </FileDropZone>
@@ -42,10 +42,10 @@ import userAvatar from '../Messages/user_avatar.svg';
42
42
  import patternflyAvatar from '../Messages/patternfly_avatar.jpg';
43
43
 
44
44
  const footnoteProps = {
45
- label: 'Lightspeed uses AI. Check for mistakes.',
45
+ label: 'ChatBot uses AI. Check for mistakes.',
46
46
  popover: {
47
47
  title: 'Verify accuracy',
48
- description: `While Lightspeed strives for accuracy, there's always a possibility of errors. It's a good practice to verify critical information from reliable sources, especially if it's crucial for decision-making or actions.`,
48
+ description: `While ChatBot strives for accuracy, there's always a possibility of errors. It's a good practice to verify critical information from reliable sources, especially if it's crucial for decision-making or actions.`,
49
49
  bannerImage: {
50
50
  src: 'https://cdn.dribbble.com/userupload/10651749/file/original-8a07b8e39d9e8bf002358c66fce1223e.gif',
51
51
  alt: 'Example image for footnote popover'
@@ -54,16 +54,6 @@
54
54
  }
55
55
  }
56
56
 
57
- html.pf-chatbot-allow--docked {
58
- padding-inline-start: 480px;
59
-
60
- // 30rem is the width of the docked chatbot
61
- // if the screen is smaller, we want to be 100%
62
- @media screen and (max-width: 30rem) {
63
- padding-inline-start: 0px;
64
- }
65
- }
66
-
67
57
  // ============================================================================
68
58
  // Chatbot Display Mode - Fullscreen
69
59
  // ============================================================================
@@ -35,15 +35,6 @@ const ChatbotBase: React.FunctionComponent<ChatbotProps> = ({
35
35
  ariaLabel,
36
36
  ...props
37
37
  }: ChatbotProps) => {
38
- // Configure docked mode
39
- React.useEffect(() => {
40
- if (displayMode === ChatbotDisplayMode.docked) {
41
- document.documentElement.classList.add('pf-chatbot-allow--docked');
42
- } else {
43
- document.documentElement.classList.remove('pf-chatbot-allow--docked');
44
- }
45
- }, [displayMode]);
46
-
47
38
  // Configure animations
48
39
  const motionChatbot = {
49
40
  visible: { opacity: 1, y: 0 },
@@ -44,10 +44,23 @@
44
44
  color: var(--pf-t--global--text--color--regular);
45
45
  font-size: var(--pf-t--global--font--size--body--lg);
46
46
  font-weight: var(--pf-t--global--font--weight--body--default);
47
+ border-radius: var(--pf-t--global--border--radius--small);
48
+ }
49
+ // allows focus state to have border radius
50
+ .pf-v6-c-menu__list-item.pf-chatbot__menu-item {
51
+ overflow: hidden;
47
52
  }
48
53
  .pf-chatbot__history-actions {
49
54
  transform: rotate(90deg);
50
55
  }
56
+
57
+ .pf-chatbot__menu-item--active {
58
+ background-color: var(--pf-t--global--background--color--action--plain--clicked);
59
+ }
60
+
61
+ button.pf-chatbot__menu-item--active {
62
+ background-color: initial;
63
+ }
51
64
  }
52
65
 
53
66
  // Chatbot Header - Drawer
@@ -105,6 +118,7 @@
105
118
  border-radius: var(--pf-t--global--border--radius--pill);
106
119
  justify-content: center;
107
120
  align-items: center;
121
+ border-radius: var(--pf-t--global--border--radius--small);
108
122
  }
109
123
  }
110
124
 
@@ -11,7 +11,7 @@ describe('ChatbotConversationHistoryNav', () => {
11
11
  const initialConversations: Conversation[] = [
12
12
  {
13
13
  id: '1',
14
- text: 'Lightspeed documentation'
14
+ text: 'ChatBot documentation'
15
15
  }
16
16
  ];
17
17
 
@@ -25,7 +25,7 @@ describe('ChatbotConversationHistoryNav', () => {
25
25
  conversations={initialConversations}
26
26
  />
27
27
  );
28
- expect(screen.queryByText('Lightspeed documentation')).toBeInTheDocument();
28
+ expect(screen.queryByText('ChatBot documentation')).toBeInTheDocument();
29
29
  });
30
30
 
31
31
  it('should display the conversations for grouped conversations', () => {
@@ -120,7 +120,7 @@ describe('ChatbotConversationHistoryNav', () => {
120
120
  });
121
121
 
122
122
  waitFor(() => {
123
- expect(screen.queryByText('Lightspeed documentation')).not.toBeInTheDocument();
123
+ expect(screen.queryByText('ChatBot documentation')).not.toBeInTheDocument();
124
124
  });
125
125
  });
126
126
  });
@@ -20,7 +20,9 @@ import {
20
20
  MenuList,
21
21
  MenuGroup,
22
22
  MenuItem,
23
- MenuContent
23
+ MenuContent,
24
+ MenuItemProps,
25
+ MenuProps
24
26
  } from '@patternfly/react-core';
25
27
 
26
28
  import { OutlinedCommentAltIcon } from '@patternfly/react-icons';
@@ -44,6 +46,8 @@ export interface Conversation {
44
46
  label?: string;
45
47
  /** Callback for when user selects item. */
46
48
  onSelect?: (event?: React.MouseEvent, value?: string | number) => void;
49
+ /** Additional props passed to conversation menu item */
50
+ additionalProps?: MenuItemProps;
47
51
  }
48
52
  export interface ChatbotConversationHistoryNavProps extends DrawerProps {
49
53
  /** Function called to toggle drawer */
@@ -76,6 +80,8 @@ export interface ChatbotConversationHistoryNavProps extends DrawerProps {
76
80
  reverseButtonOrder?: boolean;
77
81
  /** Custom test id for the drawer actions */
78
82
  drawerActionsTestId?: string;
83
+ /** Additional props applied to menu */
84
+ menuProps?: MenuProps;
79
85
  }
80
86
 
81
87
  export const ChatbotConversationHistoryNav: React.FunctionComponent<ChatbotConversationHistoryNavProps> = ({
@@ -94,6 +100,7 @@ export const ChatbotConversationHistoryNav: React.FunctionComponent<ChatbotConve
94
100
  displayMode,
95
101
  reverseButtonOrder = false,
96
102
  drawerActionsTestId = 'chatbot-nav-drawer-actions',
103
+ menuProps,
97
104
  ...props
98
105
  }: ChatbotConversationHistoryNavProps) => {
99
106
  const drawerRef = React.useRef<HTMLDivElement>(null);
@@ -104,7 +111,7 @@ export const ChatbotConversationHistoryNav: React.FunctionComponent<ChatbotConve
104
111
 
105
112
  const getNavItem = (conversation: Conversation) => (
106
113
  <MenuItem
107
- className="pf-chatbot__menu-item"
114
+ className={`pf-chatbot__menu-item ${activeItemId && activeItemId === conversation.id ? 'pf-chatbot__menu-item--active' : ''}`}
108
115
  itemId={conversation.id}
109
116
  key={conversation.id}
110
117
  {...(conversation.noIcon ? {} : { icon: conversation.icon ?? <OutlinedCommentAltIcon /> })}
@@ -121,6 +128,7 @@ export const ChatbotConversationHistoryNav: React.FunctionComponent<ChatbotConve
121
128
  )
122
129
  }
123
130
  : {})}
131
+ {...conversation.additionalProps}
124
132
  /* eslint-enable indent */
125
133
  >
126
134
  {conversation.text}
@@ -159,7 +167,7 @@ export const ChatbotConversationHistoryNav: React.FunctionComponent<ChatbotConve
159
167
  // - Consumers should pass an array to <Chatbot> of the list of conversations
160
168
  // - Groups could be optional, but items need to be ordered by date
161
169
  const menuContent = (
162
- <Menu isPlain onSelect={onSelectActiveItem} activeItemId={activeItemId}>
170
+ <Menu isPlain onSelect={onSelectActiveItem} activeItemId={activeItemId} {...menuProps}>
163
171
  <MenuContent>{buildMenu()}</MenuContent>
164
172
  </Menu>
165
173
  );
@@ -33,7 +33,8 @@
33
33
  }
34
34
  }
35
35
  .pf-chatbot__footer-container {
36
- width: 60rem;
36
+ width: 90%;
37
+ max-width: 60rem;
37
38
  padding: var(--pf-t--global--spacer--sm) 0;
38
39
  }
39
40
  }
@@ -0,0 +1,51 @@
1
+ import React from 'react';
2
+
3
+ import { Button, Icon, Tooltip, TooltipProps } from '@patternfly/react-core';
4
+ import { CloseIcon } from '@patternfly/react-icons';
5
+
6
+ export interface ChatbotHeaderCloseButtonProps {
7
+ /** Callback function for when button is clicked */
8
+ onClick: () => void;
9
+ /** Custom classname for the header component */
10
+ className?: string;
11
+ /** Props spread to the PF Tooltip component wrapping the display mode dropdown */
12
+ tooltipProps?: TooltipProps;
13
+ /** Aria label for menu */
14
+ menuAriaLabel?: string;
15
+ /** Ref applied to menu */
16
+ innerRef?: React.Ref<HTMLButtonElement>;
17
+ /** Content used in tooltip */
18
+ tooltipContent?: string;
19
+ }
20
+
21
+ const ChatbotHeaderCloseButtonBase: React.FunctionComponent<ChatbotHeaderCloseButtonProps> = ({
22
+ className,
23
+ onClick,
24
+ tooltipProps,
25
+ menuAriaLabel = 'Close',
26
+ innerRef,
27
+ tooltipContent = 'Close'
28
+ }: ChatbotHeaderCloseButtonProps) => (
29
+ <div className={`pf-chatbot__menu ${className}`}>
30
+ <Tooltip content={tooltipContent} position="bottom" {...tooltipProps}>
31
+ <Button
32
+ className="pf-chatbot__button--toggle-menu"
33
+ variant="plain"
34
+ onClick={onClick}
35
+ aria-label={menuAriaLabel}
36
+ ref={innerRef}
37
+ icon={
38
+ <Icon size="xl" isInline>
39
+ <CloseIcon />
40
+ </Icon>
41
+ }
42
+ />
43
+ </Tooltip>
44
+ </div>
45
+ );
46
+
47
+ export const ChatbotHeaderCloseButton = React.forwardRef(
48
+ (props: ChatbotHeaderCloseButtonProps, ref: React.Ref<HTMLButtonElement>) => (
49
+ <ChatbotHeaderCloseButtonBase innerRef={ref} {...props} />
50
+ )
51
+ );
@@ -14,6 +14,8 @@ export interface ChatbotHeaderMenuProps {
14
14
  menuAriaLabel?: string;
15
15
  /** Ref applied to menu */
16
16
  innerRef?: React.Ref<HTMLButtonElement>;
17
+ /** Content used in tooltip */
18
+ tooltipContent?: string;
17
19
  }
18
20
 
19
21
  const ChatbotHeaderMenuBase: React.FunctionComponent<ChatbotHeaderMenuProps> = ({
@@ -21,10 +23,11 @@ const ChatbotHeaderMenuBase: React.FunctionComponent<ChatbotHeaderMenuProps> = (
21
23
  onMenuToggle,
22
24
  tooltipProps,
23
25
  menuAriaLabel = 'Toggle menu',
24
- innerRef
26
+ innerRef,
27
+ tooltipContent = 'Menu'
25
28
  }: ChatbotHeaderMenuProps) => (
26
29
  <div className={`pf-chatbot__menu ${className}`}>
27
- <Tooltip content="Menu" position="bottom" {...tooltipProps}>
30
+ <Tooltip content={tooltipContent} position="bottom" {...tooltipProps}>
28
31
  <Button
29
32
  className="pf-chatbot__button--toggle-menu"
30
33
  variant="plain"
@@ -7,3 +7,4 @@ export * from './ChatbotHeaderMenu';
7
7
  export * from './ChatbotHeaderTitle';
8
8
  export * from './ChatbotHeaderOptionsDropdown';
9
9
  export * from './ChatbotHeaderSelectorDropdown';
10
+ export * from './ChatbotHeaderCloseButton';
@@ -74,3 +74,11 @@
74
74
  }
75
75
  }
76
76
  }
77
+
78
+ .pf-chatbot__code-modal-body {
79
+ flex: 1;
80
+ }
81
+
82
+ .pf-chatbot__code-modal--fullscreen {
83
+ height: inherit; // override shared modal so code editor works in full screen
84
+ }
@@ -87,17 +87,6 @@ export const CodeModal: React.FunctionComponent<CodeModalProps> = ({
87
87
  }
88
88
  };
89
89
 
90
- /* eslint-disable indent */
91
- const getHeight = (displayMode: ChatbotDisplayMode) => {
92
- switch (displayMode) {
93
- case ChatbotDisplayMode.docked:
94
- return '100vh';
95
- default:
96
- return '45vh';
97
- }
98
- };
99
- /* eslint-enable indent */
100
-
101
90
  const modal = (
102
91
  <ChatbotModal
103
92
  isOpen={isModalOpen}
@@ -114,7 +103,7 @@ export const CodeModal: React.FunctionComponent<CodeModalProps> = ({
114
103
  <StackItem className="pf-chatbot__code-modal-file-details">
115
104
  <FileDetails fileName={fileName} />
116
105
  </StackItem>
117
- <StackItem>
106
+ <StackItem className="pf-chatbot__code-modal-body">
118
107
  <CodeEditor
119
108
  isDarkTheme
120
109
  isLineNumbersVisible={isLineNumbersVisible}
@@ -126,7 +115,7 @@ export const CodeModal: React.FunctionComponent<CodeModalProps> = ({
126
115
  onEditorDidMount={onEditorDidMount}
127
116
  onCodeChange={onCodeChange}
128
117
  className={codeEditorClassName}
129
- height={getHeight(displayMode)}
118
+ isFullHeight
130
119
  options={{
131
120
  glyphMargin: false,
132
121
  folding: false
@@ -9,7 +9,7 @@ exports[`FileDropZone should render file drop zone 1`] = `
9
9
  >
10
10
  <input
11
11
  multiple=""
12
- style="display: none;"
12
+ style="border: 0px; clip: rect(0px, 0px, 0px, 0px); clip-path: inset(50%); height: 1px; margin: 0px -1px -1px 0px; overflow: hidden; padding: 0px; position: absolute; width: 1px; white-space: nowrap;"
13
13
  tabindex="-1"
14
14
  type="file"
15
15
  />
@@ -6,9 +6,9 @@ import React from 'react';
6
6
  import { ExtraProps } from 'react-markdown';
7
7
  import { List, ListComponent, OrderType } from '@patternfly/react-core';
8
8
 
9
- const OrderedListMessage = ({ children }: JSX.IntrinsicElements['ol'] & ExtraProps) => (
9
+ const OrderedListMessage = ({ children, start }: JSX.IntrinsicElements['ol'] & ExtraProps) => (
10
10
  <div className="pf-chatbot__message-ordered-list">
11
- <List component={ListComponent.ol} type={OrderType.number}>
11
+ <List component={ListComponent.ol} type={OrderType.number} start={start}>
12
12
  {children}
13
13
  </List>
14
14
  </div>
@@ -95,20 +95,6 @@
95
95
  display: grid;
96
96
  gap: var(--pf-t--global--spacer--sm);
97
97
  }
98
-
99
- &-quick-response {
100
- .pf-v6-c-label {
101
- --pf-v6-c-label--FontSize: var(--pf-t--global--font--size--md);
102
-
103
- @media screen and (min-width: 401px) and (max-width: 600px) {
104
- --pf-v6-c-label__text--MaxWidth: 20ch;
105
- }
106
-
107
- @media screen and (max-width: 400px) {
108
- --pf-v6-c-label__text--MaxWidth: 15ch;
109
- }
110
- }
111
- }
112
98
  }
113
99
 
114
100
  // Attachments
@@ -3,6 +3,8 @@ import { render, screen } from '@testing-library/react';
3
3
  import '@testing-library/jest-dom';
4
4
  import Message from './Message';
5
5
  import userEvent from '@testing-library/user-event';
6
+ import { monitorSampleAppQuickStart } from './QuickStarts/monitor-sampleapp-quickstart';
7
+ import { monitorSampleAppQuickStartWithImage } from './QuickStarts/monitor-sampleapp-quickstart-with-image';
6
8
 
7
9
  const ALL_ACTIONS = [
8
10
  { label: /Good response/i },
@@ -53,6 +55,22 @@ spec:
53
55
 
54
56
  const INLINE_CODE = `Here is an inline code - \`() => void\``;
55
57
 
58
+ const ORDERED_LIST_WITH_CODE = `
59
+ 1. Item 1
60
+ 2. Item 2
61
+
62
+ \`\`\`yaml
63
+ - name: Hello World Playbook
64
+ hosts: localhost
65
+ tasks:
66
+ - name: Print Hello World
67
+ ansible.builtin.debug:
68
+ msg: "Hello, World!"
69
+ \`\`\`
70
+
71
+ 3. Item 3
72
+ `;
73
+
56
74
  const checkListItemsRendered = () => {
57
75
  const items = ['Item 1', 'Item 2', 'Item 3'];
58
76
  expect(screen.getAllByRole('listitem')).toHaveLength(3);
@@ -344,6 +362,12 @@ describe('Message', () => {
344
362
  expect(screen.getByText('Here is an ordered list:')).toBeTruthy();
345
363
  checkListItemsRendered();
346
364
  });
365
+ it('should render ordered lists correctly if there is interstitial content', () => {
366
+ render(<Message avatar="./img" role="user" name="User" content={ORDERED_LIST_WITH_CODE} />);
367
+ checkListItemsRendered();
368
+ const list = screen.getAllByRole('list')[1];
369
+ expect(list).toHaveAttribute('start', '3');
370
+ });
347
371
  it('should render inline code', () => {
348
372
  render(<Message avatar="./img" role="user" name="User" content={INLINE_CODE} />);
349
373
  expect(screen.getByText(/() => void/i)).toBeTruthy();
@@ -415,4 +439,56 @@ describe('Message', () => {
415
439
  expect(screen.getByRole('img')).toHaveClass('test');
416
440
  expect(screen.getByRole('img')).toHaveClass('pf-chatbot__message-avatar');
417
441
  });
442
+ it('should handle QuickStart tile correctly', () => {
443
+ render(
444
+ <Message
445
+ avatar="./img"
446
+ role="user"
447
+ name="User"
448
+ content="Hi"
449
+ quickStarts={{
450
+ quickStart: monitorSampleAppQuickStart,
451
+ onSelectQuickStart: (id) => alert(id)
452
+ }}
453
+ />
454
+ );
455
+ expect(screen.getByRole('button', { name: 'Monitoring your sample application' })).toBeTruthy();
456
+ expect(screen.getByRole('heading', { name: '1 Prerequisite' })).toBeTruthy();
457
+ expect(screen.getByRole('button', { name: 'Show prerequisites' })).toBeTruthy();
458
+ expect(screen.getByRole('button', { name: 'Start' })).toBeTruthy();
459
+ });
460
+ it('should handle click on QuickStart tile correctly', async () => {
461
+ const spy = jest.fn();
462
+ render(
463
+ <Message
464
+ avatar="./img"
465
+ role="user"
466
+ name="User"
467
+ content="Hi"
468
+ quickStarts={{
469
+ quickStart: monitorSampleAppQuickStart,
470
+ onSelectQuickStart: (id) => spy(id)
471
+ }}
472
+ />
473
+ );
474
+ await userEvent.click(screen.getByRole('button', { name: 'Monitoring your sample application' }));
475
+ expect(spy).toHaveBeenCalledTimes(1);
476
+ expect(spy).toHaveBeenCalledWith(monitorSampleAppQuickStart.metadata.name);
477
+ });
478
+ it('should handle QuickStart tile with image correctly', async () => {
479
+ const spy = jest.fn();
480
+ render(
481
+ <Message
482
+ avatar="./img"
483
+ role="user"
484
+ name="User"
485
+ content="Hi"
486
+ quickStarts={{
487
+ quickStart: monitorSampleAppQuickStartWithImage,
488
+ onSelectQuickStart: (id) => spy(id)
489
+ }}
490
+ />
491
+ );
492
+ expect(screen.getAllByRole('img')[1]).toHaveAttribute('src', 'test.png');
493
+ });
418
494
  });