diff --git a/packages/wyatt_ui_kit/example/lib/buttons/buttons.dart b/packages/wyatt_ui_kit/example/lib/buttons/buttons.dart
index f7e312e3..8d9cbd9f 100644
--- a/packages/wyatt_ui_kit/example/lib/buttons/buttons.dart
+++ b/packages/wyatt_ui_kit/example/lib/buttons/buttons.dart
@@ -30,6 +30,7 @@ const _background = Color(0xFF16191D);
const _disabledBackground = Color(0xFF16191D + 0x66FFFFFF);
const _disabledColors = [Color(0xFF60656A), Color(0xFF383C40)];
const _selectedColors = [Color(0xFF50CE99), Color(0xFF339572)];
+const _invalidColor = Color(0xFFFB5E3C);
class Buttons extends StatelessWidget {
const Buttons({super.key});
@@ -325,6 +326,47 @@ class Buttons extends StatelessWidget {
),
],
),
+ const Gap(20),
+ FileSelectionButton(
+ leading: const DecoratedBox(
+ decoration: BoxDecoration(
+ color: _disabled,
+ borderRadius: BorderRadius.all(
+ Radius.circular(5),
+ ),
+ ),
+ child: Padding(
+ padding: EdgeInsets.all(8),
+ child: Icon(
+ Icons.file_upload_outlined,
+ color: Colors.white,
+ ),
+ ),
+ ),
+ title: TextWrapper(
+ 'Ajouter un fichier',
+ style: Theme.of(context)
+ .textTheme
+ .titleLarge
+ ?.copyWith(color: _disabled),
+ ),
+ subTitle: TextWrapper.text('Taille max: 20 Mo'),
+ normalStyle: const FileSelectionButtonStyle(
+ backgroundColors: MultiColor.single(_disabledBackground),
+ foregroundColors: MultiColor.single(_disabled),
+ borderColors: MultiColor.single(_disabled),
+ ),
+ hoveredStyle: const FileSelectionButtonStyle(
+ backgroundColors: MultiColor.single(_disabledBackground),
+ foregroundColors: MultiColor.single(_disabled),
+ borderColors: MultiColor.single(Colors.white),
+ ),
+ invalidStyle: const FileSelectionButtonStyle(
+ backgroundColors: MultiColor.single(_disabledBackground),
+ foregroundColors: MultiColor.single(_invalidColor),
+ borderColors: MultiColor.single(_invalidColor),
+ ),
+ )
],
),
),
diff --git a/packages/wyatt_ui_kit/lib/src/components/buttons/buttons.dart b/packages/wyatt_ui_kit/lib/src/components/buttons/buttons.dart
index c3cd55d7..bf04a627 100644
--- a/packages/wyatt_ui_kit/lib/src/components/buttons/buttons.dart
+++ b/packages/wyatt_ui_kit/lib/src/components/buttons/buttons.dart
@@ -14,6 +14,7 @@
// You should have received a copy of the GNU General Public License
// along with this program. If not, see .
+export './file_selection_button/file_selection_button.dart';
export './flat_button/flat_button.dart';
export './simple_icon_button/simple_icon_button.dart';
export './symbol_button/symbol_button.dart';
diff --git a/packages/wyatt_ui_kit/lib/src/components/buttons/cubit/invalid_button_cubit.dart b/packages/wyatt_ui_kit/lib/src/components/buttons/cubit/invalid_button_cubit.dart
new file mode 100644
index 00000000..e90832d8
--- /dev/null
+++ b/packages/wyatt_ui_kit/lib/src/components/buttons/cubit/invalid_button_cubit.dart
@@ -0,0 +1,73 @@
+// 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 .
+
+import 'dart:async';
+import 'dart:math';
+
+import 'package:wyatt_ui_components/wyatt_wyatt_ui_components.dart';
+import 'package:wyatt_ui_kit/src/components/buttons/cubit/button_cubit.dart';
+
+class InvalidButtonCubit extends ButtonCubit {
+ @override
+ FutureOr onClickUpIn() async {
+ if (state.isDisabled || state.isFreezed) {
+ return;
+ }
+
+ emit(
+ state.copyWith(
+ state: ControlState.hovered,
+ // TODO(hpcl): change this
+ invalid: Random().nextBool(),
+ ),
+ );
+ }
+
+ @override
+ FutureOr onClickUpOut() async {
+ if (state.isDisabled || state.isFreezed) {
+ return;
+ }
+
+ emit(
+ state.copyWith(
+ state: ControlState.normal,
+ // TODO(hpcl): change this
+ invalid: Random().nextBool(),
+ ),
+ );
+ }
+
+ FutureOr invalidate() async {
+ if (state.isDisabled || state.isFreezed) {
+ return;
+ }
+
+ emit(
+ state.copyWith(invalid: true),
+ );
+ }
+
+ FutureOr fix() async {
+ if (state.isDisabled || state.isFreezed) {
+ return;
+ }
+
+ emit(
+ state.copyWith(invalid: false),
+ );
+ }
+}
diff --git a/packages/wyatt_ui_kit/lib/src/components/buttons/cubit/selectable_button_cubit.dart b/packages/wyatt_ui_kit/lib/src/components/buttons/cubit/selectable_button_cubit.dart
index a271e09a..9b747ad4 100644
--- a/packages/wyatt_ui_kit/lib/src/components/buttons/cubit/selectable_button_cubit.dart
+++ b/packages/wyatt_ui_kit/lib/src/components/buttons/cubit/selectable_button_cubit.dart
@@ -37,4 +37,24 @@ class SelectableButtonCubit extends ButtonCubit {
}
emit(state.copyWith(state: ControlState.normal, selected: !state.selected));
}
+
+ FutureOr select() async {
+ if (state.isDisabled || state.isFreezed) {
+ return;
+ }
+
+ emit(
+ state.copyWith(selected: true),
+ );
+ }
+
+ FutureOr unselect() async {
+ if (state.isDisabled || state.isFreezed) {
+ return;
+ }
+
+ emit(
+ state.copyWith(selected: false),
+ );
+ }
}
diff --git a/packages/wyatt_ui_kit/lib/src/components/buttons/file_selection_button/file_selection_button.dart b/packages/wyatt_ui_kit/lib/src/components/buttons/file_selection_button/file_selection_button.dart
new file mode 100644
index 00000000..44759cc7
--- /dev/null
+++ b/packages/wyatt_ui_kit/lib/src/components/buttons/file_selection_button/file_selection_button.dart
@@ -0,0 +1,96 @@
+// 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 .
+
+import 'package:flutter/material.dart' hide ButtonStyle;
+import 'package:wyatt_component_copy_with_extension/component_copy_with_extension.dart';
+import 'package:wyatt_ui_components/wyatt_wyatt_ui_components.dart';
+import 'package:wyatt_ui_kit/src/components/buttons/cubit/invalid_button_cubit.dart';
+import 'package:wyatt_ui_kit/src/components/buttons/file_selection_button/file_selection_button_screen.dart';
+import 'package:wyatt_ui_kit/src/core/mixin/export_bloc_mixin.dart';
+
+part 'file_selection_button.g.dart';
+
+@ComponentCopyWithExtension()
+class FileSelectionButton extends FileSelectionButtonComponent
+ with $FileSelectionButtonCWMixin, ExportBloc {
+ FileSelectionButton({
+ super.leading,
+ super.title,
+ super.subTitle,
+ super.disabledStyle,
+ super.normalStyle,
+ super.hoveredStyle,
+ super.focusedStyle,
+ super.tappedStyle,
+ super.selectedStyle,
+ super.invalidStyle,
+ super.onPressed,
+ super.mainAxisSize,
+ super.key,
+ });
+
+ final InvalidButtonCubit _cubit = InvalidButtonCubit();
+
+ @override
+ InvalidButtonCubit get bloc => _cubit;
+
+ @override
+ FileSelectionButtonStyle? get disabledStyle =>
+ super.disabledStyle as FileSelectionButtonStyle?;
+
+ @override
+ FileSelectionButtonStyle? get normalStyle =>
+ super.normalStyle as FileSelectionButtonStyle?;
+
+ @override
+ FileSelectionButtonStyle? get hoveredStyle =>
+ super.hoveredStyle as FileSelectionButtonStyle?;
+
+ @override
+ FileSelectionButtonStyle? get focusedStyle =>
+ super.focusedStyle as FileSelectionButtonStyle?;
+
+ @override
+ FileSelectionButtonStyle? get tappedStyle =>
+ super.tappedStyle as FileSelectionButtonStyle?;
+
+ @override
+ FileSelectionButtonStyle? get selectedStyle =>
+ super.selectedStyle as FileSelectionButtonStyle?;
+
+ @override
+ FileSelectionButtonStyle? get invalidStyle =>
+ super.invalidStyle as FileSelectionButtonStyle?;
+
+ @override
+ Widget build(BuildContext context) => exportBloc(
+ child: FileSelectionButtonScreen(
+ leading: leading,
+ title: title,
+ subTitle: subTitle,
+ disabledStyle: disabledStyle,
+ normalStyle: normalStyle,
+ hoveredStyle: hoveredStyle,
+ focusedStyle: focusedStyle,
+ tappedStyle: tappedStyle,
+ selectedStyle: selectedStyle,
+ invalidStyle: invalidStyle,
+ onPressed: onPressed,
+ mainAxisSize: mainAxisSize,
+ key: key,
+ ),
+ );
+}
diff --git a/packages/wyatt_ui_kit/lib/src/components/buttons/file_selection_button/file_selection_button.g.dart b/packages/wyatt_ui_kit/lib/src/components/buttons/file_selection_button/file_selection_button.g.dart
new file mode 100644
index 00000000..d70db729
--- /dev/null
+++ b/packages/wyatt_ui_kit/lib/src/components/buttons/file_selection_button/file_selection_button.g.dart
@@ -0,0 +1,85 @@
+// GENERATED CODE - DO NOT MODIFY BY HAND
+
+part of 'file_selection_button.dart';
+
+// **************************************************************************
+// ComponentCopyWithGenerator
+// **************************************************************************
+
+class $FileSelectionButtonCWProxyImpl
+ implements $FileSelectionButtonComponentCWProxy {
+ const $FileSelectionButtonCWProxyImpl(this._value);
+ final FileSelectionButton _value;
+ @override
+ FileSelectionButton mainAxisSize(MainAxisSize? mainAxisSize) =>
+ this(mainAxisSize: mainAxisSize);
+ @override
+ FileSelectionButton leading(Widget? leading) => this(leading: leading);
+ @override
+ FileSelectionButton title(TextWrapper? title) => this(title: title);
+ @override
+ FileSelectionButton subTitle(TextWrapper? subTitle) =>
+ this(subTitle: subTitle);
+ @override
+ FileSelectionButton disabledStyle(ButtonStyle? disabledStyle) =>
+ this(disabledStyle: disabledStyle);
+ @override
+ FileSelectionButton normalStyle(ButtonStyle? normalStyle) =>
+ this(normalStyle: normalStyle);
+ @override
+ FileSelectionButton hoveredStyle(ButtonStyle? hoveredStyle) =>
+ this(hoveredStyle: hoveredStyle);
+ @override
+ FileSelectionButton focusedStyle(ButtonStyle? focusedStyle) =>
+ this(focusedStyle: focusedStyle);
+ @override
+ FileSelectionButton tappedStyle(ButtonStyle? tappedStyle) =>
+ this(tappedStyle: tappedStyle);
+ @override
+ FileSelectionButton selectedStyle(ButtonStyle? selectedStyle) =>
+ this(selectedStyle: selectedStyle);
+ @override
+ FileSelectionButton invalidStyle(ButtonStyle? invalidStyle) =>
+ this(invalidStyle: invalidStyle);
+ @override
+ FileSelectionButton onPressed(void Function(ControlState)? onPressed) =>
+ this(onPressed: onPressed);
+ @override
+ FileSelectionButton key(Key? key) => this(key: key);
+ @override
+ FileSelectionButton call({
+ MainAxisSize? mainAxisSize,
+ Widget? leading,
+ TextWrapper? title,
+ TextWrapper? subTitle,
+ ButtonStyle? disabledStyle,
+ ButtonStyle? normalStyle,
+ ButtonStyle? hoveredStyle,
+ ButtonStyle? focusedStyle,
+ ButtonStyle? tappedStyle,
+ ButtonStyle? selectedStyle,
+ ButtonStyle? invalidStyle,
+ void Function(ControlState)? onPressed,
+ Key? key,
+ }) =>
+ FileSelectionButton(
+ leading: leading ?? _value.leading,
+ title: title ?? _value.title,
+ subTitle: subTitle ?? _value.subTitle,
+ disabledStyle: disabledStyle ?? _value.disabledStyle,
+ normalStyle: normalStyle ?? _value.normalStyle,
+ hoveredStyle: hoveredStyle ?? _value.hoveredStyle,
+ focusedStyle: focusedStyle ?? _value.focusedStyle,
+ tappedStyle: tappedStyle ?? _value.tappedStyle,
+ selectedStyle: selectedStyle ?? _value.selectedStyle,
+ invalidStyle: invalidStyle ?? _value.invalidStyle,
+ onPressed: onPressed ?? _value.onPressed,
+ mainAxisSize: mainAxisSize ?? _value.mainAxisSize,
+ key: key ?? _value.key,
+ );
+}
+
+mixin $FileSelectionButtonCWMixin on Component {
+ $FileSelectionButtonComponentCWProxy get copyWith =>
+ $FileSelectionButtonCWProxyImpl(this as FileSelectionButton);
+}
diff --git a/packages/wyatt_ui_kit/lib/src/components/buttons/file_selection_button/file_selection_button_screen.dart b/packages/wyatt_ui_kit/lib/src/components/buttons/file_selection_button/file_selection_button_screen.dart
new file mode 100644
index 00000000..fd92b971
--- /dev/null
+++ b/packages/wyatt_ui_kit/lib/src/components/buttons/file_selection_button/file_selection_button_screen.dart
@@ -0,0 +1,251 @@
+// 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 .
+
+import 'package:dotted_border/dotted_border.dart';
+import 'package:flutter/material.dart' hide ButtonStyle;
+import 'package:flutter/services.dart';
+import 'package:gap/gap.dart';
+import 'package:wyatt_bloc_helper/wyatt_bloc_helper.dart';
+import 'package:wyatt_ui_components/wyatt_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/invalid_button_cubit.dart';
+import 'package:wyatt_ui_kit/src/components/gradients/gradient_text.dart';
+import 'package:wyatt_ui_kit/src/core/extensions/theme_extensions.dart';
+import 'package:wyatt_ui_kit/src/core/helpers/linear_gradient_helper.dart';
+
+class FileSelectionButtonScreen
+ extends CubitScreen {
+ const FileSelectionButtonScreen({
+ this.leading,
+ this.title,
+ this.subTitle,
+ this.disabledStyle,
+ this.normalStyle,
+ this.hoveredStyle,
+ this.focusedStyle,
+ this.tappedStyle,
+ this.selectedStyle,
+ this.invalidStyle,
+ this.onPressed,
+ this.mainAxisSize,
+ super.key,
+ });
+
+ final Widget? leading;
+ final TextWrapper? title;
+ final TextWrapper? subTitle;
+
+ final FileSelectionButtonStyle? disabledStyle;
+ final FileSelectionButtonStyle? normalStyle;
+ final FileSelectionButtonStyle? hoveredStyle;
+ final FileSelectionButtonStyle? focusedStyle;
+ final FileSelectionButtonStyle? tappedStyle;
+ final FileSelectionButtonStyle? selectedStyle;
+ final FileSelectionButtonStyle? invalidStyle;
+
+ final void Function(ControlState state)? onPressed;
+
+ final MainAxisSize? mainAxisSize;
+
+ @override
+ InvalidButtonCubit create(BuildContext context) => InvalidButtonCubit();
+
+ @override
+ Widget onBuild(BuildContext context, ButtonState state) {
+ // Set a default style
+ FileSelectionButtonStyle? style =
+ normalStyle ?? const FileSelectionButtonStyle();
+
+ switch (state.state) {
+ case ControlState.disabled:
+ style = disabledStyle ?? style;
+ break;
+ case ControlState.hovered:
+ style = hoveredStyle ?? style;
+ break;
+ case ControlState.tapped:
+ style = tappedStyle ?? style;
+ break;
+ case ControlState.focused:
+ style = focusedStyle ?? style;
+ break;
+ case ControlState.normal:
+ // already done
+ break;
+ }
+
+ if (state.isSelected) {
+ style = selectedStyle ?? style;
+ }
+
+ if (state.isInvalid) {
+ style = invalidStyle ?? style;
+ }
+
+ print(state);
+
+ return Focus(
+ onFocusChange: (hasFocus) =>
+ hasFocus ? bloc(context).onFocus() : bloc(context).onUnfocus(),
+ onKeyEvent: (focusNode, event) {
+ if (event.logicalKey == LogicalKeyboardKey.enter && state.isFocused) {
+ onPressed?.call(state.state);
+ bloc(context).onClickUpOut();
+ return KeyEventResult.handled;
+ }
+ return KeyEventResult.ignored;
+ },
+ child: MouseRegion(
+ cursor: SystemMouseCursors.click,
+ onEnter: (event) {
+ bloc(context).onMouseEnter();
+ },
+ onExit: (event) {
+ bloc(context).onMouseLeave();
+ },
+ child: GestureDetector(
+ onTapDown: (details) {
+ bloc(context).onClickDown();
+ },
+ onTapUp: (details) {
+ onPressed?.call(state.state);
+ bloc(context).onClickUpIn();
+ },
+ onTapCancel: () {
+ onPressed?.call(state.state);
+ bloc(context).onClickUpOut();
+ },
+ child: DottedBorder(
+ padding: EdgeInsets.zero,
+ dashPattern: const [5, 5],
+ strokeWidth: style.stroke ?? 3,
+ color: style.borderColors?.color ?? context.colorScheme.primary,
+ borderType: BorderType.RRect,
+ radius: Radius.circular(style.radius ?? 0),
+ strokeCap: StrokeCap.square,
+ child: DecoratedBox(
+ decoration: BoxDecoration(
+ color: style.backgroundColors?.color ??
+ context.colorScheme.primary,
+ // if no gradient colors => no default value
+ gradient: (style.backgroundColors?.isGradient ?? false)
+ ? LinearGradient(
+ colors: style.backgroundColors!.colors,
+ )
+ : null,
+ boxShadow: [
+ if (style.shadow != null) ...[style.shadow!]
+ ],
+ borderRadius: BorderRadius.all(
+ Radius.circular(style.radius ?? 0),
+ ),
+ ),
+ child: ConstrainedBox(
+ constraints: const BoxConstraints(
+ minWidth: 200,
+ minHeight: 50,
+ ), // min sizes for Material buttons
+ child: Padding(
+ padding: EdgeInsets.all(style.padding ?? 0),
+ child: Row(
+ mainAxisSize: mainAxisSize ?? MainAxisSize.min,
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+ if (leading != null) ...[
+ leading ?? const SizedBox.shrink(),
+ Gap(style.padding ?? 10),
+ ],
+
+ // Choose color
+ // label.style.color ??
+ // buttonStyle.foregroundColor.color ??
+ // context.textTheme.titleLarge.color
+ //
+ // Choose gradient
+ // label.gradient ??
+ // buttonStyle.foregroundColor.colors ??
+ // null
+ Column(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ if (title != null) ...[
+ Builder(
+ builder: (context) {
+ final color = title?.style?.color ??
+ style?.foregroundColors?.color ??
+ context.textTheme.titleLarge?.color;
+ final buttonStyleGradient =
+ (style?.foregroundColors?.isGradient ??
+ false)
+ ? style?.foregroundColors?.colors
+ : null;
+ final gradient =
+ title?.gradient ?? buttonStyleGradient;
+
+ return Text(
+ title!.text,
+ style: (title!.style ??
+ context.textTheme.titleLarge)
+ ?.copyWith(color: color),
+ ).toGradient(
+ LinearGradientHelper.fromNullableColors(
+ gradient,
+ ),
+ );
+ },
+ ),
+ ],
+ if (subTitle != null) ...[
+ Builder(
+ builder: (context) {
+ final color = subTitle?.style?.color ??
+ style?.foregroundColors?.color ??
+ context.textTheme.bodyMedium?.color;
+ final buttonStyleGradient =
+ (style?.foregroundColors?.isGradient ??
+ false)
+ ? style?.foregroundColors?.colors
+ : null;
+ final gradient =
+ subTitle?.gradient ?? buttonStyleGradient;
+
+ return Text(
+ subTitle!.text,
+ style: (subTitle!.style ??
+ context.textTheme.bodyMedium)
+ ?.copyWith(color: color),
+ ).toGradient(
+ LinearGradientHelper.fromNullableColors(
+ gradient,
+ ),
+ );
+ },
+ ),
+ ],
+ ],
+ ),
+ ],
+ ),
+ ),
+ ),
+ ),
+ ),
+ ),
+ ),
+ );
+ }
+}
diff --git a/packages/wyatt_ui_kit/lib/src/components/buttons/flat_button/flat_button_screen.dart b/packages/wyatt_ui_kit/lib/src/components/buttons/flat_button/flat_button_screen.dart
index 1d44a8f0..050ab61e 100644
--- a/packages/wyatt_ui_kit/lib/src/components/buttons/flat_button/flat_button_screen.dart
+++ b/packages/wyatt_ui_kit/lib/src/components/buttons/flat_button/flat_button_screen.dart
@@ -111,117 +111,114 @@ class FlatButtonScreen extends CubitScreen {
onPressed?.call(state.state);
bloc(context).onClickUpOut();
},
- child: Material(
- color: const Color(0x00000000),
- child: Ink(
- decoration: BoxDecoration(
- color: style.backgroundColors?.color ??
- context.colorScheme.primary,
- // If no border color => no default value
- border: (style.borderColors != null)
- ? (style.borderColors?.isGradient ?? false)
- ? GradientBoxBorder(
- gradient: LinearGradient(
- colors: style.borderColors!.colors,
- ),
- width: style.stroke ?? 2,
- )
- : Border.all(
- color: style.borderColors!.color,
- width: style.stroke ?? 2,
- )
- : null,
- // if no gradient colors => no default value
- gradient: (style.backgroundColors?.isGradient ?? false)
- ? LinearGradient(
- colors: style.backgroundColors!.colors,
- )
- : null,
- boxShadow: [
- if (style.shadow != null) ...[style.shadow!]
- ],
- borderRadius: BorderRadius.all(
- Radius.circular(style.radius ?? 0),
- ),
+ child: DecoratedBox(
+ decoration: BoxDecoration(
+ color: style.backgroundColors?.color ??
+ context.colorScheme.primary,
+ // If no border color => no default value
+ border: (style.borderColors != null)
+ ? (style.borderColors?.isGradient ?? false)
+ ? GradientBoxBorder(
+ gradient: LinearGradient(
+ colors: style.borderColors!.colors,
+ ),
+ width: style.stroke ?? 2,
+ )
+ : Border.all(
+ color: style.borderColors!.color,
+ width: style.stroke ?? 2,
+ )
+ : null,
+ // if no gradient colors => no default value
+ gradient: (style.backgroundColors?.isGradient ?? false)
+ ? LinearGradient(
+ colors: style.backgroundColors!.colors,
+ )
+ : null,
+ boxShadow: [
+ if (style.shadow != null) ...[style.shadow!]
+ ],
+ borderRadius: BorderRadius.all(
+ Radius.circular(style.radius ?? 0),
),
- child: ConstrainedBox(
- constraints: const BoxConstraints(
- minWidth: 88,
- minHeight: 36,
- ), // min sizes for Material buttons
- child: Padding(
- padding: EdgeInsets.all(style.padding ?? 0),
- child: Row(
- mainAxisSize: mainAxisSize ?? MainAxisSize.min,
- mainAxisAlignment: MainAxisAlignment.spaceBetween,
- children: [
+ ),
+ child: ConstrainedBox(
+ constraints: const BoxConstraints(
+ minWidth: 88,
+ minHeight: 36,
+ ), // min sizes for Material buttons
+ child: Padding(
+ padding: EdgeInsets.all(style.padding ?? 0),
+ child: Row(
+ mainAxisSize: mainAxisSize ?? MainAxisSize.min,
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+ Builder(
+ builder: (context) {
+ final color = style?.foregroundColors?.color;
+ if (color != null) {
+ return ColorFiltered(
+ colorFilter:
+ ColorFilter.mode(color, BlendMode.srcIn),
+ child: prefix ?? const SizedBox.shrink(),
+ );
+ } else {
+ return prefix ?? const SizedBox.shrink();
+ }
+ },
+ ),
+ Gap(style.padding ?? 10),
+ // Choose color
+ // label.style.color ??
+ // buttonStyle.foregroundColor.color ??
+ // context.textTheme.titleLarge.color
+ //
+ // Choose gradient
+ // label.gradient ??
+ // buttonStyle.foregroundColor.colors ??
+ // null
+ if (label != null) ...[
Builder(
builder: (context) {
- final color = style?.foregroundColors?.color;
- if (color != null) {
- return ColorFiltered(
- colorFilter:
- ColorFilter.mode(color, BlendMode.srcIn),
- child: prefix ?? const SizedBox.shrink(),
- );
- } else {
- return prefix ?? const SizedBox.shrink();
- }
- },
- ),
- Gap(style.padding ?? 10),
- // Choose color
- // label.style.color ??
- // buttonStyle.foregroundColor.color ??
- // context.textTheme.titleLarge.color
- //
- // Choose gradient
- // label.gradient ??
- // buttonStyle.foregroundColor.colors ??
- // null
- if (label != null) ...[
- Builder(
- builder: (context) {
- final color = label?.style?.color ??
- style?.foregroundColors?.color ??
- context.textTheme.titleLarge?.color;
- final buttonStyleGradient =
- (style?.foregroundColors?.isGradient ?? false)
- ? style?.foregroundColors?.colors
- : null;
- final gradient =
- label?.gradient ?? buttonStyleGradient;
+ final color = label?.style?.color ??
+ style?.foregroundColors?.color ??
+ context.textTheme.titleLarge?.color;
+ final buttonStyleGradient =
+ (style?.foregroundColors?.isGradient ?? false)
+ ? style?.foregroundColors?.colors
+ : null;
+ final gradient =
+ label?.gradient ?? buttonStyleGradient;
- return Text(
- label!.text,
- style:
- (label!.style ?? context.textTheme.titleLarge)
- ?.copyWith(color: color),
- ).toGradient(
- LinearGradientHelper.fromNullableColors(
- gradient,
- ),
- );
- },
- ),
- ],
- Gap(style.padding ?? 10),
- Builder(
- builder: (context) {
- final color = style?.foregroundColors?.color;
- if (color != null) {
- return ColorFiltered(
- colorFilter:
- ColorFilter.mode(color, BlendMode.srcIn),
- child: suffix ?? const SizedBox.shrink(),
- );
- } else {
- return suffix ?? const SizedBox.shrink();
- }
+ return Text(
+ label!.text,
+ style:
+ (label!.style ?? context.textTheme.titleLarge)
+ ?.copyWith(color: color),
+ ).toGradient(
+ LinearGradientHelper.fromNullableColors(
+ gradient,
+ ),
+ );
},
),
],
- ),
+ Gap(style.padding ?? 10),
+ Builder(
+ builder: (context) {
+ final color = style?.foregroundColors?.color;
+ if (color != null) {
+ return ColorFiltered(
+ colorFilter:
+ ColorFilter.mode(color, BlendMode.srcIn),
+ child: suffix ?? const SizedBox.shrink(),
+ );
+ } else {
+ return suffix ?? const SizedBox.shrink();
+ }
+ },
+ ),
+ ],
),
),
),
diff --git a/packages/wyatt_ui_kit/pubspec.yaml b/packages/wyatt_ui_kit/pubspec.yaml
index f600885d..319289e2 100644
--- a/packages/wyatt_ui_kit/pubspec.yaml
+++ b/packages/wyatt_ui_kit/pubspec.yaml
@@ -9,6 +9,7 @@ environment:
sdk: ">=2.19.0 <3.0.0"
dependencies:
+ dotted_border: ^2.0.0+3
equatable: ^2.0.5
flutter: { sdk: flutter }
flutter_animate: ^3.0.0