https://github.com/bbb0ttle/bb-msg-history
<bb-msg-history />
https://github.com/bbb0ttle/bb-msg-history
Last synced: 3 months ago
JSON representation
<bb-msg-history />
- Host: GitHub
- URL: https://github.com/bbb0ttle/bb-msg-history
- Owner: bbb0ttle
- Created: 2026-02-24T13:05:44.000Z (4 months ago)
- Default Branch: main
- Last Pushed: 2026-03-10T14:33:18.000Z (3 months ago)
- Last Synced: 2026-04-04T05:45:36.264Z (3 months ago)
- Language: TypeScript
- Homepage: https://bbb0ttle.github.io/bb-msg-history/
- Size: 290 KB
- Stars: 0
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# bb-msg-history
Chat-style message history web component. Render conversations from plain text, with avatars, bubbles, and smooth animations.
## Install
```bash
npm install @bbki.ng/bb-msg-history
```
CDN:
```html
```
## Usage
Place messages inside the element using the `author: text` format, one per line:
```html
alice: Hey, are you free this weekend?
bob: Sounds good! When?
alice: Saturday morning, around 10?
bob: Perfect. See you then!
```
## Message Format
Each message is a line with the author name, a colon, and the 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:
```js
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: '
',
side: 'left',
bubbleColor: '#e0f2fe',
});
// SVG avatar
el.setAuthor('alice', {
avatar: '...',
side: 'left',
});
```
### `setAuthor(name, options)`
| Option | Type | Default | Description |
|--------|------|---------|-------------|
| `avatar` | `string` | letter avatar | HTML string: emoji, `
`, ``, 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:
```js
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 |
```js
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 |
```js
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:
```html
alice: Loading previous messages...
```
### `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
```html
alice: First message
bob: Second message
alice: Third message
```
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 |
```css
bb-msg-history {
--bb-max-height: 400px;
}
```
### Manual Registration
By default, the component auto-registers as ``. You can also register manually with a custom tag name:
```js
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, `
`, ``, 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 `
` when Custom Elements are unsupported
## Examples
### Basic
```html
alice: Hey, are you free this weekend?
bob: Sounds good! When?
alice: Saturday morning, around 10?
bob: Perfect. See you then!
```
### Custom avatars
```html
me: Hey there!
friend: What's up?
const el = document.getElementById('chat');
el.setAuthor('me', { avatar: '🐱', side: 'right', bubbleColor: '#f3f4f6' });
el.setAuthor('friend', { avatar: '🐶', side: 'left', bubbleColor: '#e0f2fe' });
```
### Consecutive messages — avatar grouping
When the same author sends multiple messages in a row, the avatar is only shown on the first one:
```html
alice: First message
alice: Second message, avatar hidden
alice: Third, still hidden
bob: Got it!
bob: I'll send two as well
```
### Unknown authors — letter avatars
Authors without custom config receive a letter avatar and appear on the left:
```html
alice: Hello!
bob: Hi there!
charlie: Hey everyone!
```
### Empty state
When no messages are provided, a "No messages" placeholder is shown:
```html
```
### Dynamic message appending
Use `appendMessage()` to add messages programmatically with smooth scrolling:
```html
alice: Hey there!
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);
```
### Loading state
Show a loading animation while fetching messages from an API:
```html
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 });
});
});
```
### Full page example
```html
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!
const el = document.getElementById('chat');
el.setAuthor('alice', { avatar: '👩', side: 'right' });
el.setAuthor('bob', { avatar: '👨', side: 'left', bubbleColor: '#ecfdf5' });
```
See `example/` directory for a full demo.
## Development
```bash
npm install
npm run prepare
```
## License
MIT