blob: d27ccf475bb2cf992a978b2de061522e59264ed6 [file] [log] [blame]
// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'package:flutter/foundation.dart';
import 'basic.dart';
import 'framework.dart';
import 'icon_theme_data.dart';
import 'inherited_theme.dart';
// Examples can assume:
// late BuildContext context;
/// Controls the default properties of icons in a widget subtree.
/// The icon theme is honored by [Icon] and [ImageIcon] widgets.
class IconTheme extends InheritedTheme {
/// Creates an icon theme that controls properties of descendant widgets.
/// Both [data] and [child] arguments must not be null.
const IconTheme({
required super.child,
/// Creates an icon theme that controls the properties of
/// descendant widgets, and merges in the current icon theme, if any.
/// The [data] and [child] arguments must not be null.
static Widget merge({
Key? key,
required IconThemeData data,
required Widget child,
}) {
return Builder(
builder: (BuildContext context) {
return IconTheme(
key: key,
data: _getInheritedIconThemeData(context).merge(data),
child: child,
/// The set of properties to use for icons in this subtree.
final IconThemeData data;
/// The data from the closest instance of this class that encloses the given
/// context, if any.
/// If there is no ambient icon theme, defaults to [IconThemeData.fallback].
/// The returned [IconThemeData] is concrete (all values are non-null; see
/// [IconThemeData.isConcrete]). Any properties on the ambient icon theme that
/// are null get defaulted to the values specified on
/// [IconThemeData.fallback].
/// The [Theme] widget from the `material` library introduces an [IconTheme]
/// widget set to the [ThemeData.iconTheme], so in a Material Design
/// application, this will typically default to the icon theme from the
/// ambient [Theme].
/// Typical usage is as follows:
/// ```dart
/// IconThemeData theme = IconTheme.of(context);
/// ```
static IconThemeData of(BuildContext context) {
final IconThemeData iconThemeData = _getInheritedIconThemeData(context).resolve(context);
return iconThemeData.isConcrete
? iconThemeData
: iconThemeData.copyWith(
size: iconThemeData.size ?? const IconThemeData.fallback().size,
fill: iconThemeData.fill ?? const IconThemeData.fallback().fill,
weight: iconThemeData.weight ?? const IconThemeData.fallback().weight,
grade: iconThemeData.grade ?? const IconThemeData.fallback().grade,
opticalSize: iconThemeData.opticalSize ?? const IconThemeData.fallback().opticalSize,
color: iconThemeData.color ?? const IconThemeData.fallback().color,
opacity: iconThemeData.opacity ?? const IconThemeData.fallback().opacity,
shadows: iconThemeData.shadows ?? const IconThemeData.fallback().shadows,
static IconThemeData _getInheritedIconThemeData(BuildContext context) {
final IconTheme? iconTheme = context.dependOnInheritedWidgetOfExactType<IconTheme>();
return iconTheme?.data ?? const IconThemeData.fallback();
bool updateShouldNotify(IconTheme oldWidget) => data !=;
Widget wrap(BuildContext context, Widget child) {
return IconTheme(data: data, child: child);
void debugFillProperties(DiagnosticPropertiesBuilder properties) {