Welcome to Vanilla Breeze
This bell pulls live notifications from /go/notify/messages — the same contract documented at /docs/concepts/service-contracts/. Static articles like this one are the no-JS / no-backend fallback.
This bell pulls live notifications from /go/notify/messages — the same contract documented at /docs/concepts/service-contracts/. Static articles like this one are the no-JS / no-backend fallback.
Displays Agile user stories in the classic 'As a / I want / so that' format with priority, status, and story points.
A web component that renders user stories in the standard Agile format: "As a [persona], I want [action] so that [benefit]." Includes visual badges for priority, status, and story points, plus slotted sections for acceptance criteria, tasks, and notes. Designed for sprint planning boards, backlog views, and design documentation.
<user-story persona-id="persona-sarah" priority="high" status="in-progress" points="5" epic="Dashboard" story-id="PROJ-142"> <span slot="persona">Product Manager</span> <span slot="action">view all project timelines in one dashboard</span> <span slot="benefit">I can quickly identify bottlenecks and reallocate resources</span> <ul slot="acceptance-criteria"> <li>Dashboard loads within 2 seconds</li> <li>All active projects are displayed</li> <li>Timeline view is zoomable</li> </ul> <ul slot="tasks"> <li>Design dashboard wireframe</li> <li>Implement timeline API endpoint</li> <li>Build frontend grid layout</li> </ul> <p slot="notes">Consider using virtual scrolling for large project lists.</p></user-story>
| Attribute | Type | Default | Description |
|---|---|---|---|
persona-id |
string | — | ID of a <user-persona> element to link to (renders as an anchor) |
priority |
string | "medium" |
Priority level: critical, high, medium, or low |
status |
string | "backlog" |
Workflow status: backlog, to-do, in-progress, review, or done |
points |
string | — | Story point estimate displayed as a circular badge |
epic |
string | — | Epic or feature group label shown as a highlighted chip |
story-id |
string | — | Unique identifier (e.g., "PROJ-142") displayed in monospace in the header |
compact |
boolean | — | Reduces padding and font size for denser layouts |
detail |
string | "full" |
Controls content density: full (all sections), compact (hide empty sections), minimal (ID + title only, click to expand) |
src |
string (URL) | — | URL to JSON file containing story data. Loads and populates all attributes. |
| Slot | Expected Content | Description |
|---|---|---|
persona |
<span> or text |
The "As a..." role or persona name (e.g., "Product Manager") |
action |
<span> or text |
The "I want..." action description |
benefit |
<span> or text |
The "so that..." benefit. When omitted, the benefit clause is hidden. |
acceptance-criteria |
<ul> or <ol> |
Definition of done checklist. Displayed with a green accent icon. |
tasks |
<ul> or <ol> |
Implementation tasks. Displayed with a purple accent icon. |
notes |
<p> or text |
Additional notes or context. Displayed with an amber accent icon. |
The detail attribute controls how much content the card displays. Three levels support different use cases from dense kanban boards to full documentation.
| Value | Shows | Use Case |
|---|---|---|
full |
Header, statement, all sections (with empty fallbacks) | Documentation pages, standalone story views |
compact |
Header, statement, sections only if populated | Story map columns, backlog lists |
minimal |
Story ID + title only. Clickable — opens full detail in a <dialog>. |
Kanban boards, impact/effort matrix, dense grids |
<user-story story-id="PROJ-142" detail="minimal"> <span slot="persona">Product Manager</span> <span slot="action">see all project timelines in a unified dashboard</span></user-story>
Minimal cards are interactive. Clicking or pressing Enter opens a native <dialog> showing the full story. The dialog uses VB’s built-in dialog CSS for sizing, backdrop, and animation. You can also call story.showDetail() programmatically.
const story = document.querySelector('user-story[story-id="PROJ-142"]');story.showDetail(); // Opens modal dialog with full detail/code-block </section> <section> <h2>JSON Loading</h2> <p>Load story data from a JSON file using the <code>src</code> attribute. Scalar fields map to attributes; list fields populate the acceptance criteria, tasks, and notes sections.</p> <code-block language="html" show-lines label="Loading from JSON" data-escape><user-story src="/api/stories/PROJ-142.json" detail="full"></user-story>
{ "storyId": "PROJ-142", "title": "Dashboard timeline view", "persona": "Product Manager", "action": "see all project timelines in a unified dashboard", "benefit": "I can quickly identify bottlenecks", "priority": "high", "status": "in-progress", "points": "8", "epic": "Dashboard", "acceptanceCriteria": [ "Dashboard loads within 2 seconds", "All active projects displayed" ], "tasks": ["Design mockups", "Implement timeline"], "notes": "Consider virtual scrolling for performance."}
Content values — persona, action, and benefit — are provided as named slots. State attributes like priority, status, points, and story-id remain on the element. This separation keeps content in the DOM and metadata in attributes.
<user-story story-id="PROJ-142" priority="high" status="in-progress" points="5"> <span slot="persona">Product Manager</span> <span slot="action">see all project timelines in a unified dashboard</span> <span slot="benefit">I can quickly identify bottlenecks</span> <ul slot="acceptance-criteria"> <li>Dashboard loads within 2 seconds</li> </ul></user-story>
The priority attribute controls the colored badge in the story header. Here are three stories showing different priority and status combinations in compact mode.
| Value | Label | Color |
|---|---|---|
critical |
Critical | #dc2626 (red) |
high |
High | #ea580c (orange) |
medium |
Medium | #ca8a04 (amber) |
low |
Low | #16a34a (green) |
<user-story priority="critical" status="to-do" story-id="SEC-301"> <span slot="persona">Security Engineer</span> <span slot="action">receive alerts for authentication failures</span> <span slot="benefit">I can respond to potential breaches immediately</span></user-story>
The status attribute controls the workflow badge in the story header.
| Value | Label | Color |
|---|---|---|
backlog |
Backlog | #6b7280 (gray) |
to-do |
To Do | #3b82f6 (blue) |
in-progress |
In Progress | #8b5cf6 (purple) |
review |
Review | #f59e0b (amber) |
done |
Done | #22c55e (green) |
The component exposes two methods for programmatic status and priority updates. Both update the attribute and dispatch a corresponding event.
| Method | Argument | Description |
|---|---|---|
updateStatus(status) |
One of: backlog, to-do, in-progress, review, done |
Updates the status badge and fires status-changed |
updatePriority(priority) |
One of: critical, high, medium, low |
Updates the priority badge and fires priority-changed |
const story = document.querySelector('user-story[story-id="PROJ-142"]'); // Move to reviewstory.updateStatus('review'); // Escalate prioritystory.updatePriority('critical'); // Listen for changesstory.addEventListener('status-changed', (e) => { console.log(`${e.detail.storyId} moved to ${e.detail.status}`);});
| Variable | Default | Description |
|---|---|---|
--user-story-bg |
#ffffff / #1e1e1e |
Card background color |
--user-story-text |
#1a1a1a / #e8e8e8 |
Primary text color |
--user-story-muted |
#666666 / #888888 |
Secondary/muted text color |
--user-story-border |
#e0e0e0 / #333333 |
Card and section border color |
--user-story-accent |
#0066cc / #6b9fff |
Accent color for keywords and epic badge |
--user-story-card-bg |
#f8f9fa / #252525 |
Header background color |
--user-story-highlight |
rgba(0, 102, 204, 0.08) / rgba(107, 159, 255, 0.15) |
Persona text highlight and epic badge background |
--user-story-radius |
12px |
Outer card border radius |
| Event | Detail | When |
|---|---|---|
story-ready |
{ id, persona, action, benefit, priority, status, points } |
Fires after the component finishes rendering |
status-changed |
{ status, storyId } |
Fires when updateStatus() is called with a valid status |
priority-changed |
{ priority, storyId } |
Fires when updatePriority() is called with a valid priority |
role="article" with aria-label="User story"title attribute reading "Story points"prefers-reduced-motion: reduce by disabling hover transitions<user-persona> — Persona cards that stories reference<user-journey> — Journey maps that link to story IDs<empathy-map> — Empathy maps for understanding user needs<impact-effort> — Prioritization matrix for draggable story cards<story-map> — Horizontal story mapping with activity columns