, newVal = '') => {
e.preventDefault()
wave.args[props.name] = newVal
@@ -155,6 +205,9 @@ export const XChatbot = (props: Chatbot) => {
wave.emit(props.name, 'feedback', { message: messages[id].content, positive: false })
return [...messages]
})
+ },
+ handleSuggestion = (name: Id) => {
+ if (props.events?.includes('suggestion')) wave.emit(props.name, 'suggestion', name)
}
React.useEffect(() => {
@@ -212,6 +265,21 @@ export const XChatbot = (props: Chatbot) => {
))}
+ {!!props.suggestions?.length &&
+
+ {props.suggestions.map(({ name, label, caption, icon }) => {
+ const buttonProps: Fluent.IButtonProps = {
+ onClick: () => handleSuggestion(name),
+ className: clas(css.suggestion, hasSomeCaption ? css.captionButton : ''),
+ secondaryText: caption,
+ styles: { ...suggestionButtonStyles, ...{ label: { ...textEllipsisStyle, ...{ margin: caption ? undefined : 0, lineHeight: undefined } } } },
+ iconProps: icon ? { iconName: icon, style: { fontSize: hasSomeCaption ? 20 : 16, alignSelf: 'center' } } : undefined
+ }
+ return hasSomeCaption
+ ? {label}
+ : {label}
+ })}
+
}
{props.generating &&
@@ -228,6 +296,7 @@ export const XChatbot = (props: Chatbot) => {
multiline
autoAdjustHeight
placeholder={props.placeholder || 'Type your message'}
+ disabled={props.disabled}
styles={{
root: { flexGrow: 1 },
fieldGroup: { minHeight: INPUT_HEIGHT },
@@ -244,7 +313,7 @@ export const XChatbot = (props: Chatbot) => {
data-test={`${props.name}-submit`}
iconProps={{ iconName: 'Send' }}
onClick={submit}
- disabled={!userInput.trim() || props.generating}
+ disabled={props.disabled || !userInput.trim() || props.generating}
styles={{
root: { position: 'absolute', bottom: 16, right: 20, height: INPUT_HEIGHT },
rootHovered: { backgroundColor: 'transparent' },
@@ -264,10 +333,14 @@ interface State {
data: Rec
/** Chat input box placeholder. Use for prompt examples. */
placeholder?: S
- /** The events to capture on this chatbot. One of 'stop' | 'scroll_up' | 'feedback'. */
+ /** The events to capture on this chatbot. One of 'stop' | 'scroll_up' | 'feedback' | 'suggestion'. */
events?: S[]
/** True to show a button to stop the text generation. Defaults to False. */
generating?: B
+ /** Clickable prompt suggestions shown below the last response. */
+ suggestions?: ChatSuggestion[]
+ /** True if the user input should be disabled. */
+ disabled?: B
}
export const View = bond(({ name, state, changed }: Model) => {
diff --git a/website/static/img/widgets/chatbot-events-suggestions.png b/website/static/img/widgets/chatbot-events-suggestions.png
new file mode 100644
index 0000000000..c46a7a017f
Binary files /dev/null and b/website/static/img/widgets/chatbot-events-suggestions.png differ
diff --git a/website/static/img/widgets/chatbot-suggestions.gif b/website/static/img/widgets/chatbot-suggestions.gif
new file mode 100644
index 0000000000..885e7edb74
Binary files /dev/null and b/website/static/img/widgets/chatbot-suggestions.gif differ
diff --git a/website/widgets/ai/chatbot.md b/website/widgets/ai/chatbot.md
index 78592e0488..d22766725d 100644
--- a/website/widgets/ai/chatbot.md
+++ b/website/widgets/ai/chatbot.md
@@ -81,3 +81,44 @@ q.page['example'] = ui.chatbot_card(
events=['feedback']
)
```
+
+## With suggestions
+
+Use `suggestions` to provide user with pre-defined prompt options. Use in combination with `suggestion` event. See [full example](/docs/examples/chatbot-events-suggestions) to learn more.
+
+![chatbot-suggestions](/img/widgets/chatbot-suggestions.gif)
+
+```py {6,7,8,9,10,11,12} ignore
+from h2o_wave import data
+
+q.page['example'] = ui.chatbot_card(
+ box='1 1 5 5',
+ name='chatbot',
+ data=data(fields='content from_user', t='list'),
+ events=['suggestion'],
+ suggestions=[
+ ui.chat_suggestion('sug1', label="Write a poem", caption="about H2O Wave", icon="Edit"),
+ ui.chat_suggestion('sug2', label="Plan a trip", caption="to Europe", icon="Airplane"),
+ ui.chat_suggestion('sug3', label="Give me ideas", caption="for a new project", icon="Lightbulb"),
+ ui.chat_suggestion('sug4', label="Explain me", caption="CSS preprocessors", icon="Code")
+ ],
+)
+```
+
+## Disable input
+
+Disable user input with `disabled` property. This can be handy e.g. to limit user input to [suggestions](#with-suggestions) only.
+
+```py {10}
+from h2o_wave import data
+
+q.page['example'] = ui.chatbot_card(
+ box='1 1 5 5',
+ name='chatbot',
+ data=data(fields='content from_user', t='list', rows=[
+ ['Hello, buddy. Can you help me?', True],
+ ['Sure, what you need?', False],
+ ]),
+ disabled=True
+)
+```