Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ export const ChatbotFooterExample: FunctionComponent = () => {
return (
<ChatbotFooter>
<MessageBar onSendMessage={handleSend} hasMicrophoneButton hasAttachButton />
<ChatbotFootnote label="ChatBot uses AI. Check for mistakes." />
<ChatbotFootnote label="Always review AI-generated content prior to use." />
</ChatbotFooter>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,31 @@ import { FunctionComponent } from 'react';
import { ChatbotFootnote } from '@patternfly/chatbot/dist/dynamic/ChatbotFooter';

export const FootnoteDemo: FunctionComponent = () => (
<ChatbotFootnote
label="ChatBot uses AI. Check for mistakes."
popover={{
title: 'Verify information',
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.`,
bannerImage: {
src: 'https://cdn.dribbble.com/userupload/10651749/file/original-8a07b8e39d9e8bf002358c66fce1223e.gif',
alt: 'Example image for footnote popover'
},
cta: {
label: 'Dismiss',
onClick: () => {
alert('Do something!');
<>
<h4>Static text</h4>
<ChatbotFootnote label="Always review AI-generated content prior to use." />
<br />
<h4>With popover</h4>
<ChatbotFootnote
label="Always review AI-generated content prior to use."
popover={{
title: 'Verify information',
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.`,
bannerImage: {
src: 'https://cdn.dribbble.com/userupload/10651749/file/original-8a07b8e39d9e8bf002358c66fce1223e.gif',
alt: 'Example image for footnote popover'
},
cta: {
label: 'Dismiss',
onClick: () => {
alert('Do something!');
}
},
link: {
label: 'View AI policy',
url: 'https://www.redhat.com/'
}
},
link: {
label: 'View AI policy',
url: 'https://www.redhat.com/'
}
}}
/>
}}
/>
</>
);
Original file line number Diff line number Diff line change
Expand Up @@ -240,10 +240,11 @@ In this example, select the respective checkbox to toggle these features:

## Footer

### Footnote with popover
### Footnote

A footnote can be placed in the ChatBot footer to communicate any legal disclaimers or information about the ChatBot.
Footnotes can be static text or a button that opens a popover.
A `<ChatbotFootnote>` can be placed in the ChatBot footer to communicate any legal disclaimers or information about the ChatBot.

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.

```js file="./ChatbotFootnote.tsx"

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,25 +37,7 @@ import '@patternfly/react-core/dist/styles/base.css';
import '@patternfly/chatbot/dist/css/main.css';

const footnoteProps = {
label: 'ChatBot uses AI. Check for mistakes.',
popover: {
title: 'Verify information',
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.`,
bannerImage: {
src: 'https://cdn.dribbble.com/userupload/10651749/file/original-8a07b8e39d9e8bf002358c66fce1223e.gif',
alt: 'Example image for footnote popover'
},
cta: {
label: 'Dismiss',
onClick: () => {
alert('Do something!');
}
},
link: {
label: 'View AI policy',
url: 'https://www.redhat.com/'
}
}
label: 'Always review AI-generated content prior to use.'
};

const markdown = `A paragraph with *emphasis* and **strong importance**.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -273,7 +273,7 @@ export const BasicDemo: FunctionComponent = () => {
}}
onAttachRejected={handleAttachRejected}
/>
<ChatbotFootnote label="ChatBot uses AI. Check for mistakes." />
<ChatbotFootnote label="Always review AI-generated content prior to use." />
</ChatbotFooter>
</FileDropZone>
</Chatbot>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -262,7 +262,7 @@ export const AttachmentMenuDemo: FunctionComponent = () => {
onAttachMenuToggleClick: onToggleClick
}}
/>
<ChatbotFootnote label="ChatBot uses AI. Check for mistakes." />
<ChatbotFootnote label="Always review AI-generated content prior to use." />
</ChatbotFooter>
</>
</FileDropZone>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,25 +33,7 @@ import userAvatar from '../Messages/user_avatar.svg';
import patternflyAvatar from '../Messages/patternfly_avatar.jpg';

const footnoteProps = {
label: 'ChatBot uses AI. Check for mistakes.',
popover: {
title: 'Verify information',
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.`,
bannerImage: {
src: 'https://cdn.dribbble.com/userupload/10651749/file/original-8a07b8e39d9e8bf002358c66fce1223e.gif',
alt: 'Example image for footnote popover'
},
cta: {
label: 'Dismiss',
onClick: () => {
alert('Do something!');
}
},
link: {
label: 'View AI policy',
url: 'https://www.redhat.com/'
}
}
label: 'Always review AI-generated content prior to use.'
};

