@patternfly/chatbot 6.7.0-prerelease.1 → 6.7.0-prerelease.2

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 (19) hide show
  1. package/dist/cjs/ChatbotFooter/ChatbotFootnote.d.ts +4 -0
  2. package/dist/cjs/ChatbotFooter/ChatbotFootnote.js +5 -7
  3. package/dist/esm/ChatbotFooter/ChatbotFootnote.d.ts +4 -0
  4. package/dist/esm/ChatbotFooter/ChatbotFootnote.js +5 -7
  5. package/package.json +1 -1
  6. package/patternfly-docs/content/extensions/chatbot/examples/UI/ChatbotFooter.tsx +1 -1
  7. package/patternfly-docs/content/extensions/chatbot/examples/UI/ChatbotFootnote.tsx +26 -20
  8. package/patternfly-docs/content/extensions/chatbot/examples/UI/UI.md +4 -3
  9. package/patternfly-docs/content/extensions/chatbot/examples/demos/Chatbot.tsx +1 -19
  10. package/patternfly-docs/content/extensions/chatbot/examples/demos/ChatbotAttachment.tsx +1 -1
  11. package/patternfly-docs/content/extensions/chatbot/examples/demos/ChatbotAttachmentMenu.tsx +1 -1
  12. package/patternfly-docs/content/extensions/chatbot/examples/demos/ChatbotCompact.tsx +1 -19
  13. package/patternfly-docs/content/extensions/chatbot/examples/demos/ChatbotDisplayMode.tsx +1 -19
  14. package/patternfly-docs/content/extensions/chatbot/examples/demos/ChatbotInDrawer.tsx +1 -19
  15. package/patternfly-docs/content/extensions/chatbot/examples/demos/ChatbotScrolling.tsx +1 -19
  16. package/patternfly-docs/content/extensions/chatbot/examples/demos/ChatbotTranscripts.tsx +1 -19
  17. package/patternfly-docs/content/extensions/chatbot/examples/demos/EmbeddedChatbot.tsx +1 -19
  18. package/patternfly-docs/content/extensions/chatbot/examples/demos/WhiteEmbeddedChatbot.tsx +1 -19
  19. package/src/ChatbotFooter/ChatbotFootnote.tsx +14 -12
@@ -21,6 +21,10 @@ export interface ChatbotFootnotePopover {
21
21
  link?: ChatbotFootnotePopoverLink;
22
22
  /** Props for PF Popover */
23
23
  popoverProps?: PopoverProps;
24
+ /** Flag indicating whether the popover close button is rendered. Either this or a cta that closes the popover
25
+ * must be present.
26
+ */
27
+ showClose?: boolean;
24
28
  }
25
29
  export interface ChatbotFootnotePopoverCTA {
26
30
  /** Label for the CTA */
@@ -17,19 +17,17 @@ Object.defineProperty(exports, "__esModule", { value: true });
17
17
  exports.ChatbotFootnote = void 0;
18
18
  const jsx_runtime_1 = require("react/jsx-runtime");
19
19
  const react_1 = require("react");
20
- // Import Patternfly components
21
20
  const react_core_1 = require("@patternfly/react-core");
22
- // Import Patternfly icons
23
- const info_circle_icon_1 = require("@patternfly/react-icons/dist/esm/icons/info-circle-icon");
24
21
  const external_link_alt_icon_1 = require("@patternfly/react-icons/dist/esm/icons/external-link-alt-icon");
25
- // Import Chatbot components
26
22
  const ChatbotPopover_1 = __importDefault(require("../ChatbotPopover/ChatbotPopover"));
27
23
  const ChatbotFootnote = (_a) => {
28
24
  var _b, _c, _d, _e, _f;
29
25
  var { label, popover, className } = _a, props = __rest(_a, ["label", "popover", "className"]);
30
- // Popover visibility state
26
+ if (!(popover === null || popover === void 0 ? void 0 : popover.cta) && !(popover === null || popover === void 0 ? void 0 : popover.showClose)) {
27
+ // eslint-disable-next-line no-console
28
+ console.error('ChatbotFootnote: You must provide either the popover.cta or popover.showClose props in order to render a button that can close the popover.');
29
+ }
31
30
  const [isVisible, setIsVisible] = (0, react_1.useState)(false);
32
- // Define popover body content
33
31
  const popoverBodyContent = ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(popover === null || popover === void 0 ? void 0 : popover.bannerImage) && (0, jsx_runtime_1.jsx)("img", { src: popover.bannerImage.src, alt: popover.bannerImage.alt }), (0, jsx_runtime_1.jsx)(react_core_1.Content, { component: react_core_1.ContentVariants.h3, children: popover === null || popover === void 0 ? void 0 : popover.title }), (0, jsx_runtime_1.jsx)(react_core_1.Content, { component: react_core_1.ContentVariants.p, children: popover === null || popover === void 0 ? void 0 : popover.description })] }));
