@patternfly/chatbot 6.9.0-prerelease.1 → 6.9.0-prerelease.11
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/Chatbot/Chatbot.d.ts +2 -0
- package/dist/cjs/Chatbot/Chatbot.js +2 -2
- package/dist/cjs/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.js +1 -1
- package/dist/cjs/ChatbotFooter/ChatbotFootnote.js +1 -1
- package/dist/cjs/ChatbotModal/ChatbotModal.js +1 -1
- package/dist/cjs/ChatbotWelcomePrompt/ChatbotWelcomePrompt.js +1 -1
- package/dist/cjs/MessageBar/MessageBar.d.ts +1 -1
- package/dist/cjs/MessageBar/MessageBar.js +4 -3
- package/dist/cjs/MessageBar/SendButton.js +2 -2
- package/dist/cjs/SourcesCard/SourcesCard.d.ts +2 -0
- package/dist/cjs/SourcesCardBase/SourcesCardBase.d.ts +2 -0
- package/dist/cjs/SourcesCardBase/SourcesCardBase.js +2 -2
- package/dist/css/main.css +201 -66
- package/dist/css/main.css.map +1 -1
- package/dist/esm/Chatbot/Chatbot.d.ts +2 -0
- package/dist/esm/Chatbot/Chatbot.js +3 -3
- package/dist/esm/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.js +1 -1
- package/dist/esm/ChatbotFooter/ChatbotFootnote.js +1 -1
- package/dist/esm/ChatbotModal/ChatbotModal.js +1 -1
- package/dist/esm/ChatbotWelcomePrompt/ChatbotWelcomePrompt.js +1 -1
- package/dist/esm/MessageBar/MessageBar.d.ts +1 -1
- package/dist/esm/MessageBar/MessageBar.js +4 -3
- package/dist/esm/MessageBar/SendButton.js +2 -2
- package/dist/esm/SourcesCard/SourcesCard.d.ts +2 -0
- package/dist/esm/SourcesCardBase/SourcesCardBase.d.ts +2 -0
- package/dist/esm/SourcesCardBase/SourcesCardBase.js +2 -2
- package/package.json +9 -9
- package/patternfly-docs/content/extensions/chatbot/chatbot.md +1 -0
- package/patternfly-docs/content/extensions/chatbot/examples/Analytics/Analytics.md +1 -1
- package/patternfly-docs/content/extensions/chatbot/examples/Messages/MessageWithSources.tsx +31 -0
- package/patternfly-docs/content/extensions/chatbot/examples/Messages/Messages.md +2 -0
- package/patternfly-docs/content/extensions/chatbot/examples/demos/Canvas.md +132 -0
- package/patternfly-docs/content/extensions/chatbot/examples/demos/Canvas.tsx +615 -0
- package/patternfly-docs/content/extensions/chatbot/examples/demos/CanvasWithDockedNav.tsx +697 -0
- package/patternfly-docs/content/extensions/chatbot/examples/demos/Chatbot.md +39 -5
- package/patternfly-docs/content/extensions/chatbot/examples/demos/FullscreenDockedNav.tsx +385 -0
- package/patternfly-docs/patternfly-docs.config.js +1 -1
- package/src/Canvas/Canvas.scss +150 -0
- package/src/Chatbot/Chatbot.scss +13 -1
- package/src/Chatbot/Chatbot.test.tsx +11 -0
- package/src/Chatbot/Chatbot.tsx +5 -1
- package/src/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.scss +91 -77
- package/src/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.test.tsx +32 -13
- package/src/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.tsx +1 -0
- package/src/ChatbotFooter/ChatbotFooternote.test.tsx +50 -0
- package/src/ChatbotFooter/ChatbotFootnote.tsx +1 -1
- package/src/ChatbotModal/ChatbotModal.scss +2 -7
- package/src/ChatbotModal/ChatbotModal.tsx +1 -0
- package/src/ChatbotToggle/ChatbotToggle.scss +3 -2
- package/src/ChatbotToggle/ChatbotToggle.test.tsx +4 -0
- package/src/ChatbotWelcomePrompt/ChatbotWelcomePrompt.scss +9 -0
- package/src/ChatbotWelcomePrompt/ChatbotWelcomePrompt.tsx +4 -2
- package/src/FileDetails/__snapshots__/FileDetails.test.tsx.snap +2 -6
- package/src/FileDetailsLabel/__snapshots__/FileDetailsLabel.test.tsx.snap +2 -6
- package/src/Message/Message.scss +9 -0
- package/src/MessageBar/AttachButton.scss +4 -21
- package/src/MessageBar/MessageBar.scss +2 -2
- package/src/MessageBar/MessageBar.test.tsx +20 -0
- package/src/MessageBar/MessageBar.tsx +7 -3
- package/src/MessageBar/SendButton.scss +1 -32
- package/src/MessageBar/SendButton.tsx +2 -2
- package/src/SourcesCard/SourcesCard.scss +6 -0
- package/src/SourcesCard/SourcesCard.test.tsx +16 -0
- package/src/SourcesCard/SourcesCard.tsx +2 -0
- package/src/SourcesCardBase/SourcesCardBase.test.tsx +62 -0
- package/src/SourcesCardBase/SourcesCardBase.tsx +8 -0
- package/src/main.scss +1 -0
|
@@ -172,81 +172,91 @@
|
|
|
172
172
|
|
|
173
173
|
// Chatbot Header - Drawer
|
|
174
174
|
// ----------------------------------------------------------------------------
|
|
175
|
+
// Child combinators keep these rules off nested drawers such as canvas.
|
|
175
176
|
.pf-chatbot__history.pf-v6-c-drawer {
|
|
176
|
-
--pf-v6-c-drawer__panel--MinWidth: 24rem;
|
|
177
|
-
--pf-v6-c-drawer__panel--xl--MinWidth: 24rem;
|
|
178
177
|
height: 70vh;
|
|
179
178
|
|
|
180
179
|
// Drawer panel
|
|
181
|
-
.pf-v6-c-drawer__panel {
|
|
180
|
+
> .pf-v6-c-drawer__main > .pf-v6-c-drawer__panel {
|
|
181
|
+
--pf-v6-c-drawer__panel--MinWidth: 24rem;
|
|
182
|
+
--pf-v6-c-drawer__panel--xl--MinWidth: 24rem;
|
|
182
183
|
--pf-v6-c-drawer__panel--BackgroundColor: var(--pf-t--global--background--color--floating--default);
|
|
184
|
+
--pf-v6-c-drawer__panel--m-inline--BackgroundColor: var(--pf-t--global--background--color--floating--default);
|
|
185
|
+
--pf-v6-c-drawer__panel--m-inline--md--BackgroundColor: var(--pf-t--global--background--color--floating--default);
|
|
183
186
|
--pf-v6-c-drawer__panel--PaddingBlockStart: var(--pf-t--global--spacer--lg);
|
|
184
187
|
--pf-v6-c-drawer__panel--PaddingBlockEnd: var(--pf-t--global--spacer--lg);
|
|
185
188
|
--pf-v6-c-drawer__panel--RowGap: var(--pf-t--global--spacer--gap--group-to-group--vertical--default);
|
|
186
189
|
overflow-x: hidden;
|
|
187
190
|
overflow-y: hidden;
|
|
188
|
-
}
|
|
189
191
|
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
192
|
+
// Drawer head
|
|
193
|
+
.pf-v6-c-drawer__head {
|
|
194
|
+
--pf-v6-c-drawer__head--PaddingBlockStart: 0;
|
|
195
|
+
--pf-v6-c-drawer__head--PaddingBlockEnd: 0;
|
|
196
|
+
--pf-v6-c-drawer__head--PaddingInlineStart: var(--pf-t--global--spacer--lg);
|
|
197
|
+
--pf-v6-c-drawer__head--PaddingInlineEnd: var(--pf-t--global--spacer--lg);
|
|
196
198
|
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
199
|
+
display: flex;
|
|
200
|
+
align-items: center;
|
|
201
|
+
justify-content: space-between;
|
|
202
|
+
height: var(--pf-t--global--spacer--2xl);
|
|
203
|
+
}
|
|
202
204
|
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
205
|
+
// Drawer actions
|
|
206
|
+
.pf-v6-c-drawer__actions {
|
|
207
|
+
--pf-v6-c-drawer__actions--MarginBlockStart: 0;
|
|
208
|
+
--pf-v6-c-drawer__actions--MarginInlineEnd: 0;
|
|
207
209
|
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
210
|
+
display: flex;
|
|
211
|
+
align-items: center;
|
|
212
|
+
justify-content: space-between;
|
|
213
|
+
align-self: center;
|
|
214
|
+
width: 100%;
|
|
215
|
+
height: 100%;
|
|
216
|
+
}
|
|
215
217
|
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
218
|
+
.pf-v6-c-drawer__actions--reversed {
|
|
219
|
+
flex-direction: row-reverse;
|
|
220
|
+
}
|
|
219
221
|
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
222
|
+
// Close drawer
|
|
223
|
+
.pf-v6-c-drawer__close {
|
|
224
|
+
.pf-v6-c-button {
|
|
225
|
+
width: var(--pf-t--global--spacer--2xl);
|
|
226
|
+
height: var(--pf-t--global--spacer--2xl);
|
|
227
|
+
border-radius: var(--pf-t--global--border--radius--pill);
|
|
228
|
+
justify-content: center;
|
|
229
|
+
align-items: center;
|
|
230
|
+
}
|
|
228
231
|
}
|
|
229
|
-
}
|
|
230
232
|
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
233
|
+
// Drawer body
|
|
234
|
+
.pf-v6-c-drawer__body {
|
|
235
|
+
--pf-v6-c-drawer__panel__body--PaddingBlockStart: 0;
|
|
236
|
+
--pf-v6-c-drawer__panel__body--PaddingBlockEnd: 0;
|
|
237
|
+
--pf-v6-c-drawer__panel__body--PaddingInlineStart: var(--pf-t--global--spacer--lg);
|
|
238
|
+
--pf-v6-c-drawer__panel__body--PaddingInlineEnd: var(--pf-t--global--spacer--lg);
|
|
239
|
+
|
|
240
|
+
overflow-y: auto;
|
|
241
|
+
display: flex;
|
|
242
|
+
flex-direction: column;
|
|
243
|
+
height: 70vh;
|
|
244
|
+
}
|
|
237
245
|
|
|
246
|
+
// Resizable drawer spacing is different - needs manual adjustment for gaps between buttons, inputs, etc.
|
|
247
|
+
&.pf-m-resizable {
|
|
248
|
+
.pf-v6-c-drawer__panel-main {
|
|
249
|
+
row-gap: var(--pf-v6-c-drawer__panel--RowGap);
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
> .pf-v6-c-drawer__main > .pf-v6-c-drawer__content > .pf-v6-c-drawer__body {
|
|
238
255
|
overflow-y: auto;
|
|
239
256
|
display: flex;
|
|
240
257
|
flex-direction: column;
|
|
241
258
|
height: 70vh;
|
|
242
259
|
}
|
|
243
|
-
|
|
244
|
-
// Resizable drawer spacing is different - needs manual adjustment for gaps between buttons, inputs, etc.
|
|
245
|
-
.pf-v6-c-drawer__panel.pf-m-resizable {
|
|
246
|
-
.pf-v6-c-drawer__panel-main {
|
|
247
|
-
row-gap: var(--pf-v6-c-drawer__panel--RowGap);
|
|
248
|
-
}
|
|
249
|
-
}
|
|
250
260
|
}
|
|
251
261
|
|
|
252
262
|
.pf-chatbot:is(.pf-chatbot--drawer, .pf-chatbot--docked) .pf-chatbot__history {
|
|
@@ -279,7 +289,9 @@
|
|
|
279
289
|
.pf-chatbot--fullscreen {
|
|
280
290
|
.pf-chatbot__history.pf-v6-c-drawer {
|
|
281
291
|
height: 100vh;
|
|
282
|
-
|
|
292
|
+
|
|
293
|
+
> .pf-v6-c-drawer__main > .pf-v6-c-drawer__content > .pf-v6-c-drawer__body,
|
|
294
|
+
> .pf-v6-c-drawer__main > .pf-v6-c-drawer__panel .pf-v6-c-drawer__body {
|
|
283
295
|
width: 100%;
|
|
284
296
|
}
|
|
285
297
|
}
|
|
@@ -291,11 +303,14 @@
|
|
|
291
303
|
.pf-chatbot--embedded {
|
|
292
304
|
.pf-chatbot__history.pf-v6-c-drawer {
|
|
293
305
|
height: 100%;
|
|
294
|
-
|
|
306
|
+
|
|
307
|
+
> .pf-v6-c-drawer__main > .pf-v6-c-drawer__content > .pf-v6-c-drawer__body,
|
|
308
|
+
> .pf-v6-c-drawer__main > .pf-v6-c-drawer__panel .pf-v6-c-drawer__body {
|
|
295
309
|
width: 100%;
|
|
296
310
|
height: 100%;
|
|
297
311
|
}
|
|
298
|
-
|
|
312
|
+
|
|
313
|
+
> .pf-v6-c-drawer__main > .pf-v6-c-drawer__panel {
|
|
299
314
|
height: 100%;
|
|
300
315
|
}
|
|
301
316
|
}
|
|
@@ -327,37 +342,36 @@
|
|
|
327
342
|
}
|
|
328
343
|
|
|
329
344
|
.pf-chatbot__history.pf-m-compact {
|
|
330
|
-
.pf-v6-c-drawer__main {
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
--pf-v6-c-drawer__panel--RowGap: var(--pf-t--global--spacer--md);
|
|
337
|
-
}
|
|
345
|
+
> .pf-v6-c-drawer__main > .pf-v6-c-drawer__panel {
|
|
346
|
+
--pf-v6-c-drawer__panel--PaddingBlockStart: var(--pf-t--global--spacer--sm);
|
|
347
|
+
--pf-v6-c-drawer__panel--PaddingBlockEnd: var(--pf-t--global--spacer--sm);
|
|
348
|
+
--pf-v6-c-drawer__head--PaddingInlineStart: var(--pf-t--global--spacer--md);
|
|
349
|
+
--pf-v6-c-drawer__head--PaddingInlineEnd: var(--pf-t--global--spacer--md);
|
|
350
|
+
--pf-v6-c-drawer__panel--RowGap: var(--pf-t--global--spacer--md);
|
|
338
351
|
|
|
339
352
|
.pf-v6-c-drawer__body {
|
|
340
353
|
--pf-v6-c-drawer__panel__body--PaddingInlineStart: var(--pf-t--global--spacer--md);
|
|
341
354
|
--pf-v6-c-drawer__panel__body--PaddingInlineEnd: var(--pf-t--global--spacer--md);
|
|
342
355
|
}
|
|
356
|
+
|
|
357
|
+
.pf-v6-c-drawer__head {
|
|
358
|
+
--pf-v6-c-drawer__head--PaddingInlineStart: var(--pf-t--global--spacer--lg);
|
|
359
|
+
--pf-v6-c-drawer__head--PaddingInlineEnd: var(--pf-t--global--spacer--lg);
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
.pf-v6-c-drawer__close {
|
|
363
|
+
.pf-v6-c-button {
|
|
364
|
+
width: 2rem;
|
|
365
|
+
height: 2rem;
|
|
366
|
+
--pf-v6-c-button--m-plain--PaddingInlineEnd: var(--pf-t--global--spacer--xs);
|
|
367
|
+
--pf-v6-c-button--m-plain--PaddingInlineStart: var(--pf-t--global--spacer--xs);
|
|
368
|
+
--pf-v6-c-button--PaddingBlockStart: var(--pf-t--global--spacer--xs);
|
|
369
|
+
--pf-v6-c-button--PaddingBlockEnd: var(--pf-t--global--spacer--xs);
|
|
370
|
+
}
|
|
371
|
+
}
|
|
343
372
|
}
|
|
344
373
|
|
|
345
374
|
.pf-chatbot__menu-item {
|
|
346
375
|
font-size: var(--pf-t--global--font--size--body--md);
|
|
347
376
|
}
|
|
348
|
-
|
|
349
|
-
.pf-v6-c-drawer__head {
|
|
350
|
-
--pf-v6-c-drawer__head--PaddingInlineStart: var(--pf-t--global--spacer--lg);
|
|
351
|
-
--pf-v6-c-drawer__head--PaddingInlineEnd: var(--pf-t--global--spacer--lg);
|
|
352
|
-
}
|
|
353
|
-
.pf-v6-c-drawer__close {
|
|
354
|
-
.pf-v6-c-button {
|
|
355
|
-
width: 2rem;
|
|
356
|
-
height: 2rem;
|
|
357
|
-
--pf-v6-c-button--m-plain--PaddingInlineEnd: var(--pf-t--global--spacer--xs);
|
|
358
|
-
--pf-v6-c-button--m-plain--PaddingInlineStart: var(--pf-t--global--spacer--xs);
|
|
359
|
-
--pf-v6-c-button--PaddingBlockStart: var(--pf-t--global--spacer--xs);
|
|
360
|
-
--pf-v6-c-button--PaddingBlockEnd: var(--pf-t--global--spacer--xs);
|
|
361
|
-
}
|
|
362
|
-
}
|
|
363
377
|
}
|
|
@@ -161,17 +161,23 @@ describe('ChatbotConversationHistoryNav', () => {
|
|
|
161
161
|
});
|
|
162
162
|
|
|
163
163
|
it('should close the drawer when escape key is pressed', async () => {
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
164
|
+
const HistoryNavigationTest = () => {
|
|
165
|
+
const [isDrawerOpen, setIsDrawerOpen] = useState(true);
|
|
166
|
+
|
|
167
|
+
return (
|
|
168
|
+
<ChatbotConversationHistoryNav
|
|
169
|
+
onDrawerToggle={onDrawerToggle}
|
|
170
|
+
isDrawerOpen={isDrawerOpen}
|
|
171
|
+
displayMode={ChatbotDisplayMode.fullscreen}
|
|
172
|
+
setIsDrawerOpen={setIsDrawerOpen}
|
|
173
|
+
reverseButtonOrder={false}
|
|
174
|
+
handleTextInputChange={jest.fn()}
|
|
175
|
+
conversations={initialConversations}
|
|
176
|
+
/>
|
|
177
|
+
);
|
|
178
|
+
};
|
|
179
|
+
|
|
180
|
+
render(<HistoryNavigationTest />);
|
|
175
181
|
|
|
176
182
|
fireEvent.keyDown(screen.getByPlaceholderText(/Search/i), {
|
|
177
183
|
key: 'Escape',
|
|
@@ -180,8 +186,8 @@ describe('ChatbotConversationHistoryNav', () => {
|
|
|
180
186
|
charCode: 27
|
|
181
187
|
});
|
|
182
188
|
|
|
183
|
-
waitFor(() => {
|
|
184
|
-
expect(screen.
|
|
189
|
+
await waitFor(() => {
|
|
190
|
+
expect(screen.getByRole('dialog', { hidden: true })).toHaveAttribute('hidden');
|
|
185
191
|
});
|
|
186
192
|
});
|
|
187
193
|
|
|
@@ -204,6 +210,19 @@ describe('ChatbotConversationHistoryNav', () => {
|
|
|
204
210
|
);
|
|
205
211
|
});
|
|
206
212
|
|
|
213
|
+
it('should keep an opaque panel background in glass theme', () => {
|
|
214
|
+
render(
|
|
215
|
+
<ChatbotConversationHistoryNav
|
|
216
|
+
onDrawerToggle={onDrawerToggle}
|
|
217
|
+
isDrawerOpen={true}
|
|
218
|
+
displayMode={ChatbotDisplayMode.fullscreen}
|
|
219
|
+
setIsDrawerOpen={jest.fn()}
|
|
220
|
+
conversations={initialConversations}
|
|
221
|
+
/>
|
|
222
|
+
);
|
|
223
|
+
expect(screen.getByRole('dialog')).toHaveClass('pf-m-no-plain-on-glass');
|
|
224
|
+
});
|
|
225
|
+
|
|
207
226
|
it('should accept drawerContentProps', () => {
|
|
208
227
|
const { container } = render(
|
|
209
228
|
<ChatbotConversationHistoryNav
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import { act, fireEvent, render, screen, waitFor } from '@testing-library/react';
|
|
2
2
|
import ChatbotFootnote from './ChatbotFootnote';
|
|
3
3
|
|
|
4
|
+
const POPOVER_CLOSE_ERROR =
|
|
5
|
+
'ChatbotFootnote: You must provide either the popover.cta or popover.showClose props in order to render a button that can close the popover.';
|
|
6
|
+
|
|
4
7
|
describe('ChatbotFooternote', () => {
|
|
5
8
|
const onClick = jest.fn();
|
|
6
9
|
const popoverProps = {
|
|
@@ -20,11 +23,58 @@ describe('ChatbotFooternote', () => {
|
|
|
20
23
|
}
|
|
21
24
|
};
|
|
22
25
|
|
|
26
|
+
let consoleErrorSpy: jest.SpyInstance;
|
|
27
|
+
|
|
28
|
+
beforeEach(() => {
|
|
29
|
+
consoleErrorSpy = jest.spyOn(console, 'error').mockImplementation(jest.fn());
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
afterEach(() => {
|
|
33
|
+
consoleErrorSpy.mockRestore();
|
|
34
|
+
});
|
|
35
|
+
|
|
23
36
|
it('should render ChatbotFooternote', () => {
|
|
24
37
|
render(<ChatbotFootnote label="Chatbot footer" />);
|
|
25
38
|
expect(screen.getByText('Chatbot footer')).toBeTruthy();
|
|
26
39
|
});
|
|
27
40
|
|
|
41
|
+
it('should not log a console error when no popover is provided', () => {
|
|
42
|
+
render(<ChatbotFootnote label="Chatbot footer" />);
|
|
43
|
+
expect(consoleErrorSpy).not.toHaveBeenCalledWith(POPOVER_CLOSE_ERROR);
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
it('should not log a console error when popover has a cta', () => {
|
|
47
|
+
render(<ChatbotFootnote label="Chatbot footer" popover={popoverProps} />);
|
|
48
|
+
expect(consoleErrorSpy).not.toHaveBeenCalledWith(POPOVER_CLOSE_ERROR);
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
it('should not log a console error when popover has showClose', () => {
|
|
52
|
+
render(
|
|
53
|
+
<ChatbotFootnote
|
|
54
|
+
label="Chatbot footer"
|
|
55
|
+
popover={{
|
|
56
|
+
title: 'Verify accuracy',
|
|
57
|
+
description: 'description',
|
|
58
|
+
showClose: true
|
|
59
|
+
}}
|
|
60
|
+
/>
|
|
61
|
+
);
|
|
62
|
+
expect(consoleErrorSpy).not.toHaveBeenCalledWith(POPOVER_CLOSE_ERROR);
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
it('should log a console error when popover is provided without cta or showClose', () => {
|
|
66
|
+
render(
|
|
67
|
+
<ChatbotFootnote
|
|
68
|
+
label="Chatbot footer"
|
|
69
|
+
popover={{
|
|
70
|
+
title: 'Verify accuracy',
|
|
71
|
+
description: 'description'
|
|
72
|
+
}}
|
|
73
|
+
/>
|
|
74
|
+
);
|
|
75
|
+
expect(consoleErrorSpy).toHaveBeenCalledWith(POPOVER_CLOSE_ERROR);
|
|
76
|
+
});
|
|
77
|
+
|
|
28
78
|
it('should render ChatbotFooternote with popover', async () => {
|
|
29
79
|
render(<ChatbotFootnote label="Chatbot footer" popover={popoverProps} />);
|
|
30
80
|
|
|
@@ -63,7 +63,7 @@ export const ChatbotFootnote: FunctionComponent<ChatbotFootnoteProps> = ({
|
|
|
63
63
|
className,
|
|
64
64
|
...props
|
|
65
65
|
}: ChatbotFootnoteProps) => {
|
|
66
|
-
if (!popover
|
|
66
|
+
if (popover && !popover.cta && !popover.showClose) {
|
|
67
67
|
// eslint-disable-next-line no-console
|
|
68
68
|
console.error(
|
|
69
69
|
'ChatbotFootnote: You must provide either the popover.cta or popover.showClose props in order to render a button that can close the popover.'
|
|
@@ -27,13 +27,8 @@
|
|
|
27
27
|
}
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
-
:root:where(.pf-v6-theme-glass) {
|
|
31
|
-
|
|
32
|
-
--pf-v6-c-modal-box--BackgroundColor: var(
|
|
33
|
-
--pf-t--global--background--color--glass--primary--default,
|
|
34
|
-
var(--pf-t--global--background--color--secondary--default)
|
|
35
|
-
);
|
|
36
|
-
}
|
|
30
|
+
:root:where(.pf-v6-theme-glass) .pf-chatbot__code-modal {
|
|
31
|
+
--pf-v6-c-modal-box--BackgroundColor: var(--pf-t--global--background--color--floating--secondary--default);
|
|
37
32
|
}
|
|
38
33
|
|
|
39
34
|
// ============================================================================
|
|
@@ -32,6 +32,7 @@ export const ChatbotModal: FunctionComponent<ChatbotModalProps> = ({
|
|
|
32
32
|
aria-describedby="chatbot-modal"
|
|
33
33
|
className={`pf-chatbot__chatbot-modal pf-chatbot__chatbot-modal--${displayMode} ${isCompact ? 'pf-m-compact' : ''} ${className}`}
|
|
34
34
|
backdropClassName="pf-chatbot__chatbot-modal-backdrop"
|
|
35
|
+
hasAnimations={false}
|
|
35
36
|
{...props}
|
|
36
37
|
>
|
|
37
38
|
{children}
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
position: fixed;
|
|
6
6
|
inset-block-end: var(--pf-t--global--spacer--md);
|
|
7
7
|
inset-inline-end: var(--pf-t--global--spacer--md);
|
|
8
|
+
--pf-v6-c-button--BorderRadius: 0;
|
|
8
9
|
--pf-v6-c-button--m-plain--BackgroundColor: var(--pf-t--global--background--color--floating--default);
|
|
9
10
|
--pf-v6-c-button--m-plain--hover--BackgroundColor: var(--pf-t--global--background--color--floating--hover);
|
|
10
11
|
--pf-v6-c-button--m-plain--m-clicked--BackgroundColor: var(--pf-t--global--background--color--floating--clicked);
|
|
@@ -48,8 +49,8 @@
|
|
|
48
49
|
}
|
|
49
50
|
}
|
|
50
51
|
|
|
51
|
-
.pf-chatbot__button--round {
|
|
52
|
-
|
|
52
|
+
.pf-chatbot__button.pf-chatbot__button--round {
|
|
53
|
+
--pf-v6-c-button--BorderRadius: var(--pf-t--global--border--radius--pill);
|
|
53
54
|
width: 3rem;
|
|
54
55
|
height: 3rem;
|
|
55
56
|
}
|
|
@@ -38,6 +38,10 @@ describe('ChatbotToggle', () => {
|
|
|
38
38
|
expect(screen.getByRole('button')).toHaveClass('pf-chatbot__button');
|
|
39
39
|
expect(screen.getByRole('button')).toHaveClass('pf-chatbot__button--round');
|
|
40
40
|
});
|
|
41
|
+
it('should handle isRound correctly when false', () => {
|
|
42
|
+
render(<ChatbotToggle tooltipLabel="Chatbot" isRound={false} />);
|
|
43
|
+
expect(screen.getByRole('button')).not.toHaveClass('pf-chatbot__button--round');
|
|
44
|
+
});
|
|
41
45
|
it('should handle className correctly', () => {
|
|
42
46
|
render(<ChatbotToggle tooltipLabel="Chatbot" className="test" />);
|
|
43
47
|
expect(screen.getByRole('button')).toHaveClass('pf-chatbot__button');
|
|
@@ -30,6 +30,15 @@
|
|
|
30
30
|
flex: 1;
|
|
31
31
|
overflow: visible;
|
|
32
32
|
height: 100%;
|
|
33
|
+
min-width: 0;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
.pf-chatbot__prompt-suggestion-body {
|
|
37
|
+
overflow-wrap: anywhere;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
.pf-chatbot__prompt-suggestion-title {
|
|
41
|
+
--pf-v6-c-card__title-text--OverflowWrap: anywhere;
|
|
33
42
|
}
|
|
34
43
|
}
|
|
35
44
|
|
|
@@ -64,9 +64,11 @@ export const ChatbotWelcomePrompt: FunctionComponent<ChatbotWelcomePromptProps>
|
|
|
64
64
|
selectableActionAriaLabelledby: `welcome-prompt-title-${index}`
|
|
65
65
|
}}
|
|
66
66
|
>
|
|
67
|
-
<CardTitle id={`welcome-prompt-title-${index}`}>
|
|
67
|
+
<CardTitle className="pf-chatbot__prompt-suggestion-title" id={`welcome-prompt-title-${index}`}>
|
|
68
|
+
{prompt.title}
|
|
69
|
+
</CardTitle>
|
|
68
70
|
</CardHeader>
|
|
69
|
-
{prompt.message && <CardBody>{prompt.message}</CardBody>}
|
|
71
|
+
{prompt.message && <CardBody className="pf-chatbot__prompt-suggestion-body">{prompt.message}</CardBody>}
|
|
70
72
|
</Card>
|
|
71
73
|
))}
|
|
72
74
|
</div>
|
|
@@ -43,15 +43,11 @@ exports[`FileDetails should render file details 1`] = `
|
|
|
43
43
|
<div
|
|
44
44
|
class="pf-v6-l-flex pf-m-gap-xs"
|
|
45
45
|
>
|
|
46
|
-
<div
|
|
47
|
-
class=""
|
|
48
|
-
>
|
|
46
|
+
<div>
|
|
49
47
|
<div
|
|
50
48
|
class="pf-v6-l-flex pf-m-column pf-m-gap-none"
|
|
51
49
|
>
|
|
52
|
-
<div
|
|
53
|
-
class=""
|
|
54
|
-
>
|
|
50
|
+
<div>
|
|
55
51
|
<span
|
|
56
52
|
class="pf-chatbot__code-fileName"
|
|
57
53
|
>
|
|
@@ -55,15 +55,11 @@ exports[`FileDetailsLabel should render file details label 1`] = `
|
|
|
55
55
|
<div
|
|
56
56
|
class="pf-v6-l-flex pf-m-gap-xs"
|
|
57
57
|
>
|
|
58
|
-
<div
|
|
59
|
-
class=""
|
|
60
|
-
>
|
|
58
|
+
<div>
|
|
61
59
|
<div
|
|
62
60
|
class="pf-v6-l-flex pf-m-column pf-m-gap-none"
|
|
63
61
|
>
|
|
64
|
-
<div
|
|
65
|
-
class=""
|
|
66
|
-
>
|
|
62
|
+
<div>
|
|
67
63
|
<span
|
|
68
64
|
class="pf-chatbot__code-fileName"
|
|
69
65
|
>
|
package/src/Message/Message.scss
CHANGED
|
@@ -55,6 +55,7 @@
|
|
|
55
55
|
|
|
56
56
|
// Author name
|
|
57
57
|
.pf-chatbot__message-name {
|
|
58
|
+
display: flex;
|
|
58
59
|
font-family: var(
|
|
59
60
|
--pf-v6-c-content--heading--FontFamily,
|
|
60
61
|
redhatdisplayvf,
|
|
@@ -65,6 +66,14 @@
|
|
|
65
66
|
);
|
|
66
67
|
font-weight: 600;
|
|
67
68
|
font-size: var(--pf-t--global--font--size--sm);
|
|
69
|
+
|
|
70
|
+
// Truncate measures this container and treats textWidth >= parentWidth as
|
|
71
|
+
// truncated. This extra space keeps full names stay untruncated and out of
|
|
72
|
+
// the tab flow.
|
|
73
|
+
&::after {
|
|
74
|
+
content: '';
|
|
75
|
+
flex: 0 0 1px;
|
|
76
|
+
}
|
|
68
77
|
}
|
|
69
78
|
|
|
70
79
|
// Badge
|
|
@@ -7,30 +7,13 @@
|
|
|
7
7
|
width: 3rem;
|
|
8
8
|
height: 3rem;
|
|
9
9
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
// Interactive states
|
|
15
|
-
&:hover {
|
|
16
|
-
.pf-v6-c-button__icon {
|
|
17
|
-
color: var(--pf-t--global--icon--color--regular);
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
&:active,
|
|
22
|
-
&:focus {
|
|
10
|
+
&.pf-m-clicked,
|
|
11
|
+
&.pf-m-clicked:hover,
|
|
12
|
+
&.pf-m-clicked:focus {
|
|
23
13
|
background-color: var(--pf-t--global--color--brand--clicked);
|
|
24
14
|
|
|
25
15
|
.pf-v6-c-button__icon {
|
|
26
|
-
color: var(--pf-t--global--icon--color--
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
&:hover,
|
|
30
|
-
&:focus {
|
|
31
|
-
.pf-v6-c-button__icon {
|
|
32
|
-
color: var(--pf-t--global--icon--color--inverse);
|
|
33
|
-
}
|
|
16
|
+
color: var(--pf-t--global--icon--color--on-brand--default);
|
|
34
17
|
}
|
|
35
18
|
}
|
|
36
19
|
}
|
|
@@ -46,14 +46,14 @@
|
|
|
46
46
|
|
|
47
47
|
&:hover {
|
|
48
48
|
&::after {
|
|
49
|
-
border-color: var(--pf-t--global--border--color--
|
|
49
|
+
border-color: var(--pf-t--global--border--color--hover);
|
|
50
50
|
border-width: var(--pf-t--global--border--width--control--hover);
|
|
51
51
|
}
|
|
52
52
|
}
|
|
53
53
|
|
|
54
54
|
&:focus-within {
|
|
55
55
|
&::after {
|
|
56
|
-
border-color: var(--pf-t--global--border--color--
|
|
56
|
+
border-color: var(--pf-t--global--border--color--clicked);
|
|
57
57
|
border-width: var(--pf-t--global--border--width--control--clicked);
|
|
58
58
|
}
|
|
59
59
|
}
|
|
@@ -191,6 +191,9 @@ describe('Message bar', () => {
|
|
|
191
191
|
}}
|
|
192
192
|
/>
|
|
193
193
|
);
|
|
194
|
+
const attachButton = screen.getByRole('button', { name: 'Attach' });
|
|
195
|
+
expect(attachButton).toHaveClass('pf-m-clicked');
|
|
196
|
+
expect(attachButton).toHaveAttribute('aria-expanded', 'true');
|
|
194
197
|
expect(screen.getByRole('textbox', { name: /Filter menu items/i })).toBeTruthy();
|
|
195
198
|
expect(screen.getByRole('menuitem', { name: /auth-operator/i })).toBeTruthy();
|
|
196
199
|
expect(screen.getByRole('menuitem', { name: /Alerts/i })).toBeTruthy();
|
|
@@ -224,6 +227,23 @@ describe('Message bar', () => {
|
|
|
224
227
|
await userEvent.click(attachButton);
|
|
225
228
|
expect(attachToggleClickSpy).toHaveBeenCalledTimes(1);
|
|
226
229
|
});
|
|
230
|
+
it('can toggle attach menu without an optional toggle callback', async () => {
|
|
231
|
+
const setIsAttachMenuOpen = jest.fn();
|
|
232
|
+
render(
|
|
233
|
+
<MessageBar
|
|
234
|
+
onSendMessage={jest.fn}
|
|
235
|
+
attachMenuProps={{
|
|
236
|
+
isAttachMenuOpen: false,
|
|
237
|
+
setIsAttachMenuOpen,
|
|
238
|
+
attachMenuItems: ATTACH_MENU_ITEMS
|
|
239
|
+
}}
|
|
240
|
+
/>
|
|
241
|
+
);
|
|
242
|
+
|
|
243
|
+
await userEvent.click(screen.getByRole('button', { name: 'Attach' }));
|
|
244
|
+
|
|
245
|
+
expect(setIsAttachMenuOpen).toHaveBeenCalledWith(true);
|
|
246
|
+
});
|
|
227
247
|
it('can pass searchInputProps to search input in AttachMenu', () => {
|
|
228
248
|
render(
|
|
229
249
|
<MessageBar
|
|
@@ -28,7 +28,7 @@ export interface MessageBarWithAttachMenuProps {
|
|
|
28
28
|
/** Items in menu */
|
|
29
29
|
attachMenuItems: React.ReactNode;
|
|
30
30
|
/** A callback for when the attachment menu toggle is clicked */
|
|
31
|
-
onAttachMenuToggleClick
|
|
31
|
+
onAttachMenuToggleClick?: () => void;
|
|
32
32
|
/** A callback for when the input value in the menu changes. */
|
|
33
33
|
onAttachMenuInputChange?: (value: string) => void;
|
|
34
34
|
/** Function callback called when user selects item in menu. */
|
|
@@ -368,7 +368,7 @@ export const MessageBarBase: FunctionComponent<MessageBarProps> = ({
|
|
|
368
368
|
|
|
369
369
|
const handleAttachMenuToggle = () => {
|
|
370
370
|
attachMenuProps?.setIsAttachMenuOpen && attachMenuProps?.setIsAttachMenuOpen(!attachMenuProps?.isAttachMenuOpen);
|
|
371
|
-
attachMenuProps?.onAttachMenuToggleClick();
|
|
371
|
+
attachMenuProps?.onAttachMenuToggleClick?.();
|
|
372
372
|
};
|
|
373
373
|
|
|
374
374
|
const handleSpeechRecognition = (message) => {
|
|
@@ -419,6 +419,8 @@ export const MessageBarBase: FunctionComponent<MessageBarProps> = ({
|
|
|
419
419
|
validator={validator}
|
|
420
420
|
dropzoneProps={dropzoneProps}
|
|
421
421
|
{...buttonProps?.attach}
|
|
422
|
+
isClicked={attachMenuProps.isAttachMenuOpen}
|
|
423
|
+
aria-expanded={attachMenuProps.isAttachMenuOpen}
|
|
422
424
|
/>
|
|
423
425
|
);
|
|
424
426
|
}
|
|
@@ -523,7 +525,9 @@ export const MessageBarBase: FunctionComponent<MessageBarProps> = ({
|
|
|
523
525
|
{...(attachMenuProps && { handleTextInputChange: attachMenuProps.onAttachMenuInputChange })}
|
|
524
526
|
popperProps={{ direction: 'up', distance: 8 }}
|
|
525
527
|
searchInputPlaceholder={attachMenuProps?.attachMenuInputPlaceholder}
|
|
526
|
-
{
|
|
528
|
+
menuSearchProps={attachMenuProps?.menuSearchProps}
|
|
529
|
+
menuSearchInputProps={attachMenuProps?.menuSearchInputProps}
|
|
530
|
+
searchInputProps={attachMenuProps?.searchInputProps}
|
|
527
531
|
/>
|
|
528
532
|
);
|
|
529
533
|
}
|