Skip to content

bbb0ttle/bb-msg-history

Repository files navigation

bb-msg-history

Chat-style message history web component. Render conversations from plain text, with avatars, bubbles, and smooth animations.

Install

npm install @bbki.ng/bb-msg-history

CDN:

<script type="module" src="https://cdn.jsdelivr.net/npm/@bbki.ng/bb-msg-history@latest/dist/index.js"></script>

Usage

Place messages inside the element using the author: text format, one per line:

<bb-msg-history>
  alice: Hey, are you free this weekend?
  bob: Sounds good! When?
  alice: Saturday morning, around 10?
  bob: Perfect. See you then!
</bb-msg-history>

Message Format

Each message is a line with the author name, a colon, and the message text:

<author>: <message text>

Blank lines and lines without a colon are ignored.

Author Avatars

By default, every author gets a letter avatar (first character of their name) and appears on the left side.

Use the setAuthor() method to customize avatar, side, bubble color, and text color:

const el = document.querySelector('bb-msg-history');

// Emoji avatar, right side
el.setAuthor('me', { avatar: '🐱', side: 'right' });

// Image avatar, custom bubble color
el.setAuthor('bot', {
  avatar: '<img src="bot.png" width="28" height="28" />',
  side: 'left',
  bubbleColor: '#e0f2fe',
});

// SVG avatar
el.setAuthor('alice', {
  avatar: '<svg viewBox="0 0 48 48">...</svg>',
  side: 'left',
});

setAuthor(name, options)

Option Type Default Description
avatar string letter avatar HTML string: emoji, <img>, <svg>, or text
side 'left' | 'right' 'left' Which side the bubbles appear on
bubbleColor string '#f9fafb' Bubble background color
textColor string '#111827' Text color inside bubble

Returns this for chaining:

el.setAuthor('me', { avatar: '🐱', side: 'right' })
  .setAuthor('you', { avatar: '🐶', side: 'left' });

Fuzzy matching: if an author name contains a configured key (e.g. you configured "alice" and the message is from "alice(phone)"), the config is reused.

Use removeAuthor(name) to remove a custom config.

appendMessage(message)

Append a message programmatically with smooth scroll to the new message.

Parameter Type Description
message.author string The author name
message.text string The message text
el.appendMessage({ author: 'alice', text: 'Hello!' });
el.appendMessage({ author: 'bob', text: 'How are you?' });

Returns this for chaining. This is ideal for chat applications where messages arrive in real-time.

Note: Unlike modifying textContent directly, appendMessage() scrolls smoothly to the newly added message.

setLoading(isLoading)

Show or hide a loading animation overlay. Useful when fetching messages from an API.

Parameter Type Description
isLoading boolean true to show loading, false to hide
const el = document.querySelector('bb-msg-history');

// Show loading
el.setLoading(true);

// Fetch messages
fetchMessages().then(messages => {
  // Hide loading and display messages
  el.setLoading(false);
});

You can also use the HTML attribute:

<bb-msg-history loading>
  alice: Loading previous messages...
</bb-msg-history>

infinite Attribute

Remove the height constraint and disable scrolling on the component. The container expands to fit all messages.

Use this when:

  • The parent container handles scrolling
  • You want to display an entire conversation without height limits
  • You need the component to be part of a larger scrollable area
<bb-msg-history infinite>
  alice: First message
  bob: Second message
  alice: Third message
  <!-- Container keeps expanding to fit all messages -->
</bb-msg-history>

In infinite mode:

  • No max-height constraint is applied
  • No scrollbar appears on the component
  • The scroll-to-bottom button is hidden (not needed)

Customization

CSS Custom Properties

Property Default Description
--bb-max-height 600px Maximum height of the message container
bb-msg-history {
  --bb-max-height: 400px;
}

Manual Registration

By default, the component auto-registers as <bb-msg-history>. You can also register manually with a custom tag name:

import { BBMsgHistory, define } from '@bbki.ng/bb-msg-history';

// Register with default tag name
define();

// Or use a custom tag name
define('my-chat-history');

