ChatPanel

A generic chat panel which displays chat bubbles from the local input or a remote data source such as an AI agent. The example below is not connected to a backend but will give you an idea of how easy it would be to let it drive an AI agent.

Chat panel
//<code-header>
fiddle.title = 'Chat panel';
//</code-header>
let voices;

const chatPanel = new ChatPanel({
    appendTo      : targetElement,
    title         : 'Acme Sales Support',
    height        : '30em',
    showTimestamp : true,
    style         : 'margin-inline:auto;margin-block:5em',
    hidden        : false,
    floating      : false, // force panel to stay in the normal DOM flow
    messages      : [
        {
            fromOther : true,
            text      : `Hello, I am a fake chat agent in a docs app. I don't know anything but feel 
        free to ask me anything.`
        }
    ],
    bubbleTools : {
        readMessage : {
            class   : 'fa fa-volume-high',
            tooltip : 'Read message'
        }
    },

    intro : {
        html : `<h4 style="margin:0">We typically reply in a few minutes</h4>
            <br>You can contact our support team if you've checked our docs and still need help.`
    },
    // Avatar image url
    avatar : './data/Core/images/lisa.png',

    items : {
        messageField : {
            placeholder : 'Ask me anything'
        }
    },
    tools : {
        settings : {
            cls : 'b-fa b-fa-ellipsis',
            onClick({ source }) {
                if (!this.menu) {
                    this.menu = new Menu({
                        anchor : true,
                        owner  : this,
                        items  : [
                            {
                                text   : 'Clear chat',
                                onItem : 'up.onClearChatClick'
                            }
                        ]
                    });
                }
                this.menu.showBy(source.element);
            }
        }
    },

    onClearChatClick() {
        this.messages = [];
    },

    onBubbleToolClick({ tool, message }) {
        if (tool === 'readMessage') {
            const
                voices = window.speechSynthesis.getVoices(),
                utterance = new SpeechSynthesisUtterance(message.text);

            utterance.voice = voices.find(voice => voice.name.includes('Female') || voice.gender === 'female') || voices[0];

            globalThis.speechSynthesis.speak(utterance);
        }
    },

    onLocalMessage({ text }) {
        // Fake a response
        setTimeout(() => {
            this.addMessage({
                fromOther : true,
                text      : 'Sorry, no clue about that. Try hooking me up to an AI agent instead?'
            });
        }, 1500);
    }
});

window.speechSynthesis.onvoiceschanged = function() {
    voices = window.speechSynthesis.getVoices();
};

chatPanel.widgetMap.messageField.focus();

const settingsPanel = new Panel({
    appendTo        : targetElement,
    width           : '20em',
    height          : '100%',
    title           : 'Settings',
    labelPosition   : 'align-before',
    cls             : 'b-fiddle-settings',
    inputFieldAlign : 'end',    // align toggles to the right
    items           : [
        {
            type    : 'slidetoggle',
            label   : 'Show avatar',
            checked : true,
            onChange({ value }) {
                chatPanel.avatar = value ? chatPanel.initialConfig.avatar : null;
            }
        },
        {
            type    : 'slidetoggle',
            label   : 'Show intro text',
            checked : true,
            onChange({ value }) {
                chatPanel.intro = value ?  chatPanel.initialConfig.intro : null;
            }
        },
        {
            type    : 'slidetoggle',
            label   : 'Show timestamps',
            checked : true,
            onChange({ value }) {
                chatPanel.showTimestamp = value;
            }
        },
        {
            type    : 'slidetoggle',
            label   : 'Show bubble tools',
            checked : true,
            onChange({ value }) {
                chatPanel.bubbleTools = value ? {
                    readMessage : {
                        class   : 'fa fa-volume-high',
                        tooltip : 'Read message'
                    }
                } : null;
            }
        }
    ]
});

Basic configuration

To preload the chat panel with a chat history, use messages. You can set an intro message, show an avatar and set a title.

After the user adds a new message via the text input field, a localMessage event is fired. You can send this to your server, and once your remote chat service sends a message to the client, you can add it to the log using addMessage.

const chatPanel = new ChatPanel({
    appendTo      : targetElement,
    title         : 'Acme Sales Support',
    async onLocalMessage({ text }){
         const
             response = await fetch('chatServer.php'),
             text = await response.text();

         this.addMessage({ fromOther : true, text });
    }
});

On remote speech bubbles, you can show a time stamp using showTimestamp and you can also define a list of action icons via bubbleTools

