2
2
// Use of this source code is governed by a BSD-style license that can be
3
3
// found in the LICENSE file.
4
4
5
+ import 'dart:ui' ;
6
+
5
7
import 'package:flutter/foundation.dart' ;
6
8
import 'package:flutter/rendering.dart' ;
7
9
@@ -61,22 +63,26 @@ import 'icon_theme_data.dart';
61
63
/// See also:
62
64
///
63
65
/// * [IconButton] , for interactive icons.
64
- /// * [Icons] , the library of Material Icons available for use with this class.
66
+ /// * [Icons] , for the list of available Material Icons for use with this class.
65
67
/// * [IconTheme] , which provides ambient configuration for icons.
66
68
/// * [ImageIcon] , for showing icons from [AssetImage] s or other [ImageProvider] s.
67
69
class Icon extends StatelessWidget {
68
70
/// Creates an icon.
69
- ///
70
- /// The [size] and [color] default to the value given by the current [IconTheme] .
71
71
const Icon (
72
72
this .icon, {
73
73
super .key,
74
74
this .size,
75
+ this .fill,
76
+ this .weight,
77
+ this .grade,
78
+ this .opticalSize,
75
79
this .color,
80
+ this .shadows,
76
81
this .semanticLabel,
77
82
this .textDirection,
78
- this .shadows,
79
- });
83
+ }) : assert (fill == null || (0.0 <= fill && fill <= 1.0 )),
84
+ assert (weight == null || (0.0 < weight)),
85
+ assert (opticalSize == null || (0.0 < opticalSize));
80
86
81
87
/// The icon to display. The available icons are described in [Icons] .
82
88
///
@@ -88,33 +94,95 @@ class Icon extends StatelessWidget {
88
94
///
89
95
/// Icons occupy a square with width and height equal to size.
90
96
///
91
- /// Defaults to the current [IconTheme] size, if any. If there is no
92
- /// [IconTheme] , or it does not specify an explicit size, then it defaults to
93
- /// 24.0.
97
+ /// Defaults to the nearest [IconTheme] 's [IconThemeData.size] .
94
98
///
95
99
/// If this [Icon] is being placed inside an [IconButton] , then use
96
100
/// [IconButton.iconSize] instead, so that the [IconButton] can make the splash
97
101
/// area the appropriate size as well. The [IconButton] uses an [IconTheme] to
98
102
/// pass down the size to the [Icon] .
99
103
final double ? size;
100
104
101
- /// The color to use when drawing the icon.
105
+ /// The fill for drawing the icon.
102
106
///
103
- /// Defaults to the current [IconTheme] color, if any.
107
+ /// Requires the underlying icon font to support the `FILL` [FontVariation]
108
+ /// axis, otherwise has no effect. Variable font filenames often indicate
109
+ /// the supported axes. Must be between 0.0 (unfilled) and 1.0 (filled),
110
+ /// inclusive.
104
111
///
105
- /// The color (whether specified explicitly here or obtained from the
106
- /// [IconTheme] ) will be further adjusted by the opacity of the current
107
- /// [IconTheme] , if any.
112
+ /// Can be used to convey a state transition for animation or interaction.
113
+ ///
114
+ /// Defaults to nearest [IconTheme] 's [IconThemeData.fill] .
115
+ ///
116
+ /// See also:
117
+ /// * [weight] , for controlling stroke weight.
118
+ /// * [grade] , for controlling stroke weight in a more granular way.
119
+ /// * [opticalSize] , for controlling optical size.
120
+ final double ? fill;
121
+
122
+ /// The stroke weight for drawing the icon.
123
+ ///
124
+ /// Requires the underlying icon font to support the `wght` [FontVariation]
125
+ /// axis, otherwise has no effect. Variable font filenames often indicate
126
+ /// the supported axes. Must be greater than 0.
127
+ ///
128
+ /// Defaults to nearest [IconTheme] 's [IconThemeData.weight] .
129
+ ///
130
+ /// See also:
131
+ /// * [fill] , for controlling fill.
132
+ /// * [grade] , for controlling stroke weight in a more granular way.
133
+ /// * [opticalSize] , for controlling optical size.
134
+ /// * https://fonts.google.com/knowledge/glossary/weight_axis
135
+ final double ? weight;
136
+
137
+ /// The grade (granular stroke weight) for drawing the icon.
138
+ ///
139
+ /// Requires the underlying icon font to support the `GRAD` [FontVariation]
140
+ /// axis, otherwise has no effect. Variable font filenames often indicate
141
+ /// the supported axes. Can be negative.
142
+ ///
143
+ /// Grade and [weight] both affect a symbol's stroke weight (thickness), but
144
+ /// grade has a smaller impact on the size of the symbol.
145
+ ///
146
+ /// Grade is also available in some text fonts. One can match grade levels
147
+ /// between text and symbols for a harmonious visual effect. For example, if
148
+ /// the text font has a -25 grade value, the symbols can match it with a
149
+ /// suitable value, say -25.
150
+ ///
151
+ /// Defaults to nearest [IconTheme] 's [IconThemeData.grade] .
152
+ ///
153
+ /// See also:
154
+ /// * [fill] , for controlling fill.
155
+ /// * [weight] , for controlling stroke weight in a less granular way.
156
+ /// * [opticalSize] , for controlling optical size.
157
+ /// * https://fonts.google.com/knowledge/glossary/grade_axis
158
+ final double ? grade;
159
+
160
+ /// The optical size for drawing the icon.
161
+ ///
162
+ /// Requires the underlying icon font to support the `opsz` [FontVariation]
163
+ /// axis, otherwise has no effect. Variable font filenames often indicate
164
+ /// the supported axes. Must be greater than 0.
165
+ ///
166
+ /// For an icon to look the same at different sizes, the stroke weight
167
+ /// (thickness) must change as the icon size scales. Optical size offers a way
168
+ /// to automatically adjust the stroke weight as icon size changes.
169
+ ///
170
+ /// Defaults to nearest [IconTheme] 's [IconThemeData.opticalSize] .
108
171
///
109
- /// In material apps, if there is a [Theme] without any [IconTheme] s
110
- /// specified, icon colors default to white if the theme is dark
111
- /// and black if the theme is light.
172
+ /// See also:
173
+ /// * [fill] , for controlling fill.
174
+ /// * [weight] , for controlling stroke weight.
175
+ /// * [grade] , for controlling stroke weight in a more granular way.
176
+ /// * https://fonts.google.com/knowledge/glossary/optical_size_axis
177
+ final double ? opticalSize;
178
+
179
+ /// The color to use when drawing the icon.
112
180
///
113
- /// If no [IconTheme] and no [Theme] is specified, icons will default to
114
- /// black.
181
+ /// Defaults to the nearest [IconTheme] 's [IconThemeData.color] .
115
182
///
116
- /// See [Theme] to set the current theme and [ThemeData.brightness]
117
- /// for setting the current theme's brightness.
183
+ /// The color (whether specified explicitly here or obtained from the
184
+ /// [IconTheme] ) will be further adjusted by the nearest [IconTheme] 's
185
+ /// [IconThemeData.opacity] .
118
186
///
119
187
/// {@tool snippet}
120
188
/// Typically, a Material Design color will be used, as follows:
@@ -128,6 +196,17 @@ class Icon extends StatelessWidget {
128
196
/// {@end-tool}
129
197
final Color ? color;
130
198
199
+ /// A list of [Shadow] s that will be painted underneath the icon.
200
+ ///
201
+ /// Multiple shadows are supported to replicate lighting from multiple light
202
+ /// sources.
203
+ ///
204
+ /// Shadows must be in the same order for [Icon] to be considered as
205
+ /// equivalent as order produces differing transparency.
206
+ ///
207
+ /// Defaults to the nearest [IconTheme] 's [IconThemeData.shadows] .
208
+ final List <Shadow >? shadows;
209
+
131
210
/// Semantic label for the icon.
132
211
///
133
212
/// Announced in accessibility modes (e.g TalkBack/VoiceOver).
@@ -152,15 +231,6 @@ class Icon extends StatelessWidget {
152
231
/// specified, either directly using this property or using [Directionality] .
153
232
final TextDirection ? textDirection;
154
233
155
- /// A list of [Shadow] s that will be painted underneath the icon.
156
- ///
157
- /// Multiple shadows are supported to replicate lighting from multiple light
158
- /// sources.
159
- ///
160
- /// Shadows must be in the same order for [Icon] to be considered as
161
- /// equivalent as order produces differing transparency.
162
- final List <Shadow >? shadows;
163
-
164
234
@override
165
235
Widget build (BuildContext context) {
166
236
assert (this .textDirection != null || debugCheckHasDirectionality (context));
@@ -191,6 +261,12 @@ class Icon extends StatelessWidget {
191
261
text: TextSpan (
192
262
text: String .fromCharCode (icon! .codePoint),
193
263
style: TextStyle (
264
+ fontVariations: < FontVariation > [
265
+ if (fill != null ) FontVariation ('FILL' , fill! ),
266
+ if (weight != null ) FontVariation ('wght' , weight! ),
267
+ if (grade != null ) FontVariation ('GRAD' , grade! ),
268
+ if (opticalSize != null ) FontVariation ('opsz' , opticalSize! ),
269
+ ],
194
270
inherit: false ,
195
271
color: iconColor,
196
272
fontSize: iconSize,
@@ -235,7 +311,13 @@ class Icon extends StatelessWidget {
235
311
super .debugFillProperties (properties);
236
312
properties.add (IconDataProperty ('icon' , icon, ifNull: '<empty>' , showName: false ));
237
313
properties.add (DoubleProperty ('size' , size, defaultValue: null ));
314
+ properties.add (DoubleProperty ('fill' , fill, defaultValue: null ));
315
+ properties.add (DoubleProperty ('weight' , weight, defaultValue: null ));
316
+ properties.add (DoubleProperty ('grade' , grade, defaultValue: null ));
317
+ properties.add (DoubleProperty ('opticalSize' , opticalSize, defaultValue: null ));
238
318
properties.add (ColorProperty ('color' , color, defaultValue: null ));
239
319
properties.add (IterableProperty <Shadow >('shadows' , shadows, defaultValue: null ));
320
+ properties.add (StringProperty ('semanticLabel' , semanticLabel, defaultValue: null ));
321
+ properties.add (EnumProperty <TextDirection >('textDirection' , textDirection, defaultValue: null ));
240
322
}
241
323
}
0 commit comments