Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions packages/material_ui/lib/src/app_bar.dart
Original file line number Diff line number Diff line change
Expand Up @@ -906,6 +906,8 @@ class _AppBarState extends State<AppBar> {
final ThemeData theme = Theme.of(context);
final IconButtonThemeData iconButtonTheme = IconButtonTheme.of(context);
final AppBarThemeData appBarTheme = AppBarTheme.of(context);
final StyleVariant effectiveVariant = appBarTheme.variant ?? theme.variant;
assert(effectiveVariant != .material3Expressive, kUnsupportedStyleVariantAssertionMessage);
final AppBarThemeData defaults = theme.useMaterial3
? _AppBarDefaultsM3(context)
: _AppBarDefaultsM2(context);
Expand Down
16 changes: 14 additions & 2 deletions packages/material_ui/lib/src/app_bar_theme.dart
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import 'package:flutter/foundation.dart';
import 'package:flutter/services.dart';
import 'package:flutter/widgets.dart';

import 'debug.dart';
import 'theme.dart';

// Examples can assume:
Expand Down Expand Up @@ -410,10 +411,12 @@ class AppBarThemeData with Diagnosticable {
this.titleTextStyle,
this.systemOverlayStyle,
this.actionsPadding,
this.variant,
}) : assert(
color == null || backgroundColor == null,
'The color and backgroundColor parameters mean the same thing. Only specify one.',
);
),
assert(variant != .material3Expressive, kUnsupportedStyleVariantAssertionMessage);

/// Overrides the default value of [AppBar.backgroundColor].
final Color? backgroundColor;
Expand Down Expand Up @@ -466,6 +469,9 @@ class AppBarThemeData with Diagnosticable {
/// Overrides the default value of [AppBar.actionsPadding].
final EdgeInsetsGeometry? actionsPadding;

/// The style variant of Material Design used by [AppBar].
final StyleVariant? variant;

/// Creates a copy of this object but with the given fields replaced with the
/// new values.
AppBarThemeData copyWith({
Expand All @@ -491,6 +497,7 @@ class AppBarThemeData with Diagnosticable {
TextStyle? titleTextStyle,
SystemUiOverlayStyle? systemOverlayStyle,
EdgeInsetsGeometry? actionsPadding,
StyleVariant? variant,
}) {
return AppBarThemeData(
backgroundColor: backgroundColor ?? color ?? this.backgroundColor,
Expand All @@ -510,6 +517,7 @@ class AppBarThemeData with Diagnosticable {
titleTextStyle: titleTextStyle ?? this.titleTextStyle,
systemOverlayStyle: systemOverlayStyle ?? this.systemOverlayStyle,
actionsPadding: actionsPadding ?? this.actionsPadding,
variant: variant ?? this.variant,
);
}

Expand Down Expand Up @@ -538,6 +546,7 @@ class AppBarThemeData with Diagnosticable {
titleTextStyle: TextStyle.lerp(a.titleTextStyle, b.titleTextStyle, t),
systemOverlayStyle: t < 0.5 ? a.systemOverlayStyle : b.systemOverlayStyle,
actionsPadding: EdgeInsetsGeometry.lerp(a.actionsPadding, b.actionsPadding, t),
variant: t < 0.5 ? a.variant : b.variant,
);
}

Expand All @@ -560,6 +569,7 @@ class AppBarThemeData with Diagnosticable {
titleTextStyle,
systemOverlayStyle,
actionsPadding,
variant,
);

@override
Expand Down Expand Up @@ -587,7 +597,8 @@ class AppBarThemeData with Diagnosticable {
other.toolbarTextStyle == toolbarTextStyle &&
other.titleTextStyle == titleTextStyle &&
other.systemOverlayStyle == systemOverlayStyle &&
other.actionsPadding == actionsPadding;
other.actionsPadding == actionsPadding &&
other.variant == variant;
}

@override
Expand Down Expand Up @@ -633,5 +644,6 @@ class AppBarThemeData with Diagnosticable {
defaultValue: null,
),
);
properties.add(EnumProperty<StyleVariant>('variant', variant, defaultValue: null));
}
}
58 changes: 57 additions & 1 deletion packages/material_ui/lib/src/button_style.dart
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,38 @@ import 'theme_data.dart';
// late BuildContext context;
// typedef MyAppHome = Placeholder;

