@patternfly/chatbot 6.3.2 → 6.4.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 (133) hide show
  1. package/dist/cjs/ChatbotConversationHistoryNav/ChatbotConversationHistoryDropdown.d.ts +2 -0
  2. package/dist/cjs/ChatbotConversationHistoryNav/ChatbotConversationHistoryDropdown.js +2 -2
  3. package/dist/cjs/ChatbotConversationHistoryNav/ChatbotConversationHistoryDropdown.test.js +6 -6
  4. package/dist/cjs/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.d.ts +27 -4
  5. package/dist/cjs/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.js +8 -14
  6. package/dist/cjs/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.test.js +53 -2
  7. package/dist/cjs/ChatbotHeader/ChatbotHeaderMenu.js +1 -1
  8. package/dist/cjs/ChatbotHeader/ChatbotHeaderMenu.test.js +1 -1
  9. package/dist/cjs/ChatbotHeader/ChatbotHeaderNewChatButton.d.ts +18 -0
  10. package/dist/cjs/ChatbotHeader/ChatbotHeaderNewChatButton.js +25 -0
  11. package/dist/cjs/ChatbotHeader/ChatbotHeaderNewChatButton.test.d.ts +1 -0
  12. package/dist/cjs/ChatbotHeader/ChatbotHeaderNewChatButton.test.js +22 -0
  13. package/dist/cjs/ChatbotHeader/index.d.ts +1 -0
  14. package/dist/cjs/ChatbotHeader/index.js +1 -0
  15. package/dist/cjs/FileDropZone/FileDropZone.d.ts +1 -2
  16. package/dist/cjs/Message/Message.d.ts +9 -2
  17. package/dist/cjs/Message/Message.js +40 -34
  18. package/dist/cjs/Message/Message.test.js +37 -0
  19. package/dist/cjs/Message/MessageInput.d.ts +3 -1
  20. package/dist/cjs/Message/MessageInput.js +2 -2
  21. package/dist/cjs/MessageBar/AttachButton.d.ts +2 -2
  22. package/dist/cjs/MessageBar/MessageBar.d.ts +2 -2
  23. package/dist/cjs/MessageBox/JumpButton.d.ts +5 -0
  24. package/dist/cjs/MessageBox/JumpButton.js +1 -1
  25. package/dist/cjs/MessageBox/JumpButton.test.js +4 -4
  26. package/dist/cjs/MessageBox/MessageBox.d.ts +9 -0
  27. package/dist/cjs/MessageBox/MessageBox.js +2 -2
  28. package/dist/cjs/MessageBox/MessageBox.test.js +2 -2
  29. package/dist/cjs/MessageDivider/MessageDivider.d.ts +9 -0
  30. package/dist/cjs/MessageDivider/MessageDivider.js +23 -0
  31. package/dist/cjs/MessageDivider/MessageDivider.test.d.ts +1 -0
  32. package/dist/cjs/MessageDivider/MessageDivider.test.js +29 -0
  33. package/dist/cjs/MessageDivider/index.d.ts +2 -0
  34. package/dist/cjs/MessageDivider/index.js +23 -0
  35. package/dist/cjs/ResponseActions/ResponseActions.d.ts +1 -0
  36. package/dist/cjs/ResponseActions/ResponseActions.js +4 -4
  37. package/dist/cjs/ResponseActions/ResponseActions.test.js +6 -1
  38. package/dist/cjs/index.d.ts +2 -0
  39. package/dist/cjs/index.js +4 -1
  40. package/dist/css/main.css +103 -81
  41. package/dist/css/main.css.map +1 -1
  42. package/dist/dynamic/MessageDivider/package.json +1 -0
  43. package/dist/esm/ChatbotConversationHistoryNav/ChatbotConversationHistoryDropdown.d.ts +2 -0
  44. package/dist/esm/ChatbotConversationHistoryNav/ChatbotConversationHistoryDropdown.js +2 -2
  45. package/dist/esm/ChatbotConversationHistoryNav/ChatbotConversationHistoryDropdown.test.js +6 -6
  46. package/dist/esm/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.d.ts +27 -4
  47. package/dist/esm/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.js +10 -16
  48. package/dist/esm/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.test.js +54 -3
  49. package/dist/esm/ChatbotHeader/ChatbotHeaderMenu.js +1 -1
  50. package/dist/esm/ChatbotHeader/ChatbotHeaderMenu.test.js +1 -1
  51. package/dist/esm/ChatbotHeader/ChatbotHeaderNewChatButton.d.ts +18 -0
  52. package/dist/esm/ChatbotHeader/ChatbotHeaderNewChatButton.js +22 -0
  53. package/dist/esm/ChatbotHeader/ChatbotHeaderNewChatButton.test.d.ts +1 -0
  54. package/dist/esm/ChatbotHeader/ChatbotHeaderNewChatButton.test.js +20 -0
  55. package/dist/esm/ChatbotHeader/index.d.ts +1 -0
  56. package/dist/esm/ChatbotHeader/index.js +1 -0
  57. package/dist/esm/FileDropZone/FileDropZone.d.ts +1 -2
  58. package/dist/esm/Message/Message.d.ts +9 -2
  59. package/dist/esm/Message/Message.js +40 -34
  60. package/dist/esm/Message/Message.test.js +37 -0
  61. package/dist/esm/Message/MessageInput.d.ts +3 -1
  62. package/dist/esm/Message/MessageInput.js +2 -2
  63. package/dist/esm/MessageBar/AttachButton.d.ts +2 -2
  64. package/dist/esm/MessageBar/MessageBar.d.ts +2 -2
  65. package/dist/esm/MessageBox/JumpButton.d.ts +5 -0
  66. package/dist/esm/MessageBox/JumpButton.js +1 -1
  67. package/dist/esm/MessageBox/JumpButton.test.js +4 -4
  68. package/dist/esm/MessageBox/MessageBox.d.ts +9 -0
  69. package/dist/esm/MessageBox/MessageBox.js +2 -2
  70. package/dist/esm/MessageBox/MessageBox.test.js +2 -2
  71. package/dist/esm/MessageDivider/MessageDivider.d.ts +9 -0
  72. package/dist/esm/MessageDivider/MessageDivider.js +21 -0
  73. package/dist/esm/MessageDivider/MessageDivider.test.d.ts +1 -0
  74. package/dist/esm/MessageDivider/MessageDivider.test.js +24 -0
  75. package/dist/esm/MessageDivider/index.d.ts +2 -0
  76. package/dist/esm/MessageDivider/index.js +2 -0
  77. package/dist/esm/ResponseActions/ResponseActions.d.ts +1 -0
  78. package/dist/esm/ResponseActions/ResponseActions.js +5 -5
  79. package/dist/esm/ResponseActions/ResponseActions.test.js +6 -1
  80. package/dist/esm/index.d.ts +2 -0
  81. package/dist/esm/index.js +2 -0
  82. package/dist/tsconfig.tsbuildinfo +1 -1
  83. package/package.json +9 -4
  84. package/patternfly-docs/content/extensions/chatbot/examples/Messages/MessageWithDividers.tsx +24 -0
  85. package/patternfly-docs/content/extensions/chatbot/examples/Messages/Messages.md +15 -1
  86. package/patternfly-docs/content/extensions/chatbot/examples/Messages/UserMessage.tsx +39 -7
  87. package/patternfly-docs/content/extensions/chatbot/examples/UI/ChatbotConversationEditing.tsx +202 -0
  88. package/patternfly-docs/content/extensions/chatbot/examples/UI/ChatbotHeaderBasic.tsx +17 -3
  89. package/patternfly-docs/content/extensions/chatbot/examples/UI/ChatbotHeaderDrawer.tsx +45 -5
  90. package/patternfly-docs/content/extensions/chatbot/examples/UI/ChatbotHeaderDrawerWithPin.tsx +206 -0
  91. package/patternfly-docs/content/extensions/chatbot/examples/UI/UI.md +30 -4
  92. package/patternfly-docs/content/extensions/chatbot/examples/demos/Chatbot.md +33 -1
  93. package/patternfly-docs/content/extensions/chatbot/examples/demos/ChatbotDisplayMode.tsx +486 -0
  94. package/patternfly-docs/content/extensions/chatbot/examples/demos/ChatbotTranscripts.tsx +565 -0
  95. package/src/Chatbot/Chatbot.scss +1 -1
  96. package/src/ChatbotContent/ChatbotContent.scss +1 -1
  97. package/src/ChatbotConversationHistoryNav/ChatbotConversationHistoryDropdown.test.tsx +6 -6
  98. package/src/ChatbotConversationHistoryNav/ChatbotConversationHistoryDropdown.tsx +5 -2
  99. package/src/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.scss +70 -32
  100. package/src/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.test.tsx +176 -3
  101. package/src/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.tsx +110 -60
  102. package/src/ChatbotFooter/ChatbotFooter.scss +1 -1
  103. package/src/ChatbotHeader/ChatbotHeader.scss +3 -3
  104. package/src/ChatbotHeader/ChatbotHeaderMenu.test.tsx +1 -1
  105. package/src/ChatbotHeader/ChatbotHeaderMenu.tsx +2 -2
  106. package/src/ChatbotHeader/ChatbotHeaderNewChatButton.test.tsx +25 -0
  107. package/src/ChatbotHeader/ChatbotHeaderNewChatButton.tsx +64 -0
  108. package/src/ChatbotHeader/index.ts +1 -0
  109. package/src/ChatbotModal/ChatbotModal.scss +1 -1
  110. package/src/ChatbotToggle/ChatbotToggle.scss +2 -2
  111. package/src/FileDetails/__snapshots__/FileDetails.test.tsx.snap +6 -9
  112. package/src/FileDetailsLabel/__snapshots__/FileDetailsLabel.test.tsx.snap +6 -9
  113. package/src/FileDropZone/FileDropZone.tsx +2 -2
  114. package/src/Message/Message.scss +9 -7
  115. package/src/Message/Message.test.tsx +54 -0
  116. package/src/Message/Message.tsx +70 -50
  117. package/src/Message/MessageInput.tsx +5 -1
  118. package/src/MessageBar/AttachButton.tsx +2 -2
  119. package/src/MessageBar/MessageBar.tsx +2 -2
  120. package/src/MessageBar/SendButton.scss +3 -3
  121. package/src/MessageBox/JumpButton.scss +1 -1
  122. package/src/MessageBox/JumpButton.test.tsx +4 -4
  123. package/src/MessageBox/JumpButton.tsx +20 -4
  124. package/src/MessageBox/MessageBox.test.tsx +2 -2
  125. package/src/MessageBox/MessageBox.tsx +23 -2
  126. package/src/MessageDivider/MessageDivider.scss +45 -0
  127. package/src/MessageDivider/MessageDivider.test.tsx +24 -0
  128. package/src/MessageDivider/MessageDivider.tsx +35 -0
  129. package/src/MessageDivider/index.ts +3 -0
  130. package/src/ResponseActions/ResponseActions.test.tsx +6 -1
  131. package/src/ResponseActions/ResponseActions.tsx +24 -3
  132. package/src/index.ts +3 -0
  133. package/src/main.scss +1 -52
