@patternfly/chatbot 6.6.0-prerelease.5 → 6.6.0-prerelease.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. package/dist/cjs/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.d.ts +1 -1
  2. package/dist/cjs/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.test.js +1 -1
  3. package/dist/cjs/ChatbotConversationHistoryNav/LoadingState.js +1 -1
  4. package/dist/cjs/ChatbotHeader/ChatbotHeaderMenu.js +1 -1
  5. package/dist/cjs/ChatbotHeader/ChatbotHeaderMenu.test.js +1 -1
  6. package/dist/cjs/Message/Message.d.ts +4 -0
  7. package/dist/cjs/Message/Message.js +2 -2
  8. package/dist/cjs/Message/Message.test.js +72 -0
  9. package/dist/cjs/ResponseActions/ResponseActions.d.ts +6 -0
  10. package/dist/cjs/ResponseActions/ResponseActions.js +12 -5
  11. package/dist/cjs/ResponseActions/ResponseActions.test.js +28 -0
  12. package/dist/css/main.css +27 -10
  13. package/dist/css/main.css.map +1 -1
  14. package/dist/esm/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.d.ts +1 -1
  15. package/dist/esm/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.test.js +1 -1
  16. package/dist/esm/ChatbotConversationHistoryNav/LoadingState.js +1 -1
  17. package/dist/esm/ChatbotHeader/ChatbotHeaderMenu.js +1 -1
  18. package/dist/esm/ChatbotHeader/ChatbotHeaderMenu.test.js +1 -1
  19. package/dist/esm/Message/Message.d.ts +4 -0
  20. package/dist/esm/Message/Message.js +2 -2
  21. package/dist/esm/Message/Message.test.js +72 -0
  22. package/dist/esm/ResponseActions/ResponseActions.d.ts +6 -0
  23. package/dist/esm/ResponseActions/ResponseActions.js +12 -5
  24. package/dist/esm/ResponseActions/ResponseActions.test.js +28 -0
  25. package/package.json +1 -1
  26. package/patternfly-docs/content/extensions/chatbot/chatbot.md +1 -1
  27. package/patternfly-docs/content/extensions/chatbot/design-guidelines.md +10 -12
  28. package/patternfly-docs/content/extensions/chatbot/examples/Messages/MessageWithResponseActions.tsx +39 -18
  29. package/patternfly-docs/content/extensions/chatbot/examples/Messages/Messages.md +9 -8
  30. package/patternfly-docs/content/extensions/chatbot/examples/UI/ChatbotHeaderBasic.tsx +1 -1
  31. package/patternfly-docs/content/extensions/chatbot/examples/UI/UI.md +16 -16
  32. package/patternfly-docs/content/extensions/chatbot/examples/demos/Chatbot.md +3 -3
  33. package/src/Chatbot/Chatbot.scss +8 -1
  34. package/src/ChatbotContent/ChatbotContent.scss +5 -1
  35. package/src/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.test.tsx +1 -1
  36. package/src/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.tsx +1 -1
  37. package/src/ChatbotConversationHistoryNav/LoadingState.tsx +1 -5
  38. package/src/ChatbotFooter/ChatbotFooter.scss +8 -1
  39. package/src/ChatbotHeader/ChatbotHeader.scss +5 -2
  40. package/src/ChatbotHeader/ChatbotHeaderMenu.test.tsx +1 -1
  41. package/src/ChatbotHeader/ChatbotHeaderMenu.tsx +2 -2
  42. package/src/Message/Message.scss +12 -0
  43. package/src/Message/Message.test.tsx +136 -0
  44. package/src/Message/Message.tsx +12 -1
  45. package/src/MessageBar/MessageBar.scss +8 -5
  46. package/src/ResponseActions/ResponseActions.test.tsx +59 -0
  47. package/src/ResponseActions/ResponseActions.tsx +35 -10
@@ -307,7 +307,7 @@ describe('ChatbotConversationHistoryNav', () => {
307
307
  isLoading
308
308
  />
309
309
  );
310
- expect(screen.getByRole('dialog', { name: /Loading chatbot conversation history/i })).toBeTruthy();
310
+ expect(screen.getByRole('dialog', { name: /Loading chatbot chat history/i })).toBeTruthy();
311
311
  expect(screen.getByRole('button', { name: /Close drawer panel/i })).toBeTruthy();
312
312
  });
313
313
 
