message

Displays a message in a conversation, with optional avatar, header, footer, and alignment.

PreviousNext
SR @srizzonDeploying to prod real quick. LG @luizgomessIt's 4:55 PM. On a Friday. SR @srizzonIt's a one-line change.Delivered LG @luizgomessIt's always a one-line change 😭.Alright, let me take a look.👍
import { ChangeDetectionStrategy, Component } from '@angular/core';

import { ZardAvatarComponent } from '@/shared/components/avatar';
import { ZardBubbleImports } from '@/shared/components/bubble/bubble.imports';
import { ZardMessageImports } from '@/shared/components/message/message.imports';

@Component({
  selector: 'z-demo-message-default',
  imports: [ZardAvatarComponent, ...ZardBubbleImports, ...ZardMessageImports],
  template: `
    <div class="flex w-full max-w-sm flex-col gap-6 py-12">
      <z-message zAlign="end">
        <z-message-avatar>
          <z-avatar zSrc="https://github.com/srizzon.png" zAlt="@srizzon" zFallback="SR" />
        </z-message-avatar>
        <z-message-content>
          <z-bubble>
            <z-bubble-content>Deploying to prod real quick.</z-bubble-content>
          </z-bubble>
        </z-message-content>
      </z-message>

      <z-message>
        <z-message-avatar>
          <z-avatar zSrc="https://github.com/Luizgomess.png" zAlt="@luizgomess" zFallback="LG" />
        </z-message-avatar>
        <z-message-content>
          <z-bubble zVariant="muted">
            <z-bubble-content>It's 4:55 PM. On a Friday.</z-bubble-content>
          </z-bubble>
        </z-message-content>
      </z-message>

      <z-message zAlign="end">
        <z-message-avatar>
          <z-avatar zSrc="https://github.com/srizzon.png" zAlt="@srizzon" zFallback="SR" />
        </z-message-avatar>
        <z-message-content>
          <z-bubble>
            <z-bubble-content>It's a one-line change.</z-bubble-content>
          </z-bubble>
          <z-message-footer>Delivered</z-message-footer>
        </z-message-content>
      </z-message>

      <z-message>
        <z-message-avatar>
          <z-avatar zSrc="https://github.com/Luizgomess.png" zAlt="@luizgomess" zFallback="LG" />
        </z-message-avatar>
        <z-message-content>
          <z-bubble-group>
            <z-bubble zVariant="muted">
              <z-bubble-content>It's always a one-line change 😭.</z-bubble-content>
            </z-bubble>
            <z-bubble zVariant="muted">
              <z-bubble-content>Alright, let me take a look.</z-bubble-content>
              <z-bubble-reactions role="img" aria-label="Reactions: thumbs up">
                <span>👍</span>
              </z-bubble-reactions>
            </z-bubble>
          </z-bubble-group>
        </z-message-content>
      </z-message>
    </div>
  `,
  changeDetection: ChangeDetectionStrategy.OnPush,
  host: { class: 'contents' },
})
export class ZardDemoMessageDefaultComponent {}

Installation

Copy
npx zard-cli@latest add message

Usage

import { ZardMessageImports } from '@/shared/components/message/message.imports';
Copy
<z-message zSrc="https://github.com/srizzon.png" zAlt="@srizzon" zVariant="muted">
  How can I help you today?
</z-message>
Copy

Examples

default

SR @srizzonDeploying to prod real quick. LG @luizgomessIt's 4:55 PM. On a Friday. SR @srizzonIt's a one-line change.Delivered LG @luizgomessIt's always a one-line change 😭.Alright, let me take a look.👍
import { ChangeDetectionStrategy, Component } from '@angular/core';

import { ZardAvatarComponent } from '@/shared/components/avatar';
import { ZardBubbleImports } from '@/shared/components/bubble/bubble.imports';
import { ZardMessageImports } from '@/shared/components/message/message.imports';