@@ -0,0 +1,21 @@
1
+ var __rest = (this && this.__rest) || function (s, e) {
2
+ var t = {};
3
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
4
+ t[p] = s[p];
5
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
6
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
7
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
8
+ t[p[i]] = s[p[i]];
9
+ }
10
+ return t;
11
+ };
12
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
13
+ import { Divider, Label } from '@patternfly/react-core';
14
+ const MessageDivider = (_a) => {
15
+ var { variant = 'inset', content = new Date().toLocaleDateString() } = _a, props = __rest(_a, ["variant", "content"]);
16
+ if (variant === 'inset') {
17
+ return (_jsxs("div", Object.assign({ className: "pf-chatbot__message-divider pf-m-divider pf-m-wrap" }, props, { children: [_jsx(Divider, {}), _jsx(Label, { variant: "outline", children: content })] })));
18
+ }
19
+ return (_jsx("div", Object.assign({ className: "pf-chatbot__message-divider pf-m-wrap" }, props, { children: _jsx(Label, { children: content }) })));
20
+ };
21
+ export default MessageDivider;
@@ -0,0 +1 @@
1
+ import '@testing-library/jest-dom';
@@ -0,0 +1,24 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { render, screen } from '@testing-library/react';
3
+ import '@testing-library/jest-dom';
4
+ import MessageDivider from './MessageDivider';
5
+ describe('MessageDivider', () => {
6
+ beforeEach(() => {
7
+ jest.clearAllMocks();
8
+ });
9
+ it('should render default correctly with variant = date and content = new Date().toLocaleDateString()', () => {
10
+ render(_jsx(MessageDivider, { "data-testid": "message-divider" }));
11
+ expect(screen.getByText(new Date().toLocaleDateString())).toBeInTheDocument();
12
+ expect(screen.getByTestId('message-divider')).toHaveClass('pf-m-divider');
13
+ });
14
+ it('should render inset variant correctly', () => {
15
+ render(_jsx(MessageDivider, { variant: "inset", content: "test", "data-testid": "message-divider" }));
16
+ expect(screen.getByText('test')).toBeInTheDocument();
17
+ expect(screen.getByTestId('message-divider')).toHaveClass('pf-m-divider');
18
+ });
19
+ it('should render fullWidth variant correctly', () => {
20
+ render(_jsx(MessageDivider, { variant: "fullWidth", content: "test", "data-testid": "message-divider" }));
21
+ expect(screen.getByText('test')).toBeInTheDocument();
22
+ expect(screen.getByTestId('message-divider')).not.toHaveClass('pf-m-divider');
23
+ });
24
+ });
@@ -0,0 +1,2 @@
1
+ export { default } from './MessageDivider';
2
+ export * from './MessageDivider';
@@ -0,0 +1,2 @@
1
+ export { default } from './MessageDivider';
2
+ export * from './MessageDivider';
@@ -38,6 +38,7 @@ export interface ResponseActionProps {
38
38
  share?: ActionProps;
39
39
  download?: ActionProps;
40
40
  listen?: ActionProps;
41
+ edit?: ActionProps;
41
42
  };
42
43
  }
43
44
  export declare const ResponseActions: FunctionComponent<ResponseActionProps>;
