user-story
Displays Agile user stories in the classic 'As a / I want / so that' format with priority, status, and story points.
Overview
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="Product Manager" action="view all project timelines in one dashboard" benefit="I can quickly identify bottlenecks and reallocate resources" priority="high" status="in-progress" points="5" epic="Dashboard" story-id="PROJ-142"> <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>
Attributes
| Attribute | Type | Default | Description |
|---|---|---|---|
persona |
string | "user" |
The "As a..." role or persona name |
action |
string | — | The "I want..." action description |
benefit |
string | — | The "so that..." benefit. When omitted, the benefit clause is hidden. |
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 |
title |
string | — | Short title shown in minimal detail mode. Falls back to truncated action text. |
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. |
Slots
| Slot | Expected Content | Description |
|---|---|---|
persona |
text | Slot fallback for the persona attribute (SSR friendly) |
action |
text | Slot fallback for the action attribute |
benefit |
text | Slot fallback for the benefit attribute |
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. |
Detail Levels
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" title="Dashboard timeline view" persona="Product Manager" action="see all project timelines in a unified dashboard" detail="minimal"></user-story>
Click to Expand
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."}
Slot-Based Authoring
Scalar values like persona, action, and benefit can also be provided as slotted child elements. This is useful for SSR scenarios where attributes may be harder to set. Attributes take priority when both are provided.
<user-story story-id="PROJ-142" priority="high" status="in-progress"> <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>
Priority Variants
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 persona="Security Engineer" action="receive alerts for authentication failures" benefit="I can respond to potential breaches immediately" priority="critical" status="to-do" story-id="SEC-301"></user-story>
Status Variants
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) |
JavaScript API
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}`);});
CSS Custom Properties
| 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 |
Events
| 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 |
Accessibility
- The outer card uses
role="article"witharia-label="User story" - Priority and status badges use color plus text labels — never color alone
- Story points badge has a
titleattribute reading "Story points" - Slot sections include visible headings for screen reader navigation
- Respects
prefers-reduced-motion: reduceby disabling hover transitions - Responsive layout stacks header badges vertically at narrow viewports (<480px)
Related
<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- UX Planning Pack — loads all six UX components together