@Component({
  selector: 'z-demo-message-default',
  imports: [ZardAvatarComponent, ...ZardBubbleImports, ...ZardMessageImports],
  template: `
    <div class="flex w-full max-w-sm flex-col gap-6 py-12">
      <z-message zAlign="end">
        <z-message-avatar>
          <z-avatar zSrc="https://github.com/srizzon.png" zAlt="@srizzon" zFallback="SR" />
        </z-message-avatar>
        <z-message-content>
          <z-bubble>
            <z-bubble-content>Deploying to prod real quick.</z-bubble-content>
          </z-bubble>
        </z-message-content>
      </z-message>

      <z-message>
        <z-message-avatar>
          <z-avatar zSrc="https://github.com/Luizgomess.png" zAlt="@luizgomess" zFallback="LG" />
        </z-message-avatar>
        <z-message-content>
          <z-bubble zVariant="muted">
            <z-bubble-content>It's 4:55 PM. On a Friday.</z-bubble-content>
          </z-bubble>
        </z-message-content>
      </z-message>

      <z-message zAlign="end">
        <z-message-avatar>
          <z-avatar zSrc="https://github.com/srizzon.png" zAlt="@srizzon" zFallback="SR" />
        </z-message-avatar>
        <z-message-content>
          <z-bubble>
            <z-bubble-content>It's a one-line change.</z-bubble-content>
          </z-bubble>
          <z-message-footer>Delivered</z-message-footer>
        </z-message-content>
      </z-message>

      <z-message>
        <z-message-avatar>
          <z-avatar zSrc="https://github.com/Luizgomess.png" zAlt="@luizgomess" zFallback="LG" />
        </z-message-avatar>
        <z-message-content>
          <z-bubble-group>
            <z-bubble zVariant="muted">
              <z-bubble-content>It's always a one-line change 😭.</z-bubble-content>
            </z-bubble>
            <z-bubble zVariant="muted">
              <z-bubble-content>Alright, let me take a look.</z-bubble-content>
              <z-bubble-reactions role="img" aria-label="Reactions: thumbs up">
                <span>👍</span>
              </z-bubble-reactions>
            </z-bubble>
          </z-bubble-group>
        </z-message-content>
      </z-message>
    </div>
  `,
  changeDetection: ChangeDetectionStrategy.OnPush,
  host: { class: 'contents' },
})
export class ZardDemoMessageDefaultComponent {}

avatar

LG @luizgomessThe build failed during dependency installation. SR @srizzonCan you share the exact error? LG @luizgomessHere's the error from the logs Something went wrong with the build. The libraries are not installed correctly. Try running the build again.
import { ChangeDetectionStrategy, Component } from '@angular/core';

import { ZardAvatarComponent } from '@/shared/components/avatar';
import { ZardBubbleImports } from '@/shared/components/bubble/bubble.imports';
import { ZardMessageImports } from '@/shared/components/message/message.imports';

@Component({
  selector: 'z-demo-message-avatar',
  imports: [ZardAvatarComponent, ...ZardBubbleImports, ...ZardMessageImports],
  template: `
    <div class="flex w-full max-w-sm flex-col gap-6 py-12">
      <z-message>
        <z-message-avatar>
          <z-avatar zSrc="https://github.com/Luizgomess.png" zAlt="@luizgomess" zFallback="LG" />
        </z-message-avatar>
        <z-message-content>
          <z-bubble zVariant="muted">
            <z-bubble-content>The build failed during dependency installation.</z-bubble-content>
          </z-bubble>
        </z-message-content>
      </z-message>

      <z-message zAlign="end">
        <z-message-avatar>
          <z-avatar zSrc="https://github.com/srizzon.png" zAlt="@srizzon" zFallback="SR" />
        </z-message-avatar>
        <z-message-content>
          <z-bubble>
            <z-bubble-content>Can you share the exact error?</z-bubble-content>
          </z-bubble>
        </z-message-content>
      </z-message>

      <z-message>
        <z-message-avatar>
          <z-avatar zSrc="https://github.com/Luizgomess.png" zAlt="@luizgomess" zFallback="LG" />
        </z-message-avatar>
        <z-message-content>
          <z-bubble-group>
            <z-bubble zVariant="muted">
              <z-bubble-content>Here's the error from the logs</z-bubble-content>
            </z-bubble>
            <z-bubble zVariant="muted">
              <z-bubble-content>
                Something went wrong with the build. The libraries are not installed correctly. Try running the build
                again.
              </z-bubble-content>
            </z-bubble>
          </z-bubble-group>
        </z-message-content>
      </z-message>
    </div>
  `,
  changeDetection: ChangeDetectionStrategy.OnPush,
  host: { class: 'contents' },
})
export class ZardDemoMessageAvatarComponent {}

