@patternfly/chatbot 2.2.0-prerelease.11 → 2.2.0-prerelease.13

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 (93) hide show
  1. package/dist/cjs/ChatbotConversationHistoryNav/ChatbotConversationHistoryDropdown.js +3 -1
  2. package/dist/cjs/ChatbotHeader/ChatbotHeaderCloseButton.js +3 -1
  3. package/dist/cjs/ChatbotHeader/ChatbotHeaderMenu.js +3 -1
  4. package/dist/cjs/ChatbotHeader/ChatbotHeaderOptionsDropdown.js +3 -1
  5. package/dist/cjs/ChatbotHeader/ChatbotHeaderSelectorDropdown.js +3 -1
  6. package/dist/cjs/ChatbotToggle/ChatbotToggle.js +3 -1
  7. package/dist/cjs/Message/Message.d.ts +12 -1
  8. package/dist/cjs/Message/Message.js +11 -6
  9. package/dist/cjs/Message/QuickResponse/QuickResponse.d.ts +3 -1
  10. package/dist/cjs/Message/QuickResponse/QuickResponse.js +2 -1
  11. package/dist/cjs/Message/UserFeedback/CloseButton.d.ts +10 -0
  12. package/dist/cjs/Message/UserFeedback/CloseButton.js +14 -0
  13. package/dist/cjs/Message/UserFeedback/UserFeedback.d.ts +39 -0
  14. package/dist/cjs/Message/UserFeedback/UserFeedback.js +55 -0
  15. package/dist/cjs/Message/UserFeedback/UserFeedback.test.d.ts +1 -0
  16. package/dist/cjs/Message/UserFeedback/UserFeedback.test.js +146 -0
  17. package/dist/cjs/Message/UserFeedback/UserFeedbackComplete.d.ts +42 -0
  18. package/dist/cjs/Message/UserFeedback/UserFeedbackComplete.js +117 -0
  19. package/dist/cjs/Message/UserFeedback/UserFeedbackComplete.test.d.ts +1 -0
  20. package/dist/cjs/Message/UserFeedback/UserFeedbackComplete.test.js +249 -0
  21. package/dist/cjs/MessageBar/AttachButton.js +3 -1
  22. package/dist/cjs/MessageBar/SendButton.js +3 -1
  23. package/dist/cjs/MessageBar/StopButton.js +3 -1
  24. package/dist/cjs/ResponseActions/ResponseActionButton.d.ts +4 -1
  25. package/dist/cjs/ResponseActions/ResponseActionButton.js +21 -6
  26. package/dist/cjs/ResponseActions/ResponseActions.d.ts +8 -2
  27. package/dist/cjs/ResponseActions/ResponseActions.js +7 -7
  28. package/dist/css/main.css +69 -11
  29. package/dist/css/main.css.map +1 -1
  30. package/dist/esm/ChatbotConversationHistoryNav/ChatbotConversationHistoryDropdown.js +3 -1
  31. package/dist/esm/ChatbotHeader/ChatbotHeaderCloseButton.js +3 -1
  32. package/dist/esm/ChatbotHeader/ChatbotHeaderMenu.js +3 -1
  33. package/dist/esm/ChatbotHeader/ChatbotHeaderOptionsDropdown.js +3 -1
  34. package/dist/esm/ChatbotHeader/ChatbotHeaderSelectorDropdown.js +3 -1
  35. package/dist/esm/ChatbotToggle/ChatbotToggle.js +3 -1
  36. package/dist/esm/Message/Message.d.ts +12 -1
  37. package/dist/esm/Message/Message.js +8 -3
  38. package/dist/esm/Message/QuickResponse/QuickResponse.d.ts +3 -1
  39. package/dist/esm/Message/QuickResponse/QuickResponse.js +2 -1
  40. package/dist/esm/Message/UserFeedback/CloseButton.d.ts +10 -0
  41. package/dist/esm/Message/UserFeedback/CloseButton.js +9 -0
  42. package/dist/esm/Message/UserFeedback/UserFeedback.d.ts +39 -0
  43. package/dist/esm/Message/UserFeedback/UserFeedback.js +50 -0
  44. package/dist/esm/Message/UserFeedback/UserFeedback.test.d.ts +1 -0
  45. package/dist/esm/Message/UserFeedback/UserFeedback.test.js +141 -0
  46. package/dist/esm/Message/UserFeedback/UserFeedbackComplete.d.ts +42 -0
  47. package/dist/esm/Message/UserFeedback/UserFeedbackComplete.js +112 -0
  48. package/dist/esm/Message/UserFeedback/UserFeedbackComplete.test.d.ts +1 -0
  49. package/dist/esm/Message/UserFeedback/UserFeedbackComplete.test.js +244 -0
  50. package/dist/esm/MessageBar/AttachButton.js +3 -1
  51. package/dist/esm/MessageBar/SendButton.js +3 -1
  52. package/dist/esm/MessageBar/StopButton.js +3 -1
  53. package/dist/esm/ResponseActions/ResponseActionButton.d.ts +4 -1
  54. package/dist/esm/ResponseActions/ResponseActionButton.js +18 -3
  55. package/dist/esm/ResponseActions/ResponseActions.d.ts +8 -2
  56. package/dist/esm/ResponseActions/ResponseActions.js +7 -7
  57. package/dist/tsconfig.tsbuildinfo +1 -1
  58. package/package.json +1 -1
  59. package/patternfly-docs/content/extensions/chatbot/examples/Messages/MessageWithFeedback.tsx +71 -0
  60. package/patternfly-docs/content/extensions/chatbot/examples/Messages/MessageWithFeedbackTimeout.tsx +27 -0
  61. package/patternfly-docs/content/extensions/chatbot/examples/Messages/Messages.md +37 -7
  62. package/patternfly-docs/content/extensions/chatbot/examples/UI/UI.md +3 -6
  63. package/patternfly-docs/content/extensions/chatbot/examples/demos/AttachmentDemos.md +14 -0
  64. package/patternfly-docs/content/extensions/chatbot/examples/demos/Feedback.tsx +104 -0
  65. package/src/AttachMenu/AttachMenu.scss +1 -1
  66. package/src/ChatbotConversationHistoryNav/ChatbotConversationHistoryDropdown.tsx +7 -1
  67. package/src/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.scss +8 -1
  68. package/src/ChatbotHeader/ChatbotHeaderCloseButton.tsx +7 -1
  69. package/src/ChatbotHeader/ChatbotHeaderMenu.tsx +7 -1
  70. package/src/ChatbotHeader/ChatbotHeaderOptionsDropdown.tsx +8 -1
  71. package/src/ChatbotHeader/ChatbotHeaderSelectorDropdown.tsx +8 -1
  72. package/src/ChatbotModal/ChatbotModal.scss +1 -1
  73. package/src/ChatbotToggle/ChatbotToggle.tsx +6 -1
  74. package/src/CodeModal/CodeModal.scss +1 -1
  75. package/src/FileDetails/FileDetails.scss +1 -1
  76. package/src/Message/CodeBlockMessage/CodeBlockMessage.scss +1 -1
  77. package/src/Message/Message.scss +1 -1
  78. package/src/Message/Message.tsx +24 -2
  79. package/src/Message/QuickResponse/QuickResponse.tsx +6 -2
  80. package/src/Message/UserFeedback/CloseButton.tsx +21 -0
  81. package/src/Message/UserFeedback/UserFeedback.scss +53 -0
  82. package/src/Message/UserFeedback/UserFeedback.test.tsx +257 -0
  83. package/src/Message/UserFeedback/UserFeedback.tsx +132 -0
  84. package/src/Message/UserFeedback/UserFeedbackComplete.test.tsx +255 -0
  85. package/src/Message/UserFeedback/UserFeedbackComplete.tsx +211 -0
  86. package/src/MessageBar/AttachButton.tsx +2 -0
  87. package/src/MessageBar/SendButton.tsx +2 -0
  88. package/src/MessageBar/StopButton.tsx +2 -0
  89. package/src/ResponseActions/ResponseActionButton.tsx +14 -2
  90. package/src/ResponseActions/ResponseActions.tsx +26 -2
  91. package/src/Settings/Settings.scss +2 -2
  92. package/src/SourceDetailsMenuItem/SourceDetailsMenuItem.scss +1 -1
  93. package/src/main.scss +1 -0