34
32
  // Define popover footer content
35
33
  const popoverFooterContent = ((0, jsx_runtime_1.jsxs)(react_core_1.Flex, { gap: { default: 'gapSm' }, children: [(popover === null || popover === void 0 ? void 0 : popover.cta) && ((0, jsx_runtime_1.jsx)(react_core_1.Button, { variant: "secondary", onClick: () => {
@@ -37,7 +35,7 @@ const ChatbotFootnote = (_a) => {
37
35
  setIsVisible(false);
38
36
  (_a = popover.cta) === null || _a === void 0 ? void 0 : _a.onClick();
39
37
  }, children: ((_b = popover.cta) === null || _b === void 0 ? void 0 : _b.label) || 'Dismiss' })), (popover === null || popover === void 0 ? void 0 : popover.link) && ((0, jsx_runtime_1.jsx)(react_core_1.Button, { variant: "link", component: "a", href: popover.link.url, target: "_blank", icon: (0, jsx_runtime_1.jsx)(external_link_alt_icon_1.ExternalLinkAltIcon, {}), iconPosition: "end", children: popover.link.label }))] }));
40
- return ((0, jsx_runtime_1.jsxs)("div", Object.assign({ className: `pf-chatbot__footnote ${className !== null && className !== void 0 ? className : ''}` }, props, { children: [popover && ((0, jsx_runtime_1.jsx)(ChatbotPopover_1.default, Object.assign({ className: "pf-chatbot__popover--footnote", "aria-label": ((_c = popover.popoverProps) === null || _c === void 0 ? void 0 : _c['aria-label']) || 'More information', isVisible: isVisible, shouldOpen: (_event, _fn) => setIsVisible(true), shouldClose: (_event, _fn) => setIsVisible(false), bodyContent: popoverBodyContent, footerContent: popoverFooterContent, minWidth: ((_d = popover.popoverProps) === null || _d === void 0 ? void 0 : _d.minWidth) || '432', maxWidth: ((_e = popover.popoverProps) === null || _e === void 0 ? void 0 : _e.maxWidth) || '432', distance: ((_f = popover.popoverProps) === null || _f === void 0 ? void 0 : _f.distance) || 16, showClose: false }, popover.popoverProps, { children: (0, jsx_runtime_1.jsxs)(react_core_1.Button, { variant: "link", size: "sm", children: [label, " ", (0, jsx_runtime_1.jsx)(info_circle_icon_1.InfoCircleIcon, {})] }) }))), !popover && (0, jsx_runtime_1.jsx)(react_core_1.Content, { component: react_core_1.ContentVariants.small, children: label })] })));
38
+ return ((0, jsx_runtime_1.jsxs)("div", Object.assign({ className: `pf-chatbot__footnote ${className !== null && className !== void 0 ? className : ''}` }, props, { children: [popover && ((0, jsx_runtime_1.jsx)(ChatbotPopover_1.default, Object.assign({ className: "pf-chatbot__popover--footnote", "aria-label": ((_c = popover.popoverProps) === null || _c === void 0 ? void 0 : _c['aria-label']) || 'More information', isVisible: isVisible, shouldOpen: (_event, _fn) => setIsVisible(true), shouldClose: (_event, _fn) => setIsVisible(false), bodyContent: popoverBodyContent, footerContent: popoverFooterContent, minWidth: ((_d = popover.popoverProps) === null || _d === void 0 ? void 0 : _d.minWidth) || '432', maxWidth: ((_e = popover.popoverProps) === null || _e === void 0 ? void 0 : _e.maxWidth) || '432', distance: ((_f = popover.popoverProps) === null || _f === void 0 ? void 0 : _f.distance) || 16, showClose: (popover === null || popover === void 0 ? void 0 : popover.showClose) || false }, popover.popoverProps, { children: (0, jsx_runtime_1.jsx)(react_core_1.Button, { "aria-haspopup": "dialog", isExpanded: isVisible, variant: "link", size: "sm", children: label }) }))), !popover && (0, jsx_runtime_1.jsx)(react_core_1.Content, { component: react_core_1.ContentVariants.small, children: label })] })));
41
39
  };
