chipTheme static method

ChipThemeData chipTheme({
  1. required ColorScheme colorScheme,
  2. SchemeColor? selectedSchemeColor,
  3. SchemeColor? baseSchemeColor,
  4. SchemeColor? deleteIconSchemeColor,
  5. required TextStyle labelStyle,
  6. TextStyle? secondaryLabelStyle,
  7. double? radius,
  8. Color? surfaceTintColor,
  9. bool? useTintedDisable,
  10. bool? useMaterial3,
})

An opinionated ChipThemeData theme with custom border radius and a custom theme that partially mimics the M3 style in M2 and works well with FlexColorScheme surface blends.

The border radius defaults to 8dp kChipRadius, new M3 default. https://m3.material.io/components/chips/specs

Implementation

static ChipThemeData chipTheme({
  /// Typically the same [ColorScheme] that is also use for your [ThemeData].
  required final ColorScheme colorScheme,

  /// Defines which [Theme] based [ColorScheme] based color the selected Chips
  /// use as their selected state color.
  ///
  /// The color scheme contrast pair color is used for text and icons, on the
  /// [selectedSchemeColor]
  ///
  /// If not defined and [useMaterial3] is true, defaults to
  /// [SchemeColor.secondaryContainer].
  final SchemeColor? selectedSchemeColor,

  /// Defines which [Theme] based [ColorScheme] based color the Chips
  /// use as their color tint base color.
  ///
  /// The selected color is only used as base for the [Chip] colors, it also
  /// uses alpha blend and opacity to create the effective Chip colors using
  /// the selected scheme color as base.
  ///
  /// If not defined it defaults to effective theme based color from using
  /// [SchemeColor.primary], when [useMaterial3] is false.
  ///
  /// If [useMaterial3] is true, using a null [chipSchemeColor] will
  /// result in M3 default Chip coloring being used without opacity and alpha
  /// blends. To get the same coloring for M3 as when [useMaterial3] is false,
  /// pass in [SchemeColor.primary].
  final SchemeColor? baseSchemeColor,

  /// Defines which [Theme] based [ColorScheme] based color the Chips
  /// use as color of the delete icon.
  ///
  /// The selected color is only used as base for the [Chip] colors, it also
  /// uses alpha blend and opacity to create the effective Chip colors using
  /// the selected scheme color as base.
  ///
  /// If not defined it defaults to effective theme based color from using
  /// [SchemeColor.onSurface].
  final SchemeColor? deleteIconSchemeColor,

  /// Overrides the default for [ChipAttributes.labelStyle],
  /// the style of the [DefaultTextStyle] that contains the
  /// chip's label.
  ///
  /// This only has an effect on label widgets that respect the
  /// [DefaultTextStyle], such as [Text].
  ///
  /// This property applies to [ActionChip], [Chip],
  /// [FilterChip], [InputChip], [RawChip].
  required final TextStyle labelStyle,

  /// Overrides the default for [ChoiceChip.labelStyle],
  /// the style of the [DefaultTextStyle] that contains the
  /// chip's label.
  ///
  /// This only has an effect on label widgets that respect the
  /// [DefaultTextStyle], such as [Text].
  final TextStyle? secondaryLabelStyle,

  /// Corner radius of the Chip.
  ///
  /// If not defined, defaults to [kChipRadius] 8dp,
  /// based on M3 Specification
  /// https://m3.material.io/components/chips/specs
  final double? radius,

  /// Overrides the default for [ChipAttributes.surfaceTintColor], the
  /// Color of the chip's surface tint overlay when its elevation is
  /// greater than 0.
  ///
  /// This property applies to [ActionChip], [Chip], [ChoiceChip],
  /// [FilterChip], [InputChip], [RawChip].
  final Color? surfaceTintColor,

  /// Defines if the theme uses tinted disabled color.
  ///
  /// If undefined, defaults to false.
  final bool? useTintedDisable,

  /// A temporary flag used to opt-in to Material 3 features.
  ///
  /// If set to true, the theme will use Material3 default styles when
  /// properties are undefined, if false defaults will use FlexColorScheme's
  /// own opinionated default values.
  ///
  /// The M2/M3 defaults will only be used for properties that are not
  /// defined, if defined they keep their defined values.
  ///
  /// If undefined, defaults to false.
  final bool? useMaterial3,
}) {
  // Used to toggle between different defaults from M2 and M3.
  final bool useM3 = useMaterial3 ?? false;
  final bool tintDisable = useTintedDisable ?? false;

  // Function used to increase icon color for selections resulting in poor
  // icon color.
  Color fixContrast(Color color) {
    if (colorScheme.brightness == Brightness.light) {
      if (ThemeData.estimateBrightnessForColor(color) == Brightness.light) {
        return color.darken(25);
      } else {
        return color;
      }
    } else {
      if (ThemeData.estimateBrightnessForColor(color) == Brightness.dark) {
        return color.lighten(25);
      } else {
        return color;
      }
    }
  }

  // TODO(rydmike): Monitor Chip issue #115364
  // https://github.com/flutter/flutter/issues/115364
  //
  // Flag for not using any defined color values in M3 mode, but instead
  // falling back to M3 theme defaults, when using Material 3.
  // We do this when no Scheme colors are selected to get the exact M3
  // theme default. It is not possible due to SDK Chip theming issues
  // and limitations to recreate the exact M3 Chip themes with any other
  // theme colors than the default built-in ones.
  final bool useM3Defaults =
      useM3 && baseSchemeColor == null && selectedSchemeColor == null;

  // Get blend color, defaults to surface for M3 and to primary for M2.
  final SchemeColor fallbackBlend =
      useM3 ? SchemeColor.surface : SchemeColor.primary;
  final Color blendColor =
      schemeColor(baseSchemeColor ?? fallbackBlend, colorScheme);

  // Selected color
  final SchemeColor fallbackSelected =
      useM3 ? SchemeColor.secondaryContainer : SchemeColor.surface;
  final Color selectedColor = useM3 || selectedSchemeColor != null
      ? schemeColor(selectedSchemeColor ?? fallbackSelected, colorScheme)
      : blendColor.blendAlpha(
          colorScheme.surface, kChipSelectedBackgroundAlphaBlend);
  // The onSelected onColor
  final Color onSelectedColor =
      schemeColorPair(selectedSchemeColor ?? fallbackSelected, colorScheme);

  // The onSelected onColor
  final Color deleteIconColor = schemeColor(
      deleteIconSchemeColor ?? SchemeColor.onSurface, colorScheme);

  // Using these tinted overlay variable in all themes for ease of
  // reasoning and duplication.
  final Color tint = selectedColor;

  // Icon color.
  final Color iconColor;
  if (blendColor == colorScheme.surface ||
      blendColor == colorScheme.background) {
    iconColor = selectedColor;
  } else {
    iconColor = blendColor;
  }
  // Text color, uses the foreground color for all chip styles.
  final TextStyle effectiveLabelStyle =
      labelStyle.copyWith(color: colorScheme.onSurface);

  // Text color, uses the foreground color for all chip styles.
  final TextStyle effectiveSelectedLabelStyle =
      labelStyle.copyWith(color: onSelectedColor);

  return ChipThemeData(
    // Applies to [ActionChip], [Chip], [ChoiceChip], [FilterChip],
    // [InputChip], [RawChip], but NOT to ANY selected or disabled Chip.
    backgroundColor: useM3Defaults
        ? null
        : blendColor.blendAlpha(
            colorScheme.surface, kChipBackgroundAlphaBlend),

    // Applies to [Chip], [InputChip], [RawChip].
    deleteIconColor: useM3Defaults && deleteIconSchemeColor == null
        ? null
        : deleteIconColor,

    // Applies to [ChoiceChip], [FilterChip], [InputChip], [RawChip].
    // Same formula as on FCS Elevated button and ToggleButtons.
    disabledColor: useM3Defaults && !tintDisable
        ? null
        : tintDisable
            ? tintedDisable(colorScheme.onSurface, tint)
                .withAlpha(kAlphaVeryLowDisabled)
            : colorScheme.onSurface.withAlpha(kAlphaVeryLowDisabled),

    // Applies to [ChoiceChip], [FilterChip], [InputChip], [RawChip].
    selectedColor: useM3Defaults ? null : selectedColor,

    // Applies to [ChoiceChip.selectedColor], if set it overrides the
    // [selectedColor], for ChoiceChips.
    secondarySelectedColor: useM3Defaults ? null : selectedColor,

    // Applies to [ActionChip], [Chip], [ChoiceChip], [FilterChip],
    // [InputChip] and [RawChip].
    surfaceTintColor:
        useM3Defaults ? surfaceTintColor : colorScheme.surfaceTint,

    // Applies to [FilterChip], [InputChip], [RawChip].
    checkmarkColor: onSelectedColor,

    // Applies to [ActionChip], [Chip], [ChoiceChip], [FilterChip],
    // [InputChip] and [RawChip].
    padding: useM3 ? null : const EdgeInsets.all(4),

    // Applies to [ActionChip], [Chip], [ChoiceChip], [FilterChip],
    // [InputChip] and [RawChip].
    shape: useM3 && radius == null
        ? null
        : RoundedRectangleBorder(
            borderRadius: BorderRadius.all(
              Radius.circular(radius ?? kChipRadius),
            ),
          ),

    // Applies to [ActionChip], [Chip], [FilterChip], [InputChip], [RawChip].
    labelStyle: useM3Defaults ? null : effectiveLabelStyle,

    // Applies to [ChoiceChip.labelStyle],
    secondaryLabelStyle: useM3Defaults ? null : effectiveSelectedLabelStyle,

    // Applies to [ActionChip], [Chip], [ChoiceChip], [FilterChip],
    // [InputChip] and [RawChip].
    iconTheme: useM3Defaults
        ? null
        : IconThemeData(
            color: fixContrast(iconColor),
            size: 18.0,
          ),
  );
}