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
Write API documentation
Set up CI/CD pipeline
In Progress
Implement auth flow
Review pull requests
Design homepage layout
Done
Database schema design
<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.