@patternfly/chatbot 2.2.0-prerelease.20 → 2.2.0-prerelease.21

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. package/dist/cjs/Message/Message.d.ts +3 -0
  2. package/dist/cjs/Message/Message.js +22 -5
  3. package/dist/cjs/Message/Message.test.js +94 -0
  4. package/dist/cjs/Message/TableMessage/TableMessage.d.ts +20 -0
  5. package/dist/cjs/Message/TableMessage/TableMessage.js +67 -0
  6. package/dist/cjs/Message/TableMessage/TbodyMessage.d.ts +7 -0
  7. package/dist/cjs/Message/TableMessage/TbodyMessage.js +33 -0
  8. package/dist/cjs/Message/TableMessage/TdMessage.d.ts +5 -0
  9. package/dist/cjs/Message/TableMessage/TdMessage.js +26 -0
  10. package/dist/cjs/Message/TableMessage/ThMessage.d.ts +5 -0
  11. package/dist/cjs/Message/TableMessage/ThMessage.js +26 -0
  12. package/dist/cjs/Message/TableMessage/TheadMessage.d.ts +5 -0
  13. package/dist/cjs/Message/TableMessage/TheadMessage.js +26 -0
  14. package/dist/cjs/Message/TableMessage/TrMessage.d.ts +7 -0
  15. package/dist/cjs/Message/TableMessage/TrMessage.js +37 -0
  16. package/dist/css/main.css +28 -0
  17. package/dist/css/main.css.map +1 -1
  18. package/dist/esm/Message/Message.d.ts +3 -0
  19. package/dist/esm/Message/Message.js +22 -5
  20. package/dist/esm/Message/Message.test.js +94 -0
  21. package/dist/esm/Message/TableMessage/TableMessage.d.ts +20 -0
  22. package/dist/esm/Message/TableMessage/TableMessage.js +62 -0
  23. package/dist/esm/Message/TableMessage/TbodyMessage.d.ts +7 -0
  24. package/dist/esm/Message/TableMessage/TbodyMessage.js +28 -0
  25. package/dist/esm/Message/TableMessage/TdMessage.d.ts +5 -0
  26. package/dist/esm/Message/TableMessage/TdMessage.js +21 -0
  27. package/dist/esm/Message/TableMessage/ThMessage.d.ts +5 -0
  28. package/dist/esm/Message/TableMessage/ThMessage.js +21 -0
  29. package/dist/esm/Message/TableMessage/TheadMessage.d.ts +5 -0
  30. package/dist/esm/Message/TableMessage/TheadMessage.js +21 -0
  31. package/dist/esm/Message/TableMessage/TrMessage.d.ts +7 -0
  32. package/dist/esm/Message/TableMessage/TrMessage.js +32 -0
  33. package/dist/tsconfig.tsbuildinfo +1 -1
  34. package/package.json +1 -1
  35. package/patternfly-docs/content/extensions/chatbot/examples/Messages/BotMessage.tsx +27 -1
  36. package/patternfly-docs/content/extensions/chatbot/examples/Messages/UserMessage.tsx +27 -1
  37. package/src/Message/Message.test.tsx +99 -0
  38. package/src/Message/Message.tsx +25 -4
  39. package/src/Message/TableMessage/TableMessage.scss +23 -0
  40. package/src/Message/TableMessage/TableMessage.tsx +83 -0
  41. package/src/Message/TableMessage/TbodyMessage.tsx +20 -0
  42. package/src/Message/TableMessage/TdMessage.tsx +11 -0
  43. package/src/Message/TableMessage/ThMessage.tsx +11 -0
  44. package/src/Message/TableMessage/TheadMessage.tsx +11 -0
  45. package/src/Message/TableMessage/TrMessage.tsx +27 -0
  46. package/src/Message/TextMessage/TextMessage.scss +5 -0
  47. package/src/main.scss +1 -0
@@ -88,6 +88,50 @@ const HEADING = `
88
88
  const BLOCK_QUOTES = `> Blockquotes can also be nested...
89
89
  >> ...by using additional greater-than signs (>) right next to each other...
