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
| Component | Element | Purpose |
|---|---|---|
activity_feed/1 | div | Root container (role="log", aria-live="polite") |
activity_group/1 | section | Date-grouped section with a visible date label |
activity_item/1 | li | One event row: type icon, optional avatar, text, time |
Activity item types
| Type | Icon | Background / colour |
|---|---|---|
mention | at-sign | Orange |
file | file | Violet |
call | phone | Green |
task | check-square | Blue |
reaction | heart | Pink |
system | bell | Muted (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
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 tonil.Global attributes are accepted. HTML attributes forwarded to the root div (e.g.
phx-update="stream").
Slots
inner_block(required) -activity_group/1and/oractivity_item/1children.footer- Optional footer slot rendered below the event list — typically a comment form withphx-submit. Separated from the event stream by a top border.
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 tonil.- Global attributes are accepted. HTML attributes forwarded to the
<section>element.
Slots
inner_block(required) -activity_item/1children.
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 tonil.class(:string) - Additional CSS classes for the item row. Defaults tonil.Global attributes are accepted. HTML attributes forwarded to the
<li>element (e.g.idfor streams).
Slots
avatar- Optionalavatar/1component 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.