42
40
  exports.ChatbotFootnote = ChatbotFootnote;
43
41
  exports.default = exports.ChatbotFootnote;
@@ -21,6 +21,10 @@ export interface ChatbotFootnotePopover {
21
21
  link?: ChatbotFootnotePopoverLink;
22
22
  /** Props for PF Popover */
23
23
  popoverProps?: PopoverProps;
24
+ /** Flag indicating whether the popover close button is rendered. Either this or a cta that closes the popover
25
+ * must be present.
26
+ */
27
+ showClose?: boolean;
24
28
  }
25
29
  export interface ChatbotFootnotePopoverCTA {
26
30
  /** Label for the CTA */
@@ -11,19 +11,17 @@ var __rest = (this && this.__rest) || function (s, e) {
11
11
  };
12
12
  import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
13
13
  import { useState } from 'react';
14
- // Import Patternfly components
15
14
  import { Button, Content, ContentVariants, Flex } from '@patternfly/react-core';
16
- // Import Patternfly icons
17
- import { InfoCircleIcon } from '@patternfly/react-icons/dist/esm/icons/info-circle-icon';
18
15
  import { ExternalLinkAltIcon } from '@patternfly/react-icons/dist/esm/icons/external-link-alt-icon';
19
- // Import Chatbot components
20
16
  import ChatbotPopover from '../ChatbotPopover/ChatbotPopover';
21
17
  export const ChatbotFootnote = (_a) => {
22
18
  var _b, _c, _d, _e, _f;
23
19
  var { label, popover, className } = _a, props = __rest(_a, ["label", "popover", "className"]);
24
- // Popover visibility state
20
+ if (!(popover === null || popover === void 0 ? void 0 : popover.cta) && !(popover === null || popover === void 0 ? void 0 : popover.showClose)) {
21
+ // eslint-disable-next-line no-console
22
+ console.error('ChatbotFootnote: You must provide either the popover.cta or popover.showClose props in order to render a button that can close the popover.');
23
+ }
25
24
  const [isVisible, setIsVisible] = useState(false);
26
- // Define popover body content
27
25
  const popoverBodyContent = (_jsxs(_Fragment, { children: [(popover === null || popover === void 0 ? void 0 : popover.bannerImage) && _jsx("img", { src: popover.bannerImage.src, alt: popover.bannerImage.alt }), _jsx(Content, { component: ContentVariants.h3, children: popover === null || popover === void 0 ? void 0 : popover.title }), _jsx(Content, { component: ContentVariants.p, children: popover === null || popover === void 0 ? void 0 : popover.description })] }));
28
26
  // Define popover footer content
29
27
  const popoverFooterContent = (_jsxs(Flex, { gap: { default: 'gapSm' }, children: [(popover === null || popover === void 0 ? void 0 : popover.cta) && (_jsx(Button, { variant: "secondary", onClick: () => {
@@ -31,6 +29,6 @@ export const ChatbotFootnote = (_a) => {
31
29
  setIsVisible(false);
32
30
  (_a = popover.cta) === null || _a === void 0 ? void 0 : _a.onClick();
33
31
  }, children: ((_b = popover.cta) === null || _b === void 0 ? void 0 : _b.label) || 'Dismiss' })), (popover === null || popover === void 0 ? void 0 : popover.link) && (_jsx(Button, { variant: "link", component: "a", href: popover.link.url, target: "_blank", icon: _jsx(ExternalLinkAltIcon, {}), iconPosition: "end", children: popover.link.label }))] }));
34
- return (_jsxs("div", Object.assign({ className: `pf-chatbot__footnote ${className !== null && className !== void 0 ? className : ''}` }, props, { children: [popover && (_jsx(ChatbotPopover, Object.assign({ className: "pf-chatbot__popover--footnote", "aria-label": ((_c = popover.popoverProps) === null || _c === void 0 ? void 0 : _c['aria-label']) || 'More information', isVisible: isVisible, shouldOpen: (_event, _fn) => setIsVisible(true), shouldClose: (_event, _fn) => setIsVisible(false), bodyContent: popoverBodyContent, footerContent: popoverFooterContent, minWidth: ((_d = popover.popoverProps) === null || _d === void 0 ? void 0 : _d.minWidth) || '432', maxWidth: ((_e = popover.popoverProps) === null || _e === void 0 ? void 0 : _e.maxWidth) || '432', distance: ((_f = popover.popoverProps) === null || _f === void 0 ? void 0 : _f.distance) || 16, showClose: false }, popover.popoverProps, { children: _jsxs(Button, { variant: "link", size: "sm", children: [label, " ", _jsx(InfoCircleIcon, {})] }) }))), !popover && _jsx(Content, { component: ContentVariants.small, children: label })] })));
32
+ return (_jsxs("div", Object.assign({ className: `pf-chatbot__footnote ${className !== null && className !== void 0 ? className : ''}` }, props, { children: [popover && (_jsx(ChatbotPopover, Object.assign({ className: "pf-chatbot__popover--footnote", "aria-label": ((_c = popover.popoverProps) === null || _c === void 0 ? void 0 : _c['aria-label']) || 'More information', isVisible: isVisible, shouldOpen: (_event, _fn) => setIsVisible(true), shouldClose: (_event, _fn) => setIsVisible(false), bodyContent: popoverBodyContent, footerContent: popoverFooterContent, minWidth: ((_d = popover.popoverProps) === null || _d === void 0 ? void 0 : _d.minWidth) || '432', maxWidth: ((_e = popover.popoverProps) === null || _e === void 0 ? void 0 : _e.maxWidth) || '432', distance: ((_f = popover.popoverProps) === null || _f === void 0 ? void 0 : _f.distance) || 16, showClose: (popover === null || popover === void 0 ? void 0 : popover.showClose) || false }, popover.popoverProps, { children: _jsx(Button, { "aria-haspopup": "dialog", isExpanded: isVisible, variant: "link", size: "sm", children: label }) }))), !popover && _jsx(Content, { component: ContentVariants.small, children: label })] })));
35
33
  };
36
34
  export default ChatbotFootnote;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@patternfly/chatbot",
3
- "version": "6.7.0-prerelease.1",
3
+ "version": "6.7.0-prerelease.2",
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",
@@ -8,7 +8,7 @@ export const ChatbotFooterExample: FunctionComponent = () => {
8
8
  return (
9
9
  <ChatbotFooter>
10
10
  <MessageBar onSendMessage={handleSend} hasMicrophoneButton hasAttachButton />
11
- <ChatbotFootnote label="ChatBot uses AI. Check for mistakes." />
11
+ <ChatbotFootnote label="Always review AI-generated content prior to use." />
12
12
  </ChatbotFooter>
13
13
  );
14
14
  };
@@ -2,25 +2,31 @@ import { FunctionComponent } from 'react';
2
2
  import { ChatbotFootnote } from '@patternfly/chatbot/dist/dynamic/ChatbotFooter';
3
3
 
4
4
  export const FootnoteDemo: FunctionComponent = () => (
5
- <ChatbotFootnote
6
- label="ChatBot uses AI. Check for mistakes."
7
- popover={{
8
- title: 'Verify information',
9
- description: `While ChatBot strives for accuracy, AI is experimental and can make mistakes. We cannot guarantee that all information provided by ChatBot is up to date or without error. You should always verify responses using reliable sources, especially for crucial information and decision making.`,
10
- bannerImage: {
11
- src: 'https://cdn.dribbble.com/userupload/10651749/file/original-8a07b8e39d9e8bf002358c66fce1223e.gif',
12
- alt: 'Example image for footnote popover'
13
- },
14
- cta: {
15
- label: 'Dismiss',
16
- onClick: () => {
17
- alert('Do something!');
5
+ <>
6
+ <h4>Static text</h4>
7
+ <ChatbotFootnote label="Always review AI-generated content prior to use." />
8
+ <br />
9
+ <h4>With popover</h4>
10
+ <ChatbotFootnote
11
+ label="Always review AI-generated content prior to use."
12
+ popover={{
13
+ title: 'Verify information',
14
+ description: `While ChatBot strives for accuracy, AI is experimental and can make mistakes. We cannot guarantee that all information provided by ChatBot is up to date or without error. You should always verify responses using reliable sources, especially for crucial information and decision making.`,
15
+ bannerImage: {
16
+ src: 'https://cdn.dribbble.com/userupload/10651749/file/original-8a07b8e39d9e8bf002358c66fce1223e.gif',
17
+ alt: 'Example image for footnote popover'
18
+ },
19
+ cta: {
20
+ label: 'Dismiss',
21
+ onClick: () => {
22
+ alert('Do something!');
23
+ }
24
+ },
25
+ link: {
26
+ label: 'View AI policy',
27
+ url: 'https://www.redhat.com/'
18
28
  }
19
- },
20
- link: {
21
- label: 'View AI policy',
22
- url: 'https://www.redhat.com/'
23
- }
24
- }}
25
- />
29
+ }}
30
+ />
31
+ </>
26
32
  );
@@ -240,10 +240,11 @@ In this example, select the respective checkbox to toggle these features:
240
240
 
241
241
  ## Footer
242
242
 
243
- ### Footnote with popover
243
+ ### Footnote
244
244
 
245
- A footnote can be placed in the ChatBot footer to communicate any legal disclaimers or information about the ChatBot.
246
- Footnotes can be static text or a button that opens a popover.
245
+ A `<ChatbotFootnote>` can be placed in the ChatBot footer to communicate any legal disclaimers or information about the ChatBot.
246
+
247
+ To create a static text footnote, pass the `label` property. To create a footnote button that triggers a popover, pass in both the `label` and `popover` properties.
247
248
 
248
249
  ```js file="./ChatbotFootnote.tsx"
249
250
 
@@ -37,25 +37,7 @@ import '@patternfly/react-core/dist/styles/base.css';
37
37
  import '@patternfly/chatbot/dist/css/main.css';
38
38
 
39
39
  const footnoteProps = {
40
- label: 'ChatBot uses AI. Check for mistakes.',
41
- popover: {
42
- title: 'Verify information',
43
- description: `While ChatBot strives for accuracy, AI is experimental and can make mistakes. We cannot guarantee that all information provided by ChatBot is up to date or without error. You should always verify responses using reliable sources, especially for crucial information and decision making.`,
44
- bannerImage: {
45
- src: 'https://cdn.dribbble.com/userupload/10651749/file/original-8a07b8e39d9e8bf002358c66fce1223e.gif',
46
- alt: 'Example image for footnote popover'
47
- },
48
- cta: {
49
- label: 'Dismiss',
50
- onClick: () => {
51
- alert('Do something!');
52
- }
53
- },
54
- link: {
55
- label: 'View AI policy',
56
- url: 'https://www.redhat.com/'
57
- }
58
- }
40
+ label: 'Always review AI-generated content prior to use.'
59
41
  };
60
42
 
61
43
  const markdown = `A paragraph with *emphasis* and **strong importance**.
@@ -273,7 +273,7 @@ export const BasicDemo: FunctionComponent = () => {
273
273
  }}
274
274
  onAttachRejected={handleAttachRejected}
275
275
  />
276
- <ChatbotFootnote label="ChatBot uses AI. Check for mistakes." />
276
+ <ChatbotFootnote label="Always review AI-generated content prior to use." />
277
277
  </ChatbotFooter>
278
278
  </FileDropZone>
279
279
  </Chatbot>
@@ -262,7 +262,7 @@ export const AttachmentMenuDemo: FunctionComponent = () => {
262
262
  onAttachMenuToggleClick: onToggleClick
263
263
  }}
264
264
  />
265
- <ChatbotFootnote label="ChatBot uses AI. Check for mistakes." />
265
+ <ChatbotFootnote label="Always review AI-generated content prior to use." />
266
266
  </ChatbotFooter>
267
267
  </>
268
268
  </FileDropZone>
@@ -33,25 +33,7 @@ import userAvatar from '../Messages/user_avatar.svg';
33
33
  import patternflyAvatar from '../Messages/patternfly_avatar.jpg';
34
34
 
35
35
  const footnoteProps = {
36
- label: 'ChatBot uses AI. Check for mistakes.',
37
- popover: {
38
- title: 'Verify information',
39
- description: `While ChatBot strives for accuracy, AI is experimental and can make mistakes. We cannot guarantee that all information provided by ChatBot is up to date or without error. You should always verify responses using reliable sources, especially for crucial information and decision making.`,
40
- bannerImage: {
41
- src: 'https://cdn.dribbble.com/userupload/10651749/file/original-8a07b8e39d9e8bf002358c66fce1223e.gif',
42
- alt: 'Example image for footnote popover'
43
- },
44
- cta: {
45
- label: 'Dismiss',
46
- onClick: () => {
47
- alert('Do something!');
48
- }
49
- },
50
- link: {
51
- label: 'View AI policy',
52
- url: 'https://www.redhat.com/'
53
- }
54
- }
36
+ label: 'Always review AI-generated content prior to use.'
55
37
  };
56
38
 
57
39
  const markdown = `A paragraph with *emphasis* and **strong importance**.
@@ -53,25 +53,7 @@ import '@patternfly/react-core/dist/styles/base.css';
53
53
  import '@patternfly/chatbot/dist/css/main.css';
54
54
 
55
55
  const footnoteProps = {
56
- label: 'ChatBot uses AI. Check for mistakes.',
57
- popover: {
58
- title: 'Verify accuracy',
59
- description: `While ChatBot strives for accuracy, there's always a possibility of errors. It's a good practice to verify critical information from reliable sources, especially if it's crucial for decision-making or actions.`,
60
- bannerImage: {
61
- src: 'https://cdn.dribbble.com/userupload/10651749/file/original-8a07b8e39d9e8bf002358c66fce1223e.gif',
62
- alt: 'Example image for footnote popover'
63
- },
64
- cta: {
65
- label: 'Got it',
66
- onClick: () => {
67
- alert('Do something!');
68
- }
69
- },
70
- link: {
71
- label: 'Learn more',
72
- url: 'https://www.redhat.com/'
73
- }
74
- }
56
+ label: 'Always review AI-generated content prior to use.'
75
57
  };
