npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@molecule/app-message-bubble-react

v1.0.1

Published

React message bubble, composer, list, and thread indicator for chat UIs

Downloads

451

Readme

@molecule/app-message-bubble-react

Auto-generated, AI-first package reference for the molecule.dev ecosystem. It is written to be read by coding agents as much as by people, and is generated from this package's source — edit src/index.ts JSDoc, not this file.

React message/chat primitives.

Exports:

  • <MessageBubble> — one message (avatar + meta row + body + optional attachments/reactions/thread slots from message.attachments etc.). Props: message, isSelf?, showMeta?, className?.
  • <MessageMeta> — author · timestamp row.
  • <MessageAttachments attachments={[...]}> — attachment rows (icon + name · size + action slot).
  • <MessageReactions reactions={[...]} onToggle? onAdd?> — reaction-chip row.
  • <ThreadIndicator replyCount lastReplyAt? onOpen?> — "3 replies · …" footer.
  • <MessageList messages selfAuthorId? renderDateSeparator? emptyState?> — vertical list of bubbles.
  • <MessageComposer onSubmit placeholder? submitOnEnter? leading? trailing? disabled?> — textarea + Send button.
  • MessageData, MessageAuthor, MessageAttachment, MessageReaction types.

Quick Start

import { MessageComposer, MessageList } from '@molecule/app-message-bubble-react'
import type { MessageData } from '@molecule/app-message-bubble-react'

const messages: MessageData[] = [
  { id: '1', author: { id: 'u1', name: 'Alice', avatarSrc: '/alice.png' }, body: 'Hey there!', timestamp: '10:00' },
  { id: '2', author: { id: 'u2', name: 'Bob' }, body: 'Hi Alice!', timestamp: '10:01' },
]

<MessageList messages={messages} selfAuthorId="u1" />
<MessageComposer onSubmit={(text) => sendMessage(text)} />

Type

feature

Installation

npm install @molecule/app-message-bubble-react @molecule/app-react @molecule/app-ui @molecule/app-ui-react react
npm install -D @types/react

API

Interfaces

MessageAttachment

Describes a single file attachment rendered inside a message bubble.

interface MessageAttachment {
  id: string
  name: string
  /** Size label (e.g. "2.3 MB"). */
  size?: string
  /** Action slot — typically a download button. */
  action?: React.ReactNode
  /** Optional leading icon. */
  icon?: React.ReactNode
}

MessageAttachmentsProps

Props for {@link MessageAttachments}.

interface MessageAttachmentsProps {
  attachments: MessageAttachment[]
  /** Extra classes on the outer wrapper. */
  className?: string
}

MessageAuthor

Message / chat types.

interface MessageAuthor {
  /** Author id — used to derive `role` (self vs other) in rendering. */
  id: string
  /** Display name. */
  name: string
  /** Optional avatar URL. */
  avatarSrc?: string
}

MessageBubbleProps

Props for {@link MessageBubble}.

interface MessageBubbleProps {
  message: MessageData
  /** Whether the current viewer is the message author (affects alignment + accent). */
  isSelf?: boolean
  /** Render the author row (avatar + name + time). Defaults to true. */
  showMeta?: boolean
  /** Extra classes. */
  className?: string
}

MessageComposerProps

Props for {@link MessageComposer}.

interface MessageComposerProps {
  /** Called when the user submits. */
  onSubmit: (value: string) => void
  /** Optional placeholder. */
  placeholder?: string
  /** Whether Ctrl/Cmd-Enter submits. Defaults to true. */
  submitOnEnter?: boolean
  /** Optional leading slot (e.g. attachment button). */
  leading?: ReactNode
  /** Optional trailing slot rendered before the submit button. */
  trailing?: ReactNode
  /** Disable input + submit. */
  disabled?: boolean
  /** Extra classes. */
  className?: string
}

MessageData

Data shape for a single chat message rendered by the bubble component.

interface MessageData {
  id: string
  author: MessageAuthor
  /** Message body — typically plain text, but can be a ReactNode for rich content. */
  body: ReactNode
  /** ISO timestamp or any node to render as "time ago". */
  timestamp: ReactNode
  /** Optional attachments list (rendered below the body). */
  attachments?: ReactNode
  /** Optional reactions row. */
  reactions?: ReactNode
  /** Optional thread-indicator (reply count + last reply time). */
  thread?: ReactNode
}

MessageListProps

Props for {@link MessageList}.

interface MessageListProps {
  messages: MessageData[]
  /** When provided, viewer-authored messages flip alignment to the right. */
  selfAuthorId?: string
  /** Optional date separator renderer (receives the current message). */
  renderDateSeparator?: (message: MessageData, i: number) => ReactNode
  /** Empty-state node when `messages` is empty. */
  emptyState?: ReactNode
  /** Extra classes. */
  className?: string
}

MessageMetaProps

Props for {@link MessageMeta}.

