forked from vandadnp/flutter-tips-and-tricks
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathemail-drag-and-drop-in-flutter.dart
158 lines (145 loc) Β· 4.39 KB
/
email-drag-and-drop-in-flutter.dart
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
// π¦ Twitter https://twitter.com/vandadnp
// π΅ LinkedIn https://linkedin.com/in/vandadnp
// π₯ YouTube https://youtube.com/c/vandadnp
// π Free Flutter Course https://linktr.ee/vandadnp
// π¦ 11+ Hours Bloc Course https://youtu.be/Mn254cnduOY
// πΆ 7+ Hours MobX Course https://youtu.be/7Od55PBxYkI
// π¦ 9+ Hours RxDart Course https://youtu.be/xBFWMYmm9ro
// π€ Want to support my work? https://buymeacoffee.com/vandad
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
void main() {
runApp(
MaterialApp(
debugShowCheckedModeBanner: false,
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const HomePage(),
),
);
}
enum EmailProvider {
gmail('gmail.com', 'G', Colors.red, Colors.white),
yahoo('yahoo.com', 'Y', Colors.purple, Colors.white),
hotmail('hotmail.com', 'H', Colors.orange, Colors.white);
final String name;
final String title;
final Color backgroundColor;
final Color foregroundColor;
const EmailProvider(
this.name,
this.title,
this.backgroundColor,
this.foregroundColor,
);
}
extension WithAtSign on String {
String get withAtSign => '@$this';
}
extension IsEmailProvider on String {
bool get isEmailProvider {
for (final provider in EmailProvider.values) {
if (provider.name.toLowerCase().trim() == trim().toLowerCase()) {
return true;
}
}
return false;
}
}
extension Append on TextEditingController {
void append(String text) {
this.text += text;
selection = TextSelection.fromPosition(
TextPosition(
offset: this.text.length,
),
);
}
}
class DropTargetTextField extends HookWidget {
final Stream<String> onAppendText;
const DropTargetTextField({
Key? key,
required this.onAppendText,
}) : super(key: key);
@override
Widget build(BuildContext context) {
final controller = useTextEditingController();
return StreamBuilder<String>(
stream: onAppendText,
builder: (context, snapshot) {
final appendedText = snapshot.data;
if (appendedText != null && appendedText.isNotEmpty) {
controller.append(appendedText.withAtSign);
}
return DragTarget<String>(
onWillAccept: (data) => data?.isEmailProvider ?? false,
onAccept: (text) => controller.append(
text.withAtSign,
),
builder: (context, candidateData, rejectedData) {
return TextField(
autofocus: true,
autocorrect: false,
controller: controller,
decoration: InputDecoration(
hintText: 'Enter your email here...',
suffixIcon: IconButton(
onPressed: controller.clear,
icon: const Icon(Icons.clear),
),
),
keyboardType: TextInputType.emailAddress,
);
},
);
},
);
}
}
class HomePage extends HookWidget {
const HomePage({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
final streamController = useStreamController<String>();
return Scaffold(
appBar: AppBar(
title: const Text('Email Providers in Flutter'),
),
body: Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
children: [
DropTargetTextField(
onAppendText: streamController.stream,
),
Wrap(
spacing: 10.0,
children: EmailProvider.values.map(
(provider) {
final avatar = CircleAvatar(
backgroundColor: provider.backgroundColor,
foregroundColor: provider.foregroundColor,
child: Text(provider.title),
);
return Draggable<String>(
data: provider.name,
feedback: avatar,
child: InputChip(
avatar: avatar,
label: Text(provider.name),
onPressed: () {
streamController.sink.add(provider.name);
},
),
);
},
).toList(),
)
],
),
),
);
}
}