Message

ui-message is one row of a conversation. It places an avatar next to a column with an optional header (name), the message content (usually one or more ui-bubble elements) and an optional footer (time or status). align="end" mirrors the row for messages sent by the current user. The avatar moves to the end and the content aligns right.

The avatar, header and footer are child parts: ui-message-avatar, ui-message-header and ui-message-footer. They place themselves, so source order does not matter for them. Everything else is the message content.

Previewindex.html
OM Olivia Martin Hi, how can I help you today? 10:02 ME I cannot sign in to my account. 10:03 · Read
<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Message demo</title>
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@realmorg/realm@alpha/dist/realm.css">
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@realmorg/ui@alpha/dist/theme.css">
  <script type="module" src="https://cdn.jsdelivr.net/npm/@realmorg/realm@alpha/dist/realm.js"></script>
  <style>
    .demo-medium {
      width: min(100%, calc(var(--spacing) * 120));
    }
    .demo-stack {
      display: grid;
      gap: calc(var(--spacing) * 4);
    }
  </style>
</head>
<body>
  <import-element from="https://cdn.jsdelivr.net/npm/@realmorg/ui@alpha/components/avatar.html"></import-element>
  <import-element from="https://cdn.jsdelivr.net/npm/@realmorg/ui@alpha/components/bubble.html"></import-element>
  <import-element from="https://cdn.jsdelivr.net/npm/@realmorg/ui@alpha/components/message.html"></import-element>

  <div class="demo-medium demo-stack">
    <ui-message>
      <ui-message-avatar>
        <ui-avatar><ui-avatar-fallback>OM</ui-avatar-fallback></ui-avatar>
      </ui-message-avatar>
      <ui-message-header>Olivia Martin</ui-message-header>
      <ui-bubble variant="muted">Hi, how can I help you today?</ui-bubble>
      <ui-message-footer>10:02</ui-message-footer>
    </ui-message>
    <ui-message align="end">
      <ui-message-avatar>
        <ui-avatar><ui-avatar-fallback>ME</ui-avatar-fallback></ui-avatar>
      </ui-message-avatar>
      <ui-bubble align="end">I cannot sign in to my account.</ui-bubble>
      <ui-message-footer>10:03 · Read</ui-message-footer>
    </ui-message>
  </div>
</body>
</html>

Examples

Several bubbles in one message

The content column stacks its children with a gap, so consecutive bubbles from the same sender go in one ui-message.

Previewindex.html
JL Jackson Lee The new build is up. Release notes are in the usual place.
<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Message demo</title>
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@realmorg/realm@alpha/dist/realm.css">
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@realmorg/ui@alpha/dist/theme.css">
  <script type="module" src="https://cdn.jsdelivr.net/npm/@realmorg/realm@alpha/dist/realm.js"></script>
  <style>
    .demo-medium {
      width: min(100%, calc(var(--spacing) * 120));
    }
  </style>
</head>
<body>
  <import-element from="https://cdn.jsdelivr.net/npm/@realmorg/ui@alpha/components/attachment.html"></import-element>
  <import-element from="https://cdn.jsdelivr.net/npm/@realmorg/ui@alpha/components/avatar.html"></import-element>
  <import-element from="https://cdn.jsdelivr.net/npm/@realmorg/ui@alpha/components/bubble.html"></import-element>
  <import-element from="https://cdn.jsdelivr.net/npm/@realmorg/ui@alpha/components/message.html"></import-element>

  <div class="demo-medium">
    <ui-message>
      <ui-message-avatar>
        <ui-avatar><ui-avatar-fallback>JL</ui-avatar-fallback></ui-avatar>
      </ui-message-avatar>
      <ui-message-header>Jackson Lee</ui-message-header>
      <ui-bubble variant="muted">The new build is up.</ui-bubble>
      <ui-bubble variant="muted">Release notes are in the usual place.</ui-bubble>
      <ui-attachment name="release-notes.pdf" size="84 KB" href="data:text/plain,Release%20notes">
        <ui-attachment-media>
          <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true"><path d="M14 3H6v18h12V7Z" /><path d="M14 3v4h4" /></svg>
        </ui-attachment-media>
      </ui-attachment>
    </ui-message>
  </div>
</body>
</html>

Assistant reply

A ghost bubble without an avatar suits long-form replies.

Previewindex.html
Assistant To reset your password, open Settings, choose Security and click Reset password. A link is sent to your email address and stays valid for one hour.
<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Message demo</title>
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@realmorg/realm@alpha/dist/realm.css">
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@realmorg/ui@alpha/dist/theme.css">
  <script type="module" src="https://cdn.jsdelivr.net/npm/@realmorg/realm@alpha/dist/realm.js"></script>
  <style>
    .demo-medium {
      width: min(100%, calc(var(--spacing) * 120));
    }
  </style>
</head>
<body>
  <import-element from="https://cdn.jsdelivr.net/npm/@realmorg/ui@alpha/components/bubble.html"></import-element>
  <import-element from="https://cdn.jsdelivr.net/npm/@realmorg/ui@alpha/components/message.html"></import-element>

  <div class="demo-medium">
    <ui-message>
      <ui-message-header>Assistant</ui-message-header>
      <ui-bubble variant="ghost">To reset your password, open Settings, choose Security and click Reset password. A link
        is sent to your email address and stays valid for one hour.</ui-bubble>
    </ui-message>
  </div>
</body>
</html>

API

Parts

Part Slot Renders
ui-message (root) The row, with the avatar beside a column with header, content and footer.
ui-message-avatar avatar Wraps a ui-avatar, aligned to the bottom of the row.
ui-message-header header A small muted line above the content, such as the sender name and time.
ui-message-footer footer A small muted line below the content, such as the time or a read receipt.

The parts set their own slot, so they go directly inside ui-message with no attributes. Any other child (bubbles, attachments, code blocks) is the message content. The default slot of each part takes any content.

Attributes

Attribute Type Default Description
align "start" | "end" "start" end reverses the row and aligns the content to the end.

CSS parts

Part Description
content The column with the header, content and footer.

Accessibility

ui-message adds no roles. Screen readers read the header, content and footer in source order, so put the sender name in ui-message-header rather than relying on the avatar.

Edit this page on GitHub · View as Markdown