@patternfly/chatbot 6.9.0-prerelease.1 → 6.9.0-prerelease.3

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 (38) hide show
  1. package/dist/cjs/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.js +1 -1
  2. package/dist/cjs/MessageBar/MessageBar.js +1 -1
  3. package/dist/cjs/MessageBar/SendButton.js +2 -2
  4. package/dist/cjs/SourcesCard/SourcesCard.d.ts +2 -0
  5. package/dist/cjs/SourcesCardBase/SourcesCardBase.d.ts +2 -0
  6. package/dist/cjs/SourcesCardBase/SourcesCardBase.js +2 -2
  7. package/dist/css/main.css +163 -57
  8. package/dist/css/main.css.map +1 -1
  9. package/dist/esm/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.js +1 -1
  10. package/dist/esm/MessageBar/MessageBar.js +1 -1
  11. package/dist/esm/MessageBar/SendButton.js +2 -2
  12. package/dist/esm/SourcesCard/SourcesCard.d.ts +2 -0
  13. package/dist/esm/SourcesCardBase/SourcesCardBase.d.ts +2 -0
  14. package/dist/esm/SourcesCardBase/SourcesCardBase.js +2 -2
  15. package/package.json +3 -3
  16. package/patternfly-docs/content/extensions/chatbot/chatbot.md +1 -0
  17. package/patternfly-docs/content/extensions/chatbot/examples/Analytics/Analytics.md +1 -1
  18. package/patternfly-docs/content/extensions/chatbot/examples/Messages/MessageWithSources.tsx +31 -0
  19. package/patternfly-docs/content/extensions/chatbot/examples/Messages/Messages.md +2 -0
  20. package/patternfly-docs/content/extensions/chatbot/examples/demos/Canvas.md +110 -0
  21. package/patternfly-docs/content/extensions/chatbot/examples/demos/Canvas.tsx +609 -0
  22. package/patternfly-docs/content/extensions/chatbot/examples/demos/Chatbot.md +25 -3
  23. package/patternfly-docs/patternfly-docs.config.js +1 -1
  24. package/src/Canvas/Canvas.scss +138 -0
  25. package/src/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.scss +91 -77
  26. package/src/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.test.tsx +13 -0
  27. package/src/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.tsx +1 -0
  28. package/src/MessageBar/AttachButton.scss +4 -21
  29. package/src/MessageBar/MessageBar.test.tsx +3 -0
  30. package/src/MessageBar/MessageBar.tsx +2 -0
  31. package/src/MessageBar/SendButton.scss +1 -32
  32. package/src/MessageBar/SendButton.tsx +2 -2
  33. package/src/SourcesCard/SourcesCard.scss +6 -0
  34. package/src/SourcesCard/SourcesCard.test.tsx +16 -0
  35. package/src/SourcesCard/SourcesCard.tsx +2 -0
  36. package/src/SourcesCardBase/SourcesCardBase.test.tsx +62 -0
  37. package/src/SourcesCardBase/SourcesCardBase.tsx +8 -0
  38. package/src/main.scss +1 -0
