Kanban Board
Overview
An enterprise-grade Kanban board pluggable widget for Mendix 10.x+ with drag-and-drop, RTL/Arabic support, WIP limits, animations, multi-language support, and full WCAG 2.1 AA accessibility.
Documentation
Kanban Board Widget for Mendix
An enterprise-grade Kanban board pluggable widget for Mendix 10.x+ with drag-and-drop, RTL/Arabic support, WIP limits, animations, multi-language support, and full WCAG 2.1 AA accessibility.
Features
- Drag-and-drop cards between columns and within the same column using
@hello-pangea/dnd - Composable card content (drop any Mendix widgets inside cards)
- Proper sort order reindexing — no duplicate SortOrder values after drops
- WIP (Work In Progress) limits with visual warning states and optional drop blocking
- Column collapse/expand with smart drag-time auto-expand
- Search/filter bar with debounced input and multi-language placeholder
- Multi-language support — column titles, empty state text, and filter placeholder use Mendix textTemplate
- Horizontal and vertical layout direction
- Modern animations with on/off toggle (hover lift, drag shadow, drop zone glow, column accent)
- Full RTL/Arabic support with CSS logical properties and auto-detection
- WCAG 2.1 AA accessible (keyboard drag, ARIA labels, screen reader announcements)
- Studio Pro design-time preview
- Skeleton loading state
- Empty column placeholders
Installation
- Download it !
Domain Model Setup
Your entity needs at minimum:
Attribute | Type | Purpose |
| Enumeration | Determines which column the item belongs to |
| Integer | Stores the sort position within a column |
| String | (Optional) Used for filter/search |
Column Configuration
- Add the Kanban Board widget to a page
- In the Columns property, add one entry per column:
- Column ID: Expression — unique string matching your status value (e.g.,
'ToDo') - Column Title: Text template — display name, translatable per language in Studio Pro
- Column Color: Expression — hex color for the header accent bar (e.g.,
'#4CAF50') - Column Items: Datasource filtered by status, sorted by SortOrder ascending
- Card Content: Drop your card layout widgets here
- Sort Attribute: Select the
SortOrderinteger attribute - On Drop Action: A nanoflow called for each drop with action variables:
$destinationColumnId(String)$destinationIndex(Integer)$sourceColumnId(String)$sourceIndex(Integer)
- WIP Limit: Expression — max cards allowed (0 or empty = unlimited)
- Allow Drop When Limit Exceeded: Boolean — default Yes; set to No to block drops when over WIP limit
- Is Collapsible: Expression — whether users can collapse this column
- Empty State Text: Text template — shown when column has no cards
- Filter Attribute: String attribute used for search filtering
- Column ID: Expression — unique string matching your status value (e.g.,
See HOW-TO-CONFIG.md for full property reference and HOW-TO-TEST.md for step-by-step setup.
On Drop Nanoflow — Proper Sort Order Reindexing
You can download the nanoflow "ACT_Kanban_OnDrop" in Resources section, this will help you to start if you want to do your own implementation then check the below explaination
Setting SortOrder = $DestinationIndex directly causes duplicate values when inserting between existing cards. The correct approach shifts existing items to make room.
Cross-column move ($SourceColumnId != $DestinationColumnId)
- Retrieve destination items WHERE
SortOrder >= $DestinationIndex→ loop, setSortOrder = SortOrder + 1 - Change
$currentObject: Status = destination, SortOrder =$DestinationIndex - Retrieve source items WHERE
SortOrder > $SourceIndex→ loop, setSortOrder = SortOrder - 1 - Commit all
Same-column move — Moving DOWN ($SourceIndex < $DestinationIndex)
- Retrieve items WHERE
SortOrder > $SourceIndex AND SortOrder <= $DestinationIndex→ loop, setSortOrder = SortOrder - 1 - Change
$currentObject: SortOrder =$DestinationIndex - Commit all
Same-column move — Moving UP ($SourceIndex > $DestinationIndex)
- Retrieve items WHERE
SortOrder >= $DestinationIndex AND SortOrder < $SourceIndex→ loop, setSortOrder = SortOrder + 1 - Change
$currentObject: SortOrder =$DestinationIndex - Commit all
The XPath range boundaries naturally exclude $currentObject in all cases — no special ID filtering needed.RTL / Arabic Setup
The widget auto-detects RTL from:
- The Force RTL Layout property (if set to
true) document.documentElement.dir === "rtl"document.documentElement.langstarting withar,he,fa, orur
When RTL is active:
- Columns render right-to-left (first column on the right)
- Filter bar text aligns right
- Count badge appears closest to the column title, collapse button at the far end
- Drag tilt mirrors direction (-1.5deg)
- ARIA labels switch to Arabic
- Vertical layout cards flow right-to-left with correct DnD behavior
WIP Limits
For each column, set the WIP Limit expression to an integer value:
0or empty = unlimited (no badge shown)- Card count equals limit → yellow warning header
- Card count exceeds limit → red warning header with
aria-liveannouncement
Set Allow Drop When Limit Exceeded to No to block drops entirely when the column is over its limit.
Collapsible Columns
When Is Collapsible is true:
- Column shows a toggle button (▼/▶) in the header
- Collapsed columns show only the header — a small invisible area remains for DnD detection
- When a drag starts, all collapsed columns auto-expand so you can choose exactly where to drop a card
- Re-collapse After Drop: configure whether collapsed columns re-collapse after a card is dropped into them
Accessibility
- Full keyboard drag-and-drop (Space to pick up, arrows to move, Space to drop, Escape to cancel)
- ARIA roles:
regionon board,groupon columns aria-liveannouncements for WIP limit warningsfocus-visibleoutlines for keyboard navigation- Drag handle usage instructions in English and Arabic
License
Apache-2.0