Repository: rodydavis/data_tables
Branch: master
Commit: f8bda5480399
Files: 30
Total size: 49.4 KB
Directory structure:
gitextract_scyshgbk/
├── .gitattributes
├── .github/
│ └── workflows/
│ └── main.yml
├── .gitignore
├── .idea/
│ ├── codeStyles/
│ │ └── Project.xml
│ ├── libraries/
│ │ ├── Dart_SDK.xml
│ │ ├── Flutter_Plugins.xml
│ │ └── Flutter_for_Android.xml
│ ├── modules.xml
│ ├── runConfigurations/
│ │ └── example_lib_main_dart.xml
│ ├── vcs.xml
│ └── workspace.xml
├── .metadata
├── .vscode/
│ ├── launch.json
│ └── settings.json
├── CHANGELOG.md
├── LICENSE
├── README.md
├── analysis_options.yaml
├── data_tables.iml
├── example/
│ ├── ios/
│ │ └── Flutter/
│ │ └── flutter_export_environment.sh
│ ├── linux/
│ │ └── flutter/
│ │ ├── generated_plugin_registrant.cc
│ │ └── generated_plugin_registrant.h
│ ├── macos/
│ │ └── Flutter/
│ │ └── ephemeral/
│ │ ├── Flutter-Generated.xcconfig
│ │ └── flutter_export_environment.sh
│ └── windows/
│ └── flutter/
│ ├── generated_plugin_registrant.cc
│ └── generated_plugin_registrant.h
├── lib/
│ ├── data_tables.dart
│ └── ui/
│ ├── mobile_paged_listview.dart
│ └── stateless_datatable.dart
└── pubspec.yaml
================================================
FILE CONTENTS
================================================
================================================
FILE: .gitattributes
================================================
# Auto detect text files and perform LF normalization
* text=auto
================================================
FILE: .github/workflows/main.yml
================================================
name: github pages
on:
push:
branches:
- master
jobs:
deploy:
runs-on: ubuntu-18.04
steps:
- uses: actions/checkout@v2
- name: Setup Flutter
uses: subosito/flutter-action@v1
with:
channel: 'stable'
- name: Install
run: flutter pub get
- name: Build
run: cd example && flutter build web
- name: Deploy
uses: peaceiris/actions-gh-pages@v3
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./example/build/web
================================================
FILE: .gitignore
================================================
.DS_Store
.dart_tool/
.packages
.pub/
build/
================================================
FILE: .idea/codeStyles/Project.xml
================================================
<component name="ProjectCodeStyleConfiguration">
<code_scheme name="Project" version="173">
<Objective-C-extensions>
<file>
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Import" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Macro" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Typedef" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Enum" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Constant" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Global" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Struct" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="FunctionPredecl" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Function" />
</file>
<class>
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Property" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Synthesize" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="InitMethod" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="StaticMethod" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="InstanceMethod" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="DeallocMethod" />
</class>
<extensions>
<pair source="cpp" header="h" fileNamingConvention="NONE" />
<pair source="c" header="h" fileNamingConvention="NONE" />
</extensions>
</Objective-C-extensions>
</code_scheme>
</component>
================================================
FILE: .idea/libraries/Dart_SDK.xml
================================================
<component name="libraryTable">
<library name="Dart SDK">
<CLASSES>
<root url="file:///Users/developer/flutter/bin/cache/dart-sdk/lib/async" />
<root url="file:///Users/developer/flutter/bin/cache/dart-sdk/lib/collection" />
<root url="file:///Users/developer/flutter/bin/cache/dart-sdk/lib/convert" />
<root url="file:///Users/developer/flutter/bin/cache/dart-sdk/lib/core" />
<root url="file:///Users/developer/flutter/bin/cache/dart-sdk/lib/developer" />
<root url="file:///Users/developer/flutter/bin/cache/dart-sdk/lib/html" />
<root url="file:///Users/developer/flutter/bin/cache/dart-sdk/lib/io" />
<root url="file:///Users/developer/flutter/bin/cache/dart-sdk/lib/isolate" />
<root url="file:///Users/developer/flutter/bin/cache/dart-sdk/lib/math" />
<root url="file:///Users/developer/flutter/bin/cache/dart-sdk/lib/mirrors" />
<root url="file:///Users/developer/flutter/bin/cache/dart-sdk/lib/typed_data" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>
================================================
FILE: .idea/libraries/Flutter_Plugins.xml
================================================
<component name="libraryTable">
<library name="Flutter Plugins" type="FlutterPluginsLibraryType">
<CLASSES>
<root url="file://$PROJECT_DIR$" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>
================================================
FILE: .idea/libraries/Flutter_for_Android.xml
================================================
<component name="libraryTable">
<library name="Flutter for Android">
<CLASSES>
<root url="jar:///Users/developer/flutter/bin/cache/artifacts/engine/android-arm/flutter.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>
================================================
FILE: .idea/modules.xml
================================================
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/data_tables.iml" filepath="$PROJECT_DIR$/data_tables.iml" />
<module fileurl="file://$PROJECT_DIR$/android/data_tables_android.iml" filepath="$PROJECT_DIR$/android/data_tables_android.iml" />
<module fileurl="file://$PROJECT_DIR$/example/android/data_tables_example_android.iml" filepath="$PROJECT_DIR$/example/android/data_tables_example_android.iml" />
</modules>
</component>
</project>
================================================
FILE: .idea/runConfigurations/example_lib_main_dart.xml
================================================
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="example/lib/main.dart" type="FlutterRunConfigurationType" factoryName="Flutter">
<option name="filePath" value="$PROJECT_DIR$/example/lib/main.dart" />
<method />
</configuration>
</component>
================================================
FILE: .idea/vcs.xml
================================================
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$/../.." vcs="Git" />
</component>
</project>
================================================
FILE: .idea/workspace.xml
================================================
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ChangeListManager">
<list default="true" id="ca160bec-0575-4943-95ce-117072a81cb2" name="Default Changelist" comment="">
<change beforePath="$PROJECT_DIR$/../data_table/.gitignore" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/../data_table/.idea/codeStyles/Project.xml" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/../data_table/.idea/libraries/Dart_Packages.xml" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/../data_table/.idea/libraries/Dart_SDK.xml" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/../data_table/.idea/libraries/Flutter_Plugins.xml" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/../data_table/.idea/modules.xml" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/../data_table/.idea/vcs.xml" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/../data_table/.idea/workspace.xml" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/../data_table/.metadata" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/../data_table/CHANGELOG.md" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/../data_table/LICENSE" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/../data_table/README.md" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/../data_table/data_table.iml" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/../data_table/lib/data_table.dart" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/../data_table/pubspec.yaml" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/../data_table/test/data_table_test.dart" beforeDir="false" />
</list>
<ignored path="$PROJECT_DIR$/.dart_tool/" />
<ignored path="$PROJECT_DIR$/.idea/" />
<ignored path="$PROJECT_DIR$/.pub/" />
<ignored path="$PROJECT_DIR$/build/" />
<ignored path="$PROJECT_DIR$/example/.pub/" />
<ignored path="$PROJECT_DIR$/example/build/" />
<option name="EXCLUDED_CONVERTED_TO_IGNORED" value="true" />
<option name="SHOW_DIALOG" value="false" />
<option name="HIGHLIGHT_CONFLICTS" value="true" />
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
<option name="LAST_RESOLUTION" value="IGNORE" />
</component>
<component name="FUSProjectUsageTrigger">
<session id="-268260249">
<usages-collector id="statistics.lifecycle.project">
<counts>
<entry key="project.closed" value="1" />
<entry key="project.open.time.1" value="1" />
<entry key="project.opened" value="1" />
</counts>
</usages-collector>
</session>
</component>
<component name="FileEditorManager">
<leaf SIDE_TABS_SIZE_LIMIT_KEY="300">
<file pinned="false" current-in-tab="true">
<entry file="file://$PROJECT_DIR$/lib/data_tables.dart">
<provider selected="true" editor-type-id="text-editor" />
</entry>
</file>
<file pinned="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/example/lib/main.dart">
<provider selected="true" editor-type-id="text-editor" />
</entry>
</file>
</leaf>
</component>
<component name="Git.Settings">
<option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$/../.." />
</component>
<component name="ProjectFrameBounds">
<option name="x" value="683" />
<option name="y" value="343" />
<option name="width" value="2569" />
<option name="height" value="1529" />
</component>
<component name="ProjectLevelVcsManager" settingsEditedManually="true" />
<component name="ProjectView">
<navigator currentView="ProjectPane" proportions="" version="1">
<foldersAlwaysOnTop value="true" />
</navigator>
<panes>
<pane id="ProjectPane">
<subPane>
<expand>
<path>
<item name="data_tables" type="b2602c69:ProjectViewProjectNode" />
<item name="data_tables" type="462c0819:PsiDirectoryNode" />
</path>
</expand>
<select />
</subPane>
<option name="show-excluded-files" value="false" />
</pane>
<pane id="Scope" />
<pane id="PackagesPane" />
<pane id="AndroidView" />
</panes>
</component>
<component name="PropertiesComponent">
<property name="dart.analysis.tool.window.force.activate" value="false" />
<property name="last_opened_file_path" value="$PROJECT_DIR$" />
<property name="show.migrate.to.gradle.popup" value="false" />
</component>
<component name="RunDashboard">
<option name="ruleStates">
<list>
<RuleState>
<option name="name" value="ConfigurationTypeDashboardGroupingRule" />
</RuleState>
<RuleState>
<option name="name" value="StatusDashboardGroupingRule" />
</RuleState>
</list>
</option>
</component>
<component name="SvnConfiguration">
<configuration />
</component>
<component name="TaskManager">
<task active="true" id="Default" summary="Default task">
<changelist id="ca160bec-0575-4943-95ce-117072a81cb2" name="Default Changelist" comment="" />
<created>1551211010640</created>
<option name="number" value="Default" />
<option name="presentableId" value="Default" />
<updated>1551211010640</updated>
</task>
<servers />
</component>
<component name="ToolWindowManager">
<frame x="683" y="343" width="2569" height="1529" extended-state="0" />
<layout>
<window_info id="Capture Tool" />
<window_info id="Structure" side_tool="true" />
<window_info id="Favorites" side_tool="true" />
<window_info id="Build Variants" side_tool="true" />
<window_info id="Image Layers" />
<window_info id="Designer" />
<window_info id="Captures" side_tool="true" />
<window_info active="true" content_ui="combo" id="Project" order="0" visible="true" weight="0.20617333" />
<window_info anchor="bottom" id="Run" />
<window_info anchor="bottom" id="Dart Analysis" visible="true" weight="0.24913013" />
<window_info anchor="bottom" id="Logcat" />
<window_info anchor="bottom" id="TODO" />
<window_info anchor="bottom" id="Debug" />
<window_info anchor="bottom" id="Terminal" />
<window_info anchor="bottom" id="Event Log" side_tool="true" />
<window_info anchor="bottom" id="Flutter Performance" side_tool="true" />
<window_info anchor="bottom" id="Version Control" show_stripe_button="false" />
<window_info anchor="bottom" id="Android Profiler" show_stripe_button="false" />
<window_info anchor="right" id="Device File Explorer" side_tool="true" />
<window_info anchor="right" id="Capture Analysis" />
<window_info anchor="right" id="Theme Preview" />
<window_info anchor="right" id="Flutter Inspector" />
<window_info anchor="right" id="Flutter Outline" />
<window_info anchor="right" id="Palette	" />
</layout>
</component>
<component name="VcsContentAnnotationSettings">
<option name="myLimit" value="2678400000" />
</component>
<component name="editorHistoryManager">
<entry file="file://$PROJECT_DIR$/lib/data_tables.dart">
<provider selected="true" editor-type-id="text-editor" />
</entry>
<entry file="file://$PROJECT_DIR$/example/lib/main.dart">
<provider selected="true" editor-type-id="text-editor" />
</entry>
</component>
</project>
================================================
FILE: .metadata
================================================
# This file tracks properties of this Flutter project.
# Used by Flutter tool to assess capabilities and perform upgrades etc.
#
# This file should be version controlled and should not be manually edited.
version:
revision: 746d5f7676e116041dd125d98ffbeeaf9251b90d
channel: master
project_type: plugin
================================================
FILE: .vscode/launch.json
================================================
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "Flutter",
"request": "launch",
"type": "dart",
"program": "example/lib/main.dart"
}
]
}
================================================
FILE: .vscode/settings.json
================================================
{
"cSpell.words": [
"datatable",
"listview"
]
}
================================================
FILE: CHANGELOG.md
================================================
## 1.4.0
* fixed deprecated theme properties
## 1.3.2
* fixing hide select box
* recreating example target folders
## 1.3.1
* support for no items
* adding totalItems
## 1.3.0
* adding `showSelect'
* adding `showSort'
## 1.2.0
* Stable Version
* Added '.fromJson'
* Updated Examples
## 1.1.1-nullsafety
* Updating to null safety
## 1.1.0-nullsafety
* Updating to null safety
## 1.0.1 - 04.06.2019
* Fixing Bugs on Mobile
* Added `alwaysShowDataTable`
## 1.0.0 - 04.26.2019
* Adding Desktop to Example
* Requiring `Dart 2.2.2`
* Fixing Sort Fields
* Fixing Bottom Bar
* Fixed Mobile Item Builder
## 0.3.0 - 04.06.2019
* Making Example Desktop Aware
## 0.2.4
* Fixed Padding on Refresh
* Added CupertinoRefreshController
## 0.2.3
* Removing SafeArea
## 0.2.2
* Adding Mobile Slivers
* Updated Example
## 0.2.1
* Updating Toolbar on Mobile
## 0.2.0
* Updating Size Attribute to Detect if Tablet
## 0.1.3
* Adding Size Attribute to Detect if Tablet
## 0.1.2
* Fixing Mobile onSort Behavior
* Fixing Bottom Bar Sizing
## 0.1.1
* Adding Support for Widgets when No Items Loded and Empty Items
## 0.1.0
* Updated Example
* Made Tableview Stateless
* Removed Need for Data Source
## 0.0.2
* Updated Example
* Made Tableview Stateless
* Removed Need for Data Source
## 0.0.1
* Created Data Table
* Created Mobile ListView
================================================
FILE: LICENSE
================================================
MIT License
Copyright (c) 2020 Rody Davis
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
================================================
FILE: README.md
================================================
[](https://www.buymeacoffee.com/rodydavis)
[](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=WSH3GVC49GNNJ)

[](https://github.com/rodydavis/data_tables)
[](https://pub.dev/packages/data_tables)
# data_tables
- Full Screen Paginated Data Tables for Tablets/Desktops
- Mobile ListView with Action Buttons for Sorting and Selecting All
- Supports Dark Mode
- From Json
Online Demo: https://rodydavis.github.io/data_tables/
## Getting Started
- You can optionally build the listview for mobile with a builder, by default it creates a ExpansionTile with the remaining columns as children
- The tablet breakpoint can also be set.
`bool showMobileListView;` - When set to false it will always show a data table
`int sortColumnIndex;` - Current Sorted Column
`bool sortAscending;` - Sort Order
`ValueChanged<bool> onSelectAll;` - Called for Selecting and Deselecting All
`ValueChanged<int> onRowsPerPageChanged;` - Called when rows change on data table or last row reached on mobile.
`int rowsPerPage;` - Default Rows per page
`Widget header;` - Widget header for Desktop and Tablet Data Table
`List<DataColumn> columns;` - List of Columns (Must match length of DataCells in DataSource)
`IndexedWidgetBuilder mobileItemBuilder;` - Optional Item builder for the list view for Mobile
`Size tabletBreakpoint;` - Tablet breakpoint for the screen width and height
`List<Widget> actions, selectedActions;` - Actions that show when items are selected or not
`RefreshCallback onRefresh;` - If not null the list view will be wrapped in a RefreshIndicator
## Screenshots





================================================
FILE: analysis_options.yaml
================================================
include: package:pedantic/analysis_options.yaml
analyzer:
exclude:
- lib/**
- pubspec.lock
================================================
FILE: data_tables.iml
================================================
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/lib" isTestSource="false" />
<excludeFolder url="file://$MODULE_DIR$/.dart_tool" />
<excludeFolder url="file://$MODULE_DIR$/.idea" />
<excludeFolder url="file://$MODULE_DIR$/.pub" />
<excludeFolder url="file://$MODULE_DIR$/build" />
<excludeFolder url="file://$MODULE_DIR$/example/.dart_tool" />
<excludeFolder url="file://$MODULE_DIR$/example/.pub" />
<excludeFolder url="file://$MODULE_DIR$/example/build" />
</content>
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" name="Dart SDK" level="project" />
<orderEntry type="library" name="Flutter Plugins" level="project" />
</component>
</module>
================================================
FILE: example/ios/Flutter/flutter_export_environment.sh
================================================
#!/bin/sh
# This is a generated file; do not edit or check into version control.
export "FLUTTER_ROOT=/usr/local/Caskroom/flutter/1.2.1/flutter"
export "FLUTTER_APPLICATION_PATH=/Users/rodydavis/Developer/GitHub/plugins/packages/data_tables/example"
export "COCOAPODS_PARALLEL_CODE_SIGN=true"
export "FLUTTER_TARGET=lib/main.dart"
export "FLUTTER_BUILD_DIR=build"
export "FLUTTER_BUILD_NAME=1.0.0"
export "FLUTTER_BUILD_NUMBER=1"
export "DART_OBFUSCATION=false"
export "TRACK_WIDGET_CREATION=false"
export "TREE_SHAKE_ICONS=false"
export "PACKAGE_CONFIG=.packages"
================================================
FILE: example/linux/flutter/generated_plugin_registrant.cc
================================================
//
// Generated file. Do not edit.
//
// clang-format off
#include "generated_plugin_registrant.h"
void fl_register_plugins(FlPluginRegistry* registry) {
}
================================================
FILE: example/linux/flutter/generated_plugin_registrant.h
================================================
//
// Generated file. Do not edit.
//
// clang-format off
#ifndef GENERATED_PLUGIN_REGISTRANT_
#define GENERATED_PLUGIN_REGISTRANT_
#include <flutter_linux/flutter_linux.h>
// Registers Flutter plugins.
void fl_register_plugins(FlPluginRegistry* registry);
#endif // GENERATED_PLUGIN_REGISTRANT_
================================================
FILE: example/macos/Flutter/ephemeral/Flutter-Generated.xcconfig
================================================
// This is a generated file; do not edit or check into version control.
FLUTTER_ROOT=/usr/local/Caskroom/flutter/1.2.1/flutter
FLUTTER_APPLICATION_PATH=/Users/rodydavis/Developer/GitHub/plugins/packages/data_tables/example
COCOAPODS_PARALLEL_CODE_SIGN=true
FLUTTER_BUILD_DIR=build
FLUTTER_BUILD_NAME=1.0.0
FLUTTER_BUILD_NUMBER=1
EXCLUDED_ARCHS=arm64
DART_OBFUSCATION=false
TRACK_WIDGET_CREATION=false
TREE_SHAKE_ICONS=false
PACKAGE_CONFIG=.packages
================================================
FILE: example/macos/Flutter/ephemeral/flutter_export_environment.sh
================================================
#!/bin/sh
# This is a generated file; do not edit or check into version control.
export "FLUTTER_ROOT=/usr/local/Caskroom/flutter/1.2.1/flutter"
export "FLUTTER_APPLICATION_PATH=/Users/rodydavis/Developer/GitHub/plugins/packages/data_tables/example"
export "COCOAPODS_PARALLEL_CODE_SIGN=true"
export "FLUTTER_BUILD_DIR=build"
export "FLUTTER_BUILD_NAME=1.0.0"
export "FLUTTER_BUILD_NUMBER=1"
export "EXCLUDED_ARCHS=arm64"
export "DART_OBFUSCATION=false"
export "TRACK_WIDGET_CREATION=false"
export "TREE_SHAKE_ICONS=false"
export "PACKAGE_CONFIG=.packages"
================================================
FILE: example/windows/flutter/generated_plugin_registrant.cc
================================================
//
// Generated file. Do not edit.
//
// clang-format off
#include "generated_plugin_registrant.h"
void RegisterPlugins(flutter::PluginRegistry* registry) {
}
================================================
FILE: example/windows/flutter/generated_plugin_registrant.h
================================================
//
// Generated file. Do not edit.
//
// clang-format off
#ifndef GENERATED_PLUGIN_REGISTRANT_
#define GENERATED_PLUGIN_REGISTRANT_
#include <flutter/plugin_registry.h>
// Registers Flutter plugins.
void RegisterPlugins(flutter::PluginRegistry* registry);
#endif // GENERATED_PLUGIN_REGISTRANT_
================================================
FILE: lib/data_tables.dart
================================================
import 'package:flutter/material.dart';
import 'ui/mobile_paged_listview.dart';
import 'ui/stateless_datatable.dart';
const _kTabletBreakpoint = Size(480, 480);
class NativeDataTable extends StatelessWidget {
const NativeDataTable({
required this.columns,
required this.rows,
this.rowsPerPage = PaginatedDataTable.defaultRowsPerPage,
this.header,
this.showSelect = true,
this.showSort = true,
this.onRowsPerPageChanged,
this.totalItems,
this.onSelectAll,
this.sortAscending,
this.sortColumnIndex,
this.mobileItemBuilder,
this.tabletBreakpoint = _kTabletBreakpoint,
this.actions,
this.firstRowIndex = 0,
this.selectedActions,
this.onRefresh,
this.mobileFetchNextRows = 100,
this.handlePrevious,
this.handleNext,
this.rowCountApproximate = false,
this.noItems,
this.mobileIsLoading,
this.mobileSlivers,
this.alwaysShowDataTable = false,
});
NativeDataTable.fromJson({
required List<Map<String, dynamic>> items,
List<String>? columnKeys,
DataColumn Function(String key)? columnBuilder,
DataRow Function(Map<String, dynamic> item)? rowBuilder,
DataCell Function(String key, dynamic value)? cellBuilder,
this.rowsPerPage = PaginatedDataTable.defaultRowsPerPage,
this.header,
this.showSelect = true,
this.showSort = true,
this.onRowsPerPageChanged,
this.onSelectAll,
this.sortAscending,
this.sortColumnIndex,
this.mobileItemBuilder,
this.totalItems,
this.tabletBreakpoint = _kTabletBreakpoint,
this.actions,
this.firstRowIndex = 0,
this.selectedActions,
this.onRefresh,
this.mobileFetchNextRows = 100,
this.handlePrevious,
this.handleNext,
this.rowCountApproximate = false,
this.noItems,
this.mobileIsLoading,
this.mobileSlivers,
this.alwaysShowDataTable = false,
}) : assert(items.isNotEmpty || columnKeys != null),
columns = (columnKeys ?? items[0].keys.toList()).map((e) {
if (columnBuilder != null) return columnBuilder(e);
return DataColumn(label: Text(e));
}).toList(),
rows = items.isEmpty
? []
: items.map((e) {
if (rowBuilder != null) return rowBuilder(e);
return DataRow(
cells: e.entries.map((e) {
if (cellBuilder != null) return cellBuilder(e.key, e.value);
return DataCell(Text(e.value.toString()));
}).toList());
}).toList();
NativeDataTable.builder({
required this.columns,
this.rowsPerPage = PaginatedDataTable.defaultRowsPerPage,
required int itemCount,
required DataRowBuilder itemBuilder,
this.totalItems,
this.header,
this.onRowsPerPageChanged,
this.onSelectAll,
this.sortAscending,
this.showSelect = true,
this.showSort = true,
this.sortColumnIndex,
this.mobileItemBuilder,
this.tabletBreakpoint = _kTabletBreakpoint,
this.actions,
this.selectedActions,
this.firstRowIndex = 0,
this.onRefresh,
this.mobileFetchNextRows = 100,
this.handlePrevious,
this.handleNext,
this.rowCountApproximate = false,
this.noItems,
this.mobileIsLoading,
this.mobileSlivers,
this.alwaysShowDataTable = false,
}) : rows = _buildRows(itemCount, itemBuilder);
final int? sortColumnIndex;
final bool? sortAscending;
final ValueChanged<bool?>? onSelectAll;
final ValueChanged<int?>? onRowsPerPageChanged;
final int? totalItems;
final int rowsPerPage;
final int firstRowIndex;
/// Visible on Tablet/Desktop
final Widget? header;
final List<DataColumn> columns;
final List<DataRow> rows;
final IndexedWidgetBuilder? mobileItemBuilder;
final Size tabletBreakpoint;
final List<Widget>? actions, selectedActions;
final int mobileFetchNextRows;
final RefreshCallback? onRefresh;
final VoidCallback? handlePrevious, handleNext;
/// Set this to [true] for using this with a api
final bool rowCountApproximate;
final bool showSelect, showSort;
final Widget? noItems;
final Widget? mobileIsLoading;
final List<Widget>? mobileSlivers;
final bool alwaysShowDataTable;
@override
Widget build(BuildContext context) {
final size = MediaQuery.of(context).size;
final isTablet = size.width >= tabletBreakpoint.width &&
size.height >= tabletBreakpoint.height;
if (alwaysShowDataTable || isTablet) {
return StatelessDataTable(
rows: rows,
firstRowIndex: firstRowIndex,
totalItems: totalItems,
header: header,
showCheckboxColumn: showSelect,
handleNext: handleNext,
handlePrevious: handlePrevious,
rowsPerPage: rowsPerPage,
onRowsPerPageChanged: onRowsPerPageChanged,
sortColumnIndex: sortColumnIndex,
sortAscending: sortAscending ?? false,
onSelectAll: showSelect ? onSelectAll : null,
columns: columns,
// ignore: avoid_redundant_argument_values
shrinkWrap: false,
rowCountApproximate: rowCountApproximate,
actions: [
...actions ?? [],
Container(
child: onRefresh == null
? null
: IconButton(
icon: const Icon(Icons.refresh),
onPressed: onRefresh,
),
),
],
selectedActions: selectedActions,
);
}
return PagedListView(
rows: rows,
slivers: mobileSlivers,
columns: columns,
showSelect: showSelect,
showSort: showSort,
loadNext: handleNext,
mobileItemBuilder: mobileItemBuilder,
actions: actions,
selectedActions: selectedActions,
onSelectAll: onSelectAll,
rowsPerPage: rowsPerPage,
sortAscending: sortAscending,
sortColumnIndex: sortColumnIndex,
onRefresh: onRefresh,
isRowCountApproximate: rowCountApproximate,
isLoading: mobileIsLoading,
noItems: noItems,
);
}
static List<DataRow> _buildRows(int count, DataRowBuilder builder) {
List<DataRow> _rows = [];
for (int i = 0; i < count; i++) {
_rows.add(builder(i));
}
return _rows;
}
}
typedef DataRowBuilder = DataRow Function(int index);
================================================
FILE: lib/ui/mobile_paged_listview.dart
================================================
import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart' as cupertino;
class PagedListView extends StatefulWidget {
const PagedListView({
required this.rows,
required this.columns,
this.showSelect = true,
this.showSort = true,
this.mobileItemBuilder,
this.selectedActions,
this.actions,
this.onSelectAll,
this.rowsPerPage,
this.loadNext,
this.sortColumnIndex,
this.sortAscending,
this.onRefresh,
this.isRowCountApproximate = false,
this.initialScrollOffset = 0,
this.noItems,
this.isLoading,
this.slivers,
});
final double initialScrollOffset;
final List<DataColumn> columns;
final List<DataRow> rows;
final IndexedWidgetBuilder? mobileItemBuilder;
final bool showSelect, showSort;
final List<Widget>? actions;
final List<Widget>? selectedActions;
final ValueChanged<bool?>? onSelectAll;
final int? rowsPerPage;
final VoidCallback? loadNext;
final int? sortColumnIndex;
final bool? sortAscending;
final Widget? noItems, isLoading;
final RefreshCallback? onRefresh;
final bool isRowCountApproximate;
final List<Widget>? slivers;
@override
_NativePagedListViewState createState() => _NativePagedListViewState();
}
class _NativePagedListViewState extends State<PagedListView> {
ScrollController? _controller;
PersistentBottomSheetController? _sortController;
@override
void initState() {
_controller = ScrollController(
initialScrollOffset: widget.initialScrollOffset * 40.0,
);
_controller!.addListener(_scrollListener);
super.initState();
}
@override
void didUpdateWidget(covariant PagedListView oldWidget) {
if (oldWidget.showSelect != widget.showSelect) if (mounted) setState(() {});
if (oldWidget.showSort != widget.showSort) if (mounted) setState(() {});
if (oldWidget.rows != widget.rows) if (mounted) setState(() {});
if (oldWidget.columns != widget.columns) if (mounted) setState(() {});
super.didUpdateWidget(oldWidget);
}
void _scrollListener() {
if (_controller!.offset >= _controller!.position.maxScrollExtent && !_controller!.position.outOfRange) {
// Bottom of List
widget.loadNext!();
}
if (_controller!.offset <= _controller!.position.minScrollExtent && !_controller!.position.outOfRange) {
// Top of List
}
}
@override
Widget build(BuildContext context) {
return Column(
children: <Widget>[
Expanded(
child: CustomScrollView(
controller: _controller,
slivers: <Widget>[
...?widget.slivers,
if (widget.onRefresh == null) SliverToBoxAdapter(child: Container()) else cupertino.CupertinoSliverRefreshControl(onRefresh: widget.onRefresh),
if (widget.isLoading != null && widget.rows.isEmpty)
Center(child: widget.isLoading)
else
widget.noItems != null && widget.rows.isEmpty
? Center(child: widget.noItems)
: SliverList(
delegate: SliverChildBuilderDelegate(
widget.mobileItemBuilder ??
(context, index) {
return ExpansionTile(
leading: widget.showSelect
? Checkbox(
value: widget.rows[index].selected,
onChanged: (bool? value) {
setState(() {
widget.rows[index].onSelectChanged!(value);
});
},
)
: null,
title: widget.rows[index].cells.first.child,
children: _buildMobileChildren(index),
);
},
childCount: widget.rows.length,
),
)
],
),
),
if (widget.showSelect || widget.showSort)
SafeArea(
top: false,
child: Container(
decoration: BoxDecoration(
border: Border(
top: cupertino.BorderSide(color: Colors.grey[200]!),
)),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: rowsSelected ? selectedActions : actions,
),
),
),
],
);
}
List<Widget> get actions => [
if (widget.showSelect)
IconButton(
icon: const Icon(Icons.select_all),
onPressed: () {
setState(() {
widget.onSelectAll!(true);
});
},
),
if (widget.showSort)
IconButton(
tooltip: "Sort Items",
icon: const Icon(Icons.sort_by_alpha),
onPressed: () {
if (_sortController != null) {
_sortController!.close();
debugPrint("Close...");
return;
}
_sortController = Scaffold.of(context).showBottomSheet((context) {
final List<DataColumn> _cols = widget.columns.where((c) => c.onSort != null).toList();
final bool? _sortAsc = widget.sortAscending;
final int? selectedIndex = widget.sortColumnIndex;
return Container(
decoration: BoxDecoration(
color: Theme.of(context).brightness == Brightness.dark ? Colors.black38 : Colors.grey[200],
borderRadius: const BorderRadius.only(topLeft: Radius.circular(20), topRight: Radius.circular(20))),
child: SingleChildScrollView(
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
for (var i = 0; i < _cols.length; i++) ...[
ListTile(
dense: true,
selected: selectedIndex == i,
title: _cols[i].label,
subtitle: Text(widget.sortAscending! ? 'Ascending' : 'Descending'),
leading: Radio<int>(
groupValue: selectedIndex,
onChanged: (value) {
_sortController!.setState!(() {
_cols[i].onSort!(i, _sortAsc!);
});
},
value: i,
),
trailing: IconButton(
icon: Icon(_sortAsc! ? Icons.arrow_upward : Icons.arrow_downward),
onPressed: () {
_sortController!.setState!(() {
_cols[i].onSort!(i, !_sortAsc);
});
},
),
onTap: () {
if (selectedIndex == i) {
_sortController!.setState!(() {
_cols[i].onSort!(i, !_sortAsc);
});
} else {
_sortController!.setState!(() {
_cols[i].onSort!(i, _sortAsc);
});
}
},
),
],
Container(
padding: EdgeInsets.only(top: 10.0, bottom: 10.0),
child: Container(
child: TextButton(
child: Text(
"Close",
style: Theme.of(context).textTheme.headline5,
),
onPressed: () {
_sortController!.close();
},
),
),
),
],
),
),
);
});
_sortController!.closed.whenComplete(() {
debugPrint("Done");
_sortController = null;
});
},
),
Container(
child: widget.onRefresh == null
? null
: IconButton(
icon: Icon(Icons.refresh),
onPressed: widget.onRefresh,
),
),
...widget.actions ?? [],
];
List<Widget> get selectedActions => [
IconButton(
icon: Icon(Icons.clear_all),
onPressed: () {
setState(() {
widget.onSelectAll!(false);
});
},
),
...widget.selectedActions ?? []
];
bool get rowsSelected => _selectedRowCount != 0;
int get _selectedRowCount => widget.rows.where((d) => d.selected).toSet().toList().length;
List<Widget> _buildMobileChildren(int index) {
List<Widget> _children = [];
int i = 0;
for (var _cell in widget.rows[index].cells) {
_children.add(ListTile(
title: widget.columns[i].label,
subtitle: _cell.child,
));
i++;
}
return _children;
}
}
================================================
FILE: lib/ui/stateless_datatable.dart
================================================
import 'dart:ui';
import 'package:flutter/gestures.dart' show DragStartBehavior;
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter/widgets.dart';
class StatelessDataTable extends StatelessWidget {
StatelessDataTable({
Key? key,
this.header,
this.actions,
required this.columns,
required this.rows,
this.sortColumnIndex,
this.showCheckboxColumn = true,
this.sortAscending = true,
this.totalItems,
this.onSelectAll,
this.firstRowIndex = 0,
this.onPageChanged,
this.shrinkWrap = false,
this.selectedActions,
this.rowCountApproximate = false,
this.rowsPerPage = defaultRowsPerPage,
this.handlePrevious,
this.handleNext,
this.availableRowsPerPage = const <int>[defaultRowsPerPage, defaultRowsPerPage * 2, defaultRowsPerPage * 5, defaultRowsPerPage * 10],
this.onRowsPerPageChanged,
this.dragStartBehavior = DragStartBehavior.down,
}) : assert(columns.isNotEmpty),
assert(sortColumnIndex == null || (sortColumnIndex >= 0 && sortColumnIndex < columns.length)),
assert(rowsPerPage > 0),
assert(() {
if (onRowsPerPageChanged != null) {
assert(availableRowsPerPage.contains(rowsPerPage));
}
return true;
}()),
super(key: key);
final VoidCallback? handleNext, handlePrevious;
final Widget? header;
final bool showCheckboxColumn;
final List<Widget>? actions, selectedActions;
final List<DataColumn> columns;
final List<DataRow> rows;
final bool shrinkWrap;
final int? sortColumnIndex;
final int? totalItems;
final bool sortAscending;
final ValueSetter<bool?>? onSelectAll;
final ValueChanged<int?>? onPageChanged;
final int rowsPerPage;
static const int defaultRowsPerPage = 10;
final List<int> availableRowsPerPage;
final ValueChanged<int?>? onRowsPerPageChanged;
final DragStartBehavior dragStartBehavior;
final int firstRowIndex;
final bool rowCountApproximate;
final Map<int, DataRow> _rows = <int, DataRow>{};
DataRow _getBlankRowFor(int index) => DataRow.byIndex(index: index, cells: columns.map<DataCell>((DataColumn column) => DataCell.empty).toList());
DataRow _getProgressIndicatorRowFor(int index) {
bool haveProgressIndicator = false;
final List<DataCell> cells = columns.map<DataCell>((DataColumn column) {
if (!column.numeric) {
haveProgressIndicator = true;
return const DataCell(CircularProgressIndicator());
}
return DataCell.empty;
}).toList();
if (!haveProgressIndicator) {
haveProgressIndicator = true;
cells[0] = const DataCell(CircularProgressIndicator());
}
return DataRow.byIndex(index: index, cells: cells);
}
List<DataRow> _getRows(int firstRowIndex, int rowsPerPage) {
final List<DataRow> result = <DataRow>[];
final int nextPageFirstRowIndex = firstRowIndex + rowsPerPage;
bool haveProgressIndicator = false;
for (int index = firstRowIndex; index < nextPageFirstRowIndex; index += 1) {
DataRow? row;
if (index < rows.length || rowCountApproximate) {
try {
row = _rows.putIfAbsent(index, () => rows[index]);
} catch (e) {
print("Row not found => $e");
}
if (row == null && !haveProgressIndicator) {
row ??= _getProgressIndicatorRowFor(index);
haveProgressIndicator = true;
}
row ??= _getBlankRowFor(index);
result.add(row);
}
}
//show no data
if (result.isEmpty) {
var cells = columns.map<DataCell>((DataColumn column) => DataCell.empty).toList();
cells[cells.length ~/ 2] = const DataCell(Text('no data'));
result.add(DataRow.byIndex(index: 0, cells: cells));
}
return result;
}
final GlobalKey _tableKey = GlobalKey();
int get _selectedRowCount => rows.where((d) => d.selected).toSet().toList().length;
@override
Widget build(BuildContext context) {
assert(debugCheckHasMaterialLocalizations(context));
final ThemeData themeData = Theme.of(context);
final MaterialLocalizations localizations = MaterialLocalizations.of(context);
final List<Widget> headerWidgets = <Widget>[];
double startPadding = 24;
if (_selectedRowCount == 0) {
if (header != null) {
headerWidgets.add(Expanded(child: header!));
if (header is ButtonBar) {
startPadding = 12.0;
}
}
} else {
headerWidgets.add(Expanded(
child: Text(localizations.selectedRowCountTitle(_selectedRowCount)),
));
}
if (selectedActions != null && _selectedRowCount != 0) {
headerWidgets.addAll(selectedActions!.map<Widget>((Widget action) {
return Padding(
padding: const EdgeInsetsDirectional.only(start: 24.0 - 8.0 * 2.0),
child: action,
);
}).toList());
} else if (actions != null) {
headerWidgets.addAll(actions!.map<Widget>((Widget action) {
return Padding(
padding: const EdgeInsetsDirectional.only(start: 24.0 - 8.0 * 2.0),
child: action,
);
}).toList());
}
final TextStyle? footerTextStyle = themeData.textTheme.caption;
final List<Widget> footerWidgets = <Widget>[];
if (onRowsPerPageChanged != null) {
final List<Widget> _footerChildren =
availableRowsPerPage.where((int value) => value <= rows.length || value == rowsPerPage).map<DropdownMenuItem<int>>((int value) {
return DropdownMenuItem<int>(value: value, child: Text('$value'));
}).toList();
footerWidgets.addAll(<Widget>[
Container(width: 14),
Text(localizations.rowsPerPageTitle),
ConstrainedBox(
constraints: const BoxConstraints(minWidth: 64),
child: Align(
alignment: AlignmentDirectional.centerEnd,
child: DropdownButtonHideUnderline(
child: DropdownButton<int>(
items: _footerChildren as List<DropdownMenuItem<int>>?,
value: rowsPerPage,
onChanged: onRowsPerPageChanged,
style: footerTextStyle,
),
),
),
),
]);
}
footerWidgets.addAll(<Widget>[
Container(width: 32),
Text(localizations.pageRowsInfoTitle(firstRowIndex + 1, firstRowIndex + rowsPerPage, totalItems ?? rows.length, rowCountApproximate)),
Container(width: 32),
IconButton(
icon: const Icon(Icons.chevron_left),
padding: EdgeInsets.zero,
tooltip: localizations.previousPageTooltip,
onPressed: firstRowIndex <= 0 ? null : handlePrevious),
Container(width: 24),
IconButton(
icon: const Icon(Icons.chevron_right),
padding: EdgeInsets.zero,
tooltip: localizations.nextPageTooltip,
onPressed: (!rowCountApproximate && (firstRowIndex + rowsPerPage >= (totalItems ?? rows.length))) ? null : handleNext),
Container(width: 14),
]);
if (shrinkWrap) {
return SafeArea(
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
if (showCheckboxColumn)
Semantics(
container: true,
child: DefaultTextStyle(
style: _selectedRowCount > 0
? themeData.textTheme.subtitle1!.copyWith(color: themeData.colorScheme.secondary)
: themeData.textTheme.headline6!.copyWith(fontWeight: FontWeight.w400),
child: IconTheme.merge(
data: const IconThemeData(opacity: 0.54),
child: ButtonTheme(
child: Ink(
height: 64,
color: _selectedRowCount > 0 ? themeData.secondaryHeaderColor : null,
child: Padding(
padding: EdgeInsetsDirectional.only(start: startPadding, end: 14),
child: Row(mainAxisAlignment: MainAxisAlignment.end, children: headerWidgets),
),
),
),
),
),
),
SingleChildScrollView(
scrollDirection: Axis.horizontal,
dragStartBehavior: dragStartBehavior,
child: Builder(
builder: (BuildContext context) {
final rows = _getRows(firstRowIndex, rowsPerPage);
return DataTable(
showCheckboxColumn: showCheckboxColumn,
key: _tableKey,
columns: columns,
sortColumnIndex: sortColumnIndex,
sortAscending: sortAscending,
onSelectAll: onSelectAll,
rows: rows,
);
},
),
),
DefaultTextStyle(
style: footerTextStyle!,
child: IconTheme.merge(
data: const IconThemeData(opacity: 0.54),
child: Container(
height: 56,
child: SingleChildScrollView(
dragStartBehavior: dragStartBehavior,
scrollDirection: Axis.horizontal,
reverse: true,
child: Row(
children: footerWidgets,
),
),
),
),
),
],
),
);
}
return SafeArea(
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
if (showCheckboxColumn)
Semantics(
container: true,
child: DefaultTextStyle(
style: _selectedRowCount > 0
? themeData.textTheme.subtitle1!.copyWith(color: themeData.colorScheme.secondary)
: themeData.textTheme.headline6!.copyWith(fontWeight: FontWeight.w400),
child: IconTheme.merge(
data: const IconThemeData(opacity: 0.54),
child: ButtonTheme(
child: Ink(
height: 64,
color: _selectedRowCount > 0 ? themeData.secondaryHeaderColor : null,
child: Padding(
padding: EdgeInsetsDirectional.only(start: startPadding, end: 14),
child: Row(mainAxisAlignment: MainAxisAlignment.end, children: headerWidgets),
),
),
),
),
),
),
Expanded(
flex: 8,
child: ScrollConfiguration(
behavior: CustomScrollBehavior(),
child: SingleChildScrollView(
scrollDirection: Axis.vertical,
child: SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: DataTable(
key: _tableKey,
columns: columns,
sortColumnIndex: sortColumnIndex,
sortAscending: sortAscending,
onSelectAll: onSelectAll,
rows: _getRows(firstRowIndex, rowsPerPage)),
),
),
),
),
DefaultTextStyle(
style: footerTextStyle!,
child: IconTheme.merge(
data: const IconThemeData(opacity: 0.54),
child: SizedBox(
height: 56,
child: SingleChildScrollView(
dragStartBehavior: dragStartBehavior,
scrollDirection: Axis.horizontal,
reverse: true,
child: Row(
children: footerWidgets,
),
),
),
),
),
],
),
);
}
}
class CustomScrollBehavior extends MaterialScrollBehavior {
@override
Set<PointerDeviceKind> get dragDevices => {
PointerDeviceKind.touch,
PointerDeviceKind.mouse,
};
}
================================================
FILE: pubspec.yaml
================================================
name: data_tables
description: ListView on Mobile and Stateless Data Tables on Tablets and Desktops.
version: 1.4.0
homepage: https://github.com/rodydavis/plugins
repository: https://github.com/rodydavis/data_tables
environment:
sdk: '>=2.12.0-259.8.beta <3.0.0'
dependencies:
flutter:
sdk: flutter
dev_dependencies:
flutter_test:
sdk: flutter
pedantic: 1.11.1
flutter:
gitextract_scyshgbk/ ├── .gitattributes ├── .github/ │ └── workflows/ │ └── main.yml ├── .gitignore ├── .idea/ │ ├── codeStyles/ │ │ └── Project.xml │ ├── libraries/ │ │ ├── Dart_SDK.xml │ │ ├── Flutter_Plugins.xml │ │ └── Flutter_for_Android.xml │ ├── modules.xml │ ├── runConfigurations/ │ │ └── example_lib_main_dart.xml │ ├── vcs.xml │ └── workspace.xml ├── .metadata ├── .vscode/ │ ├── launch.json │ └── settings.json ├── CHANGELOG.md ├── LICENSE ├── README.md ├── analysis_options.yaml ├── data_tables.iml ├── example/ │ ├── ios/ │ │ └── Flutter/ │ │ └── flutter_export_environment.sh │ ├── linux/ │ │ └── flutter/ │ │ ├── generated_plugin_registrant.cc │ │ └── generated_plugin_registrant.h │ ├── macos/ │ │ └── Flutter/ │ │ └── ephemeral/ │ │ ├── Flutter-Generated.xcconfig │ │ └── flutter_export_environment.sh │ └── windows/ │ └── flutter/ │ ├── generated_plugin_registrant.cc │ └── generated_plugin_registrant.h ├── lib/ │ ├── data_tables.dart │ └── ui/ │ ├── mobile_paged_listview.dart │ └── stateless_datatable.dart └── pubspec.yaml
SYMBOL INDEX (20 symbols across 5 files)
FILE: example/linux/flutter/generated_plugin_registrant.cc
function fl_register_plugins (line 10) | void fl_register_plugins(FlPluginRegistry* registry) {
FILE: example/windows/flutter/generated_plugin_registrant.cc
function RegisterPlugins (line 10) | void RegisterPlugins(flutter::PluginRegistry* registry) {
FILE: lib/data_tables.dart
class NativeDataTable (line 8) | class NativeDataTable extends StatelessWidget {
method build (line 139) | Widget build(BuildContext context)
method _buildRows (line 197) | List<DataRow> _buildRows(int count, DataRowBuilder builder)
type DataRowBuilder (line 208) | typedef DataRowBuilder = DataRow Function(int index);
FILE: lib/ui/mobile_paged_listview.dart
class PagedListView (line 4) | class PagedListView extends StatefulWidget {
method createState (line 44) | _NativePagedListViewState createState()
class _NativePagedListViewState (line 47) | class _NativePagedListViewState extends State<PagedListView> {
method initState (line 52) | void initState()
method didUpdateWidget (line 62) | void didUpdateWidget(covariant PagedListView oldWidget)
method _scrollListener (line 70) | void _scrollListener()
method build (line 81) | Widget build(BuildContext context)
method _buildMobileChildren (line 259) | List<Widget> _buildMobileChildren(int index)
FILE: lib/ui/stateless_datatable.dart
class StatelessDataTable (line 8) | class StatelessDataTable extends StatelessWidget {
method _getBlankRowFor (line 63) | DataRow _getBlankRowFor(int index)
method _getProgressIndicatorRowFor (line 65) | DataRow _getProgressIndicatorRowFor(int index)
method _getRows (line 81) | List<DataRow> _getRows(int firstRowIndex, int rowsPerPage)
method build (line 116) | Widget build(BuildContext context)
class CustomScrollBehavior (line 331) | class CustomScrollBehavior extends MaterialScrollBehavior {
Condensed preview — 30 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (54K chars).
[
{
"path": ".gitattributes",
"chars": 66,
"preview": "# Auto detect text files and perform LF normalization\n* text=auto\n"
},
{
"path": ".github/workflows/main.yml",
"chars": 553,
"preview": "name: github pages\n\non:\n push:\n branches:\n - master\n\njobs:\n deploy:\n runs-on: ubuntu-18.04\n steps:\n "
},
{
"path": ".gitignore",
"chars": 47,
"preview": ".DS_Store\n.dart_tool/\n\n.packages\n.pub/\n\nbuild/\n"
},
{
"path": ".idea/codeStyles/Project.xml",
"chars": 1775,
"preview": "<component name=\"ProjectCodeStyleConfiguration\">\n <code_scheme name=\"Project\" version=\"173\">\n <Objective-C-extension"
},
{
"path": ".idea/libraries/Dart_SDK.xml",
"chars": 1062,
"preview": "<component name=\"libraryTable\">\n <library name=\"Dart SDK\">\n <CLASSES>\n <root url=\"file:///Users/developer/flutt"
},
{
"path": ".idea/libraries/Flutter_Plugins.xml",
"chars": 228,
"preview": "<component name=\"libraryTable\">\n <library name=\"Flutter Plugins\" type=\"FlutterPluginsLibraryType\">\n <CLASSES>\n "
},
{
"path": ".idea/libraries/Flutter_for_Android.xml",
"chars": 263,
"preview": "<component name=\"libraryTable\">\n <library name=\"Flutter for Android\">\n <CLASSES>\n <root url=\"jar:///Users/devel"
},
{
"path": ".idea/modules.xml",
"chars": 569,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n <component name=\"ProjectModuleManager\">\n <modules>\n "
},
{
"path": ".idea/runConfigurations/example_lib_main_dart.xml",
"chars": 291,
"preview": "<component name=\"ProjectRunConfigurationManager\">\n <configuration default=\"false\" name=\"example/lib/main.dart\" type=\"Fl"
},
{
"path": ".idea/vcs.xml",
"chars": 186,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n <component name=\"VcsDirectoryMappings\">\n <mapping dire"
},
{
"path": ".idea/workspace.xml",
"chars": 7545,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n <component name=\"ChangeListManager\">\n <list default=\"t"
},
{
"path": ".metadata",
"chars": 308,
"preview": "# This file tracks properties of this Flutter project.\n# Used by Flutter tool to assess capabilities and perform upgrade"
},
{
"path": ".vscode/launch.json",
"chars": 417,
"preview": "{\n // Use IntelliSense to learn about possible attributes.\n // Hover to view descriptions of existing attributes.\n"
},
{
"path": ".vscode/settings.json",
"chars": 71,
"preview": "{\n \"cSpell.words\": [\n \"datatable\",\n \"listview\"\n ]\n}"
},
{
"path": "CHANGELOG.md",
"chars": 1355,
"preview": "## 1.4.0\n\n* fixed deprecated theme properties\n\n## 1.3.2\n\n* fixing hide select box\n* recreating example target folders\n\n#"
},
{
"path": "LICENSE",
"chars": 1067,
"preview": "MIT License\n\nCopyright (c) 2020 Rody Davis\n\nPermission is hereby granted, free of charge, to any person obtaining a copy"
},
{
"path": "README.md",
"chars": 2391,
"preview": "[](https://www.buymeacoffee.com/"
},
{
"path": "analysis_options.yaml",
"chars": 101,
"preview": "include: package:pedantic/analysis_options.yaml\n\nanalyzer:\n exclude:\n - lib/**\n - pubspec.lock"
},
{
"path": "data_tables.iml",
"chars": 947,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<module type=\"JAVA_MODULE\" version=\"4\">\n <component name=\"NewModuleRootManager\" "
},
{
"path": "example/ios/Flutter/flutter_export_environment.sh",
"chars": 565,
"preview": "#!/bin/sh\n# This is a generated file; do not edit or check into version control.\nexport \"FLUTTER_ROOT=/usr/local/Caskroo"
},
{
"path": "example/linux/flutter/generated_plugin_registrant.cc",
"chars": 161,
"preview": "//\n// Generated file. Do not edit.\n//\n\n// clang-format off\n\n#include \"generated_plugin_registrant.h\"\n\n\nvoid fl_register"
},
{
"path": "example/linux/flutter/generated_plugin_registrant.h",
"chars": 303,
"preview": "//\n// Generated file. Do not edit.\n//\n\n// clang-format off\n\n#ifndef GENERATED_PLUGIN_REGISTRANT_\n#define GENERATED_PLUG"
},
{
"path": "example/macos/Flutter/ephemeral/Flutter-Generated.xcconfig",
"chars": 449,
"preview": "// This is a generated file; do not edit or check into version control.\nFLUTTER_ROOT=/usr/local/Caskroom/flutter/1.2.1/f"
},
{
"path": "example/macos/Flutter/ephemeral/flutter_export_environment.sh",
"chars": 557,
"preview": "#!/bin/sh\n# This is a generated file; do not edit or check into version control.\nexport \"FLUTTER_ROOT=/usr/local/Caskroo"
},
{
"path": "example/windows/flutter/generated_plugin_registrant.cc",
"chars": 164,
"preview": "//\n// Generated file. Do not edit.\n//\n\n// clang-format off\n\n#include \"generated_plugin_registrant.h\"\n\n\nvoid RegisterPlu"
},
{
"path": "example/windows/flutter/generated_plugin_registrant.h",
"chars": 302,
"preview": "//\n// Generated file. Do not edit.\n//\n\n// clang-format off\n\n#ifndef GENERATED_PLUGIN_REGISTRANT_\n#define GENERATED_PLUG"
},
{
"path": "lib/data_tables.dart",
"chars": 6297,
"preview": "import 'package:flutter/material.dart';\n\nimport 'ui/mobile_paged_listview.dart';\nimport 'ui/stateless_datatable.dart';\n\n"
},
{
"path": "lib/ui/mobile_paged_listview.dart",
"chars": 9858,
"preview": "import 'package:flutter/material.dart';\nimport 'package:flutter/cupertino.dart' as cupertino;\n\nclass PagedListView exten"
},
{
"path": "lib/ui/stateless_datatable.dart",
"chars": 12291,
"preview": "import 'dart:ui';\n\nimport 'package:flutter/gestures.dart' show DragStartBehavior;\nimport 'package:flutter/material.dart'"
},
{
"path": "pubspec.yaml",
"chars": 389,
"preview": "name: data_tables\ndescription: ListView on Mobile and Stateless Data Tables on Tablets and Desktops.\nversion: 1.4.0\nhome"
}
]
About this extraction
This page contains the full source code of the rodydavis/data_tables GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 30 files (49.4 KB), approximately 12.5k tokens, and a symbol index with 20 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.