/// Defines size variants for Material 3 Expressive button components.
///
/// Components interpret each size variant according to their own token set.
enum ButtonSize {
/// Extra small button size.
xSmall,

/// Small button size. This is the default for icon buttons.
small,

/// Medium button size.
medium,

/// Large button size.
large,

/// Extra large button size.
xLarge,
}

/// Defines the width variants for Material 3 Expressive [IconButton].
enum IconButtonWidth {
/// Uses the narrow leading and trailing space tokens.
narrow,

/// Uses the default leading and trailing space tokens.
standard,

/// Uses the wide leading and trailing space tokens.
wide,
}

/// The type for [ButtonStyle.backgroundBuilder] and [ButtonStyle.foregroundBuilder].
///
/// The [states] parameter is the button's current pressed/hovered/etc state. The [child] is
Expand Down Expand Up @@ -187,6 +219,8 @@ class ButtonStyle with Diagnosticable {
this.splashFactory,
this.backgroundBuilder,
this.foregroundBuilder,
this.size,
this.iconButtonWidth,
});

/// The style for a button's [Text] widget descendants.
Expand Down Expand Up @@ -423,6 +457,12 @@ class ButtonStyle with Diagnosticable {
/// configuring clipping.
final ButtonLayerBuilder? foregroundBuilder;

/// The size variant for this button.
final ButtonSize? size;

/// The width variant for this icon button.
final IconButtonWidth? iconButtonWidth;

/// Returns a copy of this ButtonStyle with the given fields replaced with
/// the new values.
ButtonStyle copyWith({
Expand Down Expand Up @@ -451,6 +491,8 @@ class ButtonStyle with Diagnosticable {
InteractiveInkFeatureFactory? splashFactory,
ButtonLayerBuilder? backgroundBuilder,
ButtonLayerBuilder? foregroundBuilder,
ButtonSize? size,
IconButtonWidth? iconButtonWidth,
}) {
return ButtonStyle(
textStyle: textStyle ?? this.textStyle,
Expand Down Expand Up @@ -478,6 +520,8 @@ class ButtonStyle with Diagnosticable {
splashFactory: splashFactory ?? this.splashFactory,
backgroundBuilder: backgroundBuilder ?? this.backgroundBuilder,
foregroundBuilder: foregroundBuilder ?? this.foregroundBuilder,
size: size ?? this.size,
iconButtonWidth: iconButtonWidth ?? this.iconButtonWidth,
);
}

Expand Down Expand Up @@ -516,6 +560,8 @@ class ButtonStyle with Diagnosticable {
splashFactory: splashFactory ?? style.splashFactory,
backgroundBuilder: backgroundBuilder ?? style.backgroundBuilder,
foregroundBuilder: foregroundBuilder ?? style.foregroundBuilder,
size: size ?? style.size,
iconButtonWidth: iconButtonWidth ?? style.iconButtonWidth,
);
}

Expand Down Expand Up @@ -547,6 +593,8 @@ class ButtonStyle with Diagnosticable {
splashFactory,
backgroundBuilder,
foregroundBuilder,
size,
iconButtonWidth,
];
return Object.hashAll(values);
}
Expand Down Expand Up @@ -584,7 +632,9 @@ class ButtonStyle with Diagnosticable {
other.alignment == alignment &&
other.splashFactory == splashFactory &&
other.backgroundBuilder == backgroundBuilder &&
other.foregroundBuilder == foregroundBuilder;
other.foregroundBuilder == foregroundBuilder &&
other.size == size &&
other.iconButtonWidth == iconButtonWidth;
}

@override
Expand Down Expand Up @@ -706,6 +756,10 @@ class ButtonStyle with Diagnosticable {
defaultValue: null,
),
);
properties.add(EnumProperty<ButtonSize>('size', size, defaultValue: null));
properties.add(
EnumProperty<IconButtonWidth>('iconButtonWidth', iconButtonWidth, defaultValue: null),
);
}