90
90
  > > > ...or with spaces between each sign.`;
91
+ const TABLE = `
92
+
93
+ | Column 1 | Column 2 |
94
+ |-|-|
95
+ | Cell 1 | Cell 2 |
96
+ | Cell 3 | Cell 4 |
97
+
98
+ `;
99
+ const ONE_COLUMN_TABLE = `
100
+
101
+ | Column 1 |
102
+ |-|
103
+ | Cell 1 |
104
+ | Cell 2 |
105
+
106
+ `;
107
+ const ONE_CELL_TABLE = `
108
+
109
+ | Column 1 |
110
+ |-|
111
+ | Cell 1 |
112
+
113
+ `;
114
+ const HEADERLESS_TABLE = `
115
+
116
+ | |
117
+ |-|
118
+ | Cell 1 |
119
+
120
+ `;
121
+ const CHILDLESS_TABLE = `
122
+
123
+ | Column 1 |
124
+ |-|
125
+ | |
126
+
127
+ `;
128
+ const EMPTY_TABLE = `
129
+
130
+ | |
131
+ |-|
132
+ | |
133
+
134
+ `;
91
135
  const checkListItemsRendered = () => {
92
136
  const items = ['Item 1', 'Item 2', 'Item 3'];
93
137
  expect(screen.getAllByRole('listitem')).toHaveLength(3);
@@ -413,4 +457,54 @@ describe('Message', () => {
413
457
  expect(screen.getByRole('heading', { name: /h5 Heading/i })).toBeTruthy();
414
458
  expect(screen.getByRole('heading', { name: /h6 Heading/i })).toBeTruthy();
415
459
  });
460
+ it('should render table correctly', () => {
461
+ render(React.createElement(Message, { avatar: "./img", role: "user", name: "User", content: TABLE }));
462
+ expect(screen.getByRole('row', { name: /Column 1 Column 2/i })).toBeTruthy();
463
+ expect(screen.getByRole('row', { name: /Cell 1 Cell 2/i })).toBeTruthy();
464
+ expect(screen.getByRole('row', { name: /Cell 3 Cell 4/i })).toBeTruthy();
465
+ expect(screen.getByRole('columnheader', { name: /Column 1/i })).toBeTruthy();
466
+ expect(screen.getByRole('columnheader', { name: /Column 2/i })).toBeTruthy();
467
+ expect(screen.getByRole('cell', { name: /Cell 1/i })).toBeTruthy();
468
+ expect(screen.getByRole('cell', { name: /Cell 2/i })).toBeTruthy();
469
+ expect(screen.getByRole('cell', { name: /Cell 3/i })).toBeTruthy();
470
+ expect(screen.getByRole('cell', { name: /Cell 4/i })).toBeTruthy();
471
+ });
472
+ it('should render table data labels correctly for mobile breakpoint', () => {
473
+ render(React.createElement(Message, { avatar: "./img", role: "user", name: "User", content: TABLE }));
474
+ expect(screen.getByRole('row', { name: /Cell 1 Cell 2/i })).toHaveAttribute('extraHeaders', 'Column 1,Column 2');
475
+ expect(screen.getByRole('row', { name: /Cell 3 Cell 4/i })).toHaveAttribute('extraHeaders', 'Column 1,Column 2');
476
+ expect(screen.getByRole('cell', { name: /Cell 1/i })).toHaveAttribute('data-label', 'Column 1');
477
+ expect(screen.getByRole('cell', { name: /Cell 2/i })).toHaveAttribute('data-label', 'Column 2');
478
+ expect(screen.getByRole('cell', { name: /Cell 3/i })).toHaveAttribute('data-label', 'Column 1');
479
+ expect(screen.getByRole('cell', { name: /Cell 4/i })).toHaveAttribute('data-label', 'Column 2');
480
+ });
481
+ it('should render table data labels correctly for mobile breakpoint for one column table', () => {
482
+ render(React.createElement(Message, { avatar: "./img", role: "user", name: "User", content: ONE_COLUMN_TABLE }));
483
+ expect(screen.getByRole('row', { name: /Cell 1/i })).toHaveAttribute('extraHeaders', 'Column 1');
484
+ expect(screen.getByRole('row', { name: /Cell 2/i })).toHaveAttribute('extraHeaders', 'Column 1');
485
+ expect(screen.getByRole('cell', { name: /Cell 1/i })).toHaveAttribute('data-label', 'Column 1');
486
+ expect(screen.getByRole('cell', { name: /Cell 2/i })).toHaveAttribute('data-label', 'Column 1');
487
+ });
488
+ it('should render table data labels correctly for mobile breakpoint for one cell table', () => {
489
+ render(React.createElement(Message, { avatar: "./img", role: "user", name: "User", content: ONE_CELL_TABLE }));
490
+ expect(screen.getByRole('row', { name: /Cell 1/i })).toHaveAttribute('extraHeaders', 'Column 1');
491
+ expect(screen.getByRole('cell', { name: /Cell 1/i })).toHaveAttribute('data-label', 'Column 1');
492
+ });
493
+ it('should render table data labels correctly for mobile breakpoint for headerless', () => {
494
+ render(React.createElement(Message, { avatar: "./img", role: "user", name: "User", content: HEADERLESS_TABLE }));
495
+ expect(screen.getByRole('row', { name: /Cell 1/i })).toHaveAttribute('extraHeaders', '');
496
+ expect(screen.getByRole('cell', { name: /Cell 1/i })).not.toHaveAttribute('data-label');
497
+ });
498
+ it('should render table data labels correctly for mobile breakpoint for childless', () => {
499
+ render(React.createElement(Message, { avatar: "./img", role: "user", name: "User", content: CHILDLESS_TABLE }));
500
+ expect(screen.getByRole('cell')).not.toHaveAttribute('extraHeaders', 'Column 1');
501
+ });
502
+ it('should render table data labels correctly for mobile breakpoint for empty', () => {
503
+ render(React.createElement(Message, { avatar: "./img", role: "user", name: "User", content: EMPTY_TABLE }));
504
+ expect(screen.getByRole('cell')).not.toHaveAttribute('extraHeaders', '');
505
+ });
506
+ it('should render custom table aria label correctly', () => {
507
+ render(React.createElement(Message, { avatar: "./img", role: "user", name: "User", content: TABLE, tableProps: { 'aria-label': 'Test' } }));
508
+ expect(screen.getByRole('grid', { name: /Test/i })).toBeTruthy();
509
+ });
416
510
  });
@@ -0,0 +1,20 @@
1
+ import React from 'react';
2
+ import { ExtraProps } from 'react-markdown';
3
+ import { TableProps } from '@patternfly/react-table';
4
+ interface Properties {
5
+ line: number;
6
+ column: number;
7
+ offset: number;
8
+ }
9
+ export interface TableNode {
10
+ children?: TableNode[];
11
+ value?: string;
12
+ position: {
13
+ start: Properties;
14
+ end: Properties;
15
+ };
16
+ tagName: string;
17
+ type: string;
18
+ }
19
+ declare const TableMessage: ({ children, ...props }: TableProps & ExtraProps) => React.JSX.Element;
20
+ export default TableMessage;
@@ -0,0 +1,62 @@
1
+ // ============================================================================
2
+ // Chatbot Main - Message - Content - Table
3
+ // ============================================================================
4
+ var __rest = (this && this.__rest) || function (s, e) {
5
+ var t = {};
6
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
7
+ t[p] = s[p];
8
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
9
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
10
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
11
+ t[p[i]] = s[p[i]];
12
+ }
13
+ return t;
14
+ };
15
+ import React from 'react';
16
+ import { Table } from '@patternfly/react-table';
17
+ const TableMessage = (_a) => {
18
+ var _b;
19
+ var { children } = _a, props = __rest(_a, ["children"]);
20
+ const { className } = props, rest = __rest(props, ["className"]);
21
+ // This allows us to parse the nested data we get back from the 3rd party Markdown parser
22
+ // Open to feedback here if there is a better way to do this
23
+ // This looks for ths and spits them all out so we can filter them later, looking for text values
24
+ const findHeaders = (array) => {
25
+ const headers = [];
26
+ if (!array) {
27
+ return headers;
28
+ }
29
+ const traverse = (items) => {
30
+ for (const item of items) {
31
+ if (item.tagName === 'th') {
32
+ headers.push(item);
33
+ }
34
+ if (item.children) {
35
+ traverse(item.children);
36
+ }
37
+ }
38
+ };
39
+ traverse(array);
40
+ return headers;
41
+ };
42
+ const headers = findHeaders((_b = rest.node) === null || _b === void 0 ? void 0 : _b.children);
43
+ const headerTextValues = headers.map((header) => { var _a, _b; return (_b = (_a = header === null || header === void 0 ? void 0 : header.children) === null || _a === void 0 ? void 0 : _a.filter((c) => (c === null || c === void 0 ? void 0 : c.type) === 'text')[0]) === null || _b === void 0 ? void 0 : _b.value; });
44
+ // We are sending these header text values down to child tds by passing them through children, since mobile view for tables expects a dataLabel prop
45
+ // The data structure does not otherwise know this information at that level
46
+ // This is somewhat opinionated and may break if 3rd party library changes
47
+ // See Tr and Tbody for other usage
48
+ const modifyChildren = (children) => React.Children.map(children, (child) => {
49
+ if (child && (headerTextValues === null || headerTextValues === void 0 ? void 0 : headerTextValues.length) > 0) {
50
+ return React.cloneElement(child, { extraHeaders: headerTextValues });
51
+ }
52
+ return child;
53
+ });
54
+ if (!props['aria-label']) {
55
+ // eslint-disable-next-line no-console
56
+ console.warn('For accessibility reasons an aria-label should be specified for the Table via the <Message /> tableProps prop');
57
+ }
58
+ return (
59
+ // gridBreakPoint is so we show mobile-styled-PF table
60
+ React.createElement(Table, Object.assign({ "aria-label": props['aria-label'], gridBreakPoint: "grid", className: `pf-chatbot__message-table ${className ? className : ''}` }, rest), modifyChildren(children)));
61
+ };
62
+ export default TableMessage;
@@ -0,0 +1,7 @@
1
+ import React from 'react';
2
+ import { ExtraProps } from 'react-markdown';
3
+ import { TbodyProps } from '@patternfly/react-table';
4
+ declare const TbodyProps: ({ children, ...props }: TbodyProps & ExtraProps & {
5
+ extraHeaders?: string[];
6
+ }) => React.JSX.Element;
7
+ export default TbodyProps;
@@ -0,0 +1,28 @@
1
+ // ============================================================================
2
+ // Chatbot Main - Message - Content - Table
3
+ // ============================================================================
4
+ var __rest = (this && this.__rest) || function (s, e) {
5
+ var t = {};
6
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
7
+ t[p] = s[p];
8
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
9
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
10
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
11
+ t[p[i]] = s[p[i]];
12
+ }
13
+ return t;
14
+ };
15
+ import React from 'react';
16
+ import { Tbody } from '@patternfly/react-table';
17
+ const TbodyProps = (_a) => {
18
+ var { children } = _a, props = __rest(_a, ["children"]);
19
+ // passthrough so we can place dataLabel on tds
20
+ const modifyChildren = (children) => {
21
+ if (children && props.extraHeaders) {
22
+ return React.Children.map(children, (child) => React.cloneElement(child, { extraHeaders: props.extraHeaders }));
23
+ }
24
+ return children;
25
+ };
26
+ return React.createElement(Tbody, Object.assign({}, props), modifyChildren(children));
27
+ };
28
+ export default TbodyProps;
@@ -0,0 +1,5 @@
1
+ import React from 'react';
2
+ import { ExtraProps } from 'react-markdown';
3
+ import { TdProps } from '@patternfly/react-table';
4
+ declare const TdMessage: ({ children, ...props }: TdProps & ExtraProps) => React.JSX.Element;
5
+ export default TdMessage;
@@ -0,0 +1,21 @@
1
+ // ============================================================================
2
+ // Chatbot Main - Message - Content - Table
3
+ // ============================================================================
4
+ var __rest = (this && this.__rest) || function (s, e) {
5
+ var t = {};
6
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
7
+ t[p] = s[p];
8
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
9
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
10
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
11
+ t[p[i]] = s[p[i]];
12
+ }
13
+ return t;
14
+ };
15
+ import React from 'react';
16
+ import { Td } from '@patternfly/react-table';
17
+ const TdMessage = (_a) => {
18
+ var { children } = _a, props = __rest(_a, ["children"]);
19
+ return React.createElement(Td, Object.assign({}, props), children);
20
+ };
21
+ export default TdMessage;
@@ -0,0 +1,5 @@
1
+ import React from 'react';
2
+ import { ExtraProps } from 'react-markdown';
3
+ import { ThProps } from '@patternfly/react-table';
4
+ declare const ThMessage: ({ children, ...props }: ThProps & ExtraProps) => React.JSX.Element;
5
+ export default ThMessage;
@@ -0,0 +1,21 @@
1
+ // ============================================================================
2
+ // Chatbot Main - Message - Content - Table
3
+ // ============================================================================
4
+ var __rest = (this && this.__rest) || function (s, e) {
5
+ var t = {};
6
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
7
+ t[p] = s[p];
8
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
9
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
10
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
11
+ t[p[i]] = s[p[i]];
12
+ }
13
+ return t;
14
+ };
15
+ import React from 'react';
16
+ import { Th } from '@patternfly/react-table';
17
+ const ThMessage = (_a) => {
18
+ var { children } = _a, props = __rest(_a, ["children"]);
19
+ return React.createElement(Th, Object.assign({}, props), children);
20
+ };
21
+ export default ThMessage;
@@ -0,0 +1,5 @@
1
+ import React from 'react';
2
+ import { ExtraProps } from 'react-markdown';
3
+ import { TheadProps } from '@patternfly/react-table';
4
+ declare const TheadMessage: ({ children, ...props }: TheadProps & ExtraProps) => React.JSX.Element;
5
+ export default TheadMessage;
@@ -0,0 +1,21 @@
1
+ // ============================================================================
2
+ // Chatbot Main - Message - Content - Table
3
+ // ============================================================================
4
+ var __rest = (this && this.__rest) || function (s, e) {
5
+ var t = {};
6
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
7
+ t[p] = s[p];
8
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
9
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
10
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
11
+ t[p[i]] = s[p[i]];
12
+ }
13
+ return t;
14
+ };
15
+ import React from 'react';
16
+ import { Thead } from '@patternfly/react-table';
17
+ const TheadMessage = (_a) => {
18
+ var { children } = _a, props = __rest(_a, ["children"]);
19
+ return React.createElement(Thead, Object.assign({}, props), children);
20
+ };
21
+ export default TheadMessage;
@@ -0,0 +1,7 @@
1
+ import React from 'react';
2
+ import { ExtraProps } from 'react-markdown';
3
+ import { TrProps } from '@patternfly/react-table';
4
+ declare const TrMessage: ({ children, ...props }: TrProps & ExtraProps & {
5
+ extraHeaders?: string[];
6
+ }) => React.JSX.Element;
7
+ export default TrMessage;
@@ -0,0 +1,32 @@
1
+ // ============================================================================
2
+ // Chatbot Main - Message - Content - Table
3
+ // ============================================================================
4
+ var __rest = (this && this.__rest) || function (s, e) {
5
+ var t = {};
6
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
7
+ t[p] = s[p];
8
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
9
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
10
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
11
+ t[p[i]] = s[p[i]];
12
+ }
13
+ return t;
14
+ };
15
+ import React from 'react';
16
+ import { Tr } from '@patternfly/react-table';
17
+ const TrMessage = (_a) => {
18
+ var { children } = _a, props = __rest(_a, ["children"]);
19
+ let tdIndex = 0;
20
+ // passthrough so we can place dataLabel on tds
21
+ // places column name on correct child
22
+ const modifyChildren = (children) => React.Children.map(children, (child) => {
23
+ if (child.type.name === 'td' && props.extraHeaders) {
24
+ const clonedChild = React.cloneElement(child, { dataLabel: props.extraHeaders[tdIndex] });
25
+ tdIndex = tdIndex + 1;
26
+ return clonedChild;
27
+ }
28
+ return child;
29
+ });
30
+ return React.createElement(Tr, Object.assign({}, props), modifyChildren(children));
31
+ };
32
+ export default TrMessage;
@@ -1 +1 @@
1
- {"root":["../src/index.ts","../src/AttachMenu/AttachMenu.tsx","../src/AttachMenu/index.ts","../src/AttachmentEdit/AttachmentEdit.test.tsx","../src/AttachmentEdit/AttachmentEdit.tsx","../src/AttachmentEdit/index.ts","../src/Chatbot/Chatbot.test.tsx","../src/Chatbot/Chatbot.tsx","../src/Chatbot/index.ts","../src/ChatbotAlert/ChatbotAlert.test.tsx","../src/ChatbotAlert/ChatbotAlert.tsx","../src/ChatbotAlert/index.ts","../src/ChatbotContent/ChatbotContent.test.tsx","../src/ChatbotContent/ChatbotContent.tsx","../src/ChatbotContent/index.ts","../src/ChatbotConversationHistoryNav/ChatbotConversationHistoryDropdown.test.tsx","../src/ChatbotConversationHistoryNav/ChatbotConversationHistoryDropdown.tsx","../src/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.test.tsx","../src/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.tsx","../src/ChatbotConversationHistoryNav/index.ts","../src/ChatbotFooter/ChatbotFooter.test.tsx","../src/ChatbotFooter/ChatbotFooter.tsx","../src/ChatbotFooter/ChatbotFooternote.test.tsx","../src/ChatbotFooter/ChatbotFootnote.tsx","../src/ChatbotFooter/index.ts","../src/ChatbotHeader/ChatbotHeader.test.tsx","../src/ChatbotHeader/ChatbotHeader.tsx","../src/ChatbotHeader/ChatbotHeaderActions.test.tsx","../src/ChatbotHeader/ChatbotHeaderActions.tsx","../src/ChatbotHeader/ChatbotHeaderCloseButton.test.tsx","../src/ChatbotHeader/ChatbotHeaderCloseButton.tsx","../src/ChatbotHeader/ChatbotHeaderMain.test.tsx","../src/ChatbotHeader/ChatbotHeaderMain.tsx","../src/ChatbotHeader/ChatbotHeaderMenu.test.tsx","../src/ChatbotHeader/ChatbotHeaderMenu.tsx","../src/ChatbotHeader/ChatbotHeaderOptionsDropdown.test.tsx","../src/ChatbotHeader/ChatbotHeaderOptionsDropdown.tsx","../src/ChatbotHeader/ChatbotHeaderSelectorDropdown.test.tsx","../src/ChatbotHeader/ChatbotHeaderSelectorDropdown.tsx","../src/ChatbotHeader/ChatbotHeaderTitle.test.tsx","../src/ChatbotHeader/ChatbotHeaderTitle.tsx","../src/ChatbotHeader/index.ts","../src/ChatbotModal/ChatbotModal.tsx","../src/ChatbotModal/index.ts","../src/ChatbotPopover/ChatbotPopover.tsx","../src/ChatbotPopover/index.ts","../src/ChatbotToggle/ChatbotToggle.test.tsx","../src/ChatbotToggle/ChatbotToggle.tsx","../src/ChatbotToggle/index.ts","../src/ChatbotWelcomePrompt/ChatbotWelcomePrompt.test.tsx","../src/ChatbotWelcomePrompt/ChatbotWelcomePrompt.tsx","../src/ChatbotWelcomePrompt/index.ts","../src/CodeModal/CodeModal.tsx","../src/CodeModal/index.ts","../src/Compare/Compare.test.tsx","../src/Compare/Compare.tsx","../src/Compare/index.ts","../src/FileDetails/FileDetails.test.tsx","../src/FileDetails/FileDetails.tsx","../src/FileDetails/index.ts","../src/FileDetailsLabel/FileDetailsLabel.test.tsx","../src/FileDetailsLabel/FileDetailsLabel.tsx","../src/FileDetailsLabel/index.ts","../src/FileDropZone/FileDropZone.test.tsx","../src/FileDropZone/FileDropZone.tsx","../src/FileDropZone/index.ts","../src/LoadingMessage/LoadingMessage.test.tsx","../src/LoadingMessage/LoadingMessage.tsx","../src/LoadingMessage/index.ts","../src/Message/Message.test.tsx","../src/Message/Message.tsx","../src/Message/MessageLoading.tsx","../src/Message/index.ts","../src/Message/CodeBlockMessage/CodeBlockMessage.tsx","../src/Message/ListMessage/ListItemMessage.tsx","../src/Message/ListMessage/OrderedListMessage.tsx","../src/Message/ListMessage/UnorderedListMessage.tsx","../src/Message/QuickResponse/QuickResponse.tsx","../src/Message/QuickStarts/FallbackImg.tsx","../src/Message/QuickStarts/QuickStartTile.tsx","../src/Message/QuickStarts/QuickStartTileDescription.test.tsx","../src/Message/QuickStarts/QuickStartTileDescription.tsx","../src/Message/QuickStarts/QuickStartTileHeader.tsx","../src/Message/QuickStarts/monitor-sampleapp-quickstart-with-image.ts","../src/Message/QuickStarts/monitor-sampleapp-quickstart.ts","../src/Message/QuickStarts/types.ts","../src/Message/TextMessage/TextMessage.tsx","../src/Message/UserFeedback/CloseButton.tsx","../src/Message/UserFeedback/UserFeedback.test.tsx","../src/Message/UserFeedback/UserFeedback.tsx","../src/Message/UserFeedback/UserFeedbackComplete.test.tsx","../src/Message/UserFeedback/UserFeedbackComplete.tsx","../src/MessageBar/AttachButton.test.tsx","../src/MessageBar/AttachButton.tsx","../src/MessageBar/MessageBar.test.tsx","../src/MessageBar/MessageBar.tsx","../src/MessageBar/MicrophoneButton.tsx","../src/MessageBar/SendButton.test.tsx","../src/MessageBar/SendButton.tsx","../src/MessageBar/StopButton.test.tsx","../src/MessageBar/StopButton.tsx","../src/MessageBar/index.ts","../src/MessageBox/JumpButton.test.tsx","../src/MessageBox/JumpButton.tsx","../src/MessageBox/MessageBox.test.tsx","../src/MessageBox/MessageBox.tsx","../src/MessageBox/index.ts","../src/PreviewAttachment/PreviewAttachment.test.tsx","../src/PreviewAttachment/PreviewAttachment.tsx","../src/PreviewAttachment/index.ts","../src/ResponseActions/ResponseActionButton.test.tsx","../src/ResponseActions/ResponseActionButton.tsx","../src/ResponseActions/ResponseActions.test.tsx","../src/ResponseActions/ResponseActions.tsx","../src/ResponseActions/index.ts","../src/Settings/SettingsForm.test.tsx","../src/Settings/SettingsForm.tsx","../src/Settings/index.ts","../src/SourceDetailsMenuItem/SourceDetailsMenuItem.tsx","../src/SourceDetailsMenuItem/index.ts","../src/SourcesCard/SourcesCard.test.tsx","../src/SourcesCard/SourcesCard.tsx","../src/SourcesCard/index.ts","../src/TermsOfUse/TermsOfUse.test.tsx","../src/TermsOfUse/TermsOfUse.tsx","../src/TermsOfUse/index.ts"],"version":"5.6.3"}
1
+ {"root":["../src/index.ts","../src/AttachMenu/AttachMenu.tsx","../src/AttachMenu/index.ts","../src/AttachmentEdit/AttachmentEdit.test.tsx","../src/AttachmentEdit/AttachmentEdit.tsx","../src/AttachmentEdit/index.ts","../src/Chatbot/Chatbot.test.tsx","../src/Chatbot/Chatbot.tsx","../src/Chatbot/index.ts","../src/ChatbotAlert/ChatbotAlert.test.tsx","../src/ChatbotAlert/ChatbotAlert.tsx","../src/ChatbotAlert/index.ts","../src/ChatbotContent/ChatbotContent.test.tsx","../src/ChatbotContent/ChatbotContent.tsx","../src/ChatbotContent/index.ts","../src/ChatbotConversationHistoryNav/ChatbotConversationHistoryDropdown.test.tsx","../src/ChatbotConversationHistoryNav/ChatbotConversationHistoryDropdown.tsx","../src/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.test.tsx","../src/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.tsx","../src/ChatbotConversationHistoryNav/index.ts","../src/ChatbotFooter/ChatbotFooter.test.tsx","../src/ChatbotFooter/ChatbotFooter.tsx","../src/ChatbotFooter/ChatbotFooternote.test.tsx","../src/ChatbotFooter/ChatbotFootnote.tsx","../src/ChatbotFooter/index.ts","../src/ChatbotHeader/ChatbotHeader.test.tsx","../src/ChatbotHeader/ChatbotHeader.tsx","../src/ChatbotHeader/ChatbotHeaderActions.test.tsx","../src/ChatbotHeader/ChatbotHeaderActions.tsx","../src/ChatbotHeader/ChatbotHeaderCloseButton.test.tsx","../src/ChatbotHeader/ChatbotHeaderCloseButton.tsx","../src/ChatbotHeader/ChatbotHeaderMain.test.tsx","../src/ChatbotHeader/ChatbotHeaderMain.tsx","../src/ChatbotHeader/ChatbotHeaderMenu.test.tsx","../src/ChatbotHeader/ChatbotHeaderMenu.tsx","../src/ChatbotHeader/ChatbotHeaderOptionsDropdown.test.tsx","../src/ChatbotHeader/ChatbotHeaderOptionsDropdown.tsx","../src/ChatbotHeader/ChatbotHeaderSelectorDropdown.test.tsx","../src/ChatbotHeader/ChatbotHeaderSelectorDropdown.tsx","../src/ChatbotHeader/ChatbotHeaderTitle.test.tsx","../src/ChatbotHeader/ChatbotHeaderTitle.tsx","../src/ChatbotHeader/index.ts","../src/ChatbotModal/ChatbotModal.tsx","../src/ChatbotModal/index.ts","../src/ChatbotPopover/ChatbotPopover.tsx","../src/ChatbotPopover/index.ts","../src/ChatbotToggle/ChatbotToggle.test.tsx","../src/ChatbotToggle/ChatbotToggle.tsx","../src/ChatbotToggle/index.ts","../src/ChatbotWelcomePrompt/ChatbotWelcomePrompt.test.tsx","../src/ChatbotWelcomePrompt/ChatbotWelcomePrompt.tsx","../src/ChatbotWelcomePrompt/index.ts","../src/CodeModal/CodeModal.tsx","../src/CodeModal/index.ts","../src/Compare/Compare.test.tsx","../src/Compare/Compare.tsx","../src/Compare/index.ts","../src/FileDetails/FileDetails.test.tsx","../src/FileDetails/FileDetails.tsx","../src/FileDetails/index.ts","../src/FileDetailsLabel/FileDetailsLabel.test.tsx","../src/FileDetailsLabel/FileDetailsLabel.tsx","../src/FileDetailsLabel/index.ts","../src/FileDropZone/FileDropZone.test.tsx","../src/FileDropZone/FileDropZone.tsx","../src/FileDropZone/index.ts","../src/LoadingMessage/LoadingMessage.test.tsx","../src/LoadingMessage/LoadingMessage.tsx","../src/LoadingMessage/index.ts","../src/Message/Message.test.tsx","../src/Message/Message.tsx","../src/Message/MessageLoading.tsx","../src/Message/index.ts","../src/Message/CodeBlockMessage/CodeBlockMessage.tsx","../src/Message/ListMessage/ListItemMessage.tsx","../src/Message/ListMessage/OrderedListMessage.tsx","../src/Message/ListMessage/UnorderedListMessage.tsx","../src/Message/QuickResponse/QuickResponse.tsx","../src/Message/QuickStarts/FallbackImg.tsx","../src/Message/QuickStarts/QuickStartTile.tsx","../src/Message/QuickStarts/QuickStartTileDescription.test.tsx","../src/Message/QuickStarts/QuickStartTileDescription.tsx","../src/Message/QuickStarts/QuickStartTileHeader.tsx","../src/Message/QuickStarts/monitor-sampleapp-quickstart-with-image.ts","../src/Message/QuickStarts/monitor-sampleapp-quickstart.ts","../src/Message/QuickStarts/types.ts","../src/Message/TableMessage/TableMessage.tsx","../src/Message/TableMessage/TbodyMessage.tsx","../src/Message/TableMessage/TdMessage.tsx","../src/Message/TableMessage/ThMessage.tsx","../src/Message/TableMessage/TheadMessage.tsx","../src/Message/TableMessage/TrMessage.tsx","../src/Message/TextMessage/TextMessage.tsx","../src/Message/UserFeedback/CloseButton.tsx","../src/Message/UserFeedback/UserFeedback.test.tsx","../src/Message/UserFeedback/UserFeedback.tsx","../src/Message/UserFeedback/UserFeedbackComplete.test.tsx","../src/Message/UserFeedback/UserFeedbackComplete.tsx","../src/MessageBar/AttachButton.test.tsx","../src/MessageBar/AttachButton.tsx","../src/MessageBar/MessageBar.test.tsx","../src/MessageBar/MessageBar.tsx","../src/MessageBar/MicrophoneButton.tsx","../src/MessageBar/SendButton.test.tsx","../src/MessageBar/SendButton.tsx","../src/MessageBar/StopButton.test.tsx","../src/MessageBar/StopButton.tsx","../src/MessageBar/index.ts","../src/MessageBox/JumpButton.test.tsx","../src/MessageBox/JumpButton.tsx","../src/MessageBox/MessageBox.test.tsx","../src/MessageBox/MessageBox.tsx","../src/MessageBox/index.ts","../src/PreviewAttachment/PreviewAttachment.test.tsx","../src/PreviewAttachment/PreviewAttachment.tsx","../src/PreviewAttachment/index.ts","../src/ResponseActions/ResponseActionButton.test.tsx","../src/ResponseActions/ResponseActionButton.tsx","../src/ResponseActions/ResponseActions.test.tsx","../src/ResponseActions/ResponseActions.tsx","../src/ResponseActions/index.ts","../src/Settings/SettingsForm.test.tsx","../src/Settings/SettingsForm.tsx","../src/Settings/index.ts","../src/SourceDetailsMenuItem/SourceDetailsMenuItem.tsx","../src/SourceDetailsMenuItem/index.ts","../src/SourcesCard/SourcesCard.test.tsx","../src/SourcesCard/SourcesCard.tsx","../src/SourcesCard/index.ts","../src/TermsOfUse/TermsOfUse.test.tsx","../src/TermsOfUse/TermsOfUse.tsx","../src/TermsOfUse/index.ts"],"version":"5.6.3"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@patternfly/chatbot",
3
- "version": "2.2.0-prerelease.20",
3
+ "version": "2.2.0-prerelease.21",
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",
@@ -28,6 +28,8 @@ export const BotMessageExample: React.FunctionComponent = () => {
28
28
  return inlineCode;
29
29
  case 'link':
30
30
  return link;
31
+ case 'table':
32
+ return table;
31
33
  default:
32
34
  return;
33
35
  }
@@ -125,6 +127,15 @@ _Italic text, formatted with single underscores_
125
127
 
126
128
  const inlineCode = `Here is an inline code - \`() => void\``;
