Today

Mei Chen@mei
Started run 184 in Wind tunnel · 32 cores
API keyAutomation
Completed surface validation · 18 checks passed

Lina Haddad@lina
Uploaded vehicle-body.step · 28.4 MB
<script setup>
import { ActivityFeed } from "@dicehub/kappa/components/activity-feed";
import { Avatar } from "@dicehub/kappa/components/avatar";
</script>
<template>
<ActivityFeed.Root>
<ActivityFeed.Group aria-labelledby="activity-today">
<ActivityFeed.GroupLabel id="activity-today">Today</ActivityFeed.GroupLabel>
<ActivityFeed.List aria-label="Project activity">
<ActivityFeed.Item>
<ActivityFeed.Marker variant="avatar">
<Avatar.Root>
<Avatar.Image src="/avatars/mei-chen.webp" alt="" />
<Avatar.Fallback aria-hidden="true">MC</Avatar.Fallback>
</Avatar.Root>
</ActivityFeed.Marker>
<ActivityFeed.Content>
<ActivityFeed.Header>
<ActivityFeed.Title>Mei Chen</ActivityFeed.Title>
<ActivityFeed.Time datetime="2026-09-19T14:32:00Z">14:32</ActivityFeed.Time>
</ActivityFeed.Header>
<ActivityFeed.Description>
Started run <a href="/runs/184">184</a> in Wind tunnel · 32 cores
</ActivityFeed.Description>
</ActivityFeed.Content>
</ActivityFeed.Item>
</ActivityFeed.List>
</ActivityFeed.Group>
</ActivityFeed.Root>
</template>Installation
Activity Feed is part of the main Kappa package. It uses native list and time elements and has no state-machine dependency.
Barrel
import {
ActivityFeed,
ActivityFeedActions,
ActivityFeedContent,
ActivityFeedDescription,
ActivityFeedGroup,
ActivityFeedGroupLabel,
ActivityFeedHeader,
ActivityFeedItem,
ActivityFeedList,
ActivityFeedMarker,
ActivityFeedRoot,
ActivityFeedTime,
ActivityFeedTitle,
} from "@dicehub/kappa";Granular
import {
ActivityFeed,
ActivityFeedItem,
ActivityFeedMarker,
type ActivityFeedTone,
} from "@dicehub/kappa/components/activity-feed";Usage
Use Activity Feed for ordered events such as run changes, project history, audit records, and review actions. Supply application data through slots.
Keep the actor or event name in Title and the event details in Description. Time aligns with the end of the header and wraps on narrow panels. Description links use the accent color and retain a visible keyboard focus ring.
Simulation started
Run 184 is preparing compute resources.
<script setup>
import { Play } from "@lucide/vue";
import { ActivityFeed } from "@dicehub/kappa/components/activity-feed";
</script>
<template>
<ActivityFeed.Root>
<ActivityFeed.List aria-label="Recent activity">
<ActivityFeed.Item tone="accent">
<ActivityFeed.Marker variant="icon"><Play aria-hidden="true" /></ActivityFeed.Marker>
<ActivityFeed.Content>
<ActivityFeed.Header>
<ActivityFeed.Title>Simulation started</ActivityFeed.Title>
<ActivityFeed.Time datetime="2026-09-19T14:32:00Z">2 min ago</ActivityFeed.Time>
</ActivityFeed.Header>
<ActivityFeed.Description>Run 184 is preparing compute resources.</ActivityFeed.Description>
</ActivityFeed.Content>
</ActivityFeed.Item>
</ActivityFeed.List>
</ActivityFeed.Root>
</template>Composition
ActivityFeed.Root
└── ActivityFeed.Group (optional)
├── ActivityFeed.GroupLabel
└── ActivityFeed.List
└── ActivityFeed.Item
├── ActivityFeed.Marker
└── ActivityFeed.Content
├── ActivityFeed.Header
│ ├── ActivityFeed.Title
│ └── ActivityFeed.Time
├── ActivityFeed.Description
└── ActivityFeed.Actions (optional)Kappa owns this native semantic composition because Ark UI has no Activity Feed primitive. Activity Feed does not fetch data, format events, or depend on an application store.
- Use Group and GroupLabel when events are divided by date or category.
- Use one List for each group and preserve a meaningful event order.
- Use dot markers for neutral system events, icons for typed events, and avatars for people.
- Use Actions only for controls that act on the associated event.
- Compose with Collapsible to reveal long event details.
Examples
Compact
Use compact density for audit trails and high-frequency configuration events.
Configuration history
Boundary condition updated
inlet.velocity · 14.2 m/s
Geometry synchronized
vehicle-body.step · 28.4 MB
Run settings saved
32 cores · 48 GB memory
<script setup>
import { ActivityFeed } from "@dicehub/kappa/components/activity-feed";
const events = [
{ title: "Boundary condition updated", time: "14:32" },
{ title: "Geometry synchronized", time: "14:29" },
];
</script>
<template>
<ActivityFeed.Root size="compact">
<ActivityFeed.List aria-label="Configuration history">
<ActivityFeed.Item v-for="event in events" :key="event.time">
<ActivityFeed.Marker />
<ActivityFeed.Content>
<ActivityFeed.Header>
<ActivityFeed.Title>{{ event.title }}</ActivityFeed.Title>
<ActivityFeed.Time>{{ event.time }}</ActivityFeed.Time>
</ActivityFeed.Header>
</ActivityFeed.Content>
</ActivityFeed.Item>
</ActivityFeed.List>
</ActivityFeed.Root>
</template>Markers
Distinguish system events, typed actions, and people with dot, icon, and avatar markers.
Automatic system event
Agent prepared a configuration

