master #81
@ -99,6 +99,12 @@ If you need specific settings, or pass parameters to your component, call `copyW
|
||||
)
|
||||
```
|
||||
|
||||
## Default implementation
|
||||
|
||||
To use this package, you have to create your own implementation of the components. You can check out [Wyatt UI Kit](https://git.wyatt-studio.fr/Wyatt-FOSS/wyatt-packages/src/branch/master/packages/wyatt_ui_kit) package for an example.
|
||||
|
||||
But default theme extensions (used in all implementations as fallback for styles) are available in `lib/src/domain/theme_extensions` folder.
|
||||
|
||||
## Development
|
||||
|
||||
> Common to this, and Wyatt UI Kit packages.
|
||||
|
@ -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),
|
||||
|
@ -14,28 +14,4 @@
|
||||
// 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';
|
||||
|
||||
abstract class CardThemeExtension extends ThemeExtension<CardThemeExtension> {
|
||||
const CardThemeExtension({
|
||||
this.backgroundColors,
|
||||
this.secondaryBackgroundColor,
|
||||
this.borderColors,
|
||||
this.shadowColor,
|
||||
this.body,
|
||||
this.title,
|
||||
this.subtitle,
|
||||
});
|
||||
|
||||
// Colors
|
||||
final MultiColor? backgroundColors;
|
||||
final Color? secondaryBackgroundColor;
|
||||
final MultiColor? borderColors;
|
||||
final BoxShadow? shadowColor;
|
||||
|
||||
// TextStyles
|
||||
final TextStyle? body;
|
||||
final TextStyle? title;
|
||||
final TextStyle? subtitle;
|
||||
}
|
||||
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,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),
|
||||
);
|
||||
}
|
||||
}
|
@ -16,63 +16,36 @@
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:wyatt_ui_components/wyatt_ui_components.dart';
|
||||
import 'package:wyatt_ui_kit/wyatt_ui_kit.dart';
|
||||
import 'package:wyatt_ui_kit_example/theme/constants.dart';
|
||||
|
||||
class SimpleIconButtonTheme extends SimpleIconButtonThemeExtension {
|
||||
const SimpleIconButtonTheme({
|
||||
super.disabledStyle,
|
||||
super.focusedStyle,
|
||||
super.hoveredStyle,
|
||||
super.normalStyle,
|
||||
super.tappedStyle,
|
||||
/// {@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,
|
||||
});
|
||||
|
||||
factory SimpleIconButtonTheme.light() {
|
||||
final style = SimpleIconButtonStyle(
|
||||
dimension: 30,
|
||||
radius: BorderRadius.circular(5),
|
||||
padding: const EdgeInsets.all(5),
|
||||
foregroundColors: const MultiColor.single(Constants.dark),
|
||||
backgroundColors: MultiColor.single(Constants.grey1.withOpacity(0.2)),
|
||||
);
|
||||
return SimpleIconButtonTheme(
|
||||
normalStyle: style,
|
||||
disabledStyle: style.copyWith(
|
||||
foregroundColors: MultiColor.single(Constants.dark.withOpacity(0.4)),
|
||||
),
|
||||
hoveredStyle: style.copyWith(
|
||||
backgroundColors: MultiColor.single(Constants.grey1.withOpacity(0.4)),
|
||||
),
|
||||
focusedStyle: style,
|
||||
tappedStyle: style.copyWith(
|
||||
backgroundColors: MultiColor.single(Constants.grey1.withOpacity(0.5)),
|
||||
),
|
||||
);
|
||||
}
|
||||
/// Style of this button in disabled state
|
||||
final SimpleIconButtonStyle? disabledStyle;
|
||||
|
||||
factory SimpleIconButtonTheme.dark() {
|
||||
final style = SimpleIconButtonStyle(
|
||||
dimension: 30,
|
||||
radius: BorderRadius.circular(5),
|
||||
padding: const EdgeInsets.all(5),
|
||||
foregroundColors: const MultiColor.single(Constants.white),
|
||||
backgroundColors: MultiColor.single(Constants.grey3.withOpacity(0.2)),
|
||||
);
|
||||
return SimpleIconButtonTheme(
|
||||
normalStyle: style,
|
||||
disabledStyle: style.copyWith(
|
||||
foregroundColors: MultiColor.single(Constants.white.withOpacity(0.4)),
|
||||
),
|
||||
hoveredStyle: style.copyWith(
|
||||
backgroundColors: MultiColor.single(Constants.grey3.withOpacity(0.4)),
|
||||
),
|
||||
focusedStyle: style,
|
||||
tappedStyle: style.copyWith(
|
||||
backgroundColors: MultiColor.single(Constants.grey3.withOpacity(0.5)),
|
||||
),
|
||||
);
|
||||
}
|
||||
/// 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({
|
||||
@ -82,7 +55,7 @@ class SimpleIconButtonTheme extends SimpleIconButtonThemeExtension {
|
||||
SimpleIconButtonStyle? normalStyle,
|
||||
SimpleIconButtonStyle? tappedStyle,
|
||||
}) =>
|
||||
SimpleIconButtonTheme(
|
||||
SimpleIconButtonThemeExtension(
|
||||
disabledStyle: disabledStyle ?? this.disabledStyle,
|
||||
focusedStyle: focusedStyle ?? this.focusedStyle,
|
||||
hoveredStyle: hoveredStyle ?? this.hoveredStyle,
|
||||
@ -95,10 +68,10 @@ class SimpleIconButtonTheme extends SimpleIconButtonThemeExtension {
|
||||
covariant ThemeExtension<SimpleIconButtonThemeExtension>? other,
|
||||
double t,
|
||||
) {
|
||||
if (other is! SimpleIconButtonTheme) {
|
||||
if (other is! SimpleIconButtonThemeExtension) {
|
||||
return this;
|
||||
}
|
||||
return SimpleIconButtonTheme(
|
||||
return SimpleIconButtonThemeExtension(
|
||||
disabledStyle:
|
||||
SimpleIconButtonStyle.lerp(disabledStyle, other.disabledStyle, t),
|
||||
focusedStyle:
|
@ -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';
|
||||
|
@ -17,8 +17,9 @@ class Bars extends DemoPage {
|
||||
padding: const EdgeInsets.all(8),
|
||||
child: Image.asset('assets/images/studio_logo.png'),
|
||||
),
|
||||
title: 'Wyatt Studio'.wrap(
|
||||
gradientColors: const MultiColor(
|
||||
title: const TextWrapper(
|
||||
'Wyatt Studio',
|
||||
gradientColors: MultiColor(
|
||||
[
|
||||
Color.fromRGBO(57, 167, 254, 1),
|
||||
Color.fromRGBO(71, 94, 241, 1),
|
||||
@ -35,8 +36,9 @@ class Bars extends DemoPage {
|
||||
padding: const EdgeInsets.all(8),
|
||||
child: Image.asset('assets/images/studio_logo.png'),
|
||||
),
|
||||
title: 'Wyatt Studio'.wrap(
|
||||
gradientColors: const MultiColor(
|
||||
title: const TextWrapper(
|
||||
'Wyatt Studio',
|
||||
gradientColors: MultiColor(
|
||||
[
|
||||
Color.fromRGBO(57, 167, 254, 1),
|
||||
Color.fromRGBO(71, 94, 241, 1),
|
||||
@ -67,21 +69,20 @@ class Bars extends DemoPage {
|
||||
padding: const EdgeInsets.symmetric(horizontal: 20),
|
||||
child: Image.asset('assets/images/studio_long_logo.png'),
|
||||
),
|
||||
actions: [
|
||||
actions: const [
|
||||
Padding(
|
||||
padding:
|
||||
const EdgeInsets.symmetric(horizontal: 20, vertical: 25),
|
||||
padding: EdgeInsets.symmetric(horizontal: 20, vertical: 25),
|
||||
child: FlatButton(
|
||||
label: 'Estimer mon projet'.wrap(),
|
||||
label: TextWrapper('Estimer mon projet'),
|
||||
),
|
||||
),
|
||||
],
|
||||
navigationItems: [
|
||||
'ACCEUIL'.wrap(),
|
||||
'VOTRE PROGRAMME'.wrap(),
|
||||
'LE STUDIO'.wrap(),
|
||||
'SAVOIR FAIRE'.wrap()
|
||||
].whereType<TextWrapper>().toList(),
|
||||
navigationItems: const [
|
||||
TextWrapper('ACCUEIL'),
|
||||
TextWrapper('VOTRE PROGRAMME'),
|
||||
TextWrapper('LE STUDIO'),
|
||||
TextWrapper('SAVOIR FAIRE')
|
||||
],
|
||||
),
|
||||
],
|
||||
);
|
||||
|
@ -63,7 +63,7 @@ class _FileSelectionButtonsState extends State<FileSelectionButtons> {
|
||||
title: const TextWrapper(
|
||||
'Ajouter un fichier',
|
||||
),
|
||||
subTitle: const TextWrapper('Taille max: 20 Mo'),
|
||||
subtitle: const TextWrapper('Taille max: 20 Mo'),
|
||||
),
|
||||
const Gap(20),
|
||||
BlocProvider(
|
||||
@ -73,7 +73,7 @@ class _FileSelectionButtonsState extends State<FileSelectionButtons> {
|
||||
title: const TextWrapper(
|
||||
'Enabled',
|
||||
),
|
||||
subTitle: const TextWrapper('Subtitle'),
|
||||
subtitle: const TextWrapper('subtitle'),
|
||||
),
|
||||
),
|
||||
const Gap(20),
|
||||
@ -83,7 +83,7 @@ class _FileSelectionButtonsState extends State<FileSelectionButtons> {
|
||||
title: const TextWrapper(
|
||||
'Disabled',
|
||||
),
|
||||
subTitle: const TextWrapper('Subtitle'),
|
||||
subtitle: const TextWrapper('subtitle'),
|
||||
disabled: _disabled,
|
||||
),
|
||||
const Gap(20),
|
||||
@ -94,7 +94,7 @@ class _FileSelectionButtonsState extends State<FileSelectionButtons> {
|
||||
title: const TextWrapper(
|
||||
'Hovered',
|
||||
),
|
||||
subTitle: const TextWrapper('Subtitle'),
|
||||
subtitle: const TextWrapper('subtitle'),
|
||||
),
|
||||
),
|
||||
const Gap(20),
|
||||
@ -105,7 +105,7 @@ class _FileSelectionButtonsState extends State<FileSelectionButtons> {
|
||||
title: const TextWrapper(
|
||||
'Focused',
|
||||
),
|
||||
subTitle: const TextWrapper('Subtitle'),
|
||||
subtitle: const TextWrapper('subtitle'),
|
||||
),
|
||||
),
|
||||
const Gap(20),
|
||||
@ -116,7 +116,7 @@ class _FileSelectionButtonsState extends State<FileSelectionButtons> {
|
||||
title: const TextWrapper(
|
||||
'Tapped',
|
||||
),
|
||||
subTitle: const TextWrapper('Subtitle'),
|
||||
subtitle: const TextWrapper('subtitle'),
|
||||
),
|
||||
),
|
||||
const Gap(20),
|
||||
@ -127,7 +127,7 @@ class _FileSelectionButtonsState extends State<FileSelectionButtons> {
|
||||
title: const TextWrapper(
|
||||
'Invalid',
|
||||
),
|
||||
subTitle: const TextWrapper('Subtitle'),
|
||||
subtitle: const TextWrapper('subtitle'),
|
||||
),
|
||||
),
|
||||
const Gap(20),
|
||||
@ -154,7 +154,7 @@ class _FileSelectionButtonsState extends State<FileSelectionButtons> {
|
||||
title: const TextWrapper(
|
||||
'Dynamic',
|
||||
),
|
||||
subTitle: const TextWrapper('Subtitle'),
|
||||
subtitle: const TextWrapper('subtitle'),
|
||||
disabled: _dynamic,
|
||||
),
|
||||
],
|
||||
|
@ -25,8 +25,8 @@ class InformationCards extends StatelessWidget {
|
||||
FlutterLogo(size: 60),
|
||||
],
|
||||
title: TextWrapper('Flutter'),
|
||||
subtitle: TextWrapper.text('One single code base.'),
|
||||
body: TextWrapper.text(
|
||||
subtitle: TextWrapper('One single code base.'),
|
||||
body: TextWrapper(
|
||||
'Cupidatat reprehenderit aliqua eiusmod Lorem. '
|
||||
'Qui ipsum id ea ea nulla labore aute ullamco aute '
|
||||
'quis elit ut amet velit. Incididunt fugiat proident '
|
||||
@ -57,22 +57,23 @@ class InformationCards extends StatelessWidget {
|
||||
FlutterLogo(size: 60),
|
||||
FlutterLogo(size: 60),
|
||||
],
|
||||
title: 'Flutter'.wrap(
|
||||
gradientColors: const MultiColor([Colors.blue, Colors.green]),
|
||||
title: const TextWrapper(
|
||||
'Flutter',
|
||||
gradientColors: MultiColor([Colors.blue, Colors.green]),
|
||||
),
|
||||
subtitle: const TextWrapper.text('One single code base.'),
|
||||
body: 'Cupidatat reprehenderit aliqua eiusmod Lorem. '
|
||||
'Qui ipsum id ea ea nulla labore aute ullamco aute '
|
||||
'quis elit ut amet velit. Incididunt fugiat proident '
|
||||
'proident deserunt tempor Lorem cillum qui do '
|
||||
'ullamco Lorem magna ipsum. Ullamco cupidatat velit '
|
||||
'elit sint ex cupidatat ullamco Lorem amet elit '
|
||||
'ipsum sunt ex voluptate. Eiusmod quis laborum velit '
|
||||
'excepteur eu commodo consectetur qui exercitation '
|
||||
'officia consequat ullamco sit adipisicing. Ullamco '
|
||||
'magna cupidatat Lorem nulla cupidatat voluptate '
|
||||
'irure ex reprehenderit.'
|
||||
.wrap(),
|
||||
subtitle: const TextWrapper('One single code base.'),
|
||||
body: const TextWrapper(
|
||||
'Cupidatat reprehenderit aliqua eiusmod Lorem. '
|
||||
'Qui ipsum id ea ea nulla labore aute ullamco aute '
|
||||
'quis elit ut amet velit. Incididunt fugiat proident '
|
||||
'proident deserunt tempor Lorem cillum qui do '
|
||||
'ullamco Lorem magna ipsum. Ullamco cupidatat velit '
|
||||
'elit sint ex cupidatat ullamco Lorem amet elit '
|
||||
'ipsum sunt ex voluptate. Eiusmod quis laborum velit '
|
||||
'excepteur eu commodo consectetur qui exercitation '
|
||||
'officia consequat ullamco sit adipisicing. Ullamco '
|
||||
'magna cupidatat Lorem nulla cupidatat voluptate '
|
||||
'irure ex reprehenderit.'),
|
||||
),
|
||||
],
|
||||
),
|
||||
@ -81,26 +82,26 @@ class InformationCards extends StatelessWidget {
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
InformationCard(
|
||||
icons: const [
|
||||
const InformationCard(
|
||||
icons: [
|
||||
FlutterLogo(size: 60),
|
||||
],
|
||||
axis: Axis.horizontal,
|
||||
title: const TextWrapper.text('Flutter'),
|
||||
subtitle: const TextWrapper.text('One single code base.'),
|
||||
body: 'Cupidatat reprehenderit aliqua eiusmod Lorem. '
|
||||
'Qui ipsum id ea ea nulla labore aute ullamco aute '
|
||||
'quis elit ut amet velit. Incididunt fugiat proident '
|
||||
'proident deserunt tempor Lorem cillum qui do '
|
||||
'ullamco Lorem magna ipsum. Ullamco cupidatat velit '
|
||||
'elit sint ex cupidatat ullamco Lorem amet elit '
|
||||
'ipsum sunt ex voluptate. Eiusmod quis laborum velit '
|
||||
'excepteur eu commodo consectetur qui exercitation '
|
||||
'officia consequat ullamco sit adipisicing. Ullamco '
|
||||
'magna cupidatat Lorem nulla cupidatat voluptate '
|
||||
'irure ex reprehenderit.'
|
||||
.wrap(
|
||||
gradientColors: const MultiColor([
|
||||
title: TextWrapper('Flutter'),
|
||||
subtitle: TextWrapper('One single code base.'),
|
||||
body: TextWrapper(
|
||||
'Cupidatat reprehenderit aliqua eiusmod Lorem. '
|
||||
'Qui ipsum id ea ea nulla labore aute ullamco aute '
|
||||
'quis elit ut amet velit. Incididunt fugiat proident '
|
||||
'proident deserunt tempor Lorem cillum qui do '
|
||||
'ullamco Lorem magna ipsum. Ullamco cupidatat velit '
|
||||
'elit sint ex cupidatat ullamco Lorem amet elit '
|
||||
'ipsum sunt ex voluptate. Eiusmod quis laborum velit '
|
||||
'excepteur eu commodo consectetur qui exercitation '
|
||||
'officia consequat ullamco sit adipisicing. Ullamco '
|
||||
'magna cupidatat Lorem nulla cupidatat voluptate '
|
||||
'irure ex reprehenderit.',
|
||||
gradientColors: MultiColor([
|
||||
Colors.red,
|
||||
Colors.orange,
|
||||
]),
|
||||
@ -123,14 +124,15 @@ class InformationCards extends StatelessWidget {
|
||||
FlutterLogo(size: 60),
|
||||
],
|
||||
axis: Axis.horizontal,
|
||||
title: const TextWrapper.text('Flutter'),
|
||||
subtitle: 'One single code base.'.wrap(
|
||||
// gradient: [Colors.blue, Colors.green],
|
||||
style: const TextStyle(
|
||||
title: const TextWrapper('Flutter'),
|
||||
subtitle: TextWrapper(
|
||||
'One single code base.',
|
||||
style: Theme.of(context).textTheme.titleMedium?.copyWith(
|
||||
fontSize: 15,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
body: const TextWrapper.text(
|
||||
body: const TextWrapper(
|
||||
'Cupidatat reprehenderit aliqua eiusmod Lorem. '
|
||||
'Qui ipsum id ea ea nulla labore aute ullamco aute '
|
||||
'quis elit ut amet velit. Incididunt fugiat proident '
|
||||
|
@ -44,7 +44,7 @@ class PortfolioCards extends StatelessWidget {
|
||||
fit: BoxFit.cover,
|
||||
)
|
||||
],
|
||||
keyword: const [
|
||||
keywords: const [
|
||||
TextWrapper('UI Design'),
|
||||
TextWrapper('Developpement'),
|
||||
TextWrapper('Deploiement')
|
||||
@ -52,7 +52,7 @@ class PortfolioCards extends StatelessWidget {
|
||||
),
|
||||
const Gap(20),
|
||||
PortfolioCard(
|
||||
showImagesOnTop: true,
|
||||
showAssetsOnTop: true,
|
||||
logo: const FlutterLogo(
|
||||
size: 50,
|
||||
),
|
||||
@ -115,7 +115,7 @@ class PortfolioCards extends StatelessWidget {
|
||||
fit: BoxFit.cover,
|
||||
)
|
||||
],
|
||||
keyword: const [
|
||||
keywords: const [
|
||||
TextWrapper('UI Design'),
|
||||
TextWrapper('Developpement'),
|
||||
TextWrapper('Deploiement')
|
||||
@ -163,7 +163,7 @@ class PortfolioCards extends StatelessWidget {
|
||||
fit: BoxFit.cover,
|
||||
)
|
||||
],
|
||||
keyword: const [
|
||||
keywords: const [
|
||||
TextWrapper('UI Design'),
|
||||
TextWrapper('Developpement'),
|
||||
TextWrapper('Deploiement')
|
||||
|
@ -33,33 +33,33 @@ class QuoteCards extends StatelessWidget {
|
||||
Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
children: const [
|
||||
QuoteCard(
|
||||
quote: 'Cupidatat reprehenderit aliqua eiusmod Lorem. '
|
||||
quote:
|
||||
TextWrapper('Cupidatat reprehenderit aliqua eiusmod Lorem. '
|
||||
'Qui ipsum id ea ea nulla labore aute ullamco aute '
|
||||
'quis elit ut amet velit. Incididunt fugiat proident '
|
||||
'proident deserunt tempor Lorem cillum qui do '
|
||||
'ullamco Lorem magna ipsum. Ullamco cupidatat velit '
|
||||
.wrap(),
|
||||
'ullamco Lorem magna ipsum. Ullamco cupidatat velit '),
|
||||
),
|
||||
const Gap(20),
|
||||
Gap(20),
|
||||
QuoteCard(
|
||||
quote: 'Cupidatat reprehenderit aliqua eiusmod Lorem. '
|
||||
'Qui ipsum id ea ea nulla labore aute ullamco aute '
|
||||
'quis elit ut amet velit. Incididunt fugiat proident '
|
||||
'proident deserunt tempor Lorem cillum qui do '
|
||||
'ullamco Lorem magna ipsum. Ullamco cupidatat velit '
|
||||
.wrap(
|
||||
gradientColors: const MultiColor([
|
||||
quote: TextWrapper(
|
||||
'Cupidatat reprehenderit aliqua eiusmod Lorem. '
|
||||
'Qui ipsum id ea ea nulla labore aute ullamco aute '
|
||||
'quis elit ut amet velit. Incididunt fugiat proident '
|
||||
'proident deserunt tempor Lorem cillum qui do '
|
||||
'ullamco Lorem magna ipsum. Ullamco cupidatat velit ',
|
||||
gradientColors: MultiColor([
|
||||
Colors.red,
|
||||
Colors.orange,
|
||||
]),
|
||||
),
|
||||
avatar: const FlutterLogo(
|
||||
avatar: FlutterLogo(
|
||||
size: 40,
|
||||
),
|
||||
name: 'John Doe'.wrap(),
|
||||
subtitle: 'Agence anonyme'.wrap(),
|
||||
name: TextWrapper('John Doe'),
|
||||
subtitle: TextWrapper('Agence anonyme'),
|
||||
),
|
||||
],
|
||||
),
|
||||
|
@ -35,58 +35,61 @@ class SkillCards extends StatelessWidget {
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
SkillCard(
|
||||
gradient: const [Colors.red, Colors.orange],
|
||||
icon: Container(
|
||||
padding: const EdgeInsets.all(15),
|
||||
decoration: BoxDecoration(
|
||||
shape: BoxShape.circle,
|
||||
color: Colors.white.withOpacity(0.04),
|
||||
),
|
||||
child: const GradientIcon(
|
||||
Icons.ac_unit_sharp,
|
||||
gradient:
|
||||
LinearGradient(colors: [Colors.red, Colors.orange]),
|
||||
),
|
||||
),
|
||||
title: 'Lorem Ipsum'.wrap(),
|
||||
description: 'Cupidatat reprehenderit aliqua eiusmod Lorem. '
|
||||
'Qui ipsum id ea ea nulla labore aute ullamco aute '
|
||||
'quis elit ut amet velit. Incididunt fugiat proident '
|
||||
'proident deserunt tempor Lorem cillum qui do '
|
||||
'ullamco Lorem magna ipsum. Ullamco cupidatat velit '
|
||||
.wrap(),
|
||||
icons: [
|
||||
Container(
|
||||
padding: const EdgeInsets.all(15),
|
||||
decoration: BoxDecoration(
|
||||
shape: BoxShape.circle,
|
||||
color: Colors.white.withOpacity(0.04),
|
||||
),
|
||||
child: GradientIcon(
|
||||
icon: Icons.ac_unit_sharp,
|
||||
gradientColors:
|
||||
const MultiColor([Colors.red, Colors.orange]),
|
||||
),
|
||||
)
|
||||
],
|
||||
bulletColors: const MultiColor([Colors.red, Colors.orange]),
|
||||
title: const TextWrapper('Lorem Ipsum'),
|
||||
description: const TextWrapper(
|
||||
'Cupidatat reprehenderit aliqua eiusmod Lorem. '
|
||||
'Qui ipsum id ea ea nulla labore aute ullamco aute '
|
||||
'quis elit ut amet velit. Incididunt fugiat proident '
|
||||
'proident deserunt tempor Lorem cillum qui do '
|
||||
'ullamco Lorem magna ipsum. Ullamco cupidatat velit '),
|
||||
skills: const [
|
||||
TextWrapper.text('Firebase'),
|
||||
TextWrapper.text(
|
||||
TextWrapper('Firebase'),
|
||||
TextWrapper(
|
||||
'Qui ipsum id ea ea nulla labore aute ullamco aute ',
|
||||
),
|
||||
],
|
||||
),
|
||||
const Gap(20),
|
||||
SkillCard(
|
||||
gradient: const [Colors.blue, Colors.green],
|
||||
icon: Container(
|
||||
padding: const EdgeInsets.all(15),
|
||||
decoration: BoxDecoration(
|
||||
shape: BoxShape.circle,
|
||||
color: Colors.white.withOpacity(0.04),
|
||||
),
|
||||
child: const GradientIcon(
|
||||
Icons.ac_unit_sharp,
|
||||
gradient: LinearGradient(
|
||||
colors: [Colors.blue, Colors.green],
|
||||
icons: [
|
||||
Container(
|
||||
padding: const EdgeInsets.all(15),
|
||||
decoration: BoxDecoration(
|
||||
shape: BoxShape.circle,
|
||||
color: Colors.white.withOpacity(0.04),
|
||||
),
|
||||
),
|
||||
),
|
||||
title: 'Lorem Ipsum'.wrap(),
|
||||
description: 'Cupidatat reprehenderit aliqua eiusmod Lorem. '
|
||||
'Qui ipsum id ea ea nulla labore aute ullamco aute '
|
||||
'quis elit ut amet velit. Incididunt fugiat proident '
|
||||
'proident deserunt tempor Lorem cillum qui do '
|
||||
'ullamco Lorem magna ipsum. Ullamco cupidatat velit '
|
||||
.wrap(),
|
||||
child: GradientIcon(
|
||||
icon: Icons.ac_unit_sharp,
|
||||
gradientColors:
|
||||
const MultiColor([Colors.blue, Colors.green]),
|
||||
),
|
||||
)
|
||||
],
|
||||
bulletColors: const MultiColor([Colors.blue, Colors.green]),
|
||||
title: const TextWrapper('Lorem Ipsum'),
|
||||
description: const TextWrapper(
|
||||
'Cupidatat reprehenderit aliqua eiusmod Lorem. '
|
||||
'Qui ipsum id ea ea nulla labore aute ullamco aute '
|
||||
'quis elit ut amet velit. Incididunt fugiat proident '
|
||||
'proident deserunt tempor Lorem cillum qui do '
|
||||
'ullamco Lorem magna ipsum. Ullamco cupidatat velit '),
|
||||
skills: const [
|
||||
TextWrapper.text('Firebase'),
|
||||
TextWrapper('Firebase'),
|
||||
TextWrapper(
|
||||
'Qui ipsum id ea ea nulla labore aute ullamco aute ',
|
||||
gradientColors: MultiColor([
|
||||
@ -94,11 +97,11 @@ class SkillCards extends StatelessWidget {
|
||||
Colors.orange,
|
||||
]),
|
||||
),
|
||||
TextWrapper.text('Firebase'),
|
||||
TextWrapper.text('Firebase'),
|
||||
TextWrapper.text('Firebase'),
|
||||
TextWrapper.text('Firebase'),
|
||||
TextWrapper.text('Firebase'),
|
||||
TextWrapper('Firebase'),
|
||||
TextWrapper('Firebase'),
|
||||
TextWrapper('Firebase'),
|
||||
TextWrapper('Firebase'),
|
||||
TextWrapper('Firebase'),
|
||||
],
|
||||
),
|
||||
],
|
||||
|
@ -75,7 +75,7 @@ class _TextInputsCoreState extends State<TextInputsCore> {
|
||||
key: _formKey6,
|
||||
controller: _controller6,
|
||||
focusNode: _focusNode6,
|
||||
label: 'Nom / Prénom'.wrap(),
|
||||
label: const TextWrapper('Nom / Prénom'),
|
||||
onError: (value) => 'Erreur : ${value.length} > 5.',
|
||||
validator: (value) => value.length > 5,
|
||||
),
|
||||
@ -85,7 +85,7 @@ class _TextInputsCoreState extends State<TextInputsCore> {
|
||||
enabled: _enable,
|
||||
controller: _controller,
|
||||
focusNode: _focusNode,
|
||||
label: 'Nom / Prénom'.wrap(),
|
||||
label: const TextWrapper('Nom / Prénom'),
|
||||
onError: (value) => 'Erreur : ${value.length} > 5.',
|
||||
validator: (value) => value.length > 5,
|
||||
),
|
||||
@ -105,7 +105,7 @@ class _TextInputsCoreState extends State<TextInputsCore> {
|
||||
controller: _controller3,
|
||||
focusNode: _focusNode3,
|
||||
expand: false,
|
||||
label: 'Nom / Prénom'.wrap(),
|
||||
label: const TextWrapper('Nom / Prénom'),
|
||||
onError: (value) => 'Erreur : ${value.length} > 5.',
|
||||
validator: (value) => value.length > 5,
|
||||
onChanged: (value) {},
|
||||
@ -116,7 +116,7 @@ class _TextInputsCoreState extends State<TextInputsCore> {
|
||||
expand: false,
|
||||
controller: _controller4,
|
||||
focusNode: _focusNode4,
|
||||
label: 'Nom / Prénom'.wrap(),
|
||||
label: const TextWrapper('Nom / Prénom'),
|
||||
maxLines: 3,
|
||||
onError: (value) => 'Erreur : ${value.length} > 5.',
|
||||
validator: (value) => value.length > 5,
|
||||
@ -129,7 +129,7 @@ class _TextInputsCoreState extends State<TextInputsCore> {
|
||||
suffixIcon: const Icon(Icons.architecture),
|
||||
controller: _controller5,
|
||||
focusNode: _focusNode5,
|
||||
label: 'Nom / Prénom'.wrap(),
|
||||
label: const TextWrapper('Nom / Prénom'),
|
||||
onError: (value) => 'Erreur : ${value.length} > 5.',
|
||||
validator: (value) => value.length > 5,
|
||||
),
|
||||
|
@ -1,127 +0,0 @@
|
||||
// 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:google_fonts/google_fonts.dart';
|
||||
import 'package:wyatt_ui_components/wyatt_ui_components.dart';
|
||||
import 'package:wyatt_ui_kit/wyatt_ui_kit.dart';
|
||||
|
||||
class CardTheme extends CardThemeExtension {
|
||||
const CardTheme({
|
||||
super.backgroundColors,
|
||||
super.body,
|
||||
super.borderColors,
|
||||
super.secondaryBackgroundColor,
|
||||
super.shadowColor,
|
||||
super.subtitle,
|
||||
super.title,
|
||||
});
|
||||
|
||||
factory CardTheme.light() => CardTheme(
|
||||
backgroundColors: const MultiColor.single(Color(0xFFF6F6F6)),
|
||||
secondaryBackgroundColor: Colors.white,
|
||||
borderColors: const MultiColor([
|
||||
Color(0xFFDDE0E3),
|
||||
Color(0xFFCACCD4),
|
||||
]),
|
||||
title: GoogleFonts.montserrat(
|
||||
fontSize: 24,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: const Color(0xFF24262A),
|
||||
),
|
||||
subtitle: GoogleFonts.montserrat(
|
||||
fontSize: 15,
|
||||
fontWeight: FontWeight.w300,
|
||||
color: const Color(0xFF24262A),
|
||||
),
|
||||
body: GoogleFonts.montserrat(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w300,
|
||||
height: 1.7,
|
||||
color: const Color(0xFF24262A),
|
||||
),
|
||||
);
|
||||
|
||||
factory CardTheme.dark() => CardTheme(
|
||||
backgroundColors:
|
||||
MultiColor.single(const Color(0xFFFFFFFF).withOpacity(0.04)),
|
||||
secondaryBackgroundColor: const Color(0xFFFFFFFF).withOpacity(0.04),
|
||||
borderColors: const MultiColor([
|
||||
Color(0xFF60656A),
|
||||
Color(0xFF383C40),
|
||||
]),
|
||||
title: GoogleFonts.montserrat(
|
||||
fontSize: 24,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: const Color(0xFFFFFFFF),
|
||||
),
|
||||
subtitle: GoogleFonts.montserrat(
|
||||
fontSize: 15,
|
||||
fontWeight: FontWeight.w300,
|
||||
color: const Color(0xFFFFFFFF),
|
||||
),
|
||||
body: GoogleFonts.montserrat(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w300,
|
||||
height: 1.7,
|
||||
color: const Color(0xFFFFFFFF),
|
||||
),
|
||||
);
|
||||
|
||||
@override
|
||||
ThemeExtension<CardThemeExtension> copyWith({
|
||||
MultiColor? backgroundColors,
|
||||
Color? secondaryBackgroundColor,
|
||||
MultiColor? borderColors,
|
||||
BoxShadow? shadowColor,
|
||||
TextStyle? body,
|
||||
TextStyle? title,
|
||||
TextStyle? subtitle,
|
||||
}) =>
|
||||
CardTheme(
|
||||
backgroundColors: backgroundColors ?? this.backgroundColors,
|
||||
secondaryBackgroundColor:
|
||||
secondaryBackgroundColor ?? this.secondaryBackgroundColor,
|
||||
borderColors: borderColors ?? this.borderColors,
|
||||
shadowColor: shadowColor ?? this.shadowColor,
|
||||
body: body ?? this.body,
|
||||
title: title ?? this.title,
|
||||
subtitle: subtitle ?? this.subtitle,
|
||||
);
|
||||
|
||||
@override
|
||||
ThemeExtension<CardThemeExtension> lerp(
|
||||
covariant ThemeExtension<CardThemeExtension>? other,
|
||||
double t,
|
||||
) {
|
||||
if (other is! CardTheme) {
|
||||
return this;
|
||||
}
|
||||
return CardTheme(
|
||||
backgroundColors: other.backgroundColors,
|
||||
secondaryBackgroundColor: Color.lerp(
|
||||
secondaryBackgroundColor,
|
||||
other.secondaryBackgroundColor,
|
||||
t,
|
||||
),
|
||||
borderColors: other.borderColors,
|
||||
shadowColor: BoxShadow.lerp(shadowColor, other.shadowColor, t),
|
||||
body: TextStyle.lerp(body, other.body, t),
|
||||
title: TextStyle.lerp(title, other.title, t),
|
||||
subtitle: TextStyle.lerp(subtitle, other.subtitle, t),
|
||||
);
|
||||
}
|
||||
}
|
@ -1,172 +0,0 @@
|
||||
// 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:google_fonts/google_fonts.dart';
|
||||
import 'package:wyatt_ui_components/wyatt_ui_components.dart';
|
||||
import 'package:wyatt_ui_kit/wyatt_ui_kit.dart';
|
||||
import 'package:wyatt_ui_kit_example/theme/constants.dart';
|
||||
|
||||
class FileSelectionButtonTheme extends FileSelectionButtonThemeExtension {
|
||||
const FileSelectionButtonTheme({
|
||||
super.disabledStyle,
|
||||
super.focusedStyle,
|
||||
super.hoveredStyle,
|
||||
super.normalStyle,
|
||||
super.tappedStyle,
|
||||
super.selectedStyle,
|
||||
super.invalidStyle,
|
||||
});
|
||||
|
||||
factory FileSelectionButtonTheme.light() {
|
||||
final style = FileSelectionButtonStyle(
|
||||
title: GoogleFonts.montserrat(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w400,
|
||||
),
|
||||
subTitle: GoogleFonts.montserrat(
|
||||
fontSize: 11,
|
||||
fontWeight: FontWeight.w400,
|
||||
),
|
||||
radius: BorderRadius.circular(12),
|
||||
padding: const EdgeInsets.all(13),
|
||||
foregroundColors: const MultiColor.single(Constants.grey2),
|
||||
backgroundColors: MultiColor.single(Constants.white.withOpacity(0.04)),
|
||||
borderColors: const MultiColor(Constants.greyGradient),
|
||||
stroke: 2,
|
||||
);
|
||||
return FileSelectionButtonTheme(
|
||||
normalStyle: style,
|
||||
disabledStyle: style.copyWith(
|
||||
foregroundColors: MultiColor.single(Constants.grey1.withOpacity(0.4)),
|
||||
backgroundColors: const MultiColor.single(Constants.white),
|
||||
borderColors: MultiColor.single(Constants.grey1.withOpacity(0.4)),
|
||||
),
|
||||
hoveredStyle: style.copyWith(
|
||||
backgroundColors: MultiColor.single(Constants.grey1.withOpacity(0.4)),
|
||||
),
|
||||
focusedStyle: style.copyWith(stroke: 4),
|
||||
tappedStyle: style.copyWith(
|
||||
backgroundColors: MultiColor.single(Constants.grey1.withOpacity(0.4)),
|
||||
),
|
||||
invalidStyle: style.copyWith(
|
||||
subTitle: GoogleFonts.montserrat(
|
||||
fontSize: 11,
|
||||
fontWeight: FontWeight.w400,
|
||||
color: Constants.red1,
|
||||
),
|
||||
borderColors: const MultiColor(Constants.redGradient),
|
||||
),
|
||||
// Unused
|
||||
selectedStyle: style.copyWith(
|
||||
foregroundColors: const MultiColor.single(Constants.grey2),
|
||||
borderColors: const MultiColor(Constants.greenGradient),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
factory FileSelectionButtonTheme.dark() {
|
||||
final style = FileSelectionButtonStyle(
|
||||
title: GoogleFonts.montserrat(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w400,
|
||||
),
|
||||
subTitle: GoogleFonts.montserrat(
|
||||
fontSize: 11,
|
||||
fontWeight: FontWeight.w400,
|
||||
),
|
||||
radius: BorderRadius.circular(12),
|
||||
padding: const EdgeInsets.all(13),
|
||||
foregroundColors: const MultiColor.single(Constants.white),
|
||||
backgroundColors: MultiColor.single(Constants.white.withOpacity(0.04)),
|
||||
borderColors: const MultiColor(Constants.greyGradient),
|
||||
stroke: 1,
|
||||
);
|
||||
return FileSelectionButtonTheme(
|
||||
normalStyle: style,
|
||||
disabledStyle: style.copyWith(
|
||||
foregroundColors: const MultiColor.single(Constants.grey1),
|
||||
backgroundColors: const MultiColor.single(Constants.grey4),
|
||||
),
|
||||
hoveredStyle: style.copyWith(
|
||||
borderColors: const MultiColor.single(Constants.white),
|
||||
),
|
||||
focusedStyle: style.copyWith(stroke: 3),
|
||||
tappedStyle: style.copyWith(
|
||||
backgroundColors: const MultiColor(Constants.greyDarkGradient),
|
||||
),
|
||||
invalidStyle: style.copyWith(
|
||||
subTitle: GoogleFonts.montserrat(
|
||||
fontSize: 11,
|
||||
fontWeight: FontWeight.w400,
|
||||
color: Constants.red1,
|
||||
),
|
||||
borderColors: const MultiColor(Constants.redGradient),
|
||||
),
|
||||
// Unused
|
||||
selectedStyle: style.copyWith(
|
||||
foregroundColors: const MultiColor.single(Constants.white),
|
||||
borderColors: const MultiColor(Constants.greenGradient),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
ThemeExtension<FileSelectionButtonThemeExtension> copyWith({
|
||||
FileSelectionButtonStyle? disabledStyle,
|
||||
FileSelectionButtonStyle? focusedStyle,
|
||||
FileSelectionButtonStyle? hoveredStyle,
|
||||
FileSelectionButtonStyle? normalStyle,
|
||||
FileSelectionButtonStyle? tappedStyle,
|
||||
FileSelectionButtonStyle? selectedStyle,
|
||||
FileSelectionButtonStyle? invalidStyle,
|
||||
}) =>
|
||||
FileSelectionButtonTheme(
|
||||
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! FileSelectionButtonTheme) {
|
||||
return this;
|
||||
}
|
||||
return FileSelectionButtonTheme(
|
||||
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),
|
||||
);
|
||||
}
|
||||
}
|
@ -1,153 +0,0 @@
|
||||
// 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:google_fonts/google_fonts.dart';
|
||||
import 'package:wyatt_ui_components/wyatt_ui_components.dart';
|
||||
import 'package:wyatt_ui_kit/wyatt_ui_kit.dart';
|
||||
import 'package:wyatt_ui_kit_example/theme/constants.dart';
|
||||
|
||||
class FlatButtonTheme extends FlatButtonThemeExtension {
|
||||
const FlatButtonTheme({
|
||||
super.disabledStyle,
|
||||
super.focusedStyle,
|
||||
super.hoveredStyle,
|
||||
super.normalStyle,
|
||||
super.tappedStyle,
|
||||
});
|
||||
|
||||
factory FlatButtonTheme.light() {
|
||||
final style = FlatButtonStyle(
|
||||
label: GoogleFonts.montserrat(
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
radius: BorderRadius.circular(15),
|
||||
padding: const EdgeInsets.all(10),
|
||||
foregroundColors: const MultiColor(Constants.blueGradient),
|
||||
backgroundColors: const MultiColor.single(Constants.white),
|
||||
borderColors: const MultiColor(Constants.blueGradient),
|
||||
stroke: 3,
|
||||
);
|
||||
return FlatButtonTheme(
|
||||
normalStyle: style,
|
||||
disabledStyle: style.copyWith(
|
||||
label: GoogleFonts.montserrat(
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Constants.blue1.withOpacity(0.4),
|
||||
),
|
||||
foregroundColors: MultiColor.single(Constants.blue1.withOpacity(0.4)),
|
||||
backgroundColors: const MultiColor.single(Constants.white),
|
||||
borderColors: MultiColor.single(Constants.blue1.withOpacity(0.4)),
|
||||
stroke: 1,
|
||||
),
|
||||
hoveredStyle: style.copyWith(
|
||||
label: GoogleFonts.montserrat(
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Constants.white,
|
||||
),
|
||||
foregroundColors: const MultiColor.single(Constants.white),
|
||||
backgroundColors: const MultiColor(Constants.blueGradient),
|
||||
),
|
||||
focusedStyle: style.copyWith(stroke: 5),
|
||||
tappedStyle: style.copyWith(
|
||||
label: GoogleFonts.montserrat(
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Constants.white,
|
||||
),
|
||||
foregroundColors: const MultiColor.single(Constants.white),
|
||||
backgroundColors: const MultiColor(Constants.blueDarkGradient),
|
||||
borderColors: const MultiColor(Constants.blueDarkGradient),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
factory FlatButtonTheme.dark() {
|
||||
final style = FlatButtonStyle(
|
||||
label: GoogleFonts.montserrat(
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
radius: BorderRadius.circular(15),
|
||||
padding: const EdgeInsets.all(10),
|
||||
foregroundColors: const MultiColor.single(Constants.white),
|
||||
backgroundColors: const MultiColor.single(Constants.dark),
|
||||
borderColors: const MultiColor(Constants.blueGradient),
|
||||
stroke: 3,
|
||||
);
|
||||
return FlatButtonTheme(
|
||||
normalStyle: style,
|
||||
disabledStyle: style.copyWith(
|
||||
label: GoogleFonts.montserrat(
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Constants.grey1,
|
||||
),
|
||||
foregroundColors: const MultiColor.single(Constants.grey1),
|
||||
backgroundColors: const MultiColor.single(Constants.grey4),
|
||||
borderColors: const MultiColor(Constants.greyGradient),
|
||||
stroke: 1,
|
||||
),
|
||||
hoveredStyle: style.copyWith(
|
||||
foregroundColors: const MultiColor.single(Constants.white),
|
||||
backgroundColors: const MultiColor(Constants.blueGradient),
|
||||
),
|
||||
focusedStyle: style.copyWith(stroke: 5),
|
||||
tappedStyle: style.copyWith(
|
||||
foregroundColors: const MultiColor.single(Constants.white),
|
||||
backgroundColors: const MultiColor(Constants.blueDarkGradient),
|
||||
borderColors: const MultiColor(Constants.blueDarkGradient),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
ThemeExtension<FlatButtonThemeExtension> copyWith({
|
||||
FlatButtonStyle? disabledStyle,
|
||||
FlatButtonStyle? focusedStyle,
|
||||
FlatButtonStyle? hoveredStyle,
|
||||
FlatButtonStyle? normalStyle,
|
||||
FlatButtonStyle? tappedStyle,
|
||||
}) =>
|
||||
FlatButtonTheme(
|
||||
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! FlatButtonTheme) {
|
||||
return this;
|
||||
}
|
||||
return FlatButtonTheme(
|
||||
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),
|
||||
);
|
||||
}
|
||||
}
|
@ -1,157 +0,0 @@
|
||||
// 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:google_fonts/google_fonts.dart';
|
||||
import 'package:wyatt_ui_components/wyatt_ui_components.dart';
|
||||
import 'package:wyatt_ui_kit/wyatt_ui_kit.dart';
|
||||
import 'package:wyatt_ui_kit_example/theme/constants.dart';
|
||||
|
||||
class SymbolButtonTheme extends SymbolButtonThemeExtension {
|
||||
const SymbolButtonTheme({
|
||||
super.disabledStyle,
|
||||
super.focusedStyle,
|
||||
super.hoveredStyle,
|
||||
super.normalStyle,
|
||||
super.tappedStyle,
|
||||
super.selectedStyle,
|
||||
});
|
||||
|
||||
factory SymbolButtonTheme.light() {
|
||||
final style = SymbolButtonStyle(
|
||||
label: GoogleFonts.montserrat(
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.w400,
|
||||
),
|
||||
dimension: 60,
|
||||
radius: BorderRadius.circular(12),
|
||||
padding: const EdgeInsets.all(10),
|
||||
foregroundColors: const MultiColor.single(Constants.grey2),
|
||||
backgroundColors: MultiColor.single(Constants.white.withOpacity(0.04)),
|
||||
borderColors: const MultiColor(Constants.greyGradient),
|
||||
stroke: 2,
|
||||
);
|
||||
return SymbolButtonTheme(
|
||||
normalStyle: style,
|
||||
disabledStyle: style.copyWith(
|
||||
label: GoogleFonts.montserrat(
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.w400,
|
||||
color: Constants.grey1,
|
||||
),
|
||||
foregroundColors: MultiColor.single(Constants.grey1.withOpacity(0.4)),
|
||||
backgroundColors: const MultiColor.single(Constants.white),
|
||||
borderColors: MultiColor.single(Constants.grey1.withOpacity(0.4)),
|
||||
),
|
||||
hoveredStyle: style.copyWith(
|
||||
backgroundColors: MultiColor.single(Constants.grey1.withOpacity(0.4)),
|
||||
),
|
||||
focusedStyle: style.copyWith(stroke: 4),
|
||||
tappedStyle: style.copyWith(
|
||||
backgroundColors: MultiColor.single(Constants.grey1.withOpacity(0.4)),
|
||||
),
|
||||
selectedStyle: style.copyWith(
|
||||
label: GoogleFonts.montserrat(
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
foregroundColors: const MultiColor.single(Constants.grey2),
|
||||
borderColors: const MultiColor(Constants.greenGradient),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
factory SymbolButtonTheme.dark() {
|
||||
final style = SymbolButtonStyle(
|
||||
label: GoogleFonts.montserrat(
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.w400,
|
||||
),
|
||||
dimension: 60,
|
||||
radius: BorderRadius.circular(12),
|
||||
padding: const EdgeInsets.all(10),
|
||||
foregroundColors: const MultiColor.single(Constants.white),
|
||||
backgroundColors: MultiColor.single(Constants.white.withOpacity(0.04)),
|
||||
borderColors: const MultiColor(Constants.greyGradient),
|
||||
stroke: 2,
|
||||
);
|
||||
return SymbolButtonTheme(
|
||||
normalStyle: style,
|
||||
disabledStyle: style.copyWith(
|
||||
label: GoogleFonts.montserrat(
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.w400,
|
||||
color: Constants.grey1,
|
||||
),
|
||||
foregroundColors: const MultiColor.single(Constants.grey1),
|
||||
backgroundColors: const MultiColor.single(Constants.grey4),
|
||||
),
|
||||
hoveredStyle: style.copyWith(
|
||||
backgroundColors: const MultiColor(Constants.greyDarkGradient),
|
||||
),
|
||||
focusedStyle: style.copyWith(stroke: 4),
|
||||
tappedStyle: style.copyWith(
|
||||
backgroundColors: const MultiColor(Constants.greyDarkGradient),
|
||||
),
|
||||
selectedStyle: style.copyWith(
|
||||
label: GoogleFonts.montserrat(
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
foregroundColors: const MultiColor.single(Constants.white),
|
||||
borderColors: const MultiColor(Constants.greenGradient),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
ThemeExtension<SymbolButtonThemeExtension> copyWith({
|
||||
SymbolButtonStyle? disabledStyle,
|
||||
SymbolButtonStyle? focusedStyle,
|
||||
SymbolButtonStyle? hoveredStyle,
|
||||
SymbolButtonStyle? normalStyle,
|
||||
SymbolButtonStyle? tappedStyle,
|
||||
SymbolButtonStyle? selectedStyle,
|
||||
}) =>
|
||||
SymbolButtonTheme(
|
||||
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! SymbolButtonTheme) {
|
||||
return this;
|
||||
}
|
||||
return SymbolButtonTheme(
|
||||
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),
|
||||
);
|
||||
}
|
||||
}
|
@ -1,161 +0,0 @@
|
||||
// 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:google_fonts/google_fonts.dart';
|
||||
import 'package:wyatt_ui_components/wyatt_ui_components.dart';
|
||||
import 'package:wyatt_ui_kit/wyatt_ui_kit.dart';
|
||||
|
||||
class TextInputTheme extends TextInputThemeExtension {
|
||||
const TextInputTheme({
|
||||
super.normalStyle,
|
||||
super.focusedStyle,
|
||||
super.disableStyle,
|
||||
super.errorStyle,
|
||||
});
|
||||
|
||||
factory TextInputTheme.light() => TextInputTheme(
|
||||
normalStyle: TextInputStyle(
|
||||
radius: BorderRadius.circular(12),
|
||||
borderColors: const Color.fromRGBO(221, 224, 227, 1),
|
||||
labelStyle: GoogleFonts.montserrat(
|
||||
fontWeight: FontWeight.w300,
|
||||
color: const Color.fromRGBO(55, 65, 81, 1),
|
||||
),
|
||||
inputStyle: GoogleFonts.montserrat(
|
||||
fontWeight: FontWeight.w300,
|
||||
color: const Color.fromRGBO(55, 65, 81, 1),
|
||||
),
|
||||
),
|
||||
focusedStyle: TextInputStyle(
|
||||
radius: BorderRadius.circular(12),
|
||||
borderColors: const Color.fromRGBO(60, 125, 251, 1),
|
||||
labelStyle: GoogleFonts.montserrat(
|
||||
fontWeight: FontWeight.w300,
|
||||
color: const Color.fromRGBO(55, 65, 81, 1),
|
||||
),
|
||||
inputStyle: GoogleFonts.montserrat(
|
||||
fontWeight: FontWeight.w300,
|
||||
color: const Color.fromRGBO(55, 65, 81, 1),
|
||||
),
|
||||
),
|
||||
errorStyle: TextInputStyle(
|
||||
radius: BorderRadius.circular(12),
|
||||
borderColors: const Color.fromRGBO(244, 68, 100, 1),
|
||||
labelStyle: GoogleFonts.montserrat(
|
||||
fontWeight: FontWeight.w300,
|
||||
color: const Color.fromRGBO(244, 68, 100, 1),
|
||||
),
|
||||
inputStyle: GoogleFonts.montserrat(
|
||||
fontWeight: FontWeight.w300,
|
||||
color: const Color.fromRGBO(55, 65, 81, 1),
|
||||
),
|
||||
),
|
||||
disableStyle: TextInputStyle(
|
||||
radius: BorderRadius.circular(12),
|
||||
borderColors: const Color.fromRGBO(229, 231, 235, 1),
|
||||
labelStyle: GoogleFonts.montserrat(
|
||||
fontWeight: FontWeight.w300,
|
||||
color: const Color.fromRGBO(156, 163, 175, 1),
|
||||
),
|
||||
inputStyle: GoogleFonts.montserrat(
|
||||
fontWeight: FontWeight.w300,
|
||||
color: const Color.fromRGBO(156, 163, 175, 1),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
factory TextInputTheme.dark() => TextInputTheme(
|
||||
normalStyle: TextInputStyle(
|
||||
radius: BorderRadius.circular(12),
|
||||
borderColors: const Color.fromRGBO(96, 101, 106, 1),
|
||||
labelStyle: GoogleFonts.montserrat(
|
||||
fontWeight: FontWeight.w300,
|
||||
color: const Color.fromRGBO(204, 204, 204, 1),
|
||||
),
|
||||
inputStyle: GoogleFonts.montserrat(
|
||||
fontWeight: FontWeight.w300,
|
||||
color: const Color.fromRGBO(255, 255, 255, 1),
|
||||
),
|
||||
),
|
||||
focusedStyle: TextInputStyle(
|
||||
radius: BorderRadius.circular(12),
|
||||
borderColors: const Color.fromRGBO(60, 125, 251, 1),
|
||||
labelStyle: GoogleFonts.montserrat(
|
||||
fontWeight: FontWeight.w300,
|
||||
color: const Color.fromRGBO(204, 204, 204, 1),
|
||||
),
|
||||
inputStyle: GoogleFonts.montserrat(
|
||||
fontWeight: FontWeight.w300,
|
||||
color: const Color.fromRGBO(255, 255, 255, 1),
|
||||
),
|
||||
),
|
||||
errorStyle: TextInputStyle(
|
||||
radius: BorderRadius.circular(12),
|
||||
borderColors: const Color.fromRGBO(244, 68, 100, 1),
|
||||
labelStyle: GoogleFonts.montserrat(
|
||||
fontWeight: FontWeight.w300,
|
||||
color: const Color.fromRGBO(244, 68, 100, 1),
|
||||
),
|
||||
inputStyle: GoogleFonts.montserrat(
|
||||
fontWeight: FontWeight.w300,
|
||||
color: const Color.fromRGBO(255, 255, 255, 1),
|
||||
),
|
||||
),
|
||||
disableStyle: TextInputStyle(
|
||||
radius: BorderRadius.circular(12),
|
||||
borderColors: const Color.fromRGBO(96, 101, 106, 1),
|
||||
labelStyle: GoogleFonts.montserrat(
|
||||
fontWeight: FontWeight.w300,
|
||||
color: const Color.fromRGBO(96, 101, 106, 1),
|
||||
),
|
||||
inputStyle: GoogleFonts.montserrat(
|
||||
fontWeight: FontWeight.w300,
|
||||
color: const Color.fromRGBO(255, 255, 255, 1),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
@override
|
||||
ThemeExtension<TextInputThemeExtension> lerp(
|
||||
covariant ThemeExtension<TextInputThemeExtension>? other,
|
||||
double t,
|
||||
) {
|
||||
if (other is! TextInputTheme) {
|
||||
return this;
|
||||
}
|
||||
return TextInputTheme(
|
||||
normalStyle: TextInputStyle.lerp(normalStyle, other.normalStyle, t),
|
||||
focusedStyle: TextInputStyle.lerp(focusedStyle, other.focusedStyle, t),
|
||||
disableStyle: TextInputStyle.lerp(disableStyle, other.disableStyle, t),
|
||||
errorStyle: TextInputStyle.lerp(errorStyle, other.errorStyle, t),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
ThemeExtension<TextInputThemeExtension> copyWith({
|
||||
TextInputStyle? normalStyle,
|
||||
TextInputStyle? focusedStyle,
|
||||
TextInputStyle? disableStyle,
|
||||
TextInputStyle? errorStyle,
|
||||
}) =>
|
||||
TextInputTheme(
|
||||
normalStyle: normalStyle ?? this.normalStyle,
|
||||
focusedStyle: focusedStyle ?? this.focusedStyle,
|
||||
disableStyle: disableStyle ?? this.disableStyle,
|
||||
errorStyle: errorStyle ?? this.errorStyle,
|
||||
);
|
||||
}
|
@ -17,24 +17,20 @@
|
||||
import 'package:adaptive_theme/adaptive_theme.dart';
|
||||
import 'package:flutter/material.dart' hide CardTheme;
|
||||
import 'package:google_fonts/google_fonts.dart';
|
||||
import 'package:wyatt_ui_kit_example/theme/card_theme.dart';
|
||||
import 'package:wyatt_ui_kit_example/theme/file_selection_button_theme.dart';
|
||||
import 'package:wyatt_ui_kit_example/theme/flat_button_theme.dart';
|
||||
import 'package:wyatt_ui_components/wyatt_ui_components.dart';
|
||||
import 'package:wyatt_ui_kit/wyatt_ui_kit.dart';
|
||||
import 'package:wyatt_ui_kit_example/theme/loader_theme.dart';
|
||||
import 'package:wyatt_ui_kit_example/theme/rich_text_builder_theme.dart';
|
||||
import 'package:wyatt_ui_kit_example/theme/simple_icon_button_theme.dart';
|
||||
import 'package:wyatt_ui_kit_example/theme/symbol_button_theme.dart';
|
||||
import 'package:wyatt_ui_kit_example/theme/text_input_theme.dart';
|
||||
import 'package:wyatt_ui_kit_example/theme/top_bar_theme.dart';
|
||||
|
||||
/// Easely switch between Material and Studio themes.
|
||||
abstract class Themes {
|
||||
static int currentThemeIndex = 0;
|
||||
|
||||
static List<Set<ThemeData>> themes = [
|
||||
{materialLight, materialDark},
|
||||
{studioLight, studioDark},
|
||||
];
|
||||
static List<Set<ThemeData>> get themes => [
|
||||
{materialLight, materialDark},
|
||||
{studioLight, studioDark},
|
||||
];
|
||||
|
||||
static ThemeData lightFromTheme(int themeId) {
|
||||
currentThemeIndex = themeId;
|
||||
@ -67,66 +63,114 @@ abstract class Themes {
|
||||
);
|
||||
}
|
||||
|
||||
static ThemeData get materialLight => ThemeData.light();
|
||||
|
||||
static ThemeData get studioLight => materialLight.copyWith(
|
||||
appBarTheme: AppBarTheme(
|
||||
foregroundColor: const Color(0xFF24262A),
|
||||
backgroundColor: const Color(0xFFFFFFFF),
|
||||
titleTextStyle: GoogleFonts.montserrat(
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: const Color(0xFF24262A),
|
||||
),
|
||||
static ThemeData get materialLight => ThemeData.light().copyWith(
|
||||
textTheme: GoogleFonts.robotoTextTheme(
|
||||
ThemeData.light().textTheme,
|
||||
),
|
||||
scaffoldBackgroundColor: Colors.white,
|
||||
extensions: <ThemeExtension<dynamic>>[
|
||||
// Cards
|
||||
CardTheme.light(),
|
||||
CardThemeExtensionDefault.light(),
|
||||
// Buttons
|
||||
FlatButtonTheme.light(),
|
||||
SymbolButtonTheme.light(),
|
||||
SimpleIconButtonTheme.light(),
|
||||
FileSelectionButtonTheme.light(),
|
||||
// Loader
|
||||
LoaderTheme.light(),
|
||||
// Rich Text
|
||||
RichTextBuilderTheme.light(),
|
||||
TextInputTheme.light(),
|
||||
TopAppBarTheme.light(),
|
||||
FileSelectionButtonThemeExtensionDefault.light(),
|
||||
FlatButtonThemeExtensionDefault.light(),
|
||||
SimpleIconButtonThemeExtensionDefault.light(),
|
||||
SymbolButtonThemeExtensionDefault.light(),
|
||||
// TextInput
|
||||
TextInputThemeExtensionDefault.light(),
|
||||
],
|
||||
);
|
||||
|
||||
static ThemeData get materialDark => ThemeData.dark();
|
||||
static ThemeData get studioLight {
|
||||
final theme = ThemeData.light().copyWith(
|
||||
appBarTheme: AppBarTheme(
|
||||
foregroundColor: const Color(0xFF24262A),
|
||||
backgroundColor: const Color(0xFFFFFFFF),
|
||||
titleTextStyle: GoogleFonts.montserrat(
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: const Color(0xFF24262A),
|
||||
),
|
||||
),
|
||||
scaffoldBackgroundColor: Colors.white,
|
||||
textTheme: GoogleFonts.montserratTextTheme(
|
||||
ThemeData.light().textTheme,
|
||||
),
|
||||
);
|
||||
|
||||
static ThemeData get studioDark => materialDark.copyWith(
|
||||
appBarTheme: AppBarTheme(
|
||||
foregroundColor: const Color(0xFFFFFFFF),
|
||||
backgroundColor: const Color(0xFF383C40),
|
||||
titleTextStyle: GoogleFonts.montserrat(
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: const Color(0xFFFFFFFF),
|
||||
),
|
||||
return theme.copyWith(
|
||||
extensions: <ThemeExtension<dynamic>>[
|
||||
// Cards
|
||||
CardThemeExtensionImpl.light(theme: theme),
|
||||
// Buttons
|
||||
FileSelectionButtonThemeExtensionImpl.light(theme: theme),
|
||||
FlatButtonThemeExtensionImpl.light(theme: theme),
|
||||
SimpleIconButtonThemeExtensionImpl.light(theme: theme),
|
||||
SymbolButtonThemeExtensionImpl.light(theme: theme),
|
||||
// Loader
|
||||
LoaderTheme.light(),
|
||||
// Rich Text
|
||||
RichTextBuilderTheme.light(),
|
||||
// TextInput
|
||||
TextInputThemeExtensionImpl.light(theme: theme),
|
||||
TopAppBarTheme.light(),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
static ThemeData get materialDark => ThemeData.dark().copyWith(
|
||||
textTheme: GoogleFonts.robotoTextTheme(
|
||||
ThemeData.dark().textTheme,
|
||||
),
|
||||
drawerTheme: const DrawerThemeData(
|
||||
backgroundColor: Color(0xFF383C40),
|
||||
),
|
||||
scaffoldBackgroundColor: const Color(0xFF383C40),
|
||||
extensions: <ThemeExtension<dynamic>>[
|
||||
// Cards
|
||||
CardTheme.dark(),
|
||||
CardThemeExtensionDefault.dark(),
|
||||
// Buttons
|
||||
FlatButtonTheme.dark(),
|
||||
SymbolButtonTheme.dark(),
|
||||
SimpleIconButtonTheme.dark(),
|
||||
FileSelectionButtonTheme.dark(),
|
||||
// Loader
|
||||
LoaderTheme.dark(),
|
||||
// Rich Text
|
||||
RichTextBuilderTheme.dark(),
|
||||
TextInputTheme.dark(),
|
||||
TopAppBarTheme.dark(),
|
||||
FileSelectionButtonThemeExtensionDefault.dark(),
|
||||
FlatButtonThemeExtensionDefault.dark(),
|
||||
SimpleIconButtonThemeExtensionDefault.dark(),
|
||||
SymbolButtonThemeExtensionDefault.dark(),
|
||||
// TextInput
|
||||
TextInputThemeExtensionDefault.dark(),
|
||||
],
|
||||
);
|
||||
|
||||
static ThemeData get studioDark {
|
||||
final theme = ThemeData.dark().copyWith(
|
||||
appBarTheme: AppBarTheme(
|
||||
foregroundColor: const Color(0xFFFFFFFF),
|
||||
backgroundColor: const Color(0xFF2B3139),
|
||||
titleTextStyle: GoogleFonts.montserrat(
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: const Color(0xFFFFFFFF),
|
||||
),
|
||||
),
|
||||
drawerTheme: const DrawerThemeData(
|
||||
backgroundColor: Color(0xFF383C40),
|
||||
),
|
||||
scaffoldBackgroundColor: const Color(0xFF171A1E),
|
||||
textTheme: GoogleFonts.montserratTextTheme(
|
||||
ThemeData.dark().textTheme,
|
||||
),
|
||||
);
|
||||
|
||||
return theme.copyWith(
|
||||
extensions: <ThemeExtension<dynamic>>[
|
||||
// Cards
|
||||
CardThemeExtensionImpl.dark(theme: theme),
|
||||
// Buttons
|
||||
FileSelectionButtonThemeExtensionImpl.dark(theme: theme),
|
||||
FlatButtonThemeExtensionImpl.dark(theme: theme),
|
||||
SimpleIconButtonThemeExtensionImpl.dark(theme: theme),
|
||||
SymbolButtonThemeExtensionImpl.dark(theme: theme),
|
||||
// Loader
|
||||
LoaderTheme.dark(),
|
||||
// Rich Text
|
||||
RichTextBuilderTheme.dark(),
|
||||
// TextInput
|
||||
TextInputThemeExtensionImpl.dark(theme: theme),
|
||||
TopAppBarTheme.dark(),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -8,5 +8,7 @@
|
||||
<true/>
|
||||
<key>com.apple.security.network.server</key>
|
||||
<true/>
|
||||
<key>com.apple.security.network.client</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
||||
|
@ -1,10 +1,12 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>com.apple.security.network.client</key>
|
||||
<true/>
|
||||
<key>com.apple.security.app-sandbox</key>
|
||||
<true/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>com.apple.security.network.client</key>
|
||||
<true/>
|
||||
<key>com.apple.security.app-sandbox</key>
|
||||
<true/>
|
||||
<key>com.apple.security.network.client</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
||||
|
@ -50,16 +50,16 @@ class TopAppBar extends TopAppBarComponent with $TopAppBarCWMixin {
|
||||
@override
|
||||
Widget build(BuildContext context) => DecoratedBox(
|
||||
decoration: BoxDecoration(
|
||||
gradient: ThemeHelper.getThemeElement<MultiColor, Gradient>(
|
||||
gradient: ThemeHelper.maybeGetElement<MultiColor, Gradient>(
|
||||
[
|
||||
backgroundColor,
|
||||
context.themeExtension<TopBarThemeExtension>()?.backgroundColors,
|
||||
],
|
||||
valueValidator: (value) => value?.isGradient,
|
||||
transform: (value) =>
|
||||
LinearGradientHelper.fromNullableColors(value?.colors),
|
||||
GradientHelper.linearFromNullableColors(value?.colors),
|
||||
),
|
||||
color: ThemeHelper.getThemeElement<MultiColor, Color>(
|
||||
color: ThemeHelper.maybeGetElement<MultiColor, Color>(
|
||||
[
|
||||
backgroundColor,
|
||||
context.themeExtension<TopBarThemeExtension>()?.backgroundColors,
|
||||
@ -82,8 +82,7 @@ class TopAppBar extends TopAppBarComponent with $TopAppBarCWMixin {
|
||||
scrolledUnderElevation: scrolledUnderElevation,
|
||||
shadowColor: shadowColor,
|
||||
surfaceTintColor: surfaceTintColor,
|
||||
iconTheme:
|
||||
ThemeHelper.getThemeElement<IconThemeData, IconThemeData>(
|
||||
iconTheme: ThemeHelper.getElement<IconThemeData, IconThemeData>(
|
||||
[
|
||||
iconTheme,
|
||||
context.themeExtension<TopBarThemeExtension>()?.iconTheme,
|
||||
@ -95,9 +94,9 @@ class TopAppBar extends TopAppBarComponent with $TopAppBarCWMixin {
|
||||
primary: primary ?? true,
|
||||
excludeHeaderSemantics: excludeHeaderSemantics ?? false,
|
||||
leadingWidth: leadingWidth,
|
||||
title: Text(
|
||||
title?.data ?? '',
|
||||
style: ThemeHelper.getThemeElement<TextStyle, TextStyle>(
|
||||
title: GradientText(
|
||||
data: title?.data ?? '',
|
||||
style: ThemeHelper.getElement<TextStyle, TextStyle>(
|
||||
[
|
||||
context.textTheme.titleLarge,
|
||||
context.themeExtension<TopBarThemeExtension>()?.titleStyle,
|
||||
@ -107,14 +106,15 @@ class TopAppBar extends TopAppBarComponent with $TopAppBarCWMixin {
|
||||
combine: (p0, p1) => p0?.merge(p1),
|
||||
transform: (value) => value,
|
||||
),
|
||||
).toGradient(gradientColors: title?.gradientColors),
|
||||
gradientColors: const MultiColor([]),
|
||||
),
|
||||
leading: leading,
|
||||
actions: actions,
|
||||
centerTitle: centerTitle ?? false,
|
||||
),
|
||||
if (expandedWidget != null)
|
||||
...ListTile.divideTiles(
|
||||
color: ThemeHelper.getThemeElement<Color, Color>(
|
||||
color: ThemeHelper.getElement<Color, Color>(
|
||||
[
|
||||
context
|
||||
.themeExtension<TopBarThemeExtension>()
|
||||
|
@ -54,16 +54,16 @@ class TopNavigationBar extends TopNavigationBarComponent
|
||||
@override
|
||||
Widget build(BuildContext context) => DecoratedBox(
|
||||
decoration: BoxDecoration(
|
||||
gradient: ThemeHelper.getThemeElement<MultiColor, Gradient>(
|
||||
gradient: ThemeHelper.maybeGetElement<MultiColor, Gradient>(
|
||||
[
|
||||
backgroundColor,
|
||||
context.themeExtension<TopBarThemeExtension>()?.backgroundColors,
|
||||
],
|
||||
valueValidator: (value) => value?.isGradient,
|
||||
transform: (value) =>
|
||||
LinearGradientHelper.fromNullableColors(value?.colors),
|
||||
GradientHelper.linearFromNullableColors(value?.colors),
|
||||
),
|
||||
color: ThemeHelper.getThemeElement<MultiColor, Color>(
|
||||
color: ThemeHelper.maybeGetElement<MultiColor, Color>(
|
||||
[
|
||||
backgroundColor,
|
||||
context.themeExtension<TopBarThemeExtension>()?.backgroundColors,
|
||||
@ -85,7 +85,7 @@ class TopNavigationBar extends TopNavigationBarComponent
|
||||
scrolledUnderElevation: scrolledUnderElevation,
|
||||
shadowColor: shadowColor,
|
||||
surfaceTintColor: surfaceTintColor,
|
||||
iconTheme: ThemeHelper.getThemeElement<IconThemeData, IconThemeData>(
|
||||
iconTheme: ThemeHelper.getElement<IconThemeData, IconThemeData>(
|
||||
[
|
||||
iconTheme,
|
||||
context.themeExtension<TopBarThemeExtension>()?.iconTheme,
|
||||
|
@ -33,7 +33,7 @@ class NavigationItem extends StatelessWidget {
|
||||
children: [
|
||||
if (selected)
|
||||
Container(
|
||||
height: ThemeHelper.getThemeElement<double, double>(
|
||||
height: ThemeHelper.getElement<double, double>(
|
||||
[
|
||||
context
|
||||
.themeExtension<TopBarThemeExtension>()
|
||||
@ -44,7 +44,7 @@ class NavigationItem extends StatelessWidget {
|
||||
valueValidator: (value) => value != null,
|
||||
transform: (value) => value,
|
||||
),
|
||||
width: ThemeHelper.getThemeElement<double, double>(
|
||||
width: ThemeHelper.getElement<double, double>(
|
||||
[
|
||||
context
|
||||
.themeExtension<TopBarThemeExtension>()
|
||||
@ -57,7 +57,7 @@ class NavigationItem extends StatelessWidget {
|
||||
),
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(100),
|
||||
color: ThemeHelper.getThemeElement<Color, Color>(
|
||||
color: ThemeHelper.getElement<Color, Color>(
|
||||
[
|
||||
context
|
||||
.themeExtension<TopBarThemeExtension>()
|
||||
@ -71,25 +71,24 @@ class NavigationItem extends StatelessWidget {
|
||||
),
|
||||
ConstrainedBox(
|
||||
constraints: BoxConstraints(
|
||||
minWidth: ThemeHelper.getThemeElement<double, double>(
|
||||
[
|
||||
context
|
||||
.themeExtension<TopBarThemeExtension>()
|
||||
?.selectedIndicatorWidth,
|
||||
// TODO(wyatt): move default value
|
||||
70,
|
||||
],
|
||||
valueValidator: (value) => value != null,
|
||||
transform: (value) => value,
|
||||
) ??
|
||||
double.infinity,
|
||||
minWidth: ThemeHelper.getElement<double, double>(
|
||||
[
|
||||
context
|
||||
.themeExtension<TopBarThemeExtension>()
|
||||
?.selectedIndicatorWidth,
|
||||
// TODO(wyatt): move default value
|
||||
70,
|
||||
],
|
||||
valueValidator: (value) => value != null,
|
||||
transform: (value) => value,
|
||||
),
|
||||
),
|
||||
child: SizedBox(
|
||||
height: 50,
|
||||
child: Center(
|
||||
child: Text(
|
||||
item.data,
|
||||
style: ThemeHelper.getThemeElement<TextStyle, TextStyle>(
|
||||
style: ThemeHelper.getElement<TextStyle, TextStyle>(
|
||||
[
|
||||
context.textTheme.titleMedium,
|
||||
context
|
||||
|
@ -28,7 +28,7 @@ class FileSelectionButton extends FileSelectionButtonComponent
|
||||
const FileSelectionButton({
|
||||
super.leading,
|
||||
super.title,
|
||||
super.subTitle,
|
||||
super.subtitle,
|
||||
super.disabledStyle,
|
||||
super.normalStyle,
|
||||
super.hoveredStyle,
|
||||
@ -79,7 +79,7 @@ class FileSelectionButton extends FileSelectionButtonComponent
|
||||
Widget build(BuildContext context) => FileSelectionButtonScreen(
|
||||
leading: leading,
|
||||
title: title,
|
||||
subTitle: subTitle,
|
||||
subtitle: subtitle,
|
||||
disabledStyle: disabledStyle,
|
||||
normalStyle: normalStyle,
|
||||
hoveredStyle: hoveredStyle,
|
||||
|
@ -18,8 +18,8 @@ class $FileSelectionButtonCWProxyImpl
|
||||
@override
|
||||
FileSelectionButton title(TextWrapper? title) => this(title: title);
|
||||
@override
|
||||
FileSelectionButton subTitle(TextWrapper? subTitle) =>
|
||||
this(subTitle: subTitle);
|
||||
FileSelectionButton subtitle(TextWrapper? subtitle) =>
|
||||
this(subtitle: subtitle);
|
||||
@override
|
||||
FileSelectionButton disabledStyle(ButtonStyle<dynamic>? disabledStyle) =>
|
||||
this(disabledStyle: disabledStyle);
|
||||
@ -58,7 +58,7 @@ class $FileSelectionButtonCWProxyImpl
|
||||
MainAxisSize? mainAxisSize,
|
||||
Widget? leading,
|
||||
TextWrapper? title,
|
||||
TextWrapper? subTitle,
|
||||
TextWrapper? subtitle,
|
||||
ButtonStyle<dynamic>? disabledStyle,
|
||||
ButtonStyle<dynamic>? normalStyle,
|
||||
ButtonStyle<dynamic>? hoveredStyle,
|
||||
@ -74,7 +74,7 @@ class $FileSelectionButtonCWProxyImpl
|
||||
FileSelectionButton(
|
||||
leading: leading ?? _value.leading,
|
||||
title: title ?? _value.title,
|
||||
subTitle: subTitle ?? _value.subTitle,
|
||||
subtitle: subtitle ?? _value.subtitle,
|
||||
disabledStyle: disabledStyle ?? _value.disabledStyle,
|
||||
normalStyle: normalStyle ?? _value.normalStyle,
|
||||
hoveredStyle: hoveredStyle ?? _value.hoveredStyle,
|
||||
|
@ -31,7 +31,7 @@ class FileSelectionButtonScreen
|
||||
const FileSelectionButtonScreen({
|
||||
this.leading,
|
||||
this.title,
|
||||
this.subTitle,
|
||||
this.subtitle,
|
||||
this.disabledStyle,
|
||||
this.normalStyle,
|
||||
this.hoveredStyle,
|
||||
@ -46,11 +46,19 @@ class FileSelectionButtonScreen
|
||||
super.key,
|
||||
});
|
||||
|
||||
/// The leading widget of the button.
|
||||
final Widget? leading;
|
||||
|
||||
/// The title widget of the button.
|
||||
final TextWrapper? title;
|
||||
final TextWrapper? subTitle;
|
||||
|
||||
/// The subtitle widget of the button.
|
||||
final TextWrapper? subtitle;
|
||||
|
||||
/// The main axis size of the button.
|
||||
final MainAxisSize? mainAxisSize;
|
||||
|
||||
// Styles
|
||||
final FileSelectionButtonStyle? disabledStyle;
|
||||
final FileSelectionButtonStyle? normalStyle;
|
||||
final FileSelectionButtonStyle? hoveredStyle;
|
||||
@ -59,8 +67,13 @@ class FileSelectionButtonScreen
|
||||
final FileSelectionButtonStyle? selectedStyle;
|
||||
final FileSelectionButtonStyle? invalidStyle;
|
||||
|
||||
/// The callback to be called when the button is pressed.
|
||||
final void Function(ControlState state)? onPressed;
|
||||
|
||||
/// The notifier to be used to disable the button.
|
||||
final ValueNotifier<bool>? disabled;
|
||||
|
||||
/// The theme resolver to be used to resolve the theme.
|
||||
final FileSelectionButtonThemeResolver? themeResolver;
|
||||
|
||||
@override
|
||||
@ -198,43 +211,28 @@ class FileSelectionButtonScreen
|
||||
///
|
||||
/// More infos in `ThemeResolver` class
|
||||
if (title != null) ...[
|
||||
Text(
|
||||
title!.data,
|
||||
style: title!.style ?? style.title,
|
||||
textAlign: title!.textAlign,
|
||||
textDirection: title!.textDirection,
|
||||
softWrap: title!.softWrap,
|
||||
overflow: title!.overflow,
|
||||
maxLines: title!.maxLines,
|
||||
selectionColor: title!.selectionColor,
|
||||
).toGradient(
|
||||
GradientText.fromWrapper(
|
||||
title!,
|
||||
gradientColors: style.foregroundColors,
|
||||
),
|
||||
)
|
||||
],
|
||||
|
||||
/// Choose color
|
||||
/// subTitle.style.color ??
|
||||
/// buttonStyle.subTitle.style.color ??
|
||||
/// context.textTheme.subTitleLarge.color
|
||||
/// subtitle.style.color ??
|
||||
/// buttonStyle.subtitle.style.color ??
|
||||
/// context.textTheme.subtitleLarge.color
|
||||
///
|
||||
/// Choose gradient
|
||||
/// subTitle.gradient ??
|
||||
/// subtitle.gradient ??
|
||||
/// buttonStyle.foregroundColor.colors ??
|
||||
/// null
|
||||
///
|
||||
/// More infos in `ThemeResolver` class
|
||||
if (subTitle != null) ...[
|
||||
if (subtitle != null) ...[
|
||||
const Gap(5),
|
||||
Text(
|
||||
subTitle!.data,
|
||||
style: subTitle!.style ?? style.subTitle,
|
||||
textAlign: title!.textAlign,
|
||||
textDirection: title!.textDirection,
|
||||
softWrap: title!.softWrap,
|
||||
overflow: title!.overflow,
|
||||
maxLines: title!.maxLines,
|
||||
selectionColor: title!.selectionColor,
|
||||
).toGradient(
|
||||
GradientText.fromWrapper(
|
||||
subtitle!,
|
||||
style: style.subtitleStyle,
|
||||
gradientColors: style.foregroundColors,
|
||||
),
|
||||
],
|
||||
|
@ -24,58 +24,6 @@ class FileSelectionButtonThemeResolver extends ThemeResolver<
|
||||
required this.customStyleFn,
|
||||
});
|
||||
|
||||
@override
|
||||
FileSelectionButtonStyle computeDefaultValue(
|
||||
BuildContext context, {
|
||||
ButtonState? extra,
|
||||
}) {
|
||||
MultiColor backgroundColor = MultiColor.single(context.colorScheme.primary);
|
||||
MultiColor foregroundColor =
|
||||
MultiColor.single(context.colorScheme.onPrimary);
|
||||
|
||||
switch (extra?.state) {
|
||||
case ControlState.disabled:
|
||||
backgroundColor =
|
||||
MultiColor.single(context.colorScheme.onSurface.withOpacity(0.12));
|
||||
foregroundColor =
|
||||
MultiColor.single(context.colorScheme.onSurface.withOpacity(0.38));
|
||||
break;
|
||||
case ControlState.hovered:
|
||||
backgroundColor =
|
||||
MultiColor.single(context.colorScheme.primary.withOpacity(0.92));
|
||||
break;
|
||||
case ControlState.tapped:
|
||||
backgroundColor =
|
||||
MultiColor.single(context.colorScheme.primary.withOpacity(0.92));
|
||||
break;
|
||||
case null:
|
||||
case ControlState.normal:
|
||||
case ControlState.focused:
|
||||
break;
|
||||
}
|
||||
|
||||
if (extra?.isInvalid ?? false) {
|
||||
backgroundColor = MultiColor.single(context.colorScheme.error);
|
||||
}
|
||||
|
||||
return FileSelectionButtonStyle(
|
||||
title: context.textTheme.labelLarge,
|
||||
subTitle: context.textTheme.labelSmall,
|
||||
radius: (context.buttonTheme.shape is RoundedRectangleBorder)
|
||||
? (context.buttonTheme.shape as RoundedRectangleBorder).borderRadius
|
||||
: null,
|
||||
padding: const EdgeInsets.symmetric(horizontal: 10),
|
||||
foregroundColors: foregroundColor,
|
||||
backgroundColors: backgroundColor,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
final FileSelectionButtonStyle? Function(
|
||||
BuildContext context, {
|
||||
ButtonState? extra,
|
||||
}) customStyleFn;
|
||||
|
||||
@override
|
||||
FileSelectionButtonStyle? computeExtensionValueFn(
|
||||
BuildContext context,
|
||||
@ -96,17 +44,31 @@ class FileSelectionButtonThemeResolver extends ThemeResolver<
|
||||
case ControlState.tapped:
|
||||
style = themeExtension?.tappedStyle;
|
||||
break;
|
||||
case ControlState.normal:
|
||||
case null:
|
||||
case ControlState.normal:
|
||||
style = themeExtension?.normalStyle;
|
||||
break;
|
||||
}
|
||||
|
||||
if (extra?.isInvalid ?? false) {
|
||||
style = themeExtension?.invalidStyle;
|
||||
}
|
||||
if (extra?.isSelected ?? false) {
|
||||
style = themeExtension?.selectedStyle;
|
||||
}
|
||||
if (extra?.isInvalid ?? false) {
|
||||
style = themeExtension?.invalidStyle;
|
||||
}
|
||||
|
||||
return style;
|
||||
}
|
||||
|
||||
@override
|
||||
FileSelectionButtonThemeExtension? getDefaultExtension(
|
||||
BuildContext context,
|
||||
) =>
|
||||
FileSelectionButtonThemeExtensionDefault.from(Theme.of(context));
|
||||
|
||||
@override
|
||||
final FileSelectionButtonStyle? Function(
|
||||
BuildContext context, {
|
||||
ButtonState? extra,
|
||||
}) customStyleFn;
|
||||
}
|
||||
|
@ -208,16 +208,9 @@ class FlatButtonScreen extends CubitScreen<ButtonCubit, ButtonState> {
|
||||
///
|
||||
/// More infos in ThemeResolver class
|
||||
if (label != null) ...[
|
||||
Text(
|
||||
label!.data,
|
||||
style: label!.style ?? style.label,
|
||||
textAlign: label!.textAlign,
|
||||
textDirection: label!.textDirection,
|
||||
softWrap: label!.softWrap,
|
||||
overflow: label!.overflow,
|
||||
maxLines: label!.maxLines,
|
||||
selectionColor: label!.selectionColor,
|
||||
).toGradient(
|
||||
GradientText.fromWrapper(
|
||||
label!,
|
||||
style: style.labelStyle,
|
||||
gradientColors: style.foregroundColors,
|
||||
)
|
||||
],
|
||||
|
@ -16,7 +16,6 @@
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:wyatt_ui_components/wyatt_ui_components.dart';
|
||||
import 'package:wyatt_ui_kit/wyatt_ui_kit.dart';
|
||||
|
||||
class FlatButtonThemeResolver extends ThemeResolver<FlatButtonStyle,
|
||||
FlatButtonThemeExtension, ControlState> {
|
||||
@ -24,73 +23,42 @@ class FlatButtonThemeResolver extends ThemeResolver<FlatButtonStyle,
|
||||
required this.customStyleFn,
|
||||
});
|
||||
|
||||
/// Values taken from <https://api.flutter.dev/flutter/material/ElevatedButton/defaultStyleOf.html>
|
||||
@override
|
||||
FlatButtonStyle computeDefaultValue(
|
||||
BuildContext context, {
|
||||
ControlState? extra,
|
||||
}) {
|
||||
MultiColor backgroundColor = MultiColor.single(context.colorScheme.primary);
|
||||
MultiColor foregroundColor =
|
||||
MultiColor.single(context.colorScheme.onPrimary);
|
||||
|
||||
switch (extra) {
|
||||
case ControlState.disabled:
|
||||
backgroundColor =
|
||||
MultiColor.single(context.colorScheme.onSurface.withOpacity(0.12));
|
||||
foregroundColor =
|
||||
MultiColor.single(context.colorScheme.onSurface.withOpacity(0.38));
|
||||
break;
|
||||
case ControlState.hovered:
|
||||
backgroundColor =
|
||||
MultiColor.single(context.colorScheme.primary.withOpacity(0.92));
|
||||
break;
|
||||
case ControlState.tapped:
|
||||
backgroundColor =
|
||||
MultiColor.single(context.colorScheme.primary.withOpacity(0.92));
|
||||
break;
|
||||
case null:
|
||||
case ControlState.normal:
|
||||
case ControlState.focused:
|
||||
break;
|
||||
}
|
||||
|
||||
return FlatButtonStyle(
|
||||
label:
|
||||
context.textTheme.labelLarge?.copyWith(color: foregroundColor.color),
|
||||
radius: (context.buttonTheme.shape is RoundedRectangleBorder)
|
||||
? (context.buttonTheme.shape as RoundedRectangleBorder).borderRadius
|
||||
: null,
|
||||
padding: context.buttonTheme.padding,
|
||||
foregroundColors: foregroundColor,
|
||||
backgroundColors: backgroundColor,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
final FlatButtonStyle? Function(
|
||||
BuildContext context, {
|
||||
ControlState? extra,
|
||||
}) customStyleFn;
|
||||
|
||||
@override
|
||||
FlatButtonStyle? computeExtensionValueFn(
|
||||
BuildContext context,
|
||||
FlatButtonThemeExtension? themeExtension, {
|
||||
ControlState? extra,
|
||||
}) {
|
||||
FlatButtonStyle? style;
|
||||
switch (extra) {
|
||||
case ControlState.disabled:
|
||||
return themeExtension?.disabledStyle;
|
||||
style = themeExtension?.disabledStyle;
|
||||
break;
|
||||
case ControlState.focused:
|
||||
return themeExtension?.focusedStyle;
|
||||
style = themeExtension?.focusedStyle;
|
||||
break;
|
||||
case ControlState.hovered:
|
||||
return themeExtension?.hoveredStyle;
|
||||
style = themeExtension?.hoveredStyle;
|
||||
break;
|
||||
case ControlState.tapped:
|
||||
return themeExtension?.tappedStyle;
|
||||
case ControlState.normal:
|
||||
style = themeExtension?.tappedStyle;
|
||||
break;
|
||||
case null:
|
||||
return themeExtension?.normalStyle;
|
||||
case ControlState.normal:
|
||||
style = themeExtension?.normalStyle;
|
||||
break;
|
||||
}
|
||||
|
||||
return style;
|
||||
}
|
||||
|
||||
@override
|
||||
FlatButtonThemeExtension? getDefaultExtension(BuildContext context) =>
|
||||
FlatButtonThemeExtensionDefault.from(Theme.of(context));
|
||||
|
||||
@override
|
||||
final FlatButtonStyle? Function(
|
||||
BuildContext context, {
|
||||
ControlState? extra,
|
||||
}) customStyleFn;
|
||||
}
|
||||
|
@ -11,7 +11,7 @@ class $SimpleIconButtonCWProxyImpl
|
||||
const $SimpleIconButtonCWProxyImpl(this._value);
|
||||
final SimpleIconButton _value;
|
||||
@override
|
||||
SimpleIconButton icon(Icon? icon) => this(icon: icon);
|
||||
SimpleIconButton icon(Widget? icon) => this(icon: icon);
|
||||
@override
|
||||
SimpleIconButton disabledStyle(ButtonStyle<dynamic>? disabledStyle) =>
|
||||
this(disabledStyle: disabledStyle);
|
||||
@ -41,7 +41,7 @@ class $SimpleIconButtonCWProxyImpl
|
||||
SimpleIconButton key(Key? key) => this(key: key);
|
||||
@override
|
||||
SimpleIconButton call({
|
||||
Icon? icon,
|
||||
Widget? icon,
|
||||
ButtonStyle<dynamic>? disabledStyle,
|
||||
ButtonStyle<dynamic>? normalStyle,
|
||||
ButtonStyle<dynamic>? hoveredStyle,
|
||||
|
@ -16,7 +16,6 @@
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:wyatt_ui_components/wyatt_ui_components.dart';
|
||||
import 'package:wyatt_ui_kit/wyatt_ui_kit.dart';
|
||||
|
||||
class SimpleIconButtonThemeResolver extends ThemeResolver<SimpleIconButtonStyle,
|
||||
SimpleIconButtonThemeExtension, ControlState> {
|
||||
@ -25,70 +24,41 @@ class SimpleIconButtonThemeResolver extends ThemeResolver<SimpleIconButtonStyle,
|
||||
});
|
||||
|
||||
@override
|
||||
SimpleIconButtonStyle computeDefaultValue(
|
||||
BuildContext context, {
|
||||
SimpleIconButtonStyle? computeExtensionValueFn(
|
||||
BuildContext context,
|
||||
SimpleIconButtonThemeExtension? themeExtension, {
|
||||
ControlState? extra,
|
||||
}) {
|
||||
MultiColor backgroundColor = MultiColor.single(context.colorScheme.primary);
|
||||
MultiColor foregroundColor =
|
||||
MultiColor.single(context.colorScheme.onPrimary);
|
||||
|
||||
SimpleIconButtonStyle? style;
|
||||
switch (extra) {
|
||||
case ControlState.disabled:
|
||||
backgroundColor =
|
||||
MultiColor.single(context.colorScheme.onSurface.withOpacity(0.12));
|
||||
foregroundColor =
|
||||
MultiColor.single(context.colorScheme.onSurface.withOpacity(0.38));
|
||||
style = themeExtension?.disabledStyle;
|
||||
break;
|
||||
case ControlState.focused:
|
||||
style = themeExtension?.focusedStyle;
|
||||
break;
|
||||
case ControlState.hovered:
|
||||
backgroundColor =
|
||||
MultiColor.single(context.colorScheme.primary.withOpacity(0.92));
|
||||
style = themeExtension?.hoveredStyle;
|
||||
break;
|
||||
case ControlState.tapped:
|
||||
backgroundColor =
|
||||
MultiColor.single(context.colorScheme.primary.withOpacity(0.92));
|
||||
style = themeExtension?.tappedStyle;
|
||||
break;
|
||||
case null:
|
||||
case ControlState.normal:
|
||||
case ControlState.focused:
|
||||
style = themeExtension?.normalStyle;
|
||||
break;
|
||||
}
|
||||
|
||||
return SimpleIconButtonStyle(
|
||||
dimension: context.buttonTheme.height,
|
||||
radius: (context.buttonTheme.shape is RoundedRectangleBorder)
|
||||
? (context.buttonTheme.shape as RoundedRectangleBorder).borderRadius
|
||||
: null,
|
||||
padding: EdgeInsets.zero,
|
||||
foregroundColors: foregroundColor,
|
||||
backgroundColors: backgroundColor,
|
||||
);
|
||||
return style;
|
||||
}
|
||||
|
||||
@override
|
||||
SimpleIconButtonThemeExtension? getDefaultExtension(BuildContext context) =>
|
||||
SimpleIconButtonThemeExtensionDefault.from(Theme.of(context));
|
||||
|
||||
@override
|
||||
final SimpleIconButtonStyle? Function(
|
||||
BuildContext context, {
|
||||
ControlState? extra,
|
||||
}) customStyleFn;
|
||||
|
||||
@override
|
||||
SimpleIconButtonStyle? computeExtensionValueFn(
|
||||
BuildContext context,
|
||||
SimpleIconButtonThemeExtension? themeExtension, {
|
||||
ControlState? extra,
|
||||
}) {
|
||||
switch (extra) {
|
||||
case ControlState.disabled:
|
||||
return themeExtension?.disabledStyle;
|
||||
case ControlState.focused:
|
||||
return themeExtension?.focusedStyle;
|
||||
case ControlState.hovered:
|
||||
return themeExtension?.hoveredStyle;
|
||||
case ControlState.tapped:
|
||||
return themeExtension?.tappedStyle;
|
||||
case ControlState.normal:
|
||||
case null:
|
||||
return themeExtension?.normalStyle;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -18,12 +18,9 @@ import 'package:flutter/material.dart' hide ButtonStyle;
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:wyatt_bloc_helper/wyatt_bloc_helper.dart';
|
||||
import 'package:wyatt_ui_components/wyatt_ui_components.dart';
|
||||
import 'package:wyatt_ui_kit/src/components/buttons/cubit/button_cubit.dart';
|
||||
import 'package:wyatt_ui_kit/src/components/buttons/cubit/state_listener.dart';
|
||||
import 'package:wyatt_ui_kit/src/components/buttons/simple_icon_button/simple_icon_button_theme_resolver.dart';
|
||||
import 'package:wyatt_ui_kit/src/components/gradients/gradient_box_border.dart';
|
||||
import 'package:wyatt_ui_kit/src/components/gradients/gradient_icon.dart';
|
||||
import 'package:wyatt_ui_kit/src/core/helpers/linear_gradient_helper.dart';
|
||||
import 'package:wyatt_ui_kit/wyatt_ui_kit.dart';
|
||||
|
||||
class SimpleIconButtonScreen extends CubitScreen<ButtonCubit, ButtonState> {
|
||||
const SimpleIconButtonScreen({
|
||||
@ -39,7 +36,7 @@ class SimpleIconButtonScreen extends CubitScreen<ButtonCubit, ButtonState> {
|
||||
super.key,
|
||||
});
|
||||
|
||||
final Icon? icon;
|
||||
final Widget? icon;
|
||||
|
||||
final SimpleIconButtonStyle? disabledStyle;
|
||||
final SimpleIconButtonStyle? normalStyle;
|
||||
@ -171,25 +168,23 @@ class SimpleIconButtonScreen extends CubitScreen<ButtonCubit, ButtonState> {
|
||||
/// context.buttonTheme.onPrimary
|
||||
child: Builder(
|
||||
builder: (context) {
|
||||
if (icon?.color != null) {
|
||||
return icon!;
|
||||
}
|
||||
|
||||
if (!(style.foregroundColors?.isGradient ?? false)) {
|
||||
return ColorFiltered(
|
||||
colorFilter: ColorFilter.mode(
|
||||
style.foregroundColors!.color,
|
||||
BlendMode.srcIn,
|
||||
),
|
||||
child: icon,
|
||||
if (icon != null) {
|
||||
if (icon is GradientIcon) {
|
||||
return icon!;
|
||||
}
|
||||
if (icon is Icon) {
|
||||
return GradientIcon.fromIcon(
|
||||
(icon as Icon?)!,
|
||||
gradientColors: style.foregroundColors,
|
||||
);
|
||||
}
|
||||
return GradientIcon.fromWidget(
|
||||
icon!,
|
||||
gradientColors: style.foregroundColors,
|
||||
);
|
||||
}
|
||||
|
||||
return icon!.toGradient(
|
||||
LinearGradientHelper.fromMultiColor(
|
||||
style.foregroundColors!,
|
||||
),
|
||||
);
|
||||
return const SizedBox.shrink();
|
||||
},
|
||||
),
|
||||
),
|
||||
|
@ -209,16 +209,9 @@ class SymbolButtonScreen
|
||||
/// More infos in `negociate()` method
|
||||
if (label != null) ...[
|
||||
Gap(style.padding?.horizontal ?? 10),
|
||||
Text(
|
||||
label!.data,
|
||||
style: label!.style ?? style.label,
|
||||
textAlign: label!.textAlign,
|
||||
textDirection: label!.textDirection,
|
||||
softWrap: label!.softWrap,
|
||||
overflow: label!.overflow,
|
||||
maxLines: label!.maxLines,
|
||||
selectionColor: label!.selectionColor,
|
||||
).toGradient(
|
||||
GradientText.fromWrapper(
|
||||
label!,
|
||||
style: style.labelStyle,
|
||||
gradientColors: style.foregroundColors,
|
||||
),
|
||||
],
|
||||
|
@ -24,54 +24,6 @@ class SymbolButtonThemeResolver extends ThemeResolver<SymbolButtonStyle,
|
||||
required this.customStyleFn,
|
||||
});
|
||||
|
||||
@override
|
||||
SymbolButtonStyle computeDefaultValue(
|
||||
BuildContext context, {
|
||||
ButtonState? extra,
|
||||
}) {
|
||||
MultiColor backgroundColor = MultiColor.single(context.colorScheme.primary);
|
||||
MultiColor foregroundColor =
|
||||
MultiColor.single(context.colorScheme.onPrimary);
|
||||
|
||||
switch (extra?.state) {
|
||||
case ControlState.disabled:
|
||||
backgroundColor =
|
||||
MultiColor.single(context.colorScheme.onSurface.withOpacity(0.12));
|
||||
foregroundColor =
|
||||
MultiColor.single(context.colorScheme.onSurface.withOpacity(0.38));
|
||||
break;
|
||||
case ControlState.hovered:
|
||||
backgroundColor =
|
||||
MultiColor.single(context.colorScheme.primary.withOpacity(0.92));
|
||||
break;
|
||||
case ControlState.tapped:
|
||||
backgroundColor =
|
||||
MultiColor.single(context.colorScheme.primary.withOpacity(0.92));
|
||||
break;
|
||||
case null:
|
||||
case ControlState.normal:
|
||||
case ControlState.focused:
|
||||
break;
|
||||
}
|
||||
|
||||
return SymbolButtonStyle(
|
||||
label: context.textTheme.labelLarge,
|
||||
dimension: context.buttonTheme.height * 1.5,
|
||||
radius: (context.buttonTheme.shape is RoundedRectangleBorder)
|
||||
? (context.buttonTheme.shape as RoundedRectangleBorder).borderRadius
|
||||
: null,
|
||||
padding: context.buttonTheme.padding,
|
||||
foregroundColors: foregroundColor,
|
||||
backgroundColors: backgroundColor,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
final SymbolButtonStyle? Function(
|
||||
BuildContext context, {
|
||||
ButtonState? extra,
|
||||
}) customStyleFn;
|
||||
|
||||
@override
|
||||
SymbolButtonStyle? computeExtensionValueFn(
|
||||
BuildContext context,
|
||||
@ -92,15 +44,28 @@ class SymbolButtonThemeResolver extends ThemeResolver<SymbolButtonStyle,
|
||||
case ControlState.tapped:
|
||||
style = themeExtension?.tappedStyle;
|
||||
break;
|
||||
case ControlState.normal:
|
||||
case null:
|
||||
case ControlState.normal:
|
||||
style = themeExtension?.normalStyle;
|
||||
break;
|
||||
}
|
||||
|
||||
if (extra?.isSelected ?? false) {
|
||||
style = themeExtension?.selectedStyle;
|
||||
}
|
||||
|
||||
return style;
|
||||
}
|
||||
|
||||
@override
|
||||
SymbolButtonThemeExtension? getDefaultExtension(
|
||||
BuildContext context,
|
||||
) =>
|
||||
SymbolButtonThemeExtensionDefault.from(Theme.of(context));
|
||||
|
||||
@override
|
||||
final SymbolButtonStyle? Function(
|
||||
BuildContext context, {
|
||||
ButtonState? extra,
|
||||
}) customStyleFn;
|
||||
}
|
||||
|
@ -40,50 +40,85 @@ class InformationCard extends InformationCardComponent
|
||||
super.padding,
|
||||
super.borderColors,
|
||||
super.backgroundColors,
|
||||
super.stroke,
|
||||
super.minSize,
|
||||
super.maxSize = const Size(330, double.infinity),
|
||||
super.maxSize,
|
||||
super.shadow,
|
||||
super.titleStyle,
|
||||
super.subtitleStyle,
|
||||
super.bodyStyle,
|
||||
super.background,
|
||||
super.key,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) => CardWrapper(
|
||||
background: background,
|
||||
padding: padding,
|
||||
backgroundColors: backgroundColors,
|
||||
borderColors: borderColors,
|
||||
shadow: shadow,
|
||||
maxSize: maxSize,
|
||||
minSize: minSize,
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
if (axis == Axis.horizontal) ...[
|
||||
InformationCardHorizontalHeader(
|
||||
icons: icons,
|
||||
axis: axis,
|
||||
title: title,
|
||||
subtitle: subtitle,
|
||||
),
|
||||
] else if (axis == Axis.vertical) ...[
|
||||
InformationCardVerticalHeader(
|
||||
icons: icons,
|
||||
axis: axis,
|
||||
title: title,
|
||||
subtitle: subtitle,
|
||||
),
|
||||
],
|
||||
if (body != null) ...[
|
||||
const Gap(_bodyTopSpacing),
|
||||
CardText(
|
||||
body!,
|
||||
textType: TextType.body,
|
||||
style: body!.style,
|
||||
gradientColors: body!.gradientColors,
|
||||
),
|
||||
],
|
||||
Widget build(BuildContext context) {
|
||||
final themeTitleStyle = ThemeHelper.maybeGetElement<TextStyle, TextStyle>(
|
||||
[
|
||||
titleStyle,
|
||||
Theme.of(context).extension<CardThemeExtension>()?.titleStyle,
|
||||
CardThemeExtensionDefault.from(Theme.of(context)).titleStyle,
|
||||
],
|
||||
);
|
||||
|
||||
final themeSubtitleStyle =
|
||||
ThemeHelper.maybeGetElement<TextStyle, TextStyle>(
|
||||
[
|
||||
subtitleStyle,
|
||||
Theme.of(context).extension<CardThemeExtension>()?.subtitleStyle,
|
||||
CardThemeExtensionDefault.from(Theme.of(context)).subtitleStyle,
|
||||
],
|
||||
);
|
||||
|
||||
final themeBodyStyle = ThemeHelper.maybeGetElement<TextStyle, TextStyle>(
|
||||
[
|
||||
bodyStyle,
|
||||
Theme.of(context).extension<CardThemeExtension>()?.bodyStyle,
|
||||
CardThemeExtensionDefault.from(Theme.of(context)).bodyStyle,
|
||||
],
|
||||
);
|
||||
|
||||
return CardWrapper(
|
||||
background: background,
|
||||
padding: padding,
|
||||
radius: radius,
|
||||
backgroundColors: backgroundColors,
|
||||
borderColors: borderColors,
|
||||
shadow: shadow,
|
||||
stroke: stroke,
|
||||
maxSize: maxSize,
|
||||
minSize: minSize,
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
if (axis == Axis.horizontal) ...[
|
||||
InformationCardHorizontalHeader(
|
||||
icons: icons,
|
||||
axis: axis,
|
||||
title: title,
|
||||
subtitle: subtitle,
|
||||
titleStyle: themeTitleStyle,
|
||||
subtitleStyle: themeSubtitleStyle,
|
||||
),
|
||||
] else ...[
|
||||
InformationCardVerticalHeader(
|
||||
icons: icons,
|
||||
axis: axis,
|
||||
title: title,
|
||||
subtitle: subtitle,
|
||||
titleStyle: themeTitleStyle,
|
||||
subtitleStyle: themeSubtitleStyle,
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
if (body != null) ...[
|
||||
const Gap(_bodyTopSpacing),
|
||||
CardText.fromWrapper(
|
||||
body!,
|
||||
style: themeBodyStyle,
|
||||
),
|
||||
],
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -20,9 +20,10 @@ class $InformationCardCWProxyImpl implements $InformationCardComponentCWProxy {
|
||||
@override
|
||||
InformationCard axis(Axis? axis) => this(axis: axis);
|
||||
@override
|
||||
InformationCard radius(double? radius) => this(radius: radius);
|
||||
InformationCard radius(BorderRadiusGeometry? radius) => this(radius: radius);
|
||||
@override
|
||||
InformationCard padding(double? padding) => this(padding: padding);
|
||||
InformationCard padding(EdgeInsetsGeometry? padding) =>
|
||||
this(padding: padding);
|
||||
@override
|
||||
InformationCard borderColors(MultiColor? borderColors) =>
|
||||
this(borderColors: borderColors);
|
||||
@ -30,12 +31,22 @@ class $InformationCardCWProxyImpl implements $InformationCardComponentCWProxy {
|
||||
InformationCard backgroundColors(MultiColor? backgroundColors) =>
|
||||
this(backgroundColors: backgroundColors);
|
||||
@override
|
||||
InformationCard stroke(double? stroke) => this(stroke: stroke);
|
||||
@override
|
||||
InformationCard minSize(Size? minSize) => this(minSize: minSize);
|
||||
@override
|
||||
InformationCard maxSize(Size? maxSize) => this(maxSize: maxSize);
|
||||
@override
|
||||
InformationCard shadow(BoxShadow? shadow) => this(shadow: shadow);
|
||||
@override
|
||||
InformationCard titleStyle(TextStyle? titleStyle) =>
|
||||
this(titleStyle: titleStyle);
|
||||
@override
|
||||
InformationCard subtitleStyle(TextStyle? subtitleStyle) =>
|
||||
this(subtitleStyle: subtitleStyle);
|
||||
@override
|
||||
InformationCard bodyStyle(TextStyle? bodyStyle) => this(bodyStyle: bodyStyle);
|
||||
@override
|
||||
InformationCard background(Widget? background) =>
|
||||
this(background: background);
|
||||
@override
|
||||
@ -47,13 +58,17 @@ class $InformationCardCWProxyImpl implements $InformationCardComponentCWProxy {
|
||||
TextWrapper? subtitle,
|
||||
TextWrapper? body,
|
||||
Axis? axis,
|
||||
double? radius,
|
||||
double? padding,
|
||||
BorderRadiusGeometry? radius,
|
||||
EdgeInsetsGeometry? padding,
|
||||
MultiColor? borderColors,
|
||||
MultiColor? backgroundColors,
|
||||
double? stroke,
|
||||
Size? minSize,
|
||||
Size? maxSize,
|
||||
BoxShadow? shadow,
|
||||
TextStyle? titleStyle,
|
||||
TextStyle? subtitleStyle,
|
||||
TextStyle? bodyStyle,
|
||||
Widget? background,
|
||||
Key? key,
|
||||
}) =>
|
||||
@ -67,9 +82,13 @@ class $InformationCardCWProxyImpl implements $InformationCardComponentCWProxy {
|
||||
padding: padding ?? _value.padding,
|
||||
borderColors: borderColors ?? _value.borderColors,
|
||||
backgroundColors: backgroundColors ?? _value.backgroundColors,
|
||||
stroke: stroke ?? _value.stroke,
|
||||
minSize: minSize ?? _value.minSize,
|
||||
maxSize: maxSize ?? _value.maxSize,
|
||||
shadow: shadow ?? _value.shadow,
|
||||
titleStyle: titleStyle ?? _value.titleStyle,
|
||||
subtitleStyle: subtitleStyle ?? _value.subtitleStyle,
|
||||
bodyStyle: bodyStyle ?? _value.bodyStyle,
|
||||
background: background ?? _value.background,
|
||||
key: key ?? _value.key,
|
||||
);
|
||||
|
@ -23,18 +23,33 @@ const _avatarAndTitlesSpacing = 25.0;
|
||||
|
||||
class InformationCardHorizontalHeader extends StatelessWidget {
|
||||
const InformationCardHorizontalHeader({
|
||||
this.icons,
|
||||
this.axis,
|
||||
this.title,
|
||||
this.subtitle,
|
||||
this.axis,
|
||||
this.icons,
|
||||
this.titleStyle,
|
||||
this.subtitleStyle,
|
||||
super.key,
|
||||
});
|
||||
|
||||
final TextWrapper? title;
|
||||
final TextWrapper? subtitle;
|
||||
final Axis? axis;
|
||||
/// The icons of the card header.
|
||||
final List<Widget>? icons;
|
||||
|
||||
/// The axis of the card header.
|
||||
final Axis? axis;
|
||||
|
||||
/// The title of the card.
|
||||
final TextWrapper? title;
|
||||
|
||||
/// The subtitle of the card.
|
||||
final TextWrapper? subtitle;
|
||||
|
||||
/// Styles the title of the card.
|
||||
final TextStyle? titleStyle;
|
||||
|
||||
/// Styles the subtitle of the card.
|
||||
final TextStyle? subtitleStyle;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) => Row(
|
||||
children: [
|
||||
@ -44,9 +59,11 @@ class InformationCardHorizontalHeader extends StatelessWidget {
|
||||
],
|
||||
Expanded(
|
||||
child: InformationCardTitles(
|
||||
axis: axis,
|
||||
title: title,
|
||||
subtitle: subtitle,
|
||||
axis: axis,
|
||||
titleStyle: titleStyle,
|
||||
subtitleStyle: subtitleStyle,
|
||||
),
|
||||
),
|
||||
],
|
||||
|
@ -25,6 +25,7 @@ class InformationCardIcons extends StatelessWidget {
|
||||
this.icons,
|
||||
});
|
||||
|
||||
/// The icons of the card header.
|
||||
final List<Widget>? icons;
|
||||
|
||||
@override
|
||||
|
@ -23,16 +23,29 @@ const _titlesLineSpacing = 5.0;
|
||||
|
||||
class InformationCardTitles extends StatelessWidget {
|
||||
const InformationCardTitles({
|
||||
this.axis,
|
||||
this.title,
|
||||
this.subtitle,
|
||||
this.axis,
|
||||
this.titleStyle,
|
||||
this.subtitleStyle,
|
||||
super.key,
|
||||
});
|
||||
|
||||
final TextWrapper? title;
|
||||
final TextWrapper? subtitle;
|
||||
/// The axis of the card header.
|
||||
final Axis? axis;
|
||||
|
||||
/// The title of the card.
|
||||
final TextWrapper? title;
|
||||
|
||||
/// The subtitle of the card.
|
||||
final TextWrapper? subtitle;
|
||||
|
||||
/// Styles the title of the card.
|
||||
final TextStyle? titleStyle;
|
||||
|
||||
/// Styles the subtitle of the card.
|
||||
final TextStyle? subtitleStyle;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) => Column(
|
||||
crossAxisAlignment: axis == Axis.horizontal
|
||||
@ -40,20 +53,18 @@ class InformationCardTitles extends StatelessWidget {
|
||||
: CrossAxisAlignment.center,
|
||||
children: [
|
||||
if (title != null) ...[
|
||||
CardText(
|
||||
CardText.fromWrapper(
|
||||
title!,
|
||||
style: titleStyle,
|
||||
textType: TextType.title,
|
||||
style: title!.style,
|
||||
gradientColors: title!.gradientColors,
|
||||
),
|
||||
],
|
||||
if (subtitle != null) ...[
|
||||
const Gap(_titlesLineSpacing),
|
||||
CardText(
|
||||
CardText.fromWrapper(
|
||||
subtitle!,
|
||||
style: subtitleStyle,
|
||||
textType: TextType.subtitle,
|
||||
style: subtitle!.style,
|
||||
gradientColors: subtitle!.gradientColors,
|
||||
),
|
||||
],
|
||||
],
|
||||
|
@ -24,18 +24,33 @@ const _avatarAndTitlesSpacing = 25.0;
|
||||
|
||||
class InformationCardVerticalHeader extends StatelessWidget {
|
||||
const InformationCardVerticalHeader({
|
||||
this.icons,
|
||||
this.axis,
|
||||
this.title,
|
||||
this.subtitle,
|
||||
this.axis,
|
||||
this.icons,
|
||||
this.titleStyle,
|
||||
this.subtitleStyle,
|
||||
super.key,
|
||||
});
|
||||
|
||||
final TextWrapper? title;
|
||||
final TextWrapper? subtitle;
|
||||
final Axis? axis;
|
||||
/// The icons of the card header.
|
||||
final List<Widget>? icons;
|
||||
|
||||
/// The axis of the card header.
|
||||
final Axis? axis;
|
||||
|
||||
/// The title of the card.
|
||||
final TextWrapper? title;
|
||||
|
||||
/// The subtitle of the card.
|
||||
final TextWrapper? subtitle;
|
||||
|
||||
/// Styles the title of the card.
|
||||
final TextStyle? titleStyle;
|
||||
|
||||
/// Styles the subtitle of the card.
|
||||
final TextStyle? subtitleStyle;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) => Column(
|
||||
children: [
|
||||
@ -46,9 +61,11 @@ class InformationCardVerticalHeader extends StatelessWidget {
|
||||
const Gap(_avatarAndTitlesSpacing),
|
||||
],
|
||||
InformationCardTitles(
|
||||
axis: axis,
|
||||
title: title,
|
||||
subtitle: subtitle,
|
||||
axis: axis,
|
||||
titleStyle: titleStyle,
|
||||
subtitleStyle: subtitleStyle,
|
||||
),
|
||||
],
|
||||
);
|
||||
|
@ -25,11 +25,14 @@ import 'package:wyatt_ui_kit/src/components/cards/widgets/card_wrapper.dart';
|
||||
|
||||
part 'portfolio_card.g.dart';
|
||||
|
||||
const _spacing = 20.0;
|
||||
|
||||
@ComponentCopyWithExtension()
|
||||
class PortfolioCard extends PortfolioCardComponent with $PortfolioCardCWMixin {
|
||||
const PortfolioCard({
|
||||
super.showImagesOnTop,
|
||||
super.keyword,
|
||||
super.showAssetsOnTop,
|
||||
super.keywords,
|
||||
super.keywordsBackgroundColors,
|
||||
super.description,
|
||||
super.logo,
|
||||
super.projectName,
|
||||
@ -40,79 +43,129 @@ class PortfolioCard extends PortfolioCardComponent with $PortfolioCardCWMixin {
|
||||
super.padding,
|
||||
super.borderColors,
|
||||
super.backgroundColors,
|
||||
super.secondaryBackgroundColors,
|
||||
super.stroke,
|
||||
super.minSize,
|
||||
super.maxSize = const Size(330, double.infinity),
|
||||
super.maxSize,
|
||||
super.shadow,
|
||||
super.titleStyle,
|
||||
super.subtitleStyle,
|
||||
super.bodyStyle,
|
||||
super.background,
|
||||
super.key,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) => CardWrapper(
|
||||
background: background,
|
||||
padding: padding,
|
||||
backgroundColors: backgroundColors,
|
||||
borderColors: borderColors,
|
||||
shadow: shadow,
|
||||
maxSize: maxSize,
|
||||
minSize: minSize,
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
if (showImagesOnTop ?? false) ...[
|
||||
if (assets != null) ...[
|
||||
PortfolioCardImages(
|
||||
radius: radius,
|
||||
maxSize: maxSize,
|
||||
images: assets,
|
||||
),
|
||||
const Gap(20),
|
||||
],
|
||||
CardText(
|
||||
description!,
|
||||
textType: TextType.body,
|
||||
style: description!.style,
|
||||
gradientColors: description!.gradientColors,
|
||||
),
|
||||
const Gap(20),
|
||||
PortfolioCardHeader(
|
||||
secondaryBackgroundColors: secondaryBackgroundColors,
|
||||
logo: logo,
|
||||
padding: padding,
|
||||
radius: radius,
|
||||
projectName: projectName,
|
||||
subtitle: subtitle,
|
||||
keyword: keyword,
|
||||
),
|
||||
] else ...[
|
||||
PortfolioCardHeader(
|
||||
secondaryBackgroundColors: secondaryBackgroundColors,
|
||||
logo: logo,
|
||||
padding: padding,
|
||||
radius: radius,
|
||||
projectName: projectName,
|
||||
subtitle: subtitle,
|
||||
keyword: keyword,
|
||||
),
|
||||
const Gap(10),
|
||||
if (assets != null) ...[
|
||||
PortfolioCardImages(
|
||||
radius: radius,
|
||||
maxSize: maxSize,
|
||||
images: assets,
|
||||
),
|
||||
const Gap(20),
|
||||
],
|
||||
CardText(
|
||||
description!,
|
||||
textType: TextType.body,
|
||||
style: description!.style,
|
||||
gradientColors: description!.gradientColors,
|
||||
Widget build(BuildContext context) {
|
||||
final themeTitleStyle = ThemeHelper.maybeGetElement<TextStyle, TextStyle>(
|
||||
[
|
||||
titleStyle,
|
||||
Theme.of(context).extension<CardThemeExtension>()?.titleStyle,
|
||||
CardThemeExtensionDefault.from(Theme.of(context)).titleStyle,
|
||||
],
|
||||
);
|
||||
|
||||
final themeSubtitleStyle =
|
||||
ThemeHelper.maybeGetElement<TextStyle, TextStyle>(
|
||||
[
|
||||
subtitleStyle,
|
||||
Theme.of(context).extension<CardThemeExtension>()?.subtitleStyle,
|
||||
CardThemeExtensionDefault.from(Theme.of(context)).subtitleStyle,
|
||||
],
|
||||
);
|
||||
|
||||
final themeBodyStyle = ThemeHelper.maybeGetElement<TextStyle, TextStyle>(
|
||||
[
|
||||
bodyStyle,
|
||||
Theme.of(context).extension<CardThemeExtension>()?.bodyStyle,
|
||||
CardThemeExtensionDefault.from(Theme.of(context)).bodyStyle,
|
||||
],
|
||||
);
|
||||
|
||||
final themeBorderRadius =
|
||||
ThemeHelper.maybeGetElement<BorderRadiusGeometry, BorderRadiusGeometry>(
|
||||
[
|
||||
radius,
|
||||
Theme.of(context).extension<CardThemeExtension>()?.radius,
|
||||
CardThemeExtensionDefault.from(Theme.of(context)).radius,
|
||||
],
|
||||
);
|
||||
|
||||
final themeMaxSize = ThemeHelper.maybeGetElement<Size, Size>(
|
||||
[
|
||||
maxSize,
|
||||
Theme.of(context).extension<CardThemeExtension>()?.maxSize,
|
||||
CardThemeExtensionDefault.from(Theme.of(context)).maxSize,
|
||||
],
|
||||
);
|
||||
|
||||
return CardWrapper(
|
||||
background: background,
|
||||
padding: padding,
|
||||
radius: radius,
|
||||
backgroundColors: backgroundColors,
|
||||
borderColors: borderColors,
|
||||
shadow: shadow,
|
||||
stroke: stroke,
|
||||
maxSize: maxSize,
|
||||
minSize: minSize,
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
if (showAssetsOnTop ?? false) ...[
|
||||
if (assets != null) ...[
|
||||
PortfolioCardImages(
|
||||
assets: assets,
|
||||
radius: themeBorderRadius,
|
||||
maxSize: themeMaxSize,
|
||||
),
|
||||
const Gap(_spacing),
|
||||
],
|
||||
if (ctas != null) ...[const Gap(20), ...ctas!],
|
||||
CardText.fromWrapper(
|
||||
description!,
|
||||
style: themeBodyStyle,
|
||||
),
|
||||
const Gap(_spacing),
|
||||
PortfolioCardHeader(
|
||||
logo: logo,
|
||||
projectName: projectName,
|
||||
subtitle: subtitle,
|
||||
keywords: keywords,
|
||||
keywordsBackgroundColors: keywordsBackgroundColors,
|
||||
titleStyle: themeTitleStyle,
|
||||
subtitleStyle: themeSubtitleStyle,
|
||||
keywordsStyle: themeBodyStyle,
|
||||
),
|
||||
] else ...[
|
||||
PortfolioCardHeader(
|
||||
logo: logo,
|
||||
projectName: projectName,
|
||||
subtitle: subtitle,
|
||||
keywords: keywords,
|
||||
keywordsBackgroundColors: keywordsBackgroundColors,
|
||||
titleStyle: themeTitleStyle,
|
||||
subtitleStyle: themeSubtitleStyle,
|
||||
keywordsStyle: themeBodyStyle,
|
||||
),
|
||||
const Gap(10),
|
||||
if (assets != null) ...[
|
||||
PortfolioCardImages(
|
||||
assets: assets,
|
||||
radius: themeBorderRadius,
|
||||
maxSize: themeMaxSize,
|
||||
),
|
||||
const Gap(_spacing),
|
||||
],
|
||||
CardText.fromWrapper(
|
||||
description!,
|
||||
style: themeBodyStyle,
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
if (ctas != null)
|
||||
...[const Gap(_spacing), ...ctas!].map(
|
||||
(e) => SelectionContainer.disabled(child: e),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -10,13 +10,15 @@ class $PortfolioCardCWProxyImpl implements $PortfolioCardComponentCWProxy {
|
||||
const $PortfolioCardCWProxyImpl(this._value);
|
||||
final PortfolioCard _value;
|
||||
@override
|
||||
PortfolioCard secondaryBackgroundColors(Color? secondaryBackgroundColors) =>
|
||||
this(secondaryBackgroundColors: secondaryBackgroundColors);
|
||||
PortfolioCard showAssetsOnTop(bool? showAssetsOnTop) =>
|
||||
this(showAssetsOnTop: showAssetsOnTop);
|
||||
@override
|
||||
PortfolioCard showImagesOnTop(bool? showImagesOnTop) =>
|
||||
this(showImagesOnTop: showImagesOnTop);
|
||||
PortfolioCard keywords(List<TextWrapper>? keywords) =>
|
||||
this(keywords: keywords);
|
||||
@override
|
||||
PortfolioCard keyword(List<TextWrapper>? keyword) => this(keyword: keyword);
|
||||
PortfolioCard keywordsBackgroundColors(
|
||||
MultiColor? keywordsBackgroundColors) =>
|
||||
this(keywordsBackgroundColors: keywordsBackgroundColors);
|
||||
@override
|
||||
PortfolioCard description(TextWrapper? description) =>
|
||||
this(description: description);
|
||||
@ -32,9 +34,9 @@ class $PortfolioCardCWProxyImpl implements $PortfolioCardComponentCWProxy {
|
||||
@override
|
||||
PortfolioCard assets(List<Widget>? assets) => this(assets: assets);
|
||||
@override
|
||||
PortfolioCard radius(double? radius) => this(radius: radius);
|
||||
PortfolioCard radius(BorderRadiusGeometry? radius) => this(radius: radius);
|
||||
@override
|
||||
PortfolioCard padding(double? padding) => this(padding: padding);
|
||||
PortfolioCard padding(EdgeInsetsGeometry? padding) => this(padding: padding);
|
||||
@override
|
||||
PortfolioCard borderColors(MultiColor? borderColors) =>
|
||||
this(borderColors: borderColors);
|
||||
@ -42,39 +44,55 @@ class $PortfolioCardCWProxyImpl implements $PortfolioCardComponentCWProxy {
|
||||
PortfolioCard backgroundColors(MultiColor? backgroundColors) =>
|
||||
this(backgroundColors: backgroundColors);
|
||||
@override
|
||||
PortfolioCard stroke(double? stroke) => this(stroke: stroke);
|
||||
@override
|
||||
PortfolioCard minSize(Size? minSize) => this(minSize: minSize);
|
||||
@override
|
||||
PortfolioCard maxSize(Size? maxSize) => this(maxSize: maxSize);
|
||||
@override
|
||||
PortfolioCard shadow(BoxShadow? shadow) => this(shadow: shadow);
|
||||
@override
|
||||
PortfolioCard titleStyle(TextStyle? titleStyle) =>
|
||||
this(titleStyle: titleStyle);
|
||||
@override
|
||||
PortfolioCard subtitleStyle(TextStyle? subtitleStyle) =>
|
||||
this(subtitleStyle: subtitleStyle);
|
||||
@override
|
||||
PortfolioCard bodyStyle(TextStyle? bodyStyle) => this(bodyStyle: bodyStyle);
|
||||
@override
|
||||
PortfolioCard background(Widget? background) => this(background: background);
|
||||
@override
|
||||
PortfolioCard key(Key? key) => this(key: key);
|
||||
@override
|
||||
PortfolioCard call({
|
||||
Color? secondaryBackgroundColors,
|
||||
bool? showImagesOnTop,
|
||||
List<TextWrapper>? keyword,
|
||||
bool? showAssetsOnTop,
|
||||
List<TextWrapper>? keywords,
|
||||
MultiColor? keywordsBackgroundColors,
|
||||
TextWrapper? description,
|
||||
Widget? logo,
|
||||
TextWrapper? projectName,
|
||||
TextWrapper? subtitle,
|
||||
List<Widget>? ctas,
|
||||
List<Widget>? assets,
|
||||
double? radius,
|
||||
double? padding,
|
||||
BorderRadiusGeometry? radius,
|
||||
EdgeInsetsGeometry? padding,
|
||||
MultiColor? borderColors,
|
||||
MultiColor? backgroundColors,
|
||||
double? stroke,
|
||||
Size? minSize,
|
||||
Size? maxSize,
|
||||
BoxShadow? shadow,
|
||||
TextStyle? titleStyle,
|
||||
TextStyle? subtitleStyle,
|
||||
TextStyle? bodyStyle,
|
||||
Widget? background,
|
||||
Key? key,
|
||||
}) =>
|
||||
PortfolioCard(
|
||||
showImagesOnTop: showImagesOnTop ?? _value.showImagesOnTop,
|
||||
keyword: keyword ?? _value.keyword,
|
||||
showAssetsOnTop: showAssetsOnTop ?? _value.showAssetsOnTop,
|
||||
keywords: keywords ?? _value.keywords,
|
||||
keywordsBackgroundColors:
|
||||
keywordsBackgroundColors ?? _value.keywordsBackgroundColors,
|
||||
description: description ?? _value.description,
|
||||
logo: logo ?? _value.logo,
|
||||
projectName: projectName ?? _value.projectName,
|
||||
@ -85,11 +103,13 @@ class $PortfolioCardCWProxyImpl implements $PortfolioCardComponentCWProxy {
|
||||
padding: padding ?? _value.padding,
|
||||
borderColors: borderColors ?? _value.borderColors,
|
||||
backgroundColors: backgroundColors ?? _value.backgroundColors,
|
||||
secondaryBackgroundColors:
|
||||
secondaryBackgroundColors ?? _value.secondaryBackgroundColors,
|
||||
stroke: stroke ?? _value.stroke,
|
||||
minSize: minSize ?? _value.minSize,
|
||||
maxSize: maxSize ?? _value.maxSize,
|
||||
shadow: shadow ?? _value.shadow,
|
||||
titleStyle: titleStyle ?? _value.titleStyle,
|
||||
subtitleStyle: subtitleStyle ?? _value.subtitleStyle,
|
||||
bodyStyle: bodyStyle ?? _value.bodyStyle,
|
||||
background: background ?? _value.background,
|
||||
key: key ?? _value.key,
|
||||
);
|
||||
|
@ -17,7 +17,7 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:gap/gap.dart';
|
||||
import 'package:wyatt_ui_components/wyatt_ui_components.dart';
|
||||
import 'package:wyatt_ui_kit/src/components/cards/information_card/widgets/information_card_titles.dart';
|
||||
import 'package:wyatt_ui_kit/src/components/cards/portfolio_card/widgets/portfolio_card_titles.dart';
|
||||
import 'package:wyatt_ui_kit/wyatt_ui_kit.dart';
|
||||
|
||||
const _avatarAndTitlesSpacing = 25.0;
|
||||
@ -25,22 +25,39 @@ const _avatarAndTitlesSpacing = 25.0;
|
||||
class PortfolioCardHeader extends StatelessWidget {
|
||||
const PortfolioCardHeader({
|
||||
this.logo,
|
||||
this.padding,
|
||||
this.radius,
|
||||
this.projectName,
|
||||
this.subtitle,
|
||||
this.keyword,
|
||||
this.secondaryBackgroundColors,
|
||||
this.keywords,
|
||||
this.keywordsBackgroundColors,
|
||||
this.titleStyle,
|
||||
this.subtitleStyle,
|
||||
this.keywordsStyle,
|
||||
super.key,
|
||||
});
|
||||
|
||||
/// The logo of the portfolio card.
|
||||
final Widget? logo;
|
||||
final double? padding;
|
||||
final double? radius;
|
||||
|
||||
/// Project name of the portfolio card.
|
||||
final TextWrapper? projectName;
|
||||
|
||||
/// Subtitle of the portfolio card.
|
||||
final TextWrapper? subtitle;
|
||||
final List<TextWrapper>? keyword;
|
||||
final Color? secondaryBackgroundColors;
|
||||
|
||||
/// The keywords of the portfolio card.
|
||||
final List<TextWrapper>? keywords;
|
||||
|
||||
/// Background colors for the keywords badges
|
||||
final MultiColor? keywordsBackgroundColors;
|
||||
|
||||
/// Styles the title of the card.
|
||||
final TextStyle? titleStyle;
|
||||
|
||||
/// Styles the subtitle of the card.
|
||||
final TextStyle? subtitleStyle;
|
||||
|
||||
/// Styles the keywords of the card.
|
||||
final TextStyle? keywordsStyle;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) => Column(
|
||||
@ -51,10 +68,12 @@ class PortfolioCardHeader extends StatelessWidget {
|
||||
if (logo != null) logo!,
|
||||
const Gap(_avatarAndTitlesSpacing),
|
||||
Expanded(
|
||||
child: InformationCardTitles(
|
||||
child: PortfolioCardTitles(
|
||||
axis: Axis.horizontal,
|
||||
title: projectName,
|
||||
subtitle: subtitle,
|
||||
titleStyle: titleStyle,
|
||||
subtitleStyle: subtitleStyle,
|
||||
),
|
||||
),
|
||||
],
|
||||
@ -62,27 +81,47 @@ class PortfolioCardHeader extends StatelessWidget {
|
||||
const Gap(10),
|
||||
Wrap(
|
||||
children: [
|
||||
if (keyword != null)
|
||||
...keyword!.map(
|
||||
if (keywords != null)
|
||||
...keywords!.map(
|
||||
(word) => Container(
|
||||
margin: const EdgeInsets.all(3),
|
||||
padding: const EdgeInsets.all(6),
|
||||
decoration: BoxDecoration(
|
||||
color: secondaryBackgroundColors ??
|
||||
gradient:
|
||||
ThemeHelper.maybeGetElement<MultiColor, Gradient>(
|
||||
[
|
||||
keywordsBackgroundColors,
|
||||
Theme.of(context)
|
||||
.extension<CardThemeExtension>()
|
||||
?.secondaryBackgroundColor,
|
||||
?.borderColors,
|
||||
CardThemeExtensionDefault.from(Theme.of(context))
|
||||
.borderColors,
|
||||
],
|
||||
valueValidator: (multiColor) => multiColor?.isGradient,
|
||||
transform: (multiColor) =>
|
||||
GradientHelper.linearFromMultiColor(multiColor!),
|
||||
),
|
||||
color: ThemeHelper.maybeGetElement<MultiColor, Color>(
|
||||
[
|
||||
keywordsBackgroundColors,
|
||||
Theme.of(context)
|
||||
.extension<CardThemeExtension>()
|
||||
?.borderColors,
|
||||
MultiColor.single(
|
||||
Theme.of(context).cardTheme.surfaceTintColor,
|
||||
),
|
||||
CardThemeExtensionDefault.from(Theme.of(context))
|
||||
.borderColors,
|
||||
],
|
||||
valueValidator: (multiColor) =>
|
||||
multiColor != null && multiColor.isColor,
|
||||
transform: (multiColor) => multiColor?.color,
|
||||
),
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
),
|
||||
child: Text(
|
||||
word.data,
|
||||
style: word.style ?? context.textTheme.bodySmall,
|
||||
textAlign: word.textAlign,
|
||||
textDirection: word.textDirection,
|
||||
softWrap: word.softWrap,
|
||||
overflow: word.overflow,
|
||||
maxLines: word.maxLines,
|
||||
selectionColor: word.selectionColor,
|
||||
child: GradientText.fromWrapper(
|
||||
word,
|
||||
style: context.textTheme.bodySmall,
|
||||
),
|
||||
),
|
||||
),
|
||||
|
@ -19,29 +19,34 @@ import 'package:gap/gap.dart';
|
||||
|
||||
class PortfolioCardImages extends StatelessWidget {
|
||||
const PortfolioCardImages({
|
||||
this.images,
|
||||
this.assets,
|
||||
this.radius,
|
||||
this.maxSize,
|
||||
super.key,
|
||||
});
|
||||
|
||||
final List<Widget>? images;
|
||||
final double? radius;
|
||||
/// The assets to display.
|
||||
final List<Widget>? assets;
|
||||
|
||||
/// The radius of the assets.
|
||||
final BorderRadiusGeometry? radius;
|
||||
|
||||
/// The max size of the assets.
|
||||
final Size? maxSize;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final result = <Widget>[];
|
||||
for (final image in images ?? List<Widget>.empty()) {
|
||||
for (final asset in assets ?? List<Widget>.empty()) {
|
||||
result.addAll([
|
||||
Expanded(
|
||||
child: ClipRRect(
|
||||
borderRadius: BorderRadius.circular(radius ?? 0),
|
||||
borderRadius: radius ?? BorderRadius.zero,
|
||||
child: Container(
|
||||
constraints: BoxConstraints(
|
||||
maxHeight: maxSize != null ? maxSize!.width : 100,
|
||||
maxHeight: maxSize != null ? maxSize!.width : double.infinity,
|
||||
),
|
||||
child: image,
|
||||
child: asset,
|
||||
),
|
||||
),
|
||||
),
|
||||
|
@ -20,7 +20,6 @@ import 'package:wyatt_component_copy_with_extension/wyatt_component_copy_with_ex
|
||||
import 'package:wyatt_ui_components/wyatt_ui_components.dart';
|
||||
import 'package:wyatt_ui_kit/src/components/cards/widgets/card_text.dart';
|
||||
import 'package:wyatt_ui_kit/src/components/cards/widgets/card_wrapper.dart';
|
||||
import 'package:wyatt_ui_kit/wyatt_ui_kit.dart';
|
||||
|
||||
part 'quote_card.g.dart';
|
||||
|
||||
@ -30,7 +29,6 @@ class QuoteCard extends QuoteCardComponent with $QuoteCardCWMixin {
|
||||
super.avatar,
|
||||
super.name,
|
||||
super.subtitle,
|
||||
super.gradient,
|
||||
super.quote,
|
||||
super.leftQuote,
|
||||
super.rightQuote,
|
||||
@ -38,90 +36,109 @@ class QuoteCard extends QuoteCardComponent with $QuoteCardCWMixin {
|
||||
super.padding,
|
||||
super.borderColors,
|
||||
super.backgroundColors,
|
||||
super.stroke,
|
||||
super.minSize,
|
||||
super.maxSize,
|
||||
super.shadow,
|
||||
super.titleStyle,
|
||||
super.subtitleStyle,
|
||||
super.bodyStyle,
|
||||
super.background,
|
||||
super.key,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) => CardWrapper(
|
||||
background: background,
|
||||
padding: padding,
|
||||
backgroundColors: backgroundColors,
|
||||
borderColors: borderColors,
|
||||
shadow: shadow,
|
||||
maxSize: maxSize,
|
||||
minSize: minSize,
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
leftQuote ??
|
||||
Align(
|
||||
alignment: Alignment.topLeft,
|
||||
child: GradientText(
|
||||
'“',
|
||||
style: GradientTextStyle.from(
|
||||
context.textTheme.titleLarge
|
||||
?.copyWith(fontWeight: FontWeight.bold),
|
||||
MultiColor(gradient?.colors),
|
||||
),
|
||||
),
|
||||
Widget build(BuildContext context) {
|
||||
final themeTitleStyle = ThemeHelper.maybeGetElement<TextStyle, TextStyle>(
|
||||
[
|
||||
titleStyle,
|
||||
Theme.of(context).extension<CardThemeExtension>()?.titleStyle,
|
||||
CardThemeExtensionDefault.from(Theme.of(context)).titleStyle,
|
||||
],
|
||||
);
|
||||
|
||||
final themeSubtitleStyle =
|
||||
ThemeHelper.maybeGetElement<TextStyle, TextStyle>(
|
||||
[
|
||||
subtitleStyle,
|
||||
Theme.of(context).extension<CardThemeExtension>()?.subtitleStyle,
|
||||
CardThemeExtensionDefault.from(Theme.of(context)).subtitleStyle,
|
||||
],
|
||||
);
|
||||
|
||||
final themeBodyStyle = ThemeHelper.maybeGetElement<TextStyle, TextStyle>(
|
||||
[
|
||||
bodyStyle,
|
||||
Theme.of(context).extension<CardThemeExtension>()?.bodyStyle,
|
||||
CardThemeExtensionDefault.from(Theme.of(context)).bodyStyle,
|
||||
],
|
||||
);
|
||||
|
||||
return CardWrapper(
|
||||
background: background,
|
||||
padding: padding,
|
||||
radius: radius,
|
||||
backgroundColors: backgroundColors,
|
||||
borderColors: borderColors,
|
||||
shadow: shadow,
|
||||
stroke: stroke,
|
||||
maxSize: maxSize,
|
||||
minSize: minSize,
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
leftQuote ??
|
||||
const Align(
|
||||
alignment: Alignment.topLeft,
|
||||
child: Text(
|
||||
'“',
|
||||
),
|
||||
if (quote != null) ...[
|
||||
CardText(
|
||||
quote!,
|
||||
textType: TextType.body,
|
||||
style: quote!.style,
|
||||
gradientColors: quote!.gradientColors,
|
||||
),
|
||||
],
|
||||
const Gap(15),
|
||||
rightQuote ??
|
||||
Align(
|
||||
alignment: Alignment.bottomRight,
|
||||
child: GradientText(
|
||||
'”',
|
||||
style: GradientTextStyle.from(
|
||||
context.textTheme.titleLarge
|
||||
?.copyWith(fontWeight: FontWeight.bold),
|
||||
MultiColor(gradient?.colors),
|
||||
),
|
||||
),
|
||||
),
|
||||
Row(
|
||||
children: [
|
||||
if (avatar != null) ...[
|
||||
avatar!,
|
||||
const Gap(25),
|
||||
],
|
||||
Expanded(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
if (name != null) ...[
|
||||
CardText(
|
||||
name!,
|
||||
textType: TextType.body,
|
||||
style: name!.style,
|
||||
gradientColors: name!.gradientColors,
|
||||
),
|
||||
],
|
||||
if (subtitle != null) ...[
|
||||
CardText(
|
||||
subtitle!,
|
||||
textType: TextType.subtitle,
|
||||
style: subtitle!.style,
|
||||
gradientColors: subtitle!.gradientColors,
|
||||
),
|
||||
],
|
||||
],
|
||||
),
|
||||
)
|
||||
],
|
||||
if (quote != null) ...[
|
||||
CardText.fromWrapper(
|
||||
quote!,
|
||||
style: themeBodyStyle,
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
const Gap(15),
|
||||
rightQuote ??
|
||||
const Align(
|
||||
alignment: Alignment.bottomRight,
|
||||
child: Text(
|
||||
'”',
|
||||
),
|
||||
),
|
||||
Row(
|
||||
children: [
|
||||
if (avatar != null) ...[
|
||||
avatar!,
|
||||
const Gap(25),
|
||||
],
|
||||
Expanded(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
if (name != null) ...[
|
||||
CardText.fromWrapper(
|
||||
name!,
|
||||
style: themeTitleStyle,
|
||||
textType: TextType.title,
|
||||
),
|
||||
],
|
||||
if (subtitle != null) ...[
|
||||
CardText.fromWrapper(
|
||||
subtitle!,
|
||||
style: themeSubtitleStyle,
|
||||
textType: TextType.subtitle,
|
||||
),
|
||||
],
|
||||
],
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -16,17 +16,15 @@ class $QuoteCardCWProxyImpl implements $QuoteCardComponentCWProxy {
|
||||
@override
|
||||
QuoteCard subtitle(TextWrapper? subtitle) => this(subtitle: subtitle);
|
||||
@override
|
||||
QuoteCard gradient(Gradient? gradient) => this(gradient: gradient);
|
||||
@override
|
||||
QuoteCard quote(TextWrapper? quote) => this(quote: quote);
|
||||
@override
|
||||
QuoteCard leftQuote(Widget? leftQuote) => this(leftQuote: leftQuote);
|
||||
@override
|
||||
QuoteCard rightQuote(Widget? rightQuote) => this(rightQuote: rightQuote);
|
||||
@override
|
||||
QuoteCard radius(double? radius) => this(radius: radius);
|
||||
QuoteCard radius(BorderRadiusGeometry? radius) => this(radius: radius);
|
||||
@override
|
||||
QuoteCard padding(double? padding) => this(padding: padding);
|
||||
QuoteCard padding(EdgeInsetsGeometry? padding) => this(padding: padding);
|
||||
@override
|
||||
QuoteCard borderColors(MultiColor? borderColors) =>
|
||||
this(borderColors: borderColors);
|
||||
@ -34,12 +32,21 @@ class $QuoteCardCWProxyImpl implements $QuoteCardComponentCWProxy {
|
||||
QuoteCard backgroundColors(MultiColor? backgroundColors) =>
|
||||
this(backgroundColors: backgroundColors);
|
||||
@override
|
||||
QuoteCard stroke(double? stroke) => this(stroke: stroke);
|
||||
@override
|
||||
QuoteCard minSize(Size? minSize) => this(minSize: minSize);
|
||||
@override
|
||||
QuoteCard maxSize(Size? maxSize) => this(maxSize: maxSize);
|
||||
@override
|
||||
QuoteCard shadow(BoxShadow? shadow) => this(shadow: shadow);
|
||||
@override
|
||||
QuoteCard titleStyle(TextStyle? titleStyle) => this(titleStyle: titleStyle);
|
||||
@override
|
||||
QuoteCard subtitleStyle(TextStyle? subtitleStyle) =>
|
||||
this(subtitleStyle: subtitleStyle);
|
||||
@override
|
||||
QuoteCard bodyStyle(TextStyle? bodyStyle) => this(bodyStyle: bodyStyle);
|
||||
@override
|
||||
QuoteCard background(Widget? background) => this(background: background);
|
||||
@override
|
||||
QuoteCard key(Key? key) => this(key: key);
|
||||
@ -48,17 +55,20 @@ class $QuoteCardCWProxyImpl implements $QuoteCardComponentCWProxy {
|
||||
Widget? avatar,
|
||||
TextWrapper? name,
|
||||
TextWrapper? subtitle,
|
||||
Gradient? gradient,
|
||||
TextWrapper? quote,
|
||||
Widget? leftQuote,
|
||||
Widget? rightQuote,
|
||||
double? radius,
|
||||
double? padding,
|
||||
BorderRadiusGeometry? radius,
|
||||
EdgeInsetsGeometry? padding,
|
||||
MultiColor? borderColors,
|
||||
MultiColor? backgroundColors,
|
||||
double? stroke,
|
||||
Size? minSize,
|
||||
Size? maxSize,
|
||||
BoxShadow? shadow,
|
||||
TextStyle? titleStyle,
|
||||
TextStyle? subtitleStyle,
|
||||
TextStyle? bodyStyle,
|
||||
Widget? background,
|
||||
Key? key,
|
||||
}) =>
|
||||
@ -66,7 +76,6 @@ class $QuoteCardCWProxyImpl implements $QuoteCardComponentCWProxy {
|
||||
avatar: avatar ?? _value.avatar,
|
||||
name: name ?? _value.name,
|
||||
subtitle: subtitle ?? _value.subtitle,
|
||||
gradient: gradient ?? _value.gradient,
|
||||
quote: quote ?? _value.quote,
|
||||
leftQuote: leftQuote ?? _value.leftQuote,
|
||||
rightQuote: rightQuote ?? _value.rightQuote,
|
||||
@ -74,9 +83,13 @@ class $QuoteCardCWProxyImpl implements $QuoteCardComponentCWProxy {
|
||||
padding: padding ?? _value.padding,
|
||||
borderColors: borderColors ?? _value.borderColors,
|
||||
backgroundColors: backgroundColors ?? _value.backgroundColors,
|
||||
stroke: stroke ?? _value.stroke,
|
||||
minSize: minSize ?? _value.minSize,
|
||||
maxSize: maxSize ?? _value.maxSize,
|
||||
shadow: shadow ?? _value.shadow,
|
||||
titleStyle: titleStyle ?? _value.titleStyle,
|
||||
subtitleStyle: subtitleStyle ?? _value.subtitleStyle,
|
||||
bodyStyle: bodyStyle ?? _value.bodyStyle,
|
||||
background: background ?? _value.background,
|
||||
key: key ?? _value.key,
|
||||
);
|
||||
|
@ -18,68 +18,118 @@ import 'package:flutter/material.dart';
|
||||
import 'package:gap/gap.dart';
|
||||
import 'package:wyatt_component_copy_with_extension/wyatt_component_copy_with_extension.dart';
|
||||
import 'package:wyatt_ui_components/wyatt_ui_components.dart';
|
||||
import 'package:wyatt_ui_kit/src/components/cards/skill_card/widgets/skill_card_header.dart';
|
||||
import 'package:wyatt_ui_kit/src/components/cards/skill_card/widgets/skill_card_horizontal_header.dart';
|
||||
import 'package:wyatt_ui_kit/src/components/cards/skill_card/widgets/skill_card_skills.dart';
|
||||
import 'package:wyatt_ui_kit/src/components/cards/skill_card/widgets/skill_card_vertical_header.dart';
|
||||
import 'package:wyatt_ui_kit/src/components/cards/widgets/card_text.dart';
|
||||
import 'package:wyatt_ui_kit/src/components/cards/widgets/card_wrapper.dart';
|
||||
|
||||
part 'skill_card.g.dart';
|
||||
|
||||
const _bodyTopSpacing = 25.0;
|
||||
|
||||
@ComponentCopyWithExtension()
|
||||
class SkillCard extends SkillCardComponent with $SkillCardCWMixin {
|
||||
const SkillCard({
|
||||
super.icon,
|
||||
super.gradient,
|
||||
super.secondaryBackgroundColors,
|
||||
super.axis,
|
||||
super.icons,
|
||||
super.title,
|
||||
super.subtitle,
|
||||
super.description,
|
||||
super.skills,
|
||||
super.leadingIcon,
|
||||
super.bulletColors,
|
||||
super.bulletIcon,
|
||||
super.radius,
|
||||
super.padding,
|
||||
super.borderColors,
|
||||
super.backgroundColors,
|
||||
super.stroke,
|
||||
super.minSize,
|
||||
super.maxSize = const Size(330, double.infinity),
|
||||
super.maxSize,
|
||||
super.shadow,
|
||||
super.titleStyle,
|
||||
super.subtitleStyle,
|
||||
super.bodyStyle,
|
||||
super.background,
|
||||
super.key,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) => CardWrapper(
|
||||
background: background,
|
||||
padding: padding,
|
||||
backgroundColors: backgroundColors,
|
||||
borderColors: borderColors,
|
||||
shadow: shadow,
|
||||
maxSize: maxSize,
|
||||
minSize: minSize,
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
SkillCardHeader(
|
||||
secondaryBackgroundColors: secondaryBackgroundColors,
|
||||
icon: icon,
|
||||
Widget build(BuildContext context) {
|
||||
final themeTitleStyle = ThemeHelper.maybeGetElement<TextStyle, TextStyle>(
|
||||
[
|
||||
titleStyle,
|
||||
Theme.of(context).extension<CardThemeExtension>()?.titleStyle,
|
||||
CardThemeExtensionDefault.from(Theme.of(context)).titleStyle,
|
||||
],
|
||||
);
|
||||
|
||||
final themeSubtitleStyle =
|
||||
ThemeHelper.maybeGetElement<TextStyle, TextStyle>(
|
||||
[
|
||||
subtitleStyle,
|
||||
Theme.of(context).extension<CardThemeExtension>()?.subtitleStyle,
|
||||
CardThemeExtensionDefault.from(Theme.of(context)).subtitleStyle,
|
||||
],
|
||||
);
|
||||
|
||||
final themeBodyStyle = ThemeHelper.maybeGetElement<TextStyle, TextStyle>(
|
||||
[
|
||||
bodyStyle,
|
||||
Theme.of(context).extension<CardThemeExtension>()?.bodyStyle,
|
||||
CardThemeExtensionDefault.from(Theme.of(context)).bodyStyle,
|
||||
],
|
||||
);
|
||||
|
||||
return CardWrapper(
|
||||
background: background,
|
||||
padding: padding,
|
||||
radius: radius,
|
||||
backgroundColors: backgroundColors,
|
||||
borderColors: borderColors,
|
||||
shadow: shadow,
|
||||
stroke: stroke,
|
||||
maxSize: maxSize,
|
||||
minSize: minSize,
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
if (axis == Axis.horizontal) ...[
|
||||
SkillCardHorizontalHeader(
|
||||
icons: icons,
|
||||
axis: axis,
|
||||
title: title,
|
||||
subtitle: subtitle,
|
||||
titleStyle: themeTitleStyle,
|
||||
subtitleStyle: themeSubtitleStyle,
|
||||
),
|
||||
] else ...[
|
||||
SkillCardVerticalHeader(
|
||||
icons: icons,
|
||||
axis: axis,
|
||||
title: title,
|
||||
subtitle: subtitle,
|
||||
titleStyle: themeTitleStyle,
|
||||
subtitleStyle: themeSubtitleStyle,
|
||||
),
|
||||
const Gap(25),
|
||||
if (description != null) ...[
|
||||
CardText(
|
||||
description!,
|
||||
textType: TextType.body,
|
||||
style: description!.style,
|
||||
gradientColors: description!.gradientColors,
|
||||
),
|
||||
const Gap(25),
|
||||
],
|
||||
if (skills != null)
|
||||
SkillCardSkills(
|
||||
gradient: gradient,
|
||||
skills: skills,
|
||||
leadingIcon: leadingIcon,
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
const Gap(_bodyTopSpacing),
|
||||
if (description != null) ...[
|
||||
CardText.fromWrapper(
|
||||
description!,
|
||||
style: themeBodyStyle,
|
||||
),
|
||||
const Gap(_bodyTopSpacing),
|
||||
],
|
||||
if (skills != null)
|
||||
SkillCardSkills(
|
||||
skills: skills,
|
||||
bulletColors: bulletColors,
|
||||
bulletIcon: bulletIcon,
|
||||
bodyStyle: themeBodyStyle,
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -10,26 +10,27 @@ class $SkillCardCWProxyImpl implements $SkillCardComponentCWProxy {
|
||||
const $SkillCardCWProxyImpl(this._value);
|
||||
final SkillCard _value;
|
||||
@override
|
||||
SkillCard icon(Widget? icon) => this(icon: icon);
|
||||
SkillCard axis(Axis? axis) => this(axis: axis);
|
||||
@override
|
||||
SkillCard gradient(List<Color>? gradient) => this(gradient: gradient);
|
||||
SkillCard icons(List<Widget>? icons) => this(icons: icons);
|
||||
@override
|
||||
SkillCard title(TextWrapper? title) => this(title: title);
|
||||
@override
|
||||
SkillCard subtitle(TextWrapper? subtitle) => this(subtitle: subtitle);
|
||||
@override
|
||||
SkillCard description(TextWrapper? description) =>
|
||||
this(description: description);
|
||||
@override
|
||||
SkillCard skills(List<TextWrapper>? skills) => this(skills: skills);
|
||||
@override
|
||||
SkillCard leadingIcon(IconData? leadingIcon) =>
|
||||
this(leadingIcon: leadingIcon);
|
||||
SkillCard bulletColors(MultiColor? bulletColors) =>
|
||||
this(bulletColors: bulletColors);
|
||||
@override
|
||||
SkillCard secondaryBackgroundColors(Color? secondaryBackgroundColors) =>
|
||||
this(secondaryBackgroundColors: secondaryBackgroundColors);
|
||||
SkillCard bulletIcon(Widget? bulletIcon) => this(bulletIcon: bulletIcon);
|
||||
@override
|
||||
SkillCard radius(double? radius) => this(radius: radius);
|
||||
SkillCard radius(BorderRadiusGeometry? radius) => this(radius: radius);
|
||||
@override
|
||||
SkillCard padding(double? padding) => this(padding: padding);
|
||||
SkillCard padding(EdgeInsetsGeometry? padding) => this(padding: padding);
|
||||
@override
|
||||
SkillCard borderColors(MultiColor? borderColors) =>
|
||||
this(borderColors: borderColors);
|
||||
@ -37,50 +38,68 @@ class $SkillCardCWProxyImpl implements $SkillCardComponentCWProxy {
|
||||
SkillCard backgroundColors(MultiColor? backgroundColors) =>
|
||||
this(backgroundColors: backgroundColors);
|
||||
@override
|
||||
SkillCard stroke(double? stroke) => this(stroke: stroke);
|
||||
@override
|
||||
SkillCard minSize(Size? minSize) => this(minSize: minSize);
|
||||
@override
|
||||
SkillCard maxSize(Size? maxSize) => this(maxSize: maxSize);
|
||||
@override
|
||||
SkillCard shadow(BoxShadow? shadow) => this(shadow: shadow);
|
||||
@override
|
||||
SkillCard titleStyle(TextStyle? titleStyle) => this(titleStyle: titleStyle);
|
||||
@override
|
||||
SkillCard subtitleStyle(TextStyle? subtitleStyle) =>
|
||||
this(subtitleStyle: subtitleStyle);
|
||||
@override
|
||||
SkillCard bodyStyle(TextStyle? bodyStyle) => this(bodyStyle: bodyStyle);
|
||||
@override
|
||||
SkillCard background(Widget? background) => this(background: background);
|
||||
@override
|
||||
SkillCard key(Key? key) => this(key: key);
|
||||
@override
|
||||
SkillCard call({
|
||||
Widget? icon,
|
||||
List<Color>? gradient,
|
||||
Axis? axis,
|
||||
List<Widget>? icons,
|
||||
TextWrapper? title,
|
||||
TextWrapper? subtitle,
|
||||
TextWrapper? description,
|
||||
List<TextWrapper>? skills,
|
||||
IconData? leadingIcon,
|
||||
Color? secondaryBackgroundColors,
|
||||
double? radius,
|
||||
double? padding,
|
||||
MultiColor? bulletColors,
|
||||
Widget? bulletIcon,
|
||||
BorderRadiusGeometry? radius,
|
||||
EdgeInsetsGeometry? padding,
|
||||
MultiColor? borderColors,
|
||||
MultiColor? backgroundColors,
|
||||
double? stroke,
|
||||
Size? minSize,
|
||||
Size? maxSize,
|
||||
BoxShadow? shadow,
|
||||
TextStyle? titleStyle,
|
||||
TextStyle? subtitleStyle,
|
||||
TextStyle? bodyStyle,
|
||||
Widget? background,
|
||||
Key? key,
|
||||
}) =>
|
||||
SkillCard(
|
||||
icon: icon ?? _value.icon,
|
||||
gradient: gradient ?? _value.gradient,
|
||||
secondaryBackgroundColors:
|
||||
secondaryBackgroundColors ?? _value.secondaryBackgroundColors,
|
||||
axis: axis ?? _value.axis,
|
||||
icons: icons ?? _value.icons,
|
||||
title: title ?? _value.title,
|
||||
subtitle: subtitle ?? _value.subtitle,
|
||||
description: description ?? _value.description,
|
||||
skills: skills ?? _value.skills,
|
||||
leadingIcon: leadingIcon ?? _value.leadingIcon,
|
||||
bulletColors: bulletColors ?? _value.bulletColors,
|
||||
bulletIcon: bulletIcon ?? _value.bulletIcon,
|
||||
radius: radius ?? _value.radius,
|
||||
padding: padding ?? _value.padding,
|
||||
borderColors: borderColors ?? _value.borderColors,
|
||||
backgroundColors: backgroundColors ?? _value.backgroundColors,
|
||||
stroke: stroke ?? _value.stroke,
|
||||
minSize: minSize ?? _value.minSize,
|
||||
maxSize: maxSize ?? _value.maxSize,
|
||||
shadow: shadow ?? _value.shadow,
|
||||
titleStyle: titleStyle ?? _value.titleStyle,
|
||||
subtitleStyle: subtitleStyle ?? _value.subtitleStyle,
|
||||
bodyStyle: bodyStyle ?? _value.bodyStyle,
|
||||
background: background ?? _value.background,
|
||||
key: key ?? _value.key,
|
||||
);
|
||||
|
@ -1,55 +0,0 @@
|
||||
// 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:gap/gap.dart';
|
||||
import 'package:wyatt_ui_components/wyatt_ui_components.dart';
|
||||
import 'package:wyatt_ui_kit/src/components/cards/widgets/card_text.dart';
|
||||
|
||||
class SkillCardHeader extends StatelessWidget {
|
||||
const SkillCardHeader({
|
||||
super.key,
|
||||
this.icon,
|
||||
this.title,
|
||||
this.secondaryBackgroundColors,
|
||||
});
|
||||
|
||||
final Widget? icon;
|
||||
final TextWrapper? title;
|
||||
final Color? secondaryBackgroundColors;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) => Column(
|
||||
children: [
|
||||
if (icon != null) ...[
|
||||
icon!,
|
||||
const Gap(25),
|
||||
],
|
||||
Column(
|
||||
children: [
|
||||
if (title != null) ...[
|
||||
CardText(
|
||||
title!,
|
||||
textType: TextType.title,
|
||||
style: title!.style,
|
||||
gradientColors: title!.gradientColors,
|
||||
),
|
||||
],
|
||||
],
|
||||
)
|
||||
],
|
||||
);
|
||||
}
|
@ -19,19 +19,27 @@ import 'package:gap/gap.dart';
|
||||
import 'package:wyatt_ui_components/wyatt_ui_components.dart';
|
||||
import 'package:wyatt_ui_kit/src/components/cards/widgets/card_text.dart';
|
||||
import 'package:wyatt_ui_kit/src/components/gradients/gradient_icon.dart';
|
||||
import 'package:wyatt_ui_kit/src/core/helpers/linear_gradient_helper.dart';
|
||||
|
||||
class SkillCardSkills extends StatelessWidget {
|
||||
const SkillCardSkills({
|
||||
super.key,
|
||||
this.skills,
|
||||
this.leadingIcon,
|
||||
this.gradient,
|
||||
this.bulletColors,
|
||||
this.bulletIcon,
|
||||
this.bodyStyle,
|
||||
});
|
||||
|
||||
/// Skills to be displayed
|
||||
final List<TextWrapper>? skills;
|
||||
final IconData? leadingIcon;
|
||||
final List<Color>? gradient;
|
||||
|
||||
/// Gradient of skill icons.
|
||||
final MultiColor? bulletColors;
|
||||
|
||||
/// Icon to be displayed before each skill.
|
||||
final Widget? bulletIcon;
|
||||
|
||||
/// Body style of the card.
|
||||
final TextStyle? bodyStyle;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) => Column(
|
||||
@ -39,18 +47,22 @@ class SkillCardSkills extends StatelessWidget {
|
||||
.map(
|
||||
(skill) => Row(
|
||||
children: [
|
||||
Icon(
|
||||
leadingIcon ?? Icons.check,
|
||||
).toGradient(
|
||||
LinearGradientHelper.fromNullableColors(gradient),
|
||||
),
|
||||
if (bulletIcon != null) ...[
|
||||
GradientIcon.fromWidget(
|
||||
bulletIcon!,
|
||||
gradientColors: bulletColors,
|
||||
),
|
||||
] else ...[
|
||||
GradientIcon(
|
||||
icon: Icons.check,
|
||||
gradientColors: bulletColors ?? const MultiColor([]),
|
||||
),
|
||||
],
|
||||
const Gap(10),
|
||||
Expanded(
|
||||
child: CardText(
|
||||
child: CardText.fromWrapper(
|
||||
skill,
|
||||
textType: TextType.body,
|
||||
style: skill.style,
|
||||
gradientColors: skill.gradientColors,
|
||||
style: bodyStyle,
|
||||
),
|
||||
),
|
||||
],
|
||||
|
@ -1,9 +1,16 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
/// {@template card_background}
|
||||
/// A widget that displays a background for a card.
|
||||
/// {@endtemplate}
|
||||
class CardBackground extends StatefulWidget {
|
||||
/// {@macro card_background}
|
||||
const CardBackground({super.key, this.background, this.cardKey});
|
||||
|
||||
/// Background to display
|
||||
final Widget? background;
|
||||
|
||||
/// Key of the card to display the background for
|
||||
final GlobalKey? cardKey;
|
||||
|
||||
@override
|
||||
|
@ -24,46 +24,67 @@ enum TextType {
|
||||
body;
|
||||
}
|
||||
|
||||
/// {@template card_text}
|
||||
/// Wrapper for [GradientText] that uses the [CardThemeExtension] to
|
||||
/// determine the text style to use depending on the [textType].
|
||||
/// {@endtemplate}
|
||||
class CardText extends StatelessWidget {
|
||||
/// {@macro card_text}
|
||||
const CardText(
|
||||
this.text, {
|
||||
required this.textType,
|
||||
this.style,
|
||||
this.gradientColors,
|
||||
this.textType = TextType.body,
|
||||
super.key,
|
||||
});
|
||||
|
||||
final TextWrapper text;
|
||||
/// Creates a [CardText] from a [TextWrapper].
|
||||
///
|
||||
/// The [textType] is used to determine the [CardThemeExtension] style to use.
|
||||
///
|
||||
/// You can also pass a [gradientColors] and [style] as fallbacks if the
|
||||
/// [TextWrapper] doesn't have them.
|
||||
factory CardText.fromWrapper(
|
||||
TextWrapper wrapper, {
|
||||
TextType textType = TextType.body,
|
||||
MultiColor? gradientColors,
|
||||
TextStyle? style,
|
||||
}) =>
|
||||
CardText(
|
||||
GradientText.fromWrapper(
|
||||
wrapper,
|
||||
gradientColors: gradientColors,
|
||||
style: style,
|
||||
),
|
||||
textType: textType,
|
||||
);
|
||||
|
||||
final GradientText text;
|
||||
final TextType textType;
|
||||
final TextStyle? style;
|
||||
final MultiColor? gradientColors;
|
||||
|
||||
TextStyle? _getStyle(BuildContext context) {
|
||||
if (style != null) {
|
||||
return style;
|
||||
if (text.style != null) {
|
||||
return text.style;
|
||||
} else {
|
||||
final cardThemeExtension =
|
||||
Theme.of(context).extension<CardThemeExtension>();
|
||||
Theme.of(context).extension<CardThemeExtension>() ??
|
||||
CardThemeExtensionDefault.from(Theme.of(context));
|
||||
switch (textType) {
|
||||
case TextType.title:
|
||||
return cardThemeExtension?.title ?? context.textTheme.titleLarge;
|
||||
return cardThemeExtension.titleStyle ??
|
||||
CardThemeExtensionDefault.from(Theme.of(context)).titleStyle;
|
||||
case TextType.subtitle:
|
||||
return cardThemeExtension?.subtitle ?? context.textTheme.titleMedium;
|
||||
return cardThemeExtension.subtitleStyle ??
|
||||
CardThemeExtensionDefault.from(Theme.of(context)).subtitleStyle;
|
||||
case TextType.body:
|
||||
return cardThemeExtension?.body ?? context.textTheme.bodyMedium;
|
||||
return cardThemeExtension.bodyStyle ??
|
||||
CardThemeExtensionDefault.from(Theme.of(context)).bodyStyle;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) => Text(
|
||||
text.data,
|
||||
Widget build(BuildContext context) => text.copyWith
|
||||
.call(
|
||||
style: _getStyle(context),
|
||||
textAlign: text.textAlign,
|
||||
textDirection: text.textDirection,
|
||||
softWrap: text.softWrap,
|
||||
overflow: text.overflow,
|
||||
maxLines: text.maxLines,
|
||||
selectionColor: text.selectionColor,
|
||||
).toGradient(gradientColors: gradientColors);
|
||||
)
|
||||
.build(context);
|
||||
}
|
||||
|
@ -19,128 +19,222 @@ import 'package:wyatt_ui_components/wyatt_ui_components.dart';
|
||||
import 'package:wyatt_ui_kit/src/components/cards/widgets/card_background.dart';
|
||||
import 'package:wyatt_ui_kit/wyatt_ui_kit.dart';
|
||||
|
||||
/// {@template card_wrapper}
|
||||
/// Common wrapper for all cards
|
||||
/// {@endtemplate}
|
||||
class CardWrapper extends StatelessWidget {
|
||||
/// {@macro card_wrapper}
|
||||
CardWrapper({
|
||||
required this.child,
|
||||
required this.backgroundColors,
|
||||
required this.borderColors,
|
||||
required this.shadow,
|
||||
required this.minSize,
|
||||
required this.maxSize,
|
||||
required this.padding,
|
||||
required this.background,
|
||||
this.radius,
|
||||
this.padding,
|
||||
this.foregroundColors,
|
||||
this.backgroundColors,
|
||||
this.borderColors,
|
||||
this.stroke,
|
||||
this.shadow,
|
||||
this.minSize,
|
||||
this.maxSize,
|
||||
this.background,
|
||||
super.key,
|
||||
});
|
||||
|
||||
final Widget? background;
|
||||
final Widget child;
|
||||
/// 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 foreground gradient colors (from left to right)
|
||||
///
|
||||
/// Default to `Theme.colorScheme.onPrimary`
|
||||
final MultiColor? foregroundColors;
|
||||
|
||||
/// 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, double.infinity)`
|
||||
final Size? minSize;
|
||||
|
||||
/// Maximum size of the card
|
||||
///
|
||||
/// Default to `const Size(double.infinity, double.infinity)`
|
||||
final Size? maxSize;
|
||||
final double? padding;
|
||||
|
||||
/// Background of the card
|
||||
final Widget? background;
|
||||
|
||||
final Widget child;
|
||||
|
||||
final GlobalKey _key = GlobalKey();
|
||||
|
||||
Widget _buildChild(Widget child) => (background != null)
|
||||
? Stack(
|
||||
alignment: Alignment.center,
|
||||
children: [
|
||||
CardBackground(
|
||||
cardKey: _key,
|
||||
background: background,
|
||||
),
|
||||
Padding(
|
||||
padding: EdgeInsets.all(
|
||||
padding ?? 25,
|
||||
Widget _buildChild(BuildContext context, Widget child) {
|
||||
final themePadding =
|
||||
ThemeHelper.getElement<EdgeInsetsGeometry, EdgeInsetsGeometry>(
|
||||
[
|
||||
padding,
|
||||
Theme.of(context).extension<CardThemeExtension>()?.padding,
|
||||
CardThemeExtensionDefault.from(Theme.of(context)).padding,
|
||||
],
|
||||
);
|
||||
|
||||
return (background != null)
|
||||
? Stack(
|
||||
alignment: Alignment.center,
|
||||
children: [
|
||||
CardBackground(
|
||||
cardKey: _key,
|
||||
background: background,
|
||||
),
|
||||
child: child,
|
||||
),
|
||||
],
|
||||
)
|
||||
: Padding(
|
||||
padding: EdgeInsets.all(
|
||||
padding ?? 25,
|
||||
),
|
||||
child: child,
|
||||
);
|
||||
Padding(
|
||||
padding: themePadding,
|
||||
child: child,
|
||||
),
|
||||
],
|
||||
)
|
||||
: Padding(
|
||||
padding: themePadding,
|
||||
child: child,
|
||||
);
|
||||
}
|
||||
|
||||
List<BoxShadow> _shadow(BuildContext context) {
|
||||
final themeShadow = ThemeHelper.getThemeElement<BoxShadow, BoxShadow>(
|
||||
final themeShadow = ThemeHelper.maybeGetElement<BoxShadow, BoxShadow>(
|
||||
[
|
||||
shadow,
|
||||
Theme.of(context).extension<CardThemeExtension>()?.shadowColor,
|
||||
Theme.of(context).extension<CardThemeExtension>()?.shadow,
|
||||
CardThemeExtensionDefault.from(Theme.of(context)).shadow,
|
||||
],
|
||||
valueValidator: (shadow) => shadow != null,
|
||||
transform: (shadow) => shadow,
|
||||
);
|
||||
return (themeShadow != null) ? [themeShadow] : [];
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) => SelectionArea(
|
||||
child: DecoratedBox(
|
||||
key: _key,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: const BorderRadius.all(Radius.circular(12)),
|
||||
gradient: ThemeHelper.getThemeElement<MultiColor, Gradient>(
|
||||
[
|
||||
backgroundColors,
|
||||
Theme.of(context)
|
||||
.extension<CardThemeExtension>()
|
||||
?.backgroundColors,
|
||||
],
|
||||
valueValidator: (multiColor) => multiColor?.isGradient,
|
||||
transform: (multiColor) =>
|
||||
LinearGradientHelper.fromMultiColor(multiColor!),
|
||||
),
|
||||
color: ThemeHelper.getThemeElement<MultiColor, Color>(
|
||||
[
|
||||
backgroundColors,
|
||||
Theme.of(context)
|
||||
.extension<CardThemeExtension>()
|
||||
?.backgroundColors,
|
||||
MultiColor.single(Theme.of(context).cardColor),
|
||||
],
|
||||
valueValidator: (multiColor) =>
|
||||
multiColor != null && multiColor.isColor,
|
||||
transform: (multiColor) => multiColor?.color,
|
||||
),
|
||||
border: ThemeHelper.getThemeElement<MultiColor, BoxBorder>(
|
||||
[
|
||||
borderColors,
|
||||
Theme.of(context).extension<CardThemeExtension>()?.borderColors,
|
||||
Theme.of(context)
|
||||
.extension<CardThemeExtension>()
|
||||
?.backgroundColors,
|
||||
],
|
||||
valueValidator: (multiColor) =>
|
||||
multiColor != null && multiColor.isColor,
|
||||
transform: (multiColor) {
|
||||
if (multiColor!.isGradient) {
|
||||
return GradientBoxBorder(
|
||||
gradient: LinearGradientHelper.fromMultiColor(multiColor),
|
||||
);
|
||||
}
|
||||
return Border.all(
|
||||
color: multiColor.color,
|
||||
);
|
||||
},
|
||||
),
|
||||
boxShadow: _shadow(context),
|
||||
Widget build(BuildContext context) {
|
||||
final themeBorderStroke = ThemeHelper.getElement<double, double>(
|
||||
[
|
||||
stroke,
|
||||
Theme.of(context).extension<CardThemeExtension>()?.stroke,
|
||||
CardThemeExtensionDefault.from(Theme.of(context)).stroke,
|
||||
],
|
||||
);
|
||||
|
||||
final themeBorderRadius =
|
||||
ThemeHelper.getElement<BorderRadiusGeometry, BorderRadiusGeometry>(
|
||||
[
|
||||
radius,
|
||||
Theme.of(context).extension<CardThemeExtension>()?.radius,
|
||||
CardThemeExtensionDefault.from(Theme.of(context)).radius
|
||||
],
|
||||
);
|
||||
|
||||
final themeMinSize = ThemeHelper.maybeGetElement<Size, Size>(
|
||||
[
|
||||
minSize,
|
||||
Theme.of(context).extension<CardThemeExtension>()?.minSize,
|
||||
CardThemeExtensionDefault.from(Theme.of(context)).minSize
|
||||
],
|
||||
);
|
||||
|
||||
final themeMaxSize = ThemeHelper.maybeGetElement<Size, Size>(
|
||||
[
|
||||
maxSize,
|
||||
Theme.of(context).extension<CardThemeExtension>()?.maxSize,
|
||||
CardThemeExtensionDefault.from(Theme.of(context)).maxSize
|
||||
],
|
||||
);
|
||||
|
||||
return SelectionArea(
|
||||
child: DecoratedBox(
|
||||
key: _key,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: themeBorderRadius,
|
||||
gradient: ThemeHelper.maybeGetElement<MultiColor, Gradient>(
|
||||
[
|
||||
backgroundColors,
|
||||
Theme.of(context)
|
||||
.extension<CardThemeExtension>()
|
||||
?.backgroundColors,
|
||||
CardThemeExtensionDefault.from(Theme.of(context)).backgroundColors
|
||||
],
|
||||
valueValidator: (multiColor) => multiColor?.isGradient,
|
||||
transform: (multiColor) =>
|
||||
GradientHelper.linearFromMultiColor(multiColor!),
|
||||
),
|
||||
child: (minSize != null && maxSize != null)
|
||||
? ConstrainedBox(
|
||||
constraints: BoxConstraints(
|
||||
minWidth: minSize!.width,
|
||||
minHeight: minSize!.height,
|
||||
maxWidth: maxSize!.width,
|
||||
maxHeight: maxSize!.height,
|
||||
),
|
||||
child: _buildChild(child),
|
||||
)
|
||||
: _buildChild(child),
|
||||
color: ThemeHelper.maybeGetElement<MultiColor, Color>(
|
||||
[
|
||||
backgroundColors,
|
||||
Theme.of(context)
|
||||
.extension<CardThemeExtension>()
|
||||
?.backgroundColors,
|
||||
CardThemeExtensionDefault.from(Theme.of(context))
|
||||
.backgroundColors,
|
||||
],
|
||||
valueValidator: (multiColor) =>
|
||||
multiColor != null && multiColor.isColor,
|
||||
transform: (multiColor) => multiColor?.color,
|
||||
),
|
||||
border: ThemeHelper.maybeGetElement<MultiColor, BoxBorder>(
|
||||
[
|
||||
borderColors,
|
||||
Theme.of(context).extension<CardThemeExtension>()?.borderColors,
|
||||
Theme.of(context)
|
||||
.extension<CardThemeExtension>()
|
||||
?.backgroundColors,
|
||||
CardThemeExtensionDefault.from(Theme.of(context)).borderColors,
|
||||
],
|
||||
valueValidator: (multiColor) =>
|
||||
multiColor != null && multiColor.isColor,
|
||||
transform: (multiColor) {
|
||||
if (multiColor!.isGradient) {
|
||||
return GradientBoxBorder(
|
||||
gradient: GradientHelper.linearFromMultiColor(multiColor),
|
||||
width: themeBorderStroke,
|
||||
);
|
||||
}
|
||||
return Border.all(
|
||||
color: multiColor.color,
|
||||
width: themeBorderStroke,
|
||||
);
|
||||
},
|
||||
),
|
||||
boxShadow: _shadow(context),
|
||||
),
|
||||
);
|
||||
child: (themeMinSize != null || themeMaxSize != null)
|
||||
? ConstrainedBox(
|
||||
constraints: BoxConstraints(
|
||||
minWidth: themeMinSize?.width ?? 0,
|
||||
minHeight: themeMinSize?.height ?? 0,
|
||||
maxWidth: themeMaxSize?.width ?? double.infinity,
|
||||
maxHeight: themeMaxSize?.height ?? double.infinity,
|
||||
),
|
||||
child: _buildChild(context, child),
|
||||
)
|
||||
: _buildChild(context, child),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -44,7 +44,7 @@ class Loader extends LoaderComponent with $LoaderCWMixin {
|
||||
child: RepaintBoundary(
|
||||
child: CustomPaint(
|
||||
painter: _LoaderPainter(
|
||||
ThemeHelper.getThemeElement<MultiColor, MultiColor>(
|
||||
ThemeHelper.getElement<MultiColor, MultiColor>(
|
||||
[
|
||||
colors,
|
||||
Theme.of(context).extension<LoaderThemeExtension>()?.colors,
|
||||
@ -61,9 +61,9 @@ class Loader extends LoaderComponent with $LoaderCWMixin {
|
||||
valueValidator: (multiColor) =>
|
||||
multiColor != null && multiColor.isColor,
|
||||
transform: (multiColor) => multiColor,
|
||||
)!,
|
||||
),
|
||||
dimension / 2,
|
||||
ThemeHelper.getThemeElement<double, double>(
|
||||
ThemeHelper.getElement<double, double>(
|
||||
[
|
||||
stroke,
|
||||
Theme.of(context).extension<LoaderThemeExtension>()?.stroke,
|
||||
@ -71,7 +71,7 @@ class Loader extends LoaderComponent with $LoaderCWMixin {
|
||||
],
|
||||
valueValidator: (stroke) => stroke != null,
|
||||
transform: (stroke) => stroke,
|
||||
)!,
|
||||
),
|
||||
flip: flip ?? false,
|
||||
),
|
||||
)
|
||||
|
@ -39,7 +39,7 @@ class RichTextBuilder extends RichTextBuilderComponent
|
||||
text ?? '',
|
||||
regex,
|
||||
RichTextStyleParameter(
|
||||
ThemeHelper.getThemeElement<TextStyle, TextStyle>(
|
||||
ThemeHelper.getElement<TextStyle, TextStyle>(
|
||||
[
|
||||
defaultStyle,
|
||||
Theme.of(context)
|
||||
@ -50,8 +50,7 @@ class RichTextBuilder extends RichTextBuilderComponent
|
||||
valueValidator: (style) => style != null,
|
||||
transform: (style) => style,
|
||||
),
|
||||
ThemeHelper.getThemeElement<Map<String, TextStyle>,
|
||||
Map<String, TextStyle>>(
|
||||
ThemeHelper.getElement<Map<String, TextStyle>, Map<String, TextStyle>>(
|
||||
[
|
||||
styles,
|
||||
Theme.of(context)
|
||||
@ -61,7 +60,7 @@ class RichTextBuilder extends RichTextBuilderComponent
|
||||
],
|
||||
valueValidator: (styles) => styles != null,
|
||||
transform: (styles) => styles,
|
||||
)!,
|
||||
),
|
||||
null,
|
||||
),
|
||||
);
|
||||
@ -71,7 +70,10 @@ class RichTextBuilder extends RichTextBuilderComponent
|
||||
if (style is GradientTextStyle?) {
|
||||
return WidgetSpan(
|
||||
child: GradientText(
|
||||
content,
|
||||
data: content,
|
||||
gradientColors:
|
||||
(style as GradientTextStyle?)?.gradientColors ??
|
||||
const MultiColor([]),
|
||||
style: style,
|
||||
softWrap: true,
|
||||
textHeightBehavior: const TextHeightBehavior(
|
||||
|
@ -33,6 +33,13 @@ class TextInputState extends Equatable {
|
||||
|
||||
final String? statusMessage;
|
||||
|
||||
bool get isDisabled => controlState.isDisabled();
|
||||
bool get isEnabled => controlState.isEnabled();
|
||||
bool get isFocused => controlState.isFocused();
|
||||
bool get isHovered => controlState.isHovered();
|
||||
bool get isTapped => controlState.isTapped();
|
||||
bool get isInvalid => statusState == StatusState.error;
|
||||
|
||||
@override
|
||||
List<Object?> get props => [controlState, statusState, statusMessage];
|
||||
|
||||
|
@ -38,8 +38,8 @@ class TextInput extends TextInputComponent with $TextInputCWMixin {
|
||||
super.hint,
|
||||
super.normalStyle,
|
||||
super.focusedStyle,
|
||||
super.errorStyle,
|
||||
super.disableStyle,
|
||||
super.invalidStyle,
|
||||
super.disabledStyle,
|
||||
super.controller,
|
||||
super.focusNode,
|
||||
super.keyboardType,
|
||||
@ -105,8 +105,8 @@ class TextInput extends TextInputComponent with $TextInputCWMixin {
|
||||
hint: hint,
|
||||
focusedStyle: focusedStyle,
|
||||
normalStyle: normalStyle,
|
||||
errorStyle: errorStyle,
|
||||
disableStyle: disableStyle,
|
||||
invalidStyle: invalidStyle,
|
||||
disabledStyle: disabledStyle,
|
||||
prefixIcon: prefixIcon,
|
||||
prefixText: prefixText,
|
||||
suffixIcon: suffixIcon,
|
||||
|
@ -35,11 +35,11 @@ class $TextInputCWProxyImpl implements $TextInputComponentCWProxy {
|
||||
TextInput focusedStyle(TextInputStyle? focusedStyle) =>
|
||||
this(focusedStyle: focusedStyle);
|
||||
@override
|
||||
TextInput errorStyle(TextInputStyle? errorStyle) =>
|
||||
this(errorStyle: errorStyle);
|
||||
TextInput invalidStyle(TextInputStyle? invalidStyle) =>
|
||||
this(invalidStyle: invalidStyle);
|
||||
@override
|
||||
TextInput disableStyle(TextInputStyle? disableStyle) =>
|
||||
this(disableStyle: disableStyle);
|
||||
TextInput disabledStyle(TextInputStyle? disabledStyle) =>
|
||||
this(disabledStyle: disabledStyle);
|
||||
@override
|
||||
TextInput controller(TextEditingController? controller) =>
|
||||
this(controller: controller);
|
||||
@ -206,8 +206,8 @@ class $TextInputCWProxyImpl implements $TextInputComponentCWProxy {
|
||||
TextWrapper? hint,
|
||||
TextInputStyle? normalStyle,
|
||||
TextInputStyle? focusedStyle,
|
||||
TextInputStyle? errorStyle,
|
||||
TextInputStyle? disableStyle,
|
||||
TextInputStyle? invalidStyle,
|
||||
TextInputStyle? disabledStyle,
|
||||
TextEditingController? controller,
|
||||
FocusNode? focusNode,
|
||||
TextInputType? keyboardType,
|
||||
@ -277,8 +277,8 @@ class $TextInputCWProxyImpl implements $TextInputComponentCWProxy {
|
||||
hint: hint ?? _value.hint,
|
||||
normalStyle: normalStyle ?? _value.normalStyle,
|
||||
focusedStyle: focusedStyle ?? _value.focusedStyle,
|
||||
errorStyle: errorStyle ?? _value.errorStyle,
|
||||
disableStyle: disableStyle ?? _value.disableStyle,
|
||||
invalidStyle: invalidStyle ?? _value.invalidStyle,
|
||||
disabledStyle: disabledStyle ?? _value.disabledStyle,
|
||||
controller: controller ?? _value.controller,
|
||||
focusNode: focusNode ?? _value.focusNode,
|
||||
keyboardType: keyboardType ?? _value.keyboardType,
|
||||
|
@ -40,8 +40,8 @@ class TextInputScreen extends CubitScreen<TextInputCubit, TextInputState> {
|
||||
this.hint,
|
||||
this.normalStyle,
|
||||
this.focusedStyle,
|
||||
this.errorStyle,
|
||||
this.disableStyle,
|
||||
this.invalidStyle,
|
||||
this.disabledStyle,
|
||||
this.magnifierConfiguration,
|
||||
this.controller,
|
||||
this.focusNode,
|
||||
@ -157,8 +157,8 @@ class TextInputScreen extends CubitScreen<TextInputCubit, TextInputState> {
|
||||
|
||||
final TextInputStyle? normalStyle;
|
||||
final TextInputStyle? focusedStyle;
|
||||
final TextInputStyle? errorStyle;
|
||||
final TextInputStyle? disableStyle;
|
||||
final TextInputStyle? invalidStyle;
|
||||
final TextInputStyle? disabledStyle;
|
||||
|
||||
final TextWrapper? label;
|
||||
final TextWrapper? hint;
|
||||
@ -202,7 +202,7 @@ class TextInputScreen extends CubitScreen<TextInputCubit, TextInputState> {
|
||||
textInputStyle = focusedStyle;
|
||||
break;
|
||||
case ControlState.disabled:
|
||||
textInputStyle = disableStyle;
|
||||
textInputStyle = disabledStyle;
|
||||
break;
|
||||
case ControlState.normal:
|
||||
textInputStyle = normalStyle;
|
||||
@ -216,7 +216,7 @@ class TextInputScreen extends CubitScreen<TextInputCubit, TextInputState> {
|
||||
TextInputStyle? style;
|
||||
switch (extra?.statusState) {
|
||||
case StatusState.error:
|
||||
style = errorStyle;
|
||||
style = invalidStyle;
|
||||
break;
|
||||
case StatusState.initial:
|
||||
case StatusState.success:
|
||||
@ -262,7 +262,7 @@ class TextInputScreen extends CubitScreen<TextInputCubit, TextInputState> {
|
||||
child: AnimatedContainer(
|
||||
duration: const Duration(milliseconds: 600),
|
||||
decoration: BoxDecoration(
|
||||
boxShadow: style.boxShadow != null ? [style.boxShadow!] : null,
|
||||
boxShadow: style.shadow != null ? [style.shadow!] : null,
|
||||
gradient: style.backgroundColors?.isGradient ?? false
|
||||
? LinearGradient(colors: style.backgroundColors!.colors)
|
||||
: null,
|
||||
@ -312,7 +312,7 @@ class TextInputScreen extends CubitScreen<TextInputCubit, TextInputState> {
|
||||
focusNode: focusNode ?? _focusNode,
|
||||
label: (state.statusState == StatusState.error &&
|
||||
(state.statusMessage?.isNotEmpty ?? false))
|
||||
? state.statusMessage?.wrap()
|
||||
? TextWrapper(state.statusMessage!)
|
||||
: label,
|
||||
labelStyle: style.labelStyle,
|
||||
)
|
||||
|
@ -17,8 +17,6 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:wyatt_ui_components/wyatt_ui_components.dart';
|
||||
import 'package:wyatt_ui_kit/src/components/text_inputs/cubit/text_input_cubit.dart';
|
||||
import 'package:wyatt_ui_kit/src/core/core.dart';
|
||||
import 'package:wyatt_ui_kit/src/domain/text_input_theme_extension.dart';
|
||||
|
||||
class TextInputThemeResolver extends ThemeResolver<TextInputStyle,
|
||||
TextInputThemeExtension, TextInputState> {
|
||||
@ -26,130 +24,44 @@ class TextInputThemeResolver extends ThemeResolver<TextInputStyle,
|
||||
required this.customStyleFn,
|
||||
});
|
||||
|
||||
@override
|
||||
final TextInputStyle? Function(
|
||||
BuildContext context, {
|
||||
TextInputState? extra,
|
||||
}) customStyleFn;
|
||||
|
||||
@override
|
||||
TextInputStyle computeDefaultValue(
|
||||
BuildContext context, {
|
||||
TextInputState? extra,
|
||||
}) {
|
||||
TextStyle? labelStyle = context.textTheme.labelLarge
|
||||
?.copyWith(color: Theme.of(context).unselectedWidgetColor);
|
||||
|
||||
TextStyle? hintStyle = context.textTheme.labelLarge;
|
||||
TextStyle? prefixStyle = context.textTheme.bodyMedium;
|
||||
TextStyle? suffixStyle = context.textTheme.bodyMedium;
|
||||
TextStyle? inputStyle = context.textTheme.bodyMedium;
|
||||
|
||||
Color? iconColor = context.colorScheme.inversePrimary;
|
||||
Color? prefixIconColor = Theme.of(context).unselectedWidgetColor;
|
||||
Color? suffixIconColor = Theme.of(context).unselectedWidgetColor;
|
||||
|
||||
Color? borderColors = Theme.of(context).unselectedWidgetColor;
|
||||
|
||||
MultiColor? backgroundColors;
|
||||
BoxShadow? boxShadow;
|
||||
|
||||
final BorderRadiusGeometry radius = BorderRadius.circular(4);
|
||||
|
||||
switch (extra?.controlState) {
|
||||
case ControlState.disabled:
|
||||
labelStyle =
|
||||
labelStyle?.copyWith(color: Theme.of(context).disabledColor);
|
||||
hintStyle = hintStyle?.copyWith(color: Theme.of(context).disabledColor);
|
||||
prefixStyle =
|
||||
prefixStyle?.copyWith(color: Theme.of(context).disabledColor);
|
||||
suffixStyle =
|
||||
suffixStyle?.copyWith(color: Theme.of(context).disabledColor);
|
||||
inputStyle =
|
||||
inputStyle?.copyWith(color: Theme.of(context).disabledColor);
|
||||
borderColors = Theme.of(context).disabledColor;
|
||||
prefixIconColor = Theme.of(context).disabledColor;
|
||||
suffixIconColor = Theme.of(context).disabledColor;
|
||||
|
||||
break;
|
||||
|
||||
case ControlState.focused:
|
||||
prefixIconColor = context.colorScheme.primary;
|
||||
suffixIconColor = context.colorScheme.primary;
|
||||
iconColor = context.colorScheme.primary;
|
||||
borderColors = context.colorScheme.primary;
|
||||
labelStyle = labelStyle?.copyWith(color: context.colorScheme.primary);
|
||||
break;
|
||||
case ControlState.hovered:
|
||||
case ControlState.tapped:
|
||||
case ControlState.normal:
|
||||
case null:
|
||||
break;
|
||||
}
|
||||
|
||||
switch (extra?.statusState) {
|
||||
case StatusState.error:
|
||||
labelStyle = context.textTheme.labelLarge
|
||||
?.copyWith(color: context.colorScheme.error);
|
||||
borderColors = context.colorScheme.error;
|
||||
break;
|
||||
case StatusState.initial:
|
||||
case StatusState.success:
|
||||
case StatusState.loading:
|
||||
case null:
|
||||
break;
|
||||
}
|
||||
return TextInputStyle(
|
||||
labelStyle: labelStyle,
|
||||
hintStyle: hintStyle,
|
||||
iconColor: iconColor,
|
||||
prefixIconColor: prefixIconColor,
|
||||
prefixStyle: prefixStyle,
|
||||
suffixStyle: suffixStyle,
|
||||
suffixIconColor: suffixIconColor,
|
||||
backgroundColors: backgroundColors,
|
||||
borderColors: borderColors,
|
||||
boxShadow: boxShadow,
|
||||
radius: radius,
|
||||
inputStyle: inputStyle,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
TextInputStyle? computeExtensionValueFn(
|
||||
BuildContext context,
|
||||
TextInputThemeExtension? themeExtension, {
|
||||
TextInputState? extra,
|
||||
}) {
|
||||
TextInputStyle? textInputStyle;
|
||||
TextInputStyle? style;
|
||||
switch (extra?.controlState) {
|
||||
case ControlState.focused:
|
||||
textInputStyle = themeExtension?.focusedStyle;
|
||||
break;
|
||||
case ControlState.disabled:
|
||||
textInputStyle = themeExtension?.disableStyle;
|
||||
style = themeExtension?.disabledStyle;
|
||||
break;
|
||||
case ControlState.normal:
|
||||
textInputStyle = themeExtension?.normalStyle;
|
||||
case ControlState.focused:
|
||||
style = themeExtension?.focusedStyle;
|
||||
break;
|
||||
case ControlState.hovered:
|
||||
case ControlState.tapped:
|
||||
case ControlState.normal:
|
||||
case null:
|
||||
style = themeExtension?.normalStyle;
|
||||
break;
|
||||
}
|
||||
|
||||
TextInputStyle? style;
|
||||
switch (extra?.statusState) {
|
||||
case StatusState.error:
|
||||
style = themeExtension?.errorStyle;
|
||||
break;
|
||||
case StatusState.initial:
|
||||
case StatusState.success:
|
||||
case StatusState.loading:
|
||||
case null:
|
||||
break;
|
||||
if (extra?.isInvalid ?? false) {
|
||||
style = themeExtension?.invalidStyle;
|
||||
}
|
||||
|
||||
return TextInputStyle.merge(textInputStyle, style);
|
||||
return style;
|
||||
}
|
||||
|
||||
@override
|
||||
TextInputThemeExtension? getDefaultExtension(
|
||||
BuildContext context,
|
||||
) =>
|
||||
TextInputThemeExtensionDefault.from(Theme.of(context));
|
||||
|
||||
@override
|
||||
final TextInputStyle? Function(
|
||||
BuildContext context, {
|
||||
TextInputState? extra,
|
||||
}) customStyleFn;
|
||||
}
|
||||
|
17
packages/wyatt_ui_kit/lib/src/data/data.dart
Normal file
17
packages/wyatt_ui_kit/lib/src/data/data.dart
Normal file
@ -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_impl.dart';
|
||||
export 'flat_button_theme_extension_impl.dart';
|
||||
export 'simple_icon_button_theme_extension_impl.dart';
|
||||
export 'symbol_button_theme_extension_impl.dart';
|
@ -0,0 +1,141 @@
|
||||
// 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';
|
||||
|
||||
class FileSelectionButtonThemeExtensionImpl
|
||||
extends FileSelectionButtonThemeExtension {
|
||||
const FileSelectionButtonThemeExtensionImpl({
|
||||
super.disabledStyle,
|
||||
super.focusedStyle,
|
||||
super.hoveredStyle,
|
||||
super.normalStyle,
|
||||
super.tappedStyle,
|
||||
super.selectedStyle,
|
||||
super.invalidStyle,
|
||||
});
|
||||
|
||||
factory FileSelectionButtonThemeExtensionImpl.light({ThemeData? theme}) {
|
||||
theme ??= ThemeData.light();
|
||||
final style = FileSelectionButtonStyle(
|
||||
titleStyle: theme.textTheme.labelLarge,
|
||||
subtitleStyle: theme.textTheme.labelSmall,
|
||||
radius: BorderRadius.circular(12),
|
||||
padding: const EdgeInsets.all(13),
|
||||
foregroundColors: const MultiColor.single(Color(0xFF24262A)),
|
||||
backgroundColors: const MultiColor.single(Color(0xFFDDE0E3)),
|
||||
borderColors: const MultiColor([
|
||||
Color(0xFFDDE0E3),
|
||||
Color(0xFFCACCD4),
|
||||
]),
|
||||
stroke: 2,
|
||||
);
|
||||
return FileSelectionButtonThemeExtensionImpl(
|
||||
normalStyle: style,
|
||||
disabledStyle: style.copyWith(
|
||||
foregroundColors:
|
||||
MultiColor.single(const Color(0xFF24262A).withOpacity(0.4)),
|
||||
backgroundColors: const MultiColor.single(Color(0xFFDDE0E3)),
|
||||
borderColors:
|
||||
MultiColor.single(const Color(0xFF24262A).withOpacity(0.4)),
|
||||
),
|
||||
hoveredStyle: style.copyWith(
|
||||
backgroundColors:
|
||||
MultiColor.single(const Color(0xFF24262A).withOpacity(0.4)),
|
||||
),
|
||||
focusedStyle: style.copyWith(stroke: 4),
|
||||
tappedStyle: style.copyWith(
|
||||
backgroundColors:
|
||||
MultiColor.single(const Color(0xFF24262A).withOpacity(0.4)),
|
||||
),
|
||||
invalidStyle: style.copyWith(
|
||||
subtitleStyle: theme.textTheme.labelSmall?.copyWith(
|
||||
fontSize: 11,
|
||||
fontWeight: FontWeight.w400,
|
||||
color: const Color(0xFFF44464),
|
||||
),
|
||||
borderColors: const MultiColor([
|
||||
Color(0xFFF44464),
|
||||
Color(0xFFF44464),
|
||||
]),
|
||||
),
|
||||
// Unused
|
||||
selectedStyle: style.copyWith(
|
||||
foregroundColors: const MultiColor.single(Color(0xFF24262A)),
|
||||
borderColors: const MultiColor([
|
||||
Color(0xFF00D16C),
|
||||
Color(0xFF00D16C),
|
||||
]),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
factory FileSelectionButtonThemeExtensionImpl.dark({ThemeData? theme}) {
|
||||
theme ??= ThemeData.dark();
|
||||
final style = FileSelectionButtonStyle(
|
||||
titleStyle: theme.textTheme.labelLarge,
|
||||
subtitleStyle: theme.textTheme.labelSmall,
|
||||
radius: BorderRadius.circular(12),
|
||||
padding: const EdgeInsets.all(13),
|
||||
foregroundColors: const MultiColor.single(Color(0xFFDDE0E3)),
|
||||
backgroundColors: const MultiColor.single(Color(0xFF24262A)),
|
||||
borderColors: const MultiColor([
|
||||
Color(0xFF24262A),
|
||||
Color(0xFF24262A),
|
||||
]),
|
||||
stroke: 2,
|
||||
);
|
||||
return FileSelectionButtonThemeExtensionImpl(
|
||||
normalStyle: style,
|
||||
disabledStyle: style.copyWith(
|
||||
foregroundColors:
|
||||
MultiColor.single(const Color(0xFFDDE0E3).withOpacity(0.4)),
|
||||
backgroundColors: const MultiColor.single(Color(0xFF24262A)),
|
||||
borderColors:
|
||||
MultiColor.single(const Color(0xFFDDE0E3).withOpacity(0.4)),
|
||||
),
|
||||
hoveredStyle: style.copyWith(
|
||||
backgroundColors:
|
||||
MultiColor.single(const Color(0xFFDDE0E3).withOpacity(0.4)),
|
||||
),
|
||||
focusedStyle: style.copyWith(stroke: 4),
|
||||
tappedStyle: style.copyWith(
|
||||
backgroundColors:
|
||||
MultiColor.single(const Color(0xFFDDE0E3).withOpacity(0.4)),
|
||||
),
|
||||
invalidStyle: style.copyWith(
|
||||
subtitleStyle: theme.textTheme.labelSmall?.copyWith(
|
||||
fontSize: 11,
|
||||
fontWeight: FontWeight.w400,
|
||||
color: const Color(0xFFF44464),
|
||||
),
|
||||
borderColors: const MultiColor([
|
||||
Color(0xFFF44464),
|
||||
Color(0xFFF44464),
|
||||
]),
|
||||
),
|
||||
// Unused
|
||||
selectedStyle: style.copyWith(
|
||||
foregroundColors: const MultiColor.single(Color(0xFFDDE0E3)),
|
||||
borderColors: const MultiColor([
|
||||
Color(0xFF00D16C),
|
||||
Color(0xFF00D16C),
|
||||
]),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
@ -0,0 +1,133 @@
|
||||
// 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';
|
||||
|
||||
class FlatButtonThemeExtensionImpl extends FlatButtonThemeExtension {
|
||||
const FlatButtonThemeExtensionImpl({
|
||||
super.disabledStyle,
|
||||
super.focusedStyle,
|
||||
super.hoveredStyle,
|
||||
super.normalStyle,
|
||||
super.tappedStyle,
|
||||
});
|
||||
|
||||
factory FlatButtonThemeExtensionImpl.light({ThemeData? theme}) {
|
||||
theme ??= ThemeData.light();
|
||||
final style = FlatButtonStyle(
|
||||
labelStyle: theme.textTheme.labelLarge,
|
||||
radius: BorderRadius.circular(15),
|
||||
padding: const EdgeInsets.all(10),
|
||||
foregroundColors: const MultiColor([
|
||||
Color(0xFF3C97FB),
|
||||
Color(0xFF436EF4),
|
||||
]),
|
||||
backgroundColors: const MultiColor.single(Color(0xFFDDE0E3)),
|
||||
borderColors: const MultiColor([
|
||||
Color(0xFF3C97FB),
|
||||
Color(0xFF436EF4),
|
||||
]),
|
||||
stroke: 3,
|
||||
);
|
||||
return FlatButtonThemeExtensionImpl(
|
||||
normalStyle: style,
|
||||
disabledStyle: style.copyWith(
|
||||
labelStyle: theme.textTheme.labelLarge?.copyWith(
|
||||
color: const Color(0xFF3C97FB).withOpacity(0.4),
|
||||
),
|
||||
foregroundColors:
|
||||
MultiColor.single(const Color(0xFF3C97FB).withOpacity(0.4)),
|
||||
backgroundColors: const MultiColor.single(Color(0xFFDDE0E3)),
|
||||
borderColors:
|
||||
MultiColor.single(const Color(0xFF3C97FB).withOpacity(0.4)),
|
||||
stroke: 1,
|
||||
),
|
||||
hoveredStyle: style.copyWith(
|
||||
labelStyle: theme.textTheme.labelLarge?.copyWith(
|
||||
color: const Color(0xFFDDE0E3),
|
||||
),
|
||||
foregroundColors: const MultiColor.single(Color(0xFFDDE0E3)),
|
||||
backgroundColors: const MultiColor([
|
||||
Color(0xFF3C97FB),
|
||||
Color(0xFF436EF4),
|
||||
]),
|
||||
),
|
||||
focusedStyle: style.copyWith(stroke: 5),
|
||||
tappedStyle: style.copyWith(
|
||||
labelStyle: theme.textTheme.labelLarge?.copyWith(
|
||||
color: const Color(0xFFDDE0E3),
|
||||
),
|
||||
foregroundColors: const MultiColor.single(Color(0xFFDDE0E3)),
|
||||
backgroundColors: const MultiColor([
|
||||
Color(0xFF4B68FF),
|
||||
Color(0xFF3531F5),
|
||||
]),
|
||||
borderColors: const MultiColor([
|
||||
Color(0xFF4B68FF),
|
||||
Color(0xFF3531F5),
|
||||
]),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
factory FlatButtonThemeExtensionImpl.dark({ThemeData? theme}) {
|
||||
theme ??= ThemeData.dark();
|
||||
final style = FlatButtonStyle(
|
||||
labelStyle: theme.textTheme.labelLarge,
|
||||
radius: BorderRadius.circular(15),
|
||||
padding: const EdgeInsets.all(10),
|
||||
foregroundColors: const MultiColor.single(Color(0xFFDDE0E3)),
|
||||
backgroundColors: const MultiColor.single(Color(0xFF24262A)),
|
||||
borderColors: const MultiColor([
|
||||
Color(0xFF3C97FB),
|
||||
Color(0xFF436EF4),
|
||||
]),
|
||||
stroke: 3,
|
||||
);
|
||||
return FlatButtonThemeExtensionImpl(
|
||||
normalStyle: style,
|
||||
disabledStyle: style.copyWith(
|
||||
labelStyle: theme.textTheme.labelLarge?.copyWith(
|
||||
color: const Color(0xFF60656A),
|
||||
),
|
||||
foregroundColors: const MultiColor.single(Color(0xFF60656A)),
|
||||
backgroundColors: const MultiColor.single(Color(0xFF33373E)),
|
||||
borderColors: const MultiColor([Color(0xFF60656A), Color(0xFF383C40)]),
|
||||
stroke: 1,
|
||||
),
|
||||
hoveredStyle: style.copyWith(
|
||||
foregroundColors: const MultiColor.single(Color(0xFFDDE0E3)),
|
||||
backgroundColors: const MultiColor([
|
||||
Color(0xFF3C97FB),
|
||||
Color(0xFF436EF4),
|
||||
]),
|
||||
),
|
||||
focusedStyle: style.copyWith(stroke: 5),
|
||||
tappedStyle: style.copyWith(
|
||||
foregroundColors: const MultiColor.single(Color(0xFFDDE0E3)),
|
||||
backgroundColors: const MultiColor([
|
||||
Color(0xFF4B68FF),
|
||||
Color(0xFF3531F5),
|
||||
]),
|
||||
borderColors: const MultiColor([
|
||||
Color(0xFF4B68FF),
|
||||
Color(0xFF3531F5),
|
||||
]),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
@ -0,0 +1,121 @@
|
||||
// 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';
|
||||
|
||||
class SimpleIconButtonThemeExtensionImpl
|
||||
extends SimpleIconButtonThemeExtension {
|
||||
const SimpleIconButtonThemeExtensionImpl({
|
||||
super.disabledStyle,
|
||||
super.focusedStyle,
|
||||
super.hoveredStyle,
|
||||
super.normalStyle,
|
||||
super.tappedStyle,
|
||||
});
|
||||
|
||||
factory SimpleIconButtonThemeExtensionImpl.light({ThemeData? theme}) {
|
||||
theme ??= ThemeData.light();
|
||||
final style = SimpleIconButtonStyle(
|
||||
dimension: 30,
|
||||
radius: BorderRadius.circular(15),
|
||||
padding: const EdgeInsets.all(10),
|
||||
foregroundColors: const MultiColor([
|
||||
Color(0xFF3C97FB),
|
||||
Color(0xFF436EF4),
|
||||
]),
|
||||
backgroundColors: const MultiColor.single(Color(0xFFDDE0E3)),
|
||||
borderColors: const MultiColor([
|
||||
Color(0xFF3C97FB),
|
||||
Color(0xFF436EF4),
|
||||
]),
|
||||
stroke: 3,
|
||||
);
|
||||
return SimpleIconButtonThemeExtensionImpl(
|
||||
normalStyle: style,
|
||||
disabledStyle: style.copyWith(
|
||||
foregroundColors:
|
||||
MultiColor.single(const Color(0xFF3C97FB).withOpacity(0.4)),
|
||||
backgroundColors: const MultiColor.single(Color(0xFFDDE0E3)),
|
||||
borderColors:
|
||||
MultiColor.single(const Color(0xFF3C97FB).withOpacity(0.4)),
|
||||
stroke: 1,
|
||||
),
|
||||
hoveredStyle: style.copyWith(
|
||||
foregroundColors: const MultiColor.single(Color(0xFFDDE0E3)),
|
||||
backgroundColors: const MultiColor([
|
||||
Color(0xFF3C97FB),
|
||||
Color(0xFF436EF4),
|
||||
]),
|
||||
),
|
||||
focusedStyle: style.copyWith(stroke: 5),
|
||||
tappedStyle: style.copyWith(
|
||||
foregroundColors: const MultiColor.single(Color(0xFFDDE0E3)),
|
||||
backgroundColors: const MultiColor([
|
||||
Color(0xFF4B68FF),
|
||||
Color(0xFF3531F5),
|
||||
]),
|
||||
borderColors: const MultiColor([
|
||||
Color(0xFF4B68FF),
|
||||
Color(0xFF3531F5),
|
||||
]),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
factory SimpleIconButtonThemeExtensionImpl.dark({ThemeData? theme}) {
|
||||
theme ??= ThemeData.dark();
|
||||
final style = SimpleIconButtonStyle(
|
||||
radius: BorderRadius.circular(15),
|
||||
padding: const EdgeInsets.all(10),
|
||||
foregroundColors: const MultiColor.single(Color(0xFFDDE0E3)),
|
||||
backgroundColors: const MultiColor.single(Color(0xFF24262A)),
|
||||
borderColors: const MultiColor([
|
||||
Color(0xFF3C97FB),
|
||||
Color(0xFF436EF4),
|
||||
]),
|
||||
stroke: 3,
|
||||
);
|
||||
return SimpleIconButtonThemeExtensionImpl(
|
||||
normalStyle: style,
|
||||
disabledStyle: style.copyWith(
|
||||
foregroundColors: const MultiColor.single(Color(0xFF60656A)),
|
||||
backgroundColors: const MultiColor.single(Color(0xFF33373E)),
|
||||
borderColors: const MultiColor([Color(0xFF60656A), Color(0xFF383C40)]),
|
||||
stroke: 1,
|
||||
),
|
||||
hoveredStyle: style.copyWith(
|
||||
foregroundColors: const MultiColor.single(Color(0xFFDDE0E3)),
|
||||
backgroundColors: const MultiColor([
|
||||
Color(0xFF3C97FB),
|
||||
Color(0xFF436EF4),
|
||||
]),
|
||||
),
|
||||
focusedStyle: style.copyWith(stroke: 5),
|
||||
tappedStyle: style.copyWith(
|
||||
foregroundColors: const MultiColor.single(Color(0xFFDDE0E3)),
|
||||
backgroundColors: const MultiColor([
|
||||
Color(0xFF4B68FF),
|
||||
Color(0xFF3531F5),
|
||||
]),
|
||||
borderColors: const MultiColor([
|
||||
Color(0xFF4B68FF),
|
||||
Color(0xFF3531F5),
|
||||
]),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
@ -0,0 +1,148 @@
|
||||
// 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';
|
||||
|
||||
class SymbolButtonThemeExtensionImpl extends SymbolButtonThemeExtension {
|
||||
const SymbolButtonThemeExtensionImpl({
|
||||
super.disabledStyle,
|
||||
super.focusedStyle,
|
||||
super.hoveredStyle,
|
||||
super.normalStyle,
|
||||
super.tappedStyle,
|
||||
super.selectedStyle,
|
||||
});
|
||||
|
||||
factory SymbolButtonThemeExtensionImpl.light({ThemeData? theme}) {
|
||||
theme ??= ThemeData.light();
|
||||
final style = SymbolButtonStyle(
|
||||
labelStyle: theme.textTheme.labelLarge,
|
||||
radius: BorderRadius.circular(15),
|
||||
padding: const EdgeInsets.all(10),
|
||||
foregroundColors: const MultiColor([
|
||||
Color(0xFF3C97FB),
|
||||
Color(0xFF436EF4),
|
||||
]),
|
||||
backgroundColors: const MultiColor.single(Color(0xFFDDE0E3)),
|
||||
borderColors: const MultiColor([
|
||||
Color(0xFF3C97FB),
|
||||
Color(0xFF436EF4),
|
||||
]),
|
||||
stroke: 3,
|
||||
);
|
||||
return SymbolButtonThemeExtensionImpl(
|
||||
normalStyle: style,
|
||||
disabledStyle: style.copyWith(
|
||||
labelStyle: theme.textTheme.labelLarge?.copyWith(
|
||||
color: const Color(0xFF3C97FB).withOpacity(0.4),
|
||||
),
|
||||
foregroundColors:
|
||||
MultiColor.single(const Color(0xFF3C97FB).withOpacity(0.4)),
|
||||
backgroundColors: const MultiColor.single(Color(0xFFDDE0E3)),
|
||||
borderColors:
|
||||
MultiColor.single(const Color(0xFF3C97FB).withOpacity(0.4)),
|
||||
stroke: 1,
|
||||
),
|
||||
hoveredStyle: style.copyWith(
|
||||
labelStyle: theme.textTheme.labelLarge?.copyWith(
|
||||
color: const Color(0xFFDDE0E3),
|
||||
),
|
||||
foregroundColors: const MultiColor.single(Color(0xFFDDE0E3)),
|
||||
backgroundColors: const MultiColor([
|
||||
Color(0xFF3C97FB),
|
||||
Color(0xFF436EF4),
|
||||
]),
|
||||
),
|
||||
focusedStyle: style.copyWith(stroke: 5),
|
||||
tappedStyle: style.copyWith(
|
||||
labelStyle: theme.textTheme.labelLarge?.copyWith(
|
||||
color: const Color(0xFFDDE0E3),
|
||||
),
|
||||
foregroundColors: const MultiColor.single(Color(0xFFDDE0E3)),
|
||||
backgroundColors: const MultiColor([
|
||||
Color(0xFF4B68FF),
|
||||
Color(0xFF3531F5),
|
||||
]),
|
||||
borderColors: const MultiColor([
|
||||
Color(0xFF4B68FF),
|
||||
Color(0xFF3531F5),
|
||||
]),
|
||||
),
|
||||
selectedStyle: style.copyWith(
|
||||
foregroundColors: const MultiColor.single(Color(0xFFDDE0E3)),
|
||||
borderColors: const MultiColor([
|
||||
Color(0xFF00D16C),
|
||||
Color(0xFF00D16C),
|
||||
]),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
factory SymbolButtonThemeExtensionImpl.dark({ThemeData? theme}) {
|
||||
theme ??= ThemeData.dark();
|
||||
final style = SymbolButtonStyle(
|
||||
labelStyle: theme.textTheme.labelLarge,
|
||||
radius: BorderRadius.circular(15),
|
||||
padding: const EdgeInsets.all(10),
|
||||
foregroundColors: const MultiColor.single(Color(0xFFDDE0E3)),
|
||||
backgroundColors: const MultiColor.single(Color(0xFF24262A)),
|
||||
borderColors: const MultiColor([
|
||||
Color(0xFF3C97FB),
|
||||
Color(0xFF436EF4),
|
||||
]),
|
||||
stroke: 3,
|
||||
);
|
||||
return SymbolButtonThemeExtensionImpl(
|
||||
normalStyle: style,
|
||||
disabledStyle: style.copyWith(
|
||||
labelStyle: theme.textTheme.labelLarge?.copyWith(
|
||||
color: const Color(0xFF60656A),
|
||||
),
|
||||
foregroundColors: const MultiColor.single(Color(0xFF60656A)),
|
||||
backgroundColors: const MultiColor.single(Color(0xFF33373E)),
|
||||
borderColors: const MultiColor([Color(0xFF60656A), Color(0xFF383C40)]),
|
||||
stroke: 1,
|
||||
),
|
||||
hoveredStyle: style.copyWith(
|
||||
foregroundColors: const MultiColor.single(Color(0xFFDDE0E3)),
|
||||
backgroundColors: const MultiColor([
|
||||
Color(0xFF3C97FB),
|
||||
Color(0xFF436EF4),
|
||||
]),
|
||||
),
|
||||
focusedStyle: style.copyWith(stroke: 5),
|
||||
tappedStyle: style.copyWith(
|
||||
foregroundColors: const MultiColor.single(Color(0xFFDDE0E3)),
|
||||
backgroundColors: const MultiColor([
|
||||
Color(0xFF4B68FF),
|
||||
Color(0xFF3531F5),
|
||||
]),
|
||||
borderColors: const MultiColor([
|
||||
Color(0xFF4B68FF),
|
||||
Color(0xFF3531F5),
|
||||
]),
|
||||
),
|
||||
selectedStyle: style.copyWith(
|
||||
foregroundColors: const MultiColor.single(Color(0xFFDDE0E3)),
|
||||
borderColors: const MultiColor([
|
||||
Color(0xFF00D16C),
|
||||
Color(0xFF00D16C),
|
||||
]),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
@ -0,0 +1,95 @@
|
||||
// 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 card_theme_extension_impl}
|
||||
/// Card theme extension that implements Wyatt Theme.
|
||||
/// {@endtemplate}
|
||||
class CardThemeExtensionImpl extends CardThemeExtension {
|
||||
/// {@macro card_theme_extension_impl}
|
||||
const CardThemeExtensionImpl({
|
||||
super.radius,
|
||||
super.padding,
|
||||
super.backgroundColors,
|
||||
super.borderColors,
|
||||
super.stroke,
|
||||
super.shadow,
|
||||
super.minSize,
|
||||
super.maxSize,
|
||||
super.titleStyle,
|
||||
super.subtitleStyle,
|
||||
super.bodyStyle,
|
||||
});
|
||||
|
||||
/// {@macro card_theme_extension_impl}
|
||||
///
|
||||
/// You can pass a [ThemeData] to use its text styles.
|
||||
///
|
||||
/// This is the default light theme.
|
||||
factory CardThemeExtensionImpl.light({ThemeData? theme}) {
|
||||
theme ??= ThemeData.light();
|
||||
return CardThemeExtensionImpl(
|
||||
radius: const BorderRadius.all(Radius.circular(12)),
|
||||
padding: const EdgeInsets.all(25),
|
||||
stroke: 1,
|
||||
backgroundColors: const MultiColor.single(Color(0xFFF6F6F6)),
|
||||
borderColors: const MultiColor([
|
||||
Color(0xFFDDE0E3),
|
||||
Color(0xFFCACCD4),
|
||||
]),
|
||||
titleStyle: theme.textTheme.titleLarge,
|
||||
subtitleStyle: theme.textTheme.titleMedium,
|
||||
bodyStyle: theme.textTheme.bodyMedium,
|
||||
minSize: const Size(330, 0),
|
||||
maxSize: const Size(390, double.infinity),
|
||||
shadow: BoxShadow(
|
||||
color: const Color(0xFF24262A).withOpacity(0.05),
|
||||
blurRadius: 30,
|
||||
offset: const Offset(0, 5),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/// {@macro card_theme_extension_impl}
|
||||
///
|
||||
/// This is the default dark theme.
|
||||
factory CardThemeExtensionImpl.dark({ThemeData? theme}) {
|
||||
theme ??= ThemeData.dark();
|
||||
return CardThemeExtensionImpl(
|
||||
radius: const BorderRadius.all(Radius.circular(12)),
|
||||
padding: const EdgeInsets.all(25),
|
||||
stroke: 1,
|
||||
backgroundColors:
|
||||
const MultiColor([Color(0xFF26292D), Color(0xFF202327)]),
|
||||
borderColors: const MultiColor([
|
||||
Color(0xFF60656A),
|
||||
Color(0xFF383C40),
|
||||
]),
|
||||
titleStyle: theme.textTheme.titleLarge,
|
||||
subtitleStyle: theme.textTheme.titleMedium,
|
||||
bodyStyle: theme.textTheme.bodyMedium,
|
||||
minSize: const Size(330, 0),
|
||||
maxSize: const Size(390, double.infinity),
|
||||
shadow: BoxShadow(
|
||||
color: const Color(0xFF24262A).withOpacity(0.15),
|
||||
blurRadius: 30,
|
||||
offset: const Offset(0, 5),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
@ -0,0 +1,123 @@
|
||||
// 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 text_input_theme_extension}
|
||||
/// Text input theme extension that implements Wyatt Theme
|
||||
/// {@endtemplate}
|
||||
class TextInputThemeExtensionImpl extends TextInputThemeExtension {
|
||||
/// {@macro text_input_theme_extension}
|
||||
const TextInputThemeExtensionImpl({
|
||||
super.normalStyle,
|
||||
super.focusedStyle,
|
||||
super.disabledStyle,
|
||||
super.invalidStyle,
|
||||
});
|
||||
|
||||
factory TextInputThemeExtensionImpl.light({ThemeData? theme}) {
|
||||
theme ??= ThemeData.light();
|
||||
return TextInputThemeExtensionImpl(
|
||||
normalStyle: TextInputStyle(
|
||||
radius: BorderRadius.circular(12),
|
||||
borderColors: const Color.fromRGBO(221, 224, 227, 1),
|
||||
labelStyle: theme.textTheme.labelLarge?.copyWith(
|
||||
color: const Color.fromRGBO(55, 65, 81, 1),
|
||||
),
|
||||
inputStyle: theme.textTheme.bodyMedium?.copyWith(
|
||||
color: const Color.fromRGBO(55, 65, 81, 1),
|
||||
),
|
||||
),
|
||||
focusedStyle: TextInputStyle(
|
||||
radius: BorderRadius.circular(12),
|
||||
borderColors: const Color.fromRGBO(60, 125, 251, 1),
|
||||
labelStyle: theme.textTheme.labelLarge?.copyWith(
|
||||
color: const Color.fromRGBO(55, 65, 81, 1),
|
||||
),
|
||||
inputStyle: theme.textTheme.bodyMedium?.copyWith(
|
||||
color: const Color.fromRGBO(55, 65, 81, 1),
|
||||
),
|
||||
),
|
||||
invalidStyle: TextInputStyle(
|
||||
radius: BorderRadius.circular(12),
|
||||
borderColors: const Color.fromRGBO(244, 68, 100, 1),
|
||||
labelStyle: theme.textTheme.labelLarge?.copyWith(
|
||||
color: const Color.fromRGBO(244, 68, 100, 1),
|
||||
),
|
||||
inputStyle: theme.textTheme.bodyMedium?.copyWith(
|
||||
color: const Color.fromRGBO(55, 65, 81, 1),
|
||||
),
|
||||
),
|
||||
disabledStyle: TextInputStyle(
|
||||
radius: BorderRadius.circular(12),
|
||||
borderColors: const Color.fromRGBO(229, 231, 235, 1),
|
||||
labelStyle: theme.textTheme.labelLarge?.copyWith(
|
||||
color: const Color.fromRGBO(156, 163, 175, 1),
|
||||
),
|
||||
inputStyle: theme.textTheme.bodyMedium?.copyWith(
|
||||
color: const Color.fromRGBO(156, 163, 175, 1),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
factory TextInputThemeExtensionImpl.dark({ThemeData? theme}) {
|
||||
theme ??= ThemeData.dark();
|
||||
return TextInputThemeExtensionImpl(
|
||||
normalStyle: TextInputStyle(
|
||||
radius: BorderRadius.circular(12),
|
||||
borderColors: const Color.fromRGBO(96, 101, 106, 1),
|
||||
labelStyle: theme.textTheme.labelLarge?.copyWith(
|
||||
color: const Color.fromRGBO(204, 204, 204, 1),
|
||||
),
|
||||
inputStyle: theme.textTheme.bodyMedium?.copyWith(
|
||||
color: const Color.fromRGBO(255, 255, 255, 1),
|
||||
),
|
||||
),
|
||||
focusedStyle: TextInputStyle(
|
||||
radius: BorderRadius.circular(12),
|
||||
borderColors: const Color.fromRGBO(60, 125, 251, 1),
|
||||
labelStyle: theme.textTheme.labelLarge?.copyWith(
|
||||
color: const Color.fromRGBO(204, 204, 204, 1),
|
||||
),
|
||||
inputStyle: theme.textTheme.bodyMedium?.copyWith(
|
||||
color: const Color.fromRGBO(255, 255, 255, 1),
|
||||
),
|
||||
),
|
||||
invalidStyle: TextInputStyle(
|
||||
radius: BorderRadius.circular(12),
|
||||
borderColors: const Color.fromRGBO(244, 68, 100, 1),
|
||||
labelStyle: theme.textTheme.labelLarge?.copyWith(
|
||||
color: const Color.fromRGBO(244, 68, 100, 1),
|
||||
),
|
||||
inputStyle: theme.textTheme.bodyMedium?.copyWith(
|
||||
color: const Color.fromRGBO(255, 255, 255, 1),
|
||||
),
|
||||
),
|
||||
disabledStyle: TextInputStyle(
|
||||
radius: BorderRadius.circular(12),
|
||||
borderColors: const Color.fromRGBO(96, 101, 106, 1),
|
||||
labelStyle: theme.textTheme.labelLarge?.copyWith(
|
||||
color: const Color.fromRGBO(96, 101, 106, 1),
|
||||
),
|
||||
inputStyle: theme.textTheme.bodyMedium?.copyWith(
|
||||
color: const Color.fromRGBO(255, 255, 255, 1),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
@ -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_extensions/button_theme_extensions.dart';
|
||||
export 'card_theme_extension_impl.dart';
|
||||
export 'text_input_theme_extension_impl.dart';
|
@ -1,52 +0,0 @@
|
||||
// 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';
|
||||
|
||||
abstract class FileSelectionButtonThemeExtension
|
||||
extends ThemeExtension<FileSelectionButtonThemeExtension> {
|
||||
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;
|
||||
}
|
@ -1,44 +0,0 @@
|
||||
// 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';
|
||||
|
||||
abstract class FlatButtonThemeExtension
|
||||
extends ThemeExtension<FlatButtonThemeExtension> {
|
||||
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;
|
||||
}
|
@ -1,44 +0,0 @@
|
||||
// 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';
|
||||
|
||||
abstract class SimpleIconButtonThemeExtension
|
||||
extends ThemeExtension<SimpleIconButtonThemeExtension> {
|
||||
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;
|
||||
}
|
@ -1,48 +0,0 @@
|
||||
// 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';
|
||||
|
||||
abstract class SymbolButtonThemeExtension
|
||||
extends ThemeExtension<SymbolButtonThemeExtension> {
|
||||
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;
|
||||
}
|
@ -14,8 +14,6 @@
|
||||
// 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 './loader_theme_extension.dart';
|
||||
export './rich_text_builder_theme_extension.dart';
|
||||
export './text_input_theme_extension.dart';
|
||||
|
@ -14,7 +14,8 @@
|
||||
// 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 './components/components.dart';
|
||||
export './core/core.dart';
|
||||
export './domain/domain.dart';
|
||||
export './features/wyatt_component_theme_data.dart';
|
||||
export 'components/components.dart';
|
||||
export 'core/core.dart';
|
||||
export 'data/data.dart';
|
||||
export 'domain/domain.dart';
|
||||
export 'features/wyatt_component_theme_data.dart';
|
||||
|
@ -15,6 +15,8 @@
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
/// UIKit and Design System used in Wyatt Studio.
|
||||
///
|
||||
/// Built using `wyatt_ui_components`.
|
||||
library wyatt_ui_kit;
|
||||
|
||||
export 'package:wyatt_ui_components/src/core/extensions/build_context_extensions.dart';
|
||||
|
Loading…
x
Reference in New Issue
Block a user