127
129
 
130
+ const table = `To customize your table, you can use [PatternFly TableProps](/components/table#table)
131
+
132
+ | Version | GA date | User role
133
+ |-|-|-|
134
+ | 2.5 | September 30, 2024 | Administrator |
135
+ | 2.5 | June 27, 2023 | Editor |
136
+ | 3.0 | April 1, 2025 | Administrator
137
+ `;
138
+
128
139
  return (
129
140
  <>
130
141
  <Message name="Bot" role="bot" avatar={patternflyAvatar} content={`Text-based message from a bot named "Bot"`} />
@@ -216,9 +227,24 @@ _Italic text, formatted with single underscores_
216
227
  label="More complex list"
217
228
  id="more-complex-list"
218
229
  />
230
+ <Radio
231
+ isChecked={variant === 'table'}
232
+ onChange={() => setVariant('table')}
233
+ name="bot-message-type"
234
+ label="Table"
235
+ id="table"
236
+ />
219
237
  </FormGroup>
220
238
  </Form>
221
- <Message name="Bot" role="bot" avatar={patternflyAvatar} content={renderContent()} />
239
+ <Message
240
+ name="Bot"
241
+ role="bot"
242
+ avatar={patternflyAvatar}
243
+ content={renderContent()}
244
+ tableProps={
245
+ variant === 'table' ? { 'aria-label': 'App information and user roles for bot messages' } : undefined
246
+ }
247
+ />
222
248
  </>
223
249
  );
