impact-effort
2x2 prioritization matrix with drag-and-drop between quadrants (Quick Wins, Big Bets, Fill-Ins, Money Pit).
Overview
A web component that renders a 2×2 impact/effort prioritization matrix with four quadrants: Quick Wins, Big Bets, Fill-Ins, and Money Pit. Items can be dragged between quadrants using native drag-and-drop or transferred via keyboard. Built on <drag-surface> for reorder and cross-surface transfer. Ideal for sprint prioritization, feature triage, and design workshops.
<impact-effort> <user-story data-quadrant="quick-wins" draggable="true" data-id="PROJ-101" persona="Sarah Chen" action="add keyboard shortcuts to the dashboard" priority="high" status="to-do" points="2" compact> </user-story> <user-story data-quadrant="quick-wins" draggable="true" data-id="PROJ-102" persona="Alex Rivera" action="fix broken pagination on search results" priority="medium" status="backlog" points="1" compact> </user-story> <user-story data-quadrant="big-bets" draggable="true" data-id="PROJ-103" persona="Sarah Chen" action="rebuild the reporting engine with real-time data" priority="high" status="in-progress" points="13" compact> </user-story> <user-story data-quadrant="fill-ins" draggable="true" data-id="PROJ-104" persona="Alex Rivera" action="update placeholder copy on the settings page" priority="low" status="backlog" points="1" compact> </user-story> <user-story data-quadrant="money-pit" draggable="true" data-id="PROJ-105" persona="Sarah Chen" action="migrate legacy reports to new PDF renderer" priority="medium" status="backlog" points="8" compact> </user-story></impact-effort>
Attributes
| Attribute | Type | Default | Description |
|---|---|---|---|
src |
string (URL) | — | Path to a JSON file containing an array of item objects |
compact |
boolean | — | Reduces grid height, padding, and label sizes for denser layouts |
title |
string | — | Optional heading displayed above the matrix |
Child Attributes
Each direct child of <impact-effort> represents an item in the matrix. These attributes control placement and drag behavior:
| Attribute | Type | Default | Description |
|---|---|---|---|
data-quadrant |
enum | "quick-wins" |
Target quadrant: quick-wins, big-bets, fill-ins, or money-pit |
draggable |
boolean | — | Must be set to "true" for drag capability. Auto-applied if missing. |
data-id |
string | auto-generated | Stable identifier for the item, included in event detail. Auto-generated if missing. |
Quadrant Descriptions
The matrix maps items along two axes — Impact (vertical) and Effort (horizontal) — creating four strategic quadrants:
| Quadrant | Position | Description | Typical Items |
|---|---|---|---|
quick-wins |
Top-left | High impact · Low effort | Easy fixes, quick improvements, low-hanging fruit |
big-bets |
Top-right | High impact · High effort | Major features, platform rewrites, strategic investments |
fill-ins |
Bottom-left | Low impact · Low effort | Nice-to-haves, polish tasks, minor enhancements |
money-pit |
Bottom-right | Low impact · High effort | Expensive features with unclear ROI, legacy migrations |
Axis labels ("Impact" with an up arrow, "Effort" with a right arrow) are rendered alongside the grid for visual context. Each quadrant has a subtle background tint — green for Quick Wins, amber for Big Bets, blue for Fill-Ins, and red for Money Pit.
Drag Interaction
Items move between quadrants via native drag-and-drop. Each quadrant contains a <drag-surface> element sharing the same group identifier, enabling cross-surface transfers.
- Drag — grab any item and drop it onto a different quadrant. The item's
data-quadrantattribute updates automatically. - Keyboard —
<drag-surface>provides keyboard reorder and transfer. Focus an item and use the keyboard shortcuts to move it between surfaces. - Live announcement — when an item moves between quadrants, a hidden live region announces the change for screen readers (e.g., "Moved PROJ-101 to Big Bets").
const matrix = document.querySelector('impact-effort'); matrix.addEventListener('impact-effort:move', (e) => { console.log(`${e.detail.itemId} moved from ${e.detail.from} to ${e.detail.to}`);});
Data Mode
Load items from a JSON file by setting the src attribute. The file should contain an array of item objects, each with an id, quadrant, and label (or text).
[ { "id": "PROJ-101", "quadrant": "quick-wins", "label": "Add keyboard shortcuts" }, { "id": "PROJ-102", "quadrant": "big-bets", "label": "Rebuild reporting engine" }, { "id": "PROJ-103", "quadrant": "fill-ins", "label": "Update placeholder copy" }, { "id": "PROJ-104", "quadrant": "money-pit", "label": "Migrate legacy PDF renderer" }]
<impact-effort src="/data/prioritization.json"></impact-effort>
Each JSON entry creates an <article> element with draggable="true" and the appropriate data-quadrant and data-id attributes. For richer item rendering, use <user-story> children directly in HTML instead of JSON mode.
Events
| Event | Detail | When |
|---|---|---|
impact-effort:move |
{ itemId, from, to, item } |
Fires when an item is dragged between quadrants. from and to are quadrant names. |
impact-effort:ready |
{ quadrantCounts } |
Fires after the component initializes. quadrantCounts is an object mapping each quadrant name to the number of items it contains. |
Accessibility
- The grid uses
role="region"witharia-label="Impact-Effort prioritization matrix" - Each quadrant section has an
aria-labelcombining the quadrant name and its impact/effort description (e.g., "Quick Wins: High impact · Low effort") - Axis labels ("Impact" and "Effort") use
aria-hidden="true"since the quadrant labels already convey the meaning - A hidden live region with
aria-live="polite"announces item moves between quadrants - Keyboard transfer is provided by the underlying
<drag-surface>components - Respects
prefers-reduced-motion: reduceby disabling all transitions - Uses
container-type: inline-sizeand stacks to a single column at narrow viewports (<30rem) - Print styles remove minimum heights, set static cursors, and add visible borders
Related
<user-story>— Story cards that serve as draggable items in the matrix<empathy-map>— Empathy maps for discovering pain points to prioritize<story-map>— Horizontal story mapping for sprint planning<user-persona>— Persona cards providing context for prioritized items<drag-surface>— The underlying drag-and-drop primitive used by each quadrant- UX Planning Pack — loads all six UX components together