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

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

Flow UI Logo

Flow UI DataTable #

A beautiful, universal Flutter data table with spreadsheet-style hover UX. Works with any row type and any column layout while keeping a polished, production-ready look.

Flow UI Datatable Preview

Features #

  • Universal API — generic FlowDataTable<T> with custom column definitions
  • Same UI/UX — hover highlight, subtle scale animation, bordered spreadsheet layout, dark/light theme support
  • Built-in cell types — text, avatar+subtitle, status badges, icon+text, dot indicator, dropdown
  • Sorting — per-column sort with client-side or server-side control
  • Pagination — optional footer with page navigation and page-size selector
  • Row selection — optional checkbox column with select-all
  • Row index — optional # column
  • Actions column — optional trailing actions per row
  • Loading & empty states
  • Horizontal scroll — for wide tables
  • Fully themeableFlowTableTheme for colors, sizes, fonts

Getting started #

Add to pubspec.yaml:

dependencies:
  flow_ui_datatable: ^0.1.0

Usage #

import 'package:flow_ui_datatable/flow_ui_datatable.dart';
import 'package:lucide_icons_flutter/lucide_icons.dart';

FlowDataTable<Product>(
  rows: products,
  showRowIndex: true,
  selectable: true,
  selectedRowIds: selectedIds,
  onSelectionChanged: (ids) => setState(() => selectedIds = ids),
  rowIdGetter: (product, _) => product.id,
  showActionsColumn: true,
  actionsBuilder: (context, product, index) => FlowCells.actionsButton(
    onPressed: () => _onAction(product),
  ),
  columns: [
    FlowColumn(
      id: 'name',
      label: 'Product',
      icon: LucideIcons.package,
      width: const FlowFlexColumnWidth(2),
      sortable: true,
      sortValue: (p) => p.name,
      cellBuilder: (context, product, _) => FlowCells.text(context, product.name),
    ),
    FlowColumn(
      id: 'status',
      label: 'Status',
      icon: LucideIcons.activity,
      cellBuilder: (context, product, _) => FlowCells.badge(context, product.status),
    ),
  ],
)

Built-in cells #

The library provides a FlowCells utility class containing pre-styled cells matching the design system:

  • Text cell:
    FlowCells.text(context, 'Text value')
    
  • Avatar with Subtitle:
    FlowCells.avatarWithSubtitle(context, title: 'John Doe', subtitle: 'john@example.com')
    
  • Badge cell:
    FlowCells.badge(context, 'Active')
    
  • Icon with Text:
    FlowCells.iconWithText(context, icon: LucideIcons.checkCircle, text: '5 done')
    
  • Dot Indicator with Text:
    FlowCells.dotWithText(context, text: 'Online', isActive: true)
    
  • Dropdown cell: An inline editable dropdown cell. Pass isPlain: true to display it as a plain text cell with a chevron down icon instead of a styled button pill.
    FlowCells.dropdown(
      context,
      value: role,
      options: const ['Admin', 'Member', 'Owner'],
      isPlain: true, // true for plain cell, false for styled button pill
      onChanged: (newRole) => setState(() => role = newRole),
    )
    

Custom cells #

Use any widget in cellBuilder:

FlowColumn(
  id: 'custom',
  label: 'Custom',
  cellBuilder: (context, row, index) => MyCustomWidget(data: row),
)

Pagination #

pagination: FlowPagination(
  currentPage: page,
  pageSize: 25,
  totalItems: totalCount,
  onPageChanged: (p) => setState(() => page = p),
  onPageSizeChanged: (size) => setState(() => pageSize = size),
),

Theming #

FlowDataTable<T>(
  theme: const FlowTableTheme(
    fontFamily: 'Inter',
    borderRadius: 8,
    rowHeight: 56,
  ),
  // ...
)

Example #

Live demo: flowui.lol

See the example/ folder for a full demo reproducing the original user-management table.

cd example
flutter run

AI Code Assistant Setup (skills.md) #

You can install skills.md rules into your workspace to help AI coding assistants (like Claude, Cursor, GitHub Copilot, Roo Code, or Antigravity) understand the flow_ui_datatable library specifications and design rules.

Run the interactive CLI installer to automatically install the rules for your favorite AI tools:

dart run flow_ui_datatable:install_skills