The text input field can be configured using the items object:

const chatPanel = new ChatPanel({
    appendTo      : targetElement,
    title         : 'Acme Sales Support',
    height        : '30em',
    showTimestamp : true,
    items : {
        messageField : {
            placeholder : 'Ask me anything'
        }
    }
});

Displaying selectable option chips

A remote chat response can also present a list of actions, letting the user pick one before continuing the chat.

Chat panel actions
//<code-header>
fiddle.title = 'Chat panel actions';
CSSHelper.insertRule('.b-panel .b-slidetoggle .b-label { flex : 1; }', targetElement.getRootNode());
CSSHelper.insertRule('.b-panel .b-slidetoggle .b-field-inner { flex : none; }', targetElement.getRootNode());
//</code-header>
let voices;

const chatPanel = new ChatPanel({
    appendTo      : targetElement,
    title         : 'Acme Sales Support',
    height        : '30em',
    showTimestamp : true,
    style         : 'margin-inline:auto;margin-block:5em',
    hidden        : false,
    floating      : false, // force panel to stay in the normal DOM flow
    messages      : [
        {
            fromOther : true,
            text      : 'Hello, to get to know you better - please pick your favorite JS framework.',
            options   : ['react', 'vue', 'angular', 'svelte', 'jQuery']
        }
    ],

    // Avatar image url
    avatar : './data/Core/images/lisa.png',

    onLocalMessage() {
        // Fake a response
        setTimeout(() => {
            this.addMessage({ fromOther : true, text : 'Good choice! I like vanilla JS myself.' });
        }, 1500);
    }
});

Configs

113

Common

listenersEvents

Other

The path to an avatar to display at the top of the chat bubble area

