-
Notifications
You must be signed in to change notification settings - Fork 25
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
WelcomePrompt had spacing on top, while MessageBox didn't. I moved the spacing onto the parent since WelcomePrompt is optional. Also adding prop to control position of MessageBox content, and adding a demo for how the removal interaction could work. Design wants to demonstrate the welcome message going away when new messages are sent.
- Loading branch information
1 parent
0019c2e
commit 9caed0a
Showing
7 changed files
with
212 additions
and
51 deletions.
There are no files selected for viewing
144 changes: 144 additions & 0 deletions
144
...rnfly-docs/content/extensions/virtual-assistant/examples/UI/ChatbotWelcomeInteraction.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,144 @@ | ||
import React from 'react'; | ||
|
||
import Chatbot, { ChatbotDisplayMode } from '@patternfly/virtual-assistant/dist/dynamic/Chatbot'; | ||
import ChatbotContent from '@patternfly/virtual-assistant/dist/dynamic/ChatbotContent'; | ||
import ChatbotWelcomePrompt from '@patternfly/virtual-assistant/dist/dynamic/ChatbotWelcomePrompt'; | ||
import ChatbotFooter from '@patternfly/virtual-assistant/dist/dynamic/ChatbotFooter'; | ||
import MessageBar from '@patternfly/virtual-assistant/dist/dynamic/MessageBar'; | ||
import MessageBox from '@patternfly/virtual-assistant/dist/dynamic/MessageBox'; | ||
import Message, { MessageProps } from '@patternfly/virtual-assistant/dist/dynamic/Message'; | ||
import userAvatar from '../Messages/user_avatar.jpg'; | ||
import patternflyAvatar from '../Messages/patternfly_avatar.jpg'; | ||
import { FormGroup, Radio } from '@patternfly/react-core'; | ||
|
||
export const ChatbotWelcomeInteractionDemo: React.FunctionComponent = () => { | ||
const [messages, setMessages] = React.useState<MessageProps[]>([]); | ||
const [isSendButtonDisabled, setIsSendButtonDisabled] = React.useState(false); | ||
const [announcement, setAnnouncement] = React.useState<string>(); | ||
const [position, setPosition] = React.useState<'top' | 'bottom'>('top'); | ||
const scrollToBottomRef = React.useRef<HTMLDivElement>(null); | ||
const isVisible = true; | ||
const displayMode = ChatbotDisplayMode.default; | ||
|
||
// you will likely want to come up with your own unique id function; this is for demo purposes only | ||
const generateId = () => { | ||
const id = Date.now() + Math.random(); | ||
return id.toString(); | ||
}; | ||
|
||
const handleSend = (message: string) => { | ||
setIsSendButtonDisabled(true); | ||
const newMessages: MessageProps[] = []; | ||
// We can't use structuredClone since messages contains functions, but we can't mutate | ||
// items that are going into state or the UI won't update correctly | ||
messages.forEach((message) => newMessages.push(message)); | ||
// It's important to set a timestamp prop since the Message components re-render. | ||
// The timestamps re-render with them. | ||
const date = new Date(); | ||
newMessages.push({ | ||
id: generateId(), | ||
role: 'user', | ||
content: message, | ||
name: 'User', | ||
avatar: userAvatar, | ||
timestamp: date.toLocaleString() | ||
}); | ||
newMessages.push({ | ||
id: generateId(), | ||
role: 'bot', | ||
content: 'API response goes here', | ||
name: 'Bot', | ||
isLoading: true, | ||
avatar: patternflyAvatar, | ||
timestamp: date.toLocaleString() | ||
}); | ||
setMessages(newMessages); | ||
// make announcement to assistive devices that new messages have been added | ||
setAnnouncement(`Message from User: ${message}. Message from Bot is loading.`); | ||
|
||
// this is for demo purposes only; in a real situation, there would be an API response we would wait for | ||
setTimeout(() => { | ||
const loadedMessages: MessageProps[] = []; | ||
// We can't use structuredClone since messages contains functions, but we can't mutate | ||
// items that are going into state or the UI won't update correctly | ||
newMessages.forEach((message) => loadedMessages.push(message)); | ||
loadedMessages.pop(); | ||
loadedMessages.push({ | ||
id: generateId(), | ||
role: 'bot', | ||
content: 'API response goes here', | ||
name: 'Bot', | ||
isLoading: false, | ||
avatar: patternflyAvatar, | ||
timestamp: date.toLocaleString(), | ||
actions: { | ||
// eslint-disable-next-line no-console | ||
positive: { onClick: () => console.log('Good response') }, | ||
// eslint-disable-next-line no-console | ||
negative: { onClick: () => console.log('Bad response') }, | ||
// eslint-disable-next-line no-console | ||
copy: { onClick: () => console.log('Copy') }, | ||
// eslint-disable-next-line no-console | ||
share: { onClick: () => console.log('Share') }, | ||
// eslint-disable-next-line no-console | ||
listen: { onClick: () => console.log('Listen') } | ||
} | ||
}); | ||
setMessages(loadedMessages); | ||
// make announcement to assistive devices that new message has loaded | ||
setAnnouncement(`Message from Bot: API response goes here`); | ||
setIsSendButtonDisabled(false); | ||
}, 5000); | ||
}; | ||
|
||
return ( | ||
<> | ||
<FormGroup role="radiogroup" isInline fieldId="basic-form-radio-group" label="Position"> | ||
<Radio | ||
isChecked={position === 'top'} | ||
onChange={() => setPosition('top')} | ||
name="basic-inline-radio" | ||
label="Top" | ||
id="top" | ||
/> | ||
<Radio | ||
isChecked={position === 'bottom'} | ||
onChange={() => setPosition('bottom')} | ||
name="basic-inline-radio" | ||
label="Bottom" | ||
id="bottom" | ||
/> | ||
</FormGroup> | ||
<Chatbot displayMode={displayMode} isVisible={isVisible}> | ||
<ChatbotContent> | ||
{/* Update the announcement prop on MessageBox whenever a new message is sent | ||
so that users of assistive devices receive sufficient context */} | ||
<MessageBox announcement={announcement} position={position}> | ||
{messages.length === 0 && ( | ||
<ChatbotWelcomePrompt title="Hello, Chatbot User" description="How may I help you today?" /> | ||
)} | ||
{/* This code block enables scrolling to the top of the last message. | ||
You can instead choose to move the div with scrollToBottomRef on it below | ||
the map of messages, so that users are forced to scroll to the bottom. | ||
If you are using streaming, you will want to take a different approach; | ||
see: https://github.com/patternfly/virtual-assistant/issues/201#issuecomment-2400725173 */} | ||
{messages.map((message, index) => { | ||
if (index === messages.length - 1) { | ||
return ( | ||
<> | ||
<div ref={scrollToBottomRef}></div> | ||
<Message key={message.id} {...message} /> | ||
</> | ||
); | ||
} | ||
return <Message key={message.id} {...message} />; | ||
})} | ||
</MessageBox> | ||
</ChatbotContent> | ||
<ChatbotFooter> | ||
<MessageBar onSendMessage={handleSend} hasMicrophoneButton isSendButtonDisabled={isSendButtonDisabled} /> | ||
</ChatbotFooter> | ||
</Chatbot> | ||
</> | ||
); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters