@patternfly/chatbot 6.3.0-prerelease.10 → 6.3.0-prerelease.12

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 (51) hide show
  1. package/dist/cjs/Message/CodeBlockMessage/CodeBlockMessage.js +1 -1
  2. package/dist/cjs/Message/Message.test.js +3 -3
  3. package/dist/cjs/MessageBar/AttachButton.js +1 -1
  4. package/dist/cjs/MessageBar/AttachButton.test.js +7 -7
  5. package/dist/cjs/MessageBar/MessageBar.test.js +29 -29
  6. package/dist/cjs/MessageBar/MicrophoneButton.js +1 -1
  7. package/dist/cjs/MessageBar/SendButton.js +1 -1
  8. package/dist/cjs/MessageBar/SendButton.test.js +5 -5
  9. package/dist/cjs/MessageBar/StopButton.js +1 -1
  10. package/dist/cjs/MessageBar/StopButton.test.js +5 -5
  11. package/dist/cjs/MessageBox/JumpButton.js +1 -1
  12. package/dist/cjs/MessageBox/JumpButton.test.js +4 -4
  13. package/dist/cjs/MessageBox/MessageBox.test.js +2 -2
  14. package/dist/cjs/ResponseActions/ResponseActionButton.d.ts +2 -2
  15. package/dist/cjs/ResponseActions/ResponseActions.d.ts +4 -1
  16. package/dist/cjs/ResponseActions/ResponseActions.js +6 -6
  17. package/dist/cjs/ResponseActions/ResponseActions.test.js +16 -1
  18. package/dist/esm/Message/CodeBlockMessage/CodeBlockMessage.js +1 -1
  19. package/dist/esm/Message/Message.test.js +3 -3
  20. package/dist/esm/MessageBar/AttachButton.js +1 -1
  21. package/dist/esm/MessageBar/AttachButton.test.js +7 -7
  22. package/dist/esm/MessageBar/MessageBar.test.js +29 -29
  23. package/dist/esm/MessageBar/MicrophoneButton.js +1 -1
  24. package/dist/esm/MessageBar/SendButton.js +1 -1
  25. package/dist/esm/MessageBar/SendButton.test.js +5 -5
  26. package/dist/esm/MessageBar/StopButton.js +1 -1
  27. package/dist/esm/MessageBar/StopButton.test.js +5 -5
  28. package/dist/esm/MessageBox/JumpButton.js +1 -1
  29. package/dist/esm/MessageBox/JumpButton.test.js +4 -4
  30. package/dist/esm/MessageBox/MessageBox.test.js +2 -2
  31. package/dist/esm/ResponseActions/ResponseActionButton.d.ts +2 -2
  32. package/dist/esm/ResponseActions/ResponseActions.d.ts +4 -1
  33. package/dist/esm/ResponseActions/ResponseActions.js +6 -6
  34. package/dist/esm/ResponseActions/ResponseActions.test.js +16 -1
  35. package/package.json +1 -1
  36. package/src/Message/CodeBlockMessage/CodeBlockMessage.tsx +1 -1
  37. package/src/Message/Message.test.tsx +3 -3
  38. package/src/MessageBar/AttachButton.test.tsx +7 -7
  39. package/src/MessageBar/AttachButton.tsx +1 -1
  40. package/src/MessageBar/MessageBar.test.tsx +29 -29
  41. package/src/MessageBar/MicrophoneButton.tsx +2 -1
  42. package/src/MessageBar/SendButton.test.tsx +5 -5
  43. package/src/MessageBar/SendButton.tsx +1 -1
  44. package/src/MessageBar/StopButton.test.tsx +5 -5
  45. package/src/MessageBar/StopButton.tsx +1 -1
  46. package/src/MessageBox/JumpButton.test.tsx +4 -4
  47. package/src/MessageBox/JumpButton.tsx +1 -1
  48. package/src/MessageBox/MessageBox.test.tsx +2 -2
  49. package/src/ResponseActions/ResponseActionButton.tsx +2 -2
  50. package/src/ResponseActions/ResponseActions.test.tsx +18 -1
  51. package/src/ResponseActions/ResponseActions.tsx +10 -1
