Chat Window
A complete, fully-controlled chat surface. Bring your own messages and backend; the component handles rendering, the composer, theming, attachments, reactions, replies, accessibility, and a whole lot more.
Basic Usage
Type any message — the bot will stream a few canned replies back to mimic a real conversation.
Basic Chat Window
A fully working chat window. Type a message — the bot will reply with a stream of canned responses to give you a real chat feel.
import { ChatWindow } from 'fluxo-ui';
import { useState } from 'react';
function MyChat() {
const [messages, setMessages] = useState([
{ id: '1', role: 'assistant', type: 'text', content: 'Hello! How can I help?' },
]);
const handleSend = (data) => {
setMessages((prev) => [
...prev,
{ id: String(Date.now()), role: 'user', type: 'text', content: data.text },
]);
// …call your backend, then push the assistant reply back into messages
};
return (
<ChatWindow
messages={messages}
onSendMessage={handleSend}
header={{ title: 'Support', subtitle: 'Online' }}
theme="modern"
showAvatars
showTime
/>
);
}Live Theme Switcher
Switch between any of the 9 built-in themes and the color mode (auto/light/dark) on a running chat. Every surface, bubble, and gradient updates instantly.
Live Theme Switcher
Switch between any of the 9 built-in themes on a running chat — colors, gradients, bubble shapes, and surfaces update instantly. Try sending a message to feel the theme in motion.
const [theme, setTheme] = useState('classic');
const [colorMode, setColorMode] = useState('auto');
<ChatWindow
theme={theme}
colorMode={colorMode}
messages={messages}
onSendMessage={handleSend}
/>Rich Features
Reactions, replies, the actions menu, feedback, emoji picker, and drag-drop attachments — all enabled at once. Hover or long-press a message to interact.
Rich Features
Reactions, replies, message actions, feedback (👍/👎), emoji picker, attachments — all enabled. Hover any message to see the action bar.
<ChatWindow
messages={messages}
onSendMessage={handleSend}
showAvatars
showTime
reactions={{ enabled: true, onReact: (id, emoji) => mutateReaction(id, emoji) }}
feedback={{ enabled: true, onFeedback: (id, value) => recordFeedback(id, value) }}
reply={{ enabled: true, style: 'pinned' }}
messageActions={{
enabled: true,
items: [
{ id: 'copy', label: 'Copy', onClick: copyToClipboard },
{ id: 'delete', label: 'Delete', onClick: deleteMessage, appliesTo: 'user' },
],
}}
emoji={{ enabled: true, shortcodes: true }}
attachments={{ enabled: true, maxFiles: 5, maxSize: 10 * 1024 * 1024 }}
/>Import
import { ChatWindow } from 'fluxo-ui';
import type {
ChatWindowProps,
ChatMessage,
ChatRole,
ChatTheme,
ChatColorMode,
ChatSendPayload,
} from 'fluxo-ui';ChatWindow Props
messagesreqChatMessage[]Controlled messages array. Consumer is fully responsible for maintaining and mutating this list.
messagesreqChatMessage[]Controlled messages array. Consumer is fully responsible for maintaining and mutating this list.
onSendMessage(data: ChatSendPayload) => voidFired when the user sends a message via the composer. Includes text, attachments, and inReplyTo when relevant.
onSendMessage(data: ChatSendPayload) => voidFired when the user sends a message via the composer. Includes text, attachments, and inReplyTo when relevant.
onUserAction(event: UserActionEvent) => voidGeneric callback for in-message user actions (option click, custom plugin actions, etc.).
onUserAction(event: UserActionEvent) => voidGeneric callback for in-message user actions (option click, custom plugin actions, etc.).
composerTextstringControlled composer value. If undefined, the component manages composer state internally.
composerTextstringControlled composer value. If undefined, the component manages composer state internally.
onComposerTextChange(text: string) => voidFires whenever composer text changes (typing, emoji insert, shortcode replacement).
onComposerTextChange(text: string) => voidFires whenever composer text changes (typing, emoji insert, shortcode replacement).
composerPlaceholderstring"'Type your message...'"Placeholder shown in the composer textarea.
composerPlaceholderstring"'Type your message...'"Placeholder shown in the composer textarea.
composerDisabledbooleanDisables the composer.
composerDisabledbooleanDisables the composer.
renderComposer(ctx: ComposerCtx) => ReactNodeReplaces the entire composer with a custom render. Built-in actions are skipped.
renderComposer(ctx: ComposerCtx) => ReactNodeReplaces the entire composer with a custom render. Built-in actions are skipped.
showSendButtonboolean"true"Show the send button in the composer.
showSendButtonboolean"true"Show the send button in the composer.
sendOnEnterboolean"true"Send when Enter is pressed (Shift+Enter inserts newline).
sendOnEnterboolean"true"Send when Enter is pressed (Shift+Enter inserts newline).
showMicbooleanShow the mic button. Defaults to true if onMicClick is set.
showMicbooleanShow the mic button. Defaults to true if onMicClick is set.
onMicClick() => voidCallback when the mic button is clicked. Voice handling is delegated entirely to the consumer.
onMicClick() => voidCallback when the mic button is clicked. Voice handling is delegated entirely to the consumer.
isMicActivebooleanWhen true, the mic button shows a pulsing animation.
isMicActivebooleanWhen true, the mic button shows a pulsing animation.
emojiEmojiConfigEnable + configure the emoji picker, categories, custom emojis, and shortcode replacement.
emojiEmojiConfigEnable + configure the emoji picker, categories, custom emojis, and shortcode replacement.
attachmentsAttachmentDisplayConfigEnable + configure attachments: file types, max files, max size, display mode in completed messages, onAttach callback.
attachmentsAttachmentDisplayConfigEnable + configure attachments: file types, max files, max size, display mode in completed messages, onAttach callback.
headerChatHeaderConfigHeader config: title, subtitle, logo, colors, button visibility flags, menu items.
headerChatHeaderConfigHeader config: title, subtitle, logo, colors, button visibility flags, menu items.
renderHeader(ctx: HeaderCtx) => ReactNodeReplace the entire header with a custom render.
renderHeader(ctx: HeaderCtx) => ReactNodeReplace the entire header with a custom render.
iconsChatIconsOverride every built-in icon (minimize, close, restart, menu, send, mic, attach, emoji, bot, user, status icons).
iconsChatIconsOverride every built-in icon (minimize, close, restart, menu, send, mic, attach, emoji, bot, user, status icons).
tooltipsChatTooltipsTooltip text for every built-in icon button.
tooltipsChatTooltipsTooltip text for every built-in icon button.
onMinimize() => boolean | Promise<boolean>Fires when minimize is clicked. Return false to cancel.
onMinimize() => boolean | Promise<boolean>Fires when minimize is clicked. Return false to cancel.
onClose() => boolean | Promise<boolean>Fires when close is clicked. Return false to cancel. Consumer is expected to unmount.
onClose() => boolean | Promise<boolean>Fires when close is clicked. Return false to cancel. Consumer is expected to unmount.
onRestart() => boolean | Promise<boolean>Fires when restart is clicked. Return false to cancel.
onRestart() => boolean | Promise<boolean>Fires when restart is clicked. Return false to cancel.
isMinimizedbooleanControlled minimized state. When true, the window does not render.
isMinimizedbooleanControlled minimized state. When true, the window does not render.
headerSlotReactNodeCustom content rendered between the header and message body.
headerSlotReactNodeCustom content rendered between the header and message body.
aboveComposerSlotReactNodeCustom content rendered above the composer (suggestion chips, etc.).
aboveComposerSlotReactNodeCustom content rendered above the composer (suggestion chips, etc.).
belowComposerSlotReactNodeCustom content rendered below the composer (disclaimer, branding).
belowComposerSlotReactNodeCustom content rendered below the composer (disclaimer, branding).
showTimebooleanShow time under each message.
showTimebooleanShow time under each message.
showAvatarsboolean"true"Show avatar circles next to messages.
showAvatarsboolean"true"Show avatar circles next to messages.
customMessageTypesRecord<string, ComponentType>Plug-in custom message renderers keyed by type. Merged into the built-in template map.
customMessageTypesRecord<string, ComponentType>Plug-in custom message renderers keyed by type. Merged into the built-in template map.
messageActionsMessageActionsConfigPer-message action bar shown on hover/long-press. Consumer-driven items array.
messageActionsMessageActionsConfigPer-message action bar shown on hover/long-press. Consumer-driven items array.
reactionsReactionsConfigEmoji reactions on messages. Consumer maintains reactions on each message and gets onReact.
reactionsReactionsConfigEmoji reactions on messages. Consumer maintains reactions on each message and gets onReact.
feedbackFeedbackConfigThumbs up/down feedback on assistant messages. Optional askForComment flag.
feedbackFeedbackConfigThumbs up/down feedback on assistant messages. Optional askForComment flag.
replyReplyConfigEnable replies. Style: pinned (chip in composer only), quoted (embedded in new message), both.
replyReplyConfigEnable replies. Style: pinned (chip in composer only), quoted (embedded in new message), both.
typingUsersTypingUser[]List of users currently typing. Empty / undefined hides indicator.
typingUsersTypingUser[]List of users currently typing. Empty / undefined hides indicator.
showLoaderbooleanForce-show the typing dots loader (legacy single-bot mode).
showLoaderbooleanForce-show the typing dots loader (legacy single-bot mode).
onRetryMessage(messageId: string) => voidFires when the user clicks the failed-status icon to retry.
onRetryMessage(messageId: string) => voidFires when the user clicks the failed-status icon to retry.
draggablebooleanEnable dragging the window by the header. Disabled on mobile.
draggablebooleanEnable dragging the window by the header. Disabled on mobile.
resizablebooleanEnable resizing from any edge or corner. Disabled on mobile.
resizablebooleanEnable resizing from any edge or corner. Disabled on mobile.
persistboolean | 'session'true uses localStorage, 'session' uses sessionStorage, false/undefined disables persistence.
persistboolean | 'session'true uses localStorage, 'session' uses sessionStorage, false/undefined disables persistence.
persistKeystring"'fluxo-chat-window'"Storage key for persisted position and size.
persistKeystring"'fluxo-chat-window'"Storage key for persisted position and size.
defaultPosition{ x?: number; y?: number }Initial drag offset (only applies when draggable).
defaultPosition{ x?: number; y?: number }Initial drag offset (only applies when draggable).
defaultSize{ width?: number; height?: number }Initial size in pixels (only applies when resizable).
defaultSize{ width?: number; height?: number }Initial size in pixels (only applies when resizable).
minWidthnumber"320"Minimum window width in pixels.
minWidthnumber"320"Minimum window width in pixels.
minHeightnumber"420"Minimum window height in pixels.
minHeightnumber"420"Minimum window height in pixels.
maxWidthnumber | string"'95vw'"Maximum window width.
maxWidthnumber | string"'95vw'"Maximum window width.
maxHeightnumber | string"'95vh'"Maximum window height.
maxHeightnumber | string"'95vh'"Maximum window height.
themeChatTheme"'classic'"Visual theme: classic, modern, iris, dusk, mist, ember, canvas, prism, aurora.
themeChatTheme"'classic'"Visual theme: classic, modern, iris, dusk, mist, ember, canvas, prism, aurora.
colorMode'light' | 'dark' | 'auto'Force light or dark mode. Auto follows OS / theme defaults.
colorMode'light' | 'dark' | 'auto'Force light or dark mode. Auto follows OS / theme defaults.
cssVarsRecord<string, string>Override --euic-* CSS variables for primary, fonts, surfaces, etc.
cssVarsRecord<string, string>Override --euic-* CSS variables for primary, fonts, surfaces, etc.
classNamestringExtra class on the root container.
classNamestringExtra class on the root container.
styleCSSPropertiesExtra inline styles on the root container.
styleCSSPropertiesExtra inline styles on the root container.
align'bottomRight' | 'bottomLeft'"'bottomRight'"Anchor side when not draggable.
align'bottomRight' | 'bottomLeft'"'bottomRight'"Anchor side when not draggable.
spacingCornerstring"'5px'"Distance from the anchored corner edge.
spacingCornerstring"'5px'"Distance from the anchored corner edge.
spacingBottomstring"'5px'"Distance from the anchored bottom edge.
spacingBottomstring"'5px'"Distance from the anchored bottom edge.
ariaLabelstring"'Chat'"ARIA label for the window dialog.
ariaLabelstring"'Chat'"ARIA label for the window dialog.
announcementsboolean"true"Live-region announcements for new assistant messages.
announcementsboolean"true"Live-region announcements for new assistant messages.
trapFocusbooleanTrap focus inside the window. Defaults to true in fullscreen mode.
trapFocusbooleanTrap focus inside the window. Defaults to true in fullscreen mode.
shortcutsHelpboolean"true"Enable Ctrl+/ shortcuts help dialog.
shortcutsHelpboolean"true"Enable Ctrl+/ shortcuts help dialog.
fullscreenbooleanRender the window full-viewport.
fullscreenbooleanRender the window full-viewport.
noShadowbooleanRemove window shadow.
noShadowbooleanRemove window shadow.
noAnimationbooleanDisable open/close animations.
noAnimationbooleanDisable open/close animations.
fontFamilystringOverride the body font family.
fontFamilystringOverride the body font family.
widthnumber | stringExplicit width when not resizable.
widthnumber | stringExplicit width when not resizable.
heightnumber | stringExplicit height when not resizable.
heightnumber | stringExplicit height when not resizable.
Capabilities
Fully Controlled
You own the messages array. Send/receive/update is just state.
9 Themes Built-In
Classic, modern, iris, dusk, mist, ember, canvas, prism, aurora.
Light & Dark
Auto, light, or dark color mode — every theme adapts cleanly.
Reactions & Replies
Emoji reactions, threaded replies (pinned/quoted), message actions.
Attachments
Drag-and-drop files, accept filters, max size, custom display modes.
Emoji + Shortcodes
Built-in picker, recents, and live `:smile:` → 😄 replacement.
Drag & Resize
Move and resize the floating window; persist position to local/session storage.
Custom Templates
Plug in any message type via `customMessageTypes` keyed by `type`.
Accessibility
Trap-focus, ARIA labels, keyboard shortcuts, live announcements.