Lina added a review note
<script setup>
import { Bot } from "@lucide/vue";
import { ActivityFeed } from "@dicehub/kappa/components/activity-feed";
import { Avatar } from "@dicehub/kappa/components/avatar";
</script>
<template>
<ActivityFeed.Root>
<ActivityFeed.List aria-label="Marker examples">
<ActivityFeed.Item>
<ActivityFeed.Marker />
<ActivityFeed.Content><ActivityFeed.Title>Automatic system event</ActivityFeed.Title></ActivityFeed.Content>
</ActivityFeed.Item>
<ActivityFeed.Item tone="accent">
<ActivityFeed.Marker variant="icon"><Bot aria-hidden="true" /></ActivityFeed.Marker>
<ActivityFeed.Content><ActivityFeed.Title>Agent prepared a configuration</ActivityFeed.Title></ActivityFeed.Content>
</ActivityFeed.Item>
<ActivityFeed.Item>
<ActivityFeed.Marker variant="avatar">
<Avatar.Root><Avatar.Fallback aria-hidden="true">LH</Avatar.Fallback></Avatar.Root>
</ActivityFeed.Marker>
<ActivityFeed.Content><ActivityFeed.Title>Lina added a review note</ActivityFeed.Title></ActivityFeed.Content>
</ActivityFeed.Item>
</ActivityFeed.List>
</ActivityFeed.Root>
</template>Tones
Apply restrained semantic color to the marker without coloring the full event row.
Configuration saved
Simulation started
Mesh validation passed
Residual target not reached
Solver stopped unexpectedly
<script setup lang="ts">
import { ActivityFeed, type ActivityFeedTone } from "@dicehub/kappa/components/activity-feed";
const tones: ActivityFeedTone[] = ["neutral", "accent", "success", "warning", "danger"];
</script>
<template>
<ActivityFeed.Root size="compact">
<ActivityFeed.List aria-label="Activity tones">
<ActivityFeed.Item v-for="tone in tones" :key="tone" :tone="tone">
<ActivityFeed.Marker />
<ActivityFeed.Content><ActivityFeed.Title>{{ tone }} event</ActivityFeed.Title></ActivityFeed.Content>
</ActivityFeed.Item>
</ActivityFeed.List>
</ActivityFeed.Root>
</template>Long activity
Keep a long update collapsed until it is needed. Select the arrow at the bottom center to expand the card and read the full review. The arrow stays below the content and points up when open. Collapsible supplies keyboard controls, height animation, and reduced-motion support.
<script setup lang="ts">
import { ref } from "vue";
import { ChevronDown } from "@lucide/vue";
import { ActivityFeed } from "@dicehub/kappa/components/activity-feed";
import { Avatar } from "@dicehub/kappa/components/avatar";
import { Collapsible } from "@dicehub/kappa/components/collapsible";
const open = ref(false);
</script>
<template>
<ActivityFeed.Root>
<ActivityFeed.List aria-label="Detailed project activity">
<ActivityFeed.Item>
<ActivityFeed.Marker variant="avatar">
<Avatar.Root>
<Avatar.Image src="/avatars/mei-chen.webp" alt="" />
<Avatar.Fallback aria-hidden="true">MC</Avatar.Fallback>
</Avatar.Root>
</ActivityFeed.Marker>
<ActivityFeed.Content>
<Collapsible.Root v-model:open="open" class="activity-feed-expandable">
<ActivityFeed.Header>
<ActivityFeed.Title>Mei Chen</ActivityFeed.Title>
<ActivityFeed.Time datetime="2026-09-19T12:06:00Z">12:06</ActivityFeed.Time>
</ActivityFeed.Header>
<ActivityFeed.Description>
Published a detailed review of run 184. Three changes are required before the next
wind tunnel comparison.
</ActivityFeed.Description>
<Collapsible.Content class="activity-feed-expandable__content">
<div class="activity-feed-expandable__report">
<p>
I compared the production mesh with the reference case at 14.2 m/s. The mean
drag coefficient is within the target range, but the pressure distribution
around the rear wheel still changes between the final sampling windows. Keep
this run as a baseline while we check the remaining differences.
</p>
<h4>Boundary conditions</h4>
<p>
Change the inlet turbulence intensity from 1% to 0.5% to match the measured
tunnel conditions. Keep the velocity profile and air temperature unchanged.
The outlet pressure and symmetry boundaries already match the reference
setup, so they do not need an update.
</p>
<h4>Mesh and convergence</h4>
<p>
Add one refinement level around the rear wheel and the wake. The current mesh
passes all 18 geometry checks, but the local cell size is too large to resolve
the pressure gradient. Preserve the existing prism layers and check the wall
distance again after the new volume mesh is generated.
</p>
<p>
Extend the solver by 500 iterations after the residuals settle. Compare the
final three force averages instead of the last sample alone. Record the
maximum Courant number and the mass imbalance with the exported results so
the next review can use the same acceptance checks.
</p>
<h4>Next steps</h4>
<p>
Save the updated configuration as a new revision, attach the mesh quality
report, and run the comparison on the same 32-core allocation. Share the
pressure and force plots with Lina before marking the case ready for release.
The original run remains available for comparison.
</p>
</div>
</Collapsible.Content>
<div class="activity-feed-expandable__footer">
<Collapsible.Trigger
class="activity-feed-expandable__trigger"
:aria-label="open ? 'Collapse review details' : 'Expand review details'"
>
<template #indicator>
<ChevronDown class="activity-feed-expandable__arrow" aria-hidden="true" />
</template>
</Collapsible.Trigger>
</div>
</Collapsible.Root>
</ActivityFeed.Content>
</ActivityFeed.Item>
</ActivityFeed.List>
</ActivityFeed.Root>
</template>
<style scoped>
.activity-feed-expandable {
border: 0;
border-radius: 0;
background: transparent;
}
.activity-feed-expandable__footer {
display: flex;
justify-content: center;
margin-block-start: 0.5rem;
margin-block-end: calc(
0.25rem - var(--kappa-activity-feed-item-padding-block)
);
/* Include the marker column so the arrow is centered on the whole card. */
margin-inline-start: calc(
0px - var(--kappa-activity-feed-marker-size) - var(--kappa-activity-feed-item-gap)
);
}
.activity-feed-expandable__trigger {
inline-size: 1.75rem;
min-block-size: 1.75rem;
justify-content: center;
padding: 0;
border-radius: 0.25rem;
color: var(--kappa-subtle);
}
.activity-feed-expandable__trigger[data-state="open"] {
background: transparent;
}
.activity-feed-expandable__arrow {
inline-size: 1rem;
block-size: 1rem;
transition: transform 160ms ease;
}
.activity-feed-expandable__trigger[data-state="open"] .activity-feed-expandable__arrow {
transform: rotate(180deg);
}
.activity-feed-expandable__content {
border: 0;
}
.activity-feed-expandable__content :deep([data-slot="collapsible-content-body"]) {
padding: 0.875rem 0 0;
}
.activity-feed-expandable__report {
border-block-start: 1px solid var(--kappa-line);
padding-block-start: 0.875rem;
color: var(--kappa-subtle);
font-size: 0.8125rem;
line-height: 1.6;
overflow-wrap: anywhere;
}
.activity-feed-expandable__report p {
margin: 0;
}
.activity-feed-expandable__report h4 {
margin: 1rem 0 0.25rem;
color: var(--kappa-default);
font-size: inherit;
font-weight: 600;
}
.activity-feed-expandable__report p + p {
margin-block-start: 0.75rem;
}
@media (prefers-reduced-motion: reduce) {
.activity-feed-expandable__arrow {
transition: none;
}
}
</style>Actions
Place event-specific controls after the description while keeping the title readable.
Lina requested changes to the inlet setup
The turbulence intensity must match the reference case.
<script setup>
import { ActivityFeed } from "@dicehub/kappa/components/activity-feed";
import { Button } from "@dicehub/kappa/components/button";
</script>
<template>
<ActivityFeed.Root>
<ActivityFeed.List aria-label="Review activity">
<ActivityFeed.Item tone="warning">
<ActivityFeed.Marker />
<ActivityFeed.Content>
<ActivityFeed.Title>Lina requested changes</ActivityFeed.Title>
<ActivityFeed.Description>Review the inlet setup.</ActivityFeed.Description>
<ActivityFeed.Actions>
<Button size="sm" variant="secondary">Open comment</Button>
<Button size="sm" variant="ghost">Resolve</Button>
</ActivityFeed.Actions>
</ActivityFeed.Content>
</ActivityFeed.Item>
</ActivityFeed.List>
</ActivityFeed.Root>
</template>Accessibility
- List renders a native ordered list and Item renders a native list item.
- Place
aria-labeloraria-labelledbyon List to name the event history. - Time renders a native
timeelement. Supplydatetimewhenever the value is known. - Connect each Group to its GroupLabel with
aria-labelledby. - Decorative marker icons need
aria-hidden="true". Meaningful images need alternative text. - For live events, set
aria-live="polite"on a small changing region. Do not announce the full history again. - HTML, ARIA, data attributes, and event listeners pass to every part.
- The long activity example uses a named disclosure button with
aria-expandedandaria-controls. Its height animation respects reduced motion.
API Reference
ActivityFeed.Root
| Prop | Type | Default | Description |
|---|---|---|---|
size | "default" | "compact" | "default" | Controls event spacing, marker dimensions, and type scale. |
ActivityFeed.Item
| Prop | Type | Default | Description |
|---|---|---|---|
tone | "neutral" | "accent" | "success" | "warning" | "danger" | "neutral" | Applies semantic color to the event marker. |
ActivityFeed.Marker
| Prop | Type | Default | Description |
|---|---|---|---|
variant | "dot" | "icon" | "avatar" | "dot" | Selects marker geometry for automatic, typed, or person events. |
Semantic Parts
| Part | Prop | Type | Default | Description |
|---|---|---|---|---|
GroupLabel / Title | as | "h2" | "h3" | "h4" | "h5" | "h6" | "p" | "div" | "h3" / "p" | Selects a safe native heading or text element. |
Time | datetime | string | undefined | Sets the machine-readable value on the native time element. |
Parts
| Part | Element | Description |
|---|---|---|
ActivityFeed.Root | div | Root density and token scope. |
ActivityFeed.Group | section | Optional set of events for one date or category. |
ActivityFeed.GroupLabel | h3 | Visible label for a group. |
ActivityFeed.List | ol | Native ordered event list. |
ActivityFeed.Item | li | One chronological event and its semantic tone. |
ActivityFeed.Marker | div | Dot, icon, or avatar beside the event content. |
ActivityFeed.Content | div | Flexible event content column. |
ActivityFeed.Header | div | Title and time row. |
ActivityFeed.Title | p | Primary event statement. |
ActivityFeed.Description | p | Supporting event detail. |
ActivityFeed.Time | time | Visible and machine-readable event time. |
ActivityFeed.Actions | div | Optional event actions. |
Exports
| Export | Description |
|---|---|
ActivityFeed | Compound API exposing all Activity Feed parts. |
ActivityFeedRoot | Unaugmented root component. |
ActivityFeedGroup / ActivityFeedGroupLabel | Optional event grouping parts. |
ActivityFeedList / ActivityFeedItem | Native ordered list and list-item parts. |
ActivityFeedMarker | Dot, icon, or avatar marker. |
ActivityFeedContent / ActivityFeedHeader | Event content layout parts. |
ActivityFeedTitle / ActivityFeedDescription | Primary and supporting event copy. |
ActivityFeedTime / ActivityFeedActions | Event metadata and controls. |
ActivityFeedSize / ActivityFeedTone / ActivityFeedMarkerVariant | Public option unions. |