76
58
 
77
59
  const markdown = `A paragraph with *emphasis* and **strong importance**.`;
@@ -46,25 +46,7 @@ import '@patternfly/react-core/dist/styles/base.css';
46
46
  import '@patternfly/chatbot/dist/css/main.css';
47
47
 
48
48
  const footnoteProps = {
49
- label: 'ChatBot uses AI. Check for mistakes.',
50
- popover: {
51
- title: 'Verify accuracy',
52
- description: `While ChatBot strives for accuracy, there's always a possibility of errors. It's a good practice to verify critical information from reliable sources, especially if it's crucial for decision-making or actions.`,
53
- bannerImage: {
54
- src: 'https://cdn.dribbble.com/userupload/10651749/file/original-8a07b8e39d9e8bf002358c66fce1223e.gif',
55
- alt: 'Example image for footnote popover'
56
- },
57
- cta: {
58
- label: 'Got it',
59
- onClick: () => {
60
- alert('Do something!');
61
- }
62
- },
63
- link: {
64
- label: 'Learn more',
65
- url: 'https://www.redhat.com/'
66
- }
67
- }
49
+ label: 'Always review AI-generated content prior to use.'
68
50
  };
69
51
 
70
52
  const markdown = `A paragraph with *emphasis* and **strong importance**.
@@ -36,25 +36,7 @@ import '@patternfly/react-core/dist/styles/base.css';
36
36
  import '@patternfly/chatbot/dist/css/main.css';
37
37
 
38
38
  const footnoteProps = {
39
- label: 'ChatBot uses AI. Check for mistakes.',
40
- popover: {
41
- title: 'Verify information',
42
- description: `While ChatBot strives for accuracy, AI is experimental and can make mistakes. We cannot guarantee that all information provided by ChatBot is up to date or without error. You should always verify responses using reliable sources, especially for crucial information and decision making.`,
43
- bannerImage: {
44
- src: 'https://cdn.dribbble.com/userupload/10651749/file/original-8a07b8e39d9e8bf002358c66fce1223e.gif',
45
- alt: 'Example image for footnote popover'
46
- },
47
- cta: {
48
- label: 'Dismiss',
49
- onClick: () => {
50
- alert('Do something!');
51
- }
52
- },
53
- link: {
54
- label: 'View AI policy',
55
- url: 'https://www.redhat.com/'
56
- }
57
- }
39
+ label: 'Always review AI-generated content prior to use.'
58
40
  };
59
41
 
60
42
  const markdown = `A paragraph with *emphasis* and **strong importance**.