@@ -15,11 +15,11 @@ import { AttachButton } from './AttachButton';
15
15
  describe('Attach button', () => {
16
16
  it('should render button correctly', () => {
17
17
  render(React.createElement(AttachButton, null));
18
- expect(screen.getByRole('button', { name: 'Attach button' })).toBeTruthy();
18
+ expect(screen.getByRole('button', { name: 'Attach' })).toBeTruthy();
19
19
  });
20
20
  it('should handle isDisabled prop', () => {
21
21
  render(React.createElement(AttachButton, { isDisabled: true }));
22
- expect(screen.getByRole('button', { name: 'Attach button' })).toBeDisabled();
22
+ expect(screen.getByRole('button', { name: 'Attach' })).toBeDisabled();
23
23
  });
24
24
  it('should handle spread props, including aria-label', () => {
25
25
  render(React.createElement(AttachButton, { "aria-label": "test" }));
@@ -28,22 +28,22 @@ describe('Attach button', () => {
28
28
  it('should handle onClick', () => __awaiter(void 0, void 0, void 0, function* () {
29
29
  const spy = jest.fn();
30
30
  render(React.createElement(AttachButton, { onClick: spy }));
31
- yield userEvent.click(screen.getByRole('button', { name: 'Attach button' }));
31
+ yield userEvent.click(screen.getByRole('button', { name: 'Attach' }));
32
32
  expect(screen.getByRole('tooltip', { name: 'Attach' })).toBeTruthy();
33
33
  expect(spy).toHaveBeenCalledTimes(1);
34
34
  }));
35
35
  it('should handle className prop', () => {
36
36
  render(React.createElement(AttachButton, { className: "test" }));
37
- expect(screen.getByRole('button', { name: 'Attach button' })).toHaveClass('test');
37
+ expect(screen.getByRole('button', { name: 'Attach' })).toHaveClass('test');
38
38
  });
39
39
  it('should handle custom tooltip correctly', () => __awaiter(void 0, void 0, void 0, function* () {
40
40
  render(React.createElement(AttachButton, { onClick: jest.fn, tooltipContent: "Test" }));
41
- yield userEvent.click(screen.getByRole('button', { name: 'Attach button' }));
41
+ yield userEvent.click(screen.getByRole('button', { name: 'Attach' }));
42
42
  expect(screen.getByRole('tooltip', { name: 'Test' })).toBeTruthy();
43
43
  }));
44
44
  it('should handle tooltipProps prop', () => __awaiter(void 0, void 0, void 0, function* () {
45
45
  render(React.createElement(AttachButton, { tooltipProps: { id: 'test' } }));
46
- yield userEvent.click(screen.getByRole('button', { name: 'Attach button' }));
46
+ yield userEvent.click(screen.getByRole('button', { name: 'Attach' }));
47
47
  expect(screen.getByRole('tooltip', { name: 'Attach' })).toHaveAttribute('id', 'test');
48
48
  }));
49
49
  // Based on this because I had no idea how to do this and was looking around: https://stackoverflow.com/a/75562651
@@ -51,7 +51,7 @@ describe('Attach button', () => {
51
51
  it('should handle onAttachAccepted prop', () => __awaiter(void 0, void 0, void 0, function* () {
52
52
  const spy = jest.fn();
53
53
  render(React.createElement(AttachButton, { onAttachAccepted: spy, inputTestId: "input" }));
54
- yield userEvent.click(screen.getByRole('button', { name: 'Attach button' }));
54
+ yield userEvent.click(screen.getByRole('button', { name: 'Attach' }));
55
55
  const file = new File(['test'], 'test.json');
56
56
  const input = screen.getByTestId('input');
57
57
  yield userEvent.upload(input, file);
@@ -48,9 +48,9 @@ describe('Message bar', () => {
48
48
  });
49
49
  it('should render correctly', () => {
50
50
  render(React.createElement(MessageBar, { onSendMessage: jest.fn }));
51
- expect(screen.getByRole('button', { name: 'Attach button' })).toBeTruthy();
52
- expect(screen.queryByRole('button', { name: 'Send button' })).toBeFalsy();
53
- expect(screen.queryByRole('button', { name: 'Microphone button' })).toBeFalsy();
51
+ expect(screen.getByRole('button', { name: 'Attach' })).toBeTruthy();
52
+ expect(screen.queryByRole('button', { name: 'Send' })).toBeFalsy();
53
+ expect(screen.queryByRole('button', { name: 'Use microphone' })).toBeFalsy();
54
54
  expect(screen.getByRole('textbox', { name: /Send a message.../i })).toBeTruthy();
55
55
  });
56
56
  it('can send via enter key', () => __awaiter(void 0, void 0, void 0, function* () {
@@ -84,15 +84,15 @@ describe('Message bar', () => {
84
84
  const input = screen.getByRole('textbox', { name: /Send a message.../i });
85
85
  yield userEvent.type(input, 'Hello world');
86
86
  expect(input).toHaveTextContent('Hello world');
87
- expect(screen.getByRole('button', { name: 'Send button' })).toBeTruthy();
87
+ expect(screen.getByRole('button', { name: 'Send' })).toBeTruthy();
88
88
  }));
89
89
  it('can disable send button shown when text is input', () => __awaiter(void 0, void 0, void 0, function* () {
90
90
  render(React.createElement(MessageBar, { onSendMessage: jest.fn, isSendButtonDisabled: true }));
91
91
  const input = screen.getByRole('textbox', { name: /Send a message.../i });
92
92
  yield userEvent.type(input, 'Hello world');
93
93
  expect(input).toHaveTextContent('Hello world');
94
- expect(screen.getByRole('button', { name: 'Send button' })).toBeTruthy();
95
- expect(screen.getByRole('button', { name: 'Send button' })).toBeDisabled();
94
+ expect(screen.getByRole('button', { name: 'Send' })).toBeTruthy();
95
+ expect(screen.getByRole('button', { name: 'Send' })).toBeDisabled();
96
96
  }));
97
97
  it('can click send button', () => __awaiter(void 0, void 0, void 0, function* () {
98
98
  const spy = jest.fn();
@@ -100,24 +100,24 @@ describe('Message bar', () => {
100
100
  const input = screen.getByRole('textbox', { name: /Send a message.../i });
101
101
  yield userEvent.type(input, 'Hello world');
102
102
  expect(input).toHaveTextContent('Hello world');
103
- const sendButton = screen.getByRole('button', { name: 'Send button' });
103
+ const sendButton = screen.getByRole('button', { name: 'Send' });
104
104
  expect(sendButton).toBeTruthy();
105
105
  yield userEvent.click(sendButton);
106
106
  expect(spy).toHaveBeenCalledTimes(1);
107
107
  }));
108
108
  it('can always show send button', () => {
109
109
  render(React.createElement(MessageBar, { onSendMessage: jest.fn, alwayShowSendButton: true }));
110
- expect(screen.getByRole('button', { name: 'Send button' })).toBeTruthy();
111
- expect(screen.getByRole('button', { name: 'Send button' })).toBeEnabled();
110
+ expect(screen.getByRole('button', { name: 'Send' })).toBeTruthy();
111
+ expect(screen.getByRole('button', { name: 'Send' })).toBeEnabled();
112
112
  });
113
113
  it('can disable send button if always showing', () => {
114
114
  render(React.createElement(MessageBar, { onSendMessage: jest.fn, alwayShowSendButton: true, isSendButtonDisabled: true }));
115
- expect(screen.getByRole('button', { name: 'Send button' })).toBeTruthy();
116
- expect(screen.getByRole('button', { name: 'Send button' })).toBeDisabled();
115
+ expect(screen.getByRole('button', { name: 'Send' })).toBeTruthy();
116
+ expect(screen.getByRole('button', { name: 'Send' })).toBeDisabled();
117
117
  });
118
118
  it('can handle buttonProps tooltipContent appropriately for send', () => __awaiter(void 0, void 0, void 0, function* () {
119
119
  render(React.createElement(MessageBar, { onSendMessage: jest.fn, alwayShowSendButton: true, buttonProps: { send: { tooltipContent: 'Test' } } }));
120
- yield userEvent.click(screen.getByRole('button', { name: 'Send button' }));
120
+ yield userEvent.click(screen.getByRole('button', { name: 'Send' }));
121
121
  expect(screen.getByRole('tooltip', { name: 'Test' })).toBeTruthy();
122
122
  }));
123
123
  it('can handle buttonProps props appropriately for send', () => __awaiter(void 0, void 0, void 0, function* () {
@@ -158,30 +158,30 @@ describe('Message bar', () => {
158
158
  expect(screen.queryByRole('menuitem', { name: /Logs/i })).toBeFalsy();
159
159
  expect(screen.queryByRole('menuitem', { name: /YAML - Status/i })).toBeFalsy();
160
160
  expect(screen.queryByRole('menuitem', { name: /YAML - All contents/i })).toBeFalsy();
161
- const attachButton = screen.getByRole('button', { name: 'Attach button' });
161
+ const attachButton = screen.getByRole('button', { name: 'Attach' });
162
162
  yield userEvent.click(attachButton);
163
163
  expect(attachToggleClickSpy).toHaveBeenCalledTimes(1);
164
164
  }));
165
165
  it('can hide attach button', () => {
166
166
  render(React.createElement(MessageBar, { onSendMessage: jest.fn, hasAttachButton: false }));
167
- expect(screen.queryByRole('button', { name: 'Attach button' })).toBeFalsy();
167
+ expect(screen.queryByRole('button', { name: 'Attach' })).toBeFalsy();
168
168
  });
169
169
  // Based on this because I had no idea how to do this and was looking around: https://stackoverflow.com/a/75562651
170
170
  // See also https://developer.mozilla.org/en-US/docs/Web/API/File/File for what that file variable is doing
171
171
  it('can handle handleAttach', () => __awaiter(void 0, void 0, void 0, function* () {
172
172
  const spy = jest.fn();
173
173
  render(React.createElement(MessageBar, { onSendMessage: jest.fn, hasAttachButton: true, handleAttach: spy, buttonProps: { attach: { inputTestId: 'input' } } }));
174
- expect(screen.getByRole('button', { name: 'Attach button' })).toBeTruthy();
175
- yield userEvent.click(screen.getByRole('button', { name: 'Attach button' }));
174
+ expect(screen.getByRole('button', { name: 'Attach' })).toBeTruthy();
175
+ yield userEvent.click(screen.getByRole('button', { name: 'Attach' }));
176
176
  const file = new File(['test'], 'test.json');
177
177
  const input = screen.getByTestId('input');
178
178
  yield userEvent.upload(input, file);
179
179
  expect(input.files).toHaveLength(1);
180
180
  expect(spy).toHaveBeenCalledTimes(1);
181
181
  }));
182
- it('can handle buttonProps tooltipContent appropriately for attach', () => __awaiter(void 0, void 0, void 0, function* () {
182
+ it('can handle buttonProps tooltipContent appropriately for attach', () => __awaiter(void 0, void 0, void 0, function* () {
183
183
  render(React.createElement(MessageBar, { onSendMessage: jest.fn, hasAttachButton: true, buttonProps: { attach: { tooltipContent: 'Test' } } }));
184
- yield userEvent.click(screen.getByRole('button', { name: 'Attach button' }));
184
+ yield userEvent.click(screen.getByRole('button', { name: 'Attach' }));
185
185
  expect(screen.getByRole('tooltip', { name: 'Test' })).toBeTruthy();
186
186
  }));
187
187
  it('can handle buttonProps props appropriately for attach', () => __awaiter(void 0, void 0, void 0, function* () {
@@ -192,17 +192,17 @@ describe('Message bar', () => {
192
192
  // --------------------------------------------------------------------------
193
193
  it('can show stop button', () => {
194
194
  render(React.createElement(MessageBar, { onSendMessage: jest.fn, hasStopButton: true, handleStopButton: jest.fn }));
195
- expect(screen.getByRole('button', { name: 'Stop button' })).toBeTruthy();
195
+ expect(screen.getByRole('button', { name: 'Stop' })).toBeTruthy();
196
196
  });
197
197
  it('can call handleStopButton', () => __awaiter(void 0, void 0, void 0, function* () {
198
198
  const spy = jest.fn();
199
199
  render(React.createElement(MessageBar, { onSendMessage: jest.fn, hasStopButton: true, handleStopButton: spy }));
200
- yield userEvent.click(screen.getByRole('button', { name: 'Stop button' }));
200
+ yield userEvent.click(screen.getByRole('button', { name: 'Stop' }));
201
201
  expect(spy).toHaveBeenCalledTimes(1);
202
202
  }));
203
203
  it('can handle buttonProps tooltipContent appropriately for stop', () => __awaiter(void 0, void 0, void 0, function* () {
204
204
  render(React.createElement(MessageBar, { onSendMessage: jest.fn, hasStopButton: true, handleStopButton: jest.fn, buttonProps: { stop: { tooltipContent: 'Test' } } }));
205
- yield userEvent.click(screen.getByRole('button', { name: 'Stop button' }));
205
+ yield userEvent.click(screen.getByRole('button', { name: 'Stop' }));
206
206
  expect(screen.getByRole('tooltip', { name: 'Test' })).toBeTruthy();
207
207
  }));
208
208
  it('can handle buttonProps props appropriately for stop', () => __awaiter(void 0, void 0, void 0, function* () {
@@ -213,27 +213,27 @@ describe('Message bar', () => {
213
213
  // --------------------------------------------------------------------------
214
214
  it('can hide microphone button when window.SpeechRecognition is not there', () => {
215
215
  render(React.createElement(MessageBar, { onSendMessage: jest.fn, hasMicrophoneButton: true }));
216
- expect(screen.queryByRole('button', { name: 'Microphone button' })).toBeFalsy();
216
+ expect(screen.queryByRole('button', { name: 'Use microphone' })).toBeFalsy();
217
217
  });
218
218
  it('can show microphone button', () => {
219
219
  mockSpeechRecognition();
220
220
  render(React.createElement(MessageBar, { onSendMessage: jest.fn, hasMicrophoneButton: true }));
221
- expect(screen.getByRole('button', { name: 'Microphone button' })).toBeTruthy();
221
+ expect(screen.getByRole('button', { name: 'Use microphone' })).toBeTruthy();
222
222
  });
223
223
  it('can handle buttonProps appropriately for microphone', () => __awaiter(void 0, void 0, void 0, function* () {
224
224
  mockSpeechRecognition();
225
225
  render(React.createElement(MessageBar, { onSendMessage: jest.fn, hasMicrophoneButton: true, buttonProps: {
226
226
  microphone: { tooltipContent: { active: 'Currently listening', inactive: 'Not currently listening' } }
227
227
  } }));
228
- yield userEvent.click(screen.getByRole('button', { name: 'Microphone button' }));
228
+ yield userEvent.click(screen.getByRole('button', { name: 'Use microphone' }));
229
229
  expect(screen.getByRole('tooltip', { name: 'Currently listening' })).toBeTruthy();
230
- yield userEvent.click(screen.getByRole('button', { name: 'Microphone button' }));
230
+ yield userEvent.click(screen.getByRole('button', { name: 'Stop listening' }));
231
231
  expect(screen.getByRole('tooltip', { name: 'Not currently listening' })).toBeTruthy();
232
232
  }));
233
233
  it('can customize the listening placeholder', () => __awaiter(void 0, void 0, void 0, function* () {
234
234
  mockSpeechRecognition();
235
235
  render(React.createElement(MessageBar, { onSendMessage: jest.fn, hasMicrophoneButton: true, listeningText: "I am listening" }));
236
- yield userEvent.click(screen.getByRole('button', { name: 'Microphone button' }));
236
+ yield userEvent.click(screen.getByRole('button', { name: 'Use microphone' }));
237
237
  const input = screen.getByRole('textbox', { name: /I am listening/i });
238
238
  expect(input).toBeTruthy();
239
239
  }));
@@ -244,9 +244,9 @@ describe('Message bar', () => {
244
244
  }));
245
245
  it('can be controlled', () => {
246
246
  render(React.createElement(MessageBar, { onSendMessage: jest.fn, value: "test" }));
247
- expect(screen.getByRole('button', { name: 'Attach button' })).toBeTruthy();
248
- expect(screen.getByRole('button', { name: 'Send button' })).toBeTruthy();
249
- expect(screen.queryByRole('button', { name: 'Microphone button' })).toBeFalsy();
247
+ expect(screen.getByRole('button', { name: 'Attach' })).toBeTruthy();
248
+ expect(screen.getByRole('button', { name: 'Send' })).toBeTruthy();
249
+ expect(screen.queryByRole('button', { name: 'Use microphone' })).toBeFalsy();
250
250
  expect(screen.getByRole('textbox', { name: /Send a message.../i })).toBeTruthy();
251
251
  expect(screen.getByRole('textbox', { name: /Send a message.../i })).toHaveValue('test');
252
252
  });
@@ -63,7 +63,7 @@ export const MicrophoneButton = (_a) => {
63
63
  return null;
64
64
  }
65
65
  return (React.createElement(Tooltip, Object.assign({ aria: "none", "aria-live": "polite", id: "pf-chatbot__tooltip--use-microphone", content: isListening ? tooltipContent.active : tooltipContent.inactive, position: (tooltipProps === null || tooltipProps === void 0 ? void 0 : tooltipProps.position) || 'top', entryDelay: (tooltipProps === null || tooltipProps === void 0 ? void 0 : tooltipProps.entryDelay) || 0, exitDelay: (tooltipProps === null || tooltipProps === void 0 ? void 0 : tooltipProps.exitDelay) || 0, distance: (tooltipProps === null || tooltipProps === void 0 ? void 0 : tooltipProps.distance) || 8, animationDuration: (tooltipProps === null || tooltipProps === void 0 ? void 0 : tooltipProps.animationDuration) || 0 }, tooltipProps),
66
- React.createElement(Button, Object.assign({ variant: "plain", className: `pf-chatbot__button--microphone ${isListening ? 'pf-chatbot__button--microphone--active' : ''} ${isCompact ? 'pf-m-compact' : ''} ${className !== null && className !== void 0 ? className : ''}`, "aria-label": props['aria-label'] || 'Microphone button', onClick: isListening ? stopListening : startListening, icon: React.createElement(Icon, { iconSize: isCompact ? 'lg' : 'xl', isInline: true },
66
+ React.createElement(Button, Object.assign({ variant: "plain", className: `pf-chatbot__button--microphone ${isListening ? 'pf-chatbot__button--microphone--active' : ''} ${isCompact ? 'pf-m-compact' : ''} ${className !== null && className !== void 0 ? className : ''}`, "aria-label": props['aria-label'] || (isListening ? 'Stop listening' : 'Use microphone'), "aria-pressed": isListening, onClick: isListening ? stopListening : startListening, icon: React.createElement(Icon, { iconSize: isCompact ? 'lg' : 'xl', isInline: true },
67
67
  React.createElement(MicrophoneIcon, null)), size: isCompact ? 'sm' : undefined }, props))));
68
68
  };
69
69
  export default MicrophoneButton;
@@ -21,7 +21,7 @@ export const SendButton = (_a) => {
21
21
  return (React.createElement(Tooltip, Object.assign({ id: "pf-chatbot__tooltip--send", content: tooltipContent, position: (tooltipProps === null || tooltipProps === void 0 ? void 0 : tooltipProps.position) || 'top', entryDelay: (tooltipProps === null || tooltipProps === void 0 ? void 0 : tooltipProps.entryDelay) || 0, exitDelay: (tooltipProps === null || tooltipProps === void 0 ? void 0 : tooltipProps.exitDelay) || 0, distance: (tooltipProps === null || tooltipProps === void 0 ? void 0 : tooltipProps.distance) || 8, animationDuration: (tooltipProps === null || tooltipProps === void 0 ? void 0 : tooltipProps.animationDuration) || 0,
22
22
  // prevents VO announcements of both aria label and tooltip
23
23
  aria: "none" }, tooltipProps),
24
- React.createElement(Button, Object.assign({ variant: "plain", className: `pf-chatbot__button--send ${isCompact ? 'pf-m-compact' : ''} ${className !== null && className !== void 0 ? className : ''}`, "aria-label": props['aria-label'] || 'Send button', onClick: onClick, icon: React.createElement(Icon, { iconSize: isCompact ? 'lg' : 'xl', isInline: true },
24
+ React.createElement(Button, Object.assign({ variant: "plain", className: `pf-chatbot__button--send ${isCompact ? 'pf-m-compact' : ''} ${className !== null && className !== void 0 ? className : ''}`, "aria-label": props['aria-label'] || 'Send', onClick: onClick, icon: React.createElement(Icon, { iconSize: isCompact ? 'lg' : 'xl', isInline: true },
25
25
  React.createElement(PaperPlaneIcon, null)), size: isCompact ? 'sm' : undefined }, props))));
26
26
  };
27
27
  export default SendButton;
@@ -19,23 +19,23 @@ const renderSend = (props) => {
19
19
  describe('Send button', () => {
20
20
  it('should render button correctly', () => {
21
21
  renderSend();
22
- expect(screen.getByRole('button', { name: 'Send button' })).toBeTruthy();
22
+ expect(screen.getByRole('button', { name: 'Send' })).toBeTruthy();
23
23
  });
24
24
  it('should handle onClick correctly', () => __awaiter(void 0, void 0, void 0, function* () {
25
25
  const spy = jest.fn();
26
26
  render(React.createElement(SendButton, { onClick: spy }));
27
- yield userEvent.click(screen.getByRole('button', { name: 'Send button' }));
27
+ yield userEvent.click(screen.getByRole('button', { name: 'Send' }));
28
28
  expect(screen.getByRole('tooltip', { name: 'Send' })).toBeTruthy();
29
29
  expect(spy).toHaveBeenCalledTimes(1);
30
30
  }));
31
31
  it('should handle custom tooltip correctly', () => __awaiter(void 0, void 0, void 0, function* () {
32
32
  render(React.createElement(SendButton, { onClick: jest.fn, tooltipContent: "Test" }));
33
- yield userEvent.click(screen.getByRole('button', { name: 'Send button' }));
33
+ yield userEvent.click(screen.getByRole('button', { name: 'Send' }));
34
34
  expect(screen.getByRole('tooltip', { name: 'Test' })).toBeTruthy();
35
35
  }));
36
36
  it('should handle className prop', () => {
37
37
  renderSend({ className: 'test' });
38
- expect(screen.getByRole('button', { name: 'Send button' })).toHaveClass('test');
38
+ expect(screen.getByRole('button', { name: 'Send' })).toHaveClass('test');
39
39
  });
40
40
  it('should handle spread props, including aria-label', () => {
41
41
  renderSend({ 'aria-label': 'test' });
@@ -43,7 +43,7 @@ describe('Send button', () => {
43
43
  });
44
44
  it('should handle tooltipProps prop', () => __awaiter(void 0, void 0, void 0, function* () {
45
45
  renderSend({ tooltipProps: { id: 'test' } });
46
- yield userEvent.click(screen.getByRole('button', { name: 'Send button' }));
46
+ yield userEvent.click(screen.getByRole('button', { name: 'Send' }));
47
47
  expect(screen.getByRole('tooltip', { name: 'Send' })).toHaveAttribute('id', 'test');
48
48
  }));
49
49
  it('should handle isCompact', () => {
@@ -20,7 +20,7 @@ export const StopButton = (_a) => {
20
20
  return (React.createElement(Tooltip, Object.assign({ id: "pf-chatbot__tooltip--stop", content: tooltipContent, position: (tooltipProps === null || tooltipProps === void 0 ? void 0 : tooltipProps.position) || 'top', entryDelay: (tooltipProps === null || tooltipProps === void 0 ? void 0 : tooltipProps.entryDelay) || 0, exitDelay: (tooltipProps === null || tooltipProps === void 0 ? void 0 : tooltipProps.exitDelay) || 0, distance: (tooltipProps === null || tooltipProps === void 0 ? void 0 : tooltipProps.distance) || 8, animationDuration: (tooltipProps === null || tooltipProps === void 0 ? void 0 : tooltipProps.animationDuration) || 0,
21
21
  // prevents VO announcements of both aria label and tooltip
22
22
  aria: "none" }, tooltipProps),
23
- React.createElement(Button, Object.assign({ className: `pf-chatbot__button--stop ${isCompact ? 'pf-m-compact' : ''} ${className !== null && className !== void 0 ? className : ''}`, variant: "link", "aria-label": props['aria-label'] || 'Stop button', onClick: onClick, icon: React.createElement(Icon, { iconSize: isCompact ? 'lg' : 'xl', isInline: true },
23
+ React.createElement(Button, Object.assign({ className: `pf-chatbot__button--stop ${isCompact ? 'pf-m-compact' : ''} ${className !== null && className !== void 0 ? className : ''}`, variant: "link", "aria-label": props['aria-label'] || 'Stop', onClick: onClick, icon: React.createElement(Icon, { iconSize: isCompact ? 'lg' : 'xl', isInline: true },
24
24
  React.createElement("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", xmlns: "http://www.w3.org/2000/svg" },
25
25
  React.createElement("path", { d: "M0.5 3C0.5 1.62109 1.62109 0.5 3 0.5H13C14.3789 0.5 15.5 1.62109 15.5 3V13C15.5 14.3789 14.3789 15.5 13 15.5H3C1.62109 15.5 0.5 14.3789 0.5 13V3Z", fill: "currentColor" }))), size: isCompact ? 'sm' : undefined }, props))));
26
26
  };
@@ -19,23 +19,23 @@ const renderStop = (props) => {
19
19
  describe('Stop button', () => {
20
20
  it('should render button correctly', () => {
21
21
  renderStop();
22
- expect(screen.getByRole('button', { name: 'Stop button' })).toBeTruthy();
22
+ expect(screen.getByRole('button', { name: 'Stop' })).toBeTruthy();
23
23
  });
24
24
  it('should handle onClick correctly', () => __awaiter(void 0, void 0, void 0, function* () {
25
25
  const spy = jest.fn();
26
26
  render(React.createElement(StopButton, { onClick: spy }));
27
- yield userEvent.click(screen.getByRole('button', { name: 'Stop button' }));
27
+ yield userEvent.click(screen.getByRole('button', { name: 'Stop' }));
28
28
  expect(screen.getByRole('tooltip', { name: 'Stop' })).toBeTruthy();
29
29
  expect(spy).toHaveBeenCalledTimes(1);
30
30
  }));
31
31
  it('should handle custom tooltip correctly', () => __awaiter(void 0, void 0, void 0, function* () {
32
32
  render(React.createElement(StopButton, { onClick: jest.fn, tooltipContent: "Test" }));
33
- yield userEvent.click(screen.getByRole('button', { name: 'Stop button' }));
33
+ yield userEvent.click(screen.getByRole('button', { name: 'Stop' }));
34
34
  expect(screen.getByRole('tooltip', { name: 'Test' })).toBeTruthy();
35
35
  }));
36
36
  it('should handle className prop', () => {
37
37
  renderStop({ className: 'test' });
38
- expect(screen.getByRole('button', { name: 'Stop button' })).toHaveClass('test');
38
+ expect(screen.getByRole('button', { name: 'Stop' })).toHaveClass('test');
39
39
  });
40
40
  it('should handle spread props, including aria-label', () => {
41
41
  renderStop({ 'aria-label': 'test' });
@@ -43,7 +43,7 @@ describe('Stop button', () => {
43
43
  });
44
44
  it('should handle tooltipProps prop', () => __awaiter(void 0, void 0, void 0, function* () {
45
45
  renderStop({ tooltipProps: { id: 'test' } });
46
- yield userEvent.click(screen.getByRole('button', { name: 'Stop button' }));
46
+ yield userEvent.click(screen.getByRole('button', { name: 'Stop' }));
47
47
  expect(screen.getByRole('tooltip', { name: 'Stop' })).toHaveAttribute('id', 'test');
48
48
  }));
49
49
  it('should handle isCompact', () => {
@@ -7,6 +7,6 @@ import { Button, Tooltip, Icon } from '@patternfly/react-core';
7
7
  import { ArrowUpIcon } from '@patternfly/react-icons/dist/esm/icons/arrow-up-icon';
8
8
  import { ArrowDownIcon } from '@patternfly/react-icons/dist/esm/icons/arrow-down-icon';
9
9
  const JumpButton = ({ position, isHidden, onClick }) => isHidden ? null : (React.createElement(Tooltip, { id: `pf-chatbot__tooltip--jump-${position}`, content: `Back to ${position}`, position: "top" },
10
- React.createElement(Button, { variant: "plain", className: `pf-chatbot__jump pf-chatbot__jump--${position}`, "aria-label": `Jump ${position} button`, onClick: onClick },
10
+ React.createElement(Button, { variant: "plain", className: `pf-chatbot__jump pf-chatbot__jump--${position}`, "aria-label": `Jump ${position}`, onClick: onClick },
11
11
  React.createElement(Icon, { iconSize: "lg", isInline: true }, position === 'top' ? React.createElement(ArrowUpIcon, null) : React.createElement(ArrowDownIcon, null)))));
12
12
  export default JumpButton;
@@ -15,20 +15,20 @@ import userEvent from '@testing-library/user-event';
15
15
  describe('JumpButton', () => {
16
16
  it('should render top button correctly', () => {
17
17
  render(React.createElement(JumpButton, { position: "top", onClick: jest.fn() }));
18
- expect(screen.getByRole('button', { name: /Jump top button/i })).toBeTruthy();
18
+ expect(screen.getByRole('button', { name: /Jump top/i })).toBeTruthy();
19
19
  });
20
20
  it('should render bottom button correctly', () => {
21
21
  render(React.createElement(JumpButton, { position: "bottom", onClick: jest.fn() }));
22
- expect(screen.getByRole('button', { name: /Jump bottom button/i })).toBeTruthy();
22
+ expect(screen.getByRole('button', { name: /Jump bottom/i })).toBeTruthy();
23
23
  });
24
24
  it('should call onClick appropriately', () => __awaiter(void 0, void 0, void 0, function* () {
25
25
  const spy = jest.fn();
26
26
  render(React.createElement(JumpButton, { position: "bottom", onClick: spy }));
27
- yield userEvent.click(screen.getByRole('button', { name: /Jump bottom button/i }));
27
+ yield userEvent.click(screen.getByRole('button', { name: /Jump bottom/i }));
28
28
  expect(spy).toHaveBeenCalledTimes(1);
29
29
  }));
30
30
  it('should be hidden if isHidden prop is used', () => __awaiter(void 0, void 0, void 0, function* () {
31
31
  render(React.createElement(JumpButton, { position: "bottom", onClick: jest.fn(), isHidden: true }));
32
- expect(screen.queryByRole('button', { name: /Jump bottom button/i })).toBeFalsy();
32
+ expect(screen.queryByRole('button', { name: /Jump bottom/i })).toBeFalsy();
33
33
  }));
34
34
  });
@@ -35,7 +35,7 @@ describe('MessageBox', () => {
35
35
  Object.defineProperty(region, 'scrollTop', { configurable: true, value: 0 });
36
36
  region.dispatchEvent(new Event('scroll'));
37
37
  yield waitFor(() => {
38
- userEvent.click(screen.getByRole('button', { name: /Jump bottom button/i }));
38
+ userEvent.click(screen.getByRole('button', { name: /Jump bottom/i }));
39
39
  expect(spy).toHaveBeenCalled();
40
40
  });
41
41
  }));
@@ -53,7 +53,7 @@ describe('MessageBox', () => {
53
53
  });
54
54
  region.dispatchEvent(new Event('scroll'));
55
55
  yield waitFor(() => {
56
- userEvent.click(screen.getByRole('button', { name: /Jump top button/i }));
56
+ userEvent.click(screen.getByRole('button', { name: /Jump top/i }));
57
57
  expect(spy).toHaveBeenCalled();
58
58
  });
59
59
  }));
@@ -1,6 +1,6 @@
1
1
  import React from 'react';
2
- import { TooltipProps } from '@patternfly/react-core';
3
- export interface ResponseActionButtonProps {
2
+ import { ButtonProps, TooltipProps } from '@patternfly/react-core';
3
+ export interface ResponseActionButtonProps extends ButtonProps {
4
4
  /** Aria-label for the button. Defaults to the value of the tooltipContent if none provided */
5
5
  ariaLabel?: string;
6
6
  /** Aria-label for the button, shown when the button is clicked. Defaults to the value of ariaLabel or tooltipContent if not provided. */
@@ -26,9 +26,12 @@ export interface ActionProps extends Omit<ButtonProps, 'ref'> {
26
26
  /** Id for content controlled by the button, such as the feedback form */
27
27
  'aria-controls'?: string;
28
28
  }
29
+ type ExtendedActionProps = ActionProps & {
30
+ [key: string]: any;
31
+ };
29
32
  export interface ResponseActionProps {
30
33
  /** Props for message actions, such as feedback (positive or negative), copy button, share, and listen */
31
- actions: Record<string, ActionProps | undefined> & {
34
+ actions: Record<string, ExtendedActionProps | undefined> & {
32
35
  positive?: ActionProps;
33
36
  negative?: ActionProps;
34
37
  copy?: ActionProps;
@@ -33,14 +33,14 @@ export const ResponseActions = ({ actions }) => {
33
33
  onClick && onClick(e);
34
34
  };
35
35
  return (React.createElement("div", { ref: responseActions, className: "pf-chatbot__response-actions" },
36
- positive && (React.createElement(ResponseActionButton, { ariaLabel: (_a = positive.ariaLabel) !== null && _a !== void 0 ? _a : 'Good response', clickedAriaLabel: (_b = positive.ariaLabel) !== null && _b !== void 0 ? _b : 'Response recorded', onClick: (e) => handleClick(e, 'positive', positive.onClick), className: positive.className, isDisabled: positive.isDisabled, tooltipContent: (_c = positive.tooltipContent) !== null && _c !== void 0 ? _c : 'Good response', clickedTooltipContent: (_d = positive.clickedTooltipContent) !== null && _d !== void 0 ? _d : 'Response recorded', tooltipProps: positive.tooltipProps, icon: React.createElement(OutlinedThumbsUpIcon, null), isClicked: activeButton === 'positive', ref: positive.ref, "aria-expanded": positive['aria-expanded'], "aria-controls": positive['aria-controls'] })),
37
- negative && (React.createElement(ResponseActionButton, { ariaLabel: (_e = negative.ariaLabel) !== null && _e !== void 0 ? _e : 'Bad response', clickedAriaLabel: (_f = negative.ariaLabel) !== null && _f !== void 0 ? _f : 'Response recorded', onClick: (e) => handleClick(e, 'negative', negative.onClick), className: negative.className, isDisabled: negative.isDisabled, tooltipContent: (_g = negative.tooltipContent) !== null && _g !== void 0 ? _g : 'Bad response', clickedTooltipContent: (_h = negative.clickedTooltipContent) !== null && _h !== void 0 ? _h : 'Response recorded', tooltipProps: negative.tooltipProps, icon: React.createElement(OutlinedThumbsDownIcon, null), isClicked: activeButton === 'negative', ref: negative.ref, "aria-expanded": negative['aria-expanded'], "aria-controls": negative['aria-controls'] })),
38
- copy && (React.createElement(ResponseActionButton, { ariaLabel: (_j = copy.ariaLabel) !== null && _j !== void 0 ? _j : 'Copy', clickedAriaLabel: (_k = copy.ariaLabel) !== null && _k !== void 0 ? _k : 'Copied', onClick: (e) => handleClick(e, 'copy', copy.onClick), className: copy.className, isDisabled: copy.isDisabled, tooltipContent: (_l = copy.tooltipContent) !== null && _l !== void 0 ? _l : 'Copy', clickedTooltipContent: (_m = copy.clickedTooltipContent) !== null && _m !== void 0 ? _m : 'Copied', tooltipProps: copy.tooltipProps, icon: React.createElement(OutlinedCopyIcon, null), isClicked: activeButton === 'copy', ref: copy.ref, "aria-expanded": copy['aria-expanded'], "aria-controls": copy['aria-controls'] })),
39
- share && (React.createElement(ResponseActionButton, { ariaLabel: (_o = share.ariaLabel) !== null && _o !== void 0 ? _o : 'Share', clickedAriaLabel: (_p = share.ariaLabel) !== null && _p !== void 0 ? _p : 'Shared', onClick: (e) => handleClick(e, 'share', share.onClick), className: share.className, isDisabled: share.isDisabled, tooltipContent: (_q = share.tooltipContent) !== null && _q !== void 0 ? _q : 'Share', clickedTooltipContent: (_r = share.clickedTooltipContent) !== null && _r !== void 0 ? _r : 'Shared', tooltipProps: share.tooltipProps, icon: React.createElement(ExternalLinkAltIcon, null), isClicked: activeButton === 'share', ref: share.ref, "aria-expanded": share['aria-expanded'], "aria-controls": share['aria-controls'] })),
40
- listen && (React.createElement(ResponseActionButton, { ariaLabel: (_s = listen.ariaLabel) !== null && _s !== void 0 ? _s : 'Listen', clickedAriaLabel: (_t = listen.ariaLabel) !== null && _t !== void 0 ? _t : 'Listening', onClick: (e) => handleClick(e, 'listen', listen.onClick), className: listen.className, isDisabled: listen.isDisabled, tooltipContent: (_u = listen.tooltipContent) !== null && _u !== void 0 ? _u : 'Listen', clickedTooltipContent: (_v = listen.clickedTooltipContent) !== null && _v !== void 0 ? _v : 'Listening', tooltipProps: listen.tooltipProps, icon: React.createElement(VolumeUpIcon, null), isClicked: activeButton === 'listen', ref: listen.ref, "aria-expanded": listen['aria-expanded'], "aria-controls": listen['aria-controls'] })),
36
+ positive && (React.createElement(ResponseActionButton, Object.assign({}, positive, { ariaLabel: (_a = positive.ariaLabel) !== null && _a !== void 0 ? _a : 'Good response', clickedAriaLabel: (_b = positive.ariaLabel) !== null && _b !== void 0 ? _b : 'Response recorded', onClick: (e) => handleClick(e, 'positive', positive.onClick), className: positive.className, isDisabled: positive.isDisabled, tooltipContent: (_c = positive.tooltipContent) !== null && _c !== void 0 ? _c : 'Good response', clickedTooltipContent: (_d = positive.clickedTooltipContent) !== null && _d !== void 0 ? _d : 'Response recorded', tooltipProps: positive.tooltipProps, icon: React.createElement(OutlinedThumbsUpIcon, null), isClicked: activeButton === 'positive', ref: positive.ref, "aria-expanded": positive['aria-expanded'], "aria-controls": positive['aria-controls'] }))),
37
+ negative && (React.createElement(ResponseActionButton, Object.assign({}, negative, { ariaLabel: (_e = negative.ariaLabel) !== null && _e !== void 0 ? _e : 'Bad response', clickedAriaLabel: (_f = negative.ariaLabel) !== null && _f !== void 0 ? _f : 'Response recorded', onClick: (e) => handleClick(e, 'negative', negative.onClick), className: negative.className, isDisabled: negative.isDisabled, tooltipContent: (_g = negative.tooltipContent) !== null && _g !== void 0 ? _g : 'Bad response', clickedTooltipContent: (_h = negative.clickedTooltipContent) !== null && _h !== void 0 ? _h : 'Response recorded', tooltipProps: negative.tooltipProps, icon: React.createElement(OutlinedThumbsDownIcon, null), isClicked: activeButton === 'negative', ref: negative.ref, "aria-expanded": negative['aria-expanded'], "aria-controls": negative['aria-controls'] }))),
38
+ copy && (React.createElement(ResponseActionButton, Object.assign({}, copy, { ariaLabel: (_j = copy.ariaLabel) !== null && _j !== void 0 ? _j : 'Copy', clickedAriaLabel: (_k = copy.ariaLabel) !== null && _k !== void 0 ? _k : 'Copied', onClick: (e) => handleClick(e, 'copy', copy.onClick), className: copy.className, isDisabled: copy.isDisabled, tooltipContent: (_l = copy.tooltipContent) !== null && _l !== void 0 ? _l : 'Copy', clickedTooltipContent: (_m = copy.clickedTooltipContent) !== null && _m !== void 0 ? _m : 'Copied', tooltipProps: copy.tooltipProps, icon: React.createElement(OutlinedCopyIcon, null), isClicked: activeButton === 'copy', ref: copy.ref, "aria-expanded": copy['aria-expanded'], "aria-controls": copy['aria-controls'] }))),
39
+ share && (React.createElement(ResponseActionButton, Object.assign({}, share, { ariaLabel: (_o = share.ariaLabel) !== null && _o !== void 0 ? _o : 'Share', clickedAriaLabel: (_p = share.ariaLabel) !== null && _p !== void 0 ? _p : 'Shared', onClick: (e) => handleClick(e, 'share', share.onClick), className: share.className, isDisabled: share.isDisabled, tooltipContent: (_q = share.tooltipContent) !== null && _q !== void 0 ? _q : 'Share', clickedTooltipContent: (_r = share.clickedTooltipContent) !== null && _r !== void 0 ? _r : 'Shared', tooltipProps: share.tooltipProps, icon: React.createElement(ExternalLinkAltIcon, null), isClicked: activeButton === 'share', ref: share.ref, "aria-expanded": share['aria-expanded'], "aria-controls": share['aria-controls'] }))),
40
+ listen && (React.createElement(ResponseActionButton, Object.assign({}, listen, { ariaLabel: (_s = listen.ariaLabel) !== null && _s !== void 0 ? _s : 'Listen', clickedAriaLabel: (_t = listen.ariaLabel) !== null && _t !== void 0 ? _t : 'Listening', onClick: (e) => handleClick(e, 'listen', listen.onClick), className: listen.className, isDisabled: listen.isDisabled, tooltipContent: (_u = listen.tooltipContent) !== null && _u !== void 0 ? _u : 'Listen', clickedTooltipContent: (_v = listen.clickedTooltipContent) !== null && _v !== void 0 ? _v : 'Listening', tooltipProps: listen.tooltipProps, icon: React.createElement(VolumeUpIcon, null), isClicked: activeButton === 'listen', ref: listen.ref, "aria-expanded": listen['aria-expanded'], "aria-controls": listen['aria-controls'] }))),
41
41
  Object.keys(additionalActions).map((action) => {
42
42
  var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
43
- return (React.createElement(ResponseActionButton, { key: action, ariaLabel: (_a = additionalActions[action]) === null || _a === void 0 ? void 0 : _a.ariaLabel, clickedAriaLabel: (_b = additionalActions[action]) === null || _b === void 0 ? void 0 : _b.clickedAriaLabel, onClick: (e) => { var _a; return handleClick(e, action, (_a = additionalActions[action]) === null || _a === void 0 ? void 0 : _a.onClick); }, className: (_c = additionalActions[action]) === null || _c === void 0 ? void 0 : _c.className, isDisabled: (_d = additionalActions[action]) === null || _d === void 0 ? void 0 : _d.isDisabled, tooltipContent: (_e = additionalActions[action]) === null || _e === void 0 ? void 0 : _e.tooltipContent, tooltipProps: (_f = additionalActions[action]) === null || _f === void 0 ? void 0 : _f.tooltipProps, clickedTooltipContent: (_g = additionalActions[action]) === null || _g === void 0 ? void 0 : _g.clickedTooltipContent, icon: (_h = additionalActions[action]) === null || _h === void 0 ? void 0 : _h.icon, isClicked: activeButton === action, ref: (_j = additionalActions[action]) === null || _j === void 0 ? void 0 : _j.ref, "aria-expanded": (_k = additionalActions[action]) === null || _k === void 0 ? void 0 : _k['aria-expanded'], "aria-controls": (_l = additionalActions[action]) === null || _l === void 0 ? void 0 : _l['aria-controls'] }));
43
+ return (React.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'] })));
44
44
  })));
45
45
  };
46
46
  export default ResponseActions;
@@ -47,6 +47,13 @@ const CUSTOM_ACTIONS = [
47
47
  }
48
48
  }
49
49
  ];
50
+ const ALL_ACTIONS_DATA_TEST = [
51
+ { type: 'positive', label: 'Good response', dataTestId: 'positive' },
52
+ { type: 'negative', label: 'Bad response', dataTestId: 'negative' },
53
+ { type: 'copy', label: 'Copy', dataTestId: 'copy' },
54
+ { type: 'share', label: 'Share', dataTestId: 'share' },
55
+ { type: 'listen', label: 'Listen', dataTestId: 'listen' }
56
+ ];
50
57
  describe('ResponseActions', () => {
51
58
  afterEach(() => {
52
59
  jest.clearAllMocks();
@@ -156,6 +163,12 @@ describe('ResponseActions', () => {
156
163
  expect(screen.getByRole('button', { name: label })).toHaveClass('test');
157
164
  });
158
165
  });
166
+ it('should be able to add custom attributes to buttons', () => {
167
+ ALL_ACTIONS_DATA_TEST.forEach(({ type, dataTestId }) => {
168
+ render(React.createElement(ResponseActions, { actions: { [type]: { onClick: jest.fn(), 'data-testid': dataTestId } } }));
169
+ expect(screen.getByTestId(dataTestId)).toBeTruthy();
170
+ });
171
+ });
159
172
  it('should be able to add custom actions', () => {
160
173
  CUSTOM_ACTIONS.forEach((action) => {
161
174
  const key = Object.keys(action)[0];
@@ -165,10 +178,12 @@ describe('ResponseActions', () => {
165
178
  onClick: action[key].onClick,
166
179
  // doing this just because it's easier to test without a regex for the button name
167
180
  ariaLabel: action[key].ariaLabel.toLowerCase(),
168
- icon: action[key].icon
181
+ icon: action[key].icon,
182
+ 'data-testid': action[key]
169
183
  }
170
184
  } }));
171
185
  expect(screen.getByRole('button', { name: key })).toBeTruthy();
186
+ expect(screen.getByTestId(action[key])).toBeTruthy();
172
187
  });
173
188
  });
174
189
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@patternfly/chatbot",
3
- "version": "6.3.0-prerelease.10",
3
+ "version": "6.3.0-prerelease.12",
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",
@@ -56,7 +56,7 @@ const CodeBlockMessage = ({
56
56
  {language && <div className="pf-chatbot__message-code-block-language">{language}</div>}
57
57
  <Button
58
58
  ref={buttonRef}
59
- aria-label={ariaLabel ?? 'Copy code button'}
59
+ aria-label={ariaLabel ?? 'Copy code'}
60
60
  variant="plain"
61
61
  className="pf-chatbot__button--copy"
62
62
  onClick={(event) => handleCopy(event, children)}
@@ -485,7 +485,7 @@ describe('Message', () => {
485
485
  it('should render code correctly', () => {
486
486
  render(<Message avatar="./img" role="user" name="User" content={CODE_MESSAGE} />);
487
487
  expect(screen.getByText('Here is some YAML code:')).toBeTruthy();
488
- expect(screen.getByRole('button', { name: 'Copy code button' })).toBeTruthy();
488
+ expect(screen.getByRole('button', { name: 'Copy code' })).toBeTruthy();
489
489
  expect(screen.getByText(/yaml/)).toBeTruthy();
490
490
  expect(screen.getByText(/apiVersion:/i)).toBeTruthy();
491
491
  expect(screen.getByText(/helm.openshift.io\/v1beta1/i)).toBeTruthy();
@@ -503,8 +503,8 @@ describe('Message', () => {
503
503
  // need explicit setup since RTL stubs clipboard if you do this
504
504
  const user = userEvent.setup();
505
505
  render(<Message avatar="./img" role="user" name="User" content={CODE_MESSAGE} />);
506
- expect(screen.getByRole('button', { name: 'Copy code button' })).toBeTruthy();
507
- await user.click(screen.getByRole('button', { name: 'Copy code button' }));
506
+ expect(screen.getByRole('button', { name: 'Copy code' })).toBeTruthy();
507
+ await user.click(screen.getByRole('button', { name: 'Copy code' }));
508
508
  const clipboardText = await navigator.clipboard.readText();
509
509
  expect(clipboardText.trim()).toEqual(CODE.trim());
510
510
  });
@@ -7,11 +7,11 @@ import { AttachButton } from './AttachButton';
7
7
  describe('Attach button', () => {
8
8
  it('should render button correctly', () => {
9
9
  render(<AttachButton />);
10
- expect(screen.getByRole('button', { name: 'Attach button' })).toBeTruthy();
10
+ expect(screen.getByRole('button', { name: 'Attach' })).toBeTruthy();
11
11
  });
12
12
  it('should handle isDisabled prop', () => {
13
13
  render(<AttachButton isDisabled />);
14
- expect(screen.getByRole('button', { name: 'Attach button' })).toBeDisabled();
14
+ expect(screen.getByRole('button', { name: 'Attach' })).toBeDisabled();
15
15
  });
16
16
  it('should handle spread props, including aria-label', () => {
17
17
  render(<AttachButton aria-label="test" />);
@@ -20,22 +20,22 @@ describe('Attach button', () => {
20
20
  it('should handle onClick', async () => {
21
21
  const spy = jest.fn();
22
22
  render(<AttachButton onClick={spy} />);
23
- await userEvent.click(screen.getByRole('button', { name: 'Attach button' }));
23
+ await userEvent.click(screen.getByRole('button', { name: 'Attach' }));
24
24
  expect(screen.getByRole('tooltip', { name: 'Attach' })).toBeTruthy();
25
25
  expect(spy).toHaveBeenCalledTimes(1);
26
26
  });
27
27
  it('should handle className prop', () => {
28
28
  render(<AttachButton className="test" />);
29
- expect(screen.getByRole('button', { name: 'Attach button' })).toHaveClass('test');
29
+ expect(screen.getByRole('button', { name: 'Attach' })).toHaveClass('test');
30
30
  });
31
31
  it('should handle custom tooltip correctly', async () => {
32
32
  render(<AttachButton onClick={jest.fn} tooltipContent="Test" />);
33
- await userEvent.click(screen.getByRole('button', { name: 'Attach button' }));
33
+ await userEvent.click(screen.getByRole('button', { name: 'Attach' }));
34
34
  expect(screen.getByRole('tooltip', { name: 'Test' })).toBeTruthy();
35
35
  });
36
36
  it('should handle tooltipProps prop', async () => {
37
37
  render(<AttachButton tooltipProps={{ id: 'test' }} />);
38
- await userEvent.click(screen.getByRole('button', { name: 'Attach button' }));
38
+ await userEvent.click(screen.getByRole('button', { name: 'Attach' }));
39
39
  expect(screen.getByRole('tooltip', { name: 'Attach' })).toHaveAttribute('id', 'test');
40
40
  });
41
41
  // Based on this because I had no idea how to do this and was looking around: https://stackoverflow.com/a/75562651
@@ -43,7 +43,7 @@ describe('Attach button', () => {
43
43
  it('should handle onAttachAccepted prop', async () => {
44
44
  const spy = jest.fn();
45
45
  render(<AttachButton onAttachAccepted={spy} inputTestId="input" />);
46
- await userEvent.click(screen.getByRole('button', { name: 'Attach button' }));
46
+ await userEvent.click(screen.getByRole('button', { name: 'Attach' }));
47
47
  const file = new File(['test'], 'test.json');
48
48
  const input = screen.getByTestId('input') as HTMLInputElement;
49
49
  await userEvent.upload(input, file);
@@ -65,7 +65,7 @@ const AttachButtonBase: React.FunctionComponent<AttachButtonProps> = ({
65
65
  variant="plain"
66
66
  ref={innerRef}
67
67
  className={`pf-chatbot__button--attach ${isCompact ? 'pf-m-compact' : ''} ${className ?? ''}`}
68
- aria-label={props['aria-label'] || 'Attach button'}
68
+ aria-label={props['aria-label'] || 'Attach'}
69
69
  isDisabled={isDisabled}
70
70
  onClick={onClick ?? open}
71
71
  icon={