An open API service indexing awesome lists of open source software.

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 />

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