group

I checked the registry addresses. LG @luizgomessThe component and example JSON now live under the UI registry.
import { ChangeDetectionStrategy, Component } from '@angular/core';

import { ZardAvatarComponent } from '@/shared/components/avatar';
import { ZardBubbleImports } from '@/shared/components/bubble/bubble.imports';
import { ZardMessageImports } from '@/shared/components/message/message.imports';

@Component({
  selector: 'z-demo-message-group',
  imports: [ZardAvatarComponent, ...ZardBubbleImports, ...ZardMessageImports],
  template: `
    <div class="flex w-full max-w-sm flex-col gap-6 py-12">
      <z-message-group>
        <z-message>
          <z-message-avatar />
          <z-message-content>
            <z-bubble zVariant="muted">
              <z-bubble-content>I checked the registry addresses.</z-bubble-content>
            </z-bubble>
          </z-message-content>
        </z-message>
        <z-message>
          <z-message-avatar>
            <z-avatar zSrc="https://github.com/Luizgomess.png" zAlt="@luizgomess" zFallback="LG" />
          </z-message-avatar>
          <z-message-content>
            <z-bubble zVariant="muted">
              <z-bubble-content>The component and example JSON now live under the UI registry.</z-bubble-content>
            </z-bubble>
          </z-message-content>
        </z-message>
      </z-message-group>
    </div>
  `,
  changeDetection: ChangeDetectionStrategy.OnPush,
  host: { class: 'contents' },
})
export class ZardDemoMessageGroupComponent {}

header footer

OliviaI already checked the logs.Send the report to the team. Ping @srizzon if you need help.
Read Yesterday
import { ChangeDetectionStrategy, Component } from '@angular/core';

import { ZardBubbleImports } from '@/shared/components/bubble/bubble.imports';
import { ZardMessageImports } from '@/shared/components/message/message.imports';

@Component({
  selector: 'z-demo-message-header-footer',
  imports: [...ZardBubbleImports, ...ZardMessageImports],
  template: `
    <div class="flex w-full max-w-sm flex-col gap-8 py-12">
      <z-message>
        <z-message-content>
          <z-message-header>Olivia</z-message-header>
          <z-bubble zVariant="muted">
            <z-bubble-content>I already checked the logs.</z-bubble-content>
          </z-bubble>
        </z-message-content>
      </z-message>

      <z-message zAlign="end">
        <z-message-content>
          <z-bubble>
            <z-bubble-content>Send the report to the team. Ping &#64;srizzon if you need help.</z-bubble-content>
          </z-bubble>
          <z-message-footer>
            <div>
              Read
              <span class="font-normal">Yesterday</span>
            </div>
          </z-message-footer>
        </z-message-content>
      </z-message>
    </div>
  `,
  changeDetection: ChangeDetectionStrategy.OnPush,
  host: { class: 'contents' },
})
export class ZardDemoMessageHeaderFooterComponent {}

actions

The install failure is coming from the workspace package.Okay drop me a link. Taking a look...Failed to send
import { ChangeDetectionStrategy, Component } from '@angular/core';

import { NgIcon, provideIcons } from '@ng-icons/core';
import { lucideCopy, lucideRefreshCcw, lucideThumbsDown, lucideThumbsUp } from '@ng-icons/lucide';

import { ZardBubbleImports } from '@/shared/components/bubble/bubble.imports';
import { ZardButtonComponent } from '@/shared/components/button/button.component';
import { ZardMessageImports } from '@/shared/components/message/message.imports';

