Chat
The shell for a chatbot or assistant: a header, a scrolling conversation, suggested prompts and a composer. It has no backend; your code answers an event.
- CSS
css/components/chat.css- JS
js/components/chat.js
01 — Example
In a page
Ask anything, or press a suggestion. This demo answers with a canned reply (data-chat-demo).
Assistant
Online-
Hi. Ask me about your photos.
Answers can be wrong. Check anything important.
02 — Connect it
Answer the event
respond() takes a string, { html }, or a promise of either. A rejected promise shows the error with a Retry button.
03 — Behavior
Script
| Name | Detail |
|---|---|
| Keys | Enter sends, Shift+Enter is a new line. On touch screens Enter is always a new line. |
| Prompts | [data-chat-prompt] buttons send their own text and hide once the chat starts. |
| Placement | .chat--floating fixes it in the bottom-right corner (full screen on phones). It also fits in a sheet. |
el.jewelChat | .add("user" | "bot", text), .typing(true), .clear(). |
04 — Usage
Use it for
- An assistant that answers questions about the person’s own content.
- Two or three suggested prompts that show what it can do.
- A note that answers can be wrong.
Avoid
- Pretending a person is answering.
- Long-form writing. Answers should be short and link onward.
05 — Accessibility
Notes
- The conversation is a
role="log", so new replies are announced. - The composer has a visually hidden label; the send button has an
aria-label.
06 — Without Jewel’s JS
What the script does
The script adds each message to the log, shows a typing indicator, clears the composer and fires jewel:chatsend for your code to answer. The CSS reads only the markup below, so a framework can render the conversation from its own state and leave out chat.js and data-component.
| State | Set this | Notes |
|---|---|---|
| Message | <li class="chat__msg chat__msg--user"> or chat__msg--bot, holding p.chat__author and div.chat__text | In ol.chat__log. CSS hides the user’s author line (“You”) visually. |
| Typing | A last <li class="chat__msg chat__msg--bot" aria-label="Assistant is typing"> holding <span class="chat__typing" aria-hidden="true"> with three empty <span>s | Use the bot’s name in the label. Remove it when the reply arrives. |
| Waiting for a reply | aria-busy="true" and disabled on .chat__send | Clear both when the reply or the error is in. |
| Failed reply | chat__msg--error on the bot message | Shows its text in the error color. Put a Retry button inside. |
| Started | is-started on .chat | Hides .chat__prompts after the first message. |
| Scrollable log | tabindex="0" on .chat__log | So keyboard users can scroll it. |
Events and keyboard
- Enter sends and Shift+Enter is a new line. Skip this during IME composition (
isComposing) and on touch screens (pointer: coarse), where Enter is always a new line. - After each message, scroll the log to the bottom, smoothly unless reduced motion is on.
- Clear the composer after sending. The textarea grows with
field-sizing: content; where that isn’t supported, the script sets its height fromscrollHeightas people type. jewel:chatsenddoesn’t fire without the script. Send the text to your backend yourself.