Activity Feed
Chronological event log with computed relative timestamps.
Live Demo
No events yet.
Source
HTML + JavaScript
<div data-component="activity-feed">
<button data-action="addDeploy">+ Deploy</button>
<button data-action="addAlert">+ Alert</button>
<div data-list="events">
<template>
<div class="feed-item">
<div data-bind-class="'feed-dot feed-dot-' + type"></div>
<div>
<div data-bind="message"></div>
<div data-bind="relativeTime"></div>
</div>
</div>
</template>
</div>
</div>
<script>
wildflower.component('activity-feed', {
state: {
events: [
{ type: 'deploy', message: 'Deployed auth-service v2.4.1', timestamp: Date.now() - 120000 },
{ type: 'info', message: 'Config updated for staging', timestamp: Date.now() - 300000 },
{ type: 'alert', message: 'CPU usage above 80% on node-3', timestamp: Date.now() - 600000 },
{ type: 'error', message: 'Failed health check on db-replica-2', timestamp: Date.now() - 3600000 }
]
},
computed: {
relativeTime(m) {
const diff = Date.now() - m.timestamp;
if (diff < 60000) return 'just now';
if (diff < 3600000) return Math.floor(diff / 60000) + 'm ago';
return Math.floor(diff / 3600000) + 'h ago';
}
},
addDeploy() {
this.events.unshift({
type: 'deploy', message: 'Deployed api-gateway v1.' + Math.floor(Math.random()*20),
timestamp: Date.now()
});
},
addAlert() {
this.events.unshift({
type: 'alert', message: 'Memory spike on worker-' + Math.floor(Math.random()*8),
timestamp: Date.now()
});
},
clearFeed() { this.events = []; }
});
</script>
Key Points
data-bind-class="'feed-dot feed-dot-' + type"builds a class string from the event's type, mapping to a CSS color per event kind- Item-level computed
relativeTimeformats each event's timestamp relative to now unshift()adds new events to the top of the list. The reactive proxy handles itdata-show="events.length === 0"shows an empty state when the feed is cleared