@Component({
  selector: 'z-demo-message-actions',
  imports: [NgIcon, ZardButtonComponent, ...ZardBubbleImports, ...ZardMessageImports],
  template: `
    <div class="flex w-full max-w-sm flex-col gap-8 py-12">
      <z-message>
        <z-message-content>
          <z-bubble zVariant="muted">
            <z-bubble-content>The install failure is coming from the workspace package.</z-bubble-content>
          </z-bubble>
          <z-message-footer>
            <button type="button" z-button zType="ghost" zSize="icon" aria-label="Copy" title="Copy">
              <ng-icon name="lucideCopy" />
            </button>
            <button type="button" z-button zType="ghost" zSize="icon" aria-label="Like" title="Like">
              <ng-icon name="lucideThumbsUp" />
            </button>
            <button type="button" z-button zType="ghost" zSize="icon" aria-label="Dislike" title="Dislike">
              <ng-icon name="lucideThumbsDown" />
            </button>
          </z-message-footer>
        </z-message-content>
      </z-message>

      <z-message zAlign="end">
        <z-message-content>
          <z-bubble>
            <z-bubble-content>Okay drop me a link. Taking a look...</z-bubble-content>
          </z-bubble>
          <z-message-footer class="gap-2">
            <span class="text-destructive font-normal">Failed to send</span>
            <button type="button" z-button zType="ghost" zSize="icon-xs" aria-label="Retry" title="Retry">
              <ng-icon name="lucideRefreshCcw" />
            </button>
          </z-message-footer>
        </z-message-content>
      </z-message>
    </div>
  `,
  changeDetection: ChangeDetectionStrategy.OnPush,
  viewProviders: [provideIcons({ lucideCopy, lucideRefreshCcw, lucideThumbsDown, lucideThumbsUp })],
  host: { class: 'contents' },
})
export class ZardDemoMessageActionsComponent {}

attachment

Cover pageHere's the image. Can you add it to the PDF? Use it for the cover page.Done. Here's the PDF with the image added as the cover page.sales-dashboard.pdfPDF · 2.4 MBThanks. Looks good.
import { ChangeDetectionStrategy, Component } from '@angular/core';

import { NgIcon, provideIcons } from '@ng-icons/core';
import { lucideDownload, lucideFileText } from '@ng-icons/lucide';

import { ZardBubbleImports } from '@/shared/components/bubble/bubble.imports';
import { ZardButtonComponent } from '@/shared/components/button/button.component';
import { ZardItemImports } from '@/shared/components/item/item.imports';
import { ZardMessageImports } from '@/shared/components/message/message.imports';

@Component({
  selector: 'z-demo-message-attachment',
  imports: [NgIcon, ZardButtonComponent, ...ZardBubbleImports, ...ZardItemImports, ...ZardMessageImports],
  template: `
    <div class="flex w-full max-w-sm flex-col gap-8 py-12">
      <z-message zAlign="end">
        <z-message-content>
          <z-item zVariant="outline" class="w-fit rounded-2xl p-1.5">
            <z-item-media zVariant="image" class="size-24 rounded-xl">
              <img src="/images/github_banner.png" alt="Cover page" />
            </z-item-media>
          </z-item>
          <z-bubble>
            <z-bubble-content>Here's the image. Can you add it to the PDF? Use it for the cover page.</z-bubble-content>
          </z-bubble>
        </z-message-content>
      </z-message>

      <z-message>
        <z-message-content>
          <z-bubble zVariant="muted">
            <z-bubble-content>Done. Here's the PDF with the image added as the cover page.</z-bubble-content>
          </z-bubble>
          <z-item zVariant="muted" class="w-fit rounded-2xl">
            <z-item-media zVariant="icon" class="bg-background size-9 rounded-xl">
              <ng-icon name="lucideFileText" />
            </z-item-media>
            <z-item-content>
              <z-item-title>sales-dashboard.pdf</z-item-title>
              <z-item-description>PDF · 2.4 MB</z-item-description>
            </z-item-content>
            <z-item-actions>
              <button
                type="button"
                z-button
                zType="secondary"
                zSize="icon-sm"
                zShape="circle"
                aria-label="Download"
                title="Download"
              >
                <ng-icon name="lucideDownload" />
              </button>
            </z-item-actions>
          </z-item>
        </z-message-content>
      </z-message>

      <z-message zAlign="end">
        <z-message-content>
          <z-bubble>
            <z-bubble-content>Thanks. Looks good.</z-bubble-content>
          </z-bubble>
        </z-message-content>
      </z-message>
    </div>
  `,
  changeDetection: ChangeDetectionStrategy.OnPush,
  viewProviders: [provideIcons({ lucideDownload, lucideFileText })],
  host: { class: 'contents' },
})
export class ZardDemoMessageAttachmentComponent {}

