Kanban Board
Drag-and-drop Kanban board with native HTML Drag and Drop, keyboard navigation, and htmx server persistence.
<rhx-kanban>
Examples
Interactive Board
Drag cards between columns. The "In Progress" column has a WIP limit of 3. Each drop sends a POST to the server with the card ID, source and target columns, and position.
To Do
Design homepage layout
Implement auth flow
Write API documentation
Database schema design
In Progress
Review pull requests
Done
Set up CI/CD pipeline
<rhx-kanban>
<rhx-kanban-column rhx-column-id="todo" rhx-title="To Do">
<rhx-kanban-card rhx-card-id="1"
hx-post="/Board?handler=Move"
hx-target="#board" hx-swap="innerHTML">
Design homepage
</rhx-kanban-card>
</rhx-kanban-column>
<rhx-kanban-column rhx-column-id="doing" rhx-title="In Progress"
rhx-max-cards="3" />
<rhx-kanban-column rhx-column-id="done" rhx-title="Done" />
</rhx-kanban>
Card Variants
Use rhx-variant to color-code cards by category, priority, or type.
Default
Brand
Success
Warning
Danger
WIP Limits
Set rhx-max-cards on a column. When the card count reaches the limit, the column header turns red as a visual warning.
<!-- Column shows a warning when card count >= max -->
<rhx-kanban-column rhx-column-id="doing"
rhx-title="In Progress"
rhx-max-cards="3">
...
</rhx-kanban-column>
Server Handler
The card's hx-post sends cardId, sourceColumn, targetColumn, and position as form values. Return a partial to re-render the board.
public IActionResult OnPostMove(
string cardId, string sourceColumn,
string targetColumn, int position)
{
_service.MoveCard(cardId, targetColumn, position);
return Partial("_BoardPartial", _service.GetTasks());
}
Properties
| Property | Type | Default | Description |
|---|---|---|---|
rhx-column-id |
string |
- |
Unique column identifier (sent with drop POST) |
rhx-title |
string |
- |
Column header display text |
rhx-max-cards |
int |
- |
Work-in-progress limit (visual indicator when exceeded) |
rhx-droppable |
bool |
true |
Whether cards can be dropped into this column |
rhx-card-id |
string |
- |
Unique card identifier (sent with drop POST) |
rhx-draggable |
bool |
true |
Whether this card can be dragged |
rhx-variant |
string |
- |
Card color variant: brand, success, warning, danger |
Keyboard Navigation
- Tab to focus a card.
- Enter / Space to grab the focused card.
- Arrow Left / Right moves the grabbed card to the previous or next column.
- Arrow Up / Down reorders the grabbed card within its column.
- Enter / Space again to drop and persist the move to the server.
- Escape cancels the grab without persisting.
Accessibility
- Cards are focusable with
tabindex="0"and setaria-grabbedwhen grabbed. - The board container uses
role="group"for semantic grouping. - WIP limit exceeded state uses a distinct danger border color.
- Reduced motion preferences disable card transition animations.