@appiq/flutter-workflow 1.0.0 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,597 @@
1
+ # Pretty UI Examples for AppIQ Flutter Workflow
2
+
3
+ This document contains examples of modern, beautiful UI components following Pretty UI design principles.
4
+
5
+ ## Color Palette Examples
6
+
7
+ ### Example 1: Modern Blue Palette
8
+ ```dart
9
+ class ModernBlueTheme {
10
+ static const Color primary = Color(0xFF6366F1);
11
+ static const Color primaryVariant = Color(0xFF4F46E5);
12
+ static const Color secondary = Color(0xFF06B6D4);
13
+ static const Color surface = Color(0xFFF8FAFC);
14
+ static const Color background = Color(0xFFFFFFFF);
15
+ static const Color error = Color(0xFFEF4444);
16
+ static const Color success = Color(0xFF10B981);
17
+ }
18
+ ```
19
+
20
+ ### Example 2: Warm Gradient Palette
21
+ ```dart
22
+ class WarmGradientTheme {
23
+ static const LinearGradient primaryGradient = LinearGradient(
24
+ colors: [Color(0xFFFF6B6B), Color(0xFFFFE66D)],
25
+ begin: Alignment.topLeft,
26
+ end: Alignment.bottomRight,
27
+ );
28
+
29
+ static const LinearGradient secondaryGradient = LinearGradient(
30
+ colors: [Color(0xFF4ECDC4), Color(0xFF44A08D)],
31
+ begin: Alignment.topCenter,
32
+ end: Alignment.bottomCenter,
33
+ );
34
+ }
35
+ ```
36
+
37
+ ## Component Examples
38
+
39
+ ### Modern Card Design
40
+ ```dart
41
+ class PrettyProductCard extends StatelessWidget {
42
+ const PrettyProductCard({
43
+ super.key,
44
+ required this.title,
45
+ required this.price,
46
+ required this.imageUrl,
47
+ this.onTap,
48
+ });
49
+
50
+ final String title;
51
+ final String price;
52
+ final String imageUrl;
53
+ final VoidCallback? onTap;
54
+
55
+ @override
56
+ Widget build(BuildContext context) {
57
+ return Container(
58
+ margin: const EdgeInsets.all(8.0),
59
+ decoration: BoxDecoration(
60
+ color: Colors.white,
61
+ borderRadius: BorderRadius.circular(16.0),
62
+ boxShadow: [
63
+ BoxShadow(
64
+ color: Colors.black.withOpacity(0.08),
65
+ blurRadius: 20.0,
66
+ offset: const Offset(0, 4),
67
+ ),
68
+ ],
69
+ ),
70
+ child: Material(
71
+ color: Colors.transparent,
72
+ child: InkWell(
73
+ onTap: onTap,
74
+ borderRadius: BorderRadius.circular(16.0),
75
+ child: Column(
76
+ crossAxisAlignment: CrossAxisAlignment.start,
77
+ children: [
78
+ ClipRRect(
79
+ borderRadius: const BorderRadius.vertical(
80
+ top: Radius.circular(16.0),
81
+ ),
82
+ child: AspectRatio(
83
+ aspectRatio: 16 / 9,
84
+ child: Image.network(
85
+ imageUrl,
86
+ fit: BoxFit.cover,
87
+ ),
88
+ ),
89
+ ),
90
+ Padding(
91
+ padding: const EdgeInsets.all(16.0),
92
+ child: Column(
93
+ crossAxisAlignment: CrossAxisAlignment.start,
94
+ children: [
95
+ Text(
96
+ title,
97
+ style: Theme.of(context).textTheme.titleMedium?.copyWith(
98
+ fontWeight: FontWeight.w600,
99
+ ),
100
+ maxLines: 2,
101
+ overflow: TextOverflow.ellipsis,
102
+ ),
103
+ const SizedBox(height: 8.0),
104
+ Text(
105
+ price,
106
+ style: Theme.of(context).textTheme.headlineSmall?.copyWith(
107
+ color: Theme.of(context).primaryColor,
108
+ fontWeight: FontWeight.bold,
109
+ ),
110
+ ),
111
+ ],
112
+ ),
113
+ ),
114
+ ],
115
+ ),
116
+ ),
117
+ ),
118
+ );
119
+ }
120
+ }
121
+ ```
122
+
123
+ ### Elegant Profile Header
124
+ ```dart
125
+ class PrettyProfileHeader extends StatelessWidget {
126
+ const PrettyProfileHeader({
127
+ super.key,
128
+ required this.name,
129
+ required this.subtitle,
130
+ required this.avatarUrl,
131
+ this.backgroundGradient,
132
+ });
133
+
134
+ final String name;
135
+ final String subtitle;
136
+ final String avatarUrl;
137
+ final Gradient? backgroundGradient;
138
+
139
+ @override
140
+ Widget build(BuildContext context) {
141
+ return Container(
142
+ padding: const EdgeInsets.all(24.0),
143
+ decoration: BoxDecoration(
144
+ gradient: backgroundGradient ?? LinearGradient(
145
+ colors: [
146
+ Theme.of(context).primaryColor,
147
+ Theme.of(context).primaryColor.withOpacity(0.7),
148
+ ],
149
+ begin: Alignment.topLeft,
150
+ end: Alignment.bottomRight,
151
+ ),
152
+ borderRadius: const BorderRadius.vertical(
153
+ bottom: Radius.circular(32.0),
154
+ ),
155
+ ),
156
+ child: SafeArea(
157
+ child: Column(
158
+ children: [
159
+ const SizedBox(height: 20.0),
160
+ Container(
161
+ decoration: BoxDecoration(
162
+ shape: BoxShape.circle,
163
+ border: Border.all(
164
+ color: Colors.white,
165
+ width: 4.0,
166
+ ),
167
+ boxShadow: [
168
+ BoxShadow(
169
+ color: Colors.black.withOpacity(0.2),
170
+ blurRadius: 20.0,
171
+ offset: const Offset(0, 8),
172
+ ),
173
+ ],
174
+ ),
175
+ child: CircleAvatar(
176
+ radius: 50.0,
177
+ backgroundImage: NetworkImage(avatarUrl),
178
+ ),
179
+ ),
180
+ const SizedBox(height: 16.0),
181
+ Text(
182
+ name,
183
+ style: Theme.of(context).textTheme.headlineMedium?.copyWith(
184
+ color: Colors.white,
185
+ fontWeight: FontWeight.bold,
186
+ ),
187
+ ),
188
+ const SizedBox(height: 4.0),
189
+ Text(
190
+ subtitle,
191
+ style: Theme.of(context).textTheme.bodyLarge?.copyWith(
192
+ color: Colors.white.withOpacity(0.9),
193
+ ),
194
+ ),
195
+ ],
196
+ ),
197
+ ),
198
+ );
199
+ }
200
+ }
201
+ ```
202
+
203
+ ### Modern Search Bar
204
+ ```dart
205
+ class PrettySearchBar extends StatefulWidget {
206
+ const PrettySearchBar({
207
+ super.key,
208
+ this.hintText = 'Search...',
209
+ this.onChanged,
210
+ this.onSubmitted,
211
+ });
212
+
213
+ final String hintText;
214
+ final ValueChanged<String>? onChanged;
215
+ final ValueChanged<String>? onSubmitted;
216
+
217
+ @override
218
+ State<PrettySearchBar> createState() => _PrettySearchBarState();
219
+ }
220
+
221
+ class _PrettySearchBarState extends State<PrettySearchBar> {
222
+ final _controller = TextEditingController();
223
+ final _focusNode = FocusNode();
224
+
225
+ @override
226
+ Widget build(BuildContext context) {
227
+ return Container(
228
+ margin: const EdgeInsets.symmetric(horizontal: 16.0, vertical: 8.0),
229
+ decoration: BoxDecoration(
230
+ color: Theme.of(context).colorScheme.surface,
231
+ borderRadius: BorderRadius.circular(16.0),
232
+ boxShadow: [
233
+ BoxShadow(
234
+ color: Colors.black.withOpacity(0.06),
235
+ blurRadius: 10.0,
236
+ offset: const Offset(0, 2),
237
+ ),
238
+ ],
239
+ ),
240
+ child: TextField(
241
+ controller: _controller,
242
+ focusNode: _focusNode,
243
+ onChanged: widget.onChanged,
244
+ onSubmitted: widget.onSubmitted,
245
+ decoration: InputDecoration(
246
+ hintText: widget.hintText,
247
+ hintStyle: TextStyle(
248
+ color: Theme.of(context).colorScheme.onSurface.withOpacity(0.6),
249
+ ),
250
+ prefixIcon: Icon(
251
+ Icons.search,
252
+ color: Theme.of(context).colorScheme.onSurface.withOpacity(0.6),
253
+ ),
254
+ suffixIcon: _controller.text.isNotEmpty
255
+ ? IconButton(
256
+ icon: const Icon(Icons.clear),
257
+ onPressed: () {
258
+ _controller.clear();
259
+ widget.onChanged?.call('');
260
+ },
261
+ )
262
+ : null,
263
+ border: InputBorder.none,
264
+ contentPadding: const EdgeInsets.symmetric(
265
+ horizontal: 16.0,
266
+ vertical: 12.0,
267
+ ),
268
+ ),
269
+ ),
270
+ );
271
+ }
272
+
273
+ @override
274
+ void dispose() {
275
+ _controller.dispose();
276
+ _focusNode.dispose();
277
+ super.dispose();
278
+ }
279
+ }
280
+ ```
281
+
282
+ ### Smooth Bottom Navigation
283
+ ```dart
284
+ class PrettyBottomNavigation extends StatelessWidget {
285
+ const PrettyBottomNavigation({
286
+ super.key,
287
+ required this.currentIndex,
288
+ required this.onTap,
289
+ required this.items,
290
+ });
291
+
292
+ final int currentIndex;
293
+ final ValueChanged<int> onTap;
294
+ final List<PrettyBottomNavItem> items;
295
+
296
+ @override
297
+ Widget build(BuildContext context) {
298
+ return Container(
299
+ margin: const EdgeInsets.all(16.0),
300
+ padding: const EdgeInsets.symmetric(vertical: 8.0),
301
+ decoration: BoxDecoration(
302
+ color: Colors.white,
303
+ borderRadius: BorderRadius.circular(24.0),
304
+ boxShadow: [
305
+ BoxShadow(
306
+ color: Colors.black.withOpacity(0.1),
307
+ blurRadius: 20.0,
308
+ offset: const Offset(0, 8),
309
+ ),
310
+ ],
311
+ ),
312
+ child: Row(
313
+ mainAxisAlignment: MainAxisAlignment.spaceEvenly,
314
+ children: items.asMap().entries.map((entry) {
315
+ final index = entry.key;
316
+ final item = entry.value;
317
+ final isSelected = index == currentIndex;
318
+
319
+ return GestureDetector(
320
+ onTap: () => onTap(index),
321
+ child: AnimatedContainer(
322
+ duration: const Duration(milliseconds: 200),
323
+ curve: Curves.easeInOut,
324
+ padding: const EdgeInsets.symmetric(
325
+ horizontal: 16.0,
326
+ vertical: 8.0,
327
+ ),
328
+ decoration: BoxDecoration(
329
+ color: isSelected
330
+ ? Theme.of(context).primaryColor.withOpacity(0.1)
331
+ : Colors.transparent,
332
+ borderRadius: BorderRadius.circular(16.0),
333
+ ),
334
+ child: Row(
335
+ mainAxisSize: MainAxisSize.min,
336
+ children: [
337
+ Icon(
338
+ item.icon,
339
+ color: isSelected
340
+ ? Theme.of(context).primaryColor
341
+ : Colors.grey,
342
+ ),
343
+ if (isSelected) ...[
344
+ const SizedBox(width: 8.0),
345
+ Text(
346
+ item.label,
347
+ style: TextStyle(
348
+ color: Theme.of(context).primaryColor,
349
+ fontWeight: FontWeight.w600,
350
+ ),
351
+ ),
352
+ ],
353
+ ],
354
+ ),
355
+ ),
356
+ );
357
+ }).toList(),
358
+ ),
359
+ );
360
+ }
361
+ }
362
+
363
+ class PrettyBottomNavItem {
364
+ const PrettyBottomNavItem({
365
+ required this.icon,
366
+ required this.label,
367
+ });
368
+
369
+ final IconData icon;
370
+ final String label;
371
+ }
372
+ ```
373
+
374
+ ## Animation Examples
375
+
376
+ ### Staggered List Animation
377
+ ```dart
378
+ class StaggeredListView extends StatefulWidget {
379
+ const StaggeredListView({
380
+ super.key,
381
+ required this.children,
382
+ });
383
+
384
+ final List<Widget> children;
385
+
386
+ @override
387
+ State<StaggeredListView> createState() => _StaggeredListViewState();
388
+ }
389
+
390
+ class _StaggeredListViewState extends State<StaggeredListView>
391
+ with TickerProviderStateMixin {
392
+ late AnimationController _controller;
393
+ List<Animation<double>> _animations = [];
394
+
395
+ @override
396
+ void initState() {
397
+ super.initState();
398
+ _controller = AnimationController(
399
+ duration: Duration(milliseconds: widget.children.length * 100),
400
+ vsync: this,
401
+ );
402
+
403
+ _animations = widget.children.map((child) {
404
+ final index = widget.children.indexOf(child);
405
+ return Tween<double>(
406
+ begin: 0.0,
407
+ end: 1.0,
408
+ ).animate(
409
+ CurvedAnimation(
410
+ parent: _controller,
411
+ curve: Interval(
412
+ index * 0.1,
413
+ (index * 0.1) + 0.5,
414
+ curve: Curves.easeOutBack,
415
+ ),
416
+ ),
417
+ );
418
+ }).toList();
419
+
420
+ _controller.forward();
421
+ }
422
+
423
+ @override
424
+ Widget build(BuildContext context) {
425
+ return ListView.builder(
426
+ itemCount: widget.children.length,
427
+ itemBuilder: (context, index) {
428
+ return AnimatedBuilder(
429
+ animation: _animations[index],
430
+ builder: (context, child) {
431
+ return Transform.translate(
432
+ offset: Offset(0, 50 * (1 - _animations[index].value)),
433
+ child: Opacity(
434
+ opacity: _animations[index].value,
435
+ child: widget.children[index],
436
+ ),
437
+ );
438
+ },
439
+ );
440
+ },
441
+ );
442
+ }
443
+
444
+ @override
445
+ void dispose() {
446
+ _controller.dispose();
447
+ super.dispose();
448
+ }
449
+ }
450
+ ```
451
+
452
+ ### Floating Action Button with Morphing
453
+ ```dart
454
+ class MorphingFAB extends StatefulWidget {
455
+ const MorphingFAB({super.key});
456
+
457
+ @override
458
+ State<MorphingFAB> createState() => _MorphingFABState();
459
+ }
460
+
461
+ class _MorphingFABState extends State<MorphingFAB>
462
+ with SingleTickerProviderStateMixin {
463
+ late AnimationController _controller;
464
+ late Animation<double> _scaleAnimation;
465
+ late Animation<double> _rotationAnimation;
466
+
467
+ bool _isExpanded = false;
468
+
469
+ @override
470
+ void initState() {
471
+ super.initState();
472
+ _controller = AnimationController(
473
+ duration: const Duration(milliseconds: 300),
474
+ vsync: this,
475
+ );
476
+
477
+ _scaleAnimation = Tween<double>(
478
+ begin: 1.0,
479
+ end: 1.2,
480
+ ).animate(CurvedAnimation(
481
+ parent: _controller,
482
+ curve: Curves.easeInOut,
483
+ ));
484
+
485
+ _rotationAnimation = Tween<double>(
486
+ begin: 0.0,
487
+ end: 0.125, // 45 degrees
488
+ ).animate(CurvedAnimation(
489
+ parent: _controller,
490
+ curve: Curves.easeInOut,
491
+ ));
492
+ }
493
+
494
+ void _toggle() {
495
+ setState(() {
496
+ _isExpanded = !_isExpanded;
497
+ });
498
+
499
+ if (_isExpanded) {
500
+ _controller.forward();
501
+ } else {
502
+ _controller.reverse();
503
+ }
504
+ }
505
+
506
+ @override
507
+ Widget build(BuildContext context) {
508
+ return AnimatedBuilder(
509
+ animation: _controller,
510
+ builder: (context, child) {
511
+ return Transform.scale(
512
+ scale: _scaleAnimation.value,
513
+ child: Transform.rotate(
514
+ angle: _rotationAnimation.value * 2 * 3.14159,
515
+ child: FloatingActionButton(
516
+ onPressed: _toggle,
517
+ child: Icon(_isExpanded ? Icons.close : Icons.add),
518
+ ),
519
+ ),
520
+ );
521
+ },
522
+ );
523
+ }
524
+
525
+ @override
526
+ void dispose() {
527
+ _controller.dispose();
528
+ super.dispose();
529
+ }
530
+ }
531
+ ```
532
+
533
+ ## Performance Optimization Examples
534
+
535
+ ### Efficient List with const Widgets
536
+ ```dart
537
+ class OptimizedListItem extends StatelessWidget {
538
+ const OptimizedListItem({
539
+ super.key,
540
+ required this.title,
541
+ required this.subtitle,
542
+ required this.imageUrl,
543
+ });
544
+
545
+ final String title;
546
+ final String subtitle;
547
+ final String imageUrl;
548
+
549
+ @override
550
+ Widget build(BuildContext context) {
551
+ return const Card(
552
+ margin: EdgeInsets.symmetric(horizontal: 16.0, vertical: 4.0),
553
+ child: ListTile(
554
+ leading: _OptimizedAvatar(),
555
+ title: _OptimizedTitle(),
556
+ subtitle: _OptimizedSubtitle(),
557
+ trailing: Icon(Icons.chevron_right),
558
+ ),
559
+ );
560
+ }
561
+ }
562
+
563
+ class _OptimizedAvatar extends StatelessWidget {
564
+ const _OptimizedAvatar();
565
+
566
+ @override
567
+ Widget build(BuildContext context) {
568
+ return const CircleAvatar(
569
+ radius: 24.0,
570
+ backgroundImage: NetworkImage('https://example.com/avatar.jpg'),
571
+ );
572
+ }
573
+ }
574
+
575
+ class _OptimizedTitle extends StatelessWidget {
576
+ const _OptimizedTitle();
577
+
578
+ @override
579
+ Widget build(BuildContext context) {
580
+ return const Text(
581
+ 'Title Text',
582
+ style: TextStyle(fontWeight: FontWeight.w600),
583
+ );
584
+ }
585
+ }
586
+
587
+ class _OptimizedSubtitle extends StatelessWidget {
588
+ const _OptimizedSubtitle();
589
+
590
+ @override
591
+ Widget build(BuildContext context) {
592
+ return const Text('Subtitle text');
593
+ }
594
+ }
595
+ ```
596
+
597
+ These examples demonstrate modern Flutter UI design following Pretty UI principles with platform-adaptive components, smooth animations, and performance optimizations.