@@ -0,0 +1,138 @@
1
+ // ============================================================================
2
+ // Canvas
3
+ // ============================================================================
4
+ .pf-chatbot__canvas {
5
+ --pf-chatbot__canvas--BackgroundColor: var(--pf-t--global--background--color--secondary--default);
6
+ --pf-chatbot__canvas--Padding: var(--pf-t--global--spacer--lg);
7
+
8
+ display: flex;
9
+ flex-direction: column;
10
+ flex: 1;
11
+ min-height: 0;
12
+ height: 100%;
13
+ background-color: var(--pf-chatbot__canvas--BackgroundColor);
14
+ }
15
+
16
+ :where(.pf-v6-theme-glass) .pf-chatbot__canvas {
17
+ --pf-chatbot__canvas--BackgroundColor: var(--pf-t--global--background--color--glass--primary--default);
18
+ }
19
+
20
+ // Drawer
21
+ // ----------------------------------------------------------------------------
22
+ .pf-chatbot__canvas-drawer {
23
+ flex: 1;
24
+ min-height: 0;
25
+ height: 100%;
26
+ background-color: var(--pf-chatbot__canvas--BackgroundColor);
27
+ --pf-v6-c-drawer__panel--Opacity: 1;
28
+ --pf-v6-c-drawer__panel--BackgroundColor: var(--pf-chatbot__canvas--BackgroundColor);
29
+ --pf-v6-c-drawer__panel--m-inline--BackgroundColor: var(--pf-chatbot__canvas--BackgroundColor);
30
+ --pf-v6-c-drawer__panel--m-inline--md--BackgroundColor: var(--pf-chatbot__canvas--BackgroundColor);
31
+ --pf-v6-c-drawer__panel--m-glass--BackgroundColor: var(--pf-chatbot__canvas--BackgroundColor);
32
+ --pf-v6-c-code-editor__main--BackgroundColor: var(--pf-chatbot__canvas--BackgroundColor);
33
+
34
+ > .pf-v6-c-drawer__main,
35
+ > .pf-v6-c-drawer__main > .pf-v6-c-drawer__panel,
36
+ > .pf-v6-c-drawer__main > .pf-v6-c-drawer__panel .pf-v6-c-drawer__panel-main {
37
+ background-color: var(--pf-chatbot__canvas--BackgroundColor);
38
+ }
39
+ }
40
+
41
+ @media screen and (min-width: 48rem) {
42
+ .pf-v6-c-drawer.pf-m-inline.pf-chatbot__canvas-drawer {
43
+ --pf-v6-c-drawer__panel--BackgroundColor: var(--pf-chatbot__canvas--BackgroundColor);
44
+ --pf-v6-c-drawer__panel--m-inline--md--BackgroundColor: var(--pf-chatbot__canvas--BackgroundColor);
45
+ }
46
+ }
47
+
48
+ .pf-chatbot__canvas-body {
49
+ height: 100%;
50
+ }
51
+
52
+ .pf-chatbot__canvas-column {
53
+ display: flex;
54
+ flex-direction: column;
55
+ height: 100%;
56
+ min-height: 0;
57
+ }
58
+
59
+ // Panel
60
+ // ----------------------------------------------------------------------------
61
+ .pf-chatbot__canvas-section {
62
+ display: flex;
63
+ flex-direction: column;
64
+ flex: 1;
65
+ min-height: 0;
66
+ height: 100%;
67
+ }
68
+
69
+ .pf-chatbot__canvas-panel {
70
+ height: 100%;
71
+ overflow: hidden;
72
+ background-color: var(--pf-chatbot__canvas--BackgroundColor);
73
+ --pf-v6-c-drawer__panel--BackgroundColor: var(--pf-chatbot__canvas--BackgroundColor);
74
+ --pf-v6-c-drawer__panel--m-inline--BackgroundColor: var(--pf-chatbot__canvas--BackgroundColor);
75
+ --pf-v6-c-drawer__panel--m-inline--md--BackgroundColor: var(--pf-chatbot__canvas--BackgroundColor);
76
+ --pf-v6-c-drawer__panel--m-glass--BackgroundColor: var(--pf-chatbot__canvas--BackgroundColor);
77
+ --pf-v6-c-drawer__panel--PaddingBlockStart: 0;
78
+ --pf-v6-c-drawer__panel--PaddingBlockEnd: 0;
79
+ --pf-v6-c-drawer__panel--RowGap: 0;
80
+
81
+ .pf-v6-c-drawer__panel-main {
82
+ display: flex;
83
+ flex-direction: column;
84
+ min-height: 0;
85
+ height: 100%;
86
+ }
87
+
88
+ .pf-chatbot__canvas-panel-body {
89
+ display: flex;
90
+ flex-direction: column;
91
+ flex: 1;
92
+ min-height: 0;
93
+ padding-block-end: var(--pf-chatbot__canvas--Padding);
94
+ padding-inline: var(--pf-chatbot__canvas--Padding);
95
+ box-sizing: border-box;
96
+ background-color: var(--pf-chatbot__canvas--BackgroundColor);
97
+ }
98
+
99
+ .pf-chatbot__canvas-head {
100
+ width: 100%;
101
+ grid-template-columns: minmax(0, 1fr) max-content;
102
+ --pf-v6-c-drawer__head--PaddingBlockStart: var(--pf-chatbot__canvas--Padding);
103
+ --pf-v6-c-drawer__head--PaddingBlockEnd: var(--pf-t--global--spacer--lg);
104
+ --pf-v6-c-drawer__head--PaddingInlineStart: var(--pf-chatbot__canvas--Padding);
105
+ --pf-v6-c-drawer__head--PaddingInlineEnd: var(--pf-chatbot__canvas--Padding);
106
+
107
+ .pf-v6-c-drawer__actions {
108
+ grid-column: 2;
109
+ justify-self: end;
110
+ align-self: start;
111
+ width: max-content;
112
+ --pf-v6-c-drawer__actions--MarginBlockStart: 0;
113
+ --pf-v6-c-drawer__actions--MarginInlineEnd: 0;
114
+
115
+ .pf-v6-c-button {
116
+ border-radius: var(--pf-t--global--border--radius--pill);
117
+ justify-content: center;
118
+ align-items: center;
119
+
120
+ &::before {
121
+ border-radius: inherit;
122
+ }
123
+ }
124
+ }
125
+ }
126
+ }
127
+
128
+ .pf-chatbot__canvas-editor {
129
+ display: flex;
130
+ flex: 1;
131
+ flex-direction: column;
132
+ min-height: 0;
133
+ height: 100%;
134
+
135
+ .pf-v6-c-code-editor {
136
+ --pf-v6-c-code-editor__main--BackgroundColor: var(--pf-chatbot__canvas--BackgroundColor);
137
+ }
138
+ }
@@ -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
- // Drawer head
191
- .pf-v6-c-drawer__head {
192
- --pf-v6-c-drawer__head--PaddingBlockStart: 0;
193
- --pf-v6-c-drawer__head--PaddingBlockEnd: 0;
194
- --pf-v6-c-drawer__head--PaddingInlineStart: var(--pf-t--global--spacer--lg);
195
- --pf-v6-c-drawer__head--PaddingInlineEnd: var(--pf-t--global--spacer--lg);
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
- display: flex;
198
- align-items: center;
199
- justify-content: space-between;
200
- height: var(--pf-t--global--spacer--2xl);
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
- // Drawer actions
204
- .pf-v6-c-drawer__actions {
205
- --pf-v6-c-drawer__actions--MarginBlockStart: 0;
206
- --pf-v6-c-drawer__actions--MarginInlineEnd: 0;
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
- display: flex;
209
- align-items: center;
210
- justify-content: space-between;
211
- align-self: center;
212
- width: 100%;
213
- height: 100%;
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
- .pf-v6-c-drawer__actions--reversed {
217
- flex-direction: row-reverse;
218
- }
218
+ .pf-v6-c-drawer__actions--reversed {
219
+ flex-direction: row-reverse;
220
+ }
219
221
 
220
- // Close drawer
221
- .pf-v6-c-drawer__close {
222
- .pf-v6-c-button {
223
- width: var(--pf-t--global--spacer--2xl);
224
- height: var(--pf-t--global--spacer--2xl);
225
- border-radius: var(--pf-t--global--border--radius--pill);
226
- justify-content: center;
227
- align-items: center;
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
- // Drawer body
232
- .pf-v6-c-drawer__body {
233
- --pf-v6-c-drawer__panel__body--PaddingBlockStart: 0;
234
- --pf-v6-c-drawer__panel__body--PaddingBlockEnd: 0;
235
- --pf-v6-c-drawer__panel__body--PaddingInlineStart: var(--pf-t--global--spacer--lg);
236
- --pf-v6-c-drawer__panel__body--PaddingInlineEnd: var(--pf-t--global--spacer--lg);
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
- .pf-v6-c-drawer__body {
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
- .pf-v6-c-drawer__body {
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
- .pf-v6-c-drawer__panel {
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
- .pf-v6-c-drawer__panel {
332
- --pf-v6-c-drawer__panel--PaddingBlockStart: var(--pf-t--global--spacer--sm);
333
- --pf-v6-c-drawer__panel--PaddingBlockEnd: var(--pf-t--global--spacer--sm);
334
- --pf-v6-c-drawer__head--PaddingInlineStart: var(--pf-t--global--spacer--md);
335
- --pf-v6-c-drawer__head--PaddingInlineEnd: var(--pf-t--global--spacer--md);
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
  }
@@ -204,6 +204,19 @@ describe('ChatbotConversationHistoryNav', () => {
204
204
  );
205
205
  });
206
206
 
207
+ it('should keep an opaque panel background in glass theme', () => {
208
+ render(
209
+ <ChatbotConversationHistoryNav
210
+ onDrawerToggle={onDrawerToggle}
211
+ isDrawerOpen={true}
212
+ displayMode={ChatbotDisplayMode.fullscreen}
213
+ setIsDrawerOpen={jest.fn()}
214
+ conversations={initialConversations}
215
+ />
216
+ );
217
+ expect(screen.getByRole('dialog')).toHaveClass('pf-m-no-plain-on-glass');
218
+ });
219
+
207
220
  it('should accept drawerContentProps', () => {
208
221
  const { container } = render(
209
222
  <ChatbotConversationHistoryNav
@@ -683,6 +683,7 @@ export const ChatbotConversationHistoryNav: FunctionComponent<ChatbotConversatio
683
683
  aria-live="polite"
684
684
  focusTrap={{ enabled: true }}
685
685
  defaultSize="384px"
686
+ isNoPlainOnGlass
686
687
  {...drawerPanelContentProps}
687
688
  >
688
689
  {drawer}
@@ -7,30 +7,13 @@
7
7
  width: 3rem;
8
8
  height: 3rem;
9
9
 
10
- .pf-v6-c-button__icon {
11
- color: var(--pf-t--global--icon--color--subtle);
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--inverse);
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
  }
@@ -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();
@@ -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
  }
@@ -7,38 +7,7 @@
7
7
  width: 3rem;
8
8
  height: 3rem;
9
9
 
10
- .pf-v6-c-button__icon {
11
- --pf-v6-c-button__icon--Color: var(--pf-t--global--color--brand--default);
12
- }
13
-
14
- &:hover,
15
- &:focus {
16
- background-color: rgba(146, 197, 249, 0.25); // --pf-t--global--color--nonstatus--blue--default @ 25%;
17
- color: var(--pf-t--global--color--brand--hover);
18
-
19
- .pf-v6-c-button__icon {
20
- color: var(--pf-t--global--color--brand--hover);
21
- }
22
- }
23
- }
24
-
25
- .pf-v6-theme-dark {
26
- .pf-v6-c-button.pf-chatbot__button--send {
27
- background-color: var(--pf-t--global--color--brand--default);
28
- .pf-v6-c-button__icon {
29
- --pf-v6-c-button__icon--Color: var(--pf-t--global--icon--color--inverse);
30
- }
31
- }
32
-
33
- .pf-v6-c-button:disabled.pf-chatbot__button--send:disabled {
34
- --pf-v6-c-button--disabled--Color: var(--pf-t--global--icon--color--disabled);
35
- background-color: var(--pf-t--global--background--color--disabled--default);
36
- }
37
-
38
- .pf-v6-c-button.pf-chatbot__button--send:hover,
39
- .pf-v6-c-button.pf-chatbot__button--send:focus {
40
- background-color: rgba(146, 197, 249, 0.25); // --pf-t--global--color--nonstatus--blue--default @ 25%;
41
- }
10
+ --pf-v6-c-button--m-plain__icon--Color: var(--pf-t--global--color--brand--default);
42
11
  }
43
12
 
44
13
  @keyframes motionSendButton {
@@ -6,7 +6,7 @@ import type { FunctionComponent } from 'react';
6
6
  // Import PatternFly components
7
7
  import { Button, ButtonProps, Tooltip, TooltipProps, Icon } from '@patternfly/react-core';
8
8
 
9
- import { PaperPlaneIcon } from '@patternfly/react-icons/dist/esm/icons/paper-plane-icon';
9
+ import { RhUiSendFillIcon } from '@patternfly/react-icons/dist/esm/icons/rh-ui-send-fill-icon';
10
10
 
11
11
  export interface SendButtonProps extends ButtonProps {
12
12
  /** Callback for when button is clicked */
@@ -48,7 +48,7 @@ export const SendButton: FunctionComponent<SendButtonProps> = ({
48
48
  onClick={onClick}
49
49
  icon={
50
50
  <Icon iconSize={isCompact ? 'lg' : 'xl'} isInline>
51
- <PaperPlaneIcon />
51
+ <RhUiSendFillIcon />
52
52
  </Icon>
53
53
  }
54
54
  size={isCompact ? 'sm' : undefined}
@@ -58,6 +58,12 @@
58
58
  text-overflow: ellipsis;
59
59
  }
60
60
 
61
+ .pf-chatbot__sources-header-content-container {
62
+ display: inline-flex;
63
+ width: fit-content;
64
+ margin-block-end: var(--pf-t--global--spacer--sm);
65
+ }
66
+
61
67
  .pf-chatbot__sources-card-title-container {
62
68
  display: flex;
63
69
  flex-direction: column;
@@ -25,6 +25,22 @@ describe('SourcesCard', () => {
25
25
  screen.getByRole('button', { name: /Go to next page/i });
26
26
  });
27
27
 
28
+ it('should render headerContent above the title', () => {
29
+ render(
30
+ <SourcesCard
31
+ sources={[
32
+ {
33
+ title: 'How to make an apple pie',
34
+ link: '',
35
+ headerContent: <span>Dessert</span>
36
+ }
37
+ ]}
38
+ />
39
+ );
40
+ expect(screen.getByText('Dessert')).toBeTruthy();
41
+ expect(screen.getByText('How to make an apple pie')).toBeTruthy();
42
+ });
43
+
28
44
  it('should render with wrap layout when layout is set to wrap', () => {
29
45
  render(
30
46
  <SourcesCard
@@ -49,6 +49,8 @@ export interface SourcesCardProps extends CardProps {
49
49
  footer?: React.ReactNode;
50
50
  /** Additional props passed to Truncate component */
51
51
  truncateProps?: TruncateProps;
52
+ /** Additional content applied to the beginning of the sources card header, such as a label */
53
+ headerContent?: React.ReactNode;
52
54
  }[];
53
55
  /** Label for the English word "source" */
54
56
  sourceWord?: string;
@@ -234,6 +234,68 @@ describe('SourcesCardBase', () => {
234
234
  expect(screen.getByRole('link', { name: /How to make an apple pie/i })).toHaveClass('test');
235
235
  });
236
236
 
237
+ it('should render headerContent above the title', () => {
238
+ render(
239
+ <SourcesCardBase
240
+ sources={[
241
+ {
242
+ title: 'How to make an apple pie',
243
+ link: '',
244
+ headerContent: <span>Dessert</span>
245
+ }
246
+ ]}
247
+ />
248
+ );
249
+ expect(screen.getByText('Dessert')).toBeTruthy();
250
+ expect(screen.getByText('How to make an apple pie')).toBeTruthy();
251
+ });
252
+
253
+ it('should update headerContent when navigating between sources', async () => {
254
+ render(
255
+ <SourcesCardBase
256
+ sources={[
257
+ {
258
+ title: 'How to make an apple pie',
259
+ link: '',
260
+ headerContent: <span>Dessert</span>
261
+ },
262
+ {
263
+ title: 'How to make cookies',
264
+ link: '',
265
+ headerContent: <span>Snack</span>
266
+ }
267
+ ]}
268
+ />
269
+ );
270
+ expect(screen.getByText('Dessert')).toBeTruthy();
271
+ expect(screen.queryByText('Snack')).toBeFalsy();
272
+ await userEvent.click(screen.getByRole('button', { name: /Go to next page/i }));
273
+ expect(screen.queryByText('Dessert')).toBeFalsy();
274
+ expect(screen.getByText('Snack')).toBeTruthy();
275
+ });
276
+
277
+ it('should render headerContent when using wrap layout', () => {
278
+ render(
279
+ <SourcesCardBase
280
+ layout="wrap"
281
+ sources={[
282
+ {
283
+ title: 'How to make an apple pie',
284
+ link: '',
285
+ headerContent: <span>Dessert</span>
286
+ },
287
+ {
288
+ title: 'How to make cookies',
289
+ link: '',
290
+ headerContent: <span>Snack</span>
291
+ }
292
+ ]}
293
+ />
294
+ );
295
+ expect(screen.getByText('Dessert')).toBeTruthy();
296
+ expect(screen.getByText('Snack')).toBeTruthy();
297
+ });
298
+
237
299
  it('should render with wrap layout when layout prop is set to wrap', () => {
238
300
  render(
239
301
  <SourcesCardBase
@@ -63,6 +63,8 @@ export interface SourcesCardBaseProps extends CardProps {
63
63
  footer?: React.ReactNode;
64
64
  /** Additional props passed to Truncate component */
65
65
  truncateProps?: TruncateProps;
66
+ /** Additional content applied to the beginning of the sources card header, such as a label */
67
+ headerContent?: React.ReactNode;
66
68
  }[];
67
69
  /** Accessible label for the button which moves to the next page. */
68
70
  toNextPageAriaLabel?: string;
@@ -133,6 +135,9 @@ const SourcesCardBase: FunctionComponent<SourcesCardBaseProps> = ({
133
135
  >
134
136
  <Card isFullHeight isCompact={isCompact} className="pf-chatbot__sources-card" {...props}>
135
137
  <CardTitle className="pf-chatbot__sources-card-title" {...cardTitleProps}>
138
+ {source.headerContent && (
139
+ <div className="pf-chatbot__sources-header-content-container">{source.headerContent}</div>
140
+ )}
136
141
  <div className="pf-chatbot__sources-card-title-container">
137
142
  <Button
138
143
  component="a"
@@ -196,6 +201,9 @@ const SourcesCardBase: FunctionComponent<SourcesCardBaseProps> = ({
196
201
  <div className="pf-chatbot__sources-card-base">
197
202
  <Card isCompact={isCompact} className="pf-chatbot__sources-card" {...props}>
198
203
  <CardTitle className="pf-chatbot__sources-card-title" {...cardTitleProps}>
204
+ {sources[page - 1].headerContent && (
205
+ <div className="pf-chatbot__sources-header-content-container">{sources[page - 1].headerContent}</div>
206
+ )}
199
207
  <div className="pf-chatbot__sources-card-title-container">
200
208
  <Button
201
209
  component="a"
package/src/main.scss CHANGED
@@ -9,6 +9,7 @@
9
9
  @import './ChatbotPopover/ChatbotPopover';
10
10
  @import './ChatbotToggle/ChatbotToggle';
11
11
  @import './ChatbotWelcomePrompt/ChatbotWelcomePrompt';
12
+ @import './Canvas/Canvas';
12
13
  @import './CodeModal/CodeModal';
13
14
  @import './Compare/Compare';
14
15
  @import './DeepThinking/DeepThinking';