@@ -84,7 +84,7 @@ export interface ChatbotConversationHistoryNavProps extends DrawerProps {
84
84
  activeItemId?: string | number;
85
85
  /** Callback function for when an item is selected */
86
86
  onSelectActiveItem?: (event?: React.MouseEvent, itemId?: string | number) => void;
87
- /** Items shown in conversation history */
87
+ /** Items shown in chat history */
88
88
  conversations: Conversation[] | { [key: string]: Conversation[] };
89
89
  /** Additional button props for new chat button. */
90
90
  newChatButtonProps?: ButtonProps;
@@ -4,11 +4,7 @@ import type { FunctionComponent } from 'react';
4
4
  export const LoadingState: FunctionComponent<SkeletonProps> = ({ screenreaderText, ...rest }: SkeletonProps) => (
5
5
  <div className="pf-chatbot__history-loading">
6
6
  <div className="pf-chatbot__history-loading-block">
7
- <Skeleton
8
- screenreaderText={screenreaderText ?? 'Loading chatbot conversation history'}
9
- fontSize="3xl"
10
- {...rest}
11
- />
7
+ <Skeleton screenreaderText={screenreaderText ?? 'Loading chatbot chat history'} fontSize="3xl" {...rest} />
12
8
  </div>
13
9
  <div className="pf-chatbot__history-loading-block">
14
10
  <Skeleton fontSize="sm" width="70%" {...rest} />
@@ -6,7 +6,10 @@
6
6
  // ============================================================================
7
7
  .pf-chatbot__footer {
8
8
  --pf-chatbot__footer--RowGap: var(--pf-t--global--spacer--md);
9
- background-color: var(--pf-t--global--background--color--secondary--default);
9
+ background-color: var(
10
+ --pf-t--global--background--color--floating--secondary--default,
11
+ --pf-t--global--background--color--secondary--default
12
+ );
10
13
  display: flex;
11
14
  flex-direction: column;
12
15
  row-gap: var(--pf-chatbot__footer--RowGap);
@@ -36,6 +39,10 @@
36
39
  display: none;
37
40
  }
38
41
  }
42
+ .pf-chatbot__footer {
43
+ background-color: var(--pf-t--global--background--color--secondary--default);
44
+ }
45
+
39
46
  .pf-chatbot__footer-container {
40
47
  width: 90%;
41
48
  max-width: 60rem;
@@ -9,7 +9,10 @@
9
9
  grid-template-columns: 1fr auto;
10
10
  gap: var(--pf-t--global--spacer--sm);
11
11
  position: relative; // this is so focus ring on parent chatbot doesn't include header
12
- background-color: var(--pf-t--global--background--color--secondary--default);
12
+ background-color: var(
13
+ --pf-t--global--background--color--floating--secondary--default,
14
+ --pf-t--global--background--color--secondary--default
15
+ );
13
16
  justify-content: space-between;
14
17
  padding: var(--pf-t--global--spacer--lg);
15
18
 
@@ -76,7 +79,7 @@
76
79
  .pf-chatbot--drawer,
77
80
  .pf-chatbot--docked {
78
81
  .pf-chatbot__header {
79
- background-color: var(--pf-t--global--background--color--secondary--default);
82
+ background-color: var(--pf-t--global--background--color--secondary--floating--default);
80
83
  }
81
84
  }
82
85
 
@@ -12,7 +12,7 @@ describe('ChatbotHeaderMenu', () => {
12
12
  it('should call onMenuToggle when ChatbotHeaderMenu button is clicked', () => {
13
13
  const onMenuToggle = jest.fn();
14
14
  render(<ChatbotHeaderMenu className="custom-header-menu" onMenuToggle={onMenuToggle} />);
15
- fireEvent.click(screen.getByRole('button', { name: 'Chat history menu' }));
15
+ fireEvent.click(screen.getByRole('button', { name: 'Chat history drawer' }));
16
16
 
17
17
  expect(onMenuToggle).toHaveBeenCalled();
18
18
  });
@@ -25,9 +25,9 @@ const ChatbotHeaderMenuBase: FunctionComponent<ChatbotHeaderMenuProps> = ({
25
25
  className,
26
26
  onMenuToggle,
27
27
  tooltipProps,
28
- menuAriaLabel = 'Chat history menu',
28
+ menuAriaLabel = 'Chat history drawer',
29
29
  innerRef,
30
- tooltipContent = 'Chat history menu',
30
+ tooltipContent = 'Chat history drawer',
31
31
  isCompact,
32
32
  ...props
33
33
  }: ChatbotHeaderMenuProps) => {
@@ -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
  });
@@ -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 className="pf-chatbot__response-actions-groups">
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
  </>
@@ -19,7 +19,10 @@
19
19
  flex-wrap: wrap;
20
20
  align-items: center;
21
21
  justify-content: flex-end;
22
- background-color: var(--pf-t--global--background--color--primary--default);
22
+ background-color: var(
23
+ --pf-t--global--background--color--control--default,
24
+ --pf-t--global--background--color--primary--default
25
+ );
23
26
  border-radius: calc(var(--pf-t--global--border--radius--medium) * 2);
24
27
  transition: border-color var(--pf-t--global--motion--timing-function--accelerate)
25
28
  var(--pf-t--global--motion--duration--sm);
@@ -42,20 +45,20 @@
42
45
 
43
46
  &.pf-m-primary {
44
47
  &::after {
45
- border-color: var(--pf-t--global--border--color--default);
48
+ border-color: var(--pf-t--global--border--color--control--default, --pf-t--global--border--color--default);
46
49
  }
47
50
  }
48
51
 
49
52
  &:hover {
50
53
  &::after {
51
- border-color: var(--pf-t--global--border--color--default);
54
+ border-color: var(--pf-t--global--border--color--control--default, --pf-t--global--border--color--default);
52
55
  border-width: var(--pf-t--global--border--width--control--hover);
53
56
  }
54
57
  }
55
58
 
56
59
  &:focus-within {
57
60
  &::after {
58
- border-color: var(--pf-t--global--color--brand--default);
61
+ border-color: var(--pf-t--global--border--color--control--default, --pf-t--global--border--color--default);
59
62
  border-width: var(--pf-t--global--border--width--control--clicked);
60
63
  }
61
64
  }
@@ -183,7 +186,7 @@
183
186
  :root:where(.pf-v6-theme-high-contrast) {
184
187
  .pf-chatbot__message-bar {
185
188
  &::after {
186
- border-color: var(--pf-t--global--border--color--default);
189
+ border-color: var(--pf-t--global--border--color--control--default, --pf-t--global--border--color--default);
187
190
  }
188
191
  }
189
192
  }
@@ -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 ref={responseActions} className="pf-chatbot__response-actions">
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}