@@ -12,15 +12,15 @@ var __rest = (this && this.__rest) || function (s, e) {
12
12
  import { createElement as _createElement } from "react";
13
13
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
14
14
  import { useEffect, useRef, useState } from 'react';
15
- import { ExternalLinkAltIcon, VolumeUpIcon, OutlinedThumbsUpIcon, OutlinedThumbsDownIcon, OutlinedCopyIcon, DownloadIcon } from '@patternfly/react-icons';
15
+ import { ExternalLinkAltIcon, VolumeUpIcon, OutlinedThumbsUpIcon, OutlinedThumbsDownIcon, OutlinedCopyIcon, DownloadIcon, PencilAltIcon } from '@patternfly/react-icons';
16
16
  import ResponseActionButton from './ResponseActionButton';
17
17
  export const ResponseActions = ({ actions }) => {
18
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z;
18
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _0, _1, _2, _3;
19
19
  const [activeButton, setActiveButton] = useState();
20
20
  const [clickStatePersisted, setClickStatePersisted] = useState(false);
21
21
  useEffect(() => {
22
22
  // Define the order of precedence for checking initial `isClicked`
23
- const actionPrecedence = ['positive', 'negative', 'copy', 'share', 'download', 'listen'];
23
+ const actionPrecedence = ['positive', 'negative', 'copy', 'edit', 'share', 'download', 'listen'];
24
24
  let initialActive;
25
25
  // Check predefined actions first based on precedence
26
26
  for (const actionName of actionPrecedence) {
@@ -41,7 +41,7 @@ export const ResponseActions = ({ actions }) => {
41
41
  }
42
42
  setActiveButton(initialActive);
43
43
  }, [actions]);
44
- const { positive, negative, copy, share, download, listen } = actions, additionalActions = __rest(actions, ["positive", "negative", "copy", "share", "download", "listen"]);
44
+ const { positive, negative, copy, edit, share, download, listen } = actions, additionalActions = __rest(actions, ["positive", "negative", "copy", "edit", "share", "download", "listen"]);
45
45
  const responseActions = useRef(null);
46
46
  useEffect(() => {
47
47
  const handleClickOutside = (e) => {
@@ -59,7 +59,7 @@ export const ResponseActions = ({ actions }) => {
59
59
  setActiveButton(id);
60
60
  onClick && onClick(e);
61
61
  };
62
- return (_jsxs("div", { ref: responseActions, className: "pf-chatbot__response-actions", children: [positive && (_jsx(ResponseActionButton, Object.assign({}, positive, { ariaLabel: (_a = positive.ariaLabel) !== null && _a !== void 0 ? _a : 'Good response', clickedAriaLabel: (_b = positive.ariaLabel) !== null && _b !== void 0 ? _b : 'Response recorded', onClick: (e) => handleClick(e, 'positive', positive.onClick), className: positive.className, isDisabled: positive.isDisabled, tooltipContent: (_c = positive.tooltipContent) !== null && _c !== void 0 ? _c : 'Good response', clickedTooltipContent: (_d = positive.clickedTooltipContent) !== null && _d !== void 0 ? _d : 'Response recorded', tooltipProps: positive.tooltipProps, icon: _jsx(OutlinedThumbsUpIcon, {}), isClicked: activeButton === 'positive', ref: positive.ref, "aria-expanded": positive['aria-expanded'], "aria-controls": positive['aria-controls'] }))), negative && (_jsx(ResponseActionButton, Object.assign({}, negative, { ariaLabel: (_e = negative.ariaLabel) !== null && _e !== void 0 ? _e : 'Bad response', clickedAriaLabel: (_f = negative.ariaLabel) !== null && _f !== void 0 ? _f : 'Response recorded', onClick: (e) => handleClick(e, 'negative', negative.onClick), className: negative.className, isDisabled: negative.isDisabled, tooltipContent: (_g = negative.tooltipContent) !== null && _g !== void 0 ? _g : 'Bad response', clickedTooltipContent: (_h = negative.clickedTooltipContent) !== null && _h !== void 0 ? _h : 'Response recorded', tooltipProps: negative.tooltipProps, icon: _jsx(OutlinedThumbsDownIcon, {}), isClicked: activeButton === 'negative', ref: negative.ref, "aria-expanded": negative['aria-expanded'], "aria-controls": negative['aria-controls'] }))), copy && (_jsx(ResponseActionButton, Object.assign({}, copy, { ariaLabel: (_j = copy.ariaLabel) !== null && _j !== void 0 ? _j : 'Copy', clickedAriaLabel: (_k = copy.ariaLabel) !== null && _k !== void 0 ? _k : 'Copied', onClick: (e) => handleClick(e, 'copy', copy.onClick), className: copy.className, isDisabled: copy.isDisabled, tooltipContent: (_l = copy.tooltipContent) !== null && _l !== void 0 ? _l : 'Copy', clickedTooltipContent: (_m = copy.clickedTooltipContent) !== null && _m !== void 0 ? _m : 'Copied', tooltipProps: copy.tooltipProps, icon: _jsx(OutlinedCopyIcon, {}), isClicked: activeButton === 'copy', ref: copy.ref, "aria-expanded": copy['aria-expanded'], "aria-controls": copy['aria-controls'] }))), share && (_jsx(ResponseActionButton, Object.assign({}, share, { ariaLabel: (_o = share.ariaLabel) !== null && _o !== void 0 ? _o : 'Share', clickedAriaLabel: (_p = share.ariaLabel) !== null && _p !== void 0 ? _p : 'Shared', onClick: (e) => handleClick(e, 'share', share.onClick), className: share.className, isDisabled: share.isDisabled, tooltipContent: (_q = share.tooltipContent) !== null && _q !== void 0 ? _q : 'Share', clickedTooltipContent: (_r = share.clickedTooltipContent) !== null && _r !== void 0 ? _r : 'Shared', tooltipProps: share.tooltipProps, icon: _jsx(ExternalLinkAltIcon, {}), isClicked: activeButton === 'share', ref: share.ref, "aria-expanded": share['aria-expanded'], "aria-controls": share['aria-controls'] }))), download && (_jsx(ResponseActionButton, Object.assign({}, download, { ariaLabel: (_s = download.ariaLabel) !== null && _s !== void 0 ? _s : 'Download', clickedAriaLabel: (_t = download.ariaLabel) !== null && _t !== void 0 ? _t : 'Downloaded', onClick: (e) => handleClick(e, 'download', download.onClick), className: download.className, isDisabled: download.isDisabled, tooltipContent: (_u = download.tooltipContent) !== null && _u !== void 0 ? _u : 'Download', clickedTooltipContent: (_v = download.clickedTooltipContent) !== null && _v !== void 0 ? _v : 'Downloaded', tooltipProps: download.tooltipProps, icon: _jsx(DownloadIcon, {}), isClicked: activeButton === 'download', ref: download.ref, "aria-expanded": download['aria-expanded'], "aria-controls": download['aria-controls'] }))), listen && (_jsx(ResponseActionButton, Object.assign({}, listen, { ariaLabel: (_w = listen.ariaLabel) !== null && _w !== void 0 ? _w : 'Listen', clickedAriaLabel: (_x = listen.ariaLabel) !== null && _x !== void 0 ? _x : 'Listening', onClick: (e) => handleClick(e, 'listen', listen.onClick), className: listen.className, isDisabled: listen.isDisabled, tooltipContent: (_y = listen.tooltipContent) !== null && _y !== void 0 ? _y : 'Listen', clickedTooltipContent: (_z = listen.clickedTooltipContent) !== null && _z !== void 0 ? _z : 'Listening', tooltipProps: listen.tooltipProps, icon: _jsx(VolumeUpIcon, {}), isClicked: activeButton === 'listen', ref: listen.ref, "aria-expanded": listen['aria-expanded'], "aria-controls": listen['aria-controls'] }))), Object.keys(additionalActions).map((action) => {
62
+ return (_jsxs("div", { ref: responseActions, className: "pf-chatbot__response-actions", children: [positive && (_jsx(ResponseActionButton, Object.assign({}, positive, { ariaLabel: (_a = positive.ariaLabel) !== null && _a !== void 0 ? _a : 'Good response', clickedAriaLabel: (_b = positive.ariaLabel) !== null && _b !== void 0 ? _b : 'Response recorded', onClick: (e) => handleClick(e, 'positive', positive.onClick), className: positive.className, isDisabled: positive.isDisabled, tooltipContent: (_c = positive.tooltipContent) !== null && _c !== void 0 ? _c : 'Good response', clickedTooltipContent: (_d = positive.clickedTooltipContent) !== null && _d !== void 0 ? _d : 'Response recorded', tooltipProps: positive.tooltipProps, icon: _jsx(OutlinedThumbsUpIcon, {}), isClicked: activeButton === 'positive', ref: positive.ref, "aria-expanded": positive['aria-expanded'], "aria-controls": positive['aria-controls'] }))), negative && (_jsx(ResponseActionButton, Object.assign({}, negative, { ariaLabel: (_e = negative.ariaLabel) !== null && _e !== void 0 ? _e : 'Bad response', clickedAriaLabel: (_f = negative.ariaLabel) !== null && _f !== void 0 ? _f : 'Response recorded', onClick: (e) => handleClick(e, 'negative', negative.onClick), className: negative.className, isDisabled: negative.isDisabled, tooltipContent: (_g = negative.tooltipContent) !== null && _g !== void 0 ? _g : 'Bad response', clickedTooltipContent: (_h = negative.clickedTooltipContent) !== null && _h !== void 0 ? _h : 'Response recorded', tooltipProps: negative.tooltipProps, icon: _jsx(OutlinedThumbsDownIcon, {}), isClicked: activeButton === 'negative', ref: negative.ref, "aria-expanded": negative['aria-expanded'], "aria-controls": negative['aria-controls'] }))), copy && (_jsx(ResponseActionButton, Object.assign({}, copy, { ariaLabel: (_j = copy.ariaLabel) !== null && _j !== void 0 ? _j : 'Copy', clickedAriaLabel: (_k = copy.ariaLabel) !== null && _k !== void 0 ? _k : 'Copied', onClick: (e) => handleClick(e, 'copy', copy.onClick), className: copy.className, isDisabled: copy.isDisabled, tooltipContent: (_l = copy.tooltipContent) !== null && _l !== void 0 ? _l : 'Copy', clickedTooltipContent: (_m = copy.clickedTooltipContent) !== null && _m !== void 0 ? _m : 'Copied', tooltipProps: copy.tooltipProps, icon: _jsx(OutlinedCopyIcon, {}), isClicked: activeButton === 'copy', ref: copy.ref, "aria-expanded": copy['aria-expanded'], "aria-controls": copy['aria-controls'] }))), edit && (_jsx(ResponseActionButton, Object.assign({}, edit, { ariaLabel: (_o = edit.ariaLabel) !== null && _o !== void 0 ? _o : 'Edit', clickedAriaLabel: (_p = edit.ariaLabel) !== null && _p !== void 0 ? _p : 'Editing', onClick: (e) => handleClick(e, 'edit', edit.onClick), className: edit.className, isDisabled: edit.isDisabled, tooltipContent: (_q = edit.tooltipContent) !== null && _q !== void 0 ? _q : 'Edit ', clickedTooltipContent: (_r = edit.clickedTooltipContent) !== null && _r !== void 0 ? _r : 'Editing', tooltipProps: edit.tooltipProps, icon: _jsx(PencilAltIcon, {}), isClicked: activeButton === 'edit', ref: edit.ref, "aria-expanded": edit['aria-expanded'], "aria-controls": edit['aria-controls'] }))), share && (_jsx(ResponseActionButton, Object.assign({}, share, { ariaLabel: (_s = share.ariaLabel) !== null && _s !== void 0 ? _s : 'Share', clickedAriaLabel: (_t = share.ariaLabel) !== null && _t !== void 0 ? _t : 'Shared', onClick: (e) => handleClick(e, 'share', share.onClick), className: share.className, isDisabled: share.isDisabled, tooltipContent: (_u = share.tooltipContent) !== null && _u !== void 0 ? _u : 'Share', clickedTooltipContent: (_v = share.clickedTooltipContent) !== null && _v !== void 0 ? _v : 'Shared', tooltipProps: share.tooltipProps, icon: _jsx(ExternalLinkAltIcon, {}), isClicked: activeButton === 'share', ref: share.ref, "aria-expanded": share['aria-expanded'], "aria-controls": share['aria-controls'] }))), download && (_jsx(ResponseActionButton, Object.assign({}, download, { ariaLabel: (_w = download.ariaLabel) !== null && _w !== void 0 ? _w : 'Download', clickedAriaLabel: (_x = download.ariaLabel) !== null && _x !== void 0 ? _x : 'Downloaded', onClick: (e) => handleClick(e, 'download', download.onClick), className: download.className, isDisabled: download.isDisabled, tooltipContent: (_y = download.tooltipContent) !== null && _y !== void 0 ? _y : 'Download', clickedTooltipContent: (_z = download.clickedTooltipContent) !== null && _z !== void 0 ? _z : 'Downloaded', tooltipProps: download.tooltipProps, icon: _jsx(DownloadIcon, {}), isClicked: activeButton === 'download', ref: download.ref, "aria-expanded": download['aria-expanded'], "aria-controls": download['aria-controls'] }))), listen && (_jsx(ResponseActionButton, Object.assign({}, listen, { ariaLabel: (_0 = listen.ariaLabel) !== null && _0 !== void 0 ? _0 : 'Listen', clickedAriaLabel: (_1 = listen.ariaLabel) !== null && _1 !== void 0 ? _1 : 'Listening', onClick: (e) => handleClick(e, 'listen', listen.onClick), className: listen.className, isDisabled: listen.isDisabled, tooltipContent: (_2 = listen.tooltipContent) !== null && _2 !== void 0 ? _2 : 'Listen', clickedTooltipContent: (_3 = listen.clickedTooltipContent) !== null && _3 !== void 0 ? _3 : 'Listening', tooltipProps: listen.tooltipProps, icon: _jsx(VolumeUpIcon, {}), isClicked: activeButton === 'listen', ref: listen.ref, "aria-expanded": listen['aria-expanded'], "aria-controls": listen['aria-controls'] }))), Object.keys(additionalActions).map((action) => {
63
63
  var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
64
64
  return (_createElement(ResponseActionButton, Object.assign({}, additionalActions[action], { key: action, ariaLabel: (_a = additionalActions[action]) === null || _a === void 0 ? void 0 : _a.ariaLabel, clickedAriaLabel: (_b = additionalActions[action]) === null || _b === void 0 ? void 0 : _b.clickedAriaLabel, onClick: (e) => { var _a; return handleClick(e, action, (_a = additionalActions[action]) === null || _a === void 0 ? void 0 : _a.onClick); }, className: (_c = additionalActions[action]) === null || _c === void 0 ? void 0 : _c.className, isDisabled: (_d = additionalActions[action]) === null || _d === void 0 ? void 0 : _d.isDisabled, tooltipContent: (_e = additionalActions[action]) === null || _e === void 0 ? void 0 : _e.tooltipContent, tooltipProps: (_f = additionalActions[action]) === null || _f === void 0 ? void 0 : _f.tooltipProps, clickedTooltipContent: (_g = additionalActions[action]) === null || _g === void 0 ? void 0 : _g.clickedTooltipContent, icon: (_h = additionalActions[action]) === null || _h === void 0 ? void 0 : _h.icon, isClicked: activeButton === action, ref: (_j = additionalActions[action]) === null || _j === void 0 ? void 0 : _j.ref, "aria-expanded": (_k = additionalActions[action]) === null || _k === void 0 ? void 0 : _k['aria-expanded'], "aria-controls": (_l = additionalActions[action]) === null || _l === void 0 ? void 0 : _l['aria-controls'] })));
65
65
  })] }));
@@ -18,6 +18,7 @@ const ALL_ACTIONS = [
18
18
  { type: 'positive', label: 'Good response', clickedLabel: 'Response recorded' },
19
19
  { type: 'negative', label: 'Bad response', clickedLabel: 'Response recorded' },
20
20
  { type: 'copy', label: 'Copy', clickedLabel: 'Copied' },
21
+ { type: 'edit', label: 'Edit', clickedLabel: 'Editing' },
21
22
  { type: 'share', label: 'Share', clickedLabel: 'Shared' },
22
23
  { type: 'listen', label: 'Listen', clickedLabel: 'Listening' }
23
24
  ];
@@ -51,6 +52,7 @@ const ALL_ACTIONS_DATA_TEST = [
51
52
  { type: 'positive', label: 'Good response', dataTestId: 'positive' },
52
53
  { type: 'negative', label: 'Bad response', dataTestId: 'negative' },
53
54
  { type: 'copy', label: 'Copy', dataTestId: 'copy' },
55
+ { type: 'edit', label: 'Edit', dataTestId: 'edit' },
54
56
  { type: 'share', label: 'Share', dataTestId: 'share' },
55
57
  { type: 'download', label: 'Download', dataTestId: 'download' },
56
58
  { type: 'listen', label: 'Listen', dataTestId: 'listen' }
@@ -64,6 +66,7 @@ describe('ResponseActions', () => {
64
66
  positive: { onClick: jest.fn() },
65
67
  negative: { onClick: jest.fn() },
66
68
  copy: { onClick: jest.fn() },
69
+ edit: { onClick: jest.fn() },
67
70
  share: { onClick: jest.fn() },
68
71
  download: { onClick: jest.fn() },
69
72
  listen: { onClick: jest.fn() }
@@ -71,10 +74,11 @@ describe('ResponseActions', () => {
71
74
  const goodBtn = screen.getByRole('button', { name: 'Good response' });
72
75
  const badBtn = screen.getByRole('button', { name: 'Bad response' });
73
76
  const copyBtn = screen.getByRole('button', { name: 'Copy' });
77
+ const editBtn = screen.getByRole('button', { name: 'Edit' });
74
78
  const shareBtn = screen.getByRole('button', { name: 'Share' });
75
79
  const downloadBtn = screen.getByRole('button', { name: 'Download' });
76
80
  const listenBtn = screen.getByRole('button', { name: 'Listen' });
77
- const buttons = [goodBtn, badBtn, copyBtn, shareBtn, downloadBtn, listenBtn];
81
+ const buttons = [goodBtn, badBtn, copyBtn, editBtn, shareBtn, downloadBtn, listenBtn];
78
82
  buttons.forEach((button) => {
79
83
  expect(button).toBeTruthy();
80
84
  });
@@ -206,6 +210,7 @@ describe('ResponseActions', () => {
206
210
  { type: 'positive', ariaLabel: 'Thumbs up' },
207
211
  { type: 'negative', ariaLabel: 'Thumbs down' },
208
212
  { type: 'copy', ariaLabel: 'Copy the message' },
213
+ { type: 'edit', ariaLabel: 'Edit this message' },
209
214
  { type: 'share', ariaLabel: 'Share it with friends' },
210
215
  { type: 'download', ariaLabel: 'Download your cool message' },
211
216
  { type: 'listen', ariaLabel: 'Listen up' }
@@ -40,6 +40,8 @@ export { default as MessageBar } from './MessageBar';
40
40
  export * from './MessageBar';
41
41
  export { default as MessageBox } from './MessageBox';
42
42
  export * from './MessageBox';
43
+ export { default as MessageDivider } from './MessageDivider';
44
+ export * from './MessageDivider';
43
45
  export { default as PreviewAttachment } from './PreviewAttachment';
44
46
  export * from './PreviewAttachment';
45
47
  export { default as ResponseActions } from './ResponseActions';
package/dist/esm/index.js CHANGED
@@ -41,6 +41,8 @@ export { default as MessageBar } from './MessageBar';
41
41
  export * from './MessageBar';
42
42
  export { default as MessageBox } from './MessageBox';
43
43
  export * from './MessageBox';
44
+ export { default as MessageDivider } from './MessageDivider';
45
+ export * from './MessageDivider';
44
46
  export { default as PreviewAttachment } from './PreviewAttachment';
45
47
  export * from './PreviewAttachment';
46
48
  export { default as ResponseActions } from './ResponseActions';
@@ -1 +1 @@
1
- {"root":["../src/index.ts","../src/AttachMenu/AttachMenu.tsx","../src/AttachMenu/index.ts","../src/AttachmentEdit/AttachmentEdit.test.tsx","../src/AttachmentEdit/AttachmentEdit.tsx","../src/AttachmentEdit/index.ts","../src/Chatbot/Chatbot.test.tsx","../src/Chatbot/Chatbot.tsx","../src/Chatbot/index.ts","../src/ChatbotAlert/ChatbotAlert.test.tsx","../src/ChatbotAlert/ChatbotAlert.tsx","../src/ChatbotAlert/index.ts","../src/ChatbotContent/ChatbotContent.test.tsx","../src/ChatbotContent/ChatbotContent.tsx","../src/ChatbotContent/index.ts","../src/ChatbotConversationHistoryNav/ChatbotConversationHistoryDropdown.test.tsx","../src/ChatbotConversationHistoryNav/ChatbotConversationHistoryDropdown.tsx","../src/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.test.tsx","../src/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.tsx","../src/ChatbotConversationHistoryNav/EmptyState.tsx","../src/ChatbotConversationHistoryNav/LoadingState.tsx","../src/ChatbotConversationHistoryNav/index.ts","../src/ChatbotFooter/ChatbotFooter.test.tsx","../src/ChatbotFooter/ChatbotFooter.tsx","../src/ChatbotFooter/ChatbotFooternote.test.tsx","../src/ChatbotFooter/ChatbotFootnote.tsx","../src/ChatbotFooter/index.ts","../src/ChatbotHeader/ChatbotHeader.test.tsx","../src/ChatbotHeader/ChatbotHeader.tsx","../src/ChatbotHeader/ChatbotHeaderActions.test.tsx","../src/ChatbotHeader/ChatbotHeaderActions.tsx","../src/ChatbotHeader/ChatbotHeaderCloseButton.test.tsx","../src/ChatbotHeader/ChatbotHeaderCloseButton.tsx","../src/ChatbotHeader/ChatbotHeaderMain.test.tsx","../src/ChatbotHeader/ChatbotHeaderMain.tsx","../src/ChatbotHeader/ChatbotHeaderMenu.test.tsx","../src/ChatbotHeader/ChatbotHeaderMenu.tsx","../src/ChatbotHeader/ChatbotHeaderOptionsDropdown.test.tsx","../src/ChatbotHeader/ChatbotHeaderOptionsDropdown.tsx","../src/ChatbotHeader/ChatbotHeaderSelectorDropdown.test.tsx","../src/ChatbotHeader/ChatbotHeaderSelectorDropdown.tsx","../src/ChatbotHeader/ChatbotHeaderTitle.test.tsx","../src/ChatbotHeader/ChatbotHeaderTitle.tsx","../src/ChatbotHeader/index.ts","../src/ChatbotModal/ChatbotModal.test.tsx","../src/ChatbotModal/ChatbotModal.tsx","../src/ChatbotModal/index.ts","../src/ChatbotPopover/ChatbotPopover.tsx","../src/ChatbotPopover/index.ts","../src/ChatbotToggle/ChatbotToggle.test.tsx","../src/ChatbotToggle/ChatbotToggle.tsx","../src/ChatbotToggle/index.ts","../src/ChatbotWelcomePrompt/ChatbotWelcomePrompt.test.tsx","../src/ChatbotWelcomePrompt/ChatbotWelcomePrompt.tsx","../src/ChatbotWelcomePrompt/index.ts","../src/CodeModal/CodeModal.test.tsx","../src/CodeModal/CodeModal.tsx","../src/CodeModal/index.ts","../src/Compare/Compare.test.tsx","../src/Compare/Compare.tsx","../src/Compare/index.ts","../src/FileDetails/FileDetails.test.tsx","../src/FileDetails/FileDetails.tsx","../src/FileDetails/index.ts","../src/FileDetailsLabel/FileDetailsLabel.test.tsx","../src/FileDetailsLabel/FileDetailsLabel.tsx","../src/FileDetailsLabel/index.ts","../src/FileDropZone/FileDropZone.test.tsx","../src/FileDropZone/FileDropZone.tsx","../src/FileDropZone/index.ts","../src/LoadingMessage/LoadingMessage.test.tsx","../src/LoadingMessage/LoadingMessage.tsx","../src/LoadingMessage/index.ts","../src/Message/Message.test.tsx","../src/Message/Message.tsx","../src/Message/MessageInput.tsx","../src/Message/MessageLoading.tsx","../src/Message/index.ts","../src/Message/CodeBlockMessage/CodeBlockMessage.tsx","../src/Message/ErrorMessage/ErrorMessage.tsx","../src/Message/ImageMessage/ImageMessage.tsx","../src/Message/LinkMessage/LinkMessage.tsx","../src/Message/ListMessage/ListItemMessage.tsx","../src/Message/ListMessage/OrderedListMessage.tsx","../src/Message/ListMessage/UnorderedListMessage.tsx","../src/Message/Plugins/index.ts","../src/Message/Plugins/rehypeCodeBlockToggle.ts","../src/Message/Plugins/rehypeMoveImagesOutOfParagraphs.ts","../src/Message/QuickResponse/QuickResponse.tsx","../src/Message/QuickStarts/FallbackImg.tsx","../src/Message/QuickStarts/QuickStartTile.tsx","../src/Message/QuickStarts/QuickStartTileDescription.test.tsx","../src/Message/QuickStarts/QuickStartTileDescription.tsx","../src/Message/QuickStarts/QuickStartTileHeader.tsx","../src/Message/QuickStarts/monitor-sampleapp-quickstart-with-image.ts","../src/Message/QuickStarts/monitor-sampleapp-quickstart.ts","../src/Message/QuickStarts/types.ts","../src/Message/TableMessage/TableMessage.tsx","../src/Message/TableMessage/TbodyMessage.tsx","../src/Message/TableMessage/TdMessage.tsx","../src/Message/TableMessage/ThMessage.tsx","../src/Message/TableMessage/TheadMessage.tsx","../src/Message/TableMessage/TrMessage.tsx","../src/Message/TextMessage/TextMessage.tsx","../src/Message/UserFeedback/CloseButton.tsx","../src/Message/UserFeedback/UserFeedback.test.tsx","../src/Message/UserFeedback/UserFeedback.tsx","../src/Message/UserFeedback/UserFeedbackComplete.test.tsx","../src/Message/UserFeedback/UserFeedbackComplete.tsx","../src/MessageBar/AttachButton.test.tsx","../src/MessageBar/AttachButton.tsx","../src/MessageBar/MessageBar.test.tsx","../src/MessageBar/MessageBar.tsx","../src/MessageBar/MicrophoneButton.tsx","../src/MessageBar/SendButton.test.tsx","../src/MessageBar/SendButton.tsx","../src/MessageBar/StopButton.test.tsx","../src/MessageBar/StopButton.tsx","../src/MessageBar/index.ts","../src/MessageBox/JumpButton.test.tsx","../src/MessageBox/JumpButton.tsx","../src/MessageBox/MessageBox.test.tsx","../src/MessageBox/MessageBox.tsx","../src/MessageBox/index.ts","../src/PreviewAttachment/PreviewAttachment.test.tsx","../src/PreviewAttachment/PreviewAttachment.tsx","../src/PreviewAttachment/index.ts","../src/ResponseActions/ResponseActionButton.test.tsx","../src/ResponseActions/ResponseActionButton.tsx","../src/ResponseActions/ResponseActions.test.tsx","../src/ResponseActions/ResponseActions.tsx","../src/ResponseActions/index.ts","../src/Settings/SettingsForm.test.tsx","../src/Settings/SettingsForm.tsx","../src/Settings/index.ts","../src/SourceDetailsMenuItem/SourceDetailsMenuItem.tsx","../src/SourceDetailsMenuItem/index.ts","../src/SourcesCard/SourcesCard.test.tsx","../src/SourcesCard/SourcesCard.tsx","../src/SourcesCard/index.ts","../src/TermsOfUse/TermsOfUse.test.tsx","../src/TermsOfUse/TermsOfUse.tsx","../src/TermsOfUse/index.ts","../src/__mocks__/rehype-external-links.ts","../src/__mocks__/rehype-sanitize.ts","../src/__mocks__/rehype-unwrap-images.tsx","../src/tracking/console_tracking_provider.ts","../src/tracking/index.ts","../src/tracking/posthog_tracking_provider.ts","../src/tracking/segment_tracking_provider.ts","../src/tracking/trackingProviderProxy.ts","../src/tracking/tracking_api.ts","../src/tracking/tracking_registry.ts","../src/tracking/tracking_spi.ts","../src/tracking/umami_tracking_provider.ts"],"version":"5.6.3"}
1
+ {"root":["../src/index.ts","../src/AttachMenu/AttachMenu.tsx","../src/AttachMenu/index.ts","../src/AttachmentEdit/AttachmentEdit.test.tsx","../src/AttachmentEdit/AttachmentEdit.tsx","../src/AttachmentEdit/index.ts","../src/Chatbot/Chatbot.test.tsx","../src/Chatbot/Chatbot.tsx","../src/Chatbot/index.ts","../src/ChatbotAlert/ChatbotAlert.test.tsx","../src/ChatbotAlert/ChatbotAlert.tsx","../src/ChatbotAlert/index.ts","../src/ChatbotContent/ChatbotContent.test.tsx","../src/ChatbotContent/ChatbotContent.tsx","../src/ChatbotContent/index.ts","../src/ChatbotConversationHistoryNav/ChatbotConversationHistoryDropdown.test.tsx","../src/ChatbotConversationHistoryNav/ChatbotConversationHistoryDropdown.tsx","../src/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.test.tsx","../src/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.tsx","../src/ChatbotConversationHistoryNav/EmptyState.tsx","../src/ChatbotConversationHistoryNav/LoadingState.tsx","../src/ChatbotConversationHistoryNav/index.ts","../src/ChatbotFooter/ChatbotFooter.test.tsx","../src/ChatbotFooter/ChatbotFooter.tsx","../src/ChatbotFooter/ChatbotFooternote.test.tsx","../src/ChatbotFooter/ChatbotFootnote.tsx","../src/ChatbotFooter/index.ts","../src/ChatbotHeader/ChatbotHeader.test.tsx","../src/ChatbotHeader/ChatbotHeader.tsx","../src/ChatbotHeader/ChatbotHeaderActions.test.tsx","../src/ChatbotHeader/ChatbotHeaderActions.tsx","../src/ChatbotHeader/ChatbotHeaderCloseButton.test.tsx","../src/ChatbotHeader/ChatbotHeaderCloseButton.tsx","../src/ChatbotHeader/ChatbotHeaderMain.test.tsx","../src/ChatbotHeader/ChatbotHeaderMain.tsx","../src/ChatbotHeader/ChatbotHeaderMenu.test.tsx","../src/ChatbotHeader/ChatbotHeaderMenu.tsx","../src/ChatbotHeader/ChatbotHeaderNewChatButton.test.tsx","../src/ChatbotHeader/ChatbotHeaderNewChatButton.tsx","../src/ChatbotHeader/ChatbotHeaderOptionsDropdown.test.tsx","../src/ChatbotHeader/ChatbotHeaderOptionsDropdown.tsx","../src/ChatbotHeader/ChatbotHeaderSelectorDropdown.test.tsx","../src/ChatbotHeader/ChatbotHeaderSelectorDropdown.tsx","../src/ChatbotHeader/ChatbotHeaderTitle.test.tsx","../src/ChatbotHeader/ChatbotHeaderTitle.tsx","../src/ChatbotHeader/index.ts","../src/ChatbotModal/ChatbotModal.test.tsx","../src/ChatbotModal/ChatbotModal.tsx","../src/ChatbotModal/index.ts","../src/ChatbotPopover/ChatbotPopover.tsx","../src/ChatbotPopover/index.ts","../src/ChatbotToggle/ChatbotToggle.test.tsx","../src/ChatbotToggle/ChatbotToggle.tsx","../src/ChatbotToggle/index.ts","../src/ChatbotWelcomePrompt/ChatbotWelcomePrompt.test.tsx","../src/ChatbotWelcomePrompt/ChatbotWelcomePrompt.tsx","../src/ChatbotWelcomePrompt/index.ts","../src/CodeModal/CodeModal.test.tsx","../src/CodeModal/CodeModal.tsx","../src/CodeModal/index.ts","../src/Compare/Compare.test.tsx","../src/Compare/Compare.tsx","../src/Compare/index.ts","../src/FileDetails/FileDetails.test.tsx","../src/FileDetails/FileDetails.tsx","../src/FileDetails/index.ts","../src/FileDetailsLabel/FileDetailsLabel.test.tsx","../src/FileDetailsLabel/FileDetailsLabel.tsx","../src/FileDetailsLabel/index.ts","../src/FileDropZone/FileDropZone.test.tsx","../src/FileDropZone/FileDropZone.tsx","../src/FileDropZone/index.ts","../src/LoadingMessage/LoadingMessage.test.tsx","../src/LoadingMessage/LoadingMessage.tsx","../src/LoadingMessage/index.ts","../src/Message/Message.test.tsx","../src/Message/Message.tsx","../src/Message/MessageInput.tsx","../src/Message/MessageLoading.tsx","../src/Message/index.ts","../src/Message/CodeBlockMessage/CodeBlockMessage.tsx","../src/Message/ErrorMessage/ErrorMessage.tsx","../src/Message/ImageMessage/ImageMessage.tsx","../src/Message/LinkMessage/LinkMessage.tsx","../src/Message/ListMessage/ListItemMessage.tsx","../src/Message/ListMessage/OrderedListMessage.tsx","../src/Message/ListMessage/UnorderedListMessage.tsx","../src/Message/Plugins/index.ts","../src/Message/Plugins/rehypeCodeBlockToggle.ts","../src/Message/Plugins/rehypeMoveImagesOutOfParagraphs.ts","../src/Message/QuickResponse/QuickResponse.tsx","../src/Message/QuickStarts/FallbackImg.tsx","../src/Message/QuickStarts/QuickStartTile.tsx","../src/Message/QuickStarts/QuickStartTileDescription.test.tsx","../src/Message/QuickStarts/QuickStartTileDescription.tsx","../src/Message/QuickStarts/QuickStartTileHeader.tsx","../src/Message/QuickStarts/monitor-sampleapp-quickstart-with-image.ts","../src/Message/QuickStarts/monitor-sampleapp-quickstart.ts","../src/Message/QuickStarts/types.ts","../src/Message/TableMessage/TableMessage.tsx","../src/Message/TableMessage/TbodyMessage.tsx","../src/Message/TableMessage/TdMessage.tsx","../src/Message/TableMessage/ThMessage.tsx","../src/Message/TableMessage/TheadMessage.tsx","../src/Message/TableMessage/TrMessage.tsx","../src/Message/TextMessage/TextMessage.tsx","../src/Message/UserFeedback/CloseButton.tsx","../src/Message/UserFeedback/UserFeedback.test.tsx","../src/Message/UserFeedback/UserFeedback.tsx","../src/Message/UserFeedback/UserFeedbackComplete.test.tsx","../src/Message/UserFeedback/UserFeedbackComplete.tsx","../src/MessageBar/AttachButton.test.tsx","../src/MessageBar/AttachButton.tsx","../src/MessageBar/MessageBar.test.tsx","../src/MessageBar/MessageBar.tsx","../src/MessageBar/MicrophoneButton.tsx","../src/MessageBar/SendButton.test.tsx","../src/MessageBar/SendButton.tsx","../src/MessageBar/StopButton.test.tsx","../src/MessageBar/StopButton.tsx","../src/MessageBar/index.ts","../src/MessageBox/JumpButton.test.tsx","../src/MessageBox/JumpButton.tsx","../src/MessageBox/MessageBox.test.tsx","../src/MessageBox/MessageBox.tsx","../src/MessageBox/index.ts","../src/MessageDivider/MessageDivider.test.tsx","../src/MessageDivider/MessageDivider.tsx","../src/MessageDivider/index.ts","../src/PreviewAttachment/PreviewAttachment.test.tsx","../src/PreviewAttachment/PreviewAttachment.tsx","../src/PreviewAttachment/index.ts","../src/ResponseActions/ResponseActionButton.test.tsx","../src/ResponseActions/ResponseActionButton.tsx","../src/ResponseActions/ResponseActions.test.tsx","../src/ResponseActions/ResponseActions.tsx","../src/ResponseActions/index.ts","../src/Settings/SettingsForm.test.tsx","../src/Settings/SettingsForm.tsx","../src/Settings/index.ts","../src/SourceDetailsMenuItem/SourceDetailsMenuItem.tsx","../src/SourceDetailsMenuItem/index.ts","../src/SourcesCard/SourcesCard.test.tsx","../src/SourcesCard/SourcesCard.tsx","../src/SourcesCard/index.ts","../src/TermsOfUse/TermsOfUse.test.tsx","../src/TermsOfUse/TermsOfUse.tsx","../src/TermsOfUse/index.ts","../src/__mocks__/rehype-external-links.ts","../src/__mocks__/rehype-sanitize.ts","../src/__mocks__/rehype-unwrap-images.tsx","../src/tracking/console_tracking_provider.ts","../src/tracking/index.ts","../src/tracking/posthog_tracking_provider.ts","../src/tracking/segment_tracking_provider.ts","../src/tracking/trackingProviderProxy.ts","../src/tracking/tracking_api.ts","../src/tracking/tracking_registry.ts","../src/tracking/tracking_spi.ts","../src/tracking/umami_tracking_provider.ts"],"version":"5.6.3"}
package/package.json CHANGED
@@ -1,16 +1,18 @@
1
1
  {
2
2
  "name": "@patternfly/chatbot",
3
- "version": "6.3.2",
3
+ "version": "6.4.0-prerelease.10",
4
4
  "description": "This library provides React components based on PatternFly 6 that can be used to build chatbots.",
5
5
  "main": "dist/cjs/index.js",
6
6
  "module": "dist/esm/index.js",
7
7
  "scripts": {
8
- "build": "sass src/main.scss dist/css/main.css && npm run build:index && npm run build:js && npm run build:esm && npm run build:fed:packages",
8
+ "build": "npm run build:css && npm run build:index && npm run build:js && npm run build:esm && npm run build:fed:packages",
9
9
  "build:watch": "npm run build:js && npm run build:esm -- --watch && npm run build:fed:packages -- --watch",
10
10
  "build:esm": "tsc --build --verbose ./tsconfig.json",
11
11
  "build:fed:packages": "node generate-fed-package-json.js",
12
12
  "build:js": "tsc -p tsconfig.cjs.json",
13
13
  "build:index": "node generate-index.js",
14
+ "build:css": "sass src/main.scss dist/css/main.css",
15
+ "build:css:watch": "sass src/main.scss dist/css/main.css --watch",
14
16
  "clean": "rimraf dist",
15
17
  "docs:develop": "pf-docs-framework start",
16
18
  "docs:build": "pf-docs-framework build all --output public",
@@ -52,7 +54,7 @@
52
54
  "react-dom": "^17 || ^18 || ^19"
53
55
  },
54
56
  "devDependencies": {
55
- "@patternfly/documentation-framework": "6.8.2",
57
+ "@patternfly/documentation-framework": "6.16.0",
56
58
  "@patternfly/patternfly": "^6.1.0",
57
59
  "@patternfly/patternfly-a11y": "^5.0.0",
58
60
  "@types/dom-speech-recognition": "^0.0.4",
@@ -71,7 +73,10 @@
71
73
  "victory-create-container": "^37.1.1",
72
74
  "victory-cursor-container": "^37.1.1",
73
75
  "victory-tooltip": "^37.1.1",
74
- "victory-bar": "^37.1.1"
76
+ "victory-bar": "^37.1.1",
77
+ "file-saver": "^2.0.5",
78
+ "unified": "^11.0.5",
79
+ "estree-util-is-identifier-name": "^3.0.0"
75
80
  },
76
81
  "overrides": {
77
82
  "puppeteer": "^23.6.1",
@@ -0,0 +1,24 @@
1
+ import { FunctionComponent } from 'react';
2
+ import Message from '@patternfly/chatbot/dist/dynamic/Message';
3
+ import patternflyAvatar from './patternfly_avatar.jpg';
4
+ import MessageDivider from '@patternfly/chatbot/dist/dynamic/MessageDivider';
5
+
6
+ export const MessageWithDividersExample: FunctionComponent = () => (
7
+ <>
8
+ <Message
9
+ name="Bot"
10
+ role="bot"
11
+ avatar={patternflyAvatar}
12
+ content={`This is a text-based message from a bot named "Bot."`}
13
+ />
14
+ <MessageDivider variant="inset" content="1 hour ago" />
15
+ <Message
16
+ name="Bot"
17
+ role="bot"
18
+ avatar={patternflyAvatar}
19
+ content={`This is a text-based message from "Bot," with an updated timestamp.`}
20
+ timestamp="1 hour ago"
21
+ />
22
+ <MessageDivider variant="fullWidth" content="Agent joined the chat" />
23
+ </>
24
+ );
@@ -31,6 +31,7 @@ sortValue: 3
31
31
  ---
32
32
 
33
33
  import Message from '@patternfly/chatbot/dist/dynamic/Message';
34
+ import MessageDivider from '@patternfly/chatbot/dist/dynamic/MessageDivider';
34
35
  import { rehypeCodeBlockToggle } from '@patternfly/chatbot/dist/esm/Message/Plugins/rehypeCodeBlockToggle';
35
36
  import SourcesCard from '@patternfly/chatbot/dist/dynamic/SourcesCard';
36
37
  import { RobotIcon } from '@patternfly/react-icons/dist/esm/icons/robot-icon';
@@ -48,7 +49,7 @@ import { explorePipelinesQuickStart } from './explore-pipeline-quickstart.ts';
48
49
  import { monitorSampleAppQuickStart } from '@patternfly/chatbot/src/Message/QuickStarts/monitor-sampleapp-quickstart.ts';
49
50
  import userAvatar from './user_avatar.svg';
50
51
  import squareImg from './PF-social-color-square.svg';
51
- import { CSSProperties, useState, Fragment, FunctionComponent, MouseEvent as ReactMouseEvent, KeyboardEvent as ReactKeyboardEvent, Ref, isValidElement, cloneElement, Children, ReactNode } from 'react';
52
+ import { CSSProperties, useState, Fragment, FunctionComponent, MouseEvent as ReactMouseEvent, KeyboardEvent as ReactKeyboardEvent, Ref, isValidElement, cloneElement, Children, ReactNode, useRef, useEffect } from 'react';
52
53
 
53
54
  The `content` prop of the `<Message>` component is passed to a `<Markdown>` component (from [react-markdown](https://remarkjs.github.io/react-markdown/)), which is configured to translate plain text strings into PatternFly [`<Content>` components](/components/content) and code blocks into PatternFly [`<CodeBlock>` components.](/components/code-block)
54
55
 
@@ -66,12 +67,23 @@ You can further customize the avatar by applying an additional class or passing
66
67
 
67
68
  ```
68
69
 
70
+ ### Message dividers
71
+
72
+ To provide users with important contextual updates, you can add dividers between messages.
73
+
74
+ For example, you can use the default divider to display a "timestamp" for more significant gaps in the conversation, or you can pass `variant="fullWidth"` to a divider to announce that an agent has joined the chat.
75
+
76
+ ```js file="./MessageWithDividers.tsx"
77
+
78
+ ```
79
+
69
80
  ### Message actions
70
81
 
71
82
  You can add actions to a message, to allow users to interact with the message content. These actions can include:
72
83
 
73
84
  - Feedback responses that allow users to rate a message as "good" or "bad".
74
85
  - Copy and share controls that allow users to share the message content with others.
86
+ - An edit action to allow users to edit a message they previously sent. This should only be applied to user messages - see the [user messages example](#user-messages) for details on how to implement this action.
75
87
  - A listen action, that will read the message content out loud.
76
88
 
77
89
  **Note:** The logic for the actions is not built into the component and must be implemented by the consuming application.
@@ -183,6 +195,8 @@ The quick start tile displayed below the message is based on the tile included i
183
195
 
184
196
  Messages from users have a different background color to differentiate them from bot messages. You can also display a custom avatar that is uploaded by the user. You can further customize the avatar by applying an additional class or passing [PatternFly avatar props](/components/avatar) to the `<Message>` component via `avatarProps`.
185
197
 
198
+ User messages can also be made editable by passing an "edit" object to the `actions` property. When editing is enabled focus should be placed on the text area. When editing is completed or canceled the focus should be moved back to the edit button.
199
+
186
200
  ```js file="./UserMessage.tsx"
187
201
 
188
202
  ```
@@ -1,4 +1,4 @@
1
- import { Fragment, useState, CSSProperties, FunctionComponent, MouseEvent } from 'react';
1
+ import { Fragment, useState, useRef, useEffect, CSSProperties, FunctionComponent, MouseEvent, Ref } from 'react';
2
2
  import Message from '@patternfly/chatbot/dist/dynamic/Message';
3
3
  import userAvatar from './user_avatar.svg';
4
4
  import {
@@ -12,12 +12,32 @@ import {
12
12
  import { rehypeCodeBlockToggle } from '@patternfly/chatbot/dist/esm/Message/Plugins/rehypeCodeBlockToggle';
13
13
 
14
14
  export const UserMessageExample: FunctionComponent = () => {
15
- const [variant, setVariant] = useState<string>('Code');
16
- const [isEditable, setIsEditable] = useState<boolean>(true);
15
+ const messageInputRef = useRef<HTMLTextAreaElement>(null);
16
+ const editButtonRef = useRef<HTMLButtonElement>(null);
17
+ const [variant, setVariant] = useState<string | number | undefined>('Code');
17
18
  const [isOpen, setIsOpen] = useState<boolean>(false);
18
19
  const [selected, setSelected] = useState<string>('Message content type');
19
20
  const [isExpandable, setIsExpanded] = useState(false);
20
21
 
22
+ const [isEditable, setIsEditable] = useState<boolean>(false);
23
+ const prevIsEditable = useRef<boolean>(false);
24
+
25
+ useEffect(() => {
26
+ if (isEditable && messageInputRef?.current) {
27
+ messageInputRef.current.focus();
28
+ const messageLength = messageInputRef.current.value.length;
29
+ // Mimic the behavior of the textarea when the user clicks on a label to place the cursor at the end of the input value
30
+ messageInputRef.current.setSelectionRange(messageLength, messageLength);
31
+ }
32
+
33
+ // We only want to re-focus the edit action button if the user has previously clicked on it,
34
+ // and prevent it from receiving focus on page load
35
+ if (prevIsEditable.current && !isEditable && editButtonRef?.current) {
36
+ editButtonRef.current.focus();
37
+ prevIsEditable.current = false;
38
+ }
39
+ }, [isEditable]);
40
+
21
41
  /* eslint-disable indent */
22
42
  const renderContent = () => {
23
43
  switch (variant) {
@@ -180,6 +200,11 @@ _Italic text, formatted with single underscores_
180
200
  setIsOpen(!isOpen);
181
201
  };
182
202
 
203
+ const onUpdateOrCancelEdit = () => {
204
+ prevIsEditable.current = isEditable;
205
+ setIsEditable(false);
206
+ };
207
+
183
208
  const toggle = (toggleRef: Ref<MenuToggleElement>) => (
184
209
  <MenuToggle
185
210
  className="pf-v6-u-mb-md"
@@ -212,6 +237,17 @@ _Italic text, formatted with single underscores_
212
237
  avatar={userAvatar}
213
238
  avatarProps={{ isBordered: true }}
214
239
  />
240
+ <Message
241
+ name="User"
242
+ role="user"
243
+ isEditable={isEditable}
244
+ onEditUpdate={onUpdateOrCancelEdit}
245
+ onEditCancel={onUpdateOrCancelEdit}
246
+ actions={{ edit: { onClick: () => setIsEditable(true), innerRef: editButtonRef } }}
247
+ content="This is a user message with an edit action."
248
+ avatar={userAvatar}
249
+ inputRef={messageInputRef}
250
+ />
215
251
  <Select
216
252
  id="single-select"
217
253
  isOpen={isOpen}
@@ -235,7 +271,6 @@ _Italic text, formatted with single underscores_
235
271
  <SelectOption value="Table">Table</SelectOption>
236
272
  <SelectOption value="Image">Image</SelectOption>
237
273
  <SelectOption value="Error">Error</SelectOption>
238
- <SelectOption value="Editable">Editable</SelectOption>
239
274
  </SelectList>
240
275
  </Select>
241
276
  <Message
@@ -246,10 +281,7 @@ _Italic text, formatted with single underscores_
246
281
  tableProps={
247
282
  variant === 'Table' ? { 'aria-label': 'App information and user roles for user messages' } : undefined
248
283
  }
249
- isEditable={variant === 'Editable' ? isEditable : false}
250
284
  error={variant === 'Error' ? error : undefined}
251
- onEditUpdate={() => setIsEditable(false)}
252
- onEditCancel={() => setIsEditable(false)}
253
285
  codeBlockProps={{ isExpandable, expandableSectionProps: { truncateMaxLines: isExpandable ? 1 : undefined } }}
254
286
  // In this example, custom plugin will override any custom expandedText or collapsedText attributes provided
255
287
  // The purpose of this plugin is to provide unique link names for the code blocks