PhiaUi.Components.ActivityFeed (phia_ui v0.1.17)

Copy Markdown View Source

Activity feed / audit log component for PhiaUI.

Renders a chronological, date-grouped list of events — the kind of "What happened?" sidebar you see in CRMs, project trackers, ticketing systems, and collaboration tools.

CSS-only — no JS hook required. Fully server-rendered and compatible with LiveView streams for real-time event delivery.

When to use

  • CRM contact timeline: calls, emails, tasks, notes
  • GitHub-style issue/PR activity stream
  • Audit log: "Alice archived this ticket at 9:12 AM"
  • Notification center: mentions, reactions, system alerts

Anatomy

ComponentElementPurpose
activity_feed/1divRoot container (role="log", aria-live="polite")
activity_group/1sectionDate-grouped section with a visible date label
activity_item/1liOne event row: type icon, optional avatar, text, time

Activity item types

TypeIconBackground / colour
mentionat-signOrange
filefileViolet
callphoneGreen
taskcheck-squareBlue
reactionheartPink
systembellMuted (semantic token)

Basic example

<.activity_feed id="crm-activity">
  <.activity_group label="Today">
    <.activity_item type="mention" timestamp="9:12 AM">
      <:avatar>
        <.avatar size="sm">
          <.avatar_fallback name="Jason Carter" />
        </.avatar>
      </:avatar>
      <span>
        <strong>Jason Carter</strong> mentioned
        <span class="font-medium text-primary">@you</span>
        in <strong>#Lead Follow-up</strong>.
      </span>
    </.activity_item>

    <.activity_item type="file" timestamp="9:46 AM">
      New file uploaded: <strong>Q3_Sales_Targets_v2.xlsx</strong>
    </.activity_item>
  </.activity_group>

  <.activity_group label="Yesterday">
    <.activity_item type="task" timestamp="09:18 AM">
      Task <strong>Pitch Deck</strong> was assigned to you.
    </.activity_item>
  </.activity_group>

  <:footer>
    <form phx-submit="send_comment" class="flex gap-2">
      <input
        name="comment"
        placeholder="Add a comment..."
        class="flex-1 rounded-md border border-input bg-background px-3 py-2 text-sm"
      />
      <button type="submit" class="btn btn-primary text-sm">Post</button>
    </form>
  </:footer>
</.activity_feed>

LiveView streams for real-time delivery

role="log" + aria-live="polite" means new items pushed via streams will be announced by screen readers without interrupting the user's current focus.

# In the LiveView handle_info for a PubSub broadcast:
def handle_info({:new_activity, activity}, socket) do
  {:noreply, stream_insert(socket, :activities, activity, at: 0)}
end

# In the template:
<.activity_feed id="live-feed">
  <.activity_group label="Recent">
    <.activity_item
      :for={{dom_id, item} <- @streams.activities}
      id={dom_id}
      type={item.type}
      timestamp={item.formatted_time}
    >
      {item.text}
    </.activity_item>
  </.activity_group>
</.activity_feed>

Summary

Functions

Renders the activity feed root container.

Renders a date-grouped section of activity events.

Renders a single activity event row.

Functions

activity_feed(assigns)

Renders the activity feed root container.

Sets role="log" and aria-live="polite" so assistive technologies automatically announce new events inserted via LiveView streams without interrupting the user.

Attributes

  • id (:string) - Optional DOM id. Required when using LiveView streams so the DOM diffing engine can locate and patch individual items efficiently.

    Defaults to nil.

  • class (:string) - Additional CSS classes for the feed container. Defaults to nil.

  • Global attributes are accepted. HTML attributes forwarded to the root div (e.g. phx-update="stream").

Slots

  • inner_block (required) - activity_group/1 and/or activity_item/1 children.
  • footer - Optional footer slot rendered below the event list — typically a comment form with phx-submit. Separated from the event stream by a top border.

activity_group(assigns)

Renders a date-grouped section of activity events.

The label is displayed as a pill-shaped muted badge with a horizontal rule extending to the right, visually separating date groups.

Example

<.activity_group label="Mar 1, 2026">
  <.activity_item type="call" timestamp="10:00 AM">
    Call with <strong>Acme Corp</strong> lasted 32 minutes.
  </.activity_item>
</.activity_group>

Attributes

  • label (:string) (required) - Date label for this group of events. Use "Today", "Yesterday", or a date string like "Mar 3, 2026".
  • class (:string) - Additional CSS classes for the group wrapper. Defaults to nil.
  • Global attributes are accepted. HTML attributes forwarded to the <section> element.

Slots

activity_item(assigns)

Renders a single activity event row.

The :type attr selects the icon and colour scheme for the type indicator circle. Pass an :avatar slot to show who performed the action. Use :timestamp for the time label on the right.

Example — user-initiated mention event

<.activity_item type="mention" timestamp="Just now">
  <:avatar>
    <.avatar size="sm"><.avatar_fallback name="Sarah Lin" /></.avatar>
  </:avatar>
  <strong>Sarah Lin</strong> mentioned you in
  <a href="/tickets/42" class="font-medium text-primary hover:underline">Ticket #42</a>.
</.activity_item>

Example — system event (no avatar)

<.activity_item type="system" timestamp="03:00 AM">
  Daily digest email sent to 1,204 subscribers.
</.activity_item>

Attributes

  • type (:string) - Event type — controls the icon and icon background colour:

    • mention — orange at-sign (someone tagged you or another user)
    • file — violet file icon (document uploaded or shared)
    • call — green phone icon (phone/video call logged)
    • task — blue check-square (task created, completed, or assigned)
    • reaction — pink heart (emoji reaction or like)
    • system — muted bell (automated notification, status change, etc.)

    Defaults to "system". Must be one of "mention", "file", "call", "task", "reaction", or "system".

  • timestamp (:string) - Optional time label rendered at the end of the row, e.g. "9:12 AM" or "2 hours ago". Defaults to nil.

  • class (:string) - Additional CSS classes for the item row. Defaults to nil.

  • Global attributes are accepted. HTML attributes forwarded to the <li> element (e.g. id for streams).

Slots

  • avatar - Optional avatar/1 component displayed between the type icon and the event text. Use for user-initiated events where showing who acted is important.

  • inner_block (required) - Event description text. May include inline HTML markup (<strong>, <span>, links, etc.) for rich formatting.