interface MessageMetaProps {
  /** Author display name. */
  author: ReactNode
  /** Timestamp display. */
  timestamp: ReactNode
  /** Extra classes. */
  className?: string
}

MessageReaction

A single emoji reaction with its count and current-user state.

interface MessageReaction {
  /** Emoji or symbol. */
  emoji: string
  /** Reaction count. */
  count: number
  /** Whether the current user reacted. */
  reactedByMe?: boolean
}

MessageReactionsProps

Props for {@link MessageReactions}.

interface MessageReactionsProps {
  reactions: MessageReaction[]
  /** Called when a reaction chip is toggled. */
  onToggle?: (emoji: string) => void
  /** Called when the "+" button is clicked. */
  onAdd?: () => void
  /** Extra classes. */
  className?: string
}

ThreadIndicatorProps

Props for {@link ThreadIndicator}.

interface ThreadIndicatorProps {
  /** Number of replies. */
  replyCount: number
  /** Last-reply timestamp display. */
  lastReplyAt?: ReactNode
  /** Called when clicked. */
  onOpen?: () => void
  /** Extra classes. */
  className?: string
}

Functions

MessageAttachments(props)

Vertical list of attachment rows below a message body. Each row: [icon] [name · size] [action].

function MessageAttachments({ attachments, className }: MessageAttachmentsProps): JSX.Element
  • props — Component props (see {@link MessageAttachmentsProps}).

MessageBubble(props)

One message in a chat thread — avatar, author/timestamp row, body, plus optional attachments/reactions/thread indicator passed in via message.attachments / message.reactions / message.thread.

isSelf flips the row direction so the viewer's own messages appear on the right — no bubble background/tint is applied; style the body via className if you want classic chat bubbles.

function MessageBubble({
  message,
  isSelf,
  showMeta = true,
  className,
}: MessageBubbleProps): JSX.Element
  • props — Component props (see {@link MessageBubbleProps}).

MessageComposer(props)

Message input row — text area + optional leading/trailing slots + submit button.

function MessageComposer({
  onSubmit,
  placeholder,
  submitOnEnter = true,
  leading,
  trailing,
  disabled,
  className,
}: MessageComposerProps): JSX.Element
  • props — Component props (see {@link MessageComposerProps}).

MessageList(props)

Vertical list of <MessageBubble>s with optional date separators.

function MessageList({
  messages,
  selfAuthorId,
  renderDateSeparator,
  emptyState,
  className,
}: MessageListProps): JSX.Element
  • props — Component props (see {@link MessageListProps}).

MessageMeta(props)

Small [author · timestamp] row rendered above a message body. Broken out so apps can reuse it in notification rows, quote blocks, etc.

function MessageMeta({ author, timestamp, className }: MessageMetaProps): JSX.Element
  • props — Component props (see {@link MessageMetaProps}).

MessageReactions(props)

Row of reaction chips below a message body. Each chip shows emoji + count; when the current user reacted the chip is marked with aria-pressed only — no visual highlight ships.

function MessageReactions({
  reactions,
  onToggle,
  onAdd,
  className,
}: MessageReactionsProps): JSX.Element
  • props — Component props (see {@link MessageReactionsProps}).

ThreadIndicator(props)

"3 replies · last Monday" indicator rendered below a message bubble. Clicking opens the thread view.

function ThreadIndicator({
  replyCount,
  lastReplyAt,
  onOpen,
  className,
}: ThreadIndicatorProps): JSX.Element
  • props — Component props (see {@link ThreadIndicatorProps}).

Injection Notes

Requirements

Peer dependencies:

  • @molecule/app-react ^1.0.1
  • @molecule/app-ui ^1.0.1
  • @molecule/app-ui-react ^1.0.1
  • react ^18.0.0 || ^19.0.0

Runtime Dependencies

  • @molecule/app-react

  • @molecule/app-ui

  • @molecule/app-ui-react

  • react

  • isSelf (or MessageList.selfAuthorId) only right-aligns the row — there is no built-in bubble background/tint. Style the body via className (or wrap message.body) if you want classic chat bubbles.

  • timestamp renders exactly what you pass — no time-ago or date formatting. Pre-format ("2m ago", "10:01") before passing; raw ISO strings display as-is.

  • The composer submits on the Send button or Ctrl/Cmd+Enter (submitOnEnter), NOT plain Enter; it trims and clears on submit and blocks empty sends.

  • Composer strings route through t() (composer.placeholder, composer.send) with the @molecule/app-locales-message-bubble companion bond; ThreadIndicator uses thread.replies, which that bond does not yet ship — it falls back to English.

  • MessageReactions marks the viewer's own reaction with aria-pressed only — no visual highlight ships.

  • Requires wired i18n (useTranslation) and a ClassMap bond; Avatar/Button/ Textarea come from @molecule/app-ui-react.

Translations

Translation strings are provided by @molecule/app-locales-message-bubble.