EXEPERTAI LAB

Research alpha

Time Machine
EXEPERTAI LAB
GALLERY / COLLECTION
← Browse Astryx gallery
Chat·component·@astryxdesign/core

Chat

Chat is a family of composable primitives for building AI and human chat experiences. Combine ChatLayout, ChatMessageList, ChatMessage, bubbles, system messages, tool calls, tokenized text, and ChatComposer to assemble complete conversations without reimplementing sender-aware layout, density, scrolling, or composer behavior.

@astryxdesign/core/Chat

Usage

Chat is a family of composable primitives for building AI and human chat experiences. Combine ChatLayout, ChatMessageList, ChatMessage, bubbles, system messages, tool calls, tokenized text, and ChatComposer to assemble complete conversations without reimplementing sender-aware layout, density, scrolling, or composer behavior.

  • Compose messages using MessageList > Message > Bubble for consistent sender-aware styling and density.
  • Set the density prop to control spacing globally: compact for sidebars, balanced for most views, spacious for long-form reading. Individual messages can override.
  • Use gap when top-level rows are independent (for example, LLM tool events or streamed blocks) and list spacing needs to be tuned separately from density.
  • Use the group prop on bubbles (first, middle, last) when a single sender sends multiple consecutive messages; it tightens corner radius to visually connect them.
  • Use ChatSystemMessage with variant="divider" for date separators and default for inline status notices like joins, leaves, or topic changes.
  • Put name on the first bubble and metadata on the last bubble in a message so they align with the bubble's inline padding.
  • Wrap custom in-message content (cards, attachments, citations) in a ghost bubble so it aligns with the bubble text column; add width="100%" when it should span the full message column instead of the default bubble width cap.
  • Provide an emptyState prop so new users see a clear prompt to start a conversation instead of a blank screen.
  • Use the ghost bubble variant for AI-style responses that show rich content like code blocks or markdown without a visible boundary.
  • Don't use ChatSystemMessage for sender content; it has no avatar, alignment, or bubble. Use ChatMessage with a sender role instead.
  • Don't put long or multi-line content in a system message; keep it to a single short sentence. If you need more, use a bubble or a card.
  • Don't nest ChatMessage inside another ChatMessage; each message is a standalone article element with its own sender context.
  • Don't apply a fixed height directly on the message list; wrap it in a sized container and let the list fill with flex: 1.
  • Don't mix filled and ghost bubble variants within the same sender's messages; pick one style per side and use it consistently.
  • Don't place metadata or names on both the bubble and the message wrapper; pick one based on whether the content has a bubble boundary.

Anatomy

Message area · required

Scrollable region for messages. Renders children (typically ChatMessageList) in a flex column that pushes content to the bottom when the list is short.

Frosted glass dock · required

Sticky or fixed container at the bottom with a backdrop-blur layer. Houses the scroll button and composer.

Scroll-to-bottom button · optional

Appears when the user scrolls up or new messages arrive. Defaults to ChatLayoutScrollButton; pass null to hide or a custom element to override.

Composer · required

The input area for sending messages, typically ChatComposer. Docked at the bottom inside the frosted glass layer.

Empty state · optional

Centered placeholder shown when no messages exist. Use EmptyState for a consistent look.

Avatar · optional

A sender avatar rendered beside the message. Typically Avatar with size="md". Hidden for system messages.

Name · optional

Sender name above the message body. Place on the bubble when using bubbles, or on the message wrapper for raw content.

Content · required

The message body: one or more ChatMessageBubble elements, or any free-form ReactNode like images or tool calls. Wrap non-bubble content in a ghost bubble to align it with the bubble text column.

Metadata · optional

Timestamp, delivery status, and footer actions below the message. Place on the last bubble or on the message wrapper.

Theming

Targets

astryx-chat-layout

Visual props: density

astryx-chat-composer

Visual props: density

astryx-chat-composer-input
astryx-chat-composer-drawer

Visual props: collapsed

astryx-chat-message

Visual props: sender, density

astryx-chat-message-bubble

Visual props: sender, variant, density

astryx-chat-message-list

Visual props: density

astryx-chat-system-message

Visual props: variant

astryx-chat-message-metadata
astryx-chat-send-button
astryx-chat-dictation-button
astryx-chat-layout-scroll-button
astryx-chat-tokenized-text
astryx-chat-tool-calls
astryx-trigger-menu

Variables

--_chat-composer-radius · private

Border radius of the composer body. Inner elements derive their radius concentrically.

Default: var(--radius-chat)

--_chat-composer-padding · private

Padding of the composer body. Used in the concentric radius calculation.

Default: var(--spacing-3)

--_button-radius · private · derived

Concentric button radius inside the composer.

Default: max(var(--radius-element), calc(var(--_chat-composer-radius) - var(--_chat-composer-padding)))

Formula: max(var(--radius-element), calc(var(--_chat-composer-radius) - var(--_chat-composer-padding)))

Derived properties

borderRadius

Uses --_chat-composer-radius.

padding

Uses --_chat-composer-padding.