flow_ui_datatable 0.1.4 copy "flow_ui_datatable: ^0.1.4" to clipboard
flow_ui_datatable: ^0.1.4 copied to clipboard

A beautiful, universal Flutter data table with spreadsheet-style hover UX, sorting, pagination, and selection.

example/lib/main.dart

import 'package:flutter/material.dart';
import 'package:lucide_icons_flutter/lucide_icons.dart';

import 'showcases/showcase_registry.dart';
import 'widgets/showcase_shell.dart';

//test
void main() {
  runApp(const FlowDataTableDemoApp());
}

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

  @override
  State<FlowDataTableDemoApp> createState() => _FlowDataTableDemoAppState();
}

class _FlowDataTableDemoAppState extends State<FlowDataTableDemoApp> {
  ThemeMode _themeMode = ThemeMode.light;
  int _selectedIndex = 0;

  @override
  Widget build(BuildContext context) {
    final selected = showcaseItems[_selectedIndex];

    return MaterialApp(
      title: 'Flow Data Table',
      debugShowCheckedModeBanner: false,
      themeMode: _themeMode,
      theme: ThemeData(
        brightness: Brightness.light,
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.indigo),
        useMaterial3: true,
        fontFamily: 'Inter',
      ),
      darkTheme: ThemeData(
        brightness: Brightness.dark,
        colorScheme: ColorScheme.fromSeed(
          seedColor: Colors.indigo,
          brightness: Brightness.dark,
        ),
        useMaterial3: true,
        fontFamily: 'Inter',
      ),
      home: Scaffold(
        appBar: AppBar(
          title: const Row(
            children: [
              Icon(LucideIcons.tableProperties, size: 22),
              SizedBox(width: 10),
              Text('flow_ui_datatable'),
            ],
          ),
          actions: [
            IconButton(
              tooltip: 'Toggle theme',
              icon: Icon(
                _themeMode == ThemeMode.dark
                    ? LucideIcons.sun
                    : LucideIcons.moon,
              ),
              onPressed: () => setState(() {
                _themeMode = _themeMode == ThemeMode.dark
                    ? ThemeMode.light
                    : ThemeMode.dark;
              }),
            ),
          ],
        ),
        body: LayoutBuilder(
          builder: (context, constraints) {
            final useRail = constraints.maxWidth >= 900;

            if (useRail) {
              return Row(
                children: [
                  _buildSidebar(context, extended: true),
                  Expanded(
                    child: Padding(
                      padding: const EdgeInsets.all(24),
                      child: ShowcaseShell(item: selected),
                    ),
                  ),
                ],
              );
            }

            return Column(
              children: [
                SizedBox(
                  height: 56,
                  child: ListView.builder(
                    scrollDirection: Axis.horizontal,
                    padding: const EdgeInsets.symmetric(horizontal: 12),
                    itemCount: showcaseItems.length,
                    itemBuilder: (context, index) {
                      final item = showcaseItems[index];
                      final isSelected = index == _selectedIndex;
                      return Padding(
                        padding: const EdgeInsets.symmetric(horizontal: 4),
                        child: ChoiceChip(
                          label: Text(item.title),
                          selected: isSelected,
                          onSelected: (_) =>
                              setState(() => _selectedIndex = index),
                        ),
                      );
                    },
                  ),
                ),
                Expanded(
                  child: Padding(
                    padding: const EdgeInsets.all(16),
                    child: ShowcaseShell(item: selected),
                  ),
                ),
              ],
            );
          },
        ),
      ),
    );
  }

  Widget _buildSidebar(BuildContext context, {required bool extended}) {
    final theme = Theme.of(context);

    return NavigationRail(
      extended: extended,
      minExtendedWidth: 220,
      selectedIndex: _selectedIndex,
      onDestinationSelected: (index) => setState(() => _selectedIndex = index),
      labelType: extended
          ? NavigationRailLabelType.none
          : NavigationRailLabelType.all,
      leading: Padding(
        padding: const EdgeInsets.symmetric(vertical: 16),
        child: Text(
          'Showcases',
          style: theme.textTheme.labelLarge?.copyWith(
            fontWeight: FontWeight.bold,
            color: theme.colorScheme.primary,
          ),
        ),
      ),
      destinations: showcaseItems
          .map(
            (item) => NavigationRailDestination(
              icon: Icon(item.icon),
              label: Text(item.title),
            ),
          )
          .toList(),
    );
  }
}
1
likes
0
points
88
downloads

Publisher

unverified uploader

Weekly Downloads

A beautiful, universal Flutter data table with spreadsheet-style hover UX, sorting, pagination, and selection.

Repository (GitHub)
View/report issues

License

unknown (license)

Dependencies

flutter, lucide_icons_flutter

More

Packages that depend on flow_ui_datatable