224
250
  };
@@ -28,6 +28,8 @@ export const UserMessageExample: React.FunctionComponent = () => {
28
28
  return moreComplexList;
29
29
  case 'link':
30
30
  return link;
31
+ case 'table':
32
+ return table;
31
33
  default:
32
34
  return;
33
35
  }
@@ -125,6 +127,15 @@ _Italic text, formatted with single underscores_
125
127
 
126
128
  const inlineCode = `Here is an inline code - \`() => void\``;
127
129
 
130
+ const table = `To customize your table, you can use [PatternFly TableProps](/components/table#table)
131
+
132
+ | Version | GA date | User role
133
+ |-|-|-|
134
+ | 2.5 | September 30, 2024 | Administrator |
135
+ | 2.5 | June 27, 2023 | Editor |
136
+ | 3.0 | April 1, 2025 | Administrator
137
+ `;
138
+
128
139
  return (
129
140
  <>
130
141
  <Message
@@ -206,9 +217,24 @@ _Italic text, formatted with single underscores_
206
217
  label="More complex list"
207
218
  id="user-more-complex-list"
208
219
  />
220
+ <Radio
221
+ isChecked={variant === 'table'}
222
+ onChange={() => setVariant('table')}
223
+ name="user-message-type"
224
+ label="Table"
225
+ id="user-table"
226
+ />
209
227
  </FormGroup>
210
228
  </Form>
211
- <Message name="User" role="user" content={renderContent()} avatar={userAvatar} />
229
+ <Message
230
+ name="User"
231
+ role="user"
232
+ content={renderContent()}
233
+ avatar={userAvatar}
234
+ tableProps={
235
+ variant === 'table' ? { 'aria-label': 'App information and user roles for user messages' } : undefined
236
+ }
237
+ />
212
238
  </>
213
239
  );
