adding packages

This commit is contained in:
2026-01-15 14:38:46 -08:00
parent ef86e3ab6a
commit 6869cf47e5
5253 changed files with 726695 additions and 34 deletions
@@ -0,0 +1,337 @@
import 'package:flutter/material.dart';
import 'package:flutter_slidable/flutter_slidable.dart' as slidable;
import 'templates/avatar_tile.dart';
import 'templates/base_tile.dart';
import 'templates/basic_tile.dart';
import 'templates/phone_tile.dart';
class CupertinoTableCell extends StatelessWidget {
final bool selected;
final bool editing;
final bool canEdit;
final bool canDelete;
final bool lastItem;
final Widget? child;
final String id;
final VoidCallback? onDelete, onTap;
final List<slidable.IconSlideAction>? leadingActions, trailingActions;
final ValueChanged<bool>? onSelected;
// -- Styling --
final CupertinoAccessory accessory;
final VoidCallback? accessoryTap;
final CupertinoEditingAction editingAction;
final CupertinoEditingAccessory editingAccessory;
final VoidCallback? editingAccessoryTap;
const CupertinoTableCell({
Key? key,
this.selected = false,
this.canEdit = true,
this.canDelete = true,
this.editing = false,
this.lastItem = false,
this.trailingActions,
this.leadingActions,
this.onTap,
this.child,
required this.id,
this.onDelete,
this.onSelected,
this.accessory = CupertinoAccessory.disclosureIndicator,
this.accessoryTap,
this.editingAccessoryTap,
this.editingAccessory = CupertinoEditingAccessory.none,
this.editingAction = CupertinoEditingAction.select,
}) : super(key: key);
@override
Widget build(BuildContext context) {
Widget _child;
// CupertinoListTile _item = cell?.data as CupertinoListTile;
final CupertinoListTileData _ios = CupertinoListTileData(
hideLeadingIcon: true,
style: CupertinoCellStyle.custom,
accessory: accessory,
editingAction: editingAction,
editingAccessory: editingAccessory,
padding: null,
editingAccessoryTap: editingAccessoryTap,
accessoryTap: accessoryTap,
editingActionTap: () {
switch (editingAction) {
case CupertinoEditingAction.remove:
onDelete!();
break;
case CupertinoEditingAction.select:
onSelected!(!selected);
break;
default:
}
},
);
switch (editingAction) {
case CupertinoEditingAction.select:
_child = GestureDetector(
onTapDown: (TapDownDetails details) {
if (!editing) {
print("On Tap Down..");
onSelected!(true);
}
},
onTapCancel: () {
if (!editing) {
print("On Tap Cancel..");
onSelected!(false);
}
},
child: CupertinoListTile(
editing: editing,
selected: selected,
child: child,
ios: _ios,
lastItem: lastItem,
onTap: () {
if (!editing) {
onSelected!(false);
onTap!();
} else {
print("On Tap Down..");
onSelected!(!selected);
}
},
),
);
break;
case CupertinoEditingAction.remove:
_child = GestureDetector(
onTapDown: (TapDownDetails details) {
if (!editing) {
onSelected!(true);
}
},
onTapCancel: () {
if (!editing) {
onSelected!(false);
}
},
child: CupertinoListTile(
editing: editing,
selected: selected,
child: child,
ios: _ios,
lastItem: lastItem,
onTap: () {
if (!editing) {
print("Item Tapped...");
onSelected!(false);
onTap!();
}
},
),
);
break;
default:
_child = CupertinoListTile(
editing: editing,
selected: selected,
child: child,
ios: _ios,
lastItem: lastItem,
onTap: () {
if (!editing) {
print("Item Tapped...");
onSelected!(false);
onTap!();
}
},
);
}
final List<Widget> _trailingActions = <Widget>[];
if (trailingActions != null) {
_trailingActions..addAll(trailingActions!);
}
_trailingActions.add(
slidable.IconSlideAction(
caption: 'Delete',
color: Colors.red,
icon: Icons.delete,
onTap: onDelete!,
),
);
return slidable.Slidable(
key: key,
actionPane: slidable.SlidableDrawerActionPane(),
actionExtentRatio: 0.25,
child: _child,
actions: leadingActions,
secondaryActions: _trailingActions,
);
}
}
class CupertinoListTile extends StatelessWidget {
final Text? subtitle, title, id;
final Widget? avatar, child;
final List<Widget>? trailing;
final IconData? leading;
final CupertinoListTileData? ios;
final VoidCallback? onTap, onLongPressed;
final bool selected, editing;
final bool lastItem;
CupertinoListTile({
this.title,
this.id,
this.subtitle,
this.leading,
this.trailing,
this.avatar,
this.onTap,
this.onLongPressed,
this.ios,
this.child,
this.lastItem = true,
this.selected = false,
this.editing = false,
});
// : assert(ios?.style == CupertinoCellStyle.custom && child != null);
@override
Widget build(BuildContext context) {
Widget _child = Container();
switch (ios?.style ?? CupertinoCellStyle.custom) {
case CupertinoCellStyle.avatarDetail:
_child = CupertinoAvatarListTile(
avatar: avatar,
title: title?.data,
subtitle: subtitle?.data,
actions: trailing,
);
break;
case CupertinoCellStyle.subtitle:
_child = CupertinoPhoneListTile(
title: title?.data,
subtitle: subtitle?.data,
actions: trailing,
icon: leading,
hideLeadingIcon: ios?.hideLeadingIcon,
);
break;
case CupertinoCellStyle.basic:
_child = CupertinoTextMenu(
children: <Widget?>[title]..addAll(trailing ?? []),
);
break;
case CupertinoCellStyle.leftDetail:
_child = Row(
children: <Widget>[
...[subtitle ?? Container()],
...[title ?? Container()],
],
);
break;
case CupertinoCellStyle.rightDetail:
_child = CupertinoTextMenu(
children: <Widget?>[title, subtitle],
);
break;
case CupertinoCellStyle.custom:
_child = child ?? Container();
break;
}
final Widget _row = CupertinoBaseTile(
selected: selected,
onTap: onTap,
onLongPressed: onLongPressed,
accessory: ios?.accessory,
editing: editing,
editingAccessory: ios?.editingAccessory,
editingAction: ios?.editingAction,
accessoryTap: ios?.accessoryTap,
editingAccessoryTap: ios?.editingAccessoryTap,
editingActionTap: ios?.editingActionTap,
child: _child,
padding: ios?.padding,
);
if (lastItem) {
return _row;
}
return Column(
children: <Widget>[
_row,
Container(
height: 1.0,
color: const Color(0xFFD9D9D9),
),
],
);
}
}
class CupertinoListTileData {
final CupertinoCellStyle style;
final CupertinoEditingAction editingAction;
final CupertinoEditingAccessory editingAccessory;
final CupertinoAccessory accessory;
final VoidCallback? accessoryTap, editingAccessoryTap, editingActionTap;
final bool hideLeadingIcon, enableReorder;
final EdgeInsets? padding;
CupertinoListTileData({
this.style = CupertinoCellStyle.custom,
this.accessory = CupertinoAccessory.none,
this.editingAccessory = CupertinoEditingAccessory.none,
this.editingAction = CupertinoEditingAction.remove,
this.accessoryTap,
this.hideLeadingIcon = false,
this.enableReorder = true,
this.editingAccessoryTap,
this.editingActionTap,
this.padding = const EdgeInsets.only(left: 8.0, bottom: 8.0, top: 8.0),
});
}
enum CupertinoCellStyle {
basic,
rightDetail,
leftDetail,
subtitle,
avatarDetail,
custom,
}
enum CupertinoEditingAction {
none,
remove,
select,
}
enum CupertinoAccessory {
none,
disclosureIndicator,
detailDisclosure,
checkmark,
detail
}
enum CupertinoEditingAccessory {
none,
disclosureIndicator,
detailDisclosure,
checkmark,
detail,
dragHandle
}
@@ -0,0 +1,220 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_sticky_header/flutter_sticky_header.dart';
typedef RefreshCallback = Future<void> Function();
class CupertinoTableViewController extends StatelessWidget {
final String? title, previousTitle;
final Widget? leading, trailing;
final ValueChanged<bool>? onEditing;
final RefreshCallback? onRefresh;
final bool showEditingButtonLeft, showEditingButtonRight, hideAppBarOnSearch;
final bool isEditing, isSearching;
final List<CupertinoTableViewSection> sections;
final List<Widget>? widgets, toolbarButtons;
CupertinoTableViewController({
this.previousTitle,
this.title,
this.trailing,
this.leading,
this.onRefresh,
this.hideAppBarOnSearch = false,
this.isSearching = false,
this.isEditing = false,
this.onEditing,
List<Widget> children = const <Widget>[],
this.widgets,
this.showEditingButtonLeft = true,
this.showEditingButtonRight = false,
this.toolbarButtons,
}) : sections = [CupertinoTableViewSection(children: children)],
assert(showEditingButtonLeft != showEditingButtonRight);
CupertinoTableViewController.builder({
// this.item,
this.previousTitle,
this.title,
this.trailing,
this.leading,
this.onRefresh,
this.hideAppBarOnSearch = false,
this.isSearching = false,
this.isEditing = false,
this.onEditing,
required IndexedWidgetBuilder itemBuilder,
int? itemCount,
this.widgets,
this.showEditingButtonLeft = true,
this.showEditingButtonRight = false,
this.toolbarButtons,
}) : sections = [
CupertinoTableViewSection.builder(
itemBuilder: itemBuilder,
itemCount: itemCount,
)
],
assert(showEditingButtonLeft != showEditingButtonRight);
const CupertinoTableViewController.sectioned({
this.previousTitle,
this.title,
this.trailing,
this.hideAppBarOnSearch = false,
this.leading,
this.onRefresh,
this.isSearching = false,
this.isEditing = false,
this.onEditing,
this.showEditingButtonLeft = true,
this.showEditingButtonRight = false,
this.toolbarButtons,
required this.sections,
this.widgets,
}) : assert(showEditingButtonLeft != showEditingButtonRight);
@override
Widget build(BuildContext context) {
final _editingButton = Container(
padding: EdgeInsets.only(top: 10.0),
child: CupertinoTableViewEditingButton(
isEditing: isEditing,
onPressed: () => onEditing!(!isEditing),
),
);
final _searchNavBar = <Widget>[];
if (!isSearching && hideAppBarOnSearch) {
_searchNavBar.addAll([
CupertinoSliverNavigationBar(
// heroTag: title ?? "Title",
// transitionBetweenRoutes: false,
largeTitle: Text(title ?? "Title"),
// We're specifying a back label here because the previous page
// is a Material page. CupertinoPageRoutes could auto-populate
// these back labels.
previousPageTitle: previousTitle ?? "",
leading: showEditingButtonLeft ? _editingButton : leading,
trailing: showEditingButtonRight ? _editingButton : trailing,
),
CupertinoSliverRefreshControl(onRefresh: onRefresh),
]);
}
final _widgets = <Widget>[];
if (widgets != null) {
for (Widget _widget in widgets!) {
_widgets.add(SliverToBoxAdapter(child: _widget));
}
}
final _sections = <Widget>[];
int _index = 0;
for (CupertinoTableViewSection _section in sections) {
_sections.add(new SliverStickyHeader(
header: _section.header == null
? null
: new Container(
color: CupertinoColors.lightBackgroundGray,
padding:
const EdgeInsets.symmetric(horizontal: 16.0, vertical: 5.0),
alignment: Alignment.centerLeft,
child: _section.header,
),
sliver: SliverSafeArea(
top: false,
bottom: sections.length == _index + 1,
sliver: SliverList(
delegate: _section.childrenDelegate,
),
),
));
_index++;
}
return DefaultTextStyle(
style: Theme.of(context).textTheme.title!,
child: Scaffold(
body: CustomScrollView(
primary: true,
slivers: [
..._searchNavBar,
..._widgets,
..._sections,
],
),
persistentFooterButtons: toolbarButtons,
),
);
}
}
class CupertinoTableViewEditingButton extends StatelessWidget {
final bool? isEditing;
final VoidCallback? onPressed;
const CupertinoTableViewEditingButton({
this.isEditing,
this.onPressed,
});
@override
Widget build(BuildContext context) {
if (isEditing!) {
return GestureDetector(
onTap: onPressed,
child: const Text("Cancel",
style: TextStyle(
fontWeight: FontWeight.bold,
color: CupertinoColors.activeBlue,
)),
);
}
return GestureDetector(
onTap: onPressed,
child: const Text("Edit",
style: TextStyle(
color: CupertinoColors.activeBlue,
)),
);
}
}
// Todo; Seconts for Tableview
class CupertinoTableViewSection {
final Widget? header;
final SliverChildDelegate childrenDelegate;
CupertinoTableViewSection({
this.header,
List<Widget> children = const <Widget>[],
bool addAutomaticKeepAlives = true,
bool addRepaintBoundaries = true,
bool addSemanticIndexes = true,
}) : childrenDelegate = SliverChildListDelegate(
children,
addAutomaticKeepAlives: addAutomaticKeepAlives,
addRepaintBoundaries: addRepaintBoundaries,
addSemanticIndexes: addSemanticIndexes,
);
CupertinoTableViewSection.builder({
this.header,
required IndexedWidgetBuilder itemBuilder,
int? itemCount,
bool addAutomaticKeepAlives = true,
bool addRepaintBoundaries = true,
bool addSemanticIndexes = true,
}) : childrenDelegate = SliverChildBuilderDelegate(
itemBuilder,
childCount: itemCount,
addAutomaticKeepAlives: addAutomaticKeepAlives,
addRepaintBoundaries: addRepaintBoundaries,
addSemanticIndexes: addSemanticIndexes,
);
}
@@ -0,0 +1,51 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import '../../widgets/text.dart';
class CupertinoAvatarListTile extends StatelessWidget {
const CupertinoAvatarListTile({
required this.title,
this.subtitle,
this.actions,
this.avatar,
});
final Widget? avatar;
final String? title, subtitle;
final List<Widget>? actions;
@override
Widget build(BuildContext context) {
final List<Widget> _widgets = <Widget>[
Container(
height: 60.0,
width: 60.0,
child: avatar,
),
Expanded(
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 12.0),
child: subtitle == null
? CupertinoText(title, type: CupertinoTextTheme.title)
: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
CupertinoText(title, type: CupertinoTextTheme.title),
CupertinoText(subtitle, type: CupertinoTextTheme.subtitle),
],
),
),
),
];
final Widget row = Container(
padding: const EdgeInsets.only(left: 8.0),
child: Row(
children: _widgets..addAll(actions ?? <Widget>[]),
),
);
return row;
}
}
@@ -0,0 +1,206 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import '../cell.dart';
class CupertinoBaseTile extends StatelessWidget {
const CupertinoBaseTile({
this.selected = false,
this.editing = false,
required this.child,
this.accessory = CupertinoAccessory.none,
this.editingAccessory = CupertinoEditingAccessory.none,
this.editingAction = CupertinoEditingAction.remove,
this.accessoryTap,
this.onLongPressed,
this.onTap,
this.editingAccessoryTap,
this.editingActionTap,
this.padding,
});
final bool editing, selected;
final Widget child;
final EdgeInsets? padding;
final CupertinoEditingAction? editingAction;
final CupertinoEditingAccessory? editingAccessory;
final CupertinoAccessory? accessory;
final VoidCallback? accessoryTap,
onTap,
onLongPressed,
editingAccessoryTap,
editingActionTap;
@override
Widget build(BuildContext context) {
final List<Widget> _widgets = <Widget>[];
if (editing) {
if (editingAccessory != null) {
switch (editingAccessory) {
case CupertinoEditingAccessory.disclosureIndicator:
_widgets
..add(
const Icon(CupertinoIcons.right_chevron),
);
break;
case CupertinoEditingAccessory.detailDisclosure:
_widgets
..addAll([
IconButton(
icon: const Icon(CupertinoIcons.info,
color: CupertinoColors.activeBlue),
onPressed: editingAccessoryTap,
),
const Icon(CupertinoIcons.right_chevron),
]);
break;
case CupertinoEditingAccessory.detail:
_widgets
..add(
IconButton(
icon: const Icon(CupertinoIcons.info,
color: CupertinoColors.activeBlue),
onPressed: editingAccessoryTap,
),
);
break;
case CupertinoEditingAccessory.checkmark:
_widgets
..add(
const Icon(CupertinoIcons.check_mark),
);
break;
case CupertinoEditingAccessory.dragHandle:
_widgets
..add(IconButton(
icon: const Icon(Icons.dehaze),
onPressed: () {},
));
break;
case null:
case CupertinoEditingAccessory.none:
break;
}
}
} else {
if (accessory != null)
switch (accessory) {
case CupertinoAccessory.disclosureIndicator:
_widgets..add(const Icon(CupertinoIcons.right_chevron));
break;
case CupertinoAccessory.detailDisclosure:
_widgets
..addAll([
IconButton(
icon: const Icon(CupertinoIcons.info),
onPressed: accessoryTap,
),
const Icon(CupertinoIcons.right_chevron),
]);
break;
case CupertinoAccessory.detail:
_widgets
..add(IconButton(
icon: const Icon(CupertinoIcons.info),
onPressed: accessoryTap,
));
break;
case CupertinoAccessory.checkmark:
_widgets..add(const Icon(CupertinoIcons.check_mark));
break;
case null:
case CupertinoAccessory.none:
break;
}
}
Widget? _editingAction;
if (editingAction != null) {
switch (editingAction) {
case CupertinoEditingAction.remove:
_editingAction = Container(
height: 25.0,
width: 25.0,
decoration: BoxDecoration(
color: Colors.red,
borderRadius: BorderRadius.circular(25.0),
),
child: GestureDetector(
child: Icon(
Icons.remove,
color: CupertinoColors.white,
// size: 18.0,
),
onTap: editingActionTap,
),
);
break;
case CupertinoEditingAction.select:
_editingAction = Container(
height: 25.0,
width: 25.0,
decoration: selected
? BoxDecoration(
color: CupertinoColors.activeBlue,
borderRadius: BorderRadius.circular(25.0),
)
: new BoxDecoration(
border: new Border.all(
color: CupertinoColors.lightBackgroundGray),
shape: BoxShape.circle),
child: GestureDetector(
child: Icon(
CupertinoIcons.check_mark,
color: selected ? CupertinoColors.white : Colors.transparent,
),
onTap: editingActionTap,
),
);
break;
case null:
case CupertinoEditingAction.none:
_editingAction = null;
break;
}
}
Color? _rowColor = Colors.transparent;
if (selected && editing) {
_rowColor = Colors.lightBlue[50];
}
if (!editing && selected) {
_rowColor = Colors.lightBlue[50];
}
final Widget row = GestureDetector(
behavior: HitTestBehavior.opaque,
onTap: onTap,
onLongPress: onLongPressed,
child: SafeArea(
top: false,
bottom: false,
child: Container(
color: _rowColor,
padding: padding,
child: Row(
children: <Widget>[
Container(
padding: editing && _editingAction != null
? const EdgeInsets.only(left: 12.0)
: null,
child: editing ? _editingAction : null,
),
Expanded(child: child),
]..addAll(_widgets),
),
),
),
);
return row;
}
}
@@ -0,0 +1,36 @@
import 'package:flutter/material.dart';
class CupertinoTextMenu extends StatelessWidget {
final bool lastItem;
final List<Widget?> children;
CupertinoTextMenu({
required this.children,
this.lastItem = false,
});
@override
Widget build(BuildContext context) {
return Container(
decoration: const BoxDecoration(
color: Colors.transparent,
border: Border(
top: BorderSide(color: Color(0xFFBCBBC1), width: 0.0),
bottom: BorderSide(color: Color(0xFFBCBBC1), width: 0.0),
),
),
height: 44.0,
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 16.0),
child: SafeArea(
top: false,
bottom: false,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: children as List<Widget>,
),
),
),
);
}
}
@@ -0,0 +1,111 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import '../../widgets/text.dart';
class CupertinoPhoneListTile extends StatelessWidget {
final String? subtitle, title;
final List<Widget>? actions;
final IconData? icon;
final bool? hideLeadingIcon;
const CupertinoPhoneListTile({
this.actions,
this.subtitle,
required this.title,
this.icon,
this.hideLeadingIcon = true,
});
@override
Widget build(BuildContext context) {
Widget row;
if (subtitle == null) {
row = Container(
// color: selected ? Colors.grey[400] : Colors.transparent,
height: 40.0,
padding: EdgeInsets.only(top: subtitle == null ? 0.0 : 9.0),
child: Row(
children: <Widget>[
Container(
width: hideLeadingIcon! ? 12.0 : 38.0,
child: icon != null && !hideLeadingIcon!
? Align(
alignment: Alignment.center,
child: Icon(
icon,
color: CupertinoColors.inactiveGray,
size: 18.0,
),
)
: null,
),
Expanded(
child: Container(
padding:
const EdgeInsets.only(left: 1.0, bottom: 0.0, right: 10.0),
child: Row(
children: <Widget>[
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
CupertinoText(title, type: CupertinoTextTheme.title)
],
),
),
]..addAll(actions ?? <Widget>[])),
),
),
],
),
);
} else {
row = Container(
// color: selected ? Colors.grey[400] : Colors.transparent,
height: 60.0,
padding: const EdgeInsets.only(top: 9.0),
child: Row(
children: <Widget>[
Container(
width: hideLeadingIcon! ? 12.0 : 38.0,
child: icon != null && !hideLeadingIcon!
? Align(
alignment: Alignment.topCenter,
child: Icon(
icon,
color: CupertinoColors.inactiveGray,
size: 18.0,
),
)
: null,
),
Expanded(
child: Container(
padding:
const EdgeInsets.only(left: 1.0, bottom: 9.0, right: 10.0),
child: Row(
children: <Widget>[
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
CupertinoText(title, type: CupertinoTextTheme.title),
CupertinoText(subtitle,
type: CupertinoTextTheme.subtitle),
],
),
),
]..addAll(actions ?? <Widget>[])),
),
),
],
),
);
}
return row;
}
}