The installer will ask:

  • Which AI tools to install rules for (Cursor .cursorrules, Antigravity .gemini/skills/, Copilot .github/copilot-instructions.md, Cline/Roo Code .clinerules, or All).
  • Whether to install them globally (User profile folder) or locally for the current project.

Manual Setup #

If you prefer to install it manually, copy the text in the box below and create the rules file for your tool:

  • Cursor: Create .cursorrules in your project root.
  • Cline / Roo Code: Create .clinerules in your project root.
  • GitHub Copilot: Create .github/copilot-instructions.md in your project root.
  • Antigravity: Create .gemini/skills/flow_ui_datatable/SKILL.md in your project root.
Click to show manual rules.md content
---
name: flow_ui_datatable
description: Guidelines and instructions for creating beautiful, theme-compliant, and Material-free data tables using the flow_ui_datatable package.
---
# AI Assistant Rules & Skills for `flow_ui_datatable`

This file provides context, API specifications, and design guidelines for AI coding assistants (Claude, Cursor, Codex, Antigravity) to write correct, high-quality, and theme-compliant code using the `flow_ui_datatable` package.

---

## Core Guidelines & Architectural Rules

1. **Strictly Material-Free**:
   - The package library code (`lib/src/`) must **never** import `package:flutter/material.dart` or depend on a `Material` or `ThemeData` ancestor.
   - Use `package:flutter/widgets.dart` for layouts and structural components.
   - Use custom shapes and drawings (`CustomPaint`, `BoxDecoration`, `AnimatedContainer`, `GestureDetector`) rather than material buttons, check-boxes, or icons.
2. **Greyscale Clean Design System**:
   - Do **not** use the Material `Colors` utility class (e.g. `Colors.grey`, `Colors.white`).
   - Use hex color literals (`Color(0xFF...)`) for precise greyscale colors:
     - Borders: `Color(0xFFE5E7EB)` (Light mode Gray 200), `Color(0xFF1F1F1F)` (Dark mode neutral Gray)
     - Backgrounds: `Color(0xFFFFFFFF)` (Light mode pure white), `Color(0xFF000000)` (Dark mode pure black)
     - Cards/Headers: `Color(0xFFFAFAFA)` (Light mode Gray 50), `Color(0xFF0D0D0D)` (Dark mode Gray 900)
3. **Dynamic Theme Mode Detection**:
   - To check if the app is in dark mode without Material `Theme.of`, use `FlowTableTheme.isDark(context)`. It computes the luminance of the surrounding `DefaultTextStyle` color (light text = dark mode, dark text = light mode), falling back to `platformBrightness` when text styles are unavailable.

---

## API Reference

### `FlowDataTable<T>`
Universal, highly-performant, spreadsheet-style data table.

| Parameter | Type | Description |
| :--- | :--- | :--- |
| `columns` | `List<FlowColumn<T>>` | **Required**. List of columns to display. |
| `rows` | `List<T>` | **Required**. Data models list. |
| `theme` | `FlowTableTheme` | Theme override properties. Defaults to `FlowTableTheme.defaults`. |
| `selectable` | `bool` | Enables leading checkboxes for row selection. |
| `selectedRowIds` | `Set<String>` | The set of currently selected row IDs. |
| `onSelectionChanged` | `ValueChanged<Set<String>>?` | Triggers when rows are selected/deselected. |
| `rowIdGetter` | `String Function(T row, int index)?` | Extends unique selection keys per row. |
| `pagination` | `FlowPagination?` | Pagination configurations. |
| `clientSidePagination`| `bool` | Performs pagination slicing in memory. Defaults to `true`. |
| `sort` | `FlowTableSort?` | Active sorting state. |
| `onSortChanged` | `ValueChanged<FlowTableSort>?` | Callback when a sortable column header is tapped. |
| `clientSideSort` | `bool` | Performs sorting in-memory. Defaults to `true`. |
| `showRowIndex` | `bool` | Shows a leading numbering column (e.g., `#`). |
| `showActionsColumn` | `bool` | Shows a trailing actions column. |
| `actionsBuilder` | `Widget Function(BuildContext, T, int)?` | Builds custom action widgets. |

### `FlowColumn<T>`
Column definitions.