@@ -36,25 +36,7 @@ import '@patternfly/chatbot/dist/css/main.css';
36
36
  import saveAs from 'file-saver';
37
37
 
38
38
  const footnoteProps = {
39
- label: 'ChatBot uses AI. Check for mistakes.',
40
- popover: {
41
- title: 'Verify information',
42
- description: `While ChatBot strives for accuracy, AI is experimental and can make mistakes. We cannot guarantee that all information provided by ChatBot is up to date or without error. You should always verify responses using reliable sources, especially for crucial information and decision making.`,
43
- bannerImage: {
44
- src: 'https://cdn.dribbble.com/userupload/10651749/file/original-8a07b8e39d9e8bf002358c66fce1223e.gif',
45
- alt: 'Example image for footnote popover'
46
- },
47
- cta: {
48
- label: 'Dismiss',
49
- onClick: () => {
50
- alert('Do something!');
51
- }
52
- },
53
- link: {
54
- label: 'View AI policy',
55
- url: 'https://www.redhat.com/'
56
- }
57
- }
39
+ label: 'Always review AI-generated content prior to use.'
58
40
  };
59
41
 
60
42
  const markdown = `A paragraph with *emphasis* and **strong importance**.
@@ -44,25 +44,7 @@ import '@patternfly/react-core/dist/styles/base.css';
44
44
  import '@patternfly/chatbot/dist/css/main.css';
45
45
 
46
46
  const footnoteProps = {
47
- label: 'ChatBot uses AI. Check for mistakes.',
48
- popover: {
49
- title: 'Verify information',
50
- description: `While ChatBot strives for accuracy, AI is experimental and can make mistakes. We cannot guarantee that all information provided by ChatBot is up to date or without error. You should always verify responses using reliable sources, especially for crucial information and decision making.`,
51
- bannerImage: {
52
- src: 'https://cdn.dribbble.com/userupload/10651749/file/original-8a07b8e39d9e8bf002358c66fce1223e.gif',
53
- alt: 'Example image for footnote popover'
54
- },
55
- cta: {
56
- label: 'Dismiss',
57
- onClick: () => {
58
- alert('Do something!');
59
- }
60
- },
61
- link: {
62
- label: 'View AI policy',
63
- url: 'https://www.redhat.com/'
64
- }
65
- }
47
+ label: 'Always review AI-generated content prior to use.'
66
48
  };
67
49
 
68
50
  const markdown = `A paragraph with *emphasis* and **strong importance**.
