From e527614afb3dce94d1814b17c8a3a612364b38e9 Mon Sep 17 00:00:00 2001 From: koukibadr Date: Thu, 21 May 2026 12:01:06 +0300 Subject: [PATCH] feat: update searchable listivew demo app --- example/lib/data/actor.dart | 11 + example/lib/data/actors_data.dart | 29 ++ example/lib/example_expansion.dart | 26 -- example/lib/main.dart | 407 ++---------------- example/lib/widgets/actor_item_widget.dart | 65 +++ .../widgets/async_searchable_listview.dart | 54 +++ .../widgets/basic_searchable_listview.dart | 70 +++ example/lib/widgets/empty_widget.dart | 21 + .../expansion_searchable_listview.dart | 55 +++ .../widgets/sliver_searchable_listview.dart | 23 + example/pubspec.lock | 30 +- 11 files changed, 368 insertions(+), 423 deletions(-) create mode 100644 example/lib/data/actor.dart create mode 100644 example/lib/data/actors_data.dart delete mode 100644 example/lib/example_expansion.dart create mode 100644 example/lib/widgets/actor_item_widget.dart create mode 100644 example/lib/widgets/async_searchable_listview.dart create mode 100644 example/lib/widgets/basic_searchable_listview.dart create mode 100644 example/lib/widgets/empty_widget.dart create mode 100644 example/lib/widgets/expansion_searchable_listview.dart create mode 100644 example/lib/widgets/sliver_searchable_listview.dart diff --git a/example/lib/data/actor.dart b/example/lib/data/actor.dart new file mode 100644 index 0000000..320272c --- /dev/null +++ b/example/lib/data/actor.dart @@ -0,0 +1,11 @@ +class Actor { + int age; + String name; + String lastName; + + Actor({ + required this.age, + required this.name, + required this.lastName, + }); +} diff --git a/example/lib/data/actors_data.dart b/example/lib/data/actors_data.dart new file mode 100644 index 0000000..e903081 --- /dev/null +++ b/example/lib/data/actors_data.dart @@ -0,0 +1,29 @@ +import 'package:example/data/actor.dart'; + +final List actors = [ + Actor(age: 47, name: 'Leonardo', lastName: 'DiCaprio'), + Actor(age: 58, name: 'Johnny', lastName: 'Depp'), + Actor(age: 78, name: 'Robert', lastName: 'De Niro'), + Actor(age: 44, name: 'Tom', lastName: 'Hardy'), + Actor(age: 66, name: 'Denzel', lastName: 'Washington'), + Actor(age: 49, name: 'Ben', lastName: 'Affleck'), + Actor(age: 47, name: 'Leonardo', lastName: 'DiCaprio'), + Actor(age: 58, name: 'Johnny', lastName: 'Depp'), + Actor(age: 78, name: 'Robert', lastName: 'De Niro'), + Actor(age: 44, name: 'Tom', lastName: 'Hardy'), + Actor(age: 66, name: 'Denzel', lastName: 'Washington'), + Actor(age: 49, name: 'Ben', lastName: 'Affleck'), +]; + + final Map> mapOfActors = { + 'test 1': [ + Actor(age: 47, name: 'Leonardo', lastName: 'DiCaprio'), + Actor(age: 66, name: 'Denzel', lastName: 'Washington'), + Actor(age: 49, name: 'Ben', lastName: 'Affleck'), + ], + 'test 2': [ + Actor(age: 58, name: 'Johnny', lastName: 'Depp'), + Actor(age: 78, name: 'Robert', lastName: 'De Niro'), + Actor(age: 44, name: 'Tom', lastName: 'Hardy'), + ] + }; \ No newline at end of file diff --git a/example/lib/example_expansion.dart b/example/lib/example_expansion.dart deleted file mode 100644 index 1a2e288..0000000 --- a/example/lib/example_expansion.dart +++ /dev/null @@ -1,26 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:searchable_listview/searchable_listview.dart'; - -class ExampleExpansion extends StatelessWidget { - const ExampleExpansion({Key? key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return Scaffold( - body: SearchableList.expansion( - expansionListData: const {}, - expansionTitleBuilder: (context) { - return const Text('Example Expansion'); - }, - filterExpansionData: filterFunction, - expansionListBuilder: (_, __) { - return const Text('Example Expansion Item'); - }, - ), - ); - } - - Map> filterFunction(String filter) { - return {}; - } -} diff --git a/example/lib/main.dart b/example/lib/main.dart index fa341b8..d286f58 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -1,6 +1,8 @@ +import 'package:example/widgets/async_searchable_listview.dart'; +import 'package:example/widgets/basic_searchable_listview.dart'; +import 'package:example/widgets/expansion_searchable_listview.dart'; +import 'package:example/widgets/sliver_searchable_listview.dart'; import 'package:flutter/material.dart'; -import 'package:searchable_listview/resources/arrays.dart'; -import 'package:searchable_listview/searchable_listview.dart'; void main() { runApp(const MyApp()); @@ -17,401 +19,42 @@ class MyApp extends StatelessWidget { theme: ThemeData( primarySwatch: Colors.blue, ), - home: const Scaffold( - body: SafeArea( - child: ExampleApp(), - ), - ), + home: const ExampleWidget(), ); } } -class ExampleApp extends StatefulWidget { - const ExampleApp({Key? key}) : super(key: key); - - @override - State createState() => _ExampleAppState(); -} +class ExampleWidget extends StatelessWidget { + const ExampleWidget({Key? key}) : super(key: key); -class _ExampleAppState extends State { - final List actors = [ - Actor(age: 47, name: 'Leonardo', lastName: 'DiCaprio'), - Actor(age: 58, name: 'Johnny', lastName: 'Depp'), - Actor(age: 78, name: 'Robert', lastName: 'De Niro'), - Actor(age: 44, name: 'Tom', lastName: 'Hardy'), - Actor(age: 66, name: 'Denzel', lastName: 'Washington'), - Actor(age: 49, name: 'Ben', lastName: 'Affleck'), - Actor(age: 47, name: 'Leonardo', lastName: 'DiCaprio'), - Actor(age: 58, name: 'Johnny', lastName: 'Depp'), - Actor(age: 78, name: 'Robert', lastName: 'De Niro'), - Actor(age: 44, name: 'Tom', lastName: 'Hardy'), - Actor(age: 66, name: 'Denzel', lastName: 'Washington'), - Actor(age: 49, name: 'Ben', lastName: 'Affleck'), + static const List _tabs = [ + Tab(text: 'Basic'), + Tab(text: 'Async'), + Tab(text: 'Sliver'), + Tab(text: 'Expansion'), ]; - List filteredActors = []; - - final Map> mapOfActors = { - 'test 1': [ - Actor(age: 47, name: 'Leonardo', lastName: 'DiCaprio'), - Actor(age: 66, name: 'Denzel', lastName: 'Washington'), - Actor(age: 49, name: 'Ben', lastName: 'Affleck'), - ], - 'test 2': [ - Actor(age: 58, name: 'Johnny', lastName: 'Depp'), - Actor(age: 78, name: 'Robert', lastName: 'De Niro'), - Actor(age: 44, name: 'Tom', lastName: 'Hardy'), - ] - }; - - final TextEditingController searchTextController = TextEditingController(); - final formKey = GlobalKey(); - - @override - void initState() { - super.initState(); - filteredActors = actors; - } @override Widget build(BuildContext context) { - return SizedBox( - width: double.infinity, - child: Column( - children: [ - const Text('Searchable list with divider'), - Expanded( - child: Padding( - padding: const EdgeInsets.all(15), - child: renderSimpleSearchableList(), - ), - ), - Align( - alignment: Alignment.center, - child: Row( - children: [ - ElevatedButton( - onPressed: addActor, - child: const Text('Add actor'), - ), - ElevatedButton( - onPressed: () { - if (formKey.currentState?.validate() ?? false) { - ScaffoldMessenger.of(context).showSnackBar( - const SnackBar(content: Text('Field is valid')), - ); - } else { - ScaffoldMessenger.of(context).showSnackBar( - const SnackBar(content: Text('Field is not valid')), - ); - } - }, - child: const Text('Validate field'), - ), - ], - ), - ) - ], - ), - ); - } - - void addActor() { - actors.add(Actor( - age: 10, - lastName: 'Ali', - name: 'ALi', - )); - setState(() {}); - } - - Widget simpleSearchWithSort() { - return SearchableList( - textAlignVertical: TextAlignVertical.center, - searchFieldHeight: 40, - lazyLoadingEnabled: false, - separatorBuilder: (context, index) { - return Container( - height: 40, - ); - }, - sortPredicate: (a, b) => a.age.compareTo(b.age), - itemBuilder: (item) { - int index = filteredActors.indexOf(item); - if (index == 0) { - return Container( - color: Colors.red, - height: 10, - width: 300, - ); - } else { - return ActorItem(actor: filteredActors[index - 1]); - } - }, - emptyWidget: Column( - children: [ - Container( - color: Colors.red, - height: 10, - width: 300, - ), - const Column( - children: [Icon(Icons.error), Text('No Data found')], - ) - ], - ), - filter: (query) { - filteredActors = actors - .where((element) => - element.name.toLowerCase().contains(query.toLowerCase()) || - element.lastName.toLowerCase().contains(query.toLowerCase())) - .toList(); - return filteredActors; - }, - initialList: actors, - ); - } - - Widget renderSimpleSearchableList() { - return SearchableList( - separatorBuilder: (context, index) { - return const Divider(); - }, - textStyle: const TextStyle(fontSize: 25), - itemBuilder: (item) { - return ActorItem(actor: item); - }, - searchMode: SearchMode.onSubmit, - errorWidget: const Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Icon( - Icons.error, - color: Colors.red, - ), - SizedBox( - height: 20, - ), - Text('Error while fetching actors') - ], - ), - initialList: actors, - filter: (p0) { - return actors.where((element) => element.name.contains(p0)).toList(); - }, - emptyWidget: const EmptyView(), - onRefresh: () async {}, - displaySearchIcon: true, - labelText: "Search Actor", - closeKeyboardWhenScrolling: true, - ); - } - - Widget sliverListViewBuilder() { - return SearchableList.sliver( - initialList: actors, - inputDecoration: InputDecoration( - labelText: "Search Actor", - fillColor: Colors.white, - focusedBorder: OutlineInputBorder( - borderSide: const BorderSide( - color: Colors.blue, - width: 1.0, - ), - borderRadius: BorderRadius.circular(10.0), - ), - ), - filter: (query) { - return actors.where((element) => element.name.contains(query)).toList(); - }, - itemBuilder: (Actor actorItem) { - return ActorItem(actor: actorItem); - }, - sortWidget: const Icon(Icons.sort), - sortPredicate: (a, b) { - return a.age.compareTo(b.age); - }, - ); - } - - Widget renderAsynchSearchableListview() { - return SearchableList.async( - itemBuilder: (Actor item) { - return ActorItem(actor: item); - }, - asyncListCallback: () async { - await Future.delayed(const Duration(seconds: 5)); - return actors; - }, - asyncListFilter: (query, list) async { - await Future.delayed(const Duration(seconds: 3)); - var result = actors - .where((element) => - element.name.contains(query) || - element.lastName.contains(query)) - .toList(); - return result; - }, - asyncDebounceTime: 200, - separatorBuilder: (context, index) { - return Container( - height: 30, - ); - }, - textStyle: const TextStyle(fontSize: 25), - emptyWidget: const EmptyView(), - loadingWidget: const Center( - child: CircularProgressIndicator(), - ), - inputDecoration: InputDecoration( - labelText: "Search Actor", - fillColor: Colors.white, - focusedBorder: OutlineInputBorder( - borderSide: const BorderSide( - color: Colors.blue, - width: 1.0, - ), - borderRadius: BorderRadius.circular(10.0), - ), - ), - ); - } - - Widget expansionSearchableList() { - return SearchableList.expansion( - expansionListData: mapOfActors, - expansionTitleBuilder: (p0) { - return Container( - color: Colors.grey[300], - width: MediaQuery.of(context).size.width * 0.8, - height: 30, - child: Center( - child: Text(p0.toString()), - ), - ); - }, - filterExpansionData: (p0) { - final filteredMap = { - for (final entry in mapOfActors.entries) - entry.key: (mapOfActors[entry.key] ?? []) - .where((element) => element.name.contains(p0)) - .toList() - }; - return filteredMap; - }, - textStyle: const TextStyle(fontSize: 25), - expansionListBuilder: (int index, Actor _actor) { - return ActorItem( - actor: _actor, - ); - }, - hideEmptyExpansionItems: true, - emptyWidget: const EmptyView(), - inputDecoration: InputDecoration( - labelText: "Search Actor", - fillColor: Colors.white, - focusedBorder: OutlineInputBorder( - borderSide: const BorderSide( - color: Colors.blue, - width: 1.0, + return DefaultTabController( + length: _tabs.length, + child: Scaffold( + appBar: AppBar( + title: const Text('Searchable Listview Examples'), + bottom: const TabBar( + isScrollable: true, + tabs: _tabs, ), - borderRadius: BorderRadius.circular(10.0), - ), - ), - ); - } -} - -class ActorItem extends StatelessWidget { - final Actor actor; - - const ActorItem({ - Key? key, - required this.actor, - }) : super(key: key); - - @override - Widget build(BuildContext context) { - return Padding( - padding: const EdgeInsets.all(8.0), - child: Container( - height: 60, - decoration: BoxDecoration( - color: Colors.grey[200], - borderRadius: BorderRadius.circular(10), ), - child: Row( + body: const TabBarView( children: [ - const SizedBox( - width: 10, - ), - Icon( - Icons.star, - color: Colors.yellow[700], - ), - const SizedBox( - width: 10, - ), - Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Text( - 'Firstname: ${actor.name}', - style: const TextStyle( - color: Colors.black, - fontWeight: FontWeight.bold, - ), - ), - Text( - 'Lastname: ${actor.lastName}', - style: const TextStyle( - color: Colors.black, - fontWeight: FontWeight.bold, - ), - ), - Text( - 'Age: ${actor.age}', - style: const TextStyle( - color: Colors.black, - ), - ), - ], - ), + BasicSearchableListview(), + AsyncSearchableListview(), + SliverSearchableListview(), + ExpansionSearchableListview(), ], ), ), ); } } - -class EmptyView extends StatelessWidget { - const EmptyView({Key? key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return const Center( - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Icon( - Icons.error, - color: Colors.red, - ), - Text('no actor is found with this name'), - ], - ), - ); - } -} - -class Actor { - int age; - String name; - String lastName; - - Actor({ - required this.age, - required this.name, - required this.lastName, - }); -} diff --git a/example/lib/widgets/actor_item_widget.dart b/example/lib/widgets/actor_item_widget.dart new file mode 100644 index 0000000..6a33fba --- /dev/null +++ b/example/lib/widgets/actor_item_widget.dart @@ -0,0 +1,65 @@ +import 'package:example/data/actor.dart'; +import 'package:flutter/material.dart'; + +class ActorItem extends StatelessWidget { + final Actor actor; + + const ActorItem({ + Key? key, + required this.actor, + }) : super(key: key); + + @override + Widget build(BuildContext context) { + return Padding( + padding: const EdgeInsets.all(8.0), + child: Container( + height: 60, + decoration: BoxDecoration( + color: Colors.grey[200], + borderRadius: BorderRadius.circular(10), + ), + child: Row( + children: [ + const SizedBox( + width: 10, + ), + Icon( + Icons.star, + color: Colors.yellow[700], + ), + const SizedBox( + width: 10, + ), + Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text( + 'Firstname: ${actor.name}', + style: const TextStyle( + color: Colors.black, + fontWeight: FontWeight.bold, + ), + ), + Text( + 'Lastname: ${actor.lastName}', + style: const TextStyle( + color: Colors.black, + fontWeight: FontWeight.bold, + ), + ), + Text( + 'Age: ${actor.age}', + style: const TextStyle( + color: Colors.black, + ), + ), + ], + ), + ], + ), + ), + ); + } +} diff --git a/example/lib/widgets/async_searchable_listview.dart b/example/lib/widgets/async_searchable_listview.dart new file mode 100644 index 0000000..cf65364 --- /dev/null +++ b/example/lib/widgets/async_searchable_listview.dart @@ -0,0 +1,54 @@ +import 'package:example/data/actor.dart'; +import 'package:example/data/actors_data.dart'; +import 'package:example/widgets/actor_item_widget.dart'; +import 'package:example/widgets/empty_widget.dart'; +import 'package:flutter/material.dart'; +import 'package:searchable_listview/searchable_listview.dart'; + +class AsyncSearchableListview extends StatelessWidget { + const AsyncSearchableListview({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + return SearchableList.async( + itemBuilder: (Actor item) { + return ActorItem(actor: item); + }, + asyncListCallback: () async { + await Future.delayed(const Duration(seconds: 5)); + return actors; + }, + asyncListFilter: (query, list) async { + await Future.delayed(const Duration(seconds: 3)); + var result = actors + .where((element) => + element.name.contains(query) || + element.lastName.contains(query)) + .toList(); + return result; + }, + asyncDebounceTime: 200, + separatorBuilder: (context, index) { + return Container( + height: 30, + ); + }, + textStyle: const TextStyle(fontSize: 25), + emptyWidget: const EmptyView(), + loadingWidget: const Center( + child: CircularProgressIndicator(), + ), + inputDecoration: InputDecoration( + labelText: 'Search Actor', + fillColor: Colors.white, + focusedBorder: OutlineInputBorder( + borderSide: const BorderSide( + color: Colors.blue, + width: 1.0, + ), + borderRadius: BorderRadius.circular(10.0), + ), + ), + ); + } +} diff --git a/example/lib/widgets/basic_searchable_listview.dart b/example/lib/widgets/basic_searchable_listview.dart new file mode 100644 index 0000000..ec0f7dd --- /dev/null +++ b/example/lib/widgets/basic_searchable_listview.dart @@ -0,0 +1,70 @@ +import 'package:example/data/actor.dart'; +import 'package:example/data/actors_data.dart'; +import 'package:example/widgets/actor_item_widget.dart'; +import 'package:flutter/material.dart'; +import 'package:searchable_listview/searchable_listview.dart'; + +class BasicSearchableListview extends StatefulWidget { + const BasicSearchableListview({Key? key}) : super(key: key); + + @override + State createState() => _BasicSearchableListviewState(); +} + +class _BasicSearchableListviewState extends State { + List filteredActors = []; + + @override + void initState() { + super.initState(); + filteredActors = actors; + } + + @override + Widget build(BuildContext context) { + return SearchableList( + textAlignVertical: TextAlignVertical.center, + searchFieldHeight: 40, + lazyLoadingEnabled: false, + separatorBuilder: (context, index) { + return Container( + height: 40, + ); + }, + sortPredicate: (a, b) => a.age.compareTo(b.age), + itemBuilder: (item) { + int index = filteredActors.indexOf(item); + if (index == 0) { + return Container( + color: Colors.red, + height: 10, + width: 300, + ); + } else { + return ActorItem(actor: filteredActors[index - 1]); + } + }, + emptyWidget: Column( + children: [ + Container( + color: Colors.red, + height: 10, + width: 300, + ), + const Column( + children: [Icon(Icons.error), Text('No Data found')], + ) + ], + ), + filter: (query) { + filteredActors = actors + .where((element) => + element.name.toLowerCase().contains(query.toLowerCase()) || + element.lastName.toLowerCase().contains(query.toLowerCase())) + .toList(); + return filteredActors; + }, + initialList: actors, + ); + } +} diff --git a/example/lib/widgets/empty_widget.dart b/example/lib/widgets/empty_widget.dart new file mode 100644 index 0000000..715110d --- /dev/null +++ b/example/lib/widgets/empty_widget.dart @@ -0,0 +1,21 @@ +import 'package:flutter/material.dart'; + +class EmptyView extends StatelessWidget { + const EmptyView({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + return const Center( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Icon( + Icons.error, + color: Colors.red, + ), + Text('no actor is found with this name'), + ], + ), + ); + } +} diff --git a/example/lib/widgets/expansion_searchable_listview.dart b/example/lib/widgets/expansion_searchable_listview.dart new file mode 100644 index 0000000..34efcd6 --- /dev/null +++ b/example/lib/widgets/expansion_searchable_listview.dart @@ -0,0 +1,55 @@ +import 'package:example/data/actor.dart'; +import 'package:example/data/actors_data.dart'; +import 'package:example/widgets/actor_item_widget.dart'; +import 'package:example/widgets/empty_widget.dart'; +import 'package:flutter/material.dart'; +import 'package:searchable_listview/searchable_listview.dart'; + +class ExpansionSearchableListview extends StatelessWidget { + const ExpansionSearchableListview({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + return SearchableList.expansion( + expansionListData: mapOfActors, + expansionTitleBuilder: (p0) { + return Container( + color: Colors.grey[300], + width: MediaQuery.of(context).size.width * 0.8, + height: 30, + child: Center( + child: Text(p0.toString()), + ), + ); + }, + filterExpansionData: (p0) { + final filteredMap = { + for (final entry in mapOfActors.entries) + entry.key: (mapOfActors[entry.key] ?? []) + .where((element) => element.name.contains(p0)) + .toList() + }; + return filteredMap; + }, + textStyle: const TextStyle(fontSize: 25), + expansionListBuilder: (int index, Actor _actor) { + return ActorItem( + actor: _actor, + ); + }, + hideEmptyExpansionItems: true, + emptyWidget: const EmptyView(), + inputDecoration: InputDecoration( + labelText: 'Search Actor', + fillColor: Colors.white, + focusedBorder: OutlineInputBorder( + borderSide: const BorderSide( + color: Colors.blue, + width: 1.0, + ), + borderRadius: BorderRadius.circular(10.0), + ), + ), + ); + } +} diff --git a/example/lib/widgets/sliver_searchable_listview.dart b/example/lib/widgets/sliver_searchable_listview.dart new file mode 100644 index 0000000..7c605b6 --- /dev/null +++ b/example/lib/widgets/sliver_searchable_listview.dart @@ -0,0 +1,23 @@ +import 'package:example/data/actor.dart'; +import 'package:example/data/actors_data.dart'; +import 'package:flutter/material.dart'; +import 'package:searchable_listview/searchable_listview.dart'; + +class SliverSearchableListview extends StatelessWidget { + const SliverSearchableListview({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + return SearchableList.sliver( + filter: (query) => actors + .where((actor) => '${actor.name} ${actor.lastName}' + .toLowerCase() + .contains(query.toLowerCase())) + .toList(), + initialList: actors, + itemBuilder: (item) => ListTile( + title: Text('${item.name} ${item.lastName}'), + ), + ); + } +} diff --git a/example/pubspec.lock b/example/pubspec.lock index 94a2399..138da22 100644 --- a/example/pubspec.lock +++ b/example/pubspec.lock @@ -5,10 +5,10 @@ packages: dependency: transitive description: name: async - sha256: "758e6d74e971c3e5aceb4110bfd6698efc7f501675bcfe0c775459a8140750eb" + sha256: e2eb0491ba5ddb6177742d2da23904574082139b07c1e33b8503b9f46f3e1a37 url: "https://pub.dev" source: hosted - version: "2.13.0" + version: "2.13.1" boolean_selector: dependency: transitive description: @@ -21,10 +21,10 @@ packages: dependency: transitive description: name: characters - sha256: f71061c654a3380576a52b451dd5532377954cf9dbd272a78fc8479606670803 + sha256: faf38497bda5ead2a8c7615f4f7939df04333478bf32e4173fcb06d428b5716b url: "https://pub.dev" source: hosted - version: "1.4.0" + version: "1.4.1" clock: dependency: transitive description: @@ -111,26 +111,26 @@ packages: dependency: transitive description: name: matcher - sha256: dc58c723c3c24bf8d3e2d3ad3f2f9d7bd9cf43ec6feaa64181775e60190153f2 + sha256: "31bd099b47c10cd1aeb55146a2d46ce0277630ecef3f7dae54ad7873f36696cd" url: "https://pub.dev" source: hosted - version: "0.12.17" + version: "0.12.20" material_color_utilities: dependency: transitive description: name: material_color_utilities - sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec + sha256: "9c337007e82b1889149c82ed242ed1cb24a66044e30979c44912381e9be4c48b" url: "https://pub.dev" source: hosted - version: "0.11.1" + version: "0.13.0" meta: dependency: transitive description: name: meta - sha256: "23f08335362185a5ea2ad3a4e597f1375e78bce8a040df5c600c8d3552ef2394" + sha256: df0c643f44ad098eb37988027a8e2b2b5a031fd3977f06bbfd3a76637e8df739 url: "https://pub.dev" source: hosted - version: "1.17.0" + version: "1.18.2" path: dependency: transitive description: @@ -195,18 +195,18 @@ packages: dependency: transitive description: name: test_api - sha256: ab2726c1a94d3176a45960b6234466ec367179b87dd74f1611adb1f3b5fb9d55 + sha256: "2a122cbe059f8b610d3a5415f42e255b6c17b1f21eee1d960f31080237fb4f11" url: "https://pub.dev" source: hosted - version: "0.7.7" + version: "0.7.12" vector_math: dependency: transitive description: name: vector_math - sha256: d530bd74fea330e6e364cda7a85019c434070188383e1cd8d9777ee586914c5b + sha256: "47a1b32ee755c3fcffa33db52a7258c137f97bdb2209a1075be847809fac4ccf" url: "https://pub.dev" source: hosted - version: "2.2.0" + version: "2.3.0" vm_service: dependency: transitive description: @@ -216,5 +216,5 @@ packages: source: hosted version: "15.0.0" sdks: - dart: ">=3.8.0-0 <4.0.0" + dart: ">=3.10.0 <4.0.0" flutter: ">=3.18.0-18.0.pre.54"