Tessina UI
Tessina UI
GitHubIntroduction
InstallationUsageTheming
Components
ButtonIconButtonLinkSpinnerBadgeAvatarStatusChipShortcutSkeletonSurfaceProgressMeterRating
LabelFieldFieldsetCheckboxRadioSwitchSliderSelectComboboxSearchTextareaNumberFieldDate PickerTime PickerOTP InputFile UploadCalendar
AlertBannerToastTooltip
TabsAccordionCollapsibleBreadcrumbPaginationStepperSegmentedControlButtonGroupToggleButtonToggleGroupToolbarNavigation MenuMenubarBottom NavSidebar
Split ButtonFABDropdown MenuContextMenuCommandPopoverHoverCard
ContainerStackFlexGridAspectRatioSpacerCardCarouselDividerScroll Area
Table
ChatBubblePromptInputCodeBlock
ModalAlertDialogDrawerAction SheetTop Header MobileTop Header DesktopEmptyStateForm
Contributing
ComponentsAI

ChatBubble

AI chat message bubbles with role-aware alignment, streaming state, action buttons, and RTL support.

Showcase

Usage

import { ChatBubble, TessinaAvatar } from "@tessinaui/ui/chat-bubble";

<ChatBubble role="assistant" showAvatar>
  Hello! How can I help you today?
</ChatBubble>

<ChatBubble role="user">
  Can you explain transformers?
</ChatBubble>

API

ChatBubble

PropTypeDefaultDescription
role"user" | "assistant""user"Drives alignment and color — user aligns right, assistant aligns left
variant"bubble" | "flat" | "card""bubble"Visual style of the message container
size"xs" | "sm" | "md" | "lg" | "xl""md"Controls text size
rounded"none" | "sm" | "md" | "lg" | "full""lg"Corner radius of the bubble
intent"none" | "error" | "warning" | "success" | "info""none"Semantic color intent
status"idle" | "sending" | "streaming" | "error""idle"Message delivery / generation state
avatarReactNode—Custom avatar element; defaults to TessinaAvatar when showAvatar is true
showAvatarbooleantrueShow avatar next to assistant messages
timestampstring—Timestamp string displayed below the bubble
showTimestampbooleanfalseWhether to render the timestamp
showActionsbooleanfalseShow copy / thumbs / regenerate actions below assistant messages
onCopy() => void—Fires when the copy action is clicked
onThumbsUp() => void—Fires when thumbs-up is clicked
onThumbsDown() => void—Fires when thumbs-down is clicked
onRegenerate() => void—Fires when regenerate is clicked
onRetry() => void—Fires when retry is clicked on an error bubble
dir"ltr" | "rtl""ltr"Text direction — RTL mirrors the layout
maxWidthstring"75%"CSS max-width for the bubble column

TessinaAvatar

The default avatar used inside assistant bubbles. Renders the Tessina symbol on a neutral circular background using currentColor so it respects dark mode.

PropTypeDefaultDescription
size"xs" | "sm" | "md" | "lg" | "xl""md"Size of the avatar circle
classNamestring—Additional class names

Variants

Bubble

The default. A background-filled pill that hugs its content.

<ChatBubble role="user" variant="bubble">Message text</ChatBubble>

Flat

No background — just the text. Useful for minimal or full-width layouts.

<ChatBubble role="assistant" variant="flat">Message text</ChatBubble>

Card

A bordered card. Good for rich content or when the bubble needs to span full width.

<ChatBubble role="assistant" variant="card">Message text</ChatBubble>

Status

Streaming (thinking)

Pass status="streaming" with no children to show the animated thinking indicator.

<ChatBubble role="assistant" status="streaming" showAvatar />

Pass children alongside status="streaming" to show partial content with a trailing cursor dot.

<ChatBubble role="assistant" status="streaming" showAvatar>
  Neural networks are computational models
</ChatBubble>

Error

<ChatBubble role="user" status="error" onRetry={() => resend()}>
  Message that failed to send
</ChatBubble>

Sending

<ChatBubble role="user" status="sending">
  Sending…
</ChatBubble>

Actions

Actions are only rendered for role="assistant" and only when not in sending or streaming states. Provide a handler for each action you want to appear.

<ChatBubble
  role="assistant"
  showActions
  onCopy={() => navigator.clipboard.writeText(text)}
  onThumbsUp={() => submitFeedback("up")}
  onThumbsDown={() => submitFeedback("down")}
  onRegenerate={() => regenerate()}
>
  Here is my response…
</ChatBubble>

RTL

<ChatBubble role="user" dir="rtl">هل يمكنك مساعدتي؟</ChatBubble>
<ChatBubble role="assistant" dir="rtl" showAvatar>بالتأكيد!</ChatBubble>

Custom Avatar

<ChatBubble
  role="assistant"
  showAvatar
  avatar={
    <img src="/my-bot-avatar.png" className="size-8 rounded-full" alt="Bot" />
  }
>
  Custom avatar slot accepts any ReactNode.
</ChatBubble>

Table

A complete primitive set for tabular data — header, body, footer, sortable columns, sticky header, row states, plus cell helpers for avatars, status, currency amounts, and actions. Designed in the Wise / PrimeReact tradition.

PromptInput

AI chat input with auto-grow textarea, send/stop swap, a "+" options menu, model selector, suggestion chips, drag-drop attachments, voice controls, inline & stacked layouts, RTL and a loading skeleton.

On this page

ShowcaseUsageAPIChatBubbleTessinaAvatarVariantsBubbleFlatCardStatusStreaming (thinking)ErrorSendingActionsRTLCustom Avatar