Skip to content

Commit 8a6dc47

Browse files
authored
Merge pull request #283 from adil192/feat/fa-icon-finder
feat: support icon finders in tests
2 parents eb50b98 + 90bf43b commit 8a6dc47

File tree

2 files changed

+40
-208
lines changed

2 files changed

+40
-208
lines changed

lib/src/fa_icon.dart

Lines changed: 19 additions & 208 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,12 @@
22
// Use of this source code is governed by a BSD-style license that can be
33
// found in the LICENSE file.
44

5-
import 'package:flutter/foundation.dart';
6-
import 'package:flutter/rendering.dart';
75
import 'package:flutter/widgets.dart';
86

97
/// Creates an Icon Widget that works for non-material Icons, such as the
108
/// Font Awesome Icons.
119
///
12-
/// The default `Icon` Widget from the Material package assumes all Icons are
10+
/// The default [Icon] Widget from the Material package assumes all Icons are
1311
/// square in size and wraps all Icons in a square SizedBox Widget. Icons from
1412
/// the FontAwesome package are often wider than they are tall, which causes
1513
/// alignment and cutoff issues.
@@ -22,191 +20,24 @@ import 'package:flutter/widgets.dart';
2220
///
2321
/// Original source code:
2422
/// https://github.com/flutter/flutter/blob/master/packages/flutter/lib/src/widgets/icon.dart
25-
class FaIcon extends StatelessWidget {
23+
class FaIcon extends Icon {
2624
/// Creates an icon.
2725
const FaIcon(
28-
this.icon, {
29-
super.key,
30-
this.size,
31-
this.fill,
32-
this.weight,
33-
this.grade,
34-
this.opticalSize,
35-
this.color,
36-
this.shadows,
37-
this.semanticLabel,
38-
this.textDirection,
39-
this.applyTextScaling,
40-
this.blendMode,
41-
this.fontWeight,
42-
}) : assert(fill == null || (0.0 <= fill && fill <= 1.0)),
43-
assert(weight == null || (0.0 < weight)),
44-
assert(opticalSize == null || (0.0 < opticalSize));
45-
46-
/// The icon to display. The available icons are described in [Icons].
47-
///
48-
/// The icon can be null, in which case the widget will render as an empty
49-
/// space of the specified [size].
50-
final IconData? icon;
51-
52-
/// The size of the icon in logical pixels.
53-
///
54-
/// Icons occupy a square with width and height equal to size.
55-
///
56-
/// Defaults to the nearest [IconTheme]'s [IconThemeData.size].
57-
///
58-
/// If this [Icon] is being placed inside an [IconButton], then use
59-
/// [IconButton.iconSize] instead, so that the [IconButton] can make the splash
60-
/// area the appropriate size as well. The [IconButton] uses an [IconTheme] to
61-
/// pass down the size to the [Icon].
62-
final double? size;
63-
64-
/// The fill for drawing the icon.
65-
///
66-
/// Requires the underlying icon font to support the `FILL` [FontVariation]
67-
/// axis, otherwise has no effect. Variable font filenames often indicate
68-
/// the supported axes. Must be between 0.0 (unfilled) and 1.0 (filled),
69-
/// inclusive.
70-
///
71-
/// Can be used to convey a state transition for animation or interaction.
72-
///
73-
/// Defaults to nearest [IconTheme]'s [IconThemeData.fill].
74-
///
75-
/// See also:
76-
/// * [weight], for controlling stroke weight.
77-
/// * [grade], for controlling stroke weight in a more granular way.
78-
/// * [opticalSize], for controlling optical size.
79-
final double? fill;
80-
81-
/// The stroke weight for drawing the icon.
82-
///
83-
/// Requires the underlying icon font to support the `wght` [FontVariation]
84-
/// axis, otherwise has no effect. Variable font filenames often indicate
85-
/// the supported axes. Must be greater than 0.
86-
///
87-
/// Defaults to nearest [IconTheme]'s [IconThemeData.weight].
88-
///
89-
/// See also:
90-
/// * [fill], for controlling fill.
91-
/// * [grade], for controlling stroke weight in a more granular way.
92-
/// * [opticalSize], for controlling optical size.
93-
/// * https://fonts.google.com/knowledge/glossary/weight_axis
94-
final double? weight;
95-
96-
/// The grade (granular stroke weight) for drawing the icon.
97-
///
98-
/// Requires the underlying icon font to support the `GRAD` [FontVariation]
99-
/// axis, otherwise has no effect. Variable font filenames often indicate
100-
/// the supported axes. Can be negative.
101-
///
102-
/// Grade and [weight] both affect a symbol's stroke weight (thickness), but
103-
/// grade has a smaller impact on the size of the symbol.
104-
///
105-
/// Grade is also available in some text fonts. One can match grade levels
106-
/// between text and symbols for a harmonious visual effect. For example, if
107-
/// the text font has a -25 grade value, the symbols can match it with a
108-
/// suitable value, say -25.
109-
///
110-
/// Defaults to nearest [IconTheme]'s [IconThemeData.grade].
111-
///
112-
/// See also:
113-
/// * [fill], for controlling fill.
114-
/// * [weight], for controlling stroke weight in a less granular way.
115-
/// * [opticalSize], for controlling optical size.
116-
/// * https://fonts.google.com/knowledge/glossary/grade_axis
117-
final double? grade;
118-
119-
/// The optical size for drawing the icon.
120-
///
121-
/// Requires the underlying icon font to support the `opsz` [FontVariation]
122-
/// axis, otherwise has no effect. Variable font filenames often indicate
123-
/// the supported axes. Must be greater than 0.
124-
///
125-
/// For an icon to look the same at different sizes, the stroke weight
126-
/// (thickness) must change as the icon size scales. Optical size offers a way
127-
/// to automatically adjust the stroke weight as icon size changes.
128-
///
129-
/// Defaults to nearest [IconTheme]'s [IconThemeData.opticalSize].
130-
///
131-
/// See also:
132-
/// * [fill], for controlling fill.
133-
/// * [weight], for controlling stroke weight.
134-
/// * [grade], for controlling stroke weight in a more granular way.
135-
/// * https://fonts.google.com/knowledge/glossary/optical_size_axis
136-
final double? opticalSize;
137-
138-
/// The color to use when drawing the icon.
139-
///
140-
/// Defaults to the nearest [IconTheme]'s [IconThemeData.color].
141-
///
142-
/// The color (whether specified explicitly here or obtained from the
143-
/// [IconTheme]) will be further adjusted by the nearest [IconTheme]'s
144-
/// [IconThemeData.opacity].
145-
///
146-
/// {@tool snippet}
147-
/// Typically, a Material Design color will be used, as follows:
148-
///
149-
/// ```dart
150-
/// Icon(
151-
/// Icons.widgets,
152-
/// color: Colors.blue.shade400,
153-
/// )
154-
/// ```
155-
/// {@end-tool}
156-
final Color? color;
157-
158-
/// A list of [Shadow]s that will be painted underneath the icon.
159-
///
160-
/// Multiple shadows are supported to replicate lighting from multiple light
161-
/// sources.
162-
///
163-
/// Shadows must be in the same order for [Icon] to be considered as
164-
/// equivalent as order produces differing transparency.
165-
///
166-
/// Defaults to the nearest [IconTheme]'s [IconThemeData.shadows].
167-
final List<Shadow>? shadows;
168-
169-
/// Semantic label for the icon.
170-
///
171-
/// Announced by assistive technologies (e.g TalkBack/VoiceOver).
172-
/// This label does not show in the UI.
173-
///
174-
/// * [SemanticsProperties.label], which is set to [semanticLabel] in the
175-
/// underlying [Semantics] widget.
176-
final String? semanticLabel;
177-
178-
/// The text direction to use for rendering the icon.
179-
///
180-
/// If this is null, the ambient [Directionality] is used instead.
181-
///
182-
/// Some icons follow the reading direction. For example, "back" buttons point
183-
/// left in left-to-right environments and right in right-to-left
184-
/// environments. Such icons have their [IconData.matchTextDirection] field
185-
/// set to true, and the [Icon] widget uses the [textDirection] to determine
186-
/// the orientation in which to draw the icon.
187-
///
188-
/// This property has no effect if the [icon]'s [IconData.matchTextDirection]
189-
/// field is false, but for consistency a text direction value must always be
190-
/// specified, either directly using this property or using [Directionality].
191-
final TextDirection? textDirection;
192-
193-
/// Whether to scale the size of this widget using the ambient [MediaQuery]'s [TextScaler].
194-
///
195-
/// This is specially useful when you have an icon associated with a text, as
196-
/// scaling the text without scaling the icon would result in a confusing
197-
/// interface.
198-
///
199-
/// Defaults to the nearest [IconTheme]'s
200-
/// [IconThemeData.applyTextScaling].
201-
final bool? applyTextScaling;
202-
203-
/// The [BlendMode] to apply to the foreground of the icon.
204-
///
205-
/// Defaults to [BlendMode.srcOver]
206-
final BlendMode? blendMode;
207-
208-
/// The typeface thickness to use when painting the text (e.g., bold).
209-
final FontWeight? fontWeight;
26+
super.icon, {
27+
super.key,
28+
super.size,
29+
super.fill,
30+
super.weight,
31+
super.grade,
32+
super.opticalSize,
33+
super.color,
34+
super.shadows,
35+
super.semanticLabel,
36+
super.textDirection,
37+
super.applyTextScaling,
38+
super.blendMode,
39+
super.fontWeight,
40+
});
21041

21142
@override
21243
Widget build(BuildContext context) {
@@ -298,27 +129,7 @@ class FaIcon extends StatelessWidget {
298129

299130
return Semantics(
300131
label: semanticLabel,
301-
child: ExcludeSemantics(
302-
child: iconWidget,
303-
),
304-
);
305-
}
306-
307-
@override
308-
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
309-
super.debugFillProperties(properties);
310-
properties.add(IconDataProperty('icon', icon, ifNull: '<empty>', showName: false));
311-
properties.add(DoubleProperty('size', size, defaultValue: null));
312-
properties.add(DoubleProperty('fill', fill, defaultValue: null));
313-
properties.add(DoubleProperty('weight', weight, defaultValue: null));
314-
properties.add(DoubleProperty('grade', grade, defaultValue: null));
315-
properties.add(DoubleProperty('opticalSize', opticalSize, defaultValue: null));
316-
properties.add(ColorProperty('color', color, defaultValue: null));
317-
properties.add(IterableProperty<Shadow>('shadows', shadows, defaultValue: null));
318-
properties.add(StringProperty('semanticLabel', semanticLabel, defaultValue: null));
319-
properties.add(EnumProperty<TextDirection>('textDirection', textDirection, defaultValue: null));
320-
properties.add(
321-
DiagnosticsProperty<bool>('applyTextScaling', applyTextScaling, defaultValue: null),
132+
child: ExcludeSemantics(child: iconWidget),
322133
);
323134
}
324-
}
135+
}

test/fa_finder_test.dart

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import 'package:flutter/widgets.dart';
2+
import 'package:flutter_test/flutter_test.dart';
3+
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
4+
5+
void main() {
6+
const bullseye = FontAwesomeIcons.bullseye;
7+
8+
testWidgets('find.byIcon', (WidgetTester tester) async {
9+
await tester.pumpWidget(
10+
Directionality(textDirection: TextDirection.ltr, child: FaIcon(bullseye)),
11+
);
12+
expect(find.byIcon(bullseye), findsOneWidget);
13+
});
14+
15+
testWidgets('find.widgetWithIcon', (WidgetTester tester) async {
16+
await tester.pumpWidget(
17+
Directionality(textDirection: TextDirection.ltr, child: FaIcon(bullseye)),
18+
);
19+
expect(find.widgetWithIcon(Directionality, bullseye), findsOneWidget);
20+
});
21+
}

0 commit comments

Comments
 (0)