Reference: components, segments, events, config: Every custom element with its attributes, events and CSS properties; every segment shape; the event map; the config object; the icons.
# Chatbot UI Components
> Every component for an AI chat and its agents — the conversation, the layout around it, and a kit for the rest of the app — each shown live.
**51 components**: 24 for the chat itself, 5 for the page around it, and 22 in the kit for the rest of the app. Each one is shown running below, and each page has its variants, its code and its API. The chat’s pieces are custom elements and segments: they work in plain HTML and in every framework. The kit is plain CSS classes for the controls your own page puts around the chat, themed by the same variables. ## Chat [Section titled “Chat”](#chat) The conversation and everything in it: messages, replies, tools, questions, approvals, and the composer. * [Chat, live](/preview/demo/chat/?tile) [Chat](/components/chat/) The whole chat in one tag — a transcript that scrolls, the question panel and a composer — composed for you, or from your own children. * [Conversation, live](/preview/demo/conversation/?tile) [Conversation](/components/conversation/) The transcript — it keeps the messages, renders each as a bubble, streams replies token by token and stays at the bottom while you are there. * [Message, live](/preview/demo/message/?tile) [Message](/components/message/) One message of the conversation — who wrote it, when, and its content as plain text or as a list of segments. * [Message actions, live](/preview/demo/message-actions/?tile) [Message actions](/components/message-actions/) The row of buttons under a message — copy, retry, edit, feedback, details — on when your app can answer them, in the order you choose. * [Branches, live](/preview/demo/branch-picker/?tile) [Branches](/components/branches/) Every version of a reply is kept — retry forks the conversation instead of overwriting it, and a ‹1/2› picker walks between the versions. * [Attachments, live](/preview/demo/attachments/?tile) [Attachments](/components/attachments/) Files a message carries — images shown as pictures, other files as their name and type — and the pending files in the composer before they are sent. * [Waiting indicator, live](/preview/demo/waiting/?tile) [Waiting indicator](/components/waiting-indicator/) The three dots a reply shows between the question and its first word, so the reader knows the model is on it. * [Response, live](/preview/demo/response/?tile) [Response](/components/response/) The text of a reply, rendered as Markdown — headings, lists, tables, links — and written as it streams rather than re-rendered at every token. * [Reasoning, live](/preview/demo/thinking/?tile) [Reasoning](/components/reasoning/) The model's reasoning, folded above its answer — streamed while it thinks, closed once it is done, opened by the reader who wants to know why. * [Code block, live](/preview/demo/code-block/?tile) [Code block](/components/code-block/) A block of code in a reply — its file name, its language, a copy button — highlighted as it streams when a highlighter is installed. * [Tool call, live](/preview/demo/tool/?tile) [Tool call](/components/tool/) The row a reply shows when the model calls one of your tools — its name, what it was asked, what it returned, and whether it is running, waiting for a person or done. * [Artifact, live](/preview/demo/artifact/?tile) [Artifact](/components/artifact/) A document the model produces — a page, a component, a script, a note — shown as a card with its code, a sandboxed preview, copy and download. * [Error, live](/preview/demo/error/?tile) [Error](/components/error/) A turn that failed, shown inside that turn — what went wrong in words, the technical detail beneath — with whatever had already arrived kept above it. * [Custom view, live](/preview/demo/custom-view/?tile) [Custom view](/components/custom-view/) A view of your own inside a reply — a card, a chart, a form — drawn by a renderer you register for a segment type you name. * [Approval, live](/preview/demo/approval/?tile) [Approval](/components/approval/) A tool call held until a person decides — the call and its arguments asked at the composer, approve, reject, or a word on what to do instead. * [Question, live](/preview/demo/question/?tile) [Question](/components/question/) A question put to the person mid-conversation — choices, yes or no, a short text, or several at once — answered at the composer and kept in the transcript. * [Composer, live](/preview/demo/composer/?tile) [Composer](/components/composer/) Where the user writes the next message — a field that grows, a send button that turns into stop, attached files and a toolbar, assembled from parts. * [Suggestions, live](/preview/demo/suggestions/?tile) [Suggestions](/components/suggestions/) Prompt starters — a row of ready-made prompts above the input that the reader clicks instead of typing. * [Model selector, live](/preview/demo/model-selector/?tile) [Model selector](/components/model-selector/) A picker for the provider and model a conversation uses, grouped by provider, searchable, for apps where the reader brings their own key or picks a model. * [Approval mode, live](/preview/demo/approval-mode/?tile) [Approval mode](/components/approval-mode/) The switch every agent product ends up with — plan, ask, auto-edit, auto — deciding which tool calls run, which ask first, and which are refused. * [Context gauge, live](/preview/demo/context/?tile) [Context gauge](/components/context-gauge/) How much of the model's context window the conversation uses, as a bar or a ring that warns before the window is full. * [Status line, live](/preview/demo/status-line/?tile) [Status line](/components/status-line/) A line under the conversation for what your app is doing — searching, uploading, waiting in a queue — shown and hidden by your code. * [Scroll rail, live](/preview/demo/scroll-rail/?tile) [Scroll rail](/components/scroll-rail/) A rail of ticks beside a long conversation, one per question, that shows where you are and jumps back to any turn. * [Compaction notice, live](/preview/demo/compaction-notice/?tile) [Compaction notice](/components/compaction-notice/) The summary that takes the place of the oldest turns when a long conversation fills the model's context, so the conversation can go on. ## Layout [Section titled “Layout”](#layout) The page around a chat: the shell, its header and sidebar, the list of conversations, a split. * [App shell, live](/preview/demo/app-shell/?tile) [App shell](/components/app-shell/) The page around a chat — a sidebar beside, a header above, the chat in the rest — as a grid you size once. * [Header, live](/preview/demo/app-header/?tile) [Header](/components/header/) The bar above the chat — a button for the sidebar, the conversation's title, and room for actions at the end. * [Sidebar, live](/preview/demo/sidebar/?tile) [Sidebar](/components/sidebar/) The column beside the chat — conversations, a new-chat button, a search field, an account row — that folds away and becomes a drawer on a narrow window. * [Conversation list, live](/preview/demo/conversation-list/?tile) [Conversation list](/components/conversation-list/) The reader's past conversations, grouped by date, each with a menu to rename, pin, archive or delete it. * [Split, live](/preview/demo/layout-split/?tile) [Split](/components/split/) Two panes and a seam you can drag — the chat beside a preview, an editor or a document. ## Kit [Section titled “Kit”](#kit) Buttons, fields, menus, dialogs and the rest, as plain classes on plain elements. * [Button, live](/preview/demo/kit-button/?tile) [Button](/components/button/) Buttons in five fills and seven intents, four sizes, icon and pill shapes, and groups that fuse into one control. * [Field, live](/preview/demo/kit-field/?tile) [Field](/components/field/) Text fields, text areas, checkboxes, radios, switches, ranges and choice cards, with their labels, hints and errors, on native form controls. * [Select, live](/preview/demo/select/?tile) [Select](/components/select/) A dropdown with optional groups and a search field, driven by the keyboard, for choices a native select cannot style or filter. * [Avatar, live](/preview/demo/kit-avatar/?tile) [Avatar](/components/avatar/) A person's picture or initials, in five sizes and two shapes, and a group that overlaps them. * [Icon, live](/preview/demo/icon-set/?tile) [Icon](/components/icon/) The glyphs the library draws, available in markup as aparte-icon, sized by the place they sit in. * [Badge, live](/preview/demo/kit-badge/?tile) [Badge](/components/badge/) A small pill for a count or a status — live, draft, failed, 12 — in the same intents and fills as the button, or as a dot. * [Tag, live](/preview/demo/kit-tag/?tile) [Tag](/components/tag/) A small chip for a label, a filter or a model name, with an optional button to remove it. * [Thumbnail, live](/preview/demo/kit-thumbnail/?tile) [Thumbnail](/components/thumbnail/) A square tile for a file — an image's picture, or another file's type — with room for a remove button in a corner. * [Spinner, live](/preview/demo/kit-spinner/?tile) [Spinner](/components/spinner/) A rotating indicator for a wait, as a class, or as an element that can also show how far along it is. * [Progress, live](/preview/demo/kit-progress/?tile) [Progress](/components/progress/) A progress bar, filled to a value, or moving across while the length of the wait is unknown. * [Skeleton, live](/preview/demo/kit-skeleton/?tile) [Skeleton](/components/skeleton/) Grey shapes that stand where content will appear, so the page keeps its layout while it loads. * [Divider, live](/preview/demo/kit-divider/?tile) [Divider](/components/divider/) A thin line between two parts, horizontal or vertical, with an optional label in the middle. * [Alert, live](/preview/demo/kit-alert/?tile) [Alert](/components/alert/) A callout with an icon, a title and a message, in seven intents, with an optional button to dismiss it. * [Card, live](/preview/demo/kit-card/?tile) [Card](/components/card/) A bordered surface with an optional header, body and footer, for a summary, a setting or a view of your own in a reply. * [Keyboard key, live](/preview/demo/kit-kbd/?tile) [Keyboard key](/components/kbd/) A key drawn as a key, for shortcuts in a hint or a menu — Ctrl + K, Esc, Enter. * [Mark, live](/preview/demo/kit-mark/?tile) [Mark](/components/mark/) The tint a settled choice carries — a chosen option, the conversation you are in, an approved call — as one class on your own elements. * [Tabs, live](/preview/demo/kit-tabs/?tile) [Tabs](/components/tabs/) A row of tabs and the panel under it, underlined or segmented, on the markup of the ARIA tab pattern. * [Accordion, live](/preview/demo/kit-accordion/?tile) [Accordion](/components/accordion/) Stacked sections, each a header you press and the panel it reveals, on native details or the ARIA disclosure pattern. * [Menu, live](/preview/demo/kit-menu/?tile) [Menu](/components/menu/) A floating list of commands — items, labels, separators, a checked choice, a two-line item — for a dropdown, a context menu or an overflow menu. * [Popover, live](/preview/demo/kit-popover/?tile) [Popover](/components/popover/) A floating box with a border and a shadow, for a small form, a filter or a card of details above the page. * [Dialog, live](/preview/demo/kit-dialog/?tile) [Dialog](/components/dialog/) A modal box on the native dialog element — header, body, footer — opened and closed by two attributes, with no script of your own. * [Tooltip, live](/preview/demo/kit-tooltip/?tile) [Tooltip](/components/tooltip/) A short label with an arrow, beside the control it describes, legible over any background in either theme. Looking for a tag rather than a picture? [Every element](/components/elements/), by tag, links to its page; [every segment type](/segments/) and [every kit family](/kit/) too.
# Accordion
> Stacked sections, each a header you press and the panel it reveals, on native details or the ARIA disclosure pattern.
[Accordion](/preview/demo/kit-accordion/)
```html
Shipping
Free above 50 €, otherwise 4,90 €. Two to four working days.
Returns
Thirty days, in the original packaging.
Payment
Card, PayPal, or an invoice for a company account.
```
A column of items, each a header and the panel it reveals. The header can be a native `` inside ``, and then the browser opens and closes it, or a `
`, and then your code does. The chevron turns when the item is open, either way. The chat’s [reasoning](/components/reasoning/) block is an accordion item on ``. ## Customize [Section titled “Customize”](#customize) It reads only the theme’s shared tokens, listed on the [CSS variables](/reference/css-variables/) reference. ## Classes [Section titled “Classes”](#classes) `.aparte-accordion` · `.aparte-accordion__header` · `.aparte-accordion__icon` · `.aparte-accordion__item` · `.aparte-accordion__panel` · `.aparte-icon` ## Accessibility [Section titled “Accessibility”](#accessibility) * `` and `` need nothing more: they are keyboard-operable and announce whether they are open. * With `role="button"`, keep `aria-expanded` in step with the panel, and make the header focusable with `tabindex="0"` and Enter or Space. ## Related [Section titled “Related”](#related) * [Tabs](/components/tabs/) — one section at a time, side by side. * [Reasoning](/components/reasoning/) — a disclosure in a reply.
# Alert
> A callout with an icon, a title and a message, in seven intents, with an optional button to dismiss it.
[Alert](/preview/demo/kit-alert/)
```html
Model switched
The next reply uses the model you just picked.
The request was refused: no API key is set.
```
`.aparte-alert` is a callout: an `__icon`, a `__body` holding a `__title` and a `__message`, and an optional `__dismiss` button. Its intent (info, success, warning, danger, neutral, primary, secondary) colours it. The chat’s [error](/components/error/) card wears this recipe, and so do this site’s notes and warnings. ## Customize [Section titled “Customize”](#customize) | Variable | Default | | ---------------------------------- | --------------------------------------------- | | `--aparte-alert-gap` | `var(--aparte-space-3)` | | `--aparte-alert-padding` | `var(--aparte-space-4) var(--aparte-space-5)` | | `--aparte-alert-radius` | `var(--aparte-radius-md)` | | `--aparte-alert-rail-width` | `var(--aparte-space-1)` | | `--aparte-alert-icon-size` | `var(--aparte-space-8)` | | `--aparte-alert-dismiss-size` | `var(--aparte-btn-size-sm)` | | `--aparte-alert-title-font-size` | `var(--aparte-font-size-md)` | | `--aparte-alert-message-font-size` | `var(--aparte-font-size-sm)` | | `--aparte-alert-intent` | — | ## Classes [Section titled “Classes”](#classes) `.aparte-alert` · `.aparte-alert--danger` · `.aparte-alert--info` · `.aparte-alert--neutral` · `.aparte-alert--primary` · `.aparte-alert--secondary` · `.aparte-alert--success` · `.aparte-alert--warning` · `.aparte-alert__body` · `.aparte-alert__dismiss` · `.aparte-alert__icon` · `.aparte-alert__message` · `.aparte-alert__title` ## Accessibility [Section titled “Accessibility”](#accessibility) * An alert that appears while someone is reading takes `role="status"` (or `role="alert"` when it must interrupt); one that is part of the page from the start needs neither. * The intent is written in the title or the message, not only coloured. * The dismiss button shows a cross: give it an `aria-label`. ## Related [Section titled “Related”](#related) * [Error](/components/error/) — a failed turn, drawn as an alert. * [Badge](/components/badge/) — a status in a word rather than a sentence.
# App shell
> The page around a chat — a sidebar beside, a header above, the chat in the rest — as a grid you size once.
[The application shell: sidebar, header, chat](/preview/demo/app-shell/)
```html
aparté
Deploy checklist
gpt-4.1
```
Most chat products have the same page: the conversations in a column on the left, a bar with the conversation’s title on top, the chat filling the rest. `.aparte-app-shell` is that page as a grid of two columns and two rows. The sidebar spans both rows; the [header](/components/header/) and `.aparte-app-shell__main` stack in the second column. Size the shell (`height: 100dvh` for a whole page) and everything inside follows: the main area gives the chat the height it needs to scroll. Under 48rem of window, the [sidebar](/components/sidebar/) leaves the grid and becomes a drawer behind the header’s button. This frame is narrower than that, which is why the sidebar is a drawer here; open the demo on its own page to see the column. ## Usage [Section titled “Usage”](#usage)
```html
……
```
The shell is classes and nothing else: no element, no script. The behaviour lives in the parts that have some: `` folds and becomes a drawer, `` drags. The main area takes a [split](/components/split/) as well as a chat, for a chat beside a preview. The [Layouts guide](/guides/layout/#the-whole-page-sidebar-header-and-chat) builds a whole page, and shows the other shapes a chat takes: a reading column, a side panel, a floating composer, a centred welcome. ## Classes [Section titled “Classes”](#classes) `.aparte-app-header` · `.aparte-app-shell` · `.aparte-app-shell__main` · `.aparte-sidebar` · `.aparte-split` ## Accessibility [Section titled “Accessibility”](#accessibility) * The shell styles whatever elements carry its classes, so the landmarks are yours to choose: an `