/// Linearly interpolate between two [ButtonStyle]s.
Expand Down Expand Up @@ -769,6 +823,8 @@ class ButtonStyle with Diagnosticable {
splashFactory: t < 0.5 ? a?.splashFactory : b?.splashFactory,
backgroundBuilder: t < 0.5 ? a?.backgroundBuilder : b?.backgroundBuilder,
foregroundBuilder: t < 0.5 ? a?.foregroundBuilder : b?.foregroundBuilder,
size: t < 0.5 ? a?.size : b?.size,
iconButtonWidth: t < 0.5 ? a?.iconButtonWidth : b?.iconButtonWidth,
);
}
}
5 changes: 5 additions & 0 deletions packages/material_ui/lib/src/debug.dart
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@ import 'scaffold.dart' show Scaffold, ScaffoldMessenger;
// Examples can assume:
// late BuildContext context;

/// The assertion message used while Material components do not yet support
/// Material 3 Expressive.
const String kUnsupportedStyleVariantAssertionMessage =
'Only material3 is supported. See https://github.com/orgs/flutter/projects/250 to track support for material3Expressive.';

/// Asserts that the given context has a [Material] ancestor within the closest
/// [LookupBoundary].
///
Expand Down
3 changes: 3 additions & 0 deletions packages/material_ui/lib/src/elevated_button.dart
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import 'button_style_button.dart';
import 'color_scheme.dart';
import 'colors.dart';
import 'constants.dart';
import 'debug.dart';
import 'elevated_button_theme.dart';
import 'ink_ripple.dart';
import 'ink_well.dart';
Expand Down Expand Up @@ -392,6 +393,8 @@ class ElevatedButton extends ButtonStyleButton {
@override
ButtonStyle defaultStyleOf(BuildContext context) {
final ThemeData theme = Theme.of(context);
final StyleVariant effectiveVariant = ElevatedButtonTheme.of(context).variant ?? theme.variant;
assert(effectiveVariant != .material3Expressive, kUnsupportedStyleVariantAssertionMessage);
final ColorScheme colorScheme = theme.colorScheme;
final ButtonStyle buttonStyle = theme.useMaterial3
? _ElevatedButtonDefaultsM3(context)
Expand Down
17 changes: 13 additions & 4 deletions packages/material_ui/lib/src/elevated_button_theme.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import 'package:flutter/foundation.dart';
import 'package:flutter/widgets.dart';

import 'button_style.dart';
import 'debug.dart';
import 'theme.dart';

// Examples can assume:
Expand Down Expand Up @@ -39,7 +40,8 @@ class ElevatedButtonThemeData with Diagnosticable {
/// Creates an [ElevatedButtonThemeData].
///
/// The [style] may be null.
const ElevatedButtonThemeData({this.style});
const ElevatedButtonThemeData({this.style, this.variant})
: assert(variant != .material3Expressive, kUnsupportedStyleVariantAssertionMessage);

/// Overrides for [ElevatedButton]'s default style.
///
Expand All @@ -50,6 +52,9 @@ class ElevatedButtonThemeData with Diagnosticable {
/// If [style] is null, then this theme doesn't override anything.
final ButtonStyle? style;

/// The style variant of Material Design used by [ElevatedButton].
final StyleVariant? variant;

/// Linearly interpolate between two elevated button themes.
static ElevatedButtonThemeData? lerp(
ElevatedButtonThemeData? a,
Expand All @@ -59,11 +64,14 @@ class ElevatedButtonThemeData with Diagnosticable {
if (identical(a, b)) {
return a;
}
return ElevatedButtonThemeData(style: ButtonStyle.lerp(a?.style, b?.style, t));
return ElevatedButtonThemeData(
style: ButtonStyle.lerp(a?.style, b?.style, t),
variant: t < 0.5 ? a?.variant : b?.variant,
);
}

@override
int get hashCode => style.hashCode;
int get hashCode => Object.hash(style, variant);

@override
bool operator ==(Object other) {
Expand All @@ -73,13 +81,14 @@ class ElevatedButtonThemeData with Diagnosticable {
if (other.runtimeType != runtimeType) {
return false;
}
return other is ElevatedButtonThemeData && other.style == style;
return other is ElevatedButtonThemeData && other.style == style && other.variant == variant;
}

@override
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
super.debugFillProperties(properties);
properties.add(DiagnosticsProperty<ButtonStyle>('style', style, defaultValue: null));
properties.add(EnumProperty<StyleVariant>('variant', variant, defaultValue: null));
}
}

Expand Down
6 changes: 5 additions & 1 deletion packages/material_ui/lib/src/filled_button.dart
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import 'button_style_button.dart';
import 'color_scheme.dart';
import 'colors.dart';
import 'constants.dart';
import 'debug.dart';
import 'filled_button_theme.dart';
import 'ink_well.dart';
import 'material_state.dart';
Expand Down Expand Up @@ -430,13 +431,16 @@ class FilledButton extends ButtonStyleButton {
/// [ButtonStyle.padding] is reduced from 24 to 16.
@override
ButtonStyle defaultStyleOf(BuildContext context) {
final ThemeData theme = Theme.of(context);
final StyleVariant effectiveVariant = FilledButtonTheme.of(context).variant ?? theme.variant;
assert(effectiveVariant != .material3Expressive, kUnsupportedStyleVariantAssertionMessage);
final ButtonStyle buttonStyle = switch (_variant) {
_FilledButtonVariant.filled => _FilledButtonDefaultsM3(context),
_FilledButtonVariant.tonal => _FilledTonalButtonDefaultsM3(context),
};

if (_addPadding) {
final bool useMaterial3 = Theme.of(context).useMaterial3;
final bool useMaterial3 = theme.useMaterial3;
final double defaultFontSize =
buttonStyle.textStyle?.resolve(const <WidgetState>{})?.fontSize ?? 14.0;
final double effectiveTextScale =
Expand Down
17 changes: 13 additions & 4 deletions packages/material_ui/lib/src/filled_button_theme.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import 'package:flutter/foundation.dart';
import 'package:flutter/widgets.dart';

import 'button_style.dart';
import 'debug.dart';
import 'theme.dart';

// Examples can assume:
Expand Down Expand Up @@ -39,7 +40,8 @@ class FilledButtonThemeData with Diagnosticable {
/// Creates an [FilledButtonThemeData].
///
/// The [style] may be null.
const FilledButtonThemeData({this.style});
const FilledButtonThemeData({this.style, this.variant})
: assert(variant != .material3Expressive, kUnsupportedStyleVariantAssertionMessage);

/// Overrides for [FilledButton]'s default style.
///
Expand All @@ -50,16 +52,22 @@ class FilledButtonThemeData with Diagnosticable {
/// If [style] is null, then this theme doesn't override anything.
final ButtonStyle? style;

/// The style variant of Material Design used by [FilledButton].
final StyleVariant? variant;

/// Linearly interpolate between two filled button themes.
static FilledButtonThemeData? lerp(FilledButtonThemeData? a, FilledButtonThemeData? b, double t) {
if (identical(a, b)) {
return a;
}
return FilledButtonThemeData(style: ButtonStyle.lerp(a?.style, b?.style, t));
return FilledButtonThemeData(
style: ButtonStyle.lerp(a?.style, b?.style, t),
variant: t < 0.5 ? a?.variant : b?.variant,
);
}

@override
int get hashCode => style.hashCode;
int get hashCode => Object.hash(style, variant);

@override
bool operator ==(Object other) {
Expand All @@ -69,13 +77,14 @@ class FilledButtonThemeData with Diagnosticable {
if (other.runtimeType != runtimeType) {
return false;
}
return other is FilledButtonThemeData && other.style == style;
return other is FilledButtonThemeData && other.style == style && other.variant == variant;
}

@override
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
super.debugFillProperties(properties);
properties.add(DiagnosticsProperty<ButtonStyle>('style', style, defaultValue: null));
properties.add(EnumProperty<StyleVariant>('variant', variant, defaultValue: null));
}
}

Expand Down
Loading