@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.
- package/dist/cjs/ChatbotConversationHistoryNav/ChatbotConversationHistoryDropdown.js +3 -1
- package/dist/cjs/ChatbotHeader/ChatbotHeaderCloseButton.js +3 -1
- package/dist/cjs/ChatbotHeader/ChatbotHeaderMenu.js +3 -1
- package/dist/cjs/ChatbotHeader/ChatbotHeaderOptionsDropdown.js +3 -1
- package/dist/cjs/ChatbotHeader/ChatbotHeaderSelectorDropdown.js +3 -1
- package/dist/cjs/ChatbotToggle/ChatbotToggle.js +3 -1
- package/dist/cjs/Message/Message.d.ts +12 -1
- package/dist/cjs/Message/Message.js +11 -6
- package/dist/cjs/Message/QuickResponse/QuickResponse.d.ts +3 -1
- package/dist/cjs/Message/QuickResponse/QuickResponse.js +2 -1
- package/dist/cjs/Message/UserFeedback/CloseButton.d.ts +10 -0
- package/dist/cjs/Message/UserFeedback/CloseButton.js +14 -0
- package/dist/cjs/Message/UserFeedback/UserFeedback.d.ts +39 -0
- package/dist/cjs/Message/UserFeedback/UserFeedback.js +55 -0
- package/dist/cjs/Message/UserFeedback/UserFeedback.test.d.ts +1 -0
- package/dist/cjs/Message/UserFeedback/UserFeedback.test.js +146 -0
- package/dist/cjs/Message/UserFeedback/UserFeedbackComplete.d.ts +42 -0
- package/dist/cjs/Message/UserFeedback/UserFeedbackComplete.js +117 -0
- package/dist/cjs/Message/UserFeedback/UserFeedbackComplete.test.d.ts +1 -0
- package/dist/cjs/Message/UserFeedback/UserFeedbackComplete.test.js +249 -0
- package/dist/cjs/MessageBar/AttachButton.js +3 -1
- package/dist/cjs/MessageBar/SendButton.js +3 -1
- package/dist/cjs/MessageBar/StopButton.js +3 -1
- package/dist/cjs/ResponseActions/ResponseActionButton.d.ts +4 -1
- package/dist/cjs/ResponseActions/ResponseActionButton.js +21 -6
- package/dist/cjs/ResponseActions/ResponseActions.d.ts +8 -2
- package/dist/cjs/ResponseActions/ResponseActions.js +7 -7
- package/dist/css/main.css +69 -11
- package/dist/css/main.css.map +1 -1
- package/dist/esm/ChatbotConversationHistoryNav/ChatbotConversationHistoryDropdown.js +3 -1
- package/dist/esm/ChatbotHeader/ChatbotHeaderCloseButton.js +3 -1
- package/dist/esm/ChatbotHeader/ChatbotHeaderMenu.js +3 -1
- package/dist/esm/ChatbotHeader/ChatbotHeaderOptionsDropdown.js +3 -1
- package/dist/esm/ChatbotHeader/ChatbotHeaderSelectorDropdown.js +3 -1
- package/dist/esm/ChatbotToggle/ChatbotToggle.js +3 -1
- package/dist/esm/Message/Message.d.ts +12 -1
- package/dist/esm/Message/Message.js +8 -3
- package/dist/esm/Message/QuickResponse/QuickResponse.d.ts +3 -1
- package/dist/esm/Message/QuickResponse/QuickResponse.js +2 -1
- package/dist/esm/Message/UserFeedback/CloseButton.d.ts +10 -0
- package/dist/esm/Message/UserFeedback/CloseButton.js +9 -0
- package/dist/esm/Message/UserFeedback/UserFeedback.d.ts +39 -0
- package/dist/esm/Message/UserFeedback/UserFeedback.js +50 -0
- package/dist/esm/Message/UserFeedback/UserFeedback.test.d.ts +1 -0
- package/dist/esm/Message/UserFeedback/UserFeedback.test.js +141 -0
- package/dist/esm/Message/UserFeedback/UserFeedbackComplete.d.ts +42 -0
- package/dist/esm/Message/UserFeedback/UserFeedbackComplete.js +112 -0
- package/dist/esm/Message/UserFeedback/UserFeedbackComplete.test.d.ts +1 -0
- package/dist/esm/Message/UserFeedback/UserFeedbackComplete.test.js +244 -0
- package/dist/esm/MessageBar/AttachButton.js +3 -1
- package/dist/esm/MessageBar/SendButton.js +3 -1
- package/dist/esm/MessageBar/StopButton.js +3 -1
- package/dist/esm/ResponseActions/ResponseActionButton.d.ts +4 -1
- package/dist/esm/ResponseActions/ResponseActionButton.js +18 -3
- package/dist/esm/ResponseActions/ResponseActions.d.ts +8 -2
- package/dist/esm/ResponseActions/ResponseActions.js +7 -7
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/patternfly-docs/content/extensions/chatbot/examples/Messages/MessageWithFeedback.tsx +71 -0
- package/patternfly-docs/content/extensions/chatbot/examples/Messages/MessageWithFeedbackTimeout.tsx +27 -0
- package/patternfly-docs/content/extensions/chatbot/examples/Messages/Messages.md +37 -7
- package/patternfly-docs/content/extensions/chatbot/examples/UI/UI.md +3 -6
- package/patternfly-docs/content/extensions/chatbot/examples/demos/AttachmentDemos.md +14 -0
- package/patternfly-docs/content/extensions/chatbot/examples/demos/Feedback.tsx +104 -0
- package/src/AttachMenu/AttachMenu.scss +1 -1
- package/src/ChatbotConversationHistoryNav/ChatbotConversationHistoryDropdown.tsx +7 -1
- package/src/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.scss +8 -1
- package/src/ChatbotHeader/ChatbotHeaderCloseButton.tsx +7 -1
- package/src/ChatbotHeader/ChatbotHeaderMenu.tsx +7 -1
- package/src/ChatbotHeader/ChatbotHeaderOptionsDropdown.tsx +8 -1
- package/src/ChatbotHeader/ChatbotHeaderSelectorDropdown.tsx +8 -1
- package/src/ChatbotModal/ChatbotModal.scss +1 -1
- package/src/ChatbotToggle/ChatbotToggle.tsx +6 -1
- package/src/CodeModal/CodeModal.scss +1 -1
- package/src/FileDetails/FileDetails.scss +1 -1
- package/src/Message/CodeBlockMessage/CodeBlockMessage.scss +1 -1
- package/src/Message/Message.scss +1 -1
- package/src/Message/Message.tsx +24 -2
- package/src/Message/QuickResponse/QuickResponse.tsx +6 -2
- package/src/Message/UserFeedback/CloseButton.tsx +21 -0
- package/src/Message/UserFeedback/UserFeedback.scss +53 -0
- package/src/Message/UserFeedback/UserFeedback.test.tsx +257 -0
- package/src/Message/UserFeedback/UserFeedback.tsx +132 -0
- package/src/Message/UserFeedback/UserFeedbackComplete.test.tsx +255 -0
- package/src/Message/UserFeedback/UserFeedbackComplete.tsx +211 -0
- package/src/MessageBar/AttachButton.tsx +2 -0
- package/src/MessageBar/SendButton.tsx +2 -0
- package/src/MessageBar/StopButton.tsx +2 -0
- package/src/ResponseActions/ResponseActionButton.tsx +14 -2
- package/src/ResponseActions/ResponseActions.tsx +26 -2
- package/src/Settings/Settings.scss +2 -2
- package/src/SourceDetailsMenuItem/SourceDetailsMenuItem.scss +1 -1
- 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
|
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
|
11
|
-
|
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.
|
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
|
+
};
|
package/patternfly-docs/content/extensions/chatbot/examples/Messages/MessageWithFeedbackTimeout.tsx
ADDED
@@ -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
|
-
'
|
18
|
-
'
|
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
|
-
|
106
|
-
<br />
|
105
|
+
|
107
106
|
`<ChatbotContent>` usually contains a `<ChatbotMessageBox>` for displaying messages.
|
108
|
-
|
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
|
-
|
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
|
+
};
|
@@ -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
|
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:
|
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
|
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
|
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
|
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
|
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:
|
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
|
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:
|
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:
|
5
|
+
font-weight: var(--pf-t--global--font--weight--body--bold);
|
6
6
|
}
|
7
7
|
|
8
8
|
.pf-chatbot__code-icon {
|