voo_kanban 0.0.2 copy "voo_kanban: ^0.0.2" to clipboard
voo_kanban: ^0.0.2 copied to clipboard

A highly customizable Kanban board widget for Flutter with drag-and-drop, swimlanes, WIP limits, and extensive theming

example/lib/main.dart

import 'package:flutter/material.dart';
import 'pages/basic_board_page.dart';
import 'pages/swimlanes_page.dart';
import 'pages/drag_drop_page.dart';
import 'pages/theming_page.dart';

void main() {
  runApp(const VooKanbanExampleApp());
}

class VooKanbanExampleApp extends StatelessWidget {
  const VooKanbanExampleApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Voo Kanban Examples',
      debugShowCheckedModeBanner: false,
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.indigo),
        useMaterial3: true,
      ),
      darkTheme: ThemeData(
        colorScheme: ColorScheme.fromSeed(
          seedColor: Colors.indigo,
          brightness: Brightness.dark,
        ),
        useMaterial3: true,
      ),
      themeMode: ThemeMode.system,
      home: const HomePage(),
    );
  }
}

class HomePage extends StatefulWidget {
  const HomePage({super.key});

  @override
  State<HomePage> createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  int _selectedIndex = 0;

  final List<_NavigationItem> _pages = [
    _NavigationItem(
      icon: Icons.view_kanban,
      label: 'Basic',
      page: const BasicBoardPage(),
    ),
    _NavigationItem(
      icon: Icons.view_week,
      label: 'Swimlanes',
      page: const SwimlanesPage(),
    ),
    _NavigationItem(
      icon: Icons.drag_indicator,
      label: 'Drag & Drop',
      page: const DragDropPage(),
    ),
    _NavigationItem(
      icon: Icons.palette,
      label: 'Theming',
      page: const ThemingPage(),
    ),
  ];

  @override
  Widget build(BuildContext context) {
    final isDesktop = MediaQuery.of(context).size.width >= 900;
    final isTablet = MediaQuery.of(context).size.width >= 600 &&
        MediaQuery.of(context).size.width < 900;
    final isMobile = !isDesktop && !isTablet;

    return Scaffold(
      appBar: AppBar(
        title: const Text('Voo Kanban Examples'),
        centerTitle: true,
        elevation: 0,
        backgroundColor: Theme.of(context).colorScheme.primaryContainer,
        foregroundColor: Theme.of(context).colorScheme.onPrimaryContainer,
      ),
      drawer: isMobile
          ? Drawer(
              child: ListView(
                children: [
                  DrawerHeader(
                    decoration: BoxDecoration(
                      color: Theme.of(context).colorScheme.primaryContainer,
                    ),
                    child: Column(
                      crossAxisAlignment: CrossAxisAlignment.start,
                      mainAxisAlignment: MainAxisAlignment.end,
                      children: [
                        Icon(
                          Icons.view_kanban,
                          size: 48,
                          color:
                              Theme.of(context).colorScheme.onPrimaryContainer,
                        ),
                        const SizedBox(height: 8),
                        Text(
                          'Voo Kanban',
                          style: Theme.of(context)
                              .textTheme
                              .headlineSmall
                              ?.copyWith(
                                color: Theme.of(context)
                                    .colorScheme
                                    .onPrimaryContainer,
                              ),
                        ),
                      ],
                    ),
                  ),
                  ..._pages.asMap().entries.map((entry) {
                    final index = entry.key;
                    final item = entry.value;
                    return ListTile(
                      leading: Icon(item.icon),
                      title: Text(item.label),
                      selected: _selectedIndex == index,
                      onTap: () {
                        setState(() => _selectedIndex = index);
                        Navigator.of(context).pop();
                      },
                    );
                  }),
                ],
              ),
            )
          : null,
      body: Row(
        children: [
          if (isDesktop || isTablet)
            NavigationRail(
              selectedIndex: _selectedIndex,
              onDestinationSelected: (index) {
                setState(() => _selectedIndex = index);
              },
              labelType: isDesktop
                  ? NavigationRailLabelType.all
                  : NavigationRailLabelType.selected,
              destinations: _pages
                  .map((item) => NavigationRailDestination(
                        icon: Icon(item.icon),
                        label: Text(item.label),
                      ))
                  .toList(),
            ),
          Expanded(child: _pages[_selectedIndex].page),
        ],
      ),
    );
  }
}

class _NavigationItem {
  final IconData icon;
  final String label;
  final Widget page;

  const _NavigationItem({
    required this.icon,
    required this.label,
    required this.page,
  });
}
1
likes
160
points
180
downloads

Publisher

verified publishervoostack.com

Weekly Downloads

A highly customizable Kanban board widget for Flutter with drag-and-drop, swimlanes, WIP limits, and extensive theming

Homepage
Repository (GitHub)
View/report issues

Topics

#flutter #kanban #board #drag-drop #widget

Documentation

API reference

License

MIT (license)

Dependencies

equatable, flutter, voo_motion, voo_responsive, voo_tokens, voo_ui_core

More

Packages that depend on voo_kanban