* **Constructor**:
  ```dart
  FlowColumn({
    required String id,
    required String label,
    required FlowCellBuilder<T> cellBuilder,
    IconData? icon,
    FlowColumnWidth width = const FlowFlexColumnWidth(1),
    bool center = false,
    bool sortable = false,
    Comparable<dynamic> Function(T row)? sortValue,
    String? tooltip,
  });

FlowCells (Predefined Cell Builders) #

Helper static methods returning standard cell layouts:

  1. Plain Text: FlowCells.text(context, value, {fontWeight, textAlign, maxLines, overflow})
  2. Avatar with Subtitle: FlowCells.avatarWithSubtitle(context, {title, subtitle, imageUrl, avatarRadius})
  3. Pill Badge: FlowCells.badge(context, label, {style, styleMap})
  4. Icon with Text: FlowCells.iconWithText(context, {icon, text, iconColor})
  5. Dot Status with Text: FlowCells.dotWithText(context, {text, isActive, activeColor})
  6. Plain/Styled Dropdown Menu: FlowCells.dropdown(context, {value, options, onChanged, isPlain})
  7. Ellipsis Actions Button: FlowCells.actionsButton({onPressed, icon})

Code Recipes #

Recipe 1: Basic In-Memory Table #

import 'package:flutter/widgets.dart';
import 'package:flow_ui_datatable/flow_ui_datatable.dart';

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

  @override
  Widget build(BuildContext context) {
    final users = [
      {'name': 'Alice Smith', 'role': 'Admin'},
      {'name': 'Bob Jones', 'role': 'Member'},
    ];

    return FlowDataTable<Map<String, String>>(
      rows: users,
      columns: [
        FlowColumn(
          id: 'name',
          label: 'Name',
          cellBuilder: (context, user, _) =>
              FlowCells.text(context, user['name']!),
        ),
        FlowColumn(
          id: 'role',
          label: 'Role',
          cellBuilder: (context, user, _) =>
              FlowCells.badge(context, user['role']!),
        ),
      ],
    );
  }
}

Recipe 2: Interactive Table with Selection, Sorting, and Pagination #

import 'package:flutter/widgets.dart';
import 'package:flow_ui_datatable/flow_ui_datatable.dart';
import 'package:lucide_icons_flutter/lucide_icons.dart';

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

  @override
  State<InteractiveUserTable> createState() => _InteractiveUserTableState();
}

class _InteractiveUserTableState extends State<InteractiveUserTable> {
  final List<User> _data = _getMockUsers();
  final Set<String> _selectedIds = {};
  
  int _page = 1;
  int _pageSize = 5;
  FlowTableSort? _sort;

  @override
  Widget build(BuildContext context) {
    return FlowDataTable<User>(
      rows: _data,
      selectable: true,
      selectedRowIds: _selectedIds,
      onSelectionChanged: (ids) => setState(() {
        _selectedIds.clear();
        _selectedIds.addAll(ids);
      }),
      rowIdGetter: (user, _) => user.id,
      sort: _sort,
      onSortChanged: (s) => setState(() => _sort = s),
      pagination: FlowPagination(
        currentPage: _page,
        pageSize: _pageSize,
        totalItems: _data.length,
        onPageChanged: (p) => setState(() => _page = p),
        onPageSizeChanged: (s) => setState(() {
          _pageSize = s;
          _page = 1;
        }),
      ),
      columns: [
        FlowColumn(
          id: 'name',
          label: 'Name',
          icon: LucideIcons.user,
          sortable: true,
          sortValue: (u) => u.name,
          cellBuilder: (context, user, _) =>
              FlowCells.text(context, user.name, fontWeight: FontWeight.bold),
        ),
        FlowColumn(
          id: 'status',
          label: 'Status',
          cellBuilder: (context, user, _) =>
              FlowCells.dotWithText(context, text: user.isActive ? 'Active' : 'Offline', isActive: user.isActive),
        ),
      ],
    );
  }
}

class User {
  const User(this.id, this.name, this.isActive);
  final String id;
  final String name;
  final bool isActive;
}

List<User> _getMockUsers() => [
  User('1', 'Alice', true),
  User('2', 'Bob', false),
  User('3', 'Charlie', true),
];

</details>

## License

See [LICENSE](LICENSE).

1
likes
160
points
88
downloads

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

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

Homepage
Repository (GitHub)
View/report issues

License

MIT (license)

Dependencies

flutter, lucide_icons_flutter

More

Packages that depend on flow_ui_datatable