214
240
  };
@@ -88,6 +88,55 @@ const HEADING = `
88
88
  const BLOCK_QUOTES = `> Blockquotes can also be nested...
89
89
  >> ...by using additional greater-than signs (>) right next to each other...
90
90
  > > > ...or with spaces between each sign.`;
91
+ const TABLE = `
92
+
93
+ | Column 1 | Column 2 |
94
+ |-|-|
95
+ | Cell 1 | Cell 2 |
96
+ | Cell 3 | Cell 4 |
97
+
98
+ `;
99
+
100
+ const ONE_COLUMN_TABLE = `
101
+
102
+ | Column 1 |
103
+ |-|
104
+ | Cell 1 |
105
+ | Cell 2 |
106
+
107
+ `;
108
+
109
+ const ONE_CELL_TABLE = `
110
+
111
+ | Column 1 |
112
+ |-|
113
+ | Cell 1 |
114
+
115
+ `;
116
+
117
+ const HEADERLESS_TABLE = `
118
+
119
+ | |
120
+ |-|
121
+ | Cell 1 |
122
+
123
+ `;
124
+
125
+ const CHILDLESS_TABLE = `
126
+
127
+ | Column 1 |
128
+ |-|
129
+ | |
130
+
131
+ `;
132
+
133
+ const EMPTY_TABLE = `
134
+
135
+ | |
136
+ |-|
137
+ | |
138
+
139
+ `;
91
140
 
92
141
  const checkListItemsRendered = () => {
93
142
  const items = ['Item 1', 'Item 2', 'Item 3'];
@@ -528,4 +577,54 @@ describe('Message', () => {
528
577
  expect(screen.getByRole('heading', { name: /h5 Heading/i })).toBeTruthy();
529
578
  expect(screen.getByRole('heading', { name: /h6 Heading/i })).toBeTruthy();
530
579
  });
580
+ it('should render table correctly', () => {
581
+ render(<Message avatar="./img" role="user" name="User" content={TABLE} />);
582
+ expect(screen.getByRole('row', { name: /Column 1 Column 2/i })).toBeTruthy();
583
+ expect(screen.getByRole('row', { name: /Cell 1 Cell 2/i })).toBeTruthy();
584
+ expect(screen.getByRole('row', { name: /Cell 3 Cell 4/i })).toBeTruthy();
585
+ expect(screen.getByRole('columnheader', { name: /Column 1/i })).toBeTruthy();
586
+ expect(screen.getByRole('columnheader', { name: /Column 2/i })).toBeTruthy();
587
+ expect(screen.getByRole('cell', { name: /Cell 1/i })).toBeTruthy();
588
+ expect(screen.getByRole('cell', { name: /Cell 2/i })).toBeTruthy();
589
+ expect(screen.getByRole('cell', { name: /Cell 3/i })).toBeTruthy();
590
+ expect(screen.getByRole('cell', { name: /Cell 4/i })).toBeTruthy();
591
+ });
592
+ it('should render table data labels correctly for mobile breakpoint', () => {
593
+ render(<Message avatar="./img" role="user" name="User" content={TABLE} />);
594
+ expect(screen.getByRole('row', { name: /Cell 1 Cell 2/i })).toHaveAttribute('extraHeaders', 'Column 1,Column 2');
595
+ expect(screen.getByRole('row', { name: /Cell 3 Cell 4/i })).toHaveAttribute('extraHeaders', 'Column 1,Column 2');
596
+ expect(screen.getByRole('cell', { name: /Cell 1/i })).toHaveAttribute('data-label', 'Column 1');
597
+ expect(screen.getByRole('cell', { name: /Cell 2/i })).toHaveAttribute('data-label', 'Column 2');
598
+ expect(screen.getByRole('cell', { name: /Cell 3/i })).toHaveAttribute('data-label', 'Column 1');
599
+ expect(screen.getByRole('cell', { name: /Cell 4/i })).toHaveAttribute('data-label', 'Column 2');
600
+ });
601
+ it('should render table data labels correctly for mobile breakpoint for one column table', () => {
602
+ render(<Message avatar="./img" role="user" name="User" content={ONE_COLUMN_TABLE} />);
603
+ expect(screen.getByRole('row', { name: /Cell 1/i })).toHaveAttribute('extraHeaders', 'Column 1');
604
+ expect(screen.getByRole('row', { name: /Cell 2/i })).toHaveAttribute('extraHeaders', 'Column 1');
605
+ expect(screen.getByRole('cell', { name: /Cell 1/i })).toHaveAttribute('data-label', 'Column 1');
606
+ expect(screen.getByRole('cell', { name: /Cell 2/i })).toHaveAttribute('data-label', 'Column 1');
607
+ });
608
+ it('should render table data labels correctly for mobile breakpoint for one cell table', () => {
609
+ render(<Message avatar="./img" role="user" name="User" content={ONE_CELL_TABLE} />);
610
+ expect(screen.getByRole('row', { name: /Cell 1/i })).toHaveAttribute('extraHeaders', 'Column 1');
611
+ expect(screen.getByRole('cell', { name: /Cell 1/i })).toHaveAttribute('data-label', 'Column 1');
612
+ });
613
+ it('should render table data labels correctly for mobile breakpoint for headerless', () => {
614
+ render(<Message avatar="./img" role="user" name="User" content={HEADERLESS_TABLE} />);
615
+ expect(screen.getByRole('row', { name: /Cell 1/i })).toHaveAttribute('extraHeaders', '');
616
+ expect(screen.getByRole('cell', { name: /Cell 1/i })).not.toHaveAttribute('data-label');
617
+ });
618
+ it('should render table data labels correctly for mobile breakpoint for childless', () => {
619
+ render(<Message avatar="./img" role="user" name="User" content={CHILDLESS_TABLE} />);
620
+ expect(screen.getByRole('cell')).not.toHaveAttribute('extraHeaders', 'Column 1');
621
+ });
622
+ it('should render table data labels correctly for mobile breakpoint for empty', () => {
623
+ render(<Message avatar="./img" role="user" name="User" content={EMPTY_TABLE} />);
624
+ expect(screen.getByRole('cell')).not.toHaveAttribute('extraHeaders', '');
625
+ });
626
+ it('should render custom table aria label correctly', () => {
627
+ render(<Message avatar="./img" role="user" name="User" content={TABLE} tableProps={{ 'aria-label': 'Test' }} />);
628
+ expect(screen.getByRole('grid', { name: /Test/i })).toBeTruthy();
629
+ });
531
630
  });