@@ -1,13 +1,28 @@
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
+ };
1
12
  import React from 'react';
2
13
  import { Button, Icon, Tooltip } from '@patternfly/react-core';
3
- export const ResponseActionButton = ({ ariaLabel, clickedAriaLabel = ariaLabel, className, icon, isDisabled, onClick, tooltipContent, clickedTooltipContent = tooltipContent, tooltipProps, isClicked = false }) => {
14
+ export const ResponseActionButtonBase = (_a) => {
15
+ var { ariaLabel, clickedAriaLabel = ariaLabel, className, icon, isDisabled, onClick, tooltipContent, clickedTooltipContent = tooltipContent, tooltipProps, isClicked = false, innerRef } = _a, props = __rest(_a, ["ariaLabel", "clickedAriaLabel", "className", "icon", "isDisabled", "onClick", "tooltipContent", "clickedTooltipContent", "tooltipProps", "isClicked", "innerRef"]);
4
16
  const generateAriaLabel = () => {
5
17
  if (ariaLabel) {
6
18
  return isClicked ? clickedAriaLabel : ariaLabel;
7
19
  }
8
20
  return isClicked ? clickedTooltipContent : tooltipContent;
9
21
  };
10
- return (React.createElement(Tooltip, Object.assign({ id: `pf-chatbot__tooltip-response-action-${tooltipContent}`, content: isClicked ? clickedTooltipContent : tooltipContent, "aria-live": "polite", position: "bottom", entryDelay: (tooltipProps === null || tooltipProps === void 0 ? void 0 : tooltipProps.entryDelay) || 0, exitDelay: (tooltipProps === null || tooltipProps === void 0 ? void 0 : tooltipProps.exitDelay) || 0, distance: (tooltipProps === null || tooltipProps === void 0 ? void 0 : tooltipProps.distance) || 8, animationDuration: (tooltipProps === null || tooltipProps === void 0 ? void 0 : tooltipProps.animationDuration) || 0 }, tooltipProps),
11
- React.createElement(Button, { variant: "plain", className: `pf-chatbot__button--response-action ${isClicked ? 'pf-chatbot__button--response-action-clicked' : ''} ${className !== null && className !== void 0 ? className : ''}`, "aria-label": generateAriaLabel(), icon: React.createElement(Icon, { isInline: true, size: "lg" }, icon), isDisabled: isDisabled, onClick: onClick, size: "sm" })));
22
+ return (React.createElement(Tooltip, Object.assign({ id: `pf-chatbot__tooltip-response-action-${tooltipContent}`, content: isClicked ? clickedTooltipContent : tooltipContent, "aria-live": "polite", position: "bottom", entryDelay: (tooltipProps === null || tooltipProps === void 0 ? void 0 : tooltipProps.entryDelay) || 0, exitDelay: (tooltipProps === null || tooltipProps === void 0 ? void 0 : tooltipProps.exitDelay) || 0, distance: (tooltipProps === null || tooltipProps === void 0 ? void 0 : tooltipProps.distance) || 8, animationDuration: (tooltipProps === null || tooltipProps === void 0 ? void 0 : tooltipProps.animationDuration) || 0,
23
+ // prevents VO announcements of both aria label and tooltip
24
+ aria: "none" }, tooltipProps),
25
+ React.createElement(Button, Object.assign({ variant: "plain", className: `pf-chatbot__button--response-action ${isClicked ? 'pf-chatbot__button--response-action-clicked' : ''} ${className !== null && className !== void 0 ? className : ''}`, "aria-label": generateAriaLabel(), icon: React.createElement(Icon, { isInline: true, size: "lg" }, icon), isDisabled: isDisabled, onClick: onClick, size: "sm", ref: innerRef }, props))));
12
26
  };
27
+ const ResponseActionButton = React.forwardRef((props, ref) => (React.createElement(ResponseActionButtonBase, Object.assign({ innerRef: ref }, props))));
13
28
  export default ResponseActionButton;
@@ -1,6 +1,6 @@
1
1
  import React from 'react';
2
- import { TooltipProps } from '@patternfly/react-core';
3
- export interface ActionProps {
2
+ import { ButtonProps, TooltipProps } from '@patternfly/react-core';
3
+ export interface ActionProps extends Omit<ButtonProps, 'ref'> {
4
4
  /** Aria-label for the button */
5
5
  ariaLabel?: string;
6
6
  /** Aria-label for the button, shown when the button is clicked. */
@@ -19,6 +19,12 @@ export interface ActionProps {
19
19
  tooltipProps?: TooltipProps;
20
20
  /** Icon for custom response action */
21
21
  icon?: React.ReactNode;
22
+ /** Ref for response action button */
23
+ ref?: React.Ref<HTMLButtonElement>;
24
+ /** Whether content launched by button, such as the feedback form, is expanded */
25
+ 'aria-expanded'?: boolean;
26
+ /** Id for content controlled by the button, such as the feedback form */
27
+ 'aria-controls'?: string;
22
28
  }
23
29
  export interface ResponseActionProps {
24
30
  /** Props for message actions, such as feedback (positive or negative), copy button, share, and listen */
@@ -33,14 +33,14 @@ export const ResponseActions = ({ actions }) => {
33
33
  onClick && onClick(e);
34
34
  };
35
35
  return (React.createElement("div", { ref: responseActions, className: "pf-chatbot__response-actions" },
36
- positive && (React.createElement(ResponseActionButton, { 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: React.createElement(OutlinedThumbsUpIcon, null), isClicked: activeButton === 'positive' })),
37
- negative && (React.createElement(ResponseActionButton, { 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: React.createElement(OutlinedThumbsDownIcon, null), isClicked: activeButton === 'negative' })),
38
- copy && (React.createElement(ResponseActionButton, { 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: React.createElement(OutlinedCopyIcon, null), isClicked: activeButton === 'copy' })),
39
- share && (React.createElement(ResponseActionButton, { 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: React.createElement(ExternalLinkAltIcon, null), isClicked: activeButton === 'share' })),
40
- listen && (React.createElement(ResponseActionButton, { ariaLabel: (_s = listen.ariaLabel) !== null && _s !== void 0 ? _s : 'Listen', clickedAriaLabel: (_t = listen.ariaLabel) !== null && _t !== void 0 ? _t : 'Listening', onClick: (e) => handleClick(e, 'listen', listen.onClick), className: listen.className, isDisabled: listen.isDisabled, tooltipContent: (_u = listen.tooltipContent) !== null && _u !== void 0 ? _u : 'Listen', clickedTooltipContent: (_v = listen.clickedTooltipContent) !== null && _v !== void 0 ? _v : 'Listening', tooltipProps: listen.tooltipProps, icon: React.createElement(VolumeUpIcon, null), isClicked: activeButton === 'listen' })),
36
+ positive && (React.createElement(ResponseActionButton, { 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: React.createElement(OutlinedThumbsUpIcon, null), isClicked: activeButton === 'positive', ref: positive.ref, "aria-expanded": positive['aria-expanded'], "aria-controls": positive['aria-controls'] })),
37
+ negative && (React.createElement(ResponseActionButton, { 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: React.createElement(OutlinedThumbsDownIcon, null), isClicked: activeButton === 'negative', ref: negative.ref, "aria-expanded": negative['aria-expanded'], "aria-controls": negative['aria-controls'] })),
38
+ copy && (React.createElement(ResponseActionButton, { 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: React.createElement(OutlinedCopyIcon, null), isClicked: activeButton === 'copy', ref: copy.ref, "aria-expanded": copy['aria-expanded'], "aria-controls": copy['aria-controls'] })),
39
+ share && (React.createElement(ResponseActionButton, { 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: React.createElement(ExternalLinkAltIcon, null), isClicked: activeButton === 'share', ref: share.ref, "aria-expanded": share['aria-expanded'], "aria-controls": share['aria-controls'] })),
40
+ listen && (React.createElement(ResponseActionButton, { ariaLabel: (_s = listen.ariaLabel) !== null && _s !== void 0 ? _s : 'Listen', clickedAriaLabel: (_t = listen.ariaLabel) !== null && _t !== void 0 ? _t : 'Listening', onClick: (e) => handleClick(e, 'listen', listen.onClick), className: listen.className, isDisabled: listen.isDisabled, tooltipContent: (_u = listen.tooltipContent) !== null && _u !== void 0 ? _u : 'Listen', clickedTooltipContent: (_v = listen.clickedTooltipContent) !== null && _v !== void 0 ? _v : 'Listening', tooltipProps: listen.tooltipProps, icon: React.createElement(VolumeUpIcon, null), isClicked: activeButton === 'listen', ref: listen.ref, "aria-expanded": listen['aria-expanded'], "aria-controls": listen['aria-controls'] })),
41
41
  Object.keys(additionalActions).map((action) => {
42
- var _a, _b, _c, _d, _e, _f, _g, _h;
43
- return (React.createElement(ResponseActionButton, { 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 }));
42
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
43
+ return (React.createElement(ResponseActionButton, { 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'] }));
44
44
  })));
45
45
  };
46
46
  export default ResponseActions;
@@ -1 +1 @@
1
- {"root":["../src/index.ts","../src/AttachMenu/AttachMenu.tsx","../src/AttachMenu/index.ts","../src/AttachmentEdit/AttachmentEdit.tsx","../src/AttachmentEdit/index.ts","../src/Chatbot/Chatbot.tsx","../src/Chatbot/index.ts","../src/ChatbotAlert/ChatbotAlert.tsx","../src/ChatbotAlert/index.ts","../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/index.ts","../src/ChatbotFooter/ChatbotFooter.tsx","../src/ChatbotFooter/ChatbotFootnote.tsx","../src/ChatbotFooter/index.ts","../src/ChatbotHeader/ChatbotHeader.tsx","../src/ChatbotHeader/ChatbotHeaderActions.tsx","../src/ChatbotHeader/ChatbotHeaderCloseButton.tsx","../src/ChatbotHeader/ChatbotHeaderMain.tsx","../src/ChatbotHeader/ChatbotHeaderMenu.tsx","../src/ChatbotHeader/ChatbotHeaderOptionsDropdown.tsx","../src/ChatbotHeader/ChatbotHeaderSelectorDropdown.tsx","../src/ChatbotHeader/ChatbotHeaderTitle.tsx","../src/ChatbotHeader/index.ts","../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.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/MessageLoading.tsx","../src/Message/index.ts","../src/Message/CodeBlockMessage/CodeBlockMessage.tsx","../src/Message/ListMessage/ListItemMessage.tsx","../src/Message/ListMessage/OrderedListMessage.tsx","../src/Message/ListMessage/UnorderedListMessage.tsx","../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/TextMessage/TextMessage.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.tsx","../src/MessageBox/index.ts","../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.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"],"version":"5.6.3"}
1
+ {"root":["../src/index.ts","../src/AttachMenu/AttachMenu.tsx","../src/AttachMenu/index.ts","../src/AttachmentEdit/AttachmentEdit.tsx","../src/AttachmentEdit/index.ts","../src/Chatbot/Chatbot.tsx","../src/Chatbot/index.ts","../src/ChatbotAlert/ChatbotAlert.tsx","../src/ChatbotAlert/index.ts","../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/index.ts","../src/ChatbotFooter/ChatbotFooter.tsx","../src/ChatbotFooter/ChatbotFootnote.tsx","../src/ChatbotFooter/index.ts","../src/ChatbotHeader/ChatbotHeader.tsx","../src/ChatbotHeader/ChatbotHeaderActions.tsx","../src/ChatbotHeader/ChatbotHeaderCloseButton.tsx","../src/ChatbotHeader/ChatbotHeaderMain.tsx","../src/ChatbotHeader/ChatbotHeaderMenu.tsx","../src/ChatbotHeader/ChatbotHeaderOptionsDropdown.tsx","../src/ChatbotHeader/ChatbotHeaderSelectorDropdown.tsx","../src/ChatbotHeader/ChatbotHeaderTitle.tsx","../src/ChatbotHeader/index.ts","../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.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/MessageLoading.tsx","../src/Message/index.ts","../src/Message/CodeBlockMessage/CodeBlockMessage.tsx","../src/Message/ListMessage/ListItemMessage.tsx","../src/Message/ListMessage/OrderedListMessage.tsx","../src/Message/ListMessage/UnorderedListMessage.tsx","../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/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.tsx","../src/MessageBox/index.ts","../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.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"],"version":"5.6.3"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@patternfly/chatbot",
3
- "version": "2.2.0-prerelease.11",
3
+ "version": "2.2.0-prerelease.13",
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",
@@ -0,0 +1,71 @@
1
+ import React from 'react';
2
+ import Message from '@patternfly/chatbot/dist/dynamic/Message';
3
+ import patternflyAvatar from './patternfly_avatar.jpg';
4
+ import { Checkbox, FormGroup, Stack } from '@patternfly/react-core';
5
+
6
+ export const MessageWithFeedbackExample: React.FunctionComponent = () => {
7
+ const [hasCloseButton, setHasCloseButton] = React.useState(false);
8
+ const [hasTextArea, setHasTextArea] = React.useState(false);
9
+
10
+ return (
11
+ <>
12
+ <Stack hasGutter>
13
+ <FormGroup role="radiogroup" isInline fieldId="feedback-card" label="Variant">
14
+ <Checkbox
15
+ isChecked={hasTextArea}
16
+ onChange={() => {
17
+ setHasTextArea(!hasTextArea);
18
+ }}
19
+ name="basic-inline-radio"
20
+ label="Has text area"
21
+ id="has-text-area"
22
+ />
23
+ </FormGroup>
24
+ <Message
25
+ name="Bot"
26
+ role="bot"
27
+ avatar={patternflyAvatar}
28
+ content="This is a message with the feedback card:"
29
+ userFeedbackForm={{
30
+ quickResponses: [
31
+ { id: '1', content: 'Helpful information' },
32
+ { id: '2', content: 'Easy to understand' },
33
+ { id: '3', content: 'Resolved my issue' }
34
+ ],
35
+ onSubmit: (quickResponse, additionalFeedback) =>
36
+ alert(`Selected ${quickResponse} and received the additional feedback: ${additionalFeedback}`),
37
+ hasTextArea,
38
+ // eslint-disable-next-line no-console
39
+ onClose: () => console.log('closed feedback form'),
40
+ focusOnLoad: false
41
+ }}
42
+ />
43
+ </Stack>
44
+ <Stack hasGutter>
45
+ <FormGroup role="radiogroup" isInline fieldId="feedback-thank-you" label="Variant">
46
+ <Checkbox
47
+ isChecked={hasCloseButton}
48
+ onChange={() => {
49
+ setHasCloseButton(!hasCloseButton);
50
+ }}
51
+ name="basic-inline-radio"
52
+ label="Has close button"
53
+ id="has-close"
54
+ />
55
+ </FormGroup>
56
+ <Message
57
+ name="Bot"
58
+ role="bot"
59
+ avatar={patternflyAvatar}
60
+ content="This is a thank-you message, which is displayed once the feedback card is submitted:"
61
+ // eslint-disable-next-line no-console
62
+ userFeedbackComplete={{
63
+ // eslint-disable-next-line no-console
64
+ onClose: hasCloseButton ? () => console.log('closed completion message') : undefined,
65
+ focusOnLoad: false
66
+ }}
67
+ />
68
+ </Stack>
69
+ </>
70
+ );
71
+ };
@@ -0,0 +1,27 @@
1
+ import React from 'react';
2
+ import Message from '@patternfly/chatbot/dist/dynamic/Message';
3
+ import patternflyAvatar from './patternfly_avatar.jpg';
4
+ import { Button } from '@patternfly/react-core';
5
+
6
+ export const MessageWithFeedbackTimeoutExample: React.FunctionComponent = () => {
7
+ const [hasFeedback, setHasFeedback] = React.useState(false);
8
+
9
+ return (
10
+ <>
11
+ <Button variant="secondary" onClick={() => setHasFeedback(true)}>
12
+ Show card
13
+ </Button>
14
+ <Button variant="secondary" onClick={() => setHasFeedback(false)}>
15
+ Remove card
16
+ </Button>
17
+ <Message
18
+ name="Bot"
19
+ role="bot"
20
+ avatar={patternflyAvatar}
21
+ content="This completion message times out after you click **Show card**:"
22
+ userFeedbackComplete={hasFeedback ? { timeout: true, onTimeout: () => setHasFeedback(false) } : undefined}
23
+ isLiveRegion
24
+ />
25
+ </>
26
+ );
27
+ };
@@ -14,14 +14,17 @@ propComponents:
14
14
  [
15
15
  'AttachMenu',
16
16
  'AttachmentEdit',
17
- 'FileDetails',
18
- 'FileDetailsLabel',
17
+ 'FileDetailsProps',
18
+ 'FileDetailsLabelProps',
19
19
  'FileDropZone',
20
20
  'PreviewAttachment',
21
21
  'Message',
22
22
  'PreviewAttachment',
23
23
  'ActionProps',
24
- 'SourcesCardProps'
24
+ 'SourcesCardProps',
25
+ 'UserFeedbackProps',
26
+ 'UserFeedbackCompleteProps',
27
+ 'QuickResponseProps'
25
28
  ]
26
29
  sortValue: 3
27
30
  ---
@@ -52,12 +55,8 @@ The `content` prop of the `<Message>` component is passed to a `<Markdown>` comp
52
55
 
53
56
  Messages from the ChatBot will be marked with an "AI" label to clearly communicate the use of AI to users. The ChatBot can display different `content` types, including plain text, code, or a loading animation (via `isLoading`).
54
57
 
55
- <br />
56
-
57
58
  By default, a date and timestamp is displayed with each message. We recommend using the `timestamp` prop in real ChatBots, since it will allow you to set persistent dates and times on messages, even if the messages re-render. You can update `timestamp` with a different [date and time format](/ux-writing/numerics) as needed.
58
59
 
59
- <br />
60
-
61
60
  You can further customize the avatar by applying an additional class or passing [PatternFly avatar props](/components/avatar) to the `<Message>` component via `avatarProps`.
62
61
 
63
62
  ```js file="./BotMessage.tsx"
@@ -97,6 +96,37 @@ You can apply a `clickedAriaLabel` and `clickedTooltipContent` once a button is
97
96
 
98
97
  ```
99
98
 
99
+ ### Message feedback
100
+
101
+ When a user selects a positive or negative [message action](#message-actions), you can display a message feedback card that acknowledges their response and provides space for additional written feedback. These cards can be manually dismissed via the close button and the thank-you card can be [configured to time out automatically](/patternfly-ai/chatbot/messages#message-feedback-with-timeouts).
102
+
103
+ You can see the full feedback flow [in the message demos](/patternfly-ai/chatbot/messages/demo#message-feedback).
104
+
105
+ The message feedback cards will immediately receive focus by default, but you can remove this behavior by passing `focusOnLoad: false` to the `<Message>` (as shown in the following examples). For better usability, you should generally keep the default focus behavior.
106
+
107
+ The following examples demonstrate:
108
+
109
+ - A basic feedback card. To toggle the text input area, select the **Has text area** checkbox.
110
+ - A thank-you card. To toggle the close button, select the **Has close button** checkbox.
111
+
112
+ ```js file="./MessageWithFeedback.tsx"
113
+
114
+ ```
115
+
116
+ ### Message feedback with timeouts
117
+
118
+ The feedback thank-you message can be configured to time out and automatically close after a period of time. The default time-out period is 8000 ms, but it can be customized via `timeout`.
119
+
120
+ To display the thank-you message in this example, click **Show card**.
121
+
122
+ The card will not dismiss within the default time if a user is hovering over it or if it has keyboard focus. Instead, it will dismiss after they remove focus, via `timeoutAnimation`, which is 3000 ms by default. You can adjust this duration and set an `onTimeout` callback, as well as optional `onMouseEnter` and `onMouseLeave` callbacks.
123
+
124
+ For accessibility purposes, be sure to announce when new content appears onscreen. `isLiveRegion` is set to true by default on `<Message>` so it will make appropriate announcements for you when the thank-you card appears.
125
+
126
+ ```js file="./MessageWithFeedbackTimeout.tsx"
127
+
128
+ ```
129
+
100
130
  ### Messages with quick responses
101
131
 
102
132
  You can offer convenient, clickable responses to messages in the form of quick actions. Quick actions are [PatternFly labels](/components/label/) in a label group, configured to display up to 5 visible labels. Only 1 response can be selected at a time.
@@ -102,11 +102,9 @@ The "embedded" display mode is meant to be used within a [PatternFly page](/comp
102
102
  ### Content and message box
103
103
 
104
104
  The `<ChatbotContent>` component is the container that is placed within the `<Chatbot>`, between the [`<ChatbotHeader>`](/patternfly-ai/chatbot/ui#header) and [`<ChatbotFooter>`.](/patternfly-ai/chatbot/ui#footer)
105
- <br />
106
- <br />
105
+
107
106
  `<ChatbotContent>` usually contains a `<ChatbotMessageBox>` for displaying messages.
108
- <br />
109
- <br />
107
+
110
108
  Your code structure should look like this:
111
109
 
112
110
  ```noLive
@@ -144,8 +142,7 @@ To provide users with a more specific direction, you can also include optional w
144
142
  ### Skip to content
145
143
 
146
144
  To provide page context, we recommend using a "Skip to chatbot" button. This allows you to skip past other content on the page, directly to the ChatBot content, using a [PatternFly skip to content component](/components/skip-to-content). To display this button, you must tab into the main window.
147
- <br />
148
- <br />
145
+
149
146
  When using default or docked modes, we recommend putting focus on the toggle if the ChatBot is closed, and the ChatBot when it is open. For fullscreen and embedded, we recommend putting the focus on the first focusable item in the ChatBot, such as a menu toggle. This can be seen in our more fully-featured demos for the [default, embedded, and fullscreen ChatBot](/patternfly-ai/chatbot/overview/demo#basic-chatbot) and the [embedded ChatBot](/patternfly-ai/chatbot/overview/demo#embedded-chatbot).
150
147
 
151
148
  ```js file="./SkipToContent.tsx" isFullscreen
@@ -47,6 +47,20 @@ import patternflyAvatar from '../Messages/patternfly_avatar.jpg';
47
47
 
48
48
  ## Demos
49
49
 
50
+ ### Message feedback
51
+
52
+ When a user selects a positive or negative message action, you can display a message feedback card that acknowledges their response and provides space for additional written feedback. These cards can be manually dismissed via the close button and the thank-you card can be configured to time out automatically.
53
+
54
+ The following example demonstrates a full feedback flow, which accepts written feedback submission and displays a thank you card.
55
+
56
+ It also demonstrates how to handle focus appropriately for accessibility. The card will be focused when it appears in the DOM. When the card closes, place the focus back on the launching button. To provide additional context on what the button controls, you can also add `aria-expanded` and `aria-controls` attributes to the feedback buttons.
57
+
58
+ It is also important to announce when new content appears onscreen for accessibility purposes. `isLiveRegion` is set to true by default on `<Message>` so it will make appropriate announcements for you when the feedback card appears.
59
+
60
+ ```js file="./Feedback.tsx"
61
+
62
+ ```
63
+
50
64
  ### Attach via upload button in message bar
51
65
 
52
66
  This demo displays unique attachment features, including:
@@ -0,0 +1,104 @@
1
+ import React from 'react';
2
+ import Message from '@patternfly/chatbot/dist/dynamic/Message';
3
+ import patternflyAvatar from '../Messages/patternfly_avatar.jpg';
4
+
5
+ export const MessageWithFeedbackExample: React.FunctionComponent = () => {
6
+ const [showUserFeedbackForm, setShowUserFeedbackForm] = React.useState(false);
7
+ const [showCompletionForm, setShowCompletionForm] = React.useState(false);
8
+ const [launchButton, setLaunchButton] = React.useState<string>();
9
+ const positiveRef = React.useRef<HTMLButtonElement>(null);
10
+ const negativeRef = React.useRef<HTMLButtonElement>(null);
11
+ const feedbackId = 'user-feedback-form';
12
+ const completeId = 'user-feedback-received';
13
+
14
+ const getCurrentCard = () => {
15
+ if (showUserFeedbackForm) {
16
+ return feedbackId;
17
+ }
18
+ if (showCompletionForm) {
19
+ return completeId;
20
+ }
21
+ };
22
+
23
+ const isExpanded = showUserFeedbackForm || showCompletionForm;
24
+
25
+ const focusLaunchButton = () => {
26
+ if (launchButton === 'positive') {
27
+ positiveRef.current?.focus();
28
+ }
29
+ if (launchButton === 'negative') {
30
+ negativeRef.current?.focus();
31
+ }
32
+ };
33
+
34
+ return (
35
+ <Message
36
+ name="Bot"
37
+ role="bot"
38
+ avatar={patternflyAvatar}
39
+ content="Bot message with user feedback flow; click on a message action to launch the feedback flow. Click submit to see the thank-you message."
40
+ actions={{
41
+ positive: {
42
+ onClick: () => {
43
+ setShowUserFeedbackForm(true);
44
+ setShowCompletionForm(false);
45
+ setLaunchButton('positive');
46
+ },
47
+ /* These are important for accessibility */
48
+ 'aria-expanded': isExpanded,
49
+ 'aria-controls': getCurrentCard(),
50
+ ref: positiveRef
51
+ },
52
+ negative: {
53
+ onClick: () => {
54
+ setShowUserFeedbackForm(true);
55
+ setShowCompletionForm(false);
56
+ setLaunchButton('negative');
57
+ },
58
+ /* These are important for accessibility */
59
+ 'aria-expanded': isExpanded,
60
+ 'aria-controls': getCurrentCard(),
61
+ ref: negativeRef
62
+ }
63
+ }}
64
+ userFeedbackForm={
65
+ showUserFeedbackForm
66
+ ? /* eslint-disable indent */
67
+ {
68
+ quickResponses: [
69
+ { id: '1', content: 'Helpful information' },
70
+ { id: '2', content: 'Easy to understand' },
71
+ { id: '3', content: 'Resolved my issue' }
72
+ ],
73
+ onSubmit: (quickResponse, additionalFeedback) => {
74
+ alert(`Selected ${quickResponse} and received the additional feedback: ${additionalFeedback}`);
75
+ setShowUserFeedbackForm(false);
76
+ setShowCompletionForm(true);
77
+ focusLaunchButton();
78
+ },
79
+ hasTextArea: true,
80
+ onClose: () => {
81
+ setShowUserFeedbackForm(false);
82
+ focusLaunchButton();
83
+ },
84
+ id: feedbackId
85
+ }
86
+ : undefined
87
+ /* eslint-enable indent */
88
+ }
89
+ userFeedbackComplete={
90
+ showCompletionForm
91
+ ? /* eslint-disable indent */
92
+ {
93
+ onClose: () => {
94
+ setShowCompletionForm(false);
95
+ focusLaunchButton();
96
+ },
97
+ id: completeId
98
+ }
99
+ : undefined
100
+ /* eslint-enable indent */
101
+ }
102
+ />
103
+ );
104
+ };
@@ -53,7 +53,7 @@
53
53
  }
54
54
 
55
55
  .pf-v6-c-menu__item-description {
56
- font-weight: 500;
56
+ font-weight: var(--pf-t--global--font--weight--body--bold);
57
57
  }
58
58
 
59
59
  .pf-v6-c-divider {
@@ -28,7 +28,13 @@ export const ChatbotConversationHistoryDropdown: React.FunctionComponent<Chatbot
28
28
  const [isOpen, setIsOpen] = React.useState(false);
29
29
 
30
30
  const toggle = (toggleRef: React.Ref<MenuToggleElement>) => (
31
- <Tooltip className="pf-chatbot__tooltip" content={label ?? 'Conversation options'} position="bottom">
31
+ <Tooltip
32
+ className="pf-chatbot__tooltip"
33
+ content={label ?? 'Conversation options'}
34
+ position="bottom"
35
+ // prevents VO announcements of both aria label and tooltip
36
+ aria="none"
37
+ >
32
38
  <MenuToggle
33
39
  className="pf-chatbot__history-actions"
34
40
  variant="plain"
@@ -26,7 +26,7 @@
26
26
  }
27
27
  .pf-chatbot__menu-item-header > .pf-v6-c-menu__group-title {
28
28
  color: var(--pf-t--global--text--color--subtle);
29
- font-weight: 500;
29
+ font-weight: var(--pf-t--global--font--weight--body--bold);
30
30
  font-size: var(--pf-t--global--icon--size--font--sm);
31
31
  --pf-v6-c-menu__group-title--PaddingInlineStart: var(--pf-t--global--spacer--sm);
32
32
  --pf-v6-c-menu__group-title--PaddingInlineEnd: var(--pf-t--global--spacer--sm);
@@ -134,6 +134,13 @@
134
134
  flex-direction: column;
135
135
  height: 70vh;
136
136
  }
137
+
138
+ // Resizable drawer spacing is different - needs manual adjustment for gaps between buttons, inputs, etc.
139
+ .pf-v6-c-drawer__panel.pf-m-resizable {
140
+ .pf-v6-c-drawer__panel-main {
141
+ row-gap: var(--pf-v6-c-drawer__panel--RowGap);
142
+ }
143
+ }
137
144
  }
138
145
 
139
146
  // ============================================================================
@@ -27,7 +27,13 @@ const ChatbotHeaderCloseButtonBase: React.FunctionComponent<ChatbotHeaderCloseBu
27
27
  tooltipContent = 'Close'
28
28
  }: ChatbotHeaderCloseButtonProps) => (
29
29
  <div className={`pf-chatbot__menu ${className}`}>
30
- <Tooltip content={tooltipContent} position="bottom" {...tooltipProps}>
30
+ <Tooltip
31
+ content={tooltipContent}
32
+ position="bottom"
33
+ // prevents VO announcements of both aria label and tooltip
34
+ aria="none"
35
+ {...tooltipProps}
36
+ >
31
37
  <Button
32
38
  className="pf-chatbot__button--toggle-menu"
33
39
  variant="plain"
@@ -27,7 +27,13 @@ const ChatbotHeaderMenuBase: React.FunctionComponent<ChatbotHeaderMenuProps> = (
27
27
  tooltipContent = 'Menu'
28
28
  }: ChatbotHeaderMenuProps) => (
29
29
  <div className={`pf-chatbot__menu ${className}`}>
30
- <Tooltip content={tooltipContent} position="bottom" {...tooltipProps}>
30
+ <Tooltip
31
+ content={tooltipContent}
32
+ position="bottom"
33
+ // prevents VO announcements of both aria label and tooltip
34
+ aria="none"
35
+ {...tooltipProps}
36
+ >
31
37
  <Button
32
38
  className="pf-chatbot__button--toggle-menu"
33
39
  variant="plain"
@@ -33,7 +33,14 @@ export const ChatbotHeaderOptionsDropdown: React.FunctionComponent<ChatbotHeader
33
33
  const [isOptionsMenuOpen, setIsOptionsMenuOpen] = React.useState(false);
34
34
 
35
35
  const toggle = (toggleRef: React.Ref<MenuToggleElement>) => (
36
- <Tooltip className="pf-chatbot__tooltip" content="Chatbot options" position="bottom" {...tooltipProps}>
36
+ <Tooltip
37
+ className="pf-chatbot__tooltip"
38
+ content="Chatbot options"
39
+ position="bottom"
40
+ // prevents VO announcements of both aria label and tooltip
41
+ aria="none"
42
+ {...tooltipProps}
43
+ >
37
44
  <MenuToggle
38
45
  className="pf-chatbot__button--toggle-options"
39
46
  variant="plain"
@@ -31,7 +31,14 @@ export const ChatbotHeaderSelectorDropdown: React.FunctionComponent<ChatbotHeade
31
31
  const [defaultAriaLabel, setDefaultAriaLabel] = React.useState('Chatbot selector');
32
32
 
33
33
  const toggle = (toggleRef: React.Ref<MenuToggleElement>) => (
34
- <Tooltip className="pf-chatbot__tooltip" content={tooltipContent} position="bottom" {...tooltipProps}>
34
+ <Tooltip
35
+ className="pf-chatbot__tooltip"
36
+ content={tooltipContent}
37
+ position="bottom"
38
+ // prevents VO announcements of both aria label and tooltip
39
+ aria="none"
40
+ {...tooltipProps}
41
+ >
35
42
  <MenuToggle
36
43
  variant="secondary"
37
44
  aria-label={menuToggleAriaLabel ?? defaultAriaLabel}
@@ -16,7 +16,7 @@
16
16
  }
17
17
  .pf-v6-c-button.pf-m-primary.pf-m-block,
18
18
  .pf-v6-c-button.pf-m-link.pf-m-block {
19
- --pf-v6-c-button--FontWeight: 500;
19
+ --pf-v6-c-button--FontWeight: var(--pf-t--global--font--weight--body--bold);
20
20
  }
21
21
  .pf-v6-c-modal-box__footer {
22
22
  padding-block-start: var(--pf-t--global--spacer--xl);
@@ -65,7 +65,12 @@ const ChatbotToggleBase: React.FunctionComponent<ChatbotToggleProps> = ({
65
65
  const icon = isChatbotVisible ? <AngleDownIcon data-testid={openIconTestId} /> : closedIcon;
66
66
 
67
67
  return (
68
- <Tooltip content={tooltipLabel} {...tooltipProps}>
68
+ <Tooltip
69
+ content={tooltipLabel}
70
+ // prevents VO announcements of both aria label and tooltip
71
+ aria="none"
72
+ {...tooltipProps}
73
+ >
69
74
  <Button
70
75
  className={`pf-chatbot__button ${isChatbotVisible ? 'pf-chatbot__button--active' : ''} ${isRound ? 'pf-chatbot__button--round' : ''} ${className ? className : ''}`}
71
76
  variant="plain"
@@ -38,7 +38,7 @@
38
38
  border: none;
39
39
  --pf-v6-c-code-editor__tab--BorderStartEndRadius: 0;
40
40
  border-start-start-radius: var(--pf-t--global--border--radius--small);
41
- --pf-t--global--font--weight--body--default: 500;
41
+ --pf-t--global--font--weight--body--default: var(--pf-t--global--font--weight--body--bold);
42
42
  }
43
43
  .pf-v6-c-code-editor__tab-icon {
44
44
  display: none;
@@ -2,7 +2,7 @@
2
2
  color: var(--pf-t--global--text--color--subtle);
3
3
  display: flex; // this is needed for when FileDetailsLabel is clickable
4
4
  font-size: var(--pf-t--global--icon--size--font--xs);
5
- font-weight: 500;
5
+ font-weight: var(--pf-t--global--font--weight--body--bold);
6
6
  }
7
7
 
8
8
  .pf-chatbot__code-icon {
@@ -36,7 +36,7 @@
36
36
  justify-content: space-between;
37
37
  width: 100%;
38
38
  font-size: var(--pf-t--global--font--size--sm);
39
- font-weight: 500;
39
+ font-weight: var(--pf-t--global--font--weight--body--bold);
40
40
  }
41
41
 
42
42
  .pf-chatbot__button--copy.pf-v6-c-button {