An array of DomConfig items to show tool icons associated with each remote speech bubble. Each tool can be clicked by the user to perform an action. Upon clicking a tool, the chat panel will trigger a {#event-bubbleToolClick} event with details.

An introductory text (or DomConfig) shown at the top of the chat bubble area

The initial messages to display in the chat bubble area (e.g. a bot greeting message "Hello, how may I help you?"

Set to true to show a timestamp below each chat bubble

columnWidget
defaultFocusContainer
drawerPanel
labelPositionContainer
renditionContainer
rtlRTL
spanWidget

Accessibility

ariaLabelWidget
keyMapKeyMap

Content

bbarPanel
defaultsContainer
footerPanel
headerPanel
itemsContainer
lazyItemsContainer
namedItemsContainer
stripsPanel
tbarPanel
textContentContainer
toolsPanel

CSS

bodyClsPanel
borderContainer
clsWidget
colorWidget
htmlClsWidget
itemClsContainer
styleWidget
uiPanel

DOM

adoptWidget
appendToWidget
contentWidget
datasetWidget
htmlWidget
idWidget
tagWidget

Float & align

alignWidget
anchorWidget
centeredWidget
draggableWidget
floatingWidget
xWidget
yWidget

Layout

alignSelfWidget
dockWidget
flexWidget
heightWidget
hiddenWidget
hideWhenEmptyContainer
layoutContainer
layoutStyleContainer
marginWidget
maxHeightWidget
maxWidthWidget
minHeightWidget
minWidthWidget
textAlignWidget
weightWidget
widthWidget

misc

tabBarItemsContainer

Misc

dataFieldWidget
disabledWidget
iconPanel
localeClassLocalizable
localizableLocalizable
maskedWidget
ownerWidget
readOnlyWidget
refWidget
rippleWidget
tabWidget
titlePanel
tooltipWidget

Record

recordContainer

Scrolling

State

stateIdState

Properties

102

Class hierarchy

isChatPanel: Boolean= truereadonly
Identifies an object as an instance of ChatPanel class, or subclass thereof.
isChatPanel: Boolean= truereadonlystatic
Identifies an object as an instance of ChatPanel class, or subclass thereof.
isChatPanelMixin: Boolean= truereadonlyChatPanelMixin
Identifies an object as an instance of ChatPanelMixin class, or subclass thereof.
isChatPanelMixin: Boolean= truereadonlystaticChatPanelMixin
Identifies an object as an instance of ChatPanelMixin class, or subclass thereof.
isContainerContainer
isDelayableDelayable
isEventsEvents
isKeyMapKeyMap
isLocalizableLocalizable
isPanelPanel
isStateState
isToolableToolable
isWidgetWidget

Other

The path to an avatar to display at the top of the chat bubble area

An array of DomConfig items to show tool icons associated with each remote speech bubble. Each tool can be clicked by the user to perform an action. Upon clicking a tool, the chat panel will trigger a {#event-bubbleToolClick} event with details.

An introductory text (or DomConfig) shown at the top of the chat bubble area

The initial messages to display in the chat bubble area (e.g. a bot greeting message "Hello, how may I help you?"

Set to true to show a timestamp below each chat bubble

A reference to the data store storing all the chat messages.

$namestaticWidget
columnWidget
firstItemContainer
hasChangesContainer
isValidContainer
itemsContainer
labelPositionContainer
lastItemContainer
renditionContainer
rtlRTL
spanWidget
toolsPanel
typestaticWidget
valuesContainer

Accessibility

keyMapKeyMap

Content

bbarPanel
tbarPanel

CSS

clsWidget

DOM

appendToWidget
contentWidget
datasetWidget
elementWidget
htmlWidget
idWidget
styleWidget

Float & align

xWidget
yWidget

Layout

alignSelfWidget
flexWidget
heightWidget
layoutContainer
layoutStyleContainer
marginWidget
maxHeightWidget
maxWidthWidget
minHeightWidget
minWidthWidget
widthWidget

Lifecycle

configBase

Misc

cellInfoWidget
disabledWidget
localeHelperLocalizable
localeManagerLocalizable
readOnlyWidget
refWidget
tabWidget
titlePanel
tooltipWidget

Record

recordContainer

State

stateState

Visibility

hiddenWidget
isVisibleWidget

Widget hierarchy

ownerWidget
parentWidget
widgetMapContainer

Functions

75

Other

Add a message bubble to the chat log. Accepts data for the ChatMessageModel, or a Promise that later resolves to such data. When passed a promise, the bubble will show a loading indicator until resolved.

ParameterTypeDescription
messagePromise | ChatMessageModelConfig

A message config object, or a Promise resolving a string with the text

addContainer
composeWidget
createOnFrameDelayable
disableWidget
enableWidget
focusWidget
getAtContainer
getWidgetByIdContainer
insertContainer
LstaticLocalizable
maskWidget
onEvents
recomposeWidget
relayAllEvents
removeContainer
removeAllContainer
resetValuesContainer
setValuesContainer
triggerEvents
unEvents
unmaskWidget

Configuration

applyDefaultsstaticBase

Events

Float & align

alignToWidget
setXYWidget
showByWidget
toFrontWidget

Lifecycle

createstaticWidget
destroystaticBase
initClassstaticWidget

Misc

attachTooltipstaticWidget
fromElementstaticWidget
fromSelectorstaticWidget
getByIdstaticWidget
isOfTypeNamestaticBase
mixinstaticBase
optionalLstaticLocalizable

State

Visibility

hideWidget
showWidget

Widget hierarchy

closestWidget
containsWidget
ownsWidget
queryWidget
queryAllWidget
upWidget

Events

23

Fired when chat bubble tool icon is clicked.

// Adding a listener using the "on" method
chatPanel.on('bubbleToolClick', ({ source, tool, message }) => {

});
ParameterTypeDescription
sourceChatPanel

This panel

toolString

The tool identifier

messageChatMessageModelConfig

The message data for the associated chat bubble

Fired when a client side message is added via the text input field (or by picking a predefined option bubble).

// Adding a listener using the "on" method
chatPanel.on('localMessage', ({ source, text, id }) => {

});
ParameterTypeDescription
sourceChatPanel

This panel

textString

The text

idString

The message id

catchAllEvents
destroyEvents
expandPanel
focusInWidget
focusOutWidget
hideWidget
paintWidget
readOnlyWidget
recomposeWidget
resizeWidget
showWidget

Event handlers

23

Called when chat bubble tool icon is clicked.

new ChatPanel({
    onBubbleToolClick({ source, tool, message }) {

    }
});
ParameterTypeDescription
sourceChatPanel

This panel

toolString

The tool identifier

messageChatMessageModelConfig

The message data for the associated chat bubble

Called when a client side message is added via the text input field (or by picking a predefined option bubble).

new ChatPanel({
    onLocalMessage({ source, text, id }) {

    }
});
ParameterTypeDescription
sourceChatPanel

This panel

textString

The text

idString

The message id

onDestroyEvents
onFocusInWidget
onHideWidget
onPaintWidget
onResizeWidget
onShowWidget

Typedefs

7

CSS variables

52

Inherited