const markdown = `A paragraph with *emphasis* and **strong importance**.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,25 +53,7 @@ import '@patternfly/react-core/dist/styles/base.css';
import '@patternfly/chatbot/dist/css/main.css';

const footnoteProps = {
label: 'ChatBot uses AI. Check for mistakes.',
popover: {
title: 'Verify accuracy',
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.`,
bannerImage: {
src: 'https://cdn.dribbble.com/userupload/10651749/file/original-8a07b8e39d9e8bf002358c66fce1223e.gif',
alt: 'Example image for footnote popover'
},
cta: {
label: 'Got it',
onClick: () => {
alert('Do something!');
}
},
link: {
label: 'Learn more',
url: 'https://www.redhat.com/'
}
}
label: 'Always review AI-generated content prior to use.'
};

const markdown = `A paragraph with *emphasis* and **strong importance**.`;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,25 +46,7 @@ import '@patternfly/react-core/dist/styles/base.css';
import '@patternfly/chatbot/dist/css/main.css';

const footnoteProps = {
label: 'ChatBot uses AI. Check for mistakes.',
popover: {
title: 'Verify accuracy',
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.`,
bannerImage: {
src: 'https://cdn.dribbble.com/userupload/10651749/file/original-8a07b8e39d9e8bf002358c66fce1223e.gif',
alt: 'Example image for footnote popover'
},
cta: {
label: 'Got it',
onClick: () => {
alert('Do something!');
}
},
link: {
label: 'Learn more',
url: 'https://www.redhat.com/'
}
}
label: 'Always review AI-generated content prior to use.'
};

const markdown = `A paragraph with *emphasis* and **strong importance**.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,25 +36,7 @@ import '@patternfly/react-core/dist/styles/base.css';
import '@patternfly/chatbot/dist/css/main.css';

const footnoteProps = {
label: 'ChatBot uses AI. Check for mistakes.',
popover: {
title: 'Verify information',
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.`,
bannerImage: {
src: 'https://cdn.dribbble.com/userupload/10651749/file/original-8a07b8e39d9e8bf002358c66fce1223e.gif',
alt: 'Example image for footnote popover'
},
cta: {
label: 'Dismiss',
onClick: () => {
alert('Do something!');
}
},
link: {
label: 'View AI policy',
url: 'https://www.redhat.com/'
}
}
label: 'Always review AI-generated content prior to use.'
};

const markdown = `A paragraph with *emphasis* and **strong importance**.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,25 +36,7 @@ import '@patternfly/chatbot/dist/css/main.css';
import saveAs from 'file-saver';

const footnoteProps = {
label: 'ChatBot uses AI. Check for mistakes.',
popover: {
title: 'Verify information',
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.`,
bannerImage: {
src: 'https://cdn.dribbble.com/userupload/10651749/file/original-8a07b8e39d9e8bf002358c66fce1223e.gif',
alt: 'Example image for footnote popover'
},
cta: {
label: 'Dismiss',
onClick: () => {
alert('Do something!');
}
},
link: {
label: 'View AI policy',
url: 'https://www.redhat.com/'
}
}
label: 'Always review AI-generated content prior to use.'
};

const markdown = `A paragraph with *emphasis* and **strong importance**.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,25 +44,7 @@ import '@patternfly/react-core/dist/styles/base.css';
import '@patternfly/chatbot/dist/css/main.css';

const footnoteProps = {
label: 'ChatBot uses AI. Check for mistakes.',
popover: {
title: 'Verify information',
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.`,
bannerImage: {
src: 'https://cdn.dribbble.com/userupload/10651749/file/original-8a07b8e39d9e8bf002358c66fce1223e.gif',
alt: 'Example image for footnote popover'
},
cta: {
label: 'Dismiss',
onClick: () => {
alert('Do something!');
}
},
link: {
label: 'View AI policy',
url: 'https://www.redhat.com/'
}
}
label: 'Always review AI-generated content prior to use.'
};

const markdown = `A paragraph with *emphasis* and **strong importance**.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,25 +44,7 @@ import '@patternfly/react-core/dist/styles/base.css';
import '@patternfly/chatbot/dist/css/main.css';

const footnoteProps = {
label: 'ChatBot uses AI. Check for mistakes.',
popover: {
title: 'Verify information',
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.`,
bannerImage: {
src: 'https://cdn.dribbble.com/userupload/10651749/file/original-8a07b8e39d9e8bf002358c66fce1223e.gif',
alt: 'Example image for footnote popover'
},
cta: {
label: 'Dismiss',
onClick: () => {
alert('Do something!');
}
},
link: {
label: 'View AI policy',
url: 'https://www.redhat.com/'
}
}
label: 'Always review AI-generated content prior to use.'
};

const markdown = `A paragraph with *emphasis* and **strong importance**.
Expand Down
26 changes: 14 additions & 12 deletions packages/module/src/ChatbotFooter/ChatbotFootnote.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,8 @@
import type { HTMLProps, FunctionComponent } from 'react';

import { useState } from 'react';

// Import Patternfly components
import { Button, Content, ContentVariants, Flex, PopoverProps } from '@patternfly/react-core';

// Import Patternfly icons
import { InfoCircleIcon } from '@patternfly/react-icons/dist/esm/icons/info-circle-icon';
import { ExternalLinkAltIcon } from '@patternfly/react-icons/dist/esm/icons/external-link-alt-icon';

// Import Chatbot components
import ChatbotPopover from '../ChatbotPopover/ChatbotPopover';

export interface ChatbotFootnoteProps extends Omit<HTMLProps<HTMLDivElement>, 'popover'> {
Expand All @@ -38,6 +31,10 @@ export interface ChatbotFootnotePopover {
link?: ChatbotFootnotePopoverLink;
/** Props for PF Popover */
popoverProps?: PopoverProps;
/** Flag indicating whether the popover close button is rendered. Either this or a cta that closes the popover
* must be present.
*/
showClose?: boolean;
}

export interface ChatbotFootnotePopoverCTA {
Expand Down Expand Up @@ -66,10 +63,15 @@ export const ChatbotFootnote: FunctionComponent<ChatbotFootnoteProps> = ({
className,
...props
}: ChatbotFootnoteProps) => {
// Popover visibility state
if (!popover?.cta && !popover?.showClose) {
// eslint-disable-next-line no-console
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.'
);
}

const [isVisible, setIsVisible] = useState<boolean>(false);

// Define popover body content
const popoverBodyContent = (
<>
{popover?.bannerImage && <img src={popover.bannerImage.src} alt={popover.bannerImage.alt} />}
Expand Down Expand Up @@ -121,11 +123,11 @@ export const ChatbotFootnote: FunctionComponent<ChatbotFootnoteProps> = ({
minWidth={popover.popoverProps?.minWidth || '432'}
maxWidth={popover.popoverProps?.maxWidth || '432'}
distance={popover.popoverProps?.distance || 16}
showClose={false}
showClose={popover?.showClose || false}
{...popover.popoverProps}
>
<Button variant="link" size="sm">
{label} <InfoCircleIcon />
<Button aria-haspopup="dialog" isExpanded={isVisible} variant="link" size="sm">
{label}
</Button>
</ChatbotPopover>
)}
Expand Down
Loading