@patternfly/chatbot 6.6.0-prerelease.5 → 6.6.0-prerelease.6
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/Message/Message.d.ts +4 -0
- package/dist/cjs/Message/Message.js +2 -2
- package/dist/cjs/Message/Message.test.js +72 -0
- package/dist/cjs/ResponseActions/ResponseActions.d.ts +6 -0
- package/dist/cjs/ResponseActions/ResponseActions.js +12 -5
- package/dist/cjs/ResponseActions/ResponseActions.test.js +28 -0
- package/dist/css/main.css +10 -0
- package/dist/css/main.css.map +1 -1
- package/dist/esm/Message/Message.d.ts +4 -0
- package/dist/esm/Message/Message.js +2 -2
- package/dist/esm/Message/Message.test.js +72 -0
- package/dist/esm/ResponseActions/ResponseActions.d.ts +6 -0
- package/dist/esm/ResponseActions/ResponseActions.js +12 -5
- package/dist/esm/ResponseActions/ResponseActions.test.js +28 -0
- package/package.json +1 -1
- package/patternfly-docs/content/extensions/chatbot/examples/Messages/MessageWithResponseActions.tsx +39 -18
- package/patternfly-docs/content/extensions/chatbot/examples/Messages/Messages.md +9 -8
- package/src/Message/Message.scss +12 -0
- package/src/Message/Message.test.tsx +136 -0
- package/src/Message/Message.tsx +12 -1
- package/src/ResponseActions/ResponseActions.test.tsx +59 -0
- package/src/ResponseActions/ResponseActions.tsx +35 -10
|
@@ -85,6 +85,10 @@ export interface MessageProps extends Omit<HTMLProps<HTMLDivElement>, 'role'> {
|
|
|
85
85
|
* For finer control of multiple action groups, use persistActionSelection on each group.
|
|
86
86
|
*/
|
|
87
87
|
persistActionSelection?: boolean;
|
|
88
|
+
/** Flag indicating whether the actions container is only visible when a message is hovered or an action would receive focus. Note
|
|
89
|
+
* that setting this to true will append tooltips inline instead of the document.body.
|
|
90
|
+
*/
|
|
91
|
+
showActionsOnInteraction?: boolean;
|
|
88
92
|
/** Sources for message */
|
|
89
93
|
sources?: SourcesCardProps;
|
|
90
94
|
/** Label for the English word "AI," used to tag messages with role "bot" */
|
|
@@ -39,7 +39,7 @@ const ToolCall_1 = __importDefault(require("../ToolCall"));
|
|
|
39
39
|
const MarkdownContent_1 = __importDefault(require("../MarkdownContent"));
|
|
40
40
|
const react_styles_1 = require("@patternfly/react-styles");
|
|
41
41
|
const MessageBase = (_a) => {
|
|
42
|
-
var { children, role, alignment = 'start', isMetadataVisible = true, content, extraContent, name, avatar, timestamp, isLoading, actions, persistActionSelection, sources, botWord = 'AI', loadingWord = 'Loading message', codeBlockProps, quickResponses, quickResponseContainerProps = { numLabels: 5 }, attachments, hasRoundAvatar = true, avatarProps, quickStarts, userFeedbackForm, userFeedbackComplete, isLiveRegion = true, innerRef, tableProps, openLinkInNewTab = true, additionalRehypePlugins = [], additionalRemarkPlugins = [], linkProps, error, isEditable, editPlaceholder = 'Edit prompt message...', updateWord = 'Update', cancelWord = 'Cancel', onEditUpdate, onEditCancel, inputRef, editFormProps, isCompact, isMarkdownDisabled, reactMarkdownProps, toolResponse, deepThinking, remarkGfmProps, toolCall, hasNoImagesInUserMessages = true, isPrimary, useFilledIconsOnClick } = _a, props = __rest(_a, ["children", "role", "alignment", "isMetadataVisible", "content", "extraContent", "name", "avatar", "timestamp", "isLoading", "actions", "persistActionSelection", "sources", "botWord", "loadingWord", "codeBlockProps", "quickResponses", "quickResponseContainerProps", "attachments", "hasRoundAvatar", "avatarProps", "quickStarts", "userFeedbackForm", "userFeedbackComplete", "isLiveRegion", "innerRef", "tableProps", "openLinkInNewTab", "additionalRehypePlugins", "additionalRemarkPlugins", "linkProps", "error", "isEditable", "editPlaceholder", "updateWord", "cancelWord", "onEditUpdate", "onEditCancel", "inputRef", "editFormProps", "isCompact", "isMarkdownDisabled", "reactMarkdownProps", "toolResponse", "deepThinking", "remarkGfmProps", "toolCall", "hasNoImagesInUserMessages", "isPrimary", "useFilledIconsOnClick"]);
|
|
42
|
+
var { children, role, alignment = 'start', isMetadataVisible = true, content, extraContent, name, avatar, timestamp, isLoading, actions, persistActionSelection, showActionsOnInteraction = false, sources, botWord = 'AI', loadingWord = 'Loading message', codeBlockProps, quickResponses, quickResponseContainerProps = { numLabels: 5 }, attachments, hasRoundAvatar = true, avatarProps, quickStarts, userFeedbackForm, userFeedbackComplete, isLiveRegion = true, innerRef, tableProps, openLinkInNewTab = true, additionalRehypePlugins = [], additionalRemarkPlugins = [], linkProps, error, isEditable, editPlaceholder = 'Edit prompt message...', updateWord = 'Update', cancelWord = 'Cancel', onEditUpdate, onEditCancel, inputRef, editFormProps, isCompact, isMarkdownDisabled, reactMarkdownProps, toolResponse, deepThinking, remarkGfmProps, toolCall, hasNoImagesInUserMessages = true, isPrimary, useFilledIconsOnClick } = _a, props = __rest(_a, ["children", "role", "alignment", "isMetadataVisible", "content", "extraContent", "name", "avatar", "timestamp", "isLoading", "actions", "persistActionSelection", "showActionsOnInteraction", "sources", "botWord", "loadingWord", "codeBlockProps", "quickResponses", "quickResponseContainerProps", "attachments", "hasRoundAvatar", "avatarProps", "quickStarts", "userFeedbackForm", "userFeedbackComplete", "isLiveRegion", "innerRef", "tableProps", "openLinkInNewTab", "additionalRehypePlugins", "additionalRemarkPlugins", "linkProps", "error", "isEditable", "editPlaceholder", "updateWord", "cancelWord", "onEditUpdate", "onEditCancel", "inputRef", "editFormProps", "isCompact", "isMarkdownDisabled", "reactMarkdownProps", "toolResponse", "deepThinking", "remarkGfmProps", "toolCall", "hasNoImagesInUserMessages", "isPrimary", "useFilledIconsOnClick"]);
|
|
43
43
|
const [messageText, setMessageText] = (0, react_1.useState)(content);
|
|
44
44
|
(0, react_1.useEffect)(() => {
|
|
45
45
|
setMessageText(content);
|
|
@@ -67,7 +67,7 @@ const MessageBase = (_a) => {
|
|
|
67
67
|
}
|
|
68
68
|
return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [beforeMainContent && (0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: beforeMainContent }), error ? (0, jsx_runtime_1.jsx)(ErrorMessage_1.default, Object.assign({}, error)) : handleMarkdown()] }));
|
|
69
69
|
};
|
|
70
|
-
return ((0, jsx_runtime_1.jsxs)("section", Object.assign({ "aria-label": `Message from ${role} - ${dateString}`, className: (0, react_styles_1.css)(`pf-chatbot__message pf-chatbot__message--${role}`, alignment === 'end' && 'pf-m-end'), "aria-live": isLiveRegion ? 'polite' : undefined, "aria-atomic": isLiveRegion ? false : undefined, ref: innerRef }, props, { children: [avatar && ((0, jsx_runtime_1.jsx)(react_core_1.Avatar, Object.assign({ className: `pf-chatbot__message-avatar ${hasRoundAvatar ? 'pf-chatbot__message-avatar--round' : ''} ${avatarClassName ? avatarClassName : ''}`, src: avatar, alt: "" }, avatarProps))), (0, jsx_runtime_1.jsxs)("div", { className: "pf-chatbot__message-contents", children: [isMetadataVisible && ((0, jsx_runtime_1.jsxs)("div", { className: "pf-chatbot__message-meta", children: [name && ((0, jsx_runtime_1.jsx)("span", { className: "pf-chatbot__message-name", children: (0, jsx_runtime_1.jsx)(react_core_1.Truncate, { content: name }) })), role === 'bot' && ((0, jsx_runtime_1.jsx)(react_core_1.Label, { variant: "outline", isCompact: true, children: botWord })), (0, jsx_runtime_1.jsx)(react_core_1.Timestamp, { date: date, children: timestamp })] })), (0, jsx_runtime_1.jsx)("div", { className: "pf-chatbot__message-response", children: children ? ((0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: children })) : ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsxs)("div", { className: "pf-chatbot__message-and-actions", children: [renderMessage(), afterMainContent && (0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: afterMainContent }), toolResponse && (0, jsx_runtime_1.jsx)(ToolResponse_1.default, Object.assign({}, toolResponse)), deepThinking && (0, jsx_runtime_1.jsx)(DeepThinking_1.default, Object.assign({}, deepThinking)), toolCall && (0, jsx_runtime_1.jsx)(ToolCall_1.default, Object.assign({}, toolCall)), !isLoading && sources && (0, jsx_runtime_1.jsx)(SourcesCard_1.default, Object.assign({}, sources, { isCompact: isCompact })), quickStarts && quickStarts.quickStart && ((0, jsx_runtime_1.jsx)(QuickStartTile_1.default, { quickStart: quickStarts.quickStart, onSelectQuickStart: quickStarts.onSelectQuickStart, minuteWord: quickStarts.minuteWord, minuteWordPlural: quickStarts.minuteWordPlural, prerequisiteWord: quickStarts.prerequisiteWord, prerequisiteWordPlural: quickStarts.prerequisiteWordPlural, quickStartButtonAriaLabel: quickStarts.quickStartButtonAriaLabel, isCompact: isCompact })), !isLoading && !isEditable && actions && ((0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: Array.isArray(actions) ? ((0, jsx_runtime_1.jsx)("div", { className:
|
|
70
|
+
return ((0, jsx_runtime_1.jsxs)("section", Object.assign({ "aria-label": `Message from ${role} - ${dateString}`, className: (0, react_styles_1.css)(`pf-chatbot__message pf-chatbot__message--${role}`, alignment === 'end' && 'pf-m-end'), "aria-live": isLiveRegion ? 'polite' : undefined, "aria-atomic": isLiveRegion ? false : undefined, ref: innerRef }, props, { children: [avatar && ((0, jsx_runtime_1.jsx)(react_core_1.Avatar, Object.assign({ className: `pf-chatbot__message-avatar ${hasRoundAvatar ? 'pf-chatbot__message-avatar--round' : ''} ${avatarClassName ? avatarClassName : ''}`, src: avatar, alt: "" }, avatarProps))), (0, jsx_runtime_1.jsxs)("div", { className: "pf-chatbot__message-contents", children: [isMetadataVisible && ((0, jsx_runtime_1.jsxs)("div", { className: "pf-chatbot__message-meta", children: [name && ((0, jsx_runtime_1.jsx)("span", { className: "pf-chatbot__message-name", children: (0, jsx_runtime_1.jsx)(react_core_1.Truncate, { content: name }) })), role === 'bot' && ((0, jsx_runtime_1.jsx)(react_core_1.Label, { variant: "outline", isCompact: true, children: botWord })), (0, jsx_runtime_1.jsx)(react_core_1.Timestamp, { date: date, children: timestamp })] })), (0, jsx_runtime_1.jsx)("div", { className: "pf-chatbot__message-response", children: children ? ((0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: children })) : ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsxs)("div", { className: "pf-chatbot__message-and-actions", children: [renderMessage(), afterMainContent && (0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: afterMainContent }), toolResponse && (0, jsx_runtime_1.jsx)(ToolResponse_1.default, Object.assign({}, toolResponse)), deepThinking && (0, jsx_runtime_1.jsx)(DeepThinking_1.default, Object.assign({}, deepThinking)), toolCall && (0, jsx_runtime_1.jsx)(ToolCall_1.default, Object.assign({}, toolCall)), !isLoading && sources && (0, jsx_runtime_1.jsx)(SourcesCard_1.default, Object.assign({}, sources, { isCompact: isCompact })), quickStarts && quickStarts.quickStart && ((0, jsx_runtime_1.jsx)(QuickStartTile_1.default, { quickStart: quickStarts.quickStart, onSelectQuickStart: quickStarts.onSelectQuickStart, minuteWord: quickStarts.minuteWord, minuteWordPlural: quickStarts.minuteWordPlural, prerequisiteWord: quickStarts.prerequisiteWord, prerequisiteWordPlural: quickStarts.prerequisiteWordPlural, quickStartButtonAriaLabel: quickStarts.quickStartButtonAriaLabel, isCompact: isCompact })), !isLoading && !isEditable && actions && ((0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: Array.isArray(actions) ? ((0, jsx_runtime_1.jsx)("div", { className: (0, react_styles_1.css)('pf-chatbot__response-actions-groups', showActionsOnInteraction && 'pf-m-visible-interaction'), children: actions.map((actionGroup, index) => ((0, jsx_runtime_1.jsx)(ResponseActions_1.default, { actions: actionGroup.actions || actionGroup, persistActionSelection: persistActionSelection || actionGroup.persistActionSelection, useFilledIconsOnClick: useFilledIconsOnClick }, index))) })) : ((0, jsx_runtime_1.jsx)(ResponseActions_1.default, { actions: actions, persistActionSelection: persistActionSelection, useFilledIconsOnClick: useFilledIconsOnClick, showActionsOnInteraction: showActionsOnInteraction })) })), userFeedbackForm && ((0, jsx_runtime_1.jsx)(UserFeedback_1.default, Object.assign({}, userFeedbackForm, { timestamp: dateString, isCompact: isCompact }))), userFeedbackComplete && ((0, jsx_runtime_1.jsx)(UserFeedbackComplete_1.default, Object.assign({}, userFeedbackComplete, { timestamp: dateString, isCompact: isCompact }))), !isLoading && quickResponses && ((0, jsx_runtime_1.jsx)(QuickResponse_1.default, { quickResponses: quickResponses, quickResponseContainerProps: quickResponseContainerProps, isCompact: isCompact }))] }), attachments && ((0, jsx_runtime_1.jsx)("div", { className: "pf-chatbot__message-attachments-container", children: attachments.map((attachment) => {
|
|
71
71
|
var _a;
|
|
72
72
|
return ((0, jsx_runtime_1.jsx)("div", { className: "pf-chatbot__message-attachment", children: (0, jsx_runtime_1.jsx)(FileDetailsLabel_1.default, { fileName: attachment.name, fileId: attachment.id, onClose: attachment.onClose, onClick: attachment.onClick, isLoading: attachment.isLoading, closeButtonAriaLabel: attachment.closeButtonAriaLabel, languageTestId: attachment.languageTestId, spinnerTestId: attachment.spinnerTestId, variant: isPrimary ? 'outline' : undefined }) }, (_a = attachment.id) !== null && _a !== void 0 ? _a : attachment.name));
|
|
73
73
|
}) })), !isLoading && endContent && (0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: endContent })] })) })] })] })));
|
|
@@ -1041,4 +1041,76 @@ describe('Message', () => {
|
|
|
1041
1041
|
expect(react_2.screen.getByText('ThumbsUpIcon')).toBeInTheDocument();
|
|
1042
1042
|
expect(react_2.screen.queryByText('OutlinedThumbsUpIcon')).not.toBeInTheDocument();
|
|
1043
1043
|
}));
|
|
1044
|
+
it('should apply pf-m-visible-interaction class to response actions when showActionsOnInteraction is true', () => {
|
|
1045
|
+
(0, react_2.render)((0, jsx_runtime_1.jsx)(Message_1.default, { avatar: "./img", role: "bot", name: "Bot", content: "Hi", showActionsOnInteraction: true, actions: {
|
|
1046
|
+
positive: { onClick: jest.fn() }
|
|
1047
|
+
} }));
|
|
1048
|
+
const responseContainer = react_2.screen
|
|
1049
|
+
.getByRole('button', { name: 'Good response' })
|
|
1050
|
+
.closest('.pf-chatbot__response-actions');
|
|
1051
|
+
expect(responseContainer).toHaveClass('pf-m-visible-interaction');
|
|
1052
|
+
});
|
|
1053
|
+
it('should not apply pf-m-visible-interaction class to response actions when showActionsOnInteraction is false', () => {
|
|
1054
|
+
(0, react_2.render)((0, jsx_runtime_1.jsx)(Message_1.default, { avatar: "./img", role: "bot", name: "Bot", content: "Hi", showActionsOnInteraction: false, actions: {
|
|
1055
|
+
positive: { onClick: jest.fn() }
|
|
1056
|
+
} }));
|
|
1057
|
+
const responseContainer = react_2.screen
|
|
1058
|
+
.getByRole('button', { name: 'Good response' })
|
|
1059
|
+
.closest('.pf-chatbot__response-actions');
|
|
1060
|
+
expect(responseContainer).not.toHaveClass('pf-m-visible-interaction');
|
|
1061
|
+
});
|
|
1062
|
+
it('should not apply pf-m-visible-interaction class to response actions by default', () => {
|
|
1063
|
+
(0, react_2.render)((0, jsx_runtime_1.jsx)(Message_1.default, { avatar: "./img", role: "bot", name: "Bot", content: "Hi", actions: {
|
|
1064
|
+
positive: { onClick: jest.fn() }
|
|
1065
|
+
} }));
|
|
1066
|
+
const responseContainer = react_2.screen
|
|
1067
|
+
.getByRole('button', { name: 'Good response' })
|
|
1068
|
+
.closest('.pf-chatbot__response-actions');
|
|
1069
|
+
expect(responseContainer).not.toHaveClass('pf-m-visible-interaction');
|
|
1070
|
+
});
|
|
1071
|
+
it('should apply pf-m-visible-interaction class to grouped actions container when showActionsOnInteraction is true', () => {
|
|
1072
|
+
(0, react_2.render)((0, jsx_runtime_1.jsx)(Message_1.default, { avatar: "./img", role: "bot", name: "Bot", content: "Hi", showActionsOnInteraction: true, actions: [
|
|
1073
|
+
{
|
|
1074
|
+
positive: { onClick: jest.fn() },
|
|
1075
|
+
negative: { onClick: jest.fn() }
|
|
1076
|
+
},
|
|
1077
|
+
{
|
|
1078
|
+
copy: { onClick: jest.fn() }
|
|
1079
|
+
}
|
|
1080
|
+
] }));
|
|
1081
|
+
const responseContainer = react_2.screen
|
|
1082
|
+
.getByRole('button', { name: 'Good response' })
|
|
1083
|
+
.closest('.pf-chatbot__response-actions-groups');
|
|
1084
|
+
expect(responseContainer).toHaveClass('pf-m-visible-interaction');
|
|
1085
|
+
});
|
|
1086
|
+
it('should not apply pf-m-visible-interaction class to grouped actions container when showActionsOnInteraction is false', () => {
|
|
1087
|
+
(0, react_2.render)((0, jsx_runtime_1.jsx)(Message_1.default, { avatar: "./img", role: "bot", name: "Bot", content: "Hi", showActionsOnInteraction: false, actions: [
|
|
1088
|
+
{
|
|
1089
|
+
positive: { onClick: jest.fn() },
|
|
1090
|
+
negative: { onClick: jest.fn() }
|
|
1091
|
+
},
|
|
1092
|
+
{
|
|
1093
|
+
copy: { onClick: jest.fn() }
|
|
1094
|
+
}
|
|
1095
|
+
] }));
|
|
1096
|
+
const responseContainer = react_2.screen
|
|
1097
|
+
.getByRole('button', { name: 'Good response' })
|
|
1098
|
+
.closest('.pf-chatbot__response-actions-groups');
|
|
1099
|
+
expect(responseContainer).not.toHaveClass('pf-m-visible-interaction');
|
|
1100
|
+
});
|
|
1101
|
+
it('should not apply pf-m-visible-interaction class to grouped actions container by default', () => {
|
|
1102
|
+
(0, react_2.render)((0, jsx_runtime_1.jsx)(Message_1.default, { avatar: "./img", role: "bot", name: "Bot", content: "Hi", actions: [
|
|
1103
|
+
{
|
|
1104
|
+
positive: { onClick: jest.fn() },
|
|
1105
|
+
negative: { onClick: jest.fn() }
|
|
1106
|
+
},
|
|
1107
|
+
{
|
|
1108
|
+
copy: { onClick: jest.fn() }
|
|
1109
|
+
}
|
|
1110
|
+
] }));
|
|
1111
|
+
const responseContainer = react_2.screen
|
|
1112
|
+
.getByRole('button', { name: 'Good response' })
|
|
1113
|
+
.closest('.pf-chatbot__response-actions-groups');
|
|
1114
|
+
expect(responseContainer).not.toHaveClass('pf-m-visible-interaction');
|
|
1115
|
+
});
|
|
1044
1116
|
});
|
|
@@ -34,6 +34,8 @@ type ExtendedActionProps = ActionProps & {
|
|
|
34
34
|
* Use this component when passing children to Message to customize its structure.
|
|
35
35
|
*/
|
|
36
36
|
export interface ResponseActionProps {
|
|
37
|
+
/** Additional classes for the response actions container. */
|
|
38
|
+
className?: string;
|
|
37
39
|
/** Props for message actions, such as feedback (positive or negative), copy button, share, and listen */
|
|
38
40
|
actions: Record<string, ExtendedActionProps | undefined> & {
|
|
39
41
|
positive?: ActionProps;
|
|
@@ -50,6 +52,10 @@ export interface ResponseActionProps {
|
|
|
50
52
|
/** When true, automatically swaps to filled icon variants when predefined actions are clicked.
|
|
51
53
|
* Predefined actions will use filled variants (e.g., ThumbsUpIcon) when clicked and outline variants (e.g., OutlinedThumbsUpIcon) when not clicked. */
|
|
52
54
|
useFilledIconsOnClick?: boolean;
|
|
55
|
+
/** Flag indicating whether the actions container is only visible when a message is hovered or an action would receive focus. Note
|
|
56
|
+
* that setting this to true will append tooltips inline instead of the document.body.
|
|
57
|
+
*/
|
|
58
|
+
showActionsOnInteraction?: boolean;
|
|
53
59
|
}
|
|
54
60
|
export declare const ResponseActions: FunctionComponent<ResponseActionProps>;
|
|
55
61
|
export default ResponseActions;
|
|
@@ -20,8 +20,10 @@ const jsx_runtime_1 = require("react/jsx-runtime");
|
|
|
20
20
|
const react_2 = require("react");
|
|
21
21
|
const react_icons_1 = require("@patternfly/react-icons");
|
|
22
22
|
const ResponseActionButton_1 = __importDefault(require("./ResponseActionButton"));
|
|
23
|
-
const
|
|
24
|
-
|
|
23
|
+
const react_styles_1 = require("@patternfly/react-styles");
|
|
24
|
+
const ResponseActions = (_a) => {
|
|
25
|
+
var _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _0, _1, _2, _3, _4;
|
|
26
|
+
var { className, actions, persistActionSelection = false, useFilledIconsOnClick = false, showActionsOnInteraction = false } = _a, props = __rest(_a, ["className", "actions", "persistActionSelection", "useFilledIconsOnClick", "showActionsOnInteraction"]);
|
|
25
27
|
const [activeButton, setActiveButton] = (0, react_2.useState)();
|
|
26
28
|
const [clickStatePersisted, setClickStatePersisted] = (0, react_2.useState)(false);
|
|
27
29
|
const { positive, negative, copy, edit, share, download, listen } = actions, additionalActions = __rest(actions, ["positive", "negative", "copy", "edit", "share", "download", "listen"]);
|
|
@@ -104,10 +106,15 @@ const ResponseActions = ({ actions, persistActionSelection = false, useFilledIco
|
|
|
104
106
|
}
|
|
105
107
|
return iconMap[actionName].outlined;
|
|
106
108
|
};
|
|
107
|
-
|
|
109
|
+
// We want to append the tooltip inline so that hovering the tooltip keeps the actions container visible
|
|
110
|
+
// when showActionsOnInteraction is true. Otherwise hovering the tooltip causes the actions container
|
|
111
|
+
// to disappear but the tooltip will remain visible.
|
|
112
|
+
const getTooltipContainer = () => responseActions.current || document.body;
|
|
113
|
+
const getTooltipProps = (tooltipProps) => (Object.assign(Object.assign({}, (showActionsOnInteraction && { appendTo: getTooltipContainer })), tooltipProps));
|
|
114
|
+
return ((0, jsx_runtime_1.jsxs)("div", Object.assign({ ref: responseActions, className: (0, react_styles_1.css)('pf-chatbot__response-actions', showActionsOnInteraction && 'pf-m-visible-interaction', className) }, props, { children: [positive && ((0, jsx_runtime_1.jsx)(ResponseActionButton_1.default, Object.assign({}, positive, { ariaLabel: (_b = positive.ariaLabel) !== null && _b !== void 0 ? _b : 'Good response', clickedAriaLabel: (_c = positive.ariaLabel) !== null && _c !== void 0 ? _c : 'Good response recorded', onClick: (e) => handleClick(e, 'positive', positive.onClick), className: positive.className, isDisabled: positive.isDisabled, tooltipContent: (_d = positive.tooltipContent) !== null && _d !== void 0 ? _d : 'Good response', clickedTooltipContent: (_e = positive.clickedTooltipContent) !== null && _e !== void 0 ? _e : 'Good response recorded', tooltipProps: getTooltipProps(positive.tooltipProps), icon: getIcon('positive'), isClicked: activeButton === 'positive', ref: positive.ref, "aria-expanded": positive['aria-expanded'], "aria-controls": positive['aria-controls'] }))), negative && ((0, jsx_runtime_1.jsx)(ResponseActionButton_1.default, Object.assign({}, negative, { ariaLabel: (_f = negative.ariaLabel) !== null && _f !== void 0 ? _f : 'Bad response', clickedAriaLabel: (_g = negative.ariaLabel) !== null && _g !== void 0 ? _g : 'Bad response recorded', onClick: (e) => handleClick(e, 'negative', negative.onClick), className: negative.className, isDisabled: negative.isDisabled, tooltipContent: (_h = negative.tooltipContent) !== null && _h !== void 0 ? _h : 'Bad response', clickedTooltipContent: (_j = negative.clickedTooltipContent) !== null && _j !== void 0 ? _j : 'Bad response recorded', tooltipProps: getTooltipProps(negative.tooltipProps), icon: getIcon('negative'), isClicked: activeButton === 'negative', ref: negative.ref, "aria-expanded": negative['aria-expanded'], "aria-controls": negative['aria-controls'] }))), copy && ((0, jsx_runtime_1.jsx)(ResponseActionButton_1.default, Object.assign({}, copy, { ariaLabel: (_k = copy.ariaLabel) !== null && _k !== void 0 ? _k : 'Copy', clickedAriaLabel: (_l = copy.ariaLabel) !== null && _l !== void 0 ? _l : 'Copied', onClick: (e) => handleClick(e, 'copy', copy.onClick), className: copy.className, isDisabled: copy.isDisabled, tooltipContent: (_m = copy.tooltipContent) !== null && _m !== void 0 ? _m : 'Copy', clickedTooltipContent: (_o = copy.clickedTooltipContent) !== null && _o !== void 0 ? _o : 'Copied', tooltipProps: getTooltipProps(copy.tooltipProps), icon: (0, jsx_runtime_1.jsx)(react_icons_1.OutlinedCopyIcon, {}), isClicked: activeButton === 'copy', ref: copy.ref, "aria-expanded": copy['aria-expanded'], "aria-controls": copy['aria-controls'] }))), edit && ((0, jsx_runtime_1.jsx)(ResponseActionButton_1.default, Object.assign({}, edit, { ariaLabel: (_p = edit.ariaLabel) !== null && _p !== void 0 ? _p : 'Edit', clickedAriaLabel: (_q = edit.ariaLabel) !== null && _q !== void 0 ? _q : 'Editing', onClick: (e) => handleClick(e, 'edit', edit.onClick), className: edit.className, isDisabled: edit.isDisabled, tooltipContent: (_r = edit.tooltipContent) !== null && _r !== void 0 ? _r : 'Edit ', clickedTooltipContent: (_s = edit.clickedTooltipContent) !== null && _s !== void 0 ? _s : 'Editing', tooltipProps: getTooltipProps(edit.tooltipProps), icon: (0, jsx_runtime_1.jsx)(react_icons_1.PencilAltIcon, {}), isClicked: activeButton === 'edit', ref: edit.ref, "aria-expanded": edit['aria-expanded'], "aria-controls": edit['aria-controls'] }))), share && ((0, jsx_runtime_1.jsx)(ResponseActionButton_1.default, Object.assign({}, share, { ariaLabel: (_t = share.ariaLabel) !== null && _t !== void 0 ? _t : 'Share', clickedAriaLabel: (_u = share.ariaLabel) !== null && _u !== void 0 ? _u : 'Shared', onClick: (e) => handleClick(e, 'share', share.onClick), className: share.className, isDisabled: share.isDisabled, tooltipContent: (_v = share.tooltipContent) !== null && _v !== void 0 ? _v : 'Share', clickedTooltipContent: (_w = share.clickedTooltipContent) !== null && _w !== void 0 ? _w : 'Shared', tooltipProps: getTooltipProps(share.tooltipProps), icon: (0, jsx_runtime_1.jsx)(react_icons_1.ExternalLinkAltIcon, {}), isClicked: activeButton === 'share', ref: share.ref, "aria-expanded": share['aria-expanded'], "aria-controls": share['aria-controls'] }))), download && ((0, jsx_runtime_1.jsx)(ResponseActionButton_1.default, Object.assign({}, download, { ariaLabel: (_x = download.ariaLabel) !== null && _x !== void 0 ? _x : 'Download', clickedAriaLabel: (_y = download.ariaLabel) !== null && _y !== void 0 ? _y : 'Downloaded', onClick: (e) => handleClick(e, 'download', download.onClick), className: download.className, isDisabled: download.isDisabled, tooltipContent: (_z = download.tooltipContent) !== null && _z !== void 0 ? _z : 'Download', clickedTooltipContent: (_0 = download.clickedTooltipContent) !== null && _0 !== void 0 ? _0 : 'Downloaded', tooltipProps: getTooltipProps(download.tooltipProps), icon: (0, jsx_runtime_1.jsx)(react_icons_1.DownloadIcon, {}), isClicked: activeButton === 'download', ref: download.ref, "aria-expanded": download['aria-expanded'], "aria-controls": download['aria-controls'] }))), listen && ((0, jsx_runtime_1.jsx)(ResponseActionButton_1.default, Object.assign({}, listen, { ariaLabel: (_1 = listen.ariaLabel) !== null && _1 !== void 0 ? _1 : 'Listen', clickedAriaLabel: (_2 = listen.ariaLabel) !== null && _2 !== void 0 ? _2 : 'Listening', onClick: (e) => handleClick(e, 'listen', listen.onClick), className: listen.className, isDisabled: listen.isDisabled, tooltipContent: (_3 = listen.tooltipContent) !== null && _3 !== void 0 ? _3 : 'Listen', clickedTooltipContent: (_4 = listen.clickedTooltipContent) !== null && _4 !== void 0 ? _4 : 'Listening', tooltipProps: getTooltipProps(listen.tooltipProps), icon: (0, jsx_runtime_1.jsx)(react_icons_1.VolumeUpIcon, {}), isClicked: activeButton === 'listen', ref: listen.ref, "aria-expanded": listen['aria-expanded'], "aria-controls": listen['aria-controls'] }))), Object.keys(additionalActions).map((action) => {
|
|
108
115
|
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
|
|
109
|
-
return ((0, react_1.createElement)(ResponseActionButton_1.default, Object.assign({}, additionalActions[action], { key: action, ariaLabel: (_a = additionalActions[action]) === null || _a === void 0 ? void 0 : _a.ariaLabel, clickedAriaLabel: (_b = additionalActions[action]) === null || _b === void 0 ? void 0 : _b.clickedAriaLabel, onClick: (e) => { var _a; return handleClick(e, action, (_a = additionalActions[action]) === null || _a === void 0 ? void 0 : _a.onClick); }, className: (_c = additionalActions[action]) === null || _c === void 0 ? void 0 : _c.className, isDisabled: (_d = additionalActions[action]) === null || _d === void 0 ? void 0 : _d.isDisabled, tooltipContent: (_e = additionalActions[action]) === null || _e === void 0 ? void 0 : _e.tooltipContent, tooltipProps: (_f = additionalActions[action]) === null || _f === void 0 ? void 0 : _f.tooltipProps, clickedTooltipContent: (_g = additionalActions[action]) === null || _g === void 0 ? void 0 : _g.clickedTooltipContent, icon: (_h = additionalActions[action]) === null || _h === void 0 ? void 0 : _h.icon, isClicked: activeButton === action, ref: (_j = additionalActions[action]) === null || _j === void 0 ? void 0 : _j.ref, "aria-expanded": (_k = additionalActions[action]) === null || _k === void 0 ? void 0 : _k['aria-expanded'], "aria-controls": (_l = additionalActions[action]) === null || _l === void 0 ? void 0 : _l['aria-controls'] })));
|
|
110
|
-
})] }));
|
|
116
|
+
return ((0, react_1.createElement)(ResponseActionButton_1.default, Object.assign({}, additionalActions[action], { key: action, ariaLabel: (_a = additionalActions[action]) === null || _a === void 0 ? void 0 : _a.ariaLabel, clickedAriaLabel: (_b = additionalActions[action]) === null || _b === void 0 ? void 0 : _b.clickedAriaLabel, onClick: (e) => { var _a; return handleClick(e, action, (_a = additionalActions[action]) === null || _a === void 0 ? void 0 : _a.onClick); }, className: (_c = additionalActions[action]) === null || _c === void 0 ? void 0 : _c.className, isDisabled: (_d = additionalActions[action]) === null || _d === void 0 ? void 0 : _d.isDisabled, tooltipContent: (_e = additionalActions[action]) === null || _e === void 0 ? void 0 : _e.tooltipContent, tooltipProps: getTooltipProps((_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'] })));
|
|
117
|
+
})] })));
|
|
111
118
|
};
|
|
112
119
|
exports.ResponseActions = ResponseActions;
|
|
113
120
|
exports.default = exports.ResponseActions;
|
|
@@ -329,6 +329,34 @@ describe('ResponseActions', () => {
|
|
|
329
329
|
yield user_event_1.default.click(customBtn);
|
|
330
330
|
expect(customBtn).not.toHaveClass('pf-chatbot__button--response-action-clicked');
|
|
331
331
|
}));
|
|
332
|
+
it('should apply pf-m-visible-interaction class when showActionsOnInteraction is true', () => {
|
|
333
|
+
(0, react_1.render)((0, jsx_runtime_1.jsx)(ResponseActions_1.default, { "data-testid": "test-id", actions: {
|
|
334
|
+
positive: { onClick: jest.fn() },
|
|
335
|
+
negative: { onClick: jest.fn() }
|
|
336
|
+
}, showActionsOnInteraction: true }));
|
|
337
|
+
expect(react_1.screen.getByTestId('test-id')).toHaveClass('pf-m-visible-interaction');
|
|
338
|
+
});
|
|
339
|
+
it('should not apply pf-m-visible-interaction class when showActionsOnInteraction is false', () => {
|
|
340
|
+
(0, react_1.render)((0, jsx_runtime_1.jsx)(ResponseActions_1.default, { "data-testid": "test-id", actions: {
|
|
341
|
+
positive: { onClick: jest.fn() },
|
|
342
|
+
negative: { onClick: jest.fn() }
|
|
343
|
+
}, showActionsOnInteraction: false }));
|
|
344
|
+
expect(react_1.screen.getByTestId('test-id')).not.toHaveClass('pf-m-visible-interaction');
|
|
345
|
+
});
|
|
346
|
+
it('should not apply pf-m-visible-interaction class by default', () => {
|
|
347
|
+
(0, react_1.render)((0, jsx_runtime_1.jsx)(ResponseActions_1.default, { "data-testid": "test-id", actions: {
|
|
348
|
+
positive: { onClick: jest.fn() },
|
|
349
|
+
negative: { onClick: jest.fn() }
|
|
350
|
+
} }));
|
|
351
|
+
expect(react_1.screen.getByTestId('test-id')).not.toHaveClass('pf-m-visible-interaction');
|
|
352
|
+
});
|
|
353
|
+
it('should render with custom className', () => {
|
|
354
|
+
(0, react_1.render)((0, jsx_runtime_1.jsx)(ResponseActions_1.default, { "data-testid": "test-id", actions: {
|
|
355
|
+
positive: { onClick: jest.fn() },
|
|
356
|
+
negative: { onClick: jest.fn() }
|
|
357
|
+
}, className: "custom-class" }));
|
|
358
|
+
expect(react_1.screen.getByTestId('test-id')).toHaveClass('custom-class');
|
|
359
|
+
});
|
|
332
360
|
describe('icon swapping with useFilledIconsOnClick', () => {
|
|
333
361
|
it('should render outline icons by default', () => {
|
|
334
362
|
(0, react_1.render)((0, jsx_runtime_1.jsx)(ResponseActions_1.default, { actions: {
|
package/dist/css/main.css
CHANGED
|
@@ -1284,6 +1284,16 @@
|
|
|
1284
1284
|
display: grid;
|
|
1285
1285
|
gap: var(--pf-t--global--spacer--sm);
|
|
1286
1286
|
}
|
|
1287
|
+
.pf-chatbot__message .pf-m-visible-interaction {
|
|
1288
|
+
opacity: 0;
|
|
1289
|
+
transition-timing-function: var(--pf-t--global--motion--timing-function--default);
|
|
1290
|
+
transition-duration: var(--pf-t--global--motion--duration--fade--short);
|
|
1291
|
+
transition-property: opacity;
|
|
1292
|
+
}
|
|
1293
|
+
.pf-chatbot__message:hover .pf-m-visible-interaction,
|
|
1294
|
+
.pf-chatbot__message .pf-m-visible-interaction:focus-within {
|
|
1295
|
+
opacity: 1;
|
|
1296
|
+
}
|
|
1287
1297
|
.pf-chatbot__message .footnotes,
|
|
1288
1298
|
.pf-chatbot__message .pf-chatbot__message-text.footnotes {
|
|
1289
1299
|
padding: var(--pf-t--global--spacer--sm) var(--pf-t--global--spacer--sm) 0 var(--pf-t--global--spacer--sm);
|
package/dist/css/main.css.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sourceRoot":"","sources":["../../src/AttachMenu/AttachMenu.scss","../../src/Chatbot/Chatbot.scss","../../src/ChatbotAlert/ChatbotAlert.scss","../../src/ChatbotContent/ChatbotContent.scss","../../src/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.scss","../../src/ChatbotFooter/ChatbotFootnote.scss","../../src/ChatbotFooter/ChatbotFooter.scss","../../src/ChatbotHeader/ChatbotHeader.scss","../../src/ChatbotModal/ChatbotModal.scss","../../src/ChatbotPopover/ChatbotPopover.scss","../../src/ChatbotToggle/ChatbotToggle.scss","../../src/ChatbotWelcomePrompt/ChatbotWelcomePrompt.scss","../../src/CodeModal/CodeModal.scss","../../src/Compare/Compare.scss","../../src/DeepThinking/DeepThinking.scss","../../src/FileDetails/FileDetails.scss","../../src/FileDetailsLabel/FileDetailsLabel.scss","../../src/FileDropZone/FileDropZone.scss","../../src/FilePreview/FilePreview.scss","../../src/ImagePreview/ImagePreview.scss","../../src/Message/Message.scss","../../src/Message/MessageLoading.scss","../../src/Message/CodeBlockMessage/CodeBlockMessage.scss","../../src/Message/TextMessage/TextMessage.scss","../../src/Message/SuperscriptMessage/SuperscriptMessage.scss","../../src/Message/ImageMessage/ImageMessage.scss","../../src/Message/LinkMessage/LinkMessage.scss","../../src/Message/ListMessage/ListMessage.scss","../../src/Message/TableMessage/TableMessage.scss","../../src/Message/QuickStarts/QuickStartTile.scss","../../src/Message/QuickResponse/QuickResponse.scss","../../src/Message/UserFeedback/UserFeedback.scss","../../src/MessageBar/AttachButton.scss","../../src/MessageBar/MicrophoneButton.scss","../../src/MessageBar/SendButton.scss","../../src/MessageBar/StopButton.scss","../../src/MessageBar/MessageBar.scss","../../src/MessageBox/JumpButton.scss","../../src/MessageBox/MessageBox.scss","../../src/MessageDivider/MessageDivider.scss","../../src/Onboarding/Onboarding.scss","../../src/ResponseActions/ResponseActions.scss","../../src/Settings/Settings.scss","../../src/SourcesCard/SourcesCard.scss","../../src/SourceDetailsMenuItem/SourceDetailsMenuItem.scss","../../src/TermsOfUse/TermsOfUse.scss","../../src/ToolResponse/ToolResponse.scss","../../src/ToolCall/ToolCall.scss","../../src/main.scss"],"names":[],"mappings":";AAAA;EACE;EACA;;;AAGF;AACE;AAsBA;AASA;;AA9BA;EACE;EACA;EACA;EACA;;AAEF;EACE;;AAGF;AACE;;AACA;EACE;EACA;EACA;EACA;EACA;;AAKJ;EACE;;AAGF;EACE;;AAIF;EACE;EACA;;AAGF;EACE;EACA;;AAGF;EACE;EACA;EACA;;AAGF;EACE;;AAGF;EACE;;;ACxDJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,YACE;EAYF;;AAVA;EACE;EACA;EACA;;AAEF;EACE;EACA;;AAQF;EAjCF;IAkCI;IACA;;;AAIF;EAvCF;IAwCI;;;;AAOJ;EAEE;EACA;EAEA;EACA;EACA;EACA;EACA;EACA;EACA;;AAIA;EAfF;IAgBI;;;;AAOJ;EAEE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAMF;EAEE;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;;AAGA;EACE;;AAIF;EAdF;IAeI;;;;AAIJ;EACE;;;AAGF;AAAA;AAAA;EAGE;;;AAMF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAGF;EAdF;IAgBI;;;;AAMF;EACE;;;AAOJ;EACE;;;ACjKF;EACE;EACA;EACA;;;ACAF;EACE;EACA;EACA;EACA;EACA;;AAGA;EARF;IASI;;;AAGF;EACE;;;AAOJ;EAII;AAAA;AAAA;IACE;IACA;;;ACzBJ;EACE;EACA;;AAGF;EACE;EACA;;AAKF;EACE;EACA;EACA;EACA;EACA;;AAEF;EACE;EACA;EACA;;AAEF;EACE;EACA;EACA;EACA;EACA;;AAKA;EACE;EACA;;AAIJ;EACE;;AAKF;EACE;EACA;EAEA;EACA;EACA;;AAEF;EACE;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;EAEA;EACA;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;EAEA;;AAIF;EACE;;AAGF;EACE;;AAGF;EACE;;AAGF;EACE;EACA;EACA;EACA;EACA;EAEA;;AAGF;EACE;;;AAMJ;EACE;EACA;EACA;;AAGA;EACE;EACA;EACA;EACA;EACA;EACA;;AAIF;EACE;EACA;EACA;EACA;EAEA;EACA;EACA;EACA;;AAIF;EACE;EACA;EAEA;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;;AAKA;EACE;EACA;EACA;EACA;EACA;;AAKJ;EACE;EACA;EACA;EACA;EAEA;EACA;EACA;EACA;;AAKA;EACE;;;AASJ;EACE;;;AASF;AAAA;EACE;;AACA;AAAA;EACE;;;AASJ;EACE;;AACA;EACE;EACA;;AAEF;EACE;;;AAUF;AAAA;AAAA;AAAA;EACE;;;AAKN;EACE;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;;;AAKE;EACE;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;;AAIJ;EACE;;AAGF;EACE;EACA;;AAGA;EACE;EACA;EACA;EACA;EACA;EACA;;;ACvSN;EACE;;AAEA;EACE;EACA;;;ACHJ;EACE;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;;AAGJ;EACE;EACA;EACA;EACA;EACA;;;AAMF;EAGI;AAAA;IACE;;EACA;AAAA;IACE;;EAGJ;AAAA;IACE;IACA;IACA;;;AASJ;EACE;;;AAQF;EACE;;;AAIJ;EACE;EACA;;;AAQA;EAIM;AAAA;IACE;;;;AC5EV;EACE;;;AAEF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;;AAEA;EACE;;AAKJ;EACE;EACA;EACA;;AAEA;EACE;;AAGF;EACE;EACA;;AAIJ;EACE;;AAGF;EACE;EACA;EACA;EACA;EACA;;AACA;EACE;EACA;;;AAQN;EAGI;AAAA;IACE;;EAEF;AAAA;IACE;;;AAUJ;AAAA;EACE;;;AAOJ;AAAA;EAEE;EACA;EACA;EACA;EACA;;AAEA;AAAA;EACE;;AAGF;AAAA;AAAA;AAAA;AAAA;AAAA;EAGE;;AAGF;AAAA;AAAA;AAAA;EAEE;EACA;EACA;;AAMA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;EAGE;;;AAOJ;EACE;;;AAOJ;AAAA;EAEE;;;AAGF;EACE;;;AAGF;EACE;;;AAOA;EACE;EACA;;AAGF;EACE;EACA;;;AAIJ;AAAA;EAEE;EACA;;;AAGF;EACE;;;AAQA;EAGI;AAAA;IACE;;;;AClLR;EACE;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAGF;EACE;EACA;EACA;;AAIF;EACE;;;AAOJ;EACE;AAAA;IAEE;IACA;IACA;IACA;IACA;IACA;IACA;;;AAGJ;EACE;AAAA;IAEE;IACA;IACA;IACA;IACA;IACA;IACA;;;AAOJ;EACE;;;AAMF;EACE;EACA;EACA;EACA;EACA;EACA;;;AAQE;EACE;;;AAQN;EACE;;;AAOA;EACE;;AAGF;EACE;EACA;;;ACpGF;EACE;;AAMA;EACE;;AAEF;EACE;;AAEF;EACE;;AAIF;EACE;EACA;;AAEF;EACE;;;ACxBN;EACE;EACA;EACA;EACA;EACA;EACA;;AAEA;EAEE;;AAGF;EACE;;AAIF;EACE;EACA;;;AAIJ;EACE;EACA;EACA;;;AC3BF;EACE;EACA;EACA;EACA;;AAEA;EACE;EACA;;AAGF;EACE;;AAGF;EACE;;AAGF;EACE;EACA;EACA;;AAGF;EACE;EACA;EACA;;;AAIJ;EACE;EACA;;AAEA;EACE;;;AAOJ;EAIM;AAAA;IACE;IACA;;;ACpDN;EACE;EACA;EACA;EACA;EACA;;AAEF;EACE;EACA;AACA;EACA;EACA;;AAEF;EACE;;AAEF;EACE;EACA;;AAEF;EACE;;AAEF;EACE;EACA;EACA;AAAA;AAAA;EAGA;EACA;;AAEF;EACE;EACA;;AAEF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAEF;EACE;;AAEF;EACE;EACA;EACA;;AAEF;EACE;;AAEF;EACE;EACA;;AAEF;EACE;;AAGA;EACE;;;AAUF;EACE;EACA;;;AAKN;EACE;;;AAGF;EACE;;;AAIA;EACE;;;AC9FJ;EACE;EACA;EACA;EACA;;;AAEF;EACE;;AAEA;EACE;EACA;EACA;;;AAGJ;EACE;EACA;EACA;;AAEA;EALF;IAMI;;;AAGF;EACE;;AAEA;EAHF;IAII;;;;AAKN;EACE;;AAEA;EACE;;AAGF;EACE;;AAIA;EADF;IAEI;;;;AAIN;EACE;;AAEA;EAHF;IAII;;;;AAIJ;EACE;EACA;EACA;EACA;EACA;EACA;;AAEA;EARF;IASI;IACA;IACA;;;;ACrEJ;EACE;EACA;;;AAGF;EACE;;;AAGF;EACE;EACA;EACA;;;AAGF;EACE;EACA;EACA;;;AAGF;EACE;;;ACtBF;EACE;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;;;AAGF;EACE;EACA;EACA;;;AAGF;EACE;;;AAGF;EACE;;;AAIF;EACE;EACA;EACA;EACA;EACA;;;ACjCF;EACE;EACA;EACA;EACA;;;AAGF;EACE;EAEA;EACA;EACA;;AACA;EACE;;AAGF;AAAA;EAEE;EACA;;;AAIJ;EACE;EACA;EACA;;AAEA;EACE;;;AAKF;EACE;;AAGF;EACE;;;AAIJ;AAAA;EAEE;EACA;;AAEA;AAAA;EACE;;;AAKF;EACE;;;AAMF;AAAA;EACE;;;AC/DJ;EACE;EACA;;;AAGF;EACE;EACA;EACA;;AAGA;EANF;IAOI;;;;AAIJ;EACE;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAIJ;AACA;EACE;EACA;EACA;EACA;;;AAME;EADF;IAEI;IACA;IACA;;EAEA;IACE;;;;ACnDR;EACE;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;;;AAGF;EACE;EACA;;;AAEF;EACE;EACA;;;ACpBF;EACE;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;;AAEF;EACE;;;AAIJ;EACE;;;AAGF;EACE;;;AAGF;EACE;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAIA;AAAA;EACE;;AAGJ;EACE;EACA;;AAKA;AAAA;EACE;;AAGJ;EACE;;;ACvDJ;EACE;EACA;EACA;EACA;;AAIA;EACE;EACA;EACA;EACA;EACA;;AAGF;EAKE;;AAJA;EACE;EACA;;AAOJ;EACE;EACA;;AAKF;EACE;EACA;EACA;EACA;;AAKF;EACE;EACA;EACA;;AAGA;EACE;EAQA;EACA;;AAIF;EACE;EACA;;AAIF;EACE;;AAEF;EACE;;AAMJ;EACE;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;;AAIF;AAAA;EAEE;EACA;EACA;;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;EAME;EACA;EACA;EACA;EACA;EACA;;AAEF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;EAKE;;AAEF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;EAQE;;AAIJ;EACE;;AAIF;EACE;;AAEA;EACE;;;AAON;EACE;EACA;EACA;;;AAGF;EACE;;;ACzJF;EACE;EACA;EACA;EACA;EAEA;;AAGA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEF;EAEE;EACA;EACA;EACA;;AAEF;EACE;EACA;EACA;EACA;EACA;EACA;;AAEF;EACE;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;IACE;;EAEF;IAEE;;;AAIJ;EACE;;;ACtDJ;EACE;EACA;EACA;EACA;;AAGA;EACE;EACA;;AAIF;EACE;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAGF;EACE;EACA;;AAIF;EACE;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;;AAEA;EAEE;;AAMN;EACE;EACA;EACA;EACA;EACA;;AAEA;AAAA;EAEE;EACA;EACA;;AAEF;EACE;EACA;EACA;;AAGF;EACE;EACA;;AAIJ;EACE;;;AAIJ;EACE;EAEA;EACA;EACA;EAEA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;;AAKF;EACE;EACA;;;ACrGJ;EACE;;AAGE;EACE;;;AAMN;EACE;EACA;EACA;EACA;;AAEA;EACE;;AAGF;AAAA;AAAA;AAAA;AAAA;EAKE;;AAGF;EACE;EACA;;AAKF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAIA;EACE;;AAIJ;EACE;;AAEF;EACE;EACA;;;AAUJ;EAIE;;;AAIF;EAKE;;;AAIA;EACE;;;AAKF;EACE;EACA;EACA;EACA;;AACA;EACE;;AAGF;AAAA;AAAA;AAAA;AAAA;EAKE;;AAIJ;EACE;;AAGF;EACE;EACA;;;AASF;EACE;;AACA;EACE;;AAGF;AAAA;AAAA;AAAA;AAAA;EAKE;;AAGF;EACE;EACA;;;AC/IN;EACE;EACA;;AACA;EACE;EACA;;;AJmKF;EACE;EACA;;AAEA;EACE;;AAIJ;EACE;;AAIA;EACE;EACA;;AAIJ;EACE;;;AE1LJ;EACE;EACA;EACA;EACA;;AAGA;EACE;EACA;;AAIF;EACE;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAGF;EACE;EACA;;AAIF;EACE;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;;AAEA;EAEE;;AAMN;EACE;EACA;EACA;EACA;EACA;;AAEA;AAAA;EAEE;EACA;EACA;;AAEF;EACE;EACA;EACA;;AAGF;EACE;EACA;;AAIJ;EACE;;;AAIJ;EACE;EAEA;EACA;EACA;EAEA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;;AAKF;EACE;EACA;;;AGzGJ;EACE;EACA;EACA;EACA;EAGA;;;ACNA;EACE;;;AHEJ;EACE;;AAGE;EACE;;;AAMN;EACE;EACA;EACA;EACA;;AAEA;EACE;;AAGF;AAAA;AAAA;AAAA;AAAA;EAKE;;AAGF;EACE;EACA;;AAKF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAIA;EACE;;AAIJ;EACE;;AAEF;EACE;EACA;;;AAUJ;EAIE;;;AAIF;EAKE;;;AAIA;EACE;;;AAKF;EACE;EACA;EACA;EACA;;AACA;EACE;;AAGF;AAAA;AAAA;AAAA;AAAA;EAKE;;AAIJ;EACE;;AAGF;EACE;EACA;;;AASF;EACE;;AACA;EACE;;AAGF;AAAA;AAAA;AAAA;AAAA;EAKE;;AAGF;EACE;EACA;;;AI3IN;AAAA;EAEE;EACA;EACA;;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;EAGE;;AAIA;AAAA;AAAA;AAAA;AAAA;AAAA;EAGE;;;AAMJ;AAAA;EAEE;EACA;EACA;;AAGA;AAAA;EACE;;AAMF;EACE;EACA;;AAIJ;EACE;;;AC/CJ;EACE;EACA;EACA;EAEA;;AAEA;EACE;;AAGF;EACE;;AAGF;EACE;;AAGF;EACE;EACA;;AAGF;EACE;;AAIA;AAAA;AAAA;AAAA;AAAA;AAAA;EAME;;;APhCN;EACE;EACA;EACA;EACA;EAEA;;AAGA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEF;EAEE;EACA;EACA;EACA;;AAEF;EACE;EACA;EACA;EACA;EACA;EACA;;AAEF;EACE;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;IACE;;EAEF;IAEE;;;AAIJ;EACE;;;AQzDJ;EACE;EACA;;AAEA;EAJF;IAKI;IACA;;;AAKA;EACE;;;AAOF;EACE;;;AClBF;EACE;;AAGF;EALF;IAMI;;;AAGF;EATF;IAUI;;;AAKF;EACE;EACA;;AAIJ;AAAA;EAEE;EACA;;AAIF;EACE;EACA;EACA;;;AC/BJ;EACE;EAEA;EACA;;;AAIF;EACE;EACA;EACA;EACA;EACA;;;AAEF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;;AAEF;EACE;EACA;EACA;;;AAEF;EACE;EACA;EACA;EACA;;;AAKA;EACE;;;AAGJ;EACE;EACA;EACA;EACA;;;AAGF;EACE;;;AAGF;EACE;;;AAIF;EACE;EACA;EACA;EACA;;;AAIF;EACE;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAEA;EACE;;AAGF;EACE;;;AAMJ;EACE;;AAGF;EACE;;AAIA;EACE;;;AC/FN;EACE;EACA;EACA;EACA;;AAEA;EACE;;AAKA;EACE;;AAIJ;EAEE;;AAEA;EACE;;AAKA;EACE;;;AASR;EACE;EACA;EACA;;;ACxCF;EACE;EACA;EACA;EACA;;AAEA;EACE;;AAMA;EACE;;AAKJ;EACE;EACA;;AAGA;EACE;;AAKA;EACE;;;AAMR;EACE;IACE;;EAEF;IACE;;;AAOJ;EACE;EACA;EACA;;;ACpDF;EACE;EACA;EACA;EACA;;AAEA;EACE;;AAGF;EAEE;EACA;;AAEA;EACE;;;AAMJ;EACE;;AACA;EACE;;AAIJ;EACE;EACA;;AAGF;AAAA;EAEE;;;AAIJ;EACE;IACE;IACA;;EAEF;IACE;IACA;;;AAOJ;EACE;EACA;EACA;;;ACzDF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAGF;EACE;;AAGF;EACE;;AAEA;EACE;;AAKA;EACE;;;AASR;EACE;EACA;EACA;;;ACjCF;EACE;EACA;EAEA;EACA;EAEA;EACA;EACA;EACA;EACA;EACA;EACA;EAEA;EACA;EAEA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA,YACE;;AAKF;EACE;;AAKF;EACE;EACA;;AAKF;EACE;EACA;;AAIJ;EACE;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;;AAIJ;EACE;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;;;AAIJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAEF;EACE;EACA;EACA;EACA;EACA;;AAEF;EACE;;;AAIJ;EACE;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;;;AAGF;EACE;IACE;IACA;;;AAKF;EACE;IACE;IACA;;;;AAQN;EACE;EACA;;AAEA;EACE;;;AAKF;AAAA;EAEE;EACA;;;AAOJ;EACE;;;AAQE;EACE;;;ACrLN;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,YACE;EAIF;;AAEA;EACE;;AAGF;EAEE;EACA;EACA;;AAGF;EACE;;AAGF;EACE;;AAIF;EA3CF;IA4CI;;;;AC9CJ;EACE;EACA;EACA;EACA;EACA;EACA;;AAIA;EAVF;IAWI;;;AAGF;EAdF;IAeI;;;;AAIJ;EACE;;;AAGF;EAII;AAAA;AAAA;IACE;IACA;;;AAMJ;EACE;;;ACnCJ;EACE;EACA;;AAEA;AAAA;EAEE;EACA;;AAGF;EACE;EACA;EACA;EACA;;AAEA;EACE;EACA;;AAKF;EACE;EACA;EAEA;;AAGF;EACE;;AAKF;AAAA;EAEE;;;AFrCN;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,YACE;EAIF;;AAEA;EACE;;AAGF;EAEE;EACA;EACA;;AAGF;EACE;;AAGF;EACE;;AAIF;EA3CF;IA4CI;;;;AGhDJ;EACE;;AAEA;EACE;;AAGF;EACE;EACA;EACA;EACA;;AAGF;EACE;EACA;;AAGF;EACE;EACA;EACA;;AAGF;EACE;;AAGF;EACE;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;;AAIJ;EACE;EACA;EACA;;AAGF;EACE;;AAIF;EACE;IACE;IACA;;;;AASF;AAAA;AAAA;EACE;EACA;;;AAKN;AAAA;EAGE;;AAEA;AAAA;EACE;;;AAKF;EACE;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;;AAGF;EACE;EACA;;;AClGJ;EACE;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAEF;EACE;EACA;;;AAMJ;AAAA;EAEE;;;AAIJ;EACE;EACA;EACA;EACA;;AAEA;EACE;;;AAIJ;EACE;EACA;;;AC5CF;EACE;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;;;AAGF;EACE;EACA;EACA;EACA;;;AAIA;EACE;EACA;;;AAIJ;EACE;;;AC3CF;AAAA;EAEE;EACA;EACA;EACA;;AAEA;AAAA;EACE;;;AAKF;EACE;EACA;EACA;;;AAKF;EACE;EACA;EACA;EACA;;;AAIJ;EACE;;;AAGF;EACE;;;AAGF;AAAA;EAEE;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;;;AAGF;EACE;EACA;;AAEA;EACE;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAIA;AAAA;EACE;;AAGJ;EACE;EACA;;AAKA;AAAA;EACE;;AAGJ;EACE;;;AAON;EACE;EACA;;;AChHJ;EACE;EACA;EACA;;;AAGF;EACE;EACA;;;AAGF;EACE;;;AAIF;EACE;EACA;;;AAGA;EACE;;;AAIJ;EACE;;;AAGF;EACE;;;AC9BA;EACE;;AAEA;EACE;EACA;EACA;EACA;EACA;;AAEF;EACE;;AAIJ;EACE;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;;AAGF;EACE;;AAGF;EACE;EACA;EACA;EACA;;AAIF;EACE;IACE;IACA;;;;AAKN;AAAA;EAGE;;AAGE;AAAA;EACE;;AAIJ;AAAA;EACE;;;AAKF;EACE;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;;AAGF;EACE;EACA;;;ACnFJ;EACE;EACA;;;AAGF;EACE;;;AAGF;EACE;EACA;EACA;;;AAGF;EACE;EACA;EACA;;;AAGF;EACE;EACA;;;AAGF;EACE;EACA;EACA;EACA;;AAEA;EACE;;;AAIJ;EACE;;;AAIA;EACE;;;AC3CJ;EACE;EACA;EAEA;EACA;;AAEA;EACE;EACA;EACA;;AAIA;EACE;EACA;EACA;;AAIJ;EACE;;AAGF;EACE;;AAEA;EACE;;AAIJ;EACE;;;ACWJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA","file":"main.css"}
|
|
1
|
+
{"version":3,"sourceRoot":"","sources":["../../src/AttachMenu/AttachMenu.scss","../../src/Chatbot/Chatbot.scss","../../src/ChatbotAlert/ChatbotAlert.scss","../../src/ChatbotContent/ChatbotContent.scss","../../src/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.scss","../../src/ChatbotFooter/ChatbotFootnote.scss","../../src/ChatbotFooter/ChatbotFooter.scss","../../src/ChatbotHeader/ChatbotHeader.scss","../../src/ChatbotModal/ChatbotModal.scss","../../src/ChatbotPopover/ChatbotPopover.scss","../../src/ChatbotToggle/ChatbotToggle.scss","../../src/ChatbotWelcomePrompt/ChatbotWelcomePrompt.scss","../../src/CodeModal/CodeModal.scss","../../src/Compare/Compare.scss","../../src/DeepThinking/DeepThinking.scss","../../src/FileDetails/FileDetails.scss","../../src/FileDetailsLabel/FileDetailsLabel.scss","../../src/FileDropZone/FileDropZone.scss","../../src/FilePreview/FilePreview.scss","../../src/ImagePreview/ImagePreview.scss","../../src/Message/Message.scss","../../src/Message/MessageLoading.scss","../../src/Message/CodeBlockMessage/CodeBlockMessage.scss","../../src/Message/TextMessage/TextMessage.scss","../../src/Message/SuperscriptMessage/SuperscriptMessage.scss","../../src/Message/ImageMessage/ImageMessage.scss","../../src/Message/LinkMessage/LinkMessage.scss","../../src/Message/ListMessage/ListMessage.scss","../../src/Message/TableMessage/TableMessage.scss","../../src/Message/QuickStarts/QuickStartTile.scss","../../src/Message/QuickResponse/QuickResponse.scss","../../src/Message/UserFeedback/UserFeedback.scss","../../src/MessageBar/AttachButton.scss","../../src/MessageBar/MicrophoneButton.scss","../../src/MessageBar/SendButton.scss","../../src/MessageBar/StopButton.scss","../../src/MessageBar/MessageBar.scss","../../src/MessageBox/JumpButton.scss","../../src/MessageBox/MessageBox.scss","../../src/MessageDivider/MessageDivider.scss","../../src/Onboarding/Onboarding.scss","../../src/ResponseActions/ResponseActions.scss","../../src/Settings/Settings.scss","../../src/SourcesCard/SourcesCard.scss","../../src/SourceDetailsMenuItem/SourceDetailsMenuItem.scss","../../src/TermsOfUse/TermsOfUse.scss","../../src/ToolResponse/ToolResponse.scss","../../src/ToolCall/ToolCall.scss","../../src/main.scss"],"names":[],"mappings":";AAAA;EACE;EACA;;;AAGF;AACE;AAsBA;AASA;;AA9BA;EACE;EACA;EACA;EACA;;AAEF;EACE;;AAGF;AACE;;AACA;EACE;EACA;EACA;EACA;EACA;;AAKJ;EACE;;AAGF;EACE;;AAIF;EACE;EACA;;AAGF;EACE;EACA;;AAGF;EACE;EACA;EACA;;AAGF;EACE;;AAGF;EACE;;;ACxDJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,YACE;EAYF;;AAVA;EACE;EACA;EACA;;AAEF;EACE;EACA;;AAQF;EAjCF;IAkCI;IACA;;;AAIF;EAvCF;IAwCI;;;;AAOJ;EAEE;EACA;EAEA;EACA;EACA;EACA;EACA;EACA;EACA;;AAIA;EAfF;IAgBI;;;;AAOJ;EAEE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAMF;EAEE;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;;AAGA;EACE;;AAIF;EAdF;IAeI;;;;AAIJ;EACE;;;AAGF;AAAA;AAAA;EAGE;;;AAMF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAGF;EAdF;IAgBI;;;;AAMF;EACE;;;AAOJ;EACE;;;ACjKF;EACE;EACA;EACA;;;ACAF;EACE;EACA;EACA;EACA;EACA;;AAGA;EARF;IASI;;;AAGF;EACE;;;AAOJ;EAII;AAAA;AAAA;IACE;IACA;;;ACzBJ;EACE;EACA;;AAGF;EACE;EACA;;AAKF;EACE;EACA;EACA;EACA;EACA;;AAEF;EACE;EACA;EACA;;AAEF;EACE;EACA;EACA;EACA;EACA;;AAKA;EACE;EACA;;AAIJ;EACE;;AAKF;EACE;EACA;EAEA;EACA;EACA;;AAEF;EACE;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;EAEA;EACA;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;EAEA;;AAIF;EACE;;AAGF;EACE;;AAGF;EACE;;AAGF;EACE;EACA;EACA;EACA;EACA;EAEA;;AAGF;EACE;;;AAMJ;EACE;EACA;EACA;;AAGA;EACE;EACA;EACA;EACA;EACA;EACA;;AAIF;EACE;EACA;EACA;EACA;EAEA;EACA;EACA;EACA;;AAIF;EACE;EACA;EAEA;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;;AAKA;EACE;EACA;EACA;EACA;EACA;;AAKJ;EACE;EACA;EACA;EACA;EAEA;EACA;EACA;EACA;;AAKA;EACE;;;AASJ;EACE;;;AASF;AAAA;EACE;;AACA;AAAA;EACE;;;AASJ;EACE;;AACA;EACE;EACA;;AAEF;EACE;;;AAUF;AAAA;AAAA;AAAA;EACE;;;AAKN;EACE;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;;;AAKE;EACE;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;;AAIJ;EACE;;AAGF;EACE;EACA;;AAGA;EACE;EACA;EACA;EACA;EACA;EACA;;;ACvSN;EACE;;AAEA;EACE;EACA;;;ACHJ;EACE;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;;AAGJ;EACE;EACA;EACA;EACA;EACA;;;AAMF;EAGI;AAAA;IACE;;EACA;AAAA;IACE;;EAGJ;AAAA;IACE;IACA;IACA;;;AASJ;EACE;;;AAQF;EACE;;;AAIJ;EACE;EACA;;;AAQA;EAIM;AAAA;IACE;;;;AC5EV;EACE;;;AAEF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;;AAEA;EACE;;AAKJ;EACE;EACA;EACA;;AAEA;EACE;;AAGF;EACE;EACA;;AAIJ;EACE;;AAGF;EACE;EACA;EACA;EACA;EACA;;AACA;EACE;EACA;;;AAQN;EAGI;AAAA;IACE;;EAEF;AAAA;IACE;;;AAUJ;AAAA;EACE;;;AAOJ;AAAA;EAEE;EACA;EACA;EACA;EACA;;AAEA;AAAA;EACE;;AAGF;AAAA;AAAA;AAAA;AAAA;AAAA;EAGE;;AAGF;AAAA;AAAA;AAAA;EAEE;EACA;EACA;;AAMA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;EAGE;;;AAOJ;EACE;;;AAOJ;AAAA;EAEE;;;AAGF;EACE;;;AAGF;EACE;;;AAOA;EACE;EACA;;AAGF;EACE;EACA;;;AAIJ;AAAA;EAEE;EACA;;;AAGF;EACE;;;AAQA;EAGI;AAAA;IACE;;;;AClLR;EACE;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAGF;EACE;EACA;EACA;;AAIF;EACE;;;AAOJ;EACE;AAAA;IAEE;IACA;IACA;IACA;IACA;IACA;IACA;;;AAGJ;EACE;AAAA;IAEE;IACA;IACA;IACA;IACA;IACA;IACA;;;AAOJ;EACE;;;AAMF;EACE;EACA;EACA;EACA;EACA;EACA;;;AAQE;EACE;;;AAQN;EACE;;;AAOA;EACE;;AAGF;EACE;EACA;;;ACpGF;EACE;;AAMA;EACE;;AAEF;EACE;;AAEF;EACE;;AAIF;EACE;EACA;;AAEF;EACE;;;ACxBN;EACE;EACA;EACA;EACA;EACA;EACA;;AAEA;EAEE;;AAGF;EACE;;AAIF;EACE;EACA;;;AAIJ;EACE;EACA;EACA;;;AC3BF;EACE;EACA;EACA;EACA;;AAEA;EACE;EACA;;AAGF;EACE;;AAGF;EACE;;AAGF;EACE;EACA;EACA;;AAGF;EACE;EACA;EACA;;;AAIJ;EACE;EACA;;AAEA;EACE;;;AAOJ;EAIM;AAAA;IACE;IACA;;;ACpDN;EACE;EACA;EACA;EACA;EACA;;AAEF;EACE;EACA;AACA;EACA;EACA;;AAEF;EACE;;AAEF;EACE;EACA;;AAEF;EACE;;AAEF;EACE;EACA;EACA;AAAA;AAAA;EAGA;EACA;;AAEF;EACE;EACA;;AAEF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAEF;EACE;;AAEF;EACE;EACA;EACA;;AAEF;EACE;;AAEF;EACE;EACA;;AAEF;EACE;;AAGA;EACE;;;AAUF;EACE;EACA;;;AAKN;EACE;;;AAGF;EACE;;;AAIA;EACE;;;AC9FJ;EACE;EACA;EACA;EACA;;;AAEF;EACE;;AAEA;EACE;EACA;EACA;;;AAGJ;EACE;EACA;EACA;;AAEA;EALF;IAMI;;;AAGF;EACE;;AAEA;EAHF;IAII;;;;AAKN;EACE;;AAEA;EACE;;AAGF;EACE;;AAIA;EADF;IAEI;;;;AAIN;EACE;;AAEA;EAHF;IAII;;;;AAIJ;EACE;EACA;EACA;EACA;EACA;EACA;;AAEA;EARF;IASI;IACA;IACA;;;;ACrEJ;EACE;EACA;;;AAGF;EACE;;;AAGF;EACE;EACA;EACA;;;AAGF;EACE;EACA;EACA;;;AAGF;EACE;;;ACtBF;EACE;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;;;AAGF;EACE;EACA;EACA;;;AAGF;EACE;;;AAGF;EACE;;;AAIF;EACE;EACA;EACA;EACA;EACA;;;ACjCF;EACE;EACA;EACA;EACA;;;AAGF;EACE;EAEA;EACA;EACA;;AACA;EACE;;AAGF;AAAA;EAEE;EACA;;;AAIJ;EACE;EACA;EACA;;AAEA;EACE;;;AAKF;EACE;;AAGF;EACE;;;AAIJ;AAAA;EAEE;EACA;;AAEA;AAAA;EACE;;;AAKF;EACE;;;AAMF;AAAA;EACE;;;AC/DJ;EACE;EACA;;;AAGF;EACE;EACA;EACA;;AAGA;EANF;IAOI;;;;AAIJ;EACE;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAIJ;AACA;EACE;EACA;EACA;EACA;;;AAME;EADF;IAEI;IACA;IACA;;EAEA;IACE;;;;ACnDR;EACE;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;;;AAGF;EACE;EACA;;;AAEF;EACE;EACA;;;ACpBF;EACE;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;;AAEF;EACE;;;AAIJ;EACE;;;AAGF;EACE;;;AAGF;EACE;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAIA;AAAA;EACE;;AAGJ;EACE;EACA;;AAKA;AAAA;EACE;;AAGJ;EACE;;;ACvDJ;EACE;EACA;EACA;EACA;;AAIA;EACE;EACA;EACA;EACA;EACA;;AAGF;EAKE;;AAJA;EACE;EACA;;AAOJ;EACE;EACA;;AAKF;EACE;EACA;EACA;EACA;;AAKF;EACE;EACA;EACA;;AAGA;EACE;EAQA;EACA;;AAIF;EACE;EACA;;AAIF;EACE;;AAEF;EACE;;AAMJ;EACE;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;;AAGF;EACE;EACA;EACA;EACA;;AAGF;AAAA;EAEE;;AAIF;AAAA;EAEE;EACA;EACA;;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;EAME;EACA;EACA;EACA;EACA;EACA;;AAEF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;EAKE;;AAEF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;EAQE;;AAIJ;EACE;;AAIF;EACE;;AAEA;EACE;;;AAON;EACE;EACA;EACA;;;AAGF;EACE;;;ACrKF;EACE;EACA;EACA;EACA;EAEA;;AAGA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEF;EAEE;EACA;EACA;EACA;;AAEF;EACE;EACA;EACA;EACA;EACA;EACA;;AAEF;EACE;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;IACE;;EAEF;IAEE;;;AAIJ;EACE;;;ACtDJ;EACE;EACA;EACA;EACA;;AAGA;EACE;EACA;;AAIF;EACE;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAGF;EACE;EACA;;AAIF;EACE;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;;AAEA;EAEE;;AAMN;EACE;EACA;EACA;EACA;EACA;;AAEA;AAAA;EAEE;EACA;EACA;;AAEF;EACE;EACA;EACA;;AAGF;EACE;EACA;;AAIJ;EACE;;;AAIJ;EACE;EAEA;EACA;EACA;EAEA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;;AAKF;EACE;EACA;;;ACrGJ;EACE;;AAGE;EACE;;;AAMN;EACE;EACA;EACA;EACA;;AAEA;EACE;;AAGF;AAAA;AAAA;AAAA;AAAA;EAKE;;AAGF;EACE;EACA;;AAKF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAIA;EACE;;AAIJ;EACE;;AAEF;EACE;EACA;;;AAUJ;EAIE;;;AAIF;EAKE;;;AAIA;EACE;;;AAKF;EACE;EACA;EACA;EACA;;AACA;EACE;;AAGF;AAAA;AAAA;AAAA;AAAA;EAKE;;AAIJ;EACE;;AAGF;EACE;EACA;;;AASF;EACE;;AACA;EACE;;AAGF;AAAA;AAAA;AAAA;AAAA;EAKE;;AAGF;EACE;EACA;;;AC/IN;EACE;EACA;;AACA;EACE;EACA;;;AJ+KF;EACE;EACA;;AAEA;EACE;;AAIJ;EACE;;AAIA;EACE;EACA;;AAIJ;EACE;;;AEtMJ;EACE;EACA;EACA;EACA;;AAGA;EACE;EACA;;AAIF;EACE;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAGF;EACE;EACA;;AAIF;EACE;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;;AAEA;EAEE;;AAMN;EACE;EACA;EACA;EACA;EACA;;AAEA;AAAA;EAEE;EACA;EACA;;AAEF;EACE;EACA;EACA;;AAGF;EACE;EACA;;AAIJ;EACE;;;AAIJ;EACE;EAEA;EACA;EACA;EAEA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;;AAKF;EACE;EACA;;;AGzGJ;EACE;EACA;EACA;EACA;EAGA;;;ACNA;EACE;;;AHEJ;EACE;;AAGE;EACE;;;AAMN;EACE;EACA;EACA;EACA;;AAEA;EACE;;AAGF;AAAA;AAAA;AAAA;AAAA;EAKE;;AAGF;EACE;EACA;;AAKF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAIA;EACE;;AAIJ;EACE;;AAEF;EACE;EACA;;;AAUJ;EAIE;;;AAIF;EAKE;;;AAIA;EACE;;;AAKF;EACE;EACA;EACA;EACA;;AACA;EACE;;AAGF;AAAA;AAAA;AAAA;AAAA;EAKE;;AAIJ;EACE;;AAGF;EACE;EACA;;;AASF;EACE;;AACA;EACE;;AAGF;AAAA;AAAA;AAAA;AAAA;EAKE;;AAGF;EACE;EACA;;;AI3IN;AAAA;EAEE;EACA;EACA;;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;EAGE;;AAIA;AAAA;AAAA;AAAA;AAAA;AAAA;EAGE;;;AAMJ;AAAA;EAEE;EACA;EACA;;AAGA;AAAA;EACE;;AAMF;EACE;EACA;;AAIJ;EACE;;;AC/CJ;EACE;EACA;EACA;EAEA;;AAEA;EACE;;AAGF;EACE;;AAGF;EACE;;AAGF;EACE;EACA;;AAGF;EACE;;AAIA;AAAA;AAAA;AAAA;AAAA;AAAA;EAME;;;APhCN;EACE;EACA;EACA;EACA;EAEA;;AAGA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEF;EAEE;EACA;EACA;EACA;;AAEF;EACE;EACA;EACA;EACA;EACA;EACA;;AAEF;EACE;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;IACE;;EAEF;IAEE;;;AAIJ;EACE;;;AQzDJ;EACE;EACA;;AAEA;EAJF;IAKI;IACA;;;AAKA;EACE;;;AAOF;EACE;;;AClBF;EACE;;AAGF;EALF;IAMI;;;AAGF;EATF;IAUI;;;AAKF;EACE;EACA;;AAIJ;AAAA;EAEE;EACA;;AAIF;EACE;EACA;EACA;;;AC/BJ;EACE;EAEA;EACA;;;AAIF;EACE;EACA;EACA;EACA;EACA;;;AAEF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;;AAEF;EACE;EACA;EACA;;;AAEF;EACE;EACA;EACA;EACA;;;AAKA;EACE;;;AAGJ;EACE;EACA;EACA;EACA;;;AAGF;EACE;;;AAGF;EACE;;;AAIF;EACE;EACA;EACA;EACA;;;AAIF;EACE;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAEA;EACE;;AAGF;EACE;;;AAMJ;EACE;;AAGF;EACE;;AAIA;EACE;;;AC/FN;EACE;EACA;EACA;EACA;;AAEA;EACE;;AAKA;EACE;;AAIJ;EAEE;;AAEA;EACE;;AAKA;EACE;;;AASR;EACE;EACA;EACA;;;ACxCF;EACE;EACA;EACA;EACA;;AAEA;EACE;;AAMA;EACE;;AAKJ;EACE;EACA;;AAGA;EACE;;AAKA;EACE;;;AAMR;EACE;IACE;;EAEF;IACE;;;AAOJ;EACE;EACA;EACA;;;ACpDF;EACE;EACA;EACA;EACA;;AAEA;EACE;;AAGF;EAEE;EACA;;AAEA;EACE;;;AAMJ;EACE;;AACA;EACE;;AAIJ;EACE;EACA;;AAGF;AAAA;EAEE;;;AAIJ;EACE;IACE;IACA;;EAEF;IACE;IACA;;;AAOJ;EACE;EACA;EACA;;;ACzDF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAGF;EACE;;AAGF;EACE;;AAEA;EACE;;AAKA;EACE;;;AASR;EACE;EACA;EACA;;;ACjCF;EACE;EACA;EAEA;EACA;EAEA;EACA;EACA;EACA;EACA;EACA;EACA;EAEA;EACA;EAEA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA,YACE;;AAKF;EACE;;AAKF;EACE;EACA;;AAKF;EACE;EACA;;AAIJ;EACE;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;;AAIJ;EACE;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;;;AAIJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAEF;EACE;EACA;EACA;EACA;EACA;;AAEF;EACE;;;AAIJ;EACE;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;;;AAGF;EACE;IACE;IACA;;;AAKF;EACE;IACE;IACA;;;;AAQN;EACE;EACA;;AAEA;EACE;;;AAKF;AAAA;EAEE;EACA;;;AAOJ;EACE;;;AAQE;EACE;;;ACrLN;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,YACE;EAIF;;AAEA;EACE;;AAGF;EAEE;EACA;EACA;;AAGF;EACE;;AAGF;EACE;;AAIF;EA3CF;IA4CI;;;;AC9CJ;EACE;EACA;EACA;EACA;EACA;EACA;;AAIA;EAVF;IAWI;;;AAGF;EAdF;IAeI;;;;AAIJ;EACE;;;AAGF;EAII;AAAA;AAAA;IACE;IACA;;;AAMJ;EACE;;;ACnCJ;EACE;EACA;;AAEA;AAAA;EAEE;EACA;;AAGF;EACE;EACA;EACA;EACA;;AAEA;EACE;EACA;;AAKF;EACE;EACA;EAEA;;AAGF;EACE;;AAKF;AAAA;EAEE;;;AFrCN;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,YACE;EAIF;;AAEA;EACE;;AAGF;EAEE;EACA;EACA;;AAGF;EACE;;AAGF;EACE;;AAIF;EA3CF;IA4CI;;;;AGhDJ;EACE;;AAEA;EACE;;AAGF;EACE;EACA;EACA;EACA;;AAGF;EACE;EACA;;AAGF;EACE;EACA;EACA;;AAGF;EACE;;AAGF;EACE;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;;AAIJ;EACE;EACA;EACA;;AAGF;EACE;;AAIF;EACE;IACE;IACA;;;;AASF;AAAA;AAAA;EACE;EACA;;;AAKN;AAAA;EAGE;;AAEA;AAAA;EACE;;;AAKF;EACE;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;;AAGF;EACE;EACA;;;AClGJ;EACE;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAEF;EACE;EACA;;;AAMJ;AAAA;EAEE;;;AAIJ;EACE;EACA;EACA;EACA;;AAEA;EACE;;;AAIJ;EACE;EACA;;;AC5CF;EACE;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;;;AAGF;EACE;EACA;EACA;EACA;;;AAIA;EACE;EACA;;;AAIJ;EACE;;;AC3CF;AAAA;EAEE;EACA;EACA;EACA;;AAEA;AAAA;EACE;;;AAKF;EACE;EACA;EACA;;;AAKF;EACE;EACA;EACA;EACA;;;AAIJ;EACE;;;AAGF;EACE;;;AAGF;AAAA;EAEE;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;;;AAGF;EACE;EACA;;AAEA;EACE;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAIA;AAAA;EACE;;AAGJ;EACE;EACA;;AAKA;AAAA;EACE;;AAGJ;EACE;;;AAON;EACE;EACA;;;AChHJ;EACE;EACA;EACA;;;AAGF;EACE;EACA;;;AAGF;EACE;;;AAIF;EACE;EACA;;;AAGA;EACE;;;AAIJ;EACE;;;AAGF;EACE;;;AC9BA;EACE;;AAEA;EACE;EACA;EACA;EACA;EACA;;AAEF;EACE;;AAIJ;EACE;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;;AAGF;EACE;;AAGF;EACE;EACA;EACA;EACA;;AAIF;EACE;IACE;IACA;;;;AAKN;AAAA;EAGE;;AAGE;AAAA;EACE;;AAIJ;AAAA;EACE;;;AAKF;EACE;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;;AAGF;EACE;EACA;;;ACnFJ;EACE;EACA;;;AAGF;EACE;;;AAGF;EACE;EACA;EACA;;;AAGF;EACE;EACA;EACA;;;AAGF;EACE;EACA;;;AAGF;EACE;EACA;EACA;EACA;;AAEA;EACE;;;AAIJ;EACE;;;AAIA;EACE;;;AC3CJ;EACE;EACA;EAEA;EACA;;AAEA;EACE;EACA;EACA;;AAIA;EACE;EACA;EACA;;AAIJ;EACE;;AAGF;EACE;;AAEA;EACE;;AAIJ;EACE;;;ACWJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA","file":"main.css"}
|
|
@@ -85,6 +85,10 @@ export interface MessageProps extends Omit<HTMLProps<HTMLDivElement>, 'role'> {
|
|
|
85
85
|
* For finer control of multiple action groups, use persistActionSelection on each group.
|
|
86
86
|
*/
|
|
87
87
|
persistActionSelection?: boolean;
|
|
88
|
+
/** Flag indicating whether the actions container is only visible when a message is hovered or an action would receive focus. Note
|
|
89
|
+
* that setting this to true will append tooltips inline instead of the document.body.
|
|
90
|
+
*/
|
|
91
|
+
showActionsOnInteraction?: boolean;
|
|
88
92
|
/** Sources for message */
|
|
89
93
|
sources?: SourcesCardProps;
|
|
90
94
|
/** Label for the English word "AI," used to tag messages with role "bot" */
|
|
@@ -33,7 +33,7 @@ import ToolCall from '../ToolCall';
|
|
|
33
33
|
import MarkdownContent from '../MarkdownContent';
|
|
34
34
|
import { css } from '@patternfly/react-styles';
|
|
35
35
|
export const MessageBase = (_a) => {
|
|
36
|
-
var { children, role, alignment = 'start', isMetadataVisible = true, content, extraContent, name, avatar, timestamp, isLoading, actions, persistActionSelection, sources, botWord = 'AI', loadingWord = 'Loading message', codeBlockProps, quickResponses, quickResponseContainerProps = { numLabels: 5 }, attachments, hasRoundAvatar = true, avatarProps, quickStarts, userFeedbackForm, userFeedbackComplete, isLiveRegion = true, innerRef, tableProps, openLinkInNewTab = true, additionalRehypePlugins = [], additionalRemarkPlugins = [], linkProps, error, isEditable, editPlaceholder = 'Edit prompt message...', updateWord = 'Update', cancelWord = 'Cancel', onEditUpdate, onEditCancel, inputRef, editFormProps, isCompact, isMarkdownDisabled, reactMarkdownProps, toolResponse, deepThinking, remarkGfmProps, toolCall, hasNoImagesInUserMessages = true, isPrimary, useFilledIconsOnClick } = _a, props = __rest(_a, ["children", "role", "alignment", "isMetadataVisible", "content", "extraContent", "name", "avatar", "timestamp", "isLoading", "actions", "persistActionSelection", "sources", "botWord", "loadingWord", "codeBlockProps", "quickResponses", "quickResponseContainerProps", "attachments", "hasRoundAvatar", "avatarProps", "quickStarts", "userFeedbackForm", "userFeedbackComplete", "isLiveRegion", "innerRef", "tableProps", "openLinkInNewTab", "additionalRehypePlugins", "additionalRemarkPlugins", "linkProps", "error", "isEditable", "editPlaceholder", "updateWord", "cancelWord", "onEditUpdate", "onEditCancel", "inputRef", "editFormProps", "isCompact", "isMarkdownDisabled", "reactMarkdownProps", "toolResponse", "deepThinking", "remarkGfmProps", "toolCall", "hasNoImagesInUserMessages", "isPrimary", "useFilledIconsOnClick"]);
|
|
36
|
+
var { children, role, alignment = 'start', isMetadataVisible = true, content, extraContent, name, avatar, timestamp, isLoading, actions, persistActionSelection, showActionsOnInteraction = false, sources, botWord = 'AI', loadingWord = 'Loading message', codeBlockProps, quickResponses, quickResponseContainerProps = { numLabels: 5 }, attachments, hasRoundAvatar = true, avatarProps, quickStarts, userFeedbackForm, userFeedbackComplete, isLiveRegion = true, innerRef, tableProps, openLinkInNewTab = true, additionalRehypePlugins = [], additionalRemarkPlugins = [], linkProps, error, isEditable, editPlaceholder = 'Edit prompt message...', updateWord = 'Update', cancelWord = 'Cancel', onEditUpdate, onEditCancel, inputRef, editFormProps, isCompact, isMarkdownDisabled, reactMarkdownProps, toolResponse, deepThinking, remarkGfmProps, toolCall, hasNoImagesInUserMessages = true, isPrimary, useFilledIconsOnClick } = _a, props = __rest(_a, ["children", "role", "alignment", "isMetadataVisible", "content", "extraContent", "name", "avatar", "timestamp", "isLoading", "actions", "persistActionSelection", "showActionsOnInteraction", "sources", "botWord", "loadingWord", "codeBlockProps", "quickResponses", "quickResponseContainerProps", "attachments", "hasRoundAvatar", "avatarProps", "quickStarts", "userFeedbackForm", "userFeedbackComplete", "isLiveRegion", "innerRef", "tableProps", "openLinkInNewTab", "additionalRehypePlugins", "additionalRemarkPlugins", "linkProps", "error", "isEditable", "editPlaceholder", "updateWord", "cancelWord", "onEditUpdate", "onEditCancel", "inputRef", "editFormProps", "isCompact", "isMarkdownDisabled", "reactMarkdownProps", "toolResponse", "deepThinking", "remarkGfmProps", "toolCall", "hasNoImagesInUserMessages", "isPrimary", "useFilledIconsOnClick"]);
|
|
37
37
|
const [messageText, setMessageText] = useState(content);
|
|
38
38
|
useEffect(() => {
|
|
39
39
|
setMessageText(content);
|
|
@@ -61,7 +61,7 @@ export const MessageBase = (_a) => {
|
|
|
61
61
|
}
|
|
62
62
|
return (_jsxs(_Fragment, { children: [beforeMainContent && _jsx(_Fragment, { children: beforeMainContent }), error ? _jsx(ErrorMessage, Object.assign({}, error)) : handleMarkdown()] }));
|
|
63
63
|
};
|
|
64
|
-
return (_jsxs("section", Object.assign({ "aria-label": `Message from ${role} - ${dateString}`, className: css(`pf-chatbot__message pf-chatbot__message--${role}`, alignment === 'end' && 'pf-m-end'), "aria-live": isLiveRegion ? 'polite' : undefined, "aria-atomic": isLiveRegion ? false : undefined, ref: innerRef }, props, { children: [avatar && (_jsx(Avatar, Object.assign({ className: `pf-chatbot__message-avatar ${hasRoundAvatar ? 'pf-chatbot__message-avatar--round' : ''} ${avatarClassName ? avatarClassName : ''}`, src: avatar, alt: "" }, avatarProps))), _jsxs("div", { className: "pf-chatbot__message-contents", children: [isMetadataVisible && (_jsxs("div", { className: "pf-chatbot__message-meta", children: [name && (_jsx("span", { className: "pf-chatbot__message-name", children: _jsx(Truncate, { content: name }) })), role === 'bot' && (_jsx(Label, { variant: "outline", isCompact: true, children: botWord })), _jsx(Timestamp, { date: date, children: timestamp })] })), _jsx("div", { className: "pf-chatbot__message-response", children: children ? (_jsx(_Fragment, { children: children })) : (_jsxs(_Fragment, { children: [_jsxs("div", { className: "pf-chatbot__message-and-actions", children: [renderMessage(), afterMainContent && _jsx(_Fragment, { children: afterMainContent }), toolResponse && _jsx(ToolResponse, Object.assign({}, toolResponse)), deepThinking && _jsx(DeepThinking, Object.assign({}, deepThinking)), toolCall && _jsx(ToolCall, Object.assign({}, toolCall)), !isLoading && sources && _jsx(SourcesCard, Object.assign({}, sources, { isCompact: isCompact })), quickStarts && quickStarts.quickStart && (_jsx(QuickStartTile, { quickStart: quickStarts.quickStart, onSelectQuickStart: quickStarts.onSelectQuickStart, minuteWord: quickStarts.minuteWord, minuteWordPlural: quickStarts.minuteWordPlural, prerequisiteWord: quickStarts.prerequisiteWord, prerequisiteWordPlural: quickStarts.prerequisiteWordPlural, quickStartButtonAriaLabel: quickStarts.quickStartButtonAriaLabel, isCompact: isCompact })), !isLoading && !isEditable && actions && (_jsx(_Fragment, { children: Array.isArray(actions) ? (_jsx("div", { className:
|
|
64
|
+
return (_jsxs("section", Object.assign({ "aria-label": `Message from ${role} - ${dateString}`, className: css(`pf-chatbot__message pf-chatbot__message--${role}`, alignment === 'end' && 'pf-m-end'), "aria-live": isLiveRegion ? 'polite' : undefined, "aria-atomic": isLiveRegion ? false : undefined, ref: innerRef }, props, { children: [avatar && (_jsx(Avatar, Object.assign({ className: `pf-chatbot__message-avatar ${hasRoundAvatar ? 'pf-chatbot__message-avatar--round' : ''} ${avatarClassName ? avatarClassName : ''}`, src: avatar, alt: "" }, avatarProps))), _jsxs("div", { className: "pf-chatbot__message-contents", children: [isMetadataVisible && (_jsxs("div", { className: "pf-chatbot__message-meta", children: [name && (_jsx("span", { className: "pf-chatbot__message-name", children: _jsx(Truncate, { content: name }) })), role === 'bot' && (_jsx(Label, { variant: "outline", isCompact: true, children: botWord })), _jsx(Timestamp, { date: date, children: timestamp })] })), _jsx("div", { className: "pf-chatbot__message-response", children: children ? (_jsx(_Fragment, { children: children })) : (_jsxs(_Fragment, { children: [_jsxs("div", { className: "pf-chatbot__message-and-actions", children: [renderMessage(), afterMainContent && _jsx(_Fragment, { children: afterMainContent }), toolResponse && _jsx(ToolResponse, Object.assign({}, toolResponse)), deepThinking && _jsx(DeepThinking, Object.assign({}, deepThinking)), toolCall && _jsx(ToolCall, Object.assign({}, toolCall)), !isLoading && sources && _jsx(SourcesCard, Object.assign({}, sources, { isCompact: isCompact })), quickStarts && quickStarts.quickStart && (_jsx(QuickStartTile, { quickStart: quickStarts.quickStart, onSelectQuickStart: quickStarts.onSelectQuickStart, minuteWord: quickStarts.minuteWord, minuteWordPlural: quickStarts.minuteWordPlural, prerequisiteWord: quickStarts.prerequisiteWord, prerequisiteWordPlural: quickStarts.prerequisiteWordPlural, quickStartButtonAriaLabel: quickStarts.quickStartButtonAriaLabel, isCompact: isCompact })), !isLoading && !isEditable && actions && (_jsx(_Fragment, { children: Array.isArray(actions) ? (_jsx("div", { className: css('pf-chatbot__response-actions-groups', showActionsOnInteraction && 'pf-m-visible-interaction'), children: actions.map((actionGroup, index) => (_jsx(ResponseActions, { actions: actionGroup.actions || actionGroup, persistActionSelection: persistActionSelection || actionGroup.persistActionSelection, useFilledIconsOnClick: useFilledIconsOnClick }, index))) })) : (_jsx(ResponseActions, { actions: actions, persistActionSelection: persistActionSelection, useFilledIconsOnClick: useFilledIconsOnClick, showActionsOnInteraction: showActionsOnInteraction })) })), userFeedbackForm && (_jsx(UserFeedback, Object.assign({}, userFeedbackForm, { timestamp: dateString, isCompact: isCompact }))), userFeedbackComplete && (_jsx(UserFeedbackComplete, Object.assign({}, userFeedbackComplete, { timestamp: dateString, isCompact: isCompact }))), !isLoading && quickResponses && (_jsx(QuickResponse, { quickResponses: quickResponses, quickResponseContainerProps: quickResponseContainerProps, isCompact: isCompact }))] }), attachments && (_jsx("div", { className: "pf-chatbot__message-attachments-container", children: attachments.map((attachment) => {
|
|
65
65
|
var _a;
|
|
66
66
|
return (_jsx("div", { className: "pf-chatbot__message-attachment", children: _jsx(FileDetailsLabel, { fileName: attachment.name, fileId: attachment.id, onClose: attachment.onClose, onClick: attachment.onClick, isLoading: attachment.isLoading, closeButtonAriaLabel: attachment.closeButtonAriaLabel, languageTestId: attachment.languageTestId, spinnerTestId: attachment.spinnerTestId, variant: isPrimary ? 'outline' : undefined }) }, (_a = attachment.id) !== null && _a !== void 0 ? _a : attachment.name));
|
|
67
67
|
}) })), !isLoading && endContent && _jsx(_Fragment, { children: endContent })] })) })] })] })));
|
|
@@ -1036,4 +1036,76 @@ describe('Message', () => {
|
|
|
1036
1036
|
expect(screen.getByText('ThumbsUpIcon')).toBeInTheDocument();
|
|
1037
1037
|
expect(screen.queryByText('OutlinedThumbsUpIcon')).not.toBeInTheDocument();
|
|
1038
1038
|
}));
|
|
1039
|
+
it('should apply pf-m-visible-interaction class to response actions when showActionsOnInteraction is true', () => {
|
|
1040
|
+
render(_jsx(Message, { avatar: "./img", role: "bot", name: "Bot", content: "Hi", showActionsOnInteraction: true, actions: {
|
|
1041
|
+
positive: { onClick: jest.fn() }
|
|
1042
|
+
} }));
|
|
1043
|
+
const responseContainer = screen
|
|
1044
|
+
.getByRole('button', { name: 'Good response' })
|
|
1045
|
+
.closest('.pf-chatbot__response-actions');
|
|
1046
|
+
expect(responseContainer).toHaveClass('pf-m-visible-interaction');
|
|
1047
|
+
});
|
|
1048
|
+
it('should not apply pf-m-visible-interaction class to response actions when showActionsOnInteraction is false', () => {
|
|
1049
|
+
render(_jsx(Message, { avatar: "./img", role: "bot", name: "Bot", content: "Hi", showActionsOnInteraction: false, actions: {
|
|
1050
|
+
positive: { onClick: jest.fn() }
|
|
1051
|
+
} }));
|
|
1052
|
+
const responseContainer = screen
|
|
1053
|
+
.getByRole('button', { name: 'Good response' })
|
|
1054
|
+
.closest('.pf-chatbot__response-actions');
|
|
1055
|
+
expect(responseContainer).not.toHaveClass('pf-m-visible-interaction');
|
|
1056
|
+
});
|
|
1057
|
+
it('should not apply pf-m-visible-interaction class to response actions by default', () => {
|
|
1058
|
+
render(_jsx(Message, { avatar: "./img", role: "bot", name: "Bot", content: "Hi", actions: {
|
|
1059
|
+
positive: { onClick: jest.fn() }
|
|
1060
|
+
} }));
|
|
1061
|
+
const responseContainer = screen
|
|
1062
|
+
.getByRole('button', { name: 'Good response' })
|
|
1063
|
+
.closest('.pf-chatbot__response-actions');
|
|
1064
|
+
expect(responseContainer).not.toHaveClass('pf-m-visible-interaction');
|
|
1065
|
+
});
|
|
1066
|
+
it('should apply pf-m-visible-interaction class to grouped actions container when showActionsOnInteraction is true', () => {
|
|
1067
|
+
render(_jsx(Message, { avatar: "./img", role: "bot", name: "Bot", content: "Hi", showActionsOnInteraction: true, actions: [
|
|
1068
|
+
{
|
|
1069
|
+
positive: { onClick: jest.fn() },
|
|
1070
|
+
negative: { onClick: jest.fn() }
|
|
1071
|
+
},
|
|
1072
|
+
{
|
|
1073
|
+
copy: { onClick: jest.fn() }
|
|
1074
|
+
}
|
|
1075
|
+
] }));
|
|
1076
|
+
const responseContainer = screen
|
|
1077
|
+
.getByRole('button', { name: 'Good response' })
|
|
1078
|
+
.closest('.pf-chatbot__response-actions-groups');
|
|
1079
|
+
expect(responseContainer).toHaveClass('pf-m-visible-interaction');
|
|
1080
|
+
});
|
|
1081
|
+
it('should not apply pf-m-visible-interaction class to grouped actions container when showActionsOnInteraction is false', () => {
|
|
1082
|
+
render(_jsx(Message, { avatar: "./img", role: "bot", name: "Bot", content: "Hi", showActionsOnInteraction: false, actions: [
|
|
1083
|
+
{
|
|
1084
|
+
positive: { onClick: jest.fn() },
|
|
1085
|
+
negative: { onClick: jest.fn() }
|
|
1086
|
+
},
|
|
1087
|
+
{
|
|
1088
|
+
copy: { onClick: jest.fn() }
|
|
1089
|
+
}
|
|
1090
|
+
] }));
|
|
1091
|
+
const responseContainer = screen
|
|
1092
|
+
.getByRole('button', { name: 'Good response' })
|
|
1093
|
+
.closest('.pf-chatbot__response-actions-groups');
|
|
1094
|
+
expect(responseContainer).not.toHaveClass('pf-m-visible-interaction');
|
|
1095
|
+
});
|
|
1096
|
+
it('should not apply pf-m-visible-interaction class to grouped actions container by default', () => {
|
|
1097
|
+
render(_jsx(Message, { avatar: "./img", role: "bot", name: "Bot", content: "Hi", actions: [
|
|
1098
|
+
{
|
|
1099
|
+
positive: { onClick: jest.fn() },
|
|
1100
|
+
negative: { onClick: jest.fn() }
|
|
1101
|
+
},
|
|
1102
|
+
{
|
|
1103
|
+
copy: { onClick: jest.fn() }
|
|
1104
|
+
}
|
|
1105
|
+
] }));
|
|
1106
|
+
const responseContainer = screen
|
|
1107
|
+
.getByRole('button', { name: 'Good response' })
|
|
1108
|
+
.closest('.pf-chatbot__response-actions-groups');
|
|
1109
|
+
expect(responseContainer).not.toHaveClass('pf-m-visible-interaction');
|
|
1110
|
+
});
|
|
1039
1111
|
});
|
|
@@ -34,6 +34,8 @@ type ExtendedActionProps = ActionProps & {
|
|
|
34
34
|
* Use this component when passing children to Message to customize its structure.
|
|
35
35
|
*/
|
|
36
36
|
export interface ResponseActionProps {
|
|
37
|
+
/** Additional classes for the response actions container. */
|
|
38
|
+
className?: string;
|
|
37
39
|
/** Props for message actions, such as feedback (positive or negative), copy button, share, and listen */
|
|
38
40
|
actions: Record<string, ExtendedActionProps | undefined> & {
|
|
39
41
|
positive?: ActionProps;
|
|
@@ -50,6 +52,10 @@ export interface ResponseActionProps {
|
|
|
50
52
|
/** When true, automatically swaps to filled icon variants when predefined actions are clicked.
|
|
51
53
|
* Predefined actions will use filled variants (e.g., ThumbsUpIcon) when clicked and outline variants (e.g., OutlinedThumbsUpIcon) when not clicked. */
|
|
52
54
|
useFilledIconsOnClick?: boolean;
|
|
55
|
+
/** Flag indicating whether the actions container is only visible when a message is hovered or an action would receive focus. Note
|
|
56
|
+
* that setting this to true will append tooltips inline instead of the document.body.
|
|
57
|
+
*/
|
|
58
|
+
showActionsOnInteraction?: boolean;
|
|
53
59
|
}
|
|
54
60
|
export declare const ResponseActions: FunctionComponent<ResponseActionProps>;
|
|
55
61
|
export default ResponseActions;
|
|
@@ -14,8 +14,10 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
14
14
|
import { useEffect, useRef, useState } from 'react';
|
|
15
15
|
import { ExternalLinkAltIcon, VolumeUpIcon, OutlinedThumbsUpIcon, ThumbsUpIcon, OutlinedThumbsDownIcon, ThumbsDownIcon, OutlinedCopyIcon, DownloadIcon, PencilAltIcon } from '@patternfly/react-icons';
|
|
16
16
|
import ResponseActionButton from './ResponseActionButton';
|
|
17
|
-
|
|
18
|
-
|
|
17
|
+
import { css } from '@patternfly/react-styles';
|
|
18
|
+
export const ResponseActions = (_a) => {
|
|
19
|
+
var _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _0, _1, _2, _3, _4;
|
|
20
|
+
var { className, actions, persistActionSelection = false, useFilledIconsOnClick = false, showActionsOnInteraction = false } = _a, props = __rest(_a, ["className", "actions", "persistActionSelection", "useFilledIconsOnClick", "showActionsOnInteraction"]);
|
|
19
21
|
const [activeButton, setActiveButton] = useState();
|
|
20
22
|
const [clickStatePersisted, setClickStatePersisted] = useState(false);
|
|
21
23
|
const { positive, negative, copy, edit, share, download, listen } = actions, additionalActions = __rest(actions, ["positive", "negative", "copy", "edit", "share", "download", "listen"]);
|
|
@@ -98,9 +100,14 @@ export const ResponseActions = ({ actions, persistActionSelection = false, useFi
|
|
|
98
100
|
}
|
|
99
101
|
return iconMap[actionName].outlined;
|
|
100
102
|
};
|
|
101
|
-
|
|
103
|
+
// We want to append the tooltip inline so that hovering the tooltip keeps the actions container visible
|
|
104
|
+
// when showActionsOnInteraction is true. Otherwise hovering the tooltip causes the actions container
|
|
105
|
+
// to disappear but the tooltip will remain visible.
|
|
106
|
+
const getTooltipContainer = () => responseActions.current || document.body;
|
|
107
|
+
const getTooltipProps = (tooltipProps) => (Object.assign(Object.assign({}, (showActionsOnInteraction && { appendTo: getTooltipContainer })), tooltipProps));
|
|
108
|
+
return (_jsxs("div", Object.assign({ ref: responseActions, className: css('pf-chatbot__response-actions', showActionsOnInteraction && 'pf-m-visible-interaction', className) }, props, { children: [positive && (_jsx(ResponseActionButton, Object.assign({}, positive, { ariaLabel: (_b = positive.ariaLabel) !== null && _b !== void 0 ? _b : 'Good response', clickedAriaLabel: (_c = positive.ariaLabel) !== null && _c !== void 0 ? _c : 'Good response recorded', onClick: (e) => handleClick(e, 'positive', positive.onClick), className: positive.className, isDisabled: positive.isDisabled, tooltipContent: (_d = positive.tooltipContent) !== null && _d !== void 0 ? _d : 'Good response', clickedTooltipContent: (_e = positive.clickedTooltipContent) !== null && _e !== void 0 ? _e : 'Good response recorded', tooltipProps: getTooltipProps(positive.tooltipProps), icon: getIcon('positive'), isClicked: activeButton === 'positive', ref: positive.ref, "aria-expanded": positive['aria-expanded'], "aria-controls": positive['aria-controls'] }))), negative && (_jsx(ResponseActionButton, Object.assign({}, negative, { ariaLabel: (_f = negative.ariaLabel) !== null && _f !== void 0 ? _f : 'Bad response', clickedAriaLabel: (_g = negative.ariaLabel) !== null && _g !== void 0 ? _g : 'Bad response recorded', onClick: (e) => handleClick(e, 'negative', negative.onClick), className: negative.className, isDisabled: negative.isDisabled, tooltipContent: (_h = negative.tooltipContent) !== null && _h !== void 0 ? _h : 'Bad response', clickedTooltipContent: (_j = negative.clickedTooltipContent) !== null && _j !== void 0 ? _j : 'Bad response recorded', tooltipProps: getTooltipProps(negative.tooltipProps), icon: getIcon('negative'), isClicked: activeButton === 'negative', ref: negative.ref, "aria-expanded": negative['aria-expanded'], "aria-controls": negative['aria-controls'] }))), copy && (_jsx(ResponseActionButton, Object.assign({}, copy, { ariaLabel: (_k = copy.ariaLabel) !== null && _k !== void 0 ? _k : 'Copy', clickedAriaLabel: (_l = copy.ariaLabel) !== null && _l !== void 0 ? _l : 'Copied', onClick: (e) => handleClick(e, 'copy', copy.onClick), className: copy.className, isDisabled: copy.isDisabled, tooltipContent: (_m = copy.tooltipContent) !== null && _m !== void 0 ? _m : 'Copy', clickedTooltipContent: (_o = copy.clickedTooltipContent) !== null && _o !== void 0 ? _o : 'Copied', tooltipProps: getTooltipProps(copy.tooltipProps), icon: _jsx(OutlinedCopyIcon, {}), isClicked: activeButton === 'copy', ref: copy.ref, "aria-expanded": copy['aria-expanded'], "aria-controls": copy['aria-controls'] }))), edit && (_jsx(ResponseActionButton, Object.assign({}, edit, { ariaLabel: (_p = edit.ariaLabel) !== null && _p !== void 0 ? _p : 'Edit', clickedAriaLabel: (_q = edit.ariaLabel) !== null && _q !== void 0 ? _q : 'Editing', onClick: (e) => handleClick(e, 'edit', edit.onClick), className: edit.className, isDisabled: edit.isDisabled, tooltipContent: (_r = edit.tooltipContent) !== null && _r !== void 0 ? _r : 'Edit ', clickedTooltipContent: (_s = edit.clickedTooltipContent) !== null && _s !== void 0 ? _s : 'Editing', tooltipProps: getTooltipProps(edit.tooltipProps), icon: _jsx(PencilAltIcon, {}), isClicked: activeButton === 'edit', ref: edit.ref, "aria-expanded": edit['aria-expanded'], "aria-controls": edit['aria-controls'] }))), share && (_jsx(ResponseActionButton, Object.assign({}, share, { ariaLabel: (_t = share.ariaLabel) !== null && _t !== void 0 ? _t : 'Share', clickedAriaLabel: (_u = share.ariaLabel) !== null && _u !== void 0 ? _u : 'Shared', onClick: (e) => handleClick(e, 'share', share.onClick), className: share.className, isDisabled: share.isDisabled, tooltipContent: (_v = share.tooltipContent) !== null && _v !== void 0 ? _v : 'Share', clickedTooltipContent: (_w = share.clickedTooltipContent) !== null && _w !== void 0 ? _w : 'Shared', tooltipProps: getTooltipProps(share.tooltipProps), icon: _jsx(ExternalLinkAltIcon, {}), isClicked: activeButton === 'share', ref: share.ref, "aria-expanded": share['aria-expanded'], "aria-controls": share['aria-controls'] }))), download && (_jsx(ResponseActionButton, Object.assign({}, download, { ariaLabel: (_x = download.ariaLabel) !== null && _x !== void 0 ? _x : 'Download', clickedAriaLabel: (_y = download.ariaLabel) !== null && _y !== void 0 ? _y : 'Downloaded', onClick: (e) => handleClick(e, 'download', download.onClick), className: download.className, isDisabled: download.isDisabled, tooltipContent: (_z = download.tooltipContent) !== null && _z !== void 0 ? _z : 'Download', clickedTooltipContent: (_0 = download.clickedTooltipContent) !== null && _0 !== void 0 ? _0 : 'Downloaded', tooltipProps: getTooltipProps(download.tooltipProps), icon: _jsx(DownloadIcon, {}), isClicked: activeButton === 'download', ref: download.ref, "aria-expanded": download['aria-expanded'], "aria-controls": download['aria-controls'] }))), listen && (_jsx(ResponseActionButton, Object.assign({}, listen, { ariaLabel: (_1 = listen.ariaLabel) !== null && _1 !== void 0 ? _1 : 'Listen', clickedAriaLabel: (_2 = listen.ariaLabel) !== null && _2 !== void 0 ? _2 : 'Listening', onClick: (e) => handleClick(e, 'listen', listen.onClick), className: listen.className, isDisabled: listen.isDisabled, tooltipContent: (_3 = listen.tooltipContent) !== null && _3 !== void 0 ? _3 : 'Listen', clickedTooltipContent: (_4 = listen.clickedTooltipContent) !== null && _4 !== void 0 ? _4 : 'Listening', tooltipProps: getTooltipProps(listen.tooltipProps), icon: _jsx(VolumeUpIcon, {}), isClicked: activeButton === 'listen', ref: listen.ref, "aria-expanded": listen['aria-expanded'], "aria-controls": listen['aria-controls'] }))), Object.keys(additionalActions).map((action) => {
|
|
102
109
|
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
|
|
103
|
-
return (_createElement(ResponseActionButton, Object.assign({}, additionalActions[action], { key: action, ariaLabel: (_a = additionalActions[action]) === null || _a === void 0 ? void 0 : _a.ariaLabel, clickedAriaLabel: (_b = additionalActions[action]) === null || _b === void 0 ? void 0 : _b.clickedAriaLabel, onClick: (e) => { var _a; return handleClick(e, action, (_a = additionalActions[action]) === null || _a === void 0 ? void 0 : _a.onClick); }, className: (_c = additionalActions[action]) === null || _c === void 0 ? void 0 : _c.className, isDisabled: (_d = additionalActions[action]) === null || _d === void 0 ? void 0 : _d.isDisabled, tooltipContent: (_e = additionalActions[action]) === null || _e === void 0 ? void 0 : _e.tooltipContent, tooltipProps: (_f = additionalActions[action]) === null || _f === void 0 ? void 0 : _f.tooltipProps, clickedTooltipContent: (_g = additionalActions[action]) === null || _g === void 0 ? void 0 : _g.clickedTooltipContent, icon: (_h = additionalActions[action]) === null || _h === void 0 ? void 0 : _h.icon, isClicked: activeButton === action, ref: (_j = additionalActions[action]) === null || _j === void 0 ? void 0 : _j.ref, "aria-expanded": (_k = additionalActions[action]) === null || _k === void 0 ? void 0 : _k['aria-expanded'], "aria-controls": (_l = additionalActions[action]) === null || _l === void 0 ? void 0 : _l['aria-controls'] })));
|
|
104
|
-
})] }));
|
|
110
|
+
return (_createElement(ResponseActionButton, Object.assign({}, additionalActions[action], { key: action, ariaLabel: (_a = additionalActions[action]) === null || _a === void 0 ? void 0 : _a.ariaLabel, clickedAriaLabel: (_b = additionalActions[action]) === null || _b === void 0 ? void 0 : _b.clickedAriaLabel, onClick: (e) => { var _a; return handleClick(e, action, (_a = additionalActions[action]) === null || _a === void 0 ? void 0 : _a.onClick); }, className: (_c = additionalActions[action]) === null || _c === void 0 ? void 0 : _c.className, isDisabled: (_d = additionalActions[action]) === null || _d === void 0 ? void 0 : _d.isDisabled, tooltipContent: (_e = additionalActions[action]) === null || _e === void 0 ? void 0 : _e.tooltipContent, tooltipProps: getTooltipProps((_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'] })));
|
|
111
|
+
})] })));
|
|
105
112
|
};
|
|
106
113
|
export default ResponseActions;
|
|
@@ -324,6 +324,34 @@ describe('ResponseActions', () => {
|
|
|
324
324
|
yield userEvent.click(customBtn);
|
|
325
325
|
expect(customBtn).not.toHaveClass('pf-chatbot__button--response-action-clicked');
|
|
326
326
|
}));
|
|
327
|
+
it('should apply pf-m-visible-interaction class when showActionsOnInteraction is true', () => {
|
|
328
|
+
render(_jsx(ResponseActions, { "data-testid": "test-id", actions: {
|
|
329
|
+
positive: { onClick: jest.fn() },
|
|
330
|
+
negative: { onClick: jest.fn() }
|
|
331
|
+
}, showActionsOnInteraction: true }));
|
|
332
|
+
expect(screen.getByTestId('test-id')).toHaveClass('pf-m-visible-interaction');
|
|
333
|
+
});
|
|
334
|
+
it('should not apply pf-m-visible-interaction class when showActionsOnInteraction is false', () => {
|
|
335
|
+
render(_jsx(ResponseActions, { "data-testid": "test-id", actions: {
|
|
336
|
+
positive: { onClick: jest.fn() },
|
|
337
|
+
negative: { onClick: jest.fn() }
|
|
338
|
+
}, showActionsOnInteraction: false }));
|
|
339
|
+
expect(screen.getByTestId('test-id')).not.toHaveClass('pf-m-visible-interaction');
|
|
340
|
+
});
|
|
341
|
+
it('should not apply pf-m-visible-interaction class by default', () => {
|
|
342
|
+
render(_jsx(ResponseActions, { "data-testid": "test-id", actions: {
|
|
343
|
+
positive: { onClick: jest.fn() },
|
|
344
|
+
negative: { onClick: jest.fn() }
|
|
345
|
+
} }));
|
|
346
|
+
expect(screen.getByTestId('test-id')).not.toHaveClass('pf-m-visible-interaction');
|
|
347
|
+
});
|
|
348
|
+
it('should render with custom className', () => {
|
|
349
|
+
render(_jsx(ResponseActions, { "data-testid": "test-id", actions: {
|
|
350
|
+
positive: { onClick: jest.fn() },
|
|
351
|
+
negative: { onClick: jest.fn() }
|
|
352
|
+
}, className: "custom-class" }));
|
|
353
|
+
expect(screen.getByTestId('test-id')).toHaveClass('custom-class');
|
|
354
|
+
});
|
|
327
355
|
describe('icon swapping with useFilledIconsOnClick', () => {
|
|
328
356
|
it('should render outline icons by default', () => {
|
|
329
357
|
render(_jsx(ResponseActions, { actions: {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@patternfly/chatbot",
|
|
3
|
-
"version": "6.6.0-prerelease.
|
|
3
|
+
"version": "6.6.0-prerelease.6",
|
|
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",
|
package/patternfly-docs/content/extensions/chatbot/examples/Messages/MessageWithResponseActions.tsx
CHANGED
|
@@ -4,22 +4,43 @@ import Message from '@patternfly/chatbot/dist/dynamic/Message';
|
|
|
4
4
|
import patternflyAvatar from './patternfly_avatar.jpg';
|
|
5
5
|
|
|
6
6
|
export const ResponseActionExample: FunctionComponent = () => (
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
7
|
+
<>
|
|
8
|
+
<Message
|
|
9
|
+
name="Bot"
|
|
10
|
+
role="bot"
|
|
11
|
+
avatar={patternflyAvatar}
|
|
12
|
+
content="I updated your account with those settings. You're ready to set up your first dashboard!"
|
|
13
|
+
actions={{
|
|
14
|
+
// eslint-disable-next-line no-console
|
|
15
|
+
positive: { onClick: () => console.log('Good response') },
|
|
16
|
+
// eslint-disable-next-line no-console
|
|
17
|
+
negative: { onClick: () => console.log('Bad response') },
|
|
18
|
+
// eslint-disable-next-line no-console
|
|
19
|
+
copy: { onClick: () => console.log('Copy') },
|
|
20
|
+
// eslint-disable-next-line no-console
|
|
21
|
+
download: { onClick: () => console.log('Download') },
|
|
22
|
+
// eslint-disable-next-line no-console
|
|
23
|
+
listen: { onClick: () => console.log('Listen') }
|
|
24
|
+
}}
|
|
25
|
+
/>
|
|
26
|
+
<Message
|
|
27
|
+
name="Bot"
|
|
28
|
+
role="bot"
|
|
29
|
+
showActionsOnInteraction
|
|
30
|
+
avatar={patternflyAvatar}
|
|
31
|
+
content="This message has response actions visually hidden until you hover over the message via mouse, or an action would receive focus via keyboard."
|
|
32
|
+
actions={{
|
|
33
|
+
// eslint-disable-next-line no-console
|
|
34
|
+
positive: { onClick: () => console.log('Good response') },
|
|
35
|
+
// eslint-disable-next-line no-console
|
|
36
|
+
negative: { onClick: () => console.log('Bad response') },
|
|
37
|
+
// eslint-disable-next-line no-console
|
|
38
|
+
copy: { onClick: () => console.log('Copy') },
|
|
39
|
+
// eslint-disable-next-line no-console
|
|
40
|
+
download: { onClick: () => console.log('Download') },
|
|
41
|
+
// eslint-disable-next-line no-console
|
|
42
|
+
listen: { onClick: () => console.log('Listen') }
|
|
43
|
+
}}
|
|
44
|
+
/>
|
|
45
|
+
</>
|
|
25
46
|
);
|
|
@@ -95,14 +95,16 @@ For example, you can use the default divider to display a "timestamp" for more s
|
|
|
95
95
|
|
|
96
96
|
### Message actions
|
|
97
97
|
|
|
98
|
-
|
|
98
|
+
To let users interact with a bot's responses, you can add support for message actions. While you can customize message actions to your needs, default options include the following:
|
|
99
99
|
|
|
100
|
-
-
|
|
101
|
-
- Copy
|
|
102
|
-
-
|
|
103
|
-
-
|
|
100
|
+
- Positive and negative feedback: Allows users to rate a message as "good" or "bad."
|
|
101
|
+
- Copy: Allows users to copy the message content to their clipboard.
|
|
102
|
+
- Download: Allows users to download the message content.
|
|
103
|
+
- Listen: Reads the message content out loud using text-to-speech.
|
|
104
104
|
|
|
105
|
-
|
|
105
|
+
You can display message actions by default, or use the `showActionsOnInteraction` prop to reveal actions on hover or keyboard focus.
|
|
106
|
+
|
|
107
|
+
**Note**: The underlying logic for these actions is not built-in and must be implemented within the consuming application.
|
|
106
108
|
|
|
107
109
|
```js file="./MessageWithResponseActions.tsx"
|
|
108
110
|
|
|
@@ -140,11 +142,10 @@ When `persistActionSelection` is `true`:
|
|
|
140
142
|
|
|
141
143
|
### Message actions that fill
|
|
142
144
|
|
|
143
|
-
To provide enhanced visual feedback when users interact with response actions, you can enable icon swapping by setting `useFilledIconsOnClick` to `true`. When enabled, the predefined "positive" and "negative" actions will automatically swap to their filled icon counterparts when clicked, replacing the original outlined icon variants.
|
|
145
|
+
To provide enhanced visual feedback when users interact with response actions, you can enable icon swapping by setting `useFilledIconsOnClick` to `true`. When enabled, the predefined "positive" and "negative" actions will automatically swap to their filled icon counterparts when clicked, replacing the original outlined icon variants.
|
|
144
146
|
|
|
145
147
|
This is especially useful for actions that are intended to persist (such as the "positive" and "negative" responses), so that a user's selection is more clear and emphasized.
|
|
146
148
|
|
|
147
|
-
|
|
148
149
|
```js file="./MessageWithIconSwapping.tsx"
|
|
149
150
|
|
|
150
151
|
```
|
package/src/Message/Message.scss
CHANGED
|
@@ -92,6 +92,18 @@
|
|
|
92
92
|
gap: var(--pf-t--global--spacer--sm);
|
|
93
93
|
}
|
|
94
94
|
|
|
95
|
+
.pf-m-visible-interaction {
|
|
96
|
+
opacity: 0;
|
|
97
|
+
transition-timing-function: var(--pf-t--global--motion--timing-function--default);
|
|
98
|
+
transition-duration: var(--pf-t--global--motion--duration--fade--short);
|
|
99
|
+
transition-property: opacity;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
&:hover .pf-m-visible-interaction,
|
|
103
|
+
.pf-m-visible-interaction:focus-within {
|
|
104
|
+
opacity: 1;
|
|
105
|
+
}
|
|
106
|
+
|
|
95
107
|
// targets footnotes specifically
|
|
96
108
|
.footnotes,
|
|
97
109
|
.pf-chatbot__message-text.footnotes {
|
|
@@ -1415,4 +1415,140 @@ describe('Message', () => {
|
|
|
1415
1415
|
expect(screen.getByText('ThumbsUpIcon')).toBeInTheDocument();
|
|
1416
1416
|
expect(screen.queryByText('OutlinedThumbsUpIcon')).not.toBeInTheDocument();
|
|
1417
1417
|
});
|
|
1418
|
+
|
|
1419
|
+
it('should apply pf-m-visible-interaction class to response actions when showActionsOnInteraction is true', () => {
|
|
1420
|
+
render(
|
|
1421
|
+
<Message
|
|
1422
|
+
avatar="./img"
|
|
1423
|
+
role="bot"
|
|
1424
|
+
name="Bot"
|
|
1425
|
+
content="Hi"
|
|
1426
|
+
showActionsOnInteraction
|
|
1427
|
+
actions={{
|
|
1428
|
+
positive: { onClick: jest.fn() }
|
|
1429
|
+
}}
|
|
1430
|
+
/>
|
|
1431
|
+
);
|
|
1432
|
+
|
|
1433
|
+
const responseContainer = screen
|
|
1434
|
+
.getByRole('button', { name: 'Good response' })
|
|
1435
|
+
.closest('.pf-chatbot__response-actions');
|
|
1436
|
+
expect(responseContainer).toHaveClass('pf-m-visible-interaction');
|
|
1437
|
+
});
|
|
1438
|
+
|
|
1439
|
+
it('should not apply pf-m-visible-interaction class to response actions when showActionsOnInteraction is false', () => {
|
|
1440
|
+
render(
|
|
1441
|
+
<Message
|
|
1442
|
+
avatar="./img"
|
|
1443
|
+
role="bot"
|
|
1444
|
+
name="Bot"
|
|
1445
|
+
content="Hi"
|
|
1446
|
+
showActionsOnInteraction={false}
|
|
1447
|
+
actions={{
|
|
1448
|
+
positive: { onClick: jest.fn() }
|
|
1449
|
+
}}
|
|
1450
|
+
/>
|
|
1451
|
+
);
|
|
1452
|
+
|
|
1453
|
+
const responseContainer = screen
|
|
1454
|
+
.getByRole('button', { name: 'Good response' })
|
|
1455
|
+
.closest('.pf-chatbot__response-actions');
|
|
1456
|
+
expect(responseContainer).not.toHaveClass('pf-m-visible-interaction');
|
|
1457
|
+
});
|
|
1458
|
+
|
|
1459
|
+
it('should not apply pf-m-visible-interaction class to response actions by default', () => {
|
|
1460
|
+
render(
|
|
1461
|
+
<Message
|
|
1462
|
+
avatar="./img"
|
|
1463
|
+
role="bot"
|
|
1464
|
+
name="Bot"
|
|
1465
|
+
content="Hi"
|
|
1466
|
+
actions={{
|
|
1467
|
+
positive: { onClick: jest.fn() }
|
|
1468
|
+
}}
|
|
1469
|
+
/>
|
|
1470
|
+
);
|
|
1471
|
+
|
|
1472
|
+
const responseContainer = screen
|
|
1473
|
+
.getByRole('button', { name: 'Good response' })
|
|
1474
|
+
.closest('.pf-chatbot__response-actions');
|
|
1475
|
+
expect(responseContainer).not.toHaveClass('pf-m-visible-interaction');
|
|
1476
|
+
});
|
|
1477
|
+
|
|
1478
|
+
it('should apply pf-m-visible-interaction class to grouped actions container when showActionsOnInteraction is true', () => {
|
|
1479
|
+
render(
|
|
1480
|
+
<Message
|
|
1481
|
+
avatar="./img"
|
|
1482
|
+
role="bot"
|
|
1483
|
+
name="Bot"
|
|
1484
|
+
content="Hi"
|
|
1485
|
+
showActionsOnInteraction
|
|
1486
|
+
actions={[
|
|
1487
|
+
{
|
|
1488
|
+
positive: { onClick: jest.fn() },
|
|
1489
|
+
negative: { onClick: jest.fn() }
|
|
1490
|
+
},
|
|
1491
|
+
{
|
|
1492
|
+
copy: { onClick: jest.fn() }
|
|
1493
|
+
}
|
|
1494
|
+
]}
|
|
1495
|
+
/>
|
|
1496
|
+
);
|
|
1497
|
+
|
|
1498
|
+
const responseContainer = screen
|
|
1499
|
+
.getByRole('button', { name: 'Good response' })
|
|
1500
|
+
.closest('.pf-chatbot__response-actions-groups');
|
|
1501
|
+
expect(responseContainer).toHaveClass('pf-m-visible-interaction');
|
|
1502
|
+
});
|
|
1503
|
+
|
|
1504
|
+
it('should not apply pf-m-visible-interaction class to grouped actions container when showActionsOnInteraction is false', () => {
|
|
1505
|
+
render(
|
|
1506
|
+
<Message
|
|
1507
|
+
avatar="./img"
|
|
1508
|
+
role="bot"
|
|
1509
|
+
name="Bot"
|
|
1510
|
+
content="Hi"
|
|
1511
|
+
showActionsOnInteraction={false}
|
|
1512
|
+
actions={[
|
|
1513
|
+
{
|
|
1514
|
+
positive: { onClick: jest.fn() },
|
|
1515
|
+
negative: { onClick: jest.fn() }
|
|
1516
|
+
},
|
|
1517
|
+
{
|
|
1518
|
+
copy: { onClick: jest.fn() }
|
|
1519
|
+
}
|
|
1520
|
+
]}
|
|
1521
|
+
/>
|
|
1522
|
+
);
|
|
1523
|
+
|
|
1524
|
+
const responseContainer = screen
|
|
1525
|
+
.getByRole('button', { name: 'Good response' })
|
|
1526
|
+
.closest('.pf-chatbot__response-actions-groups');
|
|
1527
|
+
expect(responseContainer).not.toHaveClass('pf-m-visible-interaction');
|
|
1528
|
+
});
|
|
1529
|
+
|
|
1530
|
+
it('should not apply pf-m-visible-interaction class to grouped actions container by default', () => {
|
|
1531
|
+
render(
|
|
1532
|
+
<Message
|
|
1533
|
+
avatar="./img"
|
|
1534
|
+
role="bot"
|
|
1535
|
+
name="Bot"
|
|
1536
|
+
content="Hi"
|
|
1537
|
+
actions={[
|
|
1538
|
+
{
|
|
1539
|
+
positive: { onClick: jest.fn() },
|
|
1540
|
+
negative: { onClick: jest.fn() }
|
|
1541
|
+
},
|
|
1542
|
+
{
|
|
1543
|
+
copy: { onClick: jest.fn() }
|
|
1544
|
+
}
|
|
1545
|
+
]}
|
|
1546
|
+
/>
|
|
1547
|
+
);
|
|
1548
|
+
|
|
1549
|
+
const responseContainer = screen
|
|
1550
|
+
.getByRole('button', { name: 'Good response' })
|
|
1551
|
+
.closest('.pf-chatbot__response-actions-groups');
|
|
1552
|
+
expect(responseContainer).not.toHaveClass('pf-m-visible-interaction');
|
|
1553
|
+
});
|
|
1418
1554
|
});
|
package/src/Message/Message.tsx
CHANGED
|
@@ -114,6 +114,10 @@ export interface MessageProps extends Omit<HTMLProps<HTMLDivElement>, 'role'> {
|
|
|
114
114
|
* For finer control of multiple action groups, use persistActionSelection on each group.
|
|
115
115
|
*/
|
|
116
116
|
persistActionSelection?: boolean;
|
|
117
|
+
/** Flag indicating whether the actions container is only visible when a message is hovered or an action would receive focus. Note
|
|
118
|
+
* that setting this to true will append tooltips inline instead of the document.body.
|
|
119
|
+
*/
|
|
120
|
+
showActionsOnInteraction?: boolean;
|
|
117
121
|
/** Sources for message */
|
|
118
122
|
sources?: SourcesCardProps;
|
|
119
123
|
/** Label for the English word "AI," used to tag messages with role "bot" */
|
|
@@ -214,6 +218,7 @@ export const MessageBase: FunctionComponent<MessageProps> = ({
|
|
|
214
218
|
isLoading,
|
|
215
219
|
actions,
|
|
216
220
|
persistActionSelection,
|
|
221
|
+
showActionsOnInteraction = false,
|
|
217
222
|
sources,
|
|
218
223
|
botWord = 'AI',
|
|
219
224
|
loadingWord = 'Loading message',
|
|
@@ -382,7 +387,12 @@ export const MessageBase: FunctionComponent<MessageProps> = ({
|
|
|
382
387
|
{!isLoading && !isEditable && actions && (
|
|
383
388
|
<>
|
|
384
389
|
{Array.isArray(actions) ? (
|
|
385
|
-
<div
|
|
390
|
+
<div
|
|
391
|
+
className={css(
|
|
392
|
+
'pf-chatbot__response-actions-groups',
|
|
393
|
+
showActionsOnInteraction && 'pf-m-visible-interaction'
|
|
394
|
+
)}
|
|
395
|
+
>
|
|
386
396
|
{actions.map((actionGroup, index) => (
|
|
387
397
|
<ResponseActions
|
|
388
398
|
key={index}
|
|
@@ -397,6 +407,7 @@ export const MessageBase: FunctionComponent<MessageProps> = ({
|
|
|
397
407
|
actions={actions}
|
|
398
408
|
persistActionSelection={persistActionSelection}
|
|
399
409
|
useFilledIconsOnClick={useFilledIconsOnClick}
|
|
410
|
+
showActionsOnInteraction={showActionsOnInteraction}
|
|
400
411
|
/>
|
|
401
412
|
)}
|
|
402
413
|
</>
|
|
@@ -437,6 +437,65 @@ describe('ResponseActions', () => {
|
|
|
437
437
|
expect(customBtn).not.toHaveClass('pf-chatbot__button--response-action-clicked');
|
|
438
438
|
});
|
|
439
439
|
|
|
440
|
+
it('should apply pf-m-visible-interaction class when showActionsOnInteraction is true', () => {
|
|
441
|
+
render(
|
|
442
|
+
<ResponseActions
|
|
443
|
+
data-testid="test-id"
|
|
444
|
+
actions={{
|
|
445
|
+
positive: { onClick: jest.fn() },
|
|
446
|
+
negative: { onClick: jest.fn() }
|
|
447
|
+
}}
|
|
448
|
+
showActionsOnInteraction
|
|
449
|
+
/>
|
|
450
|
+
);
|
|
451
|
+
|
|
452
|
+
expect(screen.getByTestId('test-id')).toHaveClass('pf-m-visible-interaction');
|
|
453
|
+
});
|
|
454
|
+
|
|
455
|
+
it('should not apply pf-m-visible-interaction class when showActionsOnInteraction is false', () => {
|
|
456
|
+
render(
|
|
457
|
+
<ResponseActions
|
|
458
|
+
data-testid="test-id"
|
|
459
|
+
actions={{
|
|
460
|
+
positive: { onClick: jest.fn() },
|
|
461
|
+
negative: { onClick: jest.fn() }
|
|
462
|
+
}}
|
|
463
|
+
showActionsOnInteraction={false}
|
|
464
|
+
/>
|
|
465
|
+
);
|
|
466
|
+
|
|
467
|
+
expect(screen.getByTestId('test-id')).not.toHaveClass('pf-m-visible-interaction');
|
|
468
|
+
});
|
|
469
|
+
|
|
470
|
+
it('should not apply pf-m-visible-interaction class by default', () => {
|
|
471
|
+
render(
|
|
472
|
+
<ResponseActions
|
|
473
|
+
data-testid="test-id"
|
|
474
|
+
actions={{
|
|
475
|
+
positive: { onClick: jest.fn() },
|
|
476
|
+
negative: { onClick: jest.fn() }
|
|
477
|
+
}}
|
|
478
|
+
/>
|
|
479
|
+
);
|
|
480
|
+
|
|
481
|
+
expect(screen.getByTestId('test-id')).not.toHaveClass('pf-m-visible-interaction');
|
|
482
|
+
});
|
|
483
|
+
|
|
484
|
+
it('should render with custom className', () => {
|
|
485
|
+
render(
|
|
486
|
+
<ResponseActions
|
|
487
|
+
data-testid="test-id"
|
|
488
|
+
actions={{
|
|
489
|
+
positive: { onClick: jest.fn() },
|
|
490
|
+
negative: { onClick: jest.fn() }
|
|
491
|
+
}}
|
|
492
|
+
className="custom-class"
|
|
493
|
+
/>
|
|
494
|
+
);
|
|
495
|
+
|
|
496
|
+
expect(screen.getByTestId('test-id')).toHaveClass('custom-class');
|
|
497
|
+
});
|
|
498
|
+
|
|
440
499
|
describe('icon swapping with useFilledIconsOnClick', () => {
|
|
441
500
|
it('should render outline icons by default', () => {
|
|
442
501
|
render(
|
|
@@ -13,6 +13,7 @@ import {
|
|
|
13
13
|
} from '@patternfly/react-icons';
|
|
14
14
|
import ResponseActionButton from './ResponseActionButton';
|
|
15
15
|
import { ButtonProps, TooltipProps } from '@patternfly/react-core';
|
|
16
|
+
import { css } from '@patternfly/react-styles';
|
|
16
17
|
|
|
17
18
|
export interface ActionProps extends Omit<ButtonProps, 'ref'> {
|
|
18
19
|
/** Aria-label for the button */
|
|
@@ -51,6 +52,8 @@ type ExtendedActionProps = ActionProps & {
|
|
|
51
52
|
*/
|
|
52
53
|
|
|
53
54
|
export interface ResponseActionProps {
|
|
55
|
+
/** Additional classes for the response actions container. */
|
|
56
|
+
className?: string;
|
|
54
57
|
/** Props for message actions, such as feedback (positive or negative), copy button, share, and listen */
|
|
55
58
|
actions: Record<string, ExtendedActionProps | undefined> & {
|
|
56
59
|
positive?: ActionProps;
|
|
@@ -67,12 +70,19 @@ export interface ResponseActionProps {
|
|
|
67
70
|
/** When true, automatically swaps to filled icon variants when predefined actions are clicked.
|
|
68
71
|
* Predefined actions will use filled variants (e.g., ThumbsUpIcon) when clicked and outline variants (e.g., OutlinedThumbsUpIcon) when not clicked. */
|
|
69
72
|
useFilledIconsOnClick?: boolean;
|
|
73
|
+
/** Flag indicating whether the actions container is only visible when a message is hovered or an action would receive focus. Note
|
|
74
|
+
* that setting this to true will append tooltips inline instead of the document.body.
|
|
75
|
+
*/
|
|
76
|
+
showActionsOnInteraction?: boolean;
|
|
70
77
|
}
|
|
71
78
|
|
|
72
79
|
export const ResponseActions: FunctionComponent<ResponseActionProps> = ({
|
|
80
|
+
className,
|
|
73
81
|
actions,
|
|
74
82
|
persistActionSelection = false,
|
|
75
|
-
useFilledIconsOnClick = false
|
|
83
|
+
useFilledIconsOnClick = false,
|
|
84
|
+
showActionsOnInteraction = false,
|
|
85
|
+
...props
|
|
76
86
|
}) => {
|
|
77
87
|
const [activeButton, setActiveButton] = useState<string>();
|
|
78
88
|
const [clickStatePersisted, setClickStatePersisted] = useState<boolean>(false);
|
|
@@ -173,8 +183,23 @@ export const ResponseActions: FunctionComponent<ResponseActionProps> = ({
|
|
|
173
183
|
return iconMap[actionName].outlined;
|
|
174
184
|
};
|
|
175
185
|
|
|
186
|
+
// We want to append the tooltip inline so that hovering the tooltip keeps the actions container visible
|
|
187
|
+
// when showActionsOnInteraction is true. Otherwise hovering the tooltip causes the actions container
|
|
188
|
+
// to disappear but the tooltip will remain visible.
|
|
189
|
+
const getTooltipContainer = (): HTMLElement => responseActions.current || document.body;
|
|
190
|
+
|
|
191
|
+
const getTooltipProps = (tooltipProps?: TooltipProps) =>
|
|
192
|
+
({
|
|
193
|
+
...(showActionsOnInteraction && { appendTo: getTooltipContainer }),
|
|
194
|
+
...tooltipProps
|
|
195
|
+
}) as TooltipProps;
|
|
196
|
+
|
|
176
197
|
return (
|
|
177
|
-
<div
|
|
198
|
+
<div
|
|
199
|
+
ref={responseActions}
|
|
200
|
+
className={css('pf-chatbot__response-actions', showActionsOnInteraction && 'pf-m-visible-interaction', className)}
|
|
201
|
+
{...props}
|
|
202
|
+
>
|
|
178
203
|
{positive && (
|
|
179
204
|
<ResponseActionButton
|
|
180
205
|
{...positive}
|
|
@@ -185,7 +210,7 @@ export const ResponseActions: FunctionComponent<ResponseActionProps> = ({
|
|
|
185
210
|
isDisabled={positive.isDisabled}
|
|
186
211
|
tooltipContent={positive.tooltipContent ?? 'Good response'}
|
|
187
212
|
clickedTooltipContent={positive.clickedTooltipContent ?? 'Good response recorded'}
|
|
188
|
-
tooltipProps={positive.tooltipProps}
|
|
213
|
+
tooltipProps={getTooltipProps(positive.tooltipProps)}
|
|
189
214
|
icon={getIcon('positive')}
|
|
190
215
|
isClicked={activeButton === 'positive'}
|
|
191
216
|
ref={positive.ref}
|
|
@@ -203,7 +228,7 @@ export const ResponseActions: FunctionComponent<ResponseActionProps> = ({
|
|
|
203
228
|
isDisabled={negative.isDisabled}
|
|
204
229
|
tooltipContent={negative.tooltipContent ?? 'Bad response'}
|
|
205
230
|
clickedTooltipContent={negative.clickedTooltipContent ?? 'Bad response recorded'}
|
|
206
|
-
tooltipProps={negative.tooltipProps}
|
|
231
|
+
tooltipProps={getTooltipProps(negative.tooltipProps)}
|
|
207
232
|
icon={getIcon('negative')}
|
|
208
233
|
isClicked={activeButton === 'negative'}
|
|
209
234
|
ref={negative.ref}
|
|
@@ -221,7 +246,7 @@ export const ResponseActions: FunctionComponent<ResponseActionProps> = ({
|
|
|
221
246
|
isDisabled={copy.isDisabled}
|
|
222
247
|
tooltipContent={copy.tooltipContent ?? 'Copy'}
|
|
223
248
|
clickedTooltipContent={copy.clickedTooltipContent ?? 'Copied'}
|
|
224
|
-
tooltipProps={copy.tooltipProps}
|
|
249
|
+
tooltipProps={getTooltipProps(copy.tooltipProps)}
|
|
225
250
|
icon={<OutlinedCopyIcon />}
|
|
226
251
|
isClicked={activeButton === 'copy'}
|
|
227
252
|
ref={copy.ref}
|
|
@@ -239,7 +264,7 @@ export const ResponseActions: FunctionComponent<ResponseActionProps> = ({
|
|
|
239
264
|
isDisabled={edit.isDisabled}
|
|
240
265
|
tooltipContent={edit.tooltipContent ?? 'Edit '}
|
|
241
266
|
clickedTooltipContent={edit.clickedTooltipContent ?? 'Editing'}
|
|
242
|
-
tooltipProps={edit.tooltipProps}
|
|
267
|
+
tooltipProps={getTooltipProps(edit.tooltipProps)}
|
|
243
268
|
icon={<PencilAltIcon />}
|
|
244
269
|
isClicked={activeButton === 'edit'}
|
|
245
270
|
ref={edit.ref}
|
|
@@ -257,7 +282,7 @@ export const ResponseActions: FunctionComponent<ResponseActionProps> = ({
|
|
|
257
282
|
isDisabled={share.isDisabled}
|
|
258
283
|
tooltipContent={share.tooltipContent ?? 'Share'}
|
|
259
284
|
clickedTooltipContent={share.clickedTooltipContent ?? 'Shared'}
|
|
260
|
-
tooltipProps={share.tooltipProps}
|
|
285
|
+
tooltipProps={getTooltipProps(share.tooltipProps)}
|
|
261
286
|
icon={<ExternalLinkAltIcon />}
|
|
262
287
|
isClicked={activeButton === 'share'}
|
|
263
288
|
ref={share.ref}
|
|
@@ -275,7 +300,7 @@ export const ResponseActions: FunctionComponent<ResponseActionProps> = ({
|
|
|
275
300
|
isDisabled={download.isDisabled}
|
|
276
301
|
tooltipContent={download.tooltipContent ?? 'Download'}
|
|
277
302
|
clickedTooltipContent={download.clickedTooltipContent ?? 'Downloaded'}
|
|
278
|
-
tooltipProps={download.tooltipProps}
|
|
303
|
+
tooltipProps={getTooltipProps(download.tooltipProps)}
|
|
279
304
|
icon={<DownloadIcon />}
|
|
280
305
|
isClicked={activeButton === 'download'}
|
|
281
306
|
ref={download.ref}
|
|
@@ -293,7 +318,7 @@ export const ResponseActions: FunctionComponent<ResponseActionProps> = ({
|
|
|
293
318
|
isDisabled={listen.isDisabled}
|
|
294
319
|
tooltipContent={listen.tooltipContent ?? 'Listen'}
|
|
295
320
|
clickedTooltipContent={listen.clickedTooltipContent ?? 'Listening'}
|
|
296
|
-
tooltipProps={listen.tooltipProps}
|
|
321
|
+
tooltipProps={getTooltipProps(listen.tooltipProps)}
|
|
297
322
|
icon={<VolumeUpIcon />}
|
|
298
323
|
isClicked={activeButton === 'listen'}
|
|
299
324
|
ref={listen.ref}
|
|
@@ -312,7 +337,7 @@ export const ResponseActions: FunctionComponent<ResponseActionProps> = ({
|
|
|
312
337
|
className={additionalActions[action]?.className}
|
|
313
338
|
isDisabled={additionalActions[action]?.isDisabled}
|
|
314
339
|
tooltipContent={additionalActions[action]?.tooltipContent}
|
|
315
|
-
tooltipProps={additionalActions[action]?.tooltipProps}
|
|
340
|
+
tooltipProps={getTooltipProps(additionalActions[action]?.tooltipProps)}
|
|
316
341
|
clickedTooltipContent={additionalActions[action]?.clickedTooltipContent}
|
|
317
342
|
icon={additionalActions[action]?.icon}
|
|
318
343
|
isClicked={activeButton === action}
|