Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion examples/with_flutter_sample/lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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());
Expand Down
Original file line number Diff line number Diff line change
@@ -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,
});
}
Original file line number Diff line number Diff line change
@@ -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<HomeScreen> createState() => _HomeScreenState();
}

class _HomeScreenState extends State<HomeScreen> {
List<Todo> 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<Todo> 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,
),
],
),
);
}
}
Original file line number Diff line number Diff line change
@@ -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...',
),
)
],
),
);
}
}
Original file line number Diff line number Diff line change
@@ -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,
});
}
}
Original file line number Diff line number Diff line change
@@ -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<Todo> 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',
),
),
],
),
),
],
),
),
);
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import './home_screen/home_screen.dart';
import 'home_screen/home_screen.dart';

const appRoutesNamespace = 'todo-app';

Expand Down
Loading