A powerful, customizable Kanban board library for Flutter applications built with clean architecture principles. It provides a complete solution for implementing Kanban-style task management with features like drag-and-drop, column limits, and persistent storage.
- Drag and drop tasks between columns
- Long press to initiate task dragging
- Configurable column limits (WIP limits)
- Custom task card designs
- Column-specific settings (e.g., disable adding tasks)
- Clear all tasks in "Done" column
- Persistent storage support
- Responsive layout design
- Material Design components
- Customizable themes (light/dark/custom)
- Loading states and progress indicators
- Error handling with user feedback
- Confirmation dialogs
- Mouse cursor support and tooltips
- Task editing and deletion
- Visual feedback during drag operations
- Clean Architecture implementation
- Event-driven updates
- Dependency injection using GetIt
- Extensive test coverage
- Type-safe implementations
Add to your pubspec.yaml
:
dependencies:
clean_kanban: ^0.0.1
void main() {
// Initialize with memory storage
setupInjection(MemoryBoardRepository());
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return ChangeNotifierProvider(
create: (_) => BoardProvider()..loadBoard(),
child: MaterialApp(
home: Scaffold(
body: BoardWidget(
theme: KanbanTheme.light(),
),
),
),
);
}
}
final config = {
'columns': [
{
'id': 'backlog',
'header': 'Backlog',
'limit': 10,
'tasks': [
{
'id': '1',
'title': 'Implement feature',
'subtitle': 'Add new functionality'
}
]
},
{
'id': 'inProgress',
'header': 'In Progress',
'limit': 3,
'canAddTask': false
},
{
'id': 'review',
'header': 'Review',
'limit': 5,
'canAddTask': false
},
{
'id': 'done',
'header': 'Done',
'canAddTask': false
}
]
};
// Load with custom config
BoardProvider()..loadBoard(config: config);
BoardWidget(
theme: KanbanTheme.light(),
)
BoardWidget(
theme: KanbanTheme.dark(),
)
// This automatically adapts to your app's ThemeData
BoardWidget(
theme: KanbanTheme.fromTheme(Theme.of(context)),
)
This approach is recommended as it:
- Ensures consistency with your app's Material 3 theme
- Automatically adapts to light/dark mode changes
- Uses the appropriate color scheme variants from your theme
- Simplifies theme management in your application
BoardWidget(
theme: KanbanTheme(
columnTheme: KanbanColumnTheme(
columnBackgroundColor: Colors.grey[100],
columnHeaderColor: Colors.blue,
columnHeaderTextColor: Colors.white,
),
cardTheme: TaskCardTheme(
cardBackgroundColor: Colors.white,
cardTitleColor: Colors.black87,
cardSubtitleColor: Colors.black54,
),
boardBackgroundColor: Colors.grey[200],
),
)
Implement your own storage solution:
class SharedPreferencesBoardRepository implements BoardRepository {
static const String _boardKey = 'kanban_board';
@override
Future<Board> getBoard() async {
final prefs = await SharedPreferences.getInstance();
final boardJson = prefs.getString(_boardKey);
if (boardJson == null) throw Exception('No board saved');
return Board.fromConfig(jsonDecode(boardJson));
}
@override
Future<void> saveBoard(Board board) async {
final prefs = await SharedPreferences.getInstance();
await prefs.setString(_boardKey, jsonEncode(board.toJson()));
}
@override
Future<void> updateBoard(Board board) async {
await saveBoard(board);
}
}
Listen to board events:
EventNotifier().subscribe((event) {
switch (event) {
case TaskMovedEvent moved:
print('Task moved from ${moved.source.header} to ${moved.destination.header}');
case TaskAddedEvent added:
print('New task added: ${added.task.title}');
case DoneColumnClearedEvent cleared:
print('${cleared.removedTasks.length} tasks cleared from Done column');
}
});
flutter test
cd example
flutter run
- Flutter SDK ^3.6.2
- Dart SDK ^3.6.2
Contributions are welcome! Please read our Contributing Guide for details.
This project is licensed under the GNU General Public License v3.0 - see the LICENSE file for details.
- π README
- π Issue Tracker
- π¬ Discussions