shorthand

@luizgomess
How can I help you today?
@srizzon
Send me the release notes.
Delivered
OL Olivia
The notes are in the shared doc.
Read Yesterday
@srizzonProject the content when the turn needs more than a bubble.
import { ChangeDetectionStrategy, Component } from '@angular/core';

import { ZardBubbleImports } from '@/shared/components/bubble/bubble.imports';
import { ZardMessageImports } from '@/shared/components/message/message.imports';

@Component({
  selector: 'z-demo-message-shorthand',
  imports: [...ZardBubbleImports, ...ZardMessageImports],
  template: `
    <div class="flex w-full max-w-sm flex-col gap-6 py-12">
      <z-message zSrc="https://github.com/Luizgomess.png" zAlt="@luizgomess" zVariant="muted">
        How can I help you today?
      </z-message>

      <z-message zAlign="end" zSrc="https://github.com/srizzon.png" zAlt="@srizzon" zFooter="Delivered">
        Send me the release notes.
      </z-message>

      <z-message zFallback="OL" zVariant="muted" zHeader="Olivia" zFooter="Read Yesterday">
        The notes are in the shared doc.
      </z-message>

      <z-message zAlign="end" zSrc="https://github.com/srizzon.png" zAlt="@srizzon">
        <z-message-content>
          <z-bubble zVariant="outline">
            <z-bubble-content>Project the content when the turn needs more than a bubble.</z-bubble-content>
          </z-bubble>
        </z-message-content>
      </z-message>
    </div>
  `,
  changeDetection: ChangeDetectionStrategy.OnPush,
  host: { class: 'contents' },
})
export class ZardDemoMessageShorthandComponent {}

API Reference

z-messageComponent

The message row wrapper. It owns the avatar, alignment, header and footer around the message surface.

PropertyDescriptionTypeDefault
[zAlign] The alignment of the message in the conversation. start | end start
[zSrc] Avatar image of the sender. Renders the avatar slot for you; a projected z-message-avatar wins over it. string | SafeUrl -
[zAlt] Alternative text of the shorthand avatar image. string -
[zFallback] Initials shown while the shorthand avatar has no image, or instead of one. string -
[zHeader] Content above the turn, such as a sender name. Only applies to the shorthand. string | TemplateRef<void> -
[zFooter] Content below the turn, such as a delivery status. Only applies to the shorthand. string | TemplateRef<void> -
[zVariant] Variant of the bubble the shorthand renders. Ignored once the content is projected. default | secondary | muted | tinted | outline | ghost | destructive default
[class] Additional classes to apply to the row. ClassValue -

z-message-avatarComponent

The avatar slot, aligned to the bottom of the message. When the message has a z-message-footer, the avatar shifts up to stay aligned with the message surface instead of the footer.

PropertyDescriptionTypeDefault
[class] Additional classes to apply to the avatar slot. ClassValue -

z-message-contentComponent

Wraps the header, message surface and footer.

PropertyDescriptionTypeDefault
[class] Additional classes to apply to the content slot. ClassValue -

z-message-headerComponent

Displays content above the message, such as a sender name. Stays aligned to the start regardless of zAlign.

PropertyDescriptionTypeDefault
[zHeader] Header content, as an alternative to projecting it. string | TemplateRef<void> -
[class] Additional classes to apply to the header. ClassValue -

z-message-footerComponent

Displays content below the message, such as status or actions. Aligns to the message side.

PropertyDescriptionTypeDefault
[zFooter] Footer content, as an alternative to projecting it. string | TemplateRef<void> -
[class] Additional classes to apply to the footer. ClassValue -

z-message-groupComponent

Groups consecutive messages from the same sender.

PropertyDescriptionTypeDefault
[class] Additional classes to apply to the group root. ClassValue -
github iconwhatsapp icondiscord iconX icon

Made with in Brazil. Open source and available on GitHub .