@patternfly/chatbot 6.6.0-prerelease.4 → 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 +6 -0
- package/dist/cjs/Message/Message.js +2 -2
- package/dist/cjs/Message/Message.test.js +109 -0
- package/dist/cjs/ResponseActions/ResponseActions.d.ts +9 -0
- package/dist/cjs/ResponseActions/ResponseActions.js +30 -5
- package/dist/cjs/ResponseActions/ResponseActions.test.js +134 -0
- package/dist/css/main.css +10 -0
- package/dist/css/main.css.map +1 -1
- package/dist/esm/Message/Message.d.ts +6 -0
- package/dist/esm/Message/Message.js +2 -2
- package/dist/esm/Message/Message.test.js +109 -0
- package/dist/esm/ResponseActions/ResponseActions.d.ts +9 -0
- package/dist/esm/ResponseActions/ResponseActions.js +31 -6
- package/dist/esm/ResponseActions/ResponseActions.test.js +135 -1
- package/package.json +1 -1
- package/patternfly-docs/content/extensions/chatbot/examples/Messages/MessageWithIconSwapping.tsx +22 -0
- package/patternfly-docs/content/extensions/chatbot/examples/Messages/MessageWithResponseActions.tsx +39 -18
- package/patternfly-docs/content/extensions/chatbot/examples/Messages/Messages.md +18 -6
- package/src/Message/Message.scss +12 -0
- package/src/Message/Message.test.tsx +200 -0
- package/src/Message/Message.tsx +21 -2
- package/src/ResponseActions/ResponseActions.test.tsx +259 -0
- package/src/ResponseActions/ResponseActions.tsx +65 -12
|
@@ -4,13 +4,16 @@ import {
|
|
|
4
4
|
ExternalLinkAltIcon,
|
|
5
5
|
VolumeUpIcon,
|
|
6
6
|
OutlinedThumbsUpIcon,
|
|
7
|
+
ThumbsUpIcon,
|
|
7
8
|
OutlinedThumbsDownIcon,
|
|
9
|
+
ThumbsDownIcon,
|
|
8
10
|
OutlinedCopyIcon,
|
|
9
11
|
DownloadIcon,
|
|
10
12
|
PencilAltIcon
|
|
11
13
|
} from '@patternfly/react-icons';
|
|
12
14
|
import ResponseActionButton from './ResponseActionButton';
|
|
13
15
|
import { ButtonProps, TooltipProps } from '@patternfly/react-core';
|
|
16
|
+
import { css } from '@patternfly/react-styles';
|
|
14
17
|
|
|
15
18
|
export interface ActionProps extends Omit<ButtonProps, 'ref'> {
|
|
16
19
|
/** Aria-label for the button */
|
|
@@ -49,6 +52,8 @@ type ExtendedActionProps = ActionProps & {
|
|
|
49
52
|
*/
|
|
50
53
|
|
|
51
54
|
export interface ResponseActionProps {
|
|
55
|
+
/** Additional classes for the response actions container. */
|
|
56
|
+
className?: string;
|
|
52
57
|
/** Props for message actions, such as feedback (positive or negative), copy button, share, and listen */
|
|
53
58
|
actions: Record<string, ExtendedActionProps | undefined> & {
|
|
54
59
|
positive?: ActionProps;
|
|
@@ -62,11 +67,22 @@ export interface ResponseActionProps {
|
|
|
62
67
|
/** When true, the selected action will persist even when clicking outside the component.
|
|
63
68
|
* When false (default), clicking outside or clicking another action will deselect the current selection. */
|
|
64
69
|
persistActionSelection?: boolean;
|
|
70
|
+
/** When true, automatically swaps to filled icon variants when predefined actions are clicked.
|
|
71
|
+
* Predefined actions will use filled variants (e.g., ThumbsUpIcon) when clicked and outline variants (e.g., OutlinedThumbsUpIcon) when not clicked. */
|
|
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;
|
|
65
77
|
}
|
|
66
78
|
|
|
67
79
|
export const ResponseActions: FunctionComponent<ResponseActionProps> = ({
|
|
80
|
+
className,
|
|
68
81
|
actions,
|
|
69
|
-
persistActionSelection = false
|
|
82
|
+
persistActionSelection = false,
|
|
83
|
+
useFilledIconsOnClick = false,
|
|
84
|
+
showActionsOnInteraction = false,
|
|
85
|
+
...props
|
|
70
86
|
}) => {
|
|
71
87
|
const [activeButton, setActiveButton] = useState<string>();
|
|
72
88
|
const [clickStatePersisted, setClickStatePersisted] = useState<boolean>(false);
|
|
@@ -129,6 +145,7 @@ export const ResponseActions: FunctionComponent<ResponseActionProps> = ({
|
|
|
129
145
|
id: string,
|
|
130
146
|
onClick?: (event: MouseEvent | MouseEvent<Element, MouseEvent> | KeyboardEvent) => void
|
|
131
147
|
) => {
|
|
148
|
+
e.stopPropagation();
|
|
132
149
|
if (persistActionSelection) {
|
|
133
150
|
if (activeButton === id) {
|
|
134
151
|
// Toggle off if clicking the same button
|
|
@@ -145,8 +162,44 @@ export const ResponseActions: FunctionComponent<ResponseActionProps> = ({
|
|
|
145
162
|
onClick && onClick(e);
|
|
146
163
|
};
|
|
147
164
|
|
|
165
|
+
const iconMap = {
|
|
166
|
+
positive: {
|
|
167
|
+
filled: <ThumbsUpIcon />,
|
|
168
|
+
outlined: <OutlinedThumbsUpIcon />
|
|
169
|
+
},
|
|
170
|
+
negative: {
|
|
171
|
+
filled: <ThumbsDownIcon />,
|
|
172
|
+
outlined: <OutlinedThumbsDownIcon />
|
|
173
|
+
}
|
|
174
|
+
};
|
|
175
|
+
|
|
176
|
+
const getIcon = (actionName: string) => {
|
|
177
|
+
const isClicked = activeButton === actionName;
|
|
178
|
+
|
|
179
|
+
if (isClicked && useFilledIconsOnClick) {
|
|
180
|
+
return iconMap[actionName].filled;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
return iconMap[actionName].outlined;
|
|
184
|
+
};
|
|
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
|
+
|
|
148
197
|
return (
|
|
149
|
-
<div
|
|
198
|
+
<div
|
|
199
|
+
ref={responseActions}
|
|
200
|
+
className={css('pf-chatbot__response-actions', showActionsOnInteraction && 'pf-m-visible-interaction', className)}
|
|
201
|
+
{...props}
|
|
202
|
+
>
|
|
150
203
|
{positive && (
|
|
151
204
|
<ResponseActionButton
|
|
152
205
|
{...positive}
|
|
@@ -157,8 +210,8 @@ export const ResponseActions: FunctionComponent<ResponseActionProps> = ({
|
|
|
157
210
|
isDisabled={positive.isDisabled}
|
|
158
211
|
tooltipContent={positive.tooltipContent ?? 'Good response'}
|
|
159
212
|
clickedTooltipContent={positive.clickedTooltipContent ?? 'Good response recorded'}
|
|
160
|
-
tooltipProps={positive.tooltipProps}
|
|
161
|
-
icon={
|
|
213
|
+
tooltipProps={getTooltipProps(positive.tooltipProps)}
|
|
214
|
+
icon={getIcon('positive')}
|
|
162
215
|
isClicked={activeButton === 'positive'}
|
|
163
216
|
ref={positive.ref}
|
|
164
217
|
aria-expanded={positive['aria-expanded']}
|
|
@@ -175,8 +228,8 @@ export const ResponseActions: FunctionComponent<ResponseActionProps> = ({
|
|
|
175
228
|
isDisabled={negative.isDisabled}
|
|
176
229
|
tooltipContent={negative.tooltipContent ?? 'Bad response'}
|
|
177
230
|
clickedTooltipContent={negative.clickedTooltipContent ?? 'Bad response recorded'}
|
|
178
|
-
tooltipProps={negative.tooltipProps}
|
|
179
|
-
icon={
|
|
231
|
+
tooltipProps={getTooltipProps(negative.tooltipProps)}
|
|
232
|
+
icon={getIcon('negative')}
|
|
180
233
|
isClicked={activeButton === 'negative'}
|
|
181
234
|
ref={negative.ref}
|
|
182
235
|
aria-expanded={negative['aria-expanded']}
|
|
@@ -193,7 +246,7 @@ export const ResponseActions: FunctionComponent<ResponseActionProps> = ({
|
|
|
193
246
|
isDisabled={copy.isDisabled}
|
|
194
247
|
tooltipContent={copy.tooltipContent ?? 'Copy'}
|
|
195
248
|
clickedTooltipContent={copy.clickedTooltipContent ?? 'Copied'}
|
|
196
|
-
tooltipProps={copy.tooltipProps}
|
|
249
|
+
tooltipProps={getTooltipProps(copy.tooltipProps)}
|
|
197
250
|
icon={<OutlinedCopyIcon />}
|
|
198
251
|
isClicked={activeButton === 'copy'}
|
|
199
252
|
ref={copy.ref}
|
|
@@ -211,7 +264,7 @@ export const ResponseActions: FunctionComponent<ResponseActionProps> = ({
|
|
|
211
264
|
isDisabled={edit.isDisabled}
|
|
212
265
|
tooltipContent={edit.tooltipContent ?? 'Edit '}
|
|
213
266
|
clickedTooltipContent={edit.clickedTooltipContent ?? 'Editing'}
|
|
214
|
-
tooltipProps={edit.tooltipProps}
|
|
267
|
+
tooltipProps={getTooltipProps(edit.tooltipProps)}
|
|
215
268
|
icon={<PencilAltIcon />}
|
|
216
269
|
isClicked={activeButton === 'edit'}
|
|
217
270
|
ref={edit.ref}
|
|
@@ -229,7 +282,7 @@ export const ResponseActions: FunctionComponent<ResponseActionProps> = ({
|
|
|
229
282
|
isDisabled={share.isDisabled}
|
|
230
283
|
tooltipContent={share.tooltipContent ?? 'Share'}
|
|
231
284
|
clickedTooltipContent={share.clickedTooltipContent ?? 'Shared'}
|
|
232
|
-
tooltipProps={share.tooltipProps}
|
|
285
|
+
tooltipProps={getTooltipProps(share.tooltipProps)}
|
|
233
286
|
icon={<ExternalLinkAltIcon />}
|
|
234
287
|
isClicked={activeButton === 'share'}
|
|
235
288
|
ref={share.ref}
|
|
@@ -247,7 +300,7 @@ export const ResponseActions: FunctionComponent<ResponseActionProps> = ({
|
|
|
247
300
|
isDisabled={download.isDisabled}
|
|
248
301
|
tooltipContent={download.tooltipContent ?? 'Download'}
|
|
249
302
|
clickedTooltipContent={download.clickedTooltipContent ?? 'Downloaded'}
|
|
250
|
-
tooltipProps={download.tooltipProps}
|
|
303
|
+
tooltipProps={getTooltipProps(download.tooltipProps)}
|
|
251
304
|
icon={<DownloadIcon />}
|
|
252
305
|
isClicked={activeButton === 'download'}
|
|
253
306
|
ref={download.ref}
|
|
@@ -265,7 +318,7 @@ export const ResponseActions: FunctionComponent<ResponseActionProps> = ({
|
|
|
265
318
|
isDisabled={listen.isDisabled}
|
|
266
319
|
tooltipContent={listen.tooltipContent ?? 'Listen'}
|
|
267
320
|
clickedTooltipContent={listen.clickedTooltipContent ?? 'Listening'}
|
|
268
|
-
tooltipProps={listen.tooltipProps}
|
|
321
|
+
tooltipProps={getTooltipProps(listen.tooltipProps)}
|
|
269
322
|
icon={<VolumeUpIcon />}
|
|
270
323
|
isClicked={activeButton === 'listen'}
|
|
271
324
|
ref={listen.ref}
|
|
@@ -284,7 +337,7 @@ export const ResponseActions: FunctionComponent<ResponseActionProps> = ({
|
|
|
284
337
|
className={additionalActions[action]?.className}
|
|
285
338
|
isDisabled={additionalActions[action]?.isDisabled}
|
|
286
339
|
tooltipContent={additionalActions[action]?.tooltipContent}
|
|
287
|
-
tooltipProps={additionalActions[action]?.tooltipProps}
|
|
340
|
+
tooltipProps={getTooltipProps(additionalActions[action]?.tooltipProps)}
|
|
288
341
|
clickedTooltipContent={additionalActions[action]?.clickedTooltipContent}
|
|
289
342
|
icon={additionalActions[action]?.icon}
|
|
290
343
|
isClicked={activeButton === action}
|