@@ -44,25 +44,7 @@ import '@patternfly/react-core/dist/styles/base.css';
44
44
  import '@patternfly/chatbot/dist/css/main.css';
45
45
 
46
46
  const footnoteProps = {
47
- label: 'ChatBot uses AI. Check for mistakes.',
48
- popover: {
49
- title: 'Verify information',
50
- description: `While ChatBot strives for accuracy, AI is experimental and can make mistakes. We cannot guarantee that all information provided by ChatBot is up to date or without error. You should always verify responses using reliable sources, especially for crucial information and decision making.`,
51
- bannerImage: {
52
- src: 'https://cdn.dribbble.com/userupload/10651749/file/original-8a07b8e39d9e8bf002358c66fce1223e.gif',
53
- alt: 'Example image for footnote popover'
54
- },
55
- cta: {
56
- label: 'Dismiss',
57
- onClick: () => {
58
- alert('Do something!');
59
- }
60
- },
61
- link: {
62
- label: 'View AI policy',
63
- url: 'https://www.redhat.com/'
64
- }
65
- }
47
+ label: 'Always review AI-generated content prior to use.'
66
48
  };
67
49
 
68
50
  const markdown = `A paragraph with *emphasis* and **strong importance**.
@@ -5,15 +5,8 @@
5
5
  import type { HTMLProps, FunctionComponent } from 'react';
6
6
 
7
7
  import { useState } from 'react';
8
-
9
- // Import Patternfly components
10
8
  import { Button, Content, ContentVariants, Flex, PopoverProps } from '@patternfly/react-core';
11
-
12
- // Import Patternfly icons
13
- import { InfoCircleIcon } from '@patternfly/react-icons/dist/esm/icons/info-circle-icon';
14
9
  import { ExternalLinkAltIcon } from '@patternfly/react-icons/dist/esm/icons/external-link-alt-icon';
15
-
16
- // Import Chatbot components
17
10
  import ChatbotPopover from '../ChatbotPopover/ChatbotPopover';
18
11
 
19
12
  export interface ChatbotFootnoteProps extends Omit<HTMLProps<HTMLDivElement>, 'popover'> {
@@ -38,6 +31,10 @@ export interface ChatbotFootnotePopover {
38
31
  link?: ChatbotFootnotePopoverLink;
39
32
  /** Props for PF Popover */
40
33
  popoverProps?: PopoverProps;
34
+ /** Flag indicating whether the popover close button is rendered. Either this or a cta that closes the popover
35
+ * must be present.
36
+ */
37
+ showClose?: boolean;
41
38
  }
42
39
 
43
40
  export interface ChatbotFootnotePopoverCTA {
@@ -66,10 +63,15 @@ export const ChatbotFootnote: FunctionComponent<ChatbotFootnoteProps> = ({
66
63
  className,
67
64
  ...props
68
65
  }: ChatbotFootnoteProps) => {
69
- // Popover visibility state
66
+ if (!popover?.cta && !popover?.showClose) {
67
+ // eslint-disable-next-line no-console
68
+ console.error(
69
+ 'ChatbotFootnote: You must provide either the popover.cta or popover.showClose props in order to render a button that can close the popover.'
70
+ );
71
+ }
72
+
70
73
  const [isVisible, setIsVisible] = useState<boolean>(false);
71
74
 
72
- // Define popover body content
73
75
  const popoverBodyContent = (
74
76
  <>
75
77
  {popover?.bannerImage && <img src={popover.bannerImage.src} alt={popover.bannerImage.alt} />}
@@ -121,11 +123,11 @@ export const ChatbotFootnote: FunctionComponent<ChatbotFootnoteProps> = ({
121
123
  minWidth={popover.popoverProps?.minWidth || '432'}
122
124
  maxWidth={popover.popoverProps?.maxWidth || '432'}
123
125
  distance={popover.popoverProps?.distance || 16}
124
- showClose={false}
126
+ showClose={popover?.showClose || false}
125
127
  {...popover.popoverProps}
126
128
  >
127
- <Button variant="link" size="sm">
128
- {label} <InfoCircleIcon />
129
+ <Button aria-haspopup="dialog" isExpanded={isVisible} variant="link" size="sm">
130
+ {label}
129
131
  </Button>
130
132
  </ChatbotPopover>
131
133
  )}