diff --git a/examples/with_flutter_sample/lib/main.dart b/examples/with_flutter_sample/lib/main.dart index 3a84aaf..6eb458c 100644 --- a/examples/with_flutter_sample/lib/main.dart +++ b/examples/with_flutter_sample/lib/main.dart @@ -3,7 +3,7 @@ import 'package:skynexui_responsive_stylesheet/skynexui_responsive_stylesheet.da import 'package:with_flutter_sample/chat_app_screen/chat_app_screen.dart'; import 'package:with_flutter_sample/flutter_basic/flutter_basic.dart'; import 'package:with_flutter_sample/holy_grail_layout/holy_grail_layout.dart'; -import 'package:with_flutter_sample/todo_app/screens/routes.dart'; +import 'package:with_flutter_sample/todo-app/screens/routes.dart'; void main() { runApp(const MyApp()); diff --git a/examples/with_flutter_sample/lib/todo-app/screens/home_screen/domain/todo/todo.dart b/examples/with_flutter_sample/lib/todo-app/screens/home_screen/domain/todo/todo.dart new file mode 100644 index 0000000..94510e2 --- /dev/null +++ b/examples/with_flutter_sample/lib/todo-app/screens/home_screen/domain/todo/todo.dart @@ -0,0 +1,16 @@ +class Todo { + final String id; + final String title; + final String description; + final bool completed; + DateTime createdAt = DateTime.now(); + final DateTime updatedAt; + + Todo({ + required this.id, + required this.title, + required this.description, + required this.completed, + required this.updatedAt, + }); +} diff --git a/examples/with_flutter_sample/lib/todo-app/screens/home_screen/home_screen.dart b/examples/with_flutter_sample/lib/todo-app/screens/home_screen/home_screen.dart new file mode 100644 index 0000000..b734383 --- /dev/null +++ b/examples/with_flutter_sample/lib/todo-app/screens/home_screen/home_screen.dart @@ -0,0 +1,117 @@ +import 'package:flutter/material.dart'; +import 'package:skynexui_responsive_stylesheet/skynexui_responsive_stylesheet.dart'; +import 'package:with_flutter_sample/todo-app/screens/home_screen/domain/todo/todo.dart'; +import 'package:with_flutter_sample/todo-app/screens/home_screen/patterns/header.dart'; +import 'package:with_flutter_sample/todo-app/screens/home_screen/patterns/main_action_button.dart'; +import 'package:with_flutter_sample/todo-app/screens/home_screen/patterns/todo_list_items.dart'; +import 'package:with_flutter_sample/todo-app/screens/home_screen/theme.dart'; + +class HomeScreen extends StatefulWidget { + const HomeScreen({Key? key}) : super(key: key); + + @override + State createState() => _HomeScreenState(); +} + +class _HomeScreenState extends State { + List todos = []; + + @override + void initState() { + super.initState(); + + Future.delayed(const Duration(milliseconds: 1 * 2000), () { + setState(() { + todos.add(Todo( + id: '1', + title: 'Buy milk', + description: 'Milk is needed for the baby', + completed: false, + updatedAt: DateTime.now(), + )); + todos.add(Todo( + id: '2', + title: 'Buy eggs', + description: 'Eggs are needed for the baby', + completed: false, + updatedAt: DateTime.now(), + )); + todos.add(Todo( + id: '3', + title: 'Buy bread', + description: 'Bread is needed for the baby', + completed: false, + updatedAt: DateTime.now(), + )); + }); + }); + } + + createTodo() { + setState(() { + todos.add(Todo( + id: '${todos.length + 1}', + title: 'New todo ${DateTime.now().toIso8601String()}', + description: '', + completed: false, + updatedAt: DateTime.now(), + )); + }); + } + + deleteTodo(int index) { + setState(() { + todos.removeAt(index); + }); + } + + @override + Widget build(BuildContext context) { + return TodoAppTheme( + child: Scaffold( + appBar: AppBar( + title: Text('Todo App (${todos.length})'), + ), + body: _HomeScreenBody( + todos: todos, + onDeleteTodo: deleteTodo, + ), + floatingActionButton: MainActionButton( + onPressed: createTodo, + ), + ), + ); + } +} + +class _HomeScreenBody extends StatelessWidget { + final List todos; + final Function(int) onDeleteTodo; + + const _HomeScreenBody({ + Key? key, + required this.todos, + required this.onDeleteTodo, + }) : super(key: key); + + @override + Widget build(BuildContext context) { + var responsive = Responsive(context); + return Container( + width: responsive.screenWidth.percent(100), + color: Colors.grey.shade100, + child: GridItem( + as: Column, + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + const Header(), + TodoListItems( + todos: todos, + onDeleteTodo: onDeleteTodo, + ), + ], + ), + ); + } +} diff --git a/examples/with_flutter_sample/lib/todo-app/screens/home_screen/patterns/header.dart b/examples/with_flutter_sample/lib/todo-app/screens/home_screen/patterns/header.dart new file mode 100644 index 0000000..cd1370e --- /dev/null +++ b/examples/with_flutter_sample/lib/todo-app/screens/home_screen/patterns/header.dart @@ -0,0 +1,30 @@ +import 'package:flutter/material.dart'; +import 'package:skynexui_responsive_stylesheet/skynexui_responsive_stylesheet.dart'; + +class Header extends StatelessWidget { + const Header({ + Key? key, + }) : super(key: key); + + @override + Widget build(BuildContext context) { + var responsive = Responsive(context); + + return Container( + margin: const EdgeInsets.only( + top: 20, + bottom: 20, + ), + child: Column( + children: const [ + TextField( + decoration: InputDecoration( + border: OutlineInputBorder(), + labelText: 'Search todos...', + ), + ) + ], + ), + ); + } +} diff --git a/examples/with_flutter_sample/lib/todo-app/screens/home_screen/patterns/main_action_button.dart b/examples/with_flutter_sample/lib/todo-app/screens/home_screen/patterns/main_action_button.dart new file mode 100644 index 0000000..a2cad77 --- /dev/null +++ b/examples/with_flutter_sample/lib/todo-app/screens/home_screen/patterns/main_action_button.dart @@ -0,0 +1,36 @@ +import 'package:flutter/material.dart'; +import 'package:skynexui_responsive_stylesheet/skynexui_responsive_stylesheet.dart'; + +class MainActionButton extends StatelessWidget { + final VoidCallback? onPressed; + + const MainActionButton({ + Key? key, + required this.onPressed, + }) : super(key: key); + + @override + Widget build(BuildContext context) { + var responsive = Responsive(context); + const label = 'Add todo'; + const icon = Icon(Icons.create); + + var btnFull = FloatingActionButton.extended( + onPressed: onPressed, + label: const Text(label), + icon: icon, + backgroundColor: Colors.blue, + ); + + var btnCompact = FloatingActionButton( + onPressed: onPressed, + backgroundColor: Colors.blue, + child: icon, + ); + + return responsive.value({ + Breakpoints.xs: btnCompact, + Breakpoints.md: btnFull, + }); + } +} diff --git a/examples/with_flutter_sample/lib/todo-app/screens/home_screen/patterns/todo_list_items.dart b/examples/with_flutter_sample/lib/todo-app/screens/home_screen/patterns/todo_list_items.dart new file mode 100644 index 0000000..7620e28 --- /dev/null +++ b/examples/with_flutter_sample/lib/todo-app/screens/home_screen/patterns/todo_list_items.dart @@ -0,0 +1,129 @@ +import 'package:flutter/material.dart'; +import 'package:skynexui_responsive_stylesheet/skynexui_responsive_stylesheet.dart'; +import 'package:with_flutter_sample/todo-app/screens/home_screen/domain/todo/todo.dart'; + +class TodoListItems extends StatelessWidget { + final List todos; + final Function(int) onDeleteTodo; + + const TodoListItems({ + Key? key, + required this.todos, + required this.onDeleteTodo, + }) : super(key: key); + + @override + Widget build(BuildContext context) { + var responsive = Responsive(context); + + if (todos.isEmpty) { + return const Expanded( + child: SizedBox( + child: Center( + child: CircularProgressIndicator( + color: Colors.amber, + ), + ), + ), + ); + } + + return Expanded( + child: GridView.builder( + gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( + crossAxisCount: responsive.value({ + Breakpoints.xs: 1, + Breakpoints.sm: 2, + Breakpoints.md: 3, + Breakpoints.lg: 4, + Breakpoints.xl: 5, + }), + ), + itemCount: todos.length, + itemBuilder: (BuildContext context, int index) { + return Card( + color: Colors.amber, + child: Center( + child: Row( + children: [ + Text(todos[index].title), + ElevatedButton( + onPressed: () { + onDeleteTodo(index); + }, + child: const Text("Delete"), + ), + ElevatedButton( + onPressed: () { + showDialog( + context: context, + builder: (context) { + var todo = todos[index]; + return TodoEditDialog( + responsive: responsive, todo: todo); + }); + }, + child: const Text("Edit"), + ), + ], + ), + ), + ); + }, + ), + ); + } +} + +class TodoEditDialog extends StatelessWidget { + const TodoEditDialog({ + Key? key, + required this.responsive, + required this.todo, + }) : super(key: key); + + final Responsive responsive; + final Todo todo; + + @override + Widget build(BuildContext context) { + return AlertDialog( + scrollable: true, + contentPadding: const EdgeInsets.all(0), + elevation: 0, + content: Expanded( + child: GridItem( + as: Column, + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Container( + width: responsive.screenWidth.percent(90), + color: Colors.amber, + padding: const EdgeInsets.all(16), + child: Column( + children: [ + TextField( + controller: TextEditingController(text: todo.title), + decoration: const InputDecoration( + border: OutlineInputBorder(), + labelText: 'Title', + ), + ), + const SizedBox(height: 16), + TextField( + controller: TextEditingController(text: todo.description), + decoration: const InputDecoration( + border: OutlineInputBorder(), + labelText: 'Title', + ), + ), + ], + ), + ), + ], + ), + ), + ); + } +} diff --git a/examples/with_flutter_sample/lib/todo_app/screens/home_screen/theme.dart b/examples/with_flutter_sample/lib/todo-app/screens/home_screen/theme.dart similarity index 100% rename from examples/with_flutter_sample/lib/todo_app/screens/home_screen/theme.dart rename to examples/with_flutter_sample/lib/todo-app/screens/home_screen/theme.dart diff --git a/examples/with_flutter_sample/lib/todo_app/screens/routes.dart b/examples/with_flutter_sample/lib/todo-app/screens/routes.dart similarity index 75% rename from examples/with_flutter_sample/lib/todo_app/screens/routes.dart rename to examples/with_flutter_sample/lib/todo-app/screens/routes.dart index f598e2f..736605f 100644 --- a/examples/with_flutter_sample/lib/todo_app/screens/routes.dart +++ b/examples/with_flutter_sample/lib/todo-app/screens/routes.dart @@ -1,4 +1,4 @@ -import './home_screen/home_screen.dart'; +import 'home_screen/home_screen.dart'; const appRoutesNamespace = 'todo-app'; diff --git a/examples/with_flutter_sample/lib/todo_app/screens/home_screen/home_screen.dart b/examples/with_flutter_sample/lib/todo_app/screens/home_screen/home_screen.dart deleted file mode 100644 index bbdac59..0000000 --- a/examples/with_flutter_sample/lib/todo_app/screens/home_screen/home_screen.dart +++ /dev/null @@ -1,54 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:skynexui_responsive_stylesheet/skynexui_responsive_stylesheet.dart'; -import 'package:with_flutter_sample/todo_app/screens/home_screen/theme.dart'; - -class HomeScreen extends StatefulWidget { - const HomeScreen({Key? key}) : super(key: key); - - @override - State createState() => _HomeScreenState(); -} - -class _HomeScreenState extends State { - @override - Widget build(BuildContext context) { - return TodoAppTheme( - child: Scaffold( - appBar: AppBar( - title: const Text('Todo App'), - ), - body: const Text('Sample page'), - floatingActionButton: const MainActionButton(), - ), - ); - } -} - -class MainActionButton extends StatelessWidget { - const MainActionButton({ - Key? key, - }) : super(key: key); - - @override - Widget build(BuildContext context) { - var responsive = Responsive(context); - - var btnFull = FloatingActionButton.extended( - onPressed: () {}, - label: const Text('Add todo'), - icon: const Icon(Icons.create), - backgroundColor: Colors.blue, - ); - - var btnCompact = FloatingActionButton( - onPressed: () {}, - backgroundColor: Colors.blue, - child: const Icon(Icons.create), - ); - - return responsive.value({ - Breakpoints.xs: btnCompact, - Breakpoints.md: btnFull, - }); - } -} diff --git a/examples/with_flutter_sample/pubspec.lock b/examples/with_flutter_sample/pubspec.lock index b6dc0ea..d68f819 100644 --- a/examples/with_flutter_sample/pubspec.lock +++ b/examples/with_flutter_sample/pubspec.lock @@ -84,7 +84,7 @@ packages: name: code_builder url: "https://pub.dartlang.org" source: hosted - version: "4.1.0" + version: "4.2.0" collection: dependency: transitive description: @@ -153,6 +153,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.0.1" + flutter_staggered_grid_view: + dependency: "direct main" + description: + name: flutter_staggered_grid_view + url: "https://pub.dartlang.org" + source: hosted + version: "0.6.2" flutter_test: dependency: "direct dev" description: flutter @@ -206,7 +213,7 @@ packages: name: mockito url: "https://pub.dartlang.org" source: hosted - version: "5.2.0" + version: "5.3.0" package_config: dependency: transitive description: @@ -239,7 +246,7 @@ packages: name: skynexui_responsive_stylesheet url: "https://pub.dartlang.org" source: hosted - version: "1.7.0" + version: "1.8.0" source_gen: dependency: transitive description: @@ -319,4 +326,4 @@ packages: version: "3.1.1" sdks: dart: ">=2.17.5 <3.0.0" - flutter: ">=1.17.0" + flutter: ">=2.0.0" diff --git a/examples/with_flutter_sample/pubspec.yaml b/examples/with_flutter_sample/pubspec.yaml index 293dc21..53befd4 100644 --- a/examples/with_flutter_sample/pubspec.yaml +++ b/examples/with_flutter_sample/pubspec.yaml @@ -29,9 +29,10 @@ environment: dependencies: flutter: sdk: flutter - skynexui_responsive_stylesheet: any - # The following adds the Cupertino Icons font to your application. - # Use with the CupertinoIcons class for iOS style icons. + # Prod + skynexui_responsive_stylesheet: 1.8.0 + flutter_staggered_grid_view: ^0.6.2 + cupertino_icons: ^1.0.2 dev_dependencies: