openskill-ai 1.0.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.
Files changed (103) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +230 -0
  3. package/dist/chunk-63EFN7CX.js +450 -0
  4. package/dist/cli.d.ts +1 -0
  5. package/dist/cli.js +286 -0
  6. package/dist/index.d.ts +158 -0
  7. package/dist/index.js +391 -0
  8. package/package.json +70 -0
  9. package/skills/backend-best-practices/SKILL.md +116 -0
  10. package/skills/backend-best-practices/rules/api-consistent-responses.md +127 -0
  11. package/skills/backend-best-practices/rules/api-pagination.md +83 -0
  12. package/skills/backend-best-practices/rules/api-rate-limiting.md +94 -0
  13. package/skills/backend-best-practices/rules/api-restful-conventions.md +67 -0
  14. package/skills/backend-best-practices/rules/api-versioning.md +69 -0
  15. package/skills/backend-best-practices/rules/arch-dependency-injection.md +55 -0
  16. package/skills/backend-best-practices/rules/arch-dto-pattern.md +64 -0
  17. package/skills/backend-best-practices/rules/arch-repository-pattern.md +74 -0
  18. package/skills/backend-best-practices/rules/arch-separation-concerns.md +80 -0
  19. package/skills/backend-best-practices/rules/arch-service-layer.md +48 -0
  20. package/skills/backend-best-practices/rules/code-documentation.md +77 -0
  21. package/skills/backend-best-practices/rules/code-dry-principle.md +49 -0
  22. package/skills/backend-best-practices/rules/code-naming-conventions.md +47 -0
  23. package/skills/backend-best-practices/rules/code-single-responsibility.md +78 -0
  24. package/skills/backend-best-practices/rules/code-type-safety.md +64 -0
  25. package/skills/backend-best-practices/rules/db-connection-pooling.md +136 -0
  26. package/skills/backend-best-practices/rules/db-indexing.md +88 -0
  27. package/skills/backend-best-practices/rules/db-migrations.md +189 -0
  28. package/skills/backend-best-practices/rules/db-n-plus-one.md +118 -0
  29. package/skills/backend-best-practices/rules/db-transactions.md +178 -0
  30. package/skills/backend-best-practices/rules/deploy-environment-variables.md +63 -0
  31. package/skills/backend-best-practices/rules/deploy-graceful-shutdown.md +77 -0
  32. package/skills/backend-best-practices/rules/deploy-health-checks.md +70 -0
  33. package/skills/backend-best-practices/rules/deploy-monitoring.md +87 -0
  34. package/skills/backend-best-practices/rules/deploy-zero-downtime.md +85 -0
  35. package/skills/backend-best-practices/rules/error-global-handler.md +94 -0
  36. package/skills/backend-best-practices/rules/error-graceful-degradation.md +70 -0
  37. package/skills/backend-best-practices/rules/error-http-status-codes.md +77 -0
  38. package/skills/backend-best-practices/rules/error-logging.md +71 -0
  39. package/skills/backend-best-practices/rules/error-meaningful-messages.md +61 -0
  40. package/skills/backend-best-practices/rules/perf-async-operations.md +55 -0
  41. package/skills/backend-best-practices/rules/perf-caching.md +81 -0
  42. package/skills/backend-best-practices/rules/perf-compression.md +33 -0
  43. package/skills/backend-best-practices/rules/perf-database-queries.md +54 -0
  44. package/skills/backend-best-practices/rules/perf-lazy-loading.md +47 -0
  45. package/skills/backend-best-practices/rules/security-https-only.md +116 -0
  46. package/skills/backend-best-practices/rules/security-input-validation.md +96 -0
  47. package/skills/backend-best-practices/rules/security-jwt-best-practices.md +140 -0
  48. package/skills/backend-best-practices/rules/security-sql-injection.md +77 -0
  49. package/skills/clean-code-skills/references/solid.md +304 -0
  50. package/skills/clean-code-skills/skills.md +263 -0
  51. package/skills/flutter-skills/AGENTS.md +1265 -0
  52. package/skills/flutter-skills/SKILL.md +116 -0
  53. package/skills/flutter-skills/rules/advanced-custom-painter.md +117 -0
  54. package/skills/flutter-skills/rules/advanced-layer-link.md +103 -0
  55. package/skills/flutter-skills/rules/advanced-render-object.md +105 -0
  56. package/skills/flutter-skills/rules/advanced-sliver-persistent.md +111 -0
  57. package/skills/flutter-skills/rules/animation-animated-builder.md +118 -0
  58. package/skills/flutter-skills/rules/animation-cached-images.md +112 -0
  59. package/skills/flutter-skills/rules/animation-physics.md +105 -0
  60. package/skills/flutter-skills/rules/animation-reduce-overdraw.md +111 -0
  61. package/skills/flutter-skills/rules/animation-tween-sequence.md +112 -0
  62. package/skills/flutter-skills/rules/async-cancel-subscriptions.md +112 -0
  63. package/skills/flutter-skills/rules/async-compute.md +78 -0
  64. package/skills/flutter-skills/rules/async-debounce-throttle.md +104 -0
  65. package/skills/flutter-skills/rules/async-future-builder.md +106 -0
  66. package/skills/flutter-skills/rules/async-parallel.md +75 -0
  67. package/skills/flutter-skills/rules/build-avoid-rebuild.md +80 -0
  68. package/skills/flutter-skills/rules/build-const-constructors.md +56 -0
  69. package/skills/flutter-skills/rules/build-itemextent.md +73 -0
  70. package/skills/flutter-skills/rules/build-keys.md +74 -0
  71. package/skills/flutter-skills/rules/build-split-widgets.md +99 -0
  72. package/skills/flutter-skills/rules/dart-avoid-dynamic.md +86 -0
  73. package/skills/flutter-skills/rules/dart-cascade-notation.md +89 -0
  74. package/skills/flutter-skills/rules/dart-collection-if.md +92 -0
  75. package/skills/flutter-skills/rules/dart-final-const.md +70 -0
  76. package/skills/flutter-skills/rules/dart-spread-operator.md +90 -0
  77. package/skills/flutter-skills/rules/dart-string-buffer.md +77 -0
  78. package/skills/flutter-skills/rules/layout-avoid-opacity.md +110 -0
  79. package/skills/flutter-skills/rules/layout-clip-behavior.md +94 -0
  80. package/skills/flutter-skills/rules/layout-intrinsic-dimensions.md +89 -0
  81. package/skills/flutter-skills/rules/layout-repaint-boundary.md +117 -0
  82. package/skills/flutter-skills/rules/layout-slivers.md +94 -0
  83. package/skills/flutter-skills/rules/memory-dispose.md +90 -0
  84. package/skills/flutter-skills/rules/memory-image-cache.md +86 -0
  85. package/skills/flutter-skills/rules/memory-isolate.md +91 -0
  86. package/skills/flutter-skills/rules/memory-precache.md +114 -0
  87. package/skills/flutter-skills/rules/memory-weak-references.md +79 -0
  88. package/skills/flutter-skills/rules/state-late-final.md +90 -0
  89. package/skills/flutter-skills/rules/state-lift-state-up.md +84 -0
  90. package/skills/flutter-skills/rules/state-minimize-rebuilds.md +95 -0
  91. package/skills/flutter-skills/rules/state-selector.md +87 -0
  92. package/skills/flutter-skills/rules/state-valuenotifier.md +85 -0
  93. package/skills/frontend-design/SKILL.md +42 -0
  94. package/skills/skill-writer-skills/AGENTS.md +637 -0
  95. package/skills/skill-writer-skills/README.md +49 -0
  96. package/skills/skill-writer-skills/SKILL.md +97 -0
  97. package/skills/skill-writer-skills/metadata.json +17 -0
  98. package/skills/skill-writer-skills/references/common-pitfalls.md +291 -0
  99. package/skills/skill-writer-skills/references/core-principles.md +147 -0
  100. package/skills/skill-writer-skills/references/creation-process.md +250 -0
  101. package/skills/skill-writer-skills/references/design-patterns.md +300 -0
  102. package/skills/skill-writer-skills/references/skill-anatomy.md +174 -0
  103. package/skills/skill-writer-skills/references/validation-checklist.md +194 -0
@@ -0,0 +1,86 @@
1
+ ---
2
+ title: Avoid Dynamic Types
3
+ impact: LOW-MEDIUM
4
+ impactDescription: Enables AOT optimization, catches errors
5
+ tags: dart, types, dynamic, safety
6
+ ---
7
+
8
+ ## Avoid Dynamic Types
9
+
10
+ Avoid `dynamic` type to enable compiler optimizations and catch errors at compile time.
11
+
12
+ **Incorrect (dynamic defeats type checking):**
13
+
14
+ ```dart
15
+ dynamic fetchData() {
16
+ // Caller has no idea what type to expect
17
+ return {'name': 'John', 'age': 30};
18
+ }
19
+
20
+ void processData(dynamic data) {
21
+ // No autocomplete, no type safety
22
+ print(data.name); // Runtime error if wrong type
23
+ print(data.nonExistent); // No compile-time error!
24
+ }
25
+
26
+ List<dynamic> items = [1, 'two', 3.0]; // Mixed types
27
+ ```
28
+
29
+ **Correct (explicit types):**
30
+
31
+ ```dart
32
+ Map<String, dynamic> fetchData() {
33
+ return {'name': 'John', 'age': 30};
34
+ }
35
+
36
+ // Better: Use a typed model
37
+ class User {
38
+ final String name;
39
+ final int age;
40
+
41
+ const User({required this.name, required this.age});
42
+
43
+ factory User.fromJson(Map<String, dynamic> json) {
44
+ return User(
45
+ name: json['name'] as String,
46
+ age: json['age'] as int,
47
+ );
48
+ }
49
+ }
50
+
51
+ User fetchUser() {
52
+ final json = {'name': 'John', 'age': 30};
53
+ return User.fromJson(json);
54
+ }
55
+ ```
56
+
57
+ **For JSON handling:**
58
+
59
+ ```dart
60
+ // Accept dynamic at API boundary, convert immediately
61
+ class ApiService {
62
+ Future<User> getUser(int id) async {
63
+ final response = await http.get('/users/$id');
64
+ final json = jsonDecode(response.body) as Map<String, dynamic>;
65
+ return User.fromJson(json); // Typed from here on
66
+ }
67
+ }
68
+ ```
69
+
70
+ **When dynamic is acceptable:**
71
+ - JSON parsing at boundaries
72
+ - Reflection/mirrors (rare)
73
+ - Interop with JavaScript
74
+
75
+ **Enable strict linting:**
76
+
77
+ ```yaml
78
+ # analysis_options.yaml
79
+ analyzer:
80
+ language:
81
+ strict-casts: true
82
+ strict-raw-types: true
83
+ linter:
84
+ rules:
85
+ - avoid_dynamic_calls
86
+ ```
@@ -0,0 +1,89 @@
1
+ ---
2
+ title: Use Cascade Notation for Multiple Operations
3
+ impact: LOW-MEDIUM
4
+ impactDescription: Cleaner code, fewer intermediate variables
5
+ tags: dart, cascade, notation, chaining
6
+ ---
7
+
8
+ ## Use Cascade Notation for Multiple Operations
9
+
10
+ Use cascade notation (`..`) to perform multiple operations on the same object without repeating the reference.
11
+
12
+ **Incorrect (repeated object reference):**
13
+
14
+ ```dart
15
+ void setupController() {
16
+ final controller = TextEditingController();
17
+ controller.text = 'Initial value';
18
+ controller.selection = TextSelection.collapsed(offset: 0);
19
+ controller.addListener(onChanged);
20
+ return controller;
21
+ }
22
+
23
+ // Or with builder pattern feeling clunky:
24
+ void buildRequest() {
25
+ final request = HttpRequest();
26
+ request.method = 'POST';
27
+ request.headers['Content-Type'] = 'application/json';
28
+ request.body = jsonEncode(data);
29
+ return request.send();
30
+ }
31
+ ```
32
+
33
+ **Correct (cascade notation):**
34
+
35
+ ```dart
36
+ TextEditingController setupController() {
37
+ return TextEditingController()
38
+ ..text = 'Initial value'
39
+ ..selection = const TextSelection.collapsed(offset: 0)
40
+ ..addListener(onChanged);
41
+ }
42
+
43
+ Future<Response> buildRequest() {
44
+ return (HttpRequest()
45
+ ..method = 'POST'
46
+ ..headers['Content-Type'] = 'application/json'
47
+ ..body = jsonEncode(data))
48
+ .send();
49
+ }
50
+ ```
51
+
52
+ **Common use cases:**
53
+
54
+ ```dart
55
+ // Paint configuration
56
+ final paint = Paint()
57
+ ..color = Colors.blue
58
+ ..strokeWidth = 2.0
59
+ ..style = PaintingStyle.stroke
60
+ ..strokeCap = StrokeCap.round;
61
+
62
+ // Path building
63
+ final path = Path()
64
+ ..moveTo(0, 0)
65
+ ..lineTo(100, 0)
66
+ ..lineTo(100, 100)
67
+ ..close();
68
+
69
+ // List population
70
+ final items = <String>[]
71
+ ..add('first')
72
+ ..addAll(['second', 'third'])
73
+ ..sort();
74
+ ```
75
+
76
+ **Null-aware cascade (Dart 2.12+):**
77
+
78
+ ```dart
79
+ // Only cascades if object is not null
80
+ paint
81
+ ?..color = Colors.red
82
+ ..strokeWidth = 3.0;
83
+ ```
84
+
85
+ **Benefits:**
86
+ - Less repetition
87
+ - Cleaner initialization
88
+ - Returns the object (unlike method calls)
89
+ - Works great with builders
@@ -0,0 +1,92 @@
1
+ ---
2
+ title: Use Collection-if Instead of Conditional Logic
3
+ impact: LOW-MEDIUM
4
+ impactDescription: Cleaner, more performant collections
5
+ tags: dart, collection, conditional, syntax
6
+ ---
7
+
8
+ ## Use Collection-if Instead of Conditional Logic
9
+
10
+ Use collection-if and collection-for for cleaner dynamic lists with better performance.
11
+
12
+ **Incorrect (imperative approach):**
13
+
14
+ ```dart
15
+ List<Widget> buildItems(bool showHeader, bool showFooter) {
16
+ var items = <Widget>[];
17
+
18
+ if (showHeader) {
19
+ items.add(HeaderWidget());
20
+ }
21
+
22
+ items.add(MainContent());
23
+
24
+ if (showFooter) {
25
+ items.add(FooterWidget());
26
+ }
27
+
28
+ return items;
29
+ }
30
+ ```
31
+
32
+ **Correct (collection-if):**
33
+
34
+ ```dart
35
+ List<Widget> buildItems(bool showHeader, bool showFooter) {
36
+ return [
37
+ if (showHeader) const HeaderWidget(),
38
+ const MainContent(),
39
+ if (showFooter) const FooterWidget(),
40
+ ];
41
+ }
42
+ ```
43
+
44
+ **In widget trees:**
45
+
46
+ ```dart
47
+ @override
48
+ Widget build(BuildContext context) {
49
+ return Column(
50
+ children: [
51
+ const TitleWidget(),
52
+ if (isLoading) const CircularProgressIndicator(),
53
+ if (hasError) Text('Error: $errorMessage'),
54
+ if (data != null) ...[
55
+ DataHeader(data: data!),
56
+ for (final item in data!.items) ItemWidget(item: item),
57
+ ],
58
+ if (showActions) const ActionButtons(),
59
+ ],
60
+ );
61
+ }
62
+ ```
63
+
64
+ **Collection-for:**
65
+
66
+ ```dart
67
+ // Incorrect
68
+ List<Widget> buildList(List<Item> items) {
69
+ return items.map((item) => ItemWidget(item: item)).toList();
70
+ }
71
+
72
+ // Correct (collection-for)
73
+ List<Widget> buildList(List<Item> items) {
74
+ return [
75
+ for (final item in items) ItemWidget(item: item),
76
+ ];
77
+ }
78
+ ```
79
+
80
+ **Combined usage:**
81
+
82
+ ```dart
83
+ final menu = [
84
+ const MenuItem(title: 'Home'),
85
+ if (isLoggedIn) ...[
86
+ const MenuItem(title: 'Profile'),
87
+ for (final bookmark in bookmarks)
88
+ MenuItem(title: bookmark.name),
89
+ ],
90
+ if (isAdmin) const MenuItem(title: 'Admin'),
91
+ ];
92
+ ```
@@ -0,0 +1,70 @@
1
+ ---
2
+ title: Use final and const Appropriately
3
+ impact: LOW-MEDIUM
4
+ impactDescription: Enables compiler optimizations
5
+ tags: dart, final, const, immutability
6
+ ---
7
+
8
+ ## Use final and const Appropriately
9
+
10
+ Use `final` for runtime constants and `const` for compile-time constants to enable optimizations.
11
+
12
+ **Incorrect (no immutability hints):**
13
+
14
+ ```dart
15
+ class BadExample {
16
+ var name = 'John'; // Mutable - can change
17
+ var items = <String>[]; // Mutable list
18
+ var config = {'key': 'value'}; // Mutable map
19
+
20
+ void process() {
21
+ var result = calculateSomething(); // Not marked final
22
+ print(result);
23
+ // result could accidentally be reassigned
24
+ }
25
+ }
26
+ ```
27
+
28
+ **Correct (proper const/final usage):**
29
+
30
+ ```dart
31
+ class GoodExample {
32
+ final String name = 'John'; // Runtime immutable
33
+ final List<String> items; // Reference immutable
34
+
35
+ // Compile-time constant
36
+ static const defaultConfig = {'key': 'value'};
37
+
38
+ // Const constructor enables const instances
39
+ const GoodExample({required this.items});
40
+
41
+ void process() {
42
+ final result = calculateSomething(); // Cannot reassign
43
+ print(result);
44
+ }
45
+ }
46
+
47
+ // Usage
48
+ const instance = GoodExample(items: ['a', 'b']); // Compile-time constant
49
+ ```
50
+
51
+ **const collections:**
52
+
53
+ ```dart
54
+ // Incorrect - creates new list each time
55
+ Widget build(BuildContext context) {
56
+ return Row(children: [Text('A'), Text('B')]);
57
+ }
58
+
59
+ // Correct - reuses same list
60
+ Widget build(BuildContext context) {
61
+ return const Row(children: [Text('A'), Text('B')]);
62
+ }
63
+ ```
64
+
65
+ **Guidelines:**
66
+ - Use `const` for values known at compile time
67
+ - Use `final` for values computed at runtime but never changed
68
+ - Prefer `const` constructors in widgets
69
+ - Use `const` for default parameter values
70
+ - Enable `prefer_const_declarations` lint
@@ -0,0 +1,90 @@
1
+ ---
2
+ title: Use Spread Operator for Collection Merging
3
+ impact: LOW-MEDIUM
4
+ impactDescription: More efficient collection operations
5
+ tags: dart, spread, collections, merge
6
+ ---
7
+
8
+ ## Use Spread Operator for Collection Merging
9
+
10
+ Use the spread operator (`...`) for efficient collection merging instead of addAll or concatenation.
11
+
12
+ **Incorrect (multiple operations):**
13
+
14
+ ```dart
15
+ List<int> combineNumbers() {
16
+ var result = <int>[];
17
+ result.addAll([1, 2, 3]);
18
+ result.add(4);
19
+ result.addAll([5, 6, 7]);
20
+ return result;
21
+ }
22
+
23
+ // Or inefficient concatenation
24
+ List<int> combineNumbers() {
25
+ return [1, 2, 3] + [4] + [5, 6, 7]; // Creates intermediate lists
26
+ }
27
+ ```
28
+
29
+ **Correct (spread operator):**
30
+
31
+ ```dart
32
+ List<int> combineNumbers() {
33
+ return [...[1, 2, 3], 4, ...[5, 6, 7]];
34
+ }
35
+
36
+ // Or more readable:
37
+ List<int> combineNumbers() {
38
+ const first = [1, 2, 3];
39
+ const last = [5, 6, 7];
40
+ return [...first, 4, ...last];
41
+ }
42
+ ```
43
+
44
+ **Null-aware spread:**
45
+
46
+ ```dart
47
+ List<Widget> buildWidgets(List<Widget>? extraWidgets) {
48
+ return [
49
+ const Header(),
50
+ ...?extraWidgets, // Only spreads if not null
51
+ const Footer(),
52
+ ];
53
+ }
54
+ ```
55
+
56
+ **With maps:**
57
+
58
+ ```dart
59
+ Map<String, dynamic> mergeConfig(Map<String, dynamic> overrides) {
60
+ return {
61
+ 'theme': 'dark',
62
+ 'fontSize': 14,
63
+ ...overrides, // Overrides default values
64
+ };
65
+ }
66
+ ```
67
+
68
+ **In widget builders:**
69
+
70
+ ```dart
71
+ @override
72
+ Widget build(BuildContext context) {
73
+ return Row(
74
+ children: [
75
+ const LeadingIcon(),
76
+ ...items.map((item) => ItemWidget(item: item)),
77
+ if (showTrailing) ...[
78
+ const Spacer(),
79
+ const TrailingIcon(),
80
+ ],
81
+ ],
82
+ );
83
+ }
84
+ ```
85
+
86
+ Benefits:
87
+ - Single list creation
88
+ - More readable
89
+ - Works with const
90
+ - Null-safety with `...?`
@@ -0,0 +1,77 @@
1
+ ---
2
+ title: Use StringBuffer for String Concatenation
3
+ impact: LOW-MEDIUM
4
+ impactDescription: O(n) vs O(n²) for large strings
5
+ tags: dart, string, buffer, performance
6
+ ---
7
+
8
+ ## Use StringBuffer for String Concatenation
9
+
10
+ Use `StringBuffer` for building strings in loops to avoid O(n²) performance.
11
+
12
+ **Incorrect (quadratic time complexity):**
13
+
14
+ ```dart
15
+ String buildHtml(List<Item> items) {
16
+ var html = '<ul>';
17
+ for (final item in items) {
18
+ html += '<li>${item.name}</li>'; // Creates new string each iteration!
19
+ }
20
+ html += '</ul>';
21
+ return html;
22
+ }
23
+ // For 1000 items: ~500,000 character copies
24
+ ```
25
+
26
+ **Correct (linear time complexity):**
27
+
28
+ ```dart
29
+ String buildHtml(List<Item> items) {
30
+ final buffer = StringBuffer('<ul>');
31
+ for (final item in items) {
32
+ buffer.write('<li>${item.name}</li>'); // Efficient append
33
+ }
34
+ buffer.write('</ul>');
35
+ return buffer.toString();
36
+ }
37
+ // For 1000 items: ~10,000 character copies
38
+ ```
39
+
40
+ **Common patterns:**
41
+
42
+ ```dart
43
+ // Building log messages
44
+ String formatLog(List<LogEntry> entries) {
45
+ final buffer = StringBuffer();
46
+ for (final entry in entries) {
47
+ buffer
48
+ ..write('[${entry.timestamp}] ')
49
+ ..write(entry.level.name.toUpperCase())
50
+ ..write(': ')
51
+ ..writeln(entry.message);
52
+ }
53
+ return buffer.toString();
54
+ }
55
+
56
+ // With writeAll for simple cases
57
+ String joinItems(List<String> items) {
58
+ final buffer = StringBuffer();
59
+ buffer.writeAll(items, ', '); // Adds separator
60
+ return buffer.toString();
61
+ }
62
+ ```
63
+
64
+ **When += is fine:**
65
+ - Fixed number of concatenations (not in loop)
66
+ - Small strings
67
+ - Readability matters more than performance
68
+
69
+ ```dart
70
+ // This is fine - constant number of operations
71
+ final message = 'Hello, ' + name + '! Welcome to ' + appName + '.';
72
+
73
+ // Or use interpolation (preferred)
74
+ final message = 'Hello, $name! Welcome to $appName.';
75
+ ```
76
+
77
+ Rule of thumb: Use StringBuffer when concatenating in loops or building strings from many parts.
@@ -0,0 +1,110 @@
1
+ ---
2
+ title: Use AnimatedOpacity Instead of Opacity
3
+ impact: MEDIUM
4
+ impactDescription: Smoother animations, less jank
5
+ tags: layout, opacity, animation, performance
6
+ ---
7
+
8
+ ## Use AnimatedOpacity Instead of Opacity
9
+
10
+ Use `AnimatedOpacity` or `FadeTransition` instead of `Opacity` widget for animated opacity changes.
11
+
12
+ **Incorrect (causes unnecessary repaints):**
13
+
14
+ ```dart
15
+ class BadFade extends StatefulWidget {
16
+ @override
17
+ State<BadFade> createState() => _BadFadeState();
18
+ }
19
+
20
+ class _BadFadeState extends State<BadFade> {
21
+ double _opacity = 1.0;
22
+
23
+ @override
24
+ Widget build(BuildContext context) {
25
+ return Opacity(
26
+ opacity: _opacity,
27
+ child: ExpensiveWidget(),
28
+ );
29
+ }
30
+
31
+ void fadeOut() {
32
+ // Each setState causes full rebuild
33
+ for (var i = 10; i >= 0; i--) {
34
+ Future.delayed(Duration(milliseconds: i * 50), () {
35
+ setState(() => _opacity = i / 10);
36
+ });
37
+ }
38
+ }
39
+ }
40
+ ```
41
+
42
+ **Correct (AnimatedOpacity handles transitions):**
43
+
44
+ ```dart
45
+ class GoodFade extends StatefulWidget {
46
+ const GoodFade({super.key});
47
+
48
+ @override
49
+ State<GoodFade> createState() => _GoodFadeState();
50
+ }
51
+
52
+ class _GoodFadeState extends State<GoodFade> {
53
+ bool _visible = true;
54
+
55
+ @override
56
+ Widget build(BuildContext context) {
57
+ return AnimatedOpacity(
58
+ opacity: _visible ? 1.0 : 0.0,
59
+ duration: const Duration(milliseconds: 300),
60
+ child: const ExpensiveWidget(), // Only built once
61
+ );
62
+ }
63
+
64
+ void toggleVisibility() {
65
+ setState(() => _visible = !_visible);
66
+ // Animation handled internally without extra rebuilds
67
+ }
68
+ }
69
+ ```
70
+
71
+ **With FadeTransition for controller-based animations:**
72
+
73
+ ```dart
74
+ class FadeWidget extends StatefulWidget {
75
+ const FadeWidget({super.key});
76
+
77
+ @override
78
+ State<FadeWidget> createState() => _FadeWidgetState();
79
+ }
80
+
81
+ class _FadeWidgetState extends State<FadeWidget>
82
+ with SingleTickerProviderStateMixin {
83
+ late final AnimationController _controller;
84
+ late final Animation<double> _opacity;
85
+
86
+ @override
87
+ void initState() {
88
+ super.initState();
89
+ _controller = AnimationController(
90
+ duration: const Duration(milliseconds: 300),
91
+ vsync: this,
92
+ );
93
+ _opacity = CurvedAnimation(parent: _controller, curve: Curves.easeIn);
94
+ }
95
+
96
+ @override
97
+ void dispose() {
98
+ _controller.dispose();
99
+ super.dispose();
100
+ }
101
+
102
+ @override
103
+ Widget build(BuildContext context) {
104
+ return FadeTransition(
105
+ opacity: _opacity,
106
+ child: const ExpensiveWidget(),
107
+ );
108
+ }
109
+ }
110
+ ```
@@ -0,0 +1,94 @@
1
+ ---
2
+ title: Set clipBehavior.none When Not Needed
3
+ impact: MEDIUM
4
+ impactDescription: Reduces GPU overdraw
5
+ tags: layout, clip, performance, rendering
6
+ ---
7
+
8
+ ## Set clipBehavior.none When Not Needed
9
+
10
+ Disable clipping on containers and stacks when content doesn't overflow.
11
+
12
+ **Incorrect (unnecessary clipping):**
13
+
14
+ ```dart
15
+ class BadLayout extends StatelessWidget {
16
+ @override
17
+ Widget build(BuildContext context) {
18
+ return Container(
19
+ // Default clipBehavior may clip unnecessarily
20
+ decoration: BoxDecoration(
21
+ color: Colors.white,
22
+ borderRadius: BorderRadius.circular(8),
23
+ ),
24
+ child: Row(
25
+ children: [
26
+ Icon(Icons.star),
27
+ Text('Rating'),
28
+ ],
29
+ ),
30
+ );
31
+ }
32
+ }
33
+ ```
34
+
35
+ **Correct (explicit no clipping):**
36
+
37
+ ```dart
38
+ class GoodLayout extends StatelessWidget {
39
+ const GoodLayout({super.key});
40
+
41
+ @override
42
+ Widget build(BuildContext context) {
43
+ return Container(
44
+ clipBehavior: Clip.none, // Explicit - no clipping needed
45
+ decoration: BoxDecoration(
46
+ color: Colors.white,
47
+ borderRadius: BorderRadius.circular(8),
48
+ ),
49
+ child: const Row(
50
+ children: [
51
+ Icon(Icons.star),
52
+ Text('Rating'),
53
+ ],
54
+ ),
55
+ );
56
+ }
57
+ }
58
+ ```
59
+
60
+ **Stack with overflow:**
61
+
62
+ ```dart
63
+ // When children intentionally overflow
64
+ Stack(
65
+ clipBehavior: Clip.none, // Allow overflow
66
+ children: [
67
+ Container(width: 100, height: 100, color: Colors.blue),
68
+ Positioned(
69
+ top: -20, // Overflows parent - needs Clip.none
70
+ child: Icon(Icons.star),
71
+ ),
72
+ ],
73
+ )
74
+ ```
75
+
76
+ **Clip options:**
77
+
78
+ ```dart
79
+ // Clip.none - No clipping, best performance
80
+ // Clip.hardEdge - Fastest clipping if needed
81
+ // Clip.antiAlias - Smooth edges, slower
82
+ // Clip.antiAliasWithSaveLayer - Smoothest, slowest
83
+
84
+ // For rounded containers that need clipping:
85
+ Container(
86
+ clipBehavior: Clip.hardEdge, // Use simplest clip that works
87
+ decoration: BoxDecoration(
88
+ borderRadius: BorderRadius.circular(8),
89
+ ),
90
+ child: Image.network(url), // Image must be clipped
91
+ )
92
+ ```
93
+
94
+ Use `Clip.none` as default, only enable clipping when content overflows.