ChatWidget
A floating, expandable chat panel that preserves its conversation and draft while minimized.
Live TypeScript example
Try the component here, then use the source below in your application.
- JavaScript
- 7.0 KiB
- Component CSS
- 3.1 KiB
- Shared theme CSS
- 3.8 KiBonce per application
How sizes are measured
The JavaScript figure includes this component’s required helpers. CSS includes its styling dependencies. Each entry is bundled separately for ES2022, minified, then compressed with gzip level 9. Your bundler may share helpers across components. Images, fonts, examples and application code are excluded.
Before compression: JavaScript 18.4 KiB; component CSS 13.5 KiB. These figures describe browser assets, not the complete package download.
View all component measurements →Open, minimize or expand the assistant. Drafts survive closing. Responses are simulated locally.
import '@blukavantui/web/theme.css'
import {createChatWidget, type BluChatMessage} from '@blukavantui/web/chat-widget';
import '@blukavantui/web/chat-widget.css';
export function mount(host:HTMLElement) {
const stage=document.createElement('div');
stage.style.cssText='position:relative;container-type:inline-size;width:100%;min-width:0;min-height:700px;';
const hint=document.createElement('p');hint.textContent='Local demonstration. Connect your own assistant through Send, Retry and Stop.';
host.append(stage,hint);
let messages:BluChatMessage[]=[],timer:ReturnType<typeof setTimeout>|undefined,active='',dead=false;
const chat=createChatWidget(stage,{Title:'BluKavantUI assistant',Messages:messages,Suggestions:[
{Key:'start',Label:'What can you do?',Text:'What can you do?'},
{Key:'connect',Label:'Connect my assistant',Text:'How do I connect an assistant?'},
],Animate:true,Position:'Container',IsOpen:true,UnreadCount:2}, {
Send:(id,text)=>respond(id,text,false),Retry:(id,text)=>respond(id,text,true),
Stop:()=>{active='';clearTimeout(timer);},
});
function respond(id:string,text:string,retry:boolean) {
active=id;clearTimeout(timer);
if(!retry)messages=[...messages,{Key:id+'-user',Role:'User',Content:text}];
chat.update({Messages:messages,Status:'Waiting',ResponseRequestId:id});
// Replace this sample timer with your application transport. Keep server API
// credentials on the server. Echo this request ID on every response update.
const answer='This is a **local demo response**. Your app can supply messages from any assistant.\n\n- Streaming updates\n- Stop and retry\n- The same UI on web and OutSystems';
const reply:BluChatMessage={Key:id+'-assistant',Role:'Assistant',Content:''};
let offset=0;
timer=setTimeout(function tick(){
if(dead||active!==id)return;
if(!offset)messages=[...messages,reply];
offset+=12;reply.Content=answer.slice(0,offset);
chat.update({Messages:[...messages],Status:offset>=answer.length?'Idle':'Streaming',ResponseRequestId:id});
if(offset<answer.length)timer=setTimeout(tick,55);
},500);
}
return {destroy(){dead=true;active='';clearTimeout(timer);chat.destroy();stage.remove();hint.remove();}};
}
const instance = mount(document.getElementById('example')!)
// When this page or framework component is removed:
// instance.destroy()
Install the library and add the host element
npm install https://blukavantui.blutekmedia.com/downloads/blukavantui-web-0.6.2.tgz<div id="example"></div>This example uses the downloadable @blukavantui/web package. Your application handles persistence and authentication through its typed callbacks. The starter ZIP includes this same example.
createChatWidget
Supply Messages and handle Send, Retry and Stop as with Chat. The widget also owns its launcher and open state; content remains mounted when minimized.
import { createChatWidget } from '@blukavantui/web/chat-widget';
import '@blukavantui/web/chat-widget.css';Load @blukavantui/web/theme.css once in your app shell.createChatWidget(host: HTMLElement, options?: ChatWidgetOptions, events?: ChatWidgetEvents)Reference for @blukavantui/web 0.6.2. Required and optional follow the shipped TypeScript declarations; optional does not imply a particular default. Pass typed arrays and objects directly where shown.
Options
31| Name | Type / requirement | Usage |
|---|---|---|
IsOpen | booleanOptional | |
IsExpanded | booleanOptional | The current expanded state of the controlled region. |
UnreadCount | numberOptional | |
LauncherLabel | stringOptional | |
Position | 'Viewport' | 'Container'Optional | |
Placement | 'BottomRight' | 'BottomLeft'Optional | |
Offset | numberOptional | |
Color | ComponentColorOptional | A shared ComponentColor name. Colors adapt to the active appearance. |
Messages | BluChatMessage[]Optional | |
Suggestions | BluChatSuggestion[]Optional | |
Title | stringOptional | The displayed title. |
Subtitle | stringOptional | |
AssistantName | stringOptional | |
AccessibleLabel | stringOptional | Accessible name for assistive technology. |
WelcomeTitle | stringOptional | |
WelcomeMessage | stringOptional | |
Placeholder | stringOptional | |
Height | numberOptional | |
MaxLength | numberOptional | |
Status | ChatStatusOptional | |
ErrorMessage | stringOptional | |
ResponseRequestId | stringOptional | Echo the request ID from Send/Retry for every response update. Stale IDs are ignored. |
ResetKey | stringOptional | Change this to load a different conversation and invalidate pending responses. |
ShowHeader | booleanOptional | |
ShowAvatars | booleanOptional | |
ShowTimestamps | booleanOptional | |
EnableMarkdown | booleanOptional | |
AllowCopy | booleanOptional | |
IsDisabled | booleanOptional | Disables interaction with this component. |
Animate | booleanOptional | |
ExtendedClass | stringOptional | Additional CSS class names on the component root. |
Callbacks
7| Name | Type / requirement | Usage |
|---|---|---|
OpenChanged | (isOpen: boolean, reason: "Launcher" | "Close" | "Escape") => unknownOptional | |
ExpandedChanged | (isExpanded: boolean) => unknownOptional | |
Send | (requestId: string, text: string) => unknownOptional | |
Retry | (requestId: string, text: string) => unknownOptional | |
Stop | (requestId: string) => unknownOptional | |
Copy | (messageKey: string) => unknownOptional | |
Error | (message: string) => unknownOptional |
Instance methods & properties
3| Name | Signature / type | Usage |
|---|---|---|
element | HTMLElement | Root owned by this instance. Dispose before removing its host. |
update | (patch: Partial<ChatWidgetOptions>) => void | Apply a partial options update to this instance. |
destroy | () => void | Dispose the instance and its listeners when the view is removed. |
Related data types
Expand a type for its fields and allowed values.
BluChatMessage
interface BluChatMessage {
Key: string;
Role: 'User' | 'Assistant' | 'System';
Content: string;
Name?: string;
AvatarUrl?: string;
Timestamp?: string;
}BluChatSuggestion
interface BluChatSuggestion {
Key: string;
Label: string;
Text: string;
}ChatEvents
interface ChatEvents {
Send?: (requestId: string, text: string) => unknown;
Retry?: (requestId: string, text: string) => unknown;
Stop?: (requestId: string) => unknown;
Copy?: (messageKey: string) => unknown;
Error?: (message: string) => unknown;
}ChatOptions
interface ChatOptions {
Messages?: BluChatMessage[];
Suggestions?: BluChatSuggestion[];
Title?: string;
Subtitle?: string;
AssistantName?: string;
AccessibleLabel?: string;
WelcomeTitle?: string;
WelcomeMessage?: string;
Placeholder?: string;
Height?: number;
MaxLength?: number;
Status?: ChatStatus;
ErrorMessage?: string;
/** Echo the request ID from Send/Retry for every response update. Stale IDs are ignored. */
ResponseRequestId?: string;
/** Change this to load a different conversation and invalidate pending responses. */
ResetKey?: string;
ShowHeader?: boolean;
ShowAvatars?: boolean;
ShowTimestamps?: boolean;
EnableMarkdown?: boolean;
AllowCopy?: boolean;
IsDisabled?: boolean;
Animate?: boolean;
ExtendedClass?: string;
}ChatStatus
type ChatStatus = 'Idle' | 'Waiting' | 'Streaming' | 'Error';ComponentColor
type ComponentColor = typeof componentColors[number];Use these inputs, events, actions and structures in Service Studio. Names and data bindings are specific to the native Blocks.
Included in the planned free BluKavantUI Community edition. The official OutSystems Forge release is coming soon. View Community scope →
Open OutSystems showcase ↗- Web runtime
- Partially supported
- TypeScript
- Partially supported
- OutSystems
- Partially supported
Statuses describe the component’s rendered code and interactions. Supply accessible content and follow the component guidance when integrating it.
Accessibility guidance →Purpose and use
A floating, expandable chat panel that preserves its conversation and draft while minimized.
Keyboard design guidance
Enter sends, Shift+Enter inserts a new line. Escape minimizes the widget and returns focus to its launcher. Streaming updates preserve focus and are announced at completion. All animation honors reduced motion.
See the support status above for review coverage and any limitations.
In your application
Provide useful labels, preserve visible focus, and test the component with your actual content. Use text alongside status colors and check contrast in each state.
Events0No events yet.
Interact with an example to see its events.