feat(ui)!: rework theme resolver mechanism + move theme extension implementations
continuous-integration/drone/pr Build is failing

This commit is contained in:
2023-04-27 16:55:10 +02:00
parent 01269027f2
commit 8f5e3923d6
92 changed files with 3303 additions and 2212 deletions
@@ -37,38 +37,67 @@ abstract class ThemeResolver<Style extends ThemeStyle<Style>, Extension,
/// {@macro theme_resolver}
const ThemeResolver();
/// Compute default value from Flutter Theme or with hardcoded values.
Style computeDefaultValue(
BuildContext context, {
Extra? extra,
});
/// Compute custom style from context.
Style? Function(BuildContext context, {Extra? extra}) get customStyleFn;
/// Compute extension value from custom component extension.
/// Compute extension value from a given extension.
Style? computeExtensionValueFn(
BuildContext context,
Extension? themeExtension, {
Extra? extra,
});
/// Return the default extension containing Flutter's default values and
/// hardcoded values.
Extension? getDefaultExtension(BuildContext context);
/// Compute default value from Flutter Theme or with hardcoded values.
///
/// If no default value is found, it will throw a [FlutterError].
Style computeDefaultValue(
BuildContext context, {
Extra? extra,
}) {
final extension = getDefaultExtension(context);
if (extension == null) {
throw FlutterError('No default extension found for $Extension\n'
'Please provide a default extension in your theme using '
'`wyatt_ui_components` default extensions kit.');
}
final style = computeExtensionValueFn(context, extension, extra: extra);
if (style == null) {
throw FlutterError(
'No default style found for $Style in $Extension${extra != null ? ' with $extra' : ''}',
);
}
return style;
}
/// Compute custom style from context.
Style? Function(BuildContext context, {Extra? extra}) get customStyleFn;
/// Choose most suitable style for a given context.
Style negotiate(BuildContext context, {Extra? extra}) {
// 1) Custom style passed in constructor (cannot be null)
final style = computeDefaultValue(context, extra: extra);
return ThemeHelper.getElement<Style, Style>(
[
// 1) Custom style passed in constructor
customStyleFn(context, extra: extra),
// 3) Default
style,
// -> then, try to find better style, and merge it with the default
// 2) Theme extension
computeExtensionValueFn(
context,
Theme.of(context).extension<Extension>(),
extra: extra,
),
// 3) Default
style,
// -> then, try to find better style, and merge it with the one above
// 1) Custom style passed in constructor
customStyleFn(context, extra: extra),
],
transform: (value) => value,
combine: (value, element) => value?.mergeWith(element),
@@ -0,0 +1,17 @@
// Copyright (C) 2023 WYATT GROUP
// Please see the AUTHORS file for details.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
export 'theme_extensions/theme_extensions.dart';
@@ -0,0 +1,20 @@
// Copyright (C) 2023 WYATT GROUP
// Please see the AUTHORS file for details.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
export 'file_selection_button_theme_extension_default.dart';
export 'flat_button_theme_extension_default.dart';
export 'simple_icon_button_theme_extension_default.dart';
export 'symbol_button_theme_extension_default.dart';
@@ -0,0 +1,81 @@
// Copyright (C) 2023 WYATT GROUP
// Please see the AUTHORS file for details.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
import 'package:flutter/material.dart';
import 'package:wyatt_ui_components/wyatt_ui_components.dart';
/// {@template file_selection_button_theme_extension}
/// Default file selection button theme extension using Flutter's
/// default theme and opinionated defaults.
/// {@endtemplate}
class FileSelectionButtonThemeExtensionDefault
extends FileSelectionButtonThemeExtension {
/// {@macro file_selection_button_theme_extension}
const FileSelectionButtonThemeExtensionDefault({
required super.disabledStyle,
required super.focusedStyle,
required super.hoveredStyle,
required super.normalStyle,
required super.tappedStyle,
required super.selectedStyle,
required super.invalidStyle,
});
/// Creates a [FileSelectionButtonThemeExtensionDefault] given a [ThemeData]
///
/// {@macro file_selection_button_theme_extension}
factory FileSelectionButtonThemeExtensionDefault.from(ThemeData theme) {
final style = FileSelectionButtonStyle(
titleStyle: theme.textTheme.labelLarge,
subtitleStyle: theme.textTheme.labelSmall,
radius: (theme.buttonTheme.shape is RoundedRectangleBorder)
? (theme.buttonTheme.shape as RoundedRectangleBorder).borderRadius
: null,
padding: const EdgeInsets.symmetric(horizontal: 10),
foregroundColors: MultiColor.single(theme.colorScheme.onPrimary),
backgroundColors: MultiColor.single(theme.colorScheme.primary),
);
return FileSelectionButtonThemeExtensionDefault(
normalStyle: style,
focusedStyle: style,
hoveredStyle: style.copyWith(
backgroundColors:
MultiColor.single(theme.colorScheme.primary.withOpacity(0.92)),
),
tappedStyle: style.copyWith(
backgroundColors:
MultiColor.single(theme.colorScheme.primary.withOpacity(0.92)),
),
selectedStyle: style,
disabledStyle: style.copyWith(
foregroundColors:
MultiColor.single(theme.colorScheme.onSurface.withOpacity(0.12)),
backgroundColors:
MultiColor.single(theme.colorScheme.onSurface.withOpacity(0.38)),
),
invalidStyle: style,
);
}
/// Creates a [FileSelectionButtonThemeExtensionDefault] from a dark theme
factory FileSelectionButtonThemeExtensionDefault.dark() =>
FileSelectionButtonThemeExtensionDefault.from(ThemeData.dark());
/// Creates a [FileSelectionButtonThemeExtensionDefault] from a light theme
factory FileSelectionButtonThemeExtensionDefault.light() =>
FileSelectionButtonThemeExtensionDefault.from(ThemeData.light());
}
@@ -0,0 +1,78 @@
// Copyright (C) 2023 WYATT GROUP
// Please see the AUTHORS file for details.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
import 'package:flutter/material.dart';
import 'package:wyatt_ui_components/wyatt_ui_components.dart';
/// {@template flat_button_theme_extension_default}
/// Default flat button theme extension using Flutter's default values.
/// {@endtemplate}
class FlatButtonThemeExtensionDefault extends FlatButtonThemeExtension {
/// {@macro flat_button_theme_extension_default}
const FlatButtonThemeExtensionDefault({
required super.disabledStyle,
required super.focusedStyle,
required super.hoveredStyle,
required super.normalStyle,
required super.tappedStyle,
});
/// Creates a [FlatButtonThemeExtensionDefault] given a [ThemeData]
///
/// {@macro flat_button_theme_extension_default}
factory FlatButtonThemeExtensionDefault.from(ThemeData theme) {
final backgroundColor = MultiColor.single(theme.colorScheme.primary);
final foregroundColor = MultiColor.single(theme.colorScheme.onPrimary);
final style = FlatButtonStyle(
labelStyle:
theme.textTheme.labelLarge?.copyWith(color: foregroundColor.color),
radius: (theme.buttonTheme.shape is RoundedRectangleBorder)
? (theme.buttonTheme.shape as RoundedRectangleBorder).borderRadius
: null,
padding: theme.buttonTheme.padding,
foregroundColors: foregroundColor,
backgroundColors: backgroundColor,
);
return FlatButtonThemeExtensionDefault(
normalStyle: style,
focusedStyle: style,
hoveredStyle: style.copyWith(
backgroundColors:
MultiColor.single(theme.colorScheme.primary.withOpacity(0.92)),
),
tappedStyle: style.copyWith(
backgroundColors:
MultiColor.single(theme.colorScheme.primary.withOpacity(0.92)),
),
disabledStyle: style.copyWith(
foregroundColors:
MultiColor.single(theme.colorScheme.onSurface.withOpacity(0.12)),
backgroundColors:
MultiColor.single(theme.colorScheme.onSurface.withOpacity(0.38)),
),
);
}
/// Creates a [FlatButtonThemeExtensionDefault] from a dark theme
factory FlatButtonThemeExtensionDefault.dark() =>
FlatButtonThemeExtensionDefault.from(ThemeData.dark());
/// Creates a [FlatButtonThemeExtensionDefault] from a light theme
factory FlatButtonThemeExtensionDefault.light() =>
FlatButtonThemeExtensionDefault.from(ThemeData.light());
}
@@ -0,0 +1,78 @@
// Copyright (C) 2023 WYATT GROUP
// Please see the AUTHORS file for details.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
import 'package:flutter/material.dart';
import 'package:wyatt_ui_components/wyatt_ui_components.dart';
/// {@template simple_icon_button_theme_extension}
/// Default simple icon button theme extension using Flutter's default values.
/// {@endtemplate}
class SimpleIconButtonThemeExtensionDefault
extends SimpleIconButtonThemeExtension {
/// {@macro simple_icon_button_theme_extension}
const SimpleIconButtonThemeExtensionDefault({
required super.disabledStyle,
required super.focusedStyle,
required super.hoveredStyle,
required super.normalStyle,
required super.tappedStyle,
});
/// Creates a [SimpleIconButtonThemeExtensionDefault] given a [ThemeData]
///
/// {@macro file_selection_button_theme_extension}
factory SimpleIconButtonThemeExtensionDefault.from(ThemeData theme) {
final backgroundColor = MultiColor.single(theme.colorScheme.primary);
final foregroundColor = MultiColor.single(theme.colorScheme.onPrimary);
final style = SimpleIconButtonStyle(
dimension: theme.buttonTheme.height,
radius: (theme.buttonTheme.shape is RoundedRectangleBorder)
? (theme.buttonTheme.shape as RoundedRectangleBorder).borderRadius
: null,
padding: theme.buttonTheme.padding,
foregroundColors: foregroundColor,
backgroundColors: backgroundColor,
);
return SimpleIconButtonThemeExtensionDefault(
normalStyle: style,
focusedStyle: style,
hoveredStyle: style.copyWith(
backgroundColors:
MultiColor.single(theme.colorScheme.primary.withOpacity(0.92)),
),
tappedStyle: style.copyWith(
backgroundColors:
MultiColor.single(theme.colorScheme.primary.withOpacity(0.92)),
),
disabledStyle: style.copyWith(
foregroundColors:
MultiColor.single(theme.colorScheme.onSurface.withOpacity(0.12)),
backgroundColors:
MultiColor.single(theme.colorScheme.onSurface.withOpacity(0.38)),
),
);
}
/// Creates a [SimpleIconButtonThemeExtensionDefault] from a dark theme
factory SimpleIconButtonThemeExtensionDefault.dark() =>
SimpleIconButtonThemeExtensionDefault.from(ThemeData.dark());
/// Creates a [SimpleIconButtonThemeExtensionDefault] from a light theme
factory SimpleIconButtonThemeExtensionDefault.light() =>
SimpleIconButtonThemeExtensionDefault.from(ThemeData.light());
}
@@ -0,0 +1,84 @@
// Copyright (C) 2023 WYATT GROUP
// Please see the AUTHORS file for details.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
import 'package:flutter/material.dart';
import 'package:wyatt_ui_components/wyatt_ui_components.dart';
/// {@template symbol_button_theme_extension}
/// Default symbol button theme extension using Flutter's default values.
/// {@endtemplate}
class SymbolButtonThemeExtensionDefault extends SymbolButtonThemeExtension {
/// {@macro flat_button_theme_extension}
const SymbolButtonThemeExtensionDefault({
required super.disabledStyle,
required super.focusedStyle,
required super.hoveredStyle,
required super.normalStyle,
required super.tappedStyle,
required super.selectedStyle,
});
/// Creates a [SymbolButtonThemeExtensionDefault] given a [ThemeData]
///
/// {@macro file_selection_button_theme_extension}
factory SymbolButtonThemeExtensionDefault.from(ThemeData theme) {
final backgroundColor = MultiColor.single(theme.colorScheme.primary);
final foregroundColor = MultiColor.single(theme.colorScheme.onPrimary);
final style = SymbolButtonStyle(
labelStyle:
theme.textTheme.labelLarge?.copyWith(color: foregroundColor.color),
dimension: theme.buttonTheme.height * 1.5,
radius: (theme.buttonTheme.shape is RoundedRectangleBorder)
? (theme.buttonTheme.shape as RoundedRectangleBorder).borderRadius
: null,
padding: theme.buttonTheme.padding,
foregroundColors: foregroundColor,
backgroundColors: backgroundColor,
);
return SymbolButtonThemeExtensionDefault(
normalStyle: style,
focusedStyle: style,
hoveredStyle: style.copyWith(
backgroundColors:
MultiColor.single(theme.colorScheme.primary.withOpacity(0.92)),
),
tappedStyle: style.copyWith(
backgroundColors:
MultiColor.single(theme.colorScheme.primary.withOpacity(0.92)),
),
disabledStyle: style.copyWith(
foregroundColors:
MultiColor.single(theme.colorScheme.onSurface.withOpacity(0.12)),
backgroundColors:
MultiColor.single(theme.colorScheme.onSurface.withOpacity(0.38)),
),
selectedStyle: style.copyWith(
backgroundColors:
MultiColor.single(theme.colorScheme.primary.withOpacity(0.92)),
),
);
}
/// Creates a [SymbolButtonThemeExtensionDefault] from a dark theme
factory SymbolButtonThemeExtensionDefault.dark() =>
SymbolButtonThemeExtensionDefault.from(ThemeData.dark());
/// Creates a [SymbolButtonThemeExtensionDefault] from a light theme
factory SymbolButtonThemeExtensionDefault.light() =>
SymbolButtonThemeExtensionDefault.from(ThemeData.light());
}
@@ -0,0 +1,67 @@
// Copyright (C) 2023 WYATT GROUP
// Please see the AUTHORS file for details.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
import 'package:flutter/material.dart';
import 'package:wyatt_ui_components/src/core/utils/multi_color.dart';
import 'package:wyatt_ui_components/src/domain/theme_extensions/theme_extensions.dart';
/// {@template card_theme_extension_default}
/// Default card theme extension using Flutter's default card theme and
/// opinionated defaults.
/// {@endtemplate}
class CardThemeExtensionDefault extends CardThemeExtension {
/// {@macro card_theme_extension_default}
const CardThemeExtensionDefault({
required super.radius,
required super.padding,
required super.backgroundColors,
required super.borderColors,
required super.stroke,
required super.shadow,
required super.minSize,
required super.maxSize,
required super.titleStyle,
required super.subtitleStyle,
required super.bodyStyle,
});
/// Creates a [CardThemeExtensionDefault] from a [ThemeData]
/// and opinionated defaults.
///
/// {@macro card_theme_extension_default}
factory CardThemeExtensionDefault.from(ThemeData theme) =>
CardThemeExtensionDefault(
radius: const BorderRadius.all(Radius.circular(12)),
padding: theme.cardTheme.margin,
backgroundColors: MultiColor.single(theme.cardTheme.color),
borderColors: MultiColor.single(theme.cardTheme.color),
minSize: const Size(330, 0),
maxSize: const Size(390, double.infinity),
titleStyle: theme.textTheme.titleLarge,
subtitleStyle: theme.textTheme.titleMedium,
bodyStyle: theme.textTheme.bodyMedium,
stroke: 1,
shadow: null,
);
/// Creates a [CardThemeExtensionDefault] from a dark [ThemeData]
factory CardThemeExtensionDefault.dark() =>
CardThemeExtensionDefault.from(ThemeData.dark());
/// Creates a [CardThemeExtensionDefault] from a light [ThemeData]
factory CardThemeExtensionDefault.light() =>
CardThemeExtensionDefault.from(ThemeData.light());
}
@@ -0,0 +1,97 @@
// Copyright (C) 2023 WYATT GROUP
// Please see the AUTHORS file for details.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
import 'package:flutter/material.dart';
import 'package:wyatt_ui_components/src/domain/entities/text_inputs/text_input_style.dart';
import 'package:wyatt_ui_components/src/domain/theme_extensions/text_input_theme_extension.dart';
/// {@template text_input_theme_extension_default}
/// The default implementation of [TextInputThemeExtension].
/// {@endtemplate}
class TextInputThemeExtensionDefault extends TextInputThemeExtension {
/// {@macro text_input_theme_extension_default}
const TextInputThemeExtensionDefault({
required super.normalStyle,
required super.focusedStyle,
required super.disabledStyle,
required super.invalidStyle,
});
/// Creates a [TextInputThemeExtensionDefault] from a [ThemeData].
///
/// {@macro text_input_theme_extension_default}
factory TextInputThemeExtensionDefault.from(ThemeData theme) {
final labelStyle = theme.textTheme.labelLarge
?.copyWith(color: theme.unselectedWidgetColor);
final hintStyle = theme.textTheme.labelLarge;
final prefixStyle = theme.textTheme.bodyMedium;
final suffixStyle = theme.textTheme.bodyMedium;
final inputStyle = theme.textTheme.bodyMedium;
final iconColor = theme.colorScheme.inversePrimary;
final prefixIconColor = theme.unselectedWidgetColor;
final suffixIconColor = theme.unselectedWidgetColor;
final borderColors = theme.unselectedWidgetColor;
final style = TextInputStyle(
labelStyle: labelStyle,
hintStyle: hintStyle,
iconColor: iconColor,
prefixIconColor: prefixIconColor,
prefixStyle: prefixStyle,
suffixStyle: suffixStyle,
suffixIconColor: suffixIconColor,
borderColors: borderColors,
inputStyle: inputStyle,
);
return TextInputThemeExtensionDefault(
normalStyle: style,
focusedStyle: style.copyWith(
prefixIconColor: theme.colorScheme.primary,
suffixIconColor: theme.colorScheme.primary,
iconColor: theme.colorScheme.primary,
borderColors: theme.colorScheme.primary,
labelStyle: labelStyle?.copyWith(color: theme.colorScheme.primary),
),
disabledStyle: style.copyWith(
labelStyle: labelStyle?.copyWith(color: theme.disabledColor),
hintStyle: hintStyle?.copyWith(color: theme.disabledColor),
prefixStyle: prefixStyle?.copyWith(color: theme.disabledColor),
suffixStyle: suffixStyle?.copyWith(color: theme.disabledColor),
inputStyle: inputStyle?.copyWith(color: theme.disabledColor),
borderColors: theme.disabledColor,
prefixIconColor: theme.disabledColor,
suffixIconColor: theme.disabledColor,
),
invalidStyle: style.copyWith(
labelStyle: theme.textTheme.labelLarge
?.copyWith(color: theme.colorScheme.error),
borderColors: theme.colorScheme.error,
),
);
}
/// Creates a [TextInputThemeExtensionDefault] from a [ThemeData.light].
factory TextInputThemeExtensionDefault.light() =>
TextInputThemeExtensionDefault.from(ThemeData.light());
/// Creates a [TextInputThemeExtensionDefault] from a [ThemeData.dark].
factory TextInputThemeExtensionDefault.dark() =>
TextInputThemeExtensionDefault.from(ThemeData.dark());
}
@@ -0,0 +1,19 @@
// Copyright (C) 2023 WYATT GROUP
// Please see the AUTHORS file for details.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
export 'button_theme_extension/button_theme_extension.dart';
export 'card_theme_extension_default.dart';
export 'text_input_theme_extension_default.dart';
@@ -15,3 +15,4 @@
// along with this program. If not, see <https://www.gnu.org/licenses/>.
export './entities/entities.dart';
export './theme_extensions/theme_extensions.dart';
@@ -0,0 +1,20 @@
// Copyright (C) 2023 WYATT GROUP
// Please see the AUTHORS file for details.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
export 'file_selection_button_theme_extension.dart';
export 'flat_button_theme_extension.dart';
export 'simple_icon_button_theme_extension.dart';
export 'symbol_button_theme_extension.dart';
@@ -0,0 +1,103 @@
// Copyright (C) 2023 WYATT GROUP
// Please see the AUTHORS file for details.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
import 'package:flutter/material.dart';
import 'package:wyatt_ui_components/wyatt_ui_components.dart';
/// {@template file_selection_button_theme_extension}
/// File selection button theme extension that extends [ThemeExtension] and
/// implements copyWith, and lerp methods so you don't have to.
/// {@endtemplate}
class FileSelectionButtonThemeExtension
extends ThemeExtension<FileSelectionButtonThemeExtension> {
/// {@macro file_selection_button_theme_extension}
const FileSelectionButtonThemeExtension({
this.disabledStyle,
this.focusedStyle,
this.hoveredStyle,
this.normalStyle,
this.tappedStyle,
this.selectedStyle,
this.invalidStyle,
});
/// Style of this button in disabled state
final FileSelectionButtonStyle? disabledStyle;
/// Style of this button in focused state
final FileSelectionButtonStyle? focusedStyle;
/// Style of this button in hovered state
final FileSelectionButtonStyle? hoveredStyle;
/// Style of this button in normal state
final FileSelectionButtonStyle? normalStyle;
/// Style of this button in tapped state
final FileSelectionButtonStyle? tappedStyle;
/// Style of this button in selected state
final FileSelectionButtonStyle? selectedStyle;
/// Style of this button in invalid state
final FileSelectionButtonStyle? invalidStyle;
@override
ThemeExtension<FileSelectionButtonThemeExtension> copyWith({
FileSelectionButtonStyle? disabledStyle,
FileSelectionButtonStyle? focusedStyle,
FileSelectionButtonStyle? hoveredStyle,
FileSelectionButtonStyle? normalStyle,
FileSelectionButtonStyle? tappedStyle,
FileSelectionButtonStyle? selectedStyle,
FileSelectionButtonStyle? invalidStyle,
}) =>
FileSelectionButtonThemeExtension(
disabledStyle: disabledStyle ?? this.disabledStyle,
focusedStyle: focusedStyle ?? this.focusedStyle,
hoveredStyle: hoveredStyle ?? this.hoveredStyle,
normalStyle: normalStyle ?? this.normalStyle,
tappedStyle: tappedStyle ?? this.tappedStyle,
selectedStyle: selectedStyle ?? this.selectedStyle,
invalidStyle: invalidStyle ?? this.invalidStyle,
);
@override
ThemeExtension<FileSelectionButtonThemeExtension> lerp(
covariant ThemeExtension<FileSelectionButtonThemeExtension>? other,
double t,
) {
if (other is! FileSelectionButtonThemeExtension) {
return this;
}
return FileSelectionButtonThemeExtension(
disabledStyle:
FileSelectionButtonStyle.lerp(disabledStyle, other.disabledStyle, t),
focusedStyle:
FileSelectionButtonStyle.lerp(focusedStyle, other.focusedStyle, t),
hoveredStyle:
FileSelectionButtonStyle.lerp(hoveredStyle, other.hoveredStyle, t),
normalStyle:
FileSelectionButtonStyle.lerp(normalStyle, other.normalStyle, t),
tappedStyle:
FileSelectionButtonStyle.lerp(tappedStyle, other.tappedStyle, t),
selectedStyle:
FileSelectionButtonStyle.lerp(selectedStyle, other.selectedStyle, t),
invalidStyle:
FileSelectionButtonStyle.lerp(invalidStyle, other.invalidStyle, t),
);
}
}
@@ -0,0 +1,83 @@
// Copyright (C) 2023 WYATT GROUP
// Please see the AUTHORS file for details.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
import 'package:flutter/material.dart';
import 'package:wyatt_ui_components/wyatt_ui_components.dart';
/// {@template flat_button_theme_extension}
/// Flat button theme extension that extends [ThemeExtension] and
/// implements copyWith, and lerp methods so you don't have to.
/// {@endtemplate}
class FlatButtonThemeExtension
extends ThemeExtension<FlatButtonThemeExtension> {
/// {@macro flat_button_theme_extension}
const FlatButtonThemeExtension({
this.disabledStyle,
this.focusedStyle,
this.hoveredStyle,
this.normalStyle,
this.tappedStyle,
});
/// Style of this button in disabled state
final FlatButtonStyle? disabledStyle;
/// Style of this button in focused state
final FlatButtonStyle? focusedStyle;
/// Style of this button in hovered state
final FlatButtonStyle? hoveredStyle;
/// Style of this button in normal state
final FlatButtonStyle? normalStyle;
/// Style of this button in tapped state
final FlatButtonStyle? tappedStyle;
@override
ThemeExtension<FlatButtonThemeExtension> copyWith({
FlatButtonStyle? disabledStyle,
FlatButtonStyle? focusedStyle,
FlatButtonStyle? hoveredStyle,
FlatButtonStyle? normalStyle,
FlatButtonStyle? tappedStyle,
}) =>
FlatButtonThemeExtension(
disabledStyle: disabledStyle ?? this.disabledStyle,
focusedStyle: focusedStyle ?? this.focusedStyle,
hoveredStyle: hoveredStyle ?? this.hoveredStyle,
normalStyle: normalStyle ?? this.normalStyle,
tappedStyle: tappedStyle ?? this.tappedStyle,
);
@override
ThemeExtension<FlatButtonThemeExtension> lerp(
covariant ThemeExtension<FlatButtonThemeExtension>? other,
double t,
) {
if (other is! FlatButtonThemeExtension) {
return this;
}
return FlatButtonThemeExtension(
disabledStyle:
FlatButtonStyle.lerp(disabledStyle, other.disabledStyle, t),
focusedStyle: FlatButtonStyle.lerp(focusedStyle, other.focusedStyle, t),
hoveredStyle: FlatButtonStyle.lerp(hoveredStyle, other.hoveredStyle, t),
normalStyle: FlatButtonStyle.lerp(normalStyle, other.normalStyle, t),
tappedStyle: FlatButtonStyle.lerp(tappedStyle, other.tappedStyle, t),
);
}
}
@@ -0,0 +1,87 @@
// Copyright (C) 2023 WYATT GROUP
// Please see the AUTHORS file for details.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
import 'package:flutter/material.dart';
import 'package:wyatt_ui_components/wyatt_ui_components.dart';
/// {@template simple_icon_button_theme_extension}
/// Simple icon button theme extension that extends [ThemeExtension] and
/// implements copyWith, and lerp methods so you don't have to.
/// {@endtemplate}
class SimpleIconButtonThemeExtension
extends ThemeExtension<SimpleIconButtonThemeExtension> {
/// {@macro simple_icon_button_theme_extension}
const SimpleIconButtonThemeExtension({
this.disabledStyle,
this.focusedStyle,
this.hoveredStyle,
this.normalStyle,
this.tappedStyle,
});
/// Style of this button in disabled state
final SimpleIconButtonStyle? disabledStyle;
/// Style of this button in focused state
final SimpleIconButtonStyle? focusedStyle;
/// Style of this button in hovered state
final SimpleIconButtonStyle? hoveredStyle;
/// Style of this button in normal state
final SimpleIconButtonStyle? normalStyle;
/// Style of this button in tapped state
final SimpleIconButtonStyle? tappedStyle;
@override
ThemeExtension<SimpleIconButtonThemeExtension> copyWith({
SimpleIconButtonStyle? disabledStyle,
SimpleIconButtonStyle? focusedStyle,
SimpleIconButtonStyle? hoveredStyle,
SimpleIconButtonStyle? normalStyle,
SimpleIconButtonStyle? tappedStyle,
}) =>
SimpleIconButtonThemeExtension(
disabledStyle: disabledStyle ?? this.disabledStyle,
focusedStyle: focusedStyle ?? this.focusedStyle,
hoveredStyle: hoveredStyle ?? this.hoveredStyle,
normalStyle: normalStyle ?? this.normalStyle,
tappedStyle: tappedStyle ?? this.tappedStyle,
);
@override
ThemeExtension<SimpleIconButtonThemeExtension> lerp(
covariant ThemeExtension<SimpleIconButtonThemeExtension>? other,
double t,
) {
if (other is! SimpleIconButtonThemeExtension) {
return this;
}
return SimpleIconButtonThemeExtension(
disabledStyle:
SimpleIconButtonStyle.lerp(disabledStyle, other.disabledStyle, t),
focusedStyle:
SimpleIconButtonStyle.lerp(focusedStyle, other.focusedStyle, t),
hoveredStyle:
SimpleIconButtonStyle.lerp(hoveredStyle, other.hoveredStyle, t),
normalStyle:
SimpleIconButtonStyle.lerp(normalStyle, other.normalStyle, t),
tappedStyle:
SimpleIconButtonStyle.lerp(tappedStyle, other.tappedStyle, t),
);
}
}
@@ -0,0 +1,91 @@
// Copyright (C) 2023 WYATT GROUP
// Please see the AUTHORS file for details.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
import 'package:flutter/material.dart';
import 'package:wyatt_ui_components/wyatt_ui_components.dart';
/// {@template symbol_button_theme_extension}
/// Symbol button theme extension that extends [ThemeExtension] and
/// implements copyWith, and lerp methods so you don't have to.
/// {@endtemplate}
class SymbolButtonThemeExtension
extends ThemeExtension<SymbolButtonThemeExtension> {
/// {@macro symbol_button_theme_extension}
const SymbolButtonThemeExtension({
this.disabledStyle,
this.focusedStyle,
this.hoveredStyle,
this.normalStyle,
this.tappedStyle,
this.selectedStyle,
});
/// Style of this button in disabled state
final SymbolButtonStyle? disabledStyle;
/// Style of this button in focused state
final SymbolButtonStyle? focusedStyle;
/// Style of this button in hovered state
final SymbolButtonStyle? hoveredStyle;
/// Style of this button in normal state
final SymbolButtonStyle? normalStyle;
/// Style of this button in tapped state
final SymbolButtonStyle? tappedStyle;
/// Style of this button in selected state
final SymbolButtonStyle? selectedStyle;
@override
ThemeExtension<SymbolButtonThemeExtension> copyWith({
SymbolButtonStyle? disabledStyle,
SymbolButtonStyle? focusedStyle,
SymbolButtonStyle? hoveredStyle,
SymbolButtonStyle? normalStyle,
SymbolButtonStyle? tappedStyle,
SymbolButtonStyle? selectedStyle,
}) =>
SymbolButtonThemeExtension(
disabledStyle: disabledStyle ?? this.disabledStyle,
focusedStyle: focusedStyle ?? this.focusedStyle,
hoveredStyle: hoveredStyle ?? this.hoveredStyle,
normalStyle: normalStyle ?? this.normalStyle,
tappedStyle: tappedStyle ?? this.tappedStyle,
selectedStyle: selectedStyle ?? this.selectedStyle,
);
@override
ThemeExtension<SymbolButtonThemeExtension> lerp(
covariant ThemeExtension<SymbolButtonThemeExtension>? other,
double t,
) {
if (other is! SymbolButtonThemeExtension) {
return this;
}
return SymbolButtonThemeExtension(
disabledStyle:
SymbolButtonStyle.lerp(disabledStyle, other.disabledStyle, t),
focusedStyle: SymbolButtonStyle.lerp(focusedStyle, other.focusedStyle, t),
hoveredStyle: SymbolButtonStyle.lerp(hoveredStyle, other.hoveredStyle, t),
normalStyle: SymbolButtonStyle.lerp(normalStyle, other.normalStyle, t),
tappedStyle: SymbolButtonStyle.lerp(tappedStyle, other.tappedStyle, t),
selectedStyle:
SymbolButtonStyle.lerp(selectedStyle, other.selectedStyle, t),
);
}
}
@@ -0,0 +1,143 @@
// Copyright (C) 2023 WYATT GROUP
// Please see the AUTHORS file for details.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
import 'package:flutter/material.dart';
import 'package:wyatt_ui_components/src/core/utils/multi_color.dart';
/// {@template card_theme_extension}
/// Card theme extension that extends [ThemeExtension] and
/// implements copyWith, and lerp methods so you don't have to.
/// {@endtemplate}
class CardThemeExtension extends ThemeExtension<CardThemeExtension> {
/// {@macro card_theme_extension}
const CardThemeExtension({
this.radius,
this.padding,
this.backgroundColors,
this.borderColors,
this.stroke,
this.shadow,
this.minSize,
this.maxSize,
this.titleStyle,
this.subtitleStyle,
this.bodyStyle,
});
/// Card radius
///
/// Default to `BorderRadius.all(Radius.circular(12.0))`
final BorderRadiusGeometry? radius;
/// Padding and gaps of this card
///
/// Default to `Theme.cardTheme.margin`
final EdgeInsetsGeometry? padding;
/// Card background gradient colors (from left to right)
///
/// Default to `Theme.cardTheme.color`
final MultiColor? backgroundColors;
/// Border colors (from left to right).
///
/// Default to `null`
final MultiColor? borderColors;
/// Stroke of the border
///
/// Default to `null`
final double? stroke;
/// Drop shadow
///
/// Default to `null`
final BoxShadow? shadow;
/// Minimum size of the card
///
/// Default to `const Size(330, 0)`
final Size? minSize;
/// Maximum size of the card
///
/// Default to `const Size(double.infinity, double.infinity)`
final Size? maxSize;
/// Title text style
///
/// Default to `Theme.textTheme.titleLarge`
final TextStyle? titleStyle;
/// Subtitle text style
///
/// Default to `Theme.textTheme.titleMedium`
final TextStyle? subtitleStyle;
/// Body text style
///
/// Default to `Theme.textTheme.bodyMedium`
final TextStyle? bodyStyle;
@override
ThemeExtension<CardThemeExtension> copyWith({
BorderRadiusGeometry? radius,
EdgeInsetsGeometry? padding,
MultiColor? backgroundColors,
MultiColor? borderColors,
double? stroke,
BoxShadow? shadow,
Size? minSize,
Size? maxSize,
TextStyle? titleStyle,
TextStyle? subtitleStyle,
TextStyle? bodyStyle,
}) =>
CardThemeExtension(
radius: radius ?? this.radius,
padding: padding ?? this.padding,
backgroundColors: backgroundColors ?? this.backgroundColors,
borderColors: borderColors ?? this.borderColors,
stroke: stroke ?? this.stroke,
shadow: shadow ?? this.shadow,
minSize: minSize ?? this.minSize,
maxSize: maxSize ?? this.maxSize,
titleStyle: titleStyle ?? this.titleStyle,
subtitleStyle: subtitleStyle ?? this.subtitleStyle,
bodyStyle: bodyStyle ?? this.bodyStyle,
);
@override
ThemeExtension<CardThemeExtension> lerp(
covariant ThemeExtension<CardThemeExtension>? other,
double t,
) {
if (other is! CardThemeExtension) {
return this;
}
return CardThemeExtension(
radius: BorderRadiusGeometry.lerp(radius, other.radius, t),
padding: EdgeInsetsGeometry.lerp(padding, other.padding, t),
backgroundColors:
MultiColor.lerp(backgroundColors, other.backgroundColors, t),
borderColors: MultiColor.lerp(borderColors, other.borderColors, t),
shadow: BoxShadow.lerp(shadow, other.shadow, t),
bodyStyle: TextStyle.lerp(bodyStyle, other.bodyStyle, t),
titleStyle: TextStyle.lerp(titleStyle, other.titleStyle, t),
subtitleStyle: TextStyle.lerp(subtitleStyle, other.subtitleStyle, t),
);
}
}
@@ -0,0 +1,69 @@
// Copyright (C) 2023 WYATT GROUP
// Please see the AUTHORS file for details.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
import 'package:flutter/material.dart';
import 'package:wyatt_ui_components/src/domain/entities/text_inputs/text_input_style.dart';
class TextInputThemeExtension extends ThemeExtension<TextInputThemeExtension> {
const TextInputThemeExtension({
this.normalStyle,
this.focusedStyle,
this.invalidStyle,
this.disabledStyle,
});
/// The default style for TextInputs.
final TextInputStyle? normalStyle;
/// The style for TextInputs when they are focused.
final TextInputStyle? focusedStyle;
/// The style for TextInputs when they are invalid.
final TextInputStyle? invalidStyle;
/// The style for TextInputs when they are disabled.
final TextInputStyle? disabledStyle;
@override
ThemeExtension<TextInputThemeExtension> lerp(
covariant ThemeExtension<TextInputThemeExtension>? other,
double t,
) {
if (other is! TextInputThemeExtension) {
return this;
}
return TextInputThemeExtension(
normalStyle: TextInputStyle.lerp(normalStyle, other.normalStyle, t),
focusedStyle: TextInputStyle.lerp(focusedStyle, other.focusedStyle, t),
disabledStyle: TextInputStyle.lerp(disabledStyle, other.disabledStyle, t),
invalidStyle: TextInputStyle.lerp(invalidStyle, other.invalidStyle, t),
);
}
@override
ThemeExtension<TextInputThemeExtension> copyWith({
TextInputStyle? normalStyle,
TextInputStyle? focusedStyle,
TextInputStyle? disabledStyle,
TextInputStyle? invalidStyle,
}) =>
TextInputThemeExtension(
normalStyle: normalStyle ?? this.normalStyle,
focusedStyle: focusedStyle ?? this.focusedStyle,
disabledStyle: disabledStyle ?? this.disabledStyle,
invalidStyle: invalidStyle ?? this.invalidStyle,
);
}
@@ -0,0 +1,19 @@
// Copyright (C) 2023 WYATT GROUP
// Please see the AUTHORS file for details.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
export 'button_theme_extension/button_theme_extension.dart';
export 'card_theme_extension.dart';
export 'text_input_theme_extension.dart';
@@ -15,5 +15,6 @@
// along with this program. If not, see <https://www.gnu.org/licenses/>.
export 'core/core.dart';
export 'data/data.dart';
export 'domain/domain.dart';
export 'features/features.dart';