Features

  • Plain-text message format — no JSON or attributes needed
  • Left/right bubble layout based on author
  • Customizable avatars: emoji, <img>, <svg>, or letter avatars
  • Hover tooltip showing the author name
  • Consecutive messages from the same author are grouped (avatar hidden)
  • Auto-scroll to the latest message on render
  • appendMessage() API — programmatically add messages with smooth scroll
  • setLoading() API — show loading animation while fetching messages
  • Long text word-wrap and overflow handling
  • Empty state when no messages are provided
  • Dark mode support via prefers-color-scheme
  • Mobile responsive layout
  • prefers-reduced-motion support
  • Reactive: automatically re-renders when content changes
  • Customizable max-height via --bb-max-height CSS custom property
  • infinite attribute — remove height constraints for parent-controlled scrolling
  • Graceful degradation to <pre> when Custom Elements are unsupported

Examples

Basic

<bb-msg-history>
  alice: Hey, are you free this weekend?
  bob: Sounds good! When?
  alice: Saturday morning, around 10?
  bob: Perfect. See you then!
</bb-msg-history>

Custom avatars

<bb-msg-history id="chat">
  me: Hey there!
  friend: What's up?
</bb-msg-history>

<script>
  const el = document.getElementById('chat');
  el.setAuthor('me', { avatar: '🐱', side: 'right', bubbleColor: '#f3f4f6' });
  el.setAuthor('friend', { avatar: '🐶', side: 'left', bubbleColor: '#e0f2fe' });
</script>

Consecutive messages — avatar grouping

When the same author sends multiple messages in a row, the avatar is only shown on the first one:

<bb-msg-history>
  alice: First message
  alice: Second message, avatar hidden
  alice: Third, still hidden
  bob: Got it!
  bob: I'll send two as well
</bb-msg-history>

Unknown authors — letter avatars

Authors without custom config receive a letter avatar and appear on the left:

<bb-msg-history>
  alice: Hello!
  bob: Hi there!
  charlie: Hey everyone!
</bb-msg-history>

Empty state

When no messages are provided, a "No messages" placeholder is shown:

<bb-msg-history></bb-msg-history>

Dynamic message appending

Use appendMessage() to add messages programmatically with smooth scrolling:

<bb-msg-history id="chat" style="--bb-max-height: 300px;">
  alice: Hey there!
</bb-msg-history>

<script>
  const el = document.getElementById('chat');
  el.setAuthor('alice', { avatar: '👩', side: 'right' });
  el.setAuthor('bob', { avatar: '👨', side: 'left' });

  // Add messages dynamically with smooth scroll
  el.appendMessage({ author: 'bob', text: 'Hello! How are you?' });
  el.appendMessage({ author: 'alice', text: 'I\'m doing great!' });
  
  // Simulate receiving a message after 2 seconds
  setTimeout(() => {
    el.appendMessage({ author: 'bob', text: 'Nice to hear that!' });
  }, 2000);
</script>

Loading state

Show a loading animation while fetching messages from an API:

<bb-msg-history id="chat" loading>
  <!-- Messages will be loaded -->
</bb-msg-history>

<script>
  const el = document.getElementById('chat');

  // Show loading (already set via HTML attribute above)
  // el.setLoading(true);

  // Fetch messages from API
  fetch('/api/messages')
    .then(res => res.json())
    .then(messages => {
      // Hide loading and populate messages
      el.setLoading(false);
      messages.forEach(msg => {
        el.appendMessage({ author: msg.author, text: msg.text });
      });
    });
</script>

Full page example

<!DOCTYPE html>
<html>
<head>
  <script type="module" src="https://cdn.jsdelivr.net/npm/@bbki.ng/bb-msg-history@latest/dist/index.js"></script>
</head>
<body>
  <bb-msg-history id="chat">
    alice: Hey, are you free this weekend?
    bob: Yeah, what's up?
    alice: Want to grab coffee?
    bob: Sounds good! Saturday morning?
    alice: Perfect, see you then!
  </bb-msg-history>

  <script>
    const el = document.getElementById('chat');
    el.setAuthor('alice', { avatar: '👩', side: 'right' });
    el.setAuthor('bob', { avatar: '👨', side: 'left', bubbleColor: '#ecfdf5' });
  </script>
</body>
</html>

See example/ directory for a full demo.

Development

npm install
npm run prepare

License

MIT

About

<bb-msg-history />

Resources

Stars

Watchers

Forks

Packages

 
 
 

Contributors